sootsim 0.0.4 → 0.1.36
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/LICENSE +21 -0
- package/README.md +4 -4
- package/dist-cli/bin.js +12 -12
- package/dist-cli/chunks/{agent-PJAOF4JS.js → agent-YZB6D3DR.js} +4 -4
- package/dist-cli/chunks/agent-wrapper-VHCVS22I.js +15 -0
- package/dist-cli/chunks/{assert-P47NW4AF.js → assert-AIVCKKLG.js} +2 -2
- package/dist-cli/chunks/auto-bootstrap-MLNTX23H.js +2 -0
- package/dist-cli/chunks/chunk-27P763IZ.js +61 -0
- package/dist-cli/chunks/chunk-3UIWOHC2.js +62 -0
- package/dist-cli/chunks/chunk-5KGFHWVR.js +1 -0
- package/dist-cli/chunks/chunk-5QIUJNT3.js +5 -0
- package/dist-cli/chunks/{chunk-W7CYWXRZ.js → chunk-6GGMKFWJ.js} +1 -1
- package/dist-cli/chunks/{chunk-EHMSE3Q3.js → chunk-6Z275LCY.js} +2 -2
- package/dist-cli/chunks/chunk-75LBYBKW.js +11 -0
- package/dist-cli/chunks/chunk-A5BRCXYE.js +2 -0
- package/dist-cli/chunks/{chunk-UQ3N6FZF.js → chunk-CYCXOAVZ.js} +2 -2
- package/dist-cli/chunks/{chunk-QIP7LYQI.js → chunk-DFN3GGH7.js} +2 -2
- package/dist-cli/chunks/chunk-EBEHZJRG.js +117 -0
- package/dist-cli/chunks/{chunk-UKYK63H6.js → chunk-EJLNUMMP.js} +1 -1
- package/dist-cli/chunks/{chunk-DQKQYPIG.js → chunk-EWSQSALM.js} +2 -2
- package/dist-cli/chunks/{chunk-BQRM4E66.js → chunk-FE7UI3MT.js} +4 -4
- package/dist-cli/chunks/chunk-G663654J.js +1 -0
- package/dist-cli/chunks/chunk-G7XQD4KC.js +4 -0
- package/dist-cli/chunks/chunk-GW7XY5KC.js +2 -0
- package/dist-cli/chunks/{chunk-QQOBLF7O.js → chunk-H2QO4TDV.js} +2 -2
- package/dist-cli/chunks/{chunk-I6XGFZPA.js → chunk-HWCKZXNJ.js} +2 -2
- package/dist-cli/chunks/{chunk-UNFERMZ3.js → chunk-HWFHBMAQ.js} +2 -2
- package/dist-cli/chunks/chunk-IJMYFYDZ.js +2 -0
- package/dist-cli/chunks/chunk-J7CTD37P.js +1 -0
- package/dist-cli/chunks/{chunk-432TMHBG.js → chunk-KAXZHEKM.js} +1 -1
- package/dist-cli/chunks/{chunk-WWDJCKMI.js → chunk-LHDWH7VS.js} +1 -1
- package/dist-cli/chunks/{chunk-VGXARPIH.js → chunk-N32NCVL2.js} +2 -2
- package/dist-cli/chunks/{chunk-XJF46GU2.js → chunk-NIZBR7EK.js} +2 -2
- package/dist-cli/chunks/{chunk-MQDPKSCK.js → chunk-NYY36OKU.js} +12 -12
- package/dist-cli/chunks/{chunk-5TTQKPGH.js → chunk-OXN2PEB7.js} +1 -1
- package/dist-cli/chunks/{chunk-SY74J6F4.js → chunk-PJL25JQV.js} +1 -1
- package/dist-cli/chunks/{chunk-4XBPZQLW.js → chunk-RMW5BO3S.js} +2 -2
- package/dist-cli/chunks/chunk-SHO54NET.js +2 -0
- package/dist-cli/chunks/chunk-SMVJOWSV.js +16 -0
- package/dist-cli/chunks/chunk-TC6V7YFC.js +3 -0
- package/dist-cli/chunks/{chunk-6SZMLFCR.js → chunk-VFDRZNPN.js} +1 -1
- package/dist-cli/chunks/{chunk-AFQBSK2J.js → chunk-YIO6S3R5.js} +1 -1
- package/dist-cli/chunks/{chunk-AUR2LTNX.js → chunk-YLIIVTTQ.js} +2 -2
- package/dist-cli/chunks/chunk-YR7BGGYE.js +2 -0
- package/dist-cli/chunks/chunk-ZEW3RF5Q.js +1 -0
- package/dist-cli/chunks/{compat-ILLJ7VDL.js → compat-Y2O2U7FL.js} +2 -2
- package/dist-cli/chunks/{config-CDIAJIIT.js → config-SRBOFUCI.js} +2 -2
- package/dist-cli/chunks/control-PL2V2O6S.js +2 -0
- package/dist-cli/chunks/daemon-IZC32PZW.js +50 -0
- package/dist-cli/chunks/{debug-6SMCTPMC.js → debug-BIDMW2PE.js} +3 -3
- package/dist-cli/chunks/demo-app-registry-5JFOUU3D.js +2 -0
- package/dist-cli/chunks/{detox-R4G5INNB.js → detox-B3FDOIS3.js} +2 -2
- package/dist-cli/chunks/{device-YSLCWS4E.js → device-ZZSI363W.js} +2 -2
- package/dist-cli/chunks/drivers-S4NGK4DB.js +2 -0
- package/dist-cli/chunks/{electron-JZOFO37G.js → electron-5YFHXEOI.js} +3 -3
- package/dist-cli/chunks/flow-JJBO6TFY.js +2 -0
- package/dist-cli/chunks/{hints-O4QR6UGI.js → hints-G5HBBV2O.js} +2 -2
- package/dist-cli/chunks/home-paths-VWC3FWA3.js +2 -0
- package/dist-cli/chunks/{inspect-DRFAUJUH.js → inspect-POOPWUQI.js} +56 -52
- package/dist-cli/chunks/install-MP6FHXNZ.js +2 -0
- package/dist-cli/chunks/install-desktop-2MYEI4FM.js +23 -0
- package/dist-cli/chunks/{install-dev-desktop-CAJHPRNP.js → install-dev-desktop-SKH3KEHY.js} +2 -2
- package/dist-cli/chunks/{keys-OWQ7SOTM.js → keys-7PNASIQR.js} +2 -2
- package/dist-cli/chunks/{launch-WUEDHSO5.js → launch-JNS47LAQ.js} +3 -3
- package/dist-cli/chunks/login-YWZWUHBS.js +26 -0
- package/dist-cli/chunks/logout-O6SXMSBP.js +2 -0
- package/dist-cli/chunks/{maestro-PMHK6EHI.js → maestro-CW6XVUKV.js} +3 -3
- package/dist-cli/chunks/{preview-4RVHA2PP.js → preview-WGKJO5FS.js} +2 -2
- package/dist-cli/chunks/{profile-3IVNHUS6.js → profile-SUOBRPIC.js} +2 -2
- package/dist-cli/chunks/{record-KEWLM5JR.js → record-QPWLYH5R.js} +2 -2
- package/dist-cli/chunks/runtime-KEMO2MSB.js +25 -0
- package/dist-cli/chunks/{screenshot-BXRAQERZ.js → screenshot-JTY46V7G.js} +2 -2
- package/dist-cli/chunks/{screenshot-mode-5IXEDIUS.js → screenshot-mode-7OYBBX6D.js} +2 -2
- package/dist-cli/chunks/{screenshots-T4MQF3TB.js → screenshots-QISKC4GD.js} +2 -2
- package/dist-cli/chunks/server-YSFJAKAV.js +34 -0
- package/dist-cli/chunks/setup-repo-LFB3HBEO.js +2 -0
- package/dist-cli/chunks/{skills-DJA6QEVR.js → skills-MO7BFNVM.js} +2 -2
- package/dist-cli/chunks/store-6MFL53I4.js +2 -0
- package/dist-cli/chunks/telemetry-CN42GMVC.js +2 -0
- package/dist-cli/chunks/{test-IWUHNFXV.js → test-XUI3KNNQ.js} +3 -3
- package/dist-cli/chunks/upload-6FUT7AX5.js +2 -0
- package/dist-cli/chunks/{whoami-MCXFWKIH.js → whoami-TQFHY42N.js} +2 -2
- package/dist-lib/agent-daemon-client.cjs +3 -1
- package/dist-lib/agent-events.cjs +1 -1
- package/dist-lib/agent-sessions.cjs +2 -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 +3 -1
- package/dist-lib/home-paths.cjs +29 -3
- package/dist-lib/host/bridge-host.cjs +499 -59
- package/dist-lib/index.cjs +2 -2
- package/dist-lib/metro.cjs +2 -2
- package/dist-lib/render-mode.cjs +1 -1
- package/dist-lib/vite-base.cjs +800 -102
- package/dist-lib/vite.cjs +1 -1
- package/package.json +5 -3
- package/dist-cli/chunks/agent-wrapper-STO7PLQD.js +0 -15
- package/dist-cli/chunks/auto-bootstrap-SC2LMI2H.js +0 -2
- package/dist-cli/chunks/chunk-47S5DXXX.js +0 -11
- package/dist-cli/chunks/chunk-4VXB2DBA.js +0 -119
- package/dist-cli/chunks/chunk-C3QLIYCS.js +0 -16
- package/dist-cli/chunks/chunk-F4ARVCRR.js +0 -1
- package/dist-cli/chunks/chunk-HAKR72LJ.js +0 -2
- package/dist-cli/chunks/chunk-HGFIS26A.js +0 -2
- package/dist-cli/chunks/chunk-MZPAJ5PQ.js +0 -1
- package/dist-cli/chunks/chunk-OAHMYSMD.js +0 -2
- package/dist-cli/chunks/chunk-W3TYN64D.js +0 -62
- package/dist-cli/chunks/chunk-WRF43M33.js +0 -4
- package/dist-cli/chunks/chunk-WVBPATRA.js +0 -2
- package/dist-cli/chunks/chunk-ZF5FCFLD.js +0 -2
- package/dist-cli/chunks/chunk-ZKNI5MRD.js +0 -1
- package/dist-cli/chunks/control-7QGKUCAX.js +0 -2
- package/dist-cli/chunks/daemon-4BLYGM5N.js +0 -49
- package/dist-cli/chunks/demo-app-registry-HLI5UGGI.js +0 -2
- package/dist-cli/chunks/drivers-YIXRFFBQ.js +0 -2
- package/dist-cli/chunks/flow-L7X5FGIN.js +0 -2
- package/dist-cli/chunks/home-paths-4YJJYGR6.js +0 -2
- package/dist-cli/chunks/install-BATRTWRI.js +0 -65
- package/dist-cli/chunks/install-desktop-6X474IQ3.js +0 -23
- package/dist-cli/chunks/login-54YJ2KH6.js +0 -26
- package/dist-cli/chunks/logout-XECXLEXW.js +0 -2
- package/dist-cli/chunks/runtime-PJKHEB36.js +0 -25
- package/dist-cli/chunks/server-CIP3LH45.js +0 -29
- package/dist-cli/chunks/store-SPC247DB.js +0 -2
- package/dist-cli/chunks/upload-UPD2RSYF.js +0 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
/*! sootsim v0.
|
|
2
|
-
import{a as U}from"./chunk-
|
|
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,
|
|
1
|
+
/*! sootsim v0.1.36 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
|
+
import{a as U}from"./chunk-N32NCVL2.js";import{a as Ne,b as _e}from"./chunk-YIO6S3R5.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-CYCXOAVZ.js";import{a as Te,e as ae}from"./chunk-HWCKZXNJ.js";import{a as me,c as pe,d as xe}from"./chunk-EBEHZJRG.js";import{b as Ae,h as Pe}from"./chunk-75LBYBKW.js";import"./chunk-GW7XY5KC.js";import{a as Me}from"./chunk-OXN2PEB7.js";import"./chunk-YR7BGGYE.js";import"./chunk-PJL25JQV.js";import"./chunk-G663654J.js";import"./chunk-A5BRCXYE.js";import{a as we}from"./chunk-SHO54NET.js";import{c as $e,e as Se,f as ve,h as ke}from"./chunk-SMVJOWSV.js";import"./chunk-6GGMKFWJ.js";import"./chunk-ZEW3RF5Q.js";import"./chunk-5QIUJNT3.js";import"./chunk-LHDWH7VS.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 ht,join as bt,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]||bt(yt(),"sootsim-inspect-notice-state.json"))}function vt(o,c){return Object.fromEntries(Object.entries(o).filter(([,i])=>typeof i?.signature=="string"&&Number.isFinite(i?.updatedAt)&&c-i.updatedAt<=$t))}function kt(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:vt(i.entries,o)}}catch{return Oe(c,{force:!0}),{version:oe,entries:{}}}}function Tt(o){let c=Ee();pt(ht(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,h=kt(u),v=Mt(o,c),$=h.entries[v];return $&&$.signature===i&&u-$.updatedAt<a?!1:(h.entries[v]={signature:i,updatedAt:u},Tt(h),!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),h=u&&!a,v=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"),k=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:h});let Z=`(async () => {
|
|
4
4
|
const t = window.__sootsimTest
|
|
5
5
|
const mainShell = window.SootSim?.bridges?.mainShell
|
|
6
6
|
const kb = window.__sootsimKeyboard
|
|
@@ -11,21 +11,21 @@ import{a as U}from"./chunk-VGXARPIH.js";import{a as Ne,b as _e}from"./chunk-AFQB
|
|
|
11
11
|
shell = typeof mainShell?.getState === 'function' ? await mainShell.getState() : null
|
|
12
12
|
} catch {}
|
|
13
13
|
|
|
14
|
-
const tree = await t.dumpTree(12, ${JSON.stringify({describe:!0,verbose:u,filter:R||"",testIdLike:S||void 0,onlyGlob:D||void 0,subtreeRoot:
|
|
14
|
+
const tree = await t.dumpTree(12, ${JSON.stringify({describe:!0,verbose:u,filter:R||"",testIdLike:S||void 0,onlyGlob:D||void 0,subtreeRoot:k||void 0,compact:I,hideXy:y})})
|
|
15
15
|
const nodeCount = (await t.getNodeCount?.()) || 0
|
|
16
16
|
const keyboard = kb && typeof kb.getLayout === 'function' ? kb.getLayout() : null
|
|
17
17
|
return { tree, shell, nodeCount, keyboard }
|
|
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||
|
|
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||k)&&e<10&&U("app-still-loading",e);return}if(console.log(J),!(R||S||D||k)&&!v&&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
|
-
keyboard: ${t.join(" ")||"visible"}`)}};if(
|
|
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,
|
|
20
|
+
keyboard: ${t.join(" ")||"visible"}`)}};if(v)for(console.log(` watching... (Ctrl+C to stop)
|
|
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,h=x=>{let J=d.indexOf(x);return J>=0&&J+1<d.length?d[J+1]:null},v=x=>d.includes(x),$=h("--testid")||h("--test-id"),I=h("--role"),y=h("--type"),S=h("--text"),A=v("--pressable"),k=v("--visible"),j=!$&&!I&&!y&&!S&&!A&&!k?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 () => {
|
|
25
25
|
const t = window.__sootsimTest
|
|
26
26
|
const all = await t.queryAll({ pruneHidden: true })
|
|
27
27
|
return all.filter(n => n.pressable)
|
|
28
|
-
})()`):
|
|
28
|
+
})()`):k?(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
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(`
|
|
@@ -36,7 +36,7 @@ import{a as U}from"./chunk-VGXARPIH.js";import{a as Ne,b as _e}from"./chunk-AFQB
|
|
|
36
36
|
return { error: 'keyboard bridge getLayout() not available' }
|
|
37
37
|
}
|
|
38
38
|
return kb.getLayout()
|
|
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:
|
|
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:h,capsLock:v,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}${h?" (shifted)":""}${v?" (caps)":""}`),$&&I.push(` accessoryBar: ${$}`),console.log(I.join(`
|
|
40
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
|
|
@@ -73,9 +73,11 @@ import{a as U}from"./chunk-VGXARPIH.js";import{a as Ne,b as _e}from"./chunk-AFQB
|
|
|
73
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
|
+
// host-side __sootsimTest is a Proxy that forwards every call to the
|
|
77
|
+
// tenant worker \u2014 every method returns a Promise, so we must await.
|
|
76
78
|
const navSnap =
|
|
77
79
|
test && typeof test.getNavigationSnapshot === 'function'
|
|
78
|
-
? test.getNavigationSnapshot()
|
|
80
|
+
? await test.getNavigationSnapshot()
|
|
79
81
|
: null
|
|
80
82
|
const keyboard =
|
|
81
83
|
kb && typeof kb.getLayout === 'function'
|
|
@@ -94,7 +96,7 @@ import{a as U}from"./chunk-VGXARPIH.js";import{a as Ne,b as _e}from"./chunk-AFQB
|
|
|
94
96
|
})()
|
|
95
97
|
: null
|
|
96
98
|
return { nav: navSnap, keyboard }
|
|
97
|
-
})()`}),d=i?.nav??null,u=i?.keyboard??null,a=await V(o,500).catch(()=>null);if(c.json){console.log(JSON.stringify({shell:a??null,nav:d,keyboard:u},null,2));return}let
|
|
99
|
+
})()`}),d=i?.nav??null,u=i?.keyboard??null,a=await V(o,500).catch(()=>null);if(c.json){console.log(JSON.stringify({shell:a??null,nav:d,keyboard:u},null,2));return}let h=[];if(a){let v=a.activeApp??a.state??"<none>",$=a.showSwitcher?" (app switcher open)":"",I=typeof a.launchProgress=="number"&&a.launchProgress<.98?` launching (${Math.round(a.launchProgress*100)}%)`:"";h.push(`shell: ${v}${$}${I}`)}else h.push("shell: <unavailable>");if(d){let v=d.transitionPhase!=="idle"?` (${d.transitionPhase}, ${d.activeTransitionCount} active)`:"";if(h.push(`nav: phase=${d.transitionPhase}${v}`),d.screens.length===0)h.push(" <no registered screens \u2014 app may not use react-native-screens>");else for(let $ of d.screens){let I=$.isActive?"\u25B6":" ",y=$.routeName?` ${$.routeName}`:"",S=$.headerHeight>0?` header=${$.headerHeight}`:"",A=$.largeTitleState&&$.largeTitleState!=="expanded"?` large-title=${$.largeTitleState}`:"";h.push(` ${I} #${$.id}${y}${S}${A}`)}}else h.push("nav: <runtime not available>");if(u&&u.visible){let v=u.spec?.keyboardType??"default",$=u.spec?.returnKeyType??"default";h.push(`keyboard: visible (${v}, return=${$}, mode=${u.mode??"?"})`)}else h.push("keyboard: hidden");console.log(h.join(`
|
|
98
100
|
`))}async function ee({bridge:o,maxMs:c,pollMs:i=50,stablePolls:d=3,strict:u=!1}){let a=await o.send({type:"evaluate",code:`(async () => {
|
|
99
101
|
const start = Date.now()
|
|
100
102
|
const deadline = start + ${Math.max(0,Math.round(c))}
|
|
@@ -144,7 +146,7 @@ import{a as U}from"./chunk-VGXARPIH.js";import{a as Ne,b as _e}from"./chunk-AFQB
|
|
|
144
146
|
await sleep(pollMs)
|
|
145
147
|
}
|
|
146
148
|
return { settled: false, elapsed: Date.now() - start }
|
|
147
|
-
})()`}),{elapsed:
|
|
149
|
+
})()`}),{elapsed:h,settled:v}=a??{};return{elapsed:typeof h=="number"?h:c,settled:v===!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:h,settled:v}=await ee({bridge:c,maxMs:u,strict:a});console.log(v?` settled in ${h}ms`:` timed out after ${h}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,h=Math.max(1e3,(Number.isFinite(a)?a:30)*1e3),v=Math.max(1,Math.ceil(h/500));console.log(" waiting for browser reconnect...");let $=await Ie(c,i,d,{attempts:v});$||(console.error(" timed out waiting for browser reconnect"),process.exit(1)),$.bridge.close(),ae({source:"inspect wait",step:{wait:h},summary:`wait ${Math.round(h/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:h,settled:v}=await ee({bridge:c,maxMs:a,strict:d});v?console.log(` idle in ${h}ms`):(console.error(` \u26A0 wait idle timed out after ${h}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(),h=a+d,v=`(async () => {
|
|
148
150
|
const t = window.__sootsimTest
|
|
149
151
|
let nodes = 0
|
|
150
152
|
try { nodes = (await t?.getNodeCount?.()) || 0 } catch {}
|
|
@@ -153,9 +155,9 @@ import{a as U}from"./chunk-VGXARPIH.js";import{a as Ne,b as _e}from"./chunk-AFQB
|
|
|
153
155
|
at: (window).__sootsimExternalAppReadyAt || 0,
|
|
154
156
|
nodes,
|
|
155
157
|
}
|
|
156
|
-
})()`,$={flag:void 0,at:0,nodes:0};for(;Date.now()<
|
|
158
|
+
})()`,$={flag:void 0,at:0,nodes:0};for(;Date.now()<h;){try{$=await c.send({type:"evaluate",code:v})??$}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 h=i.indexOf("--max-ms"),v=h>=0&&i[h+1]?Math.max(100,Number(i[h+1])):5e3,$=await c.send({type:"evaluate",code:`(async () => {
|
|
157
159
|
const start = Date.now()
|
|
158
|
-
const deadline = start + ${
|
|
160
|
+
const deadline = start + ${v}
|
|
159
161
|
const t = window.__sootsimTest
|
|
160
162
|
const find = async () => {
|
|
161
163
|
try {
|
|
@@ -172,8 +174,8 @@ import{a as U}from"./chunk-VGXARPIH.js";import{a as Ne,b as _e}from"./chunk-AFQB
|
|
|
172
174
|
await new Promise((r) => setTimeout(r, 80))
|
|
173
175
|
}
|
|
174
176
|
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)})`:"",
|
|
176
|
-
`).slice(0,5);for(let
|
|
177
|
+
})()`}),{found:I,node:y,elapsed:S}=$??{};if(I&&y){let A=y.absolutePosition?`@(${Math.round(y.absolutePosition.x)},${Math.round(y.absolutePosition.y)})`:"",k=y.layout?`${Math.round(y.layout.width)}x${Math.round(y.layout.height)}`:"?x?";console.log(` found #${a} in ${S}ms ${k} ${A}`)}else console.error(` \u26A0 wait selector #${a} timed out after ${S??v}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(`
|
|
178
|
+
`).slice(0,5);for(let h of a)console.log(` ${h.trim()}`)}}var G="__sootsimCliPerf",Ot=120;async function tt(o,c){let i=o.find((A,k)=>o[k-1]==="--id"),d=o.find((A,k)=>o[k-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:k,y:j,w:l,h:R}=A;return{x:k,y:j,w:l,h:R}}let u=o.find((A,k)=>o[k-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[k,j,l,R]=A;return{x:k,y:j,w:l,h:R}}let a=A=>{let k=o.find((l,R)=>o[R-1]===A);if(k==null)return null;let j=Number(k);return Number.isFinite(j)?j:null},h=a("--x"),v=a("--y"),$=a("--w"),I=a("--h");if(h!=null||v!=null||$!=null||I!=null)return{x:h??0,y:v??0,w:$??1,h:I??1};let S=o.filter((A,k)=>k>0&&!A.startsWith("-")&&o[k-1]!=="--output"&&o[k-1]!=="--area"&&o[k-1]!=="--id"&&o[k-1]!=="--text"&&o[k-1]!=="--x"&&o[k-1]!=="--y"&&o[k-1]!=="--w"&&o[k-1]!=="--h").map(Number).filter(A=>Number.isFinite(A));if(S.length>=2){let[A,k,j=1,l=1]=S;return{x:A,y:k,w:j,h:l}}return null}function he(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 be(o){return o.send({type:"evaluate",code:`(async () => {
|
|
177
179
|
const kb = window.__sootsimKeyboard
|
|
178
180
|
const test = window.__sootsimTest
|
|
179
181
|
if (!kb) return { error: 'keyboard bridge not available' }
|
|
@@ -205,30 +207,32 @@ import{a as U}from"./chunk-VGXARPIH.js";import{a as Ne,b as _e}from"./chunk-AFQB
|
|
|
205
207
|
frame: runtimeSnapshot?.keyboard?.frame ?? null,
|
|
206
208
|
focusedRect: runtimeSnapshot?.focused?.rect ?? null,
|
|
207
209
|
}
|
|
208
|
-
})()`})}async function Et(o,c=600){let i=Date.now()+c;for(;Date.now()<=i;){let d=await
|
|
210
|
+
})()`})}async function Et(o,c=600){let i=Date.now()+c;for(;Date.now()<=i;){let d=await be(o);if(d.visible)return d;await Y(30)}return be(o)}async function ue(o,c){let i=await be(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
211
|
const requested = ${JSON.stringify(i??"toggle")}
|
|
210
212
|
const rootBg = (document.documentElement?.style?.background || '').toLowerCase()
|
|
211
213
|
const inferredCurrent = rootBg.includes('33') ? 'dark' : 'light'
|
|
212
|
-
let
|
|
214
|
+
let next = requested
|
|
213
215
|
if (requested === 'toggle') {
|
|
214
|
-
|
|
215
|
-
} else if (requested === 'auto') {
|
|
216
|
-
applied = window.matchMedia?.('(prefers-color-scheme: dark)')?.matches ? 'dark' : 'light'
|
|
216
|
+
next = inferredCurrent === 'dark' ? 'light' : 'dark'
|
|
217
217
|
}
|
|
218
|
-
|
|
219
|
-
|
|
218
|
+
// engine accepts 'auto' since the schema picker landed; pass through.
|
|
219
|
+
window.postMessage({ type: 'soot-action', action: 'set-appearance', value: next }, '*')
|
|
220
|
+
const applied = next === 'auto'
|
|
221
|
+
? (window.matchMedia?.('(prefers-color-scheme: dark)')?.matches ? 'dark' : 'light')
|
|
222
|
+
: next
|
|
223
|
+
return { ok: true, requested, value: next, applied }
|
|
220
224
|
})()`}):o.send({type:"evaluate",code:`(async () => {
|
|
221
225
|
window.dispatchEvent(new CustomEvent(${JSON.stringify(c==="lock"?"sootsim:toggleLock":"sootsim:shake")}))
|
|
222
226
|
return { ok: true, action: ${JSON.stringify(c)} }
|
|
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,
|
|
227
|
+
})()`})}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,h=a[0],v=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 ${v} ${e}`,S=(e,t)=>` usage: ${y(e)}${t?` ${t}`:""}`;if(!h||o.includes("--help")||o.includes("-h")){let e={bridgePort:7668,defaultShellUrl:we};if(v==="do"||v==="get"||v==="debug"||v==="wait"){let r=me(v,e);r&&(console.log(`${r}
|
|
224
228
|
`),process.exit(0))}if(I==="shell"){let r=pe("shell",e);r&&(console.log(`${r}
|
|
225
229
|
`),process.exit(0))}let t=pe("inspect",e),s=["do","get","debug","wait"].map(r=>me(r,e)).filter(r=>r!=null).join(`
|
|
226
230
|
|
|
227
231
|
`);console.log(`${t??""}
|
|
228
232
|
|
|
229
233
|
${s}
|
|
230
|
-
`),process.exit(0)}let A=u.wsPort,
|
|
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),
|
|
234
|
+
`),process.exit(0)}let A=u.wsPort,k=u.browserId,j=u.commandTimeoutMs;if(h==="list"&&d.some(e=>e==="--drivers"||e==="-D")){let{buildDriverListRows:e}=await import("./drivers-S4NGK4DB.js"),t=e();console.log(` available drivers (${t.length}):
|
|
235
|
+
`);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),b=n.kind.padEnd(r);console.log(` ${m} ${p} ${b} ${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=k||"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
236
|
`)}catch{}}async function Z(){try{return await l.send({type:"evaluate",code:`(() => ({
|
|
233
237
|
console: window.__sootsimConsole?.count?.() || null,
|
|
234
238
|
requests: window.__sootsimTest?.getRequestCounts?.() || null,
|
|
@@ -238,7 +242,7 @@ ${s}
|
|
|
238
242
|
`);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
243
|
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
244
|
recent console errors:
|
|
241
|
-
`);for(let
|
|
245
|
+
`);for(let b of p){let f=new Date(b.timestamp).toLocaleTimeString(),w=Array.isArray(b.args)?b.args.map(O=>typeof O=="object"?JSON.stringify(O):String(O)).join(" "):String(b);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");v==="do"&&h==="shell"&&(console.error(" `sootsim do shell` was removed. use `sootsim shell ...` instead."),process.exit(1)),H.has(h)&&await ve(l),K.has(h)&&await ie(l,{verbose:Q});try{switch(h){case"list":{await Je({bridge:l,browserId:k,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
246
|
const t = window.__sootsimTest
|
|
243
247
|
if (!t) return []
|
|
244
248
|
const all = await t.queryAll({ pruneHidden: true })
|
|
@@ -267,7 +271,7 @@ ${s}
|
|
|
267
271
|
size: n.layout ? { w: Math.round(n.layout.width), h: Math.round(n.layout.height) } : null,
|
|
268
272
|
}))
|
|
269
273
|
})()`});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 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:
|
|
274
|
+
`);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:k,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((b,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:b}=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} ${b} 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
275
|
const t = window.__sootsimTest
|
|
272
276
|
const q = ${JSON.stringify(e)}
|
|
273
277
|
let node = null
|
|
@@ -323,17 +327,17 @@ ${s}
|
|
|
323
327
|
transform,
|
|
324
328
|
parentChain,
|
|
325
329
|
}
|
|
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=
|
|
330
|
+
})()`});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=h==="swipe"?10:12,m=h==="swipe"?8:16,p=a[5]?Number(a[5]):n,b=a[6]?Number(a[6]):m;(!Number.isFinite(e)||!Number.isFinite(t)||!Number.isFinite(s)||!Number.isFinite(r)||!Number.isFinite(p)||!Number.isFinite(b))&&(console.error(S(h,"<x1> <y1> <x2> <y2> [steps] [stepMs]")),process.exit(1));let f=await l.send({type:"evaluate",code:`(async () => {
|
|
327
331
|
const interact = window.__sootsimInteract
|
|
328
332
|
if (!interact?.drag) return { ok: false, reason: 'no interact.drag' }
|
|
329
|
-
const value = await interact.drag(${e}, ${t}, ${s}, ${r}, ${Math.max(1,Math.round(p))}, ${Math.max(0,Math.round(
|
|
333
|
+
const value = await interact.drag(${e}, ${t}, ${s}, ${r}, ${Math.max(1,Math.round(p))}, ${Math.max(0,Math.round(b))})
|
|
330
334
|
return { ok: !!value, value }
|
|
331
|
-
})()`});if(f?.ok){let w=Math.max(1,Math.round(Math.max(1,p)*Math.max(0,
|
|
335
|
+
})()`});if(f?.ok){let w=Math.max(1,Math.round(Math.max(1,p)*Math.max(0,b)));await L(`inspect ${h}`,{swipe:{start:`${e}, ${t}`,end:`${s}, ${r}`,duration:w}},`${h} ${e},${t} -> ${s},${r}`)}console.log(JSON.stringify(f,null,2));break}case"pinch":{let e=Number(a[1]),t=Number(a[2]),s=Number(a[3]),r=Number(a[4]),n=Number(a[5]),m=Number(a[6]),p=Number(a[7]),b=Number(a[8]),f=a[9]?Number(a[9]):12,w=a[10]?Number(a[10]):16;(!Number.isFinite(e)||!Number.isFinite(t)||!Number.isFinite(s)||!Number.isFinite(r)||!Number.isFinite(n)||!Number.isFinite(m)||!Number.isFinite(p)||!Number.isFinite(b)||!Number.isFinite(f)||!Number.isFinite(w))&&(console.error(S("pinch","<x1> <y1> <x2> <y2> <x1'> <y1'> <x2'> <y2'> [steps] [stepMs]")),process.exit(1));let O=await l.send({type:"evaluate",code:`(async () => {
|
|
332
336
|
const interact = window.__sootsimInteract
|
|
333
337
|
if (!interact?.pinch) return { ok: false, reason: 'no interact.pinch' }
|
|
334
|
-
const value = await interact.pinch(${e}, ${t}, ${s}, ${r}, ${n}, ${m}, ${p}, ${
|
|
338
|
+
const value = await interact.pinch(${e}, ${t}, ${s}, ${r}, ${n}, ${m}, ${p}, ${b}, ${Math.max(1,Math.round(f))}, ${Math.max(0,Math.round(w))})
|
|
335
339
|
return { ok: !!value, value }
|
|
336
|
-
})()`});O?.ok&&await L("inspect pinch",{pinch:{from:[e,t,s,r],to:[n,m,p,
|
|
340
|
+
})()`});O?.ok&&await L("inspect pinch",{pinch:{from:[e,t,s,r],to:[n,m,p,b],steps:Math.max(1,Math.round(f)),stepMs:Math.max(0,Math.round(w))}},`pinch (${e},${t}) (${s},${r}) -> (${n},${m}) (${p},${b})`),console.log(JSON.stringify(O,null,2));break}case"tap-text":{let e=a[1];e||(console.error(S("tap-text","<text>")),process.exit(1));let t=_=>{let P=o.indexOf(_);return P>=0&&P+1<o.length?o[P+1]:null},s=_=>o.includes(_),r=t("--nth")??t("--index"),n=r!==null?Number(r):null;n!==null&&!Number.isFinite(n)&&(console.error(` --nth/--index requires an integer, got: ${r}`),process.exit(1));let m=t("--within"),p=t("--role"),b=s("--exact"),f=s("--first"),w=t("--min-y"),O=t("--max-y"),B=t("--min-x"),N=t("--max-x");for(let[_,P]of[["--min-y",w],["--max-y",O],["--min-x",B],["--max-x",N]])P!==null&&!Number.isFinite(Number(P))&&(console.error(` ${_} requires a number, got: ${P}`),process.exit(1));let M=o.indexOf("--near"),F=null;if(M>=0){let _=Number(o[M+1]),P=Number(o[M+2]);(!Number.isFinite(_)||!Number.isFinite(P))&&(console.error(" --near requires two numbers: --near <x> <y>"),process.exit(1)),F={x:_,y:P}}let W=JSON.stringify({query:e,exact:b,role:p,within:m,minX:B!==null?Number(B):null,maxX:N!==null?Number(N):null,minY:w!==null?Number(w):null,maxY:O!==null?Number(O):null,near:F,nth:n,first:f}),g=await l.send({type:"evaluate",code:`(async () => {
|
|
337
341
|
const t = window.__sootsimTest
|
|
338
342
|
if (!t) return { error: 'bridge-not-ready' }
|
|
339
343
|
const F = ${W}
|
|
@@ -522,13 +526,13 @@ ${s}
|
|
|
522
526
|
if (!interact?.longPress) return { ok: false, reason: 'no interact.longPress' }
|
|
523
527
|
const value = await interact.longPress(${e}, ${t}, ${Math.max(0,Math.round(r))})
|
|
524
528
|
return { ok: !!value, value }
|
|
525
|
-
})()`});n?.ok&&await L("inspect long-press",{tapAtCoords:{x:e,y:t}},`long-press @${e},${t}`),console.log(JSON.stringify(n,null,2));break}case"touch":{let e=a[1],t=Number(a[2]),s=Number(a[3]),r=a[4]?Number(a[4]):999,n=e==="down"?"touchDown":e==="move"?"touchMove":e==="up"?"touchUp":e==="cancel"?"touchCancel":null;n||(console.error(S("touch","<down|move|up|cancel> <x> <y> [pointerId]")),process.exit(1)),e!=="cancel"&&(!Number.isFinite(t)||!Number.isFinite(s))&&(console.error(S("touch","<down|move|up|cancel> <x> <y> [pointerId]")),process.exit(1));let m=e==="down"?"tap":e==="move"?"move":null,p=m&&Number.isFinite(t)&&Number.isFinite(s)?`window.dispatchEvent(new CustomEvent('sootsim:agentAction', { detail: { type: '${m}', x: ${t}, y: ${s} } }));`:"",
|
|
529
|
+
})()`});n?.ok&&await L("inspect long-press",{tapAtCoords:{x:e,y:t}},`long-press @${e},${t}`),console.log(JSON.stringify(n,null,2));break}case"touch":{let e=a[1],t=Number(a[2]),s=Number(a[3]),r=a[4]?Number(a[4]):999,n=e==="down"?"touchDown":e==="move"?"touchMove":e==="up"?"touchUp":e==="cancel"?"touchCancel":null;n||(console.error(S("touch","<down|move|up|cancel> <x> <y> [pointerId]")),process.exit(1)),e!=="cancel"&&(!Number.isFinite(t)||!Number.isFinite(s))&&(console.error(S("touch","<down|move|up|cancel> <x> <y> [pointerId]")),process.exit(1));let m=e==="down"?"tap":e==="move"?"move":null,p=m&&Number.isFinite(t)&&Number.isFinite(s)?`window.dispatchEvent(new CustomEvent('sootsim:agentAction', { detail: { type: '${m}', x: ${t}, y: ${s} } }));`:"",b=await l.send({type:"evaluate",code:`(async () => {
|
|
526
530
|
${p}
|
|
527
531
|
const interact = window.__sootsimInteract
|
|
528
532
|
if (!interact?.${n}) return { ok: false, reason: 'no interact.${n}' }
|
|
529
533
|
const value = ${e==="cancel"?`await interact.${n}(${Math.max(1,Math.round(r))})`:`await interact.${n}(${t}, ${s}, ${Math.max(1,Math.round(r))})`}
|
|
530
534
|
return { ok: !!value, value }
|
|
531
|
-
})()`});
|
|
535
|
+
})()`});b?.ok&&e!=="cancel"&&await L("inspect touch",{tapAtCoords:{x:t,y:s}},`touch ${e} @${t},${s}`),console.log(JSON.stringify(b,null,2));break}case"gesture":{let e=a[1],t=a[2]?Number(a[2]):220;(!e||!Number.isFinite(t))&&(console.error(S("gesture","<preset> [durationMs]")),process.exit(1));let s=await l.send({type:"evaluate",code:`(async () => {
|
|
532
536
|
const spec = globalThis.__sootsimDeviceSpec || {}
|
|
533
537
|
return {
|
|
534
538
|
width: spec.width || window.innerWidth || 393,
|
|
@@ -536,7 +540,7 @@ ${s}
|
|
|
536
540
|
statusBarHeight: spec.statusBarHeight || 0,
|
|
537
541
|
homeIndicatorHeight: spec.homeIndicatorHeight || 0,
|
|
538
542
|
}
|
|
539
|
-
})()`}),r=Number(s?.width)||393,n=Number(s?.height)||852,m=Number(s?.statusBarHeight)||0,p=Number(s?.homeIndicatorHeight)||0,
|
|
543
|
+
})()`}),r=Number(s?.width)||393,n=Number(s?.height)||852,m=Number(s?.statusBarHeight)||0,p=Number(s?.homeIndicatorHeight)||0,b=Math.round(r/2),f=Math.round(n/2),w=Math.max(24,m+18),O=Math.max(24,p+18),B=18,N=Math.min(220,Math.round(n*.24)),M=Math.min(180,Math.round(r*.32)),F=b,W=f,g=b,T=f;switch(e){case"scroll-up":W=f+Math.round(N/2),T=f-Math.round(N/2);break;case"scroll-down":W=f-Math.round(N/2),T=f+Math.round(N/2);break;case"scroll-left":F=b+Math.round(M/2),g=b-Math.round(M/2);break;case"scroll-right":F=b-Math.round(M/2),g=b+Math.round(M/2);break;case"swipe-from-left-edge":F=B,W=f,g=Math.min(r-B,B+M);break;case"swipe-from-right-edge":F=r-B,W=f,g=Math.max(B,r-B-M);break;case"swipe-from-top-edge":F=b,W=w,T=Math.min(n-O,w+N);break;case"swipe-from-bottom-edge":F=b,W=n-O,T=Math.max(w,n-O-N);break;default:console.error(` unknown gesture preset: ${e}`),process.exit(1)}let _=Math.max(8,Math.round(t/16)),P=Math.max(1,Math.round(t/_)),re=await l.send({type:"evaluate",code:`(async () => {
|
|
540
544
|
const interact = window.__sootsimInteract
|
|
541
545
|
if (!interact?.drag) return { ok: false, reason: 'no interact.drag' }
|
|
542
546
|
const value = await interact.drag(${F}, ${W}, ${g}, ${T}, ${_}, ${P})
|
|
@@ -577,7 +581,7 @@ ${s}
|
|
|
577
581
|
${y("state")} scroll feed
|
|
578
582
|
${y("state")} scroll-hit 360 420
|
|
579
583
|
${y("state")} hit 200 720
|
|
580
|
-
`);break}let t;switch(e){case"shell":t=await V(l,500);break;case"worker":t=await
|
|
584
|
+
`);break}let t;switch(e){case"shell":t=await V(l,500);break;case"worker":t=await ke(l,"__sootsimRenderHost.queryStats");break;case"ownership":t=await l.send({type:"evaluate",code:`(() => {
|
|
581
585
|
const h = window.__sootsimRenderHost
|
|
582
586
|
if (!h || typeof h.getOwnershipSnapshot !== 'function') {
|
|
583
587
|
return { error: 'getOwnershipSnapshot not available' }
|
|
@@ -632,7 +636,7 @@ ${s}
|
|
|
632
636
|
${y("shell")} open-card clock 800
|
|
633
637
|
${y("shell")} appearance dark
|
|
634
638
|
${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,
|
|
639
|
+
`);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,b=o.includes("--clear-state");if(e==="launch"){let f=a[2];f||(console.error(S("shell","launch <appId> [settleMs] [--clear-state]")),process.exit(1)),b&&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",b?{launchApp:{clearState:!0}}:{launchApp:{}},b?"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
640
|
const reloadExternalApp = window.SootSim?.bridges?.hotRemount?.reloadExternalApp
|
|
637
641
|
if (typeof reloadExternalApp === 'function') {
|
|
638
642
|
reloadExternalApp()
|
|
@@ -640,9 +644,9 @@ ${s}
|
|
|
640
644
|
}
|
|
641
645
|
window.location.reload()
|
|
642
646
|
return { kind: 'page' }
|
|
643
|
-
})()`});r=!!p&&p.kind==="external-app",s=!0}catch{}console.log(" reloading...");let n=l,m=null;if(r)m=await fe(l,{timeoutMs:1e4,errorGraceMs:3e3});else{s&&await Y(300);let p=await Fe(A,j,
|
|
647
|
+
})()`});r=!!p&&p.kind==="external-app",s=!0}catch{}console.log(" reloading...");let n=l,m=null;if(r)m=await fe(l,{timeoutMs:1e4,errorGraceMs:3e3});else{s&&await Y(300);let p=await Fe(A,j,k,{timeoutMs:1e4});p?(n=p,m=await fe(p,{timeoutMs:1e4,errorGraceMs:3e3})):(console.log(" \u26A0 reload: bridge never reconnected within 10000ms"),n=null)}if(m)if(m.ready){let p=m.source==="nodes-fallback"?" (no ready signal, node-count fallback)":"";console.log(` ready in ${m.elapsedMs}ms: ${m.nodes} nodes${p}`)}else m.source==="error-bail"?console.log(` \u26A0 reload bailed after ${m.elapsedMs}ms: ${m.errors} console error(s), ready signal never fired`):console.log(` \u26A0 reload timed out after ${m.elapsedMs}ms (${m.nodes} nodes, ${m.errors} errors)`);if(n)try{let p=await n.send({type:"evaluate",code:"window.__sootsimConsole?.getErrors(10) || []"});if(n!==l&&n.close(),Array.isArray(p)&&p.length>0){console.log(`
|
|
644
648
|
\u26A0 ${p.length} error(s) during mount:
|
|
645
|
-
`);for(let
|
|
649
|
+
`);for(let b of p){let f=b.args.map(w=>typeof w=="object"?JSON.stringify(w):w).join(" ");if(console.log(` ${f}`),b.stack){let w=b.stack.split(`
|
|
646
650
|
`).slice(0,2);for(let O of w)console.log(` ${O.trim()}`)}}}}catch{}m&&!m.ready&&(process.exitCode=1);break}case"eval":case"js":{let e=a.slice(1).join(" ");e||(console.error(S("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(` ${y("js")} SootSim.bridges.test.findByText("Sign in")`),console.error(` ${y("js")} SootSim.bridges.debug.snapshot("before")`),console.error(` ${y("js")} SootSim.bridges.keyboard.type("hello")`),console.error(` ${y("js")} SootSim.state.root.children.length`),process.exit(1));let t=e;t.startsWith("(async")||(t=`(async () => ${t})()`);let s=await l.send({type:"evaluate",code:t});console.log(JSON.stringify(s,null,2));let r=e.toLowerCase(),n=[];(r.includes("sootsim:gohome")||r.includes("gohome"))&&n.push("sootsim shell home"),(r.includes("sootsim:appswitcher")||r.includes("appswitcher"))&&n.push("sootsim shell switcher"),(r.includes("keyboard.isvisible")||r.includes("keyboard.getmode"))&&n.push("sootsim debug state keyboard"),r.includes("interact.tap")&&n.push("sootsim do tap <x> <y>"),r.includes("keyboard.type")&&n.push("sootsim do type <text>"),(r.includes("keyboard.press")||r.includes("keyboard.dispatchkey"))&&n.push("sootsim do key <name>"),r.includes("keyboard.dismiss")&&n.push("sootsim do dismiss"),r.includes("dumptree")&&n.push("sootsim get tree"),r.includes("dumpaccessibilitytree")&&n.push("sootsim get a11y"),r.includes("getnodecount")&&n.push("sootsim get count"),r.includes("findbytext")&&n.push("sootsim find <text>"),(r.includes("findbytestid")||r.includes("findbyid"))&&n.push("sootsim find --testid <id>"),r.includes("document.hidden")&&n.push("sootsim debug state keyboard (includes tab health)"),n.length>0&&U("prefer-cli-over-eval",n);break}case"globals":{let e=await l.send({type:"evaluate",code:`(async () => {
|
|
647
651
|
const globals = {}
|
|
648
652
|
|
|
@@ -874,7 +878,7 @@ ${s}
|
|
|
874
878
|
mode: 'main-thread',
|
|
875
879
|
frames: (stats.recentFrames || []).slice(-${t}),
|
|
876
880
|
}
|
|
877
|
-
})()`});if(s.error&&(console.error(` error: ${s.error}`),process.exit(1)),s.mode==="render-worker"){let n=Array.isArray(s.samples)?s.samples:[];if(n.length===0){console.log(` no frame data \u2014 run '${y("perf")} start' first`);break}console.log(` last ${n.length} sampled frames (ms):`),console.log(" total layout render copy aux other t+");for(let[m,p,
|
|
881
|
+
})()`});if(s.error&&(console.error(` error: ${s.error}`),process.exit(1)),s.mode==="render-worker"){let n=Array.isArray(s.samples)?s.samples:[];if(n.length===0){console.log(` no frame data \u2014 run '${y("perf")} start' first`);break}console.log(` last ${n.length} sampled frames (ms):`),console.log(" total layout render copy aux other t+");for(let[m,p,b,f,w,O,B]of n)console.log(` ${p.toFixed(2).padStart(7)} ${b.toFixed(2).padStart(7)} ${f.toFixed(2).padStart(7)} ${w.toFixed(2).padStart(7)} ${O.toFixed(2).padStart(6)} ${B.toFixed(2).padStart(7)} ${String(m).padStart(5)}`);console.log(""),he(n.map(m=>m[1])),s.live&&console.log(" sampling continues");break}let r=Array.isArray(s.frames)?s.frames:Array.isArray(s)?s:[];if(r.length===0){console.log(` no frame data \u2014 run '${y("perf")} start' first`);break}console.log(` last ${r.length} frame times (ms):`),console.log(` ${r.map(n=>n.toFixed(2)).join(", ")}`),he(r);break}case"worst":{let t=a[2]?Number(a[2]):20;(!Number.isFinite(t)||t<=0)&&(console.error(` error: expected a positive frame count, got "${a[2]}"`),process.exit(1));let s=await l.send({type:"evaluate",code:`(async () => {
|
|
878
882
|
if (window.__sootsimRenderHost) {
|
|
879
883
|
const session = window.${G} || {}
|
|
880
884
|
if (session.active) {
|
|
@@ -916,7 +920,7 @@ ${s}
|
|
|
916
920
|
mode: 'main-thread',
|
|
917
921
|
frames: recent.slice().sort((a, b) => b - a).slice(0, ${t}),
|
|
918
922
|
}
|
|
919
|
-
})()`});if(s.error&&(console.error(` error: ${s.error}`),process.exit(1)),s.mode==="render-worker"){let n=Array.isArray(s.samples)?s.samples:[];if(n.length===0){console.log(` no frame data \u2014 run '${y("perf")} start' first`);break}console.log(` worst ${n.length} sampled frames (ms):`),console.log(" total layout render copy aux other t+");for(let[m,p,
|
|
923
|
+
})()`});if(s.error&&(console.error(` error: ${s.error}`),process.exit(1)),s.mode==="render-worker"){let n=Array.isArray(s.samples)?s.samples:[];if(n.length===0){console.log(` no frame data \u2014 run '${y("perf")} start' first`);break}console.log(` worst ${n.length} sampled frames (ms):`),console.log(" total layout render copy aux other t+");for(let[m,p,b,f,w,O,B]of n)console.log(` ${p.toFixed(2).padStart(7)} ${b.toFixed(2).padStart(7)} ${f.toFixed(2).padStart(7)} ${w.toFixed(2).padStart(7)} ${O.toFixed(2).padStart(6)} ${B.toFixed(2).padStart(7)} ${String(m).padStart(5)}`);s.live&&(console.log(""),console.log(" sampling continues"));break}let r=Array.isArray(s.frames)?s.frames:Array.isArray(s)?s:[];if(r.length===0){console.log(` no frame data \u2014 run '${y("perf")} start' first`);break}console.log(` worst ${r.length} frame times (ms):`),console.log(` ${r.map(n=>n.toFixed(2)).join(", ")}`);break}case"transition":{let t=a[2];if(!t||!["goHome","appSwitcher","lockScreen"].includes(t)){console.log(`
|
|
920
924
|
${y("perf")} transition <event> \u2014 profile a shell transition
|
|
921
925
|
|
|
922
926
|
events:
|
|
@@ -1006,25 +1010,25 @@ ${s}
|
|
|
1006
1010
|
p50: ${n.p50.toFixed(2)}ms
|
|
1007
1011
|
p95: ${n.p95.toFixed(2)}ms
|
|
1008
1012
|
p99: ${n.p99.toFixed(2)}ms
|
|
1009
|
-
jank: ${n.jankFrames} frames (${p}%) >16.67ms`),Array.isArray(n.samples)&&n.samples.length>0&&(console.log(""),
|
|
1010
|
-
`);for(let n of r){let m=new Date(n.timestamp).toLocaleTimeString(),p=n.args.map(
|
|
1011
|
-
`).slice(0,3);for(let f of
|
|
1013
|
+
jank: ${n.jankFrames} frames (${p}%) >16.67ms`),Array.isArray(n.samples)&&n.samples.length>0&&(console.log(""),he(n.samples.map(b=>b[1])));break}default:console.error(` unknown perf subcommand: ${e}`),process.exit(1)}break}case"errors":{let e=a[1];if(e==="clear"){await l.send({type:"evaluate",code:'window.__sootsimConsole?.clear(); "cleared"'}),E(d)?C({cleared:!0}):console.log(" error buffer cleared");break}let t=e?Number(e):20,s=await l.send({type:"evaluate",code:`window.__sootsimConsole?.getErrors(${t}) || []`}),r=Array.isArray(s)?s:[];if(E(d)){C(r);break}if(r.length===0){console.log(" no errors captured");break}console.log(` ${r.length} error(s):
|
|
1014
|
+
`);for(let n of r){let m=new Date(n.timestamp).toLocaleTimeString(),p=n.args.map(b=>typeof b=="object"?JSON.stringify(b):b).join(" ");if(console.log(` [${m}] ${p}`),n.stack){let b=n.stack.split(`
|
|
1015
|
+
`).slice(0,3);for(let f of b)console.log(` ${f.trim()}`)}}break}case"warnings":{let e=a[1]?Number(a[1]):20,t=await l.send({type:"evaluate",code:`window.__sootsimConsole?.getWarnings(${e}) || []`}),s=Array.isArray(t)?t:[];if(E(d)){C(s);break}if(s.length===0){console.log(" no warnings captured");break}console.log(` ${s.length} warning(s):
|
|
1012
1016
|
`);for(let r of s){let n=new Date(r.timestamp).toLocaleTimeString(),m=r.args.map(p=>typeof p=="object"?JSON.stringify(p):p).join(" ");console.log(` [${n}] ${m}`)}break}case"animations":{let e=await z(l,"listAnimations")??[];if(o.includes("--json")){console.log(JSON.stringify(e,null,2));break}if(e.length===0){console.log(" no active animations");break}console.log(` ${e.length} active animation(s):
|
|
1013
|
-
`);for(let t of e){let s=String(t.kind).padEnd(6),r=`${Number(t.from).toFixed(2)}\u2192${Number(t.to).toFixed(2)}`,n=Number(t.current??0).toFixed(2),m=`${Math.round((t.progress??0)*100)}%`,p=`${Math.round(t.elapsedMs??0)}ms`,
|
|
1014
|
-
`);for(let p of m){let
|
|
1017
|
+
`);for(let t of e){let s=String(t.kind).padEnd(6),r=`${Number(t.from).toFixed(2)}\u2192${Number(t.to).toFixed(2)}`,n=Number(t.current??0).toFixed(2),m=`${Math.round((t.progress??0)*100)}%`,p=`${Math.round(t.elapsedMs??0)}ms`,b=t.loop?" loop":"",f=t.layoutBound?" layout":"";console.log(` #${t.id} ${s} ${r.padEnd(14)} cur=${n.padEnd(7)} ${m.padStart(4)} ${p}${b}${f}`)}break}case"animation":{let e=a[1];(!e||e==="--help"||e==="-h")&&(console.error(` usage: ${y("animation")} <id>`),process.exit(1));let t=Number(e);Number.isFinite(t)||(console.error(` invalid id: ${e}`),process.exit(1));let s=await z(l,"getAnimation",t);console.log(JSON.stringify(s,null,2));break}case"stop-animation":{let e=a[1];(!e||e==="--help"||e==="-h")&&(console.error(` usage: ${y("stop-animation")} <id|all>`),process.exit(1));let t=e==="all"?"all":Number(e);t!=="all"&&!Number.isFinite(t)&&(console.error(` invalid id: ${e}`),process.exit(1));let s=await z(l,"stopAnimation",t);console.log(` stopped ${s??0} animation(s)`);break}case"requests":{let e=a[1];if(e==="clear"){await z(l,"clearRequests"),E(d)?C({cleared:!0}):console.log(" request buffer cleared");break}let t=e==="all",s=t?a[2]:e,r=s?Number(s):20,n=t?await z(l,"getRequests",r):await z(l,"getFailedRequests",r),m=Array.isArray(n)?n:[];if(E(d)){C(m);break}if(m.length===0){console.log(t?" no requests captured":" no failed requests captured");break}console.log(` ${m.length} ${t?"request(s)":"failed request(s)"}:
|
|
1018
|
+
`);for(let p of m){let b=new Date(p.timestamp).toLocaleTimeString();console.log(` [${b}] ${q(p)}`),p.responseBody?console.log(` ${p.responseBody}`):p.error&&console.log(` ${p.error}`)}break}case"network":{let e=a[1],t=null,s=null,r=!1,n=!1,m=!1;for(let N=0;N<d.length;N++){let M=d[N];if(M==="--filter")t=d[N+1]??null,N++;else if(M==="--limit"){let F=Number(d[N+1]);Number.isFinite(F)&&(s=F),N++}else M==="--failed"?r=!0:M==="--tail"||M==="-f"?n=!0:M==="--json"&&(m=!0)}if(e==="clear"){await l.send({type:"evaluate",code:'window.__sootsimObservability?.network.clear(); "cleared"'}),console.log(" network buffer cleared");break}if(e==="get"){let N=a[2];N||(console.error(" usage: sootsim network get <id>"),process.exit(1));let M=await l.send({type:"evaluate",code:`(() => {
|
|
1015
1019
|
const obs = window.__sootsimObservability;
|
|
1016
1020
|
if (!obs) return null;
|
|
1017
1021
|
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)):Ft(M);break}let p=s??(n?200:e?Number(e):20);Number.isFinite(p)||(console.error(` invalid limit: ${e}`),process.exit(1));let
|
|
1022
|
+
})()`});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 b=async()=>{let N=await l.send({type:"evaluate",code:`(() => {
|
|
1019
1023
|
const obs = window.__sootsimObservability;
|
|
1020
1024
|
if (!obs) return { ok: false };
|
|
1021
1025
|
return { ok: true, entries: obs.network.getSnapshot() };
|
|
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
|
|
1026
|
+
})()`});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 b(),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
1027
|
`);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
|
|
1028
|
+
`);let w=new Set,O=!0,B=()=>{O=!1};process.on("SIGINT",B);try{for(;O;){let N=await b(),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 b=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
1029
|
const obs = window.__sootsimObservability;
|
|
1026
1030
|
if (!obs) return { ok: false };
|
|
1027
1031
|
return { ok: true, entries: obs.logs.getSnapshot() };
|
|
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(_))),
|
|
1032
|
+
})()`});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(_))),b&&(T=T.filter(_=>b.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
1033
|
`);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: ${
|
|
1034
|
+
`);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: ${h}`),process.exit(1)}if(H.has(h)&&!o.includes("--no-wait")&&process.env.SOOTSIM_NO_AUTO_WAIT!=="1"&&await ne(l),!D.has(h)&&!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(` ${h??"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};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
/*! sootsim v0.1.36 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
|
+
import{a as o}from"./chunk-27P763IZ.js";import"./chunk-VFDRZNPN.js";import"./chunk-IJMYFYDZ.js";import"./chunk-EJLNUMMP.js";import"./chunk-TC6V7YFC.js";import"./chunk-SMVJOWSV.js";import"./chunk-6GGMKFWJ.js";import"./chunk-ZEW3RF5Q.js";import"./chunk-5QIUJNT3.js";import"./chunk-LHDWH7VS.js";async function t(n){console.error(" note: `sootsim install` is now `sootsim setup-repo`. forwarding\u2026\n"),await o(n)}export{t as runInstall};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/*! sootsim v0.1.36 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
|
+
import{a as b}from"./chunk-VFDRZNPN.js";import{a as x}from"./chunk-PJL25JQV.js";import"./chunk-LHDWH7VS.js";import{spawn as k,spawnSync as u}from"child_process";import{chmodSync as S,createWriteStream as E,existsSync as w,mkdirSync as y,renameSync as T,rmSync as g,statSync as P}from"fs";import{tmpdir as D}from"os";import{dirname as M,join as f,resolve as v}from"path";var h="https://sootbean.com/api/electron-release";function A(){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:_}}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:C}}return null}async function O({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 t=s.headers.get("content-length"),a=t?Number(t):null;if(!s.body)throw new Error("download failed: empty response body");y(M(o),{recursive:!0});let i=E(o),d=s.body.getReader(),c=0;try{for(;;){let{done:l,value:p}=await d.read();if(l)break;i.write(Buffer.from(p)),c+=p.byteLength,n?.(c,a)}}finally{await new Promise((l,p)=>{i.end(e=>e?p(e):l())})}}function I(r,o){let n=(r/1048576).toFixed(1);if(!o)return` ${n} MB`;let s=Math.min(100,Math.round(r/o*100)),t=(o/(1024*1024)).toFixed(1),a=24,i=Math.round(s/100*a);return` ${"\u2588".repeat(i)+"\u2591".repeat(a-i)} ${s}% ${n} / ${t} MB`}async function _(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
|
+
`),t=n[n.length-1].split(" ").pop()?.trim();if(!t||!w(t))throw new Error(`could not determine dmg mount point (output: ${o.stdout})`);let a=f(t,"sootsim.app");if(!w(a))throw u("hdiutil",["detach","-force",t]),new Error(`sootsim.app not found inside ${t}`);let i="/Applications",d=v(process.env.HOME||"","Applications"),c=i;try{let m=f(i,`.sootsim-write-probe-${process.pid}`);u("touch",[m]),w(m)?g(m,{force:!0}):c=d}catch{c=d}c===d&&y(c,{recursive:!0});let l=f(c,"sootsim.app");w(l)&&g(l,{recursive:!0,force:!0});let p=u("cp",["-R",a,l]),e=u("hdiutil",["detach","-force",t]);if(p.status!==0)throw new Error(`copy to ${l} failed: ${p.stderr?.toString()||""}`.trim());return e.status!==0&&console.warn(` warning: failed to unmount ${t} (${e.stderr?.toString().trim()||"unknown error"})`),u("xattr",["-dr","com.apple.quarantine",l]),l}async function L(r){let o=v(process.env.HOME||"","Applications");y(o,{recursive:!0});let n=f(o,"sootsim.AppImage");return w(n)&&g(n,{force:!0}),T(r,n),S(n,493),n}async function C(r){return await new Promise((o,n)=>{let s=k("cmd",["/c","start",'""',"/wait",r],{stdio:"inherit"});s.once("error",n),s.once("exit",t=>{t===0?o():n(new Error(`installer exited with code ${t}`))})}),r}async function Y(r){(r.includes("--help")||r.includes("-h"))&&(console.log(`
|
|
4
|
+
sootsim install-desktop \u2014 download and install the optional desktop GUI
|
|
5
|
+
|
|
6
|
+
the CLI + daemon are the canonical sootsim surface; the GUI is optional.
|
|
7
|
+
if you just want to drive a running metro/expo dev server from the
|
|
8
|
+
terminal, you don't need this.
|
|
9
|
+
|
|
10
|
+
usage:
|
|
11
|
+
sootsim install-desktop [options]
|
|
12
|
+
|
|
13
|
+
options:
|
|
14
|
+
-y, --yes skip confirmation and install immediately
|
|
15
|
+
--force reinstall even if the companion is already present
|
|
16
|
+
|
|
17
|
+
examples:
|
|
18
|
+
sootsim install-desktop
|
|
19
|
+
sootsim install-desktop --yes
|
|
20
|
+
`),process.exit(0));let o=r.includes("--yes")||r.includes("-y")||process.env.SOOTSIM_NO_PROMPT==="1"||process.env.CI==="1"||!process.stdin.isTTY,n=r.includes("--force"),s=x();if(s&&!n){console.log(` sootsim desktop already installed at: ${s.path}`),console.log(" pass --force to reinstall.");return}let t=A();if(t||(console.error(` no desktop build available for ${process.platform}/${process.arch}.`),console.error(" supported: darwin-arm64, darwin-x64, linux-x64, win32-x64"),process.exit(1)),console.log(` platform: ${t.platform}`),console.log(` download: ${t.url}`),console.log(),!o){if(!await b("download and install now?",!0)){console.log(" cancelled.");return}console.log()}let a=f(D(),`sootsim-install-${Date.now()}`),i=f(a,t.filename),d=0;process.stdout.write(` downloading ${t.filename}...
|
|
21
|
+
`);try{await O({url:t.url,dest:i,onProgress:(e,m)=>{let $=Date.now();$-d<100&&e<(m??1/0)||(d=$,process.stdout.isTTY&&process.stdout.write(`\r\x1B[2K${I(e,m)}`))}})}catch(e){g(a,{recursive:!0,force:!0}),console.error(`
|
|
22
|
+
download failed: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}process.stdout.isTTY&&process.stdout.write(`
|
|
23
|
+
`);let c=P(i).size;console.log(` downloaded ${(c/(1024*1024)).toFixed(1)} MB`),console.log(),console.log(" installing...");let{trackCliEvent:l,flushCliTelemetry:p}=await import("./telemetry-CN42GMVC.js");try{let e=await t.install(i);l({event:"cli_install_desktop_succeeded",properties:{platform:t.platform,size_bytes:c}}),console.log(` installed: ${e}`)}catch(e){l({event:"cli_install_desktop_failed",properties:{platform:t.platform,error:e instanceof Error?e.message:String(e)}}),await p(),console.error(` install failed: ${e instanceof Error?e.message:String(e)}`),console.error(` keeping download at ${i} for manual install.`),process.exit(1)}finally{g(a,{recursive:!0,force:!0})}console.log(),console.log(" next steps:"),console.log(" sootsim electron launch the desktop app"),console.log(" sootsim open <target> open a demo or bundle in it")}export{Y as runInstallDesktop};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
/*! sootsim v0.
|
|
2
|
-
import{a as b}from"./chunk-
|
|
1
|
+
/*! sootsim v0.1.36 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
|
+
import{a as b}from"./chunk-VFDRZNPN.js";import"./chunk-LHDWH7VS.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.
|
|
2
|
-
import{a as l,b as d,c as k,d as y,e as g}from"./chunk-
|
|
1
|
+
/*! sootsim v0.1.36 | (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-YLIIVTTQ.js";import{d as c}from"./chunk-EJLNUMMP.js";import"./chunk-LHDWH7VS.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.
|
|
2
|
-
import"./chunk-
|
|
1
|
+
/*! sootsim v0.1.36 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
|
+
import"./chunk-J7CTD37P.js";import{b as m}from"./chunk-YR7BGGYE.js";import{a as u}from"./chunk-PJL25JQV.js";import"./chunk-G663654J.js";import"./chunk-A5BRCXYE.js";import{q as s,r as a,v as c,w as r,x as l}from"./chunk-5QIUJNT3.js";import"./chunk-LHDWH7VS.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-KEMO2MSB.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};
|