windows-development-sandbox 1.16.0 → 1.17.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 (58) hide show
  1. package/config.example.json +6 -0
  2. package/dist/app/features/access/access.run.js +1 -1
  3. package/dist/bin/agent-sandbox.js +2 -2
  4. package/dist/bin/{chunk-7EXDUNE7.js → chunk-QLGGAG3D.js} +1 -1
  5. package/dist/bin/{chunk-HIC4CUMY.js → chunk-REE3EMHD.js} +73 -16
  6. package/dist/bin/{chunk-PXTLKIV4.js → chunk-XYUVIVJT.js} +1 -1
  7. package/dist/bin/claude-host.js +2 -2
  8. package/dist/bin/claude-sbx.js +2 -2
  9. package/dist/bin/codex-sbx.js +2 -2
  10. package/dist/bin/gemini-sbx.js +2 -2
  11. package/dist/bin/sandbox.js +2 -2
  12. package/dist/bin/sbx-hide.js +2 -2
  13. package/dist/bin/sbx-show.js +2 -2
  14. package/dist/cli/commands/web.js +1 -1
  15. package/dist/core/config/defaults.js +1 -0
  16. package/dist/core/detect/toolchains.d.ts +1 -0
  17. package/dist/core/detect/toolchains.js +7 -0
  18. package/dist/core/schema/config.d.ts +21 -0
  19. package/dist/core/schema/sandbox.js +1 -1
  20. package/dist/core/schema/toolchains.d.ts +6 -0
  21. package/dist/core/schema/toolchains.js +10 -0
  22. package/dist/guest/boot/boot.js +2 -0
  23. package/dist/guest/setup/browser-gpu.d.ts +1 -0
  24. package/dist/guest/setup/browser-gpu.js +18 -0
  25. package/dist/guest/toolchains/native/rust-extras.js +3 -1
  26. package/dist/guest/toolchains/native/unreal.d.ts +9 -0
  27. package/dist/guest/toolchains/native/unreal.js +186 -0
  28. package/dist/guest/toolchains/native/vcruntime.d.ts +3 -0
  29. package/dist/guest/toolchains/native/vcruntime.js +2 -2
  30. package/dist/guest/toolchains/plan.js +10 -2
  31. package/dist/host/engines/hcs/live-folders.js +1 -1
  32. package/dist/host/github/token.js +1 -1
  33. package/dist/host/profile/accounts.js +1 -1
  34. package/dist/host/profile/agent-accounts.js +1 -1
  35. package/dist/host/profile/plugin-share.d.ts +5 -0
  36. package/dist/host/profile/plugin-share.js +22 -1
  37. package/dist/host/secrets/secret-store.d.ts +3 -3
  38. package/dist/host/secrets/secret-store.js +37 -10
  39. package/dist/host/vpn/login.js +1 -1
  40. package/dist/runtime/agent.js +16 -1
  41. package/dist/runtime/daemon.js +522 -337
  42. package/dist/runtime/db.js +17 -1
  43. package/dist/runtime/main.js +669 -472
  44. package/dist/runtime/netproxy.js +16 -1
  45. package/dist/runtime/view.js +16 -1
  46. package/dist/selftest/accounts.test.js +7 -0
  47. package/dist/selftest/detect.test.js +7 -0
  48. package/dist/selftest/live-network.test.js +5 -0
  49. package/dist/selftest/support/fixtures.d.ts +6 -0
  50. package/dist/shared/channel/schema.d.ts +18 -0
  51. package/native/csharp/HcsHost/AssemblyInfo.cs +3 -3
  52. package/native/csharp/HostTools/AssemblyInfo.cs +3 -3
  53. package/native/csharp/HostTools/Program.cs +6 -1
  54. package/native/csharp/HostTools/Protect.cs +41 -0
  55. package/native/csharp/StorageHelper/AssemblyInfo.cs +3 -3
  56. package/package.json +1 -1
  57. package/schemas/config.schema.json +34 -1
  58. package/schemas/sandbox-config.schema.json +34 -1
