sootsim 0.1.49 → 0.1.51

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 (134) hide show
  1. package/dist-cli/bin.js +3 -3
  2. package/dist-cli/chunks/{agent-RIH2MB5X.js → agent-RLBVAUCW.js} +2 -2
  3. package/dist-cli/chunks/{agent-wrapper-R2MFZVRV.js → agent-wrapper-TWLPNETE.js} +2 -2
  4. package/dist-cli/chunks/{assert-JLQWOTX6.js → assert-JLQSBZPM.js} +2 -2
  5. package/dist-cli/chunks/auto-bootstrap-UKUFJBJA.js +2 -0
  6. package/dist-cli/chunks/beta-4OEWPO5F.js +2 -0
  7. package/dist-cli/chunks/{chunk-F3CDHMRT.js → chunk-265YGINI.js} +2 -2
  8. package/dist-cli/chunks/{chunk-3PP3IWBX.js → chunk-2ZCJFJJN.js} +2 -2
  9. package/dist-cli/chunks/{chunk-IKTUA2CO.js → chunk-3BUWCNVX.js} +1 -1
  10. package/dist-cli/chunks/chunk-3HO4Q25D.js +1 -0
  11. package/dist-cli/chunks/{chunk-JL46FF4H.js → chunk-45XEBYVX.js} +2 -2
  12. package/dist-cli/chunks/chunk-4D7Z64YQ.js +2 -0
  13. package/dist-cli/chunks/{chunk-U5LVLKCJ.js → chunk-4QM4J2UK.js} +1 -1
  14. package/dist-cli/chunks/{chunk-FGWKT2BG.js → chunk-54IIO5BV.js} +1 -1
  15. package/dist-cli/chunks/{chunk-WISEXGFB.js → chunk-5PKYORP6.js} +1 -1
  16. package/dist-cli/chunks/{chunk-EB3HUXF3.js → chunk-67AZW4HJ.js} +1 -1
  17. package/dist-cli/chunks/{chunk-OHEI4R6Z.js → chunk-6NR6NFDC.js} +2 -2
  18. package/dist-cli/chunks/chunk-ACQXOAQI.js +2 -0
  19. package/dist-cli/chunks/{chunk-MBYU2XAP.js → chunk-AQN3BB3D.js} +1 -1
  20. package/dist-cli/chunks/{chunk-TX64GCH3.js → chunk-AWQGGSDW.js} +2 -2
  21. package/dist-cli/chunks/{chunk-NQHG45SY.js → chunk-BGZRRNK4.js} +1 -1
  22. package/dist-cli/chunks/{chunk-LI5EVOPD.js → chunk-BKXH674Z.js} +2 -2
  23. package/dist-cli/chunks/{chunk-SGPKAZCV.js → chunk-CLSZB5BN.js} +2 -2
  24. package/dist-cli/chunks/{chunk-6A6FR2CJ.js → chunk-DBHV5S2L.js} +1 -1
  25. package/dist-cli/chunks/{chunk-45N4MXK2.js → chunk-DBYZF6KL.js} +1 -1
  26. package/dist-cli/chunks/chunk-DV3SI64Q.js +1 -0
  27. package/dist-cli/chunks/{chunk-I2FJJCIM.js → chunk-EOYTPHOU.js} +1 -1
  28. package/dist-cli/chunks/{chunk-FKC2YBG4.js → chunk-ET5NKJVL.js} +3 -3
  29. package/dist-cli/chunks/chunk-EWSS4C2R.js +1 -0
  30. package/dist-cli/chunks/{chunk-2GKUXZWK.js → chunk-FSTOUA6L.js} +1 -1
  31. package/dist-cli/chunks/{chunk-BKOFXQX4.js → chunk-FUHHRW7G.js} +2 -2
  32. package/dist-cli/chunks/{chunk-QRZORMLG.js → chunk-HATEGE6O.js} +3 -3
  33. package/dist-cli/chunks/{chunk-I6QTUUXO.js → chunk-IENPCJTB.js} +2 -2
  34. package/dist-cli/chunks/{chunk-NH3HVEBX.js → chunk-IEYPDVW2.js} +2 -2
  35. package/dist-cli/chunks/{chunk-UJ6RXY6G.js → chunk-JZ65NOXB.js} +2 -2
  36. package/dist-cli/chunks/{chunk-KIFVYBHP.js → chunk-L4OPPOPY.js} +2 -2
  37. package/dist-cli/chunks/{chunk-NY4NHSFE.js → chunk-LMINUIAR.js} +1 -1
  38. package/dist-cli/chunks/{chunk-WHPM3DER.js → chunk-M7HK7MWE.js} +3 -3
  39. package/dist-cli/chunks/{chunk-QFEFKXKP.js → chunk-P2IC3VRD.js} +2 -2
  40. package/dist-cli/chunks/{chunk-3H4WRU4P.js → chunk-P45EZ2VW.js} +2 -2
  41. package/dist-cli/chunks/{chunk-CDA7FZAZ.js → chunk-PTW5KT4I.js} +2 -2
  42. package/dist-cli/chunks/{chunk-UEWDRHF5.js → chunk-RSEV5NWY.js} +2 -2
  43. package/dist-cli/chunks/{chunk-Q4U25XDO.js → chunk-SLAAAEUZ.js} +1 -1
  44. package/dist-cli/chunks/{chunk-BK6LB2J2.js → chunk-SPMHQKNI.js} +2 -2
  45. package/dist-cli/chunks/{chunk-7X7G5LUX.js → chunk-VDUWPVZT.js} +2 -2
  46. package/dist-cli/chunks/{chunk-VDO4QIU7.js → chunk-VR2UDTSA.js} +2 -2
  47. package/dist-cli/chunks/{chunk-H6MLMLDA.js → chunk-VXLRXQER.js} +2 -2
  48. package/dist-cli/chunks/{chunk-KNDSZOFN.js → chunk-XWHWPFBE.js} +1 -1
  49. package/dist-cli/chunks/{chunk-YBAH7I4N.js → chunk-ZEIDKF3M.js} +1 -1
  50. package/dist-cli/chunks/{chunk-UJ32JSVY.js → chunk-ZT7672XM.js} +2 -2
  51. package/dist-cli/chunks/{compat-QOIDS7MZ.js → compat-WUI6VQPS.js} +3 -3
  52. package/dist-cli/chunks/{config-EY4HKFQ7.js → config-XCFL4A6Z.js} +2 -2
  53. package/dist-cli/chunks/control-KE4VM2BN.js +2 -0
  54. package/dist-cli/chunks/{cpu-profile-PUNOCOLC.js → cpu-profile-CPOEDK5W.js} +2 -2
  55. package/dist-cli/chunks/{daemon-5O6DIBDJ.js → daemon-NFZOWPYN.js} +2 -2
  56. package/dist-cli/chunks/{debug-6AO2VBRJ.js → debug-G6FBH3B4.js} +3 -3
  57. package/dist-cli/chunks/demo-app-registry-U4FCHIYP.js +2 -0
  58. package/dist-cli/chunks/{detox-DEFSI2KS.js → detox-PUCPDKAO.js} +2 -2
  59. package/dist-cli/chunks/{device-QU55EQRU.js → device-IUUKTF7R.js} +2 -2
  60. package/dist-cli/chunks/{diagnose-SIEVP5B4.js → diagnose-6RY4YXSP.js} +2 -2
  61. package/dist-cli/chunks/drivers-2FY62QZA.js +2 -0
  62. package/dist-cli/chunks/{electron-FPVMIKJT.js → electron-HGY5WSFG.js} +3 -3
  63. package/dist-cli/chunks/flow-HEYPRCST.js +2 -0
  64. package/dist-cli/chunks/{hints-KCLDHB7T.js → hints-H7IVKEWB.js} +2 -2
  65. package/dist-cli/chunks/{home-paths-IBJQU7RM.js → home-paths-U5CDMYH5.js} +2 -2
  66. package/dist-cli/chunks/{inspect-BKIZONOF.js → inspect-6WSCE3W3.js} +3 -3
  67. package/dist-cli/chunks/install-NPNUNOL6.js +2 -0
  68. package/dist-cli/chunks/{install-desktop-GP33EN2X.js → install-desktop-QTZ3IBQW.js} +3 -3
  69. package/dist-cli/chunks/{keys-TBDYXC4R.js → keys-DCQXAY66.js} +2 -2
  70. package/dist-cli/chunks/{launch-JZQMS4NW.js → launch-FTHBNATG.js} +3 -3
  71. package/dist-cli/chunks/{login-4DLUDLZ3.js → login-4GUBAGPQ.js} +4 -4
  72. package/dist-cli/chunks/{logout-E34Y6MXJ.js → logout-N25HFETU.js} +2 -2
  73. package/dist-cli/chunks/{maestro-RRCPPV2E.js → maestro-WQBZZDTR.js} +2 -2
  74. package/dist-cli/chunks/{preview-CWJICLK5.js → preview-6MWJ6BSM.js} +2 -2
  75. package/dist-cli/chunks/{profile-6VAPGSFI.js → profile-UXJEGF4I.js} +2 -2
  76. package/dist-cli/chunks/{react-6MPJCXKW.js → react-MHPIWH3F.js} +2 -2
  77. package/dist-cli/chunks/{record-HOG5VIB2.js → record-K5DRP3G7.js} +2 -2
  78. package/dist-cli/chunks/runtime-UVFYTDXE.js +2 -0
  79. package/dist-cli/chunks/{runtime-delivery-RYYDAQ46.js → runtime-delivery-IIDHK55K.js} +2 -2
  80. package/dist-cli/chunks/{screenshot-AHVWVGYI.js → screenshot-MDE5ZSST.js} +2 -2
  81. package/dist-cli/chunks/{screenshot-mode-6LHQHMQW.js → screenshot-mode-7W7L7IN3.js} +2 -2
  82. package/dist-cli/chunks/{screenshots-B3DT4RLC.js → screenshots-24LEZPD7.js} +2 -2
  83. package/dist-cli/chunks/server-52HFHX3S.js +35 -0
  84. package/dist-cli/chunks/setup-repo-ZHEBGISP.js +2 -0
  85. package/dist-cli/chunks/{skills-3VZQLEIN.js → skills-3DGYETTU.js} +2 -2
  86. package/dist-cli/chunks/{start-I3DGKLZW.js → start-NFVPQX74.js} +4 -4
  87. package/dist-cli/chunks/store-R2RI4XAS.js +2 -0
  88. package/dist-cli/chunks/telemetry-KGU6DBN6.js +2 -0
  89. package/dist-cli/chunks/{test-P7YNHGTK.js → test-THI53N25.js} +3 -3
  90. package/dist-cli/chunks/{three-mode-J6KQLL2D.js → three-mode-HUI4SESE.js} +2 -2
  91. package/dist-cli/chunks/{timeline-JKUQP6UJ.js → timeline-KAJ6PR4S.js} +2 -2
  92. package/dist-cli/chunks/{upgrade-N5ZOEIM2.js → upgrade-APDFMQCW.js} +2 -2
  93. package/dist-cli/chunks/upload-K7OWH74D.js +2 -0
  94. package/dist-cli/chunks/{web-F42XPZXB.js → web-XDGC5KGT.js} +2 -2
  95. package/dist-cli/chunks/{what-happened-6OJNCJOZ.js → what-happened-4VMBEL5Z.js} +2 -2
  96. package/dist-cli/chunks/{whoami-6B3HFJX6.js → whoami-NJOQICNO.js} +2 -2
  97. package/dist-lib/agent-daemon-client.cjs +1 -1
  98. package/dist-lib/agent-events.cjs +1 -1
  99. package/dist-lib/agent-sessions.cjs +1 -1
  100. package/dist-lib/attached-projects.cjs +1 -1
  101. package/dist-lib/auth/shared-session.cjs +1 -1
  102. package/dist-lib/backend-origin.cjs +1 -1
  103. package/dist-lib/bridge-constants.cjs +9 -3
  104. package/dist-lib/cli-constants.cjs +1 -1
  105. package/dist-lib/config.cjs +1 -1
  106. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  107. package/dist-lib/home-paths.cjs +1 -1
  108. package/dist-lib/host/bridge-host.cjs +47 -1
  109. package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
  110. package/dist-lib/index.cjs +1 -1
  111. package/dist-lib/metro.cjs +1 -1
  112. package/dist-lib/profiles.cjs +1 -1
  113. package/dist-lib/render-mode.cjs +1 -1
  114. package/dist-lib/vite-base.cjs +49 -3
  115. package/dist-lib/vite.cjs +1 -1
  116. package/package.json +1 -1
  117. package/dist-cli/chunks/auto-bootstrap-AQ6Q4GHZ.js +0 -2
  118. package/dist-cli/chunks/beta-JPE3O53E.js +0 -2
  119. package/dist-cli/chunks/chunk-55O3YYWS.js +0 -1
  120. package/dist-cli/chunks/chunk-7KCT4PGT.js +0 -1
  121. package/dist-cli/chunks/chunk-EALHLLVY.js +0 -2
  122. package/dist-cli/chunks/chunk-FIBNBYEC.js +0 -1
  123. package/dist-cli/chunks/chunk-SNGLDQLQ.js +0 -1
  124. package/dist-cli/chunks/control-YWRLJWJ2.js +0 -2
  125. package/dist-cli/chunks/demo-app-registry-ZK4VFIIO.js +0 -2
  126. package/dist-cli/chunks/drivers-Z7KIP2FQ.js +0 -2
  127. package/dist-cli/chunks/flow-YDGY7D7Z.js +0 -2
  128. package/dist-cli/chunks/install-YEY7MINA.js +0 -2
  129. package/dist-cli/chunks/runtime-6MVRXE4J.js +0 -2
  130. package/dist-cli/chunks/server-ZZ4ITL2F.js +0 -35
  131. package/dist-cli/chunks/setup-repo-3EOWP4RO.js +0 -2
  132. package/dist-cli/chunks/store-JHPWUUUD.js +0 -2
  133. package/dist-cli/chunks/telemetry-HHOWU464.js +0 -2
  134. package/dist-cli/chunks/upload-IXQH633Z.js +0 -2
