windows-development-sandbox 1.16.0 → 1.17.3

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 (64) hide show
  1. package/README.md +92 -92
  2. package/config.example.json +6 -0
  3. package/dist/app/features/access/access.run.js +1 -1
  4. package/dist/bin/agent-sandbox.js +2 -2
  5. package/dist/bin/{chunk-7EXDUNE7.js → chunk-QLGGAG3D.js} +1 -1
  6. package/dist/bin/{chunk-HIC4CUMY.js → chunk-REE3EMHD.js} +73 -16
  7. package/dist/bin/{chunk-PXTLKIV4.js → chunk-XYUVIVJT.js} +1 -1
  8. package/dist/bin/claude-host.js +2 -2
  9. package/dist/bin/claude-sbx.js +2 -2
  10. package/dist/bin/codex-sbx.js +2 -2
  11. package/dist/bin/gemini-sbx.js +2 -2
  12. package/dist/bin/sandbox.js +2 -2
  13. package/dist/bin/sbx-hide.js +2 -2
  14. package/dist/bin/sbx-show.js +2 -2
  15. package/dist/cli/commands/web.js +1 -1
  16. package/dist/core/config/defaults.js +1 -0
  17. package/dist/core/detect/toolchains.d.ts +1 -0
  18. package/dist/core/detect/toolchains.js +7 -0
  19. package/dist/core/schema/config.d.ts +21 -0
  20. package/dist/core/schema/sandbox.js +1 -1
  21. package/dist/core/schema/toolchains.d.ts +6 -0
  22. package/dist/core/schema/toolchains.js +10 -0
  23. package/dist/guest/agents/agent-files.d.ts +6 -0
  24. package/dist/guest/agents/agent-files.js +14 -0
  25. package/dist/guest/agents/local-state.d.ts +2 -0
  26. package/dist/guest/agents/local-state.js +13 -1
  27. package/dist/guest/boot/boot.js +4 -1
  28. package/dist/guest/setup/browser-gpu.d.ts +1 -0
  29. package/dist/guest/setup/browser-gpu.js +18 -0
  30. package/dist/guest/toolchains/native/rust-extras.js +3 -1
  31. package/dist/guest/toolchains/native/unreal.d.ts +9 -0
  32. package/dist/guest/toolchains/native/unreal.js +198 -0
  33. package/dist/guest/toolchains/native/vcruntime.d.ts +3 -0
  34. package/dist/guest/toolchains/native/vcruntime.js +2 -2
  35. package/dist/guest/toolchains/plan.js +10 -2
  36. package/dist/host/engines/hcs/live-folders.js +1 -1
  37. package/dist/host/github/token.js +1 -1
  38. package/dist/host/profile/accounts.js +1 -1
  39. package/dist/host/profile/agent-accounts.js +1 -1
  40. package/dist/host/profile/plugin-share.d.ts +5 -0
  41. package/dist/host/profile/plugin-share.js +22 -1
  42. package/dist/host/secrets/secret-store.d.ts +3 -3
  43. package/dist/host/secrets/secret-store.js +37 -10
  44. package/dist/host/vpn/login.js +1 -1
  45. package/dist/runtime/agent.js +16 -1
  46. package/dist/runtime/daemon.js +531 -337
  47. package/dist/runtime/db.js +17 -1
  48. package/dist/runtime/main.js +694 -472
  49. package/dist/runtime/netproxy.js +16 -1
  50. package/dist/runtime/view.js +16 -1
  51. package/dist/selftest/accounts.test.js +7 -0
  52. package/dist/selftest/agent-paths.test.js +12 -1
  53. package/dist/selftest/detect.test.js +7 -0
  54. package/dist/selftest/live-network.test.js +5 -0
  55. package/dist/selftest/support/fixtures.d.ts +6 -0
  56. package/dist/shared/channel/schema.d.ts +18 -0
  57. package/native/csharp/HcsHost/AssemblyInfo.cs +3 -3
  58. package/native/csharp/HostTools/AssemblyInfo.cs +3 -3
  59. package/native/csharp/HostTools/Program.cs +6 -1
  60. package/native/csharp/HostTools/Protect.cs +41 -0
  61. package/native/csharp/StorageHelper/AssemblyInfo.cs +3 -3
  62. package/package.json +1 -1
  63. package/schemas/config.schema.json +34 -1
  64. package/schemas/sandbox-config.schema.json +34 -1
