windows-development-sandbox 1.20.0 → 1.23.1

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 (337) hide show
  1. package/config.example.json +8 -1
  2. package/dist/app/features/access/access.def.js +5 -2
  3. package/dist/app/features/access/access.run.js +7 -3
  4. package/dist/app/features/accounts/accounts.def.d.ts +29 -1
  5. package/dist/app/features/accounts/accounts.def.js +10 -4
  6. package/dist/app/features/accounts/accounts.run.d.ts +1 -0
  7. package/dist/app/features/accounts/accounts.run.js +7 -2
  8. package/dist/app/features/accounts/services.def.d.ts +4 -1
  9. package/dist/app/features/accounts/services.def.js +15 -14
  10. package/dist/app/features/accounts/services.run.d.ts +1 -0
  11. package/dist/app/features/accounts/services.run.js +41 -15
  12. package/dist/app/features/defs.d.ts +39 -2
  13. package/dist/app/features/engine/engine.run.js +1 -1
  14. package/dist/app/features/github/github.def.d.ts +44 -3
  15. package/dist/app/features/github/github.def.js +145 -63
  16. package/dist/app/features/github/github.run.d.ts +9 -2
  17. package/dist/app/features/github/github.run.js +43 -5
  18. package/dist/app/features/health/health.def.js +8 -2
  19. package/dist/app/features/logs/logs.def.js +0 -8
  20. package/dist/app/features/projects/projects.def.js +2 -2
  21. package/dist/app/features/projects/projects.run.js +5 -5
  22. package/dist/app/features/sandbox/sandbox.def.js +7 -3
  23. package/dist/app/features/sessions/sessions.def.d.ts +4 -4
  24. package/dist/app/features/sessions/sessions.def.js +0 -5
  25. package/dist/app/features/sessions/sessions.run.d.ts +1 -1
  26. package/dist/app/features/sessions/sessions.run.js +2 -2
  27. package/dist/app/features/settings/categories.def.js +2 -0
  28. package/dist/app/features/settings/settings-rows.js +1 -1
  29. package/dist/app/features/settings/settings.def.js +1 -1
  30. package/dist/app/features/settings/settings.run.js +3 -3
  31. package/dist/app/features/storage/storage.run.js +18 -9
  32. package/dist/app/features/updates/update-lines.js +2 -2
  33. package/dist/app/features/updates/updates.def.js +1 -1
  34. package/dist/app/features/updates/updates.run.js +1 -1
  35. package/dist/app/features/web/web.def.js +2 -2
  36. package/dist/app/features/web/web.run.js +12 -4
  37. package/dist/app/kernel/errors.d.ts +7 -0
  38. package/dist/app/kernel/errors.js +18 -3
  39. package/dist/app/kernel/rpc.d.ts +5 -0
  40. package/dist/app/kernel/view.d.ts +11 -1
  41. package/dist/bin/agent-sandbox.js +2 -2
  42. package/dist/bin/{chunk-DK4NTBUF.js → chunk-7YPEDAJD.js} +172 -48
  43. package/dist/bin/{chunk-2IMT7ZCT.js → chunk-QFSJX2KW.js} +1 -1
  44. package/dist/bin/{chunk-Z2P5OGKL.js → chunk-USTRSHIE.js} +2436 -1693
  45. package/dist/bin/claude-host.js +2 -2
  46. package/dist/bin/claude-sbx.js +2 -2
  47. package/dist/bin/codex-sbx.js +2 -2
  48. package/dist/bin/gemini-sbx.js +2 -2
  49. package/dist/bin/sandbox.js +2 -2
  50. package/dist/bin/sbx-hide.js +2 -2
  51. package/dist/bin/sbx-show.js +2 -2
  52. package/dist/cli/manifest.d.ts +2 -2
  53. package/dist/cli/manifest.js +2 -1
  54. package/dist/cli/menu/coverage-exempt.d.ts +17 -0
  55. package/dist/cli/menu/coverage-exempt.js +61 -0
  56. package/dist/cli/menu/io-menu.d.ts +2 -0
  57. package/dist/cli/menu/io-menu.js +50 -5
  58. package/dist/cli/menu/pages/accounts-page.js +1 -1
  59. package/dist/cli/menu/pages/agents-page.js +8 -2
  60. package/dist/cli/menu/pages/maintenance-page.d.ts +6 -0
  61. package/dist/cli/menu/pages/maintenance-page.js +9 -2
  62. package/dist/cli/menu/pages/sessions-page.d.ts +2 -0
  63. package/dist/cli/menu/pages/sessions-page.js +12 -4
  64. package/dist/cli/menu/pages/settings-page.js +12 -1
  65. package/dist/cli/menu/remote-menu.js +1 -1
  66. package/dist/cli/menu/shell.d.ts +5 -0
  67. package/dist/cli/menu/shell.js +13 -0
  68. package/dist/cli/report.js +2 -0
  69. package/dist/cli/tui/app.d.ts +5 -0
  70. package/dist/cli/tui/app.js +2 -0
  71. package/dist/core/config/defaults.js +3 -1
  72. package/dist/core/schema/accounts.d.ts +6 -0
  73. package/dist/core/schema/accounts.js +13 -11
  74. package/dist/core/schema/config.d.ts +20 -8
  75. package/dist/core/schema/config.js +4 -4
  76. package/dist/core/schema/github.js +1 -1
  77. package/dist/core/schema/profile.js +8 -4
  78. package/dist/core/schema/resume.js +1 -1
  79. package/dist/core/schema/sandbox.js +3 -3
  80. package/dist/core/schema/vpn.js +1 -1
  81. package/dist/core/schema/web.js +3 -3
  82. package/dist/core/types.d.ts +6 -0
  83. package/dist/core/util/errors.d.ts +11 -1
  84. package/dist/core/util/errors.js +7 -1
  85. package/dist/core/util/index.d.ts +1 -1
  86. package/dist/core/util/index.js +1 -1
  87. package/dist/guest/accounts/adapter.d.ts +2 -0
  88. package/dist/guest/accounts/adapters.js +4 -0
  89. package/dist/guest/accounts/apply.d.ts +6 -2
  90. package/dist/guest/accounts/kinds/cfx.d.ts +7 -0
  91. package/dist/guest/accounts/kinds/cfx.js +33 -3
  92. package/dist/guest/accounts/kinds/comet.d.ts +7 -0
  93. package/dist/guest/accounts/kinds/comet.js +50 -0
  94. package/dist/guest/accounts/kinds/perplexity.d.ts +2 -0
  95. package/dist/guest/accounts/kinds/perplexity.js +12 -0
  96. package/dist/guest/accounts/watch.d.ts +2 -0
  97. package/dist/guest/accounts/watch.js +12 -2
  98. package/dist/guest/agents/agent-installer.js +1 -1
  99. package/dist/guest/agents/profile-links.d.ts +2 -0
  100. package/dist/guest/agents/profile-links.js +18 -4
  101. package/dist/guest/apps/after-install.js +19 -0
  102. package/dist/guest/apps/app-installer.d.ts +11 -0
  103. package/dist/guest/apps/app-installer.js +69 -6
  104. package/dist/guest/apps/comet-unpack.d.ts +20 -0
  105. package/dist/guest/apps/comet-unpack.js +127 -0
  106. package/dist/guest/apps/index.d.ts +1 -1
  107. package/dist/guest/apps/index.js +1 -1
  108. package/dist/guest/apps/resolvers-agents-web.d.ts +2 -0
  109. package/dist/guest/apps/resolvers-agents-web.js +7 -0
  110. package/dist/guest/apps/resolvers.js +2 -0
  111. package/dist/guest/apps/shortcuts.d.ts +2 -0
  112. package/dist/guest/apps/shortcuts.js +1 -0
  113. package/dist/guest/apps/unpack.js +14 -4
  114. package/dist/guest/boot/boot.d.ts +45 -16
  115. package/dist/guest/boot/boot.js +316 -145
  116. package/dist/guest/boot/graph.d.ts +252 -0
  117. package/dist/guest/boot/graph.js +257 -0
  118. package/dist/guest/boot/guide-lines.d.ts +25 -0
  119. package/dist/guest/boot/guide-lines.js +41 -0
  120. package/dist/guest/boot/guide.d.ts +1 -4
  121. package/dist/guest/boot/guide.js +6 -8
  122. package/dist/guest/boot/runner.d.ts +77 -0
  123. package/dist/guest/boot/runner.js +215 -0
  124. package/dist/guest/browser/cdp.d.ts +71 -0
  125. package/dist/guest/browser/cdp.js +306 -0
  126. package/dist/guest/browser/comet.d.ts +28 -0
  127. package/dist/guest/browser/comet.js +155 -0
  128. package/dist/guest/daemon/project-provisioner.js +6 -1
  129. package/dist/guest/devtools/fivem.d.ts +1 -1
  130. package/dist/guest/devtools/fivem.js +243 -3
  131. package/dist/guest/entries/daemon.js +2 -0
  132. package/dist/guest/runtime/log.d.ts +12 -0
  133. package/dist/guest/runtime/log.js +29 -5
  134. package/dist/guest/runtime/pools.d.ts +24 -0
  135. package/dist/guest/runtime/pools.js +60 -0
  136. package/dist/guest/runtime/process.d.ts +4 -0
  137. package/dist/guest/runtime/process.js +38 -1
  138. package/dist/guest/runtime/status.d.ts +5 -1
  139. package/dist/guest/runtime/status.js +19 -0
  140. package/dist/guest/setup/addon-mcp.d.ts +1 -1
  141. package/dist/guest/setup/addon-mcp.js +52 -12
  142. package/dist/guest/setup/agent-addons.d.ts +3 -2
  143. package/dist/guest/setup/agent-addons.js +12 -3
  144. package/dist/guest/setup/environment.d.ts +1 -1
  145. package/dist/guest/setup/environment.js +25 -12
  146. package/dist/guest/setup/headroom.d.ts +8 -3
  147. package/dist/guest/setup/headroom.js +44 -15
  148. package/dist/guest/setup/path-plan.d.ts +28 -0
  149. package/dist/guest/setup/path-plan.js +69 -2
  150. package/dist/guest/setup/shell-path.d.ts +1 -1
  151. package/dist/guest/setup/shell-path.js +3 -3
  152. package/dist/guest/toolchains/fivem/artifacts.d.ts +48 -1
  153. package/dist/guest/toolchains/fivem/artifacts.js +97 -4
  154. package/dist/guest/toolchains/fivem/fivem.d.ts +32 -1
  155. package/dist/guest/toolchains/fivem/fivem.js +168 -3
  156. package/dist/guest/toolchains/fivem/scaffold.d.ts +35 -0
  157. package/dist/guest/toolchains/fivem/scaffold.js +105 -0
  158. package/dist/guest/toolchains/fivem/serve-plan.d.ts +34 -0
  159. package/dist/guest/toolchains/fivem/serve-plan.js +61 -0
  160. package/dist/guest/toolchains/languages/go.js +1 -1
  161. package/dist/guest/toolchains/languages/node.js +2 -1
  162. package/dist/guest/toolchains/languages/php.d.ts +2 -0
  163. package/dist/guest/toolchains/languages/php.js +13 -1
  164. package/dist/guest/toolchains/languages/python-tools.js +1 -1
  165. package/dist/guest/toolchains/languages/ruby.js +1 -1
  166. package/dist/guest/toolchains/native/binstall.js +1 -1
  167. package/dist/guest/toolchains/native/msvc/packages.js +10 -4
  168. package/dist/guest/toolchains/native/rust.d.ts +2 -0
  169. package/dist/guest/toolchains/native/rust.js +11 -4
  170. package/dist/guest/toolchains/native/unreal.d.ts +2 -0
  171. package/dist/guest/toolchains/native/unreal.js +16 -6
  172. package/dist/guest/toolchains/native/vcruntime.d.ts +2 -0
  173. package/dist/guest/toolchains/native/vcruntime.js +10 -2
  174. package/dist/guest/toolchains/native/visual-studio.d.ts +3 -0
  175. package/dist/guest/toolchains/native/visual-studio.js +44 -26
  176. package/dist/guest/toolchains/native/vs-request.d.ts +2 -0
  177. package/dist/guest/toolchains/native/vs-request.js +2 -0
  178. package/dist/guest/toolchains/plan.js +19 -8
  179. package/dist/guest/toolchains/scheduler.d.ts +2 -21
  180. package/dist/guest/toolchains/scheduler.js +7 -121
  181. package/dist/guest/toolchains/setup.d.ts +15 -2
  182. package/dist/guest/toolchains/setup.js +39 -20
  183. package/dist/guest/toolchains/split.d.ts +28 -0
  184. package/dist/guest/toolchains/split.js +60 -0
  185. package/dist/guest/toolchains/steam/client.js +2 -1
  186. package/dist/guest/toolchains/step-scheduler.d.ts +51 -0
  187. package/dist/guest/toolchains/step-scheduler.js +147 -0
  188. package/dist/guest/toolchains/step.d.ts +13 -0
  189. package/dist/guest/toolchains/tools/git.js +18 -0
  190. package/dist/guest/vpn/openvpn.js +3 -4
  191. package/dist/guest/vpn/wireguard.js +11 -4
  192. package/dist/host/accounts/deliver.js +7 -0
  193. package/dist/host/accounts/handoff.js +2 -6
  194. package/dist/host/accounts/index.d.ts +1 -1
  195. package/dist/host/accounts/index.js +1 -1
  196. package/dist/host/accounts/kinds/cfx.d.ts +1 -1
  197. package/dist/host/accounts/kinds/cfx.js +47 -4
  198. package/dist/host/accounts/kinds/comet.d.ts +2 -0
  199. package/dist/host/accounts/kinds/comet.js +6 -0
  200. package/dist/host/accounts/kinds/perplexity.d.ts +2 -0
  201. package/dist/host/accounts/kinds/perplexity.js +30 -0
  202. package/dist/host/accounts/leases.d.ts +7 -1
  203. package/dist/host/accounts/leases.js +13 -2
  204. package/dist/host/accounts/source.d.ts +7 -1
  205. package/dist/host/accounts/source.js +27 -0
  206. package/dist/host/accounts/sources.js +4 -0
  207. package/dist/host/github/deliver.d.ts +1 -1
  208. package/dist/host/github/deliver.js +20 -1
  209. package/dist/host/github/index.d.ts +2 -1
  210. package/dist/host/github/index.js +1 -0
  211. package/dist/host/github/token.d.ts +13 -1
  212. package/dist/host/github/token.js +19 -2
  213. package/dist/host/github/verify.d.ts +27 -0
  214. package/dist/host/github/verify.js +61 -0
  215. package/dist/host/launch/hints/fivem.d.ts +3 -1
  216. package/dist/host/launch/hints/fivem.js +68 -2
  217. package/dist/host/launch/session-file.js +4 -0
  218. package/dist/host/launch/toolchains.d.ts +2 -1
  219. package/dist/host/launch/toolchains.js +5 -3
  220. package/dist/host/profile/claude-login.d.ts +2 -2
  221. package/dist/host/profile/claude-login.js +4 -3
  222. package/dist/host/vpn/nordvpn.d.ts +2 -4
  223. package/dist/host/vpn/nordvpn.js +2 -24
  224. package/dist/runtime/agent.js +405 -90
  225. package/dist/runtime/daemon.js +3010 -1383
  226. package/dist/runtime/db.js +333 -90
  227. package/dist/runtime/main.js +4720 -1954
  228. package/dist/runtime/netproxy.js +286 -69
  229. package/dist/runtime/tool.js +2852 -1780
  230. package/dist/runtime/view.js +286 -69
  231. package/dist/selftest/accounts.test.js +1 -1
  232. package/dist/selftest/agent-paths.test.js +39 -1
  233. package/dist/selftest/agent-settings.test.js +6 -0
  234. package/dist/selftest/agents-web.test.d.ts +2 -0
  235. package/dist/selftest/agents-web.test.js +647 -0
  236. package/dist/selftest/app.test.js +5 -2
  237. package/dist/selftest/boot-runner.test.d.ts +2 -0
  238. package/dist/selftest/boot-runner.test.js +456 -0
  239. package/dist/selftest/channel.test.js +15 -0
  240. package/dist/selftest/fivem.test.js +249 -3
  241. package/dist/selftest/github.test.js +94 -9
  242. package/dist/selftest/guest-boot.test.js +3 -0
  243. package/dist/selftest/health.test.js +1 -1
  244. package/dist/selftest/index.js +8 -0
  245. package/dist/selftest/layout.test.js +5 -0
  246. package/dist/selftest/menu-coverage.test.d.ts +2 -0
  247. package/dist/selftest/menu-coverage.test.js +46 -0
  248. package/dist/selftest/menu-screens.js +37 -1
  249. package/dist/selftest/persisted-installs.test.js +6 -3
  250. package/dist/selftest/service-accounts.test.js +3 -2
  251. package/dist/selftest/support/engine-golden.js +27 -0
  252. package/dist/selftest/support/fixtures.d.ts +6 -0
  253. package/dist/selftest/support/web-preview.d.ts +34 -1
  254. package/dist/selftest/support/web-preview.js +21 -18
  255. package/dist/selftest/toolchains.test.js +23 -1
  256. package/dist/selftest/ui-text.test.d.ts +7 -0
  257. package/dist/selftest/ui-text.test.js +300 -0
  258. package/dist/shared/accounts/anthropic.d.ts +1 -1
  259. package/dist/shared/accounts/anthropic.js +9 -8
  260. package/dist/shared/accounts/index.d.ts +2 -0
  261. package/dist/shared/accounts/index.js +2 -0
  262. package/dist/shared/accounts/kinds/comet.d.ts +12 -0
  263. package/dist/shared/accounts/kinds/comet.js +64 -0
  264. package/dist/shared/accounts/kinds/perplexity.d.ts +8 -0
  265. package/dist/shared/accounts/kinds/perplexity.js +37 -0
  266. package/dist/shared/accounts/kinds.d.ts +24 -5
  267. package/dist/shared/accounts/kinds.js +86 -4
  268. package/dist/shared/accounts/payloads.d.ts +81 -0
  269. package/dist/shared/accounts/payloads.js +39 -1
  270. package/dist/shared/apps/agent-addons.d.ts +33 -5
  271. package/dist/shared/apps/agent-addons.js +95 -3
  272. package/dist/shared/apps/catalogue-agents-web.d.ts +14 -0
  273. package/dist/shared/apps/catalogue-agents-web.js +112 -0
  274. package/dist/shared/apps/catalogue-modding.js +32 -1
  275. package/dist/shared/apps/catalogue.d.ts +27 -3
  276. package/dist/shared/apps/catalogue.js +2 -1
  277. package/dist/shared/apps/index.d.ts +3 -1
  278. package/dist/shared/apps/index.js +3 -1
  279. package/dist/shared/channel/schema.d.ts +21 -3
  280. package/dist/shared/channel/schema.js +7 -0
  281. package/dist/shared/channel/secrets.d.ts +19 -0
  282. package/dist/shared/concurrency/index.d.ts +3 -0
  283. package/dist/shared/concurrency/index.js +3 -0
  284. package/dist/shared/concurrency/installer-retry.d.ts +6 -0
  285. package/dist/shared/concurrency/installer-retry.js +10 -0
  286. package/dist/shared/concurrency/limiter.d.ts +19 -0
  287. package/dist/shared/concurrency/limiter.js +67 -0
  288. package/dist/shared/concurrency/pools.d.ts +7 -0
  289. package/dist/shared/concurrency/pools.js +9 -0
  290. package/dist/shared/download/archive.d.ts +2 -0
  291. package/dist/shared/download/archive.js +11 -1
  292. package/dist/shared/download/bounded-fetch.d.ts +13 -0
  293. package/dist/shared/download/bounded-fetch.js +40 -0
  294. package/dist/shared/download/downloader.d.ts +5 -0
  295. package/dist/shared/download/downloader.js +50 -38
  296. package/dist/shared/download/index.d.ts +2 -1
  297. package/dist/shared/download/index.js +2 -1
  298. package/dist/shared/readiness.d.ts +2 -2
  299. package/dist/shared/readiness.js +2 -2
  300. package/dist/web/index.html +1 -1
  301. package/dist/web/{main-OUUQYNK4.js → main-CCILLX2M.js} +67 -67
  302. package/native/csharp/HcsHost/AssemblyInfo.cs +3 -3
  303. package/native/csharp/HostTools/AssemblyInfo.cs +3 -3
  304. package/native/csharp/StorageHelper/AssemblyInfo.cs +3 -3
  305. package/package.json +1 -1
  306. package/sandbox/addons/browser-use-mcp/requirements.in +1 -0
  307. package/sandbox/addons/browser-use-mcp/requirements.txt +2350 -0
  308. package/sandbox/addons/chrome-devtools-mcp/package-lock.json +38 -0
  309. package/sandbox/addons/chrome-devtools-mcp/package.json +7 -0
  310. package/sandbox/addons/comet-mcp/package-lock.json +1277 -0
  311. package/sandbox/addons/comet-mcp/package.json +7 -0
  312. package/sandbox/addons/perplexity-mcp/package-lock.json +1655 -0
  313. package/sandbox/addons/perplexity-mcp/package.json +7 -0
  314. package/sandbox/scripts/add-firewall-port.ps1 +18 -4
  315. package/sandbox/scripts/set-machine-environment.ps1 +30 -15
  316. package/sandbox/templates/fivem/README.txt +6 -2
  317. package/sandbox/templates/fivem/cs/Client/Client.csproj +15 -0
  318. package/sandbox/templates/fivem/cs/Client/ClientMain.cs +20 -0
  319. package/sandbox/templates/fivem/cs/Server/Server.csproj +14 -0
  320. package/sandbox/templates/fivem/cs/Server/ServerMain.cs +20 -0
  321. package/sandbox/templates/fivem/cs/fxmanifest.lua +11 -0
  322. package/sandbox/templates/fivem/js/client.js +12 -0
  323. package/sandbox/templates/fivem/js/fxmanifest.lua +9 -0
  324. package/sandbox/templates/fivem/js/server.js +6 -0
  325. package/sandbox/templates/fivem/lua/client.lua +8 -0
  326. package/sandbox/templates/fivem/lua/fxmanifest.lua +10 -0
  327. package/sandbox/templates/fivem/lua/server.lua +6 -0
  328. package/sandbox/templates/fivem/server.cfg +37 -0
  329. package/sandbox/templates/fivem/ts/build.js +17 -0
  330. package/sandbox/templates/fivem/ts/fxmanifest.lua +9 -0
  331. package/sandbox/templates/fivem/ts/package.json +16 -0
  332. package/sandbox/templates/fivem/ts/src/client/client.ts +12 -0
  333. package/sandbox/templates/fivem/ts/src/client/tsconfig.json +13 -0
  334. package/sandbox/templates/fivem/ts/src/server/server.ts +6 -0
  335. package/sandbox/templates/fivem/ts/src/server/tsconfig.json +13 -0
  336. package/schemas/config.schema.json +56 -27
  337. package/schemas/sandbox-config.schema.json +37 -14
