sootsim 0.1.230 → 0.1.232

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.
Files changed (146) hide show
  1. package/dist-cli/bin.js +4 -4
  2. package/dist-cli/chunks/{agent-HKBFUUIT.js → agent-ZYXBVBKV.js} +2 -2
  3. package/dist-cli/chunks/{agent-wrapper-MKQFZDTK.js → agent-wrapper-T674ITPJ.js} +2 -2
  4. package/dist-cli/chunks/{app-fonts-AIFCR65V.js → app-fonts-K7SXZISI.js} +2 -2
  5. package/dist-cli/chunks/{assert-4TVYMSYB.js → assert-VLBPPU53.js} +2 -2
  6. package/dist-cli/chunks/{auth-WDTNFXFC.js → auth-N2YSIJWG.js} +2 -2
  7. package/dist-cli/chunks/beta-BNWNKZVD.js +2 -0
  8. package/dist-cli/chunks/{camera-YHQ4U4DY.js → camera-2HISM2VC.js} +2 -2
  9. package/dist-cli/chunks/{chunk-VSMUXKQV.js → chunk-2M62WMJ4.js} +2 -2
  10. package/dist-cli/chunks/{chunk-FKE2NHET.js → chunk-2QLL7ZTJ.js} +2 -2
  11. package/dist-cli/chunks/{chunk-RFMY24WX.js → chunk-3BQN6WRJ.js} +2 -2
  12. package/dist-cli/chunks/{chunk-AHL4WALW.js → chunk-3LAVER6S.js} +3 -3
  13. package/dist-cli/chunks/{chunk-XEYUPFNF.js → chunk-4URI2MGG.js} +1 -1
  14. package/dist-cli/chunks/{chunk-YVEZNXNW.js → chunk-576MFPKR.js} +3 -3
  15. package/dist-cli/chunks/{chunk-DBAK72QO.js → chunk-7BCDBZOP.js} +2 -2
  16. package/dist-cli/chunks/{chunk-62YYON2N.js → chunk-7VV57LAC.js} +1 -1
  17. package/dist-cli/chunks/chunk-A7RXUZTR.js +1 -0
  18. package/dist-cli/chunks/{chunk-SIU7QATA.js → chunk-AJCLM5JM.js} +1 -1
  19. package/dist-cli/chunks/{chunk-H3MLNZHE.js → chunk-APDLWZH7.js} +3 -3
  20. package/dist-cli/chunks/{chunk-HG4RA7CO.js → chunk-DEPM3RAJ.js} +2 -2
  21. package/dist-cli/chunks/chunk-DQ3UVIWC.js +1 -0
  22. package/dist-cli/chunks/{chunk-EOXIIWK6.js → chunk-E5KVZJLZ.js} +2 -2
  23. package/dist-cli/chunks/{chunk-P4KO4ECO.js → chunk-FVAYMAX3.js} +3 -3
  24. package/dist-cli/chunks/{chunk-PL6EHWGV.js → chunk-GR3HSBBW.js} +2 -2
  25. package/dist-cli/chunks/{chunk-FZFB2OZS.js → chunk-GSM3KOU7.js} +1 -1
  26. package/dist-cli/chunks/{chunk-DUBC22VO.js → chunk-H4U7AD3S.js} +2 -2
  27. package/dist-cli/chunks/{chunk-OHFY7KGT.js → chunk-HORIFBHS.js} +2 -2
  28. package/dist-cli/chunks/{chunk-3M3HSRK2.js → chunk-I6PFJTSC.js} +1 -1
  29. package/dist-cli/chunks/{chunk-TNT7TAX5.js → chunk-IQ4GXAZH.js} +3 -3
  30. package/dist-cli/chunks/{chunk-C3HOLPYO.js → chunk-ITX76FQB.js} +1 -1
  31. package/dist-cli/chunks/{chunk-TZBAMT3F.js → chunk-JLFLM25R.js} +1 -1
  32. package/dist-cli/chunks/{chunk-H6NIZEHS.js → chunk-JSNKI3AX.js} +1 -1
  33. package/dist-cli/chunks/{chunk-LULYUY7P.js → chunk-K26I444J.js} +2 -2
  34. package/dist-cli/chunks/{chunk-4QXQNNAI.js → chunk-K3QNZFXE.js} +1 -1
  35. package/dist-cli/chunks/{chunk-5FGADJZA.js → chunk-LL2KRCXL.js} +1 -1
  36. package/dist-cli/chunks/{chunk-YDIPQ2J4.js → chunk-LUDBC2J3.js} +1 -1
  37. package/dist-cli/chunks/{chunk-CMNUMJPV.js → chunk-LZK6NZLU.js} +2 -2
  38. package/dist-cli/chunks/{chunk-XS72QD5F.js → chunk-M6UUHHFL.js} +2 -2
  39. package/dist-cli/chunks/{chunk-XHPPEQI4.js → chunk-MXKSDA7J.js} +3 -3
  40. package/dist-cli/chunks/{chunk-UBMWVAU7.js → chunk-N37Q2X3Z.js} +2 -2
  41. package/dist-cli/chunks/{chunk-JS4CQN4E.js → chunk-NGTUX4OS.js} +2 -2
  42. package/dist-cli/chunks/{chunk-3SBXDOZZ.js → chunk-NQJ6EHGW.js} +2 -2
  43. package/dist-cli/chunks/{chunk-TK7M5F6S.js → chunk-QCVNJSEN.js} +1 -1
  44. package/dist-cli/chunks/{chunk-FFW4IVQI.js → chunk-RMVUXVHN.js} +1 -1
  45. package/dist-cli/chunks/{chunk-IZGUWTF7.js → chunk-SBDYAXSF.js} +2 -2
  46. package/dist-cli/chunks/{chunk-4UYMLSFL.js → chunk-SJCQEGF4.js} +1 -1
  47. package/dist-cli/chunks/{chunk-O5Q4WUPP.js → chunk-TA3JNI7A.js} +1 -1
  48. package/dist-cli/chunks/{chunk-FLUDPGRE.js → chunk-UPVCNKFF.js} +2 -2
  49. package/dist-cli/chunks/{chunk-THJZT2N5.js → chunk-UQWDGKY7.js} +1 -1
  50. package/dist-cli/chunks/{chunk-OSKXFSEW.js → chunk-W7BAZFHN.js} +2 -2
  51. package/dist-cli/chunks/{chunk-FG52DIVI.js → chunk-XHHT4CMD.js} +2 -2
  52. package/dist-cli/chunks/{chunk-JGGADCQK.js → chunk-Z3VIVTZS.js} +1 -1
  53. package/dist-cli/chunks/{chunk-ROJCLUO7.js → chunk-ZEFNMBSK.js} +1 -1
  54. package/dist-cli/chunks/cli-version-7VDEZHWX.js +2 -0
  55. package/dist-cli/chunks/{compat-TZEY7RZM.js → compat-2K4KZ6YB.js} +3 -3
  56. package/dist-cli/chunks/{config-AQ3GH3FR.js → config-QXPCZYU7.js} +2 -2
  57. package/dist-cli/chunks/{control-SG5Q4L64.js → control-JFUKBGDB.js} +2 -2
  58. package/dist-cli/chunks/daemon-5HXDKPKX.js +2 -0
  59. package/dist-cli/chunks/{debug-F2IL5OBI.js → debug-6CCPBFAD.js} +3 -3
  60. package/dist-cli/chunks/{desktop-FLQ565RL.js → desktop-3N7MIW4A.js} +3 -3
  61. package/dist-cli/chunks/{detox-5TZPMZQF.js → detox-QWVPGFZB.js} +2 -2
  62. package/dist-cli/chunks/{device-OWNJ37V4.js → device-KIB4TN52.js} +2 -2
  63. package/dist-cli/chunks/{diagnose-VLJDPUHV.js → diagnose-M6MNCYNQ.js} +2 -2
  64. package/dist-cli/chunks/drivers-W2PMIOIX.js +2 -0
  65. package/dist-cli/chunks/{film-SSXRAQBW.js → film-SEJDGF7B.js} +3 -3
  66. package/dist-cli/chunks/flow-M2S2LX67.js +2 -0
  67. package/dist-cli/chunks/help-YH2Q2TSP.js +2 -0
  68. package/dist-cli/chunks/{hidden-runtime-alias-ATPNECCP.js → hidden-runtime-alias-X3ZNKKZX.js} +2 -2
  69. package/dist-cli/chunks/{home-paths-AKSJKOCX.js → home-paths-HEIXYMSP.js} +2 -2
  70. package/dist-cli/chunks/inspect-H3PXV6CS.js +2 -0
  71. package/dist-cli/chunks/install-desktop-QVUU3MYS.js +2 -0
  72. package/dist-cli/chunks/{login-PJOZTLK2.js → login-PM66V7R2.js} +4 -4
  73. package/dist-cli/chunks/{logout-T5NNOL37.js → logout-F5QZ4ZGB.js} +2 -2
  74. package/dist-cli/chunks/{maestro-S5NCE5GL.js → maestro-FD7BPFRS.js} +3 -3
  75. package/dist-cli/chunks/{maestro-generate-ME5LCEQV.js → maestro-generate-DBQRAIL5.js} +3 -3
  76. package/dist-cli/chunks/{mode-Q6O6NBT5.js → mode-6P7F24QX.js} +2 -2
  77. package/dist-cli/chunks/optional-demo-registry-3R4ERASC.js +2 -0
  78. package/dist-cli/chunks/{perf-LV4QH54X.js → perf-WJH3CUPE.js} +2 -2
  79. package/dist-cli/chunks/{record-4LD5JGW7.js → record-5LYWSKDK.js} +3 -3
  80. package/dist-cli/chunks/runtime-7NRBQTTI.js +2 -0
  81. package/dist-cli/chunks/{screenshot-command-RBMMMK3D.js → screenshot-command-7KLNMCZY.js} +3 -3
  82. package/dist-cli/chunks/{screenshots-capture-OOR7ORQZ.js → screenshots-capture-7L4TFISK.js} +2 -2
  83. package/dist-cli/chunks/{serve-KX3TPFEM.js → serve-HTFVXDL2.js} +8 -8
  84. package/dist-cli/chunks/{setup-2WNETFVJ.js → setup-NZNQPY6O.js} +3 -3
  85. package/dist-cli/chunks/{skills-CBY4DMPN.js → skills-6BNHSBOU.js} +2 -2
  86. package/dist-cli/chunks/{storage-REOZAXUT.js → storage-L2RXZZFJ.js} +2 -2
  87. package/dist-cli/chunks/store-GUBFOLLP.js +2 -0
  88. package/dist-cli/chunks/telemetry-KUIS2R6S.js +2 -0
  89. package/dist-cli/chunks/{timeline-MC5I4MP5.js → timeline-KQS4WCD2.js} +2 -2
  90. package/dist-cli/chunks/{upgrade-XUSLR5J2.js → upgrade-RSSNHKBP.js} +2 -2
  91. package/dist-cli/chunks/upload-BGBBPPQA.js +2 -0
  92. package/dist-cli/chunks/{version-XK5CBJM6.js → version-KIRBZT2R.js} +2 -2
  93. package/dist-cli/chunks/{web-2YGOXHIY.js → web-7L2S4STL.js} +2 -2
  94. package/dist-cli/chunks/{what-happened-VM2XNZBH.js → what-happened-RGVPA3IL.js} +2 -2
  95. package/dist-lib/agent-daemon-client.cjs +1 -1
  96. package/dist-lib/agent-events.cjs +1 -1
  97. package/dist-lib/agent-identity.cjs +1 -1
  98. package/dist-lib/agent-sessions.cjs +1 -1
  99. package/dist-lib/attached-projects.cjs +1 -1
  100. package/dist-lib/auth/shared-session.cjs +1 -1
  101. package/dist-lib/backend-origin.cjs +1 -1
  102. package/dist-lib/beta.cjs +1 -1
  103. package/dist-lib/beta.mjs +1 -1
  104. package/dist-lib/bridge-constants.cjs +1 -1
  105. package/dist-lib/cli-constants.cjs +1 -1
  106. package/dist-lib/config.cjs +1 -1
  107. package/dist-lib/detox/index.cjs +1 -1
  108. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  109. package/dist-lib/home-paths.cjs +1 -1
  110. package/dist-lib/host/bridge-host.cjs +9 -2
  111. package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
  112. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  113. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  114. package/dist-lib/host/websocket-proxy.cjs +1 -1
  115. package/dist-lib/index.cjs +1 -1
  116. package/dist-lib/jump-to-source-babel.cjs +1 -1
  117. package/dist-lib/menu.cjs +1 -1
  118. package/dist-lib/menu.mjs +1 -1
  119. package/dist-lib/metro.cjs +1 -1
  120. package/dist-lib/profiles.cjs +1 -1
  121. package/dist-lib/render-mode.cjs +1 -1
  122. package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
  123. package/dist-lib/sdk.cjs +1 -1
  124. package/dist-lib/sdk.mjs +1 -1
  125. package/dist-lib/skills.cjs +13 -6
  126. package/dist-lib/vite.cjs +1 -1
  127. package/package.json +1 -1
  128. package/scripts/dev-server-scanner.ts +1 -1
  129. package/src/config.ts +5 -0
  130. package/src/host/agent-host.ts +1 -2
  131. package/src/host/bridge-host.ts +12 -0
  132. package/dist-cli/chunks/beta-P3YYMVNZ.js +0 -2
  133. package/dist-cli/chunks/chunk-PV37DC5L.js +0 -1
  134. package/dist-cli/chunks/chunk-SS4WSBTW.js +0 -1
  135. package/dist-cli/chunks/cli-version-OO7BXUF3.js +0 -2
  136. package/dist-cli/chunks/daemon-PFFOASPW.js +0 -2
  137. package/dist-cli/chunks/drivers-IDPIZR54.js +0 -2
  138. package/dist-cli/chunks/flow-ZD76KVZK.js +0 -2
  139. package/dist-cli/chunks/help-Y62CJ432.js +0 -2
  140. package/dist-cli/chunks/inspect-HIGWFAT2.js +0 -2
  141. package/dist-cli/chunks/install-desktop-7PUIVFVF.js +0 -2
  142. package/dist-cli/chunks/optional-demo-registry-EPHZ7VHD.js +0 -2
  143. package/dist-cli/chunks/runtime-3XWIYVBP.js +0 -2
  144. package/dist-cli/chunks/store-FP73G6TV.js +0 -2
  145. package/dist-cli/chunks/telemetry-I5DWQXU5.js +0 -2
  146. package/dist-cli/chunks/upload-5BLST4HU.js +0 -2
