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
@@ -69,6 +69,17 @@ const setupComposer = async (env, php) => {
69
69
  shim(env, 'composer', '"' + php + '" "' + phar + '"');
70
70
  env.summary.push('composer: ' + (/\d+\.\d+\.\d+/.exec(execOutput(php, [phar, '--version', '--no-ansi']))?.[0] ?? 'installed'));
71
71
  };
72
+ const PHP_RELEASES = 'https://windows.php.net/downloads/releases/';
73
+ const phpCache = (zip) => tool('downloads', 'php-' + path.basename(zip));
74
+ /** Downloads PHP's zip ahead of the install (which unpacks it); nothing when PHP is there already. */
75
+ export async function fetchPhp(config) {
76
+ const spec = versionFromFiles(['.php-version']) ?? { spec: config.version, source: 'config' };
77
+ const version = await resolveCached('php:' + spec.spec, async () => (await phpBuild(spec.spec)).version);
78
+ if (exists(path.join(tool('php', version), 'php.exe')))
79
+ return;
80
+ const build = await phpBuild(version);
81
+ await downloader.file(PHP_RELEASES + build.path, phpCache(build.path), build.sha256);
82
+ }
72
83
  export async function setupPhp(env, config) {
73
84
  const wantedSpec = versionFromFiles(['.php-version']) ?? { spec: config.version, source: 'config' };
74
85
  if (dryRun) {
@@ -82,10 +93,11 @@ export async function setupPhp(env, config) {
82
93
  if (!exists(path.join(home, 'php.exe'))) {
83
94
  const build = await phpBuild(version);
84
95
  log('Downloading PHP ' + version + ' (~30 MB once) ...');
85
- await downloader.archive('https://windows.php.net/downloads/releases/' + build.path, home, {
96
+ await downloader.archive(PHP_RELEASES + build.path, home, {
86
97
  sha256: build.sha256,
87
98
  locate: 'php.exe',
88
99
  fileName: build.path,
100
+ cached: phpCache(build.path),
89
101
  });
90
102
  }
91
103
  writePhpIni(home);
@@ -1,4 +1,4 @@
1
- import { execAsync } from '../../runtime/process.js';
1
+ import { execHeavy as execAsync } from '../../runtime/pools.js';
2
2
  import { exists } from '../../runtime/fs.js';
3
3
  import { tool } from '../tool-env.js';
4
4
  import { installOnce } from '../package-ledger.js';
@@ -3,7 +3,7 @@ import path from 'node:path';
3
3
  import { downloader, fetchJson } from '../../../shared/download/index.js';
4
4
  import { SYSTEM } from '../../../shared/system.js';
5
5
  import { dryRun } from '../../runtime/paths.js';
6
- import { execAsync } from '../../runtime/process.js';
6
+ import { execHeavy as execAsync } from '../../runtime/pools.js';
7
7
  import { exists } from '../../runtime/fs.js';
8
8
  import { log } from '../../runtime/log.js';
9
9
  import { installOnce } from '../package-ledger.js';
@@ -0,0 +1,3 @@
1
+ import { type ToolEnv } from '../tool-env.js';
2
+ /** Makes the AutoSDK tree from the portable MSVC if it is missing for this MSVC and SDK, and points Unreal at it. */
3
+ export declare function setupAutosdk(env: ToolEnv): Promise<void>;
@@ -0,0 +1,50 @@
1
+ // Unreal without Visual Studio (toolchains.unreal.visualStudio = "autosdk", experimental): an AutoSDK tree made from
2
+ // the portable MSVC (tools\msvc), at tools\unreal\autosdk, which UnrealBuildTool finds through UE_SDKS_ROOT. Made of
3
+ // copies (mapped folders refuse links), once; kept between sandboxes. The editor's Visual Studio integration is not
4
+ // available.
5
+ import fs from 'node:fs';
6
+ import path from 'node:path';
7
+ import { z } from 'zod';
8
+ import { writeJsonAtomic } from '../../../shared/io/json.js';
9
+ import { robocopyFailed } from '../../../shared/io/robocopy-result.js';
10
+ import { spawnAsync } from '../../../shared/download/index.js';
11
+ import { SYSTEM } from '../../../shared/system.js';
12
+ import { exists, mkdirp } from '../../runtime/fs.js';
13
+ import { log } from '../../runtime/log.js';
14
+ import { tool } from '../tool-env.js';
15
+ import { hasCompiler, readInstalled, ROOT as MSVC_ROOT } from './msvc/tree.js';
16
+ import { autosdkLayout } from './vs-request.js';
17
+ const AUTOSDK_DIR = tool('unreal', 'autosdk');
18
+ const MARKER = path.join(AUTOSDK_DIR, '.complete.json');
19
+ const MarkerSchema = z.object({ msvc: z.string(), sdk: z.string() });
20
+ function builtFor(msvc, sdk) {
21
+ try {
22
+ const done = MarkerSchema.parse(JSON.parse(fs.readFileSync(MARKER, 'utf8')));
23
+ return done.msvc === msvc && done.sdk === sdk;
24
+ }
25
+ catch {
26
+ return false; // No marker, or a half-written one: build again.
27
+ }
28
+ }
29
+ /** Makes the AutoSDK tree from the portable MSVC if it is missing for this MSVC and SDK, and points Unreal at it. */
30
+ export async function setupAutosdk(env) {
31
+ const msvc = readInstalled();
32
+ if (!msvc || !hasCompiler(msvc.msvc))
33
+ throw new Error('toolchains.unreal.visualStudio = "autosdk" builds from the portable MSVC, which is not installed ' +
34
+ '(is toolchains.msvc off?)');
35
+ if (!builtFor(msvc.msvc, msvc.sdk)) {
36
+ log('Making the Unreal AutoSDK from MSVC ' + msvc.msvc + ' (~2 GB, once) ...');
37
+ fs.rmSync(MARKER, { force: true });
38
+ for (const pair of autosdkLayout(MSVC_ROOT, msvc.msvc, msvc.sdk, AUTOSDK_DIR)) {
39
+ mkdirp(pair.to);
40
+ const code = await spawnAsync(SYSTEM.robocopy(), [pair.from, pair.to, '/E', '/COPY:DAT', '/R:1', '/W:1', '/NP']);
41
+ if (robocopyFailed(code))
42
+ throw new Error('could not copy ' + pair.from + ' into the AutoSDK (robocopy ' + code + ')');
43
+ }
44
+ writeJsonAtomic(MARKER, { msvc: msvc.msvc, sdk: msvc.sdk });
45
+ }
46
+ if (!exists(MARKER))
47
+ throw new Error('the Unreal AutoSDK was not completed');
48
+ env.vars['UE_SDKS_ROOT'] = AUTOSDK_DIR;
49
+ env.summary.push('unreal autosdk: MSVC ' + msvc.msvc + ', Windows SDK ' + msvc.sdk + ' (UE_SDKS_ROOT=' + AUTOSDK_DIR + ')');
50
+ }
@@ -2,7 +2,7 @@
2
2
  // published Windows build in seconds; only crates without one are compiled with `cargo install --locked`.
3
3
  import fs from 'node:fs';
4
4
  import path from 'node:path';
5
- import { execAsync } from '../../runtime/process.js';
5
+ import { execHeavy as execAsync } from '../../runtime/pools.js';
6
6
  import { exists } from '../../runtime/fs.js';
7
7
  import { log, warn } from '../../runtime/log.js';
8
8
  import { errMsg } from '../../../core/util/errors.js';
@@ -6,7 +6,7 @@ import path from 'node:path';
6
6
  import { downloader, extractArchive, fetchJson } from '../../../../shared/download/index.js';
7
7
  import { safeRemove } from '../../../../shared/io/safe-remove.js';
8
8
  import { system32 } from '../../../../shared/system.js';
9
- import { execAsync } from '../../../runtime/process.js';
9
+ import { runInstallerChecked } from '../../../runtime/pools.js';
10
10
  import { exists, mkdirp } from '../../../runtime/fs.js';
11
11
  import { log } from '../../../runtime/log.js';
12
12
  import { msiCabs, pickMsvcVersion, pickWindowsSdk } from '../../../../core/detect/versions.js';
@@ -93,9 +93,15 @@ const unpackVsix = async (vsix, work) => {
93
93
  const unpackMsi = async (msi) => {
94
94
  const logFile = msi + '.log';
95
95
  try {
96
- await execAsync(system32('msiexec.exe'), ['/a', msi, '/quiet', '/qn', 'TARGETDIR=' + ROOT, '/l*v', logFile], {
97
- stdio: 'ignore',
98
- });
96
+ await runInstallerChecked(system32('msiexec.exe'), [
97
+ '/a',
98
+ msi,
99
+ '/quiet',
100
+ '/qn',
101
+ 'TARGETDIR=' + ROOT,
102
+ '/l*v',
103
+ logFile,
104
+ ]);
99
105
  }
100
106
  catch (e) {
101
107
  const lines = exists(logFile)
@@ -1,3 +1,5 @@
1
1
  import type { Toolchains } from '../../../core/types.js';
2
2
  import { type ToolEnv } from '../tool-env.js';
3
+ /** rustup-init.exe (the small installer; the toolchain itself downloads when it runs), kept with Rust's tools. */
4
+ export declare function fetchRustupInit(): Promise<void>;
3
5
  export declare function setupRust(env: ToolEnv, config: Toolchains['rust'], refresh: boolean): Promise<void>;
@@ -1,7 +1,7 @@
1
1
  // Rust: rustup + cargo, with crates installed prebuilt where possible (binstall.ts).
2
2
  import path from 'node:path';
3
3
  import { dryRun } from '../../runtime/paths.js';
4
- import { execAsync } from '../../runtime/process.js';
4
+ import { execHeavy as execAsync } from '../../runtime/pools.js';
5
5
  import { exists } from '../../runtime/fs.js';
6
6
  import { log } from '../../runtime/log.js';
7
7
  import { arch, tool, versionOf } from '../tool-env.js';
@@ -9,6 +9,15 @@ import { downloadFile } from '../install.js';
9
9
  import { installOnce } from '../package-ledger.js';
10
10
  import { crateInstaller } from './binstall.js';
11
11
  import { installedMsvcEnv } from './msvc/index.js';
12
+ /** rustup-init.exe (the small installer; the toolchain itself downloads when it runs), kept with Rust's tools. */
13
+ export async function fetchRustupInit() {
14
+ const init = tool('rust', 'rustup-init.exe');
15
+ if (exists(init) || exists(path.join(tool('rust', 'cargo'), 'bin', 'rustup.exe')))
16
+ return;
17
+ await downloadFile('https://static.rust-lang.org/rustup/dist/' +
18
+ (arch === 'arm64' ? 'aarch64' : 'x86_64') +
19
+ '-pc-windows-msvc/rustup-init.exe', init);
20
+ }
12
21
  export async function setupRust(env, config, refresh) {
13
22
  const RUSTUP_HOME = tool('rust', 'rustup');
14
23
  const CARGO_HOME = tool('rust', 'cargo');
@@ -21,9 +30,7 @@ export async function setupRust(env, config, refresh) {
21
30
  if (!exists(rustup)) {
22
31
  const init = tool('rust', 'rustup-init.exe');
23
32
  log('Installing Rust with rustup (~300 MB once; the toolchain downloads after rustup itself) ...');
24
- await downloadFile('https://static.rust-lang.org/rustup/dist/' +
25
- (arch === 'arm64' ? 'aarch64' : 'x86_64') +
26
- '-pc-windows-msvc/rustup-init.exe', init);
33
+ await fetchRustupInit();
27
34
  await execAsync(init, [
28
35
  '-y',
29
36
  '--no-modify-path',
@@ -2,4 +2,6 @@ import type { Toolchains } from '../../../core/types.js';
2
2
  import type { ToolCtx } from '../step.js';
3
3
  import { type ToolEnv } from '../tool-env.js';
4
4
  export { UNREAL_COMPONENTS } from './vs-request.js';
5
+ /** Downloads the DirectX redistributable ahead of the install (only once the licence is accepted). */
6
+ export declare function fetchDirectX(config: Toolchains['unreal']): Promise<void>;
5
7
  export declare function setupUnreal(env: ToolEnv, config: Toolchains['unreal'], ctx: ToolCtx): Promise<void>;
@@ -4,7 +4,7 @@
4
4
  // (visual-studio.ts), which the plan runs first. The engine itself comes from the Epic Games Launcher or its source.
5
5
  import os from 'node:os';
6
6
  import path from 'node:path';
7
- import { spawnAsync } from '../../../shared/download/index.js';
7
+ import { runInstaller } from '../../runtime/pools.js';
8
8
  import { safeRemove } from '../../../shared/io/safe-remove.js';
9
9
  import { dryRun } from '../../runtime/paths.js';
10
10
  import { exists, mkdirp } from '../../runtime/fs.js';
@@ -12,21 +12,32 @@ import { log } from '../../runtime/log.js';
12
12
  import { setupUnrealEngines } from '../engines/unreal-engines.js';
13
13
  import { SIGNERS, signedInstaller } from '../installers.js';
14
14
  import { tool } from '../tool-env.js';
15
+ import { setupAutosdk } from './autosdk.js';
15
16
  import { installedVs } from './visual-studio.js';
16
17
  export { UNREAL_COMPONENTS } from './vs-request.js';
17
18
  const DIRECTX_URL = 'https://download.microsoft.com/download/8/4/A/84A35BF1-DAFE-4AE8-82AF-AD2AE20B6B14/directx_Jun2010_redist.exe';
18
19
  /** The June 2010 DirectX End-User Runtime (D3DX, XAudio 2.7, XInput 1.3), which Epic lists for the engine. */
19
- async function installDirectX() {
20
+ const directXInstalled = () => {
20
21
  const system32 = path.join(process.env.WINDIR ?? 'C:\\Windows', 'System32');
21
- if (exists(path.join(system32, 'd3dx9_43.dll')) && exists(path.join(system32, 'XAudio2_7.dll')))
22
+ return exists(path.join(system32, 'd3dx9_43.dll')) && exists(path.join(system32, 'XAudio2_7.dll'));
23
+ };
24
+ /** The redistributable (downloaded once, signature checked). */
25
+ const directXRedist = () => signedInstaller(DIRECTX_URL, path.join(tool('visualstudio'), 'directx_Jun2010_redist.exe'), 'the DirectX End-User Runtime (~95 MB once)', SIGNERS.microsoft);
26
+ /** Downloads the DirectX redistributable ahead of the install (only once the licence is accepted). */
27
+ export async function fetchDirectX(config) {
28
+ if (config.acceptLicense && !directXInstalled())
29
+ await directXRedist();
30
+ }
31
+ async function installDirectX() {
32
+ if (directXInstalled())
22
33
  return;
23
- const redist = await signedInstaller(DIRECTX_URL, path.join(tool('visualstudio'), 'directx_Jun2010_redist.exe'), 'the DirectX End-User Runtime (~95 MB once)', SIGNERS.microsoft);
34
+ const redist = await directXRedist();
24
35
  const unpacked = path.join(os.tmpdir(), 'directx-redist');
25
36
  safeRemove(unpacked, os.tmpdir());
26
37
  mkdirp(unpacked);
27
- if ((await spawnAsync(redist, ['/Q', '/T:' + unpacked])) !== 0 || !exists(path.join(unpacked, 'DXSETUP.exe')))
38
+ if ((await runInstaller(redist, ['/Q', '/T:' + unpacked])) !== 0 || !exists(path.join(unpacked, 'DXSETUP.exe')))
28
39
  throw new Error('could not unpack the DirectX End-User Runtime');
29
- const code = await spawnAsync(path.join(unpacked, 'DXSETUP.exe'), ['/silent']);
40
+ const code = await runInstaller(path.join(unpacked, 'DXSETUP.exe'), ['/silent']);
30
41
  safeRemove(unpacked, os.tmpdir());
31
42
  if (code !== 0)
32
43
  throw new Error('the DirectX End-User Runtime installer failed (exit ' + code + ')');
@@ -39,6 +50,8 @@ export async function setupUnreal(env, config, ctx) {
39
50
  return;
40
51
  }
41
52
  await installDirectX();
53
+ if (config.visualStudio === 'autosdk')
54
+ await setupAutosdk(env);
42
55
  await setupUnrealEngines(env, config, ctx);
43
56
  const vs = installedVs();
44
57
  env.summary.push('unreal: ' +
@@ -1,7 +1,6 @@
1
1
  import { type ToolEnv } from '../tool-env.js';
2
- export declare const MICROSOFT_SIGNER = "CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US";
3
- /** The subject of a valid Authenticode signature, or '' when the file is unsigned or tampered with. */
4
- export declare const signerOf: (file: string) => string;
2
+ /** Downloads the installer ahead of `setupVcRuntime` (nothing when the runtime or the installer is there). */
3
+ export declare function fetchVcRuntime(): Promise<void>;
5
4
  /**
6
5
  * A real installer (it writes to System32), so it runs on every boot; the installer itself is kept in persistent
7
6
  * storage and only run when Microsoft's signature on it checks out. Resolves true when this call ran the installer.
@@ -1,19 +1,24 @@
1
1
  // The Visual C++ runtime (vcruntime140.dll & co.) that PHP and other native tools need.
2
2
  import fs from 'node:fs';
3
3
  import path from 'node:path';
4
- import { spawnAsync } from '../../../shared/download/index.js';
4
+ import { runInstaller } from '../../runtime/pools.js';
5
5
  import { dryRun } from '../../runtime/paths.js';
6
- import { scriptOutput } from '../../runtime/process.js';
7
6
  import { exists } from '../../runtime/fs.js';
8
7
  import { log } from '../../runtime/log.js';
9
8
  import { downloadFile } from '../install.js';
9
+ import { SIGNERS, signedBy } from '../installers.js';
10
10
  import { tool } from '../tool-env.js';
11
11
  const VC_REDIST = 'https://aka.ms/vs/17/release/vc_redist.x64.exe';
12
- export const MICROSOFT_SIGNER = 'CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US';
13
12
  /** 1638: a newer version is already installed; 3010: installed, a restart would finish it (not needed for the DLLs). */
14
13
  const OK_EXIT_CODES = [0, 1638, 3010];
15
- /** The subject of a valid Authenticode signature, or '' when the file is unsigned or tampered with. */
16
- export const signerOf = (file) => scriptOutput('get-signer.ps1', ['-Path', file]).trim();
14
+ /** Downloads the installer ahead of `setupVcRuntime` (nothing when the runtime or the installer is there). */
15
+ export async function fetchVcRuntime() {
16
+ const system32 = path.join(process.env.WINDIR ?? 'C:\\Windows', 'System32');
17
+ const installer = tool('vcredist', 'vc_redist.x64.exe');
18
+ if (exists(installer) || exists(path.join(system32, 'vcruntime140.dll')))
19
+ return;
20
+ await downloadFile(VC_REDIST, installer);
21
+ }
17
22
  /**
18
23
  * A real installer (it writes to System32), so it runs on every boot; the installer itself is kept in persistent
19
24
  * storage and only run when Microsoft's signature on it checks out. Resolves true when this call ran the installer.
@@ -32,12 +37,12 @@ export async function setupVcRuntime(env, summary = true) {
32
37
  log('Downloading the Visual C++ runtime (~25 MB once) ...');
33
38
  await downloadFile(VC_REDIST, installer);
34
39
  }
35
- if (signerOf(installer) !== MICROSOFT_SIGNER) {
40
+ if (!signedBy(installer, SIGNERS.microsoft)) {
36
41
  fs.rmSync(installer, { force: true });
37
42
  throw new Error('vc_redist.x64.exe is not signed by Microsoft; deleted it (it is downloaded again next boot)');
38
43
  }
39
44
  log('Installing the Visual C++ runtime ...');
40
- const code = await spawnAsync(installer, ['/install', '/quiet', '/norestart']);
45
+ const code = await runInstaller(installer, ['/install', '/quiet', '/norestart']);
41
46
  if (!OK_EXIT_CODES.includes(code ?? -1) || !exists(path.join(system32, 'vcruntime140.dll')))
42
47
  throw new Error('the Visual C++ runtime installer failed (exit ' + code + ')');
43
48
  }
@@ -1,14 +1,17 @@
1
1
  import { type ToolEnv } from '../tool-env.js';
2
- import type { VsRequest } from './vs-request.js';
3
- export { BUILD_TOOLS_COMPONENTS, UNREAL_COMPONENTS, visualStudioWanted, type VsRequest } from './vs-request.js';
2
+ import { type VsRequest } from './vs-request.js';
3
+ export { BUILD_TOOLS_COMPONENTS, UNREAL_COMPONENTS, unrealUsesAutosdk, visualStudioWanted, type VsRequest, } from './vs-request.js';
4
4
  /** The newest Visual Studio (or Build Tools) with the C++ compiler: its folder and version, or null. */
5
5
  export declare function installedVs(): {
6
6
  path: string;
7
7
  version: string;
8
8
  } | null;
9
+ /** Downloads the bootstrapper now, so the install later starts without waiting for it. */
10
+ export declare function prefetchVisualStudio(req: VsRequest): Promise<void>;
9
11
  /** Visual Studio as asked for: installed at boot when it is not there yet; its folder and version. */
10
12
  export declare function ensureVisualStudio(env: ToolEnv, req: VsRequest, o: {
11
13
  keepInstallFiles: boolean;
14
+ lowPriority?: boolean;
12
15
  }): Promise<{
13
16
  path: string;
14
17
  version: string;
@@ -9,16 +9,23 @@ import os from 'node:os';
9
9
  import path from 'node:path';
10
10
  import { z } from 'zod';
11
11
  import { spawnAsync } from '../../../shared/download/index.js';
12
+ import { heavy, runInstaller } from '../../runtime/pools.js';
12
13
  import { writeJsonAtomic } from '../../../shared/io/json.js';
14
+ import { robocopyFailed } from '../../../shared/io/robocopy-result.js';
15
+ import { safeRemove } from '../../../shared/io/safe-remove.js';
16
+ import { SYSTEM } from '../../../shared/system.js';
13
17
  import { execOutput } from '../../runtime/process.js';
14
18
  import { exists, mkdirp } from '../../runtime/fs.js';
15
19
  import { log, warn } from '../../runtime/log.js';
20
+ import { logsDir } from '../../runtime/paths.js';
16
21
  import { duringSession } from '../../runtime/project-context.js';
22
+ import { backgroundRunning } from '../../runtime/status.js';
17
23
  import { errMsg } from '../../../core/util/errors.js';
18
24
  import { SIGNERS, signedInstaller } from '../installers.js';
19
25
  import { assertLocalRoom, freeBytes } from '../persisted.js';
20
26
  import { tool } from '../tool-env.js';
21
- export { BUILD_TOOLS_COMPONENTS, UNREAL_COMPONENTS, visualStudioWanted } from './vs-request.js';
27
+ import { LAYOUT_STAGING_BYTES, layoutNextStep, STAGING_RESERVE_BYTES, vsExitText, } from './vs-request.js';
28
+ export { BUILD_TOOLS_COMPONENTS, UNREAL_COMPONENTS, unrealUsesAutosdk, visualStudioWanted, } from './vs-request.js';
22
29
  const BOOTSTRAPPERS = {
23
30
  community: {
24
31
  url: 'https://aka.ms/vs/17/release/vs_community.exe',
@@ -63,8 +70,63 @@ export function installedVs() {
63
70
  function layoutDir(product) {
64
71
  return path.join(VS_DIR, product === 'community' ? 'layout' : 'layout-buildtools');
65
72
  }
73
+ /** The layout arguments of the bootstrapper (the same for the data disk and the staging folder). */
74
+ const layoutArgs = (req, folder) => [
75
+ '--layout',
76
+ folder,
77
+ '--lang',
78
+ 'en-US',
79
+ '--quiet',
80
+ '--wait',
81
+ ...req.components.flatMap((id) => ['--add', id]),
82
+ ];
83
+ /** The bootstrapper's newest log (dd_bootstrapper_*.log) in these folders, or null. */
84
+ function newestBootstrapperLog(folders) {
85
+ const logs = folders.flatMap((dir) => {
86
+ try {
87
+ return fs
88
+ .readdirSync(dir)
89
+ .filter((n) => /^dd_bootstrapper_.*\.log$/i.test(n))
90
+ .map((n) => path.join(dir, n));
91
+ }
92
+ catch {
93
+ return []; // The folder is not there: no log in it.
94
+ }
95
+ });
96
+ const stamp = (f) => {
97
+ try {
98
+ return fs.statSync(f).mtimeMs;
99
+ }
100
+ catch {
101
+ return 0; // Gone since the listing.
102
+ }
103
+ };
104
+ return logs.sort((x, y) => stamp(y) - stamp(x))[0] ?? null;
105
+ }
106
+ /** Says why the layout failed and keeps the installer's log where the sandbox's logs are. */
107
+ function reportLayoutFailure(code, temps) {
108
+ warn('Visual Studio: saving the install files failed (exit ' + code + '): ' + vsExitText(code));
109
+ const found = newestBootstrapperLog(temps);
110
+ if (!found)
111
+ return;
112
+ const kept = path.join(logsDir, 'vs-layout-' + new Date().toISOString().slice(0, 10) + '.log');
113
+ try {
114
+ fs.mkdirSync(logsDir, { recursive: true });
115
+ fs.copyFileSync(found, kept);
116
+ warn('Visual Studio: the installer log is ' + found + ' (a copy is in ' + kept + ')');
117
+ }
118
+ catch (e) {
119
+ warn('Visual Studio: the installer log is ' + found + ' (could not copy it: ' + errMsg(e) + ')');
120
+ }
121
+ }
122
+ /** Copies a finished layout onto the data disk (never /MOV: mapped folders refuse rename-over). */
123
+ async function copyLayout(from, to) {
124
+ mkdirp(to);
125
+ const code = await heavy.run(() => spawnAsync(SYSTEM.robocopy(), [from, to, '/E', '/COPY:DAT', '/R:1', '/W:1', '/MT:8', '/NP']));
126
+ return !robocopyFailed(code);
127
+ }
66
128
  /** The offline copy's installer when it holds every component; made or completed when there is room. */
67
- async function layoutInstaller(req, bootstrapper) {
129
+ async function layoutInstaller(req, bootstrapper, lowPriority) {
68
130
  const layout = layoutDir(req.product);
69
131
  const marker = path.join(layout, '.complete.json');
70
132
  const installer = path.join(layout, BOOTSTRAPPERS[req.product].file);
@@ -79,6 +141,10 @@ async function layoutInstaller(req, bootstrapper) {
79
141
  return false;
80
142
  }
81
143
  };
144
+ const finish = () => {
145
+ writeJsonAtomic(marker, { components: [...req.components] });
146
+ return installer;
147
+ };
82
148
  if (has())
83
149
  return installer;
84
150
  if (freeBytes(mkdirp(VS_DIR)) < LAYOUT_ROOM_BYTES) {
@@ -87,45 +153,79 @@ async function layoutInstaller(req, bootstrapper) {
87
153
  }
88
154
  log('Saving the Visual Studio install files for later boots (~10 GB, once) ...');
89
155
  fs.rmSync(marker, { force: true });
90
- const code = await spawnAsync(bootstrapper, [
91
- '--layout',
92
- layout,
93
- '--lang',
94
- 'en-US',
95
- '--quiet',
96
- '--wait',
97
- ...req.components.flatMap((id) => ['--add', id]),
98
- ]);
99
- if (!OK_EXIT_CODES.includes(code) || !exists(installer)) {
100
- warn('Visual Studio: saving the install files failed (exit ' + code + '); downloading this boot');
156
+ // The installer crashes (0xE0434352) when it builds the layout in a mapped folder, so it is built on the sandbox's
157
+ // own disk and copied over. That runs before Visual Studio is installed and the copy on C: is deleted first, so it
158
+ // needs room for the layout only (STAGING_RESERVE_BYTES spare), not for the layout and the install together.
159
+ const drive = (process.env.SystemDrive ?? 'C:') + '\\';
160
+ if (layoutNextStep(null, freeBytes(drive), STAGING_RESERVE_BYTES) !== 'stage') {
161
+ warn('Visual Studio: less than ' +
162
+ Math.round((LAYOUT_STAGING_BYTES + STAGING_RESERVE_BYTES) / 1024 ** 3) +
163
+ ' GB free on ' +
164
+ drive +
165
+ ' to build the install files; downloading this boot');
101
166
  return null;
102
167
  }
103
- writeJsonAtomic(marker, { components: [...req.components] });
104
- return installer;
168
+ const staging = path.join(drive, 'vs-layout-staging');
169
+ log('Building the install files on ' + drive + ' and copying them to ' + layout + ' ...');
170
+ const stagedCode = await runInstaller(bootstrapper, layoutArgs(req, staging), { lowPriority });
171
+ const staged = path.join(staging, BOOTSTRAPPERS[req.product].file);
172
+ let kept = false;
173
+ if (OK_EXIT_CODES.includes(stagedCode) && exists(staged)) {
174
+ kept = await copyLayout(staging, layout);
175
+ if (!kept)
176
+ warn('Visual Studio: copying the install files to ' + layout + ' failed');
177
+ }
178
+ else {
179
+ reportLayoutFailure(stagedCode, [os.tmpdir()]);
180
+ }
181
+ safeRemove(staging, drive);
182
+ return kept && exists(installer) ? finish() : null;
105
183
  }
106
- async function install(req, keepInstallFiles) {
184
+ /** The bootstrapper, downloaded (net pool) and checked; kept in tools\ for later boots. */
185
+ function bootstrapperFor(req) {
107
186
  const boot = BOOTSTRAPPERS[req.product];
108
- const bootstrapper = await signedInstaller(boot.url, path.join(VS_DIR, boot.file), 'the ' + boot.name + ' installer', SIGNERS.microsoft);
187
+ return signedInstaller(boot.url, path.join(VS_DIR, boot.file), 'the ' + boot.name + ' installer', SIGNERS.microsoft);
188
+ }
189
+ /** Downloads the bootstrapper now, so the install later starts without waiting for it. */
190
+ export async function prefetchVisualStudio(req) {
191
+ if (!req.accepted || installedVs())
192
+ return;
193
+ await bootstrapperFor(req);
194
+ }
195
+ async function install(req, keepInstallFiles, lowPriority) {
196
+ const boot = BOOTSTRAPPERS[req.product];
197
+ const bootstrapper = await bootstrapperFor(req);
109
198
  let installer = null;
110
199
  if (keepInstallFiles) {
111
200
  try {
112
- installer = await layoutInstaller(req, bootstrapper);
201
+ installer = await layoutInstaller(req, bootstrapper, lowPriority);
113
202
  }
114
203
  catch (e) {
115
204
  warn('Visual Studio: the offline copy failed (' + errMsg(e) + '); downloading this boot');
116
205
  }
117
206
  }
118
- log('Installing ' + boot.name + (installer ? ' from the saved install files' : ' (downloads ~5-8 GB)') + ' ...');
119
- const code = await spawnAsync(installer ?? bootstrapper, [
207
+ const run = (from, offline) => runInstaller(from, [
120
208
  '--quiet',
121
209
  '--wait',
122
210
  '--norestart',
123
211
  '--nocache',
124
- ...(installer ? ['--noWeb'] : []),
212
+ ...(offline ? ['--noWeb'] : []),
125
213
  ...req.components.flatMap((id) => ['--add', id]),
126
- ]);
214
+ ], { lowPriority });
215
+ log('Installing ' + boot.name + (installer ? ' from the saved install files' : ' (downloads ~5-8 GB)') + ' ...');
216
+ let code = await run(installer ?? bootstrapper, installer !== null);
217
+ if (installer && (!OK_EXIT_CODES.includes(code) || !installedVs())) {
218
+ // The saved copy is on the shared data disk: if installing from it fails, this boot downloads instead.
219
+ warn('Visual Studio: installing from the saved install files failed (' + vsExitText(code) + '); downloading');
220
+ code = await run(bootstrapper, false);
221
+ }
127
222
  if (!OK_EXIT_CODES.includes(code) || !installedVs())
128
- throw new Error('the Visual Studio installer failed (exit ' + code + '); its logs are the dd_*.log files in ' + os.tmpdir());
223
+ throw new Error('the Visual Studio installer failed (exit ' +
224
+ code +
225
+ ': ' +
226
+ vsExitText(code) +
227
+ '); its logs are the dd_*.log files in ' +
228
+ os.tmpdir());
129
229
  }
130
230
  /** Visual Studio as asked for: installed at boot when it is not there yet; its folder and version. */
131
231
  export async function ensureVisualStudio(env, req, o) {
@@ -142,9 +242,11 @@ export async function ensureVisualStudio(env, req, o) {
142
242
  if (have)
143
243
  return have;
144
244
  if (duringSession())
145
- throw new Error('Visual Studio is installed when the sandbox starts: restart it (sandbox restart) to get it');
245
+ throw new Error(backgroundRunning('Visual Studio')
246
+ ? 'Visual Studio is still installing in the background; it is ready in a few minutes'
247
+ : 'Visual Studio is installed when the sandbox starts: restart it (sandbox restart) to get it');
146
248
  assertLocalRoom(INSTALL_BYTES[req.product], BOOTSTRAPPERS[req.product].name);
147
- await install(req, o.keepInstallFiles);
249
+ await install(req, o.keepInstallFiles, o.lowPriority === true);
148
250
  const vs = installedVs();
149
251
  env.summary.push('visual studio: ' +
150
252
  BOOTSTRAPPERS[req.product].name +
@@ -17,3 +17,26 @@ export interface VsRequest {
17
17
  readonly accepted: boolean;
18
18
  }
19
19
  export declare function visualStudioWanted(t: Toolchains, on?: (setting: boolean | 'auto', name: string) => boolean): VsRequest | null;
20
+ /** Whether Unreal is on and builds from the portable MSVC through AutoSDK instead of Visual Studio. */
21
+ export declare function unrealUsesAutosdk(t: Toolchains, on?: (setting: boolean | 'auto', name: string) => boolean): boolean;
22
+ /** The Visual Studio installer's exit code in plain words (it is a uint32: -1 and 4294967295 are the same). */
23
+ export declare function vsExitText(code: number): string;
24
+ /** Room the staging copy of the layout needs on the sandbox's own disk, on top of the reserve. */
25
+ export declare const LAYOUT_STAGING_BYTES: number;
26
+ /** Spare room on the sandbox's disk while the layout is built there (before Visual Studio is installed). */
27
+ export declare const STAGING_RESERVE_BYTES: number;
28
+ /**
29
+ * What to do after the layout attempt in the data disk: 'done' when it worked, 'stage' (build it on the sandbox's
30
+ * own disk and copy it over) when it failed and that disk has room, 'skip' (download this boot) otherwise.
31
+ */
32
+ export declare function layoutNextStep(exit: number | null, localFreeBytes: number, reserveBytes: number): 'done' | 'stage' | 'skip';
33
+ export interface CopyPair {
34
+ readonly from: string;
35
+ readonly to: string;
36
+ }
37
+ /**
38
+ * The copies that make an Unreal AutoSDK tree from the portable MSVC (copies, not links: mapped folders refuse
39
+ * junctions): MSVC's tools into HostWin64\Win64\VS2022\<msvc> and the Windows SDK's Include, Lib and bin folders into
40
+ * HostWin64\Win64\Windows Kits\10. Pure.
41
+ */
42
+ export declare function autosdkLayout(msvcRoot: string, msvc: string, sdk: string, autosdkRoot: string): CopyPair[];