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
@@ -12169,7 +12169,7 @@ var require_lodash = __commonJS({
12169
12169
  return string4.match(reUnicodeWord) || [];
12170
12170
  }
12171
12171
  var runInContext = (function runInContext2(context) {
12172
- context = context == null ? root : _38.defaults(root.Object(), context, _38.pick(root, contextProps));
12172
+ context = context == null ? root : _39.defaults(root.Object(), context, _39.pick(root, contextProps));
12173
12173
  var Array2 = context.Array, Date2 = context.Date, Error2 = context.Error, Function2 = context.Function, Math2 = context.Math, Object2 = context.Object, RegExp2 = context.RegExp, String2 = context.String, TypeError2 = context.TypeError;
12174
12174
  var arrayProto = Array2.prototype, funcProto = Function2.prototype, objectProto = Object2.prototype;
12175
12175
  var coreJsData = context["__core-js_shared__"];
@@ -16961,17 +16961,17 @@ var require_lodash = __commonJS({
16961
16961
  }
16962
16962
  return lodash;
16963
16963
  });
16964
- var _38 = runInContext();
16964
+ var _39 = runInContext();
16965
16965
  if (typeof define == "function" && typeof define.amd == "object" && define.amd) {
16966
- root._ = _38;
16966
+ root._ = _39;
16967
16967
  define(function() {
16968
- return _38;
16968
+ return _39;
16969
16969
  });
16970
16970
  } else if (freeModule) {
16971
- (freeModule.exports = _38)._ = _38;
16972
- freeExports._ = _38;
16971
+ (freeModule.exports = _39)._ = _39;
16972
+ freeExports._ = _39;
16973
16973
  } else {
16974
- root._ = _38;
16974
+ root._ = _39;
16975
16975
  }
16976
16976
  }).call(exports);
16977
16977
  }
