windows-development-sandbox 1.18.4 → 1.23.0

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 (438) hide show
  1. package/README.md +1 -1
  2. package/config.example.json +17 -1
  3. package/dist/app/features/access/access.def.js +5 -2
  4. package/dist/app/features/access/access.run.js +7 -3
  5. package/dist/app/features/accounts/accounts.def.d.ts +33 -1
  6. package/dist/app/features/accounts/accounts.def.js +10 -4
  7. package/dist/app/features/accounts/accounts.run.d.ts +2 -0
  8. package/dist/app/features/accounts/accounts.run.js +7 -2
  9. package/dist/app/features/accounts/services.def.d.ts +7 -1
  10. package/dist/app/features/accounts/services.def.js +19 -16
  11. package/dist/app/features/accounts/services.run.d.ts +2 -0
  12. package/dist/app/features/accounts/services.run.js +44 -16
  13. package/dist/app/features/agent-commands/agent-commands.def.d.ts +37 -0
  14. package/dist/app/features/agent-commands/agent-commands.def.js +91 -0
  15. package/dist/app/features/agent-commands/agent-commands.run.d.ts +28 -0
  16. package/dist/app/features/agent-commands/agent-commands.run.js +35 -0
  17. package/dist/app/features/agent-commands/index.d.ts +2 -0
  18. package/dist/app/features/agent-commands/index.js +3 -0
  19. package/dist/app/features/agents/agents.def.d.ts +14 -1
  20. package/dist/app/features/agents/agents.def.js +61 -6
  21. package/dist/app/features/agents/agents.run.d.ts +1 -0
  22. package/dist/app/features/agents/agents.run.js +8 -1
  23. package/dist/app/features/agents/claude-env.def.d.ts +36 -0
  24. package/dist/app/features/agents/claude-env.def.js +305 -0
  25. package/dist/app/features/agents/env.def.d.ts +163 -0
  26. package/dist/app/features/agents/env.def.js +184 -0
  27. package/dist/app/features/agents/env.run.d.ts +43 -0
  28. package/dist/app/features/agents/env.run.js +86 -0
  29. package/dist/app/features/agents/index.d.ts +2 -0
  30. package/dist/app/features/agents/index.js +2 -0
  31. package/dist/app/features/defs.d.ts +171 -3
  32. package/dist/app/features/defs.js +9 -0
  33. package/dist/app/features/engine/engine.run.js +1 -1
  34. package/dist/app/features/github/github.def.d.ts +44 -3
  35. package/dist/app/features/github/github.def.js +145 -63
  36. package/dist/app/features/github/github.run.d.ts +9 -2
  37. package/dist/app/features/github/github.run.js +43 -5
  38. package/dist/app/features/health/health.def.js +8 -2
  39. package/dist/app/features/logs/logs.def.js +0 -8
  40. package/dist/app/features/projects/projects.def.js +2 -2
  41. package/dist/app/features/projects/projects.run.js +5 -5
  42. package/dist/app/features/sandbox/sandbox.def.js +7 -3
  43. package/dist/app/features/sessions/sessions.def.d.ts +4 -4
  44. package/dist/app/features/sessions/sessions.def.js +0 -5
  45. package/dist/app/features/sessions/sessions.run.d.ts +1 -1
  46. package/dist/app/features/sessions/sessions.run.js +2 -2
  47. package/dist/app/features/settings/categories.def.js +7 -2
  48. package/dist/app/features/settings/settings-rows.js +6 -2
  49. package/dist/app/features/settings/settings.def.js +1 -1
  50. package/dist/app/features/settings/settings.run.d.ts +8 -0
  51. package/dist/app/features/settings/settings.run.js +12 -3
  52. package/dist/app/features/storage/storage.run.js +18 -9
  53. package/dist/app/features/updates/update-lines.js +2 -2
  54. package/dist/app/features/updates/updates.def.js +1 -1
  55. package/dist/app/features/updates/updates.run.js +13 -3
  56. package/dist/app/features/vpn/vpn.def.d.ts +33 -0
  57. package/dist/app/features/vpn/vpn.def.js +30 -6
  58. package/dist/app/features/vpn/vpn.run.d.ts +11 -0
  59. package/dist/app/features/vpn/vpn.run.js +4 -1
  60. package/dist/app/features/web/web.def.js +2 -2
  61. package/dist/app/features/web/web.run.js +12 -4
  62. package/dist/app/kernel/errors.d.ts +7 -0
  63. package/dist/app/kernel/errors.js +18 -3
  64. package/dist/app/kernel/rpc.d.ts +6 -1
  65. package/dist/app/kernel/view.d.ts +11 -1
  66. package/dist/app/registry.js +7 -1
  67. package/dist/bin/agent-sandbox.js +2 -2
  68. package/dist/bin/{chunk-N4GXYTLV.js → chunk-JETGP2C3.js} +239 -72
  69. package/dist/bin/{chunk-MY7NLQQY.js → chunk-XZKOPGNH.js} +1 -1
  70. package/dist/bin/{chunk-FRPLQLSY.js → chunk-ZTTOF5V3.js} +6566 -4964
  71. package/dist/bin/claude-host.js +2 -2
  72. package/dist/bin/claude-sbx.js +2 -2
  73. package/dist/bin/codex-sbx.js +2 -2
  74. package/dist/bin/gemini-sbx.js +2 -2
  75. package/dist/bin/sandbox.js +2 -2
  76. package/dist/bin/sbx-hide.js +2 -2
  77. package/dist/bin/sbx-show.js +2 -2
  78. package/dist/cli/commands/agent-commands.d.ts +0 -1
  79. package/dist/cli/commands/agent-commands.js +2 -32
  80. package/dist/cli/commands/index.d.ts +1 -1
  81. package/dist/cli/commands/index.js +1 -1
  82. package/dist/cli/commands/launch/launch.js +2 -2
  83. package/dist/cli/commands/registry.js +3 -2
  84. package/dist/cli/manifest.d.ts +3 -3
  85. package/dist/cli/manifest.js +3 -2
  86. package/dist/cli/menu/coverage-exempt.d.ts +17 -0
  87. package/dist/cli/menu/coverage-exempt.js +61 -0
  88. package/dist/cli/menu/io-menu.d.ts +2 -0
  89. package/dist/cli/menu/io-menu.js +50 -5
  90. package/dist/cli/menu/menu.d.ts +1 -1
  91. package/dist/cli/menu/menu.js +3 -3
  92. package/dist/cli/menu/pages/accounts-page.js +1 -1
  93. package/dist/cli/menu/pages/agents-page.d.ts +7 -2
  94. package/dist/cli/menu/pages/agents-page.js +75 -13
  95. package/dist/cli/menu/pages/maintenance-page.d.ts +6 -0
  96. package/dist/cli/menu/pages/maintenance-page.js +10 -4
  97. package/dist/cli/menu/pages/sessions-page.d.ts +2 -0
  98. package/dist/cli/menu/pages/sessions-page.js +12 -4
  99. package/dist/cli/menu/pages/settings-page.js +13 -1
  100. package/dist/cli/menu/remote-menu.js +1 -1
  101. package/dist/cli/menu/shell.d.ts +5 -0
  102. package/dist/cli/menu/shell.js +13 -0
  103. package/dist/cli/menu/views.js +2 -1
  104. package/dist/cli/report.js +2 -0
  105. package/dist/cli/services/agent-commands-service.d.ts +2 -0
  106. package/dist/cli/services/agent-commands-service.js +13 -7
  107. package/dist/cli/services/vpn-service.d.ts +5 -1
  108. package/dist/cli/services/vpn-service.js +6 -1
  109. package/dist/cli/tui/app.d.ts +5 -0
  110. package/dist/cli/tui/app.js +2 -0
  111. package/dist/cli/tui/dialogs/text-screen.js +2 -1
  112. package/dist/cli/tui/terminal.js +3 -1
  113. package/dist/core/config/defaults.js +12 -1
  114. package/dist/core/detect/toolchains.js +9 -0
  115. package/dist/core/disk.d.ts +1 -5
  116. package/dist/core/disk.js +1 -16
  117. package/dist/core/schema/accounts.d.ts +6 -0
  118. package/dist/core/schema/accounts.js +13 -11
  119. package/dist/core/schema/codex.d.ts +29 -0
  120. package/dist/core/schema/codex.js +24 -0
  121. package/dist/core/schema/config.d.ts +58 -14
  122. package/dist/core/schema/config.js +6 -4
  123. package/dist/core/schema/github.js +1 -1
  124. package/dist/core/schema/index.d.ts +1 -0
  125. package/dist/core/schema/index.js +1 -0
  126. package/dist/core/schema/profile.js +8 -4
  127. package/dist/core/schema/resume.js +1 -1
  128. package/dist/core/schema/sandbox.js +3 -3
  129. package/dist/core/schema/toolchains.d.ts +4 -0
  130. package/dist/core/schema/toolchains.js +3 -0
  131. package/dist/core/schema/vpn.js +1 -1
  132. package/dist/core/schema/web.js +3 -3
  133. package/dist/core/types.d.ts +8 -0
  134. package/dist/core/util/errors.d.ts +11 -1
  135. package/dist/core/util/errors.js +7 -1
  136. package/dist/core/util/index.d.ts +1 -1
  137. package/dist/core/util/index.js +1 -1
  138. package/dist/guest/accounts/adapter.d.ts +2 -0
  139. package/dist/guest/accounts/adapters.js +4 -0
  140. package/dist/guest/accounts/apply.d.ts +10 -6
  141. package/dist/guest/accounts/kinds/cfx.d.ts +7 -0
  142. package/dist/guest/accounts/kinds/cfx.js +33 -3
  143. package/dist/guest/accounts/kinds/comet.d.ts +7 -0
  144. package/dist/guest/accounts/kinds/comet.js +50 -0
  145. package/dist/guest/accounts/kinds/perplexity.d.ts +2 -0
  146. package/dist/guest/accounts/kinds/perplexity.js +12 -0
  147. package/dist/guest/accounts/watch.d.ts +2 -0
  148. package/dist/guest/accounts/watch.js +12 -2
  149. package/dist/guest/agents/agent-files.d.ts +26 -6
  150. package/dist/guest/agents/agent-files.js +84 -14
  151. package/dist/guest/agents/agent-installer.js +1 -1
  152. package/dist/guest/agents/local-state.d.ts +5 -2
  153. package/dist/guest/agents/local-state.js +24 -10
  154. package/dist/guest/agents/profile-links.d.ts +2 -0
  155. package/dist/guest/agents/profile-links.js +18 -4
  156. package/dist/guest/apps/after-install.js +19 -0
  157. package/dist/guest/apps/app-installer.d.ts +11 -0
  158. package/dist/guest/apps/app-installer.js +69 -6
  159. package/dist/guest/apps/comet-unpack.d.ts +20 -0
  160. package/dist/guest/apps/comet-unpack.js +127 -0
  161. package/dist/guest/apps/index.d.ts +1 -1
  162. package/dist/guest/apps/index.js +1 -1
  163. package/dist/guest/apps/resolvers-agents-web.d.ts +2 -0
  164. package/dist/guest/apps/resolvers-agents-web.js +7 -0
  165. package/dist/guest/apps/resolvers.js +2 -0
  166. package/dist/guest/apps/shortcuts.d.ts +2 -0
  167. package/dist/guest/apps/shortcuts.js +1 -0
  168. package/dist/guest/apps/unpack.js +14 -4
  169. package/dist/guest/boot/boot.d.ts +45 -16
  170. package/dist/guest/boot/boot.js +325 -149
  171. package/dist/guest/boot/graph.d.ts +252 -0
  172. package/dist/guest/boot/graph.js +257 -0
  173. package/dist/guest/boot/guide-lines.d.ts +25 -0
  174. package/dist/guest/boot/guide-lines.js +41 -0
  175. package/dist/guest/boot/guide.d.ts +1 -4
  176. package/dist/guest/boot/guide.js +6 -8
  177. package/dist/guest/boot/runner.d.ts +77 -0
  178. package/dist/guest/boot/runner.js +215 -0
  179. package/dist/guest/browser/cdp.d.ts +71 -0
  180. package/dist/guest/browser/cdp.js +306 -0
  181. package/dist/guest/browser/comet.d.ts +28 -0
  182. package/dist/guest/browser/comet.js +155 -0
  183. package/dist/guest/daemon/project-provisioner.js +6 -1
  184. package/dist/guest/daemon/sessions.js +2 -1
  185. package/dist/guest/devtools/fivem.d.ts +1 -1
  186. package/dist/guest/devtools/fivem.js +243 -3
  187. package/dist/guest/entries/daemon.js +2 -0
  188. package/dist/guest/runtime/log.d.ts +12 -0
  189. package/dist/guest/runtime/log.js +29 -5
  190. package/dist/guest/runtime/pools.d.ts +24 -0
  191. package/dist/guest/runtime/pools.js +60 -0
  192. package/dist/guest/runtime/process.d.ts +4 -0
  193. package/dist/guest/runtime/process.js +38 -1
  194. package/dist/guest/runtime/status.d.ts +5 -1
  195. package/dist/guest/runtime/status.js +19 -0
  196. package/dist/guest/setup/addon-mcp.d.ts +1 -1
  197. package/dist/guest/setup/addon-mcp.js +52 -12
  198. package/dist/guest/setup/agent-addons.d.ts +3 -2
  199. package/dist/guest/setup/agent-addons.js +12 -3
  200. package/dist/guest/setup/environment.d.ts +1 -1
  201. package/dist/guest/setup/environment.js +25 -12
  202. package/dist/guest/setup/headroom.d.ts +8 -3
  203. package/dist/guest/setup/headroom.js +44 -15
  204. package/dist/guest/setup/path-plan.d.ts +28 -0
  205. package/dist/guest/setup/path-plan.js +69 -2
  206. package/dist/guest/setup/shell-path.d.ts +1 -1
  207. package/dist/guest/setup/shell-path.js +3 -3
  208. package/dist/guest/toolchains/fivem/artifacts.d.ts +48 -1
  209. package/dist/guest/toolchains/fivem/artifacts.js +97 -4
  210. package/dist/guest/toolchains/fivem/fivem.d.ts +32 -1
  211. package/dist/guest/toolchains/fivem/fivem.js +168 -3
  212. package/dist/guest/toolchains/fivem/scaffold.d.ts +35 -0
  213. package/dist/guest/toolchains/fivem/scaffold.js +105 -0
  214. package/dist/guest/toolchains/fivem/serve-plan.d.ts +34 -0
  215. package/dist/guest/toolchains/fivem/serve-plan.js +61 -0
  216. package/dist/guest/toolchains/installers.d.ts +6 -10
  217. package/dist/guest/toolchains/installers.js +4 -12
  218. package/dist/guest/toolchains/languages/go.js +1 -1
  219. package/dist/guest/toolchains/languages/node.js +2 -1
  220. package/dist/guest/toolchains/languages/php.d.ts +2 -0
  221. package/dist/guest/toolchains/languages/php.js +13 -1
  222. package/dist/guest/toolchains/languages/python-tools.js +1 -1
  223. package/dist/guest/toolchains/languages/ruby.js +1 -1
  224. package/dist/guest/toolchains/native/autosdk.d.ts +3 -0
  225. package/dist/guest/toolchains/native/autosdk.js +50 -0
  226. package/dist/guest/toolchains/native/binstall.js +1 -1
  227. package/dist/guest/toolchains/native/msvc/packages.js +10 -4
  228. package/dist/guest/toolchains/native/rust.d.ts +2 -0
  229. package/dist/guest/toolchains/native/rust.js +11 -4
  230. package/dist/guest/toolchains/native/unreal.d.ts +2 -0
  231. package/dist/guest/toolchains/native/unreal.js +19 -6
  232. package/dist/guest/toolchains/native/vcruntime.d.ts +2 -3
  233. package/dist/guest/toolchains/native/vcruntime.js +12 -7
  234. package/dist/guest/toolchains/native/visual-studio.d.ts +5 -2
  235. package/dist/guest/toolchains/native/visual-studio.js +127 -25
  236. package/dist/guest/toolchains/native/vs-request.d.ts +23 -0
  237. package/dist/guest/toolchains/native/vs-request.js +62 -1
  238. package/dist/guest/toolchains/not-yet.d.ts +1 -1
  239. package/dist/guest/toolchains/not-yet.js +3 -3
  240. package/dist/guest/toolchains/persisted.js +2 -7
  241. package/dist/guest/toolchains/plan.js +27 -11
  242. package/dist/guest/toolchains/scheduler.d.ts +2 -21
  243. package/dist/guest/toolchains/scheduler.js +7 -121
  244. package/dist/guest/toolchains/setup.d.ts +15 -2
  245. package/dist/guest/toolchains/setup.js +39 -20
  246. package/dist/guest/toolchains/signature.d.ts +5 -0
  247. package/dist/guest/toolchains/signature.js +22 -0
  248. package/dist/guest/toolchains/split.d.ts +28 -0
  249. package/dist/guest/toolchains/split.js +60 -0
  250. package/dist/guest/toolchains/steam/client.js +2 -1
  251. package/dist/guest/toolchains/step-scheduler.d.ts +51 -0
  252. package/dist/guest/toolchains/step-scheduler.js +147 -0
  253. package/dist/guest/toolchains/step.d.ts +13 -0
  254. package/dist/guest/toolchains/tools/git.js +18 -0
  255. package/dist/guest/vpn/openvpn.js +3 -4
  256. package/dist/guest/vpn/tunnel.d.ts +3 -0
  257. package/dist/guest/vpn/tunnel.js +10 -12
  258. package/dist/guest/vpn/vpn.js +6 -1
  259. package/dist/guest/vpn/wireguard.js +11 -4
  260. package/dist/host/accounts/deliver.js +7 -0
  261. package/dist/host/accounts/handoff.js +2 -6
  262. package/dist/host/accounts/index.d.ts +1 -1
  263. package/dist/host/accounts/index.js +1 -1
  264. package/dist/host/accounts/kinds/cfx.d.ts +1 -1
  265. package/dist/host/accounts/kinds/cfx.js +47 -4
  266. package/dist/host/accounts/kinds/comet.d.ts +2 -0
  267. package/dist/host/accounts/kinds/comet.js +6 -0
  268. package/dist/host/accounts/kinds/perplexity.d.ts +2 -0
  269. package/dist/host/accounts/kinds/perplexity.js +30 -0
  270. package/dist/host/accounts/leases.d.ts +9 -3
  271. package/dist/host/accounts/leases.js +13 -2
  272. package/dist/host/accounts/source.d.ts +7 -1
  273. package/dist/host/accounts/source.js +28 -1
  274. package/dist/host/accounts/sources.js +4 -0
  275. package/dist/host/agent-commands/commands.js +1 -1
  276. package/dist/host/agent-commands/forwarders.d.ts +14 -2
  277. package/dist/host/agent-commands/forwarders.js +31 -13
  278. package/dist/host/agent-commands/reconcile.d.ts +2 -1
  279. package/dist/host/agent-commands/reconcile.js +7 -8
  280. package/dist/host/agent-commands/user-path.d.ts +5 -0
  281. package/dist/host/agent-commands/user-path.js +13 -0
  282. package/dist/host/github/deliver.d.ts +1 -1
  283. package/dist/host/github/deliver.js +20 -1
  284. package/dist/host/github/index.d.ts +2 -1
  285. package/dist/host/github/index.js +1 -0
  286. package/dist/host/github/token.d.ts +13 -1
  287. package/dist/host/github/token.js +19 -2
  288. package/dist/host/github/verify.d.ts +27 -0
  289. package/dist/host/github/verify.js +61 -0
  290. package/dist/host/launch/hints/fivem.d.ts +3 -1
  291. package/dist/host/launch/hints/fivem.js +68 -2
  292. package/dist/host/launch/session-file.js +5 -0
  293. package/dist/host/launch/toolchains.d.ts +2 -1
  294. package/dist/host/launch/toolchains.js +5 -3
  295. package/dist/host/profile/accounts.js +2 -4
  296. package/dist/host/profile/claude-login.d.ts +3 -2
  297. package/dist/host/profile/claude-login.js +3 -13
  298. package/dist/host/vpn/index.d.ts +2 -1
  299. package/dist/host/vpn/index.js +2 -1
  300. package/dist/host/vpn/last.d.ts +28 -0
  301. package/dist/host/vpn/last.js +43 -0
  302. package/dist/host/vpn/login.d.ts +3 -1
  303. package/dist/host/vpn/login.js +17 -3
  304. package/dist/host/vpn/nordvpn.d.ts +2 -4
  305. package/dist/host/vpn/nordvpn.js +2 -24
  306. package/dist/runtime/agent.js +433 -90
  307. package/dist/runtime/daemon.js +3378 -1546
  308. package/dist/runtime/db.js +363 -90
  309. package/dist/runtime/main.js +5134 -2096
  310. package/dist/runtime/netproxy.js +308 -69
  311. package/dist/runtime/tool.js +2867 -1765
  312. package/dist/runtime/view.js +308 -69
  313. package/dist/selftest/agent-commands.test.js +45 -7
  314. package/dist/selftest/agent-paths.test.js +40 -13
  315. package/dist/selftest/agent-settings.test.d.ts +2 -0
  316. package/dist/selftest/agent-settings.test.js +94 -0
  317. package/dist/selftest/agents-web.test.d.ts +2 -0
  318. package/dist/selftest/agents-web.test.js +647 -0
  319. package/dist/selftest/app.test.js +7 -3
  320. package/dist/selftest/boot-runner.test.d.ts +2 -0
  321. package/dist/selftest/boot-runner.test.js +456 -0
  322. package/dist/selftest/channel.test.js +15 -0
  323. package/dist/selftest/cli.test.js +4 -0
  324. package/dist/selftest/fivem.test.js +249 -3
  325. package/dist/selftest/github.test.js +94 -9
  326. package/dist/selftest/guest-boot.test.js +3 -0
  327. package/dist/selftest/health.test.js +1 -1
  328. package/dist/selftest/index.js +10 -0
  329. package/dist/selftest/layout.test.js +5 -0
  330. package/dist/selftest/menu-coverage.test.d.ts +2 -0
  331. package/dist/selftest/menu-coverage.test.js +46 -0
  332. package/dist/selftest/menu-screens.js +37 -1
  333. package/dist/selftest/menu.test.js +5 -3
  334. package/dist/selftest/pc-installs.test.js +5 -0
  335. package/dist/selftest/persisted-installs.test.js +72 -0
  336. package/dist/selftest/service-accounts.test.js +3 -2
  337. package/dist/selftest/support/engine-golden.js +28 -1
  338. package/dist/selftest/support/fixtures.d.ts +15 -0
  339. package/dist/selftest/support/web-preview.d.ts +34 -1
  340. package/dist/selftest/support/web-preview.js +21 -18
  341. package/dist/selftest/toolchains.test.js +23 -1
  342. package/dist/selftest/ui-text.test.d.ts +7 -0
  343. package/dist/selftest/ui-text.test.js +300 -0
  344. package/dist/selftest/vpn.test.js +51 -3
  345. package/dist/shared/accounts/anthropic.d.ts +5 -0
  346. package/dist/shared/accounts/anthropic.js +15 -0
  347. package/dist/shared/accounts/index.d.ts +3 -0
  348. package/dist/shared/accounts/index.js +3 -0
  349. package/dist/shared/accounts/kinds/comet.d.ts +12 -0
  350. package/dist/shared/accounts/kinds/comet.js +64 -0
  351. package/dist/shared/accounts/kinds/perplexity.d.ts +8 -0
  352. package/dist/shared/accounts/kinds/perplexity.js +37 -0
  353. package/dist/shared/accounts/kinds.d.ts +24 -5
  354. package/dist/shared/accounts/kinds.js +86 -4
  355. package/dist/shared/accounts/payloads.d.ts +81 -0
  356. package/dist/shared/accounts/payloads.js +39 -1
  357. package/dist/shared/apps/agent-addons.d.ts +33 -5
  358. package/dist/shared/apps/agent-addons.js +95 -3
  359. package/dist/shared/apps/catalogue-agents-web.d.ts +14 -0
  360. package/dist/shared/apps/catalogue-agents-web.js +112 -0
  361. package/dist/shared/apps/catalogue-modding.js +32 -1
  362. package/dist/shared/apps/catalogue.d.ts +27 -3
  363. package/dist/shared/apps/catalogue.js +2 -1
  364. package/dist/shared/apps/index.d.ts +3 -1
  365. package/dist/shared/apps/index.js +3 -1
  366. package/dist/shared/channel/schema.d.ts +40 -3
  367. package/dist/shared/channel/schema.js +9 -0
  368. package/dist/shared/channel/secrets.d.ts +19 -0
  369. package/dist/shared/concurrency/index.d.ts +3 -0
  370. package/dist/shared/concurrency/index.js +3 -0
  371. package/dist/shared/concurrency/installer-retry.d.ts +6 -0
  372. package/dist/shared/concurrency/installer-retry.js +10 -0
  373. package/dist/shared/concurrency/limiter.d.ts +19 -0
  374. package/dist/shared/concurrency/limiter.js +67 -0
  375. package/dist/shared/concurrency/pools.d.ts +7 -0
  376. package/dist/shared/concurrency/pools.js +9 -0
  377. package/dist/shared/download/archive.d.ts +2 -0
  378. package/dist/shared/download/archive.js +11 -1
  379. package/dist/shared/download/bounded-fetch.d.ts +13 -0
  380. package/dist/shared/download/bounded-fetch.js +40 -0
  381. package/dist/shared/download/downloader.d.ts +5 -0
  382. package/dist/shared/download/downloader.js +50 -38
  383. package/dist/shared/download/index.d.ts +2 -1
  384. package/dist/shared/download/index.js +2 -1
  385. package/dist/shared/io/disk.d.ts +9 -0
  386. package/dist/shared/io/disk.js +19 -0
  387. package/dist/shared/io/index.d.ts +1 -0
  388. package/dist/shared/io/index.js +1 -0
  389. package/dist/shared/readiness.d.ts +9 -0
  390. package/dist/shared/readiness.js +11 -0
  391. package/dist/shared/signer.d.ts +24 -0
  392. package/dist/shared/signer.js +15 -0
  393. package/dist/shared/vpn/failure.d.ts +10 -0
  394. package/dist/shared/vpn/failure.js +28 -0
  395. package/dist/sync/watcher.js +2 -0
  396. package/dist/web/index.html +1 -1
  397. package/dist/web/{main-GVZWWP4I.js → main-CCILLX2M.js} +75 -74
  398. package/native/csharp/HcsHost/AssemblyInfo.cs +3 -3
  399. package/native/csharp/HostTools/AssemblyInfo.cs +3 -3
  400. package/native/csharp/HostTools/Program.cs +14 -1
  401. package/native/csharp/HostTools/UserPath.cs +17 -0
  402. package/native/csharp/StorageHelper/AssemblyInfo.cs +3 -3
  403. package/native/scripts/edit-user-path.ps1 +6 -2
  404. package/package.json +1 -1
  405. package/sandbox/addons/browser-use-mcp/requirements.in +1 -0
  406. package/sandbox/addons/browser-use-mcp/requirements.txt +2350 -0
  407. package/sandbox/addons/chrome-devtools-mcp/package-lock.json +38 -0
  408. package/sandbox/addons/chrome-devtools-mcp/package.json +7 -0
  409. package/sandbox/addons/comet-mcp/package-lock.json +1277 -0
  410. package/sandbox/addons/comet-mcp/package.json +7 -0
  411. package/sandbox/addons/perplexity-mcp/package-lock.json +1655 -0
  412. package/sandbox/addons/perplexity-mcp/package.json +7 -0
  413. package/sandbox/scripts/add-firewall-port.ps1 +18 -4
  414. package/sandbox/scripts/get-signature.ps1 +13 -0
  415. package/sandbox/scripts/set-machine-environment.ps1 +30 -15
  416. package/sandbox/templates/fivem/README.txt +6 -2
  417. package/sandbox/templates/fivem/cs/Client/Client.csproj +15 -0
  418. package/sandbox/templates/fivem/cs/Client/ClientMain.cs +20 -0
  419. package/sandbox/templates/fivem/cs/Server/Server.csproj +14 -0
  420. package/sandbox/templates/fivem/cs/Server/ServerMain.cs +20 -0
  421. package/sandbox/templates/fivem/cs/fxmanifest.lua +11 -0
  422. package/sandbox/templates/fivem/js/client.js +12 -0
  423. package/sandbox/templates/fivem/js/fxmanifest.lua +9 -0
  424. package/sandbox/templates/fivem/js/server.js +6 -0
  425. package/sandbox/templates/fivem/lua/client.lua +8 -0
  426. package/sandbox/templates/fivem/lua/fxmanifest.lua +10 -0
  427. package/sandbox/templates/fivem/lua/server.lua +6 -0
  428. package/sandbox/templates/fivem/server.cfg +37 -0
  429. package/sandbox/templates/fivem/ts/build.js +17 -0
  430. package/sandbox/templates/fivem/ts/fxmanifest.lua +9 -0
  431. package/sandbox/templates/fivem/ts/package.json +16 -0
  432. package/sandbox/templates/fivem/ts/src/client/client.ts +12 -0
  433. package/sandbox/templates/fivem/ts/src/client/tsconfig.json +13 -0
  434. package/sandbox/templates/fivem/ts/src/server/server.ts +6 -0
  435. package/sandbox/templates/fivem/ts/src/server/tsconfig.json +13 -0
  436. package/schemas/config.schema.json +120 -27
  437. package/schemas/sandbox-config.schema.json +45 -14
  438. package/sandbox/scripts/get-signer.ps1 +0 -8
