windows-development-sandbox 1.23.2 → 1.25.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 (85) hide show
  1. package/config.example.json +0 -1
  2. package/dist/bin/agent-sandbox.js +2 -2
  3. package/dist/bin/{chunk-USTRSHIE.js → chunk-IZRGTSQ5.js} +158 -131
  4. package/dist/bin/{chunk-QFSJX2KW.js → chunk-KH4MI2U5.js} +1 -1
  5. package/dist/bin/{chunk-7YPEDAJD.js → chunk-SUYYVIDW.js} +1 -1
  6. package/dist/bin/claude-host.js +2 -2
  7. package/dist/bin/claude-sbx.js +2 -2
  8. package/dist/bin/codex-sbx.js +2 -2
  9. package/dist/bin/gemini-sbx.js +2 -2
  10. package/dist/bin/sandbox.js +2 -2
  11. package/dist/bin/sbx-hide.js +2 -2
  12. package/dist/bin/sbx-show.js +2 -2
  13. package/dist/core/config/defaults.js +0 -1
  14. package/dist/core/detect/toolchains.js +0 -6
  15. package/dist/core/schema/config.d.ts +1 -2
  16. package/dist/core/schema/toolchains.d.ts +1 -2
  17. package/dist/core/schema/toolchains.js +3 -6
  18. package/dist/guest/agents/agent-files.d.ts +11 -7
  19. package/dist/guest/agents/agent-files.js +37 -11
  20. package/dist/guest/agents/local-state.d.ts +2 -1
  21. package/dist/guest/agents/local-state.js +2 -1
  22. package/dist/guest/boot/boot-console.d.ts +28 -0
  23. package/dist/guest/boot/boot-console.js +98 -0
  24. package/dist/guest/boot/boot.d.ts +8 -1
  25. package/dist/guest/boot/boot.js +66 -42
  26. package/dist/guest/boot/graph.d.ts +9 -5
  27. package/dist/guest/boot/graph.js +8 -2
  28. package/dist/guest/boot/progress-view.d.ts +116 -0
  29. package/dist/guest/boot/progress-view.js +456 -0
  30. package/dist/guest/boot/runner.d.ts +20 -10
  31. package/dist/guest/boot/runner.js +39 -47
  32. package/dist/guest/runtime/log-line.d.ts +7 -0
  33. package/dist/guest/runtime/log-line.js +18 -0
  34. package/dist/guest/runtime/log.d.ts +17 -4
  35. package/dist/guest/runtime/log.js +40 -17
  36. package/dist/guest/runtime/process.d.ts +9 -0
  37. package/dist/guest/runtime/process.js +69 -8
  38. package/dist/guest/setup/environment.js +9 -4
  39. package/dist/guest/setup/hooks.d.ts +2 -0
  40. package/dist/guest/setup/hooks.js +4 -0
  41. package/dist/guest/setup/path-plan.d.ts +12 -0
  42. package/dist/guest/setup/path-plan.js +18 -0
  43. package/dist/guest/toolchains/native/unreal.js +4 -6
  44. package/dist/guest/toolchains/native/visual-studio.d.ts +14 -14
  45. package/dist/guest/toolchains/native/visual-studio.js +145 -174
  46. package/dist/guest/toolchains/native/vs-persist.d.ts +189 -0
  47. package/dist/guest/toolchains/native/vs-persist.js +256 -0
  48. package/dist/guest/toolchains/native/vs-request.d.ts +6 -26
  49. package/dist/guest/toolchains/native/vs-request.js +16 -50
  50. package/dist/guest/toolchains/plan.js +11 -14
  51. package/dist/host/migrate/migrations/drop-vs-install-files.d.ts +5 -0
  52. package/dist/host/migrate/migrations/drop-vs-install-files.js +34 -0
  53. package/dist/host/migrate/registry.js +7 -1
  54. package/dist/runtime/agent.js +67 -26
  55. package/dist/runtime/daemon.js +958 -716
  56. package/dist/runtime/db.js +67 -26
  57. package/dist/runtime/main.js +1792 -1038
  58. package/dist/runtime/netproxy.js +3 -6
  59. package/dist/runtime/tool.js +44 -24
  60. package/dist/runtime/view.js +4 -7
  61. package/dist/selftest/agent-paths.test.js +17 -1
  62. package/dist/selftest/agent-settings.test.js +36 -5
  63. package/dist/selftest/boot-console.test.d.ts +2 -0
  64. package/dist/selftest/boot-console.test.js +291 -0
  65. package/dist/selftest/boot-runner.test.js +10 -12
  66. package/dist/selftest/guest-boot.test.js +7 -1
  67. package/dist/selftest/index.js +2 -0
  68. package/dist/selftest/layout.test.js +4 -0
  69. package/dist/selftest/migrate.test.js +21 -0
  70. package/dist/selftest/persisted-installs.test.js +169 -33
  71. package/dist/selftest/support/engine-golden.js +2 -0
  72. package/dist/selftest/support/fixtures.d.ts +1 -2
  73. package/dist/shared/channel/schema.d.ts +3 -6
  74. package/dist/shared/pty/terminal.js +2 -1
  75. package/dist/sync/watcher.js +5 -1
  76. package/native/csharp/HcsHost/AssemblyInfo.cs +3 -3
  77. package/native/csharp/HostTools/AssemblyInfo.cs +3 -3
  78. package/native/csharp/StorageHelper/AssemblyInfo.cs +3 -3
  79. package/package.json +1 -1
  80. package/sandbox/scripts/restore-visual-studio.ps1 +78 -0
  81. package/sandbox/scripts/save-visual-studio.ps1 +106 -0
  82. package/schemas/config.schema.json +3 -7
  83. package/schemas/sandbox-config.schema.json +3 -7
  84. package/dist/guest/toolchains/native/autosdk.d.ts +0 -3
  85. package/dist/guest/toolchains/native/autosdk.js +0 -50
