sootsim 0.1.53 → 0.1.55
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-PA7ZGTHU.js → agent-K3IFO5CV.js} +2 -2
- package/dist-cli/chunks/{agent-wrapper-CVZFXQKJ.js → agent-wrapper-QLSTAEJA.js} +2 -2
- package/dist-cli/chunks/{assert-6LHIY63B.js → assert-5YXZANCD.js} +2 -2
- package/dist-cli/chunks/auto-bootstrap-EXYDOLCY.js +2 -0
- package/dist-cli/chunks/beta-ER25Q3B4.js +2 -0
- package/dist-cli/chunks/chunk-2EGTJLOK.js +2 -0
- package/dist-cli/chunks/{chunk-R3VVVXF3.js → chunk-4GLNQZFI.js} +2 -2
- package/dist-cli/chunks/{chunk-R5XV3WIE.js → chunk-4OOZDIIQ.js} +2 -2
- package/dist-cli/chunks/{chunk-XBP7BBSF.js → chunk-6AEQVSS6.js} +2 -2
- package/dist-cli/chunks/{chunk-ERC46HTZ.js → chunk-6KGSLO4W.js} +1 -1
- package/dist-cli/chunks/{chunk-LL3XAMKC.js → chunk-7CET27Q3.js} +2 -2
- package/dist-cli/chunks/{chunk-QTVGSFY6.js → chunk-AO7LMODD.js} +10 -10
- package/dist-cli/chunks/chunk-APAO2IQW.js +1 -0
- package/dist-cli/chunks/{chunk-5U2BN4IU.js → chunk-ATJEMKBT.js} +2 -2
- package/dist-cli/chunks/{chunk-5Q3XBH5M.js → chunk-BNX3LAMN.js} +2 -2
- package/dist-cli/chunks/{chunk-7ZHWA3WD.js → chunk-BTP3PAIO.js} +2 -2
- package/dist-cli/chunks/{chunk-XC3T7UDH.js → chunk-CKNMXP6L.js} +1 -1
- package/dist-cli/chunks/{chunk-FDA2NX2E.js → chunk-CT3BVUCO.js} +2 -2
- package/dist-cli/chunks/{chunk-CTGH5SFH.js → chunk-DC7ANPA5.js} +1 -1
- package/dist-cli/chunks/{chunk-6A4CZMPO.js → chunk-DFNL55QN.js} +2 -2
- package/dist-cli/chunks/{chunk-2ZBZCRN6.js → chunk-DVPSMF32.js} +1 -1
- package/dist-cli/chunks/{chunk-6JZNIGOQ.js → chunk-EVARILGS.js} +1 -1
- package/dist-cli/chunks/{chunk-ZYITMTYD.js → chunk-ITS6IHOX.js} +1 -1
- package/dist-cli/chunks/{chunk-CTDDR7HW.js → chunk-JHZ6QH6V.js} +2 -2
- package/dist-cli/chunks/{chunk-AYU6WUNF.js → chunk-LB4RU4OV.js} +1 -1
- package/dist-cli/chunks/{chunk-YEE4EO2P.js → chunk-LBFWPKYG.js} +1 -1
- package/dist-cli/chunks/{chunk-WXOAHKCZ.js → chunk-LOUL5QVO.js} +1 -1
- package/dist-cli/chunks/chunk-LXDHH3TW.js +11 -0
- package/dist-cli/chunks/chunk-MTLPC2NY.js +2 -0
- package/dist-cli/chunks/{chunk-WBAIONOO.js → chunk-N5EKXLXC.js} +2 -2
- package/dist-cli/chunks/{chunk-CW2X4KRW.js → chunk-NCAKZ2QL.js} +2 -2
- package/dist-cli/chunks/{chunk-LELB2PV3.js → chunk-OP4ALEJL.js} +1 -1
- package/dist-cli/chunks/{chunk-AFXPU7YQ.js → chunk-PKYDQIBB.js} +3 -3
- package/dist-cli/chunks/{chunk-7IYYIF5B.js → chunk-Q3LSFKVP.js} +2 -2
- package/dist-cli/chunks/{chunk-RBXJA2PW.js → chunk-Q5MLOHVB.js} +2 -2
- package/dist-cli/chunks/{chunk-E4JTYQVY.js → chunk-RN2SMUS4.js} +2 -2
- package/dist-cli/chunks/{chunk-N3RWXMD3.js → chunk-SDUNLEAF.js} +2 -2
- package/dist-cli/chunks/{chunk-GWGF4J4Y.js → chunk-SPJQ6B6W.js} +2 -2
- package/dist-cli/chunks/chunk-T6NGCA35.js +1 -0
- package/dist-cli/chunks/{chunk-LYHVX7TD.js → chunk-UF27WZ7Q.js} +3 -3
- package/dist-cli/chunks/chunk-UNLFZUUU.js +1 -0
- package/dist-cli/chunks/{chunk-IS5ORPFW.js → chunk-VPYEMRIC.js} +2 -2
- package/dist-cli/chunks/{chunk-CRUPWYHV.js → chunk-VZH3VTOY.js} +3 -3
- package/dist-cli/chunks/{chunk-MX5HFYST.js → chunk-W3M6NG6B.js} +1 -1
- package/dist-cli/chunks/{chunk-E3S6U2QR.js → chunk-WZDVJFJX.js} +1 -1
- package/dist-cli/chunks/{chunk-AZYLZGRV.js → chunk-X46ROUJY.js} +1 -1
- package/dist-cli/chunks/chunk-X4VUDSXT.js +3 -0
- package/dist-cli/chunks/{chunk-SQZXAKBL.js → chunk-YDKX4GPS.js} +2 -2
- package/dist-cli/chunks/{chunk-STWL7EXR.js → chunk-ZNXPOJDD.js} +1 -1
- package/dist-cli/chunks/cli-version-FQQ7DWZU.js +2 -0
- package/dist-cli/chunks/{compat-CHBJ7TDK.js → compat-7EFQ4K63.js} +3 -3
- package/dist-cli/chunks/{config-XTZOLM5E.js → config-BXQ5RYP3.js} +2 -2
- package/dist-cli/chunks/control-J7H2HTKN.js +2 -0
- package/dist-cli/chunks/{cpu-profile-EQHKYVOF.js → cpu-profile-P2HBDYZ3.js} +2 -2
- package/dist-cli/chunks/{daemon-K42MZR2E.js → daemon-EMP5NFIK.js} +2 -2
- package/dist-cli/chunks/{debug-ULTTL5L2.js → debug-VG2EYIRM.js} +3 -3
- package/dist-cli/chunks/demo-app-registry-X3JPEPV6.js +2 -0
- package/dist-cli/chunks/{detox-LU3G3EBC.js → detox-6N2GHBJD.js} +2 -2
- package/dist-cli/chunks/{device-RYW4ZE4R.js → device-L4MPWY7S.js} +2 -2
- package/dist-cli/chunks/{diagnose-5YQAXWFB.js → diagnose-M7L2CKMA.js} +2 -2
- package/dist-cli/chunks/drivers-LCWLVDG3.js +2 -0
- package/dist-cli/chunks/{electron-ORBIXXTP.js → electron-TYPTY4Y7.js} +3 -3
- package/dist-cli/chunks/flow-IUMVR5GK.js +2 -0
- package/dist-cli/chunks/{hints-V4SHPWCI.js → hints-CLDM5YBJ.js} +2 -2
- package/dist-cli/chunks/{home-paths-UYEDTYXU.js → home-paths-CIRYHGNC.js} +2 -2
- package/dist-cli/chunks/{inspect-K2FN4JPL.js → inspect-IPLQLR2B.js} +94 -94
- package/dist-cli/chunks/install-3IBRZDCU.js +2 -0
- package/dist-cli/chunks/{install-desktop-BDDNVONK.js → install-desktop-DMIJXVAQ.js} +3 -3
- package/dist-cli/chunks/{keys-QH5VOSUK.js → keys-6NSIIG5W.js} +2 -2
- package/dist-cli/chunks/{launch-K2LP5XFZ.js → launch-WZPZT7QA.js} +3 -3
- package/dist-cli/chunks/{login-5AJTPRVD.js → login-DVAESD5E.js} +4 -4
- package/dist-cli/chunks/{logout-45VCRSXX.js → logout-ZPNORUPW.js} +2 -2
- package/dist-cli/chunks/{maestro-5LDII3YE.js → maestro-TCIBCLOE.js} +2 -2
- package/dist-cli/chunks/{preview-IA2UUMLO.js → preview-QXRUBXPI.js} +2 -2
- package/dist-cli/chunks/{profile-ZALUAYTJ.js → profile-YQMD5RSB.js} +2 -2
- package/dist-cli/chunks/{react-KJBOHVG7.js → react-TU4SHD4N.js} +2 -2
- package/dist-cli/chunks/{record-UI226Z7F.js → record-VWCIULWT.js} +2 -2
- package/dist-cli/chunks/runtime-AFEO53IB.js +2 -0
- package/dist-cli/chunks/{runtime-delivery-Y4QVOPLO.js → runtime-delivery-U65W6ABO.js} +2 -2
- package/dist-cli/chunks/{screenshot-SV5S4UGU.js → screenshot-2NP6RB6K.js} +2 -2
- package/dist-cli/chunks/{screenshot-mode-NCISGI6W.js → screenshot-mode-HTTJRZXJ.js} +2 -2
- package/dist-cli/chunks/{screenshots-MQZDYKF5.js → screenshots-YOGPCEDA.js} +2 -2
- package/dist-cli/chunks/{server-RLDTPMHN.js → server-ZTCVFCWZ.js} +2 -2
- package/dist-cli/chunks/setup-repo-ITPK57UJ.js +2 -0
- package/dist-cli/chunks/{skills-NECP76E4.js → skills-EC7Q2ISG.js} +2 -2
- package/dist-cli/chunks/{start-K4ASMK7D.js → start-MODFVXM3.js} +4 -4
- package/dist-cli/chunks/store-2EL3VFR5.js +2 -0
- package/dist-cli/chunks/telemetry-3CH4GAWO.js +2 -0
- package/dist-cli/chunks/{test-YJLRC3IE.js → test-QASBXD56.js} +3 -3
- package/dist-cli/chunks/{three-mode-NAAIMEHL.js → three-mode-ANW4NQAP.js} +2 -2
- package/dist-cli/chunks/{timeline-BJXCTH7E.js → timeline-NQUBPM67.js} +2 -2
- package/dist-cli/chunks/{upgrade-NRJOML2W.js → upgrade-A3TXVNAC.js} +2 -2
- package/dist-cli/chunks/upload-URNEXJIS.js +2 -0
- package/dist-cli/chunks/{web-P3IP7M5Q.js → web-DH4EW3I6.js} +2 -2
- package/dist-cli/chunks/{what-happened-5Q2RBX5R.js → what-happened-AWHOPBQ3.js} +2 -2
- package/dist-cli/chunks/{whoami-7W6WPTVA.js → whoami-ZZYOBY77.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-SVBAUCSM.js +0 -2
- package/dist-cli/chunks/beta-YEBFYYIB.js +0 -2
- package/dist-cli/chunks/chunk-BPXSSZJS.js +0 -11
- package/dist-cli/chunks/chunk-CKZSGUTE.js +0 -2
- package/dist-cli/chunks/chunk-ELEP2COQ.js +0 -3
- package/dist-cli/chunks/chunk-H4C3WE3C.js +0 -1
- package/dist-cli/chunks/chunk-NIHI6NXE.js +0 -1
- package/dist-cli/chunks/chunk-XO4UV6EO.js +0 -1
- package/dist-cli/chunks/chunk-YCPH4ZTS.js +0 -2
- package/dist-cli/chunks/cli-version-NMWGV7OU.js +0 -2
- package/dist-cli/chunks/control-XAZGNLFM.js +0 -2
- package/dist-cli/chunks/demo-app-registry-SO43B5HW.js +0 -2
- package/dist-cli/chunks/drivers-SXP44QNY.js +0 -2
- package/dist-cli/chunks/flow-GP7GAXLT.js +0 -2
- package/dist-cli/chunks/install-R4H47HDX.js +0 -2
- package/dist-cli/chunks/runtime-JNHCYB5L.js +0 -2
- package/dist-cli/chunks/setup-repo-F4RNWTDL.js +0 -2
- package/dist-cli/chunks/store-TLB2YDDQ.js +0 -2
- package/dist-cli/chunks/telemetry-EXCKYRZL.js +0 -2
- package/dist-cli/chunks/upload-BQTZTOJL.js +0 -2
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
2
|
-
import{a as G}from"./chunk-
|
|
3
|
-
`)}function
|
|
4
|
-
`).length>=80&&G("describe-use-filters"),
|
|
1
|
+
/*! sootsim v0.1.55 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
|
+
import{a as G}from"./chunk-Q5MLOHVB.js";import{a as Je,b as Le}from"./chunk-ITS6IHOX.js";import{a as X,b as D,c as B,d as z,e as de,f as re,g as at,h as lt,i as ke}from"./chunk-X4VUDSXT.js";import{B as se,C as rt,I as it,a as We,b as qe,c as He,d as Ue,e as Ke,f as ze,g as Se,h as ve,m as Ye,n as Ge,o as Xe,p as Ve,q as Qe,r as Ze,s as et,t as tt,u as ot,v as st,z as nt}from"./chunk-AO7LMODD.js";import{a as Be,g as ce}from"./chunk-BTP3PAIO.js";import{b as ct,c as dt,i as ut}from"./chunk-LXDHH3TW.js";import"./chunk-LOUL5QVO.js";import{a as je}from"./chunk-EVARILGS.js";import"./chunk-DFNL55QN.js";import"./chunk-LB4RU4OV.js";import"./chunk-UNLFZUUU.js";import"./chunk-Q3LSFKVP.js";import"./chunk-LBFWPKYG.js";import{a as we,c as $e,d as Pe}from"./chunk-CKNMXP6L.js";import{a as Ae}from"./chunk-MTLPC2NY.js";import{c as Re,e as Ee,f as Ce,g as De,h as xe}from"./chunk-SPJQ6B6W.js";import{b as Oe}from"./chunk-ZNXPOJDD.js";import"./chunk-2EGTJLOK.js";import"./chunk-WZDVJFJX.js";import"./chunk-OP4ALEJL.js";import{existsSync as Ht,mkdirSync as Ut,readFileSync as Kt,rmSync as mt,writeFileSync as zt}from"fs";import{tmpdir as Yt}from"os";import{dirname as Gt,join as Xt,resolve as Vt}from"path";var ie=1,Qt="SOOTSIM_INSPECT_NOTICE_PATH",Zt=300*1e3,eo=15e3;function pt(){return Vt(process.env[Qt]||Xt(Yt(),"sootsim-inspect-notice-state.json"))}function to(o,d){return Object.fromEntries(Object.entries(o).filter(([,i])=>typeof i?.signature=="string"&&Number.isFinite(i?.updatedAt)&&d-i.updatedAt<=Zt))}function oo(o){let d=pt();if(!Ht(d))return{version:ie,entries:{}};try{let i=JSON.parse(Kt(d,"utf8"));return i.version!==ie||!i.entries||typeof i.entries!="object"?(mt(d,{force:!0}),{version:ie,entries:{}}):{version:ie,entries:to(i.entries,o)}}catch{return mt(d,{force:!0}),{version:ie,entries:{}}}}function so(o){let d=pt();Ut(Gt(d),{recursive:!0}),zt(d,JSON.stringify(o,null,2)+`
|
|
3
|
+
`)}function no(o,d){let i=d.trim()||"default";return`${o}:${i}`}function Te(o,d,i,l={}){let f=l.nowMs??Date.now(),a=l.cooldownMs??eo,y=oo(f),S=no(o,d),N=y.entries[S];return N&&N.signature===i&&f-N.updatedAt<a?!1:(y.entries[S]={signature:i,updatedAt:f},so(y),!0)}async function ft(o,d={args:[]}){let i=await We(o);if(D(d.args)){B(i);return}console.log(` nodes: ${i.nodes}`)}function Me(o,d){let i=o.indexOf(d);return i>=0&&i+1<o.length?o[i+1]:null}async function gt(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"),N=1e3,k=i.includes("--compact"),b=i.includes("--no-xy"),v=Me(i,"--testid-like"),_=Me(i,"--only"),T=Me(i,"--subtree"),E=l[1],L=E?/[*?]/.test(E):!1,c=!L&&!_?E:void 0,K=_??(L?E:void 0),j=async()=>{await de(d,{verbose:y});let Y=await Ue(d,{describe:!0,verbose:f,filter:c||"",testIdLike:v||void 0,onlyGlob:K||void 0,subtreeRoot:T||void 0,compact:k,hideXy:b}),W=Y?.tree,w=Y?.shell,I=Y?.keyboard;if(a){B({shell:w,tree:W??"",keyboard:I});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 W=="string"&&W.startsWith("__SUBTREE_NOT_FOUND__:")){let P=W.slice(22);console.log(` subtree root not found: ${P}`),G("subtree-root-not-found",P);return}if(!W){let P=Y?.nodeCount??0;console.log(" no matching nodes found"),!(c||v||K||T)&&P<10&&G("app-still-loading",P);return}if(console.log(W),!(c||v||K||T)&&!S&&W.split(`
|
|
4
|
+
`).length>=80&&G("describe-use-filters"),I&&I.visible){let P=I.spec,V=[P?.keyboardType?`type=${P.keyboardType}`:null,P?.returnKeyType&&P.returnKeyType!=="default"?`return=${P.returnKeyType}`:null,I.mode!=="letters"?`mode=${I.mode}`:null,I.shifted?"shift":null,I.capsLock?"caps":null,P?.autoCapitalize&&P.autoCapitalize!=="sentences"?`autoCap=${P.autoCapitalize}`:null,I.accessoryBarId?`accessory=${I.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
|
|
6
|
+
`);;)console.clear(),await j(),await X(N);else await j()}var ro=["SOOTSIM_AGENT","CLAUDECODE","CLAUDE_CODE_ENTRYPOINT","CLAUDE_CODE_SESSION_ID","CODEX_THREAD_ID","CURSOR_TRACE_ID","AIDER_MODEL"];function yt(){if(process.env.SOOTSIM_AGENT==="0")return!1;for(let o of ro){let d=process.env[o];if(d&&d.trim()&&d!=="0")return!0}return!1}async function ht(o){let{bridge:d,args:i,effectiveArgs:l,positional:f,inspectUsage:a}=o,y=w=>{let I=l.indexOf(w);return I>=0&&I+1<l.length?l[I+1]:null},S=w=>l.includes(w),N=y("--testid")||y("--test-id"),k=y("--role"),b=y("--type"),v=y("--text"),_=S("--pressable"),T=S("--visible"),E=S("--interactive-targets")||S("--actions"),L=!N&&!k&&!b&&!v&&!_&&!T&&!E?f[1]:null,c=v??L,K=await ze(d,{testId:N,role:k,type:b,text:c,pressable:_,visible:T,interactive:E});K||(console.error(a("find","<text> | --text <t> | --testid <id> | --role <r> | --type <t> | --pressable | --visible | --interactive-targets")),process.exit(1));let{mode:j,result:C}=K,Y=D(i),W=i.includes("--verbose")||i.includes("--dump");if(Y)j==="interactive-targets"&&Array.isArray(C)?B(Se(C).map(w=>({...w,tap:ve(w)}))):B(C??null);else if(Array.isArray(C))if(C.length===0){console.log(` no ${j} 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(j==="interactive-targets"){let w=Se(C);console.log(` found ${w.length} interactive target${w.length===1?"":"s"} (sorted by score):`);for(let I of w.slice(0,20)){let Z=I.absolutePosition?`@(${Math.round(I.absolutePosition.x)},${Math.round(I.absolutePosition.y)})`:"",P=I.layout?`${Math.round(I.layout.width)}x${Math.round(I.layout.height)}`:"?x?",V=I.text?` "${I.text.slice(0,30)}"`:"",oe=I.testID?` #${I.testID}`:"",ee=I.accessibilityLabel?` \u24D8"${String(I.accessibilityLabel).slice(0,24)}"`:"",ye=I.accessibilityRole?`[${I.accessibilityRole}]`:I.type,he=ve(I);console.log(` ${ye}${V}${ee}${oe} ${P} ${Z}`),console.log(` \u2192 ${he}`),W&&console.log(Ie(JSON.stringify(I,null,2)," "))}w.length>20&&console.log(` ... and ${w.length-20} more`)}else{console.log(` found ${C.length} node${C.length===1?"":"s"} (${j}):`);for(let w of C.slice(0,20)){let I=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}`:"",oe=w.pressable?" (tap)":"",ee=w.accessibilityRole?`[${w.accessibilityRole}]`:w.type;console.log(` ${ee}${P}${V} ${Z} ${I}${oe}`),W&&console.log(Ie(JSON.stringify(w,null,2)," "))}C.length>20&&console.log(` ... and ${C.length-20} more`)}else if(C==null)console.log(` not found: ${c||N||k||b||""||j}`),N&&G("wait-selector-for-missing-testid",N);else{let w=C;if(w.type&&w.absolutePosition){let I=`@(${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}`:"",oe=w.pressable?" (tap)":"",ee=w.accessibilityRole?`[${w.accessibilityRole}]`:w.type;console.log(` ${ee}${P}${V} ${Z} ${I}${oe}`),W&&console.log(Ie(JSON.stringify(w,null,2)," "))}else console.log(JSON.stringify(C,null,2))}}function Ie(o,d){return o.split(`
|
|
7
7
|
`).map(i=>d+i).join(`
|
|
8
|
-
`)}async function
|
|
9
|
-
`))}async function
|
|
8
|
+
`)}async function bt(o,d={}){let i=await nt(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:N}=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)":""}`),N&&k.push(` accessoryBar: ${N}`),console.log(k.join(`
|
|
9
|
+
`))}async function wt(o){let d=await o.bridge.listSims();if(D(o.args)){B(d.map(i=>({...i,active:i.id===o.simId})));return}ut(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 $t(o,d={args:[]}){let i=await it(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,7 +24,7 @@ import{a as G}from"./chunk-RBXJA2PW.js";import{a as je,b as Je}from"./chunk-ZYIT
|
|
|
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
|
|
27
|
+
})()`})??null}async function xt(o,d={}){let{nav:i,keyboard:l,shell:f}=await rt(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)":"",N=typeof f.launchProgress=="number"&&f.launchProgress<.98?` launching (${Math.round(f.launchProgress*100)}%)`:"";a.push(`shell: ${y}${S}${N}`)}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 N=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(` ${N} #${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
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))}
|
|
@@ -74,12 +74,12 @@ import{a as G}from"./chunk-RBXJA2PW.js";import{a as je,b as Je}from"./chunk-ZYIT
|
|
|
74
74
|
await sleep(pollMs)
|
|
75
75
|
}
|
|
76
76
|
return { settled: false, elapsed: Date.now() - start }
|
|
77
|
-
})()`}),{elapsed:y,settled:S}=a??{};return{elapsed:typeof y=="number"?y:d,settled:S===!0}}async function
|
|
77
|
+
})()`}),{elapsed:y,settled:S}=a??{};return{elapsed:typeof y=="number"?y:d,settled:S===!0}}async function St(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 vt(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 kt(o){let{bridge:d,args:i,positional:l}=o,f=l[1]?Number(l[1]):5,{tree:a}=await qe(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 Tt(o,d={args:[]}){let i=await He(o);if(D(d.args)){B(i);return}console.log(i.url)}async function Mt(o){let{wsPort:d,commandTimeoutMs:i,simId:l,simIdSource:f,positional:a}=o,y=a[1]?Number(a[1]):30,S=Math.max(1e3,(Number.isFinite(y)?y:30)*1e3),N=Math.max(1,Math.ceil(S/500));console.log(" waiting for sim reconnect...");let k=await at(d,i,l,{attempts:N,simIdSource:f});k||(console.error(" timed out waiting for sim reconnect"),process.exit(1)),k.bridge.close(),ce({source:"inspect wait",step:{wait:S},summary:`wait ${Math.round(S/1e3)}s`}),console.log(` ready: ${k.count} nodes`)}var It=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 io(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)),It.has(a)||console.error(` warning: '${a}' is not a known timeline kind \u2014 waiting anyway. known: ${[...It].sort().join(", ")}`);let y=pe(i,"--max-ms"),S=y&&Number.isFinite(Number(y))?Math.max(100,Number(y)):5e3,N=pe(i,"--filter"),k=pe(i,"--equals"),b=pe(i,"--since")??"now",v=i.includes("--json"),_=Date.now(),T=_+S,E=200,L=_;for(;Date.now()<T;){let K={kinds:[a],since:b==="cursor"?void 0:L,limit:50},j=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
|
-
})()`});(!
|
|
82
|
-
`).slice(0,5);for(let y of a)console.log(` ${y.trim()}`)}}var Q="__sootsimCliPerf",
|
|
81
|
+
})()`});(!j||!j.ok)&&(console.error(` could not query timeline: ${j&&"error"in j?j.error:"unknown"}`),process.exit(1));let C=j.result.events??[];for(let Y of C)if(io(Y,{filter:N,equals:k})){let W=Date.now()-_;console.log(v?JSON.stringify({found:!0,elapsedMs:W,event:Y}):` ${a} event after ${W}ms${N?` (filter: ${N})`:""}${k?` (equals: ${k})`:""}`);return}j.result.watermark&&j.result.watermark>L&&(L=j.result.watermark),await new Promise(Y=>setTimeout(Y,E))}let c=Date.now()-_;v?console.log(JSON.stringify({found:!1,elapsedMs:c,kind:a,filter:N,equals:k})):console.error(` \u26A0 wait event ${a} timed out after ${c}ms${N?` (filter: ${N})`:""}${k?` (equals: ${k})`:""}`),process.exit(1)}async function _t(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 Ft(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 Ye(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 At(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:N,node:k,elapsed:b}=await Ge(d,a,S);if(N&&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 Dt(o){return o==null?"\u2014":o<1024?`${o}B`:o<1024*1024?`${(o/1024).toFixed(1)}K`:`${(o/1024/1024).toFixed(1)}M`}function Bt(o){return o==null?" \u2026":o<1e3?`${o}ms`.padStart(5):`${(o/1e3).toFixed(2)}s`.padStart(5)}function lo(o){return o.error?"err":o.status==null?" \u2026 ":String(o.status)}function Pt(o){let d=new Date(o.startTs).toLocaleTimeString(),i=lo(o).padEnd(3),l=o.method.padEnd(5),f=Dt(o.size).padStart(6),a=Bt(o.durationMs);console.log(` [${d}] ${i} ${l} ${f} ${a} ${o.displayUrl}`),o.error&&console.log(` error: ${o.error}`)}function co(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",Bt(o.durationMs).trim()],["size",Dt(o.size)],["content-type",o.type??"\u2014"]];for(let[i,l]of d)console.log(` ${i.padEnd(13)} ${l}`)}var uo={error:"\x1B[31m",warn:"\x1B[33m",info:"\x1B[36m",debug:"\x1B[35m",log:"\x1B[37m"},Ot="\x1B[0m",mo="\x1B[2m";function Rt(o,d){let i=new Date(o.ts).toLocaleTimeString(),l=o.level.toUpperCase().padEnd(5),f=o.args.join(" ");if(d){let a=uo[o.level];console.log(` ${mo}[${i}]${Ot} ${a}${l}${Ot} ${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",po=120;async function Et(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:E,w:L,h:c}=_;return{x:T,y:E,w:L,h:c}}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,E,L,c]=_;return{x:T,y:E,w:L,h:c}}let a=_=>{let T=o.find((L,c)=>o[c-1]===_);if(T==null)return null;let E=Number(T);return Number.isFinite(E)?E:null},y=a("--x"),S=a("--y"),N=a("--w"),k=a("--h");if(y!=null||S!=null||N!=null||k!=null)return{x:y??0,y:S??0,w:N??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,E=1,L=1]=v;return{x:_,y:T,w:E,h:L}}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 Fe(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,7 +111,7 @@ import{a as G}from"./chunk-RBXJA2PW.js";import{a as je,b as Je}from"./chunk-ZYIT
|
|
|
111
111
|
frame: runtimeSnapshot?.keyboard?.frame ?? null,
|
|
112
112
|
focusedRect: runtimeSnapshot?.focused?.rect ?? null,
|
|
113
113
|
}
|
|
114
|
-
})()`})}async function
|
|
114
|
+
})()`})}async function fo(o,d=600){let i=Date.now()+d;for(;Date.now()<=i;){let l=await Fe(o);if(l.visible)return l;await X(30)}return Fe(o)}async function ge(o,d){let i=await Fe(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 Ct(o,d,i){return d==="appearance"?o.send({type:"evaluate",code:`(async () => {
|
|
115
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'
|
|
@@ -128,28 +128,28 @@ import{a as G}from"./chunk-RBXJA2PW.js";import{a as je,b as Je}from"./chunk-ZYIT
|
|
|
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 n
|
|
133
|
-
`),process.exit(0))}let
|
|
131
|
+
})()`})}function go(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 yo(o){if(typeof o!="string")return null;let d=o.replace(/\s+/g," ").trim();return d?d.slice(0,80):null}function jt(...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 ho(o,d,i){if(!i||i.hit===!1)return null;let l=jt(i.responderTestID,i.testID);if(l)return{step:{tapOn:{id:l}},summary:`tap #${l}`};let f=yo(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 _e(o,d,i){let l=jt(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 Vs(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=Re(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",N=typeof l[0]=="string"&&Pe.has(l[0]),k=N?l[0]:null,b=t=>N&&t===l[0]?`sootsim ${t}`:`sootsim ${S} ${t}`,v=(t,e)=>` usage: ${b(t)}${e?` ${e}`:""}`;if(!y||o.includes("--help")||o.includes("-h")){let t={bridgePort:7668,defaultShellUrl:Ae};if(S==="do"||S==="get"||S==="debug"||S==="wait"){let n=we(S,t);n&&(console.log(`${n}
|
|
132
|
+
`),process.exit(0))}if(k==="shell"){let n=$e("shell",t);n&&(console.log(`${n}
|
|
133
|
+
`),process.exit(0))}let e=$e("inspect",t),s=["do","get","debug","wait"].map(n=>we(n,t)).filter(n=>n!=null).join(`
|
|
134
134
|
|
|
135
|
-
`);console.log(`${
|
|
135
|
+
`);console.log(`${e??""}
|
|
136
136
|
|
|
137
137
|
${s}
|
|
138
|
-
`),process.exit(0)}let _=f.wsPort,T=f.simId,
|
|
139
|
-
`);let s=Math.max(...
|
|
140
|
-
`)}catch{}}async function
|
|
138
|
+
`),process.exit(0)}let _=f.wsPort,T=f.simId,E=f.simIdSource,L=f.commandTimeoutMs;if(y==="list"&&l.some(t=>t==="--drivers"||t==="-D")){let{buildDriverListRows:t}=await import("./drivers-LCWLVDG3.js"),e=t();console.log(` available drivers (${e.length}):
|
|
139
|
+
`);let s=Math.max(...e.map(r=>r.id.length),6),n=Math.max(...e.map(r=>r.kind.length),4);for(let r of e){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=Ee(f),K=T||"default",j=new Set(["errors","warnings","requests","js","eval","reload","globals","perf","list","wait","sleep"]),C=200;function Y(t){let e=t.replace(/\s+/g," ").trim();if(!e)return"";if(/^<(!doctype html|html|\?xml)|<body[\s>]/i.test(e)){let n=/<title[^>]*>([^<]+)<\/title>/i.exec(t)?.[1]?.trim(),r=/<body[^>]*>([\s\S]*?)<\//i.exec(t)?.[1]?.replace(/<[^>]+>/g," ").replace(/\s+/g," ").trim().slice(0,80),u=n||r||"html error page";return`<html ${t.length}B> "${u}" (body elided \u2014 add --json for the full payload)`}return e.length<=C?e:`${e.slice(0,C)}\u2026 (+${e.length-C} more bytes)`}function W(t){let e=t.displayUrl||t.url;return t.status!=null?`${t.method} ${e} -> ${t.status}${t.statusText?` ${t.statusText}`:""}`:t.error?`${t.method} ${e} -> ${t.error}`:`${t.method} ${e}`}async function w(t){let e=yt()?1200:350;try{let{settled:s,elapsed:n}=await ne({bridge:t,maxMs:e,pollMs:32,stablePolls:2});s||process.stderr.write(` \u26A0 auto-wait timed out after ${n??e}ms \u2014 next command may see mid-animation state. use \`sootsim do settle\` for a longer wait.
|
|
140
|
+
`)}catch{}}async function I(){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
|
|
144
|
-
network: ${s} failed request${s===1?"":"s"}`),console.log(` inspect: ${b("requests")} 5`),!
|
|
143
|
+
}))()`})||{console:null,requests:null}}catch{return{console:null,requests:null}}}async function Z(t={}){let e=t.counts!==void 0?t.counts:await z(c,"getRequestCounts");if(!e||typeof e!="object")return;let s=Math.max(0,Number(e.failed)||0);if(s===0||!t.includeTail&&!Te("requests",K,String(s))||(console.log(`
|
|
144
|
+
network: ${s} failed request${s===1?"":"s"}`),console.log(` inspect: ${b("requests")} 5`),!t.includeTail))return;let n=await z(c,"getFailedRequests",5);if(!(!Array.isArray(n)||n.length===0)){console.log(`
|
|
145
145
|
recent failed requests:
|
|
146
|
-
`);for(let r of n){let u=new Date(r.timestamp).toLocaleTimeString();console.log(` [${u}] ${
|
|
147
|
-
console: ${u.join(", ")}`),console.log(` inspect: ${b("errors")} 5`),r>0&&console.log(` inspect: ${b("warnings")} 5`),!
|
|
146
|
+
`);for(let r of n){let u=new Date(r.timestamp).toLocaleTimeString();console.log(` [${u}] ${W(r)}`),r.responseBody?console.log(` ${Y(r.responseBody)}`):r.error&&console.log(` ${r.error}`)}}}async function P(t={}){let e=t.counts!==void 0?t.counts:await c.send({type:"evaluate",code:"window.__sootsimConsole?.count?.() || { errors: 0, warnings: 0, total: 0 }"});if(!e||typeof e!="object")return;let s=e,n=Math.max(0,Number(s.errors)||0),r=Math.max(0,Number(s.warnings)||0);if(n===0&&r===0||!t.includeTail&&!Te("console",K,`${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`),!t.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 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
|
|
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 V=["console","fetch","toast","alert","notification","screen","app-launch","keyboard","route","actionsheet","picker","shell","scroll","gesture","text-input","animation","reanimated"];async function oe(t){let e=Oe(),s=null;try{s=await De(t,`(() => {
|
|
150
150
|
const tl = window.SootSim && window.SootSim.bridges && window.SootSim.bridges.timeline
|
|
151
151
|
if (!tl || typeof tl.summary !== 'function') return null
|
|
152
|
-
const cursorKey = ${JSON.stringify(
|
|
152
|
+
const cursorKey = ${JSON.stringify(e)}
|
|
153
153
|
const summary = tl.summary({ sinceCursor: cursorKey })
|
|
154
154
|
let consoleSplit = null
|
|
155
155
|
if (summary && summary.byKind && summary.byKind.console) {
|
|
@@ -162,11 +162,11 @@ ${s}
|
|
|
162
162
|
}
|
|
163
163
|
}
|
|
164
164
|
return summary ? { summary, consoleSplit } : null
|
|
165
|
-
})()`)}catch{return}if(!s||!s.summary||!s.summary.total)return;let n=s.summary.byKind??{},r=[],u=new Set;for(let m of
|
|
166
|
-
since last: ${r.join(" \xB7 ")} \u2014 sootsim what-happened`),s.summary.lastAt))try{await
|
|
167
|
-
`);for(let
|
|
165
|
+
})()`)}catch{return}if(!s||!s.summary||!s.summary.total)return;let n=s.summary.byKind??{},r=[],u=new Set;for(let m of V){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 xe(t,"SootSim.bridges.timeline.cursorAdvance",e,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"]),ye=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"]),he=(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 Ce(c),ye.has(y)&&await de(c,{verbose:he});try{switch(y){case"list":{await wt({bridge:c,simId:T,args:l});break}case"tree":{await kt({bridge:c,args:l,positional:a});break}case"a11y":{let t=await Ke(c);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):
|
|
167
|
+
`);for(let e of t){let s=[];if(s.push(`[${e.role}]`),e.label){let n=e.label.length>50?e.label.slice(0,47)+"...":e.label;s.push(`"${n}"`)}if(e.hint&&s.push(`(hint: "${e.hint}")`),e.testID&&s.push(`#${e.testID}`),e.state){let n=[];e.state.disabled&&n.push("disabled"),e.state.selected&&n.push("selected"),e.state.checked===!0&&n.push("checked"),e.state.checked==="mixed"&&n.push("mixed"),e.state.busy&&n.push("busy"),e.state.expanded===!0&&n.push("expanded"),e.state.expanded===!1&&n.push("collapsed"),n.length&&s.push(`{${n.join(", ")}}`)}e.position&&s.push(`@(${e.position.x},${e.position.y})`),e.size&&s.push(`${e.size.w}x${e.size.h}`),console.log(" "+s.join(" "))}}break}case"find":{await ht({bridge:c,args:o,effectiveArgs:l,positional:a,inspectUsage:v});break}case"count":{await ft(c,{args:l});break}case"keyboard":{await bt(c,{json:o.includes("--json")});break}case"screens":{await xt(c,{json:o.includes("--json")});break}case"memory":{await $t(c,{args:l});break}case"wait":{await Mt({wsPort:_,commandTimeoutMs:L,simId:T,simIdSource:E,positional:a});break}case"sleep":{await vt({positional:a,inspectUsage:v});break}case"settle":{await St({bridge:c,args:o,positional:a});break}case"ready":{await Ft({bridge:c,args:o});break}case"idle":{await _t({bridge:c,args:o,positional:a});break}case"selector":{await At({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 t=a[1];t||(console.error(v("layout","<id>")),process.exit(1));let e=await c.send({type:"evaluate",code:`(async () => await window.__sootsimTest.getLayout(${JSON.stringify(t)}))()`});console.log(JSON.stringify(e,null,2));break}case"capture":case"screenshot":{let e=o.find((x,g)=>o[g-1]==="--output")||"/tmp/sootsim-inspect.png",s=await Et(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(e,Buffer.from(u,"base64")),console.log(` saved: ${e}`);break}case"sample-color":{let t=await Et(o,c);t||(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 e=await c.send({type:"evaluate",code:Le(t)});if(o.includes("--json"))console.log(JSON.stringify(e,null,2));else{let{r:s,g:n,b:r,a:u,hex:m,samples:x}=e,g=t.w===1&&t.h===1?`@(${t.x},${t.y})`:`@(${t.x},${t.y}) ${t.w}x${t.h}`;console.log(` ${m} rgba(${s}, ${n}, ${r}, ${u}) ${g} ${x} samples`)}break}case"node":{let t=a[1];t||(console.error(v("node","<matcher>")),console.error(" resolves testID, id, then text \u2014 dumps full node info as JSON"),process.exit(1));let e=await c.send({type:"evaluate",code:`(async () => {
|
|
168
168
|
const t = window.__sootsimTest
|
|
169
|
-
const q = ${JSON.stringify(
|
|
169
|
+
const q = ${JSON.stringify(t)}
|
|
170
170
|
let node = null
|
|
171
171
|
let via = null
|
|
172
172
|
if (t.findByTestId) { node = await t.findByTestId(q); if (node) via = 'testID' }
|
|
@@ -220,17 +220,17 @@ ${s}
|
|
|
220
220
|
transform,
|
|
221
221
|
parentChain,
|
|
222
222
|
}
|
|
223
|
-
})()`});console.log(JSON.stringify(
|
|
223
|
+
})()`});console.log(JSON.stringify(e,null,2));break}case"tap":{let t=Number(a[1]),e=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)),t=u.x,e=u.y}(!Number.isFinite(t)||!Number.isFinite(e))&&(console.error(v("tap","<x> <y> | --testid <id> | --text <t>")),process.exit(1));let n=await c.send({type:"tap",x:t,y:e}),r=ho(t,e,n);r&&await J("inspect tap",r.step,r.summary),console.log(JSON.stringify(n,null,2));break}case"drag":case"swipe":{let t=Number(a[1]),e=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(t)||!Number.isFinite(e)||!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 () => {
|
|
224
224
|
const interact = window.__sootsimInteract
|
|
225
225
|
if (!interact?.drag) return { ok: false, reason: 'no interact.drag' }
|
|
226
|
-
const value = await interact.drag(${
|
|
226
|
+
const value = await interact.drag(${t}, ${e}, ${s}, ${n}, ${Math.max(1,Math.round(m))}, ${Math.max(0,Math.round(x))})
|
|
227
227
|
return { ok: !!value, value }
|
|
228
|
-
})()`});if(g?.ok){let $=Math.max(1,Math.round(Math.max(1,m)*Math.max(0,x)));await
|
|
228
|
+
})()`});if(g?.ok){let $=Math.max(1,Math.round(Math.max(1,m)*Math.max(0,x)));await J(`inspect ${y}`,{swipe:{start:`${t}, ${e}`,end:`${s}, ${n}`,duration:$}},`${y} ${t},${e} -> ${s},${n}`)}console.log(JSON.stringify(g,null,2));break}case"pinch":{let t=Number(a[1]),e=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(t)||!Number.isFinite(e)||!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 () => {
|
|
229
229
|
const interact = window.__sootsimInteract
|
|
230
230
|
if (!interact?.pinch) return { ok: false, reason: 'no interact.pinch' }
|
|
231
|
-
const value = await interact.pinch(${
|
|
231
|
+
const value = await interact.pinch(${t}, ${e}, ${s}, ${n}, ${r}, ${u}, ${m}, ${x}, ${Math.max(1,Math.round(g))}, ${Math.max(0,Math.round($))})
|
|
232
232
|
return { ok: !!value, value }
|
|
233
|
-
})()`});F?.ok&&await
|
|
233
|
+
})()`});F?.ok&&await J("inspect pinch",{pinch:{from:[t,e,s,n],to:[r,u,m,x],steps:Math.max(1,Math.round(g)),stepMs:Math.max(0,Math.round($))}},`pinch (${t},${e}) (${s},${n}) -> (${r},${u}) (${m},${x})`),console.log(JSON.stringify(F,null,2));break}case"tap-text":{let t=a[1];t||(console.error(v("tap-text","<text>")),process.exit(1));let e=R=>{let A=o.indexOf(R);return A>=0&&A+1<o.length?o[A+1]:null},s=R=>o.includes(R),n=e("--nth")??e("--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=e("--within"),m=e("--role"),x=s("--exact"),g=s("--first"),$=e("--min-y"),F=e("--max-y"),q=e("--min-x"),H=e("--max-x");for(let[R,A]of[["--min-y",$],["--max-y",F],["--min-x",q],["--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"),M=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)),M={x:R,y:A}}let h=JSON.stringify({query:t,exact:x,role:m,within:u,minX:q!==null?Number(q):null,maxX:H!==null?Number(H):null,minY:$!==null?Number($):null,maxY:F!==null?Number(F):null,near:M,nth:r,first:g}),p=await c.send({type:"evaluate",code:`(async () => {
|
|
234
234
|
const t = window.__sootsimTest
|
|
235
235
|
if (!t) return { error: 'bridge-not-ready' }
|
|
236
236
|
const F = ${h}
|
|
@@ -344,13 +344,13 @@ ${s}
|
|
|
344
344
|
total,
|
|
345
345
|
idx,
|
|
346
346
|
}
|
|
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 "${
|
|
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 "${t}"`);for(let A of R){let be=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}`:"",Lt=A.text?` "${A.text}"`:"",Wt=A.ancestorTestIDs.length>0?` within ${A.ancestorTestIDs.slice(0,3).map(qt=>`#${qt}`).join(" > ")}`:"";console.error(` [${A.idx}] <${A.type}>${Lt}${Jt} ${be}${le}${Wt}`)}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 "${t}"`),process.exit(1)),(!p||typeof p.cx!="number")&&(console.error(` not found: ${t}`),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=_e(t,{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 t=a[1];t||(console.error(v("tap-best","<query>")),process.exit(1));let e=JSON.stringify(t),s=await c.send({type:"evaluate",code:`(async () => {
|
|
348
348
|
const t = window.__sootsimTest
|
|
349
349
|
if (!t) return { error: 'bridge-not-ready' }
|
|
350
350
|
// try testID first \u2014 strongest signal of "this is the
|
|
351
351
|
// intended tap target".
|
|
352
352
|
const byTestId =
|
|
353
|
-
(await t.findByTestId(${
|
|
353
|
+
(await t.findByTestId(${e})) || (await t.findById(${e}))
|
|
354
354
|
if (byTestId && byTestId.absolutePosition && byTestId.layout) {
|
|
355
355
|
return {
|
|
356
356
|
strategy: 'testid',
|
|
@@ -369,7 +369,7 @@ ${s}
|
|
|
369
369
|
// 0 or 2+ matches \u2014 to disambiguate we'd send the user
|
|
370
370
|
// back to tap-text with --nth, which is the right
|
|
371
371
|
// failure mode.
|
|
372
|
-
const byText = await t.findByText(${
|
|
372
|
+
const byText = await t.findByText(${e})
|
|
373
373
|
if (byText && byText.absolutePosition && byText.layout) {
|
|
374
374
|
return {
|
|
375
375
|
strategy: 'text',
|
|
@@ -385,10 +385,10 @@ ${s}
|
|
|
385
385
|
}
|
|
386
386
|
}
|
|
387
387
|
return { strategy: 'none' }
|
|
388
|
-
})()`});"error"in s&&(console.error(` ${s.error}`),process.exit(1)),s.strategy==="none"&&(console.error(` tap-best: no testID or visible text matched "${
|
|
388
|
+
})()`});"error"in s&&(console.error(` ${s.error}`),process.exit(1)),s.strategy==="none"&&(console.error(` tap-best: no testID or visible text matched "${t}". 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=_e(t,{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 t=a[1];t||(console.error(v("tap-id","<id>")),process.exit(1));let e=JSON.stringify(t),s=await c.send({type:"evaluate",code:`(async () => {
|
|
389
389
|
const t = window.__sootsimTest
|
|
390
390
|
if (!t) return null
|
|
391
|
-
const n = (await t.findByTestId(${
|
|
391
|
+
const n = (await t.findByTestId(${e})) || (await t.findById(${e}))
|
|
392
392
|
if (!n || !n.absolutePosition || !n.layout) return { cx: null }
|
|
393
393
|
const resolved =
|
|
394
394
|
typeof n.nodeId === 'number' && typeof t.resolveTapTarget === 'function'
|
|
@@ -420,7 +420,7 @@ ${s}
|
|
|
420
420
|
},
|
|
421
421
|
strategy: (resolved && resolved.strategy) || 'matched-node',
|
|
422
422
|
}
|
|
423
|
-
})()`});(!s||typeof s.cx!="number")&&(console.error(` not found: ${
|
|
423
|
+
})()`});(!s||typeof s.cx!="number")&&(console.error(` not found: ${t}`),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=_e(t,{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 t=a[1],e=a.slice(2).join(" ");(!t||!e)&&(console.error(v("type-into","<id> <text>")),process.exit(1));let s=JSON.stringify(t),n=await c.send({type:"evaluate",code:`(async () => {
|
|
424
424
|
const t = window.__sootsimTest
|
|
425
425
|
if (!t) return null
|
|
426
426
|
const n = await (t.findByTestId(${s}) || t.findById(${s}))
|
|
@@ -432,41 +432,41 @@ ${s}
|
|
|
432
432
|
isTextInput: !!n.isTextInput,
|
|
433
433
|
placeholder: n.placeholder || null,
|
|
434
434
|
}
|
|
435
|
-
})()`});(!n||typeof n.cx!="number")&&(console.error(` not found: ${
|
|
435
|
+
})()`});(!n||typeof n.cx!="number")&&(console.error(` not found: ${t}`),process.exit(1)),n.isTextInput||console.error(` warning: ${t} is not a text input (isTextInput: false)`);let r=await c.send({type:"tap",x:n.cx,y:n.cy}),u=await fo(c);u.visible||(console.error(` keyboard did not open after tapping ${t}`),process.exit(1));let m=u.focusedInput;m&&(m.testID===t||m.id===t||(console.error(` focus routing mismatch after tap: requested ${JSON.stringify(t)} 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:e}),await J("inspect type-into",{tapOn:{id:t},inputText:e},`type-into #${t} ${JSON.stringify(e)}`),console.log(JSON.stringify({target:t,isTextInput:n.isTextInput,keyboardOpened:u.visible??r?.keyboardOpened??!1,focusedInput:u.focusedInput??null,typed:e},null,2));break}case"type":{let t=a.slice(1).join(" ");t||(console.error(v("type","<text>")),process.exit(1)),await ge(c,"type"),await c.send({type:"keyboard",action:"type",text:t}),await J("inspect type",{inputText:t},`type ${JSON.stringify(t)}`),console.log(` typed: ${JSON.stringify(t)}`);break}case"key":{let t=a[1];t||(console.error(v("key","<name>")),process.exit(1)),await ge(c,"key"),await c.send({type:"keyboard",action:"press",text:t}),await J("inspect key",{pressKey:t},`key ${t}`),console.log(` pressed: ${t}`);break}case"key-sequence":{let t=a.slice(1);t.length===0&&(console.error(v("key-sequence","<key> [<key> ...]")),process.exit(1)),await ge(c,"key-sequence");for(let e of t)await c.send({type:"keyboard",action:"press",text:e});await J("inspect key-sequence",{pressKey:t.join(" ")},`key-sequence ${t.join(" ")}`),console.log(` pressed: ${t.join(", ")}`);break}case"keycode":{let t=a.slice(1);t.length===0&&(console.error(v("keycode","<code> [<code> ...]")),process.exit(1));let e=t.map(n=>({code:n,key:go(n)})),s=e.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 e)await c.send({type:"keyboard",action:"press",text:n.key});await J("inspect keycode",{pressKey:e.map(n=>n.key).join(" ")},`keycode ${t.join(" ")}`),console.log(` pressed: ${t.join(", ")}`);break}case"dispatch":{let t=a[1];t||(console.error(v("dispatch","<char>")),process.exit(1)),await c.send({type:"keyboard",action:"dispatchKey",text:t}),await J("inspect dispatch",{dispatchKey:t},`dispatch ${JSON.stringify(t)}`),console.log(` dispatched: ${t}`);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 t=Number(a[1]),e=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)),t=m.x,e=m.y}let n=a[3]?Number(a[3]):80;(!Number.isFinite(t)||!Number.isFinite(e)||!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 () => {
|
|
436
436
|
const interact = window.__sootsimInteract
|
|
437
437
|
if (interact?.doubleTap) {
|
|
438
438
|
return {
|
|
439
|
-
ok: !!(await interact.doubleTap(${
|
|
439
|
+
ok: !!(await interact.doubleTap(${t}, ${e}, ${r})),
|
|
440
440
|
gapMs: ${r},
|
|
441
441
|
}
|
|
442
442
|
}
|
|
443
443
|
if (!interact?.tap) {
|
|
444
444
|
return { ok: false, reason: 'no interact.tap', gapMs: ${r} }
|
|
445
445
|
}
|
|
446
|
-
const first = await interact.tap(${
|
|
446
|
+
const first = await interact.tap(${t}, ${e})
|
|
447
447
|
if (!first || first.hit === false) {
|
|
448
448
|
return { ok: false, reason: 'first tap missed', gapMs: ${r}, first }
|
|
449
449
|
}
|
|
450
450
|
await new Promise((resolve) => setTimeout(resolve, ${r}))
|
|
451
|
-
const second = await interact.tap(${
|
|
451
|
+
const second = await interact.tap(${t}, ${e})
|
|
452
452
|
return {
|
|
453
453
|
ok: !!second && second.hit !== false,
|
|
454
454
|
gapMs: ${r},
|
|
455
455
|
first,
|
|
456
456
|
second,
|
|
457
457
|
}
|
|
458
|
-
})()`});u?.ok&&await
|
|
458
|
+
})()`});u?.ok&&await J("inspect double-tap",{doubleTapAtCoords:{x:t,y:e,gapMs:r}},`double-tap @${t},${e}`),console.log(JSON.stringify(u,null,2));break}case"long-press":{let t=Number(a[1]),e=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)),t=u.x,e=u.y}let n=a[3]?Number(a[3]):600;(!Number.isFinite(t)||!Number.isFinite(e)||!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 () => {
|
|
459
459
|
const interact = window.__sootsimInteract
|
|
460
460
|
if (!interact?.longPress) return { ok: false, reason: 'no interact.longPress' }
|
|
461
|
-
const value = await interact.longPress(${
|
|
461
|
+
const value = await interact.longPress(${t}, ${e}, ${Math.max(0,Math.round(n))})
|
|
462
462
|
return { ok: !!value, value }
|
|
463
|
-
})()`});r?.ok&&await
|
|
463
|
+
})()`});r?.ok&&await J("inspect long-press",{tapAtCoords:{x:t,y:e}},`long-press @${t},${e}`),console.log(JSON.stringify(r,null,2));break}case"touch":{let t=a[1],e=Number(a[2]),s=Number(a[3]),n=a[4]?Number(a[4]):999,r=t==="down"?"touchDown":t==="move"?"touchMove":t==="up"?"touchUp":t==="cancel"?"touchCancel":null;r||(console.error(v("touch","<down|move|up|cancel> <x> <y> [pointerId]")),process.exit(1)),t!=="cancel"&&(!Number.isFinite(e)||!Number.isFinite(s))&&(console.error(v("touch","<down|move|up|cancel> <x> <y> [pointerId]")),process.exit(1));let u=t==="down"?"tap":t==="move"?"move":null,m=u&&Number.isFinite(e)&&Number.isFinite(s)?`window.dispatchEvent(new CustomEvent('sootsim:agentAction', { detail: { type: '${u}', x: ${e}, y: ${s} } }));`:"",x=await c.send({type:"evaluate",code:`(async () => {
|
|
464
464
|
${m}
|
|
465
465
|
const interact = window.__sootsimInteract
|
|
466
466
|
if (!interact?.${r}) return { ok: false, reason: 'no interact.${r}' }
|
|
467
|
-
const value = ${
|
|
467
|
+
const value = ${t==="cancel"?`await interact.${r}(${Math.max(1,Math.round(n))})`:`await interact.${r}(${e}, ${s}, ${Math.max(1,Math.round(n))})`}
|
|
468
468
|
return { ok: !!value, value }
|
|
469
|
-
})()`});x?.ok&&
|
|
469
|
+
})()`});x?.ok&&t!=="cancel"&&await J("inspect touch",{tapAtCoords:{x:e,y:s}},`touch ${t} @${e},${s}`),console.log(JSON.stringify(x,null,2));break}case"gesture":{let t=["scroll-up","scroll-down","scroll-left","scroll-right","swipe-from-left-edge","swipe-from-right-edge","swipe-from-top-edge","swipe-from-bottom-edge"],e=a[1],s=a[2]?Number(a[2]):220;(!e||!Number.isFinite(s))&&(console.error(v("gesture","<preset> [durationMs]")),console.error(` presets: ${t.join(", ")}`),process.exit(1)),t.includes(e)||(console.error(` unknown gesture preset: ${e}`),console.error(` presets: ${t.join(", ")}`),process.exit(1));let n=await c.send({type:"evaluate",code:`(async () => {
|
|
470
470
|
const spec = globalThis.__sootsimDeviceSpec || {}
|
|
471
471
|
return {
|
|
472
472
|
width: spec.width || window.innerWidth || 393,
|
|
@@ -474,25 +474,25 @@ ${s}
|
|
|
474
474
|
statusBarHeight: spec.statusBarHeight || 0,
|
|
475
475
|
homeIndicatorHeight: spec.homeIndicatorHeight || 0,
|
|
476
476
|
}
|
|
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),
|
|
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),q=Math.max(24,x+18),H=18,U=Math.min(220,Math.round(u*.24)),M=Math.min(180,Math.round(r*.32)),h=g,p=$,O=g,R=$;switch(e){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(M/2),O=g-Math.round(M/2);break;case"scroll-right":h=g-Math.round(M/2),O=g+Math.round(M/2);break;case"swipe-from-left-edge":h=H,p=$,O=Math.min(r-H,H+M);break;case"swipe-from-right-edge":h=r-H,p=$,O=Math.max(H,r-H-M);break;case"swipe-from-top-edge":h=g,p=F,R=Math.min(u-q,F+U);break;case"swipe-from-bottom-edge":h=g,p=u-q,R=Math.max(F,u-q-U);break}let A=Math.max(8,Math.round(s/16)),be=Math.max(1,Math.round(s/A)),le=await c.send({type:"evaluate",code:`(async () => {
|
|
478
478
|
const interact = window.__sootsimInteract
|
|
479
479
|
if (!interact?.drag) return { ok: false, reason: 'no interact.drag' }
|
|
480
|
-
const value = await interact.drag(${h}, ${p}, ${O}, ${R}, ${A}, ${
|
|
480
|
+
const value = await interact.drag(${h}, ${p}, ${O}, ${R}, ${A}, ${be})
|
|
481
481
|
return { ok: !!value, value }
|
|
482
|
-
})()`});le?.ok&&await
|
|
482
|
+
})()`});le?.ok&&await J("inspect gesture",{swipe:{start:`${h}, ${p}`,end:`${O}, ${R}`,duration:Math.max(1,Math.round(s))}},`gesture ${e}`),console.log(JSON.stringify({preset:e,from:{x:h,y:p},to:{x:O,y:R},result:le},null,2));break}case"scroll":{let t=ae(o),e=t?.mode==="testid"?t.value:a[1],s=Number(a[t?1:2]),n=Number(a[t?2:3]);(!e||!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 () => {
|
|
483
483
|
const t = window.__sootsimTest
|
|
484
484
|
if (!t) return null
|
|
485
|
-
const n = await t.findByTestId(${JSON.stringify(
|
|
486
|
-
|| await t.findById(${JSON.stringify(
|
|
485
|
+
const n = await t.findByTestId(${JSON.stringify(e)})
|
|
486
|
+
|| await t.findById(${JSON.stringify(e)})
|
|
487
487
|
if (!n || !n.absolutePosition || !n.layout) return null
|
|
488
488
|
return {
|
|
489
489
|
cx: n.absolutePosition.x + (n.layout.width || 0) / 2,
|
|
490
490
|
cy: n.absolutePosition.y + (n.layout.height || 0) / 2,
|
|
491
491
|
}
|
|
492
|
-
})()`}),u=await
|
|
492
|
+
})()`}),u=await z(c,"scrollTo",e,s,n,!1);u?.ok&&await J("inspect scroll",{scrollTo:{id:e,x:s,y:n}},`scroll ${e} -> ${s},${n}`),console.log(JSON.stringify({...u,...r?{at:{x:r.cx,y:r.cy}}:{}},null,2));break}case"state":{let t=a[1];if(i==="get"&&!t){let s=await z(c,"getRuntimeState"),n=await c.send({type:"evaluate",code:`({
|
|
493
493
|
errors: window.__sootsimConsole?.getErrors?.()?.length ?? 0,
|
|
494
494
|
warnings: window.__sootsimConsole?.getWarnings?.()?.length ?? 0,
|
|
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(!
|
|
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(!t||t==="--help"||t==="-h"){console.log(`
|
|
496
496
|
${b("state")} \u2014 dump raw runtime state
|
|
497
497
|
|
|
498
498
|
subcommands:
|
|
@@ -515,13 +515,13 @@ ${s}
|
|
|
515
515
|
${b("state")} scroll feed
|
|
516
516
|
${b("state")} scroll-hit 360 420
|
|
517
517
|
${b("state")} hit 200 720
|
|
518
|
-
`);break}let
|
|
518
|
+
`);break}let e;switch(t){case"shell":e=await se(c,500);break;case"worker":e=await xe(c,"__sootsimRenderHost.queryStats");break;case"ownership":e=await c.send({type:"evaluate",code:`(() => {
|
|
519
519
|
const h = window.__sootsimRenderHost
|
|
520
520
|
if (!h || typeof h.getOwnershipSnapshot !== 'function') {
|
|
521
521
|
return { error: 'getOwnershipSnapshot not available' }
|
|
522
522
|
}
|
|
523
523
|
return h.getOwnershipSnapshot()
|
|
524
|
-
})()`});break;case"keyboard":
|
|
524
|
+
})()`});break;case"keyboard":e=await c.send({type:"evaluate",code:`(async () => {
|
|
525
525
|
const kb = window.__sootsimKeyboard
|
|
526
526
|
const test = window.__sootsimTest
|
|
527
527
|
if (!kb) return { error: 'keyboard bridge not available' }
|
|
@@ -546,7 +546,7 @@ ${s}
|
|
|
546
546
|
text: focused.text || null,
|
|
547
547
|
} : null,
|
|
548
548
|
}
|
|
549
|
-
})()`});break;case"node":{let s=a[2];s||(console.error(` usage: ${b("state")} node <id>`),process.exit(1)),
|
|
549
|
+
})()`});break;case"node":{let s=a[2];s||(console.error(` usage: ${b("state")} node <id>`),process.exit(1)),e=await z(c,"findByTestId",s)||await z(c,"findById",s);break}case"scroll":{let s=a[2];s||(console.error(` usage: ${b("state")} scroll <id>`),process.exit(1)),e=await z(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)),e=await z(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)),e=await z(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)),e=await z(c,"debugGestureAt",s,n);break}default:console.error(` unknown state subcommand: ${t}`),process.exit(1)}console.log(JSON.stringify(e,null,2));break}case"shell":{let t=a[1];if(!t||t==="--help"||t==="-h"){console.log(`
|
|
550
550
|
${b("shell")} \u2014 run built-in shell commands
|
|
551
551
|
|
|
552
552
|
subcommands:
|
|
@@ -570,7 +570,7 @@ ${s}
|
|
|
570
570
|
${b("shell")} open-card clock 800
|
|
571
571
|
${b("shell")} appearance dark
|
|
572
572
|
${b("shell")} lock
|
|
573
|
-
`);break}let t
|
|
573
|
+
`);break}let e=t==="launch"||t==="open-card"||t==="home"||t==="switcher",s=t==="launch"||t==="open-card"?a[3]:a[2],n=s?Number(s):350;e&&(!Number.isFinite(n)||n<0)&&(console.error(v("shell",t==="launch"||t==="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(t==="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:Be}),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(t==="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(t==="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(po),m=await se(c));else if(t==="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(t==="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 Ct(c,"appearance",g);if(r=!!$?.ok,m={appearance:$},r){let F=$?.applied??g;console.log(` appearance: ${F}`)}}else if(t==="lock"||t==="shake"){let g=await Ct(c,t);r=!!g?.ok,m={[t]:g}}else console.error(` unknown shell subcommand: ${t}`),process.exit(1);console.log(JSON.stringify({ok:r,settled:u,state:m},null,2));break}case"url":{await Tt(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:`;(() => {
|
|
574
574
|
const reloadExternalApp = window.SootSim?.bridges?.hotRemount?.reloadExternalApp
|
|
575
575
|
if (typeof reloadExternalApp === 'function') {
|
|
576
576
|
reloadExternalApp()
|
|
@@ -578,10 +578,10 @@ ${s}
|
|
|
578
578
|
}
|
|
579
579
|
window.location.reload()
|
|
580
580
|
return { kind: 'page' }
|
|
581
|
-
})()`});n=!!m&&m.kind==="external-app",s=!0}catch{}console.log(" reloading...");let r=c,u=null;if(n)u=await
|
|
581
|
+
})()`});n=!!m&&m.kind==="external-app",s=!0}catch{}console.log(" reloading...");let r=c,u=null;if(n)u=await ke(c,{timeoutMs:1e4,errorGraceMs:3e3});else{s&&await X(300);let m=await lt(_,L,T,{timeoutMs:1e4,simIdSource:E});m?(r=m,u=await ke(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(`
|
|
582
582
|
\u26A0 ${m.length} error(s) during mount:
|
|
583
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
|
|
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 t=a.slice(1).join(" ");t||(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 e=t;e.startsWith("(async")||(e=`(async () => ${e})()`);let s=await c.send({type:"evaluate",code:e});console.log(JSON.stringify(s,null,2));let n=t.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 t=await c.send({type:"evaluate",code:`(async () => {
|
|
585
585
|
const globals = {}
|
|
586
586
|
|
|
587
587
|
// test bridge (proxy in worker mode)
|
|
@@ -619,7 +619,7 @@ ${s}
|
|
|
619
619
|
|
|
620
620
|
return globals
|
|
621
621
|
})()`});console.log(` sootsim JS API:
|
|
622
|
-
`);for(let[
|
|
622
|
+
`);for(let[e,s]of Object.entries(t)){console.log(` ${e}:`);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 gt({bridge:c,args:o,positional:a});break}case"perf":{let t=a[1];if(!t||t==="--help"||t==="-h"){console.log(`
|
|
623
623
|
${b("perf")} \u2014 performance profiling
|
|
624
624
|
|
|
625
625
|
subcommands:
|
|
@@ -635,7 +635,7 @@ ${s}
|
|
|
635
635
|
# ... interact with the app ...
|
|
636
636
|
${b("perf")} stop
|
|
637
637
|
${b("perf")} transition goHome
|
|
638
|
-
`);break}switch(
|
|
638
|
+
`);break}switch(t){case"stats":{let e=await c.send({type:"evaluate",code:`(async () => {
|
|
639
639
|
// worker mode (host exposes these)
|
|
640
640
|
if (window.__sootsimPerfStats) {
|
|
641
641
|
return await window.__sootsimPerfStats()
|
|
@@ -660,7 +660,7 @@ ${s}
|
|
|
660
660
|
jankFrames: frameStats.recentFrames?.filter(f => f > 16.67).length || 0,
|
|
661
661
|
recentCount: frameStats.recentFrames?.length || 0,
|
|
662
662
|
}
|
|
663
|
-
})()`});
|
|
663
|
+
})()`});e.error&&(console.error(` error: ${e.error}`),process.exit(1));let s=e.avgMs!=="?"?(1e3/parseFloat(e.avgMs)).toFixed(1):"?";console.log(" perf stats:"),console.log(` frames: ${e.frames}`),console.log(` avg: ${e.avgMs}ms (${s} fps)`),console.log(` max: ${e.maxMs}ms`),console.log(` layout: ${e.layoutMs}ms total`),console.log(` nodes: ${e.nodeCount}`),e.recentCount>0&&console.log(` jank: ${e.jankFrames}/${e.recentCount} frames >16.67ms`);break}case"start":{await c.send({type:"evaluate",code:`(async () => {
|
|
664
664
|
// worker mode
|
|
665
665
|
if (window.__sootsimPerfStart && window.__sootsimRenderHost) {
|
|
666
666
|
const result = window.__sootsimPerfStart()
|
|
@@ -682,7 +682,7 @@ ${s}
|
|
|
682
682
|
startedAt: performance.now(),
|
|
683
683
|
}
|
|
684
684
|
return { started: true }
|
|
685
|
-
})()`}),console.log(` profiling started \u2014 interact with the app, then run '${b("perf")} stop'`);break}case"stop":{let
|
|
685
|
+
})()`}),console.log(` profiling started \u2014 interact with the app, then run '${b("perf")} stop'`);break}case"stop":{let e=await c.send({type:"evaluate",code:`(async () => {
|
|
686
686
|
// worker mode
|
|
687
687
|
if (window.__sootsimRenderHost) {
|
|
688
688
|
const session = window.${Q} || {}
|
|
@@ -776,8 +776,8 @@ ${s}
|
|
|
776
776
|
jankFrames: recent.filter(f => f > 16.67).length,
|
|
777
777
|
sampleCount: recent.length,
|
|
778
778
|
}
|
|
779
|
-
})()`});
|
|
780
|
-
`),console.log(` frames: ${
|
|
779
|
+
})()`});e.error&&(console.error(` error: ${e.error}`),process.exit(1));let s=e.avgMs>0?(1e3/e.avgMs).toFixed(1):"?",n=e.sampleCount>0?(e.jankFrames/e.sampleCount*100).toFixed(1):"0";console.log(` profiling stopped:
|
|
780
|
+
`),console.log(` frames: ${e.frames}`),console.log(` total: ${e.totalMs.toFixed(1)}ms`),console.log(` avg: ${e.avgMs.toFixed(2)}ms (${s} fps)`),console.log(` max: ${e.maxMs.toFixed(2)}ms`),console.log(""),e.layoutAvgMs!==void 0&&(console.log(" breakdown (avg per frame):"),console.log(` layout: ${e.layoutAvgMs.toFixed(2)}ms`),console.log(` render: ${e.renderAvgMs.toFixed(2)}ms`),console.log(` copy: ${e.copyAvgMs.toFixed(2)}ms`),e.auxAvgMs!==void 0&&console.log(` aux: ${e.auxAvgMs.toFixed(2)}ms`),e.otherAvgMs!==void 0&&console.log(` other: ${e.otherAvgMs.toFixed(2)}ms`),console.log("")),console.log(` distribution (${e.sampleCount} samples):`),console.log(` p50: ${e.p50.toFixed(2)}ms`),console.log(` p95: ${e.p95.toFixed(2)}ms`),console.log(` p99: ${e.p99.toFixed(2)}ms`),console.log(` jank: ${e.jankFrames} frames (${n}%) >16.67ms`);break}case"frames":{let e=a[2]?Number(a[2]):50;(!Number.isFinite(e)||e<=0)&&(console.error(` error: expected a positive frame count, got "${a[2]}"`),process.exit(1));let s=await c.send({type:"evaluate",code:`(async () => {
|
|
781
781
|
if (window.__sootsimRenderHost) {
|
|
782
782
|
const session = window.${Q} || {}
|
|
783
783
|
if (session.active) {
|
|
@@ -795,13 +795,13 @@ ${s}
|
|
|
795
795
|
return {
|
|
796
796
|
mode: 'render-worker',
|
|
797
797
|
live: true,
|
|
798
|
-
samples: samples.slice(-${
|
|
798
|
+
samples: samples.slice(-${e}),
|
|
799
799
|
}
|
|
800
800
|
}
|
|
801
801
|
return {
|
|
802
802
|
mode: 'render-worker',
|
|
803
803
|
live: false,
|
|
804
|
-
samples: (session.lastSamples || []).slice(-${
|
|
804
|
+
samples: (session.lastSamples || []).slice(-${e}),
|
|
805
805
|
}
|
|
806
806
|
}
|
|
807
807
|
// main-thread mode
|
|
@@ -810,9 +810,9 @@ ${s}
|
|
|
810
810
|
const stats = perf.getFrameStats?.() || {}
|
|
811
811
|
return {
|
|
812
812
|
mode: 'main-thread',
|
|
813
|
-
frames: (stats.recentFrames || []).slice(-${
|
|
813
|
+
frames: (stats.recentFrames || []).slice(-${e}),
|
|
814
814
|
}
|
|
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,
|
|
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,q]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)} ${q.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 e=a[2]?Number(a[2]):20;(!Number.isFinite(e)||e<=0)&&(console.error(` error: expected a positive frame count, got "${a[2]}"`),process.exit(1));let s=await c.send({type:"evaluate",code:`(async () => {
|
|
816
816
|
if (window.__sootsimRenderHost) {
|
|
817
817
|
const session = window.${Q} || {}
|
|
818
818
|
if (session.active) {
|
|
@@ -833,7 +833,7 @@ ${s}
|
|
|
833
833
|
samples: samples
|
|
834
834
|
.slice()
|
|
835
835
|
.sort((a, b) => b[1] - a[1])
|
|
836
|
-
.slice(0, ${
|
|
836
|
+
.slice(0, ${e}),
|
|
837
837
|
}
|
|
838
838
|
}
|
|
839
839
|
const samples = Array.isArray(session.lastSamples) ? session.lastSamples : []
|
|
@@ -843,7 +843,7 @@ ${s}
|
|
|
843
843
|
samples: samples
|
|
844
844
|
.slice()
|
|
845
845
|
.sort((a, b) => b[1] - a[1])
|
|
846
|
-
.slice(0, ${
|
|
846
|
+
.slice(0, ${e}),
|
|
847
847
|
}
|
|
848
848
|
}
|
|
849
849
|
const perf = window.__sootsimPerf
|
|
@@ -852,9 +852,9 @@ ${s}
|
|
|
852
852
|
const recent = Array.isArray(stats.recentFrames) ? stats.recentFrames : []
|
|
853
853
|
return {
|
|
854
854
|
mode: 'main-thread',
|
|
855
|
-
frames: recent.slice().sort((a, b) => b - a).slice(0, ${
|
|
855
|
+
frames: recent.slice().sort((a, b) => b - a).slice(0, ${e}),
|
|
856
856
|
}
|
|
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,
|
|
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,q]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)} ${q.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 e=a[2];if(!e||!["goHome","appSwitcher","lockScreen"].includes(e)){console.log(`
|
|
858
858
|
${b("perf")} transition <event> \u2014 profile a shell transition
|
|
859
859
|
|
|
860
860
|
events:
|
|
@@ -867,7 +867,7 @@ ${s}
|
|
|
867
867
|
examples:
|
|
868
868
|
${b("perf")} transition goHome --timeout 10000
|
|
869
869
|
${b("perf")} transition appSwitcher
|
|
870
|
-
`);break}let n=`sootsim:${
|
|
870
|
+
`);break}let n=`sootsim:${e}`;console.log(` profiling ${e} transition...`),console.log(" (use --timeout 10000 if this times out)");let r=await c.send({type:"evaluate",code:`(async () => {
|
|
871
871
|
// only supported in render-worker mode
|
|
872
872
|
if (!window.__sootsimRenderHost) {
|
|
873
873
|
return { error: 'transition profiling requires render-worker mode' }
|
|
@@ -905,7 +905,7 @@ ${s}
|
|
|
905
905
|
const otherTotal = otherTimes.reduce((a, b) => a + b, 0)
|
|
906
906
|
|
|
907
907
|
return {
|
|
908
|
-
event: '${
|
|
908
|
+
event: '${e}',
|
|
909
909
|
frames: frameTimes.length,
|
|
910
910
|
totalMs: total,
|
|
911
911
|
avgMs: avg,
|
|
@@ -926,7 +926,7 @@ ${s}
|
|
|
926
926
|
jankFrames: frameTimes.filter(f => f > 16.67).length,
|
|
927
927
|
samples,
|
|
928
928
|
}
|
|
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(` ${
|
|
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(` ${e} transition profiled:
|
|
930
930
|
|
|
931
931
|
frames: ${r.frames}
|
|
932
932
|
total: ${r.totalMs.toFixed(1)}ms
|
|
@@ -944,27 +944,27 @@ ${s}
|
|
|
944
944
|
p50: ${r.p50.toFixed(2)}ms
|
|
945
945
|
p95: ${r.p95.toFixed(2)}ms
|
|
946
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: ${
|
|
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: ${t}`),process.exit(1)}break}case"errors":{let t=a[1];if(t==="clear"){await Qe(c),D(l)?B({cleared:!0}):console.log(" error buffer cleared");break}let e=t?Number(t):20,s=await Xe(c,e);if(D(l)){B(s);break}if(s.length===0){console.log(" no errors captured");break}console.log(` ${s.length} error(s):
|
|
948
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
|
|
950
|
-
`);for(let s of
|
|
951
|
-
`);for(let
|
|
952
|
-
`);for(let u of r){let m=new Date(u.timestamp).toLocaleTimeString();console.log(` [${m}] ${
|
|
949
|
+
`).slice(0,3);for(let x of m)console.log(` ${x.trim()}`)}}break}case"warnings":{let t=a[1]?Number(a[1]):20,e=await Ve(c,t);if(D(l)){B(e);break}if(e.length===0){console.log(" no warnings captured");break}console.log(` ${e.length} warning(s):
|
|
950
|
+
`);for(let s of e){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 t=await z(c,"listAnimations")??[];if(o.includes("--json")){console.log(JSON.stringify(t,null,2));break}if(t.length===0){console.log(" no active animations");break}console.log(` ${t.length} active animation(s):
|
|
951
|
+
`);for(let e of t){let s=String(e.kind).padEnd(6),n=`${Number(e.from).toFixed(2)}\u2192${Number(e.to).toFixed(2)}`,r=Number(e.current??0).toFixed(2),u=`${Math.round((e.progress??0)*100)}%`,m=`${Math.round(e.elapsedMs??0)}ms`,x=e.loop?" loop":"",g=e.layoutBound?" layout":"";console.log(` #${e.id} ${s} ${n.padEnd(14)} cur=${r.padEnd(7)} ${u.padStart(4)} ${m}${x}${g}`)}break}case"animation":{let t=a[1];(!t||t==="--help"||t==="-h")&&(console.error(` usage: ${b("animation")} <id>`),process.exit(1));let e=Number(t);Number.isFinite(e)||(console.error(` invalid id: ${t}`),process.exit(1));let s=await z(c,"getAnimation",e);console.log(JSON.stringify(s,null,2));break}case"stop-animation":{let t=a[1];(!t||t==="--help"||t==="-h")&&(console.error(` usage: ${b("stop-animation")} <id|all>`),process.exit(1));let e=t==="all"?"all":Number(t);e!=="all"&&!Number.isFinite(e)&&(console.error(` invalid id: ${t}`),process.exit(1));let s=await z(c,"stopAnimation",e);console.log(` stopped ${s??0} animation(s)`);break}case"requests":{let t=a[1];if(t==="clear"){await et(c),D(l)?B({cleared:!0}):console.log(" request buffer cleared");break}let e=t==="all",s=e?a[2]:t,n=s?Number(s):20,r=await Ze(c,{failed:!e,limit:n});if(D(l)){B(r);break}if(r.length===0){console.log(e?" no requests captured":" no failed requests captured");break}console.log(` ${r.length} ${e?"request(s)":"failed request(s)"}:
|
|
952
|
+
`);for(let u of r){let m=new Date(u.timestamp).toLocaleTimeString();console.log(` [${m}] ${W(u)}`),u.responseBody?console.log(` ${u.responseBody}`):u.error&&console.log(` ${u.error}`)}break}case"network":{let t=a[1],e=null,s=null,n=!1,r=!1,u=1e3,m=!1,x=!1;for(let M=0;M<l.length;M++){let h=l[M];if(h==="--filter")e=l[M+1]??null,M++;else if(h==="--limit"){let p=Number(l[M+1]);Number.isFinite(p)&&(s=p),M++}else if(h==="--threshold"){let p=Number(l[M+1]);Number.isFinite(p)&&p>0&&(u=p),M++}else h==="--failed"?n=!0:h==="--slow"?r=!0:h==="--tail"||h==="-f"?m=!0:h==="--json"&&(x=!0)}if(t==="clear"){await c.send({type:"evaluate",code:'window.__sootsimObservability?.network.clear(); "cleared"'}),console.log(" network buffer cleared");break}if(t==="get"){let M=a[2];M||(console.error(" usage: sootsim network get <id>"),process.exit(1));let h=await c.send({type:"evaluate",code:`(() => {
|
|
953
953
|
const obs = window.__sootsimObservability;
|
|
954
954
|
if (!obs) return null;
|
|
955
|
-
return obs.network.getSnapshot().find(e => e.id === ${JSON.stringify(
|
|
956
|
-
})()`});h||(console.error(` no entry with id ${
|
|
957
|
-
to target a specific sim, use \`--sim ${
|
|
955
|
+
return obs.network.getSnapshot().find(e => e.id === ${JSON.stringify(M)}) || null;
|
|
956
|
+
})()`});h||(console.error(` no entry with id ${M}`),process.exit(1)),x?console.log(JSON.stringify(h,null,2)):co(h);break}let g=s??(m?200:t?Number(t):20);Number.isFinite(g)||(console.error(` invalid limit: ${t} \u2014 \`network\` takes a numeric count (e.g. ${b("network")} 100).
|
|
957
|
+
to target a specific sim, use \`--sim ${t}\` instead.`),process.exit(1));let $=async()=>{let M=await c.send({type:"evaluate",code:`(() => {
|
|
958
958
|
const obs = window.__sootsimObservability;
|
|
959
959
|
if (!obs) return { ok: false };
|
|
960
960
|
return { ok: true, entries: obs.network.getSnapshot() };
|
|
961
|
-
})()`});if(!
|
|
961
|
+
})()`});if(!M||!M.ok)throw new Error("observability bridge not installed \u2014 is the engine running?");return M.entries??[]},F=M=>{let h=M;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)),e){let p=e.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 M=await $(),h=F(M).slice(-g);if(x){console.log(JSON.stringify(h,null,2));break}if(h.length===0){M.length===0?console.log(" no network requests captured"):console.log(r?` no requests slower than ${u}ms (${M.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):
|
|
962
962
|
`:` ${h.length} request(s):
|
|
963
|
-
`);for(let p of h)
|
|
964
|
-
`);let
|
|
965
|
-
to target a specific sim, use \`--sim ${
|
|
966
|
-
`);for(let O of p)
|
|
967
|
-
`);let H=new Set,U=!0,
|
|
963
|
+
`);for(let p of h)Pt(p);break}console.log(` tailing network (ctrl-c to stop)...
|
|
964
|
+
`);let q=new Set,H=!0,U=()=>{H=!1};process.on("SIGINT",U);try{for(;H;){let M=await $(),h=F(M);for(let p of h)p.durationMs!=null&&(q.has(p.id)||(q.add(p.id),x?console.log(JSON.stringify(p)):Pt(p)));await X(250)}}finally{process.off("SIGINT",U)}break}case"logs":{let t=a[1],e=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")e=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(t==="clear"){await ot(c),console.log(" log buffer cleared");break}let g=!u&&process.stdout.isTTY===!0,$=s??(r?500:t?Number(t):50);Number.isFinite($)||(console.error(` invalid limit: ${t} \u2014 \`logs\` takes a numeric count (e.g. ${b("logs")} 100).
|
|
965
|
+
to target a specific sim, use \`--sim ${t}\` instead.`),process.exit(1));let F=()=>tt(c),q=h=>st(h,{level:x,filter:e,showInternal:m});if(!r){let h=await F(),p=q(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)Rt(O,g);break}console.log(` tailing logs (ctrl-c to stop)...
|
|
967
|
+
`);let H=new Set,U=!0,M=()=>{U=!1};process.on("SIGINT",M);try{for(;U;){let h=await F(),p=q(h);for(let O of p)H.has(O.id)||(H.add(O.id),u?console.log(JSON.stringify(O)):Rt(O,g));await X(250)}}finally{process.off("SIGINT",M)}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 w(c),!j.has(y)&&!D(l))try{await oe(c)}catch{}}catch(t){let e=t instanceof Error?t.message:String(t);console.error(` ${y??"inspect"} failed: ${e}`);let s=/^no sim connected with id (.+)$/.exec(e),n=/^command timed out after \d+s$/.test(e)||e.startsWith("sim disconnected:")||e.startsWith("bridge never reconnected")||e.startsWith("could not connect to ws://");if(s)await dt(c,_,s[1]);else if(/^no sim connected$/.test(e))ct(_);else if(n)process.stderr.write(` the sim is not responding. recover it with:
|
|
968
968
|
sootsim close --sim <id> # force-close the wedged sim
|
|
969
969
|
sootsim list # confirm it's gone
|
|
970
|
-
`);else{try{await
|
|
970
|
+
`);else{try{await je(c)}catch{}try{await P({includeTail:!0})}catch{}try{await Z({includeTail:!0})}catch{}}process.exit(1)}finally{c.close()}}export{Vs as runInspect};
|