@@ -1,3 +1,8 @@
1
+ // Which Visual Studio this sandbox installs (a real installer: it runs every boot), from every toolchain that needs
2
+ // one: Unreal (Community with the C++ game workload), Flutter's Windows desktop builds and Unity's Windows IL2CPP
3
+ // builds (the Build Tools' C++ parts). Pure: no runtime, so the self-test loads it. Community holds everything the
4
+ // Build Tools would add, so one install serves all of them.
5
+ import path from 'node:path';
1
6
  /**
2
7
  * What Epic lists for Unreal Engine 5 with Visual Studio 2022: the game workload, MSVC v143, a Windows SDK of
3
8
  * 10.0.18362 or newer, the C++ profiling tools, the .NET Framework targeting packs some engine tools build against,
@@ -22,7 +27,8 @@ export const BUILD_TOOLS_COMPONENTS = [
22
27
  /** Whether a toolchain is on (the host resolved "auto"; a session file that still says "auto" counts as off). */
23
28
  const isOn = (setting) => setting === true;
24
29
  export function visualStudioWanted(t, on = isOn) {
25
- const unreal = on(t.unreal.enabled, 'unreal');
30
+ // Unreal with visualStudio "autosdk" needs no Visual Studio: it builds from the portable MSVC (autosdk.ts).
31
+ const unreal = on(t.unreal.enabled, 'unreal') && t.unreal.visualStudio === 'full';
26
32
  const flutter = on(t.flutter.enabled, 'flutter') && t.flutter.windowsDesktop;
27
33
  const unity = on(t.unity.enabled, 'unity') && t.unity.modules.includes('windows-il2cpp');
28
34
  const users = [...(unreal ? ['unreal'] : []), ...(flutter ? ['flutter'] : []), ...(unity ? ['unity'] : [])];
@@ -44,3 +50,58 @@ export function visualStudioWanted(t, on = isOn) {
44
50
  accepted: t.msvc.acceptLicense,
45
51
  };
46
52
  }
