windows-development-sandbox 1.23.2 → 1.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/config.example.json +0 -1
  2. package/dist/bin/agent-sandbox.js +2 -2
  3. package/dist/bin/{chunk-USTRSHIE.js → chunk-IZRGTSQ5.js} +158 -131
  4. package/dist/bin/{chunk-QFSJX2KW.js → chunk-KH4MI2U5.js} +1 -1
  5. package/dist/bin/{chunk-7YPEDAJD.js → chunk-SUYYVIDW.js} +1 -1
  6. package/dist/bin/claude-host.js +2 -2
  7. package/dist/bin/claude-sbx.js +2 -2
  8. package/dist/bin/codex-sbx.js +2 -2
  9. package/dist/bin/gemini-sbx.js +2 -2
  10. package/dist/bin/sandbox.js +2 -2
  11. package/dist/bin/sbx-hide.js +2 -2
  12. package/dist/bin/sbx-show.js +2 -2
  13. package/dist/core/config/defaults.js +0 -1
  14. package/dist/core/detect/toolchains.js +0 -6
  15. package/dist/core/schema/config.d.ts +1 -2
  16. package/dist/core/schema/toolchains.d.ts +1 -2
  17. package/dist/core/schema/toolchains.js +3 -6
  18. package/dist/guest/agents/agent-files.d.ts +11 -7
  19. package/dist/guest/agents/agent-files.js +37 -11
  20. package/dist/guest/agents/local-state.d.ts +2 -1
  21. package/dist/guest/agents/local-state.js +2 -1
  22. package/dist/guest/boot/boot-console.d.ts +28 -0
  23. package/dist/guest/boot/boot-console.js +98 -0
  24. package/dist/guest/boot/boot.d.ts +8 -1
  25. package/dist/guest/boot/boot.js +66 -42
  26. package/dist/guest/boot/graph.d.ts +9 -5
  27. package/dist/guest/boot/graph.js +8 -2
  28. package/dist/guest/boot/progress-view.d.ts +116 -0
  29. package/dist/guest/boot/progress-view.js +456 -0
  30. package/dist/guest/boot/runner.d.ts +20 -10
  31. package/dist/guest/boot/runner.js +39 -47
  32. package/dist/guest/runtime/log-line.d.ts +7 -0
  33. package/dist/guest/runtime/log-line.js +18 -0
  34. package/dist/guest/runtime/log.d.ts +17 -4
  35. package/dist/guest/runtime/log.js +40 -17
  36. package/dist/guest/runtime/process.d.ts +9 -0
  37. package/dist/guest/runtime/process.js +69 -8
  38. package/dist/guest/setup/environment.js +9 -4
  39. package/dist/guest/setup/hooks.d.ts +2 -0
  40. package/dist/guest/setup/hooks.js +4 -0
  41. package/dist/guest/setup/path-plan.d.ts +12 -0
  42. package/dist/guest/setup/path-plan.js +18 -0
  43. package/dist/guest/toolchains/native/unreal.js +4 -6
  44. package/dist/guest/toolchains/native/visual-studio.d.ts +14 -14
  45. package/dist/guest/toolchains/native/visual-studio.js +145 -174
  46. package/dist/guest/toolchains/native/vs-persist.d.ts +189 -0
  47. package/dist/guest/toolchains/native/vs-persist.js +256 -0
  48. package/dist/guest/toolchains/native/vs-request.d.ts +6 -26
  49. package/dist/guest/toolchains/native/vs-request.js +16 -50
  50. package/dist/guest/toolchains/plan.js +11 -14
  51. package/dist/host/migrate/migrations/drop-vs-install-files.d.ts +5 -0
  52. package/dist/host/migrate/migrations/drop-vs-install-files.js +34 -0
  53. package/dist/host/migrate/registry.js +7 -1
  54. package/dist/runtime/agent.js +67 -26
  55. package/dist/runtime/daemon.js +958 -716
  56. package/dist/runtime/db.js +67 -26
  57. package/dist/runtime/main.js +1792 -1038
  58. package/dist/runtime/netproxy.js +3 -6
  59. package/dist/runtime/tool.js +44 -24
  60. package/dist/runtime/view.js +4 -7
  61. package/dist/selftest/agent-paths.test.js +17 -1
  62. package/dist/selftest/agent-settings.test.js +36 -5
  63. package/dist/selftest/boot-console.test.d.ts +2 -0
  64. package/dist/selftest/boot-console.test.js +291 -0
  65. package/dist/selftest/boot-runner.test.js +10 -12
  66. package/dist/selftest/guest-boot.test.js +7 -1
  67. package/dist/selftest/index.js +2 -0
  68. package/dist/selftest/layout.test.js +4 -0
  69. package/dist/selftest/migrate.test.js +21 -0
  70. package/dist/selftest/persisted-installs.test.js +169 -33
  71. package/dist/selftest/support/engine-golden.js +2 -0
  72. package/dist/selftest/support/fixtures.d.ts +1 -2
  73. package/dist/shared/channel/schema.d.ts +3 -6
  74. package/dist/shared/pty/terminal.js +2 -1
  75. package/dist/sync/watcher.js +5 -1
  76. package/native/csharp/HcsHost/AssemblyInfo.cs +3 -3
  77. package/native/csharp/HostTools/AssemblyInfo.cs +3 -3
  78. package/native/csharp/StorageHelper/AssemblyInfo.cs +3 -3
  79. package/package.json +1 -1
  80. package/sandbox/scripts/restore-visual-studio.ps1 +78 -0
  81. package/sandbox/scripts/save-visual-studio.ps1 +106 -0
  82. package/schemas/config.schema.json +3 -7
  83. package/schemas/sandbox-config.schema.json +3 -7
  84. package/dist/guest/toolchains/native/autosdk.d.ts +0 -3
  85. package/dist/guest/toolchains/native/autosdk.js +0 -50
@@ -1363,11 +1363,11 @@ var require_lodash = __commonJS({
1363
1363
  return isFunction(object2[key2]);
1364
1364
  });
1365
1365
  }
