windows-development-sandbox 1.9.0 → 1.10.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 (52) hide show
  1. package/config.example.json +2 -1
  2. package/dist/cli/commands/launch/launch.js +2 -0
  3. package/dist/cli/commands/vpn.js +1 -0
  4. package/dist/cli/commands/web.d.ts +5 -0
  5. package/dist/cli/commands/web.js +38 -0
  6. package/dist/core/config/defaults.js +1 -1
  7. package/dist/core/schema/config.d.ts +1 -0
  8. package/dist/core/schema/vpn.js +1 -1
  9. package/dist/core/schema/web.d.ts +1 -0
  10. package/dist/core/schema/web.js +4 -1
  11. package/dist/guest/boot/boot.js +3 -1
  12. package/dist/guest/governor/decide.d.ts +11 -1
  13. package/dist/guest/governor/decide.js +30 -1
  14. package/dist/guest/governor/governor.d.ts +3 -0
  15. package/dist/guest/governor/governor.js +18 -2
  16. package/dist/guest/network/firewall.d.ts +1 -0
  17. package/dist/guest/network/firewall.js +65 -23
  18. package/dist/guest/runtime/process.js +53 -5
  19. package/dist/guest/setup/claude-mem.js +12 -4
  20. package/dist/guest/toolchains/languages/node.js +29 -3
  21. package/dist/host/life/host-memory.d.ts +1 -0
  22. package/dist/host/life/host-memory.js +4 -1
  23. package/dist/host/life/watchdog.d.ts +2 -0
  24. package/dist/host/life/watchdog.js +19 -3
  25. package/dist/runtime/agent.js +14 -10
  26. package/dist/runtime/daemon.js +861 -711
  27. package/dist/runtime/db.js +14 -10
  28. package/dist/runtime/main.js +159 -41
  29. package/dist/runtime/netproxy.js +4 -3
  30. package/dist/runtime/view.js +4 -3
  31. package/dist/selftest/guest-boot.test.js +47 -1
  32. package/dist/selftest/heavy-load.test.js +27 -1
  33. package/dist/selftest/network.test.js +20 -1
  34. package/dist/selftest/support/fixtures.d.ts +1 -0
  35. package/dist/shared/io/copy-tree.d.ts +7 -0
  36. package/dist/shared/io/copy-tree.js +45 -0
  37. package/dist/shared/io/index.d.ts +2 -0
  38. package/dist/shared/io/index.js +2 -0
  39. package/dist/shared/io/robocopy-result.d.ts +6 -0
  40. package/dist/shared/io/robocopy-result.js +23 -0
  41. package/dist/shared/memory/policy.d.ts +5 -0
  42. package/dist/shared/memory/policy.js +8 -0
  43. package/dist/shared/network/firewall-rules.d.ts +8 -0
  44. package/dist/shared/network/firewall-rules.js +28 -0
  45. package/native/csharp/HcsHost/AssemblyInfo.cs +3 -3
  46. package/native/csharp/HostTools/AssemblyInfo.cs +3 -3
  47. package/native/csharp/HostTools/MemoryStatus.cs +128 -107
  48. package/native/scripts/memory-status.ps1 +10 -2
  49. package/package.json +1 -1
  50. package/sandbox/csharp/MemGov.cs +466 -398
  51. package/sandbox/scripts/new-shortcuts.ps1 +3 -1
  52. package/schemas/config.schema.json +6 -2
@@ -1363,11 +1363,11 @@ var require_lodash = __commonJS({
1363
1363
  return isFunction(object2[key2]);
1364
1364
  });
1365
1365
  }