53
+ /** Whether Unreal is on and builds from the portable MSVC through AutoSDK instead of Visual Studio. */
54
+ export function unrealUsesAutosdk(t, on = isOn) {
55
+ return on(t.unreal.enabled, 'unreal') && t.unreal.visualStudio === 'autosdk';
56
+ }
57
+ /** The Visual Studio installer's exit code in plain words (it is a uint32: -1 and 4294967295 are the same). */
58
+ export function vsExitText(code) {
59
+ const c = code >>> 0;
60
+ switch (c) {
61
+ case 0:
62
+ return 'installed';
63
+ case 3010:
64
+ return 'done; a restart would finish it (not needed here)';
65
+ case 1602:
66
+ return 'cancelled';
67
+ case 5007:
68
+ return 'the installer refused to run (blocked by Windows, for example a restart waiting)';
69
+ case 8006:
70
+ return 'Visual Studio is running and must be closed first';
71
+ case 0xe0434352:
72
+ return '0xE0434352: the Visual Studio installer crashed';
73
+ default:
74
+ return 'the installer failed with exit ' + c + ' (0x' + c.toString(16).toUpperCase() + ')';
75
+ }
76
+ }
77
+ /** Room the staging copy of the layout needs on the sandbox's own disk, on top of the reserve. */
78
+ export const LAYOUT_STAGING_BYTES = 12 * 1024 ** 3;
79
+ /** Spare room on the sandbox's disk while the layout is built there (before Visual Studio is installed). */
80
+ export const STAGING_RESERVE_BYTES = 3 * 1024 ** 3;
81
+ /**
82
+ * What to do after the layout attempt in the data disk: 'done' when it worked, 'stage' (build it on the sandbox's
83
+ * own disk and copy it over) when it failed and that disk has room, 'skip' (download this boot) otherwise.
84
+ */
85
+ export function layoutNextStep(exit, localFreeBytes, reserveBytes) {
86
+ if (exit !== null && (exit === 0 || exit === 3010))
87
+ return 'done';
88
+ return localFreeBytes >= LAYOUT_STAGING_BYTES + reserveBytes ? 'stage' : 'skip';
89
+ }
90
+ /**
91
+ * The copies that make an Unreal AutoSDK tree from the portable MSVC (copies, not links: mapped folders refuse
92
+ * junctions): MSVC's tools into HostWin64\Win64\VS2022\<msvc> and the Windows SDK's Include, Lib and bin folders into
93
+ * HostWin64\Win64\Windows Kits\10. Pure.
94
+ */
95
+ export function autosdkLayout(msvcRoot, msvc, sdk, autosdkRoot) {
96
+ const win64 = path.win32.join(autosdkRoot, 'HostWin64', 'Win64');
97
+ return [
98
+ {
99
+ from: path.win32.join(msvcRoot, 'VC', 'Tools', 'MSVC', msvc),
100
+ to: path.win32.join(win64, 'VS2022', msvc),
101
+ },
102
+ ...['Include', 'Lib', 'bin'].map((part) => ({
103
+ from: path.win32.join(msvcRoot, 'Windows Kits', '10', part, sdk),
104
+ to: path.win32.join(win64, 'Windows Kits', '10', part, sdk),
105
+ })),
106
+ ];
107
+ }
@@ -1,2 +1,2 @@
1
1
  import type { ToolEnv } from './tool-env.js';