@@ -722,11 +722,11 @@ var require_lodash = __commonJS({
722
722
  function unicodeWords(string4) {
723
723
  return string4.match(reUnicodeWord) || [];
724
724
  }
725
- var runInContext = (function runInContext2(context) {
726
- context = context == null ? root : _2.defaults(root.Object(), context, _2.pick(root, contextProps));
727
- var Array2 = context.Array, Date2 = context.Date, Error2 = context.Error, Function2 = context.Function, Math2 = context.Math, Object2 = context.Object, RegExp2 = context.RegExp, String2 = context.String, TypeError2 = context.TypeError;
725
+ var runInContext = (function runInContext2(context2) {
726
+ context2 = context2 == null ? root : _2.defaults(root.Object(), context2, _2.pick(root, contextProps));
727
+ var Array2 = context2.Array, Date2 = context2.Date, Error2 = context2.Error, Function2 = context2.Function, Math2 = context2.Math, Object2 = context2.Object, RegExp2 = context2.RegExp, String2 = context2.String, TypeError2 = context2.TypeError;
728
728
  var arrayProto = Array2.prototype, funcProto = Function2.prototype, objectProto = Object2.prototype;
729
- var coreJsData = context["__core-js_shared__"];
729
+ var coreJsData = context2["__core-js_shared__"];
730
730
  var funcToString = funcProto.toString;
731
731
  var hasOwnProperty = objectProto.hasOwnProperty;
732
732
  var idCounter = 0;
@@ -740,7 +740,7 @@ var require_lodash = __commonJS({
740
740
  var reIsNative = RegExp2(
741
741
  "^" + funcToString.call(hasOwnProperty).replace(reRegExpChar, "\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, "$1.*?") + "$"
742
742
  );
743
- var Buffer2 = moduleExports ? context.Buffer : undefined2, Symbol2 = context.Symbol, Uint8Array2 = context.Uint8Array, allocUnsafe = Buffer2 ? Buffer2.allocUnsafe : undefined2, getPrototype = overArg(Object2.getPrototypeOf, Object2), objectCreate = Object2.create, propertyIsEnumerable = objectProto.propertyIsEnumerable, splice = arrayProto.splice, spreadableSymbol = Symbol2 ? Symbol2.isConcatSpreadable : undefined2, symIterator = Symbol2 ? Symbol2.iterator : undefined2, symToStringTag = Symbol2 ? Symbol2.toStringTag : undefined2;
743
+ var Buffer2 = moduleExports ? context2.Buffer : undefined2, Symbol2 = context2.Symbol, Uint8Array2 = context2.Uint8Array, allocUnsafe = Buffer2 ? Buffer2.allocUnsafe : undefined2, getPrototype = overArg(Object2.getPrototypeOf, Object2), objectCreate = Object2.create, propertyIsEnumerable = objectProto.propertyIsEnumerable, splice = arrayProto.splice, spreadableSymbol = Symbol2 ? Symbol2.isConcatSpreadable : undefined2, symIterator = Symbol2 ? Symbol2.iterator : undefined2, symToStringTag = Symbol2 ? Symbol2.toStringTag : undefined2;
744
744
  var defineProperty = (function() {
745
745
  try {
746
746
  var func = getNative(Object2, "defineProperty");
@@ -749,9 +749,9 @@ var require_lodash = __commonJS({
749
749
  } catch (e) {
750
750
  }
751
751
  })();
752
- var ctxClearTimeout = context.clearTimeout !== root.clearTimeout && context.clearTimeout, ctxNow = Date2 && Date2.now !== root.Date.now && Date2.now, ctxSetTimeout = context.setTimeout !== root.setTimeout && context.setTimeout;
753
- var nativeCeil = Math2.ceil, nativeFloor = Math2.floor, nativeGetSymbols = Object2.getOwnPropertySymbols, nativeIsBuffer = Buffer2 ? Buffer2.isBuffer : undefined2, nativeIsFinite = context.isFinite, nativeJoin = arrayProto.join, nativeKeys = overArg(Object2.keys, Object2), nativeMax = Math2.max, nativeMin = Math2.min, nativeNow = Date2.now, nativeParseInt = context.parseInt, nativeRandom = Math2.random, nativeReverse = arrayProto.reverse;
754
- var DataView = getNative(context, "DataView"), Map2 = getNative(context, "Map"), Promise2 = getNative(context, "Promise"), Set2 = getNative(context, "Set"), WeakMap2 = getNative(context, "WeakMap"), nativeCreate = getNative(Object2, "create");
752
+ var ctxClearTimeout = context2.clearTimeout !== root.clearTimeout && context2.clearTimeout, ctxNow = Date2 && Date2.now !== root.Date.now && Date2.now, ctxSetTimeout = context2.setTimeout !== root.setTimeout && context2.setTimeout;
753
+ var nativeCeil = Math2.ceil, nativeFloor = Math2.floor, nativeGetSymbols = Object2.getOwnPropertySymbols, nativeIsBuffer = Buffer2 ? Buffer2.isBuffer : undefined2, nativeIsFinite = context2.isFinite, nativeJoin = arrayProto.join, nativeKeys = overArg(Object2.keys, Object2), nativeMax = Math2.max, nativeMin = Math2.min, nativeNow = Date2.now, nativeParseInt = context2.parseInt, nativeRandom = Math2.random, nativeReverse = arrayProto.reverse;
754
+ var DataView = getNative(context2, "DataView"), Map2 = getNative(context2, "Map"), Promise2 = getNative(context2, "Promise"), Set2 = getNative(context2, "Set"), WeakMap2 = getNative(context2, "WeakMap"), nativeCreate = getNative(Object2, "create");
755
755
  var metaMap = WeakMap2 && new WeakMap2();
756
756
  var realNames = {};
757
757
  var dataViewCtorString = toSource(DataView), mapCtorString = toSource(Map2), promiseCtorString = toSource(Promise2), setCtorString = toSource(Set2), weakMapCtorString = toSource(WeakMap2);
@@ -25426,15 +25426,17 @@ var SecretsSchema = external_exports.strictObject({
25426
25426
  )
25427
25427
  });
25428
25428
  var AttachSchema = external_exports.strictObject({
25429
- enabled: external_exports.boolean().describe("Allow sandbox claude --terminal / sandbox attach from this PC."),
25429
+ enabled: external_exports.boolean().describe(
25430
+ "Allow attaching this PC's terminal to a session (the terminal option when starting an agent, and attach)."
25431
+ ),
25430
25432
  reuseSession: external_exports.boolean().describe(
25431
- "sandbox claude -t in a running sandbox reattaches to this folder's session when no terminal on this PC is attached to it (--new always starts another)."
25433
+ "Starting an agent with a terminal in a running sandbox reattaches to this folder's session when no terminal on this PC is attached to it (starting a new session on purpose always starts another)."
25432
25434
  ),
25433
25435
  auto: external_exports.boolean().describe(
25434
25436
  "Starting an agent attaches this terminal automatically, as if you passed -t (only in an interactive terminal)."
25435
25437
  ),
25436
25438
  autoHide: external_exports.boolean().describe(
25437
- "Hide the Windows Sandbox window whenever this terminal attaches; it keeps running (sandbox show brings it back)."
25439
+ "Hide the Windows Sandbox window whenever this terminal attaches; it keeps running (Sandbox > Status shows it again)."
25438
25440
  ),
25439
25441
  confirmCtrlC: external_exports.boolean().describe(
25440
25442
  'In an attached terminal and the sandbox window, a single Ctrl+C is held back (the title says so) and only a second one within 1.5 seconds reaches the agent: a Ctrl+C meant as "copy" no longer stops it. Esc still stops an agent.'
@@ -25451,7 +25453,7 @@ var ClaudeProfileSchema = external_exports.strictObject({
25451
25453
  hostDir: external_exports.string().describe('Your Claude folder, or "auto" (~/.claude or CLAUDE_CONFIG_DIR).'),
25452
25454
  include: external_exports.array(external_exports.string().regex(/^[A-Za-z0-9._-]+$/)).describe("Files and folders copied from it."),
25453
25455
  globalStateFile: external_exports.string().describe('Your .claude.json, or "auto". Empty string = do not copy.'),
25454
- copyCredentials: external_exports.boolean().describe("Copy your Claude LOGIN into the sandbox. Prefer sandbox account instead."),
25456
+ copyCredentials: external_exports.boolean().describe("Copy your Claude LOGIN into the sandbox. Prefer saving the login in Accounts instead."),
25455
25457
  overwrite: external_exports.boolean().describe("Refresh these settings from this PC on every launch."),
25456
25458
  sharePluginsAcrossAccounts: external_exports.boolean().describe(
25457
25459
  "When you switch Claude accounts, copy your Claude plugins (and which ones are enabled) into a data set that has none yet. Off by default: plugins are code that runs in your sessions."
@@ -25480,7 +25482,7 @@ var MappingSchema = external_exports.strictObject({
25480
25482
  });
25481
25483
  var SandboxSchema = external_exports.strictObject({
25482
25484
  engine: external_exports.enum(["windows-sandbox", "hcs"]).describe(
25483
- '(alpha) What runs the sandbox. "windows-sandbox" = Windows Sandbox (the default: desktop, Windows Terminal, GPU, clipboard, audio, printers). "hcs" = a headless Hyper-V isolated Server Core container for agents (no desktop, GPU or clipboard); it needs Windows features and an image on this PC (sandbox engine check hcs lists what is missing), and starting it is not enabled yet in this alpha. sandbox engine shows what each engine can do. Yours only: a project file (.sandbox-config.json) cannot set it.'
25485
+ '(alpha) What runs the sandbox. "windows-sandbox" = Windows Sandbox (the default: desktop, Windows Terminal, GPU, clipboard, audio, printers). "hcs" = a headless Hyper-V isolated Server Core container for agents (no desktop, GPU or clipboard); it needs Windows features and an image on this PC (Maintenance > Engine lists what is missing), and starting it is not enabled yet in this alpha. Maintenance > Engine shows what each engine can do. Yours only: a project file (.sandbox-config.json) cannot set it.'
25484
25486
  ),
25485
25487
  memoryMb: external_exports.union([external_exports.literal("auto"), external_exports.number().int().min(2048)]).describe(
25486
25488
  'Sandbox RAM in MB (>= 2048), or "auto": free RAM minus reserveHostMb, capped at maxMemoryMb. Never more than this PC can keep in RAM for it (its RAM minus the larger of reserveHostMb and 25 %, 4 GB more with vGPU): a bigger value is lowered.'
@@ -25507,7 +25509,7 @@ var SandboxSchema = external_exports.strictObject({
25507
25509
  ),
25508
25510
  networking: external_exports.boolean().describe("Internet access. false is the only hard network isolation Windows Sandbox offers."),
25509
25511
  clipboard: external_exports.boolean().describe(
25510
- "Shared clipboard between this PC and the sandbox. Also lets an agent's copy (in sandbox attach) reach this PC's clipboard."
25512
+ "Shared clipboard between this PC and the sandbox. Also lets an agent's copy (in an attached terminal) reach this PC's clipboard."
25511
25513
  ),
25512
25514
  audioInput: external_exports.boolean().describe("Microphone access."),
25513
25515
  videoInput: external_exports.boolean().describe("Camera access."),
@@ -25558,7 +25560,7 @@ var NetworkSchema = external_exports.strictObject({
25558
25560
  });
25559
25561
  var AuditSchema = external_exports.strictObject({
25560
25562
  enabled: external_exports.boolean().describe(
25561
- "Keep an audit log on this PC of what your agents did: programs started (with their command lines, secrets hidden), files changed in the projects, git commits, sessions, and what the repo guard caught, each linked to the agent session that did it where that can be known. The sandbox cannot change it. Read it with sandbox audit or on the Activity page."
25563
+ "Keep an audit log on this PC of what your agents did: programs started (with their command lines, secrets hidden), files changed in the projects, git commits, sessions, and what the repo guard caught, each linked to the agent session that did it where that can be known. The sandbox cannot change it. Read it on the Activity page."
25562
25564
  ),
25563
25565
  days: external_exports.number().int().min(1).max(365).describe(
25564
25566
  "Days the audit log is kept (1 to 30; a larger number keeps 30); older days are deleted when a sandbox starts and once a day."
@@ -25902,6 +25904,114 @@ var ToolchainsSchema = external_exports.strictObject({
25902
25904
  )
25903
25905
  });
25904
25906
 
25907
+ // src/shared/apps/catalogue-agents-web.ts
25908
+ var PERPLEXITY_MCP_VERSION = "1.3.0";
25909
+ var COMET_MCP_VERSION = "2.3.0";
25910
+ var CHROME_DEVTOOLS_MCP_VERSION = "1.12.0";
25911
+ var BROWSER_USE_VERSION = "0.13.14";
25912
+ var PERPLEXITY_COMPUTER_MCP_URL = "https://www.perplexity.ai/rest/computer/mcp";
25913
+ var COMET_SIGNER = {
25914
+ subject: ['^CN="?PERPLEXITY AI, INC\\.?"?(,|$)', '(^|, )O="?PERPLEXITY AI, INC\\.?"?(,|$)'],
25915
+ issuer: ["^CN=GlobalSign GCC R45 EV CodeSigning CA 2020(,|$)"]
25916
+ };
25917
+ var EDGE_EXE = "C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe";
25918
+ var AGENTS_WEB_APPS = [
25919
+ {
25920
+ id: "perplexity-mcp",
25921
+ name: "Perplexity MCP (API)",
25922
+ category: "agents",
25923
+ about: "Web search, answers and deep research from Perplexity's API in Claude Code and Codex (perplexity_search, perplexity_ask, perplexity_research, perplexity_reason): Perplexity's own @perplexity-ai/mcp-server. Needs your Perplexity API key in Accounts; API use is billed separately from Perplexity Pro.",
25924
+ size: "30 MB",
25925
+ source: { locked: "npm", package: "@perplexity-ai/mcp-server", version: PERPLEXITY_MCP_VERSION },
25926
+ exe: "perplexity-mcp.cmd",
25927
+ service: true,
25928
+ mcp: {
25929
+ name: "sbx-perplexity",
25930
+ script: "node_modules/@perplexity-ai/mcp-server/dist/index.js",
25931
+ envVars: ["PERPLEXITY_API_KEY"],
25932
+ codex: true
25933
+ },
25934
+ plugsInto: "Claude Code and Codex as the MCP server sbx-perplexity; the key comes from Accounts as PERPLEXITY_API_KEY, never from a file",
25935
+ userOnly: true
25936
+ },
25937
+ {
25938
+ id: "perplexity-computer-mcp",
25939
+ name: "Perplexity Computer MCP",
25940
+ category: "agents",
25941
+ about: "Hands tasks to Perplexity Computer, Perplexity's cloud agent (it browses and works in its own cloud computer), from Claude Code and Codex: Perplexity's official remote MCP server. Nothing is installed. Sign in with your Perplexity account the first time (Claude Code: /mcp; Codex: codex mcp login sbx-perplexity-computer); tasks spend your Computer credits.",
25942
+ size: "0 MB",
25943
+ source: { remote: true },
25944
+ exe: "",
25945
+ service: true,
25946
+ mcp: { name: "sbx-perplexity-computer", url: PERPLEXITY_COMPUTER_MCP_URL, codex: true },
25947
+ plugsInto: "Claude Code and Codex as the remote MCP server sbx-perplexity-computer; its sign-in is kept with your agent login",
25948
+ userOnly: true
25949
+ },
25950
+ {
25951
+ id: "comet",
25952
+ name: "Comet (Perplexity browser)",
25953
+ category: "browsers",
25954
+ about: "Perplexity's agentic browser (Chromium), unpacked to run portable with its own profile on the sandbox's disk. With accounts.comet.share on, your perplexity.ai sign-in is kept for the next sandboxes. Its assistant acts on the pages it reads, so a page can try to steer it: browse only what you would let it act on.",
25955
+ size: "600 MB",
25956
+ source: { resolve: "comet" },
25957
+ unpack: "chromium",
25958
+ exe: "comet.exe",
25959
+ needs: ["7zip"],
25960
+ signer: COMET_SIGNER,
25961
+ userOnly: true
25962
+ },
25963
+ {
25964
+ id: "comet-mcp",
25965
+ name: "Comet MCP",
25966
+ category: "agents",
25967
+ about: "Lets Claude Code and Codex hand web tasks to Comet's own assistant and read its answers (hanzili/comet-mcp). Needs the Comet app: start Comet from its shortcut first, so the agent uses the sandbox's Comet profile and your sign-in.",
25968
+ size: "15 MB",
25969
+ source: { locked: "npm", package: "comet-mcp", version: COMET_MCP_VERSION },
25970
+ exe: "comet-mcp.cmd",
25971
+ service: true,
25972
+ mcp: { name: "sbx-comet", script: "node_modules/comet-mcp/dist/index.js", codex: true },
25973
+ plugsInto: "Claude Code and Codex as the MCP server sbx-comet, talking to Comet's DevTools on 127.0.0.1:9222",
25974
+ userOnly: true
25975
+ },
25976
+ {
25977
+ id: "chrome-devtools-mcp",
25978
+ name: "Chrome DevTools MCP",
25979
+ category: "agents",
25980
+ about: "Lets Claude Code and Codex drive and inspect a browser with DevTools: navigate, click, read the console and network, record performance traces (ChromeDevTools/chrome-devtools-mcp). It starts Microsoft Edge with a throwaway profile; Google's usage statistics and CrUX lookups are off.",
25981
+ size: "40 MB",
25982
+ source: { locked: "npm", package: "chrome-devtools-mcp", version: CHROME_DEVTOOLS_MCP_VERSION },
25983
+ exe: "chrome-devtools-mcp.cmd",
25984
+ service: true,
25985
+ mcp: {
25986
+ name: "sbx-chrome-devtools",
25987
+ script: "node_modules/chrome-devtools-mcp/build/src/bin/chrome-devtools-mcp.js",
25988
+ args: ["--executablePath", EDGE_EXE, "--isolated", "--no-usage-statistics", "--no-performance-crux"],
25989
+ codex: true
25990
+ },
25991
+ plugsInto: "Claude Code and Codex as the MCP server sbx-chrome-devtools (with Edge)",
25992
+ userOnly: true
25993
+ },
25994
+ {
25995
+ id: "browser-use-mcp",
25996
+ name: "Browser Use MCP",
25997
+ category: "agents",
25998
+ about: "Browser automation for agents from Browser Use (browser-use --mcp): open pages, click, type, read them, and hand a whole task to Browser Use's own agent (that one needs an OpenAI or Anthropic API key). It finds Edge in the sandbox; its telemetry is off.",
25999
+ size: "250 MB",
26000
+ source: { locked: "uv", package: "browser-use", version: BROWSER_USE_VERSION },
26001
+ exe: "browser-use.exe",
26002
+ service: true,
26003
+ mcp: {
26004
+ name: "sbx-browser-use",
26005
+ program: true,
26006
+ args: ["--mcp"],
26007
+ env: { ANONYMIZED_TELEMETRY: "false" },
26008
+ codex: true
26009
+ },
26010
+ plugsInto: "Claude Code and Codex as the MCP server sbx-browser-use",
26011
+ userOnly: true
26012
+ }
26013
+ ];
26014
+
25905
26015
  // src/shared/apps/catalogue-gamedev.ts
25906
26016
  var GAMEDEV_APPS = [];
25907
26017
 
@@ -25909,7 +26019,38 @@ var GAMEDEV_APPS = [];
25909
26019
  var MOBILE_APPS = [];
25910
26020
 
25911
26021
  // src/shared/apps/catalogue-modding.ts
25912
- var MODDING_APPS = [];
26022
+ var MODDING_APPS = [
26023
+ {
26024
+ id: "lua-language-server",
26025
+ name: "Lua Language Server",
26026
+ category: "cli",
26027
+ about: "The Lua language server (LuaLS): completion, diagnostics and go-to-definition for Lua in editors and agents that speak LSP. FiveM resources use Lua 5.4 (lua54 in fxmanifest.lua).",
26028
+ size: "15 MB",
26029
+ source: { github: "LuaLS/lua-language-server", asset: "^lua-language-server-[\\d.]+-win32-x64\\.zip$" },
26030
+ exe: "lua-language-server.exe",
26031
+ cli: true
26032
+ },
26033
+ {
26034
+ id: "stylua",
26035
+ name: "StyLua",
26036
+ category: "cli",
26037
+ about: "An opinionated Lua formatter (`stylua .`), configured with a stylua.toml in the project.",
26038
+ size: "6 MB",
26039
+ source: { github: "JohnnyMorganz/StyLua", asset: "^stylua-windows-x86_64\\.zip$" },
26040
+ exe: "stylua.exe",
26041
+ cli: true
26042
+ },
26043
+ {
26044
+ id: "selene",
26045
+ name: "selene",
26046
+ category: "cli",
26047
+ about: 'A Lua linter (`selene .`), configured with a selene.toml (std = "lua54", and a standard library file for the FiveM / RedM globals).',
26048
+ size: "7 MB",
26049
+ source: { github: "Kampfkarren/selene", asset: "^selene-[\\d.]+-windows\\.zip$" },
26050
+ exe: "selene.exe",
26051
+ cli: true
26052
+ }
26053
+ ];
25913
26054
 
25914
26055
  // src/shared/apps/catalogue.ts
25915
26056
  var gh = (github, asset) => ({ github, asset });
@@ -26743,7 +26884,7 @@ var CORE_APPS = [
26743
26884
  cli: true
26744
26885
  }
26745
26886
  ];
26746
- var APPS = [...CORE_APPS, ...GAMEDEV_APPS, ...MODDING_APPS, ...MOBILE_APPS];
26887
+ var APPS = [...CORE_APPS, ...GAMEDEV_APPS, ...MODDING_APPS, ...MOBILE_APPS, ...AGENTS_WEB_APPS];
26747
26888
 
26748
26889
  // src/core/schema/apps.ts
26749
26890
  var CATALOGUE_IDS = APPS.filter((a) => !a.setting).map((a) => a.id);
@@ -26813,7 +26954,7 @@ var ProjectsSchema = external_exports.strictObject({
26813
26954
  var RESUME_SESSIONS = ["ask", "always", "afterCrash", "never"];
26814
26955
  var ResumeSchema = external_exports.strictObject({
26815
26956
  sessions: external_exports.enum(RESUME_SESSIONS).describe(
26816
- 'When a sandbox starts after one that had agent sessions: "ask" lists them and asks whether to reopen them (without a terminal it prints the command sandbox resume), "always" reopens them, "afterCrash" reopens them only when the last sandbox ended unexpectedly, "never" leaves it to sandbox resume. Terminal tabs you opened yourself in the sandbox are never reopened.'
26957
+ 'When a sandbox starts after one that had agent sessions: "ask" lists them and asks whether to reopen them (without a terminal it only says they can be reopened), "always" reopens them, "afterCrash" reopens them only when the last sandbox ended unexpectedly, "never" leaves it to you (Sessions reopens them). Terminal tabs you opened yourself in the sandbox are never reopened.'
26817
26958
  ),
26818
26959
  restartAfterCrash: external_exports.boolean().describe(
26819
26960
  "When the sandbox ends because Windows Sandbox crashed or ran out of memory, start it again by itself and reopen its sessions (at most 3 times in 6 hours)."
@@ -26832,14 +26973,14 @@ var RemoteUserSchema = external_exports.strictObject({
26832
26973
  });
26833
26974
  var WebLanSchema = external_exports.strictObject({
26834
26975
  enabled: external_exports.boolean().describe(
26835
- "(Beta) Devices on your network (a phone): an HTTPS address on this PC for devices you pair with a one-time code (sandbox web pair). Needs a firewall rule (sandbox web lan on asks Windows once). Off: every paired device is signed out."
26976
+ "(Beta) Devices on your network (a phone): an HTTPS address on this PC for devices you pair with a one-time code (Remote access). Needs a firewall rule (turning it on asks Windows once). Off: every paired device is signed out."
26836
26977
  ),
26837
26978
  port: external_exports.number().int().min(1024).max(65535).describe("HTTPS port for paired devices on your network."),
26838
26979
  address: external_exports.string().trim().max(15).regex(/^$|^\d{1,3}(\.\d{1,3}){3}$/, "an IPv4 address or empty").describe("This PC's private address to listen on. Empty: the one of its network adapter (never a public one).")
26839
26980
  });
26840
26981
  var WebRemoteSchema = external_exports.strictObject({
26841
26982
  windowsSignIn: external_exports.boolean().describe(
26842
- "(Beta) Other Windows users of this PC named in web.remote.users sign in to your web UI (and sandbox remote) with their own Windows account: no password, no link."
26983
+ "(Beta) Other Windows users of this PC named in web.remote.users sign in to your web UI (and the remote menu) with their own Windows account: no password, no link."
26843
26984
  ),
26844
26985
  users: external_exports.array(RemoteUserSchema).max(32).describe("Who else may sign in with Windows, and their role (view or control)."),
26845
26986
  rememberDays: external_exports.number().int().min(1).max(90).describe(
@@ -26849,7 +26990,7 @@ var WebRemoteSchema = external_exports.strictObject({
26849
26990
  });
26850
26991
  var WebSchema = external_exports.strictObject({
26851
26992
  enabled: external_exports.boolean().describe(
26852
- "(Beta) The web UI: your sandbox sessions in a browser on this PC (http://127.0.0.1:<port>, this PC only). On: every sandbox start also starts it in the background (it keeps running until sandbox web stop or a restart of the PC). Off: only sandbox web start runs it. Open it signed in with sandbox web open."
26993
+ "(Beta) The web UI: your sessions in a browser on this PC (http://127.0.0.1:<port>, this PC only). On: every start of a sandbox also starts it in the background (it keeps running until you stop it in Maintenance > Web UI or restart the PC). Off: it runs only when you start it there. Open it signed in from the same page."
26853
26994
  ),
26854
26995
  port: external_exports.number().int().min(1024).max(65535).describe("Port of the web UI on 127.0.0.1 (this PC only). Pick another when it is taken."),
26855
26996
  openOnLaunch: external_exports.boolean().describe("(Beta) With the web UI on: open it in your browser, already signed in, every time a sandbox starts."),
@@ -26860,7 +27001,7 @@ var WebSchema = external_exports.strictObject({
26860
27001
  var VPN_PROVIDERS = ["nordvpn", "openvpn-file", "wireguard-file"];
26861
27002
  var VpnSchema = external_exports.strictObject({
26862
27003
  enabled: external_exports.boolean().describe(
26863
- "(Alpha: not yet tried on a real PC) Send the sandbox's traffic through a VPN. Only the sandbox: your PC's own connection is untouched. Needs a saved login first (sandbox vpn login). The agent in the sandbox can read that login and can turn the tunnel off (it is the administrator there)."
27004
+ "(Alpha: not yet tried on a real PC) Send the sandbox's traffic through a VPN. Only the sandbox: your PC's own connection is untouched. Needs a saved login first (Settings > Network > VPN). The agent in the sandbox can read that login and can turn the tunnel off (it is the administrator there)."
26864
27005
  ),
26865
27006
  provider: external_exports.enum(VPN_PROVIDERS).describe(
26866
27007
  "nordvpn: a recommended NordVPN server is picked at every launch. openvpn-file: your own .ovpn file (configFile). wireguard-file: your own WireGuard .conf (configFile), e.g. from your company."
@@ -26878,13 +27019,14 @@ var VpnSchema = external_exports.strictObject({
26878
27019
  // src/core/schema/github.ts
26879
27020
  var GithubSchema = external_exports.strictObject({
26880
27021
  shareToken: external_exports.boolean().describe(
26881
- 'Give each sandbox the GitHub token you saved with `sandbox github login` (best a fine-grained token limited to some repositories and permissions), so gh and https git work there without logging in. Only with provisioning.git.access "full". The agent in the sandbox can read the token and use it for whatever it allows. A project file (.sandbox-config.json) cannot turn this on.'
27022
+ 'Give each sandbox the GitHub token you saved in Accounts (best a fine-grained token limited to some repositories and permissions), so gh and https git work there without logging in. Only with provisioning.git.access "full". The agent in the sandbox can read the token and use it for whatever it allows. A project file (.sandbox-config.json) cannot turn this on.'
26882
27023
  )
26883
27024
  });
26884
27025
 
26885
27026
  // src/shared/accounts/kinds.ts
26886
27027
  var AGENT_CAN_USE = "The agent in the sandbox can use this sign-in while it is there.";
26887
27028
  var ONE_PLACE = "It works in one sandbox at a time: a second sandbox starts without it while the first one runs.";
27029
+ var PERPLEXITY_KEY_PATTERN = /^pplx-[A-Za-z0-9_-]{8,200}$/;
26888
27030
  var SERVICE_SPECS = {
26889
27031
  epic: {
26890
27032
  kind: "epic",
@@ -26938,19 +27080,28 @@ var SERVICE_SPECS = {
26938
27080
  kind: "cfx",
26939
27081
  label: "Cfx.re (FiveM / RedM server key)",
26940
27082
  usedBy: ["fivem"],
26941
- sources: ["typed"],
27083
+ sources: ["typed", "file"],
26942
27084
  singleHolder: false,
26943
27085
  returns: false,
27086
+ // `import cfx --from` reads a whole server.cfg (they often run to tens of KB); the payload itself is tiny.
26944
27087
  maxBytes: 4 * 1024,
27088
+ maxFileBytes: 256 * 1024,
26945
27089
  warnings: [AGENT_CAN_USE + " Anyone with the key can run a server under your Cfx.re account."],
26946
27090
  fields: [
26947
- { name: "licenseKey", label: "Server licence key (cfxk_...)", secret: true, pattern: /^cfxk_[A-Za-z0-9_]+$/ },
27091
+ {
27092
+ name: "licenseKey",
27093
+ label: "Server licence key (cfxk_...)",
27094
+ secret: true,
27095
+ pattern: /^cfxk_[A-Za-z0-9_]+$/,
27096
+ only: "typed"
27097
+ },
26948
27098
  {
26949
27099
  name: "steamWebApiKey",
26950
27100
  label: "Steam Web API key (optional)",
26951
27101
  secret: true,
26952
27102
  optional: true,
26953
- pattern: /^[A-F0-9]{32}$/
27103
+ pattern: /^[A-F0-9]{32}$/,
27104
+ only: "typed"
26954
27105
  }
26955
27106
  ]
26956
27107
  },
@@ -27004,33 +27155,77 @@ var SERVICE_SPECS = {
27004
27155
  { name: "issuerId", label: "Issuer ID", secret: false },
27005
27156
  { name: "keyId", label: "Key ID", secret: false, pattern: /^[A-Z0-9]{10}$/ }
27006
27157
  ]
27158
+ },
27159
+ perplexity: {
27160
+ kind: "perplexity",
27161
+ label: "Perplexity API key",
27162
+ usedBy: ["perplexity"],
27163
+ sources: ["pc", "file", "typed"],
27164
+ singleHolder: false,
27165
+ returns: false,
27166
+ maxBytes: 1024,
27167
+ maxFileBytes: 64 * 1024,
27168
+ warnings: [
27169
+ AGENT_CAN_USE + " It can read the key and spend your API credit: use a separate API key with a spending limit.",
27170
+ "Perplexity Pro does not include API use; the API key is billed separately.",
27171
+ "Only the variable PERPLEXITY_API_KEY of the agent gets it: nothing in the sandbox writes it to a file."
27172
+ ],
27173
+ fields: [
27174
+ {
27175
+ name: "apiKey",
27176
+ label: "Perplexity API key (pplx-...)",
27177
+ secret: true,
27178
+ pattern: PERPLEXITY_KEY_PATTERN,
27179
+ only: "typed"
27180
+ }
27181
+ ]
27182
+ },
27183
+ comet: {
27184
+ kind: "comet",
27185
+ label: "Comet (Perplexity browser)",
27186
+ usedBy: ["comet"],
27187
+ sources: ["sandbox"],
27188
+ singleHolder: false,
27189
+ returns: true,
27190
+ maxBytes: 256 * 1024,
27191
+ warnings: [
27192
+ AGENT_CAN_USE + " It can act as you in Comet and spend your Perplexity Computer credits; agentic browsing is open to prompt injection from the pages it reads.",
27193
+ "Your Comet sign-in can't be copied from this PC: Windows locks it to your PC account. Sign in once inside a sandbox and it is kept for the next ones.",
27194
+ "Only the perplexity.ai sign-in cookies are kept: never saved passwords, other sites, localStorage or history. Never import your main browser profile.",
27195
+ "Several sandboxes can use it at once: the sign-in the last one hands back is kept."
27196
+ ],
27197
+ fields: []
27007
27198
  }
27008
27199
  };
27200
+ var APP_USER_TEXT = {
27201
+ perplexity: "the Perplexity MCP app",
27202
+ comet: "the Comet app"
27203
+ };
27204
+ function usedByText(usedBy) {
27205
+ return usedBy.map((u) => u in APP_USER_TEXT ? APP_USER_TEXT[u] : u).join(" or ");
27206
+ }
27009
27207
 
27010
27208
  // src/core/schema/accounts.ts
27011
27209
  function share(kind, how) {
27012
27210
  const spec = SERVICE_SPECS[kind];
27013
27211
  return external_exports.strictObject({
27014
27212
  share: external_exports.boolean().describe(
27015
- "Hand your saved " + spec.label + " sign-in to sandboxes that use " + spec.usedBy.join(" or ") + " (" + how + "). Kept encrypted on this PC; " + spec.warnings.join(" ") + " Yours only: a project file can only turn it off."
27213
+ "Hand your saved " + spec.label + " sign-in to sandboxes that use " + usedByText(spec.usedBy) + " (" + how + "). Kept encrypted on this PC; " + spec.warnings.join(" ") + " Yours only: a project file can only turn it off."
27016
27214
  )
27017
27215
  });
27018
27216
  }
27019
27217
  var AccountsSchema = external_exports.strictObject({
27020
- epic: share("epic", "sign in to the launcher once in a sandbox, or take this PC's: sandbox account import epic"),
27021
- steam: share(
27022
- "steam",
27023
- "sign in once with sbx-steam login, or: sandbox account import steam --from <steamcmd folder>"
27024
- ),
27025
- unity: share("unity", "sign in once in a sandbox, or take this PC's licence: sandbox account import unity"),
27026
- cfx: share("cfx", "sandbox account login cfx"),
27027
- keystore: share("keystore", "sandbox account import keystore --from <upload.jks>"),
27028
- play: share("play", "sandbox account import play --from <service-account.json>"),
27029
- expo: share("expo", "sandbox account login expo"),
27030
- appstore: share("appstore", "sandbox account import appstore --from <AuthKey.p8>")
27031
- }).describe(
27032
- "Service sign-ins for sandboxes (game stores, engines, app signing). Manage them in Accounts: sandbox account status."
27033
- );
27218
+ epic: share("epic", "sign in to the launcher once in a sandbox, or take this PC's from Accounts"),
27219
+ steam: share("steam", "sign in once with sbx-steam login, or take it from a SteamCMD folder in Accounts"),
27220
+ unity: share("unity", "sign in once in a sandbox, or take this PC's licence from Accounts"),
27221
+ cfx: share("cfx", "type the key in Accounts"),
27222
+ keystore: share("keystore", "import the upload.jks file in Accounts"),
27223
+ play: share("play", "import the service-account.json file in Accounts"),
27224
+ expo: share("expo", "type the token in Accounts"),
27225
+ appstore: share("appstore", "import the AuthKey.p8 file in Accounts"),
27226
+ perplexity: share("perplexity", "type the API key in Accounts, or import it from a .env file"),
27227
+ comet: share("comet", "sign in to Comet once in a sandbox: it cannot be taken from this PC")
27228
+ }).describe("Service sign-ins for sandboxes (game stores, engines, app signing, Perplexity). Manage them in Accounts.");
27034
27229
 
27035
27230
  // src/core/schema/pc-installs.ts
27036
27231
  var pick2 = (item, what, example) => external_exports.union([external_exports.boolean(), external_exports.array(item)]).describe(
@@ -27094,7 +27289,9 @@ function reservedEnvName(name) {
27094
27289
  }
27095
27290
  var ConfigSchema = external_exports.strictObject({
27096
27291
  $schema: SchemaRefSchema.optional(),
27097
- defaultHarness: NameSchema.describe("Agent started by `sandbox launch` (sandbox claude always runs claude)."),
27292
+ defaultHarness: NameSchema.describe(
27293
+ "The agent that starts when you do not name one (starting claude by name always runs claude)."
27294
+ ),
27098
27295
  guestWorkspace: GuestWorkspaceSchema,
27099
27296
  readOnly: external_exports.boolean().describe("Map the workspace read-only."),
27100
27297
  workspaceFilter: WorkspaceFilterSchema,
@@ -27104,7 +27301,7 @@ var ConfigSchema = external_exports.strictObject({
27104
27301
  sharing: SharingSchema,
27105
27302
  storage: external_exports.strictObject({
27106
27303
  root: external_exports.string().min(1).describe(
27107
- "Where everything is kept on this PC (tools, databases, logins, launches). The default is a private folder for you under %ProgramData%\\AgentSandbox\\users, which works for installs for one user and for everyone. sandbox storage move <folder> moves it."
27304
+ "Where everything is kept on this PC (tools, databases, logins, launches). The default is a private folder for you under %ProgramData%\\AgentSandbox\\users, which works for installs for one user and for everyone. Maintenance > Storage moves it."
27108
27305
  ),
27109
27306
  persistAgentState: external_exports.boolean().describe("Keep agent logins and history between sandboxes."),
27110
27307
  dataName: NameSchema.describe("Name of the persistent data set (C:\\AgentData) shared by all workspaces."),
@@ -27112,11 +27309,11 @@ var ConfigSchema = external_exports.strictObject({
27112
27309
  `Programs and scripts (.exe, .ps1, .bat, .cmd, .msi, .lnk ...) that appear or change in your project while a sandbox runs get Windows' "downloaded from the internet" mark, so SmartScreen and PowerShell ask before they run on this PC.`
27113
27310
  ),
27114
27311
  contained: external_exports.enum(["off", "vhdx"]).describe(
27115
- '(beta) Keep the sandbox tools, state and logs inside one disk image file (vhdx) instead of loose folders, so scanning programs on this PC see one file. Not yet tried on a real PC. Turn it on with sandbox storage contained on (it moves your files and asks first); Windows asks for permission to mount the image when a sandbox starts. "off" = loose folders, as always. Yours only: a project file (.sandbox-config.json) cannot set it.'
27312
+ '(beta) Keep the sandbox tools, state and logs inside one disk image file (vhdx) instead of loose folders, so scanning programs on this PC see one file. Not yet tried on a real PC. Turn it on in Maintenance > Storage (it moves your files and asks first); Windows asks for permission to mount the image when a sandbox starts. "off" = loose folders, as always. Yours only: a project file (.sandbox-config.json) cannot set it.'
27116
27313
  ),
27117
27314
  containedMaxGb: external_exports.number().int().min(8).max(4096).describe("(beta) Largest size, in GB, the disk image of storage.contained may grow to."),
27118
27315
  warnDataGb: external_exports.number().min(0).describe(
27119
- "Say at launch when the persisted data (tools, databases, logins) is bigger than this many GB; 0 = never. sandbox data shows what takes the space."
27316
+ "Say at launch when the persisted data (tools, databases, logins) is bigger than this many GB; 0 = never. Maintenance > Data shows what takes the space."
27120
27317
  )
27121
27318
  }),
27122
27319
  network: NetworkSchema,
@@ -27223,6 +27420,10 @@ var BootProgressSchema = external_exports.strictObject({
27223
27420
  done: external_exports.number().int().min(0).max(1e3),
27224
27421
  total: external_exports.number().int().min(0).max(1e3)
27225
27422
  });
27423
+ var BackgroundWorkSchema = external_exports.strictObject({
27424
+ name: Text(64),
27425
+ state: external_exports.enum(["running", "done", "failed"])
27426
+ });
27226
27427
  var SandboxStatusSchema = external_exports.object({
27227
27428
  launchId: Text(64),
27228
27429
  phase: external_exports.enum(["booting", "provisioning", "ready", "failed"]),
@@ -27234,7 +27435,9 @@ var SandboxStatusSchema = external_exports.object({
27234
27435
  /** The sandbox's IPv4 addresses (for network.forwardPorts; the host only uses ones on its Hyper-V network). */
27235
27436
  addresses: external_exports.array(external_exports.string().max(45)).max(8).optional(),
27236
27437
  /** A malformed progress is dropped, never the status (the phase still counts). */
27237
- progress: BootProgressSchema.optional().catch(void 0)
27438
+ progress: BootProgressSchema.optional().catch(void 0),
27439
+ /** Installs that continue after the boot is ready; a malformed list is dropped, never the status. */
27440
+ background: external_exports.array(BackgroundWorkSchema).max(16).optional().catch(void 0)
27238
27441
  });
27239
27442
  var VersionSchema = external_exports.strictObject({ spec: Text(128), source: Text(256) });
27240
27443
  var DatabasePlanSchema = external_exports.strictObject({
@@ -27648,24 +27851,37 @@ function mkdirp(p) {
27648
27851
  // src/guest/runtime/log.ts
27649
27852
  import fs6 from "node:fs";
27650
27853
  import path7 from "node:path";
27854
+ import { AsyncLocalStorage } from "node:async_hooks";
27651
27855
  fs6.mkdirSync(logsDir, { recursive: true });
27652
27856
  var logFile = path7.join(
27653
27857
  logsDir,
27654
27858
  (process.env.AGENT_LOG_PREFIX ?? "guest") + "-" + (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-") + ".log"
27655
27859
  );
27860
+ var context = new AsyncLocalStorage();
27861
+ function fileLine(message, at = /* @__PURE__ */ new Date()) {
27862
+ return at.toISOString() + " " + message;
27863
+ }
27656
27864
  var append = (line) => {
27657
27865
  try {
27658
- fs6.appendFileSync(logFile, line + "\n");
27866
+ fs6.appendFileSync(logFile, fileLine(line) + "\n");
27659
27867
  } catch {
27660
27868
  }
27661
27869
  };
27870
+ var tagged = (message, ctx) => {
27871
+ const prefix = ctx?.prefix?.();
27872
+ return prefix ? prefix + " | " + message : message;
27873
+ };
27662
27874
  function log(message) {
27663
- console.log(message);
27664
- append(message);
27875
+ const ctx = context.getStore();
27876
+ const line = tagged(message, ctx);
27877
+ if (!ctx?.quiet) console.log(line);
27878
+ append(line);
27665
27879
  }
27666
27880
  function warn(message) {
27667
- console.warn("\x1B[33mWARNING: " + message + "\x1B[0m");
27668
- append("WARNING: " + message);
27881
+ const ctx = context.getStore();
27882
+ const line = tagged(message, ctx);
27883
+ if (!ctx?.quiet) console.warn("\x1B[33mWARNING: " + line + "\x1B[0m");
27884
+ append("WARNING: " + line);
27669
27885
  }
27670
27886
 
27671
27887
  // src/guest/toolchains/tool-env.ts
@@ -27675,7 +27891,7 @@ import path12 from "node:path";
27675
27891
  import fs10 from "node:fs";
27676
27892
  import os3 from "node:os";
27677
27893
  import path11 from "node:path";
27678
- import { spawnSync } from "node:child_process";
27894
+ import { spawn as spawn2, spawnSync } from "node:child_process";
27679
27895
 
27680
27896
  // src/shared/download/http.ts
27681
27897
  var USER_AGENT = "windows-development-sandbox";
@@ -27751,7 +27967,11 @@ function moveIntoPlace(work, destination) {
27751
27967
  fs8.mkdirSync(path9.dirname(destination), { recursive: true });
27752
27968
  fs8.renameSync(work, destination);
27753
27969
  }
27754
- async function extractArchive(archive, destination, members2 = []) {
27970
+ var extractLimit = null;
27971
+ function extractArchive(archive, destination, members2 = []) {
27972
+ return extractLimit ? extractLimit.run(() => extract(archive, destination, members2)) : extract(archive, destination, members2);
27973
+ }
27974
+ async function extract(archive, destination, members2) {
27755
27975
  fs8.mkdirSync(destination, { recursive: true });
27756
27976
  let status = await spawnAsync(SYSTEM.tar(), ["-xf", archive, "-C", destination, ...members2]);
27757
27977
  if (status !== 0 && /\.(zip|nupkg)$/i.test(archive)) {
@@ -27786,6 +28006,8 @@ import { pipeline } from "node:stream/promises";
27786
28006
  var Downloader = class {
27787
28007
  /** downloads.requireChecksum: refuse anything without an expected hash. The guest sets it from session.json. */
27788
28008
  requireChecksum = false;
28009
+ /** The guest's net pool: how many HTTP bodies stream at once. Host code leaves it null. */
28010
+ limit = null;
27789
28011
  watcher = null;
27790
28012
  /** Reports coarse progress of the downloads that start from now on to `watcher` (null: stop). */
27791
28013
  watch(watcher) {
@@ -27803,39 +28025,42 @@ var Downloader = class {
27803
28025
  "Refusing to download " + path10.basename(destination) + " (" + url2 + "): no checksum is published for it, and downloads.requireChecksum is on. Turn that setting off to allow downloads that cannot be verified."
27804
28026
  );
27805
28027
  }
27806
- const response = await fetchRetry(url2, {}, 3, 20 * 60 * 1e3);
27807
- if (!response.body) throw new Error("Empty response for " + url2);
27808
28028
  fs9.mkdirSync(path10.dirname(destination), { recursive: true });
27809
28029
  const checks = ["sha256", "sha512", "sha1"].flatMap((kind) => {
27810
28030
  const want = sums[kind]?.trim().toLowerCase();
27811
28031
  return want ? [{ want, hash: crypto2.createHash(kind) }] : [];
27812
28032
  });
27813
- const size = Number(response.headers.get("content-length")) || 0;
27814
- const report = size > 0 ? this.watcher?.() ?? null : null;
27815
- let received = 0;
27816
- let tenth = 0;
27817
- let reportedAt = Date.now();
27818
- const tap = new Transform({
27819
- transform(chunk, _encoding, done) {
27820
- for (const c of checks) c.hash.update(chunk);
27821
- if (report) {
27822
- received += chunk.length;
27823
- const now = Math.floor(received * 10 / size);
27824
- if (now !== tenth || Date.now() - reportedAt > 5e3) {
27825
- tenth = now;
27826
- reportedAt = Date.now();
27827
- try {
27828
- report(Math.min(1, received / size));
27829
- } catch {
28033
+ const partial2 = destination + ".part";
28034
+ const transfer = async () => {
28035
+ const response = await fetchRetry(url2, {}, 3, 20 * 60 * 1e3);
28036
+ if (!response.body) throw new Error("Empty response for " + url2);
28037
+ const size = Number(response.headers.get("content-length")) || 0;
28038
+ const report = size > 0 ? this.watcher?.() ?? null : null;
28039
+ let received = 0;
28040
+ let tenth = 0;
28041
+ let reportedAt = Date.now();
28042
+ const tap = new Transform({
28043
+ transform(chunk, _encoding, done) {
28044
+ for (const c of checks) c.hash.update(chunk);
28045
+ if (report) {
28046
+ received += chunk.length;
28047
+ const now = Math.floor(received * 10 / size);
28048
+ if (now !== tenth || Date.now() - reportedAt > 5e3) {
28049
+ tenth = now;
28050
+ reportedAt = Date.now();
28051
+ try {
28052
+ report(Math.min(1, received / size));
28053
+ } catch {
28054
+ }
27830
28055
  }
27831
28056
  }
28057
+ done(null, chunk);
27832
28058
  }
27833
- done(null, chunk);
27834
- }
27835
- });
27836
- const partial2 = destination + ".part";
27837
- try {
28059
+ });
27838
28060
  await pipeline(Readable.fromWeb(response.body), tap, fs9.createWriteStream(partial2));
28061
+ };
28062
+ try {
28063
+ await (this.limit ? this.limit.run(transfer) : transfer());
27839
28064
  if (checks.some((c) => c.hash.digest("hex") !== c.want)) throw new Error("Checksum mismatch for " + url2);
27840
28065
  if (sums.verify) await sums.verify(partial2);
27841
28066
  fs9.rmSync(destination, { force: true });
@@ -27852,12 +28077,17 @@ var Downloader = class {
27852
28077
  const work = stagingFolder(destination);
27853
28078
  try {
27854
28079
  const archive = path10.join(work, options.fileName ?? path10.basename(new URL(url2).pathname));
27855
- await this.file(url2, archive, {
27856
- sha256: options.sha256,
27857
- sha512: options.sha512,
27858
- sha1: options.sha1,
27859
- ...options.verify ? { verify: options.verify } : {}
27860
- });
28080
+ if (options.cached && fs9.existsSync(options.cached)) {
28081
+ fs9.mkdirSync(work, { recursive: true });
28082
+ fs9.copyFileSync(options.cached, archive);
28083
+ fs9.rmSync(options.cached, { force: true });
28084
+ } else
28085
+ await this.file(url2, archive, {
28086
+ sha256: options.sha256,
28087
+ sha512: options.sha512,
28088
+ sha1: options.sha1,
28089
+ ...options.verify ? { verify: options.verify } : {}
28090
+ });
27861
28091
  const extracted = path10.join(work, "x");
27862
28092
  await extractArchive(archive, extracted, options.members);
27863
28093
  let root = extracted;
@@ -28045,6 +28275,78 @@ async function setupUv(env) {
28045
28275
  env.prepend.push(mkdirp(tool("uv-bin")));
28046
28276
  }
28047
28277
 
28278
+ // src/guest/runtime/pools.ts
28279
+ import os4 from "node:os";
28280
+
28281
+ // src/shared/concurrency/limiter.ts
28282
+ import { AsyncLocalStorage as AsyncLocalStorage2 } from "node:async_hooks";
28283
+ var held = new AsyncLocalStorage2();
28284
+ var priorityOf = new AsyncLocalStorage2();
28285
+ var Limiter = class {
28286
+ constructor(size, name = "pool") {
28287
+ this.size = size;
28288
+ this.name = name;
28289
+ if (!Number.isInteger(size) || size < 1) throw new Error("A pool needs a size of at least 1");
28290
+ }
28291
+ size;
28292
+ name;
28293
+ active = 0;
28294
+ peakActive = 0;
28295
+ queues = { foreground: [], background: [] };
28296
+ /** The most slots that were ever busy at once (tests). */
28297
+ get peak() {
28298
+ return this.peakActive;
28299
+ }
28300
+ get running() {
28301
+ return this.active;
28302
+ }
28303
+ /** Runs `work` in a free slot (waiting its turn), and frees the slot afterwards. */
28304
+ async run(work, priority = priorityOf.getStore() ?? "foreground") {
28305
+ const holding = held.getStore();
28306
+ if (holding) throw new Error("nested pool: " + this.name + " requested while holding " + holding.name);
28307
+ await this.acquire(priority);
28308
+ try {
28309
+ return await held.run(this, async () => work());
28310
+ } finally {
28311
+ this.release();
28312
+ }
28313
+ }
28314
+ acquire(priority) {
28315
+ if (this.active < this.size) {
28316
+ this.take();
28317
+ return Promise.resolve();
28318
+ }
28319
+ return new Promise((resolve) => {
28320
+ this.queues[priority].push({
28321
+ start: () => {
28322
+ this.take();
28323
+ resolve();
28324
+ }
28325
+ });
28326
+ });
28327
+ }
28328
+ take() {
28329
+ this.active++;
28330
+ this.peakActive = Math.max(this.peakActive, this.active);
28331
+ }
28332
+ release() {
28333
+ this.active--;
28334
+ const next = this.queues.foreground.shift() ?? this.queues.background.shift();
28335
+ next?.start();
28336
+ }
28337
+ };
28338
+
28339
+ // src/shared/concurrency/pools.ts
28340
+ var net = new Limiter(4, "net");
28341
+ var heavy = new Limiter(2, "heavy");
28342
+ var installer = new Limiter(1, "installer");
28343
+
28344
+ // src/guest/runtime/pools.ts
28345
+ var BELOW_NORMAL = os4.constants.priority.PRIORITY_BELOW_NORMAL;
28346
+ function execHeavy(file2, args, options = {}) {
28347
+ return heavy.run(() => execAsync(file2, args, options));
28348
+ }
28349
+
28048
28350
  // src/guest/runtime/session.ts
28049
28351
  import fs11 from "node:fs";
28050
28352
  import path14 from "node:path";
@@ -28103,13 +28405,26 @@ function planPath(input2) {
28103
28405
  seen.add(key);
28104
28406
  result.push(entry);
28105
28407
  }
28106
- return result;
28408
+ return msvcBeforeGitUsr(result);
28107
28409
  }
28108
28410
  function isPinnedNodeDir(folder, nvmHome2) {
28109
28411
  const key = pathKey(folder);
28110
28412
  const home = pathKey(nvmHome2);
28111
28413
  return key.startsWith(home + "\\") && /^v\d/.test(path16.win32.basename(key));
28112
28414
  }
28415
+ function isMsvcToolsDir(folder) {
28416
+ return /\\vc\\tools\\msvc\\[^\\]+\\bin\\host[^\\]+\\[^\\]+$/.test(pathKey(folder));
28417
+ }
28418
+ function isGitUsrBin(folder) {
28419
+ const key = pathKey(folder);
28420
+ return key.endsWith("\\usr\\bin") && /\\git(\\|$)/.test(key);
28421
+ }
28422
+ function msvcBeforeGitUsr(folders) {
28423
+ const firstGit = folders.findIndex(isGitUsrBin);
28424
+ if (firstGit < 0 || !folders.slice(firstGit).some(isMsvcToolsDir)) return [...folders];
28425
+ const late = folders.slice(firstGit).filter(isMsvcToolsDir);
28426
+ return [...folders.slice(0, firstGit), ...late, ...folders.slice(firstGit).filter((f) => !isMsvcToolsDir(f))];
28427
+ }
28113
28428
 
28114
28429
  // src/guest/setup/environment.ts
28115
28430
  function addMachineEnvironment(vars, dirs, additive = false) {
@@ -28125,11 +28440,11 @@ var nvmHome = () => path17.join(toolsDir, "nvm");
28125
28440
 
28126
28441
  // src/guest/agents/profile-links.ts
28127
28442
  var profileRoot = () => process.env.USERPROFILE ?? "";
28443
+ var linkPairs = (agents2) => !isWin || dryRun || testMode || !profileRoot() ? [] : Object.entries(agents2).flatMap(
28444
+ ([agent, dirs]) => dirs?.length ? profileLinkPairs(agent, dirs, profileRoot(), stateDir) : []
28445
+ );
28128
28446
  function linkProfileDirs(agents2) {
28129
- if (!isWin || dryRun || testMode || !profileRoot()) return;
28130
- const pairs = Object.entries(agents2).flatMap(
28131
- ([agent, dirs]) => dirs?.length ? profileLinkPairs(agent, dirs, profileRoot(), stateDir) : []
28132
- );
28447
+ const pairs = linkPairs(agents2);
28133
28448
  if (!pairs.length) return;
28134
28449
  try {
28135
28450
  runScriptWithJson("link-profile-dirs.ps1", "PairsFile", pairs);
@@ -28155,7 +28470,7 @@ async function installViaNpm(name, harness, dir, env) {
28155
28470
  return;
28156
28471
  }
28157
28472
  if (!exists(npmCli)) throw new Error("npm not found at " + npmCli);
28158
- await execAsync(process.execPath, args, { env });
28473
+ await execHeavy(process.execPath, args, { env });
28159
28474
  }
28160
28475
  async function installViaUv(name, harness, dir, env) {
28161
28476
  const uv = path18.join(toolsDir, "uv", "uv.exe");
@@ -28168,7 +28483,7 @@ async function installViaUv(name, harness, dir, env) {
28168
28483
  log("Installing uv for " + name + " ...");
28169
28484
  await setupUv(emptyEnv());
28170
28485
  }
28171
- await execAsync(uv, ["tool", "install", "--force", "--python", "3.12", harness.uvPackage], {
28486
+ await execHeavy(uv, ["tool", "install", "--force", "--python", "3.12", harness.uvPackage], {
28172
28487
  env: { ...env, ...uvVars(), UV_TOOL_BIN_DIR: dir }
28173
28488
  });
28174
28489
  }