windows-development-sandbox 1.15.0 → 1.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/config.example.json +6 -0
  2. package/dist/app/features/access/access.run.js +1 -1
  3. package/dist/app/features/accounts/accounts.def.js +4 -3
  4. package/dist/app/features/defs.d.ts +3 -1
  5. package/dist/app/features/defs.js +26 -12
  6. package/dist/app/features/sandbox/sandbox.def.js +9 -5
  7. package/dist/app/features/sessions/sessions.def.js +1 -1
  8. package/dist/bin/agent-sandbox.js +2 -2
  9. package/dist/bin/{chunk-HTQT5SBY.js → chunk-QLGGAG3D.js} +98 -79
  10. package/dist/bin/{chunk-D7CM63BS.js → chunk-REE3EMHD.js} +105 -41
  11. package/dist/bin/{chunk-RQ4BWBYX.js → chunk-XYUVIVJT.js} +1 -1
  12. package/dist/bin/claude-host.js +2 -2
  13. package/dist/bin/claude-sbx.js +2 -2
  14. package/dist/bin/codex-sbx.js +2 -2
  15. package/dist/bin/gemini-sbx.js +2 -2
  16. package/dist/bin/sandbox.js +2 -2
  17. package/dist/bin/sbx-hide.js +2 -2
  18. package/dist/bin/sbx-show.js +2 -2
  19. package/dist/cli/commands/web.js +1 -1
  20. package/dist/cli/index.js +4 -1
  21. package/dist/cli/report.d.ts +7 -0
  22. package/dist/cli/report.js +31 -0
  23. package/dist/core/config/defaults.js +1 -0
  24. package/dist/core/detect/toolchains.d.ts +1 -0
  25. package/dist/core/detect/toolchains.js +7 -0
  26. package/dist/core/schema/config.d.ts +21 -0
  27. package/dist/core/schema/sandbox.js +1 -1
  28. package/dist/core/schema/toolchains.d.ts +6 -0
  29. package/dist/core/schema/toolchains.js +10 -0
  30. package/dist/guest/boot/boot.js +2 -0
  31. package/dist/guest/setup/browser-gpu.d.ts +1 -0
  32. package/dist/guest/setup/browser-gpu.js +18 -0
  33. package/dist/guest/toolchains/native/rust-extras.js +3 -1
  34. package/dist/guest/toolchains/native/unreal.d.ts +9 -0
  35. package/dist/guest/toolchains/native/unreal.js +186 -0
  36. package/dist/guest/toolchains/native/vcruntime.d.ts +3 -0
  37. package/dist/guest/toolchains/native/vcruntime.js +2 -2
  38. package/dist/guest/toolchains/plan.js +10 -2
  39. package/dist/host/engines/hcs/live-folders.js +1 -1
  40. package/dist/host/github/token.js +1 -1
  41. package/dist/host/profile/accounts.js +1 -1
  42. package/dist/host/profile/agent-accounts.js +1 -1
  43. package/dist/host/profile/plugin-share.d.ts +5 -0
  44. package/dist/host/profile/plugin-share.js +22 -1
  45. package/dist/host/secrets/secret-store.d.ts +3 -3
  46. package/dist/host/secrets/secret-store.js +37 -10
  47. package/dist/host/vpn/login.js +1 -1
  48. package/dist/runtime/agent.js +16 -1
  49. package/dist/runtime/daemon.js +522 -337
  50. package/dist/runtime/db.js +17 -1
  51. package/dist/runtime/main.js +669 -472
  52. package/dist/runtime/netproxy.js +16 -1
  53. package/dist/runtime/view.js +16 -1
  54. package/dist/selftest/accounts.test.js +29 -0
  55. package/dist/selftest/app.test.js +2 -2
  56. package/dist/selftest/detect.test.js +7 -0
  57. package/dist/selftest/live-network.test.js +5 -0
  58. package/dist/selftest/support/fixtures.d.ts +6 -0
  59. package/dist/shared/channel/schema.d.ts +18 -0
  60. package/dist/web/index.html +2 -2
  61. package/dist/web/main-JTH3FT4O.js +221 -0
  62. package/dist/web/{main-UAQPI5XD.css → main-XT7T6ODM.css} +1 -1
  63. package/native/csharp/HcsHost/AssemblyInfo.cs +3 -3
  64. package/native/csharp/HostTools/AssemblyInfo.cs +3 -3
  65. package/native/csharp/HostTools/Program.cs +6 -1
  66. package/native/csharp/HostTools/Protect.cs +41 -0
  67. package/native/csharp/StorageHelper/AssemblyInfo.cs +3 -3
  68. package/package.json +1 -1
  69. package/schemas/config.schema.json +34 -1
  70. package/schemas/sandbox-config.schema.json +34 -1
  71. package/dist/web/main-7DJZ2M27.js +0 -221
@@ -1363,11 +1363,11 @@ var require_lodash = __commonJS({
1363
1363
  return isFunction(object2[key]);
1364
1364
  });
1365
1365
  }
1366
- function baseGet(object2, path77) {
1367
- path77 = castPath(path77, object2);
1368
- var index = 0, length = path77.length;
1366
+ function baseGet(object2, path78) {
1367
+ path78 = castPath(path78, object2);
1368
+ var index = 0, length = path78.length;
1369
1369
  while (object2 != null && index < length) {
1370
- object2 = object2[toKey(path77[index++])];
1370
+ object2 = object2[toKey(path78[index++])];
1371
1371
  }
1372
1372
  return index && index == length ? object2 : undefined2;
1373
1373
  }
@@ -1431,10 +1431,10 @@ var require_lodash = __commonJS({
1431
1431
  });
1432
1432
  return accumulator;
1433
1433
  }
