windows-development-sandbox 1.25.0 → 1.25.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (158) hide show
  1. package/config.example.json +5 -2
  2. package/dist/app/features/data/data.def.d.ts +4 -4
  3. package/dist/app/features/data/data.run.d.ts +1 -1
  4. package/dist/app/features/defs.d.ts +161 -6
  5. package/dist/app/features/defs.js +7 -0
  6. package/dist/app/features/projects/projects.def.d.ts +1 -1
  7. package/dist/app/features/projects/projects.run.d.ts +1 -1
  8. package/dist/app/features/unreal/index.d.ts +2 -0
  9. package/dist/app/features/unreal/index.js +3 -0
  10. package/dist/app/features/unreal/unreal.def.d.ts +236 -0
  11. package/dist/app/features/unreal/unreal.def.js +379 -0
  12. package/dist/app/features/unreal/unreal.run.d.ts +96 -0
  13. package/dist/app/features/unreal/unreal.run.js +217 -0
  14. package/dist/app/registry.js +5 -0
  15. package/dist/bin/agent-sandbox.js +2 -2
  16. package/dist/bin/{chunk-SUYYVIDW.js → chunk-3GAXLATK.js} +58 -5
  17. package/dist/bin/{chunk-IZRGTSQ5.js → chunk-F4PVBN23.js} +2465 -1392
  18. package/dist/bin/{chunk-KH4MI2U5.js → chunk-G3TG4ZT7.js} +1 -1
  19. package/dist/bin/claude-host.js +2 -2
  20. package/dist/bin/claude-sbx.js +2 -2
  21. package/dist/bin/codex-sbx.js +2 -2
  22. package/dist/bin/gemini-sbx.js +2 -2
  23. package/dist/bin/sandbox.js +2 -2
  24. package/dist/bin/sbx-hide.js +2 -2
  25. package/dist/bin/sbx-show.js +2 -2
  26. package/dist/cli/commands/launch/launch.js +5 -2
  27. package/dist/cli/commands/registry.js +3 -0
  28. package/dist/cli/manifest.d.ts +18 -0
  29. package/dist/cli/manifest.js +26 -0
  30. package/dist/cli/menu/coverage-exempt.js +1 -0
  31. package/dist/cli/menu/pages/sandbox-page.d.ts +3 -0
  32. package/dist/cli/menu/pages/sandbox-page.js +34 -4
  33. package/dist/cli/menu/views.js +2 -0
  34. package/dist/core/config/defaults.js +18 -4
  35. package/dist/core/schema/config.d.ts +9 -7
  36. package/dist/core/schema/pc-installs.d.ts +3 -1
  37. package/dist/core/schema/pc-installs.js +10 -1
  38. package/dist/core/schema/toolchains.js +1 -1
  39. package/dist/guest/accounts/kinds/epic.js +18 -13
  40. package/dist/guest/apps/after-install.d.ts +1 -1
  41. package/dist/guest/apps/after-install.js +6 -1
  42. package/dist/guest/apps/app-installer.d.ts +1 -0
  43. package/dist/guest/apps/app-installer.js +13 -3
  44. package/dist/guest/apps/comet-unpack.js +3 -2
  45. package/dist/guest/apps/resolvers-gamedev.js +55 -1
  46. package/dist/guest/boot/boot.js +14 -1
  47. package/dist/guest/boot/guide.js +24 -0
  48. package/dist/guest/daemon/daemon.js +3 -0
  49. package/dist/guest/setup/addon-mcp.d.ts +7 -0
  50. package/dist/guest/setup/addon-mcp.js +19 -4
  51. package/dist/guest/setup/browser-gpu.js +14 -11
  52. package/dist/guest/setup/headroom.js +4 -0
  53. package/dist/guest/toolchains/engines/epic-launcher.d.ts +26 -0
  54. package/dist/guest/toolchains/engines/epic-launcher.js +127 -0
  55. package/dist/guest/toolchains/engines/unreal-engines.d.ts +21 -1
  56. package/dist/guest/toolchains/engines/unreal-engines.js +163 -3
  57. package/dist/guest/toolchains/engines/unreal-status.d.ts +13 -0
  58. package/dist/guest/toolchains/engines/unreal-status.js +41 -0
  59. package/dist/guest/toolchains/native/debuggers.d.ts +6 -0
  60. package/dist/guest/toolchains/native/debuggers.js +57 -0
  61. package/dist/guest/toolchains/native/mesa.js +15 -8
  62. package/dist/guest/toolchains/native/rust-extras.d.ts +7 -0
  63. package/dist/guest/toolchains/native/rust-extras.js +23 -1
  64. package/dist/guest/toolchains/native/unreal.d.ts +2 -2
  65. package/dist/guest/toolchains/native/unreal.js +96 -18
  66. package/dist/guest/toolchains/plan.js +12 -1
  67. package/dist/guest/toolchains/tools/vscode-profile.js +2 -0
  68. package/dist/host/accounts/kinds/epic.js +11 -5
  69. package/dist/host/accounts/source.d.ts +2 -0
  70. package/dist/host/accounts/source.js +1 -0
  71. package/dist/host/pc-installs/discover.d.ts +2 -0
  72. package/dist/host/pc-installs/discover.js +25 -5
  73. package/dist/host/pc-installs/epic.d.ts +3 -0
  74. package/dist/host/pc-installs/epic.js +33 -2
  75. package/dist/host/pc-installs/source.d.ts +1 -1
  76. package/dist/host/pc-installs/unreal-vault.d.ts +11 -0
  77. package/dist/host/pc-installs/unreal-vault.js +78 -0
  78. package/dist/host/pc-installs/unreal.d.ts +36 -0
  79. package/dist/host/pc-installs/unreal.js +145 -2
  80. package/dist/host/profile/claude-profile.d.ts +8 -0
  81. package/dist/host/profile/claude-profile.js +43 -4
  82. package/dist/host/profile/index.d.ts +1 -1
  83. package/dist/host/profile/index.js +1 -1
  84. package/dist/runtime/agent.js +81 -7
  85. package/dist/runtime/daemon.js +2645 -1287
  86. package/dist/runtime/db.js +81 -7
  87. package/dist/runtime/main.js +2901 -1722
  88. package/dist/runtime/netproxy.js +81 -7
  89. package/dist/runtime/tool.js +81 -7
  90. package/dist/runtime/view.js +81 -7
  91. package/dist/selftest/agent-paths.test.js +1 -0
  92. package/dist/selftest/agents-web.test.js +12 -0
  93. package/dist/selftest/engines.test.js +602 -3
  94. package/dist/selftest/heavy-load.test.js +3 -1
  95. package/dist/selftest/hostile-input.test.js +11 -1
  96. package/dist/selftest/index.js +2 -0
  97. package/dist/selftest/menu-screens.js +3 -1
  98. package/dist/selftest/mixamo.test.d.ts +2 -0
  99. package/dist/selftest/mixamo.test.js +60 -0
  100. package/dist/selftest/secrets.test.js +36 -1
  101. package/dist/selftest/support/engine-golden.js +3 -0
  102. package/dist/selftest/support/fixtures.d.ts +3 -1
  103. package/dist/selftest/support/unreal-sample.d.ts +2 -0
  104. package/dist/selftest/support/unreal-sample.js +83 -0
  105. package/dist/selftest/toolchains.test.js +32 -2
  106. package/dist/shared/accounts/index.d.ts +1 -1
  107. package/dist/shared/accounts/index.js +1 -1
  108. package/dist/shared/accounts/kinds/epic.d.ts +6 -1
  109. package/dist/shared/accounts/kinds/epic.js +11 -1
  110. package/dist/shared/apps/associations.d.ts +7 -0
  111. package/dist/shared/apps/associations.js +26 -0
  112. package/dist/shared/apps/catalogue-agents-web.d.ts +4 -1
  113. package/dist/shared/apps/catalogue-agents-web.js +5 -2
  114. package/dist/shared/apps/catalogue-gamedev.js +71 -1
  115. package/dist/shared/apps/index.d.ts +2 -0
  116. package/dist/shared/apps/index.js +2 -0
  117. package/dist/shared/apps/preview.d.ts +2 -0
  118. package/dist/shared/apps/preview.js +10 -0
  119. package/dist/shared/browser-policy.d.ts +14 -0
  120. package/dist/shared/browser-policy.js +22 -0
  121. package/dist/shared/io/index.d.ts +1 -0
  122. package/dist/shared/io/index.js +1 -0
  123. package/dist/shared/io/rotate-log.d.ts +2 -0
  124. package/dist/shared/io/rotate-log.js +16 -0
  125. package/dist/shared/memory/policy.d.ts +5 -0
  126. package/dist/shared/memory/policy.js +7 -0
  127. package/dist/shared/paths/pc-installs.d.ts +13 -2
  128. package/dist/shared/paths/pc-installs.js +1 -0
  129. package/dist/shared/readiness.d.ts +0 -1
  130. package/dist/shared/readiness.js +0 -1
  131. package/dist/shared/signer.d.ts +4 -0
  132. package/dist/shared/signer.js +2 -0
  133. package/dist/shared/unreal/engines.d.ts +161 -0
  134. package/dist/shared/unreal/engines.js +308 -0
  135. package/dist/shared/unreal/guide.d.ts +19 -0
  136. package/dist/shared/unreal/guide.js +105 -0
  137. package/dist/shared/unreal/index.d.ts +7 -0
  138. package/dist/shared/unreal/index.js +8 -0
  139. package/dist/shared/unreal/launcher-files.d.ts +88 -0
  140. package/dist/shared/unreal/launcher-files.js +292 -0
  141. package/dist/shared/unreal/mixamo.d.ts +5 -0
  142. package/dist/shared/unreal/mixamo.js +16 -0
  143. package/dist/shared/unreal/room.d.ts +17 -0
  144. package/dist/shared/unreal/room.js +34 -0
  145. package/dist/shared/unreal/status.d.ts +54 -0
  146. package/dist/shared/unreal/status.js +57 -0
  147. package/dist/shared/unreal/vault.d.ts +21 -0
  148. package/dist/shared/unreal/vault.js +67 -0
  149. package/dist/shared/unreal/vs-check.d.ts +39 -0
  150. package/dist/shared/unreal/vs-check.js +79 -0
  151. package/dist/web/index.html +1 -1
  152. package/dist/web/{main-CCILLX2M.js → main-FNE6XEHA.js} +84 -84
  153. package/package.json +1 -1
  154. package/sandbox/csharp/VsSetup.cs +210 -0
  155. package/sandbox/scripts/get-vs-setup.ps1 +93 -0
  156. package/sandbox/scripts/set-registry-values.ps1 +35 -0
  157. package/schemas/config.schema.json +35 -2
  158. package/schemas/sandbox-config.schema.json +8 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "windows-development-sandbox",
