windows-development-sandbox 1.20.0 → 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 (331) hide show
  1. package/config.example.json +8 -1
  2. package/dist/app/features/access/access.def.js +5 -2
  3. package/dist/app/features/access/access.run.js +7 -3
  4. package/dist/app/features/accounts/accounts.def.d.ts +29 -1
  5. package/dist/app/features/accounts/accounts.def.js +10 -4
  6. package/dist/app/features/accounts/accounts.run.d.ts +1 -0
  7. package/dist/app/features/accounts/accounts.run.js +7 -2
  8. package/dist/app/features/accounts/services.def.d.ts +4 -1
  9. package/dist/app/features/accounts/services.def.js +15 -14
  10. package/dist/app/features/accounts/services.run.d.ts +1 -0
  11. package/dist/app/features/accounts/services.run.js +41 -15
  12. package/dist/app/features/defs.d.ts +39 -2
  13. package/dist/app/features/engine/engine.run.js +1 -1
  14. package/dist/app/features/github/github.def.d.ts +44 -3
  15. package/dist/app/features/github/github.def.js +145 -63
  16. package/dist/app/features/github/github.run.d.ts +9 -2
  17. package/dist/app/features/github/github.run.js +43 -5
  18. package/dist/app/features/health/health.def.js +8 -2
  19. package/dist/app/features/logs/logs.def.js +0 -8
  20. package/dist/app/features/projects/projects.def.js +2 -2
  21. package/dist/app/features/projects/projects.run.js +5 -5
  22. package/dist/app/features/sandbox/sandbox.def.js +7 -3
  23. package/dist/app/features/sessions/sessions.def.d.ts +4 -4
  24. package/dist/app/features/sessions/sessions.def.js +0 -5
  25. package/dist/app/features/sessions/sessions.run.d.ts +1 -1
  26. package/dist/app/features/sessions/sessions.run.js +2 -2
  27. package/dist/app/features/settings/categories.def.js +2 -0
  28. package/dist/app/features/settings/settings-rows.js +1 -1
  29. package/dist/app/features/settings/settings.def.js +1 -1
  30. package/dist/app/features/settings/settings.run.js +3 -3
  31. package/dist/app/features/storage/storage.run.js +18 -9
  32. package/dist/app/features/updates/update-lines.js +2 -2
  33. package/dist/app/features/updates/updates.def.js +1 -1
  34. package/dist/app/features/updates/updates.run.js +1 -1
  35. package/dist/app/features/web/web.def.js +2 -2
  36. package/dist/app/features/web/web.run.js +12 -4
  37. package/dist/app/kernel/errors.d.ts +7 -0
  38. package/dist/app/kernel/errors.js +18 -3
  39. package/dist/app/kernel/rpc.d.ts +5 -0
  40. package/dist/app/kernel/view.d.ts +11 -1
  41. package/dist/bin/agent-sandbox.js +2 -2
  42. package/dist/bin/{chunk-DK4NTBUF.js → chunk-JETGP2C3.js} +172 -48
  43. package/dist/bin/{chunk-2IMT7ZCT.js → chunk-XZKOPGNH.js} +1 -1
  44. package/dist/bin/{chunk-Z2P5OGKL.js → chunk-ZTTOF5V3.js} +2430 -1688
  45. package/dist/bin/claude-host.js +2 -2
  46. package/dist/bin/claude-sbx.js +2 -2
  47. package/dist/bin/codex-sbx.js +2 -2
  48. package/dist/bin/gemini-sbx.js +2 -2
  49. package/dist/bin/sandbox.js +2 -2
  50. package/dist/bin/sbx-hide.js +2 -2
  51. package/dist/bin/sbx-show.js +2 -2
  52. package/dist/cli/manifest.d.ts +2 -2
  53. package/dist/cli/manifest.js +2 -1
  54. package/dist/cli/menu/coverage-exempt.d.ts +17 -0
  55. package/dist/cli/menu/coverage-exempt.js +61 -0
  56. package/dist/cli/menu/io-menu.d.ts +2 -0
  57. package/dist/cli/menu/io-menu.js +50 -5
  58. package/dist/cli/menu/pages/accounts-page.js +1 -1
  59. package/dist/cli/menu/pages/agents-page.js +8 -2
  60. package/dist/cli/menu/pages/maintenance-page.d.ts +6 -0
  61. package/dist/cli/menu/pages/maintenance-page.js +9 -2
  62. package/dist/cli/menu/pages/sessions-page.d.ts +2 -0
  63. package/dist/cli/menu/pages/sessions-page.js +12 -4
  64. package/dist/cli/menu/pages/settings-page.js +12 -1
  65. package/dist/cli/menu/remote-menu.js +1 -1
  66. package/dist/cli/menu/shell.d.ts +5 -0
  67. package/dist/cli/menu/shell.js +13 -0
  68. package/dist/cli/report.js +2 -0
  69. package/dist/cli/tui/app.d.ts +5 -0
  70. package/dist/cli/tui/app.js +2 -0
  71. package/dist/core/config/defaults.js +3 -1
  72. package/dist/core/schema/accounts.d.ts +6 -0
  73. package/dist/core/schema/accounts.js +13 -11
  74. package/dist/core/schema/config.d.ts +20 -8
  75. package/dist/core/schema/config.js +4 -4
  76. package/dist/core/schema/github.js +1 -1
  77. package/dist/core/schema/profile.js +8 -4
  78. package/dist/core/schema/resume.js +1 -1
  79. package/dist/core/schema/sandbox.js +3 -3
  80. package/dist/core/schema/vpn.js +1 -1
  81. package/dist/core/schema/web.js +3 -3
  82. package/dist/core/types.d.ts +6 -0
  83. package/dist/core/util/errors.d.ts +11 -1
  84. package/dist/core/util/errors.js +7 -1
  85. package/dist/core/util/index.d.ts +1 -1
  86. package/dist/core/util/index.js +1 -1
  87. package/dist/guest/accounts/adapter.d.ts +2 -0
  88. package/dist/guest/accounts/adapters.js +4 -0
  89. package/dist/guest/accounts/apply.d.ts +6 -2
  90. package/dist/guest/accounts/kinds/cfx.d.ts +7 -0
  91. package/dist/guest/accounts/kinds/cfx.js +33 -3
  92. package/dist/guest/accounts/kinds/comet.d.ts +7 -0
  93. package/dist/guest/accounts/kinds/comet.js +50 -0
  94. package/dist/guest/accounts/kinds/perplexity.d.ts +2 -0
  95. package/dist/guest/accounts/kinds/perplexity.js +12 -0
  96. package/dist/guest/accounts/watch.d.ts +2 -0
  97. package/dist/guest/accounts/watch.js +12 -2
  98. package/dist/guest/agents/agent-installer.js +1 -1
  99. package/dist/guest/agents/profile-links.d.ts +2 -0
  100. package/dist/guest/agents/profile-links.js +18 -4
  101. package/dist/guest/apps/after-install.js +19 -0
  102. package/dist/guest/apps/app-installer.d.ts +11 -0
  103. package/dist/guest/apps/app-installer.js +69 -6
  104. package/dist/guest/apps/comet-unpack.d.ts +20 -0
  105. package/dist/guest/apps/comet-unpack.js +127 -0
  106. package/dist/guest/apps/index.d.ts +1 -1
  107. package/dist/guest/apps/index.js +1 -1
  108. package/dist/guest/apps/resolvers-agents-web.d.ts +2 -0
  109. package/dist/guest/apps/resolvers-agents-web.js +7 -0
  110. package/dist/guest/apps/resolvers.js +2 -0
  111. package/dist/guest/apps/shortcuts.d.ts +2 -0
  112. package/dist/guest/apps/shortcuts.js +1 -0
  113. package/dist/guest/apps/unpack.js +14 -4
  114. package/dist/guest/boot/boot.d.ts +45 -16
  115. package/dist/guest/boot/boot.js +316 -145
  116. package/dist/guest/boot/graph.d.ts +252 -0
  117. package/dist/guest/boot/graph.js +257 -0
  118. package/dist/guest/boot/guide-lines.d.ts +25 -0
  119. package/dist/guest/boot/guide-lines.js +41 -0
  120. package/dist/guest/boot/guide.d.ts +1 -4
  121. package/dist/guest/boot/guide.js +6 -8
  122. package/dist/guest/boot/runner.d.ts +77 -0
  123. package/dist/guest/boot/runner.js +215 -0
  124. package/dist/guest/browser/cdp.d.ts +71 -0
  125. package/dist/guest/browser/cdp.js +306 -0
  126. package/dist/guest/browser/comet.d.ts +28 -0
  127. package/dist/guest/browser/comet.js +155 -0
  128. package/dist/guest/daemon/project-provisioner.js +6 -1
  129. package/dist/guest/devtools/fivem.d.ts +1 -1
  130. package/dist/guest/devtools/fivem.js +243 -3
  131. package/dist/guest/entries/daemon.js +2 -0
  132. package/dist/guest/runtime/log.d.ts +12 -0
  133. package/dist/guest/runtime/log.js +29 -5
  134. package/dist/guest/runtime/pools.d.ts +24 -0
  135. package/dist/guest/runtime/pools.js +60 -0
  136. package/dist/guest/runtime/process.d.ts +4 -0
  137. package/dist/guest/runtime/process.js +38 -1
  138. package/dist/guest/runtime/status.d.ts +5 -1
  139. package/dist/guest/runtime/status.js +19 -0
  140. package/dist/guest/setup/addon-mcp.d.ts +1 -1
  141. package/dist/guest/setup/addon-mcp.js +52 -12
  142. package/dist/guest/setup/agent-addons.d.ts +3 -2
  143. package/dist/guest/setup/agent-addons.js +12 -3
  144. package/dist/guest/setup/environment.d.ts +1 -1
  145. package/dist/guest/setup/environment.js +25 -12
  146. package/dist/guest/setup/headroom.d.ts +8 -3
  147. package/dist/guest/setup/headroom.js +44 -15
  148. package/dist/guest/setup/path-plan.d.ts +28 -0
  149. package/dist/guest/setup/path-plan.js +69 -2
  150. package/dist/guest/setup/shell-path.d.ts +1 -1
  151. package/dist/guest/setup/shell-path.js +3 -3
  152. package/dist/guest/toolchains/fivem/artifacts.d.ts +48 -1
  153. package/dist/guest/toolchains/fivem/artifacts.js +97 -4
  154. package/dist/guest/toolchains/fivem/fivem.d.ts +32 -1
  155. package/dist/guest/toolchains/fivem/fivem.js +168 -3
  156. package/dist/guest/toolchains/fivem/scaffold.d.ts +35 -0
  157. package/dist/guest/toolchains/fivem/scaffold.js +105 -0
  158. package/dist/guest/toolchains/fivem/serve-plan.d.ts +34 -0
  159. package/dist/guest/toolchains/fivem/serve-plan.js +61 -0
  160. package/dist/guest/toolchains/languages/go.js +1 -1
  161. package/dist/guest/toolchains/languages/node.js +2 -1
  162. package/dist/guest/toolchains/languages/php.d.ts +2 -0
  163. package/dist/guest/toolchains/languages/php.js +13 -1
  164. package/dist/guest/toolchains/languages/python-tools.js +1 -1
  165. package/dist/guest/toolchains/languages/ruby.js +1 -1
  166. package/dist/guest/toolchains/native/binstall.js +1 -1
  167. package/dist/guest/toolchains/native/msvc/packages.js +10 -4
  168. package/dist/guest/toolchains/native/rust.d.ts +2 -0
  169. package/dist/guest/toolchains/native/rust.js +11 -4
  170. package/dist/guest/toolchains/native/unreal.d.ts +2 -0
  171. package/dist/guest/toolchains/native/unreal.js +16 -6
  172. package/dist/guest/toolchains/native/vcruntime.d.ts +2 -0
  173. package/dist/guest/toolchains/native/vcruntime.js +10 -2
  174. package/dist/guest/toolchains/native/visual-studio.d.ts +3 -0
  175. package/dist/guest/toolchains/native/visual-studio.js +44 -26
  176. package/dist/guest/toolchains/native/vs-request.d.ts +2 -0
  177. package/dist/guest/toolchains/native/vs-request.js +2 -0
  178. package/dist/guest/toolchains/plan.js +19 -8
  179. package/dist/guest/toolchains/scheduler.d.ts +2 -21
  180. package/dist/guest/toolchains/scheduler.js +7 -121
  181. package/dist/guest/toolchains/setup.d.ts +15 -2
  182. package/dist/guest/toolchains/setup.js +39 -20
  183. package/dist/guest/toolchains/split.d.ts +28 -0
  184. package/dist/guest/toolchains/split.js +60 -0
  185. package/dist/guest/toolchains/steam/client.js +2 -1
  186. package/dist/guest/toolchains/step-scheduler.d.ts +51 -0
  187. package/dist/guest/toolchains/step-scheduler.js +147 -0
  188. package/dist/guest/toolchains/step.d.ts +13 -0
  189. package/dist/guest/toolchains/tools/git.js +18 -0
  190. package/dist/guest/vpn/openvpn.js +3 -4
  191. package/dist/guest/vpn/wireguard.js +11 -4
  192. package/dist/host/accounts/deliver.js +7 -0
  193. package/dist/host/accounts/handoff.js +2 -6
  194. package/dist/host/accounts/index.d.ts +1 -1
  195. package/dist/host/accounts/index.js +1 -1
  196. package/dist/host/accounts/kinds/cfx.d.ts +1 -1
  197. package/dist/host/accounts/kinds/cfx.js +47 -4
  198. package/dist/host/accounts/kinds/comet.d.ts +2 -0
  199. package/dist/host/accounts/kinds/comet.js +6 -0
  200. package/dist/host/accounts/kinds/perplexity.d.ts +2 -0
  201. package/dist/host/accounts/kinds/perplexity.js +30 -0
  202. package/dist/host/accounts/leases.d.ts +7 -1
  203. package/dist/host/accounts/leases.js +13 -2
  204. package/dist/host/accounts/source.d.ts +7 -1
  205. package/dist/host/accounts/source.js +27 -0
  206. package/dist/host/accounts/sources.js +4 -0
  207. package/dist/host/github/deliver.d.ts +1 -1
  208. package/dist/host/github/deliver.js +20 -1
  209. package/dist/host/github/index.d.ts +2 -1
  210. package/dist/host/github/index.js +1 -0
  211. package/dist/host/github/token.d.ts +13 -1
  212. package/dist/host/github/token.js +19 -2
  213. package/dist/host/github/verify.d.ts +27 -0
  214. package/dist/host/github/verify.js +61 -0
  215. package/dist/host/launch/hints/fivem.d.ts +3 -1
  216. package/dist/host/launch/hints/fivem.js +68 -2
  217. package/dist/host/launch/session-file.js +4 -0
  218. package/dist/host/launch/toolchains.d.ts +2 -1
  219. package/dist/host/launch/toolchains.js +5 -3
  220. package/dist/host/vpn/nordvpn.d.ts +2 -4
  221. package/dist/host/vpn/nordvpn.js +2 -24
  222. package/dist/runtime/agent.js +405 -90
  223. package/dist/runtime/daemon.js +3010 -1383
  224. package/dist/runtime/db.js +333 -90
  225. package/dist/runtime/main.js +4720 -1954
  226. package/dist/runtime/netproxy.js +286 -69
  227. package/dist/runtime/tool.js +2852 -1780
  228. package/dist/runtime/view.js +286 -69
  229. package/dist/selftest/agent-paths.test.js +39 -1
  230. package/dist/selftest/agents-web.test.d.ts +2 -0
  231. package/dist/selftest/agents-web.test.js +647 -0
  232. package/dist/selftest/app.test.js +5 -2
  233. package/dist/selftest/boot-runner.test.d.ts +2 -0
  234. package/dist/selftest/boot-runner.test.js +456 -0
  235. package/dist/selftest/channel.test.js +15 -0
  236. package/dist/selftest/fivem.test.js +249 -3
  237. package/dist/selftest/github.test.js +94 -9
  238. package/dist/selftest/guest-boot.test.js +3 -0
  239. package/dist/selftest/health.test.js +1 -1
  240. package/dist/selftest/index.js +8 -0
  241. package/dist/selftest/layout.test.js +5 -0
  242. package/dist/selftest/menu-coverage.test.d.ts +2 -0
  243. package/dist/selftest/menu-coverage.test.js +46 -0
  244. package/dist/selftest/menu-screens.js +37 -1
  245. package/dist/selftest/persisted-installs.test.js +6 -3
  246. package/dist/selftest/service-accounts.test.js +3 -2
  247. package/dist/selftest/support/engine-golden.js +27 -0
  248. package/dist/selftest/support/fixtures.d.ts +6 -0
  249. package/dist/selftest/support/web-preview.d.ts +34 -1
  250. package/dist/selftest/support/web-preview.js +21 -18
  251. package/dist/selftest/toolchains.test.js +23 -1
  252. package/dist/selftest/ui-text.test.d.ts +7 -0
  253. package/dist/selftest/ui-text.test.js +300 -0
  254. package/dist/shared/accounts/index.d.ts +2 -0
  255. package/dist/shared/accounts/index.js +2 -0
  256. package/dist/shared/accounts/kinds/comet.d.ts +12 -0
  257. package/dist/shared/accounts/kinds/comet.js +64 -0
  258. package/dist/shared/accounts/kinds/perplexity.d.ts +8 -0
  259. package/dist/shared/accounts/kinds/perplexity.js +37 -0
  260. package/dist/shared/accounts/kinds.d.ts +24 -5
  261. package/dist/shared/accounts/kinds.js +86 -4
  262. package/dist/shared/accounts/payloads.d.ts +81 -0
  263. package/dist/shared/accounts/payloads.js +39 -1
  264. package/dist/shared/apps/agent-addons.d.ts +33 -5
  265. package/dist/shared/apps/agent-addons.js +95 -3
  266. package/dist/shared/apps/catalogue-agents-web.d.ts +14 -0
  267. package/dist/shared/apps/catalogue-agents-web.js +112 -0
  268. package/dist/shared/apps/catalogue-modding.js +32 -1
  269. package/dist/shared/apps/catalogue.d.ts +27 -3
  270. package/dist/shared/apps/catalogue.js +2 -1
  271. package/dist/shared/apps/index.d.ts +3 -1
  272. package/dist/shared/apps/index.js +3 -1
  273. package/dist/shared/channel/schema.d.ts +21 -3
  274. package/dist/shared/channel/schema.js +7 -0
  275. package/dist/shared/channel/secrets.d.ts +19 -0
  276. package/dist/shared/concurrency/index.d.ts +3 -0
  277. package/dist/shared/concurrency/index.js +3 -0
  278. package/dist/shared/concurrency/installer-retry.d.ts +6 -0
  279. package/dist/shared/concurrency/installer-retry.js +10 -0
  280. package/dist/shared/concurrency/limiter.d.ts +19 -0
  281. package/dist/shared/concurrency/limiter.js +67 -0
  282. package/dist/shared/concurrency/pools.d.ts +7 -0
  283. package/dist/shared/concurrency/pools.js +9 -0
  284. package/dist/shared/download/archive.d.ts +2 -0
  285. package/dist/shared/download/archive.js +11 -1
  286. package/dist/shared/download/bounded-fetch.d.ts +13 -0
  287. package/dist/shared/download/bounded-fetch.js +40 -0
  288. package/dist/shared/download/downloader.d.ts +5 -0
  289. package/dist/shared/download/downloader.js +50 -38
  290. package/dist/shared/download/index.d.ts +2 -1
  291. package/dist/shared/download/index.js +2 -1
  292. package/dist/shared/readiness.d.ts +2 -2
  293. package/dist/shared/readiness.js +2 -2
  294. package/dist/web/index.html +1 -1
  295. package/dist/web/{main-OUUQYNK4.js → main-CCILLX2M.js} +67 -67
  296. package/native/csharp/HcsHost/AssemblyInfo.cs +3 -3
  297. package/native/csharp/HostTools/AssemblyInfo.cs +3 -3
  298. package/native/csharp/StorageHelper/AssemblyInfo.cs +3 -3
  299. package/package.json +1 -1
  300. package/sandbox/addons/browser-use-mcp/requirements.in +1 -0
  301. package/sandbox/addons/browser-use-mcp/requirements.txt +2350 -0
  302. package/sandbox/addons/chrome-devtools-mcp/package-lock.json +38 -0
  303. package/sandbox/addons/chrome-devtools-mcp/package.json +7 -0
  304. package/sandbox/addons/comet-mcp/package-lock.json +1277 -0
  305. package/sandbox/addons/comet-mcp/package.json +7 -0
  306. package/sandbox/addons/perplexity-mcp/package-lock.json +1655 -0
  307. package/sandbox/addons/perplexity-mcp/package.json +7 -0
  308. package/sandbox/scripts/add-firewall-port.ps1 +18 -4
  309. package/sandbox/scripts/set-machine-environment.ps1 +30 -15
  310. package/sandbox/templates/fivem/README.txt +6 -2
  311. package/sandbox/templates/fivem/cs/Client/Client.csproj +15 -0
  312. package/sandbox/templates/fivem/cs/Client/ClientMain.cs +20 -0
  313. package/sandbox/templates/fivem/cs/Server/Server.csproj +14 -0
  314. package/sandbox/templates/fivem/cs/Server/ServerMain.cs +20 -0
  315. package/sandbox/templates/fivem/cs/fxmanifest.lua +11 -0
  316. package/sandbox/templates/fivem/js/client.js +12 -0
  317. package/sandbox/templates/fivem/js/fxmanifest.lua +9 -0
  318. package/sandbox/templates/fivem/js/server.js +6 -0
  319. package/sandbox/templates/fivem/lua/client.lua +8 -0
  320. package/sandbox/templates/fivem/lua/fxmanifest.lua +10 -0
  321. package/sandbox/templates/fivem/lua/server.lua +6 -0
  322. package/sandbox/templates/fivem/server.cfg +37 -0
  323. package/sandbox/templates/fivem/ts/build.js +17 -0
  324. package/sandbox/templates/fivem/ts/fxmanifest.lua +9 -0
  325. package/sandbox/templates/fivem/ts/package.json +16 -0
  326. package/sandbox/templates/fivem/ts/src/client/client.ts +12 -0
  327. package/sandbox/templates/fivem/ts/src/client/tsconfig.json +13 -0
  328. package/sandbox/templates/fivem/ts/src/server/server.ts +6 -0
  329. package/sandbox/templates/fivem/ts/src/server/tsconfig.json +13 -0
  330. package/schemas/config.schema.json +56 -27
  331. package/schemas/sandbox-config.schema.json +37 -14
