windows-development-sandbox 1.23.2 → 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 (211) hide show
  1. package/config.example.json +5 -3
  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-7YPEDAJD.js → chunk-3GAXLATK.js} +58 -5
  17. package/dist/bin/{chunk-USTRSHIE.js → chunk-F4PVBN23.js} +2615 -1515
  18. package/dist/bin/{chunk-QFSJX2KW.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 -5
  35. package/dist/core/detect/toolchains.js +0 -6
  36. package/dist/core/schema/config.d.ts +10 -9
  37. package/dist/core/schema/pc-installs.d.ts +3 -1
  38. package/dist/core/schema/pc-installs.js +10 -1
  39. package/dist/core/schema/toolchains.d.ts +1 -2
  40. package/dist/core/schema/toolchains.js +4 -7
  41. package/dist/guest/accounts/kinds/epic.js +18 -13
  42. package/dist/guest/agents/agent-files.d.ts +11 -7
  43. package/dist/guest/agents/agent-files.js +37 -11
  44. package/dist/guest/agents/local-state.d.ts +2 -1
  45. package/dist/guest/agents/local-state.js +2 -1
  46. package/dist/guest/apps/after-install.d.ts +1 -1
  47. package/dist/guest/apps/after-install.js +6 -1
  48. package/dist/guest/apps/app-installer.d.ts +1 -0
  49. package/dist/guest/apps/app-installer.js +13 -3
  50. package/dist/guest/apps/comet-unpack.js +3 -2
  51. package/dist/guest/apps/resolvers-gamedev.js +55 -1
  52. package/dist/guest/boot/boot-console.d.ts +28 -0
  53. package/dist/guest/boot/boot-console.js +98 -0
  54. package/dist/guest/boot/boot.d.ts +8 -1
  55. package/dist/guest/boot/boot.js +80 -43
  56. package/dist/guest/boot/graph.d.ts +9 -5
  57. package/dist/guest/boot/graph.js +8 -2
  58. package/dist/guest/boot/guide.js +24 -0
  59. package/dist/guest/boot/progress-view.d.ts +116 -0
  60. package/dist/guest/boot/progress-view.js +456 -0
  61. package/dist/guest/boot/runner.d.ts +20 -10
  62. package/dist/guest/boot/runner.js +39 -47
  63. package/dist/guest/daemon/daemon.js +3 -0
  64. package/dist/guest/runtime/log-line.d.ts +7 -0
  65. package/dist/guest/runtime/log-line.js +18 -0
  66. package/dist/guest/runtime/log.d.ts +17 -4
  67. package/dist/guest/runtime/log.js +40 -17
  68. package/dist/guest/runtime/process.d.ts +9 -0
  69. package/dist/guest/runtime/process.js +69 -8
  70. package/dist/guest/setup/addon-mcp.d.ts +7 -0
  71. package/dist/guest/setup/addon-mcp.js +19 -4
  72. package/dist/guest/setup/browser-gpu.js +14 -11
  73. package/dist/guest/setup/environment.js +9 -4
  74. package/dist/guest/setup/headroom.js +4 -0
  75. package/dist/guest/setup/hooks.d.ts +2 -0
  76. package/dist/guest/setup/hooks.js +4 -0
  77. package/dist/guest/setup/path-plan.d.ts +12 -0
  78. package/dist/guest/setup/path-plan.js +18 -0
  79. package/dist/guest/toolchains/engines/epic-launcher.d.ts +26 -0
  80. package/dist/guest/toolchains/engines/epic-launcher.js +127 -0
  81. package/dist/guest/toolchains/engines/unreal-engines.d.ts +21 -1
  82. package/dist/guest/toolchains/engines/unreal-engines.js +163 -3
  83. package/dist/guest/toolchains/engines/unreal-status.d.ts +13 -0
  84. package/dist/guest/toolchains/engines/unreal-status.js +41 -0
  85. package/dist/guest/toolchains/native/debuggers.d.ts +6 -0
  86. package/dist/guest/toolchains/native/debuggers.js +57 -0
  87. package/dist/guest/toolchains/native/mesa.js +15 -8
  88. package/dist/guest/toolchains/native/rust-extras.d.ts +7 -0
  89. package/dist/guest/toolchains/native/rust-extras.js +23 -1
  90. package/dist/guest/toolchains/native/unreal.d.ts +2 -2
  91. package/dist/guest/toolchains/native/unreal.js +96 -20
  92. package/dist/guest/toolchains/native/visual-studio.d.ts +14 -14
  93. package/dist/guest/toolchains/native/visual-studio.js +145 -174
  94. package/dist/guest/toolchains/native/vs-persist.d.ts +189 -0
  95. package/dist/guest/toolchains/native/vs-persist.js +256 -0
  96. package/dist/guest/toolchains/native/vs-request.d.ts +6 -26
  97. package/dist/guest/toolchains/native/vs-request.js +16 -50
  98. package/dist/guest/toolchains/plan.js +23 -15
  99. package/dist/guest/toolchains/tools/vscode-profile.js +2 -0
  100. package/dist/host/accounts/kinds/epic.js +11 -5
  101. package/dist/host/accounts/source.d.ts +2 -0
  102. package/dist/host/accounts/source.js +1 -0
  103. package/dist/host/migrate/migrations/drop-vs-install-files.d.ts +5 -0
  104. package/dist/host/migrate/migrations/drop-vs-install-files.js +34 -0
  105. package/dist/host/migrate/registry.js +7 -1
  106. package/dist/host/pc-installs/discover.d.ts +2 -0
  107. package/dist/host/pc-installs/discover.js +25 -5
  108. package/dist/host/pc-installs/epic.d.ts +3 -0
  109. package/dist/host/pc-installs/epic.js +33 -2
  110. package/dist/host/pc-installs/source.d.ts +1 -1
  111. package/dist/host/pc-installs/unreal-vault.d.ts +11 -0
  112. package/dist/host/pc-installs/unreal-vault.js +78 -0
  113. package/dist/host/pc-installs/unreal.d.ts +36 -0
  114. package/dist/host/pc-installs/unreal.js +145 -2
  115. package/dist/host/profile/claude-profile.d.ts +8 -0
  116. package/dist/host/profile/claude-profile.js +43 -4
  117. package/dist/host/profile/index.d.ts +1 -1
  118. package/dist/host/profile/index.js +1 -1
  119. package/dist/runtime/agent.js +148 -33
  120. package/dist/runtime/daemon.js +3146 -1546
  121. package/dist/runtime/db.js +148 -33
  122. package/dist/runtime/main.js +3982 -2049
  123. package/dist/runtime/netproxy.js +84 -13
  124. package/dist/runtime/tool.js +125 -31
  125. package/dist/runtime/view.js +85 -14
  126. package/dist/selftest/agent-paths.test.js +18 -1
  127. package/dist/selftest/agent-settings.test.js +36 -5
  128. package/dist/selftest/agents-web.test.js +12 -0
  129. package/dist/selftest/boot-console.test.d.ts +2 -0
  130. package/dist/selftest/boot-console.test.js +291 -0
  131. package/dist/selftest/boot-runner.test.js +10 -12
  132. package/dist/selftest/engines.test.js +602 -3
  133. package/dist/selftest/guest-boot.test.js +7 -1
  134. package/dist/selftest/heavy-load.test.js +3 -1
  135. package/dist/selftest/hostile-input.test.js +11 -1
  136. package/dist/selftest/index.js +4 -0
  137. package/dist/selftest/layout.test.js +4 -0
  138. package/dist/selftest/menu-screens.js +3 -1
  139. package/dist/selftest/migrate.test.js +21 -0
  140. package/dist/selftest/mixamo.test.d.ts +2 -0
  141. package/dist/selftest/mixamo.test.js +60 -0
  142. package/dist/selftest/persisted-installs.test.js +169 -33
  143. package/dist/selftest/secrets.test.js +36 -1
  144. package/dist/selftest/support/engine-golden.js +5 -0
  145. package/dist/selftest/support/fixtures.d.ts +4 -3
  146. package/dist/selftest/support/unreal-sample.d.ts +2 -0
  147. package/dist/selftest/support/unreal-sample.js +83 -0
  148. package/dist/selftest/toolchains.test.js +32 -2
  149. package/dist/shared/accounts/index.d.ts +1 -1
  150. package/dist/shared/accounts/index.js +1 -1
  151. package/dist/shared/accounts/kinds/epic.d.ts +6 -1
  152. package/dist/shared/accounts/kinds/epic.js +11 -1
  153. package/dist/shared/apps/associations.d.ts +7 -0
  154. package/dist/shared/apps/associations.js +26 -0
  155. package/dist/shared/apps/catalogue-agents-web.d.ts +4 -1
  156. package/dist/shared/apps/catalogue-agents-web.js +5 -2
  157. package/dist/shared/apps/catalogue-gamedev.js +71 -1
  158. package/dist/shared/apps/index.d.ts +2 -0
  159. package/dist/shared/apps/index.js +2 -0
  160. package/dist/shared/apps/preview.d.ts +2 -0
  161. package/dist/shared/apps/preview.js +10 -0
  162. package/dist/shared/browser-policy.d.ts +14 -0
  163. package/dist/shared/browser-policy.js +22 -0
  164. package/dist/shared/channel/schema.d.ts +3 -6
  165. package/dist/shared/io/index.d.ts +1 -0
  166. package/dist/shared/io/index.js +1 -0
  167. package/dist/shared/io/rotate-log.d.ts +2 -0
  168. package/dist/shared/io/rotate-log.js +16 -0
  169. package/dist/shared/memory/policy.d.ts +5 -0
  170. package/dist/shared/memory/policy.js +7 -0
  171. package/dist/shared/paths/pc-installs.d.ts +13 -2
  172. package/dist/shared/paths/pc-installs.js +1 -0
  173. package/dist/shared/pty/terminal.js +2 -1
  174. package/dist/shared/readiness.d.ts +0 -1
  175. package/dist/shared/readiness.js +0 -1
  176. package/dist/shared/signer.d.ts +4 -0
  177. package/dist/shared/signer.js +2 -0
  178. package/dist/shared/unreal/engines.d.ts +161 -0
  179. package/dist/shared/unreal/engines.js +308 -0
  180. package/dist/shared/unreal/guide.d.ts +19 -0
  181. package/dist/shared/unreal/guide.js +105 -0
  182. package/dist/shared/unreal/index.d.ts +7 -0
  183. package/dist/shared/unreal/index.js +8 -0
  184. package/dist/shared/unreal/launcher-files.d.ts +88 -0
  185. package/dist/shared/unreal/launcher-files.js +292 -0
  186. package/dist/shared/unreal/mixamo.d.ts +5 -0
  187. package/dist/shared/unreal/mixamo.js +16 -0
  188. package/dist/shared/unreal/room.d.ts +17 -0
  189. package/dist/shared/unreal/room.js +34 -0
  190. package/dist/shared/unreal/status.d.ts +54 -0
  191. package/dist/shared/unreal/status.js +57 -0
  192. package/dist/shared/unreal/vault.d.ts +21 -0
  193. package/dist/shared/unreal/vault.js +67 -0
  194. package/dist/shared/unreal/vs-check.d.ts +39 -0
  195. package/dist/shared/unreal/vs-check.js +79 -0
  196. package/dist/sync/watcher.js +5 -1
  197. package/dist/web/index.html +1 -1
  198. package/dist/web/{main-CCILLX2M.js → main-FNE6XEHA.js} +84 -84
  199. package/native/csharp/HcsHost/AssemblyInfo.cs +3 -3
  200. package/native/csharp/HostTools/AssemblyInfo.cs +3 -3
  201. package/native/csharp/StorageHelper/AssemblyInfo.cs +3 -3
  202. package/package.json +1 -1
  203. package/sandbox/csharp/VsSetup.cs +210 -0
  204. package/sandbox/scripts/get-vs-setup.ps1 +93 -0
  205. package/sandbox/scripts/restore-visual-studio.ps1 +78 -0
  206. package/sandbox/scripts/save-visual-studio.ps1 +106 -0
  207. package/sandbox/scripts/set-registry-values.ps1 +35 -0
  208. package/schemas/config.schema.json +38 -9
  209. package/schemas/sandbox-config.schema.json +11 -8
  210. package/dist/guest/toolchains/native/autosdk.d.ts +0 -3
  211. package/dist/guest/toolchains/native/autosdk.js +0 -50
@@ -1,5 +1,13 @@
1
1
  import type { ClaudeProfileConfig, ProfileResult } from '../../core/types.js';
2
2
  import { type SecretsConfig } from './secrets.js';
3
+ /**
4
+ * Which parts of your plugins folder are staged, as a filter over full paths. Everything Claude needs to load a plugin
5
+ * (installed_plugins.json, marketplaces, the plugin cache) is kept; when that is over the size cap, git history
6
+ * (`.git`) and then `node_modules` are left out, and the guest's plugins restore what they need on first use.
7
+ */
8
+ export declare function pluginFilter(source: string, level: 0 | 1 | 2): (full: string) => boolean;
9
+ /** The least trimmed level at which the plugins folder fits the cap, or null when even the most trimmed does not. */
10
+ export declare function pluginTrimLevel(source: string): 0 | 1 | 2 | null;
3
11
  export declare function hostClaudeDir(settings: ClaudeProfileConfig): string;
4
12
  export declare function hostGlobalStateFile(settings: ClaudeProfileConfig): string;
5
13
  /**
@@ -5,17 +5,54 @@ import { dirExists, ensureDir, fileExists, homeDir, isLink, readJson, writeJson
5
5
  import { stripMcpServers, stripSettings } from './secrets.js';
6
6
  const MAX_BYTES = 250 * 1024 * 1024;
7
7
  /** Real files only: a link inside ~/.claude (even a loop or a dead one) is neither followed nor counted nor copied. */
8
- function directorySize(dir) {
8
+ function directorySize(dir, keep = () => true) {
9
9
  let total = 0;
10
10
  for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
11
11
  const full = path.join(dir, entry.name);
12
+ if (!keep(full))
13
+ continue;
12
14
  if (entry.isDirectory())
13
- total += directorySize(full);
15
+ total += directorySize(full, keep);
14
16
  else if (entry.isFile())
15
17
  total += fs.statSync(full).size;
16
18
  }
17
19
  return total;
18
20
  }
21
+ /** Plugin leftovers Claude never reads: interrupted clones (temp_*) and marketplace backups. */
22
+ function isPluginJunk(parts) {
23
+ const top = parts[0]?.toLowerCase();
24
+ const name = parts[1]?.toLowerCase() ?? '';
25
+ return (parts.length >= 2 &&
26
+ (top === 'cache' || top === 'marketplaces') &&
27
+ (name.startsWith('temp_') || name.endsWith('.backup') || name.endsWith('.staging')));
28
+ }
29
+ /**
30
+ * Which parts of your plugins folder are staged, as a filter over full paths. Everything Claude needs to load a plugin
31
+ * (installed_plugins.json, marketplaces, the plugin cache) is kept; when that is over the size cap, git history
32
+ * (`.git`) and then `node_modules` are left out, and the guest's plugins restore what they need on first use.
33
+ */
34
+ export function pluginFilter(source, level) {
35
+ return (full) => {
36
+ if (full === source)
37
+ return true;
38
+ const parts = path.relative(source, full).split(path.sep);
39
+ if (isPluginJunk(parts))
40
+ return false;
41
+ if (level >= 1 && parts.includes('.git'))
42
+ return false;
43
+ if (level >= 2 && parts.includes('node_modules'))
44
+ return false;
45
+ return true;
46
+ };
47
+ }
48
+ /** The least trimmed level at which the plugins folder fits the cap, or null when even the most trimmed does not. */
49
+ export function pluginTrimLevel(source) {
50
+ for (const level of [0, 1, 2]) {
51
+ if (directorySize(source, pluginFilter(source, level)) <= MAX_BYTES)
52
+ return level;
53
+ }
54
+ return null;
55
+ }
19
56
  function validJson(file) {
20
57
  try {
21
58
  JSON.parse(fs.readFileSync(file, 'utf8').replace(/^\uFEFF/, ''));
@@ -84,14 +121,16 @@ export function stageClaudeProfile(settings, launchPath, workspaceHost, secrets)
84
121
  fs.copyFileSync(source, destination);
85
122
  }
86
123
  else if (dirExists(source)) {
87
- if (directorySize(source) > MAX_BYTES) {
124
+ const level = name === 'plugins' ? pluginTrimLevel(source) : directorySize(source) > MAX_BYTES ? null : 0;
125
+ if (level === null) {
88
126
  result.skipped.push(name + ' (over 250 MB)');
89
127
  continue;
90
128
  }
129
+ const keep = name === 'plugins' ? pluginFilter(source, level) : () => true;
91
130
  fs.cpSync(source, destination, {
92
131
  recursive: true,
93
132
  force: true,
94
- filter: (from) => from === source || !isLink(from),
133
+ filter: (from) => from === source || (!isLink(from) && keep(from)),
95
134
  });
96
135
  }
97
136
  else {
@@ -1,6 +1,6 @@
1
1
  export { isSecretName, isSecretValue, mayPass, stripMcpServers, stripSettings, stripVariables, type SecretsConfig, } from './secrets.js';
2
2
  export { findSecretFiles } from './secret-files.js';
3
- export { hostClaudeDir, hostGlobalStateFile, sandboxGlobalState, stageClaudeProfile } from './claude-profile.js';
3
+ export { hostClaudeDir, hostGlobalStateFile, pluginFilter, pluginTrimLevel, sandboxGlobalState, stageClaudeProfile, } from './claude-profile.js';
4
4
  export { capturePersonalization } from './personalize.js';
5
5
  export { toRegFile, type RegValue } from './reg-file.js';
6
6
  export { AccountStore, accountsDir, type Account, type AccountMeta, type AccountRow } from './accounts.js';
@@ -1,6 +1,6 @@
1
1
  export { isSecretName, isSecretValue, mayPass, stripMcpServers, stripSettings, stripVariables, } from './secrets.js';
2
2
  export { findSecretFiles } from './secret-files.js';
3
- export { hostClaudeDir, hostGlobalStateFile, sandboxGlobalState, stageClaudeProfile } from './claude-profile.js';
3
+ export { hostClaudeDir, hostGlobalStateFile, pluginFilter, pluginTrimLevel, sandboxGlobalState, stageClaudeProfile, } from './claude-profile.js';
4
4
  export { capturePersonalization } from './personalize.js';
5
5
  export { toRegFile } from './reg-file.js';
6
6
  export { AccountStore, accountsDir } from './accounts.js';
@@ -25650,7 +25650,7 @@ var ToolchainsSchema = external_exports.strictObject({
25650
25650
  `"auto" (default): on the sandbox's own disk when C: has 25 GB free at boot, else "separate" (builds then write through the mapped workspace, which can overload this PC's disk). "shared": cargo's default target\\ (shared with builds on this PC, so builds on either side invalidate the other), "separate": <workspace>\\target\\sandbox (kept, no cross-talk), "local": on the sandbox's own disk (fastest, lost every boot), or a guest path.`
25651
25651
  ),
25652
25652
  linker: external_exports.enum(["lld", "gnu"]).describe(
25653
- `GNU host: "lld" links with Rust's own lld through MinGW's gcc (much less memory than GNU ld), "gnu" with GNU ld.`
25653
+ `"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.`
25654
25654
  ),
25655
25655
  linkSlots: external_exports.union([external_exports.literal("auto"), external_exports.number().int().min(1).max(32)]).describe(
25656
25656
  'GNU host: how many programs may link at the same time in the whole sandbox (other links wait). "auto" = one per 6 GB of sandbox memory, 1 to 4 (the memory governor slows links down too when memory runs short).'
@@ -25669,7 +25669,7 @@ var ToolchainsSchema = external_exports.strictObject({
25669
25669
  }),
25670
25670
  unreal: external_exports.strictObject({
25671
25671
  enabled: enabled(
25672
- "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.",
25672
+ "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. Visual Studio is installed once and kept on the data disk (~6.5 GB); later boots put it back in seconds. The engine itself comes from the Epic Games Launcher or its source.",
25673
25673
  "a .uproject or .uplugin"
25674
25674
  ),
25675
25675
  acceptLicense: external_exports.boolean().describe(
@@ -25678,11 +25678,8 @@ var ToolchainsSchema = external_exports.strictObject({
25678
25678
  components: StringsSchema.describe(
25679
25679
  'More Visual Studio workload or component IDs to add, e.g. ["Microsoft.VisualStudio.Component.VC.Llvm.Clang"].'
25680
25680
  ),
25681
- keepInstallFiles: external_exports.boolean().describe(
25682
- "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."
25683
- ),
25684
- visualStudio: external_exports.enum(["full", "autosdk"]).describe(
25685
- `"full": install Visual Studio Community (the engine finds it through the Setup API; ~10 GB, redone every boot). "autosdk" (experimental): skip Visual Studio and build an Unreal AutoSDK tree from the portable MSVC in tools\\unreal\\autosdk (kept between sandboxes); UnrealBuildTool finds MSVC through AutoSDK, but the editor's Visual Studio integration is not available. Needs toolchains.msvc (turned on for you).`
25681
+ visualStudio: external_exports.enum(["full", "buildtools"]).describe(
25682
+ '"full": Visual Studio Community with the C++ game workload (the IDE, its debugger and Unreal integration). "buildtools": only the Visual Studio Build Tools (MSVC, the Windows SDK and the .NET Framework parts UnrealBuildTool needs; no IDE). Either is installed once and kept on the data disk (tools\\visualstudio\\persist, ~6.5 GB for Community); later boots put it back in seconds.'
25686
25683
  ),
25687
25684
  persistEngines: external_exports.boolean().describe(
25688
25685
  "Engines the Epic Games Launcher installs go to tools\\unreal\\engines (kept between sandboxes, 40-60 GB each) and are registered with the launcher again every boot. Off: they go on the sandbox disk and are lost when it closes. Engines installed on this PC can be mapped instead (pcInstalls.unrealEngines)."
@@ -25911,7 +25908,7 @@ var CHROME_DEVTOOLS_MCP_VERSION = "1.12.0";
25911
25908
  var BROWSER_USE_VERSION = "0.13.14";
25912
25909
  var PERPLEXITY_COMPUTER_MCP_URL = "https://www.perplexity.ai/rest/computer/mcp";
25913
25910
  var COMET_SIGNER = {
25914
- subject: ['^CN="?PERPLEXITY AI, INC\\.?"?(,|$)', '(^|, )O="?PERPLEXITY AI, INC\\.?"?(,|$)'],
25911
+ subject: ['(^|, )CN="?PERPLEXITY AI, INC\\.?"?(,|$)', '(^|, )O="?PERPLEXITY AI, INC\\.?"?(,|$)'],
25915
25912
  issuer: ["^CN=GlobalSign GCC R45 EV CodeSigning CA 2020(,|$)"]
25916
25913
  };
25917
25914
  var EDGE_EXE = "C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe";
@@ -26013,7 +26010,77 @@ var AGENTS_WEB_APPS = [
26013
26010
  ];
26014
26011
 
26015
26012
  // src/shared/apps/catalogue-gamedev.ts
26016
- var GAMEDEV_APPS = [];
26013
+ var GAMEDEV_APPS = [
26014
+ {
26015
+ id: "krita",
26016
+ name: "Krita",
26017
+ category: "gamedev",
26018
+ about: "Painting and texture editor (PSD, layers, brushes), checked against the SHA-256 download.kde.org publishes.",
26019
+ size: "450 MB",
26020
+ source: { resolve: "krita" },
26021
+ exe: "krita.exe",
26022
+ needs: ["mesa"]
26023
+ },
26024
+ {
26025
+ id: "inkscape",
26026
+ name: "Inkscape",
26027
+ category: "gamedev",
26028
+ about: "Vector graphics for UI, icons and 2D art (SVG), checked against the SHA-256 inkscape.org publishes.",
26029
+ size: "400 MB",
26030
+ source: { resolve: "inkscape" },
26031
+ exe: "inkscape.exe",
26032
+ needs: ["7zip"]
26033
+ },
26034
+ {
26035
+ id: "audacity",
26036
+ name: "Audacity",
26037
+ category: "gamedev",
26038
+ about: "Records and edits sound effects and music (WAV, OGG, FLAC).",
26039
+ size: "80 MB",
26040
+ source: { github: "audacity/audacity", asset: "^audacity-win-[\\d.]+-(?:64bit\\.zip|x86_64\\.7z)$" },
26041
+ exe: "Audacity.exe",
26042
+ needs: ["7zip"]
26043
+ },
26044
+ {
26045
+ id: "renderdoc",
26046
+ name: "RenderDoc",
26047
+ category: "gamedev",
26048
+ about: "Captures a frame of a game (Unreal's -d3d12/-vulkan builds) to inspect every draw call, texture and shader. Needs the sandbox's GPU (vGPU) for live captures.",
26049
+ size: "70 MB",
26050
+ source: { resolve: "renderdoc" },
26051
+ exe: "qrenderdoc.exe"
26052
+ },
26053
+ {
26054
+ id: "f3d",
26055
+ name: "F3D",
26056
+ category: "gamedev",
26057
+ about: "Fast 3D viewer (FBX, glTF/GLB, OBJ, STL, PLY, 3DS, USD); renders still previews from the command line.",
26058
+ size: "100 MB",
26059
+ source: { github: "f3d-app/f3d", asset: "^F3D-[\\d.]+-Windows-x86_64\\.zip$" },
26060
+ exe: "f3d.exe",
26061
+ needs: ["mesa"]
26062
+ },
26063
+ {
26064
+ id: "imagemagick",
26065
+ name: "ImageMagick",
26066
+ category: "gamedev",
26067
+ about: "Converts and thumbnails textures (TGA, PSD, DDS, EXR, HDR) and builds contact sheets (magick montage).",
26068
+ size: "150 MB",
26069
+ source: { github: "ImageMagick/ImageMagick", asset: "^ImageMagick-[\\d.]+-\\d+-portable-Q16-HDRI-x64\\.7z$" },
26070
+ exe: "magick.exe",
26071
+ cli: true,
26072
+ needs: ["7zip"]
26073
+ },
26074
+ {
26075
+ id: "nomacs",
26076
+ name: "nomacs",
26077
+ category: "gamedev",
26078
+ about: "Image viewer for textures (TGA, PSD, DDS, EXR).",
26079
+ size: "60 MB",
26080
+ source: { github: "nomacs/nomacs", asset: "^nomacs-portable-win\\.zip$" },
26081
+ exe: "nomacs.exe"
26082
+ }
26083
+ ];
26017
26084
 
26018
26085
  // src/shared/apps/catalogue-mobile.ts
26019
26086
  var MOBILE_APPS = [];
@@ -27242,10 +27309,14 @@ var PcInstallsSchema = external_exports.strictObject({
27242
27309
  "Epic Games Launcher games (by their app name)",
27243
27310
  '["Fortnite"]'
27244
27311
  ),
27245
- unrealEngines: pick2(
27246
- external_exports.string().regex(/^(UE_)?\d+\.\d+$/),
27247
- "Unreal Engine versions installed with the Epic Games Launcher",
27248
- '["5.4"]'
27312
+ unrealEngines: external_exports.union([external_exports.literal("auto"), external_exports.boolean(), external_exports.array(external_exports.string().regex(/^(UE_)?\d+\.\d+$/))]).describe(
27313
+ '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"]).'
27314
+ ),
27315
+ unrealEngineFolders: external_exports.array(external_exports.string().min(3).max(260)).max(8).describe(
27316
+ "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."
27317
+ ),
27318
+ unrealAssets: external_exports.union([external_exports.literal("auto"), external_exports.boolean()]).describe(
27319
+ `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.`
27249
27320
  ),
27250
27321
  unityEditors: pick2(
27251
27322
  external_exports.string().regex(/^\d+\.\d+\.\d+[abfp]\d+$/),
@@ -27852,36 +27923,45 @@ function mkdirp(p) {
27852
27923
  import fs6 from "node:fs";
27853
27924
  import path7 from "node:path";
27854
27925
  import { AsyncLocalStorage } from "node:async_hooks";
27926
+
27927
+ // src/guest/runtime/log-line.ts
27928
+ var ESCAPES = /\x1b\[[0-9;?]{0,32}[A-Za-z]/g;
27929
+ function plainText(text) {
27930
+ return text.replace(ESCAPES, "");
27931
+ }
27932
+ function fileLines(message, at = /* @__PURE__ */ new Date(), task) {
27933
+ const stamp = at.toISOString() + " " + (task ? "[" + task + "] " : "");
27934
+ return plainText(message).split(/\r?\n/).filter((line) => line.trim() !== "").map((line) => stamp + line.trimEnd());
27935
+ }
27936
+
27937
+ // src/guest/runtime/log.ts
27855
27938
  fs6.mkdirSync(logsDir, { recursive: true });
27856
27939
  var logFile = path7.join(
27857
27940
  logsDir,
27858
27941
  (process.env.AGENT_LOG_PREFIX ?? "guest") + "-" + (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-") + ".log"
27859
27942
  );
27860
27943
  var context = new AsyncLocalStorage();
27861
- function fileLine(message, at = /* @__PURE__ */ new Date()) {
27862
- return at.toISOString() + " " + message;
27863
- }
27864
- var append = (line) => {
27944
+ var sink = null;
27945
+ var append = (message, ctx) => {
27865
27946
  try {
27866
- fs6.appendFileSync(logFile, fileLine(line) + "\n");
27947
+ const lines = fileLines(message, /* @__PURE__ */ new Date(), ctx?.task);
27948
+ if (lines.length) fs6.appendFileSync(logFile, lines.join("\n") + "\n");
27867
27949
  } catch {
27868
27950
  }
27869
27951
  };
27870
- var tagged = (message, ctx) => {
27871
- const prefix = ctx?.prefix?.();
27872
- return prefix ? prefix + " | " + message : message;
27873
- };
27874
27952
  function log(message) {
27875
27953
  const ctx = context.getStore();
27876
- const line = tagged(message, ctx);
27877
- if (!ctx?.quiet) console.log(line);
27878
- append(line);
27954
+ append(message, ctx);
27955
+ if (ctx?.quiet) return;
27956
+ if (sink) sink.line(message, ctx?.stage);
27957
+ else console.log(message);
27879
27958
  }
27880
27959
  function warn(message) {
27881
27960
  const ctx = context.getStore();
27882
- const line = tagged(message, ctx);
27883
- if (!ctx?.quiet) console.warn("\x1B[33mWARNING: " + line + "\x1B[0m");
27884
- append("WARNING: " + line);
27961
+ append("WARNING: " + message, ctx);
27962
+ if (ctx?.quiet) return;
27963
+ if (sink) sink.warning(message);
27964
+ else console.warn("\x1B[33mWARNING: " + message + "\x1B[0m");
27885
27965
  }
27886
27966
 
27887
27967
  // src/guest/toolchains/tool-env.ts
@@ -28177,24 +28257,56 @@ var githubAssetFromPage = async (repo, pattern, searchOlder) => {
28177
28257
  };
28178
28258
 
28179
28259
  // src/guest/runtime/process.ts
28260
+ var outputSink = null;
28261
+ var captureOutput = () => outputSink?.capturing() ?? false;
28262
+ function logOutput(text) {
28263
+ for (const line of text.split(/\r?\n/)) if (line.trim()) outputSink?.line(line.trimEnd());
28264
+ }
28265
+ var CAPTURE_BYTES = 64 * 1024 * 1024;
28266
+ var LINE_CHARS = 2e3;
28267
+ function logLines(stream) {
28268
+ if (!stream) return;
28269
+ let partial2 = "";
28270
+ stream.setEncoding("utf8");
28271
+ stream.on("data", (chunk) => {
28272
+ const lines = (partial2 + chunk).split(/\r?\n/);
28273
+ partial2 = lines.pop().slice(0, LINE_CHARS);
28274
+ logOutput(lines.map((l) => l.slice(0, LINE_CHARS)).join("\n"));
28275
+ });
28276
+ stream.on("end", () => logOutput(partial2));
28277
+ }
28180
28278
  async function execAsync(file2, args, options = {}) {
28181
- const code = await spawnAsync(file2, args, { stdio: "inherit", ...options });
28279
+ const code = captureOutput() ? await new Promise((resolve, reject) => {
28280
+ const child = spawn2(file2, args, { stdio: ["inherit", "pipe", "pipe"], windowsHide: true, ...options });
28281
+ logLines(child.stdout);
28282
+ logLines(child.stderr);
28283
+ child.once("error", reject);
28284
+ child.once("close", (c) => resolve(c ?? -1));
28285
+ }) : await spawnAsync(file2, args, { stdio: "inherit", ...options });
28182
28286
  if (code !== 0)
28183
28287
  throw new Error(path11.basename(file2) + " " + args.slice(0, 3).join(" ") + " failed with exit code " + code);
28184
28288
  }
28289
+ function scriptErrors(errors) {
28290
+ if (!errors) return;
28291
+ if (captureOutput()) logOutput(errors);
28292
+ else process.stderr.write(errors + "\n");
28293
+ }
28185
28294
  function execOutput(file2, args, options = {}) {
28186
28295
  const result = spawnSync(file2, args, { encoding: "utf8", windowsHide: true, ...options });
28187
28296
  return result.status === 0 ? String(result.stdout ?? "").trim() : "";
28188
28297
  }
28189
28298
  function runScript(name, args = []) {
28299
+ const capture = captureOutput();
28190
28300
  const result = spawnSync(SYSTEM.powershell(), scriptArgs(name, args), {
28191
- stdio: ["inherit", "inherit", "pipe"],
28301
+ stdio: ["inherit", capture ? "pipe" : "inherit", "pipe"],
28192
28302
  encoding: "utf8",
28193
- windowsHide: true
28303
+ windowsHide: true,
28304
+ ...capture ? { maxBuffer: CAPTURE_BYTES } : {}
28194
28305
  });
28306
+ if (capture) logOutput(String(result.stdout ?? ""));
28195
28307
  if (result.error) throw result.error;
28196
28308
  const errors = String(result.stderr ?? "").trim();
28197
- if (errors) process.stderr.write(errors + "\n");
28309
+ scriptErrors(errors);
28198
28310
  if (result.status !== 0)
28199
28311
  throw new Error(name + " failed with exit code " + result.status + (errors ? ": " + errors.slice(0, 400) : ""));
28200
28312
  }
@@ -28381,9 +28493,12 @@ function agentCommand(name, harness) {
28381
28493
  return harness.npmBin ?? harness.uvBin ?? (harness.hostExecutable ?? name).replace(/\.exe$/i, "");
28382
28494
  }
28383
28495
  var CODEX_MARKER = "# Set by the sandbox";
28496
+ var CODEX_MARKER_LINE = CODEX_MARKER + " from its codex settings (`sandbox config`); a line of your own without it wins.";
28497
+ var CODEX_MARKERS = [CODEX_MARKER, "# agent-sandbox:"];
28498
+ var CODEX_OWNED_KEYS = ["sandbox_mode", "approval_policy", "model", "model_reasoning_effort"];
28384
28499
  var MAX_CODEX_CONFIG_BYTES = 1024 * 1024;
28385
28500
  var MARKED_LINES = new RegExp(
28386
- "^" + CODEX_MARKER + "[^\r\n]*\r?\n(?:(?:sandbox_mode|approval_policy)[ ]*=[^\r\n]*\r?\n)*(?:[ ]*\r?\n)?",
28501
+ "^(?:" + CODEX_MARKERS.join("|") + ")[^\r\n]*\r?\n(?:(?:" + CODEX_OWNED_KEYS.join("|") + ")[ ]*=[^\r\n]*(?:\r?\n|$))*(?:[ ]*\r?\n)?",
28387
28502
  "m"
28388
28503
  );
28389
28504