sootsim 0.0.3 → 0.0.4
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 +7 -7
- package/dist-cli/chunks/{agent-D5NBV32O.js → agent-PJAOF4JS.js} +2 -2
- package/dist-cli/chunks/{agent-wrapper-Y7I5QGHM.js → agent-wrapper-STO7PLQD.js} +2 -2
- package/dist-cli/chunks/{assert-EJ7DQS2H.js → assert-P47NW4AF.js} +2 -2
- package/dist-cli/chunks/auto-bootstrap-SC2LMI2H.js +2 -0
- package/dist-cli/chunks/{chunk-44CBTM22.js → chunk-432TMHBG.js} +1 -1
- package/dist-cli/chunks/{chunk-BU3TZP4Y.js → chunk-47S5DXXX.js} +3 -3
- package/dist-cli/chunks/{chunk-5AG24UFX.js → chunk-4VXB2DBA.js} +1 -1
- package/dist-cli/chunks/{chunk-OG5CKIPC.js → chunk-4XBPZQLW.js} +2 -2
- package/dist-cli/chunks/{chunk-SUZR2SZZ.js → chunk-5TTQKPGH.js} +1 -1
- package/dist-cli/chunks/{chunk-VI3VW5BL.js → chunk-6SZMLFCR.js} +1 -1
- package/dist-cli/chunks/{chunk-AFTHIY3L.js → chunk-AFQBSK2J.js} +1 -1
- package/dist-cli/chunks/{chunk-X2W4IRXK.js → chunk-AUR2LTNX.js} +2 -2
- package/dist-cli/chunks/{chunk-NKJLTISU.js → chunk-BQRM4E66.js} +2 -2
- package/dist-cli/chunks/chunk-C3QLIYCS.js +16 -0
- package/dist-cli/chunks/{chunk-3K6VDPVD.js → chunk-DQKQYPIG.js} +2 -2
- package/dist-cli/chunks/{chunk-CQ6PX2EU.js → chunk-EHMSE3Q3.js} +1 -1
- package/dist-cli/chunks/chunk-F4ARVCRR.js +1 -0
- package/dist-cli/chunks/chunk-HAKR72LJ.js +2 -0
- package/dist-cli/chunks/chunk-HGFIS26A.js +2 -0
- package/dist-cli/chunks/{chunk-UZL5ZZ4E.js → chunk-I6XGFZPA.js} +2 -2
- package/dist-cli/chunks/{chunk-XJBPH4JR.js → chunk-MQDPKSCK.js} +3 -3
- package/dist-cli/chunks/chunk-MZPAJ5PQ.js +1 -0
- package/dist-cli/chunks/{chunk-REYWQVAH.js → chunk-OAHMYSMD.js} +1 -1
- package/dist-cli/chunks/{chunk-5IPP4HAW.js → chunk-QIP7LYQI.js} +2 -2
- package/dist-cli/chunks/{chunk-O2HBPZW5.js → chunk-QQOBLF7O.js} +2 -2
- package/dist-cli/chunks/{chunk-46LRF7PH.js → chunk-SY74J6F4.js} +1 -1
- package/dist-cli/chunks/{chunk-3SLEIN6B.js → chunk-UKYK63H6.js} +1 -1
- package/dist-cli/chunks/{chunk-BYLX2DO4.js → chunk-UNFERMZ3.js} +2 -2
- package/dist-cli/chunks/{chunk-FTRI7SVV.js → chunk-UQ3N6FZF.js} +2 -2
- package/dist-cli/chunks/{chunk-H3JVJXOC.js → chunk-VGXARPIH.js} +2 -2
- package/dist-cli/chunks/{chunk-EEBR5YP5.js → chunk-W3TYN64D.js} +2 -2
- package/dist-cli/chunks/{chunk-RLS6PHBW.js → chunk-W7CYWXRZ.js} +1 -1
- package/dist-cli/chunks/{chunk-EQ7G3UHS.js → chunk-WRF43M33.js} +1 -1
- package/dist-cli/chunks/{chunk-USRNDVQ3.js → chunk-WVBPATRA.js} +1 -1
- package/dist-cli/chunks/{chunk-P5C3UASK.js → chunk-WWDJCKMI.js} +1 -1
- package/dist-cli/chunks/{chunk-D4JFMCXD.js → chunk-XJF46GU2.js} +2 -2
- package/dist-cli/chunks/{chunk-2FPPPJE5.js → chunk-ZF5FCFLD.js} +2 -2
- package/dist-cli/chunks/chunk-ZKNI5MRD.js +1 -0
- package/dist-cli/chunks/{compat-5KSMOWLB.js → compat-ILLJ7VDL.js} +2 -2
- package/dist-cli/chunks/{config-NJB6PQHU.js → config-CDIAJIIT.js} +2 -2
- package/dist-cli/chunks/control-7QGKUCAX.js +2 -0
- package/dist-cli/chunks/{daemon-MLG65V4S.js → daemon-4BLYGM5N.js} +2 -2
- package/dist-cli/chunks/{debug-QVOBTTLP.js → debug-6SMCTPMC.js} +3 -3
- package/dist-cli/chunks/demo-app-registry-HLI5UGGI.js +2 -0
- package/dist-cli/chunks/{detox-ZZSNZL4T.js → detox-R4G5INNB.js} +2 -2
- package/dist-cli/chunks/{device-PQB3YGHN.js → device-YSLCWS4E.js} +2 -2
- package/dist-cli/chunks/drivers-YIXRFFBQ.js +2 -0
- package/dist-cli/chunks/{electron-JB26VHOO.js → electron-JZOFO37G.js} +3 -3
- package/dist-cli/chunks/flow-L7X5FGIN.js +2 -0
- package/dist-cli/chunks/{hints-IGYDXXDS.js → hints-O4QR6UGI.js} +2 -2
- package/dist-cli/chunks/{home-paths-CEGSGQTD.js → home-paths-4YJJYGR6.js} +2 -2
- package/dist-cli/chunks/{inspect-DSU6ELRM.js → inspect-DRFAUJUH.js} +29 -29
- package/dist-cli/chunks/{install-K6IJKADG.js → install-BATRTWRI.js} +2 -2
- package/dist-cli/chunks/{install-desktop-SC3LNFFF.js → install-desktop-6X474IQ3.js} +2 -2
- package/dist-cli/chunks/{install-dev-desktop-4DP3UY2X.js → install-dev-desktop-CAJHPRNP.js} +2 -2
- package/dist-cli/chunks/{keys-R5LAPAAL.js → keys-OWQ7SOTM.js} +2 -2
- package/dist-cli/chunks/{launch-K3WJV4QA.js → launch-WUEDHSO5.js} +3 -3
- package/dist-cli/chunks/{login-A23PYJAW.js → login-54YJ2KH6.js} +2 -2
- package/dist-cli/chunks/{logout-AJ24PH5O.js → logout-XECXLEXW.js} +2 -2
- package/dist-cli/chunks/{maestro-YALWKKGU.js → maestro-PMHK6EHI.js} +2 -2
- package/dist-cli/chunks/{preview-D35EEONY.js → preview-4RVHA2PP.js} +2 -2
- package/dist-cli/chunks/{profile-MAF7NM5Q.js → profile-3IVNHUS6.js} +2 -2
- package/dist-cli/chunks/{record-ZCPQNGFW.js → record-KEWLM5JR.js} +2 -2
- package/dist-cli/chunks/{runtime-Z2WIXYUN.js → runtime-PJKHEB36.js} +3 -3
- package/dist-cli/chunks/{screenshot-NQVZYC3C.js → screenshot-BXRAQERZ.js} +2 -2
- package/dist-cli/chunks/{screenshot-mode-E45D2ZFH.js → screenshot-mode-5IXEDIUS.js} +2 -2
- package/dist-cli/chunks/{screenshots-I4SQI4DA.js → screenshots-T4MQF3TB.js} +2 -2
- package/dist-cli/chunks/{server-ZUXKJRR5.js → server-CIP3LH45.js} +2 -2
- package/dist-cli/chunks/{skills-N4U63E5W.js → skills-DJA6QEVR.js} +2 -2
- package/dist-cli/chunks/store-SPC247DB.js +2 -0
- package/dist-cli/chunks/{test-VBD6N3AR.js → test-IWUHNFXV.js} +3 -3
- package/dist-cli/chunks/upload-UPD2RSYF.js +2 -0
- package/dist-cli/chunks/{whoami-4K6JGMWH.js → whoami-MCXFWKIH.js} +2 -2
- package/dist-lib/agent-daemon-client.cjs +1 -1
- package/dist-lib/agent-events.cjs +1 -1
- package/dist-lib/agent-sessions.cjs +1 -1
- package/dist-lib/attached-projects.cjs +1 -1
- package/dist-lib/auth/shared-session.cjs +1 -1
- package/dist-lib/backend-origin.cjs +1 -1
- package/dist-lib/bridge-constants.cjs +1 -1
- package/dist-lib/cli-constants.cjs +1 -1
- package/dist-lib/config.cjs +1 -1
- package/dist-lib/dev-bundle-resolution.cjs +1 -1
- package/dist-lib/home-paths.cjs +1 -1
- package/dist-lib/host/bridge-host.cjs +1 -1
- package/dist-lib/index.cjs +1 -1
- package/dist-lib/metro.cjs +1 -1
- package/dist-lib/render-mode.cjs +1 -1
- package/dist-lib/vite-base.cjs +1 -1
- package/dist-lib/vite.cjs +1 -1
- package/package.json +1 -1
- package/dist-cli/chunks/auto-bootstrap-Q7GNLISM.js +0 -2
- package/dist-cli/chunks/chunk-3WPAEUOO.js +0 -1
- package/dist-cli/chunks/chunk-4RYT6AQV.js +0 -16
- package/dist-cli/chunks/chunk-CPMW2QLM.js +0 -1
- package/dist-cli/chunks/chunk-LV5U7TI4.js +0 -1
- package/dist-cli/chunks/chunk-WUYJFYOW.js +0 -2
- package/dist-cli/chunks/chunk-ZSRMXBGK.js +0 -2
- package/dist-cli/chunks/control-2F3AGZAO.js +0 -2
- package/dist-cli/chunks/demo-app-registry-XRYNJ4GC.js +0 -2
- package/dist-cli/chunks/drivers-GWDQEGWD.js +0 -2
- package/dist-cli/chunks/flow-7JRQXMFV.js +0 -2
- package/dist-cli/chunks/store-4A6X4GBJ.js +0 -2
- package/dist-cli/chunks/upload-Y6FZ5XF2.js +0 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
/*! sootsim v0.0.
|
|
2
|
-
import{a as U}from"./chunk-
|
|
3
|
-
`)}function
|
|
1
|
+
/*! sootsim v0.0.4 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
|
+
import{a as U}from"./chunk-VGXARPIH.js";import{a as Ne,b as _e}from"./chunk-AFQBSK2J.js";import{a as Y,b as E,c as C,d as z,e as ie,f as V,g as te,h as Ie,i as Fe,j as fe}from"./chunk-UQ3N6FZF.js";import{a as Te,e as ae}from"./chunk-I6XGFZPA.js";import{a as me,c as pe,d as xe}from"./chunk-4VXB2DBA.js";import{b as Ae,h as Pe}from"./chunk-47S5DXXX.js";import"./chunk-OAHMYSMD.js";import{a as Me}from"./chunk-5TTQKPGH.js";import"./chunk-WVBPATRA.js";import{a as we}from"./chunk-HGFIS26A.js";import{c as $e,e as Se,f as ke,h as ve}from"./chunk-C3QLIYCS.js";import"./chunk-W7CYWXRZ.js";import"./chunk-MZPAJ5PQ.js";import"./chunk-WRF43M33.js";import"./chunk-ZF5FCFLD.js";import"./chunk-SY74J6F4.js";import"./chunk-WWDJCKMI.js";import{existsSync as mt,mkdirSync as pt,readFileSync as ft,rmSync as Oe,writeFileSync as gt}from"fs";import{tmpdir as yt}from"os";import{dirname as bt,join as ht,resolve as wt}from"path";var oe=1,xt="SOOTSIM_INSPECT_NOTICE_PATH",$t=300*1e3,St=15e3;function Ee(){return wt(process.env[xt]||ht(yt(),"sootsim-inspect-notice-state.json"))}function kt(o,c){return Object.fromEntries(Object.entries(o).filter(([,i])=>typeof i?.signature=="string"&&Number.isFinite(i?.updatedAt)&&c-i.updatedAt<=$t))}function vt(o){let c=Ee();if(!mt(c))return{version:oe,entries:{}};try{let i=JSON.parse(ft(c,"utf8"));return i.version!==oe||!i.entries||typeof i.entries!="object"?(Oe(c,{force:!0}),{version:oe,entries:{}}):{version:oe,entries:kt(i.entries,o)}}catch{return Oe(c,{force:!0}),{version:oe,entries:{}}}}function Tt(o){let c=Ee();pt(bt(c),{recursive:!0}),gt(c,JSON.stringify(o,null,2)+`
|
|
3
|
+
`)}function Mt(o,c){let i=c.trim()||"default";return`${o}:${i}`}function ge(o,c,i,d={}){let u=d.nowMs??Date.now(),a=d.cooldownMs??St,b=vt(u),k=Mt(o,c),$=b.entries[k];return $&&$.signature===i&&u-$.updatedAt<a?!1:(b.entries[k]={signature:i,updatedAt:u},Tt(b),!0)}async function Re(o,c={args:[]}){let i=await o.send({type:"evaluate",code:"(async () => await window.__sootsimTest.getNodeCount())()"}),d=typeof i=="number"?i:0;if(E(c.args)){C({nodes:d});return}console.log(` nodes: ${d}`)}function ye(o,c){let i=o.indexOf(c);return i>=0&&i+1<o.length?o[i+1]:null}async function Ce(o){let{bridge:c,args:i,positional:d}=o,u=i.includes("--verbose")||i.includes("-v"),a=E(i),b=u&&!a,k=i.includes("--watch")||i.includes("-w"),$=1e3,I=i.includes("--compact"),y=i.includes("--no-xy"),S=ye(i,"--testid-like"),A=ye(i,"--only"),v=ye(i,"--subtree"),j=d[1],l=j?/[*?]/.test(j):!1,R=!l&&!A?j:void 0,D=A??(l?j:void 0),q=async()=>{await ie(c,{verbose:b});let Z=`(async () => {
|
|
4
4
|
const t = window.__sootsimTest
|
|
5
5
|
const mainShell = window.SootSim?.bridges?.mainShell
|
|
6
6
|
const kb = window.__sootsimKeyboard
|
|
@@ -18,7 +18,7 @@ import{a as U}from"./chunk-H3JVJXOC.js";import{a as Ne,b as _e}from"./chunk-AFTH
|
|
|
18
18
|
})()`,x=await c.send({type:"evaluate",code:Z}),J=x?.tree,H=x?.shell,K=x?.keyboard;if(a){C({shell:H,tree:J??"",keyboard:K});return}if(H&&typeof H=="object"){let e=[H.state?`state=${H.state}`:null,H.activeApp?`app=${H.activeApp}`:null,H.showSwitcher?"switcher":null,H.switcherPhase&&H.switcherPhase!=="idle"?`phase=${H.switcherPhase}`:null].filter(Boolean);e.length>0&&console.log(` shell: ${e.join(" ")}`)}if(typeof J=="string"&&J.startsWith("__SUBTREE_NOT_FOUND__:")){let e=J.slice(22);console.log(` subtree root not found: ${e}`),U("subtree-root-not-found",e);return}if(!J){let e=x?.nodeCount??0;console.log(" no matching nodes found"),!(R||S||D||v)&&e<10&&U("app-still-loading",e);return}if(console.log(J),!(R||S||D||v)&&!k&&J.split(`
|
|
19
19
|
`).length>=80&&U("describe-use-filters"),K&&K.visible){let e=K.spec,t=[e?.keyboardType?`type=${e.keyboardType}`:null,e?.returnKeyType&&e.returnKeyType!=="default"?`return=${e.returnKeyType}`:null,K.mode!=="letters"?`mode=${K.mode}`:null,K.shifted?"shift":null,K.capsLock?"caps":null,e?.autoCapitalize&&e.autoCapitalize!=="sentences"?`autoCap=${e.autoCapitalize}`:null,K.accessoryBarId?`accessory=${K.accessoryBarId}`:null].filter(Boolean);console.log(`
|
|
20
20
|
keyboard: ${t.join(" ")||"visible"}`)}};if(k)for(console.log(` watching... (Ctrl+C to stop)
|
|
21
|
-
`);;)console.clear(),await q(),await Y($);else await q()}var
|
|
21
|
+
`);;)console.clear(),await q(),await Y($);else await q()}var Nt=["SOOTSIM_AGENT","CLAUDECODE","CLAUDE_CODE_ENTRYPOINT","CLAUDE_CODE_SESSION_ID","CODEX_THREAD_ID","CURSOR_TRACE_ID","AIDER_MODEL"];function De(){if(process.env.SOOTSIM_AGENT==="0")return!1;for(let o of Nt){let c=process.env[o];if(c&&c.trim()&&c!=="0")return!0}return!1}async function Le(o){let{bridge:c,args:i,effectiveArgs:d,positional:u,inspectUsage:a}=o,b=x=>{let J=d.indexOf(x);return J>=0&&J+1<d.length?d[J+1]:null},k=x=>d.includes(x),$=b("--testid")||b("--test-id"),I=b("--role"),y=b("--type"),S=b("--text"),A=k("--pressable"),v=k("--visible"),j=!$&&!I&&!y&&!S&&!A&&!v?u[1]:null,l=S??j,R,D;$?(D="testid",R=`(async () => {
|
|
22
22
|
const t = window.__sootsimTest
|
|
23
23
|
return (await t.findByTestId(${JSON.stringify($)})) || (await t.findById(${JSON.stringify($)}))
|
|
24
24
|
})()`):I?(D="role",R=`(async () => await window.__sootsimTest.queryAll({ hasRole: ${JSON.stringify(I)}, pruneHidden: true }))()`):y?(D="type",R=`(async () => await window.__sootsimTest.queryAll({ type: ${JSON.stringify(y)}, pruneHidden: true }))()`):A?(D="pressable",R=`(async () => {
|
|
@@ -28,16 +28,16 @@ import{a as U}from"./chunk-H3JVJXOC.js";import{a as Ne,b as _e}from"./chunk-AFTH
|
|
|
28
28
|
})()`):v?(D="visible",R=`(async () => {
|
|
29
29
|
const all = await window.__sootsimTest.queryAll({ pruneHidden: true })
|
|
30
30
|
return all.filter(n => n.layout && n.layout.width > 0 && n.layout.height > 0)
|
|
31
|
-
})()`):l?(D="text",R=`(async () => await window.__sootsimTest.findByText(${JSON.stringify(l)}))()`):(console.error(a("find","<text> | --text <t> | --testid <id> | --role <r> | --type <t> | --pressable | --visible")),process.exit(1));let q=await c.send({type:"evaluate",code:R}),ne=E(i),Z=i.includes("--verbose")||i.includes("--dump");if(ne)C(q??null);else if(Array.isArray(q))if(q.length===0){console.log(` no ${D} nodes found`);let x=await c.send({type:"evaluate",code:"(async () => (await window.__sootsimTest?.getNodeCount?.()) || 0)()"});typeof x=="number"&&x<10&&U("app-still-loading",x)}else{console.log(` found ${q.length} node${q.length===1?"":"s"} (${D}):`);for(let x of q.slice(0,20)){let J=x.absolutePosition?`@(${Math.round(x.absolutePosition.x)},${Math.round(x.absolutePosition.y)})`:"",H=x.layout?`${Math.round(x.layout.width)}x${Math.round(x.layout.height)}`:"?x?",K=x.text?` "${x.text.slice(0,30)}"`:"",Q=x.testID?` #${x.testID}`:"",e=x.pressable?" (tap)":"",t=x.accessibilityRole?`[${x.accessibilityRole}]`:x.type;console.log(` ${t}${K}${Q} ${H} ${J}${e}`),Z&&console.log(
|
|
31
|
+
})()`):l?(D="text",R=`(async () => await window.__sootsimTest.findByText(${JSON.stringify(l)}))()`):(console.error(a("find","<text> | --text <t> | --testid <id> | --role <r> | --type <t> | --pressable | --visible")),process.exit(1));let q=await c.send({type:"evaluate",code:R}),ne=E(i),Z=i.includes("--verbose")||i.includes("--dump");if(ne)C(q??null);else if(Array.isArray(q))if(q.length===0){console.log(` no ${D} nodes found`);let x=await c.send({type:"evaluate",code:"(async () => (await window.__sootsimTest?.getNodeCount?.()) || 0)()"});typeof x=="number"&&x<10&&U("app-still-loading",x)}else{console.log(` found ${q.length} node${q.length===1?"":"s"} (${D}):`);for(let x of q.slice(0,20)){let J=x.absolutePosition?`@(${Math.round(x.absolutePosition.x)},${Math.round(x.absolutePosition.y)})`:"",H=x.layout?`${Math.round(x.layout.width)}x${Math.round(x.layout.height)}`:"?x?",K=x.text?` "${x.text.slice(0,30)}"`:"",Q=x.testID?` #${x.testID}`:"",e=x.pressable?" (tap)":"",t=x.accessibilityRole?`[${x.accessibilityRole}]`:x.type;console.log(` ${t}${K}${Q} ${H} ${J}${e}`),Z&&console.log(Be(JSON.stringify(x,null,2)," "))}q.length>20&&console.log(` ... and ${q.length-20} more`)}else if(q==null)console.log(` not found: ${l||$||I||y||""||D}`),$&&U("wait-selector-for-missing-testid",$);else{let x=q;if(x.type&&x.absolutePosition){let J=`@(${Math.round(x.absolutePosition.x)},${Math.round(x.absolutePosition.y)})`,H=x.layout?`${Math.round(x.layout.width)}x${Math.round(x.layout.height)}`:"?x?",K=x.text?` "${x.text.slice(0,40)}"`:"",Q=x.testID?` #${x.testID}`:"",e=x.pressable?" (tap)":"",t=x.accessibilityRole?`[${x.accessibilityRole}]`:x.type;console.log(` ${t}${K}${Q} ${H} ${J}${e}`),Z&&console.log(Be(JSON.stringify(x,null,2)," "))}else console.log(JSON.stringify(q,null,2))}}function Be(o,c){return o.split(`
|
|
32
32
|
`).map(i=>c+i).join(`
|
|
33
|
-
`)}async function
|
|
33
|
+
`)}async function je(o,c={}){let i=await o.send({type:"evaluate",code:`(() => {
|
|
34
34
|
const kb = window.__sootsimKeyboard
|
|
35
35
|
if (!kb || typeof kb.getLayout !== 'function') {
|
|
36
36
|
return { error: 'keyboard bridge getLayout() not available' }
|
|
37
37
|
}
|
|
38
38
|
return kb.getLayout()
|
|
39
39
|
})()`});if("error"in i&&(console.error(i.error),process.exit(1)),c.json){console.log(JSON.stringify(i,null,2));return}let{visible:d,spec:u,mode:a,shifted:b,capsLock:k,accessoryBarId:$}=i,I=[];I.push(`keyboard: ${d?"visible":"hidden"}`),u?(I.push(` type: ${u.keyboardType}`),I.push(` returnKey: ${u.returnKeyType}`),I.push(` autoCap: ${u.autoCapitalize}`),I.push(` autoCorrect: ${u.autoCorrect?"on":"off"}`),I.push(` appearance: ${u.keyboardAppearance}`),u.secureTextEntry&&I.push(" secureTextEntry: true"),u.enablesReturnKeyAutomatically&&I.push(` return: ${u.currentTextIsEmpty?"disabled (empty)":"enabled"}`)):I.push(" spec: <none> (shown via dev-tools with no TextInput)"),I.push(` mode: ${a}${b?" (shifted)":""}${k?" (caps)":""}`),$&&I.push(` accessoryBar: ${$}`),console.log(I.join(`
|
|
40
|
-
`))}async function
|
|
40
|
+
`))}async function Je(o){let c=await o.bridge.listBrowsers();if(E(o.args)){C(c.map(i=>({...i,active:i.id===o.browserId})));return}Pe(c,o.browserId)}function X(o){return o<1024?`${o}B`:o<1024*1024?`${(o/1024).toFixed(1)}KB`:`${(o/1024/1024).toFixed(1)}MB`}function le(o,c){return c<=0?"?":`${(o/c*100).toFixed(0)}%`}async function He(o,c={args:[]}){let d=await o.send({type:"evaluate",code:`(async () => {
|
|
41
41
|
const host = window.__sootsimRenderHost
|
|
42
42
|
const stats = host?.queryStats ? await host.queryStats() : null
|
|
43
43
|
const hostMem = performance.memory
|
|
@@ -70,7 +70,7 @@ import{a as U}from"./chunk-H3JVJXOC.js";import{a as Ne,b as _e}from"./chunk-AFTH
|
|
|
70
70
|
? resolved.cy
|
|
71
71
|
: n.absolutePosition.y + (n.layout.height || 0) / 2
|
|
72
72
|
return { x: cx, y: cy, testID: n.testID, text: n.text }
|
|
73
|
-
})()`})??null}async function
|
|
73
|
+
})()`})??null}async function qe(o,c={}){let i=await o.send({type:"evaluate",code:`(async () => {
|
|
74
74
|
const test = window.__sootsimTest
|
|
75
75
|
const kb = window.__sootsimKeyboard
|
|
76
76
|
const navSnap =
|
|
@@ -144,7 +144,7 @@ import{a as U}from"./chunk-H3JVJXOC.js";import{a as Ne,b as _e}from"./chunk-AFTH
|
|
|
144
144
|
await sleep(pollMs)
|
|
145
145
|
}
|
|
146
146
|
return { settled: false, elapsed: Date.now() - start }
|
|
147
|
-
})()`}),{elapsed:b,settled:k}=a??{};return{elapsed:typeof b=="number"?b:c,settled:k===!0}}async function
|
|
147
|
+
})()`}),{elapsed:b,settled:k}=a??{};return{elapsed:typeof b=="number"?b:c,settled:k===!0}}async function We(o){let{bridge:c,args:i,positional:d}=o,u=d[1]?Number(d[1])*1e3:3e3,a=i.includes("--strict"),{elapsed:b,settled:k}=await ee({bridge:c,maxMs:u,strict:a});console.log(k?` settled in ${b}ms`:` timed out after ${b}ms (may still be animating)`)}async function ze(o){let c=o.positional[1]?Number(o.positional[1]):.5;(!Number.isFinite(c)||c<0)&&(console.error(o.inspectUsage("sleep","[seconds]")),process.exit(1)),await Y(c*1e3),console.log(` slept ${c}s`)}async function Ke(o){let{bridge:c,args:i,positional:d}=o,u=d[1]?Number(d[1]):5,a=await c.send({type:"evaluate",code:`(async () => await window.__sootsimTest.dumpTree(${u}))()`});if(E(i)){C({depth:u,tree:a??null});return}console.log(typeof a=="string"?a:JSON.stringify(a,null,2))}async function Ue(o,c={args:[]}){let i=await o.send({type:"evaluate",code:"window.location.href"}),d=typeof i=="string"?i:"";if(E(c.args)){C({url:d});return}console.log(d)}async function Ye(o){let{wsPort:c,commandTimeoutMs:i,browserId:d,positional:u}=o,a=u[1]?Number(u[1]):30,b=Math.max(1e3,(Number.isFinite(a)?a:30)*1e3),k=Math.max(1,Math.ceil(b/500));console.log(" waiting for browser reconnect...");let $=await Ie(c,i,d,{attempts:k});$||(console.error(" timed out waiting for browser reconnect"),process.exit(1)),$.bridge.close(),ae({source:"inspect wait",step:{wait:b},summary:`wait ${Math.round(b/1e3)}s`}),console.log(` ready: ${$.count} nodes`)}async function Ge(o){let{bridge:c,args:i}=o,d=i.includes("--strict"),u=i.indexOf("--max-ms"),a=u>=0&&i[u+1]?Math.max(100,Number(i[u+1])):3e3,{elapsed:b,settled:k}=await ee({bridge:c,maxMs:a,strict:d});k?console.log(` idle in ${b}ms`):(console.error(` \u26A0 wait idle timed out after ${b}ms (may still be animating)`),process.exit(1))}async function Xe(o){let{bridge:c,args:i}=o,d=2e4,u=i.indexOf("--max-ms");u>=0&&i[u+1]&&(d=Math.max(100,Number(i[u+1])));let a=Date.now(),b=a+d,k=`(async () => {
|
|
148
148
|
const t = window.__sootsimTest
|
|
149
149
|
let nodes = 0
|
|
150
150
|
try { nodes = (await t?.getNodeCount?.()) || 0 } catch {}
|
|
@@ -153,7 +153,7 @@ import{a as U}from"./chunk-H3JVJXOC.js";import{a as Ne,b as _e}from"./chunk-AFTH
|
|
|
153
153
|
at: (window).__sootsimExternalAppReadyAt || 0,
|
|
154
154
|
nodes,
|
|
155
155
|
}
|
|
156
|
-
})()`,$={flag:void 0,at:0,nodes:0};for(;Date.now()<b;){try{$=await c.send({type:"evaluate",code:k})??$}catch{}if($.flag===!0){console.log(` ready in ${Date.now()-a}ms: ${$.nodes} nodes (flag)`);return}await new Promise(I=>setTimeout(I,150))}console.error(` \u26A0 wait ready timed out after ${Date.now()-a}ms \u2014 guest app did not emit sootsim:externalAppReady (nodes: ${$.nodes})`),process.exit(1)}async function
|
|
156
|
+
})()`,$={flag:void 0,at:0,nodes:0};for(;Date.now()<b;){try{$=await c.send({type:"evaluate",code:k})??$}catch{}if($.flag===!0){console.log(` ready in ${Date.now()-a}ms: ${$.nodes} nodes (flag)`);return}await new Promise(I=>setTimeout(I,150))}console.error(` \u26A0 wait ready timed out after ${Date.now()-a}ms \u2014 guest app did not emit sootsim:externalAppReady (nodes: ${$.nodes})`),process.exit(1)}async function Ve(o){let{bridge:c,args:i,positional:d,inspectUsage:u}=o,a=d[1];a||(console.error(u("wait selector","<testid> [--max-ms 5000]")),process.exit(1));let b=i.indexOf("--max-ms"),k=b>=0&&i[b+1]?Math.max(100,Number(i[b+1])):5e3,$=await c.send({type:"evaluate",code:`(async () => {
|
|
157
157
|
const start = Date.now()
|
|
158
158
|
const deadline = start + ${k}
|
|
159
159
|
const t = window.__sootsimTest
|
|
@@ -172,8 +172,8 @@ import{a as U}from"./chunk-H3JVJXOC.js";import{a as Ne,b as _e}from"./chunk-AFTH
|
|
|
172
172
|
await new Promise((r) => setTimeout(r, 80))
|
|
173
173
|
}
|
|
174
174
|
return { found: false, elapsed: Date.now() - start }
|
|
175
|
-
})()`}),{found:I,node:y,elapsed:S}=$??{};if(I&&y){let A=y.absolutePosition?`@(${Math.round(y.absolutePosition.x)},${Math.round(y.absolutePosition.y)})`:"",v=y.layout?`${Math.round(y.layout.width)}x${Math.round(y.layout.height)}`:"?x?";console.log(` found #${a} in ${S}ms ${v} ${A}`)}else console.error(` \u26A0 wait selector #${a} timed out after ${S??k}ms`),process.exit(1)}function
|
|
176
|
-
`).slice(0,5);for(let b of a)console.log(` ${b.trim()}`)}}var G="__sootsimCliPerf",
|
|
175
|
+
})()`}),{found:I,node:y,elapsed:S}=$??{};if(I&&y){let A=y.absolutePosition?`@(${Math.round(y.absolutePosition.x)},${Math.round(y.absolutePosition.y)})`:"",v=y.layout?`${Math.round(y.layout.width)}x${Math.round(y.layout.height)}`:"?x?";console.log(` found #${a} in ${S}ms ${v} ${A}`)}else console.error(` \u26A0 wait selector #${a} timed out after ${S??k}ms`),process.exit(1)}function nt(o){return o==null?"\u2014":o<1024?`${o}B`:o<1024*1024?`${(o/1024).toFixed(1)}K`:`${(o/1024/1024).toFixed(1)}M`}function rt(o){return o==null?" \u2026":o<1e3?`${o}ms`.padStart(5):`${(o/1e3).toFixed(2)}s`.padStart(5)}function It(o){return o.error?"err":o.status==null?" \u2026 ":String(o.status)}function Ze(o){let c=new Date(o.startTs).toLocaleTimeString(),i=It(o).padEnd(3),d=o.method.padEnd(5),u=nt(o.size).padStart(6),a=rt(o.durationMs);console.log(` [${c}] ${i} ${d} ${u} ${a} ${o.displayUrl}`),o.error&&console.log(` error: ${o.error}`)}function Ft(o){let c=[["id",o.id],["source",o.source],["kind",o.kind],["method",o.method],["status",o.error?`error: ${o.error}`:`${o.status??"\u2014"} ${o.statusText??""}`.trim()],["url",o.url],["started",new Date(o.startTs).toLocaleTimeString()],["duration",rt(o.durationMs).trim()],["size",nt(o.size)],["content-type",o.type??"\u2014"]];for(let[i,d]of c)console.log(` ${i.padEnd(13)} ${d}`)}var At={error:"\x1B[31m",warn:"\x1B[33m",info:"\x1B[36m",debug:"\x1B[35m",log:"\x1B[37m"},Qe="\x1B[0m",Pt="\x1B[2m";function et(o,c){let i=new Date(o.ts).toLocaleTimeString(),d=o.level.toUpperCase().padEnd(5),u=o.args.join(" ");if(c){let a=At[o.level];console.log(` ${Pt}[${i}]${Qe} ${a}${d}${Qe} ${u}`)}else console.log(` [${i}] ${d} ${u}`);if(o.stack&&o.level==="error"){let a=o.stack.split(`
|
|
176
|
+
`).slice(0,5);for(let b of a)console.log(` ${b.trim()}`)}}var G="__sootsimCliPerf",Ot=120;async function tt(o,c){let i=o.find((A,v)=>o[v-1]==="--id"),d=o.find((A,v)=>o[v-1]==="--text");if(i||d){let A=await c.send({type:"evaluate",code:Ne({id:i,text:d})});if(!A)throw new Error(i?`no node with id "${i}"`:`no node matching text "${d}"`);let{x:v,y:j,w:l,h:R}=A;return{x:v,y:j,w:l,h:R}}let u=o.find((A,v)=>o[v-1]==="--area");if(u){let A=u.split(",").map(D=>Number(D.trim()));if(A.length!==4||A.some(D=>!Number.isFinite(D)))throw new Error(`--area expects x,y,w,h (got "${u}")`);let[v,j,l,R]=A;return{x:v,y:j,w:l,h:R}}let a=A=>{let v=o.find((l,R)=>o[R-1]===A);if(v==null)return null;let j=Number(v);return Number.isFinite(j)?j:null},b=a("--x"),k=a("--y"),$=a("--w"),I=a("--h");if(b!=null||k!=null||$!=null||I!=null)return{x:b??0,y:k??0,w:$??1,h:I??1};let S=o.filter((A,v)=>v>0&&!A.startsWith("-")&&o[v-1]!=="--output"&&o[v-1]!=="--area"&&o[v-1]!=="--id"&&o[v-1]!=="--text"&&o[v-1]!=="--x"&&o[v-1]!=="--y"&&o[v-1]!=="--w"&&o[v-1]!=="--h").map(Number).filter(A=>Number.isFinite(A));if(S.length>=2){let[A,v,j=1,l=1]=S;return{x:A,y:v,w:j,h:l}}return null}function be(o){let c={"<8":0,"8-12":0,"12-16":0,"16-20":0,"20-33":0,">33":0};for(let i of o)i<8?c["<8"]++:i<12?c["8-12"]++:i<16?c["12-16"]++:i<20?c["16-20"]++:i<33?c["20-33"]++:c[">33"]++;console.log(" histogram:");for(let[i,d]of Object.entries(c)){let u="\u2588".repeat(Math.ceil(d/o.length*40));console.log(` ${i.padEnd(6)} ${u} ${d}`)}}async function de(o,c,i){let d=Date.now()+c,u=await V(o,c);for(;;){if(i(u))return{settled:!0,state:u};if(Date.now()>=d)return{settled:!1,state:u};await Y(16),u=await V(o)}}async function he(o){return o.send({type:"evaluate",code:`(async () => {
|
|
177
177
|
const kb = window.__sootsimKeyboard
|
|
178
178
|
const test = window.__sootsimTest
|
|
179
179
|
if (!kb) return { error: 'keyboard bridge not available' }
|
|
@@ -205,7 +205,7 @@ import{a as U}from"./chunk-H3JVJXOC.js";import{a as Ne,b as _e}from"./chunk-AFTH
|
|
|
205
205
|
frame: runtimeSnapshot?.keyboard?.frame ?? null,
|
|
206
206
|
focusedRect: runtimeSnapshot?.focused?.rect ?? null,
|
|
207
207
|
}
|
|
208
|
-
})()`})}async function
|
|
208
|
+
})()`})}async function Et(o,c=600){let i=Date.now()+c;for(;Date.now()<=i;){let d=await he(o);if(d.visible)return d;await Y(30)}return he(o)}async function ue(o,c){let i=await he(o);if(i.visible)return i;console.error(` ${c} requires the iOS keyboard to be visible. focus an input first with sootsim do tap-id/tap-text or sootsim do type-into.`),process.exit(1)}async function ot(o,c,i){return c==="appearance"?o.send({type:"evaluate",code:`(async () => {
|
|
209
209
|
const requested = ${JSON.stringify(i??"toggle")}
|
|
210
210
|
const rootBg = (document.documentElement?.style?.background || '').toLowerCase()
|
|
211
211
|
const inferredCurrent = rootBg.includes('33') ? 'dark' : 'light'
|
|
@@ -220,15 +220,15 @@ import{a as U}from"./chunk-H3JVJXOC.js";import{a as Ne,b as _e}from"./chunk-AFTH
|
|
|
220
220
|
})()`}):o.send({type:"evaluate",code:`(async () => {
|
|
221
221
|
window.dispatchEvent(new CustomEvent(${JSON.stringify(c==="lock"?"sootsim:toggleLock":"sootsim:shake")}))
|
|
222
222
|
return { ok: true, action: ${JSON.stringify(c)} }
|
|
223
|
-
})()`})}function
|
|
223
|
+
})()`})}function Rt(o){let c={Enter:"return",NumpadEnter:"return",Backspace:"delete",Delete:"delete",Space:"space",ShiftLeft:"shift",ShiftRight:"shift"};if(c[o])return c[o];let i=o.match(/^Digit([0-9])$/);if(i)return i[1];let d=o.match(/^Key([A-Z])$/);return d?d[1].toLowerCase():null}function Ct(o){if(typeof o!="string")return null;let c=o.replace(/\s+/g," ").trim();return c?c.slice(0,80):null}function at(...o){for(let c of o){if(typeof c!="string")continue;let i=c.trim();if(i)return i}return null}async function L(o,c,i){ae({source:o,step:c,summary:i})}function Dt(o,c,i){if(!i||i.hit===!1)return null;let d=at(i.responderTestID,i.testID);if(d)return{step:{tapOn:{id:d}},summary:`tap #${d}`};let u=Ct(i.text);return u?{step:{tapOn:u},summary:`tap "${u}"`}:{step:{tapAtCoords:{x:o,y:c}},summary:`tap @${Math.round(o)},${Math.round(c)}`}}function st(o,c,i){let d=at(c?.testID,c?.id);return d?{step:{tapOn:{id:d}},summary:`tap #${d}`}:i==="id"?{step:{tapOn:{id:o}},summary:`tap #${o}`}:{step:{tapOn:o},summary:`tap "${o}"`}}async function rs(o,c){let i=o[0]==="get"||o[0]==="do"||o[0]==="debug"||o[0]==="wait"?o[0]:null,d=i?o.slice(1):o,u=$e(d,{port:c.port,commandTimeoutMs:c.timeoutMs,stripBooleanFlags:["--verbose","-v","--help","-h","--clear-state","--json","--all","--watch","-w","--strict","--no-wait","--dump","--failed","--tail","-f","--internal"],stripValueFlags:["--output","--nth","--index","--testid","--test-id","--text","--max-ms","--filter","--limit","--level"]}),a=u.positional,b=a[0],k=i==="get"||i==="do"||i==="debug"||i==="wait"?i:"inspect",$=typeof d[0]=="string"&&xe.has(d[0]),I=$?d[0]:null,y=e=>$&&e===d[0]?`sootsim ${e}`:`sootsim ${k} ${e}`,S=(e,t)=>` usage: ${y(e)}${t?` ${t}`:""}`;if(!b||o.includes("--help")||o.includes("-h")){let e={bridgePort:7668,defaultShellUrl:we};if(k==="do"||k==="get"||k==="debug"||k==="wait"){let r=me(k,e);r&&(console.log(`${r}
|
|
224
224
|
`),process.exit(0))}if(I==="shell"){let r=pe("shell",e);r&&(console.log(`${r}
|
|
225
225
|
`),process.exit(0))}let t=pe("inspect",e),s=["do","get","debug","wait"].map(r=>me(r,e)).filter(r=>r!=null).join(`
|
|
226
226
|
|
|
227
227
|
`);console.log(`${t??""}
|
|
228
228
|
|
|
229
229
|
${s}
|
|
230
|
-
`),process.exit(0)}let A=u.wsPort,v=u.browserId,j=u.commandTimeoutMs;if(b==="list"&&d.some(e=>e==="--drivers"||e==="-D")){let{buildDriverListRows:e}=await import("./drivers-
|
|
231
|
-
`);let s=Math.max(...t.map(n=>n.id.length),6),r=Math.max(...t.map(n=>n.kind.length),4);for(let n of t){let m=n.available?"\u2713":"\u2717",p=n.id.padEnd(s),h=n.kind.padEnd(r);console.log(` ${m} ${p} ${h} ${n.description}`),n.available&&n.detail?console.log(` ${n.detail}`):!n.available&&n.reason&&console.log(` unavailable: ${n.reason}`)}return}let l=Se(u),R=v||"default",D=new Set(["errors","warnings","requests","js","eval","reload","globals","perf","list","wait","sleep"]);function q(e){let t=e.displayUrl||e.url;return e.status!=null?`${e.method} ${t} -> ${e.status}${e.statusText?` ${e.statusText}`:""}`:e.error?`${e.method} ${t} -> ${e.error}`:`${e.method} ${t}`}async function ne(e){let t=
|
|
230
|
+
`),process.exit(0)}let A=u.wsPort,v=u.browserId,j=u.commandTimeoutMs;if(b==="list"&&d.some(e=>e==="--drivers"||e==="-D")){let{buildDriverListRows:e}=await import("./drivers-YIXRFFBQ.js"),t=e();console.log(` available drivers (${t.length}):
|
|
231
|
+
`);let s=Math.max(...t.map(n=>n.id.length),6),r=Math.max(...t.map(n=>n.kind.length),4);for(let n of t){let m=n.available?"\u2713":"\u2717",p=n.id.padEnd(s),h=n.kind.padEnd(r);console.log(` ${m} ${p} ${h} ${n.description}`),n.available&&n.detail?console.log(` ${n.detail}`):!n.available&&n.reason&&console.log(` unavailable: ${n.reason}`)}return}let l=Se(u),R=v||"default",D=new Set(["errors","warnings","requests","js","eval","reload","globals","perf","list","wait","sleep"]);function q(e){let t=e.displayUrl||e.url;return e.status!=null?`${e.method} ${t} -> ${e.status}${e.statusText?` ${e.statusText}`:""}`:e.error?`${e.method} ${t} -> ${e.error}`:`${e.method} ${t}`}async function ne(e){let t=De()?1200:350;try{let{settled:s,elapsed:r}=await ee({bridge:e,maxMs:t,pollMs:32,stablePolls:2});s||process.stderr.write(` \u26A0 auto-wait timed out after ${r??t}ms \u2014 next command may see mid-animation state. use \`sootsim do settle\` for a longer wait.
|
|
232
232
|
`)}catch{}}async function Z(){try{return await l.send({type:"evaluate",code:`(() => ({
|
|
233
233
|
console: window.__sootsimConsole?.count?.() || null,
|
|
234
234
|
requests: window.__sootsimTest?.getRequestCounts?.() || null,
|
|
@@ -238,7 +238,7 @@ ${s}
|
|
|
238
238
|
`);for(let n of r){let m=new Date(n.timestamp).toLocaleTimeString();console.log(` [${m}] ${q(n)}`),n.responseBody?console.log(` ${n.responseBody}`):n.error&&console.log(` ${n.error}`)}}}async function J(e={}){let t=e.counts!==void 0?e.counts:await l.send({type:"evaluate",code:"window.__sootsimConsole?.count?.() || { errors: 0, warnings: 0, total: 0 }"});if(!t||typeof t!="object")return;let s=t,r=Math.max(0,Number(s.errors)||0),n=Math.max(0,Number(s.warnings)||0);if(r===0&&n===0||!e.includeTail&&!ge("console",R,`${r}:${n}`))return;let m=[];if(r>0&&m.push(`${r} console error${r===1?"":"s"}`),n>0&&m.push(`${n} console warning${n===1?"":"s"}`),console.log(`
|
|
239
239
|
console: ${m.join(", ")}`),console.log(` inspect: ${y("errors")} 5`),n>0&&console.log(` inspect: ${y("warnings")} 5`),!e.includeTail||r===0)return;let p=await l.send({type:"evaluate",code:"window.__sootsimConsole?.getErrors?.(5) || []"});if(!(!Array.isArray(p)||p.length===0)){console.log(`
|
|
240
240
|
recent console errors:
|
|
241
|
-
`);for(let h of p){let f=new Date(h.timestamp).toLocaleTimeString(),w=Array.isArray(h.args)?h.args.map(O=>typeof O=="object"?JSON.stringify(O):String(O)).join(" "):String(h);console.log(` [${f}] ${w}`)}}}let H=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"]),K=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"]),Q=(o.includes("--verbose")||o.includes("-v"))&&!o.includes("--json");k==="do"&&b==="shell"&&(console.error(" `sootsim do shell` was removed. use `sootsim shell ...` instead."),process.exit(1)),H.has(b)&&await ke(l),K.has(b)&&await ie(l,{verbose:Q});try{switch(b){case"list":{await
|
|
241
|
+
`);for(let h of p){let f=new Date(h.timestamp).toLocaleTimeString(),w=Array.isArray(h.args)?h.args.map(O=>typeof O=="object"?JSON.stringify(O):String(O)).join(" "):String(h);console.log(` [${f}] ${w}`)}}}let H=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"]),K=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"]),Q=(o.includes("--verbose")||o.includes("-v"))&&!o.includes("--json");k==="do"&&b==="shell"&&(console.error(" `sootsim do shell` was removed. use `sootsim shell ...` instead."),process.exit(1)),H.has(b)&&await ke(l),K.has(b)&&await ie(l,{verbose:Q});try{switch(b){case"list":{await Je({bridge:l,browserId:v,args:d});break}case"tree":{await Ke({bridge:l,args:d,positional:a});break}case"a11y":{let e=a[1]?Number(a[1]):5,t=await l.send({type:"evaluate",code:`(async () => {
|
|
242
242
|
const t = window.__sootsimTest
|
|
243
243
|
if (!t) return []
|
|
244
244
|
const all = await t.queryAll({ pruneHidden: true })
|
|
@@ -267,7 +267,7 @@ ${s}
|
|
|
267
267
|
size: n.layout ? { w: Math.round(n.layout.width), h: Math.round(n.layout.height) } : null,
|
|
268
268
|
}))
|
|
269
269
|
})()`});if(!Array.isArray(t)||t.length===0){console.log(" no accessible nodes found");break}if(o.includes("--json"))console.log(JSON.stringify(t,null,2));else{console.log(` accessibility tree (${t.length} nodes):
|
|
270
|
-
`);for(let s of t){let r=[];if(r.push(`[${s.role}]`),s.label){let n=s.label.length>50?s.label.slice(0,47)+"...":s.label;r.push(`"${n}"`)}if(s.hint&&r.push(`(hint: "${s.hint}")`),s.testID&&r.push(`#${s.testID}`),s.state){let n=[];s.state.disabled&&n.push("disabled"),s.state.selected&&n.push("selected"),s.state.checked===!0&&n.push("checked"),s.state.checked==="mixed"&&n.push("mixed"),s.state.busy&&n.push("busy"),s.state.expanded===!0&&n.push("expanded"),s.state.expanded===!1&&n.push("collapsed"),n.length&&r.push(`{${n.join(", ")}}`)}s.position&&r.push(`@(${s.position.x},${s.position.y})`),s.size&&r.push(`${s.size.w}x${s.size.h}`),console.log(" "+r.join(" "))}}break}case"find":{await
|
|
270
|
+
`);for(let s of t){let r=[];if(r.push(`[${s.role}]`),s.label){let n=s.label.length>50?s.label.slice(0,47)+"...":s.label;r.push(`"${n}"`)}if(s.hint&&r.push(`(hint: "${s.hint}")`),s.testID&&r.push(`#${s.testID}`),s.state){let n=[];s.state.disabled&&n.push("disabled"),s.state.selected&&n.push("selected"),s.state.checked===!0&&n.push("checked"),s.state.checked==="mixed"&&n.push("mixed"),s.state.busy&&n.push("busy"),s.state.expanded===!0&&n.push("expanded"),s.state.expanded===!1&&n.push("collapsed"),n.length&&r.push(`{${n.join(", ")}}`)}s.position&&r.push(`@(${s.position.x},${s.position.y})`),s.size&&r.push(`${s.size.w}x${s.size.h}`),console.log(" "+r.join(" "))}}break}case"find":{await Le({bridge:l,args:o,effectiveArgs:d,positional:a,inspectUsage:S});break}case"count":{await Re(l,{args:d});break}case"keyboard":{await je(l,{json:o.includes("--json")});break}case"screens":{await qe(l,{json:o.includes("--json")});break}case"memory":{await He(l,{args:d});break}case"wait":{await Ye({wsPort:A,commandTimeoutMs:j,browserId:v,positional:a});break}case"sleep":{await ze({positional:a,inspectUsage:S});break}case"settle":{await We({bridge:l,args:o,positional:a});break}case"ready":{await Xe({bridge:l,args:o});break}case"idle":{await Ge({bridge:l,args:o,positional:a});break}case"selector":{await Ve({bridge:l,args:o,positional:a,inspectUsage:S});break}case"layout":{let e=a[1];e||(console.error(S("layout","<id>")),process.exit(1));let t=await l.send({type:"evaluate",code:`(async () => await window.__sootsimTest.getLayout(${JSON.stringify(e)}))()`});console.log(JSON.stringify(t,null,2));break}case"capture":case"screenshot":{let t=o.find((h,f)=>o[f-1]==="--output")||"/tmp/sootsim-inspect.png",s=await tt(o,l),r={type:"screenshot"};s&&(r.crop=s);let m=(await l.send(r)).replace(/^data:image\/png;base64,/,"");s&&console.log(` area: x=${s.x} y=${s.y} w=${s.w} h=${s.h}`),(await import("fs")).writeFileSync(t,Buffer.from(m,"base64")),console.log(` saved: ${t}`);break}case"sample-color":{let e=await tt(o,l);e||(console.error(S("sample-color","<x> <y> [w] [h] | --id <testID> | --text <text>")),console.error(" samples an averaged color from the canvas. coords are logical sootsim units."),process.exit(1));let t=await l.send({type:"evaluate",code:_e(e)});if(o.includes("--json"))console.log(JSON.stringify(t,null,2));else{let{r:s,g:r,b:n,a:m,hex:p,samples:h}=t,f=e.w===1&&e.h===1?`@(${e.x},${e.y})`:`@(${e.x},${e.y}) ${e.w}x${e.h}`;console.log(` ${p} rgba(${s}, ${r}, ${n}, ${m}) ${f} ${h} samples`)}break}case"node":{let e=a[1];e||(console.error(S("node","<matcher>")),console.error(" resolves testID, id, then text \u2014 dumps full node info as JSON"),process.exit(1));let t=await l.send({type:"evaluate",code:`(async () => {
|
|
271
271
|
const t = window.__sootsimTest
|
|
272
272
|
const q = ${JSON.stringify(e)}
|
|
273
273
|
let node = null
|
|
@@ -323,7 +323,7 @@ ${s}
|
|
|
323
323
|
transform,
|
|
324
324
|
parentChain,
|
|
325
325
|
}
|
|
326
|
-
})()`});console.log(JSON.stringify(t,null,2));break}case"tap":{let e=Number(a[1]),t=Number(a[2]),s=se(o);if(s){let m=await ce(l,s);m||(console.error(` not found: ${s.value}`),s.mode==="testid"&&U("wait-selector-for-missing-testid",s.value),process.exit(1)),e=m.x,t=m.y}(!Number.isFinite(e)||!Number.isFinite(t))&&(console.error(S("tap","<x> <y> | --testid <id> | --text <t>")),process.exit(1));let r=await l.send({type:"tap",x:e,y:t}),n=
|
|
326
|
+
})()`});console.log(JSON.stringify(t,null,2));break}case"tap":{let e=Number(a[1]),t=Number(a[2]),s=se(o);if(s){let m=await ce(l,s);m||(console.error(` not found: ${s.value}`),s.mode==="testid"&&U("wait-selector-for-missing-testid",s.value),process.exit(1)),e=m.x,t=m.y}(!Number.isFinite(e)||!Number.isFinite(t))&&(console.error(S("tap","<x> <y> | --testid <id> | --text <t>")),process.exit(1));let r=await l.send({type:"tap",x:e,y:t}),n=Dt(e,t,r);n&&await L("inspect tap",n.step,n.summary),console.log(JSON.stringify(r,null,2));break}case"drag":case"swipe":{let e=Number(a[1]),t=Number(a[2]),s=Number(a[3]),r=Number(a[4]),n=b==="swipe"?10:12,m=b==="swipe"?8:16,p=a[5]?Number(a[5]):n,h=a[6]?Number(a[6]):m;(!Number.isFinite(e)||!Number.isFinite(t)||!Number.isFinite(s)||!Number.isFinite(r)||!Number.isFinite(p)||!Number.isFinite(h))&&(console.error(S(b,"<x1> <y1> <x2> <y2> [steps] [stepMs]")),process.exit(1));let f=await l.send({type:"evaluate",code:`(async () => {
|
|
327
327
|
const interact = window.__sootsimInteract
|
|
328
328
|
if (!interact?.drag) return { ok: false, reason: 'no interact.drag' }
|
|
329
329
|
const value = await interact.drag(${e}, ${t}, ${s}, ${r}, ${Math.max(1,Math.round(p))}, ${Math.max(0,Math.round(h))})
|
|
@@ -447,7 +447,7 @@ ${s}
|
|
|
447
447
|
total,
|
|
448
448
|
idx,
|
|
449
449
|
}
|
|
450
|
-
})()`});if(g?.error==="bridge-not-ready"&&(console.error(" sootsim test bridge not ready"),process.exit(1)),g?.ambiguous){let _=g.candidates;console.error(` ambiguous: ${g.total} matches for "${e}"`);for(let P of _){let re=P.abs?`@(${Math.round(P.abs.x)},${Math.round(P.abs.y)})`:"",
|
|
450
|
+
})()`});if(g?.error==="bridge-not-ready"&&(console.error(" sootsim test bridge not ready"),process.exit(1)),g?.ambiguous){let _=g.candidates;console.error(` ambiguous: ${g.total} matches for "${e}"`);for(let P of _){let re=P.abs?`@(${Math.round(P.abs.x)},${Math.round(P.abs.y)})`:"",it=P.layout?` ${P.layout.width}x${P.layout.height}`:"",lt=P.testID?` #${P.testID}`:"",ct=P.text?` "${P.text}"`:"",dt=P.ancestorTestIDs.length>0?` within ${P.ancestorTestIDs.slice(0,3).map(ut=>`#${ut}`).join(" > ")}`:"";console.error(` [${P.idx}] <${P.type}>${ct}${lt} ${re}${it}${dt}`)}g.total>_.length&&console.error(` ... and ${g.total-_.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)}g?.nthOutOfRange&&(console.error(` not found: nth ${g.nth} of ${g.total} match${g.total===1?"":"es"} for "${e}"`),process.exit(1)),(!g||typeof g.cx!="number")&&(console.error(` not found: ${e}`),process.exit(1));let T=await l.send({type:"tap",x:g.cx,y:g.cy});if(T?.hit!==!1&&T?.ok!==!1){let _=st(e,{id:g.target?.id??null,testID:g.target?.testID??null,type:g.target?.type??null,cx:g.cx,cy:g.cy},"text");await L("inspect tap-text",_.step,_.summary)}console.log(JSON.stringify({matched:g.match,tapped:{nodeId:g.target?.nodeId??null,id:g.target?.id??null,testID:g.target?.testID??null,type:g.target?.type??null,cx:g.cx,cy:g.cy},...g.strategy&&g.strategy!=="matched-node"?{strategy:g.strategy}:{},...g.total>1||n!==null?{nth:{index:g.idx,total:g.total}}:{},result:T},null,2));break}case"tap-id":{let e=a[1];e||(console.error(S("tap-id","<id>")),process.exit(1));let t=JSON.stringify(e),s=await l.send({type:"evaluate",code:`(async () => {
|
|
451
451
|
const t = window.__sootsimTest
|
|
452
452
|
if (!t) return null
|
|
453
453
|
const n = (await t.findByTestId(${t})) || (await t.findById(${t}))
|
|
@@ -482,7 +482,7 @@ ${s}
|
|
|
482
482
|
},
|
|
483
483
|
strategy: (resolved && resolved.strategy) || 'matched-node',
|
|
484
484
|
}
|
|
485
|
-
})()`});(!s||typeof s.cx!="number")&&(console.error(` not found: ${e}`),process.exit(1));let r=await l.send({type:"tap",x:s.cx,y:s.cy});if(r?.hit!==!1&&r?.ok!==!1){let n=
|
|
485
|
+
})()`});(!s||typeof s.cx!="number")&&(console.error(` not found: ${e}`),process.exit(1));let r=await l.send({type:"tap",x:s.cx,y:s.cy});if(r?.hit!==!1&&r?.ok!==!1){let n=st(e,{id:s.target?.id??null,testID:s.target?.testID??null,type:s.target?.type??null,cx:s.cx,cy:s.cy},"id");await L("inspect tap-id",n.step,n.summary)}console.log(JSON.stringify({matched:s.match,tapped:{nodeId:s.target?.nodeId??null,id:s.target?.id??null,testID:s.target?.testID??null,type:s.target?.type??null,cx:s.cx,cy:s.cy},...s.strategy&&s.strategy!=="matched-node"?{strategy:s.strategy}:{},result:r},null,2));break}case"type-into":{let e=a[1],t=a.slice(2).join(" ");(!e||!t)&&(console.error(S("type-into","<id> <text>")),process.exit(1));let s=JSON.stringify(e),r=await l.send({type:"evaluate",code:`(async () => {
|
|
486
486
|
const t = window.__sootsimTest
|
|
487
487
|
if (!t) return null
|
|
488
488
|
const n = await (t.findByTestId(${s}) || t.findById(${s}))
|
|
@@ -494,7 +494,7 @@ ${s}
|
|
|
494
494
|
isTextInput: !!n.isTextInput,
|
|
495
495
|
placeholder: n.placeholder || null,
|
|
496
496
|
}
|
|
497
|
-
})()`});(!r||typeof r.cx!="number")&&(console.error(` not found: ${e}`),process.exit(1)),r.isTextInput||console.error(` warning: ${e} is not a text input (isTextInput: false)`);let n=await l.send({type:"tap",x:r.cx,y:r.cy}),m=await
|
|
497
|
+
})()`});(!r||typeof r.cx!="number")&&(console.error(` not found: ${e}`),process.exit(1)),r.isTextInput||console.error(` warning: ${e} is not a text input (isTextInput: false)`);let n=await l.send({type:"tap",x:r.cx,y:r.cy}),m=await Et(l);m.visible||(console.error(` keyboard did not open after tapping ${e}`),process.exit(1));let p=m.focusedInput;p&&(p.testID===e||p.id===e||(console.error(` focus routing mismatch after tap: requested ${JSON.stringify(e)} but focus is on ${JSON.stringify(p.testID??p.id??null)}. did the tap land on an outer Pressable wrapper?`),process.exit(1))),await l.send({type:"keyboard",action:"type",text:t}),await L("inspect type-into",{tapOn:{id:e},inputText:t},`type-into #${e} ${JSON.stringify(t)}`),console.log(JSON.stringify({target:e,isTextInput:r.isTextInput,keyboardOpened:m.visible??n?.keyboardOpened??!1,focusedInput:m.focusedInput??null,typed:t},null,2));break}case"type":{let e=a.slice(1).join(" ");e||(console.error(S("type","<text>")),process.exit(1)),await ue(l,"type"),await l.send({type:"keyboard",action:"type",text:e}),await L("inspect type",{inputText:e},`type ${JSON.stringify(e)}`),console.log(` typed: ${JSON.stringify(e)}`);break}case"key":{let e=a[1];e||(console.error(S("key","<name>")),process.exit(1)),await ue(l,"key"),await l.send({type:"keyboard",action:"press",text:e}),await L("inspect key",{pressKey:e},`key ${e}`),console.log(` pressed: ${e}`);break}case"key-sequence":{let e=a.slice(1);e.length===0&&(console.error(S("key-sequence","<key> [<key> ...]")),process.exit(1)),await ue(l,"key-sequence");for(let t of e)await l.send({type:"keyboard",action:"press",text:t});await L("inspect key-sequence",{pressKey:e.join(" ")},`key-sequence ${e.join(" ")}`),console.log(` pressed: ${e.join(", ")}`);break}case"keycode":{let e=a.slice(1);e.length===0&&(console.error(S("keycode","<code> [<code> ...]")),process.exit(1));let t=e.map(r=>({code:r,key:Rt(r)})),s=t.filter(r=>!r.key);s.length>0&&(console.error(` unsupported keycode(s): ${s.map(r=>r.code).join(", ")}`),process.exit(1)),await ue(l,"keycode");for(let r of t)await l.send({type:"keyboard",action:"press",text:r.key});await L("inspect keycode",{pressKey:t.map(r=>r.key).join(" ")},`keycode ${e.join(" ")}`),console.log(` pressed: ${e.join(", ")}`);break}case"dispatch":{let e=a[1];e||(console.error(S("dispatch","<char>")),process.exit(1)),await l.send({type:"keyboard",action:"dispatchKey",text:e}),await L("inspect dispatch",{dispatchKey:e},`dispatch ${JSON.stringify(e)}`),console.log(` dispatched: ${e}`);break}case"dismiss":{await l.send({type:"keyboard",action:"dismiss"}),await L("inspect dismiss",{hideKeyboard:!0},"dismiss keyboard"),console.log(" keyboard dismissed");break}case"double-tap":{let e=Number(a[1]),t=Number(a[2]),s=se(o);if(s){let p=await ce(l,s);p||(console.error(` not found: ${s.value}`),s.mode==="testid"&&U("wait-selector-for-missing-testid",s.value),process.exit(1)),e=p.x,t=p.y}let r=a[3]?Number(a[3]):80;(!Number.isFinite(e)||!Number.isFinite(t)||!Number.isFinite(r))&&(console.error(S("double-tap","<x> <y> [gapMs] | --testid <id>")),process.exit(1));let n=Math.max(0,Math.round(r)),m=await l.send({type:"evaluate",code:`(async () => {
|
|
498
498
|
const interact = window.__sootsimInteract
|
|
499
499
|
if (interact?.doubleTap) {
|
|
500
500
|
return {
|
|
@@ -632,7 +632,7 @@ ${s}
|
|
|
632
632
|
${y("shell")} open-card clock 800
|
|
633
633
|
${y("shell")} appearance dark
|
|
634
634
|
${y("shell")} lock
|
|
635
|
-
`);break}let t=e==="launch"||e==="open-card"||e==="home"||e==="switcher",s=e==="launch"||e==="open-card"?a[3]:a[2],r=s?Number(s):350;t&&(!Number.isFinite(r)||r<0)&&(console.error(S("shell",e==="launch"||e==="open-card"?"<launch|open-card> <appId> [settleMs]":"<home|switcher> [settleMs]")),process.exit(1));let n=!1,m=!1,p=null,h=o.includes("--clear-state");if(e==="launch"){let f=a[2];f||(console.error(S("shell","launch <appId> [settleMs] [--clear-state]")),process.exit(1)),h&&await l.send({type:"evaluate",code:Te}),n=!!await te(l,"launchApp",r,f),{settled:m,state:p}=await de(l,Math.round(r),w=>!!w&&w.state==="app"&&w.activeApp===f&&w.showSwitcher===!1&&w.switcherPhase==="idle"&&typeof w.launchProgress=="number"&&w.launchProgress>=.98),n&&await L("inspect shell launch",h?{launchApp:{clearState:!0}}:{launchApp:{}},h?"launch app (clear state)":"launch app")}else if(e==="home")n=!!await te(l,"goHome",r),{settled:m,state:p}=await de(l,Math.round(r),f=>!!f&&f.state==="home"&&f.activeApp==null&&f.showSwitcher===!1&&f.switcherPhase==="idle"&&typeof f.launchProgress=="number"&&f.launchProgress>=.98);else if(e==="switcher")n=!!await te(l,"openSwitcher",r),{settled:m,state:p}=await de(l,Math.round(r),f=>!!f&&f.state==="app"&&f.showSwitcher===!0&&f.switcherPhase==="idle"&&typeof f.zoomLevel=="number"&&Math.abs(f.zoomLevel)<=.02&&typeof f.horizontalZoom=="number"&&Math.abs(f.horizontalZoom)<=.02),m&&(await Y(
|
|
635
|
+
`);break}let t=e==="launch"||e==="open-card"||e==="home"||e==="switcher",s=e==="launch"||e==="open-card"?a[3]:a[2],r=s?Number(s):350;t&&(!Number.isFinite(r)||r<0)&&(console.error(S("shell",e==="launch"||e==="open-card"?"<launch|open-card> <appId> [settleMs]":"<home|switcher> [settleMs]")),process.exit(1));let n=!1,m=!1,p=null,h=o.includes("--clear-state");if(e==="launch"){let f=a[2];f||(console.error(S("shell","launch <appId> [settleMs] [--clear-state]")),process.exit(1)),h&&await l.send({type:"evaluate",code:Te}),n=!!await te(l,"launchApp",r,f),{settled:m,state:p}=await de(l,Math.round(r),w=>!!w&&w.state==="app"&&w.activeApp===f&&w.showSwitcher===!1&&w.switcherPhase==="idle"&&typeof w.launchProgress=="number"&&w.launchProgress>=.98),n&&await L("inspect shell launch",h?{launchApp:{clearState:!0}}:{launchApp:{}},h?"launch app (clear state)":"launch app")}else if(e==="home")n=!!await te(l,"goHome",r),{settled:m,state:p}=await de(l,Math.round(r),f=>!!f&&f.state==="home"&&f.activeApp==null&&f.showSwitcher===!1&&f.switcherPhase==="idle"&&typeof f.launchProgress=="number"&&f.launchProgress>=.98);else if(e==="switcher")n=!!await te(l,"openSwitcher",r),{settled:m,state:p}=await de(l,Math.round(r),f=>!!f&&f.state==="app"&&f.showSwitcher===!0&&f.switcherPhase==="idle"&&typeof f.zoomLevel=="number"&&Math.abs(f.zoomLevel)<=.02&&typeof f.horizontalZoom=="number"&&Math.abs(f.horizontalZoom)<=.02),m&&(await Y(Ot),p=await V(l));else if(e==="open-card"){let f=a[2];f||(console.error(S("shell","open-card <appId> [settleMs]")),process.exit(1)),n=!!await te(l,"openSwitcherCard",r,f),{settled:m,state:p}=await de(l,Math.round(r),w=>!!w&&w.state==="app"&&w.activeApp===f&&w.showSwitcher===!1&&w.switcherPhase==="idle"&&typeof w.zoomLevel=="number"&&w.zoomLevel>=.98&&typeof w.horizontalZoom=="number"&&w.horizontalZoom>=.98),n&&await L("inspect shell open-card",{openSwitcherCard:{appId:f}},`open switcher card ${f}`)}else if(e==="appearance"){let f=a[2];(!f||!["light","dark","auto","toggle"].includes(f))&&(console.error(S("shell","appearance <light|dark|auto|toggle>")),process.exit(1));let w=await ot(l,"appearance",f);n=!!w?.ok,p={appearance:w}}else if(e==="lock"||e==="shake"){let f=await ot(l,e);n=!!f?.ok,p={[e]:f}}else console.error(` unknown shell subcommand: ${e}`),process.exit(1);console.log(JSON.stringify({ok:n,settled:m,state:p},null,2));break}case"url":{await Ue(l,{args:d});break}case"reload":{let s=!1,r=!1;try{await l.send({type:"evaluate",code:"window.__sootsimConsole?.clear()"});let p=await l.send({type:"evaluate",code:`;(() => {
|
|
636
636
|
const reloadExternalApp = window.SootSim?.bridges?.hotRemount?.reloadExternalApp
|
|
637
637
|
if (typeof reloadExternalApp === 'function') {
|
|
638
638
|
reloadExternalApp()
|
|
@@ -681,7 +681,7 @@ ${s}
|
|
|
681
681
|
|
|
682
682
|
return globals
|
|
683
683
|
})()`});console.log(` sootsim JS API:
|
|
684
|
-
`);for(let[t,s]of Object.entries(e)){console.log(` ${t}:`);for(let r of s)console.log(` .${r}`);console.log("")}console.log(` use: ${y("js")} <expression>`),console.log(` example: ${y("js")} test.findByText("Sign in")`);break}case"describe":{await
|
|
684
|
+
`);for(let[t,s]of Object.entries(e)){console.log(` ${t}:`);for(let r of s)console.log(` .${r}`);console.log("")}console.log(` use: ${y("js")} <expression>`),console.log(` example: ${y("js")} test.findByText("Sign in")`);break}case"describe":{await Ce({bridge:l,args:o,positional:a});break}case"perf":{let e=a[1];if(!e||e==="--help"||e==="-h"){console.log(`
|
|
685
685
|
${y("perf")} \u2014 performance profiling
|
|
686
686
|
|
|
687
687
|
subcommands:
|
|
@@ -1015,16 +1015,16 @@ ${s}
|
|
|
1015
1015
|
const obs = window.__sootsimObservability;
|
|
1016
1016
|
if (!obs) return null;
|
|
1017
1017
|
return obs.network.getSnapshot().find(e => e.id === ${JSON.stringify(N)}) || null;
|
|
1018
|
-
})()`});M||(console.error(` no entry with id ${N}`),process.exit(1)),m?console.log(JSON.stringify(M,null,2)):
|
|
1018
|
+
})()`});M||(console.error(` no entry with id ${N}`),process.exit(1)),m?console.log(JSON.stringify(M,null,2)):Ft(M);break}let p=s??(n?200:e?Number(e):20);Number.isFinite(p)||(console.error(` invalid limit: ${e}`),process.exit(1));let h=async()=>{let N=await l.send({type:"evaluate",code:`(() => {
|
|
1019
1019
|
const obs = window.__sootsimObservability;
|
|
1020
1020
|
if (!obs) return { ok: false };
|
|
1021
1021
|
return { ok: true, entries: obs.network.getSnapshot() };
|
|
1022
1022
|
})()`});if(!N||!N.ok)throw new Error("observability bridge not installed \u2014 is the engine running?");return N.entries??[]},f=N=>{let M=N;if(r&&(M=M.filter(F=>!!F.error||F.status!=null&&F.status>=400)),t){let F=t.toLowerCase();M=M.filter(W=>(W.displayUrl||W.url).toLowerCase().includes(F))}return M};if(!n){let N=await h(),M=f(N).slice(-p);if(m){console.log(JSON.stringify(M,null,2));break}if(M.length===0){console.log(N.length===0?" no network requests captured":" no matching requests");break}console.log(` ${M.length} request(s):
|
|
1023
|
-
`);for(let F of M)
|
|
1024
|
-
`);let w=new Set,O=!0,B=()=>{O=!1};process.on("SIGINT",B);try{for(;O;){let N=await h(),M=f(N);for(let F of M)F.durationMs!=null&&(w.has(F.id)||(w.add(F.id),m?console.log(JSON.stringify(F)):
|
|
1023
|
+
`);for(let F of M)Ze(F);break}console.log(` tailing network (ctrl-c to stop)...
|
|
1024
|
+
`);let w=new Set,O=!0,B=()=>{O=!1};process.on("SIGINT",B);try{for(;O;){let N=await h(),M=f(N);for(let F of M)F.durationMs!=null&&(w.has(F.id)||(w.add(F.id),m?console.log(JSON.stringify(F)):Ze(F)));await Y(250)}}finally{process.off("SIGINT",B)}break}case"logs":{let e=a[1],t=null,s=null,r=null,n=!1,m=!1,p=!1;for(let g=0;g<d.length;g++){let T=d[g];if(T==="--filter")t=d[g+1]??null,g++;else if(T==="--limit"){let _=Number(d[g+1]);Number.isFinite(_)&&(s=_),g++}else T==="--level"?(r=d[g+1]??null,g++):T==="--tail"||T==="-f"?n=!0:T==="--json"?m=!0:(T==="--internal"||T==="--all")&&(p=!0)}let h=r?new Set(r.split(",").map(g=>g.trim()).filter(g=>g==="log"||g==="info"||g==="warn"||g==="error"||g==="debug")):null;if(e==="clear"){await l.send({type:"evaluate",code:'window.__sootsimObservability?.logs.clear(); "cleared"'}),console.log(" log buffer cleared");break}let f=!m&&process.stdout.isTTY===!0,w=s??(n?500:e?Number(e):50);Number.isFinite(w)||(console.error(` invalid limit: ${e}`),process.exit(1));let O=async()=>{let g=await l.send({type:"evaluate",code:`(() => {
|
|
1025
1025
|
const obs = window.__sootsimObservability;
|
|
1026
1026
|
if (!obs) return { ok: false };
|
|
1027
1027
|
return { ok: true, entries: obs.logs.getSnapshot() };
|
|
1028
1028
|
})()`});if(!g||!g.ok)throw new Error("observability bridge not installed \u2014 is the engine running?");return g.entries??[]},B=g=>{let T=g.args[0];return typeof T!="string"?!1:T.startsWith("[sootsim]")},N=g=>{let T=g;if(p||(T=T.filter(_=>!B(_))),h&&(T=T.filter(_=>h.has(_.level))),t){let _=t.toLowerCase();T=T.filter(P=>P.args.join(" ").toLowerCase().includes(_))}return T};if(!n){let g=await O(),T=N(g).slice(-w);if(m){console.log(JSON.stringify(T,null,2));break}if(T.length===0){console.log(g.length===0?" no logs captured":" no matching logs");break}console.log(` ${T.length} log(s):
|
|
1029
|
-
`);for(let _ of T)
|
|
1030
|
-
`);let M=new Set,F=!0,W=()=>{F=!1};process.on("SIGINT",W);try{for(;F;){let g=await O(),T=N(g);for(let _ of T)M.has(_.id)||(M.add(_.id),m?console.log(JSON.stringify(_)):
|
|
1029
|
+
`);for(let _ of T)et(_,f);break}console.log(` tailing logs (ctrl-c to stop)...
|
|
1030
|
+
`);let M=new Set,F=!0,W=()=>{F=!1};process.on("SIGINT",W);try{for(;F;){let g=await O(),T=N(g);for(let _ of T)M.has(_.id)||(M.add(_.id),m?console.log(JSON.stringify(_)):et(_,f));await Y(250)}}finally{process.off("SIGINT",W)}break}default:console.error(` unknown subcommand: ${b}`),process.exit(1)}if(H.has(b)&&!o.includes("--no-wait")&&process.env.SOOTSIM_NO_AUTO_WAIT!=="1"&&await ne(l),!D.has(b)&&!E(d)){let e=await Z();try{await J({counts:e.console})}catch{}try{await x({counts:e.requests})}catch{}}}catch(e){let t=e instanceof Error?e.message:String(e);if(console.error(` ${b??"inspect"} failed: ${t}`),/^no browser connected( with id .+)?$/.test(t))Ae(A);else{try{await Me(l)}catch{}try{await J({includeTail:!0})}catch{}try{await x({includeTail:!0})}catch{}}process.exit(1)}finally{l.close()}}export{rs as runInspect};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
/*! sootsim v0.0.
|
|
2
|
-
import{a as j,b as P}from"./chunk-
|
|
1
|
+
/*! sootsim v0.0.4 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
|
+
import{a as j,b as P}from"./chunk-6SZMLFCR.js";import{d as b}from"./chunk-HAKR72LJ.js";import"./chunk-C3QLIYCS.js";import"./chunk-W7CYWXRZ.js";import"./chunk-MZPAJ5PQ.js";import"./chunk-WRF43M33.js";import"./chunk-WWDJCKMI.js";import{execSync as V}from"child_process";import{existsSync as w,readFileSync as C,writeFileSync as x}from"fs";import{relative as A,resolve as u}from"path";import{existsSync as a,readFileSync as d,readdirSync as O,statSync as L}from"fs";import{basename as R,dirname as T,join as c}from"path";function S(e){let n=e;for(;;){if(a(c(n,"turbo.json"))||a(c(n,"nx.json"))||a(c(n,"lerna.json"))||a(c(n,"pnpm-workspace.yaml")))return n;let s=c(n,"package.json");if(a(s))try{if(JSON.parse(d(s,"utf8")).workspaces)return n}catch{}let i=T(n);if(i===n)break;n=i}return e}function W(e){return a(c(e,"bun.lock"))||a(c(e,"bun.lockb"))?"bun":a(c(e,"pnpm-lock.yaml"))?"pnpm":a(c(e,"yarn.lock"))?"yarn":"npm"}function _(e){if(a(c(e,"turbo.json")))return"turbo";if(a(c(e,"nx.json")))return"nx";if(a(c(e,"pnpm-workspace.yaml")))return"pnpm";let n=c(e,"package.json");if(a(n))try{if(JSON.parse(d(n,"utf8")).workspaces)return"npm-workspaces"}catch{}return"single"}function J(e){return e.one?"one":e.expo?"expo":e["react-native"]?"bare":"unknown"}function y(e){let n=c(e,"package.json");if(!a(n))return null;let s;try{s=JSON.parse(d(n,"utf8"))}catch{return null}let i={...s.dependencies,...s.devDependencies},r=J(i);return r==="unknown"?null:{dir:e,name:s.name||R(e),framework:r,hasViteConfig:a(c(e,"vite.config.ts"))||a(c(e,"vite.config.js")),hasMetroConfig:a(c(e,"metro.config.js"))||a(c(e,"metro.config.ts")),hasSootsimDependency:!!i.sootsim,devCommand:s.scripts?.dev||null}}function N(e){let n=[],s=c(e,"pnpm-workspace.yaml");if(a(s)){let o=d(s,"utf8").match(/packages:\s*\n((?:\s+-\s+.+\n?)+)/);if(o){let t=o[1].split(`
|
|
3
3
|
`).filter(Boolean);for(let g of t){let l=g.replace(/^\s*-\s*['"]?/,"").replace(/['"]?\s*$/,"");l&&n.push(...v(e,l))}}return n}let i=c(e,"package.json");if(a(i))try{let r=JSON.parse(d(i,"utf8")),o=Array.isArray(r.workspaces)?r.workspaces:r.workspaces?.packages||[];for(let t of o)n.push(...v(e,t))}catch{}return n}function v(e,n){let s=n.replace(/\/\*\*?$/,"").replace(/\*$/,""),i=c(e,s);if(!a(i))return[];try{return O(i).map(o=>c(i,o)).filter(o=>{try{return L(o).isDirectory()&&a(c(o,"package.json"))}catch{return!1}})}catch{return[]}}function D(e){let n=_(e),s=W(e);if(n==="single"){let t=y(e);return{root:e,type:n,packageManager:s,apps:t?[t]:[]}}let i=N(e),r=[],o=y(e);o&&r.push(o);for(let t of i){if(t===e)continue;let g=y(t);g&&r.push(g)}return{root:e,type:n,packageManager:s,apps:r}}function M(e){switch(e){case"bun":return"bun add -d sootsim";case"pnpm":return"pnpm add -D sootsim";case"yarn":return"yarn add -D sootsim";case"npm":return"npm install -D sootsim"}}async function re(e){(e.includes("--help")||e.includes("-h"))&&(console.log(`
|
|
4
4
|
sootsim install \u2014 set up sootsim in your project
|
|
5
5
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
/*! sootsim v0.0.
|
|
2
|
-
import{a as x}from"./chunk-
|
|
1
|
+
/*! sootsim v0.0.4 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
|
+
import{a as x}from"./chunk-6SZMLFCR.js";import{a as $}from"./chunk-SY74J6F4.js";import"./chunk-WWDJCKMI.js";import{spawn as v,spawnSync as u}from"child_process";import{chmodSync as k,createWriteStream as S,existsSync as f,mkdirSync as y,renameSync as P,rmSync as w,statSync as T}from"fs";import{tmpdir as E}from"os";import{dirname as D,join as m,resolve as b}from"path";var h="https://sootbean.com/api/electron-release";function M(){let r=process.arch;if(process.platform==="darwin"){let o=r==="arm64"?"mac-arm64":"mac-x64",n=`sootsim-latest-${o}.dmg`;return{platform:o,filename:n,url:`${h}/${n}`,install:I}}if(process.platform==="linux"){let o="sootsim-latest-linux-x64.AppImage";return{platform:"linux-x64",filename:o,url:`${h}/${o}`,install:L}}if(process.platform==="win32"){let o="sootsim-latest-win-x64.exe";return{platform:"win-x64",filename:o,url:`${h}/${o}`,install:B}}return null}async function A({url:r,dest:o,onProgress:n}){let s=await fetch(r,{redirect:"follow"});if(!s.ok)throw new Error(`download failed: ${s.status} ${s.statusText} (${r})`);let e=s.headers.get("content-length"),l=e?Number(e):null;if(!s.body)throw new Error("download failed: empty response body");y(D(o),{recursive:!0});let i=S(o),d=s.body.getReader(),a=0;try{for(;;){let{done:t,value:c}=await d.read();if(t)break;i.write(Buffer.from(c)),a+=c.byteLength,n?.(a,l)}}finally{await new Promise((t,c)=>{i.end(p=>p?c(p):t())})}}function O(r,o){let n=(r/1048576).toFixed(1);if(!o)return` ${n} MB`;let s=Math.min(100,Math.round(r/o*100)),e=(o/(1024*1024)).toFixed(1),l=24,i=Math.round(s/100*l);return` ${"\u2588".repeat(i)+"\u2591".repeat(l-i)} ${s}% ${n} / ${e} MB`}async function I(r){let o=u("hdiutil",["attach","-nobrowse","-readonly",r],{encoding:"utf8"});if(o.status!==0)throw new Error(`hdiutil attach failed: ${o.stderr||o.stdout}`.trim());let n=o.stdout.trim().split(`
|
|
3
3
|
`),e=n[n.length-1].split(" ").pop()?.trim();if(!e||!f(e))throw new Error(`could not determine dmg mount point (output: ${o.stdout})`);let l=m(e,"sootsim.app");if(!f(l))throw u("hdiutil",["detach","-force",e]),new Error(`sootsim.app not found inside ${e}`);let i="/Applications",d=b(process.env.HOME||"","Applications"),a=i;try{let g=m(i,`.sootsim-write-probe-${process.pid}`);u("touch",[g]),f(g)?w(g,{force:!0}):a=d}catch{a=d}a===d&&y(a,{recursive:!0});let t=m(a,"sootsim.app");f(t)&&w(t,{recursive:!0,force:!0});let c=u("cp",["-R",l,t]),p=u("hdiutil",["detach","-force",e]);if(c.status!==0)throw new Error(`copy to ${t} failed: ${c.stderr?.toString()||""}`.trim());return p.status!==0&&console.warn(` warning: failed to unmount ${e} (${p.stderr?.toString().trim()||"unknown error"})`),u("xattr",["-dr","com.apple.quarantine",t]),t}async function L(r){let o=b(process.env.HOME||"","Applications");y(o,{recursive:!0});let n=m(o,"sootsim.AppImage");return f(n)&&w(n,{force:!0}),P(r,n),k(n,493),n}async function B(r){return await new Promise((o,n)=>{let s=v("cmd",["/c","start",'""',"/wait",r],{stdio:"inherit"});s.once("error",n),s.once("exit",e=>{e===0?o():n(new Error(`installer exited with code ${e}`))})}),r}async function _(r){(r.includes("--help")||r.includes("-h"))&&(console.log(`
|
|
4
4
|
sootsim install-desktop \u2014 download and install the optional desktop GUI
|
|
5
5
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
/*! sootsim v0.0.
|
|
2
|
-
import{a as b}from"./chunk-
|
|
1
|
+
/*! sootsim v0.0.4 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
|
+
import{a as b}from"./chunk-6SZMLFCR.js";import"./chunk-WWDJCKMI.js";import{spawnSync as m}from"child_process";import{chmodSync as $,existsSync as u,mkdirSync as y,rmSync as N,writeFileSync as g,cpSync as B}from"fs";import{dirname as p,join as s,resolve as k}from"path";import{fileURLToPath as S}from"url";var C=p(S(import.meta.resolve("sootsim-engine/package.json"))),I="sootsim-dev",E="dev.sootsim.simulator.dev";function w(e){let n={yes:e.includes("--yes")||e.includes("-y")||process.env.SOOTSIM_NO_PROMPT==="1"||process.env.CI==="1"||!process.stdin.isTTY,force:e.includes("--force"),appName:I,bundleId:E};for(let o=0;o<e.length;o++){let t=e[o];t==="--name"&&e[o+1]?n.appName=e[++o]:t==="--bundle-id"&&e[o+1]?n.bundleId=e[++o]:t==="--path"&&e[o+1]&&(n.installRoot=e[++o])}return n}function T(e){let r=process.platform==="darwin"?"electron/dist/Electron.app/Contents/MacOS/Electron":process.platform==="win32"?"electron/dist/electron.exe":"electron/dist/electron",c=e;for(let l=0;l<6;l++){let d=s(c,"node_modules",r);if(u(d))return d;let i=p(c);if(i===c)break;c=i}return null}function D(e){if(e)return k(e);let n="/Applications",o=k(process.env.HOME||"","Applications");try{let t=s(n,`.sootsim-dev-write-probe-${process.pid}`);if(m("touch",[t]).status===0&&u(t))return N(t,{force:!0}),n}catch{}return y(o,{recursive:!0}),o}function L(e){return`<?xml version="1.0" encoding="UTF-8"?>
|
|
3
3
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
4
4
|
<plist version="1.0">
|
|
5
5
|
<dict>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
/*! sootsim v0.0.
|
|
2
|
-
import{a as l,b as d,c as k,d as y,e as g}from"./chunk-
|
|
1
|
+
/*! sootsim v0.0.4 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
|
+
import{a as l,b as d,c as k,d as y,e as g}from"./chunk-AUR2LTNX.js";import{d as c}from"./chunk-UKYK63H6.js";import"./chunk-WWDJCKMI.js";async function a(){let s=await c();return s?.token||(process.stderr.write(" sootsim keys ... needs you to be signed in.\n run `sootsim login` first.\n"),process.exit(1)),{origin:s.origin,token:s.token}}function f(s){if(!s)return"never";try{return new Date(s).toLocaleString()}catch{return s}}async function h(s){let i=s[0];if(!i||i==="--help"||i==="-h"){u();return}if(i==="list"){let{origin:o,token:e}=await a(),n=await fetch(`${o.replace(/\/$/,"")}/api/sootsim/billing/keys`,{headers:{authorization:`Bearer ${e}`}});n.ok||(console.error(` keys list failed (${n.status})`),process.exit(1));let{keys:r}=await n.json();if(r.length===0){console.log(" no keys. create one with `sootsim keys create <label>`.");return}for(let t of r)console.log(` ${t.keyPrefix}\u2026 ${t.label.padEnd(24)} scopes=${t.scopes.join(",")} last=${f(t.lastUsedAt)} id=${t.id}`);return}if(i==="create"){let o=s[1]?.trim();o||(console.error(" usage: sootsim keys create <label>"),process.exit(1));let{origin:e,token:n}=await a(),r=await fetch(`${e.replace(/\/$/,"")}/api/sootsim/billing/keys`,{method:"POST",headers:{authorization:`Bearer ${n}`,"content-type":"application/json"},body:JSON.stringify({label:o})});r.ok||(console.error(` keys create failed (${r.status}): ${await r.text()}`),process.exit(1));let t=await r.json();console.log(`
|
|
3
3
|
created: ${t.record.label} (${t.record.keyPrefix}\u2026)`),console.log(` scopes: ${t.record.scopes.join(",")}`),console.log(`
|
|
4
4
|
secret: ${t.secret}
|
|
5
5
|
`),console.log(` copy this now \u2014 we can't show it again.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
/*! sootsim v0.0.
|
|
2
|
-
import"./chunk-
|
|
1
|
+
/*! sootsim v0.0.4 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
|
+
import"./chunk-F4ARVCRR.js";import{o as s,p as a,t as c,u as r,v as l}from"./chunk-WRF43M33.js";import{b as m}from"./chunk-ZF5FCFLD.js";import{a as u}from"./chunk-SY74J6F4.js";import"./chunk-WWDJCKMI.js";import{spawn as p}from"child_process";import{existsSync as h}from"fs";async function I(n){if(n.includes("--help")||n.includes("-h")){console.log(`
|
|
3
3
|
sootsim launch \u2014 one-shot: install runtime if needed, start daemon, open app
|
|
4
4
|
|
|
5
5
|
usage:
|
|
@@ -13,4 +13,4 @@ options:
|
|
|
13
13
|
examples:
|
|
14
14
|
sootsim launch
|
|
15
15
|
sootsim launch --version 1.2.3
|
|
16
|
-
`);return}let e=n.includes("--no-runtime-install"),i=n.indexOf("--channel"),t=i>=0&&n[i+1]?n[i+1]:"stable",o=n.indexOf("--version"),f=o>=0&&n[o+1]?n[o+1]:void 0;s(),await v({skipAutoInstall:e,channel:t,explicitVersion:f}),await d(),await x()}async function v(n){let e=a(),i=c();if(e&&i)return;n.skipAutoInstall&&(console.error(" no sootsim runtime installed. run `sootsim runtime install` first, or drop --no-runtime-install."),process.exit(1)),console.log("sootsim: first run \u2014 installing runtime");let{runRuntime:t}=await import("./runtime-
|
|
16
|
+
`);return}let e=n.includes("--no-runtime-install"),i=n.indexOf("--channel"),t=i>=0&&n[i+1]?n[i+1]:"stable",o=n.indexOf("--version"),f=o>=0&&n[o+1]?n[o+1]:void 0;s(),await v({skipAutoInstall:e,channel:t,explicitVersion:f}),await d(),await x()}async function v(n){let e=a(),i=c();if(e&&i)return;n.skipAutoInstall&&(console.error(" no sootsim runtime installed. run `sootsim runtime install` first, or drop --no-runtime-install."),process.exit(1)),console.log("sootsim: first run \u2014 installing runtime");let{runRuntime:t}=await import("./runtime-PJKHEB36.js"),o=[];n.explicitVersion&&o.push(n.explicitVersion),n.channel!=="stable"&&o.push("--channel",n.channel),await t(["install",...o],{channel:n.channel})}async function d(){let n=r();if(l(n))return;console.log("sootsim: starting daemon");let e=w();p(e,["server","--quiet"],{detached:!0,stdio:"ignore",env:process.env}).unref();let t=Date.now()+8e3;for(;Date.now()<t;){let o=r();if(l(o))return;await g(150)}console.error(" daemon didn't become ready within 8s \u2014 check ~/.sootsim/ or run `sootsim server` in a terminal to see errors"),process.exit(1)}async function x(){u()||(console.error(" no sootsim desktop companion installed. run `sootsim install-desktop` to download electron + the shell."),process.exit(1));let e=await m.launch({});e.launched||(console.error(` ${e.message}`),process.exit(1)),console.log(` ${e.message}`)}function w(){let n=process.argv[1];return n&&h(n)?n:"sootsim"}function g(n){return new Promise(e=>setTimeout(e,n))}async function R(){s(),await d()}export{R as ensureDaemonRunning,I as runLaunch};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
/*! sootsim v0.0.
|
|
2
|
-
import{b as g,d as f}from"./chunk-
|
|
1
|
+
/*! sootsim v0.0.4 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
|
+
import{b as g,d as f}from"./chunk-UKYK63H6.js";import"./chunk-WWDJCKMI.js";import{exec as S}from"node:child_process";import{randomBytes as v}from"node:crypto";import w from"node:http";var I=process.env.SOOTSIM_AUTH_ORIGIN||"https://sootbean.com",m="http://localhost:3000";async function $(e){if(e)return e;if(process.env.SOOTSIM_AUTH_ORIGIN)return process.env.SOOTSIM_AUTH_ORIGIN;if(process.env.SOOTSIM_UPLOAD_ORIGIN)return process.env.SOOTSIM_UPLOAD_ORIGIN;try{if((await fetch(`${m}/api/auth/me`)).ok)return m}catch{}return I}function x(){console.log(`
|
|
3
3
|
sootsim login \u2014 sign in so desktop uploads can attach to your account
|
|
4
4
|
|
|
5
5
|
usage:
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
/*! sootsim v0.0.
|
|
2
|
-
import{a as e,c as t}from"./chunk-
|
|
1
|
+
/*! sootsim v0.0.4 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
|
+
import{a as e,c as t}from"./chunk-UKYK63H6.js";import"./chunk-WWDJCKMI.js";async function r(){let o=e();if(!o?.token){console.log(" not signed in");return}try{await fetch(`${o.origin.replace(/\/$/,"")}/api/auth/sign-out`,{method:"POST",headers:{authorization:`Bearer ${o.token}`}})}catch{}t(),console.log(" signed out")}export{r as runLogout};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
/*! sootsim v0.0.
|
|
2
|
-
import{c as h}from"./chunk-
|
|
1
|
+
/*! sootsim v0.0.4 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
|
+
import{c as h}from"./chunk-MQDPKSCK.js";import"./chunk-QIP7LYQI.js";import"./chunk-UNFERMZ3.js";import"./chunk-DQKQYPIG.js";import"./chunk-ZKNI5MRD.js";import"./chunk-QQOBLF7O.js";import"./chunk-W3TYN64D.js";import"./chunk-AUR2LTNX.js";import"./chunk-UKYK63H6.js";import"./chunk-4XBPZQLW.js";import"./chunk-XJF46GU2.js";import"./chunk-EHMSE3Q3.js";import"./chunk-I6XGFZPA.js";import"./chunk-47S5DXXX.js";import"./chunk-OAHMYSMD.js";import"./chunk-5TTQKPGH.js";import"./chunk-WVBPATRA.js";import"./chunk-HGFIS26A.js";import"./chunk-C3QLIYCS.js";import"./chunk-W7CYWXRZ.js";import"./chunk-MZPAJ5PQ.js";import"./chunk-WRF43M33.js";import"./chunk-ZF5FCFLD.js";import"./chunk-SY74J6F4.js";import"./chunk-WWDJCKMI.js";import*as i from"fs";import*as l from"path";var w=[".maestro","maestro"];function v(){console.log(`
|
|
3
3
|
sootsim maestro \u2014 run maestro YAML flows against sootsim (drop-in)
|
|
4
4
|
|
|
5
5
|
usage:
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
/*! sootsim v0.0.
|
|
2
|
-
import"./chunk-
|
|
1
|
+
/*! sootsim v0.0.4 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
|
+
import"./chunk-WWDJCKMI.js";import{resolve as c,dirname as m}from"path";import{fileURLToPath as a}from"url";var t=m(a(import.meta.resolve("sootsim-engine/package.json")));async function g(o,r){(o.includes("--help")||o.includes("-h"))&&(console.log(`
|
|
3
3
|
sootsim preview \u2014 production-like preview
|
|
4
4
|
|
|
5
5
|
usage:
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
/*! sootsim v0.0.
|
|
2
|
-
import{c as I,e as N,i as S}from"./chunk-
|
|
1
|
+
/*! sootsim v0.0.4 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
|
+
import{c as I,e as N,i as S}from"./chunk-C3QLIYCS.js";import"./chunk-W7CYWXRZ.js";import"./chunk-MZPAJ5PQ.js";import"./chunk-WRF43M33.js";import"./chunk-WWDJCKMI.js";import{createWriteStream as v,mkdirSync as k,writeFileSync as w}from"fs";import{dirname as T,resolve as x}from"path";import{Readable as y}from"stream";import{pipeline as C}from"stream/promises";import{createGzip as F}from"zlib";async function E(r,m){if(r.includes("--help")||r.includes("-h"))return console.log(`
|
|
3
3
|
sootsim profile \u2014 capture a sampled CPU trace from the tenant worker
|
|
4
4
|
|
|
5
5
|
usage:
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
/*! sootsim v0.0.
|
|
2
|
-
import{a as z}from"./chunk-
|
|
1
|
+
/*! sootsim v0.0.4 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
|
+
import{a as z}from"./chunk-UNFERMZ3.js";import"./chunk-AUR2LTNX.js";import"./chunk-UKYK63H6.js";import{a as C}from"./chunk-WVBPATRA.js";import{c as R,e as $}from"./chunk-C3QLIYCS.js";import{c as W}from"./chunk-W7CYWXRZ.js";import"./chunk-MZPAJ5PQ.js";import"./chunk-WRF43M33.js";import"./chunk-WWDJCKMI.js";import{existsSync as Z,mkdirSync as _,readFileSync as ee,rmSync as L,writeFileSync as U}from"fs";import{tmpdir as oe}from"os";import{dirname as T,extname as re,join as te,resolve as O}from"path";var D=6e4;async function ve(e,r){if((e.includes("--help")||e.includes("-h"))&&(console.log(`
|
|
3
3
|
sootsim record \u2014 capture the running session
|
|
4
4
|
|
|
5
5
|
usage:
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
/*! sootsim v0.0.
|
|
2
|
-
import{a as k}from"./chunk-
|
|
1
|
+
/*! sootsim v0.0.4 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
|
+
import{a as k}from"./chunk-C3QLIYCS.js";import"./chunk-W7CYWXRZ.js";import"./chunk-MZPAJ5PQ.js";import{h as v,l as S,o as p,p as d,q as R,r as w}from"./chunk-WRF43M33.js";import"./chunk-WWDJCKMI.js";import{spawn as T}from"child_process";import N from"crypto";import i from"fs";import g from"path";import{Readable as A}from"stream";import{pipeline as C}from"stream/promises";import{WebSocket as M}from"ws";var O="https://sootbean.com",P="SOOTSIM_CDN_ORIGIN";function y(){let e=process.env[P];return e&&e.length>0?e.replace(/\/+$/,""):O}function j(){let e=new URL(`${y()}/runtimes/manifest.json`);return e.searchParams.set("t",String(Date.now())),e.toString()}function _(e){return`${y()}/runtimes/sootsim-runtime-${e}.tar.gz`}async function se(e,n={}){let[s,...t]=e;if(!s||s==="--help"||s==="-h"){I();return}switch(s){case"install":return E(t,n);case"list":case"ls":return U(t);case"use":return L(t);case"remove":case"rm":return W(t);case"which":case"active":return V();default:console.error(` unknown runtime subcommand: ${s}`),I(),process.exit(1)}}function I(){console.log(`
|
|
3
3
|
sootsim runtime \u2014 manage engine runtimes under ~/.sootsim/runtimes/
|
|
4
4
|
|
|
5
5
|
usage:
|
|
@@ -22,4 +22,4 @@ examples:
|
|
|
22
22
|
sootsim runtime install 1.2.3
|
|
23
23
|
sootsim runtime install --channel beta
|
|
24
24
|
sootsim runtime use 1.2.3
|
|
25
|
-
`)}async function E(e,n){let{version:s,flags:t}=z(e),o=t.channel??n.channel??"stable",a=t.force===!0,f=t.setActive!==!1;p(),console.log("sootsim runtime install"),console.log(` cdn: ${y()}`);let l=await D(),m=s||l.channels[o]?.latest;m||(console.error(` no version specified and channel '${o}' has no latest entry in the manifest`),process.exit(1));let r=m,u=l.versions[r];u||(console.error(` version ${r} not found in manifest`),console.error(` available: ${Object.keys(l.versions).slice(-10).join(", ")||"(none)"}`),process.exit(1)),console.log(` version: ${r} (channel: ${o})`);let c=v(r);if(!a&&i.existsSync(g.join(c,"index.html"))){console.log(` already installed at ${c}`),f&&await $(r);return}let b=u.tarball||_(r),h=g.join(S(),`sootsim-runtime-${r}.tar.gz`);console.log(` fetch: ${b}`),await G(b,h),console.log(" verify: sha256");let x=await H(h);x!==u.sha256&&(i.rmSync(h,{force:!0}),console.error(" sha256 mismatch"),console.error(` expected: ${u.sha256}`),console.error(` actual: ${x}`),process.exit(1)),console.log(` extract: ${c}`),i.rmSync(c,{recursive:!0,force:!0}),i.mkdirSync(c,{recursive:!0}),await q(h,c),i.existsSync(g.join(c,"index.html"))||(console.error(" extracted tarball is missing index.html \u2014 corrupted runtime"),process.exit(1)),console.log(` installed ${r}`),f&&await $(r)}async function $(e){R(e),console.log(` active: ${e}`),await F(e)||console.log(` (no daemon running \u2014 next sootsim/electron launch will pick up ${e})`)}async function F(e){let{isDaemonLockfileFresh:n,readDaemonLockfile:s}=await import("./home-paths-
|
|
25
|
+
`)}async function E(e,n){let{version:s,flags:t}=z(e),o=t.channel??n.channel??"stable",a=t.force===!0,f=t.setActive!==!1;p(),console.log("sootsim runtime install"),console.log(` cdn: ${y()}`);let l=await D(),m=s||l.channels[o]?.latest;m||(console.error(` no version specified and channel '${o}' has no latest entry in the manifest`),process.exit(1));let r=m,u=l.versions[r];u||(console.error(` version ${r} not found in manifest`),console.error(` available: ${Object.keys(l.versions).slice(-10).join(", ")||"(none)"}`),process.exit(1)),console.log(` version: ${r} (channel: ${o})`);let c=v(r);if(!a&&i.existsSync(g.join(c,"index.html"))){console.log(` already installed at ${c}`),f&&await $(r);return}let b=u.tarball||_(r),h=g.join(S(),`sootsim-runtime-${r}.tar.gz`);console.log(` fetch: ${b}`),await G(b,h),console.log(" verify: sha256");let x=await H(h);x!==u.sha256&&(i.rmSync(h,{force:!0}),console.error(" sha256 mismatch"),console.error(` expected: ${u.sha256}`),console.error(` actual: ${x}`),process.exit(1)),console.log(` extract: ${c}`),i.rmSync(c,{recursive:!0,force:!0}),i.mkdirSync(c,{recursive:!0}),await q(h,c),i.existsSync(g.join(c,"index.html"))||(console.error(" extracted tarball is missing index.html \u2014 corrupted runtime"),process.exit(1)),console.log(` installed ${r}`),f&&await $(r)}async function $(e){R(e),console.log(` active: ${e}`),await F(e)||console.log(` (no daemon running \u2014 next sootsim/electron launch will pick up ${e})`)}async function F(e){let{isDaemonLockfileFresh:n,readDaemonLockfile:s}=await import("./home-paths-4YJJYGR6.js"),t=s();if(!n(t))return!1;let o=k();return new Promise(a=>{let f=!1,l=!1,m=c=>{f||(f=!0,a(c))},r=new M(`ws://127.0.0.1:${o}`,{handshakeTimeout:800}),u=setTimeout(()=>{try{r.close()}catch{}m(l)},1500);r.on("open",()=>{try{r.send(JSON.stringify({type:"runtime:use",version:e,id:0})),l=!0}catch{}setTimeout(()=>{try{r.close()}catch{}},100)}),r.on("close",()=>{clearTimeout(u),m(l)}),r.on("error",()=>{clearTimeout(u),m(!1)})})}async function U(e){p();let n=w(),s=d();if(console.log("installed:"),n.length===0)console.log(" (none)");else for(let t of n)console.log(` ${t===s?"*":" "} ${t}`);try{let t=await D();console.log("available (latest per channel):");for(let[o,a]of Object.entries(t.channels))console.log(` ${o.padEnd(8)} ${a.latest}`)}catch(t){console.log(`available: (could not fetch manifest: ${B(t)})`)}}async function L(e){let n=e[0];n||(console.error(" usage: sootsim runtime use <version>"),process.exit(1));let s=w();s.includes(n)||(console.error(` version ${n} is not installed`),console.error(` installed: ${s.join(", ")||"(none)"}`),console.error(` run \`sootsim runtime install ${n}\` first`),process.exit(1)),await $(n)}async function W(e){let n=e[0];n||(console.error(" usage: sootsim runtime remove <version>"),process.exit(1)),d()===n&&(console.error(` cannot remove active runtime ${n}`),console.error(" switch with `sootsim runtime use <other>` first, or install another version"),process.exit(1));let t=v(n);if(!i.existsSync(t)){console.error(` ${n} is not installed`);return}i.rmSync(t,{recursive:!0,force:!0}),console.log(` removed ${n}`)}async function V(){let e=d();if(!e){console.log(" no active runtime");return}console.log(e)}function z(e){let n={},s=[];for(let t=0;t<e.length;t++){let o=e[t];if(o==="--channel"&&t+1<e.length){n.channel=e[t+1],t++;continue}if(o.startsWith("--channel=")){n.channel=o.slice(10);continue}if(o==="--force"){n.force=!0;continue}if(o==="--set-active=false"||o==="--no-set-active"){n.setActive=!1;continue}s.push(o)}return{version:s[0]??null,flags:n}}async function D(){let e=j(),n=await fetch(e,{headers:{Accept:"application/json"}});if(!n.ok)throw new Error(`manifest fetch failed: ${n.status} ${n.statusText} (${e})`);return await n.json()}async function G(e,n){let s=await fetch(e);if(!s.ok||!s.body)throw new Error(`download failed: ${s.status} ${s.statusText} (${e})`);i.mkdirSync(g.dirname(n),{recursive:!0});let t=`${n}.partial`;try{await C(A.fromWeb(s.body),i.createWriteStream(t)),i.renameSync(t,n)}catch(o){try{i.unlinkSync(t)}catch{}throw o}}function H(e){return new Promise((n,s)=>{let t=N.createHash("sha256"),o=i.createReadStream(e);o.on("data",a=>t.update(a)),o.on("error",s),o.on("end",()=>n(t.digest("hex")))})}function q(e,n){return new Promise((s,t)=>{let o=T("tar",["-xzf",e,"-C",n],{stdio:["ignore","inherit","inherit"]});o.on("error",t),o.on("exit",a=>{a===0?s():t(new Error(`tar exited with code ${a}`))})})}function B(e){return e instanceof Error?e.message:String(e)}export{se as runRuntime};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
/*! sootsim v0.0.
|
|
2
|
-
import{a as v}from"./chunk-
|
|
1
|
+
/*! sootsim v0.0.4 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
|
+
import{a as v}from"./chunk-DQKQYPIG.js";import"./chunk-ZKNI5MRD.js";import"./chunk-4XBPZQLW.js";import"./chunk-XJF46GU2.js";import{f}from"./chunk-EHMSE3Q3.js";import{a as x}from"./chunk-AFQBSK2J.js";import{c as h,d as g,e as w,h as y}from"./chunk-C3QLIYCS.js";import"./chunk-W7CYWXRZ.js";import"./chunk-MZPAJ5PQ.js";import"./chunk-WRF43M33.js";import"./chunk-WWDJCKMI.js";import{mkdirSync as _,writeFileSync as S}from"fs";import{dirname as R,resolve as B}from"path";async function V(e,t){(e.includes("--help")||e.includes("-h"))&&(console.log(`
|
|
3
3
|
sootsim screenshot \u2014 capture the canvas as a PNG
|
|
4
4
|
|
|
5
5
|
usage:
|