@@ -6,7 +6,7 @@ import path from 'node:path';
6
6
  import { DEFAULTS } from '../core/config/index.js';
7
7
  import { assertLocalRoom, ensurePersisted, installRecords, InstallRecordsSchema, LOCAL_RESERVE_BYTES, recordUse, } from '../guest/toolchains/persisted.js';
8
8
  import { BUILD_TOOLS_COMPONENTS, UNREAL_COMPONENTS, visualStudioWanted, } from '../guest/toolchains/native/vs-request.js';
9
- import { autosdkLayout, layoutNextStep, unrealUsesAutosdk, vsExitText } from '../guest/toolchains/native/vs-request.js';
9
+ import { autosdkLayout, layoutNextStep, STAGING_RESERVE_BYTES, unrealUsesAutosdk, vsExitText, } from '../guest/toolchains/native/vs-request.js';
10
10
  import { freeBytesAt } from '../shared/io/disk.js';
11
11
  import { SIGNERS, signerMatches } from '../shared/signer.js';
12
12
  import { decideToolchains } from '../core/detect/toolchains.js';
@@ -145,6 +145,8 @@ export const persistedInstallsSuite = {
145
145
  layoutNextStep(3762504530, room(40 * GB), reserve) === 'stage' &&
146
146
  layoutNextStep(3762504530, room(20 * GB), reserve) === 'skip' &&
147
147
  layoutNextStep(null, room(40 * GB), reserve) === 'stage', 'a failed layout is built on the sandbox disk only with room for it (12 GB plus the reserve)');
