sootsim 0.1.188 → 0.1.190
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/README.md +9 -9
- package/dist-cli/bin.js +7 -7
- package/dist-cli/chunks/{agent-BRLC23GZ.js → agent-XZWMKC4F.js} +2 -2
- package/dist-cli/chunks/{agent-wrapper-HDWSAABN.js → agent-wrapper-CFJYDDAY.js} +2 -2
- package/dist-cli/chunks/{app-fonts-KQHDDWAH.js → app-fonts-64UN5GRY.js} +2 -2
- package/dist-cli/chunks/{assert-BA3G3DLH.js → assert-A3MQH7ZB.js} +2 -2
- package/dist-cli/chunks/auth-CNKNHD6U.js +10 -0
- package/dist-cli/chunks/beta-CDL7U2RE.js +2 -0
- package/dist-cli/chunks/camera-YQPIDOEN.js +20 -0
- package/dist-cli/chunks/{chunk-I52NHG4X.js → chunk-24OZOK2K.js} +1 -1
- package/dist-cli/chunks/{chunk-OXB6RPMX.js → chunk-3JVMBXLH.js} +2 -2
- package/dist-cli/chunks/{chunk-GAP76GG5.js → chunk-5IM3DYTZ.js} +1 -1
- package/dist-cli/chunks/{chunk-DBOVJCG5.js → chunk-6EFMFMJB.js} +2 -2
- package/dist-cli/chunks/{chunk-DKOKNFWR.js → chunk-6UQKBGI7.js} +2 -3
- package/dist-cli/chunks/{chunk-ERHMPVNZ.js → chunk-7TSFDDU7.js} +2 -2
- package/dist-cli/chunks/chunk-AAQ6AYYW.js +2 -0
- package/dist-cli/chunks/chunk-CD3ARXZW.js +1 -0
- package/dist-cli/chunks/chunk-CTP3U4WV.js +13 -0
- package/dist-cli/chunks/{chunk-QDUHROO5.js → chunk-CVUAT6TO.js} +1 -1
- package/dist-cli/chunks/chunk-DHDV2I2T.js +1 -0
- package/dist-cli/chunks/{chunk-TAXDBR5N.js → chunk-EBBYYBYM.js} +3 -3
- package/dist-cli/chunks/chunk-F6GCSGBJ.js +8 -0
- package/dist-cli/chunks/{chunk-HIS4TFND.js → chunk-INRO26KS.js} +2 -2
- package/dist-cli/chunks/{install-desktop-F43JZSJO.js → chunk-IOJDFCGV.js} +7 -7
- package/dist-cli/chunks/{chunk-D6GYUATH.js → chunk-ITQV76PX.js} +1 -1
- package/dist-cli/chunks/chunk-IUVDM73R.js +140 -0
- package/dist-cli/chunks/{chunk-2MRFRROI.js → chunk-K5GLQDTG.js} +2 -2
- package/dist-cli/chunks/{chunk-FUZNRCAR.js → chunk-K7OCH4WY.js} +2 -2
- package/dist-cli/chunks/{chunk-NCENLBIL.js → chunk-KLGX6B46.js} +2 -2
- package/dist-cli/chunks/{chunk-AUQ7FZIX.js → chunk-LRJVY7SN.js} +2 -2
- package/dist-cli/chunks/{chunk-2T6Z4WCN.js → chunk-MH6BMKK5.js} +1 -1
- package/dist-cli/chunks/{chunk-Y3I43AUV.js → chunk-MJU4XNZ3.js} +1 -1
- package/dist-cli/chunks/{chunk-ZZ7FODQE.js → chunk-NAI6N6SN.js} +8 -7
- package/dist-cli/chunks/chunk-P7MW7S62.js +87 -0
- package/dist-cli/chunks/chunk-PGQHNKRL.js +119 -0
- package/dist-cli/chunks/chunk-PR3IKD6A.js +2 -0
- package/dist-cli/chunks/chunk-PSETHPMH.js +565 -0
- package/dist-cli/chunks/{chunk-BZNPGYJQ.js → chunk-QJVITDKU.js} +1 -1
- package/dist-cli/chunks/{chunk-SVSZFGNA.js → chunk-QNVY6BLP.js} +1 -1
- package/dist-cli/chunks/{chunk-YNY3WSH4.js → chunk-R3VO3MDO.js} +1 -1
- package/dist-cli/chunks/{chunk-5U22ZNDP.js → chunk-SJHC6HZH.js} +1 -1
- package/dist-cli/chunks/{chunk-ZZTGVTE3.js → chunk-SMDCNCVZ.js} +1 -1
- package/dist-cli/chunks/{chunk-TPHYWQB2.js → chunk-SPYRMNAJ.js} +5 -5
- package/dist-cli/chunks/{chunk-B272R3FA.js → chunk-TBFBGSRV.js} +1 -1
- package/dist-cli/chunks/chunk-UPN7Z5XZ.js +916 -0
- package/dist-cli/chunks/{chunk-KOEBHC3D.js → chunk-WHYPFQIZ.js} +2 -2
- package/dist-cli/chunks/{chunk-NDAGMI4C.js → chunk-WR5IDCCN.js} +1 -1
- package/dist-cli/chunks/{chunk-BJMQRL7V.js → chunk-WT74ZUKN.js} +1 -1
- package/dist-cli/chunks/{chunk-5XZN2C22.js → chunk-Y6CZ5N26.js} +2 -2
- package/dist-cli/chunks/{chunk-IULK4TUU.js → chunk-YWQH2KQJ.js} +1 -1
- package/dist-cli/chunks/cli-version-PVRNMRL7.js +2 -0
- package/dist-cli/chunks/{compat-6QHB5UPF.js → compat-AU7EW2AY.js} +3 -3
- package/dist-cli/chunks/config-TNZV6ASD.js +11 -0
- package/dist-cli/chunks/control-TKDPQACC.js +2 -0
- package/dist-cli/chunks/daemon-L57B7HBL.js +2 -0
- package/dist-cli/chunks/{debug-OTEVKM5L.js → debug-H5UHUDC4.js} +3 -3
- package/dist-cli/chunks/desktop-WYPCYR3Z.js +32 -0
- package/dist-cli/chunks/{detox-MISIYJRV.js → detox-36VI5PZ3.js} +2 -2
- package/dist-cli/chunks/{device-R3BORN7B.js → device-XPSGGSM5.js} +2 -2
- package/dist-cli/chunks/{diagnose-G7UE2PUJ.js → diagnose-CH3VYGFO.js} +10 -10
- package/dist-cli/chunks/drivers-XDAXVIZF.js +2 -0
- package/dist-cli/chunks/flow-Q24HN25I.js +2 -0
- package/dist-cli/chunks/help-OPVDM7BI.js +2 -0
- package/dist-cli/chunks/{home-paths-EJFFLJZR.js → home-paths-IT2LCG6O.js} +2 -2
- package/dist-cli/chunks/inspect-FEMU6KSY.js +2 -0
- package/dist-cli/chunks/install-desktop-NCMJNSW7.js +2 -0
- package/dist-cli/chunks/{login-3ZNZJ7P4.js → login-O6XRDK26.js} +5 -5
- package/dist-cli/chunks/{logout-34JBFFT4.js → logout-YK7BH4AK.js} +2 -2
- package/dist-cli/chunks/{maestro-JYCD7OQT.js → maestro-T52UBLSK.js} +6 -6
- package/dist-cli/chunks/mode-L4GR563F.js +93 -0
- package/dist-cli/chunks/optional-demo-registry-PDFLBZMQ.js +2 -0
- package/dist-cli/chunks/perf-7DYLYEBO.js +43 -0
- package/dist-cli/chunks/{record-L54OVMQQ.js → record-MNIFB5DJ.js} +7 -7
- package/dist-cli/chunks/runtime-E4KWRPBT.js +2 -0
- package/dist-cli/chunks/screenshot-command-D77AXBND.js +190 -0
- package/dist-cli/chunks/{serve-D6HGTNWI.js → serve-LFPZVOVA.js} +2 -2
- package/dist-cli/chunks/{setup-MR7SX23V.js → setup-6FX2KQP4.js} +3 -3
- package/dist-cli/chunks/skills-36CRDBMN.js +48 -0
- package/dist-cli/chunks/storage-N45XGOMV.js +35 -0
- package/dist-cli/chunks/store-USJP5W6S.js +2 -0
- package/dist-cli/chunks/telemetry-WQ7RK6NE.js +2 -0
- package/dist-cli/chunks/test-GCVW3U2P.js +69 -0
- package/dist-cli/chunks/{timeline-SBCWQHQT.js → timeline-4ALLBESW.js} +2 -2
- package/dist-cli/chunks/{upgrade-RGJVNFZO.js → upgrade-75XAVSMJ.js} +2 -2
- package/dist-cli/chunks/upload-34BCSEFZ.js +2 -0
- package/dist-cli/chunks/{version-23HGJOE3.js → version-MSFDAHVF.js} +2 -2
- package/dist-cli/chunks/{web-YMQPB45M.js → web-IS75NWAC.js} +2 -2
- package/dist-cli/chunks/{what-happened-3AJBD35R.js → what-happened-TW6SN7Z7.js} +2 -2
- package/dist-lib/agent-daemon-client.cjs +1 -1
- package/dist-lib/agent-events.cjs +1 -1
- package/dist-lib/agent-identity.cjs +53 -0
- 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/beta.cjs +1 -1
- package/dist-lib/beta.mjs +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/detox/index.cjs +1 -1
- package/dist-lib/dev-bundle-resolution.cjs +1 -1
- package/dist-lib/home-paths.cjs +1 -1
- package/dist-lib/host/bridge-host.cjs +1 -1
- package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
- package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
- package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
- package/dist-lib/host/websocket-proxy.cjs +1 -1
- package/dist-lib/index.cjs +15 -7
- package/dist-lib/jump-to-source-babel.cjs +1 -1
- package/dist-lib/menu.cjs +1 -1
- package/dist-lib/menu.mjs +1 -1
- package/dist-lib/metro.cjs +13 -5
- package/dist-lib/profiles.cjs +1 -1
- package/dist-lib/render-mode.cjs +1 -1
- package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
- package/dist-lib/sdk.cjs +1 -1
- package/dist-lib/sdk.mjs +1 -1
- package/dist-lib/skills.cjs +121 -79
- package/dist-lib/vite.cjs +13 -5
- package/package.json +1 -1
- package/skills/{soot.md → soot/SKILL.md} +12 -25
- package/skills/{sootsim-debug.md → sootsim-debug/SKILL.md} +1 -1
- package/skills/sootsim-perf/SKILL.md +169 -0
- package/skills/{sootsim-test.md → sootsim-test/SKILL.md} +10 -7
- package/src/metro-plugin.ts +2 -2
- package/src/runtime-assets.ts +16 -2
- package/src/screenshots/orchestrate.ts +1 -1
- package/src/screenshots/org-deck.ts +1 -1
- package/src/vite-plugin-one.ts +2 -2
- package/dist-cli/chunks/beta-O43XI622.js +0 -2
- package/dist-cli/chunks/camera-22Q4QVTC.js +0 -20
- package/dist-cli/chunks/chunk-3ECPODR2.js +0 -382
- package/dist-cli/chunks/chunk-4JG6GDLB.js +0 -2
- package/dist-cli/chunks/chunk-5D6TXWZQ.js +0 -3
- package/dist-cli/chunks/chunk-6LAPS7RP.js +0 -3
- package/dist-cli/chunks/chunk-FHHOZTPI.js +0 -3
- package/dist-cli/chunks/chunk-FXHED7P5.js +0 -79
- package/dist-cli/chunks/chunk-HGER3AOP.js +0 -69
- package/dist-cli/chunks/chunk-HXEGZCLS.js +0 -118
- package/dist-cli/chunks/chunk-JOE4R2PO.js +0 -1
- package/dist-cli/chunks/chunk-MXYAGDBC.js +0 -24
- package/dist-cli/chunks/chunk-PCKWE63K.js +0 -987
- package/dist-cli/chunks/chunk-QCDWRDUC.js +0 -1
- package/dist-cli/chunks/chunk-SGZP6JCZ.js +0 -16
- package/dist-cli/chunks/chunk-V7V6WDIM.js +0 -13
- package/dist-cli/chunks/chunk-WST3QKHD.js +0 -180
- package/dist-cli/chunks/cli-version-74E3VGPF.js +0 -2
- package/dist-cli/chunks/control-A2KALMZE.js +0 -2
- package/dist-cli/chunks/cpu-profile-A3ST63G2.js +0 -2
- package/dist-cli/chunks/daemon-KBQK2QRU.js +0 -2
- package/dist-cli/chunks/drivers-4URQ5PMT.js +0 -2
- package/dist-cli/chunks/electron-DXMMDHR3.js +0 -19
- package/dist-cli/chunks/flow-OETRQOLM.js +0 -2
- package/dist-cli/chunks/help-FSZ5FRHV.js +0 -2
- package/dist-cli/chunks/hints-QJSWKWC5.js +0 -2
- package/dist-cli/chunks/inspect-EFTHNTN2.js +0 -2
- package/dist-cli/chunks/keys-P2HBCVAX.js +0 -19
- package/dist-cli/chunks/optional-demo-registry-MM6GWJNB.js +0 -2
- package/dist-cli/chunks/preview-PIEAC5MZ.js +0 -17
- package/dist-cli/chunks/profile-BTCKOPAU.js +0 -22
- package/dist-cli/chunks/react-UYKTFQZW.js +0 -30
- package/dist-cli/chunks/runtime-ZB7S4Z3H.js +0 -2
- package/dist-cli/chunks/screenshot-A5WQUFIQ.js +0 -35
- package/dist-cli/chunks/screenshot-mode-GBZSTZTV.js +0 -17
- package/dist-cli/chunks/screenshots-EHE2FKTA.js +0 -74
- package/dist-cli/chunks/screenshots-capture-MOZJ2RQV.js +0 -41
- package/dist-cli/chunks/skills-NHV2ZFOU.js +0 -48
- package/dist-cli/chunks/slides-WDFLQWCZ.js +0 -46
- package/dist-cli/chunks/store-7EYKU7RK.js +0 -2
- package/dist-cli/chunks/telemetry-MU23XMBJ.js +0 -2
- package/dist-cli/chunks/telemetry-NF6KAWA4.js +0 -2
- package/dist-cli/chunks/test-CVQHZHMJ.js +0 -31
- package/dist-cli/chunks/three-mode-UCOVUXVY.js +0 -58
- package/dist-cli/chunks/upload-GHIMBL2Y.js +0 -2
- package/dist-cli/chunks/whoami-ZM3TCPNU.js +0 -2
- /package/skills/{sootsim-setup.md → sootsim-setup/SKILL.md} +0 -0
- /package/skills/{sootsim-visual.md → sootsim-visual/SKILL.md} +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
1
|
+
/*! sootsim v0.1.190 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
import t from"node:fs";import{homedir as A}from"node:os";import o from"node:path";var E="SOOTSIM_HOME",_="active",I="daemon.json",N="dev-bridge.json",P="config.json",x=3e4;function u(){let e=process.env[E];return e&&e.length>0?o.resolve(e):o.join(A(),".sootsim")}function j(){if(process.env.SOOTSIM_FORCE_DAEMON_INSTALL==="1")return!1;let e=process.env.SOOTSIM_DEV;if(e==="1"||e==="true")return!0;if(e==="0"||e==="false")return!1;let r=process.argv[1];if(!r)return!1;try{return t.realpathSync(r).includes(`${o.sep}packages${o.sep}sootsim${o.sep}`)}catch{return!1}}function F(){return process.env.SOOTSIM_FORCE_DAEMON_INSTALL==="1"?!1:process.env.IS_TAMAGUI_DEV==="1"}function W(){return j()||F()}function f(){return o.join(u(),"runtimes")}function w(e){return o.join(f(),e)}function k(){return o.join(f(),_)}function D(){return o.join(u(),"electron")}function X(){return o.join(D(),"userData")}function q(e){return o.join(D(),e)}function T(){return o.join(u(),"profiles")}function B(){return o.join(u(),"daemon-app")}function M(){return o.join(B(),"SootSim Daemon.app")}function z(){return o.join(M(),"Contents","MacOS","sootsim-daemon")}function C(){return o.join(u(),"cache")}function p(){return o.join(u(),I)}function m(){return o.join(u(),N)}function b(){return o.join(u(),P)}function L(){try{let e=t.readFileSync(b(),"utf8"),r=JSON.parse(e);return r&&typeof r=="object"?r:{}}catch{return{}}}function R(e){g();let r=L(),i={...r,...e};e.settings&&typeof e.settings=="object"&&(i.settings={...r.settings&&typeof r.settings=="object"?r.settings:{},...e.settings});let c=`${b()}.tmp`;return t.writeFileSync(c,`${JSON.stringify(i,null,2)}
|
|
3
3
|
`,"utf8"),t.renameSync(c,b()),i}function Q(){return L().telemetry!==!1}function Z(e){R({telemetry:e})}function g(){t.mkdirSync(u(),{recursive:!0}),t.mkdirSync(f(),{recursive:!0}),t.mkdirSync(D(),{recursive:!0}),t.mkdirSync(T(),{recursive:!0}),t.mkdirSync(C(),{recursive:!0})}function $(){try{let e=t.readFileSync(k(),"utf8").trim();return e.length>0?e:null}catch{return null}}function ee(e){t.mkdirSync(f(),{recursive:!0}),t.writeFileSync(k(),`${e}
|
|
4
4
|
`,"utf8")}function re(){try{return t.readdirSync(f(),{withFileTypes:!0}).filter(e=>e.isDirectory()).map(e=>e.name).sort(J)}catch{return[]}}function J(e,r){let i=s=>{let a=s.indexOf("-"),l=a>=0?s.slice(0,a):s,O=a>=0?s.slice(a+1):"",v=l.split(".").map(S=>Number.parseInt(S,10));return v.some(S=>!Number.isFinite(S))?[[Number.POSITIVE_INFINITY],s]:[v,O]},[c,n]=i(e),[h,y]=i(r);for(let s=0;s<Math.max(c.length,h.length);s++){let a=c[s]??0,l=h[s]??0;if(a!==l)return a-l}return n===y?0:n?y?n<y?-1:1:-1:1}function te(){let e=$();if(!e)return null;let r=w(e);try{if(t.statSync(r).isDirectory())return r}catch{}return null}var d=16*1024;function V(){try{let e=t.openSync(p(),"r");try{let r=Buffer.alloc(d),i=t.readSync(e,r,0,d,0),c=r.subarray(0,i).toString("utf8"),n=JSON.parse(c);return n&&n.schema===1&&typeof n.pid=="number"&&typeof n.bridgePort=="number"&&typeof n.runtimePort=="number"&&typeof n.startedAt=="number"&&typeof n.heartbeatAt=="number"?n:null}finally{t.closeSync(e)}}catch{return null}}function ne(){try{let e=t.openSync(m(),"r");try{let r=Buffer.alloc(d),i=t.readSync(e,r,0,d,0),c=r.subarray(0,i).toString("utf8"),n=JSON.parse(c);return n&&n.schema===1&&n.source==="vite-dev"&&typeof n.pid=="number"&&typeof n.bridgePort=="number"&&typeof n.runtimePort=="number"&&typeof n.cwd=="string"&&typeof n.startedAt=="number"&&typeof n.heartbeatAt=="number"&&(n.shellPort===void 0||typeof n.shellPort=="number")?n:null}finally{t.closeSync(e)}}catch{return null}}function H(e,r=Date.now()){if(!e||r-e.heartbeatAt>x)return!1;try{return process.kill(e.pid,0),!0}catch{return!1}}function oe(e,r=Date.now()){if(!e||r-e.heartbeatAt>x)return!1;try{return process.kill(e.pid,0),!0}catch{return!1}}function G(e){g();let r=`${p()}.tmp`;t.writeFileSync(r,`${JSON.stringify(e,null,2)}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
1
|
+
/*! sootsim v0.1.190 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
var t="./demo-app-registry.ts",o=null;async function n(){if(o)return o;try{let r=await import(t);o=Array.isArray(r.APPS)?r.APPS:[]}catch{o=[]}return o}function e(){return o??[]}export{n as a,e as b};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
2
|
-
import{a as
|
|
1
|
+
/*! sootsim v0.1.190 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
|
+
import{a as m,b as I}from"./chunk-TBFBGSRV.js";import{a as w,b as T,c as _}from"./chunk-QJVITDKU.js";import{c as O}from"./chunk-SJHC6HZH.js";import{C as k,o as x,q as f}from"./chunk-MH6BMKK5.js";import h from"fs";import v from"path";var c="default",U="profiles.json",a=1;function s(e){let r=e.trim();if(!r)throw new Error("profile id is required");if(!/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(r))throw new Error("profile ids must start with a letter or number and contain only letters, numbers, dot, dash, or underscore");if(r==="."||r==="..")throw new Error(`invalid profile id: ${r}`);return r}function g(){return v.join(f(),U)}function q(e){return`sootsim-profile-${s(e)}`}function H(e){return v.join(x(),"Partitions",q(e))}function y(e){return v.join(f(),"playwright",s(e))}function b(){try{let e=JSON.parse(h.readFileSync(g(),"utf8"));if(!e||e.version!==a)return{version:a,profiles:[]};let r=Array.isArray(e.profiles)?e.profiles.filter(t=>!!t&&typeof t.id=="string"&&typeof t.createdAt=="string"&&typeof t.updatedAt=="string").map(t=>({id:s(t.id),createdAt:t.createdAt,updatedAt:t.updatedAt})):[];return{version:a,profiles:r}}catch{return{version:a,profiles:[]}}}function A(e){return[...e].sort((r,t)=>r.id===c?-1:t.id===c?1:r.id.localeCompare(t.id))}function P(e){if(e.profiles.some(t=>t.id===c))return{...e,profiles:A(e.profiles)};let r=new Date().toISOString();return{version:a,profiles:A([{id:c,createdAt:r,updatedAt:r},...e.profiles])}}function S(e){k();let r=P(e),t=`${g()}.tmp`;return h.writeFileSync(t,`${JSON.stringify(r,null,2)}
|
|
3
|
+
`,"utf8"),h.renameSync(t,g()),r}function G(){return S(b()).profiles}function z(e){let r=s(e);return G().find(t=>t.id===r)??null}function E(e=c){let r=s(e),t=z(r);return t||B(r)}function B(e){let r=s(e),t=P(b());if(t.profiles.some(n=>n.id===r))throw new Error(`profile already exists: ${r}`);let o=new Date().toISOString(),i={id:r,createdAt:o,updatedAt:o};return S({version:a,profiles:[...t.profiles,i]}),i}function pe(e){let r=s(e);if(r===c)throw new Error("the default profile cannot be deleted; clear it instead");let t=P(b()),o=t.profiles.find(i=>i.id===r);if(!o)throw new Error(`profile not found: ${r}`);return S({version:a,profiles:t.profiles.filter(i=>i.id!==r)}),j(r),o}function j(e){let r=s(e);for(let t of[H(r),y(r)])try{h.rmSync(t,{recursive:!0,force:!0})}catch{}}function Y(){let e=w();return e?{available:!0,reason:null,detail:e}:{available:!1,reason:"no chromium-family browser found (chrome, chromium, edge, brave, arc)"}}async function K(e){if(e.headless)return{launched:!1,message:"the chromium driver launches a visible browser window and cannot run headless \u2014 a headless `chrome --headless=new` process exits immediately and the sim never connects. for headless automation use `--driver playwright`."};let r=w();if(!r)return{launched:!1,message:"chromium not found \u2014 install chrome or run `sootsim list --drivers`"};if(!e.url)return{launched:!1,message:"chromium driver requires a target url"};if(e.profileId||e.ephemeralProfile)return{launched:!1,message:"profiles require electron or playwright; browser tabs use your current Chrome profile"};try{let t=await _(e.url,{detached:e.detached??!0});return{launched:!0,message:`chromium launched \u2192 ${e.url}`,pid:t.pid,target:t.target??r,attachUrl:e.url}}catch(t){return{launched:!1,message:`chromium spawn failed: ${t instanceof Error?t.message:String(t)}`}}}var M={id:"chromium",name:"chromium",description:"system chrome / chromium / edge \u2014 visible window (headless: use playwright)",kind:"browser",availability:Y,launch:K};function V(){let e=m();return e?{available:!0,reason:null,detail:`${e.kind} @ ${e.path}`}:{available:!1,reason:"sootsim desktop app not installed (run `sootsim desktop install`)"}}async function J(e){let r=m();if(!r)return{launched:!1,message:"sootsim desktop app not installed"};try{let t=await I(e.url,r,{device:e.device,profileId:e.profileId,ephemeralProfile:e.ephemeralProfile});return t.launched?{launched:!0,message:e.url?`electron launched via ${t.via} \u2192 ${e.url}`:`electron launched via ${t.via}`,target:t.target,attachUrl:e.url}:{launched:!1,message:"desktop companion failed to start"}}catch(t){return{launched:!1,message:`electron launch failed: ${t instanceof Error?t.message:String(t)}`}}}var L={id:"electron",name:"electron",description:"sootsim desktop companion app (native window, menu bar)",kind:"native",availability:V,launch:J};import{spawn as X}from"child_process";import{closeSync as Z,mkdtempSync as Q,openSync as ee,readFileSync as re}from"fs";import{createRequire as te}from"module";import{tmpdir as C}from"os";import{join as W}from"path";var oe=`
|
|
3
4
|
const modulePath = process.env.SOOTSIM_PW_MODULE;
|
|
4
5
|
const url = process.env.SOOTSIM_PW_URL;
|
|
5
6
|
const headless = process.env.SOOTSIM_PW_HEADLESS === '1';
|
|
@@ -11,7 +12,7 @@ const callerUserDataDir = process.env.SOOTSIM_PW_USERDATADIR || '';
|
|
|
11
12
|
const ownerPid = Number(process.env.SOOTSIM_PW_OWNER_PID || 0);
|
|
12
13
|
const ownerPollMs = Number(process.env.SOOTSIM_PW_OWNER_POLL_MS || 5000);
|
|
13
14
|
// optional CDP port \u2014 exposes Chrome's remote-debugging endpoint so a
|
|
14
|
-
// bridge-driven sim can also be cpu-profiled (sootsim cpu
|
|
15
|
+
// bridge-driven sim can also be cpu-profiled (sootsim perf cpu --cdp-port).
|
|
15
16
|
// playwright keeps its own pipe connection; the port is an additional endpoint.
|
|
16
17
|
const cdpPort = process.env.SOOTSIM_PW_CDP_PORT || '';
|
|
17
18
|
// browser engine: 'chromium' (default) | 'webkit' | 'firefox'. webkit is the
|
|
@@ -216,7 +217,7 @@ const cleanupProfile = () => {
|
|
|
216
217
|
// errors with "not supported on Linux Arm64"), fall back to Playwright's
|
|
217
218
|
// bundled chromium so the driver still works rather than crashing the
|
|
218
219
|
// sim out entirely. set SOOTSIM_PW_CHANNEL=chrome|chromium|msedge|... to
|
|
219
|
-
// pin the channel. NOTE: this is NOT enough to make \`sootsim cpu
|
|
220
|
+
// pin the channel. NOTE: this is NOT enough to make \`sootsim perf cpu\`
|
|
220
221
|
// work \u2014 that profiles the tenant *worker*, and the JS Self-Profiler API
|
|
221
222
|
// cannot be constructed in a dedicated worker (see
|
|
222
223
|
// worker-handlers/cpu-profile.ts). cpu-profile needs a CDP-based profiler
|
|
@@ -343,6 +344,6 @@ const cleanupProfile = () => {
|
|
|
343
344
|
process.stderr.write(String((err && err.stack) || err) + '\\n');
|
|
344
345
|
process.exit(1);
|
|
345
346
|
});
|
|
346
|
-
`;function
|
|
347
|
-
${
|
|
348
|
-
${
|
|
347
|
+
`;function R(){let e=[process.cwd()+"/"];try{process.argv[1]&&e.push(process.argv[1])}catch{}for(let r of e)try{let t=te(r);for(let o of["playwright","playwright-chromium","playwright-core"])try{return{spec:o,modulePath:t.resolve(o)}}catch{}}catch{}return null}function ie(){let e=R();return e?{available:!0,reason:null,detail:`resolved via ${e.spec}`}:{available:!1,reason:"playwright not installed in the current workspace"}}function ne(e,r){return process.platform!=="linux"||e.headless||process.env.DISPLAY||process.env.WAYLAND_DISPLAY||!/missing x server|cannot open display|x server|x11/i.test(r)?null:" hint: linux without DISPLAY/WAYLAND_DISPLAY \u2014 rerun without --headed (or add --headless) to run playwright headless."}function se(e){return e.profileId?y(E(e.profileId).id):e.ephemeralProfile?Q(W(C(),"sootsim-playwright-profile-")):""}async function ae(e){let r=R();if(!r)return{launched:!1,message:"playwright not installed \u2014 run `bun add -D playwright` first"};if(!e.url)return{launched:!1,message:"playwright driver requires a target url"};let t=W(C(),`sootsim-playwright-host-${Date.now().toString(36)}-${process.pid}.log`),o=`${t}.connected`,i=ee(t,"a");try{let n=O(),p=X(process.execPath,["-e",oe],{detached:!0,stdio:["ignore","ignore",i],env:{...process.env,SOOTSIM_PW_MODULE:r.modulePath,SOOTSIM_PW_URL:e.url,SOOTSIM_PW_HEADLESS:e.headless??!0?"1":"0",SOOTSIM_PW_USERDATADIR:se(e),SOOTSIM_PW_CDP_PORT:e.cdpPort?String(e.cdpPort):"",SOOTSIM_PW_BROWSER:e.browser??"",SOOTSIM_PW_VIEWPORT:e.viewport?`${e.viewport.width}x${e.viewport.height}`:"",SOOTSIM_PW_CONNECTED_ACK_FILE:o,SOOTSIM_PW_CONNECT_TIMEOUT_MS:String(e.connectTimeoutMs??12e4),SOOTSIM_PW_OWNER_PID:n&&n>1?String(n):""}});p.unref();let D=await new Promise(l=>{let d=setTimeout(()=>l(null),4e3);p.once("exit",F=>{clearTimeout(d),l(F??0)})});if(D!==null){let l=re(t,"utf8").trim(),d=ne(e,l);return{launched:!1,message:`playwright host exited early (code ${D}) \u2014 host log ${t}${l?`:
|
|
348
|
+
${l}`:""}${d?`
|
|
349
|
+
${d}`:""}`}}return{launched:!0,message:`playwright chrome launched \u2192 ${e.url}`,pid:p.pid,target:r.spec,attachUrl:e.url,connectAckFile:o,diagnosticLogPath:t}}catch(n){return{launched:!1,message:`playwright launch failed: ${n instanceof Error?n.message:String(n)}`}}finally{Z(i)}}var N={id:"playwright",name:"playwright",description:"programmatic chromium via the playwright package \u2014 headless default",kind:"automation",availability:ie,launch:ae};function le(){return process.platform!=="darwin"&&process.platform!=="linux"&&process.platform!=="win32"?{available:!1,reason:`unsupported platform: ${process.platform}`}:{available:!0,reason:null,detail:process.platform==="darwin"?"open(1)":process.platform==="win32"?"cmd /c start":"xdg-open(1)"}}async function ce(e){if(e.headless)return{launched:!1,message:"system driver does not support --headless; use chromium or playwright"};if(!e.url)return{launched:!1,message:"system driver requires a target url"};if(e.profileId||e.ephemeralProfile)return{launched:!1,message:"profiles require electron or playwright; browser tabs use your current browser profile"};try{let r=await T(e.url,{detached:e.detached??!0,newWindow:e.newWindow});return{launched:!0,message:`${r.via} launch \u2192 ${e.url}`,pid:r.pid,target:r.target,attachUrl:e.url}}catch(r){return{launched:!1,message:`system launch failed: ${r instanceof Error?r.message:String(r)}`}}}var $={id:"system",name:"system",description:"shared browser launcher \u2014 system default or chromium window",kind:"delegate",availability:le,launch:ce};var u=[M,L,N,$];function Le(){return u}function Ce(e){return u.find(r=>r.id===e)??null}function We(e,r){if(e)return u.find(o=>o.id===e)??null;for(let t of r){let o=u.find(i=>i.id===t);if(o&&o.availability().available)return o}return null}function Re(){return u.map(e=>{let r=e.availability();return{id:e.id,name:e.name,kind:e.kind,description:e.description,available:r.available,reason:r.reason,detail:r.detail??null}})}export{G as a,E as b,B as c,pe as d,j as e,M as f,L as g,N as h,$ as i,u as j,Le as k,Ce as l,We as m,Re as n};
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/*! sootsim v0.1.190 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
|
+
import{a as ve,b as Te,c as Se}from"./chunk-AAQ6AYYW.js";import{c as he}from"./chunk-R3VO3MDO.js";import{d as ge}from"./chunk-WR5IDCCN.js";import{g as ye,i as be,k as x}from"./chunk-Y6CZ5N26.js";import{d as we}from"./chunk-QJVITDKU.js";import{a as me,b as S}from"./chunk-KLGX6B46.js";import{a as fe}from"./chunk-K5GLQDTG.js";import{createHash as rt}from"crypto";import{readFileSync as te}from"fs";import{gzipSync as Ue}from"zlib";function xe(e){let t=(e||"").toLowerCase().split(";")[0].trim();return t?!(t.startsWith("image/")||t.startsWith("video/")||t.startsWith("audio/")||t==="font/woff2"||t==="application/font-woff2"||t==="application/zip"||t==="application/gzip"):!0}import{brotliCompressSync as Ke,constants as je}from"node:zlib";var Ge=9;function Ie(e){return Ke(e,{params:{[je.BROTLI_PARAM_QUALITY]:Ge}})}function ee(e,t){let r=new AbortController,s=setTimeout(()=>r.abort(new Error(`${t} timed out after ${e/1e3}s`)),e);return{signal:r.signal,cancel:()=>clearTimeout(s)}}async function Ye(e){let t=ee(12e4,`PUT ${e.url}`),r;try{r=await fetch(e.url,{method:"PUT",headers:{"content-type":e.contentType},body:e.bytes,signal:t.signal})}finally{t.cancel()}if(!r.ok){let s=await r.text().catch(()=>"");throw new Error(`PUT ${e.url} failed ${r.status}: ${s.slice(0,200)}`)}}async function Qe(e,t=8,r){let s=0,i=0,a=e.length;await Promise.all(Array.from({length:Math.min(t,a)},async()=>{for(;s<a;){let c=e[s++];await Ye(c),i++,r?.(i,a)}}))}function Xe(e,t,r,s){let i=[];i.push({url:e.bundle.putUrl,contentType:e.bundle.contentType,bytes:t});for(let a of e.files){let c=r.get(a.urlhash);c&&i.push({url:a.putUrl,contentType:a.contentType,bytes:c})}e.events&&s?.eventsBytes&&i.push({url:e.events.putUrl,contentType:e.events.contentType,bytes:s.eventsBytes}),e.timeline&&s?.timelineBytes&&i.push({url:e.timeline.putUrl,contentType:e.timeline.contentType,bytes:s.timelineBytes}),e.flowVideo&&s?.videoBytes&&i.push({url:e.flowVideo.putUrl,contentType:e.flowVideo.contentType,bytes:s.videoBytes}),e.storage&&s?.storageBytes&&i.push({url:e.storage.putUrl,contentType:e.storage.contentType,bytes:s.storageBytes});for(let a of e.snapshots??[]){let c=s?.snapshotBytes?.get(a.id);c&&i.push({url:a.putUrl,contentType:a.contentType,bytes:c})}return i}function Ze(e){return e.replace(/\/+$/,"")}var N=class extends Error{constructor(r,s,i,a=""){super(r);this.status=s;this.phase=i;this.responseText=a;this.name="PresignedUploadError"}};async function Me(e){let t=Ze(e.originBase),r={"content-type":"application/json"};e.authHeader&&(r.authorization=e.authHeader),e.adminBypassToken&&(r["x-soot-admin-upload-bypass"]=e.adminBypassToken);let s=ee(3e4,"init"),i;try{i=await fetch(`${t}/api/preview/upload/init`,{method:"POST",headers:r,body:JSON.stringify(e.initBody),signal:s.signal})}finally{s.cancel()}if(!i.ok){let y=await i.text().catch(()=>"");throw new N(`init failed: ${i.status} ${y.slice(0,200)}`,i.status,"init",y)}let a=await i.json(),c=Xe(a,e.bundleBytes,e.filesByHash,e.extras);await Qe(c,e.concurrency??8,e.onPutProgress);let h=ee(3e4,"finalize"),p;try{p=await fetch(`${t}/api/preview/upload/finalize`,{method:"POST",headers:r,body:JSON.stringify({token:a.token}),signal:h.signal})}finally{h.cancel()}if(!p.ok){let y=await p.text().catch(()=>"");throw new N(`finalize failed: ${p.status} ${y.slice(0,200)}`,p.status,"finalize",y)}let _=await p.json();return{init:a,finalize:_}}function et(e){return e!==null&&typeof e=="object"?e:null}function Re(e){return typeof e=="number"&&Number.isFinite(e)?e:void 0}function Ee(e){let t=et(e);return t?t.schemaVersion===1&&Re(t.t)!==void 0&&Re(t.seq)!==void 0&&typeof t.context=="string"&&typeof t.kind=="string"&&"data"in t:!1}function ot(e){if(!e)return null;try{let t=JSON.parse(e);return typeof t.message=="string"&&t.message?t.message:null}catch{return null}}var ke=process.env.SOOTSIM_UPLOAD_ORIGIN||"https://sootbean.com",$e=process.env.SOOTSIM_PREVIEW_ORIGIN||"https://sootsim.com",re="http://localhost:3000",st=2e3;async function it(e){if(e)return e;if(process.env.SOOTSIM_UPLOAD_ORIGIN)return process.env.SOOTSIM_UPLOAD_ORIGIN;try{let t=await fetch(`${re}/api/preview/upload/init`,{method:"OPTIONS",signal:AbortSignal.timeout(st)});if(t.ok||t.status===204||t.status===405)return re}catch{}return ke}function B(e){return e.replace(/\/$/,"")}function at(e){try{let r=new URL(e).hostname.replace(/^\[|\]$/g,"").toLowerCase();return r==="localhost"||r.endsWith(".localhost")||r==="0.0.0.0"||r==="::1"||/^127(?:\.\d{1,3}){3}$/.test(r)}catch{return!1}}function lt(e){try{let t=new URL(e).hostname.toLowerCase();return t==="sootbean.com"||t.endsWith(".sootbean.com")}catch{return!1}}function ut(e,t){return t?B(t):process.env.SOOTSIM_PREVIEW_ORIGIN?B(process.env.SOOTSIM_PREVIEW_ORIGIN):at(e)?B(e):lt(e)?B($e):B(e)}function ct(){console.log(`
|
|
3
|
+
sootsim record upload \u2014 publish the current recorded bundle as a /preview/<id> link
|
|
4
|
+
|
|
5
|
+
usage:
|
|
6
|
+
sootsim record upload [--origin <url>] [--public-origin <url>] (--events <path> | --video <path>) [--screenshot <path>] [--owner <org> --repo <repo>] [--sim <sim>] [--open] [--assets-only]
|
|
7
|
+
|
|
8
|
+
options:
|
|
9
|
+
--origin <url> upload target (default: auto)
|
|
10
|
+
prefers ${re} when available, otherwise
|
|
11
|
+
falls back to ${ke}
|
|
12
|
+
override with SOOTSIM_UPLOAD_ORIGIN env var
|
|
13
|
+
--public-origin <url>
|
|
14
|
+
public /preview link origin (default: ${$e}
|
|
15
|
+
for prod uploads, upload origin for localhost/custom origins).
|
|
16
|
+
override with SOOTSIM_PREVIEW_ORIGIN env var
|
|
17
|
+
--events <path> path to a gzipped events .jsonl.gz file to attach
|
|
18
|
+
required unless --video is present; previews must
|
|
19
|
+
have replay or recording playback data
|
|
20
|
+
--screenshot <path>
|
|
21
|
+
path to a PNG thumbnail to attach to the share
|
|
22
|
+
--video <path> path to a mp4/gif flow recording. embedded inline
|
|
23
|
+
in the pr sticky comment served at
|
|
24
|
+
/api/preview/flow-video?id=<share-id>
|
|
25
|
+
--video-duration-ms <ms>
|
|
26
|
+
duration hint for attached flow video
|
|
27
|
+
--owner <org> associate a session upload with a linked org repo
|
|
28
|
+
--repo <repo> repo name for --owner; the signed-in user must belong
|
|
29
|
+
to the local/org team that owns the link
|
|
30
|
+
--billing-kind test_run
|
|
31
|
+
meter this upload as a natural-language test run
|
|
32
|
+
--sim <sim> target a specific sim (see: sootsim list)
|
|
33
|
+
--open open the resulting /preview/<id> url in the browser
|
|
34
|
+
--assets-only drop API/JSON/HTML records before upload; keep images,
|
|
35
|
+
fonts, css, js, and binary blobs. live-data demos hit
|
|
36
|
+
the real network at replay time instead of serving
|
|
37
|
+
recorded API snapshots
|
|
38
|
+
-h, --help
|
|
39
|
+
|
|
40
|
+
examples:
|
|
41
|
+
sootsim record upload --events ./my-session.jsonl.gz
|
|
42
|
+
sootsim record upload --origin http://localhost:3000 --events ./my-session.jsonl.gz --open
|
|
43
|
+
sootsim record upload --video /tmp/soot-flow.mp4 --video-duration-ms 12000
|
|
44
|
+
`)}function d(e,t){let r=e.findIndex(i=>i===t);if(r<0)return;let s=e[r+1];return e.splice(r,2),s}function Be(e,t){let r=e.findIndex(s=>s===t);return r<0?!1:(e.splice(r,1),!0)}function Pe(e,t){if(!e)return;let r=Number(e);return(!Number.isFinite(r)||r<=0)&&(console.error(` invalid ${t}: ${e}`),process.exit(1)),Math.round(r)}function Ae(e){let t=(e||"").toLowerCase().split(";")[0].trim();return t?!!(t.startsWith("image/")||t.startsWith("font/")||t.startsWith("video/")||t.startsWith("audio/")||t.startsWith("model/")||t==="text/css"||t==="application/javascript"||t==="text/javascript"||t==="application/wasm"||t==="application/font-woff"||t==="application/font-woff2"||t==="application/octet-stream"):!1}async function _e(e){let t=await fetch(e);if(!t.ok)throw new Error(`fetch ${e} -> ${t.status} ${t.statusText}`);return new Uint8Array(await t.arrayBuffer())}function dt(e){return/\.bundle($|\?)/.test(e)||/\.js($|\?)/.test(e)?"application/javascript":/\.zip($|\?)/.test(e)?"application/zip":"application/javascript"}function pt(e){try{return new URL(e).searchParams.get("appFonts")||""}catch{return""}}function ft(e){try{return new URL(e).searchParams.get("appSplash")||""}catch{return""}}function mt(e){try{let t=new URL(e);return t.searchParams.get("lazy")==="true"?(t.searchParams.set("lazy","false"),t.toString()):e}catch{return e}}async function gt(e,t){let s=[];for(let i=0;i<t;i+=15e5){let a=Math.min(i+15e5,t),c=await x(e,`(window.__sootsimLastTransformedBundle?.text || "").slice(${i}, ${a})`);if(typeof c!="string")return null;s.push(c)}return s.join("")}function ht(e){return e.recordedDurationMs&&e.recordingStartedAtMs?{since:e.recordingStartedAtMs-1e4,until:e.recordingStartedAtMs+e.recordedDurationMs+5e3,limit:2e3}:{limit:2e3}}function ne(e){let t=new Map;for(let r of e)t.set(r.urlhash||r.url,r);return Array.from(t.values())}async function Ft(e,t){(e.includes("--help")||e.includes("-h"))&&(ct(),process.exit(0));let r=[...e],s=await it(d(r,"--origin")),i=ut(s,d(r,"--public-origin")),a=d(r,"--events"),c=d(r,"--screenshot"),h=d(r,"--video"),p=d(r,"--video-duration-ms"),_=Pe(d(r,"--recorded-duration-ms"),"--recorded-duration-ms"),y=Pe(d(r,"--recording-started-at-ms"),"--recording-started-at-ms"),z=d(r,"--owner"),D=d(r,"--repo"),k=d(r,"--billing-kind"),Le=Be(r,"--open");(z&&!D||!z&&D)&&(console.error(" --owner and --repo must be provided together"),process.exit(1)),k&&k!=="test_run"&&(console.error(` invalid --billing-kind: ${k}`),process.exit(1)),!a&&!h&&(console.error(" preview uploads require playback data: pass --events or --video.\n for a normal local preview, use `sootsim record --mode combined --open`\n or `sootsim flow --preview` instead of uploading a bundle-only snapshot."),process.exit(1));let oe=Be(r,"--assets-only"),Oe=ye(r,{stripBooleanFlags:[],stripValueFlags:[]}),b=be(Oe),u,se=[],w=[],$=[],H=null;try{if(u=await x(b,'(typeof window.__sootsimCaptureBundle === "function") ? window.__sootsimCaptureBundle() : null'),u?.bundleUrl){let l=new URL(u.bundleUrl).origin,[Y,Q]=await Promise.all([x(b,`(window.__sootsimPreviewRecorder?.list?.(${JSON.stringify(l)}) || [])`),x(b,`(async () => {
|
|
45
|
+
const list = window.__sootsimListWorkerFetchRecorder
|
|
46
|
+
return typeof list === 'function'
|
|
47
|
+
? await list(${JSON.stringify(l)})
|
|
48
|
+
: []
|
|
49
|
+
})()`)]);se=ne([...Y,...Q]).filter(f=>{try{return!new URL(f.url).pathname.startsWith("/api/")}catch{return!0}});let U=await x(b,`(async () => {
|
|
50
|
+
const rec = window.__sootsimPreviewRecorder
|
|
51
|
+
const workerList = window.__sootsimListWorkerFetchRecorder
|
|
52
|
+
return {
|
|
53
|
+
main: rec?.list ? rec.list() : [],
|
|
54
|
+
worker: typeof workerList === 'function' ? await workerList() : [],
|
|
55
|
+
}
|
|
56
|
+
})()`),A=(U?ne([...U.main,...U.worker]):[]).filter(f=>{try{return new URL(f.url).origin!==l}catch{return!1}}),T=A.length>0?{count:A.length,totalBytes:A.reduce((f,X)=>f+(X.size||0),0)}:null;if(T&&T.count>0){console.log(` ${T.count} recorded cross-origin responses (${(T.totalBytes/1024).toFixed(1)} KiB)`);let f=await x(b,`(async () => {
|
|
57
|
+
const rec = window.__sootsimPreviewRecorder
|
|
58
|
+
const workerDump = window.__sootsimDumpWorkerFetchRecorder
|
|
59
|
+
const bundleUrl = ${JSON.stringify(u.bundleUrl)}
|
|
60
|
+
const keep = (r) => {
|
|
61
|
+
try {
|
|
62
|
+
const u = new URL(r.url)
|
|
63
|
+
if (u.origin !== ${JSON.stringify(l)}) return true
|
|
64
|
+
// bundle-origin api responses came from the rewritten
|
|
65
|
+
// /__app-api proxy at record time (re-keyed by the
|
|
66
|
+
// recorder's unwrap step). they need bodies attached the
|
|
67
|
+
// same way as cross-origin records \u2014 direct re-fetch from
|
|
68
|
+
// the dev server lacks the bundle's session cookies.
|
|
69
|
+
if (r.url !== bundleUrl && u.pathname.startsWith('/api/')) return true
|
|
70
|
+
return false
|
|
71
|
+
} catch { return false }
|
|
72
|
+
}
|
|
73
|
+
return {
|
|
74
|
+
main: rec?.dump ? rec.dump().filter(keep) : [],
|
|
75
|
+
worker: typeof workerDump === 'function'
|
|
76
|
+
? (await workerDump()).filter(keep)
|
|
77
|
+
: [],
|
|
78
|
+
}
|
|
79
|
+
})()`);if(w=ne([...f.main,...f.worker]),oe){let X=w.length;w=w.filter(Z=>Ae(Z.contentType));let qe=T.totalBytes-w.reduce((Z,Je)=>Z+(Je.size||0),0);console.log(` --assets-only: kept ${w.length}/${X} records (dropped ${(qe/1024).toFixed(1)} KiB of API responses)`)}}}u?.transformedBundle&&(H=await gt(b,u.transformedBundle.byteLength));let n=await x(b,`(() => {
|
|
80
|
+
const bridge = window.SootSim?.bridges?.timeline ?? window.__sootsimTimeline
|
|
81
|
+
if (!bridge || typeof bridge.recent !== 'function') return null
|
|
82
|
+
return bridge.recent(${JSON.stringify(ht({recordedDurationMs:_,recordingStartedAtMs:y}))})
|
|
83
|
+
})()`).catch(l=>(console.warn(` warning: failed to capture trace timeline: ${l instanceof Error?l.message:String(l)}`),null));$=(Array.isArray(n?.events)?n.events:[]).filter(Ee)}finally{b.close()}u||(console.error(" could not read bundle snapshot \u2014 is sootsim running and is the bundle loaded?"),process.exit(2)),u.bundleUrl||(console.error(` no ?bundle= URL on the current sootsim tab.
|
|
84
|
+
open the app you want to share first (e.g. sootsim open 8082), then run upload.`),process.exit(2));let m,V=!1;if(H!==null)m=new TextEncoder().encode(H),V=!0,console.log(` using post-transform bundle: ${(m.byteLength/1024).toFixed(1)} KiB`);else{let n=mt(u.bundleUrl);n!==u.bundleUrl&&console.log(" forcing lazy=false for self-contained bundle"),console.log(` capturing: ${n}`),m=await _e(n),console.log(` main bundle: ${(m.byteLength/1024).toFixed(1)} KiB`)}let L=se.filter(n=>n.url!==u.bundleUrl);oe&&(L=L.filter(n=>Ae(n.contentType))),console.log(` fetching ${L.length} extra files\u2026`);let O=(await Promise.all(L.map(async n=>{try{let o=await _e(n.url);return{...n,bytes:o}}catch(o){return console.error(` warning: failed to re-fetch ${n.url}: ${o instanceof Error?o.message:o}`),null}}))).filter(n=>!!n),Fe=O.reduce((n,o)=>n+o.bytes.byteLength,0);console.log(` ${O.length} extra files: ${(Fe/1024).toFixed(1)} KiB`);let I;a&&(I=te(a));let ie=$.map(n=>JSON.stringify(n)).join(`
|
|
85
|
+
`),W=Ue(ie?`${ie}
|
|
86
|
+
`:"");console.log(` trace timeline: ${$.length} events`);let g;c&&(g=te(c),console.log(` attaching screenshot: ${(g.byteLength/1024).toFixed(1)} KiB`));let v,P,ae;if(h){if(v=te(h),P=h.endsWith(".mp4")?"video/mp4":h.endsWith(".gif")?"image/gif":void 0,P||(console.error(" preview flow videos must be mp4 or gif"),await S(),process.exit(1)),p){let n=Number(p);(!Number.isFinite(n)||n<=0)&&(console.error(` invalid --video-duration-ms: ${p}`),await S(),process.exit(1)),ae=Math.round(n)}console.log(` attaching flow video: ${(v.byteLength/1024).toFixed(1)} KiB (${P})`)}let M=ve(),R=Se(M),Ce=fe();me({event:"preview_upload_started",identity:{userId:M?.kind==="session"?Ce?.user?.id??null:null,repoId:R?.repoId??null,installationId:R?.installationId??null},properties:{origin:s,hasAuth:!!M,authMode:M?.kind??"none",bundleBytes:m.byteLength,isTransformed:V,extraFiles:O.length,recordedFetches:w.length,hasEvents:!!I,traceTimelineEvents:$.length,hasScreenshot:!!g,hasVideo:!!v}}),M||(console.error(" preview uploads need auth."),console.error(" set SOOTSIM_API_KEY=sk_sootsim_..., run `sootsim login`, or use the soot github runner."),await S(),process.exit(1));let Ne=Te(M),ze=(()=>{try{return new URL(u.bundleUrl).origin}catch{return null}})(),F=(n,o,l,Y,Q,U,pe,A)=>{let T=xe(U),f=T?Ue(n):n;return{url:o,urlhash:l,method:Y,bodyHash:Q,requestVaryHash:A,contentType:U,responseHeaders:pe,bytes:f,encoding:T?"gzip":void 0}},le=[],q=pt(u.pageHref)||"";if(q){let n=await ge(q,{onStaged:({url:o,byteLength:l})=>console.log(` staged app font: ${o} (${(l/1024).toFixed(1)} KiB)`),onError:(o,l)=>console.error(` warning: failed to fetch app font ${o}: ${l instanceof Error?l.message:l}`)});for(let o of n)le.push(F(Buffer.from(o.bytes),o.url,o.urlhash,"GET","-",o.contentType))}let ue=[],J=ft(u.pageHref)||"";if(J){let n=await he(J,{onStaged:({url:o,byteLength:l})=>console.log(` staged splash image: ${o} (${(l/1024).toFixed(1)} KiB)`),onError:(o,l)=>console.error(` warning: failed to fetch splash image ${o}: ${l instanceof Error?l.message:l}`)});for(let o of n)ue.push(F(Buffer.from(o.bytes),o.url,o.urlhash,"GET","-",o.contentType))}let K=[...O.map(n=>F(n.bytes,n.url,n.urlhash,"GET","-",n.contentType,n.responseHeaders,n.requestVaryHash)),...w.map(n=>F(Buffer.from(n.bodyBase64,"base64"),n.url,n.urlhash,n.method||"GET",n.bodyHash||"-",n.contentType,n.responseHeaders,n.requestVaryHash)),...le,...ue],j=Ie(m),De=rt("sha256").update(m).digest("hex");console.log(` bundle raw=${(m.byteLength/1024).toFixed(1)} KiB br=${(j.byteLength/1024).toFixed(1)} KiB`);let He={contentHash:De,bundleSizeBytes:m.byteLength,bundleContentType:dt(u.bundleUrl),bundleEncoding:"br",bundleOrigin:ze,runtimeVersion:u.runtimeVersion??void 0,appFonts:q||void 0,appSplash:J||void 0,entry:u.entry,isTransformed:V,deviceSpec:u.deviceSpec,installationId:R?.installationId??void 0,repoId:R?.repoId,owner:z??R?.owner,repo:D??R?.repo,billingKind:k==="test_run"?"test_run":void 0,files:K.map(n=>({url:n.url,urlhash:n.urlhash,method:n.method,bodyHash:n.bodyHash,contentType:n.contentType,responseHeaders:n.responseHeaders,requestVaryHash:n.requestVaryHash,encoding:n.encoding,sizeBytes:n.bytes.byteLength})),events:I?{sizeBytes:I.byteLength}:void 0,timeline:{sizeBytes:W.byteLength,encoding:"gzip"},recordedDurationMs:_,recordingStartedAtMs:y,snapshots:g?[{id:"landing",label:"Landing",kind:"landing",t:0,contentType:"image/png",sizeBytes:g.byteLength}]:void 0,flowVideo:v&&P?{sizeBytes:v.byteLength,contentType:P,durationMs:ae}:void 0},ce=new Map;for(let n of K)ce.set(n.urlhash,n.bytes);let de=new Map;g&&de.set("landing",g);let Ve=Date.now(),E=j.byteLength;for(let n of K)E+=n.bytes.byteLength;I&&(E+=I.byteLength),E+=W.byteLength,g&&(E+=g.byteLength),v&&(E+=v.byteLength);let We=`${B(s)}/api/preview/upload/init`;console.log(` init: ${We}`);let C;try{let n=await Me({originBase:s,initBody:He,bundleBytes:j,filesByHash:ce,extras:{eventsBytes:I,timelineBytes:W,videoBytes:v,snapshotBytes:de},authHeader:Ne,concurrency:16});C=n.finalize;let o=1+n.init.files.length+(n.init.events?1:0)+(n.init.timeline?1:0)+n.init.snapshots.length+(n.init.flowVideo?1:0);console.log(` PUT ${o} objects in ${Date.now()-Ve}ms (${(E/1024).toFixed(1)} KiB)`)}catch(n){let o=n;o.phase==="init"&&o.status===401&&(console.error(" preview upload requires a valid login."),console.error(" run `sootsim login` and retry."),await S(),process.exit(1)),o.status===402&&(console.error(` ${ot(o.responseText)??"preview uploads require Personal, Team, or an active trial \u2014 upgrade from the billing dialog."}`),await S(),process.exit(1)),console.error(` ${o.message??`${o.phase??"upload"} failed: ${String(n)}`}`),await S(),process.exit(1)}let G=`${i}${C.url}`;return console.log(`
|
|
87
|
+
stored ${C.filesStored??0} extra files`),console.log(` preview: ${G}`),Le&&await we(G),await S(),{previewUrl:G,shareId:C.id}}export{it as a,ut as b,Ft as c};
|