sootsim 0.1.118 → 0.1.119
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-NJPQWWOB.js → agent-HMYFFW3K.js} +2 -2
- package/dist-cli/chunks/{agent-wrapper-XY2KLHD5.js → agent-wrapper-L5TRN5OW.js} +2 -2
- package/dist-cli/chunks/{app-fonts-VVWZHR3V.js → app-fonts-G5L5BPHX.js} +2 -2
- package/dist-cli/chunks/{assert-WCZYRGGS.js → assert-MN4TCTKK.js} +2 -2
- package/dist-cli/chunks/auto-bootstrap-QJ5PP7KT.js +2 -0
- package/dist-cli/chunks/beta-LAPRQ3TP.js +2 -0
- package/dist-cli/chunks/{chunk-SCAOPMDY.js → chunk-3MWC6EE2.js} +2 -2
- package/dist-cli/chunks/{chunk-WYQOR72S.js → chunk-475TNRB7.js} +2 -2
- package/dist-cli/chunks/{chunk-FXARAPTS.js → chunk-47SB3JEW.js} +3 -3
- package/dist-cli/chunks/{chunk-4YCHWQKG.js → chunk-4EQ5V4CA.js} +1 -1
- package/dist-cli/chunks/{chunk-BJGF7NGV.js → chunk-4KU7AIP7.js} +1 -1
- package/dist-cli/chunks/chunk-5AL4WWUG.js +1 -0
- package/dist-cli/chunks/{chunk-EGAVQVNQ.js → chunk-5OZHLK4L.js} +2 -2
- package/dist-cli/chunks/{chunk-XEWSIOAB.js → chunk-APWX6YCC.js} +2 -2
- package/dist-cli/chunks/{chunk-UPSFFGWI.js → chunk-AUKEEPZT.js} +1 -1
- package/dist-cli/chunks/{chunk-FPUW7ZDL.js → chunk-AV6YDPVF.js} +2 -2
- package/dist-cli/chunks/{chunk-QDBFZQ2P.js → chunk-BBLE5DMP.js} +1 -1
- package/dist-cli/chunks/{chunk-3OU23VHJ.js → chunk-BZH7FKZZ.js} +73 -12
- package/dist-cli/chunks/{chunk-5YSLVAQO.js → chunk-C3VO2MSV.js} +2 -2
- package/dist-cli/chunks/{chunk-2KH3XP25.js → chunk-CHHBZJBH.js} +1 -1
- package/dist-cli/chunks/{chunk-W3XLQMHS.js → chunk-DE6JMHEW.js} +2 -2
- package/dist-cli/chunks/{chunk-VCYQZSOW.js → chunk-EIAYJLBW.js} +2 -2
- package/dist-cli/chunks/{chunk-MAFA2R2B.js → chunk-FCRJNHIA.js} +1 -1
- package/dist-cli/chunks/{chunk-WGFN4X7U.js → chunk-FUUXRMXG.js} +2 -2
- package/dist-cli/chunks/{chunk-QK5KDLOL.js → chunk-GEPWAAGG.js} +2 -2
- package/dist-cli/chunks/{chunk-A3RAHXFP.js → chunk-H4F45EGT.js} +2 -2
- package/dist-cli/chunks/{chunk-RRGMPOCZ.js → chunk-HPTOFA3Y.js} +3 -3
- package/dist-cli/chunks/chunk-IKVDJYRI.js +2 -0
- package/dist-cli/chunks/{chunk-YW6R4AZS.js → chunk-J6UPVQ37.js} +2 -2
- package/dist-cli/chunks/{chunk-5PU4UF46.js → chunk-JFHETXYV.js} +1 -1
- package/dist-cli/chunks/{chunk-WETDSNVK.js → chunk-JP3PNWTD.js} +1 -1
- package/dist-cli/chunks/{chunk-QBRJUGX4.js → chunk-LB7BYFMF.js} +2 -2
- package/dist-cli/chunks/{chunk-UFM5KZV5.js → chunk-MJQXUHDS.js} +2 -2
- package/dist-cli/chunks/{chunk-2R6ISGHK.js → chunk-MNILEOSP.js} +1 -1
- package/dist-cli/chunks/{chunk-L2353XE5.js → chunk-O552XDE7.js} +2 -2
- package/dist-cli/chunks/{chunk-U6CXSNU5.js → chunk-O7SJH4E7.js} +2 -2
- package/dist-cli/chunks/{chunk-UNGEGYXQ.js → chunk-OS62SSOF.js} +2 -2
- package/dist-cli/chunks/{chunk-LP46VFFE.js → chunk-QMU4MAG3.js} +1 -1
- package/dist-cli/chunks/{chunk-GJB3233O.js → chunk-RAWQNHKI.js} +1 -1
- package/dist-cli/chunks/{chunk-6YPNZR54.js → chunk-RF2STDGD.js} +2 -2
- package/dist-cli/chunks/chunk-RIMNMM3O.js +1 -0
- package/dist-cli/chunks/{chunk-JSIQX4RC.js → chunk-SSQWBV2F.js} +2 -2
- package/dist-cli/chunks/{chunk-IIPXHHCA.js → chunk-TGLPBQ4D.js} +2 -2
- package/dist-cli/chunks/{chunk-JH3UHLET.js → chunk-TUJWNKG4.js} +1 -1
- package/dist-cli/chunks/{chunk-GF3PTYUG.js → chunk-WNK5XRWG.js} +2 -2
- package/dist-cli/chunks/{chunk-PC6MD7KR.js → chunk-XYT2OO4N.js} +2 -2
- package/dist-cli/chunks/{chunk-D2HFLNQK.js → chunk-YBRJSW5C.js} +3 -3
- package/dist-cli/chunks/chunk-YPLXVVG4.js +1 -0
- package/dist-cli/chunks/{chunk-N6A3DLGD.js → chunk-YZ6MQTDJ.js} +2 -2
- package/dist-cli/chunks/{chunk-SLBI37WD.js → chunk-ZX4FJNIW.js} +1 -1
- package/dist-cli/chunks/cli-version-JKOW3OL3.js +2 -0
- package/dist-cli/chunks/{compat-3RY7MNRD.js → compat-3C3O2TKY.js} +3 -3
- package/dist-cli/chunks/{config-3B4KNHNB.js → config-TEO7DXWJ.js} +2 -2
- package/dist-cli/chunks/control-UUSQA7VO.js +2 -0
- package/dist-cli/chunks/{cpu-profile-ZH2TY3EB.js → cpu-profile-QSFGY7HA.js} +2 -2
- package/dist-cli/chunks/{daemon-IUAIVTIM.js → daemon-R2TQX4HR.js} +2 -2
- package/dist-cli/chunks/{debug-BEFVOWIO.js → debug-UMLASBX2.js} +3 -3
- package/dist-cli/chunks/{detox-HPNYBEKZ.js → detox-Y6TFEKQU.js} +2 -2
- package/dist-cli/chunks/{device-ZBDEEYN6.js → device-4NBQC4LP.js} +2 -2
- package/dist-cli/chunks/{diagnose-D5CLXJP7.js → diagnose-DKXPE4P6.js} +2 -2
- package/dist-cli/chunks/drivers-TFUZRRDZ.js +2 -0
- package/dist-cli/chunks/{electron-HDDFR27N.js → electron-3AZTVV3N.js} +3 -3
- package/dist-cli/chunks/flow-744L27RP.js +2 -0
- package/dist-cli/chunks/help-JUP3UEFR.js +2 -0
- package/dist-cli/chunks/{hints-NOGPSCHT.js → hints-K323Q4NQ.js} +2 -2
- package/dist-cli/chunks/{home-paths-IQNPKC6L.js → home-paths-H7GUBJAB.js} +2 -2
- package/dist-cli/chunks/{inspect-EGBGTKVK.js → inspect-UJFYMPE5.js} +52 -51
- package/dist-cli/chunks/install-D5J5LA2V.js +2 -0
- package/dist-cli/chunks/{install-desktop-SVGXW4NS.js → install-desktop-NT5QJIPD.js} +3 -3
- package/dist-cli/chunks/{keys-6ZOTMI56.js → keys-OJVAQQK5.js} +2 -2
- package/dist-cli/chunks/{launch-IQGYTPQM.js → launch-VMMQENF6.js} +3 -3
- package/dist-cli/chunks/{login-J4U23Q3R.js → login-CRJE2OZK.js} +4 -4
- package/dist-cli/chunks/{logout-H6K35NLA.js → logout-3DXVRPLM.js} +2 -2
- package/dist-cli/chunks/{maestro-QO2LITVQ.js → maestro-FPDCZ3NO.js} +2 -2
- package/dist-cli/chunks/{preview-Q4W6QO7P.js → preview-7WLF767D.js} +2 -2
- package/dist-cli/chunks/{profile-2QJPFSDY.js → profile-DE5LJZ5Y.js} +2 -2
- package/dist-cli/chunks/{react-DXK7ST5T.js → react-HLRPZFFH.js} +2 -2
- package/dist-cli/chunks/{record-UG6W5IME.js → record-VQAG2YYZ.js} +2 -2
- package/dist-cli/chunks/runtime-LBAJOT4M.js +2 -0
- package/dist-cli/chunks/{runtime-delivery-RAZ445Y5.js → runtime-delivery-O2WD2RT6.js} +2 -2
- package/dist-cli/chunks/{screenshot-Q44UHEGZ.js → screenshot-HYSJVWYN.js} +2 -2
- package/dist-cli/chunks/{screenshot-mode-I2TYYAON.js → screenshot-mode-ME7WKY7S.js} +2 -2
- package/dist-cli/chunks/{screenshots-GGLAOVD7.js → screenshots-5MY3SHOW.js} +2 -2
- package/dist-cli/chunks/{server-3IPGETBZ.js → server-LRSX4VKM.js} +2 -2
- package/dist-cli/chunks/setup-repo-5FHT7B6J.js +2 -0
- package/dist-cli/chunks/{skills-BCFKQBDG.js → skills-SHJHDYYU.js} +2 -2
- package/dist-cli/chunks/{start-WVYUD6CH.js → start-FBIHKRWV.js} +4 -4
- package/dist-cli/chunks/store-ZSAUNVP6.js +2 -0
- package/dist-cli/chunks/telemetry-E2ZAX2C6.js +2 -0
- package/dist-cli/chunks/{test-ZATFIL25.js → test-W5VLOO6C.js} +3 -3
- package/dist-cli/chunks/{three-mode-B7MYORNU.js → three-mode-OILRSRAU.js} +2 -2
- package/dist-cli/chunks/{timeline-SDEOHHGZ.js → timeline-H4SFNSBA.js} +2 -2
- package/dist-cli/chunks/{upgrade-MMU63PN3.js → upgrade-4SYAHMAP.js} +2 -2
- package/dist-cli/chunks/upload-NPGWC7E5.js +2 -0
- package/dist-cli/chunks/{web-BXAEFDAJ.js → web-UXTXQNYW.js} +2 -2
- package/dist-cli/chunks/{what-happened-7PASTCPU.js → what-happened-SNC6DEIJ.js} +2 -2
- package/dist-cli/chunks/{whoami-26VWXEUX.js → whoami-QDFN5LHP.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 +92 -1
- package/dist-lib/sdk.mjs +89 -1
- 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-4T7P2AEZ.js +0 -2
- package/dist-cli/chunks/beta-XPL4OA73.js +0 -2
- package/dist-cli/chunks/chunk-2TJIYYD6.js +0 -1
- package/dist-cli/chunks/chunk-JAR6ZK7S.js +0 -2
- package/dist-cli/chunks/chunk-JWC43Q7G.js +0 -1
- package/dist-cli/chunks/chunk-RHTOXVIQ.js +0 -1
- package/dist-cli/chunks/cli-version-5RR6YSLC.js +0 -2
- package/dist-cli/chunks/control-NE52GBD2.js +0 -2
- package/dist-cli/chunks/drivers-GTB2MH7E.js +0 -2
- package/dist-cli/chunks/flow-QYL7HHKN.js +0 -2
- package/dist-cli/chunks/help-LMXH2UHV.js +0 -2
- package/dist-cli/chunks/install-Q2JJJBNC.js +0 -2
- package/dist-cli/chunks/runtime-72QZY6P4.js +0 -2
- package/dist-cli/chunks/setup-repo-UR2N2LUC.js +0 -2
- package/dist-cli/chunks/store-7NUGDP6M.js +0 -2
- package/dist-cli/chunks/telemetry-PXZEDDM5.js +0 -2
- package/dist-cli/chunks/upload-SLNXXIBH.js +0 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
2
|
-
import{a as G}from"./chunk-
|
|
3
|
-
`)}function
|
|
1
|
+
/*! sootsim v0.1.119 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
|
+
import{a as G}from"./chunk-MJQXUHDS.js";import{a as bt,b as wt}from"./chunk-MNILEOSP.js";import{a as Ke,h as we,k as ee}from"./chunk-3MWC6EE2.js";import{b as xt,c as $t,j as St}from"./chunk-J6UPVQ37.js";import"./chunk-5OZHLK4L.js";import{a as Z,b as A,c as P,d as Oe,e as re,f as Y,g as ce,h as pe,i as gt,j as yt,k as Ae,l as ht}from"./chunk-OS62SSOF.js";import{D as mt,F as le,G as pt,M as ft,a as be,b as ze,c as Ye,d as Ge,e as Xe,f as Ve,g as Qe,h as Ze,i as et,j as tt,k as Ne,l as Fe,p as _e,q as ot,r as st,s as nt,t as rt,u as it,v as at,w as lt,x as ct,y as dt,z as ut}from"./chunk-BZH7FKZZ.js";import"./chunk-H4F45EGT.js";import{c as We,e as qe,f as He,g as Ue,h as Ie}from"./chunk-WNK5XRWG.js";import"./chunk-C3VO2MSV.js";import"./chunk-JP3PNWTD.js";import"./chunk-RIMNMM3O.js";import"./chunk-TGLPBQ4D.js";import"./chunk-CHHBZJBH.js";import{b as Le}from"./chunk-RAWQNHKI.js";import{a as je}from"./chunk-4KU7AIP7.js";import{a as Te,c as Me}from"./chunk-XYT2OO4N.js";import{a as Je}from"./chunk-IKVDJYRI.js";import"./chunk-QMU4MAG3.js";import"./chunk-ZX4FJNIW.js";import"./chunk-AUKEEPZT.js";import{existsSync as lo,mkdirSync as co,readFileSync as uo,rmSync as vt,writeFileSync as mo}from"fs";import{tmpdir as po}from"os";import{dirname as fo,join as go,resolve as yo}from"path";var fe=1,ho="SOOTSIM_INSPECT_NOTICE_PATH",bo=300*1e3,wo=15e3;function kt(){return yo(process.env[ho]||go(po(),"sootsim-inspect-notice-state.json"))}function xo(e,c){return Object.fromEntries(Object.entries(e).filter(([,n])=>typeof n?.signature=="string"&&Number.isFinite(n?.updatedAt)&&c-n.updatedAt<=bo))}function $o(e){let c=kt();if(!lo(c))return{version:fe,entries:{}};try{let n=JSON.parse(uo(c,"utf8"));return n.version!==fe||!n.entries||typeof n.entries!="object"?(vt(c,{force:!0}),{version:fe,entries:{}}):{version:fe,entries:xo(n.entries,e)}}catch{return vt(c,{force:!0}),{version:fe,entries:{}}}}function So(e){let c=kt();co(fo(c),{recursive:!0}),mo(c,JSON.stringify(e,null,2)+`
|
|
3
|
+
`)}function vo(e,c){let n=c.trim()||"default";return`${e}:${n}`}function Pe(e,c,n,l={}){let m=l.nowMs??Date.now(),a=l.cooldownMs??wo,g=$o(m),y=vo(e,c),T=g.entries[y];return T&&T.signature===n&&m-T.updatedAt<a?!1:(g.entries[y]={signature:n,updatedAt:m},So(g),!0)}var ko={initialWaitMs:3e3,deadlineMs:5e3,retryWaitMs:700},To={initialWaitMs:1200,deadlineMs:2500,retryWaitMs:700};function Mo(e,c={}){return{...e?ko:To,...c}}function de(e){return!(!e||e.hit===!1||e.ok===!1||e.pointerTapHandled===!1&&!e.keyboardOpened&&!e.isTextInput)}function Io(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=Mo(!!c.agent,c.timing),l=0,m=null,a=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:Io(y,c.textFallback)});if(a=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:a,attempts:l,failure:m&&typeof m.cx=="number"?"missed":"not-found"}}async function Tt(e,c,n,l){return e.send({type:"tap",x:c,y:n,...l?{target:l}:{}})}async function Mt(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}))
|
|
@@ -42,7 +42,7 @@ import{a as G}from"./chunk-UFM5KZV5.js";import{a as yt,b as ht}from"./chunk-2R6I
|
|
|
42
42
|
},
|
|
43
43
|
strategy: (resolved && resolved.strategy) || 'matched-node',
|
|
44
44
|
}
|
|
45
|
-
})()`})})}async function
|
|
45
|
+
})()`})})}async function It(e,c,n={},l={}){let m=JSON.stringify({query:c,exact:!!n.exact,role:n.role??null,within:n.within??null,minX:n.minX??null,maxX:n.maxX??null,minY:n.minY??null,maxY:n.maxY??null,near:n.near??null,nth:n.nth??null,first:!!n.first});return ge(e,{agent:l.agent,timing:l.timing,textFallback:c,resolve:()=>e.send({type:"evaluate",code:`(async () => {
|
|
46
46
|
const t = window.__sootsimTest
|
|
47
47
|
if (!t) return { error: 'bridge-not-ready' }
|
|
48
48
|
const F = ${m}
|
|
@@ -162,7 +162,7 @@ import{a as G}from"./chunk-UFM5KZV5.js";import{a as yt,b as ht}from"./chunk-2R6I
|
|
|
162
162
|
total,
|
|
163
163
|
idx,
|
|
164
164
|
}
|
|
165
|
-
})()`})})}async function
|
|
165
|
+
})()`})})}async function Nt(e,c,n={}){let l=JSON.stringify(c);return ge(e,{agent:n.agent,timing:n.timing,textFallback:c,resolve:async()=>{let m=await e.send({type:"evaluate",code:`(async () => {
|
|
166
166
|
const t = window.__sootsimTest
|
|
167
167
|
if (!t) return { error: 'bridge-not-ready' }
|
|
168
168
|
const byTestId =
|
|
@@ -197,15 +197,16 @@ import{a as G}from"./chunk-UFM5KZV5.js";import{a as yt,b as ht}from"./chunk-2R6I
|
|
|
197
197
|
}
|
|
198
198
|
}
|
|
199
199
|
return { strategy: 'none' }
|
|
200
|
-
})()`});if(!m||!("node"in m))return m;let a=m.node,g=a.absolutePosition.x+a.layout.width/2,y=a.absolutePosition.y+a.layout.height/2;return{...m,cx:g,cy:y,target:{id:a.id,testID:a.testID,text:m.strategy==="text"?c:a.text,type:a.type}}}})}async function
|
|
200
|
+
})()`});if(!m||!("node"in m))return m;let a=m.node,g=a.absolutePosition.x+a.layout.width/2,y=a.absolutePosition.y+a.layout.height/2;return{...m,cx:g,cy:y,target:{id:a.id,testID:a.testID,text:m.strategy==="text"?c:a.text,type:a.type}}}})}async function Ft(e,c={args:[]}){let n=await Ye(e);if(A(c.args)){P(n);return}console.log(` nodes: ${n.nodes}`)}function Re(e,c){let n=e.indexOf(c);return n>=0&&n+1<e.length?e[n+1]:null}async function _t(e){let{bridge:c,args:n,positional:l}=e,m=n.includes("--verbose")||n.includes("-v"),a=A(n),g=m&&!a,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=Re(n,"--testid-like"),R=Re(n,"--only"),j=Re(n,"--subtree"),d=l[1]&&!l[1].startsWith("-")?l[1]:void 0,z=d?/[*?]/.test(d):!1,B=!z&&!R?d:void 0,C=R??(z?d:void 0),V=async()=>{await ce(c,{verbose:g});let S=await Ve(c,{describe:!0,verbose:m,filter:B||"",testIdLike:I||void 0,onlyGlob:C||void 0,subtreeRoot:j||void 0,compact:M,hideXy:h,includeOccluded:_}),N=S?.tree,L=S?.shell,W=S?.keyboard;if(a){P({shell:L,tree:N??"",keyboard:W});return}if(L&&typeof L=="object"){let D=[L.state?`state=${L.state}`:null,L.activeApp?`app=${L.activeApp}`:null,L.showSwitcher?"switcher":null,L.switcherPhase&&L.switcherPhase!=="idle"?`phase=${L.switcherPhase}`:null].filter(Boolean);D.length>0&&console.log(` shell: ${D.join(" ")}`)}if(typeof N=="string"&&N.startsWith("__SUBTREE_NOT_FOUND__:")){let D=N.slice(22);console.log(` subtree root not found: ${D}`),G("subtree-root-not-found",D);return}if(!N){let D=S?.nodeCount??0;console.log(" no matching nodes found"),!(B||I||C||j)&&D<10&&G("app-still-loading",D);return}let X=N,Q=0;if(k&&typeof X=="string"){let D=X.split(`
|
|
201
201
|
`),ae=[];for(let o of D){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||C||j;if((B||I||C)&&!y&&G("describe-filter-context"),!ne&&!y&&N.split(`
|
|
203
203
|
`).length>=80&&G("describe-use-filters"),W&&W.visible){let D=W.spec,ae=[D?.keyboardType?`type=${D.keyboardType}`:null,D?.returnKeyType&&D.returnKeyType!=="default"?`return=${D.returnKeyType}`:null,W.mode!=="letters"?`mode=${W.mode}`:null,W.shifted?"shift":null,W.capsLock?"caps":null,D?.autoCapitalize&&D.autoCapitalize!=="sentences"?`autoCap=${D.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
|
|
205
|
+
`);;)console.clear(),await V(),await Z(T);else await V()}var No=["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 No){let c=process.env[e];if(c&&c.trim()&&c!=="0")return!0}return!1}async function Ot(e){let{bridge:c,args:n,effectiveArgs:l,positional:m,inspectUsage:a}=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 tt(c,{testId:T,role:M,type:h,text:d,pressable:_,visible:I,interactive:R});z||(console.error(a("find","<text> | --text <t> | --testid <id> | --role <r> | --type <t> | --pressable | --visible | --interactive-targets")),process.exit(1));let{mode:B,result:C}=z,V=A(n),te=n.includes("--verbose")||n.includes("--dump");if(V)B==="interactive-targets"&&Array.isArray(C)?P(Ne(C).map(S=>({...S,tap:Fe(S)}))):P(C??null);else if(Array.isArray(C))if(C.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=Ne(C);console.log(` found ${S.length} interactive target${S.length===1?"":"s"} (sorted by score):`);for(let N of S.slice(0,20)){let L=N.absolutePosition?`@(${Math.round(N.absolutePosition.x)},${Math.round(N.absolutePosition.y)})`:"",W=N.layout?`${Math.round(N.layout.width)}x${Math.round(N.layout.height)}`:"?x?",X=N.text?` "${N.text.slice(0,30)}"`:"",Q=N.testID?` #${N.testID}`:"",ne=N.accessibilityLabel?` \u24D8"${String(N.accessibilityLabel).slice(0,24)}"`:"",me=N.accessibilityRole?`[${N.accessibilityRole}]`:N.type,D=Fe(N);console.log(` ${me}${X}${ne}${Q} ${W} ${L}`),console.log(` \u2192 ${D}`),te&&console.log(Ee(JSON.stringify(N,null,2)," "))}S.length>20&&console.log(` ... and ${S.length-20} more`)}else{console.log(` found ${C.length} node${C.length===1?"":"s"} (${B}):`);for(let S of C.slice(0,20)){let N=S.absolutePosition?`@(${Math.round(S.absolutePosition.x)},${Math.round(S.absolutePosition.y)})`:"",L=S.layout?`${Math.round(S.layout.width)}x${Math.round(S.layout.height)}`:"?x?",W=S.text?` "${S.text.slice(0,30)}"`:"",X=S.testID?` #${S.testID}`:"",Q=S.pressable?" (tap)":"",ne=S.accessibilityRole?`[${S.accessibilityRole}]`:S.type;console.log(` ${ne}${W}${X} ${L} ${N}${Q}`),te&&console.log(Ee(JSON.stringify(S,null,2)," "))}C.length>20&&console.log(` ... and ${C.length-20} more`)}else if(C==null)console.log(` not found: ${d||T||M||h||""||B}`),T&&G("wait-selector-for-missing-testid",T);else{let S=C;if(S.type&&S.absolutePosition){let N=`@(${Math.round(S.absolutePosition.x)},${Math.round(S.absolutePosition.y)})`,L=S.layout?`${Math.round(S.layout.width)}x${Math.round(S.layout.height)}`:"?x?",W=S.text?` "${S.text.slice(0,40)}"`:"",X=S.testID?` #${S.testID}`:"",Q=S.pressable?" (tap)":"",ne=S.accessibilityRole?`[${S.accessibilityRole}]`:S.type;console.log(` ${ne}${W}${X} ${L} ${N}${Q}`),te&&console.log(Ee(JSON.stringify(S,null,2)," "))}else console.log(JSON.stringify(C,null,2))}}function Ee(e,c){return e.split(`
|
|
206
206
|
`).map(n=>c+n).join(`
|
|
207
|
-
`)}async function
|
|
208
|
-
`))}async function
|
|
207
|
+
`)}async function At(e){let{bridge:c,args:n}=e,l=A(n);await ce(c,{verbose:!l});let m=await Qe(c);if(l){P({count:m.length,elements:m});return}console.log(` layout (${m.length} element${m.length===1?"":"s"}):
|
|
208
|
+
`),console.log(Ze(m))}async function Pt(e,c={}){let n=await mt(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:a,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: ${a}${g?" (shifted)":""}${y?" (caps)":""}`),T&&M.push(` accessoryBar: ${T}`),console.log(M.join(`
|
|
209
|
+
`))}async function Rt(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"),a=e.args.includes("--primary"),g=c.filter(y=>!(a&&!y.isPrimary||l&&!(y.url??"").includes(l)||m&&!(y.url??"").includes(`/rn/${m}`)||!n&&!l&&!m&&!a&&!(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}St(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 xe(e,c){return c<=0?"?":`${(e/c*100).toFixed(0)}%`}async function Et(e,c={args:[]}){let n=await ft(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} (${xe(l.cacheEntries,l.cacheMaxEntries)})`),console.log(` pixel bytes: ${ie(l.cachePixelBytes)} / ${ie(l.cachePixelBudget)} (${xe(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)} (${xe(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)} (${xe(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 $e(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 () => {
|
|
209
210
|
const t = window.__sootsimTest
|
|
210
211
|
if (!t) return null
|
|
211
212
|
const n = ${l}
|
|
@@ -230,15 +231,15 @@ import{a as G}from"./chunk-UFM5KZV5.js";import{a as yt,b as ht}from"./chunk-2R6I
|
|
|
230
231
|
text: ${JSON.stringify(c.mode==="text")} ? ${n} : (n.text ?? n.accessibilityLabel ?? null),
|
|
231
232
|
type: n.type ?? null,
|
|
232
233
|
}
|
|
233
|
-
})()`})??null}async function
|
|
234
|
-
`))}async function
|
|
234
|
+
})()`})??null}async function Ct(e,c={}){let{nav:n,keyboard:l,shell:m}=await pt(e);if(c.json){console.log(JSON.stringify({shell:m??null,nav:n,keyboard:l},null,2));return}let a=[];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)}%)`:"";a.push(`shell: ${g}${y}${T}`)}else a.push("shell: <unavailable>");if(n){let g=n.transitionPhase!=="idle"?` (${n.transitionPhase}, ${n.activeTransitionCount} active)`:"";if(a.push(`nav: phase=${n.transitionPhase}${g}`),n.screens.length===0)a.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}`:"";a.push(` ${T} #${y.id}${M}${h}${k}`)}}else a.push("nav: <runtime not available>");if(l&&l.visible){let g=l.spec?.keyboardType??"default",y=l.spec?.returnKeyType??"default";a.push(`keyboard: visible (${g}, return=${y}, mode=${l.mode??"?"})`)}else a.push("keyboard: hidden");console.log(a.join(`
|
|
235
|
+
`))}async function Dt(e){let{bridge:c,args:n,positional:l}=e,m=l[1]?Number(l[1])*1e3:3e3,a=n.includes("--strict"),{elapsed:g,settled:y}=await ee({bridge:c,maxMs:m,strict:a});console.log(y?` settled in ${g}ms`:` timed out after ${g}ms (may still be animating)`)}async function Bt(e){let c=e.positional[1]?Number(e.positional[1]):.5;(!Number.isFinite(c)||c<0)&&(console.error(e.inspectUsage("sleep","[seconds]")),process.exit(1)),await Z(c*1e3),console.log(` slept ${c}s`)}async function jt(e){let{bridge:c,args:n,positional:l}=e,m=l[1]?Number(l[1]):5,{tree:a}=await Ge(c,m);if(A(n)){P({depth:m,tree:a??null});return}console.log(typeof a=="string"?a:JSON.stringify(a,null,2))}async function Jt(e,c={args:[]}){let n=await Xe(e);if(A(c.args)){P(n);return}console.log(n.url)}async function Lt(e){let{wsPort:c,commandTimeoutMs:n,simId:l,simIdSource:m,positional:a}=e,g=a[1]?Number(a[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 gt(c,n,l,{attempts:T,simIdSource:m});M||(console.error(" timed out waiting for sim reconnect"),process.exit(1)),M.bridge.close(),we({source:"inspect wait",step:{wait:y},summary:`wait ${Math.round(y/1e3)}s`}),console.log(` ready: ${M.count} nodes`)}var Wt=new Set(["app-launch","toast","keyboard","screen","route","alert","actionsheet","picker","notification","fetch","console","shell","scroll","gesture","text-input","react-commit","animation","reanimated"]);function Se(e,c){let n=e.indexOf(c);if(n>=0&&n+1<e.length)return e[n+1]}function Fo(e,c){if(!c.filter&&!c.equals)return!0;let n=e.data,l=[];if(n&&typeof n=="object")for(let a of["url","displayUrl","message","name","activeName","path","pathname","title","phase","event","type","kind"]){let g=n[a];typeof g=="string"&&g.length>0&&l.push(g)}let m=l.join(" ");return c.equals?l.some(a=>a===c.equals):c.filter?m.toLowerCase().includes(c.filter.toLowerCase()):!0}async function qt(e){let{bridge:c,args:n,positional:l,inspectUsage:m}=e,a=l[1];a||(console.error(m("wait event","<kind> [--max-ms 5000] [--filter <substring>] [--equals <exact>] [--since now|cursor]")),process.exit(1)),Wt.has(a)||console.error(` warning: '${a}' is not a known timeline kind \u2014 waiting anyway. known: ${[...Wt].sort().join(", ")}`);let g=Se(n,"--max-ms"),y=g&&Number.isFinite(Number(g))?Math.max(100,Number(g)):5e3,T=Se(n,"--filter"),M=Se(n,"--equals"),h=Se(n,"--since")??"now",k=n.includes("--json"),_=Date.now(),I=_+y,R=200,j=_;for(;Date.now()<I;){let z={kinds:[a],since:h==="cursor"?void 0:j,limit:50},B=await c.send({type:"evaluate",code:`(async () => {
|
|
235
236
|
const t = window.SootSim?.bridges?.timeline
|
|
236
237
|
if (!t) return { ok: false, error: 'timeline bridge missing' }
|
|
237
238
|
return { ok: true, result: await t.recent(${JSON.stringify(z)}) }
|
|
238
|
-
})()`});(!B||!B.ok)&&(console.error(` could not query timeline: ${B&&"error"in B?B.error:"unknown"}`),process.exit(1));let C=B.result.events??[];for(let V of C)if(
|
|
239
|
+
})()`});(!B||!B.ok)&&(console.error(` could not query timeline: ${B&&"error"in B?B.error:"unknown"}`),process.exit(1));let C=B.result.events??[];for(let V of C)if(Fo(V,{filter:T,equals:M})){let te=Date.now()-_;console.log(k?JSON.stringify({found:!0,elapsedMs:te,event:V}):` ${a} 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:a,filter:T,equals:M})):console.error(` \u26A0 wait event ${a} timed out after ${d}ms${T?` (filter: ${T})`:""}${M?` (equals: ${M})`:""}`),process.exit(1)}async function Ht(e){let{bridge:c,args:n}=e,l=n.includes("--strict"),m=be(n,3e3),{elapsed:a,settled:g}=await ee({bridge:c,maxMs:m,strict:l});g?console.log(` idle in ${a}ms`):(console.error(` \u26A0 wait idle timed out after ${a}ms (may still be animating)`),process.exit(1))}async function Ut(e){let{bridge:c,args:n}=e,l=be(n,2e4),{ready:m,elapsedMs:a,nodes:g,targets:y,flag:T,loadingText:M,externalReady:h,externalError:k,errors:_}=await ot(c,l,{onProgress(R){console.error(` still waiting after ${R.elapsedMs}ms \u2014 ${_e(R)} (nodes: ${R.nodes}, targets: ${R.targets}, errors: ${R.errors})`)}});if(m){let R=l-a,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 ${a+d.elapsed}ms \u2014 app mounted but did not settle (nodes: ${g}, targets: ${y})`),process.exit(1)),console.log(` ready in ${a+d.elapsed}ms: ${g} nodes, ${y} targets`);return}let I=_e({externalError:k,loadingText:M,externalReady:h,flag:T,targets:y});console.error(` \u26A0 wait ready timed out after ${a}ms \u2014 ${I} (nodes: ${g}, targets: ${y}, errors: ${_})`),process.exit(1)}async function Kt(e){let{bridge:c,args:n,positional:l,inspectUsage:m}=e,a=l[1];a||(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 st(c,a,y,{gone:T});if(T){M?console.log(` #${a} gone after ${k}ms`):(console.error(` \u26A0 wait selector #${a} --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 #${a} in ${k}ms ${I} ${_}`)}else console.error(` \u26A0 wait selector #${a} timed out after ${k??y}ms`),process.exit(1)}function eo(e){return e==null?"\u2014":e<1024?`${e}B`:e<1024*1024?`${(e/1024).toFixed(1)}K`:`${(e/1024/1024).toFixed(1)}M`}function to(e){return e==null?" \u2026":e<1e3?`${e}ms`.padStart(5):`${(e/1e3).toFixed(2)}s`.padStart(5)}function zt(){process.stderr.write(` the sim is not responding. recover it with:
|
|
239
240
|
sootsim close --sim <id> # force-close the wedged sim
|
|
240
241
|
sootsim list # confirm it's gone
|
|
241
|
-
`)}async function
|
|
242
|
+
`)}async function Oo(e){try{return await e.send({type:"evaluate",code:"1"},{timeoutMs:3e3}),!0}catch{return!1}}async function Ao(e,c){try{let n=await e.send({type:"evaluate",code:`(async () => {
|
|
242
243
|
const t = window.__sootsimTest
|
|
243
244
|
if (!t || typeof t.queryAll !== 'function') return []
|
|
244
245
|
try {
|
|
@@ -257,8 +258,8 @@ import{a as G}from"./chunk-UFM5KZV5.js";import{a as yt,b as ht}from"./chunk-2R6I
|
|
|
257
258
|
} catch {
|
|
258
259
|
return []
|
|
259
260
|
}
|
|
260
|
-
})()`});if(!Array.isArray(n)||n.length===0)return;let l=c.toLowerCase(),m=n.map(a=>({id:a,score:
|
|
261
|
-
`).slice(0,5);for(let g of a)console.log(` ${g.trim()}`)}}var se="__sootsimCliPerf",
|
|
261
|
+
})()`});if(!Array.isArray(n)||n.length===0)return;let l=c.toLowerCase(),m=n.map(a=>({id:a,score:Po(l,a.toLowerCase())})).filter(a=>a.score<l.length+4).sort((a,g)=>a.score-g.score).slice(0,5);if(m.length===0)return;console.error(" similar testIDs:");for(let a of m)console.error(` ${a.id}`)}catch{}}function Po(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 Ro(e,c)-n}function Ro(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 a=n;n=l,l=a}return n[c.length]}function Eo(e){return e.error?"err":e.status==null?" \u2026 ":String(e.status)}function Co(e){return e.externalError?`guest app errored: ${e.externalError}`:e.loadingText?`still showing "${e.loadingText}"`:e.externalReady===!1?"guest app is still loading":e.flag!==!0?"guest app has not emitted sootsim:externalAppReady":e.targets<=0?"ready flag emitted but no visible app content is inspectable yet":"node tree is still changing"}function Yt(e){let c=re(e.startTs),n=Eo(e).padEnd(3),l=e.method.padEnd(5),m=eo(e.size).padStart(6),a=to(e.durationMs);console.log(` [${c}] ${n} ${l} ${m} ${a} ${e.displayUrl}`),e.error&&console.log(` error: ${e.error}`)}function Do(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",to(e.durationMs).trim()],["size",eo(e.size)],["content-type",e.type??"\u2014"]];for(let[n,l]of c)console.log(` ${n.padEnd(13)} ${l}`)}var Bo={error:"\x1B[31m",warn:"\x1B[33m",info:"\x1B[36m",debug:"\x1B[35m",log:"\x1B[37m"},Gt="\x1B[0m",jo="\x1B[2m";function Xt(e,c){let n=re(e.ts),l=e.level.toUpperCase().padEnd(5),m=e.args.join(" ");if(c){let a=Bo[e.level];console.log(` ${jo}[${n}]${Gt} ${a}${l}${Gt} ${m}`)}else console.log(` [${n}] ${l} ${m}`);if(e.stack&&e.level==="error"){let a=e.stack.split(`
|
|
262
|
+
`).slice(0,5);for(let g of a)console.log(` ${g.trim()}`)}}var se="__sootsimCliPerf",Jo=120;async function Vt(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:bt({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 a=_=>{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=a("--x"),y=a("--y"),T=a("--w"),M=a("--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 Ce(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 ve(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 Be(e){return e.send({type:"evaluate",code:`(async () => {
|
|
262
263
|
const kb = window.__sootsimKeyboard
|
|
263
264
|
const test = window.__sootsimTest
|
|
264
265
|
if (!kb) return { error: 'keyboard bridge not available' }
|
|
@@ -290,7 +291,7 @@ import{a as G}from"./chunk-UFM5KZV5.js";import{a as yt,b as ht}from"./chunk-2R6I
|
|
|
290
291
|
frame: runtimeSnapshot?.keyboard?.frame ?? null,
|
|
291
292
|
focusedRect: runtimeSnapshot?.focused?.rect ?? null,
|
|
292
293
|
}
|
|
293
|
-
})()`})}async function
|
|
294
|
+
})()`})}async function Lo(e,c=600){let n=Date.now()+c;for(;Date.now()<=n;){let l=await Be(e);if(l.visible)return l;await Z(30)}return Be(e)}async function ke(e,c){let n=await Be(e);if(n.visible)return n;console.error(` ${c} requires the iOS keyboard to be visible. focus an input first with sootsim do tap-id/tap-text or sootsim do type-into.`),process.exit(1)}async function Qt(e,c,n){return c==="appearance"?e.send({type:"evaluate",code:`(async () => {
|
|
294
295
|
const requested = ${JSON.stringify(n??"toggle")}
|
|
295
296
|
const rootBg = (document.documentElement?.style?.background || '').toLowerCase()
|
|
296
297
|
const inferredCurrent = rootBg.includes('33') ? 'dark' : 'light'
|
|
@@ -307,15 +308,15 @@ import{a as G}from"./chunk-UFM5KZV5.js";import{a as yt,b as ht}from"./chunk-2R6I
|
|
|
307
308
|
})()`}):e.send({type:"evaluate",code:`(async () => {
|
|
308
309
|
window.dispatchEvent(new CustomEvent(${JSON.stringify(c==="lock"?"sootsim:toggleLock":"sootsim:shake")}))
|
|
309
310
|
return { ok: true, action: ${JSON.stringify(c)} }
|
|
310
|
-
})()`})}function
|
|
311
|
+
})()`})}function Wo(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 qo(e){if(typeof e!="string")return null;let c=e.replace(/\s+/g," ").trim();return c?c.slice(0,80):null}function oo(...e){for(let c of e){if(typeof c!="string")continue;let n=c.trim();if(n)return n}return null}function Ho(e){let c=e.indexOf("--node-id");if(c<0)return null;let n=e[c+1];if(!n)return null;let l=Number(n);return Number.isInteger(l)&&l>0?l:null}async function J(e,c,n){let l=we({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 Zt(e,c,n){if(!n||n.hit===!1)return null;let l=oo(n.responderTestID,n.testID);if(l)return{step:{tapOn:{id:l}},summary:`tap #${l}`};let m=qo(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 De(e,c,n){let l=oo(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 Pn(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=We(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"]}),a=m.positional,g=a[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:Je};if(y==="do"||y==="get"||y==="debug"||y==="wait"){let r=Te(y,o);r&&(console.log(`${r}
|
|
311
312
|
`),process.exit(0))}if(M==="shell"){let r=Me("shell",o);r&&(console.log(`${r}
|
|
312
313
|
`),process.exit(0))}let t=Me("inspect",o),s=["do","get","debug","wait"].map(r=>Te(r,o)).filter(r=>r!=null).join(`
|
|
313
314
|
|
|
314
315
|
`);console.log(`${t??""}
|
|
315
316
|
|
|
316
317
|
${s}
|
|
317
|
-
`),process.exit(0)}let _=m.wsPort,I=m.simId,
|
|
318
|
-
`);let s=Math.max(...t.map(i=>i.id.length),6),r=Math.max(...t.map(i=>i.kind.length),4);for(let i of t){let u=i.available?"\u2713":"\u2717",p=i.id.padEnd(s),w=i.kind.padEnd(r);console.log(` ${u} ${p} ${w} ${i.description}`),i.available&&i.detail?console.log(` ${i.detail}`):!i.available&&i.reason&&console.log(` unavailable: ${i.reason}`)}return}let d=qe(m),z=I||"default",B=new Set(["errors","warnings","requests","js","eval","reload","globals","perf","list","wait","sleep"]),C=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 r=/<title[^>]*>([^<]+)<\/title>/i.exec(o)?.[1]?.trim(),i=/<body[^>]*>([\s\S]*?)<\//i.exec(o)?.[1]?.replace(/<[^>]+>/g," ").replace(/\s+/g," ").trim().slice(0,80),u=r||i||"html error page";return`<html ${o.length}B> "${u}" (body elided \u2014 add --json for the full payload)`}return t.length<=C?t:`${t.slice(0,C)}\u2026 (+${t.length-C} 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=
|
|
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-TFUZRRDZ.js"),t=o();console.log(` available drivers (${t.length}):
|
|
319
|
+
`);let s=Math.max(...t.map(i=>i.id.length),6),r=Math.max(...t.map(i=>i.kind.length),4);for(let i of t){let u=i.available?"\u2713":"\u2717",p=i.id.padEnd(s),w=i.kind.padEnd(r);console.log(` ${u} ${p} ${w} ${i.description}`),i.available&&i.detail?console.log(` ${i.detail}`):!i.available&&i.reason&&console.log(` unavailable: ${i.reason}`)}return}let d=qe(m),z=I||"default",B=new Set(["errors","warnings","requests","js","eval","reload","globals","perf","list","wait","sleep"]),C=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 r=/<title[^>]*>([^<]+)<\/title>/i.exec(o)?.[1]?.trim(),i=/<body[^>]*>([\s\S]*?)<\//i.exec(o)?.[1]?.replace(/<[^>]+>/g," ").replace(/\s+/g," ").trim().slice(0,80),u=r||i||"html error page";return`<html ${o.length}B> "${u}" (body elided \u2014 add --json for the full payload)`}return t.length<=C?t:`${t.slice(0,C)}\u2026 (+${t.length-C} 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:r}=await ee({bridge:o,maxMs:t,pollMs:32,stablePolls:2});s||process.stderr.write(` \u26A0 auto-wait timed out after ${r??t}ms \u2014 next command may see mid-animation state. use \`sootsim do settle\` for a longer wait.
|
|
319
320
|
`)}catch{}}function N(o,t){console.error(` tap failed: ${o} stayed visible but did not receive a hittable press after ${t.attempts} attempt${t.attempts===1?"":"s"}`),t.result&&console.error(` last result: ${JSON.stringify(t.result)}`)}async function L(){try{return await d.send({type:"evaluate",code:`(() => ({
|
|
320
321
|
console: window.__sootsimConsole?.count?.() || null,
|
|
321
322
|
requests: window.__sootsimTest?.getRequestCounts?.() || null,
|
|
@@ -325,7 +326,7 @@ ${s}
|
|
|
325
326
|
`);for(let i of r){let u=re(i.timestamp);console.log(` [${u}] ${te(i)}`),i.responseBody?console.log(` ${V(i.responseBody)}`):i.error&&console.log(` ${i.error}`)}}}async function X(o={}){let t=o.counts!==void 0?o.counts:await d.send({type:"evaluate",code:"window.__sootsimConsole?.count?.() || { errors: 0, warnings: 0, total: 0 }"});if(!t||typeof t!="object")return;let s=t,r=Math.max(0,Number(s.errors)||0),i=Math.max(0,Number(s.warnings)||0);if(r===0&&i===0||!o.includeTail&&!Pe("console",z,`${r}:${i}`))return;let u=[];if(r>0&&u.push(`${r} console error${r===1?"":"s"}`),i>0&&u.push(`${i} console warning${i===1?"":"s"}`),console.log(`
|
|
326
327
|
console: ${u.join(", ")}`),console.log(` inspect: ${h("errors")} 5`),i>0&&console.log(` inspect: ${h("warnings")} 5`),!o.includeTail||r===0)return;let p=await d.send({type:"evaluate",code:"window.__sootsimConsole?.getErrors?.(5) || []"});if(!(!Array.isArray(p)||p.length===0)){console.log(`
|
|
327
328
|
recent console errors:
|
|
328
|
-
`);for(let w of p){let f=re(w.timestamp),x=Array.isArray(w.args)?w.args.map(
|
|
329
|
+
`);for(let w of p){let f=re(w.timestamp),x=Array.isArray(w.args)?w.args.map(O=>typeof O=="object"?JSON.stringify(O):String(O)).join(" "):String(w);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=Le(),s=null;try{s=await Ue(o,`(() => {
|
|
329
330
|
const tl = window.SootSim && window.SootSim.bridges && window.SootSim.bridges.timeline
|
|
330
331
|
if (!tl || typeof tl.summary !== 'function') return null
|
|
331
332
|
const cursorKey = ${JSON.stringify(t)}
|
|
@@ -342,8 +343,8 @@ ${s}
|
|
|
342
343
|
}
|
|
343
344
|
return summary ? { summary, consoleSplit } : null
|
|
344
345
|
})()`)}catch{return}if(!s||!s.summary||!s.summary.total)return;let r=s.summary.byKind??{},i=[],u=new Set;for(let p of Q){let w=r[p];if(w)if(u.add(p),p==="console"&&s.consoleSplit){let{error:f,warn:x}=s.consoleSplit;f>0&&i.push(`${f} error${f===1?"":"s"}`),x>0&&i.push(`${x} warning${x===1?"":"s"}`)}else i.push(`${w} ${p}${w===1?"":"s"}`)}for(let[p,w]of Object.entries(r))!u.has(p)&&w&&i.push(`${w} ${p}${w===1?"":"s"}`);if(i.length!==0&&(console.log(`
|
|
345
|
-
since last: ${i.join(" \xB7 ")} \u2014 sootsim what-happened`),s.summary.lastAt))try{await Ie(o,"SootSim.bridges.timeline.cursorAdvance",t,s.summary.lastAt)}catch{}}let
|
|
346
|
-
`);for(let t of o){let s=[];if(s.push(`[${t.role}]`),t.label){let r=t.label.length>50?t.label.slice(0,47)+"...":t.label;s.push(`"${r}"`)}if(t.hint&&s.push(`(hint: "${t.hint}")`),t.testID&&s.push(`#${t.testID}`),t.state){let r=[];t.state.disabled&&r.push("disabled"),t.state.selected&&r.push("selected"),t.state.checked===!0&&r.push("checked"),t.state.checked==="mixed"&&r.push("mixed"),t.state.busy&&r.push("busy"),t.state.expanded===!0&&r.push("expanded"),t.state.expanded===!1&&r.push("collapsed"),r.length&&s.push(`{${r.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
|
|
346
|
+
since last: ${i.join(" \xB7 ")} \u2014 sootsim what-happened`),s.summary.lastAt))try{await Ie(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"]),D=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 He(d),D.has(g)&&await ce(d,{verbose:ae});try{switch(g){case"list":{await Rt({bridge:d,simId:I,args:l});break}case"tree":{await jt({bridge:d,args:l,positional:a});break}case"a11y":{let o=await et(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 r=t.label.length>50?t.label.slice(0,47)+"...":t.label;s.push(`"${r}"`)}if(t.hint&&s.push(`(hint: "${t.hint}")`),t.testID&&s.push(`#${t.testID}`),t.state){let r=[];t.state.disabled&&r.push("disabled"),t.state.selected&&r.push("selected"),t.state.checked===!0&&r.push("checked"),t.state.checked==="mixed"&&r.push("mixed"),t.state.busy&&r.push("busy"),t.state.expanded===!0&&r.push("expanded"),t.state.expanded===!1&&r.push("collapsed"),r.length&&s.push(`{${r.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 Ot({bridge:d,args:e,effectiveArgs:l,positional:a,inspectUsage:k});break}case"count":{await Ft(d,{args:l});break}case"keyboard":{await Pt(d,{json:e.includes("--json")});break}case"screens":{await Ct(d,{json:e.includes("--json")});break}case"memory":{await Et(d,{args:l});break}case"wait":{await Lt({wsPort:_,commandTimeoutMs:j,simId:I,simIdSource:R,positional:a});break}case"sleep":{await Bt({positional:a,inspectUsage:k});break}case"settle":{await Dt({bridge:d,args:e,positional:a});break}case"ready":{await Ut({bridge:d,args:e});break}case"idle":{await Ht({bridge:d,args:e,positional:a});break}case"selector":{await Kt({bridge:d,args:e,positional:a,inspectUsage:k});break}case"event":{await qt({bridge:d,args:e,positional:a,inspectUsage:k});break}case"layout":{let o=a[1];if(!o){await At({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((w,f)=>e[f-1]==="--output")||"/tmp/sootsim-inspect.png",s=await Vt(e,d),r={type:"screenshot"};s&&(r.crop=s);let u=(await d.send(r)).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 Vt(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:wt(o)});if(e.includes("--json"))console.log(JSON.stringify(t,null,2));else{let{r:s,g:r,b:i,a:u,hex:p,samples:w}=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}, ${r}, ${i}, ${u}) ${f} ${w} samples`)}break}case"node":{let o=a[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 () => {
|
|
347
348
|
const t = window.__sootsimTest
|
|
348
349
|
const q = ${JSON.stringify(o)}
|
|
349
350
|
let node = null
|
|
@@ -399,17 +400,17 @@ ${s}
|
|
|
399
400
|
transform,
|
|
400
401
|
parentChain,
|
|
401
402
|
}
|
|
402
|
-
})()`});console.log(JSON.stringify(t,null,2));break}case"tap":{let o=Number(a[1]),t=Number(a[2]),s=
|
|
403
|
+
})()`});console.log(JSON.stringify(t,null,2));break}case"tap":{let o=Number(a[1]),t=Number(a[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 $e(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 w=Zt(p.cx,p.cy,u.result);w&&await J("inspect tap",w.step,w.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 r=await Tt(d,o,t),i=Zt(o,t,r);i&&await J("inspect tap",i.step,i.summary),console.log(JSON.stringify(r,null,2));break}case"drag":case"swipe":{let o=Number(a[1]),t=Number(a[2]),s=Number(a[3]),r=Number(a[4]),i=g==="swipe"?10:12,u=g==="swipe"?8:16,p=a[5]?Number(a[5]):i,w=a[6]?Number(a[6]):u;(!Number.isFinite(o)||!Number.isFinite(t)||!Number.isFinite(s)||!Number.isFinite(r)||!Number.isFinite(p)||!Number.isFinite(w))&&(console.error(k(g,"<x1> <y1> <x2> <y2> [steps] [stepMs]")),process.exit(1));let f=await d.send({type:"evaluate",code:`(async () => {
|
|
403
404
|
const interact = window.__sootsimInteract
|
|
404
405
|
if (!interact?.drag) return { ok: false, reason: 'no interact.drag' }
|
|
405
406
|
const value = await interact.drag(${o}, ${t}, ${s}, ${r}, ${Math.max(1,Math.round(p))}, ${Math.max(0,Math.round(w))})
|
|
406
407
|
return { ok: !!value, value }
|
|
407
|
-
})()`});if(f?.ok){let x=Math.max(1,Math.round(Math.max(1,p)*Math.max(0,w)));await J(`inspect ${g}`,{swipe:{start:`${o}, ${t}`,end:`${s}, ${r}`,duration:x}},`${g} ${o},${t} -> ${s},${r}`)}console.log(JSON.stringify(f,null,2));break}case"pinch":{let o=Number(a[1]),t=Number(a[2]),s=Number(a[3]),r=Number(a[4]),i=Number(a[5]),u=Number(a[6]),p=Number(a[7]),w=Number(a[8]),f=a[9]?Number(a[9]):12,x=a[10]?Number(a[10]):16;(!Number.isFinite(o)||!Number.isFinite(t)||!Number.isFinite(s)||!Number.isFinite(r)||!Number.isFinite(i)||!Number.isFinite(u)||!Number.isFinite(p)||!Number.isFinite(w)||!Number.isFinite(f)||!Number.isFinite(x))&&(console.error(k("pinch","<x1> <y1> <x2> <y2> <x1'> <y1'> <x2'> <y2'> [steps] [stepMs]")),process.exit(1));let
|
|
408
|
+
})()`});if(f?.ok){let x=Math.max(1,Math.round(Math.max(1,p)*Math.max(0,w)));await J(`inspect ${g}`,{swipe:{start:`${o}, ${t}`,end:`${s}, ${r}`,duration:x}},`${g} ${o},${t} -> ${s},${r}`)}console.log(JSON.stringify(f,null,2));break}case"pinch":{let o=Number(a[1]),t=Number(a[2]),s=Number(a[3]),r=Number(a[4]),i=Number(a[5]),u=Number(a[6]),p=Number(a[7]),w=Number(a[8]),f=a[9]?Number(a[9]):12,x=a[10]?Number(a[10]):16;(!Number.isFinite(o)||!Number.isFinite(t)||!Number.isFinite(s)||!Number.isFinite(r)||!Number.isFinite(i)||!Number.isFinite(u)||!Number.isFinite(p)||!Number.isFinite(w)||!Number.isFinite(f)||!Number.isFinite(x))&&(console.error(k("pinch","<x1> <y1> <x2> <y2> <x1'> <y1'> <x2'> <y2'> [steps] [stepMs]")),process.exit(1));let O=await d.send({type:"evaluate",code:`(async () => {
|
|
408
409
|
const interact = window.__sootsimInteract
|
|
409
410
|
if (!interact?.pinch) return { ok: false, reason: 'no interact.pinch' }
|
|
410
411
|
const value = await interact.pinch(${o}, ${t}, ${s}, ${r}, ${i}, ${u}, ${p}, ${w}, ${Math.max(1,Math.round(f))}, ${Math.max(0,Math.round(x))})
|
|
411
412
|
return { ok: !!value, value }
|
|
412
|
-
})()`});
|
|
413
|
+
})()`});O?.ok&&await J("inspect pinch",{pinch:{from:[o,t,s,r],to:[i,u,p,w],steps:Math.max(1,Math.round(f)),stepMs:Math.max(0,Math.round(x))}},`pinch (${o},${t}) (${s},${r}) -> (${i},${u}) (${p},${w})`),console.log(JSON.stringify(O,null,2));break}case"tap-text":{let o=a[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),r=t("--nth")??t("--index"),i=r!==null?Number(r):null;i!==null&&!Number.isFinite(i)&&(console.error(` --nth/--index requires an integer, got: ${r}`),process.exit(1));let u=t("--within"),p=t("--role"),w=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 b={exact:w,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:i,first:f},$=await It(d,o,b,{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)})`:"",so=E.layout?` ${E.layout.width}x${E.layout.height}`:"",no=E.testID?` #${E.testID}`:"",ro=E.text?` "${E.text}"`:"",io=E.ancestorTestIDs.length>0?` within ${E.ancestorTestIDs.slice(0,3).map(ao=>`#${ao}`).join(" > ")}`:"";console.error(` [${E.idx}] <${E.type}>${ro}${no} ${he}${so}${io}`)}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=De(o,{id:v.target?.id??null,testID:v.target?.testID??null,type:v.target?.type??null,cx:v.cx,cy:v.cy},"text");await J("inspect tap-text",oe.step,oe.summary),console.log(JSON.stringify({matched:v.match,tapped:{nodeId:v.target?.nodeId??null,id:v.target?.id??null,testID:v.target?.testID??null,type:v.target?.type??null,cx:v.cx,cy:v.cy},...v.strategy&&v.strategy!=="matched-node"?{strategy:v.strategy}:{},...v.total>1||i!==null?{nth:{index:v.idx,total:v.total}}:{},...$.attempts>1?{attempts:$.attempts}:{},result:$.result},null,2));break}case"tap-best":{let o=a[1];o||(console.error(k("tap-best","<query>")),process.exit(1));let t=await Nt(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 r=s.node;de(t.result)||(N(`best "${o}"`,t),process.exit(1));let i=De(o,{id:r.id,testID:r.testID,type:r.type,cx:s.cx,cy:s.cy},s.strategy==="testid"?"id":"text");await J("inspect tap-best",i.step,i.summary),console.log(JSON.stringify({matched:{strategy:s.strategy,nodeId:r.nodeId,id:r.id,testID:r.testID,type:r.type,text:r.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=a[1];o||(console.error(k("tap-id","<id>")),process.exit(1));let t=await Mt(d,o,{agent:ue()}),s=t.payload;(!s||typeof s.cx!="number")&&(console.error(` not found: ${o}`),await Ao(d,o),process.exit(1)),de(t.result)||(N(`id "${o}"`,t),process.exit(1));let r=De(o,{id:s.target?.id??null,testID:s.target?.testID??null,type:s.target?.type??null,cx:s.cx,cy:s.cy},"id");await J("inspect tap-id",r.step,r.summary),console.log(JSON.stringify({matched:s.match,tapped:{nodeId:s.target?.nodeId??null,id:s.target?.id??null,testID:s.target?.testID??null,type:s.target?.type??null,cx:s.cx,cy:s.cy},...s.strategy&&s.strategy!=="matched-node"?{strategy:s.strategy}:{},...t.attempts>1?{attempts:t.attempts}:{},result:t.result},null,2));break}case"type-into":{let o=a[1],t=a.slice(2).join(" ");(!o||!t)&&(console.error(k("type-into","<id> <text>")),process.exit(1));let s=JSON.stringify(o),r=await d.send({type:"evaluate",code:`(async () => {
|
|
413
414
|
const t = window.__sootsimTest
|
|
414
415
|
if (!t) return null
|
|
415
416
|
const n = await (t.findByTestId(${s}) || t.findById(${s}))
|
|
@@ -423,7 +424,7 @@ ${s}
|
|
|
423
424
|
isTextInput: !!n.isTextInput,
|
|
424
425
|
placeholder: n.placeholder || null,
|
|
425
426
|
}
|
|
426
|
-
})()`});(!r||typeof r.cx!="number")&&(console.error(` not found: ${o}`),process.exit(1)),r.isTextInput||console.error(` warning: ${o} is not a text input (isTextInput: false)`);let i=await d.send({type:"tap",x:r.cx,y:r.cy,target:{id:r.id??o,testID:r.testID??o,text:null,type:r.type??null}}),u=await
|
|
427
|
+
})()`});(!r||typeof r.cx!="number")&&(console.error(` not found: ${o}`),process.exit(1)),r.isTextInput||console.error(` warning: ${o} is not a text input (isTextInput: false)`);let i=await d.send({type:"tap",x:r.cx,y:r.cy,target:{id:r.id??o,testID:r.testID??o,text:null,type:r.type??null}}),u=await Lo(d);u.visible||(console.error(` keyboard did not open after tapping ${o}`),process.exit(1));let p=u.focusedInput;p&&(p.testID===o||p.id===o||(console.error(` focus routing mismatch after tap: requested ${JSON.stringify(o)} but focus is on ${JSON.stringify(p.testID??p.id??null)}. did the tap land on an outer Pressable wrapper?`),process.exit(1))),await d.send({type:"keyboard",action:"type",text:t}),await J("inspect type-into",{tapOn:{id:o},inputText:t},`type-into #${o} ${JSON.stringify(t)}`),console.log(JSON.stringify({target:o,isTextInput:r.isTextInput,keyboardOpened:u.visible??i?.keyboardOpened??!1,focusedInput:u.focusedInput??null,typed:t},null,2));break}case"type":{let o=a.slice(1).join(" ");o||(console.error(k("type","<text>")),process.exit(1)),await ke(d,"type"),await d.send({type:"keyboard",action:"type",text:o}),await J("inspect type",{inputText:o},`type ${JSON.stringify(o)}`),console.log(` typed: ${JSON.stringify(o)}`);break}case"key":{let o=a[1];o||(console.error(k("key","<name>")),process.exit(1)),await ke(d,"key"),await d.send({type:"keyboard",action:"press",text:o}),await J("inspect key",{pressKey:o},`key ${o}`),console.log(` pressed: ${o}`);break}case"key-sequence":{let o=a.slice(1);o.length===0&&(console.error(k("key-sequence","<key> [<key> ...]")),process.exit(1)),await ke(d,"key-sequence");for(let t of o)await d.send({type:"keyboard",action:"press",text:t});await J("inspect key-sequence",{pressKey:o.join(" ")},`key-sequence ${o.join(" ")}`),console.log(` pressed: ${o.join(", ")}`);break}case"keycode":{let o=a.slice(1);o.length===0&&(console.error(k("keycode","<code> [<code> ...]")),process.exit(1));let t=o.map(r=>({code:r,key:Wo(r)})),s=t.filter(r=>!r.key);s.length>0&&(console.error(` unsupported keycode(s): ${s.map(r=>r.code).join(", ")}`),process.exit(1)),await ke(d,"keycode");for(let r of t)await d.send({type:"keyboard",action:"press",text:r.key});await J("inspect keycode",{pressKey:t.map(r=>r.key).join(" ")},`keycode ${o.join(" ")}`),console.log(` pressed: ${o.join(", ")}`);break}case"dispatch":{let o=a[1];o||(console.error(k("dispatch","<char>")),process.exit(1)),await d.send({type:"keyboard",action:"dispatchKey",text:o}),await J("inspect dispatch",{dispatchKey:o},`dispatch ${JSON.stringify(o)}`),console.log(` dispatched: ${o}`);break}case"dismiss":{await d.send({type:"keyboard",action:"dismiss"}),await J("inspect dismiss",{hideKeyboard:!0},"dismiss keyboard"),console.log(" keyboard dismissed");break}case"double-tap":{let o=Number(a[1]),t=Number(a[2]),s=ye(e);if(s){let p=await $e(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 r=a[3]?Number(a[3]):80;(!Number.isFinite(o)||!Number.isFinite(t)||!Number.isFinite(r))&&(console.error(k("double-tap","<x> <y> [gapMs] | --testid <id>")),process.exit(1));let i=Math.max(0,Math.round(r)),u=await d.send({type:"evaluate",code:`(async () => {
|
|
427
428
|
const interact = window.__sootsimInteract
|
|
428
429
|
if (interact?.doubleTap) {
|
|
429
430
|
return {
|
|
@@ -446,7 +447,7 @@ ${s}
|
|
|
446
447
|
first,
|
|
447
448
|
second,
|
|
448
449
|
}
|
|
449
|
-
})()`});u?.ok&&await J("inspect double-tap",{doubleTapAtCoords:{x:o,y:t,gapMs:i}},`double-tap @${o},${t}`),console.log(JSON.stringify(u,null,2));break}case"long-press":{let o=Number(a[1]),t=Number(a[2]),s=
|
|
450
|
+
})()`});u?.ok&&await J("inspect double-tap",{doubleTapAtCoords:{x:o,y:t,gapMs:i}},`double-tap @${o},${t}`),console.log(JSON.stringify(u,null,2));break}case"long-press":{let o=Number(a[1]),t=Number(a[2]),s=ye(e);if(s){let u=await $e(d,s);u||(console.error(` not found: ${s.value}`),s.mode==="testid"&&G("wait-selector-for-missing-testid",s.value),process.exit(1)),o=u.x,t=u.y}let r=a[3]?Number(a[3]):600;(!Number.isFinite(o)||!Number.isFinite(t)||!Number.isFinite(r))&&(console.error(k("long-press","<x> <y> [durationMs] | --testid <id>")),process.exit(1));let i=await d.send({type:"evaluate",code:`(async () => {
|
|
450
451
|
const interact = window.__sootsimInteract
|
|
451
452
|
if (!interact?.longPress) return { ok: false, reason: 'no interact.longPress' }
|
|
452
453
|
const value = await interact.longPress(${o}, ${t}, ${Math.max(0,Math.round(r))})
|
|
@@ -465,12 +466,12 @@ ${s}
|
|
|
465
466
|
statusBarHeight: spec.statusBarHeight || 0,
|
|
466
467
|
homeIndicatorHeight: spec.homeIndicatorHeight || 0,
|
|
467
468
|
}
|
|
468
|
-
})()`}),i=Number(r?.width)||393,u=Number(r?.height)||852,p=Number(r?.statusBarHeight)||0,w=Number(r?.homeIndicatorHeight)||0,f=Math.round(i/2),x=Math.round(u/2),
|
|
469
|
+
})()`}),i=Number(r?.width)||393,u=Number(r?.height)||852,p=Number(r?.statusBarHeight)||0,w=Number(r?.homeIndicatorHeight)||0,f=Math.round(i/2),x=Math.round(u/2),O=Math.max(24,p+18),q=Math.max(24,w+18),H=18,U=Math.min(220,Math.round(u*.24)),F=Math.min(180,Math.round(i*.32)),b=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":b=f+Math.round(F/2),v=f-Math.round(F/2);break;case"scroll-right":b=f-Math.round(F/2),v=f+Math.round(F/2);break;case"swipe-from-left-edge":b=H,$=x,v=Math.min(i-H,H+F);break;case"swipe-from-right-edge":b=i-H,$=x,v=Math.max(H,i-H-F);break;case"swipe-from-top-edge":b=f,$=O,oe=Math.min(u-q,O+U);break;case"swipe-from-bottom-edge":b=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 () => {
|
|
469
470
|
const interact = window.__sootsimInteract
|
|
470
471
|
if (!interact?.drag) return { ok: false, reason: 'no interact.drag' }
|
|
471
|
-
const value = await interact.drag(${b}, ${$}, ${v}, ${oe}, ${K}, ${
|
|
472
|
+
const value = await interact.drag(${b}, ${$}, ${v}, ${oe}, ${K}, ${E})
|
|
472
473
|
return { ok: !!value, value }
|
|
473
|
-
})()`});
|
|
474
|
+
})()`});he?.ok&&await J("inspect gesture",{swipe:{start:`${b}, ${$}`,end:`${v}, ${oe}`,duration:Math.max(1,Math.round(s))}},`gesture ${t}`),console.log(JSON.stringify({preset:t,from:{x:b,y:$},to:{x:v,y:oe},result:he},null,2));break}case"scroll":{let o=ye(e),t=Ho(e),s=o?.mode==="testid"?o.value:t==null?a[1]:null,r=o||t!=null?1:2,i=Number(a[r]),u=Number(a[r+1]);(!s&&t==null||!Number.isFinite(i)||!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 () => {
|
|
474
475
|
const t = window.__sootsimTest
|
|
475
476
|
if (!t) return null
|
|
476
477
|
const n = ${t!=null?`await t.inspectByNodeId(${JSON.stringify(t)})`:`await t.findByTestId(${JSON.stringify(s)})
|
|
@@ -561,7 +562,7 @@ ${s}
|
|
|
561
562
|
${h("shell")} open-card clock 800
|
|
562
563
|
${h("shell")} appearance dark
|
|
563
564
|
${h("shell")} lock
|
|
564
|
-
`);break}let t=o==="launch"||o==="open-card"||o==="home"||o==="switcher",s=o==="launch"||o==="open-card"?a[3]:a[2],r=s?Number(s):350;t&&(!Number.isFinite(r)||r<0)&&(console.error(k("shell",o==="launch"||o==="open-card"?"<launch|open-card> <appId> [settleMs]":"<home|switcher> [settleMs]")),process.exit(1));let i=!1,u=!1,p=null,w=e.includes("--clear-state");if(o==="launch"){let f=a[2];f||(console.error(k("shell","launch <appId> [settleMs] [--clear-state]")),process.exit(1)),w&&await d.send({type:"evaluate",code:Ke}),i=!!await
|
|
565
|
+
`);break}let t=o==="launch"||o==="open-card"||o==="home"||o==="switcher",s=o==="launch"||o==="open-card"?a[3]:a[2],r=s?Number(s):350;t&&(!Number.isFinite(r)||r<0)&&(console.error(k("shell",o==="launch"||o==="open-card"?"<launch|open-card> <appId> [settleMs]":"<home|switcher> [settleMs]")),process.exit(1));let i=!1,u=!1,p=null,w=e.includes("--clear-state");if(o==="launch"){let f=a[2];f||(console.error(k("shell","launch <appId> [settleMs] [--clear-state]")),process.exit(1)),w&&await d.send({type:"evaluate",code:Ke}),i=!!await pe(d,"launchApp",r,f),{settled:u,state:p}=await ve(d,Math.round(r),x=>!!x&&x.state==="app"&&x.activeApp===f&&x.showSwitcher===!1&&x.switcherPhase==="idle"&&typeof x.launchProgress=="number"&&x.launchProgress>=.98),i&&await J("inspect shell launch",w?{launchApp:{clearState:!0}}:{launchApp:{}},w?"launch app (clear state)":"launch app")}else if(o==="home")i=!!await pe(d,"goHome",r),{settled:u,state:p}=await ve(d,Math.round(r),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")i=!!await pe(d,"openSwitcher",r),{settled:u,state:p}=await ve(d,Math.round(r),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=a[2];f||(console.error(k("shell","open-card <appId> [settleMs]")),process.exit(1)),i=!!await pe(d,"openSwitcherCard",r,f),{settled:u,state:p}=await ve(d,Math.round(r),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),i&&await J("inspect shell open-card",{openSwitcherCard:{appId:f}},`open switcher card ${f}`)}else if(o==="appearance"){let f=a[2];(!f||!["light","dark","auto","toggle"].includes(f))&&(console.error(k("shell","appearance <light|dark|auto|toggle>")),process.exit(1));let x=await Qt(d,"appearance",f);if(i=!!x?.ok,p={appearance:x},i){let O=x?.applied??f;console.log(` appearance: ${O}`)}}else if(o==="lock"||o==="shake"){let f=await Qt(d,o);i=!!f?.ok,p={[o]:f}}else console.error(` unknown shell subcommand: ${o}`),process.exit(1);console.log(JSON.stringify({ok:i,settled:u,state:p},null,2));break}case"url":{await Jt(d,{args:l});break}case"reload":{let s=!1,r=!1;try{await d.send({type:"evaluate",code:"window.__sootsimConsole?.clear()"});let p=await d.send({type:"evaluate",code:`;(() => {
|
|
565
566
|
const reloadExternalApp = window.SootSim?.bridges?.hotRemount?.reloadExternalApp
|
|
566
567
|
if (typeof reloadExternalApp === 'function') {
|
|
567
568
|
reloadExternalApp()
|
|
@@ -569,10 +570,10 @@ ${s}
|
|
|
569
570
|
}
|
|
570
571
|
window.location.reload()
|
|
571
572
|
return { kind: 'page' }
|
|
572
|
-
})()`});r=!!p&&p.kind==="external-app",s=!0}catch{}console.log(" reloading...");let i=d,u=null;if(r)u=await
|
|
573
|
+
})()`});r=!!p&&p.kind==="external-app",s=!0}catch{}console.log(" reloading...");let i=d,u=null;if(r)u=await Ae(d,{timeoutMs:1e4,errorGraceMs:3e3});else{s&&await Z(300);let p=await yt(_,j,I,{timeoutMs:1e4,simIdSource:R});p?(i=p,u=await Ae(p,{timeoutMs:1e4,errorGraceMs:3e3})):(console.log(" \u26A0 reload: bridge never reconnected within 10000ms"),i=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(i)try{let p=await i.send({type:"evaluate",code:"window.__sootsimConsole?.getErrors(10) || []"});if(i!==d&&i.close(),Array.isArray(p)&&p.length>0){console.log(`
|
|
573
574
|
\u26A0 ${p.length} error(s) during mount:
|
|
574
575
|
`);for(let w of p){let f=w.args.map(x=>typeof x=="object"?JSON.stringify(x):x).join(" ");if(console.log(` ${f}`),w.stack){let x=w.stack.split(`
|
|
575
|
-
`).slice(0,2);for(let
|
|
576
|
+
`).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=a.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 r=o.toLowerCase(),i=[];(r.includes("sootsim:gohome")||r.includes("gohome"))&&i.push("sootsim shell home"),(r.includes("sootsim:appswitcher")||r.includes("appswitcher"))&&i.push("sootsim shell switcher"),(r.includes("keyboard.isvisible")||r.includes("keyboard.getmode"))&&i.push("sootsim debug state keyboard"),r.includes("interact.tap")&&i.push("sootsim do tap <x> <y>"),r.includes("keyboard.type")&&i.push("sootsim do type <text>"),(r.includes("keyboard.press")||r.includes("keyboard.dispatchkey"))&&i.push("sootsim do key <name>"),r.includes("keyboard.dismiss")&&i.push("sootsim do dismiss"),r.includes("dumptree")&&i.push("sootsim get tree"),r.includes("dumpaccessibilitytree")&&i.push("sootsim get a11y"),r.includes("getnodecount")&&i.push("sootsim get count"),r.includes("findbytext")&&i.push("sootsim find <text>"),(r.includes("findbytestid")||r.includes("findbyid"))&&i.push("sootsim find --testid <id>"),r.includes("document.hidden")&&i.push("sootsim debug state keyboard (includes tab health)"),i.length>0&&G("prefer-cli-over-eval",i);break}case"globals":{let o=await d.send({type:"evaluate",code:`(async () => {
|
|
576
577
|
const globals = {}
|
|
577
578
|
|
|
578
579
|
// test bridge (proxy in worker mode)
|
|
@@ -610,7 +611,7 @@ ${s}
|
|
|
610
611
|
|
|
611
612
|
return globals
|
|
612
613
|
})()`});console.log(` sootsim JS API:
|
|
613
|
-
`);for(let[t,s]of Object.entries(o)){console.log(` ${t}:`);for(let r of s)console.log(` .${r}`);console.log("")}console.log(` use: ${h("js")} <expression>`),console.log(` example: ${h("js")} test.findByText("Sign in")`);break}case"describe":{await
|
|
614
|
+
`);for(let[t,s]of Object.entries(o)){console.log(` ${t}:`);for(let r of s)console.log(` .${r}`);console.log("")}console.log(` use: ${h("js")} <expression>`),console.log(` example: ${h("js")} test.findByText("Sign in")`);break}case"describe":{await _t({bridge:d,args:e,positional:a});break}case"perf":{let o=a[1];if(!o||o==="--help"||o==="-h"){console.log(`
|
|
614
615
|
${h("perf")} \u2014 performance profiling
|
|
615
616
|
|
|
616
617
|
subcommands:
|
|
@@ -656,7 +657,7 @@ ${s}
|
|
|
656
657
|
jankFrames: frameStats.recentFrames?.filter(f => f > 16.67).length || 0,
|
|
657
658
|
recentCount: frameStats.recentFrames?.length || 0,
|
|
658
659
|
}
|
|
659
|
-
})()`});if(t.error&&(console.error(` error: ${t.error}`),process.exit(1)),
|
|
660
|
+
})()`});if(t.error&&(console.error(` error: ${t.error}`),process.exit(1)),A(l)){P(t);break}let s=t.avgMs==="?"&&t.maxMs==="?",r=t.avgMs!=="?"?(1e3/parseFloat(t.avgMs)).toFixed(1):"?";console.log(" perf stats:"),console.log(` frames: ${t.frames}`),console.log(` avg: ${t.avgMs}ms (${r} 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(`
|
|
660
661
|
\u26A0 frame timings are zero \u2014 enable them first:
|
|
661
662
|
sootsim debug perf start # begin recording
|
|
662
663
|
# \u2026 interact / run a flow / wait for the transition \u2026
|
|
@@ -778,7 +779,7 @@ ${s}
|
|
|
778
779
|
jankFrames: recent.filter(f => f > 16.67).length,
|
|
779
780
|
sampleCount: recent.length,
|
|
780
781
|
}
|
|
781
|
-
})()`});if(t.error&&(console.error(` error: ${t.error}`),process.exit(1)),
|
|
782
|
+
})()`});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):"?",r=t.sampleCount>0?(t.jankFrames/t.sampleCount*100).toFixed(1):"0";console.log(` profiling stopped:
|
|
782
783
|
`),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 (${r}%) >16.67ms`);break}case"frames":{let t=a[2]?Number(a[2]):50;(!Number.isFinite(t)||t<=0)&&(console.error(` error: expected a positive frame count, got "${a[2]}"`),process.exit(1));let s=await d.send({type:"evaluate",code:`(async () => {
|
|
783
784
|
if (window.__sootsimRenderHost) {
|
|
784
785
|
const session = window.${se} || {}
|
|
@@ -814,7 +815,7 @@ ${s}
|
|
|
814
815
|
mode: 'main-thread',
|
|
815
816
|
frames: (stats.recentFrames || []).slice(-${t}),
|
|
816
817
|
}
|
|
817
|
-
})()`});if(s.error&&(console.error(` error: ${s.error}`),process.exit(1)),
|
|
818
|
+
})()`});if(s.error&&(console.error(` error: ${s.error}`),process.exit(1)),A(l)){P(s);break}if(s.mode==="render-worker"){let i=Array.isArray(s.samples)?s.samples:[];if(i.length===0){console.log(` no frame data \u2014 run '${h("perf")} start' first`);break}console.log(` last ${i.length} sampled frames (ms):`),console.log(" total layout render copy aux other t+");for(let[u,p,w,f,x,O,q]of i)console.log(` ${p.toFixed(2).padStart(7)} ${w.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(""),Ce(i.map(u=>u[1])),s.live&&console.log(" sampling continues");break}let r=Array.isArray(s.frames)?s.frames:Array.isArray(s)?s:[];if(r.length===0){console.log(` no frame data \u2014 run '${h("perf")} start' first`);break}console.log(` last ${r.length} frame times (ms):`),console.log(` ${r.map(i=>i.toFixed(2)).join(", ")}`),Ce(r);break}case"worst":{let t=a[2]?Number(a[2]):20;(!Number.isFinite(t)||t<=0)&&(console.error(` error: expected a positive frame count, got "${a[2]}"`),process.exit(1));let s=await d.send({type:"evaluate",code:`(async () => {
|
|
818
819
|
if (window.__sootsimRenderHost) {
|
|
819
820
|
const session = window.${se} || {}
|
|
820
821
|
if (session.active) {
|
|
@@ -856,7 +857,7 @@ ${s}
|
|
|
856
857
|
mode: 'main-thread',
|
|
857
858
|
frames: recent.slice().sort((a, b) => b - a).slice(0, ${t}),
|
|
858
859
|
}
|
|
859
|
-
})()`});if(s.error&&(console.error(` error: ${s.error}`),process.exit(1)),
|
|
860
|
+
})()`});if(s.error&&(console.error(` error: ${s.error}`),process.exit(1)),A(l)){P(s);break}if(s.mode==="render-worker"){let i=Array.isArray(s.samples)?s.samples:[];if(i.length===0){console.log(` no frame data \u2014 run '${h("perf")} start' first`);break}console.log(` worst ${i.length} sampled frames (ms):`),console.log(" total layout render copy aux other t+");for(let[u,p,w,f,x,O,q]of i)console.log(` ${p.toFixed(2).padStart(7)} ${w.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 r=Array.isArray(s.frames)?s.frames:Array.isArray(s)?s:[];if(r.length===0){console.log(` no frame data \u2014 run '${h("perf")} start' first`);break}console.log(` worst ${r.length} frame times (ms):`),console.log(` ${r.map(i=>i.toFixed(2)).join(", ")}`);break}case"transition":{let t=a[2];if(!t||!["goHome","appSwitcher","lockScreen"].includes(t)){console.log(`
|
|
860
861
|
${h("perf")} transition <event> \u2014 profile a shell transition
|
|
861
862
|
|
|
862
863
|
events:
|
|
@@ -869,7 +870,7 @@ ${s}
|
|
|
869
870
|
examples:
|
|
870
871
|
${h("perf")} transition goHome --timeout 10000
|
|
871
872
|
${h("perf")} transition appSwitcher
|
|
872
|
-
`);break}let r=`sootsim:${t}`;
|
|
873
|
+
`);break}let r=`sootsim:${t}`;Oe(` profiling ${t} transition...`),Oe(" (use --timeout 10000 if this times out)");let i=await d.send({type:"evaluate",code:`(async () => {
|
|
873
874
|
// only supported in render-worker mode
|
|
874
875
|
if (!window.__sootsimRenderHost) {
|
|
875
876
|
return { error: 'transition profiling requires render-worker mode' }
|
|
@@ -928,7 +929,7 @@ ${s}
|
|
|
928
929
|
jankFrames: frameTimes.filter(f => f > 16.67).length,
|
|
929
930
|
samples,
|
|
930
931
|
}
|
|
931
|
-
})()`});if(i.error&&(console.error(` error: ${i.error}`),process.exit(1)),
|
|
932
|
+
})()`});if(i.error&&(console.error(` error: ${i.error}`),process.exit(1)),A(l)){P(i);break}if(i.warning&&console.log(` warning: ${i.warning}`),i.frames===0){console.log(" no frames captured");break}let u=i.avgMs>0?(1e3/i.avgMs).toFixed(1):"?",p=i.frames>0?(i.jankFrames/i.frames*100).toFixed(1):"0";console.log(` ${t} transition profiled:
|
|
932
933
|
|
|
933
934
|
frames: ${i.frames}
|
|
934
935
|
total: ${i.totalMs.toFixed(1)}ms
|
|
@@ -946,29 +947,29 @@ ${s}
|
|
|
946
947
|
p50: ${i.p50.toFixed(2)}ms
|
|
947
948
|
p95: ${i.p95.toFixed(2)}ms
|
|
948
949
|
p99: ${i.p99.toFixed(2)}ms
|
|
949
|
-
jank: ${i.jankFrames} frames (${p}%) >16.67ms`),Array.isArray(i.samples)&&i.samples.length>0&&(console.log(""),Ce(i.samples.map(w=>w[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=a[1];if(o==="clear"){await
|
|
950
|
+
jank: ${i.jankFrames} frames (${p}%) >16.67ms`),Array.isArray(i.samples)&&i.samples.length>0&&(console.log(""),Ce(i.samples.map(w=>w[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=a[1];if(o==="clear"){await it(d),A(l)?P({cleared:!0}):console.log(" error buffer cleared");break}let t=o?Number(o):20,s=await nt(d,t);if(A(l)){P(s);break}if(s.length===0){console.log(" no errors captured");break}console.log(` ${s.length} error(s):
|
|
950
951
|
`);for(let r of s){let i=re(r.timestamp),u=r.args.map(p=>typeof p=="object"?JSON.stringify(p):p).join(" ");if(console.log(` [${i}] ${u}`),r.stack){let p=r.stack.split(`
|
|
951
|
-
`).slice(0,3);for(let w of p)console.log(` ${w.trim()}`)}}break}case"warnings":{let o=a[1]?Number(a[1]):20,t=await
|
|
952
|
+
`).slice(0,3);for(let w of p)console.log(` ${w.trim()}`)}}break}case"warnings":{let o=a[1]?Number(a[1]):20,t=await rt(d,o);if(A(l)){P(t);break}if(t.length===0){console.log(" no warnings captured");break}console.log(` ${t.length} warning(s):
|
|
952
953
|
`);for(let s of t){let r=re(s.timestamp),i=s.args.map(u=>typeof u=="object"?JSON.stringify(u):u).join(" ");console.log(` [${r}] ${i}`)}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):
|
|
953
|
-
`);for(let t of o){let s=String(t.kind).padEnd(6),r=`${Number(t.from).toFixed(2)}\u2192${Number(t.to).toFixed(2)}`,i=Number(t.current??0).toFixed(2),u=`${Math.round((t.progress??0)*100)}%`,p=`${Math.round(t.elapsedMs??0)}ms`,w=t.loop?" loop":"",f=t.layoutBound?" layout":"";console.log(` #${t.id} ${s} ${r.padEnd(14)} cur=${i.padEnd(7)} ${u.padStart(4)} ${p}${w}${f}`)}break}case"animation":{let o=a[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=a[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=a[1];if(o==="clear"){await
|
|
954
|
+
`);for(let t of o){let s=String(t.kind).padEnd(6),r=`${Number(t.from).toFixed(2)}\u2192${Number(t.to).toFixed(2)}`,i=Number(t.current??0).toFixed(2),u=`${Math.round((t.progress??0)*100)}%`,p=`${Math.round(t.elapsedMs??0)}ms`,w=t.loop?" loop":"",f=t.layoutBound?" layout":"";console.log(` #${t.id} ${s} ${r.padEnd(14)} cur=${i.padEnd(7)} ${u.padStart(4)} ${p}${w}${f}`)}break}case"animation":{let o=a[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=a[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=a[1];if(o==="clear"){await lt(d),A(l)?P({cleared:!0}):console.log(" request buffer cleared");break}let t=o==="all",s=t?a[2]:o,r=s?Number(s):20,i=await at(d,{failed:!t,limit:r});if(A(l)){P(i);break}if(i.length===0){console.log(t?" no requests captured":" no failed requests captured");break}console.log(` ${i.length} ${t?"request(s)":"failed request(s)"}:
|
|
954
955
|
`);for(let u of i){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=a[1],t=null,s=null,r=!1,i=!1,u=1e3,p=!1,w=!1;for(let F=0;F<l.length;F++){let b=l[F];if(b==="--filter")t=l[F+1]??null,F++;else if(b==="--limit"){let $=Number(l[F+1]);Number.isFinite($)&&(s=$),F++}else if(b==="--threshold"){let $=Number(l[F+1]);Number.isFinite($)&&$>0&&(u=$),F++}else b==="--failed"?r=!0:b==="--slow"?i=!0:b==="--tail"||b==="-f"?p=!0:b==="--json"&&(w=!0)}if(o==="clear"){await d.send({type:"evaluate",code:'window.__sootsimObservability?.network.clear(); "cleared"'}),console.log(" network buffer cleared");break}if(o==="get"){let F=a[2];F||(console.error(" usage: sootsim network get <id>"),process.exit(1));let b=await d.send({type:"evaluate",code:`(() => {
|
|
955
956
|
const obs = window.__sootsimObservability;
|
|
956
957
|
if (!obs) return null;
|
|
957
958
|
return obs.network.getSnapshot().find(e => e.id === ${JSON.stringify(F)}) || null;
|
|
958
|
-
})()`});b||(console.error(` no entry with id ${F}`),process.exit(1)),w?console.log(JSON.stringify(b,null,2)):
|
|
959
|
+
})()`});b||(console.error(` no entry with id ${F}`),process.exit(1)),w?console.log(JSON.stringify(b,null,2)):Do(b);break}let f=s??(p?200:o?Number(o):20);Number.isFinite(f)||(console.error(` invalid limit: ${o} \u2014 \`network\` takes a numeric count (e.g. ${h("network")} 100).
|
|
959
960
|
to target a specific sim, use \`--sim ${o}\` instead.`),process.exit(1));let x=async()=>{let F=await d.send({type:"evaluate",code:`(() => {
|
|
960
961
|
const obs = window.__sootsimObservability;
|
|
961
962
|
if (!obs) return { ok: false };
|
|
962
963
|
return { ok: true, entries: obs.network.getSnapshot() };
|
|
963
|
-
})()`});if(!F||!F.ok)throw new Error("observability bridge not installed \u2014 is the engine running?");return F.entries??[]},
|
|
964
|
+
})()`});if(!F||!F.ok)throw new Error("observability bridge not installed \u2014 is the engine running?");return F.entries??[]},O=F=>{let b=F;if(r&&(b=b.filter($=>!!$.error||$.status!=null&&$.status>=400)),i&&(b=b.filter($=>$.durationMs!=null&&$.durationMs>=u)),t){let $=t.toLowerCase();b=b.filter(v=>(v.displayUrl||v.url).toLowerCase().includes($))}return i&&!p&&(b=[...b].sort(($,v)=>(v.durationMs??0)-($.durationMs??0))),b};if(!p){let F=await x(),b=O(F).slice(-f);if(w){console.log(JSON.stringify(b,null,2));break}if(b.length===0){F.length===0?console.log(" no network requests captured"):console.log(i?` no requests slower than ${u}ms (${F.length} total \u2014 try --threshold <ms>)`:" no matching requests");break}console.log(i?` ${b.length} request(s) slower than ${u}ms (sorted by duration desc):
|
|
964
965
|
`:` ${b.length} request(s):
|
|
965
|
-
`);for(let $ of b)
|
|
966
|
-
`);let q=new Set,H=!0,U=()=>{H=!1};process.on("SIGINT",U);try{for(;H;){let F=await x(),b=
|
|
967
|
-
to target a specific sim, use \`--sim ${o}\` instead.`),process.exit(1));let
|
|
968
|
-
`);for(let v of $)
|
|
969
|
-
`);let H=new Set,U=!0,F=()=>{U=!1};process.on("SIGINT",F);try{for(;U;){let b=await
|
|
966
|
+
`);for(let $ of b)Yt($);break}console.log(` tailing network (ctrl-c to stop)...
|
|
967
|
+
`);let q=new Set,H=!0,U=()=>{H=!1};process.on("SIGINT",U);try{for(;H;){let F=await x(),b=O(F);for(let $ of b)$.durationMs!=null&&(q.has($.id)||(q.add($.id),w?console.log(JSON.stringify($)):Yt($)));await Z(250)}}finally{process.off("SIGINT",U)}break}case"logs":{let o=a[1],t=null,s=null,r=null,i=!1,u=!1,p=!1;for(let b=0;b<l.length;b++){let $=l[b];if($==="--filter")t=l[b+1]??null,b++;else if($==="--limit"){let v=Number(l[b+1]);Number.isFinite(v)&&(s=v),b++}else $==="--level"?(r=l[b+1]??null,b++):$==="--tail"||$==="-f"?i=!0:$==="--json"?u=!0:($==="--internal"||$==="--all")&&(p=!0)}let w=r?new Set(r.split(",").map(b=>b.trim()).filter(b=>b==="log"||b==="info"||b==="warn"||b==="error"||b==="debug")):null;if(o==="clear"){await dt(d),console.log(" log buffer cleared");break}let f=!u&&process.stdout.isTTY===!0,x=s??(i?500:o?Number(o):50);Number.isFinite(x)||(console.error(` invalid limit: ${o} \u2014 \`logs\` takes a numeric count (e.g. ${h("logs")} 100).
|
|
968
|
+
to target a specific sim, use \`--sim ${o}\` instead.`),process.exit(1));let O=()=>ct(d),q=b=>ut(b,{level:w,filter:t,showInternal:p});if(!i){let b=await O(),$=q(b).slice(-x);if(u){console.log(JSON.stringify($,null,2));break}if($.length===0){console.log(b.length===0?" no logs captured":" no matching logs");break}console.log(` ${$.length} log(s):
|
|
969
|
+
`);for(let v of $)Xt(v,f);break}console.log(` tailing logs (ctrl-c to stop)...
|
|
970
|
+
`);let H=new Set,U=!0,F=()=>{U=!1};process.on("SIGINT",F);try{for(;U;){let b=await O(),$=q(b);for(let v of $)H.has(v.id)||(H.add(v.id),u?console.log(JSON.stringify(v)):Xt(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 ze(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),r=/^command timed out after (\d+)s$/.exec(t),i=t.startsWith("sim disconnected:")||t.startsWith("bridge never reconnected")||t.startsWith("could not connect to ws://");if(s)await $t(d,_,s[1]);else if(/^no sim connected$/.test(t))xt(_);else if(r)if(await Oo(d)){let p=g??"describe";process.stderr.write(` the sim is still responsive \u2014 '${p}' just exceeded the ${r[1]}s command budget.
|
|
970
971
|
the screen's node tree is large; narrow the query or raise the budget:
|
|
971
972
|
sootsim ${p} --testid <id> # scope to one subtree
|
|
972
973
|
sootsim find --testid <id> # targeted single-node lookup
|
|
973
974
|
sootsim ${p} --timeout 60000 # raise per-command budget (ms)
|
|
974
|
-
`)}else
|
|
975
|
+
`)}else zt();else if(i)zt();else{try{await ht(d)}catch{}try{await X({includeTail:!0})}catch{}try{await W({includeTail:!0})}catch{}}process.exit(1)}finally{d.close()}}export{Pn as runInspect};
|