@@ -1,25 +1,25 @@
1
- /*! sootsim v0.1.230 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{b as le,c as H,d as de,e as F,f as ue,h as pe,i as C,j as me,k as he,l as fe,p as ge,s as v,t as Se,u as ye,v as ve,w as be}from"./chunk-IZGUWTF7.js";import"./chunk-5FGADJZA.js";import{a as ce}from"./chunk-PL6EHWGV.js";import"./chunk-RFMY24WX.js";import{h as ae}from"./chunk-JS4CQN4E.js";import{f as P,g as se}from"./chunk-YVEZNXNW.js";import"./chunk-YDIPQ2J4.js";import"./chunk-4QXQNNAI.js";import{d as oe}from"./chunk-TZBAMT3F.js";import"./chunk-JGGADCQK.js";import"./chunk-DUBC22VO.js";import{a as ee,b as te}from"./chunk-EOXIIWK6.js";import"./chunk-XS72QD5F.js";import{a as re,b as ne}from"./chunk-TK7M5F6S.js";import"./chunk-THJZT2N5.js";import{E as J,G as E,H as K,I as V,J as D,L as G,M as q,O as z,Q as X,R as Y,S as Z,T as U,U as Q,y as M,z as j}from"./chunk-3M3HSRK2.js";import{a as ie}from"./chunk-62YYON2N.js";import"./chunk-ROJCLUO7.js";import{spawn as ut}from"child_process";import I from"fs";import{createServer as pt}from"http";import S from"path";import{WebSocket as h,WebSocketServer as mt}from"ws";import Ie from"node:fs";import R from"node:path";import{spawn as Me}from"node:child_process";import De from"node:fs";import Ue from"node:os";import He from"node:path";var we=/^[A-Za-z0-9._:-]{1,160}$/;function W(o){if(!o?.startsWith("AGENTBUS_SESSION:"))return null;let e=o.slice(17).trim();return we.test(e)?e:null}function Ae(o){return we.test(o)}function Fe(o){return typeof o.text=="string"?o.text.trim():""}function We(o){let e=o?.trim();if(e)return e;let t=process.env.AGENTBUS_COMMAND?.trim();if(t)return t;let i=He.join(Ue.homedir(),".local","bin","agentbus");return De.existsSync(i)?i:"agentbus"}async function ke(o){let e=o.sessionId.trim();if(!Ae(e))throw new Error(`invalid agentbus session id: ${e||"<empty>"}`);let t=Fe(o.prompt);if(!t)throw new Error("prompt text is empty");let i=We(o.command),s=o.timeoutMs??15e3;await new Promise((n,a)=>{let r=Me(i,["send",e,t],{stdio:["ignore","ignore","pipe"],env:process.env}),c="",d=setTimeout(()=>{try{r.kill("SIGTERM")}catch{}a(new Error(`agentbus send timed out after ${Math.round(s/1e3)}s`))},s);r.stderr?.setEncoding("utf8"),r.stderr?.on("data",l=>{c.length<4e3&&(c+=String(l))}),r.on("error",l=>{clearTimeout(d),a(l)}),r.on("exit",(l,u)=>{if(clearTimeout(d),l===0){n();return}let p=c.trim();a(new Error(p||`agentbus send exited with ${u?`signal ${u}`:`code ${l??"unknown"}`}`))})})}var _=1;function $e(){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(o=>Number.isFinite(o)&&o>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 v?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 fe()}catch(e){process.stderr.write(`[sootsim-agent] seedFromDemoAppRegistry failed: ${e instanceof Error?e.message:String(e)}
1
+ /*! sootsim v0.1.232 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{b as le,c as H,d as de,e as F,f as ue,h as pe,i as C,j as me,k as he,l as fe,p as ge,s as v,t as Se,u as ye,v as ve,w as be}from"./chunk-SBDYAXSF.js";import"./chunk-LL2KRCXL.js";import{a as ce}from"./chunk-GR3HSBBW.js";import"./chunk-3BQN6WRJ.js";import{h as ae}from"./chunk-NGTUX4OS.js";import{f as P,g as se}from"./chunk-576MFPKR.js";import"./chunk-LUDBC2J3.js";import"./chunk-K3QNZFXE.js";import{d as oe}from"./chunk-JLFLM25R.js";import"./chunk-Z3VIVTZS.js";import"./chunk-H4U7AD3S.js";import{a as ee,b as te}from"./chunk-E5KVZJLZ.js";import"./chunk-M6UUHHFL.js";import{a as re,b as ne}from"./chunk-QCVNJSEN.js";import"./chunk-UQWDGKY7.js";import{E as J,G as E,H as K,I as V,J as D,L as G,M as q,O as z,Q as X,R as Y,S as Z,T as U,U as Q,y as M,z as j}from"./chunk-I6PFJTSC.js";import{a as ie}from"./chunk-7VV57LAC.js";import"./chunk-ZEFNMBSK.js";import{spawn as ut}from"child_process";import I from"fs";import{createServer as pt}from"http";import S from"path";import{WebSocket as h,WebSocketServer as mt}from"ws";import Ie from"node:fs";import R from"node:path";import{spawn as Me}from"node:child_process";import De from"node:fs";import Ue from"node:os";import He from"node:path";var we=/^[A-Za-z0-9._:-]{1,160}$/;function W(o){if(!o?.startsWith("AGENTBUS_SESSION:"))return null;let e=o.slice(17).trim();return we.test(e)?e:null}function Ae(o){return we.test(o)}function Fe(o){return typeof o.text=="string"?o.text.trim():""}function We(o){let e=o?.trim();if(e)return e;let t=process.env.AGENTBUS_COMMAND?.trim();if(t)return t;let i=He.join(Ue.homedir(),".local","bin","agentbus");return De.existsSync(i)?i:"agentbus"}async function ke(o){let e=o.sessionId.trim();if(!Ae(e))throw new Error(`invalid agentbus session id: ${e||"<empty>"}`);let t=Fe(o.prompt);if(!t)throw new Error("prompt text is empty");let i=We(o.command),s=o.timeoutMs??15e3;await new Promise((n,a)=>{let r=Me(i,["send",e,t],{stdio:["ignore","ignore","pipe"],env:process.env}),c="",d=setTimeout(()=>{try{r.kill("SIGTERM")}catch{}a(new Error(`agentbus send timed out after ${Math.round(s/1e3)}s`))},s);r.stderr?.setEncoding("utf8"),r.stderr?.on("data",l=>{c.length<4e3&&(c+=String(l))}),r.on("error",l=>{clearTimeout(d),a(l)}),r.on("exit",(l,u)=>{if(clearTimeout(d),l===0){n();return}let p=c.trim();a(new Error(p||`agentbus send exited with ${u?`signal ${u}`:`code ${l??"unknown"}`}`))})})}var x=1;function $e(){return[Number(process.env.VITE_PORT_WEB||process.env.PORT||3e3),Number(process.env.VITE_PORT_ZERO||7849),Number(process.env.VITE_PORT_R2||9500)].filter(o=>Number.isFinite(o)&&o>0)}var _=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 v?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 fe()}catch(e){process.stderr.write(`[sootsim-agent] seedFromDemoAppRegistry failed: ${e instanceof Error?e.message:String(e)}
3
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 F();case"agent:upsert-project":return H(i.input??{});case"agent:delete-project":return pe(String(i.projectId)),{ok:!0};case"agent:auto-attach-for-url":return this.autoAttachForUrl(i.input??{});case"agent:list-sessions":return me(i.projectId?String(i.projectId):void 0);case"agent:start-session":return this.doStartSession(i.input??{});case"agent:send-claimed-prompt":return this.sendClaimedPrompt(i);case"agent:send-prompt":{let n=String(i.sessionId),a=C(n);if(!a)throw new v("NO_SESSION",`no session: ${n}`);let r=this.normalizePromptEnvelope(i);return await ye(n,r),this.notePromptAccepted(n,r,a.status==="working")}case"agent:end-session":this.dropSessionFanout(String(i.sessionId)),await ve(String(i.sessionId));let s=C(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 v("UNKNOWN_AGENT_MSG",`unknown agent message: ${t}`)}}async sendClaimedPrompt(e){let t=typeof e.simId=="string"?e.simId.trim():"";if(!t)throw new v("NO_SIM","agent:send-claimed-prompt requires simId");let i=this.opts.resolveCliLease?.(t)??null;if(!i||i.kind!=="cli"||i.expiresAt<=Date.now())throw new v("NO_CLAIM",`sim ${t} has no active CLI claim`);let s=W(i.cliIdentityKey);if(!s)throw new v("UNSUPPORTED_CLAIM",`sim ${t} is claimed by a CLI identity that is not promptable`);return await ke({sessionId:s,prompt:this.normalizePromptEnvelope(e)}),{ok:!0,routed:"agentbus",sessionId:s}}async doStartSession(e){if(!de(e.projectId))throw new v("NO_PROJECT",`no project: ${e.projectId}`);let i=await Se(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?.()??$e(),a=(await P({excludePorts:s})).find(l=>String(l.port)===i);if(!a||!a.cwd)return{project:null};let r=F().find(l=>l.cwd===a.cwd)??null,c=Array.from(new Set([...r?.knownBundleUrls??[],a.bundleUrl,t]));return{project:H({cwd:a.cwd,name:a.projectName??R.basename(a.cwd),preferredProvider:e.provider??r?.preferredProvider,sourceRoots:r?.sourceRoots??[a.cwd],knownBundleUrls:c,framework:r?.framework??je(a.framework),bundleId:a.bundleId??r?.bundleId})}}getTranscript(e){let t=ge(e);return Ie.existsSync(t)?Ie.readFileSync(t,"utf8"):{error:"transcript not found",code:"NO_TRANSCRIPT"}}getPaths(){let e=le();return{userDataDir:e,storeFile:R.join(e,"attached-projects.json"),sessionsDir:R.join(e,"sessions"),transcriptsDir:R.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=be(t,a=>{let r=this.coalescePromptEcho(t,a);if(r&&(this.applySessionEvent(t,r),this.fanOutEvent(t,r)),a.type==="turn-completed"){let c=C(t);if(c)try{ue(c.projectId,{usd:a.costUsd,ts:a.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 a=Math.max(this.pendingTurns.get(e)??0,i?1:0)+1;this.pendingTurns.set(e,a);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:a>1,pendingTurns:a,queueDepth:Math.max(0,a-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){he(e,t);let i=C(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===_)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===_)try{i.send(t)}catch{}}respond(e,t,i){if(e.readyState===_)try{e.send(JSON.stringify({id:t,result:i}))}catch{}}respondError(e,t,i,s){if(e.readyState===_)try{e.send(JSON.stringify({id:t,error:i,...s?{code:s}:{}}))}catch{}}};function je(o){return o==="expo"?"expo":o==="one"||o==="vxrn"?"one":"unknown"}import Ve from"http";import Ge from"https";var $="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/146.0.0.0 Safari/537.36",Je=[{hostSuffix:"uniswap.org",headers:{origin:"https://app.uniswap.org",referer:"https://app.uniswap.org/"},suppressBrowserUserAgent:!0}];function Ke(o){let e=o.toLowerCase();for(let t of Je)if(e===t.hostSuffix||e.endsWith(`.${t.hostSuffix}`))return t}function Ce(o){let e=Ke(o.hostname);return{"accept-encoding":"identity",...e?.suppressBrowserUserAgent?{}:{"user-agent":$},...e?.headers}}var qe=new Set(["host","origin","referer","user-agent","accept-encoding","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"]),ze={"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"},Xe=new Set(["host","origin","referer","sec-fetch-site","sec-fetch-mode","sec-fetch-dest"]);function T(o){for(let[e,t]of Object.entries(ze))o.setHeader(e,t)}function Ye(o,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 o.includes("stored-in-.env.local")?`${n} | upstream url still contains placeholder env values`:n}function Ze(o){let t=(Array.isArray(o)?o[0]:o)?.split(";",1)[0]?.trim().toLowerCase();return t?t.startsWith("text/")||t==="application/json"||t.endsWith("+json")||t==="application/x-www-form-urlencoded"||t==="application/xml"||t.endsWith("+xml")||t==="application/javascript"||t==="application/graphql":!1}function Qe(o,e){let t={};for(let[i,s]of Object.entries(o))s&&(qe.has(i.toLowerCase())||(t[i]=Array.isArray(s)?s.join(", "):s));return Object.assign(t,e?Ce(e):{"user-agent":$}),t}function et(o,e){let t={};for(let[i,s]of Object.entries(o))s&&(Xe.has(i.toLowerCase())||(t[i]=s));return t.host=e.host,t.origin=e.origin,t.referer=`${e.origin}/`,t}function Te(o){return o?.startsWith("/__fetch-proxy?")||o?.startsWith("/__proxy?")||!1}function Ee(o){return o?!!(o.startsWith("/__app-api?")||o.startsWith("/__app-api/")):!1}async function Pe(o,e){if(o.method==="OPTIONS"){T(e),e.writeHead(204),e.end();return}let i=new URLSearchParams((o.url||"").split("?")[1]||"").get("url");if(!i){T(e),e.writeHead(400,{"Content-Type":"text/plain"}),e.end("missing url param");return}let s;try{s=new URL(i)}catch{T(e),e.writeHead(400,{"Content-Type":"text/plain"}),e.end("invalid url param");return}let n=Qe(o.headers,s),a;if(o.method!=="GET"&&o.method!=="HEAD"){let l=[];for await(let u of o)l.push(Buffer.isBuffer(u)?u:Buffer.from(u));if(l.length>0){let u=Buffer.concat(l);a=Ze(o.headers["content-type"])?u.toString("utf8"):u}}let r;try{r=await fetch(s.href,{method:o.method,headers:n,body:a,redirect:"follow"})}catch(l){T(e),e.writeHead(502,{"Content-Type":"text/plain"}),e.end(`fetch proxy error: ${Ye(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)}),T(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 Re(o,e){let t=o.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(o.method==="OPTIONS")return e.writeHead(204,{"Access-Control-Allow-Origin":o.headers.origin||"*","Access-Control-Allow-Methods":"GET,POST,PUT,PATCH,DELETE,OPTIONS","Access-Control-Allow-Headers":o.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 a=n.protocol==="https:"?Ge:Ve,r=et(o.headers,n),c=a.request({hostname:n.hostname,port:n.port||(n.protocol==="https:"?443:80),path:n.pathname+n.search,method:o.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":o.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}`)}),o.pipe(c),!0}import{WebSocket as k,WebSocketServer as tt}from"ws";var it="/__websocket-proxy",rt=new Set(["host","connection","upgrade","transfer-encoding","content-length","sec-websocket-accept","sec-websocket-extensions","sec-websocket-key","sec-websocket-protocol","sec-websocket-version"]);function A(o,e,t){try{o.write(`HTTP/1.1 ${e} ${t}\r
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 a=Math.max(this.pendingTurns.get(e)??0,i?1:0)+1;this.pendingTurns.set(e,a);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:a>1,pendingTurns:a,queueDepth:Math.max(0,a-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){he(e,t);let i=C(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===x)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===x)try{i.send(t)}catch{}}respond(e,t,i){if(e.readyState===x)try{e.send(JSON.stringify({id:t,result:i}))}catch{}}respondError(e,t,i,s){if(e.readyState===x)try{e.send(JSON.stringify({id:t,error:i,...s?{code:s}:{}}))}catch{}}};function je(o){return o==="expo"?"expo":o==="one"||o==="vxrn"?"one":"unknown"}import Ve from"http";import Ge from"https";var $="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/146.0.0.0 Safari/537.36",Je=[{hostSuffix:"uniswap.org",headers:{origin:"https://app.uniswap.org",referer:"https://app.uniswap.org/"},suppressBrowserUserAgent:!0}];function Ke(o){let e=o.toLowerCase();for(let t of Je)if(e===t.hostSuffix||e.endsWith(`.${t.hostSuffix}`))return t}function Ce(o){let e=Ke(o.hostname);return{"accept-encoding":"identity",...e?.suppressBrowserUserAgent?{}:{"user-agent":$},...e?.headers}}var qe=new Set(["host","origin","referer","user-agent","accept-encoding","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"]),ze={"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"},Xe=new Set(["host","origin","referer","sec-fetch-site","sec-fetch-mode","sec-fetch-dest"]);function T(o){for(let[e,t]of Object.entries(ze))o.setHeader(e,t)}function Ye(o,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 o.includes("stored-in-.env.local")?`${n} | upstream url still contains placeholder env values`:n}function Ze(o){let t=(Array.isArray(o)?o[0]:o)?.split(";",1)[0]?.trim().toLowerCase();return t?t.startsWith("text/")||t==="application/json"||t.endsWith("+json")||t==="application/x-www-form-urlencoded"||t==="application/xml"||t.endsWith("+xml")||t==="application/javascript"||t==="application/graphql":!1}function Qe(o,e){let t={};for(let[i,s]of Object.entries(o))s&&(qe.has(i.toLowerCase())||(t[i]=Array.isArray(s)?s.join(", "):s));return Object.assign(t,e?Ce(e):{"user-agent":$}),t}function et(o,e){let t={};for(let[i,s]of Object.entries(o))s&&(Xe.has(i.toLowerCase())||(t[i]=s));return t.host=e.host,t.origin=e.origin,t.referer=`${e.origin}/`,t}function Te(o){return o?.startsWith("/__fetch-proxy?")||o?.startsWith("/__proxy?")||!1}function Ee(o){return o?!!(o.startsWith("/__app-api?")||o.startsWith("/__app-api/")):!1}async function Pe(o,e){if(o.method==="OPTIONS"){T(e),e.writeHead(204),e.end();return}let i=new URLSearchParams((o.url||"").split("?")[1]||"").get("url");if(!i){T(e),e.writeHead(400,{"Content-Type":"text/plain"}),e.end("missing url param");return}let s;try{s=new URL(i)}catch{T(e),e.writeHead(400,{"Content-Type":"text/plain"}),e.end("invalid url param");return}let n=Qe(o.headers,s),a;if(o.method!=="GET"&&o.method!=="HEAD"){let l=[];for await(let u of o)l.push(Buffer.isBuffer(u)?u:Buffer.from(u));if(l.length>0){let u=Buffer.concat(l);a=Ze(o.headers["content-type"])?u.toString("utf8"):u}}let r;try{r=await fetch(s.href,{method:o.method,headers:n,body:a,redirect:"follow"})}catch(l){T(e),e.writeHead(502,{"Content-Type":"text/plain"}),e.end(`fetch proxy error: ${Ye(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)}),T(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 Re(o,e){let t=o.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(o.method==="OPTIONS")return e.writeHead(204,{"Access-Control-Allow-Origin":o.headers.origin||"*","Access-Control-Allow-Methods":"GET,POST,PUT,PATCH,DELETE,OPTIONS","Access-Control-Allow-Headers":o.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 a=n.protocol==="https:"?Ge:Ve,r=et(o.headers,n),c=a.request({hostname:n.hostname,port:n.port||(n.protocol==="https:"?443:80),path:n.pathname+n.search,method:o.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":o.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}`)}),o.pipe(c),!0}import{WebSocket as k,WebSocketServer as tt}from"ws";var it="/__websocket-proxy",rt=new Set(["host","connection","upgrade","transfer-encoding","content-length","sec-websocket-accept","sec-websocket-extensions","sec-websocket-key","sec-websocket-protocol","sec-websocket-version"]);function A(o,e,t){try{o.write(`HTTP/1.1 ${e} ${t}\r
5
5
  Connection: close\r
6
6
  Content-Type: text/plain\r
7
7
  Content-Length: ${t.length}\r
8
8
  \r
9
- ${t}`)}catch{}o.destroy()}function nt(o){let e=o.headers.origin,t=o.headers.host;if(!e||!t)return!1;try{return new URL(e).host===t}catch{return!1}}function st(o){if(!o)return{};let e=o.replace(/-/g,"+").replace(/_/g,"/"),t=e+"=".repeat((4-e.length%4)%4),i=JSON.parse(Buffer.from(t,"base64").toString("utf8"));if(!i||typeof i!="object"||Array.isArray(i))return{};let s={};for(let[n,a]of Object.entries(i))a!=null&&(rt.has(n.toLowerCase())||(s[n]=Array.isArray(a)?a.join(", "):String(a)));return s}function ot(o){let e=new URL(o.href);return e.protocol=o.protocol==="wss:"?"https:":"http:",e.origin}function at(o){let e=o.headers["sec-websocket-protocol"];return(Array.isArray(e)?e.join(","):e||"").split(",").map(i=>i.trim()).filter(Boolean)}function O(o,e,t){if(!(o.readyState===k.CLOSED||o.readyState===k.CLOSING))try{o.close(e,t)}catch{o.terminate()}}function ct(o,e){let t=!1,i=(s,n,a,r)=>{t||(t=!0,O(n,a,r.toString()),s.readyState===k.OPEN&&O(s,a,r.toString()))};o.on("message",(s,n)=>{e.readyState===k.OPEN&&e.send(s,{binary:n})}),e.on("message",(s,n)=>{o.readyState===k.OPEN&&o.send(s,{binary:n})}),o.on("close",(s,n)=>i(o,e,s,n)),e.on("close",(s,n)=>i(e,o,s,n)),o.on("error",()=>O(e,1011,"proxy client error")),e.on("error",()=>O(o,1011,"upstream websocket error"))}function lt(o,e,t){let i={...t};return Object.keys(i).some(s=>s.toLowerCase()==="origin")||(i.origin=ot(o)),new k(o.href,e,{headers:i})}function dt(o){if(!o)return!1;try{return new URL(o,"http://localhost").pathname===it}catch{return!1}}function _e(o,e,t){if(!dt(o.url))return!1;if(!nt(o))return A(e,403,"forbidden websocket proxy origin"),!0;let i,s;try{let c=new URL(o.url||"/","http://localhost"),d=c.searchParams.get("url");if(!d)return A(e,400,"missing websocket proxy url"),!0;if(i=new URL(d),i.protocol!=="ws:"&&i.protocol!=="wss:")return A(e,400,"invalid websocket proxy protocol"),!0;s=st(c.searchParams.get("headers"))}catch{return A(e,400,"invalid websocket proxy request"),!0}let n=at(o),a=lt(i,n,s),r=!1;return e.once("close",()=>{r||a.terminate()}),a.once("open",()=>{if(r)return;r=!0;let c=a.protocol;new tt({noServer:!0,clientTracking:!1,handleProtocols(l){return c||l.values().next().value||!1}}).handleUpgrade(o,e,t,l=>{ct(l,a)})}),a.once("error",()=>{r||(r=!0,A(e,502,"upstream websocket error"))}),a.once("close",()=>{r||(r=!0,A(e,502,"upstream websocket closed"))}),!0}var ht="require-corp",ft=new Set(["tap","keyboard"]),gt=2e3,St=1e3;function yt(o){return!o||typeof o.type!="string"?!1:o.acquireLock===!0?!0:o.readOnly===!0?!1:ft.has(o.type)}var xe=5e3,vt=3600*1e3,bt="SOOTSIM_RUNTIME_UPDATE_INTERVAL_MS",wt={".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 Oe(o,e,t){let i;try{let c=M();i=JSON.stringify(c)}catch{i="{}"}let s=e>0?`window.__sootsimBridgePort=${e};`:"",n=t?`window.__sootsimContrastOrigin=${JSON.stringify(t)};`:"",a=`<script>window.__sootsimSharedConfig=${i};`+s+n+`window.__sootsimCliVersion=${JSON.stringify(ie())};</script>`,r=o.toString("utf8");return r.includes("<head>")?r.replace("<head>",`<head>${a}`):r.includes("</head>")?r.replace("</head>",a+"</head>"):r.includes("</body>")?r.replace("</body>",a+"</body>"):a+r}function Le(o){typeof o=="object"&&o!==null&&"unref"in o&&o.unref()}var L=class o{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;static SIM_IDLE_REAP_TTL_MS=30*6e4;static AUTOMATION_SIM_IDLE_REAP_TTL_MS=10*6e4;static MAX_CONCURRENT_AUTOMATION_SIMS=6;static AUTOMATION_SIM_ACTIVE_GRACE_MS=6e4;preferredPort;portFallbackCount;simIdleReapTtlMs;automationSimIdleReapTtlMs;maxConcurrentAutomationSims;automationSimActiveGraceMs;shouldWriteLockfile;shouldWriteDevLockfile;getShellPort;contrastOrigin=null;effectivePort=0;startedAt=0;heartbeatTimer=null;devHeartbeatTimer=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.shouldWriteDevLockfile=e.writeDevLockfile===!0,this.getShellPort=e.getShellPort??null,this.portFallbackCount=Math.max(1,e.portFallbackCount??10),this.openUrlHandler=e.openUrl,this.agentHost=new x({getExcludePorts:e.agentScanExcludes,resolveCliLease:t=>{let i=this.sims.get(t),s=i?this.getActiveLease(i):null;return s?{kind:s.kind,cliIdentityKey:s.cliIdentityKey,expiresAt:s.expiresAt}:null}}),this.contrastOrigin=e.contrastOrigin?.replace(/\/$/,"")||null,this.simIdleReapTtlMs=e.simIdleReapTtlMs??o.SIM_IDLE_REAP_TTL_MS,this.automationSimIdleReapTtlMs=e.automationSimIdleReapTtlMs??o.AUTOMATION_SIM_IDLE_REAP_TTL_MS,this.maxConcurrentAutomationSims=e.maxConcurrentAutomationSims??o.MAX_CONCURRENT_AUTOMATION_SIMS,this.automationSimActiveGraceMs=e.automationSimActiveGraceMs??o.AUTOMATION_SIM_ACTIVE_GRACE_MS}getAgentHost(){return this.agentHost}reapIdleSimsForTest(e=Date.now()){this.reapIdleSims(e)}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)
9
+ ${t}`)}catch{}o.destroy()}function nt(o){let e=o.headers.origin,t=o.headers.host;if(!e||!t)return!1;try{return new URL(e).host===t}catch{return!1}}function st(o){if(!o)return{};let e=o.replace(/-/g,"+").replace(/_/g,"/"),t=e+"=".repeat((4-e.length%4)%4),i=JSON.parse(Buffer.from(t,"base64").toString("utf8"));if(!i||typeof i!="object"||Array.isArray(i))return{};let s={};for(let[n,a]of Object.entries(i))a!=null&&(rt.has(n.toLowerCase())||(s[n]=Array.isArray(a)?a.join(", "):String(a)));return s}function ot(o){let e=new URL(o.href);return e.protocol=o.protocol==="wss:"?"https:":"http:",e.origin}function at(o){let e=o.headers["sec-websocket-protocol"];return(Array.isArray(e)?e.join(","):e||"").split(",").map(i=>i.trim()).filter(Boolean)}function O(o,e,t){if(!(o.readyState===k.CLOSED||o.readyState===k.CLOSING))try{o.close(e,t)}catch{o.terminate()}}function ct(o,e){let t=!1,i=(s,n,a,r)=>{t||(t=!0,O(n,a,r.toString()),s.readyState===k.OPEN&&O(s,a,r.toString()))};o.on("message",(s,n)=>{e.readyState===k.OPEN&&e.send(s,{binary:n})}),e.on("message",(s,n)=>{o.readyState===k.OPEN&&o.send(s,{binary:n})}),o.on("close",(s,n)=>i(o,e,s,n)),e.on("close",(s,n)=>i(e,o,s,n)),o.on("error",()=>O(e,1011,"proxy client error")),e.on("error",()=>O(o,1011,"upstream websocket error"))}function lt(o,e,t){let i={...t};return Object.keys(i).some(s=>s.toLowerCase()==="origin")||(i.origin=ot(o)),new k(o.href,e,{headers:i})}function dt(o){if(!o)return!1;try{return new URL(o,"http://localhost").pathname===it}catch{return!1}}function xe(o,e,t){if(!dt(o.url))return!1;if(!nt(o))return A(e,403,"forbidden websocket proxy origin"),!0;let i,s;try{let c=new URL(o.url||"/","http://localhost"),d=c.searchParams.get("url");if(!d)return A(e,400,"missing websocket proxy url"),!0;if(i=new URL(d),i.protocol!=="ws:"&&i.protocol!=="wss:")return A(e,400,"invalid websocket proxy protocol"),!0;s=st(c.searchParams.get("headers"))}catch{return A(e,400,"invalid websocket proxy request"),!0}let n=at(o),a=lt(i,n,s),r=!1;return e.once("close",()=>{r||a.terminate()}),a.once("open",()=>{if(r)return;r=!0;let c=a.protocol;new tt({noServer:!0,clientTracking:!1,handleProtocols(l){return c||l.values().next().value||!1}}).handleUpgrade(o,e,t,l=>{ct(l,a)})}),a.once("error",()=>{r||(r=!0,A(e,502,"upstream websocket error"))}),a.once("close",()=>{r||(r=!0,A(e,502,"upstream websocket closed"))}),!0}var ht="require-corp",ft=new Set(["tap","keyboard"]),gt=2e3,St=1e3;function yt(o){return!o||typeof o.type!="string"?!1:o.acquireLock===!0?!0:o.readOnly===!0?!1:ft.has(o.type)}var _e=5e3,vt=3600*1e3,bt="SOOTSIM_RUNTIME_UPDATE_INTERVAL_MS",wt={".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 Oe(o,e,t){let i;try{let c=M();i=JSON.stringify(c)}catch{i="{}"}let s=e>0?`window.__sootsimBridgePort=${e};`:"",n=t?`window.__sootsimContrastOrigin=${JSON.stringify(t)};`:"",a=`<script>window.__sootsimSharedConfig=${i};`+s+n+`window.__sootsimCliVersion=${JSON.stringify(ie())};</script>`,r=o.toString("utf8");return r.includes("<head>")?r.replace("<head>",`<head>${a}`):r.includes("</head>")?r.replace("</head>",a+"</head>"):r.includes("</body>")?r.replace("</body>",a+"</body>"):a+r}function Le(o){typeof o=="object"&&o!==null&&"unref"in o&&o.unref()}var L=class o{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;static SIM_IDLE_REAP_TTL_MS=30*6e4;static AUTOMATION_SIM_IDLE_REAP_TTL_MS=10*6e4;static MAX_CONCURRENT_AUTOMATION_SIMS=6;static AUTOMATION_SIM_ACTIVE_GRACE_MS=6e4;preferredPort;portFallbackCount;simIdleReapTtlMs;automationSimIdleReapTtlMs;maxConcurrentAutomationSims;automationSimActiveGraceMs;shouldWriteLockfile;shouldWriteDevLockfile;getShellPort;contrastOrigin=null;effectivePort=0;startedAt=0;heartbeatTimer=null;devHeartbeatTimer=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.shouldWriteDevLockfile=e.writeDevLockfile===!0,this.getShellPort=e.getShellPort??null,this.portFallbackCount=Math.max(1,e.portFallbackCount??10),this.openUrlHandler=e.openUrl,this.agentHost=new _({getExcludePorts:e.agentScanExcludes,resolveCliLease:t=>{let i=this.sims.get(t),s=i?this.getActiveLease(i):null;return s?{kind:s.kind,cliIdentityKey:s.cliIdentityKey,expiresAt:s.expiresAt}:null}}),this.contrastOrigin=e.contrastOrigin?.replace(/\/$/,"")||null,this.simIdleReapTtlMs=e.simIdleReapTtlMs??o.SIM_IDLE_REAP_TTL_MS,this.automationSimIdleReapTtlMs=e.automationSimIdleReapTtlMs??o.AUTOMATION_SIM_IDLE_REAP_TTL_MS,this.maxConcurrentAutomationSims=e.maxConcurrentAutomationSims??o.MAX_CONCURRENT_AUTOMATION_SIMS,this.automationSimActiveGraceMs=e.automationSimActiveGraceMs??o.AUTOMATION_SIM_ACTIVE_GRACE_MS}getAgentHost(){return this.agentHost}reapIdleSimsForTest(e=Date.now()){this.reapIdleSims(e)}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)
10
10
  `),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}
11
11
  `)}}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=pt((c,d)=>this.handleHttpRequest(c,d)),a=!1,r=c=>{if(!a){a=!0;try{n.close()}catch{}this.httpServer=null,this.wss=null,s(c)}};n.once("error",r),n.listen(e,"127.0.0.1",()=>{a||(a=!0,n.removeListener("error",r),n.on("error",c=>{process.stderr.write(`ws bridge http error: ${String(c)}
12
- `)}),this.httpServer=n,this.wss=new mt({noServer:!0}),this.wireWebSocketServer(),n.on("upgrade",(c,d,l)=>{_e(c,d,l)||this.wss?.handleUpgrade(c,d,l,u=>{this.wss?.emit("connection",u,c)})}),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 a=`ws-${this.nextCliFallbackId++}`;this.cliIdentityKeyBySocket.set(e,a)}e.on("message",a=>{let r;try{r=JSON.parse(a.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(),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(!D().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"&&r.type==="bridge:hello"&&n&&!n.url){let c=n.id;this.sims.delete(c),this.primarySimId===c&&(this.primarySimId=this.getOpenSim()?.id??null),n=null,s="cli",this.cliIdentityKeyBySocket.set(e,`ws-${this.nextCliFallbackId++}`),this.broadcastSimAssignments(),this.broadcastSimClientStates()}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,typeof l.kind=="string"&&l.kind.trim()&&(n.kind=l.kind.trim()),l.meta&&typeof l.meta=="object"&&(n.meta=l.meta);let p=this.primarySimId!==n.id&&this.shouldPromoteSim(n);p&&(this.primarySimId=n.id),(u||p)&&(this.broadcastSimAssignments(),this.broadcastSimClientStates());return}if(r.type==="bridge:user-focus-state"&&n){let l=r;this.updateUserFocusLease(n,l);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=j(l)}catch(m){process.stderr.write(`sootsim: bridge:write-shared-config failed: ${m instanceof Error?m.message:String(m)}
12
+ `)}),this.httpServer=n,this.wss=new mt({noServer:!0}),this.wireWebSocketServer(),n.on("upgrade",(c,d,l)=>{xe(c,d,l)||this.wss?.handleUpgrade(c,d,l,u=>{this.wss?.emit("connection",u,c)})}),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 a=`ws-${this.nextCliFallbackId++}`;this.cliIdentityKeyBySocket.set(e,a)}e.on("message",a=>{let r;try{r=JSON.parse(a.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(),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(!D().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"&&r.type==="bridge:hello"&&n&&!n.url){let c=n.id;this.sims.delete(c),this.primarySimId===c&&(this.primarySimId=this.getOpenSim()?.id??null),n=null,s="cli",this.cliIdentityKeyBySocket.set(e,`ws-${this.nextCliFallbackId++}`),this.broadcastSimAssignments(),this.broadcastSimClientStates()}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,typeof l.kind=="string"&&l.kind.trim()&&(n.kind=l.kind.trim()),l.meta&&typeof l.meta=="object"&&(n.meta=l.meta);let p=this.primarySimId!==n.id&&this.shouldPromoteSim(n);p&&(this.primarySimId=n.id),(u||p)&&(this.broadcastSimAssignments(),this.broadcastSimClientStates());return}if(r.type==="bridge:user-focus-state"&&n){let l=r;this.updateUserFocusLease(n,l);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=j(l)}catch(m){process.stderr.write(`sootsim: bridge:write-shared-config failed: ${m instanceof Error?m.message:String(m)}
13
13
  `);return}let p=JSON.stringify({type:"bridge:shared-config-changed",config:u});for(let m of this.sims.values())if(m.ws.readyState===h.OPEN)try{m.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,m]of this.cliSimBySocket)m===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()+o.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}]
14
14
  `),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===h.OPEN)){let l=this.getOtherCliIdentityCount(d.ws,d.simId),u=l>0?{...r,id:d.originalId,_otherCliCount: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[m,f]of this.cliBySentId)f.ws===e&&this.cliBySentId.delete(m);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===h.OPEN&&e.send(JSON.stringify({id:r.id,result:{cliIdentityKey:p,leaseTtlMs:o.CLI_LEASE_TTL_MS,leasing:!0}}));return}if(r.type==="bridge:list-sims"){e.readyState===h.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===h.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),m=this.tryAcquireLease(e,p,{force:r.force===!0});if(!m.granted){e.readyState===h.OPEN&&e.send(JSON.stringify({id:r.id,error:`sim ${p.id} is locked by another cli`,_locked:m.lock}));return}this.setCliSimTarget(e,p.id),this.recordSimAction(p.id,m.bootedCount>0?`cli force-claimed sim (booted ${m.bootedCount})`:"cli claimed sim"),e.readyState===h.OPEN&&e.send(JSON.stringify({id:r.id,result:{simId:p.id,lockedBy:m.lease.cliIdentityKey,lockExpiresAt:m.lease.expiresAt,bootedCount:m.bootedCount}}));return}let c=await this.waitForSim(r.simId);if(yt(r)){let p=this.tryAcquireLease(e,c);if(!p.granted){e.readyState===h.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\``,_locked: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;if(c.ws.send(JSON.stringify({...u,id:d})),u.type==="close"){this.cliBySentId.delete(d),e.readyState===h.OPEN&&e.send(JSON.stringify({id:r.id,result:{requested:!0,simId:c.id}}));let p=c.ws,m=setTimeout(()=>{this.closeSimSocketFromHost(p)},gt);Le(m)}}catch(c){e.readyState===h.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[a,r]of this.pendingCommands)r.simId===n.id&&(r.reject(new Error("sim disconnected")),this.pendingCommands.delete(a));for(let[a,r]of this.cliBySentId)r.simId===n.id&&(r.ws.readyState===h.OPEN&&r.ws.send(JSON.stringify({id:r.originalId,error:"sim disconnected before responding"})),this.cliBySentId.delete(a));this.broadcastSimAssignments(),this.broadcastSimClientStates()}else if(s==="cli"){let a=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);a&&this.broadcastSimClientStates()}})})}afterBind(){if(process.stderr.write(`ws bridge listening on port ${this.port}
15
15
  `),this.cliIdleTimer=setInterval(()=>this.sweepIdleCliClients(),3e4),this.cliIdleTimer.unref(),this.wsHeartbeatTimer=setInterval(()=>this.sweepDeadWebSockets(),o.WS_HEARTBEAT_INTERVAL_MS),this.wsHeartbeatTimer.unref(),this.shouldWriteLockfile){try{if(E(),!Z(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)}
16
- `),e}this.heartbeatTimer=setInterval(()=>{try{this.writeLockfileSnapshot()}catch{}},xe),this.heartbeatTimer.unref(),this.startRuntimeUpdater()}if(this.shouldWriteDevLockfile){try{this.writeDevLockfileSnapshot()}catch(e){process.stderr.write(`ws bridge failed to write dev bridge lockfile: ${String(e)}
17
- `)}this.devHeartbeatTimer=setInterval(()=>{try{this.writeDevLockfileSnapshot()}catch{}},xe),this.devHeartbeatTimer.unref()}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}}buildDevLockfileSnapshot(){let e=this.getShellPort?.()??null;return{schema:1,pid:process.pid,platform:process.platform,bridgePort:this.effectivePort,runtimePort:this.effectivePort,...e&&e>0?{shellPort:e}:{},cwd:process.cwd(),startedAt:this.startedAt,heartbeatAt:Date.now(),source:"vite-dev"}}writeLockfileSnapshot(){X(this.buildLockfileSnapshot())}writeDevLockfileSnapshot(){Y(this.buildDevLockfileSnapshot())}refreshActiveRuntime(){this.activeRuntimeVersion=K(),this.activeRuntimeDirPath=se()??G()}runServerScan(){if(this.inflightScan)return this.inflightScan;let e=this.effectivePort>0?[this.effectivePort]:[];return this.inflightScan=P({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<o.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[bt]);return Number.isFinite(e)&&e>0?Math.max(100,Math.round(e)):vt}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
16
+ `),e}this.heartbeatTimer=setInterval(()=>{try{this.writeLockfileSnapshot()}catch{}},_e),this.heartbeatTimer.unref(),this.startRuntimeUpdater()}if(this.shouldWriteDevLockfile){try{this.writeDevLockfileSnapshot()}catch(e){process.stderr.write(`ws bridge failed to write dev bridge lockfile: ${String(e)}
17
+ `)}this.devHeartbeatTimer=setInterval(()=>{try{this.writeDevLockfileSnapshot()}catch{}},_e),this.devHeartbeatTimer.unref()}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}}buildDevLockfileSnapshot(){let e=this.getShellPort?.()??null;return{schema:1,pid:process.pid,platform:process.platform,bridgePort:this.effectivePort,runtimePort:this.effectivePort,...e&&e>0?{shellPort:e}:{},cwd:process.cwd(),startedAt:this.startedAt,heartbeatAt:Date.now(),source:"vite-dev"}}writeLockfileSnapshot(){X(this.buildLockfileSnapshot())}writeDevLockfileSnapshot(){Y(this.buildDevLockfileSnapshot())}refreshActiveRuntime(){this.activeRuntimeVersion=K(),this.activeRuntimeDirPath=se()??G()}runServerScan(){if(this.inflightScan)return this.inflightScan;let e=this.effectivePort>0?[this.effectivePort]:[];return this.inflightScan=P({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<o.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[bt]);return Number.isFinite(e)&&e>0?Math.max(100,Math.round(e)):vt}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
18
18
  `);let t=await ae();if(!t.updated||!t.latestVersion){e==="startup"&&process.stderr.write(`sootsim: runtime ${this.activeRuntimeVersion??"(none)"} is current
19
19
  `);return}let i=this.activeRuntimeVersion,s=this.setActiveRuntime(t.latestVersion);process.stderr.write(`sootsim runtime updated to ${s.version} (${e})
20
20
  `);try{J({from:i,to:s.version,at:Date.now()})}catch{}}catch(t){process.stderr.write(`sootsim runtime update failed (${e}): ${t instanceof Error?t.message:String(t)}
21
21
  `)}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
22
- `)}}})(),this.runtimeUpdateInFlight)}setActiveRuntime(e){if(V(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===h.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{U()}catch{}}handleHttpRequest(e,t){if(t.setHeader("Cross-Origin-Opener-Policy","same-origin"),t.setHeader("Cross-Origin-Embedder-Policy",ht),t.setHeader("Cross-Origin-Resource-Policy","cross-origin"),t.setHeader("Document-Policy","js-profiling"),Te(e.url)){Pe(e,t);return}if(Ee(e.url)&&Re(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 m=await fetch(l.toString(),{redirect:"follow"}),f={},y=m.headers.get("content-type");if(y&&(f["Content-Type"]=y),f["Cache-Control"]="no-store",t.writeHead(m.status,f),!m.body){t.end();return}let g=m.body.getReader();for(;;){let{done:b,value:w}=await g.read();if(b)break;t.write(Buffer.from(w))}t.end()}catch(m){t.writeHead(502,{"Content-Type":"text/plain"}),t.end(`bundle-proxy: upstream fetch failed: ${m instanceof Error?m.message:String(m)}`)}})();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,bridgeSource:this.shouldWriteDevLockfile?"vite-dev":this.shouldWriteLockfile?"daemon":"embedded",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(M())}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 a=s.pathname;if(a==="/runtime"||a==="/runtime/"?a="/":a.startsWith("/runtime/")?a=a.slice(8):a==="/sootsim"||a==="/sootsim/"?a="/":a.startsWith("/sootsim/")&&(a=a.slice(8)),(a===""||a==="/")&&(a="/index.html"),a.includes("\0")){t.writeHead(400),t.end("bad request");return}if(process.platform!=="win32"&&a.includes("\\")){t.writeHead(400),t.end("bad request");return}for(let d of a.split("/"))if(d===".."){t.writeHead(403),t.end("forbidden");return}let r=S.resolve(n,"."+a),c=n.endsWith(S.sep)?n:n+S.sep;if(!r.startsWith(c)&&r!==n){t.writeHead(403),t.end("forbidden");return}I.realpath(r,(d,l)=>{let u=d?r:l,p=u.endsWith(S.sep)?u:u+S.sep;if(!d){let m=(()=>{try{let f=I.realpathSync(n);return f.endsWith(S.sep)?f:f+S.sep}catch{return c}})();if(!p.startsWith(m)&&u+S.sep!==m){t.writeHead(403),t.end("forbidden");return}}I.stat(u,(m,f)=>{if(m||!f?.isFile()){let w=S.extname(a).toLowerCase();if(w&&w!==".html"){t.writeHead(404),t.end("not found");return}if(a.startsWith("/__")||a.startsWith("/api/")||a==="/api"){t.writeHead(404,{"Content-Type":"text/plain; charset=utf-8"}),t.end("not found");return}let N=S.join(n,"index.html");I.readFile(N,(Be,Ne)=>{if(Be){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(Oe(Ne,this.effectivePort,this.contrastOrigin))});return}let y=S.extname(u).toLowerCase(),g=wt[y]||"application/octet-stream";if(t.writeHead(200,{"Content-Type":g,"Cache-Control":"no-store"}),i==="HEAD"){t.end();return}if(y===".html"){I.readFile(u,(w,N)=>{if(w){try{t.end()}catch{}return}t.end(Oe(N,this.effectivePort,this.contrastOrigin))});return}let b=I.createReadStream(u);b.pipe(t),b.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<o.CLI_IDLE_TIMEOUT_MS)){this.cliSimBySocket.delete(i),this.cliLastCommandAt.delete(i);for(let[a,r]of this.cliBySentId)r.ws===i&&this.cliBySentId.delete(a);try{i.close(1e3,"idle timeout")}catch{}t=!0}}t&&this.broadcastSimClientStates(),this.sweepRestorableSims(e),this.reapIdleSims(e)}isAutomationSim(e){return e.meta?.sootsimHostDriver==="playwright"}automationSimOwnerAlive(e){let t=Number(e.meta?.sootsimHostPid);if(!Number.isInteger(t)||t<=1||t===process.pid)return!1;try{return process.kill(t,0),!0}catch(i){return i.code==="EPERM"}}reapIdleSims(e=Date.now()){let t=new Set(this.cliSimBySocket.values()),i=[];for(let n of this.sims.values()){if(n.id===this.primarySimId||t.has(n.id)||this.getActiveLease(n))continue;let a=Math.max(n.lastActiveAt,n.connectedAt),r=e-a,c=this.isAutomationSim(n);if(c&&this.automationSimOwnerAlive(n))continue;let d=c?this.automationSimIdleReapTtlMs:this.simIdleReapTtlMs;if(r>=d){this.closeSimSocketFromHost(n.ws);continue}c&&i.push({sim:n,idleMs:r})}let s=this.maxConcurrentAutomationSims;if(i.length>s){i.sort((n,a)=>a.idleMs-n.idleMs);for(let{sim:n,idleMs:a}of i.slice(0,i.length-s))a<this.automationSimActiveGraceMs||this.closeSimSocketFromHost(n.ws)}}sweepDeadWebSockets(){if(this.wss)for(let e of this.wss.clients){if(e.readyState!==h.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{}}}}closeSimSocketFromHost(e){if(e.readyState!==h.OPEN)return;try{e.close(re,ne)}catch{try{e.terminate()}catch{}return}let t=setTimeout(()=>{if(e.readyState!==h.CLOSED)try{e.terminate()}catch{}},St);Le(t)}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 a=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(a),this.pendingCommands.delete(i),this.broadcastSimClientStates(),s(d)},reject:d=>{clearTimeout(a),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}`,a=(c,d)=>new Promise(l=>{try{let u=ut(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 a(c[0],[...c.slice(1),"-g",n]))return}await a("cursor",["-g",n])||await a("code",["-g",n])||await this.openUrl(e)}async openUrl(e,t={}){if(this.openUrlHandler){await this.openUrlHandler(e,t);return}await oe(e,t)}async close(){if(this.cliIdleTimer&&(clearInterval(this.cliIdleTimer),this.cliIdleTimer=null),this.heartbeatTimer&&(clearInterval(this.heartbeatTimer),this.heartbeatTimer=null),this.devHeartbeatTimer&&(clearInterval(this.devHeartbeatTimer),this.devHeartbeatTimer=null),this.wsHeartbeatTimer&&(clearInterval(this.wsHeartbeatTimer),this.wsHeartbeatTimer=null),this.runtimeUpdateTimer&&(clearInterval(this.runtimeUpdateTimer),this.runtimeUpdateTimer=null),this.shouldWriteLockfile)try{U()}catch{}if(this.shouldWriteDevLockfile)try{Q()}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=h.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===h.OPEN?"open":t===h.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,userVisible:e.userVisible,visibilityState:e.visibilityState,documentFocused:e.documentFocused,kind:e.kind,meta:e.meta}}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),a=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-a)},bootedCount:0};if(r&&!c&&i.force)for(let[u,p]of this.cliSimBySocket){if(p!==t.id)continue;let m=this.cliIdentityKeyBySocket.get(u);if(m&&m!==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:a+o.CLI_LEASE_TTL_MS};return t.cliLease=l,{granted:!0,lease:l,bootedCount:d}}updateUserFocusLease(e,t){let i=t.focused===!0,s=typeof t.visible=="boolean"?t.visible:void 0,n=typeof t.visibilityState=="string"?t.visibilityState:void 0,a=typeof t.documentFocused=="boolean"?t.documentFocused:void 0;e.userFocused===i&&e.userVisible===s&&e.visibilityState===n&&e.documentFocused===a||(e.userFocused=i,e.userVisible=s,e.visibilityState=n,e.documentFocused=a,this.broadcastSimClientStates())}updateUserActivity(e){let t=this.getActiveLease(e);if(t&&t.kind==="cli")return;let s=Date.now()+o.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 s=this.sims.get(e);return s?.ws.readyState===h.OPEN?s:null}let t=this.primarySimId!=null?this.sims.get(this.primarySimId):null;if(t?.ws.readyState===h.OPEN&&t.url)return t;let i=null;for(let s of this.sims.values())if(s.ws.readyState===h.OPEN){if(s.url)return s;i??=s}return t?.ws.readyState===h.OPEN?t:i}async waitForSim(e,t={}){let i=t.attempts??10,s=t.intervalMs??200;for(let n=0;n<i;n++){let a=this.getOpenSim(e);if(a)return a;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;if(!e.url)return!t;let i=t?.ws.readyState===h.OPEN;if(!t||!i||!t.url)return!0;let s=e.origin?.includes(":5173"),n=t.origin?.includes(":5173");return!!s||!n}broadcastSimAssignments(){for(let e of this.sims.values())e.ws.readyState===h.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!==h.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,userVisible:e.userVisible,visibilityState:e.visibilityState,documentFocused:e.documentFocused};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 a=Date.now();n.lastActiveAt=a,n.recentActions=[{label:s,at:a},...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!==h.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,a]of this.cliSimBySocket){if(a!==t||n.readyState!==h.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===h.OPEN)return!1;let n=this.getRestorableSimState(i),a=e.id;this.sims.delete(a),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===a&&(this.primarySimId=e.id);for(let[r,c]of this.cliSimBySocket)c===a&&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()+o.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 At(){return!!((process.env.XPC_SERVICE_NAME||"").includes("dev.sootsim.daemon")||process.env.INVOCATION_ID)}async function mi(o,e={}){(o.includes("--help")||o.includes("-h"))&&(console.log(`
22
+ `)}}})(),this.runtimeUpdateInFlight)}setActiveRuntime(e){if(V(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===h.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{U()}catch{}}handleHttpRequest(e,t){if(t.setHeader("Cross-Origin-Opener-Policy","same-origin"),t.setHeader("Cross-Origin-Embedder-Policy",ht),t.setHeader("Cross-Origin-Resource-Policy","cross-origin"),t.setHeader("Document-Policy","js-profiling"),Te(e.url)){Pe(e,t);return}if(Ee(e.url)&&Re(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 m=await fetch(l.toString(),{redirect:"follow"}),f={},y=m.headers.get("content-type");if(y&&(f["Content-Type"]=y),f["Cache-Control"]="no-store",t.writeHead(m.status,f),!m.body){t.end();return}let g=m.body.getReader();for(;;){let{done:b,value:w}=await g.read();if(b)break;t.write(Buffer.from(w))}t.end()}catch(m){t.writeHead(502,{"Content-Type":"text/plain"}),t.end(`bundle-proxy: upstream fetch failed: ${m instanceof Error?m.message:String(m)}`)}})();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,bridgeSource:this.shouldWriteDevLockfile?"vite-dev":this.shouldWriteLockfile?"daemon":"embedded",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(M())}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 a=s.pathname;if(a==="/runtime"||a==="/runtime/"?a="/":a.startsWith("/runtime/")?a=a.slice(8):a==="/sootsim"||a==="/sootsim/"?a="/":a.startsWith("/sootsim/")&&(a=a.slice(8)),(a===""||a==="/")&&(a="/index.html"),a.includes("\0")){t.writeHead(400),t.end("bad request");return}if(process.platform!=="win32"&&a.includes("\\")){t.writeHead(400),t.end("bad request");return}for(let d of a.split("/"))if(d===".."){t.writeHead(403),t.end("forbidden");return}let r=S.resolve(n,"."+a),c=n.endsWith(S.sep)?n:n+S.sep;if(!r.startsWith(c)&&r!==n){t.writeHead(403),t.end("forbidden");return}I.realpath(r,(d,l)=>{let u=d?r:l,p=u.endsWith(S.sep)?u:u+S.sep;if(!d){let m=(()=>{try{let f=I.realpathSync(n);return f.endsWith(S.sep)?f:f+S.sep}catch{return c}})();if(!p.startsWith(m)&&u+S.sep!==m){t.writeHead(403),t.end("forbidden");return}}I.stat(u,(m,f)=>{if(m||!f?.isFile()){let w=S.extname(a).toLowerCase();if(w&&w!==".html"){t.writeHead(404),t.end("not found");return}if(a.startsWith("/__")||a.startsWith("/api/")||a==="/api"){t.writeHead(404,{"Content-Type":"text/plain; charset=utf-8"}),t.end("not found");return}let N=S.join(n,"index.html");I.readFile(N,(Be,Ne)=>{if(Be){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(Oe(Ne,this.effectivePort,this.contrastOrigin))});return}let y=S.extname(u).toLowerCase(),g=wt[y]||"application/octet-stream";if(t.writeHead(200,{"Content-Type":g,"Cache-Control":"no-store"}),i==="HEAD"){t.end();return}if(y===".html"){I.readFile(u,(w,N)=>{if(w){try{t.end()}catch{}return}t.end(Oe(N,this.effectivePort,this.contrastOrigin))});return}let b=I.createReadStream(u);b.pipe(t),b.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<o.CLI_IDLE_TIMEOUT_MS)continue;let a=!1;for(let r of this.cliBySentId.values())if(r.ws===i){a=!0;break}if(!a){this.cliSimBySocket.delete(i),this.cliLastCommandAt.delete(i);for(let[r,c]of this.cliBySentId)c.ws===i&&this.cliBySentId.delete(r);try{i.close(1e3,"idle timeout")}catch{}t=!0}}t&&this.broadcastSimClientStates(),this.sweepRestorableSims(e),this.reapIdleSims(e)}isAutomationSim(e){return e.meta?.sootsimHostDriver==="playwright"}automationSimOwnerAlive(e){let t=Number(e.meta?.sootsimHostPid);if(!Number.isInteger(t)||t<=1||t===process.pid)return!1;try{return process.kill(t,0),!0}catch(i){return i.code==="EPERM"}}reapIdleSims(e=Date.now()){let t=new Set(this.cliSimBySocket.values()),i=[];for(let n of this.sims.values()){if(n.id===this.primarySimId||t.has(n.id)||this.getActiveLease(n))continue;let a=Math.max(n.lastActiveAt,n.connectedAt),r=e-a,c=this.isAutomationSim(n);if(c&&this.automationSimOwnerAlive(n))continue;let d=c?this.automationSimIdleReapTtlMs:this.simIdleReapTtlMs;if(r>=d){this.closeSimSocketFromHost(n.ws);continue}c&&i.push({sim:n,idleMs:r})}let s=this.maxConcurrentAutomationSims;if(i.length>s){i.sort((n,a)=>a.idleMs-n.idleMs);for(let{sim:n,idleMs:a}of i.slice(0,i.length-s))a<this.automationSimActiveGraceMs||this.closeSimSocketFromHost(n.ws)}}sweepDeadWebSockets(){if(this.wss)for(let e of this.wss.clients){if(e.readyState!==h.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{}}}}closeSimSocketFromHost(e){if(e.readyState!==h.OPEN)return;try{e.close(re,ne)}catch{try{e.terminate()}catch{}return}let t=setTimeout(()=>{if(e.readyState!==h.CLOSED)try{e.terminate()}catch{}},St);Le(t)}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 a=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(a),this.pendingCommands.delete(i),this.broadcastSimClientStates(),s(d)},reject:d=>{clearTimeout(a),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}`,a=(c,d)=>new Promise(l=>{try{let u=ut(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 a(c[0],[...c.slice(1),"-g",n]))return}await a("cursor",["-g",n])||await a("code",["-g",n])||await this.openUrl(e)}async openUrl(e,t={}){if(this.openUrlHandler){await this.openUrlHandler(e,t);return}await oe(e,t)}async close(){if(this.cliIdleTimer&&(clearInterval(this.cliIdleTimer),this.cliIdleTimer=null),this.heartbeatTimer&&(clearInterval(this.heartbeatTimer),this.heartbeatTimer=null),this.devHeartbeatTimer&&(clearInterval(this.devHeartbeatTimer),this.devHeartbeatTimer=null),this.wsHeartbeatTimer&&(clearInterval(this.wsHeartbeatTimer),this.wsHeartbeatTimer=null),this.runtimeUpdateTimer&&(clearInterval(this.runtimeUpdateTimer),this.runtimeUpdateTimer=null),this.shouldWriteLockfile)try{U()}catch{}if(this.shouldWriteDevLockfile)try{Q()}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=h.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===h.OPEN?"open":t===h.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,userVisible:e.userVisible,visibilityState:e.visibilityState,documentFocused:e.documentFocused,kind:e.kind,meta:e.meta}}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),a=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-a)},bootedCount:0};if(r&&!c&&i.force)for(let[u,p]of this.cliSimBySocket){if(p!==t.id)continue;let m=this.cliIdentityKeyBySocket.get(u);if(m&&m!==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:a+o.CLI_LEASE_TTL_MS};return t.cliLease=l,{granted:!0,lease:l,bootedCount:d}}updateUserFocusLease(e,t){let i=t.focused===!0,s=typeof t.visible=="boolean"?t.visible:void 0,n=typeof t.visibilityState=="string"?t.visibilityState:void 0,a=typeof t.documentFocused=="boolean"?t.documentFocused:void 0;e.userFocused===i&&e.userVisible===s&&e.visibilityState===n&&e.documentFocused===a||(e.userFocused=i,e.userVisible=s,e.visibilityState=n,e.documentFocused=a,this.broadcastSimClientStates())}updateUserActivity(e){let t=this.getActiveLease(e);if(t&&t.kind==="cli")return;let s=Date.now()+o.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 s=this.sims.get(e);return s?.ws.readyState===h.OPEN?s:null}let t=this.primarySimId!=null?this.sims.get(this.primarySimId):null;if(t?.ws.readyState===h.OPEN&&t.url)return t;let i=null;for(let s of this.sims.values())if(s.ws.readyState===h.OPEN){if(s.url)return s;i??=s}return t?.ws.readyState===h.OPEN?t:i}async waitForSim(e,t={}){let i=t.attempts??10,s=t.intervalMs??200;for(let n=0;n<i;n++){let a=this.getOpenSim(e);if(a)return a;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;if(!e.url)return!t;let i=t?.ws.readyState===h.OPEN;if(!t||!i||!t.url)return!0;let s=e.origin?.includes(":5173"),n=t.origin?.includes(":5173");return!!s||!n}broadcastSimAssignments(){for(let e of this.sims.values())e.ws.readyState===h.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!==h.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,userVisible:e.userVisible,visibilityState:e.visibilityState,documentFocused:e.documentFocused};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 a=Date.now();n.lastActiveAt=a,n.recentActions=[{label:s,at:a},...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!==h.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,a]of this.cliSimBySocket){if(a!==t||n.readyState!==h.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===h.OPEN)return!1;let n=this.getRestorableSimState(i),a=e.id;this.sims.delete(a),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===a&&(this.primarySimId=e.id);for(let[r,c]of this.cliSimBySocket)c===a&&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()+o.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 At(){return!!((process.env.XPC_SERVICE_NAME||"").includes("dev.sootsim.daemon")||process.env.INVOCATION_ID)}async function mi(o,e={}){(o.includes("--help")||o.includes("-h"))&&(console.log(`
23
23
  sootsim serve \u2014 run the sootsim bridge in the foreground
24
24
 
25
25
  hosts the WS bridge that CLI commands talk to. once running, any sootsim
@@ -1,5 +1,5 @@
1
- /*! sootsim v0.1.230 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{a as g,b as k}from"./chunk-4UYMLSFL.js";import{b as S,c as x}from"./chunk-LULYUY7P.js";import{a as w}from"./chunk-EOXIIWK6.js";import"./chunk-XS72QD5F.js";import"./chunk-FLUDPGRE.js";import"./chunk-FG52DIVI.js";import"./chunk-CMNUMJPV.js";import"./chunk-UBMWVAU7.js";import"./chunk-TK7M5F6S.js";import"./chunk-THJZT2N5.js";import"./chunk-FFW4IVQI.js";import{H as v,M as f,O as m,l as b}from"./chunk-3M3HSRK2.js";import"./chunk-62YYON2N.js";import"./chunk-C3HOLPYO.js";import"./chunk-H6NIZEHS.js";import"./chunk-ROJCLUO7.js";import{existsSync as r,mkdirSync as j,readFileSync as d,readdirSync as I,writeFileSync as D}from"fs";import{basename as p,dirname as y,join as i,relative as c,resolve as h}from"path";var T=["bun","pnpm","npm"];async function pe(n){(n.includes("--help")||n.includes("-h"))&&(console.log(`
1
+ /*! sootsim v0.1.232 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{a as g,b as k}from"./chunk-SJCQEGF4.js";import{b as S,c as x}from"./chunk-K26I444J.js";import{a as w}from"./chunk-E5KVZJLZ.js";import"./chunk-M6UUHHFL.js";import"./chunk-UPVCNKFF.js";import"./chunk-XHHT4CMD.js";import"./chunk-LZK6NZLU.js";import"./chunk-N37Q2X3Z.js";import"./chunk-QCVNJSEN.js";import"./chunk-UQWDGKY7.js";import"./chunk-RMVUXVHN.js";import{H as v,M as f,O as m,l as b}from"./chunk-I6PFJTSC.js";import"./chunk-7VV57LAC.js";import"./chunk-ITX76FQB.js";import"./chunk-JSNKI3AX.js";import"./chunk-ZEFNMBSK.js";import{existsSync as r,mkdirSync as j,readFileSync as d,readdirSync as I,writeFileSync as D}from"fs";import{basename as p,dirname as y,join as i,relative as c,resolve as h}from"path";var T=["bun","pnpm","npm"];async function pe(n){(n.includes("--help")||n.includes("-h"))&&(console.log(`
3
3
  sootsim setup \u2014 set up this machine for SootSim
4
4
 
5
5
  usage:
@@ -94,4 +94,4 @@ module.exports = {
94
94
  4. inspect and drive it:
95
95
  sootsim describe
96
96
  sootsim do tap-text "Sign in"
97
- `)}function N(n,e){switch(n){case"bun":return`bunx ${e}`;case"pnpm":return`pnpm exec ${e}`;case"npm":return`npx ${e}`}}function ne(n,e){switch(n){case"bun":return`bun run ${e}`;case"pnpm":return`pnpm run ${e}`;case"npm":return`npm run ${e}`}}function oe(n){switch(n){case"bun":return"bun add -g sootsim";case"pnpm":return"pnpm add -g sootsim";case"npm":return"npm i -g sootsim"}}async function te(n,e){if(!e||n.dryRun)return;if(console.log(" last step:"),!process.stdin.isTTY){console.log(" run `sootsim open` after your Metro/Expo/One server is up");return}if(!await g("I'll run `sootsim open` for you now?",!0)){console.log(" later: sootsim open");return}let{runOpenCommand:o}=await import("./control-SG5Q4L64.js");await o([],{port:7668})}async function R(n,e,o){return o.yes?!0:process.stdin.isTTY?g(n,e):(console.log(` ${n} ${e?"[Y/n]":"[y/N]"} n (non-interactive; pass --yes to accept)`),!1)}export{J as detectConfigScaffoldExt,M as detectNodeVersionPins,W as detectPreferredPackageManager,E as readMachineSetupStatus,pe as runSetup,de as shouldRunSetupForBareCommand};
97
+ `)}function N(n,e){switch(n){case"bun":return`bunx ${e}`;case"pnpm":return`pnpm exec ${e}`;case"npm":return`npx ${e}`}}function ne(n,e){switch(n){case"bun":return`bun run ${e}`;case"pnpm":return`pnpm run ${e}`;case"npm":return`npm run ${e}`}}function oe(n){switch(n){case"bun":return"bun add -g sootsim";case"pnpm":return"pnpm add -g sootsim";case"npm":return"npm i -g sootsim"}}async function te(n,e){if(!e||n.dryRun)return;if(console.log(" last step:"),!process.stdin.isTTY){console.log(" run `sootsim open` after your Metro/Expo/One server is up");return}if(!await g("I'll run `sootsim open` for you now?",!0)){console.log(" later: sootsim open");return}let{runOpenCommand:o}=await import("./control-JFUKBGDB.js");await o([],{port:7668})}async function R(n,e,o){return o.yes?!0:process.stdin.isTTY?g(n,e):(console.log(` ${n} ${e?"[Y/n]":"[y/N]"} n (non-interactive; pass --yes to accept)`),!1)}export{J as detectConfigScaffoldExt,M as detectNodeVersionPins,W as detectPreferredPackageManager,E as readMachineSetupStatus,pe as runSetup,de as shouldRunSetupForBareCommand};
@@ -1,5 +1,5 @@
1
- /*! sootsim v0.1.230 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import"./chunk-ROJCLUO7.js";import*as i from"fs";import*as I from"os";import*as a from"path";import{fileURLToPath as h}from"url";function $(){try{let t=h(import.meta.resolve("sootsim/package.json"));return a.join(a.dirname(t),"skills")}catch{let t=a.dirname(h(import.meta.url));return a.resolve(t,"../../skills")}}var d=$(),w=new Set(["all","codex","claude"]);function S(){console.log(`sootsim skill
1
+ /*! sootsim v0.1.232 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import"./chunk-ZEFNMBSK.js";import*as i from"fs";import*as I from"os";import*as a from"path";import{fileURLToPath as h}from"url";function $(){try{let t=h(import.meta.resolve("sootsim/package.json"));return a.join(a.dirname(t),"skills")}catch{let t=a.dirname(h(import.meta.url));return a.resolve(t,"../../skills")}}var d=$(),w=new Set(["all","codex","claude"]);function S(){console.log(`sootsim skill
3
3
 
4
4
  install and inspect bundled SootSim agent skills.
5
5
 
@@ -1,5 +1,5 @@
1
- /*! sootsim v0.1.230 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{k as f}from"./chunk-TNT7TAX5.js";import"./chunk-OSKXFSEW.js";import"./chunk-FKE2NHET.js";import"./chunk-YVEZNXNW.js";import"./chunk-SS4WSBTW.js";import{a as t,b as n,c as l,d as c,e as a}from"./chunk-VSMUXKQV.js";import"./chunk-FZFB2OZS.js";import"./chunk-YDIPQ2J4.js";import"./chunk-4QXQNNAI.js";import"./chunk-TZBAMT3F.js";import"./chunk-JGGADCQK.js";import"./chunk-3SBXDOZZ.js";import"./chunk-O5Q4WUPP.js";import"./chunk-DUBC22VO.js";import"./chunk-SIU7QATA.js";import"./chunk-CMNUMJPV.js";import"./chunk-UBMWVAU7.js";import"./chunk-TK7M5F6S.js";import"./chunk-THJZT2N5.js";import"./chunk-FFW4IVQI.js";import"./chunk-3M3HSRK2.js";import"./chunk-HG4RA7CO.js";import"./chunk-H6NIZEHS.js";import"./chunk-ROJCLUO7.js";function p(){console.log(`
1
+ /*! sootsim v0.1.232 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{k as f}from"./chunk-IQ4GXAZH.js";import"./chunk-W7BAZFHN.js";import"./chunk-2QLL7ZTJ.js";import"./chunk-576MFPKR.js";import"./chunk-DQ3UVIWC.js";import{a as t,b as n,c as l,d as c,e as a}from"./chunk-2M62WMJ4.js";import"./chunk-GSM3KOU7.js";import"./chunk-LUDBC2J3.js";import"./chunk-K3QNZFXE.js";import"./chunk-JLFLM25R.js";import"./chunk-Z3VIVTZS.js";import"./chunk-NQJ6EHGW.js";import"./chunk-TA3JNI7A.js";import"./chunk-H4U7AD3S.js";import"./chunk-AJCLM5JM.js";import"./chunk-LZK6NZLU.js";import"./chunk-N37Q2X3Z.js";import"./chunk-QCVNJSEN.js";import"./chunk-UQWDGKY7.js";import"./chunk-RMVUXVHN.js";import"./chunk-I6PFJTSC.js";import"./chunk-DEPM3RAJ.js";import"./chunk-JSNKI3AX.js";import"./chunk-ZEFNMBSK.js";function p(){console.log(`
3
3
  sootsim storage profile \u2014 manage isolated storage profiles
4
4
 
5
5
  usage:
@@ -0,0 +1,2 @@
1
+ /*! sootsim v0.1.232 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{a}from"./chunk-DEPM3RAJ.js";import"./chunk-JSNKI3AX.js";import"./chunk-ZEFNMBSK.js";export{a as settingsStore};
@@ -0,0 +1,2 @@
1
+ /*! sootsim v0.1.232 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{a,b}from"./chunk-E5KVZJLZ.js";import"./chunk-M6UUHHFL.js";import"./chunk-I6PFJTSC.js";import"./chunk-ZEFNMBSK.js";export{b as flushCliTelemetry,a as trackCliEvent};
@@ -1,5 +1,5 @@
1
- /*! sootsim v0.1.230 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{g as m,i as d,l as s}from"./chunk-DUBC22VO.js";import"./chunk-TK7M5F6S.js";import"./chunk-THJZT2N5.js";import"./chunk-3M3HSRK2.js";import"./chunk-ROJCLUO7.js";import{writeFileSync as g}from"fs";function u(){console.log(`
1
+ /*! sootsim v0.1.232 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{g as m,i as d,l as s}from"./chunk-H4U7AD3S.js";import"./chunk-QCVNJSEN.js";import"./chunk-UQWDGKY7.js";import"./chunk-I6PFJTSC.js";import"./chunk-ZEFNMBSK.js";import{writeFileSync as g}from"fs";function u(){console.log(`
3
3
  sootsim timeline \u2014 control the semantic event timeline
4
4
 
5
5
  usage:
@@ -1,4 +1,4 @@
1
- /*! sootsim v0.1.230 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{a as d}from"./chunk-P4KO4ECO.js";import{e as m}from"./chunk-JS4CQN4E.js";import"./chunk-DUBC22VO.js";import"./chunk-TK7M5F6S.js";import"./chunk-THJZT2N5.js";import{K as a,g as r,h as l}from"./chunk-3M3HSRK2.js";import{a as c}from"./chunk-62YYON2N.js";import"./chunk-ROJCLUO7.js";import{spawn as g}from"node:child_process";import u from"node:fs";import p from"node:os";import e from"node:path";var f="https://registry.npmjs.org/sootsim/latest";async function j(o){let n=o.indexOf("--channel"),t=n>=0&&o[n+1]?o[n+1]:void 0;console.log(`sootsim upgrade
1
+ /*! sootsim v0.1.232 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{a as d}from"./chunk-FVAYMAX3.js";import{e as m}from"./chunk-NGTUX4OS.js";import"./chunk-H4U7AD3S.js";import"./chunk-QCVNJSEN.js";import"./chunk-UQWDGKY7.js";import{K as a,g as r,h as l}from"./chunk-I6PFJTSC.js";import{a as c}from"./chunk-7VV57LAC.js";import"./chunk-ZEFNMBSK.js";import{spawn as g}from"node:child_process";import u from"node:fs";import p from"node:os";import e from"node:path";var f="https://registry.npmjs.org/sootsim/latest";async function j(o){let n=o.indexOf("--channel"),t=n>=0&&o[n+1]?o[n+1]:void 0;console.log(`sootsim upgrade
3
3
  `),console.log("runtime:");let i=m();i&&(console.log(` pinned to ${i} \u2014 installing the pin, not channel latest`),console.log(" (run `sootsim runtime unpin` to follow latest again)")),await d(["install",...t?["--channel",t]:[]],{}),console.log(`
4
4
  cli:`),await $()}function h(){if(l())return{kind:"dev"};let o=process.argv[1]??"";try{o=u.realpathSync(o)}catch{}let n=e.sep;if(o.includes(`${n}_npx${n}`)||o.includes(`${n}.bunx${n}`))return{kind:"npx"};if(o.includes(`${n}.bun${n}`))return{kind:"global",command:"bun",args:["add","-g","sootsim@latest"]};if(o.includes(`${n}pnpm${n}`))return{kind:"global",command:"pnpm",args:["add","-g","sootsim@latest"]};let t=e.join(r(),"cli");if(o.startsWith(`${t}${n}`))return{kind:"global",command:"npm",args:["i","-g","--prefix",t,"sootsim@latest"]};let i=e.resolve(process.env.SOOTSIM_CLI_PREFIX||e.join(p.homedir(),".local"));return o.startsWith(`${i}${n}`)?{kind:"global",command:"npm",args:["i","-g","--prefix",i,"sootsim@latest"]}:{kind:"global",command:"npm",args:["i","-g","sootsim@latest"]}}async function $(){let o=c(),n=await k();if(!n){console.log(` v${o} \u2014 couldn't reach the npm registry, skipped`);return}if(a(n,o)<=0){console.log(` v${o} (latest)`);return}let t=h();if(console.log(` v${o} \u2192 v${n}`),t.kind==="dev"){console.log(" running from the Contrast dev checkout \u2014 pull instead of upgrading");return}if(t.kind==="npx"){console.log(" running from the npx cache \u2014 get the latest with:"),console.log(" npx sootsim@latest");return}let i=`${t.command} ${t.args.join(" ")}`;console.log(` updating global install (${i})\u2026`),await v(t.command,t.args)?console.log(` updated to v${n}`):(console.log(" update failed \u2014 run it yourself:"),console.log(` ${i}`))}function v(o,n){return new Promise(t=>{let i=g(o,n,{stdio:"inherit"});i.on("error",()=>t(!1)),i.on("exit",s=>t(s===0))})}async function k(){try{let o=await fetch(f,{headers:{accept:"application/json"},signal:AbortSignal.timeout(8e3)});if(!o.ok)return null;let n=await o.json();return typeof n.version=="string"&&n.version?n.version:null}catch{return null}}export{j as runUpgrade};
@@ -0,0 +1,2 @@
1
+ /*! sootsim v0.1.232 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{a,b,c}from"./chunk-GR3HSBBW.js";import"./chunk-3BQN6WRJ.js";import"./chunk-LUDBC2J3.js";import"./chunk-K3QNZFXE.js";import"./chunk-JLFLM25R.js";import"./chunk-H4U7AD3S.js";import"./chunk-E5KVZJLZ.js";import"./chunk-M6UUHHFL.js";import"./chunk-QCVNJSEN.js";import"./chunk-UQWDGKY7.js";import"./chunk-I6PFJTSC.js";import"./chunk-ZEFNMBSK.js";export{a as resolveDefaultUploadOrigin,b as resolvePublicPreviewOrigin,c as runUpload};
@@ -1,4 +1,4 @@
1
- /*! sootsim v0.1.230 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{b as s,d as l,i as r}from"./chunk-JS4CQN4E.js";import{a as i}from"./chunk-FG52DIVI.js";import"./chunk-3M3HSRK2.js";import{a as t}from"./chunk-62YYON2N.js";import"./chunk-ROJCLUO7.js";async function f(c){let{IS_BETA:m,BETA_LABEL:a}=await import("./beta-P3YYMVNZ.js"),u=m?` \xB7 ${a}`:"";console.log(`sootsim v${t()}${u}`);let o=i(),e=l();o.isDevBridge?(console.log(o.primary),o.installedRuntime&&console.log(`${o.installedRuntime} \xB7 ${e}`)):o.primary==="runtime not installed"?console.log("runtime not installed \u2014 run `sootsim runtime install`"):console.log(`${o.primary} \xB7 ${e}`);let n=await r({channel:e});n.pinned&&console.log(` runtime pinned to v${n.pinned} (\`sootsim runtime unpin\` to follow latest)`),n.outdated&&n.latest&&console.log(`
1
+ /*! sootsim v0.1.232 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{b as s,d as l,i as r}from"./chunk-NGTUX4OS.js";import{a as i}from"./chunk-XHHT4CMD.js";import"./chunk-I6PFJTSC.js";import{a as t}from"./chunk-7VV57LAC.js";import"./chunk-ZEFNMBSK.js";async function f(c){let{IS_BETA:m,BETA_LABEL:a}=await import("./beta-BNWNKZVD.js"),u=m?` \xB7 ${a}`:"";console.log(`sootsim v${t()}${u}`);let o=i(),e=l();o.isDevBridge?(console.log(o.primary),o.installedRuntime&&console.log(`${o.installedRuntime} \xB7 ${e}`)):o.primary==="runtime not installed"?console.log("runtime not installed \u2014 run `sootsim runtime install`"):console.log(`${o.primary} \xB7 ${e}`);let n=await r({channel:e});n.pinned&&console.log(` runtime pinned to v${n.pinned} (\`sootsim runtime unpin\` to follow latest)`),n.outdated&&n.latest&&console.log(`
3
3
  \u2191 runtime v${n.latest} available \u2014 run \`sootsim upgrade\``),console.log(`
4
4
  what's new: ${s}`)}export{f as runVersion};