@@ -17171,7 +17171,7 @@ var require_ignore = __commonJS({
17171
17171
  // ever starts again inside it -- `(\\+?) ` did, which made a long run
17172
17172
  // quadratic.
17173
17173
  /(\\+)( ?)/g,
17174
- (_38, run3, space) => space ? run3.slice(0, run3.length - run3.length % 2) + SPACE : run3,
17174
+ (_39, run3, space) => space ? run3.slice(0, run3.length - run3.length % 2) + SPACE : run3,
17175
17175
  ESCAPE + SPACE
17176
17176
  ],
17177
17177
  // Escape metacharacters
@@ -17248,7 +17248,7 @@ var require_ignore = __commonJS({
17248
17248
  // Zero, one or several directories
17249
17249
  // should not use '*', or it will be replaced by the next replacer
17250
17250
  // Check if it is not the last `'/**'`
17251
- (_38, index, str) => index + 6 < str.length ? str.slice(index + 6) === "\\/" ? "(?:\\/[^\\/]+)+" : "(?:\\/[^\\/]+)*" : `\\/${TRAILING_DOUBLESTAR}`,
17251
+ (_39, index, str) => index + 6 < str.length ? str.slice(index + 6) === "\\/" ? "(?:\\/[^\\/]+)+" : "(?:\\/[^\\/]+)*" : `\\/${TRAILING_DOUBLESTAR}`,
17252
17252
  "*"
17253
17253
  ],
17254
17254
  // normal intermediate wildcards
@@ -17261,7 +17261,7 @@ var require_ignore = __commonJS({
17261
17261
  /(^|[^\\]+)(\\\*)+(?=.+)/g,
17262
17262
  // '*.js' matches '.js'
17263
17263
  // '*.js' doesn't match 'abc'
17264
- (_38, p1, p2) => {
17264
+ (_39, p1, p2) => {
17265
17265
  const unescaped = p2.replace(/\\\*/g, "[^\\/]*");
17266
17266
  return p1 + unescaped;
17267
17267
  },
@@ -17337,7 +17337,7 @@ var require_ignore = __commonJS({
17337
17337
  var MODE_IGNORE = "regex";
17338
17338
  var MODE_CHECK_IGNORE = "checkRegex";
17339
17339
  var UNDERSCORE = "_";
17340
- var replaceTrailingWildcard = (_38, p1) => {
17340
+ var replaceTrailingWildcard = (_39, p1) => {
17341
17341
  const prefix = p1 ? `${p1}[^/]+` : "[^/]*";
17342
17342
  return `${prefix}(?=$|\\/$)`;
17343
17343
  };
@@ -19596,7 +19596,7 @@ var require_sender = __commonJS({
19596
19596
  const perMessageDeflate = this._extensions[PerMessageDeflate2.extensionName];
19597
19597
  this._bufferedBytes += options[kByteLength];
19598
19598
  this._state = DEFLATING;
19599
- perMessageDeflate.compress(data, options.fin, (_38, buf) => {
19599
+ perMessageDeflate.compress(data, options.fin, (_39, buf) => {
19600
19600
  if (this._socket.destroyed) {
19601
19601
  const err = new Error(
19602
19602
  "The socket was closed while data was being compressed"
@@ -22369,7 +22369,7 @@ var SignalExit = class extends SignalExitBase {
22369
22369
  const fn = this.#sigListeners[sig];
22370
22370
  if (fn)
22371
22371
  this.#process.on(sig, fn);
22372
- } catch (_38) {
22372
+ } catch (_39) {
22373
22373
  }
22374
22374
  }
22375
22375
  this.#process.emit = (ev, ...a) => {
@@ -22391,7 +22391,7 @@ var SignalExit = class extends SignalExitBase {
22391
22391
  }
22392
22392
  try {
22393
22393
  this.#process.removeListener(sig, listener);
22394
- } catch (_38) {
22394
+ } catch (_39) {
22395
22395
  }
22396
22396
  });
22397
22397
  this.#process.emit = this.#originalProcessEmit;
@@ -22549,7 +22549,7 @@ function getCallSites() {
22549
22549
  const _prepareStackTrace = Error.prepareStackTrace;
22550
22550
  let result = [];
22551
22551
  try {
22552
- Error.prepareStackTrace = (_38, callSites) => {
22552
+ Error.prepareStackTrace = (_39, callSites) => {
22553
22553
  const callSitesWithoutCurrent = callSites.slice(1);
22554
22554
  result = callSitesWithoutCurrent;
22555
22555
  return callSitesWithoutCurrent;
@@ -24361,30 +24361,30 @@ var CharacterCodes;
24361
24361
  })(CharacterCodes || (CharacterCodes = {}));
24362
24362
 
24363
24363
  // node_modules/jsonc-parser/lib/esm/impl/string-intern.js
24364
- var cachedSpaces = new Array(20).fill(0).map((_38, index) => {
24364
+ var cachedSpaces = new Array(20).fill(0).map((_39, index) => {
24365
24365
  return " ".repeat(index);
24366
24366
  });
24367
24367
  var maxCachedValues = 200;
24368
24368
  var cachedBreakLinesWithSpaces = {
24369
24369
  " ": {
24370
- "\n": new Array(maxCachedValues).fill(0).map((_38, index) => {
24370
+ "\n": new Array(maxCachedValues).fill(0).map((_39, index) => {
24371
24371
  return "\n" + " ".repeat(index);
24372
24372
  }),
24373
- "\r": new Array(maxCachedValues).fill(0).map((_38, index) => {
24373
+ "\r": new Array(maxCachedValues).fill(0).map((_39, index) => {
24374
24374
  return "\r" + " ".repeat(index);
24375
24375
  }),
24376
- "\r\n": new Array(maxCachedValues).fill(0).map((_38, index) => {
24376
+ "\r\n": new Array(maxCachedValues).fill(0).map((_39, index) => {
24377
24377
  return "\r\n" + " ".repeat(index);
24378
24378
  })
24379
24379
  },
24380
24380
  " ": {
24381
- "\n": new Array(maxCachedValues).fill(0).map((_38, index) => {
24381
+ "\n": new Array(maxCachedValues).fill(0).map((_39, index) => {
24382
24382
  return "\n" + " ".repeat(index);
24383
24383
  }),
24384
- "\r": new Array(maxCachedValues).fill(0).map((_38, index) => {
24384
+ "\r": new Array(maxCachedValues).fill(0).map((_39, index) => {
24385
24385
  return "\r" + " ".repeat(index);
24386
24386
  }),
24387
- "\r\n": new Array(maxCachedValues).fill(0).map((_38, index) => {
24387
+ "\r\n": new Array(maxCachedValues).fill(0).map((_39, index) => {
24388
24388
  return "\r\n" + " ".repeat(index);
24389
24389
  })
24390
24390
  }
@@ -26035,7 +26035,6 @@ var DEFAULTS = {
26035
26035
  enabled: "auto",
26036
26036
  acceptLicense: false,
26037
26037
  components: [],
26038
- keepInstallFiles: true,
26039
26038
  visualStudio: "full",
26040
26039
  persistEngines: true,
26041
26040
  derivedDataCache: "persisted"
@@ -26977,17 +26976,17 @@ function assertIs(_arg) {
26977
26976
  function assertNever(_x) {
26978
26977
  throw new Error("Unexpected value in exhaustive check");
26979
26978
  }
26980
- function assert(_38) {
26979
+ function assert(_39) {
26981
26980
  }
26982
26981
  function getEnumValues(entries) {
26983
26982
  const numericValues = Object.values(entries).filter((v) => typeof v === "number");
26984
- const values = Object.entries(entries).filter(([k, _38]) => numericValues.indexOf(+k) === -1).map(([_38, v]) => v);
26983
+ const values = Object.entries(entries).filter(([k, _39]) => numericValues.indexOf(+k) === -1).map(([_39, v]) => v);
26985
26984
  return values;
26986
26985
  }
26987
26986
  function joinValues(array2, separator = "|") {
26988
26987
  return array2.map((val) => stringifyPrimitive(val)).join(separator);
26989
26988
  }
26990
- function jsonStringifyReplacer(_38, value) {
26989
+ function jsonStringifyReplacer(_39, value) {
26991
26990
  if (typeof value === "bigint")
26992
26991
  return value.toString();
26993
26992
  return value;
@@ -27166,7 +27165,7 @@ var allowsEval = /* @__PURE__ */ cached(() => {
27166
27165
  const F = Function;
27167
27166
  new F("");
27168
27167
  return true;
27169
- } catch (_38) {
27168
+ } catch (_39) {
27170
27169
  return false;
27171
27170
  }
27172
27171
  });
@@ -27287,31 +27286,31 @@ function normalizeParams(_params) {
27287
27286
  function createTransparentProxy(getter) {
27288
27287
  let target2;
27289
27288
  return new Proxy({}, {
27290
- get(_38, prop, receiver) {
27289
+ get(_39, prop, receiver) {
27291
27290
  target2 ?? (target2 = getter());
27292
27291
  return Reflect.get(target2, prop, receiver);
27293
27292
  },
27294
- set(_38, prop, value, receiver) {
27293
+ set(_39, prop, value, receiver) {
27295
27294
  target2 ?? (target2 = getter());
27296
27295
  return Reflect.set(target2, prop, value, receiver);
27297
27296
  },
27298
- has(_38, prop) {
27297
+ has(_39, prop) {
27299
27298
  target2 ?? (target2 = getter());
27300
27299
  return Reflect.has(target2, prop);
27301
27300
  },
27302
- deleteProperty(_38, prop) {
27301
+ deleteProperty(_39, prop) {
27303
27302
  target2 ?? (target2 = getter());
27304
27303
  return Reflect.deleteProperty(target2, prop);
27305
27304
  },
27306
- ownKeys(_38) {
27305
+ ownKeys(_39) {
27307
27306
  target2 ?? (target2 = getter());
27308
27307
  return Reflect.ownKeys(target2);
27309
27308
  },
27310
- getOwnPropertyDescriptor(_38, prop) {
27309
+ getOwnPropertyDescriptor(_39, prop) {
27311
27310
  target2 ?? (target2 = getter());
27312
27311
  return Reflect.getOwnPropertyDescriptor(target2, prop);
27313
27312
  },
27314
- defineProperty(_38, prop, descriptor) {
27313
+ defineProperty(_39, prop, descriptor) {
27315
27314
  target2 ?? (target2 = getter());
27316
27315
  return Reflect.defineProperty(target2, prop, descriptor);
27317
27316
  }
@@ -27568,7 +27567,7 @@ function issue(...args) {
27568
27567
  return { ...iss };
27569
27568
  }
27570
27569
  function cleanEnum(obj) {
27571
- return Object.entries(obj).filter(([k, _38]) => {
27570
+ return Object.entries(obj).filter(([k, _39]) => {
27572
27571
  return Number.isNaN(Number.parseInt(k, 10));
27573
27572
  }).map((el) => el[1]);
27574
27573
  }
@@ -27759,7 +27758,7 @@ function $constructor(name2, initializer3, proto, params) {
27759
27758
  const zodProto = {};
27760
27759
  function Internals(def) {
27761
27760
  this.def = def;
27762
- this.constr = _38;
27761
+ this.constr = _39;
27763
27762
  this.traits = /* @__PURE__ */ new Set();
27764
27763
  }
27765
27764
  Internals.prototype = zodProto;
@@ -27790,7 +27789,7 @@ function $constructor(name2, initializer3, proto, params) {
27790
27789
  members(target2, protoMembers);
27791
27790
  }
27792
27791
  }
27793
- const proto2 = _38.prototype;
27792
+ const proto2 = _39.prototype;
27794
27793
  for (const k in proto2) {
27795
27794
  if (!Object.prototype.hasOwnProperty.call(proto2, k))
27796
27795
  continue;
@@ -27803,7 +27802,7 @@ function $constructor(name2, initializer3, proto, params) {
27803
27802
  class Definition extends Parent {
27804
27803
  }
27805
27804
  Object.defineProperty(Definition, "name", { value: name2 });
27806
- function _38(def) {
27805
+ function _39(def) {
27807
27806
  const inst = params?.Parent ? newError(Definition) : this;
27808
27807
  init(inst, def);
27809
27808
  const deferred = inst._zod.deferred;
@@ -27818,16 +27817,16 @@ function $constructor(name2, initializer3, proto, params) {
27818
27817
  pp(inst);
27819
27818
  return inst;
27820
27819
  }
27821
- Object.defineProperty(_38, "init", { value: init });
27822
- Object.defineProperty(_38, Symbol.hasInstance, {
27820
+ Object.defineProperty(_39, "init", { value: init });
27821
+ Object.defineProperty(_39, Symbol.hasInstance, {
27823
27822
  value: (inst) => {
27824
27823
  if (params?.Parent && inst instanceof params.Parent)
27825
27824
  return true;
27826
27825
  return inst?._zod?.traits?.has(name2);
27827
27826
  }
27828
27827
  });
27829
- Object.defineProperty(_38, "name", { value: name2 });
27830
- return _38;
27828
+ Object.defineProperty(_39, "name", { value: name2 });
27829
+ return _39;
27831
27830
  }
27832
27831
  var $brand = /* @__PURE__ */ Symbol("zod_brand");
27833
27832
  var $ZodAsyncError = class extends Error {
@@ -28933,13 +28932,13 @@ var $ZodType = /* @__PURE__ */ $constructor("$ZodType", (inst, def) => {
28933
28932
  continue;
28934
28933
  }
28935
28934
  const currLen = payload.issues.length;
28936
- const _38 = ch._zod.check(payload);
28937
- if (_38 instanceof Promise && ctx?.async === false) {
28935
+ const _39 = ch._zod.check(payload);
28936
+ if (_39 instanceof Promise && ctx?.async === false) {
28938
28937
  throw new $ZodAsyncError();
28939
28938
  }
28940
- if (asyncResult || _38 instanceof Promise) {
28939
+ if (asyncResult || _39 instanceof Promise) {
28941
28940
  asyncResult = (asyncResult ?? Promise.resolve()).then(async () => {
28942
- await _38;
28941
+ await _39;
28943
28942
  const nextLen = payload.issues.length;
28944
28943
  if (nextLen === currLen)
28945
28944
  return;
@@ -29020,7 +29019,7 @@ function standardProps(inst) {
29020
29019
  const r = inst._zod.run({ value, issues: [] }, ctx);
29021
29020
  if (!(r instanceof Promise))
29022
29021
  return toStandardResult(r, ctx);
29023
- } catch (_38) {
29022
+ } catch (_39) {
29024
29023
  }
29025
29024
  return validateAsync2(inst, value);
29026
29025
  },
@@ -29031,11 +29030,11 @@ function standardProps(inst) {
29031
29030
  var $ZodString = /* @__PURE__ */ $constructor("$ZodString", (inst, def) => {
29032
29031
  $ZodType.init(inst, def);
29033
29032
  inst._zod.pattern = def.pattern ?? anyString;
29034
- inst._zod.parse = (payload, _38) => {
29033
+ inst._zod.parse = (payload, _39) => {
29035
29034
  if (def.coerce)
29036
29035
  try {
29037
29036
  payload.value = String(payload.value);
29038
- } catch (_39) {
29037
+ } catch (_40) {
29039
29038
  }
29040
29039
  if (typeof payload.value === "string")
29041
29040
  return payload;
@@ -29180,7 +29179,7 @@ var $ZodURL = /* @__PURE__ */ $constructor("$ZodURL", (inst, def) => {
29180
29179
  }
29181
29180
  payload.value = def.normalize ? url2.href : stripTabAndNewline(trimmed);
29182
29181
  return;
29183
- } catch (_38) {
29182
+ } catch (_39) {
29184
29183
  payload.issues.push({
29185
29184
  code: "invalid_format",
29186
29185
  format: "url",
@@ -29476,7 +29475,7 @@ var $ZodNumber = /* @__PURE__ */ $constructor("$ZodNumber", (inst, def) => {
29476
29475
  if (def.coerce)
29477
29476
  try {
29478
29477
  payload.value = Number(payload.value);
29479
- } catch (_38) {
29478
+ } catch (_39) {
29480
29479
  }
29481
29480
  const input2 = payload.value;
29482
29481
  if (typeof input2 === "number" && !Number.isNaN(input2) && Number.isFinite(input2)) {
@@ -29504,7 +29503,7 @@ var $ZodBoolean = /* @__PURE__ */ $constructor("$ZodBoolean", (inst, def) => {
29504
29503
  if (def.coerce)
29505
29504
  try {
29506
29505
  payload.value = Boolean(payload.value);
29507
- } catch (_38) {
29506
+ } catch (_39) {
29508
29507
  }
29509
29508
  const input2 = payload.value;
29510
29509
  if (typeof input2 === "boolean")
@@ -29525,7 +29524,7 @@ var $ZodBigInt = /* @__PURE__ */ $constructor("$ZodBigInt", (inst, def) => {
29525
29524
  if (def.coerce)
29526
29525
  try {
29527
29526
  payload.value = BigInt(payload.value);
29528
- } catch (_38) {
29527
+ } catch (_39) {
29529
29528
  }
29530
29529
  if (typeof payload.value === "bigint")
29531
29530
  return payload;
@@ -31280,7 +31279,7 @@ var $ZodLazy = /* @__PURE__ */ $constructor("$ZodLazy", (inst, def) => {
31280
31279
  var $ZodCustom = /* @__PURE__ */ $constructor("$ZodCustom", (inst, def) => {
31281
31280
  $ZodCheck.init(inst, def);
31282
31281
  $ZodType.init(inst, def);
31283
- inst._zod.parse = (payload, _38) => {
31282
+ inst._zod.parse = (payload, _39) => {
31284
31283
  return payload;
31285
31284
  };
31286
31285
  inst._zod.check = (payload) => {
@@ -42990,7 +42989,7 @@ var nonoptionalProcessor = (schema, ctx, _json, params) => {
42990
42989
  var UNREPRESENTABLE_DEFAULT = /* @__PURE__ */ Symbol();
42991
42990
  function serializeDefaultValue(value, schema, ctx, json3, params) {
42992
42991
  let unrepresentable = false;
42993
- const serialized = JSON.stringify(value, (_38, val) => {
42992
+ const serialized = JSON.stringify(value, (_39, val) => {
42994
42993
  if (typeof val !== "bigint")
42995
42994
  return val;
42996
42995
  unrepresentable = true;
@@ -43115,7 +43114,7 @@ function toJSONSchema(input2, params) {
43115
43114
  const ctx2 = initializeContext({ ...params, processors: allProcessors });
43116
43115
  const defs = {};
43117
43116
  for (const entry of registry2._idmap.entries()) {
43118
- const [_38, schema] = entry;
43117
+ const [_39, schema] = entry;
43119
43118
  processSchema(schema, ctx2);
43120
43119
  }
43121
43120
  const schemas = {};
@@ -43217,7 +43216,7 @@ var JSONSchemaGenerator = class {
43217
43216
  this.ctx.sharedEmitDoneFor = void 0;
43218
43217
  extractDefs(this.ctx, schema);
43219
43218
  const result = finalize(this.ctx, schema);
43220
- const { "~standard": _38, ...plainResult } = result;
43219
+ const { "~standard": _39, ...plainResult } = result;
43221
43220
  return plainResult;
43222
43221
  }
43223
43222
  };
@@ -46362,7 +46361,7 @@ var ToolchainsSchema = external_exports.strictObject({
46362
46361
  }),
46363
46362
  unreal: external_exports.strictObject({
46364
46363
  enabled: enabled(
46365
- "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.",
46364
+ "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.",
46366
46365
  "a .uproject or .uplugin"
46367
46366
  ),
46368
46367
  acceptLicense: external_exports.boolean().describe(
@@ -46371,11 +46370,8 @@ var ToolchainsSchema = external_exports.strictObject({
46371
46370
  components: StringsSchema.describe(
46372
46371
  'More Visual Studio workload or component IDs to add, e.g. ["Microsoft.VisualStudio.Component.VC.Llvm.Clang"].'
46373
46372
  ),
46374
- keepInstallFiles: external_exports.boolean().describe(
46375
- "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."
46376
- ),
46377
- visualStudio: external_exports.enum(["full", "autosdk"]).describe(
46378
- `"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).`
46373
+ visualStudio: external_exports.enum(["full", "buildtools"]).describe(
46374
+ '"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.'
46379
46375
  ),
46380
46376
  persistEngines: external_exports.boolean().describe(
46381
46377
  "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)."
@@ -54998,7 +54994,7 @@ function guestPathFor(hostDir, workspaceHost, guestWorkspace) {
54998
54994
  }
54999
54995
 
55000
54996
  // src/cli/commands/launch/launch.ts
55001
- var import_lodash37 = __toESM(require_lodash(), 1);
54997
+ var import_lodash38 = __toESM(require_lodash(), 1);
55002
54998
  import path181 from "node:path";
55003
54999
 
55004
55000
  // src/host/engines/hcs/check.ts
@@ -56757,12 +56753,8 @@ function applyImplications(settings, result) {
56757
56753
  if (result.flutter.on) imply(settings, result, "android", "Flutter builds for Android");
56758
56754
  if (result.reactNative.on) imply(settings, result, "android", "React Native builds for Android");
56759
56755
  if (result.godot.on && settings.godot.dotnet === true) imply(settings, result, "dotnet", "Godot's .NET build");
56760
- if (result.unreal.on && settings.unreal.visualStudio === "autosdk")
56761
- imply(settings, result, "msvc", "Unreal builds from the portable MSVC (AutoSDK)");
56762
- const autosdkLicence = settings.unreal.visualStudio === "autosdk" && settings.unreal.acceptLicense;
56763
56756
  for (const name2 of LICENSED_TOOLCHAINS) {
56764
56757
  if (settings[name2].enabled !== "auto" || !result[name2].on || settings[name2].acceptLicense) continue;
56765
- if (name2 === "msvc" && autosdkLicence) continue;
56766
56758
  result[name2] = {
56767
56759
  on: false,
56768
56760
  reason: "would be used (" + result[name2].reason + "); set toolchains." + name2 + ".acceptLicense to install it"
@@ -64045,7 +64037,7 @@ function runTerminalClient(socket, token, options = {}) {
64045
64037
  socket.on("close", () => finish({ reason: "closed" }));
64046
64038
  socket.on("error", () => finish({ reason: "closed" }));
64047
64039
  const [c2, r] = size();
64048
- stdout.write("\x1B[2J\x1B[3J\x1B[H");
64040
+ stdout.write("\x1B[2J\x1B[H");
64049
64041
  socket.write(helloFrame(token, c2, r));
64050
64042
  if (stdin.isTTY) stdin.setRawMode(true);
64051
64043
  vtInput = enableVtInput();
@@ -64937,7 +64929,7 @@ function watcherRunning(dataPath) {
64937
64929
  return false;
64938
64930
  }
64939
64931
  }
64940
- var RESTARTABLE = ["sandboxCrash", "memory", "gpu", "hyperv", "vanished"];
64932
+ var RESTARTABLE = ["sandboxCrash", "memory", "gpu", "hyperv"];
64941
64933
  var Watcher = class {
64942
64934
  constructor(dataPath, resume = { restartAfterCrash: false }) {
64943
64935
  this.dataPath = dataPath;
@@ -67628,20 +67620,50 @@ var MigrationRunner = class {
67628
67620
  }
67629
67621
  };
67630
67622
 
67631
- // src/host/migrate/migrations/follow-machine-storage.ts
67623
+ // src/host/migrate/migrations/drop-vs-install-files.ts
67632
67624
  var import_lodash20 = __toESM(require_lodash(), 1);
67625
+ var KEEP_INSTALL_FILES = ["toolchains", "unreal", "keepInstallFiles"];
67626
+ var VISUAL_STUDIO = ["toolchains", "unreal", "visualStudio"];
67627
+ function retiredVsSettings(file2) {
67628
+ return [
67629
+ ...import_lodash20.default.has(file2, KEEP_INSTALL_FILES) ? [KEEP_INSTALL_FILES] : [],
67630
+ ...import_lodash20.default.get(file2, VISUAL_STUDIO) === "autosdk" ? [VISUAL_STUDIO] : []
67631
+ ];
67632
+ }
67633
+ var dropVsInstallFiles = {
67634
+ id: "2026-11-drop-vs-install-files",
67635
+ introducedIn: "1.24.0",
67636
+ scope: "user",
67637
+ needsIdleSandbox: false,
67638
+ summary: 'Removes toolchains.unreal.keepInstallFiles and visualStudio "autosdk": Visual Studio is now kept on the data disk.',
67639
+ applies(ctx) {
67640
+ const file2 = readFileObject(ctx.configPath);
67641
+ return file2 !== null && retiredVsSettings(file2).length > 0;
67642
+ },
67643
+ touches(ctx) {
67644
+ return ctx.configPath ? [ctx.configPath] : [];
67645
+ },
67646
+ async run(ctx, note) {
67647
+ const parsed = readFileObject(ctx.configPath);
67648
+ if (ctx.configPath && parsed)
67649
+ removeValues(ctx.configPath, retiredVsSettings(parsed), "No longer needed (Visual Studio is kept)", note);
67650
+ }
67651
+ };
67652
+
67653
+ // src/host/migrate/migrations/follow-machine-storage.ts
67654
+ var import_lodash21 = __toESM(require_lodash(), 1);
67633
67655
  import path135 from "node:path";
67634
67656
  var ROOT = ["storage", "root"];
67635
67657
  function pinnedOverMachine(configPath) {
67636
67658
  const machine3 = readFileObject(machineConfigPath());
67637
- if (!machine3 || !import_lodash20.default.has(machine3, ROOT)) return false;
67659
+ if (!machine3 || !import_lodash21.default.has(machine3, ROOT)) return false;
67638
67660
  const file2 = readFileObject(configPath);
67639
- if (!file2 || !import_lodash20.default.has(file2, ROOT)) return false;
67640
- const value = import_lodash20.default.get(file2, ROOT);
67641
- const defaults = [import_lodash20.default.get(DEFAULTS, ROOT), ...fullSnapshots(file2).map((s) => import_lodash20.default.get(s.defaults, ROOT))];
67642
- if (!defaults.some((d) => import_lodash20.default.isEqual(d, value))) return false;
67661
+ if (!file2 || !import_lodash21.default.has(file2, ROOT)) return false;
67662
+ const value = import_lodash21.default.get(file2, ROOT);
67663
+ const defaults = [import_lodash21.default.get(DEFAULTS, ROOT), ...fullSnapshots(file2).map((s) => import_lodash21.default.get(s.defaults, ROOT))];
67664
+ if (!defaults.some((d) => import_lodash21.default.isEqual(d, value))) return false;
67643
67665
  const pinned = typeof value === "string" ? expandPath(value, path135.dirname(configPath ?? "")) : "";
67644
- const shared = expandPath(String(import_lodash20.default.get(machine3, ROOT)), path135.dirname(machineConfigPath()));
67666
+ const shared = expandPath(String(import_lodash21.default.get(machine3, ROOT)), path135.dirname(machineConfigPath()));
67645
67667
  return !(holdsData(pinned) && !holdsData(shared));
67646
67668
  }
67647
67669
  var followMachineStorage = {
@@ -67663,7 +67685,7 @@ var followMachineStorage = {
67663
67685
  };
67664
67686
 
67665
67687
  // src/host/migrate/migrations/pin-storage-root.ts
67666
- var import_lodash21 = __toESM(require_lodash(), 1);
67688
+ var import_lodash22 = __toESM(require_lodash(), 1);
67667
67689
  import fs104 from "node:fs";
67668
67690
  import path136 from "node:path";
67669
67691
  var ROOT2 = ["storage", "root"];
@@ -67673,10 +67695,10 @@ function targetFile(ctx) {
67673
67695
  function needsPin(file2, machineFile, oldRoot) {
67674
67696
  if (!oldRoot || !holdsData(oldRoot)) return false;
67675
67697
  const machine3 = readFileObject(machineFile);
67676
- if (machine3 && import_lodash21.default.has(machine3, ROOT2)) return false;
67698
+ if (machine3 && import_lodash22.default.has(machine3, ROOT2)) return false;
67677
67699
  if (!fs104.existsSync(file2)) return true;
67678
67700
  const parsed = readFileObject(file2);
67679
- return parsed !== null && !import_lodash21.default.has(parsed, ROOT2);
67701
+ return parsed !== null && !import_lodash22.default.has(parsed, ROOT2);
67680
67702
  }
67681
67703
  var pinStorageRoot = {
67682
67704
  id: "2026-10-pin-storage-root",
@@ -67698,17 +67720,17 @@ var pinStorageRoot = {
67698
67720
  };
67699
67721
 
67700
67722
  // src/host/migrate/migrations/unpin-config-defaults.ts
67701
- var import_lodash22 = __toESM(require_lodash(), 1);
67723
+ var import_lodash23 = __toESM(require_lodash(), 1);
67702
67724
  var KEEP_PINNED = ["storage", "root"];
67703
67725
  function leafPaths(value, prefix = []) {
67704
- if (!import_lodash22.default.isPlainObject(value)) return prefix.length ? [prefix] : [];
67726
+ if (!import_lodash23.default.isPlainObject(value)) return prefix.length ? [prefix] : [];
67705
67727
  return Object.entries(value).flatMap(([key3, child]) => leafPaths(child, [...prefix, key3]));
67706
67728
  }
67707
67729
  function pinnedLeaves(file2) {
67708
67730
  const snapshots = fullSnapshots(file2);
67709
67731
  return leafPaths(file2).filter((path182) => {
67710
- const value = import_lodash22.default.get(file2, path182);
67711
- return !import_lodash22.default.isEqual(path182, KEEP_PINNED) && import_lodash22.default.has(DEFAULTS, path182) && !import_lodash22.default.isEqual(value, import_lodash22.default.get(DEFAULTS, path182)) && snapshots.some((snapshot) => import_lodash22.default.has(snapshot.defaults, path182) && import_lodash22.default.isEqual(import_lodash22.default.get(snapshot.defaults, path182), value));
67732
+ const value = import_lodash23.default.get(file2, path182);
67733
+ return !import_lodash23.default.isEqual(path182, KEEP_PINNED) && import_lodash23.default.has(DEFAULTS, path182) && !import_lodash23.default.isEqual(value, import_lodash23.default.get(DEFAULTS, path182)) && snapshots.some((snapshot) => import_lodash23.default.has(snapshot.defaults, path182) && import_lodash23.default.isEqual(import_lodash23.default.get(snapshot.defaults, path182), value));
67712
67734
  });
67713
67735
  }
67714
67736
  var unpinConfigDefaults = {
@@ -67731,7 +67753,12 @@ var unpinConfigDefaults = {
67731
67753
  };
67732
67754
 
67733
67755
  // src/host/migrate/registry.ts
67734
- var MIGRATIONS = [unpinConfigDefaults, followMachineStorage, pinStorageRoot];
67756
+ var MIGRATIONS = [
67757
+ unpinConfigDefaults,
67758
+ followMachineStorage,
67759
+ pinStorageRoot,
67760
+ dropVsInstallFiles
67761
+ ];
67735
67762
 
67736
67763
  // src/cli/services/migrate-service.ts
67737
67764
  var MigrateService = class {
@@ -68409,7 +68436,7 @@ var VpnService = class {
68409
68436
  };
68410
68437
 
68411
68438
  // src/cli/services/logs-service.ts
68412
- var import_lodash23 = __toESM(require_lodash(), 1);
68439
+ var import_lodash24 = __toESM(require_lodash(), 1);
68413
68440
  import fs108 from "node:fs";
68414
68441
  import path142 from "node:path";
68415
68442
  var LOG_NAME = /^(guest|daemon|bootstrap)-.*\.log$/;
@@ -68433,7 +68460,7 @@ var LogsService = class {
68433
68460
  const stat = fs108.statSync(path142.join(dir, name2));
68434
68461
  return { name: name2, path: path142.join(dir, name2), bytes: stat.size, modified: stat.mtimeMs };
68435
68462
  });
68436
- return import_lodash23.default.orderBy(found, "modified", "desc");
68463
+ return import_lodash24.default.orderBy(found, "modified", "desc");
68437
68464
  }
68438
68465
  /** The folder the logs are in (whether or not it exists yet). */
68439
68466
  folder() {
@@ -68474,13 +68501,13 @@ var LogsService = class {
68474
68501
  import path145 from "node:path";
68475
68502
 
68476
68503
  // src/cli/commands/shared-use.ts
68477
- var import_lodash24 = __toESM(require_lodash(), 1);
68504
+ var import_lodash25 = __toESM(require_lodash(), 1);
68478
68505
  function withoutHarnessEnvironment(loaded) {
68479
68506
  return {
68480
68507
  ...loaded,
68481
68508
  config: {
68482
68509
  ...loaded.config,
68483
- harnesses: import_lodash24.default.mapValues(loaded.config.harnesses, (harness) => ({ ...harness, environment: {} }))
68510
+ harnesses: import_lodash25.default.mapValues(loaded.config.harnesses, (harness) => ({ ...harness, environment: {} }))
68484
68511
  }
68485
68512
  };
68486
68513
  }
@@ -68666,7 +68693,7 @@ async function readyHere(ctx, status) {
68666
68693
  }
68667
68694
 
68668
68695
  // src/cli/services/sessions-service.ts
68669
- var import_lodash25 = __toESM(require_lodash(), 1);
68696
+ var import_lodash26 = __toESM(require_lodash(), 1);
68670
68697
  var SHELL_START_MS = 15 * 60 * 1e3;
68671
68698
  function viewerText(v) {
68672
68699
  return v === void 0 ? "-" : v === null ? "unknown (older session)" : v.remote + " here, " + (v.viewers - v.remote) + " in sandbox";
@@ -68700,11 +68727,11 @@ var SessionsService = class {
68700
68727
  /** This folder's project first, newest first within each group. */
68701
68728
  ordered(list2) {
68702
68729
  return [
68703
- ...import_lodash25.default.sortBy(
68730
+ ...import_lodash26.default.sortBy(
68704
68731
  list2.filter((s) => s.here),
68705
68732
  (s) => s.startedAt
68706
68733
  ).reverse(),
68707
- ...import_lodash25.default.sortBy(
68734
+ ...import_lodash26.default.sortBy(
68708
68735
  list2.filter((s) => !s.here),
68709
68736
  (s) => s.startedAt
68710
68737
  ).reverse()
@@ -68829,13 +68856,13 @@ var WebService = class {
68829
68856
  import { spawnSync as spawnSync27 } from "node:child_process";
68830
68857
 
68831
68858
  // src/cli/commands/setup/facts.ts
68832
- var import_lodash26 = __toESM(require_lodash(), 1);
68859
+ var import_lodash27 = __toESM(require_lodash(), 1);
68833
68860
  import os20 from "node:os";
68834
68861
  var FEATURE = "Containers-DisposableClientVM";
68835
68862
  var ENABLE_COMMAND = "Enable-WindowsOptionalFeature -Online -FeatureName " + FEATURE + " -All -NoRestart";
68836
68863
  function parseRegQuery(text) {
68837
68864
  return Object.fromEntries(
68838
- import_lodash26.default.compact(
68865
+ import_lodash27.default.compact(
68839
68866
  text.split(/\r?\n/).map((line) => /^\s+(\S+)\s+REG_\w+\s+(.*)$/.exec(line)?.slice(1, 3))
68840
68867
  )
68841
68868
  );
@@ -68856,7 +68883,7 @@ var ProbeSchema = external_exports.object({
68856
68883
  }).partial();
68857
68884
  function parseProbe(text) {
68858
68885
  try {
68859
- return ProbeSchema.parse(JSON.parse(import_lodash26.default.last(text.trim().split(/\r?\n/)) ?? ""));
68886
+ return ProbeSchema.parse(JSON.parse(import_lodash27.default.last(text.trim().split(/\r?\n/)) ?? ""));
68860
68887
  } catch {
68861
68888
  return {};
68862
68889
  }
@@ -69057,7 +69084,7 @@ import path149 from "node:path";
69057
69084
  // src/cli/commands/user-config.ts
69058
69085
  import fs111 from "node:fs";
69059
69086
  import path148 from "node:path";
69060
- var import_lodash30 = __toESM(require_lodash(), 1);
69087
+ var import_lodash31 = __toESM(require_lodash(), 1);
69061
69088
 
69062
69089
  // src/app/features/settings/categories.def.ts
69063
69090
  var CATEGORIES = [
@@ -69703,13 +69730,13 @@ var settingsView = defineView({
69703
69730
  });
69704
69731
 
69705
69732
  // src/app/features/settings/settings-rows.ts
69706
- var import_lodash27 = __toESM(require_lodash(), 1);
69733
+ var import_lodash28 = __toESM(require_lodash(), 1);
69707
69734
 
69708
69735
  // src/cli/validate.ts
69709
69736
  import fs109 from "node:fs";
69710
69737
  import path146 from "node:path";
69711
69738
  function distance(a, b) {
69712
- let row2 = Array.from({ length: b.length + 1 }, (_38, i) => i);
69739
+ let row2 = Array.from({ length: b.length + 1 }, (_39, i) => i);
69713
69740
  for (let i = 1; i <= a.length; i++) {
69714
69741
  const next = [i];
69715
69742
  for (let j = 1; j <= b.length; j++)
@@ -69833,11 +69860,11 @@ function settingsOf(file2) {
69833
69860
  }
69834
69861
  var SAVED = {
69835
69862
  written: (file2, key3) => file2.valueInFile(key3),
69836
- effective: (file2, key3, config3) => file2.isProject ? file2.valueInFile(key3) : import_lodash27.default.get(config3, key3)
69863
+ effective: (file2, key3, config3) => file2.isProject ? file2.valueInFile(key3) : import_lodash28.default.get(config3, key3)
69837
69864
  };
69838
69865
  function masked(key3, value) {
69839
69866
  if (value === void 0) return void 0;
69840
- return import_lodash27.default.get(redactSecrets(import_lodash27.default.set({}, key3, structuredClone(value))), key3);
69867
+ return import_lodash28.default.get(redactSecrets(import_lodash28.default.set({}, key3, structuredClone(value))), key3);
69841
69868
  }
69842
69869
  var projectKeysOf = /* @__PURE__ */ new WeakMap();
69843
69870
  function projectKeys(files) {
@@ -69889,7 +69916,7 @@ function findSetting(file2, key3) {
69889
69916
  }
69890
69917
 
69891
69918
  // src/app/features/settings/settings.run.ts
69892
- var import_lodash29 = __toESM(require_lodash(), 1);
69919
+ var import_lodash30 = __toESM(require_lodash(), 1);
69893
69920
  import fs110 from "node:fs";
69894
69921
  import path147 from "node:path";
69895
69922
 
@@ -69905,7 +69932,7 @@ function typedConfirm(io) {
69905
69932
  }
69906
69933
 
69907
69934
  // src/app/features/settings/settings-share.ts
69908
- var import_lodash28 = __toESM(require_lodash(), 1);
69935
+ var import_lodash29 = __toESM(require_lodash(), 1);
69909
69936
  var MACHINE_ONLY = ["storage.root"];
69910
69937
  var ABSOLUTE = /^([a-zA-Z]:[\\/]|\\\\|\/|%)/;
69911
69938
  var WHY_TEXT = {
@@ -69945,26 +69972,26 @@ function prune(value, trail, withPaths, skipped) {
69945
69972
  }
69946
69973
  return kept.length || value.length === 0 ? kept : void 0;
69947
69974
  }
69948
- if (import_lodash28.default.isPlainObject(value)) {
69975
+ if (import_lodash29.default.isPlainObject(value)) {
69949
69976
  const out = {};
69950
69977
  for (const [k, v] of Object.entries(value)) {
69951
69978
  const next = prune(v, [...trail, k], withPaths, skipped);
69952
69979
  if (next !== void 0) out[k] = next;
69953
69980
  }
69954
- return import_lodash28.default.isEmpty(out) && !import_lodash28.default.isEmpty(value) ? void 0 : out;
69981
+ return import_lodash29.default.isEmpty(out) && !import_lodash29.default.isEmpty(value) ? void 0 : out;
69955
69982
  }
69956
69983
  return value;
69957
69984
  }
69958
69985
  function differences(value, base) {
69959
- if (import_lodash28.default.isPlainObject(value) && import_lodash28.default.isPlainObject(base)) {
69986
+ if (import_lodash29.default.isPlainObject(value) && import_lodash29.default.isPlainObject(base)) {
69960
69987
  const out = {};
69961
69988
  for (const [k, v] of Object.entries(value)) {
69962
69989
  const d = differences(v, base[k]);
69963
69990
  if (d !== void 0) out[k] = d;
69964
69991
  }
69965
- return import_lodash28.default.isEmpty(out) ? void 0 : out;
69992
+ return import_lodash29.default.isEmpty(out) ? void 0 : out;
69966
69993
  }
69967
- return import_lodash28.default.isEqual(value, base) ? void 0 : value;
69994
+ return import_lodash29.default.isEqual(value, base) ? void 0 : value;
69968
69995
  }
69969
69996
  function exportSettings(config3, withPaths) {
69970
69997
  const skipped = [];
@@ -69973,7 +70000,7 @@ function exportSettings(config3, withPaths) {
69973
70000
  return { data, skipped };
69974
70001
  }
69975
70002
  function leaves(value, key3 = []) {
69976
- if (import_lodash28.default.isPlainObject(value) && !import_lodash28.default.isEmpty(value))
70003
+ if (import_lodash29.default.isPlainObject(value) && !import_lodash29.default.isEmpty(value))
69977
70004
  return Object.entries(value).flatMap(([k, v]) => leaves(v, [...key3, k]));
69978
70005
  return key3.length ? [{ key: key3, value }] : [];
69979
70006
  }
@@ -69981,9 +70008,9 @@ function planImport(text, current) {
69981
70008
  const none = { changes: [], lines: [], skipped: [] };
69982
70009
  const errors = [];
69983
70010
  const parsed = parse2(text, errors, { allowTrailingComma: true });
69984
- if (errors.length || !import_lodash28.default.isPlainObject(parsed))
70011
+ if (errors.length || !import_lodash29.default.isPlainObject(parsed))
69985
70012
  return { ...none, problems: ["The file is not a settings file (a JSON object is expected)."] };
69986
- const raw = import_lodash28.default.omit(parsed, "$schema");
70013
+ const raw = import_lodash29.default.omit(parsed, "$schema");
69987
70014
  const skipped = [];
69988
70015
  const safe = prune(raw, [], false, skipped) ?? {};
69989
70016
  const checked = ConfigSchema.safeParse(mergeConfig(DEFAULTS, safe));
@@ -69991,8 +70018,8 @@ function planImport(text, current) {
69991
70018
  const changes = [];
69992
70019
  const lines = [];
69993
70020
  for (const { key: key3, value } of leaves(safe)) {
69994
- const from = import_lodash28.default.get(current, key3);
69995
- if (import_lodash28.default.isEqual(from, value)) continue;
70021
+ const from = import_lodash29.default.get(current, key3);
70022
+ if (import_lodash29.default.isEqual(from, value)) continue;
69996
70023
  changes.push({ key: key3, value });
69997
70024
  lines.push({ key: key3, from, to: value });
69998
70025
  }
@@ -70036,7 +70063,7 @@ var listSettingsRun = implement(listSettings, (ctx, input2) => {
70036
70063
  var getSettingRun = implement(getSetting, (ctx, input2) => {
70037
70064
  const file2 = settingsFiles(ctx).user;
70038
70065
  const { key: key3 } = findSetting(file2, input2.key);
70039
- return { key: input2.key, value: import_lodash29.default.get(redactSecrets(file2.userConfig()), key3) };
70066
+ return { key: input2.key, value: import_lodash30.default.get(redactSecrets(file2.userConfig()), key3) };
70040
70067
  });
70041
70068
  function keepShownSecrets(saved, incoming) {
70042
70069
  if (incoming === REDACTED) return typeof saved === "string" ? saved : incoming;
@@ -70167,7 +70194,7 @@ function configFile(ctx) {
70167
70194
  function fileSetting(ctx, key3, fallback) {
70168
70195
  const file2 = configFile(ctx);
70169
70196
  const text = fs111.existsSync(file2) ? fs111.readFileSync(file2, "utf8") : "";
70170
- return import_lodash30.default.get(parse2(text) ?? {}, key3) ?? fallback;
70197
+ return import_lodash31.default.get(parse2(text) ?? {}, key3) ?? fallback;
70171
70198
  }
70172
70199
  function setSetting2(ctx, key3, value) {
70173
70200
  const file2 = configFile(ctx);
@@ -70498,11 +70525,11 @@ function syncAgentCommands(ctx, config3, quiet = false) {
70498
70525
  }
70499
70526
 
70500
70527
  // src/cli/commands/projects/restart.ts
70501
- var import_lodash32 = __toESM(require_lodash(), 1);
70528
+ var import_lodash33 = __toESM(require_lodash(), 1);
70502
70529
  import path151 from "node:path";
70503
70530
 
70504
70531
  // src/cli/commands/sessions/reopen.ts
70505
- var import_lodash31 = __toESM(require_lodash(), 1);
70532
+ var import_lodash32 = __toESM(require_lodash(), 1);
70506
70533
  function sessionsToReopen(registry2, sessions) {
70507
70534
  return sessions.flatMap((s) => {
70508
70535
  if (s.kind === "shell") return [];
@@ -70572,7 +70599,7 @@ async function reopenSessions(ctx, ready, reopen, relauncher) {
70572
70599
  return opened;
70573
70600
  }
70574
70601
  function reopenedText(opened, wanted, reopen) {
70575
- const same3 = import_lodash31.default.every(reopen, (s) => Boolean(s.conversation));
70602
+ const same3 = import_lodash32.default.every(reopen, (s) => Boolean(s.conversation));
70576
70603
  return "Reopened " + opened + (opened === wanted ? "" : " of " + wanted) + " session" + (opened === 1 ? "" : "s") + (opened ? same3 ? " (continuing their conversations)." : " (continuing the last conversation of each agent)." : ".");
70577
70604
  }
70578
70605
 
@@ -70597,7 +70624,7 @@ function explain(needs, hidden, registry2, sessions) {
70597
70624
  console.log(
70598
70625
  (hidden.length ? "A restart maps " + (hidden.length === 1 ? "it" : "them") + " as well" : "Restarting with what " + needs.map((n) => path151.basename(n.hostDir)).join(", ") + " wants") + " (and keeps " + registry2.projects.map((p) => p.host).join(", ") + "). " + (sessions.length ? describeSessions(sessions) + " will end and reopen afterwards" : "No session is running") + "; your files, tools, databases and logins are kept. It takes about a minute."
70599
70626
  );
70600
- for (const parent of import_lodash32.default.uniq(hidden.map((n) => path151.dirname(n.hostDir))))
70627
+ for (const parent of import_lodash33.default.uniq(hidden.map((n) => path151.dirname(n.hostDir))))
70601
70628
  console.log(
70602
70629
  c.dim("No restart next time for folders in " + parent + ': sandbox projects roots add "' + parent + '"')
70603
70630
  );
@@ -70727,7 +70754,7 @@ async function sessionsToResume(ctx, run3) {
70727
70754
  }
70728
70755
 
70729
70756
  // src/cli/commands/launch/running.ts
70730
- var import_lodash33 = __toESM(require_lodash(), 1);
70757
+ var import_lodash34 = __toESM(require_lodash(), 1);
70731
70758
 
70732
70759
  // src/cli/commands/launch/boot-progress.ts
70733
70760
  function clean(text, max) {
@@ -70917,7 +70944,7 @@ async function launchIntoRunning(ctx, relauncher) {
70917
70944
  }
70918
70945
  }
70919
70946
  if (needs.length) return offerRestart(ctx, needs, () => launchIntoRunning(ctx, relauncher), relauncher);
70920
- for (const note of import_lodash33.default.uniq(joined.flatMap((j) => j.joined.notes))) console.log(note);
70947
+ for (const note of import_lodash34.default.uniq(joined.flatMap((j) => j.joined.notes))) console.log(note);
70921
70948
  if (joined.length === 1) return openSession(joined[0].ctx, ready, joined[0].joined, { attach: ctx.options.terminal });
70922
70949
  return openSessions(ctx, ready, joined);
70923
70950
  }
@@ -74576,10 +74603,10 @@ var removeAgentRun = implement(removeAgent, async (ctx, input2, io) => {
74576
74603
  });
74577
74604
 
74578
74605
  // src/app/features/agents/env.run.ts
74579
- var import_lodash34 = __toESM(require_lodash(), 1);
74606
+ var import_lodash35 = __toESM(require_lodash(), 1);
74580
74607
  function ownVariables(file2, agent) {
74581
74608
  const raw = file2.valueInFile(["harnesses", agent, "environment"]);
74582
- if (!import_lodash34.default.isPlainObject(raw)) return {};
74609
+ if (!import_lodash35.default.isPlainObject(raw)) return {};
74583
74610
  return Object.fromEntries(
74584
74611
  Object.entries(raw).filter(([, v]) => typeof v === "string")
74585
74612
  );
@@ -74876,7 +74903,7 @@ function servicesText(o) {
74876
74903
  [s.ready ? s.summary : "coming", s.heldBy ? "in use by sandbox " + s.heldBy : null].filter(Boolean).join(", ") || "-"
74877
74904
  ])
74878
74905
  ];
74879
- const widths = table2[0].map((_38, i) => Math.max(...table2.map((r) => r[i].length)));
74906
+ const widths = table2[0].map((_39, i) => Math.max(...table2.map((r) => r[i].length)));
74880
74907
  return table2.map((r) => r.map((cell, i) => i === r.length - 1 ? cell : cell.padEnd(widths[i] + 2)).join("")).join("\n");
74881
74908
  }
74882
74909
  var listServices = defineQuery({
@@ -75046,7 +75073,7 @@ function agentText(o) {
75046
75073
  a.savedAt.slice(0, 16).replace("T", " ")
75047
75074
  ])
75048
75075
  ];
75049
- const widths = table2[0].map((_38, i) => Math.max(...table2.map((r) => r[i].length)));
75076
+ const widths = table2[0].map((_39, i) => Math.max(...table2.map((r) => r[i].length)));
75050
75077
  const lines = table2.map((r) => r.map((cell, i) => i === r.length - 1 ? cell : cell.padEnd(widths[i] + 2)).join(""));
75051
75078
  return [...lines, "", "* = active in the sandbox D = default for new launches"].join("\n");
75052
75079
  }
@@ -75901,14 +75928,14 @@ var appsView = defineView({
75901
75928
  });
75902
75929
 
75903
75930
  // src/app/features/apps/apps-rows.ts
75904
- var import_lodash35 = __toESM(require_lodash(), 1);
75931
+ var import_lodash36 = __toESM(require_lodash(), 1);
75905
75932
  import fs120 from "node:fs";
75906
75933
  import path160 from "node:path";
75907
75934
  var INSTALL = ["apps", "install"];
75908
75935
  var CUSTOM_KEY = ["apps", "custom"];
75909
75936
  var SAVED2 = {
75910
75937
  install: (file2) => file2.isProject ? file2.valueInFile(INSTALL) : file2.userConfig().apps.install,
75911
- setting: (file2, key3) => import_lodash35.default.get(file2.userConfig(), key3),
75938
+ setting: (file2, key3) => import_lodash36.default.get(file2.userConfig(), key3),
75912
75939
  custom: (file2) => file2.isProject ? {} : file2.userConfig().apps.custom
75913
75940
  };
75914
75941
  function entriesOf2(file2) {
@@ -82442,7 +82469,7 @@ async function attachOpened(ctx, session) {
82442
82469
  nextStep("sandbox attach " + session);
82443
82470
  return 0;
82444
82471
  }
82445
- const { attach: attach2 } = await import("./chunk-QFSJX2KW.js");
82472
+ const { attach: attach2 } = await import("./chunk-KH4MI2U5.js");
82446
82473
  return attach2({ ...ctx, options: { ...ctx.options, positionals: [session] } });
82447
82474
  }
82448
82475
  function definitionHandler(def) {
@@ -82751,13 +82778,13 @@ async function prepare(ctx, run3) {
82751
82778
  }
82752
82779
 
82753
82780
  // src/cli/commands/launch/boot-wants.ts
82754
- var import_lodash36 = __toESM(require_lodash(), 1);
82781
+ var import_lodash37 = __toESM(require_lodash(), 1);
82755
82782
  import path180 from "node:path";
82756
82783
  async function bootWantsFor(ctx, run3, extraProjects) {
82757
82784
  const { roots } = run3.config.projects;
82758
82785
  const planned = planBootProjects({ run: run3, packageRoot: ctx.packageRoot, extraProjects }).projects.map((p) => p.host);
82759
82786
  const inRoots = new KnownProjects(run3.storageRoot).list().map((k) => k.host).filter((h) => roots.some((r) => isWithin(path180.resolve(r), h)));
82760
- const folders = import_lodash36.default.uniqBy(
82787
+ const folders = import_lodash37.default.uniqBy(
82761
82788
  [...(extraProjects ?? []).map((p) => path180.resolve(p)), ...planned, ...inRoots],
82762
82789
  (f) => f.toLowerCase()
82763
82790
  ).filter((f) => !isWithin(run3.workspaceHost, f) && dirExists(f)).slice(0, 200);
@@ -82781,7 +82808,7 @@ async function bootWantsFor(ctx, run3, extraProjects) {
82781
82808
  notes.push("What " + path180.basename(folder) + " asks for at boot is not included: " + errMsg(e).split("\n")[0]);
82782
82809
  }
82783
82810
  }
82784
- const keepOff = BOOT_SETTINGS.filter((s) => import_lodash36.default.get(ctx.loaded.config, s) === true && import_lodash36.default.get(run3.config, s) === false);
82811
+ const keepOff = BOOT_SETTINGS.filter((s) => import_lodash37.default.get(ctx.loaded.config, s) === true && import_lodash37.default.get(run3.config, s) === false);
82785
82812
  return { wants: { projects, keepOff }, notes };
82786
82813
  }
82787
82814
 
@@ -82902,7 +82929,7 @@ var Launcher = class {
82902
82929
  const wants = this.options.sessions;
82903
82930
  if (wants.length === 1) return launch(contextFor(ctx, wants[0]), generateOnly, extras);
82904
82931
  const first = contextFor(ctx, wants[0]);
82905
- const others = import_lodash37.default.uniqBy(
82932
+ const others = import_lodash38.default.uniqBy(
82906
82933
  wants.slice(1).map((w) => w.folder).filter((f) => !isWithin(wants[0].folder, f)),
82907
82934
  (f) => f.toLowerCase()
82908
82935
  );