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[key2]);
1364
1364
  });
1365
1365
  }
1366
- function baseGet(object2, path72) {
1367
- path72 = castPath(path72, object2);
1368
- var index = 0, length = path72.length;
1366
+ function baseGet(object2, path73) {
1367
+ path73 = castPath(path73, object2);
1368
+ var index = 0, length = path73.length;
1369
1369
  while (object2 != null && index < length) {
1370
- object2 = object2[toKey(path72[index++])];
1370
+ object2 = object2[toKey(path73[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, path72, args) {
1435
- path72 = castPath(path72, object2);
1436
- object2 = parent(object2, path72);
1437
- var func = object2 == null ? object2 : object2[toKey(last(path72))];
1434
+ function baseInvoke(object2, path73, args) {
1435
+ path73 = castPath(path73, object2);
1436
+ object2 = parent(object2, path73);
1437
+ var func = object2 == null ? object2 : object2[toKey(last(path73))];
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(path72, srcValue) {
1594
- if (isKey(path72) && isStrictComparable(srcValue)) {
1595
- return matchesStrictComparable(toKey(path72), srcValue);
1593
+ function baseMatchesProperty(path73, srcValue) {
1594
+ if (isKey(path73) && isStrictComparable(srcValue)) {
1595
+ return matchesStrictComparable(toKey(path73), srcValue);
1596
1596
  }
1597
1597
  return function(object2) {
1598
- var objValue = get(object2, path72);
1599
- return objValue === undefined2 && objValue === srcValue ? hasIn(object2, path72) : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG);
1598
+ var objValue = get(object2, path73);
1599
+ return objValue === undefined2 && objValue === srcValue ? hasIn(object2, path73) : 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, path72) {
1697
- return hasIn(object2, path72);
1696
+ return basePickBy(object2, paths, function(value, path73) {
1697
+ return hasIn(object2, path73);
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 path72 = paths[index], value = baseGet(object2, path72);
1704
- if (predicate(value, path72)) {
1705
- baseSet(result2, castPath(path72, object2), value);
1703
+ var path73 = paths[index], value = baseGet(object2, path73);
1704
+ if (predicate(value, path73)) {
1705
+ baseSet(result2, castPath(path73, object2), value);
1706
1706
  }
1707
1707
  }
1708
1708
  return result2;
1709
1709
  }
1710
- function basePropertyDeep(path72) {
1710
+ function basePropertyDeep(path73) {
1711
1711
  return function(object2) {
1712
- return baseGet(object2, path72);
1712
+ return baseGet(object2, path73);
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, path72, value, customizer) {
1786
+ function baseSet(object2, path73, value, customizer) {
1787
1787
  if (!isObject2(object2)) {
1788
1788
  return object2;
1789
1789
  }
1790
- path72 = castPath(path72, object2);
1791
- var index = -1, length = path72.length, lastIndex = length - 1, nested = object2;
1790
+ path73 = castPath(path73, object2);
1791
+ var index = -1, length = path73.length, lastIndex = length - 1, nested = object2;
1792
1792
  while (nested != null && ++index < length) {
1793
- var key2 = toKey(path72[index]), newValue = value;
1793
+ var key2 = toKey(path73[index]), newValue = value;
1794
1794
  if (key2 === "__proto__" || key2 === "constructor" || key2 === "prototype") {
1795
1795
  return object2;
1796
1796
  }
@@ -1798,7 +1798,7 @@ var require_lodash = __commonJS({
1798
1798
  var objValue = nested[key2];
1799
1799
  newValue = customizer ? customizer(objValue, key2, nested) : undefined2;
1800
1800
  if (newValue === undefined2) {
1801
- newValue = isObject2(objValue) ? objValue : isIndex(path72[index + 1]) ? [] : {};
1801
+ newValue = isObject2(objValue) ? objValue : isIndex(path73[index + 1]) ? [] : {};
1802
1802
  }
1803
1803
  }
1804
1804
  assignValue(nested, key2, newValue);
@@ -1964,14 +1964,14 @@ var require_lodash = __commonJS({
1964
1964
  }
1965
1965
  return result2;
1966
1966
  }
1967
- function baseUnset(object2, path72) {
1968
- path72 = castPath(path72, object2);
1969
- var index = -1, length = path72.length;
1967
+ function baseUnset(object2, path73) {
1968
+ path73 = castPath(path73, object2);
1969
+ var index = -1, length = path73.length;
1970
1970
  if (!length) {
1971
1971
  return true;
1972
1972
  }
1973
1973
  while (++index < length) {
1974
- var key2 = toKey(path72[index]);
1974
+ var key2 = toKey(path73[index]);
1975
1975
  if (key2 === "__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, path72);
1983
- return obj == null || delete obj[toKey(last(path72))];
1982
+ var obj = parent(object2, path73);
1983
+ return obj == null || delete obj[toKey(last(path73))];
1984
1984
  }
1985
- function baseUpdate(object2, path72, updater, customizer) {
1986
- return baseSet(object2, path72, updater(baseGet(object2, path72)), customizer);
1985
+ function baseUpdate(object2, path73, updater, customizer) {
1986
+ return baseSet(object2, path73, updater(baseGet(object2, path73)), 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, path72, hasFunc) {
2870
- path72 = castPath(path72, object2);
2871
- var index = -1, length = path72.length, result2 = false;
2869
+ function hasPath(object2, path73, hasFunc) {
2870
+ path73 = castPath(path73, object2);
2871
+ var index = -1, length = path73.length, result2 = false;
2872
2872
  while (++index < length) {
2873
- var key2 = toKey(path72[index]);
2873
+ var key2 = toKey(path73[index]);
2874
2874
  if (!(result2 = object2 != null && hasFunc(object2, key2))) {
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, path72) {
3076
- return path72.length < 2 ? object2 : baseGet(object2, baseSlice(path72, 0, -1));
3075
+ function parent(object2, path73) {
3076
+ return path73.length < 2 ? object2 : baseGet(object2, baseSlice(path73, 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, path72, args) {
3712
- var index = -1, isFunc = typeof path72 == "function", result2 = isArrayLike(collection) ? Array2(collection.length) : [];
3711
+ var invokeMap = baseRest(function(collection, path73, args) {
3712
+ var index = -1, isFunc = typeof path73 == "function", result2 = isArrayLike(collection) ? Array2(collection.length) : [];
3713
3713
  baseEach(collection, function(value) {
3714
- result2[++index] = isFunc ? apply(path72, value, args) : baseInvoke(value, path72, args);
3714
+ result2[++index] = isFunc ? apply(path73, value, args) : baseInvoke(value, path73, 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, path72, defaultValue) {
4367
- var result2 = object2 == null ? undefined2 : baseGet(object2, path72);
4366
+ function get(object2, path73, defaultValue) {
4367
+ var result2 = object2 == null ? undefined2 : baseGet(object2, path73);
4368
4368
  return result2 === undefined2 ? defaultValue : result2;
4369
4369
  }
4370
- function has(object2, path72) {
4371
- return object2 != null && hasPath(object2, path72, baseHas);
4370
+ function has(object2, path73) {
4371
+ return object2 != null && hasPath(object2, path73, baseHas);
4372
4372
  }
4373
- function hasIn(object2, path72) {
4374
- return object2 != null && hasPath(object2, path72, baseHasIn);
4373
+ function hasIn(object2, path73) {
4374
+ return object2 != null && hasPath(object2, path73, baseHasIn);
4375
4375
  }
4376
4376
  var invert = createInverter(function(result2, value, key2) {
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(path72) {
4428
- path72 = castPath(path72, object2);
4429
- isDeep || (isDeep = path72.length > 1);
4430
- return path72;
4427
+ paths = arrayMap(paths, function(path73) {
4428
+ path73 = castPath(path73, object2);
4429
+ isDeep || (isDeep = path73.length > 1);
4430
+ return path73;
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, path72) {
4457
- return predicate(value, path72[0]);
4456
+ return basePickBy(object2, props, function(value, path73) {
4457
+ return predicate(value, path73[0]);
4458
4458
  });
4459
4459
  }
4460
- function result(object2, path72, defaultValue) {
4461
- path72 = castPath(path72, object2);
4462
- var index = -1, length = path72.length;
4460
+ function result(object2, path73, defaultValue) {
4461
+ path73 = castPath(path73, object2);
4462
+ var index = -1, length = path73.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(path72[index])];
4468
+ var value = object2 == null ? undefined2 : object2[toKey(path73[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, path72, value) {
4478
- return object2 == null ? object2 : baseSet(object2, path72, value);
4477
+ function set2(object2, path73, value) {
4478
+ return object2 == null ? object2 : baseSet(object2, path73, value);
4479
4479
  }
4480
- function setWith(object2, path72, value, customizer) {
4480
+ function setWith(object2, path73, value, customizer) {
4481
4481
  customizer = typeof customizer == "function" ? customizer : undefined2;
4482
- return object2 == null ? object2 : baseSet(object2, path72, value, customizer);
4482
+ return object2 == null ? object2 : baseSet(object2, path73, 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, path72) {
4505
- return object2 == null ? true : baseUnset(object2, path72);
4504
+ function unset(object2, path73) {
4505
+ return object2 == null ? true : baseUnset(object2, path73);
4506
4506
  }
4507
- function update(object2, path72, updater) {
4508
- return object2 == null ? object2 : baseUpdate(object2, path72, castFunction(updater));
4507
+ function update(object2, path73, updater) {
4508
+ return object2 == null ? object2 : baseUpdate(object2, path73, castFunction(updater));
4509
4509
  }
4510
- function updateWith(object2, path72, updater, customizer) {
4510
+ function updateWith(object2, path73, updater, customizer) {
4511
4511
  customizer = typeof customizer == "function" ? customizer : undefined2;
4512
- return object2 == null ? object2 : baseUpdate(object2, path72, castFunction(updater), customizer);
4512
+ return object2 == null ? object2 : baseUpdate(object2, path73, 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(path72, srcValue) {
4899
- return baseMatchesProperty(path72, baseClone(srcValue, CLONE_DEEP_FLAG));
4898
+ function matchesProperty(path73, srcValue) {
4899
+ return baseMatchesProperty(path73, baseClone(srcValue, CLONE_DEEP_FLAG));
4900
4900
  }
4901
- var method = baseRest(function(path72, args) {
4901
+ var method = baseRest(function(path73, args) {
4902
4902
  return function(object2) {
4903
- return baseInvoke(object2, path72, args);
4903
+ return baseInvoke(object2, path73, args);
4904
4904
  };
4905
4905
  });
4906
4906
  var methodOf = baseRest(function(object2, args) {
4907
- return function(path72) {
4908
- return baseInvoke(object2, path72, args);
4907
+ return function(path73) {
4908
+ return baseInvoke(object2, path73, 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(path72) {
4956
- return isKey(path72) ? baseProperty(toKey(path72)) : basePropertyDeep(path72);
4955
+ function property(path73) {
4956
+ return isKey(path73) ? baseProperty(toKey(path73)) : basePropertyDeep(path73);
4957
4957
  }
4958
4958
  function propertyOf(object2) {
4959
- return function(path72) {
4960
- return object2 == null ? undefined2 : baseGet(object2, path72);
4959
+ return function(path73) {
4960
+ return object2 == null ? undefined2 : baseGet(object2, path73);
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(path72, args) {
5414
- if (typeof path72 == "function") {
5413
+ LazyWrapper.prototype.invokeMap = baseRest(function(path73, args) {
5414
+ if (typeof path73 == "function") {
5415
5415
  return new LazyWrapper(this);
5416
5416
  }
5417
5417
  return this.map(function(value) {
5418
- return baseInvoke(value, path72, args);
5418
+ return baseInvoke(value, path73, args);
5419
5419
  });
5420
5420
  });
5421
5421
  LazyWrapper.prototype.reject = function(predicate) {
@@ -6366,10 +6366,10 @@ function mergeDefs(...defs) {
6366
6366
  function cloneDef(schema) {
6367
6367
  return mergeDefs(schema._zod.def);
6368
6368
  }
6369
- function getElementAtPath(obj, path72) {
6370
- if (!path72)
6369
+ function getElementAtPath(obj, path73) {
6370
+ if (!path73)
6371
6371
  return obj;
6372
- return path72.reduce((acc, key2) => acc?.[key2], obj);
6372
+ return path73.reduce((acc, key2) => acc?.[key2], obj);
6373
6373
  }
6374
6374
  function promiseAllObject(promisesObj) {
6375
6375
  const keys = Object.keys(promisesObj);
@@ -6709,11 +6709,11 @@ function explicitlyAborted(x, startIndex = 0) {
6709
6709
  }
6710
6710
  return false;
6711
6711
  }
6712
- function prefixIssues(path72, issues) {
6712
+ function prefixIssues(path73, issues) {
6713
6713
  return issues.map((iss) => {
6714
6714
  var _a3;
6715
6715
  (_a3 = iss).path ?? (_a3.path = []);
6716
- iss.path.unshift(path72);
6716
+ iss.path.unshift(path73);
6717
6717
  return iss;
6718
6718
  });
6719
6719
  }
@@ -7163,16 +7163,16 @@ function flattenError(error62, mapper = (issue2) => issue2.message) {
7163
7163
  }
7164
7164
  function formatError(error62, mapper = (issue2) => issue2.message) {
7165
7165
  const fieldErrors = { _errors: [] };
7166
- const processError = (error63, path72 = []) => {
7166
+ const processError = (error63, path73 = []) => {
7167
7167
  for (const issue2 of error63.issues) {
7168
7168
  if (issue2.code === "invalid_union" && issue2.errors.length) {
7169
- issue2.errors.map((issues) => processError({ issues }, [...path72, ...issue2.path]));
7169
+ issue2.errors.map((issues) => processError({ issues }, [...path73, ...issue2.path]));
7170
7170
  } else if (issue2.code === "invalid_key") {
7171
- processError({ issues: issue2.issues }, [...path72, ...issue2.path]);
7171
+ processError({ issues: issue2.issues }, [...path73, ...issue2.path]);
7172
7172
  } else if (issue2.code === "invalid_element") {
7173
- processError({ issues: issue2.issues }, [...path72, ...issue2.path]);
7173
+ processError({ issues: issue2.issues }, [...path73, ...issue2.path]);
7174
7174
  } else {
7175
- const fullpath = [...path72, ...issue2.path];
7175
+ const fullpath = [...path73, ...issue2.path];
7176
7176
  if (fullpath.length === 0) {
7177
7177
  fieldErrors._errors.push(mapper(issue2));
7178
7178
  } else {
@@ -7211,17 +7211,17 @@ function formatError(error62, mapper = (issue2) => issue2.message) {
7211
7211
  }
7212
7212
  function treeifyError(error62, mapper = (issue2) => issue2.message) {
7213
7213
  const result = { errors: [] };
7214
- const processError = (error63, path72 = []) => {
7214
+ const processError = (error63, path73 = []) => {
7215
7215
  var _a3;
7216
7216
  for (const issue2 of error63.issues) {
7217
7217
  if (issue2.code === "invalid_union" && issue2.errors.length) {
7218
- issue2.errors.map((issues) => processError({ issues }, [...path72, ...issue2.path]));
7218
+ issue2.errors.map((issues) => processError({ issues }, [...path73, ...issue2.path]));
7219
7219
  } else if (issue2.code === "invalid_key") {
7220
- processError({ issues: issue2.issues }, [...path72, ...issue2.path]);
7220
+ processError({ issues: issue2.issues }, [...path73, ...issue2.path]);
7221
7221
  } else if (issue2.code === "invalid_element") {
7222
- processError({ issues: issue2.issues }, [...path72, ...issue2.path]);
7222
+ processError({ issues: issue2.issues }, [...path73, ...issue2.path]);
7223
7223
  } else {
7224
- const fullpath = [...path72, ...issue2.path];
7224
+ const fullpath = [...path73, ...issue2.path];
7225
7225
  if (fullpath.length === 0) {
7226
7226
  result.errors.push(mapper(issue2));
7227
7227
  continue;
@@ -7260,8 +7260,8 @@ function treeifyError(error62, mapper = (issue2) => issue2.message) {
7260
7260
  }
7261
7261
  function toDotPath(_path) {
7262
7262
  const segs = [];
7263
- const path72 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
7264
- for (const seg of path72) {
7263
+ const path73 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
7264
+ for (const seg of path73) {
7265
7265
  if (typeof seg === "number")
7266
7266
  segs.push(`[${seg}]`);
7267
7267
  else if (typeof seg === "symbol")
@@ -24363,13 +24363,13 @@ function resolveRef(ref, ctx) {
24363
24363
  if (!ref.startsWith("#")) {
24364
24364
  throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
24365
24365
  }
24366
- const path72 = ref.slice(1).split("/").filter(Boolean);
24367
- if (path72.length === 0) {
24366
+ const path73 = ref.slice(1).split("/").filter(Boolean);
24367
+ if (path73.length === 0) {
24368
24368
  return ctx.rootSchema;
24369
24369
  }
24370
24370
  const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
24371
- if (path72[0] === defsKey) {
24372
- const key2 = path72[1] === void 0 ? void 0 : decodeJSONPointerSegment(path72[1]);
24371
+ if (path73[0] === defsKey) {
24372
+ const key2 = path73[1] === void 0 ? void 0 : decodeJSONPointerSegment(path73[1]);
24373
24373
  if (!key2 || !ctx.defs[key2]) {
24374
24374
  throw new Error(`Reference not found: ${ref}`);
24375
24375
  }
@@ -25505,7 +25505,7 @@ var SandboxSchema = external_exports.strictObject({
25505
25505
  "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."
25506
25506
  ),
25507
25507
  vGpu: external_exports.boolean().describe(
25508
- "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)."
25508
+ "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)."
25509
25509
  ),
25510
25510
  networking: external_exports.boolean().describe("Internet access. false is the only hard network isolation Windows Sandbox offers."),
25511
25511
  clipboard: external_exports.boolean().describe(
@@ -25667,6 +25667,21 @@ var ToolchainsSchema = external_exports.strictObject({
25667
25667
  msvcVersion: external_exports.string().min(1).describe('"latest" or an MSVC tools version prefix, e.g. "14.44".'),
25668
25668
  sdkVersion: external_exports.string().min(1).describe('"latest" or a Windows SDK build, e.g. "26100" or "10.0.22621".')
25669
25669
  }),
25670
+ unreal: external_exports.strictObject({
25671
+ enabled: enabled(
25672
+ "Unreal Engine development: Visual Studio Community 2022 with the C++ game workload (MSVC, a Windows 11 SDK, .NET Framework targeting packs, Unreal integration and the Epic Games Launcher) and the DirectX End-User Runtime. A real installer: it runs every boot (~10 GB on the sandbox disk). The engine itself comes from the Epic Games Launcher or its source.",
25673
+ "a .uproject or .uplugin"
25674
+ ),
25675
+ acceptLicense: external_exports.boolean().describe(
25676
+ "Required to install: you accept the Visual Studio Community licence terms (https://visualstudio.microsoft.com/license-terms/) and the DirectX End-User Runtime licence."
25677
+ ),
25678
+ components: StringsSchema.describe(
25679
+ 'More Visual Studio workload or component IDs to add, e.g. ["Microsoft.VisualStudio.Component.VC.Llvm.Clang"].'
25680
+ ),
25681
+ keepInstallFiles: external_exports.boolean().describe(
25682
+ "Keep an offline copy of the Visual Studio install files in tools\\visualstudio (~10 GB, made once), so later boots install without downloading them again. Skipped while that disk has too little room."
25683
+ )
25684
+ }),
25670
25685
  cpp: external_exports.strictObject({
25671
25686
  enabled: enabled(
25672
25687
  "MinGW-w64 GCC with CMake, Ninja, premake5 and mingw32-make (also Rust's linker).",
@@ -28041,7 +28056,7 @@ function withRequestSecrets(req) {
28041
28056
  }
28042
28057
 
28043
28058
  // src/guest/daemon/daemon.ts
28044
- import fs57 from "node:fs";
28059
+ import fs58 from "node:fs";
28045
28060
 
28046
28061
  // src/guest/setup/claude-mem.ts
28047
28062
  import fs15 from "node:fs";
@@ -28482,8 +28497,8 @@ function withRegistryPath(env) {
28482
28497
  }
28483
28498
 
28484
28499
  // src/guest/daemon/project-provisioner.ts
28485
- import fs49 from "node:fs";
28486
- import path63 from "node:path";
28500
+ import fs50 from "node:fs";
28501
+ import path64 from "node:path";
28487
28502
 
28488
28503
  // src/guest/boot/boot-env.ts
28489
28504
  import fs17 from "node:fs";
@@ -29312,6 +29327,7 @@ var MARKERS = {
29312
29327
  ],
29313
29328
  rust: ["Cargo.toml", "rust-toolchain", "rust-toolchain.toml"],
29314
29329
  msvc: ["*.vcxproj", "CMakePresets.json", "CMakeUserPresets.json"],
29330
+ unreal: ["*.uproject", "*.uplugin"],
29315
29331
  cpp: [
29316
29332
  "CMakeLists.txt",
29317
29333
  "Makefile",
@@ -30952,25 +30968,230 @@ async function setupMsvc(env, config2) {
30952
30968
  env.summary.push("msvc: " + done.msvc + ", Windows SDK " + done.sdk + " (cl, link; vcvars64.bat and vswhere work)");
30953
30969
  }
30954
30970
 
30955
- // src/guest/toolchains/native/rust.ts
30971
+ // src/guest/toolchains/native/unreal.ts
30972
+ import fs43 from "node:fs";
30973
+ import os7 from "node:os";
30956
30974
  import path55 from "node:path";
30957
30975
 
30958
- // src/guest/toolchains/native/binstall.ts
30976
+ // src/guest/toolchains/native/vcruntime.ts
30959
30977
  import fs42 from "node:fs";
30960
30978
  import path54 from "node:path";
30979
+ var VC_REDIST = "https://aka.ms/vs/17/release/vc_redist.x64.exe";
30980
+ var MICROSOFT_SIGNER = "CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US";
30981
+ var OK_EXIT_CODES = [0, 1638, 3010];
30982
+ var signerOf = (file3) => scriptOutput("get-signer.ps1", ["-Path", file3]).trim();
30983
+ async function setupVcRuntime(env, summary = true) {
30984
+ if (dryRun) {
30985
+ log("(dry run) would install the Visual C++ runtime");
30986
+ return false;
30987
+ }
30988
+ const system322 = path54.join(process.env.WINDIR ?? "C:\\Windows", "System32");
30989
+ const missing = !exists(path54.join(system322, "vcruntime140.dll")) || !exists(path54.join(system322, "msvcp140.dll"));
30990
+ if (missing) {
30991
+ const installer = tool("vcredist", "vc_redist.x64.exe");
30992
+ if (!exists(installer)) {
30993
+ log("Downloading the Visual C++ runtime (~25 MB once) ...");
30994
+ await downloadFile(VC_REDIST, installer);
30995
+ }
30996
+ if (signerOf(installer) !== MICROSOFT_SIGNER) {
30997
+ fs42.rmSync(installer, { force: true });
30998
+ throw new Error("vc_redist.x64.exe is not signed by Microsoft; deleted it (it is downloaded again next boot)");
30999
+ }
31000
+ log("Installing the Visual C++ runtime ...");
31001
+ const code = await spawnAsync(installer, ["/install", "/quiet", "/norestart"]);
31002
+ if (!OK_EXIT_CODES.includes(code ?? -1) || !exists(path54.join(system322, "vcruntime140.dll")))
31003
+ throw new Error("the Visual C++ runtime installer failed (exit " + code + ")");
31004
+ }
31005
+ if (summary) env.summary.push("vc++ runtime: installed");
31006
+ return missing;
31007
+ }
31008
+
31009
+ // src/guest/toolchains/native/unreal.ts
31010
+ var BOOTSTRAPPER_URL = "https://aka.ms/vs/17/release/vs_community.exe";
31011
+ var DIRECTX_URL = "https://download.microsoft.com/download/8/4/A/84A35BF1-DAFE-4AE8-82AF-AD2AE20B6B14/directx_Jun2010_redist.exe";
31012
+ var UNREAL_COMPONENTS = [
31013
+ "Microsoft.VisualStudio.Workload.NativeGame",
31014
+ "Microsoft.VisualStudio.Component.VC.Tools.x86.x64",
31015
+ "Microsoft.VisualStudio.Component.Windows11SDK.22621",
31016
+ "Microsoft.VisualStudio.Component.VC.DiagnosticTools",
31017
+ "Microsoft.Net.Component.4.6.2.TargetingPack",
31018
+ "Microsoft.Net.Component.4.8.SDK",
31019
+ "Component.Unreal.Ide",
31020
+ "Component.Unreal"
31021
+ ];
31022
+ var OK_EXIT_CODES2 = [0, 3010];
31023
+ var LAYOUT_ROOM_BYTES = 15 * 1024 ** 3;
31024
+ var INSTALL_ROOM_BYTES = 20 * 1024 ** 3;
31025
+ var ID = /^[A-Za-z0-9][A-Za-z0-9._-]{0,199}$/;
31026
+ var VS_DIR = tool("visualstudio");
31027
+ var BOOTSTRAPPER = path55.join(VS_DIR, "vs_community.exe");
31028
+ var LAYOUT = path55.join(VS_DIR, "layout");
31029
+ var LAYOUT_MARKER = path55.join(LAYOUT, ".complete.json");
31030
+ var LayoutSchema = external_exports.object({ components: external_exports.array(external_exports.string()) });
31031
+ var VSWHERE = path55.join(
31032
+ process.env["ProgramFiles(x86)"] ?? "C:\\Program Files (x86)",
31033
+ "Microsoft Visual Studio",
31034
+ "Installer",
31035
+ "vswhere.exe"
31036
+ );
31037
+ function installedVs() {
31038
+ if (!exists(VSWHERE)) return null;
31039
+ const ask = (property) => execOutput(VSWHERE, [
31040
+ "-latest",
31041
+ "-products",
31042
+ "*",
31043
+ "-requires",
31044
+ "Microsoft.VisualStudio.Component.VC.Tools.x86.x64",
31045
+ "-property",
31046
+ property
31047
+ ]);
31048
+ const at = ask("installationPath");
31049
+ return at ? { path: at, version: ask("installationVersion") || "installed" } : null;
31050
+ }
31051
+ async function signedInstaller(url2, file3, what) {
31052
+ if (!exists(file3)) {
31053
+ log("Downloading " + what + " ...");
31054
+ mkdirp(path55.dirname(file3));
31055
+ await downloadFile(url2, file3);
31056
+ }
31057
+ if (signerOf(file3) !== MICROSOFT_SIGNER) {
31058
+ fs43.rmSync(file3, { force: true });
31059
+ throw new Error(path55.basename(file3) + " is not signed by Microsoft; deleted it (it is downloaded again next boot)");
31060
+ }
31061
+ return file3;
31062
+ }
31063
+ function freeBytes(dir) {
31064
+ try {
31065
+ const s = fs43.statfsSync(dir);
31066
+ return s.bavail * s.bsize;
31067
+ } catch {
31068
+ return 0;
31069
+ }
31070
+ }
31071
+ async function layoutInstaller(bootstrapper, ids) {
31072
+ const installer = path55.join(LAYOUT, "vs_community.exe");
31073
+ const has = () => {
31074
+ if (!exists(LAYOUT_MARKER) || !exists(installer)) return false;
31075
+ try {
31076
+ const done = LayoutSchema.parse(JSON.parse(fs43.readFileSync(LAYOUT_MARKER, "utf8")));
31077
+ return ids.every((id) => done.components.includes(id));
31078
+ } catch {
31079
+ return false;
31080
+ }
31081
+ };
31082
+ if (has()) return installer;
31083
+ if (freeBytes(mkdirp(VS_DIR)) < LAYOUT_ROOM_BYTES) {
31084
+ warn("unreal: not keeping the install files (less than 15 GB free in " + VS_DIR + "); downloading this boot");
31085
+ return null;
31086
+ }
31087
+ log("Saving the Visual Studio install files for later boots (~10 GB, once) ...");
31088
+ fs43.rmSync(LAYOUT_MARKER, { force: true });
31089
+ const code = await spawnAsync(bootstrapper, [
31090
+ "--layout",
31091
+ LAYOUT,
31092
+ "--lang",
31093
+ "en-US",
31094
+ "--quiet",
31095
+ "--wait",
31096
+ ...ids.flatMap((id) => ["--add", id])
31097
+ ]);
31098
+ if (!OK_EXIT_CODES2.includes(code) || !exists(installer)) {
31099
+ warn("unreal: saving the install files failed (exit " + code + "); downloading this boot");
31100
+ return null;
31101
+ }
31102
+ writeJsonAtomic(LAYOUT_MARKER, { components: [...ids] });
31103
+ return installer;
31104
+ }
31105
+ async function installVisualStudio(config2, ids) {
31106
+ const bootstrapper = await signedInstaller(BOOTSTRAPPER_URL, BOOTSTRAPPER, "the Visual Studio installer");
31107
+ let installer = null;
31108
+ if (config2.keepInstallFiles) {
31109
+ try {
31110
+ installer = await layoutInstaller(bootstrapper, ids);
31111
+ } catch (e) {
31112
+ warn("unreal: the offline copy failed (" + errMsg(e) + "); downloading this boot");
31113
+ }
31114
+ }
31115
+ log(
31116
+ "Installing Visual Studio Community 2022 with the C++ game workload" + (installer ? " from the saved install files" : " (downloads ~5-8 GB)") + " ..."
31117
+ );
31118
+ const code = await spawnAsync(installer ?? bootstrapper, [
31119
+ "--quiet",
31120
+ "--wait",
31121
+ "--norestart",
31122
+ "--nocache",
31123
+ ...installer ? ["--noWeb"] : [],
31124
+ ...ids.flatMap((id) => ["--add", id])
31125
+ ]);
31126
+ if (!OK_EXIT_CODES2.includes(code) || !installedVs())
31127
+ throw new Error(
31128
+ "the Visual Studio installer failed (exit " + code + "); its logs are the dd_*.log files in " + os7.tmpdir()
31129
+ );
31130
+ }
31131
+ async function installDirectX() {
31132
+ const system322 = path55.join(process.env.WINDIR ?? "C:\\Windows", "System32");
31133
+ if (exists(path55.join(system322, "d3dx9_43.dll")) && exists(path55.join(system322, "XAudio2_7.dll"))) return;
31134
+ const redist = await signedInstaller(
31135
+ DIRECTX_URL,
31136
+ path55.join(VS_DIR, "directx_Jun2010_redist.exe"),
31137
+ "the DirectX End-User Runtime (~95 MB once)"
31138
+ );
31139
+ const unpacked = path55.join(os7.tmpdir(), "directx-redist");
31140
+ safeRemove(unpacked, os7.tmpdir());
31141
+ mkdirp(unpacked);
31142
+ if (await spawnAsync(redist, ["/Q", "/T:" + unpacked]) !== 0 || !exists(path55.join(unpacked, "DXSETUP.exe")))
31143
+ throw new Error("could not unpack the DirectX End-User Runtime");
31144
+ const code = await spawnAsync(path55.join(unpacked, "DXSETUP.exe"), ["/silent"]);
31145
+ safeRemove(unpacked, os7.tmpdir());
31146
+ if (code !== 0) throw new Error("the DirectX End-User Runtime installer failed (exit " + code + ")");
31147
+ }
31148
+ async function setupUnreal(env, config2) {
31149
+ if (!config2.acceptLicense)
31150
+ throw new Error(
31151
+ "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/)"
31152
+ );
31153
+ const bad = config2.components.find((id) => !ID.test(id));
31154
+ if (bad) throw new Error('toolchains.unreal.components: "' + bad + '" is not a Visual Studio component ID');
31155
+ const ids = [.../* @__PURE__ */ new Set([...UNREAL_COMPONENTS, ...config2.components])];
31156
+ if (dryRun) {
31157
+ log("(dry run) would install Visual Studio Community 2022 with " + ids.join(", ") + " and DirectX");
31158
+ return;
31159
+ }
31160
+ if (!installedVs()) {
31161
+ const programFiles = process.env.ProgramFiles ?? "C:\\Program Files";
31162
+ const free = freeBytes(programFiles);
31163
+ if (free < INSTALL_ROOM_BYTES)
31164
+ throw new Error(
31165
+ "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)"
31166
+ );
31167
+ await installVisualStudio(config2, ids);
31168
+ }
31169
+ await installDirectX();
31170
+ const vs = installedVs();
31171
+ env.summary.push(
31172
+ "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)"
31173
+ );
31174
+ }
31175
+
31176
+ // src/guest/toolchains/native/rust.ts
31177
+ import path57 from "node:path";
31178
+
31179
+ // src/guest/toolchains/native/binstall.ts
31180
+ import fs44 from "node:fs";
31181
+ import path56 from "node:path";
30961
31182
  var ensureBinstall = async (cargoBin) => {
30962
- const target = path54.join(cargoBin, "cargo-binstall.exe");
31183
+ const target = path56.join(cargoBin, "cargo-binstall.exe");
30963
31184
  if (exists(target)) return true;
30964
31185
  try {
30965
31186
  const dir = tool("cargo-binstall");
30966
- if (!exists(path54.join(dir, "cargo-binstall.exe"))) {
31187
+ if (!exists(path56.join(dir, "cargo-binstall.exe"))) {
30967
31188
  await installFromGithub("cargo-bins/cargo-binstall", binstallAsset(arch), {
30968
31189
  dest: dir,
30969
31190
  what: "cargo-binstall for prebuilt Rust tools (~10 MB once)",
30970
31191
  locate: "cargo-binstall.exe"
30971
31192
  });
30972
31193
  }
30973
- fs42.copyFileSync(path54.join(dir, "cargo-binstall.exe"), target);
31194
+ fs44.copyFileSync(path56.join(dir, "cargo-binstall.exe"), target);
30974
31195
  return true;
30975
31196
  } catch (e) {
30976
31197
  warn("cargo-binstall unavailable, compiling crates with cargo install instead: " + errMsg(e));
@@ -30978,14 +31199,14 @@ var ensureBinstall = async (cargoBin) => {
30978
31199
  }
30979
31200
  };
30980
31201
  function crateInstaller(cargoHome, cargoEnv) {
30981
- const cargo = path54.join(cargoHome, "bin", "cargo.exe");
31202
+ const cargo = path56.join(cargoHome, "bin", "cargo.exe");
30982
31203
  let binstall = null;
30983
31204
  const binstallEnv = {
30984
31205
  ...cargoEnv,
30985
31206
  env: { ...cargoEnv.env ?? process.env, BINSTALL_DISABLE_TELEMETRY: "true" }
30986
31207
  };
30987
31208
  return async (crate) => {
30988
- binstall ??= ensureBinstall(path54.join(cargoHome, "bin"));
31209
+ binstall ??= ensureBinstall(path56.join(cargoHome, "bin"));
30989
31210
  if (await binstall) {
30990
31211
  try {
30991
31212
  await execAsync(
@@ -31007,7 +31228,7 @@ async function setupRust(env, config2, refresh) {
31007
31228
  const RUSTUP_HOME = tool("rust", "rustup");
31008
31229
  const CARGO_HOME = tool("rust", "cargo");
31009
31230
  const rustEnv = { env: { ...process.env, RUSTUP_HOME, CARGO_HOME } };
31010
- const rustup = path55.join(CARGO_HOME, "bin", "rustup.exe");
31231
+ const rustup = path57.join(CARGO_HOME, "bin", "rustup.exe");
31011
31232
  if (dryRun) {
31012
31233
  log("(dry run) would provision Rust " + config2.toolchain + " (" + config2.host + ")");
31013
31234
  return;
@@ -31043,9 +31264,9 @@ async function setupRust(env, config2, refresh) {
31043
31264
  if (refresh) await execAsync(rustup, ["update"], rustEnv);
31044
31265
  }
31045
31266
  Object.assign(env.vars, { RUSTUP_HOME, CARGO_HOME });
31046
- env.prepend.push(path55.join(CARGO_HOME, "bin"));
31267
+ env.prepend.push(path57.join(CARGO_HOME, "bin"));
31047
31268
  env.summary.push(
31048
- "rust: " + versionOf(path55.join(CARGO_HOME, "bin", "rustc.exe"), ["--version"], rustEnv) + " [" + config2.host + "]"
31269
+ "rust: " + versionOf(path57.join(CARGO_HOME, "bin", "rustc.exe"), ["--version"], rustEnv) + " [" + config2.host + "]"
31049
31270
  );
31050
31271
  const toolchainKey = "rustup@" + config2.toolchain;
31051
31272
  await installOnce(
@@ -31066,36 +31287,36 @@ async function setupRust(env, config2, refresh) {
31066
31287
  env: {
31067
31288
  ...rustEnv.env,
31068
31289
  ...msvc.vars,
31069
- PATH: [path55.join(CARGO_HOME, "bin"), ...msvc.path, process.env.PATH ?? ""].join(path55.delimiter)
31290
+ PATH: [path57.join(CARGO_HOME, "bin"), ...msvc.path, process.env.PATH ?? ""].join(path57.delimiter)
31070
31291
  }
31071
31292
  } : {
31072
31293
  env: {
31073
31294
  ...rustEnv.env,
31074
- CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER: path55.join(mingw, "gcc.exe"),
31075
- PATH: [path55.join(CARGO_HOME, "bin"), mingw, process.env.PATH ?? ""].join(path55.delimiter)
31295
+ CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER: path57.join(mingw, "gcc.exe"),
31296
+ PATH: [path57.join(CARGO_HOME, "bin"), mingw, process.env.PATH ?? ""].join(path57.delimiter)
31076
31297
  }
31077
31298
  };
31078
31299
  await installOnce(env, "cargo", config2.crates, crateInstaller(CARGO_HOME, cargoEnv));
31079
31300
  }
31080
31301
 
31081
31302
  // src/guest/toolchains/languages/node.ts
31082
- import fs43 from "node:fs";
31083
- import path56 from "node:path";
31303
+ import fs45 from "node:fs";
31304
+ import path58 from "node:path";
31084
31305
  import { spawn as spawn4 } from "node:child_process";
31085
31306
  var NVM_HOME = tool("nvm");
31086
- var NVM_SYMLINK = path56.join(localDir, "nodejs");
31087
- var HOST_NVM = path56.join(hostToolsDir, "nvm");
31307
+ var NVM_SYMLINK = path58.join(localDir, "nodejs");
31308
+ var HOST_NVM = path58.join(hostToolsDir, "nvm");
31088
31309
  var HOST_VERSIONS_MAX = 3;
31089
- var hostNvmVersions = () => exists(HOST_NVM) ? fs43.readdirSync(HOST_NVM).filter((d) => /^v\d+\.\d+\.\d+$/.test(d) && exists(path56.join(HOST_NVM, d, "node.exe"))).map((d) => d.slice(1)) : [];
31310
+ var hostNvmVersions = () => exists(HOST_NVM) ? fs45.readdirSync(HOST_NVM).filter((d) => /^v\d+\.\d+\.\d+$/.test(d) && exists(path58.join(HOST_NVM, d, "node.exe"))).map((d) => d.slice(1)) : [];
31090
31311
  var resolveNode = (spec) => resolveCached("node:" + spec, async () => {
31091
31312
  const exact = spec.replace(/^v/, "");
31092
31313
  if (/^\d+\.\d+\.\d+$/.test(exact)) return exact;
31093
31314
  const releases = await fetchJson("https://nodejs.org/dist/index.json");
31094
31315
  return pickNodeVersion(releases, spec) ?? Promise.reject(new Error('No Node.js release matches "' + spec + '"'));
31095
31316
  });
31096
- var NVM_TEMP = path56.join(NVM_HOME, ".tmp");
31317
+ var NVM_TEMP = path58.join(NVM_HOME, ".tmp");
31097
31318
  var nvm = (args) => new Promise((resolve2) => {
31098
- const child = spawn4(path56.join(NVM_HOME, "nvm.exe"), args, {
31319
+ const child = spawn4(path58.join(NVM_HOME, "nvm.exe"), args, {
31099
31320
  windowsHide: true,
31100
31321
  env: { ...process.env, NVM_HOME, NVM_SYMLINK, TEMP: NVM_TEMP, TMP: NVM_TEMP }
31101
31322
  });
@@ -31110,12 +31331,12 @@ var nvm = (args) => new Promise((resolve2) => {
31110
31331
  child.once("close", () => resolve2(out));
31111
31332
  });
31112
31333
  var ensureNvm = async () => {
31113
- if (exists(path56.join(NVM_HOME, "nvm.exe"))) return;
31114
- if (exists(path56.join(HOST_NVM, "nvm.exe"))) {
31334
+ if (exists(path58.join(NVM_HOME, "nvm.exe"))) return;
31335
+ if (exists(path58.join(HOST_NVM, "nvm.exe"))) {
31115
31336
  log("Copying nvm from this PC ...");
31116
31337
  mkdirp(NVM_HOME);
31117
- const files = fs43.readdirSync(HOST_NVM).filter((f) => /\.(exe|cmd|vbs)$/i.test(f)).sort((a, b) => Number(a.toLowerCase() === "nvm.exe") - Number(b.toLowerCase() === "nvm.exe"));
31118
- for (const file3 of files) fs43.copyFileSync(path56.join(HOST_NVM, file3), path56.join(NVM_HOME, file3));
31338
+ const files = fs45.readdirSync(HOST_NVM).filter((f) => /\.(exe|cmd|vbs)$/i.test(f)).sort((a, b) => Number(a.toLowerCase() === "nvm.exe") - Number(b.toLowerCase() === "nvm.exe"));
31339
+ for (const file3 of files) fs45.copyFileSync(path58.join(HOST_NVM, file3), path58.join(NVM_HOME, file3));
31119
31340
  return;
31120
31341
  }
31121
31342
  const asset = await githubAsset("coreybutler/nvm-windows", /^nvm-noinstall\.zip$/, true);
@@ -31123,14 +31344,14 @@ var ensureNvm = async () => {
31123
31344
  await downloader.archive(asset.url, NVM_HOME, { sha256: asset.sha256, locate: "nvm.exe", fileName: asset.name });
31124
31345
  };
31125
31346
  var hostNodeFolder = (version2) => {
31126
- const dir = path56.join(hostToolsDir, "node");
31127
- return session.hostTools.nodeVersion?.replace(/^v/, "") === version2 && exists(path56.join(dir, "node.exe")) ? dir : null;
31347
+ const dir = path58.join(hostToolsDir, "node");
31348
+ return session.hostTools.nodeVersion?.replace(/^v/, "") === version2 && exists(path58.join(dir, "node.exe")) ? dir : null;
31128
31349
  };
31129
31350
  var installNodeVersion = async (version2) => {
31130
- const dir = path56.join(NVM_HOME, "v" + version2);
31131
- const fromHost = path56.join(HOST_NVM, "v" + version2);
31132
- if (exists(path56.join(dir, "node.exe"))) return;
31133
- if (exists(path56.join(fromHost, "node.exe"))) {
31351
+ const dir = path58.join(NVM_HOME, "v" + version2);
31352
+ const fromHost = path58.join(HOST_NVM, "v" + version2);
31353
+ if (exists(path58.join(dir, "node.exe"))) return;
31354
+ if (exists(path58.join(fromHost, "node.exe"))) {
31134
31355
  log("Copying Node " + version2 + " from this PC's nvm (without global packages) ...");
31135
31356
  copyNode(fromHost, dir);
31136
31357
  return;
@@ -31149,19 +31370,19 @@ var installNodeVersion = async (version2) => {
31149
31370
  } finally {
31150
31371
  safeRemove(NVM_TEMP, NVM_HOME);
31151
31372
  }
31152
- if (!exists(path56.join(dir, "node.exe"))) {
31373
+ if (!exists(path58.join(dir, "node.exe"))) {
31153
31374
  const tail = out.trim().split(/\r?\n/).filter(Boolean).slice(-3).join(" ");
31154
31375
  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";
31155
31376
  throw new Error(
31156
- "nvm install " + version2 + " did not leave " + path56.join(dir, "node.exe") + " (" + why + ")" + (tail ? ". nvm printed: " + tail : "")
31377
+ "nvm install " + version2 + " did not leave " + path58.join(dir, "node.exe") + " (" + why + ")" + (tail ? ". nvm printed: " + tail : "")
31157
31378
  );
31158
31379
  }
31159
31380
  };
31160
31381
  var activate = async (version2) => {
31161
31382
  await nvm(["use", version2]);
31162
- if (exists(path56.join(NVM_SYMLINK, "node.exe"))) return;
31163
- fs43.rmSync(NVM_SYMLINK, { recursive: true, force: true });
31164
- fs43.symlinkSync(path56.join(NVM_HOME, "v" + version2), NVM_SYMLINK, "junction");
31383
+ if (exists(path58.join(NVM_SYMLINK, "node.exe"))) return;
31384
+ fs45.rmSync(NVM_SYMLINK, { recursive: true, force: true });
31385
+ fs45.symlinkSync(path58.join(NVM_HOME, "v" + version2), NVM_SYMLINK, "junction");
31165
31386
  };
31166
31387
  var PLAYWRIGHT_VARS = () => ({
31167
31388
  PLAYWRIGHT_BROWSERS_PATH: tool("ms-playwright"),
@@ -31173,8 +31394,8 @@ async function setupNode(env, versions, config2) {
31173
31394
  return;
31174
31395
  }
31175
31396
  await ensureNvm();
31176
- fs43.writeFileSync(
31177
- path56.join(NVM_HOME, "settings.txt"),
31397
+ fs45.writeFileSync(
31398
+ path58.join(NVM_HOME, "settings.txt"),
31178
31399
  [
31179
31400
  "root: " + NVM_HOME,
31180
31401
  "path: " + NVM_SYMLINK,
@@ -31201,7 +31422,7 @@ async function setupNode(env, versions, config2) {
31201
31422
  }
31202
31423
  }
31203
31424
  Object.assign(env.vars, { NVM_HOME, NVM_SYMLINK, ...PLAYWRIGHT_VARS() });
31204
- if (duringSession()) env.prepend.push(path56.join(NVM_HOME, "v" + main), NVM_HOME, NVM_SYMLINK);
31425
+ if (duringSession()) env.prepend.push(path58.join(NVM_HOME, "v" + main), NVM_HOME, NVM_SYMLINK);
31205
31426
  else {
31206
31427
  await activate(main);
31207
31428
  env.prepend.push(NVM_HOME, NVM_SYMLINK);
@@ -31211,13 +31432,13 @@ async function setupNode(env, versions, config2) {
31211
31432
  await packageManagers(env, config2, main);
31212
31433
  }
31213
31434
  var packageManagers = async (env, config2, version2) => {
31214
- const dir = path56.join(NVM_HOME, "v" + version2);
31215
- const nodeEnv = { ...process.env, PATH: dir + path56.delimiter + (process.env.PATH ?? "") };
31216
- const npm = (args) => execAsync(path56.join(dir, "node.exe"), [path56.join(dir, "node_modules", "npm", "bin", "npm-cli.js"), ...args], {
31435
+ const dir = path58.join(NVM_HOME, "v" + version2);
31436
+ const nodeEnv = { ...process.env, PATH: dir + path58.delimiter + (process.env.PATH ?? "") };
31437
+ const npm = (args) => execAsync(path58.join(dir, "node.exe"), [path58.join(dir, "node_modules", "npm", "bin", "npm-cli.js"), ...args], {
31217
31438
  env: nodeEnv,
31218
31439
  stdio: "ignore"
31219
31440
  });
31220
- const corepackJs = path56.join(dir, "node_modules", "corepack", "dist", "corepack.js");
31441
+ const corepackJs = path58.join(dir, "node_modules", "corepack", "dist", "corepack.js");
31221
31442
  const extra = config2.corepack && !exists(corepackJs) ? ["corepack"] : [];
31222
31443
  await installOnce(
31223
31444
  env,
@@ -31238,7 +31459,7 @@ var packageManagers = async (env, config2, version2) => {
31238
31459
  }
31239
31460
  try {
31240
31461
  await execAsync(
31241
- path56.join(dir, "node.exe"),
31462
+ path58.join(dir, "node.exe"),
31242
31463
  [corepackJs, "enable", "--install-directory", mkdirp(tool("bin")), "pnpm", "yarn"],
31243
31464
  { env: nodeEnv, stdio: "ignore" }
31244
31465
  );
@@ -31263,8 +31484,8 @@ async function setupPwsh(env, refresh = false) {
31263
31484
  }
31264
31485
 
31265
31486
  // src/guest/toolchains/languages/python.ts
31266
- import fs44 from "node:fs";
31267
- import path57 from "node:path";
31487
+ import fs46 from "node:fs";
31488
+ import path59 from "node:path";
31268
31489
  var installPython = async (pkg, spec) => {
31269
31490
  const version2 = await resolveCached(pkg + ":" + spec, async () => {
31270
31491
  const { versions } = await fetchJson(
@@ -31273,7 +31494,7 @@ var installPython = async (pkg, spec) => {
31273
31494
  return pickPackageVersion(versions, spec) ?? Promise.reject(new Error("No " + pkg + ' release matches "' + spec + '"'));
31274
31495
  });
31275
31496
  const dir = tool("python", pkg + "-" + version2);
31276
- const exe = path57.join(dir, "python.exe");
31497
+ const exe = path59.join(dir, "python.exe");
31277
31498
  if (!exists(exe)) {
31278
31499
  log("Downloading Python " + version2 + (pkg === "python2" ? " (Python 2, " : " (") + "~30 MB once) ...");
31279
31500
  await downloader.archive(
@@ -31282,32 +31503,32 @@ var installPython = async (pkg, spec) => {
31282
31503
  { locate: "python.exe", fileName: pkg + "." + version2 + ".zip" }
31283
31504
  );
31284
31505
  }
31285
- if (!exists(path57.join(dir, "Scripts", "pip.exe")) && !exists(path57.join(dir, "Scripts", "pip2.exe")))
31506
+ if (!exists(path59.join(dir, "Scripts", "pip.exe")) && !exists(path59.join(dir, "Scripts", "pip2.exe")))
31286
31507
  await execAsync(exe, ["-m", "ensurepip", "--default-pip"], { stdio: "ignore" });
31287
31508
  return dir;
31288
31509
  };
31289
- var shimDir = (dir) => duringSession() ? tool("shims", path57.basename(dir)) : tool("shims");
31510
+ var shimDir = (dir) => duringSession() ? tool("shims", path59.basename(dir)) : tool("shims");
31290
31511
  var shim = (folder, name, program, args = []) => {
31291
31512
  const fixed = [program, ...args];
31292
- fs44.writeFileSync(
31293
- path57.join(mkdirp(folder), name + ".cmd"),
31513
+ fs46.writeFileSync(
31514
+ path59.join(mkdirp(folder), name + ".cmd"),
31294
31515
  "@echo off\r\n" + fixed.map((a) => '"' + a + '"').join(" ") + " %*\r\n"
31295
31516
  );
31296
31517
  const sh = fixed.map((a) => "'" + a.replace(/\\/g, "/").replace(/'/g, "'\\''") + "'").join(" ");
31297
- fs44.writeFileSync(path57.join(folder, name), "#!/bin/sh\nexec " + sh + ' "$@"\n');
31518
+ fs46.writeFileSync(path59.join(folder, name), "#!/bin/sh\nexec " + sh + ' "$@"\n');
31298
31519
  };
31299
31520
  var shimPair = (folder, version2, dir) => {
31300
- const python = path57.join(dir, "python.exe");
31521
+ const python = path59.join(dir, "python.exe");
31301
31522
  shim(folder, "python" + version2, python);
31302
31523
  shim(folder, "pip" + version2, python, ["-m", "pip"]);
31303
31524
  };
31304
31525
  var pyLauncher = (folder, py3, py2) => {
31305
- const script = path57.join(mkdirp(folder), "py-launcher.py");
31306
- fs44.writeFileSync(
31526
+ const script = path59.join(mkdirp(folder), "py-launcher.py");
31527
+ fs46.writeFileSync(
31307
31528
  script,
31308
31529
  [
31309
31530
  "import subprocess, sys",
31310
- "PY3, PY2 = " + JSON.stringify(path57.join(py3, "python.exe")) + ", " + JSON.stringify(py2 ? path57.join(py2, "python.exe") : null),
31531
+ "PY3, PY2 = " + JSON.stringify(path59.join(py3, "python.exe")) + ", " + JSON.stringify(py2 ? path59.join(py2, "python.exe") : null),
31311
31532
  "args = sys.argv[1:]",
31312
31533
  "exe = PY3",
31313
31534
  "if args and args[0].startswith('-2'):",
@@ -31319,7 +31540,7 @@ var pyLauncher = (folder, py3, py2) => {
31319
31540
  ""
31320
31541
  ].join("\n")
31321
31542
  );
31322
- shim(folder, "py", path57.join(py3, "python.exe"), [script]);
31543
+ shim(folder, "py", path59.join(py3, "python.exe"), [script]);
31323
31544
  };
31324
31545
  async function setupPython(env, config2, versions) {
31325
31546
  if (dryRun) {
@@ -31329,10 +31550,10 @@ async function setupPython(env, config2, versions) {
31329
31550
  const py3 = await installPython("python", versions.python.spec);
31330
31551
  const shims = shimDir(py3);
31331
31552
  shimPair(shims, "3", py3);
31332
- env.prepend.push(py3, mkdirp(path57.join(py3, "Scripts")), shims);
31553
+ env.prepend.push(py3, mkdirp(path59.join(py3, "Scripts")), shims);
31333
31554
  env.vars.PYTHONIOENCODING = "utf-8";
31334
31555
  env.summary.push(
31335
- "python: " + path57.basename(py3).replace("python-", "") + " (from " + versions.python.source + "; py works too)"
31556
+ "python: " + path59.basename(py3).replace("python-", "") + " (from " + versions.python.source + "; py works too)"
31336
31557
  );
31337
31558
  if (!config2.python2) {
31338
31559
  pyLauncher(shims, py3, null);
@@ -31341,47 +31562,12 @@ async function setupPython(env, config2, versions) {
31341
31562
  const py2 = await installPython("python2", "2.7");
31342
31563
  shimPair(shims, "2", py2);
31343
31564
  pyLauncher(shims, py3, py2);
31344
- env.summary.push("python2: " + path57.basename(py2).replace("python2-", ""));
31345
- }
31346
-
31347
- // src/guest/toolchains/languages/php.ts
31348
- import fs46 from "node:fs";
31349
- import path59 from "node:path";
31350
-
31351
- // src/guest/toolchains/native/vcruntime.ts
31352
- import fs45 from "node:fs";
31353
- import path58 from "node:path";
31354
- var VC_REDIST = "https://aka.ms/vs/17/release/vc_redist.x64.exe";
31355
- var MICROSOFT_SIGNER = "CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US";
31356
- var OK_EXIT_CODES = [0, 1638, 3010];
31357
- var signerOf = (file3) => scriptOutput("get-signer.ps1", ["-Path", file3]).trim();
31358
- async function setupVcRuntime(env, summary = true) {
31359
- if (dryRun) {
31360
- log("(dry run) would install the Visual C++ runtime");
31361
- return false;
31362
- }
31363
- const system322 = path58.join(process.env.WINDIR ?? "C:\\Windows", "System32");
31364
- const missing = !exists(path58.join(system322, "vcruntime140.dll")) || !exists(path58.join(system322, "msvcp140.dll"));
31365
- if (missing) {
31366
- const installer = tool("vcredist", "vc_redist.x64.exe");
31367
- if (!exists(installer)) {
31368
- log("Downloading the Visual C++ runtime (~25 MB once) ...");
31369
- await downloadFile(VC_REDIST, installer);
31370
- }
31371
- if (signerOf(installer) !== MICROSOFT_SIGNER) {
31372
- fs45.rmSync(installer, { force: true });
31373
- throw new Error("vc_redist.x64.exe is not signed by Microsoft; deleted it (it is downloaded again next boot)");
31374
- }
31375
- log("Installing the Visual C++ runtime ...");
31376
- const code = await spawnAsync(installer, ["/install", "/quiet", "/norestart"]);
31377
- if (!OK_EXIT_CODES.includes(code ?? -1) || !exists(path58.join(system322, "vcruntime140.dll")))
31378
- throw new Error("the Visual C++ runtime installer failed (exit " + code + ")");
31379
- }
31380
- if (summary) env.summary.push("vc++ runtime: installed");
31381
- return missing;
31565
+ env.summary.push("python2: " + path59.basename(py2).replace("python2-", ""));
31382
31566
  }
31383
31567
 
31384
31568
  // src/guest/toolchains/languages/php.ts
31569
+ import fs47 from "node:fs";
31570
+ import path60 from "node:path";
31385
31571
  var PHP_EXTENSIONS = [
31386
31572
  "curl",
31387
31573
  "fileinfo",
@@ -31412,16 +31598,16 @@ var phpBuild = async (spec) => {
31412
31598
  return { version: release.version, ...build.zip };
31413
31599
  };
31414
31600
  var writePhpIni = (home) => {
31415
- const ini = path59.join(home, "php.ini");
31416
- if (exists(ini) || !exists(path59.join(home, "php.ini-development"))) return;
31417
- let text = fs46.readFileSync(path59.join(home, "php.ini-development"), "utf8").replace(/^;\s*extension_dir\s*=\s*"ext"/m, 'extension_dir = "' + path59.join(home, "ext") + '"');
31418
- for (const ext of PHP_EXTENSIONS.filter((e) => exists(path59.join(home, "ext", "php_" + e + ".dll"))))
31601
+ const ini = path60.join(home, "php.ini");
31602
+ if (exists(ini) || !exists(path60.join(home, "php.ini-development"))) return;
31603
+ let text = fs47.readFileSync(path60.join(home, "php.ini-development"), "utf8").replace(/^;\s*extension_dir\s*=\s*"ext"/m, 'extension_dir = "' + path60.join(home, "ext") + '"');
31604
+ for (const ext of PHP_EXTENSIONS.filter((e) => exists(path60.join(home, "ext", "php_" + e + ".dll"))))
31419
31605
  text = text.replace(new RegExp("^;(extension=" + ext + ")\\s*$", "m"), "$1");
31420
- fs46.writeFileSync(ini + ".tmp", text);
31421
- fs46.renameSync(ini + ".tmp", ini);
31606
+ fs47.writeFileSync(ini + ".tmp", text);
31607
+ fs47.renameSync(ini + ".tmp", ini);
31422
31608
  };
31423
31609
  var shim2 = (env, name, command) => {
31424
- fs46.writeFileSync(path59.join(mkdirp(tool("shims")), name + ".cmd"), "@echo off\r\n" + command + " %*\r\n");
31610
+ fs47.writeFileSync(path60.join(mkdirp(tool("shims")), name + ".cmd"), "@echo off\r\n" + command + " %*\r\n");
31425
31611
  env.prepend.push(tool("shims"));
31426
31612
  };
31427
31613
  var setupComposer = async (env, php) => {
@@ -31433,7 +31619,7 @@ var setupComposer = async (env, php) => {
31433
31619
  }
31434
31620
  const composerHome = tool("composer-home");
31435
31621
  env.vars.COMPOSER_HOME = composerHome;
31436
- env.prepend.push(path59.join(composerHome, "vendor", "bin"));
31622
+ env.prepend.push(path60.join(composerHome, "vendor", "bin"));
31437
31623
  shim2(env, "composer", '"' + php + '" "' + phar + '"');
31438
31624
  env.summary.push(
31439
31625
  "composer: " + (/\d+\.\d+\.\d+/.exec(execOutput(php, [phar, "--version", "--no-ansi"]))?.[0] ?? "installed")
@@ -31448,7 +31634,7 @@ async function setupPhp(env, config2) {
31448
31634
  await setupVcRuntime(env, false);
31449
31635
  const version2 = await resolveCached("php:" + wantedSpec.spec, async () => (await phpBuild(wantedSpec.spec)).version);
31450
31636
  const home = tool("php", version2);
31451
- if (!exists(path59.join(home, "php.exe"))) {
31637
+ if (!exists(path60.join(home, "php.exe"))) {
31452
31638
  const build = await phpBuild(version2);
31453
31639
  log("Downloading PHP " + version2 + " (~30 MB once) ...");
31454
31640
  await downloader.archive("https://windows.php.net/downloads/releases/" + build.path, home, {
@@ -31460,11 +31646,11 @@ async function setupPhp(env, config2) {
31460
31646
  writePhpIni(home);
31461
31647
  env.prepend.push(home);
31462
31648
  env.summary.push("php: " + version2 + " (from " + wantedSpec.source + ")");
31463
- if (config2.composer) await setupComposer(env, path59.join(home, "php.exe"));
31649
+ if (config2.composer) await setupComposer(env, path60.join(home, "php.exe"));
31464
31650
  }
31465
31651
 
31466
31652
  // src/guest/toolchains/languages/ruby.ts
31467
- import path60 from "node:path";
31653
+ import path61 from "node:path";
31468
31654
  var RUBY_ASSET = /^rubyinstaller-(\d+\.\d+\.\d+)-(\d+)-x64\.7z$/;
31469
31655
  var buildNumber = (asset) => Number(RUBY_ASSET.exec(asset.name)?.[2] ?? 0);
31470
31656
  var rubyBuilds = async () => {
@@ -31492,7 +31678,7 @@ async function setupRuby(env, config2) {
31492
31678
  async () => pickPackageVersion([...(await rubyBuilds()).keys()], wantedSpec.spec) ?? Promise.reject(new Error('No RubyInstaller build matches "' + wantedSpec.spec + '"'))
31493
31679
  );
31494
31680
  const home = tool("ruby", version2);
31495
- if (!exists(path60.join(home, "bin", "ruby.exe"))) {
31681
+ if (!exists(path61.join(home, "bin", "ruby.exe"))) {
31496
31682
  const asset = (await rubyBuilds()).get(version2);
31497
31683
  if (!asset) throw new Error("RubyInstaller " + version2 + " is no longer published");
31498
31684
  log("Downloading Ruby " + version2 + " (~100 MB once) ...");
@@ -31505,11 +31691,11 @@ async function setupRuby(env, config2) {
31505
31691
  }
31506
31692
  const gems = tool("ruby-gems", version2.split(".").slice(0, 2).join("."));
31507
31693
  Object.assign(env.vars, { GEM_HOME: gems, BUNDLE_USER_HOME: tool("bundle-home") });
31508
- env.prepend.push(path60.join(home, "bin"), path60.join(gems, "bin"));
31694
+ env.prepend.push(path61.join(home, "bin"), path61.join(gems, "bin"));
31509
31695
  env.summary.push(
31510
- "ruby: " + versionOf(path60.join(home, "bin", "ruby.exe")) + " (from " + wantedSpec.source + "; gems with C extensions need MSYS2, not included)"
31696
+ "ruby: " + versionOf(path61.join(home, "bin", "ruby.exe")) + " (from " + wantedSpec.source + "; gems with C extensions need MSYS2, not included)"
31511
31697
  );
31512
- const gem = path60.join(home, "bin", "gem.cmd");
31698
+ const gem = path61.join(home, "bin", "gem.cmd");
31513
31699
  await installOnce(
31514
31700
  env,
31515
31701
  "gem@" + version2,
@@ -31521,9 +31707,9 @@ async function setupRuby(env, config2) {
31521
31707
  }
31522
31708
 
31523
31709
  // src/guest/toolchains/tools/vscode.ts
31524
- import fs47 from "node:fs";
31525
- import os7 from "node:os";
31526
- import path61 from "node:path";
31710
+ import fs48 from "node:fs";
31711
+ import os8 from "node:os";
31712
+ import path62 from "node:path";
31527
31713
 
31528
31714
  // node_modules/jsonc-parser/lib/esm/impl/scanner.js
31529
31715
  var CharacterCodes;
@@ -31703,14 +31889,14 @@ var ParseErrorCode;
31703
31889
  var VERSION_MARKER = ".agent-sandbox-version";
31704
31890
  var desktopShortcut = (exe) => {
31705
31891
  if (!isWin) return;
31706
- const link = path61.join(os7.homedir(), "Desktop", "Visual Studio Code.lnk");
31892
+ const link = path62.join(os8.homedir(), "Desktop", "Visual Studio Code.lnk");
31707
31893
  runScriptWithJson("new-shortcuts.ps1", "ListFile", [
31708
31894
  { link, target: exe, arguments: '"' + (process.env.AGENT_WORKSPACE ?? "") + '"' }
31709
31895
  ]);
31710
31896
  };
31711
31897
  async function setupVscode(env, refresh) {
31712
31898
  const root = tool("vscode");
31713
- const exe = path61.join(root, "Code.exe");
31899
+ const exe = path62.join(root, "Code.exe");
31714
31900
  if (dryRun) {
31715
31901
  log("(dry run) would provision VS Code");
31716
31902
  return;
@@ -31720,11 +31906,11 @@ async function setupVscode(env, refresh) {
31720
31906
  "https://update.code.visualstudio.com/api/update/win32-" + (arch === "arm64" ? "arm64" : "x64") + "-archive/stable/latest"
31721
31907
  );
31722
31908
  log("Downloading VS Code " + release.productVersion + " (~150 MB once) ...");
31723
- const keep = path61.join(root, "data");
31909
+ const keep = path62.join(root, "data");
31724
31910
  const parked = root + "-data";
31725
31911
  if (exists(keep)) {
31726
- fs47.rmSync(parked, { recursive: true, force: true });
31727
- fs47.renameSync(keep, parked);
31912
+ fs48.rmSync(parked, { recursive: true, force: true });
31913
+ fs48.renameSync(keep, parked);
31728
31914
  }
31729
31915
  try {
31730
31916
  await downloader.archive(release.url, root, {
@@ -31732,26 +31918,26 @@ async function setupVscode(env, refresh) {
31732
31918
  locate: "Code.exe",
31733
31919
  fileName: "vscode.zip"
31734
31920
  });
31735
- fs47.writeFileSync(path61.join(root, VERSION_MARKER), release.productVersion);
31921
+ fs48.writeFileSync(path62.join(root, VERSION_MARKER), release.productVersion);
31736
31922
  } finally {
31737
31923
  if (exists(parked)) {
31738
31924
  mkdirp(root);
31739
- fs47.rmSync(keep, { recursive: true, force: true });
31740
- fs47.renameSync(parked, keep);
31925
+ fs48.rmSync(keep, { recursive: true, force: true });
31926
+ fs48.renameSync(parked, keep);
31741
31927
  }
31742
31928
  }
31743
31929
  }
31744
- mkdirp(path61.join(root, "data"));
31745
- env.prepend.push(path61.join(root, "bin"));
31930
+ mkdirp(path62.join(root, "data"));
31931
+ env.prepend.push(path62.join(root, "bin"));
31746
31932
  desktopShortcut(exe);
31747
- const version2 = exists(path61.join(root, VERSION_MARKER)) ? fs47.readFileSync(path61.join(root, VERSION_MARKER), "utf8").trim() : "installed";
31933
+ const version2 = exists(path62.join(root, VERSION_MARKER)) ? fs48.readFileSync(path62.join(root, VERSION_MARKER), "utf8").trim() : "installed";
31748
31934
  env.summary.push("vscode: " + version2 + " (portable; run code . or use the desktop shortcut)");
31749
31935
  }
31750
31936
 
31751
31937
  // src/guest/toolchains/native/rust-extras.ts
31752
- import fs48 from "node:fs";
31753
- import os8 from "node:os";
31754
- import path62 from "node:path";
31938
+ import fs49 from "node:fs";
31939
+ import os9 from "node:os";
31940
+ import path63 from "node:path";
31755
31941
 
31756
31942
  // src/shared/memory/policy.ts
31757
31943
  var DIAL_STEPS = {
@@ -31800,41 +31986,41 @@ function maxCompilers(cpus, profile) {
31800
31986
  // src/guest/toolchains/native/rust-extras.ts
31801
31987
  var cargoTarget = (targetDir) => {
31802
31988
  if (targetDir === "shared" || targetDir === "separate") return null;
31803
- if (targetDir === "local") return path62.join(localDir, "cargo-target");
31989
+ if (targetDir === "local") return path63.join(localDir, "cargo-target");
31804
31990
  return targetDir;
31805
31991
  };
31806
31992
  function cargoShim(env, rust) {
31807
- const real = path62.join(tool("rust", "cargo", "bin"), "cargo.exe");
31993
+ const real = path63.join(tool("rust", "cargo", "bin"), "cargo.exe");
31808
31994
  if (rust.targetDir !== "separate" || !exists(real)) return;
31809
31995
  const dir = mkdirp(tool("shims", "cargo"));
31810
- fs48.copyFileSync(ensureCompiled("cargoshim"), path62.join(dir, "cargo.exe"));
31996
+ fs49.copyFileSync(ensureCompiled("cargoshim"), path63.join(dir, "cargo.exe"));
31811
31997
  env.prepend.unshift(dir);
31812
31998
  env.vars.AGENT_REAL_CARGO = real;
31813
31999
  }
31814
32000
  function linkGate(env, rust, host) {
31815
32001
  const gcc = tool("mingw", "mingw64", "bin", "gcc.exe");
31816
32002
  if (!host.endsWith("-pc-windows-gnu") || !exists(gcc)) return;
31817
- const gate = path62.join(mkdirp(tool("shims")), "linkgate.exe");
31818
- fs48.copyFileSync(ensureCompiled("linkgate"), gate);
31819
- const memoryGb = os8.totalmem() / 1024 ** 3;
32003
+ const gate = path63.join(mkdirp(tool("shims")), "linkgate.exe");
32004
+ fs49.copyFileSync(ensureCompiled("linkgate"), gate);
32005
+ const memoryGb = os9.totalmem() / 1024 ** 3;
31820
32006
  const slots = rust.linkSlots === "auto" ? linkSlotsFor(memoryGb) : rust.linkSlots;
31821
32007
  env.vars.AGENT_LINK_SLOTS = String(slots);
31822
32008
  env.vars.AGENT_REAL_LINKER = gcc;
31823
32009
  env.vars.CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER = gate;
31824
32010
  const rustEnv = { ...process.env, RUSTUP_HOME: tool("rust", "rustup"), CARGO_HOME: tool("rust", "cargo") };
31825
32011
  const sysroot = rust.linker === "lld" ? execOutput(tool("rust", "cargo", "bin", "rustc.exe"), ["--print", "sysroot"], { env: rustEnv }) : "";
31826
- const lld = sysroot ? path62.join(sysroot, "lib", "rustlib", host, "bin", "gcc-ld") : "";
31827
- if (lld && exists(path62.join(lld, "ld.lld.exe"))) env.vars.AGENT_LLD_DIR = lld;
32012
+ const lld = sysroot ? path63.join(sysroot, "lib", "rustlib", host, "bin", "gcc-ld") : "";
32013
+ if (lld && exists(path63.join(lld, "ld.lld.exe"))) env.vars.AGENT_LLD_DIR = lld;
31828
32014
  env.summary.push(
31829
32015
  "rust linking: " + (env.vars.AGENT_LLD_DIR ? "lld" : "GNU ld") + ", at most " + env.vars.AGENT_LINK_SLOTS + " at once"
31830
32016
  );
31831
32017
  }
31832
32018
  function cargoDefaults(host) {
31833
32019
  const file3 = tool("rust", "cargo", "config.toml");
31834
- if (exists(file3) || !exists(path62.dirname(file3))) return;
31835
- const jobs = cargoJobs(os8.cpus().length, os8.totalmem() / 1024 ** 3, 1);
32020
+ if (exists(file3) || !exists(path63.dirname(file3))) return;
32021
+ const jobs = cargoJobs(os9.cpus().length, os9.totalmem() / 1024 ** 3, 1);
31836
32022
  const gnu = host.endsWith("-gnu");
31837
- fs48.writeFileSync(
32023
+ fs49.writeFileSync(
31838
32024
  file3,
31839
32025
  [
31840
32026
  "# Written by windows-development-sandbox once; edit freely, it is never overwritten.",
@@ -31849,13 +32035,14 @@ function rustCaches(rust) {
31849
32035
  const target = cargoTarget(rust.targetDir);
31850
32036
  return {
31851
32037
  ...target ? { CARGO_TARGET_DIR: target } : {},
31852
- ...process.env.SCCACHE_DIR ? {} : { SCCACHE_DIR: path62.join(dataDir, "cache", "sccache") }
32038
+ ...process.env.SCCACHE_DIR ? {} : { SCCACHE_DIR: path63.join(dataDir, "cache", "sccache") }
31853
32039
  };
31854
32040
  }
31855
32041
  function rustHost(config2) {
31856
32042
  if (config2.rust.host !== "auto") return config2.rust.host;
31857
32043
  const cpu = arch === "arm64" ? "aarch64" : "x86_64";
31858
- return cpu + (wanted(config2.msvc.enabled, "msvc") ? "-pc-windows-msvc" : "-pc-windows-gnu");
32044
+ const msvc = wanted(config2.msvc.enabled, "msvc") || wanted(config2.unreal.enabled, "unreal");
32045
+ return cpu + (msvc ? "-pc-windows-msvc" : "-pc-windows-gnu");
31859
32046
  }
31860
32047
 
31861
32048
  // src/guest/toolchains/languages/python-tools.ts
@@ -31875,6 +32062,7 @@ function plan(config2, versions, o) {
31875
32062
  const apps = Boolean(o.apps && (o.apps.install.length || Object.keys(o.apps.custom).length));
31876
32063
  const java = wanted(config2.java.enabled, "java");
31877
32064
  const python = wanted(config2.python.enabled, "python");
32065
+ const unreal = wanted(config2.unreal.enabled, "unreal");
31878
32066
  return [
31879
32067
  {
31880
32068
  name: "Git",
@@ -31892,12 +32080,18 @@ function plan(config2, versions, o) {
31892
32080
  enabled: wanted(config2.cpp.enabled, "cpp") || wanted(config2.rust.enabled, "rust"),
31893
32081
  install: (env) => setupCpp(env, config2.cpp)
31894
32082
  },
31895
- { name: "MSVC", enabled: wanted(config2.msvc.enabled, "msvc"), install: (env) => setupMsvc(env, config2.msvc) },
32083
+ // Unreal's Visual Studio brings MSVC and the real vswhere: the portable MSVC (and its stand-in vswhere) stays out.
32084
+ { name: "Unreal", enabled: unreal, shared: true, install: (env) => setupUnreal(env, config2.unreal) },
32085
+ {
32086
+ name: "MSVC",
32087
+ enabled: wanted(config2.msvc.enabled, "msvc") && !unreal,
32088
+ install: (env) => setupMsvc(env, config2.msvc)
32089
+ },
31896
32090
  // Rust links with MSVC (msvc host) or MinGW's gcc (GNU host): whichever it uses goes first.
31897
32091
  {
31898
32092
  name: "Rust",
31899
32093
  enabled: wanted(config2.rust.enabled, "rust"),
31900
- after: ["C/C++", "MSVC"],
32094
+ after: ["C/C++", "MSVC", "Unreal"],
31901
32095
  install: async (env) => {
31902
32096
  await setupRust(env, { ...config2.rust, host: rustHost(config2) }, o.refresh);
31903
32097
  Object.assign(env.vars, rustCaches(config2.rust));
@@ -31990,7 +32184,7 @@ function plan(config2, versions, o) {
31990
32184
  import { AsyncLocalStorage as AsyncLocalStorage2 } from "node:async_hooks";
31991
32185
 
31992
32186
  // src/guest/runtime/status.ts
31993
- import os9 from "node:os";
32187
+ import os10 from "node:os";
31994
32188
  var progress;
31995
32189
  function setSandboxStatus(phase, message, update) {
31996
32190
  try {
@@ -32014,7 +32208,7 @@ function fitProgress(p) {
32014
32208
  };
32015
32209
  }
32016
32210
  function ownAddresses() {
32017
- return Object.values(os9.networkInterfaces()).flat().filter((i) => Boolean(i) && i.family === "IPv4" && !i.internal).map((i) => i.address).slice(0, 8);
32211
+ return Object.values(os10.networkInterfaces()).flat().filter((i) => Boolean(i) && i.family === "IPv4" && !i.internal).map((i) => i.address).slice(0, 8);
32018
32212
  }
32019
32213
  function writeStatus(phase, message) {
32020
32214
  writeJsonAtomic(run.sandboxFile, {
@@ -32159,21 +32353,21 @@ function cmdSet(env, names) {
32159
32353
  return names.filter((n) => env[n] !== void 0 && !/[\r\n]/.test(String(env[n]))).map((n) => '@set "' + n + "=" + String(env[n]).replace(/%/g, "%%") + '"');
32160
32354
  }
32161
32355
  function writeShell(spec, env, names) {
32162
- const dir = mkdirp(path63.join(localDir, "projects", spec.name));
32163
- fs49.writeFileSync(path63.join(dir, "env.cmd"), [...cmdSet(env, [...names, "PATH"]), ""].join("\r\n"));
32164
- fs49.writeFileSync(
32165
- path63.join(dir, "shell.cmd"),
32166
- ['@call "' + path63.join(dir, "env.cmd") + '"', '@cd /d "' + spec.workspace + '"', "@title " + spec.name, ""].join(
32356
+ const dir = mkdirp(path64.join(localDir, "projects", spec.name));
32357
+ fs50.writeFileSync(path64.join(dir, "env.cmd"), [...cmdSet(env, [...names, "PATH"]), ""].join("\r\n"));
32358
+ fs50.writeFileSync(
32359
+ path64.join(dir, "shell.cmd"),
32360
+ ['@call "' + path64.join(dir, "env.cmd") + '"', '@cd /d "' + spec.workspace + '"', "@title " + spec.name, ""].join(
32167
32361
  "\r\n"
32168
32362
  )
32169
32363
  );
32170
- const bin = mkdirp(path63.join(localDir, "bin"));
32171
- fs49.writeFileSync(
32172
- path63.join(bin, "sbx-shell.cmd"),
32364
+ const bin = mkdirp(path64.join(localDir, "bin"));
32365
+ fs50.writeFileSync(
32366
+ path64.join(bin, "sbx-shell.cmd"),
32173
32367
  [
32174
- '@if "%~1"=="" (echo Usage: sbx-shell ^<project^> ^(a terminal in that project with its tools^) & dir /b "' + path63.join(localDir, "projects") + '" & exit /b 2)',
32175
- '@if not exist "' + path63.join(localDir, "projects") + '\\%~1\\shell.cmd" (echo No project %~1 in this sandbox. & exit /b 2)',
32176
- '@cmd /k ""' + path63.join(localDir, "projects") + '\\%~1\\shell.cmd""',
32368
+ '@if "%~1"=="" (echo Usage: sbx-shell ^<project^> ^(a terminal in that project with its tools^) & dir /b "' + path64.join(localDir, "projects") + '" & exit /b 2)',
32369
+ '@if not exist "' + path64.join(localDir, "projects") + '\\%~1\\shell.cmd" (echo No project %~1 in this sandbox. & exit /b 2)',
32370
+ '@cmd /k ""' + path64.join(localDir, "projects") + '\\%~1\\shell.cmd""',
32177
32371
  ""
32178
32372
  ].join("\r\n")
32179
32373
  );
@@ -32226,10 +32420,10 @@ async function setUp(spec, say) {
32226
32420
  }
32227
32421
  )
32228
32422
  );
32229
- tools.prepend.push(path63.join(localDir, "bin"));
32423
+ tools.prepend.push(path64.join(localDir, "bin"));
32230
32424
  const env = agentEnv(tools, { workspace: spec.workspace, project: spec.name, base });
32231
- const specFile = path63.join(mkdirp(path63.join(localDir, "projects", spec.name)), "project.json");
32232
- fs49.writeFileSync(specFile, JSON.stringify(spec));
32425
+ const specFile = path64.join(mkdirp(path64.join(localDir, "projects", spec.name)), "project.json");
32426
+ fs50.writeFileSync(specFile, JSON.stringify(spec));
32233
32427
  env.AGENT_PROJECT_FILE = specFile;
32234
32428
  addMachineEnvironment(tools.vars, [...tools.prepend, ...tools.append], true);
32235
32429
  try {
@@ -32346,10 +32540,10 @@ function execCommand(req) {
32346
32540
  }
32347
32541
 
32348
32542
  // src/guest/daemon/sessions.ts
32349
- import fs53 from "node:fs";
32350
- import path68 from "node:path";
32543
+ import fs54 from "node:fs";
32544
+ import path69 from "node:path";
32351
32545
  import crypto4 from "node:crypto";
32352
- import os11 from "node:os";
32546
+ import os12 from "node:os";
32353
32547
  import { spawn as spawn7 } from "node:child_process";
32354
32548
 
32355
32549
  // src/shared/pty/protocol.ts
@@ -32428,7 +32622,7 @@ async function sendControl(endpoint, type) {
32428
32622
  var MAX_CLIPBOARD_STRING = 1024 * 1024;
32429
32623
 
32430
32624
  // src/guest/sessions/cmdline.ts
32431
- import path64 from "node:path";
32625
+ import path65 from "node:path";
32432
32626
  var quoted = (arg) => '"' + arg.replace(/(\\*)"/g, '$1$1\\"').replace(/(\\+)$/, "$1$1") + '"';
32433
32627
  function quoteArg(arg) {
32434
32628
  return arg !== "" && !/[\s"]/.test(arg) ? arg : quoted(arg);
@@ -32442,7 +32636,7 @@ function cmdArgs(args) {
32442
32636
  }).join("");
32443
32637
  }
32444
32638
  function commandLine(file3, args) {
32445
- return path64.win32.basename(file3).toLowerCase() === "cmd.exe" ? [quoteArg(file3), cmdArgs(args)].filter(Boolean).join(" ") : [file3, ...args].map(quoteArg).join(" ");
32639
+ return path65.win32.basename(file3).toLowerCase() === "cmd.exe" ? [quoteArg(file3), cmdArgs(args)].filter(Boolean).join(" ") : [file3, ...args].map(quoteArg).join(" ");
32446
32640
  }
32447
32641
  function shellLaunch(asked, paths) {
32448
32642
  if (asked === "cmd") return { name: "cmd", file: paths.cmd, args: [] };
@@ -32456,8 +32650,8 @@ function shellLaunch(asked, paths) {
32456
32650
  }
32457
32651
 
32458
32652
  // src/guest/sessions/pty-host.ts
32459
- import fs50 from "node:fs";
32460
- import path65 from "node:path";
32653
+ import fs51 from "node:fs";
32654
+ import path66 from "node:path";
32461
32655
  import { execFile, spawn as spawn6 } from "node:child_process";
32462
32656
  function ensurePtyHost() {
32463
32657
  return ensureCompiled("ptyhost");
@@ -32476,21 +32670,21 @@ async function waitForPtyHost(child, port, timeoutMs) {
32476
32670
  throw new Error("the session host did not start listening on port " + port);
32477
32671
  }
32478
32672
  function ptyHostLog(id) {
32479
- return path65.join(logsDir, "ptyhost-" + id + ".log");
32673
+ return path66.join(logsDir, "ptyhost-" + id + ".log");
32480
32674
  }
32481
32675
  function ptyHostLogTail(id, lines = 12) {
32482
32676
  try {
32483
- return fs50.readFileSync(ptyHostLog(id), "utf8").trim().split(/\r?\n/).slice(-lines).join("\n");
32677
+ return fs51.readFileSync(ptyHostLog(id), "utf8").trim().split(/\r?\n/).slice(-lines).join("\n");
32484
32678
  } catch {
32485
32679
  return "";
32486
32680
  }
32487
32681
  }
32488
32682
  var conptyDll = () => {
32489
- const dll = path65.join(toolsDir, "conpty", "conpty.dll");
32490
- return session.provisioning.conpty?.enabled !== false && fs50.existsSync(dll) && fs50.existsSync(path65.join(toolsDir, "conpty", "OpenConsole.exe")) ? dll : null;
32683
+ const dll = path66.join(toolsDir, "conpty", "conpty.dll");
32684
+ return session.provisioning.conpty?.enabled !== false && fs51.existsSync(dll) && fs51.existsSync(path66.join(toolsDir, "conpty", "OpenConsole.exe")) ? dll : null;
32491
32685
  };
32492
32686
  function startPtyHost(o) {
32493
- fs50.mkdirSync(run.treesDir, { recursive: true });
32687
+ fs51.mkdirSync(run.treesDir, { recursive: true });
32494
32688
  const env = {
32495
32689
  ...o.env,
32496
32690
  PTYHOST_BIND: o.remote ? "any" : "loopback",
@@ -32508,13 +32702,13 @@ function startPtyHost(o) {
32508
32702
  var END_TREE_MS = 3e4;
32509
32703
  function endLeftoverTree(id, exe = ensurePtyHost()) {
32510
32704
  const file3 = run.treeFile(id);
32511
- if (!fs50.existsSync(file3)) return Promise.resolve(null);
32705
+ if (!fs51.existsSync(file3)) return Promise.resolve(null);
32512
32706
  return new Promise((resolve2) => {
32513
32707
  execFile(exe, ["--end-tree", file3], { timeout: END_TREE_MS, windowsHide: true }, (error62, stdout) => {
32514
32708
  const code = error62 ? typeof error62.code === "number" ? error62.code : -1 : 0;
32515
32709
  if (code !== 3)
32516
32710
  try {
32517
- fs50.rmSync(file3, { force: true });
32711
+ fs51.rmSync(file3, { force: true });
32518
32712
  } catch {
32519
32713
  }
32520
32714
  resolve2(code === 0 ? stdout.trim().slice(0, 200) : code === 3 ? null : "could not end them (code " + code + ")");
@@ -32523,15 +32717,15 @@ function endLeftoverTree(id, exe = ensurePtyHost()) {
32523
32717
  }
32524
32718
  function recordedTrees() {
32525
32719
  try {
32526
- return fs50.readdirSync(run.treesDir).filter((n) => /^[A-Za-z0-9_-]{1,64}\.json$/.test(n)).map((n) => n.slice(0, -".json".length));
32720
+ return fs51.readdirSync(run.treesDir).filter((n) => /^[A-Za-z0-9_-]{1,64}\.json$/.test(n)).map((n) => n.slice(0, -".json".length));
32527
32721
  } catch {
32528
32722
  return [];
32529
32723
  }
32530
32724
  }
32531
32725
 
32532
32726
  // src/guest/agents/agent-installer.ts
32533
- import fs51 from "node:fs";
32534
- import path66 from "node:path";
32727
+ import fs52 from "node:fs";
32728
+ import path67 from "node:path";
32535
32729
 
32536
32730
  // src/guest/agents/profile-links.ts
32537
32731
  var profileRoot = () => process.env.USERPROFILE ?? "";
@@ -32557,7 +32751,7 @@ var agentPaths2 = (name, harness) => agentPaths(toolsDir, name, harness);
32557
32751
  async function installViaNpm(name, harness, dir, env) {
32558
32752
  if (!harness.npmPackage)
32559
32753
  throw new Error("No npmPackage configured for " + name + " and no host executable was available.");
32560
- const npmCli = path66.join(path66.dirname(process.execPath), "node_modules", "npm", "bin", "npm-cli.js");
32754
+ const npmCli = path67.join(path67.dirname(process.execPath), "node_modules", "npm", "bin", "npm-cli.js");
32561
32755
  const args = [npmCli, "install", "--global", "--prefix", dir, harness.npmPackage, "--no-fund", "--no-audit"];
32562
32756
  log("Installing " + harness.npmPackage + " (this can take a minute)...");
32563
32757
  if (dryRun) {
@@ -32568,7 +32762,7 @@ async function installViaNpm(name, harness, dir, env) {
32568
32762
  await execAsync(process.execPath, args, { env });
32569
32763
  }
32570
32764
  async function installViaUv(name, harness, dir, env) {
32571
- const uv = path66.join(toolsDir, "uv", "uv.exe");
32765
+ const uv = path67.join(toolsDir, "uv", "uv.exe");
32572
32766
  log("Installing " + harness.uvPackage + " with uv (this can take a minute)...");
32573
32767
  if (dryRun) {
32574
32768
  log("(dry run) uv tool install " + harness.uvPackage);
@@ -32583,8 +32777,8 @@ async function installViaUv(name, harness, dir, env) {
32583
32777
  });
32584
32778
  }
32585
32779
  function putOnPath(dir, env) {
32586
- const parts2 = (env.PATH ?? "").split(path66.delimiter);
32587
- if (!parts2.some((p) => p.toLowerCase() === dir.toLowerCase())) env.PATH = [...parts2, dir].join(path66.delimiter);
32780
+ const parts2 = (env.PATH ?? "").split(path67.delimiter);
32781
+ if (!parts2.some((p) => p.toLowerCase() === dir.toLowerCase())) env.PATH = [...parts2, dir].join(path67.delimiter);
32588
32782
  addMachineEnvironment({}, [dir], true);
32589
32783
  }
32590
32784
  var AgentInstaller = class {
@@ -32625,9 +32819,9 @@ var AgentInstaller = class {
32625
32819
  }
32626
32820
  mkdirp(p.dir);
32627
32821
  if (this.sourceOf(name, harness) === "host") {
32628
- const source = path66.join(hostToolsDir, "agents", name, harness.hostExecutable);
32822
+ const source = path67.join(hostToolsDir, "agents", name, harness.hostExecutable);
32629
32823
  if (exists(source) && p.exe) {
32630
- fs51.copyFileSync(source, p.exe);
32824
+ fs52.copyFileSync(source, p.exe);
32631
32825
  log("Copied " + name + " from this PC: " + source);
32632
32826
  return;
32633
32827
  }
@@ -32642,28 +32836,28 @@ var AgentInstaller = class {
32642
32836
  var agents = new AgentInstaller();
32643
32837
 
32644
32838
  // src/guest/network/addresses.ts
32645
- import os10 from "node:os";
32839
+ import os11 from "node:os";
32646
32840
  function guestAddresses() {
32647
- return Object.values(os10.networkInterfaces()).flat().filter((i) => Boolean(i) && i.family === "IPv4" && !i.internal).map((i) => i.address);
32841
+ return Object.values(os11.networkInterfaces()).flat().filter((i) => Boolean(i) && i.family === "IPv4" && !i.internal).map((i) => i.address);
32648
32842
  }
32649
32843
 
32650
32844
  // src/guest/sessions/conversation.ts
32651
- import fs52 from "node:fs";
32652
- import path67 from "node:path";
32845
+ import fs53 from "node:fs";
32846
+ import path68 from "node:path";
32653
32847
  var MAX_FILES = 2e3;
32654
32848
  function conversationFiles(claudeDir2, cwd) {
32655
32849
  const names = /* @__PURE__ */ new Set([projectFolderName(cwd), projectFolderName(sandboxFolder(cwd))]);
32656
32850
  return [...names].flatMap((name) => {
32657
- const dir = path67.join(claudeDir2, "projects", name);
32851
+ const dir = path68.join(claudeDir2, "projects", name);
32658
32852
  let entries2;
32659
32853
  try {
32660
- entries2 = fs52.readdirSync(dir);
32854
+ entries2 = fs53.readdirSync(dir);
32661
32855
  } catch {
32662
32856
  return [];
32663
32857
  }
32664
32858
  return entries2.filter((e) => e.endsWith(".jsonl") && isConversationId(e.slice(0, -".jsonl".length))).slice(0, MAX_FILES).flatMap((e) => {
32665
32859
  try {
32666
- return [{ id: e.slice(0, -".jsonl".length), createdMs: fs52.statSync(path67.join(dir, e)).birthtimeMs }];
32860
+ return [{ id: e.slice(0, -".jsonl".length), createdMs: fs53.statSync(path68.join(dir, e)).birthtimeMs }];
32667
32861
  } catch {
32668
32862
  return [];
32669
32863
  }
@@ -32704,8 +32898,8 @@ var IdleShutdown = class {
32704
32898
  var CLOSE_WAIT_MS = 8e3;
32705
32899
  var ROOTS_KEPT_MS = 10 * 60 * 1e3;
32706
32900
  function terminalTab(id, title, cwd) {
32707
- const view = [process.execPath, path68.join(path68.dirname(process.argv[1]), "view.js"), id];
32708
- const wt = path68.join(toolsDir, "terminal", "wt.exe");
32901
+ const view = [process.execPath, path69.join(path69.dirname(process.argv[1]), "view.js"), id];
32902
+ const wt = path69.join(toolsDir, "terminal", "wt.exe");
32709
32903
  if (exists(wt))
32710
32904
  spawn7(wt, ["-w", "0", "nt", "--title", title, "-d", cwd, ...view], { detached: true, stdio: "ignore" }).unref();
32711
32905
  else spawn7(SYSTEM.cmd(), ["/d", "/c", "start", title, ...view], { detached: true, stdio: "ignore", cwd }).unref();
@@ -32721,8 +32915,8 @@ var harnessFor = (req) => {
32721
32915
  function memoryEnv(env, sessions2) {
32722
32916
  const out = {};
32723
32917
  out.PTYHOST_BACKSTOP_MB = String(session.agentBackstop ?? "auto");
32724
- const cpus = usableCpus(os11.cpus().length, session.cpuLimitPercent ?? null);
32725
- const memoryGb = os11.totalmem() / 1024 ** 3;
32918
+ const cpus = usableCpus(os12.cpus().length, session.cpuLimitPercent ?? null);
32919
+ const memoryGb = os12.totalmem() / 1024 ** 3;
32726
32920
  const jobs = cargoJobs(cpus, memoryGb, sessions2);
32727
32921
  out.NUMBER_OF_PROCESSORS = String(cpus);
32728
32922
  if (!env.CARGO_BUILD_JOBS) out.CARGO_BUILD_JOBS = String(jobs);
@@ -32761,10 +32955,10 @@ var agentProgram = async (req, env, say) => {
32761
32955
  };
32762
32956
  function shellPaths() {
32763
32957
  const candidates = [
32764
- path68.join(pwshDir(), "pwsh.exe"),
32765
- path68.join(process.env.ProgramFiles ?? "C:\\Program Files", "PowerShell", "7", "pwsh.exe")
32958
+ path69.join(pwshDir(), "pwsh.exe"),
32959
+ path69.join(process.env.ProgramFiles ?? "C:\\Program Files", "PowerShell", "7", "pwsh.exe")
32766
32960
  ];
32767
- return { pwsh: candidates.find((f) => fs53.existsSync(f)) ?? null, powershell: SYSTEM.powershell(), cmd: SYSTEM.cmd() };
32961
+ return { pwsh: candidates.find((f) => fs54.existsSync(f)) ?? null, powershell: SYSTEM.powershell(), cmd: SYSTEM.cmd() };
32768
32962
  }
32769
32963
  var shellProgram = (shell) => {
32770
32964
  const line = commandLine(shell.file, shell.args);
@@ -32798,7 +32992,7 @@ var launchPtyHost = async (req, program, remote, env, sessions2, onSpawn) => {
32798
32992
  } catch (e) {
32799
32993
  const tail = ptyHostLogTail(req.id);
32800
32994
  throw new Error(
32801
- errMsg(e) + (tail ? ". From its log:\n" + tail : "") + "\nLog: " + path68.join(dataDir, "logs", "ptyhost-" + req.id + ".log")
32995
+ errMsg(e) + (tail ? ". From its log:\n" + tail : "") + "\nLog: " + path69.join(dataDir, "logs", "ptyhost-" + req.id + ".log")
32802
32996
  );
32803
32997
  }
32804
32998
  return { child, port, token };
@@ -32912,7 +33106,7 @@ var SessionManager = class {
32912
33106
  };
32913
33107
  this.starting++;
32914
33108
  if (req.id !== session.launchId && process.env.AGENT_NO_TABS !== "1")
32915
- safely("terminal tab", () => terminalTab(req.id, name + " " + path68.basename(req.cwd), req.cwd));
33109
+ safely("terminal tab", () => terminalTab(req.id, name + " " + path69.basename(req.cwd), req.cwd));
32916
33110
  try {
32917
33111
  if (problem) throw new Error(problem);
32918
33112
  const place = await placeFor(req, say);
@@ -33406,9 +33600,9 @@ var GovernorCore = class {
33406
33600
  };
33407
33601
 
33408
33602
  // src/guest/governor/governor.ts
33409
- import fs54 from "node:fs";
33410
- import os12 from "node:os";
33411
- import path69 from "node:path";
33603
+ import fs55 from "node:fs";
33604
+ import os13 from "node:os";
33605
+ import path70 from "node:path";
33412
33606
  import { spawn as spawn8 } from "node:child_process";
33413
33607
  import { createInterface } from "node:readline";
33414
33608
  var SampleSchema = external_exports.object({
@@ -33478,12 +33672,12 @@ var MemGovProcess = class {
33478
33672
  };
33479
33673
  function appendToMemoryLog(line) {
33480
33674
  try {
33481
- const logs = path69.join(dataDir, "logs");
33482
- const newest = fs54.readdirSync(logs).filter((f) => /^memory-\d{8}-\d{6}\.log$/.test(f)).sort().pop();
33675
+ const logs = path70.join(dataDir, "logs");
33676
+ const newest = fs55.readdirSync(logs).filter((f) => /^memory-\d{8}-\d{6}\.log$/.test(f)).sort().pop();
33483
33677
  if (!newest) return;
33484
33678
  const t = /* @__PURE__ */ new Date();
33485
33679
  const stamp = [t.getHours(), t.getMinutes(), t.getSeconds()].map((n) => String(n).padStart(2, "0")).join(":");
33486
- fs54.appendFileSync(path69.join(logs, newest), stamp + " | " + line + "\r\n");
33680
+ fs55.appendFileSync(path70.join(logs, newest), stamp + " | " + line + "\r\n");
33487
33681
  } catch {
33488
33682
  }
33489
33683
  }
@@ -33501,7 +33695,7 @@ var Governor = class {
33501
33695
  this.core = new GovernorCore({
33502
33696
  port: proc,
33503
33697
  profile,
33504
- maxCompilers: maxCompilers(os12.cpus().length, profile),
33698
+ maxCompilers: maxCompilers(os13.cpus().length, profile),
33505
33699
  now: () => Date.now(),
33506
33700
  logLine: appendToMemoryLog,
33507
33701
  warn,
@@ -33523,13 +33717,13 @@ var Governor = class {
33523
33717
  var governor = new Governor();
33524
33718
 
33525
33719
  // src/guest/daemon/live.ts
33526
- import fs56 from "node:fs";
33527
- import path71 from "node:path";
33720
+ import fs57 from "node:fs";
33721
+ import path72 from "node:path";
33528
33722
  import { spawnSync as spawnSync7 } from "node:child_process";
33529
33723
 
33530
33724
  // src/guest/daemon/live-folders.ts
33531
- import fs55 from "node:fs";
33532
- import path70 from "node:path";
33725
+ import fs56 from "node:fs";
33726
+ import path71 from "node:path";
33533
33727
 
33534
33728
  // src/shared/channel/live.ts
33535
33729
  import crypto5 from "node:crypto";
@@ -33622,7 +33816,7 @@ var LiveFolderHandler = class {
33622
33816
  }
33623
33817
  read() {
33624
33818
  try {
33625
- const text = fs55.readFileSync(this.o.stateFile, "utf8");
33819
+ const text = fs56.readFileSync(this.o.stateFile, "utf8");
33626
33820
  const parsed = StateSchema.safeParse(JSON.parse(text));
33627
33821
  if (parsed.success && parsed.data.launchId === this.o.launchId) return parsed.data;
33628
33822
  } catch {
@@ -33630,7 +33824,7 @@ var LiveFolderHandler = class {
33630
33824
  return { key: null, launchId: this.o.launchId, seen: [], mappings: [] };
33631
33825
  }
33632
33826
  save(state) {
33633
- fs55.mkdirSync(path70.dirname(this.o.stateFile), { recursive: true });
33827
+ fs56.mkdirSync(path71.dirname(this.o.stateFile), { recursive: true });
33634
33828
  writeJsonAtomic(this.o.stateFile, state);
33635
33829
  }
33636
33830
  /** The key the boot handed over (from the one-shot secrets file). */
@@ -33641,30 +33835,30 @@ var LiveFolderHandler = class {
33641
33835
  /** C:\Workspace\<name> from a checked name only. */
33642
33836
  folderPath(name) {
33643
33837
  if (!LIVE_FOLDER_NAME.test(name)) throw new Error("not a plain folder name");
33644
- return path70.win32.join(this.o.workspaces ?? WORKSPACES_GUEST, name);
33838
+ return path71.win32.join(this.o.workspaces ?? WORKSPACES_GUEST, name);
33645
33839
  }
33646
33840
  /** One pass over run\live: every file is claimed (deleted) at once; valid ones are handled one after another. */
33647
33841
  tick() {
33648
33842
  const dir = this.o.run.liveDir;
33649
33843
  let names;
33650
33844
  try {
33651
- names = fs55.readdirSync(dir);
33845
+ names = fs56.readdirSync(dir);
33652
33846
  } catch {
33653
33847
  return;
33654
33848
  }
33655
33849
  for (const name of names.slice(0, 64)) {
33656
33850
  if (name.endsWith(".tmp")) continue;
33657
- const file3 = path70.join(dir, name);
33851
+ const file3 = path71.join(dir, name);
33658
33852
  let envelope = null;
33659
33853
  try {
33660
- const stat = fs55.lstatSync(file3);
33854
+ const stat = fs56.lstatSync(file3);
33661
33855
  if (stat.isFile() && stat.size <= MAX_REQUEST_BYTES && /^[A-Za-z0-9_-]{1,64}\.json$/.test(name))
33662
- envelope = JSON.parse(fs55.readFileSync(file3, "utf8"));
33856
+ envelope = JSON.parse(fs56.readFileSync(file3, "utf8"));
33663
33857
  } catch {
33664
33858
  envelope = null;
33665
33859
  } finally {
33666
33860
  try {
33667
- fs55.rmSync(file3, { recursive: true, force: true });
33861
+ fs56.rmSync(file3, { recursive: true, force: true });
33668
33862
  } catch {
33669
33863
  }
33670
33864
  }
@@ -33701,7 +33895,7 @@ var LiveFolderHandler = class {
33701
33895
  }
33702
33896
  reply(id, r) {
33703
33897
  try {
33704
- fs55.mkdirSync(this.o.run.liveRepliesDir, { recursive: true });
33898
+ fs56.mkdirSync(this.o.run.liveRepliesDir, { recursive: true });
33705
33899
  writeJsonAtomic(this.o.run.liveReplyFile(id), { id, ...r, finishedAt: new Date(this.now()).toISOString() });
33706
33900
  } catch (e) {
33707
33901
  this.log("live folder reply not written: " + errMsg(e));
@@ -33722,14 +33916,14 @@ var LiveFolderHandler = class {
33722
33916
  assertFree(folder) {
33723
33917
  let exists2 = true;
33724
33918
  try {
33725
- fs55.lstatSync(folder);
33919
+ fs56.lstatSync(folder);
33726
33920
  } catch {
33727
33921
  exists2 = false;
33728
33922
  }
33729
33923
  if (exists2) throw new Error(folder + " exists already");
33730
- const parent = path70.dirname(folder);
33731
- fs55.mkdirSync(parent, { recursive: true });
33732
- if (!fs55.lstatSync(parent).isDirectory()) throw new Error(parent + " is not a plain folder");
33924
+ const parent = path71.dirname(folder);
33925
+ fs56.mkdirSync(parent, { recursive: true });
33926
+ if (!fs56.lstatSync(parent).isDirectory()) throw new Error(parent + " is not a plain folder");
33733
33927
  }
33734
33928
  async act(p) {
33735
33929
  const folder = this.folderPath(p.folder);
@@ -33750,9 +33944,9 @@ var LiveFolderHandler = class {
33750
33944
  const code2 = await this.mapWithRetry(folder, share, true);
33751
33945
  if (code2 !== EXIT_OK) return { ok: false, message: "the test share could not be shown (" + code2 + ")" };
33752
33946
  try {
33753
- const file3 = path70.join(folder, "token.txt");
33754
- const stat = fs55.statSync(file3);
33755
- const token = stat.size <= 64 ? fs55.readFileSync(file3, "utf8").trim() : "";
33947
+ const file3 = path71.join(folder, "token.txt");
33948
+ const stat = fs56.statSync(file3);
33949
+ const token = stat.size <= 64 ? fs56.readFileSync(file3, "utf8").trim() : "";
33756
33950
  return LIVE_TOKEN.test(token) ? { ok: true, message: "read the test share", token } : { ok: false, message: "the test share holds no token" };
33757
33951
  } finally {
33758
33952
  this.o.bind.unmap(folder);
@@ -33780,7 +33974,7 @@ var LiveFolderHandler = class {
33780
33974
  for (const m of this.read().mappings) {
33781
33975
  const folder = this.folderPath(m.folder);
33782
33976
  if (this.o.bind.mapped(folder) === EXIT_OK) continue;
33783
- fs55.mkdirSync(path70.dirname(folder), { recursive: true });
33977
+ fs56.mkdirSync(path71.dirname(folder), { recursive: true });
33784
33978
  if (this.o.bind.map(folder, m.share, m.readOnly) === EXIT_OK) done++;
33785
33979
  else this.log("live folder " + folder + " could not be shown again");
33786
33980
  }
@@ -33791,7 +33985,7 @@ var LiveFolderHandler = class {
33791
33985
  // src/guest/daemon/live.ts
33792
33986
  var BIND_TIMEOUT_MS = 3e4;
33793
33987
  var testing = Boolean(process.env.AGENT_DAEMON_STATE_DIR || process.env.AGENT_LOCAL_DIR);
33794
- var stateDir2 = process.env.AGENT_DAEMON_STATE_DIR ?? (process.env.AGENT_LOCAL_DIR ? path71.join(localDir, "daemon-state") : path71.join(process.env.ProgramData ?? "C:\\ProgramData", "AgentSandboxDaemon"));
33988
+ var stateDir2 = process.env.AGENT_DAEMON_STATE_DIR ?? (process.env.AGENT_LOCAL_DIR ? path72.join(localDir, "daemon-state") : path72.join(process.env.ProgramData ?? "C:\\ProgramData", "AgentSandboxDaemon"));
33795
33989
  function bindMount(args) {
33796
33990
  const r = spawnSync7(ensureCompiled("bindmount"), args, {
33797
33991
  windowsHide: true,
@@ -33806,7 +34000,7 @@ var realBind = {
33806
34000
  mapped: (folder) => bindMount(["mapped", folder])
33807
34001
  };
33808
34002
  function protectStateDir() {
33809
- fs56.mkdirSync(stateDir2, { recursive: true });
34003
+ fs57.mkdirSync(stateDir2, { recursive: true });
33810
34004
  if (!isWin || testMode || testing) return;
33811
34005
  spawnSync7(
33812
34006
  SYSTEM.icacls(),
@@ -33819,7 +34013,7 @@ function protectStateDir() {
33819
34013
  }
33820
34014
  var liveFolders = new LiveFolderHandler({
33821
34015
  run,
33822
- stateFile: path71.join(stateDir2, "live-folders.json"),
34016
+ stateFile: path72.join(stateDir2, "live-folders.json"),
33823
34017
  launchId: session.launchId,
33824
34018
  bind: realBind,
33825
34019
  log: warn
@@ -33849,9 +34043,9 @@ var Daemon = class {
33849
34043
  tick() {
33850
34044
  const { valid, invalid } = run.scanRequests();
33851
34045
  for (const file3 of invalid)
33852
- safely("removing an invalid request", () => fs57.rmSync(file3, { recursive: true, force: true }));
34046
+ safely("removing an invalid request", () => fs58.rmSync(file3, { recursive: true, force: true }));
33853
34047
  for (const req of valid) {
33854
- safely("claiming a request", () => fs57.rmSync(run.requestFile(req.id), { force: true }));
34048
+ safely("claiming a request", () => fs58.rmSync(run.requestFile(req.id), { force: true }));
33855
34049
  if (run.readSession(req.id)) continue;
33856
34050
  void Promise.resolve(this.handle(withRequestSecrets(req))).catch(
33857
34051
  (e) => respond(req.id, { ok: false, message: errMsg(e) })