sootsim 0.1.59 → 0.1.60
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-GD3Q5RPA.js → agent-3QM476OM.js} +2 -2
- package/dist-cli/chunks/{agent-wrapper-LBIAKQGM.js → agent-wrapper-ZGA3WMEQ.js} +2 -2
- package/dist-cli/chunks/{assert-LZUX5QVA.js → assert-7LOZ3UZU.js} +2 -2
- package/dist-cli/chunks/auto-bootstrap-5SEVYWHQ.js +2 -0
- package/dist-cli/chunks/beta-WS6QLCUE.js +2 -0
- package/dist-cli/chunks/{chunk-D6O2NXGB.js → chunk-2367OT3T.js} +2 -2
- package/dist-cli/chunks/{chunk-4VNKLERI.js → chunk-2X5KYBDL.js} +2 -2
- package/dist-cli/chunks/{chunk-PSPZTTCO.js → chunk-32X2Q5FN.js} +2 -2
- package/dist-cli/chunks/chunk-4LRESDDC.js +11 -0
- package/dist-cli/chunks/{chunk-D26QPCEP.js → chunk-4V7H5CSS.js} +2 -2
- package/dist-cli/chunks/{chunk-5RLJWEFW.js → chunk-7K3CWKDO.js} +1 -1
- package/dist-cli/chunks/{chunk-XDIT5SEC.js → chunk-A33UZUKE.js} +2 -2
- package/dist-cli/chunks/{chunk-HMPHDE5A.js → chunk-ARKBI7JL.js} +1 -1
- package/dist-cli/chunks/{chunk-4ENZNH7P.js → chunk-BOVJRVYZ.js} +2 -2
- package/dist-cli/chunks/{chunk-LLOURJ3N.js → chunk-BXZN6LGB.js} +3 -3
- package/dist-cli/chunks/chunk-C6YD4Y7P.js +1 -0
- package/dist-cli/chunks/{chunk-YT54ZKTQ.js → chunk-DMLDEQSS.js} +2 -2
- package/dist-cli/chunks/{chunk-NGEPSXEE.js → chunk-EJYB47BH.js} +9 -4
- package/dist-cli/chunks/{chunk-AMEUPM6D.js → chunk-FVH44DUL.js} +1 -1
- package/dist-cli/chunks/{chunk-Y65GFG22.js → chunk-GZQHWPLT.js} +3 -3
- package/dist-cli/chunks/chunk-HJEHZSNV.js +92 -0
- package/dist-cli/chunks/{chunk-KYP5XLIR.js → chunk-I7FBCRYN.js} +2 -2
- package/dist-cli/chunks/{chunk-F2DSLYX4.js → chunk-IDNLH47C.js} +1 -1
- package/dist-cli/chunks/chunk-IKICAURU.js +1 -0
- package/dist-cli/chunks/{chunk-V4SMVFRV.js → chunk-LKHZHA2M.js} +1 -1
- package/dist-cli/chunks/{chunk-XM4D43UP.js → chunk-LO7IVLWX.js} +2 -2
- package/dist-cli/chunks/{chunk-A3ATSCOF.js → chunk-LYEPRAQA.js} +2 -2
- package/dist-cli/chunks/{chunk-WQOEMVXN.js → chunk-N7VXONQG.js} +1 -1
- package/dist-cli/chunks/{chunk-TYRPY3SN.js → chunk-NH6WDZCD.js} +1 -1
- package/dist-cli/chunks/{chunk-V6NAG62D.js → chunk-NRYQ2JZJ.js} +1 -1
- package/dist-cli/chunks/{chunk-5S62LOV4.js → chunk-OXLLV636.js} +2 -2
- package/dist-cli/chunks/{chunk-4L72FYCQ.js → chunk-PDC6SIIZ.js} +1 -1
- package/dist-cli/chunks/{chunk-WQXLD5YU.js → chunk-PIV6WQG4.js} +2 -2
- package/dist-cli/chunks/{chunk-O4I44BRL.js → chunk-QJBS67HI.js} +1 -1
- package/dist-cli/chunks/{chunk-BL3IZLNB.js → chunk-QOWJXECZ.js} +2 -2
- package/dist-cli/chunks/{chunk-IY3JNNU7.js → chunk-RDCLJUAL.js} +2 -2
- package/dist-cli/chunks/{chunk-ZLMNBI7T.js → chunk-RFSQAGQM.js} +2 -2
- package/dist-cli/chunks/{chunk-WMTMNKH2.js → chunk-S4LMLA46.js} +2 -2
- package/dist-cli/chunks/{chunk-XRMTMRS5.js → chunk-S75CWUM2.js} +1 -1
- package/dist-cli/chunks/{chunk-ZX66GIXV.js → chunk-TNN7OYGT.js} +2 -2
- package/dist-cli/chunks/chunk-UW4IDGIR.js +2 -0
- package/dist-cli/chunks/{chunk-G3A23B5Q.js → chunk-VTLZR3XL.js} +1 -1
- package/dist-cli/chunks/chunk-W7X3YMV3.js +1 -0
- package/dist-cli/chunks/{chunk-5DO55JWB.js → chunk-WY7EM456.js} +27 -27
- package/dist-cli/chunks/{chunk-PS57ERTY.js → chunk-XNZIAKU5.js} +2 -2
- package/dist-cli/chunks/chunk-YKLWG4AA.js +119 -0
- package/dist-cli/chunks/chunk-YN2754CX.js +2 -0
- package/dist-cli/chunks/{chunk-24VAZEFY.js → chunk-YQT3TRJ5.js} +2 -2
- package/dist-cli/chunks/cli-version-ARDD24DZ.js +2 -0
- package/dist-cli/chunks/{compat-77WWLIGJ.js → compat-4TESUCFM.js} +3 -3
- package/dist-cli/chunks/{config-WGPGLVTW.js → config-GKXIKKRU.js} +2 -2
- package/dist-cli/chunks/control-NKGES73S.js +2 -0
- package/dist-cli/chunks/{cpu-profile-XMBVCI7K.js → cpu-profile-2F4C2O7S.js} +2 -2
- package/dist-cli/chunks/{daemon-FFHD2I32.js → daemon-FMZ7MNVI.js} +2 -2
- package/dist-cli/chunks/{debug-FMXTU6TB.js → debug-IJCU56E5.js} +3 -3
- package/dist-cli/chunks/demo-app-registry-B2GQWZAE.js +2 -0
- package/dist-cli/chunks/{detox-QGFGC5RT.js → detox-5UFOIOLZ.js} +2 -2
- package/dist-cli/chunks/{device-OL7VGMK7.js → device-AE6AZUWE.js} +2 -2
- package/dist-cli/chunks/{diagnose-6CSSFWBQ.js → diagnose-FE27W2WT.js} +2 -2
- package/dist-cli/chunks/drivers-EQGVLU5S.js +2 -0
- package/dist-cli/chunks/{electron-MHXT6NTC.js → electron-FFIZI3WU.js} +3 -3
- package/dist-cli/chunks/flow-DKRIB4D4.js +2 -0
- package/dist-cli/chunks/{hints-W5DK2COL.js → hints-AVO3XSF2.js} +2 -2
- package/dist-cli/chunks/{home-paths-RWCQ7AU2.js → home-paths-XCSL4IZG.js} +2 -2
- package/dist-cli/chunks/{inspect-5XMF34Y7.js → inspect-SEWOLKW2.js} +130 -108
- package/dist-cli/chunks/install-5SPPQPBO.js +2 -0
- package/dist-cli/chunks/{install-desktop-YVHWBC3T.js → install-desktop-ZVPLNWWN.js} +3 -3
- package/dist-cli/chunks/{keys-6HAEB4IC.js → keys-2ANCWIJR.js} +2 -2
- package/dist-cli/chunks/{launch-OHCK4MRM.js → launch-QBCI6F33.js} +3 -3
- package/dist-cli/chunks/{login-VBHIW5ZN.js → login-MPEC3IQC.js} +4 -4
- package/dist-cli/chunks/{logout-LHFYJFHT.js → logout-FHKV7PVB.js} +2 -2
- package/dist-cli/chunks/{maestro-56F3HFUH.js → maestro-HEPFHHZM.js} +2 -2
- package/dist-cli/chunks/{preview-ATGWKYQI.js → preview-SAM2AO6M.js} +2 -2
- package/dist-cli/chunks/{profile-UII6DPNJ.js → profile-CW3WET2M.js} +2 -2
- package/dist-cli/chunks/{react-4F2HFSY7.js → react-LFKI73YH.js} +2 -2
- package/dist-cli/chunks/record-CM3G44PK.js +45 -0
- package/dist-cli/chunks/runtime-JUMLSSWP.js +2 -0
- package/dist-cli/chunks/{runtime-delivery-CUCNWWQP.js → runtime-delivery-MSETJQQ6.js} +2 -2
- package/dist-cli/chunks/{screenshot-GKJ4ICW4.js → screenshot-D77TOEEP.js} +2 -2
- package/dist-cli/chunks/{screenshot-mode-OCP4HA3H.js → screenshot-mode-2YPUHGUB.js} +2 -2
- package/dist-cli/chunks/{screenshots-RTRJF63K.js → screenshots-RKWVNLEI.js} +2 -2
- package/dist-cli/chunks/{server-SY6BQAVD.js → server-GDOHSZQ3.js} +3 -3
- package/dist-cli/chunks/setup-repo-GGNBHKN6.js +2 -0
- package/dist-cli/chunks/{skills-KX3LI7Y6.js → skills-2KROZMJJ.js} +2 -2
- package/dist-cli/chunks/{start-5IOHCWG6.js → start-RTIULO26.js} +4 -4
- package/dist-cli/chunks/store-XAQEN3N3.js +2 -0
- package/dist-cli/chunks/telemetry-GIZM7C4U.js +2 -0
- package/dist-cli/chunks/{test-2QTF7GWW.js → test-WIBWT3SJ.js} +3 -3
- package/dist-cli/chunks/{three-mode-EQSSYVHT.js → three-mode-XMBKE6NN.js} +2 -2
- package/dist-cli/chunks/{timeline-GZZYRE2U.js → timeline-3RHZIXQV.js} +2 -2
- package/dist-cli/chunks/{upgrade-KVJ2HKRH.js → upgrade-MLQ3YZEU.js} +2 -2
- package/dist-cli/chunks/upload-K36QDGWB.js +2 -0
- package/dist-cli/chunks/{web-2C5AJBCN.js → web-6SI6NZ22.js} +2 -2
- package/dist-cli/chunks/{what-happened-YECRPXV5.js → what-happened-FK6I5XEC.js} +2 -2
- package/dist-cli/chunks/{whoami-WCPVDNPA.js → whoami-ZVUQ4ICS.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 +2 -2
- package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
- package/dist-lib/host/fetch-proxy-overrides.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 +2 -2
- package/dist-lib/vite.cjs +1 -1
- package/package.json +1 -1
- package/dist-cli/chunks/auto-bootstrap-RGEU3N4Y.js +0 -2
- package/dist-cli/chunks/beta-7YMPFJF7.js +0 -2
- package/dist-cli/chunks/chunk-DFXUPNYD.js +0 -119
- package/dist-cli/chunks/chunk-GL3JT3P7.js +0 -1
- package/dist-cli/chunks/chunk-L5PBH3V6.js +0 -1
- package/dist-cli/chunks/chunk-N7OHTYFK.js +0 -2
- package/dist-cli/chunks/chunk-O2W7EB7L.js +0 -11
- package/dist-cli/chunks/chunk-QNH7IX5F.js +0 -59
- package/dist-cli/chunks/chunk-UPW76NDZ.js +0 -2
- package/dist-cli/chunks/chunk-ZEB4DGC6.js +0 -1
- package/dist-cli/chunks/cli-version-CL32HHD6.js +0 -2
- package/dist-cli/chunks/control-KZYO5BDN.js +0 -2
- package/dist-cli/chunks/demo-app-registry-RSAPXLUE.js +0 -2
- package/dist-cli/chunks/drivers-7PFWCFVQ.js +0 -2
- package/dist-cli/chunks/flow-HMBOPMQV.js +0 -2
- package/dist-cli/chunks/install-3MNX7DSK.js +0 -2
- package/dist-cli/chunks/record-YHRJJJRY.js +0 -41
- package/dist-cli/chunks/runtime-HOPZF7H6.js +0 -2
- package/dist-cli/chunks/setup-repo-Z7WKSSP5.js +0 -2
- package/dist-cli/chunks/store-WYV5UMFH.js +0 -2
- package/dist-cli/chunks/telemetry-XABHSL5O.js +0 -2
- package/dist-cli/chunks/upload-4VWBZXY4.js +0 -2
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
2
|
-
import{a as G}from"./chunk-
|
|
3
|
-
`)}function no(
|
|
4
|
-
`).length>=80&&G("describe-use-filters"),
|
|
1
|
+
/*! sootsim v0.1.60 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
|
+
import{a as G}from"./chunk-RFSQAGQM.js";import{a as Le,b as Je}from"./chunk-IDNLH47C.js";import{a as X,b as C,c as B,d as z,e as de,f as re,g as at,h as lt,i as ke}from"./chunk-A33UZUKE.js";import{a as Be,g as ce}from"./chunk-QOWJXECZ.js";import{b as ct,c as dt,i as ut}from"./chunk-4LRESDDC.js";import"./chunk-S4LMLA46.js";import{a as je}from"./chunk-QJBS67HI.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-EJYB47BH.js";import"./chunk-TNN7OYGT.js";import"./chunk-HJEHZSNV.js";import"./chunk-7K3CWKDO.js";import"./chunk-C6YD4Y7P.js";import"./chunk-2367OT3T.js";import"./chunk-VTLZR3XL.js";import{a as we,c as xe,d as Oe}from"./chunk-YKLWG4AA.js";import{a as Ae}from"./chunk-UW4IDGIR.js";import{c as Re,e as Ee,f as De,g as Ce,h as $e}from"./chunk-I7FBCRYN.js";import{b as Pe}from"./chunk-PDC6SIIZ.js";import"./chunk-YN2754CX.js";import"./chunk-NRYQ2JZJ.js";import"./chunk-FVH44DUL.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(s,d){return Object.fromEntries(Object.entries(s).filter(([,i])=>typeof i?.signature=="string"&&Number.isFinite(i?.updatedAt)&&d-i.updatedAt<=Zt))}function oo(s){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,s)}}catch{return mt(d,{force:!0}),{version:ie,entries:{}}}}function so(s){let d=pt();Ut(Gt(d),{recursive:!0}),zt(d,JSON.stringify(s,null,2)+`
|
|
3
|
+
`)}function no(s,d){let i=d.trim()||"default";return`${s}:${i}`}function Te(s,d,i,l={}){let f=l.nowMs??Date.now(),a=l.cooldownMs??eo,y=oo(f),S=no(s,d),T=y.entries[S];return T&&T.signature===i&&f-T.updatedAt<a?!1:(y.entries[S]={signature:i,updatedAt:f},so(y),!0)}async function ft(s,d={args:[]}){let i=await We(s);if(C(d.args)){B(i);return}console.log(` nodes: ${i.nodes}`)}function Me(s,d){let i=s.indexOf(d);return i>=0&&i+1<s.length?s[i+1]:null}async function gt(s){let{bridge:d,args:i,positional:l}=s,f=i.includes("--verbose")||i.includes("-v"),a=C(i),y=f&&!a,S=i.includes("--watch")||i.includes("-w"),T=1e3,k=i.includes("--compact"),h=i.includes("--no-xy"),v=Me(i,"--testid-like"),N=Me(i,"--only"),M=Me(i,"--subtree"),E=l[1],J=E?/[*?]/.test(E):!1,c=!J&&!N?E:void 0,K=N??(J?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:M||void 0,compact:k,hideXy:h}),W=Y?.tree,x=Y?.shell,_=Y?.keyboard;if(a){B({shell:x,tree:W??"",keyboard:_});return}if(x&&typeof x=="object"){let O=[x.state?`state=${x.state}`:null,x.activeApp?`app=${x.activeApp}`:null,x.showSwitcher?"switcher":null,x.switcherPhase&&x.switcherPhase!=="idle"?`phase=${x.switcherPhase}`:null].filter(Boolean);O.length>0&&console.log(` shell: ${O.join(" ")}`)}if(typeof W=="string"&&W.startsWith("__SUBTREE_NOT_FOUND__:")){let O=W.slice(22);console.log(` subtree root not found: ${O}`),G("subtree-root-not-found",O);return}if(!W){let O=Y?.nodeCount??0;console.log(" no matching nodes found"),!(c||v||K||M)&&O<10&&G("app-still-loading",O);return}if(console.log(W),!(c||v||K||M)&&!S&&W.split(`
|
|
4
|
+
`).length>=80&&G("describe-use-filters"),_&&_.visible){let O=_.spec,V=[O?.keyboardType?`type=${O.keyboardType}`:null,O?.returnKeyType&&O.returnKeyType!=="default"?`return=${O.returnKeyType}`:null,_.mode!=="letters"?`mode=${_.mode}`:null,_.shifted?"shift":null,_.capsLock?"caps":null,O?.autoCapitalize&&O.autoCapitalize!=="sentences"?`autoCap=${O.autoCapitalize}`:null,_.accessoryBarId?`accessory=${_.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 j(),await X(
|
|
6
|
+
`);;)console.clear(),await j(),await X(T);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 s of ro){let d=process.env[s];if(d&&d.trim()&&d!=="0")return!0}return!1}async function ht(s){let{bridge:d,args:i,effectiveArgs:l,positional:f,inspectUsage:a}=s,y=x=>{let _=l.indexOf(x);return _>=0&&_+1<l.length?l[_+1]:null},S=x=>l.includes(x),T=y("--testid")||y("--test-id"),k=y("--role"),h=y("--type"),v=y("--text"),N=S("--pressable"),M=S("--visible"),E=S("--interactive-targets")||S("--actions"),J=!T&&!k&&!h&&!v&&!N&&!M&&!E?f[1]:null,c=v??J,K=await ze(d,{testId:T,role:k,type:h,text:c,pressable:N,visible:M,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:D}=K,Y=C(i),W=i.includes("--verbose")||i.includes("--dump");if(Y)j==="interactive-targets"&&Array.isArray(D)?B(Se(D).map(x=>({...x,tap:ve(x)}))):B(D??null);else if(Array.isArray(D))if(D.length===0){console.log(` no ${j} nodes found`);let x=await d.send({type:"evaluate",code:"(async () => (await window.__sootsimTest?.getNodeCount?.()) || 0)()"});typeof x=="number"&&x<10&&G("app-still-loading",x)}else if(j==="interactive-targets"){let x=Se(D);console.log(` found ${x.length} interactive target${x.length===1?"":"s"} (sorted by score):`);for(let _ of x.slice(0,20)){let Z=_.absolutePosition?`@(${Math.round(_.absolutePosition.x)},${Math.round(_.absolutePosition.y)})`:"",O=_.layout?`${Math.round(_.layout.width)}x${Math.round(_.layout.height)}`:"?x?",V=_.text?` "${_.text.slice(0,30)}"`:"",oe=_.testID?` #${_.testID}`:"",ee=_.accessibilityLabel?` \u24D8"${String(_.accessibilityLabel).slice(0,24)}"`:"",ye=_.accessibilityRole?`[${_.accessibilityRole}]`:_.type,he=ve(_);console.log(` ${ye}${V}${ee}${oe} ${O} ${Z}`),console.log(` \u2192 ${he}`),W&&console.log(Ie(JSON.stringify(_,null,2)," "))}x.length>20&&console.log(` ... and ${x.length-20} more`)}else{console.log(` found ${D.length} node${D.length===1?"":"s"} (${j}):`);for(let x of D.slice(0,20)){let _=x.absolutePosition?`@(${Math.round(x.absolutePosition.x)},${Math.round(x.absolutePosition.y)})`:"",Z=x.layout?`${Math.round(x.layout.width)}x${Math.round(x.layout.height)}`:"?x?",O=x.text?` "${x.text.slice(0,30)}"`:"",V=x.testID?` #${x.testID}`:"",oe=x.pressable?" (tap)":"",ee=x.accessibilityRole?`[${x.accessibilityRole}]`:x.type;console.log(` ${ee}${O}${V} ${Z} ${_}${oe}`),W&&console.log(Ie(JSON.stringify(x,null,2)," "))}D.length>20&&console.log(` ... and ${D.length-20} more`)}else if(D==null)console.log(` not found: ${c||T||k||h||""||j}`),T&&G("wait-selector-for-missing-testid",T);else{let x=D;if(x.type&&x.absolutePosition){let _=`@(${Math.round(x.absolutePosition.x)},${Math.round(x.absolutePosition.y)})`,Z=x.layout?`${Math.round(x.layout.width)}x${Math.round(x.layout.height)}`:"?x?",O=x.text?` "${x.text.slice(0,40)}"`:"",V=x.testID?` #${x.testID}`:"",oe=x.pressable?" (tap)":"",ee=x.accessibilityRole?`[${x.accessibilityRole}]`:x.type;console.log(` ${ee}${O}${V} ${Z} ${_}${oe}`),W&&console.log(Ie(JSON.stringify(x,null,2)," "))}else console.log(JSON.stringify(D,null,2))}}function Ie(s,d){return s.split(`
|
|
7
7
|
`).map(i=>d+i).join(`
|
|
8
|
-
`)}async function bt(
|
|
9
|
-
`))}async function wt(
|
|
8
|
+
`)}async function bt(s,d={}){let i=await nt(s);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:T}=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)":""}`),T&&k.push(` accessoryBar: ${T}`),console.log(k.join(`
|
|
9
|
+
`))}async function wt(s){let d=await s.bridge.listSims();if(C(s.args)){B(d.map(i=>({...i,active:i.id===s.simId})));return}ut(d,s.simId)}function te(s){return s<1024?`${s}B`:s<1024*1024?`${(s/1024).toFixed(1)}KB`:`${(s/1024/1024).toFixed(1)}MB`}function ue(s,d){return d<=0?"?":`${(s/d*100).toFixed(0)}%`}async function xt(s,d={args:[]}){let i=await it(s);if(C(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(s){let d=s.indexOf("--testid");if(d>=0&&s[d+1])return{mode:"testid",value:s[d+1]};let i=s.indexOf("--test-id");if(i>=0&&s[i+1])return{mode:"testid",value:s[i+1]};let l=s.indexOf("--text");return l>=0&&s[l+1]?{mode:"text",value:s[l+1]}:null}async function me(s,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 s.send({type:"evaluate",code:`(async () => {
|
|
10
10
|
const t = window.__sootsimTest
|
|
11
11
|
if (!t) return null
|
|
12
12
|
const n = ${l}
|
|
@@ -23,9 +23,16 @@ import{a as G}from"./chunk-ZLMNBI7T.js";import{a as Je,b as Le}from"./chunk-F2DS
|
|
|
23
23
|
typeof resolved?.cy === 'number'
|
|
24
24
|
? resolved.cy
|
|
25
25
|
: n.absolutePosition.y + (n.layout.height || 0) / 2
|
|
26
|
-
return {
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
return {
|
|
27
|
+
x: cx,
|
|
28
|
+
y: cy,
|
|
29
|
+
id: n.id ?? null,
|
|
30
|
+
testID: n.testID ?? null,
|
|
31
|
+
text: ${JSON.stringify(d.mode==="text")} ? ${i} : (n.text ?? n.accessibilityLabel ?? null),
|
|
32
|
+
type: n.type ?? null,
|
|
33
|
+
}
|
|
34
|
+
})()`})??null}async function $t(s,d={}){let{nav:i,keyboard:l,shell:f}=await rt(s);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)":"",T=typeof f.launchProgress=="number"&&f.launchProgress<.98?` launching (${Math.round(f.launchProgress*100)}%)`:"";a.push(`shell: ${y}${S}${T}`)}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 T=S.isActive?"\u25B6":" ",k=S.routeName?` ${S.routeName}`:"",h=S.headerHeight>0?` header=${S.headerHeight}`:"",v=S.largeTitleState&&S.largeTitleState!=="expanded"?` large-title=${S.largeTitleState}`:"";a.push(` ${T} #${S.id}${k}${h}${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(`
|
|
35
|
+
`))}async function ne({bridge:s,maxMs:d,pollMs:i=50,stablePolls:l=3,strict:f=!1}){let a=await s.send({type:"evaluate",code:`(async () => {
|
|
29
36
|
const start = Date.now()
|
|
30
37
|
const deadline = start + ${Math.max(0,Math.round(d))}
|
|
31
38
|
const pollMs = ${Math.max(1,Math.round(i))}
|
|
@@ -74,12 +81,12 @@ import{a as G}from"./chunk-ZLMNBI7T.js";import{a as Je,b as Le}from"./chunk-F2DS
|
|
|
74
81
|
await sleep(pollMs)
|
|
75
82
|
}
|
|
76
83
|
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 St(
|
|
84
|
+
})()`}),{elapsed:y,settled:S}=a??{};return{elapsed:typeof y=="number"?y:d,settled:S===!0}}async function St(s){let{bridge:d,args:i,positional:l}=s,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(s){let d=s.positional[1]?Number(s.positional[1]):.5;(!Number.isFinite(d)||d<0)&&(console.error(s.inspectUsage("sleep","[seconds]")),process.exit(1)),await X(d*1e3),console.log(` slept ${d}s`)}async function kt(s){let{bridge:d,args:i,positional:l}=s,f=l[1]?Number(l[1]):5,{tree:a}=await qe(d,f);if(C(i)){B({depth:f,tree:a??null});return}console.log(typeof a=="string"?a:JSON.stringify(a,null,2))}async function Tt(s,d={args:[]}){let i=await He(s);if(C(d.args)){B(i);return}console.log(i.url)}async function Mt(s){let{wsPort:d,commandTimeoutMs:i,simId:l,simIdSource:f,positional:a}=s,y=a[1]?Number(a[1]):30,S=Math.max(1e3,(Number.isFinite(y)?y:30)*1e3),T=Math.max(1,Math.ceil(S/500));console.log(" waiting for sim reconnect...");let k=await at(d,i,l,{attempts:T,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(s,d){let i=s.indexOf(d);if(i>=0&&i+1<s.length)return s[i+1]}function io(s,d){if(!d.filter&&!d.equals)return!0;let i=s.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(s){let{bridge:d,args:i,positional:l,inspectUsage:f}=s,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,T=pe(i,"--filter"),k=pe(i,"--equals"),h=pe(i,"--since")??"now",v=i.includes("--json"),N=Date.now(),M=N+S,E=200,J=N;for(;Date.now()<M;){let K={kinds:[a],since:h==="cursor"?void 0:J,limit:50},j=await d.send({type:"evaluate",code:`(async () => {
|
|
78
85
|
const t = window.SootSim?.bridges?.timeline
|
|
79
86
|
if (!t) return { ok: false, error: 'timeline bridge missing' }
|
|
80
87
|
return { ok: true, result: await t.recent(${JSON.stringify(K)}) }
|
|
81
|
-
})()`});(!j||!j.ok)&&(console.error(` could not query timeline: ${j&&"error"in j?j.error:"unknown"}`),process.exit(1));let
|
|
82
|
-
`).slice(0,5);for(let y of a)console.log(` ${y.trim()}`)}}var Q="__sootsimCliPerf",po=120;async function Et(
|
|
88
|
+
})()`});(!j||!j.ok)&&(console.error(` could not query timeline: ${j&&"error"in j?j.error:"unknown"}`),process.exit(1));let D=j.result.events??[];for(let Y of D)if(io(Y,{filter:T,equals:k})){let W=Date.now()-N;console.log(v?JSON.stringify({found:!0,elapsedMs:W,event:Y}):` ${a} event after ${W}ms${T?` (filter: ${T})`:""}${k?` (equals: ${k})`:""}`);return}j.result.watermark&&j.result.watermark>J&&(J=j.result.watermark),await new Promise(Y=>setTimeout(Y,E))}let c=Date.now()-N;v?console.log(JSON.stringify({found:!1,elapsedMs:c,kind:a,filter:T,equals:k})):console.error(` \u26A0 wait event ${a} timed out after ${c}ms${T?` (filter: ${T})`:""}${k?` (equals: ${k})`:""}`),process.exit(1)}async function _t(s){let{bridge:d,args:i}=s,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(s){let{bridge:d,args:i}=s,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,targets:T,flag:k,loadingText:h,errors:v}=await Ye(d,l);if(a){console.log(` ready in ${y}ms: ${S} nodes, ${T} targets`);return}let N=h?`still showing "${h}"`:k!==!0?"guest app has not emitted sootsim:externalAppReady":T<=0?"ready flag emitted but no visible app content is inspectable yet":"node tree is still changing";console.error(` \u26A0 wait ready timed out after ${y}ms \u2014 ${N} (nodes: ${S}, targets: ${T}, errors: ${v})`),process.exit(1)}async function At(s){let{bridge:d,args:i,positional:l,inspectUsage:f}=s,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:T,node:k,elapsed:h}=await Ge(d,a,S);if(T&&k){let v=k.absolutePosition?`@(${Math.round(k.absolutePosition.x)},${Math.round(k.absolutePosition.y)})`:"",N=k.layout?`${Math.round(k.layout.width)}x${Math.round(k.layout.height)}`:"?x?";console.log(` found #${a} in ${h}ms ${N} ${v}`)}else console.error(` \u26A0 wait selector #${a} timed out after ${h??S}ms`),process.exit(1)}function Ct(s){return s==null?"\u2014":s<1024?`${s}B`:s<1024*1024?`${(s/1024).toFixed(1)}K`:`${(s/1024/1024).toFixed(1)}M`}function Bt(s){return s==null?" \u2026":s<1e3?`${s}ms`.padStart(5):`${(s/1e3).toFixed(2)}s`.padStart(5)}function lo(s){return s.error?"err":s.status==null?" \u2026 ":String(s.status)}function Ot(s){let d=new Date(s.startTs).toLocaleTimeString(),i=lo(s).padEnd(3),l=s.method.padEnd(5),f=Ct(s.size).padStart(6),a=Bt(s.durationMs);console.log(` [${d}] ${i} ${l} ${f} ${a} ${s.displayUrl}`),s.error&&console.log(` error: ${s.error}`)}function co(s){let d=[["id",s.id],["source",s.source],["kind",s.kind],["method",s.method],["status",s.error?`error: ${s.error}`:`${s.status??"\u2014"} ${s.statusText??""}`.trim()],["url",s.url],["started",new Date(s.startTs).toLocaleTimeString()],["duration",Bt(s.durationMs).trim()],["size",Ct(s.size)],["content-type",s.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"},Pt="\x1B[0m",mo="\x1B[2m";function Rt(s,d){let i=new Date(s.ts).toLocaleTimeString(),l=s.level.toUpperCase().padEnd(5),f=s.args.join(" ");if(d){let a=uo[s.level];console.log(` ${mo}[${i}]${Pt} ${a}${l}${Pt} ${f}`)}else console.log(` [${i}] ${l} ${f}`);if(s.stack&&s.level==="error"){let a=s.stack.split(`
|
|
89
|
+
`).slice(0,5);for(let y of a)console.log(` ${y.trim()}`)}}var Q="__sootsimCliPerf",po=120;async function Et(s,d){let i=s.find((N,M)=>s[M-1]==="--id"),l=s.find((N,M)=>s[M-1]==="--text");if(i||l){let N=await d.send({type:"evaluate",code:Le({id:i,text:l})});if(!N)throw new Error(i?`no node with id "${i}"`:`no node matching text "${l}"`);let{x:M,y:E,w:J,h:c}=N;return{x:M,y:E,w:J,h:c}}let f=s.find((N,M)=>s[M-1]==="--area");if(f){let N=f.split(",").map(K=>Number(K.trim()));if(N.length!==4||N.some(K=>!Number.isFinite(K)))throw new Error(`--area expects x,y,w,h (got "${f}")`);let[M,E,J,c]=N;return{x:M,y:E,w:J,h:c}}let a=N=>{let M=s.find((J,c)=>s[c-1]===N);if(M==null)return null;let E=Number(M);return Number.isFinite(E)?E:null},y=a("--x"),S=a("--y"),T=a("--w"),k=a("--h");if(y!=null||S!=null||T!=null||k!=null)return{x:y??0,y:S??0,w:T??1,h:k??1};let v=s.filter((N,M)=>M>0&&!N.startsWith("-")&&s[M-1]!=="--output"&&s[M-1]!=="--area"&&s[M-1]!=="--id"&&s[M-1]!=="--text"&&s[M-1]!=="--x"&&s[M-1]!=="--y"&&s[M-1]!=="--w"&&s[M-1]!=="--h").map(Number).filter(N=>Number.isFinite(N));if(v.length>=2){let[N,M,E=1,J=1]=v;return{x:N,y:M,w:E,h:J}}return null}function Ne(s){let d={"<8":0,"8-12":0,"12-16":0,"16-20":0,"20-33":0,">33":0};for(let i of s)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/s.length*40));console.log(` ${i.padEnd(6)} ${f} ${l}`)}}async function fe(s,d,i){let l=Date.now()+d,f=await se(s,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(s)}}async function Fe(s){return s.send({type:"evaluate",code:`(async () => {
|
|
83
90
|
const kb = window.__sootsimKeyboard
|
|
84
91
|
const test = window.__sootsimTest
|
|
85
92
|
if (!kb) return { error: 'keyboard bridge not available' }
|
|
@@ -111,7 +118,7 @@ import{a as G}from"./chunk-ZLMNBI7T.js";import{a as Je,b as Le}from"./chunk-F2DS
|
|
|
111
118
|
frame: runtimeSnapshot?.keyboard?.frame ?? null,
|
|
112
119
|
focusedRect: runtimeSnapshot?.focused?.rect ?? null,
|
|
113
120
|
}
|
|
114
|
-
})()`})}async function fo(
|
|
121
|
+
})()`})}async function fo(s,d=600){let i=Date.now()+d;for(;Date.now()<=i;){let l=await Fe(s);if(l.visible)return l;await X(30)}return Fe(s)}async function ge(s,d){let i=await Fe(s);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 Dt(s,d,i){return d==="appearance"?s.send({type:"evaluate",code:`(async () => {
|
|
115
122
|
const requested = ${JSON.stringify(i??"toggle")}
|
|
116
123
|
const rootBg = (document.documentElement?.style?.background || '').toLowerCase()
|
|
117
124
|
const inferredCurrent = rootBg.includes('33') ? 'dark' : 'light'
|
|
@@ -125,28 +132,28 @@ import{a as G}from"./chunk-ZLMNBI7T.js";import{a as Je,b as Le}from"./chunk-F2DS
|
|
|
125
132
|
? (window.matchMedia?.('(prefers-color-scheme: dark)')?.matches ? 'dark' : 'light')
|
|
126
133
|
: next
|
|
127
134
|
return { ok: true, requested, value: next, applied }
|
|
128
|
-
})()`}):
|
|
135
|
+
})()`}):s.send({type:"evaluate",code:`(async () => {
|
|
129
136
|
window.dispatchEvent(new CustomEvent(${JSON.stringify(d==="lock"?"sootsim:toggleLock":"sootsim:shake")}))
|
|
130
137
|
return { ok: true, action: ${JSON.stringify(d)} }
|
|
131
|
-
})()`})}function go(
|
|
132
|
-
`),process.exit(0))}if(k==="shell"){let n
|
|
133
|
-
`),process.exit(0))}let e
|
|
138
|
+
})()`})}function go(s){let d={Enter:"return",NumpadEnter:"return",Backspace:"delete",Delete:"delete",Space:"space",ShiftLeft:"shift",ShiftRight:"shift"};if(d[s])return d[s];let i=s.match(/^Digit([0-9])$/);if(i)return i[1];let l=s.match(/^Key([A-Z])$/);return l?l[1].toLowerCase():null}function yo(s){if(typeof s!="string")return null;let d=s.replace(/\s+/g," ").trim();return d?d.slice(0,80):null}function jt(...s){for(let d of s){if(typeof d!="string")continue;let i=d.trim();if(i)return i}return null}function ho(s){let d=s.indexOf("--node-id");if(d<0)return null;let i=s[d+1];if(!i)return null;let l=Number(i);return Number.isInteger(l)&&l>0?l:null}async function L(s,d,i){let l=ce({source:s,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 bo(s,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:s,y:d}},summary:`tap @${Math.round(s)},${Math.round(d)}`}}function _e(s,d,i){let l=jt(d?.testID,d?.id);return l?{step:{tapOn:{id:l}},summary:`tap #${l}`}:i==="id"?{step:{tapOn:{id:s}},summary:`tap #${s}`}:{step:{tapOn:s},summary:`tap "${s}"`}}async function Qs(s,d){let i=s[0]==="get"||s[0]==="do"||s[0]==="debug"||s[0]==="wait"?s[0]:null,l=i?s.slice(1):s,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","--node-id","--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",T=typeof l[0]=="string"&&Oe.has(l[0]),k=T?l[0]:null,h=t=>T&&t===l[0]?`sootsim ${t}`:`sootsim ${S} ${t}`,v=(t,e)=>` usage: ${h(t)}${e?` ${e}`:""}`;if(!y||s.includes("--help")||s.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}
|
|
139
|
+
`),process.exit(0))}if(k==="shell"){let n=xe("shell",t);n&&(console.log(`${n}
|
|
140
|
+
`),process.exit(0))}let e=xe("inspect",t),o=["do","get","debug","wait"].map(n=>we(n,t)).filter(n=>n!=null).join(`
|
|
134
141
|
|
|
135
142
|
`);console.log(`${e??""}
|
|
136
143
|
|
|
137
|
-
${
|
|
138
|
-
`),process.exit(0)}let
|
|
139
|
-
`);let
|
|
140
|
-
`)}catch{}}async function
|
|
144
|
+
${o}
|
|
145
|
+
`),process.exit(0)}let N=f.wsPort,M=f.simId,E=f.simIdSource,J=f.commandTimeoutMs;if(y==="list"&&l.some(t=>t==="--drivers"||t==="-D")){let{buildDriverListRows:t}=await import("./drivers-EQGVLU5S.js"),e=t();console.log(` available drivers (${e.length}):
|
|
146
|
+
`);let o=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(o),w=r.kind.padEnd(n);console.log(` ${u} ${m} ${w} ${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=M||"default",j=new Set(["errors","warnings","requests","js","eval","reload","globals","perf","list","wait","sleep"]),D=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<=D?e:`${e.slice(0,D)}\u2026 (+${e.length-D} 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 x(t){let e=yt()?1200:350;try{let{settled:o,elapsed:n}=await ne({bridge:t,maxMs:e,pollMs:32,stablePolls:2});o||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.
|
|
147
|
+
`)}catch{}}async function _(){try{return await c.send({type:"evaluate",code:`(() => ({
|
|
141
148
|
console: window.__sootsimConsole?.count?.() || null,
|
|
142
149
|
requests: window.__sootsimTest?.getRequestCounts?.() || null,
|
|
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
|
|
144
|
-
network: ${
|
|
150
|
+
}))()`})||{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 o=Math.max(0,Number(e.failed)||0);if(o===0||!t.includeTail&&!Te("requests",K,String(o))||(console.log(`
|
|
151
|
+
network: ${o} failed request${o===1?"":"s"}`),console.log(` inspect: ${h("requests")} 5`),!t.includeTail))return;let n=await z(c,"getFailedRequests",5);if(!(!Array.isArray(n)||n.length===0)){console.log(`
|
|
145
152
|
recent failed requests:
|
|
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
|
|
147
|
-
console: ${u.join(", ")}`),console.log(` inspect: ${
|
|
153
|
+
`);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 O(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 o=e,n=Math.max(0,Number(o.errors)||0),r=Math.max(0,Number(o.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(`
|
|
154
|
+
console: ${u.join(", ")}`),console.log(` inspect: ${h("errors")} 5`),r>0&&console.log(` inspect: ${h("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
155
|
recent console errors:
|
|
149
|
-
`);for(let
|
|
156
|
+
`);for(let w of m){let g=new Date(w.timestamp).toLocaleTimeString(),$=Array.isArray(w.args)?w.args.map(F=>typeof F=="object"?JSON.stringify(F):String(F)).join(" "):String(w);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=Pe(),o=null;try{o=await Ce(t,`(() => {
|
|
150
157
|
const tl = window.SootSim && window.SootSim.bridges && window.SootSim.bridges.timeline
|
|
151
158
|
if (!tl || typeof tl.summary !== 'function') return null
|
|
152
159
|
const cursorKey = ${JSON.stringify(e)}
|
|
@@ -162,9 +169,9 @@ ${s}
|
|
|
162
169
|
}
|
|
163
170
|
}
|
|
164
171
|
return summary ? { summary, consoleSplit } : null
|
|
165
|
-
})()`)}catch{return}if(!
|
|
166
|
-
since last: ${r.join(" \xB7 ")} \u2014 sootsim what-happened`),
|
|
167
|
-
`);for(let e of t){let
|
|
172
|
+
})()`)}catch{return}if(!o||!o.summary||!o.summary.total)return;let n=o.summary.byKind??{},r=[],u=new Set;for(let m of V){let w=n[m];if(w)if(u.add(m),m==="console"&&o.consoleSplit){let{error:g,warn:$}=o.consoleSplit;g>0&&r.push(`${g} error${g===1?"":"s"}`),$>0&&r.push(`${$} warning${$===1?"":"s"}`)}else r.push(`${w} ${m}${w===1?"":"s"}`)}for(let[m,w]of Object.entries(n))!u.has(m)&&w&&r.push(`${w} ${m}${w===1?"":"s"}`);if(r.length!==0&&(console.log(`
|
|
173
|
+
since last: ${r.join(" \xB7 ")} \u2014 sootsim what-happened`),o.summary.lastAt))try{await $e(t,"SootSim.bridges.timeline.cursorAdvance",e,o.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=(s.includes("--verbose")||s.includes("-v"))&&!s.includes("--json");S==="do"&&y==="shell"&&(console.error(" `sootsim do shell` was removed. use `sootsim shell ...` instead."),process.exit(1)),ee.has(y)&&await De(c),ye.has(y)&&await de(c,{verbose:he});try{switch(y){case"list":{await wt({bridge:c,simId:M,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(s.includes("--json"))console.log(JSON.stringify(t,null,2));else{console.log(` accessibility tree (${t.length} nodes):
|
|
174
|
+
`);for(let e of t){let o=[];if(o.push(`[${e.role}]`),e.label){let n=e.label.length>50?e.label.slice(0,47)+"...":e.label;o.push(`"${n}"`)}if(e.hint&&o.push(`(hint: "${e.hint}")`),e.testID&&o.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&&o.push(`{${n.join(", ")}}`)}e.position&&o.push(`@(${e.position.x},${e.position.y})`),e.size&&o.push(`${e.size.w}x${e.size.h}`),console.log(" "+o.join(" "))}}break}case"find":{await ht({bridge:c,args:s,effectiveArgs:l,positional:a,inspectUsage:v});break}case"count":{await ft(c,{args:l});break}case"keyboard":{await bt(c,{json:s.includes("--json")});break}case"screens":{await $t(c,{json:s.includes("--json")});break}case"memory":{await xt(c,{args:l});break}case"wait":{await Mt({wsPort:N,commandTimeoutMs:J,simId:M,simIdSource:E,positional:a});break}case"sleep":{await vt({positional:a,inspectUsage:v});break}case"settle":{await St({bridge:c,args:s,positional:a});break}case"ready":{await Ft({bridge:c,args:s});break}case"idle":{await _t({bridge:c,args:s,positional:a});break}case"selector":{await At({bridge:c,args:s,positional:a,inspectUsage:v});break}case"event":{await Nt({bridge:c,args:s,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=s.find((w,g)=>s[g-1]==="--output")||"/tmp/sootsim-inspect.png",o=await Et(s,c),n={type:"screenshot"};o&&(n.crop=o);let u=(await c.send(n)).replace(/^data:image\/png;base64,/,"");o&&console.log(` area: x=${o.x} y=${o.y} w=${o.w} h=${o.h}`),(await import("fs")).writeFileSync(e,Buffer.from(u,"base64")),console.log(` saved: ${e}`);break}case"sample-color":{let t=await Et(s,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:Je(t)});if(s.includes("--json"))console.log(JSON.stringify(e,null,2));else{let{r:o,g:n,b:r,a:u,hex:m,samples:w}=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(${o}, ${n}, ${r}, ${u}) ${g} ${w} 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
175
|
const t = window.__sootsimTest
|
|
169
176
|
const q = ${JSON.stringify(t)}
|
|
170
177
|
let node = null
|
|
@@ -220,20 +227,20 @@ ${s}
|
|
|
220
227
|
transform,
|
|
221
228
|
parentChain,
|
|
222
229
|
}
|
|
223
|
-
})()`});console.log(JSON.stringify(e,null,2));break}case"tap":{let t=Number(a[1]),e=Number(a[2]),
|
|
230
|
+
})()`});console.log(JSON.stringify(e,null,2));break}case"tap":{let t=Number(a[1]),e=Number(a[2]),o=ae(s),n=null;if(o){let m=await me(c,o);m||(console.error(` not found: ${o.value}`),o.mode==="testid"&&G("wait-selector-for-missing-testid",o.value),process.exit(1)),t=m.x,e=m.y,n=m}(!Number.isFinite(t)||!Number.isFinite(e))&&(console.error(v("tap","<x> <y> | --testid <id> | --text <t>")),process.exit(1));let r=await c.send({type:"tap",x:t,y:e,...o?{target:{id:n?.id??(o.mode==="testid"?o.value:null),testID:n?.testID??(o.mode==="testid"?o.value:null),text:n?.text??(o.mode==="text"?o.value:null),type:n?.type??null}}:{}}),u=bo(t,e,r);u&&await L("inspect tap",u.step,u.summary),console.log(JSON.stringify(r,null,2));break}case"drag":case"swipe":{let t=Number(a[1]),e=Number(a[2]),o=Number(a[3]),n=Number(a[4]),r=y==="swipe"?10:12,u=y==="swipe"?8:16,m=a[5]?Number(a[5]):r,w=a[6]?Number(a[6]):u;(!Number.isFinite(t)||!Number.isFinite(e)||!Number.isFinite(o)||!Number.isFinite(n)||!Number.isFinite(m)||!Number.isFinite(w))&&(console.error(v(y,"<x1> <y1> <x2> <y2> [steps] [stepMs]")),process.exit(1));let g=await c.send({type:"evaluate",code:`(async () => {
|
|
224
231
|
const interact = window.__sootsimInteract
|
|
225
232
|
if (!interact?.drag) return { ok: false, reason: 'no interact.drag' }
|
|
226
|
-
const value = await interact.drag(${t}, ${e}, ${
|
|
233
|
+
const value = await interact.drag(${t}, ${e}, ${o}, ${n}, ${Math.max(1,Math.round(m))}, ${Math.max(0,Math.round(w))})
|
|
227
234
|
return { ok: !!value, value }
|
|
228
|
-
})()`});if(g?.ok){let $=Math.max(1,Math.round(Math.max(1,m)*Math.max(0,
|
|
235
|
+
})()`});if(g?.ok){let $=Math.max(1,Math.round(Math.max(1,m)*Math.max(0,w)));await L(`inspect ${y}`,{swipe:{start:`${t}, ${e}`,end:`${o}, ${n}`,duration:$}},`${y} ${t},${e} -> ${o},${n}`)}console.log(JSON.stringify(g,null,2));break}case"pinch":{let t=Number(a[1]),e=Number(a[2]),o=Number(a[3]),n=Number(a[4]),r=Number(a[5]),u=Number(a[6]),m=Number(a[7]),w=Number(a[8]),g=a[9]?Number(a[9]):12,$=a[10]?Number(a[10]):16;(!Number.isFinite(t)||!Number.isFinite(e)||!Number.isFinite(o)||!Number.isFinite(n)||!Number.isFinite(r)||!Number.isFinite(u)||!Number.isFinite(m)||!Number.isFinite(w)||!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
236
|
const interact = window.__sootsimInteract
|
|
230
237
|
if (!interact?.pinch) return { ok: false, reason: 'no interact.pinch' }
|
|
231
|
-
const value = await interact.pinch(${t}, ${e}, ${
|
|
238
|
+
const value = await interact.pinch(${t}, ${e}, ${o}, ${n}, ${r}, ${u}, ${m}, ${w}, ${Math.max(1,Math.round(g))}, ${Math.max(0,Math.round($))})
|
|
232
239
|
return { ok: !!value, value }
|
|
233
|
-
})()`});F?.ok&&await
|
|
240
|
+
})()`});F?.ok&&await L("inspect pinch",{pinch:{from:[t,e,o,n],to:[r,u,m,w],steps:Math.max(1,Math.round(g)),stepMs:Math.max(0,Math.round($))}},`pinch (${t},${e}) (${o},${n}) -> (${r},${u}) (${m},${w})`),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=s.indexOf(R);return A>=0&&A+1<s.length?s[A+1]:null},o=R=>s.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"),w=o("--exact"),g=o("--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=s.indexOf("--near"),I=null;if(U>=0){let R=Number(s[U+1]),A=Number(s[U+2]);(!Number.isFinite(R)||!Number.isFinite(A))&&(console.error(" --near requires two numbers: --near <x> <y>"),process.exit(1)),I={x:R,y:A}}let b=JSON.stringify({query:t,exact:w,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:I,nth:r,first:g}),p=await c.send({type:"evaluate",code:`(async () => {
|
|
234
241
|
const t = window.__sootsimTest
|
|
235
242
|
if (!t) return { error: 'bridge-not-ready' }
|
|
236
|
-
const F = ${
|
|
243
|
+
const F = ${b}
|
|
237
244
|
|
|
238
245
|
const res = await t.queryTextCandidates({
|
|
239
246
|
query: F.query,
|
|
@@ -338,13 +345,19 @@ ${s}
|
|
|
338
345
|
nodeId: target.nodeId ?? null,
|
|
339
346
|
id: target.id,
|
|
340
347
|
testID: target.testID,
|
|
348
|
+
text:
|
|
349
|
+
target.text ??
|
|
350
|
+
target.accessibilityLabel ??
|
|
351
|
+
n.text ??
|
|
352
|
+
n.accessibilityLabel ??
|
|
353
|
+
null,
|
|
341
354
|
type: target.type,
|
|
342
355
|
},
|
|
343
356
|
strategy: (resolved && resolved.strategy) || 'matched-node',
|
|
344
357
|
total,
|
|
345
358
|
idx,
|
|
346
359
|
}
|
|
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}`:"",
|
|
360
|
+
})()`});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}`:"",Lt=A.testID?` #${A.testID}`:"",Jt=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}>${Jt}${Lt} ${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 P=await c.send({type:"tap",x:p.cx,y:p.cy,target:{id:p.target?.id??null,testID:p.target?.testID??null,text:t,type:p.target?.type??null}});if(P?.hit!==!1&&P?.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 L("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:P},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),o=await c.send({type:"evaluate",code:`(async () => {
|
|
348
361
|
const t = window.__sootsimTest
|
|
349
362
|
if (!t) return { error: 'bridge-not-ready' }
|
|
350
363
|
// try testID first \u2014 strongest signal of "this is the
|
|
@@ -385,7 +398,7 @@ ${s}
|
|
|
385
398
|
}
|
|
386
399
|
}
|
|
387
400
|
return { strategy: 'none' }
|
|
388
|
-
})()`});"error"in
|
|
401
|
+
})()`});"error"in o&&(console.error(` ${o.error}`),process.exit(1)),o.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=o.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,target:{id:n.id,testID:n.testID,text:o.strategy==="text"?t:null,type:n.type}});if(m?.hit!==!1&&m?.ok!==!1){let w=_e(t,{id:n.id,testID:n.testID,type:n.type,cx:r,cy:u},o.strategy==="testid"?"id":"text");await L("inspect tap-best",w.step,w.summary)}console.log(JSON.stringify({matched:{strategy:o.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),o=await c.send({type:"evaluate",code:`(async () => {
|
|
389
402
|
const t = window.__sootsimTest
|
|
390
403
|
if (!t) return null
|
|
391
404
|
const n = (await t.findByTestId(${e})) || (await t.findById(${e}))
|
|
@@ -410,29 +423,38 @@ ${s}
|
|
|
410
423
|
nodeId: n.nodeId ?? null,
|
|
411
424
|
id: n.id,
|
|
412
425
|
testID: n.testID,
|
|
426
|
+
text: n.text ?? n.accessibilityLabel ?? null,
|
|
413
427
|
type: n.type,
|
|
414
428
|
},
|
|
415
429
|
target: {
|
|
416
430
|
nodeId: target.nodeId ?? null,
|
|
417
431
|
id: target.id,
|
|
418
432
|
testID: target.testID,
|
|
433
|
+
text:
|
|
434
|
+
target.text ??
|
|
435
|
+
target.accessibilityLabel ??
|
|
436
|
+
n.text ??
|
|
437
|
+
n.accessibilityLabel ??
|
|
438
|
+
null,
|
|
419
439
|
type: target.type,
|
|
420
440
|
},
|
|
421
441
|
strategy: (resolved && resolved.strategy) || 'matched-node',
|
|
422
442
|
}
|
|
423
|
-
})()`});(!
|
|
443
|
+
})()`});(!o||typeof o.cx!="number")&&(console.error(` not found: ${t}`),process.exit(1));let n=await c.send({type:"tap",x:o.cx,y:o.cy,target:{id:o.target?.id??o.match?.id??null,testID:o.target?.testID??o.match?.testID??null,text:o.target?.text??o.target?.accessibilityLabel??o.match?.text??o.match?.accessibilityLabel??null,type:o.target?.type??o.match?.type??null}});if(n?.hit!==!1&&n?.ok!==!1){let r=_e(t,{id:o.target?.id??null,testID:o.target?.testID??null,type:o.target?.type??null,cx:o.cx,cy:o.cy},"id");await L("inspect tap-id",r.step,r.summary)}console.log(JSON.stringify({matched:o.match,tapped:{nodeId:o.target?.nodeId??null,id:o.target?.id??null,testID:o.target?.testID??null,type:o.target?.type??null,cx:o.cx,cy:o.cy},...o.strategy&&o.strategy!=="matched-node"?{strategy:o.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 o=JSON.stringify(t),n=await c.send({type:"evaluate",code:`(async () => {
|
|
424
444
|
const t = window.__sootsimTest
|
|
425
445
|
if (!t) return null
|
|
426
|
-
const n = await (t.findByTestId(${
|
|
446
|
+
const n = await (t.findByTestId(${o}) || t.findById(${o}))
|
|
427
447
|
if (!n || !n.absolutePosition || !n.layout) return null
|
|
428
448
|
return {
|
|
429
449
|
cx: n.absolutePosition.x + (n.layout.width || 0) / 2,
|
|
430
450
|
cy: n.absolutePosition.y + (n.layout.height || 0) / 2,
|
|
451
|
+
id: n.id,
|
|
431
452
|
testID: n.testID,
|
|
453
|
+
type: n.type,
|
|
432
454
|
isTextInput: !!n.isTextInput,
|
|
433
455
|
placeholder: n.placeholder || null,
|
|
434
456
|
}
|
|
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
|
|
457
|
+
})()`});(!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,target:{id:n.id??t,testID:n.testID??t,text:null,type:n.type??null}}),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 L("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 L("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 L("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 L("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)})),o=e.filter(n=>!n.key);o.length>0&&(console.error(` unsupported keycode(s): ${o.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 L("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 L("inspect dispatch",{dispatchKey:t},`dispatch ${JSON.stringify(t)}`),console.log(` dispatched: ${t}`);break}case"dismiss":{await c.send({type:"keyboard",action:"dismiss"}),await L("inspect dismiss",{hideKeyboard:!0},"dismiss keyboard"),console.log(" keyboard dismissed");break}case"double-tap":{let t=Number(a[1]),e=Number(a[2]),o=ae(s);if(o){let m=await me(c,o);m||(console.error(` not found: ${o.value}`),o.mode==="testid"&&G("wait-selector-for-missing-testid",o.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
458
|
const interact = window.__sootsimInteract
|
|
437
459
|
if (interact?.doubleTap) {
|
|
438
460
|
return {
|
|
@@ -455,18 +477,18 @@ ${s}
|
|
|
455
477
|
first,
|
|
456
478
|
second,
|
|
457
479
|
}
|
|
458
|
-
})()`});u?.ok&&await
|
|
480
|
+
})()`});u?.ok&&await L("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]),o=ae(s);if(o){let u=await me(c,o);u||(console.error(` not found: ${o.value}`),o.mode==="testid"&&G("wait-selector-for-missing-testid",o.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
481
|
const interact = window.__sootsimInteract
|
|
460
482
|
if (!interact?.longPress) return { ok: false, reason: 'no interact.longPress' }
|
|
461
483
|
const value = await interact.longPress(${t}, ${e}, ${Math.max(0,Math.round(n))})
|
|
462
484
|
return { ok: !!value, value }
|
|
463
|
-
})()`});r?.ok&&await
|
|
485
|
+
})()`});r?.ok&&await L("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]),o=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(o))&&(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(o)?`window.dispatchEvent(new CustomEvent('sootsim:agentAction', { detail: { type: '${u}', x: ${e}, y: ${o} } }));`:"",w=await c.send({type:"evaluate",code:`(async () => {
|
|
464
486
|
${m}
|
|
465
487
|
const interact = window.__sootsimInteract
|
|
466
488
|
if (!interact?.${r}) return { ok: false, reason: 'no interact.${r}' }
|
|
467
|
-
const value = ${t==="cancel"?`await interact.${r}(${Math.max(1,Math.round(n))})`:`await interact.${r}(${e}, ${
|
|
489
|
+
const value = ${t==="cancel"?`await interact.${r}(${Math.max(1,Math.round(n))})`:`await interact.${r}(${e}, ${o}, ${Math.max(1,Math.round(n))})`}
|
|
468
490
|
return { ok: !!value, value }
|
|
469
|
-
})()`});
|
|
491
|
+
})()`});w?.ok&&t!=="cancel"&&await L("inspect touch",{tapAtCoords:{x:e,y:o}},`touch ${t} @${e},${o}`),console.log(JSON.stringify(w,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],o=a[2]?Number(a[2]):220;(!e||!Number.isFinite(o))&&(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
492
|
const spec = globalThis.__sootsimDeviceSpec || {}
|
|
471
493
|
return {
|
|
472
494
|
width: spec.width || window.innerWidth || 393,
|
|
@@ -474,26 +496,26 @@ ${s}
|
|
|
474
496
|
statusBarHeight: spec.statusBarHeight || 0,
|
|
475
497
|
homeIndicatorHeight: spec.homeIndicatorHeight || 0,
|
|
476
498
|
}
|
|
477
|
-
})()`}),r=Number(n?.width)||393,u=Number(n?.height)||852,m=Number(n?.statusBarHeight)||0,
|
|
499
|
+
})()`}),r=Number(n?.width)||393,u=Number(n?.height)||852,m=Number(n?.statusBarHeight)||0,w=Number(n?.homeIndicatorHeight)||0,g=Math.round(r/2),$=Math.round(u/2),F=Math.max(24,m+18),q=Math.max(24,w+18),H=18,U=Math.min(220,Math.round(u*.24)),I=Math.min(180,Math.round(r*.32)),b=g,p=$,P=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":b=g+Math.round(I/2),P=g-Math.round(I/2);break;case"scroll-right":b=g-Math.round(I/2),P=g+Math.round(I/2);break;case"swipe-from-left-edge":b=H,p=$,P=Math.min(r-H,H+I);break;case"swipe-from-right-edge":b=r-H,p=$,P=Math.max(H,r-H-I);break;case"swipe-from-top-edge":b=g,p=F,R=Math.min(u-q,F+U);break;case"swipe-from-bottom-edge":b=g,p=u-q,R=Math.max(F,u-q-U);break}let A=Math.max(8,Math.round(o/16)),be=Math.max(1,Math.round(o/A)),le=await c.send({type:"evaluate",code:`(async () => {
|
|
478
500
|
const interact = window.__sootsimInteract
|
|
479
501
|
if (!interact?.drag) return { ok: false, reason: 'no interact.drag' }
|
|
480
|
-
const value = await interact.drag(${
|
|
502
|
+
const value = await interact.drag(${b}, ${p}, ${P}, ${R}, ${A}, ${be})
|
|
481
503
|
return { ok: !!value, value }
|
|
482
|
-
})()`});le?.ok&&await
|
|
504
|
+
})()`});le?.ok&&await L("inspect gesture",{swipe:{start:`${b}, ${p}`,end:`${P}, ${R}`,duration:Math.max(1,Math.round(o))}},`gesture ${e}`),console.log(JSON.stringify({preset:e,from:{x:b,y:p},to:{x:P,y:R},result:le},null,2));break}case"scroll":{let t=ae(s),e=ho(s),o=t?.mode==="testid"?t.value:e==null?a[1]:null,n=t||e!=null?1:2,r=Number(a[n]),u=Number(a[n+1]);(!o&&e==null||!Number.isFinite(r)||!Number.isFinite(u))&&(console.error(v("scroll","<id> <x> <y> | --testid <id> <x> <y> | --node-id <nodeId> <x> <y>")),process.exit(1));let m=await c.send({type:"evaluate",code:`(async () => {
|
|
483
505
|
const t = window.__sootsimTest
|
|
484
506
|
if (!t) return null
|
|
485
|
-
const n = await t.
|
|
486
|
-
|| await t.findById(${JSON.stringify(
|
|
507
|
+
const n = ${e!=null?`await t.inspectByNodeId(${JSON.stringify(e)})`:`await t.findByTestId(${JSON.stringify(o)})
|
|
508
|
+
|| await t.findById(${JSON.stringify(o)})`}
|
|
487
509
|
if (!n || !n.absolutePosition || !n.layout) return null
|
|
488
510
|
return {
|
|
489
511
|
cx: n.absolutePosition.x + (n.layout.width || 0) / 2,
|
|
490
512
|
cy: n.absolutePosition.y + (n.layout.height || 0) / 2,
|
|
491
513
|
}
|
|
492
|
-
})()`}),
|
|
514
|
+
})()`}),w=await z(c,"scrollTo",e!=null?{nodeId:e}:o,r,u,!1);if(w?.ok){let g=e!=null?`node ${e}`:`#${o}`;await L("inspect scroll",{scrollTo:{...e!=null?{nodeId:e}:{id:o},x:r,y:u}},`scroll ${g} -> ${r},${u}`)}console.log(JSON.stringify({...w,...m?{at:{x:m.cx,y:m.cy}}:{}},null,2));break}case"state":{let t=a[1];if(i==="get"&&!t){let o=await z(c,"getRuntimeState"),n=await c.send({type:"evaluate",code:`({
|
|
493
515
|
errors: window.__sootsimConsole?.getErrors?.()?.length ?? 0,
|
|
494
516
|
warnings: window.__sootsimConsole?.getWarnings?.()?.length ?? 0,
|
|
495
|
-
})`});if(
|
|
496
|
-
${
|
|
517
|
+
})`});if(o&&typeof o=="object"&&o.diagnostics&&(o.diagnostics.errors=n?.errors??0,o.diagnostics.warnings=n?.warnings??0),o&&typeof o=="object"&&o.shell==null)try{let r=await se(c);r&&(o.shell=r)}catch{}console.log(JSON.stringify(o,null,2));break}if(!t||t==="--help"||t==="-h"){console.log(`
|
|
518
|
+
${h("state")} \u2014 dump raw runtime state
|
|
497
519
|
|
|
498
520
|
subcommands:
|
|
499
521
|
shell dump shell transition/layout state
|
|
@@ -507,15 +529,15 @@ ${s}
|
|
|
507
529
|
gesture <x> <y> dump gesture routing/debug info at coordinates
|
|
508
530
|
|
|
509
531
|
examples:
|
|
510
|
-
${
|
|
511
|
-
${
|
|
512
|
-
${
|
|
513
|
-
${
|
|
514
|
-
${
|
|
515
|
-
${
|
|
516
|
-
${
|
|
517
|
-
${
|
|
518
|
-
`);break}let e;switch(t){case"shell":e=await se(c,500);break;case"worker":e=await
|
|
532
|
+
${h("state")} shell
|
|
533
|
+
${h("state")} worker
|
|
534
|
+
${h("state")} keyboard
|
|
535
|
+
${h("state")} ownership
|
|
536
|
+
${h("state")} node photos
|
|
537
|
+
${h("state")} scroll feed
|
|
538
|
+
${h("state")} scroll-hit 360 420
|
|
539
|
+
${h("state")} hit 200 720
|
|
540
|
+
`);break}let e;switch(t){case"shell":e=await se(c,500);break;case"worker":e=await $e(c,"__sootsimRenderHost.queryStats");break;case"ownership":e=await c.send({type:"evaluate",code:`(() => {
|
|
519
541
|
const h = window.__sootsimRenderHost
|
|
520
542
|
if (!h || typeof h.getOwnershipSnapshot !== 'function') {
|
|
521
543
|
return { error: 'getOwnershipSnapshot not available' }
|
|
@@ -546,8 +568,8 @@ ${s}
|
|
|
546
568
|
text: focused.text || null,
|
|
547
569
|
} : null,
|
|
548
570
|
}
|
|
549
|
-
})()`});break;case"node":{let
|
|
550
|
-
${
|
|
571
|
+
})()`});break;case"node":{let o=a[2];o||(console.error(` usage: ${h("state")} node <id>`),process.exit(1)),e=await z(c,"findByTestId",o)||await z(c,"findById",o);break}case"scroll":{let o=a[2];o||(console.error(` usage: ${h("state")} scroll <id>`),process.exit(1)),e=await z(c,"getScrollState",o);break}case"scroll-hit":{let o=Number(a[2]),n=Number(a[3]);(!Number.isFinite(o)||!Number.isFinite(n))&&(console.error(` usage: ${h("state")} scroll-hit <x> <y>`),process.exit(1)),e=await z(c,"getScrollStateAt",o,n);break}case"hit":{let o=Number(a[2]),n=Number(a[3]);(!Number.isFinite(o)||!Number.isFinite(n))&&(console.error(` usage: ${h("state")} hit <x> <y>`),process.exit(1)),e=await z(c,"debugHitAt",o,n);break}case"gesture":{let o=Number(a[2]),n=Number(a[3]);(!Number.isFinite(o)||!Number.isFinite(n))&&(console.error(` usage: ${h("state")} gesture <x> <y>`),process.exit(1)),e=await z(c,"debugGestureAt",o,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(`
|
|
572
|
+
${h("shell")} \u2014 run built-in shell commands
|
|
551
573
|
|
|
552
574
|
subcommands:
|
|
553
575
|
launch <appId> [waitMs] [--clear-state]
|
|
@@ -562,15 +584,15 @@ ${s}
|
|
|
562
584
|
shake trigger the simulator shake gesture
|
|
563
585
|
|
|
564
586
|
examples:
|
|
565
|
-
${
|
|
566
|
-
${
|
|
567
|
-
${
|
|
568
|
-
${
|
|
569
|
-
${
|
|
570
|
-
${
|
|
571
|
-
${
|
|
572
|
-
${
|
|
573
|
-
`);break}let e=t==="launch"||t==="open-card"||t==="home"||t==="switcher",
|
|
587
|
+
${h("shell")} launch photos
|
|
588
|
+
${h("shell")} launch rn --clear-state
|
|
589
|
+
${h("shell")} launch photos 1500
|
|
590
|
+
${h("shell")} home 500
|
|
591
|
+
${h("shell")} switcher 800
|
|
592
|
+
${h("shell")} open-card clock 800
|
|
593
|
+
${h("shell")} appearance dark
|
|
594
|
+
${h("shell")} lock
|
|
595
|
+
`);break}let e=t==="launch"||t==="open-card"||t==="home"||t==="switcher",o=t==="launch"||t==="open-card"?a[3]:a[2],n=o?Number(o):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,w=s.includes("--clear-state");if(t==="launch"){let g=a[2];g||(console.error(v("shell","launch <appId> [settleMs] [--clear-state]")),process.exit(1)),w&&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 L("inspect shell launch",w?{launchApp:{clearState:!0}}:{launchApp:{}},w?"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 L("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 Dt(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 Dt(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 o=!1,n=!1;try{await c.send({type:"evaluate",code:"window.__sootsimConsole?.clear()"});let m=await c.send({type:"evaluate",code:`;(() => {
|
|
574
596
|
const reloadExternalApp = window.SootSim?.bridges?.hotRemount?.reloadExternalApp
|
|
575
597
|
if (typeof reloadExternalApp === 'function') {
|
|
576
598
|
reloadExternalApp()
|
|
@@ -578,10 +600,10 @@ ${s}
|
|
|
578
600
|
}
|
|
579
601
|
window.location.reload()
|
|
580
602
|
return { kind: 'page' }
|
|
581
|
-
})()`});n=!!m&&m.kind==="external-app",
|
|
603
|
+
})()`});n=!!m&&m.kind==="external-app",o=!0}catch{}console.log(" reloading...");let r=c,u=null;if(n)u=await ke(c,{timeoutMs:1e4,errorGraceMs:3e3});else{o&&await X(300);let m=await lt(N,J,M,{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
604
|
\u26A0 ${m.length} error(s) during mount:
|
|
583
|
-
`);for(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(` ${
|
|
605
|
+
`);for(let w of m){let g=w.args.map($=>typeof $=="object"?JSON.stringify($):$).join(" ");if(console.log(` ${g}`),w.stack){let $=w.stack.split(`
|
|
606
|
+
`).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(` ${h("js")} SootSim.bridges.test.findByText("Sign in")`),console.error(` ${h("js")} SootSim.bridges.debug.snapshot("before")`),console.error(` ${h("js")} SootSim.bridges.keyboard.type("hello")`),console.error(` ${h("js")} SootSim.state.root.children.length`),process.exit(1));let e=t;e.startsWith("(async")||(e=`(async () => ${e})()`);let o=await c.send({type:"evaluate",code:e});console.log(JSON.stringify(o,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
607
|
const globals = {}
|
|
586
608
|
|
|
587
609
|
// test bridge (proxy in worker mode)
|
|
@@ -619,8 +641,8 @@ ${s}
|
|
|
619
641
|
|
|
620
642
|
return globals
|
|
621
643
|
})()`});console.log(` sootsim JS API:
|
|
622
|
-
`);for(let[e,
|
|
623
|
-
${
|
|
644
|
+
`);for(let[e,o]of Object.entries(t)){console.log(` ${e}:`);for(let n of o)console.log(` .${n}`);console.log("")}console.log(` use: ${h("js")} <expression>`),console.log(` example: ${h("js")} test.findByText("Sign in")`);break}case"describe":{await gt({bridge:c,args:s,positional:a});break}case"perf":{let t=a[1];if(!t||t==="--help"||t==="-h"){console.log(`
|
|
645
|
+
${h("perf")} \u2014 performance profiling
|
|
624
646
|
|
|
625
647
|
subcommands:
|
|
626
648
|
stats one-shot stats (zero overhead query)
|
|
@@ -630,11 +652,11 @@ ${s}
|
|
|
630
652
|
transition <e> profile a shell transition (goHome, appSwitcher, lockScreen)
|
|
631
653
|
|
|
632
654
|
examples:
|
|
633
|
-
${
|
|
634
|
-
${
|
|
655
|
+
${h("perf")} stats
|
|
656
|
+
${h("perf")} start
|
|
635
657
|
# ... interact with the app ...
|
|
636
|
-
${
|
|
637
|
-
${
|
|
658
|
+
${h("perf")} stop
|
|
659
|
+
${h("perf")} transition goHome
|
|
638
660
|
`);break}switch(t){case"stats":{let e=await c.send({type:"evaluate",code:`(async () => {
|
|
639
661
|
// worker mode (host exposes these)
|
|
640
662
|
if (window.__sootsimPerfStats) {
|
|
@@ -660,7 +682,7 @@ ${s}
|
|
|
660
682
|
jankFrames: frameStats.recentFrames?.filter(f => f > 16.67).length || 0,
|
|
661
683
|
recentCount: frameStats.recentFrames?.length || 0,
|
|
662
684
|
}
|
|
663
|
-
})()`});e.error&&(console.error(` error: ${e.error}`),process.exit(1));let
|
|
685
|
+
})()`});e.error&&(console.error(` error: ${e.error}`),process.exit(1));let o=e.avgMs!=="?"?(1e3/parseFloat(e.avgMs)).toFixed(1):"?";console.log(" perf stats:"),console.log(` frames: ${e.frames}`),console.log(` avg: ${e.avgMs}ms (${o} 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
686
|
// worker mode
|
|
665
687
|
if (window.__sootsimPerfStart && window.__sootsimRenderHost) {
|
|
666
688
|
const result = window.__sootsimPerfStart()
|
|
@@ -682,7 +704,7 @@ ${s}
|
|
|
682
704
|
startedAt: performance.now(),
|
|
683
705
|
}
|
|
684
706
|
return { started: true }
|
|
685
|
-
})()`}),console.log(` profiling started \u2014 interact with the app, then run '${
|
|
707
|
+
})()`}),console.log(` profiling started \u2014 interact with the app, then run '${h("perf")} stop'`);break}case"stop":{let e=await c.send({type:"evaluate",code:`(async () => {
|
|
686
708
|
// worker mode
|
|
687
709
|
if (window.__sootsimRenderHost) {
|
|
688
710
|
const session = window.${Q} || {}
|
|
@@ -776,8 +798,8 @@ ${s}
|
|
|
776
798
|
jankFrames: recent.filter(f => f > 16.67).length,
|
|
777
799
|
sampleCount: recent.length,
|
|
778
800
|
}
|
|
779
|
-
})()`});e.error&&(console.error(` error: ${e.error}`),process.exit(1));let
|
|
780
|
-
`),console.log(` frames: ${e.frames}`),console.log(` total: ${e.totalMs.toFixed(1)}ms`),console.log(` avg: ${e.avgMs.toFixed(2)}ms (${
|
|
801
|
+
})()`});e.error&&(console.error(` error: ${e.error}`),process.exit(1));let o=e.avgMs>0?(1e3/e.avgMs).toFixed(1):"?",n=e.sampleCount>0?(e.jankFrames/e.sampleCount*100).toFixed(1):"0";console.log(` profiling stopped:
|
|
802
|
+
`),console.log(` frames: ${e.frames}`),console.log(` total: ${e.totalMs.toFixed(1)}ms`),console.log(` avg: ${e.avgMs.toFixed(2)}ms (${o} 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 o=await c.send({type:"evaluate",code:`(async () => {
|
|
781
803
|
if (window.__sootsimRenderHost) {
|
|
782
804
|
const session = window.${Q} || {}
|
|
783
805
|
if (session.active) {
|
|
@@ -812,7 +834,7 @@ ${s}
|
|
|
812
834
|
mode: 'main-thread',
|
|
813
835
|
frames: (stats.recentFrames || []).slice(-${e}),
|
|
814
836
|
}
|
|
815
|
-
})()`});if(
|
|
837
|
+
})()`});if(o.error&&(console.error(` error: ${o.error}`),process.exit(1)),o.mode==="render-worker"){let r=Array.isArray(o.samples)?o.samples:[];if(r.length===0){console.log(` no frame data \u2014 run '${h("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,w,g,$,F,q]of r)console.log(` ${m.toFixed(2).padStart(7)} ${w.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])),o.live&&console.log(" sampling continues");break}let n=Array.isArray(o.frames)?o.frames:Array.isArray(o)?o:[];if(n.length===0){console.log(` no frame data \u2014 run '${h("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 o=await c.send({type:"evaluate",code:`(async () => {
|
|
816
838
|
if (window.__sootsimRenderHost) {
|
|
817
839
|
const session = window.${Q} || {}
|
|
818
840
|
if (session.active) {
|
|
@@ -854,8 +876,8 @@ ${s}
|
|
|
854
876
|
mode: 'main-thread',
|
|
855
877
|
frames: recent.slice().sort((a, b) => b - a).slice(0, ${e}),
|
|
856
878
|
}
|
|
857
|
-
})()`});if(
|
|
858
|
-
${
|
|
879
|
+
})()`});if(o.error&&(console.error(` error: ${o.error}`),process.exit(1)),o.mode==="render-worker"){let r=Array.isArray(o.samples)?o.samples:[];if(r.length===0){console.log(` no frame data \u2014 run '${h("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,w,g,$,F,q]of r)console.log(` ${m.toFixed(2).padStart(7)} ${w.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)}`);o.live&&(console.log(""),console.log(" sampling continues"));break}let n=Array.isArray(o.frames)?o.frames:Array.isArray(o)?o:[];if(n.length===0){console.log(` no frame data \u2014 run '${h("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(`
|
|
880
|
+
${h("perf")} transition <event> \u2014 profile a shell transition
|
|
859
881
|
|
|
860
882
|
events:
|
|
861
883
|
goHome swipe-to-home animation
|
|
@@ -865,8 +887,8 @@ ${s}
|
|
|
865
887
|
note: uses 600ms capture window \u2014 may need --timeout 10000 flag
|
|
866
888
|
|
|
867
889
|
examples:
|
|
868
|
-
${
|
|
869
|
-
${
|
|
890
|
+
${h("perf")} transition goHome --timeout 10000
|
|
891
|
+
${h("perf")} transition appSwitcher
|
|
870
892
|
`);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
893
|
// only supported in render-worker mode
|
|
872
894
|
if (!window.__sootsimRenderHost) {
|
|
@@ -944,27 +966,27 @@ ${s}
|
|
|
944
966
|
p50: ${r.p50.toFixed(2)}ms
|
|
945
967
|
p95: ${r.p95.toFixed(2)}ms
|
|
946
968
|
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(
|
|
948
|
-
`);for(let n of
|
|
949
|
-
`).slice(0,3);for(let
|
|
950
|
-
`);for(let
|
|
951
|
-
`);for(let e of t){let
|
|
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,
|
|
969
|
+
jank: ${r.jankFrames} frames (${m}%) >16.67ms`),Array.isArray(r.samples)&&r.samples.length>0&&(console.log(""),Ne(r.samples.map(w=>w[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),C(l)?B({cleared:!0}):console.log(" error buffer cleared");break}let e=t?Number(t):20,o=await Xe(c,e);if(C(l)){B(o);break}if(o.length===0){console.log(" no errors captured");break}console.log(` ${o.length} error(s):
|
|
970
|
+
`);for(let n of o){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(`
|
|
971
|
+
`).slice(0,3);for(let w of m)console.log(` ${w.trim()}`)}}break}case"warnings":{let t=a[1]?Number(a[1]):20,e=await Ve(c,t);if(C(l)){B(e);break}if(e.length===0){console.log(" no warnings captured");break}console.log(` ${e.length} warning(s):
|
|
972
|
+
`);for(let o of e){let n=new Date(o.timestamp).toLocaleTimeString(),r=o.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(s.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):
|
|
973
|
+
`);for(let e of t){let o=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`,w=e.loop?" loop":"",g=e.layoutBound?" layout":"";console.log(` #${e.id} ${o} ${n.padEnd(14)} cur=${r.padEnd(7)} ${u.padStart(4)} ${m}${w}${g}`)}break}case"animation":{let t=a[1];(!t||t==="--help"||t==="-h")&&(console.error(` usage: ${h("animation")} <id>`),process.exit(1));let e=Number(t);Number.isFinite(e)||(console.error(` invalid id: ${t}`),process.exit(1));let o=await z(c,"getAnimation",e);console.log(JSON.stringify(o,null,2));break}case"stop-animation":{let t=a[1];(!t||t==="--help"||t==="-h")&&(console.error(` usage: ${h("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 o=await z(c,"stopAnimation",e);console.log(` stopped ${o??0} animation(s)`);break}case"requests":{let t=a[1];if(t==="clear"){await et(c),C(l)?B({cleared:!0}):console.log(" request buffer cleared");break}let e=t==="all",o=e?a[2]:t,n=o?Number(o):20,r=await Ze(c,{failed:!e,limit:n});if(C(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)"}:
|
|
974
|
+
`);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,o=null,n=!1,r=!1,u=1e3,m=!1,w=!1;for(let I=0;I<l.length;I++){let b=l[I];if(b==="--filter")e=l[I+1]??null,I++;else if(b==="--limit"){let p=Number(l[I+1]);Number.isFinite(p)&&(o=p),I++}else if(b==="--threshold"){let p=Number(l[I+1]);Number.isFinite(p)&&p>0&&(u=p),I++}else b==="--failed"?n=!0:b==="--slow"?r=!0:b==="--tail"||b==="-f"?m=!0:b==="--json"&&(w=!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 I=a[2];I||(console.error(" usage: sootsim network get <id>"),process.exit(1));let b=await c.send({type:"evaluate",code:`(() => {
|
|
953
975
|
const obs = window.__sootsimObservability;
|
|
954
976
|
if (!obs) return null;
|
|
955
|
-
return obs.network.getSnapshot().find(e => e.id === ${JSON.stringify(
|
|
956
|
-
})()`});
|
|
957
|
-
to target a specific sim, use \`--sim ${t}\` instead.`),process.exit(1));let $=async()=>{let
|
|
977
|
+
return obs.network.getSnapshot().find(e => e.id === ${JSON.stringify(I)}) || null;
|
|
978
|
+
})()`});b||(console.error(` no entry with id ${I}`),process.exit(1)),w?console.log(JSON.stringify(b,null,2)):co(b);break}let g=o??(m?200:t?Number(t):20);Number.isFinite(g)||(console.error(` invalid limit: ${t} \u2014 \`network\` takes a numeric count (e.g. ${h("network")} 100).
|
|
979
|
+
to target a specific sim, use \`--sim ${t}\` instead.`),process.exit(1));let $=async()=>{let I=await c.send({type:"evaluate",code:`(() => {
|
|
958
980
|
const obs = window.__sootsimObservability;
|
|
959
981
|
if (!obs) return { ok: false };
|
|
960
982
|
return { ok: true, entries: obs.network.getSnapshot() };
|
|
961
|
-
})()`});if(!
|
|
962
|
-
`:` ${
|
|
963
|
-
`);for(let p of
|
|
964
|
-
`);let q=new Set,H=!0,U=()=>{H=!1};process.on("SIGINT",U);try{for(;H;){let
|
|
965
|
-
to target a specific sim, use \`--sim ${t}\` instead.`),process.exit(1));let F=()=>tt(c),q=
|
|
966
|
-
`);for(let
|
|
967
|
-
`);let H=new Set,U=!0,
|
|
983
|
+
})()`});if(!I||!I.ok)throw new Error("observability bridge not installed \u2014 is the engine running?");return I.entries??[]},F=I=>{let b=I;if(n&&(b=b.filter(p=>!!p.error||p.status!=null&&p.status>=400)),r&&(b=b.filter(p=>p.durationMs!=null&&p.durationMs>=u)),e){let p=e.toLowerCase();b=b.filter(P=>(P.displayUrl||P.url).toLowerCase().includes(p))}return r&&!m&&(b=[...b].sort((p,P)=>(P.durationMs??0)-(p.durationMs??0))),b};if(!m){let I=await $(),b=F(I).slice(-g);if(w){console.log(JSON.stringify(b,null,2));break}if(b.length===0){I.length===0?console.log(" no network requests captured"):console.log(r?` no requests slower than ${u}ms (${I.length} total \u2014 try --threshold <ms>)`:" no matching requests");break}console.log(r?` ${b.length} request(s) slower than ${u}ms (sorted by duration desc):
|
|
984
|
+
`:` ${b.length} request(s):
|
|
985
|
+
`);for(let p of b)Ot(p);break}console.log(` tailing network (ctrl-c to stop)...
|
|
986
|
+
`);let q=new Set,H=!0,U=()=>{H=!1};process.on("SIGINT",U);try{for(;H;){let I=await $(),b=F(I);for(let p of b)p.durationMs!=null&&(q.has(p.id)||(q.add(p.id),w?console.log(JSON.stringify(p)):Ot(p)));await X(250)}}finally{process.off("SIGINT",U)}break}case"logs":{let t=a[1],e=null,o=null,n=null,r=!1,u=!1,m=!1;for(let b=0;b<l.length;b++){let p=l[b];if(p==="--filter")e=l[b+1]??null,b++;else if(p==="--limit"){let P=Number(l[b+1]);Number.isFinite(P)&&(o=P),b++}else p==="--level"?(n=l[b+1]??null,b++):p==="--tail"||p==="-f"?r=!0:p==="--json"?u=!0:(p==="--internal"||p==="--all")&&(m=!0)}let w=n?new Set(n.split(",").map(b=>b.trim()).filter(b=>b==="log"||b==="info"||b==="warn"||b==="error"||b==="debug")):null;if(t==="clear"){await ot(c),console.log(" log buffer cleared");break}let g=!u&&process.stdout.isTTY===!0,$=o??(r?500:t?Number(t):50);Number.isFinite($)||(console.error(` invalid limit: ${t} \u2014 \`logs\` takes a numeric count (e.g. ${h("logs")} 100).
|
|
987
|
+
to target a specific sim, use \`--sim ${t}\` instead.`),process.exit(1));let F=()=>tt(c),q=b=>st(b,{level:w,filter:e,showInternal:m});if(!r){let b=await F(),p=q(b).slice(-$);if(u){console.log(JSON.stringify(p,null,2));break}if(p.length===0){console.log(b.length===0?" no logs captured":" no matching logs");break}console.log(` ${p.length} log(s):
|
|
988
|
+
`);for(let P of p)Rt(P,g);break}console.log(` tailing logs (ctrl-c to stop)...
|
|
989
|
+
`);let H=new Set,U=!0,I=()=>{U=!1};process.on("SIGINT",I);try{for(;U;){let b=await F(),p=q(b);for(let P of p)H.has(P.id)||(H.add(P.id),u?console.log(JSON.stringify(P)):Rt(P,g));await X(250)}}finally{process.off("SIGINT",I)}break}default:console.error(` unknown subcommand: ${y}`),process.exit(1)}if(ee.has(y)&&!s.includes("--no-wait")&&process.env.SOOTSIM_NO_AUTO_WAIT!=="1"&&await x(c),!j.has(y)&&!C(l))try{await oe(c)}catch{}}catch(t){let e=t instanceof Error?t.message:String(t);console.error(` ${y??"inspect"} failed: ${e}`);let o=/^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(o)await dt(c,N,o[1]);else if(/^no sim connected$/.test(e))ct(N);else if(n)process.stderr.write(` the sim is not responding. recover it with:
|
|
968
990
|
sootsim close --sim <id> # force-close the wedged sim
|
|
969
991
|
sootsim list # confirm it's gone
|
|
970
|
-
`);else{try{await je(c)}catch{}try{await
|
|
992
|
+
`);else{try{await je(c)}catch{}try{await O({includeTail:!0})}catch{}try{await Z({includeTail:!0})}catch{}}process.exit(1)}finally{c.close()}}export{Qs as runInspect};
|