sootsim 0.1.39 → 0.1.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-cli/bin.js +16 -15
- package/dist-cli/chunks/{agent-HZP3LUGJ.js → agent-3F5PO4NL.js} +2 -2
- package/dist-cli/chunks/{agent-wrapper-CS6TV5UR.js → agent-wrapper-LVUUZRWL.js} +2 -2
- package/dist-cli/chunks/{assert-WVTX4CNR.js → assert-4WMVS3WU.js} +2 -2
- package/dist-cli/chunks/auto-bootstrap-Q4A3PTF5.js +2 -0
- package/dist-cli/chunks/beta-CLLKUB5X.js +2 -0
- package/dist-cli/chunks/{chunk-MIE6NMPJ.js → chunk-4IAKB3C4.js} +6 -6
- package/dist-cli/chunks/{chunk-ZBB7YS6C.js → chunk-4L45Q3YX.js} +2 -2
- package/dist-cli/chunks/{chunk-UWRBEBML.js → chunk-553OZX4H.js} +2 -2
- package/dist-cli/chunks/{chunk-CBPTHIJV.js → chunk-5GK4YX7O.js} +1 -1
- package/dist-cli/chunks/{runtime-YJPWA3XA.js → chunk-5IAIIX7B.js} +3 -3
- package/dist-cli/chunks/{chunk-223TXYOC.js → chunk-6X5NQJT7.js} +3 -3
- package/dist-cli/chunks/{chunk-JXKW62SL.js → chunk-6XI4VHIL.js} +2 -2
- package/dist-cli/chunks/{chunk-B2SCT4DL.js → chunk-BZED27B2.js} +2 -2
- package/dist-cli/chunks/{chunk-5L5SZXXG.js → chunk-CAJ247SC.js} +2 -2
- package/dist-cli/chunks/{chunk-YUKH7HF6.js → chunk-CCZHRBXJ.js} +1 -1
- package/dist-cli/chunks/{chunk-DSDLGFWH.js → chunk-D2ZMP7G4.js} +2 -2
- package/dist-cli/chunks/{chunk-WHQWINDB.js → chunk-D4Z7MWQY.js} +2 -2
- package/dist-cli/chunks/{chunk-WD54RD4K.js → chunk-DEBXVPIE.js} +1 -1
- package/dist-cli/chunks/{chunk-SLQ2GTYF.js → chunk-DHJIXXWG.js} +2 -2
- package/dist-cli/chunks/chunk-DPZDTJVQ.js +1 -0
- package/dist-cli/chunks/{chunk-NYZGZDHI.js → chunk-DSTHAISO.js} +1 -1
- package/dist-cli/chunks/{chunk-C6GUAXKO.js → chunk-EOWN4ZFJ.js} +1 -1
- package/dist-cli/chunks/chunk-FFR7EA4U.js +1 -0
- package/dist-cli/chunks/chunk-FNIL6BYS.js +108 -0
- package/dist-cli/chunks/chunk-I7KXFJDK.js +1 -0
- package/dist-cli/chunks/{chunk-OB3TB4AN.js → chunk-J6BPROH4.js} +1 -1
- package/dist-cli/chunks/{chunk-NJ4WXWKO.js → chunk-KGVH3YAG.js} +2 -2
- package/dist-cli/chunks/{chunk-RJQ73DLG.js → chunk-KVOMVYG6.js} +4 -4
- package/dist-cli/chunks/{chunk-FEMOLCB5.js → chunk-LCES5ZJI.js} +2 -2
- package/dist-cli/chunks/{chunk-NF65BNJR.js → chunk-LXR5EI74.js} +2 -2
- package/dist-cli/chunks/{chunk-YHYSOUIJ.js → chunk-MLCBIX7O.js} +2 -2
- package/dist-cli/chunks/{chunk-2ESCYOZW.js → chunk-OV5TY7M3.js} +2 -2
- package/dist-cli/chunks/chunk-PKB6IEGM.js +2 -0
- package/dist-cli/chunks/chunk-PNGBWMQH.js +17 -0
- package/dist-cli/chunks/{chunk-P6F636LU.js → chunk-QMBYRPRK.js} +1 -1
- package/dist-cli/chunks/{chunk-4YUHJ5FX.js → chunk-QUULF2II.js} +2 -2
- package/dist-cli/chunks/chunk-S4PJMUC7.js +2 -0
- package/dist-cli/chunks/{chunk-MGVTLDI3.js → chunk-TK2IPNHL.js} +2 -2
- package/dist-cli/chunks/chunk-U3JD6X75.js +4 -0
- package/dist-cli/chunks/{chunk-VLUFTHBB.js → chunk-W2XRHDQQ.js} +2 -2
- package/dist-cli/chunks/{chunk-XYTDYBXJ.js → chunk-WPS3TIOB.js} +1 -1
- package/dist-cli/chunks/{chunk-GUHXSXNO.js → chunk-WQXG4I5N.js} +2 -2
- package/dist-cli/chunks/{chunk-YGUQSPU6.js → chunk-WZE6T3GT.js} +1 -1
- package/dist-cli/chunks/chunk-XWXFUFB2.js +1 -0
- package/dist-cli/chunks/{chunk-7J4UIBA5.js → chunk-Y5CFIRLN.js} +2 -2
- package/dist-cli/chunks/{chunk-RLGCJT2D.js → chunk-Y66CDFAT.js} +1 -1
- package/dist-cli/chunks/chunk-YJMXGTP4.js +2 -0
- package/dist-cli/chunks/{chunk-ECDPQ6S7.js → chunk-YKEBL6GE.js} +1 -1
- package/dist-cli/chunks/{chunk-E5RYQUFB.js → chunk-Z3I2I4IO.js} +3 -3
- package/dist-cli/chunks/{compat-UMJ2IXUW.js → compat-NBFWHK5S.js} +2 -2
- package/dist-cli/chunks/{config-YMJK426V.js → config-JEDQ3NHA.js} +2 -2
- package/dist-cli/chunks/control-IMWZVYC3.js +2 -0
- package/dist-cli/chunks/{cpu-profile-67MCPAA2.js → cpu-profile-MQPUSRHG.js} +2 -2
- package/dist-cli/chunks/{daemon-LIVCJZR3.js → daemon-HOL7J3BI.js} +2 -2
- package/dist-cli/chunks/{debug-EV73WC7H.js → debug-LNVMIWD6.js} +20 -20
- package/dist-cli/chunks/demo-app-registry-4RFMJ4FM.js +2 -0
- package/dist-cli/chunks/{detox-NBT5BVX3.js → detox-EEZPH3DZ.js} +2 -2
- package/dist-cli/chunks/{device-MMROWQZ3.js → device-GVLYQI7X.js} +2 -2
- package/dist-cli/chunks/{diagnose-WXOKGBAJ.js → diagnose-JQ7DPTSL.js} +2 -2
- package/dist-cli/chunks/drivers-JUW6JBWH.js +2 -0
- package/dist-cli/chunks/{electron-F5DT7CFY.js → electron-UDV6K3IH.js} +3 -3
- package/dist-cli/chunks/flow-JOW23WNH.js +2 -0
- package/dist-cli/chunks/{hints-RODH4XE4.js → hints-46PJLATZ.js} +2 -2
- package/dist-cli/chunks/{home-paths-PCUMN33Z.js → home-paths-XD7AOYU7.js} +2 -2
- package/dist-cli/chunks/inspect-EDIKZ6O2.js +993 -0
- package/dist-cli/chunks/install-CCC3IF5S.js +2 -0
- package/dist-cli/chunks/{install-desktop-ASRNFHZU.js → install-desktop-CX6ATQTR.js} +3 -3
- package/dist-cli/chunks/{keys-DOOCGNTD.js → keys-CXQIYEVW.js} +2 -2
- package/dist-cli/chunks/{launch-DTVAQMZG.js → launch-DCFRKVD3.js} +3 -3
- package/dist-cli/chunks/{login-JA6VEDEP.js → login-HCIZL5GT.js} +4 -4
- package/dist-cli/chunks/{logout-H4WFWTPC.js → logout-7X2YHJY3.js} +2 -2
- package/dist-cli/chunks/{maestro-4TR7U6TS.js → maestro-TY622MIW.js} +2 -2
- package/dist-cli/chunks/{preview-GP7XXDW6.js → preview-DYI6ESOK.js} +2 -2
- package/dist-cli/chunks/{profile-3FESGAZD.js → profile-7SXJEJTG.js} +2 -2
- package/dist-cli/chunks/{react-SJD2DQQV.js → react-VGSDY766.js} +2 -2
- package/dist-cli/chunks/{record-PQUAMW5K.js → record-7JX2SMVP.js} +2 -2
- package/dist-cli/chunks/runtime-FTOQD7QK.js +2 -0
- package/dist-cli/chunks/runtime-delivery-PWLODFCY.js +2 -0
- package/dist-cli/chunks/{screenshot-45SAK7EW.js → screenshot-PTKY4UU4.js} +2 -2
- package/dist-cli/chunks/{screenshot-mode-TCY7FBGR.js → screenshot-mode-HSV7VY4G.js} +2 -2
- package/dist-cli/chunks/{screenshots-KZ364S2O.js → screenshots-VY7VAGSV.js} +2 -2
- package/dist-cli/chunks/server-EDB3EK4K.js +35 -0
- package/dist-cli/chunks/setup-repo-S2GFZR7F.js +2 -0
- package/dist-cli/chunks/{skills-SMXCCJCM.js → skills-KEPQLCMR.js} +2 -2
- package/dist-cli/chunks/start-5CJTBNRM.js +23 -0
- package/dist-cli/chunks/store-SCRULNVS.js +2 -0
- package/dist-cli/chunks/telemetry-RC3OT67I.js +2 -0
- package/dist-cli/chunks/{test-ZXTSA5GV.js → test-REKHGKFE.js} +3 -3
- package/dist-cli/chunks/{three-mode-4Q65J2ZA.js → three-mode-FZYHB4ZQ.js} +2 -2
- package/dist-cli/chunks/{timeline-ISEDS6XR.js → timeline-CWZAY52K.js} +2 -2
- package/dist-cli/chunks/upgrade-AIUJEF5F.js +4 -0
- package/dist-cli/chunks/upload-UDA5ITTE.js +2 -0
- package/dist-cli/chunks/what-happened-JSQQVQGE.js +15 -0
- package/dist-cli/chunks/{whoami-VKRQOG2U.js → whoami-5WUUPIRN.js} +2 -2
- package/dist-lib/agent-daemon-client.cjs +1 -1
- package/dist-lib/agent-events.cjs +1 -1
- package/dist-lib/agent-sessions.cjs +1 -1
- package/dist-lib/attached-projects.cjs +1 -1
- package/dist-lib/auth/shared-session.cjs +1 -1
- package/dist-lib/backend-origin.cjs +1 -1
- package/dist-lib/bridge-constants.cjs +1 -1
- package/dist-lib/cli-constants.cjs +1 -1
- package/dist-lib/config.cjs +1 -1
- package/dist-lib/dev-bundle-resolution.cjs +1 -1
- package/dist-lib/home-paths.cjs +1 -1
- package/dist-lib/host/bridge-host.cjs +115 -82
- package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
- package/dist-lib/index.cjs +1 -1
- package/dist-lib/metro.cjs +1 -1
- package/dist-lib/profiles.cjs +1 -1
- package/dist-lib/render-mode.cjs +1 -1
- package/dist-lib/vite-base.cjs +140 -88
- package/dist-lib/vite.cjs +1 -1
- package/package.json +1 -1
- package/dist-cli/chunks/auto-bootstrap-3TUCG2BC.js +0 -2
- package/dist-cli/chunks/beta-3SCMB3IN.js +0 -2
- package/dist-cli/chunks/chunk-4LHQRDSN.js +0 -2
- package/dist-cli/chunks/chunk-4UI5OHEO.js +0 -1
- package/dist-cli/chunks/chunk-5RSSCKBF.js +0 -1
- package/dist-cli/chunks/chunk-6TSUQHSC.js +0 -4
- package/dist-cli/chunks/chunk-B3OEHV2C.js +0 -1
- package/dist-cli/chunks/chunk-HWRR23AJ.js +0 -17
- package/dist-cli/chunks/chunk-NFJDHJHK.js +0 -1
- package/dist-cli/chunks/chunk-W4QHQT64.js +0 -2
- package/dist-cli/chunks/control-DJR3DUAB.js +0 -2
- package/dist-cli/chunks/demo-app-registry-NZBZVJ52.js +0 -2
- package/dist-cli/chunks/drivers-NSPV5S6T.js +0 -2
- package/dist-cli/chunks/flow-T6DZQWHE.js +0 -2
- package/dist-cli/chunks/inspect-BIMFJFDR.js +0 -1101
- package/dist-cli/chunks/install-5YPVP466.js +0 -2
- package/dist-cli/chunks/server-S5CRYXXZ.js +0 -35
- package/dist-cli/chunks/setup-repo-TH3GXOP7.js +0 -2
- package/dist-cli/chunks/start-KLSAQM3C.js +0 -23
- package/dist-cli/chunks/store-E2N5NOUS.js +0 -2
- package/dist-cli/chunks/telemetry-RJXVYJSN.js +0 -2
- package/dist-cli/chunks/upload-KB7INQRC.js +0 -2
- package/dist-cli/chunks/what-happened-STY3AOCQ.js +0 -15
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
/*! sootsim v0.1.39 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
|
-
import{a as o}from"./chunk-DSDLGFWH.js";import"./chunk-OB3TB4AN.js";import"./chunk-E5RYQUFB.js";import"./chunk-VLUFTHBB.js";import"./chunk-UWRBEBML.js";import"./chunk-HWRR23AJ.js";import"./chunk-RLGCJT2D.js";import"./chunk-B3OEHV2C.js";import"./chunk-ECDPQ6S7.js";import"./chunk-WD54RD4K.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};
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
/*! sootsim v0.1.39 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
|
-
import{b as Y,c as D,d as X,e as H,f as Z,h as Q,i as w,j as ee,k as te,l as ie,p as re,s as A,t as ne,u as se,v as oe,w as ae}from"./chunk-2ESCYOZW.js";import"./chunk-NYZGZDHI.js";import{a as E}from"./chunk-ZBB7YS6C.js";import"./chunk-YUKH7HF6.js";import"./chunk-FEMOLCB5.js";import{e as z}from"./chunk-6TSUQHSC.js";import{a as V,b as G}from"./chunk-VLUFTHBB.js";import"./chunk-UWRBEBML.js";import{d as q}from"./chunk-C6GUAXKO.js";import"./chunk-B3OEHV2C.js";import{A as W,B as _,D as F,E as j,F as $,G as J,H as K,I as N,u as L,v as U,y as T,z as M}from"./chunk-ECDPQ6S7.js";import"./chunk-WD54RD4K.js";import{spawn as Te}from"child_process";import v from"fs";import{createServer as Ee}from"http";import S from"path";import{WebSocket as m,WebSocketServer as Ie}from"ws";import ce from"node:fs";import I from"node:path";var P=1;function ge(){return[Number(process.env.VITE_PORT_WEB||process.env.PORT||3e3),Number(process.env.VITE_PORT_ZERO||7849),Number(process.env.VITE_PORT_POSTGRES||7432),Number(process.env.VITE_PORT_R2||9500)].filter(a=>Number.isFinite(a)&&a>0)}var x=class{subscriptions=new Map;sessionsBySocket=new Map;allSockets=new Set;pendingPromptEchoes=new Map;pendingTurns=new Map;opts;constructor(e={}){this.opts=e}registerSocket(e){this.allSockets.add(e)}unregisterSocket(e){let t=this.sessionsBySocket.get(e);if(t){for(let i of t)this.decrementSubscription(i);this.sessionsBySocket.delete(e)}this.allSockets.delete(e)}async handleMessage(e,t){let i=t?.type;if(typeof i!="string"||!i.startsWith("agent:"))return!1;let s=t.id;try{let n=await this.dispatch(e,i,t);this.respond(e,s,n)}catch(n){n instanceof A?this.respondError(e,s,n.message,n.code):this.respondError(e,s,n instanceof Error?n.message:String(n))}return!0}async seedOnBoot(){try{await ie()}catch(e){process.stderr.write(`[sootsim-agent] seedFromDemoAppRegistry failed: ${e instanceof Error?e.message:String(e)}
|
|
3
|
-
`)}}close(){for(let e of this.subscriptions.values())try{e.unsubscribe()}catch{}this.subscriptions.clear(),this.sessionsBySocket.clear(),this.allSockets.clear()}async dispatch(e,t,i){switch(t){case"agent:list-projects":return H();case"agent:upsert-project":return D(i.input??{});case"agent:delete-project":return Q(String(i.projectId)),{ok:!0};case"agent:auto-attach-for-url":return this.autoAttachForUrl(i.input??{});case"agent:list-sessions":return ee(i.projectId?String(i.projectId):void 0);case"agent:start-session":return this.doStartSession(i.input??{});case"agent:send-prompt":{let n=String(i.sessionId),o=w(n);if(!o)throw new A("NO_SESSION",`no session: ${n}`);let r=this.normalizePromptEnvelope(i);return await se(n,r),this.notePromptAccepted(n,r,o.status==="working")}case"agent:end-session":this.dropSessionFanout(String(i.sessionId)),await oe(String(i.sessionId));let s=w(String(i.sessionId));return s&&this.broadcastSessionStatus(s),{ok:!0};case"agent:get-transcript":return this.getTranscript(String(i.sessionId));case"agent:get-paths":return this.getPaths();case"agent:subscribe-events":return this.subscribeSocket(e,String(i.sessionId));case"agent:unsubscribe-events":return this.unsubscribeSocket(e,String(i.sessionId));default:throw new A("UNKNOWN_AGENT_MSG",`unknown agent message: ${t}`)}}async doStartSession(e){if(!X(e.projectId))throw new A("NO_PROJECT",`no project: ${e.projectId}`);let i=await ne(e);return this.broadcastSessionStatus(i.session),i}async autoAttachForUrl(e){let t=e.bundleUrl??"",i=(()=>{try{return new URL(t).port||null}catch{return null}})();if(!i)return{project:null};let s=this.opts.getExcludePorts?.()??ge(),o=(await E({excludePorts:s})).find(l=>String(l.port)===i);if(!o||!o.cwd)return{project:null};let r=H().find(l=>l.cwd===o.cwd)??null,c=Array.from(new Set([...r?.knownBundleUrls??[],o.bundleUrl,t]));return{project:D({cwd:o.cwd,name:o.projectName??I.basename(o.cwd),preferredProvider:e.provider??r?.preferredProvider,sourceRoots:r?.sourceRoots??[o.cwd],knownBundleUrls:c,framework:r?.framework??Se(o.framework),bundleId:o.bundleId??r?.bundleId})}}getTranscript(e){let t=re(e);return ce.existsSync(t)?ce.readFileSync(t,"utf8"):{error:"transcript not found",code:"NO_TRANSCRIPT"}}getPaths(){let e=Y();return{userDataDir:e,storeFile:I.join(e,"attached-projects.json"),sessionsDir:I.join(e,"sessions"),transcriptsDir:I.join(e,"transcripts")}}subscribeSocket(e,t){let i=this.sessionsBySocket.get(e);if(i||(i=new Set,this.sessionsBySocket.set(e,i)),i.has(t))return{ok:!0,refCount:this.subscriptions.get(t)?.refCount??1};i.add(t);let s=this.subscriptions.get(t);if(s)return s.refCount++,{ok:!0,refCount:s.refCount};let n=ae(t,o=>{let r=this.coalescePromptEcho(t,o);if(r&&(this.applySessionEvent(t,r),this.fanOutEvent(t,r)),o.type==="turn-completed"){let c=w(t);if(c)try{Z(c.projectId,{usd:o.costUsd,ts:o.ts})}catch(d){process.stderr.write(`[sootsim-agent] recordTurnTelemetry failed: ${d instanceof Error?d.message:String(d)}
|
|
4
|
-
`)}}});return this.subscriptions.set(t,{unsubscribe:n,refCount:1}),{ok:!0,refCount:1}}unsubscribeSocket(e,t){let i=this.sessionsBySocket.get(e);return!i||!i.has(t)?{ok:!0,refCount:0}:(i.delete(t),this.decrementSubscription(t))}decrementSubscription(e){let t=this.subscriptions.get(e);if(!t)return{ok:!0,refCount:0};if(t.refCount--,t.refCount<=0){try{t.unsubscribe()}catch{}return this.subscriptions.delete(e),{ok:!0,refCount:0}}return{ok:!0,refCount:t.refCount}}dropSessionFanout(e){let t=this.subscriptions.get(e);if(t){try{t.unsubscribe()}catch{}this.subscriptions.delete(e)}for(let i of this.sessionsBySocket.values())i.delete(e);this.clearPromptTracking(e)}normalizePromptEnvelope(e){if(e?.prompt&&typeof e.prompt=="object"){let t=e.prompt;return{text:String(t.text??""),...typeof t.displayText=="string"?{displayText:t.displayText}:{},...typeof t.inspectSummary=="string"?{inspectSummary:t.inspectSummary}:{},...typeof t.inspectTrace=="string"?{inspectTrace:t.inspectTrace}:{}}}return{text:String(e?.text??""),...typeof e?.displayText=="string"?{displayText:e.displayText}:{},...typeof e?.inspectSummary=="string"?{inspectSummary:e.inspectSummary}:{},...typeof e?.inspectTrace=="string"?{inspectTrace:e.inspectTrace}:{}}}notePromptAccepted(e,t,i){let s=Date.now(),n=this.pendingPromptEchoes.get(e)??[];n.push({sentAt:s}),this.pendingPromptEchoes.set(e,n);let o=Math.max(this.pendingTurns.get(e)??0,i?1:0)+1;this.pendingTurns.set(e,o);let r=t.displayText??t.text;return this.patchSession(e,{lastPrompt:r,status:"working",needsAttention:!1}),this.fanOutEvent(e,{type:"prompt-received",text:r,...t.inspectSummary?{inspectSummary:t.inspectSummary}:{},...t.inspectTrace?{inspectTrace:t.inspectTrace}:{},ts:s}),{ok:!0,queued:o>1,pendingTurns:o,queueDepth:Math.max(0,o-1)}}applySessionEvent(e,t){switch(t.type){case"prompt-received":case"turn-started":this.patchSession(e,{status:"working",needsAttention:!1});return;case"turn-completed":{let i=this.consumeSettledTurn(e);this.patchSession(e,{status:i>0?"working":"idle",needsAttention:!1,lastTurnFiles:t.filesTouched,currentlyEditing:void 0});return}case"approval-needed":this.patchSession(e,{status:"needs-attention",needsAttention:!0});return;case"error":{let i=this.consumeSettledTurn(e);this.patchSession(e,{status:i>0?"working":"needs-attention",needsAttention:i<=0,currentlyEditing:void 0});return}case"exited":this.clearPromptTracking(e),this.patchSession(e,{status:"ended",needsAttention:!1,wrapperPid:void 0,currentlyEditing:void 0});return;case"ready":case"turn-reasoning":case"turn-message":case"turn-plan":case"tool-call":case"file-edited":case"file-diff-delta":return}}patchSession(e,t){te(e,t);let i=w(e);i&&this.broadcastSessionStatus(i)}coalescePromptEcho(e,t){if(t.type!=="prompt-received")return t;let i=this.pendingPromptEchoes.get(e);if(!i||i.length===0)return t;for(;i.length>0&&Date.now()-i[0].sentAt>15e3;)i.shift();return i.length===0?(this.pendingPromptEchoes.delete(e),t):(i.shift(),i.length===0?this.pendingPromptEchoes.delete(e):this.pendingPromptEchoes.set(e,i),null)}consumeSettledTurn(e){let t=Math.max(0,(this.pendingTurns.get(e)??1)-1);return t>0?this.pendingTurns.set(e,t):this.pendingTurns.delete(e),t}clearPromptTracking(e){this.pendingPromptEchoes.delete(e),this.pendingTurns.delete(e)}fanOutEvent(e,t){let i=JSON.stringify({type:"agent:event",sessionId:e,event:t});for(let[s,n]of this.sessionsBySocket)if(n.has(e)&&s.readyState===P)try{s.send(i)}catch{}}broadcastSessionStatus(e){let t=JSON.stringify({type:"agent:session-status",session:e});for(let i of this.allSockets)if(i.readyState===P)try{i.send(t)}catch{}}respond(e,t,i){if(e.readyState===P)try{e.send(JSON.stringify({id:t,result:i}))}catch{}}respondError(e,t,i,s){if(e.readyState===P)try{e.send(JSON.stringify({id:t,error:i,...s?{code:s}:{}}))}catch{}}};function Se(a){return a==="expo"?"expo":a==="one"||a==="vxrn"?"one":"unknown"}import ye from"http";import ve from"https";var be="sootsim",we=new Set(["host","origin","referer","user-agent","cookie","connection","keep-alive","transfer-encoding","upgrade","content-length","sec-fetch-site","sec-fetch-mode","sec-fetch-dest","sec-ch-ua","sec-ch-ua-mobile","sec-ch-ua-platform"]),Ae={"access-control-allow-origin":"*","access-control-allow-methods":"GET,POST,PUT,DELETE,PATCH,OPTIONS","access-control-allow-headers":"*","access-control-expose-headers":"*","access-control-max-age":"3600"};function k(a){for(let[e,t]of Object.entries(Ae))a.setHeader(e,t)}function ke(a,e){let t=[],i=e;i?.code&&t.push(i.code),i?.message&&t.push(i.message),i?.cause?.code&&t.push(i.cause.code),i?.cause?.message&&t.push(i.cause.message);let n=[...new Set(t.filter(Boolean))].join(" | ")||String(e);return a.includes("stored-in-.env.local")?`${n} | upstream url still contains placeholder env values`:n}function Ce(a){let e={};for(let[t,i]of Object.entries(a))i&&(we.has(t.toLowerCase())||(e[t]=Array.isArray(i)?i.join(", "):i));return e["user-agent"]=be,e}function de(a){return a?.startsWith("/__fetch-proxy?")||a?.startsWith("/__proxy?")||!1}function le(a){return a?!!(a.startsWith("/__app-api?")||a.startsWith("/__app-api/")):!1}async function ue(a,e){if(a.method==="OPTIONS"){k(e),e.writeHead(204),e.end();return}let i=new URLSearchParams((a.url||"").split("?")[1]||"").get("url");if(!i){k(e),e.writeHead(400,{"Content-Type":"text/plain"}),e.end("missing url param");return}let s;try{s=new URL(i)}catch{k(e),e.writeHead(400,{"Content-Type":"text/plain"}),e.end("invalid url param");return}let n=Ce(a.headers),o;if(a.method!=="GET"&&a.method!=="HEAD"){let l=[];for await(let u of a)l.push(Buffer.isBuffer(u)?u:Buffer.from(u));l.length>0&&(o=Buffer.concat(l))}let r;try{r=await fetch(s.href,{method:a.method,headers:n,body:o,redirect:"follow"})}catch(l){k(e),e.writeHead(502,{"Content-Type":"text/plain"}),e.end(`fetch proxy error: ${ke(s.href,l)}`);return}r.headers.forEach((l,u)=>{let p=u.toLowerCase();p==="content-encoding"||p==="transfer-encoding"||p==="content-length"||p==="set-cookie"||p.startsWith("access-control-")||e.setHeader(u,l)}),k(e);let c=r.headers.getSetCookie?.()??[];c.length>0&&e.setHeader("x-sootsim-set-cookie",c.join(", ")),e.statusCode=r.status;let d=Buffer.from(await r.arrayBuffer());e.end(d)}function pe(a,e){let t=a.url||"",i="",s="";if(t.startsWith("/__app-api?")){let d=new URL(t,"http://sootsim.local");i=d.searchParams.get("path")||"",s=d.searchParams.get("origin")?.trim()||""}else if(t.startsWith("/__app-api/"))i=t.slice(10);else return!1;if(!s)return e.writeHead(400,{"Content-Type":"text/plain"}),e.end("app-api: missing origin query param"),!0;if(a.method==="OPTIONS")return e.writeHead(204,{"Access-Control-Allow-Origin":a.headers.origin||"*","Access-Control-Allow-Methods":"GET,POST,PUT,PATCH,DELETE,OPTIONS","Access-Control-Allow-Headers":a.headers["access-control-request-headers"]||"*","Access-Control-Allow-Credentials":"true","Access-Control-Max-Age":"86400"}),e.end(),!0;let n;try{n=new URL(i,s)}catch{return e.writeHead(400,{"Content-Type":"text/plain"}),e.end("app-api: invalid origin or path"),!0}let o=n.protocol==="https:"?ve:ye,r={...a.headers};delete r.host,r.host=n.host;let c=o.request({hostname:n.hostname,port:n.port||(n.protocol==="https:"?443:80),path:n.pathname+n.search,method:a.method,headers:r},d=>{let l=Object.keys(d.headers).filter(u=>{let p=u.toLowerCase();return!p.startsWith("access-control-")&&p!=="set-cookie"}).join(", ");e.writeHead(d.statusCode??502,{...d.headers,"access-control-allow-origin":a.headers.origin||"*","access-control-allow-credentials":"true","access-control-expose-headers":l}),d.pipe(e)});return c.on("error",d=>{e.statusCode=502,e.end(`app proxy error: ${d.message}`)}),a.pipe(c),!0}var Pe=new Set(["tap","keyboard","close"]);function xe(a){return!a||typeof a.type!="string"?!1:a.acquireLock===!0?!0:a.readOnly===!0?!1:Pe.has(a.type)}var Re=5e3,Be=3600*1e3,Oe="SOOTSIM_RUNTIME_UPDATE_INTERVAL_MS",Le={".html":"text/html; charset=utf-8",".js":"application/javascript",".cjs":"application/javascript",".mjs":"application/javascript",".css":"text/css; charset=utf-8",".json":"application/json; charset=utf-8",".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".svg":"image/svg+xml",".webp":"image/webp",".avif":"image/avif",".ico":"image/x-icon",".wasm":"application/wasm",".ttf":"font/ttf",".otf":"font/otf",".woff":"font/woff",".woff2":"font/woff2",".map":"application/json",".txt":"text/plain; charset=utf-8"};function he(a){let e;try{let s=L();e=JSON.stringify(s)}catch{e="{}"}let t=`<script>window.__sootsimSharedConfig=${e};</script>`,i=a.toString("utf8");return i.includes("</head>")?i.replace("</head>",t+"</head>"):i.includes("</body>")?i.replace("</body>",t+"</body>"):t+i}var R=class a{port;openUrlHandler;httpServer=null;wss=null;nextCommandId=1;nextSimNumber=161;sims=new Map;primarySimId=null;pendingCommands=new Map;cliBySentId=new Map;cliSimBySocket=new Map;cliLastCommandAt=new Map;cliIdentityKeyBySocket=new Map;cliLabelBySocket=new Map;restorableSims=new Map;nextCliFallbackId=1;cliIdleTimer=null;agentHost;static CLI_IDLE_TIMEOUT_MS=6e4;static CLI_LEASE_TTL_MS=6e5;static USER_ACTIVE_LEASE_TTL_MS=8e3;static USER_BOOT_LEASE_TTL_MS=6e4;static SIM_RECONNECT_TTL_MS=3e4;preferredPort;portFallbackCount;shouldWriteLockfile;effectivePort=0;startedAt=0;heartbeatTimer=null;wsHeartbeatTimer=null;wsIsAlive=new WeakMap;static WS_HEARTBEAT_INTERVAL_MS=3e4;runtimeUpdateTimer=null;runtimeUpdateInFlight=null;activeRuntimeVersion=null;activeRuntimeDirPath=null;scanCache=null;scanCacheAt=0;inflightScan=null;static SCAN_FRESH_MS=2e3;constructor(e={}){this.preferredPort=e.port||7668,this.port=this.preferredPort,this.shouldWriteLockfile=e.writeLockfile===!0,this.portFallbackCount=Math.max(1,e.portFallbackCount??10),this.openUrlHandler=e.openUrl,this.agentHost=new x({getExcludePorts:e.agentScanExcludes})}getAgentHost(){return this.agentHost}start(e){this.startAsync(e)}async startAsync(e){if(this.httpServer||this.wss)return this.effectivePort;this.refreshActiveRuntime();for(let t=0;t<this.portFallbackCount;t++){let i=this.preferredPort+t;try{return await this.bindOnce(i,e?.silent===!0),this.effectivePort=i,this.port=i,this.startedAt=Date.now(),t>0&&!e?.silent&&process.stderr.write(`ws bridge bound to port ${i} (preferred ${this.preferredPort} was taken)
|
|
5
|
-
`),this.afterBind(),i}catch(s){if(s?.code!=="EADDRINUSE")throw s;e?.silent||process.stderr.write(`ws bridge port ${i} already in use, trying ${i+1}
|
|
6
|
-
`)}}throw new Error(`could not bind ws bridge after ${this.portFallbackCount} attempts starting at ${this.preferredPort}`)}bindOnce(e,t){return new Promise((i,s)=>{let n=Ee((c,d)=>this.handleHttpRequest(c,d)),o=!1,r=c=>{if(!o){o=!0;try{n.close()}catch{}this.httpServer=null,this.wss=null,s(c)}};n.once("error",r),n.listen(e,"127.0.0.1",()=>{o||(o=!0,n.removeListener("error",r),n.on("error",c=>{process.stderr.write(`ws bridge http error: ${String(c)}
|
|
7
|
-
`)}),this.httpServer=n,this.wss=new Ie({server:n}),this.wireWebSocketServer(),i())})})}wireWebSocketServer(){this.wss&&this.wss.on("connection",(e,t)=>{let i=t.headers.origin,s=i?"sim":"cli",n=null;if(e.on("error",()=>{}),this.wsIsAlive.set(e,!0),e.on("pong",()=>{this.wsIsAlive.set(e,!0)}),this.agentHost.registerSocket(e),s==="sim")n={id:this.allocateSimId(),ws:e,origin:i,connectedAt:Date.now(),lastSeenAt:Date.now(),lastActiveAt:0,recentActions:[]},this.sims.set(n.id,n),this.shouldPromoteSim(n)&&(this.primarySimId=n.id),this.broadcastSimAssignments(),this.broadcastSimClientStates();else{let o=`ws-${this.nextCliFallbackId++}`;this.cliIdentityKeyBySocket.set(e,o)}e.on("message",o=>{let r;try{r=JSON.parse(o.toString())}catch{return}if(!(!r||typeof r!="object")){if(typeof r.type=="string"&&r.type.startsWith("agent:")){this.agentHost.handleMessage(e,r);return}if(r.type==="runtime:list"){let c=_(),d=this.getActiveRuntime(),l={type:"runtime:list:ok",id:r.id,installed:c,active:d.version,activeRuntimeDir:d.runtimeDir};try{e.send(JSON.stringify(l))}catch{}return}if(r.type==="runtime:use"){let c=typeof r.version=="string"?r.version:"";if(!_().includes(c)){try{e.send(JSON.stringify({type:"runtime:use:error",id:r.id,error:`runtime ${c||"(missing)"} is not installed`}))}catch{}return}let l=this.setActiveRuntime(c);try{e.send(JSON.stringify({type:"runtime:use:ok",id:r.id,version:l.version,runtimeDir:l.runtimeDir}))}catch{}return}if(r.type==="runtime:get"){let c=this.getActiveRuntime();try{e.send(JSON.stringify({type:"runtime:get:ok",id:r.id,active:c.version,activeRuntimeDir:c.runtimeDir}))}catch{}return}if(s==="sim"){if(n&&(n.lastSeenAt=Date.now()),r.type==="bridge:register"&&n){let l=r,u=this.tryRestoreSimId(n,l.simId);n.url=l.url,n.title=l.title,n.userAgent=l.userAgent,u&&(this.broadcastSimAssignments(),this.broadcastSimClientStates());return}if(r.type==="bridge:user-focus-state"&&n){let l=r;this.updateUserFocusLease(n,l.focused===!0);return}if(r.type==="bridge:user-interact"&&n){this.updateUserActivity(n);return}if(r.type==="bridge:write-shared-config"){let l=r.patch&&typeof r.patch=="object"?r.patch:null;if(!l)return;let u;try{u=U(l)}catch(h){process.stderr.write(`sootsim: bridge:write-shared-config failed: ${h instanceof Error?h.message:String(h)}
|
|
8
|
-
`);return}let p=JSON.stringify({type:"bridge:shared-config-changed",config:u});for(let h of this.sims.values())if(h.ws.readyState===m.OPEN)try{h.ws.send(p)}catch{}return}if(r.type==="bridge:open-path"){let l=typeof r.path=="string"?r.path:"",u=typeof r.line=="number"&&Number.isFinite(r.line)?r.line:void 0,p=typeof r.column=="number"&&Number.isFinite(r.column)?r.column:void 0;l&&this.openPathInEditor(l,u,p);return}if(r.type==="bridge:boot-clients"&&n){let l=[];for(let[p,h]of this.cliSimBySocket)h===n.id&&l.push(p);for(let p of l){this.cliSimBySocket.delete(p);try{p.close(1e3,"booted by sim")}catch{}}let u=!!n.cliLease;n.cliLease={kind:"user-active",cliIdentityKey:"__user-active__",cliLabel:"active user",expiresAt:Date.now()+a.USER_BOOT_LEASE_TTL_MS},process.stderr.write(`sootsim booted ${l.length} cli client(s)${u?" (overrode prior lease)":""}; held sim for user [${n.id}]
|
|
9
|
-
`),this.recordSimAction(n.id,"sim booted cli clients"),this.broadcastSimClientStates();return}let c=this.pendingCommands.get(r.id);if(c){this.pendingCommands.delete(r.id),r.error?c.reject(new Error(r.error)):c.resolve(r.result);return}let d=this.cliBySentId.get(r.id);if(d&&(this.cliBySentId.delete(r.id),d.ws.readyState===m.OPEN)){let l=this.getOtherCliIdentityCount(d.ws,d.simId),u=l>0?{...r,id:d.originalId,i:l}:{...r,id:d.originalId};d.ws.send(JSON.stringify(u))}return}(async()=>{this.cliLastCommandAt.set(e,Date.now());try{if(r.type==="bridge:bye"){let p=this.cliSimBySocket.delete(e);this.cliLastCommandAt.delete(e),this.cliIdentityKeyBySocket.delete(e),this.cliLabelBySocket.delete(e);for(let[h,g]of this.cliBySentId)g.ws===e&&this.cliBySentId.delete(h);p&&this.broadcastSimClientStates();return}if(r.type==="bridge:hello"){let p=typeof r.cliIdentityKey=="string"&&r.cliIdentityKey.trim()?r.cliIdentityKey.trim():this.cliIdentityKeyBySocket.get(e)||`ws-${this.nextCliFallbackId++}`;this.cliIdentityKeyBySocket.set(e,p),typeof r.cliLabel=="string"&&r.cliLabel.trim()&&this.cliLabelBySocket.set(e,r.cliLabel.trim()),e.readyState===m.OPEN&&e.send(JSON.stringify({id:r.id,result:{cliIdentityKey:p,leaseTtlMs:a.CLI_LEASE_TTL_MS,leasing:!0}}));return}if(r.type==="bridge:list-sims"){e.readyState===m.OPEN&&e.send(JSON.stringify({id:r.id,result:this.listSims()}));return}if(r.type==="bridge:open"){if(typeof r.url!="string"||!r.url)throw new Error("bridge:open requires a url");await this.openUrl(r.url,{newWindow:r.newWindow===!0}),e.readyState===m.OPEN&&e.send(JSON.stringify({id:r.id,result:{ok:!0,url:r.url}}));return}if(r.type==="bridge:claim"){let p=await this.waitForSim(r.simId),h=this.tryAcquireLease(e,p,{force:r.force===!0});if(!h.granted){e.readyState===m.OPEN&&e.send(JSON.stringify({id:r.id,error:`sim ${p.id} is locked by another cli`,o:h.lock}));return}this.setCliSimTarget(e,p.id),this.recordSimAction(p.id,h.bootedCount>0?`cli force-claimed sim (booted ${h.bootedCount})`:"cli claimed sim"),e.readyState===m.OPEN&&e.send(JSON.stringify({id:r.id,result:{simId:p.id,lockedBy:h.lease.cliIdentityKey,lockExpiresAt:h.lease.expiresAt,bootedCount:h.bootedCount}}));return}let c=await this.waitForSim(r.simId);if(xe(r)){let p=this.tryAcquireLease(e,c);if(!p.granted){e.readyState===m.OPEN&&e.send(JSON.stringify({id:r.id,error:`sim ${c.id} is locked by another cli \u2014 use \`sootsim claim ${c.id} --force\` or \`sootsim open --new\``,o:p.lock}));return}}else this.ensureCliIdentityKey(e);this.setCliSimTarget(e,c.id),this.recordSimAction(c.id,this.describeForwardedCommand(r));let d=this.nextCommandId++;this.cliBySentId.set(d,{simId:c.id,ws:e,originalId:r.id});let{simId:l,...u}=r;c.ws.send(JSON.stringify({...u,id:d}))}catch(c){e.readyState===m.OPEN&&e.send(JSON.stringify({id:r.id,error:c instanceof Error?c.message:String(c)}))}})()}}),e.on("close",()=>{if(this.agentHost.unregisterSocket(e),s==="sim"&&n){this.rememberDisconnectedSim(n),this.primarySimId===n.id&&(this.primarySimId=this.getOpenSim()?.id??null);for(let[o,r]of this.pendingCommands)r.simId===n.id&&(r.reject(new Error("sim disconnected")),this.pendingCommands.delete(o));for(let[o,r]of this.cliBySentId)r.simId===n.id&&(r.ws.readyState===m.OPEN&&r.ws.send(JSON.stringify({id:r.originalId,error:"sim disconnected before responding"})),this.cliBySentId.delete(o));this.broadcastSimAssignments(),this.broadcastSimClientStates()}else if(s==="cli"){let o=this.cliSimBySocket.delete(e);this.cliLastCommandAt.delete(e),this.cliIdentityKeyBySocket.delete(e),this.cliLabelBySocket.delete(e);for(let[r,c]of this.cliBySentId)c.ws===e&&this.cliBySentId.delete(r);o&&this.broadcastSimClientStates()}})})}afterBind(){if(process.stderr.write(`ws bridge listening on port ${this.port}
|
|
10
|
-
`),this.cliIdleTimer=setInterval(()=>this.sweepIdleCliClients(),3e4),this.cliIdleTimer.unref(),this.wsHeartbeatTimer=setInterval(()=>this.sweepDeadWebSockets(),a.WS_HEARTBEAT_INTERVAL_MS),this.wsHeartbeatTimer.unref(),this.shouldWriteLockfile){try{if(T(),!K(this.buildLockfileSnapshot()))throw new Error("another sootsim daemon wrote the lockfile during startup \u2014 aborting")}catch(e){throw process.stderr.write(`ws bridge failed to claim daemon lockfile: ${String(e)}
|
|
11
|
-
`),e}this.heartbeatTimer=setInterval(()=>{try{this.writeLockfileSnapshot()}catch{}},Re),this.heartbeatTimer.unref(),this.startRuntimeUpdater()}this.agentHost.seedOnBoot()}bootstrapping=!0;buildLockfileSnapshot(){return{schema:1,pid:process.pid,platform:process.platform,bridgePort:this.effectivePort,runtimePort:this.effectivePort,activeRuntime:this.activeRuntimeVersion,activeRuntimeDir:this.activeRuntimeDirPath,startedAt:this.startedAt,heartbeatAt:Date.now(),bootstrapping:this.bootstrapping}}writeLockfileSnapshot(){J(this.buildLockfileSnapshot())}refreshActiveRuntime(){this.activeRuntimeVersion=M(),this.activeRuntimeDirPath=F()}runServerScan(){if(this.inflightScan)return this.inflightScan;let e=this.effectivePort>0?[this.effectivePort]:[];return this.inflightScan=E({excludePorts:e,buildIconProxyUrl:t=>`/__bundle-proxy?url=${encodeURIComponent(t)}`}).then(t=>(this.scanCache=t,this.scanCacheAt=Date.now(),t)).catch(t=>{let i=t instanceof Error?t.message:String(t);return console.error("[sootsim] /__server-scan failed:",i),this.scanCache??[]}).finally(()=>{this.inflightScan=null}),this.inflightScan}handleServerScan(e){let t=s=>{e.writeHead(200,{"Content-Type":"application/json; charset=utf-8","Cache-Control":"no-store"}),e.end(JSON.stringify(s))},i=Date.now()-this.scanCacheAt;if(this.scanCache&&i<a.SCAN_FRESH_MS){t(this.scanCache);return}if(this.scanCache){t(this.scanCache),this.runServerScan().catch(()=>{});return}this.runServerScan().then(s=>t(s))}resolveRuntimeUpdateIntervalMs(){let e=Number(process.env[Oe]);return Number.isFinite(e)&&e>0?Math.max(100,Math.round(e)):Be}startRuntimeUpdater(){if(!this.shouldWriteLockfile||this.runtimeUpdateTimer)return;this.runRuntimeUpdate("startup");let e=this.resolveRuntimeUpdateIntervalMs();this.runtimeUpdateTimer=setInterval(()=>{this.runRuntimeUpdate("periodic")},e),this.runtimeUpdateTimer.unref()}runRuntimeUpdate(e){return this.runtimeUpdateInFlight?this.runtimeUpdateInFlight:(this.runtimeUpdateInFlight=(async()=>{try{e==="startup"&&process.stderr.write(`sootsim: checking for runtime updates\u2026
|
|
12
|
-
`);let t=await z();if(!t.updated||!t.latestVersion){e==="startup"&&process.stderr.write(`sootsim: runtime ${this.activeRuntimeVersion??"(none)"} is current
|
|
13
|
-
`);return}let i=this.setActiveRuntime(t.latestVersion);process.stderr.write(`sootsim runtime updated to ${i.version} (${e})
|
|
14
|
-
`)}catch(t){process.stderr.write(`sootsim runtime update failed (${e}): ${t instanceof Error?t.message:String(t)}
|
|
15
|
-
`)}finally{if(this.runtimeUpdateInFlight=null,e==="startup"&&this.bootstrapping){if(this.bootstrapping=!1,this.shouldWriteLockfile&&this.httpServer)try{this.writeLockfileSnapshot()}catch{}process.stderr.write(`sootsim: ready
|
|
16
|
-
`)}}})(),this.runtimeUpdateInFlight)}setActiveRuntime(e){if(W(e),this.refreshActiveRuntime(),this.shouldWriteLockfile&&this.httpServer)try{this.writeLockfileSnapshot()}catch{}let t=JSON.stringify({type:"runtime:changed",version:e,runtimeDir:this.activeRuntimeDirPath});for(let i of this.sims.values())if(i.ws.readyState===m.OPEN)try{i.ws.send(t)}catch{}return{version:e,runtimeDir:this.activeRuntimeDirPath}}getActiveRuntime(){return{version:this.activeRuntimeVersion,runtimeDir:this.activeRuntimeDirPath}}removeLockfile(){if(this.shouldWriteLockfile)try{N()}catch{}}handleHttpRequest(e,t){if(t.setHeader("Cross-Origin-Opener-Policy","same-origin"),t.setHeader("Cross-Origin-Embedder-Policy","credentialless"),t.setHeader("Cross-Origin-Resource-Policy","cross-origin"),t.setHeader("Document-Policy","js-profiling"),de(e.url)){ue(e,t);return}if(le(e.url)&&pe(e,t))return;let i=(e.method||"GET").toUpperCase();if(i!=="GET"&&i!=="HEAD"){t.writeHead(405,{Allow:"GET, HEAD"}),t.end("method not allowed");return}let s=new URL(e.url||"/","http://localhost");if(s.pathname==="/__bundle-proxy"){let d=s.searchParams.get("url");if(!d){t.writeHead(400,{"Content-Type":"text/plain"}),t.end("bundle-proxy: missing url query param");return}let l;try{l=new URL(d)}catch{t.writeHead(400,{"Content-Type":"text/plain"}),t.end("bundle-proxy: invalid url");return}let u=l.hostname;if(!(u==="localhost"||u==="127.0.0.1"||u==="::1"||u.endsWith(".localhost"))){t.writeHead(403,{"Content-Type":"text/plain"}),t.end("bundle-proxy: only loopback targets allowed");return}(async()=>{try{let h=await fetch(l.toString(),{redirect:"follow"}),g={},f=h.headers.get("content-type");if(f&&(g["Content-Type"]=f),g["Cache-Control"]="no-store",t.writeHead(h.status,g),!h.body){t.end();return}let b=h.body.getReader();for(;;){let{done:C,value:y}=await b.read();if(C)break;t.write(Buffer.from(y))}t.end()}catch(h){t.writeHead(502,{"Content-Type":"text/plain"}),t.end(`bundle-proxy: upstream fetch failed: ${h instanceof Error?h.message:String(h)}`)}})();return}if(s.pathname==="/__server-scan"){this.handleServerScan(t);return}if(s.pathname==="/healthz"){t.writeHead(200,{"Content-Type":"application/json","Cache-Control":"no-store"}),t.end(JSON.stringify({ok:!0,pid:process.pid,platform:process.platform,bridgePort:this.effectivePort,runtimePort:this.effectivePort,activeRuntime:this.activeRuntimeVersion,startedAt:this.startedAt,uptimeMs:this.startedAt>0?Date.now()-this.startedAt:0}));return}if(s.pathname==="/__sootsim/shared-config"){if(t.setHeader("Access-Control-Allow-Origin","*"),t.setHeader("Cache-Control","no-store"),i==="GET"||i==="HEAD"){let d="{}";try{d=JSON.stringify(L())}catch{}t.writeHead(200,{"Content-Type":"application/json"}),i==="HEAD"?t.end():t.end(d);return}t.writeHead(405,{Allow:"GET, HEAD"}),t.end("method not allowed (use the bridge over WS for writes)");return}this.refreshActiveRuntime();let n=this.activeRuntimeDirPath;if(!n){t.writeHead(503,{"Content-Type":"text/plain; charset=utf-8"}),t.end("sootsim: no active runtime installed. run `sootsim runtime install` to fetch one.");return}let o=s.pathname;if(o==="/runtime"||o==="/runtime/"?o="/":o.startsWith("/runtime/")&&(o=o.slice(8)),(o===""||o==="/")&&(o="/index.html"),o.includes("\0")){t.writeHead(400),t.end("bad request");return}if(process.platform!=="win32"&&o.includes("\\")){t.writeHead(400),t.end("bad request");return}for(let d of o.split("/"))if(d===".."){t.writeHead(403),t.end("forbidden");return}let r=S.resolve(n,"."+o),c=n.endsWith(S.sep)?n:n+S.sep;if(!r.startsWith(c)&&r!==n){t.writeHead(403),t.end("forbidden");return}v.realpath(r,(d,l)=>{let u=d?r:l,p=u.endsWith(S.sep)?u:u+S.sep;if(!d){let h=(()=>{try{let g=v.realpathSync(n);return g.endsWith(S.sep)?g:g+S.sep}catch{return c}})();if(!p.startsWith(h)&&u+S.sep!==h){t.writeHead(403),t.end("forbidden");return}}v.stat(u,(h,g)=>{if(h||!g?.isFile()){let y=S.extname(o).toLowerCase();if(y&&y!==".html"){t.writeHead(404),t.end("not found");return}if(o.startsWith("/__")||o.startsWith("/api/")||o==="/api"){t.writeHead(404,{"Content-Type":"text/plain; charset=utf-8"}),t.end("not found");return}let O=S.join(n,"index.html");v.readFile(O,(me,fe)=>{if(me){t.writeHead(404),t.end("not found");return}if(t.writeHead(200,{"Content-Type":"text/html; charset=utf-8","Cache-Control":"no-store"}),i==="HEAD"){t.end();return}t.end(he(fe))});return}let f=S.extname(u).toLowerCase(),b=Le[f]||"application/octet-stream";if(t.writeHead(200,{"Content-Type":b,"Cache-Control":"no-store"}),i==="HEAD"){t.end();return}if(f===".html"){v.readFile(u,(y,O)=>{if(y){try{t.end()}catch{}return}t.end(he(O))});return}let C=v.createReadStream(u);C.pipe(t),C.on("error",()=>{try{t.end()}catch{}})})})}sweepIdleCliClients(){let e=Date.now(),t=!1;for(let[i,s]of this.cliSimBySocket){let n=this.cliLastCommandAt.get(i)??0;if(!(e-n<a.CLI_IDLE_TIMEOUT_MS)){this.cliSimBySocket.delete(i),this.cliLastCommandAt.delete(i);for(let[o,r]of this.cliBySentId)r.ws===i&&this.cliBySentId.delete(o);try{i.close(1e3,"idle timeout")}catch{}t=!0}}t&&this.broadcastSimClientStates(),this.sweepRestorableSims(e)}sweepDeadWebSockets(){if(this.wss)for(let e of this.wss.clients){if(e.readyState!==m.OPEN)continue;if(this.wsIsAlive.get(e)===!1){try{e.terminate()}catch{}continue}this.wsIsAlive.set(e,!1);try{e.ping()}catch{try{e.terminate()}catch{}}}}listSims(){return Array.from(this.sims.values()).sort((e,t)=>e.id===this.primarySimId?-1:t.id===this.primarySimId?1:e.connectedAt-t.connectedAt).map(e=>this.describeSim(e))}async sendCommand(e){let t=await this.waitForSim(e.simId),i=this.nextCommandId++;return new Promise((s,n)=>{let o=setTimeout(()=>{this.pendingCommands.delete(i),this.broadcastSimClientStates(),n(new Error("command timed out after 30s"))},3e4);this.pendingCommands.set(i,{simId:t.id,resolve:d=>{clearTimeout(o),this.pendingCommands.delete(i),this.broadcastSimClientStates(),s(d)},reject:d=>{clearTimeout(o),this.pendingCommands.delete(i),this.broadcastSimClientStates(),n(d)}}),this.broadcastSimClientStates();let{simId:r,...c}=e;t.ws.send(JSON.stringify({...c,id:i}))})}async evaluate(e,t){return this.sendCommand({type:"evaluate",code:e,simId:t})}async focusSim(e){return this.sendCommand({type:"focus",simId:e})}async closeSim(e){return this.sendCommand({type:"close",simId:e})}async openPathInEditor(e,t,i){let s=t!=null?`:${t}${i!=null?`:${i}`:""}`:"",n=`${e}${s}`,o=(c,d)=>new Promise(l=>{try{let u=Te(c,d,{detached:!0,stdio:"ignore"}),p=!1;u.on("error",()=>{p||(p=!0,l(!1))}),u.on("spawn",()=>{p||(p=!0,u.unref(),l(!0))})}catch{l(!1)}}),r=process.env.REACT_EDITOR||process.env.EDITOR;if(r){let c=r.split(" ").filter(Boolean);if(c.length&&await o(c[0],[...c.slice(1),"-g",n]))return}await o("cursor",["-g",n])||await o("code",["-g",n])||await this.openUrl(e)}async openUrl(e,t={}){if(this.openUrlHandler){await this.openUrlHandler(e,t);return}await q(e,t)}async close(){if(this.cliIdleTimer&&(clearInterval(this.cliIdleTimer),this.cliIdleTimer=null),this.heartbeatTimer&&(clearInterval(this.heartbeatTimer),this.heartbeatTimer=null),this.wsHeartbeatTimer&&(clearInterval(this.wsHeartbeatTimer),this.wsHeartbeatTimer=null),this.runtimeUpdateTimer&&(clearInterval(this.runtimeUpdateTimer),this.runtimeUpdateTimer=null),this.shouldWriteLockfile)try{N()}catch{}this.effectivePort=0,this.startedAt=0,this.agentHost.close();for(let[i,s]of this.pendingCommands)s.reject(new Error("server closing")),this.pendingCommands.delete(i);for(let i of this.sims.values())i.ws.close();this.sims.clear(),this.primarySimId=null;let e=this.wss,t=this.httpServer;if(this.wss=null,this.httpServer=null,e)try{e.close()}catch{}if(t)try{t.close()}catch{}}describeSim(e){let t;try{t=e.ws.readyState}catch{t=m.CLOSED}let i=this.getActiveLease(e);return{id:e.id,origin:e.origin,url:e.url,title:e.title,userAgent:e.userAgent,connectedAt:e.connectedAt,lastSeenAt:e.lastSeenAt,lastActiveAt:e.lastActiveAt||void 0,isPrimary:e.id===this.primarySimId,readyState:t===m.OPEN?"open":t===m.CLOSING?"closing":"closed",attachedCliCount:this.getAttachedCliCount(e.id),lockedBy:i?i.cliLabel||i.cliIdentityKey:void 0,lockedByKind:i?i.kind:void 0,lockExpiresAt:i?i.expiresAt:void 0,userFocused:e.userFocused||void 0}}getActiveLease(e){let t=e.cliLease;return t?Date.now()>=t.expiresAt?(e.cliLease=void 0,null):t:null}tryAcquireLease(e,t,i={}){let s=this.cliIdentityKeyBySocket.get(e)??(()=>{let u=`ws-${this.nextCliFallbackId++}`;return this.cliIdentityKeyBySocket.set(e,u),u})(),n=this.cliLabelBySocket.get(e),o=Date.now(),r=this.getActiveLease(t),c=r&&r.cliIdentityKey===s,d=0;if(r&&!c&&!i.force)return{granted:!1,lease:r,lock:{by:r.cliLabel||r.cliIdentityKey,expiresInMs:Math.max(0,r.expiresAt-o)},bootedCount:0};if(r&&!c&&i.force)for(let[u,p]of this.cliSimBySocket){if(p!==t.id)continue;let h=this.cliIdentityKeyBySocket.get(u);if(h&&h!==s){this.cliSimBySocket.delete(u);try{u.close(1e3,"lease claimed by another cli")}catch{}d++}}let l={kind:"cli",cliIdentityKey:s,cliLabel:n,expiresAt:o+a.CLI_LEASE_TTL_MS};return t.cliLease=l,{granted:!0,lease:l,bootedCount:d}}updateUserFocusLease(e,t){let i=t;e.userFocused!==i&&(e.userFocused=i,this.broadcastSimClientStates())}updateUserActivity(e){let t=this.getActiveLease(e);if(t&&t.kind==="cli")return;let s=Date.now()+a.USER_ACTIVE_LEASE_TTL_MS,n=t&&t.kind==="user-active"?Math.max(t.expiresAt,s):s;e.cliLease={kind:"user-active",cliIdentityKey:"__user-active__",cliLabel:"active user",expiresAt:n},this.broadcastSimClientStates()}ensureCliIdentityKey(e){let t=this.cliIdentityKeyBySocket.get(e);if(t)return t;let i=`ws-${this.nextCliFallbackId++}`;return this.cliIdentityKeyBySocket.set(e,i),i}getOpenSim(e){if(e){let i=this.sims.get(e);return i?.ws.readyState===m.OPEN?i:null}let t=this.primarySimId!=null?this.sims.get(this.primarySimId):null;if(t?.ws.readyState===m.OPEN)return t;for(let i of this.sims.values())if(i.ws.readyState===m.OPEN)return i;return null}async waitForSim(e,t={}){let i=t.attempts??10,s=t.intervalMs??200;for(let n=0;n<i;n++){let o=this.getOpenSim(e);if(o)return o;await new Promise(r=>setTimeout(r,s))}throw new Error(e?`no sim connected with id ${e}`:"no sim connected")}shouldPromoteSim(e){let t=this.primarySimId?this.sims.get(this.primarySimId):null,i=e.origin?.includes(":5173"),s=t?.origin?.includes(":5173");return!t||t.ws.readyState!==m.OPEN||!!i||!s}broadcastSimAssignments(){for(let e of this.sims.values())e.ws.readyState===m.OPEN&&e.ws.send(JSON.stringify({type:"bridge:welcome",simId:e.id,isPrimary:e.id===this.primarySimId}))}broadcastSimClientStates(){for(let e of this.sims.values()){if(e.ws.readyState!==m.OPEN)continue;let t=this.getActiveLease(e),i={type:"bridge:client-state",attachedCliCount:this.getAttachedCliCount(e.id),activeAgentCommandCount:this.getActiveAgentCommandCount(e.id),recentActions:e.recentActions,lockedBy:t?t.cliLabel||t.cliIdentityKey:void 0,lockedByKind:t?t.kind:void 0,lockExpiresAt:t?t.expiresAt:void 0,userFocused:e.userFocused||void 0};e.ws.send(JSON.stringify(i))}}setCliSimTarget(e,t){let i=this.cliSimBySocket.get(e);i!==t&&(this.cliSimBySocket.set(e,t),this.recordSimAction(t,i?"cli switched sims":"cli connected",!1),this.broadcastSimClientStates())}recordSimAction(e,t,i=!0){let s=t?.trim();if(!s)return;let n=this.sims.get(e);if(!n)return;let o=Date.now();n.lastActiveAt=o,n.recentActions=[{label:s,at:o},...n.recentActions.filter(r=>r.label!==s)].slice(0,4),i&&this.broadcastSimClientStates()}describeForwardedCommand(e){switch(e?.type){case"evaluate":return"evaluated page state";case"screenshot":return"captured screenshot";case"tap":return"sent tap event";case"keyboard":return e?.action==="type"?"typed text":"used keyboard";case"tree":return"dumped tree";case"focus":return"focused sim";case"close":return"requested close";default:return typeof e?.type=="string"?e.type:null}}getAttachedCliCount(e){let t=new Set;for(let[i,s]of this.cliSimBySocket){if(s!==e||i.readyState!==m.OPEN)continue;let n=this.cliIdentityKeyBySocket.get(i);t.add(n??`ws-unknown-${t.size}`)}return t.size}getOtherCliIdentityCount(e,t){let i=this.cliIdentityKeyBySocket.get(e),s=new Set;for(let[n,o]of this.cliSimBySocket){if(o!==t||n.readyState!==m.OPEN)continue;let r=this.cliIdentityKeyBySocket.get(n);r&&r===i||s.add(r??`ws-unknown-${s.size}`)}return s.size}getActiveAgentCommandCount(e){let t=0;for(let i of this.pendingCommands.values())i.simId===e&&t++;return t}allocateSimId(){for(;;){let e=this.nextSimNumber.toString(16);if(this.nextSimNumber++,!this.sims.has(e)&&!this.restorableSims.has(e))return e}}tryRestoreSimId(e,t){let i=t?.trim();if(!i||i===e.id)return!1;let s=this.sims.get(i);if(s&&s!==e&&s.ws.readyState===m.OPEN)return!1;let n=this.getRestorableSimState(i),o=e.id;this.sims.delete(o),e.id=i,n&&(e.recentActions=n.recentActions.map(r=>({...r})),e.lastActiveAt=n.lastActiveAt,e.cliLease=n.cliLease?{...n.cliLease}:void 0,this.restorableSims.delete(i)),this.sims.set(e.id,e),this.primarySimId===o&&(this.primarySimId=e.id);for(let[r,c]of this.cliSimBySocket)c===o&&this.cliSimBySocket.set(r,e.id);return!0}rememberDisconnectedSim(e){let t=this.getActiveLease(e);this.restorableSims.set(e.id,{recentActions:e.recentActions.map(i=>({...i})),lastActiveAt:e.lastActiveAt,cliLease:t&&t.kind==="cli"?{...t}:void 0,expiresAt:Date.now()+a.SIM_RECONNECT_TTL_MS}),this.sims.delete(e.id)}getRestorableSimState(e){let t=this.restorableSims.get(e);return t?t.expiresAt<=Date.now()?(this.restorableSims.delete(e),null):(t.cliLease&&t.cliLease.expiresAt<=Date.now()&&(t.cliLease=void 0),t):null}sweepRestorableSims(e=Date.now()){for(let[t,i]of this.restorableSims)if(!(i.expiresAt>e)){this.restorableSims.delete(t);for(let[s,n]of this.cliSimBySocket)n===t&&this.cliSimBySocket.delete(s)}}resetServerState(){this.cliIdleTimer&&(clearInterval(this.cliIdleTimer),this.cliIdleTimer=null),this.wsHeartbeatTimer&&(clearInterval(this.wsHeartbeatTimer),this.wsHeartbeatTimer=null),this.runtimeUpdateTimer&&(clearInterval(this.runtimeUpdateTimer),this.runtimeUpdateTimer=null);let e=this.wss,t=this.httpServer;if(this.wss=null,this.httpServer=null,e)try{e.close()}catch{}if(t)try{t.close()}catch{}}};function _e(){let a=process.env.XPC_SERVICE_NAME||"";return!!(a.includes("dev.sootsim.daemon")||a.includes("dev.sootsim.server")||process.env.INVOCATION_ID)}async function at(a,e={}){(a.includes("--help")||a.includes("-h"))&&(console.log(`
|
|
17
|
-
sootsim server \u2014 run the sootsim bridge daemon in the foreground
|
|
18
|
-
|
|
19
|
-
hosts the WS bridge that CLI commands talk to. once running, any sootsim
|
|
20
|
-
renderer (browser, electron, headless playwright) that connects to port 7668
|
|
21
|
-
becomes drivable from 'sootsim describe', 'sootsim tap', etc.
|
|
22
|
-
|
|
23
|
-
usage:
|
|
24
|
-
sootsim server [options]
|
|
25
|
-
|
|
26
|
-
options:
|
|
27
|
-
--port <n> bridge port (defaults to ${7668})
|
|
28
|
-
--quiet suppress per-connection logging
|
|
29
|
-
|
|
30
|
-
examples:
|
|
31
|
-
sootsim server
|
|
32
|
-
sootsim server --port 7668 --quiet
|
|
33
|
-
`),process.exit(0));let t=a.indexOf("--port"),i=t>=0&&a[t+1]?Number(a[t+1]):e.port??7668;Number.isNaN(i)&&(console.error(` invalid --port value: ${a[t+1]}`),process.exit(1));let s=a.includes("--quiet")||a.includes("-q"),n=j();n&&$(n)&&(console.error(` a sootsim daemon is already running (pid ${n.pid}, port ${n.bridgePort})`),console.error(" stop it with 'sootsim daemon stop' first"),process.exit(1)),T();let o=new R({port:i,writeLockfile:!0}),r=await o.startAsync({silent:s}),c=Date.now(),d=h=>{s||process.stdout.write(`${h}
|
|
34
|
-
`)},l=new Set,u=setInterval(()=>{let h=o.listSims(),g=new Set(h.map(f=>f.id));for(let f of h)if(!l.has(f.id)){let b=f.title||f.url||f.origin||"(unknown)";d(` + ${f.id} ${b}`)}for(let f of l)g.has(f)||d(` - ${f}`);l.clear();for(let f of g)l.add(f)},500);V({event:"daemon_heartbeat",properties:{bridge_port:r,under_daemon:_e(),platform:process.platform,subsource:"daemon"}}),G(),d(`sootsim bridge listening on ws://localhost:${r} (runtime http on same port)`),r!==i&&d(` (preferred port ${i} was taken \u2014 fell back to ${r})`),d(" ready for browser, electron, or headless playwright sims to connect"),d(" (ctrl-c to stop)");let p=async h=>{clearInterval(u),d(`
|
|
35
|
-
${h} received \u2014 shutting down after ${Math.round((Date.now()-c)/1e3)}s`);try{await o.close()}catch{}process.exit(0)};process.on("SIGINT",()=>p("SIGINT")),process.on("SIGTERM",()=>p("SIGTERM")),process.on("SIGHUP",()=>p("SIGHUP")),process.on("exit",()=>{try{o.removeLockfile()}catch{}}),await new Promise(()=>{})}export{at as runServer};
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
/*! sootsim v0.1.39 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
|
-
import{a}from"./chunk-DSDLGFWH.js";import"./chunk-OB3TB4AN.js";import"./chunk-E5RYQUFB.js";import"./chunk-VLUFTHBB.js";import"./chunk-UWRBEBML.js";import"./chunk-HWRR23AJ.js";import"./chunk-RLGCJT2D.js";import"./chunk-B3OEHV2C.js";import"./chunk-ECDPQ6S7.js";import"./chunk-WD54RD4K.js";export{a as runSetupRepo};
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
/*! sootsim v0.1.39 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
|
-
import{d as _}from"./chunk-C6GUAXKO.js";import"./chunk-HWRR23AJ.js";import"./chunk-RLGCJT2D.js";import"./chunk-B3OEHV2C.js";import{E as b,F as v,i as D,y as O,z as $}from"./chunk-ECDPQ6S7.js";import"./chunk-WD54RD4K.js";import{spawn as N}from"child_process";import{existsSync as F}from"fs";import{WebSocket as B}from"ws";var k=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"];var A={reset:"\x1B[0m",dim:"\x1B[2m",red:"\x1B[31m",green:"\x1B[32m",yellow:"\x1B[33m",cyan:"\x1B[36m",bold:"\x1B[1m"};function T(){return process.stderr.isTTY===!0}function l(t,e){return T()?`${A[t]}${e}${A.reset}`:e}function L(t,e){switch(t){case"pending":return l("dim","\xB7");case"running":return l("cyan",e);case"done":return l("green","\u2713");case"fail":return l("red","\u2717");case"skip":return l("yellow","\u25CB")}}var E=class{constructor(e,s){this.stepper=e;this.data=s}start(e){this.data.state="running",e!==void 0&&(this.data.detail=e),this.stepper.render()}update(e){this.data.detail=e,this.stepper.render()}done(e){this.data.state="done",e!==void 0&&(this.data.detail=e),this.stepper.render()}fail(e){this.data.state="fail",e!==void 0&&(this.data.detail=e),this.stepper.render()}skip(e){this.data.state="skip",e!==void 0&&(this.data.detail=e),this.stepper.render()}},S=class{steps=[];bannerText="";frame=0;timer=null;lastLineCount=0;paused=!1;finished=!1;banner(e){this.bannerText=e}add(e){let s={label:e,state:"pending"};return this.steps.push(s),new E(this,s)}render(){this.paused||this.finished||(this.startSpinner(),this.draw())}pause(){this.paused||(this.paused=!0,this.stopSpinner(),this.eraseRendered(),this.lastLineCount=0)}resume(){this.paused&&(this.paused=!1,this.draw(),this.startSpinner())}finish(){this.finished||(this.finished=!0,this.stopSpinner(),this.draw())}startSpinner(){this.timer||!T()||this.steps.some(e=>e.state==="running")&&(this.timer=setInterval(()=>{this.frame=(this.frame+1)%k.length,this.draw()},80),this.timer?.unref?.())}stopSpinner(){this.timer&&(clearInterval(this.timer),this.timer=null)}draw(){if(!T()){this.drawForwardOnly();return}this.eraseRendered();let e=[];this.bannerText&&(e.push(l("bold",this.bannerText)),e.push(""));let s=k[this.frame],i=Math.max(...this.steps.map(r=>r.label.length),0);for(let r of this.steps){let n=L(r.state,s),u=r.label.padEnd(i),y=r.detail?` ${l("dim",r.detail)}`:"";e.push(` ${n} ${u}${y}`)}process.stderr.write(e.join(`
|
|
3
|
-
`)+`
|
|
4
|
-
`),this.lastLineCount=e.length,this.steps.some(r=>r.state==="running")||this.stopSpinner()}bannerPrinted=!1;lastEmitted=new Map;drawForwardOnly(){this.bannerText&&!this.bannerPrinted&&(process.stderr.write(this.bannerText+`
|
|
5
|
-
|
|
6
|
-
`),this.bannerPrinted=!0);for(let e of this.steps){let s=`${e.state}:${e.detail||""}`;if(this.lastEmitted.get(e.label)===s)continue;if(e.state==="pending"){this.lastEmitted.set(e.label,s);continue}let r=L(e.state,k[0]),n=e.detail?` ${e.detail}`:"";process.stderr.write(` ${r} ${e.label}${n}
|
|
7
|
-
`),this.lastEmitted.set(e.label,s)}}eraseRendered(){this.lastLineCount!==0&&(process.stderr.write(`\x1B[${this.lastLineCount}A\x1B[0J`),this.lastLineCount=0)}};var U=3e4,I=1e4;async function Z(t,e={}){if(t.includes("--help")||t.includes("-h")){console.log(`
|
|
8
|
-
sootsim start \u2014 install + run sootsim, open it in your browser
|
|
9
|
-
|
|
10
|
-
bare \`sootsim\` (or \`npx sootsim\`) defaults to this command. it makes sure
|
|
11
|
-
the engine runtime is on disk, ensures the bridge daemon is up (or falls
|
|
12
|
-
back to a detached server), then opens the iOS shell in your browser.
|
|
13
|
-
|
|
14
|
-
usage:
|
|
15
|
-
sootsim start [options]
|
|
16
|
-
sootsim # same thing
|
|
17
|
-
|
|
18
|
-
options:
|
|
19
|
-
--port <n> bridge port (default: ${7668})
|
|
20
|
-
--no-open don't open the browser at the end
|
|
21
|
-
`);return}O();let s=t.indexOf("--port"),i=s>=0&&t[s+1]?Number(t[s+1]):e.port??7668;Number.isNaN(i)&&(console.error(` invalid --port value: ${t[s+1]}`),process.exit(1));let r=t.includes("--no-open"),n=new S,{IS_BETA:u,BETA_TAGLINE:y}=await import("./beta-3SCMB3IN.js");n.banner(u?`sootsim \u2014 ${y}`:"sootsim \u2014 starting up");let c=n.add("runtime"),d=n.add("server"),x=n.add("ready"),f=n.add("open");n.render();let g=null;try{c.start("checking\u2026");let a=$();if(a&&F(D(a)))g=a,c.done(`v${a}`);else{c.start("downloading engine (~6 MB)\u2026");let{runRuntime:h}=await import("./runtime-YJPWA3XA.js");n.pause(),await h(["install"],{}),n.resume(),g=$(),c.done(g?`v${g}`:"installed")}}catch(a){c.fail(m(a)),n.finish(),process.exit(1)}let o=i,p="standalone";try{d.start("checking\u2026");let a=b();if(v(a)&&await P(a.bridgePort,800))o=a.bridgePort,p="daemon-existing",d.done(`already running (port ${o})`);else if(process.platform==="darwin"||process.platform==="linux"){d.start("registering background daemon\u2026");try{let{daemonInstall:h}=await import("./daemon-LIVCJZR3.js");n.pause(),await h({port:i,force:!0}),n.resume();let R=b();o=v(R)?R.bridgePort:i,p="daemon-installed",d.done(`daemon registered (port ${o})`)}catch(h){n.resume(),d.start("daemon unavailable, starting standalone server\u2026"),o=await C(i),p="standalone",d.done(`standalone (port ${o}) \u2014 ${m(h)}`)}}else d.start("starting standalone server\u2026"),o=await C(i),p="standalone",d.done(`standalone (port ${o})`)}catch(a){d.fail(m(a)),n.finish(),process.exit(1)}try{if(x.start("waiting for bridge\u2026"),!await V(o,U))throw new Error(`bridge never came online on port ${o}`);x.done(`ws://localhost:${o}`)}catch(a){x.fail(m(a)),n.finish(),process.exit(1)}let w=`http://localhost:${o}/`;if(r){f.skip(w),n.finish();return}try{f.start("launching browser\u2026"),await _(w),f.done(w)}catch(a){f.skip(`${w} (open it manually \u2014 ${m(a)})`)}n.finish(),p==="standalone"?(console.log(`
|
|
22
|
-
running in standalone mode. sootsim will exit when this process does.
|
|
23
|
-
press ctrl-c to stop.`),await new Promise(()=>{})):p==="daemon-installed"&&console.log("\n installed as a background daemon \u2014 it'll restart on login.\n manage it with `sootsim daemon status / restart / uninstall`.")}function P(t,e){return new Promise(s=>{let i=new B(`ws://127.0.0.1:${t}`,{handshakeTimeout:e}),r=!1,n=u=>{if(!r){r=!0;try{i.close()}catch{}s(u)}};i.once("open",()=>n(!0)),i.once("error",()=>n(!1)),setTimeout(()=>n(!1),e)})}async function V(t,e){let s=Date.now()+e;for(;Date.now()<s;){if(await P(t,500))return!0;await new Promise(i=>setTimeout(i,200))}return!1}async function C(t){let e=W();N(e,["server","--quiet","--port",String(t)],{detached:!0,stdio:"ignore",env:process.env}).unref();let i=Date.now()+I;for(;Date.now()<i;){let r=b();if(v(r))return r.bridgePort;await new Promise(n=>setTimeout(n,150))}if(await P(t,800))return t;throw new Error(`standalone server didn't come online within ${Math.round(I/1e3)}s`)}function W(){let t=process.argv[1];return t&&F(t)?t:"sootsim"}function m(t){return t instanceof Error?t.message:String(t)}export{Z as runStart};
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
/*! sootsim v0.1.39 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
|
-
import{a,b,c}from"./chunk-NF65BNJR.js";import"./chunk-4YUHJ5FX.js";import"./chunk-4UI5OHEO.js";import"./chunk-VLUFTHBB.js";import"./chunk-UWRBEBML.js";import"./chunk-C6GUAXKO.js";import"./chunk-HWRR23AJ.js";import"./chunk-RLGCJT2D.js";import"./chunk-B3OEHV2C.js";import"./chunk-ECDPQ6S7.js";import"./chunk-WD54RD4K.js";export{a as resolveDefaultUploadOrigin,b as resolvePublicPreviewOrigin,c as runUpload};
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
/*! sootsim v0.1.39 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
|
-
import{c as w,e as b,h as d}from"./chunk-HWRR23AJ.js";import{b as S}from"./chunk-RLGCJT2D.js";import"./chunk-B3OEHV2C.js";import"./chunk-ECDPQ6S7.js";import"./chunk-WD54RD4K.js";function T(n){let e=[];for(let t=0;t<n.length;t++)if(n[t]==="--since"&&t+1<n.length){e.push(t,t+1);let o=n[t+1].trim(),i=/^(\d+(?:\.\d+)?)(ms|s|m)?$/.exec(o);if(i){let l=Number(i[1]),u=i[2]??"ms",r=u==="s"?l*1e3:u==="m"?l*6e4:l;return{since:Date.now()-r,consumed:e}}let s=Number(o);if(Number.isFinite(s)&&s>1e12)return{since:s,consumed:e}}return{consumed:e}}function x(n){let e=[];for(let t=0;t<n.length;t++)if(n[t]==="--kinds"&&t+1<n.length)return e.push(t,t+1),{kinds:n[t+1].split(",").map(o=>o.trim()).filter(Boolean),consumed:e};return{consumed:e}}function A(n){let e=[];for(let t=0;t<n.length;t++)if(n[t]==="--limit"&&t+1<n.length){e.push(t,t+1);let o=Number(n[t+1]);if(Number.isFinite(o)&&o>0)return{limit:o,consumed:e}}return{consumed:e}}function M(n,e){if(e===null)return new Date(n).toLocaleTimeString();let t=(n-e)/1e3;return`${t>=0?"+":""}${t.toFixed(2)}s`}function E(n,e){switch(n){case"app-launch":return e.phase==="launch"?`launch ${e.appName??e.toAppId??""}`:`dismiss ${e.appName??e.fromAppId??""} \u2192 ${e.toAppId??""}`;case"toast":return`"${e.text??""}"${e.durationMs?` (${e.durationMs}ms)`:""}`;case"keyboard":return`${e.phase??"?"}${e.heightPx?` h=${e.heightPx}`:""}${e.mode?` ${e.mode}`:""}`;case"screen":return`${e.phase??"?"} ${e.name??e.activeName??""}`;case"route":return`${e.phase??"?"} ${e.path??e.pathname??""}`;case"alert":case"actionsheet":case"picker":return`${e.phase??"?"} ${e.title??e.message??""}`;case"notification":return`${e.title??""}${e.body?` \u2014 ${e.body}`:""}`;case"fetch":return`${e.method??"GET"} ${e.url??""}${e.status?` -> ${e.status}`:""}`;case"console":return`${e.level??"log"}: ${(e.message??"").toString().slice(0,120)}`;case"shell":return`${e.event??e.type??e.phase??""}`;case"scroll":return`${e.phase??"?"} ${e.target??""}`;case"gesture":return`${e.phase??"?"} ${e.type??""}`;case"text-input":return`${e.phase??"?"}${e.value!==void 0?` "${String(e.value).slice(0,40)}"`:""}`;case"react-commit":{let t=e.slowest;return`${e.fiberCount??"?"} fibers ${e.durationMs??"?"}ms${t?.displayName?` \xB7 ${t.displayName} ${t.durationMs??"?"}ms`:""}`}case"reanimated":case"animation":return`${e.kind??""} ${e.target??""}${e.durationMs?` ${e.durationMs}ms`:""}`}}function y(n,e){let t=M(n.t,e).padStart(8),o=n.context.padEnd(6),i=`[${n.kind}]`.padEnd(15),s="",l=n.data;return l&&typeof l=="object"&&(s=E(n.kind,l)),` ${t} ${o} ${i} ${s}`}function k(n){let e=[],t={label:"initial state",events:[],startedAt:n[0]?.t??null};e.push(t);for(let o of n)if(t.events.push(o),o.kind==="screen"||o.kind==="route"){let i=o.data,s=i?.phase;if(!s||s==="enter"||s==="appear"||s==="active"){let l=i?.name||i?.activeName||i?.path||i?.pathname||o.kind;e.length===1&&t.events.length===1?t.label=`${o.kind}: ${l}`:(t={label:`${o.kind}: ${l}`,events:[],startedAt:o.t},e.push(t))}}return e}function R(n){if(n.total===0)return"nothing recorded";let e=[],t=["error","warning","console","fetch","toast","alert","actionsheet","picker","notification","screen","route","keyboard","app-launch","shell","scroll","gesture","text-input","react-commit","animation","reanimated"],o=new Set;for(let i of t){let s=n.byKind[i];s&&(e.push(`${s} ${i}${s===1?"":"s"}`),o.add(i))}for(let[i,s]of Object.entries(n.byKind))!o.has(i)&&s&&e.push(`${s} ${i}${s===1?"":"s"}`);return e.join(" \xB7 ")}async function B(n,e){let t=w(n,{port:e.port,stripBooleanFlags:["--summary","--all","--json","--no-advance","--help","-h","--flow"],stripValueFlags:["--since","--kinds","--limit"]});(n.includes("--help")||n.includes("-h"))&&(console.log(`
|
|
3
|
-
sootsim what-happened \u2014 show recent events from the semantic timeline
|
|
4
|
-
|
|
5
|
-
usage:
|
|
6
|
-
sootsim what-happened # since last CLI call
|
|
7
|
-
sootsim what-happened --summary # one-line counts
|
|
8
|
-
sootsim what-happened --all # full ring (ignore cursor)
|
|
9
|
-
sootsim what-happened --since 5s # absolute window
|
|
10
|
-
sootsim what-happened --kinds toast,fetch
|
|
11
|
-
sootsim what-happened --limit 50
|
|
12
|
-
sootsim what-happened --json
|
|
13
|
-
sootsim what-happened --no-advance # don't advance cursor after read
|
|
14
|
-
`),process.exit(0));let o=n.includes("--summary"),i=n.includes("--flow"),s=n.includes("--all"),l=n.includes("--json"),u=n.includes("--no-advance"),{since:r}=T(n),{kinds:f}=x(n),{limit:F}=A(n),$=S(),v={limit:F??200,...f&&f.length?{kinds:f}:{},...r!==void 0?{since:r}:s?{}:{sinceCursor:$}},m=b(t);try{if(o){let c=await d(m,"SootSim.bridges.timeline.summary",v);if(l)console.log(JSON.stringify(c));else{let p=s?"all time":r!==void 0?`last ${((Date.now()-r)/1e3).toFixed(1)}s`:"since last call";console.log(` ${p}: ${R(c)}`)}!u&&!s&&c.lastAt&&await d(m,"SootSim.bridges.timeline.cursorAdvance",$,c.lastAt);return}let a=await d(m,"SootSim.bridges.timeline.recent",v);if(l)console.log(JSON.stringify(i?k(a.events):a,null,2));else if(a.events.length===0)console.log(s?" no events recorded":r!==void 0?" no events in window":" no new events since last call");else if(i){let c=a.events[0]?.t??null,p=k(a.events),g=s?`\u2500\u2500\u2500 ${a.events.length} event(s) total \u2014 flow view \u2500\u2500\u2500`:r!==void 0?`\u2500\u2500\u2500 ${a.events.length} event(s) in last ${((Date.now()-r)/1e3).toFixed(1)}s \u2014 flow view \u2500\u2500\u2500`:`\u2500\u2500\u2500 ${a.events.length} event(s) since last call \u2014 flow view \u2500\u2500\u2500`;console.log(` ${g}`);for(let h of p){console.log(`
|
|
15
|
-
\u2500\u2500 ${h.label} (${h.events.length} event${h.events.length===1?"":"s"}) \u2500\u2500`);for(let N of h.events)console.log(y(N,c))}}else{let c=a.events[0]?.t??null,p=s?`\u2500\u2500\u2500 ${a.events.length} event(s) total \u2500\u2500\u2500`:r!==void 0?`\u2500\u2500\u2500 ${a.events.length} event(s) in last ${((Date.now()-r)/1e3).toFixed(1)}s \u2500\u2500\u2500`:`\u2500\u2500\u2500 ${a.events.length} event(s) since last call \u2500\u2500\u2500`;console.log(` ${p}`);for(let g of a.events)console.log(y(g,c))}!u&&!s&&a.watermark>0&&await d(m,"SootSim.bridges.timeline.cursorAdvance",$,a.watermark)}finally{m.close()}}export{B as runWhatHappened};
|