3
- "version": "1.25.0",
3
+ "version": "1.25.1",
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",
@@ -0,0 +1,210 @@
1
+ // The Visual Studio Setup Configuration API as UnrealBuildTool calls it (MicrosoftPlatformSDK: SetupConfiguration,
2
+ // ISetupConfiguration2.EnumAllInstances, ISetupInstance2): every instance with its state, version, product, path and
3
+ // packages. Loaded by scripts\get-vs-setup.ps1 (Add-Type), which adds the file checks and writes the JSON. C# 5.
4
+ using System;
5
+ using System.Collections.Generic;
6
+ using System.Runtime.InteropServices;
7
+ using FILETIME = System.Runtime.InteropServices.ComTypes.FILETIME;
8
+
9
+ namespace AgentSandbox
10
+ {
11
+ [ComImport]
12
+ [Guid("42843719-DB4C-46C2-8E7C-64F1816EFD5B")]
13
+ [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
14
+ public interface ISetupConfiguration
15
+ {
16
+ IEnumSetupInstances EnumInstances();
17
+ ISetupInstance GetInstanceForCurrentProcess();
18
+ ISetupInstance GetInstanceForPath([In, MarshalAs(UnmanagedType.LPWStr)] string path);
19
+ }
20
+
21
+ [ComImport]
22
+ [Guid("26AAB78C-4A60-49D6-AF3B-3C35BC93365D")]
23
+ [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
24
+ public interface ISetupConfiguration2 : ISetupConfiguration
25
+ {
26
+ new IEnumSetupInstances EnumInstances();
27
+ new ISetupInstance GetInstanceForCurrentProcess();
28
+ new ISetupInstance GetInstanceForPath([In, MarshalAs(UnmanagedType.LPWStr)] string path);
29
+ IEnumSetupInstances EnumAllInstances();
30
+ }
31
+
32
+ [ComImport]
33
+ [Guid("6380BCFF-41D3-4B2E-8B2E-BF8A6810C848")]
34
+ [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
35
+ public interface IEnumSetupInstances
36
+ {
37
+ void Next(
38
+ [In, MarshalAs(UnmanagedType.U4)] int celt,
39
+ [Out, MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.Interface, SizeParamIndex = 0)]
40
+ ISetupInstance[] rgelt,
41
+ [Out, MarshalAs(UnmanagedType.U4)] out int pceltFetched);
42
+ void Skip([In, MarshalAs(UnmanagedType.U4)] int celt);
43
+ void Reset();
44
+ IEnumSetupInstances Clone();
45
+ }
46
+
47
+ [ComImport]
48
+ [Guid("B41463C3-8866-43B5-BC33-2B0676F7F42E")]
49
+ [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
50
+ public interface ISetupInstance
51
+ {
52
+ [return: MarshalAs(UnmanagedType.BStr)] string GetInstanceId();
53
+ [return: MarshalAs(UnmanagedType.Struct)] FILETIME GetInstallDate();
54
+ [return: MarshalAs(UnmanagedType.BStr)] string GetInstallationName();
55
+ [return: MarshalAs(UnmanagedType.BStr)] string GetInstallationPath();
56
+ [return: MarshalAs(UnmanagedType.BStr)] string GetInstallationVersion();
57
+ [return: MarshalAs(UnmanagedType.BStr)] string GetDisplayName([In, MarshalAs(UnmanagedType.U4)] int lcid);
58
+ [return: MarshalAs(UnmanagedType.BStr)] string GetDescription([In, MarshalAs(UnmanagedType.U4)] int lcid);
59
+ [return: MarshalAs(UnmanagedType.BStr)] string ResolvePath([In, MarshalAs(UnmanagedType.LPWStr)] string path);
60
+ }
61
+
62
+ [ComImport]
63
+ [Guid("89143C9A-05AF-49B0-B717-72E218A2185C")]
64
+ [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
65
+ public interface ISetupInstance2 : ISetupInstance
66
+ {
67
+ [return: MarshalAs(UnmanagedType.BStr)] new string GetInstanceId();
68
+ [return: MarshalAs(UnmanagedType.Struct)] new FILETIME GetInstallDate();
69
+ [return: MarshalAs(UnmanagedType.BStr)] new string GetInstallationName();
70
+ [return: MarshalAs(UnmanagedType.BStr)] new string GetInstallationPath();
71
+ [return: MarshalAs(UnmanagedType.BStr)] new string GetInstallationVersion();
72
+ [return: MarshalAs(UnmanagedType.BStr)] new string GetDisplayName([In, MarshalAs(UnmanagedType.U4)] int lcid);
73
+ [return: MarshalAs(UnmanagedType.BStr)] new string GetDescription([In, MarshalAs(UnmanagedType.U4)] int lcid);
74
+ [return: MarshalAs(UnmanagedType.BStr)] new string ResolvePath([In, MarshalAs(UnmanagedType.LPWStr)] string path);
75
+ [return: MarshalAs(UnmanagedType.U4)] uint GetState();
76
+ [return: MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_UNKNOWN)]
77
+ ISetupPackageReference[] GetPackages();
78
+ ISetupPackageReference GetProduct();
79
+ [return: MarshalAs(UnmanagedType.BStr)] string GetProductPath();
80
+ [return: MarshalAs(UnmanagedType.IUnknown)] object GetErrors();
81
+ [return: MarshalAs(UnmanagedType.VariantBool)] bool IsLaunchable();
82
+ [return: MarshalAs(UnmanagedType.VariantBool)] bool IsComplete();
83
+ }
84
+
85
+ [ComImport]
86
+ [Guid("DA8D8A16-B2B6-4487-A2F1-594CCCCD6BF5")]
87
+ [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
88
+ public interface ISetupPackageReference
89
+ {
90
+ [return: MarshalAs(UnmanagedType.BStr)] string GetId();
91
+ [return: MarshalAs(UnmanagedType.BStr)] string GetVersion();
92
+ [return: MarshalAs(UnmanagedType.BStr)] string GetChip();
93
+ [return: MarshalAs(UnmanagedType.BStr)] string GetLanguage();
94
+ [return: MarshalAs(UnmanagedType.BStr)] string GetBranch();
95
+ [return: MarshalAs(UnmanagedType.BStr)] string GetType();
96
+ [return: MarshalAs(UnmanagedType.BStr)] string GetUniqueId();
97
+ [return: MarshalAs(UnmanagedType.VariantBool)] bool GetIsExtension();
98
+ }
99
+
100
+ [ComImport]
101
+ [Guid("177F0C4A-1CD3-4DE7-A32C-71DBBB9FA36D")]
102
+ [ClassInterface(ClassInterfaceType.None)]
103
+ public class SetupConfiguration
104
+ {
105
+ }
106
+
107
+ /// <summary>One instance as the Setup API reports it.</summary>
108
+ public class SetupInstanceInfo
109
+ {
110
+ public string InstanceId;
111
+ public string InstallationPath;
112
+ public string InstallationVersion;
113
+ public string ProductId;
114
+ public uint State;
115
+ public bool IsComplete;
116
+ public bool IsLaunchable;
117
+ public string[] Packages;
118
+ }
119
+
120
+ public static class VsSetup
121
+ {
122
+ /// <summary>InstanceState.Local: the instance's files are on this machine (the only ones UnrealBuildTool uses).</summary>
123
+ public const uint StateLocal = 1;
124
+
125
+ /// <summary>Every instance EnumAllInstances lists (complete or not), as UnrealBuildTool enumerates them.</summary>
126
+ public static SetupInstanceInfo[] AllInstances()
127
+ {
128
+ List<SetupInstanceInfo> found = new List<SetupInstanceInfo>();
129
+ ISetupConfiguration2 setup = (ISetupConfiguration2)new SetupConfiguration();
130
+ IEnumSetupInstances instances = null;
131
+ try
132
+ {
133
+ instances = setup.EnumAllInstances();
134
+ ISetupInstance[] one = new ISetupInstance[1];
135
+ while (true)
136
+ {
137
+ int fetched;
138
+ instances.Next(1, one, out fetched);
139
+ if (fetched == 0)
140
+ {
141
+ break;
142
+ }
143
+ ISetupInstance2 instance = (ISetupInstance2)one[0];
144
+ try
145
+ {
146
+ found.Add(Describe(instance));
147
+ }
148
+ finally
149
+ {
150
+ Marshal.ReleaseComObject(instance);
151
+ }
152
+ }
153
+ }
154
+ finally
155
+ {
156
+ if (instances != null)
157
+ {
158
+ Marshal.ReleaseComObject(instances);
159
+ }
160
+ Marshal.ReleaseComObject(setup);
161
+ }
162
+ return found.ToArray();
163
+ }
164
+
165
+ private static SetupInstanceInfo Describe(ISetupInstance2 instance)
166
+ {
167
+ SetupInstanceInfo info = new SetupInstanceInfo();
168
+ info.InstanceId = instance.GetInstanceId();
169
+ info.InstallationPath = instance.GetInstallationPath();
170
+ info.InstallationVersion = instance.GetInstallationVersion();
171
+ info.State = instance.GetState();
172
+ ISetupPackageReference product = instance.GetProduct();
173
+ if (product == null)
174
+ {
175
+ info.ProductId = "";
176
+ }
177
+ else
178
+ {
179
+ try
180
+ {
181
+ info.ProductId = product.GetId();
182
+ }
183
+ finally
184
+ {
185
+ Marshal.ReleaseComObject(product);
186
+ }
187
+ }
188
+ info.IsComplete = instance.IsComplete();
189
+ info.IsLaunchable = instance.IsLaunchable();
190
+ ISetupPackageReference[] packages = instance.GetPackages();
191
+ List<string> ids = new List<string>();
192
+ if (packages != null)
193
+ {
194
+ foreach (ISetupPackageReference package in packages)
195
+ {
196
+ try
197
+ {
198
+ ids.Add(package.GetId());
199
+ }
200
+ finally
201
+ {
202
+ Marshal.ReleaseComObject(package);
203
+ }
204
+ }
205
+ }
206
+ info.Packages = ids.ToArray();
207
+ return info;
208
+ }
209
+ }
210
+ }
@@ -0,0 +1,93 @@
1
+ #Requires -Version 5.1
2
+ # Looks for Visual Studio the way UnrealBuildTool does (guest/toolchains/engines/unreal-engines.ts runs it; the
3
+ # verdict is decided in vs-check.ts): every instance the Setup Configuration API lists (csharp\VsSetup.cs), the MSVC
4
+ # toolchains under each one's VC\Tools\MSVC that have the x64 compiler, and the Windows SDKs under each KitsRoot10 the
5
+ # registry names (HKLM in both views, HKCU) that have windows.h and the x64 kernel32.lib. Writes JSON to -ResultFile.
6
+ param([Parameter(Mandatory = $true)][string]$ResultFile)
7
+ $ErrorActionPreference = 'Stop'
8
+
9
+ Add-Type -Path (Join-Path $PSScriptRoot '..\csharp\VsSetup.cs')
10
+
11
+ $instances = New-Object System.Collections.ArrayList
12
+ $setupError = ''
13
+ try {
14
+ foreach ($i in [AgentSandbox.VsSetup]::AllInstances()) {
15
+ $toolchains = New-Object System.Collections.ArrayList
16
+ $msvc = Join-Path $i.InstallationPath 'VC\Tools\MSVC'
17
+ if (Test-Path -LiteralPath $msvc -PathType Container) {
18
+ foreach ($dir in Get-ChildItem -LiteralPath $msvc -Directory) {
19
+ $cl = Join-Path $dir.FullName 'bin\Hostx64\x64\cl.exe'
20
+ $link = Join-Path $dir.FullName 'bin\Hostx64\x64\link.exe'
21
+ [void]$toolchains.Add([ordered]@{
22
+ version = $dir.Name
23
+ cl = (Test-Path -LiteralPath $cl -PathType Leaf)
24
+ link = (Test-Path -LiteralPath $link -PathType Leaf)
25
+ })
26
+ }
27
+ }
28
+ $wanted = @('Microsoft.VisualStudio.Component.VC.Tools.x86.x64', 'Microsoft.VisualStudio.Workload.NativeGame',
29
+ 'Microsoft.VisualStudio.Workload.VCTools', 'Component.Unreal', 'Component.Unreal.Ide')
30
+ [void]$instances.Add([ordered]@{
31
+ instanceId = $i.InstanceId
32
+ installationPath = $i.InstallationPath
33
+ installationVersion = $i.InstallationVersion
34
+ productId = $i.ProductId
35
+ state = [int64]$i.State
36
+ isComplete = $i.IsComplete
37
+ isLaunchable = $i.IsLaunchable
38
+ packages = @($i.Packages | Where-Object { $wanted -contains $_ })
39
+ packageCount = @($i.Packages).Count
40
+ toolchains = @($toolchains)
41
+ })
42
+ }
43
+ } catch {
44
+ $setupError = $_.Exception.Message
45
+ }
46
+
47
+ $roots = New-Object System.Collections.ArrayList
48
+ $places = @(
49
+ @{ hive = [Microsoft.Win32.RegistryHive]::LocalMachine; view = [Microsoft.Win32.RegistryView]::Registry64; name = 'HKLM (64-bit)' },
50
+ @{ hive = [Microsoft.Win32.RegistryHive]::LocalMachine; view = [Microsoft.Win32.RegistryView]::Registry32; name = 'HKLM (32-bit)' },
51
+ @{ hive = [Microsoft.Win32.RegistryHive]::CurrentUser; view = [Microsoft.Win32.RegistryView]::Registry64; name = 'HKCU' }
52
+ )
53
+ foreach ($place in $places) {
54
+ $base = [Microsoft.Win32.RegistryKey]::OpenBaseKey($place.hive, $place.view)
55
+ try {
56
+ $key = $base.OpenSubKey('SOFTWARE\Microsoft\Windows Kits\Installed Roots')
57
+ if ($key) {
58
+ $value = [string]$key.GetValue('KitsRoot10')
59
+ $key.Close()
60
+ if ($value) { [void]$roots.Add([ordered]@{ where = $place.name; path = $value }) }
61
+ }
62
+ } finally {
63
+ $base.Close()
64
+ }
65
+ }
66
+
67
+ $sdks = New-Object System.Collections.ArrayList
68
+ $seen = @{}
69
+ foreach ($root in $roots) {
70
+ $include = Join-Path $root.path 'Include'
71
+ if ($seen.ContainsKey($include.ToLowerInvariant())) { continue }
72
+ $seen[$include.ToLowerInvariant()] = $true
73
+ if (-not (Test-Path -LiteralPath $include -PathType Container)) { continue }
74
+ foreach ($dir in Get-ChildItem -LiteralPath $include -Directory) {
75
+ if ($dir.Name -notmatch '^10\.\d+\.\d+\.\d+$') { continue }
76
+ [void]$sdks.Add([ordered]@{
77
+ version = $dir.Name
78
+ root = $root.path
79
+ windowsH = (Test-Path -LiteralPath (Join-Path $dir.FullName 'um\windows.h') -PathType Leaf)
80
+ kernel32 = (Test-Path -LiteralPath (Join-Path $root.path ('Lib\' + $dir.Name + '\um\x64\kernel32.lib')) -PathType Leaf)
81
+ ucrt = (Test-Path -LiteralPath (Join-Path $root.path ('Lib\' + $dir.Name + '\ucrt\x64\ucrt.lib')) -PathType Leaf)
82
+ })
83
+ }
84
+ }
85
+
86
+ $result = [ordered]@{
87
+ setupError = $setupError
88
+ instances = @($instances)
89
+ kitsRoots = @($roots)
90
+ sdks = @($sdks)
91
+ }
92
+ $json = ConvertTo-Json -InputObject $result -Depth 6
93
+ [System.IO.File]::WriteAllText($ResultFile, $json, (New-Object System.Text.UTF8Encoding($false)))
@@ -0,0 +1,35 @@
1
+ #Requires -Version 5.1
2
+ # Writes string registry values from a plan (guest/toolchains/engines/unreal-engines.ts: the Unreal engines'
3
+ # registration and the .uproject file association; what goes where is decided in shared/unreal/engines.ts). -PlanFile
4
+ # is JSON written by the runtime:
5
+ # values: [{ hive: 'HKLM' | 'HKCU', key, name, value }] 64-bit view, '' = the default value
6
+ # Safe to run again. Exit 0 when every value is set, 2 when one could not be.
7
+ param([Parameter(Mandatory = $true)][string]$PlanFile)
8
+ $ErrorActionPreference = 'Stop'
9
+
10
+ $plan = Get-Content -LiteralPath $PlanFile -Raw -Encoding UTF8 | ConvertFrom-Json
11
+ $failed = New-Object System.Collections.ArrayList
12
+ $set = 0
13
+ foreach ($v in @($plan.values)) {
14
+ $hive = if ($v.hive -eq 'HKLM') { [Microsoft.Win32.RegistryHive]::LocalMachine } else { [Microsoft.Win32.RegistryHive]::CurrentUser }
15
+ $base = [Microsoft.Win32.RegistryKey]::OpenBaseKey($hive, [Microsoft.Win32.RegistryView]::Registry64)
16
+ try {
17
+ $key = $base.CreateSubKey([string]$v.key)
18
+ try {
19
+ $key.SetValue([string]$v.name, [string]$v.value, [Microsoft.Win32.RegistryValueKind]::String)
20
+ $set++
21
+ } finally {
22
+ $key.Close()
23
+ }
24
+ } catch {
25
+ [void]$failed.Add($v.hive + '\' + $v.key + ' ' + $v.name + ' (' + $_.Exception.Message + ')')
26
+ } finally {
27
+ $base.Close()
28
+ }
29
+ }
30
+ if ($failed.Count) {
31
+ Write-Host ('Could not set: ' + ($failed -join '; '))
32
+ exit 2
33
+ }
34
+ Write-Host ('Set ' + $set + ' registry values')
35
+ exit 0
@@ -554,6 +554,10 @@
554
554
  },
555
555
  "unrealEngines": {
556
556
  "anyOf": [
557
+ {
558
+ "type": "string",
559
+ "const": "auto"
560
+ },
557
561
  {
558
562
  "type": "boolean"
559
563
  },
@@ -565,7 +569,29 @@
565
569
  }
566
570
  }
567
571
  ],
568
- "description": "Unreal Engine versions installed with the Epic Games Launcher of this PC, read-only in the sandbox under C:\\PcInstalls: true = all of them, false = none, or a list (e.g. [\"5.4\"]). The agent can read their files."
572
+ "description": "Unreal Engine versions installed on this PC (with the Epic Games Launcher, or source builds it lists), read-only in the sandbox under C:\\PcInstalls\\unreal and registered there, so projects build with them without a download. \"auto\" = all of them whenever the sandbox is set up for Unreal, true = always, false = never, or a list (e.g. [\"5.4\"])."
573
+ },
574
+ "unrealEngineFolders": {
575
+ "maxItems": 8,
576
+ "type": "array",
577
+ "items": {
578
+ "type": "string",
579
+ "minLength": 3,
580
+ "maxLength": 260
581
+ },
582
+ "description": "Unreal Engine folders of this PC to use in the sandbox, writable (a source build, or a copy you build plugins into): each must hold Engine\\Build\\Build.version. Mapped under C:\\PcInstalls\\unreal and registered there."
583
+ },
584
+ "unrealAssets": {
585
+ "anyOf": [
586
+ {
587
+ "type": "string",
588
+ "const": "auto"
589
+ },
590
+ {
591
+ "type": "boolean"
592
+ }
593
+ ],
594
+ "description": "The Epic Games Launcher's vault cache of this PC (the Fab and Marketplace packs you downloaded), read-only in the sandbox at C:\\PcInstalls\\unreal\\Vault: what you download on your PC is there for the agents at once. \"auto\" = whenever the sandbox is set up for Unreal, true = always, false = never."
569
595
  },
570
596
  "unityEditors": {
571
597
  "anyOf": [
@@ -800,7 +826,7 @@
800
826
  "lld",
801
827
  "gnu"
802
828
  ],
803
- "description": "GNU host: \"lld\" links with Rust's own lld through MinGW's gcc (much less memory than GNU ld), \"gnu\" with GNU ld."
829
+ "description": "\"lld\" (default) links with Rust's own lld: through MinGW's gcc on the GNU host (much less memory than GNU ld), and instead of link.exe on the MSVC host (link.exe writes executables into mapped folders as all zeros: os error 1392). \"gnu\" keeps GNU ld / link.exe."
804
830
  },
805
831
  "linkSlots": {
806
832
  "anyOf": [
@@ -2026,6 +2052,13 @@
2026
2052
  "gitleaks",
2027
2053
  "ast-grep",
2028
2054
  "rust-analyzer",
2055
+ "krita",
2056
+ "inkscape",
2057
+ "audacity",
2058
+ "renderdoc",
2059
+ "f3d",
2060
+ "imagemagick",
2061
+ "nomacs",
2029
2062
  "lua-language-server",
2030
2063
  "stylua",
2031
2064
  "selene",
@@ -485,7 +485,7 @@
485
485
  "lld",
486
486
  "gnu"
487
487
  ],
488
- "description": "GNU host: \"lld\" links with Rust's own lld through MinGW's gcc (much less memory than GNU ld), \"gnu\" with GNU ld."
488
+ "description": "\"lld\" (default) links with Rust's own lld: through MinGW's gcc on the GNU host (much less memory than GNU ld), and instead of link.exe on the MSVC host (link.exe writes executables into mapped folders as all zeros: os error 1392). \"gnu\" keeps GNU ld / link.exe."
489
489
  },
490
490
  "linkSlots": {
491
491
  "anyOf": [
@@ -1565,6 +1565,13 @@
1565
1565
  "gitleaks",
1566
1566
  "ast-grep",
1567
1567
  "rust-analyzer",
1568
+ "krita",
1569
+ "inkscape",
1570
+ "audacity",
1571
+ "renderdoc",
1572
+ "f3d",
1573
+ "imagemagick",
1574
+ "nomacs",
1568
1575
  "lua-language-server",
1569
1576
  "stylua",
1570
1577
  "selene"