1366
- function baseGet(object2, path69) {
1367
- path69 = castPath(path69, object2);
1368
- var index = 0, length = path69.length;
1366
+ function baseGet(object2, path70) {
1367
+ path70 = castPath(path70, object2);
1368
+ var index = 0, length = path70.length;
1369
1369
  while (object2 != null && index < length) {
1370
- object2 = object2[toKey(path69[index++])];
1370
+ object2 = object2[toKey(path70[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, path69, args) {
1435
- path69 = castPath(path69, object2);
1436
- object2 = parent(object2, path69);
1437
- var func = object2 == null ? object2 : object2[toKey(last(path69))];
1434
+ function baseInvoke(object2, path70, args) {
1435
+ path70 = castPath(path70, object2);
1436
+ object2 = parent(object2, path70);
1437
+ var func = object2 == null ? object2 : object2[toKey(last(path70))];
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(path69, srcValue) {
1594
- if (isKey(path69) && isStrictComparable(srcValue)) {
1595
- return matchesStrictComparable(toKey(path69), srcValue);
1593
+ function baseMatchesProperty(path70, srcValue) {
1594
+ if (isKey(path70) && isStrictComparable(srcValue)) {
1595
+ return matchesStrictComparable(toKey(path70), srcValue);
1596
1596
  }
1597
1597
  return function(object2) {
1598
- var objValue = get(object2, path69);
1599
- return objValue === undefined2 && objValue === srcValue ? hasIn(object2, path69) : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG);
1598
+ var objValue = get(object2, path70);
1599
+ return objValue === undefined2 && objValue === srcValue ? hasIn(object2, path70) : 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, path69) {
1697
- return hasIn(object2, path69);
1696
+ return basePickBy(object2, paths, function(value, path70) {
1697
+ return hasIn(object2, path70);
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 path69 = paths[index], value = baseGet(object2, path69);
1704
- if (predicate(value, path69)) {
1705
- baseSet(result2, castPath(path69, object2), value);
1703
+ var path70 = paths[index], value = baseGet(object2, path70);
1704
+ if (predicate(value, path70)) {
1705
+ baseSet(result2, castPath(path70, object2), value);
1706
1706
  }
1707
1707
  }
1708
1708
  return result2;
1709
1709
  }
1710
- function basePropertyDeep(path69) {
1710
+ function basePropertyDeep(path70) {
1711
1711
  return function(object2) {
1712
- return baseGet(object2, path69);
1712
+ return baseGet(object2, path70);
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, path69, value, customizer) {
1786
+ function baseSet(object2, path70, value, customizer) {
1787
1787
  if (!isObject2(object2)) {
1788
1788
  return object2;
1789
1789
  }
1790
- path69 = castPath(path69, object2);
1791
- var index = -1, length = path69.length, lastIndex = length - 1, nested = object2;
1790
+ path70 = castPath(path70, object2);
1791
+ var index = -1, length = path70.length, lastIndex = length - 1, nested = object2;
1792
1792
  while (nested != null && ++index < length) {
1793
- var key2 = toKey(path69[index]), newValue = value;
1793
+ var key2 = toKey(path70[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(path69[index + 1]) ? [] : {};
1801
+ newValue = isObject2(objValue) ? objValue : isIndex(path70[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, path69) {
1968
- path69 = castPath(path69, object2);
1969
- var index = -1, length = path69.length;
1967
+ function baseUnset(object2, path70) {
1968
+ path70 = castPath(path70, object2);
1969
+ var index = -1, length = path70.length;
1970
1970
  if (!length) {
1971
1971
  return true;
1972
1972
  }
1973
1973
  while (++index < length) {
1974
- var key2 = toKey(path69[index]);
1974
+ var key2 = toKey(path70[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, path69);
1983
- return obj == null || delete obj[toKey(last(path69))];
1982
+ var obj = parent(object2, path70);
1983
+ return obj == null || delete obj[toKey(last(path70))];
1984
1984
  }
1985
- function baseUpdate(object2, path69, updater, customizer) {
1986
- return baseSet(object2, path69, updater(baseGet(object2, path69)), customizer);
1985
+ function baseUpdate(object2, path70, updater, customizer) {
1986
+ return baseSet(object2, path70, updater(baseGet(object2, path70)), 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, path69, hasFunc) {
2870
- path69 = castPath(path69, object2);
2871
- var index = -1, length = path69.length, result2 = false;
2869
+ function hasPath(object2, path70, hasFunc) {
2870
+ path70 = castPath(path70, object2);
2871
+ var index = -1, length = path70.length, result2 = false;
2872
2872
  while (++index < length) {
2873
- var key2 = toKey(path69[index]);
2873
+ var key2 = toKey(path70[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, path69) {
3076
- return path69.length < 2 ? object2 : baseGet(object2, baseSlice(path69, 0, -1));
3075
+ function parent(object2, path70) {
3076
+ return path70.length < 2 ? object2 : baseGet(object2, baseSlice(path70, 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, path69, args) {
3712
- var index = -1, isFunc = typeof path69 == "function", result2 = isArrayLike(collection) ? Array2(collection.length) : [];
3711
+ var invokeMap = baseRest(function(collection, path70, args) {
3712
+ var index = -1, isFunc = typeof path70 == "function", result2 = isArrayLike(collection) ? Array2(collection.length) : [];
3713
3713
  baseEach(collection, function(value) {
3714
- result2[++index] = isFunc ? apply(path69, value, args) : baseInvoke(value, path69, args);
3714
+ result2[++index] = isFunc ? apply(path70, value, args) : baseInvoke(value, path70, 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, path69, defaultValue) {
4367
- var result2 = object2 == null ? undefined2 : baseGet(object2, path69);
4366
+ function get(object2, path70, defaultValue) {
4367
+ var result2 = object2 == null ? undefined2 : baseGet(object2, path70);
4368
4368
  return result2 === undefined2 ? defaultValue : result2;
4369
4369
  }
4370
- function has(object2, path69) {
4371
- return object2 != null && hasPath(object2, path69, baseHas);
4370
+ function has(object2, path70) {
4371
+ return object2 != null && hasPath(object2, path70, baseHas);
4372
4372
  }
4373
- function hasIn(object2, path69) {
4374
- return object2 != null && hasPath(object2, path69, baseHasIn);
4373
+ function hasIn(object2, path70) {
4374
+ return object2 != null && hasPath(object2, path70, 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(path69) {
4428
- path69 = castPath(path69, object2);
4429
- isDeep || (isDeep = path69.length > 1);
4430
- return path69;
4427
+ paths = arrayMap(paths, function(path70) {
4428
+ path70 = castPath(path70, object2);
4429
+ isDeep || (isDeep = path70.length > 1);
4430
+ return path70;
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, path69) {
4457
- return predicate(value, path69[0]);
4456
+ return basePickBy(object2, props, function(value, path70) {
4457
+ return predicate(value, path70[0]);
4458
4458
  });
4459
4459
  }
4460
- function result(object2, path69, defaultValue) {
4461
- path69 = castPath(path69, object2);
4462
- var index = -1, length = path69.length;
4460
+ function result(object2, path70, defaultValue) {
4461
+ path70 = castPath(path70, object2);
4462
+ var index = -1, length = path70.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(path69[index])];
4468
+ var value = object2 == null ? undefined2 : object2[toKey(path70[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, path69, value) {
4478
- return object2 == null ? object2 : baseSet(object2, path69, value);
4477
+ function set2(object2, path70, value) {
4478
+ return object2 == null ? object2 : baseSet(object2, path70, value);
4479
4479
  }
4480
- function setWith(object2, path69, value, customizer) {
4480
+ function setWith(object2, path70, value, customizer) {
4481
4481
  customizer = typeof customizer == "function" ? customizer : undefined2;
4482
- return object2 == null ? object2 : baseSet(object2, path69, value, customizer);
4482
+ return object2 == null ? object2 : baseSet(object2, path70, 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, path69) {
4505
- return object2 == null ? true : baseUnset(object2, path69);
4504
+ function unset(object2, path70) {
4505
+ return object2 == null ? true : baseUnset(object2, path70);
4506
4506
  }
4507
- function update(object2, path69, updater) {
4508
- return object2 == null ? object2 : baseUpdate(object2, path69, castFunction(updater));
4507
+ function update(object2, path70, updater) {
4508
+ return object2 == null ? object2 : baseUpdate(object2, path70, castFunction(updater));
4509
4509
  }
4510
- function updateWith(object2, path69, updater, customizer) {
4510
+ function updateWith(object2, path70, updater, customizer) {
4511
4511
  customizer = typeof customizer == "function" ? customizer : undefined2;
4512
- return object2 == null ? object2 : baseUpdate(object2, path69, castFunction(updater), customizer);
4512
+ return object2 == null ? object2 : baseUpdate(object2, path70, 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(path69, srcValue) {
4899
- return baseMatchesProperty(path69, baseClone(srcValue, CLONE_DEEP_FLAG));
4898
+ function matchesProperty(path70, srcValue) {
4899
+ return baseMatchesProperty(path70, baseClone(srcValue, CLONE_DEEP_FLAG));
4900
4900
  }
4901
- var method = baseRest(function(path69, args) {
4901
+ var method = baseRest(function(path70, args) {
4902
4902
  return function(object2) {
4903
- return baseInvoke(object2, path69, args);
4903
+ return baseInvoke(object2, path70, args);
4904
4904
  };
4905
4905
  });
4906
4906
  var methodOf = baseRest(function(object2, args) {
4907
- return function(path69) {
4908
- return baseInvoke(object2, path69, args);
4907
+ return function(path70) {
4908
+ return baseInvoke(object2, path70, 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(path69) {
4956
- return isKey(path69) ? baseProperty(toKey(path69)) : basePropertyDeep(path69);
4955
+ function property(path70) {
4956
+ return isKey(path70) ? baseProperty(toKey(path70)) : basePropertyDeep(path70);
4957
4957
  }
4958
4958
  function propertyOf(object2) {
4959
- return function(path69) {
4960
- return object2 == null ? undefined2 : baseGet(object2, path69);
4959
+ return function(path70) {
4960
+ return object2 == null ? undefined2 : baseGet(object2, path70);
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(path69, args) {
5414
- if (typeof path69 == "function") {
5413
+ LazyWrapper.prototype.invokeMap = baseRest(function(path70, args) {
5414
+ if (typeof path70 == "function") {
5415
5415
  return new LazyWrapper(this);
5416
5416
  }
5417
5417
  return this.map(function(value) {
5418
- return baseInvoke(value, path69, args);
5418
+ return baseInvoke(value, path70, args);
5419
5419
  });
5420
5420
  });
5421
5421
  LazyWrapper.prototype.reject = function(predicate) {
@@ -5540,15 +5540,15 @@ function relayPort(index) {
5540
5540
  }
5541
5541
 
5542
5542
  // src/guest/runtime/log.ts
5543
- import fs5 from "node:fs";
5544
- import path8 from "node:path";
5543
+ import fs6 from "node:fs";
5544
+ import path9 from "node:path";
5545
5545
 
5546
5546
  // src/guest/runtime/paths.ts
5547
- import path7 from "node:path";
5547
+ import path8 from "node:path";
5548
5548
 
5549
5549
  // src/shared/channel/run-dir.ts
5550
- import fs4 from "node:fs";
5551
- import path6 from "node:path";
5550
+ import fs5 from "node:fs";
5551
+ import path7 from "node:path";
5552
5552
 
5553
5553
  // node_modules/zod/v4/classic/external.js
5554
5554
  var external_exports = {};
@@ -6366,10 +6366,10 @@ function mergeDefs(...defs) {
6366
6366
  function cloneDef(schema) {
6367
6367
  return mergeDefs(schema._zod.def);
6368
6368
  }
6369
- function getElementAtPath(obj, path69) {
6370
- if (!path69)
6369
+ function getElementAtPath(obj, path70) {
6370
+ if (!path70)
6371
6371
  return obj;
6372
- return path69.reduce((acc, key2) => acc?.[key2], obj);
6372
+ return path70.reduce((acc, key2) => acc?.[key2], obj);
6373
6373
  }
6374
6374
  function promiseAllObject(promisesObj) {
6375
6375
  const keys = Object.keys(promisesObj);
@@ -6709,11 +6709,11 @@ function explicitlyAborted(x, startIndex = 0) {
6709
6709
  }
6710
6710
  return false;
6711
6711
  }
6712
- function prefixIssues(path69, issues) {
6712
+ function prefixIssues(path70, issues) {
6713
6713
  return issues.map((iss) => {
6714
6714
  var _a3;
6715
6715
  (_a3 = iss).path ?? (_a3.path = []);
6716
- iss.path.unshift(path69);
6716
+ iss.path.unshift(path70);
6717
6717
  return iss;
6718
6718
  });
6719
6719
  }
@@ -7163,16 +7163,16 @@ function flattenError(error62, mapper = (issue2) => issue2.message) {
7163
7163
  }
7164
7164
  function formatError(error62, mapper = (issue2) => issue2.message) {
7165
7165
  const fieldErrors = { _errors: [] };
7166
- const processError = (error63, path69 = []) => {
7166
+ const processError = (error63, path70 = []) => {
7167
7167
  for (const issue2 of error63.issues) {
7168
7168
  if (issue2.code === "invalid_union" && issue2.errors.length) {
7169
- issue2.errors.map((issues) => processError({ issues }, [...path69, ...issue2.path]));
7169
+ issue2.errors.map((issues) => processError({ issues }, [...path70, ...issue2.path]));
7170
7170
  } else if (issue2.code === "invalid_key") {
7171
- processError({ issues: issue2.issues }, [...path69, ...issue2.path]);
7171
+ processError({ issues: issue2.issues }, [...path70, ...issue2.path]);
7172
7172
  } else if (issue2.code === "invalid_element") {
7173
- processError({ issues: issue2.issues }, [...path69, ...issue2.path]);
7173
+ processError({ issues: issue2.issues }, [...path70, ...issue2.path]);
7174
7174
  } else {
7175
- const fullpath = [...path69, ...issue2.path];
7175
+ const fullpath = [...path70, ...issue2.path];
7176
7176
  if (fullpath.length === 0) {
7177
7177
  fieldErrors._errors.push(mapper(issue2));
7178
7178
  } else {
@@ -7211,17 +7211,17 @@ function formatError(error62, mapper = (issue2) => issue2.message) {
7211
7211
  }
7212
7212
  function treeifyError(error62, mapper = (issue2) => issue2.message) {
7213
7213
  const result = { errors: [] };
7214
- const processError = (error63, path69 = []) => {
7214
+ const processError = (error63, path70 = []) => {
7215
7215
  var _a3;
7216
7216
  for (const issue2 of error63.issues) {
7217
7217
  if (issue2.code === "invalid_union" && issue2.errors.length) {
7218
- issue2.errors.map((issues) => processError({ issues }, [...path69, ...issue2.path]));
7218
+ issue2.errors.map((issues) => processError({ issues }, [...path70, ...issue2.path]));
7219
7219
  } else if (issue2.code === "invalid_key") {
7220
- processError({ issues: issue2.issues }, [...path69, ...issue2.path]);
7220
+ processError({ issues: issue2.issues }, [...path70, ...issue2.path]);
7221
7221
  } else if (issue2.code === "invalid_element") {
7222
- processError({ issues: issue2.issues }, [...path69, ...issue2.path]);
7222
+ processError({ issues: issue2.issues }, [...path70, ...issue2.path]);
7223
7223
  } else {
7224
- const fullpath = [...path69, ...issue2.path];
7224
+ const fullpath = [...path70, ...issue2.path];
7225
7225
  if (fullpath.length === 0) {
7226
7226
  result.errors.push(mapper(issue2));
7227
7227
  continue;
@@ -7260,8 +7260,8 @@ function treeifyError(error62, mapper = (issue2) => issue2.message) {
7260
7260
  }
7261
7261
  function toDotPath(_path) {
7262
7262
  const segs = [];
7263
- const path69 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
7264
- for (const seg of path69) {
7263
+ const path70 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
7264
+ for (const seg of path70) {
7265
7265
  if (typeof seg === "number")
7266
7266
  segs.push(`[${seg}]`);
7267
7267
  else if (typeof seg === "symbol")
@@ -24363,13 +24363,13 @@ function resolveRef(ref, ctx) {
24363
24363
  if (!ref.startsWith("#")) {
24364
24364
  throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
24365
24365
  }
24366
- const path69 = ref.slice(1).split("/").filter(Boolean);
24367
- if (path69.length === 0) {
24366
+ const path70 = ref.slice(1).split("/").filter(Boolean);
24367
+ if (path70.length === 0) {
24368
24368
  return ctx.rootSchema;
24369
24369
  }
24370
24370
  const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
24371
- if (path69[0] === defsKey) {
24372
- const key2 = path69[1] === void 0 ? void 0 : decodeJSONPointerSegment(path69[1]);
24371
+ if (path70[0] === defsKey) {
24372
+ const key2 = path70[1] === void 0 ? void 0 : decodeJSONPointerSegment(path70[1]);
24373
24373
  if (!key2 || !ctx.defs[key2]) {
24374
24374
  throw new Error(`Reference not found: ${ref}`);
24375
24375
  }
@@ -26621,16 +26621,17 @@ var ResumeSchema = external_exports.strictObject({
26621
26621
  // src/core/schema/web.ts
26622
26622
  var WebSchema = external_exports.strictObject({
26623
26623
  enabled: external_exports.boolean().describe(
26624
- "(Beta) Allow the web UI: your sandbox sessions in a browser on this PC. Off by default, and nothing starts it by itself yet: sandbox web start works either way and runs it until sandbox web stop (or a restart of the PC)."
26624
+ "(Beta) The web UI: your sandbox sessions in a browser on this PC (http://127.0.0.1:<port>, this PC only). On: every sandbox start also starts it in the background (it keeps running until sandbox web stop or a restart of the PC). Off: only sandbox web start runs it. Open it signed in with sandbox web open."
26625
26625
  ),
26626
- port: external_exports.number().int().min(1024).max(65535).describe("Port of the web UI on 127.0.0.1 (this PC only). Pick another when it is taken.")
26626
+ port: external_exports.number().int().min(1024).max(65535).describe("Port of the web UI on 127.0.0.1 (this PC only). Pick another when it is taken."),
26627
+ openOnLaunch: external_exports.boolean().describe("(Beta) With the web UI on: open it in your browser, already signed in, every time a sandbox starts.")
26627
26628
  });
26628
26629
 
26629
26630
  // src/core/schema/vpn.ts
26630
26631
  var VPN_PROVIDERS = ["nordvpn", "openvpn-file", "wireguard-file"];
26631
26632
  var VpnSchema = external_exports.strictObject({
26632
26633
  enabled: external_exports.boolean().describe(
26633
- "Send the sandbox's traffic through a VPN. Only the sandbox: your PC's own connection is untouched. Needs a saved login first (sandbox vpn login). The agent in the sandbox can read that login and can turn the tunnel off (it is the administrator there)."
26634
+ "(Alpha: not yet tried on a real PC) Send the sandbox's traffic through a VPN. Only the sandbox: your PC's own connection is untouched. Needs a saved login first (sandbox vpn login). The agent in the sandbox can read that login and can turn the tunnel off (it is the administrator there)."
26634
26635
  ),
26635
26636
  provider: external_exports.enum(VPN_PROVIDERS).describe(
26636
26637
  "nordvpn: a recommended NordVPN server is picked at every launch. openvpn-file: your own .ovpn file (configFile). wireguard-file: your own WireGuard .conf (configFile), e.g. from your company."
@@ -27040,6 +27041,59 @@ function safeRemove(target, root) {
27040
27041
  fs3.rmSync(target, { recursive: true, force: true, maxRetries: 2 });
27041
27042
  }
27042
27043
 
27044
+ // src/shared/io/robocopy-result.ts
27045
+ function robocopyFailed(code) {
27046
+ return code === null || code >= 8;
27047
+ }
27048
+ function robocopyMeaning(code) {
27049
+ if (code === null) return "robocopy did not finish";
27050
+ if (code >= 16) return "robocopy stopped with a fatal error (bad path or no access)";
27051
+ if (code >= 8) return code & 1 ? "some files were copied and some could not be" : "files could not be copied";
27052
+ return code === 0 ? "nothing to copy" : "copied";
27053
+ }
27054
+ function robocopyErrors(output2, max = 3) {
27055
+ const lines = output2.split(/\r?\n/).map((l) => l.trim()).filter((l) => /\bERROR\b/.test(l) || /^The (process|system) cannot/i.test(l));
27056
+ return lines.slice(0, max).map((l) => l.length > 220 ? l.slice(0, 217) + "..." : l);
27057
+ }
27058
+
27059
+ // src/shared/io/copy-tree.ts
27060
+ import fs4 from "node:fs";
27061
+ import path6 from "node:path";
27062
+ var isGone = (e) => e?.code === "ENOENT";
27063
+ function copyTreeTolerant(from, to, skip = () => false) {
27064
+ let copied = 0;
27065
+ let vanished = 0;
27066
+ const walk = (src, dest) => {
27067
+ fs4.mkdirSync(dest, { recursive: true });
27068
+ let entries2;
27069
+ try {
27070
+ entries2 = fs4.readdirSync(src, { withFileTypes: true });
27071
+ } catch (e) {
27072
+ if (!isGone(e)) throw e;
27073
+ vanished++;
27074
+ return;
27075
+ }
27076
+ for (const entry of entries2) {
27077
+ if (skip(entry.name)) continue;
27078
+ const source = path6.join(src, entry.name);
27079
+ const target = path6.join(dest, entry.name);
27080
+ try {
27081
+ if (entry.isDirectory()) walk(source, target);
27082
+ else if (entry.isFile()) {
27083
+ fs4.copyFileSync(source, target);
27084
+ copied++;
27085
+ }
27086
+ } catch (e) {
27087
+ if (!isGone(e)) throw e;
27088
+ vanished++;
27089
+ fs4.rmSync(target, { force: true });
27090
+ }
27091
+ }
27092
+ };
27093
+ walk(from, to);
27094
+ return { copied, vanished };
27095
+ }
27096
+
27043
27097
  // src/shared/channel/run-dir.ts
27044
27098
  function safeId(id) {
27045
27099
  return IdSchema.parse(id);
@@ -27048,14 +27102,14 @@ function now() {
27048
27102
  return (/* @__PURE__ */ new Date()).toISOString();
27049
27103
  }
27050
27104
  var scan = (schema, dir) => {
27051
- if (!fs4.existsSync(dir)) return { valid: [], invalid: [] };
27105
+ if (!fs5.existsSync(dir)) return { valid: [], invalid: [] };
27052
27106
  const valid = [];
27053
27107
  const invalid = [];
27054
- for (const name of fs4.readdirSync(dir)) {
27108
+ for (const name of fs5.readdirSync(dir)) {
27055
27109
  if (name.endsWith(".tmp")) continue;
27056
- const message = /^[A-Za-z0-9_-]{1,64}\.json$/.test(name) ? readValid(schema, path6.join(dir, name)) : null;
27110
+ const message = /^[A-Za-z0-9_-]{1,64}\.json$/.test(name) ? readValid(schema, path7.join(dir, name)) : null;
27057
27111
  if (message) valid.push(message);
27058
- else invalid.push(path6.join(dir, name));
27112
+ else invalid.push(path7.join(dir, name));
27059
27113
  }
27060
27114
  return { valid, invalid };
27061
27115
  };
@@ -27074,31 +27128,31 @@ var RunDir = class {
27074
27128
  /** One-shot secrets the host hands over (see secrets.ts). Next to run, not in it: shared-use users can change run. */
27075
27129
  secretsDir;
27076
27130
  constructor(dataDir2) {
27077
- this.root = path6.join(dataDir2, "run");
27078
- this.sandboxFile = path6.join(this.root, "sandbox.json");
27079
- this.vpnFile = path6.join(this.root, "vpn.json");
27080
- this.pressureFile = path6.join(this.root, "pressure.json");
27081
- this.requestsDir = path6.join(this.root, "requests");
27082
- this.responsesDir = path6.join(this.root, "responses");
27083
- this.sessionsDir = path6.join(this.root, "sessions");
27084
- this.projectsDir = path6.join(this.root, "projects");
27085
- this.auditDir = path6.join(this.root, "audit");
27086
- this.secretsDir = path6.join(dataDir2, "secrets");
27131
+ this.root = path7.join(dataDir2, "run");
27132
+ this.sandboxFile = path7.join(this.root, "sandbox.json");
27133
+ this.vpnFile = path7.join(this.root, "vpn.json");
27134
+ this.pressureFile = path7.join(this.root, "pressure.json");
27135
+ this.requestsDir = path7.join(this.root, "requests");
27136
+ this.responsesDir = path7.join(this.root, "responses");
27137
+ this.sessionsDir = path7.join(this.root, "sessions");
27138
+ this.projectsDir = path7.join(this.root, "projects");
27139
+ this.auditDir = path7.join(this.root, "audit");
27140
+ this.secretsDir = path7.join(dataDir2, "secrets");
27087
27141
  }
27088
27142
  requestFile(id) {
27089
- return path6.join(this.requestsDir, safeId(id) + ".json");
27143
+ return path7.join(this.requestsDir, safeId(id) + ".json");
27090
27144
  }
27091
27145
  responseFile(id) {
27092
- return path6.join(this.responsesDir, safeId(id) + ".json");
27146
+ return path7.join(this.responsesDir, safeId(id) + ".json");
27093
27147
  }
27094
27148
  sessionFile(id) {
27095
- return path6.join(this.sessionsDir, safeId(id) + ".json");
27149
+ return path7.join(this.sessionsDir, safeId(id) + ".json");
27096
27150
  }
27097
27151
  projectFile(name) {
27098
- return path6.join(this.projectsDir, safeId(name) + ".json");
27152
+ return path7.join(this.projectsDir, safeId(name) + ".json");
27099
27153
  }
27100
27154
  secretFile(id) {
27101
- return path6.join(this.secretsDir, safeId(id) + ".json");
27155
+ return path7.join(this.secretsDir, safeId(id) + ".json");
27102
27156
  }
27103
27157
  readSandboxStatus() {
27104
27158
  return readValid(SandboxStatusSchema, this.sandboxFile);
@@ -27137,19 +27191,19 @@ var launchDir = process.env.AGENT_LAUNCH_DIR ?? "C:\\AgentLaunch";
27137
27191
  var dataDir = process.env.AGENT_DATA_DIR ?? "C:\\AgentData";
27138
27192
  var hostToolsDir = process.env.AGENT_HOST_TOOLS_DIR ?? "C:\\HostTools";
27139
27193
  var localDir = process.env.AGENT_LOCAL_DIR ?? "C:\\nvm";
27140
- var toolsDir = path7.join(dataDir, "tools");
27141
- var logsDir = path7.join(dataDir, "logs");
27194
+ var toolsDir = path8.join(dataDir, "tools");
27195
+ var logsDir = path8.join(dataDir, "logs");
27142
27196
  var run = new RunDir(dataDir);
27143
27197
 
27144
27198
  // src/guest/runtime/log.ts
27145
- fs5.mkdirSync(logsDir, { recursive: true });
27146
- var logFile = path8.join(
27199
+ fs6.mkdirSync(logsDir, { recursive: true });
27200
+ var logFile = path9.join(
27147
27201
  logsDir,
27148
27202
  (process.env.AGENT_LOG_PREFIX ?? "guest") + "-" + (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-") + ".log"
27149
27203
  );
27150
27204
  var append = (line) => {
27151
27205
  try {
27152
- fs5.appendFileSync(logFile, line + "\n");
27206
+ fs6.appendFileSync(logFile, line + "\n");
27153
27207
  } catch {
27154
27208
  }
27155
27209
  };
@@ -27163,8 +27217,8 @@ function warn(message) {
27163
27217
  }
27164
27218
 
27165
27219
  // src/guest/runtime/session.ts
27166
- import fs9 from "node:fs";
27167
- import path13 from "node:path";
27220
+ import fs10 from "node:fs";
27221
+ import path14 from "node:path";
27168
27222
 
27169
27223
  // src/shared/download/http.ts
27170
27224
  var USER_AGENT = "windows-development-sandbox";
@@ -27195,15 +27249,15 @@ async function fetchText(url2) {
27195
27249
  }
27196
27250
 
27197
27251
  // src/shared/download/archive.ts
27198
- import fs7 from "node:fs";
27199
- import path11 from "node:path";
27252
+ import fs8 from "node:fs";
27253
+ import path12 from "node:path";
27200
27254
  import crypto from "node:crypto";
27201
27255
 
27202
27256
  // src/shared/system.ts
27203
- import path9 from "node:path";
27257
+ import path10 from "node:path";
27204
27258
  var systemRoot = () => process.env.SystemRoot ?? process.env.WINDIR ?? "C:\\Windows";
27205
27259
  function system32(exe) {
27206
- return path9.join(systemRoot(), "System32", exe);
27260
+ return path10.join(systemRoot(), "System32", exe);
27207
27261
  }
27208
27262
  var SYSTEM = {
27209
27263
  cmd: () => system32("cmd.exe"),
@@ -27223,17 +27277,17 @@ var SYSTEM = {
27223
27277
  msiexec: () => system32("msiexec.exe"),
27224
27278
  sc: () => system32("sc.exe"),
27225
27279
  /** The .NET Framework C# compiler that ships with Windows (C# 5). */
27226
- csc: () => path9.join(systemRoot(), "Microsoft.NET", "Framework64", "v4.0.30319", "csc.exe")
27280
+ csc: () => path10.join(systemRoot(), "Microsoft.NET", "Framework64", "v4.0.30319", "csc.exe")
27227
27281
  };
27228
27282
 
27229
27283
  // src/shared/scripts.ts
27230
- import fs6 from "node:fs";
27231
- import path10 from "node:path";
27284
+ import fs7 from "node:fs";
27285
+ import path11 from "node:path";
27232
27286
  import { fileURLToPath } from "node:url";
27233
- var HERE = path10.dirname(fileURLToPath(import.meta.url));
27287
+ var HERE = path11.dirname(fileURLToPath(import.meta.url));
27234
27288
  function sandboxScriptsDir() {
27235
- const candidates = [path10.resolve(HERE, "..", "sandbox"), path10.resolve(HERE, "..", "..", "sandbox")];
27236
- return candidates.find((dir) => fs6.existsSync(path10.join(dir, "boot", "bootstrap.ps1"))) ?? candidates[candidates.length - 1];
27289
+ const candidates = [path11.resolve(HERE, "..", "sandbox"), path11.resolve(HERE, "..", "..", "sandbox")];
27290
+ return candidates.find((dir) => fs7.existsSync(path11.join(dir, "boot", "bootstrap.ps1"))) ?? candidates[candidates.length - 1];
27237
27291
  }
27238
27292
  function scriptArgs(name, args = []) {
27239
27293
  return [
@@ -27243,7 +27297,7 @@ function scriptArgs(name, args = []) {
27243
27297
  "-ExecutionPolicy",
27244
27298
  "Bypass",
27245
27299
  "-File",
27246
- path10.join(sandboxScriptsDir(), "scripts", name),
27300
+ path11.join(sandboxScriptsDir(), "scripts", name),
27247
27301
  ...args
27248
27302
  ];
27249
27303
  }
@@ -27263,16 +27317,16 @@ function stagingFolder(destination) {
27263
27317
  return destination + ".staging-" + crypto.randomBytes(3).toString("hex");
27264
27318
  }
27265
27319
  function moveIntoPlace(work, destination) {
27266
- safeRemove(destination, path11.dirname(destination));
27267
- fs7.mkdirSync(path11.dirname(destination), { recursive: true });
27268
- fs7.renameSync(work, destination);
27320
+ safeRemove(destination, path12.dirname(destination));
27321
+ fs8.mkdirSync(path12.dirname(destination), { recursive: true });
27322
+ fs8.renameSync(work, destination);
27269
27323
  }
27270
27324
  async function extractArchive(archive, destination, members2 = []) {
27271
- fs7.mkdirSync(destination, { recursive: true });
27325
+ fs8.mkdirSync(destination, { recursive: true });
27272
27326
  let status = await spawnAsync(SYSTEM.tar(), ["-xf", archive, "-C", destination, ...members2]);
27273
27327
  if (status !== 0 && /\.(zip|nupkg)$/i.test(archive)) {
27274
27328
  const zip = archive.endsWith(".zip") ? archive : archive + ".zip";
27275
- if (zip !== archive) fs7.copyFileSync(archive, zip);
27329
+ if (zip !== archive) fs8.copyFileSync(archive, zip);
27276
27330
  status = await spawnAsync(
27277
27331
  SYSTEM.powershell(),
27278
27332
  scriptArgs("expand-archive.ps1", ["-Archive", zip, "-Destination", destination])
@@ -27281,21 +27335,21 @@ async function extractArchive(archive, destination, members2 = []) {
27281
27335
  if (status !== 0) throw new Error("Could not extract " + archive);
27282
27336
  }
27283
27337
  function findFile(root, name, maxDepth = 4) {
27284
- if (maxDepth < 0 || !fs7.existsSync(root)) return null;
27285
- const entries2 = fs7.readdirSync(root, { withFileTypes: true });
27338
+ if (maxDepth < 0 || !fs8.existsSync(root)) return null;
27339
+ const entries2 = fs8.readdirSync(root, { withFileTypes: true });
27286
27340
  for (const entry of entries2)
27287
- if (entry.isFile() && entry.name.toLowerCase() === name.toLowerCase()) return path11.join(root, entry.name);
27341
+ if (entry.isFile() && entry.name.toLowerCase() === name.toLowerCase()) return path12.join(root, entry.name);
27288
27342
  for (const entry of entries2)
27289
27343
  if (entry.isDirectory()) {
27290
- const found = findFile(path11.join(root, entry.name), name, maxDepth - 1);
27344
+ const found = findFile(path12.join(root, entry.name), name, maxDepth - 1);
27291
27345
  if (found) return found;
27292
27346
  }
27293
27347
  return null;
27294
27348
  }
27295
27349
 
27296
27350
  // src/shared/download/downloader.ts
27297
- import fs8 from "node:fs";
27298
- import path12 from "node:path";
27351
+ import fs9 from "node:fs";
27352
+ import path13 from "node:path";
27299
27353
  import crypto2 from "node:crypto";
27300
27354
  import { Readable, Transform } from "node:stream";
27301
27355
  import { pipeline } from "node:stream/promises";
@@ -27316,12 +27370,12 @@ var Downloader = class {
27316
27370
  const sums = typeof expected === "string" || expected === null ? { sha256: expected } : expected;
27317
27371
  if (this.requireChecksum && !sums.sha256?.trim() && !sums.sha512?.trim()) {
27318
27372
  throw new Error(
27319
- "Refusing to download " + path12.basename(destination) + " (" + url2 + "): no checksum is published for it, and downloads.requireChecksum is on. Turn that setting off to allow downloads that cannot be verified."
27373
+ "Refusing to download " + path13.basename(destination) + " (" + url2 + "): no checksum is published for it, and downloads.requireChecksum is on. Turn that setting off to allow downloads that cannot be verified."
27320
27374
  );
27321
27375
  }
27322
27376
  const response = await fetchRetry(url2, {}, 3, 20 * 60 * 1e3);
27323
27377
  if (!response.body) throw new Error("Empty response for " + url2);
27324
- fs8.mkdirSync(path12.dirname(destination), { recursive: true });
27378
+ fs9.mkdirSync(path13.dirname(destination), { recursive: true });
27325
27379
  const checks = ["sha256", "sha512"].flatMap((kind) => {
27326
27380
  const want = sums[kind]?.trim().toLowerCase();
27327
27381
  return want ? [{ want, hash: crypto2.createHash(kind) }] : [];
@@ -27351,12 +27405,12 @@ var Downloader = class {
27351
27405
  });
27352
27406
  const partial2 = destination + ".part";
27353
27407
  try {
27354
- await pipeline(Readable.fromWeb(response.body), tap, fs8.createWriteStream(partial2));
27408
+ await pipeline(Readable.fromWeb(response.body), tap, fs9.createWriteStream(partial2));
27355
27409
  if (checks.some((c) => c.hash.digest("hex") !== c.want)) throw new Error("Checksum mismatch for " + url2);
27356
- fs8.rmSync(destination, { force: true });
27357
- fs8.renameSync(partial2, destination);
27410
+ fs9.rmSync(destination, { force: true });
27411
+ fs9.renameSync(partial2, destination);
27358
27412
  } finally {
27359
- fs8.rmSync(partial2, { force: true });
27413
+ fs9.rmSync(partial2, { force: true });
27360
27414
  }
27361
27415
  }
27362
27416
  /**
@@ -27366,21 +27420,21 @@ var Downloader = class {
27366
27420
  async archive(url2, destination, options = {}) {
27367
27421
  const work = stagingFolder(destination);
27368
27422
  try {
27369
- const archive = path12.join(work, options.fileName ?? path12.basename(new URL(url2).pathname));
27423
+ const archive = path13.join(work, options.fileName ?? path13.basename(new URL(url2).pathname));
27370
27424
  await this.file(url2, archive, { sha256: options.sha256, sha512: options.sha512 });
27371
- const extracted = path12.join(work, "x");
27425
+ const extracted = path13.join(work, "x");
27372
27426
  await extractArchive(archive, extracted, options.members);
27373
27427
  let root = extracted;
27374
27428
  if (options.locate) {
27375
27429
  const found = findFile(extracted, options.locate);
27376
27430
  if (!found) throw new Error(options.locate + " not found in " + url2);
27377
- root = path12.dirname(found);
27378
- for (let i = 0; i < (options.up ?? 0) && path12.dirname(root).startsWith(extracted); i++)
27379
- root = path12.dirname(root);
27431
+ root = path13.dirname(found);
27432
+ for (let i = 0; i < (options.up ?? 0) && path13.dirname(root).startsWith(extracted); i++)
27433
+ root = path13.dirname(root);
27380
27434
  }
27381
27435
  moveIntoPlace(root, destination);
27382
27436
  } finally {
27383
- safeRemove(work, path12.dirname(work));
27437
+ safeRemove(work, path13.dirname(work));
27384
27438
  }
27385
27439
  }
27386
27440
  };
@@ -27458,12 +27512,12 @@ var githubAssetFromPage = async (repo, pattern, searchOlder) => {
27458
27512
 
27459
27513
  // src/guest/runtime/session.ts
27460
27514
  var session = JSON.parse(
27461
- fs9.readFileSync(path13.join(launchDir, "session.json"), "utf8").replace(/^\uFEFF/, "")
27515
+ fs10.readFileSync(path14.join(launchDir, "session.json"), "utf8").replace(/^\uFEFF/, "")
27462
27516
  );
27463
27517
  downloader.requireChecksum = session.downloads?.requireChecksum === true;
27464
27518
  var workspace = process.env.AGENT_WORKSPACE ?? session.workspace;
27465
- var stateDir = path13.join(dataDir, session.persistAgentState ? "state" : "state-session");
27466
- var claudeDir = path13.join(stateDir, "claude");
27519
+ var stateDir = path14.join(dataDir, session.persistAgentState ? "state" : "state-session");
27520
+ var claudeDir = path14.join(stateDir, "claude");
27467
27521
 
27468
27522
  // src/core/util/errors.ts
27469
27523
  function errMsg(e) {
@@ -27489,12 +27543,12 @@ function startRelays() {
27489
27543
  }
27490
27544
 
27491
27545
  // src/guest/audit/process-audit.ts
27492
- import fs11 from "node:fs";
27493
- import path15 from "node:path";
27546
+ import fs12 from "node:fs";
27547
+ import path16 from "node:path";
27494
27548
  import { spawnSync } from "node:child_process";
27495
27549
 
27496
27550
  // src/guest/audit/parse.ts
27497
- import path14 from "node:path";
27551
+ import path15 from "node:path";
27498
27552
  var NOISE = /* @__PURE__ */ new Set([
27499
27553
  "conhost.exe",
27500
27554
  "svchost.exe",
@@ -27531,7 +27585,7 @@ function parseProcessEvents(xml) {
27531
27585
  if (!id) continue;
27532
27586
  last = Math.max(last, id);
27533
27587
  const program = field(event, "NewProcessName");
27534
- if (!program || NOISE.has(path14.win32.basename(program).toLowerCase())) continue;
27588
+ if (!program || NOISE.has(path15.win32.basename(program).toLowerCase())) continue;
27535
27589
  const t = /SystemTime='([^']+)'/.exec(event)?.[1] ?? (/* @__PURE__ */ new Date()).toISOString();
27536
27590
  lines.push(
27537
27591
  JSON.stringify({
@@ -27547,19 +27601,19 @@ function parseProcessEvents(xml) {
27547
27601
  }
27548
27602
 
27549
27603
  // src/guest/runtime/fs.ts
27550
- import fs10 from "node:fs";
27604
+ import fs11 from "node:fs";
27551
27605
  function exists(p) {
27552
- return fs10.existsSync(p);
27606
+ return fs11.existsSync(p);
27553
27607
  }
27554
27608
  function mkdirp(p) {
27555
- fs10.mkdirSync(p, { recursive: true });
27609
+ fs11.mkdirSync(p, { recursive: true });
27556
27610
  return p;
27557
27611
  }
27558
27612
 
27559
27613
  // src/guest/audit/process-audit.ts
27560
27614
  var MAX_PER_PASS = 2e3;
27561
27615
  var auditOn = () => Boolean(session.auditProcesses) && isWin && !dryRun;
27562
- var wevtutil = () => path15.join(process.env.WINDIR ?? "C:\\Windows", "System32", "wevtutil.exe");
27616
+ var wevtutil = () => path16.join(process.env.WINDIR ?? "C:\\Windows", "System32", "wevtutil.exe");
27563
27617
  var newestRecord = () => {
27564
27618
  const r = spawnSync(wevtutil(), ["qe", "Security", "/q:*[System[(EventID=4688)]]", "/f:xml", "/c:1", "/rd:true"], {
27565
27619
  encoding: "utf8",
@@ -27586,8 +27640,8 @@ function startProcessCollector() {
27586
27640
  const { lines, last: newest } = parseProcessEvents(r.stdout ?? "");
27587
27641
  if (newest) last = newest;
27588
27642
  if (lines.length)
27589
- fs11.writeFileSync(
27590
- path15.join(mkdirp(run.auditDir), Date.now() + "-" + process.pid + ".jsonl"),
27643
+ fs12.writeFileSync(
27644
+ path16.join(mkdirp(run.auditDir), Date.now() + "-" + process.pid + ".jsonl"),
27591
27645
  lines.join("\n") + "\n"
27592
27646
  );
27593
27647
  } catch (e) {
@@ -27598,14 +27652,14 @@ function startProcessCollector() {
27598
27652
  }
27599
27653
 
27600
27654
  // src/guest/daemon/state.ts
27601
- import path16 from "node:path";
27655
+ import path17 from "node:path";
27602
27656
  var MAX_MESSAGE = 3500;
27603
27657
  function insidePrimary(cwd) {
27604
- const rel = path16.relative(workspace.toLowerCase(), path16.resolve(cwd).toLowerCase());
27605
- return rel === "" || !rel.startsWith("..") && !path16.isAbsolute(rel);
27658
+ const rel = path17.relative(workspace.toLowerCase(), path17.resolve(cwd).toLowerCase());
27659
+ return rel === "" || !rel.startsWith("..") && !path17.isAbsolute(rel);
27606
27660
  }
27607
27661
  function insideWorkspace(cwd) {
27608
- return insidePrimary(cwd) || session.projectsDir !== void 0 && insideProjects(path16.resolve(cwd), session.roots ?? [], session.projectsDir);
27662
+ return insidePrimary(cwd) || session.projectsDir !== void 0 && insideProjects(path17.resolve(cwd), session.roots ?? [], session.projectsDir);
27609
27663
  }
27610
27664
  function tryWrite(file3, value) {
27611
27665
  try {
@@ -27629,7 +27683,7 @@ function safely(what, work) {
27629
27683
  }
27630
27684
 
27631
27685
  // src/guest/runtime/secrets.ts
27632
- import fs12 from "node:fs";
27686
+ import fs13 from "node:fs";
27633
27687
 
27634
27688
  // src/shared/channel/secrets.ts
27635
27689
  var Environment = external_exports.record(external_exports.string().max(256), external_exports.string().max(65536));
@@ -27674,12 +27728,12 @@ function takeSecrets(id) {
27674
27728
  const file3 = run.secretFile(id);
27675
27729
  let text;
27676
27730
  try {
27677
- if (fs12.statSync(file3).size > MAX_BYTES) throw new Error("too big");
27678
- text = fs12.readFileSync(file3, "utf8").replace(/^\uFEFF/, "");
27731
+ if (fs13.statSync(file3).size > MAX_BYTES) throw new Error("too big");
27732
+ text = fs13.readFileSync(file3, "utf8").replace(/^\uFEFF/, "");
27679
27733
  } catch {
27680
27734
  return {};
27681
27735
  } finally {
27682
- fs12.rmSync(file3, { force: true });
27736
+ fs13.rmSync(file3, { force: true });
27683
27737
  }
27684
27738
  try {
27685
27739
  const parsed = SecretsFileSchema.safeParse(JSON.parse(text));
@@ -27709,95 +27763,127 @@ function withRequestSecrets(req) {
27709
27763
  }
27710
27764
 
27711
27765
  // src/guest/daemon/daemon.ts
27712
- import fs53 from "node:fs";
27766
+ import fs54 from "node:fs";
27713
27767
 
27714
27768
  // src/guest/setup/claude-mem.ts
27715
- import fs14 from "node:fs";
27769
+ import fs15 from "node:fs";
27716
27770
  import os4 from "node:os";
27717
- import path18 from "node:path";
27771
+ import path19 from "node:path";
27718
27772
 
27719
27773
  // src/guest/runtime/process.ts
27720
- import fs13 from "node:fs";
27774
+ import fs14 from "node:fs";
27721
27775
  import os3 from "node:os";
27722
- import path17 from "node:path";
27776
+ import path18 from "node:path";
27723
27777
  import { spawnSync as spawnSync2 } from "node:child_process";
27724
- function exec(file3, args, options = {}) {
27725
- const result = spawnSync2(file3, args, { stdio: "inherit", windowsHide: true, ...options });
27726
- if (result.error) throw result.error;
27727
- if (result.status !== 0)
27728
- throw new Error(path17.basename(file3) + " " + args.slice(0, 3).join(" ") + " failed with exit code " + result.status);
27729
- }
27730
27778
  async function execAsync(file3, args, options = {}) {
27731
27779
  const code = await spawnAsync(file3, args, { stdio: "inherit", ...options });
27732
27780
  if (code !== 0)
27733
- throw new Error(path17.basename(file3) + " " + args.slice(0, 3).join(" ") + " failed with exit code " + code);
27781
+ throw new Error(path18.basename(file3) + " " + args.slice(0, 3).join(" ") + " failed with exit code " + code);
27734
27782
  }
27735
27783
  function execOutput(file3, args, options = {}) {
27736
27784
  const result = spawnSync2(file3, args, { encoding: "utf8", windowsHide: true, ...options });
27737
27785
  return result.status === 0 ? String(result.stdout ?? "").trim() : "";
27738
27786
  }
27739
27787
  function runScript(name, args = []) {
27740
- exec(SYSTEM.powershell(), scriptArgs(name, args));
27788
+ const result = spawnSync2(SYSTEM.powershell(), scriptArgs(name, args), {
27789
+ stdio: ["inherit", "inherit", "pipe"],
27790
+ encoding: "utf8",
27791
+ windowsHide: true
27792
+ });
27793
+ if (result.error) throw result.error;
27794
+ const errors = String(result.stderr ?? "").trim();
27795
+ if (errors) process.stderr.write(errors + "\n");
27796
+ if (result.status !== 0)
27797
+ throw new Error(name + " failed with exit code " + result.status + (errors ? ": " + errors.slice(0, 400) : ""));
27741
27798
  }
27742
27799
  function scriptOutput(name, args = [], options = {}) {
27743
27800
  return execOutput(SYSTEM.powershell(), scriptArgs(name, args), options);
27744
27801
  }
27745
27802
  function runScriptWithJson(name, param, data, args = []) {
27746
- const dir = fs13.mkdtempSync(path17.join(os3.tmpdir(), "sbx-"));
27747
- const file3 = path17.join(dir, "input.json");
27803
+ const dir = fs14.mkdtempSync(path18.join(os3.tmpdir(), "sbx-"));
27804
+ const file3 = path18.join(dir, "input.json");
27748
27805
  try {
27749
- fs13.writeFileSync(file3, JSON.stringify(data), "utf8");
27806
+ fs14.writeFileSync(file3, JSON.stringify(data), "utf8");
27750
27807
  runScript(name, ["-" + param, file3, ...args]);
27751
27808
  } finally {
27752
- fs13.rmSync(dir, { recursive: true, force: true });
27809
+ fs14.rmSync(dir, { recursive: true, force: true });
27753
27810
  }
27754
27811
  }
27755
27812
  function robocopy(from, to, files = []) {
27756
27813
  if (!isWin) {
27757
27814
  if (!files.length) {
27758
- fs13.cpSync(from, to, { recursive: true });
27815
+ fs14.cpSync(from, to, { recursive: true });
27759
27816
  return;
27760
27817
  }
27761
- fs13.mkdirSync(to, { recursive: true });
27762
- for (const f of files.filter((f2) => fs13.existsSync(path17.join(from, f2))))
27763
- fs13.copyFileSync(path17.join(from, f), path17.join(to, f));
27818
+ fs14.mkdirSync(to, { recursive: true });
27819
+ for (const f of files.filter((f2) => fs14.existsSync(path18.join(from, f2))))
27820
+ fs14.copyFileSync(path18.join(from, f), path18.join(to, f));
27764
27821
  return;
27765
27822
  }
27766
- const what = files.length ? files : ["/E", "/MT:16"];
27767
- const result = spawnSync2(
27768
- SYSTEM.robocopy(),
27769
- [from, to, ...what, "/NFL", "/NDL", "/NJH", "/NJS", "/NP", "/R:1", "/W:1", "/XJ"],
27770
- { stdio: "ignore", windowsHide: true }
27823
+ const what = files.length ? files : ["/E"];
27824
+ const passes = [
27825
+ ["/MT:16", "/R:1", "/W:1"],
27826
+ ["/MT:1", "/R:4", "/W:3"]
27827
+ ];
27828
+ let code = null;
27829
+ let output2 = "";
27830
+ for (const pass of passes) {
27831
+ const result = spawnSync2(
27832
+ SYSTEM.robocopy(),
27833
+ [
27834
+ from,
27835
+ to,
27836
+ ...what,
27837
+ ...files.length ? [] : [pass[0]],
27838
+ pass[1],
27839
+ pass[2],
27840
+ "/NFL",
27841
+ "/NDL",
27842
+ "/NJH",
27843
+ "/NJS",
27844
+ "/NP",
27845
+ "/XJ"
27846
+ ],
27847
+ { encoding: "utf8", windowsHide: true }
27848
+ );
27849
+ code = result.status;
27850
+ output2 = String(result.stdout ?? "") + String(result.stderr ?? "");
27851
+ if (!robocopyFailed(code)) return;
27852
+ }
27853
+ const why = robocopyErrors(output2);
27854
+ throw new Error(
27855
+ "robocopy " + from + " -> " + to + " failed (exit " + code + ": " + robocopyMeaning(code) + ")" + (why.length ? ": " + why.join(" | ") : "")
27771
27856
  );
27772
- if ((result.status ?? 16) >= 8)
27773
- throw new Error("robocopy " + from + " -> " + to + " failed (exit " + result.status + ")");
27774
27857
  }
27775
27858
  function copyNode(from, to) {
27776
27859
  const work = stagingFolder(to);
27777
27860
  try {
27778
27861
  robocopy(from, work, ["node.exe", "npm", "npm.cmd", "npx", "npx.cmd"]);
27779
- robocopy(path17.join(from, "node_modules", "npm"), path17.join(work, "node_modules", "npm"));
27862
+ robocopy(path18.join(from, "node_modules", "npm"), path18.join(work, "node_modules", "npm"));
27780
27863
  moveIntoPlace(work, to);
27781
27864
  } finally {
27782
- safeRemove(work, path17.dirname(work));
27865
+ safeRemove(work, path18.dirname(work));
27783
27866
  }
27784
27867
  }
27785
27868
 
27786
27869
  // src/guest/setup/claude-mem.ts
27787
27870
  var claudeMemPaths = {
27788
- store: path18.join(stateDir, "claude-mem"),
27789
- local: path18.join(os4.homedir(), ".claude-mem")
27871
+ store: path19.join(stateDir, "claude-mem"),
27872
+ local: path19.join(os4.homedir(), ".claude-mem")
27790
27873
  };
27791
27874
  var claudeMemEnabled = () => session.claudeProfile.syncClaudeMem && !dryRun;
27792
27875
  var databaseFingerprint = (dir) => {
27793
27876
  const parts2 = [];
27794
27877
  const walk = (folder) => {
27795
- for (const entry of fs14.readdirSync(folder, { withFileTypes: true })) {
27796
- const full = path18.join(folder, entry.name);
27878
+ for (const entry of fs15.readdirSync(folder, { withFileTypes: true })) {
27879
+ const full = path19.join(folder, entry.name);
27797
27880
  if (entry.isDirectory()) walk(full);
27798
27881
  else if (entry.isFile() && /\.(db|sqlite3?)(-wal)?$/i.test(entry.name)) {
27799
- const s = fs14.statSync(full);
27800
- parts2.push(full + ":" + s.size + ":" + s.mtimeMs);
27882
+ try {
27883
+ const s = fs15.statSync(full);
27884
+ parts2.push(full + ":" + s.size + ":" + s.mtimeMs);
27885
+ } catch {
27886
+ }
27801
27887
  }
27802
27888
  }
27803
27889
  };
@@ -27808,34 +27894,34 @@ var lastSaved = null;
27808
27894
  var SQLITE_HEADER = "SQLite format 3\0";
27809
27895
  var looksLikeSqlite = (file3) => {
27810
27896
  if (!exists(file3)) return true;
27811
- const fd = fs14.openSync(file3, "r");
27897
+ const fd = fs15.openSync(file3, "r");
27812
27898
  try {
27813
27899
  const head = Buffer.alloc(16);
27814
- return fs14.readSync(fd, head, 0, 16, 0) === 16 && head.toString("latin1") === SQLITE_HEADER;
27900
+ return fs15.readSync(fd, head, 0, 16, 0) === 16 && head.toString("latin1") === SQLITE_HEADER;
27815
27901
  } finally {
27816
- fs14.closeSync(fd);
27902
+ fs15.closeSync(fd);
27817
27903
  }
27818
27904
  };
27819
27905
  var MAX_BACKUPS = 3;
27820
27906
  var BACKUP_EVERY_MS = 6 * 3600 * 1e3;
27821
27907
  var keepBackup = (previous, dir) => {
27822
27908
  if (!exists(previous)) return;
27823
- const backups = exists(dir) ? fs14.readdirSync(dir).filter((n) => /^\d{13}$/.test(n)).sort() : [];
27909
+ const backups = exists(dir) ? fs15.readdirSync(dir).filter((n) => /^\d{13}$/.test(n)).sort() : [];
27824
27910
  const newest = Number(backups[backups.length - 1] ?? 0);
27825
27911
  if (Date.now() - newest < BACKUP_EVERY_MS) {
27826
- fs14.rmSync(previous, { recursive: true, force: true });
27912
+ fs15.rmSync(previous, { recursive: true, force: true });
27827
27913
  return;
27828
27914
  }
27829
- fs14.renameSync(previous, path18.join(mkdirp(dir), String(Date.now())));
27915
+ fs15.renameSync(previous, path19.join(mkdirp(dir), String(Date.now())));
27830
27916
  for (const old of [...backups, String(Date.now())].slice(0, -MAX_BACKUPS))
27831
- fs14.rmSync(path18.join(dir, old), { recursive: true, force: true });
27917
+ fs15.rmSync(path19.join(dir, old), { recursive: true, force: true });
27832
27918
  };
27833
27919
  function saveClaudeMem() {
27834
27920
  if (!claudeMemEnabled() || !exists(claudeMemPaths.local)) return;
27835
27921
  const { store: store2, local } = claudeMemPaths;
27836
27922
  const fingerprint2 = databaseFingerprint(local);
27837
27923
  if (fingerprint2 === lastSaved && exists(store2)) return;
27838
- if (!looksLikeSqlite(path18.join(local, "claude-mem.db"))) {
27924
+ if (!looksLikeSqlite(path19.join(local, "claude-mem.db"))) {
27839
27925
  warn(
27840
27926
  "claude-mem: the local database does not look valid, so it was not saved over the stored copy (" + local + ")."
27841
27927
  );
@@ -27843,14 +27929,14 @@ function saveClaudeMem() {
27843
27929
  }
27844
27930
  const incoming = store2 + ".incoming";
27845
27931
  const previous = store2 + ".previous";
27846
- fs14.rmSync(incoming, { recursive: true, force: true });
27847
- fs14.cpSync(local, incoming, { recursive: true, filter: (src) => !/\.(pid|lock)$/i.test(src) });
27848
- fs14.rmSync(previous, { recursive: true, force: true });
27849
- if (exists(store2)) fs14.renameSync(store2, previous);
27932
+ fs15.rmSync(incoming, { recursive: true, force: true });
27933
+ copyTreeTolerant(local, incoming, (name) => /\.(pid|lock)$|-journal$|-shm$/i.test(name));
27934
+ fs15.rmSync(previous, { recursive: true, force: true });
27935
+ if (exists(store2)) fs15.renameSync(store2, previous);
27850
27936
  try {
27851
- fs14.renameSync(incoming, store2);
27937
+ fs15.renameSync(incoming, store2);
27852
27938
  } catch (e) {
27853
- if (exists(previous)) fs14.renameSync(previous, store2);
27939
+ if (exists(previous)) fs15.renameSync(previous, store2);
27854
27940
  throw e;
27855
27941
  }
27856
27942
  keepBackup(previous, store2 + ".backups");
@@ -27858,18 +27944,18 @@ function saveClaudeMem() {
27858
27944
  }
27859
27945
 
27860
27946
  // src/guest/agents/local-state.ts
27861
- import fs15 from "node:fs";
27862
- import path20 from "node:path";
27947
+ import fs16 from "node:fs";
27948
+ import path21 from "node:path";
27863
27949
 
27864
27950
  // src/guest/agents/agent-files.ts
27865
- import path19 from "node:path";
27951
+ import path20 from "node:path";
27866
27952
  function agentPaths(toolsDir2, name, harness) {
27867
- const dir = path19.join(toolsDir2, "agents", name);
27953
+ const dir = path20.join(toolsDir2, "agents", name);
27868
27954
  const exe = harness.hostExecutable ?? (harness.uvBin ? harness.uvBin + ".exe" : null);
27869
27955
  return {
27870
27956
  dir,
27871
- exe: exe ? path19.join(dir, exe) : null,
27872
- cmd: harness.npmBin ? path19.join(dir, harness.npmBin + ".cmd") : null
27957
+ exe: exe ? path20.join(dir, exe) : null,
27958
+ cmd: harness.npmBin ? path20.join(dir, harness.npmBin + ".cmd") : null
27873
27959
  };
27874
27960
  }
27875
27961
  function agentCommand(name, harness) {
@@ -27880,10 +27966,10 @@ function localStateEntries(agents2, stateDir2, localRoot2) {
27880
27966
  ([agent, harness]) => Object.entries(harness.localState ?? {}).map(([env, folder]) => ({
27881
27967
  agent,
27882
27968
  env,
27883
- store: path19.join(stateDir2, agent, folder),
27884
- local: path19.join(localRoot2, agent, folder),
27969
+ store: path20.join(stateDir2, agent, folder),
27970
+ local: path20.join(localRoot2, agent, folder),
27885
27971
  processes: [agentCommand(agent, harness) + ".exe"],
27886
- legacy: path19.join(stateDir2, agent)
27972
+ legacy: path20.join(stateDir2, agent)
27887
27973
  }))
27888
27974
  );
27889
27975
  }
@@ -27892,39 +27978,39 @@ var isCopyableDatabaseFile = (name) => isDatabaseFile(name) && !/-shm$/i.test(na
27892
27978
 
27893
27979
  // src/guest/agents/local-state.ts
27894
27980
  var SQLITE_HEADER2 = "SQLite format 3\0";
27895
- var localRoot = () => path20.join(localDir, "agent-state");
27981
+ var localRoot = () => path21.join(localDir, "agent-state");
27896
27982
  function agentLocalStates() {
27897
27983
  return localStateEntries(session.agents ?? {}, stateDir, localRoot());
27898
27984
  }
27899
27985
  function localStateVars() {
27900
27986
  return Object.fromEntries(agentLocalStates().map((s) => [s.env, s.local]));
27901
27987
  }
27902
- var databaseFiles = (dir, keep) => exists(dir) ? fs15.readdirSync(dir, { withFileTypes: true }).flatMap((e) => e.isFile() && keep(e.name) ? [e.name] : []) : [];
27988
+ var databaseFiles = (dir, keep) => exists(dir) ? fs16.readdirSync(dir, { withFileTypes: true }).flatMap((e) => e.isFile() && keep(e.name) ? [e.name] : []) : [];
27903
27989
  var looksLikeSqlite2 = (file3) => {
27904
- const fd = fs15.openSync(file3, "r");
27990
+ const fd = fs16.openSync(file3, "r");
27905
27991
  try {
27906
27992
  const head = Buffer.alloc(16);
27907
- return fs15.readSync(fd, head, 0, 16, 0) === 16 && head.toString("latin1") === SQLITE_HEADER2;
27993
+ return fs16.readSync(fd, head, 0, 16, 0) === 16 && head.toString("latin1") === SQLITE_HEADER2;
27908
27994
  } finally {
27909
- fs15.closeSync(fd);
27995
+ fs16.closeSync(fd);
27910
27996
  }
27911
27997
  };
27912
27998
  var copyFiles = (from, to, names) => {
27913
- fs15.rmSync(to, { recursive: true, force: true });
27999
+ fs16.rmSync(to, { recursive: true, force: true });
27914
28000
  mkdirp(to);
27915
- for (const name of names) fs15.copyFileSync(path20.join(from, name), path20.join(to, name));
28001
+ for (const name of names) fs16.copyFileSync(path21.join(from, name), path21.join(to, name));
27916
28002
  };
27917
28003
  var swapIn = (incoming, store2) => {
27918
28004
  const previous = store2 + ".previous";
27919
- fs15.rmSync(previous, { recursive: true, force: true });
27920
- if (exists(store2)) fs15.renameSync(store2, previous);
28005
+ fs16.rmSync(previous, { recursive: true, force: true });
28006
+ if (exists(store2)) fs16.renameSync(store2, previous);
27921
28007
  try {
27922
- fs15.renameSync(incoming, store2);
28008
+ fs16.renameSync(incoming, store2);
27923
28009
  } catch (e) {
27924
- if (exists(previous)) fs15.renameSync(previous, store2);
28010
+ if (exists(previous)) fs16.renameSync(previous, store2);
27925
28011
  throw e;
27926
28012
  }
27927
- fs15.rmSync(previous, { recursive: true, force: true });
28013
+ fs16.rmSync(previous, { recursive: true, force: true });
27928
28014
  };
27929
28015
  function held(s) {
27930
28016
  if (!isWin) return false;
@@ -27933,7 +28019,7 @@ function held(s) {
27933
28019
  );
27934
28020
  }
27935
28021
  var fingerprint = (dir) => databaseFiles(dir, isCopyableDatabaseFile).sort().map((n) => {
27936
- const st = fs15.statSync(path20.join(dir, n));
28022
+ const st = fs16.statSync(path21.join(dir, n));
27937
28023
  return n + ":" + st.size + ":" + st.mtimeMs;
27938
28024
  }).join("|");
27939
28025
  var saved = /* @__PURE__ */ new Map();
@@ -27952,12 +28038,12 @@ function snapshotWhileRunning(s, print) {
27952
28038
  return;
27953
28039
  }
27954
28040
  const incoming = s.store + ".incoming";
27955
- fs15.rmSync(incoming, { recursive: true, force: true });
28041
+ fs16.rmSync(incoming, { recursive: true, force: true });
27956
28042
  mkdirp(incoming);
27957
28043
  for (const name of databaseFiles(s.local, (n) => isCopyableDatabaseFile(n) && !/-wal$/i.test(n))) {
27958
- const db = new sqlite.DatabaseSync(path20.join(s.local, name), { readOnly: true });
28044
+ const db = new sqlite.DatabaseSync(path21.join(s.local, name), { readOnly: true });
27959
28045
  try {
27960
- await sqlite.backup(db, path20.join(incoming, name));
28046
+ await sqlite.backup(db, path21.join(incoming, name));
27961
28047
  } finally {
27962
28048
  db.close();
27963
28049
  }
@@ -27983,7 +28069,7 @@ function saveLocalState() {
27983
28069
  continue;
27984
28070
  }
27985
28071
  const names = databaseFiles(s.local, isCopyableDatabaseFile);
27986
- const bad = names.filter((n) => !/-wal$/i.test(n) && !looksLikeSqlite2(path20.join(s.local, n)));
28072
+ const bad = names.filter((n) => !/-wal$/i.test(n) && !looksLikeSqlite2(path21.join(s.local, n)));
27987
28073
  if (bad.length) {
27988
28074
  warn(s.agent + ": " + bad.join(", ") + " do not look like SQLite databases, so they were not saved.");
27989
28075
  continue;
@@ -28002,10 +28088,10 @@ function saveLocalState() {
28002
28088
  import { spawn as spawn5 } from "node:child_process";
28003
28089
 
28004
28090
  // src/guest/setup/environment.ts
28005
- import path22 from "node:path";
28091
+ import path23 from "node:path";
28006
28092
 
28007
28093
  // src/guest/setup/path-plan.ts
28008
- import path21 from "node:path";
28094
+ import path22 from "node:path";
28009
28095
  function pathKey(folder) {
28010
28096
  const slashes = folder.trim().replace(/^"|"$/g, "").replace(/\//g, "\\");
28011
28097
  return (slashes.length > 3 ? slashes.replace(/\\+$/, "") : slashes).toLowerCase();
@@ -28045,13 +28131,13 @@ function parseRegPath(output2) {
28045
28131
  function isPinnedNodeDir(folder, nvmHome2) {
28046
28132
  const key2 = pathKey(folder);
28047
28133
  const home = pathKey(nvmHome2);
28048
- return key2.startsWith(home + "\\") && /^v\d/.test(path21.win32.basename(key2));
28134
+ return key2.startsWith(home + "\\") && /^v\d/.test(path22.win32.basename(key2));
28049
28135
  }
28050
28136
 
28051
28137
  // src/guest/setup/environment.ts
28052
28138
  var LEGACY_HOMES = { CODEX_HOME: "codex", GEMINI_CLI_HOME: "gemini" };
28053
28139
  var agentHomes = () => Object.fromEntries(
28054
- Object.entries(session.agentHomes ?? LEGACY_HOMES).filter(([name]) => name !== "CLAUDE_CONFIG_DIR").map(([name, sub]) => [name, path22.join(stateDir, sub)])
28140
+ Object.entries(session.agentHomes ?? LEGACY_HOMES).filter(([name]) => name !== "CLAUDE_CONFIG_DIR").map(([name, sub]) => [name, path23.join(stateDir, sub)])
28055
28141
  );
28056
28142
  function agentEnv(tools, target = { workspace, project: session.project, base: process.env }) {
28057
28143
  const homes = agentHomes();
@@ -28061,7 +28147,7 @@ function agentEnv(tools, target = { workspace, project: session.project, base: p
28061
28147
  CLAUDE_CONFIG_DIR: claudeDir,
28062
28148
  ...homes,
28063
28149
  ...localStateVars(),
28064
- npm_config_cache: path22.join(toolsDir, "npm-cache"),
28150
+ npm_config_cache: path23.join(toolsDir, "npm-cache"),
28065
28151
  npm_config_update_notifier: "false",
28066
28152
  AGENT_WORKSPACE: target.workspace,
28067
28153
  AGENT_DATA: dataDir,
@@ -28079,9 +28165,9 @@ function agentEnv(tools, target = { workspace, project: session.project, base: p
28079
28165
  ...local.map((n) => env[n])
28080
28166
  ])
28081
28167
  mkdirp(dir);
28082
- const runners = [path22.join(toolsDir, "node"), path22.dirname(process.execPath)].map((d) => d.toLowerCase());
28083
- const base = (target.base.PATH ?? "").split(path22.delimiter).filter((d) => d && !runners.includes(d.toLowerCase()));
28084
- env.PATH = [.../* @__PURE__ */ new Set([...tools.prepend, ...base, ...tools.append])].join(path22.delimiter);
28168
+ const runners = [path23.join(toolsDir, "node"), path23.dirname(process.execPath)].map((d) => d.toLowerCase());
28169
+ const base = (target.base.PATH ?? "").split(path23.delimiter).filter((d) => d && !runners.includes(d.toLowerCase()));
28170
+ env.PATH = [.../* @__PURE__ */ new Set([...tools.prepend, ...base, ...tools.append])].join(path23.delimiter);
28085
28171
  return env;
28086
28172
  }
28087
28173
  function addMachineEnvironment(vars, dirs, additive = false) {
@@ -28093,7 +28179,7 @@ function addMachineEnvironment(vars, dirs, additive = false) {
28093
28179
  warn("Could not add to the environment: " + errMsg(e));
28094
28180
  }
28095
28181
  }
28096
- var nvmHome = () => path22.join(toolsDir, "nvm");
28182
+ var nvmHome = () => path23.join(toolsDir, "nvm");
28097
28183
  var MACHINE_ENVIRONMENT_KEY = "HKLM\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment";
28098
28184
  var USER_ENVIRONMENT_KEY = "HKCU\\Environment";
28099
28185
  var registryPath = (key2) => parseRegPath(execOutput(SYSTEM.reg(), ["query", key2, "/v", "Path"]));
@@ -28101,7 +28187,7 @@ function withRegistryPath(env) {
28101
28187
  if (!isWin || dryRun || testMode) return env;
28102
28188
  try {
28103
28189
  const registry2 = expandVars(registryPath(MACHINE_ENVIRONMENT_KEY) + ";" + registryPath(USER_ENVIRONMENT_KEY), env);
28104
- const runner = pathKey(path22.join(toolsDir, "node"));
28190
+ const runner = pathKey(path23.join(toolsDir, "node"));
28105
28191
  const pathName = Object.keys(env).find((k) => k.toLowerCase() === "path") ?? "PATH";
28106
28192
  return {
28107
28193
  ...env,
@@ -28118,12 +28204,12 @@ function withRegistryPath(env) {
28118
28204
  }
28119
28205
 
28120
28206
  // src/guest/daemon/project-provisioner.ts
28121
- import fs48 from "node:fs";
28122
- import path62 from "node:path";
28207
+ import fs49 from "node:fs";
28208
+ import path63 from "node:path";
28123
28209
 
28124
28210
  // src/guest/boot/boot-env.ts
28125
- import fs16 from "node:fs";
28126
- import path23 from "node:path";
28211
+ import fs17 from "node:fs";
28212
+ import path24 from "node:path";
28127
28213
 
28128
28214
  // src/guest/boot/project-env.ts
28129
28215
  var EnvSchema = external_exports.object({
@@ -28153,22 +28239,22 @@ function baseEnvFor(boot, current = process.env) {
28153
28239
  }
28154
28240
 
28155
28241
  // src/guest/boot/boot-env.ts
28156
- var file2 = () => path23.join(localDir, "boot-env.json");
28242
+ var file2 = () => path24.join(localDir, "boot-env.json");
28157
28243
  function readBootEnv() {
28158
28244
  try {
28159
- return BootEnvSchema.safeParse(JSON.parse(fs16.readFileSync(file2(), "utf8"))).data ?? null;
28245
+ return BootEnvSchema.safeParse(JSON.parse(fs17.readFileSync(file2(), "utf8"))).data ?? null;
28160
28246
  } catch {
28161
28247
  return null;
28162
28248
  }
28163
28249
  }
28164
28250
 
28165
28251
  // src/guest/boot/guide.ts
28166
- import fs17 from "node:fs";
28167
- import path24 from "node:path";
28252
+ import fs18 from "node:fs";
28253
+ import path25 from "node:path";
28168
28254
  var BEGIN = "<!-- agent-sandbox:begin (generated every boot, do not edit) -->";
28169
28255
  var END = "<!-- agent-sandbox:end -->";
28170
28256
  var mirrorLine = () => {
28171
- const drives = (session.substDrives ?? []).filter((d) => fs17.existsSync(d.letter + ":\\"));
28257
+ const drives = (session.substDrives ?? []).filter((d) => fs18.existsSync(d.letter + ":\\"));
28172
28258
  if (!drives.length) return [];
28173
28259
  return [
28174
28260
  "- " + drives.map((d) => d.letter + ":").join(", ") + " = mapped folders at their PC paths (subst onto `" + drives.map((d) => d.target).join("`, `") + "`; real-path tools may print that form)."
@@ -28184,8 +28270,8 @@ function sandboxGuide(toolSummary, lan = "blocked", projects = []) {
28184
28270
  ...projects.map(
28185
28271
  (p) => "- RW, persists: `" + p.guest + "` = host folder " + p.host + " (another project in this sandbox; your own is `%AGENT_WORKSPACE%`)"
28186
28272
  ),
28187
- "- RW, persists: `" + toolsDir + "` (toolchains) \u2014 put portable exes in `" + path24.join(toolsDir, "bin") + "` (on PATH)",
28188
- "- RW, persists: `" + stateDir + "` (agent config/history; do not edit logins) \xB7 logs: `" + path24.join(dataDir, "logs") + "`",
28273
+ "- RW, persists: `" + toolsDir + "` (toolchains) \u2014 put portable exes in `" + path25.join(toolsDir, "bin") + "` (on PATH)",
28274
+ "- RW, persists: `" + stateDir + "` (agent config/history; do not edit logins) \xB7 logs: `" + path25.join(dataDir, "logs") + "`",
28189
28275
  "- RO: `" + launchDir + "` (this boot's scripts) \xB7 lost on close: everything else, incl. `C:\\nvm` (Node symlink)",
28190
28276
  ...mirrorLine(),
28191
28277
  "- Tools: " + toolSummary.join(" \xB7 "),
@@ -28196,37 +28282,37 @@ function sandboxGuide(toolSummary, lan = "blocked", projects = []) {
28196
28282
  ].join("\n");
28197
28283
  }
28198
28284
  function upsertGuide(file3, guide) {
28199
- fs17.mkdirSync(path24.dirname(file3), { recursive: true });
28200
- const current = fs17.existsSync(file3) ? fs17.readFileSync(file3, "utf8") : "";
28285
+ fs18.mkdirSync(path25.dirname(file3), { recursive: true });
28286
+ const current = fs18.existsSync(file3) ? fs18.readFileSync(file3, "utf8") : "";
28201
28287
  const start = current.indexOf(BEGIN);
28202
28288
  const end = current.indexOf(END);
28203
28289
  const without = start >= 0 && end > start ? current.slice(0, start) + current.slice(end + END.length) : current;
28204
- fs17.writeFileSync(file3, without.trimEnd() + (without.trim() ? "\n\n" : "") + guide + "\n", "utf8");
28290
+ fs18.writeFileSync(file3, without.trimEnd() + (without.trim() ? "\n\n" : "") + guide + "\n", "utf8");
28205
28291
  }
28206
28292
  function managedClaudeMd() {
28207
- return path24.join(
28208
- process.env.AGENT_MANAGED_DIR ?? path24.join(process.env.ProgramFiles ?? "C:\\Program Files", "ClaudeCode"),
28293
+ return path25.join(
28294
+ process.env.AGENT_MANAGED_DIR ?? path25.join(process.env.ProgramFiles ?? "C:\\Program Files", "ClaudeCode"),
28209
28295
  "CLAUDE.md"
28210
28296
  );
28211
28297
  }
28212
28298
  function writeGuides(toolSummary, lan, projects = []) {
28213
28299
  const guide = sandboxGuide(toolSummary, lan, projects);
28214
28300
  const managed = managedClaudeMd();
28215
- fs17.mkdirSync(path24.dirname(managed), { recursive: true });
28216
- fs17.writeFileSync(managed, guide + "\n", "utf8");
28217
- fs17.writeFileSync(path24.join(dataDir, "SANDBOX.md"), guide + "\n", "utf8");
28218
- upsertGuide(path24.join(stateDir, "codex", "AGENTS.md"), guide);
28219
- upsertGuide(path24.join(stateDir, "gemini", ".gemini", "GEMINI.md"), guide);
28220
- removeGuide(path24.join(claudeDir, "CLAUDE.md"));
28301
+ fs18.mkdirSync(path25.dirname(managed), { recursive: true });
28302
+ fs18.writeFileSync(managed, guide + "\n", "utf8");
28303
+ fs18.writeFileSync(path25.join(dataDir, "SANDBOX.md"), guide + "\n", "utf8");
28304
+ upsertGuide(path25.join(stateDir, "codex", "AGENTS.md"), guide);
28305
+ upsertGuide(path25.join(stateDir, "gemini", ".gemini", "GEMINI.md"), guide);
28306
+ removeGuide(path25.join(claudeDir, "CLAUDE.md"));
28221
28307
  return managed;
28222
28308
  }
28223
28309
  var removeGuide = (file3) => {
28224
- if (!fs17.existsSync(file3)) return;
28225
- const current = fs17.readFileSync(file3, "utf8");
28310
+ if (!fs18.existsSync(file3)) return;
28311
+ const current = fs18.readFileSync(file3, "utf8");
28226
28312
  const start = current.indexOf(BEGIN);
28227
28313
  const end = current.indexOf(END);
28228
28314
  if (start >= 0 && end > start)
28229
- fs17.writeFileSync(file3, (current.slice(0, start) + current.slice(end + END.length)).trim() + "\n", "utf8");
28315
+ fs18.writeFileSync(file3, (current.slice(0, start) + current.slice(end + END.length)).trim() + "\n", "utf8");
28230
28316
  };
28231
28317
 
28232
28318
  // src/guest/runtime/project-context.ts
@@ -28263,11 +28349,11 @@ function saveProjectStatus(name, workspace2, phase, message, databases, summary)
28263
28349
  }
28264
28350
 
28265
28351
  // src/guest/setup/hooks.ts
28266
- import fs18 from "node:fs";
28267
- import path25 from "node:path";
28352
+ import fs19 from "node:fs";
28353
+ import path26 from "node:path";
28268
28354
  import { spawnSync as spawnSync3 } from "node:child_process";
28269
28355
  var commandFor = (file3) => {
28270
- const ext = path25.extname(file3).toLowerCase();
28356
+ const ext = path26.extname(file3).toLowerCase();
28271
28357
  if (ext === ".mjs" || ext === ".js") return [process.execPath, [file3]];
28272
28358
  if (!isWin) return null;
28273
28359
  if (ext === ".ps1")
@@ -28275,18 +28361,18 @@ var commandFor = (file3) => {
28275
28361
  if (ext === ".cmd" || ext === ".bat") return [SYSTEM.cmd(), ["/d", "/c", file3]];
28276
28362
  return null;
28277
28363
  };
28278
- var BOOT = { root: path25.join(launchDir, "hooks"), cwd: workspace };
28364
+ var BOOT = { root: path26.join(launchDir, "hooks"), cwd: workspace };
28279
28365
  function projectHooks(name, cwd) {
28280
28366
  return {
28281
- root: path25.join(launchDir, "projects", name, "hooks"),
28367
+ root: path26.join(launchDir, "projects", name, "hooks"),
28282
28368
  cwd
28283
28369
  };
28284
28370
  }
28285
28371
  var hooksOf = (stage, target) => {
28286
- const dir = path25.join(target.root, stage);
28372
+ const dir = path26.join(target.root, stage);
28287
28373
  if (!exists(dir)) return [];
28288
- return fs18.readdirSync(dir).sort().flatMap((name) => {
28289
- const command = commandFor(path25.join(dir, name));
28374
+ return fs19.readdirSync(dir).sort().flatMap((name) => {
28375
+ const command = commandFor(path26.join(dir, name));
28290
28376
  return command ? [{ name, command }] : [];
28291
28377
  });
28292
28378
  };
@@ -28316,25 +28402,25 @@ async function runHooksAsync(stage, env, target) {
28316
28402
  }
28317
28403
 
28318
28404
  // src/guest/toolchains/tool-env.ts
28319
- import path26 from "node:path";
28405
+ import path27 from "node:path";
28320
28406
  function emptyEnv() {
28321
28407
  return { vars: {}, prepend: [], append: [], summary: [] };
28322
28408
  }
28323
28409
  var arch = process.arch === "arm64" ? "arm64" : "x64";
28324
28410
  function tool(...parts2) {
28325
- return path26.join(toolsDir, ...parts2);
28411
+ return path27.join(toolsDir, ...parts2);
28326
28412
  }
28327
28413
  function versionOf(exe, args = ["--version"], options = {}) {
28328
28414
  return /\d+\.\d+\.\d+\S*/.exec(execOutput(exe, args, options))?.[0] ?? "installed";
28329
28415
  }
28330
28416
 
28331
28417
  // src/guest/apps/app-installer.ts
28332
- import fs22 from "node:fs";
28333
- import path31 from "node:path";
28418
+ import fs23 from "node:fs";
28419
+ import path32 from "node:path";
28334
28420
 
28335
28421
  // src/guest/apps/after-install.ts
28336
- import fs19 from "node:fs";
28337
- import path27 from "node:path";
28422
+ import fs20 from "node:fs";
28423
+ import path28 from "node:path";
28338
28424
  var SYSINTERNALS_TOOLS = [
28339
28425
  "Process Explorer",
28340
28426
  "Process Monitor",
@@ -28355,16 +28441,16 @@ var SYSINTERNALS_TOOLS = [
28355
28441
  "ZoomIt"
28356
28442
  ];
28357
28443
  async function afterInstall(entry, exe) {
28358
- const dir = path27.dirname(exe);
28444
+ const dir = path28.dirname(exe);
28359
28445
  if (entry.needs?.includes("mesa")) {
28360
28446
  const mesa = tool("mesa", arch === "arm64" ? "arm64" : "x64");
28361
28447
  for (const dll of ["opengl32.dll", "libgallium_wgl.dll", "dxil.dll"]) {
28362
- if (exists(path27.join(mesa, dll)) && !exists(path27.join(dir, dll)))
28363
- fs19.copyFileSync(path27.join(mesa, dll), path27.join(dir, dll));
28448
+ if (exists(path28.join(mesa, dll)) && !exists(path28.join(dir, dll)))
28449
+ fs20.copyFileSync(path28.join(mesa, dll), path28.join(dir, dll));
28364
28450
  }
28365
28451
  }
28366
- if (entry.id === "godot" && !exists(path27.join(dir, "._sc_"))) fs19.writeFileSync(path27.join(dir, "._sc_"), "");
28367
- if (entry.id === "sublime") mkdirp(path27.join(dir, "Data"));
28452
+ if (entry.id === "godot" && !exists(path28.join(dir, "._sc_"))) fs20.writeFileSync(path28.join(dir, "._sc_"), "");
28453
+ if (entry.id === "sublime") mkdirp(path28.join(dir, "Data"));
28368
28454
  if (entry.id === "sysinternals") {
28369
28455
  for (const name of SYSINTERNALS_TOOLS) {
28370
28456
  await execAsync(
@@ -28377,14 +28463,14 @@ async function afterInstall(entry, exe) {
28377
28463
  }
28378
28464
 
28379
28465
  // src/guest/apps/find-exe.ts
28380
- import fs20 from "node:fs";
28381
- import path28 from "node:path";
28466
+ import fs21 from "node:fs";
28467
+ import path29 from "node:path";
28382
28468
  var MAX_DEPTH = 7;
28383
28469
  var MAX_ENTRIES = 5e4;
28384
28470
  var X64_FOLDER = /(^|[\\/])(amd64|x64|x86_64|win64)([\\/]|$)/i;
28385
28471
  function findExe(root, exe) {
28386
28472
  const match = exeMatcher(exe);
28387
- const best = (hits) => hits.find((h) => X64_FOLDER.test(path28.relative(root, h))) ?? hits[0] ?? null;
28473
+ const best = (hits) => hits.find((h) => X64_FOLDER.test(path29.relative(root, h))) ?? hits[0] ?? null;
28388
28474
  let queue = [root];
28389
28475
  let seen = 0;
28390
28476
  for (let depth = 0; depth < MAX_DEPTH && queue.length; depth++) {
@@ -28393,14 +28479,14 @@ function findExe(root, exe) {
28393
28479
  for (const dir of queue) {
28394
28480
  let entries2;
28395
28481
  try {
28396
- entries2 = fs20.readdirSync(dir, { withFileTypes: true });
28482
+ entries2 = fs21.readdirSync(dir, { withFileTypes: true });
28397
28483
  } catch {
28398
28484
  continue;
28399
28485
  }
28400
28486
  const hit = entries2.find((e) => e.isFile() && match(e.name));
28401
- if (hit) hits.push(path28.join(dir, hit.name));
28487
+ if (hit) hits.push(path29.join(dir, hit.name));
28402
28488
  else
28403
- next.push(...entries2.filter((e) => e.isDirectory() && !e.isSymbolicLink()).map((e) => path28.join(dir, e.name)));
28489
+ next.push(...entries2.filter((e) => e.isDirectory() && !e.isSymbolicLink()).map((e) => path29.join(dir, e.name)));
28404
28490
  if ((seen += entries2.length) > MAX_ENTRIES) return best(hits);
28405
28491
  }
28406
28492
  if (hits.length) return best(hits);
@@ -28411,12 +28497,12 @@ function findExe(root, exe) {
28411
28497
 
28412
28498
  // src/guest/apps/shortcuts.ts
28413
28499
  import os5 from "node:os";
28414
- import path29 from "node:path";
28500
+ import path30 from "node:path";
28415
28501
  function shortcuts(apps) {
28416
28502
  if (!apps.length) return;
28417
- const desktop = path29.join(os5.homedir(), "Desktop");
28418
- const start = path29.join(
28419
- process.env.APPDATA ?? path29.join(os5.homedir(), "AppData", "Roaming"),
28503
+ const desktop = path30.join(os5.homedir(), "Desktop");
28504
+ const start = path30.join(
28505
+ process.env.APPDATA ?? path30.join(os5.homedir(), "AppData", "Roaming"),
28420
28506
  "Microsoft",
28421
28507
  "Windows",
28422
28508
  "Start Menu",
@@ -28426,9 +28512,9 @@ function shortcuts(apps) {
28426
28512
  const links = apps.flatMap((app) => {
28427
28513
  const name = app.name.replace(/[\\/:*?"<>|]/g, "");
28428
28514
  return [desktop, start].map((folder) => ({
28429
- link: path29.join(folder, name + ".lnk"),
28515
+ link: path30.join(folder, name + ".lnk"),
28430
28516
  target: app.exe,
28431
- workingDirectory: path29.dirname(app.exe)
28517
+ workingDirectory: path30.dirname(app.exe)
28432
28518
  }));
28433
28519
  });
28434
28520
  runScriptWithJson("new-shortcuts.ps1", "ListFile", links);
@@ -28560,12 +28646,12 @@ async function resolve(entry) {
28560
28646
  }
28561
28647
 
28562
28648
  // src/guest/apps/unpack.ts
28563
- import fs21 from "node:fs";
28564
- import path30 from "node:path";
28649
+ import fs22 from "node:fs";
28650
+ import path31 from "node:path";
28565
28651
  var sevenZip = () => tool("apps", "7zip", "7z.exe");
28566
28652
  async function unpack(entry, file3, out, d) {
28567
28653
  if (entry.id === "7zip") {
28568
- const sevenZr = path30.join(path30.dirname(file3), "7zr.exe");
28654
+ const sevenZr = path31.join(path31.dirname(file3), "7zr.exe");
28569
28655
  const zr = await githubAsset("ip7z/7zip", /^7zr\.exe$/);
28570
28656
  await downloader.file(zr.url, sevenZr, zr.sha256);
28571
28657
  await execAsync(sevenZr, ["x", "-y", "-o" + out, file3], { stdio: "ignore" });
@@ -28574,17 +28660,17 @@ async function unpack(entry, file3, out, d) {
28574
28660
  switch (entry.unpack ?? "archive") {
28575
28661
  case "file": {
28576
28662
  mkdirp(out);
28577
- fs21.renameSync(file3, path30.join(out, /^\//.test(entry.exe) ? path30.basename(file3) : entry.exe));
28663
+ fs22.renameSync(file3, path31.join(out, /^\//.test(entry.exe) ? path31.basename(file3) : entry.exe));
28578
28664
  return;
28579
28665
  }
28580
28666
  case "nsis": {
28581
28667
  if (!exists(sevenZip()))
28582
28668
  throw new Error("7-Zip is needed to unpack " + entry.name + " and could not be installed");
28583
- const raw = path30.join(path30.dirname(out), "raw");
28669
+ const raw = path31.join(path31.dirname(out), "raw");
28584
28670
  await execAsync(sevenZip(), ["x", "-y", "-o" + raw, file3], { stdio: "ignore" });
28585
28671
  const inner = findExe(raw, "/^app-64\\.7z$/");
28586
28672
  if (inner) await execAsync(sevenZip(), ["x", "-y", "-o" + out, inner], { stdio: "ignore" });
28587
- else fs21.renameSync(raw, out);
28673
+ else fs22.renameSync(raw, out);
28588
28674
  return;
28589
28675
  }
28590
28676
  case "msi": {
@@ -28634,11 +28720,11 @@ var AppInstaller = class {
28634
28720
  async installOne(entry) {
28635
28721
  try {
28636
28722
  const dest = tool("apps", ...entry.id.split("/"));
28637
- if (!exists(path31.join(dest, MARKER)) || this.options.refresh) await this.download(entry, dest);
28723
+ if (!exists(path32.join(dest, MARKER)) || this.options.refresh) await this.download(entry, dest);
28638
28724
  const exe = findExe(dest, entry.exe);
28639
28725
  if (!exe) throw new Error(entry.exe + " not found in the download");
28640
28726
  await afterInstall(entry, exe);
28641
- if (entry.cli || entry.id === "sysinternals") this.env.prepend.push(path31.dirname(exe));
28727
+ if (entry.cli || entry.id === "sysinternals") this.env.prepend.push(path32.dirname(exe));
28642
28728
  if (!entry.cli) this.gui.push({ name: entry.name, exe });
28643
28729
  this.installed.push(entry.name);
28644
28730
  } catch (e) {
@@ -28651,10 +28737,10 @@ var AppInstaller = class {
28651
28737
  /** Downloads and unpacks one entry into its folder (replaced in one step: never half there). */
28652
28738
  async download(entry, dest) {
28653
28739
  const work = stagingFolder(dest);
28654
- const out = path31.join(work, "out");
28740
+ const out = path32.join(work, "out");
28655
28741
  try {
28656
28742
  if ("npm" in entry.source) {
28657
- const npmCli = path31.join(path31.dirname(process.execPath), "node_modules", "npm", "bin", "npm-cli.js");
28743
+ const npmCli = path32.join(path32.dirname(process.execPath), "node_modules", "npm", "bin", "npm-cli.js");
28658
28744
  log("Installing " + entry.name + " (npm) ...");
28659
28745
  await execAsync(process.execPath, [
28660
28746
  npmCli,
@@ -28669,14 +28755,14 @@ var AppInstaller = class {
28669
28755
  } else {
28670
28756
  const d = await resolve(entry);
28671
28757
  log("Downloading " + entry.name + " (" + d.fileName + ", ~" + entry.size + " once) ...");
28672
- const file3 = path31.join(mkdirp(work), d.fileName.replace(/[\\/:*?"<>|]/g, "_"));
28758
+ const file3 = path32.join(mkdirp(work), d.fileName.replace(/[\\/:*?"<>|]/g, "_"));
28673
28759
  await downloader.file(d.url, file3, { sha256: d.sha256 ?? null });
28674
28760
  await unpack(entry, file3, out, d);
28675
28761
  }
28676
- fs22.writeFileSync(path31.join(out, MARKER), JSON.stringify({ id: entry.id, at: (/* @__PURE__ */ new Date()).toISOString() }));
28762
+ fs23.writeFileSync(path32.join(out, MARKER), JSON.stringify({ id: entry.id, at: (/* @__PURE__ */ new Date()).toISOString() }));
28677
28763
  moveIntoPlace(out, dest);
28678
28764
  } finally {
28679
- safeRemove(work, path31.dirname(work));
28765
+ safeRemove(work, path32.dirname(work));
28680
28766
  }
28681
28767
  }
28682
28768
  };
@@ -28691,8 +28777,8 @@ async function setupApps(env, apps, o) {
28691
28777
  }
28692
28778
 
28693
28779
  // src/guest/toolchains/detect.ts
28694
- import fs23 from "node:fs";
28695
- import path32 from "node:path";
28780
+ import fs24 from "node:fs";
28781
+ import path33 from "node:path";
28696
28782
 
28697
28783
  // src/core/detect/versions.ts
28698
28784
  function pickNodeVersion(releases, spec) {
@@ -28824,14 +28910,14 @@ function workspaceEntries() {
28824
28910
  if (known) return known;
28825
28911
  const list = (dir) => {
28826
28912
  try {
28827
- return fs23.readdirSync(dir, { withFileTypes: true });
28913
+ return fs24.readdirSync(dir, { withFileTypes: true });
28828
28914
  } catch {
28829
28915
  return [];
28830
28916
  }
28831
28917
  };
28832
28918
  const top = list(workspace2);
28833
28919
  const below = top.filter((d) => d.isDirectory() && !d.name.startsWith(".") && !SKIP_DIRS.has(d.name.toLowerCase())).flatMap(
28834
- (d) => list(path32.join(workspace2, d.name)).filter((f) => f.isFile()).map((f) => d.name + "/" + f.name)
28920
+ (d) => list(path33.join(workspace2, d.name)).filter((f) => f.isFile()).map((f) => d.name + "/" + f.name)
28835
28921
  );
28836
28922
  const found = [...top.filter((d) => d.isFile()).map((d) => d.name), ...below];
28837
28923
  entries.set(workspace2.toLowerCase(), found);
@@ -28842,9 +28928,9 @@ function wanted(setting, toolchain) {
28842
28928
  }
28843
28929
  function versionFromFiles(files, parse5 = (t) => specFromVersionFile(t)) {
28844
28930
  for (const name of files) {
28845
- const file3 = path32.join(projectWorkspace(), name);
28931
+ const file3 = path33.join(projectWorkspace(), name);
28846
28932
  if (!exists(file3)) continue;
28847
- const spec = parse5(fs23.readFileSync(file3, "utf8"), name);
28933
+ const spec = parse5(fs24.readFileSync(file3, "utf8"), name);
28848
28934
  if (spec) return { spec, source: name };
28849
28935
  }
28850
28936
  return null;
@@ -28917,22 +29003,22 @@ var DatabaseServer = class {
28917
29003
  };
28918
29004
 
28919
29005
  // src/guest/databases/dynamodb.ts
28920
- import fs28 from "node:fs";
28921
- import path35 from "node:path";
29006
+ import fs29 from "node:fs";
29007
+ import path36 from "node:path";
28922
29008
  import { spawn as spawn3 } from "node:child_process";
28923
29009
 
28924
29010
  // src/guest/toolchains/languages/java.ts
28925
- import fs26 from "node:fs";
28926
- import path33 from "node:path";
29011
+ import fs27 from "node:fs";
29012
+ import path34 from "node:path";
28927
29013
 
28928
29014
  // src/guest/toolchains/version-cache.ts
28929
- import fs25 from "node:fs";
29015
+ import fs26 from "node:fs";
28930
29016
 
28931
29017
  // src/guest/toolchains/state-file.ts
28932
- import fs24 from "node:fs";
29018
+ import fs25 from "node:fs";
28933
29019
  function readState(file3, schema, empty) {
28934
29020
  try {
28935
- return schema.safeParse(JSON.parse(fs24.readFileSync(file3, "utf8").replace(/^\uFEFF/, ""))).data ?? empty;
29021
+ return schema.safeParse(JSON.parse(fs25.readFileSync(file3, "utf8").replace(/^\uFEFF/, ""))).data ?? empty;
28936
29022
  } catch {
28937
29023
  return empty;
28938
29024
  }
@@ -28967,7 +29053,7 @@ var VersionCache = class {
28967
29053
  return cached2.value;
28968
29054
  try {
28969
29055
  const value = await resolve2();
28970
- fs25.mkdirSync(toolsDir, { recursive: true });
29056
+ fs26.mkdirSync(toolsDir, { recursive: true });
28971
29057
  writeJsonAtomic(this.file(), { ...this.remembered(), [key2]: { value, at: Date.now() } });
28972
29058
  return value;
28973
29059
  } catch (e) {
@@ -29020,7 +29106,7 @@ var setupJdk = async (env, config2) => {
29020
29106
  const { major, source } = await javaMajor(config2);
29021
29107
  const release = await resolveCached("java:" + major, async () => (await temurin(major)).release_name);
29022
29108
  const home = tool("java", release.replace(/[^A-Za-z0-9.-]/g, "_"));
29023
- if (!exists(path33.join(home, "bin", "java.exe"))) {
29109
+ if (!exists(path34.join(home, "bin", "java.exe"))) {
29024
29110
  const asset = await temurin(major);
29025
29111
  log("Downloading Java " + release + " (JDK, ~200 MB once) ...");
29026
29112
  await downloader.archive(asset.binary.package.link, home, {
@@ -29030,13 +29116,13 @@ var setupJdk = async (env, config2) => {
29030
29116
  });
29031
29117
  }
29032
29118
  env.vars.JAVA_HOME = home;
29033
- env.prepend.push(path33.join(home, "bin"));
29119
+ env.prepend.push(path34.join(home, "bin"));
29034
29120
  env.summary.push("java: " + release + " (Temurin, from " + source + ")");
29035
29121
  };
29036
29122
  async function ensureJdk() {
29037
29123
  const root = tool("java");
29038
- const installed = exists(root) ? fs26.readdirSync(root).filter((d) => exists(path33.join(root, d, "bin", "java.exe"))).sort((a, b) => b.localeCompare(a, void 0, { numeric: true })) : [];
29039
- if (installed.length) return path33.join(root, installed[0]);
29124
+ const installed = exists(root) ? fs27.readdirSync(root).filter((d) => exists(path34.join(root, d, "bin", "java.exe"))).sort((a, b) => b.localeCompare(a, void 0, { numeric: true })) : [];
29125
+ if (installed.length) return path34.join(root, installed[0]);
29040
29126
  const scratch = emptyEnv();
29041
29127
  await setupJdk(scratch, { enabled: true, version: "lts", maven: false, gradle: false });
29042
29128
  return scratch.vars.JAVA_HOME;
@@ -29049,7 +29135,7 @@ var setupMaven = async (env) => {
29049
29135
  return pickPackageVersion(versions, "3") ?? Promise.reject(new Error("No Maven 3 release found"));
29050
29136
  });
29051
29137
  const home = tool("maven", version2);
29052
- if (!exists(path33.join(home, "bin", "mvn.cmd"))) {
29138
+ if (!exists(path34.join(home, "bin", "mvn.cmd"))) {
29053
29139
  const url2 = MAVEN + version2 + "/apache-maven-" + version2 + "-bin.zip";
29054
29140
  log("Downloading Maven " + version2 + " (~10 MB once) ...");
29055
29141
  await downloader.archive(url2, home, {
@@ -29059,7 +29145,7 @@ var setupMaven = async (env) => {
29059
29145
  }
29060
29146
  const repo = tool("maven-repository");
29061
29147
  Object.assign(env.vars, { MAVEN_HOME: home, M2_HOME: home, MAVEN_OPTS: "-Dmaven.repo.local=" + repo });
29062
- env.prepend.push(path33.join(home, "bin"));
29148
+ env.prepend.push(path34.join(home, "bin"));
29063
29149
  env.summary.push("maven: " + version2);
29064
29150
  };
29065
29151
  var setupGradle = async (env) => {
@@ -29071,7 +29157,7 @@ var setupGradle = async (env) => {
29071
29157
  async () => current?.version ?? Promise.reject(new Error("Gradle version lookup failed"))
29072
29158
  );
29073
29159
  const home = tool("gradle", version2);
29074
- if (!exists(path33.join(home, "bin", "gradle.bat"))) {
29160
+ if (!exists(path34.join(home, "bin", "gradle.bat"))) {
29075
29161
  if (!current || current.version !== version2)
29076
29162
  throw new Error("Gradle " + version2 + " is not installed and cannot be downloaded right now");
29077
29163
  log("Downloading Gradle " + version2 + " (~130 MB once) ...");
@@ -29082,13 +29168,13 @@ var setupGradle = async (env) => {
29082
29168
  });
29083
29169
  }
29084
29170
  const userHome = tool("gradle-home");
29085
- fs26.mkdirSync(userHome, { recursive: true });
29171
+ fs27.mkdirSync(userHome, { recursive: true });
29086
29172
  Object.assign(env.vars, {
29087
29173
  GRADLE_HOME: home,
29088
29174
  GRADLE_USER_HOME: userHome,
29089
29175
  GRADLE_OPTS: "-Dorg.gradle.vfs.watch=false"
29090
29176
  });
29091
- env.prepend.push(path33.join(home, "bin"));
29177
+ env.prepend.push(path34.join(home, "bin"));
29092
29178
  env.summary.push("gradle: " + version2);
29093
29179
  };
29094
29180
  async function setupJava(env, config2) {
@@ -29112,29 +29198,29 @@ async function setupJava(env, config2) {
29112
29198
  }
29113
29199
 
29114
29200
  // src/guest/databases/server.ts
29115
- import fs27 from "node:fs";
29116
- import path34 from "node:path";
29201
+ import fs28 from "node:fs";
29202
+ import path35 from "node:path";
29117
29203
  import { spawn as spawn2 } from "node:child_process";
29118
29204
  function dataFor(name) {
29119
- return path34.join(dataDir, "databases", name);
29205
+ return path35.join(dataDir, "databases", name);
29120
29206
  }
29121
29207
  async function startServer(name, exe, args, port) {
29122
29208
  if (await portOpen(port)) throw new Error("port " + port + " is already in use (change databases." + name + ".port)");
29123
- const logFile2 = path34.join(logsDir, name + ".log");
29124
- const out = fs27.openSync(logFile2, "a");
29209
+ const logFile2 = path35.join(logsDir, name + ".log");
29210
+ const out = fs28.openSync(logFile2, "a");
29125
29211
  spawn2(exe, args, { detached: true, stdio: ["ignore", out, out], windowsHide: true }).unref();
29126
- fs27.closeSync(out);
29212
+ fs28.closeSync(out);
29127
29213
  if (!await waitForPort(port, 60))
29128
29214
  throw new Error(name + " did not start listening on port " + port + "; see " + logFile2);
29129
29215
  }
29130
29216
  async function clearStaleLocks(dir, files, port) {
29131
29217
  if (await portOpen(port)) return;
29132
- for (const f of files) fs27.rmSync(path34.join(dir, f), { force: true });
29218
+ for (const f of files) fs28.rmSync(path35.join(dir, f), { force: true });
29133
29219
  }
29134
29220
  async function createOnce(data, marker, create) {
29135
- if (exists(path34.join(data, marker))) return;
29221
+ if (exists(path35.join(data, marker))) return;
29136
29222
  const existed = exists(data);
29137
- mkdirp(path34.dirname(data));
29223
+ mkdirp(path35.dirname(data));
29138
29224
  try {
29139
29225
  await create();
29140
29226
  } catch (e) {
@@ -29158,9 +29244,9 @@ var DynamoServer = class extends DatabaseServer {
29158
29244
  * local endpoint up from AWS_ENDPOINT_URL_DYNAMODB, with dummy credentials (real ones never reach the sandbox).
29159
29245
  */
29160
29246
  async start(env, plan2) {
29161
- const java = path35.join(await ensureJdk(), "bin", "java.exe");
29247
+ const java = path36.join(await ensureJdk(), "bin", "java.exe");
29162
29248
  const home = tool("dynamodb-local");
29163
- if (!exists(path35.join(home, "DynamoDBLocal.jar"))) {
29249
+ if (!exists(path36.join(home, "DynamoDBLocal.jar"))) {
29164
29250
  log("Downloading DynamoDB Local (~60 MB once) ...");
29165
29251
  const sha256 = (await fetchText(DYNAMO_ZIP + ".sha256")).trim().split(/\s+/)[0];
29166
29252
  await downloader.archive(DYNAMO_ZIP, home, {
@@ -29174,9 +29260,9 @@ var DynamoServer = class extends DatabaseServer {
29174
29260
  "dynamodb",
29175
29261
  java,
29176
29262
  [
29177
- "-Djava.library.path=" + path35.join(home, "DynamoDBLocal_lib"),
29263
+ "-Djava.library.path=" + path36.join(home, "DynamoDBLocal_lib"),
29178
29264
  "-jar",
29179
- path35.join(home, "DynamoDBLocal.jar"),
29265
+ path36.join(home, "DynamoDBLocal.jar"),
29180
29266
  "-sharedDb",
29181
29267
  "-dbPath",
29182
29268
  data,
@@ -29200,10 +29286,10 @@ var DynamoServer = class extends DatabaseServer {
29200
29286
  );
29201
29287
  if (!plan2.adminPort) return;
29202
29288
  const prefix = tool("dynamodb-admin");
29203
- const script = path35.join(prefix, "node_modules", "dynamodb-admin", "dist", "dynamodb-admin.js");
29289
+ const script = path36.join(prefix, "node_modules", "dynamodb-admin", "dist", "dynamodb-admin.js");
29204
29290
  if (!exists(script)) {
29205
29291
  log("Installing dynamodb-admin, the DynamoDB web UI (~20 MB once) ...");
29206
- const npmCli = path35.join(path35.dirname(process.execPath), "node_modules", "npm", "bin", "npm-cli.js");
29292
+ const npmCli = path36.join(path36.dirname(process.execPath), "node_modules", "npm", "bin", "npm-cli.js");
29207
29293
  await execAsync(
29208
29294
  process.execPath,
29209
29295
  [npmCli, "install", "--global", "--prefix", prefix, "dynamodb-admin", "--no-fund", "--no-audit"],
@@ -29216,15 +29302,15 @@ var DynamoServer = class extends DatabaseServer {
29216
29302
  );
29217
29303
  return;
29218
29304
  }
29219
- const out = fs28.openSync(path35.join(logsDir, "dynamodb-admin.log"), "a");
29305
+ const out = fs29.openSync(path36.join(logsDir, "dynamodb-admin.log"), "a");
29220
29306
  spawn3(
29221
29307
  process.execPath,
29222
29308
  [script, "--port", String(plan2.adminPort), "--dynamo-endpoint", endpoint, "--skip-default-credentials"],
29223
29309
  { detached: true, stdio: ["ignore", out, out], windowsHide: true, env: { ...process.env, ...aws } }
29224
29310
  ).unref();
29225
- fs28.closeSync(out);
29311
+ fs29.closeSync(out);
29226
29312
  if (!await waitForPort(plan2.adminPort, 30))
29227
- throw new Error("dynamodb-admin did not start; see " + path35.join(logsDir, "dynamodb-admin.log"));
29313
+ throw new Error("dynamodb-admin did not start; see " + path36.join(logsDir, "dynamodb-admin.log"));
29228
29314
  env.summary.push(
29229
29315
  "dynamodb-admin: http://localhost:" + plan2.adminPort + " (browse and edit tables in the sandbox's browser)"
29230
29316
  );
@@ -29232,18 +29318,18 @@ var DynamoServer = class extends DatabaseServer {
29232
29318
  };
29233
29319
 
29234
29320
  // src/guest/databases/mongodb.ts
29235
- import path36 from "node:path";
29321
+ import path37 from "node:path";
29236
29322
 
29237
29323
  // src/guest/toolchains/install.ts
29238
- import fs29 from "node:fs";
29324
+ import fs30 from "node:fs";
29239
29325
  async function downloadFile(url2, file3, sha256 = null) {
29240
29326
  const part = file3 + ".part";
29241
29327
  try {
29242
29328
  await downloader.file(url2, part, sha256);
29243
- fs29.rmSync(file3, { force: true });
29244
- fs29.renameSync(part, file3);
29329
+ fs30.rmSync(file3, { force: true });
29330
+ fs30.renameSync(part, file3);
29245
29331
  } finally {
29246
- fs29.rmSync(part, { force: true });
29332
+ fs30.rmSync(part, { force: true });
29247
29333
  }
29248
29334
  }
29249
29335
  async function installFromGithub(repo, pattern, o) {
@@ -29272,13 +29358,13 @@ var MongoServer = class extends DatabaseServer {
29272
29358
  };
29273
29359
  const version2 = await resolveCached("mongodb:" + plan2.version, async () => (await find()).version);
29274
29360
  const home = tool("mongodb", version2);
29275
- if (!exists(path36.join(home, "bin", "mongod.exe"))) {
29361
+ if (!exists(path37.join(home, "bin", "mongod.exe"))) {
29276
29362
  const { archive } = await find();
29277
29363
  log("Downloading MongoDB " + version2 + " (~400 MB once) ...");
29278
29364
  await downloader.archive(archive.url, home, { sha256: archive.sha256, locate: "mongod.exe", up: 1 });
29279
29365
  }
29280
29366
  const shell = tool("mongosh");
29281
- if (!exists(path36.join(shell, "mongosh.exe"))) {
29367
+ if (!exists(path37.join(shell, "mongosh.exe"))) {
29282
29368
  await installFromGithub("mongodb-js/mongosh", /^mongosh-[\d.]+-win32-x64\.zip$/, {
29283
29369
  dest: shell,
29284
29370
  what: "mongosh, the MongoDB shell (~50 MB once)",
@@ -29289,17 +29375,17 @@ var MongoServer = class extends DatabaseServer {
29289
29375
  await clearStaleLocks(data, ["mongod.lock"], plan2.port);
29290
29376
  await startServer(
29291
29377
  "mongodb",
29292
- path36.join(home, "bin", "mongod.exe"),
29378
+ path37.join(home, "bin", "mongod.exe"),
29293
29379
  ["--dbpath", data, "--bind_ip", "127.0.0.1", "--port", String(plan2.port)],
29294
29380
  plan2.port
29295
29381
  );
29296
- env.prepend.push(path36.join(home, "bin"), shell);
29382
+ env.prepend.push(path37.join(home, "bin"), shell);
29297
29383
  env.summary.push("mongodb " + version2 + ": mongodb://127.0.0.1:" + plan2.port + " (mongosh on PATH)");
29298
29384
  }
29299
29385
  };
29300
29386
 
29301
29387
  // src/guest/databases/mysql.ts
29302
- import path37 from "node:path";
29388
+ import path38 from "node:path";
29303
29389
  var MARIA = "https://downloads.mariadb.org/rest-api/mariadb/";
29304
29390
  var MysqlServer = class extends DatabaseServer {
29305
29391
  id = "mysql";
@@ -29317,8 +29403,8 @@ var MysqlServer = class extends DatabaseServer {
29317
29403
  };
29318
29404
  const version2 = await resolveCached("mariadb-version:" + series, async () => (await latest()).version);
29319
29405
  const home = tool("mariadb", version2);
29320
- const bin = path37.join(home, "bin");
29321
- if (!exists(path37.join(bin, "mariadbd.exe"))) {
29406
+ const bin = path38.join(home, "bin");
29407
+ if (!exists(path38.join(bin, "mariadbd.exe"))) {
29322
29408
  const { zip } = await latest();
29323
29409
  log("Downloading MariaDB " + version2 + " (~90 MB once) ...");
29324
29410
  await downloader.archive(zip.file_download_url.replace(/^http:/, "https:"), home, {
@@ -29331,13 +29417,13 @@ var MysqlServer = class extends DatabaseServer {
29331
29417
  const data = dataFor("mariadb");
29332
29418
  await createOnce(data, "mysql", async () => {
29333
29419
  log("Creating the MariaDB database (first start) ...");
29334
- await execAsync(path37.join(bin, "mariadb-install-db.exe"), ["--datadir=" + data, "--port=" + plan2.port], {
29420
+ await execAsync(path38.join(bin, "mariadb-install-db.exe"), ["--datadir=" + data, "--port=" + plan2.port], {
29335
29421
  stdio: "ignore"
29336
29422
  });
29337
29423
  });
29338
29424
  await startServer(
29339
29425
  "mysql",
29340
- path37.join(bin, "mariadbd.exe"),
29426
+ path38.join(bin, "mariadbd.exe"),
29341
29427
  ["--datadir=" + data, "--port=" + plan2.port, "--bind-address=127.0.0.1", "--console"],
29342
29428
  plan2.port
29343
29429
  );
@@ -29350,8 +29436,8 @@ var MysqlServer = class extends DatabaseServer {
29350
29436
  };
29351
29437
 
29352
29438
  // src/guest/databases/postgres.ts
29353
- import fs30 from "node:fs";
29354
- import path38 from "node:path";
29439
+ import fs31 from "node:fs";
29440
+ import path39 from "node:path";
29355
29441
  function postgresData(version2) {
29356
29442
  return dataFor("postgres-" + version2.split(".")[0]);
29357
29443
  }
@@ -29366,8 +29452,8 @@ var PostgresServer = class extends DatabaseServer {
29366
29452
  return hit ? hit.major + "." + hit.latestMinor : Promise.reject(new Error("No supported PostgreSQL " + plan2.version));
29367
29453
  });
29368
29454
  const home = tool("postgres", exact);
29369
- const bin = path38.join(home, "bin");
29370
- if (!exists(path38.join(bin, "pg_ctl.exe"))) {
29455
+ const bin = path39.join(home, "bin");
29456
+ if (!exists(path39.join(bin, "pg_ctl.exe"))) {
29371
29457
  log("Downloading PostgreSQL " + exact + " (~330 MB once) ...");
29372
29458
  await downloader.archive(
29373
29459
  "https://get.enterprisedb.com/postgresql/postgresql-" + exact + "-1-windows-x64-binaries.zip",
@@ -29384,7 +29470,7 @@ var PostgresServer = class extends DatabaseServer {
29384
29470
  await createOnce(data, "PG_VERSION", async () => {
29385
29471
  log("Creating the PostgreSQL database (first start) ...");
29386
29472
  await execAsync(
29387
- path38.join(bin, "initdb.exe"),
29473
+ path39.join(bin, "initdb.exe"),
29388
29474
  ["-D", data, "-U", "postgres", "-A", "trust", "-E", "UTF8", "--locale=C"],
29389
29475
  { stdio: "ignore" }
29390
29476
  );
@@ -29393,7 +29479,7 @@ var PostgresServer = class extends DatabaseServer {
29393
29479
  throw new Error("port " + plan2.port + " is already in use (change databases.postgres.port)");
29394
29480
  await clearStaleLocks(data, ["postmaster.pid"], plan2.port);
29395
29481
  await execAsync(
29396
- path38.join(bin, "pg_ctl.exe"),
29482
+ path39.join(bin, "pg_ctl.exe"),
29397
29483
  [
29398
29484
  "start",
29399
29485
  "-D",
@@ -29402,7 +29488,7 @@ var PostgresServer = class extends DatabaseServer {
29402
29488
  "-t",
29403
29489
  "60",
29404
29490
  "-l",
29405
- path38.join(logsDir, "postgres.log"),
29491
+ path39.join(logsDir, "postgres.log"),
29406
29492
  "-o",
29407
29493
  "-p " + plan2.port + " -c listen_addresses=localhost"
29408
29494
  ],
@@ -29417,10 +29503,10 @@ var PostgresServer = class extends DatabaseServer {
29417
29503
  /** Every installed version's cluster shuts down cleanly through pg_ctl first. */
29418
29504
  async stop(plan2) {
29419
29505
  if (exists(tool("postgres"))) {
29420
- for (const version2 of fs30.readdirSync(tool("postgres"))) {
29506
+ for (const version2 of fs31.readdirSync(tool("postgres"))) {
29421
29507
  const data = postgresData(version2);
29422
- const pgCtl = path38.join(tool("postgres", version2), "bin", "pg_ctl.exe");
29423
- if (exists(path38.join(data, "postmaster.pid")) && exists(pgCtl))
29508
+ const pgCtl = path39.join(tool("postgres", version2), "bin", "pg_ctl.exe");
29509
+ if (exists(path39.join(data, "postmaster.pid")) && exists(pgCtl))
29424
29510
  await execAsync(pgCtl, ["stop", "-D", data, "-m", "fast", "-w"], { stdio: "ignore" });
29425
29511
  }
29426
29512
  }
@@ -29429,12 +29515,12 @@ var PostgresServer = class extends DatabaseServer {
29429
29515
  };
29430
29516
 
29431
29517
  // src/guest/databases/redis.ts
29432
- import path39 from "node:path";
29518
+ import path40 from "node:path";
29433
29519
  var RedisServer = class extends DatabaseServer {
29434
29520
  id = "redis";
29435
29521
  async start(env, plan2) {
29436
29522
  const home = tool("redis");
29437
- if (!exists(path39.join(home, "redis-server.exe"))) {
29523
+ if (!exists(path40.join(home, "redis-server.exe"))) {
29438
29524
  await installFromGithub("redis-windows/redis-windows", /^Redis-[\d.]+-Windows-x64-msys2\.zip$/, {
29439
29525
  dest: home,
29440
29526
  what: (a) => "Redis (" + a.name + ", ~10 MB once)",
@@ -29444,7 +29530,7 @@ var RedisServer = class extends DatabaseServer {
29444
29530
  const data = mkdirp(dataFor("redis"));
29445
29531
  await startServer(
29446
29532
  "redis",
29447
- path39.join(home, "redis-server.exe"),
29533
+ path40.join(home, "redis-server.exe"),
29448
29534
  ["--port", String(plan2.port), "--bind", "127.0.0.1", "--dir", data.replace(/\\/g, "/"), "--appendonly", "yes"],
29449
29535
  plan2.port
29450
29536
  );
@@ -29482,16 +29568,16 @@ async function setupDatabase(env, plan2) {
29482
29568
  }
29483
29569
 
29484
29570
  // src/guest/toolchains/tools/git.ts
29485
- import fs32 from "node:fs";
29486
- import path41 from "node:path";
29571
+ import fs33 from "node:fs";
29572
+ import path42 from "node:path";
29487
29573
 
29488
29574
  // src/guest/runtime/csc.ts
29489
- import fs31 from "node:fs";
29575
+ import fs32 from "node:fs";
29490
29576
  import os6 from "node:os";
29491
- import path40 from "node:path";
29577
+ import path41 from "node:path";
29492
29578
  import crypto3 from "node:crypto";
29493
29579
  import { spawnSync as spawnSync5 } from "node:child_process";
29494
- var CSC = path40.join(process.env.WINDIR ?? "C:\\Windows", "Microsoft.NET", "Framework64", "v4.0.30319", "csc.exe");
29580
+ var CSC = path41.join(process.env.WINDIR ?? "C:\\Windows", "Microsoft.NET", "Framework64", "v4.0.30319", "csc.exe");
29495
29581
  var SOURCES = {
29496
29582
  ptyhost: "PtyHost.cs",
29497
29583
  gitshim: "GitShim.cs",
@@ -29503,17 +29589,17 @@ var SOURCES = {
29503
29589
  memgov: "MemGov.cs"
29504
29590
  };
29505
29591
  function sourceOf(name) {
29506
- return path40.join(launchDir, "sandbox", "csharp", SOURCES[name]);
29592
+ return path41.join(launchDir, "sandbox", "csharp", SOURCES[name]);
29507
29593
  }
29508
29594
  function sourceHash(name) {
29509
- return crypto3.createHash("sha256").update(fs31.readFileSync(sourceOf(name))).digest("hex").slice(0, 12);
29595
+ return crypto3.createHash("sha256").update(fs32.readFileSync(sourceOf(name))).digest("hex").slice(0, 12);
29510
29596
  }
29511
29597
  function ensureCompiled(name) {
29512
- const exe = path40.join(os6.tmpdir(), "agent-sandbox", name + "-" + sourceHash(name) + ".exe");
29598
+ const exe = path41.join(os6.tmpdir(), "agent-sandbox", name + "-" + sourceHash(name) + ".exe");
29513
29599
  if (exists(exe)) return exe;
29514
29600
  if (!exists(CSC))
29515
29601
  throw new Error("The .NET Framework C# compiler was not found at " + CSC + " (it ships with Windows 10/11).");
29516
- mkdirp(path40.dirname(exe));
29602
+ mkdirp(path41.dirname(exe));
29517
29603
  const result = spawnSync5(CSC, ["/nologo", "/optimize", "/target:exe", "/out:" + exe, sourceOf(name)], {
29518
29604
  encoding: "utf8",
29519
29605
  windowsHide: true
@@ -29547,23 +29633,23 @@ var installPortableGit = async (root) => {
29547
29633
  await downloader.file(asset.url, sfx, asset.sha256);
29548
29634
  await execAsync(sfx, ["-o" + root, "-y"], { stdio: "ignore" });
29549
29635
  } finally {
29550
- fs32.rmSync(sfx, { force: true });
29636
+ fs33.rmSync(sfx, { force: true });
29551
29637
  }
29552
29638
  };
29553
29639
  var installGuard = (env, access, realGit) => {
29554
29640
  const dir = mkdirp(tool("gitguard"));
29555
- const guard = path41.join(launchDir, "runtime", "gitguard.js");
29556
- if (duringSession() && (exists(path41.join(dir, "git.exe")) || exists(path41.join(dir, "git.cmd")))) {
29641
+ const guard = path42.join(launchDir, "runtime", "gitguard.js");
29642
+ if (duringSession() && (exists(path42.join(dir, "git.exe")) || exists(path42.join(dir, "git.cmd")))) {
29557
29643
  } else
29558
29644
  try {
29559
- fs32.copyFileSync(ensureCompiled("gitshim"), path41.join(dir, "git.exe"));
29560
- fs32.rmSync(path41.join(dir, "git.cmd"), { force: true });
29645
+ fs33.copyFileSync(ensureCompiled("gitshim"), path42.join(dir, "git.exe"));
29646
+ fs33.rmSync(path42.join(dir, "git.cmd"), { force: true });
29561
29647
  } catch (e) {
29562
29648
  warn("git guard: falling back to git.cmd (" + errMsg(e) + ")");
29563
- fs32.writeFileSync(path41.join(dir, "git.cmd"), '@"' + process.execPath + '" "' + guard + '" %*\r\n');
29649
+ fs33.writeFileSync(path42.join(dir, "git.cmd"), '@"' + process.execPath + '" "' + guard + '" %*\r\n');
29564
29650
  }
29565
- fs32.writeFileSync(
29566
- path41.join(dir, "bashenv.sh"),
29651
+ fs33.writeFileSync(
29652
+ path42.join(dir, "bashenv.sh"),
29567
29653
  'git() { "' + posix(process.execPath) + '" "' + posix(guard) + '" "$@"; }\nexport -f git\n'
29568
29654
  );
29569
29655
  env.prepend.unshift(dir);
@@ -29572,13 +29658,13 @@ var installGuard = (env, access, realGit) => {
29572
29658
  AGENT_REAL_GIT: access === "readonly" ? realGit : "",
29573
29659
  AGENT_GUARD_NODE: process.execPath,
29574
29660
  AGENT_GUARD_SCRIPT: guard,
29575
- BASH_ENV: posix(path41.join(dir, "bashenv.sh"))
29661
+ BASH_ENV: posix(path42.join(dir, "bashenv.sh"))
29576
29662
  });
29577
29663
  if (access === "readonly") {
29578
- const hooks = mkdirp(path41.join(dir, "hooks"));
29664
+ const hooks = mkdirp(path42.join(dir, "hooks"));
29579
29665
  for (const hook of BLOCKED_HOOKS)
29580
- fs32.writeFileSync(
29581
- path41.join(hooks, hook),
29666
+ fs33.writeFileSync(
29667
+ path42.join(hooks, hook),
29582
29668
  '#!/bin/sh\necho "git is read-only in this sandbox: ' + hook + ' refused." >&2\nexit 1\n'
29583
29669
  );
29584
29670
  Object.assign(env.vars, {
@@ -29587,22 +29673,22 @@ var installGuard = (env, access, realGit) => {
29587
29673
  GIT_CONFIG_VALUE_0: posix(hooks)
29588
29674
  });
29589
29675
  } else {
29590
- env.vars.GIT_DIR = path41.join(dataDir, "git-disabled");
29676
+ env.vars.GIT_DIR = path42.join(dataDir, "git-disabled");
29591
29677
  }
29592
29678
  };
29593
29679
  var pointAtOwnCertificates = (root) => {
29594
- const config2 = path41.join(root, "etc", "gitconfig");
29595
- const bundle = path41.join(root, "mingw64", "etc", "ssl", "certs", "ca-bundle.crt");
29680
+ const config2 = path42.join(root, "etc", "gitconfig");
29681
+ const bundle = path42.join(root, "mingw64", "etc", "ssl", "certs", "ca-bundle.crt");
29596
29682
  if (!exists(config2) || !exists(bundle)) return;
29597
- const text = fs32.readFileSync(config2, "utf8");
29683
+ const text = fs33.readFileSync(config2, "utf8");
29598
29684
  const fixed = text.replace(/^(\s*sslCAInfo\s*=\s*).*$/gim, (_m, key2) => key2 + posix(bundle));
29599
- if (fixed !== text) fs32.writeFileSync(config2, fixed);
29685
+ if (fixed !== text) fs33.writeFileSync(config2, fixed);
29600
29686
  };
29601
29687
  async function setupGit(env, hostCopy, refresh, access) {
29602
29688
  const root = tool("git");
29603
- const bash = path41.join(root, "bin", "bash.exe");
29604
- const gitExe = path41.join(root, "cmd", "git.exe");
29605
- const hostGit = path41.join(hostToolsDir, "git");
29689
+ const bash = path42.join(root, "bin", "bash.exe");
29690
+ const gitExe = path42.join(root, "cmd", "git.exe");
29691
+ const hostGit = path42.join(hostToolsDir, "git");
29606
29692
  if (exists(root) && !exists(bash)) {
29607
29693
  log("Replacing the old MinGit (no bash) with full Git for Windows.");
29608
29694
  safeRemove(root, toolsDir);
@@ -29616,11 +29702,11 @@ async function setupGit(env, hostCopy, refresh, access) {
29616
29702
  }
29617
29703
  const work = stagingFolder(root);
29618
29704
  try {
29619
- if (hostCopy && exists(path41.join(hostGit, "bin", "bash.exe"))) {
29705
+ if (hostCopy && exists(path42.join(hostGit, "bin", "bash.exe"))) {
29620
29706
  log("Copying Git for Windows from this PC ...");
29621
29707
  robocopy(hostGit, work);
29622
29708
  } else await installPortableGit(work);
29623
- if (!exists(path41.join(work, "bin", "bash.exe"))) throw new Error("bash.exe missing after installing Git");
29709
+ if (!exists(path42.join(work, "bin", "bash.exe"))) throw new Error("bash.exe missing after installing Git");
29624
29710
  moveIntoPlace(work, root);
29625
29711
  } finally {
29626
29712
  safeRemove(work, toolsDir);
@@ -29629,10 +29715,10 @@ async function setupGit(env, hostCopy, refresh, access) {
29629
29715
  if (!exists(bash)) throw new Error("bash.exe missing after installing Git");
29630
29716
  pointAtOwnCertificates(root);
29631
29717
  env.vars.CLAUDE_CODE_GIT_BASH_PATH = bash;
29632
- env.append.push(path41.join(root, "usr", "bin"));
29718
+ env.append.push(path42.join(root, "usr", "bin"));
29633
29719
  const version2 = execOutput(gitExe, ["--version"]).replace(/^git version /, "");
29634
29720
  if (access === "full") {
29635
- env.prepend.push(path41.join(root, "cmd"));
29721
+ env.prepend.push(path42.join(root, "cmd"));
29636
29722
  env.summary.push("git: " + version2);
29637
29723
  return;
29638
29724
  }
@@ -29643,8 +29729,8 @@ async function setupGit(env, hostCopy, refresh, access) {
29643
29729
  }
29644
29730
 
29645
29731
  // src/guest/toolchains/languages/go.ts
29646
- import fs33 from "node:fs";
29647
- import path42 from "node:path";
29732
+ import fs34 from "node:fs";
29733
+ import path43 from "node:path";
29648
29734
 
29649
29735
  // src/guest/toolchains/package-ledger.ts
29650
29736
  var LedgerSchema = external_exports.record(external_exports.string(), external_exports.string());
@@ -29698,7 +29784,7 @@ async function setupGo(env, config2) {
29698
29784
  }
29699
29785
  const version2 = await resolveCached("go:" + config2.version, async () => (await findRelease(config2.version)).version);
29700
29786
  const root = tool("go", version2);
29701
- if (!exists(path42.join(root, "bin", "go.exe"))) {
29787
+ if (!exists(path43.join(root, "bin", "go.exe"))) {
29702
29788
  const goArch = arch === "arm64" ? "arm64" : "amd64";
29703
29789
  const file3 = (await findRelease(version2)).files.find(
29704
29790
  (f) => f.os === "windows" && f.arch === goArch && f.kind === "archive"
@@ -29715,16 +29801,16 @@ async function setupGo(env, config2) {
29715
29801
  const vars = {
29716
29802
  GOROOT: root,
29717
29803
  GOPATH,
29718
- GOBIN: path42.join(GOPATH, "bin"),
29719
- GOMODCACHE: path42.join(GOPATH, "pkg", "mod"),
29804
+ GOBIN: path43.join(GOPATH, "bin"),
29805
+ GOMODCACHE: path43.join(GOPATH, "pkg", "mod"),
29720
29806
  GOCACHE: tool("go-cache"),
29721
29807
  GOTOOLCHAIN: "auto",
29722
29808
  GOTELEMETRY: "off"
29723
29809
  };
29724
- fs33.mkdirSync(vars.GOBIN, { recursive: true });
29810
+ fs34.mkdirSync(vars.GOBIN, { recursive: true });
29725
29811
  Object.assign(env.vars, vars);
29726
- env.prepend.push(path42.join(root, "bin"), vars.GOBIN);
29727
- const go = path42.join(root, "bin", "go.exe");
29812
+ env.prepend.push(path43.join(root, "bin"), vars.GOBIN);
29813
+ const go = path43.join(root, "bin", "go.exe");
29728
29814
  env.summary.push("go: " + versionOf(go, ["version"]));
29729
29815
  await installOnce(
29730
29816
  env,
@@ -29735,8 +29821,8 @@ async function setupGo(env, config2) {
29735
29821
  }
29736
29822
 
29737
29823
  // src/guest/toolchains/tools/cli.ts
29738
- import fs34 from "node:fs";
29739
- import path44 from "node:path";
29824
+ import fs35 from "node:fs";
29825
+ import path45 from "node:path";
29740
29826
 
29741
29827
  // src/guest/toolchains/catalogue.ts
29742
29828
  function pwshAsset(arch2) {
@@ -29783,14 +29869,14 @@ function decideCli(settings, ctx) {
29783
29869
  }
29784
29870
 
29785
29871
  // src/guest/toolchains/runtimes.ts
29786
- import path43 from "node:path";
29872
+ import path44 from "node:path";
29787
29873
  async function setupSingleExe(env, name, repo, pattern, exeName, dir, options = {}) {
29788
29874
  if (dryRun) {
29789
29875
  log("(dry run) would provision " + name);
29790
29876
  return;
29791
29877
  }
29792
- const bin = options.subdir ? path43.join(dir, options.subdir) : dir;
29793
- const exe = path43.join(bin, exeName);
29878
+ const bin = options.subdir ? path44.join(dir, options.subdir) : dir;
29879
+ const exe = path44.join(bin, exeName);
29794
29880
  if (!exists(exe) || options.refresh) {
29795
29881
  const size = options.size ? ", ~" + options.size : "";
29796
29882
  await installFromGithub(repo, pattern, {
@@ -29815,8 +29901,8 @@ async function setupBun(env) {
29815
29901
  );
29816
29902
  Object.assign(env.vars, {
29817
29903
  BUN_INSTALL: tool("bun"),
29818
- BUN_INSTALL_CACHE_DIR: path43.join(localDir, "bun-cache"),
29819
- BUN_TMPDIR: path43.join(localDir, "bun-tmp")
29904
+ BUN_INSTALL_CACHE_DIR: path44.join(localDir, "bun-cache"),
29905
+ BUN_TMPDIR: path44.join(localDir, "bun-tmp")
29820
29906
  });
29821
29907
  }
29822
29908
  async function setupDeno(env) {
@@ -29855,7 +29941,7 @@ async function setupUv(env) {
29855
29941
 
29856
29942
  // src/guest/toolchains/tools/cli.ts
29857
29943
  function ghConfigDir() {
29858
- return path44.join(stateDir, "gh");
29944
+ return path45.join(stateDir, "gh");
29859
29945
  }
29860
29946
  var toolVars = {
29861
29947
  gh: () => ({
@@ -29870,16 +29956,16 @@ var shimOpenssl = (env) => {
29870
29956
  return;
29871
29957
  }
29872
29958
  const shims = mkdirp(tool("shims"));
29873
- fs34.copyFileSync(ensureCompiled("openssl"), path44.join(shims, "openssl.exe"));
29874
- fs34.rmSync(path44.join(shims, "openssl.cmd"), { force: true });
29959
+ fs35.copyFileSync(ensureCompiled("openssl"), path45.join(shims, "openssl.exe"));
29960
+ fs35.rmSync(path45.join(shims, "openssl.cmd"), { force: true });
29875
29961
  env.prepend.push(shims);
29876
29962
  env.summary.push("openssl: Git for Windows' copy");
29877
29963
  };
29878
29964
  async function setupCli(env, settings, gitAccess, refresh = false) {
29879
- const decisions = decideCli(settings, { gitAccess, hasGithubDir: exists(path44.join(projectWorkspace(), ".github")) });
29965
+ const decisions = decideCli(settings, { gitAccess, hasGithubDir: exists(path45.join(projectWorkspace(), ".github")) });
29880
29966
  if (settings.gh && !decisions.gh.on) {
29881
29967
  env.summary.push("gh: off (" + decisions.gh.reason + ")");
29882
- if (exists(path44.join(ghConfigDir(), "hosts.yml")))
29968
+ if (exists(path45.join(ghConfigDir(), "hosts.yml")))
29883
29969
  warn(
29884
29970
  'gh is off (git access is not "full"), but an earlier gh login is still stored in ' + ghConfigDir() + " and readable by the agent. Run `gh auth logout` in a full-access sandbox, or delete that folder."
29885
29971
  );
@@ -29916,12 +30002,12 @@ async function setupCli(env, settings, gitAccess, refresh = false) {
29916
30002
  }
29917
30003
 
29918
30004
  // src/guest/toolchains/managers.ts
29919
- import fs35 from "node:fs";
29920
- import path45 from "node:path";
30005
+ import fs36 from "node:fs";
30006
+ import path46 from "node:path";
29921
30007
  function voltaPins() {
29922
30008
  try {
29923
30009
  const pkg = JSON.parse(
29924
- fs35.readFileSync(path45.join(projectWorkspace(), "package.json"), "utf8").replace(/^\uFEFF/, "")
30010
+ fs36.readFileSync(path46.join(projectWorkspace(), "package.json"), "utf8").replace(/^\uFEFF/, "")
29925
30011
  );
29926
30012
  return Object.fromEntries(
29927
30013
  Object.entries(pkg.volta ?? {}).filter(
@@ -29944,7 +30030,7 @@ async function setupVolta(env) {
29944
30030
  return;
29945
30031
  }
29946
30032
  const dir = tool("volta");
29947
- if (!exists(path45.join(dir, "volta.exe"))) {
30033
+ if (!exists(path46.join(dir, "volta.exe"))) {
29948
30034
  const pattern = arch === "arm64" ? /^volta-[\d.]+-windows-arm64\.zip$/ : /^volta-[\d.]+-windows\.zip$/;
29949
30035
  await installFromGithub("volta-cli/volta", pattern, {
29950
30036
  dest: dir,
@@ -29953,17 +30039,17 @@ async function setupVolta(env) {
29953
30039
  });
29954
30040
  }
29955
30041
  for (const shim3 of ["node", "npm", "npx", "pnpm", "pnpx", "yarn", "yarnpkg"]) {
29956
- const target = path45.join(dir, shim3 + ".exe");
29957
- if (!exists(target)) fs35.copyFileSync(path45.join(dir, "volta-shim.exe"), target);
30042
+ const target = path46.join(dir, shim3 + ".exe");
30043
+ if (!exists(target)) fs36.copyFileSync(path46.join(dir, "volta-shim.exe"), target);
29958
30044
  }
29959
30045
  const home = mkdirp(tool("volta-home"));
29960
- const shims = mkdirp(path45.join(home, "bin"));
30046
+ const shims = mkdirp(path46.join(home, "bin"));
29961
30047
  const vars = { VOLTA_HOME: home, VOLTA_FEATURE_PNPM: "1" };
29962
30048
  Object.assign(env.vars, vars);
29963
30049
  const pins = voltaPins();
29964
30050
  if (Object.keys(pins).length) env.prepend.push(dir, shims);
29965
30051
  else env.append.push(dir, shims);
29966
- const volta = path45.join(dir, "volta.exe");
30052
+ const volta = path46.join(dir, "volta.exe");
29967
30053
  for (const [toolName, version2] of Object.entries(pins)) {
29968
30054
  try {
29969
30055
  await execAsync(volta, ["install", toolName + "@" + version2], {
@@ -29985,7 +30071,7 @@ async function setupPyenv(env) {
29985
30071
  return;
29986
30072
  }
29987
30073
  const root = tool("pyenv", "pyenv-win");
29988
- if (!exists(path45.join(root, "bin", "pyenv.bat"))) {
30074
+ if (!exists(path46.join(root, "bin", "pyenv.bat"))) {
29989
30075
  const tag = await resolveCached("pyenv-win", () => latestGithubTag("pyenv-win/pyenv-win"));
29990
30076
  log("Downloading pyenv-win " + tag + " (~5 MB once) ...");
29991
30077
  await downloader.archive(
@@ -29994,17 +30080,17 @@ async function setupPyenv(env) {
29994
30080
  { locate: "pyenv.bat", up: 1, fileName: "pyenv-win.zip" }
29995
30081
  );
29996
30082
  }
29997
- const home = root + path45.sep;
30083
+ const home = root + path46.sep;
29998
30084
  Object.assign(env.vars, { PYENV: home, PYENV_ROOT: home, PYENV_HOME: home });
29999
- env.append.push(path45.join(root, "bin"), path45.join(root, "shims"));
30085
+ env.append.push(path46.join(root, "bin"), path46.join(root, "shims"));
30000
30086
  env.summary.push("pyenv-win: pyenv install <version> / pyenv local <version> (versions persist)");
30001
30087
  }
30002
30088
 
30003
30089
  // src/guest/toolchains/native/cpp.ts
30004
- import path46 from "node:path";
30090
+ import path47 from "node:path";
30005
30091
  async function setupCpp(env, config2) {
30006
30092
  const bin = tool("mingw", "mingw64", "bin");
30007
- const gcc = path46.join(bin, "gcc.exe");
30093
+ const gcc = path47.join(bin, "gcc.exe");
30008
30094
  if (dryRun) {
30009
30095
  log("(dry run) would provision MinGW-w64 GCC");
30010
30096
  return;
@@ -30020,7 +30106,7 @@ async function setupCpp(env, config2) {
30020
30106
  if (!exists(gcc)) throw new Error("gcc.exe missing after installing MinGW");
30021
30107
  env.append.unshift(bin);
30022
30108
  env.vars.CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER = gcc;
30023
- const cmake = versionOf(path46.join(bin, "cmake.exe"));
30109
+ const cmake = versionOf(path47.join(bin, "cmake.exe"));
30024
30110
  if (cmakeTooOld(cmake))
30025
30111
  warn(
30026
30112
  "The bundled CMake " + cmake + " is older than " + CMAKE_FLOOR + ", which many projects need; set toolchains.cpp.enabled to refresh it, or install a newer CMake into C:\\AgentData\\tools\\bin."
@@ -30030,7 +30116,7 @@ async function setupCpp(env, config2) {
30030
30116
  }
30031
30117
  var setupFlexBison = async (env) => {
30032
30118
  const dir = tool("winflexbison");
30033
- if (!exists(path46.join(dir, "win_bison.exe"))) {
30119
+ if (!exists(path47.join(dir, "win_bison.exe"))) {
30034
30120
  await installFromGithub("lexxmark/winflexbison", /^win_flex_bison-[\d.]+\.zip$/, {
30035
30121
  dest: dir,
30036
30122
  what: "win_flex / win_bison (~1 MB once)",
@@ -30038,16 +30124,16 @@ var setupFlexBison = async (env) => {
30038
30124
  });
30039
30125
  }
30040
30126
  env.append.push(dir);
30041
- env.summary.push("win_flex/win_bison: " + versionOf(path46.join(dir, "win_bison.exe")));
30127
+ env.summary.push("win_flex/win_bison: " + versionOf(path47.join(dir, "win_bison.exe")));
30042
30128
  };
30043
30129
 
30044
30130
  // src/guest/toolchains/native/dotnet.ts
30045
- import fs36 from "node:fs";
30046
- import path47 from "node:path";
30131
+ import fs37 from "node:fs";
30132
+ import path48 from "node:path";
30047
30133
  var DotnetMarkerSchema = external_exports.record(external_exports.string(), external_exports.boolean());
30048
30134
  async function setupDotnet(env, config2, refresh) {
30049
30135
  const root = tool("dotnet");
30050
- const marker = path47.join(root, ".agent-sandbox-installed.json");
30136
+ const marker = path48.join(root, ".agent-sandbox-installed.json");
30051
30137
  const script = tool("dotnet-install.ps1");
30052
30138
  if (dryRun) {
30053
30139
  log("(dry run) would provision .NET SDK channels " + config2.channels.join(", "));
@@ -30055,11 +30141,11 @@ async function setupDotnet(env, config2, refresh) {
30055
30141
  }
30056
30142
  const recorded = DotnetMarkerSchema.safeParse(exists(marker) && !refresh ? readJsonFile(marker) : {});
30057
30143
  const done = recorded.success ? recorded.data : {};
30058
- const globalJson = path47.join(projectWorkspace(), "global.json");
30144
+ const globalJson = path48.join(projectWorkspace(), "global.json");
30059
30145
  const installs = [
30060
30146
  ...config2.channels.map((c) => ["channel:" + c, ["-Channel", c]]),
30061
30147
  ...exists(globalJson) ? [
30062
- ["global.json:" + fs36.readFileSync(globalJson, "utf8").replace(/\s+/g, ""), ["-JSonFile", globalJson]]
30148
+ ["global.json:" + fs37.readFileSync(globalJson, "utf8").replace(/\s+/g, ""), ["-JSonFile", globalJson]]
30063
30149
  ] : []
30064
30150
  ];
30065
30151
  for (const [key2, args] of installs.filter(([k]) => !done[k])) {
@@ -30091,12 +30177,12 @@ async function setupDotnet(env, config2, refresh) {
30091
30177
  DOTNET_SKIP_FIRST_TIME_EXPERIENCE: "1",
30092
30178
  NUGET_PACKAGES: tool("nuget", "packages")
30093
30179
  });
30094
- env.prepend.push(root, path47.join(home, ".dotnet", "tools"));
30180
+ env.prepend.push(root, path48.join(home, ".dotnet", "tools"));
30095
30181
  env.summary.push(
30096
- "dotnet: " + execOutput(path47.join(root, "dotnet.exe"), ["--list-sdks"]).split(/\r?\n/).map((l) => l.split(" ")[0]).filter(Boolean).join(", ")
30182
+ "dotnet: " + execOutput(path48.join(root, "dotnet.exe"), ["--list-sdks"]).split(/\r?\n/).map((l) => l.split(" ")[0]).filter(Boolean).join(", ")
30097
30183
  );
30098
- const dotnet = path47.join(root, "dotnet.exe");
30099
- const dotnetEnv = { env: { ...process.env, ...env.vars, PATH: root + path47.delimiter + (process.env.PATH ?? "") } };
30184
+ const dotnet = path48.join(root, "dotnet.exe");
30185
+ const dotnetEnv = { env: { ...process.env, ...env.vars, PATH: root + path48.delimiter + (process.env.PATH ?? "") } };
30100
30186
  await installOnce(
30101
30187
  env,
30102
30188
  "dotnet workload",
@@ -30117,7 +30203,7 @@ var setupFrameworkReferences = async (env, targets) => {
30117
30203
  const root = tool("netfx-references");
30118
30204
  for (const target of targets) {
30119
30205
  const id = "microsoft.netframework.referenceassemblies." + target.toLowerCase();
30120
- const marker = path47.join(root, ".installed-" + target.toLowerCase());
30206
+ const marker = path48.join(root, ".installed-" + target.toLowerCase());
30121
30207
  if (exists(marker)) continue;
30122
30208
  const staging = tool("netfx-references-" + target.toLowerCase());
30123
30209
  try {
@@ -30132,8 +30218,8 @@ var setupFrameworkReferences = async (env, targets) => {
30132
30218
  staging,
30133
30219
  { fileName: id + ".zip" }
30134
30220
  );
30135
- fs36.cpSync(path47.join(staging, "build", ".NETFramework"), path47.join(root, ".NETFramework"), { recursive: true });
30136
- fs36.writeFileSync(marker, version2);
30221
+ fs37.cpSync(path48.join(staging, "build", ".NETFramework"), path48.join(root, ".NETFramework"), { recursive: true });
30222
+ fs37.writeFileSync(marker, version2);
30137
30223
  } catch (e) {
30138
30224
  warn(
30139
30225
  ".NET Framework " + target + " reference assemblies could not be installed (projects targeting it will not build): " + errMsg(e)
@@ -30142,9 +30228,9 @@ var setupFrameworkReferences = async (env, targets) => {
30142
30228
  safeRemove(staging, dataDir);
30143
30229
  }
30144
30230
  }
30145
- if (!exists(path47.join(root, ".NETFramework"))) return;
30146
- env.vars.TargetFrameworkRootPath = root + path47.sep;
30147
- env.summary.push(".NET Framework targeting: " + fs36.readdirSync(path47.join(root, ".NETFramework")).join(", "));
30231
+ if (!exists(path48.join(root, ".NETFramework"))) return;
30232
+ env.vars.TargetFrameworkRootPath = root + path48.sep;
30233
+ env.summary.push(".NET Framework targeting: " + fs37.readdirSync(path48.join(root, ".NETFramework")).join(", "));
30148
30234
  };
30149
30235
  var setupNetFx35 = async (env) => {
30150
30236
  if (execOutput(SYSTEM.reg(), [
@@ -30171,15 +30257,15 @@ var setupNetFx35 = async (env) => {
30171
30257
  };
30172
30258
 
30173
30259
  // src/guest/toolchains/native/mesa.ts
30174
- import path48 from "node:path";
30260
+ import path49 from "node:path";
30175
30261
  async function setupMesa(env, config2) {
30176
30262
  if (dryRun) {
30177
30263
  log("(dry run) would provision Mesa 3D");
30178
30264
  return;
30179
30265
  }
30180
30266
  const root = tool("mesa");
30181
- const dir = path48.join(root, arch === "arm64" ? "arm64" : "x64");
30182
- if (!exists(path48.join(dir, "opengl32.dll"))) {
30267
+ const dir = path49.join(root, arch === "arm64" ? "arm64" : "x64");
30268
+ if (!exists(path49.join(dir, "opengl32.dll"))) {
30183
30269
  await installFromGithub("pal1000/mesa-dist-win", /^mesa3d-[\d.]+-release-msvc\.7z$/, {
30184
30270
  dest: root,
30185
30271
  what: "Mesa 3D for software OpenGL (~100 MB once)",
@@ -30195,10 +30281,10 @@ async function setupMesa(env, config2) {
30195
30281
  }
30196
30282
  var VULKAN_RUNTIME = "https://sdk.lunarg.com/sdk/download/latest/windows/vulkan-runtime-components.zip";
30197
30283
  var setupLavapipe = async (env, mesaDir) => {
30198
- const icd = path48.join(mesaDir, arch === "arm64" ? "lvp_icd.aarch64.json" : "lvp_icd.x86_64.json");
30199
- if (!exists(icd)) throw new Error("this Mesa build has no lavapipe (" + path48.basename(icd) + ")");
30284
+ const icd = path49.join(mesaDir, arch === "arm64" ? "lvp_icd.aarch64.json" : "lvp_icd.x86_64.json");
30285
+ if (!exists(icd)) throw new Error("this Mesa build has no lavapipe (" + path49.basename(icd) + ")");
30200
30286
  const dir = tool("vulkan");
30201
- if (!exists(path48.join(dir, "vulkan-1.dll"))) {
30287
+ if (!exists(path49.join(dir, "vulkan-1.dll"))) {
30202
30288
  log("Downloading the Vulkan loader (~10 MB once) ...");
30203
30289
  await downloader.archive(VULKAN_RUNTIME, dir, {
30204
30290
  locate: "vulkan-1.dll",
@@ -30212,7 +30298,7 @@ var setupLavapipe = async (env, mesaDir) => {
30212
30298
  { stdio: "ignore" }
30213
30299
  );
30214
30300
  await register(icd);
30215
- const dozen = path48.join(mesaDir, arch === "arm64" ? "dzn_icd.aarch64.json" : "dzn_icd.x86_64.json");
30301
+ const dozen = path49.join(mesaDir, arch === "arm64" ? "dzn_icd.aarch64.json" : "dzn_icd.x86_64.json");
30216
30302
  const gpu = hasGpu();
30217
30303
  if (gpu && exists(dozen)) await register(dozen);
30218
30304
  env.prepend.push(dir);
@@ -30223,20 +30309,20 @@ var setupLavapipe = async (env, mesaDir) => {
30223
30309
  var hasGpu = () => scriptOutput("get-gpu-names.ps1", [], { timeout: 3e4 }).split(/\r?\n/).map((n) => n.trim()).some((n) => n && !/^Microsoft (Remote Display|Basic (Render|Display))/i.test(n));
30224
30310
 
30225
30311
  // src/guest/toolchains/native/msvc/index.ts
30226
- import fs40 from "node:fs";
30227
- import path52 from "node:path";
30312
+ import fs41 from "node:fs";
30313
+ import path53 from "node:path";
30228
30314
 
30229
30315
  // src/guest/toolchains/native/msvc/environment.ts
30230
- import fs38 from "node:fs";
30231
- import path50 from "node:path";
30316
+ import fs39 from "node:fs";
30317
+ import path51 from "node:path";
30232
30318
 
30233
30319
  // src/guest/toolchains/native/msvc/tree.ts
30234
- import fs37 from "node:fs";
30235
- import path49 from "node:path";
30320
+ import fs38 from "node:fs";
30321
+ import path50 from "node:path";
30236
30322
  var ROOT = tool("msvc");
30237
- var MARKER2 = path49.join(ROOT, ".installed.json");
30323
+ var MARKER2 = path50.join(ROOT, ".installed.json");
30238
30324
  function msvcTools(msvc, ...parts2) {
30239
- return path49.join(ROOT, "VC", "Tools", "MSVC", msvc, ...parts2);
30325
+ return path50.join(ROOT, "VC", "Tools", "MSVC", msvc, ...parts2);
30240
30326
  }
30241
30327
  function hostBin(msvc, ...parts2) {
30242
30328
  return msvcTools(msvc, "bin", "Hostx64", "x64", ...parts2);
@@ -30247,27 +30333,27 @@ function hasCompiler(msvc) {
30247
30333
  var InstalledSchema = external_exports.object({ msvc: external_exports.string().min(1), sdk: external_exports.string().min(1), want: external_exports.string() });
30248
30334
  function readInstalled() {
30249
30335
  try {
30250
- return InstalledSchema.safeParse(JSON.parse(fs37.readFileSync(MARKER2, "utf8"))).data ?? null;
30336
+ return InstalledSchema.safeParse(JSON.parse(fs38.readFileSync(MARKER2, "utf8"))).data ?? null;
30251
30337
  } catch {
30252
30338
  return null;
30253
30339
  }
30254
30340
  }
30255
30341
 
30256
30342
  // src/guest/toolchains/native/msvc/environment.ts
30257
- var VSWHERE_DIR = path50.join(
30343
+ var VSWHERE_DIR = path51.join(
30258
30344
  process.env["ProgramFiles(x86)"] ?? "C:\\Program Files (x86)",
30259
30345
  "Microsoft Visual Studio",
30260
30346
  "Installer"
30261
30347
  );
30262
30348
  function vcvars(root, msvc, sdk) {
30263
- const vc = path50.join(root, "VC", "Tools", "MSVC", msvc);
30264
- const kits = path50.join(root, "Windows Kits", "10");
30265
- const inc = (...p) => path50.join(kits, "Include", sdk, ...p);
30266
- const lib = (...p) => path50.join(kits, "Lib", sdk, ...p);
30349
+ const vc = path51.join(root, "VC", "Tools", "MSVC", msvc);
30350
+ const kits = path51.join(root, "Windows Kits", "10");
30351
+ const inc = (...p) => path51.join(kits, "Include", sdk, ...p);
30352
+ const lib = (...p) => path51.join(kits, "Lib", sdk, ...p);
30267
30353
  return {
30268
30354
  vars: {
30269
30355
  VSINSTALLDIR: root + "\\",
30270
- VCINSTALLDIR: path50.join(root, "VC") + "\\",
30356
+ VCINSTALLDIR: path51.join(root, "VC") + "\\",
30271
30357
  VCToolsInstallDir: vc + "\\",
30272
30358
  VCToolsVersion: msvc,
30273
30359
  VisualStudioVersion: "17.0",
@@ -30279,17 +30365,17 @@ function vcvars(root, msvc, sdk) {
30279
30365
  VSCMD_ARG_HOST_ARCH: "x64",
30280
30366
  VSCMD_ARG_TGT_ARCH: "x64",
30281
30367
  Platform: "x64",
30282
- INCLUDE: [path50.join(vc, "include"), inc("ucrt"), inc("shared"), inc("um"), inc("winrt"), inc("cppwinrt")].join(
30368
+ INCLUDE: [path51.join(vc, "include"), inc("ucrt"), inc("shared"), inc("um"), inc("winrt"), inc("cppwinrt")].join(
30283
30369
  ";"
30284
30370
  ),
30285
- LIB: [path50.join(vc, "lib", "x64"), lib("ucrt", "x64"), lib("um", "x64")].join(";"),
30286
- LIBPATH: [path50.join(vc, "lib", "x64"), path50.join(vc, "lib", "x86", "store", "references")].join(";")
30371
+ LIB: [path51.join(vc, "lib", "x64"), lib("ucrt", "x64"), lib("um", "x64")].join(";"),
30372
+ LIBPATH: [path51.join(vc, "lib", "x64"), path51.join(vc, "lib", "x86", "store", "references")].join(";")
30287
30373
  },
30288
- path: [path50.join(vc, "bin", "Hostx64", "x64"), path50.join(kits, "bin", sdk, "x64")]
30374
+ path: [path51.join(vc, "bin", "Hostx64", "x64"), path51.join(kits, "bin", sdk, "x64")]
30289
30375
  };
30290
30376
  }
30291
30377
  function writeVcvars(env) {
30292
- const dir = mkdirp(path50.join(ROOT, "VC", "Auxiliary", "Build"));
30378
+ const dir = mkdirp(path51.join(ROOT, "VC", "Auxiliary", "Build"));
30293
30379
  const lines = [
30294
30380
  "@echo off",
30295
30381
  "rem Written by Windows Development Sandbox for its portable MSVC (host x64, target x64).",
@@ -30297,9 +30383,9 @@ function writeVcvars(env) {
30297
30383
  'set "PATH=' + env.path.join(";") + ';%PATH%"',
30298
30384
  "exit /b 0"
30299
30385
  ];
30300
- fs38.writeFileSync(path50.join(dir, "vcvars64.bat"), lines.join("\r\n") + "\r\n");
30301
- fs38.writeFileSync(
30302
- path50.join(dir, "vcvarsall.bat"),
30386
+ fs39.writeFileSync(path51.join(dir, "vcvars64.bat"), lines.join("\r\n") + "\r\n");
30387
+ fs39.writeFileSync(
30388
+ path51.join(dir, "vcvarsall.bat"),
30303
30389
  ["@echo off", "rem Only x64 (amd64) is installed.", 'call "%~dp0vcvars64.bat"', "exit /b %errorlevel%"].join(
30304
30390
  "\r\n"
30305
30391
  ) + "\r\n"
@@ -30307,24 +30393,24 @@ function writeVcvars(env) {
30307
30393
  }
30308
30394
  function installVswhere(msvc) {
30309
30395
  mkdirp(VSWHERE_DIR);
30310
- fs38.copyFileSync(ensureCompiled("vswhere"), path50.join(VSWHERE_DIR, "vswhere.exe"));
30396
+ fs39.copyFileSync(ensureCompiled("vswhere"), path51.join(VSWHERE_DIR, "vswhere.exe"));
30311
30397
  const [major, minor] = msvc.split(".").slice(2);
30312
- fs38.writeFileSync(
30313
- path50.join(VSWHERE_DIR, "vswhere.json"),
30398
+ fs39.writeFileSync(
30399
+ path51.join(VSWHERE_DIR, "vswhere.json"),
30314
30400
  JSON.stringify({ installationPath: ROOT, installationVersion: "17." + (minor ?? "0") + ".0." + (major ?? "0") })
30315
30401
  );
30316
30402
  }
30317
30403
  function removeTelemetry(msvc) {
30318
30404
  try {
30319
- fs38.rmSync(hostBin(msvc, "vctip.exe"), { force: true });
30405
+ fs39.rmSync(hostBin(msvc, "vctip.exe"), { force: true });
30320
30406
  } catch (e) {
30321
30407
  warn("Could not remove MSVC's telemetry helper (vctip.exe); it may keep tools\\msvc locked: " + errMsg(e));
30322
30408
  }
30323
30409
  }
30324
30410
 
30325
30411
  // src/guest/toolchains/native/msvc/packages.ts
30326
- import fs39 from "node:fs";
30327
- import path51 from "node:path";
30412
+ import fs40 from "node:fs";
30413
+ import path52 from "node:path";
30328
30414
  var CHANNEL = "https://aka.ms/vs/17/release/channel";
30329
30415
  var MANIFEST_DAY_MS = 24 * 60 * 60 * 1e3;
30330
30416
  var MSVC_PARTS = [
@@ -30350,10 +30436,10 @@ var SDK_MSIS = [
30350
30436
  "Windows SDK Desktop Tools x64-x86_en-us.msi"
30351
30437
  ];
30352
30438
  var manifest = async () => {
30353
- const cached2 = path51.join(ROOT, ".manifest.json");
30354
- if (exists(cached2) && Date.now() - fs39.statSync(cached2).mtimeMs < MANIFEST_DAY_MS) {
30439
+ const cached2 = path52.join(ROOT, ".manifest.json");
30440
+ if (exists(cached2) && Date.now() - fs40.statSync(cached2).mtimeMs < MANIFEST_DAY_MS) {
30355
30441
  try {
30356
- return JSON.parse(fs39.readFileSync(cached2, "utf8"));
30442
+ return JSON.parse(fs40.readFileSync(cached2, "utf8"));
30357
30443
  } catch {
30358
30444
  }
30359
30445
  }
@@ -30362,26 +30448,26 @@ var manifest = async () => {
30362
30448
  if (!item) throw new Error("the Visual Studio channel has no package manifest");
30363
30449
  mkdirp(ROOT);
30364
30450
  await downloader.file(item.url, cached2);
30365
- return JSON.parse(fs39.readFileSync(cached2, "utf8"));
30451
+ return JSON.parse(fs40.readFileSync(cached2, "utf8"));
30366
30452
  };
30367
30453
  var unpackVsix = async (vsix, work) => {
30368
- const out = mkdirp(path51.join(work, "vsix-" + path51.basename(vsix)));
30454
+ const out = mkdirp(path52.join(work, "vsix-" + path52.basename(vsix)));
30369
30455
  await extractArchive(vsix, out, ["Contents"]);
30370
30456
  const decode4 = (dir) => {
30371
- for (const entry of fs39.readdirSync(dir, { withFileTypes: true })) {
30372
- const from = path51.join(dir, entry.name);
30457
+ for (const entry of fs40.readdirSync(dir, { withFileTypes: true })) {
30458
+ const from = path52.join(dir, entry.name);
30373
30459
  let name = entry.name;
30374
30460
  try {
30375
30461
  if (name.includes("%")) name = decodeURIComponent(name);
30376
30462
  } catch {
30377
30463
  }
30378
- const to = path51.join(dir, name);
30379
- if (to !== from) fs39.renameSync(from, to);
30464
+ const to = path52.join(dir, name);
30465
+ if (to !== from) fs40.renameSync(from, to);
30380
30466
  if (entry.isDirectory()) decode4(to);
30381
30467
  }
30382
30468
  };
30383
30469
  decode4(out);
30384
- fs39.cpSync(path51.join(out, "Contents"), ROOT, { recursive: true, force: true });
30470
+ fs40.cpSync(path52.join(out, "Contents"), ROOT, { recursive: true, force: true });
30385
30471
  safeRemove(out, work);
30386
30472
  };
30387
30473
  var unpackMsi = async (msi) => {
@@ -30391,9 +30477,9 @@ var unpackMsi = async (msi) => {
30391
30477
  stdio: "ignore"
30392
30478
  });
30393
30479
  } catch (e) {
30394
- const lines = exists(logFile2) ? fs39.readFileSync(logFile2, "utf16le").split(/\r?\n/).filter((l) => /error|return value 3|failed/i.test(l)).slice(-4).join(" | ") : "";
30480
+ const lines = exists(logFile2) ? fs40.readFileSync(logFile2, "utf16le").split(/\r?\n/).filter((l) => /error|return value 3|failed/i.test(l)).slice(-4).join(" | ") : "";
30395
30481
  throw new Error(
30396
- path51.basename(msi) + " did not unpack: " + (e instanceof Error ? e.message : String(e)) + (lines ? " (" + lines.slice(0, 600) + ")" : "")
30482
+ path52.basename(msi) + " did not unpack: " + (e instanceof Error ? e.message : String(e)) + (lines ? " (" + lines.slice(0, 600) + ")" : "")
30397
30483
  );
30398
30484
  }
30399
30485
  };
@@ -30406,13 +30492,13 @@ var catalogue = (m) => {
30406
30492
  };
30407
30493
  };
30408
30494
  var payloadFetcher = (work) => async (p) => {
30409
- const file3 = path51.join(work, path51.basename(p.fileName.replace(/\\/g, "/")));
30495
+ const file3 = path52.join(work, path52.basename(p.fileName.replace(/\\/g, "/")));
30410
30496
  if (!exists(file3)) await downloader.file(p.url, file3, p.sha256);
30411
30497
  return file3;
30412
30498
  };
30413
30499
  var unpackedToolset = () => {
30414
- const toolsRoot = path51.join(ROOT, "VC", "Tools", "MSVC");
30415
- return fs39.readdirSync(toolsRoot).filter((d) => exists(hostBin(d, "cl.exe"))).sort((a, b) => a.localeCompare(b, void 0, { numeric: true })).pop();
30500
+ const toolsRoot = path52.join(ROOT, "VC", "Tools", "MSVC");
30501
+ return fs40.readdirSync(toolsRoot).filter((d) => exists(hostBin(d, "cl.exe"))).sort((a, b) => a.localeCompare(b, void 0, { numeric: true })).pop();
30416
30502
  };
30417
30503
  async function installPackages(config2) {
30418
30504
  const { ids, pick: pick2 } = catalogue(await manifest());
@@ -30420,7 +30506,7 @@ async function installPackages(config2) {
30420
30506
  if (!version2) throw new Error("no MSVC " + config2.msvcVersion + " in the Visual Studio manifest");
30421
30507
  const sdk = pickWindowsSdk(ids, config2.sdkVersion);
30422
30508
  if (!sdk) throw new Error("no Windows SDK " + config2.sdkVersion + " in the Visual Studio manifest");
30423
- const work = mkdirp(path51.join(ROOT, ".download"));
30509
+ const work = mkdirp(path52.join(ROOT, ".download"));
30424
30510
  const fetchPayload = payloadFetcher(work);
30425
30511
  log("Downloading the MSVC " + version2 + " compiler and C/C++ libraries ...");
30426
30512
  for (const part of MSVC_PARTS) {
@@ -30440,17 +30526,17 @@ async function installPackages(config2) {
30440
30526
  if (!p) throw new Error("the Windows SDK package has no " + name);
30441
30527
  const file3 = await fetchPayload(p);
30442
30528
  msis.push(file3);
30443
- for (const cab of msiCabs(fs39.readFileSync(file3))) {
30529
+ for (const cab of msiCabs(fs40.readFileSync(file3))) {
30444
30530
  const c = payload(cab);
30445
30531
  if (c) await fetchPayload(c);
30446
30532
  }
30447
30533
  }
30448
30534
  log("Unpacking the Windows SDK (a few minutes) ...");
30449
30535
  for (const msi of msis) await unpackMsi(msi);
30450
- for (const name of fs39.readdirSync(ROOT).filter((n) => n.toLowerCase().endsWith(".msi")))
30451
- fs39.rmSync(path51.join(ROOT, name), { force: true });
30536
+ for (const name of fs40.readdirSync(ROOT).filter((n) => n.toLowerCase().endsWith(".msi")))
30537
+ fs40.rmSync(path52.join(ROOT, name), { force: true });
30452
30538
  safeRemove(work, ROOT);
30453
- const sdkVersion = fs39.readdirSync(path51.join(ROOT, "Windows Kits", "10", "Include")).filter((d) => d.startsWith("10.0." + sdk.build)).sort().pop();
30539
+ const sdkVersion = fs40.readdirSync(path52.join(ROOT, "Windows Kits", "10", "Include")).filter((d) => d.startsWith("10.0." + sdk.build)).sort().pop();
30454
30540
  if (!sdkVersion) throw new Error("the Windows SDK did not unpack (no Include\\10.0." + sdk.build + ".*)");
30455
30541
  const toolset = unpackedToolset();
30456
30542
  if (!toolset) throw new Error("MSVC " + version2 + " did not unpack (no cl.exe under VC\\Tools\\MSVC)");
@@ -30464,8 +30550,8 @@ function installedMsvcEnv() {
30464
30550
  }
30465
30551
  var clearTree = () => {
30466
30552
  if (!exists(ROOT)) return;
30467
- for (const name of fs40.readdirSync(ROOT).filter((n) => n !== ".manifest.json" && n !== ".download"))
30468
- safeRemove(path52.join(ROOT, name), ROOT);
30553
+ for (const name of fs41.readdirSync(ROOT).filter((n) => n !== ".manifest.json" && n !== ".download"))
30554
+ safeRemove(path53.join(ROOT, name), ROOT);
30469
30555
  };
30470
30556
  async function setupMsvc(env, config2) {
30471
30557
  if (!config2.acceptLicense) {
@@ -30495,24 +30581,24 @@ async function setupMsvc(env, config2) {
30495
30581
  }
30496
30582
 
30497
30583
  // src/guest/toolchains/native/rust.ts
30498
- import path54 from "node:path";
30584
+ import path55 from "node:path";
30499
30585
 
30500
30586
  // src/guest/toolchains/native/binstall.ts
30501
- import fs41 from "node:fs";
30502
- import path53 from "node:path";
30587
+ import fs42 from "node:fs";
30588
+ import path54 from "node:path";
30503
30589
  var ensureBinstall = async (cargoBin) => {
30504
- const target = path53.join(cargoBin, "cargo-binstall.exe");
30590
+ const target = path54.join(cargoBin, "cargo-binstall.exe");
30505
30591
  if (exists(target)) return true;
30506
30592
  try {
30507
30593
  const dir = tool("cargo-binstall");
30508
- if (!exists(path53.join(dir, "cargo-binstall.exe"))) {
30594
+ if (!exists(path54.join(dir, "cargo-binstall.exe"))) {
30509
30595
  await installFromGithub("cargo-bins/cargo-binstall", binstallAsset(arch), {
30510
30596
  dest: dir,
30511
30597
  what: "cargo-binstall for prebuilt Rust tools (~10 MB once)",
30512
30598
  locate: "cargo-binstall.exe"
30513
30599
  });
30514
30600
  }
30515
- fs41.copyFileSync(path53.join(dir, "cargo-binstall.exe"), target);
30601
+ fs42.copyFileSync(path54.join(dir, "cargo-binstall.exe"), target);
30516
30602
  return true;
30517
30603
  } catch (e) {
30518
30604
  warn("cargo-binstall unavailable, compiling crates with cargo install instead: " + errMsg(e));
@@ -30520,14 +30606,14 @@ var ensureBinstall = async (cargoBin) => {
30520
30606
  }
30521
30607
  };
30522
30608
  function crateInstaller(cargoHome, cargoEnv) {
30523
- const cargo = path53.join(cargoHome, "bin", "cargo.exe");
30609
+ const cargo = path54.join(cargoHome, "bin", "cargo.exe");
30524
30610
  let binstall = null;
30525
30611
  const binstallEnv = {
30526
30612
  ...cargoEnv,
30527
30613
  env: { ...cargoEnv.env ?? process.env, BINSTALL_DISABLE_TELEMETRY: "true" }
30528
30614
  };
30529
30615
  return async (crate) => {
30530
- binstall ??= ensureBinstall(path53.join(cargoHome, "bin"));
30616
+ binstall ??= ensureBinstall(path54.join(cargoHome, "bin"));
30531
30617
  if (await binstall) {
30532
30618
  try {
30533
30619
  await execAsync(
@@ -30549,7 +30635,7 @@ async function setupRust(env, config2, refresh) {
30549
30635
  const RUSTUP_HOME = tool("rust", "rustup");
30550
30636
  const CARGO_HOME = tool("rust", "cargo");
30551
30637
  const rustEnv = { env: { ...process.env, RUSTUP_HOME, CARGO_HOME } };
30552
- const rustup = path54.join(CARGO_HOME, "bin", "rustup.exe");
30638
+ const rustup = path55.join(CARGO_HOME, "bin", "rustup.exe");
30553
30639
  if (dryRun) {
30554
30640
  log("(dry run) would provision Rust " + config2.toolchain + " (" + config2.host + ")");
30555
30641
  return;
@@ -30585,9 +30671,9 @@ async function setupRust(env, config2, refresh) {
30585
30671
  if (refresh) await execAsync(rustup, ["update"], rustEnv);
30586
30672
  }
30587
30673
  Object.assign(env.vars, { RUSTUP_HOME, CARGO_HOME });
30588
- env.prepend.push(path54.join(CARGO_HOME, "bin"));
30674
+ env.prepend.push(path55.join(CARGO_HOME, "bin"));
30589
30675
  env.summary.push(
30590
- "rust: " + versionOf(path54.join(CARGO_HOME, "bin", "rustc.exe"), ["--version"], rustEnv) + " [" + config2.host + "]"
30676
+ "rust: " + versionOf(path55.join(CARGO_HOME, "bin", "rustc.exe"), ["--version"], rustEnv) + " [" + config2.host + "]"
30591
30677
  );
30592
30678
  const toolchainKey = "rustup@" + config2.toolchain;
30593
30679
  await installOnce(
@@ -30608,36 +30694,36 @@ async function setupRust(env, config2, refresh) {
30608
30694
  env: {
30609
30695
  ...rustEnv.env,
30610
30696
  ...msvc.vars,
30611
- PATH: [path54.join(CARGO_HOME, "bin"), ...msvc.path, process.env.PATH ?? ""].join(path54.delimiter)
30697
+ PATH: [path55.join(CARGO_HOME, "bin"), ...msvc.path, process.env.PATH ?? ""].join(path55.delimiter)
30612
30698
  }
30613
30699
  } : {
30614
30700
  env: {
30615
30701
  ...rustEnv.env,
30616
- CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER: path54.join(mingw, "gcc.exe"),
30617
- PATH: [path54.join(CARGO_HOME, "bin"), mingw, process.env.PATH ?? ""].join(path54.delimiter)
30702
+ CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER: path55.join(mingw, "gcc.exe"),
30703
+ PATH: [path55.join(CARGO_HOME, "bin"), mingw, process.env.PATH ?? ""].join(path55.delimiter)
30618
30704
  }
30619
30705
  };
30620
30706
  await installOnce(env, "cargo", config2.crates, crateInstaller(CARGO_HOME, cargoEnv));
30621
30707
  }
30622
30708
 
30623
30709
  // src/guest/toolchains/languages/node.ts
30624
- import fs42 from "node:fs";
30625
- import path55 from "node:path";
30710
+ import fs43 from "node:fs";
30711
+ import path56 from "node:path";
30626
30712
  import { spawn as spawn4 } from "node:child_process";
30627
30713
  var NVM_HOME = tool("nvm");
30628
- var NVM_SYMLINK = path55.join(localDir, "nodejs");
30629
- var HOST_NVM = path55.join(hostToolsDir, "nvm");
30714
+ var NVM_SYMLINK = path56.join(localDir, "nodejs");
30715
+ var HOST_NVM = path56.join(hostToolsDir, "nvm");
30630
30716
  var HOST_VERSIONS_MAX = 3;
30631
- var hostNvmVersions = () => exists(HOST_NVM) ? fs42.readdirSync(HOST_NVM).filter((d) => /^v\d+\.\d+\.\d+$/.test(d) && exists(path55.join(HOST_NVM, d, "node.exe"))).map((d) => d.slice(1)) : [];
30717
+ var hostNvmVersions = () => exists(HOST_NVM) ? fs43.readdirSync(HOST_NVM).filter((d) => /^v\d+\.\d+\.\d+$/.test(d) && exists(path56.join(HOST_NVM, d, "node.exe"))).map((d) => d.slice(1)) : [];
30632
30718
  var resolveNode = (spec) => resolveCached("node:" + spec, async () => {
30633
30719
  const exact = spec.replace(/^v/, "");
30634
30720
  if (/^\d+\.\d+\.\d+$/.test(exact)) return exact;
30635
30721
  const releases = await fetchJson("https://nodejs.org/dist/index.json");
30636
30722
  return pickNodeVersion(releases, spec) ?? Promise.reject(new Error('No Node.js release matches "' + spec + '"'));
30637
30723
  });
30638
- var NVM_TEMP = path55.join(NVM_HOME, ".tmp");
30724
+ var NVM_TEMP = path56.join(NVM_HOME, ".tmp");
30639
30725
  var nvm = (args) => new Promise((resolve2) => {
30640
- const child = spawn4(path55.join(NVM_HOME, "nvm.exe"), args, {
30726
+ const child = spawn4(path56.join(NVM_HOME, "nvm.exe"), args, {
30641
30727
  windowsHide: true,
30642
30728
  env: { ...process.env, NVM_HOME, NVM_SYMLINK, TEMP: NVM_TEMP, TMP: NVM_TEMP }
30643
30729
  });
@@ -30652,27 +30738,37 @@ var nvm = (args) => new Promise((resolve2) => {
30652
30738
  child.once("close", () => resolve2(out));
30653
30739
  });
30654
30740
  var ensureNvm = async () => {
30655
- if (exists(path55.join(NVM_HOME, "nvm.exe"))) return;
30656
- if (exists(path55.join(HOST_NVM, "nvm.exe"))) {
30741
+ if (exists(path56.join(NVM_HOME, "nvm.exe"))) return;
30742
+ if (exists(path56.join(HOST_NVM, "nvm.exe"))) {
30657
30743
  log("Copying nvm from this PC ...");
30658
30744
  mkdirp(NVM_HOME);
30659
- const files = fs42.readdirSync(HOST_NVM).filter((f) => /\.(exe|cmd|vbs)$/i.test(f)).sort((a, b) => Number(a.toLowerCase() === "nvm.exe") - Number(b.toLowerCase() === "nvm.exe"));
30660
- for (const file3 of files) fs42.copyFileSync(path55.join(HOST_NVM, file3), path55.join(NVM_HOME, file3));
30745
+ const files = fs43.readdirSync(HOST_NVM).filter((f) => /\.(exe|cmd|vbs)$/i.test(f)).sort((a, b) => Number(a.toLowerCase() === "nvm.exe") - Number(b.toLowerCase() === "nvm.exe"));
30746
+ for (const file3 of files) fs43.copyFileSync(path56.join(HOST_NVM, file3), path56.join(NVM_HOME, file3));
30661
30747
  return;
30662
30748
  }
30663
30749
  const asset = await githubAsset("coreybutler/nvm-windows", /^nvm-noinstall\.zip$/, true);
30664
30750
  log("Downloading nvm-windows (" + asset.url.split("/").slice(-2, -1)[0] + ") ...");
30665
30751
  await downloader.archive(asset.url, NVM_HOME, { sha256: asset.sha256, locate: "nvm.exe", fileName: asset.name });
30666
30752
  };
30753
+ var hostNodeFolder = (version2) => {
30754
+ const dir = path56.join(hostToolsDir, "node");
30755
+ return session.hostTools.nodeVersion?.replace(/^v/, "") === version2 && exists(path56.join(dir, "node.exe")) ? dir : null;
30756
+ };
30667
30757
  var installNodeVersion = async (version2) => {
30668
- const dir = path55.join(NVM_HOME, "v" + version2);
30669
- const fromHost = path55.join(HOST_NVM, "v" + version2);
30670
- if (exists(path55.join(dir, "node.exe"))) return;
30671
- if (exists(path55.join(fromHost, "node.exe"))) {
30758
+ const dir = path56.join(NVM_HOME, "v" + version2);
30759
+ const fromHost = path56.join(HOST_NVM, "v" + version2);
30760
+ if (exists(path56.join(dir, "node.exe"))) return;
30761
+ if (exists(path56.join(fromHost, "node.exe"))) {
30672
30762
  log("Copying Node " + version2 + " from this PC's nvm (without global packages) ...");
30673
30763
  copyNode(fromHost, dir);
30674
30764
  return;
30675
30765
  }
30766
+ const hostNode = hostNodeFolder(version2);
30767
+ if (hostNode) {
30768
+ log("Copying Node " + version2 + " from this PC (without global packages) ...");
30769
+ copyNode(hostNode, dir);
30770
+ return;
30771
+ }
30676
30772
  log("Downloading Node " + version2 + " (~30 MB once) ...");
30677
30773
  mkdirp(NVM_TEMP);
30678
30774
  let out;
@@ -30681,14 +30777,19 @@ var installNodeVersion = async (version2) => {
30681
30777
  } finally {
30682
30778
  safeRemove(NVM_TEMP, NVM_HOME);
30683
30779
  }
30684
- if (!exists(path55.join(dir, "node.exe")))
30685
- throw new Error("nvm install " + version2 + " failed: " + out.trim().split("\n").slice(-2).join(" "));
30780
+ if (!exists(path56.join(dir, "node.exe"))) {
30781
+ const tail = out.trim().split(/\r?\n/).filter(Boolean).slice(-3).join(" ");
30782
+ 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";
30783
+ throw new Error(
30784
+ "nvm install " + version2 + " did not leave " + path56.join(dir, "node.exe") + " (" + why + ")" + (tail ? ". nvm printed: " + tail : "")
30785
+ );
30786
+ }
30686
30787
  };
30687
30788
  var activate = async (version2) => {
30688
30789
  await nvm(["use", version2]);
30689
- if (exists(path55.join(NVM_SYMLINK, "node.exe"))) return;
30690
- fs42.rmSync(NVM_SYMLINK, { recursive: true, force: true });
30691
- fs42.symlinkSync(path55.join(NVM_HOME, "v" + version2), NVM_SYMLINK, "junction");
30790
+ if (exists(path56.join(NVM_SYMLINK, "node.exe"))) return;
30791
+ fs43.rmSync(NVM_SYMLINK, { recursive: true, force: true });
30792
+ fs43.symlinkSync(path56.join(NVM_HOME, "v" + version2), NVM_SYMLINK, "junction");
30692
30793
  };
30693
30794
  async function setupNode(env, versions, config2) {
30694
30795
  if (dryRun) {
@@ -30696,8 +30797,8 @@ async function setupNode(env, versions, config2) {
30696
30797
  return;
30697
30798
  }
30698
30799
  await ensureNvm();
30699
- fs42.writeFileSync(
30700
- path55.join(NVM_HOME, "settings.txt"),
30800
+ fs43.writeFileSync(
30801
+ path56.join(NVM_HOME, "settings.txt"),
30701
30802
  [
30702
30803
  "root: " + NVM_HOME,
30703
30804
  "path: " + NVM_SYMLINK,
@@ -30724,7 +30825,7 @@ async function setupNode(env, versions, config2) {
30724
30825
  }
30725
30826
  }
30726
30827
  Object.assign(env.vars, { NVM_HOME, NVM_SYMLINK });
30727
- if (duringSession()) env.prepend.push(path55.join(NVM_HOME, "v" + main), NVM_HOME, NVM_SYMLINK);
30828
+ if (duringSession()) env.prepend.push(path56.join(NVM_HOME, "v" + main), NVM_HOME, NVM_SYMLINK);
30728
30829
  else {
30729
30830
  await activate(main);
30730
30831
  env.prepend.push(NVM_HOME, NVM_SYMLINK);
@@ -30733,13 +30834,13 @@ async function setupNode(env, versions, config2) {
30733
30834
  await packageManagers(env, config2, main);
30734
30835
  }
30735
30836
  var packageManagers = async (env, config2, version2) => {
30736
- const dir = path55.join(NVM_HOME, "v" + version2);
30737
- const nodeEnv = { ...process.env, PATH: dir + path55.delimiter + (process.env.PATH ?? "") };
30738
- const npm = (args) => execAsync(path55.join(dir, "node.exe"), [path55.join(dir, "node_modules", "npm", "bin", "npm-cli.js"), ...args], {
30837
+ const dir = path56.join(NVM_HOME, "v" + version2);
30838
+ const nodeEnv = { ...process.env, PATH: dir + path56.delimiter + (process.env.PATH ?? "") };
30839
+ const npm = (args) => execAsync(path56.join(dir, "node.exe"), [path56.join(dir, "node_modules", "npm", "bin", "npm-cli.js"), ...args], {
30739
30840
  env: nodeEnv,
30740
30841
  stdio: "ignore"
30741
30842
  });
30742
- const corepackJs = path55.join(dir, "node_modules", "corepack", "dist", "corepack.js");
30843
+ const corepackJs = path56.join(dir, "node_modules", "corepack", "dist", "corepack.js");
30743
30844
  const extra = config2.corepack && !exists(corepackJs) ? ["corepack"] : [];
30744
30845
  await installOnce(
30745
30846
  env,
@@ -30760,7 +30861,7 @@ var packageManagers = async (env, config2, version2) => {
30760
30861
  }
30761
30862
  try {
30762
30863
  await execAsync(
30763
- path55.join(dir, "node.exe"),
30864
+ path56.join(dir, "node.exe"),
30764
30865
  [corepackJs, "enable", "--install-directory", mkdirp(tool("bin")), "pnpm", "yarn"],
30765
30866
  { env: nodeEnv, stdio: "ignore" }
30766
30867
  );
@@ -30785,8 +30886,8 @@ async function setupPwsh(env, refresh = false) {
30785
30886
  }
30786
30887
 
30787
30888
  // src/guest/toolchains/languages/python.ts
30788
- import fs43 from "node:fs";
30789
- import path56 from "node:path";
30889
+ import fs44 from "node:fs";
30890
+ import path57 from "node:path";
30790
30891
  var installPython = async (pkg, spec) => {
30791
30892
  const version2 = await resolveCached(pkg + ":" + spec, async () => {
30792
30893
  const { versions } = await fetchJson(
@@ -30795,7 +30896,7 @@ var installPython = async (pkg, spec) => {
30795
30896
  return pickPackageVersion(versions, spec) ?? Promise.reject(new Error("No " + pkg + ' release matches "' + spec + '"'));
30796
30897
  });
30797
30898
  const dir = tool("python", pkg + "-" + version2);
30798
- const exe = path56.join(dir, "python.exe");
30899
+ const exe = path57.join(dir, "python.exe");
30799
30900
  if (!exists(exe)) {
30800
30901
  log("Downloading Python " + version2 + (pkg === "python2" ? " (Python 2, " : " (") + "~30 MB once) ...");
30801
30902
  await downloader.archive(
@@ -30804,32 +30905,32 @@ var installPython = async (pkg, spec) => {
30804
30905
  { locate: "python.exe", fileName: pkg + "." + version2 + ".zip" }
30805
30906
  );
30806
30907
  }
30807
- if (!exists(path56.join(dir, "Scripts", "pip.exe")) && !exists(path56.join(dir, "Scripts", "pip2.exe")))
30908
+ if (!exists(path57.join(dir, "Scripts", "pip.exe")) && !exists(path57.join(dir, "Scripts", "pip2.exe")))
30808
30909
  await execAsync(exe, ["-m", "ensurepip", "--default-pip"], { stdio: "ignore" });
30809
30910
  return dir;
30810
30911
  };
30811
- var shimDir = (dir) => duringSession() ? tool("shims", path56.basename(dir)) : tool("shims");
30912
+ var shimDir = (dir) => duringSession() ? tool("shims", path57.basename(dir)) : tool("shims");
30812
30913
  var shim = (folder, name, program, args = []) => {
30813
30914
  const fixed = [program, ...args];
30814
- fs43.writeFileSync(
30815
- path56.join(mkdirp(folder), name + ".cmd"),
30915
+ fs44.writeFileSync(
30916
+ path57.join(mkdirp(folder), name + ".cmd"),
30816
30917
  "@echo off\r\n" + fixed.map((a) => '"' + a + '"').join(" ") + " %*\r\n"
30817
30918
  );
30818
30919
  const sh = fixed.map((a) => "'" + a.replace(/\\/g, "/").replace(/'/g, "'\\''") + "'").join(" ");
30819
- fs43.writeFileSync(path56.join(folder, name), "#!/bin/sh\nexec " + sh + ' "$@"\n');
30920
+ fs44.writeFileSync(path57.join(folder, name), "#!/bin/sh\nexec " + sh + ' "$@"\n');
30820
30921
  };
30821
30922
  var shimPair = (folder, version2, dir) => {
30822
- const python = path56.join(dir, "python.exe");
30923
+ const python = path57.join(dir, "python.exe");
30823
30924
  shim(folder, "python" + version2, python);
30824
30925
  shim(folder, "pip" + version2, python, ["-m", "pip"]);
30825
30926
  };
30826
30927
  var pyLauncher = (folder, py3, py2) => {
30827
- const script = path56.join(mkdirp(folder), "py-launcher.py");
30828
- fs43.writeFileSync(
30928
+ const script = path57.join(mkdirp(folder), "py-launcher.py");
30929
+ fs44.writeFileSync(
30829
30930
  script,
30830
30931
  [
30831
30932
  "import subprocess, sys",
30832
- "PY3, PY2 = " + JSON.stringify(path56.join(py3, "python.exe")) + ", " + JSON.stringify(py2 ? path56.join(py2, "python.exe") : null),
30933
+ "PY3, PY2 = " + JSON.stringify(path57.join(py3, "python.exe")) + ", " + JSON.stringify(py2 ? path57.join(py2, "python.exe") : null),
30833
30934
  "args = sys.argv[1:]",
30834
30935
  "exe = PY3",
30835
30936
  "if args and args[0].startswith('-2'):",
@@ -30841,7 +30942,7 @@ var pyLauncher = (folder, py3, py2) => {
30841
30942
  ""
30842
30943
  ].join("\n")
30843
30944
  );
30844
- shim(folder, "py", path56.join(py3, "python.exe"), [script]);
30945
+ shim(folder, "py", path57.join(py3, "python.exe"), [script]);
30845
30946
  };
30846
30947
  async function setupPython(env, config2, versions) {
30847
30948
  if (dryRun) {
@@ -30851,10 +30952,10 @@ async function setupPython(env, config2, versions) {
30851
30952
  const py3 = await installPython("python", versions.python.spec);
30852
30953
  const shims = shimDir(py3);
30853
30954
  shimPair(shims, "3", py3);
30854
- env.prepend.push(py3, mkdirp(path56.join(py3, "Scripts")), shims);
30955
+ env.prepend.push(py3, mkdirp(path57.join(py3, "Scripts")), shims);
30855
30956
  env.vars.PYTHONIOENCODING = "utf-8";
30856
30957
  env.summary.push(
30857
- "python: " + path56.basename(py3).replace("python-", "") + " (from " + versions.python.source + "; py works too)"
30958
+ "python: " + path57.basename(py3).replace("python-", "") + " (from " + versions.python.source + "; py works too)"
30858
30959
  );
30859
30960
  if (!config2.python2) {
30860
30961
  pyLauncher(shims, py3, null);
@@ -30863,16 +30964,16 @@ async function setupPython(env, config2, versions) {
30863
30964
  const py2 = await installPython("python2", "2.7");
30864
30965
  shimPair(shims, "2", py2);
30865
30966
  pyLauncher(shims, py3, py2);
30866
- env.summary.push("python2: " + path56.basename(py2).replace("python2-", ""));
30967
+ env.summary.push("python2: " + path57.basename(py2).replace("python2-", ""));
30867
30968
  }
30868
30969
 
30869
30970
  // src/guest/toolchains/languages/php.ts
30870
- import fs45 from "node:fs";
30871
- import path58 from "node:path";
30971
+ import fs46 from "node:fs";
30972
+ import path59 from "node:path";
30872
30973
 
30873
30974
  // src/guest/toolchains/native/vcruntime.ts
30874
- import fs44 from "node:fs";
30875
- import path57 from "node:path";
30975
+ import fs45 from "node:fs";
30976
+ import path58 from "node:path";
30876
30977
  var VC_REDIST = "https://aka.ms/vs/17/release/vc_redist.x64.exe";
30877
30978
  var MICROSOFT_SIGNER = "CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US";
30878
30979
  var OK_EXIT_CODES = [0, 1638, 3010];
@@ -30882,8 +30983,8 @@ async function setupVcRuntime(env, summary = true) {
30882
30983
  log("(dry run) would install the Visual C++ runtime");
30883
30984
  return false;
30884
30985
  }
30885
- const system322 = path57.join(process.env.WINDIR ?? "C:\\Windows", "System32");
30886
- const missing = !exists(path57.join(system322, "vcruntime140.dll")) || !exists(path57.join(system322, "msvcp140.dll"));
30986
+ const system322 = path58.join(process.env.WINDIR ?? "C:\\Windows", "System32");
30987
+ const missing = !exists(path58.join(system322, "vcruntime140.dll")) || !exists(path58.join(system322, "msvcp140.dll"));
30887
30988
  if (missing) {
30888
30989
  const installer = tool("vcredist", "vc_redist.x64.exe");
30889
30990
  if (!exists(installer)) {
@@ -30891,12 +30992,12 @@ async function setupVcRuntime(env, summary = true) {
30891
30992
  await downloadFile(VC_REDIST, installer);
30892
30993
  }
30893
30994
  if (signerOf(installer) !== MICROSOFT_SIGNER) {
30894
- fs44.rmSync(installer, { force: true });
30995
+ fs45.rmSync(installer, { force: true });
30895
30996
  throw new Error("vc_redist.x64.exe is not signed by Microsoft; deleted it (it is downloaded again next boot)");
30896
30997
  }
30897
30998
  log("Installing the Visual C++ runtime ...");
30898
30999
  const code = await spawnAsync(installer, ["/install", "/quiet", "/norestart"]);
30899
- if (!OK_EXIT_CODES.includes(code ?? -1) || !exists(path57.join(system322, "vcruntime140.dll")))
31000
+ if (!OK_EXIT_CODES.includes(code ?? -1) || !exists(path58.join(system322, "vcruntime140.dll")))
30900
31001
  throw new Error("the Visual C++ runtime installer failed (exit " + code + ")");
30901
31002
  }
30902
31003
  if (summary) env.summary.push("vc++ runtime: installed");
@@ -30934,16 +31035,16 @@ var phpBuild = async (spec) => {
30934
31035
  return { version: release.version, ...build.zip };
30935
31036
  };
30936
31037
  var writePhpIni = (home) => {
30937
- const ini = path58.join(home, "php.ini");
30938
- if (exists(ini) || !exists(path58.join(home, "php.ini-development"))) return;
30939
- let text = fs45.readFileSync(path58.join(home, "php.ini-development"), "utf8").replace(/^;\s*extension_dir\s*=\s*"ext"/m, 'extension_dir = "' + path58.join(home, "ext") + '"');
30940
- for (const ext of PHP_EXTENSIONS.filter((e) => exists(path58.join(home, "ext", "php_" + e + ".dll"))))
31038
+ const ini = path59.join(home, "php.ini");
31039
+ if (exists(ini) || !exists(path59.join(home, "php.ini-development"))) return;
31040
+ let text = fs46.readFileSync(path59.join(home, "php.ini-development"), "utf8").replace(/^;\s*extension_dir\s*=\s*"ext"/m, 'extension_dir = "' + path59.join(home, "ext") + '"');
31041
+ for (const ext of PHP_EXTENSIONS.filter((e) => exists(path59.join(home, "ext", "php_" + e + ".dll"))))
30941
31042
  text = text.replace(new RegExp("^;(extension=" + ext + ")\\s*$", "m"), "$1");
30942
- fs45.writeFileSync(ini + ".tmp", text);
30943
- fs45.renameSync(ini + ".tmp", ini);
31043
+ fs46.writeFileSync(ini + ".tmp", text);
31044
+ fs46.renameSync(ini + ".tmp", ini);
30944
31045
  };
30945
31046
  var shim2 = (env, name, command) => {
30946
- fs45.writeFileSync(path58.join(mkdirp(tool("shims")), name + ".cmd"), "@echo off\r\n" + command + " %*\r\n");
31047
+ fs46.writeFileSync(path59.join(mkdirp(tool("shims")), name + ".cmd"), "@echo off\r\n" + command + " %*\r\n");
30947
31048
  env.prepend.push(tool("shims"));
30948
31049
  };
30949
31050
  var setupComposer = async (env, php) => {
@@ -30955,7 +31056,7 @@ var setupComposer = async (env, php) => {
30955
31056
  }
30956
31057
  const composerHome = tool("composer-home");
30957
31058
  env.vars.COMPOSER_HOME = composerHome;
30958
- env.prepend.push(path58.join(composerHome, "vendor", "bin"));
31059
+ env.prepend.push(path59.join(composerHome, "vendor", "bin"));
30959
31060
  shim2(env, "composer", '"' + php + '" "' + phar + '"');
30960
31061
  env.summary.push(
30961
31062
  "composer: " + (/\d+\.\d+\.\d+/.exec(execOutput(php, [phar, "--version", "--no-ansi"]))?.[0] ?? "installed")
@@ -30970,7 +31071,7 @@ async function setupPhp(env, config2) {
30970
31071
  await setupVcRuntime(env, false);
30971
31072
  const version2 = await resolveCached("php:" + wantedSpec.spec, async () => (await phpBuild(wantedSpec.spec)).version);
30972
31073
  const home = tool("php", version2);
30973
- if (!exists(path58.join(home, "php.exe"))) {
31074
+ if (!exists(path59.join(home, "php.exe"))) {
30974
31075
  const build = await phpBuild(version2);
30975
31076
  log("Downloading PHP " + version2 + " (~30 MB once) ...");
30976
31077
  await downloader.archive("https://windows.php.net/downloads/releases/" + build.path, home, {
@@ -30982,11 +31083,11 @@ async function setupPhp(env, config2) {
30982
31083
  writePhpIni(home);
30983
31084
  env.prepend.push(home);
30984
31085
  env.summary.push("php: " + version2 + " (from " + wantedSpec.source + ")");
30985
- if (config2.composer) await setupComposer(env, path58.join(home, "php.exe"));
31086
+ if (config2.composer) await setupComposer(env, path59.join(home, "php.exe"));
30986
31087
  }
30987
31088
 
30988
31089
  // src/guest/toolchains/languages/ruby.ts
30989
- import path59 from "node:path";
31090
+ import path60 from "node:path";
30990
31091
  var RUBY_ASSET = /^rubyinstaller-(\d+\.\d+\.\d+)-(\d+)-x64\.7z$/;
30991
31092
  var buildNumber = (asset) => Number(RUBY_ASSET.exec(asset.name)?.[2] ?? 0);
30992
31093
  var rubyBuilds = async () => {
@@ -31014,7 +31115,7 @@ async function setupRuby(env, config2) {
31014
31115
  async () => pickPackageVersion([...(await rubyBuilds()).keys()], wantedSpec.spec) ?? Promise.reject(new Error('No RubyInstaller build matches "' + wantedSpec.spec + '"'))
31015
31116
  );
31016
31117
  const home = tool("ruby", version2);
31017
- if (!exists(path59.join(home, "bin", "ruby.exe"))) {
31118
+ if (!exists(path60.join(home, "bin", "ruby.exe"))) {
31018
31119
  const asset = (await rubyBuilds()).get(version2);
31019
31120
  if (!asset) throw new Error("RubyInstaller " + version2 + " is no longer published");
31020
31121
  log("Downloading Ruby " + version2 + " (~100 MB once) ...");
@@ -31027,11 +31128,11 @@ async function setupRuby(env, config2) {
31027
31128
  }
31028
31129
  const gems = tool("ruby-gems", version2.split(".").slice(0, 2).join("."));
31029
31130
  Object.assign(env.vars, { GEM_HOME: gems, BUNDLE_USER_HOME: tool("bundle-home") });
31030
- env.prepend.push(path59.join(home, "bin"), path59.join(gems, "bin"));
31131
+ env.prepend.push(path60.join(home, "bin"), path60.join(gems, "bin"));
31031
31132
  env.summary.push(
31032
- "ruby: " + versionOf(path59.join(home, "bin", "ruby.exe")) + " (from " + wantedSpec.source + "; gems with C extensions need MSYS2, not included)"
31133
+ "ruby: " + versionOf(path60.join(home, "bin", "ruby.exe")) + " (from " + wantedSpec.source + "; gems with C extensions need MSYS2, not included)"
31033
31134
  );
31034
- const gem = path59.join(home, "bin", "gem.cmd");
31135
+ const gem = path60.join(home, "bin", "gem.cmd");
31035
31136
  await installOnce(
31036
31137
  env,
31037
31138
  "gem@" + version2,
@@ -31043,9 +31144,9 @@ async function setupRuby(env, config2) {
31043
31144
  }
31044
31145
 
31045
31146
  // src/guest/toolchains/tools/vscode.ts
31046
- import fs46 from "node:fs";
31147
+ import fs47 from "node:fs";
31047
31148
  import os7 from "node:os";
31048
- import path60 from "node:path";
31149
+ import path61 from "node:path";
31049
31150
 
31050
31151
  // node_modules/jsonc-parser/lib/esm/impl/scanner.js
31051
31152
  var CharacterCodes;
@@ -31225,14 +31326,14 @@ var ParseErrorCode;
31225
31326
  var VERSION_MARKER = ".agent-sandbox-version";
31226
31327
  var desktopShortcut = (exe) => {
31227
31328
  if (!isWin) return;
31228
- const link = path60.join(os7.homedir(), "Desktop", "Visual Studio Code.lnk");
31329
+ const link = path61.join(os7.homedir(), "Desktop", "Visual Studio Code.lnk");
31229
31330
  runScriptWithJson("new-shortcuts.ps1", "ListFile", [
31230
31331
  { link, target: exe, arguments: '"' + (process.env.AGENT_WORKSPACE ?? "") + '"' }
31231
31332
  ]);
31232
31333
  };
31233
31334
  async function setupVscode(env, refresh) {
31234
31335
  const root = tool("vscode");
31235
- const exe = path60.join(root, "Code.exe");
31336
+ const exe = path61.join(root, "Code.exe");
31236
31337
  if (dryRun) {
31237
31338
  log("(dry run) would provision VS Code");
31238
31339
  return;
@@ -31242,11 +31343,11 @@ async function setupVscode(env, refresh) {
31242
31343
  "https://update.code.visualstudio.com/api/update/win32-" + (arch === "arm64" ? "arm64" : "x64") + "-archive/stable/latest"
31243
31344
  );
31244
31345
  log("Downloading VS Code " + release.productVersion + " (~150 MB once) ...");
31245
- const keep = path60.join(root, "data");
31346
+ const keep = path61.join(root, "data");
31246
31347
  const parked = root + "-data";
31247
31348
  if (exists(keep)) {
31248
- fs46.rmSync(parked, { recursive: true, force: true });
31249
- fs46.renameSync(keep, parked);
31349
+ fs47.rmSync(parked, { recursive: true, force: true });
31350
+ fs47.renameSync(keep, parked);
31250
31351
  }
31251
31352
  try {
31252
31353
  await downloader.archive(release.url, root, {
@@ -31254,26 +31355,26 @@ async function setupVscode(env, refresh) {
31254
31355
  locate: "Code.exe",
31255
31356
  fileName: "vscode.zip"
31256
31357
  });
31257
- fs46.writeFileSync(path60.join(root, VERSION_MARKER), release.productVersion);
31358
+ fs47.writeFileSync(path61.join(root, VERSION_MARKER), release.productVersion);
31258
31359
  } finally {
31259
31360
  if (exists(parked)) {
31260
31361
  mkdirp(root);
31261
- fs46.rmSync(keep, { recursive: true, force: true });
31262
- fs46.renameSync(parked, keep);
31362
+ fs47.rmSync(keep, { recursive: true, force: true });
31363
+ fs47.renameSync(parked, keep);
31263
31364
  }
31264
31365
  }
31265
31366
  }
31266
- mkdirp(path60.join(root, "data"));
31267
- env.prepend.push(path60.join(root, "bin"));
31367
+ mkdirp(path61.join(root, "data"));
31368
+ env.prepend.push(path61.join(root, "bin"));
31268
31369
  desktopShortcut(exe);
31269
- const version2 = exists(path60.join(root, VERSION_MARKER)) ? fs46.readFileSync(path60.join(root, VERSION_MARKER), "utf8").trim() : "installed";
31370
+ const version2 = exists(path61.join(root, VERSION_MARKER)) ? fs47.readFileSync(path61.join(root, VERSION_MARKER), "utf8").trim() : "installed";
31270
31371
  env.summary.push("vscode: " + version2 + " (portable; run code . or use the desktop shortcut)");
31271
31372
  }
31272
31373
 
31273
31374
  // src/guest/toolchains/native/rust-extras.ts
31274
- import fs47 from "node:fs";
31375
+ import fs48 from "node:fs";
31275
31376
  import os8 from "node:os";
31276
- import path61 from "node:path";
31377
+ import path62 from "node:path";
31277
31378
 
31278
31379
  // src/shared/memory/policy.ts
31279
31380
  var GUEST_THRESHOLDS = {
@@ -31298,26 +31399,29 @@ function cargoJobs(cpus, memoryGb, sessions2) {
31298
31399
  const jobs = Math.min(byCpu, byMemory);
31299
31400
  return Math.max(1, Math.min(jobs, Math.floor(8 / Math.max(1, sessions2))));
31300
31401
  }
31402
+ function maxCompilers(cpus, profile) {
31403
+ return profile === "gentle" ? Math.max(2, Math.floor(cpus / 4)) : null;
31404
+ }
31301
31405
 
31302
31406
  // src/guest/toolchains/native/rust-extras.ts
31303
31407
  var cargoTarget = (targetDir) => {
31304
31408
  if (targetDir === "shared" || targetDir === "separate") return null;
31305
- if (targetDir === "local") return path61.join(localDir, "cargo-target");
31409
+ if (targetDir === "local") return path62.join(localDir, "cargo-target");
31306
31410
  return targetDir;
31307
31411
  };
31308
31412
  function cargoShim(env, rust) {
31309
- const real = path61.join(tool("rust", "cargo", "bin"), "cargo.exe");
31413
+ const real = path62.join(tool("rust", "cargo", "bin"), "cargo.exe");
31310
31414
  if (rust.targetDir !== "separate" || !exists(real)) return;
31311
31415
  const dir = mkdirp(tool("shims", "cargo"));
31312
- fs47.copyFileSync(ensureCompiled("cargoshim"), path61.join(dir, "cargo.exe"));
31416
+ fs48.copyFileSync(ensureCompiled("cargoshim"), path62.join(dir, "cargo.exe"));
31313
31417
  env.prepend.unshift(dir);
31314
31418
  env.vars.AGENT_REAL_CARGO = real;
31315
31419
  }
31316
31420
  function linkGate(env, rust, host) {
31317
31421
  const gcc = tool("mingw", "mingw64", "bin", "gcc.exe");
31318
31422
  if (!host.endsWith("-pc-windows-gnu") || !exists(gcc)) return;
31319
- const gate = path61.join(mkdirp(tool("shims")), "linkgate.exe");
31320
- fs47.copyFileSync(ensureCompiled("linkgate"), gate);
31423
+ const gate = path62.join(mkdirp(tool("shims")), "linkgate.exe");
31424
+ fs48.copyFileSync(ensureCompiled("linkgate"), gate);
31321
31425
  const memoryGb = os8.totalmem() / 1024 ** 3;
31322
31426
  const slots = rust.linkSlots === "auto" ? Math.max(2, Math.min(4, Math.floor(memoryGb / 8))) : rust.linkSlots;
31323
31427
  env.vars.AGENT_LINK_SLOTS = String(slots);
@@ -31325,18 +31429,18 @@ function linkGate(env, rust, host) {
31325
31429
  env.vars.CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER = gate;
31326
31430
  const rustEnv = { ...process.env, RUSTUP_HOME: tool("rust", "rustup"), CARGO_HOME: tool("rust", "cargo") };
31327
31431
  const sysroot = rust.linker === "lld" ? execOutput(tool("rust", "cargo", "bin", "rustc.exe"), ["--print", "sysroot"], { env: rustEnv }) : "";
31328
- const lld = sysroot ? path61.join(sysroot, "lib", "rustlib", host, "bin", "gcc-ld") : "";
31329
- if (lld && exists(path61.join(lld, "ld.lld.exe"))) env.vars.AGENT_LLD_DIR = lld;
31432
+ const lld = sysroot ? path62.join(sysroot, "lib", "rustlib", host, "bin", "gcc-ld") : "";
31433
+ if (lld && exists(path62.join(lld, "ld.lld.exe"))) env.vars.AGENT_LLD_DIR = lld;
31330
31434
  env.summary.push(
31331
31435
  "rust linking: " + (env.vars.AGENT_LLD_DIR ? "lld" : "GNU ld") + ", at most " + env.vars.AGENT_LINK_SLOTS + " at once"
31332
31436
  );
31333
31437
  }
31334
31438
  function cargoDefaults(host) {
31335
31439
  const file3 = tool("rust", "cargo", "config.toml");
31336
- if (exists(file3) || !exists(path61.dirname(file3))) return;
31440
+ if (exists(file3) || !exists(path62.dirname(file3))) return;
31337
31441
  const jobs = cargoJobs(os8.cpus().length, os8.totalmem() / 1024 ** 3, 1);
31338
31442
  const gnu = host.endsWith("-gnu");
31339
- fs47.writeFileSync(
31443
+ fs48.writeFileSync(
31340
31444
  file3,
31341
31445
  [
31342
31446
  "# Written by windows-development-sandbox once; edit freely, it is never overwritten.",
@@ -31351,7 +31455,7 @@ function rustCaches(rust) {
31351
31455
  const target = cargoTarget(rust.targetDir);
31352
31456
  return {
31353
31457
  ...target ? { CARGO_TARGET_DIR: target } : {},
31354
- ...process.env.SCCACHE_DIR ? {} : { SCCACHE_DIR: path61.join(dataDir, "cache", "sccache") }
31458
+ ...process.env.SCCACHE_DIR ? {} : { SCCACHE_DIR: path62.join(dataDir, "cache", "sccache") }
31355
31459
  };
31356
31460
  }
31357
31461
  function rustHost(config2) {
@@ -31655,21 +31759,21 @@ function cmdSet(env, names) {
31655
31759
  return names.filter((n) => env[n] !== void 0 && !/[\r\n]/.test(String(env[n]))).map((n) => '@set "' + n + "=" + String(env[n]).replace(/%/g, "%%") + '"');
31656
31760
  }
31657
31761
  function writeShell(spec, env, names) {
31658
- const dir = mkdirp(path62.join(localDir, "projects", spec.name));
31659
- fs48.writeFileSync(path62.join(dir, "env.cmd"), [...cmdSet(env, [...names, "PATH"]), ""].join("\r\n"));
31660
- fs48.writeFileSync(
31661
- path62.join(dir, "shell.cmd"),
31662
- ['@call "' + path62.join(dir, "env.cmd") + '"', '@cd /d "' + spec.workspace + '"', "@title " + spec.name, ""].join(
31762
+ const dir = mkdirp(path63.join(localDir, "projects", spec.name));
31763
+ fs49.writeFileSync(path63.join(dir, "env.cmd"), [...cmdSet(env, [...names, "PATH"]), ""].join("\r\n"));
31764
+ fs49.writeFileSync(
31765
+ path63.join(dir, "shell.cmd"),
31766
+ ['@call "' + path63.join(dir, "env.cmd") + '"', '@cd /d "' + spec.workspace + '"', "@title " + spec.name, ""].join(
31663
31767
  "\r\n"
31664
31768
  )
31665
31769
  );
31666
- const bin = mkdirp(path62.join(localDir, "bin"));
31667
- fs48.writeFileSync(
31668
- path62.join(bin, "sbx-shell.cmd"),
31770
+ const bin = mkdirp(path63.join(localDir, "bin"));
31771
+ fs49.writeFileSync(
31772
+ path63.join(bin, "sbx-shell.cmd"),
31669
31773
  [
31670
- '@if "%~1"=="" (echo Usage: sbx-shell ^<project^> ^(a terminal in that project with its tools^) & dir /b "' + path62.join(localDir, "projects") + '" & exit /b 2)',
31671
- '@if not exist "' + path62.join(localDir, "projects") + '\\%~1\\shell.cmd" (echo No project %~1 in this sandbox. & exit /b 2)',
31672
- '@cmd /k ""' + path62.join(localDir, "projects") + '\\%~1\\shell.cmd""',
31774
+ '@if "%~1"=="" (echo Usage: sbx-shell ^<project^> ^(a terminal in that project with its tools^) & dir /b "' + path63.join(localDir, "projects") + '" & exit /b 2)',
31775
+ '@if not exist "' + path63.join(localDir, "projects") + '\\%~1\\shell.cmd" (echo No project %~1 in this sandbox. & exit /b 2)',
31776
+ '@cmd /k ""' + path63.join(localDir, "projects") + '\\%~1\\shell.cmd""',
31673
31777
  ""
31674
31778
  ].join("\r\n")
31675
31779
  );
@@ -31722,10 +31826,10 @@ async function setUp(spec, say) {
31722
31826
  }
31723
31827
  )
31724
31828
  );
31725
- tools.prepend.push(path62.join(localDir, "bin"));
31829
+ tools.prepend.push(path63.join(localDir, "bin"));
31726
31830
  const env = agentEnv(tools, { workspace: spec.workspace, project: spec.name, base });
31727
- const specFile = path62.join(mkdirp(path62.join(localDir, "projects", spec.name)), "project.json");
31728
- fs48.writeFileSync(specFile, JSON.stringify(spec));
31831
+ const specFile = path63.join(mkdirp(path63.join(localDir, "projects", spec.name)), "project.json");
31832
+ fs49.writeFileSync(specFile, JSON.stringify(spec));
31729
31833
  env.AGENT_PROJECT_FILE = specFile;
31730
31834
  addMachineEnvironment(tools.vars, [...tools.prepend, ...tools.append], true);
31731
31835
  try {
@@ -31842,7 +31946,7 @@ function execCommand(req) {
31842
31946
  }
31843
31947
 
31844
31948
  // src/guest/daemon/sessions.ts
31845
- import path67 from "node:path";
31949
+ import path68 from "node:path";
31846
31950
  import crypto4 from "node:crypto";
31847
31951
  import os11 from "node:os";
31848
31952
  import { spawn as spawn7 } from "node:child_process";
@@ -31919,7 +32023,7 @@ async function sendControl(endpoint, type) {
31919
32023
  var MAX_CLIPBOARD_STRING = 1024 * 1024;
31920
32024
 
31921
32025
  // src/guest/sessions/cmdline.ts
31922
- import path63 from "node:path";
32026
+ import path64 from "node:path";
31923
32027
  var quoted = (arg) => '"' + arg.replace(/(\\*)"/g, '$1$1\\"').replace(/(\\+)$/, "$1$1") + '"';
31924
32028
  function quoteArg(arg) {
31925
32029
  return arg !== "" && !/[\s"]/.test(arg) ? arg : quoted(arg);
@@ -31933,12 +32037,12 @@ function cmdArgs(args) {
31933
32037
  }).join("");
31934
32038
  }
31935
32039
  function commandLine(file3, args) {
31936
- return path63.win32.basename(file3).toLowerCase() === "cmd.exe" ? [quoteArg(file3), cmdArgs(args)].filter(Boolean).join(" ") : [file3, ...args].map(quoteArg).join(" ");
32040
+ return path64.win32.basename(file3).toLowerCase() === "cmd.exe" ? [quoteArg(file3), cmdArgs(args)].filter(Boolean).join(" ") : [file3, ...args].map(quoteArg).join(" ");
31937
32041
  }
31938
32042
 
31939
32043
  // src/guest/sessions/pty-host.ts
31940
- import fs49 from "node:fs";
31941
- import path64 from "node:path";
32044
+ import fs50 from "node:fs";
32045
+ import path65 from "node:path";
31942
32046
  import { spawn as spawn6 } from "node:child_process";
31943
32047
  function ensurePtyHost() {
31944
32048
  return ensureCompiled("ptyhost");
@@ -31957,18 +32061,18 @@ async function waitForPtyHost(child, port, timeoutMs) {
31957
32061
  throw new Error("the session host did not start listening on port " + port);
31958
32062
  }
31959
32063
  function ptyHostLog(id) {
31960
- return path64.join(logsDir, "ptyhost-" + id + ".log");
32064
+ return path65.join(logsDir, "ptyhost-" + id + ".log");
31961
32065
  }
31962
32066
  function ptyHostLogTail(id, lines = 12) {
31963
32067
  try {
31964
- return fs49.readFileSync(ptyHostLog(id), "utf8").trim().split(/\r?\n/).slice(-lines).join("\n");
32068
+ return fs50.readFileSync(ptyHostLog(id), "utf8").trim().split(/\r?\n/).slice(-lines).join("\n");
31965
32069
  } catch {
31966
32070
  return "";
31967
32071
  }
31968
32072
  }
31969
32073
  var conptyDll = () => {
31970
- const dll = path64.join(toolsDir, "conpty", "conpty.dll");
31971
- return session.provisioning.conpty?.enabled !== false && fs49.existsSync(dll) && fs49.existsSync(path64.join(toolsDir, "conpty", "OpenConsole.exe")) ? dll : null;
32074
+ const dll = path65.join(toolsDir, "conpty", "conpty.dll");
32075
+ return session.provisioning.conpty?.enabled !== false && fs50.existsSync(dll) && fs50.existsSync(path65.join(toolsDir, "conpty", "OpenConsole.exe")) ? dll : null;
31972
32076
  };
31973
32077
  function startPtyHost(o) {
31974
32078
  const env = { ...o.env, PTYHOST_BIND: o.remote ? "any" : "loopback" };
@@ -31983,8 +32087,8 @@ function startPtyHost(o) {
31983
32087
  }
31984
32088
 
31985
32089
  // src/guest/agents/agent-installer.ts
31986
- import fs50 from "node:fs";
31987
- import path65 from "node:path";
32090
+ import fs51 from "node:fs";
32091
+ import path66 from "node:path";
31988
32092
 
31989
32093
  // src/guest/agents/profile-links.ts
31990
32094
  var profileRoot = () => process.env.USERPROFILE ?? "";
@@ -32010,7 +32114,7 @@ var agentPaths2 = (name, harness) => agentPaths(toolsDir, name, harness);
32010
32114
  async function installViaNpm(name, harness, dir, env) {
32011
32115
  if (!harness.npmPackage)
32012
32116
  throw new Error("No npmPackage configured for " + name + " and no host executable was available.");
32013
- const npmCli = path65.join(path65.dirname(process.execPath), "node_modules", "npm", "bin", "npm-cli.js");
32117
+ const npmCli = path66.join(path66.dirname(process.execPath), "node_modules", "npm", "bin", "npm-cli.js");
32014
32118
  const args = [npmCli, "install", "--global", "--prefix", dir, harness.npmPackage, "--no-fund", "--no-audit"];
32015
32119
  log("Installing " + harness.npmPackage + " (this can take a minute)...");
32016
32120
  if (dryRun) {
@@ -32021,7 +32125,7 @@ async function installViaNpm(name, harness, dir, env) {
32021
32125
  await execAsync(process.execPath, args, { env });
32022
32126
  }
32023
32127
  async function installViaUv(name, harness, dir, env) {
32024
- const uv = path65.join(toolsDir, "uv", "uv.exe");
32128
+ const uv = path66.join(toolsDir, "uv", "uv.exe");
32025
32129
  log("Installing " + harness.uvPackage + " with uv (this can take a minute)...");
32026
32130
  if (dryRun) {
32027
32131
  log("(dry run) uv tool install " + harness.uvPackage);
@@ -32036,8 +32140,8 @@ async function installViaUv(name, harness, dir, env) {
32036
32140
  });
32037
32141
  }
32038
32142
  function putOnPath(dir, env) {
32039
- const parts2 = (env.PATH ?? "").split(path65.delimiter);
32040
- if (!parts2.some((p) => p.toLowerCase() === dir.toLowerCase())) env.PATH = [...parts2, dir].join(path65.delimiter);
32143
+ const parts2 = (env.PATH ?? "").split(path66.delimiter);
32144
+ if (!parts2.some((p) => p.toLowerCase() === dir.toLowerCase())) env.PATH = [...parts2, dir].join(path66.delimiter);
32041
32145
  addMachineEnvironment({}, [dir], true);
32042
32146
  }
32043
32147
  var AgentInstaller = class {
@@ -32078,9 +32182,9 @@ var AgentInstaller = class {
32078
32182
  }
32079
32183
  mkdirp(p.dir);
32080
32184
  if (this.sourceOf(name, harness) === "host") {
32081
- const source = path65.join(hostToolsDir, "agents", name, harness.hostExecutable);
32185
+ const source = path66.join(hostToolsDir, "agents", name, harness.hostExecutable);
32082
32186
  if (exists(source) && p.exe) {
32083
- fs50.copyFileSync(source, p.exe);
32187
+ fs51.copyFileSync(source, p.exe);
32084
32188
  log("Copied " + name + " from this PC: " + source);
32085
32189
  return;
32086
32190
  }
@@ -32101,22 +32205,22 @@ function guestAddresses() {
32101
32205
  }
32102
32206
 
32103
32207
  // src/guest/sessions/conversation.ts
32104
- import fs51 from "node:fs";
32105
- import path66 from "node:path";
32208
+ import fs52 from "node:fs";
32209
+ import path67 from "node:path";
32106
32210
  var MAX_FILES = 2e3;
32107
32211
  function conversationFiles(claudeDir2, cwd) {
32108
32212
  const names = /* @__PURE__ */ new Set([projectFolderName(cwd), projectFolderName(sandboxFolder(cwd))]);
32109
32213
  return [...names].flatMap((name) => {
32110
- const dir = path66.join(claudeDir2, "projects", name);
32214
+ const dir = path67.join(claudeDir2, "projects", name);
32111
32215
  let entries2;
32112
32216
  try {
32113
- entries2 = fs51.readdirSync(dir);
32217
+ entries2 = fs52.readdirSync(dir);
32114
32218
  } catch {
32115
32219
  return [];
32116
32220
  }
32117
32221
  return entries2.filter((e) => e.endsWith(".jsonl") && isConversationId(e.slice(0, -".jsonl".length))).slice(0, MAX_FILES).flatMap((e) => {
32118
32222
  try {
32119
- return [{ id: e.slice(0, -".jsonl".length), createdMs: fs51.statSync(path66.join(dir, e)).birthtimeMs }];
32223
+ return [{ id: e.slice(0, -".jsonl".length), createdMs: fs52.statSync(path67.join(dir, e)).birthtimeMs }];
32120
32224
  } catch {
32121
32225
  return [];
32122
32226
  }
@@ -32155,8 +32259,8 @@ var IdleShutdown = class {
32155
32259
 
32156
32260
  // src/guest/daemon/sessions.ts
32157
32261
  function terminalTab(id, title, cwd) {
32158
- const view = [process.execPath, path67.join(path67.dirname(process.argv[1]), "view.js"), id];
32159
- const wt = path67.join(toolsDir, "terminal", "wt.exe");
32262
+ const view = [process.execPath, path68.join(path68.dirname(process.argv[1]), "view.js"), id];
32263
+ const wt = path68.join(toolsDir, "terminal", "wt.exe");
32160
32264
  if (exists(wt))
32161
32265
  spawn7(wt, ["-w", "0", "nt", "--title", title, "-d", cwd, ...view], { detached: true, stdio: "ignore" }).unref();
32162
32266
  else spawn7(SYSTEM.cmd(), ["/d", "/c", "start", title, ...view], { detached: true, stdio: "ignore", cwd }).unref();
@@ -32202,7 +32306,7 @@ var launchPtyHost = async (req, remote, env, say, sessions2) => {
32202
32306
  } catch (e) {
32203
32307
  const tail = ptyHostLogTail(req.id);
32204
32308
  throw new Error(
32205
- errMsg(e) + (tail ? ". From its log:\n" + tail : "") + "\nLog: " + path67.join(dataDir, "logs", "ptyhost-" + req.id + ".log")
32309
+ errMsg(e) + (tail ? ". From its log:\n" + tail : "") + "\nLog: " + path68.join(dataDir, "logs", "ptyhost-" + req.id + ".log")
32206
32310
  );
32207
32311
  }
32208
32312
  return { child, port, token };
@@ -32260,7 +32364,7 @@ var SessionManager = class {
32260
32364
  };
32261
32365
  this.starting++;
32262
32366
  if (req.id !== session.launchId && process.env.AGENT_NO_TABS !== "1")
32263
- safely("terminal tab", () => terminalTab(req.id, req.harness + " " + path67.basename(req.cwd), req.cwd));
32367
+ safely("terminal tab", () => terminalTab(req.id, req.harness + " " + path68.basename(req.cwd), req.cwd));
32264
32368
  try {
32265
32369
  const place = await placeFor(req, say);
32266
32370
  const remote = session.networking && session.attach.enabled;
@@ -32450,6 +32554,23 @@ var NEVER2 = /* @__PURE__ */ new Set([
32450
32554
  var key = (name) => name.toLowerCase().replace(/\.exe$/, "");
32451
32555
  var isNeverTouched = (name) => NEVER2.has(key(name));
32452
32556
  var canLower = (name) => !isNeverTouched(name) && (COMPILERS.has(key(name)) || BUILD_TOOLS.has(key(name)));
32557
+ var HEAVY = /* @__PURE__ */ new Set([
32558
+ "rustc",
32559
+ "clippy-driver",
32560
+ "rustdoc",
32561
+ "cc1",
32562
+ "cc1plus",
32563
+ "clang",
32564
+ "clang++",
32565
+ "clang-cl",
32566
+ "cl",
32567
+ "link",
32568
+ "lld",
32569
+ "lld-link",
32570
+ "ld",
32571
+ "ld.lld"
32572
+ ]);
32573
+ var isHeavyCompiler = (name) => !isNeverTouched(name) && HEAVY.has(key(name));
32453
32574
  var canPause = (name) => !isNeverTouched(name) && COMPILERS.has(key(name));
32454
32575
  var INITIAL_STATE = {
32455
32576
  pressure: false,
@@ -32460,12 +32581,13 @@ var INITIAL_STATE = {
32460
32581
  nextPauseAt: 0,
32461
32582
  hostUntil: 0
32462
32583
  };
32584
+ var HOLD_MS = 3e3;
32463
32585
  var PAUSE_MS = 5e3;
32464
32586
  var PAUSE_COOLDOWN_MS = 1e4;
32465
32587
  var IDLE_AFTER = 3;
32466
32588
  var PAUSE_AFTER = 4;
32467
32589
  var PAUSE_MIN_MB = 300;
32468
- function decide(prev, sample, nowMs, thresholds, profile) {
32590
+ function decide(prev, sample, nowMs, thresholds, profile, maxCompilers2 = null) {
32469
32591
  const ramFree = sample.ramAvailMb / Math.max(1, sample.ramTotalMb) * 100;
32470
32592
  const commit = (sample.commitLimitMb - sample.commitAvailMb) / Math.max(1, sample.commitLimitMb) * 100;
32471
32593
  const pcLow = nowMs < prev.hostUntil;
@@ -32523,6 +32645,13 @@ function decide(prev, sample, nowMs, thresholds, profile) {
32523
32645
  nextPauseAt = pausedUntil + PAUSE_COOLDOWN_MS;
32524
32646
  }
32525
32647
  }
32648
+ if (maxCompilers2 !== null) {
32649
+ const heavy = sample.procs.filter(
32650
+ (p) => isHeavyCompiler(p.name) && !(nowMs < pausedUntil && actions.some((a) => a.kind === "pause" && a.pid === p.pid))
32651
+ ).sort((a, b) => a.pid - b.pid);
32652
+ for (const p of heavy.slice(Math.max(1, maxCompilers2)))
32653
+ actions.push({ kind: "hold", pid: p.pid, name: p.name, ms: HOLD_MS });
32654
+ }
32526
32655
  const level = nowMs < pausedUntil ? "suspending" : pressure ? "throttled" : "ok";
32527
32656
  return {
32528
32657
  state: { pressure, calm, samples, lowered, pausedUntil, nextPauseAt, hostUntil: prev.hostUntil },
@@ -32534,8 +32663,9 @@ function decide(prev, sample, nowMs, thresholds, profile) {
32534
32663
  }
32535
32664
 
32536
32665
  // src/guest/governor/governor.ts
32537
- import fs52 from "node:fs";
32538
- import path68 from "node:path";
32666
+ import fs53 from "node:fs";
32667
+ import os12 from "node:os";
32668
+ import path69 from "node:path";
32539
32669
  import { spawn as spawn8 } from "node:child_process";
32540
32670
  import { createInterface } from "node:readline";
32541
32671
  var SampleSchema = external_exports.object({
@@ -32563,6 +32693,7 @@ var GovernorCore = class {
32563
32693
  lastWriteAt = 0;
32564
32694
  pausedName = "";
32565
32695
  pausedPid = 0;
32696
+ held = /* @__PURE__ */ new Set();
32566
32697
  hostPressure(seconds, reason) {
32567
32698
  const until = this.deps.now() + seconds * 1e3;
32568
32699
  if (until > this.state.hostUntil) {
@@ -32577,7 +32708,16 @@ var GovernorCore = class {
32577
32708
  onSample(sample) {
32578
32709
  const nowMs = this.deps.now();
32579
32710
  const before = this.state.pressure;
32580
- const d = decide(this.state, sample, nowMs, GUEST_THRESHOLDS[this.deps.profile], this.deps.profile);
32711
+ const seen = new Set(sample.procs.map((p) => p.pid));
32712
+ for (const pid of this.held) if (!seen.has(pid)) this.held.delete(pid);
32713
+ const d = decide(
32714
+ this.state,
32715
+ sample,
32716
+ nowMs,
32717
+ GUEST_THRESHOLDS[this.deps.profile],
32718
+ this.deps.profile,
32719
+ this.deps.maxCompilers ?? null
32720
+ );
32581
32721
  this.state = d.state;
32582
32722
  for (const action of d.actions) this.apply(action);
32583
32723
  if (d.state.pressure !== before)
@@ -32605,6 +32745,15 @@ var GovernorCore = class {
32605
32745
  }
32606
32746
  apply(action) {
32607
32747
  try {
32748
+ if (action.kind === "hold") {
32749
+ this.deps.port.pause(action.pid, action.ms);
32750
+ if (!this.held.has(action.pid)) {
32751
+ this.held.add(action.pid);
32752
+ this.lastAction = "holding " + action.name + " (" + action.pid + ") until another compiler ends";
32753
+ this.deps.logLine("governor: " + this.lastAction);
32754
+ }
32755
+ return;
32756
+ }
32608
32757
  if (action.kind === "priority") {
32609
32758
  this.deps.port.setPriority(action.pid, action.to);
32610
32759
  this.lastAction = action.name + " (" + action.pid + ") priority " + action.to;
@@ -32660,12 +32809,12 @@ var MemGovProcess = class {
32660
32809
  };
32661
32810
  function appendToMemoryLog(line) {
32662
32811
  try {
32663
- const logs = path68.join(dataDir, "logs");
32664
- const newest = fs52.readdirSync(logs).filter((f) => /^memory-\d{8}-\d{6}\.log$/.test(f)).sort().pop();
32812
+ const logs = path69.join(dataDir, "logs");
32813
+ const newest = fs53.readdirSync(logs).filter((f) => /^memory-\d{8}-\d{6}\.log$/.test(f)).sort().pop();
32665
32814
  if (!newest) return;
32666
32815
  const t = /* @__PURE__ */ new Date();
32667
32816
  const stamp = [t.getHours(), t.getMinutes(), t.getSeconds()].map((n) => String(n).padStart(2, "0")).join(":");
32668
- fs52.appendFileSync(path68.join(logs, newest), stamp + " | " + line + "\r\n");
32817
+ fs53.appendFileSync(path69.join(logs, newest), stamp + " | " + line + "\r\n");
32669
32818
  } catch {
32670
32819
  }
32671
32820
  }
@@ -32683,6 +32832,7 @@ var Governor = class {
32683
32832
  this.core = new GovernorCore({
32684
32833
  port: proc,
32685
32834
  profile,
32835
+ maxCompilers: maxCompilers(os12.cpus().length, profile),
32686
32836
  now: () => Date.now(),
32687
32837
  logLine: appendToMemoryLog,
32688
32838
  saveStatus: (status) => {
@@ -32720,9 +32870,9 @@ var Daemon = class {
32720
32870
  tick() {
32721
32871
  const { valid, invalid } = run.scanRequests();
32722
32872
  for (const file3 of invalid)
32723
- safely("removing an invalid request", () => fs53.rmSync(file3, { recursive: true, force: true }));
32873
+ safely("removing an invalid request", () => fs54.rmSync(file3, { recursive: true, force: true }));
32724
32874
  for (const req of valid) {
32725
- safely("claiming a request", () => fs53.rmSync(run.requestFile(req.id), { force: true }));
32875
+ safely("claiming a request", () => fs54.rmSync(run.requestFile(req.id), { force: true }));
32726
32876
  if (run.readSession(req.id)) continue;
32727
32877
  void Promise.resolve(this.handle(withRequestSecrets(req))).catch(
32728
32878
  (e) => respond(req.id, { ok: false, message: errMsg(e) })