1434
- function baseInvoke(object2, path77, args) {
1435
- path77 = castPath(path77, object2);
1436
- object2 = parent(object2, path77);
1437
- var func = object2 == null ? object2 : object2[toKey(last(path77))];
1434
+ function baseInvoke(object2, path78, args) {
1435
+ path78 = castPath(path78, object2);
1436
+ object2 = parent(object2, path78);
1437
+ var func = object2 == null ? object2 : object2[toKey(last(path78))];
1438
1438
  return func == null ? undefined2 : apply(func, object2, args);
1439
1439
  }
1440
1440
  function baseIsArguments(value) {
@@ -1590,13 +1590,13 @@ var require_lodash = __commonJS({
1590
1590
  return object2 === source || baseIsMatch(object2, source, matchData);
1591
1591
  };
1592
1592
  }
1593
- function baseMatchesProperty(path77, srcValue) {
1594
- if (isKey(path77) && isStrictComparable(srcValue)) {
1595
- return matchesStrictComparable(toKey(path77), srcValue);
1593
+ function baseMatchesProperty(path78, srcValue) {
1594
+ if (isKey(path78) && isStrictComparable(srcValue)) {
1595
+ return matchesStrictComparable(toKey(path78), srcValue);
1596
1596
  }
1597
1597
  return function(object2) {
1598
- var objValue = get(object2, path77);
1599
- return objValue === undefined2 && objValue === srcValue ? hasIn(object2, path77) : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG);
1598
+ var objValue = get(object2, path78);
1599
+ return objValue === undefined2 && objValue === srcValue ? hasIn(object2, path78) : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG);
1600
1600
  };
1601
1601
  }
1602
1602
  function baseMerge(object2, source, srcIndex, customizer, stack) {
@@ -1693,23 +1693,23 @@ var require_lodash = __commonJS({
1693
1693
  });
1694
1694
  }
1695
1695
  function basePick(object2, paths) {
1696
- return basePickBy(object2, paths, function(value, path77) {
1697
- return hasIn(object2, path77);
1696
+ return basePickBy(object2, paths, function(value, path78) {
1697
+ return hasIn(object2, path78);
1698
1698
  });
1699
1699
  }
1700
1700
  function basePickBy(object2, paths, predicate) {
1701
1701
  var index = -1, length = paths.length, result2 = {};
1702
1702
  while (++index < length) {
1703
- var path77 = paths[index], value = baseGet(object2, path77);
1704
- if (predicate(value, path77)) {
1705
- baseSet(result2, castPath(path77, object2), value);
1703
+ var path78 = paths[index], value = baseGet(object2, path78);
1704
+ if (predicate(value, path78)) {
1705
+ baseSet(result2, castPath(path78, object2), value);
1706
1706
  }
1707
1707
  }
1708
1708
  return result2;
1709
1709
  }
1710
- function basePropertyDeep(path77) {
1710
+ function basePropertyDeep(path78) {
1711
1711
  return function(object2) {
1712
- return baseGet(object2, path77);
1712
+ return baseGet(object2, path78);
1713
1713
  };
1714
1714
  }
1715
1715
  function basePullAll(array2, values2, iteratee2, comparator) {
@@ -1783,14 +1783,14 @@ var require_lodash = __commonJS({
1783
1783
  var array2 = values(collection);
1784
1784
  return shuffleSelf(array2, baseClamp(n, 0, array2.length));
1785
1785
  }
1786
- function baseSet(object2, path77, value, customizer) {
1786
+ function baseSet(object2, path78, value, customizer) {
1787
1787
  if (!isObject2(object2)) {
1788
1788
  return object2;
1789
1789
  }
1790
- path77 = castPath(path77, object2);
1791
- var index = -1, length = path77.length, lastIndex = length - 1, nested = object2;
1790
+ path78 = castPath(path78, object2);
1791
+ var index = -1, length = path78.length, lastIndex = length - 1, nested = object2;
1792
1792
  while (nested != null && ++index < length) {
1793
- var key = toKey(path77[index]), newValue = value;
1793
+ var key = toKey(path78[index]), newValue = value;
1794
1794
  if (key === "__proto__" || key === "constructor" || key === "prototype") {
1795
1795
  return object2;
1796
1796
  }
@@ -1798,7 +1798,7 @@ var require_lodash = __commonJS({
1798
1798
  var objValue = nested[key];
1799
1799
  newValue = customizer ? customizer(objValue, key, nested) : undefined2;
1800
1800
  if (newValue === undefined2) {
1801
- newValue = isObject2(objValue) ? objValue : isIndex(path77[index + 1]) ? [] : {};
1801
+ newValue = isObject2(objValue) ? objValue : isIndex(path78[index + 1]) ? [] : {};
1802
1802
  }
1803
1803
  }
1804
1804
  assignValue(nested, key, newValue);
@@ -1964,14 +1964,14 @@ var require_lodash = __commonJS({
1964
1964
  }
1965
1965
  return result2;
1966
1966
  }
1967
- function baseUnset(object2, path77) {
1968
- path77 = castPath(path77, object2);
1969
- var index = -1, length = path77.length;
1967
+ function baseUnset(object2, path78) {
1968
+ path78 = castPath(path78, object2);
1969
+ var index = -1, length = path78.length;
1970
1970
  if (!length) {
1971
1971
  return true;
1972
1972
  }
1973
1973
  while (++index < length) {
1974
- var key = toKey(path77[index]);
1974
+ var key = toKey(path78[index]);
1975
1975
  if (key === "__proto__" && !hasOwnProperty.call(object2, "__proto__")) {
1976
1976
  return false;
1977
1977
  }
@@ -1979,11 +1979,11 @@ var require_lodash = __commonJS({
1979
1979
  return false;
1980
1980
  }
1981
1981
  }
1982
- var obj = parent(object2, path77);
1983
- return obj == null || delete obj[toKey(last(path77))];
1982
+ var obj = parent(object2, path78);
1983
+ return obj == null || delete obj[toKey(last(path78))];
1984
1984
  }
1985
- function baseUpdate(object2, path77, updater, customizer) {
1986
- return baseSet(object2, path77, updater(baseGet(object2, path77)), customizer);
1985
+ function baseUpdate(object2, path78, updater, customizer) {
1986
+ return baseSet(object2, path78, updater(baseGet(object2, path78)), customizer);
1987
1987
  }
1988
1988
  function baseWhile(array2, predicate, isDrop, fromRight) {
1989
1989
  var length = array2.length, index = fromRight ? length : -1;
@@ -2866,11 +2866,11 @@ var require_lodash = __commonJS({
2866
2866
  var match = source.match(reWrapDetails);
2867
2867
  return match ? match[1].split(reSplitDetails) : [];
2868
2868
  }
2869
- function hasPath(object2, path77, hasFunc) {
2870
- path77 = castPath(path77, object2);
2871
- var index = -1, length = path77.length, result2 = false;
2869
+ function hasPath(object2, path78, hasFunc) {
2870
+ path78 = castPath(path78, object2);
2871
+ var index = -1, length = path78.length, result2 = false;
2872
2872
  while (++index < length) {
2873
- var key = toKey(path77[index]);
2873
+ var key = toKey(path78[index]);
2874
2874
  if (!(result2 = object2 != null && hasFunc(object2, key))) {
2875
2875
  break;
2876
2876
  }
@@ -3072,8 +3072,8 @@ var require_lodash = __commonJS({
3072
3072
  return apply(func, this, otherArgs);
3073
3073
  };
3074
3074
  }
3075
- function parent(object2, path77) {
3076
- return path77.length < 2 ? object2 : baseGet(object2, baseSlice(path77, 0, -1));
3075
+ function parent(object2, path78) {
3076
+ return path78.length < 2 ? object2 : baseGet(object2, baseSlice(path78, 0, -1));
3077
3077
  }
3078
3078
  function reorder(array2, indexes) {
3079
3079
  var arrLength = array2.length, length = nativeMin(indexes.length, arrLength), oldArray = copyArray(array2);
@@ -3708,10 +3708,10 @@ var require_lodash = __commonJS({
3708
3708
  }
3709
3709
  return isString(collection) ? fromIndex <= length && collection.indexOf(value, fromIndex) > -1 : !!length && baseIndexOf(collection, value, fromIndex) > -1;
3710
3710
  }
3711
- var invokeMap = baseRest(function(collection, path77, args) {
3712
- var index = -1, isFunc = typeof path77 == "function", result2 = isArrayLike(collection) ? Array2(collection.length) : [];
3711
+ var invokeMap = baseRest(function(collection, path78, args) {
3712
+ var index = -1, isFunc = typeof path78 == "function", result2 = isArrayLike(collection) ? Array2(collection.length) : [];
3713
3713
  baseEach(collection, function(value) {
3714
- result2[++index] = isFunc ? apply(path77, value, args) : baseInvoke(value, path77, args);
3714
+ result2[++index] = isFunc ? apply(path78, value, args) : baseInvoke(value, path78, args);
3715
3715
  });
3716
3716
  return result2;
3717
3717
  });
@@ -4363,15 +4363,15 @@ var require_lodash = __commonJS({
4363
4363
  function functionsIn(object2) {
4364
4364
  return object2 == null ? [] : baseFunctions(object2, keysIn(object2));
4365
4365
  }
4366
- function get(object2, path77, defaultValue) {
4367
- var result2 = object2 == null ? undefined2 : baseGet(object2, path77);
4366
+ function get(object2, path78, defaultValue) {
4367
+ var result2 = object2 == null ? undefined2 : baseGet(object2, path78);
4368
4368
  return result2 === undefined2 ? defaultValue : result2;
4369
4369
  }
4370
- function has(object2, path77) {
4371
- return object2 != null && hasPath(object2, path77, baseHas);
4370
+ function has(object2, path78) {
4371
+ return object2 != null && hasPath(object2, path78, baseHas);
4372
4372
  }
4373
- function hasIn(object2, path77) {
4374
- return object2 != null && hasPath(object2, path77, baseHasIn);
4373
+ function hasIn(object2, path78) {
4374
+ return object2 != null && hasPath(object2, path78, baseHasIn);
4375
4375
  }
4376
4376
  var invert = createInverter(function(result2, value, key) {
4377
4377
  if (value != null && typeof value.toString != "function") {
@@ -4424,10 +4424,10 @@ var require_lodash = __commonJS({
4424
4424
  return result2;
4425
4425
  }
4426
4426
  var isDeep = false;
4427
- paths = arrayMap(paths, function(path77) {
4428
- path77 = castPath(path77, object2);
4429
- isDeep || (isDeep = path77.length > 1);
4430
- return path77;
4427
+ paths = arrayMap(paths, function(path78) {
4428
+ path78 = castPath(path78, object2);
4429
+ isDeep || (isDeep = path78.length > 1);
4430
+ return path78;
4431
4431
  });
4432
4432
  copyObject(object2, getAllKeysIn(object2), result2);
4433
4433
  if (isDeep) {
@@ -4453,19 +4453,19 @@ var require_lodash = __commonJS({
4453
4453
  return [prop];
4454
4454
  });
4455
4455
  predicate = getIteratee(predicate);
4456
- return basePickBy(object2, props, function(value, path77) {
4457
- return predicate(value, path77[0]);
4456
+ return basePickBy(object2, props, function(value, path78) {
4457
+ return predicate(value, path78[0]);
4458
4458
  });
4459
4459
  }
4460
- function result(object2, path77, defaultValue) {
4461
- path77 = castPath(path77, object2);
4462
- var index = -1, length = path77.length;
4460
+ function result(object2, path78, defaultValue) {
4461
+ path78 = castPath(path78, object2);
4462
+ var index = -1, length = path78.length;
4463
4463
  if (!length) {
4464
4464
  length = 1;
4465
4465
  object2 = undefined2;
4466
4466
  }
4467
4467
  while (++index < length) {
4468
- var value = object2 == null ? undefined2 : object2[toKey(path77[index])];
4468
+ var value = object2 == null ? undefined2 : object2[toKey(path78[index])];
4469
4469
  if (value === undefined2) {
4470
4470
  index = length;
4471
4471
  value = defaultValue;
@@ -4474,12 +4474,12 @@ var require_lodash = __commonJS({
4474
4474
  }
4475
4475
  return object2;
4476
4476
  }
4477
- function set2(object2, path77, value) {
4478
- return object2 == null ? object2 : baseSet(object2, path77, value);
4477
+ function set2(object2, path78, value) {
4478
+ return object2 == null ? object2 : baseSet(object2, path78, value);
4479
4479
  }
4480
- function setWith(object2, path77, value, customizer) {
4480
+ function setWith(object2, path78, value, customizer) {
4481
4481
  customizer = typeof customizer == "function" ? customizer : undefined2;
4482
- return object2 == null ? object2 : baseSet(object2, path77, value, customizer);
4482
+ return object2 == null ? object2 : baseSet(object2, path78, value, customizer);
4483
4483
  }
4484
4484
  var toPairs = createToPairs(keys);
4485
4485
  var toPairsIn = createToPairs(keysIn);
@@ -4501,15 +4501,15 @@ var require_lodash = __commonJS({
4501
4501
  });
4502
4502
  return accumulator;
4503
4503
  }
4504
- function unset(object2, path77) {
4505
- return object2 == null ? true : baseUnset(object2, path77);
4504
+ function unset(object2, path78) {
4505
+ return object2 == null ? true : baseUnset(object2, path78);
4506
4506
  }
4507
- function update(object2, path77, updater) {
4508
- return object2 == null ? object2 : baseUpdate(object2, path77, castFunction(updater));
4507
+ function update(object2, path78, updater) {
4508
+ return object2 == null ? object2 : baseUpdate(object2, path78, castFunction(updater));
4509
4509
  }
4510
- function updateWith(object2, path77, updater, customizer) {
4510
+ function updateWith(object2, path78, updater, customizer) {
4511
4511
  customizer = typeof customizer == "function" ? customizer : undefined2;
4512
- return object2 == null ? object2 : baseUpdate(object2, path77, castFunction(updater), customizer);
4512
+ return object2 == null ? object2 : baseUpdate(object2, path78, castFunction(updater), customizer);
4513
4513
  }
4514
4514
  function values(object2) {
4515
4515
  return object2 == null ? [] : baseValues(object2, keys(object2));
@@ -4895,17 +4895,17 @@ var require_lodash = __commonJS({
4895
4895
  function matches(source) {
4896
4896
  return baseMatches(baseClone(source, CLONE_DEEP_FLAG));
4897
4897
  }
4898
- function matchesProperty(path77, srcValue) {
4899
- return baseMatchesProperty(path77, baseClone(srcValue, CLONE_DEEP_FLAG));
4898
+ function matchesProperty(path78, srcValue) {
4899
+ return baseMatchesProperty(path78, baseClone(srcValue, CLONE_DEEP_FLAG));
4900
4900
  }
4901
- var method = baseRest(function(path77, args) {
4901
+ var method = baseRest(function(path78, args) {
4902
4902
  return function(object2) {
4903
- return baseInvoke(object2, path77, args);
4903
+ return baseInvoke(object2, path78, args);
4904
4904
  };
4905
4905
  });
4906
4906
  var methodOf = baseRest(function(object2, args) {
4907
- return function(path77) {
4908
- return baseInvoke(object2, path77, args);
4907
+ return function(path78) {
4908
+ return baseInvoke(object2, path78, args);
4909
4909
  };
4910
4910
  });
4911
4911
  function mixin(object2, source, options) {
@@ -4952,12 +4952,12 @@ var require_lodash = __commonJS({
4952
4952
  var over = createOver(arrayMap);
4953
4953
  var overEvery = createOver(arrayEvery);
4954
4954
  var overSome = createOver(arraySome);
4955
- function property(path77) {
4956
- return isKey(path77) ? baseProperty(toKey(path77)) : basePropertyDeep(path77);
4955
+ function property(path78) {
4956
+ return isKey(path78) ? baseProperty(toKey(path78)) : basePropertyDeep(path78);
4957
4957
  }
4958
4958
  function propertyOf(object2) {
4959
- return function(path77) {
4960
- return object2 == null ? undefined2 : baseGet(object2, path77);
4959
+ return function(path78) {
4960
+ return object2 == null ? undefined2 : baseGet(object2, path78);
4961
4961
  };
4962
4962
  }
4963
4963
  var range = createRange();
@@ -5410,12 +5410,12 @@ var require_lodash = __commonJS({
5410
5410
  LazyWrapper.prototype.findLast = function(predicate) {
5411
5411
  return this.reverse().find(predicate);
5412
5412
  };
5413
- LazyWrapper.prototype.invokeMap = baseRest(function(path77, args) {
5414
- if (typeof path77 == "function") {
5413
+ LazyWrapper.prototype.invokeMap = baseRest(function(path78, args) {
5414
+ if (typeof path78 == "function") {
5415
5415
  return new LazyWrapper(this);
5416
5416
  }
5417
5417
  return this.map(function(value) {
5418
- return baseInvoke(value, path77, args);
5418
+ return baseInvoke(value, path78, args);
5419
5419
  });
5420
5420
  });
5421
5421
  LazyWrapper.prototype.reject = function(predicate) {
@@ -5532,8 +5532,8 @@ var require_lodash = __commonJS({
5532
5532
  });
5533
5533
 
5534
5534
  // src/guest/entries/main.ts
5535
- import fs63 from "node:fs";
5536
- import path76 from "node:path";
5535
+ import fs64 from "node:fs";
5536
+ import path77 from "node:path";
5537
5537
 
5538
5538
  // src/guest/runtime/paths.ts
5539
5539
  import path7 from "node:path";
@@ -6358,10 +6358,10 @@ function mergeDefs(...defs) {
6358
6358
  function cloneDef(schema) {
6359
6359
  return mergeDefs(schema._zod.def);
6360
6360
  }
6361
- function getElementAtPath(obj, path77) {
6362
- if (!path77)
6361
+ function getElementAtPath(obj, path78) {
6362
+ if (!path78)
6363
6363
  return obj;
6364
- return path77.reduce((acc, key) => acc?.[key], obj);
6364
+ return path78.reduce((acc, key) => acc?.[key], obj);
6365
6365
  }
6366
6366
  function promiseAllObject(promisesObj) {
6367
6367
  const keys = Object.keys(promisesObj);
@@ -6701,11 +6701,11 @@ function explicitlyAborted(x, startIndex = 0) {
6701
6701
  }
6702
6702
  return false;
6703
6703
  }
6704
- function prefixIssues(path77, issues) {
6704
+ function prefixIssues(path78, issues) {
6705
6705
  return issues.map((iss) => {
6706
6706
  var _a3;
6707
6707
  (_a3 = iss).path ?? (_a3.path = []);
6708
- iss.path.unshift(path77);
6708
+ iss.path.unshift(path78);
6709
6709
  return iss;
6710
6710
  });
6711
6711
  }
@@ -7155,16 +7155,16 @@ function flattenError(error62, mapper = (issue2) => issue2.message) {
7155
7155
  }
7156
7156
  function formatError(error62, mapper = (issue2) => issue2.message) {
7157
7157
  const fieldErrors = { _errors: [] };
7158
- const processError = (error63, path77 = []) => {
7158
+ const processError = (error63, path78 = []) => {
7159
7159
  for (const issue2 of error63.issues) {
7160
7160
  if (issue2.code === "invalid_union" && issue2.errors.length) {
7161
- issue2.errors.map((issues) => processError({ issues }, [...path77, ...issue2.path]));
7161
+ issue2.errors.map((issues) => processError({ issues }, [...path78, ...issue2.path]));
7162
7162
  } else if (issue2.code === "invalid_key") {
7163
- processError({ issues: issue2.issues }, [...path77, ...issue2.path]);
7163
+ processError({ issues: issue2.issues }, [...path78, ...issue2.path]);
7164
7164
  } else if (issue2.code === "invalid_element") {
7165
- processError({ issues: issue2.issues }, [...path77, ...issue2.path]);
7165
+ processError({ issues: issue2.issues }, [...path78, ...issue2.path]);
7166
7166
  } else {
7167
- const fullpath = [...path77, ...issue2.path];
7167
+ const fullpath = [...path78, ...issue2.path];
7168
7168
  if (fullpath.length === 0) {
7169
7169
  fieldErrors._errors.push(mapper(issue2));
7170
7170
  } else {
@@ -7203,17 +7203,17 @@ function formatError(error62, mapper = (issue2) => issue2.message) {
7203
7203
  }
7204
7204
  function treeifyError(error62, mapper = (issue2) => issue2.message) {
7205
7205
  const result = { errors: [] };
7206
- const processError = (error63, path77 = []) => {
7206
+ const processError = (error63, path78 = []) => {
7207
7207
  var _a3;
7208
7208
  for (const issue2 of error63.issues) {
7209
7209
  if (issue2.code === "invalid_union" && issue2.errors.length) {
7210
- issue2.errors.map((issues) => processError({ issues }, [...path77, ...issue2.path]));
7210
+ issue2.errors.map((issues) => processError({ issues }, [...path78, ...issue2.path]));
7211
7211
  } else if (issue2.code === "invalid_key") {
7212
- processError({ issues: issue2.issues }, [...path77, ...issue2.path]);
7212
+ processError({ issues: issue2.issues }, [...path78, ...issue2.path]);
7213
7213
  } else if (issue2.code === "invalid_element") {
7214
- processError({ issues: issue2.issues }, [...path77, ...issue2.path]);
7214
+ processError({ issues: issue2.issues }, [...path78, ...issue2.path]);
7215
7215
  } else {
7216
- const fullpath = [...path77, ...issue2.path];
7216
+ const fullpath = [...path78, ...issue2.path];
7217
7217
  if (fullpath.length === 0) {
7218
7218
  result.errors.push(mapper(issue2));
7219
7219
  continue;
@@ -7252,8 +7252,8 @@ function treeifyError(error62, mapper = (issue2) => issue2.message) {
7252
7252
  }
7253
7253
  function toDotPath(_path) {
7254
7254
  const segs = [];
7255
- const path77 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
7256
- for (const seg of path77) {
7255
+ const path78 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
7256
+ for (const seg of path78) {
7257
7257
  if (typeof seg === "number")
7258
7258
  segs.push(`[${seg}]`);
7259
7259
  else if (typeof seg === "symbol")
@@ -24355,13 +24355,13 @@ function resolveRef(ref, ctx) {
24355
24355
  if (!ref.startsWith("#")) {
24356
24356
  throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
24357
24357
  }
24358
- const path77 = ref.slice(1).split("/").filter(Boolean);
24359
- if (path77.length === 0) {
24358
+ const path78 = ref.slice(1).split("/").filter(Boolean);
24359
+ if (path78.length === 0) {
24360
24360
  return ctx.rootSchema;
24361
24361
  }
24362
24362
  const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
24363
- if (path77[0] === defsKey) {
24364
- const key = path77[1] === void 0 ? void 0 : decodeJSONPointerSegment(path77[1]);
24363
+ if (path78[0] === defsKey) {
24364
+ const key = path78[1] === void 0 ? void 0 : decodeJSONPointerSegment(path78[1]);
24365
24365
  if (!key || !ctx.defs[key]) {
24366
24366
  throw new Error(`Reference not found: ${ref}`);
24367
24367
  }
@@ -25479,7 +25479,7 @@ var SandboxSchema = external_exports.strictObject({
25479
25479
  "When the sandbox (or this PC) runs low on memory, slow builds down in steps, like a PC that gets slower instead of failing: build programs get lower CPU and memory priority, then less CPU, then compilers take turns (the waiting ones briefly suspended and trimmed to the paging file). Nothing is stopped or killed, and the agents themselves are never touched. Yours only: a project file cannot change it."
25480
25480
  ),
25481
25481
  vGpu: external_exports.boolean().describe(
25482
- "Virtual GPU. Off by default: Microsoft notes it widens the sandbox attack surface. The sandbox then uses this PC's graphics card, and with some graphics drivers heavy use can freeze the whole PC: turn it on only when a program in the sandbox needs the GPU (the mesa toolchain gives software OpenGL without it)."
25482
+ "Virtual GPU. Off by default: Microsoft notes it widens the sandbox attack surface. The sandbox then uses this PC's graphics card, and with some graphics drivers heavy use can freeze the whole PC: turn it on only when a program in the sandbox needs the GPU (the mesa toolchain gives software OpenGL without it). Browsers in the sandbox never use it (they draw in software)."
25483
25483
  ),
25484
25484
  networking: external_exports.boolean().describe("Internet access. false is the only hard network isolation Windows Sandbox offers."),
25485
25485
  clipboard: external_exports.boolean().describe(
@@ -25641,6 +25641,21 @@ var ToolchainsSchema = external_exports.strictObject({
25641
25641
  msvcVersion: external_exports.string().min(1).describe('"latest" or an MSVC tools version prefix, e.g. "14.44".'),
25642
25642
  sdkVersion: external_exports.string().min(1).describe('"latest" or a Windows SDK build, e.g. "26100" or "10.0.22621".')
25643
25643
  }),
25644
+ unreal: external_exports.strictObject({
25645
+ enabled: enabled(
25646
+ "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.",
25647
+ "a .uproject or .uplugin"
25648
+ ),
25649
+ acceptLicense: external_exports.boolean().describe(
25650
+ "Required to install: you accept the Visual Studio Community licence terms (https://visualstudio.microsoft.com/license-terms/) and the DirectX End-User Runtime licence."
25651
+ ),
25652
+ components: StringsSchema.describe(
25653
+ 'More Visual Studio workload or component IDs to add, e.g. ["Microsoft.VisualStudio.Component.VC.Llvm.Clang"].'
25654
+ ),
25655
+ keepInstallFiles: external_exports.boolean().describe(
25656
+ "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."
25657
+ )
25658
+ }),
25644
25659
  cpp: external_exports.strictObject({
25645
25660
  enabled: enabled(
25646
25661
  "MinGW-w64 GCC with CMake, Ninja, premake5 and mingw32-make (also Rust's linker).",
@@ -27792,8 +27807,8 @@ function writeStatus(phase, message) {
27792
27807
  }
27793
27808
 
27794
27809
  // src/guest/boot/boot.ts
27795
- import fs62 from "node:fs";
27796
- import path75 from "node:path";
27810
+ import fs63 from "node:fs";
27811
+ import path76 from "node:path";
27797
27812
  import { spawn as spawn10 } from "node:child_process";
27798
27813
 
27799
27814
  // src/guest/boot/guide.ts
@@ -28623,6 +28638,7 @@ var MARKERS = {
28623
28638
  ],
28624
28639
  rust: ["Cargo.toml", "rust-toolchain", "rust-toolchain.toml"],
28625
28640
  msvc: ["*.vcxproj", "CMakePresets.json", "CMakeUserPresets.json"],
28641
+ unreal: ["*.uproject", "*.uplugin"],
28626
28642
  cpp: [
28627
28643
  "CMakeLists.txt",
28628
28644
  "Makefile",
@@ -30258,25 +30274,221 @@ async function setupMsvc(env, config2) {
30258
30274
  env.summary.push("msvc: " + done.msvc + ", Windows SDK " + done.sdk + " (cl, link; vcvars64.bat and vswhere work)");
30259
30275
  }
30260
30276
 
30261
- // src/guest/toolchains/native/rust.ts
30277
+ // src/guest/toolchains/native/unreal.ts
30278
+ import fs36 from "node:fs";
30279
+ import os7 from "node:os";
30262
30280
  import path44 from "node:path";
30263
30281
 
30264
- // src/guest/toolchains/native/binstall.ts
30282
+ // src/guest/toolchains/native/vcruntime.ts
30265
30283
  import fs35 from "node:fs";
30266
30284
  import path43 from "node:path";
30285
+ var VC_REDIST = "https://aka.ms/vs/17/release/vc_redist.x64.exe";
30286
+ var MICROSOFT_SIGNER = "CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US";
30287
+ var OK_EXIT_CODES = [0, 1638, 3010];
30288
+ var signerOf = (file3) => scriptOutput("get-signer.ps1", ["-Path", file3]).trim();
30289
+ async function setupVcRuntime(env, summary = true) {
30290
+ if (dryRun) {
30291
+ log("(dry run) would install the Visual C++ runtime");
30292
+ return false;
30293
+ }
30294
+ const system322 = path43.join(process.env.WINDIR ?? "C:\\Windows", "System32");
30295
+ const missing = !exists(path43.join(system322, "vcruntime140.dll")) || !exists(path43.join(system322, "msvcp140.dll"));
30296
+ if (missing) {
30297
+ const installer = tool("vcredist", "vc_redist.x64.exe");
30298
+ if (!exists(installer)) {
30299
+ log("Downloading the Visual C++ runtime (~25 MB once) ...");
30300
+ await downloadFile(VC_REDIST, installer);
30301
+ }
30302
+ if (signerOf(installer) !== MICROSOFT_SIGNER) {
30303
+ fs35.rmSync(installer, { force: true });
30304
+ throw new Error("vc_redist.x64.exe is not signed by Microsoft; deleted it (it is downloaded again next boot)");
30305
+ }
30306
+ log("Installing the Visual C++ runtime ...");
30307
+ const code = await spawnAsync(installer, ["/install", "/quiet", "/norestart"]);
30308
+ if (!OK_EXIT_CODES.includes(code ?? -1) || !exists(path43.join(system322, "vcruntime140.dll")))
30309
+ throw new Error("the Visual C++ runtime installer failed (exit " + code + ")");
30310
+ }
30311
+ if (summary) env.summary.push("vc++ runtime: installed");
30312
+ return missing;
30313
+ }
30314
+
30315
+ // src/guest/toolchains/native/unreal.ts
30316
+ var BOOTSTRAPPER_URL = "https://aka.ms/vs/17/release/vs_community.exe";
30317
+ var DIRECTX_URL = "https://download.microsoft.com/download/8/4/A/84A35BF1-DAFE-4AE8-82AF-AD2AE20B6B14/directx_Jun2010_redist.exe";
30318
+ var UNREAL_COMPONENTS = [
30319
+ "Microsoft.VisualStudio.Workload.NativeGame",
30320
+ "Microsoft.VisualStudio.Component.VC.Tools.x86.x64",
30321
+ "Microsoft.VisualStudio.Component.Windows11SDK.22621",
30322
+ "Microsoft.VisualStudio.Component.VC.DiagnosticTools",
30323
+ "Microsoft.Net.Component.4.6.2.TargetingPack",
30324
+ "Microsoft.Net.Component.4.8.SDK",
30325
+ "Component.Unreal.Ide",
30326
+ "Component.Unreal"
30327
+ ];
30328
+ var OK_EXIT_CODES2 = [0, 3010];
30329
+ var LAYOUT_ROOM_BYTES = 15 * 1024 ** 3;
30330
+ var ID = /^[A-Za-z0-9][A-Za-z0-9._-]{0,199}$/;
30331
+ var VS_DIR = tool("visualstudio");
30332
+ var BOOTSTRAPPER = path44.join(VS_DIR, "vs_community.exe");
30333
+ var LAYOUT = path44.join(VS_DIR, "layout");
30334
+ var LAYOUT_MARKER = path44.join(LAYOUT, ".complete.json");
30335
+ var LayoutSchema = external_exports.object({ components: external_exports.array(external_exports.string()) });
30336
+ var VSWHERE = path44.join(
30337
+ process.env["ProgramFiles(x86)"] ?? "C:\\Program Files (x86)",
30338
+ "Microsoft Visual Studio",
30339
+ "Installer",
30340
+ "vswhere.exe"
30341
+ );
30342
+ function installedVs() {
30343
+ if (!exists(VSWHERE)) return null;
30344
+ const ask = (property) => execOutput(VSWHERE, [
30345
+ "-latest",
30346
+ "-products",
30347
+ "*",
30348
+ "-requires",
30349
+ "Microsoft.VisualStudio.Component.VC.Tools.x86.x64",
30350
+ "-property",
30351
+ property
30352
+ ]);
30353
+ const at = ask("installationPath");
30354
+ return at ? { path: at, version: ask("installationVersion") || "installed" } : null;
30355
+ }
30356
+ async function signedInstaller(url2, file3, what) {
30357
+ if (!exists(file3)) {
30358
+ log("Downloading " + what + " ...");
30359
+ mkdirp(path44.dirname(file3));
30360
+ await downloadFile(url2, file3);
30361
+ }
30362
+ if (signerOf(file3) !== MICROSOFT_SIGNER) {
30363
+ fs36.rmSync(file3, { force: true });
30364
+ throw new Error(path44.basename(file3) + " is not signed by Microsoft; deleted it (it is downloaded again next boot)");
30365
+ }
30366
+ return file3;
30367
+ }
30368
+ function freeBytes(dir) {
30369
+ try {
30370
+ const s = fs36.statfsSync(dir);
30371
+ return s.bavail * s.bsize;
30372
+ } catch {
30373
+ return 0;
30374
+ }
30375
+ }
30376
+ async function layoutInstaller(bootstrapper, ids) {
30377
+ const installer = path44.join(LAYOUT, "vs_community.exe");
30378
+ const has = () => {
30379
+ if (!exists(LAYOUT_MARKER) || !exists(installer)) return false;
30380
+ try {
30381
+ const done = LayoutSchema.parse(JSON.parse(fs36.readFileSync(LAYOUT_MARKER, "utf8")));
30382
+ return ids.every((id) => done.components.includes(id));
30383
+ } catch {
30384
+ return false;
30385
+ }
30386
+ };
30387
+ if (has()) return installer;
30388
+ if (freeBytes(mkdirp(VS_DIR)) < LAYOUT_ROOM_BYTES) {
30389
+ warn("unreal: not keeping the install files (less than 15 GB free in " + VS_DIR + "); downloading this boot");
30390
+ return null;
30391
+ }
30392
+ log("Saving the Visual Studio install files for later boots (~10 GB, once) ...");
30393
+ fs36.rmSync(LAYOUT_MARKER, { force: true });
30394
+ const code = await spawnAsync(bootstrapper, [
30395
+ "--layout",
30396
+ LAYOUT,
30397
+ "--lang",
30398
+ "en-US",
30399
+ "--quiet",
30400
+ "--wait",
30401
+ ...ids.flatMap((id) => ["--add", id])
30402
+ ]);
30403
+ if (!OK_EXIT_CODES2.includes(code) || !exists(installer)) {
30404
+ warn("unreal: saving the install files failed (exit " + code + "); downloading this boot");
30405
+ return null;
30406
+ }
30407
+ writeJsonAtomic(LAYOUT_MARKER, { components: [...ids] });
30408
+ return installer;
30409
+ }
30410
+ async function installVisualStudio(config2, ids) {
30411
+ const bootstrapper = await signedInstaller(BOOTSTRAPPER_URL, BOOTSTRAPPER, "the Visual Studio installer");
30412
+ let installer = null;
30413
+ if (config2.keepInstallFiles) {
30414
+ try {
30415
+ installer = await layoutInstaller(bootstrapper, ids);
30416
+ } catch (e) {
30417
+ warn("unreal: the offline copy failed (" + errMsg(e) + "); downloading this boot");
30418
+ }
30419
+ }
30420
+ log(
30421
+ "Installing Visual Studio Community 2022 with the C++ game workload" + (installer ? " from the saved install files" : " (downloads ~5-8 GB)") + " ..."
30422
+ );
30423
+ const code = await spawnAsync(installer ?? bootstrapper, [
30424
+ "--quiet",
30425
+ "--wait",
30426
+ "--norestart",
30427
+ "--nocache",
30428
+ ...installer ? ["--noWeb"] : [],
30429
+ ...ids.flatMap((id) => ["--add", id])
30430
+ ]);
30431
+ if (!OK_EXIT_CODES2.includes(code) || !installedVs())
30432
+ throw new Error(
30433
+ "the Visual Studio installer failed (exit " + code + "); its logs are the dd_*.log files in " + os7.tmpdir()
30434
+ );
30435
+ }
30436
+ async function installDirectX() {
30437
+ const system322 = path44.join(process.env.WINDIR ?? "C:\\Windows", "System32");
30438
+ if (exists(path44.join(system322, "d3dx9_43.dll")) && exists(path44.join(system322, "XAudio2_7.dll"))) return;
30439
+ const redist = await signedInstaller(
30440
+ DIRECTX_URL,
30441
+ path44.join(VS_DIR, "directx_Jun2010_redist.exe"),
30442
+ "the DirectX End-User Runtime (~95 MB once)"
30443
+ );
30444
+ const unpacked = path44.join(os7.tmpdir(), "directx-redist");
30445
+ safeRemove(unpacked, os7.tmpdir());
30446
+ mkdirp(unpacked);
30447
+ if (await spawnAsync(redist, ["/Q", "/T:" + unpacked]) !== 0 || !exists(path44.join(unpacked, "DXSETUP.exe")))
30448
+ throw new Error("could not unpack the DirectX End-User Runtime");
30449
+ const code = await spawnAsync(path44.join(unpacked, "DXSETUP.exe"), ["/silent"]);
30450
+ safeRemove(unpacked, os7.tmpdir());
30451
+ if (code !== 0) throw new Error("the DirectX End-User Runtime installer failed (exit " + code + ")");
30452
+ }
30453
+ async function setupUnreal(env, config2) {
30454
+ if (!config2.acceptLicense)
30455
+ throw new Error(
30456
+ "Unreal tools are installed only with toolchains.unreal.acceptLicense = true: Visual Studio Community and the DirectX End-User Runtime come under Microsoft licence terms (https://visualstudio.microsoft.com/license-terms/)"
30457
+ );
30458
+ const bad = config2.components.find((id) => !ID.test(id));
30459
+ if (bad) throw new Error('toolchains.unreal.components: "' + bad + '" is not a Visual Studio component ID');
30460
+ const ids = [.../* @__PURE__ */ new Set([...UNREAL_COMPONENTS, ...config2.components])];
30461
+ if (dryRun) {
30462
+ log("(dry run) would install Visual Studio Community 2022 with " + ids.join(", ") + " and DirectX");
30463
+ return;
30464
+ }
30465
+ if (!installedVs()) await installVisualStudio(config2, ids);
30466
+ await installDirectX();
30467
+ const vs = installedVs();
30468
+ env.summary.push(
30469
+ "unreal: Visual Studio Community " + vs.version + " (C++ game workload, Windows 11 SDK, Unreal support) at " + vs.path + "; DirectX End-User Runtime; get the engine from the Epic Games Launcher (Start menu)"
30470
+ );
30471
+ }
30472
+
30473
+ // src/guest/toolchains/native/rust.ts
30474
+ import path46 from "node:path";
30475
+
30476
+ // src/guest/toolchains/native/binstall.ts
30477
+ import fs37 from "node:fs";
30478
+ import path45 from "node:path";
30267
30479
  var ensureBinstall = async (cargoBin) => {
30268
- const target = path43.join(cargoBin, "cargo-binstall.exe");
30480
+ const target = path45.join(cargoBin, "cargo-binstall.exe");
30269
30481
  if (exists(target)) return true;
30270
30482
  try {
30271
30483
  const dir = tool("cargo-binstall");
30272
- if (!exists(path43.join(dir, "cargo-binstall.exe"))) {
30484
+ if (!exists(path45.join(dir, "cargo-binstall.exe"))) {
30273
30485
  await installFromGithub("cargo-bins/cargo-binstall", binstallAsset(arch), {
30274
30486
  dest: dir,
30275
30487
  what: "cargo-binstall for prebuilt Rust tools (~10 MB once)",
30276
30488
  locate: "cargo-binstall.exe"
30277
30489
  });
30278
30490
  }
30279
- fs35.copyFileSync(path43.join(dir, "cargo-binstall.exe"), target);
30491
+ fs37.copyFileSync(path45.join(dir, "cargo-binstall.exe"), target);
30280
30492
  return true;
30281
30493
  } catch (e) {
30282
30494
  warn("cargo-binstall unavailable, compiling crates with cargo install instead: " + errMsg(e));
@@ -30284,14 +30496,14 @@ var ensureBinstall = async (cargoBin) => {
30284
30496
  }
30285
30497
  };
30286
30498
  function crateInstaller(cargoHome, cargoEnv) {
30287
- const cargo = path43.join(cargoHome, "bin", "cargo.exe");
30499
+ const cargo = path45.join(cargoHome, "bin", "cargo.exe");
30288
30500
  let binstall = null;
30289
30501
  const binstallEnv = {
30290
30502
  ...cargoEnv,
30291
30503
  env: { ...cargoEnv.env ?? process.env, BINSTALL_DISABLE_TELEMETRY: "true" }
30292
30504
  };
30293
30505
  return async (crate) => {
30294
- binstall ??= ensureBinstall(path43.join(cargoHome, "bin"));
30506
+ binstall ??= ensureBinstall(path45.join(cargoHome, "bin"));
30295
30507
  if (await binstall) {
30296
30508
  try {
30297
30509
  await execAsync(
@@ -30313,7 +30525,7 @@ async function setupRust(env, config2, refresh) {
30313
30525
  const RUSTUP_HOME = tool("rust", "rustup");
30314
30526
  const CARGO_HOME = tool("rust", "cargo");
30315
30527
  const rustEnv = { env: { ...process.env, RUSTUP_HOME, CARGO_HOME } };
30316
- const rustup = path44.join(CARGO_HOME, "bin", "rustup.exe");
30528
+ const rustup = path46.join(CARGO_HOME, "bin", "rustup.exe");
30317
30529
  if (dryRun) {
30318
30530
  log("(dry run) would provision Rust " + config2.toolchain + " (" + config2.host + ")");
30319
30531
  return;
@@ -30349,9 +30561,9 @@ async function setupRust(env, config2, refresh) {
30349
30561
  if (refresh) await execAsync(rustup, ["update"], rustEnv);
30350
30562
  }
30351
30563
  Object.assign(env.vars, { RUSTUP_HOME, CARGO_HOME });
30352
- env.prepend.push(path44.join(CARGO_HOME, "bin"));
30564
+ env.prepend.push(path46.join(CARGO_HOME, "bin"));
30353
30565
  env.summary.push(
30354
- "rust: " + versionOf(path44.join(CARGO_HOME, "bin", "rustc.exe"), ["--version"], rustEnv) + " [" + config2.host + "]"
30566
+ "rust: " + versionOf(path46.join(CARGO_HOME, "bin", "rustc.exe"), ["--version"], rustEnv) + " [" + config2.host + "]"
30355
30567
  );
30356
30568
  const toolchainKey = "rustup@" + config2.toolchain;
30357
30569
  await installOnce(
@@ -30372,36 +30584,36 @@ async function setupRust(env, config2, refresh) {
30372
30584
  env: {
30373
30585
  ...rustEnv.env,
30374
30586
  ...msvc.vars,
30375
- PATH: [path44.join(CARGO_HOME, "bin"), ...msvc.path, process.env.PATH ?? ""].join(path44.delimiter)
30587
+ PATH: [path46.join(CARGO_HOME, "bin"), ...msvc.path, process.env.PATH ?? ""].join(path46.delimiter)
30376
30588
  }
30377
30589
  } : {
30378
30590
  env: {
30379
30591
  ...rustEnv.env,
30380
- CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER: path44.join(mingw, "gcc.exe"),
30381
- PATH: [path44.join(CARGO_HOME, "bin"), mingw, process.env.PATH ?? ""].join(path44.delimiter)
30592
+ CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER: path46.join(mingw, "gcc.exe"),
30593
+ PATH: [path46.join(CARGO_HOME, "bin"), mingw, process.env.PATH ?? ""].join(path46.delimiter)
30382
30594
  }
30383
30595
  };
30384
30596
  await installOnce(env, "cargo", config2.crates, crateInstaller(CARGO_HOME, cargoEnv));
30385
30597
  }
30386
30598
 
30387
30599
  // src/guest/toolchains/languages/node.ts
30388
- import fs36 from "node:fs";
30389
- import path45 from "node:path";
30600
+ import fs38 from "node:fs";
30601
+ import path47 from "node:path";
30390
30602
  import { spawn as spawn4 } from "node:child_process";
30391
30603
  var NVM_HOME = tool("nvm");
30392
- var NVM_SYMLINK = path45.join(localDir, "nodejs");
30393
- var HOST_NVM = path45.join(hostToolsDir, "nvm");
30604
+ var NVM_SYMLINK = path47.join(localDir, "nodejs");
30605
+ var HOST_NVM = path47.join(hostToolsDir, "nvm");
30394
30606
  var HOST_VERSIONS_MAX = 3;
30395
- var hostNvmVersions = () => exists(HOST_NVM) ? fs36.readdirSync(HOST_NVM).filter((d) => /^v\d+\.\d+\.\d+$/.test(d) && exists(path45.join(HOST_NVM, d, "node.exe"))).map((d) => d.slice(1)) : [];
30607
+ var hostNvmVersions = () => exists(HOST_NVM) ? fs38.readdirSync(HOST_NVM).filter((d) => /^v\d+\.\d+\.\d+$/.test(d) && exists(path47.join(HOST_NVM, d, "node.exe"))).map((d) => d.slice(1)) : [];
30396
30608
  var resolveNode = (spec) => resolveCached("node:" + spec, async () => {
30397
30609
  const exact = spec.replace(/^v/, "");
30398
30610
  if (/^\d+\.\d+\.\d+$/.test(exact)) return exact;
30399
30611
  const releases = await fetchJson("https://nodejs.org/dist/index.json");
30400
30612
  return pickNodeVersion(releases, spec) ?? Promise.reject(new Error('No Node.js release matches "' + spec + '"'));
30401
30613
  });
30402
- var NVM_TEMP = path45.join(NVM_HOME, ".tmp");
30614
+ var NVM_TEMP = path47.join(NVM_HOME, ".tmp");
30403
30615
  var nvm = (args) => new Promise((resolve2) => {
30404
- const child = spawn4(path45.join(NVM_HOME, "nvm.exe"), args, {
30616
+ const child = spawn4(path47.join(NVM_HOME, "nvm.exe"), args, {
30405
30617
  windowsHide: true,
30406
30618
  env: { ...process.env, NVM_HOME, NVM_SYMLINK, TEMP: NVM_TEMP, TMP: NVM_TEMP }
30407
30619
  });
@@ -30416,12 +30628,12 @@ var nvm = (args) => new Promise((resolve2) => {
30416
30628
  child.once("close", () => resolve2(out));
30417
30629
  });
30418
30630
  var ensureNvm = async () => {
30419
- if (exists(path45.join(NVM_HOME, "nvm.exe"))) return;
30420
- if (exists(path45.join(HOST_NVM, "nvm.exe"))) {
30631
+ if (exists(path47.join(NVM_HOME, "nvm.exe"))) return;
30632
+ if (exists(path47.join(HOST_NVM, "nvm.exe"))) {
30421
30633
  log("Copying nvm from this PC ...");
30422
30634
  mkdirp(NVM_HOME);
30423
- const files = fs36.readdirSync(HOST_NVM).filter((f) => /\.(exe|cmd|vbs)$/i.test(f)).sort((a, b) => Number(a.toLowerCase() === "nvm.exe") - Number(b.toLowerCase() === "nvm.exe"));
30424
- for (const file3 of files) fs36.copyFileSync(path45.join(HOST_NVM, file3), path45.join(NVM_HOME, file3));
30635
+ const files = fs38.readdirSync(HOST_NVM).filter((f) => /\.(exe|cmd|vbs)$/i.test(f)).sort((a, b) => Number(a.toLowerCase() === "nvm.exe") - Number(b.toLowerCase() === "nvm.exe"));
30636
+ for (const file3 of files) fs38.copyFileSync(path47.join(HOST_NVM, file3), path47.join(NVM_HOME, file3));
30425
30637
  return;
30426
30638
  }
30427
30639
  const asset = await githubAsset("coreybutler/nvm-windows", /^nvm-noinstall\.zip$/, true);
@@ -30429,14 +30641,14 @@ var ensureNvm = async () => {
30429
30641
  await downloader.archive(asset.url, NVM_HOME, { sha256: asset.sha256, locate: "nvm.exe", fileName: asset.name });
30430
30642
  };
30431
30643
  var hostNodeFolder = (version2) => {
30432
- const dir = path45.join(hostToolsDir, "node");
30433
- return session.hostTools.nodeVersion?.replace(/^v/, "") === version2 && exists(path45.join(dir, "node.exe")) ? dir : null;
30644
+ const dir = path47.join(hostToolsDir, "node");
30645
+ return session.hostTools.nodeVersion?.replace(/^v/, "") === version2 && exists(path47.join(dir, "node.exe")) ? dir : null;
30434
30646
  };
30435
30647
  var installNodeVersion = async (version2) => {
30436
- const dir = path45.join(NVM_HOME, "v" + version2);
30437
- const fromHost = path45.join(HOST_NVM, "v" + version2);
30438
- if (exists(path45.join(dir, "node.exe"))) return;
30439
- if (exists(path45.join(fromHost, "node.exe"))) {
30648
+ const dir = path47.join(NVM_HOME, "v" + version2);
30649
+ const fromHost = path47.join(HOST_NVM, "v" + version2);
30650
+ if (exists(path47.join(dir, "node.exe"))) return;
30651
+ if (exists(path47.join(fromHost, "node.exe"))) {
30440
30652
  log("Copying Node " + version2 + " from this PC's nvm (without global packages) ...");
30441
30653
  copyNode(fromHost, dir);
30442
30654
  return;
@@ -30455,19 +30667,19 @@ var installNodeVersion = async (version2) => {
30455
30667
  } finally {
30456
30668
  safeRemove(NVM_TEMP, NVM_HOME);
30457
30669
  }
30458
- if (!exists(path45.join(dir, "node.exe"))) {
30670
+ if (!exists(path47.join(dir, "node.exe"))) {
30459
30671
  const tail2 = out.trim().split(/\r?\n/).filter(Boolean).slice(-3).join(" ");
30460
30672
  const why = /complete/i.test(out) ? "nvm said it finished, but its move into the data folder did not happen" : "nvm could not download or unpack it: check the internet connection and the free disk space";
30461
30673
  throw new Error(
30462
- "nvm install " + version2 + " did not leave " + path45.join(dir, "node.exe") + " (" + why + ")" + (tail2 ? ". nvm printed: " + tail2 : "")
30674
+ "nvm install " + version2 + " did not leave " + path47.join(dir, "node.exe") + " (" + why + ")" + (tail2 ? ". nvm printed: " + tail2 : "")
30463
30675
  );
30464
30676
  }
30465
30677
  };
30466
30678
  var activate = async (version2) => {
30467
30679
  await nvm(["use", version2]);
30468
- if (exists(path45.join(NVM_SYMLINK, "node.exe"))) return;
30469
- fs36.rmSync(NVM_SYMLINK, { recursive: true, force: true });
30470
- fs36.symlinkSync(path45.join(NVM_HOME, "v" + version2), NVM_SYMLINK, "junction");
30680
+ if (exists(path47.join(NVM_SYMLINK, "node.exe"))) return;
30681
+ fs38.rmSync(NVM_SYMLINK, { recursive: true, force: true });
30682
+ fs38.symlinkSync(path47.join(NVM_HOME, "v" + version2), NVM_SYMLINK, "junction");
30471
30683
  };
30472
30684
  var PLAYWRIGHT_VARS = () => ({
30473
30685
  PLAYWRIGHT_BROWSERS_PATH: tool("ms-playwright"),
@@ -30479,8 +30691,8 @@ async function setupNode(env, versions, config2) {
30479
30691
  return;
30480
30692
  }
30481
30693
  await ensureNvm();
30482
- fs36.writeFileSync(
30483
- path45.join(NVM_HOME, "settings.txt"),
30694
+ fs38.writeFileSync(
30695
+ path47.join(NVM_HOME, "settings.txt"),
30484
30696
  [
30485
30697
  "root: " + NVM_HOME,
30486
30698
  "path: " + NVM_SYMLINK,
@@ -30507,7 +30719,7 @@ async function setupNode(env, versions, config2) {
30507
30719
  }
30508
30720
  }
30509
30721
  Object.assign(env.vars, { NVM_HOME, NVM_SYMLINK, ...PLAYWRIGHT_VARS() });
30510
- if (duringSession()) env.prepend.push(path45.join(NVM_HOME, "v" + main), NVM_HOME, NVM_SYMLINK);
30722
+ if (duringSession()) env.prepend.push(path47.join(NVM_HOME, "v" + main), NVM_HOME, NVM_SYMLINK);
30511
30723
  else {
30512
30724
  await activate(main);
30513
30725
  env.prepend.push(NVM_HOME, NVM_SYMLINK);
@@ -30517,13 +30729,13 @@ async function setupNode(env, versions, config2) {
30517
30729
  await packageManagers(env, config2, main);
30518
30730
  }
30519
30731
  var packageManagers = async (env, config2, version2) => {
30520
- const dir = path45.join(NVM_HOME, "v" + version2);
30521
- const nodeEnv = { ...process.env, PATH: dir + path45.delimiter + (process.env.PATH ?? "") };
30522
- const npm = (args) => execAsync(path45.join(dir, "node.exe"), [path45.join(dir, "node_modules", "npm", "bin", "npm-cli.js"), ...args], {
30732
+ const dir = path47.join(NVM_HOME, "v" + version2);
30733
+ const nodeEnv = { ...process.env, PATH: dir + path47.delimiter + (process.env.PATH ?? "") };
30734
+ const npm = (args) => execAsync(path47.join(dir, "node.exe"), [path47.join(dir, "node_modules", "npm", "bin", "npm-cli.js"), ...args], {
30523
30735
  env: nodeEnv,
30524
30736
  stdio: "ignore"
30525
30737
  });
30526
- const corepackJs = path45.join(dir, "node_modules", "corepack", "dist", "corepack.js");
30738
+ const corepackJs = path47.join(dir, "node_modules", "corepack", "dist", "corepack.js");
30527
30739
  const extra = config2.corepack && !exists(corepackJs) ? ["corepack"] : [];
30528
30740
  await installOnce(
30529
30741
  env,
@@ -30544,7 +30756,7 @@ var packageManagers = async (env, config2, version2) => {
30544
30756
  }
30545
30757
  try {
30546
30758
  await execAsync(
30547
- path45.join(dir, "node.exe"),
30759
+ path47.join(dir, "node.exe"),
30548
30760
  [corepackJs, "enable", "--install-directory", mkdirp(tool("bin")), "pnpm", "yarn"],
30549
30761
  { env: nodeEnv, stdio: "ignore" }
30550
30762
  );
@@ -30569,8 +30781,8 @@ async function setupPwsh(env, refresh = false) {
30569
30781
  }
30570
30782
 
30571
30783
  // src/guest/toolchains/languages/python.ts
30572
- import fs37 from "node:fs";
30573
- import path46 from "node:path";
30784
+ import fs39 from "node:fs";
30785
+ import path48 from "node:path";
30574
30786
  var installPython = async (pkg, spec) => {
30575
30787
  const version2 = await resolveCached(pkg + ":" + spec, async () => {
30576
30788
  const { versions } = await fetchJson(
@@ -30579,7 +30791,7 @@ var installPython = async (pkg, spec) => {
30579
30791
  return pickPackageVersion(versions, spec) ?? Promise.reject(new Error("No " + pkg + ' release matches "' + spec + '"'));
30580
30792
  });
30581
30793
  const dir = tool("python", pkg + "-" + version2);
30582
- const exe = path46.join(dir, "python.exe");
30794
+ const exe = path48.join(dir, "python.exe");
30583
30795
  if (!exists(exe)) {
30584
30796
  log("Downloading Python " + version2 + (pkg === "python2" ? " (Python 2, " : " (") + "~30 MB once) ...");
30585
30797
  await downloader.archive(
@@ -30588,32 +30800,32 @@ var installPython = async (pkg, spec) => {
30588
30800
  { locate: "python.exe", fileName: pkg + "." + version2 + ".zip" }
30589
30801
  );
30590
30802
  }
30591
- if (!exists(path46.join(dir, "Scripts", "pip.exe")) && !exists(path46.join(dir, "Scripts", "pip2.exe")))
30803
+ if (!exists(path48.join(dir, "Scripts", "pip.exe")) && !exists(path48.join(dir, "Scripts", "pip2.exe")))
30592
30804
  await execAsync(exe, ["-m", "ensurepip", "--default-pip"], { stdio: "ignore" });
30593
30805
  return dir;
30594
30806
  };
30595
- var shimDir = (dir) => duringSession() ? tool("shims", path46.basename(dir)) : tool("shims");
30807
+ var shimDir = (dir) => duringSession() ? tool("shims", path48.basename(dir)) : tool("shims");
30596
30808
  var shim = (folder, name, program, args = []) => {
30597
30809
  const fixed = [program, ...args];
30598
- fs37.writeFileSync(
30599
- path46.join(mkdirp(folder), name + ".cmd"),
30810
+ fs39.writeFileSync(
30811
+ path48.join(mkdirp(folder), name + ".cmd"),
30600
30812
  "@echo off\r\n" + fixed.map((a) => '"' + a + '"').join(" ") + " %*\r\n"
30601
30813
  );
30602
30814
  const sh = fixed.map((a) => "'" + a.replace(/\\/g, "/").replace(/'/g, "'\\''") + "'").join(" ");
30603
- fs37.writeFileSync(path46.join(folder, name), "#!/bin/sh\nexec " + sh + ' "$@"\n');
30815
+ fs39.writeFileSync(path48.join(folder, name), "#!/bin/sh\nexec " + sh + ' "$@"\n');
30604
30816
  };
30605
30817
  var shimPair = (folder, version2, dir) => {
30606
- const python = path46.join(dir, "python.exe");
30818
+ const python = path48.join(dir, "python.exe");
30607
30819
  shim(folder, "python" + version2, python);
30608
30820
  shim(folder, "pip" + version2, python, ["-m", "pip"]);
30609
30821
  };
30610
30822
  var pyLauncher = (folder, py3, py2) => {
30611
- const script = path46.join(mkdirp(folder), "py-launcher.py");
30612
- fs37.writeFileSync(
30823
+ const script = path48.join(mkdirp(folder), "py-launcher.py");
30824
+ fs39.writeFileSync(
30613
30825
  script,
30614
30826
  [
30615
30827
  "import subprocess, sys",
30616
- "PY3, PY2 = " + JSON.stringify(path46.join(py3, "python.exe")) + ", " + JSON.stringify(py2 ? path46.join(py2, "python.exe") : null),
30828
+ "PY3, PY2 = " + JSON.stringify(path48.join(py3, "python.exe")) + ", " + JSON.stringify(py2 ? path48.join(py2, "python.exe") : null),
30617
30829
  "args = sys.argv[1:]",
30618
30830
  "exe = PY3",
30619
30831
  "if args and args[0].startswith('-2'):",
@@ -30625,7 +30837,7 @@ var pyLauncher = (folder, py3, py2) => {
30625
30837
  ""
30626
30838
  ].join("\n")
30627
30839
  );
30628
- shim(folder, "py", path46.join(py3, "python.exe"), [script]);
30840
+ shim(folder, "py", path48.join(py3, "python.exe"), [script]);
30629
30841
  };
30630
30842
  async function setupPython(env, config2, versions) {
30631
30843
  if (dryRun) {
@@ -30635,10 +30847,10 @@ async function setupPython(env, config2, versions) {
30635
30847
  const py3 = await installPython("python", versions.python.spec);
30636
30848
  const shims = shimDir(py3);
30637
30849
  shimPair(shims, "3", py3);
30638
- env.prepend.push(py3, mkdirp(path46.join(py3, "Scripts")), shims);
30850
+ env.prepend.push(py3, mkdirp(path48.join(py3, "Scripts")), shims);
30639
30851
  env.vars.PYTHONIOENCODING = "utf-8";
30640
30852
  env.summary.push(
30641
- "python: " + path46.basename(py3).replace("python-", "") + " (from " + versions.python.source + "; py works too)"
30853
+ "python: " + path48.basename(py3).replace("python-", "") + " (from " + versions.python.source + "; py works too)"
30642
30854
  );
30643
30855
  if (!config2.python2) {
30644
30856
  pyLauncher(shims, py3, null);
@@ -30647,47 +30859,12 @@ async function setupPython(env, config2, versions) {
30647
30859
  const py2 = await installPython("python2", "2.7");
30648
30860
  shimPair(shims, "2", py2);
30649
30861
  pyLauncher(shims, py3, py2);
30650
- env.summary.push("python2: " + path46.basename(py2).replace("python2-", ""));
30651
- }
30652
-
30653
- // src/guest/toolchains/languages/php.ts
30654
- import fs39 from "node:fs";
30655
- import path48 from "node:path";
30656
-
30657
- // src/guest/toolchains/native/vcruntime.ts
30658
- import fs38 from "node:fs";
30659
- import path47 from "node:path";
30660
- var VC_REDIST = "https://aka.ms/vs/17/release/vc_redist.x64.exe";
30661
- var MICROSOFT_SIGNER = "CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US";
30662
- var OK_EXIT_CODES = [0, 1638, 3010];
30663
- var signerOf = (file3) => scriptOutput("get-signer.ps1", ["-Path", file3]).trim();
30664
- async function setupVcRuntime(env, summary = true) {
30665
- if (dryRun) {
30666
- log("(dry run) would install the Visual C++ runtime");
30667
- return false;
30668
- }
30669
- const system322 = path47.join(process.env.WINDIR ?? "C:\\Windows", "System32");
30670
- const missing = !exists(path47.join(system322, "vcruntime140.dll")) || !exists(path47.join(system322, "msvcp140.dll"));
30671
- if (missing) {
30672
- const installer = tool("vcredist", "vc_redist.x64.exe");
30673
- if (!exists(installer)) {
30674
- log("Downloading the Visual C++ runtime (~25 MB once) ...");
30675
- await downloadFile(VC_REDIST, installer);
30676
- }
30677
- if (signerOf(installer) !== MICROSOFT_SIGNER) {
30678
- fs38.rmSync(installer, { force: true });
30679
- throw new Error("vc_redist.x64.exe is not signed by Microsoft; deleted it (it is downloaded again next boot)");
30680
- }
30681
- log("Installing the Visual C++ runtime ...");
30682
- const code = await spawnAsync(installer, ["/install", "/quiet", "/norestart"]);
30683
- if (!OK_EXIT_CODES.includes(code ?? -1) || !exists(path47.join(system322, "vcruntime140.dll")))
30684
- throw new Error("the Visual C++ runtime installer failed (exit " + code + ")");
30685
- }
30686
- if (summary) env.summary.push("vc++ runtime: installed");
30687
- return missing;
30862
+ env.summary.push("python2: " + path48.basename(py2).replace("python2-", ""));
30688
30863
  }
30689
30864
 
30690
30865
  // src/guest/toolchains/languages/php.ts
30866
+ import fs40 from "node:fs";
30867
+ import path49 from "node:path";
30691
30868
  var PHP_EXTENSIONS = [
30692
30869
  "curl",
30693
30870
  "fileinfo",
@@ -30718,16 +30895,16 @@ var phpBuild = async (spec) => {
30718
30895
  return { version: release.version, ...build.zip };
30719
30896
  };
30720
30897
  var writePhpIni = (home) => {
30721
- const ini = path48.join(home, "php.ini");
30722
- if (exists(ini) || !exists(path48.join(home, "php.ini-development"))) return;
30723
- let text = fs39.readFileSync(path48.join(home, "php.ini-development"), "utf8").replace(/^;\s*extension_dir\s*=\s*"ext"/m, 'extension_dir = "' + path48.join(home, "ext") + '"');
30724
- for (const ext of PHP_EXTENSIONS.filter((e) => exists(path48.join(home, "ext", "php_" + e + ".dll"))))
30898
+ const ini = path49.join(home, "php.ini");
30899
+ if (exists(ini) || !exists(path49.join(home, "php.ini-development"))) return;
30900
+ let text = fs40.readFileSync(path49.join(home, "php.ini-development"), "utf8").replace(/^;\s*extension_dir\s*=\s*"ext"/m, 'extension_dir = "' + path49.join(home, "ext") + '"');
30901
+ for (const ext of PHP_EXTENSIONS.filter((e) => exists(path49.join(home, "ext", "php_" + e + ".dll"))))
30725
30902
  text = text.replace(new RegExp("^;(extension=" + ext + ")\\s*$", "m"), "$1");
30726
- fs39.writeFileSync(ini + ".tmp", text);
30727
- fs39.renameSync(ini + ".tmp", ini);
30903
+ fs40.writeFileSync(ini + ".tmp", text);
30904
+ fs40.renameSync(ini + ".tmp", ini);
30728
30905
  };
30729
30906
  var shim2 = (env, name, command) => {
30730
- fs39.writeFileSync(path48.join(mkdirp(tool("shims")), name + ".cmd"), "@echo off\r\n" + command + " %*\r\n");
30907
+ fs40.writeFileSync(path49.join(mkdirp(tool("shims")), name + ".cmd"), "@echo off\r\n" + command + " %*\r\n");
30731
30908
  env.prepend.push(tool("shims"));
30732
30909
  };
30733
30910
  var setupComposer = async (env, php) => {
@@ -30739,7 +30916,7 @@ var setupComposer = async (env, php) => {
30739
30916
  }
30740
30917
  const composerHome = tool("composer-home");
30741
30918
  env.vars.COMPOSER_HOME = composerHome;
30742
- env.prepend.push(path48.join(composerHome, "vendor", "bin"));
30919
+ env.prepend.push(path49.join(composerHome, "vendor", "bin"));
30743
30920
  shim2(env, "composer", '"' + php + '" "' + phar + '"');
30744
30921
  env.summary.push(
30745
30922
  "composer: " + (/\d+\.\d+\.\d+/.exec(execOutput(php, [phar, "--version", "--no-ansi"]))?.[0] ?? "installed")
@@ -30754,7 +30931,7 @@ async function setupPhp(env, config2) {
30754
30931
  await setupVcRuntime(env, false);
30755
30932
  const version2 = await resolveCached("php:" + wantedSpec.spec, async () => (await phpBuild(wantedSpec.spec)).version);
30756
30933
  const home = tool("php", version2);
30757
- if (!exists(path48.join(home, "php.exe"))) {
30934
+ if (!exists(path49.join(home, "php.exe"))) {
30758
30935
  const build = await phpBuild(version2);
30759
30936
  log("Downloading PHP " + version2 + " (~30 MB once) ...");
30760
30937
  await downloader.archive("https://windows.php.net/downloads/releases/" + build.path, home, {
@@ -30766,11 +30943,11 @@ async function setupPhp(env, config2) {
30766
30943
  writePhpIni(home);
30767
30944
  env.prepend.push(home);
30768
30945
  env.summary.push("php: " + version2 + " (from " + wantedSpec.source + ")");
30769
- if (config2.composer) await setupComposer(env, path48.join(home, "php.exe"));
30946
+ if (config2.composer) await setupComposer(env, path49.join(home, "php.exe"));
30770
30947
  }
30771
30948
 
30772
30949
  // src/guest/toolchains/languages/ruby.ts
30773
- import path49 from "node:path";
30950
+ import path50 from "node:path";
30774
30951
  var RUBY_ASSET = /^rubyinstaller-(\d+\.\d+\.\d+)-(\d+)-x64\.7z$/;
30775
30952
  var buildNumber = (asset) => Number(RUBY_ASSET.exec(asset.name)?.[2] ?? 0);
30776
30953
  var rubyBuilds = async () => {
@@ -30798,7 +30975,7 @@ async function setupRuby(env, config2) {
30798
30975
  async () => pickPackageVersion([...(await rubyBuilds()).keys()], wantedSpec.spec) ?? Promise.reject(new Error('No RubyInstaller build matches "' + wantedSpec.spec + '"'))
30799
30976
  );
30800
30977
  const home = tool("ruby", version2);
30801
- if (!exists(path49.join(home, "bin", "ruby.exe"))) {
30978
+ if (!exists(path50.join(home, "bin", "ruby.exe"))) {
30802
30979
  const asset = (await rubyBuilds()).get(version2);
30803
30980
  if (!asset) throw new Error("RubyInstaller " + version2 + " is no longer published");
30804
30981
  log("Downloading Ruby " + version2 + " (~100 MB once) ...");
@@ -30811,11 +30988,11 @@ async function setupRuby(env, config2) {
30811
30988
  }
30812
30989
  const gems = tool("ruby-gems", version2.split(".").slice(0, 2).join("."));
30813
30990
  Object.assign(env.vars, { GEM_HOME: gems, BUNDLE_USER_HOME: tool("bundle-home") });
30814
- env.prepend.push(path49.join(home, "bin"), path49.join(gems, "bin"));
30991
+ env.prepend.push(path50.join(home, "bin"), path50.join(gems, "bin"));
30815
30992
  env.summary.push(
30816
- "ruby: " + versionOf(path49.join(home, "bin", "ruby.exe")) + " (from " + wantedSpec.source + "; gems with C extensions need MSYS2, not included)"
30993
+ "ruby: " + versionOf(path50.join(home, "bin", "ruby.exe")) + " (from " + wantedSpec.source + "; gems with C extensions need MSYS2, not included)"
30817
30994
  );
30818
- const gem = path49.join(home, "bin", "gem.cmd");
30995
+ const gem = path50.join(home, "bin", "gem.cmd");
30819
30996
  await installOnce(
30820
30997
  env,
30821
30998
  "gem@" + version2,
@@ -30827,9 +31004,9 @@ async function setupRuby(env, config2) {
30827
31004
  }
30828
31005
 
30829
31006
  // src/guest/toolchains/tools/vscode.ts
30830
- import fs40 from "node:fs";
30831
- import os7 from "node:os";
30832
- import path50 from "node:path";
31007
+ import fs41 from "node:fs";
31008
+ import os8 from "node:os";
31009
+ import path51 from "node:path";
30833
31010
  import { spawn as spawn5 } from "node:child_process";
30834
31011
 
30835
31012
  // node_modules/jsonc-parser/lib/esm/impl/scanner.js
@@ -31628,12 +31805,12 @@ function parseTree(text, errors = [], options = ParseOptions.DEFAULT) {
31628
31805
  }
31629
31806
  return result;
31630
31807
  }
31631
- function findNodeAtLocation(root, path77) {
31808
+ function findNodeAtLocation(root, path78) {
31632
31809
  if (!root) {
31633
31810
  return void 0;
31634
31811
  }
31635
31812
  let node2 = root;
31636
- for (let segment of path77) {
31813
+ for (let segment of path78) {
31637
31814
  if (typeof segment === "string") {
31638
31815
  if (node2.type !== "object" || !Array.isArray(node2.children)) {
31639
31816
  return void 0;
@@ -31987,14 +32164,14 @@ function getNodeType(value) {
31987
32164
 
31988
32165
  // node_modules/jsonc-parser/lib/esm/impl/edit.js
31989
32166
  function setProperty(text, originalPath, value, options) {
31990
- const path77 = originalPath.slice();
32167
+ const path78 = originalPath.slice();
31991
32168
  const errors = [];
31992
32169
  const root = parseTree(text, errors);
31993
32170
  let parent = void 0;
31994
32171
  let lastSegment = void 0;
31995
- while (path77.length > 0) {
31996
- lastSegment = path77.pop();
31997
- parent = findNodeAtLocation(root, path77);
32172
+ while (path78.length > 0) {
32173
+ lastSegment = path78.pop();
32174
+ parent = findNodeAtLocation(root, path78);
31998
32175
  if (parent === void 0 && value !== void 0) {
31999
32176
  if (typeof lastSegment === "string") {
32000
32177
  value = { [lastSegment]: value };
@@ -32180,8 +32357,8 @@ var ParseErrorCode;
32180
32357
  ParseErrorCode2[ParseErrorCode2["InvalidEscapeCharacter"] = 15] = "InvalidEscapeCharacter";
32181
32358
  ParseErrorCode2[ParseErrorCode2["InvalidCharacter"] = 16] = "InvalidCharacter";
32182
32359
  })(ParseErrorCode || (ParseErrorCode = {}));
32183
- function modify(text, path77, value, options) {
32184
- return setProperty(text, path77, value, options);
32360
+ function modify(text, path78, value, options) {
32361
+ return setProperty(text, path78, value, options);
32185
32362
  }
32186
32363
  function applyEdits(text, edits) {
32187
32364
  let sortedEdits = edits.slice(0).sort((a, b) => {
@@ -32282,7 +32459,7 @@ function missingExtensions(wanted2, folders) {
32282
32459
  var VERSION_MARKER = ".agent-sandbox-version";
32283
32460
  var desktopShortcut = (exe) => {
32284
32461
  if (!isWin) return;
32285
- const link = path50.join(os7.homedir(), "Desktop", "Visual Studio Code.lnk");
32462
+ const link = path51.join(os8.homedir(), "Desktop", "Visual Studio Code.lnk");
32286
32463
  runScriptWithJson("new-shortcuts.ps1", "ListFile", [
32287
32464
  { link, target: exe, arguments: '"' + (process.env.AGENT_WORKSPACE ?? "") + '"' }
32288
32465
  ]);
@@ -32290,16 +32467,16 @@ var desktopShortcut = (exe) => {
32290
32467
  var findIn = (dirs, ...names) => {
32291
32468
  for (const dir of dirs)
32292
32469
  for (const name of names) {
32293
- const file3 = path50.join(dir, name);
32470
+ const file3 = path51.join(dir, name);
32294
32471
  if (exists(file3)) return file3;
32295
32472
  }
32296
32473
  return void 0;
32297
32474
  };
32298
32475
  var recommendedBy = (workspace2) => {
32299
- const file3 = path50.join(workspace2, ".vscode", "extensions.json");
32476
+ const file3 = path51.join(workspace2, ".vscode", "extensions.json");
32300
32477
  try {
32301
- if (!exists(file3) || fs40.statSync(file3).size > 64 * 1024) return [];
32302
- const data = parse4(fs40.readFileSync(file3, "utf8"));
32478
+ if (!exists(file3) || fs41.statSync(file3).size > 64 * 1024) return [];
32479
+ const data = parse4(fs41.readFileSync(file3, "utf8"));
32303
32480
  return Array.isArray(data?.recommendations) ? data.recommendations.filter((r) => typeof r === "string" && EXTENSION_ID.test(r)).slice(0, 50) : [];
32304
32481
  } catch {
32305
32482
  return [];
@@ -32307,12 +32484,12 @@ var recommendedBy = (workspace2) => {
32307
32484
  };
32308
32485
  function configureVscode(tools, o) {
32309
32486
  const root = tool("vscode");
32310
- const code = path50.join(root, "bin", "code.cmd");
32487
+ const code = path51.join(root, "bin", "code.cmd");
32311
32488
  if (dryRun) {
32312
32489
  log("(dry run) would set up VS Code for: " + o.toolchains.join(", "));
32313
32490
  return;
32314
32491
  }
32315
- if (!exists(path50.join(root, "Code.exe"))) return;
32492
+ if (!exists(path51.join(root, "Code.exe"))) return;
32316
32493
  const dirs = [...tools.prepend, ...tools.append];
32317
32494
  const git = findIn([tool("git", "cmd"), ...dirs], "git.exe");
32318
32495
  const settings = vscodeSettings({
@@ -32327,14 +32504,14 @@ function configureVscode(tools, o) {
32327
32504
  node: findIn(dirs, "node.exe"),
32328
32505
  pwsh: findIn(dirs, "pwsh.exe"),
32329
32506
  git,
32330
- bash: git ? findIn([path50.join(path50.dirname(path50.dirname(git)), "bin")], "bash.exe") : void 0,
32507
+ bash: git ? findIn([path51.join(path51.dirname(path51.dirname(git)), "bin")], "bash.exe") : void 0,
32331
32508
  php: findIn(dirs, "php.exe"),
32332
32509
  ruby: findIn(dirs, "ruby.exe"),
32333
32510
  deno: findIn(dirs, "deno.exe")
32334
32511
  });
32335
32512
  writeManagedSettings(
32336
- path50.join(root, "data", "user-data", "User", "settings.json"),
32337
- path50.join(root, "data", ".agent-sandbox-managed.json"),
32513
+ path51.join(root, "data", "user-data", "User", "settings.json"),
32514
+ path51.join(root, "data", ".agent-sandbox-managed.json"),
32338
32515
  settings
32339
32516
  );
32340
32517
  const wanted2 = vscodeExtensions({
@@ -32345,7 +32522,7 @@ function configureVscode(tools, o) {
32345
32522
  });
32346
32523
  let folders = [];
32347
32524
  try {
32348
- folders = fs40.readdirSync(path50.join(root, "data", "extensions"));
32525
+ folders = fs41.readdirSync(path51.join(root, "data", "extensions"));
32349
32526
  } catch {
32350
32527
  }
32351
32528
  const missing = missingExtensions(wanted2, folders);
@@ -32353,19 +32530,19 @@ function configureVscode(tools, o) {
32353
32530
  "vscode: set up for " + (o.toolchains.join(", ") || "Node") + (missing.length ? "; installing " + missing.length + " extension(s) in the background" : "; extensions ready")
32354
32531
  );
32355
32532
  if (!missing.length) return;
32356
- const logFile2 = fs40.openSync(path50.join(logsDir, "vscode-extensions.log"), "a");
32533
+ const logFile2 = fs41.openSync(path51.join(logsDir, "vscode-extensions.log"), "a");
32357
32534
  spawn5(SYSTEM.cmd(), ["/d", "/c", code, ...missing.flatMap((id) => ["--install-extension", id])], {
32358
32535
  detached: true,
32359
32536
  stdio: ["ignore", logFile2, logFile2],
32360
32537
  windowsHide: true
32361
32538
  }).unref();
32362
- fs40.closeSync(logFile2);
32539
+ fs41.closeSync(logFile2);
32363
32540
  }
32364
32541
  var writeManagedSettings = (file3, managedFile, values) => {
32365
- let text = exists(file3) ? fs40.readFileSync(file3, "utf8") : "{}";
32542
+ let text = exists(file3) ? fs41.readFileSync(file3, "utf8") : "{}";
32366
32543
  let before = [];
32367
32544
  try {
32368
- before = JSON.parse(fs40.readFileSync(managedFile, "utf8"));
32545
+ before = JSON.parse(fs41.readFileSync(managedFile, "utf8"));
32369
32546
  } catch {
32370
32547
  }
32371
32548
  const format2 = { formattingOptions: { insertSpaces: true, tabSize: 2, eol: "\n" } };
@@ -32374,13 +32551,13 @@ var writeManagedSettings = (file3, managedFile, values) => {
32374
32551
  text = applyEdits(text, modify(text, [key], void 0, format2));
32375
32552
  }
32376
32553
  for (const [key, value] of Object.entries(values)) text = applyEdits(text, modify(text, [key], value, format2));
32377
- mkdirp(path50.dirname(file3));
32378
- fs40.writeFileSync(file3, text);
32379
- fs40.writeFileSync(managedFile, JSON.stringify(Object.keys(values)));
32554
+ mkdirp(path51.dirname(file3));
32555
+ fs41.writeFileSync(file3, text);
32556
+ fs41.writeFileSync(managedFile, JSON.stringify(Object.keys(values)));
32380
32557
  };
32381
32558
  async function setupVscode(env, refresh) {
32382
32559
  const root = tool("vscode");
32383
- const exe = path50.join(root, "Code.exe");
32560
+ const exe = path51.join(root, "Code.exe");
32384
32561
  if (dryRun) {
32385
32562
  log("(dry run) would provision VS Code");
32386
32563
  return;
@@ -32390,11 +32567,11 @@ async function setupVscode(env, refresh) {
32390
32567
  "https://update.code.visualstudio.com/api/update/win32-" + (arch === "arm64" ? "arm64" : "x64") + "-archive/stable/latest"
32391
32568
  );
32392
32569
  log("Downloading VS Code " + release.productVersion + " (~150 MB once) ...");
32393
- const keep = path50.join(root, "data");
32570
+ const keep = path51.join(root, "data");
32394
32571
  const parked = root + "-data";
32395
32572
  if (exists(keep)) {
32396
- fs40.rmSync(parked, { recursive: true, force: true });
32397
- fs40.renameSync(keep, parked);
32573
+ fs41.rmSync(parked, { recursive: true, force: true });
32574
+ fs41.renameSync(keep, parked);
32398
32575
  }
32399
32576
  try {
32400
32577
  await downloader.archive(release.url, root, {
@@ -32402,26 +32579,26 @@ async function setupVscode(env, refresh) {
32402
32579
  locate: "Code.exe",
32403
32580
  fileName: "vscode.zip"
32404
32581
  });
32405
- fs40.writeFileSync(path50.join(root, VERSION_MARKER), release.productVersion);
32582
+ fs41.writeFileSync(path51.join(root, VERSION_MARKER), release.productVersion);
32406
32583
  } finally {
32407
32584
  if (exists(parked)) {
32408
32585
  mkdirp(root);
32409
- fs40.rmSync(keep, { recursive: true, force: true });
32410
- fs40.renameSync(parked, keep);
32586
+ fs41.rmSync(keep, { recursive: true, force: true });
32587
+ fs41.renameSync(parked, keep);
32411
32588
  }
32412
32589
  }
32413
32590
  }
32414
- mkdirp(path50.join(root, "data"));
32415
- env.prepend.push(path50.join(root, "bin"));
32591
+ mkdirp(path51.join(root, "data"));
32592
+ env.prepend.push(path51.join(root, "bin"));
32416
32593
  desktopShortcut(exe);
32417
- const version2 = exists(path50.join(root, VERSION_MARKER)) ? fs40.readFileSync(path50.join(root, VERSION_MARKER), "utf8").trim() : "installed";
32594
+ const version2 = exists(path51.join(root, VERSION_MARKER)) ? fs41.readFileSync(path51.join(root, VERSION_MARKER), "utf8").trim() : "installed";
32418
32595
  env.summary.push("vscode: " + version2 + " (portable; run code . or use the desktop shortcut)");
32419
32596
  }
32420
32597
 
32421
32598
  // src/guest/toolchains/native/rust-extras.ts
32422
- import fs41 from "node:fs";
32423
- import os8 from "node:os";
32424
- import path51 from "node:path";
32599
+ import fs42 from "node:fs";
32600
+ import os9 from "node:os";
32601
+ import path52 from "node:path";
32425
32602
 
32426
32603
  // src/shared/memory/policy.ts
32427
32604
  function buildJobs(cpus, memoryGb) {
@@ -32440,41 +32617,41 @@ function cargoJobs(cpus, memoryGb, sessions) {
32440
32617
  // src/guest/toolchains/native/rust-extras.ts
32441
32618
  var cargoTarget = (targetDir) => {
32442
32619
  if (targetDir === "shared" || targetDir === "separate") return null;
32443
- if (targetDir === "local") return path51.join(localDir, "cargo-target");
32620
+ if (targetDir === "local") return path52.join(localDir, "cargo-target");
32444
32621
  return targetDir;
32445
32622
  };
32446
32623
  function cargoShim(env, rust) {
32447
- const real = path51.join(tool("rust", "cargo", "bin"), "cargo.exe");
32624
+ const real = path52.join(tool("rust", "cargo", "bin"), "cargo.exe");
32448
32625
  if (rust.targetDir !== "separate" || !exists(real)) return;
32449
32626
  const dir = mkdirp(tool("shims", "cargo"));
32450
- fs41.copyFileSync(ensureCompiled("cargoshim"), path51.join(dir, "cargo.exe"));
32627
+ fs42.copyFileSync(ensureCompiled("cargoshim"), path52.join(dir, "cargo.exe"));
32451
32628
  env.prepend.unshift(dir);
32452
32629
  env.vars.AGENT_REAL_CARGO = real;
32453
32630
  }
32454
32631
  function linkGate(env, rust, host) {
32455
32632
  const gcc = tool("mingw", "mingw64", "bin", "gcc.exe");
32456
32633
  if (!host.endsWith("-pc-windows-gnu") || !exists(gcc)) return;
32457
- const gate = path51.join(mkdirp(tool("shims")), "linkgate.exe");
32458
- fs41.copyFileSync(ensureCompiled("linkgate"), gate);
32459
- const memoryGb = os8.totalmem() / 1024 ** 3;
32634
+ const gate = path52.join(mkdirp(tool("shims")), "linkgate.exe");
32635
+ fs42.copyFileSync(ensureCompiled("linkgate"), gate);
32636
+ const memoryGb = os9.totalmem() / 1024 ** 3;
32460
32637
  const slots = rust.linkSlots === "auto" ? linkSlotsFor(memoryGb) : rust.linkSlots;
32461
32638
  env.vars.AGENT_LINK_SLOTS = String(slots);
32462
32639
  env.vars.AGENT_REAL_LINKER = gcc;
32463
32640
  env.vars.CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER = gate;
32464
32641
  const rustEnv = { ...process.env, RUSTUP_HOME: tool("rust", "rustup"), CARGO_HOME: tool("rust", "cargo") };
32465
32642
  const sysroot = rust.linker === "lld" ? execOutput(tool("rust", "cargo", "bin", "rustc.exe"), ["--print", "sysroot"], { env: rustEnv }) : "";
32466
- const lld = sysroot ? path51.join(sysroot, "lib", "rustlib", host, "bin", "gcc-ld") : "";
32467
- if (lld && exists(path51.join(lld, "ld.lld.exe"))) env.vars.AGENT_LLD_DIR = lld;
32643
+ const lld = sysroot ? path52.join(sysroot, "lib", "rustlib", host, "bin", "gcc-ld") : "";
32644
+ if (lld && exists(path52.join(lld, "ld.lld.exe"))) env.vars.AGENT_LLD_DIR = lld;
32468
32645
  env.summary.push(
32469
32646
  "rust linking: " + (env.vars.AGENT_LLD_DIR ? "lld" : "GNU ld") + ", at most " + env.vars.AGENT_LINK_SLOTS + " at once"
32470
32647
  );
32471
32648
  }
32472
32649
  function cargoDefaults(host) {
32473
32650
  const file3 = tool("rust", "cargo", "config.toml");
32474
- if (exists(file3) || !exists(path51.dirname(file3))) return;
32475
- const jobs = cargoJobs(os8.cpus().length, os8.totalmem() / 1024 ** 3, 1);
32651
+ if (exists(file3) || !exists(path52.dirname(file3))) return;
32652
+ const jobs = cargoJobs(os9.cpus().length, os9.totalmem() / 1024 ** 3, 1);
32476
32653
  const gnu = host.endsWith("-gnu");
32477
- fs41.writeFileSync(
32654
+ fs42.writeFileSync(
32478
32655
  file3,
32479
32656
  [
32480
32657
  "# Written by windows-development-sandbox once; edit freely, it is never overwritten.",
@@ -32489,13 +32666,14 @@ function rustCaches(rust) {
32489
32666
  const target = cargoTarget(rust.targetDir);
32490
32667
  return {
32491
32668
  ...target ? { CARGO_TARGET_DIR: target } : {},
32492
- ...process.env.SCCACHE_DIR ? {} : { SCCACHE_DIR: path51.join(dataDir, "cache", "sccache") }
32669
+ ...process.env.SCCACHE_DIR ? {} : { SCCACHE_DIR: path52.join(dataDir, "cache", "sccache") }
32493
32670
  };
32494
32671
  }
32495
32672
  function rustHost(config2) {
32496
32673
  if (config2.rust.host !== "auto") return config2.rust.host;
32497
32674
  const cpu = arch === "arm64" ? "aarch64" : "x86_64";
32498
- return cpu + (wanted(config2.msvc.enabled, "msvc") ? "-pc-windows-msvc" : "-pc-windows-gnu");
32675
+ const msvc = wanted(config2.msvc.enabled, "msvc") || wanted(config2.unreal.enabled, "unreal");
32676
+ return cpu + (msvc ? "-pc-windows-msvc" : "-pc-windows-gnu");
32499
32677
  }
32500
32678
 
32501
32679
  // src/guest/toolchains/languages/python-tools.ts
@@ -32515,6 +32693,7 @@ function plan(config2, versions, o) {
32515
32693
  const apps = Boolean(o.apps && (o.apps.install.length || Object.keys(o.apps.custom).length));
32516
32694
  const java = wanted(config2.java.enabled, "java");
32517
32695
  const python = wanted(config2.python.enabled, "python");
32696
+ const unreal = wanted(config2.unreal.enabled, "unreal");
32518
32697
  return [
32519
32698
  {
32520
32699
  name: "Git",
@@ -32532,12 +32711,18 @@ function plan(config2, versions, o) {
32532
32711
  enabled: wanted(config2.cpp.enabled, "cpp") || wanted(config2.rust.enabled, "rust"),
32533
32712
  install: (env) => setupCpp(env, config2.cpp)
32534
32713
  },
32535
- { name: "MSVC", enabled: wanted(config2.msvc.enabled, "msvc"), install: (env) => setupMsvc(env, config2.msvc) },
32714
+ // Unreal's Visual Studio brings MSVC and the real vswhere: the portable MSVC (and its stand-in vswhere) stays out.
32715
+ { name: "Unreal", enabled: unreal, shared: true, install: (env) => setupUnreal(env, config2.unreal) },
32716
+ {
32717
+ name: "MSVC",
32718
+ enabled: wanted(config2.msvc.enabled, "msvc") && !unreal,
32719
+ install: (env) => setupMsvc(env, config2.msvc)
32720
+ },
32536
32721
  // Rust links with MSVC (msvc host) or MinGW's gcc (GNU host): whichever it uses goes first.
32537
32722
  {
32538
32723
  name: "Rust",
32539
32724
  enabled: wanted(config2.rust.enabled, "rust"),
32540
- after: ["C/C++", "MSVC"],
32725
+ after: ["C/C++", "MSVC", "Unreal"],
32541
32726
  install: async (env) => {
32542
32727
  await setupRust(env, { ...config2.rust, host: rustHost(config2) }, o.refresh);
32543
32728
  Object.assign(env.vars, rustCaches(config2.rust));
@@ -32752,25 +32937,25 @@ async function setupToolchains(config2, versions, options, run3 = {}) {
32752
32937
  }
32753
32938
 
32754
32939
  // src/guest/agents/agent-installer.ts
32755
- import fs43 from "node:fs";
32756
- import path56 from "node:path";
32940
+ import fs44 from "node:fs";
32941
+ import path57 from "node:path";
32757
32942
 
32758
32943
  // src/guest/setup/environment.ts
32759
- import path55 from "node:path";
32944
+ import path56 from "node:path";
32760
32945
 
32761
32946
  // src/guest/agents/local-state.ts
32762
- import fs42 from "node:fs";
32763
- import path53 from "node:path";
32947
+ import fs43 from "node:fs";
32948
+ import path54 from "node:path";
32764
32949
 
32765
32950
  // src/guest/agents/agent-files.ts
32766
- import path52 from "node:path";
32951
+ import path53 from "node:path";
32767
32952
  function agentPaths(toolsDir2, name, harness) {
32768
- const dir = path52.join(toolsDir2, "agents", name);
32953
+ const dir = path53.join(toolsDir2, "agents", name);
32769
32954
  const exe = harness.hostExecutable ?? (harness.uvBin ? harness.uvBin + ".exe" : null);
32770
32955
  return {
32771
32956
  dir,
32772
- exe: exe ? path52.join(dir, exe) : null,
32773
- cmd: harness.npmBin ? path52.join(dir, harness.npmBin + ".cmd") : null
32957
+ exe: exe ? path53.join(dir, exe) : null,
32958
+ cmd: harness.npmBin ? path53.join(dir, harness.npmBin + ".cmd") : null
32774
32959
  };
32775
32960
  }
32776
32961
  function agentCommand(name, harness) {
@@ -32806,46 +32991,46 @@ function localStateEntries(agents2, stateDir2, localRoot2) {
32806
32991
  ([agent, harness]) => Object.entries(harness.localState ?? {}).map(([env, folder]) => ({
32807
32992
  agent,
32808
32993
  env,
32809
- store: path52.join(stateDir2, agent, folder),
32810
- local: path52.join(localRoot2, agent, folder),
32994
+ store: path53.join(stateDir2, agent, folder),
32995
+ local: path53.join(localRoot2, agent, folder),
32811
32996
  processes: [agentCommand(agent, harness) + ".exe"],
32812
- legacy: path52.join(stateDir2, agent)
32997
+ legacy: path53.join(stateDir2, agent)
32813
32998
  }))
32814
32999
  );
32815
33000
  }
32816
33001
  function bootResetPaths(agents2, stateDir2) {
32817
33002
  return Object.entries(agents2).flatMap(
32818
- ([agent, harness]) => (harness.bootReset ?? []).map((rel) => ({ agent, path: path52.join(stateDir2, agent, rel) }))
33003
+ ([agent, harness]) => (harness.bootReset ?? []).map((rel) => ({ agent, path: path53.join(stateDir2, agent, rel) }))
32819
33004
  );
32820
33005
  }
32821
33006
  var isDatabaseFile = (name) => /\.(sqlite3?|db)(-wal|-shm)?$/i.test(name);
32822
33007
  var isCopyableDatabaseFile = (name) => isDatabaseFile(name) && !/-shm$/i.test(name);
32823
33008
 
32824
33009
  // src/guest/agents/local-state.ts
32825
- var localRoot = () => path53.join(localDir, "agent-state");
33010
+ var localRoot = () => path54.join(localDir, "agent-state");
32826
33011
  function agentLocalStates() {
32827
33012
  return localStateEntries(session.agents ?? {}, stateDir, localRoot());
32828
33013
  }
32829
33014
  function localStateVars() {
32830
33015
  return Object.fromEntries(agentLocalStates().map((s) => [s.env, s.local]));
32831
33016
  }
32832
- var databaseFiles = (dir, keep) => exists(dir) ? fs42.readdirSync(dir, { withFileTypes: true }).flatMap((e) => e.isFile() && keep(e.name) ? [e.name] : []) : [];
33017
+ var databaseFiles = (dir, keep) => exists(dir) ? fs43.readdirSync(dir, { withFileTypes: true }).flatMap((e) => e.isFile() && keep(e.name) ? [e.name] : []) : [];
32833
33018
  var copyFiles = (from, to, names) => {
32834
- fs42.rmSync(to, { recursive: true, force: true });
33019
+ fs43.rmSync(to, { recursive: true, force: true });
32835
33020
  mkdirp(to);
32836
- for (const name of names) fs42.copyFileSync(path53.join(from, name), path53.join(to, name));
33021
+ for (const name of names) fs43.copyFileSync(path54.join(from, name), path54.join(to, name));
32837
33022
  };
32838
33023
  var swapIn = (incoming, store2) => {
32839
33024
  const previous = store2 + ".previous";
32840
- fs42.rmSync(previous, { recursive: true, force: true });
32841
- if (exists(store2)) fs42.renameSync(store2, previous);
33025
+ fs43.rmSync(previous, { recursive: true, force: true });
33026
+ if (exists(store2)) fs43.renameSync(store2, previous);
32842
33027
  try {
32843
- fs42.renameSync(incoming, store2);
33028
+ fs43.renameSync(incoming, store2);
32844
33029
  } catch (e) {
32845
- if (exists(previous)) fs42.renameSync(previous, store2);
33030
+ if (exists(previous)) fs43.renameSync(previous, store2);
32846
33031
  throw e;
32847
33032
  }
32848
- fs42.rmSync(previous, { recursive: true, force: true });
33033
+ fs43.rmSync(previous, { recursive: true, force: true });
32849
33034
  };
32850
33035
  function adoptLegacy(s) {
32851
33036
  if (exists(s.store)) return;
@@ -32856,24 +33041,24 @@ function adoptLegacy(s) {
32856
33041
  copyFiles(s.legacy, incoming, copyable);
32857
33042
  swapIn(incoming, s.store);
32858
33043
  const same = copyable.every(
32859
- (n) => fs42.statSync(path53.join(s.store, n)).size === fs42.statSync(path53.join(s.legacy, n)).size
33044
+ (n) => fs43.statSync(path54.join(s.store, n)).size === fs43.statSync(path54.join(s.legacy, n)).size
32860
33045
  );
32861
33046
  if (!same) {
32862
33047
  warn(s.agent + ": the copied databases differ in size from the originals; the originals were kept.");
32863
33048
  return;
32864
33049
  }
32865
- for (const n of names) fs42.rmSync(path53.join(s.legacy, n), { force: true });
33050
+ for (const n of names) fs43.rmSync(path54.join(s.legacy, n), { force: true });
32866
33051
  log(s.agent + ": moved " + copyable.length + " database file(s) to " + s.store + ".");
32867
33052
  }
32868
33053
  function resetMachineBound() {
32869
33054
  if (dryRun) return;
32870
33055
  for (const { agent, path: target } of bootResetPaths(session.agents ?? {}, stateDir)) {
32871
33056
  try {
32872
- const stat = fs42.lstatSync(target, { throwIfNoEntry: false });
33057
+ const stat = fs43.lstatSync(target, { throwIfNoEntry: false });
32873
33058
  if (!stat || stat.isSymbolicLink()) continue;
32874
- fs42.rmSync(target, { recursive: true, force: true });
33059
+ fs43.rmSync(target, { recursive: true, force: true });
32875
33060
  log(
32876
- agent + ": removed " + path53.relative(path53.join(stateDir, agent), target) + " (it only worked in the last sandbox)."
33061
+ agent + ": removed " + path54.relative(path54.join(stateDir, agent), target) + " (it only worked in the last sandbox)."
32877
33062
  );
32878
33063
  } catch (e) {
32879
33064
  warn(agent + ": could not remove " + target + " (" + errMsg(e) + ").");
@@ -32887,7 +33072,7 @@ function restoreLocalState() {
32887
33072
  adoptLegacy(s);
32888
33073
  mkdirp(s.local);
32889
33074
  const names = databaseFiles(s.store, isCopyableDatabaseFile);
32890
- for (const n of names) fs42.copyFileSync(path53.join(s.store, n), path53.join(s.local, n));
33075
+ for (const n of names) fs43.copyFileSync(path54.join(s.store, n), path54.join(s.local, n));
32891
33076
  if (names.length) log(s.agent + ": databases restored to " + s.local + ".");
32892
33077
  } catch (e) {
32893
33078
  warn(s.agent + ": could not restore its databases (" + errMsg(e) + "); it starts with empty ones.");
@@ -32896,7 +33081,7 @@ function restoreLocalState() {
32896
33081
  }
32897
33082
 
32898
33083
  // src/guest/setup/path-plan.ts
32899
- import path54 from "node:path";
33084
+ import path55 from "node:path";
32900
33085
  function pathKey(folder) {
32901
33086
  const slashes = folder.trim().replace(/^"|"$/g, "").replace(/\//g, "\\");
32902
33087
  return (slashes.length > 3 ? slashes.replace(/\\+$/, "") : slashes).toLowerCase();
@@ -32918,13 +33103,13 @@ function planPath(input2) {
32918
33103
  function isPinnedNodeDir(folder, nvmHome2) {
32919
33104
  const key = pathKey(folder);
32920
33105
  const home = pathKey(nvmHome2);
32921
- return key.startsWith(home + "\\") && /^v\d/.test(path54.win32.basename(key));
33106
+ return key.startsWith(home + "\\") && /^v\d/.test(path55.win32.basename(key));
32922
33107
  }
32923
33108
 
32924
33109
  // src/guest/setup/environment.ts
32925
33110
  var LEGACY_HOMES = { CODEX_HOME: "codex", GEMINI_CLI_HOME: "gemini" };
32926
33111
  var agentHomes = () => Object.fromEntries(
32927
- Object.entries(session.agentHomes ?? LEGACY_HOMES).filter(([name]) => name !== "CLAUDE_CONFIG_DIR").map(([name, sub]) => [name, path55.join(stateDir, sub)])
33112
+ Object.entries(session.agentHomes ?? LEGACY_HOMES).filter(([name]) => name !== "CLAUDE_CONFIG_DIR").map(([name, sub]) => [name, path56.join(stateDir, sub)])
32928
33113
  );
32929
33114
  var AGENT_VARS = [
32930
33115
  "CLAUDE_CONFIG_DIR",
@@ -32945,7 +33130,7 @@ function agentEnv(tools, target = { workspace, project: session.project, base: p
32945
33130
  CLAUDE_CONFIG_DIR: claudeDir,
32946
33131
  ...homes,
32947
33132
  ...localStateVars(),
32948
- npm_config_cache: path55.join(toolsDir, "npm-cache"),
33133
+ npm_config_cache: path56.join(toolsDir, "npm-cache"),
32949
33134
  npm_config_update_notifier: "false",
32950
33135
  AGENT_WORKSPACE: target.workspace,
32951
33136
  AGENT_DATA: dataDir,
@@ -32963,9 +33148,9 @@ function agentEnv(tools, target = { workspace, project: session.project, base: p
32963
33148
  ...local.map((n) => env[n])
32964
33149
  ])
32965
33150
  mkdirp(dir);
32966
- const runners = [path55.join(toolsDir, "node"), path55.dirname(process.execPath)].map((d) => d.toLowerCase());
32967
- const base = (target.base.PATH ?? "").split(path55.delimiter).filter((d) => d && !runners.includes(d.toLowerCase()));
32968
- env.PATH = [.../* @__PURE__ */ new Set([...tools.prepend, ...base, ...tools.append])].join(path55.delimiter);
33151
+ const runners = [path56.join(toolsDir, "node"), path56.dirname(process.execPath)].map((d) => d.toLowerCase());
33152
+ const base = (target.base.PATH ?? "").split(path56.delimiter).filter((d) => d && !runners.includes(d.toLowerCase()));
33153
+ env.PATH = [.../* @__PURE__ */ new Set([...tools.prepend, ...base, ...tools.append])].join(path56.delimiter);
32969
33154
  return env;
32970
33155
  }
32971
33156
  function persistEnvironment(env, toolVars2) {
@@ -32980,7 +33165,7 @@ function persistEnvironment(env, toolVars2) {
32980
33165
  entries: [env.PATH ?? "", ...installedAgentDirs()],
32981
33166
  exists,
32982
33167
  drop: (dir) => isPinnedNodeDir(dir, nvmHome())
32983
- }).join(path55.delimiter),
33168
+ }).join(path56.delimiter),
32984
33169
  add: [],
32985
33170
  additive: false
32986
33171
  });
@@ -32997,7 +33182,7 @@ function addMachineEnvironment(vars, dirs, additive = false) {
32997
33182
  warn("Could not add to the environment: " + errMsg(e));
32998
33183
  }
32999
33184
  }
33000
- var nvmHome = () => path55.join(toolsDir, "nvm");
33185
+ var nvmHome = () => path56.join(toolsDir, "nvm");
33001
33186
  function installedAgentDirs() {
33002
33187
  return Object.entries(session.agents ?? {}).flatMap(([name, harness]) => {
33003
33188
  const p = agentPaths(toolsDir, name, harness);
@@ -33029,7 +33214,7 @@ var agentPaths2 = (name, harness) => agentPaths(toolsDir, name, harness);
33029
33214
  async function installViaNpm(name, harness, dir, env) {
33030
33215
  if (!harness.npmPackage)
33031
33216
  throw new Error("No npmPackage configured for " + name + " and no host executable was available.");
33032
- const npmCli = path56.join(path56.dirname(process.execPath), "node_modules", "npm", "bin", "npm-cli.js");
33217
+ const npmCli = path57.join(path57.dirname(process.execPath), "node_modules", "npm", "bin", "npm-cli.js");
33033
33218
  const args = [npmCli, "install", "--global", "--prefix", dir, harness.npmPackage, "--no-fund", "--no-audit"];
33034
33219
  log("Installing " + harness.npmPackage + " (this can take a minute)...");
33035
33220
  if (dryRun) {
@@ -33040,7 +33225,7 @@ async function installViaNpm(name, harness, dir, env) {
33040
33225
  await execAsync(process.execPath, args, { env });
33041
33226
  }
33042
33227
  async function installViaUv(name, harness, dir, env) {
33043
- const uv = path56.join(toolsDir, "uv", "uv.exe");
33228
+ const uv = path57.join(toolsDir, "uv", "uv.exe");
33044
33229
  log("Installing " + harness.uvPackage + " with uv (this can take a minute)...");
33045
33230
  if (dryRun) {
33046
33231
  log("(dry run) uv tool install " + harness.uvPackage);
@@ -33055,8 +33240,8 @@ async function installViaUv(name, harness, dir, env) {
33055
33240
  });
33056
33241
  }
33057
33242
  function putOnPath(dir, env) {
33058
- const parts2 = (env.PATH ?? "").split(path56.delimiter);
33059
- if (!parts2.some((p) => p.toLowerCase() === dir.toLowerCase())) env.PATH = [...parts2, dir].join(path56.delimiter);
33243
+ const parts2 = (env.PATH ?? "").split(path57.delimiter);
33244
+ if (!parts2.some((p) => p.toLowerCase() === dir.toLowerCase())) env.PATH = [...parts2, dir].join(path57.delimiter);
33060
33245
  addMachineEnvironment({}, [dir], true);
33061
33246
  }
33062
33247
  var AgentInstaller = class {
@@ -33097,9 +33282,9 @@ var AgentInstaller = class {
33097
33282
  }
33098
33283
  mkdirp(p.dir);
33099
33284
  if (this.sourceOf(name, harness) === "host") {
33100
- const source = path56.join(hostToolsDir, "agents", name, harness.hostExecutable);
33285
+ const source = path57.join(hostToolsDir, "agents", name, harness.hostExecutable);
33101
33286
  if (exists(source) && p.exe) {
33102
- fs43.copyFileSync(source, p.exe);
33287
+ fs44.copyFileSync(source, p.exe);
33103
33288
  log("Copied " + name + " from this PC: " + source);
33104
33289
  return;
33105
33290
  }
@@ -33114,44 +33299,44 @@ var AgentInstaller = class {
33114
33299
  var agents = new AgentInstaller();
33115
33300
 
33116
33301
  // src/guest/setup/shell-path.ts
33117
- import fs44 from "node:fs";
33118
- import path57 from "node:path";
33302
+ import fs45 from "node:fs";
33303
+ import path58 from "node:path";
33119
33304
  function installShellPath() {
33120
33305
  if (!isWin || dryRun || testMode) return;
33121
- const helper = path57.join(mkdirp(path57.join(localDir, "bin")), "pathsync.exe");
33122
- fs44.copyFileSync(ensureCompiled("pathsync"), helper);
33306
+ const helper = path58.join(mkdirp(path58.join(localDir, "bin")), "pathsync.exe");
33307
+ fs45.copyFileSync(ensureCompiled("pathsync"), helper);
33123
33308
  runScript("install-shell-path.ps1", [
33124
33309
  "-Helper",
33125
33310
  helper,
33126
33311
  "-PwshDir",
33127
- path57.join(toolsDir, "pwsh"),
33312
+ path58.join(toolsDir, "pwsh"),
33128
33313
  "-GitRoot",
33129
- path57.join(toolsDir, "git")
33314
+ path58.join(toolsDir, "git")
33130
33315
  ]);
33131
33316
  }
33132
33317
 
33133
33318
  // src/guest/setup/claude-mem.ts
33134
- import fs45 from "node:fs";
33135
- import os9 from "node:os";
33136
- import path58 from "node:path";
33319
+ import fs46 from "node:fs";
33320
+ import os10 from "node:os";
33321
+ import path59 from "node:path";
33137
33322
  var claudeMemPaths = {
33138
- store: path58.join(stateDir, "claude-mem"),
33139
- local: path58.join(os9.homedir(), ".claude-mem")
33323
+ store: path59.join(stateDir, "claude-mem"),
33324
+ local: path59.join(os10.homedir(), ".claude-mem")
33140
33325
  };
33141
33326
  var claudeMemEnabled = () => session.claudeProfile.syncClaudeMem && !dryRun;
33142
33327
  function restoreClaudeMem() {
33143
33328
  if (!claudeMemEnabled()) return;
33144
33329
  const previous = claudeMemPaths.store + ".previous";
33145
- if (!exists(claudeMemPaths.store) && exists(previous)) fs45.renameSync(previous, claudeMemPaths.store);
33330
+ if (!exists(claudeMemPaths.store) && exists(previous)) fs46.renameSync(previous, claudeMemPaths.store);
33146
33331
  const backups = claudeMemPaths.store + ".backups";
33147
- if (!looksLikeSqlite(path58.join(claudeMemPaths.store, "claude-mem.db")) || !exists(claudeMemPaths.store)) {
33148
- const good = (exists(backups) ? fs45.readdirSync(backups).sort().reverse() : []).find(
33149
- (b) => exists(path58.join(backups, b, "claude-mem.db")) && looksLikeSqlite(path58.join(backups, b, "claude-mem.db"))
33332
+ if (!looksLikeSqlite(path59.join(claudeMemPaths.store, "claude-mem.db")) || !exists(claudeMemPaths.store)) {
33333
+ const good = (exists(backups) ? fs46.readdirSync(backups).sort().reverse() : []).find(
33334
+ (b) => exists(path59.join(backups, b, "claude-mem.db")) && looksLikeSqlite(path59.join(backups, b, "claude-mem.db"))
33150
33335
  );
33151
33336
  if (good) {
33152
33337
  if (exists(claudeMemPaths.store))
33153
- fs45.renameSync(claudeMemPaths.store, claudeMemPaths.store + ".damaged-" + Date.now());
33154
- fs45.cpSync(path58.join(backups, good), claudeMemPaths.store, { recursive: true });
33338
+ fs46.renameSync(claudeMemPaths.store, claudeMemPaths.store + ".damaged-" + Date.now());
33339
+ fs46.cpSync(path59.join(backups, good), claudeMemPaths.store, { recursive: true });
33155
33340
  warn(
33156
33341
  "claude-mem: the stored database was missing or damaged; restored the backup from " + new Date(Number(good)).toISOString() + "."
33157
33342
  );
@@ -33164,33 +33349,33 @@ function restoreClaudeMem() {
33164
33349
  var SQLITE_HEADER = "SQLite format 3\0";
33165
33350
  var looksLikeSqlite = (file3) => {
33166
33351
  if (!exists(file3)) return true;
33167
- const fd = fs45.openSync(file3, "r");
33352
+ const fd = fs46.openSync(file3, "r");
33168
33353
  try {
33169
33354
  const head = Buffer.alloc(16);
33170
- return fs45.readSync(fd, head, 0, 16, 0) === 16 && head.toString("latin1") === SQLITE_HEADER;
33355
+ return fs46.readSync(fd, head, 0, 16, 0) === 16 && head.toString("latin1") === SQLITE_HEADER;
33171
33356
  } finally {
33172
- fs45.closeSync(fd);
33357
+ fs46.closeSync(fd);
33173
33358
  }
33174
33359
  };
33175
33360
  var BACKUP_EVERY_MS = 6 * 3600 * 1e3;
33176
33361
 
33177
33362
  // src/guest/setup/claude-profile.ts
33178
- import fs46 from "node:fs";
33179
- import path59 from "node:path";
33363
+ import fs47 from "node:fs";
33364
+ import path60 from "node:path";
33180
33365
  var KEEP_SANDBOX_COPY = [".claude.json", ".credentials.json"];
33181
33366
  var fixPluginPaths = (hostConfigDir) => {
33182
- const plugins = path59.join(claudeDir, "plugins");
33367
+ const plugins = path60.join(claudeDir, "plugins");
33183
33368
  if (!hostConfigDir || !exists(plugins)) return;
33184
- for (const name of fs46.readdirSync(plugins).filter((f) => f.endsWith(".json"))) {
33185
- const file3 = path59.join(plugins, name);
33186
- const text = fs46.readFileSync(file3, "utf8");
33369
+ for (const name of fs47.readdirSync(plugins).filter((f) => f.endsWith(".json"))) {
33370
+ const file3 = path60.join(plugins, name);
33371
+ const text = fs47.readFileSync(file3, "utf8");
33187
33372
  const fixed = translatePaths(text, hostConfigDir, claudeDir);
33188
- if (fixed !== text) fs46.writeFileSync(file3, fixed, "utf8");
33373
+ if (fixed !== text) fs47.writeFileSync(file3, fixed, "utf8");
33189
33374
  }
33190
33375
  };
33191
33376
  var readState2 = (file3) => {
33192
33377
  try {
33193
- return JSON.parse(fs46.readFileSync(file3, "utf8").replace(/^\uFEFF/, ""));
33378
+ return JSON.parse(fs47.readFileSync(file3, "utf8").replace(/^\uFEFF/, ""));
33194
33379
  } catch {
33195
33380
  return null;
33196
33381
  }
@@ -33221,14 +33406,14 @@ function syncClaudeProfile(credentials) {
33221
33406
  log("No Claude settings were staged from this PC.");
33222
33407
  return;
33223
33408
  }
33224
- const source = path59.join(launchDir, "claude-profile");
33409
+ const source = path60.join(launchDir, "claude-profile");
33225
33410
  mkdirp(claudeDir);
33226
33411
  for (const name of profile.items) {
33227
- const from = path59.join(source, name);
33228
- const to = path59.join(claudeDir, name);
33412
+ const from = path60.join(source, name);
33413
+ const to = path60.join(claudeDir, name);
33229
33414
  if (name === ".credentials.json") {
33230
33415
  if (credentials && !exists(to)) {
33231
- fs46.writeFileSync(to, credentials, "utf8");
33416
+ fs47.writeFileSync(to, credentials, "utf8");
33232
33417
  log("Claude settings: copied " + name + " from this PC");
33233
33418
  } else log("Claude settings: kept the sandbox's " + name);
33234
33419
  continue;
@@ -33238,14 +33423,14 @@ function syncClaudeProfile(credentials) {
33238
33423
  log("Claude settings: kept the sandbox's " + name);
33239
33424
  continue;
33240
33425
  }
33241
- if (fs46.statSync(from).isDirectory()) safeRemove(to, claudeDir);
33242
- fs46.cpSync(from, to, { recursive: true, force: true });
33426
+ if (fs47.statSync(from).isDirectory()) safeRemove(to, claudeDir);
33427
+ fs47.cpSync(from, to, { recursive: true, force: true });
33243
33428
  log("Claude settings: copied " + name + " from this PC");
33244
33429
  }
33245
33430
  fixPluginPaths(profile.hostConfigDir);
33246
33431
  const mcp = mergeMcpServers(
33247
- path59.join(source, ".claude.json"),
33248
- path59.join(claudeDir, ".claude.json"),
33432
+ path60.join(source, ".claude.json"),
33433
+ path60.join(claudeDir, ".claude.json"),
33249
33434
  session.workspaceHost,
33250
33435
  workspace
33251
33436
  );
@@ -33254,11 +33439,11 @@ function syncClaudeProfile(credentials) {
33254
33439
  }
33255
33440
 
33256
33441
  // src/guest/setup/hooks.ts
33257
- import fs47 from "node:fs";
33258
- import path60 from "node:path";
33442
+ import fs48 from "node:fs";
33443
+ import path61 from "node:path";
33259
33444
  import { spawnSync as spawnSync4 } from "node:child_process";
33260
33445
  var commandFor = (file3) => {
33261
- const ext = path60.extname(file3).toLowerCase();
33446
+ const ext = path61.extname(file3).toLowerCase();
33262
33447
  if (ext === ".mjs" || ext === ".js") return [process.execPath, [file3]];
33263
33448
  if (!isWin) return null;
33264
33449
  if (ext === ".ps1")
@@ -33266,12 +33451,12 @@ var commandFor = (file3) => {
33266
33451
  if (ext === ".cmd" || ext === ".bat") return [SYSTEM.cmd(), ["/d", "/c", file3]];
33267
33452
  return null;
33268
33453
  };
33269
- var BOOT = { root: path60.join(launchDir, "hooks"), cwd: workspace };
33454
+ var BOOT = { root: path61.join(launchDir, "hooks"), cwd: workspace };
33270
33455
  var hooksOf = (stage, target) => {
33271
- const dir = path60.join(target.root, stage);
33456
+ const dir = path61.join(target.root, stage);
33272
33457
  if (!exists(dir)) return [];
33273
- return fs47.readdirSync(dir).sort().flatMap((name) => {
33274
- const command = commandFor(path60.join(dir, name));
33458
+ return fs48.readdirSync(dir).sort().flatMap((name) => {
33459
+ const command = commandFor(path61.join(dir, name));
33275
33460
  return command ? [{ name, command }] : [];
33276
33461
  });
33277
33462
  };
@@ -33289,8 +33474,8 @@ function runHooks(stage, env, target = BOOT) {
33289
33474
  }
33290
33475
 
33291
33476
  // src/guest/network/allow-only.ts
33292
- import fs49 from "node:fs";
33293
- import path62 from "node:path";
33477
+ import fs50 from "node:fs";
33478
+ import path63 from "node:path";
33294
33479
  import { spawn as spawn6, spawnSync as spawnSync6 } from "node:child_process";
33295
33480
 
33296
33481
  // src/shared/network/policy.ts
@@ -33385,8 +33570,8 @@ var PROXY_PORT = 38080;
33385
33570
 
33386
33571
  // src/guest/network/firewall.ts
33387
33572
  import dns from "node:dns";
33388
- import fs48 from "node:fs";
33389
- import path61 from "node:path";
33573
+ import fs49 from "node:fs";
33574
+ import path62 from "node:path";
33390
33575
  import { spawnSync as spawnSync5 } from "node:child_process";
33391
33576
 
33392
33577
  // src/shared/network/firewall-rules.ts
@@ -33577,7 +33762,7 @@ function networkProblems() {
33577
33762
  function longPath(file3) {
33578
33763
  if (!hasShortName(file3)) return file3;
33579
33764
  try {
33580
- return fs48.realpathSync.native(file3);
33765
+ return fs49.realpathSync.native(file3);
33581
33766
  } catch {
33582
33767
  return file3;
33583
33768
  }
@@ -33676,12 +33861,12 @@ async function applyNetworkPolicy(ptyHostExe) {
33676
33861
  return "blocked";
33677
33862
  }
33678
33863
  var FORWARD_RULE = "AgentSandbox-Forward";
33679
- var HOSTS_FILE = path61.join(process.env.WINDIR ?? "C:\\Windows", "System32", "drivers", "etc", "hosts");
33864
+ var HOSTS_FILE = path62.join(process.env.WINDIR ?? "C:\\Windows", "System32", "drivers", "etc", "hosts");
33680
33865
  var applyBlockedHosts = () => {
33681
33866
  const hosts = session.network.blockHosts ?? [];
33682
33867
  if (!hosts.length) return;
33683
- const text = fs48.existsSync(HOSTS_FILE) ? fs48.readFileSync(HOSTS_FILE, "utf8") : "";
33684
- fs48.writeFileSync(HOSTS_FILE, withBlockedHosts(text, hosts));
33868
+ const text = fs49.existsSync(HOSTS_FILE) ? fs49.readFileSync(HOSTS_FILE, "utf8") : "";
33869
+ fs49.writeFileSync(HOSTS_FILE, withBlockedHosts(text, hosts));
33685
33870
  log("Blocked hosts (network.blockHosts): " + hosts.join(", "));
33686
33871
  };
33687
33872
  var applyDns = () => {
@@ -33736,11 +33921,11 @@ async function applyAllowOnly() {
33736
33921
  log("(dry run) would allow only: " + hosts.join(", "));
33737
33922
  return false;
33738
33923
  }
33739
- const exe = path62.join(toolsDir, "netproxy", "sbx-netproxy.exe");
33740
- fs49.mkdirSync(path62.dirname(exe), { recursive: true });
33741
- if (!fs49.existsSync(exe) || fs49.statSync(exe).size !== fs49.statSync(process.execPath).size)
33742
- fs49.copyFileSync(process.execPath, exe);
33743
- spawn6(exe, [path62.join(launchDir, "runtime", "netproxy.js")], {
33924
+ const exe = path63.join(toolsDir, "netproxy", "sbx-netproxy.exe");
33925
+ fs50.mkdirSync(path63.dirname(exe), { recursive: true });
33926
+ if (!fs50.existsSync(exe) || fs50.statSync(exe).size !== fs50.statSync(process.execPath).size)
33927
+ fs50.copyFileSync(process.execPath, exe);
33928
+ spawn6(exe, [path63.join(launchDir, "runtime", "netproxy.js")], {
33744
33929
  detached: true,
33745
33930
  stdio: "ignore",
33746
33931
  windowsHide: true
@@ -33784,8 +33969,8 @@ async function applyAllowOnly() {
33784
33969
  }
33785
33970
 
33786
33971
  // src/guest/setup/managed-policy.ts
33787
- import fs50 from "node:fs";
33788
- import path63 from "node:path";
33972
+ import fs51 from "node:fs";
33973
+ import path64 from "node:path";
33789
33974
 
33790
33975
  // src/guest/setup/git-rules.ts
33791
33976
  var SHELLS = ["Bash", "PowerShell"];
@@ -33842,24 +34027,24 @@ function gitDenyRules(access) {
33842
34027
 
33843
34028
  // src/guest/setup/managed-policy.ts
33844
34029
  function managedSettingsFile() {
33845
- return path63.join(path63.dirname(managedClaudeMd()), "managed-settings.json");
34030
+ return path64.join(path64.dirname(managedClaudeMd()), "managed-settings.json");
33846
34031
  }
33847
34032
  function writeManagedSettings2(access, headroom = null) {
33848
34033
  const file3 = managedSettingsFile();
33849
34034
  const rtk = installedRtk();
33850
34035
  const settings = claudeManagedSettings(gitDenyRules(access), rtk, headroom);
33851
34036
  if (!settings) {
33852
- fs50.rmSync(file3, { force: true });
34037
+ fs51.rmSync(file3, { force: true });
33853
34038
  return;
33854
34039
  }
33855
- fs50.mkdirSync(path63.dirname(file3), { recursive: true });
33856
- fs50.writeFileSync(file3, JSON.stringify(settings, null, 2) + "\n", "utf8");
34040
+ fs51.mkdirSync(path64.dirname(file3), { recursive: true });
34041
+ fs51.writeFileSync(file3, JSON.stringify(settings, null, 2) + "\n", "utf8");
33857
34042
  if (rtk) log("rtk: Claude Code's Bash commands go through it (hook in " + file3 + ")");
33858
34043
  }
33859
34044
 
33860
34045
  // src/guest/setup/addon-mcp.ts
33861
- import fs51 from "node:fs";
33862
- import path64 from "node:path";
34046
+ import fs52 from "node:fs";
34047
+ import path65 from "node:path";
33863
34048
  var ADDON_MCP_NAMES = APPS.flatMap((a) => a.mcp ? [a.mcp.name] : []);
33864
34049
  function writeAddonMcpServers() {
33865
34050
  const servers = {};
@@ -33867,11 +34052,11 @@ function writeAddonMcpServers() {
33867
34052
  const mcp = APPS.find((a) => a.id === id)?.mcp;
33868
34053
  if (mcp) servers[mcp.name] = addonMcpServer(folder, mcp);
33869
34054
  }
33870
- const file3 = path64.join(claudeDir, ".claude.json");
34055
+ const file3 = path65.join(claudeDir, ".claude.json");
33871
34056
  let state = {};
33872
- if (fs51.existsSync(file3)) {
34057
+ if (fs52.existsSync(file3)) {
33873
34058
  try {
33874
- const text = fs51.readFileSync(file3, "utf8");
34059
+ const text = fs52.readFileSync(file3, "utf8");
33875
34060
  state = JSON.parse(text.charCodeAt(0) === 65279 ? text.slice(1) : text);
33876
34061
  } catch {
33877
34062
  warn("Claude Code MCP servers from Apps: " + file3 + " is not valid JSON, left as it is");
@@ -33883,7 +34068,7 @@ function writeAddonMcpServers() {
33883
34068
  const before = current && typeof current === "object" && !Array.isArray(current) ? current : {};
33884
34069
  const after = withAddonMcpServers(before, servers, ADDON_MCP_NAMES);
33885
34070
  if (JSON.stringify(before) !== JSON.stringify(after)) {
33886
- fs51.mkdirSync(claudeDir, { recursive: true });
34071
+ fs52.mkdirSync(claudeDir, { recursive: true });
33887
34072
  writeJsonAtomic(file3, { ...state, mcpServers: after });
33888
34073
  }
33889
34074
  const names = Object.keys(servers);
@@ -33892,11 +34077,11 @@ function writeAddonMcpServers() {
33892
34077
  }
33893
34078
 
33894
34079
  // src/guest/setup/headroom.ts
33895
- import fs52 from "node:fs";
34080
+ import fs53 from "node:fs";
33896
34081
  import http from "node:http";
33897
- import path65 from "node:path";
34082
+ import path66 from "node:path";
33898
34083
  import { spawn as spawn7 } from "node:child_process";
33899
- var HEADROOM_LOG = path65.join(logsDir, "headroom.log");
34084
+ var HEADROOM_LOG = path66.join(logsDir, "headroom.log");
33900
34085
  function answersAsHeadroom(port) {
33901
34086
  return new Promise((resolve2) => {
33902
34087
  const req = http.get({ host: "127.0.0.1", port, path: "/livez", timeout: 3e3 }, (res) => {
@@ -33920,14 +34105,14 @@ async function startHeadroom(env) {
33920
34105
  }
33921
34106
  const port = HEADROOM_PORT;
33922
34107
  if (!await portOpen(port)) {
33923
- const out = fs52.openSync(HEADROOM_LOG, "a");
34108
+ const out = fs53.openSync(HEADROOM_LOG, "a");
33924
34109
  spawn7(exe, headroomArgs(port), {
33925
34110
  detached: true,
33926
34111
  stdio: ["ignore", out, out],
33927
34112
  windowsHide: true,
33928
34113
  env: headroomEnv(env)
33929
34114
  }).unref();
33930
- fs52.closeSync(out);
34115
+ fs53.closeSync(out);
33931
34116
  if (!await waitForPort(port, 90))
33932
34117
  throw new Error("the Headroom proxy did not start on port " + port + "; see " + HEADROOM_LOG);
33933
34118
  }
@@ -33938,30 +34123,41 @@ async function startHeadroom(env) {
33938
34123
  }
33939
34124
 
33940
34125
  // src/guest/setup/desktop.ts
33941
- import fs53 from "node:fs";
33942
- import os10 from "node:os";
33943
- import path66 from "node:path";
34126
+ import fs54 from "node:fs";
34127
+ import os11 from "node:os";
34128
+ import path67 from "node:path";
33944
34129
  function applyPersonalization() {
33945
- const dir = path66.join(launchDir, "personalize");
34130
+ const dir = path67.join(launchDir, "personalize");
33946
34131
  if (!session.personalization || !exists(dir) || dryRun || !isWin) return;
33947
- exec(SYSTEM.reg(), ["import", path66.join(dir, "personalize.reg")], { stdio: "ignore" });
33948
- const wallpaper = fs53.readdirSync(dir).find((f) => f.startsWith("wallpaper"));
33949
- const local = wallpaper ? path66.join(mkdirp(path66.join(os10.homedir(), "Pictures")), wallpaper) : null;
33950
- if (wallpaper && local) fs53.copyFileSync(path66.join(dir, wallpaper), local);
34132
+ exec(SYSTEM.reg(), ["import", path67.join(dir, "personalize.reg")], { stdio: "ignore" });
34133
+ const wallpaper = fs54.readdirSync(dir).find((f) => f.startsWith("wallpaper"));
34134
+ const local = wallpaper ? path67.join(mkdirp(path67.join(os11.homedir(), "Pictures")), wallpaper) : null;
34135
+ if (wallpaper && local) fs54.copyFileSync(path67.join(dir, wallpaper), local);
33951
34136
  runScript("set-desktop.ps1", local ? ["-Wallpaper", local] : []);
33952
34137
  log("Desktop personalisation applied from this PC.");
33953
34138
  }
33954
34139
 
34140
+ // src/guest/setup/browser-gpu.ts
34141
+ var POLICY_KEYS = ["HKLM\\SOFTWARE\\Policies\\Microsoft\\Edge", "HKLM\\SOFTWARE\\Policies\\Google\\Chrome"];
34142
+ function keepBrowsersOffGpu() {
34143
+ if (dryRun || !isWin) return;
34144
+ for (const key of POLICY_KEYS)
34145
+ exec(SYSTEM.reg(), ["add", key, "/v", "HardwareAccelerationModeEnabled", "/t", "REG_DWORD", "/d", "0", "/f"], {
34146
+ stdio: "ignore"
34147
+ });
34148
+ log("Browsers draw without the GPU (Edge and Chrome policy).");
34149
+ }
34150
+
33955
34151
  // src/guest/setup/git-identity.ts
33956
- import fs54 from "node:fs";
33957
- import os11 from "node:os";
33958
- import path67 from "node:path";
34152
+ import fs55 from "node:fs";
34153
+ import os12 from "node:os";
34154
+ import path68 from "node:path";
33959
34155
  import { spawnSync as spawnSync7 } from "node:child_process";
33960
34156
  function setupGitConfig(env) {
33961
34157
  if (dryRun) return;
33962
- const source = path67.join(launchDir, "home", ".gitconfig");
33963
- if (exists(source)) fs54.copyFileSync(source, path67.join(os11.homedir(), ".gitconfig"));
33964
- const git = path67.join(toolsDir, "git", "cmd", "git.exe");
34158
+ const source = path68.join(launchDir, "home", ".gitconfig");
34159
+ if (exists(source)) fs55.copyFileSync(source, path68.join(os12.homedir(), ".gitconfig"));
34160
+ const git = path68.join(toolsDir, "git", "cmd", "git.exe");
33965
34161
  if (!exists(git)) return;
33966
34162
  const { GIT_DIR: _gitDir, ...rest } = env;
33967
34163
  spawnSync7(git, ["config", "--global", "--add", "safe.directory", "*"], {
@@ -33974,7 +34170,7 @@ function setupGitConfig(env) {
33974
34170
  }
33975
34171
 
33976
34172
  // src/guest/setup/github-token.ts
33977
- import fs55 from "node:fs";
34173
+ import fs56 from "node:fs";
33978
34174
  import { spawnSync as spawnSync8 } from "node:child_process";
33979
34175
 
33980
34176
  // src/shared/github/token.ts
@@ -34020,7 +34216,7 @@ function ghOutputText(text, token) {
34020
34216
  var GH_TIMEOUT_MS = 6e4;
34021
34217
  function prepareGithubFolder(token) {
34022
34218
  const dir = deliveredGhConfigDir();
34023
- fs55.rmSync(dir, { recursive: true, force: true });
34219
+ fs56.rmSync(dir, { recursive: true, force: true });
34024
34220
  if (!token) return false;
34025
34221
  mkdirp(dir);
34026
34222
  return true;
@@ -34048,7 +34244,7 @@ function loginGithub(token, env) {
34048
34244
  const gh2 = ghExePath();
34049
34245
  const dir = deliveredGhConfigDir();
34050
34246
  if (!exists(gh2) || env.GH_CONFIG_DIR !== dir) {
34051
- fs55.rmSync(dir, { recursive: true, force: true });
34247
+ fs56.rmSync(dir, { recursive: true, force: true });
34052
34248
  log("A GitHub token arrived, but gh is not set up in this sandbox (toolchains.cli.gh), so it is not used.");
34053
34249
  return;
34054
34250
  }
@@ -34056,7 +34252,7 @@ function loginGithub(token, env) {
34056
34252
  runGh(ghLoginCommand(gh2, dir, token, env), token, "gh auth login");
34057
34253
  runGh(ghSetupGitCommand(gh2, dir, env), token, "gh auth setup-git");
34058
34254
  } catch (e) {
34059
- fs55.rmSync(dir, { recursive: true, force: true });
34255
+ fs56.rmSync(dir, { recursive: true, force: true });
34060
34256
  env.GH_CONFIG_DIR = mkdirp(ghConfigDir());
34061
34257
  addMachineEnvironment({ GH_CONFIG_DIR: env.GH_CONFIG_DIR }, []);
34062
34258
  throw e;
@@ -34070,35 +34266,35 @@ function ensurePtyHost() {
34070
34266
  }
34071
34267
 
34072
34268
  // src/guest/toolchains/leftovers.ts
34073
- import fs56 from "node:fs";
34074
- import path68 from "node:path";
34269
+ import fs57 from "node:fs";
34270
+ import path69 from "node:path";
34075
34271
  var STAGING = /\.staging-[0-9a-f]+$/i;
34076
34272
  var entries2 = (dir) => {
34077
34273
  try {
34078
- return fs56.readdirSync(dir, { withFileTypes: true });
34274
+ return fs57.readdirSync(dir, { withFileTypes: true });
34079
34275
  } catch {
34080
34276
  return [];
34081
34277
  }
34082
34278
  };
34083
34279
  function pruneToolLeftovers() {
34084
- for (const legacy of ["ptyhost", "gitshim"]) safeRemove(path68.join(toolsDir, legacy), toolsDir);
34280
+ for (const legacy of ["ptyhost", "gitshim"]) safeRemove(path69.join(toolsDir, legacy), toolsDir);
34085
34281
  for (const top of entries2(toolsDir)) {
34086
- const dir = path68.join(toolsDir, top.name);
34282
+ const dir = path69.join(toolsDir, top.name);
34087
34283
  if (STAGING.test(top.name)) safeRemove(dir, toolsDir);
34088
34284
  else if (top.isDirectory())
34089
- for (const sub of entries2(dir).filter((e) => STAGING.test(e.name))) safeRemove(path68.join(dir, sub.name), dir);
34285
+ for (const sub of entries2(dir).filter((e) => STAGING.test(e.name))) safeRemove(path69.join(dir, sub.name), dir);
34090
34286
  }
34091
34287
  }
34092
34288
 
34093
34289
  // src/guest/audit/process-audit.ts
34094
- import path69 from "node:path";
34290
+ import path70 from "node:path";
34095
34291
  import { spawnSync as spawnSync9 } from "node:child_process";
34096
34292
  var PROCESS_CREATION = "{0CCE922B-69AE-11D9-BED3-505054503030}";
34097
34293
  var auditOn = () => Boolean(session.auditProcesses) && isWin && !dryRun;
34098
34294
  function enableProcessAudit() {
34099
34295
  if (!auditOn()) return;
34100
34296
  spawnSync9(
34101
- path69.join(process.env.WINDIR ?? "C:\\Windows", "System32", "auditpol.exe"),
34297
+ path70.join(process.env.WINDIR ?? "C:\\Windows", "System32", "auditpol.exe"),
34102
34298
  ["/set", "/subcategory:" + PROCESS_CREATION, "/success:enable"],
34103
34299
  { windowsHide: true, stdio: "ignore" }
34104
34300
  );
@@ -34122,10 +34318,10 @@ function enableProcessAudit() {
34122
34318
 
34123
34319
  // src/guest/vpn/vpn.ts
34124
34320
  import dns2 from "node:dns";
34125
- import fs60 from "node:fs";
34321
+ import fs61 from "node:fs";
34126
34322
  import net3 from "node:net";
34127
- import os14 from "node:os";
34128
- import path73 from "node:path";
34323
+ import os15 from "node:os";
34324
+ import path74 from "node:path";
34129
34325
 
34130
34326
  // src/shared/vpn/ovpn.ts
34131
34327
  var PROGRAM_DIRECTIVES = [
@@ -34648,8 +34844,8 @@ function tunnelAddressFromLog(log2) {
34648
34844
 
34649
34845
  // src/guest/vpn/openvpn.ts
34650
34846
  import crypto4 from "node:crypto";
34651
- import fs57 from "node:fs";
34652
- import path70 from "node:path";
34847
+ import fs58 from "node:fs";
34848
+ import path71 from "node:path";
34653
34849
 
34654
34850
  // src/shared/vpn/download.ts
34655
34851
  var OPENVPN_MSI = {
@@ -34679,7 +34875,7 @@ var WIREGUARD_MSI = {
34679
34875
 
34680
34876
  // src/guest/vpn/openvpn.ts
34681
34877
  function openvpnExe(env = process.env) {
34682
- return path70.join(env.ProgramFiles ?? "C:\\Program Files", "OpenVPN", "bin", "openvpn.exe");
34878
+ return path71.join(env.ProgramFiles ?? "C:\\Program Files", "OpenVPN", "bin", "openvpn.exe");
34683
34879
  }
34684
34880
  function openvpnDownload(arch2 = process.arch) {
34685
34881
  const entry = arch2 === "arm64" ? OPENVPN_MSI.arm64 : OPENVPN_MSI.x64;
@@ -34690,20 +34886,20 @@ function repairServiceQueries() {
34690
34886
  if (did === "removed") log("VPN: repaired the Windows service queries installers use (a Windows Sandbox gap).");
34691
34887
  else if (did !== "absent" && did !== "kept") warn("VPN: could not check the Windows service queries installers use.");
34692
34888
  }
34693
- var hasHash = (file3, sha256) => crypto4.createHash("sha256").update(fs57.readFileSync(file3)).digest("hex") === sha256;
34889
+ var hasHash = (file3, sha256) => crypto4.createHash("sha256").update(fs58.readFileSync(file3)).digest("hex") === sha256;
34694
34890
  async function ensureOpenVpn() {
34695
34891
  const exe = openvpnExe();
34696
34892
  if (!isWin || dryRun) return exe;
34697
34893
  if (exists(exe)) return exe;
34698
34894
  const dl = openvpnDownload();
34699
- const msi = path70.join(mkdirp(path70.join(toolsDir, "downloads")), dl.file);
34895
+ const msi = path71.join(mkdirp(path71.join(toolsDir, "downloads")), dl.file);
34700
34896
  if (!exists(msi) || !hasHash(msi, dl.sha256)) {
34701
34897
  log("VPN: downloading OpenVPN " + OPENVPN_MSI.version + " (about 6 MB)");
34702
34898
  await downloader.file(dl.url, msi, dl.sha256);
34703
34899
  }
34704
34900
  repairServiceQueries();
34705
34901
  log("VPN: installing OpenVPN");
34706
- const logFile2 = path70.join(toolsDir, "downloads", "openvpn-install.log");
34902
+ const logFile2 = path71.join(toolsDir, "downloads", "openvpn-install.log");
34707
34903
  const code = await spawnAsync(SYSTEM.msiexec(), ["/i", msi, "/qn", "/norestart", "/l*v", logFile2], {
34708
34904
  stdio: "ignore"
34709
34905
  });
@@ -34715,9 +34911,9 @@ async function ensureOpenVpn() {
34715
34911
 
34716
34912
  // src/guest/vpn/tunnel.ts
34717
34913
  import { spawn as spawn8 } from "node:child_process";
34718
- import fs58 from "node:fs";
34719
- import os12 from "node:os";
34720
- import path71 from "node:path";
34914
+ import fs59 from "node:fs";
34915
+ import os13 from "node:os";
34916
+ import path72 from "node:path";
34721
34917
  var DONE = "Initialization Sequence Completed";
34722
34918
  function failureReason(text) {
34723
34919
  if (/AUTH_FAILED/i.test(text))
@@ -34733,17 +34929,17 @@ function failureReason(text) {
34733
34929
  }
34734
34930
  var tail = (text, lines = 12) => text.trim().split(/\r?\n/).slice(-lines).join("\n");
34735
34931
  async function startTunnel(o) {
34736
- const dir = fs58.mkdtempSync(path71.join(os12.tmpdir(), "sbx-vpn-"));
34737
- const auth = path71.join(dir, "login.txt");
34738
- const logFile2 = path71.join(dir, "openvpn.log");
34932
+ const dir = fs59.mkdtempSync(path72.join(os13.tmpdir(), "sbx-vpn-"));
34933
+ const auth = path72.join(dir, "login.txt");
34934
+ const logFile2 = path72.join(dir, "openvpn.log");
34739
34935
  const keepLog = () => {
34740
34936
  try {
34741
- fs58.mkdirSync(logsDir, { recursive: true });
34742
- fs58.copyFileSync(logFile2, path71.join(logsDir, "openvpn.log"));
34937
+ fs59.mkdirSync(logsDir, { recursive: true });
34938
+ fs59.copyFileSync(logFile2, path72.join(logsDir, "openvpn.log"));
34743
34939
  } catch {
34744
34940
  }
34745
34941
  };
34746
- fs58.writeFileSync(auth, o.username + "\r\n" + o.password + "\r\n", "utf8");
34942
+ fs59.writeFileSync(auth, o.username + "\r\n" + o.password + "\r\n", "utf8");
34747
34943
  try {
34748
34944
  const child = spawn8(
34749
34945
  o.exe,
@@ -34761,7 +34957,7 @@ async function startTunnel(o) {
34761
34957
  child.unref();
34762
34958
  const deadline = Date.now() + (o.timeoutMs ?? 9e4);
34763
34959
  for (; ; ) {
34764
- const text = fs58.existsSync(logFile2) ? fs58.readFileSync(logFile2, "utf8") : "";
34960
+ const text = fs59.existsSync(logFile2) ? fs59.readFileSync(logFile2, "utf8") : "";
34765
34961
  if (text.includes(DONE)) {
34766
34962
  keepLog();
34767
34963
  const tunnelIp = tunnelAddressFromLog(text) ?? void 0;
@@ -34781,41 +34977,41 @@ async function startTunnel(o) {
34781
34977
  await new Promise((r) => setTimeout(r, 500));
34782
34978
  }
34783
34979
  } finally {
34784
- fs58.rmSync(auth, { force: true });
34980
+ fs59.rmSync(auth, { force: true });
34785
34981
  }
34786
34982
  }
34787
34983
 
34788
34984
  // src/guest/vpn/wireguard.ts
34789
34985
  import { execFile } from "node:child_process";
34790
34986
  import crypto5 from "node:crypto";
34791
- import fs59 from "node:fs";
34792
- import os13 from "node:os";
34793
- import path72 from "node:path";
34987
+ import fs60 from "node:fs";
34988
+ import os14 from "node:os";
34989
+ import path73 from "node:path";
34794
34990
  var WIREGUARD_TUNNEL = "sandbox";
34795
34991
  function wireguardDir(env = process.env) {
34796
- return path72.join(env.ProgramFiles ?? "C:\\Program Files", "WireGuard");
34992
+ return path73.join(env.ProgramFiles ?? "C:\\Program Files", "WireGuard");
34797
34993
  }
34798
34994
  function wireguardExe(env = process.env) {
34799
- return path72.join(wireguardDir(env), "wireguard.exe");
34995
+ return path73.join(wireguardDir(env), "wireguard.exe");
34800
34996
  }
34801
34997
  function wireguardDownload(arch2 = process.arch) {
34802
34998
  const entry = arch2 === "arm64" ? WIREGUARD_MSI.arm64 : WIREGUARD_MSI.x64;
34803
34999
  return { ...entry, url: WIREGUARD_MSI.base + entry.file };
34804
35000
  }
34805
- var hasHash2 = (file3, sha256) => crypto5.createHash("sha256").update(fs59.readFileSync(file3)).digest("hex") === sha256;
35001
+ var hasHash2 = (file3, sha256) => crypto5.createHash("sha256").update(fs60.readFileSync(file3)).digest("hex") === sha256;
34806
35002
  async function ensureWireguard() {
34807
35003
  const exe = wireguardExe();
34808
35004
  if (!isWin || dryRun) return exe;
34809
35005
  if (exists(exe)) return exe;
34810
35006
  const dl = wireguardDownload();
34811
- const msi = path72.join(mkdirp(path72.join(toolsDir, "downloads")), dl.file);
35007
+ const msi = path73.join(mkdirp(path73.join(toolsDir, "downloads")), dl.file);
34812
35008
  if (!exists(msi) || !hasHash2(msi, dl.sha256)) {
34813
35009
  log("VPN: downloading WireGuard " + WIREGUARD_MSI.version + " (about 3 MB)");
34814
35010
  await downloader.file(dl.url, msi, dl.sha256);
34815
35011
  }
34816
35012
  repairServiceQueries();
34817
35013
  log("VPN: installing WireGuard");
34818
- const logFile2 = path72.join(toolsDir, "downloads", "wireguard-install.log");
35014
+ const logFile2 = path73.join(toolsDir, "downloads", "wireguard-install.log");
34819
35015
  const code = await spawnAsync(
34820
35016
  SYSTEM.msiexec(),
34821
35017
  ["/i", msi, "/qn", "/norestart", "DO_NOT_LAUNCH=1", "/l*v", logFile2],
@@ -34839,7 +35035,7 @@ function output2(file3, args) {
34839
35035
  });
34840
35036
  }
34841
35037
  var serviceName = () => "WireGuardTunnel$" + WIREGUARD_TUNNEL;
34842
- var hasAdapter = (ip) => Object.values(os13.networkInterfaces()).some((list) => (list ?? []).some((i) => i.address === ip));
35038
+ var hasAdapter = (ip) => Object.values(os14.networkInterfaces()).some((list) => (list ?? []).some((i) => i.address === ip));
34843
35039
  async function removeWireguardTunnel(exe) {
34844
35040
  try {
34845
35041
  await output2(exe, ["/uninstalltunnelservice", WIREGUARD_TUNNEL]);
@@ -34847,10 +35043,10 @@ async function removeWireguardTunnel(exe) {
34847
35043
  }
34848
35044
  }
34849
35045
  async function startWireguardTunnel(o) {
34850
- const root = path72.join(process.env.SystemRoot ?? "C:\\Windows", "Temp");
34851
- const dir = fs59.mkdtempSync(path72.join(fs59.existsSync(root) ? root : os13.tmpdir(), "sbx-wg-"));
34852
- const file3 = path72.join(dir, WIREGUARD_TUNNEL + ".conf");
34853
- fs59.writeFileSync(file3, o.config, "utf8");
35046
+ const root = path73.join(process.env.SystemRoot ?? "C:\\Windows", "Temp");
35047
+ const dir = fs60.mkdtempSync(path73.join(fs60.existsSync(root) ? root : os14.tmpdir(), "sbx-wg-"));
35048
+ const file3 = path73.join(dir, WIREGUARD_TUNNEL + ".conf");
35049
+ fs60.writeFileSync(file3, o.config, "utf8");
34854
35050
  const fail = async (message) => {
34855
35051
  await removeWireguardTunnel(o.exe);
34856
35052
  return { ok: false, message };
@@ -34871,11 +35067,11 @@ async function startWireguardTunnel(o) {
34871
35067
  await sleep(500);
34872
35068
  }
34873
35069
  } finally {
34874
- fs59.rmSync(dir, { recursive: true, force: true });
35070
+ fs60.rmSync(dir, { recursive: true, force: true });
34875
35071
  }
34876
35072
  }
34877
35073
  async function waitForHandshake(exe, poke, timeoutMs = 3e4) {
34878
- const wg = path72.join(path72.dirname(exe), "wg.exe");
35074
+ const wg = path73.join(path73.dirname(exe), "wg.exe");
34879
35075
  if (!exists(wg)) return { ok: true, message: "the tunnel service is running (no wg.exe to check the handshake)" };
34880
35076
  const deadline = Date.now() + timeoutMs;
34881
35077
  for (; ; ) {
@@ -34939,7 +35135,7 @@ async function publicAddress() {
34939
35135
  return null;
34940
35136
  }
34941
35137
  }
34942
- var hasAdapter2 = (ip) => Object.values(os14.networkInterfaces()).some((list) => (list ?? []).some((i) => i.address === ip));
35138
+ var hasAdapter2 = (ip) => Object.values(os15.networkInterfaces()).some((list) => (list ?? []).some((i) => i.address === ip));
34943
35139
  var PROBE_TARGETS = ["1.1.1.1", "8.8.8.8", "9.9.9.9"];
34944
35140
  var PROBE_TIMEOUT_MS = 3e3;
34945
35141
  function connects(ip, port) {
@@ -35010,8 +35206,8 @@ async function setupVpn(secrets, ptyHostExe) {
35010
35206
  } else {
35011
35207
  const credentials = secrets.vpn;
35012
35208
  if (!credentials) throw new Error("the VPN login did not arrive (start the sandbox again)");
35013
- const profile = path73.join(launchDir, "vpn", "server.ovpn");
35014
- const remotes = assertSafeOvpn(fs60.readFileSync(profile, "utf8"), vpn.server);
35209
+ const profile = path74.join(launchDir, "vpn", "server.ovpn");
35210
+ const remotes = assertSafeOvpn(fs61.readFileSync(profile, "utf8"), vpn.server);
35015
35211
  const exe = await ensureOpenVpn();
35016
35212
  const servers = await serverAddresses(remotes);
35017
35213
  if (servers.length === 0) throw new Error("the VPN server addresses could not be found");
@@ -35697,7 +35893,7 @@ async function viewSession(id) {
35697
35893
  }
35698
35894
 
35699
35895
  // src/guest/boot/boot-env.ts
35700
- import path74 from "node:path";
35896
+ import path75 from "node:path";
35701
35897
 
35702
35898
  // src/guest/boot/project-env.ts
35703
35899
  var EnvSchema = external_exports.object({
@@ -35716,7 +35912,7 @@ var BootEnvSchema = external_exports.object({
35716
35912
  });
35717
35913
 
35718
35914
  // src/guest/boot/boot-env.ts
35719
- var file2 = () => path74.join(localDir, "boot-env.json");
35915
+ var file2 = () => path75.join(localDir, "boot-env.json");
35720
35916
  function saveBootEnv(value) {
35721
35917
  try {
35722
35918
  writeJsonAtomic(file2(), value);
@@ -35745,7 +35941,7 @@ function saveProjectStatus(name, workspace2, phase, message, databases, summary)
35745
35941
  }
35746
35942
 
35747
35943
  // src/guest/runtime/secrets.ts
35748
- import fs61 from "node:fs";
35944
+ import fs62 from "node:fs";
35749
35945
 
35750
35946
  // src/shared/channel/secrets.ts
35751
35947
  var Environment = external_exports.record(external_exports.string().max(256), external_exports.string().max(65536));
@@ -35775,12 +35971,12 @@ function takeSecrets(id) {
35775
35971
  const file3 = run.secretFile(id);
35776
35972
  let text;
35777
35973
  try {
35778
- if (fs61.statSync(file3).size > MAX_BYTES) throw new Error("too big");
35779
- text = fs61.readFileSync(file3, "utf8").replace(/^\uFEFF/, "");
35974
+ if (fs62.statSync(file3).size > MAX_BYTES) throw new Error("too big");
35975
+ text = fs62.readFileSync(file3, "utf8").replace(/^\uFEFF/, "");
35780
35976
  } catch {
35781
35977
  return {};
35782
35978
  } finally {
35783
- fs61.rmSync(file3, { force: true });
35979
+ fs62.rmSync(file3, { force: true });
35784
35980
  }
35785
35981
  try {
35786
35982
  const parsed = SecretsFileSchema.safeParse(JSON.parse(text));
@@ -35818,7 +36014,7 @@ async function soft(what, work) {
35818
36014
  }
35819
36015
  }
35820
36016
  function startDaemon(env, secrets) {
35821
- spawn10(process.execPath, [path75.join(path75.dirname(process.argv[1]), "daemon.js")], {
36017
+ spawn10(process.execPath, [path76.join(path76.dirname(process.argv[1]), "daemon.js")], {
35822
36018
  detached: true,
35823
36019
  stdio: "ignore",
35824
36020
  windowsHide: true,
@@ -35837,20 +36033,20 @@ function startDaemon(env, secrets) {
35837
36033
  }).unref();
35838
36034
  }
35839
36035
  function writeDbCommand() {
35840
- const dir = mkdirp(path75.join(localDir, "bin"));
35841
- const db = path75.join(path75.dirname(process.argv[1]), "db.js");
35842
- fs62.writeFileSync(
35843
- path75.join(dir, "sbx-db.cmd"),
36036
+ const dir = mkdirp(path76.join(localDir, "bin"));
36037
+ const db = path76.join(path76.dirname(process.argv[1]), "db.js");
36038
+ fs63.writeFileSync(
36039
+ path76.join(dir, "sbx-db.cmd"),
35844
36040
  '@setlocal\r\n@set AGENT_LOG_PREFIX=db\r\n@"' + process.execPath + '" "' + db + '" %*\r\n'
35845
36041
  );
35846
36042
  writeAgentCommands(dir);
35847
36043
  return dir;
35848
36044
  }
35849
36045
  function writeAgentCommands(dir) {
35850
- const install = { node: process.execPath, script: path75.join(path75.dirname(process.argv[1]), "agent.js") };
36046
+ const install = { node: process.execPath, script: path76.join(path76.dirname(process.argv[1]), "agent.js") };
35851
36047
  for (const shim3 of agentShims(toolsDir, session.agents ?? {}))
35852
- fs62.writeFileSync(path75.join(dir, shim3.command + ".cmd"), shimText(shim3, install));
35853
- fs62.writeFileSync(path75.join(dir, "sbx-agent.cmd"), sbxAgentText(install));
36048
+ fs63.writeFileSync(path76.join(dir, shim3.command + ".cmd"), shimText(shim3, install));
36049
+ fs63.writeFileSync(path76.join(dir, "sbx-agent.cmd"), sbxAgentText(install));
35854
36050
  }
35855
36051
  async function waitForPrimary() {
35856
36052
  for (let i = 0; i < PRIMARY_POLLS; i++) {
@@ -35878,7 +36074,7 @@ var Boot = class {
35878
36074
  log(
35879
36075
  "Agent sandbox: " + session.project + " | workspace " + workspace + " | agent " + session.harnessName + " | log " + logPath
35880
36076
  );
35881
- if (!fs62.statSync(workspace, { throwIfNoEntry: false })?.isDirectory())
36077
+ if (!fs63.statSync(workspace, { throwIfNoEntry: false })?.isDirectory())
35882
36078
  throw new Error("Workspace folder is missing in the sandbox: " + workspace);
35883
36079
  mkdirp(toolsDir);
35884
36080
  mkdirp(run.root);
@@ -35910,6 +36106,7 @@ var Boot = class {
35910
36106
  step(2, "Pre-provision hooks and desktop");
35911
36107
  runHooks("pre-provision", process.env);
35912
36108
  await soft("Personalisation", applyPersonalization);
36109
+ await soft("Browsers without the GPU", keepBrowsersOffGpu);
35913
36110
  }
35914
36111
  /** Toolchains, databases, apps, the network proxy and VS Code; then the agent environment, saved machine-wide. */
35915
36112
  async developerTools() {
@@ -36038,11 +36235,11 @@ runBoot().catch((e) => {
36038
36235
  const message = errMsg(e) + (e instanceof Error && e.stack ? "\n" + e.stack : "");
36039
36236
  try {
36040
36237
  setSandboxStatus("failed", errMsg(e));
36041
- fs63.writeFileSync(path76.join(logsDir, "guest-error.txt"), message);
36238
+ fs64.writeFileSync(path77.join(logsDir, "guest-error.txt"), message);
36042
36239
  } catch {
36043
36240
  }
36044
36241
  console.error(
36045
- "\n\x1B[31mThe sandbox could not start: " + errMsg(e) + "\x1B[0m\nDetails: " + path76.join(logsDir, "guest-error.txt")
36242
+ "\n\x1B[31mThe sandbox could not start: " + errMsg(e) + "\x1B[0m\nDetails: " + path77.join(logsDir, "guest-error.txt")
36046
36243
  );
36047
36244
  process.exitCode = 1;
36048
36245
  });