@@ -1,5 +1,5 @@
1
- /*! sootsim v0.1.49 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{E as F,r as S,s as k,t as g}from"./chunk-U5LVLKCJ.js";import{c as b,e as y}from"./chunk-LI5EVOPD.js";import{b as w}from"./chunk-WISEXGFB.js";import"./chunk-SNGLDQLQ.js";import"./chunk-2GKUXZWK.js";import"./chunk-IKTUA2CO.js";function M(t){let e=[];for(let n=0;n<t.length;n++)if(t[n]==="--since"&&n+1<t.length){e.push(n,n+1);let s=t[n+1].trim(),a=/^(\d+(?:\.\d+)?)(ms|s|m)?$/.exec(s);if(a){let l=Number(a[1]),u=a[2]??"ms",r=u==="s"?l*1e3:u==="m"?l*6e4:l;return{since:Date.now()-r,consumed:e}}let o=Number(s);if(Number.isFinite(o)&&o>1e12)return{since:o,consumed:e}}return{consumed:e}}function E(t){let e=[];for(let n=0;n<t.length;n++)if(t[n]==="--kinds"&&n+1<t.length)return e.push(n,n+1),{kinds:t[n+1].split(",").map(s=>s.trim()).filter(Boolean),consumed:e};return{consumed:e}}function C(t){let e=[];for(let n=0;n<t.length;n++)if(t[n]==="--limit"&&n+1<t.length){e.push(n,n+1);let s=Number(t[n+1]);if(Number.isFinite(s)&&s>0)return{limit:s,consumed:e}}return{consumed:e}}function _(t,e){if(e===null)return new Date(t).toLocaleTimeString();let n=(t-e)/1e3;return`${n>=0?"+":""}${n.toFixed(2)}s`}function j(t,e){switch(t){case"app-launch":return e.phase==="launch"?`launch ${e.appName??e.toAppId??""}`:`dismiss ${e.appName??e.fromAppId??""} \u2192 ${e.toAppId??""}`;case"toast":return`"${e.text??""}"${e.durationMs?` (${e.durationMs}ms)`:""}`;case"keyboard":return`${e.phase??"?"}${e.heightPx?` h=${e.heightPx}`:""}${e.mode?` ${e.mode}`:""}`;case"screen":return`${e.phase??"?"} ${e.name??e.activeName??""}`;case"route":return`${e.phase??"?"} ${e.path??e.pathname??""}`;case"alert":case"actionsheet":case"picker":return`${e.phase??"?"} ${e.title??e.message??""}`;case"notification":return`${e.title??""}${e.body?` \u2014 ${e.body}`:""}`;case"fetch":return`${e.method??"GET"} ${e.url??""}${e.status?` -> ${e.status}`:""}`;case"console":return`${e.level??"log"}: ${(e.message??"").toString().slice(0,120)}`;case"shell":return`${e.event??e.type??e.phase??""}`;case"scroll":return`${e.phase??"?"} ${e.target??""}`;case"gesture":return`${e.phase??"?"} ${e.type??""}`;case"text-input":return`${e.phase??"?"}${e.value!==void 0?` "${String(e.value).slice(0,40)}"`:""}`;case"react-commit":{let n=e.slowest;return`${e.fiberCount??"?"} fibers ${e.durationMs??"?"}ms${n?.displayName?` \xB7 ${n.displayName} ${n.durationMs??"?"}ms`:""}`}case"reanimated":case"animation":return`${e.kind??""} ${e.target??""}${e.durationMs?` ${e.durationMs}ms`:""}`}}function N(t,e){let n=_(t.t,e).padStart(8),s=t.context.padEnd(6),a=`[${t.kind}]`.padEnd(15),o="",l=t.data;return l&&typeof l=="object"&&(o=j(t.kind,l)),` ${n} ${s} ${a} ${o}`}function T(t){let e=[],n={label:"initial state",events:[],startedAt:t[0]?.t??null};e.push(n);for(let s of t)if(n.events.push(s),s.kind==="screen"||s.kind==="route"){let a=s.data,o=a?.phase;if(!o||o==="enter"||o==="appear"||o==="active"){let l=a?.name||a?.activeName||a?.path||a?.pathname||s.kind;e.length===1&&n.events.length===1?n.label=`${s.kind}: ${l}`:(n={label:`${s.kind}: ${l}`,events:[],startedAt:s.t},e.push(n))}}return e}async function O(t,e){let n=b(t,{port:e.port,stripBooleanFlags:["--summary","--all","--json","--no-advance","--help","-h","--flow"],stripValueFlags:["--since","--kinds","--limit"]});(t.includes("--help")||t.includes("-h"))&&(console.log(`
1
+ /*! sootsim v0.1.51 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{E as F,r as S,s as k,t as g}from"./chunk-4QM4J2UK.js";import{c as b,e as y}from"./chunk-BKXH674Z.js";import{b as w}from"./chunk-5PKYORP6.js";import"./chunk-ACQXOAQI.js";import"./chunk-FSTOUA6L.js";import"./chunk-3BUWCNVX.js";function M(t){let e=[];for(let n=0;n<t.length;n++)if(t[n]==="--since"&&n+1<t.length){e.push(n,n+1);let s=t[n+1].trim(),a=/^(\d+(?:\.\d+)?)(ms|s|m)?$/.exec(s);if(a){let l=Number(a[1]),u=a[2]??"ms",r=u==="s"?l*1e3:u==="m"?l*6e4:l;return{since:Date.now()-r,consumed:e}}let o=Number(s);if(Number.isFinite(o)&&o>1e12)return{since:o,consumed:e}}return{consumed:e}}function E(t){let e=[];for(let n=0;n<t.length;n++)if(t[n]==="--kinds"&&n+1<t.length)return e.push(n,n+1),{kinds:t[n+1].split(",").map(s=>s.trim()).filter(Boolean),consumed:e};return{consumed:e}}function C(t){let e=[];for(let n=0;n<t.length;n++)if(t[n]==="--limit"&&n+1<t.length){e.push(n,n+1);let s=Number(t[n+1]);if(Number.isFinite(s)&&s>0)return{limit:s,consumed:e}}return{consumed:e}}function _(t,e){if(e===null)return new Date(t).toLocaleTimeString();let n=(t-e)/1e3;return`${n>=0?"+":""}${n.toFixed(2)}s`}function j(t,e){switch(t){case"app-launch":return e.phase==="launch"?`launch ${e.appName??e.toAppId??""}`:`dismiss ${e.appName??e.fromAppId??""} \u2192 ${e.toAppId??""}`;case"toast":return`"${e.text??""}"${e.durationMs?` (${e.durationMs}ms)`:""}`;case"keyboard":return`${e.phase??"?"}${e.heightPx?` h=${e.heightPx}`:""}${e.mode?` ${e.mode}`:""}`;case"screen":return`${e.phase??"?"} ${e.name??e.activeName??""}`;case"route":return`${e.phase??"?"} ${e.path??e.pathname??""}`;case"alert":case"actionsheet":case"picker":return`${e.phase??"?"} ${e.title??e.message??""}`;case"notification":return`${e.title??""}${e.body?` \u2014 ${e.body}`:""}`;case"fetch":return`${e.method??"GET"} ${e.url??""}${e.status?` -> ${e.status}`:""}`;case"console":return`${e.level??"log"}: ${(e.message??"").toString().slice(0,120)}`;case"shell":return`${e.event??e.type??e.phase??""}`;case"scroll":return`${e.phase??"?"} ${e.target??""}`;case"gesture":return`${e.phase??"?"} ${e.type??""}`;case"text-input":return`${e.phase??"?"}${e.value!==void 0?` "${String(e.value).slice(0,40)}"`:""}`;case"react-commit":{let n=e.slowest;return`${e.fiberCount??"?"} fibers ${e.durationMs??"?"}ms${n?.displayName?` \xB7 ${n.displayName} ${n.durationMs??"?"}ms`:""}`}case"reanimated":case"animation":return`${e.kind??""} ${e.target??""}${e.durationMs?` ${e.durationMs}ms`:""}`}}function N(t,e){let n=_(t.t,e).padStart(8),s=t.context.padEnd(6),a=`[${t.kind}]`.padEnd(15),o="",l=t.data;return l&&typeof l=="object"&&(o=j(t.kind,l)),` ${n} ${s} ${a} ${o}`}function T(t){let e=[],n={label:"initial state",events:[],startedAt:t[0]?.t??null};e.push(n);for(let s of t)if(n.events.push(s),s.kind==="screen"||s.kind==="route"){let a=s.data,o=a?.phase;if(!o||o==="enter"||o==="appear"||o==="active"){let l=a?.name||a?.activeName||a?.path||a?.pathname||s.kind;e.length===1&&n.events.length===1?n.label=`${s.kind}: ${l}`:(n={label:`${s.kind}: ${l}`,events:[],startedAt:s.t},e.push(n))}}return e}async function O(t,e){let n=b(t,{port:e.port,stripBooleanFlags:["--summary","--all","--json","--no-advance","--help","-h","--flow"],stripValueFlags:["--since","--kinds","--limit"]});(t.includes("--help")||t.includes("-h"))&&(console.log(`
3
3
  sootsim what-happened \u2014 show recent events from the semantic timeline
4
4
 
5
5
  usage:
@@ -1,2 +1,2 @@
1
- /*! sootsim v0.1.49 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{d as i}from"./chunk-OHEI4R6Z.js";import{d as n}from"./chunk-QFEFKXKP.js";import"./chunk-2GKUXZWK.js";import"./chunk-IKTUA2CO.js";async function u(){let o=i();if(o||(console.log(" not signed in"),console.log(" set SOOTSIM_API_KEY=sk_sootsim_\u2026 or run `sootsim login`"),process.exit(1)),o.kind==="api-key"){let r=`${o.secret.slice(0,14)}\u2026`,t=o.source==="env"?"SOOTSIM_API_KEY env var":"saved key (~/.config/sootsim/credentials.json)";console.log(` api key ${r}`),console.log(` source: ${t}`);return}if(o.kind==="github"){console.log(` github token (${o.source})`),console.log(` repo: ${o.repoId}`);return}let e=await n(),s=e?.user;console.log(` ${s?.email||s?.name||s?.id||"signed in"}`),console.log(` origin: ${e?.origin??o.origin}`),e?.updatedAt&&console.log(` updated: ${e.updatedAt}`)}export{u as runWhoami};
1
+ /*! sootsim v0.1.51 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import{d as i}from"./chunk-6NR6NFDC.js";import{d as n}from"./chunk-P2IC3VRD.js";import"./chunk-FSTOUA6L.js";import"./chunk-3BUWCNVX.js";async function u(){let o=i();if(o||(console.log(" not signed in"),console.log(" set SOOTSIM_API_KEY=sk_sootsim_\u2026 or run `sootsim login`"),process.exit(1)),o.kind==="api-key"){let r=`${o.secret.slice(0,14)}\u2026`,t=o.source==="env"?"SOOTSIM_API_KEY env var":"saved key (~/.config/sootsim/credentials.json)";console.log(` api key ${r}`),console.log(` source: ${t}`);return}if(o.kind==="github"){console.log(` github token (${o.source})`),console.log(` repo: ${o.repoId}`);return}let e=await n(),s=e?.user;console.log(` ${s?.email||s?.name||s?.id||"signed in"}`),console.log(` origin: ${e?.origin??o.origin}`),e?.updatedAt&&console.log(` updated: ${e.updatedAt}`)}export{u as runWhoami};
@@ -1,4 +1,4 @@
1
- /*! sootsim v0.1.49 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.51 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -1,4 +1,4 @@
1
- /*! sootsim v0.1.49 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.51 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! sootsim v0.1.49 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.51 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -1,4 +1,4 @@
1
- /*! sootsim v0.1.49 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.51 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -1,4 +1,4 @@
1
- /*! sootsim v0.1.49 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.51 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -1,4 +1,4 @@
1
- /*! sootsim v0.1.49 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.51 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! sootsim v0.1.49 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.51 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -22,11 +22,17 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
22
22
  // src/bridge-constants.ts
23
23
  var bridge_constants_exports = {};
24
24
  __export(bridge_constants_exports, {
25
- DEFAULT_SOOTSIM_BRIDGE_PORT: () => DEFAULT_SOOTSIM_BRIDGE_PORT
25
+ DEFAULT_SOOTSIM_BRIDGE_PORT: () => DEFAULT_SOOTSIM_BRIDGE_PORT,
26
+ SOOTSIM_BRIDGE_SIM_CLOSE_CODE: () => SOOTSIM_BRIDGE_SIM_CLOSE_CODE,
27
+ SOOTSIM_BRIDGE_SIM_CLOSE_REASON: () => SOOTSIM_BRIDGE_SIM_CLOSE_REASON
26
28
  });
27
29
  module.exports = __toCommonJS(bridge_constants_exports);
28
30
  var DEFAULT_SOOTSIM_BRIDGE_PORT = 7668;
31
+ var SOOTSIM_BRIDGE_SIM_CLOSE_CODE = 4001;
32
+ var SOOTSIM_BRIDGE_SIM_CLOSE_REASON = "sootsim close";
29
33
  // Annotate the CommonJS export names for ESM import in node:
30
34
  0 && (module.exports = {
31
- DEFAULT_SOOTSIM_BRIDGE_PORT
35
+ DEFAULT_SOOTSIM_BRIDGE_PORT,
36
+ SOOTSIM_BRIDGE_SIM_CLOSE_CODE,
37
+ SOOTSIM_BRIDGE_SIM_CLOSE_REASON
32
38
  });
@@ -1,4 +1,4 @@
1
- /*! sootsim v0.1.49 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.51 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! sootsim v0.1.49 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.51 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! sootsim v0.1.49 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.51 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! sootsim v0.1.49 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.51 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -1,4 +1,4 @@
1
- /*! sootsim v0.1.49 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.51 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -1225,6 +1225,8 @@ async function scanDevServers(opts = {}) {
1225
1225
 
1226
1226
  // src/bridge-constants.ts
1227
1227
  var DEFAULT_SOOTSIM_BRIDGE_PORT = 7668;
1228
+ var SOOTSIM_BRIDGE_SIM_CLOSE_CODE = 4001;
1229
+ var SOOTSIM_BRIDGE_SIM_CLOSE_REASON = "sootsim close";
1228
1230
 
1229
1231
  // src/cli-version.ts
1230
1232
  var import_node_fs2 = require("node:fs");
@@ -3178,6 +3180,8 @@ async function openUrl(url, options = {}) {
3178
3180
 
3179
3181
  // src/host/bridge-host.ts
3180
3182
  var WRITE_COMMAND_TYPES = /* @__PURE__ */ new Set(["tap", "keyboard", "close"]);