@@ -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,230 @@ 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 INSTALL_ROOM_BYTES = 20 * 1024 ** 3;
30331
+ var ID = /^[A-Za-z0-9][A-Za-z0-9._-]{0,199}$/;
30332
+ var VS_DIR = tool("visualstudio");
30333
+ var BOOTSTRAPPER = path44.join(VS_DIR, "vs_community.exe");
30334
+ var LAYOUT = path44.join(VS_DIR, "layout");
30335
+ var LAYOUT_MARKER = path44.join(LAYOUT, ".complete.json");
30336
+ var LayoutSchema = external_exports.object({ components: external_exports.array(external_exports.string()) });
30337
+ var VSWHERE = path44.join(
30338
+ process.env["ProgramFiles(x86)"] ?? "C:\\Program Files (x86)",
30339
+ "Microsoft Visual Studio",
30340
+ "Installer",
30341
+ "vswhere.exe"
30342
+ );
30343
+ function installedVs() {
30344
+ if (!exists(VSWHERE)) return null;
30345
+ const ask = (property) => execOutput(VSWHERE, [
30346
+ "-latest",
30347
+ "-products",
30348
+ "*",
30349
+ "-requires",
30350
+ "Microsoft.VisualStudio.Component.VC.Tools.x86.x64",
30351
+ "-property",
30352
+ property
30353
+ ]);
30354
+ const at = ask("installationPath");
30355
+ return at ? { path: at, version: ask("installationVersion") || "installed" } : null;
30356
+ }
30357
+ async function signedInstaller(url2, file3, what) {
30358
+ if (!exists(file3)) {
30359
+ log("Downloading " + what + " ...");
30360
+ mkdirp(path44.dirname(file3));
30361
+ await downloadFile(url2, file3);
30362
+ }
30363
+ if (signerOf(file3) !== MICROSOFT_SIGNER) {
30364
+ fs36.rmSync(file3, { force: true });
30365
+ throw new Error(path44.basename(file3) + " is not signed by Microsoft; deleted it (it is downloaded again next boot)");
30366
+ }
30367
+ return file3;
30368
+ }
30369
+ function freeBytes(dir) {
30370
+ try {
30371
+ const s = fs36.statfsSync(dir);
30372
+ return s.bavail * s.bsize;
30373
+ } catch {
30374
+ return 0;
30375
+ }
30376
+ }
30377
+ async function layoutInstaller(bootstrapper, ids) {
30378
+ const installer = path44.join(LAYOUT, "vs_community.exe");
30379
+ const has = () => {
30380
+ if (!exists(LAYOUT_MARKER) || !exists(installer)) return false;
30381
+ try {
30382
+ const done = LayoutSchema.parse(JSON.parse(fs36.readFileSync(LAYOUT_MARKER, "utf8")));
30383
+ return ids.every((id) => done.components.includes(id));
30384
+ } catch {
30385
+ return false;
30386
+ }
30387
+ };
30388
+ if (has()) return installer;
30389
+ if (freeBytes(mkdirp(VS_DIR)) < LAYOUT_ROOM_BYTES) {
30390
+ warn("unreal: not keeping the install files (less than 15 GB free in " + VS_DIR + "); downloading this boot");
30391
+ return null;
30392
+ }
30393
+ log("Saving the Visual Studio install files for later boots (~10 GB, once) ...");
30394
+ fs36.rmSync(LAYOUT_MARKER, { force: true });
30395
+ const code = await spawnAsync(bootstrapper, [
30396
+ "--layout",
30397
+ LAYOUT,
30398
+ "--lang",
30399
+ "en-US",
30400
+ "--quiet",
30401
+ "--wait",
30402
+ ...ids.flatMap((id) => ["--add", id])
30403
+ ]);
30404
+ if (!OK_EXIT_CODES2.includes(code) || !exists(installer)) {
30405
+ warn("unreal: saving the install files failed (exit " + code + "); downloading this boot");
30406
+ return null;
30407
+ }
30408
+ writeJsonAtomic(LAYOUT_MARKER, { components: [...ids] });
30409
+ return installer;
30410
+ }
30411
+ async function installVisualStudio(config2, ids) {
30412
+ const bootstrapper = await signedInstaller(BOOTSTRAPPER_URL, BOOTSTRAPPER, "the Visual Studio installer");
30413
+ let installer = null;
30414
+ if (config2.keepInstallFiles) {
30415
+ try {
30416
+ installer = await layoutInstaller(bootstrapper, ids);
30417
+ } catch (e) {
30418
+ warn("unreal: the offline copy failed (" + errMsg(e) + "); downloading this boot");
30419
+ }
30420
+ }
30421
+ log(
30422
+ "Installing Visual Studio Community 2022 with the C++ game workload" + (installer ? " from the saved install files" : " (downloads ~5-8 GB)") + " ..."
30423
+ );
30424
+ const code = await spawnAsync(installer ?? bootstrapper, [
30425
+ "--quiet",
30426
+ "--wait",
30427
+ "--norestart",
30428
+ "--nocache",
30429
+ ...installer ? ["--noWeb"] : [],
30430
+ ...ids.flatMap((id) => ["--add", id])
30431
+ ]);
30432
+ if (!OK_EXIT_CODES2.includes(code) || !installedVs())
30433
+ throw new Error(
30434
+ "the Visual Studio installer failed (exit " + code + "); its logs are the dd_*.log files in " + os7.tmpdir()
30435
+ );
30436
+ }
30437
+ async function installDirectX() {
30438
+ const system322 = path44.join(process.env.WINDIR ?? "C:\\Windows", "System32");
30439
+ if (exists(path44.join(system322, "d3dx9_43.dll")) && exists(path44.join(system322, "XAudio2_7.dll"))) return;
30440
+ const redist = await signedInstaller(
30441
+ DIRECTX_URL,
30442
+ path44.join(VS_DIR, "directx_Jun2010_redist.exe"),
30443
+ "the DirectX End-User Runtime (~95 MB once)"
30444
+ );
30445
+ const unpacked = path44.join(os7.tmpdir(), "directx-redist");
30446
+ safeRemove(unpacked, os7.tmpdir());
30447
+ mkdirp(unpacked);
30448
+ if (await spawnAsync(redist, ["/Q", "/T:" + unpacked]) !== 0 || !exists(path44.join(unpacked, "DXSETUP.exe")))
30449
+ throw new Error("could not unpack the DirectX End-User Runtime");
30450
+ const code = await spawnAsync(path44.join(unpacked, "DXSETUP.exe"), ["/silent"]);
30451
+ safeRemove(unpacked, os7.tmpdir());
30452
+ if (code !== 0) throw new Error("the DirectX End-User Runtime installer failed (exit " + code + ")");
30453
+ }
30454
+ async function setupUnreal(env, config2) {
30455
+ if (!config2.acceptLicense)
30456
+ throw new Error(
30457
+ "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/)"
30458
+ );
30459
+ const bad = config2.components.find((id) => !ID.test(id));
30460
+ if (bad) throw new Error('toolchains.unreal.components: "' + bad + '" is not a Visual Studio component ID');
30461
+ const ids = [.../* @__PURE__ */ new Set([...UNREAL_COMPONENTS, ...config2.components])];
30462
+ if (dryRun) {
30463
+ log("(dry run) would install Visual Studio Community 2022 with " + ids.join(", ") + " and DirectX");
30464
+ return;
30465
+ }
30466
+ if (!installedVs()) {
30467
+ const programFiles = process.env.ProgramFiles ?? "C:\\Program Files";
30468
+ const free = freeBytes(programFiles);
30469
+ if (free < INSTALL_ROOM_BYTES)
30470
+ throw new Error(
30471
+ "not installing Visual Studio: the sandbox disk has " + (free / 1024 ** 3).toFixed(1) + " GB free and it needs 20 GB (7 GB for Visual Studio, the rest for builds and the paging file)"
30472
+ );
30473
+ await installVisualStudio(config2, ids);
30474
+ }
30475
+ await installDirectX();
30476
+ const vs = installedVs();
30477
+ env.summary.push(
30478
+ "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)"
30479
+ );
30480
+ }
30481
+
30482
+ // src/guest/toolchains/native/rust.ts
30483
+ import path46 from "node:path";
30484
+
30485
+ // src/guest/toolchains/native/binstall.ts
30486
+ import fs37 from "node:fs";
30487
+ import path45 from "node:path";
30267
30488
  var ensureBinstall = async (cargoBin) => {
30268
- const target = path43.join(cargoBin, "cargo-binstall.exe");
30489
+ const target = path45.join(cargoBin, "cargo-binstall.exe");
30269
30490
  if (exists(target)) return true;
30270
30491
  try {
30271
30492
  const dir = tool("cargo-binstall");
30272
- if (!exists(path43.join(dir, "cargo-binstall.exe"))) {
30493
+ if (!exists(path45.join(dir, "cargo-binstall.exe"))) {
30273
30494
  await installFromGithub("cargo-bins/cargo-binstall", binstallAsset(arch), {
30274
30495
  dest: dir,
30275
30496
  what: "cargo-binstall for prebuilt Rust tools (~10 MB once)",
30276
30497
  locate: "cargo-binstall.exe"
30277
30498
  });
30278
30499
  }
30279
- fs35.copyFileSync(path43.join(dir, "cargo-binstall.exe"), target);
30500
+ fs37.copyFileSync(path45.join(dir, "cargo-binstall.exe"), target);
30280
30501
  return true;
30281
30502
  } catch (e) {
30282
30503
  warn("cargo-binstall unavailable, compiling crates with cargo install instead: " + errMsg(e));
@@ -30284,14 +30505,14 @@ var ensureBinstall = async (cargoBin) => {
30284
30505
  }
30285
30506
  };
30286
30507
  function crateInstaller(cargoHome, cargoEnv) {
30287
- const cargo = path43.join(cargoHome, "bin", "cargo.exe");
30508
+ const cargo = path45.join(cargoHome, "bin", "cargo.exe");
30288
30509
  let binstall = null;
30289
30510
  const binstallEnv = {
30290
30511
  ...cargoEnv,
30291
30512
  env: { ...cargoEnv.env ?? process.env, BINSTALL_DISABLE_TELEMETRY: "true" }
30292
30513
  };
30293
30514
  return async (crate) => {
30294
- binstall ??= ensureBinstall(path43.join(cargoHome, "bin"));
30515
+ binstall ??= ensureBinstall(path45.join(cargoHome, "bin"));
30295
30516
  if (await binstall) {
30296
30517
  try {
30297
30518
  await execAsync(
@@ -30313,7 +30534,7 @@ async function setupRust(env, config2, refresh) {
30313
30534
  const RUSTUP_HOME = tool("rust", "rustup");
30314
30535
  const CARGO_HOME = tool("rust", "cargo");
30315
30536
  const rustEnv = { env: { ...process.env, RUSTUP_HOME, CARGO_HOME } };
30316
- const rustup = path44.join(CARGO_HOME, "bin", "rustup.exe");
30537
+ const rustup = path46.join(CARGO_HOME, "bin", "rustup.exe");
30317
30538
  if (dryRun) {
30318
30539
  log("(dry run) would provision Rust " + config2.toolchain + " (" + config2.host + ")");
30319
30540
  return;
@@ -30349,9 +30570,9 @@ async function setupRust(env, config2, refresh) {
30349
30570
  if (refresh) await execAsync(rustup, ["update"], rustEnv);
30350
30571
  }
30351
30572
  Object.assign(env.vars, { RUSTUP_HOME, CARGO_HOME });
30352
- env.prepend.push(path44.join(CARGO_HOME, "bin"));
30573
+ env.prepend.push(path46.join(CARGO_HOME, "bin"));
30353
30574
  env.summary.push(
30354
- "rust: " + versionOf(path44.join(CARGO_HOME, "bin", "rustc.exe"), ["--version"], rustEnv) + " [" + config2.host + "]"
30575
+ "rust: " + versionOf(path46.join(CARGO_HOME, "bin", "rustc.exe"), ["--version"], rustEnv) + " [" + config2.host + "]"
30355
30576
  );
30356
30577
  const toolchainKey = "rustup@" + config2.toolchain;
30357
30578
  await installOnce(
@@ -30372,36 +30593,36 @@ async function setupRust(env, config2, refresh) {
30372
30593
  env: {
30373
30594
  ...rustEnv.env,
30374
30595
  ...msvc.vars,
30375
- PATH: [path44.join(CARGO_HOME, "bin"), ...msvc.path, process.env.PATH ?? ""].join(path44.delimiter)
30596
+ PATH: [path46.join(CARGO_HOME, "bin"), ...msvc.path, process.env.PATH ?? ""].join(path46.delimiter)
30376
30597
  }
30377
30598
  } : {
30378
30599
  env: {
30379
30600
  ...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)
30601
+ CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER: path46.join(mingw, "gcc.exe"),
30602
+ PATH: [path46.join(CARGO_HOME, "bin"), mingw, process.env.PATH ?? ""].join(path46.delimiter)
30382
30603
  }
30383
30604
  };
30384
30605
  await installOnce(env, "cargo", config2.crates, crateInstaller(CARGO_HOME, cargoEnv));
30385
30606
  }
30386
30607
 
30387
30608
  // src/guest/toolchains/languages/node.ts
30388
- import fs36 from "node:fs";
30389
- import path45 from "node:path";
30609
+ import fs38 from "node:fs";
30610
+ import path47 from "node:path";
30390
30611
  import { spawn as spawn4 } from "node:child_process";
30391
30612
  var NVM_HOME = tool("nvm");
30392
- var NVM_SYMLINK = path45.join(localDir, "nodejs");
30393
- var HOST_NVM = path45.join(hostToolsDir, "nvm");
30613
+ var NVM_SYMLINK = path47.join(localDir, "nodejs");
30614
+ var HOST_NVM = path47.join(hostToolsDir, "nvm");
30394
30615
  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)) : [];
30616
+ 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
30617
  var resolveNode = (spec) => resolveCached("node:" + spec, async () => {
30397
30618
  const exact = spec.replace(/^v/, "");
30398
30619
  if (/^\d+\.\d+\.\d+$/.test(exact)) return exact;
30399
30620
  const releases = await fetchJson("https://nodejs.org/dist/index.json");
30400
30621
  return pickNodeVersion(releases, spec) ?? Promise.reject(new Error('No Node.js release matches "' + spec + '"'));
30401
30622
  });
30402
- var NVM_TEMP = path45.join(NVM_HOME, ".tmp");
30623
+ var NVM_TEMP = path47.join(NVM_HOME, ".tmp");
30403
30624
  var nvm = (args) => new Promise((resolve2) => {
30404
- const child = spawn4(path45.join(NVM_HOME, "nvm.exe"), args, {
30625
+ const child = spawn4(path47.join(NVM_HOME, "nvm.exe"), args, {
30405
30626
  windowsHide: true,
30406
30627
  env: { ...process.env, NVM_HOME, NVM_SYMLINK, TEMP: NVM_TEMP, TMP: NVM_TEMP }
30407
30628
  });
@@ -30416,12 +30637,12 @@ var nvm = (args) => new Promise((resolve2) => {
30416
30637
  child.once("close", () => resolve2(out));
30417
30638
  });
30418
30639
  var ensureNvm = async () => {
30419
- if (exists(path45.join(NVM_HOME, "nvm.exe"))) return;
30420
- if (exists(path45.join(HOST_NVM, "nvm.exe"))) {
30640
+ if (exists(path47.join(NVM_HOME, "nvm.exe"))) return;
30641
+ if (exists(path47.join(HOST_NVM, "nvm.exe"))) {
30421
30642
  log("Copying nvm from this PC ...");
30422
30643
  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));
30644
+ 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"));
30645
+ for (const file3 of files) fs38.copyFileSync(path47.join(HOST_NVM, file3), path47.join(NVM_HOME, file3));
30425
30646
  return;
30426
30647
  }
30427
30648
  const asset = await githubAsset("coreybutler/nvm-windows", /^nvm-noinstall\.zip$/, true);
@@ -30429,14 +30650,14 @@ var ensureNvm = async () => {
30429
30650
  await downloader.archive(asset.url, NVM_HOME, { sha256: asset.sha256, locate: "nvm.exe", fileName: asset.name });
30430
30651
  };
30431
30652
  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;
30653
+ const dir = path47.join(hostToolsDir, "node");
30654
+ return session.hostTools.nodeVersion?.replace(/^v/, "") === version2 && exists(path47.join(dir, "node.exe")) ? dir : null;
30434
30655
  };
30435
30656
  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"))) {
30657
+ const dir = path47.join(NVM_HOME, "v" + version2);
30658
+ const fromHost = path47.join(HOST_NVM, "v" + version2);
30659
+ if (exists(path47.join(dir, "node.exe"))) return;
30660
+ if (exists(path47.join(fromHost, "node.exe"))) {
30440
30661
  log("Copying Node " + version2 + " from this PC's nvm (without global packages) ...");
30441
30662
  copyNode(fromHost, dir);
30442
30663
  return;
@@ -30455,19 +30676,19 @@ var installNodeVersion = async (version2) => {
30455
30676
  } finally {
30456
30677
  safeRemove(NVM_TEMP, NVM_HOME);
30457
30678
  }
30458
- if (!exists(path45.join(dir, "node.exe"))) {
30679
+ if (!exists(path47.join(dir, "node.exe"))) {
30459
30680
  const tail2 = out.trim().split(/\r?\n/).filter(Boolean).slice(-3).join(" ");
30460
30681
  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
30682
  throw new Error(
30462
- "nvm install " + version2 + " did not leave " + path45.join(dir, "node.exe") + " (" + why + ")" + (tail2 ? ". nvm printed: " + tail2 : "")
30683
+ "nvm install " + version2 + " did not leave " + path47.join(dir, "node.exe") + " (" + why + ")" + (tail2 ? ". nvm printed: " + tail2 : "")
30463
30684
  );
30464
30685
  }
30465
30686
  };
30466
30687
  var activate = async (version2) => {
30467
30688
  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");
30689
+ if (exists(path47.join(NVM_SYMLINK, "node.exe"))) return;
30690
+ fs38.rmSync(NVM_SYMLINK, { recursive: true, force: true });
30691
+ fs38.symlinkSync(path47.join(NVM_HOME, "v" + version2), NVM_SYMLINK, "junction");
30471
30692
  };
30472
30693
  var PLAYWRIGHT_VARS = () => ({
30473
30694
  PLAYWRIGHT_BROWSERS_PATH: tool("ms-playwright"),
@@ -30479,8 +30700,8 @@ async function setupNode(env, versions, config2) {
30479
30700
  return;
30480
30701
  }
30481
30702
  await ensureNvm();
30482
- fs36.writeFileSync(
30483
- path45.join(NVM_HOME, "settings.txt"),
30703
+ fs38.writeFileSync(
30704
+ path47.join(NVM_HOME, "settings.txt"),
30484
30705
  [
30485
30706
  "root: " + NVM_HOME,
30486
30707
  "path: " + NVM_SYMLINK,
@@ -30507,7 +30728,7 @@ async function setupNode(env, versions, config2) {
30507
30728
  }
30508
30729
  }
30509
30730
  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);
30731
+ if (duringSession()) env.prepend.push(path47.join(NVM_HOME, "v" + main), NVM_HOME, NVM_SYMLINK);
30511
30732
  else {
30512
30733
  await activate(main);
30513
30734
  env.prepend.push(NVM_HOME, NVM_SYMLINK);
@@ -30517,13 +30738,13 @@ async function setupNode(env, versions, config2) {
30517
30738
  await packageManagers(env, config2, main);
30518
30739
  }
30519
30740
  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], {
30741
+ const dir = path47.join(NVM_HOME, "v" + version2);
30742
+ const nodeEnv = { ...process.env, PATH: dir + path47.delimiter + (process.env.PATH ?? "") };
30743
+ const npm = (args) => execAsync(path47.join(dir, "node.exe"), [path47.join(dir, "node_modules", "npm", "bin", "npm-cli.js"), ...args], {
30523
30744
  env: nodeEnv,
30524
30745
  stdio: "ignore"
30525
30746
  });
30526
- const corepackJs = path45.join(dir, "node_modules", "corepack", "dist", "corepack.js");
30747
+ const corepackJs = path47.join(dir, "node_modules", "corepack", "dist", "corepack.js");
30527
30748
  const extra = config2.corepack && !exists(corepackJs) ? ["corepack"] : [];
30528
30749
  await installOnce(
30529
30750
  env,
@@ -30544,7 +30765,7 @@ var packageManagers = async (env, config2, version2) => {
30544
30765
  }
30545
30766
  try {
30546
30767
  await execAsync(
30547
- path45.join(dir, "node.exe"),
30768
+ path47.join(dir, "node.exe"),
30548
30769
  [corepackJs, "enable", "--install-directory", mkdirp(tool("bin")), "pnpm", "yarn"],
30549
30770
  { env: nodeEnv, stdio: "ignore" }
30550
30771
  );
@@ -30569,8 +30790,8 @@ async function setupPwsh(env, refresh = false) {
30569
30790
  }
30570
30791
 
30571
30792
  // src/guest/toolchains/languages/python.ts
30572
- import fs37 from "node:fs";
30573
- import path46 from "node:path";
30793
+ import fs39 from "node:fs";
30794
+ import path48 from "node:path";
30574
30795
  var installPython = async (pkg, spec) => {
30575
30796
  const version2 = await resolveCached(pkg + ":" + spec, async () => {
30576
30797
  const { versions } = await fetchJson(
@@ -30579,7 +30800,7 @@ var installPython = async (pkg, spec) => {
30579
30800
  return pickPackageVersion(versions, spec) ?? Promise.reject(new Error("No " + pkg + ' release matches "' + spec + '"'));
30580
30801
  });
30581
30802
  const dir = tool("python", pkg + "-" + version2);
30582
- const exe = path46.join(dir, "python.exe");
30803
+ const exe = path48.join(dir, "python.exe");
30583
30804
  if (!exists(exe)) {
30584
30805
  log("Downloading Python " + version2 + (pkg === "python2" ? " (Python 2, " : " (") + "~30 MB once) ...");
30585
30806
  await downloader.archive(
@@ -30588,32 +30809,32 @@ var installPython = async (pkg, spec) => {
30588
30809
  { locate: "python.exe", fileName: pkg + "." + version2 + ".zip" }
30589
30810
  );
30590
30811
  }
30591
- if (!exists(path46.join(dir, "Scripts", "pip.exe")) && !exists(path46.join(dir, "Scripts", "pip2.exe")))
30812
+ if (!exists(path48.join(dir, "Scripts", "pip.exe")) && !exists(path48.join(dir, "Scripts", "pip2.exe")))
30592
30813
  await execAsync(exe, ["-m", "ensurepip", "--default-pip"], { stdio: "ignore" });
30593
30814
  return dir;
30594
30815
  };
30595
- var shimDir = (dir) => duringSession() ? tool("shims", path46.basename(dir)) : tool("shims");
30816
+ var shimDir = (dir) => duringSession() ? tool("shims", path48.basename(dir)) : tool("shims");
30596
30817
  var shim = (folder, name, program, args = []) => {
30597
30818
  const fixed = [program, ...args];
30598
- fs37.writeFileSync(
30599
- path46.join(mkdirp(folder), name + ".cmd"),
30819
+ fs39.writeFileSync(
30820
+ path48.join(mkdirp(folder), name + ".cmd"),
30600
30821
  "@echo off\r\n" + fixed.map((a) => '"' + a + '"').join(" ") + " %*\r\n"
30601
30822
  );
30602
30823
  const sh = fixed.map((a) => "'" + a.replace(/\\/g, "/").replace(/'/g, "'\\''") + "'").join(" ");
30603
- fs37.writeFileSync(path46.join(folder, name), "#!/bin/sh\nexec " + sh + ' "$@"\n');
30824
+ fs39.writeFileSync(path48.join(folder, name), "#!/bin/sh\nexec " + sh + ' "$@"\n');
30604
30825
  };
30605
30826
  var shimPair = (folder, version2, dir) => {
30606
- const python = path46.join(dir, "python.exe");
30827
+ const python = path48.join(dir, "python.exe");
30607
30828
  shim(folder, "python" + version2, python);
30608
30829
  shim(folder, "pip" + version2, python, ["-m", "pip"]);
30609
30830
  };
30610
30831
  var pyLauncher = (folder, py3, py2) => {
30611
- const script = path46.join(mkdirp(folder), "py-launcher.py");
30612
- fs37.writeFileSync(
30832
+ const script = path48.join(mkdirp(folder), "py-launcher.py");
30833
+ fs39.writeFileSync(
30613
30834
  script,
30614
30835
  [
30615
30836
  "import subprocess, sys",
30616
- "PY3, PY2 = " + JSON.stringify(path46.join(py3, "python.exe")) + ", " + JSON.stringify(py2 ? path46.join(py2, "python.exe") : null),
30837
+ "PY3, PY2 = " + JSON.stringify(path48.join(py3, "python.exe")) + ", " + JSON.stringify(py2 ? path48.join(py2, "python.exe") : null),
30617
30838
  "args = sys.argv[1:]",
30618
30839
  "exe = PY3",
30619
30840
  "if args and args[0].startswith('-2'):",
@@ -30625,7 +30846,7 @@ var pyLauncher = (folder, py3, py2) => {
30625
30846
  ""
30626
30847
  ].join("\n")
30627
30848
  );
30628
- shim(folder, "py", path46.join(py3, "python.exe"), [script]);
30849
+ shim(folder, "py", path48.join(py3, "python.exe"), [script]);
30629
30850
  };
30630
30851
  async function setupPython(env, config2, versions) {
30631
30852
  if (dryRun) {
@@ -30635,10 +30856,10 @@ async function setupPython(env, config2, versions) {
30635
30856
  const py3 = await installPython("python", versions.python.spec);
30636
30857
  const shims = shimDir(py3);
30637
30858
  shimPair(shims, "3", py3);
30638
- env.prepend.push(py3, mkdirp(path46.join(py3, "Scripts")), shims);
30859
+ env.prepend.push(py3, mkdirp(path48.join(py3, "Scripts")), shims);
30639
30860
  env.vars.PYTHONIOENCODING = "utf-8";
30640
30861
  env.summary.push(
30641
- "python: " + path46.basename(py3).replace("python-", "") + " (from " + versions.python.source + "; py works too)"
30862
+ "python: " + path48.basename(py3).replace("python-", "") + " (from " + versions.python.source + "; py works too)"
30642
30863
  );
30643
30864
  if (!config2.python2) {
30644
30865
  pyLauncher(shims, py3, null);
@@ -30647,47 +30868,12 @@ async function setupPython(env, config2, versions) {
30647
30868
  const py2 = await installPython("python2", "2.7");
30648
30869
  shimPair(shims, "2", py2);
30649
30870
  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;
30871
+ env.summary.push("python2: " + path48.basename(py2).replace("python2-", ""));
30688
30872
  }
30689
30873
 
30690
30874
  // src/guest/toolchains/languages/php.ts
30875
+ import fs40 from "node:fs";
30876
+ import path49 from "node:path";
30691
30877
  var PHP_EXTENSIONS = [
30692
30878
  "curl",
30693
30879
  "fileinfo",
@@ -30718,16 +30904,16 @@ var phpBuild = async (spec) => {
30718
30904
  return { version: release.version, ...build.zip };
30719
30905
  };
30720
30906
  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"))))
30907
+ const ini = path49.join(home, "php.ini");
30908
+ if (exists(ini) || !exists(path49.join(home, "php.ini-development"))) return;
30909
+ 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") + '"');
30910
+ for (const ext of PHP_EXTENSIONS.filter((e) => exists(path49.join(home, "ext", "php_" + e + ".dll"))))
30725
30911
  text = text.replace(new RegExp("^;(extension=" + ext + ")\\s*$", "m"), "$1");
30726
- fs39.writeFileSync(ini + ".tmp", text);
30727
- fs39.renameSync(ini + ".tmp", ini);
30912
+ fs40.writeFileSync(ini + ".tmp", text);
30913
+ fs40.renameSync(ini + ".tmp", ini);
30728
30914
  };
30729
30915
  var shim2 = (env, name, command) => {
30730
- fs39.writeFileSync(path48.join(mkdirp(tool("shims")), name + ".cmd"), "@echo off\r\n" + command + " %*\r\n");
30916
+ fs40.writeFileSync(path49.join(mkdirp(tool("shims")), name + ".cmd"), "@echo off\r\n" + command + " %*\r\n");
30731
30917
  env.prepend.push(tool("shims"));
30732
30918
  };
30733
30919
  var setupComposer = async (env, php) => {
@@ -30739,7 +30925,7 @@ var setupComposer = async (env, php) => {
30739
30925
  }
30740
30926
  const composerHome = tool("composer-home");
30741
30927
  env.vars.COMPOSER_HOME = composerHome;
30742
- env.prepend.push(path48.join(composerHome, "vendor", "bin"));
30928
+ env.prepend.push(path49.join(composerHome, "vendor", "bin"));
30743
30929
  shim2(env, "composer", '"' + php + '" "' + phar + '"');
30744
30930
  env.summary.push(
30745
30931
  "composer: " + (/\d+\.\d+\.\d+/.exec(execOutput(php, [phar, "--version", "--no-ansi"]))?.[0] ?? "installed")
@@ -30754,7 +30940,7 @@ async function setupPhp(env, config2) {
30754
30940
  await setupVcRuntime(env, false);
30755
30941
  const version2 = await resolveCached("php:" + wantedSpec.spec, async () => (await phpBuild(wantedSpec.spec)).version);
30756
30942
  const home = tool("php", version2);
30757
- if (!exists(path48.join(home, "php.exe"))) {
30943
+ if (!exists(path49.join(home, "php.exe"))) {
30758
30944
  const build = await phpBuild(version2);
30759
30945
  log("Downloading PHP " + version2 + " (~30 MB once) ...");
30760
30946
  await downloader.archive("https://windows.php.net/downloads/releases/" + build.path, home, {
@@ -30766,11 +30952,11 @@ async function setupPhp(env, config2) {
30766
30952
  writePhpIni(home);
30767
30953
  env.prepend.push(home);
30768
30954
  env.summary.push("php: " + version2 + " (from " + wantedSpec.source + ")");
30769
- if (config2.composer) await setupComposer(env, path48.join(home, "php.exe"));
30955
+ if (config2.composer) await setupComposer(env, path49.join(home, "php.exe"));
30770
30956
  }
30771
30957
 
30772
30958
  // src/guest/toolchains/languages/ruby.ts
30773
- import path49 from "node:path";
30959
+ import path50 from "node:path";
30774
30960
  var RUBY_ASSET = /^rubyinstaller-(\d+\.\d+\.\d+)-(\d+)-x64\.7z$/;
30775
30961
  var buildNumber = (asset) => Number(RUBY_ASSET.exec(asset.name)?.[2] ?? 0);
30776
30962
  var rubyBuilds = async () => {
@@ -30798,7 +30984,7 @@ async function setupRuby(env, config2) {
30798
30984
  async () => pickPackageVersion([...(await rubyBuilds()).keys()], wantedSpec.spec) ?? Promise.reject(new Error('No RubyInstaller build matches "' + wantedSpec.spec + '"'))
30799
30985
  );
30800
30986
  const home = tool("ruby", version2);
30801
- if (!exists(path49.join(home, "bin", "ruby.exe"))) {
30987
+ if (!exists(path50.join(home, "bin", "ruby.exe"))) {
30802
30988
  const asset = (await rubyBuilds()).get(version2);
30803
30989
  if (!asset) throw new Error("RubyInstaller " + version2 + " is no longer published");
30804
30990
  log("Downloading Ruby " + version2 + " (~100 MB once) ...");
@@ -30811,11 +30997,11 @@ async function setupRuby(env, config2) {
30811
30997
  }
30812
30998
  const gems = tool("ruby-gems", version2.split(".").slice(0, 2).join("."));
30813
30999
  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"));
31000
+ env.prepend.push(path50.join(home, "bin"), path50.join(gems, "bin"));
30815
31001
  env.summary.push(
30816
- "ruby: " + versionOf(path49.join(home, "bin", "ruby.exe")) + " (from " + wantedSpec.source + "; gems with C extensions need MSYS2, not included)"
31002
+ "ruby: " + versionOf(path50.join(home, "bin", "ruby.exe")) + " (from " + wantedSpec.source + "; gems with C extensions need MSYS2, not included)"
30817
31003
  );
30818
- const gem = path49.join(home, "bin", "gem.cmd");
31004
+ const gem = path50.join(home, "bin", "gem.cmd");
30819
31005
  await installOnce(
30820
31006
  env,
30821
31007
  "gem@" + version2,
@@ -30827,9 +31013,9 @@ async function setupRuby(env, config2) {
30827
31013
  }
30828
31014
 
30829
31015
  // src/guest/toolchains/tools/vscode.ts
30830
- import fs40 from "node:fs";
30831
- import os7 from "node:os";
30832
- import path50 from "node:path";
31016
+ import fs41 from "node:fs";
31017
+ import os8 from "node:os";
31018
+ import path51 from "node:path";
30833
31019
  import { spawn as spawn5 } from "node:child_process";
30834
31020
 
30835
31021
  // node_modules/jsonc-parser/lib/esm/impl/scanner.js
@@ -31628,12 +31814,12 @@ function parseTree(text, errors = [], options = ParseOptions.DEFAULT) {
31628
31814
  }
31629
31815
  return result;
31630
31816
  }
31631
- function findNodeAtLocation(root, path77) {
31817
+ function findNodeAtLocation(root, path78) {
31632
31818
  if (!root) {
31633
31819
  return void 0;
31634
31820
  }
31635
31821
  let node2 = root;
31636
- for (let segment of path77) {
31822
+ for (let segment of path78) {
31637
31823
  if (typeof segment === "string") {
31638
31824
  if (node2.type !== "object" || !Array.isArray(node2.children)) {
31639
31825
  return void 0;
@@ -31987,14 +32173,14 @@ function getNodeType(value) {
31987
32173
 
31988
32174
  // node_modules/jsonc-parser/lib/esm/impl/edit.js
31989
32175
  function setProperty(text, originalPath, value, options) {
31990
- const path77 = originalPath.slice();
32176
+ const path78 = originalPath.slice();
31991
32177
  const errors = [];
31992
32178
  const root = parseTree(text, errors);
31993
32179
  let parent = void 0;
31994
32180
  let lastSegment = void 0;
31995
- while (path77.length > 0) {
31996
- lastSegment = path77.pop();
31997
- parent = findNodeAtLocation(root, path77);
32181
+ while (path78.length > 0) {
32182
+ lastSegment = path78.pop();
32183
+ parent = findNodeAtLocation(root, path78);
31998
32184
  if (parent === void 0 && value !== void 0) {
31999
32185
  if (typeof lastSegment === "string") {
32000
32186
  value = { [lastSegment]: value };
@@ -32180,8 +32366,8 @@ var ParseErrorCode;
32180
32366
  ParseErrorCode2[ParseErrorCode2["InvalidEscapeCharacter"] = 15] = "InvalidEscapeCharacter";
32181
32367
  ParseErrorCode2[ParseErrorCode2["InvalidCharacter"] = 16] = "InvalidCharacter";
32182
32368
  })(ParseErrorCode || (ParseErrorCode = {}));
32183
- function modify(text, path77, value, options) {
32184
- return setProperty(text, path77, value, options);
32369
+ function modify(text, path78, value, options) {
32370
+ return setProperty(text, path78, value, options);
32185
32371
  }
32186
32372
  function applyEdits(text, edits) {
32187
32373
  let sortedEdits = edits.slice(0).sort((a, b) => {
@@ -32282,7 +32468,7 @@ function missingExtensions(wanted2, folders) {
32282
32468
  var VERSION_MARKER = ".agent-sandbox-version";
32283
32469
  var desktopShortcut = (exe) => {
32284
32470
  if (!isWin) return;
32285
- const link = path50.join(os7.homedir(), "Desktop", "Visual Studio Code.lnk");
32471
+ const link = path51.join(os8.homedir(), "Desktop", "Visual Studio Code.lnk");
32286
32472
  runScriptWithJson("new-shortcuts.ps1", "ListFile", [
32287
32473
  { link, target: exe, arguments: '"' + (process.env.AGENT_WORKSPACE ?? "") + '"' }
32288
32474
  ]);
@@ -32290,16 +32476,16 @@ var desktopShortcut = (exe) => {
32290
32476
  var findIn = (dirs, ...names) => {
32291
32477
  for (const dir of dirs)
32292
32478
  for (const name of names) {
32293
- const file3 = path50.join(dir, name);
32479
+ const file3 = path51.join(dir, name);
32294
32480
  if (exists(file3)) return file3;
32295
32481
  }
32296
32482
  return void 0;
32297
32483
  };
32298
32484
  var recommendedBy = (workspace2) => {
32299
- const file3 = path50.join(workspace2, ".vscode", "extensions.json");
32485
+ const file3 = path51.join(workspace2, ".vscode", "extensions.json");
32300
32486
  try {
32301
- if (!exists(file3) || fs40.statSync(file3).size > 64 * 1024) return [];
32302
- const data = parse4(fs40.readFileSync(file3, "utf8"));
32487
+ if (!exists(file3) || fs41.statSync(file3).size > 64 * 1024) return [];
32488
+ const data = parse4(fs41.readFileSync(file3, "utf8"));
32303
32489
  return Array.isArray(data?.recommendations) ? data.recommendations.filter((r) => typeof r === "string" && EXTENSION_ID.test(r)).slice(0, 50) : [];
32304
32490
  } catch {
32305
32491
  return [];
@@ -32307,12 +32493,12 @@ var recommendedBy = (workspace2) => {
32307
32493
  };
32308
32494
  function configureVscode(tools, o) {
32309
32495
  const root = tool("vscode");
32310
- const code = path50.join(root, "bin", "code.cmd");
32496
+ const code = path51.join(root, "bin", "code.cmd");
32311
32497
  if (dryRun) {
32312
32498
  log("(dry run) would set up VS Code for: " + o.toolchains.join(", "));
32313
32499
  return;
32314
32500
  }
32315
- if (!exists(path50.join(root, "Code.exe"))) return;
32501
+ if (!exists(path51.join(root, "Code.exe"))) return;
32316
32502
  const dirs = [...tools.prepend, ...tools.append];
32317
32503
  const git = findIn([tool("git", "cmd"), ...dirs], "git.exe");
32318
32504
  const settings = vscodeSettings({
@@ -32327,14 +32513,14 @@ function configureVscode(tools, o) {
32327
32513
  node: findIn(dirs, "node.exe"),
32328
32514
  pwsh: findIn(dirs, "pwsh.exe"),
32329
32515
  git,
32330
- bash: git ? findIn([path50.join(path50.dirname(path50.dirname(git)), "bin")], "bash.exe") : void 0,
32516
+ bash: git ? findIn([path51.join(path51.dirname(path51.dirname(git)), "bin")], "bash.exe") : void 0,
32331
32517
  php: findIn(dirs, "php.exe"),
32332
32518
  ruby: findIn(dirs, "ruby.exe"),
32333
32519
  deno: findIn(dirs, "deno.exe")
32334
32520
  });
32335
32521
  writeManagedSettings(
32336
- path50.join(root, "data", "user-data", "User", "settings.json"),
32337
- path50.join(root, "data", ".agent-sandbox-managed.json"),
32522
+ path51.join(root, "data", "user-data", "User", "settings.json"),
32523
+ path51.join(root, "data", ".agent-sandbox-managed.json"),
32338
32524
  settings
32339
32525
  );
32340
32526
  const wanted2 = vscodeExtensions({
@@ -32345,7 +32531,7 @@ function configureVscode(tools, o) {
32345
32531
  });
32346
32532
  let folders = [];
32347
32533
  try {
32348
- folders = fs40.readdirSync(path50.join(root, "data", "extensions"));
32534
+ folders = fs41.readdirSync(path51.join(root, "data", "extensions"));
32349
32535
  } catch {
32350
32536
  }
32351
32537
  const missing = missingExtensions(wanted2, folders);
@@ -32353,19 +32539,19 @@ function configureVscode(tools, o) {
32353
32539
  "vscode: set up for " + (o.toolchains.join(", ") || "Node") + (missing.length ? "; installing " + missing.length + " extension(s) in the background" : "; extensions ready")
32354
32540
  );
32355
32541
  if (!missing.length) return;
32356
- const logFile2 = fs40.openSync(path50.join(logsDir, "vscode-extensions.log"), "a");
32542
+ const logFile2 = fs41.openSync(path51.join(logsDir, "vscode-extensions.log"), "a");
32357
32543
  spawn5(SYSTEM.cmd(), ["/d", "/c", code, ...missing.flatMap((id) => ["--install-extension", id])], {
32358
32544
  detached: true,
32359
32545
  stdio: ["ignore", logFile2, logFile2],
32360
32546
  windowsHide: true
32361
32547
  }).unref();
32362
- fs40.closeSync(logFile2);
32548
+ fs41.closeSync(logFile2);
32363
32549
  }
32364
32550
  var writeManagedSettings = (file3, managedFile, values) => {
32365
- let text = exists(file3) ? fs40.readFileSync(file3, "utf8") : "{}";
32551
+ let text = exists(file3) ? fs41.readFileSync(file3, "utf8") : "{}";
32366
32552
  let before = [];
32367
32553
  try {
32368
- before = JSON.parse(fs40.readFileSync(managedFile, "utf8"));
32554
+ before = JSON.parse(fs41.readFileSync(managedFile, "utf8"));
32369
32555
  } catch {
32370
32556
  }
32371
32557
  const format2 = { formattingOptions: { insertSpaces: true, tabSize: 2, eol: "\n" } };
@@ -32374,13 +32560,13 @@ var writeManagedSettings = (file3, managedFile, values) => {
32374
32560
  text = applyEdits(text, modify(text, [key], void 0, format2));
32375
32561
  }
32376
32562
  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)));
32563
+ mkdirp(path51.dirname(file3));
32564
+ fs41.writeFileSync(file3, text);
32565
+ fs41.writeFileSync(managedFile, JSON.stringify(Object.keys(values)));
32380
32566
  };
32381
32567
  async function setupVscode(env, refresh) {
32382
32568
  const root = tool("vscode");
32383
- const exe = path50.join(root, "Code.exe");
32569
+ const exe = path51.join(root, "Code.exe");
32384
32570
  if (dryRun) {
32385
32571
  log("(dry run) would provision VS Code");
32386
32572
  return;
@@ -32390,11 +32576,11 @@ async function setupVscode(env, refresh) {
32390
32576
  "https://update.code.visualstudio.com/api/update/win32-" + (arch === "arm64" ? "arm64" : "x64") + "-archive/stable/latest"
32391
32577
  );
32392
32578
  log("Downloading VS Code " + release.productVersion + " (~150 MB once) ...");
32393
- const keep = path50.join(root, "data");
32579
+ const keep = path51.join(root, "data");
32394
32580
  const parked = root + "-data";
32395
32581
  if (exists(keep)) {
32396
- fs40.rmSync(parked, { recursive: true, force: true });
32397
- fs40.renameSync(keep, parked);
32582
+ fs41.rmSync(parked, { recursive: true, force: true });
32583
+ fs41.renameSync(keep, parked);
32398
32584
  }
32399
32585
  try {
32400
32586
  await downloader.archive(release.url, root, {
@@ -32402,26 +32588,26 @@ async function setupVscode(env, refresh) {
32402
32588
  locate: "Code.exe",
32403
32589
  fileName: "vscode.zip"
32404
32590
  });
32405
- fs40.writeFileSync(path50.join(root, VERSION_MARKER), release.productVersion);
32591
+ fs41.writeFileSync(path51.join(root, VERSION_MARKER), release.productVersion);
32406
32592
  } finally {
32407
32593
  if (exists(parked)) {
32408
32594
  mkdirp(root);
32409
- fs40.rmSync(keep, { recursive: true, force: true });
32410
- fs40.renameSync(parked, keep);
32595
+ fs41.rmSync(keep, { recursive: true, force: true });
32596
+ fs41.renameSync(parked, keep);
32411
32597
  }
32412
32598
  }
32413
32599
  }
32414
- mkdirp(path50.join(root, "data"));
32415
- env.prepend.push(path50.join(root, "bin"));
32600
+ mkdirp(path51.join(root, "data"));
32601
+ env.prepend.push(path51.join(root, "bin"));
32416
32602
  desktopShortcut(exe);
32417
- const version2 = exists(path50.join(root, VERSION_MARKER)) ? fs40.readFileSync(path50.join(root, VERSION_MARKER), "utf8").trim() : "installed";
32603
+ const version2 = exists(path51.join(root, VERSION_MARKER)) ? fs41.readFileSync(path51.join(root, VERSION_MARKER), "utf8").trim() : "installed";
32418
32604
  env.summary.push("vscode: " + version2 + " (portable; run code . or use the desktop shortcut)");
32419
32605
  }
32420
32606
 
32421
32607
  // 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";
32608
+ import fs42 from "node:fs";
32609
+ import os9 from "node:os";
32610
+ import path52 from "node:path";
32425
32611
 
32426
32612
  // src/shared/memory/policy.ts
32427
32613
  function buildJobs(cpus, memoryGb) {
@@ -32440,41 +32626,41 @@ function cargoJobs(cpus, memoryGb, sessions) {
32440
32626
  // src/guest/toolchains/native/rust-extras.ts
32441
32627
  var cargoTarget = (targetDir) => {
32442
32628
  if (targetDir === "shared" || targetDir === "separate") return null;
32443
- if (targetDir === "local") return path51.join(localDir, "cargo-target");
32629
+ if (targetDir === "local") return path52.join(localDir, "cargo-target");
32444
32630
  return targetDir;
32445
32631
  };
32446
32632
  function cargoShim(env, rust) {
32447
- const real = path51.join(tool("rust", "cargo", "bin"), "cargo.exe");
32633
+ const real = path52.join(tool("rust", "cargo", "bin"), "cargo.exe");
32448
32634
  if (rust.targetDir !== "separate" || !exists(real)) return;
32449
32635
  const dir = mkdirp(tool("shims", "cargo"));
32450
- fs41.copyFileSync(ensureCompiled("cargoshim"), path51.join(dir, "cargo.exe"));
32636
+ fs42.copyFileSync(ensureCompiled("cargoshim"), path52.join(dir, "cargo.exe"));
32451
32637
  env.prepend.unshift(dir);
32452
32638
  env.vars.AGENT_REAL_CARGO = real;
32453
32639
  }
32454
32640
  function linkGate(env, rust, host) {
32455
32641
  const gcc = tool("mingw", "mingw64", "bin", "gcc.exe");
32456
32642
  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;
32643
+ const gate = path52.join(mkdirp(tool("shims")), "linkgate.exe");
32644
+ fs42.copyFileSync(ensureCompiled("linkgate"), gate);
32645
+ const memoryGb = os9.totalmem() / 1024 ** 3;
32460
32646
  const slots = rust.linkSlots === "auto" ? linkSlotsFor(memoryGb) : rust.linkSlots;
32461
32647
  env.vars.AGENT_LINK_SLOTS = String(slots);
32462
32648
  env.vars.AGENT_REAL_LINKER = gcc;
32463
32649
  env.vars.CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER = gate;
32464
32650
  const rustEnv = { ...process.env, RUSTUP_HOME: tool("rust", "rustup"), CARGO_HOME: tool("rust", "cargo") };
32465
32651
  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;
32652
+ const lld = sysroot ? path52.join(sysroot, "lib", "rustlib", host, "bin", "gcc-ld") : "";
32653
+ if (lld && exists(path52.join(lld, "ld.lld.exe"))) env.vars.AGENT_LLD_DIR = lld;
32468
32654
  env.summary.push(
32469
32655
  "rust linking: " + (env.vars.AGENT_LLD_DIR ? "lld" : "GNU ld") + ", at most " + env.vars.AGENT_LINK_SLOTS + " at once"
32470
32656
  );
32471
32657
  }
32472
32658
  function cargoDefaults(host) {
32473
32659
  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);
32660
+ if (exists(file3) || !exists(path52.dirname(file3))) return;
32661
+ const jobs = cargoJobs(os9.cpus().length, os9.totalmem() / 1024 ** 3, 1);
32476
32662
  const gnu = host.endsWith("-gnu");
32477
- fs41.writeFileSync(
32663
+ fs42.writeFileSync(
32478
32664
  file3,
32479
32665
  [
32480
32666
  "# Written by windows-development-sandbox once; edit freely, it is never overwritten.",
@@ -32489,13 +32675,14 @@ function rustCaches(rust) {
32489
32675
  const target = cargoTarget(rust.targetDir);
32490
32676
  return {
32491
32677
  ...target ? { CARGO_TARGET_DIR: target } : {},
32492
- ...process.env.SCCACHE_DIR ? {} : { SCCACHE_DIR: path51.join(dataDir, "cache", "sccache") }
32678
+ ...process.env.SCCACHE_DIR ? {} : { SCCACHE_DIR: path52.join(dataDir, "cache", "sccache") }
32493
32679
  };
32494
32680
  }
32495
32681
  function rustHost(config2) {
32496
32682
  if (config2.rust.host !== "auto") return config2.rust.host;
32497
32683
  const cpu = arch === "arm64" ? "aarch64" : "x86_64";
32498
- return cpu + (wanted(config2.msvc.enabled, "msvc") ? "-pc-windows-msvc" : "-pc-windows-gnu");
32684
+ const msvc = wanted(config2.msvc.enabled, "msvc") || wanted(config2.unreal.enabled, "unreal");
32685
+ return cpu + (msvc ? "-pc-windows-msvc" : "-pc-windows-gnu");
32499
32686
  }
32500
32687
 
32501
32688
  // src/guest/toolchains/languages/python-tools.ts
@@ -32515,6 +32702,7 @@ function plan(config2, versions, o) {
32515
32702
  const apps = Boolean(o.apps && (o.apps.install.length || Object.keys(o.apps.custom).length));
32516
32703
  const java = wanted(config2.java.enabled, "java");
32517
32704
  const python = wanted(config2.python.enabled, "python");
32705
+ const unreal = wanted(config2.unreal.enabled, "unreal");
32518
32706
  return [
32519
32707
  {
32520
32708
  name: "Git",
@@ -32532,12 +32720,18 @@ function plan(config2, versions, o) {
32532
32720
  enabled: wanted(config2.cpp.enabled, "cpp") || wanted(config2.rust.enabled, "rust"),
32533
32721
  install: (env) => setupCpp(env, config2.cpp)
32534
32722
  },
32535
- { name: "MSVC", enabled: wanted(config2.msvc.enabled, "msvc"), install: (env) => setupMsvc(env, config2.msvc) },
32723
+ // Unreal's Visual Studio brings MSVC and the real vswhere: the portable MSVC (and its stand-in vswhere) stays out.
32724
+ { name: "Unreal", enabled: unreal, shared: true, install: (env) => setupUnreal(env, config2.unreal) },
32725
+ {
32726
+ name: "MSVC",
32727
+ enabled: wanted(config2.msvc.enabled, "msvc") && !unreal,
32728
+ install: (env) => setupMsvc(env, config2.msvc)
32729
+ },
32536
32730
  // Rust links with MSVC (msvc host) or MinGW's gcc (GNU host): whichever it uses goes first.
32537
32731
  {
32538
32732
  name: "Rust",
32539
32733
  enabled: wanted(config2.rust.enabled, "rust"),
32540
- after: ["C/C++", "MSVC"],
32734
+ after: ["C/C++", "MSVC", "Unreal"],
32541
32735
  install: async (env) => {
32542
32736
  await setupRust(env, { ...config2.rust, host: rustHost(config2) }, o.refresh);
32543
32737
  Object.assign(env.vars, rustCaches(config2.rust));
@@ -32752,25 +32946,25 @@ async function setupToolchains(config2, versions, options, run3 = {}) {
32752
32946
  }
32753
32947
 
32754
32948
  // src/guest/agents/agent-installer.ts
32755
- import fs43 from "node:fs";
32756
- import path56 from "node:path";
32949
+ import fs44 from "node:fs";
32950
+ import path57 from "node:path";
32757
32951
 
32758
32952
  // src/guest/setup/environment.ts
32759
- import path55 from "node:path";
32953
+ import path56 from "node:path";
32760
32954
 
32761
32955
  // src/guest/agents/local-state.ts
32762
- import fs42 from "node:fs";
32763
- import path53 from "node:path";
32956
+ import fs43 from "node:fs";
32957
+ import path54 from "node:path";
32764
32958
 
32765
32959
  // src/guest/agents/agent-files.ts
32766
- import path52 from "node:path";
32960
+ import path53 from "node:path";
32767
32961
  function agentPaths(toolsDir2, name, harness) {
32768
- const dir = path52.join(toolsDir2, "agents", name);
32962
+ const dir = path53.join(toolsDir2, "agents", name);
32769
32963
  const exe = harness.hostExecutable ?? (harness.uvBin ? harness.uvBin + ".exe" : null);
32770
32964
  return {
32771
32965
  dir,
32772
- exe: exe ? path52.join(dir, exe) : null,
32773
- cmd: harness.npmBin ? path52.join(dir, harness.npmBin + ".cmd") : null
32966
+ exe: exe ? path53.join(dir, exe) : null,
32967
+ cmd: harness.npmBin ? path53.join(dir, harness.npmBin + ".cmd") : null
32774
32968
  };
32775
32969
  }
32776
32970
  function agentCommand(name, harness) {
@@ -32806,46 +33000,52 @@ function localStateEntries(agents2, stateDir2, localRoot2) {
32806
33000
  ([agent, harness]) => Object.entries(harness.localState ?? {}).map(([env, folder]) => ({
32807
33001
  agent,
32808
33002
  env,
32809
- store: path52.join(stateDir2, agent, folder),
32810
- local: path52.join(localRoot2, agent, folder),
33003
+ store: path53.join(stateDir2, agent, folder),
33004
+ local: path53.join(localRoot2, agent, folder),
32811
33005
  processes: [agentCommand(agent, harness) + ".exe"],
32812
- legacy: path52.join(stateDir2, agent)
33006
+ legacy: path53.join(stateDir2, agent)
32813
33007
  }))
32814
33008
  );
32815
33009
  }
32816
33010
  function bootResetPaths(agents2, stateDir2) {
32817
33011
  return Object.entries(agents2).flatMap(
32818
- ([agent, harness]) => (harness.bootReset ?? []).map((rel) => ({ agent, path: path52.join(stateDir2, agent, rel) }))
33012
+ ([agent, harness]) => (harness.bootReset ?? []).map((rel) => ({ agent, path: path53.join(stateDir2, agent, rel) }))
32819
33013
  );
32820
33014
  }
33015
+ function codexConfigWithoutSandbox(toml) {
33016
+ const firstTable = toml.search(/^\s*\[/m);
33017
+ const topLevel = firstTable < 0 ? toml : toml.slice(0, firstTable);
33018
+ if (/^\s*sandbox_mode\s*=/m.test(topLevel)) return null;
33019
+ return '# Set by the sandbox: Windows Sandbox already contains Codex, its own command sandbox would only slow it down.\nsandbox_mode = "danger-full-access"\n' + (toml ? "\n" + toml : "");
33020
+ }
32821
33021
  var isDatabaseFile = (name) => /\.(sqlite3?|db)(-wal|-shm)?$/i.test(name);
32822
33022
  var isCopyableDatabaseFile = (name) => isDatabaseFile(name) && !/-shm$/i.test(name);
32823
33023
 
32824
33024
  // src/guest/agents/local-state.ts
32825
- var localRoot = () => path53.join(localDir, "agent-state");
33025
+ var localRoot = () => path54.join(localDir, "agent-state");
32826
33026
  function agentLocalStates() {
32827
33027
  return localStateEntries(session.agents ?? {}, stateDir, localRoot());
32828
33028
  }
32829
33029
  function localStateVars() {
32830
33030
  return Object.fromEntries(agentLocalStates().map((s) => [s.env, s.local]));
32831
33031
  }
32832
- var databaseFiles = (dir, keep) => exists(dir) ? fs42.readdirSync(dir, { withFileTypes: true }).flatMap((e) => e.isFile() && keep(e.name) ? [e.name] : []) : [];
33032
+ var databaseFiles = (dir, keep) => exists(dir) ? fs43.readdirSync(dir, { withFileTypes: true }).flatMap((e) => e.isFile() && keep(e.name) ? [e.name] : []) : [];
32833
33033
  var copyFiles = (from, to, names) => {
32834
- fs42.rmSync(to, { recursive: true, force: true });
33034
+ fs43.rmSync(to, { recursive: true, force: true });
32835
33035
  mkdirp(to);
32836
- for (const name of names) fs42.copyFileSync(path53.join(from, name), path53.join(to, name));
33036
+ for (const name of names) fs43.copyFileSync(path54.join(from, name), path54.join(to, name));
32837
33037
  };
32838
33038
  var swapIn = (incoming, store2) => {
32839
33039
  const previous = store2 + ".previous";
32840
- fs42.rmSync(previous, { recursive: true, force: true });
32841
- if (exists(store2)) fs42.renameSync(store2, previous);
33040
+ fs43.rmSync(previous, { recursive: true, force: true });
33041
+ if (exists(store2)) fs43.renameSync(store2, previous);
32842
33042
  try {
32843
- fs42.renameSync(incoming, store2);
33043
+ fs43.renameSync(incoming, store2);
32844
33044
  } catch (e) {
32845
- if (exists(previous)) fs42.renameSync(previous, store2);
33045
+ if (exists(previous)) fs43.renameSync(previous, store2);
32846
33046
  throw e;
32847
33047
  }
32848
- fs42.rmSync(previous, { recursive: true, force: true });
33048
+ fs43.rmSync(previous, { recursive: true, force: true });
32849
33049
  };
32850
33050
  function adoptLegacy(s) {
32851
33051
  if (exists(s.store)) return;
@@ -32856,30 +33056,39 @@ function adoptLegacy(s) {
32856
33056
  copyFiles(s.legacy, incoming, copyable);
32857
33057
  swapIn(incoming, s.store);
32858
33058
  const same = copyable.every(
32859
- (n) => fs42.statSync(path53.join(s.store, n)).size === fs42.statSync(path53.join(s.legacy, n)).size
33059
+ (n) => fs43.statSync(path54.join(s.store, n)).size === fs43.statSync(path54.join(s.legacy, n)).size
32860
33060
  );
32861
33061
  if (!same) {
32862
33062
  warn(s.agent + ": the copied databases differ in size from the originals; the originals were kept.");
32863
33063
  return;
32864
33064
  }
32865
- for (const n of names) fs42.rmSync(path53.join(s.legacy, n), { force: true });
33065
+ for (const n of names) fs43.rmSync(path54.join(s.legacy, n), { force: true });
32866
33066
  log(s.agent + ": moved " + copyable.length + " database file(s) to " + s.store + ".");
32867
33067
  }
32868
33068
  function resetMachineBound() {
32869
33069
  if (dryRun) return;
32870
33070
  for (const { agent, path: target } of bootResetPaths(session.agents ?? {}, stateDir)) {
32871
33071
  try {
32872
- const stat = fs42.lstatSync(target, { throwIfNoEntry: false });
33072
+ const stat = fs43.lstatSync(target, { throwIfNoEntry: false });
32873
33073
  if (!stat || stat.isSymbolicLink()) continue;
32874
- fs42.rmSync(target, { recursive: true, force: true });
33074
+ fs43.rmSync(target, { recursive: true, force: true });
32875
33075
  log(
32876
- agent + ": removed " + path53.relative(path53.join(stateDir, agent), target) + " (it only worked in the last sandbox)."
33076
+ agent + ": removed " + path54.relative(path54.join(stateDir, agent), target) + " (it only worked in the last sandbox)."
32877
33077
  );
32878
33078
  } catch (e) {
32879
33079
  warn(agent + ": could not remove " + target + " (" + errMsg(e) + ").");
32880
33080
  }
32881
33081
  }
32882
33082
  }
33083
+ function codexWithoutInnerSandbox() {
33084
+ if (dryRun || !session.agents?.codex) return;
33085
+ const file3 = path54.join(stateDir, "codex", "config.toml");
33086
+ const updated = codexConfigWithoutSandbox(exists(file3) ? fs43.readFileSync(file3, "utf8") : "");
33087
+ if (updated === null) return;
33088
+ mkdirp(path54.dirname(file3));
33089
+ fs43.writeFileSync(file3, updated, "utf8");
33090
+ log('codex: its own command sandbox is off (sandbox_mode = "danger-full-access" in config.toml).');
33091
+ }
32883
33092
  function restoreLocalState() {
32884
33093
  if (dryRun) return;
32885
33094
  for (const s of agentLocalStates()) {
@@ -32887,7 +33096,7 @@ function restoreLocalState() {
32887
33096
  adoptLegacy(s);
32888
33097
  mkdirp(s.local);
32889
33098
  const names = databaseFiles(s.store, isCopyableDatabaseFile);
32890
- for (const n of names) fs42.copyFileSync(path53.join(s.store, n), path53.join(s.local, n));
33099
+ for (const n of names) fs43.copyFileSync(path54.join(s.store, n), path54.join(s.local, n));
32891
33100
  if (names.length) log(s.agent + ": databases restored to " + s.local + ".");
32892
33101
  } catch (e) {
32893
33102
  warn(s.agent + ": could not restore its databases (" + errMsg(e) + "); it starts with empty ones.");
@@ -32896,7 +33105,7 @@ function restoreLocalState() {
32896
33105
  }
32897
33106
 
32898
33107
  // src/guest/setup/path-plan.ts
32899
- import path54 from "node:path";
33108
+ import path55 from "node:path";
32900
33109
  function pathKey(folder) {
32901
33110
  const slashes = folder.trim().replace(/^"|"$/g, "").replace(/\//g, "\\");
32902
33111
  return (slashes.length > 3 ? slashes.replace(/\\+$/, "") : slashes).toLowerCase();
@@ -32918,13 +33127,13 @@ function planPath(input2) {
32918
33127
  function isPinnedNodeDir(folder, nvmHome2) {
32919
33128
  const key = pathKey(folder);
32920
33129
  const home = pathKey(nvmHome2);
32921
- return key.startsWith(home + "\\") && /^v\d/.test(path54.win32.basename(key));
33130
+ return key.startsWith(home + "\\") && /^v\d/.test(path55.win32.basename(key));
32922
33131
  }
32923
33132
 
32924
33133
  // src/guest/setup/environment.ts
32925
33134
  var LEGACY_HOMES = { CODEX_HOME: "codex", GEMINI_CLI_HOME: "gemini" };
32926
33135
  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)])
33136
+ Object.entries(session.agentHomes ?? LEGACY_HOMES).filter(([name]) => name !== "CLAUDE_CONFIG_DIR").map(([name, sub]) => [name, path56.join(stateDir, sub)])
32928
33137
  );
32929
33138
  var AGENT_VARS = [
32930
33139
  "CLAUDE_CONFIG_DIR",
@@ -32945,7 +33154,7 @@ function agentEnv(tools, target = { workspace, project: session.project, base: p
32945
33154
  CLAUDE_CONFIG_DIR: claudeDir,
32946
33155
  ...homes,
32947
33156
  ...localStateVars(),
32948
- npm_config_cache: path55.join(toolsDir, "npm-cache"),
33157
+ npm_config_cache: path56.join(toolsDir, "npm-cache"),
32949
33158
  npm_config_update_notifier: "false",
32950
33159
  AGENT_WORKSPACE: target.workspace,
32951
33160
  AGENT_DATA: dataDir,
@@ -32963,9 +33172,9 @@ function agentEnv(tools, target = { workspace, project: session.project, base: p
32963
33172
  ...local.map((n) => env[n])
32964
33173
  ])
32965
33174
  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);
33175
+ const runners = [path56.join(toolsDir, "node"), path56.dirname(process.execPath)].map((d) => d.toLowerCase());
33176
+ const base = (target.base.PATH ?? "").split(path56.delimiter).filter((d) => d && !runners.includes(d.toLowerCase()));
33177
+ env.PATH = [.../* @__PURE__ */ new Set([...tools.prepend, ...base, ...tools.append])].join(path56.delimiter);
32969
33178
  return env;
32970
33179
  }
32971
33180
  function persistEnvironment(env, toolVars2) {
@@ -32980,7 +33189,7 @@ function persistEnvironment(env, toolVars2) {
32980
33189
  entries: [env.PATH ?? "", ...installedAgentDirs()],
32981
33190
  exists,
32982
33191
  drop: (dir) => isPinnedNodeDir(dir, nvmHome())
32983
- }).join(path55.delimiter),
33192
+ }).join(path56.delimiter),
32984
33193
  add: [],
32985
33194
  additive: false
32986
33195
  });
@@ -32997,7 +33206,7 @@ function addMachineEnvironment(vars, dirs, additive = false) {
32997
33206
  warn("Could not add to the environment: " + errMsg(e));
32998
33207
  }
32999
33208
  }
33000
- var nvmHome = () => path55.join(toolsDir, "nvm");
33209
+ var nvmHome = () => path56.join(toolsDir, "nvm");
33001
33210
  function installedAgentDirs() {
33002
33211
  return Object.entries(session.agents ?? {}).flatMap(([name, harness]) => {
33003
33212
  const p = agentPaths(toolsDir, name, harness);
@@ -33029,7 +33238,7 @@ var agentPaths2 = (name, harness) => agentPaths(toolsDir, name, harness);
33029
33238
  async function installViaNpm(name, harness, dir, env) {
33030
33239
  if (!harness.npmPackage)
33031
33240
  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");
33241
+ const npmCli = path57.join(path57.dirname(process.execPath), "node_modules", "npm", "bin", "npm-cli.js");
33033
33242
  const args = [npmCli, "install", "--global", "--prefix", dir, harness.npmPackage, "--no-fund", "--no-audit"];
33034
33243
  log("Installing " + harness.npmPackage + " (this can take a minute)...");
33035
33244
  if (dryRun) {
@@ -33040,7 +33249,7 @@ async function installViaNpm(name, harness, dir, env) {
33040
33249
  await execAsync(process.execPath, args, { env });
33041
33250
  }
33042
33251
  async function installViaUv(name, harness, dir, env) {
33043
- const uv = path56.join(toolsDir, "uv", "uv.exe");
33252
+ const uv = path57.join(toolsDir, "uv", "uv.exe");
33044
33253
  log("Installing " + harness.uvPackage + " with uv (this can take a minute)...");
33045
33254
  if (dryRun) {
33046
33255
  log("(dry run) uv tool install " + harness.uvPackage);
@@ -33055,8 +33264,8 @@ async function installViaUv(name, harness, dir, env) {
33055
33264
  });
33056
33265
  }
33057
33266
  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);
33267
+ const parts2 = (env.PATH ?? "").split(path57.delimiter);
33268
+ if (!parts2.some((p) => p.toLowerCase() === dir.toLowerCase())) env.PATH = [...parts2, dir].join(path57.delimiter);
33060
33269
  addMachineEnvironment({}, [dir], true);
33061
33270
  }
33062
33271
  var AgentInstaller = class {
@@ -33097,9 +33306,9 @@ var AgentInstaller = class {
33097
33306
  }
33098
33307
  mkdirp(p.dir);
33099
33308
  if (this.sourceOf(name, harness) === "host") {
33100
- const source = path56.join(hostToolsDir, "agents", name, harness.hostExecutable);
33309
+ const source = path57.join(hostToolsDir, "agents", name, harness.hostExecutable);
33101
33310
  if (exists(source) && p.exe) {
33102
- fs43.copyFileSync(source, p.exe);
33311
+ fs44.copyFileSync(source, p.exe);
33103
33312
  log("Copied " + name + " from this PC: " + source);
33104
33313
  return;
33105
33314
  }
@@ -33114,44 +33323,44 @@ var AgentInstaller = class {
33114
33323
  var agents = new AgentInstaller();
33115
33324
 
33116
33325
  // src/guest/setup/shell-path.ts
33117
- import fs44 from "node:fs";
33118
- import path57 from "node:path";
33326
+ import fs45 from "node:fs";
33327
+ import path58 from "node:path";
33119
33328
  function installShellPath() {
33120
33329
  if (!isWin || dryRun || testMode) return;
33121
- const helper = path57.join(mkdirp(path57.join(localDir, "bin")), "pathsync.exe");
33122
- fs44.copyFileSync(ensureCompiled("pathsync"), helper);
33330
+ const helper = path58.join(mkdirp(path58.join(localDir, "bin")), "pathsync.exe");
33331
+ fs45.copyFileSync(ensureCompiled("pathsync"), helper);
33123
33332
  runScript("install-shell-path.ps1", [
33124
33333
  "-Helper",
33125
33334
  helper,
33126
33335
  "-PwshDir",
33127
- path57.join(toolsDir, "pwsh"),
33336
+ path58.join(toolsDir, "pwsh"),
33128
33337
  "-GitRoot",
33129
- path57.join(toolsDir, "git")
33338
+ path58.join(toolsDir, "git")
33130
33339
  ]);
33131
33340
  }
33132
33341
 
33133
33342
  // src/guest/setup/claude-mem.ts
33134
- import fs45 from "node:fs";
33135
- import os9 from "node:os";
33136
- import path58 from "node:path";
33343
+ import fs46 from "node:fs";
33344
+ import os10 from "node:os";
33345
+ import path59 from "node:path";
33137
33346
  var claudeMemPaths = {
33138
- store: path58.join(stateDir, "claude-mem"),
33139
- local: path58.join(os9.homedir(), ".claude-mem")
33347
+ store: path59.join(stateDir, "claude-mem"),
33348
+ local: path59.join(os10.homedir(), ".claude-mem")
33140
33349
  };
33141
33350
  var claudeMemEnabled = () => session.claudeProfile.syncClaudeMem && !dryRun;
33142
33351
  function restoreClaudeMem() {
33143
33352
  if (!claudeMemEnabled()) return;
33144
33353
  const previous = claudeMemPaths.store + ".previous";
33145
- if (!exists(claudeMemPaths.store) && exists(previous)) fs45.renameSync(previous, claudeMemPaths.store);
33354
+ if (!exists(claudeMemPaths.store) && exists(previous)) fs46.renameSync(previous, claudeMemPaths.store);
33146
33355
  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"))
33356
+ if (!looksLikeSqlite(path59.join(claudeMemPaths.store, "claude-mem.db")) || !exists(claudeMemPaths.store)) {
33357
+ const good = (exists(backups) ? fs46.readdirSync(backups).sort().reverse() : []).find(
33358
+ (b) => exists(path59.join(backups, b, "claude-mem.db")) && looksLikeSqlite(path59.join(backups, b, "claude-mem.db"))
33150
33359
  );
33151
33360
  if (good) {
33152
33361
  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 });
33362
+ fs46.renameSync(claudeMemPaths.store, claudeMemPaths.store + ".damaged-" + Date.now());
33363
+ fs46.cpSync(path59.join(backups, good), claudeMemPaths.store, { recursive: true });
33155
33364
  warn(
33156
33365
  "claude-mem: the stored database was missing or damaged; restored the backup from " + new Date(Number(good)).toISOString() + "."
33157
33366
  );
@@ -33164,33 +33373,33 @@ function restoreClaudeMem() {
33164
33373
  var SQLITE_HEADER = "SQLite format 3\0";
33165
33374
  var looksLikeSqlite = (file3) => {
33166
33375
  if (!exists(file3)) return true;
33167
- const fd = fs45.openSync(file3, "r");
33376
+ const fd = fs46.openSync(file3, "r");
33168
33377
  try {
33169
33378
  const head = Buffer.alloc(16);
33170
- return fs45.readSync(fd, head, 0, 16, 0) === 16 && head.toString("latin1") === SQLITE_HEADER;
33379
+ return fs46.readSync(fd, head, 0, 16, 0) === 16 && head.toString("latin1") === SQLITE_HEADER;
33171
33380
  } finally {
33172
- fs45.closeSync(fd);
33381
+ fs46.closeSync(fd);
33173
33382
  }
33174
33383
  };
33175
33384
  var BACKUP_EVERY_MS = 6 * 3600 * 1e3;
33176
33385
 
33177
33386
  // src/guest/setup/claude-profile.ts
33178
- import fs46 from "node:fs";
33179
- import path59 from "node:path";
33387
+ import fs47 from "node:fs";
33388
+ import path60 from "node:path";
33180
33389
  var KEEP_SANDBOX_COPY = [".claude.json", ".credentials.json"];
33181
33390
  var fixPluginPaths = (hostConfigDir) => {
33182
- const plugins = path59.join(claudeDir, "plugins");
33391
+ const plugins = path60.join(claudeDir, "plugins");
33183
33392
  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");
33393
+ for (const name of fs47.readdirSync(plugins).filter((f) => f.endsWith(".json"))) {
33394
+ const file3 = path60.join(plugins, name);
33395
+ const text = fs47.readFileSync(file3, "utf8");
33187
33396
  const fixed = translatePaths(text, hostConfigDir, claudeDir);
33188
- if (fixed !== text) fs46.writeFileSync(file3, fixed, "utf8");
33397
+ if (fixed !== text) fs47.writeFileSync(file3, fixed, "utf8");
33189
33398
  }
33190
33399
  };
33191
33400
  var readState2 = (file3) => {
33192
33401
  try {
33193
- return JSON.parse(fs46.readFileSync(file3, "utf8").replace(/^\uFEFF/, ""));
33402
+ return JSON.parse(fs47.readFileSync(file3, "utf8").replace(/^\uFEFF/, ""));
33194
33403
  } catch {
33195
33404
  return null;
33196
33405
  }
@@ -33221,14 +33430,14 @@ function syncClaudeProfile(credentials) {
33221
33430
  log("No Claude settings were staged from this PC.");
33222
33431
  return;
33223
33432
  }
33224
- const source = path59.join(launchDir, "claude-profile");
33433
+ const source = path60.join(launchDir, "claude-profile");
33225
33434
  mkdirp(claudeDir);
33226
33435
  for (const name of profile.items) {
33227
- const from = path59.join(source, name);
33228
- const to = path59.join(claudeDir, name);
33436
+ const from = path60.join(source, name);
33437
+ const to = path60.join(claudeDir, name);
33229
33438
  if (name === ".credentials.json") {
33230
33439
  if (credentials && !exists(to)) {
33231
- fs46.writeFileSync(to, credentials, "utf8");
33440
+ fs47.writeFileSync(to, credentials, "utf8");
33232
33441
  log("Claude settings: copied " + name + " from this PC");
33233
33442
  } else log("Claude settings: kept the sandbox's " + name);
33234
33443
  continue;
@@ -33238,14 +33447,14 @@ function syncClaudeProfile(credentials) {
33238
33447
  log("Claude settings: kept the sandbox's " + name);
33239
33448
  continue;
33240
33449
  }
33241
- if (fs46.statSync(from).isDirectory()) safeRemove(to, claudeDir);
33242
- fs46.cpSync(from, to, { recursive: true, force: true });
33450
+ if (fs47.statSync(from).isDirectory()) safeRemove(to, claudeDir);
33451
+ fs47.cpSync(from, to, { recursive: true, force: true });
33243
33452
  log("Claude settings: copied " + name + " from this PC");
33244
33453
  }
33245
33454
  fixPluginPaths(profile.hostConfigDir);
33246
33455
  const mcp = mergeMcpServers(
33247
- path59.join(source, ".claude.json"),
33248
- path59.join(claudeDir, ".claude.json"),
33456
+ path60.join(source, ".claude.json"),
33457
+ path60.join(claudeDir, ".claude.json"),
33249
33458
  session.workspaceHost,
33250
33459
  workspace
33251
33460
  );
@@ -33254,11 +33463,11 @@ function syncClaudeProfile(credentials) {
33254
33463
  }
33255
33464
 
33256
33465
  // src/guest/setup/hooks.ts
33257
- import fs47 from "node:fs";
33258
- import path60 from "node:path";
33466
+ import fs48 from "node:fs";
33467
+ import path61 from "node:path";
33259
33468
  import { spawnSync as spawnSync4 } from "node:child_process";
33260
33469
  var commandFor = (file3) => {
33261
- const ext = path60.extname(file3).toLowerCase();
33470
+ const ext = path61.extname(file3).toLowerCase();
33262
33471
  if (ext === ".mjs" || ext === ".js") return [process.execPath, [file3]];
33263
33472
  if (!isWin) return null;
33264
33473
  if (ext === ".ps1")
@@ -33266,12 +33475,12 @@ var commandFor = (file3) => {
33266
33475
  if (ext === ".cmd" || ext === ".bat") return [SYSTEM.cmd(), ["/d", "/c", file3]];
33267
33476
  return null;
33268
33477
  };
33269
- var BOOT = { root: path60.join(launchDir, "hooks"), cwd: workspace };
33478
+ var BOOT = { root: path61.join(launchDir, "hooks"), cwd: workspace };
33270
33479
  var hooksOf = (stage, target) => {
33271
- const dir = path60.join(target.root, stage);
33480
+ const dir = path61.join(target.root, stage);
33272
33481
  if (!exists(dir)) return [];
33273
- return fs47.readdirSync(dir).sort().flatMap((name) => {
33274
- const command = commandFor(path60.join(dir, name));
33482
+ return fs48.readdirSync(dir).sort().flatMap((name) => {
33483
+ const command = commandFor(path61.join(dir, name));
33275
33484
  return command ? [{ name, command }] : [];
33276
33485
  });
33277
33486
  };
@@ -33289,8 +33498,8 @@ function runHooks(stage, env, target = BOOT) {
33289
33498
  }
33290
33499
 
33291
33500
  // src/guest/network/allow-only.ts
33292
- import fs49 from "node:fs";
33293
- import path62 from "node:path";
33501
+ import fs50 from "node:fs";
33502
+ import path63 from "node:path";
33294
33503
  import { spawn as spawn6, spawnSync as spawnSync6 } from "node:child_process";
33295
33504
 
33296
33505
  // src/shared/network/policy.ts
@@ -33385,8 +33594,8 @@ var PROXY_PORT = 38080;
33385
33594
 
33386
33595
  // src/guest/network/firewall.ts
33387
33596
  import dns from "node:dns";
33388
- import fs48 from "node:fs";
33389
- import path61 from "node:path";
33597
+ import fs49 from "node:fs";
33598
+ import path62 from "node:path";
33390
33599
  import { spawnSync as spawnSync5 } from "node:child_process";
33391
33600
 
33392
33601
  // src/shared/network/firewall-rules.ts
@@ -33577,7 +33786,7 @@ function networkProblems() {
33577
33786
  function longPath(file3) {
33578
33787
  if (!hasShortName(file3)) return file3;
33579
33788
  try {
33580
- return fs48.realpathSync.native(file3);
33789
+ return fs49.realpathSync.native(file3);
33581
33790
  } catch {
33582
33791
  return file3;
33583
33792
  }
@@ -33676,12 +33885,12 @@ async function applyNetworkPolicy(ptyHostExe) {
33676
33885
  return "blocked";
33677
33886
  }
33678
33887
  var FORWARD_RULE = "AgentSandbox-Forward";
33679
- var HOSTS_FILE = path61.join(process.env.WINDIR ?? "C:\\Windows", "System32", "drivers", "etc", "hosts");
33888
+ var HOSTS_FILE = path62.join(process.env.WINDIR ?? "C:\\Windows", "System32", "drivers", "etc", "hosts");
33680
33889
  var applyBlockedHosts = () => {
33681
33890
  const hosts = session.network.blockHosts ?? [];
33682
33891
  if (!hosts.length) return;
33683
- const text = fs48.existsSync(HOSTS_FILE) ? fs48.readFileSync(HOSTS_FILE, "utf8") : "";
33684
- fs48.writeFileSync(HOSTS_FILE, withBlockedHosts(text, hosts));
33892
+ const text = fs49.existsSync(HOSTS_FILE) ? fs49.readFileSync(HOSTS_FILE, "utf8") : "";
33893
+ fs49.writeFileSync(HOSTS_FILE, withBlockedHosts(text, hosts));
33685
33894
  log("Blocked hosts (network.blockHosts): " + hosts.join(", "));
33686
33895
  };
33687
33896
  var applyDns = () => {
@@ -33736,11 +33945,11 @@ async function applyAllowOnly() {
33736
33945
  log("(dry run) would allow only: " + hosts.join(", "));
33737
33946
  return false;
33738
33947
  }
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")], {
33948
+ const exe = path63.join(toolsDir, "netproxy", "sbx-netproxy.exe");
33949
+ fs50.mkdirSync(path63.dirname(exe), { recursive: true });
33950
+ if (!fs50.existsSync(exe) || fs50.statSync(exe).size !== fs50.statSync(process.execPath).size)
33951
+ fs50.copyFileSync(process.execPath, exe);
33952
+ spawn6(exe, [path63.join(launchDir, "runtime", "netproxy.js")], {
33744
33953
  detached: true,
33745
33954
  stdio: "ignore",
33746
33955
  windowsHide: true
@@ -33784,8 +33993,8 @@ async function applyAllowOnly() {
33784
33993
  }
33785
33994
 
33786
33995
  // src/guest/setup/managed-policy.ts
33787
- import fs50 from "node:fs";
33788
- import path63 from "node:path";
33996
+ import fs51 from "node:fs";
33997
+ import path64 from "node:path";
33789
33998
 
33790
33999
  // src/guest/setup/git-rules.ts
33791
34000
  var SHELLS = ["Bash", "PowerShell"];
@@ -33842,24 +34051,24 @@ function gitDenyRules(access) {
33842
34051
 
33843
34052
  // src/guest/setup/managed-policy.ts
33844
34053
  function managedSettingsFile() {
33845
- return path63.join(path63.dirname(managedClaudeMd()), "managed-settings.json");
34054
+ return path64.join(path64.dirname(managedClaudeMd()), "managed-settings.json");
33846
34055
  }
33847
34056
  function writeManagedSettings2(access, headroom = null) {
33848
34057
  const file3 = managedSettingsFile();
33849
34058
  const rtk = installedRtk();
33850
34059
  const settings = claudeManagedSettings(gitDenyRules(access), rtk, headroom);
33851
34060
  if (!settings) {
33852
- fs50.rmSync(file3, { force: true });
34061
+ fs51.rmSync(file3, { force: true });
33853
34062
  return;
33854
34063
  }
33855
- fs50.mkdirSync(path63.dirname(file3), { recursive: true });
33856
- fs50.writeFileSync(file3, JSON.stringify(settings, null, 2) + "\n", "utf8");
34064
+ fs51.mkdirSync(path64.dirname(file3), { recursive: true });
34065
+ fs51.writeFileSync(file3, JSON.stringify(settings, null, 2) + "\n", "utf8");
33857
34066
  if (rtk) log("rtk: Claude Code's Bash commands go through it (hook in " + file3 + ")");
33858
34067
  }
33859
34068
 
33860
34069
  // src/guest/setup/addon-mcp.ts
33861
- import fs51 from "node:fs";
33862
- import path64 from "node:path";
34070
+ import fs52 from "node:fs";
34071
+ import path65 from "node:path";
33863
34072
  var ADDON_MCP_NAMES = APPS.flatMap((a) => a.mcp ? [a.mcp.name] : []);
33864
34073
  function writeAddonMcpServers() {
33865
34074
  const servers = {};
@@ -33867,11 +34076,11 @@ function writeAddonMcpServers() {
33867
34076
  const mcp = APPS.find((a) => a.id === id)?.mcp;
33868
34077
  if (mcp) servers[mcp.name] = addonMcpServer(folder, mcp);
33869
34078
  }
33870
- const file3 = path64.join(claudeDir, ".claude.json");
34079
+ const file3 = path65.join(claudeDir, ".claude.json");
33871
34080
  let state = {};
33872
- if (fs51.existsSync(file3)) {
34081
+ if (fs52.existsSync(file3)) {
33873
34082
  try {
33874
- const text = fs51.readFileSync(file3, "utf8");
34083
+ const text = fs52.readFileSync(file3, "utf8");
33875
34084
  state = JSON.parse(text.charCodeAt(0) === 65279 ? text.slice(1) : text);
33876
34085
  } catch {
33877
34086
  warn("Claude Code MCP servers from Apps: " + file3 + " is not valid JSON, left as it is");
@@ -33883,7 +34092,7 @@ function writeAddonMcpServers() {
33883
34092
  const before = current && typeof current === "object" && !Array.isArray(current) ? current : {};
33884
34093
  const after = withAddonMcpServers(before, servers, ADDON_MCP_NAMES);
33885
34094
  if (JSON.stringify(before) !== JSON.stringify(after)) {
33886
- fs51.mkdirSync(claudeDir, { recursive: true });
34095
+ fs52.mkdirSync(claudeDir, { recursive: true });
33887
34096
  writeJsonAtomic(file3, { ...state, mcpServers: after });
33888
34097
  }
33889
34098
  const names = Object.keys(servers);
@@ -33892,11 +34101,11 @@ function writeAddonMcpServers() {
33892
34101
  }
33893
34102
 
33894
34103
  // src/guest/setup/headroom.ts
33895
- import fs52 from "node:fs";
34104
+ import fs53 from "node:fs";
33896
34105
  import http from "node:http";
33897
- import path65 from "node:path";
34106
+ import path66 from "node:path";
33898
34107
  import { spawn as spawn7 } from "node:child_process";
33899
- var HEADROOM_LOG = path65.join(logsDir, "headroom.log");
34108
+ var HEADROOM_LOG = path66.join(logsDir, "headroom.log");
33900
34109
  function answersAsHeadroom(port) {
33901
34110
  return new Promise((resolve2) => {
33902
34111
  const req = http.get({ host: "127.0.0.1", port, path: "/livez", timeout: 3e3 }, (res) => {
@@ -33920,14 +34129,14 @@ async function startHeadroom(env) {
33920
34129
  }
33921
34130
  const port = HEADROOM_PORT;
33922
34131
  if (!await portOpen(port)) {
33923
- const out = fs52.openSync(HEADROOM_LOG, "a");
34132
+ const out = fs53.openSync(HEADROOM_LOG, "a");
33924
34133
  spawn7(exe, headroomArgs(port), {
33925
34134
  detached: true,
33926
34135
  stdio: ["ignore", out, out],
33927
34136
  windowsHide: true,
33928
34137
  env: headroomEnv(env)
33929
34138
  }).unref();
33930
- fs52.closeSync(out);
34139
+ fs53.closeSync(out);
33931
34140
  if (!await waitForPort(port, 90))
33932
34141
  throw new Error("the Headroom proxy did not start on port " + port + "; see " + HEADROOM_LOG);
33933
34142
  }
@@ -33938,30 +34147,41 @@ async function startHeadroom(env) {
33938
34147
  }
33939
34148
 
33940
34149
  // src/guest/setup/desktop.ts
33941
- import fs53 from "node:fs";
33942
- import os10 from "node:os";
33943
- import path66 from "node:path";
34150
+ import fs54 from "node:fs";
34151
+ import os11 from "node:os";
34152
+ import path67 from "node:path";
33944
34153
  function applyPersonalization() {
33945
- const dir = path66.join(launchDir, "personalize");
34154
+ const dir = path67.join(launchDir, "personalize");
33946
34155
  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);
34156
+ exec(SYSTEM.reg(), ["import", path67.join(dir, "personalize.reg")], { stdio: "ignore" });
34157
+ const wallpaper = fs54.readdirSync(dir).find((f) => f.startsWith("wallpaper"));
34158
+ const local = wallpaper ? path67.join(mkdirp(path67.join(os11.homedir(), "Pictures")), wallpaper) : null;
34159
+ if (wallpaper && local) fs54.copyFileSync(path67.join(dir, wallpaper), local);
33951
34160
  runScript("set-desktop.ps1", local ? ["-Wallpaper", local] : []);
33952
34161
  log("Desktop personalisation applied from this PC.");
33953
34162
  }
33954
34163
 
34164
+ // src/guest/setup/browser-gpu.ts
34165
+ var POLICY_KEYS = ["HKLM\\SOFTWARE\\Policies\\Microsoft\\Edge", "HKLM\\SOFTWARE\\Policies\\Google\\Chrome"];
34166
+ function keepBrowsersOffGpu() {
34167
+ if (dryRun || !isWin) return;
34168
+ for (const key of POLICY_KEYS)
34169
+ exec(SYSTEM.reg(), ["add", key, "/v", "HardwareAccelerationModeEnabled", "/t", "REG_DWORD", "/d", "0", "/f"], {
34170
+ stdio: "ignore"
34171
+ });
34172
+ log("Browsers draw without the GPU (Edge and Chrome policy).");
34173
+ }
34174
+
33955
34175
  // src/guest/setup/git-identity.ts
33956
- import fs54 from "node:fs";
33957
- import os11 from "node:os";
33958
- import path67 from "node:path";
34176
+ import fs55 from "node:fs";
34177
+ import os12 from "node:os";
34178
+ import path68 from "node:path";
33959
34179
  import { spawnSync as spawnSync7 } from "node:child_process";
33960
34180
  function setupGitConfig(env) {
33961
34181
  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");
34182
+ const source = path68.join(launchDir, "home", ".gitconfig");
34183
+ if (exists(source)) fs55.copyFileSync(source, path68.join(os12.homedir(), ".gitconfig"));
34184
+ const git = path68.join(toolsDir, "git", "cmd", "git.exe");
33965
34185
  if (!exists(git)) return;
33966
34186
  const { GIT_DIR: _gitDir, ...rest } = env;
33967
34187
  spawnSync7(git, ["config", "--global", "--add", "safe.directory", "*"], {
@@ -33974,7 +34194,7 @@ function setupGitConfig(env) {
33974
34194
  }
33975
34195
 
33976
34196
  // src/guest/setup/github-token.ts
33977
- import fs55 from "node:fs";
34197
+ import fs56 from "node:fs";
33978
34198
  import { spawnSync as spawnSync8 } from "node:child_process";
33979
34199
 
33980
34200
  // src/shared/github/token.ts
@@ -34020,7 +34240,7 @@ function ghOutputText(text, token) {
34020
34240
  var GH_TIMEOUT_MS = 6e4;
34021
34241
  function prepareGithubFolder(token) {
34022
34242
  const dir = deliveredGhConfigDir();
34023
- fs55.rmSync(dir, { recursive: true, force: true });
34243
+ fs56.rmSync(dir, { recursive: true, force: true });
34024
34244
  if (!token) return false;
34025
34245
  mkdirp(dir);
34026
34246
  return true;
@@ -34048,7 +34268,7 @@ function loginGithub(token, env) {
34048
34268
  const gh2 = ghExePath();
34049
34269
  const dir = deliveredGhConfigDir();
34050
34270
  if (!exists(gh2) || env.GH_CONFIG_DIR !== dir) {
34051
- fs55.rmSync(dir, { recursive: true, force: true });
34271
+ fs56.rmSync(dir, { recursive: true, force: true });
34052
34272
  log("A GitHub token arrived, but gh is not set up in this sandbox (toolchains.cli.gh), so it is not used.");
34053
34273
  return;
34054
34274
  }
@@ -34056,7 +34276,7 @@ function loginGithub(token, env) {
34056
34276
  runGh(ghLoginCommand(gh2, dir, token, env), token, "gh auth login");
34057
34277
  runGh(ghSetupGitCommand(gh2, dir, env), token, "gh auth setup-git");
34058
34278
  } catch (e) {
34059
- fs55.rmSync(dir, { recursive: true, force: true });
34279
+ fs56.rmSync(dir, { recursive: true, force: true });
34060
34280
  env.GH_CONFIG_DIR = mkdirp(ghConfigDir());
34061
34281
  addMachineEnvironment({ GH_CONFIG_DIR: env.GH_CONFIG_DIR }, []);
34062
34282
  throw e;
@@ -34070,35 +34290,35 @@ function ensurePtyHost() {
34070
34290
  }
34071
34291
 
34072
34292
  // src/guest/toolchains/leftovers.ts
34073
- import fs56 from "node:fs";
34074
- import path68 from "node:path";
34293
+ import fs57 from "node:fs";
34294
+ import path69 from "node:path";
34075
34295
  var STAGING = /\.staging-[0-9a-f]+$/i;
34076
34296
  var entries2 = (dir) => {
34077
34297
  try {
34078
- return fs56.readdirSync(dir, { withFileTypes: true });
34298
+ return fs57.readdirSync(dir, { withFileTypes: true });
34079
34299
  } catch {
34080
34300
  return [];
34081
34301
  }
34082
34302
  };
34083
34303
  function pruneToolLeftovers() {
34084
- for (const legacy of ["ptyhost", "gitshim"]) safeRemove(path68.join(toolsDir, legacy), toolsDir);
34304
+ for (const legacy of ["ptyhost", "gitshim"]) safeRemove(path69.join(toolsDir, legacy), toolsDir);
34085
34305
  for (const top of entries2(toolsDir)) {
34086
- const dir = path68.join(toolsDir, top.name);
34306
+ const dir = path69.join(toolsDir, top.name);
34087
34307
  if (STAGING.test(top.name)) safeRemove(dir, toolsDir);
34088
34308
  else if (top.isDirectory())
34089
- for (const sub of entries2(dir).filter((e) => STAGING.test(e.name))) safeRemove(path68.join(dir, sub.name), dir);
34309
+ for (const sub of entries2(dir).filter((e) => STAGING.test(e.name))) safeRemove(path69.join(dir, sub.name), dir);
34090
34310
  }
34091
34311
  }
34092
34312
 
34093
34313
  // src/guest/audit/process-audit.ts
34094
- import path69 from "node:path";
34314
+ import path70 from "node:path";
34095
34315
  import { spawnSync as spawnSync9 } from "node:child_process";
34096
34316
  var PROCESS_CREATION = "{0CCE922B-69AE-11D9-BED3-505054503030}";
34097
34317
  var auditOn = () => Boolean(session.auditProcesses) && isWin && !dryRun;
34098
34318
  function enableProcessAudit() {
34099
34319
  if (!auditOn()) return;
34100
34320
  spawnSync9(
34101
- path69.join(process.env.WINDIR ?? "C:\\Windows", "System32", "auditpol.exe"),
34321
+ path70.join(process.env.WINDIR ?? "C:\\Windows", "System32", "auditpol.exe"),
34102
34322
  ["/set", "/subcategory:" + PROCESS_CREATION, "/success:enable"],
34103
34323
  { windowsHide: true, stdio: "ignore" }
34104
34324
  );
@@ -34122,10 +34342,10 @@ function enableProcessAudit() {
34122
34342
 
34123
34343
  // src/guest/vpn/vpn.ts
34124
34344
  import dns2 from "node:dns";
34125
- import fs60 from "node:fs";
34345
+ import fs61 from "node:fs";
34126
34346
  import net3 from "node:net";
34127
- import os14 from "node:os";
34128
- import path73 from "node:path";
34347
+ import os15 from "node:os";
34348
+ import path74 from "node:path";
34129
34349
 
34130
34350
  // src/shared/vpn/ovpn.ts
34131
34351
  var PROGRAM_DIRECTIVES = [
@@ -34648,8 +34868,8 @@ function tunnelAddressFromLog(log2) {
34648
34868
 
34649
34869
  // src/guest/vpn/openvpn.ts
34650
34870
  import crypto4 from "node:crypto";
34651
- import fs57 from "node:fs";
34652
- import path70 from "node:path";
34871
+ import fs58 from "node:fs";
34872
+ import path71 from "node:path";
34653
34873
 
34654
34874
  // src/shared/vpn/download.ts
34655
34875
  var OPENVPN_MSI = {
@@ -34679,7 +34899,7 @@ var WIREGUARD_MSI = {
34679
34899
 
34680
34900
  // src/guest/vpn/openvpn.ts
34681
34901
  function openvpnExe(env = process.env) {
34682
- return path70.join(env.ProgramFiles ?? "C:\\Program Files", "OpenVPN", "bin", "openvpn.exe");
34902
+ return path71.join(env.ProgramFiles ?? "C:\\Program Files", "OpenVPN", "bin", "openvpn.exe");
34683
34903
  }
34684
34904
  function openvpnDownload(arch2 = process.arch) {
34685
34905
  const entry = arch2 === "arm64" ? OPENVPN_MSI.arm64 : OPENVPN_MSI.x64;
@@ -34690,20 +34910,20 @@ function repairServiceQueries() {
34690
34910
  if (did === "removed") log("VPN: repaired the Windows service queries installers use (a Windows Sandbox gap).");
34691
34911
  else if (did !== "absent" && did !== "kept") warn("VPN: could not check the Windows service queries installers use.");
34692
34912
  }
34693
- var hasHash = (file3, sha256) => crypto4.createHash("sha256").update(fs57.readFileSync(file3)).digest("hex") === sha256;
34913
+ var hasHash = (file3, sha256) => crypto4.createHash("sha256").update(fs58.readFileSync(file3)).digest("hex") === sha256;
34694
34914
  async function ensureOpenVpn() {
34695
34915
  const exe = openvpnExe();
34696
34916
  if (!isWin || dryRun) return exe;
34697
34917
  if (exists(exe)) return exe;
34698
34918
  const dl = openvpnDownload();
34699
- const msi = path70.join(mkdirp(path70.join(toolsDir, "downloads")), dl.file);
34919
+ const msi = path71.join(mkdirp(path71.join(toolsDir, "downloads")), dl.file);
34700
34920
  if (!exists(msi) || !hasHash(msi, dl.sha256)) {
34701
34921
  log("VPN: downloading OpenVPN " + OPENVPN_MSI.version + " (about 6 MB)");
34702
34922
  await downloader.file(dl.url, msi, dl.sha256);
34703
34923
  }
34704
34924
  repairServiceQueries();
34705
34925
  log("VPN: installing OpenVPN");
34706
- const logFile2 = path70.join(toolsDir, "downloads", "openvpn-install.log");
34926
+ const logFile2 = path71.join(toolsDir, "downloads", "openvpn-install.log");
34707
34927
  const code = await spawnAsync(SYSTEM.msiexec(), ["/i", msi, "/qn", "/norestart", "/l*v", logFile2], {
34708
34928
  stdio: "ignore"
34709
34929
  });
@@ -34715,9 +34935,9 @@ async function ensureOpenVpn() {
34715
34935
 
34716
34936
  // src/guest/vpn/tunnel.ts
34717
34937
  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";
34938
+ import fs59 from "node:fs";
34939
+ import os13 from "node:os";
34940
+ import path72 from "node:path";
34721
34941
  var DONE = "Initialization Sequence Completed";
34722
34942
  function failureReason(text) {
34723
34943
  if (/AUTH_FAILED/i.test(text))
@@ -34733,17 +34953,17 @@ function failureReason(text) {
34733
34953
  }
34734
34954
  var tail = (text, lines = 12) => text.trim().split(/\r?\n/).slice(-lines).join("\n");
34735
34955
  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");
34956
+ const dir = fs59.mkdtempSync(path72.join(os13.tmpdir(), "sbx-vpn-"));
34957
+ const auth = path72.join(dir, "login.txt");
34958
+ const logFile2 = path72.join(dir, "openvpn.log");
34739
34959
  const keepLog = () => {
34740
34960
  try {
34741
- fs58.mkdirSync(logsDir, { recursive: true });
34742
- fs58.copyFileSync(logFile2, path71.join(logsDir, "openvpn.log"));
34961
+ fs59.mkdirSync(logsDir, { recursive: true });
34962
+ fs59.copyFileSync(logFile2, path72.join(logsDir, "openvpn.log"));
34743
34963
  } catch {
34744
34964
  }
34745
34965
  };
34746
- fs58.writeFileSync(auth, o.username + "\r\n" + o.password + "\r\n", "utf8");
34966
+ fs59.writeFileSync(auth, o.username + "\r\n" + o.password + "\r\n", "utf8");
34747
34967
  try {
34748
34968
  const child = spawn8(
34749
34969
  o.exe,
@@ -34761,7 +34981,7 @@ async function startTunnel(o) {
34761
34981
  child.unref();
34762
34982
  const deadline = Date.now() + (o.timeoutMs ?? 9e4);
34763
34983
  for (; ; ) {
34764
- const text = fs58.existsSync(logFile2) ? fs58.readFileSync(logFile2, "utf8") : "";
34984
+ const text = fs59.existsSync(logFile2) ? fs59.readFileSync(logFile2, "utf8") : "";
34765
34985
  if (text.includes(DONE)) {
34766
34986
  keepLog();
34767
34987
  const tunnelIp = tunnelAddressFromLog(text) ?? void 0;
@@ -34781,41 +35001,41 @@ async function startTunnel(o) {
34781
35001
  await new Promise((r) => setTimeout(r, 500));
34782
35002
  }
34783
35003
  } finally {
34784
- fs58.rmSync(auth, { force: true });
35004
+ fs59.rmSync(auth, { force: true });
34785
35005
  }
34786
35006
  }
34787
35007
 
34788
35008
  // src/guest/vpn/wireguard.ts
34789
35009
  import { execFile } from "node:child_process";
34790
35010
  import crypto5 from "node:crypto";
34791
- import fs59 from "node:fs";
34792
- import os13 from "node:os";
34793
- import path72 from "node:path";
35011
+ import fs60 from "node:fs";
35012
+ import os14 from "node:os";
35013
+ import path73 from "node:path";
34794
35014
  var WIREGUARD_TUNNEL = "sandbox";
34795
35015
  function wireguardDir(env = process.env) {
34796
- return path72.join(env.ProgramFiles ?? "C:\\Program Files", "WireGuard");
35016
+ return path73.join(env.ProgramFiles ?? "C:\\Program Files", "WireGuard");
34797
35017
  }
34798
35018
  function wireguardExe(env = process.env) {
34799
- return path72.join(wireguardDir(env), "wireguard.exe");
35019
+ return path73.join(wireguardDir(env), "wireguard.exe");
34800
35020
  }
34801
35021
  function wireguardDownload(arch2 = process.arch) {
34802
35022
  const entry = arch2 === "arm64" ? WIREGUARD_MSI.arm64 : WIREGUARD_MSI.x64;
34803
35023
  return { ...entry, url: WIREGUARD_MSI.base + entry.file };
34804
35024
  }
34805
- var hasHash2 = (file3, sha256) => crypto5.createHash("sha256").update(fs59.readFileSync(file3)).digest("hex") === sha256;
35025
+ var hasHash2 = (file3, sha256) => crypto5.createHash("sha256").update(fs60.readFileSync(file3)).digest("hex") === sha256;
34806
35026
  async function ensureWireguard() {
34807
35027
  const exe = wireguardExe();
34808
35028
  if (!isWin || dryRun) return exe;
34809
35029
  if (exists(exe)) return exe;
34810
35030
  const dl = wireguardDownload();
34811
- const msi = path72.join(mkdirp(path72.join(toolsDir, "downloads")), dl.file);
35031
+ const msi = path73.join(mkdirp(path73.join(toolsDir, "downloads")), dl.file);
34812
35032
  if (!exists(msi) || !hasHash2(msi, dl.sha256)) {
34813
35033
  log("VPN: downloading WireGuard " + WIREGUARD_MSI.version + " (about 3 MB)");
34814
35034
  await downloader.file(dl.url, msi, dl.sha256);
34815
35035
  }
34816
35036
  repairServiceQueries();
34817
35037
  log("VPN: installing WireGuard");
34818
- const logFile2 = path72.join(toolsDir, "downloads", "wireguard-install.log");
35038
+ const logFile2 = path73.join(toolsDir, "downloads", "wireguard-install.log");
34819
35039
  const code = await spawnAsync(
34820
35040
  SYSTEM.msiexec(),
34821
35041
  ["/i", msi, "/qn", "/norestart", "DO_NOT_LAUNCH=1", "/l*v", logFile2],
@@ -34839,7 +35059,7 @@ function output2(file3, args) {
34839
35059
  });
34840
35060
  }
34841
35061
  var serviceName = () => "WireGuardTunnel$" + WIREGUARD_TUNNEL;
34842
- var hasAdapter = (ip) => Object.values(os13.networkInterfaces()).some((list) => (list ?? []).some((i) => i.address === ip));
35062
+ var hasAdapter = (ip) => Object.values(os14.networkInterfaces()).some((list) => (list ?? []).some((i) => i.address === ip));
34843
35063
  async function removeWireguardTunnel(exe) {
34844
35064
  try {
34845
35065
  await output2(exe, ["/uninstalltunnelservice", WIREGUARD_TUNNEL]);
@@ -34847,10 +35067,10 @@ async function removeWireguardTunnel(exe) {
34847
35067
  }
34848
35068
  }
34849
35069
  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");
35070
+ const root = path73.join(process.env.SystemRoot ?? "C:\\Windows", "Temp");
35071
+ const dir = fs60.mkdtempSync(path73.join(fs60.existsSync(root) ? root : os14.tmpdir(), "sbx-wg-"));
35072
+ const file3 = path73.join(dir, WIREGUARD_TUNNEL + ".conf");
35073
+ fs60.writeFileSync(file3, o.config, "utf8");
34854
35074
  const fail = async (message) => {
34855
35075
  await removeWireguardTunnel(o.exe);
34856
35076
  return { ok: false, message };
@@ -34871,11 +35091,11 @@ async function startWireguardTunnel(o) {
34871
35091
  await sleep(500);
34872
35092
  }
34873
35093
  } finally {
34874
- fs59.rmSync(dir, { recursive: true, force: true });
35094
+ fs60.rmSync(dir, { recursive: true, force: true });
34875
35095
  }
34876
35096
  }
34877
35097
  async function waitForHandshake(exe, poke, timeoutMs = 3e4) {
34878
- const wg = path72.join(path72.dirname(exe), "wg.exe");
35098
+ const wg = path73.join(path73.dirname(exe), "wg.exe");
34879
35099
  if (!exists(wg)) return { ok: true, message: "the tunnel service is running (no wg.exe to check the handshake)" };
34880
35100
  const deadline = Date.now() + timeoutMs;
34881
35101
  for (; ; ) {
@@ -34939,7 +35159,7 @@ async function publicAddress() {
34939
35159
  return null;
34940
35160
  }
34941
35161
  }
34942
- var hasAdapter2 = (ip) => Object.values(os14.networkInterfaces()).some((list) => (list ?? []).some((i) => i.address === ip));
35162
+ var hasAdapter2 = (ip) => Object.values(os15.networkInterfaces()).some((list) => (list ?? []).some((i) => i.address === ip));
34943
35163
  var PROBE_TARGETS = ["1.1.1.1", "8.8.8.8", "9.9.9.9"];
34944
35164
  var PROBE_TIMEOUT_MS = 3e3;
34945
35165
  function connects(ip, port) {
@@ -35010,8 +35230,8 @@ async function setupVpn(secrets, ptyHostExe) {
35010
35230
  } else {
35011
35231
  const credentials = secrets.vpn;
35012
35232
  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);
35233
+ const profile = path74.join(launchDir, "vpn", "server.ovpn");
35234
+ const remotes = assertSafeOvpn(fs61.readFileSync(profile, "utf8"), vpn.server);
35015
35235
  const exe = await ensureOpenVpn();
35016
35236
  const servers = await serverAddresses(remotes);
35017
35237
  if (servers.length === 0) throw new Error("the VPN server addresses could not be found");
@@ -35697,7 +35917,7 @@ async function viewSession(id) {
35697
35917
  }
35698
35918
 
35699
35919
  // src/guest/boot/boot-env.ts
35700
- import path74 from "node:path";
35920
+ import path75 from "node:path";
35701
35921
 
35702
35922
  // src/guest/boot/project-env.ts
35703
35923
  var EnvSchema = external_exports.object({
@@ -35716,7 +35936,7 @@ var BootEnvSchema = external_exports.object({
35716
35936
  });
35717
35937
 
35718
35938
  // src/guest/boot/boot-env.ts
35719
- var file2 = () => path74.join(localDir, "boot-env.json");
35939
+ var file2 = () => path75.join(localDir, "boot-env.json");
35720
35940
  function saveBootEnv(value) {
35721
35941
  try {
35722
35942
  writeJsonAtomic(file2(), value);
@@ -35745,7 +35965,7 @@ function saveProjectStatus(name, workspace2, phase, message, databases, summary)
35745
35965
  }
35746
35966
 
35747
35967
  // src/guest/runtime/secrets.ts
35748
- import fs61 from "node:fs";
35968
+ import fs62 from "node:fs";
35749
35969
 
35750
35970
  // src/shared/channel/secrets.ts
35751
35971
  var Environment = external_exports.record(external_exports.string().max(256), external_exports.string().max(65536));
@@ -35775,12 +35995,12 @@ function takeSecrets(id) {
35775
35995
  const file3 = run.secretFile(id);
35776
35996
  let text;
35777
35997
  try {
35778
- if (fs61.statSync(file3).size > MAX_BYTES) throw new Error("too big");
35779
- text = fs61.readFileSync(file3, "utf8").replace(/^\uFEFF/, "");
35998
+ if (fs62.statSync(file3).size > MAX_BYTES) throw new Error("too big");
35999
+ text = fs62.readFileSync(file3, "utf8").replace(/^\uFEFF/, "");
35780
36000
  } catch {
35781
36001
  return {};
35782
36002
  } finally {
35783
- fs61.rmSync(file3, { force: true });
36003
+ fs62.rmSync(file3, { force: true });
35784
36004
  }
35785
36005
  try {
35786
36006
  const parsed = SecretsFileSchema.safeParse(JSON.parse(text));
@@ -35818,7 +36038,7 @@ async function soft(what, work) {
35818
36038
  }
35819
36039
  }
35820
36040
  function startDaemon(env, secrets) {
35821
- spawn10(process.execPath, [path75.join(path75.dirname(process.argv[1]), "daemon.js")], {
36041
+ spawn10(process.execPath, [path76.join(path76.dirname(process.argv[1]), "daemon.js")], {
35822
36042
  detached: true,
35823
36043
  stdio: "ignore",
35824
36044
  windowsHide: true,
@@ -35837,20 +36057,20 @@ function startDaemon(env, secrets) {
35837
36057
  }).unref();
35838
36058
  }
35839
36059
  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"),
36060
+ const dir = mkdirp(path76.join(localDir, "bin"));
36061
+ const db = path76.join(path76.dirname(process.argv[1]), "db.js");
36062
+ fs63.writeFileSync(
36063
+ path76.join(dir, "sbx-db.cmd"),
35844
36064
  '@setlocal\r\n@set AGENT_LOG_PREFIX=db\r\n@"' + process.execPath + '" "' + db + '" %*\r\n'
35845
36065
  );
35846
36066
  writeAgentCommands(dir);
35847
36067
  return dir;
35848
36068
  }
35849
36069
  function writeAgentCommands(dir) {
35850
- const install = { node: process.execPath, script: path75.join(path75.dirname(process.argv[1]), "agent.js") };
36070
+ const install = { node: process.execPath, script: path76.join(path76.dirname(process.argv[1]), "agent.js") };
35851
36071
  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));
36072
+ fs63.writeFileSync(path76.join(dir, shim3.command + ".cmd"), shimText(shim3, install));
36073
+ fs63.writeFileSync(path76.join(dir, "sbx-agent.cmd"), sbxAgentText(install));
35854
36074
  }
35855
36075
  async function waitForPrimary() {
35856
36076
  for (let i = 0; i < PRIMARY_POLLS; i++) {
@@ -35878,7 +36098,7 @@ var Boot = class {
35878
36098
  log(
35879
36099
  "Agent sandbox: " + session.project + " | workspace " + workspace + " | agent " + session.harnessName + " | log " + logPath
35880
36100
  );
35881
- if (!fs62.statSync(workspace, { throwIfNoEntry: false })?.isDirectory())
36101
+ if (!fs63.statSync(workspace, { throwIfNoEntry: false })?.isDirectory())
35882
36102
  throw new Error("Workspace folder is missing in the sandbox: " + workspace);
35883
36103
  mkdirp(toolsDir);
35884
36104
  mkdirp(run.root);
@@ -35910,6 +36130,7 @@ var Boot = class {
35910
36130
  step(2, "Pre-provision hooks and desktop");
35911
36131
  runHooks("pre-provision", process.env);
35912
36132
  await soft("Personalisation", applyPersonalization);
36133
+ await soft("Browsers without the GPU", keepBrowsersOffGpu);
35913
36134
  }
35914
36135
  /** Toolchains, databases, apps, the network proxy and VS Code; then the agent environment, saved machine-wide. */
35915
36136
  async developerTools() {
@@ -35980,6 +36201,7 @@ var Boot = class {
35980
36201
  await soft("claude-mem restore", restoreClaudeMem);
35981
36202
  await soft("Agent files of the last sandbox", resetMachineBound);
35982
36203
  await soft("Agent databases restore", restoreLocalState);
36204
+ await soft("Codex without its own sandbox", codexWithoutInnerSandbox);
35983
36205
  let headroom = null;
35984
36206
  await soft("MCP servers from Apps", writeAddonMcpServers);
35985
36207
  await soft("Headroom proxy", async () => {
@@ -36038,11 +36260,11 @@ runBoot().catch((e) => {
36038
36260
  const message = errMsg(e) + (e instanceof Error && e.stack ? "\n" + e.stack : "");
36039
36261
  try {
36040
36262
  setSandboxStatus("failed", errMsg(e));
36041
- fs63.writeFileSync(path76.join(logsDir, "guest-error.txt"), message);
36263
+ fs64.writeFileSync(path77.join(logsDir, "guest-error.txt"), message);
36042
36264
  } catch {
36043
36265
  }
36044
36266
  console.error(
36045
- "\n\x1B[31mThe sandbox could not start: " + errMsg(e) + "\x1B[0m\nDetails: " + path76.join(logsDir, "guest-error.txt")
36267
+ "\n\x1B[31mThe sandbox could not start: " + errMsg(e) + "\x1B[0m\nDetails: " + path77.join(logsDir, "guest-error.txt")
36046
36268
  );
36047
36269
  process.exitCode = 1;
36048
36270
  });