2
- export declare function notAvailableYet(env: ToolEnv, what: string): void;
2
+ export declare function notAvailableYet(_env: ToolEnv, what: string): void;
@@ -1,6 +1,6 @@
1
- // What a toolchain step whose module is not written yet does: says so in the log and the summary, installs nothing.
1
+ // What a toolchain step whose module is not written yet does: says so in the log, installs nothing and adds no
2
+ // summary line.
2
3
  import { log } from '../runtime/log.js';
3
- export function notAvailableYet(env, what) {
4
+ export function notAvailableYet(_env, what) {
4
5
  log(what + ': not available yet (nothing installed)');
5
- env.summary.push(what + ': not available yet');
6
6
  }
@@ -7,6 +7,7 @@
7
7
  import crypto from 'node:crypto';
8
8
  import fs from 'node:fs';
9
9
  import path from 'node:path';
10
+ import { freeBytesAt } from '../../shared/io/disk.js';
10
11
  import { readValid, writeJsonAtomic } from '../../shared/io/json.js';
11
12
  import { safeRemove } from '../../shared/io/safe-remove.js';
12
13
  import { dataDir } from '../runtime/paths.js';
@@ -27,13 +28,7 @@ function checkSpec(spec) {
27
28
  }
28
29
  /** Free bytes for this user on the disk holding `dir` (0 when it cannot be told). */
29
30
  export function freeBytes(dir, deps = {}) {
30
- try {
31
- const s = (deps.statfs ?? fs.statfsSync)(dir);
32
- return s.bavail * s.bsize;
33
- }
34
- catch {
35
- return 0;
36
- }
31
+ return freeBytesAt(dir, deps.statfs) ?? 0;
37
32
  }
38
33
  const gb = (bytes) => (bytes / GB).toFixed(1) + ' GB';
39
34
  /** Throws (with the fix) when the disk holding `dir` has less than `needBytes` free. */
@@ -1,4 +1,4 @@
1
- import { appsNeedMesa, appsNeedUv, setupApps } from '../apps/index.js';
1
+ import { appsNeedMesa, appsNeedUv, prefetchApps, setupApps } from '../apps/index.js';
2
2
  import { dryRun } from '../runtime/paths.js';
3
3
  import { wanted } from './detect.js';
4
4
  import { DATABASE_NAMES, setupDatabase } from '../databases/index.js';
@@ -11,17 +11,17 @@ import { setupCpp } from './native/cpp.js';
11
11
  import { setupDotnet } from './native/dotnet.js';
12
12
  import { setupMesa } from './native/mesa.js';
13
13
  import { setupMsvc } from './native/msvc/index.js';
14
- import { setupUnreal } from './native/unreal.js';
15
- import { setupRust } from './native/rust.js';
14
+ import { fetchDirectX, setupUnreal } from './native/unreal.js';
15
+ import { fetchRustupInit, setupRust } from './native/rust.js';
16
16
  import { setupNode } from './languages/node.js';
17
17
  import { setupPwsh } from './tools/pwsh.js';
18
18
  import { setupPython } from './languages/python.js';
19
19
  import { setupBun, setupDeno, setupUv } from './runtimes.js';
20
- import { setupPhp } from './languages/php.js';
20
+ import { fetchPhp, setupPhp } from './languages/php.js';
21
21
  import { setupRuby } from './languages/ruby.js';
22
- import { setupVcRuntime } from './native/vcruntime.js';
22
+ import { fetchVcRuntime, setupVcRuntime } from './native/vcruntime.js';
23
23
  import { setupVscode } from './tools/vscode.js';
24
- import { ensureVisualStudio, visualStudioWanted } from './native/visual-studio.js';
24
+ import { ensureVisualStudio, prefetchVisualStudio, unrealUsesAutosdk, visualStudioWanted, } from './native/visual-studio.js';
25
25
  import { duringSession } from '../runtime/project-context.js';
26
26
  import { setupSteam } from './steam/steam.js';
27
27
  import { setupGodot } from './engines/godot.js';
@@ -42,11 +42,16 @@ export function plan(config, versions, o) {
42
42
  const android = wanted(config.android.enabled, 'android');
43
43
  // One Visual Studio for every toolchain that needs the real one (Unreal, Flutter desktop, Unity IL2CPP).
44
44
  const vs = visualStudioWanted(config, (setting, name) => wanted(setting, name));
45
+ // Unreal on the portable MSVC (AutoSDK) needs that MSVC even when nothing else asked for it.
46
+ const autosdk = unrealUsesAutosdk(config, (setting, name) => wanted(setting, name));
45
47
  const ctx = {
46
48
  refresh: o.refresh,
47
49
  pcInstalls: o.pcInstalls ?? { items: [] },
48
50
  duringSession: duringSession(),
49
51
  };
52
+ // Downloads that run ahead of their steps (the scheduler starts them at once); a dry run downloads nothing.
53
+ const ahead = (work) => (dryRun ? {} : { fetch: work });
54
+ const deferred = o.deferHeavy === true && !dryRun;
50
55
  return [
51
56
  {
52
57
  name: 'Git',
@@ -69,27 +74,35 @@ export function plan(config, versions, o) {
69
74
  name: 'Visual Studio',
70
75
  enabled: vs !== null,
71
76
  shared: true,
77
+ background: deferred,
78
+ ...ahead(() => prefetchVisualStudio(vs)),
72
79
  install: async (env) => {
73
- await ensureVisualStudio(env, vs, { keepInstallFiles: config.unreal.keepInstallFiles });
80
+ await ensureVisualStudio(env, vs, { keepInstallFiles: config.unreal.keepInstallFiles, lowPriority: deferred });
74
81
  },
75
82
  },
76
83
  {
77
84
  name: 'Unreal',
78
85
  enabled: unreal,
79
86
  shared: true,
80
- after: ['Visual Studio'],
87
+ after: ['Visual Studio', 'MSVC'],
88
+ ...ahead(() => fetchDirectX(config.unreal)),
81
89
  install: (env) => setupUnreal(env, config.unreal, ctx),
82
90
  },
83
91
  {
84
92
  name: 'MSVC',
85
- enabled: wanted(config.msvc.enabled, 'msvc') && vs === null,
86
- install: (env) => setupMsvc(env, config.msvc),
93
+ enabled: (wanted(config.msvc.enabled, 'msvc') || (autosdk && config.msvc.enabled !== false)) && vs === null,
94
+ // The same Visual Studio licence terms, which Unreal's acceptLicense already names.
95
+ install: (env) => setupMsvc(env, autosdk
96
+ ? { ...config.msvc, acceptLicense: config.msvc.acceptLicense || config.unreal.acceptLicense }
97
+ : config.msvc),
87
98
  },
88
99
  // Rust links with MSVC (msvc host) or MinGW's gcc (GNU host): whichever it uses goes first.
89
100
  {
90
101
  name: 'Rust',
91
102
  enabled: wanted(config.rust.enabled, 'rust'),
92
- after: ['C/C++', 'MSVC', 'Visual Studio', 'Unreal'],
103
+ // Only the msvc host links with Visual Studio (and Unreal's tools): the GNU host does not wait for them.
104
+ after: rustHost(config).endsWith('-msvc') ? ['C/C++', 'MSVC', 'Visual Studio', 'Unreal'] : ['C/C++'],
105
+ ...ahead(fetchRustupInit),
93
106
  install: async (env) => {
94
107
  await setupRust(env, { ...config.rust, host: rustHost(config) }, o.refresh);
95
108
  const rust = resolveTargetDir(config.rust);
@@ -159,6 +172,7 @@ export function plan(config, versions, o) {
159
172
  name: 'Visual C++ runtime',
160
173
  enabled: config.vcRuntime.enabled || apps,
161
174
  shared: true,
175
+ ...ahead(fetchVcRuntime),
162
176
  install: async (env) => {
163
177
  await setupVcRuntime(env);
164
178
  },
@@ -167,6 +181,7 @@ export function plan(config, versions, o) {
167
181
  name: 'PHP',
168
182
  enabled: wanted(config.php.enabled, 'php'),
169
183
  after: ['Visual C++ runtime'],
184
+ ...ahead(() => fetchPhp(config.php)),
170
185
  install: (env) => setupPhp(env, config.php),
171
186
  },
172
187
  { name: 'Deno', enabled: wanted(config.deno.enabled, 'deno'), install: (env) => setupDeno(env) },
@@ -203,6 +218,7 @@ export function plan(config, versions, o) {
203
218
  enabled: apps,
204
219
  shared: true,
205
220
  after: ['Mesa 3D', 'Visual C++ runtime', 'uv'],
221
+ ...ahead(() => prefetchApps(o.apps, { gitAccess: o.gitAccess, refresh: o.refresh })),
206
222
  install: (env) => setupApps(env, o.apps, { gitAccess: o.gitAccess, refresh: o.refresh }),
207
223
  },
208
224
  {
@@ -1,22 +1,3 @@
1
- import { type ToolEnv } from './tool-env.js';
2
- import type { ToolchainStep } from './step.js';
3
- export interface RunOptions {
4
- /** Progress lines ("Installing Go, Rust (3 of 9 done)"); default: the sandbox's boot status. */
5
- report?: (message: string) => void;
6
- /** What machine-wide (shared) steps contributed at boot: reused instead of run again. */
7
- reuse?: Record<string, ToolEnv>;
8
- }
9
- export declare class StepScheduler {
10
- private readonly parallel;
11
- /** One lock per kind of step ("Node 20" and "Node 22" share nvm's folders): held while that step runs, in any run. */
12
- private readonly locks;
13
- /** The step a download belongs to (several run at once), for its progress. */
14
- private readonly currentStep;
15
- constructor(parallel?: number);
16
- /** Runs the steps (each with its own environment) and returns each step's environment, in plan order. */
17
- run(steps: readonly ToolchainStep[], o: RunOptions): Promise<Map<string, ToolEnv>>;
18
- /** Runs `work` once no other step of the same kind (first word of the name) is running. */
19
- private exclusive;
20
- }
21
- /** The one scheduler: its locks span the boot's run and every project's run. */
1
+ import { StepScheduler } from './step-scheduler.js';
2
+ export { StepScheduler, type RunOptions, type SchedulerSink } from './step-scheduler.js';
22
3
  export declare const scheduler: StepScheduler;
@@ -1,123 +1,9 @@
1
- // Runs the planned steps in parallel, a few at a time, after the steps they depend on. One lock per kind of step is
2
- // held across runs: the boot and projects that join later never install two Nodes (or two Gos) at once.
3
- import { AsyncLocalStorage } from 'node:async_hooks';
4
- import { downloader } from '../../shared/download/index.js';
1
+ // The one scheduler: its locks span the boot's run and every project's run.
5
2
  import { warn } from '../runtime/log.js';
6
3
  import { setSandboxStatus } from '../runtime/status.js';
7
- import { errMsg } from '../../core/util/errors.js';
8
- import { emptyEnv } from './tool-env.js';
9
- /** How many installers run at once: enough to overlap downloads with installs, few enough not to thrash the disk. */
10
- const PARALLEL = 4;
11
- /** Runs one installer; a failure is reported and skipped so it never blocks the other toolchains. */
12
- async function runReported(name, env, work) {
13
- try {
14
- await work();
15
- }
16
- catch (e) {
17
- warn(name +
18
- ' could not be set up and is skipped; everything else still works, and the next start tries again. Reason: ' +
19
- errMsg(e));
20
- env.summary.push(name + ': FAILED');
21
- }
22
- }
23
- export class StepScheduler {
24
- parallel;
25
- /** One lock per kind of step ("Node 20" and "Node 22" share nvm's folders): held while that step runs, in any run. */
26
- locks = new Map();
27
- /** The step a download belongs to (several run at once), for its progress. */
28
- currentStep = new AsyncLocalStorage();
29
- constructor(parallel = PARALLEL) {
30
- this.parallel = parallel;
31
- }
32
- /** Runs the steps (each with its own environment) and returns each step's environment, in plan order. */
33
- async run(steps, o) {
34
- const envs = new Map(steps.map((s) => [s.name, emptyEnv()]));
35
- const finished = new Map();
36
- const running = new Set();
37
- const waiting = [];
38
- let done = 0;
39
- // The boot (no `report`) also publishes structured progress: what runs now, how far its download is, how many are
40
- // done.
41
- const percent = new Map();
42
- const active = () => [...running].map((name) => ({ name, ...(percent.has(name) ? { percent: percent.get(name) } : {}) }));
43
- const say = o.report ??
44
- ((message) => setSandboxStatus('provisioning', message, { active: active(), done, total: steps.length }));
45
- const report = () => {
46
- if (running.size)
47
- say('Installing ' + [...running].join(', ') + ' (' + done + ' of ' + steps.length + ' done)');
48
- };
49
- if (!o.report)
50
- downloader.watch(() => {
51
- const name = this.currentStep.getStore();
52
- return name
53
- ? (fraction) => {
54
- percent.set(name, Math.round(fraction * 100));
55
- report();
56
- }
57
- : null;
58
- });
59
- for (const s of steps) {
60
- // Dependencies first (they are earlier in the plan, so their promises exist), then a free slot.
61
- finished.set(s.name, (async () => {
62
- await Promise.all((s.after ?? []).map((name) => finished.get(name)));
63
- const env = envs.get(s.name);
64
- const reused = s.shared ? o.reuse?.[s.name] : undefined;
65
- if (reused) {
66
- envs.set(s.name, structuredClone(reused));
67
- done++;
68
- return;
69
- }
70
- while (running.size >= this.parallel)
71
- await new Promise((r) => waiting.push(r));
72
- running.add(s.name);
73
- report();
74
- try {
75
- await this.currentStep.run(s.name, () => this.exclusive(s.name, () => runReported(s.name, env, async () => s.install(env))));
76
- }
77
- finally {
78
- running.delete(s.name);
79
- percent.delete(s.name);
80
- done++;
81
- report();
82
- waiting.shift()?.();
83
- }
84
- })());
85
- }
86
- try {
87
- await Promise.all(finished.values());
88
- }
89
- finally {
90
- if (!o.report)
91
- downloader.watch(null);
92
- }
93
- if (!o.report)
94
- setSandboxStatus('provisioning', 'Set up ' + steps.length + ' toolchains and databases', {
95
- active: [],
96
- done,
97
- total: steps.length,
98
- });
99
- return envs;
100
- }
101
- /** Runs `work` once no other step of the same kind (first word of the name) is running. */
102
- async exclusive(name, work) {
103
- const key = name.split(' ')[0].toLowerCase();
104
- const previous = this.locks.get(key) ?? Promise.resolve();
105
- let release = () => undefined;
106
- const mine = new Promise((r) => {
107
- release = r;
108
- });
109
- const chained = previous.then(() => mine);
110
- this.locks.set(key, chained);
111
- await previous;
112
- try {
113
- return await work();
114
- }
115
- finally {
116
- release();
117
- if (this.locks.get(key) === chained)
118
- this.locks.delete(key);
119
- }
120
- }
121
- }
122
- /** The one scheduler: its locks span the boot's run and every project's run. */
123
- export const scheduler = new StepScheduler();
4
+ import { StepScheduler } from './step-scheduler.js';
5
+ export { StepScheduler } from './step-scheduler.js';
6
+ export const scheduler = new StepScheduler({
7
+ warn,
8
+ status: (message, progress) => setSandboxStatus('provisioning', message, progress),
9
+ });
@@ -5,6 +5,19 @@ import { type RunOptions } from './scheduler.js';
5
5
  /** The combined environment, plus what each step contributed (kept so later projects reuse the shared steps). */
6
6
  export interface ToolchainResult extends ToolEnv {
7
7
  steps: Record<string, ToolEnv>;
8
+ /** Every enabled step of the plan (foreground and background), in plan order: the order the parts are merged in. */
9
+ names: string[];
8
10
  }
9
- /** Provisions every enabled toolchain and database, and returns the combined environment for the agent. */
10
- export declare function setupToolchains(config: Toolchains, versions: ToolVersions, options: ToolchainOptions, run?: RunOptions): Promise<ToolchainResult>;
11
+ export interface SetupExtras {
12
+ /** The background steps start once this resolves (the boot: the agent's first session is running). */
13
+ gate?: Promise<void>;
14
+ }
15
+ /** The parts of these steps merged in the order of `names` (and the config's own variables on top). */
16
+ export declare function mergeToolchains(config: Toolchains, names: readonly string[], parts: ReadonlyMap<string, ToolEnv> | Readonly<Record<string, ToolEnv>>, planNames?: readonly string[]): ToolchainResult;
17
+ /**
18
+ * Provisions every enabled toolchain and database, and returns the combined environment for the agent. `later` is
19
+ * set when steps were left for the background: it resolves with the result of those steps alone.
20
+ */
21
+ export declare function setupToolchains(config: Toolchains, versions: ToolVersions, options: ToolchainOptions, run?: RunOptions, extras?: SetupExtras): Promise<ToolchainResult & {
22
+ later: Promise<ToolchainResult> | null;
23
+ }>;
@@ -1,25 +1,44 @@
1
- import { log } from '../runtime/log.js';
1
+ import fs from 'node:fs';
2
+ import { log, runQuiet } from '../runtime/log.js';
3
+ import { toolsDir } from '../runtime/paths.js';
4
+ import { installedToolPaths } from '../setup/path-plan.js';
2
5
  import { mkdirp } from '../runtime/fs.js';
3
- import { emptyEnv, tool } from './tool-env.js';
6
+ import { tool } from './tool-env.js';
4
7
  import { plan } from './plan.js';
5
8
  import { scheduler } from './scheduler.js';
6
- /** Provisions every enabled toolchain and database, and returns the combined environment for the agent. */
7
- export async function setupToolchains(config, versions, options, run = {}) {
9
+ import { mergeParts, runSplit } from './split.js';
10
+ /** The parts of these steps merged in the order of `names` (and the config's own variables on top). */
11
+ export function mergeToolchains(config, names, parts, planNames = names) {
12
+ const map = parts instanceof Map ? parts : new Map(Object.entries(parts));
13
+ return {
14
+ ...mergeParts(names, map, { environment: config.environment, bin: mkdirp(tool('bin')) }),
15
+ names: [...planNames],
16
+ };
17
+ }
18
+ /**
19
+ * Provisions every enabled toolchain and database, and returns the combined environment for the agent. `later` is
20
+ * set when steps were left for the background: it resolves with the result of those steps alone.
21
+ */
22
+ export async function setupToolchains(config, versions, options, run = {}, extras = {}) {
8
23
  const steps = plan(config, versions, options).filter((s) => s.enabled);
9
- const envs = await scheduler.run(steps, run);
10
- // Merged in plan order, so PATH order never depends on which download finished first.
11
- const env = { ...emptyEnv(), steps: Object.fromEntries(envs) };
12
- env.prepend.push(mkdirp(tool('bin')));
13
- for (const part of envs.values()) {
14
- Object.assign(env.vars, part.vars);
15
- env.prepend.push(...part.prepend);
16
- env.append.push(...part.append);
17
- env.summary.push(...part.summary);
18
- }
19
- Object.assign(env.vars, config.environment);
20
- // The git guard's variables (AGENT_GIT_ACCESS, GIT_DIR, GIT_CONFIG_*, BASH_ENV) always win over
21
- // toolchains.environment.
22
- Object.assign(env.vars, envs.get('Git')?.vars);
23
- log('Set up ' + steps.length + ' toolchains and databases.');
24
- return env;
24
+ const split = await runSplit(scheduler, steps, run, { ...extras, quiet: runQuiet });
25
+ const result = mergeToolchains(config, split.nowNames, split.now, steps.map((s) => s.name));
26
+ // Python and rust already installed in the persistent tools are on PATH for every project (at the end, nothing is
27
+ // installed): the project this session is for may not have asked for them, but its scripts and neighbours use them.
28
+ const have = new Set(steps.map((s) => s.name));
29
+ const installed = installedToolPaths(toolsDir, { exists: fs.existsSync, list: (dir) => (fs.existsSync(dir) ? fs.readdirSync(dir) : []) }, new Set([...(have.has('Python') ? ['python'] : []), ...(have.has('Rust') ? ['rust'] : [])]));
30
+ result.append.push(...installed.append);
31
+ result.summary.push(...installed.summary);
32
+ for (const [name, value] of Object.entries(installed.vars))
33
+ result.vars[name] ??= value;
34
+ log('Set up ' +
35
+ split.nowNames.length +
36
+ ' toolchains and databases' +
37
+ (split.laterNames.length ? ' (' + split.laterNames.length + ' more later)' : '') +
38
+ '.');
39
+ const later = split.later
40
+ ? split.later.then((parts) => mergeToolchains(config, split.laterNames, parts, steps.map((s) => s.name)))
41
+ : null;
42
+ later?.catch(() => undefined);
43
+ return Object.assign(result, { later });
25
44
  }
@@ -0,0 +1,5 @@
1
+ import { type AppSigner, type Signature } from '../../shared/signer.js';
2
+ /** The names on a file's valid signature, or null when it is unsigned, tampered with, or cannot be read. */
3
+ export declare function signatureOf(file: string): Signature | null;
4
+ /** Whether a file's valid signature is the expected signer's. */
5
+ export declare function signedBy(file: string, signer: AppSigner): boolean;
@@ -0,0 +1,22 @@
1
+ // A file's Authenticode signature (sandbox\scripts\get-signature.ps1) checked against the signer a download names.
2
+ import { z } from 'zod';
3
+ import { signerMatches } from '../../shared/signer.js';
4
+ import { scriptOutput } from '../runtime/process.js';
5
+ const SignatureSchema = z.object({ subject: z.string().max(4096), issuer: z.string().max(4096) });
6
+ /** The names on a file's valid signature, or null when it is unsigned, tampered with, or cannot be read. */
7
+ export function signatureOf(file) {
8
+ const text = scriptOutput('get-signature.ps1', ['-Path', file]).trim();
9
+ if (!text)
10
+ return null;
11
+ try {
12
+ const parsed = SignatureSchema.safeParse(JSON.parse(text));
13
+ return parsed.success ? parsed.data : null;
14
+ }
15
+ catch {
16
+ return null; // Not the script's JSON: treated as unsigned.
17
+ }
18
+ }
19
+ /** Whether a file's valid signature is the expected signer's. */
20
+ export function signedBy(file, signer) {
21
+ return signerMatches(signatureOf(file), signer);
22
+ }
@@ -0,0 +1,28 @@
1
+ import { type ToolEnv } from './tool-env.js';
2
+ import type { ToolchainStep } from './step.js';
3
+ import type { RunOptions, StepScheduler } from './step-scheduler.js';
4
+ /** The steps that wait for the gate: the ones marked `background`, and every step that comes after one. */
5
+ export declare function backgroundNames(steps: readonly ToolchainStep[]): Set<string>;
6
+ export interface SplitRun {
7
+ /** What the foreground steps contributed, in plan order. */
8
+ readonly now: Map<string, ToolEnv>;
9
+ readonly nowNames: readonly string[];
10
+ readonly laterNames: readonly string[];
11
+ /** The background steps' parts, once the gate opened and they ran; null when nothing was left for later. */
12
+ readonly later: Promise<Map<string, ToolEnv>> | null;
13
+ }
14
+ /**
15
+ * Runs the foreground steps and returns; the background steps (their downloads start now, behind the foreground ones)
16
+ * run after `gate`, inside `quiet` (file-only logging).
17
+ */
18
+ export declare function runSplit(scheduler: StepScheduler, steps: readonly ToolchainStep[], run: RunOptions, o?: {
19
+ gate?: Promise<void>;
20
+ quiet?: <T>(work: () => T) => T;
21
+ }): Promise<SplitRun>;
22
+ /** The parts of these steps merged in the order of `names`, so PATH order never depends on which finished first. */
23
+ export declare function mergeParts(names: readonly string[], parts: ReadonlyMap<string, ToolEnv>, o: {
24
+ environment: Readonly<Record<string, string>>;
25
+ bin: string;
26
+ }): ToolEnv & {
27
+ steps: Record<string, ToolEnv>;
28
+ };
@@ -0,0 +1,60 @@
1
+ // Splits a plan into the steps that run now and the ones that wait for a gate (the background: Visual Studio and what
2
+ // needs it), and merges the steps' parts in plan order. Pure apart from the scheduler it is given.
3
+ import { asBackground } from '../../shared/concurrency/index.js';
4
+ import { emptyEnv } from './tool-env.js';
5
+ /** The steps that wait for the gate: the ones marked `background`, and every step that comes after one. */
6
+ export function backgroundNames(steps) {
7
+ const later = new Set(steps.filter((s) => s.background).map((s) => s.name));
8
+ for (let grew = later.size > 0; grew;) {
9
+ grew = false;
10
+ for (const s of steps)
11
+ if (!later.has(s.name) && (s.after ?? []).some((n) => later.has(n))) {
12
+ later.add(s.name);
13
+ grew = true;
14
+ }
15
+ }
16
+ return later;
17
+ }
18
+ /**
19
+ * Runs the foreground steps and returns; the background steps (their downloads start now, behind the foreground ones)
20
+ * run after `gate`, inside `quiet` (file-only logging).
21
+ */
22
+ export async function runSplit(scheduler, steps, run, o = {}) {
23
+ const waiting = backgroundNames(steps);
24
+ const now = steps.filter((s) => !waiting.has(s.name));
25
+ const rest = steps.filter((s) => waiting.has(s.name));
26
+ asBackground(() => scheduler.startFetches(rest));
27
+ const parts = await scheduler.run(now, run);
28
+ const quiet = o.quiet ?? ((work) => work());
29
+ const later = rest.length
30
+ ? (async () => {
31
+ await o.gate;
32
+ // A progress callback that does nothing: the scheduler must not rewrite the boot's status as "ready".
33
+ return quiet(() => asBackground(() => scheduler.run(rest, { progress: () => undefined })));
34
+ })()
35
+ : null;
36
+ // Nobody may see a failed background run as an unhandled rejection before the boot awaits it.
37
+ later?.catch(() => undefined);
38
+ return { now: parts, nowNames: now.map((s) => s.name), laterNames: rest.map((s) => s.name), later };
39
+ }
40
+ /** The parts of these steps merged in the order of `names`, so PATH order never depends on which finished first. */
41
+ export function mergeParts(names, parts, o) {
42
+ const present = names.filter((n) => parts.has(n));
43
+ const env = {
44
+ ...emptyEnv(),
45
+ steps: Object.fromEntries(present.map((n) => [n, parts.get(n)])),
46
+ };
47
+ env.prepend.push(o.bin);
48
+ for (const name of present) {
49
+ const p = parts.get(name);
50
+ Object.assign(env.vars, p.vars);
51
+ env.prepend.push(...p.prepend);
52
+ env.append.push(...p.append);
53
+ env.summary.push(...p.summary);
54
+ }
55
+ Object.assign(env.vars, o.environment);
56
+ // The git guard's variables (AGENT_GIT_ACCESS, GIT_DIR, GIT_CONFIG_*, BASH_ENV) always win over
57
+ // toolchains.environment.
58
+ Object.assign(env.vars, parts.get('Git')?.vars);
59
+ return env;
60
+ }
@@ -4,6 +4,7 @@
4
4
  import fs from 'node:fs';
5
5
  import path from 'node:path';
6
6
  import { errMsg } from '../../../core/util/errors.js';
7
+ import { heavy } from '../../../shared/concurrency/index.js';
7
8
  import { moveIntoPlace, spawnAsync, stagingFolder } from '../../../shared/download/index.js';
8
9
  import { safeRemove } from '../../../shared/io/safe-remove.js';
9
10
  import { exists } from '../../runtime/fs.js';
@@ -38,7 +39,7 @@ async function installSteamClient() {
38
39
  try {
39
40
  log('Unpacking the Steam client into tools\\steam ...');
40
41
  // NSIS: /S silent, /D= the folder (last, unquoted: the staging path has no spaces).
41
- const code = await spawnAsync(setup, ['/S', '/D=' + work], { timeout: SETUP_TIMEOUT_MS });
42
+ const code = await heavy.run(() => spawnAsync(setup, ['/S', '/D=' + work], { timeout: SETUP_TIMEOUT_MS }));
42
43
  const unpacked = path.join(work, 'steam.exe');
43
44
  if (!exists(unpacked))
44
45
  throw new Error('SteamSetup.exe did not unpack steam.exe (exit code ' + code + ')');