3183
+ var FORCE_CLOSE_GRACE_MS = 2e3;
3184
+ var FORCE_CLOSE_TERMINATE_MS = 1e3;
3181
3185
  function shouldAcquireLease(msg) {
3182
3186
  if (!msg || typeof msg.type !== "string") return false;
3183
3187
  if (msg.acquireLock === true) return true;
@@ -3226,6 +3230,12 @@ function injectSharedConfigIntoHtml(data, bridgePort, sootbeanOrigin) {
3226
3230
  if (html.includes("</body>")) return html.replace("</body>", tag + "</body>");
3227
3231
  return tag + html;
3228
3232
  }
3233
+ function unrefTimer(timer) {
3234
+ if (typeof timer === "object" && timer !== null && "unref" in timer) {
3235
+ ;
3236
+ timer.unref();
3237
+ }
3238
+ }
3229
3239
  var SootSimBridgeHost = class _SootSimBridgeHost {
3230
3240
  port;
3231
3241
  openUrlHandler;
@@ -3715,6 +3725,22 @@ var SootSimBridgeHost = class _SootSimBridgeHost {
3715
3725
  });
3716
3726
  const { simId: _simId, ...forwarded } = msg;
3717
3727
  targetSim.ws.send(JSON.stringify({ ...forwarded, id: sentId }));
3728
+ if (forwarded.type === "close") {
3729
+ this.cliBySentId.delete(sentId);
3730
+ if (ws.readyState === import_ws.WebSocket.OPEN) {
3731
+ ws.send(
3732
+ JSON.stringify({
3733
+ id: msg.id,
3734
+ result: { requested: true, simId: targetSim.id }
3735
+ })
3736
+ );
3737
+ }
3738
+ const simWs = targetSim.ws;
3739
+ const closeTimer = setTimeout(() => {
3740
+ this.closeSimSocketFromHost(simWs);
3741
+ }, FORCE_CLOSE_GRACE_MS);
3742
+ unrefTimer(closeTimer);
3743
+ }
3718
3744
  } catch (err) {
3719
3745
  if (ws.readyState === import_ws.WebSocket.OPEN) {
3720
3746
  ws.send(
@@ -4262,6 +4288,26 @@ var SootSimBridgeHost = class _SootSimBridgeHost {
4262
4288
  }
4263
4289
  }
4264
4290
  }
4291
+ closeSimSocketFromHost(ws) {
4292
+ if (ws.readyState !== import_ws.WebSocket.OPEN) return;
4293
+ try {
4294
+ ws.close(SOOTSIM_BRIDGE_SIM_CLOSE_CODE, SOOTSIM_BRIDGE_SIM_CLOSE_REASON);
4295
+ } catch {
4296
+ try {
4297
+ ws.terminate();
4298
+ } catch {
4299
+ }
4300
+ return;
4301
+ }
4302
+ const terminateTimer = setTimeout(() => {
4303
+ if (ws.readyState === import_ws.WebSocket.CLOSED) return;
4304
+ try {
4305
+ ws.terminate();
4306
+ } catch {
4307
+ }
4308
+ }, FORCE_CLOSE_TERMINATE_MS);
4309
+ unrefTimer(terminateTimer);
4310
+ }
4265
4311
  listSims() {
4266
4312
  return Array.from(this.sims.values()).sort((a, b) => {
4267
4313
  if (a.id === this.primarySimId) return -1;
@@ -1,4 +1,4 @@
1
- /*! sootsim v0.1.49 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.51 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -1,4 +1,4 @@
1
- /*! sootsim v0.1.49 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.51 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -1,4 +1,4 @@
1
- /*! sootsim v0.1.49 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.51 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -1,4 +1,4 @@
1
- /*! sootsim v0.1.49 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.51 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -1,4 +1,4 @@
1
- /*! sootsim v0.1.49 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.51 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! sootsim v0.1.49 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.51 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -33,11 +33,13 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
33
33
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
34
34
 
35
35
  // src/bridge-constants.ts
36
- var DEFAULT_SOOTSIM_BRIDGE_PORT;
36
+ var DEFAULT_SOOTSIM_BRIDGE_PORT, SOOTSIM_BRIDGE_SIM_CLOSE_CODE, SOOTSIM_BRIDGE_SIM_CLOSE_REASON;
37
37
  var init_bridge_constants = __esm({
38
38
  "src/bridge-constants.ts"() {
39
39
  "use strict";
40
40
  DEFAULT_SOOTSIM_BRIDGE_PORT = 7668;
41
+ SOOTSIM_BRIDGE_SIM_CLOSE_CODE = 4001;
42
+ SOOTSIM_BRIDGE_SIM_CLOSE_REASON = "sootsim close";
41
43
  }
42
44
  });
43
45
 
@@ -3287,7 +3289,13 @@ function injectSharedConfigIntoHtml(data, bridgePort, sootbeanOrigin) {
3287
3289
  if (html.includes("</body>")) return html.replace("</body>", tag + "</body>");
3288
3290
  return tag + html;
3289
3291
  }
3290
- var import_child_process4, import_fs3, import_http3, import_path3, import_ws, WRITE_COMMAND_TYPES, DAEMON_HEARTBEAT_INTERVAL_MS, DEFAULT_RUNTIME_UPDATE_INTERVAL_MS, RUNTIME_UPDATE_INTERVAL_ENV, HTTP_MIME_TYPES, SootSimBridgeHost;
3292
+ function unrefTimer(timer) {
3293
+ if (typeof timer === "object" && timer !== null && "unref" in timer) {
3294
+ ;
3295
+ timer.unref();
3296
+ }
3297
+ }
3298
+ var import_child_process4, import_fs3, import_http3, import_path3, import_ws, WRITE_COMMAND_TYPES, FORCE_CLOSE_GRACE_MS, FORCE_CLOSE_TERMINATE_MS, DAEMON_HEARTBEAT_INTERVAL_MS, DEFAULT_RUNTIME_UPDATE_INTERVAL_MS, RUNTIME_UPDATE_INTERVAL_ENV, HTTP_MIME_TYPES, SootSimBridgeHost;
3291
3299
  var init_bridge_host = __esm({
3292
3300
  "src/host/bridge-host.ts"() {
3293
3301
  "use strict";
@@ -3305,6 +3313,8 @@ var init_bridge_host = __esm({
3305
3313
  init_fetch_proxy_handler();
3306
3314
  init_open_url();
3307
3315
  WRITE_COMMAND_TYPES = /* @__PURE__ */ new Set(["tap", "keyboard", "close"]);
3316
+ FORCE_CLOSE_GRACE_MS = 2e3;
3317
+ FORCE_CLOSE_TERMINATE_MS = 1e3;
3308
3318
  DAEMON_HEARTBEAT_INTERVAL_MS = 5e3;
3309
3319
  DEFAULT_RUNTIME_UPDATE_INTERVAL_MS = 60 * 60 * 1e3;
3310
3320
  RUNTIME_UPDATE_INTERVAL_ENV = "SOOTSIM_RUNTIME_UPDATE_INTERVAL_MS";
@@ -3820,6 +3830,22 @@ var init_bridge_host = __esm({
3820
3830
  });
3821
3831
  const { simId: _simId, ...forwarded } = msg;
3822
3832
  targetSim.ws.send(JSON.stringify({ ...forwarded, id: sentId }));
3833
+ if (forwarded.type === "close") {
3834
+ this.cliBySentId.delete(sentId);
3835
+ if (ws.readyState === import_ws.WebSocket.OPEN) {
3836
+ ws.send(
3837
+ JSON.stringify({
3838
+ id: msg.id,
3839
+ result: { requested: true, simId: targetSim.id }
3840
+ })
3841
+ );
3842
+ }
3843
+ const simWs = targetSim.ws;
3844
+ const closeTimer = setTimeout(() => {
3845
+ this.closeSimSocketFromHost(simWs);
3846
+ }, FORCE_CLOSE_GRACE_MS);
3847
+ unrefTimer(closeTimer);
3848
+ }
3823
3849
  } catch (err) {
3824
3850
  if (ws.readyState === import_ws.WebSocket.OPEN) {
3825
3851
  ws.send(
@@ -4367,6 +4393,26 @@ var init_bridge_host = __esm({
4367
4393
  }
4368
4394
  }
4369
4395
  }
4396
+ closeSimSocketFromHost(ws) {
4397
+ if (ws.readyState !== import_ws.WebSocket.OPEN) return;
4398
+ try {
4399
+ ws.close(SOOTSIM_BRIDGE_SIM_CLOSE_CODE, SOOTSIM_BRIDGE_SIM_CLOSE_REASON);
4400
+ } catch {
4401
+ try {
4402
+ ws.terminate();
4403
+ } catch {
4404
+ }
4405
+ return;
4406
+ }
4407
+ const terminateTimer = setTimeout(() => {
4408
+ if (ws.readyState === import_ws.WebSocket.CLOSED) return;
4409
+ try {
4410
+ ws.terminate();
4411
+ } catch {
4412
+ }
4413
+ }, FORCE_CLOSE_TERMINATE_MS);
4414
+ unrefTimer(terminateTimer);
4415
+ }
4370
4416
  listSims() {
4371
4417
  return Array.from(this.sims.values()).sort((a, b) => {
4372
4418
  if (a.id === this.primarySimId) return -1;
package/dist-lib/vite.cjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! sootsim v0.1.49 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.51 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sootsim",
3
- "version": "0.1.49",
3
+ "version": "0.1.51",
4
4
  "description": "sootsim CLI + vite/metro plugins + skills registry. bridge client for driving the proprietary sootsim-engine over WebSocket.",
5
5
  "author": "Tamagui LLC",
6
6
  "license": "MIT",
@@ -1,2 +0,0 @@
1
- /*! sootsim v0.1.49 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{a,b,c,d}from"./chunk-QRZORMLG.js";import"./chunk-LI5EVOPD.js";import"./chunk-WISEXGFB.js";import"./chunk-SNGLDQLQ.js";import"./chunk-2GKUXZWK.js";import"./chunk-IKTUA2CO.js";export{c as ensureDaemonRunning,a as ensureRuntimeInstalled,d as ensureSootsimReady,b as resolveBootstrapPort};
@@ -1,2 +0,0 @@
1
- /*! sootsim v0.1.49 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{a,b,c,d,e}from"./chunk-YBAH7I4N.js";import"./chunk-IKTUA2CO.js";export{e as BETA_ASK_HEADLINE,c as BETA_LABEL,d as BETA_TAGLINE,b as BETA_VERSION_TARGET,a as IS_BETA};
@@ -1 +0,0 @@
1
- /*! sootsim v0.1.49 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
@@ -1 +0,0 @@
1
- /*! sootsim v0.1.49 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
@@ -1,2 +0,0 @@
1
- /*! sootsim v0.1.49 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- var t="http://localhost:5173/";export{t as a};
@@ -1 +0,0 @@
1
- /*! sootsim v0.1.49 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
@@ -1 +0,0 @@
1
- /*! sootsim v0.1.49 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
@@ -1,2 +0,0 @@
1
- /*! sootsim v0.1.49 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{d as a,e as b,f as c,g as d,h as e,i as f,j as g,k as h,l as i,m as j,n as k,o as l,p as m}from"./chunk-UJ32JSVY.js";import"./chunk-Q4U25XDO.js";import"./chunk-NY4NHSFE.js";import"./chunk-F3CDHMRT.js";import"./chunk-45N4MXK2.js";import"./chunk-7X7G5LUX.js";import"./chunk-FIBNBYEC.js";import"./chunk-NQHG45SY.js";import"./chunk-EALHLLVY.js";import"./chunk-LI5EVOPD.js";import"./chunk-WISEXGFB.js";import"./chunk-SNGLDQLQ.js";import"./chunk-2GKUXZWK.js";import"./chunk-IKTUA2CO.js";export{d as buildOpenUrl,c as buildShellUrl,f as printConnectedSims,a as resolveBundleTarget,b as resolveDefaultShellBaseUrl,l as runClaimCommand,m as runCloseCommand,k as runFocusCommand,h as runListCommand,i as runOpenCommand,j as runUseCommand,e as summarizeSimUrl,g as waitForSimMatch};
@@ -1,2 +0,0 @@
1
- /*! sootsim v0.1.49 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{a}from"./chunk-BKOFXQX4.js";import"./chunk-IKTUA2CO.js";export{a as APPS};
@@ -1,2 +0,0 @@
1
- /*! sootsim v0.1.49 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import"./chunk-55O3YYWS.js";import{a,b,c,d,e,f,g,h,i}from"./chunk-F3CDHMRT.js";import"./chunk-45N4MXK2.js";import"./chunk-7X7G5LUX.js";import"./chunk-FIBNBYEC.js";import"./chunk-NQHG45SY.js";import"./chunk-2GKUXZWK.js";import"./chunk-IKTUA2CO.js";export{e as ALL_DRIVERS,i as buildDriverListRows,a as chromiumDriver,b as electronDriver,f as getAllDrivers,g as getDriver,c as playwrightDriver,h as resolveDriver,d as systemDriver};
@@ -1,2 +0,0 @@
1
- /*! sootsim v0.1.49 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{a,b,c,d}from"./chunk-FKC2YBG4.js";import"./chunk-TX64GCH3.js";import"./chunk-CDA7FZAZ.js";import"./chunk-7KCT4PGT.js";import"./chunk-NH3HVEBX.js";import"./chunk-BK6LB2J2.js";import"./chunk-UJ32JSVY.js";import"./chunk-Q4U25XDO.js";import"./chunk-NY4NHSFE.js";import"./chunk-F3CDHMRT.js";import"./chunk-45N4MXK2.js";import"./chunk-7X7G5LUX.js";import"./chunk-BKOFXQX4.js";import"./chunk-I6QTUUXO.js";import"./chunk-OHEI4R6Z.js";import"./chunk-FIBNBYEC.js";import"./chunk-NQHG45SY.js";import"./chunk-VDO4QIU7.js";import"./chunk-EALHLLVY.js";import"./chunk-JL46FF4H.js";import"./chunk-EB3HUXF3.js";import"./chunk-LI5EVOPD.js";import"./chunk-WISEXGFB.js";import"./chunk-H6MLMLDA.js";import"./chunk-QFEFKXKP.js";import"./chunk-SNGLDQLQ.js";import"./chunk-2GKUXZWK.js";import"./chunk-IKTUA2CO.js";export{b as discoverSootsimUrl,a as parseFlowFile,d as runFlow,c as runFlowPlayback};
@@ -1,2 +0,0 @@
1
- /*! sootsim v0.1.49 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{a as o}from"./chunk-UEWDRHF5.js";import"./chunk-MBYU2XAP.js";import"./chunk-QRZORMLG.js";import"./chunk-LI5EVOPD.js";import"./chunk-WISEXGFB.js";import"./chunk-H6MLMLDA.js";import"./chunk-QFEFKXKP.js";import"./chunk-SNGLDQLQ.js";import"./chunk-2GKUXZWK.js";import"./chunk-IKTUA2CO.js";async function t(n){console.error(" note: `sootsim install` is now `sootsim setup-repo`. forwarding\u2026\n"),await o(n)}export{t as runInstall};
@@ -1,2 +0,0 @@
1
- /*! sootsim v0.1.49 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{a}from"./chunk-WHPM3DER.js";import"./chunk-LI5EVOPD.js";import"./chunk-WISEXGFB.js";import"./chunk-SGPKAZCV.js";import"./chunk-SNGLDQLQ.js";import"./chunk-2GKUXZWK.js";import"./chunk-IKTUA2CO.js";export{a as runRuntime};
@@ -1,35 +0,0 @@
1
- /*! sootsim v0.1.49 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{b as Z,c as D,d as Q,e as H,f as ee,h as te,i as A,j as ie,k as re,l as ne,p as se,s as k,t as oe,u as ae,v as ce,w as de}from"./chunk-KIFVYBHP.js";import"./chunk-6A6FR2CJ.js";import{a as E}from"./chunk-TX64GCH3.js";import"./chunk-Q4U25XDO.js";import"./chunk-BKOFXQX4.js";import{a as X}from"./chunk-I6QTUUXO.js";import"./chunk-OHEI4R6Z.js";import"./chunk-FIBNBYEC.js";import{d as z}from"./chunk-NQHG45SY.js";import{a as U}from"./chunk-FGWKT2BG.js";import"./chunk-LI5EVOPD.js";import"./chunk-WISEXGFB.js";import{k as Y}from"./chunk-SGPKAZCV.js";import{a as G,b as q}from"./chunk-H6MLMLDA.js";import"./chunk-QFEFKXKP.js";import"./chunk-SNGLDQLQ.js";import{A as F,B as L,D as j,E as $,F as J,G as K,H as V,I as N,u as B,v as M,y as T,z as W}from"./chunk-2GKUXZWK.js";import"./chunk-IKTUA2CO.js";import{spawn as Ie}from"child_process";import w from"fs";import{createServer as Pe}from"http";import S from"path";import{WebSocket as m,WebSocketServer as xe}from"ws";import le from"node:fs";import I from"node:path";var P=1;function ye(){return[Number(process.env.VITE_PORT_WEB||process.env.PORT||3e3),Number(process.env.VITE_PORT_ZERO||7849),Number(process.env.VITE_PORT_POSTGRES||7432),Number(process.env.VITE_PORT_R2||9500)].filter(a=>Number.isFinite(a)&&a>0)}var x=class{subscriptions=new Map;sessionsBySocket=new Map;allSockets=new Set;pendingPromptEchoes=new Map;pendingTurns=new Map;opts;constructor(e={}){this.opts=e}registerSocket(e){this.allSockets.add(e)}unregisterSocket(e){let t=this.sessionsBySocket.get(e);if(t){for(let i of t)this.decrementSubscription(i);this.sessionsBySocket.delete(e)}this.allSockets.delete(e)}async handleMessage(e,t){let i=t?.type;if(typeof i!="string"||!i.startsWith("agent:"))return!1;let o=t.id;try{let n=await this.dispatch(e,i,t);this.respond(e,o,n)}catch(n){n instanceof k?this.respondError(e,o,n.message,n.code):this.respondError(e,o,n instanceof Error?n.message:String(n))}return!0}async seedOnBoot(){try{await ne()}catch(e){process.stderr.write(`[sootsim-agent] seedFromDemoAppRegistry failed: ${e instanceof Error?e.message:String(e)}
3
- `)}}close(){for(let e of this.subscriptions.values())try{e.unsubscribe()}catch{}this.subscriptions.clear(),this.sessionsBySocket.clear(),this.allSockets.clear()}async dispatch(e,t,i){switch(t){case"agent:list-projects":return H();case"agent:upsert-project":return D(i.input??{});case"agent:delete-project":return te(String(i.projectId)),{ok:!0};case"agent:auto-attach-for-url":return this.autoAttachForUrl(i.input??{});case"agent:list-sessions":return ie(i.projectId?String(i.projectId):void 0);case"agent:start-session":return this.doStartSession(i.input??{});case"agent:send-prompt":{let n=String(i.sessionId),s=A(n);if(!s)throw new k("NO_SESSION",`no session: ${n}`);let r=this.normalizePromptEnvelope(i);return await ae(n,r),this.notePromptAccepted(n,r,s.status==="working")}case"agent:end-session":this.dropSessionFanout(String(i.sessionId)),await ce(String(i.sessionId));let o=A(String(i.sessionId));return o&&this.broadcastSessionStatus(o),{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 k("UNKNOWN_AGENT_MSG",`unknown agent message: ${t}`)}}async doStartSession(e){if(!Q(e.projectId))throw new k("NO_PROJECT",`no project: ${e.projectId}`);let i=await oe(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 o=this.opts.getExcludePorts?.()??ye(),s=(await E({excludePorts:o})).find(d=>String(d.port)===i);if(!s||!s.cwd)return{project:null};let r=H().find(d=>d.cwd===s.cwd)??null,c=Array.from(new Set([...r?.knownBundleUrls??[],s.bundleUrl,t]));return{project:D({cwd:s.cwd,name:s.projectName??I.basename(s.cwd),preferredProvider:e.provider??r?.preferredProvider,sourceRoots:r?.sourceRoots??[s.cwd],knownBundleUrls:c,framework:r?.framework??ve(s.framework),bundleId:s.bundleId??r?.bundleId})}}getTranscript(e){let t=se(e);return le.existsSync(t)?le.readFileSync(t,"utf8"):{error:"transcript not found",code:"NO_TRANSCRIPT"}}getPaths(){let e=Z();return{userDataDir:e,storeFile:I.join(e,"attached-projects.json"),sessionsDir:I.join(e,"sessions"),transcriptsDir:I.join(e,"transcripts")}}subscribeSocket(e,t){let i=this.sessionsBySocket.get(e);if(i||(i=new Set,this.sessionsBySocket.set(e,i)),i.has(t))return{ok:!0,refCount:this.subscriptions.get(t)?.refCount??1};i.add(t);let o=this.subscriptions.get(t);if(o)return o.refCount++,{ok:!0,refCount:o.refCount};let n=de(t,s=>{let r=this.coalescePromptEcho(t,s);if(r&&(this.applySessionEvent(t,r),this.fanOutEvent(t,r)),s.type==="turn-completed"){let c=A(t);if(c)try{ee(c.projectId,{usd:s.costUsd,ts:s.ts})}catch(l){process.stderr.write(`[sootsim-agent] recordTurnTelemetry failed: ${l instanceof Error?l.message:String(l)}
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 o=Date.now(),n=this.pendingPromptEchoes.get(e)??[];n.push({sentAt:o}),this.pendingPromptEchoes.set(e,n);let s=Math.max(this.pendingTurns.get(e)??0,i?1:0)+1;this.pendingTurns.set(e,s);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:o}),{ok:!0,queued:s>1,pendingTurns:s,queueDepth:Math.max(0,s-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){re(e,t);let i=A(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[o,n]of this.sessionsBySocket)if(n.has(e)&&o.readyState===P)try{o.send(i)}catch{}}broadcastSessionStatus(e){let t=JSON.stringify({type:"agent:session-status",session:e});for(let i of this.allSockets)if(i.readyState===P)try{i.send(t)}catch{}}respond(e,t,i){if(e.readyState===P)try{e.send(JSON.stringify({id:t,result:i}))}catch{}}respondError(e,t,i,o){if(e.readyState===P)try{e.send(JSON.stringify({id:t,error:i,...o?{code:o}:{}}))}catch{}}};function ve(a){return a==="expo"?"expo":a==="one"||a==="vxrn"?"one":"unknown"}import be from"http";import we from"https";var Ae="sootsim",ke=new Set(["host","origin","referer","user-agent","cookie","connection","keep-alive","transfer-encoding","upgrade","content-length","sec-fetch-site","sec-fetch-mode","sec-fetch-dest","sec-ch-ua","sec-ch-ua-mobile","sec-ch-ua-platform"]),Ce={"access-control-allow-origin":"*","access-control-allow-methods":"GET,POST,PUT,DELETE,PATCH,OPTIONS","access-control-allow-headers":"*","access-control-expose-headers":"*","access-control-max-age":"3600"};function C(a){for(let[e,t]of Object.entries(Ce))a.setHeader(e,t)}function Te(a,e){let t=[],i=e;i?.code&&t.push(i.code),i?.message&&t.push(i.message),i?.cause?.code&&t.push(i.cause.code),i?.cause?.message&&t.push(i.cause.message);let n=[...new Set(t.filter(Boolean))].join(" | ")||String(e);return a.includes("stored-in-.env.local")?`${n} | upstream url still contains placeholder env values`:n}function Ee(a){let e={};for(let[t,i]of Object.entries(a))i&&(ke.has(t.toLowerCase())||(e[t]=Array.isArray(i)?i.join(", "):i));return e["user-agent"]=Ae,e}function ue(a){return a?.startsWith("/__fetch-proxy?")||a?.startsWith("/__proxy?")||!1}function pe(a){return a?!!(a.startsWith("/__app-api?")||a.startsWith("/__app-api/")):!1}async function he(a,e){if(a.method==="OPTIONS"){C(e),e.writeHead(204),e.end();return}let i=new URLSearchParams((a.url||"").split("?")[1]||"").get("url");if(!i){C(e),e.writeHead(400,{"Content-Type":"text/plain"}),e.end("missing url param");return}let o;try{o=new URL(i)}catch{C(e),e.writeHead(400,{"Content-Type":"text/plain"}),e.end("invalid url param");return}let n=Ee(a.headers),s;if(a.method!=="GET"&&a.method!=="HEAD"){let d=[];for await(let u of a)d.push(Buffer.isBuffer(u)?u:Buffer.from(u));d.length>0&&(s=Buffer.concat(d))}let r;try{r=await fetch(o.href,{method:a.method,headers:n,body:s,redirect:"follow"})}catch(d){C(e),e.writeHead(502,{"Content-Type":"text/plain"}),e.end(`fetch proxy error: ${Te(o.href,d)}`);return}r.headers.forEach((d,u)=>{let p=u.toLowerCase();p==="content-encoding"||p==="transfer-encoding"||p==="content-length"||p==="set-cookie"||p.startsWith("access-control-")||e.setHeader(u,d)}),C(e);let c=r.headers.getSetCookie?.()??[];c.length>0&&e.setHeader("x-sootsim-set-cookie",c.join(", ")),e.statusCode=r.status;let l=Buffer.from(await r.arrayBuffer());e.end(l)}function me(a,e){let t=a.url||"",i="",o="";if(t.startsWith("/__app-api?")){let l=new URL(t,"http://sootsim.local");i=l.searchParams.get("path")||"",o=l.searchParams.get("origin")?.trim()||""}else if(t.startsWith("/__app-api/"))i=t.slice(10);else return!1;if(!o)return e.writeHead(400,{"Content-Type":"text/plain"}),e.end("app-api: missing origin query param"),!0;if(a.method==="OPTIONS")return e.writeHead(204,{"Access-Control-Allow-Origin":a.headers.origin||"*","Access-Control-Allow-Methods":"GET,POST,PUT,PATCH,DELETE,OPTIONS","Access-Control-Allow-Headers":a.headers["access-control-request-headers"]||"*","Access-Control-Allow-Credentials":"true","Access-Control-Max-Age":"86400"}),e.end(),!0;let n;try{n=new URL(i,o)}catch{return e.writeHead(400,{"Content-Type":"text/plain"}),e.end("app-api: invalid origin or path"),!0}let s=n.protocol==="https:"?we:be,r={...a.headers};delete r.host,r.host=n.host;let c=s.request({hostname:n.hostname,port:n.port||(n.protocol==="https:"?443:80),path:n.pathname+n.search,method:a.method,headers:r},l=>{let d=Object.keys(l.headers).filter(u=>{let p=u.toLowerCase();return!p.startsWith("access-control-")&&p!=="set-cookie"}).join(", ");e.writeHead(l.statusCode??502,{...l.headers,"access-control-allow-origin":a.headers.origin||"*","access-control-allow-credentials":"true","access-control-expose-headers":d}),l.pipe(e)});return c.on("error",l=>{e.statusCode=502,e.end(`app proxy error: ${l.message}`)}),a.pipe(c),!0}var Oe=new Set(["tap","keyboard","close"]);function Re(a){return!a||typeof a.type!="string"?!1:a.acquireLock===!0?!0:a.readOnly===!0?!1:Oe.has(a.type)}var _e=5e3,Be=3600*1e3,Le="SOOTSIM_RUNTIME_UPDATE_INTERVAL_MS",Ne={".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 fe(a,e,t){let i;try{let c=B();i=JSON.stringify(c)}catch{i="{}"}let o=e>0?`window.__sootsimBridgePort=${e};`:"",n=t?`window.__sootsimSootbeanOrigin=${JSON.stringify(t)};`:"",s=`<script>window.__sootsimSharedConfig=${i};`+o+n+`window.__sootsimCliVersion=${JSON.stringify(U())};</script>`,r=a.toString("utf8");return r.includes("</head>")?r.replace("</head>",s+"</head>"):r.includes("</body>")?r.replace("</body>",s+"</body>"):s+r}var O=class a{port;openUrlHandler;httpServer=null;wss=null;nextCommandId=1;nextSimNumber=161;sims=new Map;primarySimId=null;pendingCommands=new Map;cliBySentId=new Map;cliSimBySocket=new Map;cliLastCommandAt=new Map;cliIdentityKeyBySocket=new Map;cliLabelBySocket=new Map;restorableSims=new Map;nextCliFallbackId=1;cliIdleTimer=null;agentHost;static CLI_IDLE_TIMEOUT_MS=6e4;static CLI_LEASE_TTL_MS=6e5;static USER_ACTIVE_LEASE_TTL_MS=8e3;static USER_BOOT_LEASE_TTL_MS=6e4;static SIM_RECONNECT_TTL_MS=3e4;preferredPort;portFallbackCount;shouldWriteLockfile;sootbeanOrigin=null;effectivePort=0;startedAt=0;heartbeatTimer=null;wsHeartbeatTimer=null;wsIsAlive=new WeakMap;static WS_HEARTBEAT_INTERVAL_MS=3e4;runtimeUpdateTimer=null;runtimeUpdateInFlight=null;activeRuntimeVersion=null;activeRuntimeDirPath=null;scanCache=null;scanCacheAt=0;inflightScan=null;static SCAN_FRESH_MS=2e3;constructor(e={}){this.preferredPort=e.port||7668,this.port=this.preferredPort,this.shouldWriteLockfile=e.writeLockfile===!0,this.portFallbackCount=Math.max(1,e.portFallbackCount??10),this.openUrlHandler=e.openUrl,this.agentHost=new x({getExcludePorts:e.agentScanExcludes}),this.sootbeanOrigin=e.sootbeanOrigin?.replace(/\/$/,"")||null}getAgentHost(){return this.agentHost}start(e){this.startAsync(e)}async startAsync(e){if(this.httpServer||this.wss)return this.effectivePort;this.refreshActiveRuntime();for(let t=0;t<this.portFallbackCount;t++){let i=this.preferredPort+t;try{return await this.bindOnce(i,e?.silent===!0),this.effectivePort=i,this.port=i,this.startedAt=Date.now(),t>0&&!e?.silent&&process.stderr.write(`ws bridge bound to port ${i} (preferred ${this.preferredPort} was taken)
5
- `),this.afterBind(),i}catch(o){if(o?.code!=="EADDRINUSE")throw o;e?.silent||process.stderr.write(`ws bridge port ${i} already in use, trying ${i+1}
6
- `)}}throw new Error(`could not bind ws bridge after ${this.portFallbackCount} attempts starting at ${this.preferredPort}`)}bindOnce(e,t){return new Promise((i,o)=>{let n=Pe((c,l)=>this.handleHttpRequest(c,l)),s=!1,r=c=>{if(!s){s=!0;try{n.close()}catch{}this.httpServer=null,this.wss=null,o(c)}};n.once("error",r),n.listen(e,"127.0.0.1",()=>{s||(s=!0,n.removeListener("error",r),n.on("error",c=>{process.stderr.write(`ws bridge http error: ${String(c)}
7
- `)}),this.httpServer=n,this.wss=new xe({server:n}),this.wireWebSocketServer(),i())})})}wireWebSocketServer(){this.wss&&this.wss.on("connection",(e,t)=>{let i=t.headers.origin,o=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),o==="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 s=`ws-${this.nextCliFallbackId++}`;this.cliIdentityKeyBySocket.set(e,s)}e.on("message",s=>{let r;try{r=JSON.parse(s.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=L(),l=this.getActiveRuntime(),d={type:"runtime:list:ok",id:r.id,installed:c,active:l.version,activeRuntimeDir:l.runtimeDir};try{e.send(JSON.stringify(d))}catch{}return}if(r.type==="runtime:use"){let c=typeof r.version=="string"?r.version:"";if(!L().includes(c)){try{e.send(JSON.stringify({type:"runtime:use:error",id:r.id,error:`runtime ${c||"(missing)"} is not installed`}))}catch{}return}let d=this.setActiveRuntime(c);try{e.send(JSON.stringify({type:"runtime:use:ok",id:r.id,version:d.version,runtimeDir:d.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(o==="sim"){if(n&&(n.lastSeenAt=Date.now()),r.type==="bridge:register"&&n){let d=r,u=this.tryRestoreSimId(n,d.simId);n.url=d.url,n.title=d.title,n.userAgent=d.userAgent,typeof d.kind=="string"&&d.kind.trim()&&(n.kind=d.kind.trim()),d.meta&&typeof d.meta=="object"&&(n.meta=d.meta),u&&(this.broadcastSimAssignments(),this.broadcastSimClientStates());return}if(r.type==="bridge:user-focus-state"&&n){let d=r;this.updateUserFocusLease(n,d.focused===!0);return}if(r.type==="bridge:user-interact"&&n){this.updateUserActivity(n);return}if(r.type==="bridge:write-shared-config"){let d=r.patch&&typeof r.patch=="object"?r.patch:null;if(!d)return;let u;try{u=M(d)}catch(h){process.stderr.write(`sootsim: bridge:write-shared-config failed: ${h instanceof Error?h.message:String(h)}
8
- `);return}let p=JSON.stringify({type:"bridge:shared-config-changed",config:u});for(let h of this.sims.values())if(h.ws.readyState===m.OPEN)try{h.ws.send(p)}catch{}return}if(r.type==="bridge:open-path"){let d=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;d&&this.openPathInEditor(d,u,p);return}if(r.type==="bridge:boot-clients"&&n){let d=[];for(let[p,h]of this.cliSimBySocket)h===n.id&&d.push(p);for(let p of d){this.cliSimBySocket.delete(p);try{p.close(1e3,"booted by sim")}catch{}}let u=!!n.cliLease;n.cliLease={kind:"user-active",cliIdentityKey:"__user-active__",cliLabel:"active user",expiresAt:Date.now()+a.USER_BOOT_LEASE_TTL_MS},process.stderr.write(`sootsim booted ${d.length} cli client(s)${u?" (overrode prior lease)":""}; held sim for user [${n.id}]
9
- `),this.recordSimAction(n.id,"sim booted cli clients"),this.broadcastSimClientStates();return}let c=this.pendingCommands.get(r.id);if(c){this.pendingCommands.delete(r.id),r.error?c.reject(new Error(r.error)):c.resolve(r.result);return}let l=this.cliBySentId.get(r.id);if(l&&(this.cliBySentId.delete(r.id),l.ws.readyState===m.OPEN)){let d=this.getOtherCliIdentityCount(l.ws,l.simId),u=d>0?{...r,id:l.originalId,i:d}:{...r,id:l.originalId};l.ws.send(JSON.stringify(u))}return}(async()=>{this.cliLastCommandAt.set(e,Date.now());try{if(r.type==="bridge:bye"){let p=this.cliSimBySocket.delete(e);this.cliLastCommandAt.delete(e),this.cliIdentityKeyBySocket.delete(e),this.cliLabelBySocket.delete(e);for(let[h,f]of this.cliBySentId)f.ws===e&&this.cliBySentId.delete(h);p&&this.broadcastSimClientStates();return}if(r.type==="bridge:hello"){let p=typeof r.cliIdentityKey=="string"&&r.cliIdentityKey.trim()?r.cliIdentityKey.trim():this.cliIdentityKeyBySocket.get(e)||`ws-${this.nextCliFallbackId++}`;this.cliIdentityKeyBySocket.set(e,p),typeof r.cliLabel=="string"&&r.cliLabel.trim()&&this.cliLabelBySocket.set(e,r.cliLabel.trim()),e.readyState===m.OPEN&&e.send(JSON.stringify({id:r.id,result:{cliIdentityKey:p,leaseTtlMs:a.CLI_LEASE_TTL_MS,leasing:!0}}));return}if(r.type==="bridge:list-sims"){e.readyState===m.OPEN&&e.send(JSON.stringify({id:r.id,result:this.listSims()}));return}if(r.type==="bridge:open"){if(typeof r.url!="string"||!r.url)throw new Error("bridge:open requires a url");await this.openUrl(r.url,{newWindow:r.newWindow===!0}),e.readyState===m.OPEN&&e.send(JSON.stringify({id:r.id,result:{ok:!0,url:r.url}}));return}if(r.type==="bridge:claim"){let p=await this.waitForSim(r.simId),h=this.tryAcquireLease(e,p,{force:r.force===!0});if(!h.granted){e.readyState===m.OPEN&&e.send(JSON.stringify({id:r.id,error:`sim ${p.id} is locked by another cli`,o:h.lock}));return}this.setCliSimTarget(e,p.id),this.recordSimAction(p.id,h.bootedCount>0?`cli force-claimed sim (booted ${h.bootedCount})`:"cli claimed sim"),e.readyState===m.OPEN&&e.send(JSON.stringify({id:r.id,result:{simId:p.id,lockedBy:h.lease.cliIdentityKey,lockExpiresAt:h.lease.expiresAt,bootedCount:h.bootedCount}}));return}let c=await this.waitForSim(r.simId);if(Re(r)){let p=this.tryAcquireLease(e,c);if(!p.granted){e.readyState===m.OPEN&&e.send(JSON.stringify({id:r.id,error:`sim ${c.id} is locked by another cli \u2014 use \`sootsim claim ${c.id} --force\` or \`sootsim open --new\``,o:p.lock}));return}}else this.ensureCliIdentityKey(e);this.setCliSimTarget(e,c.id),this.recordSimAction(c.id,this.describeForwardedCommand(r));let l=this.nextCommandId++;this.cliBySentId.set(l,{simId:c.id,ws:e,originalId:r.id});let{simId:d,...u}=r;c.ws.send(JSON.stringify({...u,id:l}))}catch(c){e.readyState===m.OPEN&&e.send(JSON.stringify({id:r.id,error:c instanceof Error?c.message:String(c)}))}})()}}),e.on("close",()=>{if(this.agentHost.unregisterSocket(e),o==="sim"&&n){this.rememberDisconnectedSim(n),this.primarySimId===n.id&&(this.primarySimId=this.getOpenSim()?.id??null);for(let[s,r]of this.pendingCommands)r.simId===n.id&&(r.reject(new Error("sim disconnected")),this.pendingCommands.delete(s));for(let[s,r]of this.cliBySentId)r.simId===n.id&&(r.ws.readyState===m.OPEN&&r.ws.send(JSON.stringify({id:r.originalId,error:"sim disconnected before responding"})),this.cliBySentId.delete(s));this.broadcastSimAssignments(),this.broadcastSimClientStates()}else if(o==="cli"){let s=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);s&&this.broadcastSimClientStates()}})})}afterBind(){if(process.stderr.write(`ws bridge listening on port ${this.port}
10
- `),this.cliIdleTimer=setInterval(()=>this.sweepIdleCliClients(),3e4),this.cliIdleTimer.unref(),this.wsHeartbeatTimer=setInterval(()=>this.sweepDeadWebSockets(),a.WS_HEARTBEAT_INTERVAL_MS),this.wsHeartbeatTimer.unref(),this.shouldWriteLockfile){try{if(T(),!V(this.buildLockfileSnapshot()))throw new Error("another sootsim daemon wrote the lockfile during startup \u2014 aborting")}catch(e){throw process.stderr.write(`ws bridge failed to claim daemon lockfile: ${String(e)}
11
- `),e}this.heartbeatTimer=setInterval(()=>{try{this.writeLockfileSnapshot()}catch{}},_e),this.heartbeatTimer.unref(),this.startRuntimeUpdater()}this.agentHost.seedOnBoot()}bootstrapping=!0;buildLockfileSnapshot(){return{schema:1,pid:process.pid,platform:process.platform,bridgePort:this.effectivePort,runtimePort:this.effectivePort,activeRuntime:this.activeRuntimeVersion,activeRuntimeDir:this.activeRuntimeDirPath,startedAt:this.startedAt,heartbeatAt:Date.now(),bootstrapping:this.bootstrapping}}writeLockfileSnapshot(){K(this.buildLockfileSnapshot())}refreshActiveRuntime(){this.activeRuntimeVersion=W(),this.activeRuntimeDirPath=j()}runServerScan(){if(this.inflightScan)return this.inflightScan;let e=this.effectivePort>0?[this.effectivePort]:[];return this.inflightScan=E({excludePorts:e,buildIconProxyUrl:t=>`/__bundle-proxy?url=${encodeURIComponent(t)}`}).then(t=>(this.scanCache=t,this.scanCacheAt=Date.now(),t)).catch(t=>{let i=t instanceof Error?t.message:String(t);return console.error("[sootsim] /__server-scan failed:",i),this.scanCache??[]}).finally(()=>{this.inflightScan=null}),this.inflightScan}handleServerScan(e){let t=o=>{e.writeHead(200,{"Content-Type":"application/json; charset=utf-8","Cache-Control":"no-store"}),e.end(JSON.stringify(o))},i=Date.now()-this.scanCacheAt;if(this.scanCache&&i<a.SCAN_FRESH_MS){t(this.scanCache);return}if(this.scanCache){t(this.scanCache),this.runServerScan().catch(()=>{});return}this.runServerScan().then(o=>t(o))}resolveRuntimeUpdateIntervalMs(){let e=Number(process.env[Le]);return Number.isFinite(e)&&e>0?Math.max(100,Math.round(e)):Be}startRuntimeUpdater(){if(!this.shouldWriteLockfile||this.runtimeUpdateTimer)return;this.runRuntimeUpdate("startup");let e=this.resolveRuntimeUpdateIntervalMs();this.runtimeUpdateTimer=setInterval(()=>{this.runRuntimeUpdate("periodic")},e),this.runtimeUpdateTimer.unref()}runRuntimeUpdate(e){return this.runtimeUpdateInFlight?this.runtimeUpdateInFlight:(this.runtimeUpdateInFlight=(async()=>{try{e==="startup"&&process.stderr.write(`sootsim: checking for runtime updates\u2026
12
- `);let t=await Y();if(!t.updated||!t.latestVersion){e==="startup"&&process.stderr.write(`sootsim: runtime ${this.activeRuntimeVersion??"(none)"} is current
13
- `);return}let i=this.setActiveRuntime(t.latestVersion);process.stderr.write(`sootsim runtime updated to ${i.version} (${e})
14
- `)}catch(t){process.stderr.write(`sootsim runtime update failed (${e}): ${t instanceof Error?t.message:String(t)}
15
- `)}finally{if(this.runtimeUpdateInFlight=null,e==="startup"&&this.bootstrapping){if(this.bootstrapping=!1,this.shouldWriteLockfile&&this.httpServer)try{this.writeLockfileSnapshot()}catch{}process.stderr.write(`sootsim: ready
16
- `)}}})(),this.runtimeUpdateInFlight)}setActiveRuntime(e){if(F(e),this.refreshActiveRuntime(),this.shouldWriteLockfile&&this.httpServer)try{this.writeLockfileSnapshot()}catch{}let t=JSON.stringify({type:"runtime:changed",version:e,runtimeDir:this.activeRuntimeDirPath});for(let i of this.sims.values())if(i.ws.readyState===m.OPEN)try{i.ws.send(t)}catch{}return{version:e,runtimeDir:this.activeRuntimeDirPath}}getActiveRuntime(){return{version:this.activeRuntimeVersion,runtimeDir:this.activeRuntimeDirPath}}removeLockfile(){if(this.shouldWriteLockfile)try{N()}catch{}}handleHttpRequest(e,t){if(t.setHeader("Cross-Origin-Opener-Policy","same-origin"),t.setHeader("Cross-Origin-Embedder-Policy","credentialless"),t.setHeader("Cross-Origin-Resource-Policy","cross-origin"),t.setHeader("Document-Policy","js-profiling"),ue(e.url)){he(e,t);return}if(pe(e.url)&&me(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 o=new URL(e.url||"/","http://localhost");if(o.pathname==="/__bundle-proxy"){let l=o.searchParams.get("url");if(!l){t.writeHead(400,{"Content-Type":"text/plain"}),t.end("bundle-proxy: missing url query param");return}let d;try{d=new URL(l)}catch{t.writeHead(400,{"Content-Type":"text/plain"}),t.end("bundle-proxy: invalid url");return}let u=d.hostname;if(!(u==="localhost"||u==="127.0.0.1"||u==="::1"||u.endsWith(".localhost"))){t.writeHead(403,{"Content-Type":"text/plain"}),t.end("bundle-proxy: only loopback targets allowed");return}(async()=>{try{let h=await fetch(d.toString(),{redirect:"follow"}),f={},y=h.headers.get("content-type");if(y&&(f["Content-Type"]=y),f["Cache-Control"]="no-store",t.writeHead(h.status,f),!h.body){t.end();return}let g=h.body.getReader();for(;;){let{done:v,value:b}=await g.read();if(v)break;t.write(Buffer.from(b))}t.end()}catch(h){t.writeHead(502,{"Content-Type":"text/plain"}),t.end(`bundle-proxy: upstream fetch failed: ${h instanceof Error?h.message:String(h)}`)}})();return}if(o.pathname==="/__server-scan"){this.handleServerScan(t);return}if(o.pathname==="/healthz"){t.writeHead(200,{"Content-Type":"application/json","Cache-Control":"no-store"}),t.end(JSON.stringify({ok:!0,pid:process.pid,platform:process.platform,bridgePort:this.effectivePort,runtimePort:this.effectivePort,activeRuntime:this.activeRuntimeVersion,startedAt:this.startedAt,uptimeMs:this.startedAt>0?Date.now()-this.startedAt:0}));return}if(o.pathname==="/__sootsim/shared-config"){if(t.setHeader("Access-Control-Allow-Origin","*"),t.setHeader("Cache-Control","no-store"),i==="GET"||i==="HEAD"){let l="{}";try{l=JSON.stringify(B())}catch{}t.writeHead(200,{"Content-Type":"application/json"}),i==="HEAD"?t.end():t.end(l);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 s=o.pathname;if(s==="/runtime"||s==="/runtime/"?s="/":s.startsWith("/runtime/")&&(s=s.slice(8)),(s===""||s==="/")&&(s="/index.html"),s.includes("\0")){t.writeHead(400),t.end("bad request");return}if(process.platform!=="win32"&&s.includes("\\")){t.writeHead(400),t.end("bad request");return}for(let l of s.split("/"))if(l===".."){t.writeHead(403),t.end("forbidden");return}let r=S.resolve(n,"."+s),c=n.endsWith(S.sep)?n:n+S.sep;if(!r.startsWith(c)&&r!==n){t.writeHead(403),t.end("forbidden");return}w.realpath(r,(l,d)=>{let u=l?r:d,p=u.endsWith(S.sep)?u:u+S.sep;if(!l){let h=(()=>{try{let f=w.realpathSync(n);return f.endsWith(S.sep)?f:f+S.sep}catch{return c}})();if(!p.startsWith(h)&&u+S.sep!==h){t.writeHead(403),t.end("forbidden");return}}w.stat(u,(h,f)=>{if(h||!f?.isFile()){let b=S.extname(s).toLowerCase();if(b&&b!==".html"){t.writeHead(404),t.end("not found");return}if(s.startsWith("/__")||s.startsWith("/api/")||s==="/api"){t.writeHead(404,{"Content-Type":"text/plain; charset=utf-8"}),t.end("not found");return}let _=S.join(n,"index.html");w.readFile(_,(ge,Se)=>{if(ge){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(fe(Se,this.effectivePort,this.sootbeanOrigin))});return}let y=S.extname(u).toLowerCase(),g=Ne[y]||"application/octet-stream";if(t.writeHead(200,{"Content-Type":g,"Cache-Control":"no-store"}),i==="HEAD"){t.end();return}if(y===".html"){w.readFile(u,(b,_)=>{if(b){try{t.end()}catch{}return}t.end(fe(_,this.effectivePort,this.sootbeanOrigin))});return}let v=w.createReadStream(u);v.pipe(t),v.on("error",()=>{try{t.end()}catch{}})})})}sweepIdleCliClients(){let e=Date.now(),t=!1;for(let[i,o]of this.cliSimBySocket){let n=this.cliLastCommandAt.get(i)??0;if(!(e-n<a.CLI_IDLE_TIMEOUT_MS)){this.cliSimBySocket.delete(i),this.cliLastCommandAt.delete(i);for(let[s,r]of this.cliBySentId)r.ws===i&&this.cliBySentId.delete(s);try{i.close(1e3,"idle timeout")}catch{}t=!0}}t&&this.broadcastSimClientStates(),this.sweepRestorableSims(e)}sweepDeadWebSockets(){if(this.wss)for(let e of this.wss.clients){if(e.readyState!==m.OPEN)continue;if(this.wsIsAlive.get(e)===!1){try{e.terminate()}catch{}continue}this.wsIsAlive.set(e,!1);try{e.ping()}catch{try{e.terminate()}catch{}}}}listSims(){return Array.from(this.sims.values()).sort((e,t)=>e.id===this.primarySimId?-1:t.id===this.primarySimId?1:e.connectedAt-t.connectedAt).map(e=>this.describeSim(e))}async sendCommand(e){let t=await this.waitForSim(e.simId),i=this.nextCommandId++;return new Promise((o,n)=>{let s=setTimeout(()=>{this.pendingCommands.delete(i),this.broadcastSimClientStates(),n(new Error("command timed out after 30s"))},3e4);this.pendingCommands.set(i,{simId:t.id,resolve:l=>{clearTimeout(s),this.pendingCommands.delete(i),this.broadcastSimClientStates(),o(l)},reject:l=>{clearTimeout(s),this.pendingCommands.delete(i),this.broadcastSimClientStates(),n(l)}}),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 o=t!=null?`:${t}${i!=null?`:${i}`:""}`:"",n=`${e}${o}`,s=(c,l)=>new Promise(d=>{try{let u=Ie(c,l,{detached:!0,stdio:"ignore"}),p=!1;u.on("error",()=>{p||(p=!0,d(!1))}),u.on("spawn",()=>{p||(p=!0,u.unref(),d(!0))})}catch{d(!1)}}),r=process.env.REACT_EDITOR||process.env.EDITOR;if(r){let c=r.split(" ").filter(Boolean);if(c.length&&await s(c[0],[...c.slice(1),"-g",n]))return}await s("cursor",["-g",n])||await s("code",["-g",n])||await this.openUrl(e)}async openUrl(e,t={}){if(this.openUrlHandler){await this.openUrlHandler(e,t);return}await z(e,t)}async close(){if(this.cliIdleTimer&&(clearInterval(this.cliIdleTimer),this.cliIdleTimer=null),this.heartbeatTimer&&(clearInterval(this.heartbeatTimer),this.heartbeatTimer=null),this.wsHeartbeatTimer&&(clearInterval(this.wsHeartbeatTimer),this.wsHeartbeatTimer=null),this.runtimeUpdateTimer&&(clearInterval(this.runtimeUpdateTimer),this.runtimeUpdateTimer=null),this.shouldWriteLockfile)try{N()}catch{}this.effectivePort=0,this.startedAt=0,this.agentHost.close();for(let[i,o]of this.pendingCommands)o.reject(new Error("server closing")),this.pendingCommands.delete(i);for(let i of this.sims.values())i.ws.close();this.sims.clear(),this.primarySimId=null;let e=this.wss,t=this.httpServer;if(this.wss=null,this.httpServer=null,e)try{e.close()}catch{}if(t)try{t.close()}catch{}}describeSim(e){let t;try{t=e.ws.readyState}catch{t=m.CLOSED}let i=this.getActiveLease(e);return{id:e.id,origin:e.origin,url:e.url,title:e.title,userAgent:e.userAgent,connectedAt:e.connectedAt,lastSeenAt:e.lastSeenAt,lastActiveAt:e.lastActiveAt||void 0,isPrimary:e.id===this.primarySimId,readyState:t===m.OPEN?"open":t===m.CLOSING?"closing":"closed",attachedCliCount:this.getAttachedCliCount(e.id),lockedBy:i?i.cliLabel||i.cliIdentityKey:void 0,lockedByKind:i?i.kind:void 0,lockExpiresAt:i?i.expiresAt:void 0,userFocused:e.userFocused||void 0,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 o=this.cliIdentityKeyBySocket.get(e)??(()=>{let u=`ws-${this.nextCliFallbackId++}`;return this.cliIdentityKeyBySocket.set(e,u),u})(),n=this.cliLabelBySocket.get(e),s=Date.now(),r=this.getActiveLease(t),c=r&&r.cliIdentityKey===o,l=0;if(r&&!c&&!i.force)return{granted:!1,lease:r,lock:{by:r.cliLabel||r.cliIdentityKey,expiresInMs:Math.max(0,r.expiresAt-s)},bootedCount:0};if(r&&!c&&i.force)for(let[u,p]of this.cliSimBySocket){if(p!==t.id)continue;let h=this.cliIdentityKeyBySocket.get(u);if(h&&h!==o){this.cliSimBySocket.delete(u);try{u.close(1e3,"lease claimed by another cli")}catch{}l++}}let d={kind:"cli",cliIdentityKey:o,cliLabel:n,expiresAt:s+a.CLI_LEASE_TTL_MS};return t.cliLease=d,{granted:!0,lease:d,bootedCount:l}}updateUserFocusLease(e,t){let i=t;e.userFocused!==i&&(e.userFocused=i,this.broadcastSimClientStates())}updateUserActivity(e){let t=this.getActiveLease(e);if(t&&t.kind==="cli")return;let o=Date.now()+a.USER_ACTIVE_LEASE_TTL_MS,n=t&&t.kind==="user-active"?Math.max(t.expiresAt,o):o;e.cliLease={kind:"user-active",cliIdentityKey:"__user-active__",cliLabel:"active user",expiresAt:n},this.broadcastSimClientStates()}ensureCliIdentityKey(e){let t=this.cliIdentityKeyBySocket.get(e);if(t)return t;let i=`ws-${this.nextCliFallbackId++}`;return this.cliIdentityKeyBySocket.set(e,i),i}getOpenSim(e){if(e){let i=this.sims.get(e);return i?.ws.readyState===m.OPEN?i:null}let t=this.primarySimId!=null?this.sims.get(this.primarySimId):null;if(t?.ws.readyState===m.OPEN)return t;for(let i of this.sims.values())if(i.ws.readyState===m.OPEN)return i;return null}async waitForSim(e,t={}){let i=t.attempts??10,o=t.intervalMs??200;for(let n=0;n<i;n++){let s=this.getOpenSim(e);if(s)return s;await new Promise(r=>setTimeout(r,o))}throw new Error(e?`no sim connected with id ${e}`:"no sim connected")}shouldPromoteSim(e){let t=this.primarySimId?this.sims.get(this.primarySimId):null,i=e.origin?.includes(":5173"),o=t?.origin?.includes(":5173");return!t||t.ws.readyState!==m.OPEN||!!i||!o}broadcastSimAssignments(){for(let e of this.sims.values())e.ws.readyState===m.OPEN&&e.ws.send(JSON.stringify({type:"bridge:welcome",simId:e.id,isPrimary:e.id===this.primarySimId}))}broadcastSimClientStates(){for(let e of this.sims.values()){if(e.ws.readyState!==m.OPEN)continue;let t=this.getActiveLease(e),i={type:"bridge:client-state",attachedCliCount:this.getAttachedCliCount(e.id),activeAgentCommandCount:this.getActiveAgentCommandCount(e.id),recentActions:e.recentActions,lockedBy:t?t.cliLabel||t.cliIdentityKey:void 0,lockedByKind:t?t.kind:void 0,lockExpiresAt:t?t.expiresAt:void 0,userFocused:e.userFocused||void 0};e.ws.send(JSON.stringify(i))}}setCliSimTarget(e,t){let i=this.cliSimBySocket.get(e);i!==t&&(this.cliSimBySocket.set(e,t),this.recordSimAction(t,i?"cli switched sims":"cli connected",!1),this.broadcastSimClientStates())}recordSimAction(e,t,i=!0){let o=t?.trim();if(!o)return;let n=this.sims.get(e);if(!n)return;let s=Date.now();n.lastActiveAt=s,n.recentActions=[{label:o,at:s},...n.recentActions.filter(r=>r.label!==o)].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,o]of this.cliSimBySocket){if(o!==e||i.readyState!==m.OPEN)continue;let n=this.cliIdentityKeyBySocket.get(i);t.add(n??`ws-unknown-${t.size}`)}return t.size}getOtherCliIdentityCount(e,t){let i=this.cliIdentityKeyBySocket.get(e),o=new Set;for(let[n,s]of this.cliSimBySocket){if(s!==t||n.readyState!==m.OPEN)continue;let r=this.cliIdentityKeyBySocket.get(n);r&&r===i||o.add(r??`ws-unknown-${o.size}`)}return o.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 o=this.sims.get(i);if(o&&o!==e&&o.ws.readyState===m.OPEN)return!1;let n=this.getRestorableSimState(i),s=e.id;this.sims.delete(s),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===s&&(this.primarySimId=e.id);for(let[r,c]of this.cliSimBySocket)c===s&&this.cliSimBySocket.set(r,e.id);return!0}rememberDisconnectedSim(e){let t=this.getActiveLease(e);this.restorableSims.set(e.id,{recentActions:e.recentActions.map(i=>({...i})),lastActiveAt:e.lastActiveAt,cliLease:t&&t.kind==="cli"?{...t}:void 0,expiresAt:Date.now()+a.SIM_RECONNECT_TTL_MS}),this.sims.delete(e.id)}getRestorableSimState(e){let t=this.restorableSims.get(e);return t?t.expiresAt<=Date.now()?(this.restorableSims.delete(e),null):(t.cliLease&&t.cliLease.expiresAt<=Date.now()&&(t.cliLease=void 0),t):null}sweepRestorableSims(e=Date.now()){for(let[t,i]of this.restorableSims)if(!(i.expiresAt>e)){this.restorableSims.delete(t);for(let[o,n]of this.cliSimBySocket)n===t&&this.cliSimBySocket.delete(o)}}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 De(){let a=process.env.XPC_SERVICE_NAME||"";return!!(a.includes("dev.sootsim.daemon")||a.includes("dev.sootsim.server")||process.env.INVOCATION_ID)}async function ut(a,e={}){(a.includes("--help")||a.includes("-h"))&&(console.log(`
17
- sootsim server \u2014 run the sootsim bridge daemon in the foreground
18
-
19
- hosts the WS bridge that CLI commands talk to. once running, any sootsim
20
- renderer (browser, electron, headless playwright) that connects to port 7668
21
- becomes drivable from 'sootsim describe', 'sootsim tap', etc.
22
-
23
- usage:
24
- sootsim server [options]
25
-
26
- options:
27
- --port <n> bridge port (defaults to ${7668})
28
- --quiet suppress per-connection logging
29
-
30
- examples:
31
- sootsim server
32
- sootsim server --port 7668 --quiet
33
- `),process.exit(0));let t=a.indexOf("--port"),i=t>=0&&a[t+1]?Number(a[t+1]):e.port??7668;Number.isNaN(i)&&(console.error(` invalid --port value: ${a[t+1]}`),process.exit(1));let o=a.includes("--quiet")||a.includes("-q"),n=$();n&&J(n)&&(console.error(` a sootsim daemon is already running (pid ${n.pid}, port ${n.bridgePort})`),console.error(" stop it with 'sootsim daemon stop' first"),process.exit(1)),T();let s=await X(),r=new O({port:i,writeLockfile:!0,sootbeanOrigin:s}),c=await r.startAsync({silent:o}),l=Date.now(),d=f=>{o||process.stdout.write(`${f}
34
- `)},u=new Set,p=setInterval(()=>{let f=r.listSims(),y=new Set(f.map(g=>g.id));for(let g of f)if(!u.has(g.id)){let v=g.title||g.url||g.origin||"(unknown)";d(` + ${g.id} ${v}`)}for(let g of u)y.has(g)||d(` - ${g}`);u.clear();for(let g of y)u.add(g)},500);G({event:"daemon_heartbeat",properties:{bridge_port:c,under_daemon:De(),platform:process.platform,subsource:"daemon"}}),q(),d(`sootsim bridge listening on ws://localhost:${c} (runtime http on same port)`),c!==i&&d(` (preferred port ${i} was taken \u2014 fell back to ${c})`),d(" ready for browser, electron, or headless playwright sims to connect"),d(" (ctrl-c to stop)");let h=async f=>{clearInterval(p),d(`
35
- ${f} received \u2014 shutting down after ${Math.round((Date.now()-l)/1e3)}s`);try{await r.close()}catch{}process.exit(0)};process.on("SIGINT",()=>h("SIGINT")),process.on("SIGTERM",()=>h("SIGTERM")),process.on("SIGHUP",()=>h("SIGHUP")),process.on("exit",()=>{try{r.removeLockfile()}catch{}}),await new Promise(()=>{})}export{ut as runServer};
@@ -1,2 +0,0 @@
1
- /*! sootsim v0.1.49 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{a}from"./chunk-UEWDRHF5.js";import"./chunk-MBYU2XAP.js";import"./chunk-QRZORMLG.js";import"./chunk-LI5EVOPD.js";import"./chunk-WISEXGFB.js";import"./chunk-H6MLMLDA.js";import"./chunk-QFEFKXKP.js";import"./chunk-SNGLDQLQ.js";import"./chunk-2GKUXZWK.js";import"./chunk-IKTUA2CO.js";export{a as runSetupRepo};
@@ -1,2 +0,0 @@
1
- /*! sootsim v0.1.49 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{a}from"./chunk-JL46FF4H.js";import"./chunk-EB3HUXF3.js";import"./chunk-IKTUA2CO.js";export{a as settingsStore};
@@ -1,2 +0,0 @@
1
- /*! sootsim v0.1.49 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{a,b}from"./chunk-H6MLMLDA.js";import"./chunk-QFEFKXKP.js";import"./chunk-2GKUXZWK.js";import"./chunk-IKTUA2CO.js";export{b as flushCliTelemetry,a as trackCliEvent};
@@ -1,2 +0,0 @@
1
- /*! sootsim v0.1.49 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{a,b,c}from"./chunk-I6QTUUXO.js";import"./chunk-OHEI4R6Z.js";import"./chunk-FIBNBYEC.js";import"./chunk-NQHG45SY.js";import"./chunk-LI5EVOPD.js";import"./chunk-WISEXGFB.js";import"./chunk-H6MLMLDA.js";import"./chunk-QFEFKXKP.js";import"./chunk-SNGLDQLQ.js";import"./chunk-2GKUXZWK.js";import"./chunk-IKTUA2CO.js";export{a as resolveDefaultUploadOrigin,b as resolvePublicPreviewOrigin,c as runUpload};