1366
- function baseGet(object2, path96) {
1367
- path96 = castPath(path96, object2);
1368
- var index = 0, length = path96.length;
1366
+ function baseGet(object2, path95) {
1367
+ path95 = castPath(path95, object2);
1368
+ var index = 0, length = path95.length;
1369
1369
  while (object2 != null && index < length) {
1370
- object2 = object2[toKey(path96[index++])];
1370
+ object2 = object2[toKey(path95[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, path96, args) {
1435
- path96 = castPath(path96, object2);
1436
- object2 = parent(object2, path96);
1437
- var func = object2 == null ? object2 : object2[toKey(last(path96))];
1434
+ function baseInvoke(object2, path95, args) {
1435
+ path95 = castPath(path95, object2);
1436
+ object2 = parent(object2, path95);
1437
+ var func = object2 == null ? object2 : object2[toKey(last(path95))];
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(path96, srcValue) {
1594
- if (isKey(path96) && isStrictComparable(srcValue)) {
1595
- return matchesStrictComparable(toKey(path96), srcValue);
1593
+ function baseMatchesProperty(path95, srcValue) {
1594
+ if (isKey(path95) && isStrictComparable(srcValue)) {
1595
+ return matchesStrictComparable(toKey(path95), srcValue);
1596
1596
  }
1597
1597
  return function(object2) {
1598
- var objValue = get(object2, path96);
1599
- return objValue === undefined2 && objValue === srcValue ? hasIn(object2, path96) : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG);
1598
+ var objValue = get(object2, path95);
1599
+ return objValue === undefined2 && objValue === srcValue ? hasIn(object2, path95) : 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, path96) {
1697
- return hasIn(object2, path96);
1696
+ return basePickBy(object2, paths, function(value, path95) {
1697
+ return hasIn(object2, path95);
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 path96 = paths[index], value = baseGet(object2, path96);
1704
- if (predicate(value, path96)) {
1705
- baseSet(result2, castPath(path96, object2), value);
1703
+ var path95 = paths[index], value = baseGet(object2, path95);
1704
+ if (predicate(value, path95)) {
1705
+ baseSet(result2, castPath(path95, object2), value);
1706
1706
  }
1707
1707
  }
1708
1708
  return result2;
1709
1709
  }
1710
- function basePropertyDeep(path96) {
1710
+ function basePropertyDeep(path95) {
1711
1711
  return function(object2) {
1712
- return baseGet(object2, path96);
1712
+ return baseGet(object2, path95);
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, path96, value, customizer) {
1786
+ function baseSet(object2, path95, value, customizer) {
1787
1787
  if (!isObject2(object2)) {
1788
1788
  return object2;
1789
1789
  }
1790
- path96 = castPath(path96, object2);
1791
- var index = -1, length = path96.length, lastIndex = length - 1, nested = object2;
1790
+ path95 = castPath(path95, object2);
1791
+ var index = -1, length = path95.length, lastIndex = length - 1, nested = object2;
1792
1792
  while (nested != null && ++index < length) {
1793
- var key2 = toKey(path96[index]), newValue = value;
1793
+ var key2 = toKey(path95[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(path96[index + 1]) ? [] : {};
1801
+ newValue = isObject2(objValue) ? objValue : isIndex(path95[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, path96) {
1968
- path96 = castPath(path96, object2);
1969
- var index = -1, length = path96.length;
1967
+ function baseUnset(object2, path95) {
1968
+ path95 = castPath(path95, object2);
1969
+ var index = -1, length = path95.length;
1970
1970
  if (!length) {
1971
1971
  return true;
1972
1972
  }
1973
1973
  while (++index < length) {
1974
- var key2 = toKey(path96[index]);
1974
+ var key2 = toKey(path95[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, path96);
1983
- return obj == null || delete obj[toKey(last(path96))];
1982
+ var obj = parent(object2, path95);
1983
+ return obj == null || delete obj[toKey(last(path95))];
1984
1984
  }
1985
- function baseUpdate(object2, path96, updater, customizer) {
1986
- return baseSet(object2, path96, updater(baseGet(object2, path96)), customizer);
1985
+ function baseUpdate(object2, path95, updater, customizer) {
1986
+ return baseSet(object2, path95, updater(baseGet(object2, path95)), 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, path96, hasFunc) {
2870
- path96 = castPath(path96, object2);
2871
- var index = -1, length = path96.length, result2 = false;
2869
+ function hasPath(object2, path95, hasFunc) {
2870
+ path95 = castPath(path95, object2);
2871
+ var index = -1, length = path95.length, result2 = false;
2872
2872
  while (++index < length) {
2873
- var key2 = toKey(path96[index]);
2873
+ var key2 = toKey(path95[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, path96) {
3076
- return path96.length < 2 ? object2 : baseGet(object2, baseSlice(path96, 0, -1));
3075
+ function parent(object2, path95) {
3076
+ return path95.length < 2 ? object2 : baseGet(object2, baseSlice(path95, 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, path96, args) {
3712
- var index = -1, isFunc = typeof path96 == "function", result2 = isArrayLike(collection) ? Array2(collection.length) : [];
3711
+ var invokeMap = baseRest(function(collection, path95, args) {
3712
+ var index = -1, isFunc = typeof path95 == "function", result2 = isArrayLike(collection) ? Array2(collection.length) : [];
3713
3713
  baseEach(collection, function(value) {
3714
- result2[++index] = isFunc ? apply(path96, value, args) : baseInvoke(value, path96, args);
3714
+ result2[++index] = isFunc ? apply(path95, value, args) : baseInvoke(value, path95, 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, path96, defaultValue) {
4367
- var result2 = object2 == null ? undefined2 : baseGet(object2, path96);
4366
+ function get(object2, path95, defaultValue) {
4367
+ var result2 = object2 == null ? undefined2 : baseGet(object2, path95);
4368
4368
  return result2 === undefined2 ? defaultValue : result2;
4369
4369
  }
4370
- function has(object2, path96) {
4371
- return object2 != null && hasPath(object2, path96, baseHas);
4370
+ function has(object2, path95) {
4371
+ return object2 != null && hasPath(object2, path95, baseHas);
4372
4372
  }
4373
- function hasIn(object2, path96) {
4374
- return object2 != null && hasPath(object2, path96, baseHasIn);
4373
+ function hasIn(object2, path95) {
4374
+ return object2 != null && hasPath(object2, path95, 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(path96) {
4428
- path96 = castPath(path96, object2);
4429
- isDeep || (isDeep = path96.length > 1);
4430
- return path96;
4427
+ paths = arrayMap(paths, function(path95) {
4428
+ path95 = castPath(path95, object2);
4429
+ isDeep || (isDeep = path95.length > 1);
4430
+ return path95;
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, path96) {
4457
- return predicate(value, path96[0]);
4456
+ return basePickBy(object2, props, function(value, path95) {
4457
+ return predicate(value, path95[0]);
4458
4458
  });
4459
4459
  }
4460
- function result(object2, path96, defaultValue) {
4461
- path96 = castPath(path96, object2);
4462
- var index = -1, length = path96.length;
4460
+ function result(object2, path95, defaultValue) {
4461
+ path95 = castPath(path95, object2);
4462
+ var index = -1, length = path95.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(path96[index])];
4468
+ var value = object2 == null ? undefined2 : object2[toKey(path95[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, path96, value) {
4478
- return object2 == null ? object2 : baseSet(object2, path96, value);
4477
+ function set2(object2, path95, value) {
4478
+ return object2 == null ? object2 : baseSet(object2, path95, value);
4479
4479
  }
4480
- function setWith(object2, path96, value, customizer) {
4480
+ function setWith(object2, path95, value, customizer) {
4481
4481
  customizer = typeof customizer == "function" ? customizer : undefined2;
4482
- return object2 == null ? object2 : baseSet(object2, path96, value, customizer);
4482
+ return object2 == null ? object2 : baseSet(object2, path95, 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, path96) {
4505
- return object2 == null ? true : baseUnset(object2, path96);
4504
+ function unset(object2, path95) {
4505
+ return object2 == null ? true : baseUnset(object2, path95);
4506
4506
  }
4507
- function update(object2, path96, updater) {
4508
- return object2 == null ? object2 : baseUpdate(object2, path96, castFunction(updater));
4507
+ function update(object2, path95, updater) {
4508
+ return object2 == null ? object2 : baseUpdate(object2, path95, castFunction(updater));
4509
4509
  }
4510
- function updateWith(object2, path96, updater, customizer) {
4510
+ function updateWith(object2, path95, updater, customizer) {
4511
4511
  customizer = typeof customizer == "function" ? customizer : undefined2;
4512
- return object2 == null ? object2 : baseUpdate(object2, path96, castFunction(updater), customizer);
4512
+ return object2 == null ? object2 : baseUpdate(object2, path95, 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(path96, srcValue) {
4899
- return baseMatchesProperty(path96, baseClone(srcValue, CLONE_DEEP_FLAG));
4898
+ function matchesProperty(path95, srcValue) {
4899
+ return baseMatchesProperty(path95, baseClone(srcValue, CLONE_DEEP_FLAG));
4900
4900
  }
4901
- var method = baseRest(function(path96, args) {
4901
+ var method = baseRest(function(path95, args) {
4902
4902
  return function(object2) {
4903
- return baseInvoke(object2, path96, args);
4903
+ return baseInvoke(object2, path95, args);
4904
4904
  };
4905
4905
  });
4906
4906
  var methodOf = baseRest(function(object2, args) {
4907
- return function(path96) {
4908
- return baseInvoke(object2, path96, args);
4907
+ return function(path95) {
4908
+ return baseInvoke(object2, path95, 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(path96) {
4956
- return isKey(path96) ? baseProperty(toKey(path96)) : basePropertyDeep(path96);
4955
+ function property(path95) {
4956
+ return isKey(path95) ? baseProperty(toKey(path95)) : basePropertyDeep(path95);
4957
4957
  }
4958
4958
  function propertyOf(object2) {
4959
- return function(path96) {
4960
- return object2 == null ? undefined2 : baseGet(object2, path96);
4959
+ return function(path95) {
4960
+ return object2 == null ? undefined2 : baseGet(object2, path95);
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(path96, args) {
5414
- if (typeof path96 == "function") {
5413
+ LazyWrapper.prototype.invokeMap = baseRest(function(path95, args) {
5414
+ if (typeof path95 == "function") {
5415
5415
  return new LazyWrapper(this);
5416
5416
  }
5417
5417
  return this.map(function(value) {
5418
- return baseInvoke(value, path96, args);
5418
+ return baseInvoke(value, path95, args);
5419
5419
  });
5420
5420
  });
5421
5421
  LazyWrapper.prototype.reject = function(predicate) {
@@ -6367,10 +6367,10 @@ function mergeDefs(...defs) {
6367
6367
  function cloneDef(schema) {
6368
6368
  return mergeDefs(schema._zod.def);
6369
6369
  }
6370
- function getElementAtPath(obj, path96) {
6371
- if (!path96)
6370
+ function getElementAtPath(obj, path95) {
6371
+ if (!path95)
6372
6372
  return obj;
6373
- return path96.reduce((acc, key2) => acc?.[key2], obj);
6373
+ return path95.reduce((acc, key2) => acc?.[key2], obj);
6374
6374
  }
6375
6375
  function promiseAllObject(promisesObj) {
6376
6376
  const keys = Object.keys(promisesObj);
@@ -6710,11 +6710,11 @@ function explicitlyAborted(x, startIndex = 0) {
6710
6710
  }
6711
6711
  return false;
6712
6712
  }
6713
- function prefixIssues(path96, issues) {
6713
+ function prefixIssues(path95, issues) {
6714
6714
  return issues.map((iss) => {
6715
6715
  var _a3;
6716
6716
  (_a3 = iss).path ?? (_a3.path = []);
6717
- iss.path.unshift(path96);
6717
+ iss.path.unshift(path95);
6718
6718
  return iss;
6719
6719
  });
6720
6720
  }
@@ -7164,16 +7164,16 @@ function flattenError(error62, mapper = (issue2) => issue2.message) {
7164
7164
  }
7165
7165
  function formatError(error62, mapper = (issue2) => issue2.message) {
7166
7166
  const fieldErrors = { _errors: [] };
7167
- const processError = (error63, path96 = []) => {
7167
+ const processError = (error63, path95 = []) => {
7168
7168
  for (const issue2 of error63.issues) {
7169
7169
  if (issue2.code === "invalid_union" && issue2.errors.length) {
7170
- issue2.errors.map((issues) => processError({ issues }, [...path96, ...issue2.path]));
7170
+ issue2.errors.map((issues) => processError({ issues }, [...path95, ...issue2.path]));
7171
7171
  } else if (issue2.code === "invalid_key") {
7172
- processError({ issues: issue2.issues }, [...path96, ...issue2.path]);
7172
+ processError({ issues: issue2.issues }, [...path95, ...issue2.path]);
7173
7173
  } else if (issue2.code === "invalid_element") {
7174
- processError({ issues: issue2.issues }, [...path96, ...issue2.path]);
7174
+ processError({ issues: issue2.issues }, [...path95, ...issue2.path]);
7175
7175
  } else {
7176
- const fullpath = [...path96, ...issue2.path];
7176
+ const fullpath = [...path95, ...issue2.path];
7177
7177
  if (fullpath.length === 0) {
7178
7178
  fieldErrors._errors.push(mapper(issue2));
7179
7179
  } else {
@@ -7212,17 +7212,17 @@ function formatError(error62, mapper = (issue2) => issue2.message) {
7212
7212
  }
7213
7213
  function treeifyError(error62, mapper = (issue2) => issue2.message) {
7214
7214
  const result = { errors: [] };
7215
- const processError = (error63, path96 = []) => {
7215
+ const processError = (error63, path95 = []) => {
7216
7216
  var _a3;
7217
7217
  for (const issue2 of error63.issues) {
7218
7218
  if (issue2.code === "invalid_union" && issue2.errors.length) {
7219
- issue2.errors.map((issues) => processError({ issues }, [...path96, ...issue2.path]));
7219
+ issue2.errors.map((issues) => processError({ issues }, [...path95, ...issue2.path]));
7220
7220
  } else if (issue2.code === "invalid_key") {
7221
- processError({ issues: issue2.issues }, [...path96, ...issue2.path]);
7221
+ processError({ issues: issue2.issues }, [...path95, ...issue2.path]);
7222
7222
  } else if (issue2.code === "invalid_element") {
7223
- processError({ issues: issue2.issues }, [...path96, ...issue2.path]);
7223
+ processError({ issues: issue2.issues }, [...path95, ...issue2.path]);
7224
7224
  } else {
7225
- const fullpath = [...path96, ...issue2.path];
7225
+ const fullpath = [...path95, ...issue2.path];
7226
7226
  if (fullpath.length === 0) {
7227
7227
  result.errors.push(mapper(issue2));
7228
7228
  continue;
@@ -7261,8 +7261,8 @@ function treeifyError(error62, mapper = (issue2) => issue2.message) {
7261
7261
  }
7262
7262
  function toDotPath(_path) {
7263
7263
  const segs = [];
7264
- const path96 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
7265
- for (const seg of path96) {
7264
+ const path95 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
7265
+ for (const seg of path95) {
7266
7266
  if (typeof seg === "number")
7267
7267
  segs.push(`[${seg}]`);
7268
7268
  else if (typeof seg === "symbol")
@@ -24364,13 +24364,13 @@ function resolveRef(ref, ctx) {
24364
24364
  if (!ref.startsWith("#")) {
24365
24365
  throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
24366
24366
  }
24367
- const path96 = ref.slice(1).split("/").filter(Boolean);
24368
- if (path96.length === 0) {
24367
+ const path95 = ref.slice(1).split("/").filter(Boolean);
24368
+ if (path95.length === 0) {
24369
24369
  return ctx.rootSchema;
24370
24370
  }
24371
24371
  const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
24372
- if (path96[0] === defsKey) {
24373
- const key2 = path96[1] === void 0 ? void 0 : decodeJSONPointerSegment(path96[1]);
24372
+ if (path95[0] === defsKey) {
24373
+ const key2 = path95[1] === void 0 ? void 0 : decodeJSONPointerSegment(path95[1]);
24374
24374
  if (!key2 || !ctx.defs[key2]) {
24375
24375
  throw new Error(`Reference not found: ${ref}`);
24376
24376
  }
@@ -25688,7 +25688,7 @@ var ToolchainsSchema = external_exports.strictObject({
25688
25688
  }),
25689
25689
  unreal: external_exports.strictObject({
25690
25690
  enabled: enabled(
25691
- "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.",
25691
+ "Unreal Engine development: Visual Studio Community 2022 with the C++ game workload (MSVC, a Windows 11 SDK, .NET Framework targeting packs, Unreal integration and the Epic Games Launcher) and the DirectX End-User Runtime. Visual Studio is installed once and kept on the data disk (~6.5 GB); later boots put it back in seconds. The engine itself comes from the Epic Games Launcher or its source.",
25692
25692
  "a .uproject or .uplugin"
25693
25693
  ),
25694
25694
  acceptLicense: external_exports.boolean().describe(
@@ -25697,11 +25697,8 @@ var ToolchainsSchema = external_exports.strictObject({
25697
25697
  components: StringsSchema.describe(
25698
25698
  'More Visual Studio workload or component IDs to add, e.g. ["Microsoft.VisualStudio.Component.VC.Llvm.Clang"].'
25699
25699
  ),
25700
- keepInstallFiles: external_exports.boolean().describe(
25701
- "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."
25702
- ),
25703
- visualStudio: external_exports.enum(["full", "autosdk"]).describe(
25704
- `"full": install Visual Studio Community (the engine finds it through the Setup API; ~10 GB, redone every boot). "autosdk" (experimental): skip Visual Studio and build an Unreal AutoSDK tree from the portable MSVC in tools\\unreal\\autosdk (kept between sandboxes); UnrealBuildTool finds MSVC through AutoSDK, but the editor's Visual Studio integration is not available. Needs toolchains.msvc (turned on for you).`
25700
+ visualStudio: external_exports.enum(["full", "buildtools"]).describe(
25701
+ '"full": Visual Studio Community with the C++ game workload (the IDE, its debugger and Unreal integration). "buildtools": only the Visual Studio Build Tools (MSVC, the Windows SDK and the .NET Framework parts UnrealBuildTool needs; no IDE). Either is installed once and kept on the data disk (tools\\visualstudio\\persist, ~6.5 GB for Community); later boots put it back in seconds.'
25705
25702
  ),
25706
25703
  persistEngines: external_exports.boolean().describe(
25707
25704
  "Engines the Epic Games Launcher installs go to tools\\unreal\\engines (kept between sandboxes, 40-60 GB each) and are registered with the launcher again every boot. Off: they go on the sandbox disk and are lost when it closes. Engines installed on this PC can be mapped instead (pcInstalls.unrealEngines)."
@@ -26935,12 +26932,12 @@ function appsToInstall(apps, gitAccess) {
26935
26932
  return e && !e.setting ? [e] : [];
26936
26933
  });
26937
26934
  const skipped = chosen.filter((e) => e.fullGitOnly && gitAccess !== "full").map((e) => e.name + ' (needs provisioning.git.access "full")');
26938
- const allowed = [
26935
+ const allowed2 = [
26939
26936
  ...chosen.filter((e) => !(e.fullGitOnly && gitAccess !== "full")),
26940
26937
  ...Object.entries(apps.custom).map(([id, app]) => customEntry(id, app))
26941
26938
  ];
26942
- const needs7zip = allowed.some((e) => e.needs?.includes("7zip") || e.unpack === "nsis") && !allowed.some((e) => e.id === "7zip");
26943
- return { entries: [...needs7zip ? [appById("7zip")] : [], ...allowed], skipped };
26939
+ const needs7zip = allowed2.some((e) => e.needs?.includes("7zip") || e.unpack === "nsis") && !allowed2.some((e) => e.id === "7zip");
26940
+ return { entries: [...needs7zip ? [appById("7zip")] : [], ...allowed2], skipped };
26944
26941
  }
26945
26942
  function appsNeedUv(apps) {
26946
26943
  return Boolean(
@@ -28086,6 +28083,16 @@ var toolsDir = path9.join(dataDir, "tools");
28086
28083
  var logsDir = path9.join(dataDir, "logs");
28087
28084
  var run = new RunDir(dataDir);
28088
28085
 
28086
+ // src/guest/runtime/log-line.ts
28087
+ var ESCAPES = /\x1b\[[0-9;?]{0,32}[A-Za-z]/g;
28088
+ function plainText(text) {
28089
+ return text.replace(ESCAPES, "");
28090
+ }
28091
+ function fileLines(message, at = /* @__PURE__ */ new Date(), task) {
28092
+ const stamp = at.toISOString() + " " + (task ? "[" + task + "] " : "");
28093
+ return plainText(message).split(/\r?\n/).filter((line) => line.trim() !== "").map((line) => stamp + line.trimEnd());
28094
+ }
28095
+
28089
28096
  // src/guest/runtime/log.ts
28090
28097
  fs8.mkdirSync(logsDir, { recursive: true });
28091
28098
  var logFile = path10.join(
@@ -28093,33 +28100,30 @@ var logFile = path10.join(
28093
28100
  (process.env.AGENT_LOG_PREFIX ?? "guest") + "-" + (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-") + ".log"
28094
28101
  );
28095
28102
  var context = new AsyncLocalStorage();
28103
+ var sink = null;
28096
28104
  function runQuiet(work) {
28097
28105
  return context.run({ ...context.getStore(), quiet: true }, work);
28098
28106
  }
28099
- function fileLine(message, at = /* @__PURE__ */ new Date()) {
28100
- return at.toISOString() + " " + message;
28101
- }
28102
- var append = (line) => {
28107
+ var append = (message, ctx) => {
28103
28108
  try {
28104
- fs8.appendFileSync(logFile, fileLine(line) + "\n");
28109
+ const lines = fileLines(message, /* @__PURE__ */ new Date(), ctx?.task);
28110
+ if (lines.length) fs8.appendFileSync(logFile, lines.join("\n") + "\n");
28105
28111
  } catch {
28106
28112
  }
28107
28113
  };
28108
- var tagged = (message, ctx) => {
28109
- const prefix = ctx?.prefix?.();
28110
- return prefix ? prefix + " | " + message : message;
28111
- };
28112
28114
  function log(message) {
28113
28115
  const ctx = context.getStore();
28114
- const line = tagged(message, ctx);
28115
- if (!ctx?.quiet) console.log(line);
28116
- append(line);
28116
+ append(message, ctx);
28117
+ if (ctx?.quiet) return;
28118
+ if (sink) sink.line(message, ctx?.stage);
28119
+ else console.log(message);
28117
28120
  }
28118
28121
  function warn(message) {
28119
28122
  const ctx = context.getStore();
28120
- const line = tagged(message, ctx);
28121
- if (!ctx?.quiet) console.warn("\x1B[33mWARNING: " + line + "\x1B[0m");
28122
- append("WARNING: " + line);
28123
+ append("WARNING: " + message, ctx);
28124
+ if (ctx?.quiet) return;
28125
+ if (sink) sink.warning(message);
28126
+ else console.warn("\x1B[33mWARNING: " + message + "\x1B[0m");
28123
28127
  }
28124
28128
 
28125
28129
  // src/guest/runtime/session.ts
@@ -28917,27 +28921,82 @@ import fs16 from "node:fs";
28917
28921
  import os3 from "node:os";
28918
28922
  import path19 from "node:path";
28919
28923
  import { spawn as spawn2, spawnSync as spawnSync2 } from "node:child_process";
28924
+ var outputSink = null;
28925
+ var captureOutput = () => outputSink?.capturing() ?? false;
28926
+ function logOutput(text) {
28927
+ for (const line of text.split(/\r?\n/)) if (line.trim()) outputSink?.line(line.trimEnd());
28928
+ }
28929
+ var CAPTURE_BYTES = 64 * 1024 * 1024;
28930
+ var LINE_CHARS = 2e3;
28931
+ function logLines(stream) {
28932
+ if (!stream) return;
28933
+ let partial2 = "";
28934
+ stream.setEncoding("utf8");
28935
+ stream.on("data", (chunk) => {
28936
+ const lines = (partial2 + chunk).split(/\r?\n/);
28937
+ partial2 = lines.pop().slice(0, LINE_CHARS);
28938
+ logOutput(lines.map((l) => l.slice(0, LINE_CHARS)).join("\n"));
28939
+ });
28940
+ stream.on("end", () => logOutput(partial2));
28941
+ }
28920
28942
  async function execAsync(file3, args, options = {}) {
28921
- const code = await spawnAsync(file3, args, { stdio: "inherit", ...options });
28943
+ const code = captureOutput() ? await new Promise((resolve2, reject) => {
28944
+ const child = spawn2(file3, args, { stdio: ["inherit", "pipe", "pipe"], windowsHide: true, ...options });
28945
+ logLines(child.stdout);
28946
+ logLines(child.stderr);
28947
+ child.once("error", reject);
28948
+ child.once("close", (c) => resolve2(c ?? -1));
28949
+ }) : await spawnAsync(file3, args, { stdio: "inherit", ...options });
28922
28950
  if (code !== 0)
28923
28951
  throw new Error(path19.basename(file3) + " " + args.slice(0, 3).join(" ") + " failed with exit code " + code);
28924
28952
  }
28953
+ function scriptErrors(errors) {
28954
+ if (!errors) return;
28955
+ if (captureOutput()) logOutput(errors);
28956
+ else process.stderr.write(errors + "\n");
28957
+ }
28925
28958
  function execOutput(file3, args, options = {}) {
28926
28959
  const result = spawnSync2(file3, args, { encoding: "utf8", windowsHide: true, ...options });
28927
28960
  return result.status === 0 ? String(result.stdout ?? "").trim() : "";
28928
28961
  }
28929
28962
  function runScript(name, args = []) {
28963
+ const capture = captureOutput();
28930
28964
  const result = spawnSync2(SYSTEM.powershell(), scriptArgs(name, args), {
28931
- stdio: ["inherit", "inherit", "pipe"],
28965
+ stdio: ["inherit", capture ? "pipe" : "inherit", "pipe"],
28932
28966
  encoding: "utf8",
28933
- windowsHide: true
28967
+ windowsHide: true,
28968
+ ...capture ? { maxBuffer: CAPTURE_BYTES } : {}
28934
28969
  });
28970
+ if (capture) logOutput(String(result.stdout ?? ""));
28935
28971
  if (result.error) throw result.error;
28936
28972
  const errors = String(result.stderr ?? "").trim();
28937
- if (errors) process.stderr.write(errors + "\n");
28973
+ scriptErrors(errors);
28938
28974
  if (result.status !== 0)
28939
28975
  throw new Error(name + " failed with exit code " + result.status + (errors ? ": " + errors.slice(0, 400) : ""));
28940
28976
  }
28977
+ function runScriptAsync(name, args = []) {
28978
+ return new Promise((resolve2, reject) => {
28979
+ const capture = captureOutput();
28980
+ const child = spawn2(SYSTEM.powershell(), scriptArgs(name, args), {
28981
+ stdio: ["inherit", capture ? "pipe" : "inherit", "pipe"],
28982
+ windowsHide: true
28983
+ });
28984
+ if (capture) logLines(child.stdout);
28985
+ let errors = "";
28986
+ child.stderr?.setEncoding("utf8");
28987
+ child.stderr?.on("data", (chunk) => {
28988
+ if (errors.length < 4096) errors += chunk;
28989
+ });
28990
+ child.once("error", reject);
28991
+ child.once("close", (code) => {
28992
+ errors = errors.trim();
28993
+ scriptErrors(errors);
28994
+ if (code !== 0)
28995
+ reject(new Error(name + " failed with exit code " + code + (errors ? ": " + errors.slice(0, 400) : "")));
28996
+ else resolve2();
28997
+ });
28998
+ });
28999
+ }
28941
29000
  function scriptOutput(name, args = [], options = {}) {
28942
29001
  return execOutput(SYSTEM.powershell(), scriptArgs(name, args), options);
28943
29002
  }
@@ -28951,6 +29010,16 @@ function runScriptWithJson(name, param, data, args = []) {
28951
29010
  fs16.rmSync(dir, { recursive: true, force: true });
28952
29011
  }
28953
29012
  }
29013
+ async function runScriptWithJsonAsync(name, param, data, args = []) {
29014
+ const dir = fs16.mkdtempSync(path19.join(os3.tmpdir(), "sbx-"));
29015
+ const file3 = path19.join(dir, "input.json");
29016
+ try {
29017
+ fs16.writeFileSync(file3, JSON.stringify(data), "utf8");
29018
+ await runScriptAsync(name, ["-" + param, file3, ...args]);
29019
+ } finally {
29020
+ fs16.rmSync(dir, { recursive: true, force: true });
29021
+ }
29022
+ }
28954
29023
  function robocopy(from, to, files = []) {
28955
29024
  if (!isWin) {
28956
29025
  if (!files.length) {
@@ -29050,7 +29119,7 @@ function execHeavy(file3, args, options = {}) {
29050
29119
  }
29051
29120
 
29052
29121
  // src/guest/daemon/daemon.ts
29053
- import fs76 from "node:fs";
29122
+ import fs75 from "node:fs";
29054
29123
 
29055
29124
  // src/guest/setup/claude-mem.ts
29056
29125
  import fs17 from "node:fs";
@@ -29163,6 +29232,9 @@ function localStateEntries(agents2, stateDir3, localRoot2) {
29163
29232
  );
29164
29233
  }
29165
29234
  var CODEX_MARKER = "# Set by the sandbox";
29235
+ var CODEX_MARKER_LINE = CODEX_MARKER + " from its codex settings (`sandbox config`); a line of your own without it wins.";
29236
+ var CODEX_MARKERS = [CODEX_MARKER, "# agent-sandbox:"];
29237
+ var CODEX_OWNED_KEYS = ["sandbox_mode", "approval_policy", "model", "model_reasoning_effort"];
29166
29238
  function codexArguments(c) {
29167
29239
  const out = c.sandboxMode === "danger-full-access" && c.approvalPolicy === "never" ? ["--dangerously-bypass-approvals-and-sandbox"] : ["--sandbox", c.sandboxMode, "--ask-for-approval", c.approvalPolicy];
29168
29240
  if (c.model) out.push("-c", 'model="' + c.model + '"');
@@ -29174,7 +29246,7 @@ function agentArguments(name, harness, codex) {
29174
29246
  }
29175
29247
  var MAX_CODEX_CONFIG_BYTES = 1024 * 1024;
29176
29248
  var MARKED_LINES = new RegExp(
29177
- "^" + CODEX_MARKER + "[^\r\n]*\r?\n(?:(?:sandbox_mode|approval_policy)[ ]*=[^\r\n]*\r?\n)*(?:[ ]*\r?\n)?",
29249
+ "^(?:" + CODEX_MARKERS.join("|") + ")[^\r\n]*\r?\n(?:(?:" + CODEX_OWNED_KEYS.join("|") + ")[ ]*=[^\r\n]*(?:\r?\n|$))*(?:[ ]*\r?\n)?",
29178
29250
  "m"
29179
29251
  );
29180
29252
  var isDatabaseFile = (name) => /\.(sqlite3?|db)(-wal|-shm)?$/i.test(name);
@@ -29318,6 +29390,17 @@ function planPath(input2) {
29318
29390
  }
29319
29391
  return msvcBeforeGitUsr(result);
29320
29392
  }
29393
+ function sessionPath(o) {
29394
+ const seen = /* @__PURE__ */ new Set();
29395
+ const result = [];
29396
+ for (const folder of [o.commands, ...o.prepend, ...o.base, ...o.append]) {
29397
+ const key2 = pathKey(folder);
29398
+ if (!folder.trim() || seen.has(key2)) continue;
29399
+ seen.add(key2);
29400
+ result.push(folder);
29401
+ }
29402
+ return msvcBeforeGitUsr(result);
29403
+ }
29321
29404
  function appendMissing(base, extra, skip = () => false) {
29322
29405
  const seen = new Set(splitPath(base).map(pathKey));
29323
29406
  const added = splitPath(extra).filter((folder) => {
@@ -29415,7 +29498,12 @@ function agentEnv(tools, target = { workspace, project: session.project, base: p
29415
29498
  mkdirp(dir);
29416
29499
  const runners = [path25.join(toolsDir, "node"), path25.dirname(process.execPath)].map((d) => d.toLowerCase());
29417
29500
  const base = (target.base.PATH ?? "").split(path25.delimiter).filter((d) => d && !runners.includes(d.toLowerCase()));
29418
- env.PATH = msvcBeforeGitUsr([.../* @__PURE__ */ new Set([...tools.prepend, ...base, ...tools.append])]).join(path25.delimiter);
29501
+ env.PATH = sessionPath({
29502
+ commands: path25.join(localDir, "bin"),
29503
+ prepend: tools.prepend,
29504
+ base,
29505
+ append: tools.append
29506
+ }).join(path25.delimiter);
29419
29507
  return env;
29420
29508
  }
29421
29509
  function addMachineEnvironment(vars, dirs, additive = false) {
@@ -29452,8 +29540,8 @@ function withRegistryPath(env) {
29452
29540
  }
29453
29541
 
29454
29542
  // src/guest/daemon/project-provisioner.ts
29455
- import fs66 from "node:fs";
29456
- import path84 from "node:path";
29543
+ import fs65 from "node:fs";
29544
+ import path83 from "node:path";
29457
29545
 
29458
29546
  // src/guest/boot/boot-env.ts
29459
29547
  import fs19 from "node:fs";
@@ -29766,7 +29854,7 @@ async function runHooksAsync(stage, env, target) {
29766
29854
  }
29767
29855
 
29768
29856
  // src/guest/toolchains/setup.ts
29769
- import fs65 from "node:fs";
29857
+ import fs64 from "node:fs";
29770
29858
 
29771
29859
  // src/guest/apps/app-installer.ts
29772
29860
  import fs32 from "node:fs";
@@ -32915,7 +33003,7 @@ async function setupMsvc(env, config2) {
32915
33003
 
32916
33004
  // src/guest/toolchains/native/unreal.ts
32917
33005
  import os10 from "node:os";
32918
- import path68 from "node:path";
33006
+ import path67 from "node:path";
32919
33007
 
32920
33008
  // src/guest/toolchains/not-yet.ts
32921
33009
  function notAvailableYet2(_env, what) {
@@ -32927,132 +33015,10 @@ async function setupUnrealEngines(env, _config, _ctx) {
32927
33015
  notAvailableYet2(env, "Unreal engines");
32928
33016
  }
32929
33017
 
32930
- // src/guest/toolchains/native/autosdk.ts
32931
- import fs50 from "node:fs";
32932
- import path65 from "node:path";
32933
-
32934
- // src/guest/toolchains/native/vs-request.ts
32935
- import path64 from "node:path";
32936
- var UNREAL_COMPONENTS = [
32937
- "Microsoft.VisualStudio.Workload.NativeGame",
32938
- "Microsoft.VisualStudio.Component.VC.Tools.x86.x64",
32939
- "Microsoft.VisualStudio.Component.Windows11SDK.22621",
32940
- "Microsoft.VisualStudio.Component.VC.DiagnosticTools",
32941
- "Microsoft.Net.Component.4.6.2.TargetingPack",
32942
- "Microsoft.Net.Component.4.8.SDK",
32943
- "Component.Unreal.Ide",
32944
- "Component.Unreal"
32945
- ];
32946
- var BUILD_TOOLS_COMPONENTS = [
32947
- "Microsoft.VisualStudio.Workload.VCTools",
32948
- "Microsoft.VisualStudio.Component.VC.Tools.x86.x64",
32949
- "Microsoft.VisualStudio.Component.Windows11SDK.22621"
32950
- ];
32951
- var isOn = (setting) => setting === true;
32952
- function visualStudioWanted(t, on = isOn) {
32953
- const unreal = on(t.unreal.enabled, "unreal") && t.unreal.visualStudio === "full";
32954
- const flutter = on(t.flutter.enabled, "flutter") && t.flutter.windowsDesktop;
32955
- const unity = on(t.unity.enabled, "unity") && t.unity.modules.includes("windows-il2cpp");
32956
- const users = [...unreal ? ["unreal"] : [], ...flutter ? ["flutter"] : [], ...unity ? ["unity"] : []];
32957
- if (!users.length) return null;
32958
- if (unreal)
32959
- return {
32960
- product: "community",
32961
- components: [.../* @__PURE__ */ new Set([...UNREAL_COMPONENTS, ...t.unreal.components])],
32962
- for: users,
32963
- licence: "toolchains.unreal.acceptLicense",
32964
- accepted: t.unreal.acceptLicense
32965
- };
32966
- return {
32967
- product: "buildtools",
32968
- components: [...BUILD_TOOLS_COMPONENTS],
32969
- for: users,
32970
- licence: "toolchains.msvc.acceptLicense",
32971
- accepted: t.msvc.acceptLicense
32972
- };
32973
- }
32974
- function unrealUsesAutosdk(t, on = isOn) {
32975
- return on(t.unreal.enabled, "unreal") && t.unreal.visualStudio === "autosdk";
32976
- }
32977
- function vsExitText(code) {
32978
- const c = code >>> 0;
32979
- switch (c) {
32980
- case 0:
32981
- return "installed";
32982
- case 3010:
32983
- return "done; a restart would finish it (not needed here)";
32984
- case 1602:
32985
- return "cancelled";
32986
- case 5007:
32987
- return "the installer refused to run (blocked by Windows, for example a restart waiting)";
32988
- case 8006:
32989
- return "Visual Studio is running and must be closed first";
32990
- case 3762504530:
32991
- return "0xE0434352: the Visual Studio installer crashed";
32992
- default:
32993
- return "the installer failed with exit " + c + " (0x" + c.toString(16).toUpperCase() + ")";
32994
- }
32995
- }
32996
- var LAYOUT_STAGING_BYTES = 8 * 1024 ** 3;
32997
- var STAGING_RESERVE_BYTES = 1.5 * 1024 ** 3;
32998
- function layoutNextStep(exit, localFreeBytes, reserveBytes) {
32999
- if (exit !== null && (exit === 0 || exit === 3010)) return "done";
33000
- return localFreeBytes >= LAYOUT_STAGING_BYTES + reserveBytes ? "stage" : "skip";
33001
- }
33002
- function autosdkLayout(msvcRoot, msvc, sdk, autosdkRoot) {
33003
- const win64 = path64.win32.join(autosdkRoot, "HostWin64", "Win64");
33004
- return [
33005
- {
33006
- from: path64.win32.join(msvcRoot, "VC", "Tools", "MSVC", msvc),
33007
- to: path64.win32.join(win64, "VS2022", msvc)
33008
- },
33009
- ...["Include", "Lib", "bin"].map((part) => ({
33010
- from: path64.win32.join(msvcRoot, "Windows Kits", "10", part, sdk),
33011
- to: path64.win32.join(win64, "Windows Kits", "10", part, sdk)
33012
- }))
33013
- ];
33014
- }
33015
-
33016
- // src/guest/toolchains/native/autosdk.ts
33017
- var AUTOSDK_DIR = tool("unreal", "autosdk");
33018
- var MARKER3 = path65.join(AUTOSDK_DIR, ".complete.json");
33019
- var MarkerSchema = external_exports.object({ msvc: external_exports.string(), sdk: external_exports.string() });
33020
- function builtFor(msvc, sdk) {
33021
- try {
33022
- const done = MarkerSchema.parse(JSON.parse(fs50.readFileSync(MARKER3, "utf8")));
33023
- return done.msvc === msvc && done.sdk === sdk;
33024
- } catch {
33025
- return false;
33026
- }
33027
- }
33028
- async function setupAutosdk(env) {
33029
- const msvc = readInstalled();
33030
- if (!msvc || !hasCompiler(msvc.msvc))
33031
- throw new Error(
33032
- 'toolchains.unreal.visualStudio = "autosdk" builds from the portable MSVC, which is not installed (is toolchains.msvc off?)'
33033
- );
33034
- if (!builtFor(msvc.msvc, msvc.sdk)) {
33035
- log("Making the Unreal AutoSDK from MSVC " + msvc.msvc + " (~2 GB, once) ...");
33036
- fs50.rmSync(MARKER3, { force: true });
33037
- for (const pair of autosdkLayout(ROOT, msvc.msvc, msvc.sdk, AUTOSDK_DIR)) {
33038
- mkdirp(pair.to);
33039
- const code = await spawnAsync(SYSTEM.robocopy(), [pair.from, pair.to, "/E", "/COPY:DAT", "/R:1", "/W:1", "/NP"]);
33040
- if (robocopyFailed(code))
33041
- throw new Error("could not copy " + pair.from + " into the AutoSDK (robocopy " + code + ")");
33042
- }
33043
- writeJsonAtomic(MARKER3, { msvc: msvc.msvc, sdk: msvc.sdk });
33044
- }
33045
- if (!exists(MARKER3)) throw new Error("the Unreal AutoSDK was not completed");
33046
- env.vars["UE_SDKS_ROOT"] = AUTOSDK_DIR;
33047
- env.summary.push(
33048
- "unreal autosdk: MSVC " + msvc.msvc + ", Windows SDK " + msvc.sdk + " (UE_SDKS_ROOT=" + AUTOSDK_DIR + ")"
33049
- );
33050
- }
33051
-
33052
33018
  // src/guest/toolchains/native/visual-studio.ts
33053
- import fs52 from "node:fs";
33019
+ import fs51 from "node:fs";
33054
33020
  import os9 from "node:os";
33055
- import path67 from "node:path";
33021
+ import path66 from "node:path";
33056
33022
 
33057
33023
  // src/guest/runtime/status.ts
33058
33024
  import os8 from "node:os";
@@ -33104,8 +33070,8 @@ function writeStatus(phase, message) {
33104
33070
 
33105
33071
  // src/guest/toolchains/persisted.ts
33106
33072
  import crypto6 from "node:crypto";
33107
- import fs51 from "node:fs";
33108
- import path66 from "node:path";
33073
+ import fs50 from "node:fs";
33074
+ import path64 from "node:path";
33109
33075
 
33110
33076
  // src/shared/installs.ts
33111
33077
  var INSTALL_RECORDS_FILE = "installs.json";
@@ -33121,11 +33087,11 @@ var InstallRecordsSchema = external_exports.object({ installs: external_exports.
33121
33087
  // src/guest/toolchains/persisted.ts
33122
33088
  var GB = 1024 ** 3;
33123
33089
  var LOCAL_RESERVE_BYTES = 13 * GB;
33124
- var MARKER4 = ".complete.json";
33090
+ var MARKER3 = ".complete.json";
33125
33091
  var MAX_WALK = 2e6;
33126
33092
  var NAME = /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/;
33127
- var toolsOf = (deps) => deps.toolsDir ?? path66.join(dataDir, "tools");
33128
- var recordsFile = (deps) => path66.join(toolsOf(deps), INSTALL_RECORDS_FILE);
33093
+ var toolsOf = (deps) => deps.toolsDir ?? path64.join(dataDir, "tools");
33094
+ var recordsFile = (deps) => path64.join(toolsOf(deps), INSTALL_RECORDS_FILE);
33129
33095
  function checkSpec(spec) {
33130
33096
  const parts2 = spec.name.split("/");
33131
33097
  if (parts2.length > 2 || !parts2.every((p) => NAME.test(p)) || !NAME.test(spec.version))
@@ -33156,7 +33122,7 @@ function installRecords(deps = {}) {
33156
33122
  return readValid(InstallRecordsSchema, recordsFile(deps))?.installs ?? [];
33157
33123
  }
33158
33124
  function writeRecords(records, deps) {
33159
- fs51.mkdirSync(toolsOf(deps), { recursive: true });
33125
+ fs50.mkdirSync(toolsOf(deps), { recursive: true });
33160
33126
  writeJsonAtomic(recordsFile(deps), { installs: [...records] });
33161
33127
  }
33162
33128
  function recordUse(name, version2, deps = {}) {
@@ -33176,17 +33142,17 @@ function folderSize(dir) {
33176
33142
  const current2 = stack.pop();
33177
33143
  let entries2;
33178
33144
  try {
33179
- entries2 = fs51.readdirSync(current2, { withFileTypes: true });
33145
+ entries2 = fs50.readdirSync(current2, { withFileTypes: true });
33180
33146
  } catch {
33181
33147
  continue;
33182
33148
  }
33183
33149
  for (const e of entries2) {
33184
33150
  if (++seen > MAX_WALK) return null;
33185
- const full = path66.join(current2, e.name);
33151
+ const full = path64.join(current2, e.name);
33186
33152
  if (e.isDirectory()) stack.push(full);
33187
33153
  else if (e.isFile())
33188
33154
  try {
33189
- total += fs51.statSync(full).size;
33155
+ total += fs50.statSync(full).size;
33190
33156
  } catch {
33191
33157
  }
33192
33158
  }
@@ -33194,16 +33160,16 @@ function folderSize(dir) {
33194
33160
  return total;
33195
33161
  }
33196
33162
  function complete(dir, marker) {
33197
- return fs51.existsSync(path66.join(dir, MARKER4)) && fs51.existsSync(path66.join(dir, marker));
33163
+ return fs50.existsSync(path64.join(dir, MARKER3)) && fs50.existsSync(path64.join(dir, marker));
33198
33164
  }
33199
33165
  function prune(spec, deps) {
33200
33166
  if (!spec.keepVersions) return;
33201
- const root = path66.join(toolsOf(deps), ...spec.name.split("/"));
33167
+ const root = path64.join(toolsOf(deps), ...spec.name.split("/"));
33202
33168
  const mine = installRecords(deps).filter((r) => r.name === spec.name && r.version !== spec.version).sort((a, b) => b.usedAt.localeCompare(a.usedAt));
33203
33169
  const gone = mine.slice(Math.max(0, spec.keepVersions - 1));
33204
33170
  for (const r of gone) {
33205
33171
  if (!NAME.test(r.version)) continue;
33206
- safeRemove(path66.join(root, r.version), root);
33172
+ safeRemove(path64.join(root, r.version), root);
33207
33173
  deps.log?.("Removed " + spec.name + " " + r.version + " (keepVersions " + spec.keepVersions + ")");
33208
33174
  }
33209
33175
  const isGone2 = (r) => r.name === spec.name && gone.some((g) => g.version === r.version);
@@ -33215,14 +33181,14 @@ function prune(spec, deps) {
33215
33181
  }
33216
33182
  async function ensurePersisted(spec, install2, deps = {}) {
33217
33183
  checkSpec(spec);
33218
- const root = path66.join(toolsOf(deps), ...spec.name.split("/"));
33219
- const dir = path66.join(root, spec.version);
33184
+ const root = path64.join(toolsOf(deps), ...spec.name.split("/"));
33185
+ const dir = path64.join(root, spec.version);
33220
33186
  if (complete(dir, spec.marker)) {
33221
33187
  recordUse(spec.name, spec.version, deps);
33222
33188
  const known = installRecords(deps).find((r) => r.name === spec.name && r.version === spec.version);
33223
33189
  return { dir, fresh: false, sizeBytes: known?.sizeBytes ?? null };
33224
33190
  }
33225
- fs51.mkdirSync(root, { recursive: true });
33191
+ fs50.mkdirSync(root, { recursive: true });
33226
33192
  assertRoom(
33227
33193
  root,
33228
33194
  spec.needBytes,
@@ -33230,18 +33196,18 @@ async function ensurePersisted(spec, install2, deps = {}) {
33230
33196
  "Free room on that disk (with contained storage: raise storage.containedMaxGb), or keep fewer versions.",
33231
33197
  deps
33232
33198
  );
33233
- const staging = path66.join(root, ".staging-" + spec.version + "-" + crypto6.randomBytes(3).toString("hex"));
33234
- const temp = path66.join(staging, ".temp");
33235
- fs51.mkdirSync(temp, { recursive: true });
33199
+ const staging = path64.join(root, ".staging-" + spec.version + "-" + crypto6.randomBytes(3).toString("hex"));
33200
+ const temp = path64.join(staging, ".temp");
33201
+ fs50.mkdirSync(temp, { recursive: true });
33236
33202
  try {
33237
33203
  await install2(staging, temp);
33238
- if (!fs51.existsSync(path66.join(staging, spec.marker)))
33204
+ if (!fs50.existsSync(path64.join(staging, spec.marker)))
33239
33205
  throw new Error(spec.what + ": the install finished without " + spec.marker);
33240
33206
  safeRemove(temp, staging);
33241
33207
  const sizeBytes = folderSize(staging);
33242
- writeJsonAtomic(path66.join(staging, MARKER4), { name: spec.name, version: spec.version, sizeBytes });
33243
- if (fs51.existsSync(dir)) safeRemove(dir, root);
33244
- fs51.renameSync(staging, dir);
33208
+ writeJsonAtomic(path64.join(staging, MARKER3), { name: spec.name, version: spec.version, sizeBytes });
33209
+ if (fs50.existsSync(dir)) safeRemove(dir, root);
33210
+ fs50.renameSync(staging, dir);
33245
33211
  const now2 = (/* @__PURE__ */ new Date()).toISOString();
33246
33212
  writeRecords(
33247
33213
  [
@@ -33253,8 +33219,295 @@ async function ensurePersisted(spec, install2, deps = {}) {
33253
33219
  prune(spec, deps);
33254
33220
  return { dir, fresh: true, sizeBytes };
33255
33221
  } finally {
33256
- if (fs51.existsSync(staging)) safeRemove(staging, root);
33222
+ if (fs50.existsSync(staging)) safeRemove(staging, root);
33223
+ }
33224
+ }
33225
+
33226
+ // src/guest/toolchains/native/vs-request.ts
33227
+ var UNREAL_COMPONENTS = [
33228
+ "Microsoft.VisualStudio.Workload.NativeGame",
33229
+ "Microsoft.VisualStudio.Component.VC.Tools.x86.x64",
33230
+ "Microsoft.VisualStudio.Component.Windows11SDK.22621",
33231
+ "Microsoft.VisualStudio.Component.VC.DiagnosticTools",
33232
+ "Microsoft.Net.Component.4.6.2.TargetingPack",
33233
+ "Microsoft.Net.Component.4.8.SDK",
33234
+ "Component.Unreal.Ide",
33235
+ "Component.Unreal"
33236
+ ];
33237
+ var BUILD_TOOLS_COMPONENTS = [
33238
+ "Microsoft.VisualStudio.Workload.VCTools",
33239
+ "Microsoft.VisualStudio.Component.VC.Tools.x86.x64",
33240
+ "Microsoft.VisualStudio.Component.Windows11SDK.22621"
33241
+ ];
33242
+ var UNREAL_BUILD_TOOLS_COMPONENTS = [
33243
+ ...BUILD_TOOLS_COMPONENTS,
33244
+ "Microsoft.Net.Component.4.6.2.TargetingPack",
33245
+ "Microsoft.Net.Component.4.8.SDK"
33246
+ ];
33247
+ var isOn = (setting) => setting === true;
33248
+ function visualStudioWanted(t, on = isOn) {
33249
+ const unreal = on(t.unreal.enabled, "unreal");
33250
+ const flutter = on(t.flutter.enabled, "flutter") && t.flutter.windowsDesktop;
33251
+ const unity = on(t.unity.enabled, "unity") && t.unity.modules.includes("windows-il2cpp");
33252
+ const users = [...unreal ? ["unreal"] : [], ...flutter ? ["flutter"] : [], ...unity ? ["unity"] : []];
33253
+ if (!users.length) return null;
33254
+ if (unreal) {
33255
+ const full = t.unreal.visualStudio === "full";
33256
+ return {
33257
+ product: full ? "community" : "buildtools",
33258
+ components: [.../* @__PURE__ */ new Set([...full ? UNREAL_COMPONENTS : UNREAL_BUILD_TOOLS_COMPONENTS, ...t.unreal.components])],
33259
+ for: users,
33260
+ licence: "toolchains.unreal.acceptLicense",
33261
+ accepted: t.unreal.acceptLicense
33262
+ };
33263
+ }
33264
+ return {
33265
+ product: "buildtools",
33266
+ components: [...BUILD_TOOLS_COMPONENTS],
33267
+ for: users,
33268
+ licence: "toolchains.msvc.acceptLicense",
33269
+ accepted: t.msvc.acceptLicense
33270
+ };
33271
+ }
33272
+ function vsExitText(code) {
33273
+ const c = code >>> 0;
33274
+ switch (c) {
33275
+ case 0:
33276
+ return "installed";
33277
+ case 3010:
33278
+ return "done; a restart would finish it (not needed here)";
33279
+ case 1602:
33280
+ return "cancelled";
33281
+ case 5007:
33282
+ return "the installer refused to run (blocked by Windows, for example a restart waiting)";
33283
+ case 8006:
33284
+ return "Visual Studio is running and must be closed first";
33285
+ case 3762504530:
33286
+ return "0xE0434352: the Visual Studio installer crashed";
33287
+ default:
33288
+ return "the installer failed with exit " + c + " (0x" + c.toString(16).toUpperCase() + ")";
33289
+ }
33290
+ }
33291
+
33292
+ // src/guest/toolchains/native/vs-persist.ts
33293
+ import path65 from "node:path";
33294
+ var win = path65.win32;
33295
+ var MARKER_FILE = ".complete.json";
33296
+ var SETUP_CLSID = "{177F0C4A-1CD3-4DE7-A32C-71DBBB9FA36D}";
33297
+ var SETUP_DLL = "Microsoft.VisualStudio.Setup.Configuration.Native.dll";
33298
+ var INSTANCE_ID = /^[A-Za-z0-9]{1,64}$/;
33299
+ function winPlaces(env) {
33300
+ return {
33301
+ programFiles: env.ProgramFiles ?? "C:\\Program Files",
33302
+ programFilesX86: env["ProgramFiles(x86)"] ?? "C:\\Program Files (x86)",
33303
+ programData: env.ProgramData ?? "C:\\ProgramData"
33304
+ };
33305
+ }
33306
+ var FOLDER_NAMES = [
33307
+ "Community",
33308
+ "BuildTools",
33309
+ "WindowsKits10",
33310
+ "NETFXSDK",
33311
+ "MicrosoftSDKs-v10.0A",
33312
+ "ReferenceAssemblies",
33313
+ "Installer",
33314
+ "Shared",
33315
+ "Setup",
33316
+ "instance"
33317
+ ];
33318
+ function productFolder(product) {
33319
+ return product === "community" ? "Community" : "BuildTools";
33320
+ }
33321
+ function instancesDir(places) {
33322
+ return win.join(places.programData, "Microsoft", "VisualStudio", "Packages", "_Instances");
33323
+ }
33324
+ function persistFolders(vs, places) {
33325
+ if (!INSTANCE_ID.test(vs.instanceId)) throw new Error('"' + vs.instanceId + '" is not a Visual Studio instance ID');
33326
+ const x86 = places.programFilesX86;
33327
+ const one = (name, source, restore, optional2 = false) => ({
33328
+ name,
33329
+ source,
33330
+ restore,
33331
+ optional: optional2
33332
+ });
33333
+ return [
33334
+ one(productFolder(vs.product), vs.installationPath, "stay"),
33335
+ one("WindowsKits10", win.join(x86, "Windows Kits", "10"), "stay"),
33336
+ one("NETFXSDK", win.join(x86, "Windows Kits", "NETFXSDK"), "stay", true),
33337
+ one("MicrosoftSDKs-v10.0A", win.join(x86, "Microsoft SDKs", "Windows", "v10.0A"), "stay", true),
33338
+ // MSBuild looks for the .NET Framework reference assemblies at this fixed path.
33339
+ one(
33340
+ "ReferenceAssemblies",
33341
+ win.join(x86, "Reference Assemblies", "Microsoft", "Framework", ".NETFramework"),
33342
+ "copy-missing",
33343
+ true
33344
+ ),
33345
+ // Scripts and build tools look for vswhere here; the instance's state names setup.exe here too (144 MB).
33346
+ one("Installer", win.join(x86, "Microsoft Visual Studio", "Installer"), "copy"),
33347
+ one("Shared", win.join(x86, "Microsoft Visual Studio", "Shared"), "copy", true),
33348
+ one("Setup", win.join(places.programData, "Microsoft", "VisualStudio", "Setup"), "copy"),
33349
+ one("instance", win.join(instancesDir(places), vs.instanceId), "copy")
33350
+ ];
33351
+ }
33352
+ var RegEntrySchema = external_exports.strictObject({
33353
+ view: external_exports.enum(["64", "32"]),
33354
+ /** Under HKLM, e.g. SOFTWARE\Microsoft\Microsoft SDKs\Windows\v10.0 (the view picks WOW6432Node). */
33355
+ key: external_exports.string().min(1).max(400),
33356
+ /** '' is the default value. */
33357
+ name: external_exports.string().max(200),
33358
+ kind: external_exports.enum(["string", "expand", "dword"]),
33359
+ value: external_exports.union([external_exports.string().max(2e3), external_exports.number().int()])
33360
+ });
33361
+ var REGISTRY_READS = [
33362
+ { key: "SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots", names: ["KitsRoot10"], recurse: false },
33363
+ { key: "SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\v10.0", names: null, recurse: false },
33364
+ { key: "SOFTWARE\\Microsoft\\Microsoft SDKs\\NETFXSDK", names: null, recurse: true },
33365
+ { key: "SOFTWARE\\Microsoft\\VisualStudio\\Setup", names: null, recurse: false }
33366
+ ];
33367
+ var VIEWS = ["64", "32"];
33368
+ var VsPersistMarkerSchema = external_exports.strictObject({
33369
+ product: external_exports.enum(["community", "buildtools"]),
33370
+ /** The installed version (17.14.37827.9). */
33371
+ version: external_exports.string().min(1).max(100),
33372
+ /** The component IDs it was installed with. */
33373
+ components: external_exports.array(external_exports.string().max(200)).max(500),
33374
+ instanceId: external_exports.string().regex(INSTANCE_ID),
33375
+ /** Where the installer put it (the paths in its state and the registry are rewritten from this). */
33376
+ installationPath: external_exports.string().min(3).max(400),
33377
+ /** The Windows SDK's ProductVersion (10.0.22621), '' when there is none. */
33378
+ sdkVersion: external_exports.string().max(50),
33379
+ folders: external_exports.array(external_exports.enum(FOLDER_NAMES)).max(FOLDER_NAMES.length),
33380
+ /** The registry values as the installer wrote them (paths on C:). */
33381
+ registry: external_exports.array(RegEntrySchema).max(500),
33382
+ capturedAt: external_exports.string().max(50)
33383
+ });
33384
+ var SaveResultSchema = external_exports.strictObject({
33385
+ copied: external_exports.array(external_exports.enum(FOLDER_NAMES)).max(FOLDER_NAMES.length),
33386
+ registry: external_exports.array(RegEntrySchema).max(500)
33387
+ });
33388
+ var needed = (product) => [
33389
+ productFolder(product),
33390
+ "instance",
33391
+ "Setup",
33392
+ "Installer",
33393
+ "WindowsKits10"
33394
+ ];
33395
+ function persistCovers(marker, req) {
33396
+ const same = marker.product === req.product;
33397
+ if (!same && !(marker.product === "community" && req.product === "buildtools")) return false;
33398
+ if (!needed(marker.product).every((f) => marker.folders.includes(f))) return false;
33399
+ const have = new Set(marker.components.map((c) => c.toLowerCase()));
33400
+ return req.components.filter((id) => same || !/\.workload\./i.test(id)).every((id) => have.has(id.toLowerCase()));
33401
+ }
33402
+ var jsonEscaped = (s) => JSON.stringify(s).slice(1, -1);
33403
+ function rewriteInstanceState(text, from, to) {
33404
+ const needle = jsonEscaped(win.normalize(from).replace(/\\+$/, ""));
33405
+ const replacement = jsonEscaped(win.normalize(to).replace(/\\+$/, ""));
33406
+ const lower = text.toLowerCase();
33407
+ const find = needle.toLowerCase();
33408
+ let out = "";
33409
+ let at = 0;
33410
+ for (let i = lower.indexOf(find); i !== -1; i = lower.indexOf(find, i + find.length)) {
33411
+ const next = text.slice(i + find.length, i + find.length + 2);
33412
+ if (next !== "\\\\" && !next.startsWith('"')) continue;
33413
+ out += text.slice(at, i) + replacement;
33414
+ at = i + find.length;
33415
+ }
33416
+ return out + text.slice(at);
33417
+ }
33418
+ function rebase(value, moves) {
33419
+ for (const move of moves) {
33420
+ const from = move.from.replace(/\\+$/, "");
33421
+ const lower = value.toLowerCase();
33422
+ if (lower === from.toLowerCase() || lower.startsWith(from.toLowerCase() + "\\"))
33423
+ return move.to.replace(/\\+$/, "") + value.slice(from.length);
33257
33424
  }
33425
+ return value;
33426
+ }
33427
+ var allowed = (entry) => REGISTRY_READS.some((read) => {
33428
+ const key2 = entry.key.toLowerCase();
33429
+ const root = read.key.toLowerCase();
33430
+ const under = key2 === root || read.recurse && key2.startsWith(root + "\\");
33431
+ return under && (read.names === null || read.names.some((n) => n.toLowerCase() === entry.name.toLowerCase()));
33432
+ });
33433
+ function registryPlan(marker, root, places) {
33434
+ const folders = persistFolders(marker, places).filter((f) => marker.folders.includes(f.name));
33435
+ const moves = folders.filter((f) => f.restore === "stay").map((f) => ({ from: f.source, to: win.join(root, f.name) }));
33436
+ const values = /* @__PURE__ */ new Map();
33437
+ const put = (e) => {
33438
+ values.set(e.key.toLowerCase() + "|" + e.name.toLowerCase(), e);
33439
+ };
33440
+ for (const e of marker.registry.filter(allowed))
33441
+ put({
33442
+ key: e.key,
33443
+ name: e.name,
33444
+ kind: e.kind,
33445
+ value: typeof e.value === "string" ? rebase(e.value, moves) : e.value
33446
+ });
33447
+ if (marker.folders.includes("WindowsKits10")) {
33448
+ const kits = win.join(root, "WindowsKits10") + "\\";
33449
+ const sdk = "SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\v10.0";
33450
+ put({ key: "SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots", name: "KitsRoot10", kind: "string", value: kits });
33451
+ put({ key: sdk, name: "InstallationFolder", kind: "string", value: kits });
33452
+ if (marker.sdkVersion) put({ key: sdk, name: "ProductVersion", kind: "string", value: marker.sdkVersion });
33453
+ }
33454
+ const both = [...values.values()].flatMap((e) => VIEWS.map((view) => ({ view, ...e })));
33455
+ const setup = win.join(places.programData, "Microsoft", "VisualStudio", "Setup");
33456
+ const com = (view, arch2) => {
33457
+ const key2 = "SOFTWARE\\Classes\\CLSID\\" + SETUP_CLSID + "\\InprocServer32";
33458
+ return [
33459
+ { view, key: key2, name: "", kind: "string", value: win.join(setup, arch2, SETUP_DLL) },
33460
+ { view, key: key2, name: "ThreadingModel", kind: "string", value: "Both" }
33461
+ ];
33462
+ };
33463
+ return [...both, ...com("64", "x64"), ...com("32", "x86")];
33464
+ }
33465
+ function compareVersions2(a, b) {
33466
+ const x = a.split(".").map((p) => parseInt(p, 10) || 0);
33467
+ const y = b.split(".").map((p) => parseInt(p, 10) || 0);
33468
+ for (let i = 0; i < Math.max(x.length, y.length); i++)
33469
+ if ((x[i] ?? 0) !== (y[i] ?? 0)) return (x[i] ?? 0) - (y[i] ?? 0);
33470
+ return 0;
33471
+ }
33472
+ function newestInstance(instances) {
33473
+ return [...instances].sort((a, b) => compareVersions2(b.installationVersion ?? "", a.installationVersion ?? ""))[0] ?? null;
33474
+ }
33475
+ function saveInput(vs, root, places, resultFile) {
33476
+ return {
33477
+ copies: persistFolders(vs, places).map((f) => ({
33478
+ name: f.name,
33479
+ from: f.source,
33480
+ to: win.join(root, f.name),
33481
+ optional: f.optional
33482
+ })),
33483
+ registry: VIEWS.flatMap((view) => REGISTRY_READS.map((r) => ({ view, ...r }))),
33484
+ resultFile
33485
+ };
33486
+ }
33487
+ function markerFrom(req, vs, result, capturedAt) {
33488
+ const sdk = result.registry.find(
33489
+ (e) => /\\Microsoft SDKs\\Windows\\v10\.0$/i.test(e.key) && e.name.toLowerCase() === "productversion"
33490
+ );
33491
+ return {
33492
+ product: req.product,
33493
+ version: vs.version,
33494
+ components: [...req.components],
33495
+ instanceId: vs.instanceId,
33496
+ installationPath: vs.installationPath,
33497
+ sdkVersion: typeof sdk?.value === "string" ? sdk.value : "",
33498
+ folders: [...result.copied],
33499
+ registry: [...result.registry],
33500
+ capturedAt
33501
+ };
33502
+ }
33503
+ function restoreInput(marker, root, places) {
33504
+ const copies = persistFolders(marker, places).filter((f) => f.restore !== "stay" && marker.folders.includes(f.name)).map((f) => ({
33505
+ name: f.name,
33506
+ from: win.join(root, f.name),
33507
+ to: f.source,
33508
+ mode: f.restore === "copy-missing" ? "missing" : "all"
33509
+ }));
33510
+ return { copies, registry: registryPlan(marker, root, places) };
33258
33511
  }
33259
33512
 
33260
33513
  // src/guest/toolchains/native/visual-studio.ts
@@ -33270,204 +33523,197 @@ var BOOTSTRAPPERS = {
33270
33523
  name: "Visual Studio Build Tools 2022"
33271
33524
  }
33272
33525
  };
33526
+ var GB2 = 1024 ** 3;
33273
33527
  var INSTALL_BYTES = {
33274
- community: 7 * 1024 ** 3,
33275
- buildtools: 5 * 1024 ** 3
33528
+ community: 7 * GB2,
33529
+ buildtools: 5 * GB2
33276
33530
  };
33531
+ var SAVE_ROOM_BYTES = 8 * GB2;
33277
33532
  var OK_EXIT_CODES = [0, 3010];
33278
- var LAYOUT_ROOM_BYTES = 15 * 1024 ** 3;
33279
33533
  var ID = /^[A-Za-z0-9][A-Za-z0-9._-]{0,199}$/;
33280
33534
  var VS_DIR = tool("visualstudio");
33281
- var LayoutSchema = external_exports.object({ components: external_exports.array(external_exports.string()) });
33282
- var VSWHERE = path67.join(
33283
- process.env["ProgramFiles(x86)"] ?? "C:\\Program Files (x86)",
33284
- "Microsoft Visual Studio",
33285
- "Installer",
33286
- "vswhere.exe"
33535
+ var PERSIST_DIR = path66.join(VS_DIR, "persist");
33536
+ var MARKER4 = path66.join(PERSIST_DIR, MARKER_FILE);
33537
+ var LEFTOVERS = ["layout", "layout-buildtools", "tmp"];
33538
+ var PLACES = winPlaces(process.env);
33539
+ var INSTALLER_DIR = path66.join(PLACES.programFilesX86, "Microsoft Visual Studio", "Installer");
33540
+ var VSWHERE = path66.join(INSTALLER_DIR, "vswhere.exe");
33541
+ var VswhereSchema = external_exports.array(
33542
+ external_exports.looseObject({
33543
+ instanceId: external_exports.string(),
33544
+ installationPath: external_exports.string(),
33545
+ installationVersion: external_exports.string().optional()
33546
+ })
33287
33547
  );
33288
33548
  function installedVs() {
33289
33549
  if (!exists(VSWHERE)) return null;
33290
- const ask = (property) => execOutput(VSWHERE, [
33291
- "-latest",
33550
+ const out = execOutput(VSWHERE, [
33292
33551
  "-products",
33293
33552
  "*",
33294
33553
  "-requires",
33295
33554
  "Microsoft.VisualStudio.Component.VC.Tools.x86.x64",
33296
- "-property",
33297
- property
33555
+ "-format",
33556
+ "json",
33557
+ "-utf8"
33298
33558
  ]);
33299
- const at = ask("installationPath");
33300
- return at ? { path: at, version: ask("installationVersion") || "installed" } : null;
33301
- }
33302
- function layoutDir(product) {
33303
- return path67.join(VS_DIR, product === "community" ? "layout" : "layout-buildtools");
33304
- }
33305
- var layoutArgs = (req, folder) => [
33306
- "--layout",
33307
- folder,
33308
- "--lang",
33309
- "en-US",
33310
- "--quiet",
33311
- "--wait",
33312
- ...req.components.flatMap((id) => ["--add", id])
33313
- ];
33314
- function newestBootstrapperLog(folders) {
33315
- const logs = folders.flatMap((dir) => {
33316
- try {
33317
- return fs52.readdirSync(dir).filter((n) => /^dd_bootstrapper_.*\.log$/i.test(n)).map((n) => path67.join(dir, n));
33318
- } catch {
33319
- return [];
33320
- }
33321
- });
33322
- const stamp = (f) => {
33323
- try {
33324
- return fs52.statSync(f).mtimeMs;
33325
- } catch {
33326
- return 0;
33327
- }
33328
- };
33329
- return logs.sort((x, y) => stamp(y) - stamp(x))[0] ?? null;
33330
- }
33331
- function reportLayoutFailure(code, temps) {
33332
- warn("Visual Studio: saving the install files failed (exit " + code + "): " + vsExitText(code));
33333
- const found = newestBootstrapperLog(temps);
33334
- if (!found) return;
33335
- const kept = path67.join(logsDir, "vs-layout-" + (/* @__PURE__ */ new Date()).toISOString().slice(0, 10) + ".log");
33559
+ let found;
33336
33560
  try {
33337
- fs52.mkdirSync(logsDir, { recursive: true });
33338
- fs52.copyFileSync(found, kept);
33339
- warn("Visual Studio: the installer log is " + found + " (a copy is in " + kept + ")");
33340
- } catch (e) {
33341
- warn("Visual Studio: the installer log is " + found + " (could not copy it: " + errMsg(e) + ")");
33561
+ found = JSON.parse(out || "[]");
33562
+ } catch {
33563
+ return null;
33342
33564
  }
33565
+ const first = newestInstance(VswhereSchema.safeParse(found).data ?? []);
33566
+ return first ? { path: first.installationPath, version: first.installationVersion ?? "installed", instanceId: first.instanceId } : null;
33567
+ }
33568
+ function savedCopy(req) {
33569
+ const marker = readValid(VsPersistMarkerSchema, MARKER4);
33570
+ if (!marker || !persistCovers(marker, req)) return null;
33571
+ const product = path66.join(PERSIST_DIR, productFolder(marker.product));
33572
+ const files = [
33573
+ path66.join(product, "VC", "Auxiliary", "Build", "vcvars64.bat"),
33574
+ path66.join(PERSIST_DIR, "instance", "state.json"),
33575
+ path66.join(PERSIST_DIR, "Installer", "vswhere.exe"),
33576
+ path66.join(PERSIST_DIR, "Setup", "x64", "Microsoft.VisualStudio.Setup.Configuration.Native.dll")
33577
+ ];
33578
+ return files.every(exists) ? marker : null;
33343
33579
  }
33344
- async function copyLayout(from, to) {
33345
- mkdirp(to);
33346
- const code = await heavy.run(
33347
- () => spawnAsync(SYSTEM.robocopy(), [from, to, "/E", "/COPY:DAT", "/R:1", "/W:1", "/MT:8", "/NP"])
33580
+ function visualStudioSaved(req) {
33581
+ return savedCopy(req) !== null;
33582
+ }
33583
+ async function restoreSaved(marker) {
33584
+ const started = Date.now();
33585
+ log("Visual Studio: putting back the copy saved in " + PERSIST_DIR + " ...");
33586
+ const plan2 = restoreInput(marker, PERSIST_DIR, PLACES);
33587
+ await heavy.run(() => runScriptWithJsonAsync("restore-visual-studio.ps1", "PlanFile", plan2));
33588
+ const vs = installedVs();
33589
+ if (!vs) throw new Error("vswhere does not find the Visual Studio that was put back");
33590
+ log(
33591
+ "Visual Studio " + vs.version + " is back in " + Math.round((Date.now() - started) / 1e3) + " s (" + vs.path + ")"
33348
33592
  );
33349
- return !robocopyFailed(code);
33350
- }
33351
- async function layoutInstaller(req, bootstrapper, lowPriority) {
33352
- const layout = layoutDir(req.product);
33353
- const marker = path67.join(layout, ".complete.json");
33354
- const installer2 = path67.join(layout, BOOTSTRAPPERS[req.product].file);
33355
- const has = () => {
33356
- if (!exists(marker) || !exists(installer2)) return false;
33357
- try {
33358
- const done = LayoutSchema.parse(JSON.parse(fs52.readFileSync(marker, "utf8")));
33359
- return req.components.every((id) => done.components.includes(id));
33360
- } catch {
33361
- return false;
33362
- }
33363
- };
33364
- const finish = () => {
33365
- writeJsonAtomic(marker, { components: [...req.components] });
33366
- return installer2;
33367
- };
33368
- if (has()) return installer2;
33369
- if (freeBytes(mkdirp(VS_DIR)) < LAYOUT_ROOM_BYTES) {
33593
+ return vs;
33594
+ }
33595
+ async function saveInstall(req, vs, lowPriority) {
33596
+ const free = freeBytes(mkdirp(PERSIST_DIR));
33597
+ if (free < SAVE_ROOM_BYTES) {
33370
33598
  warn(
33371
- "Visual Studio: not keeping the install files (less than 15 GB free in " + VS_DIR + "); downloading this boot"
33599
+ "Visual Studio: not saved for later boots (" + (free / GB2).toFixed(1) + " GB free in " + PERSIST_DIR + ", it needs 8 GB); the next boot installs it again"
33372
33600
  );
33373
- return null;
33601
+ return;
33374
33602
  }
33375
- log("Saving the Visual Studio install files for later boots (~10 GB, once) ...");
33376
- fs52.rmSync(marker, { force: true });
33377
- const drive = (process.env.SystemDrive ?? "C:") + "\\";
33378
- if (layoutNextStep(null, freeBytes(drive), STAGING_RESERVE_BYTES) !== "stage") {
33379
- warn(
33380
- "Visual Studio: less than " + Math.round((LAYOUT_STAGING_BYTES + STAGING_RESERVE_BYTES) / 1024 ** 3) + " GB free on " + drive + " to build the install files; downloading this boot"
33603
+ fs51.rmSync(MARKER4, { force: true });
33604
+ log("Saving Visual Studio in " + PERSIST_DIR + " for later boots (~6.5 GB, once) ...");
33605
+ const dir = fs51.mkdtempSync(path66.join(os9.tmpdir(), "sbx-vs-"));
33606
+ const resultFile = path66.join(dir, "result.json");
33607
+ try {
33608
+ const plan2 = saveInput(
33609
+ { product: req.product, installationPath: vs.path, instanceId: vs.instanceId },
33610
+ PERSIST_DIR,
33611
+ PLACES,
33612
+ resultFile
33381
33613
  );
33382
- return null;
33383
- }
33384
- const staging = path67.join(drive, "vs-layout-staging");
33385
- log("Building the install files on " + drive + " and copying them to " + layout + " ...");
33386
- const stagedCode = await runInstaller(bootstrapper, layoutArgs(req, staging), { lowPriority });
33387
- const staged = path67.join(staging, BOOTSTRAPPERS[req.product].file);
33388
- let kept = false;
33389
- if (OK_EXIT_CODES.includes(stagedCode) && exists(staged)) {
33390
- kept = await copyLayout(staging, layout);
33391
- if (!kept) warn("Visual Studio: copying the install files to " + layout + " failed");
33392
- } else {
33393
- reportLayoutFailure(stagedCode, [os9.tmpdir()]);
33614
+ await heavy.run(
33615
+ () => runScriptWithJsonAsync("save-visual-studio.ps1", "PlanFile", plan2, lowPriority ? ["-LowPriority"] : [])
33616
+ );
33617
+ const result = readValid(SaveResultSchema, resultFile);
33618
+ if (!result) throw new Error("the save script left no result");
33619
+ const state = path66.join(PERSIST_DIR, "instance", "state.json");
33620
+ const saved2 = path66.join(PERSIST_DIR, productFolder(req.product));
33621
+ fs51.writeFileSync(state, rewriteInstanceState(fs51.readFileSync(state, "utf8"), vs.path, saved2), "utf8");
33622
+ safeRemove(path66.join(PERSIST_DIR, productFolder(req.product === "community" ? "buildtools" : "community")), VS_DIR);
33623
+ writeJsonAtomic(
33624
+ MARKER4,
33625
+ markerFrom(
33626
+ req,
33627
+ { installationPath: vs.path, instanceId: vs.instanceId, version: vs.version },
33628
+ result,
33629
+ (/* @__PURE__ */ new Date()).toISOString()
33630
+ )
33631
+ );
33632
+ log("Visual Studio is saved: later boots put it back in seconds");
33633
+ } catch (e) {
33634
+ warn("Visual Studio: saving it for later boots failed (" + errMsg(e) + "); the next boot installs it again");
33635
+ } finally {
33636
+ fs51.rmSync(dir, { recursive: true, force: true });
33394
33637
  }
33395
- safeRemove(staging, drive);
33396
- return kept && exists(installer2) ? finish() : null;
33397
33638
  }
33398
33639
  function bootstrapperFor(req) {
33399
33640
  const boot = BOOTSTRAPPERS[req.product];
33400
- return signedInstaller(boot.url, path67.join(VS_DIR, boot.file), "the " + boot.name + " installer", SIGNERS.microsoft);
33641
+ return signedInstaller(boot.url, path66.join(VS_DIR, boot.file), "the " + boot.name + " installer", SIGNERS.microsoft);
33401
33642
  }
33402
33643
  async function prefetchVisualStudio(req) {
33403
- if (!req.accepted || installedVs()) return;
33644
+ if (!req.accepted || installedVs() || savedCopy(req)) return;
33404
33645
  await bootstrapperFor(req);
33405
33646
  }
33406
- async function install(req, keepInstallFiles, lowPriority) {
33647
+ async function install(req, lowPriority) {
33407
33648
  const boot = BOOTSTRAPPERS[req.product];
33408
33649
  const bootstrapper = await bootstrapperFor(req);
33409
- let installer2 = null;
33410
- if (keepInstallFiles) {
33411
- try {
33412
- installer2 = await layoutInstaller(req, bootstrapper, lowPriority);
33413
- } catch (e) {
33414
- warn("Visual Studio: the offline copy failed (" + errMsg(e) + "); downloading this boot");
33415
- }
33416
- }
33417
- const run2 = (from, offline) => runInstaller(
33418
- from,
33419
- [
33420
- "--quiet",
33421
- "--wait",
33422
- "--norestart",
33423
- "--nocache",
33424
- ...offline ? ["--noWeb"] : [],
33425
- ...req.components.flatMap((id) => ["--add", id])
33426
- ],
33650
+ log("Installing " + boot.name + " (downloads ~5-8 GB, once: it is saved on the data disk afterwards) ...");
33651
+ const code = await runInstaller(
33652
+ bootstrapper,
33653
+ ["--quiet", "--wait", "--norestart", "--nocache", ...req.components.flatMap((id) => ["--add", id])],
33427
33654
  { lowPriority }
33428
33655
  );
33429
- log("Installing " + boot.name + (installer2 ? " from the saved install files" : " (downloads ~5-8 GB)") + " ...");
33430
- let code = await run2(installer2 ?? bootstrapper, installer2 !== null);
33431
- if (installer2 && (!OK_EXIT_CODES.includes(code) || !installedVs())) {
33432
- warn("Visual Studio: installing from the saved install files failed (" + vsExitText(code) + "); downloading");
33433
- code = await run2(bootstrapper, false);
33434
- }
33435
33656
  if (!OK_EXIT_CODES.includes(code) || !installedVs())
33436
33657
  throw new Error(
33437
33658
  "the Visual Studio installer failed (exit " + code + ": " + vsExitText(code) + "); its logs are the dd_*.log files in " + os9.tmpdir()
33438
33659
  );
33439
33660
  }
33440
- async function ensureVisualStudio(env, req, o) {
33661
+ function removeLeftovers() {
33662
+ for (const name of LEFTOVERS) {
33663
+ const dir = path66.join(VS_DIR, name);
33664
+ try {
33665
+ if (exists(dir)) safeRemove(dir, VS_DIR);
33666
+ } catch (e) {
33667
+ warn("Visual Studio: could not remove " + dir + " (" + errMsg(e) + ")");
33668
+ }
33669
+ }
33670
+ }
33671
+ async function ensureVisualStudio(env, req, o = {}) {
33441
33672
  if (!req.accepted)
33442
33673
  throw new Error(
33443
33674
  "Visual Studio (for " + req.for.join(", ") + ") is installed only with " + req.licence + " = true: it comes under Microsoft licence terms (https://visualstudio.microsoft.com/license-terms/)"
33444
33675
  );
33445
33676
  const bad = req.components.find((id) => !ID.test(id));
33446
33677
  if (bad) throw new Error('"' + bad + '" is not a Visual Studio component ID');
33678
+ removeLeftovers();
33679
+ const name = BOOTSTRAPPERS[req.product].name;
33680
+ const done = (vs2, how) => {
33681
+ env.append.push(INSTALLER_DIR);
33682
+ env.summary.push(
33683
+ "visual studio: " + name + " " + vs2.version + " at " + vs2.path + " (" + how + "; for " + req.for.join(", ") + ")"
33684
+ );
33685
+ return vs2;
33686
+ };
33447
33687
  const have = installedVs();
33448
- if (have) return have;
33688
+ if (have) return done(have, "installed");
33689
+ const saved2 = savedCopy(req);
33690
+ if (saved2) {
33691
+ try {
33692
+ return done(await restoreSaved(saved2), "kept on the data disk");
33693
+ } catch (e) {
33694
+ warn("Visual Studio: putting the saved copy back failed (" + errMsg(e) + "); installing it again");
33695
+ }
33696
+ }
33449
33697
  if (duringSession())
33450
33698
  throw new Error(
33451
33699
  backgroundRunning("Visual Studio") ? "Visual Studio is still installing in the background; it is ready in a few minutes" : "Visual Studio is installed when the sandbox starts: restart it (sandbox restart) to get it"
33452
33700
  );
33453
- assertLocalRoom(INSTALL_BYTES[req.product], BOOTSTRAPPERS[req.product].name);
33454
- await install(req, o.keepInstallFiles, o.lowPriority === true);
33701
+ assertLocalRoom(INSTALL_BYTES[req.product], name);
33702
+ await install(req, o.lowPriority === true);
33455
33703
  const vs = installedVs();
33456
- env.summary.push(
33457
- "visual studio: " + BOOTSTRAPPERS[req.product].name + " " + vs.version + " at " + vs.path + " (for " + req.for.join(", ") + ")"
33458
- );
33459
- return vs;
33704
+ await saveInstall(req, vs, o.lowPriority === true);
33705
+ return done(vs, "installed, saved for later boots");
33460
33706
  }
33461
33707
 
33462
33708
  // src/guest/toolchains/native/unreal.ts
33463
33709
  var DIRECTX_URL = "https://download.microsoft.com/download/8/4/A/84A35BF1-DAFE-4AE8-82AF-AD2AE20B6B14/directx_Jun2010_redist.exe";
33464
33710
  var directXInstalled = () => {
33465
- const system322 = path68.join(process.env.WINDIR ?? "C:\\Windows", "System32");
33466
- return exists(path68.join(system322, "d3dx9_43.dll")) && exists(path68.join(system322, "XAudio2_7.dll"));
33711
+ const system322 = path67.join(process.env.WINDIR ?? "C:\\Windows", "System32");
33712
+ return exists(path67.join(system322, "d3dx9_43.dll")) && exists(path67.join(system322, "XAudio2_7.dll"));
33467
33713
  };
33468
33714
  var directXRedist = () => signedInstaller(
33469
33715
  DIRECTX_URL,
33470
- path68.join(tool("visualstudio"), "directx_Jun2010_redist.exe"),
33716
+ path67.join(tool("visualstudio"), "directx_Jun2010_redist.exe"),
33471
33717
  "the DirectX End-User Runtime (~95 MB once)",
33472
33718
  SIGNERS.microsoft
33473
33719
  );
@@ -33477,12 +33723,12 @@ async function fetchDirectX(config2) {
33477
33723
  async function installDirectX() {
33478
33724
  if (directXInstalled()) return;
33479
33725
  const redist = await directXRedist();
33480
- const unpacked = path68.join(os10.tmpdir(), "directx-redist");
33726
+ const unpacked = path67.join(os10.tmpdir(), "directx-redist");
33481
33727
  safeRemove(unpacked, os10.tmpdir());
33482
33728
  mkdirp(unpacked);
33483
- if (await runInstaller(redist, ["/Q", "/T:" + unpacked]) !== 0 || !exists(path68.join(unpacked, "DXSETUP.exe")))
33729
+ if (await runInstaller(redist, ["/Q", "/T:" + unpacked]) !== 0 || !exists(path67.join(unpacked, "DXSETUP.exe")))
33484
33730
  throw new Error("could not unpack the DirectX End-User Runtime");
33485
- const code = await runInstaller(path68.join(unpacked, "DXSETUP.exe"), ["/silent"]);
33731
+ const code = await runInstaller(path67.join(unpacked, "DXSETUP.exe"), ["/silent"]);
33486
33732
  safeRemove(unpacked, os10.tmpdir());
33487
33733
  if (code !== 0) throw new Error("the DirectX End-User Runtime installer failed (exit " + code + ")");
33488
33734
  }
@@ -33496,33 +33742,32 @@ async function setupUnreal(env, config2, ctx) {
33496
33742
  return;
33497
33743
  }
33498
33744
  await installDirectX();
33499
- if (config2.visualStudio === "autosdk") await setupAutosdk(env);
33500
33745
  await setupUnrealEngines(env, config2, ctx);
33501
33746
  const vs = installedVs();
33502
33747
  env.summary.push(
33503
- "unreal: " + (vs ? "Visual Studio " + vs.version + " (C++ game workload, Windows 11 SDK, Unreal support); " : "") + "DirectX End-User Runtime; get the engine from the Epic Games Launcher (Start menu)"
33748
+ "unreal: " + (vs ? "Visual Studio " + vs.version + " at " + vs.path + "; " : "") + "DirectX End-User Runtime; get the engine from the Epic Games Launcher (Start menu)"
33504
33749
  );
33505
33750
  }
33506
33751
 
33507
33752
  // src/guest/toolchains/native/rust.ts
33508
- import path70 from "node:path";
33753
+ import path69 from "node:path";
33509
33754
 
33510
33755
  // src/guest/toolchains/native/binstall.ts
33511
- import fs53 from "node:fs";
33512
- import path69 from "node:path";
33756
+ import fs52 from "node:fs";
33757
+ import path68 from "node:path";
33513
33758
  var ensureBinstall = async (cargoBin) => {
33514
- const target = path69.join(cargoBin, "cargo-binstall.exe");
33759
+ const target = path68.join(cargoBin, "cargo-binstall.exe");
33515
33760
  if (exists(target)) return true;
33516
33761
  try {
33517
33762
  const dir = tool("cargo-binstall");
33518
- if (!exists(path69.join(dir, "cargo-binstall.exe"))) {
33763
+ if (!exists(path68.join(dir, "cargo-binstall.exe"))) {
33519
33764
  await installFromGithub("cargo-bins/cargo-binstall", binstallAsset(arch), {
33520
33765
  dest: dir,
33521
33766
  what: "cargo-binstall for prebuilt Rust tools (~10 MB once)",
33522
33767
  locate: "cargo-binstall.exe"
33523
33768
  });
33524
33769
  }
33525
- fs53.copyFileSync(path69.join(dir, "cargo-binstall.exe"), target);
33770
+ fs52.copyFileSync(path68.join(dir, "cargo-binstall.exe"), target);
33526
33771
  return true;
33527
33772
  } catch (e) {
33528
33773
  warn("cargo-binstall unavailable, compiling crates with cargo install instead: " + errMsg(e));
@@ -33530,14 +33775,14 @@ var ensureBinstall = async (cargoBin) => {
33530
33775
  }
33531
33776
  };
33532
33777
  function crateInstaller(cargoHome, cargoEnv) {
33533
- const cargo = path69.join(cargoHome, "bin", "cargo.exe");
33778
+ const cargo = path68.join(cargoHome, "bin", "cargo.exe");
33534
33779
  let binstall = null;
33535
33780
  const binstallEnv = {
33536
33781
  ...cargoEnv,
33537
33782
  env: { ...cargoEnv.env ?? process.env, BINSTALL_DISABLE_TELEMETRY: "true" }
33538
33783
  };
33539
33784
  return async (crate) => {
33540
- binstall ??= ensureBinstall(path69.join(cargoHome, "bin"));
33785
+ binstall ??= ensureBinstall(path68.join(cargoHome, "bin"));
33541
33786
  if (await binstall) {
33542
33787
  try {
33543
33788
  await execHeavy(
@@ -33557,7 +33802,7 @@ function crateInstaller(cargoHome, cargoEnv) {
33557
33802
  // src/guest/toolchains/native/rust.ts
33558
33803
  async function fetchRustupInit() {
33559
33804
  const init = tool("rust", "rustup-init.exe");
33560
- if (exists(init) || exists(path70.join(tool("rust", "cargo"), "bin", "rustup.exe"))) return;
33805
+ if (exists(init) || exists(path69.join(tool("rust", "cargo"), "bin", "rustup.exe"))) return;
33561
33806
  await downloadFile(
33562
33807
  "https://static.rust-lang.org/rustup/dist/" + (arch === "arm64" ? "aarch64" : "x86_64") + "-pc-windows-msvc/rustup-init.exe",
33563
33808
  init
@@ -33567,7 +33812,7 @@ async function setupRust(env, config2, refresh) {
33567
33812
  const RUSTUP_HOME = tool("rust", "rustup");
33568
33813
  const CARGO_HOME = tool("rust", "cargo");
33569
33814
  const rustEnv = { env: { ...process.env, RUSTUP_HOME, CARGO_HOME } };
33570
- const rustup = path70.join(CARGO_HOME, "bin", "rustup.exe");
33815
+ const rustup = path69.join(CARGO_HOME, "bin", "rustup.exe");
33571
33816
  if (dryRun) {
33572
33817
  log("(dry run) would provision Rust " + config2.toolchain + " (" + config2.host + ")");
33573
33818
  return;
@@ -33600,9 +33845,9 @@ async function setupRust(env, config2, refresh) {
33600
33845
  if (refresh) await execHeavy(rustup, ["update"], rustEnv);
33601
33846
  }
33602
33847
  Object.assign(env.vars, { RUSTUP_HOME, CARGO_HOME });
33603
- env.prepend.push(path70.join(CARGO_HOME, "bin"));
33848
+ env.prepend.push(path69.join(CARGO_HOME, "bin"));
33604
33849
  env.summary.push(
33605
- "rust: " + versionOf(path70.join(CARGO_HOME, "bin", "rustc.exe"), ["--version"], rustEnv) + " [" + config2.host + "]"
33850
+ "rust: " + versionOf(path69.join(CARGO_HOME, "bin", "rustc.exe"), ["--version"], rustEnv) + " [" + config2.host + "]"
33606
33851
  );
33607
33852
  const toolchainKey = "rustup@" + config2.toolchain;
33608
33853
  await installOnce(
@@ -33623,36 +33868,36 @@ async function setupRust(env, config2, refresh) {
33623
33868
  env: {
33624
33869
  ...rustEnv.env,
33625
33870
  ...msvc.vars,
33626
- PATH: [path70.join(CARGO_HOME, "bin"), ...msvc.path, process.env.PATH ?? ""].join(path70.delimiter)
33871
+ PATH: [path69.join(CARGO_HOME, "bin"), ...msvc.path, process.env.PATH ?? ""].join(path69.delimiter)
33627
33872
  }
33628
33873
  } : {
33629
33874
  env: {
33630
33875
  ...rustEnv.env,
33631
- CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER: path70.join(mingw, "gcc.exe"),
33632
- PATH: [path70.join(CARGO_HOME, "bin"), mingw, process.env.PATH ?? ""].join(path70.delimiter)
33876
+ CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER: path69.join(mingw, "gcc.exe"),
33877
+ PATH: [path69.join(CARGO_HOME, "bin"), mingw, process.env.PATH ?? ""].join(path69.delimiter)
33633
33878
  }
33634
33879
  };
33635
33880
  await installOnce(env, "cargo", config2.crates, crateInstaller(CARGO_HOME, cargoEnv));
33636
33881
  }
33637
33882
 
33638
33883
  // src/guest/toolchains/languages/node.ts
33639
- import fs54 from "node:fs";
33640
- import path71 from "node:path";
33884
+ import fs53 from "node:fs";
33885
+ import path70 from "node:path";
33641
33886
  import { spawn as spawn7 } from "node:child_process";
33642
33887
  var NVM_HOME = tool("nvm");
33643
- var NVM_SYMLINK = path71.join(localDir, "nodejs");
33644
- var HOST_NVM = path71.join(hostToolsDir, "nvm");
33888
+ var NVM_SYMLINK = path70.join(localDir, "nodejs");
33889
+ var HOST_NVM = path70.join(hostToolsDir, "nvm");
33645
33890
  var HOST_VERSIONS_MAX = 3;
33646
- var hostNvmVersions = () => exists(HOST_NVM) ? fs54.readdirSync(HOST_NVM).filter((d) => /^v\d+\.\d+\.\d+$/.test(d) && exists(path71.join(HOST_NVM, d, "node.exe"))).map((d) => d.slice(1)) : [];
33891
+ var hostNvmVersions = () => exists(HOST_NVM) ? fs53.readdirSync(HOST_NVM).filter((d) => /^v\d+\.\d+\.\d+$/.test(d) && exists(path70.join(HOST_NVM, d, "node.exe"))).map((d) => d.slice(1)) : [];
33647
33892
  var resolveNode = (spec) => resolveCached("node:" + spec, async () => {
33648
33893
  const exact = spec.replace(/^v/, "");
33649
33894
  if (/^\d+\.\d+\.\d+$/.test(exact)) return exact;
33650
33895
  const releases = await fetchJson("https://nodejs.org/dist/index.json");
33651
33896
  return pickNodeVersion(releases, spec) ?? Promise.reject(new Error('No Node.js release matches "' + spec + '"'));
33652
33897
  });
33653
- var NVM_TEMP = path71.join(NVM_HOME, ".tmp");
33898
+ var NVM_TEMP = path70.join(NVM_HOME, ".tmp");
33654
33899
  var nvm = (args) => new Promise((resolve2) => {
33655
- const child = spawn7(path71.join(NVM_HOME, "nvm.exe"), args, {
33900
+ const child = spawn7(path70.join(NVM_HOME, "nvm.exe"), args, {
33656
33901
  windowsHide: true,
33657
33902
  env: { ...process.env, NVM_HOME, NVM_SYMLINK, TEMP: NVM_TEMP, TMP: NVM_TEMP }
33658
33903
  });
@@ -33667,12 +33912,12 @@ var nvm = (args) => new Promise((resolve2) => {
33667
33912
  child.once("close", () => resolve2(out));
33668
33913
  });
33669
33914
  var ensureNvm = async () => {
33670
- if (exists(path71.join(NVM_HOME, "nvm.exe"))) return;
33671
- if (exists(path71.join(HOST_NVM, "nvm.exe"))) {
33915
+ if (exists(path70.join(NVM_HOME, "nvm.exe"))) return;
33916
+ if (exists(path70.join(HOST_NVM, "nvm.exe"))) {
33672
33917
  log("Copying nvm from this PC ...");
33673
33918
  mkdirp(NVM_HOME);
33674
- const files = fs54.readdirSync(HOST_NVM).filter((f) => /\.(exe|cmd|vbs)$/i.test(f)).sort((a, b) => Number(a.toLowerCase() === "nvm.exe") - Number(b.toLowerCase() === "nvm.exe"));
33675
- for (const file3 of files) fs54.copyFileSync(path71.join(HOST_NVM, file3), path71.join(NVM_HOME, file3));
33919
+ const files = fs53.readdirSync(HOST_NVM).filter((f) => /\.(exe|cmd|vbs)$/i.test(f)).sort((a, b) => Number(a.toLowerCase() === "nvm.exe") - Number(b.toLowerCase() === "nvm.exe"));
33920
+ for (const file3 of files) fs53.copyFileSync(path70.join(HOST_NVM, file3), path70.join(NVM_HOME, file3));
33676
33921
  return;
33677
33922
  }
33678
33923
  const asset = await githubAsset("coreybutler/nvm-windows", /^nvm-noinstall\.zip$/, true);
@@ -33680,14 +33925,14 @@ var ensureNvm = async () => {
33680
33925
  await downloader.archive(asset.url, NVM_HOME, { sha256: asset.sha256, locate: "nvm.exe", fileName: asset.name });
33681
33926
  };
33682
33927
  var hostNodeFolder = (version2) => {
33683
- const dir = path71.join(hostToolsDir, "node");
33684
- return session.hostTools.nodeVersion?.replace(/^v/, "") === version2 && exists(path71.join(dir, "node.exe")) ? dir : null;
33928
+ const dir = path70.join(hostToolsDir, "node");
33929
+ return session.hostTools.nodeVersion?.replace(/^v/, "") === version2 && exists(path70.join(dir, "node.exe")) ? dir : null;
33685
33930
  };
33686
33931
  var installNodeVersion = async (version2) => {
33687
- const dir = path71.join(NVM_HOME, "v" + version2);
33688
- const fromHost = path71.join(HOST_NVM, "v" + version2);
33689
- if (exists(path71.join(dir, "node.exe"))) return;
33690
- if (exists(path71.join(fromHost, "node.exe"))) {
33932
+ const dir = path70.join(NVM_HOME, "v" + version2);
33933
+ const fromHost = path70.join(HOST_NVM, "v" + version2);
33934
+ if (exists(path70.join(dir, "node.exe"))) return;
33935
+ if (exists(path70.join(fromHost, "node.exe"))) {
33691
33936
  log("Copying Node " + version2 + " from this PC's nvm (without global packages) ...");
33692
33937
  copyNode(fromHost, dir);
33693
33938
  return;
@@ -33706,19 +33951,19 @@ var installNodeVersion = async (version2) => {
33706
33951
  } finally {
33707
33952
  safeRemove(NVM_TEMP, NVM_HOME);
33708
33953
  }
33709
- if (!exists(path71.join(dir, "node.exe"))) {
33954
+ if (!exists(path70.join(dir, "node.exe"))) {
33710
33955
  const tail = out.trim().split(/\r?\n/).filter(Boolean).slice(-3).join(" ");
33711
33956
  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";
33712
33957
  throw new Error(
33713
- "nvm install " + version2 + " did not leave " + path71.join(dir, "node.exe") + " (" + why + ")" + (tail ? ". nvm printed: " + tail : "")
33958
+ "nvm install " + version2 + " did not leave " + path70.join(dir, "node.exe") + " (" + why + ")" + (tail ? ". nvm printed: " + tail : "")
33714
33959
  );
33715
33960
  }
33716
33961
  };
33717
33962
  var activate = async (version2) => {
33718
33963
  await nvm(["use", version2]);
33719
- if (exists(path71.join(NVM_SYMLINK, "node.exe"))) return;
33720
- fs54.rmSync(NVM_SYMLINK, { recursive: true, force: true });
33721
- fs54.symlinkSync(path71.join(NVM_HOME, "v" + version2), NVM_SYMLINK, "junction");
33964
+ if (exists(path70.join(NVM_SYMLINK, "node.exe"))) return;
33965
+ fs53.rmSync(NVM_SYMLINK, { recursive: true, force: true });
33966
+ fs53.symlinkSync(path70.join(NVM_HOME, "v" + version2), NVM_SYMLINK, "junction");
33722
33967
  };
33723
33968
  var PLAYWRIGHT_VARS = () => ({
33724
33969
  PLAYWRIGHT_BROWSERS_PATH: tool("ms-playwright"),
@@ -33730,8 +33975,8 @@ async function setupNode(env, versions, config2) {
33730
33975
  return;
33731
33976
  }
33732
33977
  await ensureNvm();
33733
- fs54.writeFileSync(
33734
- path71.join(NVM_HOME, "settings.txt"),
33978
+ fs53.writeFileSync(
33979
+ path70.join(NVM_HOME, "settings.txt"),
33735
33980
  [
33736
33981
  "root: " + NVM_HOME,
33737
33982
  "path: " + NVM_SYMLINK,
@@ -33758,7 +34003,7 @@ async function setupNode(env, versions, config2) {
33758
34003
  }
33759
34004
  }
33760
34005
  Object.assign(env.vars, { NVM_HOME, NVM_SYMLINK, ...PLAYWRIGHT_VARS() });
33761
- if (duringSession()) env.prepend.push(path71.join(NVM_HOME, "v" + main), NVM_HOME, NVM_SYMLINK);
34006
+ if (duringSession()) env.prepend.push(path70.join(NVM_HOME, "v" + main), NVM_HOME, NVM_SYMLINK);
33762
34007
  else {
33763
34008
  await activate(main);
33764
34009
  env.prepend.push(NVM_HOME, NVM_SYMLINK);
@@ -33768,13 +34013,13 @@ async function setupNode(env, versions, config2) {
33768
34013
  await packageManagers(env, config2, main);
33769
34014
  }
33770
34015
  var packageManagers = async (env, config2, version2) => {
33771
- const dir = path71.join(NVM_HOME, "v" + version2);
33772
- const nodeEnv = { ...process.env, PATH: dir + path71.delimiter + (process.env.PATH ?? "") };
33773
- const npm = (args) => execHeavy(path71.join(dir, "node.exe"), [path71.join(dir, "node_modules", "npm", "bin", "npm-cli.js"), ...args], {
34016
+ const dir = path70.join(NVM_HOME, "v" + version2);
34017
+ const nodeEnv = { ...process.env, PATH: dir + path70.delimiter + (process.env.PATH ?? "") };
34018
+ const npm = (args) => execHeavy(path70.join(dir, "node.exe"), [path70.join(dir, "node_modules", "npm", "bin", "npm-cli.js"), ...args], {
33774
34019
  env: nodeEnv,
33775
34020
  stdio: "ignore"
33776
34021
  });
33777
- const corepackJs = path71.join(dir, "node_modules", "corepack", "dist", "corepack.js");
34022
+ const corepackJs = path70.join(dir, "node_modules", "corepack", "dist", "corepack.js");
33778
34023
  const extra = config2.corepack && !exists(corepackJs) ? ["corepack"] : [];
33779
34024
  await installOnce(
33780
34025
  env,
@@ -33795,7 +34040,7 @@ var packageManagers = async (env, config2, version2) => {
33795
34040
  }
33796
34041
  try {
33797
34042
  await execHeavy(
33798
- path71.join(dir, "node.exe"),
34043
+ path70.join(dir, "node.exe"),
33799
34044
  [corepackJs, "enable", "--install-directory", mkdirp(tool("bin")), "pnpm", "yarn"],
33800
34045
  { env: nodeEnv, stdio: "ignore" }
33801
34046
  );
@@ -33820,8 +34065,8 @@ async function setupPwsh(env, refresh = false) {
33820
34065
  }
33821
34066
 
33822
34067
  // src/guest/toolchains/languages/python.ts
33823
- import fs55 from "node:fs";
33824
- import path72 from "node:path";
34068
+ import fs54 from "node:fs";
34069
+ import path71 from "node:path";
33825
34070
  var installPython = async (pkg, spec) => {
33826
34071
  const version2 = await resolveCached(pkg + ":" + spec, async () => {
33827
34072
  const { versions } = await fetchJson(
@@ -33830,7 +34075,7 @@ var installPython = async (pkg, spec) => {
33830
34075
  return pickPackageVersion(versions, spec) ?? Promise.reject(new Error("No " + pkg + ' release matches "' + spec + '"'));
33831
34076
  });
33832
34077
  const dir = tool("python", pkg + "-" + version2);
33833
- const exe = path72.join(dir, "python.exe");
34078
+ const exe = path71.join(dir, "python.exe");
33834
34079
  if (!exists(exe)) {
33835
34080
  log("Downloading Python " + version2 + (pkg === "python2" ? " (Python 2, " : " (") + "~30 MB once) ...");
33836
34081
  await downloader.archive(
@@ -33839,32 +34084,32 @@ var installPython = async (pkg, spec) => {
33839
34084
  { locate: "python.exe", fileName: pkg + "." + version2 + ".zip" }
33840
34085
  );
33841
34086
  }
33842
- if (!exists(path72.join(dir, "Scripts", "pip.exe")) && !exists(path72.join(dir, "Scripts", "pip2.exe")))
34087
+ if (!exists(path71.join(dir, "Scripts", "pip.exe")) && !exists(path71.join(dir, "Scripts", "pip2.exe")))
33843
34088
  await execAsync(exe, ["-m", "ensurepip", "--default-pip"], { stdio: "ignore" });
33844
34089
  return dir;
33845
34090
  };
33846
- var shimDir = (dir) => duringSession() ? tool("shims", path72.basename(dir)) : tool("shims");
34091
+ var shimDir = (dir) => duringSession() ? tool("shims", path71.basename(dir)) : tool("shims");
33847
34092
  var shim = (folder, name, program, args = []) => {
33848
34093
  const fixed = [program, ...args];
33849
- fs55.writeFileSync(
33850
- path72.join(mkdirp(folder), name + ".cmd"),
34094
+ fs54.writeFileSync(
34095
+ path71.join(mkdirp(folder), name + ".cmd"),
33851
34096
  "@echo off\r\n" + fixed.map((a) => '"' + a + '"').join(" ") + " %*\r\n"
33852
34097
  );
33853
34098
  const sh = fixed.map((a) => "'" + a.replace(/\\/g, "/").replace(/'/g, "'\\''") + "'").join(" ");
33854
- fs55.writeFileSync(path72.join(folder, name), "#!/bin/sh\nexec " + sh + ' "$@"\n');
34099
+ fs54.writeFileSync(path71.join(folder, name), "#!/bin/sh\nexec " + sh + ' "$@"\n');
33855
34100
  };
33856
34101
  var shimPair = (folder, version2, dir) => {
33857
- const python = path72.join(dir, "python.exe");
34102
+ const python = path71.join(dir, "python.exe");
33858
34103
  shim(folder, "python" + version2, python);
33859
34104
  shim(folder, "pip" + version2, python, ["-m", "pip"]);
33860
34105
  };
33861
34106
  var pyLauncher = (folder, py3, py2) => {
33862
- const script = path72.join(mkdirp(folder), "py-launcher.py");
33863
- fs55.writeFileSync(
34107
+ const script = path71.join(mkdirp(folder), "py-launcher.py");
34108
+ fs54.writeFileSync(
33864
34109
  script,
33865
34110
  [
33866
34111
  "import subprocess, sys",
33867
- "PY3, PY2 = " + JSON.stringify(path72.join(py3, "python.exe")) + ", " + JSON.stringify(py2 ? path72.join(py2, "python.exe") : null),
34112
+ "PY3, PY2 = " + JSON.stringify(path71.join(py3, "python.exe")) + ", " + JSON.stringify(py2 ? path71.join(py2, "python.exe") : null),
33868
34113
  "args = sys.argv[1:]",
33869
34114
  "exe = PY3",
33870
34115
  "if args and args[0].startswith('-2'):",
@@ -33876,7 +34121,7 @@ var pyLauncher = (folder, py3, py2) => {
33876
34121
  ""
33877
34122
  ].join("\n")
33878
34123
  );
33879
- shim(folder, "py", path72.join(py3, "python.exe"), [script]);
34124
+ shim(folder, "py", path71.join(py3, "python.exe"), [script]);
33880
34125
  };
33881
34126
  async function setupPython(env, config2, versions) {
33882
34127
  if (dryRun) {
@@ -33886,10 +34131,10 @@ async function setupPython(env, config2, versions) {
33886
34131
  const py3 = await installPython("python", versions.python.spec);
33887
34132
  const shims = shimDir(py3);
33888
34133
  shimPair(shims, "3", py3);
33889
- env.prepend.push(py3, mkdirp(path72.join(py3, "Scripts")), shims);
34134
+ env.prepend.push(py3, mkdirp(path71.join(py3, "Scripts")), shims);
33890
34135
  env.vars.PYTHONIOENCODING = "utf-8";
33891
34136
  env.summary.push(
33892
- "python: " + path72.basename(py3).replace("python-", "") + " (from " + versions.python.source + "; py works too)"
34137
+ "python: " + path71.basename(py3).replace("python-", "") + " (from " + versions.python.source + "; py works too)"
33893
34138
  );
33894
34139
  if (!config2.python2) {
33895
34140
  pyLauncher(shims, py3, null);
@@ -33898,22 +34143,22 @@ async function setupPython(env, config2, versions) {
33898
34143
  const py2 = await installPython("python2", "2.7");
33899
34144
  shimPair(shims, "2", py2);
33900
34145
  pyLauncher(shims, py3, py2);
33901
- env.summary.push("python2: " + path72.basename(py2).replace("python2-", ""));
34146
+ env.summary.push("python2: " + path71.basename(py2).replace("python2-", ""));
33902
34147
  }
33903
34148
 
33904
34149
  // src/guest/toolchains/languages/php.ts
33905
- import fs57 from "node:fs";
33906
- import path74 from "node:path";
33907
-
33908
- // src/guest/toolchains/native/vcruntime.ts
33909
34150
  import fs56 from "node:fs";
33910
34151
  import path73 from "node:path";
34152
+
34153
+ // src/guest/toolchains/native/vcruntime.ts
34154
+ import fs55 from "node:fs";
34155
+ import path72 from "node:path";
33911
34156
  var VC_REDIST = "https://aka.ms/vs/17/release/vc_redist.x64.exe";
33912
34157
  var OK_EXIT_CODES2 = [0, 1638, 3010];
33913
34158
  async function fetchVcRuntime() {
33914
- const system322 = path73.join(process.env.WINDIR ?? "C:\\Windows", "System32");
34159
+ const system322 = path72.join(process.env.WINDIR ?? "C:\\Windows", "System32");
33915
34160
  const installer2 = tool("vcredist", "vc_redist.x64.exe");
33916
- if (exists(installer2) || exists(path73.join(system322, "vcruntime140.dll"))) return;
34161
+ if (exists(installer2) || exists(path72.join(system322, "vcruntime140.dll"))) return;
33917
34162
  await downloadFile(VC_REDIST, installer2);
33918
34163
  }
33919
34164
  async function setupVcRuntime(env, summary = true) {
@@ -33921,8 +34166,8 @@ async function setupVcRuntime(env, summary = true) {
33921
34166
  log("(dry run) would install the Visual C++ runtime");
33922
34167
  return false;
33923
34168
  }
33924
- const system322 = path73.join(process.env.WINDIR ?? "C:\\Windows", "System32");
33925
- const missing = !exists(path73.join(system322, "vcruntime140.dll")) || !exists(path73.join(system322, "msvcp140.dll"));
34169
+ const system322 = path72.join(process.env.WINDIR ?? "C:\\Windows", "System32");
34170
+ const missing = !exists(path72.join(system322, "vcruntime140.dll")) || !exists(path72.join(system322, "msvcp140.dll"));
33926
34171
  if (missing) {
33927
34172
  const installer2 = tool("vcredist", "vc_redist.x64.exe");
33928
34173
  if (!exists(installer2)) {
@@ -33930,12 +34175,12 @@ async function setupVcRuntime(env, summary = true) {
33930
34175
  await downloadFile(VC_REDIST, installer2);
33931
34176
  }
33932
34177
  if (!signedBy(installer2, SIGNERS.microsoft)) {
33933
- fs56.rmSync(installer2, { force: true });
34178
+ fs55.rmSync(installer2, { force: true });
33934
34179
  throw new Error("vc_redist.x64.exe is not signed by Microsoft; deleted it (it is downloaded again next boot)");
33935
34180
  }
33936
34181
  log("Installing the Visual C++ runtime ...");
33937
34182
  const code = await runInstaller(installer2, ["/install", "/quiet", "/norestart"]);
33938
- if (!OK_EXIT_CODES2.includes(code ?? -1) || !exists(path73.join(system322, "vcruntime140.dll")))
34183
+ if (!OK_EXIT_CODES2.includes(code ?? -1) || !exists(path72.join(system322, "vcruntime140.dll")))
33939
34184
  throw new Error("the Visual C++ runtime installer failed (exit " + code + ")");
33940
34185
  }
33941
34186
  if (summary) env.summary.push("vc++ runtime: installed");
@@ -33973,16 +34218,16 @@ var phpBuild = async (spec) => {
33973
34218
  return { version: release.version, ...build.zip };
33974
34219
  };
33975
34220
  var writePhpIni = (home) => {
33976
- const ini = path74.join(home, "php.ini");
33977
- if (exists(ini) || !exists(path74.join(home, "php.ini-development"))) return;
33978
- let text = fs57.readFileSync(path74.join(home, "php.ini-development"), "utf8").replace(/^;\s*extension_dir\s*=\s*"ext"/m, 'extension_dir = "' + path74.join(home, "ext") + '"');
33979
- for (const ext of PHP_EXTENSIONS.filter((e) => exists(path74.join(home, "ext", "php_" + e + ".dll"))))
34221
+ const ini = path73.join(home, "php.ini");
34222
+ if (exists(ini) || !exists(path73.join(home, "php.ini-development"))) return;
34223
+ let text = fs56.readFileSync(path73.join(home, "php.ini-development"), "utf8").replace(/^;\s*extension_dir\s*=\s*"ext"/m, 'extension_dir = "' + path73.join(home, "ext") + '"');
34224
+ for (const ext of PHP_EXTENSIONS.filter((e) => exists(path73.join(home, "ext", "php_" + e + ".dll"))))
33980
34225
  text = text.replace(new RegExp("^;(extension=" + ext + ")\\s*$", "m"), "$1");
33981
- fs57.writeFileSync(ini + ".tmp", text);
33982
- fs57.renameSync(ini + ".tmp", ini);
34226
+ fs56.writeFileSync(ini + ".tmp", text);
34227
+ fs56.renameSync(ini + ".tmp", ini);
33983
34228
  };
33984
34229
  var shim2 = (env, name, command) => {
33985
- fs57.writeFileSync(path74.join(mkdirp(tool("shims")), name + ".cmd"), "@echo off\r\n" + command + " %*\r\n");
34230
+ fs56.writeFileSync(path73.join(mkdirp(tool("shims")), name + ".cmd"), "@echo off\r\n" + command + " %*\r\n");
33986
34231
  env.prepend.push(tool("shims"));
33987
34232
  };
33988
34233
  var setupComposer = async (env, php) => {
@@ -33994,18 +34239,18 @@ var setupComposer = async (env, php) => {
33994
34239
  }
33995
34240
  const composerHome = tool("composer-home");
33996
34241
  env.vars.COMPOSER_HOME = composerHome;
33997
- env.prepend.push(path74.join(composerHome, "vendor", "bin"));
34242
+ env.prepend.push(path73.join(composerHome, "vendor", "bin"));
33998
34243
  shim2(env, "composer", '"' + php + '" "' + phar + '"');
33999
34244
  env.summary.push(
34000
34245
  "composer: " + (/\d+\.\d+\.\d+/.exec(execOutput(php, [phar, "--version", "--no-ansi"]))?.[0] ?? "installed")
34001
34246
  );
34002
34247
  };
34003
34248
  var PHP_RELEASES = "https://windows.php.net/downloads/releases/";
34004
- var phpCache = (zip) => tool("downloads", "php-" + path74.basename(zip));
34249
+ var phpCache = (zip) => tool("downloads", "php-" + path73.basename(zip));
34005
34250
  async function fetchPhp(config2) {
34006
34251
  const spec = versionFromFiles([".php-version"]) ?? { spec: config2.version, source: "config" };
34007
34252
  const version2 = await resolveCached("php:" + spec.spec, async () => (await phpBuild(spec.spec)).version);
34008
- if (exists(path74.join(tool("php", version2), "php.exe"))) return;
34253
+ if (exists(path73.join(tool("php", version2), "php.exe"))) return;
34009
34254
  const build = await phpBuild(version2);
34010
34255
  await downloader.file(PHP_RELEASES + build.path, phpCache(build.path), build.sha256);
34011
34256
  }
@@ -34018,7 +34263,7 @@ async function setupPhp(env, config2) {
34018
34263
  await setupVcRuntime(env, false);
34019
34264
  const version2 = await resolveCached("php:" + wantedSpec.spec, async () => (await phpBuild(wantedSpec.spec)).version);
34020
34265
  const home = tool("php", version2);
34021
- if (!exists(path74.join(home, "php.exe"))) {
34266
+ if (!exists(path73.join(home, "php.exe"))) {
34022
34267
  const build = await phpBuild(version2);
34023
34268
  log("Downloading PHP " + version2 + " (~30 MB once) ...");
34024
34269
  await downloader.archive(PHP_RELEASES + build.path, home, {
@@ -34031,11 +34276,11 @@ async function setupPhp(env, config2) {
34031
34276
  writePhpIni(home);
34032
34277
  env.prepend.push(home);
34033
34278
  env.summary.push("php: " + version2 + " (from " + wantedSpec.source + ")");
34034
- if (config2.composer) await setupComposer(env, path74.join(home, "php.exe"));
34279
+ if (config2.composer) await setupComposer(env, path73.join(home, "php.exe"));
34035
34280
  }
34036
34281
 
34037
34282
  // src/guest/toolchains/languages/ruby.ts
34038
- import path75 from "node:path";
34283
+ import path74 from "node:path";
34039
34284
  var RUBY_ASSET = /^rubyinstaller-(\d+\.\d+\.\d+)-(\d+)-x64\.7z$/;
34040
34285
  var buildNumber = (asset) => Number(RUBY_ASSET.exec(asset.name)?.[2] ?? 0);
34041
34286
  var rubyBuilds = async () => {
@@ -34063,7 +34308,7 @@ async function setupRuby(env, config2) {
34063
34308
  async () => pickPackageVersion([...(await rubyBuilds()).keys()], wantedSpec.spec) ?? Promise.reject(new Error('No RubyInstaller build matches "' + wantedSpec.spec + '"'))
34064
34309
  );
34065
34310
  const home = tool("ruby", version2);
34066
- if (!exists(path75.join(home, "bin", "ruby.exe"))) {
34311
+ if (!exists(path74.join(home, "bin", "ruby.exe"))) {
34067
34312
  const asset = (await rubyBuilds()).get(version2);
34068
34313
  if (!asset) throw new Error("RubyInstaller " + version2 + " is no longer published");
34069
34314
  log("Downloading Ruby " + version2 + " (~100 MB once) ...");
@@ -34076,11 +34321,11 @@ async function setupRuby(env, config2) {
34076
34321
  }
34077
34322
  const gems = tool("ruby-gems", version2.split(".").slice(0, 2).join("."));
34078
34323
  Object.assign(env.vars, { GEM_HOME: gems, BUNDLE_USER_HOME: tool("bundle-home") });
34079
- env.prepend.push(path75.join(home, "bin"), path75.join(gems, "bin"));
34324
+ env.prepend.push(path74.join(home, "bin"), path74.join(gems, "bin"));
34080
34325
  env.summary.push(
34081
- "ruby: " + versionOf(path75.join(home, "bin", "ruby.exe")) + " (from " + wantedSpec.source + "; gems with C extensions need MSYS2, not included)"
34326
+ "ruby: " + versionOf(path74.join(home, "bin", "ruby.exe")) + " (from " + wantedSpec.source + "; gems with C extensions need MSYS2, not included)"
34082
34327
  );
34083
- const gem = path75.join(home, "bin", "gem.cmd");
34328
+ const gem = path74.join(home, "bin", "gem.cmd");
34084
34329
  await installOnce(
34085
34330
  env,
34086
34331
  "gem@" + version2,
@@ -34092,9 +34337,9 @@ async function setupRuby(env, config2) {
34092
34337
  }
34093
34338
 
34094
34339
  // src/guest/toolchains/tools/vscode.ts
34095
- import fs58 from "node:fs";
34340
+ import fs57 from "node:fs";
34096
34341
  import os11 from "node:os";
34097
- import path76 from "node:path";
34342
+ import path75 from "node:path";
34098
34343
 
34099
34344
  // node_modules/jsonc-parser/lib/esm/impl/scanner.js
34100
34345
  var CharacterCodes;
@@ -34274,14 +34519,14 @@ var ParseErrorCode;
34274
34519
  var VERSION_MARKER = ".agent-sandbox-version";
34275
34520
  var desktopShortcut = (exe) => {
34276
34521
  if (!isWin) return;
34277
- const link = path76.join(os11.homedir(), "Desktop", "Visual Studio Code.lnk");
34522
+ const link = path75.join(os11.homedir(), "Desktop", "Visual Studio Code.lnk");
34278
34523
  runScriptWithJson("new-shortcuts.ps1", "ListFile", [
34279
34524
  { link, target: exe, arguments: '"' + (process.env.AGENT_WORKSPACE ?? "") + '"' }
34280
34525
  ]);
34281
34526
  };
34282
34527
  async function setupVscode(env, refresh) {
34283
34528
  const root = tool("vscode");
34284
- const exe = path76.join(root, "Code.exe");
34529
+ const exe = path75.join(root, "Code.exe");
34285
34530
  if (dryRun) {
34286
34531
  log("(dry run) would provision VS Code");
34287
34532
  return;
@@ -34291,11 +34536,11 @@ async function setupVscode(env, refresh) {
34291
34536
  "https://update.code.visualstudio.com/api/update/win32-" + (arch === "arm64" ? "arm64" : "x64") + "-archive/stable/latest"
34292
34537
  );
34293
34538
  log("Downloading VS Code " + release.productVersion + " (~150 MB once) ...");
34294
- const keep = path76.join(root, "data");
34539
+ const keep = path75.join(root, "data");
34295
34540
  const parked = root + "-data";
34296
34541
  if (exists(keep)) {
34297
- fs58.rmSync(parked, { recursive: true, force: true });
34298
- fs58.renameSync(keep, parked);
34542
+ fs57.rmSync(parked, { recursive: true, force: true });
34543
+ fs57.renameSync(keep, parked);
34299
34544
  }
34300
34545
  try {
34301
34546
  await downloader.archive(release.url, root, {
@@ -34303,77 +34548,77 @@ async function setupVscode(env, refresh) {
34303
34548
  locate: "Code.exe",
34304
34549
  fileName: "vscode.zip"
34305
34550
  });
34306
- fs58.writeFileSync(path76.join(root, VERSION_MARKER), release.productVersion);
34551
+ fs57.writeFileSync(path75.join(root, VERSION_MARKER), release.productVersion);
34307
34552
  } finally {
34308
34553
  if (exists(parked)) {
34309
34554
  mkdirp(root);
34310
- fs58.rmSync(keep, { recursive: true, force: true });
34311
- fs58.renameSync(parked, keep);
34555
+ fs57.rmSync(keep, { recursive: true, force: true });
34556
+ fs57.renameSync(parked, keep);
34312
34557
  }
34313
34558
  }
34314
34559
  }
34315
- mkdirp(path76.join(root, "data"));
34316
- env.prepend.push(path76.join(root, "bin"));
34560
+ mkdirp(path75.join(root, "data"));
34561
+ env.prepend.push(path75.join(root, "bin"));
34317
34562
  desktopShortcut(exe);
34318
- const version2 = exists(path76.join(root, VERSION_MARKER)) ? fs58.readFileSync(path76.join(root, VERSION_MARKER), "utf8").trim() : "installed";
34563
+ const version2 = exists(path75.join(root, VERSION_MARKER)) ? fs57.readFileSync(path75.join(root, VERSION_MARKER), "utf8").trim() : "installed";
34319
34564
  env.summary.push("vscode: " + version2 + " (portable; run code . or use the desktop shortcut)");
34320
34565
  }
34321
34566
 
34322
34567
  // src/guest/toolchains/steam/steam.ts
34323
- import fs61 from "node:fs";
34324
- import path80 from "node:path";
34568
+ import fs60 from "node:fs";
34569
+ import path79 from "node:path";
34325
34570
 
34326
34571
  // src/guest/toolchains/steam/client.ts
34327
- import fs59 from "node:fs";
34328
- import path78 from "node:path";
34572
+ import fs58 from "node:fs";
34573
+ import path77 from "node:path";
34329
34574
 
34330
34575
  // src/guest/toolchains/steam/commands.ts
34331
- import path77 from "node:path";
34576
+ import path76 from "node:path";
34332
34577
  var STEAMCMD_DIR = "C:\\SteamCMD";
34333
34578
  var STEAMCMD_URL = "https://steamcdn-a.akamaihd.net/client/installer/steamcmd.zip";
34334
34579
  var STEAM_CLIENT_URL = "https://steamcdn-a.akamaihd.net/client/installer/SteamSetup.exe";
34335
34580
  function steamCmdStore(tools = toolsDir) {
34336
- return path77.join(tools, "steamcmd");
34581
+ return path76.join(tools, "steamcmd");
34337
34582
  }
34338
34583
  function steamClientDir(tools = toolsDir) {
34339
- return path77.join(tools, "steam");
34584
+ return path76.join(tools, "steam");
34340
34585
  }
34341
34586
  var MAX_SCRIPT_BYTES = 256 * 1024;
34342
34587
 
34343
34588
  // src/guest/toolchains/steam/client.ts
34344
- var GB2 = 1024 ** 3;
34345
- var CLIENT_NEED_BYTES = 2 * GB2;
34589
+ var GB3 = 1024 ** 3;
34590
+ var CLIENT_NEED_BYTES = 2 * GB3;
34346
34591
  var SETUP_TIMEOUT_MS = 10 * 60 * 1e3;
34347
34592
  function installedSteamClient() {
34348
- const exe = path78.join(steamClientDir(), "steam.exe");
34593
+ const exe = path77.join(steamClientDir(), "steam.exe");
34349
34594
  return exists(exe) && signedBy(exe, SIGNERS.valve) ? exe : null;
34350
34595
  }
34351
34596
  async function installSteamClient() {
34352
34597
  const dir = steamClientDir();
34353
- const exe = path78.join(dir, "steam.exe");
34598
+ const exe = path77.join(dir, "steam.exe");
34354
34599
  if (exists(exe)) {
34355
34600
  if (!signedBy(exe, SIGNERS.valve)) throw new Error("tools\\steam\\steam.exe is not signed by Valve");
34356
34601
  return exe;
34357
34602
  }
34358
- fs59.mkdirSync(toolsDir, { recursive: true });
34603
+ fs58.mkdirSync(toolsDir, { recursive: true });
34359
34604
  assertRoom(toolsDir, CLIENT_NEED_BYTES, "the Steam client", "Free room on the data disk.");
34360
34605
  const setup = await signedInstaller(
34361
34606
  STEAM_CLIENT_URL,
34362
- path78.join(tool("steam-setup"), "SteamSetup.exe"),
34607
+ path77.join(tool("steam-setup"), "SteamSetup.exe"),
34363
34608
  "the Steam client installer (~2 MB once)",
34364
34609
  SIGNERS.valve
34365
34610
  );
34366
34611
  const work = stagingFolder(dir);
34367
- fs59.mkdirSync(work, { recursive: true });
34612
+ fs58.mkdirSync(work, { recursive: true });
34368
34613
  try {
34369
34614
  log("Unpacking the Steam client into tools\\steam ...");
34370
34615
  const code = await heavy.run(() => spawnAsync(setup, ["/S", "/D=" + work], { timeout: SETUP_TIMEOUT_MS }));
34371
- const unpacked = path78.join(work, "steam.exe");
34616
+ const unpacked = path77.join(work, "steam.exe");
34372
34617
  if (!exists(unpacked)) throw new Error("SteamSetup.exe did not unpack steam.exe (exit code " + code + ")");
34373
34618
  if (!signedBy(unpacked, SIGNERS.valve)) throw new Error("the unpacked steam.exe is not signed by Valve");
34374
34619
  moveIntoPlace(work, dir);
34375
34620
  } finally {
34376
- if (fs59.existsSync(work)) safeRemove(work, path78.dirname(work));
34621
+ if (fs58.existsSync(work)) safeRemove(work, path77.dirname(work));
34377
34622
  }
34378
34623
  return exe;
34379
34624
  }
@@ -34391,8 +34636,8 @@ async function ensureSteamClient(env) {
34391
34636
 
34392
34637
  // src/guest/toolchains/steam/steamcmd-install.ts
34393
34638
  import { spawn as spawn8 } from "node:child_process";
34394
- import fs60 from "node:fs";
34395
- import path79 from "node:path";
34639
+ import fs59 from "node:fs";
34640
+ import path78 from "node:path";
34396
34641
  var MB = 1024 ** 2;
34397
34642
  var STEAMCMD_NEED_BYTES = 600 * MB;
34398
34643
  var STEAMCMD_UPDATE_TIMEOUT_MS = 15 * 60 * 1e3;
@@ -34417,41 +34662,41 @@ function runWithTimeout(exe, args, cwd, timeoutMs) {
34417
34662
  });
34418
34663
  });
34419
34664
  }
34420
- var notSigned = (file3) => new Error(path79.basename(file3) + " is not signed by Valve: not running it (it is downloaded again next boot)");
34665
+ var notSigned = (file3) => new Error(path78.basename(file3) + " is not signed by Valve: not running it (it is downloaded again next boot)");
34421
34666
  async function fetchSteamCmd(store2, deps) {
34422
- fs60.mkdirSync(path79.dirname(store2), { recursive: true });
34423
- assertRoom(path79.dirname(store2), STEAMCMD_NEED_BYTES, "SteamCMD", "Free room on the data disk.", deps);
34667
+ fs59.mkdirSync(path78.dirname(store2), { recursive: true });
34668
+ assertRoom(path78.dirname(store2), STEAMCMD_NEED_BYTES, "SteamCMD", "Free room on the data disk.", deps);
34424
34669
  const work = stagingFolder(store2);
34425
- const unpacked = path79.join(work, "x");
34670
+ const unpacked = path78.join(work, "x");
34426
34671
  const extract2 = deps.extract ?? extractArchive;
34427
34672
  try {
34428
- fs60.mkdirSync(work, { recursive: true });
34673
+ fs59.mkdirSync(work, { recursive: true });
34429
34674
  const verify = async (part) => {
34430
34675
  await extract2(part, unpacked);
34431
- const exe = path79.join(unpacked, "steamcmd.exe");
34432
- if (!fs60.existsSync(exe)) throw new Error("steamcmd.zip has no steamcmd.exe");
34676
+ const exe = path78.join(unpacked, "steamcmd.exe");
34677
+ if (!fs59.existsSync(exe)) throw new Error("steamcmd.zip has no steamcmd.exe");
34433
34678
  if (!deps.signed(exe)) throw notSigned(exe);
34434
34679
  };
34435
- const zip = path79.join(work, "steamcmd.zip");
34680
+ const zip = path78.join(work, "steamcmd.zip");
34436
34681
  if (deps.download) await deps.download(STEAMCMD_URL, zip, verify);
34437
34682
  else await downloader.file(STEAMCMD_URL, zip, { verify });
34438
34683
  moveIntoPlace(unpacked, store2);
34439
34684
  } finally {
34440
- if (fs60.existsSync(work)) safeRemove(work, path79.dirname(work));
34685
+ if (fs59.existsSync(work)) safeRemove(work, path78.dirname(work));
34441
34686
  }
34442
34687
  }
34443
34688
  async function copyBinaries(from, to) {
34444
- fs60.mkdirSync(to, { recursive: true });
34445
- for (const entry of fs60.readdirSync(from, { withFileTypes: true })) {
34689
+ fs59.mkdirSync(to, { recursive: true });
34690
+ for (const entry of fs59.readdirSync(from, { withFileTypes: true })) {
34446
34691
  if (isPrivate(entry.name) || entry.isSymbolicLink()) continue;
34447
34692
  if (!entry.isFile() && !entry.isDirectory()) continue;
34448
- await fs60.promises.cp(path79.join(from, entry.name), path79.join(to, entry.name), {
34693
+ await fs59.promises.cp(path78.join(from, entry.name), path78.join(to, entry.name), {
34449
34694
  recursive: true,
34450
34695
  force: true,
34451
34696
  verbatimSymlinks: true,
34452
34697
  filter: (source) => {
34453
34698
  try {
34454
- return !fs60.lstatSync(source).isSymbolicLink();
34699
+ return !fs59.lstatSync(source).isSymbolicLink();
34455
34700
  } catch {
34456
34701
  return false;
34457
34702
  }
@@ -34461,41 +34706,41 @@ async function copyBinaries(from, to) {
34461
34706
  }
34462
34707
  function snapshot(dir) {
34463
34708
  try {
34464
- return fs60.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && !isPrivate(e.name) && /\.(exe|dll)$/i.test(e.name)).map((e) => {
34465
- const s = fs60.statSync(path79.join(dir, e.name));
34709
+ return fs59.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && !isPrivate(e.name) && /\.(exe|dll)$/i.test(e.name)).map((e) => {
34710
+ const s = fs59.statSync(path78.join(dir, e.name));
34466
34711
  return e.name.toLowerCase() + ":" + s.size + ":" + Math.floor(s.mtimeMs / 1e3);
34467
34712
  }).sort().join("|");
34468
34713
  } catch {
34469
34714
  return "";
34470
34715
  }
34471
34716
  }
34472
- var bootstrapped = (dir) => BOOTSTRAPPED.some((f) => fs60.existsSync(path79.join(dir, f)));
34717
+ var bootstrapped = (dir) => BOOTSTRAPPED.some((f) => fs59.existsSync(path78.join(dir, f)));
34473
34718
  function scrubStore(store2) {
34474
34719
  let names = [];
34475
34720
  try {
34476
- names = fs60.readdirSync(store2);
34721
+ names = fs59.readdirSync(store2);
34477
34722
  } catch {
34478
34723
  return;
34479
34724
  }
34480
- for (const name of names.filter(isPrivate)) safeRemove(path79.join(store2, name), store2);
34725
+ for (const name of names.filter(isPrivate)) safeRemove(path78.join(store2, name), store2);
34481
34726
  }
34482
34727
  async function prepareSteamCmd(deps) {
34483
34728
  const store2 = deps.storeDir ?? steamCmdStore(deps.toolsDir);
34484
34729
  const work = deps.workDir ?? STEAMCMD_DIR;
34485
34730
  const log2 = deps.log ?? (() => void 0);
34486
- const exe = path79.join(work, "steamcmd.exe");
34487
- if (fs60.existsSync(exe) && bootstrapped(work)) {
34731
+ const exe = path78.join(work, "steamcmd.exe");
34732
+ if (fs59.existsSync(exe) && bootstrapped(work)) {
34488
34733
  if (!deps.signed(exe)) throw notSigned(exe);
34489
34734
  return exe;
34490
34735
  }
34491
- if (!fs60.existsSync(path79.join(store2, "steamcmd.exe"))) {
34736
+ if (!fs59.existsSync(path78.join(store2, "steamcmd.exe"))) {
34492
34737
  log2("Downloading SteamCMD (~3 MB once; it fetches ~300 MB on its first run) ...");
34493
34738
  await fetchSteamCmd(store2, deps);
34494
34739
  }
34495
34740
  scrubStore(store2);
34496
34741
  await copyBinaries(store2, work);
34497
34742
  if (!deps.signed(exe)) {
34498
- safeRemove(store2, path79.dirname(store2));
34743
+ safeRemove(store2, path78.dirname(store2));
34499
34744
  throw notSigned(exe);
34500
34745
  }
34501
34746
  const before = snapshot(work);
@@ -34516,7 +34761,7 @@ async function prepareSteamCmd(deps) {
34516
34761
  await copyBinaries(work, staging);
34517
34762
  moveIntoPlace(staging, store2);
34518
34763
  } finally {
34519
- if (fs60.existsSync(staging)) safeRemove(staging, path79.dirname(staging));
34764
+ if (fs59.existsSync(staging)) safeRemove(staging, path78.dirname(staging));
34520
34765
  }
34521
34766
  }
34522
34767
  return exe;
@@ -34535,10 +34780,10 @@ function signedInAs() {
34535
34780
  }
34536
34781
  function sdkFolder(env, setting) {
34537
34782
  if (!setting.trim()) return;
34538
- const dir = path80.resolve(projectWorkspace(), setting.trim());
34783
+ const dir = path79.resolve(projectWorkspace(), setting.trim());
34539
34784
  let ok = false;
34540
34785
  try {
34541
- ok = fs61.statSync(dir).isDirectory();
34786
+ ok = fs60.statSync(dir).isDirectory();
34542
34787
  } catch {
34543
34788
  }
34544
34789
  if (!ok) {
@@ -34586,14 +34831,14 @@ async function setupUnity(env, _config, _ctx) {
34586
34831
  }
34587
34832
 
34588
34833
  // src/guest/toolchains/fivem/fivem.ts
34589
- import fs63 from "node:fs";
34590
- import path82 from "node:path";
34591
-
34592
- // src/guest/accounts/kinds/cfx.ts
34593
34834
  import fs62 from "node:fs";
34594
34835
  import path81 from "node:path";
34836
+
34837
+ // src/guest/accounts/kinds/cfx.ts
34838
+ import fs61 from "node:fs";
34839
+ import path80 from "node:path";
34595
34840
  function cfxSecretsFile(dir = secretDir("cfx")) {
34596
- return path81.join(dir, "server-secrets.cfg");
34841
+ return path80.join(dir, "server-secrets.cfg");
34597
34842
  }
34598
34843
  function cfxSecretsText(p) {
34599
34844
  return [
@@ -34606,8 +34851,8 @@ function cfxSecretsText(p) {
34606
34851
  }
34607
34852
  function writeCfxSecrets(p, dir = secretDir("cfx")) {
34608
34853
  const file3 = cfxSecretsFile(dir);
34609
- fs62.mkdirSync(dir, { recursive: true });
34610
- fs62.writeFileSync(file3, cfxSecretsText(p), { encoding: "utf8", mode: 384 });
34854
+ fs61.mkdirSync(dir, { recursive: true });
34855
+ fs61.writeFileSync(file3, cfxSecretsText(p), { encoding: "utf8", mode: 384 });
34611
34856
  return file3;
34612
34857
  }
34613
34858
  var cfxAdapter = {
@@ -34708,25 +34953,25 @@ var SelectionSchema = external_exports.strictObject({
34708
34953
  build: external_exports.number().int().positive()
34709
34954
  });
34710
34955
  function fivemStateDir() {
34711
- return path82.join(stateDir, "fivem");
34956
+ return path81.join(stateDir, "fivem");
34712
34957
  }
34713
34958
  function txDataDir() {
34714
- return path82.join(fivemStateDir(), "txData");
34959
+ return path81.join(fivemStateDir(), "txData");
34715
34960
  }
34716
- var selectionFile = () => path82.join(fivemStateDir(), "artifact.json");
34961
+ var selectionFile = () => path81.join(fivemStateDir(), "artifact.json");
34717
34962
  function artifactDir(build) {
34718
- return path82.join(toolsDir, ...ARTIFACTS_NAME.split("/"), String(build));
34963
+ return path81.join(toolsDir, ...ARTIFACTS_NAME.split("/"), String(build));
34719
34964
  }
34720
34965
  function secretsCfg() {
34721
34966
  const file3 = cfxSecretsFile();
34722
- return fs63.existsSync(file3) ? file3 : null;
34967
+ return fs62.existsSync(file3) ? file3 : null;
34723
34968
  }
34724
34969
  function chosenArtifact(setting) {
34725
34970
  const picked = readValid(SelectionSchema, selectionFile());
34726
34971
  return picked ? { setting: picked.artifact, chosen: true, build: picked.build } : { setting, chosen: false, build: null };
34727
34972
  }
34728
34973
  function installedBuilds() {
34729
- return installRecords().filter((r) => r.name === ARTIFACTS_NAME && /^\d+$/.test(r.version)).map((r) => Number(r.version)).filter((b) => fs63.existsSync(path82.join(artifactDir(b), "FXServer.exe"))).sort((a, b) => b - a);
34974
+ return installRecords().filter((r) => r.name === ARTIFACTS_NAME && /^\d+$/.test(r.version)).map((r) => Number(r.version)).filter((b) => fs62.existsSync(path81.join(artifactDir(b), "FXServer.exe"))).sort((a, b) => b - a);
34730
34975
  }
34731
34976
  async function resolveArtifact(setting, live = false) {
34732
34977
  const want = artifactSetting(setting);
@@ -34748,12 +34993,12 @@ async function resolveArtifact(setting, live = false) {
34748
34993
  }
34749
34994
  }
34750
34995
  async function installBuild(a, staging, temp) {
34751
- const zip = path82.join(temp, "server.zip");
34752
- const check2 = path82.join(temp, "check");
34996
+ const zip = path81.join(temp, "server.zip");
34997
+ const check2 = path81.join(temp, "check");
34753
34998
  const verify = async (file3) => {
34754
34999
  await extractArchive(file3, check2, ["FXServer.exe"]);
34755
- const exe2 = path82.join(check2, "FXServer.exe");
34756
- if (artifactTrust(true, fs63.existsSync(exe2) ? signatureOf(exe2)?.subject ?? "" : "") !== "signed")
35000
+ const exe2 = path81.join(check2, "FXServer.exe");
35001
+ if (artifactTrust(true, fs62.existsSync(exe2) ? signatureOf(exe2)?.subject ?? "" : "") !== "signed")
34757
35002
  throw new Error(
34758
35003
  "FXServer build " + a.build + ": FXServer.exe is not validly signed by Rockstar Games, and downloads.requireChecksum is on (Cfx.re publishes no checksums)"
34759
35004
  );
@@ -34762,9 +35007,9 @@ async function installBuild(a, staging, temp) {
34762
35007
  log("Downloading FXServer build " + a.build + " (~65 MB once) ...");
34763
35008
  await downloader.file(a.url, zip, downloader.requireChecksum ? { verify } : null);
34764
35009
  await extractArchive(zip, staging);
34765
- fs63.rmSync(zip, { force: true });
34766
- const exe = path82.join(staging, "FXServer.exe");
34767
- const trust = artifactTrust(downloader.requireChecksum, fs63.existsSync(exe) ? signatureOf(exe)?.subject ?? "" : "");
35010
+ fs62.rmSync(zip, { force: true });
35011
+ const exe = path81.join(staging, "FXServer.exe");
35012
+ const trust = artifactTrust(downloader.requireChecksum, fs62.existsSync(exe) ? signatureOf(exe)?.subject ?? "" : "");
34768
35013
  if (trust === "refused") throw new Error("FXServer build " + a.build + " is not validly signed; not using it");
34769
35014
  if (trust === "unsigned-allowed")
34770
35015
  warn(
@@ -34794,7 +35039,7 @@ async function setupFivem(env, config2, _ctx) {
34794
35039
  }
34795
35040
  const artifact = await resolveArtifact(setting);
34796
35041
  const installed = await installArtifact(artifact, config2.keepVersions);
34797
- fs63.mkdirSync(txDataDir(), { recursive: true });
35042
+ fs62.mkdirSync(txDataDir(), { recursive: true });
34798
35043
  env.vars.FXSERVER_DIR = installed.dir;
34799
35044
  env.vars.FIVEM_GAME = config2.game;
34800
35045
  env.summary.push(
@@ -34828,9 +35073,9 @@ async function setupKotlin(env, _ctx) {
34828
35073
  }
34829
35074
 
34830
35075
  // src/guest/toolchains/native/rust-extras.ts
34831
- import fs64 from "node:fs";
35076
+ import fs63 from "node:fs";
34832
35077
  import os12 from "node:os";
34833
- import path83 from "node:path";
35078
+ import path82 from "node:path";
34834
35079
 
34835
35080
  // src/shared/memory/policy.ts
34836
35081
  var DIAL_STEPS = {
@@ -35085,11 +35330,11 @@ function decide(prev, sample, nowMs, profile, maxCompilers2 = null) {
35085
35330
  const cpuRate = DIAL_CPU_RATE[step] ?? 100;
35086
35331
  if (cpuRate !== prev.cpuRate) actions.push({ kind: "cpu", percent: cpuRate });
35087
35332
  const heavy2 = sample.procs.filter((p) => isHeavyCompiler(p.name)).sort((a, b) => a.pid - b.pid);
35088
- let allowed = compilersAllowed(step, heavy2.length);
35089
- if (maxCompilers2 !== null && step >= 1) allowed = Math.min(allowed, Math.max(1, maxCompilers2));
35333
+ let allowed2 = compilersAllowed(step, heavy2.length);
35334
+ if (maxCompilers2 !== null && step >= 1) allowed2 = Math.min(allowed2, Math.max(1, maxCompilers2));
35090
35335
  const turn = heavy2.length > 0 ? Math.floor(nowMs / ROTATE_MS) % heavy2.length : 0;
35091
35336
  const order = [...heavy2.slice(turn), ...heavy2.slice(0, turn)];
35092
- let waiting = order.slice(Math.min(allowed, order.length));
35337
+ let waiting = order.slice(Math.min(allowed2, order.length));
35093
35338
  if (step >= 2) {
35094
35339
  const waitingPids = new Set(waiting.map((p) => p.pid));
35095
35340
  let linking = 0;
@@ -35148,40 +35393,40 @@ function targetSummary(rust) {
35148
35393
  }
35149
35394
  var cargoTarget = (targetDir) => {
35150
35395
  if (targetDir === "shared" || targetDir === "separate") return null;
35151
- if (targetDir === "local") return path83.join(localDir, "cargo-target");
35396
+ if (targetDir === "local") return path82.join(localDir, "cargo-target");
35152
35397
  return targetDir;
35153
35398
  };
35154
35399
  function cargoShim(env, rust) {
35155
- const real = path83.join(tool("rust", "cargo", "bin"), "cargo.exe");
35400
+ const real = path82.join(tool("rust", "cargo", "bin"), "cargo.exe");
35156
35401
  if (rust.targetDir !== "separate" || !exists(real)) return;
35157
35402
  const dir = mkdirp(tool("shims", "cargo"));
35158
- fs64.copyFileSync(ensureCompiled("cargoshim"), path83.join(dir, "cargo.exe"));
35403
+ fs63.copyFileSync(ensureCompiled("cargoshim"), path82.join(dir, "cargo.exe"));
35159
35404
  env.prepend.unshift(dir);
35160
35405
  env.vars.AGENT_REAL_CARGO = real;
35161
35406
  }
35162
35407
  function linkGate(env, rust, host) {
35163
35408
  const gcc = tool("mingw", "mingw64", "bin", "gcc.exe");
35164
35409
  if (!host.endsWith("-pc-windows-gnu") || !exists(gcc)) return;
35165
- const gate = path83.join(mkdirp(tool("shims")), "linkgate.exe");
35166
- fs64.copyFileSync(ensureCompiled("linkgate"), gate);
35410
+ const gate = path82.join(mkdirp(tool("shims")), "linkgate.exe");
35411
+ fs63.copyFileSync(ensureCompiled("linkgate"), gate);
35167
35412
  const slots = rust.linkSlots === "auto" ? linkerSlots(os12.totalmem() / 1024 ** 2, os12.cpus().length) : rust.linkSlots;
35168
35413
  env.vars.AGENT_LINK_SLOTS = String(slots);
35169
35414
  env.vars.AGENT_REAL_LINKER = gcc;
35170
35415
  env.vars.CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER = gate;
35171
35416
  const rustEnv = { ...process.env, RUSTUP_HOME: tool("rust", "rustup"), CARGO_HOME: tool("rust", "cargo") };
35172
35417
  const sysroot = rust.linker === "lld" ? execOutput(tool("rust", "cargo", "bin", "rustc.exe"), ["--print", "sysroot"], { env: rustEnv }) : "";
35173
- const lld = sysroot ? path83.join(sysroot, "lib", "rustlib", host, "bin", "gcc-ld") : "";
35174
- if (lld && exists(path83.join(lld, "ld.lld.exe"))) env.vars.AGENT_LLD_DIR = lld;
35418
+ const lld = sysroot ? path82.join(sysroot, "lib", "rustlib", host, "bin", "gcc-ld") : "";
35419
+ if (lld && exists(path82.join(lld, "ld.lld.exe"))) env.vars.AGENT_LLD_DIR = lld;
35175
35420
  env.summary.push(
35176
35421
  "rust linking: " + (env.vars.AGENT_LLD_DIR ? "lld" : "GNU ld") + ", at most " + env.vars.AGENT_LINK_SLOTS + " at once"
35177
35422
  );
35178
35423
  }
35179
35424
  function cargoDefaults(host) {
35180
35425
  const file3 = tool("rust", "cargo", "config.toml");
35181
- if (exists(file3) || !exists(path83.dirname(file3))) return;
35426
+ if (exists(file3) || !exists(path82.dirname(file3))) return;
35182
35427
  const jobs = cargoJobs(os12.cpus().length, os12.totalmem() / 1024 ** 3, 1);
35183
35428
  const gnu = host.endsWith("-gnu");
35184
- fs64.writeFileSync(
35429
+ fs63.writeFileSync(
35185
35430
  file3,
35186
35431
  [
35187
35432
  "# Written by windows-development-sandbox once; edit freely, it is never overwritten.",
@@ -35196,7 +35441,7 @@ function rustCaches(rust) {
35196
35441
  const target = cargoTarget(rust.targetDir);
35197
35442
  return {
35198
35443
  ...target ? { CARGO_TARGET_DIR: target } : {},
35199
- ...process.env.SCCACHE_DIR ? {} : { SCCACHE_DIR: path83.join(dataDir, "cache", "sccache") }
35444
+ ...process.env.SCCACHE_DIR ? {} : { SCCACHE_DIR: path82.join(dataDir, "cache", "sccache") }
35200
35445
  };
35201
35446
  }
35202
35447
  function rustHost(config2) {
@@ -35226,7 +35471,6 @@ function plan(config2, versions, o) {
35226
35471
  const unreal = wanted(config2.unreal.enabled, "unreal");
35227
35472
  const android = wanted(config2.android.enabled, "android");
35228
35473
  const vs = visualStudioWanted(config2, (setting, name) => wanted(setting, name));
35229
- const autosdk = unrealUsesAutosdk(config2, (setting, name) => wanted(setting, name));
35230
35474
  const ctx = {
35231
35475
  refresh: o.refresh,
35232
35476
  pcInstalls: o.pcInstalls ?? { items: [] },
@@ -35251,33 +35495,30 @@ function plan(config2, versions, o) {
35251
35495
  enabled: wanted(config2.cpp.enabled, "cpp") || wanted(config2.rust.enabled, "rust"),
35252
35496
  install: (env) => setupCpp(env, config2.cpp)
35253
35497
  },
35254
- // Visual Studio brings MSVC and the real vswhere: the portable MSVC (and its stand-in vswhere) stays out.
35498
+ // Visual Studio brings MSVC and the real vswhere: the portable MSVC (and its stand-in vswhere) stays out. Only the
35499
+ // first install goes to the background: a saved copy is back in seconds, before the agent starts.
35255
35500
  {
35256
35501
  name: "Visual Studio",
35257
35502
  enabled: vs !== null,
35258
35503
  shared: true,
35259
- background: deferred,
35504
+ background: deferred && !visualStudioSaved(vs),
35260
35505
  ...ahead(() => prefetchVisualStudio(vs)),
35261
35506
  install: async (env) => {
35262
- await ensureVisualStudio(env, vs, { keepInstallFiles: config2.unreal.keepInstallFiles, lowPriority: deferred });
35507
+ await ensureVisualStudio(env, vs, { lowPriority: deferred });
35263
35508
  }
35264
35509
  },
35265
35510
  {
35266
35511
  name: "Unreal",
35267
35512
  enabled: unreal,
35268
35513
  shared: true,
35269
- after: ["Visual Studio", "MSVC"],
35514
+ after: ["Visual Studio"],
35270
35515
  ...ahead(() => fetchDirectX(config2.unreal)),
35271
35516
  install: (env) => setupUnreal(env, config2.unreal, ctx)
35272
35517
  },
35273
35518
  {
35274
35519
  name: "MSVC",
35275
- enabled: (wanted(config2.msvc.enabled, "msvc") || autosdk && config2.msvc.enabled !== false) && vs === null,
35276
- // The same Visual Studio licence terms, which Unreal's acceptLicense already names.
35277
- install: (env) => setupMsvc(
35278
- env,
35279
- autosdk ? { ...config2.msvc, acceptLicense: config2.msvc.acceptLicense || config2.unreal.acceptLicense } : config2.msvc
35280
- )
35520
+ enabled: wanted(config2.msvc.enabled, "msvc") && vs === null,
35521
+ install: (env) => setupMsvc(env, config2.msvc)
35281
35522
  },
35282
35523
  // Rust links with MSVC (msvc host) or MinGW's gcc (GNU host): whichever it uses goes first.
35283
35524
  {
@@ -35350,10 +35591,11 @@ function plan(config2, versions, o) {
35350
35591
  },
35351
35592
  { name: "Ruby", enabled: wanted(config2.ruby.enabled, "ruby"), install: (env) => setupRuby(env, config2.ruby) },
35352
35593
  // PHP installs the Visual C++ runtime itself: one installer at a time.
35353
- // Many apps (bat, delta, Neovim, most GUIs, your own programs) are built against it too.
35594
+ // Many apps (bat, delta, Neovim, most GUIs, your own programs) are built against it too, and so is what Visual
35595
+ // Studio builds: a Visual Studio put back from the data disk does not bring it, as its installer did.
35354
35596
  {
35355
35597
  name: "Visual C++ runtime",
35356
- enabled: config2.vcRuntime.enabled || apps,
35598
+ enabled: config2.vcRuntime.enabled || apps || vs !== null,
35357
35599
  shared: true,
35358
35600
  ...ahead(fetchVcRuntime),
35359
35601
  install: async (env) => {
@@ -35425,19 +35667,19 @@ function plan(config2, versions, o) {
35425
35667
  // src/guest/toolchains/step-scheduler.ts
35426
35668
  import { AsyncLocalStorage as AsyncLocalStorage4 } from "node:async_hooks";
35427
35669
  var PARALLEL2 = 4;
35428
- async function runReported(sink, name, env, work) {
35670
+ async function runReported(sink2, name, env, work) {
35429
35671
  try {
35430
35672
  await work();
35431
35673
  } catch (e) {
35432
- sink.warn(
35674
+ sink2.warn(
35433
35675
  name + " could not be set up and is skipped; everything else still works, and the next start tries again. Reason: " + errMsg(e)
35434
35676
  );
35435
35677
  env.summary.push(name + ": FAILED");
35436
35678
  }
35437
35679
  }
35438
35680
  var StepScheduler = class {
35439
- constructor(sink, parallel = PARALLEL2) {
35440
- this.sink = sink;
35681
+ constructor(sink2, parallel = PARALLEL2) {
35682
+ this.sink = sink2;
35441
35683
  this.parallel = parallel;
35442
35684
  }
35443
35685
  sink;
@@ -35624,7 +35866,7 @@ async function setupToolchains(config2, versions, options, run2 = {}, extras = {
35624
35866
  const have = new Set(steps.map((s) => s.name));
35625
35867
  const installed = installedToolPaths(
35626
35868
  toolsDir,
35627
- { exists: fs65.existsSync, list: (dir) => fs65.existsSync(dir) ? fs65.readdirSync(dir) : [] },
35869
+ { exists: fs64.existsSync, list: (dir) => fs64.existsSync(dir) ? fs64.readdirSync(dir) : [] },
35628
35870
  /* @__PURE__ */ new Set([...have.has("Python") ? ["python"] : [], ...have.has("Rust") ? ["rust"] : []])
35629
35871
  );
35630
35872
  result.append.push(...installed.append);
@@ -35650,21 +35892,21 @@ function cmdSet(env, names) {
35650
35892
  return names.filter((n) => env[n] !== void 0 && !/[\r\n]/.test(String(env[n]))).map((n) => '@set "' + n + "=" + String(env[n]).replace(/%/g, "%%") + '"');
35651
35893
  }
35652
35894
  function writeShell(spec, env, names) {
35653
- const dir = mkdirp(path84.join(localDir, "projects", spec.name));
35654
- fs66.writeFileSync(path84.join(dir, "env.cmd"), [...cmdSet(env, [...names, "PATH"]), ""].join("\r\n"));
35655
- fs66.writeFileSync(
35656
- path84.join(dir, "shell.cmd"),
35657
- ['@call "' + path84.join(dir, "env.cmd") + '"', '@cd /d "' + spec.workspace + '"', "@title " + spec.name, ""].join(
35895
+ const dir = mkdirp(path83.join(localDir, "projects", spec.name));
35896
+ fs65.writeFileSync(path83.join(dir, "env.cmd"), [...cmdSet(env, [...names, "PATH"]), ""].join("\r\n"));
35897
+ fs65.writeFileSync(
35898
+ path83.join(dir, "shell.cmd"),
35899
+ ['@call "' + path83.join(dir, "env.cmd") + '"', '@cd /d "' + spec.workspace + '"', "@title " + spec.name, ""].join(
35658
35900
  "\r\n"
35659
35901
  )
35660
35902
  );
35661
- const bin = mkdirp(path84.join(localDir, "bin"));
35662
- fs66.writeFileSync(
35663
- path84.join(bin, "sbx-shell.cmd"),
35903
+ const bin = mkdirp(path83.join(localDir, "bin"));
35904
+ fs65.writeFileSync(
35905
+ path83.join(bin, "sbx-shell.cmd"),
35664
35906
  [
35665
- '@if "%~1"=="" (echo Usage: sbx-shell ^<project^> ^(a terminal in that project with its tools^) & dir /b "' + path84.join(localDir, "projects") + '" & exit /b 2)',
35666
- '@if not exist "' + path84.join(localDir, "projects") + '\\%~1\\shell.cmd" (echo No project %~1 in this sandbox. & exit /b 2)',
35667
- '@cmd /k ""' + path84.join(localDir, "projects") + '\\%~1\\shell.cmd""',
35907
+ '@if "%~1"=="" (echo Usage: sbx-shell ^<project^> ^(a terminal in that project with its tools^) & dir /b "' + path83.join(localDir, "projects") + '" & exit /b 2)',
35908
+ '@if not exist "' + path83.join(localDir, "projects") + '\\%~1\\shell.cmd" (echo No project %~1 in this sandbox. & exit /b 2)',
35909
+ '@cmd /k ""' + path83.join(localDir, "projects") + '\\%~1\\shell.cmd""',
35668
35910
  ""
35669
35911
  ].join("\r\n")
35670
35912
  );
@@ -35722,10 +35964,10 @@ async function setUp(spec, say) {
35722
35964
  }
35723
35965
  )
35724
35966
  );
35725
- tools.prepend.push(path84.join(localDir, "bin"));
35967
+ tools.prepend.push(path83.join(localDir, "bin"));
35726
35968
  const env = agentEnv(tools, { workspace: spec.workspace, project: spec.name, base });
35727
- const specFile = path84.join(mkdirp(path84.join(localDir, "projects", spec.name)), "project.json");
35728
- fs66.writeFileSync(specFile, JSON.stringify(spec));
35969
+ const specFile = path83.join(mkdirp(path83.join(localDir, "projects", spec.name)), "project.json");
35970
+ fs65.writeFileSync(specFile, JSON.stringify(spec));
35729
35971
  env.AGENT_PROJECT_FILE = specFile;
35730
35972
  addMachineEnvironment(tools.vars, [...tools.prepend, ...tools.append], true);
35731
35973
  try {
@@ -35842,8 +36084,8 @@ function execCommand(req) {
35842
36084
  }
35843
36085
 
35844
36086
  // src/guest/daemon/sessions.ts
35845
- import fs73 from "node:fs";
35846
- import path93 from "node:path";
36087
+ import fs72 from "node:fs";
36088
+ import path92 from "node:path";
35847
36089
  import crypto7 from "node:crypto";
35848
36090
  import os16 from "node:os";
35849
36091
  import { spawn as spawn12 } from "node:child_process";
@@ -35924,7 +36166,7 @@ async function sendControl(endpoint, type) {
35924
36166
  var MAX_CLIPBOARD_STRING = 1024 * 1024;
35925
36167
 
35926
36168
  // src/guest/sessions/cmdline.ts
35927
- import path85 from "node:path";
36169
+ import path84 from "node:path";
35928
36170
  var quoted = (arg) => '"' + arg.replace(/(\\*)"/g, '$1$1\\"').replace(/(\\+)$/, "$1$1") + '"';
35929
36171
  function quoteArg(arg) {
35930
36172
  return arg !== "" && !/[\s"]/.test(arg) ? arg : quoted(arg);
@@ -35938,7 +36180,7 @@ function cmdArgs(args) {
35938
36180
  }).join("");
35939
36181
  }
35940
36182
  function commandLine(file3, args) {
35941
- return path85.win32.basename(file3).toLowerCase() === "cmd.exe" ? [quoteArg(file3), cmdArgs(args)].filter(Boolean).join(" ") : [file3, ...args].map(quoteArg).join(" ");
36183
+ return path84.win32.basename(file3).toLowerCase() === "cmd.exe" ? [quoteArg(file3), cmdArgs(args)].filter(Boolean).join(" ") : [file3, ...args].map(quoteArg).join(" ");
35942
36184
  }
35943
36185
  function shellLaunch(asked, paths) {
35944
36186
  if (asked === "cmd") return { name: "cmd", file: paths.cmd, args: [] };
@@ -35952,8 +36194,8 @@ function shellLaunch(asked, paths) {
35952
36194
  }
35953
36195
 
35954
36196
  // src/guest/sessions/pty-host.ts
35955
- import fs67 from "node:fs";
35956
- import path86 from "node:path";
36197
+ import fs66 from "node:fs";
36198
+ import path85 from "node:path";
35957
36199
  import { execFile, spawn as spawn10 } from "node:child_process";
35958
36200
  function ensurePtyHost() {
35959
36201
  return ensureCompiled("ptyhost");
@@ -35972,21 +36214,21 @@ async function waitForPtyHost(child, port, timeoutMs) {
35972
36214
  throw new Error("the session host did not start listening on port " + port);
35973
36215
  }
35974
36216
  function ptyHostLog(id) {
35975
- return path86.join(logsDir, "ptyhost-" + id + ".log");
36217
+ return path85.join(logsDir, "ptyhost-" + id + ".log");
35976
36218
  }
35977
36219
  function ptyHostLogTail(id, lines = 12) {
35978
36220
  try {
35979
- return fs67.readFileSync(ptyHostLog(id), "utf8").trim().split(/\r?\n/).slice(-lines).join("\n");
36221
+ return fs66.readFileSync(ptyHostLog(id), "utf8").trim().split(/\r?\n/).slice(-lines).join("\n");
35980
36222
  } catch {
35981
36223
  return "";
35982
36224
  }
35983
36225
  }
35984
36226
  var conptyDll = () => {
35985
- const dll = path86.join(toolsDir, "conpty", "conpty.dll");
35986
- return session.provisioning.conpty?.enabled !== false && fs67.existsSync(dll) && fs67.existsSync(path86.join(toolsDir, "conpty", "OpenConsole.exe")) ? dll : null;
36227
+ const dll = path85.join(toolsDir, "conpty", "conpty.dll");
36228
+ return session.provisioning.conpty?.enabled !== false && fs66.existsSync(dll) && fs66.existsSync(path85.join(toolsDir, "conpty", "OpenConsole.exe")) ? dll : null;
35987
36229
  };
35988
36230
  function startPtyHost(o) {
35989
- fs67.mkdirSync(run.treesDir, { recursive: true });
36231
+ fs66.mkdirSync(run.treesDir, { recursive: true });
35990
36232
  const env = {
35991
36233
  ...o.env,
35992
36234
  PTYHOST_BIND: o.remote ? "any" : "loopback",
@@ -36004,13 +36246,13 @@ function startPtyHost(o) {
36004
36246
  var END_TREE_MS = 3e4;
36005
36247
  function endLeftoverTree(id, exe = ensurePtyHost()) {
36006
36248
  const file3 = run.treeFile(id);
36007
- if (!fs67.existsSync(file3)) return Promise.resolve(null);
36249
+ if (!fs66.existsSync(file3)) return Promise.resolve(null);
36008
36250
  return new Promise((resolve2) => {
36009
36251
  execFile(exe, ["--end-tree", file3], { timeout: END_TREE_MS, windowsHide: true }, (error62, stdout) => {
36010
36252
  const code = error62 ? typeof error62.code === "number" ? error62.code : -1 : 0;
36011
36253
  if (code !== 3)
36012
36254
  try {
36013
- fs67.rmSync(file3, { force: true });
36255
+ fs66.rmSync(file3, { force: true });
36014
36256
  } catch {
36015
36257
  }
36016
36258
  resolve2(code === 0 ? stdout.trim().slice(0, 200) : code === 3 ? null : "could not end them (code " + code + ")");
@@ -36019,15 +36261,15 @@ function endLeftoverTree(id, exe = ensurePtyHost()) {
36019
36261
  }
36020
36262
  function recordedTrees() {
36021
36263
  try {
36022
- return fs67.readdirSync(run.treesDir).filter((n) => /^[A-Za-z0-9_-]{1,64}\.json$/.test(n)).map((n) => n.slice(0, -".json".length));
36264
+ return fs66.readdirSync(run.treesDir).filter((n) => /^[A-Za-z0-9_-]{1,64}\.json$/.test(n)).map((n) => n.slice(0, -".json".length));
36023
36265
  } catch {
36024
36266
  return [];
36025
36267
  }
36026
36268
  }
36027
36269
 
36028
36270
  // src/guest/agents/agent-installer.ts
36029
- import fs68 from "node:fs";
36030
- import path87 from "node:path";
36271
+ import fs67 from "node:fs";
36272
+ import path86 from "node:path";
36031
36273
 
36032
36274
  // src/guest/agents/profile-links.ts
36033
36275
  var profileRoot = () => process.env.USERPROFILE ?? "";
@@ -36053,7 +36295,7 @@ var agentPaths2 = (name, harness) => agentPaths(toolsDir, name, harness);
36053
36295
  async function installViaNpm(name, harness, dir, env) {
36054
36296
  if (!harness.npmPackage)
36055
36297
  throw new Error("No npmPackage configured for " + name + " and no host executable was available.");
36056
- const npmCli = path87.join(path87.dirname(process.execPath), "node_modules", "npm", "bin", "npm-cli.js");
36298
+ const npmCli = path86.join(path86.dirname(process.execPath), "node_modules", "npm", "bin", "npm-cli.js");
36057
36299
  const args = [npmCli, "install", "--global", "--prefix", dir, harness.npmPackage, "--no-fund", "--no-audit"];
36058
36300
  log("Installing " + harness.npmPackage + " (this can take a minute)...");
36059
36301
  if (dryRun) {
@@ -36064,7 +36306,7 @@ async function installViaNpm(name, harness, dir, env) {
36064
36306
  await execHeavy(process.execPath, args, { env });
36065
36307
  }
36066
36308
  async function installViaUv(name, harness, dir, env) {
36067
- const uv = path87.join(toolsDir, "uv", "uv.exe");
36309
+ const uv = path86.join(toolsDir, "uv", "uv.exe");
36068
36310
  log("Installing " + harness.uvPackage + " with uv (this can take a minute)...");
36069
36311
  if (dryRun) {
36070
36312
  log("(dry run) uv tool install " + harness.uvPackage);
@@ -36079,8 +36321,8 @@ async function installViaUv(name, harness, dir, env) {
36079
36321
  });
36080
36322
  }
36081
36323
  function putOnPath(dir, env) {
36082
- const parts2 = (env.PATH ?? "").split(path87.delimiter);
36083
- if (!parts2.some((p) => p.toLowerCase() === dir.toLowerCase())) env.PATH = [...parts2, dir].join(path87.delimiter);
36324
+ const parts2 = (env.PATH ?? "").split(path86.delimiter);
36325
+ if (!parts2.some((p) => p.toLowerCase() === dir.toLowerCase())) env.PATH = [...parts2, dir].join(path86.delimiter);
36084
36326
  addMachineEnvironment({}, [dir], true);
36085
36327
  }
36086
36328
  var AgentInstaller = class {
@@ -36121,9 +36363,9 @@ var AgentInstaller = class {
36121
36363
  }
36122
36364
  mkdirp(p.dir);
36123
36365
  if (this.sourceOf(name, harness) === "host") {
36124
- const source = path87.join(hostToolsDir, "agents", name, harness.hostExecutable);
36366
+ const source = path86.join(hostToolsDir, "agents", name, harness.hostExecutable);
36125
36367
  if (exists(source) && p.exe) {
36126
- fs68.copyFileSync(source, p.exe);
36368
+ fs67.copyFileSync(source, p.exe);
36127
36369
  log("Copied " + name + " from this PC: " + source);
36128
36370
  return;
36129
36371
  }
@@ -36144,22 +36386,22 @@ function guestAddresses() {
36144
36386
  }
36145
36387
 
36146
36388
  // src/guest/sessions/conversation.ts
36147
- import fs69 from "node:fs";
36148
- import path88 from "node:path";
36389
+ import fs68 from "node:fs";
36390
+ import path87 from "node:path";
36149
36391
  var MAX_FILES = 2e3;
36150
36392
  function conversationFiles(claudeDir2, cwd) {
36151
36393
  const names = /* @__PURE__ */ new Set([projectFolderName(cwd), projectFolderName(sandboxFolder(cwd))]);
36152
36394
  return [...names].flatMap((name) => {
36153
- const dir = path88.join(claudeDir2, "projects", name);
36395
+ const dir = path87.join(claudeDir2, "projects", name);
36154
36396
  let entries2;
36155
36397
  try {
36156
- entries2 = fs69.readdirSync(dir);
36398
+ entries2 = fs68.readdirSync(dir);
36157
36399
  } catch {
36158
36400
  return [];
36159
36401
  }
36160
36402
  return entries2.filter((e) => e.endsWith(".jsonl") && isConversationId(e.slice(0, -".jsonl".length))).slice(0, MAX_FILES).flatMap((e) => {
36161
36403
  try {
36162
- return [{ id: e.slice(0, -".jsonl".length), createdMs: fs69.statSync(path88.join(dir, e)).birthtimeMs }];
36404
+ return [{ id: e.slice(0, -".jsonl".length), createdMs: fs68.statSync(path87.join(dir, e)).birthtimeMs }];
36163
36405
  } catch {
36164
36406
  return [];
36165
36407
  }
@@ -36174,8 +36416,8 @@ function findConversation(claudeDir2, cwd, sessionStartMs, claimed) {
36174
36416
  import { spawnSync as spawnSync6 } from "node:child_process";
36175
36417
 
36176
36418
  // src/guest/accounts/watch.ts
36177
- import fs71 from "node:fs";
36178
- import path91 from "node:path";
36419
+ import fs70 from "node:fs";
36420
+ import path90 from "node:path";
36179
36421
 
36180
36422
  // src/guest/accounts/kinds/appstore.ts
36181
36423
  var appstoreAdapter = {
@@ -36186,8 +36428,8 @@ var appstoreAdapter = {
36186
36428
  };
36187
36429
 
36188
36430
  // src/guest/accounts/kinds/epic.ts
36189
- import fs70 from "node:fs";
36190
- import path89 from "node:path";
36431
+ import fs69 from "node:fs";
36432
+ import path88 from "node:path";
36191
36433
  function settingsFile() {
36192
36434
  return epicSettingsFile(localAppData());
36193
36435
  }
@@ -36197,8 +36439,8 @@ var epicAdapter = {
36197
36439
  const file3 = settingsFile();
36198
36440
  const bytes = readBoundedFile(file3, MAX_EPIC_INI_BYTES);
36199
36441
  const read = bytes ? decodeText(bytes) : { text: "", encoding: "utf8" };
36200
- fs70.mkdirSync(path89.dirname(file3), { recursive: true });
36201
- fs70.writeFileSync(file3, encodeText(withEpicLogin(read.text, p), read.encoding));
36442
+ fs69.mkdirSync(path88.dirname(file3), { recursive: true });
36443
+ fs69.writeFileSync(file3, encodeText(withEpicLogin(read.text, p), read.encoding));
36202
36444
  return { summary: "Epic Games Launcher: signed in with your saved sign-in" };
36203
36445
  },
36204
36446
  current() {
@@ -36278,13 +36520,13 @@ var ADAPTERS = {
36278
36520
  };
36279
36521
 
36280
36522
  // src/guest/accounts/apply.ts
36281
- import path90 from "node:path";
36523
+ import path89 from "node:path";
36282
36524
  var DeliveredSchema = external_exports.object({
36283
36525
  fingerprints: external_exports.partialRecord(external_exports.enum(SERVICE_KINDS), external_exports.string().max(128)),
36284
36526
  leased: external_exports.array(external_exports.enum(SERVICE_KINDS))
36285
36527
  });
36286
36528
  function deliveredFile(root = accountsRoot()) {
36287
- return path90.join(root, "delivered.json");
36529
+ return path89.join(root, "delivered.json");
36288
36530
  }
36289
36531
  function readDelivered(root = accountsRoot()) {
36290
36532
  return readValid(DeliveredSchema, deliveredFile(root)) ?? { fingerprints: {}, leased: [] };
@@ -36333,8 +36575,8 @@ var AccountWatch = class {
36333
36575
  if (!now2) return false;
36334
36576
  const print = fingerprint2(now2);
36335
36577
  if (print === this.last.get(kind)) return false;
36336
- const file3 = path91.join(this.o.dataDir, ...HANDOFF_PARTS, kind + ".json");
36337
- fs71.mkdirSync(path91.dirname(file3), { recursive: true });
36578
+ const file3 = path90.join(this.o.dataDir, ...HANDOFF_PARTS, kind + ".json");
36579
+ fs70.mkdirSync(path90.dirname(file3), { recursive: true });
36338
36580
  writeJsonAtomic(file3, { kind, launchId: this.o.launchId, payload: now2 });
36339
36581
  this.last.set(kind, print);
36340
36582
  return true;
@@ -36504,9 +36746,9 @@ var GovernorCore = class {
36504
36746
  };
36505
36747
 
36506
36748
  // src/guest/governor/governor.ts
36507
- import fs72 from "node:fs";
36749
+ import fs71 from "node:fs";
36508
36750
  import os14 from "node:os";
36509
- import path92 from "node:path";
36751
+ import path91 from "node:path";
36510
36752
  import { spawn as spawn11 } from "node:child_process";
36511
36753
  import { createInterface } from "node:readline";
36512
36754
  var SampleSchema = external_exports.object({
@@ -36579,12 +36821,12 @@ var MemGovProcess = class {
36579
36821
  };
36580
36822
  function appendToMemoryLog(line) {
36581
36823
  try {
36582
- const logs = path92.join(dataDir, "logs");
36583
- const newest = fs72.readdirSync(logs).filter((f) => /^memory-\d{8}-\d{6}\.log$/.test(f)).sort().pop();
36824
+ const logs = path91.join(dataDir, "logs");
36825
+ const newest = fs71.readdirSync(logs).filter((f) => /^memory-\d{8}-\d{6}\.log$/.test(f)).sort().pop();
36584
36826
  if (!newest) return;
36585
36827
  const t = /* @__PURE__ */ new Date();
36586
36828
  const stamp = [t.getHours(), t.getMinutes(), t.getSeconds()].map((n) => String(n).padStart(2, "0")).join(":");
36587
- fs72.appendFileSync(path92.join(logs, newest), stamp + " | " + line + "\r\n");
36829
+ fs71.appendFileSync(path91.join(logs, newest), stamp + " | " + line + "\r\n");
36588
36830
  } catch {
36589
36831
  }
36590
36832
  }
@@ -36701,8 +36943,8 @@ var IdleShutdown = class {
36701
36943
  var CLOSE_WAIT_MS = 8e3;
36702
36944
  var ROOTS_KEPT_MS = 10 * 60 * 1e3;
36703
36945
  function terminalTab(id, title, cwd) {
36704
- const view = [process.execPath, path93.join(path93.dirname(process.argv[1]), "view.js"), id];
36705
- const wt = path93.join(toolsDir, "terminal", "wt.exe");
36946
+ const view = [process.execPath, path92.join(path92.dirname(process.argv[1]), "view.js"), id];
36947
+ const wt = path92.join(toolsDir, "terminal", "wt.exe");
36706
36948
  if (exists(wt))
36707
36949
  spawn12(wt, ["-w", "0", "nt", "--title", title, "-d", cwd, ...view], { detached: true, stdio: "ignore" }).unref();
36708
36950
  else spawn12(SYSTEM.cmd(), ["/d", "/c", "start", title, ...view], { detached: true, stdio: "ignore", cwd }).unref();
@@ -36758,10 +37000,10 @@ var agentProgram = async (req, env, say) => {
36758
37000
  };
36759
37001
  function shellPaths() {
36760
37002
  const candidates = [
36761
- path93.join(pwshDir(), "pwsh.exe"),
36762
- path93.join(process.env.ProgramFiles ?? "C:\\Program Files", "PowerShell", "7", "pwsh.exe")
37003
+ path92.join(pwshDir(), "pwsh.exe"),
37004
+ path92.join(process.env.ProgramFiles ?? "C:\\Program Files", "PowerShell", "7", "pwsh.exe")
36763
37005
  ];
36764
- return { pwsh: candidates.find((f) => fs73.existsSync(f)) ?? null, powershell: SYSTEM.powershell(), cmd: SYSTEM.cmd() };
37006
+ return { pwsh: candidates.find((f) => fs72.existsSync(f)) ?? null, powershell: SYSTEM.powershell(), cmd: SYSTEM.cmd() };
36765
37007
  }
36766
37008
  var shellProgram = (shell) => {
36767
37009
  const line = commandLine(shell.file, shell.args);
@@ -36795,7 +37037,7 @@ var launchPtyHost = async (req, program, remote, env, sessions2, onSpawn) => {
36795
37037
  } catch (e) {
36796
37038
  const tail = ptyHostLogTail(req.id);
36797
37039
  throw new Error(
36798
- errMsg(e) + (tail ? ". From its log:\n" + tail : "") + "\nLog: " + path93.join(dataDir, "logs", "ptyhost-" + req.id + ".log")
37040
+ errMsg(e) + (tail ? ". From its log:\n" + tail : "") + "\nLog: " + path92.join(dataDir, "logs", "ptyhost-" + req.id + ".log")
36799
37041
  );
36800
37042
  }
36801
37043
  return { child, port, token };
@@ -36909,7 +37151,7 @@ var SessionManager = class {
36909
37151
  };
36910
37152
  this.starting++;
36911
37153
  if (req.id !== session.launchId && process.env.AGENT_NO_TABS !== "1")
36912
- safely("terminal tab", () => terminalTab(req.id, name + " " + path93.basename(req.cwd), req.cwd));
37154
+ safely("terminal tab", () => terminalTab(req.id, name + " " + path92.basename(req.cwd), req.cwd));
36913
37155
  try {
36914
37156
  if (problem) throw new Error(problem);
36915
37157
  const place = await placeFor(req, say);
@@ -37078,13 +37320,13 @@ var SessionManager = class {
37078
37320
  var sessions = new SessionManager();
37079
37321
 
37080
37322
  // src/guest/daemon/live.ts
37081
- import fs75 from "node:fs";
37082
- import path95 from "node:path";
37323
+ import fs74 from "node:fs";
37324
+ import path94 from "node:path";
37083
37325
  import { spawnSync as spawnSync7 } from "node:child_process";
37084
37326
 
37085
37327
  // src/guest/daemon/live-folders.ts
37086
- import fs74 from "node:fs";
37087
- import path94 from "node:path";
37328
+ import fs73 from "node:fs";
37329
+ import path93 from "node:path";
37088
37330
 
37089
37331
  // src/shared/channel/live.ts
37090
37332
  import crypto8 from "node:crypto";
@@ -37177,7 +37419,7 @@ var LiveFolderHandler = class {
37177
37419
  }
37178
37420
  read() {
37179
37421
  try {
37180
- const text = fs74.readFileSync(this.o.stateFile, "utf8");
37422
+ const text = fs73.readFileSync(this.o.stateFile, "utf8");
37181
37423
  const parsed = StateSchema.safeParse(JSON.parse(text));
37182
37424
  if (parsed.success && parsed.data.launchId === this.o.launchId) return parsed.data;
37183
37425
  } catch {
@@ -37185,7 +37427,7 @@ var LiveFolderHandler = class {
37185
37427
  return { key: null, launchId: this.o.launchId, seen: [], mappings: [] };
37186
37428
  }
37187
37429
  save(state) {
37188
- fs74.mkdirSync(path94.dirname(this.o.stateFile), { recursive: true });
37430
+ fs73.mkdirSync(path93.dirname(this.o.stateFile), { recursive: true });
37189
37431
  writeJsonAtomic(this.o.stateFile, state);
37190
37432
  }
37191
37433
  /** The key the boot handed over (from the one-shot secrets file). */
@@ -37196,30 +37438,30 @@ var LiveFolderHandler = class {
37196
37438
  /** C:\Workspace\<name> from a checked name only. */
37197
37439
  folderPath(name) {
37198
37440
  if (!LIVE_FOLDER_NAME.test(name)) throw new Error("not a plain folder name");
37199
- return path94.win32.join(this.o.workspaces ?? WORKSPACES_GUEST, name);
37441
+ return path93.win32.join(this.o.workspaces ?? WORKSPACES_GUEST, name);
37200
37442
  }
37201
37443
  /** One pass over run\live: every file is claimed (deleted) at once; valid ones are handled one after another. */
37202
37444
  tick() {
37203
37445
  const dir = this.o.run.liveDir;
37204
37446
  let names;
37205
37447
  try {
37206
- names = fs74.readdirSync(dir);
37448
+ names = fs73.readdirSync(dir);
37207
37449
  } catch {
37208
37450
  return;
37209
37451
  }
37210
37452
  for (const name of names.slice(0, 64)) {
37211
37453
  if (name.endsWith(".tmp")) continue;
37212
- const file3 = path94.join(dir, name);
37454
+ const file3 = path93.join(dir, name);
37213
37455
  let envelope = null;
37214
37456
  try {
37215
- const stat = fs74.lstatSync(file3);
37457
+ const stat = fs73.lstatSync(file3);
37216
37458
  if (stat.isFile() && stat.size <= MAX_REQUEST_BYTES && /^[A-Za-z0-9_-]{1,64}\.json$/.test(name))
37217
- envelope = JSON.parse(fs74.readFileSync(file3, "utf8"));
37459
+ envelope = JSON.parse(fs73.readFileSync(file3, "utf8"));
37218
37460
  } catch {
37219
37461
  envelope = null;
37220
37462
  } finally {
37221
37463
  try {
37222
- fs74.rmSync(file3, { recursive: true, force: true });
37464
+ fs73.rmSync(file3, { recursive: true, force: true });
37223
37465
  } catch {
37224
37466
  }
37225
37467
  }
@@ -37256,7 +37498,7 @@ var LiveFolderHandler = class {
37256
37498
  }
37257
37499
  reply(id, r) {
37258
37500
  try {
37259
- fs74.mkdirSync(this.o.run.liveRepliesDir, { recursive: true });
37501
+ fs73.mkdirSync(this.o.run.liveRepliesDir, { recursive: true });
37260
37502
  writeJsonAtomic(this.o.run.liveReplyFile(id), { id, ...r, finishedAt: new Date(this.now()).toISOString() });
37261
37503
  } catch (e) {
37262
37504
  this.log("live folder reply not written: " + errMsg(e));
@@ -37277,14 +37519,14 @@ var LiveFolderHandler = class {
37277
37519
  assertFree(folder) {
37278
37520
  let exists2 = true;
37279
37521
  try {
37280
- fs74.lstatSync(folder);
37522
+ fs73.lstatSync(folder);
37281
37523
  } catch {
37282
37524
  exists2 = false;
37283
37525
  }
37284
37526
  if (exists2) throw new Error(folder + " exists already");
37285
- const parent = path94.dirname(folder);
37286
- fs74.mkdirSync(parent, { recursive: true });
37287
- if (!fs74.lstatSync(parent).isDirectory()) throw new Error(parent + " is not a plain folder");
37527
+ const parent = path93.dirname(folder);
37528
+ fs73.mkdirSync(parent, { recursive: true });
37529
+ if (!fs73.lstatSync(parent).isDirectory()) throw new Error(parent + " is not a plain folder");
37288
37530
  }
37289
37531
  async act(p) {
37290
37532
  const folder = this.folderPath(p.folder);
@@ -37305,9 +37547,9 @@ var LiveFolderHandler = class {
37305
37547
  const code2 = await this.mapWithRetry(folder, share2, true);
37306
37548
  if (code2 !== EXIT_OK) return { ok: false, message: "the test share could not be shown (" + code2 + ")" };
37307
37549
  try {
37308
- const file3 = path94.join(folder, "token.txt");
37309
- const stat = fs74.statSync(file3);
37310
- const token = stat.size <= 64 ? fs74.readFileSync(file3, "utf8").trim() : "";
37550
+ const file3 = path93.join(folder, "token.txt");
37551
+ const stat = fs73.statSync(file3);
37552
+ const token = stat.size <= 64 ? fs73.readFileSync(file3, "utf8").trim() : "";
37311
37553
  return LIVE_TOKEN.test(token) ? { ok: true, message: "read the test share", token } : { ok: false, message: "the test share holds no token" };
37312
37554
  } finally {
37313
37555
  this.o.bind.unmap(folder);
@@ -37335,7 +37577,7 @@ var LiveFolderHandler = class {
37335
37577
  for (const m of this.read().mappings) {
37336
37578
  const folder = this.folderPath(m.folder);
37337
37579
  if (this.o.bind.mapped(folder) === EXIT_OK) continue;
37338
- fs74.mkdirSync(path94.dirname(folder), { recursive: true });
37580
+ fs73.mkdirSync(path93.dirname(folder), { recursive: true });
37339
37581
  if (this.o.bind.map(folder, m.share, m.readOnly) === EXIT_OK) done++;
37340
37582
  else this.log("live folder " + folder + " could not be shown again");
37341
37583
  }
@@ -37346,7 +37588,7 @@ var LiveFolderHandler = class {
37346
37588
  // src/guest/daemon/live.ts
37347
37589
  var BIND_TIMEOUT_MS = 3e4;
37348
37590
  var testing = Boolean(process.env.AGENT_DAEMON_STATE_DIR || process.env.AGENT_LOCAL_DIR);
37349
- var stateDir2 = process.env.AGENT_DAEMON_STATE_DIR ?? (process.env.AGENT_LOCAL_DIR ? path95.join(localDir, "daemon-state") : path95.join(process.env.ProgramData ?? "C:\\ProgramData", "AgentSandboxDaemon"));
37591
+ var stateDir2 = process.env.AGENT_DAEMON_STATE_DIR ?? (process.env.AGENT_LOCAL_DIR ? path94.join(localDir, "daemon-state") : path94.join(process.env.ProgramData ?? "C:\\ProgramData", "AgentSandboxDaemon"));
37350
37592
  function bindMount(args) {
37351
37593
  const r = spawnSync7(ensureCompiled("bindmount"), args, {
37352
37594
  windowsHide: true,
@@ -37361,7 +37603,7 @@ var realBind = {
37361
37603
  mapped: (folder) => bindMount(["mapped", folder])
37362
37604
  };
37363
37605
  function protectStateDir() {
37364
- fs75.mkdirSync(stateDir2, { recursive: true });
37606
+ fs74.mkdirSync(stateDir2, { recursive: true });
37365
37607
  if (!isWin || testMode || testing) return;
37366
37608
  spawnSync7(
37367
37609
  SYSTEM.icacls(),
@@ -37374,7 +37616,7 @@ function protectStateDir() {
37374
37616
  }
37375
37617
  var liveFolders = new LiveFolderHandler({
37376
37618
  run,
37377
- stateFile: path95.join(stateDir2, "live-folders.json"),
37619
+ stateFile: path94.join(stateDir2, "live-folders.json"),
37378
37620
  launchId: session.launchId,
37379
37621
  bind: realBind,
37380
37622
  log: warn
@@ -37404,9 +37646,9 @@ var Daemon = class {
37404
37646
  tick() {
37405
37647
  const { valid, invalid } = run.scanRequests();
37406
37648
  for (const file3 of invalid)
37407
- safely("removing an invalid request", () => fs76.rmSync(file3, { recursive: true, force: true }));
37649
+ safely("removing an invalid request", () => fs75.rmSync(file3, { recursive: true, force: true }));
37408
37650
  for (const req of valid) {
37409
- safely("claiming a request", () => fs76.rmSync(run.requestFile(req.id), { force: true }));
37651
+ safely("claiming a request", () => fs75.rmSync(run.requestFile(req.id), { force: true }));
37410
37652
  if (run.readSession(req.id)) continue;
37411
37653
  void Promise.resolve(this.handle(withRequestSecrets(req))).catch(
37412
37654
  (e) => respond(req.id, { ok: false, message: errMsg(e) })