@@ -25515,7 +25515,7 @@ var SandboxSchema = external_exports.strictObject({
25515
25515
  "When the sandbox (or this PC) runs low on memory, slow builds down in steps, like a PC that gets slower instead of failing: build programs get lower CPU and memory priority, then less CPU, then compilers take turns (the waiting ones briefly suspended and trimmed to the paging file). Nothing is stopped or killed, and the agents themselves are never touched. Yours only: a project file cannot change it."
25516
25516
  ),
25517
25517
  vGpu: external_exports.boolean().describe(
25518
- "Virtual GPU. Off by default: Microsoft notes it widens the sandbox attack surface. The sandbox then uses this PC's graphics card, and with some graphics drivers heavy use can freeze the whole PC: turn it on only when a program in the sandbox needs the GPU (the mesa toolchain gives software OpenGL without it)."
25518
+ "Virtual GPU. Off by default: Microsoft notes it widens the sandbox attack surface. The sandbox then uses this PC's graphics card, and with some graphics drivers heavy use can freeze the whole PC: turn it on only when a program in the sandbox needs the GPU (the mesa toolchain gives software OpenGL without it). Browsers in the sandbox never use it (they draw in software)."
25519
25519
  ),
25520
25520
  networking: external_exports.boolean().describe("Internet access. false is the only hard network isolation Windows Sandbox offers."),
25521
25521
  clipboard: external_exports.boolean().describe(
@@ -25677,6 +25677,21 @@ var ToolchainsSchema = external_exports.strictObject({
25677
25677
  msvcVersion: external_exports.string().min(1).describe('"latest" or an MSVC tools version prefix, e.g. "14.44".'),
25678
25678
  sdkVersion: external_exports.string().min(1).describe('"latest" or a Windows SDK build, e.g. "26100" or "10.0.22621".')
25679
25679
  }),
25680
+ unreal: external_exports.strictObject({
25681
+ enabled: enabled(
25682
+ "Unreal Engine development: Visual Studio Community 2022 with the C++ game workload (MSVC, a Windows 11 SDK, .NET Framework targeting packs, Unreal integration and the Epic Games Launcher) and the DirectX End-User Runtime. A real installer: it runs every boot (~10 GB on the sandbox disk). The engine itself comes from the Epic Games Launcher or its source.",
25683
+ "a .uproject or .uplugin"
25684
+ ),
25685
+ acceptLicense: external_exports.boolean().describe(
25686
+ "Required to install: you accept the Visual Studio Community licence terms (https://visualstudio.microsoft.com/license-terms/) and the DirectX End-User Runtime licence."
25687
+ ),
25688
+ components: StringsSchema.describe(
25689
+ 'More Visual Studio workload or component IDs to add, e.g. ["Microsoft.VisualStudio.Component.VC.Llvm.Clang"].'
25690
+ ),
25691
+ keepInstallFiles: external_exports.boolean().describe(
25692
+ "Keep an offline copy of the Visual Studio install files in tools\\visualstudio (~10 GB, made once), so later boots install without downloading them again. Skipped while that disk has too little room."
25693
+ )
25694
+ }),
25680
25695
  cpp: external_exports.strictObject({
25681
25696
  enabled: enabled(
25682
25697
  "MinGW-w64 GCC with CMake, Ninja, premake5 and mingw32-make (also Rust's linker).",
@@ -26090,7 +26090,7 @@ var SandboxSchema = external_exports.strictObject({
26090
26090
  "When the sandbox (or this PC) runs low on memory, slow builds down in steps, like a PC that gets slower instead of failing: build programs get lower CPU and memory priority, then less CPU, then compilers take turns (the waiting ones briefly suspended and trimmed to the paging file). Nothing is stopped or killed, and the agents themselves are never touched. Yours only: a project file cannot change it."
26091
26091
  ),
26092
26092
  vGpu: external_exports.boolean().describe(
26093
- "Virtual GPU. Off by default: Microsoft notes it widens the sandbox attack surface. The sandbox then uses this PC's graphics card, and with some graphics drivers heavy use can freeze the whole PC: turn it on only when a program in the sandbox needs the GPU (the mesa toolchain gives software OpenGL without it)."
26093
+ "Virtual GPU. Off by default: Microsoft notes it widens the sandbox attack surface. The sandbox then uses this PC's graphics card, and with some graphics drivers heavy use can freeze the whole PC: turn it on only when a program in the sandbox needs the GPU (the mesa toolchain gives software OpenGL without it). Browsers in the sandbox never use it (they draw in software)."
26094
26094
  ),
26095
26095
  networking: external_exports.boolean().describe("Internet access. false is the only hard network isolation Windows Sandbox offers."),
26096
26096
  clipboard: external_exports.boolean().describe(
@@ -26252,6 +26252,21 @@ var ToolchainsSchema = external_exports.strictObject({
26252
26252
  msvcVersion: external_exports.string().min(1).describe('"latest" or an MSVC tools version prefix, e.g. "14.44".'),
26253
26253
  sdkVersion: external_exports.string().min(1).describe('"latest" or a Windows SDK build, e.g. "26100" or "10.0.22621".')
26254
26254
  }),
26255
+ unreal: external_exports.strictObject({
26256
+ enabled: enabled(
26257
+ "Unreal Engine development: Visual Studio Community 2022 with the C++ game workload (MSVC, a Windows 11 SDK, .NET Framework targeting packs, Unreal integration and the Epic Games Launcher) and the DirectX End-User Runtime. A real installer: it runs every boot (~10 GB on the sandbox disk). The engine itself comes from the Epic Games Launcher or its source.",
26258
+ "a .uproject or .uplugin"
26259
+ ),
26260
+ acceptLicense: external_exports.boolean().describe(
26261
+ "Required to install: you accept the Visual Studio Community licence terms (https://visualstudio.microsoft.com/license-terms/) and the DirectX End-User Runtime licence."
26262
+ ),
26263
+ components: StringsSchema.describe(
26264
+ 'More Visual Studio workload or component IDs to add, e.g. ["Microsoft.VisualStudio.Component.VC.Llvm.Clang"].'
26265
+ ),
26266
+ keepInstallFiles: external_exports.boolean().describe(
26267
+ "Keep an offline copy of the Visual Studio install files in tools\\visualstudio (~10 GB, made once), so later boots install without downloading them again. Skipped while that disk has too little room."
26268
+ )
26269
+ }),
26255
26270
  cpp: external_exports.strictObject({
26256
26271
  enabled: enabled(
26257
26272
  "MinGW-w64 GCC with CMake, Ninja, premake5 and mingw32-make (also Rust's linker).",
@@ -79,6 +79,13 @@ export const accountsSuite = {
79
79
  settingsB.enabledPlugins['p@m'] === true &&
80
80
  settingsB.enabledPlugins['q@m'] === false &&
81
81
  !fs.existsSync(path.join(storage, 'accounts', 'shared-plugins', '.credentials.json')), 'on: plugins and enabledPlugins reach the other data set; its own settings win and no login travels');
82
+ const sentinel = path.join(storage, 'accounts', 'shared-plugins', 'plugins', 'cache', 'kept.js');
83
+ t.write(sentinel, 'k');
84
+ on.activate(dataP('p1'), 'one');
85
+ t.check(fs.existsSync(sentinel), 'switching with the same plugins does not copy the plugins folder again');
86
+ t.write(path.join(plugA, 'plugins', 'installed_plugins.json'), '{"version":2,"plugins":{"p@m":[]}}');
87
+ on.activate(dataP('p1'), 'one');
88
+ t.check(!fs.existsSync(sentinel), 'once a plugin changed, the switch refreshes the shared set');
82
89
  t.write(path.join(plugC, 'plugins', 'installed_plugins.json'), '{}');
83
90
  const outside = t.dir('plugin-victim');
84
91
  t.write(path.join(outside, 'secret.txt'), 's');
@@ -66,6 +66,13 @@ export const detectSuite = {
66
66
  t.check(fresh.python.on && fresh.dotnet.on && !fresh.go.on && fresh.python.reason.includes('this PC'), 'a folder that is no project yet gets the languages this PC has, and the reason names this PC');
67
67
  const rusty = decideToolchains({ ...tc, python: { ...tc.python, enabled: true } }, ['Cargo.toml'], []);
68
68
  t.check(rusty.rust.on && rusty.cpp.on && rusty.python.on && rusty.python.reason === 'enabled in config', 'Rust brings its C/C++ linker; true in config always wins');
69
+ const game = ['ZombieGame.uproject', 'Source/ZombieGame.Target.cs'];
70
+ const accepted = { ...tc, unreal: { ...tc.unreal, acceptLicense: true } };
71
+ t.check(decideToolchains(accepted, game, []).unreal.on &&
72
+ decideToolchains(accepted, ['Plugins/Kit.uplugin'], []).unreal.on &&
73
+ !decideToolchains(accepted, ['go.mod'], []).unreal.on, 'Unreal: "auto" follows a .uproject or .uplugin');
74
+ const unaccepted = decideToolchains(tc, game, []).unreal;
75
+ t.check(!unaccepted.on && unaccepted.reason.includes('toolchains.unreal.acceptLicense'), 'Unreal is not installed until its licence is accepted, and the reason says how');
69
76
  const resolved = resolveToolchains(tc, goProject);
70
77
  t.check(resolved.go.enabled === true && resolved.python.enabled === false, 'the sandbox gets plain decisions instead of "auto"');
71
78
  t.section('optional tools: Bun, uv, VS Code');
@@ -122,6 +122,11 @@ export const liveNetworkSuite = {
122
122
  typeof e.id === 'number' &&
123
123
  typeof e.provider === 'string' &&
124
124
  typeof e.process === 'string'), 'HostTools stop-events prints a JSON list of { at, id, provider, process }', events.stdout.slice(0, 500) + events.stderr);
125
+ const plain = Buffer.from('a saved login').toString('base64');
126
+ const sealed = spawnSync(hostTools, ['protect'], { encoding: 'utf8', input: plain });
127
+ const opened = spawnSync(hostTools, ['unprotect'], { encoding: 'utf8', input: sealed.stdout });
128
+ t.check(sealed.status === 0 && sealed.stdout !== plain && opened.status === 0 && opened.stdout === plain, 'HostTools protect and unprotect round-trip through DPAPI', sealed.stderr + opened.stderr);
129
+ t.equal(spawnSync(hostTools, ['unprotect'], { encoding: 'utf8', input: 'not base64!' }).status, 1, 'HostTools unprotect refuses bad input');
125
130
  t.equal(spawnSync(hostTools, ['stop-events'], { encoding: 'utf8' }).status, 2, 'HostTools without --since prints its usage');
126
131
  },
127
132
  };
@@ -157,6 +157,12 @@ export declare function createFixtures(t: Harness): {
157
157
  msvcVersion: string;
158
158
  sdkVersion: string;
159
159
  };
160
+ unreal: {
161
+ enabled: boolean | "auto";
162
+ acceptLicense: boolean;
163
+ components: string[];
164
+ keepInstallFiles: boolean;
165
+ };
160
166
  cpp: {
161
167
  enabled: boolean | "auto";
162
168
  flexBison: boolean;
@@ -88,6 +88,12 @@ export declare const ProjectSpecSchema: z.ZodObject<{
88
88
  msvcVersion: z.ZodString;
89
89
  sdkVersion: z.ZodString;
90
90
  }, z.core.$strict>;
91
+ unreal: z.ZodObject<{
92
+ enabled: z.ZodUnion<readonly [z.ZodBoolean, z.ZodLiteral<"auto">]>;
93
+ acceptLicense: z.ZodBoolean;
94
+ components: z.ZodArray<z.ZodString>;
95
+ keepInstallFiles: z.ZodBoolean;
96
+ }, z.core.$strict>;
91
97
  cpp: z.ZodObject<{
92
98
  enabled: z.ZodUnion<readonly [z.ZodBoolean, z.ZodLiteral<"auto">]>;
93
99
  flexBison: z.ZodBoolean;
@@ -254,6 +260,12 @@ export declare const GuestRequestSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
254
260
  msvcVersion: z.ZodString;
255
261
  sdkVersion: z.ZodString;
256
262
  }, z.core.$strict>;
263
+ unreal: z.ZodObject<{
264
+ enabled: z.ZodUnion<readonly [z.ZodBoolean, z.ZodLiteral<"auto">]>;
265
+ acceptLicense: z.ZodBoolean;
266
+ components: z.ZodArray<z.ZodString>;
267
+ keepInstallFiles: z.ZodBoolean;
268
+ }, z.core.$strict>;
257
269
  cpp: z.ZodObject<{
258
270
  enabled: z.ZodUnion<readonly [z.ZodBoolean, z.ZodLiteral<"auto">]>;
259
271
  flexBison: z.ZodBoolean;
@@ -440,6 +452,12 @@ export declare const GuestRequestSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
440
452
  msvcVersion: z.ZodString;
441
453
  sdkVersion: z.ZodString;
442
454
  }, z.core.$strict>;
455
+ unreal: z.ZodObject<{
456
+ enabled: z.ZodUnion<readonly [z.ZodBoolean, z.ZodLiteral<"auto">]>;
457
+ acceptLicense: z.ZodBoolean;
458
+ components: z.ZodArray<z.ZodString>;
459
+ keepInstallFiles: z.ZodBoolean;
460
+ }, z.core.$strict>;
443
461
  cpp: z.ZodObject<{
444
462
  enabled: z.ZodUnion<readonly [z.ZodBoolean, z.ZodLiteral<"auto">]>;
445
463
  flexBison: z.ZodBoolean;
@@ -8,9 +8,9 @@ using System.Runtime.InteropServices;
8
8
  [assembly: AssemblyCompany("windows-development-sandbox (open source)")]
9
9
  [assembly: AssemblyProduct("Windows Development Sandbox")]
10
10
  [assembly: AssemblyCopyright("MIT License, windows-development-sandbox contributors")]
11
- [assembly: AssemblyVersion("1.16.0.0")]
12
- [assembly: AssemblyFileVersion("1.16.0.0")]
13
- [assembly: AssemblyInformationalVersion("1.16.0")]
11
+ [assembly: AssemblyVersion("1.17.0.0")]
12
+ [assembly: AssemblyFileVersion("1.17.0.0")]
13
+ [assembly: AssemblyInformationalVersion("1.17.0")]
14
14
  [assembly: ComVisible(false)]
15
15
  // computecore.dll and computestorage.dll are not KnownDLLs: load them from System32 only, never from the exe's folder.
16
16
  [assembly: DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
@@ -8,7 +8,7 @@ using System.Runtime.InteropServices;
8
8
  [assembly: AssemblyCompany("windows-development-sandbox (open source)")]
9
9
  [assembly: AssemblyProduct("Windows Development Sandbox")]
10
10
  [assembly: AssemblyCopyright("MIT License, windows-development-sandbox contributors")]
11
- [assembly: AssemblyVersion("1.16.0.0")]
12
- [assembly: AssemblyFileVersion("1.16.0.0")]
13
- [assembly: AssemblyInformationalVersion("1.16.0")]
11
+ [assembly: AssemblyVersion("1.17.0.0")]
12
+ [assembly: AssemblyFileVersion("1.17.0.0")]
13
+ [assembly: AssemblyInformationalVersion("1.17.0")]
14
14
  [assembly: ComVisible(false)]
@@ -8,6 +8,7 @@
8
8
  // user-path --add|--remove D D first on, or off, your PATH; exit 3 when PATH would be too long
9
9
  // web-helper --pipe P --server-pid N Windows sign-in for the web UI (WebHelper.cs), until stdin closes
10
10
  // door-client --owner USER another user's side of that sign-in: prints the answer
11
+ // protect | unprotect DPAPI for the current user (Protect.cs): base64 on stdin, base64 on stdout
11
12
  using System;
12
13
  using System.Collections.Generic;
13
14
  using System.Diagnostics;
@@ -112,6 +113,10 @@ static class Program
112
113
  return Usage();
113
114
  }
114
115
  return AgentSandbox.WebHelper.Client(value);
116
+ case "protect":
117
+ return AgentSandbox.Protect.Run(true);
118
+ case "unprotect":
119
+ return AgentSandbox.Protect.Run(false);
115
120
  default:
116
121
  return Usage();
117
122
  }
@@ -119,7 +124,7 @@ static class Program
119
124
 
120
125
  static int Usage()
121
126
  {
122
- Console.Error.WriteLine("Usage: HostTools keep-awake --owner-pid N | stop-events --since <ISO time> | memory-status | hide-window --wait S | show-window [--handles a,b] | user-path --add|--remove <folder> | web-helper --pipe P --server-pid N | door-client --owner USER");
127
+ Console.Error.WriteLine("Usage: HostTools keep-awake --owner-pid N | stop-events --since <ISO time> | memory-status | hide-window --wait S | show-window [--handles a,b] | user-path --add|--remove <folder> | web-helper --pipe P --server-pid N | door-client --owner USER | protect | unprotect");
123
128
  return 2;
124
129
  }
125
130
 
@@ -0,0 +1,41 @@
1
+ // HostTools protect / unprotect: Windows DPAPI for the current user, as native\scripts\protect-data.ps1 does it (same
2
+ // entropy, same format), without starting PowerShell. Standard input: base64 of the bytes; standard output: base64 of
3
+ // the result. Nothing goes on the command line or to disk.
4
+ using System;
5
+ using System.IO;
6
+ using System.Security.Cryptography;
7
+ using System.Text;
8
+
9
+ namespace AgentSandbox
10
+ {
11
+ static class Protect
12
+ {
13
+ /// <summary>The fixed extra secret of protect-data.ps1: another program that calls DPAPI without it cannot open these.</summary>
14
+ private const string Entropy = "agent-sandbox/secret-store/v1";
15
+
16
+ public static int Run(bool protect)
17
+ {
18
+ try
19
+ {
20
+ string text;
21
+ using (Stream input = Console.OpenStandardInput())
22
+ using (StreamReader reader = new StreamReader(input, Encoding.ASCII))
23
+ {
24
+ text = reader.ReadToEnd().Trim();
25
+ }
26
+ byte[] data = Convert.FromBase64String(text);
27
+ byte[] entropy = Encoding.UTF8.GetBytes(Entropy);
28
+ byte[] result = protect
29
+ ? ProtectedData.Protect(data, entropy, DataProtectionScope.CurrentUser)
30
+ : ProtectedData.Unprotect(data, entropy, DataProtectionScope.CurrentUser);
31
+ Console.Out.Write(Convert.ToBase64String(result));
32
+ return 0;
33
+ }
34
+ catch (Exception e)
35
+ {
36
+ Console.Error.WriteLine(e.Message);
37
+ return 1;
38
+ }
39
+ }
40
+ }
41
+ }
@@ -9,7 +9,7 @@ using System.Runtime.InteropServices;
9
9
  [assembly: AssemblyCompany("windows-development-sandbox (open source)")]
10
10
  [assembly: AssemblyProduct("Windows Development Sandbox")]
11
11
  [assembly: AssemblyCopyright("MIT License, windows-development-sandbox contributors")]
12
- [assembly: AssemblyVersion("1.16.0.0")]
13
- [assembly: AssemblyFileVersion("1.16.0.0")]
14
- [assembly: AssemblyInformationalVersion("1.16.0")]
12
+ [assembly: AssemblyVersion("1.17.0.0")]
13
+ [assembly: AssemblyFileVersion("1.17.0.0")]
14
+ [assembly: AssemblyInformationalVersion("1.17.0")]
15
15
  [assembly: ComVisible(false)]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "windows-development-sandbox",
3
- "version": "1.16.0",
3
+ "version": "1.17.0",
4
4
  "description": "A disposable Windows Sandbox for development, with or without an AI agent (Claude Code, Codex, Gemini, opencode, ...): the folder you run it from is the workspace, toolchains and databases for your project install themselves, and nothing else on your PC is reachable.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -208,7 +208,7 @@
208
208
  },
209
209
  "vGpu": {
210
210
  "type": "boolean",
211
- "description": "Virtual GPU. Off by default: Microsoft notes it widens the sandbox attack surface. The sandbox then uses this PC's graphics card, and with some graphics drivers heavy use can freeze the whole PC: turn it on only when a program in the sandbox needs the GPU (the mesa toolchain gives software OpenGL without it)."
211
+ "description": "Virtual GPU. Off by default: Microsoft notes it widens the sandbox attack surface. The sandbox then uses this PC's graphics card, and with some graphics drivers heavy use can freeze the whole PC: turn it on only when a program in the sandbox needs the GPU (the mesa toolchain gives software OpenGL without it). Browsers in the sandbox never use it (they draw in software)."
212
212
  },
213
213
  "networking": {
214
214
  "type": "boolean",
@@ -676,6 +676,39 @@
676
676
  },
677
677
  "additionalProperties": false
678
678
  },
679
+ "unreal": {
680
+ "type": "object",
681
+ "properties": {
682
+ "enabled": {
683
+ "anyOf": [
684
+ {
685
+ "type": "boolean"
686
+ },
687
+ {
688
+ "type": "string",
689
+ "const": "auto"
690
+ }
691
+ ],
692
+ "description": "Unreal Engine development: Visual Studio Community 2022 with the C++ game workload (MSVC, a Windows 11 SDK, .NET Framework targeting packs, Unreal integration and the Epic Games Launcher) and the DirectX End-User Runtime. A real installer: it runs every boot (~10 GB on the sandbox disk). The engine itself comes from the Epic Games Launcher or its source. true, false, or \"auto\" = only when the project has a .uproject or .uplugin."
693
+ },
694
+ "acceptLicense": {
695
+ "type": "boolean",
696
+ "description": "Required to install: you accept the Visual Studio Community licence terms (https://visualstudio.microsoft.com/license-terms/) and the DirectX End-User Runtime licence."
697
+ },
698
+ "components": {
699
+ "type": "array",
700
+ "items": {
701
+ "type": "string"
702
+ },
703
+ "description": "More Visual Studio workload or component IDs to add, e.g. [\"Microsoft.VisualStudio.Component.VC.Llvm.Clang\"]."
704
+ },
705
+ "keepInstallFiles": {
706
+ "type": "boolean",
707
+ "description": "Keep an offline copy of the Visual Studio install files in tools\\visualstudio (~10 GB, made once), so later boots install without downloading them again. Skipped while that disk has too little room."
708
+ }
709
+ },
710
+ "additionalProperties": false
711
+ },
679
712
  "cpp": {
680
713
  "type": "object",
681
714
  "properties": {
@@ -109,7 +109,7 @@
109
109
  },
110
110
  "vGpu": {
111
111
  "type": "boolean",
112
- "description": "Virtual GPU. Off by default: Microsoft notes it widens the sandbox attack surface. The sandbox then uses this PC's graphics card, and with some graphics drivers heavy use can freeze the whole PC: turn it on only when a program in the sandbox needs the GPU (the mesa toolchain gives software OpenGL without it)."
112
+ "description": "Virtual GPU. Off by default: Microsoft notes it widens the sandbox attack surface. The sandbox then uses this PC's graphics card, and with some graphics drivers heavy use can freeze the whole PC: turn it on only when a program in the sandbox needs the GPU (the mesa toolchain gives software OpenGL without it). Browsers in the sandbox never use it (they draw in software)."
113
113
  },
114
114
  "networking": {
115
115
  "type": "boolean",
@@ -430,6 +430,39 @@
430
430
  },
431
431
  "additionalProperties": false
432
432
  },
433
+ "unreal": {
434
+ "type": "object",
435
+ "properties": {
436
+ "enabled": {
437
+ "anyOf": [
438
+ {
439
+ "type": "boolean"
440
+ },
441
+ {
442
+ "type": "string",
443
+ "const": "auto"
444
+ }
445
+ ],
446
+ "description": "Unreal Engine development: Visual Studio Community 2022 with the C++ game workload (MSVC, a Windows 11 SDK, .NET Framework targeting packs, Unreal integration and the Epic Games Launcher) and the DirectX End-User Runtime. A real installer: it runs every boot (~10 GB on the sandbox disk). The engine itself comes from the Epic Games Launcher or its source. true, false, or \"auto\" = only when the project has a .uproject or .uplugin."
447
+ },
448
+ "acceptLicense": {
449
+ "type": "boolean",
450
+ "description": "Required to install: you accept the Visual Studio Community licence terms (https://visualstudio.microsoft.com/license-terms/) and the DirectX End-User Runtime licence."
451
+ },
452
+ "components": {
453
+ "type": "array",
454
+ "items": {
455
+ "type": "string"
456
+ },
457
+ "description": "More Visual Studio workload or component IDs to add, e.g. [\"Microsoft.VisualStudio.Component.VC.Llvm.Clang\"]."
458
+ },
459
+ "keepInstallFiles": {
460
+ "type": "boolean",
461
+ "description": "Keep an offline copy of the Visual Studio install files in tools\\visualstudio (~10 GB, made once), so later boots install without downloading them again. Skipped while that disk has too little room."
462
+ }
463
+ },
464
+ "additionalProperties": false
465
+ },
433
466
  "cpp": {
434
467
  "type": "object",
435
468
  "properties": {