148
+ t.check(layoutNextStep(null, room(15 * GB), STAGING_RESERVE_BYTES) === 'stage' &&
149
+ layoutNextStep(null, room(14 * GB), STAGING_RESERVE_BYTES) === 'skip', 'before Visual Studio is installed, 15 GB free on C: is enough to build the install files there');
148
150
  t.equal(freeBytesAt(path.join(t.dir('layout-room'), 'not', 'there'), () => ({ bavail: 3, bsize: 2 })), 6, 'free room of a folder that does not exist asks its parent');
149
151
  t.equal(freeBytesAt(t.dir('layout-room'), () => {
150
152
  throw new Error('no');
@@ -170,7 +172,8 @@ export const persistedInstallsSuite = {
170
172
  const found = decideToolchains(everything, ['ProjectVersion.txt', 'project.godot', 'fxmanifest.lua'], ['unity']);
171
173
  t.check(NOT_READY.toolchains.every((n) => !found[n].on), '"auto" never turns on a toolchain that is not written yet, whatever the project holds');
172
174
  const shown = settingsOf(ConfigFile.user(t.at('settings', 'config.json'))).map((r) => r.key.join('.'));
173
- t.check(!shown.some((k) => /^toolchains\.(unity|godot|android|flutter|dart|reactNative|fivem)\./.test(k)) &&
174
- shown.includes('toolchains.unreal.visualStudio'), 'settings do not list the toolchains that are not written yet');
175
+ t.check(!shown.some((k) => /^toolchains\.(unity|godot|android|flutter|dart|reactNative)\./.test(k)) &&
176
+ shown.includes('toolchains.unreal.visualStudio') &&
177
+ shown.some((k) => k.startsWith('toolchains.fivem.')), 'settings do not list the toolchains that are not written yet');
175
178
  },
176
179
  };
@@ -298,7 +298,7 @@ export const serviceAccountsSuite = {
298
298
  JSON.stringify(asked).includes('signs the launcher on this PC out') &&
299
299
  !JSON.stringify(seen).includes(SIGN_IN) &&
300
300
  !taken.message.includes(SIGN_IN) &&
301
- taken.message.includes('accounts.epic.share'), 'importing asks first (the command line too: --yes answers it), warns the PC is signed out, never shows the sign-in');
301
+ taken.message.includes('Share with sandboxes'), 'importing asks first (the command line too: --yes answers it), warns the PC is signed out, never shows the sign-in');
302
302
  const empty = await importServiceFlow(fakeIO([true]).io, 'epic', undefined, {
303
303
  store: flowStore,
304
304
  pc: { ...pc, localAppData: t.dir('svc-pc-empty') },
@@ -306,7 +306,8 @@ export const serviceAccountsSuite = {
306
306
  });
307
307
  t.check(empty.message.includes('No saved'), 'no launcher sign-in on this PC: it says so');
308
308
  await t.throws(() => loginServiceFlow(fakeIO([]).io, 'epic', { store: flowStore, share: true }), 'nothing to type', 'Epic has nothing to type');
309
- await t.throws(() => loginServiceFlow(fakeIO([CFX, '']).io, 'cfx', { store: flowStore, share: true }), 'comes in a later version', 'a kind whose host side is not written yet says so');
309
+ const typed = await loginServiceFlow(fakeIO([CFX, '']).io, 'cfx', { store: flowStore, share: true });
310
+ t.check(flowStore.read('cfx')?.licenseKey === CFX && !typed.message.includes(CFX), 'a typed kind (the Cfx.re key) is saved from what you type, and never shown back');
310
311
  t.check(Boolean(HOST_SOURCES.epic.fromPc) && !HOST_SOURCES.epic.fromAnswers, 'Epic comes from this PC (or a sandbox), never typed');
311
312
  const gone = await logoutServiceFlow(fakeIO([true]).io, 'epic', t.dir('svc-flow-root'), flowStore, new AccountLeases(t.dir('svc-flow-root')));
312
313
  t.check(gone.deleted && flowStore.state('epic') === 'none', 'forgetting deletes it after asking');
@@ -32,12 +32,20 @@ export const LAUNCH_FILES_GOLDEN = [
32
32
  'runtime/tool.js',
33
33
  'runtime/view.js',
34
34
  // The agent add-ons' lock files (pinned installs), copied with the rest of sandbox\.
35
+ 'sandbox/addons/browser-use-mcp/requirements.in',
36
+ 'sandbox/addons/browser-use-mcp/requirements.txt',
35
37
  'sandbox/addons/ccusage/package-lock.json',
36
38
  'sandbox/addons/ccusage/package.json',
39
+ 'sandbox/addons/chrome-devtools-mcp/package-lock.json',
40
+ 'sandbox/addons/chrome-devtools-mcp/package.json',
41
+ 'sandbox/addons/comet-mcp/package-lock.json',
42
+ 'sandbox/addons/comet-mcp/package.json',
37
43
  'sandbox/addons/context7/package-lock.json',
38
44
  'sandbox/addons/context7/package.json',
39
45
  'sandbox/addons/headroom/requirements.in',
40
46
  'sandbox/addons/headroom/requirements.txt',
47
+ 'sandbox/addons/perplexity-mcp/package-lock.json',
48
+ 'sandbox/addons/perplexity-mcp/package.json',
41
49
  'sandbox/addons/playwright-mcp/package-lock.json',
42
50
  'sandbox/addons/playwright-mcp/package.json',
43
51
  'sandbox/boot/bootstrap.ps1',
@@ -76,5 +84,24 @@ export const LAUNCH_FILES_GOLDEN = [
76
84
  'sandbox/scripts/set-dns-servers.ps1',
77
85
  'sandbox/scripts/set-machine-environment.ps1',
78
86
  'sandbox/templates/fivem/README.txt',
87
+ 'sandbox/templates/fivem/cs/Client/Client.csproj',
88
+ 'sandbox/templates/fivem/cs/Client/ClientMain.cs',
89
+ 'sandbox/templates/fivem/cs/Server/Server.csproj',
90
+ 'sandbox/templates/fivem/cs/Server/ServerMain.cs',
91
+ 'sandbox/templates/fivem/cs/fxmanifest.lua',
92
+ 'sandbox/templates/fivem/js/client.js',
93
+ 'sandbox/templates/fivem/js/fxmanifest.lua',
94
+ 'sandbox/templates/fivem/js/server.js',
95
+ 'sandbox/templates/fivem/lua/client.lua',
96
+ 'sandbox/templates/fivem/lua/fxmanifest.lua',
97
+ 'sandbox/templates/fivem/lua/server.lua',
98
+ 'sandbox/templates/fivem/server.cfg',
99
+ 'sandbox/templates/fivem/ts/build.js',
100
+ 'sandbox/templates/fivem/ts/fxmanifest.lua',
101
+ 'sandbox/templates/fivem/ts/package.json',
102
+ 'sandbox/templates/fivem/ts/src/client/client.ts',
103
+ 'sandbox/templates/fivem/ts/src/client/tsconfig.json',
104
+ 'sandbox/templates/fivem/ts/src/server/server.ts',
105
+ 'sandbox/templates/fivem/ts/src/server/tsconfig.json',
79
106
  'session.json',
80
107
  ];
@@ -132,6 +132,12 @@ export declare function createFixtures(t: Harness): {
132
132
  appstore: {
133
133
  share: boolean;
134
134
  };
135
+ perplexity: {
136
+ share: boolean;
137
+ };
138
+ comet: {
139
+ share: boolean;
140
+ };
135
141
  };
136
142
  pcInstalls: {
137
143
  steamGames: boolean | number[];
@@ -1 +1,34 @@
1
- export {};
1
+ import { AuditLog } from '../../host/audit/index.js';
2
+ import type { SessionStatus } from '../../core/types.js';
3
+ export declare const SESSIONS: SessionStatus[];
4
+ /** The sandbox as the status query would say it: running, two projects, the helper answering. */
5
+ export declare function sampleStatus(running: boolean): unknown;
6
+ /** Sample logins (names and emails only, no credentials): Claude with two, codex with one, opencode keeps none. */
7
+ export declare function sampleAccounts(): unknown;
8
+ export declare function sampleSessions(running: boolean): unknown;
9
+ /** The program's updates: installed for you, one previous version, one failed update, one saved-settings change. */
10
+ export declare function sampleUpdates(): unknown;
11
+ /** Where the saved data is (the storage area's query), parsed with its own output schema. */
12
+ export declare function sampleStorage(): unknown;
13
+ /** Contained storage (beta): off, and this PC can use it. */
14
+ export declare function sampleContained(): unknown;
15
+ /** What is stored: a toolchain, the agent's login folder, databases and logs, and what this PC keeps (sample sizes). */
16
+ export declare function sampleData(): unknown;
17
+ /** The agents as settings and the sandbox say them: two built in (one ready), two added (one ready). */
18
+ export declare function sampleAgents(): unknown;
19
+ /** Sample projects: this folder's project and a root's (mapped), one not mapped, and one excluded. */
20
+ export declare function sampleProjects(running: boolean): unknown;
21
+ /** The last check: a few results of each kind, the doctor rows, the setup and a log (nothing here is run). */
22
+ export declare function sampleHealth(): unknown;
23
+ /** The engines and their checks (what engine.status returns): HCS is missing its features on this sample PC. */
24
+ export declare function sampleEngines(): unknown;
25
+ /** The sandbox's log files, newest first, and a crash report (what logs.list returns). */
26
+ export declare function sampleLogs(): unknown;
27
+ /** The end of one log (what logs.tail returns): plausible sandbox lines, one of them very long. */
28
+ export declare function sampleLogTail(input: {
29
+ readonly name?: string;
30
+ }): unknown;
31
+ /** A plausible audit log: two agents' sessions, the sandbox's own setup, a commit each, a guard finding. */
32
+ export declare function sampleAuditLog(dir: string): AuditLog;
33
+ /** Remote access: LAN mode on, two devices, one Windows sign-in, a code waiting. */
34
+ export declare function sampleAccess(): unknown;
@@ -65,7 +65,7 @@ function startFakePty() {
65
65
  function iso(msAgo) {
66
66
  return new Date(Date.now() - msAgo).toISOString();
67
67
  }
68
- const SESSIONS = [
68
+ export const SESSIONS = [
69
69
  {
70
70
  id: 'mva4ungc50e051',
71
71
  launchId: 'launch1',
@@ -102,7 +102,7 @@ const SESSIONS = [
102
102
  },
103
103
  ];
104
104
  /** The sandbox as the status query would say it: running, two projects, the helper answering. */
105
- function sampleStatus(running) {
105
+ export function sampleStatus(running) {
106
106
  const project = (name, here, sessions) => ({
107
107
  name,
108
108
  host: 'F:\\AgentProjects\\' + name,
@@ -142,9 +142,10 @@ function sampleStatus(running) {
142
142
  });
143
143
  }
144
144
  /** Sample logins (names and emails only, no credentials): Claude with two, codex with one, opencode keeps none. */
145
- function sampleAccounts() {
145
+ export function sampleAccounts() {
146
146
  return listAccounts.output.parse({
147
147
  agent: 'claude',
148
+ services: [],
148
149
  agents: [
149
150
  {
150
151
  name: 'claude',
@@ -190,7 +191,7 @@ function sampleAccounts() {
190
191
  ],
191
192
  });
192
193
  }
193
- function sampleSessions(running) {
194
+ export function sampleSessions(running) {
194
195
  return listSessions.output.parse({
195
196
  sandboxRunning: running,
196
197
  defaultAgent: 'claude',
@@ -207,7 +208,7 @@ function sampleSessions(running) {
207
208
  });
208
209
  }
209
210
  /** The program's updates: installed for you, one previous version, one failed update, one saved-settings change. */
210
- function sampleUpdates() {
211
+ export function sampleUpdates() {
211
212
  return updatesStatus.output.parse({
212
213
  managed: true,
213
214
  version: '1.4.3',
@@ -225,7 +226,7 @@ function sampleUpdates() {
225
226
  });
226
227
  }
227
228
  /** Where the saved data is (the storage area's query), parsed with its own output schema. */
228
- function sampleStorage() {
229
+ export function sampleStorage() {
229
230
  return showStorage.output.parse({
230
231
  root: 'F:\\AgentSandbox',
231
232
  exists: true,
@@ -238,7 +239,7 @@ function sampleStorage() {
238
239
  });
239
240
  }
240
241
  /** Contained storage (beta): off, and this PC can use it. */
241
- function sampleContained() {
242
+ export function sampleContained() {
242
243
  return containedStatus.output.parse({
243
244
  setting: 'off',
244
245
  maxGb: 60,
@@ -255,7 +256,7 @@ function sampleContained() {
255
256
  });
256
257
  }
257
258
  /** What is stored: a toolchain, the agent's login folder, databases and logs, and what this PC keeps (sample sizes). */
258
- function sampleData() {
259
+ export function sampleData() {
259
260
  const GB = (n) => (n / 1e9).toFixed(1) + ' GB';
260
261
  const entry = (area, name, bytes, target) => ({
261
262
  area,
@@ -307,7 +308,7 @@ function sampleData() {
307
308
  });
308
309
  }
309
310
  /** The agents as settings and the sandbox say them: two built in (one ready), two added (one ready). */
310
- function sampleAgents() {
311
+ export function sampleAgents() {
311
312
  return listAgents.output.parse({
312
313
  folder: 'F:\\AgentProjects\\windows-sandbox',
313
314
  defaultAgent: 'claude',
@@ -320,7 +321,7 @@ function sampleAgents() {
320
321
  });
321
322
  }
322
323
  /** Sample projects: this folder's project and a root's (mapped), one not mapped, and one excluded. */
323
- function sampleProjects(running) {
324
+ export function sampleProjects(running) {
324
325
  const inSandbox = (name, how) => (running ? name + ' (' + how + ')' : null);
325
326
  return listProjects.output.parse({
326
327
  all: false,
@@ -367,7 +368,7 @@ function sampleProjects(running) {
367
368
  });
368
369
  }
369
370
  /** The last check: a few results of each kind, the doctor rows, the setup and a log (nothing here is run). */
370
- function sampleHealth() {
371
+ export function sampleHealth() {
371
372
  const at = new Date(Date.now() - 3 * MINUTE).toISOString();
372
373
  return lastHealth.output.parse({
373
374
  last: {
@@ -398,7 +399,7 @@ function sampleHealth() {
398
399
  status: 'needs-you',
399
400
  detail: 'two folders from a sandbox that did not close',
400
401
  means: 'they take space and can confuse the next start',
401
- fix: 'stop the sandbox, then run sandbox repair again',
402
+ fix: 'stop the sandbox, then repair again',
402
403
  lines: ['run-20261012-0931', 'run-20261013-1744'],
403
404
  fixable: false,
404
405
  },
@@ -434,7 +435,7 @@ function sampleHealth() {
434
435
  }
435
436
  const LOG_DIR = 'C:\\AgentData\\logs';
436
437
  /** The engines and their checks (what engine.status returns): HCS is missing its features on this sample PC. */
437
- function sampleEngines() {
438
+ export function sampleEngines() {
438
439
  const capabilities = {
439
440
  desktop: true,
440
441
  gpu: true,
@@ -484,7 +485,7 @@ function sampleEngines() {
484
485
  });
485
486
  }
486
487
  /** The sandbox's log files, newest first, and a crash report (what logs.list returns). */
487
- function sampleLogs() {
488
+ export function sampleLogs() {
488
489
  return listLogs.output.parse({
489
490
  folder: LOG_DIR,
490
491
  files: [
@@ -511,7 +512,7 @@ function sampleLogs() {
511
512
  });
512
513
  }
513
514
  /** The end of one log (what logs.tail returns): plausible sandbox lines, one of them very long. */
514
- function sampleLogTail(input) {
515
+ export function sampleLogTail(input) {
515
516
  const name = input.name ?? 'guest-2026-10-16.log';
516
517
  if (name === CRASH)
517
518
  return tailLog.output.parse({
@@ -531,7 +532,7 @@ function sampleLogTail(input) {
531
532
  });
532
533
  }
533
534
  /** A plausible audit log: two agents' sessions, the sandbox's own setup, a commit each, a guard finding. */
534
- function sampleAuditLog(dir) {
535
+ export function sampleAuditLog(dir) {
535
536
  const log = new AuditLog(dir, { days: 7, maxMb: 100 });
536
537
  const at = (minutesAgo) => new Date(Date.now() - minutesAgo * MINUTE).toISOString();
537
538
  const claude = { s: SESSIONS[0].id, ag: 'claude', pj: 'windows-sandbox', sv: 'p' };
@@ -620,7 +621,7 @@ function sampleAuditLog(dir) {
620
621
  }
621
622
  const ACCESS_FINGERPRINT = '3A:7F:01:C2:9B:44:E8:15:6D:A0:2B:93:CC:71:58:0E:F4:12:9A:BD:63:07:E5:2C:48:D9:B1:76:0A:3F:C8:E2';
622
623
  /** Remote access: LAN mode on, two devices, one Windows sign-in, a code waiting. */
623
- function sampleAccess() {
624
+ export function sampleAccess() {
624
625
  const at = (hours) => new Date(Date.now() + hours * 3_600_000).toISOString();
625
626
  return {
626
627
  lan: {
@@ -1032,4 +1033,6 @@ async function main() {
1032
1033
  console.log('Web UI preview (sample data; settings in ' + configPath + '):');
1033
1034
  console.log('http://127.0.0.1:' + server.port + '/#k=' + TOKEN);
1034
1035
  }
1035
- void main();
1036
+ // Only when run as the preview itself (the UI-text self-test imports the sample data above).
1037
+ if (/web-preview\.js$/.test(process.argv[1] ?? ''))
1038
+ void main();
@@ -5,6 +5,7 @@ import path from 'node:path';
5
5
  import { javaMajorFrom, pickGoRelease, pickNodeVersion, pickPackageVersion, pickSpreadVersions, projectUses, specFromVersionFile, } from '../core/detect/index.js';
6
6
  import { parseReleasePage, parseReleaseTags } from '../shared/download/index.js';
7
7
  import { decidePwsh, pcHasPwsh, PWSH_MAX_BYTES, readPwshScripts, usesPwsh } from '../core/detect/index.js';
8
+ import { projectFolderLines, toolLines } from '../guest/boot/guide-lines.js';
8
9
  import { binstallAsset, CLI_TOOLS, decideCli, pwshAsset } from '../guest/toolchains/catalogue.js';
9
10
  import { missingExtensions, vscodeExtensions, vscodeSettings } from '../guest/toolchains/tools/vscode-profile.js';
10
11
  import { addonGuideLine, addonMcpServer, APP_CATEGORIES, APPS, appsNeedMesa, appsNeedUv, appsToInstall, CCUSAGE_VERSION, claudeManagedSettings, CONTEXT7_MCP_VERSION, exeMatcher, HEADROOM_VERSION, headroomArgs, headroomEnv, headroomUrl, PLAYWRIGHT_MCP_VERSION, RTK_VERSION, withAddonMcpServers, } from '../shared/apps/index.js';
@@ -371,7 +372,8 @@ export const toolchainsSuite = {
371
372
  const mine = { playwright: { type: 'stdio', command: 'npx', args: ['@playwright/mcp'] } };
372
373
  const on = withAddonMcpServers(mine, pw ? { 'sbx-playwright': pw } : {}, known);
373
374
  const off = withAddonMcpServers({ ...on, 'sbx-context7': {} }, {}, known);
374
- t.check(known.length === 2 &&
375
+ t.check(['sbx-playwright', 'sbx-context7'].every((n) => known.includes(n)) &&
376
+ new Set(known).size === known.length &&
375
377
  known.every((n) => n.startsWith('sbx-')) &&
376
378
  context7?.name === 'sbx-context7' &&
377
379
  'sbx-playwright' in on &&
@@ -381,5 +383,25 @@ export const toolchainsSuite = {
381
383
  t.check(addonGuideLine([], false).length === 0 &&
382
384
  addonGuideLine(['sbx-playwright'], true).length === 2 &&
383
385
  addonGuideLine(['sbx-playwright'], false)[0].includes('sbx-playwright'), 'add-ons: the agent guide names the MCP servers and ccusage only when they are on');
386
+ t.section('sandbox guide: every project in the sandbox');
387
+ const wsGuest = 'C:\\Projects\\AgentProjects\\windows-sandbox';
388
+ const rootMap = { host: 'F:\\AgentProjects', guest: 'C:\\Projects\\AgentProjects', root: true };
389
+ const inRoot = projectFolderLines(wsGuest, 'F:\\AgentProjects\\windows-sandbox', [rootMap], []);
390
+ t.equal(inRoot.length, 1, 'a launch folder inside a mapped root is covered by the one root line (not listed twice)');
391
+ t.check(inRoot[0].includes('`C:\\Projects\\AgentProjects\\*`') && inRoot[0].includes('F:\\AgentProjects\\*'), 'the persists line names the mapped root and its PC folder');
392
+ const outside = projectFolderLines('C:\\Workspace\\app', 'D:\\app', [rootMap], [
393
+ { guest: 'C:\\Projects\\AgentProjects\\mw2-agent', host: 'F:\\AgentProjects\\mw2-agent' },
394
+ { guest: 'C:\\Workspace\\other', host: 'D:\\other' },
395
+ ]);
396
+ t.check(outside.length === 3 && outside[0].includes('C:\\Workspace\\app') && outside[2].includes('C:\\Workspace\\other'), 'the workspace outside any root is listed, a project already under a root is not repeated');
397
+ t.equal(toolLines('a', ['node: 24'], []), ['- Tools: node: 24'], 'one project: the single Tools line, as before');
398
+ const many = toolLines('a', ['node: 24'], [
399
+ { guest: 'C:\\Projects\\b', host: 'F:\\b', name: 'b', tools: ['python: 3.15.2', 'rust: 1.99'] },
400
+ { guest: 'C:\\Projects\\c', host: 'F:\\c', name: 'c', tools: [] },
401
+ ]);
402
+ t.check(many[0] === '- Tools (a): node: 24' &&
403
+ many[1] === '- Tools (b): python: 3.15.2 · rust: 1.99' &&
404
+ many.length === 3 &&
405
+ !many.join().includes('(c)'), 'several projects: the tools of each one that was set up, by name');
384
406
  },
385
407
  };
@@ -0,0 +1,7 @@
1
+ import { type Page } from '../app/kernel/index.js';
2
+ import type { Suite } from './support/suite.js';
3
+ /** Every visible string of a page: what a person reads in the menu or the web (CLI-only text is left out). */
4
+ export declare function visibleText(page: Page): string[];
5
+ /** What is wrong with a text, or undefined. */
6
+ export declare function textProblem(text: string, where: string, command?: RegExp): string | undefined;
7
+ export declare const uiTextSuite: Suite;