sootsim 0.1.52 → 0.1.53
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-RUWGJCSS.js → agent-PA7ZGTHU.js} +2 -2
- package/dist-cli/chunks/{agent-wrapper-FBCGP5N7.js → agent-wrapper-CVZFXQKJ.js} +2 -2
- package/dist-cli/chunks/{assert-IOU2NWE2.js → assert-6LHIY63B.js} +2 -2
- package/dist-cli/chunks/auto-bootstrap-SVBAUCSM.js +2 -0
- package/dist-cli/chunks/beta-YEBFYYIB.js +2 -0
- package/dist-cli/chunks/{chunk-EYRQG47K.js → chunk-2ZBZCRN6.js} +1 -1
- package/dist-cli/chunks/{chunk-EJYVXNQL.js → chunk-5Q3XBH5M.js} +2 -2
- package/dist-cli/chunks/{chunk-MWGIKDXO.js → chunk-5U2BN4IU.js} +2 -2
- package/dist-cli/chunks/{chunk-H4G7IRXG.js → chunk-6A4CZMPO.js} +2 -2
- package/dist-cli/chunks/{chunk-HRIQRZX3.js → chunk-6JZNIGOQ.js} +1 -1
- package/dist-cli/chunks/{chunk-EQPRFEHH.js → chunk-7IYYIF5B.js} +2 -2
- package/dist-cli/chunks/{chunk-FPIJBBYW.js → chunk-7ZHWA3WD.js} +2 -2
- package/dist-cli/chunks/{chunk-UCCSXQ2P.js → chunk-AFXPU7YQ.js} +3 -3
- package/dist-cli/chunks/{chunk-I5WEW3ES.js → chunk-AYU6WUNF.js} +1 -1
- package/dist-cli/chunks/{chunk-Q2424XB2.js → chunk-AZYLZGRV.js} +1 -1
- package/dist-cli/chunks/{chunk-ABEYZDD7.js → chunk-BPXSSZJS.js} +2 -2
- package/dist-cli/chunks/chunk-CKZSGUTE.js +2 -0
- package/dist-cli/chunks/{chunk-PZJSYDQ7.js → chunk-CRUPWYHV.js} +3 -3
- package/dist-cli/chunks/{chunk-DNKB2V2W.js → chunk-CTDDR7HW.js} +2 -2
- package/dist-cli/chunks/{chunk-IQU56D6C.js → chunk-CTGH5SFH.js} +1 -1
- package/dist-cli/chunks/{chunk-IXITVIJV.js → chunk-CW2X4KRW.js} +2 -2
- package/dist-cli/chunks/{chunk-JPLTR6JM.js → chunk-E3S6U2QR.js} +1 -1
- package/dist-cli/chunks/{chunk-UXE5BFPK.js → chunk-E4JTYQVY.js} +2 -2
- package/dist-cli/chunks/chunk-ELEP2COQ.js +3 -0
- package/dist-cli/chunks/{chunk-U3UHXJNE.js → chunk-ERC46HTZ.js} +1 -1
- package/dist-cli/chunks/{chunk-4TSGUAV3.js → chunk-FDA2NX2E.js} +2 -2
- package/dist-cli/chunks/{chunk-MBH3NFBC.js → chunk-GWGF4J4Y.js} +2 -2
- package/dist-cli/chunks/chunk-H4C3WE3C.js +1 -0
- package/dist-cli/chunks/{chunk-BF7F45CZ.js → chunk-IS5ORPFW.js} +2 -2
- package/dist-cli/chunks/{chunk-6QDFLMJL.js → chunk-LELB2PV3.js} +1 -1
- package/dist-cli/chunks/chunk-LL3XAMKC.js +16 -0
- package/dist-cli/chunks/{chunk-MSKCUZ5B.js → chunk-LYHVX7TD.js} +3 -3
- package/dist-cli/chunks/{chunk-YDKXZS7D.js → chunk-MX5HFYST.js} +1 -1
- package/dist-cli/chunks/{chunk-USGUHWUJ.js → chunk-N3RWXMD3.js} +2 -2
- package/dist-cli/chunks/chunk-NIHI6NXE.js +1 -0
- package/dist-cli/chunks/chunk-QTVGSFY6.js +305 -0
- package/dist-cli/chunks/{chunk-T6RAXKVI.js → chunk-R3VVVXF3.js} +2 -2
- package/dist-cli/chunks/{chunk-JPX7OS7B.js → chunk-R5XV3WIE.js} +2 -2
- package/dist-cli/chunks/{chunk-3DDSYQHM.js → chunk-RBXJA2PW.js} +2 -2
- package/dist-cli/chunks/{chunk-7Y3FYPJH.js → chunk-SQZXAKBL.js} +2 -2
- package/dist-cli/chunks/{chunk-CTEXZ7BE.js → chunk-STWL7EXR.js} +1 -1
- package/dist-cli/chunks/{chunk-GNQSOQXZ.js → chunk-WBAIONOO.js} +2 -2
- package/dist-cli/chunks/{chunk-3MIWVHCX.js → chunk-WXOAHKCZ.js} +1 -1
- package/dist-cli/chunks/{chunk-FVBSPGBR.js → chunk-XBP7BBSF.js} +2 -2
- package/dist-cli/chunks/{chunk-PDZ4JVAW.js → chunk-XC3T7UDH.js} +1 -1
- package/dist-cli/chunks/chunk-XO4UV6EO.js +1 -0
- package/dist-cli/chunks/chunk-YCPH4ZTS.js +2 -0
- package/dist-cli/chunks/{chunk-MTE3DEWY.js → chunk-YEE4EO2P.js} +1 -1
- package/dist-cli/chunks/{chunk-EXQJSXDF.js → chunk-ZYITMTYD.js} +1 -1
- package/dist-cli/chunks/cli-version-NMWGV7OU.js +2 -0
- package/dist-cli/chunks/{compat-ZBLH6EWV.js → compat-CHBJ7TDK.js} +3 -3
- package/dist-cli/chunks/{config-DH2GG63H.js → config-XTZOLM5E.js} +2 -2
- package/dist-cli/chunks/control-XAZGNLFM.js +2 -0
- package/dist-cli/chunks/{cpu-profile-3PRCXZMV.js → cpu-profile-EQHKYVOF.js} +2 -2
- package/dist-cli/chunks/{daemon-XSFKUDKZ.js → daemon-K42MZR2E.js} +2 -2
- package/dist-cli/chunks/{debug-VAWCOXQ3.js → debug-ULTTL5L2.js} +3 -3
- package/dist-cli/chunks/demo-app-registry-SO43B5HW.js +2 -0
- package/dist-cli/chunks/{detox-UABOFTDQ.js → detox-LU3G3EBC.js} +2 -2
- package/dist-cli/chunks/{device-LCB4N66D.js → device-RYW4ZE4R.js} +2 -2
- package/dist-cli/chunks/{diagnose-MT3WMY4M.js → diagnose-5YQAXWFB.js} +2 -2
- package/dist-cli/chunks/drivers-SXP44QNY.js +2 -0
- package/dist-cli/chunks/{electron-WVNFRA4S.js → electron-ORBIXXTP.js} +3 -3
- package/dist-cli/chunks/flow-GP7GAXLT.js +2 -0
- package/dist-cli/chunks/{hints-PFAKBGFX.js → hints-V4SHPWCI.js} +2 -2
- package/dist-cli/chunks/{home-paths-X6RB72PF.js → home-paths-UYEDTYXU.js} +2 -2
- package/dist-cli/chunks/{inspect-UFYXDO6B.js → inspect-K2FN4JPL.js} +96 -124
- package/dist-cli/chunks/install-R4H47HDX.js +2 -0
- package/dist-cli/chunks/{install-desktop-W6QJX52Y.js → install-desktop-BDDNVONK.js} +3 -3
- package/dist-cli/chunks/{keys-ORDSAMP7.js → keys-QH5VOSUK.js} +2 -2
- package/dist-cli/chunks/{launch-NQZTWTPY.js → launch-K2LP5XFZ.js} +3 -3
- package/dist-cli/chunks/{login-J2NVLHK5.js → login-5AJTPRVD.js} +4 -4
- package/dist-cli/chunks/{logout-HI7A6PFH.js → logout-45VCRSXX.js} +2 -2
- package/dist-cli/chunks/{maestro-KIOOFK5M.js → maestro-5LDII3YE.js} +2 -2
- package/dist-cli/chunks/{preview-QUJO4B4G.js → preview-IA2UUMLO.js} +2 -2
- package/dist-cli/chunks/{profile-U6RWYQV2.js → profile-ZALUAYTJ.js} +2 -2
- package/dist-cli/chunks/{react-3V65RTQC.js → react-KJBOHVG7.js} +2 -2
- package/dist-cli/chunks/{record-476LFCQV.js → record-UI226Z7F.js} +2 -2
- package/dist-cli/chunks/runtime-JNHCYB5L.js +2 -0
- package/dist-cli/chunks/{runtime-delivery-BSRHUXJQ.js → runtime-delivery-Y4QVOPLO.js} +2 -2
- package/dist-cli/chunks/{screenshot-2S3BCN35.js → screenshot-SV5S4UGU.js} +2 -2
- package/dist-cli/chunks/{screenshot-mode-SZCHOYZV.js → screenshot-mode-NCISGI6W.js} +2 -2
- package/dist-cli/chunks/{screenshots-LGP7LA3M.js → screenshots-MQZDYKF5.js} +2 -2
- package/dist-cli/chunks/{server-G4BGS6GE.js → server-RLDTPMHN.js} +2 -2
- package/dist-cli/chunks/setup-repo-F4RNWTDL.js +2 -0
- package/dist-cli/chunks/{skills-2YOLQVV6.js → skills-NECP76E4.js} +2 -2
- package/dist-cli/chunks/{start-SF3I4SLN.js → start-K4ASMK7D.js} +4 -4
- package/dist-cli/chunks/store-TLB2YDDQ.js +2 -0
- package/dist-cli/chunks/telemetry-EXCKYRZL.js +2 -0
- package/dist-cli/chunks/{test-YYHXTVDI.js → test-YJLRC3IE.js} +3 -3
- package/dist-cli/chunks/three-mode-NAAIMEHL.js +54 -0
- package/dist-cli/chunks/{timeline-IOEIFEH2.js → timeline-BJXCTH7E.js} +2 -2
- package/dist-cli/chunks/{upgrade-YF2U5QJY.js → upgrade-NRJOML2W.js} +2 -2
- package/dist-cli/chunks/upload-BQTZTOJL.js +2 -0
- package/dist-cli/chunks/{web-GAOXH77P.js → web-P3IP7M5Q.js} +2 -2
- package/dist-cli/chunks/{what-happened-DBI2RQVE.js → what-happened-5Q2RBX5R.js} +2 -2
- package/dist-cli/chunks/{whoami-YDAMLYNA.js → whoami-7W6WPTVA.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/bridge-constants.cjs +1 -1
- package/dist-lib/cli-constants.cjs +1 -1
- package/dist-lib/config.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/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/vite-base.cjs +1 -1
- package/dist-lib/vite.cjs +1 -1
- package/package.json +1 -1
- package/dist-cli/chunks/auto-bootstrap-OYBDYAZM.js +0 -2
- package/dist-cli/chunks/beta-D4OEPOSE.js +0 -2
- package/dist-cli/chunks/chunk-2QNHBNWB.js +0 -16
- package/dist-cli/chunks/chunk-A3YSGT76.js +0 -37
- package/dist-cli/chunks/chunk-DSJ7PGU3.js +0 -2
- package/dist-cli/chunks/chunk-DVCE2KQL.js +0 -108
- package/dist-cli/chunks/chunk-KVQWMXDV.js +0 -2
- package/dist-cli/chunks/chunk-SEETW74F.js +0 -1
- package/dist-cli/chunks/chunk-ULHAQFCE.js +0 -1
- package/dist-cli/chunks/chunk-YVGHAT6Q.js +0 -1
- package/dist-cli/chunks/cli-version-2VO66OZ6.js +0 -2
- package/dist-cli/chunks/control-W3BOP6AT.js +0 -2
- package/dist-cli/chunks/demo-app-registry-7GNP7WE4.js +0 -2
- package/dist-cli/chunks/drivers-YGVUWGMB.js +0 -2
- package/dist-cli/chunks/flow-OUOMEOSC.js +0 -2
- package/dist-cli/chunks/install-NBUHIXEP.js +0 -2
- package/dist-cli/chunks/runtime-4TK5DY5R.js +0 -2
- package/dist-cli/chunks/setup-repo-5LUDPPSI.js +0 -2
- package/dist-cli/chunks/store-LLUQKQB7.js +0 -2
- package/dist-cli/chunks/telemetry-RDTORLS2.js +0 -2
- package/dist-cli/chunks/three-mode-5U3H4QDF.js +0 -39
- package/dist-cli/chunks/upload-3DFSK4NV.js +0 -2
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
2
|
-
import{a as G}from"./chunk-
|
|
3
|
-
`)}function
|
|
1
|
+
/*! sootsim v0.1.53 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
|
+
import{a as G}from"./chunk-RBXJA2PW.js";import{a as je,b as Je}from"./chunk-ZYITMTYD.js";import{a as X,b as D,c as B,d as Y,e as de,f as re,g as it,h as at,i as ve}from"./chunk-ELEP2COQ.js";import{B as se,C as nt,I as rt,a as Le,b as We,c as qe,d as He,e as Ue,f as Ke,g as xe,h as Se,m as ze,n as Ye,o as Ge,p as Xe,q as Ve,r as Qe,s as Ze,t as et,u as tt,v as ot,z as st}from"./chunk-QTVGSFY6.js";import{a as De,g as ce}from"./chunk-7ZHWA3WD.js";import{b as lt,c as ct,i as dt}from"./chunk-BPXSSZJS.js";import"./chunk-WXOAHKCZ.js";import{a as Be}from"./chunk-6JZNIGOQ.js";import"./chunk-6A4CZMPO.js";import"./chunk-AYU6WUNF.js";import"./chunk-NIHI6NXE.js";import"./chunk-7IYYIF5B.js";import"./chunk-YEE4EO2P.js";import{a as be,c as we,d as Ae}from"./chunk-XC3T7UDH.js";import{a as Fe}from"./chunk-CKZSGUTE.js";import{c as Oe,e as Re,f as Ee,g as Ce,h as $e}from"./chunk-GWGF4J4Y.js";import{b as Pe}from"./chunk-STWL7EXR.js";import"./chunk-YCPH4ZTS.js";import"./chunk-E3S6U2QR.js";import"./chunk-LELB2PV3.js";import{existsSync as qt,mkdirSync as Ht,readFileSync as Ut,rmSync as ut,writeFileSync as Kt}from"fs";import{tmpdir as zt}from"os";import{dirname as Yt,join as Gt,resolve as Xt}from"path";var ie=1,Vt="SOOTSIM_INSPECT_NOTICE_PATH",Qt=300*1e3,Zt=15e3;function mt(){return Xt(process.env[Vt]||Gt(zt(),"sootsim-inspect-notice-state.json"))}function eo(o,d){return Object.fromEntries(Object.entries(o).filter(([,i])=>typeof i?.signature=="string"&&Number.isFinite(i?.updatedAt)&&d-i.updatedAt<=Qt))}function to(o){let d=mt();if(!qt(d))return{version:ie,entries:{}};try{let i=JSON.parse(Ut(d,"utf8"));return i.version!==ie||!i.entries||typeof i.entries!="object"?(ut(d,{force:!0}),{version:ie,entries:{}}):{version:ie,entries:eo(i.entries,o)}}catch{return ut(d,{force:!0}),{version:ie,entries:{}}}}function oo(o){let d=mt();Ht(Yt(d),{recursive:!0}),Kt(d,JSON.stringify(o,null,2)+`
|
|
3
|
+
`)}function so(o,d){let i=d.trim()||"default";return`${o}:${i}`}function ke(o,d,i,l={}){let f=l.nowMs??Date.now(),a=l.cooldownMs??Zt,y=to(f),S=so(o,d),I=y.entries[S];return I&&I.signature===i&&f-I.updatedAt<a?!1:(y.entries[S]={signature:i,updatedAt:f},oo(y),!0)}async function pt(o,d={args:[]}){let i=await Le(o);if(D(d.args)){B(i);return}console.log(` nodes: ${i.nodes}`)}function Te(o,d){let i=o.indexOf(d);return i>=0&&i+1<o.length?o[i+1]:null}async function ft(o){let{bridge:d,args:i,positional:l}=o,f=i.includes("--verbose")||i.includes("-v"),a=D(i),y=f&&!a,S=i.includes("--watch")||i.includes("-w"),I=1e3,k=i.includes("--compact"),b=i.includes("--no-xy"),v=Te(i,"--testid-like"),_=Te(i,"--only"),T=Te(i,"--subtree"),C=l[1],c=C?/[*?]/.test(C):!1,L=!c&&!_?C:void 0,K=_??(c?C:void 0),E=async()=>{await de(d,{verbose:y});let z=await He(d,{describe:!0,verbose:f,filter:L||"",testIdLike:v||void 0,onlyGlob:K||void 0,subtreeRoot:T||void 0,compact:k,hideXy:b}),q=z?.tree,w=z?.shell,M=z?.keyboard;if(a){B({shell:w,tree:q??"",keyboard:M});return}if(w&&typeof w=="object"){let P=[w.state?`state=${w.state}`:null,w.activeApp?`app=${w.activeApp}`:null,w.showSwitcher?"switcher":null,w.switcherPhase&&w.switcherPhase!=="idle"?`phase=${w.switcherPhase}`:null].filter(Boolean);P.length>0&&console.log(` shell: ${P.join(" ")}`)}if(typeof q=="string"&&q.startsWith("__SUBTREE_NOT_FOUND__:")){let P=q.slice(22);console.log(` subtree root not found: ${P}`),G("subtree-root-not-found",P);return}if(!q){let P=z?.nodeCount??0;console.log(" no matching nodes found"),!(L||v||K||T)&&P<10&&G("app-still-loading",P);return}if(console.log(q),!(L||v||K||T)&&!S&&q.split(`
|
|
4
4
|
`).length>=80&&G("describe-use-filters"),M&&M.visible){let P=M.spec,V=[P?.keyboardType?`type=${P.keyboardType}`:null,P?.returnKeyType&&P.returnKeyType!=="default"?`return=${P.returnKeyType}`:null,M.mode!=="letters"?`mode=${M.mode}`:null,M.shifted?"shift":null,M.capsLock?"caps":null,P?.autoCapitalize&&P.autoCapitalize!=="sentences"?`autoCap=${P.autoCapitalize}`:null,M.accessoryBarId?`accessory=${M.accessoryBarId}`:null].filter(Boolean);console.log(`
|
|
5
5
|
keyboard: ${V.join(" ")||"visible"}`)}};if(S)for(console.log(` watching... (Ctrl+C to stop)
|
|
6
|
-
`);;)console.clear(),await E(),await X(I);else await E()}var
|
|
7
|
-
`).map(
|
|
8
|
-
`)}async function
|
|
9
|
-
`))}async function
|
|
6
|
+
`);;)console.clear(),await E(),await X(I);else await E()}var no=["SOOTSIM_AGENT","CLAUDECODE","CLAUDE_CODE_ENTRYPOINT","CLAUDE_CODE_SESSION_ID","CODEX_THREAD_ID","CURSOR_TRACE_ID","AIDER_MODEL"];function gt(){if(process.env.SOOTSIM_AGENT==="0")return!1;for(let o of no){let d=process.env[o];if(d&&d.trim()&&d!=="0")return!0}return!1}async function yt(o){let{bridge:d,args:i,effectiveArgs:l,positional:f,inspectUsage:a}=o,y=w=>{let M=l.indexOf(w);return M>=0&&M+1<l.length?l[M+1]:null},S=w=>l.includes(w),I=y("--testid")||y("--test-id"),k=y("--role"),b=y("--type"),v=y("--text"),_=S("--pressable"),T=S("--visible"),C=S("--interactive-targets")||S("--actions"),c=!I&&!k&&!b&&!v&&!_&&!T&&!C?f[1]:null,L=v??c,K=await Ke(d,{testId:I,role:k,type:b,text:L,pressable:_,visible:T,interactive:C});K||(console.error(a("find","<text> | --text <t> | --testid <id> | --role <r> | --type <t> | --pressable | --visible | --interactive-targets")),process.exit(1));let{mode:E,result:J}=K,z=D(i),q=i.includes("--verbose")||i.includes("--dump");if(z)E==="interactive-targets"&&Array.isArray(J)?B(xe(J).map(w=>({...w,tap:Se(w)}))):B(J??null);else if(Array.isArray(J))if(J.length===0){console.log(` no ${E} nodes found`);let w=await d.send({type:"evaluate",code:"(async () => (await window.__sootsimTest?.getNodeCount?.()) || 0)()"});typeof w=="number"&&w<10&&G("app-still-loading",w)}else if(E==="interactive-targets"){let w=xe(J);console.log(` found ${w.length} interactive target${w.length===1?"":"s"} (sorted by score):`);for(let M of w.slice(0,20)){let Z=M.absolutePosition?`@(${Math.round(M.absolutePosition.x)},${Math.round(M.absolutePosition.y)})`:"",P=M.layout?`${Math.round(M.layout.width)}x${Math.round(M.layout.height)}`:"?x?",V=M.text?` "${M.text.slice(0,30)}"`:"",ee=M.testID?` #${M.testID}`:"",oe=M.accessibilityLabel?` \u24D8"${String(M.accessibilityLabel).slice(0,24)}"`:"",ye=M.accessibilityRole?`[${M.accessibilityRole}]`:M.type,e=Se(M);console.log(` ${ye}${V}${oe}${ee} ${P} ${Z}`),console.log(` \u2192 ${e}`),q&&console.log(Me(JSON.stringify(M,null,2)," "))}w.length>20&&console.log(` ... and ${w.length-20} more`)}else{console.log(` found ${J.length} node${J.length===1?"":"s"} (${E}):`);for(let w of J.slice(0,20)){let M=w.absolutePosition?`@(${Math.round(w.absolutePosition.x)},${Math.round(w.absolutePosition.y)})`:"",Z=w.layout?`${Math.round(w.layout.width)}x${Math.round(w.layout.height)}`:"?x?",P=w.text?` "${w.text.slice(0,30)}"`:"",V=w.testID?` #${w.testID}`:"",ee=w.pressable?" (tap)":"",oe=w.accessibilityRole?`[${w.accessibilityRole}]`:w.type;console.log(` ${oe}${P}${V} ${Z} ${M}${ee}`),q&&console.log(Me(JSON.stringify(w,null,2)," "))}J.length>20&&console.log(` ... and ${J.length-20} more`)}else if(J==null)console.log(` not found: ${L||I||k||b||""||E}`),I&&G("wait-selector-for-missing-testid",I);else{let w=J;if(w.type&&w.absolutePosition){let M=`@(${Math.round(w.absolutePosition.x)},${Math.round(w.absolutePosition.y)})`,Z=w.layout?`${Math.round(w.layout.width)}x${Math.round(w.layout.height)}`:"?x?",P=w.text?` "${w.text.slice(0,40)}"`:"",V=w.testID?` #${w.testID}`:"",ee=w.pressable?" (tap)":"",oe=w.accessibilityRole?`[${w.accessibilityRole}]`:w.type;console.log(` ${oe}${P}${V} ${Z} ${M}${ee}`),q&&console.log(Me(JSON.stringify(w,null,2)," "))}else console.log(JSON.stringify(J,null,2))}}function Me(o,d){return o.split(`
|
|
7
|
+
`).map(i=>d+i).join(`
|
|
8
|
+
`)}async function ht(o,d={}){let i=await st(o);if("error"in i&&(console.error(i.error),process.exit(1)),d.json){console.log(JSON.stringify(i,null,2));return}let{visible:l,spec:f,mode:a,shifted:y,capsLock:S,accessoryBarId:I}=i,k=[];k.push(`keyboard: ${l?"visible":"hidden"}`),f?(k.push(` type: ${f.keyboardType}`),k.push(` returnKey: ${f.returnKeyType}`),k.push(` autoCap: ${f.autoCapitalize}`),k.push(` autoCorrect: ${f.autoCorrect?"on":"off"}`),k.push(` appearance: ${f.keyboardAppearance}`),f.secureTextEntry&&k.push(" secureTextEntry: true"),f.enablesReturnKeyAutomatically&&k.push(` return: ${f.currentTextIsEmpty?"disabled (empty)":"enabled"}`)):k.push(" spec: <none> (shown via dev-tools with no TextInput)"),k.push(` mode: ${a}${y?" (shifted)":""}${S?" (caps)":""}`),I&&k.push(` accessoryBar: ${I}`),console.log(k.join(`
|
|
9
|
+
`))}async function bt(o){let d=await o.bridge.listSims();if(D(o.args)){B(d.map(i=>({...i,active:i.id===o.simId})));return}dt(d,o.simId)}function te(o){return o<1024?`${o}B`:o<1024*1024?`${(o/1024).toFixed(1)}KB`:`${(o/1024/1024).toFixed(1)}MB`}function ue(o,d){return d<=0?"?":`${(o/d*100).toFixed(0)}%`}async function wt(o,d={args:[]}){let i=await rt(o);if(D(d.args)){B(i);return}if(console.log(" memory:"),i.imageLoader){let l=i.imageLoader;console.log(" image-loader cache"),console.log(` entries: ${l.cacheEntries} / ${l.cacheMaxEntries} (${ue(l.cacheEntries,l.cacheMaxEntries)})`),console.log(` pixel bytes: ${te(l.cachePixelBytes)} / ${te(l.cachePixelBudget)} (${ue(l.cachePixelBytes,l.cachePixelBudget)})`),console.log(` pending: ${l.pendingFetches} fetches, ${l.pendingBytes} bytes`),console.log(` failed uris: ${l.failedUris}`),console.log(` snapshots: ${l.snapshots}`),console.log(` camera frames: ${l.cameraFrames}`)}else console.log(" image-loader cache: not available (engine pre-rebuild?)");if(i.workerHeap){let l=i.workerHeap;console.log(" worker heap (chrome only)"),console.log(` used: ${te(l.usedJSHeapSize)} / ${te(l.jsHeapSizeLimit)} (${ue(l.usedJSHeapSize,l.jsHeapSizeLimit)})`),console.log(` total: ${te(l.totalJSHeapSize)}`)}if(i.hostHeap){let l=i.hostHeap;console.log(" host heap (chrome only)"),console.log(` used: ${te(l.usedJSHeapSize)} / ${te(l.jsHeapSizeLimit)} (${ue(l.usedJSHeapSize,l.jsHeapSizeLimit)})`),console.log(` total: ${te(l.totalJSHeapSize)}`)}}function ae(o){let d=o.indexOf("--testid");if(d>=0&&o[d+1])return{mode:"testid",value:o[d+1]};let i=o.indexOf("--test-id");if(i>=0&&o[i+1])return{mode:"testid",value:o[i+1]};let l=o.indexOf("--text");return l>=0&&o[l+1]?{mode:"text",value:o[l+1]}:null}async function me(o,d){let i=JSON.stringify(d.value),l=d.mode==="testid"?`(await t.findByTestId(${i})) || (await t.findById(${i}))`:`await t.findByText(${i})`;return await o.send({type:"evaluate",code:`(async () => {
|
|
10
10
|
const t = window.__sootsimTest
|
|
11
11
|
if (!t) return null
|
|
12
12
|
const n = ${l}
|
|
@@ -24,11 +24,11 @@ import{a as G}from"./chunk-3DDSYQHM.js";import{a as je,b as Le}from"./chunk-EXQJ
|
|
|
24
24
|
? resolved.cy
|
|
25
25
|
: n.absolutePosition.y + (n.layout.height || 0) / 2
|
|
26
26
|
return { x: cx, y: cy, testID: n.testID, text: n.text }
|
|
27
|
-
})()`})??null}async function
|
|
28
|
-
`))}async function
|
|
27
|
+
})()`})??null}async function $t(o,d={}){let{nav:i,keyboard:l,shell:f}=await nt(o);if(d.json){console.log(JSON.stringify({shell:f??null,nav:i,keyboard:l},null,2));return}let a=[];if(f){let y=f.activeApp??f.state??"<none>",S=f.showSwitcher?" (app switcher open)":"",I=typeof f.launchProgress=="number"&&f.launchProgress<.98?` launching (${Math.round(f.launchProgress*100)}%)`:"";a.push(`shell: ${y}${S}${I}`)}else a.push("shell: <unavailable>");if(i){let y=i.transitionPhase!=="idle"?` (${i.transitionPhase}, ${i.activeTransitionCount} active)`:"";if(a.push(`nav: phase=${i.transitionPhase}${y}`),i.screens.length===0)a.push(" <no registered screens \u2014 app may not use react-native-screens>");else for(let S of i.screens){let I=S.isActive?"\u25B6":" ",k=S.routeName?` ${S.routeName}`:"",b=S.headerHeight>0?` header=${S.headerHeight}`:"",v=S.largeTitleState&&S.largeTitleState!=="expanded"?` large-title=${S.largeTitleState}`:"";a.push(` ${I} #${S.id}${k}${b}${v}`)}}else a.push("nav: <runtime not available>");if(l&&l.visible){let y=l.spec?.keyboardType??"default",S=l.spec?.returnKeyType??"default";a.push(`keyboard: visible (${y}, return=${S}, mode=${l.mode??"?"})`)}else a.push("keyboard: hidden");console.log(a.join(`
|
|
28
|
+
`))}async function ne({bridge:o,maxMs:d,pollMs:i=50,stablePolls:l=3,strict:f=!1}){let a=await o.send({type:"evaluate",code:`(async () => {
|
|
29
29
|
const start = Date.now()
|
|
30
30
|
const deadline = start + ${Math.max(0,Math.round(d))}
|
|
31
|
-
const pollMs = ${Math.max(1,Math.round(
|
|
31
|
+
const pollMs = ${Math.max(1,Math.round(i))}
|
|
32
32
|
const requiredStablePolls = ${Math.max(1,Math.round(l))}
|
|
33
33
|
const strict = ${f?"true":"false"}
|
|
34
34
|
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms))
|
|
@@ -74,12 +74,12 @@ import{a as G}from"./chunk-3DDSYQHM.js";import{a as je,b as Le}from"./chunk-EXQJ
|
|
|
74
74
|
await sleep(pollMs)
|
|
75
75
|
}
|
|
76
76
|
return { settled: false, elapsed: Date.now() - start }
|
|
77
|
-
})()`}),{elapsed:y,settled:S}=
|
|
77
|
+
})()`}),{elapsed:y,settled:S}=a??{};return{elapsed:typeof y=="number"?y:d,settled:S===!0}}async function xt(o){let{bridge:d,args:i,positional:l}=o,f=l[1]?Number(l[1])*1e3:3e3,a=i.includes("--strict"),{elapsed:y,settled:S}=await ne({bridge:d,maxMs:f,strict:a});console.log(S?` settled in ${y}ms`:` timed out after ${y}ms (may still be animating)`)}async function St(o){let d=o.positional[1]?Number(o.positional[1]):.5;(!Number.isFinite(d)||d<0)&&(console.error(o.inspectUsage("sleep","[seconds]")),process.exit(1)),await X(d*1e3),console.log(` slept ${d}s`)}async function vt(o){let{bridge:d,args:i,positional:l}=o,f=l[1]?Number(l[1]):5,{tree:a}=await We(d,f);if(D(i)){B({depth:f,tree:a??null});return}console.log(typeof a=="string"?a:JSON.stringify(a,null,2))}async function kt(o,d={args:[]}){let i=await qe(o);if(D(d.args)){B(i);return}console.log(i.url)}async function Tt(o){let{wsPort:d,commandTimeoutMs:i,simId:l,positional:f}=o,a=f[1]?Number(f[1]):30,y=Math.max(1e3,(Number.isFinite(a)?a:30)*1e3),S=Math.max(1,Math.ceil(y/500));console.log(" waiting for sim reconnect...");let I=await it(d,i,l,{attempts:S});I||(console.error(" timed out waiting for sim reconnect"),process.exit(1)),I.bridge.close(),ce({source:"inspect wait",step:{wait:y},summary:`wait ${Math.round(y/1e3)}s`}),console.log(` ready: ${I.count} nodes`)}var Mt=new Set(["app-launch","toast","keyboard","screen","route","alert","actionsheet","picker","notification","fetch","console","shell","scroll","gesture","text-input","react-commit","animation","reanimated"]);function pe(o,d){let i=o.indexOf(d);if(i>=0&&i+1<o.length)return o[i+1]}function ro(o,d){if(!d.filter&&!d.equals)return!0;let i=o.data,l=[];if(i&&typeof i=="object")for(let a of["url","displayUrl","message","name","activeName","path","pathname","title","phase","event","type","kind"]){let y=i[a];typeof y=="string"&&y.length>0&&l.push(y)}let f=l.join(" ");return d.equals?l.some(a=>a===d.equals):d.filter?f.toLowerCase().includes(d.filter.toLowerCase()):!0}async function Nt(o){let{bridge:d,args:i,positional:l,inspectUsage:f}=o,a=l[1];a||(console.error(f("wait event","<kind> [--max-ms 5000] [--filter <substring>] [--equals <exact>] [--since now|cursor]")),process.exit(1)),Mt.has(a)||console.error(` warning: '${a}' is not a known timeline kind \u2014 waiting anyway. known: ${[...Mt].sort().join(", ")}`);let y=pe(i,"--max-ms"),S=y&&Number.isFinite(Number(y))?Math.max(100,Number(y)):5e3,I=pe(i,"--filter"),k=pe(i,"--equals"),b=pe(i,"--since")??"now",v=i.includes("--json"),_=Date.now(),T=_+S,C=200,c=_;for(;Date.now()<T;){let K={kinds:[a],since:b==="cursor"?void 0:c,limit:50},E=await d.send({type:"evaluate",code:`(async () => {
|
|
78
78
|
const t = window.SootSim?.bridges?.timeline
|
|
79
79
|
if (!t) return { ok: false, error: 'timeline bridge missing' }
|
|
80
80
|
return { ok: true, result: await t.recent(${JSON.stringify(K)}) }
|
|
81
|
-
})()`});(!E||!E.ok)&&(console.error(` could not query timeline: ${E&&"error"in E?E.error:"unknown"}`),process.exit(1));let
|
|
82
|
-
`).slice(0,5);for(let y of
|
|
81
|
+
})()`});(!E||!E.ok)&&(console.error(` could not query timeline: ${E&&"error"in E?E.error:"unknown"}`),process.exit(1));let J=E.result.events??[];for(let z of J)if(ro(z,{filter:I,equals:k})){let q=Date.now()-_;console.log(v?JSON.stringify({found:!0,elapsedMs:q,event:z}):` ${a} event after ${q}ms${I?` (filter: ${I})`:""}${k?` (equals: ${k})`:""}`);return}E.result.watermark&&E.result.watermark>c&&(c=E.result.watermark),await new Promise(z=>setTimeout(z,C))}let L=Date.now()-_;v?console.log(JSON.stringify({found:!1,elapsedMs:L,kind:a,filter:I,equals:k})):console.error(` \u26A0 wait event ${a} timed out after ${L}ms${I?` (filter: ${I})`:""}${k?` (equals: ${k})`:""}`),process.exit(1)}async function It(o){let{bridge:d,args:i}=o,l=i.includes("--strict"),f=i.indexOf("--max-ms"),a=f>=0&&i[f+1]?Math.max(100,Number(i[f+1])):3e3,{elapsed:y,settled:S}=await ne({bridge:d,maxMs:a,strict:l});S?console.log(` idle in ${y}ms`):(console.error(` \u26A0 wait idle timed out after ${y}ms (may still be animating)`),process.exit(1))}async function _t(o){let{bridge:d,args:i}=o,l=2e4,f=i.indexOf("--max-ms");f>=0&&i[f+1]&&(l=Math.max(100,Number(i[f+1])));let{ready:a,elapsedMs:y,nodes:S}=await ze(d,l);if(a){console.log(` ready in ${y}ms: ${S} nodes (flag)`);return}console.error(` \u26A0 wait ready timed out after ${y}ms \u2014 guest app did not emit sootsim:externalAppReady (nodes: ${S})`),process.exit(1)}async function Ft(o){let{bridge:d,args:i,positional:l,inspectUsage:f}=o,a=l[1];a||(console.error(f("wait selector","<testid> [--max-ms 5000]")),process.exit(1));let y=i.indexOf("--max-ms"),S=y>=0&&i[y+1]?Math.max(100,Number(i[y+1])):5e3,{found:I,node:k,elapsed:b}=await Ye(d,a,S);if(I&&k){let v=k.absolutePosition?`@(${Math.round(k.absolutePosition.x)},${Math.round(k.absolutePosition.y)})`:"",_=k.layout?`${Math.round(k.layout.width)}x${Math.round(k.layout.height)}`:"?x?";console.log(` found #${a} in ${b}ms ${_} ${v}`)}else console.error(` \u26A0 wait selector #${a} timed out after ${b??S}ms`),process.exit(1)}function Ct(o){return o==null?"\u2014":o<1024?`${o}B`:o<1024*1024?`${(o/1024).toFixed(1)}K`:`${(o/1024/1024).toFixed(1)}M`}function Dt(o){return o==null?" \u2026":o<1e3?`${o}ms`.padStart(5):`${(o/1e3).toFixed(2)}s`.padStart(5)}function ao(o){return o.error?"err":o.status==null?" \u2026 ":String(o.status)}function At(o){let d=new Date(o.startTs).toLocaleTimeString(),i=ao(o).padEnd(3),l=o.method.padEnd(5),f=Ct(o.size).padStart(6),a=Dt(o.durationMs);console.log(` [${d}] ${i} ${l} ${f} ${a} ${o.displayUrl}`),o.error&&console.log(` error: ${o.error}`)}function lo(o){let d=[["id",o.id],["source",o.source],["kind",o.kind],["method",o.method],["status",o.error?`error: ${o.error}`:`${o.status??"\u2014"} ${o.statusText??""}`.trim()],["url",o.url],["started",new Date(o.startTs).toLocaleTimeString()],["duration",Dt(o.durationMs).trim()],["size",Ct(o.size)],["content-type",o.type??"\u2014"]];for(let[i,l]of d)console.log(` ${i.padEnd(13)} ${l}`)}var co={error:"\x1B[31m",warn:"\x1B[33m",info:"\x1B[36m",debug:"\x1B[35m",log:"\x1B[37m"},Pt="\x1B[0m",uo="\x1B[2m";function Ot(o,d){let i=new Date(o.ts).toLocaleTimeString(),l=o.level.toUpperCase().padEnd(5),f=o.args.join(" ");if(d){let a=co[o.level];console.log(` ${uo}[${i}]${Pt} ${a}${l}${Pt} ${f}`)}else console.log(` [${i}] ${l} ${f}`);if(o.stack&&o.level==="error"){let a=o.stack.split(`
|
|
82
|
+
`).slice(0,5);for(let y of a)console.log(` ${y.trim()}`)}}var Q="__sootsimCliPerf",mo=120;async function Rt(o,d){let i=o.find((_,T)=>o[T-1]==="--id"),l=o.find((_,T)=>o[T-1]==="--text");if(i||l){let _=await d.send({type:"evaluate",code:je({id:i,text:l})});if(!_)throw new Error(i?`no node with id "${i}"`:`no node matching text "${l}"`);let{x:T,y:C,w:c,h:L}=_;return{x:T,y:C,w:c,h:L}}let f=o.find((_,T)=>o[T-1]==="--area");if(f){let _=f.split(",").map(K=>Number(K.trim()));if(_.length!==4||_.some(K=>!Number.isFinite(K)))throw new Error(`--area expects x,y,w,h (got "${f}")`);let[T,C,c,L]=_;return{x:T,y:C,w:c,h:L}}let a=_=>{let T=o.find((c,L)=>o[L-1]===_);if(T==null)return null;let C=Number(T);return Number.isFinite(C)?C:null},y=a("--x"),S=a("--y"),I=a("--w"),k=a("--h");if(y!=null||S!=null||I!=null||k!=null)return{x:y??0,y:S??0,w:I??1,h:k??1};let v=o.filter((_,T)=>T>0&&!_.startsWith("-")&&o[T-1]!=="--output"&&o[T-1]!=="--area"&&o[T-1]!=="--id"&&o[T-1]!=="--text"&&o[T-1]!=="--x"&&o[T-1]!=="--y"&&o[T-1]!=="--w"&&o[T-1]!=="--h").map(Number).filter(_=>Number.isFinite(_));if(v.length>=2){let[_,T,C=1,c=1]=v;return{x:_,y:T,w:C,h:c}}return null}function Ne(o){let d={"<8":0,"8-12":0,"12-16":0,"16-20":0,"20-33":0,">33":0};for(let i of o)i<8?d["<8"]++:i<12?d["8-12"]++:i<16?d["12-16"]++:i<20?d["16-20"]++:i<33?d["20-33"]++:d[">33"]++;console.log(" histogram:");for(let[i,l]of Object.entries(d)){let f="\u2588".repeat(Math.ceil(l/o.length*40));console.log(` ${i.padEnd(6)} ${f} ${l}`)}}async function fe(o,d,i){let l=Date.now()+d,f=await se(o,d);for(;;){if(i(f))return{settled:!0,state:f};if(Date.now()>=l)return{settled:!1,state:f};await X(16),f=await se(o)}}async function _e(o){return o.send({type:"evaluate",code:`(async () => {
|
|
83
83
|
const kb = window.__sootsimKeyboard
|
|
84
84
|
const test = window.__sootsimTest
|
|
85
85
|
if (!kb) return { error: 'keyboard bridge not available' }
|
|
@@ -111,8 +111,8 @@ import{a as G}from"./chunk-3DDSYQHM.js";import{a as je,b as Le}from"./chunk-EXQJ
|
|
|
111
111
|
frame: runtimeSnapshot?.keyboard?.frame ?? null,
|
|
112
112
|
focusedRect: runtimeSnapshot?.focused?.rect ?? null,
|
|
113
113
|
}
|
|
114
|
-
})()`})}async function
|
|
115
|
-
const requested = ${JSON.stringify(
|
|
114
|
+
})()`})}async function po(o,d=600){let i=Date.now()+d;for(;Date.now()<=i;){let l=await _e(o);if(l.visible)return l;await X(30)}return _e(o)}async function ge(o,d){let i=await _e(o);if(i.visible)return i;console.error(` ${d} requires the iOS keyboard to be visible. focus an input first with sootsim do tap-id/tap-text or sootsim do type-into.`),process.exit(1)}async function Et(o,d,i){return d==="appearance"?o.send({type:"evaluate",code:`(async () => {
|
|
115
|
+
const requested = ${JSON.stringify(i??"toggle")}
|
|
116
116
|
const rootBg = (document.documentElement?.style?.background || '').toLowerCase()
|
|
117
117
|
const inferredCurrent = rootBg.includes('33') ? 'dark' : 'light'
|
|
118
118
|
let next = requested
|
|
@@ -128,25 +128,25 @@ import{a as G}from"./chunk-3DDSYQHM.js";import{a as je,b as Le}from"./chunk-EXQJ
|
|
|
128
128
|
})()`}):o.send({type:"evaluate",code:`(async () => {
|
|
129
129
|
window.dispatchEvent(new CustomEvent(${JSON.stringify(d==="lock"?"sootsim:toggleLock":"sootsim:shake")}))
|
|
130
130
|
return { ok: true, action: ${JSON.stringify(d)} }
|
|
131
|
-
})()`})}function
|
|
132
|
-
`),process.exit(0))}if(k==="shell"){let
|
|
133
|
-
`),process.exit(0))}let t=we("inspect",e),s=["do","get","debug","wait"].map(
|
|
131
|
+
})()`})}function fo(o){let d={Enter:"return",NumpadEnter:"return",Backspace:"delete",Delete:"delete",Space:"space",ShiftLeft:"shift",ShiftRight:"shift"};if(d[o])return d[o];let i=o.match(/^Digit([0-9])$/);if(i)return i[1];let l=o.match(/^Key([A-Z])$/);return l?l[1].toLowerCase():null}function go(o){if(typeof o!="string")return null;let d=o.replace(/\s+/g," ").trim();return d?d.slice(0,80):null}function Bt(...o){for(let d of o){if(typeof d!="string")continue;let i=d.trim();if(i)return i}return null}async function j(o,d,i){let l=ce({source:o,step:d,summary:i});l.active&&(l.replaced?console.error(` draft: replaced unkept action "${l.replaced.summary}" \u2014 \`flow keep\` commits one action at a time`):console.error(" draft: action pending \u2014 `sootsim flow keep` to commit"))}function yo(o,d,i){if(!i||i.hit===!1)return null;let l=Bt(i.responderTestID,i.testID);if(l)return{step:{tapOn:{id:l}},summary:`tap #${l}`};let f=go(i.text);return f?{step:{tapOn:f},summary:`tap "${f}"`}:{step:{tapAtCoords:{x:o,y:d}},summary:`tap @${Math.round(o)},${Math.round(d)}`}}function Ie(o,d,i){let l=Bt(d?.testID,d?.id);return l?{step:{tapOn:{id:l}},summary:`tap #${l}`}:i==="id"?{step:{tapOn:{id:o}},summary:`tap #${o}`}:{step:{tapOn:o},summary:`tap "${o}"`}}async function Xs(o,d){let i=o[0]==="get"||o[0]==="do"||o[0]==="debug"||o[0]==="wait"?o[0]:null,l=i?o.slice(1):o,f=Oe(l,{port:d.port,commandTimeoutMs:d.timeoutMs,stripBooleanFlags:["--verbose","-v","--help","-h","--clear-state","--json","--all","--watch","-w","--strict","--no-wait","--dump","--failed","--slow","--tail","-f","--interactive-targets","--actions","--internal"],stripValueFlags:["--output","--nth","--index","--testid","--test-id","--text","--max-ms","--filter","--limit","--level","--threshold","--equals","--since"]}),a=f.positional,y=a[0],S=i==="get"||i==="do"||i==="debug"||i==="wait"?i:"inspect",I=typeof l[0]=="string"&&Ae.has(l[0]),k=I?l[0]:null,b=e=>I&&e===l[0]?`sootsim ${e}`:`sootsim ${S} ${e}`,v=(e,t)=>` usage: ${b(e)}${t?` ${t}`:""}`;if(!y||o.includes("--help")||o.includes("-h")){let e={bridgePort:7668,defaultShellUrl:Fe};if(S==="do"||S==="get"||S==="debug"||S==="wait"){let n=be(S,e);n&&(console.log(`${n}
|
|
132
|
+
`),process.exit(0))}if(k==="shell"){let n=we("shell",e);n&&(console.log(`${n}
|
|
133
|
+
`),process.exit(0))}let t=we("inspect",e),s=["do","get","debug","wait"].map(n=>be(n,e)).filter(n=>n!=null).join(`
|
|
134
134
|
|
|
135
135
|
`);console.log(`${t??""}
|
|
136
136
|
|
|
137
137
|
${s}
|
|
138
|
-
`),process.exit(0)}let _=f.wsPort,T=f.simId,C=f.commandTimeoutMs;if(y==="list"&&l.some(e=>e==="--drivers"||e==="-D")){let{buildDriverListRows:e}=await import("./drivers-
|
|
139
|
-
`);let s=Math.max(...t.map(
|
|
138
|
+
`),process.exit(0)}let _=f.wsPort,T=f.simId,C=f.commandTimeoutMs;if(y==="list"&&l.some(e=>e==="--drivers"||e==="-D")){let{buildDriverListRows:e}=await import("./drivers-SXP44QNY.js"),t=e();console.log(` available drivers (${t.length}):
|
|
139
|
+
`);let s=Math.max(...t.map(r=>r.id.length),6),n=Math.max(...t.map(r=>r.kind.length),4);for(let r of t){let u=r.available?"\u2713":"\u2717",m=r.id.padEnd(s),x=r.kind.padEnd(n);console.log(` ${u} ${m} ${x} ${r.description}`),r.available&&r.detail?console.log(` ${r.detail}`):!r.available&&r.reason&&console.log(` unavailable: ${r.reason}`)}return}let c=Re(f),L=T||"default",K=new Set(["errors","warnings","requests","js","eval","reload","globals","perf","list","wait","sleep"]),E=200;function J(e){let t=e.replace(/\s+/g," ").trim();if(!t)return"";if(/^<(!doctype html|html|\?xml)|<body[\s>]/i.test(t)){let n=/<title[^>]*>([^<]+)<\/title>/i.exec(e)?.[1]?.trim(),r=/<body[^>]*>([\s\S]*?)<\//i.exec(e)?.[1]?.replace(/<[^>]+>/g," ").replace(/\s+/g," ").trim().slice(0,80),u=n||r||"html error page";return`<html ${e.length}B> "${u}" (body elided \u2014 add --json for the full payload)`}return t.length<=E?t:`${t.slice(0,E)}\u2026 (+${t.length-E} more bytes)`}function z(e){let t=e.displayUrl||e.url;return e.status!=null?`${e.method} ${t} -> ${e.status}${e.statusText?` ${e.statusText}`:""}`:e.error?`${e.method} ${t} -> ${e.error}`:`${e.method} ${t}`}async function q(e){let t=gt()?1200:350;try{let{settled:s,elapsed:n}=await ne({bridge:e,maxMs:t,pollMs:32,stablePolls:2});s||process.stderr.write(` \u26A0 auto-wait timed out after ${n??t}ms \u2014 next command may see mid-animation state. use \`sootsim do settle\` for a longer wait.
|
|
140
140
|
`)}catch{}}async function w(){try{return await c.send({type:"evaluate",code:`(() => ({
|
|
141
141
|
console: window.__sootsimConsole?.count?.() || null,
|
|
142
142
|
requests: window.__sootsimTest?.getRequestCounts?.() || null,
|
|
143
|
-
}))()`})||{console:null,requests:null}}catch{return{console:null,requests:null}}}async function M(e={}){let t=e.counts!==void 0?e.counts:await Y(c,"getRequestCounts");if(!t||typeof t!="object")return;let s=Math.max(0,Number(t.failed)||0);if(s===0||!e.includeTail&&!ke("requests",
|
|
144
|
-
network: ${s} failed request${s===1?"":"s"}`),console.log(` inspect: ${b("requests")} 5`),!e.includeTail))return;let
|
|
143
|
+
}))()`})||{console:null,requests:null}}catch{return{console:null,requests:null}}}async function M(e={}){let t=e.counts!==void 0?e.counts:await Y(c,"getRequestCounts");if(!t||typeof t!="object")return;let s=Math.max(0,Number(t.failed)||0);if(s===0||!e.includeTail&&!ke("requests",L,String(s))||(console.log(`
|
|
144
|
+
network: ${s} failed request${s===1?"":"s"}`),console.log(` inspect: ${b("requests")} 5`),!e.includeTail))return;let n=await Y(c,"getFailedRequests",5);if(!(!Array.isArray(n)||n.length===0)){console.log(`
|
|
145
145
|
recent failed requests:
|
|
146
|
-
`);for(let
|
|
147
|
-
console: ${u.join(", ")}`),console.log(` inspect: ${b("errors")} 5`),
|
|
146
|
+
`);for(let r of n){let u=new Date(r.timestamp).toLocaleTimeString();console.log(` [${u}] ${z(r)}`),r.responseBody?console.log(` ${J(r.responseBody)}`):r.error&&console.log(` ${r.error}`)}}}async function Z(e={}){let t=e.counts!==void 0?e.counts:await c.send({type:"evaluate",code:"window.__sootsimConsole?.count?.() || { errors: 0, warnings: 0, total: 0 }"});if(!t||typeof t!="object")return;let s=t,n=Math.max(0,Number(s.errors)||0),r=Math.max(0,Number(s.warnings)||0);if(n===0&&r===0||!e.includeTail&&!ke("console",L,`${n}:${r}`))return;let u=[];if(n>0&&u.push(`${n} console error${n===1?"":"s"}`),r>0&&u.push(`${r} console warning${r===1?"":"s"}`),console.log(`
|
|
147
|
+
console: ${u.join(", ")}`),console.log(` inspect: ${b("errors")} 5`),r>0&&console.log(` inspect: ${b("warnings")} 5`),!e.includeTail||n===0)return;let m=await c.send({type:"evaluate",code:"window.__sootsimConsole?.getErrors?.(5) || []"});if(!(!Array.isArray(m)||m.length===0)){console.log(`
|
|
148
148
|
recent console errors:
|
|
149
|
-
`);for(let
|
|
149
|
+
`);for(let x of m){let g=new Date(x.timestamp).toLocaleTimeString(),$=Array.isArray(x.args)?x.args.map(F=>typeof F=="object"?JSON.stringify(F):String(F)).join(" "):String(x);console.log(` [${g}] ${$}`)}}}let P=["console","fetch","toast","alert","notification","screen","app-launch","keyboard","route","actionsheet","picker","shell","scroll","gesture","text-input","animation","reanimated"];async function V(e){let t=Pe(),s=null;try{s=await Ce(e,`(() => {
|
|
150
150
|
const tl = window.SootSim && window.SootSim.bridges && window.SootSim.bridges.timeline
|
|
151
151
|
if (!tl || typeof tl.summary !== 'function') return null
|
|
152
152
|
const cursorKey = ${JSON.stringify(t)}
|
|
@@ -162,37 +162,9 @@ ${s}
|
|
|
162
162
|
}
|
|
163
163
|
}
|
|
164
164
|
return summary ? { summary, consoleSplit } : null
|
|
165
|
-
})()`)}catch{return}if(!s||!s.summary||!s.summary.total)return;let
|
|
166
|
-
since last: ${
|
|
167
|
-
|
|
168
|
-
if (!t) return []
|
|
169
|
-
const all = await t.queryAll({ pruneHidden: true })
|
|
170
|
-
return all.filter(n => {
|
|
171
|
-
// skip zero-size nodes
|
|
172
|
-
if (!n.layout || n.layout.width <= 0 || n.layout.height <= 0) return false
|
|
173
|
-
// keep nodes with explicit accessibility roles or labels
|
|
174
|
-
if (n.accessibilityRole) return true
|
|
175
|
-
if (n.accessibilityHint) return true
|
|
176
|
-
if (n.isTextInput) return true
|
|
177
|
-
if (n.pressable) return true
|
|
178
|
-
// keep text leaf nodes
|
|
179
|
-
if (n.type === 'text' && n.text) return true
|
|
180
|
-
// keep views with intentional labels (not auto-derived)
|
|
181
|
-
if (n.accessibilityLabel && n.accessibilityLabel.length <= 30
|
|
182
|
-
&& n.accessibilityLabel !== n.text) return true
|
|
183
|
-
// skip container views without role (just concatenated child text)
|
|
184
|
-
return false
|
|
185
|
-
}).map(n => ({
|
|
186
|
-
role: n.accessibilityRole || (n.pressable ? 'button' : n.isTextInput ? 'textfield' : n.type === 'text' ? 'statictext' : 'none'),
|
|
187
|
-
label: n.accessibilityLabel || n.text || null,
|
|
188
|
-
hint: n.accessibilityHint || null,
|
|
189
|
-
state: n.accessibilityState || null,
|
|
190
|
-
testID: n.testID || null,
|
|
191
|
-
position: n.absolutePosition ? { x: Math.round(n.absolutePosition.x), y: Math.round(n.absolutePosition.y) } : null,
|
|
192
|
-
size: n.layout ? { w: Math.round(n.layout.width), h: Math.round(n.layout.height) } : null,
|
|
193
|
-
}))
|
|
194
|
-
})()`});if(!Array.isArray(t)||t.length===0){console.log(" no accessible nodes found");break}if(o.includes("--json"))console.log(JSON.stringify(t,null,2));else{console.log(` accessibility tree (${t.length} nodes):
|
|
195
|
-
`);for(let s of t){let r=[];if(r.push(`[${s.role}]`),s.label){let n=s.label.length>50?s.label.slice(0,47)+"...":s.label;r.push(`"${n}"`)}if(s.hint&&r.push(`(hint: "${s.hint}")`),s.testID&&r.push(`#${s.testID}`),s.state){let n=[];s.state.disabled&&n.push("disabled"),s.state.selected&&n.push("selected"),s.state.checked===!0&&n.push("checked"),s.state.checked==="mixed"&&n.push("mixed"),s.state.busy&&n.push("busy"),s.state.expanded===!0&&n.push("expanded"),s.state.expanded===!1&&n.push("collapsed"),n.length&&r.push(`{${n.join(", ")}}`)}s.position&&r.push(`@(${s.position.x},${s.position.y})`),s.size&&r.push(`${s.size.w}x${s.size.h}`),console.log(" "+r.join(" "))}}break}case"find":{await gt({bridge:c,args:o,effectiveArgs:l,positional:i,inspectUsage:v});break}case"count":{await mt(c,{args:l});break}case"keyboard":{await yt(c,{json:o.includes("--json")});break}case"screens":{await wt(c,{json:o.includes("--json")});break}case"memory":{await bt(c,{args:l});break}case"wait":{await kt({wsPort:_,commandTimeoutMs:C,simId:T,positional:i});break}case"sleep":{await $t({positional:i,inspectUsage:v});break}case"settle":{await xt({bridge:c,args:o,positional:i});break}case"ready":{await It({bridge:c,args:o});break}case"idle":{await Nt({bridge:c,args:o,positional:i});break}case"selector":{await _t({bridge:c,args:o,positional:i,inspectUsage:v});break}case"event":{await Mt({bridge:c,args:o,positional:i,inspectUsage:v});break}case"layout":{let e=i[1];e||(console.error(v("layout","<id>")),process.exit(1));let t=await c.send({type:"evaluate",code:`(async () => await window.__sootsimTest.getLayout(${JSON.stringify(e)}))()`});console.log(JSON.stringify(t,null,2));break}case"capture":case"screenshot":{let t=o.find(($,g)=>o[g-1]==="--output")||"/tmp/sootsim-inspect.png",s=await Ot(o,c),r={type:"screenshot"};s&&(r.crop=s);let u=(await c.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 e=await Ot(o,c);e||(console.error(v("sample-color","<x> <y> [w] [h] | --id <testID> | --text <text>")),console.error(" samples an averaged color from the canvas. coords are logical sootsim units."),process.exit(1));let t=await c.send({type:"evaluate",code:Le(e)});if(o.includes("--json"))console.log(JSON.stringify(t,null,2));else{let{r:s,g:r,b:n,a:u,hex:m,samples:$}=t,g=e.w===1&&e.h===1?`@(${e.x},${e.y})`:`@(${e.x},${e.y}) ${e.w}x${e.h}`;console.log(` ${m} rgba(${s}, ${r}, ${n}, ${u}) ${g} ${$} samples`)}break}case"node":{let e=i[1];e||(console.error(v("node","<matcher>")),console.error(" resolves testID, id, then text \u2014 dumps full node info as JSON"),process.exit(1));let t=await c.send({type:"evaluate",code:`(async () => {
|
|
165
|
+
})()`)}catch{return}if(!s||!s.summary||!s.summary.total)return;let n=s.summary.byKind??{},r=[],u=new Set;for(let m of P){let x=n[m];if(x)if(u.add(m),m==="console"&&s.consoleSplit){let{error:g,warn:$}=s.consoleSplit;g>0&&r.push(`${g} error${g===1?"":"s"}`),$>0&&r.push(`${$} warning${$===1?"":"s"}`)}else r.push(`${x} ${m}${x===1?"":"s"}`)}for(let[m,x]of Object.entries(n))!u.has(m)&&x&&r.push(`${x} ${m}${x===1?"":"s"}`);if(r.length!==0&&(console.log(`
|
|
166
|
+
since last: ${r.join(" \xB7 ")} \u2014 sootsim what-happened`),s.summary.lastAt))try{await $e(e,"SootSim.bridges.timeline.cursorAdvance",t,s.summary.lastAt)}catch{}}let ee=new Set(["tap","double-tap","tap-text","tap-id","type","type-into","key","key-sequence","keycode","drag","swipe","long-press","touch","gesture","pinch","scroll","shell"]),oe=new Set(["a11y","capture","count","double-tap","drag","find","gesture","layout","long-press","node","pinch","sample-color","scroll","screenshot","swipe","tap","tap-id","tap-text","touch","tree","type-into"]),ye=(o.includes("--verbose")||o.includes("-v"))&&!o.includes("--json");S==="do"&&y==="shell"&&(console.error(" `sootsim do shell` was removed. use `sootsim shell ...` instead."),process.exit(1)),ee.has(y)&&await Ee(c),oe.has(y)&&await de(c,{verbose:ye});try{switch(y){case"list":{await bt({bridge:c,simId:T,args:l});break}case"tree":{await vt({bridge:c,args:l,positional:a});break}case"a11y":{let e=await Ue(c);if(!Array.isArray(e)||e.length===0){console.log(" no accessible nodes found");break}if(o.includes("--json"))console.log(JSON.stringify(e,null,2));else{console.log(` accessibility tree (${e.length} nodes):
|
|
167
|
+
`);for(let t of e){let s=[];if(s.push(`[${t.role}]`),t.label){let n=t.label.length>50?t.label.slice(0,47)+"...":t.label;s.push(`"${n}"`)}if(t.hint&&s.push(`(hint: "${t.hint}")`),t.testID&&s.push(`#${t.testID}`),t.state){let n=[];t.state.disabled&&n.push("disabled"),t.state.selected&&n.push("selected"),t.state.checked===!0&&n.push("checked"),t.state.checked==="mixed"&&n.push("mixed"),t.state.busy&&n.push("busy"),t.state.expanded===!0&&n.push("expanded"),t.state.expanded===!1&&n.push("collapsed"),n.length&&s.push(`{${n.join(", ")}}`)}t.position&&s.push(`@(${t.position.x},${t.position.y})`),t.size&&s.push(`${t.size.w}x${t.size.h}`),console.log(" "+s.join(" "))}}break}case"find":{await yt({bridge:c,args:o,effectiveArgs:l,positional:a,inspectUsage:v});break}case"count":{await pt(c,{args:l});break}case"keyboard":{await ht(c,{json:o.includes("--json")});break}case"screens":{await $t(c,{json:o.includes("--json")});break}case"memory":{await wt(c,{args:l});break}case"wait":{await Tt({wsPort:_,commandTimeoutMs:C,simId:T,positional:a});break}case"sleep":{await St({positional:a,inspectUsage:v});break}case"settle":{await xt({bridge:c,args:o,positional:a});break}case"ready":{await _t({bridge:c,args:o});break}case"idle":{await It({bridge:c,args:o,positional:a});break}case"selector":{await Ft({bridge:c,args:o,positional:a,inspectUsage:v});break}case"event":{await Nt({bridge:c,args:o,positional:a,inspectUsage:v});break}case"layout":{let e=a[1];e||(console.error(v("layout","<id>")),process.exit(1));let t=await c.send({type:"evaluate",code:`(async () => await window.__sootsimTest.getLayout(${JSON.stringify(e)}))()`});console.log(JSON.stringify(t,null,2));break}case"capture":case"screenshot":{let t=o.find((x,g)=>o[g-1]==="--output")||"/tmp/sootsim-inspect.png",s=await Rt(o,c),n={type:"screenshot"};s&&(n.crop=s);let u=(await c.send(n)).replace(/^data:image\/png;base64,/,"");s&&console.log(` area: x=${s.x} y=${s.y} w=${s.w} h=${s.h}`),(await import("fs")).writeFileSync(t,Buffer.from(u,"base64")),console.log(` saved: ${t}`);break}case"sample-color":{let e=await Rt(o,c);e||(console.error(v("sample-color","<x> <y> [w] [h] | --id <testID> | --text <text>")),console.error(" samples an averaged color from the canvas. coords are logical sootsim units."),process.exit(1));let t=await c.send({type:"evaluate",code:Je(e)});if(o.includes("--json"))console.log(JSON.stringify(t,null,2));else{let{r:s,g:n,b:r,a:u,hex:m,samples:x}=t,g=e.w===1&&e.h===1?`@(${e.x},${e.y})`:`@(${e.x},${e.y}) ${e.w}x${e.h}`;console.log(` ${m} rgba(${s}, ${n}, ${r}, ${u}) ${g} ${x} samples`)}break}case"node":{let e=a[1];e||(console.error(v("node","<matcher>")),console.error(" resolves testID, id, then text \u2014 dumps full node info as JSON"),process.exit(1));let t=await c.send({type:"evaluate",code:`(async () => {
|
|
196
168
|
const t = window.__sootsimTest
|
|
197
169
|
const q = ${JSON.stringify(e)}
|
|
198
170
|
let node = null
|
|
@@ -248,17 +220,17 @@ ${s}
|
|
|
248
220
|
transform,
|
|
249
221
|
parentChain,
|
|
250
222
|
}
|
|
251
|
-
})()`});console.log(JSON.stringify(t,null,2));break}case"tap":{let e=Number(
|
|
223
|
+
})()`});console.log(JSON.stringify(t,null,2));break}case"tap":{let e=Number(a[1]),t=Number(a[2]),s=ae(o);if(s){let u=await me(c,s);u||(console.error(` not found: ${s.value}`),s.mode==="testid"&&G("wait-selector-for-missing-testid",s.value),process.exit(1)),e=u.x,t=u.y}(!Number.isFinite(e)||!Number.isFinite(t))&&(console.error(v("tap","<x> <y> | --testid <id> | --text <t>")),process.exit(1));let n=await c.send({type:"tap",x:e,y:t}),r=yo(e,t,n);r&&await j("inspect tap",r.step,r.summary),console.log(JSON.stringify(n,null,2));break}case"drag":case"swipe":{let e=Number(a[1]),t=Number(a[2]),s=Number(a[3]),n=Number(a[4]),r=y==="swipe"?10:12,u=y==="swipe"?8:16,m=a[5]?Number(a[5]):r,x=a[6]?Number(a[6]):u;(!Number.isFinite(e)||!Number.isFinite(t)||!Number.isFinite(s)||!Number.isFinite(n)||!Number.isFinite(m)||!Number.isFinite(x))&&(console.error(v(y,"<x1> <y1> <x2> <y2> [steps] [stepMs]")),process.exit(1));let g=await c.send({type:"evaluate",code:`(async () => {
|
|
252
224
|
const interact = window.__sootsimInteract
|
|
253
225
|
if (!interact?.drag) return { ok: false, reason: 'no interact.drag' }
|
|
254
|
-
const value = await interact.drag(${e}, ${t}, ${s}, ${
|
|
226
|
+
const value = await interact.drag(${e}, ${t}, ${s}, ${n}, ${Math.max(1,Math.round(m))}, ${Math.max(0,Math.round(x))})
|
|
255
227
|
return { ok: !!value, value }
|
|
256
|
-
})()`});if(g?.ok){let
|
|
228
|
+
})()`});if(g?.ok){let $=Math.max(1,Math.round(Math.max(1,m)*Math.max(0,x)));await j(`inspect ${y}`,{swipe:{start:`${e}, ${t}`,end:`${s}, ${n}`,duration:$}},`${y} ${e},${t} -> ${s},${n}`)}console.log(JSON.stringify(g,null,2));break}case"pinch":{let e=Number(a[1]),t=Number(a[2]),s=Number(a[3]),n=Number(a[4]),r=Number(a[5]),u=Number(a[6]),m=Number(a[7]),x=Number(a[8]),g=a[9]?Number(a[9]):12,$=a[10]?Number(a[10]):16;(!Number.isFinite(e)||!Number.isFinite(t)||!Number.isFinite(s)||!Number.isFinite(n)||!Number.isFinite(r)||!Number.isFinite(u)||!Number.isFinite(m)||!Number.isFinite(x)||!Number.isFinite(g)||!Number.isFinite($))&&(console.error(v("pinch","<x1> <y1> <x2> <y2> <x1'> <y1'> <x2'> <y2'> [steps] [stepMs]")),process.exit(1));let F=await c.send({type:"evaluate",code:`(async () => {
|
|
257
229
|
const interact = window.__sootsimInteract
|
|
258
230
|
if (!interact?.pinch) return { ok: false, reason: 'no interact.pinch' }
|
|
259
|
-
const value = await interact.pinch(${e}, ${t}, ${s}, ${
|
|
231
|
+
const value = await interact.pinch(${e}, ${t}, ${s}, ${n}, ${r}, ${u}, ${m}, ${x}, ${Math.max(1,Math.round(g))}, ${Math.max(0,Math.round($))})
|
|
260
232
|
return { ok: !!value, value }
|
|
261
|
-
})()`});F?.ok&&await j("inspect pinch",{pinch:{from:[e,t,s,
|
|
233
|
+
})()`});F?.ok&&await j("inspect pinch",{pinch:{from:[e,t,s,n],to:[r,u,m,x],steps:Math.max(1,Math.round(g)),stepMs:Math.max(0,Math.round($))}},`pinch (${e},${t}) (${s},${n}) -> (${r},${u}) (${m},${x})`),console.log(JSON.stringify(F,null,2));break}case"tap-text":{let e=a[1];e||(console.error(v("tap-text","<text>")),process.exit(1));let t=R=>{let A=o.indexOf(R);return A>=0&&A+1<o.length?o[A+1]:null},s=R=>o.includes(R),n=t("--nth")??t("--index"),r=n!==null?Number(n):null;r!==null&&!Number.isFinite(r)&&(console.error(` --nth/--index requires an integer, got: ${n}`),process.exit(1));let u=t("--within"),m=t("--role"),x=s("--exact"),g=s("--first"),$=t("--min-y"),F=t("--max-y"),W=t("--min-x"),H=t("--max-x");for(let[R,A]of[["--min-y",$],["--max-y",F],["--min-x",W],["--max-x",H]])A!==null&&!Number.isFinite(Number(A))&&(console.error(` ${R} requires a number, got: ${A}`),process.exit(1));let U=o.indexOf("--near"),N=null;if(U>=0){let R=Number(o[U+1]),A=Number(o[U+2]);(!Number.isFinite(R)||!Number.isFinite(A))&&(console.error(" --near requires two numbers: --near <x> <y>"),process.exit(1)),N={x:R,y:A}}let h=JSON.stringify({query:e,exact:x,role:m,within:u,minX:W!==null?Number(W):null,maxX:H!==null?Number(H):null,minY:$!==null?Number($):null,maxY:F!==null?Number(F):null,near:N,nth:r,first:g}),p=await c.send({type:"evaluate",code:`(async () => {
|
|
262
234
|
const t = window.__sootsimTest
|
|
263
235
|
if (!t) return { error: 'bridge-not-ready' }
|
|
264
236
|
const F = ${h}
|
|
@@ -372,7 +344,7 @@ ${s}
|
|
|
372
344
|
total,
|
|
373
345
|
idx,
|
|
374
346
|
}
|
|
375
|
-
})()`});if(p?.error==="bridge-not-ready"&&(console.error(" sootsim test bridge not ready"),process.exit(1)),p?.ambiguous){let R=p.candidates;console.error(` ambiguous: ${p.total} matches for "${e}"`);for(let A of R){let he=A.abs?`@(${Math.round(A.abs.x)},${Math.round(A.abs.y)})`:"",le=A.layout?` ${A.layout.width}x${A.layout.height}`:"",
|
|
347
|
+
})()`});if(p?.error==="bridge-not-ready"&&(console.error(" sootsim test bridge not ready"),process.exit(1)),p?.ambiguous){let R=p.candidates;console.error(` ambiguous: ${p.total} matches for "${e}"`);for(let A of R){let he=A.abs?`@(${Math.round(A.abs.x)},${Math.round(A.abs.y)})`:"",le=A.layout?` ${A.layout.width}x${A.layout.height}`:"",jt=A.testID?` #${A.testID}`:"",Jt=A.text?` "${A.text}"`:"",Lt=A.ancestorTestIDs.length>0?` within ${A.ancestorTestIDs.slice(0,3).map(Wt=>`#${Wt}`).join(" > ")}`:"";console.error(` [${A.idx}] <${A.type}>${Jt}${jt} ${he}${le}${Lt}`)}p.total>R.length&&console.error(` ... and ${p.total-R.length} more`),console.error(" pick one:"),console.error(" --nth <index> pick the nth match (top-to-bottom, left-to-right; negatives from end)"),console.error(" --within <testID> narrow to descendants of a node"),console.error(" --min-y / --max-y geometric filter (pixels, absolute)"),console.error(" --min-x / --max-x geometric filter (pixels, absolute)"),console.error(" --near <x> <y> pick the closest match to a point"),console.error(" --exact exact text match (default is substring)"),console.error(" --role <role> narrow to accessibilityRole"),console.error(" --first keep the old pick-first-silently behavior"),process.exit(2)}p?.nthOutOfRange&&(console.error(` not found: nth ${p.nth} of ${p.total} match${p.total===1?"":"es"} for "${e}"`),process.exit(1)),(!p||typeof p.cx!="number")&&(console.error(` not found: ${e}`),process.exit(1));let O=await c.send({type:"tap",x:p.cx,y:p.cy});if(O?.hit!==!1&&O?.ok!==!1){let R=Ie(e,{id:p.target?.id??null,testID:p.target?.testID??null,type:p.target?.type??null,cx:p.cx,cy:p.cy},"text");await j("inspect tap-text",R.step,R.summary)}console.log(JSON.stringify({matched:p.match,tapped:{nodeId:p.target?.nodeId??null,id:p.target?.id??null,testID:p.target?.testID??null,type:p.target?.type??null,cx:p.cx,cy:p.cy},...p.strategy&&p.strategy!=="matched-node"?{strategy:p.strategy}:{},...p.total>1||r!==null?{nth:{index:p.idx,total:p.total}}:{},result:O},null,2));break}case"tap-best":{let e=a[1];e||(console.error(v("tap-best","<query>")),process.exit(1));let t=JSON.stringify(e),s=await c.send({type:"evaluate",code:`(async () => {
|
|
376
348
|
const t = window.__sootsimTest
|
|
377
349
|
if (!t) return { error: 'bridge-not-ready' }
|
|
378
350
|
// try testID first \u2014 strongest signal of "this is the
|
|
@@ -413,7 +385,7 @@ ${s}
|
|
|
413
385
|
}
|
|
414
386
|
}
|
|
415
387
|
return { strategy: 'none' }
|
|
416
|
-
})()`});"error"in s&&(console.error(` ${s.error}`),process.exit(1)),s.strategy==="none"&&(console.error(` tap-best: no testID or visible text matched "${e}". try \`sootsim find --interactive-targets\` to list candidates.`),process.exit(1));let
|
|
388
|
+
})()`});"error"in s&&(console.error(` ${s.error}`),process.exit(1)),s.strategy==="none"&&(console.error(` tap-best: no testID or visible text matched "${e}". try \`sootsim find --interactive-targets\` to list candidates.`),process.exit(1));let n=s.node,r=n.absolutePosition.x+n.layout.width/2,u=n.absolutePosition.y+n.layout.height/2,m=await c.send({type:"tap",x:r,y:u});if(m?.hit!==!1&&m?.ok!==!1){let x=Ie(e,{id:n.id,testID:n.testID,type:n.type,cx:r,cy:u},s.strategy==="testid"?"id":"text");await j("inspect tap-best",x.step,x.summary)}console.log(JSON.stringify({matched:{strategy:s.strategy,nodeId:n.nodeId,id:n.id,testID:n.testID,type:n.type,text:n.text},tapped:{cx:r,cy:u},result:m},null,2));break}case"tap-id":{let e=a[1];e||(console.error(v("tap-id","<id>")),process.exit(1));let t=JSON.stringify(e),s=await c.send({type:"evaluate",code:`(async () => {
|
|
417
389
|
const t = window.__sootsimTest
|
|
418
390
|
if (!t) return null
|
|
419
391
|
const n = (await t.findByTestId(${t})) || (await t.findById(${t}))
|
|
@@ -448,7 +420,7 @@ ${s}
|
|
|
448
420
|
},
|
|
449
421
|
strategy: (resolved && resolved.strategy) || 'matched-node',
|
|
450
422
|
}
|
|
451
|
-
})()`});(!s||typeof s.cx!="number")&&(console.error(` not found: ${e}`),process.exit(1));let
|
|
423
|
+
})()`});(!s||typeof s.cx!="number")&&(console.error(` not found: ${e}`),process.exit(1));let n=await c.send({type:"tap",x:s.cx,y:s.cy});if(n?.hit!==!1&&n?.ok!==!1){let r=Ie(e,{id:s.target?.id??null,testID:s.target?.testID??null,type:s.target?.type??null,cx:s.cx,cy:s.cy},"id");await j("inspect tap-id",r.step,r.summary)}console.log(JSON.stringify({matched:s.match,tapped:{nodeId:s.target?.nodeId??null,id:s.target?.id??null,testID:s.target?.testID??null,type:s.target?.type??null,cx:s.cx,cy:s.cy},...s.strategy&&s.strategy!=="matched-node"?{strategy:s.strategy}:{},result:n},null,2));break}case"type-into":{let e=a[1],t=a.slice(2).join(" ");(!e||!t)&&(console.error(v("type-into","<id> <text>")),process.exit(1));let s=JSON.stringify(e),n=await c.send({type:"evaluate",code:`(async () => {
|
|
452
424
|
const t = window.__sootsimTest
|
|
453
425
|
if (!t) return null
|
|
454
426
|
const n = await (t.findByTestId(${s}) || t.findById(${s}))
|
|
@@ -460,41 +432,41 @@ ${s}
|
|
|
460
432
|
isTextInput: !!n.isTextInput,
|
|
461
433
|
placeholder: n.placeholder || null,
|
|
462
434
|
}
|
|
463
|
-
})()`});(!
|
|
435
|
+
})()`});(!n||typeof n.cx!="number")&&(console.error(` not found: ${e}`),process.exit(1)),n.isTextInput||console.error(` warning: ${e} is not a text input (isTextInput: false)`);let r=await c.send({type:"tap",x:n.cx,y:n.cy}),u=await po(c);u.visible||(console.error(` keyboard did not open after tapping ${e}`),process.exit(1));let m=u.focusedInput;m&&(m.testID===e||m.id===e||(console.error(` focus routing mismatch after tap: requested ${JSON.stringify(e)} but focus is on ${JSON.stringify(m.testID??m.id??null)}. did the tap land on an outer Pressable wrapper?`),process.exit(1))),await c.send({type:"keyboard",action:"type",text:t}),await j("inspect type-into",{tapOn:{id:e},inputText:t},`type-into #${e} ${JSON.stringify(t)}`),console.log(JSON.stringify({target:e,isTextInput:n.isTextInput,keyboardOpened:u.visible??r?.keyboardOpened??!1,focusedInput:u.focusedInput??null,typed:t},null,2));break}case"type":{let e=a.slice(1).join(" ");e||(console.error(v("type","<text>")),process.exit(1)),await ge(c,"type"),await c.send({type:"keyboard",action:"type",text:e}),await j("inspect type",{inputText:e},`type ${JSON.stringify(e)}`),console.log(` typed: ${JSON.stringify(e)}`);break}case"key":{let e=a[1];e||(console.error(v("key","<name>")),process.exit(1)),await ge(c,"key"),await c.send({type:"keyboard",action:"press",text:e}),await j("inspect key",{pressKey:e},`key ${e}`),console.log(` pressed: ${e}`);break}case"key-sequence":{let e=a.slice(1);e.length===0&&(console.error(v("key-sequence","<key> [<key> ...]")),process.exit(1)),await ge(c,"key-sequence");for(let t of e)await c.send({type:"keyboard",action:"press",text:t});await j("inspect key-sequence",{pressKey:e.join(" ")},`key-sequence ${e.join(" ")}`),console.log(` pressed: ${e.join(", ")}`);break}case"keycode":{let e=a.slice(1);e.length===0&&(console.error(v("keycode","<code> [<code> ...]")),process.exit(1));let t=e.map(n=>({code:n,key:fo(n)})),s=t.filter(n=>!n.key);s.length>0&&(console.error(` unsupported keycode(s): ${s.map(n=>n.code).join(", ")}`),process.exit(1)),await ge(c,"keycode");for(let n of t)await c.send({type:"keyboard",action:"press",text:n.key});await j("inspect keycode",{pressKey:t.map(n=>n.key).join(" ")},`keycode ${e.join(" ")}`),console.log(` pressed: ${e.join(", ")}`);break}case"dispatch":{let e=a[1];e||(console.error(v("dispatch","<char>")),process.exit(1)),await c.send({type:"keyboard",action:"dispatchKey",text:e}),await j("inspect dispatch",{dispatchKey:e},`dispatch ${JSON.stringify(e)}`),console.log(` dispatched: ${e}`);break}case"dismiss":{await c.send({type:"keyboard",action:"dismiss"}),await j("inspect dismiss",{hideKeyboard:!0},"dismiss keyboard"),console.log(" keyboard dismissed");break}case"double-tap":{let e=Number(a[1]),t=Number(a[2]),s=ae(o);if(s){let m=await me(c,s);m||(console.error(` not found: ${s.value}`),s.mode==="testid"&&G("wait-selector-for-missing-testid",s.value),process.exit(1)),e=m.x,t=m.y}let n=a[3]?Number(a[3]):80;(!Number.isFinite(e)||!Number.isFinite(t)||!Number.isFinite(n))&&(console.error(v("double-tap","<x> <y> [gapMs] | --testid <id>")),process.exit(1));let r=Math.max(0,Math.round(n)),u=await c.send({type:"evaluate",code:`(async () => {
|
|
464
436
|
const interact = window.__sootsimInteract
|
|
465
437
|
if (interact?.doubleTap) {
|
|
466
438
|
return {
|
|
467
|
-
ok: !!(await interact.doubleTap(${e}, ${t}, ${
|
|
468
|
-
gapMs: ${
|
|
439
|
+
ok: !!(await interact.doubleTap(${e}, ${t}, ${r})),
|
|
440
|
+
gapMs: ${r},
|
|
469
441
|
}
|
|
470
442
|
}
|
|
471
443
|
if (!interact?.tap) {
|
|
472
|
-
return { ok: false, reason: 'no interact.tap', gapMs: ${
|
|
444
|
+
return { ok: false, reason: 'no interact.tap', gapMs: ${r} }
|
|
473
445
|
}
|
|
474
446
|
const first = await interact.tap(${e}, ${t})
|
|
475
447
|
if (!first || first.hit === false) {
|
|
476
|
-
return { ok: false, reason: 'first tap missed', gapMs: ${
|
|
448
|
+
return { ok: false, reason: 'first tap missed', gapMs: ${r}, first }
|
|
477
449
|
}
|
|
478
|
-
await new Promise((resolve) => setTimeout(resolve, ${
|
|
450
|
+
await new Promise((resolve) => setTimeout(resolve, ${r}))
|
|
479
451
|
const second = await interact.tap(${e}, ${t})
|
|
480
452
|
return {
|
|
481
453
|
ok: !!second && second.hit !== false,
|
|
482
|
-
gapMs: ${
|
|
454
|
+
gapMs: ${r},
|
|
483
455
|
first,
|
|
484
456
|
second,
|
|
485
457
|
}
|
|
486
|
-
})()`});u?.ok&&await j("inspect double-tap",{doubleTapAtCoords:{x:e,y:t,gapMs:
|
|
458
|
+
})()`});u?.ok&&await j("inspect double-tap",{doubleTapAtCoords:{x:e,y:t,gapMs:r}},`double-tap @${e},${t}`),console.log(JSON.stringify(u,null,2));break}case"long-press":{let e=Number(a[1]),t=Number(a[2]),s=ae(o);if(s){let u=await me(c,s);u||(console.error(` not found: ${s.value}`),s.mode==="testid"&&G("wait-selector-for-missing-testid",s.value),process.exit(1)),e=u.x,t=u.y}let n=a[3]?Number(a[3]):600;(!Number.isFinite(e)||!Number.isFinite(t)||!Number.isFinite(n))&&(console.error(v("long-press","<x> <y> [durationMs] | --testid <id>")),process.exit(1));let r=await c.send({type:"evaluate",code:`(async () => {
|
|
487
459
|
const interact = window.__sootsimInteract
|
|
488
460
|
if (!interact?.longPress) return { ok: false, reason: 'no interact.longPress' }
|
|
489
|
-
const value = await interact.longPress(${e}, ${t}, ${Math.max(0,Math.round(
|
|
461
|
+
const value = await interact.longPress(${e}, ${t}, ${Math.max(0,Math.round(n))})
|
|
490
462
|
return { ok: !!value, value }
|
|
491
|
-
})()`});
|
|
463
|
+
})()`});r?.ok&&await j("inspect long-press",{tapAtCoords:{x:e,y:t}},`long-press @${e},${t}`),console.log(JSON.stringify(r,null,2));break}case"touch":{let e=a[1],t=Number(a[2]),s=Number(a[3]),n=a[4]?Number(a[4]):999,r=e==="down"?"touchDown":e==="move"?"touchMove":e==="up"?"touchUp":e==="cancel"?"touchCancel":null;r||(console.error(v("touch","<down|move|up|cancel> <x> <y> [pointerId]")),process.exit(1)),e!=="cancel"&&(!Number.isFinite(t)||!Number.isFinite(s))&&(console.error(v("touch","<down|move|up|cancel> <x> <y> [pointerId]")),process.exit(1));let u=e==="down"?"tap":e==="move"?"move":null,m=u&&Number.isFinite(t)&&Number.isFinite(s)?`window.dispatchEvent(new CustomEvent('sootsim:agentAction', { detail: { type: '${u}', x: ${t}, y: ${s} } }));`:"",x=await c.send({type:"evaluate",code:`(async () => {
|
|
492
464
|
${m}
|
|
493
465
|
const interact = window.__sootsimInteract
|
|
494
|
-
if (!interact?.${
|
|
495
|
-
const value = ${e==="cancel"?`await interact.${
|
|
466
|
+
if (!interact?.${r}) return { ok: false, reason: 'no interact.${r}' }
|
|
467
|
+
const value = ${e==="cancel"?`await interact.${r}(${Math.max(1,Math.round(n))})`:`await interact.${r}(${t}, ${s}, ${Math.max(1,Math.round(n))})`}
|
|
496
468
|
return { ok: !!value, value }
|
|
497
|
-
})()`})
|
|
469
|
+
})()`});x?.ok&&e!=="cancel"&&await j("inspect touch",{tapAtCoords:{x:t,y:s}},`touch ${e} @${t},${s}`),console.log(JSON.stringify(x,null,2));break}case"gesture":{let e=["scroll-up","scroll-down","scroll-left","scroll-right","swipe-from-left-edge","swipe-from-right-edge","swipe-from-top-edge","swipe-from-bottom-edge"],t=a[1],s=a[2]?Number(a[2]):220;(!t||!Number.isFinite(s))&&(console.error(v("gesture","<preset> [durationMs]")),console.error(` presets: ${e.join(", ")}`),process.exit(1)),e.includes(t)||(console.error(` unknown gesture preset: ${t}`),console.error(` presets: ${e.join(", ")}`),process.exit(1));let n=await c.send({type:"evaluate",code:`(async () => {
|
|
498
470
|
const spec = globalThis.__sootsimDeviceSpec || {}
|
|
499
471
|
return {
|
|
500
472
|
width: spec.width || window.innerWidth || 393,
|
|
@@ -502,12 +474,12 @@ ${s}
|
|
|
502
474
|
statusBarHeight: spec.statusBarHeight || 0,
|
|
503
475
|
homeIndicatorHeight: spec.homeIndicatorHeight || 0,
|
|
504
476
|
}
|
|
505
|
-
})()`}),
|
|
477
|
+
})()`}),r=Number(n?.width)||393,u=Number(n?.height)||852,m=Number(n?.statusBarHeight)||0,x=Number(n?.homeIndicatorHeight)||0,g=Math.round(r/2),$=Math.round(u/2),F=Math.max(24,m+18),W=Math.max(24,x+18),H=18,U=Math.min(220,Math.round(u*.24)),N=Math.min(180,Math.round(r*.32)),h=g,p=$,O=g,R=$;switch(t){case"scroll-up":p=$+Math.round(U/2),R=$-Math.round(U/2);break;case"scroll-down":p=$-Math.round(U/2),R=$+Math.round(U/2);break;case"scroll-left":h=g+Math.round(N/2),O=g-Math.round(N/2);break;case"scroll-right":h=g-Math.round(N/2),O=g+Math.round(N/2);break;case"swipe-from-left-edge":h=H,p=$,O=Math.min(r-H,H+N);break;case"swipe-from-right-edge":h=r-H,p=$,O=Math.max(H,r-H-N);break;case"swipe-from-top-edge":h=g,p=F,R=Math.min(u-W,F+U);break;case"swipe-from-bottom-edge":h=g,p=u-W,R=Math.max(F,u-W-U);break}let A=Math.max(8,Math.round(s/16)),he=Math.max(1,Math.round(s/A)),le=await c.send({type:"evaluate",code:`(async () => {
|
|
506
478
|
const interact = window.__sootsimInteract
|
|
507
479
|
if (!interact?.drag) return { ok: false, reason: 'no interact.drag' }
|
|
508
480
|
const value = await interact.drag(${h}, ${p}, ${O}, ${R}, ${A}, ${he})
|
|
509
481
|
return { ok: !!value, value }
|
|
510
|
-
})()`});le?.ok&&await j("inspect gesture",{swipe:{start:`${h}, ${p}`,end:`${O}, ${R}`,duration:Math.max(1,Math.round(s))}},`gesture ${t}`),console.log(JSON.stringify({preset:t,from:{x:h,y:p},to:{x:O,y:R},result:le},null,2));break}case"scroll":{let e=ae(o),t=e?.mode==="testid"?e.value:
|
|
482
|
+
})()`});le?.ok&&await j("inspect gesture",{swipe:{start:`${h}, ${p}`,end:`${O}, ${R}`,duration:Math.max(1,Math.round(s))}},`gesture ${t}`),console.log(JSON.stringify({preset:t,from:{x:h,y:p},to:{x:O,y:R},result:le},null,2));break}case"scroll":{let e=ae(o),t=e?.mode==="testid"?e.value:a[1],s=Number(a[e?1:2]),n=Number(a[e?2:3]);(!t||!Number.isFinite(s)||!Number.isFinite(n))&&(console.error(v("scroll","<id> <dx> <dy> | --testid <id> <dx> <dy>")),process.exit(1));let r=await c.send({type:"evaluate",code:`(async () => {
|
|
511
483
|
const t = window.__sootsimTest
|
|
512
484
|
if (!t) return null
|
|
513
485
|
const n = await t.findByTestId(${JSON.stringify(t)})
|
|
@@ -517,10 +489,10 @@ ${s}
|
|
|
517
489
|
cx: n.absolutePosition.x + (n.layout.width || 0) / 2,
|
|
518
490
|
cy: n.absolutePosition.y + (n.layout.height || 0) / 2,
|
|
519
491
|
}
|
|
520
|
-
})()`}),u=await Y(c,"scrollTo",t,s,
|
|
492
|
+
})()`}),u=await Y(c,"scrollTo",t,s,n,!1);u?.ok&&await j("inspect scroll",{scrollTo:{id:t,x:s,y:n}},`scroll ${t} -> ${s},${n}`),console.log(JSON.stringify({...u,...r?{at:{x:r.cx,y:r.cy}}:{}},null,2));break}case"state":{let e=a[1];if(i==="get"&&!e){let s=await Y(c,"getRuntimeState"),n=await c.send({type:"evaluate",code:`({
|
|
521
493
|
errors: window.__sootsimConsole?.getErrors?.()?.length ?? 0,
|
|
522
494
|
warnings: window.__sootsimConsole?.getWarnings?.()?.length ?? 0,
|
|
523
|
-
})`});s&&typeof s=="object"&&s.diagnostics&&(s.diagnostics.errors=
|
|
495
|
+
})`});if(s&&typeof s=="object"&&s.diagnostics&&(s.diagnostics.errors=n?.errors??0,s.diagnostics.warnings=n?.warnings??0),s&&typeof s=="object"&&s.shell==null)try{let r=await se(c);r&&(s.shell=r)}catch{}console.log(JSON.stringify(s,null,2));break}if(!e||e==="--help"||e==="-h"){console.log(`
|
|
524
496
|
${b("state")} \u2014 dump raw runtime state
|
|
525
497
|
|
|
526
498
|
subcommands:
|
|
@@ -543,7 +515,7 @@ ${s}
|
|
|
543
515
|
${b("state")} scroll feed
|
|
544
516
|
${b("state")} scroll-hit 360 420
|
|
545
517
|
${b("state")} hit 200 720
|
|
546
|
-
`);break}let t;switch(e){case"shell":t=await
|
|
518
|
+
`);break}let t;switch(e){case"shell":t=await se(c,500);break;case"worker":t=await $e(c,"__sootsimRenderHost.queryStats");break;case"ownership":t=await c.send({type:"evaluate",code:`(() => {
|
|
547
519
|
const h = window.__sootsimRenderHost
|
|
548
520
|
if (!h || typeof h.getOwnershipSnapshot !== 'function') {
|
|
549
521
|
return { error: 'getOwnershipSnapshot not available' }
|
|
@@ -574,7 +546,7 @@ ${s}
|
|
|
574
546
|
text: focused.text || null,
|
|
575
547
|
} : null,
|
|
576
548
|
}
|
|
577
|
-
})()`});break;case"node":{let s=
|
|
549
|
+
})()`});break;case"node":{let s=a[2];s||(console.error(` usage: ${b("state")} node <id>`),process.exit(1)),t=await Y(c,"findByTestId",s)||await Y(c,"findById",s);break}case"scroll":{let s=a[2];s||(console.error(` usage: ${b("state")} scroll <id>`),process.exit(1)),t=await Y(c,"getScrollState",s);break}case"scroll-hit":{let s=Number(a[2]),n=Number(a[3]);(!Number.isFinite(s)||!Number.isFinite(n))&&(console.error(` usage: ${b("state")} scroll-hit <x> <y>`),process.exit(1)),t=await Y(c,"getScrollStateAt",s,n);break}case"hit":{let s=Number(a[2]),n=Number(a[3]);(!Number.isFinite(s)||!Number.isFinite(n))&&(console.error(` usage: ${b("state")} hit <x> <y>`),process.exit(1)),t=await Y(c,"debugHitAt",s,n);break}case"gesture":{let s=Number(a[2]),n=Number(a[3]);(!Number.isFinite(s)||!Number.isFinite(n))&&(console.error(` usage: ${b("state")} gesture <x> <y>`),process.exit(1)),t=await Y(c,"debugGestureAt",s,n);break}default:console.error(` unknown state subcommand: ${e}`),process.exit(1)}console.log(JSON.stringify(t,null,2));break}case"shell":{let e=a[1];if(!e||e==="--help"||e==="-h"){console.log(`
|
|
578
550
|
${b("shell")} \u2014 run built-in shell commands
|
|
579
551
|
|
|
580
552
|
subcommands:
|
|
@@ -598,7 +570,7 @@ ${s}
|
|
|
598
570
|
${b("shell")} open-card clock 800
|
|
599
571
|
${b("shell")} appearance dark
|
|
600
572
|
${b("shell")} lock
|
|
601
|
-
`);break}let t=e==="launch"||e==="open-card"||e==="home"||e==="switcher",s=e==="launch"||e==="open-card"?
|
|
573
|
+
`);break}let t=e==="launch"||e==="open-card"||e==="home"||e==="switcher",s=e==="launch"||e==="open-card"?a[3]:a[2],n=s?Number(s):350;t&&(!Number.isFinite(n)||n<0)&&(console.error(v("shell",e==="launch"||e==="open-card"?"<launch|open-card> <appId> [settleMs]":"<home|switcher> [settleMs]")),process.exit(1));let r=!1,u=!1,m=null,x=o.includes("--clear-state");if(e==="launch"){let g=a[2];g||(console.error(v("shell","launch <appId> [settleMs] [--clear-state]")),process.exit(1)),x&&await c.send({type:"evaluate",code:De}),r=!!await re(c,"launchApp",n,g),{settled:u,state:m}=await fe(c,Math.round(n),$=>!!$&&$.state==="app"&&$.activeApp===g&&$.showSwitcher===!1&&$.switcherPhase==="idle"&&typeof $.launchProgress=="number"&&$.launchProgress>=.98),r&&await j("inspect shell launch",x?{launchApp:{clearState:!0}}:{launchApp:{}},x?"launch app (clear state)":"launch app")}else if(e==="home")r=!!await re(c,"goHome",n),{settled:u,state:m}=await fe(c,Math.round(n),g=>!!g&&g.state==="home"&&g.activeApp==null&&g.showSwitcher===!1&&g.switcherPhase==="idle"&&typeof g.launchProgress=="number"&&g.launchProgress>=.98);else if(e==="switcher")r=!!await re(c,"openSwitcher",n),{settled:u,state:m}=await fe(c,Math.round(n),g=>!!g&&g.state==="app"&&g.showSwitcher===!0&&g.switcherPhase==="idle"&&typeof g.zoomLevel=="number"&&Math.abs(g.zoomLevel)<=.02&&typeof g.horizontalZoom=="number"&&Math.abs(g.horizontalZoom)<=.02),u&&(await X(mo),m=await se(c));else if(e==="open-card"){let g=a[2];g||(console.error(v("shell","open-card <appId> [settleMs]")),process.exit(1)),r=!!await re(c,"openSwitcherCard",n,g),{settled:u,state:m}=await fe(c,Math.round(n),$=>!!$&&$.state==="app"&&$.activeApp===g&&$.showSwitcher===!1&&$.switcherPhase==="idle"&&typeof $.zoomLevel=="number"&&$.zoomLevel>=.98&&typeof $.horizontalZoom=="number"&&$.horizontalZoom>=.98),r&&await j("inspect shell open-card",{openSwitcherCard:{appId:g}},`open switcher card ${g}`)}else if(e==="appearance"){let g=a[2];(!g||!["light","dark","auto","toggle"].includes(g))&&(console.error(v("shell","appearance <light|dark|auto|toggle>")),process.exit(1));let $=await Et(c,"appearance",g);if(r=!!$?.ok,m={appearance:$},r){let F=$?.applied??g;console.log(` appearance: ${F}`)}}else if(e==="lock"||e==="shake"){let g=await Et(c,e);r=!!g?.ok,m={[e]:g}}else console.error(` unknown shell subcommand: ${e}`),process.exit(1);console.log(JSON.stringify({ok:r,settled:u,state:m},null,2));break}case"url":{await kt(c,{args:l});break}case"reload":{let s=!1,n=!1;try{await c.send({type:"evaluate",code:"window.__sootsimConsole?.clear()"});let m=await c.send({type:"evaluate",code:`;(() => {
|
|
602
574
|
const reloadExternalApp = window.SootSim?.bridges?.hotRemount?.reloadExternalApp
|
|
603
575
|
if (typeof reloadExternalApp === 'function') {
|
|
604
576
|
reloadExternalApp()
|
|
@@ -606,10 +578,10 @@ ${s}
|
|
|
606
578
|
}
|
|
607
579
|
window.location.reload()
|
|
608
580
|
return { kind: 'page' }
|
|
609
|
-
})()`});
|
|
581
|
+
})()`});n=!!m&&m.kind==="external-app",s=!0}catch{}console.log(" reloading...");let r=c,u=null;if(n)u=await ve(c,{timeoutMs:1e4,errorGraceMs:3e3});else{s&&await X(300);let m=await at(_,C,T,{timeoutMs:1e4});m?(r=m,u=await ve(m,{timeoutMs:1e4,errorGraceMs:3e3})):(console.log(" \u26A0 reload: bridge never reconnected within 10000ms"),r=null)}if(u)if(u.ready){let m=u.source==="nodes-fallback"?" (no ready signal, node-count fallback)":"";console.log(` ready in ${u.elapsedMs}ms: ${u.nodes} nodes${m}`)}else u.source==="error-bail"?console.log(` \u26A0 reload bailed after ${u.elapsedMs}ms: ${u.errors} console error(s), ready signal never fired`):console.log(` \u26A0 reload timed out after ${u.elapsedMs}ms (${u.nodes} nodes, ${u.errors} errors)`);if(r)try{let m=await r.send({type:"evaluate",code:"window.__sootsimConsole?.getErrors(10) || []"});if(r!==c&&r.close(),Array.isArray(m)&&m.length>0){console.log(`
|
|
610
582
|
\u26A0 ${m.length} error(s) during mount:
|
|
611
|
-
`);for(let
|
|
612
|
-
`).slice(0,2);for(let F of
|
|
583
|
+
`);for(let x of m){let g=x.args.map($=>typeof $=="object"?JSON.stringify($):$).join(" ");if(console.log(` ${g}`),x.stack){let $=x.stack.split(`
|
|
584
|
+
`).slice(0,2);for(let F of $)console.log(` ${F.trim()}`)}}}}catch{}u&&!u.ready&&(process.exitCode=1);break}case"eval":case"js":{let e=a.slice(1).join(" ");e||(console.error(v("js","<javascript>")),console.error(""),console.error(" runs the snippet in the engine realm. SootSim is the"),console.error(" canonical state surface \u2014 reach into it directly."),console.error(""),console.error(" examples:"),console.error(` ${b("js")} SootSim.bridges.test.findByText("Sign in")`),console.error(` ${b("js")} SootSim.bridges.debug.snapshot("before")`),console.error(` ${b("js")} SootSim.bridges.keyboard.type("hello")`),console.error(` ${b("js")} SootSim.state.root.children.length`),process.exit(1));let t=e;t.startsWith("(async")||(t=`(async () => ${t})()`);let s=await c.send({type:"evaluate",code:t});console.log(JSON.stringify(s,null,2));let n=e.toLowerCase(),r=[];(n.includes("sootsim:gohome")||n.includes("gohome"))&&r.push("sootsim shell home"),(n.includes("sootsim:appswitcher")||n.includes("appswitcher"))&&r.push("sootsim shell switcher"),(n.includes("keyboard.isvisible")||n.includes("keyboard.getmode"))&&r.push("sootsim debug state keyboard"),n.includes("interact.tap")&&r.push("sootsim do tap <x> <y>"),n.includes("keyboard.type")&&r.push("sootsim do type <text>"),(n.includes("keyboard.press")||n.includes("keyboard.dispatchkey"))&&r.push("sootsim do key <name>"),n.includes("keyboard.dismiss")&&r.push("sootsim do dismiss"),n.includes("dumptree")&&r.push("sootsim get tree"),n.includes("dumpaccessibilitytree")&&r.push("sootsim get a11y"),n.includes("getnodecount")&&r.push("sootsim get count"),n.includes("findbytext")&&r.push("sootsim find <text>"),(n.includes("findbytestid")||n.includes("findbyid"))&&r.push("sootsim find --testid <id>"),n.includes("document.hidden")&&r.push("sootsim debug state keyboard (includes tab health)"),r.length>0&&G("prefer-cli-over-eval",r);break}case"globals":{let e=await c.send({type:"evaluate",code:`(async () => {
|
|
613
585
|
const globals = {}
|
|
614
586
|
|
|
615
587
|
// test bridge (proxy in worker mode)
|
|
@@ -647,7 +619,7 @@ ${s}
|
|
|
647
619
|
|
|
648
620
|
return globals
|
|
649
621
|
})()`});console.log(` sootsim JS API:
|
|
650
|
-
`);for(let[t,s]of Object.entries(e)){console.log(` ${t}:`);for(let
|
|
622
|
+
`);for(let[t,s]of Object.entries(e)){console.log(` ${t}:`);for(let n of s)console.log(` .${n}`);console.log("")}console.log(` use: ${b("js")} <expression>`),console.log(` example: ${b("js")} test.findByText("Sign in")`);break}case"describe":{await ft({bridge:c,args:o,positional:a});break}case"perf":{let e=a[1];if(!e||e==="--help"||e==="-h"){console.log(`
|
|
651
623
|
${b("perf")} \u2014 performance profiling
|
|
652
624
|
|
|
653
625
|
subcommands:
|
|
@@ -804,8 +776,8 @@ ${s}
|
|
|
804
776
|
jankFrames: recent.filter(f => f > 16.67).length,
|
|
805
777
|
sampleCount: recent.length,
|
|
806
778
|
}
|
|
807
|
-
})()`});t.error&&(console.error(` error: ${t.error}`),process.exit(1));let s=t.avgMs>0?(1e3/t.avgMs).toFixed(1):"?",
|
|
808
|
-
`),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 (${
|
|
779
|
+
})()`});t.error&&(console.error(` error: ${t.error}`),process.exit(1));let s=t.avgMs>0?(1e3/t.avgMs).toFixed(1):"?",n=t.sampleCount>0?(t.jankFrames/t.sampleCount*100).toFixed(1):"0";console.log(` profiling stopped:
|
|
780
|
+
`),console.log(` frames: ${t.frames}`),console.log(` total: ${t.totalMs.toFixed(1)}ms`),console.log(` avg: ${t.avgMs.toFixed(2)}ms (${s} fps)`),console.log(` max: ${t.maxMs.toFixed(2)}ms`),console.log(""),t.layoutAvgMs!==void 0&&(console.log(" breakdown (avg per frame):"),console.log(` layout: ${t.layoutAvgMs.toFixed(2)}ms`),console.log(` render: ${t.renderAvgMs.toFixed(2)}ms`),console.log(` copy: ${t.copyAvgMs.toFixed(2)}ms`),t.auxAvgMs!==void 0&&console.log(` aux: ${t.auxAvgMs.toFixed(2)}ms`),t.otherAvgMs!==void 0&&console.log(` other: ${t.otherAvgMs.toFixed(2)}ms`),console.log("")),console.log(` distribution (${t.sampleCount} samples):`),console.log(` p50: ${t.p50.toFixed(2)}ms`),console.log(` p95: ${t.p95.toFixed(2)}ms`),console.log(` p99: ${t.p99.toFixed(2)}ms`),console.log(` jank: ${t.jankFrames} frames (${n}%) >16.67ms`);break}case"frames":{let t=a[2]?Number(a[2]):50;(!Number.isFinite(t)||t<=0)&&(console.error(` error: expected a positive frame count, got "${a[2]}"`),process.exit(1));let s=await c.send({type:"evaluate",code:`(async () => {
|
|
809
781
|
if (window.__sootsimRenderHost) {
|
|
810
782
|
const session = window.${Q} || {}
|
|
811
783
|
if (session.active) {
|
|
@@ -840,7 +812,7 @@ ${s}
|
|
|
840
812
|
mode: 'main-thread',
|
|
841
813
|
frames: (stats.recentFrames || []).slice(-${t}),
|
|
842
814
|
}
|
|
843
|
-
})()`});if(s.error&&(console.error(` error: ${s.error}`),process.exit(1)),s.mode==="render-worker"){let
|
|
815
|
+
})()`});if(s.error&&(console.error(` error: ${s.error}`),process.exit(1)),s.mode==="render-worker"){let r=Array.isArray(s.samples)?s.samples:[];if(r.length===0){console.log(` no frame data \u2014 run '${b("perf")} start' first`);break}console.log(` last ${r.length} sampled frames (ms):`),console.log(" total layout render copy aux other t+");for(let[u,m,x,g,$,F,W]of r)console.log(` ${m.toFixed(2).padStart(7)} ${x.toFixed(2).padStart(7)} ${g.toFixed(2).padStart(7)} ${$.toFixed(2).padStart(7)} ${F.toFixed(2).padStart(6)} ${W.toFixed(2).padStart(7)} ${String(u).padStart(5)}`);console.log(""),Ne(r.map(u=>u[1])),s.live&&console.log(" sampling continues");break}let n=Array.isArray(s.frames)?s.frames:Array.isArray(s)?s:[];if(n.length===0){console.log(` no frame data \u2014 run '${b("perf")} start' first`);break}console.log(` last ${n.length} frame times (ms):`),console.log(` ${n.map(r=>r.toFixed(2)).join(", ")}`),Ne(n);break}case"worst":{let t=a[2]?Number(a[2]):20;(!Number.isFinite(t)||t<=0)&&(console.error(` error: expected a positive frame count, got "${a[2]}"`),process.exit(1));let s=await c.send({type:"evaluate",code:`(async () => {
|
|
844
816
|
if (window.__sootsimRenderHost) {
|
|
845
817
|
const session = window.${Q} || {}
|
|
846
818
|
if (session.active) {
|
|
@@ -882,7 +854,7 @@ ${s}
|
|
|
882
854
|
mode: 'main-thread',
|
|
883
855
|
frames: recent.slice().sort((a, b) => b - a).slice(0, ${t}),
|
|
884
856
|
}
|
|
885
|
-
})()`});if(s.error&&(console.error(` error: ${s.error}`),process.exit(1)),s.mode==="render-worker"){let
|
|
857
|
+
})()`});if(s.error&&(console.error(` error: ${s.error}`),process.exit(1)),s.mode==="render-worker"){let r=Array.isArray(s.samples)?s.samples:[];if(r.length===0){console.log(` no frame data \u2014 run '${b("perf")} start' first`);break}console.log(` worst ${r.length} sampled frames (ms):`),console.log(" total layout render copy aux other t+");for(let[u,m,x,g,$,F,W]of r)console.log(` ${m.toFixed(2).padStart(7)} ${x.toFixed(2).padStart(7)} ${g.toFixed(2).padStart(7)} ${$.toFixed(2).padStart(7)} ${F.toFixed(2).padStart(6)} ${W.toFixed(2).padStart(7)} ${String(u).padStart(5)}`);s.live&&(console.log(""),console.log(" sampling continues"));break}let n=Array.isArray(s.frames)?s.frames:Array.isArray(s)?s:[];if(n.length===0){console.log(` no frame data \u2014 run '${b("perf")} start' first`);break}console.log(` worst ${n.length} frame times (ms):`),console.log(` ${n.map(r=>r.toFixed(2)).join(", ")}`);break}case"transition":{let t=a[2];if(!t||!["goHome","appSwitcher","lockScreen"].includes(t)){console.log(`
|
|
886
858
|
${b("perf")} transition <event> \u2014 profile a shell transition
|
|
887
859
|
|
|
888
860
|
events:
|
|
@@ -895,7 +867,7 @@ ${s}
|
|
|
895
867
|
examples:
|
|
896
868
|
${b("perf")} transition goHome --timeout 10000
|
|
897
869
|
${b("perf")} transition appSwitcher
|
|
898
|
-
`);break}let
|
|
870
|
+
`);break}let n=`sootsim:${t}`;console.log(` profiling ${t} transition...`),console.log(" (use --timeout 10000 if this times out)");let r=await c.send({type:"evaluate",code:`(async () => {
|
|
899
871
|
// only supported in render-worker mode
|
|
900
872
|
if (!window.__sootsimRenderHost) {
|
|
901
873
|
return { error: 'transition profiling requires render-worker mode' }
|
|
@@ -908,7 +880,7 @@ ${s}
|
|
|
908
880
|
await new Promise(r => requestAnimationFrame(() => r(undefined)))
|
|
909
881
|
|
|
910
882
|
// dispatch the shell event
|
|
911
|
-
window.dispatchEvent(new Event('${
|
|
883
|
+
window.dispatchEvent(new Event('${n}'))
|
|
912
884
|
|
|
913
885
|
// wait 600ms for transition to complete (shell animations are ~300-500ms)
|
|
914
886
|
// using fixed timing avoids complex animation-end detection
|
|
@@ -954,45 +926,45 @@ ${s}
|
|
|
954
926
|
jankFrames: frameTimes.filter(f => f > 16.67).length,
|
|
955
927
|
samples,
|
|
956
928
|
}
|
|
957
|
-
})()`});if(
|
|
929
|
+
})()`});if(r.error&&(console.error(` error: ${r.error}`),process.exit(1)),r.warning&&console.log(` warning: ${r.warning}`),r.frames===0){console.log(" no frames captured");break}let u=r.avgMs>0?(1e3/r.avgMs).toFixed(1):"?",m=r.frames>0?(r.jankFrames/r.frames*100).toFixed(1):"0";console.log(` ${t} transition profiled:
|
|
958
930
|
|
|
959
|
-
frames: ${
|
|
960
|
-
total: ${
|
|
961
|
-
avg: ${
|
|
962
|
-
max: ${
|
|
931
|
+
frames: ${r.frames}
|
|
932
|
+
total: ${r.totalMs.toFixed(1)}ms
|
|
933
|
+
avg: ${r.avgMs.toFixed(2)}ms (${u} fps)
|
|
934
|
+
max: ${r.maxMs.toFixed(2)}ms
|
|
963
935
|
|
|
964
936
|
breakdown (avg per frame):
|
|
965
|
-
layout: ${
|
|
966
|
-
render: ${
|
|
967
|
-
copy: ${
|
|
968
|
-
aux: ${
|
|
969
|
-
other: ${
|
|
970
|
-
|
|
971
|
-
distribution (${
|
|
972
|
-
p50: ${
|
|
973
|
-
p95: ${
|
|
974
|
-
p99: ${
|
|
975
|
-
jank: ${
|
|
976
|
-
`);for(let
|
|
977
|
-
`).slice(0,3);for(let
|
|
978
|
-
`);for(let s of t){let
|
|
979
|
-
`);for(let t of e){let s=String(t.kind).padEnd(6),
|
|
980
|
-
`);for(let u of
|
|
937
|
+
layout: ${r.layoutAvgMs?.toFixed(2)||"?"}ms
|
|
938
|
+
render: ${r.renderAvgMs?.toFixed(2)||"?"}ms
|
|
939
|
+
copy: ${r.copyAvgMs?.toFixed(2)||"?"}ms
|
|
940
|
+
aux: ${r.auxAvgMs?.toFixed(2)||"?"}ms
|
|
941
|
+
other: ${r.otherAvgMs?.toFixed(2)||"?"}ms
|
|
942
|
+
|
|
943
|
+
distribution (${r.frames} samples):
|
|
944
|
+
p50: ${r.p50.toFixed(2)}ms
|
|
945
|
+
p95: ${r.p95.toFixed(2)}ms
|
|
946
|
+
p99: ${r.p99.toFixed(2)}ms
|
|
947
|
+
jank: ${r.jankFrames} frames (${m}%) >16.67ms`),Array.isArray(r.samples)&&r.samples.length>0&&(console.log(""),Ne(r.samples.map(x=>x[1])));break}default:console.error(` unknown perf subcommand: ${e}`),process.exit(1)}break}case"errors":{let e=a[1];if(e==="clear"){await Ve(c),D(l)?B({cleared:!0}):console.log(" error buffer cleared");break}let t=e?Number(e):20,s=await Ge(c,t);if(D(l)){B(s);break}if(s.length===0){console.log(" no errors captured");break}console.log(` ${s.length} error(s):
|
|
948
|
+
`);for(let n of s){let r=new Date(n.timestamp).toLocaleTimeString(),u=n.args.map(m=>typeof m=="object"?JSON.stringify(m):m).join(" ");if(console.log(` [${r}] ${u}`),n.stack){let m=n.stack.split(`
|
|
949
|
+
`).slice(0,3);for(let x of m)console.log(` ${x.trim()}`)}}break}case"warnings":{let e=a[1]?Number(a[1]):20,t=await Xe(c,e);if(D(l)){B(t);break}if(t.length===0){console.log(" no warnings captured");break}console.log(` ${t.length} warning(s):
|
|
950
|
+
`);for(let s of t){let n=new Date(s.timestamp).toLocaleTimeString(),r=s.args.map(u=>typeof u=="object"?JSON.stringify(u):u).join(" ");console.log(` [${n}] ${r}`)}break}case"animations":{let e=await Y(c,"listAnimations")??[];if(o.includes("--json")){console.log(JSON.stringify(e,null,2));break}if(e.length===0){console.log(" no active animations");break}console.log(` ${e.length} active animation(s):
|
|
951
|
+
`);for(let t of e){let s=String(t.kind).padEnd(6),n=`${Number(t.from).toFixed(2)}\u2192${Number(t.to).toFixed(2)}`,r=Number(t.current??0).toFixed(2),u=`${Math.round((t.progress??0)*100)}%`,m=`${Math.round(t.elapsedMs??0)}ms`,x=t.loop?" loop":"",g=t.layoutBound?" layout":"";console.log(` #${t.id} ${s} ${n.padEnd(14)} cur=${r.padEnd(7)} ${u.padStart(4)} ${m}${x}${g}`)}break}case"animation":{let e=a[1];(!e||e==="--help"||e==="-h")&&(console.error(` usage: ${b("animation")} <id>`),process.exit(1));let t=Number(e);Number.isFinite(t)||(console.error(` invalid id: ${e}`),process.exit(1));let s=await Y(c,"getAnimation",t);console.log(JSON.stringify(s,null,2));break}case"stop-animation":{let e=a[1];(!e||e==="--help"||e==="-h")&&(console.error(` usage: ${b("stop-animation")} <id|all>`),process.exit(1));let t=e==="all"?"all":Number(e);t!=="all"&&!Number.isFinite(t)&&(console.error(` invalid id: ${e}`),process.exit(1));let s=await Y(c,"stopAnimation",t);console.log(` stopped ${s??0} animation(s)`);break}case"requests":{let e=a[1];if(e==="clear"){await Ze(c),D(l)?B({cleared:!0}):console.log(" request buffer cleared");break}let t=e==="all",s=t?a[2]:e,n=s?Number(s):20,r=await Qe(c,{failed:!t,limit:n});if(D(l)){B(r);break}if(r.length===0){console.log(t?" no requests captured":" no failed requests captured");break}console.log(` ${r.length} ${t?"request(s)":"failed request(s)"}:
|
|
952
|
+
`);for(let u of r){let m=new Date(u.timestamp).toLocaleTimeString();console.log(` [${m}] ${z(u)}`),u.responseBody?console.log(` ${u.responseBody}`):u.error&&console.log(` ${u.error}`)}break}case"network":{let e=a[1],t=null,s=null,n=!1,r=!1,u=1e3,m=!1,x=!1;for(let N=0;N<l.length;N++){let h=l[N];if(h==="--filter")t=l[N+1]??null,N++;else if(h==="--limit"){let p=Number(l[N+1]);Number.isFinite(p)&&(s=p),N++}else if(h==="--threshold"){let p=Number(l[N+1]);Number.isFinite(p)&&p>0&&(u=p),N++}else h==="--failed"?n=!0:h==="--slow"?r=!0:h==="--tail"||h==="-f"?m=!0:h==="--json"&&(x=!0)}if(e==="clear"){await c.send({type:"evaluate",code:'window.__sootsimObservability?.network.clear(); "cleared"'}),console.log(" network buffer cleared");break}if(e==="get"){let N=a[2];N||(console.error(" usage: sootsim network get <id>"),process.exit(1));let h=await c.send({type:"evaluate",code:`(() => {
|
|
981
953
|
const obs = window.__sootsimObservability;
|
|
982
954
|
if (!obs) return null;
|
|
983
955
|
return obs.network.getSnapshot().find(e => e.id === ${JSON.stringify(N)}) || null;
|
|
984
|
-
})()`});h||(console.error(` no entry with id ${N}`),process.exit(1))
|
|
985
|
-
to target a specific sim, use \`--sim ${e}\` instead.`),process.exit(1));let
|
|
956
|
+
})()`});h||(console.error(` no entry with id ${N}`),process.exit(1)),x?console.log(JSON.stringify(h,null,2)):lo(h);break}let g=s??(m?200:e?Number(e):20);Number.isFinite(g)||(console.error(` invalid limit: ${e} \u2014 \`network\` takes a numeric count (e.g. ${b("network")} 100).
|
|
957
|
+
to target a specific sim, use \`--sim ${e}\` instead.`),process.exit(1));let $=async()=>{let N=await c.send({type:"evaluate",code:`(() => {
|
|
986
958
|
const obs = window.__sootsimObservability;
|
|
987
959
|
if (!obs) return { ok: false };
|
|
988
960
|
return { ok: true, entries: obs.network.getSnapshot() };
|
|
989
|
-
})()`});if(!N||!N.ok)throw new Error("observability bridge not installed \u2014 is the engine running?");return N.entries??[]},F=N=>{let h=N;if(
|
|
961
|
+
})()`});if(!N||!N.ok)throw new Error("observability bridge not installed \u2014 is the engine running?");return N.entries??[]},F=N=>{let h=N;if(n&&(h=h.filter(p=>!!p.error||p.status!=null&&p.status>=400)),r&&(h=h.filter(p=>p.durationMs!=null&&p.durationMs>=u)),t){let p=t.toLowerCase();h=h.filter(O=>(O.displayUrl||O.url).toLowerCase().includes(p))}return r&&!m&&(h=[...h].sort((p,O)=>(O.durationMs??0)-(p.durationMs??0))),h};if(!m){let N=await $(),h=F(N).slice(-g);if(x){console.log(JSON.stringify(h,null,2));break}if(h.length===0){N.length===0?console.log(" no network requests captured"):console.log(r?` no requests slower than ${u}ms (${N.length} total \u2014 try --threshold <ms>)`:" no matching requests");break}console.log(r?` ${h.length} request(s) slower than ${u}ms (sorted by duration desc):
|
|
990
962
|
`:` ${h.length} request(s):
|
|
991
|
-
`);for(let p of h)
|
|
992
|
-
`);let W=new Set,H=!0,U=()=>{H=!1};process.on("SIGINT",U);try{for(;H;){let N=await
|
|
993
|
-
to target a specific sim, use \`--sim ${e}\` instead.`),process.exit(1));let F=()=>
|
|
994
|
-
`);for(let O of p)
|
|
995
|
-
`);let H=new Set,U=!0,N=()=>{U=!1};process.on("SIGINT",N);try{for(;U;){let h=await F(),p=W(h);for(let O of p)H.has(O.id)||(H.add(O.id),u?console.log(JSON.stringify(O)):
|
|
963
|
+
`);for(let p of h)At(p);break}console.log(` tailing network (ctrl-c to stop)...
|
|
964
|
+
`);let W=new Set,H=!0,U=()=>{H=!1};process.on("SIGINT",U);try{for(;H;){let N=await $(),h=F(N);for(let p of h)p.durationMs!=null&&(W.has(p.id)||(W.add(p.id),x?console.log(JSON.stringify(p)):At(p)));await X(250)}}finally{process.off("SIGINT",U)}break}case"logs":{let e=a[1],t=null,s=null,n=null,r=!1,u=!1,m=!1;for(let h=0;h<l.length;h++){let p=l[h];if(p==="--filter")t=l[h+1]??null,h++;else if(p==="--limit"){let O=Number(l[h+1]);Number.isFinite(O)&&(s=O),h++}else p==="--level"?(n=l[h+1]??null,h++):p==="--tail"||p==="-f"?r=!0:p==="--json"?u=!0:(p==="--internal"||p==="--all")&&(m=!0)}let x=n?new Set(n.split(",").map(h=>h.trim()).filter(h=>h==="log"||h==="info"||h==="warn"||h==="error"||h==="debug")):null;if(e==="clear"){await tt(c),console.log(" log buffer cleared");break}let g=!u&&process.stdout.isTTY===!0,$=s??(r?500:e?Number(e):50);Number.isFinite($)||(console.error(` invalid limit: ${e} \u2014 \`logs\` takes a numeric count (e.g. ${b("logs")} 100).
|
|
965
|
+
to target a specific sim, use \`--sim ${e}\` instead.`),process.exit(1));let F=()=>et(c),W=h=>ot(h,{level:x,filter:t,showInternal:m});if(!r){let h=await F(),p=W(h).slice(-$);if(u){console.log(JSON.stringify(p,null,2));break}if(p.length===0){console.log(h.length===0?" no logs captured":" no matching logs");break}console.log(` ${p.length} log(s):
|
|
966
|
+
`);for(let O of p)Ot(O,g);break}console.log(` tailing logs (ctrl-c to stop)...
|
|
967
|
+
`);let H=new Set,U=!0,N=()=>{U=!1};process.on("SIGINT",N);try{for(;U;){let h=await F(),p=W(h);for(let O of p)H.has(O.id)||(H.add(O.id),u?console.log(JSON.stringify(O)):Ot(O,g));await X(250)}}finally{process.off("SIGINT",N)}break}default:console.error(` unknown subcommand: ${y}`),process.exit(1)}if(ee.has(y)&&!o.includes("--no-wait")&&process.env.SOOTSIM_NO_AUTO_WAIT!=="1"&&await q(c),!K.has(y)&&!D(l))try{await V(c)}catch{}}catch(e){let t=e instanceof Error?e.message:String(e);console.error(` ${y??"inspect"} failed: ${t}`);let s=/^no sim connected with id (.+)$/.exec(t),n=/^command timed out after \d+s$/.test(t)||t.startsWith("sim disconnected:")||t.startsWith("bridge never reconnected")||t.startsWith("could not connect to ws://");if(s)await ct(c,_,s[1]);else if(/^no sim connected$/.test(t))lt(_);else if(n)process.stderr.write(` the sim is not responding. recover it with:
|
|
996
968
|
sootsim close --sim <id> # force-close the wedged sim
|
|
997
969
|
sootsim list # confirm it's gone
|
|
998
|
-
`);else{try{await Be(c)}catch{}try{await Z({includeTail:!0})}catch{}try{await M({includeTail:!0})}catch{}}process.exit(1)}finally{c.close()}}export{
|
|
970
|
+
`);else{try{await Be(c)}catch{}try{await Z({includeTail:!0})}catch{}try{await M({includeTail:!0})}catch{}}process.exit(1)}finally{c.close()}}export{Xs as runInspect};
|