@@ -25645,7 +25645,7 @@ var ToolchainsSchema = external_exports.strictObject({
25645
25645
  }),
25646
25646
  unreal: external_exports.strictObject({
25647
25647
  enabled: enabled(
25648
- "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.",
25648
+ "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.",
25649
25649
  "a .uproject or .uplugin"
25650
25650
  ),
25651
25651
  acceptLicense: external_exports.boolean().describe(
@@ -25654,11 +25654,8 @@ var ToolchainsSchema = external_exports.strictObject({
25654
25654
  components: StringsSchema.describe(
25655
25655
  'More Visual Studio workload or component IDs to add, e.g. ["Microsoft.VisualStudio.Component.VC.Llvm.Clang"].'
25656
25656
  ),
25657
- keepInstallFiles: external_exports.boolean().describe(
25658
- "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."
25659
- ),
25660
- visualStudio: external_exports.enum(["full", "autosdk"]).describe(
25661
- `"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).`
25657
+ visualStudio: external_exports.enum(["full", "buildtools"]).describe(
25658
+ '"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.'
25662
25659
  ),
25663
25660
  persistEngines: external_exports.boolean().describe(
25664
25661
  "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)."
@@ -27880,36 +27877,45 @@ var run = new RunDir(dataDir);
27880
27877
  import fs5 from "node:fs";
27881
27878
  import path7 from "node:path";
27882
27879
  import { AsyncLocalStorage } from "node:async_hooks";
27880
+
27881
+ // src/guest/runtime/log-line.ts
27882
+ var ESCAPES = /\x1b\[[0-9;?]{0,32}[A-Za-z]/g;
27883
+ function plainText(text) {
27884
+ return text.replace(ESCAPES, "");
27885
+ }
27886
+ function fileLines(message, at = /* @__PURE__ */ new Date(), task) {
27887
+ const stamp = at.toISOString() + " " + (task ? "[" + task + "] " : "");
27888
+ return plainText(message).split(/\r?\n/).filter((line) => line.trim() !== "").map((line) => stamp + line.trimEnd());
27889
+ }
27890
+
27891
+ // src/guest/runtime/log.ts
27883
27892
  fs5.mkdirSync(logsDir, { recursive: true });
27884
27893
  var logFile = path7.join(
27885
27894
  logsDir,
27886
27895
  (process.env.AGENT_LOG_PREFIX ?? "guest") + "-" + (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-") + ".log"
27887
27896
  );
27888
27897
  var context = new AsyncLocalStorage();
27889
- function fileLine(message, at = /* @__PURE__ */ new Date()) {
27890
- return at.toISOString() + " " + message;
27891
- }
27892
- var append = (line) => {
27898
+ var sink = null;
27899
+ var append = (message, ctx) => {
27893
27900
  try {
27894
- fs5.appendFileSync(logFile, fileLine(line) + "\n");
27901
+ const lines = fileLines(message, /* @__PURE__ */ new Date(), ctx?.task);
27902
+ if (lines.length) fs5.appendFileSync(logFile, lines.join("\n") + "\n");
27895
27903
  } catch {
27896
27904
  }
27897
27905
  };
27898
- var tagged = (message, ctx) => {
27899
- const prefix = ctx?.prefix?.();
27900
- return prefix ? prefix + " | " + message : message;
27901
- };
27902
27906
  function log(message) {
27903
27907
  const ctx = context.getStore();
27904
- const line = tagged(message, ctx);
27905
- if (!ctx?.quiet) console.log(line);
27906
- append(line);
27908
+ append(message, ctx);
27909
+ if (ctx?.quiet) return;
27910
+ if (sink) sink.line(message, ctx?.stage);
27911
+ else console.log(message);
27907
27912
  }
27908
27913
  function warn(message) {
27909
27914
  const ctx = context.getStore();
27910
- const line = tagged(message, ctx);
27911
- if (!ctx?.quiet) console.warn("\x1B[33mWARNING: " + line + "\x1B[0m");
27912
- append("WARNING: " + line);
27915
+ append("WARNING: " + message, ctx);
27916
+ if (ctx?.quiet) return;
27917
+ if (sink) sink.warning(message);
27918
+ else console.warn("\x1B[33mWARNING: " + message + "\x1B[0m");
27913
27919
  }
27914
27920
 
27915
27921
  // src/guest/runtime/project-context.ts
@@ -28257,20 +28263,52 @@ import fs10 from "node:fs";
28257
28263
  import os3 from "node:os";
28258
28264
  import path12 from "node:path";
28259
28265
  import { spawn as spawn2, spawnSync as spawnSync2 } from "node:child_process";
28266
+ var outputSink = null;
28267
+ var captureOutput = () => outputSink?.capturing() ?? false;
28268
+ function logOutput(text) {
28269
+ for (const line of text.split(/\r?\n/)) if (line.trim()) outputSink?.line(line.trimEnd());
28270
+ }
28271
+ var CAPTURE_BYTES = 64 * 1024 * 1024;
28272
+ var LINE_CHARS = 2e3;
28273
+ function logLines(stream) {
28274
+ if (!stream) return;
28275
+ let partial2 = "";
28276
+ stream.setEncoding("utf8");
28277
+ stream.on("data", (chunk) => {
28278
+ const lines = (partial2 + chunk).split(/\r?\n/);
28279
+ partial2 = lines.pop().slice(0, LINE_CHARS);
28280
+ logOutput(lines.map((l) => l.slice(0, LINE_CHARS)).join("\n"));
28281
+ });
28282
+ stream.on("end", () => logOutput(partial2));
28283
+ }
28260
28284
  async function execAsync(file2, args, options = {}) {
28261
- const code = await spawnAsync(file2, args, { stdio: "inherit", ...options });
28285
+ const code = captureOutput() ? await new Promise((resolve, reject) => {
28286
+ const child = spawn2(file2, args, { stdio: ["inherit", "pipe", "pipe"], windowsHide: true, ...options });
28287
+ logLines(child.stdout);
28288
+ logLines(child.stderr);
28289
+ child.once("error", reject);
28290
+ child.once("close", (c) => resolve(c ?? -1));
28291
+ }) : await spawnAsync(file2, args, { stdio: "inherit", ...options });
28262
28292
  if (code !== 0)
28263
28293
  throw new Error(path12.basename(file2) + " " + args.slice(0, 3).join(" ") + " failed with exit code " + code);
28264
28294
  }
28295
+ function scriptErrors(errors) {
28296
+ if (!errors) return;
28297
+ if (captureOutput()) logOutput(errors);
28298
+ else process.stderr.write(errors + "\n");
28299
+ }
28265
28300
  function runScript(name, args = []) {
28301
+ const capture = captureOutput();
28266
28302
  const result = spawnSync2(SYSTEM.powershell(), scriptArgs(name, args), {
28267
- stdio: ["inherit", "inherit", "pipe"],
28303
+ stdio: ["inherit", capture ? "pipe" : "inherit", "pipe"],
28268
28304
  encoding: "utf8",
28269
- windowsHide: true
28305
+ windowsHide: true,
28306
+ ...capture ? { maxBuffer: CAPTURE_BYTES } : {}
28270
28307
  });
28308
+ if (capture) logOutput(String(result.stdout ?? ""));
28271
28309
  if (result.error) throw result.error;
28272
28310
  const errors = String(result.stderr ?? "").trim();
28273
- if (errors) process.stderr.write(errors + "\n");
28311
+ scriptErrors(errors);
28274
28312
  if (result.status !== 0)
28275
28313
  throw new Error(name + " failed with exit code " + result.status + (errors ? ": " + errors.slice(0, 400) : ""));
28276
28314
  }
@@ -28892,9 +28930,12 @@ import path23 from "node:path";
28892
28930
 
28893
28931
  // src/guest/agents/agent-files.ts
28894
28932
  var CODEX_MARKER = "# Set by the sandbox";
28933
+ var CODEX_MARKER_LINE = CODEX_MARKER + " from its codex settings (`sandbox config`); a line of your own without it wins.";
28934
+ var CODEX_MARKERS = [CODEX_MARKER, "# agent-sandbox:"];
28935
+ var CODEX_OWNED_KEYS = ["sandbox_mode", "approval_policy", "model", "model_reasoning_effort"];
28895
28936
  var MAX_CODEX_CONFIG_BYTES = 1024 * 1024;
28896
28937
  var MARKED_LINES = new RegExp(
28897
- "^" + CODEX_MARKER + "[^\r\n]*\r?\n(?:(?:sandbox_mode|approval_policy)[ ]*=[^\r\n]*\r?\n)*(?:[ ]*\r?\n)?",
28938
+ "^(?:" + CODEX_MARKERS.join("|") + ")[^\r\n]*\r?\n(?:(?:" + CODEX_OWNED_KEYS.join("|") + ")[ ]*=[^\r\n]*(?:\r?\n|$))*(?:[ ]*\r?\n)?",
28898
28939
  "m"
28899
28940
  );
28900
28941