windows-development-sandbox 1.18.4 → 1.20.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 (181) hide show
  1. package/README.md +1 -1
  2. package/config.example.json +9 -0
  3. package/dist/app/features/accounts/accounts.def.d.ts +4 -0
  4. package/dist/app/features/accounts/accounts.run.d.ts +1 -0
  5. package/dist/app/features/accounts/services.def.d.ts +3 -0
  6. package/dist/app/features/accounts/services.def.js +4 -2
  7. package/dist/app/features/accounts/services.run.d.ts +1 -0
  8. package/dist/app/features/accounts/services.run.js +3 -1
  9. package/dist/app/features/agent-commands/agent-commands.def.d.ts +37 -0
  10. package/dist/app/features/agent-commands/agent-commands.def.js +91 -0
  11. package/dist/app/features/agent-commands/agent-commands.run.d.ts +28 -0
  12. package/dist/app/features/agent-commands/agent-commands.run.js +35 -0
  13. package/dist/app/features/agent-commands/index.d.ts +2 -0
  14. package/dist/app/features/agent-commands/index.js +3 -0
  15. package/dist/app/features/agents/agents.def.d.ts +14 -1
  16. package/dist/app/features/agents/agents.def.js +61 -6
  17. package/dist/app/features/agents/agents.run.d.ts +1 -0
  18. package/dist/app/features/agents/agents.run.js +8 -1
  19. package/dist/app/features/agents/claude-env.def.d.ts +36 -0
  20. package/dist/app/features/agents/claude-env.def.js +305 -0
  21. package/dist/app/features/agents/env.def.d.ts +163 -0
  22. package/dist/app/features/agents/env.def.js +184 -0
  23. package/dist/app/features/agents/env.run.d.ts +43 -0
  24. package/dist/app/features/agents/env.run.js +86 -0
  25. package/dist/app/features/agents/index.d.ts +2 -0
  26. package/dist/app/features/agents/index.js +2 -0
  27. package/dist/app/features/defs.d.ts +132 -1
  28. package/dist/app/features/defs.js +9 -0
  29. package/dist/app/features/settings/categories.def.js +5 -2
  30. package/dist/app/features/settings/settings-rows.js +5 -1
  31. package/dist/app/features/settings/settings.run.d.ts +8 -0
  32. package/dist/app/features/settings/settings.run.js +9 -0
  33. package/dist/app/features/updates/updates.run.js +12 -2
  34. package/dist/app/features/vpn/vpn.def.d.ts +33 -0
  35. package/dist/app/features/vpn/vpn.def.js +30 -6
  36. package/dist/app/features/vpn/vpn.run.d.ts +11 -0
  37. package/dist/app/features/vpn/vpn.run.js +4 -1
  38. package/dist/app/kernel/rpc.d.ts +1 -1
  39. package/dist/app/registry.js +7 -1
  40. package/dist/bin/agent-sandbox.js +2 -2
  41. package/dist/bin/{chunk-MY7NLQQY.js → chunk-2IMT7ZCT.js} +1 -1
  42. package/dist/bin/{chunk-N4GXYTLV.js → chunk-DK4NTBUF.js} +69 -26
  43. package/dist/bin/{chunk-FRPLQLSY.js → chunk-Z2P5OGKL.js} +4323 -3463
  44. package/dist/bin/claude-host.js +2 -2
  45. package/dist/bin/claude-sbx.js +2 -2
  46. package/dist/bin/codex-sbx.js +2 -2
  47. package/dist/bin/gemini-sbx.js +2 -2
  48. package/dist/bin/sandbox.js +2 -2
  49. package/dist/bin/sbx-hide.js +2 -2
  50. package/dist/bin/sbx-show.js +2 -2
  51. package/dist/cli/commands/agent-commands.d.ts +0 -1
  52. package/dist/cli/commands/agent-commands.js +2 -32
  53. package/dist/cli/commands/index.d.ts +1 -1
  54. package/dist/cli/commands/index.js +1 -1
  55. package/dist/cli/commands/launch/launch.js +2 -2
  56. package/dist/cli/commands/registry.js +3 -2
  57. package/dist/cli/manifest.d.ts +1 -1
  58. package/dist/cli/manifest.js +1 -1
  59. package/dist/cli/menu/menu.d.ts +1 -1
  60. package/dist/cli/menu/menu.js +3 -3
  61. package/dist/cli/menu/pages/agents-page.d.ts +7 -2
  62. package/dist/cli/menu/pages/agents-page.js +67 -11
  63. package/dist/cli/menu/pages/maintenance-page.js +1 -2
  64. package/dist/cli/menu/pages/settings-page.js +1 -0
  65. package/dist/cli/menu/views.js +2 -1
  66. package/dist/cli/services/agent-commands-service.d.ts +2 -0
  67. package/dist/cli/services/agent-commands-service.js +13 -7
  68. package/dist/cli/services/vpn-service.d.ts +5 -1
  69. package/dist/cli/services/vpn-service.js +6 -1
  70. package/dist/cli/tui/dialogs/text-screen.js +2 -1
  71. package/dist/cli/tui/terminal.js +3 -1
  72. package/dist/core/config/defaults.js +9 -0
  73. package/dist/core/detect/toolchains.js +9 -0
  74. package/dist/core/disk.d.ts +1 -5
  75. package/dist/core/disk.js +1 -16
  76. package/dist/core/schema/codex.d.ts +29 -0
  77. package/dist/core/schema/codex.js +24 -0
  78. package/dist/core/schema/config.d.ts +46 -14
  79. package/dist/core/schema/config.js +2 -0
  80. package/dist/core/schema/index.d.ts +1 -0
  81. package/dist/core/schema/index.js +1 -0
  82. package/dist/core/schema/toolchains.d.ts +4 -0
  83. package/dist/core/schema/toolchains.js +3 -0
  84. package/dist/core/types.d.ts +2 -0
  85. package/dist/guest/accounts/apply.d.ts +6 -6
  86. package/dist/guest/agents/agent-files.d.ts +26 -6
  87. package/dist/guest/agents/agent-files.js +84 -14
  88. package/dist/guest/agents/local-state.d.ts +5 -2
  89. package/dist/guest/agents/local-state.js +24 -10
  90. package/dist/guest/boot/boot.js +10 -5
  91. package/dist/guest/daemon/sessions.js +2 -1
  92. package/dist/guest/toolchains/installers.d.ts +6 -10
  93. package/dist/guest/toolchains/installers.js +4 -12
  94. package/dist/guest/toolchains/native/autosdk.d.ts +3 -0
  95. package/dist/guest/toolchains/native/autosdk.js +50 -0
  96. package/dist/guest/toolchains/native/unreal.js +3 -0
  97. package/dist/guest/toolchains/native/vcruntime.d.ts +0 -3
  98. package/dist/guest/toolchains/native/vcruntime.js +2 -5
  99. package/dist/guest/toolchains/native/visual-studio.d.ts +2 -2
  100. package/dist/guest/toolchains/native/visual-studio.js +100 -16
  101. package/dist/guest/toolchains/native/vs-request.d.ts +21 -0
  102. package/dist/guest/toolchains/native/vs-request.js +60 -1
  103. package/dist/guest/toolchains/not-yet.d.ts +1 -1
  104. package/dist/guest/toolchains/not-yet.js +3 -3
  105. package/dist/guest/toolchains/persisted.js +2 -7
  106. package/dist/guest/toolchains/plan.js +9 -4
  107. package/dist/guest/toolchains/signature.d.ts +5 -0
  108. package/dist/guest/toolchains/signature.js +22 -0
  109. package/dist/guest/vpn/tunnel.d.ts +3 -0
  110. package/dist/guest/vpn/tunnel.js +10 -12
  111. package/dist/guest/vpn/vpn.js +6 -1
  112. package/dist/host/accounts/leases.d.ts +3 -3
  113. package/dist/host/accounts/source.js +1 -1
  114. package/dist/host/agent-commands/commands.js +1 -1
  115. package/dist/host/agent-commands/forwarders.d.ts +14 -2
  116. package/dist/host/agent-commands/forwarders.js +31 -13
  117. package/dist/host/agent-commands/reconcile.d.ts +2 -1
  118. package/dist/host/agent-commands/reconcile.js +7 -8
  119. package/dist/host/agent-commands/user-path.d.ts +5 -0
  120. package/dist/host/agent-commands/user-path.js +13 -0
  121. package/dist/host/launch/session-file.js +1 -0
  122. package/dist/host/profile/accounts.js +2 -4
  123. package/dist/host/profile/claude-login.d.ts +3 -2
  124. package/dist/host/profile/claude-login.js +3 -13
  125. package/dist/host/vpn/index.d.ts +2 -1
  126. package/dist/host/vpn/index.js +2 -1
  127. package/dist/host/vpn/last.d.ts +28 -0
  128. package/dist/host/vpn/last.js +43 -0
  129. package/dist/host/vpn/login.d.ts +3 -1
  130. package/dist/host/vpn/login.js +17 -3
  131. package/dist/runtime/agent.js +28 -0
  132. package/dist/runtime/daemon.js +1117 -912
  133. package/dist/runtime/db.js +30 -0
  134. package/dist/runtime/main.js +1308 -1036
  135. package/dist/runtime/netproxy.js +22 -0
  136. package/dist/runtime/tool.js +238 -208
  137. package/dist/runtime/view.js +22 -0
  138. package/dist/selftest/agent-commands.test.js +45 -7
  139. package/dist/selftest/agent-paths.test.js +1 -12
  140. package/dist/selftest/agent-settings.test.d.ts +2 -0
  141. package/dist/selftest/agent-settings.test.js +94 -0
  142. package/dist/selftest/app.test.js +2 -1
  143. package/dist/selftest/cli.test.js +4 -0
  144. package/dist/selftest/index.js +2 -0
  145. package/dist/selftest/menu.test.js +5 -3
  146. package/dist/selftest/pc-installs.test.js +5 -0
  147. package/dist/selftest/persisted-installs.test.js +69 -0
  148. package/dist/selftest/service-accounts.test.js +1 -1
  149. package/dist/selftest/support/engine-golden.js +1 -1
  150. package/dist/selftest/support/fixtures.d.ts +9 -0
  151. package/dist/selftest/vpn.test.js +51 -3
  152. package/dist/shared/accounts/anthropic.d.ts +5 -0
  153. package/dist/shared/accounts/anthropic.js +15 -0
  154. package/dist/shared/accounts/index.d.ts +1 -0
  155. package/dist/shared/accounts/index.js +1 -0
  156. package/dist/shared/channel/schema.d.ts +19 -0
  157. package/dist/shared/channel/schema.js +2 -0
  158. package/dist/shared/io/disk.d.ts +9 -0
  159. package/dist/shared/io/disk.js +19 -0
  160. package/dist/shared/io/index.d.ts +1 -0
  161. package/dist/shared/io/index.js +1 -0
  162. package/dist/shared/readiness.d.ts +9 -0
  163. package/dist/shared/readiness.js +11 -0
  164. package/dist/shared/signer.d.ts +24 -0
  165. package/dist/shared/signer.js +15 -0
  166. package/dist/shared/vpn/failure.d.ts +10 -0
  167. package/dist/shared/vpn/failure.js +28 -0
  168. package/dist/sync/watcher.js +2 -0
  169. package/dist/web/index.html +1 -1
  170. package/dist/web/{main-GVZWWP4I.js → main-OUUQYNK4.js} +75 -74
  171. package/native/csharp/HcsHost/AssemblyInfo.cs +3 -3
  172. package/native/csharp/HostTools/AssemblyInfo.cs +3 -3
  173. package/native/csharp/HostTools/Program.cs +14 -1
  174. package/native/csharp/HostTools/UserPath.cs +17 -0
  175. package/native/csharp/StorageHelper/AssemblyInfo.cs +3 -3
  176. package/native/scripts/edit-user-path.ps1 +6 -2
  177. package/package.json +1 -1
  178. package/sandbox/scripts/get-signature.ps1 +13 -0
  179. package/schemas/config.schema.json +64 -0
  180. package/schemas/sandbox-config.schema.json +8 -0
  181. package/sandbox/scripts/get-signer.ps1 +0 -8
@@ -1363,11 +1363,11 @@ var require_lodash = __commonJS({
1363
1363
  return isFunction(object2[key2]);
1364
1364
  });
1365
1365
  }
1366
- function baseGet(object2, path84) {
1367
- path84 = castPath(path84, object2);
1368
- var index = 0, length = path84.length;
1366
+ function baseGet(object2, path87) {
1367
+ path87 = castPath(path87, object2);
1368
+ var index = 0, length = path87.length;
1369
1369
  while (object2 != null && index < length) {
1370
- object2 = object2[toKey(path84[index++])];
1370
+ object2 = object2[toKey(path87[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, path84, args) {
1435
- path84 = castPath(path84, object2);
1436
- object2 = parent(object2, path84);
1437
- var func = object2 == null ? object2 : object2[toKey(last(path84))];
1434
+ function baseInvoke(object2, path87, args) {
1435
+ path87 = castPath(path87, object2);
1436
+ object2 = parent(object2, path87);
1437
+ var func = object2 == null ? object2 : object2[toKey(last(path87))];
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(path84, srcValue) {
1594
- if (isKey(path84) && isStrictComparable(srcValue)) {
1595
- return matchesStrictComparable(toKey(path84), srcValue);
1593
+ function baseMatchesProperty(path87, srcValue) {
1594
+ if (isKey(path87) && isStrictComparable(srcValue)) {
1595
+ return matchesStrictComparable(toKey(path87), srcValue);
1596
1596
  }
1597
1597
  return function(object2) {
1598
- var objValue = get(object2, path84);
1599
- return objValue === undefined2 && objValue === srcValue ? hasIn(object2, path84) : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG);
1598
+ var objValue = get(object2, path87);
1599
+ return objValue === undefined2 && objValue === srcValue ? hasIn(object2, path87) : 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, path84) {
1697
- return hasIn(object2, path84);
1696
+ return basePickBy(object2, paths, function(value, path87) {
1697
+ return hasIn(object2, path87);
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 path84 = paths[index], value = baseGet(object2, path84);
1704
- if (predicate(value, path84)) {
1705
- baseSet(result2, castPath(path84, object2), value);
1703
+ var path87 = paths[index], value = baseGet(object2, path87);
1704
+ if (predicate(value, path87)) {
1705
+ baseSet(result2, castPath(path87, object2), value);
1706
1706
  }
1707
1707
  }
1708
1708
  return result2;
1709
1709
  }
1710
- function basePropertyDeep(path84) {
1710
+ function basePropertyDeep(path87) {
1711
1711
  return function(object2) {
1712
- return baseGet(object2, path84);
1712
+ return baseGet(object2, path87);
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, path84, value, customizer) {
1786
+ function baseSet(object2, path87, value, customizer) {
1787
1787
  if (!isObject2(object2)) {
1788
1788
  return object2;
1789
1789
  }
1790
- path84 = castPath(path84, object2);
1791
- var index = -1, length = path84.length, lastIndex = length - 1, nested = object2;
1790
+ path87 = castPath(path87, object2);
1791
+ var index = -1, length = path87.length, lastIndex = length - 1, nested = object2;
1792
1792
  while (nested != null && ++index < length) {
1793
- var key2 = toKey(path84[index]), newValue = value;
1793
+ var key2 = toKey(path87[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(path84[index + 1]) ? [] : {};
1801
+ newValue = isObject2(objValue) ? objValue : isIndex(path87[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, path84) {
1968
- path84 = castPath(path84, object2);
1969
- var index = -1, length = path84.length;
1967
+ function baseUnset(object2, path87) {
1968
+ path87 = castPath(path87, object2);
1969
+ var index = -1, length = path87.length;
1970
1970
  if (!length) {
1971
1971
  return true;
1972
1972
  }
1973
1973
  while (++index < length) {
1974
- var key2 = toKey(path84[index]);
1974
+ var key2 = toKey(path87[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, path84);
1983
- return obj == null || delete obj[toKey(last(path84))];
1982
+ var obj = parent(object2, path87);
1983
+ return obj == null || delete obj[toKey(last(path87))];
1984
1984
  }
1985
- function baseUpdate(object2, path84, updater, customizer) {
1986
- return baseSet(object2, path84, updater(baseGet(object2, path84)), customizer);
1985
+ function baseUpdate(object2, path87, updater, customizer) {
1986
+ return baseSet(object2, path87, updater(baseGet(object2, path87)), 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, path84, hasFunc) {
2870
- path84 = castPath(path84, object2);
2871
- var index = -1, length = path84.length, result2 = false;
2869
+ function hasPath(object2, path87, hasFunc) {
2870
+ path87 = castPath(path87, object2);
2871
+ var index = -1, length = path87.length, result2 = false;
2872
2872
  while (++index < length) {
2873
- var key2 = toKey(path84[index]);
2873
+ var key2 = toKey(path87[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, path84) {
3076
- return path84.length < 2 ? object2 : baseGet(object2, baseSlice(path84, 0, -1));
3075
+ function parent(object2, path87) {
3076
+ return path87.length < 2 ? object2 : baseGet(object2, baseSlice(path87, 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, path84, args) {
3712
- var index = -1, isFunc = typeof path84 == "function", result2 = isArrayLike(collection) ? Array2(collection.length) : [];
3711
+ var invokeMap = baseRest(function(collection, path87, args) {
3712
+ var index = -1, isFunc = typeof path87 == "function", result2 = isArrayLike(collection) ? Array2(collection.length) : [];
3713
3713
  baseEach(collection, function(value) {
3714
- result2[++index] = isFunc ? apply(path84, value, args) : baseInvoke(value, path84, args);
3714
+ result2[++index] = isFunc ? apply(path87, value, args) : baseInvoke(value, path87, 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, path84, defaultValue) {
4367
- var result2 = object2 == null ? undefined2 : baseGet(object2, path84);
4366
+ function get(object2, path87, defaultValue) {
4367
+ var result2 = object2 == null ? undefined2 : baseGet(object2, path87);
4368
4368
  return result2 === undefined2 ? defaultValue : result2;
4369
4369
  }
4370
- function has(object2, path84) {
4371
- return object2 != null && hasPath(object2, path84, baseHas);
4370
+ function has(object2, path87) {
4371
+ return object2 != null && hasPath(object2, path87, baseHas);
4372
4372
  }
4373
- function hasIn(object2, path84) {
4374
- return object2 != null && hasPath(object2, path84, baseHasIn);
4373
+ function hasIn(object2, path87) {
4374
+ return object2 != null && hasPath(object2, path87, 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(path84) {
4428
- path84 = castPath(path84, object2);
4429
- isDeep || (isDeep = path84.length > 1);
4430
- return path84;
4427
+ paths = arrayMap(paths, function(path87) {
4428
+ path87 = castPath(path87, object2);
4429
+ isDeep || (isDeep = path87.length > 1);
4430
+ return path87;
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, path84) {
4457
- return predicate(value, path84[0]);
4456
+ return basePickBy(object2, props, function(value, path87) {
4457
+ return predicate(value, path87[0]);
4458
4458
  });
4459
4459
  }
4460
- function result(object2, path84, defaultValue) {
4461
- path84 = castPath(path84, object2);
4462
- var index = -1, length = path84.length;
4460
+ function result(object2, path87, defaultValue) {
4461
+ path87 = castPath(path87, object2);
4462
+ var index = -1, length = path87.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(path84[index])];
4468
+ var value = object2 == null ? undefined2 : object2[toKey(path87[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, path84, value) {
4478
- return object2 == null ? object2 : baseSet(object2, path84, value);
4477
+ function set2(object2, path87, value) {
4478
+ return object2 == null ? object2 : baseSet(object2, path87, value);
4479
4479
  }
4480
- function setWith(object2, path84, value, customizer) {
4480
+ function setWith(object2, path87, value, customizer) {
4481
4481
  customizer = typeof customizer == "function" ? customizer : undefined2;
4482
- return object2 == null ? object2 : baseSet(object2, path84, value, customizer);
4482
+ return object2 == null ? object2 : baseSet(object2, path87, 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, path84) {
4505
- return object2 == null ? true : baseUnset(object2, path84);
4504
+ function unset(object2, path87) {
4505
+ return object2 == null ? true : baseUnset(object2, path87);
4506
4506
  }
4507
- function update(object2, path84, updater) {
4508
- return object2 == null ? object2 : baseUpdate(object2, path84, castFunction(updater));
4507
+ function update(object2, path87, updater) {
4508
+ return object2 == null ? object2 : baseUpdate(object2, path87, castFunction(updater));
4509
4509
  }
4510
- function updateWith(object2, path84, updater, customizer) {
4510
+ function updateWith(object2, path87, updater, customizer) {
4511
4511
  customizer = typeof customizer == "function" ? customizer : undefined2;
4512
- return object2 == null ? object2 : baseUpdate(object2, path84, castFunction(updater), customizer);
4512
+ return object2 == null ? object2 : baseUpdate(object2, path87, 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(path84, srcValue) {
4899
- return baseMatchesProperty(path84, baseClone(srcValue, CLONE_DEEP_FLAG));
4898
+ function matchesProperty(path87, srcValue) {
4899
+ return baseMatchesProperty(path87, baseClone(srcValue, CLONE_DEEP_FLAG));
4900
4900
  }
4901
- var method = baseRest(function(path84, args) {
4901
+ var method = baseRest(function(path87, args) {
4902
4902
  return function(object2) {
4903
- return baseInvoke(object2, path84, args);
4903
+ return baseInvoke(object2, path87, args);
4904
4904
  };
4905
4905
  });
4906
4906
  var methodOf = baseRest(function(object2, args) {
4907
- return function(path84) {
4908
- return baseInvoke(object2, path84, args);
4907
+ return function(path87) {
4908
+ return baseInvoke(object2, path87, 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(path84) {
4956
- return isKey(path84) ? baseProperty(toKey(path84)) : basePropertyDeep(path84);
4955
+ function property(path87) {
4956
+ return isKey(path87) ? baseProperty(toKey(path87)) : basePropertyDeep(path87);
4957
4957
  }
4958
4958
  function propertyOf(object2) {
4959
- return function(path84) {
4960
- return object2 == null ? undefined2 : baseGet(object2, path84);
4959
+ return function(path87) {
4960
+ return object2 == null ? undefined2 : baseGet(object2, path87);
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(path84, args) {
5414
- if (typeof path84 == "function") {
5413
+ LazyWrapper.prototype.invokeMap = baseRest(function(path87, args) {
5414
+ if (typeof path87 == "function") {
5415
5415
  return new LazyWrapper(this);
5416
5416
  }
5417
5417
  return this.map(function(value) {
5418
- return baseInvoke(value, path84, args);
5418
+ return baseInvoke(value, path87, 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 fs7 from "node:fs";
5544
- import path9 from "node:path";
5543
+ import fs8 from "node:fs";
5544
+ import path10 from "node:path";
5545
5545
 
5546
5546
  // src/guest/runtime/paths.ts
5547
- import path8 from "node:path";
5547
+ import path9 from "node:path";
5548
5548
 
5549
5549
  // src/shared/channel/run-dir.ts
5550
- import fs6 from "node:fs";
5551
- import path7 from "node:path";
5550
+ import fs7 from "node:fs";
5551
+ import path8 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, path84) {
6370
- if (!path84)
6369
+ function getElementAtPath(obj, path87) {
6370
+ if (!path87)
6371
6371
  return obj;
6372
- return path84.reduce((acc, key2) => acc?.[key2], obj);
6372
+ return path87.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(path84, issues) {
6712
+ function prefixIssues(path87, issues) {
6713
6713
  return issues.map((iss) => {
6714
6714
  var _a3;
6715
6715
  (_a3 = iss).path ?? (_a3.path = []);
6716
- iss.path.unshift(path84);
6716
+ iss.path.unshift(path87);
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, path84 = []) => {
7166
+ const processError = (error63, path87 = []) => {
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 }, [...path84, ...issue2.path]));
7169
+ issue2.errors.map((issues) => processError({ issues }, [...path87, ...issue2.path]));
7170
7170
  } else if (issue2.code === "invalid_key") {
7171
- processError({ issues: issue2.issues }, [...path84, ...issue2.path]);
7171
+ processError({ issues: issue2.issues }, [...path87, ...issue2.path]);
7172
7172
  } else if (issue2.code === "invalid_element") {
7173
- processError({ issues: issue2.issues }, [...path84, ...issue2.path]);
7173
+ processError({ issues: issue2.issues }, [...path87, ...issue2.path]);
7174
7174
  } else {
7175
- const fullpath = [...path84, ...issue2.path];
7175
+ const fullpath = [...path87, ...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, path84 = []) => {
7214
+ const processError = (error63, path87 = []) => {
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 }, [...path84, ...issue2.path]));
7218
+ issue2.errors.map((issues) => processError({ issues }, [...path87, ...issue2.path]));
7219
7219
  } else if (issue2.code === "invalid_key") {
7220
- processError({ issues: issue2.issues }, [...path84, ...issue2.path]);
7220
+ processError({ issues: issue2.issues }, [...path87, ...issue2.path]);
7221
7221
  } else if (issue2.code === "invalid_element") {
7222
- processError({ issues: issue2.issues }, [...path84, ...issue2.path]);
7222
+ processError({ issues: issue2.issues }, [...path87, ...issue2.path]);
7223
7223
  } else {
7224
- const fullpath = [...path84, ...issue2.path];
7224
+ const fullpath = [...path87, ...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 path84 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
7264
- for (const seg of path84) {
7263
+ const path87 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
7264
+ for (const seg of path87) {
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 path84 = ref.slice(1).split("/").filter(Boolean);
24367
- if (path84.length === 0) {
24366
+ const path87 = ref.slice(1).split("/").filter(Boolean);
24367
+ if (path87.length === 0) {
24368
24368
  return ctx.rootSchema;
24369
24369
  }
24370
24370
  const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
24371
- if (path84[0] === defsKey) {
24372
- const key2 = path84[1] === void 0 ? void 0 : decodeJSONPointerSegment(path84[1]);
24371
+ if (path87[0] === defsKey) {
24372
+ const key2 = path87[1] === void 0 ? void 0 : decodeJSONPointerSegment(path87[1]);
24373
24373
  if (!key2 || !ctx.defs[key2]) {
24374
24374
  throw new Error(`Reference not found: ${ref}`);
24375
24375
  }
@@ -25369,6 +25369,22 @@ var DatabasesSchema = external_exports.strictObject({
25369
25369
  })
25370
25370
  });
25371
25371
 
25372
+ // src/core/schema/codex.ts
25373
+ var CodexSchema = external_exports.strictObject({
25374
+ sandboxMode: external_exports.enum(["danger-full-access", "workspace-write", "read-only"]).describe(
25375
+ "Codex's own sandbox. Inside Windows Sandbox Codex's own sandbox only slows it down (it re-grants file permissions over your profile at every boot), so the default is danger-full-access: Windows Sandbox is the sandbox."
25376
+ ),
25377
+ approvalPolicy: external_exports.enum(["never", "on-request", "on-failure", "untrusted"]).describe('When Codex asks before it runs a command. "never" with danger-full-access starts it with no questions.'),
25378
+ model: external_exports.string().max(100).regex(/^[A-Za-z0-9._:/-]*$/, "letters, digits and . _ : / - only").describe("The model Codex uses. Empty = Codex's own default."),
25379
+ reasoningEffort: external_exports.enum(["default", "minimal", "low", "medium", "high", "xhigh"]).describe(`How hard Codex thinks. "default" = Codex's own default.`),
25380
+ windowsSandbox: external_exports.enum(["off", "unelevated", "elevated"]).describe(
25381
+ `Codex's Windows sandbox mode in its config.toml. "off" removes the setting so Codex does not set up its sandbox users and firewall rules at every boot.`
25382
+ ),
25383
+ mcpLoginsInFile: external_exports.boolean().describe(
25384
+ `Keep the sign-ins of Codex's MCP servers in a file in the saved Codex folder (mcp_oauth_credentials_store = "file"), so they survive between sandboxes. A value you set in config.toml is kept.`
25385
+ )
25386
+ });
25387
+
25372
25388
  // src/core/schema/harness.ts
25373
25389
  var SubfolderSchema = external_exports.string().regex(/^(?!.*(^|[\\/])\.\.([\\/]|$))[A-Za-z0-9._ -]+([\\/][A-Za-z0-9._ -]+)*$/, "a plain relative folder");
25374
25390
  var HarnessHomeSchema = external_exports.strictObject({
@@ -25681,6 +25697,9 @@ var ToolchainsSchema = external_exports.strictObject({
25681
25697
  keepInstallFiles: external_exports.boolean().describe(
25682
25698
  "Keep an offline copy of the Visual Studio install files in tools\\visualstudio (~10 GB, made once), so later boots install without downloading them again. Skipped while that disk has too little room."
25683
25699
  ),
25700
+ visualStudio: external_exports.enum(["full", "autosdk"]).describe(
25701
+ `"full": install Visual Studio Community (the engine finds it through the Setup API; ~10 GB, redone every boot). "autosdk" (experimental): skip Visual Studio and build an Unreal AutoSDK tree from the portable MSVC in tools\\unreal\\autosdk (kept between sandboxes); UnrealBuildTool finds MSVC through AutoSDK, but the editor's Visual Studio integration is not available. Needs toolchains.msvc (turned on for you).`
25702
+ ),
25684
25703
  persistEngines: external_exports.boolean().describe(
25685
25704
  "Engines the Epic Games Launcher installs go to tools\\unreal\\engines (kept between sandboxes, 40-60 GB each) and are registered with the launcher again every boot. Off: they go on the sandbox disk and are lost when it closes. Engines installed on this PC can be mapped instead (pcInstalls.unrealEngines)."
25686
25705
  ),
@@ -27203,6 +27222,7 @@ var ConfigSchema = external_exports.strictObject({
27203
27222
  apps: AppsSchema,
27204
27223
  claudeProfile: ClaudeProfileSchema,
27205
27224
  harnesses: external_exports.record(NameSchema, HarnessSchema).describe("Agents that can run in the sandbox."),
27225
+ codex: CodexSchema,
27206
27226
  hooks: external_exports.strictObject({ failFast: external_exports.boolean().describe("Stop when a hook script fails.") }),
27207
27227
  projects: ProjectsSchema.describe(
27208
27228
  "Several projects in one sandbox: folders of projects mapped at every start, and adding folders while it runs."
@@ -27446,6 +27466,8 @@ var ProjectStatusSchema = external_exports.object({
27446
27466
  var VpnStatusSchema = external_exports.object({
27447
27467
  state: external_exports.enum(["off", "starting", "up", "failed"]),
27448
27468
  message: Text(2e3),
27469
+ /** Why it failed, when it did: `auth` (login refused), `unreachable`, `driver`, `timeout` or `other`. */
27470
+ code: external_exports.enum(["auth", "unreachable", "driver", "timeout", "other"]).optional(),
27449
27471
  killSwitch: external_exports.boolean(),
27450
27472
  /** A direct connection was tried after the kill switch was applied: false = it still got out. */
27451
27473
  killSwitchHeld: external_exports.boolean().optional(),
@@ -27692,6 +27714,20 @@ function encodeText(text, encoding) {
27692
27714
  return Buffer.from(text, "utf8");
27693
27715
  }
27694
27716
 
27717
+ // src/shared/io/disk.ts
27718
+ import fs6 from "node:fs";
27719
+ import path7 from "node:path";
27720
+ function freeBytesAt(dir, statfs = fs6.statfsSync) {
27721
+ let at = path7.resolve(dir);
27722
+ while (!fs6.existsSync(at) && path7.dirname(at) !== at) at = path7.dirname(at);
27723
+ try {
27724
+ const s = statfs(at);
27725
+ return s.bavail * s.bsize;
27726
+ } catch {
27727
+ return null;
27728
+ }
27729
+ }
27730
+
27695
27731
  // src/shared/channel/run-dir.ts
27696
27732
  function safeId(id) {
27697
27733
  return IdSchema.parse(id);
@@ -27700,14 +27736,14 @@ function now() {
27700
27736
  return (/* @__PURE__ */ new Date()).toISOString();
27701
27737
  }
27702
27738
  var scan = (schema, dir) => {
27703
- if (!fs6.existsSync(dir)) return { valid: [], invalid: [] };
27739
+ if (!fs7.existsSync(dir)) return { valid: [], invalid: [] };
27704
27740
  const valid = [];
27705
27741
  const invalid = [];
27706
- for (const name of fs6.readdirSync(dir)) {
27742
+ for (const name of fs7.readdirSync(dir)) {
27707
27743
  if (name.endsWith(".tmp")) continue;
27708
- const message = /^[A-Za-z0-9_-]{1,64}\.json$/.test(name) ? readValid(schema, path7.join(dir, name)) : null;
27744
+ const message = /^[A-Za-z0-9_-]{1,64}\.json$/.test(name) ? readValid(schema, path8.join(dir, name)) : null;
27709
27745
  if (message) valid.push(message);
27710
- else invalid.push(path7.join(dir, name));
27746
+ else invalid.push(path8.join(dir, name));
27711
27747
  }
27712
27748
  return { valid, invalid };
27713
27749
  };
@@ -27738,45 +27774,45 @@ var RunDir = class {
27738
27774
  liveDir;
27739
27775
  liveRepliesDir;
27740
27776
  constructor(dataDir2) {
27741
- this.root = path7.join(dataDir2, "run");
27742
- this.sandboxFile = path7.join(this.root, "sandbox.json");
27743
- this.vpnFile = path7.join(this.root, "vpn.json");
27744
- this.pressureFile = path7.join(this.root, "pressure.json");
27745
- this.heartbeatFile = path7.join(this.root, "heartbeat.json");
27746
- this.budgetFile = path7.join(this.root, "budget.json");
27747
- this.requestsDir = path7.join(this.root, "requests");
27748
- this.responsesDir = path7.join(this.root, "responses");
27749
- this.sessionsDir = path7.join(this.root, "sessions");
27750
- this.projectsDir = path7.join(this.root, "projects");
27751
- this.auditDir = path7.join(this.root, "audit");
27752
- this.treesDir = path7.join(this.root, "trees");
27753
- this.secretsDir = path7.join(dataDir2, "secrets");
27754
- this.liveDir = path7.join(this.root, "live");
27755
- this.liveRepliesDir = path7.join(this.root, "live-replies");
27777
+ this.root = path8.join(dataDir2, "run");
27778
+ this.sandboxFile = path8.join(this.root, "sandbox.json");
27779
+ this.vpnFile = path8.join(this.root, "vpn.json");
27780
+ this.pressureFile = path8.join(this.root, "pressure.json");
27781
+ this.heartbeatFile = path8.join(this.root, "heartbeat.json");
27782
+ this.budgetFile = path8.join(this.root, "budget.json");
27783
+ this.requestsDir = path8.join(this.root, "requests");
27784
+ this.responsesDir = path8.join(this.root, "responses");
27785
+ this.sessionsDir = path8.join(this.root, "sessions");
27786
+ this.projectsDir = path8.join(this.root, "projects");
27787
+ this.auditDir = path8.join(this.root, "audit");
27788
+ this.treesDir = path8.join(this.root, "trees");
27789
+ this.secretsDir = path8.join(dataDir2, "secrets");
27790
+ this.liveDir = path8.join(this.root, "live");
27791
+ this.liveRepliesDir = path8.join(this.root, "live-replies");
27756
27792
  }
27757
27793
  liveFile(id) {
27758
- return path7.join(this.liveDir, safeId(id) + ".json");
27794
+ return path8.join(this.liveDir, safeId(id) + ".json");
27759
27795
  }
27760
27796
  liveReplyFile(id) {
27761
- return path7.join(this.liveRepliesDir, safeId(id) + ".json");
27797
+ return path8.join(this.liveRepliesDir, safeId(id) + ".json");
27762
27798
  }
27763
27799
  requestFile(id) {
27764
- return path7.join(this.requestsDir, safeId(id) + ".json");
27800
+ return path8.join(this.requestsDir, safeId(id) + ".json");
27765
27801
  }
27766
27802
  responseFile(id) {
27767
- return path7.join(this.responsesDir, safeId(id) + ".json");
27803
+ return path8.join(this.responsesDir, safeId(id) + ".json");
27768
27804
  }
27769
27805
  sessionFile(id) {
27770
- return path7.join(this.sessionsDir, safeId(id) + ".json");
27806
+ return path8.join(this.sessionsDir, safeId(id) + ".json");
27771
27807
  }
27772
27808
  treeFile(id) {
27773
- return path7.join(this.treesDir, safeId(id) + ".json");
27809
+ return path8.join(this.treesDir, safeId(id) + ".json");
27774
27810
  }
27775
27811
  projectFile(name) {
27776
- return path7.join(this.projectsDir, safeId(name) + ".json");
27812
+ return path8.join(this.projectsDir, safeId(name) + ".json");
27777
27813
  }
27778
27814
  secretFile(id) {
27779
- return path7.join(this.secretsDir, safeId(id) + ".json");
27815
+ return path8.join(this.secretsDir, safeId(id) + ".json");
27780
27816
  }
27781
27817
  readSandboxStatus() {
27782
27818
  return readValid(SandboxStatusSchema, this.sandboxFile);
@@ -27818,19 +27854,19 @@ var launchDir = process.env.AGENT_LAUNCH_DIR ?? "C:\\AgentLaunch";
27818
27854
  var dataDir = process.env.AGENT_DATA_DIR ?? "C:\\AgentData";
27819
27855
  var hostToolsDir = process.env.AGENT_HOST_TOOLS_DIR ?? "C:\\HostTools";
27820
27856
  var localDir = process.env.AGENT_LOCAL_DIR ?? "C:\\nvm";
27821
- var toolsDir = path8.join(dataDir, "tools");
27822
- var logsDir = path8.join(dataDir, "logs");
27857
+ var toolsDir = path9.join(dataDir, "tools");
27858
+ var logsDir = path9.join(dataDir, "logs");
27823
27859
  var run = new RunDir(dataDir);
27824
27860
 
27825
27861
  // src/guest/runtime/log.ts
27826
- fs7.mkdirSync(logsDir, { recursive: true });
27827
- var logFile = path9.join(
27862
+ fs8.mkdirSync(logsDir, { recursive: true });
27863
+ var logFile = path10.join(
27828
27864
  logsDir,
27829
27865
  (process.env.AGENT_LOG_PREFIX ?? "guest") + "-" + (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-") + ".log"
27830
27866
  );
27831
27867
  var append = (line) => {
27832
27868
  try {
27833
- fs7.appendFileSync(logFile, line + "\n");
27869
+ fs8.appendFileSync(logFile, line + "\n");
27834
27870
  } catch {
27835
27871
  }
27836
27872
  };
@@ -27844,8 +27880,8 @@ function warn(message) {
27844
27880
  }
27845
27881
 
27846
27882
  // src/guest/runtime/session.ts
27847
- import fs11 from "node:fs";
27848
- import path14 from "node:path";
27883
+ import fs12 from "node:fs";
27884
+ import path15 from "node:path";
27849
27885
 
27850
27886
  // src/shared/download/http.ts
27851
27887
  var USER_AGENT = "windows-development-sandbox";
@@ -27876,15 +27912,15 @@ async function fetchText(url2) {
27876
27912
  }
27877
27913
 
27878
27914
  // src/shared/download/archive.ts
27879
- import fs9 from "node:fs";
27880
- import path12 from "node:path";
27915
+ import fs10 from "node:fs";
27916
+ import path13 from "node:path";
27881
27917
  import crypto from "node:crypto";
27882
27918
 
27883
27919
  // src/shared/system.ts
27884
- import path10 from "node:path";
27920
+ import path11 from "node:path";
27885
27921
  var systemRoot = () => process.env.SystemRoot ?? process.env.WINDIR ?? "C:\\Windows";
27886
27922
  function system32(exe) {
27887
- return path10.join(systemRoot(), "System32", exe);
27923
+ return path11.join(systemRoot(), "System32", exe);
27888
27924
  }
27889
27925
  var SYSTEM = {
27890
27926
  cmd: () => system32("cmd.exe"),
@@ -27905,17 +27941,17 @@ var SYSTEM = {
27905
27941
  msiexec: () => system32("msiexec.exe"),
27906
27942
  sc: () => system32("sc.exe"),
27907
27943
  /** The .NET Framework C# compiler that ships with Windows (C# 5). */
27908
- csc: () => path10.join(systemRoot(), "Microsoft.NET", "Framework64", "v4.0.30319", "csc.exe")
27944
+ csc: () => path11.join(systemRoot(), "Microsoft.NET", "Framework64", "v4.0.30319", "csc.exe")
27909
27945
  };
27910
27946
 
27911
27947
  // src/shared/scripts.ts
27912
- import fs8 from "node:fs";
27913
- import path11 from "node:path";
27948
+ import fs9 from "node:fs";
27949
+ import path12 from "node:path";
27914
27950
  import { fileURLToPath } from "node:url";
27915
- var HERE = path11.dirname(fileURLToPath(import.meta.url));
27951
+ var HERE = path12.dirname(fileURLToPath(import.meta.url));
27916
27952
  function sandboxScriptsDir() {
27917
- const candidates = [path11.resolve(HERE, "..", "sandbox"), path11.resolve(HERE, "..", "..", "sandbox")];
27918
- return candidates.find((dir) => fs8.existsSync(path11.join(dir, "boot", "bootstrap.ps1"))) ?? candidates[candidates.length - 1];
27953
+ const candidates = [path12.resolve(HERE, "..", "sandbox"), path12.resolve(HERE, "..", "..", "sandbox")];
27954
+ return candidates.find((dir) => fs9.existsSync(path12.join(dir, "boot", "bootstrap.ps1"))) ?? candidates[candidates.length - 1];
27919
27955
  }
27920
27956
  function scriptArgs(name, args = []) {
27921
27957
  return [
@@ -27925,7 +27961,7 @@ function scriptArgs(name, args = []) {
27925
27961
  "-ExecutionPolicy",
27926
27962
  "Bypass",
27927
27963
  "-File",
27928
- path11.join(sandboxScriptsDir(), "scripts", name),
27964
+ path12.join(sandboxScriptsDir(), "scripts", name),
27929
27965
  ...args
27930
27966
  ];
27931
27967
  }
@@ -27945,16 +27981,16 @@ function stagingFolder(destination) {
27945
27981
  return destination + ".staging-" + crypto.randomBytes(3).toString("hex");
27946
27982
  }
27947
27983
  function moveIntoPlace(work, destination) {
27948
- safeRemove(destination, path12.dirname(destination));
27949
- fs9.mkdirSync(path12.dirname(destination), { recursive: true });
27950
- fs9.renameSync(work, destination);
27984
+ safeRemove(destination, path13.dirname(destination));
27985
+ fs10.mkdirSync(path13.dirname(destination), { recursive: true });
27986
+ fs10.renameSync(work, destination);
27951
27987
  }
27952
27988
  async function extractArchive(archive, destination, members2 = []) {
27953
- fs9.mkdirSync(destination, { recursive: true });
27989
+ fs10.mkdirSync(destination, { recursive: true });
27954
27990
  let status = await spawnAsync(SYSTEM.tar(), ["-xf", archive, "-C", destination, ...members2]);
27955
27991
  if (status !== 0 && /\.(zip|nupkg)$/i.test(archive)) {
27956
27992
  const zip = archive.endsWith(".zip") ? archive : archive + ".zip";
27957
- if (zip !== archive) fs9.copyFileSync(archive, zip);
27993
+ if (zip !== archive) fs10.copyFileSync(archive, zip);
27958
27994
  status = await spawnAsync(
27959
27995
  SYSTEM.powershell(),
27960
27996
  scriptArgs("expand-archive.ps1", ["-Archive", zip, "-Destination", destination])
@@ -27963,21 +27999,21 @@ async function extractArchive(archive, destination, members2 = []) {
27963
27999
  if (status !== 0) throw new Error("Could not extract " + archive);
27964
28000
  }
27965
28001
  function findFile(root, name, maxDepth = 4) {
27966
- if (maxDepth < 0 || !fs9.existsSync(root)) return null;
27967
- const entries2 = fs9.readdirSync(root, { withFileTypes: true });
28002
+ if (maxDepth < 0 || !fs10.existsSync(root)) return null;
28003
+ const entries2 = fs10.readdirSync(root, { withFileTypes: true });
27968
28004
  for (const entry of entries2)
27969
- if (entry.isFile() && entry.name.toLowerCase() === name.toLowerCase()) return path12.join(root, entry.name);
28005
+ if (entry.isFile() && entry.name.toLowerCase() === name.toLowerCase()) return path13.join(root, entry.name);
27970
28006
  for (const entry of entries2)
27971
28007
  if (entry.isDirectory()) {
27972
- const found = findFile(path12.join(root, entry.name), name, maxDepth - 1);
28008
+ const found = findFile(path13.join(root, entry.name), name, maxDepth - 1);
27973
28009
  if (found) return found;
27974
28010
  }
27975
28011
  return null;
27976
28012
  }
27977
28013
 
27978
28014
  // src/shared/download/downloader.ts
27979
- import fs10 from "node:fs";
27980
- import path13 from "node:path";
28015
+ import fs11 from "node:fs";
28016
+ import path14 from "node:path";
27981
28017
  import crypto2 from "node:crypto";
27982
28018
  import { Readable, Transform } from "node:stream";
27983
28019
  import { pipeline } from "node:stream/promises";
@@ -27998,12 +28034,12 @@ var Downloader = class {
27998
28034
  const sums = typeof expected === "string" || expected === null ? { sha256: expected } : expected;
27999
28035
  if (this.requireChecksum && !sums.sha256?.trim() && !sums.sha512?.trim() && !sums.sha1?.trim() && !sums.verify) {
28000
28036
  throw new Error(
28001
- "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."
28037
+ "Refusing to download " + path14.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."
28002
28038
  );
28003
28039
  }
28004
28040
  const response = await fetchRetry(url2, {}, 3, 20 * 60 * 1e3);
28005
28041
  if (!response.body) throw new Error("Empty response for " + url2);
28006
- fs10.mkdirSync(path13.dirname(destination), { recursive: true });
28042
+ fs11.mkdirSync(path14.dirname(destination), { recursive: true });
28007
28043
  const checks = ["sha256", "sha512", "sha1"].flatMap((kind) => {
28008
28044
  const want = sums[kind]?.trim().toLowerCase();
28009
28045
  return want ? [{ want, hash: crypto2.createHash(kind) }] : [];
@@ -28033,13 +28069,13 @@ var Downloader = class {
28033
28069
  });
28034
28070
  const partial2 = destination + ".part";
28035
28071
  try {
28036
- await pipeline(Readable.fromWeb(response.body), tap, fs10.createWriteStream(partial2));
28072
+ await pipeline(Readable.fromWeb(response.body), tap, fs11.createWriteStream(partial2));
28037
28073
  if (checks.some((c) => c.hash.digest("hex") !== c.want)) throw new Error("Checksum mismatch for " + url2);
28038
28074
  if (sums.verify) await sums.verify(partial2);
28039
- fs10.rmSync(destination, { force: true });
28040
- fs10.renameSync(partial2, destination);
28075
+ fs11.rmSync(destination, { force: true });
28076
+ fs11.renameSync(partial2, destination);
28041
28077
  } finally {
28042
- fs10.rmSync(partial2, { force: true });
28078
+ fs11.rmSync(partial2, { force: true });
28043
28079
  }
28044
28080
  }
28045
28081
  /**
@@ -28049,26 +28085,26 @@ var Downloader = class {
28049
28085
  async archive(url2, destination, options = {}) {
28050
28086
  const work = stagingFolder(destination);
28051
28087
  try {
28052
- const archive = path13.join(work, options.fileName ?? path13.basename(new URL(url2).pathname));
28088
+ const archive = path14.join(work, options.fileName ?? path14.basename(new URL(url2).pathname));
28053
28089
  await this.file(url2, archive, {
28054
28090
  sha256: options.sha256,
28055
28091
  sha512: options.sha512,
28056
28092
  sha1: options.sha1,
28057
28093
  ...options.verify ? { verify: options.verify } : {}
28058
28094
  });
28059
- const extracted = path13.join(work, "x");
28095
+ const extracted = path14.join(work, "x");
28060
28096
  await extractArchive(archive, extracted, options.members);
28061
28097
  let root = extracted;
28062
28098
  if (options.locate) {
28063
28099
  const found = findFile(extracted, options.locate);
28064
28100
  if (!found) throw new Error(options.locate + " not found in " + url2);
28065
- root = path13.dirname(found);
28066
- for (let i = 0; i < (options.up ?? 0) && path13.dirname(root).startsWith(extracted); i++)
28067
- root = path13.dirname(root);
28101
+ root = path14.dirname(found);
28102
+ for (let i = 0; i < (options.up ?? 0) && path14.dirname(root).startsWith(extracted); i++)
28103
+ root = path14.dirname(root);
28068
28104
  }
28069
28105
  moveIntoPlace(root, destination);
28070
28106
  } finally {
28071
- safeRemove(work, path13.dirname(work));
28107
+ safeRemove(work, path14.dirname(work));
28072
28108
  }
28073
28109
  }
28074
28110
  };
@@ -28146,12 +28182,12 @@ var githubAssetFromPage = async (repo, pattern, searchOlder) => {
28146
28182
 
28147
28183
  // src/guest/runtime/session.ts
28148
28184
  var session = JSON.parse(
28149
- fs11.readFileSync(path14.join(launchDir, "session.json"), "utf8").replace(/^\uFEFF/, "")
28185
+ fs12.readFileSync(path15.join(launchDir, "session.json"), "utf8").replace(/^\uFEFF/, "")
28150
28186
  );
28151
28187
  downloader.requireChecksum = session.downloads?.requireChecksum === true;
28152
28188
  var workspace = process.env.AGENT_WORKSPACE ?? session.workspace;
28153
- var stateDir = path14.join(dataDir, session.persistAgentState ? "state" : "state-session");
28154
- var claudeDir = path14.join(stateDir, "claude");
28189
+ var stateDir = path15.join(dataDir, session.persistAgentState ? "state" : "state-session");
28190
+ var claudeDir = path15.join(stateDir, "claude");
28155
28191
 
28156
28192
  // src/core/util/errors.ts
28157
28193
  function errMsg(e) {
@@ -28177,12 +28213,12 @@ function startRelays() {
28177
28213
  }
28178
28214
 
28179
28215
  // src/guest/audit/process-audit.ts
28180
- import fs13 from "node:fs";
28181
- import path16 from "node:path";
28216
+ import fs14 from "node:fs";
28217
+ import path17 from "node:path";
28182
28218
  import { spawnSync } from "node:child_process";
28183
28219
 
28184
28220
  // src/guest/audit/parse.ts
28185
- import path15 from "node:path";
28221
+ import path16 from "node:path";
28186
28222
  var NOISE = /* @__PURE__ */ new Set([
28187
28223
  "conhost.exe",
28188
28224
  "svchost.exe",
@@ -28243,7 +28279,7 @@ function parseProcessEvents(xml, attribution) {
28243
28279
  const pid = pidOf(field(event, "NewProcessId"));
28244
28280
  const ppid = pidOf(field(event, "ProcessId"));
28245
28281
  const session2 = attribution && pid && ppid ? attribution.attributor.attribute({ pid, ppid, t: Date.parse(t) || Date.now() }, attribution.roots) : void 0;
28246
- if (!program || NOISE.has(path15.win32.basename(program).toLowerCase())) continue;
28282
+ if (!program || NOISE.has(path16.win32.basename(program).toLowerCase())) continue;
28247
28283
  lines.push(
28248
28284
  JSON.stringify({
28249
28285
  t,
@@ -28259,19 +28295,19 @@ function parseProcessEvents(xml, attribution) {
28259
28295
  }
28260
28296
 
28261
28297
  // src/guest/runtime/fs.ts
28262
- import fs12 from "node:fs";
28298
+ import fs13 from "node:fs";
28263
28299
  function exists(p) {
28264
- return fs12.existsSync(p);
28300
+ return fs13.existsSync(p);
28265
28301
  }
28266
28302
  function mkdirp(p) {
28267
- fs12.mkdirSync(p, { recursive: true });
28303
+ fs13.mkdirSync(p, { recursive: true });
28268
28304
  return p;
28269
28305
  }
28270
28306
 
28271
28307
  // src/guest/audit/process-audit.ts
28272
28308
  var MAX_PER_PASS = 2e3;
28273
28309
  var auditOn = () => Boolean(session.auditProcesses) && isWin && !dryRun;
28274
- var wevtutil = () => path16.join(process.env.WINDIR ?? "C:\\Windows", "System32", "wevtutil.exe");
28310
+ var wevtutil = () => path17.join(process.env.WINDIR ?? "C:\\Windows", "System32", "wevtutil.exe");
28275
28311
  var newestRecord = () => {
28276
28312
  const r = spawnSync(wevtutil(), ["qe", "Security", "/q:*[System[(EventID=4688)]]", "/f:xml", "/c:1", "/rd:true"], {
28277
28313
  encoding: "utf8",
@@ -28299,8 +28335,8 @@ function startProcessCollector(roots = () => []) {
28299
28335
  const { lines, last: newest } = parseProcessEvents(r.stdout ?? "", { attributor, roots: roots() });
28300
28336
  if (newest) last = newest;
28301
28337
  if (lines.length)
28302
- fs13.writeFileSync(
28303
- path16.join(mkdirp(run.auditDir), Date.now() + "-" + process.pid + ".jsonl"),
28338
+ fs14.writeFileSync(
28339
+ path17.join(mkdirp(run.auditDir), Date.now() + "-" + process.pid + ".jsonl"),
28304
28340
  lines.join("\n") + "\n"
28305
28341
  );
28306
28342
  } catch (e) {
@@ -28311,14 +28347,14 @@ function startProcessCollector(roots = () => []) {
28311
28347
  }
28312
28348
 
28313
28349
  // src/guest/daemon/state.ts
28314
- import path17 from "node:path";
28350
+ import path18 from "node:path";
28315
28351
  var MAX_MESSAGE = 3500;
28316
28352
  function insidePrimary(cwd) {
28317
- const rel = path17.relative(workspace.toLowerCase(), path17.resolve(cwd).toLowerCase());
28318
- return rel === "" || !rel.startsWith("..") && !path17.isAbsolute(rel);
28353
+ const rel = path18.relative(workspace.toLowerCase(), path18.resolve(cwd).toLowerCase());
28354
+ return rel === "" || !rel.startsWith("..") && !path18.isAbsolute(rel);
28319
28355
  }
28320
28356
  function insideWorkspace(cwd) {
28321
- return insidePrimary(cwd) || session.projectsDir !== void 0 && insideProjects(path17.resolve(cwd), session.roots ?? [], session.projectsDir);
28357
+ return insidePrimary(cwd) || session.projectsDir !== void 0 && insideProjects(path18.resolve(cwd), session.roots ?? [], session.projectsDir);
28322
28358
  }
28323
28359
  function tryWrite(file3, value) {
28324
28360
  try {
@@ -28342,7 +28378,7 @@ function safely(what, work) {
28342
28378
  }
28343
28379
 
28344
28380
  // src/guest/runtime/secrets.ts
28345
- import fs14 from "node:fs";
28381
+ import fs15 from "node:fs";
28346
28382
 
28347
28383
  // src/shared/accounts/payloads.ts
28348
28384
  var KB = 1024;
@@ -28460,12 +28496,12 @@ function takeSecrets(id) {
28460
28496
  const file3 = run.secretFile(id);
28461
28497
  let text;
28462
28498
  try {
28463
- if (fs14.statSync(file3).size > MAX_BYTES) throw new Error("too big");
28464
- text = fs14.readFileSync(file3, "utf8").replace(/^\uFEFF/, "");
28499
+ if (fs15.statSync(file3).size > MAX_BYTES) throw new Error("too big");
28500
+ text = fs15.readFileSync(file3, "utf8").replace(/^\uFEFF/, "");
28465
28501
  } catch {
28466
28502
  return {};
28467
28503
  } finally {
28468
- fs14.rmSync(file3, { force: true });
28504
+ fs15.rmSync(file3, { force: true });
28469
28505
  }
28470
28506
  try {
28471
28507
  const parsed = SecretsFileSchema.safeParse(JSON.parse(text));
@@ -28501,22 +28537,22 @@ function withRequestSecrets(req) {
28501
28537
  }
28502
28538
 
28503
28539
  // src/guest/daemon/daemon.ts
28504
- import fs67 from "node:fs";
28540
+ import fs68 from "node:fs";
28505
28541
 
28506
28542
  // src/guest/setup/claude-mem.ts
28507
- import fs16 from "node:fs";
28543
+ import fs17 from "node:fs";
28508
28544
  import os4 from "node:os";
28509
- import path19 from "node:path";
28545
+ import path20 from "node:path";
28510
28546
 
28511
28547
  // src/guest/runtime/process.ts
28512
- import fs15 from "node:fs";
28548
+ import fs16 from "node:fs";
28513
28549
  import os3 from "node:os";
28514
- import path18 from "node:path";
28550
+ import path19 from "node:path";
28515
28551
  import { spawnSync as spawnSync2 } from "node:child_process";
28516
28552
  async function execAsync(file3, args, options = {}) {
28517
28553
  const code = await spawnAsync(file3, args, { stdio: "inherit", ...options });
28518
28554
  if (code !== 0)
28519
- throw new Error(path18.basename(file3) + " " + args.slice(0, 3).join(" ") + " failed with exit code " + code);
28555
+ throw new Error(path19.basename(file3) + " " + args.slice(0, 3).join(" ") + " failed with exit code " + code);
28520
28556
  }
28521
28557
  function execOutput(file3, args, options = {}) {
28522
28558
  const result = spawnSync2(file3, args, { encoding: "utf8", windowsHide: true, ...options });
@@ -28538,24 +28574,24 @@ function scriptOutput(name, args = [], options = {}) {
28538
28574
  return execOutput(SYSTEM.powershell(), scriptArgs(name, args), options);
28539
28575
  }
28540
28576
  function runScriptWithJson(name, param, data, args = []) {
28541
- const dir = fs15.mkdtempSync(path18.join(os3.tmpdir(), "sbx-"));
28542
- const file3 = path18.join(dir, "input.json");
28577
+ const dir = fs16.mkdtempSync(path19.join(os3.tmpdir(), "sbx-"));
28578
+ const file3 = path19.join(dir, "input.json");
28543
28579
  try {
28544
- fs15.writeFileSync(file3, JSON.stringify(data), "utf8");
28580
+ fs16.writeFileSync(file3, JSON.stringify(data), "utf8");
28545
28581
  runScript(name, ["-" + param, file3, ...args]);
28546
28582
  } finally {
28547
- fs15.rmSync(dir, { recursive: true, force: true });
28583
+ fs16.rmSync(dir, { recursive: true, force: true });
28548
28584
  }
28549
28585
  }
28550
28586
  function robocopy(from, to, files = []) {
28551
28587
  if (!isWin) {
28552
28588
  if (!files.length) {
28553
- fs15.cpSync(from, to, { recursive: true });
28589
+ fs16.cpSync(from, to, { recursive: true });
28554
28590
  return;
28555
28591
  }
28556
- fs15.mkdirSync(to, { recursive: true });
28557
- for (const f of files.filter((f2) => fs15.existsSync(path18.join(from, f2))))
28558
- fs15.copyFileSync(path18.join(from, f), path18.join(to, f));
28592
+ fs16.mkdirSync(to, { recursive: true });
28593
+ for (const f of files.filter((f2) => fs16.existsSync(path19.join(from, f2))))
28594
+ fs16.copyFileSync(path19.join(from, f), path19.join(to, f));
28559
28595
  return;
28560
28596
  }
28561
28597
  const what = files.length ? files : ["/E"];
@@ -28597,28 +28633,28 @@ function copyNode(from, to) {
28597
28633
  const work = stagingFolder(to);
28598
28634
  try {
28599
28635
  robocopy(from, work, ["node.exe", "npm", "npm.cmd", "npx", "npx.cmd"]);
28600
- robocopy(path18.join(from, "node_modules", "npm"), path18.join(work, "node_modules", "npm"));
28636
+ robocopy(path19.join(from, "node_modules", "npm"), path19.join(work, "node_modules", "npm"));
28601
28637
  moveIntoPlace(work, to);
28602
28638
  } finally {
28603
- safeRemove(work, path18.dirname(work));
28639
+ safeRemove(work, path19.dirname(work));
28604
28640
  }
28605
28641
  }
28606
28642
 
28607
28643
  // src/guest/setup/claude-mem.ts
28608
28644
  var claudeMemPaths = {
28609
- store: path19.join(stateDir, "claude-mem"),
28610
- local: path19.join(os4.homedir(), ".claude-mem")
28645
+ store: path20.join(stateDir, "claude-mem"),
28646
+ local: path20.join(os4.homedir(), ".claude-mem")
28611
28647
  };
28612
28648
  var claudeMemEnabled = () => session.claudeProfile.syncClaudeMem && !dryRun;
28613
28649
  var databaseFingerprint = (dir) => {
28614
28650
  const parts2 = [];
28615
28651
  const walk = (folder) => {
28616
- for (const entry of fs16.readdirSync(folder, { withFileTypes: true })) {
28617
- const full = path19.join(folder, entry.name);
28652
+ for (const entry of fs17.readdirSync(folder, { withFileTypes: true })) {
28653
+ const full = path20.join(folder, entry.name);
28618
28654
  if (entry.isDirectory()) walk(full);
28619
28655
  else if (entry.isFile() && /\.(db|sqlite3?)(-wal)?$/i.test(entry.name)) {
28620
28656
  try {
28621
- const s = fs16.statSync(full);
28657
+ const s = fs17.statSync(full);
28622
28658
  parts2.push(full + ":" + s.size + ":" + s.mtimeMs);
28623
28659
  } catch {
28624
28660
  }
@@ -28632,34 +28668,34 @@ var lastSaved = null;
28632
28668
  var SQLITE_HEADER = "SQLite format 3\0";
28633
28669
  var looksLikeSqlite = (file3) => {
28634
28670
  if (!exists(file3)) return true;
28635
- const fd = fs16.openSync(file3, "r");
28671
+ const fd = fs17.openSync(file3, "r");
28636
28672
  try {
28637
28673
  const head = Buffer.alloc(16);
28638
- return fs16.readSync(fd, head, 0, 16, 0) === 16 && head.toString("latin1") === SQLITE_HEADER;
28674
+ return fs17.readSync(fd, head, 0, 16, 0) === 16 && head.toString("latin1") === SQLITE_HEADER;
28639
28675
  } finally {
28640
- fs16.closeSync(fd);
28676
+ fs17.closeSync(fd);
28641
28677
  }
28642
28678
  };
28643
28679
  var MAX_BACKUPS = 3;
28644
28680
  var BACKUP_EVERY_MS = 6 * 3600 * 1e3;
28645
28681
  var keepBackup = (previous, dir) => {
28646
28682
  if (!exists(previous)) return;
28647
- const backups = exists(dir) ? fs16.readdirSync(dir).filter((n) => /^\d{13}$/.test(n)).sort() : [];
28683
+ const backups = exists(dir) ? fs17.readdirSync(dir).filter((n) => /^\d{13}$/.test(n)).sort() : [];
28648
28684
  const newest = Number(backups[backups.length - 1] ?? 0);
28649
28685
  if (Date.now() - newest < BACKUP_EVERY_MS) {
28650
- fs16.rmSync(previous, { recursive: true, force: true });
28686
+ fs17.rmSync(previous, { recursive: true, force: true });
28651
28687
  return;
28652
28688
  }
28653
- fs16.renameSync(previous, path19.join(mkdirp(dir), String(Date.now())));
28689
+ fs17.renameSync(previous, path20.join(mkdirp(dir), String(Date.now())));
28654
28690
  for (const old of [...backups, String(Date.now())].slice(0, -MAX_BACKUPS))
28655
- fs16.rmSync(path19.join(dir, old), { recursive: true, force: true });
28691
+ fs17.rmSync(path20.join(dir, old), { recursive: true, force: true });
28656
28692
  };
28657
28693
  function saveClaudeMem() {
28658
28694
  if (!claudeMemEnabled() || !exists(claudeMemPaths.local)) return;
28659
28695
  const { store: store2, local } = claudeMemPaths;
28660
28696
  const fingerprint3 = databaseFingerprint(local);
28661
28697
  if (fingerprint3 === lastSaved && exists(store2)) return;
28662
- if (!looksLikeSqlite(path19.join(local, "claude-mem.db"))) {
28698
+ if (!looksLikeSqlite(path20.join(local, "claude-mem.db"))) {
28663
28699
  warn(
28664
28700
  "claude-mem: the local database does not look valid, so it was not saved over the stored copy (" + local + ")."
28665
28701
  );
@@ -28667,14 +28703,14 @@ function saveClaudeMem() {
28667
28703
  }
28668
28704
  const incoming = store2 + ".incoming";
28669
28705
  const previous = store2 + ".previous";
28670
- fs16.rmSync(incoming, { recursive: true, force: true });
28706
+ fs17.rmSync(incoming, { recursive: true, force: true });
28671
28707
  copyTreeTolerant(local, incoming, (name) => /\.(pid|lock)$|-journal$|-shm$/i.test(name));
28672
- fs16.rmSync(previous, { recursive: true, force: true });
28673
- if (exists(store2)) fs16.renameSync(store2, previous);
28708
+ fs17.rmSync(previous, { recursive: true, force: true });
28709
+ if (exists(store2)) fs17.renameSync(store2, previous);
28674
28710
  try {
28675
- fs16.renameSync(incoming, store2);
28711
+ fs17.renameSync(incoming, store2);
28676
28712
  } catch (e) {
28677
- if (exists(previous)) fs16.renameSync(previous, store2);
28713
+ if (exists(previous)) fs17.renameSync(previous, store2);
28678
28714
  throw e;
28679
28715
  }
28680
28716
  keepBackup(previous, store2 + ".backups");
@@ -28682,18 +28718,18 @@ function saveClaudeMem() {
28682
28718
  }
28683
28719
 
28684
28720
  // src/guest/agents/local-state.ts
28685
- import fs17 from "node:fs";
28686
- import path21 from "node:path";
28721
+ import fs18 from "node:fs";
28722
+ import path22 from "node:path";
28687
28723
 
28688
28724
  // src/guest/agents/agent-files.ts
28689
- import path20 from "node:path";
28725
+ import path21 from "node:path";
28690
28726
  function agentPaths(toolsDir2, name, harness) {
28691
- const dir = path20.join(toolsDir2, "agents", name);
28727
+ const dir = path21.join(toolsDir2, "agents", name);
28692
28728
  const exe = harness.hostExecutable ?? (harness.uvBin ? harness.uvBin + ".exe" : null);
28693
28729
  return {
28694
28730
  dir,
28695
- exe: exe ? path20.join(dir, exe) : null,
28696
- cmd: harness.npmBin ? path20.join(dir, harness.npmBin + ".cmd") : null
28731
+ exe: exe ? path21.join(dir, exe) : null,
28732
+ cmd: harness.npmBin ? path21.join(dir, harness.npmBin + ".cmd") : null
28697
28733
  };
28698
28734
  }
28699
28735
  function agentCommand(name, harness) {
@@ -28704,51 +28740,66 @@ function localStateEntries(agents2, stateDir3, localRoot2) {
28704
28740
  ([agent, harness]) => Object.entries(harness.localState ?? {}).map(([env, folder]) => ({
28705
28741
  agent,
28706
28742
  env,
28707
- store: path20.join(stateDir3, agent, folder),
28708
- local: path20.join(localRoot2, agent, folder),
28743
+ store: path21.join(stateDir3, agent, folder),
28744
+ local: path21.join(localRoot2, agent, folder),
28709
28745
  processes: [agentCommand(agent, harness) + ".exe"],
28710
- legacy: path20.join(stateDir3, agent)
28746
+ legacy: path21.join(stateDir3, agent)
28711
28747
  }))
28712
28748
  );
28713
28749
  }
28750
+ var CODEX_MARKER = "# Set by the sandbox";
28751
+ function codexArguments(c) {
28752
+ const out = c.sandboxMode === "danger-full-access" && c.approvalPolicy === "never" ? ["--dangerously-bypass-approvals-and-sandbox"] : ["--sandbox", c.sandboxMode, "--ask-for-approval", c.approvalPolicy];
28753
+ if (c.model) out.push("-c", 'model="' + c.model + '"');
28754
+ if (c.reasoningEffort !== "default") out.push("-c", 'model_reasoning_effort="' + c.reasoningEffort + '"');
28755
+ return out;
28756
+ }
28757
+ function agentArguments(name, harness, codex) {
28758
+ return name === "codex" && codex ? [...harness.arguments, ...codexArguments(codex)] : [...harness.arguments];
28759
+ }
28760
+ var MAX_CODEX_CONFIG_BYTES = 1024 * 1024;
28761
+ var MARKED_LINES = new RegExp(
28762
+ "^" + CODEX_MARKER + "[^\r\n]*\r?\n(?:(?:sandbox_mode|approval_policy)[ ]*=[^\r\n]*\r?\n)*(?:[ ]*\r?\n)?",
28763
+ "m"
28764
+ );
28714
28765
  var isDatabaseFile = (name) => /\.(sqlite3?|db)(-wal|-shm)?$/i.test(name);
28715
28766
  var isCopyableDatabaseFile = (name) => isDatabaseFile(name) && !/-shm$/i.test(name);
28716
28767
 
28717
28768
  // src/guest/agents/local-state.ts
28718
28769
  var SQLITE_HEADER2 = "SQLite format 3\0";
28719
- var localRoot = () => path21.join(localDir, "agent-state");
28770
+ var localRoot = () => path22.join(localDir, "agent-state");
28720
28771
  function agentLocalStates() {
28721
28772
  return localStateEntries(session.agents ?? {}, stateDir, localRoot());
28722
28773
  }
28723
28774
  function localStateVars() {
28724
28775
  return Object.fromEntries(agentLocalStates().map((s) => [s.env, s.local]));
28725
28776
  }
28726
- var databaseFiles = (dir, keep) => exists(dir) ? fs17.readdirSync(dir, { withFileTypes: true }).flatMap((e) => e.isFile() && keep(e.name) ? [e.name] : []) : [];
28777
+ var databaseFiles = (dir, keep) => exists(dir) ? fs18.readdirSync(dir, { withFileTypes: true }).flatMap((e) => e.isFile() && keep(e.name) ? [e.name] : []) : [];
28727
28778
  var looksLikeSqlite2 = (file3) => {
28728
- const fd = fs17.openSync(file3, "r");
28779
+ const fd = fs18.openSync(file3, "r");
28729
28780
  try {
28730
28781
  const head = Buffer.alloc(16);
28731
- return fs17.readSync(fd, head, 0, 16, 0) === 16 && head.toString("latin1") === SQLITE_HEADER2;
28782
+ return fs18.readSync(fd, head, 0, 16, 0) === 16 && head.toString("latin1") === SQLITE_HEADER2;
28732
28783
  } finally {
28733
- fs17.closeSync(fd);
28784
+ fs18.closeSync(fd);
28734
28785
  }
28735
28786
  };
28736
28787
  var copyFiles = (from, to, names) => {
28737
- fs17.rmSync(to, { recursive: true, force: true });
28788
+ fs18.rmSync(to, { recursive: true, force: true });
28738
28789
  mkdirp(to);
28739
- for (const name of names) fs17.copyFileSync(path21.join(from, name), path21.join(to, name));
28790
+ for (const name of names) fs18.copyFileSync(path22.join(from, name), path22.join(to, name));
28740
28791
  };
28741
28792
  var swapIn = (incoming, store2) => {
28742
28793
  const previous = store2 + ".previous";
28743
- fs17.rmSync(previous, { recursive: true, force: true });
28744
- if (exists(store2)) fs17.renameSync(store2, previous);
28794
+ fs18.rmSync(previous, { recursive: true, force: true });
28795
+ if (exists(store2)) fs18.renameSync(store2, previous);
28745
28796
  try {
28746
- fs17.renameSync(incoming, store2);
28797
+ fs18.renameSync(incoming, store2);
28747
28798
  } catch (e) {
28748
- if (exists(previous)) fs17.renameSync(previous, store2);
28799
+ if (exists(previous)) fs18.renameSync(previous, store2);
28749
28800
  throw e;
28750
28801
  }
28751
- fs17.rmSync(previous, { recursive: true, force: true });
28802
+ fs18.rmSync(previous, { recursive: true, force: true });
28752
28803
  };
28753
28804
  function held(s) {
28754
28805
  if (!isWin) return false;
@@ -28757,7 +28808,7 @@ function held(s) {
28757
28808
  );
28758
28809
  }
28759
28810
  var fingerprint = (dir) => databaseFiles(dir, isCopyableDatabaseFile).sort().map((n) => {
28760
- const st = fs17.statSync(path21.join(dir, n));
28811
+ const st = fs18.statSync(path22.join(dir, n));
28761
28812
  return n + ":" + st.size + ":" + st.mtimeMs;
28762
28813
  }).join("|");
28763
28814
  var saved = /* @__PURE__ */ new Map();
@@ -28776,12 +28827,12 @@ function snapshotWhileRunning(s, print) {
28776
28827
  return;
28777
28828
  }
28778
28829
  const incoming = s.store + ".incoming";
28779
- fs17.rmSync(incoming, { recursive: true, force: true });
28830
+ fs18.rmSync(incoming, { recursive: true, force: true });
28780
28831
  mkdirp(incoming);
28781
28832
  for (const name of databaseFiles(s.local, (n) => isCopyableDatabaseFile(n) && !/-wal$/i.test(n))) {
28782
- const db = new sqlite.DatabaseSync(path21.join(s.local, name), { readOnly: true });
28833
+ const db = new sqlite.DatabaseSync(path22.join(s.local, name), { readOnly: true });
28783
28834
  try {
28784
- await sqlite.backup(db, path21.join(incoming, name));
28835
+ await sqlite.backup(db, path22.join(incoming, name));
28785
28836
  } finally {
28786
28837
  db.close();
28787
28838
  }
@@ -28807,7 +28858,7 @@ function saveLocalState() {
28807
28858
  continue;
28808
28859
  }
28809
28860
  const names = databaseFiles(s.local, isCopyableDatabaseFile);
28810
- const bad = names.filter((n) => !/-wal$/i.test(n) && !looksLikeSqlite2(path21.join(s.local, n)));
28861
+ const bad = names.filter((n) => !/-wal$/i.test(n) && !looksLikeSqlite2(path22.join(s.local, n)));
28811
28862
  if (bad.length) {
28812
28863
  warn(s.agent + ": " + bad.join(", ") + " do not look like SQLite databases, so they were not saved.");
28813
28864
  continue;
@@ -28826,10 +28877,10 @@ function saveLocalState() {
28826
28877
  import { spawn as spawn6 } from "node:child_process";
28827
28878
 
28828
28879
  // src/guest/setup/environment.ts
28829
- import path23 from "node:path";
28880
+ import path24 from "node:path";
28830
28881
 
28831
28882
  // src/guest/setup/path-plan.ts
28832
- import path22 from "node:path";
28883
+ import path23 from "node:path";
28833
28884
  function pathKey(folder) {
28834
28885
  const slashes = folder.trim().replace(/^"|"$/g, "").replace(/\//g, "\\");
28835
28886
  return (slashes.length > 3 ? slashes.replace(/\\+$/, "") : slashes).toLowerCase();
@@ -28869,13 +28920,13 @@ function parseRegPath(output2) {
28869
28920
  function isPinnedNodeDir(folder, nvmHome2) {
28870
28921
  const key2 = pathKey(folder);
28871
28922
  const home = pathKey(nvmHome2);
28872
- return key2.startsWith(home + "\\") && /^v\d/.test(path22.win32.basename(key2));
28923
+ return key2.startsWith(home + "\\") && /^v\d/.test(path23.win32.basename(key2));
28873
28924
  }
28874
28925
 
28875
28926
  // src/guest/setup/environment.ts
28876
28927
  var LEGACY_HOMES = { CODEX_HOME: "codex", GEMINI_CLI_HOME: "gemini" };
28877
28928
  var agentHomes = () => Object.fromEntries(
28878
- Object.entries(session.agentHomes ?? LEGACY_HOMES).filter(([name]) => name !== "CLAUDE_CONFIG_DIR").map(([name, sub]) => [name, path23.join(stateDir, sub)])
28929
+ Object.entries(session.agentHomes ?? LEGACY_HOMES).filter(([name]) => name !== "CLAUDE_CONFIG_DIR").map(([name, sub]) => [name, path24.join(stateDir, sub)])
28879
28930
  );
28880
28931
  function agentEnv(tools, target = { workspace, project: session.project, base: process.env }) {
28881
28932
  const homes = agentHomes();
@@ -28885,7 +28936,7 @@ function agentEnv(tools, target = { workspace, project: session.project, base: p
28885
28936
  CLAUDE_CONFIG_DIR: claudeDir,
28886
28937
  ...homes,
28887
28938
  ...localStateVars(),
28888
- npm_config_cache: path23.join(toolsDir, "npm-cache"),
28939
+ npm_config_cache: path24.join(toolsDir, "npm-cache"),
28889
28940
  npm_config_update_notifier: "false",
28890
28941
  AGENT_WORKSPACE: target.workspace,
28891
28942
  AGENT_DATA: dataDir,
@@ -28903,9 +28954,9 @@ function agentEnv(tools, target = { workspace, project: session.project, base: p
28903
28954
  ...local.map((n) => env[n])
28904
28955
  ])
28905
28956
  mkdirp(dir);
28906
- const runners = [path23.join(toolsDir, "node"), path23.dirname(process.execPath)].map((d) => d.toLowerCase());
28907
- const base = (target.base.PATH ?? "").split(path23.delimiter).filter((d) => d && !runners.includes(d.toLowerCase()));
28908
- env.PATH = [.../* @__PURE__ */ new Set([...tools.prepend, ...base, ...tools.append])].join(path23.delimiter);
28957
+ const runners = [path24.join(toolsDir, "node"), path24.dirname(process.execPath)].map((d) => d.toLowerCase());
28958
+ const base = (target.base.PATH ?? "").split(path24.delimiter).filter((d) => d && !runners.includes(d.toLowerCase()));
28959
+ env.PATH = [.../* @__PURE__ */ new Set([...tools.prepend, ...base, ...tools.append])].join(path24.delimiter);
28909
28960
  return env;
28910
28961
  }
28911
28962
  function addMachineEnvironment(vars, dirs, additive = false) {
@@ -28917,7 +28968,7 @@ function addMachineEnvironment(vars, dirs, additive = false) {
28917
28968
  warn("Could not add to the environment: " + errMsg(e));
28918
28969
  }
28919
28970
  }
28920
- var nvmHome = () => path23.join(toolsDir, "nvm");
28971
+ var nvmHome = () => path24.join(toolsDir, "nvm");
28921
28972
  var MACHINE_ENVIRONMENT_KEY = "HKLM\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment";
28922
28973
  var USER_ENVIRONMENT_KEY = "HKCU\\Environment";
28923
28974
  var registryPath = (key2) => parseRegPath(execOutput(SYSTEM.reg(), ["query", key2, "/v", "Path"]));
@@ -28925,7 +28976,7 @@ function withRegistryPath(env) {
28925
28976
  if (!isWin || dryRun || testMode) return env;
28926
28977
  try {
28927
28978
  const registry2 = expandVars(registryPath(MACHINE_ENVIRONMENT_KEY) + ";" + registryPath(USER_ENVIRONMENT_KEY), env);
28928
- const runner = pathKey(path23.join(toolsDir, "node"));
28979
+ const runner = pathKey(path24.join(toolsDir, "node"));
28929
28980
  const pathName = Object.keys(env).find((k) => k.toLowerCase() === "path") ?? "PATH";
28930
28981
  return {
28931
28982
  ...env,
@@ -28942,12 +28993,12 @@ function withRegistryPath(env) {
28942
28993
  }
28943
28994
 
28944
28995
  // src/guest/daemon/project-provisioner.ts
28945
- import fs57 from "node:fs";
28946
- import path71 from "node:path";
28996
+ import fs58 from "node:fs";
28997
+ import path74 from "node:path";
28947
28998
 
28948
28999
  // src/guest/boot/boot-env.ts
28949
- import fs18 from "node:fs";
28950
- import path24 from "node:path";
29000
+ import fs19 from "node:fs";
29001
+ import path25 from "node:path";
28951
29002
 
28952
29003
  // src/guest/boot/project-env.ts
28953
29004
  var EnvSchema = external_exports.object({
@@ -28977,28 +29028,28 @@ function baseEnvFor(boot, current = process.env) {
28977
29028
  }
28978
29029
 
28979
29030
  // src/guest/boot/boot-env.ts
28980
- var file2 = () => path24.join(localDir, "boot-env.json");
29031
+ var file2 = () => path25.join(localDir, "boot-env.json");
28981
29032
  function readBootEnv() {
28982
29033
  try {
28983
- return BootEnvSchema.safeParse(JSON.parse(fs18.readFileSync(file2(), "utf8"))).data ?? null;
29034
+ return BootEnvSchema.safeParse(JSON.parse(fs19.readFileSync(file2(), "utf8"))).data ?? null;
28984
29035
  } catch {
28985
29036
  return null;
28986
29037
  }
28987
29038
  }
28988
29039
 
28989
29040
  // src/guest/boot/guide.ts
28990
- import fs20 from "node:fs";
28991
- import path27 from "node:path";
29041
+ import fs21 from "node:fs";
29042
+ import path28 from "node:path";
28992
29043
 
28993
29044
  // src/guest/apps/find-exe.ts
28994
- import fs19 from "node:fs";
28995
- import path25 from "node:path";
29045
+ import fs20 from "node:fs";
29046
+ import path26 from "node:path";
28996
29047
  var MAX_DEPTH = 7;
28997
29048
  var MAX_ENTRIES = 5e4;
28998
29049
  var X64_FOLDER = /(^|[\\/])(amd64|x64|x86_64|win64)([\\/]|$)/i;
28999
29050
  function findExe(root, exe) {
29000
29051
  const match = exeMatcher(exe);
29001
- const best = (hits) => hits.find((h) => X64_FOLDER.test(path25.relative(root, h))) ?? hits[0] ?? null;
29052
+ const best = (hits) => hits.find((h) => X64_FOLDER.test(path26.relative(root, h))) ?? hits[0] ?? null;
29002
29053
  let queue = [root];
29003
29054
  let seen = 0;
29004
29055
  for (let depth = 0; depth < MAX_DEPTH && queue.length; depth++) {
@@ -29007,14 +29058,14 @@ function findExe(root, exe) {
29007
29058
  for (const dir of queue) {
29008
29059
  let entries2;
29009
29060
  try {
29010
- entries2 = fs19.readdirSync(dir, { withFileTypes: true });
29061
+ entries2 = fs20.readdirSync(dir, { withFileTypes: true });
29011
29062
  } catch {
29012
29063
  continue;
29013
29064
  }
29014
29065
  const hit = entries2.find((e) => e.isFile() && match(e.name));
29015
- if (hit) hits.push(path25.join(dir, hit.name));
29066
+ if (hit) hits.push(path26.join(dir, hit.name));
29016
29067
  else
29017
- next.push(...entries2.filter((e) => e.isDirectory() && !e.isSymbolicLink()).map((e) => path25.join(dir, e.name)));
29068
+ next.push(...entries2.filter((e) => e.isDirectory() && !e.isSymbolicLink()).map((e) => path26.join(dir, e.name)));
29018
29069
  if ((seen += entries2.length) > MAX_ENTRIES) return best(hits);
29019
29070
  }
29020
29071
  if (hits.length) return best(hits);
@@ -29024,13 +29075,13 @@ function findExe(root, exe) {
29024
29075
  }
29025
29076
 
29026
29077
  // src/guest/toolchains/tool-env.ts
29027
- import path26 from "node:path";
29078
+ import path27 from "node:path";
29028
29079
  function emptyEnv() {
29029
29080
  return { vars: {}, prepend: [], append: [], summary: [] };
29030
29081
  }
29031
29082
  var arch = process.arch === "arm64" ? "arm64" : "x64";
29032
29083
  function tool(...parts2) {
29033
- return path26.join(toolsDir, ...parts2);
29084
+ return path27.join(toolsDir, ...parts2);
29034
29085
  }
29035
29086
  function versionOf(exe, args = ["--version"], options = {}) {
29036
29087
  return /\d+\.\d+\.\d+\S*/.exec(execOutput(exe, args, options))?.[0] ?? "installed";
@@ -29050,7 +29101,7 @@ function installedRtk() {
29050
29101
  var BEGIN = "<!-- agent-sandbox:begin (generated every boot, do not edit) -->";
29051
29102
  var END = "<!-- agent-sandbox:end -->";
29052
29103
  var mirrorLine = () => {
29053
- const drives = (session.substDrives ?? []).filter((d) => fs20.existsSync(d.letter + ":\\"));
29104
+ const drives = (session.substDrives ?? []).filter((d) => fs21.existsSync(d.letter + ":\\"));
29054
29105
  if (!drives.length) return [];
29055
29106
  return [
29056
29107
  "- " + 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)."
@@ -29066,8 +29117,8 @@ function sandboxGuide(toolSummary, lan = "blocked", projects = [], addons = [])
29066
29117
  ...projects.map(
29067
29118
  (p) => "- RW, persists: `" + p.guest + "` = host folder " + p.host + " (another project in this sandbox; your own is `%AGENT_WORKSPACE%`)"
29068
29119
  ),
29069
- "- RW, persists: `" + toolsDir + "` (toolchains) \u2014 put portable exes in `" + path27.join(toolsDir, "bin") + "` (on PATH)",
29070
- "- RW, persists: `" + stateDir + "` (agent config/history; do not edit logins) \xB7 logs: `" + path27.join(dataDir, "logs") + "`",
29120
+ "- RW, persists: `" + toolsDir + "` (toolchains) \u2014 put portable exes in `" + path28.join(toolsDir, "bin") + "` (on PATH)",
29121
+ "- RW, persists: `" + stateDir + "` (agent config/history; do not edit logins) \xB7 logs: `" + path28.join(dataDir, "logs") + "`",
29071
29122
  "- RO: `" + launchDir + "` (this boot's scripts) \xB7 lost on close: everything else, incl. `C:\\nvm` (Node symlink)",
29072
29123
  ...mirrorLine(),
29073
29124
  "- Tools: " + toolSummary.join(" \xB7 "),
@@ -29080,23 +29131,23 @@ function sandboxGuide(toolSummary, lan = "blocked", projects = [], addons = [])
29080
29131
  ].join("\n");
29081
29132
  }
29082
29133
  function upsertGuide(file3, guide) {
29083
- fs20.mkdirSync(path27.dirname(file3), { recursive: true });
29084
- const current = fs20.existsSync(file3) ? fs20.readFileSync(file3, "utf8") : "";
29134
+ fs21.mkdirSync(path28.dirname(file3), { recursive: true });
29135
+ const current = fs21.existsSync(file3) ? fs21.readFileSync(file3, "utf8") : "";
29085
29136
  const start = current.indexOf(BEGIN);
29086
29137
  const end = current.indexOf(END);
29087
29138
  const without = start >= 0 && end > start ? current.slice(0, start) + current.slice(end + END.length) : current;
29088
- fs20.writeFileSync(file3, without.trimEnd() + (without.trim() ? "\n\n" : "") + guide + "\n", "utf8");
29139
+ fs21.writeFileSync(file3, without.trimEnd() + (without.trim() ? "\n\n" : "") + guide + "\n", "utf8");
29089
29140
  }
29090
29141
  function managedClaudeMd() {
29091
- return path27.join(
29092
- process.env.AGENT_MANAGED_DIR ?? path27.join(process.env.ProgramFiles ?? "C:\\Program Files", "ClaudeCode"),
29142
+ return path28.join(
29143
+ process.env.AGENT_MANAGED_DIR ?? path28.join(process.env.ProgramFiles ?? "C:\\Program Files", "ClaudeCode"),
29093
29144
  "CLAUDE.md"
29094
29145
  );
29095
29146
  }
29096
29147
  var headroomRuns = () => {
29097
29148
  try {
29098
- const file3 = path27.join(path27.dirname(managedClaudeMd()), "managed-settings.json");
29099
- const settings = JSON.parse(fs20.readFileSync(file3, "utf8"));
29149
+ const file3 = path28.join(path28.dirname(managedClaudeMd()), "managed-settings.json");
29150
+ const settings = JSON.parse(fs21.readFileSync(file3, "utf8"));
29100
29151
  return typeof settings.env?.ANTHROPIC_BASE_URL === "string";
29101
29152
  } catch {
29102
29153
  return false;
@@ -29106,28 +29157,28 @@ function addonLines() {
29106
29157
  const mcp = APPS.flatMap((a) => a.mcp && installedAddon(a.id) ? [a.mcp.name] : []);
29107
29158
  return [
29108
29159
  ...installedRtk() ? [RTK_GUIDE_LINE] : [],
29109
- ...installedAddon("headroom") && headroomRuns() ? [headroomGuideLine(path27.join(logsDir, "headroom.log"))] : [],
29160
+ ...installedAddon("headroom") && headroomRuns() ? [headroomGuideLine(path28.join(logsDir, "headroom.log"))] : [],
29110
29161
  ...addonGuideLine(mcp, Boolean(installedAddon("ccusage")))
29111
29162
  ];
29112
29163
  }
29113
29164
  function writeGuides(toolSummary, lan, projects = []) {
29114
29165
  const guide = sandboxGuide(toolSummary, lan, projects, addonLines());
29115
29166
  const managed = managedClaudeMd();
29116
- fs20.mkdirSync(path27.dirname(managed), { recursive: true });
29117
- fs20.writeFileSync(managed, guide + "\n", "utf8");
29118
- fs20.writeFileSync(path27.join(dataDir, "SANDBOX.md"), guide + "\n", "utf8");
29119
- upsertGuide(path27.join(stateDir, "codex", "AGENTS.md"), guide);
29120
- upsertGuide(path27.join(stateDir, "gemini", ".gemini", "GEMINI.md"), guide);
29121
- removeGuide(path27.join(claudeDir, "CLAUDE.md"));
29167
+ fs21.mkdirSync(path28.dirname(managed), { recursive: true });
29168
+ fs21.writeFileSync(managed, guide + "\n", "utf8");
29169
+ fs21.writeFileSync(path28.join(dataDir, "SANDBOX.md"), guide + "\n", "utf8");
29170
+ upsertGuide(path28.join(stateDir, "codex", "AGENTS.md"), guide);
29171
+ upsertGuide(path28.join(stateDir, "gemini", ".gemini", "GEMINI.md"), guide);
29172
+ removeGuide(path28.join(claudeDir, "CLAUDE.md"));
29122
29173
  return managed;
29123
29174
  }
29124
29175
  var removeGuide = (file3) => {
29125
- if (!fs20.existsSync(file3)) return;
29126
- const current = fs20.readFileSync(file3, "utf8");
29176
+ if (!fs21.existsSync(file3)) return;
29177
+ const current = fs21.readFileSync(file3, "utf8");
29127
29178
  const start = current.indexOf(BEGIN);
29128
29179
  const end = current.indexOf(END);
29129
29180
  if (start >= 0 && end > start)
29130
- fs20.writeFileSync(file3, (current.slice(0, start) + current.slice(end + END.length)).trim() + "\n", "utf8");
29181
+ fs21.writeFileSync(file3, (current.slice(0, start) + current.slice(end + END.length)).trim() + "\n", "utf8");
29131
29182
  };
29132
29183
 
29133
29184
  // src/guest/runtime/project-context.ts
@@ -29164,11 +29215,11 @@ function saveProjectStatus(name, workspace2, phase, message, databases, summary)
29164
29215
  }
29165
29216
 
29166
29217
  // src/guest/setup/hooks.ts
29167
- import fs21 from "node:fs";
29168
- import path28 from "node:path";
29218
+ import fs22 from "node:fs";
29219
+ import path29 from "node:path";
29169
29220
  import { spawnSync as spawnSync3 } from "node:child_process";
29170
29221
  var commandFor = (file3) => {
29171
- const ext = path28.extname(file3).toLowerCase();
29222
+ const ext = path29.extname(file3).toLowerCase();
29172
29223
  if (ext === ".mjs" || ext === ".js") return [process.execPath, [file3]];
29173
29224
  if (!isWin) return null;
29174
29225
  if (ext === ".ps1")
@@ -29176,18 +29227,18 @@ var commandFor = (file3) => {
29176
29227
  if (ext === ".cmd" || ext === ".bat") return [SYSTEM.cmd(), ["/d", "/c", file3]];
29177
29228
  return null;
29178
29229
  };
29179
- var BOOT = { root: path28.join(launchDir, "hooks"), cwd: workspace };
29230
+ var BOOT = { root: path29.join(launchDir, "hooks"), cwd: workspace };
29180
29231
  function projectHooks(name, cwd) {
29181
29232
  return {
29182
- root: path28.join(launchDir, "projects", name, "hooks"),
29233
+ root: path29.join(launchDir, "projects", name, "hooks"),
29183
29234
  cwd
29184
29235
  };
29185
29236
  }
29186
29237
  var hooksOf = (stage, target) => {
29187
- const dir = path28.join(target.root, stage);
29238
+ const dir = path29.join(target.root, stage);
29188
29239
  if (!exists(dir)) return [];
29189
- return fs21.readdirSync(dir).sort().flatMap((name) => {
29190
- const command = commandFor(path28.join(dir, name));
29240
+ return fs22.readdirSync(dir).sort().flatMap((name) => {
29241
+ const command = commandFor(path29.join(dir, name));
29191
29242
  return command ? [{ name, command }] : [];
29192
29243
  });
29193
29244
  };
@@ -29217,22 +29268,22 @@ async function runHooksAsync(stage, env, target) {
29217
29268
  }
29218
29269
 
29219
29270
  // src/guest/apps/app-installer.ts
29220
- import fs25 from "node:fs";
29221
- import path33 from "node:path";
29271
+ import fs26 from "node:fs";
29272
+ import path34 from "node:path";
29222
29273
 
29223
29274
  // src/guest/toolchains/runtimes.ts
29224
- import path29 from "node:path";
29275
+ import path30 from "node:path";
29225
29276
 
29226
29277
  // src/guest/toolchains/install.ts
29227
- import fs22 from "node:fs";
29278
+ import fs23 from "node:fs";
29228
29279
  async function downloadFile(url2, file3, sha256 = null) {
29229
29280
  const part = file3 + ".part";
29230
29281
  try {
29231
29282
  await downloader.file(url2, part, sha256);
29232
- fs22.rmSync(file3, { force: true });
29233
- fs22.renameSync(part, file3);
29283
+ fs23.rmSync(file3, { force: true });
29284
+ fs23.renameSync(part, file3);
29234
29285
  } finally {
29235
- fs22.rmSync(part, { force: true });
29286
+ fs23.rmSync(part, { force: true });
29236
29287
  }
29237
29288
  }
29238
29289
  async function installFromGithub(repo, pattern, o) {
@@ -29252,8 +29303,8 @@ async function setupSingleExe(env, name, repo, pattern, exeName, dir, options =
29252
29303
  log("(dry run) would provision " + name);
29253
29304
  return;
29254
29305
  }
29255
- const bin = options.subdir ? path29.join(dir, options.subdir) : dir;
29256
- const exe = path29.join(bin, exeName);
29306
+ const bin = options.subdir ? path30.join(dir, options.subdir) : dir;
29307
+ const exe = path30.join(bin, exeName);
29257
29308
  if (!exists(exe) || options.refresh) {
29258
29309
  const size = options.size ? ", ~" + options.size : "";
29259
29310
  await installFromGithub(repo, pattern, {
@@ -29278,8 +29329,8 @@ async function setupBun(env) {
29278
29329
  );
29279
29330
  Object.assign(env.vars, {
29280
29331
  BUN_INSTALL: tool("bun"),
29281
- BUN_INSTALL_CACHE_DIR: path29.join(localDir, "bun-cache"),
29282
- BUN_TMPDIR: path29.join(localDir, "bun-tmp")
29332
+ BUN_INSTALL_CACHE_DIR: path30.join(localDir, "bun-cache"),
29333
+ BUN_TMPDIR: path30.join(localDir, "bun-tmp")
29283
29334
  });
29284
29335
  }
29285
29336
  async function setupDeno(env) {
@@ -29317,8 +29368,8 @@ async function setupUv(env) {
29317
29368
  }
29318
29369
 
29319
29370
  // src/guest/apps/after-install.ts
29320
- import fs23 from "node:fs";
29321
- import path30 from "node:path";
29371
+ import fs24 from "node:fs";
29372
+ import path31 from "node:path";
29322
29373
  var SYSINTERNALS_TOOLS = [
29323
29374
  "Process Explorer",
29324
29375
  "Process Monitor",
@@ -29339,16 +29390,16 @@ var SYSINTERNALS_TOOLS = [
29339
29390
  "ZoomIt"
29340
29391
  ];
29341
29392
  async function afterInstall(entry, exe) {
29342
- const dir = path30.dirname(exe);
29393
+ const dir = path31.dirname(exe);
29343
29394
  if (entry.needs?.includes("mesa")) {
29344
29395
  const mesa = tool("mesa", arch === "arm64" ? "arm64" : "x64");
29345
29396
  for (const dll of ["opengl32.dll", "libgallium_wgl.dll", "dxil.dll"]) {
29346
- if (exists(path30.join(mesa, dll)) && !exists(path30.join(dir, dll)))
29347
- fs23.copyFileSync(path30.join(mesa, dll), path30.join(dir, dll));
29397
+ if (exists(path31.join(mesa, dll)) && !exists(path31.join(dir, dll)))
29398
+ fs24.copyFileSync(path31.join(mesa, dll), path31.join(dir, dll));
29348
29399
  }
29349
29400
  }
29350
- if (entry.id === "godot" && !exists(path30.join(dir, "._sc_"))) fs23.writeFileSync(path30.join(dir, "._sc_"), "");
29351
- if (entry.id === "sublime") mkdirp(path30.join(dir, "Data"));
29401
+ if (entry.id === "godot" && !exists(path31.join(dir, "._sc_"))) fs24.writeFileSync(path31.join(dir, "._sc_"), "");
29402
+ if (entry.id === "sublime") mkdirp(path31.join(dir, "Data"));
29352
29403
  if (entry.id === "sysinternals") {
29353
29404
  for (const name of SYSINTERNALS_TOOLS) {
29354
29405
  await execAsync(
@@ -29362,12 +29413,12 @@ async function afterInstall(entry, exe) {
29362
29413
 
29363
29414
  // src/guest/apps/shortcuts.ts
29364
29415
  import os5 from "node:os";
29365
- import path31 from "node:path";
29416
+ import path32 from "node:path";
29366
29417
  function shortcuts(apps) {
29367
29418
  if (!apps.length) return;
29368
- const desktop = path31.join(os5.homedir(), "Desktop");
29369
- const start = path31.join(
29370
- process.env.APPDATA ?? path31.join(os5.homedir(), "AppData", "Roaming"),
29419
+ const desktop = path32.join(os5.homedir(), "Desktop");
29420
+ const start = path32.join(
29421
+ process.env.APPDATA ?? path32.join(os5.homedir(), "AppData", "Roaming"),
29371
29422
  "Microsoft",
29372
29423
  "Windows",
29373
29424
  "Start Menu",
@@ -29377,9 +29428,9 @@ function shortcuts(apps) {
29377
29428
  const links = apps.flatMap((app) => {
29378
29429
  const name = app.name.replace(/[\\/:*?"<>|]/g, "");
29379
29430
  return [desktop, start].map((folder) => ({
29380
- link: path31.join(folder, name + ".lnk"),
29431
+ link: path32.join(folder, name + ".lnk"),
29381
29432
  target: app.exe,
29382
- workingDirectory: path31.dirname(app.exe)
29433
+ workingDirectory: path32.dirname(app.exe)
29383
29434
  }));
29384
29435
  });
29385
29436
  runScriptWithJson("new-shortcuts.ps1", "ListFile", links);
@@ -29519,12 +29570,12 @@ async function resolve(entry) {
29519
29570
  }
29520
29571
 
29521
29572
  // src/guest/apps/unpack.ts
29522
- import fs24 from "node:fs";
29523
- import path32 from "node:path";
29573
+ import fs25 from "node:fs";
29574
+ import path33 from "node:path";
29524
29575
  var sevenZip = () => tool("apps", "7zip", "7z.exe");
29525
29576
  async function unpack(entry, file3, out, d) {
29526
29577
  if (entry.id === "7zip") {
29527
- const sevenZr = path32.join(path32.dirname(file3), "7zr.exe");
29578
+ const sevenZr = path33.join(path33.dirname(file3), "7zr.exe");
29528
29579
  const zr = await githubAsset("ip7z/7zip", /^7zr\.exe$/);
29529
29580
  await downloader.file(zr.url, sevenZr, zr.sha256);
29530
29581
  await execAsync(sevenZr, ["x", "-y", "-o" + out, file3], { stdio: "ignore" });
@@ -29533,17 +29584,17 @@ async function unpack(entry, file3, out, d) {
29533
29584
  switch (entry.unpack ?? "archive") {
29534
29585
  case "file": {
29535
29586
  mkdirp(out);
29536
- fs24.renameSync(file3, path32.join(out, /^\//.test(entry.exe) ? path32.basename(file3) : entry.exe));
29587
+ fs25.renameSync(file3, path33.join(out, /^\//.test(entry.exe) ? path33.basename(file3) : entry.exe));
29537
29588
  return;
29538
29589
  }
29539
29590
  case "nsis": {
29540
29591
  if (!exists(sevenZip()))
29541
29592
  throw new Error("7-Zip is needed to unpack " + entry.name + " and could not be installed");
29542
- const raw = path32.join(path32.dirname(out), "raw");
29593
+ const raw = path33.join(path33.dirname(out), "raw");
29543
29594
  await execAsync(sevenZip(), ["x", "-y", "-o" + raw, file3], { stdio: "ignore" });
29544
29595
  const inner = findExe(raw, "/^app-64\\.7z$/");
29545
29596
  if (inner) await execAsync(sevenZip(), ["x", "-y", "-o" + out, inner], { stdio: "ignore" });
29546
- else fs24.renameSync(raw, out);
29597
+ else fs25.renameSync(raw, out);
29547
29598
  return;
29548
29599
  }
29549
29600
  case "msi": {
@@ -29593,11 +29644,11 @@ var AppInstaller = class {
29593
29644
  async installOne(entry) {
29594
29645
  try {
29595
29646
  const dest = tool("apps", ...entry.id.split("/"));
29596
- if (!exists(path33.join(dest, MARKER)) || this.options.refresh) await this.download(entry, dest);
29647
+ if (!exists(path34.join(dest, MARKER)) || this.options.refresh) await this.download(entry, dest);
29597
29648
  const exe = findExe(dest, entry.exe);
29598
29649
  if (!exe) throw new Error(entry.exe + " not found in the download");
29599
29650
  await afterInstall(entry, exe);
29600
- if (!entry.service && (entry.cli || entry.id === "sysinternals")) this.env.prepend.push(path33.dirname(exe));
29651
+ if (!entry.service && (entry.cli || entry.id === "sysinternals")) this.env.prepend.push(path34.dirname(exe));
29601
29652
  if (!entry.cli && !entry.service) this.gui.push({ name: entry.name, exe });
29602
29653
  this.installed.push(entry.name);
29603
29654
  } catch (e) {
@@ -29610,13 +29661,13 @@ var AppInstaller = class {
29610
29661
  /** Downloads and unpacks one entry into its folder (replaced in one step: never half there). */
29611
29662
  async download(entry, dest) {
29612
29663
  const work = stagingFolder(dest);
29613
- const out = path33.join(work, "out");
29664
+ const out = path34.join(work, "out");
29614
29665
  try {
29615
29666
  if ("locked" in entry.source) {
29616
29667
  log("Installing " + entry.name + " " + entry.source.version + " (pinned, every file checked) ...");
29617
29668
  await installLocked(entry.id, entry.source.locked, mkdirp(out));
29618
29669
  } else if ("npm" in entry.source) {
29619
- const npmCli = path33.join(path33.dirname(process.execPath), "node_modules", "npm", "bin", "npm-cli.js");
29670
+ const npmCli = path34.join(path34.dirname(process.execPath), "node_modules", "npm", "bin", "npm-cli.js");
29620
29671
  log("Installing " + entry.name + " (npm) ...");
29621
29672
  await execAsync(process.execPath, [
29622
29673
  npmCli,
@@ -29631,23 +29682,23 @@ var AppInstaller = class {
29631
29682
  } else {
29632
29683
  const d = await resolve(entry);
29633
29684
  log("Downloading " + entry.name + " (" + d.fileName + ", ~" + entry.size + " once) ...");
29634
- const file3 = path33.join(mkdirp(work), d.fileName.replace(/[\\/:*?"<>|]/g, "_"));
29685
+ const file3 = path34.join(mkdirp(work), d.fileName.replace(/[\\/:*?"<>|]/g, "_"));
29635
29686
  await downloader.file(d.url, file3, { sha256: d.sha256 ?? null });
29636
29687
  await unpack(entry, file3, out, d);
29637
29688
  }
29638
- fs25.writeFileSync(path33.join(out, MARKER), JSON.stringify({ id: entry.id, at: (/* @__PURE__ */ new Date()).toISOString() }));
29689
+ fs26.writeFileSync(path34.join(out, MARKER), JSON.stringify({ id: entry.id, at: (/* @__PURE__ */ new Date()).toISOString() }));
29639
29690
  moveIntoPlace(out, dest);
29640
29691
  } finally {
29641
- safeRemove(work, path33.dirname(work));
29692
+ safeRemove(work, path34.dirname(work));
29642
29693
  }
29643
29694
  }
29644
29695
  };
29645
29696
  var LOCKED_PYTHON = "3.13";
29646
29697
  async function installLocked(id, kind, out) {
29647
- const lock = path33.join(launchDir, "sandbox", "addons", id);
29698
+ const lock = path34.join(launchDir, "sandbox", "addons", id);
29648
29699
  if (kind === "npm") {
29649
- for (const f of ["package.json", "package-lock.json"]) fs25.copyFileSync(path33.join(lock, f), path33.join(out, f));
29650
- const npmCli = path33.join(path33.dirname(process.execPath), "node_modules", "npm", "bin", "npm-cli.js");
29700
+ for (const f of ["package.json", "package-lock.json"]) fs26.copyFileSync(path34.join(lock, f), path34.join(out, f));
29701
+ const npmCli = path34.join(path34.dirname(process.execPath), "node_modules", "npm", "bin", "npm-cli.js");
29651
29702
  await execAsync(
29652
29703
  process.execPath,
29653
29704
  [npmCli, "ci", "--ignore-scripts", "--no-audit", "--no-fund", "--loglevel=error"],
@@ -29658,7 +29709,7 @@ async function installLocked(id, kind, out) {
29658
29709
  const uv = findExe(tool("uv"), "uv.exe");
29659
29710
  if (!uv) throw new Error("uv is not installed (the uv step failed)");
29660
29711
  const env = { ...process.env, ...uvVars() };
29661
- const venv = path33.join(out, "venv");
29712
+ const venv = path34.join(out, "venv");
29662
29713
  await execAsync(
29663
29714
  uv,
29664
29715
  ["venv", "--relocatable", "--python", LOCKED_PYTHON, "--python-preference", "only-managed", venv],
@@ -29672,7 +29723,7 @@ async function installLocked(id, kind, out) {
29672
29723
  "pip",
29673
29724
  "install",
29674
29725
  "--python",
29675
- path33.join(venv, "Scripts", "python.exe"),
29726
+ path34.join(venv, "Scripts", "python.exe"),
29676
29727
  "--require-hashes",
29677
29728
  "--no-deps",
29678
29729
  "--only-binary",
@@ -29680,7 +29731,7 @@ async function installLocked(id, kind, out) {
29680
29731
  "--link-mode",
29681
29732
  "copy",
29682
29733
  "-r",
29683
- path33.join(lock, "requirements.txt")
29734
+ path34.join(lock, "requirements.txt")
29684
29735
  ],
29685
29736
  { env }
29686
29737
  );
@@ -29696,8 +29747,8 @@ async function setupApps(env, apps, o) {
29696
29747
  }
29697
29748
 
29698
29749
  // src/guest/toolchains/detect.ts
29699
- import fs26 from "node:fs";
29700
- import path34 from "node:path";
29750
+ import fs27 from "node:fs";
29751
+ import path35 from "node:path";
29701
29752
 
29702
29753
  // src/core/detect/versions.ts
29703
29754
  function pickNodeVersion(releases, spec) {
@@ -29841,14 +29892,14 @@ function workspaceEntries() {
29841
29892
  if (known) return known;
29842
29893
  const list = (dir) => {
29843
29894
  try {
29844
- return fs26.readdirSync(dir, { withFileTypes: true });
29895
+ return fs27.readdirSync(dir, { withFileTypes: true });
29845
29896
  } catch {
29846
29897
  return [];
29847
29898
  }
29848
29899
  };
29849
29900
  const top = list(workspace2);
29850
29901
  const below = top.filter((d) => d.isDirectory() && !d.name.startsWith(".") && !SKIP_DIRS.has(d.name.toLowerCase())).flatMap(
29851
- (d) => list(path34.join(workspace2, d.name)).filter((f) => f.isFile()).map((f) => d.name + "/" + f.name)
29902
+ (d) => list(path35.join(workspace2, d.name)).filter((f) => f.isFile()).map((f) => d.name + "/" + f.name)
29852
29903
  );
29853
29904
  const found = [...top.filter((d) => d.isFile()).map((d) => d.name), ...below];
29854
29905
  entries.set(workspace2.toLowerCase(), found);
@@ -29859,9 +29910,9 @@ function wanted(setting, toolchain) {
29859
29910
  }
29860
29911
  function versionFromFiles(files, parse5 = (t) => specFromVersionFile(t)) {
29861
29912
  for (const name of files) {
29862
- const file3 = path34.join(projectWorkspace(), name);
29913
+ const file3 = path35.join(projectWorkspace(), name);
29863
29914
  if (!exists(file3)) continue;
29864
- const spec = parse5(fs26.readFileSync(file3, "utf8"), name);
29915
+ const spec = parse5(fs27.readFileSync(file3, "utf8"), name);
29865
29916
  if (spec) return { spec, source: name };
29866
29917
  }
29867
29918
  return null;
@@ -29934,22 +29985,22 @@ var DatabaseServer = class {
29934
29985
  };
29935
29986
 
29936
29987
  // src/guest/databases/dynamodb.ts
29937
- import fs31 from "node:fs";
29938
- import path37 from "node:path";
29988
+ import fs32 from "node:fs";
29989
+ import path38 from "node:path";
29939
29990
  import { spawn as spawn3 } from "node:child_process";
29940
29991
 
29941
29992
  // src/guest/toolchains/languages/java.ts
29942
- import fs29 from "node:fs";
29943
- import path35 from "node:path";
29993
+ import fs30 from "node:fs";
29994
+ import path36 from "node:path";
29944
29995
 
29945
29996
  // src/guest/toolchains/version-cache.ts
29946
- import fs28 from "node:fs";
29997
+ import fs29 from "node:fs";
29947
29998
 
29948
29999
  // src/guest/toolchains/state-file.ts
29949
- import fs27 from "node:fs";
30000
+ import fs28 from "node:fs";
29950
30001
  function readState(file3, schema, empty) {
29951
30002
  try {
29952
- return schema.safeParse(JSON.parse(fs27.readFileSync(file3, "utf8").replace(/^\uFEFF/, ""))).data ?? empty;
30003
+ return schema.safeParse(JSON.parse(fs28.readFileSync(file3, "utf8").replace(/^\uFEFF/, ""))).data ?? empty;
29953
30004
  } catch {
29954
30005
  return empty;
29955
30006
  }
@@ -29984,7 +30035,7 @@ var VersionCache = class {
29984
30035
  return cached2.value;
29985
30036
  try {
29986
30037
  const value = await resolve2();
29987
- fs28.mkdirSync(toolsDir, { recursive: true });
30038
+ fs29.mkdirSync(toolsDir, { recursive: true });
29988
30039
  writeJsonAtomic(this.file(), { ...this.remembered(), [key2]: { value, at: Date.now() } });
29989
30040
  return value;
29990
30041
  } catch (e) {
@@ -30037,7 +30088,7 @@ var setupJdk = async (env, config2) => {
30037
30088
  const { major, source } = await javaMajor(config2);
30038
30089
  const release = await resolveCached("java:" + major, async () => (await temurin(major)).release_name);
30039
30090
  const home = tool("java", release.replace(/[^A-Za-z0-9.-]/g, "_"));
30040
- if (!exists(path35.join(home, "bin", "java.exe"))) {
30091
+ if (!exists(path36.join(home, "bin", "java.exe"))) {
30041
30092
  const asset = await temurin(major);
30042
30093
  log("Downloading Java " + release + " (JDK, ~200 MB once) ...");
30043
30094
  await downloader.archive(asset.binary.package.link, home, {
@@ -30047,13 +30098,13 @@ var setupJdk = async (env, config2) => {
30047
30098
  });
30048
30099
  }
30049
30100
  env.vars.JAVA_HOME = home;
30050
- env.prepend.push(path35.join(home, "bin"));
30101
+ env.prepend.push(path36.join(home, "bin"));
30051
30102
  env.summary.push("java: " + release + " (Temurin, from " + source + ")");
30052
30103
  };
30053
30104
  async function ensureJdk() {
30054
30105
  const root = tool("java");
30055
- const installed = exists(root) ? fs29.readdirSync(root).filter((d) => exists(path35.join(root, d, "bin", "java.exe"))).sort((a, b) => b.localeCompare(a, void 0, { numeric: true })) : [];
30056
- if (installed.length) return path35.join(root, installed[0]);
30106
+ const installed = exists(root) ? fs30.readdirSync(root).filter((d) => exists(path36.join(root, d, "bin", "java.exe"))).sort((a, b) => b.localeCompare(a, void 0, { numeric: true })) : [];
30107
+ if (installed.length) return path36.join(root, installed[0]);
30057
30108
  const scratch = emptyEnv();
30058
30109
  await setupJdk(scratch, { enabled: true, version: "lts", maven: false, gradle: false, kotlin: false });
30059
30110
  return scratch.vars.JAVA_HOME;
@@ -30066,7 +30117,7 @@ var setupMaven = async (env) => {
30066
30117
  return pickPackageVersion(versions, "3") ?? Promise.reject(new Error("No Maven 3 release found"));
30067
30118
  });
30068
30119
  const home = tool("maven", version2);
30069
- if (!exists(path35.join(home, "bin", "mvn.cmd"))) {
30120
+ if (!exists(path36.join(home, "bin", "mvn.cmd"))) {
30070
30121
  const url2 = MAVEN + version2 + "/apache-maven-" + version2 + "-bin.zip";
30071
30122
  log("Downloading Maven " + version2 + " (~10 MB once) ...");
30072
30123
  await downloader.archive(url2, home, {
@@ -30076,7 +30127,7 @@ var setupMaven = async (env) => {
30076
30127
  }
30077
30128
  const repo = tool("maven-repository");
30078
30129
  Object.assign(env.vars, { MAVEN_HOME: home, M2_HOME: home, MAVEN_OPTS: "-Dmaven.repo.local=" + repo });
30079
- env.prepend.push(path35.join(home, "bin"));
30130
+ env.prepend.push(path36.join(home, "bin"));
30080
30131
  env.summary.push("maven: " + version2);
30081
30132
  };
30082
30133
  var setupGradle = async (env) => {
@@ -30088,7 +30139,7 @@ var setupGradle = async (env) => {
30088
30139
  async () => current?.version ?? Promise.reject(new Error("Gradle version lookup failed"))
30089
30140
  );
30090
30141
  const home = tool("gradle", version2);
30091
- if (!exists(path35.join(home, "bin", "gradle.bat"))) {
30142
+ if (!exists(path36.join(home, "bin", "gradle.bat"))) {
30092
30143
  if (!current || current.version !== version2)
30093
30144
  throw new Error("Gradle " + version2 + " is not installed and cannot be downloaded right now");
30094
30145
  log("Downloading Gradle " + version2 + " (~130 MB once) ...");
@@ -30099,13 +30150,13 @@ var setupGradle = async (env) => {
30099
30150
  });
30100
30151
  }
30101
30152
  const userHome = tool("gradle-home");
30102
- fs29.mkdirSync(userHome, { recursive: true });
30153
+ fs30.mkdirSync(userHome, { recursive: true });
30103
30154
  Object.assign(env.vars, {
30104
30155
  GRADLE_HOME: home,
30105
30156
  GRADLE_USER_HOME: userHome,
30106
30157
  GRADLE_OPTS: "-Dorg.gradle.vfs.watch=false"
30107
30158
  });
30108
- env.prepend.push(path35.join(home, "bin"));
30159
+ env.prepend.push(path36.join(home, "bin"));
30109
30160
  env.summary.push("gradle: " + version2);
30110
30161
  };
30111
30162
  async function setupJava(env, config2) {
@@ -30129,29 +30180,29 @@ async function setupJava(env, config2) {
30129
30180
  }
30130
30181
 
30131
30182
  // src/guest/databases/server.ts
30132
- import fs30 from "node:fs";
30133
- import path36 from "node:path";
30183
+ import fs31 from "node:fs";
30184
+ import path37 from "node:path";
30134
30185
  import { spawn as spawn2 } from "node:child_process";
30135
30186
  function dataFor(name) {
30136
- return path36.join(dataDir, "databases", name);
30187
+ return path37.join(dataDir, "databases", name);
30137
30188
  }
30138
30189
  async function startServer(name, exe, args, port) {
30139
30190
  if (await portOpen(port)) throw new Error("port " + port + " is already in use (change databases." + name + ".port)");
30140
- const logFile2 = path36.join(logsDir, name + ".log");
30141
- const out = fs30.openSync(logFile2, "a");
30191
+ const logFile2 = path37.join(logsDir, name + ".log");
30192
+ const out = fs31.openSync(logFile2, "a");
30142
30193
  spawn2(exe, args, { detached: true, stdio: ["ignore", out, out], windowsHide: true }).unref();
30143
- fs30.closeSync(out);
30194
+ fs31.closeSync(out);
30144
30195
  if (!await waitForPort(port, 60))
30145
30196
  throw new Error(name + " did not start listening on port " + port + "; see " + logFile2);
30146
30197
  }
30147
30198
  async function clearStaleLocks(dir, files, port) {
30148
30199
  if (await portOpen(port)) return;
30149
- for (const f of files) fs30.rmSync(path36.join(dir, f), { force: true });
30200
+ for (const f of files) fs31.rmSync(path37.join(dir, f), { force: true });
30150
30201
  }
30151
30202
  async function createOnce(data, marker, create) {
30152
- if (exists(path36.join(data, marker))) return;
30203
+ if (exists(path37.join(data, marker))) return;
30153
30204
  const existed = exists(data);
30154
- mkdirp(path36.dirname(data));
30205
+ mkdirp(path37.dirname(data));
30155
30206
  try {
30156
30207
  await create();
30157
30208
  } catch (e) {
@@ -30175,9 +30226,9 @@ var DynamoServer = class extends DatabaseServer {
30175
30226
  * local endpoint up from AWS_ENDPOINT_URL_DYNAMODB, with dummy credentials (real ones never reach the sandbox).
30176
30227
  */
30177
30228
  async start(env, plan2) {
30178
- const java = path37.join(await ensureJdk(), "bin", "java.exe");
30229
+ const java = path38.join(await ensureJdk(), "bin", "java.exe");
30179
30230
  const home = tool("dynamodb-local");
30180
- if (!exists(path37.join(home, "DynamoDBLocal.jar"))) {
30231
+ if (!exists(path38.join(home, "DynamoDBLocal.jar"))) {
30181
30232
  log("Downloading DynamoDB Local (~60 MB once) ...");
30182
30233
  const sha256 = (await fetchText(DYNAMO_ZIP + ".sha256")).trim().split(/\s+/)[0];
30183
30234
  await downloader.archive(DYNAMO_ZIP, home, {
@@ -30191,9 +30242,9 @@ var DynamoServer = class extends DatabaseServer {
30191
30242
  "dynamodb",
30192
30243
  java,
30193
30244
  [
30194
- "-Djava.library.path=" + path37.join(home, "DynamoDBLocal_lib"),
30245
+ "-Djava.library.path=" + path38.join(home, "DynamoDBLocal_lib"),
30195
30246
  "-jar",
30196
- path37.join(home, "DynamoDBLocal.jar"),
30247
+ path38.join(home, "DynamoDBLocal.jar"),
30197
30248
  "-sharedDb",
30198
30249
  "-dbPath",
30199
30250
  data,
@@ -30217,10 +30268,10 @@ var DynamoServer = class extends DatabaseServer {
30217
30268
  );
30218
30269
  if (!plan2.adminPort) return;
30219
30270
  const prefix = tool("dynamodb-admin");
30220
- const script = path37.join(prefix, "node_modules", "dynamodb-admin", "dist", "dynamodb-admin.js");
30271
+ const script = path38.join(prefix, "node_modules", "dynamodb-admin", "dist", "dynamodb-admin.js");
30221
30272
  if (!exists(script)) {
30222
30273
  log("Installing dynamodb-admin, the DynamoDB web UI (~20 MB once) ...");
30223
- const npmCli = path37.join(path37.dirname(process.execPath), "node_modules", "npm", "bin", "npm-cli.js");
30274
+ const npmCli = path38.join(path38.dirname(process.execPath), "node_modules", "npm", "bin", "npm-cli.js");
30224
30275
  await execAsync(
30225
30276
  process.execPath,
30226
30277
  [npmCli, "install", "--global", "--prefix", prefix, "dynamodb-admin", "--no-fund", "--no-audit"],
@@ -30233,15 +30284,15 @@ var DynamoServer = class extends DatabaseServer {
30233
30284
  );
30234
30285
  return;
30235
30286
  }
30236
- const out = fs31.openSync(path37.join(logsDir, "dynamodb-admin.log"), "a");
30287
+ const out = fs32.openSync(path38.join(logsDir, "dynamodb-admin.log"), "a");
30237
30288
  spawn3(
30238
30289
  process.execPath,
30239
30290
  [script, "--port", String(plan2.adminPort), "--dynamo-endpoint", endpoint, "--skip-default-credentials"],
30240
30291
  { detached: true, stdio: ["ignore", out, out], windowsHide: true, env: { ...process.env, ...aws } }
30241
30292
  ).unref();
30242
- fs31.closeSync(out);
30293
+ fs32.closeSync(out);
30243
30294
  if (!await waitForPort(plan2.adminPort, 30))
30244
- throw new Error("dynamodb-admin did not start; see " + path37.join(logsDir, "dynamodb-admin.log"));
30295
+ throw new Error("dynamodb-admin did not start; see " + path38.join(logsDir, "dynamodb-admin.log"));
30245
30296
  env.summary.push(
30246
30297
  "dynamodb-admin: http://localhost:" + plan2.adminPort + " (browse and edit tables in the sandbox's browser)"
30247
30298
  );
@@ -30249,7 +30300,7 @@ var DynamoServer = class extends DatabaseServer {
30249
30300
  };
30250
30301
 
30251
30302
  // src/guest/databases/mongodb.ts
30252
- import path38 from "node:path";
30303
+ import path39 from "node:path";
30253
30304
  var MongoServer = class extends DatabaseServer {
30254
30305
  id = "mongodb";
30255
30306
  async start(env, plan2) {
@@ -30264,13 +30315,13 @@ var MongoServer = class extends DatabaseServer {
30264
30315
  };
30265
30316
  const version2 = await resolveCached("mongodb:" + plan2.version, async () => (await find()).version);
30266
30317
  const home = tool("mongodb", version2);
30267
- if (!exists(path38.join(home, "bin", "mongod.exe"))) {
30318
+ if (!exists(path39.join(home, "bin", "mongod.exe"))) {
30268
30319
  const { archive } = await find();
30269
30320
  log("Downloading MongoDB " + version2 + " (~400 MB once) ...");
30270
30321
  await downloader.archive(archive.url, home, { sha256: archive.sha256, locate: "mongod.exe", up: 1 });
30271
30322
  }
30272
30323
  const shell = tool("mongosh");
30273
- if (!exists(path38.join(shell, "mongosh.exe"))) {
30324
+ if (!exists(path39.join(shell, "mongosh.exe"))) {
30274
30325
  await installFromGithub("mongodb-js/mongosh", /^mongosh-[\d.]+-win32-x64\.zip$/, {
30275
30326
  dest: shell,
30276
30327
  what: "mongosh, the MongoDB shell (~50 MB once)",
@@ -30281,17 +30332,17 @@ var MongoServer = class extends DatabaseServer {
30281
30332
  await clearStaleLocks(data, ["mongod.lock"], plan2.port);
30282
30333
  await startServer(
30283
30334
  "mongodb",
30284
- path38.join(home, "bin", "mongod.exe"),
30335
+ path39.join(home, "bin", "mongod.exe"),
30285
30336
  ["--dbpath", data, "--bind_ip", "127.0.0.1", "--port", String(plan2.port)],
30286
30337
  plan2.port
30287
30338
  );
30288
- env.prepend.push(path38.join(home, "bin"), shell);
30339
+ env.prepend.push(path39.join(home, "bin"), shell);
30289
30340
  env.summary.push("mongodb " + version2 + ": mongodb://127.0.0.1:" + plan2.port + " (mongosh on PATH)");
30290
30341
  }
30291
30342
  };
30292
30343
 
30293
30344
  // src/guest/databases/mysql.ts
30294
- import path39 from "node:path";
30345
+ import path40 from "node:path";
30295
30346
  var MARIA = "https://downloads.mariadb.org/rest-api/mariadb/";
30296
30347
  var MysqlServer = class extends DatabaseServer {
30297
30348
  id = "mysql";
@@ -30309,8 +30360,8 @@ var MysqlServer = class extends DatabaseServer {
30309
30360
  };
30310
30361
  const version2 = await resolveCached("mariadb-version:" + series, async () => (await latest()).version);
30311
30362
  const home = tool("mariadb", version2);
30312
- const bin = path39.join(home, "bin");
30313
- if (!exists(path39.join(bin, "mariadbd.exe"))) {
30363
+ const bin = path40.join(home, "bin");
30364
+ if (!exists(path40.join(bin, "mariadbd.exe"))) {
30314
30365
  const { zip } = await latest();
30315
30366
  log("Downloading MariaDB " + version2 + " (~90 MB once) ...");
30316
30367
  await downloader.archive(zip.file_download_url.replace(/^http:/, "https:"), home, {
@@ -30323,13 +30374,13 @@ var MysqlServer = class extends DatabaseServer {
30323
30374
  const data = dataFor("mariadb");
30324
30375
  await createOnce(data, "mysql", async () => {
30325
30376
  log("Creating the MariaDB database (first start) ...");
30326
- await execAsync(path39.join(bin, "mariadb-install-db.exe"), ["--datadir=" + data, "--port=" + plan2.port], {
30377
+ await execAsync(path40.join(bin, "mariadb-install-db.exe"), ["--datadir=" + data, "--port=" + plan2.port], {
30327
30378
  stdio: "ignore"
30328
30379
  });
30329
30380
  });
30330
30381
  await startServer(
30331
30382
  "mysql",
30332
- path39.join(bin, "mariadbd.exe"),
30383
+ path40.join(bin, "mariadbd.exe"),
30333
30384
  ["--datadir=" + data, "--port=" + plan2.port, "--bind-address=127.0.0.1", "--console"],
30334
30385
  plan2.port
30335
30386
  );
@@ -30342,8 +30393,8 @@ var MysqlServer = class extends DatabaseServer {
30342
30393
  };
30343
30394
 
30344
30395
  // src/guest/databases/postgres.ts
30345
- import fs32 from "node:fs";
30346
- import path40 from "node:path";
30396
+ import fs33 from "node:fs";
30397
+ import path41 from "node:path";
30347
30398
  function postgresData(version2) {
30348
30399
  return dataFor("postgres-" + version2.split(".")[0]);
30349
30400
  }
@@ -30358,8 +30409,8 @@ var PostgresServer = class extends DatabaseServer {
30358
30409
  return hit ? hit.major + "." + hit.latestMinor : Promise.reject(new Error("No supported PostgreSQL " + plan2.version));
30359
30410
  });
30360
30411
  const home = tool("postgres", exact);
30361
- const bin = path40.join(home, "bin");
30362
- if (!exists(path40.join(bin, "pg_ctl.exe"))) {
30412
+ const bin = path41.join(home, "bin");
30413
+ if (!exists(path41.join(bin, "pg_ctl.exe"))) {
30363
30414
  log("Downloading PostgreSQL " + exact + " (~330 MB once) ...");
30364
30415
  await downloader.archive(
30365
30416
  "https://get.enterprisedb.com/postgresql/postgresql-" + exact + "-1-windows-x64-binaries.zip",
@@ -30376,7 +30427,7 @@ var PostgresServer = class extends DatabaseServer {
30376
30427
  await createOnce(data, "PG_VERSION", async () => {
30377
30428
  log("Creating the PostgreSQL database (first start) ...");
30378
30429
  await execAsync(
30379
- path40.join(bin, "initdb.exe"),
30430
+ path41.join(bin, "initdb.exe"),
30380
30431
  ["-D", data, "-U", "postgres", "-A", "trust", "-E", "UTF8", "--locale=C"],
30381
30432
  { stdio: "ignore" }
30382
30433
  );
@@ -30385,7 +30436,7 @@ var PostgresServer = class extends DatabaseServer {
30385
30436
  throw new Error("port " + plan2.port + " is already in use (change databases.postgres.port)");
30386
30437
  await clearStaleLocks(data, ["postmaster.pid"], plan2.port);
30387
30438
  await execAsync(
30388
- path40.join(bin, "pg_ctl.exe"),
30439
+ path41.join(bin, "pg_ctl.exe"),
30389
30440
  [
30390
30441
  "start",
30391
30442
  "-D",
@@ -30394,7 +30445,7 @@ var PostgresServer = class extends DatabaseServer {
30394
30445
  "-t",
30395
30446
  "60",
30396
30447
  "-l",
30397
- path40.join(logsDir, "postgres.log"),
30448
+ path41.join(logsDir, "postgres.log"),
30398
30449
  "-o",
30399
30450
  "-p " + plan2.port + " -c listen_addresses=localhost"
30400
30451
  ],
@@ -30409,10 +30460,10 @@ var PostgresServer = class extends DatabaseServer {
30409
30460
  /** Every installed version's cluster shuts down cleanly through pg_ctl first. */
30410
30461
  async stop(plan2) {
30411
30462
  if (exists(tool("postgres"))) {
30412
- for (const version2 of fs32.readdirSync(tool("postgres"))) {
30463
+ for (const version2 of fs33.readdirSync(tool("postgres"))) {
30413
30464
  const data = postgresData(version2);
30414
- const pgCtl = path40.join(tool("postgres", version2), "bin", "pg_ctl.exe");
30415
- if (exists(path40.join(data, "postmaster.pid")) && exists(pgCtl))
30465
+ const pgCtl = path41.join(tool("postgres", version2), "bin", "pg_ctl.exe");
30466
+ if (exists(path41.join(data, "postmaster.pid")) && exists(pgCtl))
30416
30467
  await execAsync(pgCtl, ["stop", "-D", data, "-m", "fast", "-w"], { stdio: "ignore" });
30417
30468
  }
30418
30469
  }
@@ -30421,12 +30472,12 @@ var PostgresServer = class extends DatabaseServer {
30421
30472
  };
30422
30473
 
30423
30474
  // src/guest/databases/redis.ts
30424
- import path41 from "node:path";
30475
+ import path42 from "node:path";
30425
30476
  var RedisServer = class extends DatabaseServer {
30426
30477
  id = "redis";
30427
30478
  async start(env, plan2) {
30428
30479
  const home = tool("redis");
30429
- if (!exists(path41.join(home, "redis-server.exe"))) {
30480
+ if (!exists(path42.join(home, "redis-server.exe"))) {
30430
30481
  await installFromGithub("redis-windows/redis-windows", /^Redis-[\d.]+-Windows-x64-msys2\.zip$/, {
30431
30482
  dest: home,
30432
30483
  what: (a) => "Redis (" + a.name + ", ~10 MB once)",
@@ -30436,7 +30487,7 @@ var RedisServer = class extends DatabaseServer {
30436
30487
  const data = mkdirp(dataFor("redis"));
30437
30488
  await startServer(
30438
30489
  "redis",
30439
- path41.join(home, "redis-server.exe"),
30490
+ path42.join(home, "redis-server.exe"),
30440
30491
  ["--port", String(plan2.port), "--bind", "127.0.0.1", "--dir", data.replace(/\\/g, "/"), "--appendonly", "yes"],
30441
30492
  plan2.port
30442
30493
  );
@@ -30474,16 +30525,16 @@ async function setupDatabase(env, plan2) {
30474
30525
  }
30475
30526
 
30476
30527
  // src/guest/toolchains/tools/git.ts
30477
- import fs34 from "node:fs";
30478
- import path43 from "node:path";
30528
+ import fs35 from "node:fs";
30529
+ import path44 from "node:path";
30479
30530
 
30480
30531
  // src/guest/runtime/csc.ts
30481
- import fs33 from "node:fs";
30532
+ import fs34 from "node:fs";
30482
30533
  import os6 from "node:os";
30483
- import path42 from "node:path";
30534
+ import path43 from "node:path";
30484
30535
  import crypto3 from "node:crypto";
30485
30536
  import { spawnSync as spawnSync5 } from "node:child_process";
30486
- var CSC = path42.join(process.env.WINDIR ?? "C:\\Windows", "Microsoft.NET", "Framework64", "v4.0.30319", "csc.exe");
30537
+ var CSC = path43.join(process.env.WINDIR ?? "C:\\Windows", "Microsoft.NET", "Framework64", "v4.0.30319", "csc.exe");
30487
30538
  var SOURCES = {
30488
30539
  ptyhost: "PtyHost.cs",
30489
30540
  gitshim: "GitShim.cs",
@@ -30496,17 +30547,17 @@ var SOURCES = {
30496
30547
  bindmount: "BindMount.cs"
30497
30548
  };
30498
30549
  function sourceOf(name) {
30499
- return path42.join(launchDir, "sandbox", "csharp", SOURCES[name]);
30550
+ return path43.join(launchDir, "sandbox", "csharp", SOURCES[name]);
30500
30551
  }
30501
30552
  function sourceHash(name) {
30502
- return crypto3.createHash("sha256").update(fs33.readFileSync(sourceOf(name))).digest("hex").slice(0, 12);
30553
+ return crypto3.createHash("sha256").update(fs34.readFileSync(sourceOf(name))).digest("hex").slice(0, 12);
30503
30554
  }
30504
30555
  function ensureCompiled(name) {
30505
- const exe = path42.join(os6.tmpdir(), "agent-sandbox", name + "-" + sourceHash(name) + ".exe");
30556
+ const exe = path43.join(os6.tmpdir(), "agent-sandbox", name + "-" + sourceHash(name) + ".exe");
30506
30557
  if (exists(exe)) return exe;
30507
30558
  if (!exists(CSC))
30508
30559
  throw new Error("The .NET Framework C# compiler was not found at " + CSC + " (it ships with Windows 10/11).");
30509
- mkdirp(path42.dirname(exe));
30560
+ mkdirp(path43.dirname(exe));
30510
30561
  const result = spawnSync5(CSC, ["/nologo", "/optimize", "/target:exe", "/out:" + exe, sourceOf(name)], {
30511
30562
  encoding: "utf8",
30512
30563
  windowsHide: true
@@ -30540,23 +30591,23 @@ var installPortableGit = async (root) => {
30540
30591
  await downloader.file(asset.url, sfx, asset.sha256);
30541
30592
  await execAsync(sfx, ["-o" + root, "-y"], { stdio: "ignore" });
30542
30593
  } finally {
30543
- fs34.rmSync(sfx, { force: true });
30594
+ fs35.rmSync(sfx, { force: true });
30544
30595
  }
30545
30596
  };
30546
30597
  var installGuard = (env, access, realGit) => {
30547
30598
  const dir = mkdirp(tool("gitguard"));
30548
- const guard = path43.join(launchDir, "runtime", "gitguard.js");
30549
- if (duringSession() && (exists(path43.join(dir, "git.exe")) || exists(path43.join(dir, "git.cmd")))) {
30599
+ const guard = path44.join(launchDir, "runtime", "gitguard.js");
30600
+ if (duringSession() && (exists(path44.join(dir, "git.exe")) || exists(path44.join(dir, "git.cmd")))) {
30550
30601
  } else
30551
30602
  try {
30552
- fs34.copyFileSync(ensureCompiled("gitshim"), path43.join(dir, "git.exe"));
30553
- fs34.rmSync(path43.join(dir, "git.cmd"), { force: true });
30603
+ fs35.copyFileSync(ensureCompiled("gitshim"), path44.join(dir, "git.exe"));
30604
+ fs35.rmSync(path44.join(dir, "git.cmd"), { force: true });
30554
30605
  } catch (e) {
30555
30606
  warn("git guard: falling back to git.cmd (" + errMsg(e) + ")");
30556
- fs34.writeFileSync(path43.join(dir, "git.cmd"), '@"' + process.execPath + '" "' + guard + '" %*\r\n');
30607
+ fs35.writeFileSync(path44.join(dir, "git.cmd"), '@"' + process.execPath + '" "' + guard + '" %*\r\n');
30557
30608
  }
30558
- fs34.writeFileSync(
30559
- path43.join(dir, "bashenv.sh"),
30609
+ fs35.writeFileSync(
30610
+ path44.join(dir, "bashenv.sh"),
30560
30611
  'git() { "' + posix(process.execPath) + '" "' + posix(guard) + '" "$@"; }\nexport -f git\n'
30561
30612
  );
30562
30613
  env.prepend.unshift(dir);
@@ -30565,13 +30616,13 @@ var installGuard = (env, access, realGit) => {
30565
30616
  AGENT_REAL_GIT: access === "readonly" ? realGit : "",
30566
30617
  AGENT_GUARD_NODE: process.execPath,
30567
30618
  AGENT_GUARD_SCRIPT: guard,
30568
- BASH_ENV: posix(path43.join(dir, "bashenv.sh"))
30619
+ BASH_ENV: posix(path44.join(dir, "bashenv.sh"))
30569
30620
  });
30570
30621
  if (access === "readonly") {
30571
- const hooks = mkdirp(path43.join(dir, "hooks"));
30622
+ const hooks = mkdirp(path44.join(dir, "hooks"));
30572
30623
  for (const hook of BLOCKED_HOOKS)
30573
- fs34.writeFileSync(
30574
- path43.join(hooks, hook),
30624
+ fs35.writeFileSync(
30625
+ path44.join(hooks, hook),
30575
30626
  '#!/bin/sh\necho "git is read-only in this sandbox: ' + hook + ' refused." >&2\nexit 1\n'
30576
30627
  );
30577
30628
  Object.assign(env.vars, {
@@ -30580,22 +30631,22 @@ var installGuard = (env, access, realGit) => {
30580
30631
  GIT_CONFIG_VALUE_0: posix(hooks)
30581
30632
  });
30582
30633
  } else {
30583
- env.vars.GIT_DIR = path43.join(dataDir, "git-disabled");
30634
+ env.vars.GIT_DIR = path44.join(dataDir, "git-disabled");
30584
30635
  }
30585
30636
  };
30586
30637
  var pointAtOwnCertificates = (root) => {
30587
- const config2 = path43.join(root, "etc", "gitconfig");
30588
- const bundle = path43.join(root, "mingw64", "etc", "ssl", "certs", "ca-bundle.crt");
30638
+ const config2 = path44.join(root, "etc", "gitconfig");
30639
+ const bundle = path44.join(root, "mingw64", "etc", "ssl", "certs", "ca-bundle.crt");
30589
30640
  if (!exists(config2) || !exists(bundle)) return;
30590
- const text = fs34.readFileSync(config2, "utf8");
30641
+ const text = fs35.readFileSync(config2, "utf8");
30591
30642
  const fixed = text.replace(/^(\s*sslCAInfo\s*=\s*).*$/gim, (_m, key2) => key2 + posix(bundle));
30592
- if (fixed !== text) fs34.writeFileSync(config2, fixed);
30643
+ if (fixed !== text) fs35.writeFileSync(config2, fixed);
30593
30644
  };
30594
30645
  async function setupGit(env, hostCopy, refresh, access) {
30595
30646
  const root = tool("git");
30596
- const bash = path43.join(root, "bin", "bash.exe");
30597
- const gitExe = path43.join(root, "cmd", "git.exe");
30598
- const hostGit = path43.join(hostToolsDir, "git");
30647
+ const bash = path44.join(root, "bin", "bash.exe");
30648
+ const gitExe = path44.join(root, "cmd", "git.exe");
30649
+ const hostGit = path44.join(hostToolsDir, "git");
30599
30650
  if (exists(root) && !exists(bash)) {
30600
30651
  log("Replacing the old MinGit (no bash) with full Git for Windows.");
30601
30652
  safeRemove(root, toolsDir);
@@ -30609,11 +30660,11 @@ async function setupGit(env, hostCopy, refresh, access) {
30609
30660
  }
30610
30661
  const work = stagingFolder(root);
30611
30662
  try {
30612
- if (hostCopy && exists(path43.join(hostGit, "bin", "bash.exe"))) {
30663
+ if (hostCopy && exists(path44.join(hostGit, "bin", "bash.exe"))) {
30613
30664
  log("Copying Git for Windows from this PC ...");
30614
30665
  robocopy(hostGit, work);
30615
30666
  } else await installPortableGit(work);
30616
- if (!exists(path43.join(work, "bin", "bash.exe"))) throw new Error("bash.exe missing after installing Git");
30667
+ if (!exists(path44.join(work, "bin", "bash.exe"))) throw new Error("bash.exe missing after installing Git");
30617
30668
  moveIntoPlace(work, root);
30618
30669
  } finally {
30619
30670
  safeRemove(work, toolsDir);
@@ -30622,10 +30673,10 @@ async function setupGit(env, hostCopy, refresh, access) {
30622
30673
  if (!exists(bash)) throw new Error("bash.exe missing after installing Git");
30623
30674
  pointAtOwnCertificates(root);
30624
30675
  env.vars.CLAUDE_CODE_GIT_BASH_PATH = bash;
30625
- env.append.push(path43.join(root, "usr", "bin"));
30676
+ env.append.push(path44.join(root, "usr", "bin"));
30626
30677
  const version2 = execOutput(gitExe, ["--version"]).replace(/^git version /, "");
30627
30678
  if (access === "full") {
30628
- env.prepend.push(path43.join(root, "cmd"));
30679
+ env.prepend.push(path44.join(root, "cmd"));
30629
30680
  env.summary.push("git: " + version2);
30630
30681
  return;
30631
30682
  }
@@ -30636,8 +30687,8 @@ async function setupGit(env, hostCopy, refresh, access) {
30636
30687
  }
30637
30688
 
30638
30689
  // src/guest/toolchains/languages/go.ts
30639
- import fs35 from "node:fs";
30640
- import path44 from "node:path";
30690
+ import fs36 from "node:fs";
30691
+ import path45 from "node:path";
30641
30692
 
30642
30693
  // src/guest/toolchains/package-ledger.ts
30643
30694
  var LedgerSchema = external_exports.record(external_exports.string(), external_exports.string());
@@ -30691,7 +30742,7 @@ async function setupGo(env, config2) {
30691
30742
  }
30692
30743
  const version2 = await resolveCached("go:" + config2.version, async () => (await findRelease(config2.version)).version);
30693
30744
  const root = tool("go", version2);
30694
- if (!exists(path44.join(root, "bin", "go.exe"))) {
30745
+ if (!exists(path45.join(root, "bin", "go.exe"))) {
30695
30746
  const goArch = arch === "arm64" ? "arm64" : "amd64";
30696
30747
  const file3 = (await findRelease(version2)).files.find(
30697
30748
  (f) => f.os === "windows" && f.arch === goArch && f.kind === "archive"
@@ -30708,16 +30759,16 @@ async function setupGo(env, config2) {
30708
30759
  const vars = {
30709
30760
  GOROOT: root,
30710
30761
  GOPATH,
30711
- GOBIN: path44.join(GOPATH, "bin"),
30712
- GOMODCACHE: path44.join(GOPATH, "pkg", "mod"),
30762
+ GOBIN: path45.join(GOPATH, "bin"),
30763
+ GOMODCACHE: path45.join(GOPATH, "pkg", "mod"),
30713
30764
  GOCACHE: tool("go-cache"),
30714
30765
  GOTOOLCHAIN: "auto",
30715
30766
  GOTELEMETRY: "off"
30716
30767
  };
30717
- fs35.mkdirSync(vars.GOBIN, { recursive: true });
30768
+ fs36.mkdirSync(vars.GOBIN, { recursive: true });
30718
30769
  Object.assign(env.vars, vars);
30719
- env.prepend.push(path44.join(root, "bin"), vars.GOBIN);
30720
- const go = path44.join(root, "bin", "go.exe");
30770
+ env.prepend.push(path45.join(root, "bin"), vars.GOBIN);
30771
+ const go = path45.join(root, "bin", "go.exe");
30721
30772
  env.summary.push("go: " + versionOf(go, ["version"]));
30722
30773
  await installOnce(
30723
30774
  env,
@@ -30728,8 +30779,8 @@ async function setupGo(env, config2) {
30728
30779
  }
30729
30780
 
30730
30781
  // src/guest/toolchains/tools/cli.ts
30731
- import fs36 from "node:fs";
30732
- import path45 from "node:path";
30782
+ import fs37 from "node:fs";
30783
+ import path46 from "node:path";
30733
30784
 
30734
30785
  // src/guest/toolchains/catalogue.ts
30735
30786
  function pwshAsset(arch2) {
@@ -30777,15 +30828,15 @@ function decideCli(settings, ctx) {
30777
30828
 
30778
30829
  // src/guest/toolchains/tools/cli.ts
30779
30830
  function ghConfigDir() {
30780
- return path45.join(stateDir, "gh");
30831
+ return path46.join(stateDir, "gh");
30781
30832
  }
30782
30833
  function deliveredGhConfigDir() {
30783
- return path45.join(localDir, "gh-token");
30834
+ return path46.join(localDir, "gh-token");
30784
30835
  }
30785
30836
  var GH_NOTE = " (log in once with: gh auth login --web --insecure-storage; it is kept between sandboxes)";
30786
30837
  function warnKeyringLogin() {
30787
30838
  try {
30788
- const hosts = fs36.readFileSync(path45.join(ghConfigDir(), "hosts.yml"), "utf8");
30839
+ const hosts = fs37.readFileSync(path46.join(ghConfigDir(), "hosts.yml"), "utf8");
30789
30840
  if (/^\s*user:/m.test(hosts) && !/oauth_token:/.test(hosts))
30790
30841
  warn(
30791
30842
  "gh: the GitHub login from an earlier sandbox was kept in Windows Credential Manager, which is wiped with each sandbox. Log in again with: gh auth login --web --insecure-storage (then it lasts)."
@@ -30806,16 +30857,16 @@ var shimOpenssl = (env) => {
30806
30857
  return;
30807
30858
  }
30808
30859
  const shims = mkdirp(tool("shims"));
30809
- fs36.copyFileSync(ensureCompiled("openssl"), path45.join(shims, "openssl.exe"));
30810
- fs36.rmSync(path45.join(shims, "openssl.cmd"), { force: true });
30860
+ fs37.copyFileSync(ensureCompiled("openssl"), path46.join(shims, "openssl.exe"));
30861
+ fs37.rmSync(path46.join(shims, "openssl.cmd"), { force: true });
30811
30862
  env.prepend.push(shims);
30812
30863
  env.summary.push("openssl: Git for Windows' copy");
30813
30864
  };
30814
30865
  async function setupCli(env, settings, gitAccess, refresh = false) {
30815
- const decisions = decideCli(settings, { gitAccess, hasGithubDir: exists(path45.join(projectWorkspace(), ".github")) });
30866
+ const decisions = decideCli(settings, { gitAccess, hasGithubDir: exists(path46.join(projectWorkspace(), ".github")) });
30816
30867
  if (settings.gh && !decisions.gh.on) {
30817
30868
  env.summary.push("gh: off (" + decisions.gh.reason + ")");
30818
- if (exists(path45.join(ghConfigDir(), "hosts.yml")))
30869
+ if (exists(path46.join(ghConfigDir(), "hosts.yml")))
30819
30870
  warn(
30820
30871
  '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."
30821
30872
  );
@@ -30854,12 +30905,12 @@ async function setupCli(env, settings, gitAccess, refresh = false) {
30854
30905
  }
30855
30906
 
30856
30907
  // src/guest/toolchains/managers.ts
30857
- import fs37 from "node:fs";
30858
- import path46 from "node:path";
30908
+ import fs38 from "node:fs";
30909
+ import path47 from "node:path";
30859
30910
  function voltaPins() {
30860
30911
  try {
30861
30912
  const pkg = JSON.parse(
30862
- fs37.readFileSync(path46.join(projectWorkspace(), "package.json"), "utf8").replace(/^\uFEFF/, "")
30913
+ fs38.readFileSync(path47.join(projectWorkspace(), "package.json"), "utf8").replace(/^\uFEFF/, "")
30863
30914
  );
30864
30915
  return Object.fromEntries(
30865
30916
  Object.entries(pkg.volta ?? {}).filter(
@@ -30882,7 +30933,7 @@ async function setupVolta(env) {
30882
30933
  return;
30883
30934
  }
30884
30935
  const dir = tool("volta");
30885
- if (!exists(path46.join(dir, "volta.exe"))) {
30936
+ if (!exists(path47.join(dir, "volta.exe"))) {
30886
30937
  const pattern = arch === "arm64" ? /^volta-[\d.]+-windows-arm64\.zip$/ : /^volta-[\d.]+-windows\.zip$/;
30887
30938
  await installFromGithub("volta-cli/volta", pattern, {
30888
30939
  dest: dir,
@@ -30891,17 +30942,17 @@ async function setupVolta(env) {
30891
30942
  });
30892
30943
  }
30893
30944
  for (const shim3 of ["node", "npm", "npx", "pnpm", "pnpx", "yarn", "yarnpkg"]) {
30894
- const target = path46.join(dir, shim3 + ".exe");
30895
- if (!exists(target)) fs37.copyFileSync(path46.join(dir, "volta-shim.exe"), target);
30945
+ const target = path47.join(dir, shim3 + ".exe");
30946
+ if (!exists(target)) fs38.copyFileSync(path47.join(dir, "volta-shim.exe"), target);
30896
30947
  }
30897
30948
  const home = mkdirp(tool("volta-home"));
30898
- const shims = mkdirp(path46.join(home, "bin"));
30949
+ const shims = mkdirp(path47.join(home, "bin"));
30899
30950
  const vars = { VOLTA_HOME: home, VOLTA_FEATURE_PNPM: "1" };
30900
30951
  Object.assign(env.vars, vars);
30901
30952
  const pins = voltaPins();
30902
30953
  if (Object.keys(pins).length) env.prepend.push(dir, shims);
30903
30954
  else env.append.push(dir, shims);
30904
- const volta = path46.join(dir, "volta.exe");
30955
+ const volta = path47.join(dir, "volta.exe");
30905
30956
  for (const [toolName, version2] of Object.entries(pins)) {
30906
30957
  try {
30907
30958
  await execAsync(volta, ["install", toolName + "@" + version2], {
@@ -30923,7 +30974,7 @@ async function setupPyenv(env) {
30923
30974
  return;
30924
30975
  }
30925
30976
  const root = tool("pyenv", "pyenv-win");
30926
- if (!exists(path46.join(root, "bin", "pyenv.bat"))) {
30977
+ if (!exists(path47.join(root, "bin", "pyenv.bat"))) {
30927
30978
  const tag = await resolveCached("pyenv-win", () => latestGithubTag("pyenv-win/pyenv-win"));
30928
30979
  log("Downloading pyenv-win " + tag + " (~5 MB once) ...");
30929
30980
  await downloader.archive(
@@ -30932,17 +30983,17 @@ async function setupPyenv(env) {
30932
30983
  { locate: "pyenv.bat", up: 1, fileName: "pyenv-win.zip" }
30933
30984
  );
30934
30985
  }
30935
- const home = root + path46.sep;
30986
+ const home = root + path47.sep;
30936
30987
  Object.assign(env.vars, { PYENV: home, PYENV_ROOT: home, PYENV_HOME: home });
30937
- env.append.push(path46.join(root, "bin"), path46.join(root, "shims"));
30988
+ env.append.push(path47.join(root, "bin"), path47.join(root, "shims"));
30938
30989
  env.summary.push("pyenv-win: pyenv install <version> / pyenv local <version> (versions persist)");
30939
30990
  }
30940
30991
 
30941
30992
  // src/guest/toolchains/native/cpp.ts
30942
- import path47 from "node:path";
30993
+ import path48 from "node:path";
30943
30994
  async function setupCpp(env, config2) {
30944
30995
  const bin = tool("mingw", "mingw64", "bin");
30945
- const gcc = path47.join(bin, "gcc.exe");
30996
+ const gcc = path48.join(bin, "gcc.exe");
30946
30997
  if (dryRun) {
30947
30998
  log("(dry run) would provision MinGW-w64 GCC");
30948
30999
  return;
@@ -30958,7 +31009,7 @@ async function setupCpp(env, config2) {
30958
31009
  if (!exists(gcc)) throw new Error("gcc.exe missing after installing MinGW");
30959
31010
  env.append.unshift(bin);
30960
31011
  env.vars.CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER = gcc;
30961
- const cmake = versionOf(path47.join(bin, "cmake.exe"));
31012
+ const cmake = versionOf(path48.join(bin, "cmake.exe"));
30962
31013
  if (cmakeTooOld(cmake))
30963
31014
  warn(
30964
31015
  "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."
@@ -30968,7 +31019,7 @@ async function setupCpp(env, config2) {
30968
31019
  }
30969
31020
  var setupFlexBison = async (env) => {
30970
31021
  const dir = tool("winflexbison");
30971
- if (!exists(path47.join(dir, "win_bison.exe"))) {
31022
+ if (!exists(path48.join(dir, "win_bison.exe"))) {
30972
31023
  await installFromGithub("lexxmark/winflexbison", /^win_flex_bison-[\d.]+\.zip$/, {
30973
31024
  dest: dir,
30974
31025
  what: "win_flex / win_bison (~1 MB once)",
@@ -30976,16 +31027,16 @@ var setupFlexBison = async (env) => {
30976
31027
  });
30977
31028
  }
30978
31029
  env.append.push(dir);
30979
- env.summary.push("win_flex/win_bison: " + versionOf(path47.join(dir, "win_bison.exe")));
31030
+ env.summary.push("win_flex/win_bison: " + versionOf(path48.join(dir, "win_bison.exe")));
30980
31031
  };
30981
31032
 
30982
31033
  // src/guest/toolchains/native/dotnet.ts
30983
- import fs38 from "node:fs";
30984
- import path48 from "node:path";
31034
+ import fs39 from "node:fs";
31035
+ import path49 from "node:path";
30985
31036
  var DotnetMarkerSchema = external_exports.record(external_exports.string(), external_exports.boolean());
30986
31037
  async function setupDotnet(env, config2, refresh) {
30987
31038
  const root = tool("dotnet");
30988
- const marker = path48.join(root, ".agent-sandbox-installed.json");
31039
+ const marker = path49.join(root, ".agent-sandbox-installed.json");
30989
31040
  const script = tool("dotnet-install.ps1");
30990
31041
  if (dryRun) {
30991
31042
  log("(dry run) would provision .NET SDK channels " + config2.channels.join(", "));
@@ -30993,11 +31044,11 @@ async function setupDotnet(env, config2, refresh) {
30993
31044
  }
30994
31045
  const recorded = DotnetMarkerSchema.safeParse(exists(marker) && !refresh ? readJsonFile(marker) : {});
30995
31046
  const done = recorded.success ? recorded.data : {};
30996
- const globalJson = path48.join(projectWorkspace(), "global.json");
31047
+ const globalJson = path49.join(projectWorkspace(), "global.json");
30997
31048
  const installs = [
30998
31049
  ...config2.channels.map((c) => ["channel:" + c, ["-Channel", c]]),
30999
31050
  ...exists(globalJson) ? [
31000
- ["global.json:" + fs38.readFileSync(globalJson, "utf8").replace(/\s+/g, ""), ["-JSonFile", globalJson]]
31051
+ ["global.json:" + fs39.readFileSync(globalJson, "utf8").replace(/\s+/g, ""), ["-JSonFile", globalJson]]
31001
31052
  ] : []
31002
31053
  ];
31003
31054
  for (const [key2, args] of installs.filter(([k]) => !done[k])) {
@@ -31029,12 +31080,12 @@ async function setupDotnet(env, config2, refresh) {
31029
31080
  DOTNET_SKIP_FIRST_TIME_EXPERIENCE: "1",
31030
31081
  NUGET_PACKAGES: tool("nuget", "packages")
31031
31082
  });
31032
- env.prepend.push(root, path48.join(home, ".dotnet", "tools"));
31083
+ env.prepend.push(root, path49.join(home, ".dotnet", "tools"));
31033
31084
  env.summary.push(
31034
- "dotnet: " + execOutput(path48.join(root, "dotnet.exe"), ["--list-sdks"]).split(/\r?\n/).map((l) => l.split(" ")[0]).filter(Boolean).join(", ")
31085
+ "dotnet: " + execOutput(path49.join(root, "dotnet.exe"), ["--list-sdks"]).split(/\r?\n/).map((l) => l.split(" ")[0]).filter(Boolean).join(", ")
31035
31086
  );
31036
- const dotnet = path48.join(root, "dotnet.exe");
31037
- const dotnetEnv = { env: { ...process.env, ...env.vars, PATH: root + path48.delimiter + (process.env.PATH ?? "") } };
31087
+ const dotnet = path49.join(root, "dotnet.exe");
31088
+ const dotnetEnv = { env: { ...process.env, ...env.vars, PATH: root + path49.delimiter + (process.env.PATH ?? "") } };
31038
31089
  await installOnce(
31039
31090
  env,
31040
31091
  "dotnet workload",
@@ -31055,7 +31106,7 @@ var setupFrameworkReferences = async (env, targets) => {
31055
31106
  const root = tool("netfx-references");
31056
31107
  for (const target of targets) {
31057
31108
  const id = "microsoft.netframework.referenceassemblies." + target.toLowerCase();
31058
- const marker = path48.join(root, ".installed-" + target.toLowerCase());
31109
+ const marker = path49.join(root, ".installed-" + target.toLowerCase());
31059
31110
  if (exists(marker)) continue;
31060
31111
  const staging = tool("netfx-references-" + target.toLowerCase());
31061
31112
  try {
@@ -31070,8 +31121,8 @@ var setupFrameworkReferences = async (env, targets) => {
31070
31121
  staging,
31071
31122
  { fileName: id + ".zip" }
31072
31123
  );
31073
- fs38.cpSync(path48.join(staging, "build", ".NETFramework"), path48.join(root, ".NETFramework"), { recursive: true });
31074
- fs38.writeFileSync(marker, version2);
31124
+ fs39.cpSync(path49.join(staging, "build", ".NETFramework"), path49.join(root, ".NETFramework"), { recursive: true });
31125
+ fs39.writeFileSync(marker, version2);
31075
31126
  } catch (e) {
31076
31127
  warn(
31077
31128
  ".NET Framework " + target + " reference assemblies could not be installed (projects targeting it will not build): " + errMsg(e)
@@ -31080,9 +31131,9 @@ var setupFrameworkReferences = async (env, targets) => {
31080
31131
  safeRemove(staging, dataDir);
31081
31132
  }
31082
31133
  }
31083
- if (!exists(path48.join(root, ".NETFramework"))) return;
31084
- env.vars.TargetFrameworkRootPath = root + path48.sep;
31085
- env.summary.push(".NET Framework targeting: " + fs38.readdirSync(path48.join(root, ".NETFramework")).join(", "));
31134
+ if (!exists(path49.join(root, ".NETFramework"))) return;
31135
+ env.vars.TargetFrameworkRootPath = root + path49.sep;
31136
+ env.summary.push(".NET Framework targeting: " + fs39.readdirSync(path49.join(root, ".NETFramework")).join(", "));
31086
31137
  };
31087
31138
  var setupNetFx35 = async (env) => {
31088
31139
  if (execOutput(SYSTEM.reg(), [
@@ -31109,15 +31160,15 @@ var setupNetFx35 = async (env) => {
31109
31160
  };
31110
31161
 
31111
31162
  // src/guest/toolchains/native/mesa.ts
31112
- import path49 from "node:path";
31163
+ import path50 from "node:path";
31113
31164
  async function setupMesa(env, config2) {
31114
31165
  if (dryRun) {
31115
31166
  log("(dry run) would provision Mesa 3D");
31116
31167
  return;
31117
31168
  }
31118
31169
  const root = tool("mesa");
31119
- const dir = path49.join(root, arch === "arm64" ? "arm64" : "x64");
31120
- if (!exists(path49.join(dir, "opengl32.dll"))) {
31170
+ const dir = path50.join(root, arch === "arm64" ? "arm64" : "x64");
31171
+ if (!exists(path50.join(dir, "opengl32.dll"))) {
31121
31172
  await installFromGithub("pal1000/mesa-dist-win", /^mesa3d-[\d.]+-release-msvc\.7z$/, {
31122
31173
  dest: root,
31123
31174
  what: "Mesa 3D for software OpenGL (~100 MB once)",
@@ -31133,10 +31184,10 @@ async function setupMesa(env, config2) {
31133
31184
  }
31134
31185
  var VULKAN_RUNTIME = "https://sdk.lunarg.com/sdk/download/latest/windows/vulkan-runtime-components.zip";
31135
31186
  var setupLavapipe = async (env, mesaDir) => {
31136
- const icd = path49.join(mesaDir, arch === "arm64" ? "lvp_icd.aarch64.json" : "lvp_icd.x86_64.json");
31137
- if (!exists(icd)) throw new Error("this Mesa build has no lavapipe (" + path49.basename(icd) + ")");
31187
+ const icd = path50.join(mesaDir, arch === "arm64" ? "lvp_icd.aarch64.json" : "lvp_icd.x86_64.json");
31188
+ if (!exists(icd)) throw new Error("this Mesa build has no lavapipe (" + path50.basename(icd) + ")");
31138
31189
  const dir = tool("vulkan");
31139
- if (!exists(path49.join(dir, "vulkan-1.dll"))) {
31190
+ if (!exists(path50.join(dir, "vulkan-1.dll"))) {
31140
31191
  log("Downloading the Vulkan loader (~10 MB once) ...");
31141
31192
  await downloader.archive(VULKAN_RUNTIME, dir, {
31142
31193
  locate: "vulkan-1.dll",
@@ -31150,7 +31201,7 @@ var setupLavapipe = async (env, mesaDir) => {
31150
31201
  { stdio: "ignore" }
31151
31202
  );
31152
31203
  await register(icd);
31153
- const dozen = path49.join(mesaDir, arch === "arm64" ? "dzn_icd.aarch64.json" : "dzn_icd.x86_64.json");
31204
+ const dozen = path50.join(mesaDir, arch === "arm64" ? "dzn_icd.aarch64.json" : "dzn_icd.x86_64.json");
31154
31205
  const gpu = hasGpu();
31155
31206
  if (gpu && exists(dozen)) await register(dozen);
31156
31207
  env.prepend.push(dir);
@@ -31161,20 +31212,20 @@ var setupLavapipe = async (env, mesaDir) => {
31161
31212
  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));
31162
31213
 
31163
31214
  // src/guest/toolchains/native/msvc/index.ts
31164
- import fs42 from "node:fs";
31165
- import path53 from "node:path";
31215
+ import fs43 from "node:fs";
31216
+ import path54 from "node:path";
31166
31217
 
31167
31218
  // src/guest/toolchains/native/msvc/environment.ts
31168
- import fs40 from "node:fs";
31169
- import path51 from "node:path";
31219
+ import fs41 from "node:fs";
31220
+ import path52 from "node:path";
31170
31221
 
31171
31222
  // src/guest/toolchains/native/msvc/tree.ts
31172
- import fs39 from "node:fs";
31173
- import path50 from "node:path";
31223
+ import fs40 from "node:fs";
31224
+ import path51 from "node:path";
31174
31225
  var ROOT = tool("msvc");
31175
- var MARKER2 = path50.join(ROOT, ".installed.json");
31226
+ var MARKER2 = path51.join(ROOT, ".installed.json");
31176
31227
  function msvcTools(msvc, ...parts2) {
31177
- return path50.join(ROOT, "VC", "Tools", "MSVC", msvc, ...parts2);
31228
+ return path51.join(ROOT, "VC", "Tools", "MSVC", msvc, ...parts2);
31178
31229
  }
31179
31230
  function hostBin(msvc, ...parts2) {
31180
31231
  return msvcTools(msvc, "bin", "Hostx64", "x64", ...parts2);
@@ -31185,27 +31236,27 @@ function hasCompiler(msvc) {
31185
31236
  var InstalledSchema = external_exports.object({ msvc: external_exports.string().min(1), sdk: external_exports.string().min(1), want: external_exports.string() });
31186
31237
  function readInstalled() {
31187
31238
  try {
31188
- return InstalledSchema.safeParse(JSON.parse(fs39.readFileSync(MARKER2, "utf8"))).data ?? null;
31239
+ return InstalledSchema.safeParse(JSON.parse(fs40.readFileSync(MARKER2, "utf8"))).data ?? null;
31189
31240
  } catch {
31190
31241
  return null;
31191
31242
  }
31192
31243
  }
31193
31244
 
31194
31245
  // src/guest/toolchains/native/msvc/environment.ts
31195
- var VSWHERE_DIR = path51.join(
31246
+ var VSWHERE_DIR = path52.join(
31196
31247
  process.env["ProgramFiles(x86)"] ?? "C:\\Program Files (x86)",
31197
31248
  "Microsoft Visual Studio",
31198
31249
  "Installer"
31199
31250
  );
31200
31251
  function vcvars(root, msvc, sdk) {
31201
- const vc = path51.join(root, "VC", "Tools", "MSVC", msvc);
31202
- const kits = path51.join(root, "Windows Kits", "10");
31203
- const inc = (...p) => path51.join(kits, "Include", sdk, ...p);
31204
- const lib = (...p) => path51.join(kits, "Lib", sdk, ...p);
31252
+ const vc = path52.join(root, "VC", "Tools", "MSVC", msvc);
31253
+ const kits = path52.join(root, "Windows Kits", "10");
31254
+ const inc = (...p) => path52.join(kits, "Include", sdk, ...p);
31255
+ const lib = (...p) => path52.join(kits, "Lib", sdk, ...p);
31205
31256
  return {
31206
31257
  vars: {
31207
31258
  VSINSTALLDIR: root + "\\",
31208
- VCINSTALLDIR: path51.join(root, "VC") + "\\",
31259
+ VCINSTALLDIR: path52.join(root, "VC") + "\\",
31209
31260
  VCToolsInstallDir: vc + "\\",
31210
31261
  VCToolsVersion: msvc,
31211
31262
  VisualStudioVersion: "17.0",
@@ -31217,17 +31268,17 @@ function vcvars(root, msvc, sdk) {
31217
31268
  VSCMD_ARG_HOST_ARCH: "x64",
31218
31269
  VSCMD_ARG_TGT_ARCH: "x64",
31219
31270
  Platform: "x64",
31220
- INCLUDE: [path51.join(vc, "include"), inc("ucrt"), inc("shared"), inc("um"), inc("winrt"), inc("cppwinrt")].join(
31271
+ INCLUDE: [path52.join(vc, "include"), inc("ucrt"), inc("shared"), inc("um"), inc("winrt"), inc("cppwinrt")].join(
31221
31272
  ";"
31222
31273
  ),
31223
- LIB: [path51.join(vc, "lib", "x64"), lib("ucrt", "x64"), lib("um", "x64")].join(";"),
31224
- LIBPATH: [path51.join(vc, "lib", "x64"), path51.join(vc, "lib", "x86", "store", "references")].join(";")
31274
+ LIB: [path52.join(vc, "lib", "x64"), lib("ucrt", "x64"), lib("um", "x64")].join(";"),
31275
+ LIBPATH: [path52.join(vc, "lib", "x64"), path52.join(vc, "lib", "x86", "store", "references")].join(";")
31225
31276
  },
31226
- path: [path51.join(vc, "bin", "Hostx64", "x64"), path51.join(kits, "bin", sdk, "x64")]
31277
+ path: [path52.join(vc, "bin", "Hostx64", "x64"), path52.join(kits, "bin", sdk, "x64")]
31227
31278
  };
31228
31279
  }
31229
31280
  function writeVcvars(env) {
31230
- const dir = mkdirp(path51.join(ROOT, "VC", "Auxiliary", "Build"));
31281
+ const dir = mkdirp(path52.join(ROOT, "VC", "Auxiliary", "Build"));
31231
31282
  const lines = [
31232
31283
  "@echo off",
31233
31284
  "rem Written by Windows Development Sandbox for its portable MSVC (host x64, target x64).",
@@ -31235,9 +31286,9 @@ function writeVcvars(env) {
31235
31286
  'set "PATH=' + env.path.join(";") + ';%PATH%"',
31236
31287
  "exit /b 0"
31237
31288
  ];
31238
- fs40.writeFileSync(path51.join(dir, "vcvars64.bat"), lines.join("\r\n") + "\r\n");
31239
- fs40.writeFileSync(
31240
- path51.join(dir, "vcvarsall.bat"),
31289
+ fs41.writeFileSync(path52.join(dir, "vcvars64.bat"), lines.join("\r\n") + "\r\n");
31290
+ fs41.writeFileSync(
31291
+ path52.join(dir, "vcvarsall.bat"),
31241
31292
  ["@echo off", "rem Only x64 (amd64) is installed.", 'call "%~dp0vcvars64.bat"', "exit /b %errorlevel%"].join(
31242
31293
  "\r\n"
31243
31294
  ) + "\r\n"
@@ -31245,24 +31296,24 @@ function writeVcvars(env) {
31245
31296
  }
31246
31297
  function installVswhere(msvc) {
31247
31298
  mkdirp(VSWHERE_DIR);
31248
- fs40.copyFileSync(ensureCompiled("vswhere"), path51.join(VSWHERE_DIR, "vswhere.exe"));
31299
+ fs41.copyFileSync(ensureCompiled("vswhere"), path52.join(VSWHERE_DIR, "vswhere.exe"));
31249
31300
  const [major, minor] = msvc.split(".").slice(2);
31250
- fs40.writeFileSync(
31251
- path51.join(VSWHERE_DIR, "vswhere.json"),
31301
+ fs41.writeFileSync(
31302
+ path52.join(VSWHERE_DIR, "vswhere.json"),
31252
31303
  JSON.stringify({ installationPath: ROOT, installationVersion: "17." + (minor ?? "0") + ".0." + (major ?? "0") })
31253
31304
  );
31254
31305
  }
31255
31306
  function removeTelemetry(msvc) {
31256
31307
  try {
31257
- fs40.rmSync(hostBin(msvc, "vctip.exe"), { force: true });
31308
+ fs41.rmSync(hostBin(msvc, "vctip.exe"), { force: true });
31258
31309
  } catch (e) {
31259
31310
  warn("Could not remove MSVC's telemetry helper (vctip.exe); it may keep tools\\msvc locked: " + errMsg(e));
31260
31311
  }
31261
31312
  }
31262
31313
 
31263
31314
  // src/guest/toolchains/native/msvc/packages.ts
31264
- import fs41 from "node:fs";
31265
- import path52 from "node:path";
31315
+ import fs42 from "node:fs";
31316
+ import path53 from "node:path";
31266
31317
  var CHANNEL = "https://aka.ms/vs/17/release/channel";
31267
31318
  var MANIFEST_DAY_MS = 24 * 60 * 60 * 1e3;
31268
31319
  var MSVC_PARTS = [
@@ -31288,10 +31339,10 @@ var SDK_MSIS = [
31288
31339
  "Windows SDK Desktop Tools x64-x86_en-us.msi"
31289
31340
  ];
31290
31341
  var manifest = async () => {
31291
- const cached2 = path52.join(ROOT, ".manifest.json");
31292
- if (exists(cached2) && Date.now() - fs41.statSync(cached2).mtimeMs < MANIFEST_DAY_MS) {
31342
+ const cached2 = path53.join(ROOT, ".manifest.json");
31343
+ if (exists(cached2) && Date.now() - fs42.statSync(cached2).mtimeMs < MANIFEST_DAY_MS) {
31293
31344
  try {
31294
- return JSON.parse(fs41.readFileSync(cached2, "utf8"));
31345
+ return JSON.parse(fs42.readFileSync(cached2, "utf8"));
31295
31346
  } catch {
31296
31347
  }
31297
31348
  }
@@ -31300,26 +31351,26 @@ var manifest = async () => {
31300
31351
  if (!item) throw new Error("the Visual Studio channel has no package manifest");
31301
31352
  mkdirp(ROOT);
31302
31353
  await downloader.file(item.url, cached2);
31303
- return JSON.parse(fs41.readFileSync(cached2, "utf8"));
31354
+ return JSON.parse(fs42.readFileSync(cached2, "utf8"));
31304
31355
  };
31305
31356
  var unpackVsix = async (vsix, work) => {
31306
- const out = mkdirp(path52.join(work, "vsix-" + path52.basename(vsix)));
31357
+ const out = mkdirp(path53.join(work, "vsix-" + path53.basename(vsix)));
31307
31358
  await extractArchive(vsix, out, ["Contents"]);
31308
31359
  const decode4 = (dir) => {
31309
- for (const entry of fs41.readdirSync(dir, { withFileTypes: true })) {
31310
- const from = path52.join(dir, entry.name);
31360
+ for (const entry of fs42.readdirSync(dir, { withFileTypes: true })) {
31361
+ const from = path53.join(dir, entry.name);
31311
31362
  let name = entry.name;
31312
31363
  try {
31313
31364
  if (name.includes("%")) name = decodeURIComponent(name);
31314
31365
  } catch {
31315
31366
  }
31316
- const to = path52.join(dir, name);
31317
- if (to !== from) fs41.renameSync(from, to);
31367
+ const to = path53.join(dir, name);
31368
+ if (to !== from) fs42.renameSync(from, to);
31318
31369
  if (entry.isDirectory()) decode4(to);
31319
31370
  }
31320
31371
  };
31321
31372
  decode4(out);
31322
- fs41.cpSync(path52.join(out, "Contents"), ROOT, { recursive: true, force: true });
31373
+ fs42.cpSync(path53.join(out, "Contents"), ROOT, { recursive: true, force: true });
31323
31374
  safeRemove(out, work);
31324
31375
  };
31325
31376
  var unpackMsi = async (msi) => {
@@ -31329,9 +31380,9 @@ var unpackMsi = async (msi) => {
31329
31380
  stdio: "ignore"
31330
31381
  });
31331
31382
  } catch (e) {
31332
- const lines = exists(logFile2) ? fs41.readFileSync(logFile2, "utf16le").split(/\r?\n/).filter((l) => /error|return value 3|failed/i.test(l)).slice(-4).join(" | ") : "";
31383
+ const lines = exists(logFile2) ? fs42.readFileSync(logFile2, "utf16le").split(/\r?\n/).filter((l) => /error|return value 3|failed/i.test(l)).slice(-4).join(" | ") : "";
31333
31384
  throw new Error(
31334
- path52.basename(msi) + " did not unpack: " + (e instanceof Error ? e.message : String(e)) + (lines ? " (" + lines.slice(0, 600) + ")" : "")
31385
+ path53.basename(msi) + " did not unpack: " + (e instanceof Error ? e.message : String(e)) + (lines ? " (" + lines.slice(0, 600) + ")" : "")
31335
31386
  );
31336
31387
  }
31337
31388
  };
@@ -31344,13 +31395,13 @@ var catalogue = (m) => {
31344
31395
  };
31345
31396
  };
31346
31397
  var payloadFetcher = (work) => async (p) => {
31347
- const file3 = path52.join(work, path52.basename(p.fileName.replace(/\\/g, "/")));
31398
+ const file3 = path53.join(work, path53.basename(p.fileName.replace(/\\/g, "/")));
31348
31399
  if (!exists(file3)) await downloader.file(p.url, file3, p.sha256);
31349
31400
  return file3;
31350
31401
  };
31351
31402
  var unpackedToolset = () => {
31352
- const toolsRoot = path52.join(ROOT, "VC", "Tools", "MSVC");
31353
- return fs41.readdirSync(toolsRoot).filter((d) => exists(hostBin(d, "cl.exe"))).sort((a, b) => a.localeCompare(b, void 0, { numeric: true })).pop();
31403
+ const toolsRoot = path53.join(ROOT, "VC", "Tools", "MSVC");
31404
+ return fs42.readdirSync(toolsRoot).filter((d) => exists(hostBin(d, "cl.exe"))).sort((a, b) => a.localeCompare(b, void 0, { numeric: true })).pop();
31354
31405
  };
31355
31406
  async function installPackages(config2) {
31356
31407
  const { ids, pick: pick3 } = catalogue(await manifest());
@@ -31358,7 +31409,7 @@ async function installPackages(config2) {
31358
31409
  if (!version2) throw new Error("no MSVC " + config2.msvcVersion + " in the Visual Studio manifest");
31359
31410
  const sdk = pickWindowsSdk(ids, config2.sdkVersion);
31360
31411
  if (!sdk) throw new Error("no Windows SDK " + config2.sdkVersion + " in the Visual Studio manifest");
31361
- const work = mkdirp(path52.join(ROOT, ".download"));
31412
+ const work = mkdirp(path53.join(ROOT, ".download"));
31362
31413
  const fetchPayload = payloadFetcher(work);
31363
31414
  log("Downloading the MSVC " + version2 + " compiler and C/C++ libraries ...");
31364
31415
  for (const part of MSVC_PARTS) {
@@ -31378,17 +31429,17 @@ async function installPackages(config2) {
31378
31429
  if (!p) throw new Error("the Windows SDK package has no " + name);
31379
31430
  const file3 = await fetchPayload(p);
31380
31431
  msis.push(file3);
31381
- for (const cab of msiCabs(fs41.readFileSync(file3))) {
31432
+ for (const cab of msiCabs(fs42.readFileSync(file3))) {
31382
31433
  const c = payload(cab);
31383
31434
  if (c) await fetchPayload(c);
31384
31435
  }
31385
31436
  }
31386
31437
  log("Unpacking the Windows SDK (a few minutes) ...");
31387
31438
  for (const msi of msis) await unpackMsi(msi);
31388
- for (const name of fs41.readdirSync(ROOT).filter((n) => n.toLowerCase().endsWith(".msi")))
31389
- fs41.rmSync(path52.join(ROOT, name), { force: true });
31439
+ for (const name of fs42.readdirSync(ROOT).filter((n) => n.toLowerCase().endsWith(".msi")))
31440
+ fs42.rmSync(path53.join(ROOT, name), { force: true });
31390
31441
  safeRemove(work, ROOT);
31391
- const sdkVersion = fs41.readdirSync(path52.join(ROOT, "Windows Kits", "10", "Include")).filter((d) => d.startsWith("10.0." + sdk.build)).sort().pop();
31442
+ const sdkVersion = fs42.readdirSync(path53.join(ROOT, "Windows Kits", "10", "Include")).filter((d) => d.startsWith("10.0." + sdk.build)).sort().pop();
31392
31443
  if (!sdkVersion) throw new Error("the Windows SDK did not unpack (no Include\\10.0." + sdk.build + ".*)");
31393
31444
  const toolset = unpackedToolset();
31394
31445
  if (!toolset) throw new Error("MSVC " + version2 + " did not unpack (no cl.exe under VC\\Tools\\MSVC)");
@@ -31402,8 +31453,8 @@ function installedMsvcEnv() {
31402
31453
  }
31403
31454
  var clearTree = () => {
31404
31455
  if (!exists(ROOT)) return;
31405
- for (const name of fs42.readdirSync(ROOT).filter((n) => n !== ".manifest.json" && n !== ".download"))
31406
- safeRemove(path53.join(ROOT, name), ROOT);
31456
+ for (const name of fs43.readdirSync(ROOT).filter((n) => n !== ".manifest.json" && n !== ".download"))
31457
+ safeRemove(path54.join(ROOT, name), ROOT);
31407
31458
  };
31408
31459
  async function setupMsvc(env, config2) {
31409
31460
  if (!config2.acceptLicense) {
@@ -31434,12 +31485,11 @@ async function setupMsvc(env, config2) {
31434
31485
 
31435
31486
  // src/guest/toolchains/native/unreal.ts
31436
31487
  import os8 from "node:os";
31437
- import path57 from "node:path";
31488
+ import path59 from "node:path";
31438
31489
 
31439
31490
  // src/guest/toolchains/not-yet.ts
31440
- function notAvailableYet(env, what) {
31491
+ function notAvailableYet(_env, what) {
31441
31492
  log(what + ": not available yet (nothing installed)");
31442
- env.summary.push(what + ": not available yet");
31443
31493
  }
31444
31494
 
31445
31495
  // src/guest/toolchains/engines/unreal-engines.ts
@@ -31451,49 +31501,35 @@ async function setupUnrealEngines(env, _config, _ctx) {
31451
31501
  import fs44 from "node:fs";
31452
31502
  import path55 from "node:path";
31453
31503
 
31454
- // src/guest/toolchains/native/vcruntime.ts
31455
- import fs43 from "node:fs";
31456
- import path54 from "node:path";
31457
- var VC_REDIST = "https://aka.ms/vs/17/release/vc_redist.x64.exe";
31458
- var MICROSOFT_SIGNER = "CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US";
31459
- var OK_EXIT_CODES = [0, 1638, 3010];
31460
- var signerOf = (file3) => scriptOutput("get-signer.ps1", ["-Path", file3]).trim();
31461
- async function setupVcRuntime(env, summary = true) {
31462
- if (dryRun) {
31463
- log("(dry run) would install the Visual C++ runtime");
31464
- return false;
31465
- }
31466
- const system322 = path54.join(process.env.WINDIR ?? "C:\\Windows", "System32");
31467
- const missing = !exists(path54.join(system322, "vcruntime140.dll")) || !exists(path54.join(system322, "msvcp140.dll"));
31468
- if (missing) {
31469
- const installer = tool("vcredist", "vc_redist.x64.exe");
31470
- if (!exists(installer)) {
31471
- log("Downloading the Visual C++ runtime (~25 MB once) ...");
31472
- await downloadFile(VC_REDIST, installer);
31473
- }
31474
- if (signerOf(installer) !== MICROSOFT_SIGNER) {
31475
- fs43.rmSync(installer, { force: true });
31476
- throw new Error("vc_redist.x64.exe is not signed by Microsoft; deleted it (it is downloaded again next boot)");
31477
- }
31478
- log("Installing the Visual C++ runtime ...");
31479
- const code = await spawnAsync(installer, ["/install", "/quiet", "/norestart"]);
31480
- if (!OK_EXIT_CODES.includes(code ?? -1) || !exists(path54.join(system322, "vcruntime140.dll")))
31481
- throw new Error("the Visual C++ runtime installer failed (exit " + code + ")");
31482
- }
31483
- if (summary) env.summary.push("vc++ runtime: installed");
31484
- return missing;
31504
+ // src/shared/signer.ts
31505
+ function signerMatches(signature, signer) {
31506
+ if (!signature || !signature.subject) return false;
31507
+ const all = (text, patterns) => patterns.every((p) => new RegExp(p, "i").test(text));
31508
+ return all(signature.subject, signer.subject) && all(signature.issuer, signer.issuer ?? []);
31485
31509
  }
31486
-
31487
- // src/guest/toolchains/installers.ts
31488
31510
  var SIGNERS = {
31489
- microsoft: MICROSOFT_SIGNER,
31490
- valve: /^CN="?Valve(,| Corp)/,
31491
- unity: /^CN="?Unity Technologies/
31511
+ microsoft: { subject: ["^CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US$"] },
31512
+ valve: { subject: ['^CN="?Valve(,| Corp)'] },
31513
+ unity: { subject: ['^CN="?Unity Technologies'] }
31492
31514
  };
31515
+
31516
+ // src/guest/toolchains/signature.ts
31517
+ var SignatureSchema = external_exports.object({ subject: external_exports.string().max(4096), issuer: external_exports.string().max(4096) });
31518
+ function signatureOf(file3) {
31519
+ const text = scriptOutput("get-signature.ps1", ["-Path", file3]).trim();
31520
+ if (!text) return null;
31521
+ try {
31522
+ const parsed = SignatureSchema.safeParse(JSON.parse(text));
31523
+ return parsed.success ? parsed.data : null;
31524
+ } catch {
31525
+ return null;
31526
+ }
31527
+ }
31493
31528
  function signedBy(file3, signer) {
31494
- const subject = signerOf(file3);
31495
- return typeof signer === "string" ? subject === signer : signer.test(subject);
31529
+ return signerMatches(signatureOf(file3), signer);
31496
31530
  }
31531
+
31532
+ // src/guest/toolchains/installers.ts
31497
31533
  function signatureCheck(signer, what) {
31498
31534
  return (file3) => {
31499
31535
  if (!signedBy(file3, signer)) throw new Error(what + " is not signed by its vendor");
@@ -31514,55 +31550,12 @@ async function signedInstaller(url2, file3, what, signer, sha256 = null) {
31514
31550
  return file3;
31515
31551
  }
31516
31552
 
31517
- // src/guest/toolchains/native/visual-studio.ts
31518
- import fs46 from "node:fs";
31519
- import os7 from "node:os";
31520
- import path56 from "node:path";
31521
-
31522
- // src/guest/toolchains/persisted.ts
31553
+ // src/guest/toolchains/native/autosdk.ts
31523
31554
  import fs45 from "node:fs";
31524
-
31525
- // src/shared/installs.ts
31526
- var InstallRecordSchema = external_exports.object({
31527
- name: external_exports.string().max(100),
31528
- version: external_exports.string().max(100),
31529
- sizeBytes: external_exports.number().nonnegative().nullable(),
31530
- installedAt: external_exports.string().max(64),
31531
- usedAt: external_exports.string().max(64)
31532
- });
31533
- var InstallRecordsSchema = external_exports.object({ installs: external_exports.array(InstallRecordSchema).max(1e3) });
31534
-
31535
- // src/guest/toolchains/persisted.ts
31536
- var GB = 1024 ** 3;
31537
- var LOCAL_RESERVE_BYTES = 13 * GB;
31538
- function freeBytes(dir, deps = {}) {
31539
- try {
31540
- const s = (deps.statfs ?? fs45.statfsSync)(dir);
31541
- return s.bavail * s.bsize;
31542
- } catch {
31543
- return 0;
31544
- }
31545
- }
31546
- var gb = (bytes) => (bytes / GB).toFixed(1) + " GB";
31547
- function assertRoom(dir, needBytes, what, fix, deps = {}) {
31548
- const free = freeBytes(dir, deps);
31549
- if (free < needBytes)
31550
- throw new Error(
31551
- "not installing " + what + ": " + gb(free) + " free where it goes, it needs " + gb(needBytes) + ". " + fix
31552
- );
31553
- }
31554
- function assertLocalRoom(needBytes, what, deps = {}) {
31555
- const drive = deps.localDir ?? (process.env.SystemDrive ?? "C:") + "\\";
31556
- assertRoom(
31557
- drive,
31558
- needBytes + LOCAL_RESERVE_BYTES,
31559
- what,
31560
- "The sandbox's own disk also holds the paging file and every build: give the sandbox less to install, or a smaller sandbox.pageFileMb.",
31561
- deps
31562
- );
31563
- }
31555
+ import path57 from "node:path";
31564
31556
 
31565
31557
  // src/guest/toolchains/native/vs-request.ts
31558
+ import path56 from "node:path";
31566
31559
  var UNREAL_COMPONENTS = [
31567
31560
  "Microsoft.VisualStudio.Workload.NativeGame",
31568
31561
  "Microsoft.VisualStudio.Component.VC.Tools.x86.x64",
@@ -31580,7 +31573,7 @@ var BUILD_TOOLS_COMPONENTS = [
31580
31573
  ];
31581
31574
  var isOn = (setting) => setting === true;
31582
31575
  function visualStudioWanted(t, on = isOn) {
31583
- const unreal = on(t.unreal.enabled, "unreal");
31576
+ const unreal = on(t.unreal.enabled, "unreal") && t.unreal.visualStudio === "full";
31584
31577
  const flutter = on(t.flutter.enabled, "flutter") && t.flutter.windowsDesktop;
31585
31578
  const unity = on(t.unity.enabled, "unity") && t.unity.modules.includes("windows-il2cpp");
31586
31579
  const users = [...unreal ? ["unreal"] : [], ...flutter ? ["flutter"] : [], ...unity ? ["unity"] : []];
@@ -31601,6 +31594,122 @@ function visualStudioWanted(t, on = isOn) {
31601
31594
  accepted: t.msvc.acceptLicense
31602
31595
  };
31603
31596
  }
31597
+ function unrealUsesAutosdk(t, on = isOn) {
31598
+ return on(t.unreal.enabled, "unreal") && t.unreal.visualStudio === "autosdk";
31599
+ }
31600
+ function vsExitText(code) {
31601
+ const c = code >>> 0;
31602
+ switch (c) {
31603
+ case 0:
31604
+ return "installed";
31605
+ case 3010:
31606
+ return "done; a restart would finish it (not needed here)";
31607
+ case 1602:
31608
+ return "cancelled";
31609
+ case 5007:
31610
+ return "the installer refused to run (blocked by Windows, for example a restart waiting)";
31611
+ case 8006:
31612
+ return "Visual Studio is running and must be closed first";
31613
+ case 3762504530:
31614
+ return "0xE0434352: the Visual Studio installer crashed";
31615
+ default:
31616
+ return "the installer failed with exit " + c + " (0x" + c.toString(16).toUpperCase() + ")";
31617
+ }
31618
+ }
31619
+ var LAYOUT_STAGING_BYTES = 12 * 1024 ** 3;
31620
+ function layoutNextStep(exit, localFreeBytes, reserveBytes) {
31621
+ if (exit !== null && (exit === 0 || exit === 3010)) return "done";
31622
+ return localFreeBytes >= LAYOUT_STAGING_BYTES + reserveBytes ? "stage" : "skip";
31623
+ }
31624
+ function autosdkLayout(msvcRoot, msvc, sdk, autosdkRoot) {
31625
+ const win64 = path56.win32.join(autosdkRoot, "HostWin64", "Win64");
31626
+ return [
31627
+ {
31628
+ from: path56.win32.join(msvcRoot, "VC", "Tools", "MSVC", msvc),
31629
+ to: path56.win32.join(win64, "VS2022", msvc)
31630
+ },
31631
+ ...["Include", "Lib", "bin"].map((part) => ({
31632
+ from: path56.win32.join(msvcRoot, "Windows Kits", "10", part, sdk),
31633
+ to: path56.win32.join(win64, "Windows Kits", "10", part, sdk)
31634
+ }))
31635
+ ];
31636
+ }
31637
+
31638
+ // src/guest/toolchains/native/autosdk.ts
31639
+ var AUTOSDK_DIR = tool("unreal", "autosdk");
31640
+ var MARKER3 = path57.join(AUTOSDK_DIR, ".complete.json");
31641
+ var MarkerSchema = external_exports.object({ msvc: external_exports.string(), sdk: external_exports.string() });
31642
+ function builtFor(msvc, sdk) {
31643
+ try {
31644
+ const done = MarkerSchema.parse(JSON.parse(fs45.readFileSync(MARKER3, "utf8")));
31645
+ return done.msvc === msvc && done.sdk === sdk;
31646
+ } catch {
31647
+ return false;
31648
+ }
31649
+ }
31650
+ async function setupAutosdk(env) {
31651
+ const msvc = readInstalled();
31652
+ if (!msvc || !hasCompiler(msvc.msvc))
31653
+ throw new Error(
31654
+ 'toolchains.unreal.visualStudio = "autosdk" builds from the portable MSVC, which is not installed (is toolchains.msvc off?)'
31655
+ );
31656
+ if (!builtFor(msvc.msvc, msvc.sdk)) {
31657
+ log("Making the Unreal AutoSDK from MSVC " + msvc.msvc + " (~2 GB, once) ...");
31658
+ fs45.rmSync(MARKER3, { force: true });
31659
+ for (const pair of autosdkLayout(ROOT, msvc.msvc, msvc.sdk, AUTOSDK_DIR)) {
31660
+ mkdirp(pair.to);
31661
+ const code = await spawnAsync(SYSTEM.robocopy(), [pair.from, pair.to, "/E", "/COPY:DAT", "/R:1", "/W:1", "/NP"]);
31662
+ if (robocopyFailed(code))
31663
+ throw new Error("could not copy " + pair.from + " into the AutoSDK (robocopy " + code + ")");
31664
+ }
31665
+ writeJsonAtomic(MARKER3, { msvc: msvc.msvc, sdk: msvc.sdk });
31666
+ }
31667
+ if (!exists(MARKER3)) throw new Error("the Unreal AutoSDK was not completed");
31668
+ env.vars["UE_SDKS_ROOT"] = AUTOSDK_DIR;
31669
+ env.summary.push(
31670
+ "unreal autosdk: MSVC " + msvc.msvc + ", Windows SDK " + msvc.sdk + " (UE_SDKS_ROOT=" + AUTOSDK_DIR + ")"
31671
+ );
31672
+ }
31673
+
31674
+ // src/guest/toolchains/native/visual-studio.ts
31675
+ import fs46 from "node:fs";
31676
+ import os7 from "node:os";
31677
+ import path58 from "node:path";
31678
+
31679
+ // src/shared/installs.ts
31680
+ var InstallRecordSchema = external_exports.object({
31681
+ name: external_exports.string().max(100),
31682
+ version: external_exports.string().max(100),
31683
+ sizeBytes: external_exports.number().nonnegative().nullable(),
31684
+ installedAt: external_exports.string().max(64),
31685
+ usedAt: external_exports.string().max(64)
31686
+ });
31687
+ var InstallRecordsSchema = external_exports.object({ installs: external_exports.array(InstallRecordSchema).max(1e3) });
31688
+
31689
+ // src/guest/toolchains/persisted.ts
31690
+ var GB = 1024 ** 3;
31691
+ var LOCAL_RESERVE_BYTES = 13 * GB;
31692
+ function freeBytes(dir, deps = {}) {
31693
+ return freeBytesAt(dir, deps.statfs) ?? 0;
31694
+ }
31695
+ var gb = (bytes) => (bytes / GB).toFixed(1) + " GB";
31696
+ function assertRoom(dir, needBytes, what, fix, deps = {}) {
31697
+ const free = freeBytes(dir, deps);
31698
+ if (free < needBytes)
31699
+ throw new Error(
31700
+ "not installing " + what + ": " + gb(free) + " free where it goes, it needs " + gb(needBytes) + ". " + fix
31701
+ );
31702
+ }
31703
+ function assertLocalRoom(needBytes, what, deps = {}) {
31704
+ const drive = deps.localDir ?? (process.env.SystemDrive ?? "C:") + "\\";
31705
+ assertRoom(
31706
+ drive,
31707
+ needBytes + LOCAL_RESERVE_BYTES,
31708
+ what,
31709
+ "The sandbox's own disk also holds the paging file and every build: give the sandbox less to install, or a smaller sandbox.pageFileMb.",
31710
+ deps
31711
+ );
31712
+ }
31604
31713
 
31605
31714
  // src/guest/toolchains/native/visual-studio.ts
31606
31715
  var BOOTSTRAPPERS = {
@@ -31619,12 +31728,12 @@ var INSTALL_BYTES = {
31619
31728
  community: 7 * 1024 ** 3,
31620
31729
  buildtools: 5 * 1024 ** 3
31621
31730
  };
31622
- var OK_EXIT_CODES2 = [0, 3010];
31731
+ var OK_EXIT_CODES = [0, 3010];
31623
31732
  var LAYOUT_ROOM_BYTES = 15 * 1024 ** 3;
31624
31733
  var ID = /^[A-Za-z0-9][A-Za-z0-9._-]{0,199}$/;
31625
31734
  var VS_DIR = tool("visualstudio");
31626
31735
  var LayoutSchema = external_exports.object({ components: external_exports.array(external_exports.string()) });
31627
- var VSWHERE = path56.join(
31736
+ var VSWHERE = path58.join(
31628
31737
  process.env["ProgramFiles(x86)"] ?? "C:\\Program Files (x86)",
31629
31738
  "Microsoft Visual Studio",
31630
31739
  "Installer",
@@ -31645,12 +31754,56 @@ function installedVs() {
31645
31754
  return at ? { path: at, version: ask("installationVersion") || "installed" } : null;
31646
31755
  }
31647
31756
  function layoutDir(product) {
31648
- return path56.join(VS_DIR, product === "community" ? "layout" : "layout-buildtools");
31757
+ return path58.join(VS_DIR, product === "community" ? "layout" : "layout-buildtools");
31758
+ }
31759
+ var layoutArgs = (req, folder) => [
31760
+ "--layout",
31761
+ folder,
31762
+ "--lang",
31763
+ "en-US",
31764
+ "--quiet",
31765
+ "--wait",
31766
+ ...req.components.flatMap((id) => ["--add", id])
31767
+ ];
31768
+ function newestBootstrapperLog(folders) {
31769
+ const logs = folders.flatMap((dir) => {
31770
+ try {
31771
+ return fs46.readdirSync(dir).filter((n) => /^dd_bootstrapper_.*\.log$/i.test(n)).map((n) => path58.join(dir, n));
31772
+ } catch {
31773
+ return [];
31774
+ }
31775
+ });
31776
+ const stamp = (f) => {
31777
+ try {
31778
+ return fs46.statSync(f).mtimeMs;
31779
+ } catch {
31780
+ return 0;
31781
+ }
31782
+ };
31783
+ return logs.sort((x, y) => stamp(y) - stamp(x))[0] ?? null;
31784
+ }
31785
+ function reportLayoutFailure(code, temps) {
31786
+ warn("Visual Studio: saving the install files failed (exit " + code + "): " + vsExitText(code));
31787
+ const found = newestBootstrapperLog(temps);
31788
+ if (!found) return;
31789
+ const kept = path58.join(logsDir, "vs-layout-" + (/* @__PURE__ */ new Date()).toISOString().slice(0, 10) + ".log");
31790
+ try {
31791
+ fs46.mkdirSync(logsDir, { recursive: true });
31792
+ fs46.copyFileSync(found, kept);
31793
+ warn("Visual Studio: the installer log is " + found + " (a copy is in " + kept + ")");
31794
+ } catch (e) {
31795
+ warn("Visual Studio: the installer log is " + found + " (could not copy it: " + errMsg(e) + ")");
31796
+ }
31797
+ }
31798
+ async function copyLayout(from, to) {
31799
+ mkdirp(to);
31800
+ const code = await spawnAsync(SYSTEM.robocopy(), [from, to, "/E", "/COPY:DAT", "/R:1", "/W:1", "/MT:8", "/NP"]);
31801
+ return !robocopyFailed(code);
31649
31802
  }
31650
31803
  async function layoutInstaller(req, bootstrapper) {
31651
31804
  const layout = layoutDir(req.product);
31652
- const marker = path56.join(layout, ".complete.json");
31653
- const installer = path56.join(layout, BOOTSTRAPPERS[req.product].file);
31805
+ const marker = path58.join(layout, ".complete.json");
31806
+ const installer = path58.join(layout, BOOTSTRAPPERS[req.product].file);
31654
31807
  const has = () => {
31655
31808
  if (!exists(marker) || !exists(installer)) return false;
31656
31809
  try {
@@ -31660,6 +31813,10 @@ async function layoutInstaller(req, bootstrapper) {
31660
31813
  return false;
31661
31814
  }
31662
31815
  };
31816
+ const finish = () => {
31817
+ writeJsonAtomic(marker, { components: [...req.components] });
31818
+ return installer;
31819
+ };
31663
31820
  if (has()) return installer;
31664
31821
  if (freeBytes(mkdirp(VS_DIR)) < LAYOUT_ROOM_BYTES) {
31665
31822
  warn(
@@ -31669,27 +31826,36 @@ async function layoutInstaller(req, bootstrapper) {
31669
31826
  }
31670
31827
  log("Saving the Visual Studio install files for later boots (~10 GB, once) ...");
31671
31828
  fs46.rmSync(marker, { force: true });
31672
- const code = await spawnAsync(bootstrapper, [
31673
- "--layout",
31674
- layout,
31675
- "--lang",
31676
- "en-US",
31677
- "--quiet",
31678
- "--wait",
31679
- ...req.components.flatMap((id) => ["--add", id])
31680
- ]);
31681
- if (!OK_EXIT_CODES2.includes(code) || !exists(installer)) {
31682
- warn("Visual Studio: saving the install files failed (exit " + code + "); downloading this boot");
31829
+ const scratch = mkdirp(path58.join(VS_DIR, "tmp"));
31830
+ const code = await spawnAsync(bootstrapper, layoutArgs(req, layout), {
31831
+ env: { ...process.env, TEMP: scratch, TMP: scratch }
31832
+ });
31833
+ if (OK_EXIT_CODES.includes(code) && exists(installer)) return finish();
31834
+ reportLayoutFailure(code, [scratch, os7.tmpdir()]);
31835
+ const drive = (process.env.SystemDrive ?? "C:") + "\\";
31836
+ if (layoutNextStep(code, freeBytes(drive), LOCAL_RESERVE_BYTES) !== "stage") {
31837
+ warn("Visual Studio: not enough room on " + drive + " to build the install files there; downloading this boot");
31683
31838
  return null;
31684
31839
  }
31685
- writeJsonAtomic(marker, { components: [...req.components] });
31686
- return installer;
31840
+ const staging = path58.join(drive, "vs-layout-staging");
31841
+ log("Building the install files on " + drive + " and copying them to " + layout + " ...");
31842
+ const stagedCode = await spawnAsync(bootstrapper, layoutArgs(req, staging));
31843
+ const staged = path58.join(staging, BOOTSTRAPPERS[req.product].file);
31844
+ let kept = false;
31845
+ if (OK_EXIT_CODES.includes(stagedCode) && exists(staged)) {
31846
+ kept = await copyLayout(staging, layout);
31847
+ if (!kept) warn("Visual Studio: copying the install files to " + layout + " failed");
31848
+ } else {
31849
+ reportLayoutFailure(stagedCode, [os7.tmpdir()]);
31850
+ }
31851
+ safeRemove(staging, drive);
31852
+ return kept && exists(installer) ? finish() : null;
31687
31853
  }
31688
31854
  async function install(req, keepInstallFiles) {
31689
31855
  const boot = BOOTSTRAPPERS[req.product];
31690
31856
  const bootstrapper = await signedInstaller(
31691
31857
  boot.url,
31692
- path56.join(VS_DIR, boot.file),
31858
+ path58.join(VS_DIR, boot.file),
31693
31859
  "the " + boot.name + " installer",
31694
31860
  SIGNERS.microsoft
31695
31861
  );
@@ -31710,9 +31876,9 @@ async function install(req, keepInstallFiles) {
31710
31876
  ...installer ? ["--noWeb"] : [],
31711
31877
  ...req.components.flatMap((id) => ["--add", id])
31712
31878
  ]);
31713
- if (!OK_EXIT_CODES2.includes(code) || !installedVs())
31879
+ if (!OK_EXIT_CODES.includes(code) || !installedVs())
31714
31880
  throw new Error(
31715
- "the Visual Studio installer failed (exit " + code + "); its logs are the dd_*.log files in " + os7.tmpdir()
31881
+ "the Visual Studio installer failed (exit " + code + ": " + vsExitText(code) + "); its logs are the dd_*.log files in " + os7.tmpdir()
31716
31882
  );
31717
31883
  }
31718
31884
  async function ensureVisualStudio(env, req, o) {
@@ -31738,20 +31904,20 @@ async function ensureVisualStudio(env, req, o) {
31738
31904
  // src/guest/toolchains/native/unreal.ts
31739
31905
  var DIRECTX_URL = "https://download.microsoft.com/download/8/4/A/84A35BF1-DAFE-4AE8-82AF-AD2AE20B6B14/directx_Jun2010_redist.exe";
31740
31906
  async function installDirectX() {
31741
- const system322 = path57.join(process.env.WINDIR ?? "C:\\Windows", "System32");
31742
- if (exists(path57.join(system322, "d3dx9_43.dll")) && exists(path57.join(system322, "XAudio2_7.dll"))) return;
31907
+ const system322 = path59.join(process.env.WINDIR ?? "C:\\Windows", "System32");
31908
+ if (exists(path59.join(system322, "d3dx9_43.dll")) && exists(path59.join(system322, "XAudio2_7.dll"))) return;
31743
31909
  const redist = await signedInstaller(
31744
31910
  DIRECTX_URL,
31745
- path57.join(tool("visualstudio"), "directx_Jun2010_redist.exe"),
31911
+ path59.join(tool("visualstudio"), "directx_Jun2010_redist.exe"),
31746
31912
  "the DirectX End-User Runtime (~95 MB once)",
31747
31913
  SIGNERS.microsoft
31748
31914
  );
31749
- const unpacked = path57.join(os8.tmpdir(), "directx-redist");
31915
+ const unpacked = path59.join(os8.tmpdir(), "directx-redist");
31750
31916
  safeRemove(unpacked, os8.tmpdir());
31751
31917
  mkdirp(unpacked);
31752
- if (await spawnAsync(redist, ["/Q", "/T:" + unpacked]) !== 0 || !exists(path57.join(unpacked, "DXSETUP.exe")))
31918
+ if (await spawnAsync(redist, ["/Q", "/T:" + unpacked]) !== 0 || !exists(path59.join(unpacked, "DXSETUP.exe")))
31753
31919
  throw new Error("could not unpack the DirectX End-User Runtime");
31754
- const code = await spawnAsync(path57.join(unpacked, "DXSETUP.exe"), ["/silent"]);
31920
+ const code = await spawnAsync(path59.join(unpacked, "DXSETUP.exe"), ["/silent"]);
31755
31921
  safeRemove(unpacked, os8.tmpdir());
31756
31922
  if (code !== 0) throw new Error("the DirectX End-User Runtime installer failed (exit " + code + ")");
31757
31923
  }
@@ -31765,6 +31931,7 @@ async function setupUnreal(env, config2, ctx) {
31765
31931
  return;
31766
31932
  }
31767
31933
  await installDirectX();
31934
+ if (config2.visualStudio === "autosdk") await setupAutosdk(env);
31768
31935
  await setupUnrealEngines(env, config2, ctx);
31769
31936
  const vs = installedVs();
31770
31937
  env.summary.push(
@@ -31773,24 +31940,24 @@ async function setupUnreal(env, config2, ctx) {
31773
31940
  }
31774
31941
 
31775
31942
  // src/guest/toolchains/native/rust.ts
31776
- import path59 from "node:path";
31943
+ import path61 from "node:path";
31777
31944
 
31778
31945
  // src/guest/toolchains/native/binstall.ts
31779
31946
  import fs47 from "node:fs";
31780
- import path58 from "node:path";
31947
+ import path60 from "node:path";
31781
31948
  var ensureBinstall = async (cargoBin) => {
31782
- const target = path58.join(cargoBin, "cargo-binstall.exe");
31949
+ const target = path60.join(cargoBin, "cargo-binstall.exe");
31783
31950
  if (exists(target)) return true;
31784
31951
  try {
31785
31952
  const dir = tool("cargo-binstall");
31786
- if (!exists(path58.join(dir, "cargo-binstall.exe"))) {
31953
+ if (!exists(path60.join(dir, "cargo-binstall.exe"))) {
31787
31954
  await installFromGithub("cargo-bins/cargo-binstall", binstallAsset(arch), {
31788
31955
  dest: dir,
31789
31956
  what: "cargo-binstall for prebuilt Rust tools (~10 MB once)",
31790
31957
  locate: "cargo-binstall.exe"
31791
31958
  });
31792
31959
  }
31793
- fs47.copyFileSync(path58.join(dir, "cargo-binstall.exe"), target);
31960
+ fs47.copyFileSync(path60.join(dir, "cargo-binstall.exe"), target);
31794
31961
  return true;
31795
31962
  } catch (e) {
31796
31963
  warn("cargo-binstall unavailable, compiling crates with cargo install instead: " + errMsg(e));
@@ -31798,14 +31965,14 @@ var ensureBinstall = async (cargoBin) => {
31798
31965
  }
31799
31966
  };
31800
31967
  function crateInstaller(cargoHome, cargoEnv) {
31801
- const cargo = path58.join(cargoHome, "bin", "cargo.exe");
31968
+ const cargo = path60.join(cargoHome, "bin", "cargo.exe");
31802
31969
  let binstall = null;
31803
31970
  const binstallEnv = {
31804
31971
  ...cargoEnv,
31805
31972
  env: { ...cargoEnv.env ?? process.env, BINSTALL_DISABLE_TELEMETRY: "true" }
31806
31973
  };
31807
31974
  return async (crate) => {
31808
- binstall ??= ensureBinstall(path58.join(cargoHome, "bin"));
31975
+ binstall ??= ensureBinstall(path60.join(cargoHome, "bin"));
31809
31976
  if (await binstall) {
31810
31977
  try {
31811
31978
  await execAsync(
@@ -31827,7 +31994,7 @@ async function setupRust(env, config2, refresh) {
31827
31994
  const RUSTUP_HOME = tool("rust", "rustup");
31828
31995
  const CARGO_HOME = tool("rust", "cargo");
31829
31996
  const rustEnv = { env: { ...process.env, RUSTUP_HOME, CARGO_HOME } };
31830
- const rustup = path59.join(CARGO_HOME, "bin", "rustup.exe");
31997
+ const rustup = path61.join(CARGO_HOME, "bin", "rustup.exe");
31831
31998
  if (dryRun) {
31832
31999
  log("(dry run) would provision Rust " + config2.toolchain + " (" + config2.host + ")");
31833
32000
  return;
@@ -31863,9 +32030,9 @@ async function setupRust(env, config2, refresh) {
31863
32030
  if (refresh) await execAsync(rustup, ["update"], rustEnv);
31864
32031
  }
31865
32032
  Object.assign(env.vars, { RUSTUP_HOME, CARGO_HOME });
31866
- env.prepend.push(path59.join(CARGO_HOME, "bin"));
32033
+ env.prepend.push(path61.join(CARGO_HOME, "bin"));
31867
32034
  env.summary.push(
31868
- "rust: " + versionOf(path59.join(CARGO_HOME, "bin", "rustc.exe"), ["--version"], rustEnv) + " [" + config2.host + "]"
32035
+ "rust: " + versionOf(path61.join(CARGO_HOME, "bin", "rustc.exe"), ["--version"], rustEnv) + " [" + config2.host + "]"
31869
32036
  );
31870
32037
  const toolchainKey = "rustup@" + config2.toolchain;
31871
32038
  await installOnce(
@@ -31886,13 +32053,13 @@ async function setupRust(env, config2, refresh) {
31886
32053
  env: {
31887
32054
  ...rustEnv.env,
31888
32055
  ...msvc.vars,
31889
- PATH: [path59.join(CARGO_HOME, "bin"), ...msvc.path, process.env.PATH ?? ""].join(path59.delimiter)
32056
+ PATH: [path61.join(CARGO_HOME, "bin"), ...msvc.path, process.env.PATH ?? ""].join(path61.delimiter)
31890
32057
  }
31891
32058
  } : {
31892
32059
  env: {
31893
32060
  ...rustEnv.env,
31894
- CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER: path59.join(mingw, "gcc.exe"),
31895
- PATH: [path59.join(CARGO_HOME, "bin"), mingw, process.env.PATH ?? ""].join(path59.delimiter)
32061
+ CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER: path61.join(mingw, "gcc.exe"),
32062
+ PATH: [path61.join(CARGO_HOME, "bin"), mingw, process.env.PATH ?? ""].join(path61.delimiter)
31896
32063
  }
31897
32064
  };
31898
32065
  await installOnce(env, "cargo", config2.crates, crateInstaller(CARGO_HOME, cargoEnv));
@@ -31900,22 +32067,22 @@ async function setupRust(env, config2, refresh) {
31900
32067
 
31901
32068
  // src/guest/toolchains/languages/node.ts
31902
32069
  import fs48 from "node:fs";
31903
- import path60 from "node:path";
32070
+ import path62 from "node:path";
31904
32071
  import { spawn as spawn4 } from "node:child_process";
31905
32072
  var NVM_HOME = tool("nvm");
31906
- var NVM_SYMLINK = path60.join(localDir, "nodejs");
31907
- var HOST_NVM = path60.join(hostToolsDir, "nvm");
32073
+ var NVM_SYMLINK = path62.join(localDir, "nodejs");
32074
+ var HOST_NVM = path62.join(hostToolsDir, "nvm");
31908
32075
  var HOST_VERSIONS_MAX = 3;
31909
- var hostNvmVersions = () => exists(HOST_NVM) ? fs48.readdirSync(HOST_NVM).filter((d) => /^v\d+\.\d+\.\d+$/.test(d) && exists(path60.join(HOST_NVM, d, "node.exe"))).map((d) => d.slice(1)) : [];
32076
+ var hostNvmVersions = () => exists(HOST_NVM) ? fs48.readdirSync(HOST_NVM).filter((d) => /^v\d+\.\d+\.\d+$/.test(d) && exists(path62.join(HOST_NVM, d, "node.exe"))).map((d) => d.slice(1)) : [];
31910
32077
  var resolveNode = (spec) => resolveCached("node:" + spec, async () => {
31911
32078
  const exact = spec.replace(/^v/, "");
31912
32079
  if (/^\d+\.\d+\.\d+$/.test(exact)) return exact;
31913
32080
  const releases = await fetchJson("https://nodejs.org/dist/index.json");
31914
32081
  return pickNodeVersion(releases, spec) ?? Promise.reject(new Error('No Node.js release matches "' + spec + '"'));
31915
32082
  });
31916
- var NVM_TEMP = path60.join(NVM_HOME, ".tmp");
32083
+ var NVM_TEMP = path62.join(NVM_HOME, ".tmp");
31917
32084
  var nvm = (args) => new Promise((resolve2) => {
31918
- const child = spawn4(path60.join(NVM_HOME, "nvm.exe"), args, {
32085
+ const child = spawn4(path62.join(NVM_HOME, "nvm.exe"), args, {
31919
32086
  windowsHide: true,
31920
32087
  env: { ...process.env, NVM_HOME, NVM_SYMLINK, TEMP: NVM_TEMP, TMP: NVM_TEMP }
31921
32088
  });
@@ -31930,12 +32097,12 @@ var nvm = (args) => new Promise((resolve2) => {
31930
32097
  child.once("close", () => resolve2(out));
31931
32098
  });
31932
32099
  var ensureNvm = async () => {
31933
- if (exists(path60.join(NVM_HOME, "nvm.exe"))) return;
31934
- if (exists(path60.join(HOST_NVM, "nvm.exe"))) {
32100
+ if (exists(path62.join(NVM_HOME, "nvm.exe"))) return;
32101
+ if (exists(path62.join(HOST_NVM, "nvm.exe"))) {
31935
32102
  log("Copying nvm from this PC ...");
31936
32103
  mkdirp(NVM_HOME);
31937
32104
  const files = fs48.readdirSync(HOST_NVM).filter((f) => /\.(exe|cmd|vbs)$/i.test(f)).sort((a, b) => Number(a.toLowerCase() === "nvm.exe") - Number(b.toLowerCase() === "nvm.exe"));
31938
- for (const file3 of files) fs48.copyFileSync(path60.join(HOST_NVM, file3), path60.join(NVM_HOME, file3));
32105
+ for (const file3 of files) fs48.copyFileSync(path62.join(HOST_NVM, file3), path62.join(NVM_HOME, file3));
31939
32106
  return;
31940
32107
  }
31941
32108
  const asset = await githubAsset("coreybutler/nvm-windows", /^nvm-noinstall\.zip$/, true);
@@ -31943,14 +32110,14 @@ var ensureNvm = async () => {
31943
32110
  await downloader.archive(asset.url, NVM_HOME, { sha256: asset.sha256, locate: "nvm.exe", fileName: asset.name });
31944
32111
  };
31945
32112
  var hostNodeFolder = (version2) => {
31946
- const dir = path60.join(hostToolsDir, "node");
31947
- return session.hostTools.nodeVersion?.replace(/^v/, "") === version2 && exists(path60.join(dir, "node.exe")) ? dir : null;
32113
+ const dir = path62.join(hostToolsDir, "node");
32114
+ return session.hostTools.nodeVersion?.replace(/^v/, "") === version2 && exists(path62.join(dir, "node.exe")) ? dir : null;
31948
32115
  };
31949
32116
  var installNodeVersion = async (version2) => {
31950
- const dir = path60.join(NVM_HOME, "v" + version2);
31951
- const fromHost = path60.join(HOST_NVM, "v" + version2);
31952
- if (exists(path60.join(dir, "node.exe"))) return;
31953
- if (exists(path60.join(fromHost, "node.exe"))) {
32117
+ const dir = path62.join(NVM_HOME, "v" + version2);
32118
+ const fromHost = path62.join(HOST_NVM, "v" + version2);
32119
+ if (exists(path62.join(dir, "node.exe"))) return;
32120
+ if (exists(path62.join(fromHost, "node.exe"))) {
31954
32121
  log("Copying Node " + version2 + " from this PC's nvm (without global packages) ...");
31955
32122
  copyNode(fromHost, dir);
31956
32123
  return;
@@ -31969,19 +32136,19 @@ var installNodeVersion = async (version2) => {
31969
32136
  } finally {
31970
32137
  safeRemove(NVM_TEMP, NVM_HOME);
31971
32138
  }
31972
- if (!exists(path60.join(dir, "node.exe"))) {
32139
+ if (!exists(path62.join(dir, "node.exe"))) {
31973
32140
  const tail = out.trim().split(/\r?\n/).filter(Boolean).slice(-3).join(" ");
31974
32141
  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";
31975
32142
  throw new Error(
31976
- "nvm install " + version2 + " did not leave " + path60.join(dir, "node.exe") + " (" + why + ")" + (tail ? ". nvm printed: " + tail : "")
32143
+ "nvm install " + version2 + " did not leave " + path62.join(dir, "node.exe") + " (" + why + ")" + (tail ? ". nvm printed: " + tail : "")
31977
32144
  );
31978
32145
  }
31979
32146
  };
31980
32147
  var activate = async (version2) => {
31981
32148
  await nvm(["use", version2]);
31982
- if (exists(path60.join(NVM_SYMLINK, "node.exe"))) return;
32149
+ if (exists(path62.join(NVM_SYMLINK, "node.exe"))) return;
31983
32150
  fs48.rmSync(NVM_SYMLINK, { recursive: true, force: true });
31984
- fs48.symlinkSync(path60.join(NVM_HOME, "v" + version2), NVM_SYMLINK, "junction");
32151
+ fs48.symlinkSync(path62.join(NVM_HOME, "v" + version2), NVM_SYMLINK, "junction");
31985
32152
  };
31986
32153
  var PLAYWRIGHT_VARS = () => ({
31987
32154
  PLAYWRIGHT_BROWSERS_PATH: tool("ms-playwright"),
@@ -31994,7 +32161,7 @@ async function setupNode(env, versions, config2) {
31994
32161
  }
31995
32162
  await ensureNvm();
31996
32163
  fs48.writeFileSync(
31997
- path60.join(NVM_HOME, "settings.txt"),
32164
+ path62.join(NVM_HOME, "settings.txt"),
31998
32165
  [
31999
32166
  "root: " + NVM_HOME,
32000
32167
  "path: " + NVM_SYMLINK,
@@ -32021,7 +32188,7 @@ async function setupNode(env, versions, config2) {
32021
32188
  }
32022
32189
  }
32023
32190
  Object.assign(env.vars, { NVM_HOME, NVM_SYMLINK, ...PLAYWRIGHT_VARS() });
32024
- if (duringSession()) env.prepend.push(path60.join(NVM_HOME, "v" + main), NVM_HOME, NVM_SYMLINK);
32191
+ if (duringSession()) env.prepend.push(path62.join(NVM_HOME, "v" + main), NVM_HOME, NVM_SYMLINK);
32025
32192
  else {
32026
32193
  await activate(main);
32027
32194
  env.prepend.push(NVM_HOME, NVM_SYMLINK);
@@ -32031,13 +32198,13 @@ async function setupNode(env, versions, config2) {
32031
32198
  await packageManagers(env, config2, main);
32032
32199
  }
32033
32200
  var packageManagers = async (env, config2, version2) => {
32034
- const dir = path60.join(NVM_HOME, "v" + version2);
32035
- const nodeEnv = { ...process.env, PATH: dir + path60.delimiter + (process.env.PATH ?? "") };
32036
- const npm = (args) => execAsync(path60.join(dir, "node.exe"), [path60.join(dir, "node_modules", "npm", "bin", "npm-cli.js"), ...args], {
32201
+ const dir = path62.join(NVM_HOME, "v" + version2);
32202
+ const nodeEnv = { ...process.env, PATH: dir + path62.delimiter + (process.env.PATH ?? "") };
32203
+ const npm = (args) => execAsync(path62.join(dir, "node.exe"), [path62.join(dir, "node_modules", "npm", "bin", "npm-cli.js"), ...args], {
32037
32204
  env: nodeEnv,
32038
32205
  stdio: "ignore"
32039
32206
  });
32040
- const corepackJs = path60.join(dir, "node_modules", "corepack", "dist", "corepack.js");
32207
+ const corepackJs = path62.join(dir, "node_modules", "corepack", "dist", "corepack.js");
32041
32208
  const extra = config2.corepack && !exists(corepackJs) ? ["corepack"] : [];
32042
32209
  await installOnce(
32043
32210
  env,
@@ -32058,7 +32225,7 @@ var packageManagers = async (env, config2, version2) => {
32058
32225
  }
32059
32226
  try {
32060
32227
  await execAsync(
32061
- path60.join(dir, "node.exe"),
32228
+ path62.join(dir, "node.exe"),
32062
32229
  [corepackJs, "enable", "--install-directory", mkdirp(tool("bin")), "pnpm", "yarn"],
32063
32230
  { env: nodeEnv, stdio: "ignore" }
32064
32231
  );
@@ -32084,7 +32251,7 @@ async function setupPwsh(env, refresh = false) {
32084
32251
 
32085
32252
  // src/guest/toolchains/languages/python.ts
32086
32253
  import fs49 from "node:fs";
32087
- import path61 from "node:path";
32254
+ import path63 from "node:path";
32088
32255
  var installPython = async (pkg, spec) => {
32089
32256
  const version2 = await resolveCached(pkg + ":" + spec, async () => {
32090
32257
  const { versions } = await fetchJson(
@@ -32093,7 +32260,7 @@ var installPython = async (pkg, spec) => {
32093
32260
  return pickPackageVersion(versions, spec) ?? Promise.reject(new Error("No " + pkg + ' release matches "' + spec + '"'));
32094
32261
  });
32095
32262
  const dir = tool("python", pkg + "-" + version2);
32096
- const exe = path61.join(dir, "python.exe");
32263
+ const exe = path63.join(dir, "python.exe");
32097
32264
  if (!exists(exe)) {
32098
32265
  log("Downloading Python " + version2 + (pkg === "python2" ? " (Python 2, " : " (") + "~30 MB once) ...");
32099
32266
  await downloader.archive(
@@ -32102,32 +32269,32 @@ var installPython = async (pkg, spec) => {
32102
32269
  { locate: "python.exe", fileName: pkg + "." + version2 + ".zip" }
32103
32270
  );
32104
32271
  }
32105
- if (!exists(path61.join(dir, "Scripts", "pip.exe")) && !exists(path61.join(dir, "Scripts", "pip2.exe")))
32272
+ if (!exists(path63.join(dir, "Scripts", "pip.exe")) && !exists(path63.join(dir, "Scripts", "pip2.exe")))
32106
32273
  await execAsync(exe, ["-m", "ensurepip", "--default-pip"], { stdio: "ignore" });
32107
32274
  return dir;
32108
32275
  };
32109
- var shimDir = (dir) => duringSession() ? tool("shims", path61.basename(dir)) : tool("shims");
32276
+ var shimDir = (dir) => duringSession() ? tool("shims", path63.basename(dir)) : tool("shims");
32110
32277
  var shim = (folder, name, program, args = []) => {
32111
32278
  const fixed = [program, ...args];
32112
32279
  fs49.writeFileSync(
32113
- path61.join(mkdirp(folder), name + ".cmd"),
32280
+ path63.join(mkdirp(folder), name + ".cmd"),
32114
32281
  "@echo off\r\n" + fixed.map((a) => '"' + a + '"').join(" ") + " %*\r\n"
32115
32282
  );
32116
32283
  const sh = fixed.map((a) => "'" + a.replace(/\\/g, "/").replace(/'/g, "'\\''") + "'").join(" ");
32117
- fs49.writeFileSync(path61.join(folder, name), "#!/bin/sh\nexec " + sh + ' "$@"\n');
32284
+ fs49.writeFileSync(path63.join(folder, name), "#!/bin/sh\nexec " + sh + ' "$@"\n');
32118
32285
  };
32119
32286
  var shimPair = (folder, version2, dir) => {
32120
- const python = path61.join(dir, "python.exe");
32287
+ const python = path63.join(dir, "python.exe");
32121
32288
  shim(folder, "python" + version2, python);
32122
32289
  shim(folder, "pip" + version2, python, ["-m", "pip"]);
32123
32290
  };
32124
32291
  var pyLauncher = (folder, py3, py2) => {
32125
- const script = path61.join(mkdirp(folder), "py-launcher.py");
32292
+ const script = path63.join(mkdirp(folder), "py-launcher.py");
32126
32293
  fs49.writeFileSync(
32127
32294
  script,
32128
32295
  [
32129
32296
  "import subprocess, sys",
32130
- "PY3, PY2 = " + JSON.stringify(path61.join(py3, "python.exe")) + ", " + JSON.stringify(py2 ? path61.join(py2, "python.exe") : null),
32297
+ "PY3, PY2 = " + JSON.stringify(path63.join(py3, "python.exe")) + ", " + JSON.stringify(py2 ? path63.join(py2, "python.exe") : null),
32131
32298
  "args = sys.argv[1:]",
32132
32299
  "exe = PY3",
32133
32300
  "if args and args[0].startswith('-2'):",
@@ -32139,7 +32306,7 @@ var pyLauncher = (folder, py3, py2) => {
32139
32306
  ""
32140
32307
  ].join("\n")
32141
32308
  );
32142
- shim(folder, "py", path61.join(py3, "python.exe"), [script]);
32309
+ shim(folder, "py", path63.join(py3, "python.exe"), [script]);
32143
32310
  };
32144
32311
  async function setupPython(env, config2, versions) {
32145
32312
  if (dryRun) {
@@ -32149,10 +32316,10 @@ async function setupPython(env, config2, versions) {
32149
32316
  const py3 = await installPython("python", versions.python.spec);
32150
32317
  const shims = shimDir(py3);
32151
32318
  shimPair(shims, "3", py3);
32152
- env.prepend.push(py3, mkdirp(path61.join(py3, "Scripts")), shims);
32319
+ env.prepend.push(py3, mkdirp(path63.join(py3, "Scripts")), shims);
32153
32320
  env.vars.PYTHONIOENCODING = "utf-8";
32154
32321
  env.summary.push(
32155
- "python: " + path61.basename(py3).replace("python-", "") + " (from " + versions.python.source + "; py works too)"
32322
+ "python: " + path63.basename(py3).replace("python-", "") + " (from " + versions.python.source + "; py works too)"
32156
32323
  );
32157
32324
  if (!config2.python2) {
32158
32325
  pyLauncher(shims, py3, null);
@@ -32161,12 +32328,45 @@ async function setupPython(env, config2, versions) {
32161
32328
  const py2 = await installPython("python2", "2.7");
32162
32329
  shimPair(shims, "2", py2);
32163
32330
  pyLauncher(shims, py3, py2);
32164
- env.summary.push("python2: " + path61.basename(py2).replace("python2-", ""));
32331
+ env.summary.push("python2: " + path63.basename(py2).replace("python2-", ""));
32165
32332
  }
32166
32333
 
32167
32334
  // src/guest/toolchains/languages/php.ts
32335
+ import fs51 from "node:fs";
32336
+ import path65 from "node:path";
32337
+
32338
+ // src/guest/toolchains/native/vcruntime.ts
32168
32339
  import fs50 from "node:fs";
32169
- import path62 from "node:path";
32340
+ import path64 from "node:path";
32341
+ var VC_REDIST = "https://aka.ms/vs/17/release/vc_redist.x64.exe";
32342
+ var OK_EXIT_CODES2 = [0, 1638, 3010];
32343
+ async function setupVcRuntime(env, summary = true) {
32344
+ if (dryRun) {
32345
+ log("(dry run) would install the Visual C++ runtime");
32346
+ return false;
32347
+ }
32348
+ const system322 = path64.join(process.env.WINDIR ?? "C:\\Windows", "System32");
32349
+ const missing = !exists(path64.join(system322, "vcruntime140.dll")) || !exists(path64.join(system322, "msvcp140.dll"));
32350
+ if (missing) {
32351
+ const installer = tool("vcredist", "vc_redist.x64.exe");
32352
+ if (!exists(installer)) {
32353
+ log("Downloading the Visual C++ runtime (~25 MB once) ...");
32354
+ await downloadFile(VC_REDIST, installer);
32355
+ }
32356
+ if (!signedBy(installer, SIGNERS.microsoft)) {
32357
+ fs50.rmSync(installer, { force: true });
32358
+ throw new Error("vc_redist.x64.exe is not signed by Microsoft; deleted it (it is downloaded again next boot)");
32359
+ }
32360
+ log("Installing the Visual C++ runtime ...");
32361
+ const code = await spawnAsync(installer, ["/install", "/quiet", "/norestart"]);
32362
+ if (!OK_EXIT_CODES2.includes(code ?? -1) || !exists(path64.join(system322, "vcruntime140.dll")))
32363
+ throw new Error("the Visual C++ runtime installer failed (exit " + code + ")");
32364
+ }
32365
+ if (summary) env.summary.push("vc++ runtime: installed");
32366
+ return missing;
32367
+ }
32368
+
32369
+ // src/guest/toolchains/languages/php.ts
32170
32370
  var PHP_EXTENSIONS = [
32171
32371
  "curl",
32172
32372
  "fileinfo",
@@ -32197,16 +32397,16 @@ var phpBuild = async (spec) => {
32197
32397
  return { version: release.version, ...build.zip };
32198
32398
  };
32199
32399
  var writePhpIni = (home) => {
32200
- const ini = path62.join(home, "php.ini");
32201
- if (exists(ini) || !exists(path62.join(home, "php.ini-development"))) return;
32202
- let text = fs50.readFileSync(path62.join(home, "php.ini-development"), "utf8").replace(/^;\s*extension_dir\s*=\s*"ext"/m, 'extension_dir = "' + path62.join(home, "ext") + '"');
32203
- for (const ext of PHP_EXTENSIONS.filter((e) => exists(path62.join(home, "ext", "php_" + e + ".dll"))))
32400
+ const ini = path65.join(home, "php.ini");
32401
+ if (exists(ini) || !exists(path65.join(home, "php.ini-development"))) return;
32402
+ let text = fs51.readFileSync(path65.join(home, "php.ini-development"), "utf8").replace(/^;\s*extension_dir\s*=\s*"ext"/m, 'extension_dir = "' + path65.join(home, "ext") + '"');
32403
+ for (const ext of PHP_EXTENSIONS.filter((e) => exists(path65.join(home, "ext", "php_" + e + ".dll"))))
32204
32404
  text = text.replace(new RegExp("^;(extension=" + ext + ")\\s*$", "m"), "$1");
32205
- fs50.writeFileSync(ini + ".tmp", text);
32206
- fs50.renameSync(ini + ".tmp", ini);
32405
+ fs51.writeFileSync(ini + ".tmp", text);
32406
+ fs51.renameSync(ini + ".tmp", ini);
32207
32407
  };
32208
32408
  var shim2 = (env, name, command) => {
32209
- fs50.writeFileSync(path62.join(mkdirp(tool("shims")), name + ".cmd"), "@echo off\r\n" + command + " %*\r\n");
32409
+ fs51.writeFileSync(path65.join(mkdirp(tool("shims")), name + ".cmd"), "@echo off\r\n" + command + " %*\r\n");
32210
32410
  env.prepend.push(tool("shims"));
32211
32411
  };
32212
32412
  var setupComposer = async (env, php) => {
@@ -32218,7 +32418,7 @@ var setupComposer = async (env, php) => {
32218
32418
  }
32219
32419
  const composerHome = tool("composer-home");
32220
32420
  env.vars.COMPOSER_HOME = composerHome;
32221
- env.prepend.push(path62.join(composerHome, "vendor", "bin"));
32421
+ env.prepend.push(path65.join(composerHome, "vendor", "bin"));
32222
32422
  shim2(env, "composer", '"' + php + '" "' + phar + '"');
32223
32423
  env.summary.push(
32224
32424
  "composer: " + (/\d+\.\d+\.\d+/.exec(execOutput(php, [phar, "--version", "--no-ansi"]))?.[0] ?? "installed")
@@ -32233,7 +32433,7 @@ async function setupPhp(env, config2) {
32233
32433
  await setupVcRuntime(env, false);
32234
32434
  const version2 = await resolveCached("php:" + wantedSpec.spec, async () => (await phpBuild(wantedSpec.spec)).version);
32235
32435
  const home = tool("php", version2);
32236
- if (!exists(path62.join(home, "php.exe"))) {
32436
+ if (!exists(path65.join(home, "php.exe"))) {
32237
32437
  const build = await phpBuild(version2);
32238
32438
  log("Downloading PHP " + version2 + " (~30 MB once) ...");
32239
32439
  await downloader.archive("https://windows.php.net/downloads/releases/" + build.path, home, {
@@ -32245,11 +32445,11 @@ async function setupPhp(env, config2) {
32245
32445
  writePhpIni(home);
32246
32446
  env.prepend.push(home);
32247
32447
  env.summary.push("php: " + version2 + " (from " + wantedSpec.source + ")");
32248
- if (config2.composer) await setupComposer(env, path62.join(home, "php.exe"));
32448
+ if (config2.composer) await setupComposer(env, path65.join(home, "php.exe"));
32249
32449
  }
32250
32450
 
32251
32451
  // src/guest/toolchains/languages/ruby.ts
32252
- import path63 from "node:path";
32452
+ import path66 from "node:path";
32253
32453
  var RUBY_ASSET = /^rubyinstaller-(\d+\.\d+\.\d+)-(\d+)-x64\.7z$/;
32254
32454
  var buildNumber = (asset) => Number(RUBY_ASSET.exec(asset.name)?.[2] ?? 0);
32255
32455
  var rubyBuilds = async () => {
@@ -32277,7 +32477,7 @@ async function setupRuby(env, config2) {
32277
32477
  async () => pickPackageVersion([...(await rubyBuilds()).keys()], wantedSpec.spec) ?? Promise.reject(new Error('No RubyInstaller build matches "' + wantedSpec.spec + '"'))
32278
32478
  );
32279
32479
  const home = tool("ruby", version2);
32280
- if (!exists(path63.join(home, "bin", "ruby.exe"))) {
32480
+ if (!exists(path66.join(home, "bin", "ruby.exe"))) {
32281
32481
  const asset = (await rubyBuilds()).get(version2);
32282
32482
  if (!asset) throw new Error("RubyInstaller " + version2 + " is no longer published");
32283
32483
  log("Downloading Ruby " + version2 + " (~100 MB once) ...");
@@ -32290,11 +32490,11 @@ async function setupRuby(env, config2) {
32290
32490
  }
32291
32491
  const gems = tool("ruby-gems", version2.split(".").slice(0, 2).join("."));
32292
32492
  Object.assign(env.vars, { GEM_HOME: gems, BUNDLE_USER_HOME: tool("bundle-home") });
32293
- env.prepend.push(path63.join(home, "bin"), path63.join(gems, "bin"));
32493
+ env.prepend.push(path66.join(home, "bin"), path66.join(gems, "bin"));
32294
32494
  env.summary.push(
32295
- "ruby: " + versionOf(path63.join(home, "bin", "ruby.exe")) + " (from " + wantedSpec.source + "; gems with C extensions need MSYS2, not included)"
32495
+ "ruby: " + versionOf(path66.join(home, "bin", "ruby.exe")) + " (from " + wantedSpec.source + "; gems with C extensions need MSYS2, not included)"
32296
32496
  );
32297
- const gem = path63.join(home, "bin", "gem.cmd");
32497
+ const gem = path66.join(home, "bin", "gem.cmd");
32298
32498
  await installOnce(
32299
32499
  env,
32300
32500
  "gem@" + version2,
@@ -32306,9 +32506,9 @@ async function setupRuby(env, config2) {
32306
32506
  }
32307
32507
 
32308
32508
  // src/guest/toolchains/tools/vscode.ts
32309
- import fs51 from "node:fs";
32509
+ import fs52 from "node:fs";
32310
32510
  import os9 from "node:os";
32311
- import path64 from "node:path";
32511
+ import path67 from "node:path";
32312
32512
 
32313
32513
  // node_modules/jsonc-parser/lib/esm/impl/scanner.js
32314
32514
  var CharacterCodes;
@@ -32488,14 +32688,14 @@ var ParseErrorCode;
32488
32688
  var VERSION_MARKER = ".agent-sandbox-version";
32489
32689
  var desktopShortcut = (exe) => {
32490
32690
  if (!isWin) return;
32491
- const link = path64.join(os9.homedir(), "Desktop", "Visual Studio Code.lnk");
32691
+ const link = path67.join(os9.homedir(), "Desktop", "Visual Studio Code.lnk");
32492
32692
  runScriptWithJson("new-shortcuts.ps1", "ListFile", [
32493
32693
  { link, target: exe, arguments: '"' + (process.env.AGENT_WORKSPACE ?? "") + '"' }
32494
32694
  ]);
32495
32695
  };
32496
32696
  async function setupVscode(env, refresh) {
32497
32697
  const root = tool("vscode");
32498
- const exe = path64.join(root, "Code.exe");
32698
+ const exe = path67.join(root, "Code.exe");
32499
32699
  if (dryRun) {
32500
32700
  log("(dry run) would provision VS Code");
32501
32701
  return;
@@ -32505,11 +32705,11 @@ async function setupVscode(env, refresh) {
32505
32705
  "https://update.code.visualstudio.com/api/update/win32-" + (arch === "arm64" ? "arm64" : "x64") + "-archive/stable/latest"
32506
32706
  );
32507
32707
  log("Downloading VS Code " + release.productVersion + " (~150 MB once) ...");
32508
- const keep = path64.join(root, "data");
32708
+ const keep = path67.join(root, "data");
32509
32709
  const parked = root + "-data";
32510
32710
  if (exists(keep)) {
32511
- fs51.rmSync(parked, { recursive: true, force: true });
32512
- fs51.renameSync(keep, parked);
32711
+ fs52.rmSync(parked, { recursive: true, force: true });
32712
+ fs52.renameSync(keep, parked);
32513
32713
  }
32514
32714
  try {
32515
32715
  await downloader.archive(release.url, root, {
@@ -32517,29 +32717,29 @@ async function setupVscode(env, refresh) {
32517
32717
  locate: "Code.exe",
32518
32718
  fileName: "vscode.zip"
32519
32719
  });
32520
- fs51.writeFileSync(path64.join(root, VERSION_MARKER), release.productVersion);
32720
+ fs52.writeFileSync(path67.join(root, VERSION_MARKER), release.productVersion);
32521
32721
  } finally {
32522
32722
  if (exists(parked)) {
32523
32723
  mkdirp(root);
32524
- fs51.rmSync(keep, { recursive: true, force: true });
32525
- fs51.renameSync(parked, keep);
32724
+ fs52.rmSync(keep, { recursive: true, force: true });
32725
+ fs52.renameSync(parked, keep);
32526
32726
  }
32527
32727
  }
32528
32728
  }
32529
- mkdirp(path64.join(root, "data"));
32530
- env.prepend.push(path64.join(root, "bin"));
32729
+ mkdirp(path67.join(root, "data"));
32730
+ env.prepend.push(path67.join(root, "bin"));
32531
32731
  desktopShortcut(exe);
32532
- const version2 = exists(path64.join(root, VERSION_MARKER)) ? fs51.readFileSync(path64.join(root, VERSION_MARKER), "utf8").trim() : "installed";
32732
+ const version2 = exists(path67.join(root, VERSION_MARKER)) ? fs52.readFileSync(path67.join(root, VERSION_MARKER), "utf8").trim() : "installed";
32533
32733
  env.summary.push("vscode: " + version2 + " (portable; run code . or use the desktop shortcut)");
32534
32734
  }
32535
32735
 
32536
32736
  // src/guest/toolchains/steam/steam.ts
32537
- import fs55 from "node:fs";
32538
- import path69 from "node:path";
32737
+ import fs56 from "node:fs";
32738
+ import path72 from "node:path";
32539
32739
 
32540
32740
  // src/shared/accounts/kinds/steam.ts
32541
- import fs52 from "node:fs";
32542
- import path65 from "node:path";
32741
+ import fs53 from "node:fs";
32742
+ import path68 from "node:path";
32543
32743
 
32544
32744
  // src/shared/vdf.ts
32545
32745
  var DEFAULT_MAX_BYTES = 1024 * 1024;
@@ -32667,7 +32867,7 @@ var SENTRY = /^ssfn\d{1,40}$/;
32667
32867
  var STEAM_ACCOUNT = /^[A-Za-z0-9_]{1,64}$/;
32668
32868
  var STEAM_ACCOUNT_FILE = "sbx-account.txt";
32669
32869
  function steamConfigFile(steamcmdDir) {
32670
- return path65.join(steamcmdDir, "config", "config.vdf");
32870
+ return path68.join(steamcmdDir, "config", "config.vdf");
32671
32871
  }
32672
32872
  function steamKey(root) {
32673
32873
  return vdfObject(root, "InstallConfigStore", "Software", "Valve", "Steam");
@@ -32681,20 +32881,20 @@ function steamAccounts(configVdf) {
32681
32881
  return accounts ? Object.keys(accounts).filter((a) => STEAM_ACCOUNT.test(a)) : [];
32682
32882
  }
32683
32883
  function readSteamAccountFile(steamcmdDir) {
32684
- const bytes = readBoundedFile(path65.join(steamcmdDir, "config", STEAM_ACCOUNT_FILE), 256);
32884
+ const bytes = readBoundedFile(path68.join(steamcmdDir, "config", STEAM_ACCOUNT_FILE), 256);
32685
32885
  const name = bytes ? decodeText(bytes).text.trim() : "";
32686
32886
  return STEAM_ACCOUNT.test(name) ? name : null;
32687
32887
  }
32688
32888
  function readSentries(steamcmdDir) {
32689
32889
  let names;
32690
32890
  try {
32691
- names = fs52.readdirSync(steamcmdDir).slice(0, MAX_ENTRIES2).filter((n) => SENTRY.test(n));
32891
+ names = fs53.readdirSync(steamcmdDir).slice(0, MAX_ENTRIES2).filter((n) => SENTRY.test(n));
32692
32892
  } catch {
32693
32893
  return [];
32694
32894
  }
32695
32895
  const mtime = (name) => {
32696
32896
  try {
32697
- return fs52.lstatSync(path65.join(steamcmdDir, name)).mtimeMs;
32897
+ return fs53.lstatSync(path68.join(steamcmdDir, name)).mtimeMs;
32698
32898
  } catch {
32699
32899
  return 0;
32700
32900
  }
@@ -32702,7 +32902,7 @@ function readSentries(steamcmdDir) {
32702
32902
  const found = [];
32703
32903
  for (const name of names.sort((a, b) => mtime(b) - mtime(a))) {
32704
32904
  if (found.length >= MAX_SENTRIES) break;
32705
- const bytes = readBoundedFile(path65.join(steamcmdDir, name), MAX_SENTRY_BYTES);
32905
+ const bytes = readBoundedFile(path68.join(steamcmdDir, name), MAX_SENTRY_BYTES);
32706
32906
  if (bytes && bytes.length) found.push({ name, base64: bytes.toString("base64") });
32707
32907
  }
32708
32908
  return found.sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0);
@@ -32719,27 +32919,27 @@ function readSteamCmdLogin(steamcmdDir, account) {
32719
32919
  }
32720
32920
  function writeSteamCmdLogin(steamcmdDir, p) {
32721
32921
  const login = SteamPayloadSchema.parse(p);
32722
- const config2 = path65.dirname(steamConfigFile(steamcmdDir));
32723
- fs52.mkdirSync(config2, { recursive: true });
32724
- fs52.writeFileSync(steamConfigFile(steamcmdDir), login.configVdf, "utf8");
32725
- fs52.writeFileSync(path65.join(config2, STEAM_ACCOUNT_FILE), login.account, "utf8");
32726
- for (const s of login.sentries) fs52.writeFileSync(path65.join(steamcmdDir, s.name), Buffer.from(s.base64, "base64"));
32922
+ const config2 = path68.dirname(steamConfigFile(steamcmdDir));
32923
+ fs53.mkdirSync(config2, { recursive: true });
32924
+ fs53.writeFileSync(steamConfigFile(steamcmdDir), login.configVdf, "utf8");
32925
+ fs53.writeFileSync(path68.join(config2, STEAM_ACCOUNT_FILE), login.account, "utf8");
32926
+ for (const s of login.sentries) fs53.writeFileSync(path68.join(steamcmdDir, s.name), Buffer.from(s.base64, "base64"));
32727
32927
  }
32728
32928
 
32729
32929
  // src/guest/toolchains/steam/client.ts
32730
- import fs53 from "node:fs";
32731
- import path67 from "node:path";
32930
+ import fs54 from "node:fs";
32931
+ import path70 from "node:path";
32732
32932
 
32733
32933
  // src/guest/toolchains/steam/commands.ts
32734
- import path66 from "node:path";
32934
+ import path69 from "node:path";
32735
32935
  var STEAMCMD_DIR = "C:\\SteamCMD";
32736
32936
  var STEAMCMD_URL = "https://steamcdn-a.akamaihd.net/client/installer/steamcmd.zip";
32737
32937
  var STEAM_CLIENT_URL = "https://steamcdn-a.akamaihd.net/client/installer/SteamSetup.exe";
32738
32938
  function steamCmdStore(tools = toolsDir) {
32739
- return path66.join(tools, "steamcmd");
32939
+ return path69.join(tools, "steamcmd");
32740
32940
  }
32741
32941
  function steamClientDir(tools = toolsDir) {
32742
- return path66.join(tools, "steam");
32942
+ return path69.join(tools, "steam");
32743
32943
  }
32744
32944
  var MAX_SCRIPT_BYTES = 256 * 1024;
32745
32945
 
@@ -32748,35 +32948,35 @@ var GB2 = 1024 ** 3;
32748
32948
  var CLIENT_NEED_BYTES = 2 * GB2;
32749
32949
  var SETUP_TIMEOUT_MS = 10 * 60 * 1e3;
32750
32950
  function installedSteamClient() {
32751
- const exe = path67.join(steamClientDir(), "steam.exe");
32951
+ const exe = path70.join(steamClientDir(), "steam.exe");
32752
32952
  return exists(exe) && signedBy(exe, SIGNERS.valve) ? exe : null;
32753
32953
  }
32754
32954
  async function installSteamClient() {
32755
32955
  const dir = steamClientDir();
32756
- const exe = path67.join(dir, "steam.exe");
32956
+ const exe = path70.join(dir, "steam.exe");
32757
32957
  if (exists(exe)) {
32758
32958
  if (!signedBy(exe, SIGNERS.valve)) throw new Error("tools\\steam\\steam.exe is not signed by Valve");
32759
32959
  return exe;
32760
32960
  }
32761
- fs53.mkdirSync(toolsDir, { recursive: true });
32961
+ fs54.mkdirSync(toolsDir, { recursive: true });
32762
32962
  assertRoom(toolsDir, CLIENT_NEED_BYTES, "the Steam client", "Free room on the data disk.");
32763
32963
  const setup = await signedInstaller(
32764
32964
  STEAM_CLIENT_URL,
32765
- path67.join(tool("steam-setup"), "SteamSetup.exe"),
32965
+ path70.join(tool("steam-setup"), "SteamSetup.exe"),
32766
32966
  "the Steam client installer (~2 MB once)",
32767
32967
  SIGNERS.valve
32768
32968
  );
32769
32969
  const work = stagingFolder(dir);
32770
- fs53.mkdirSync(work, { recursive: true });
32970
+ fs54.mkdirSync(work, { recursive: true });
32771
32971
  try {
32772
32972
  log("Unpacking the Steam client into tools\\steam ...");
32773
32973
  const code = await spawnAsync(setup, ["/S", "/D=" + work], { timeout: SETUP_TIMEOUT_MS });
32774
- const unpacked = path67.join(work, "steam.exe");
32974
+ const unpacked = path70.join(work, "steam.exe");
32775
32975
  if (!exists(unpacked)) throw new Error("SteamSetup.exe did not unpack steam.exe (exit code " + code + ")");
32776
32976
  if (!signedBy(unpacked, SIGNERS.valve)) throw new Error("the unpacked steam.exe is not signed by Valve");
32777
32977
  moveIntoPlace(work, dir);
32778
32978
  } finally {
32779
- if (fs53.existsSync(work)) safeRemove(work, path67.dirname(work));
32979
+ if (fs54.existsSync(work)) safeRemove(work, path70.dirname(work));
32780
32980
  }
32781
32981
  return exe;
32782
32982
  }
@@ -32794,8 +32994,8 @@ async function ensureSteamClient(env) {
32794
32994
 
32795
32995
  // src/guest/toolchains/steam/steamcmd-install.ts
32796
32996
  import { spawn as spawn5 } from "node:child_process";
32797
- import fs54 from "node:fs";
32798
- import path68 from "node:path";
32997
+ import fs55 from "node:fs";
32998
+ import path71 from "node:path";
32799
32999
  var MB = 1024 ** 2;
32800
33000
  var STEAMCMD_NEED_BYTES = 600 * MB;
32801
33001
  var STEAMCMD_UPDATE_TIMEOUT_MS = 15 * 60 * 1e3;
@@ -32820,41 +33020,41 @@ function runWithTimeout(exe, args, cwd, timeoutMs) {
32820
33020
  });
32821
33021
  });
32822
33022
  }
32823
- var notSigned = (file3) => new Error(path68.basename(file3) + " is not signed by Valve: not running it (it is downloaded again next boot)");
33023
+ var notSigned = (file3) => new Error(path71.basename(file3) + " is not signed by Valve: not running it (it is downloaded again next boot)");
32824
33024
  async function fetchSteamCmd(store2, deps) {
32825
- fs54.mkdirSync(path68.dirname(store2), { recursive: true });
32826
- assertRoom(path68.dirname(store2), STEAMCMD_NEED_BYTES, "SteamCMD", "Free room on the data disk.", deps);
33025
+ fs55.mkdirSync(path71.dirname(store2), { recursive: true });
33026
+ assertRoom(path71.dirname(store2), STEAMCMD_NEED_BYTES, "SteamCMD", "Free room on the data disk.", deps);
32827
33027
  const work = stagingFolder(store2);
32828
- const unpacked = path68.join(work, "x");
33028
+ const unpacked = path71.join(work, "x");
32829
33029
  const extract = deps.extract ?? extractArchive;
32830
33030
  try {
32831
- fs54.mkdirSync(work, { recursive: true });
33031
+ fs55.mkdirSync(work, { recursive: true });
32832
33032
  const verify = async (part) => {
32833
33033
  await extract(part, unpacked);
32834
- const exe = path68.join(unpacked, "steamcmd.exe");
32835
- if (!fs54.existsSync(exe)) throw new Error("steamcmd.zip has no steamcmd.exe");
33034
+ const exe = path71.join(unpacked, "steamcmd.exe");
33035
+ if (!fs55.existsSync(exe)) throw new Error("steamcmd.zip has no steamcmd.exe");
32836
33036
  if (!deps.signed(exe)) throw notSigned(exe);
32837
33037
  };
32838
- const zip = path68.join(work, "steamcmd.zip");
33038
+ const zip = path71.join(work, "steamcmd.zip");
32839
33039
  if (deps.download) await deps.download(STEAMCMD_URL, zip, verify);
32840
33040
  else await downloader.file(STEAMCMD_URL, zip, { verify });
32841
33041
  moveIntoPlace(unpacked, store2);
32842
33042
  } finally {
32843
- if (fs54.existsSync(work)) safeRemove(work, path68.dirname(work));
33043
+ if (fs55.existsSync(work)) safeRemove(work, path71.dirname(work));
32844
33044
  }
32845
33045
  }
32846
33046
  async function copyBinaries(from, to) {
32847
- fs54.mkdirSync(to, { recursive: true });
32848
- for (const entry of fs54.readdirSync(from, { withFileTypes: true })) {
33047
+ fs55.mkdirSync(to, { recursive: true });
33048
+ for (const entry of fs55.readdirSync(from, { withFileTypes: true })) {
32849
33049
  if (isPrivate(entry.name) || entry.isSymbolicLink()) continue;
32850
33050
  if (!entry.isFile() && !entry.isDirectory()) continue;
32851
- await fs54.promises.cp(path68.join(from, entry.name), path68.join(to, entry.name), {
33051
+ await fs55.promises.cp(path71.join(from, entry.name), path71.join(to, entry.name), {
32852
33052
  recursive: true,
32853
33053
  force: true,
32854
33054
  verbatimSymlinks: true,
32855
33055
  filter: (source) => {
32856
33056
  try {
32857
- return !fs54.lstatSync(source).isSymbolicLink();
33057
+ return !fs55.lstatSync(source).isSymbolicLink();
32858
33058
  } catch {
32859
33059
  return false;
32860
33060
  }
@@ -32864,41 +33064,41 @@ async function copyBinaries(from, to) {
32864
33064
  }
32865
33065
  function snapshot(dir) {
32866
33066
  try {
32867
- return fs54.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && !isPrivate(e.name) && /\.(exe|dll)$/i.test(e.name)).map((e) => {
32868
- const s = fs54.statSync(path68.join(dir, e.name));
33067
+ return fs55.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && !isPrivate(e.name) && /\.(exe|dll)$/i.test(e.name)).map((e) => {
33068
+ const s = fs55.statSync(path71.join(dir, e.name));
32869
33069
  return e.name.toLowerCase() + ":" + s.size + ":" + Math.floor(s.mtimeMs / 1e3);
32870
33070
  }).sort().join("|");
32871
33071
  } catch {
32872
33072
  return "";
32873
33073
  }
32874
33074
  }
32875
- var bootstrapped = (dir) => BOOTSTRAPPED.some((f) => fs54.existsSync(path68.join(dir, f)));
33075
+ var bootstrapped = (dir) => BOOTSTRAPPED.some((f) => fs55.existsSync(path71.join(dir, f)));
32876
33076
  function scrubStore(store2) {
32877
33077
  let names = [];
32878
33078
  try {
32879
- names = fs54.readdirSync(store2);
33079
+ names = fs55.readdirSync(store2);
32880
33080
  } catch {
32881
33081
  return;
32882
33082
  }
32883
- for (const name of names.filter(isPrivate)) safeRemove(path68.join(store2, name), store2);
33083
+ for (const name of names.filter(isPrivate)) safeRemove(path71.join(store2, name), store2);
32884
33084
  }
32885
33085
  async function prepareSteamCmd(deps) {
32886
33086
  const store2 = deps.storeDir ?? steamCmdStore(deps.toolsDir);
32887
33087
  const work = deps.workDir ?? STEAMCMD_DIR;
32888
33088
  const log2 = deps.log ?? (() => void 0);
32889
- const exe = path68.join(work, "steamcmd.exe");
32890
- if (fs54.existsSync(exe) && bootstrapped(work)) {
33089
+ const exe = path71.join(work, "steamcmd.exe");
33090
+ if (fs55.existsSync(exe) && bootstrapped(work)) {
32891
33091
  if (!deps.signed(exe)) throw notSigned(exe);
32892
33092
  return exe;
32893
33093
  }
32894
- if (!fs54.existsSync(path68.join(store2, "steamcmd.exe"))) {
33094
+ if (!fs55.existsSync(path71.join(store2, "steamcmd.exe"))) {
32895
33095
  log2("Downloading SteamCMD (~3 MB once; it fetches ~300 MB on its first run) ...");
32896
33096
  await fetchSteamCmd(store2, deps);
32897
33097
  }
32898
33098
  scrubStore(store2);
32899
33099
  await copyBinaries(store2, work);
32900
33100
  if (!deps.signed(exe)) {
32901
- safeRemove(store2, path68.dirname(store2));
33101
+ safeRemove(store2, path71.dirname(store2));
32902
33102
  throw notSigned(exe);
32903
33103
  }
32904
33104
  const before = snapshot(work);
@@ -32919,7 +33119,7 @@ async function prepareSteamCmd(deps) {
32919
33119
  await copyBinaries(work, staging);
32920
33120
  moveIntoPlace(staging, store2);
32921
33121
  } finally {
32922
- if (fs54.existsSync(staging)) safeRemove(staging, path68.dirname(staging));
33122
+ if (fs55.existsSync(staging)) safeRemove(staging, path71.dirname(staging));
32923
33123
  }
32924
33124
  }
32925
33125
  return exe;
@@ -32938,10 +33138,10 @@ function signedInAs() {
32938
33138
  }
32939
33139
  function sdkFolder(env, setting) {
32940
33140
  if (!setting.trim()) return;
32941
- const dir = path69.resolve(projectWorkspace(), setting.trim());
33141
+ const dir = path72.resolve(projectWorkspace(), setting.trim());
32942
33142
  let ok = false;
32943
33143
  try {
32944
- ok = fs55.statSync(dir).isDirectory();
33144
+ ok = fs56.statSync(dir).isDirectory();
32945
33145
  } catch {
32946
33146
  }
32947
33147
  if (!ok) {
@@ -33019,9 +33219,9 @@ async function setupKotlin(env, _ctx) {
33019
33219
  }
33020
33220
 
33021
33221
  // src/guest/toolchains/native/rust-extras.ts
33022
- import fs56 from "node:fs";
33222
+ import fs57 from "node:fs";
33023
33223
  import os10 from "node:os";
33024
- import path70 from "node:path";
33224
+ import path73 from "node:path";
33025
33225
 
33026
33226
  // src/shared/memory/policy.ts
33027
33227
  var DIAL_STEPS = {
@@ -33339,40 +33539,40 @@ function targetSummary(rust) {
33339
33539
  }
33340
33540
  var cargoTarget = (targetDir) => {
33341
33541
  if (targetDir === "shared" || targetDir === "separate") return null;
33342
- if (targetDir === "local") return path70.join(localDir, "cargo-target");
33542
+ if (targetDir === "local") return path73.join(localDir, "cargo-target");
33343
33543
  return targetDir;
33344
33544
  };
33345
33545
  function cargoShim(env, rust) {
33346
- const real = path70.join(tool("rust", "cargo", "bin"), "cargo.exe");
33546
+ const real = path73.join(tool("rust", "cargo", "bin"), "cargo.exe");
33347
33547
  if (rust.targetDir !== "separate" || !exists(real)) return;
33348
33548
  const dir = mkdirp(tool("shims", "cargo"));
33349
- fs56.copyFileSync(ensureCompiled("cargoshim"), path70.join(dir, "cargo.exe"));
33549
+ fs57.copyFileSync(ensureCompiled("cargoshim"), path73.join(dir, "cargo.exe"));
33350
33550
  env.prepend.unshift(dir);
33351
33551
  env.vars.AGENT_REAL_CARGO = real;
33352
33552
  }
33353
33553
  function linkGate(env, rust, host) {
33354
33554
  const gcc = tool("mingw", "mingw64", "bin", "gcc.exe");
33355
33555
  if (!host.endsWith("-pc-windows-gnu") || !exists(gcc)) return;
33356
- const gate = path70.join(mkdirp(tool("shims")), "linkgate.exe");
33357
- fs56.copyFileSync(ensureCompiled("linkgate"), gate);
33556
+ const gate = path73.join(mkdirp(tool("shims")), "linkgate.exe");
33557
+ fs57.copyFileSync(ensureCompiled("linkgate"), gate);
33358
33558
  const slots = rust.linkSlots === "auto" ? linkerSlots(os10.totalmem() / 1024 ** 2, os10.cpus().length) : rust.linkSlots;
33359
33559
  env.vars.AGENT_LINK_SLOTS = String(slots);
33360
33560
  env.vars.AGENT_REAL_LINKER = gcc;
33361
33561
  env.vars.CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER = gate;
33362
33562
  const rustEnv = { ...process.env, RUSTUP_HOME: tool("rust", "rustup"), CARGO_HOME: tool("rust", "cargo") };
33363
33563
  const sysroot = rust.linker === "lld" ? execOutput(tool("rust", "cargo", "bin", "rustc.exe"), ["--print", "sysroot"], { env: rustEnv }) : "";
33364
- const lld = sysroot ? path70.join(sysroot, "lib", "rustlib", host, "bin", "gcc-ld") : "";
33365
- if (lld && exists(path70.join(lld, "ld.lld.exe"))) env.vars.AGENT_LLD_DIR = lld;
33564
+ const lld = sysroot ? path73.join(sysroot, "lib", "rustlib", host, "bin", "gcc-ld") : "";
33565
+ if (lld && exists(path73.join(lld, "ld.lld.exe"))) env.vars.AGENT_LLD_DIR = lld;
33366
33566
  env.summary.push(
33367
33567
  "rust linking: " + (env.vars.AGENT_LLD_DIR ? "lld" : "GNU ld") + ", at most " + env.vars.AGENT_LINK_SLOTS + " at once"
33368
33568
  );
33369
33569
  }
33370
33570
  function cargoDefaults(host) {
33371
33571
  const file3 = tool("rust", "cargo", "config.toml");
33372
- if (exists(file3) || !exists(path70.dirname(file3))) return;
33572
+ if (exists(file3) || !exists(path73.dirname(file3))) return;
33373
33573
  const jobs = cargoJobs(os10.cpus().length, os10.totalmem() / 1024 ** 3, 1);
33374
33574
  const gnu = host.endsWith("-gnu");
33375
- fs56.writeFileSync(
33575
+ fs57.writeFileSync(
33376
33576
  file3,
33377
33577
  [
33378
33578
  "# Written by windows-development-sandbox once; edit freely, it is never overwritten.",
@@ -33387,7 +33587,7 @@ function rustCaches(rust) {
33387
33587
  const target = cargoTarget(rust.targetDir);
33388
33588
  return {
33389
33589
  ...target ? { CARGO_TARGET_DIR: target } : {},
33390
- ...process.env.SCCACHE_DIR ? {} : { SCCACHE_DIR: path70.join(dataDir, "cache", "sccache") }
33590
+ ...process.env.SCCACHE_DIR ? {} : { SCCACHE_DIR: path73.join(dataDir, "cache", "sccache") }
33391
33591
  };
33392
33592
  }
33393
33593
  function rustHost(config2) {
@@ -33417,6 +33617,7 @@ function plan(config2, versions, o) {
33417
33617
  const unreal = wanted(config2.unreal.enabled, "unreal");
33418
33618
  const android = wanted(config2.android.enabled, "android");
33419
33619
  const vs = visualStudioWanted(config2, (setting, name) => wanted(setting, name));
33620
+ const autosdk = unrealUsesAutosdk(config2, (setting, name) => wanted(setting, name));
33420
33621
  const ctx = {
33421
33622
  refresh: o.refresh,
33422
33623
  pcInstalls: o.pcInstalls ?? { items: [] },
@@ -33452,13 +33653,17 @@ function plan(config2, versions, o) {
33452
33653
  name: "Unreal",
33453
33654
  enabled: unreal,
33454
33655
  shared: true,
33455
- after: ["Visual Studio"],
33656
+ after: ["Visual Studio", "MSVC"],
33456
33657
  install: (env) => setupUnreal(env, config2.unreal, ctx)
33457
33658
  },
33458
33659
  {
33459
33660
  name: "MSVC",
33460
- enabled: wanted(config2.msvc.enabled, "msvc") && vs === null,
33461
- install: (env) => setupMsvc(env, config2.msvc)
33661
+ enabled: (wanted(config2.msvc.enabled, "msvc") || autosdk && config2.msvc.enabled !== false) && vs === null,
33662
+ // The same Visual Studio licence terms, which Unreal's acceptLicense already names.
33663
+ install: (env) => setupMsvc(
33664
+ env,
33665
+ autosdk ? { ...config2.msvc, acceptLicense: config2.msvc.acceptLicense || config2.unreal.acceptLicense } : config2.msvc
33666
+ )
33462
33667
  },
33463
33668
  // Rust links with MSVC (msvc host) or MinGW's gcc (GNU host): whichever it uses goes first.
33464
33669
  {
@@ -33771,21 +33976,21 @@ function cmdSet(env, names) {
33771
33976
  return names.filter((n) => env[n] !== void 0 && !/[\r\n]/.test(String(env[n]))).map((n) => '@set "' + n + "=" + String(env[n]).replace(/%/g, "%%") + '"');
33772
33977
  }
33773
33978
  function writeShell(spec, env, names) {
33774
- const dir = mkdirp(path71.join(localDir, "projects", spec.name));
33775
- fs57.writeFileSync(path71.join(dir, "env.cmd"), [...cmdSet(env, [...names, "PATH"]), ""].join("\r\n"));
33776
- fs57.writeFileSync(
33777
- path71.join(dir, "shell.cmd"),
33778
- ['@call "' + path71.join(dir, "env.cmd") + '"', '@cd /d "' + spec.workspace + '"', "@title " + spec.name, ""].join(
33979
+ const dir = mkdirp(path74.join(localDir, "projects", spec.name));
33980
+ fs58.writeFileSync(path74.join(dir, "env.cmd"), [...cmdSet(env, [...names, "PATH"]), ""].join("\r\n"));
33981
+ fs58.writeFileSync(
33982
+ path74.join(dir, "shell.cmd"),
33983
+ ['@call "' + path74.join(dir, "env.cmd") + '"', '@cd /d "' + spec.workspace + '"', "@title " + spec.name, ""].join(
33779
33984
  "\r\n"
33780
33985
  )
33781
33986
  );
33782
- const bin = mkdirp(path71.join(localDir, "bin"));
33783
- fs57.writeFileSync(
33784
- path71.join(bin, "sbx-shell.cmd"),
33987
+ const bin = mkdirp(path74.join(localDir, "bin"));
33988
+ fs58.writeFileSync(
33989
+ path74.join(bin, "sbx-shell.cmd"),
33785
33990
  [
33786
- '@if "%~1"=="" (echo Usage: sbx-shell ^<project^> ^(a terminal in that project with its tools^) & dir /b "' + path71.join(localDir, "projects") + '" & exit /b 2)',
33787
- '@if not exist "' + path71.join(localDir, "projects") + '\\%~1\\shell.cmd" (echo No project %~1 in this sandbox. & exit /b 2)',
33788
- '@cmd /k ""' + path71.join(localDir, "projects") + '\\%~1\\shell.cmd""',
33991
+ '@if "%~1"=="" (echo Usage: sbx-shell ^<project^> ^(a terminal in that project with its tools^) & dir /b "' + path74.join(localDir, "projects") + '" & exit /b 2)',
33992
+ '@if not exist "' + path74.join(localDir, "projects") + '\\%~1\\shell.cmd" (echo No project %~1 in this sandbox. & exit /b 2)',
33993
+ '@cmd /k ""' + path74.join(localDir, "projects") + '\\%~1\\shell.cmd""',
33789
33994
  ""
33790
33995
  ].join("\r\n")
33791
33996
  );
@@ -33838,10 +34043,10 @@ async function setUp(spec, say) {
33838
34043
  }
33839
34044
  )
33840
34045
  );
33841
- tools.prepend.push(path71.join(localDir, "bin"));
34046
+ tools.prepend.push(path74.join(localDir, "bin"));
33842
34047
  const env = agentEnv(tools, { workspace: spec.workspace, project: spec.name, base });
33843
- const specFile = path71.join(mkdirp(path71.join(localDir, "projects", spec.name)), "project.json");
33844
- fs57.writeFileSync(specFile, JSON.stringify(spec));
34048
+ const specFile = path74.join(mkdirp(path74.join(localDir, "projects", spec.name)), "project.json");
34049
+ fs58.writeFileSync(specFile, JSON.stringify(spec));
33845
34050
  env.AGENT_PROJECT_FILE = specFile;
33846
34051
  addMachineEnvironment(tools.vars, [...tools.prepend, ...tools.append], true);
33847
34052
  try {
@@ -33958,8 +34163,8 @@ function execCommand(req) {
33958
34163
  }
33959
34164
 
33960
34165
  // src/guest/daemon/sessions.ts
33961
- import fs64 from "node:fs";
33962
- import path81 from "node:path";
34166
+ import fs65 from "node:fs";
34167
+ import path84 from "node:path";
33963
34168
  import crypto5 from "node:crypto";
33964
34169
  import os15 from "node:os";
33965
34170
  import { spawn as spawn9 } from "node:child_process";
@@ -34040,7 +34245,7 @@ async function sendControl(endpoint, type) {
34040
34245
  var MAX_CLIPBOARD_STRING = 1024 * 1024;
34041
34246
 
34042
34247
  // src/guest/sessions/cmdline.ts
34043
- import path72 from "node:path";
34248
+ import path75 from "node:path";
34044
34249
  var quoted = (arg) => '"' + arg.replace(/(\\*)"/g, '$1$1\\"').replace(/(\\+)$/, "$1$1") + '"';
34045
34250
  function quoteArg(arg) {
34046
34251
  return arg !== "" && !/[\s"]/.test(arg) ? arg : quoted(arg);
@@ -34054,7 +34259,7 @@ function cmdArgs(args) {
34054
34259
  }).join("");
34055
34260
  }
34056
34261
  function commandLine(file3, args) {
34057
- return path72.win32.basename(file3).toLowerCase() === "cmd.exe" ? [quoteArg(file3), cmdArgs(args)].filter(Boolean).join(" ") : [file3, ...args].map(quoteArg).join(" ");
34262
+ return path75.win32.basename(file3).toLowerCase() === "cmd.exe" ? [quoteArg(file3), cmdArgs(args)].filter(Boolean).join(" ") : [file3, ...args].map(quoteArg).join(" ");
34058
34263
  }
34059
34264
  function shellLaunch(asked, paths) {
34060
34265
  if (asked === "cmd") return { name: "cmd", file: paths.cmd, args: [] };
@@ -34068,8 +34273,8 @@ function shellLaunch(asked, paths) {
34068
34273
  }
34069
34274
 
34070
34275
  // src/guest/sessions/pty-host.ts
34071
- import fs58 from "node:fs";
34072
- import path73 from "node:path";
34276
+ import fs59 from "node:fs";
34277
+ import path76 from "node:path";
34073
34278
  import { execFile, spawn as spawn7 } from "node:child_process";
34074
34279
  function ensurePtyHost() {
34075
34280
  return ensureCompiled("ptyhost");
@@ -34088,21 +34293,21 @@ async function waitForPtyHost(child, port, timeoutMs) {
34088
34293
  throw new Error("the session host did not start listening on port " + port);
34089
34294
  }
34090
34295
  function ptyHostLog(id) {
34091
- return path73.join(logsDir, "ptyhost-" + id + ".log");
34296
+ return path76.join(logsDir, "ptyhost-" + id + ".log");
34092
34297
  }
34093
34298
  function ptyHostLogTail(id, lines = 12) {
34094
34299
  try {
34095
- return fs58.readFileSync(ptyHostLog(id), "utf8").trim().split(/\r?\n/).slice(-lines).join("\n");
34300
+ return fs59.readFileSync(ptyHostLog(id), "utf8").trim().split(/\r?\n/).slice(-lines).join("\n");
34096
34301
  } catch {
34097
34302
  return "";
34098
34303
  }
34099
34304
  }
34100
34305
  var conptyDll = () => {
34101
- const dll = path73.join(toolsDir, "conpty", "conpty.dll");
34102
- return session.provisioning.conpty?.enabled !== false && fs58.existsSync(dll) && fs58.existsSync(path73.join(toolsDir, "conpty", "OpenConsole.exe")) ? dll : null;
34306
+ const dll = path76.join(toolsDir, "conpty", "conpty.dll");
34307
+ return session.provisioning.conpty?.enabled !== false && fs59.existsSync(dll) && fs59.existsSync(path76.join(toolsDir, "conpty", "OpenConsole.exe")) ? dll : null;
34103
34308
  };
34104
34309
  function startPtyHost(o) {
34105
- fs58.mkdirSync(run.treesDir, { recursive: true });
34310
+ fs59.mkdirSync(run.treesDir, { recursive: true });
34106
34311
  const env = {
34107
34312
  ...o.env,
34108
34313
  PTYHOST_BIND: o.remote ? "any" : "loopback",
@@ -34120,13 +34325,13 @@ function startPtyHost(o) {
34120
34325
  var END_TREE_MS = 3e4;
34121
34326
  function endLeftoverTree(id, exe = ensurePtyHost()) {
34122
34327
  const file3 = run.treeFile(id);
34123
- if (!fs58.existsSync(file3)) return Promise.resolve(null);
34328
+ if (!fs59.existsSync(file3)) return Promise.resolve(null);
34124
34329
  return new Promise((resolve2) => {
34125
34330
  execFile(exe, ["--end-tree", file3], { timeout: END_TREE_MS, windowsHide: true }, (error62, stdout) => {
34126
34331
  const code = error62 ? typeof error62.code === "number" ? error62.code : -1 : 0;
34127
34332
  if (code !== 3)
34128
34333
  try {
34129
- fs58.rmSync(file3, { force: true });
34334
+ fs59.rmSync(file3, { force: true });
34130
34335
  } catch {
34131
34336
  }
34132
34337
  resolve2(code === 0 ? stdout.trim().slice(0, 200) : code === 3 ? null : "could not end them (code " + code + ")");
@@ -34135,15 +34340,15 @@ function endLeftoverTree(id, exe = ensurePtyHost()) {
34135
34340
  }
34136
34341
  function recordedTrees() {
34137
34342
  try {
34138
- return fs58.readdirSync(run.treesDir).filter((n) => /^[A-Za-z0-9_-]{1,64}\.json$/.test(n)).map((n) => n.slice(0, -".json".length));
34343
+ return fs59.readdirSync(run.treesDir).filter((n) => /^[A-Za-z0-9_-]{1,64}\.json$/.test(n)).map((n) => n.slice(0, -".json".length));
34139
34344
  } catch {
34140
34345
  return [];
34141
34346
  }
34142
34347
  }
34143
34348
 
34144
34349
  // src/guest/agents/agent-installer.ts
34145
- import fs59 from "node:fs";
34146
- import path74 from "node:path";
34350
+ import fs60 from "node:fs";
34351
+ import path77 from "node:path";
34147
34352
 
34148
34353
  // src/guest/agents/profile-links.ts
34149
34354
  var profileRoot = () => process.env.USERPROFILE ?? "";
@@ -34169,7 +34374,7 @@ var agentPaths2 = (name, harness) => agentPaths(toolsDir, name, harness);
34169
34374
  async function installViaNpm(name, harness, dir, env) {
34170
34375
  if (!harness.npmPackage)
34171
34376
  throw new Error("No npmPackage configured for " + name + " and no host executable was available.");
34172
- const npmCli = path74.join(path74.dirname(process.execPath), "node_modules", "npm", "bin", "npm-cli.js");
34377
+ const npmCli = path77.join(path77.dirname(process.execPath), "node_modules", "npm", "bin", "npm-cli.js");
34173
34378
  const args = [npmCli, "install", "--global", "--prefix", dir, harness.npmPackage, "--no-fund", "--no-audit"];
34174
34379
  log("Installing " + harness.npmPackage + " (this can take a minute)...");
34175
34380
  if (dryRun) {
@@ -34180,7 +34385,7 @@ async function installViaNpm(name, harness, dir, env) {
34180
34385
  await execAsync(process.execPath, args, { env });
34181
34386
  }
34182
34387
  async function installViaUv(name, harness, dir, env) {
34183
- const uv = path74.join(toolsDir, "uv", "uv.exe");
34388
+ const uv = path77.join(toolsDir, "uv", "uv.exe");
34184
34389
  log("Installing " + harness.uvPackage + " with uv (this can take a minute)...");
34185
34390
  if (dryRun) {
34186
34391
  log("(dry run) uv tool install " + harness.uvPackage);
@@ -34195,8 +34400,8 @@ async function installViaUv(name, harness, dir, env) {
34195
34400
  });
34196
34401
  }
34197
34402
  function putOnPath(dir, env) {
34198
- const parts2 = (env.PATH ?? "").split(path74.delimiter);
34199
- if (!parts2.some((p) => p.toLowerCase() === dir.toLowerCase())) env.PATH = [...parts2, dir].join(path74.delimiter);
34403
+ const parts2 = (env.PATH ?? "").split(path77.delimiter);
34404
+ if (!parts2.some((p) => p.toLowerCase() === dir.toLowerCase())) env.PATH = [...parts2, dir].join(path77.delimiter);
34200
34405
  addMachineEnvironment({}, [dir], true);
34201
34406
  }
34202
34407
  var AgentInstaller = class {
@@ -34237,9 +34442,9 @@ var AgentInstaller = class {
34237
34442
  }
34238
34443
  mkdirp(p.dir);
34239
34444
  if (this.sourceOf(name, harness) === "host") {
34240
- const source = path74.join(hostToolsDir, "agents", name, harness.hostExecutable);
34445
+ const source = path77.join(hostToolsDir, "agents", name, harness.hostExecutable);
34241
34446
  if (exists(source) && p.exe) {
34242
- fs59.copyFileSync(source, p.exe);
34447
+ fs60.copyFileSync(source, p.exe);
34243
34448
  log("Copied " + name + " from this PC: " + source);
34244
34449
  return;
34245
34450
  }
@@ -34260,22 +34465,22 @@ function guestAddresses() {
34260
34465
  }
34261
34466
 
34262
34467
  // src/guest/sessions/conversation.ts
34263
- import fs60 from "node:fs";
34264
- import path75 from "node:path";
34468
+ import fs61 from "node:fs";
34469
+ import path78 from "node:path";
34265
34470
  var MAX_FILES = 2e3;
34266
34471
  function conversationFiles(claudeDir2, cwd) {
34267
34472
  const names = /* @__PURE__ */ new Set([projectFolderName(cwd), projectFolderName(sandboxFolder(cwd))]);
34268
34473
  return [...names].flatMap((name) => {
34269
- const dir = path75.join(claudeDir2, "projects", name);
34474
+ const dir = path78.join(claudeDir2, "projects", name);
34270
34475
  let entries2;
34271
34476
  try {
34272
- entries2 = fs60.readdirSync(dir);
34477
+ entries2 = fs61.readdirSync(dir);
34273
34478
  } catch {
34274
34479
  return [];
34275
34480
  }
34276
34481
  return entries2.filter((e) => e.endsWith(".jsonl") && isConversationId(e.slice(0, -".jsonl".length))).slice(0, MAX_FILES).flatMap((e) => {
34277
34482
  try {
34278
- return [{ id: e.slice(0, -".jsonl".length), createdMs: fs60.statSync(path75.join(dir, e)).birthtimeMs }];
34483
+ return [{ id: e.slice(0, -".jsonl".length), createdMs: fs61.statSync(path78.join(dir, e)).birthtimeMs }];
34279
34484
  } catch {
34280
34485
  return [];
34281
34486
  }
@@ -34290,8 +34495,8 @@ function findConversation(claudeDir2, cwd, sessionStartMs, claimed) {
34290
34495
  import { spawnSync as spawnSync6 } from "node:child_process";
34291
34496
 
34292
34497
  // src/guest/accounts/watch.ts
34293
- import fs62 from "node:fs";
34294
- import path79 from "node:path";
34498
+ import fs63 from "node:fs";
34499
+ import path82 from "node:path";
34295
34500
 
34296
34501
  // src/shared/accounts/fingerprint.ts
34297
34502
  import crypto4 from "node:crypto";
@@ -34306,12 +34511,12 @@ function fingerprint2(payload) {
34306
34511
  }
34307
34512
 
34308
34513
  // src/guest/accounts/adapter.ts
34309
- import path76 from "node:path";
34514
+ import path79 from "node:path";
34310
34515
  function localAppData() {
34311
34516
  return process.env.LOCALAPPDATA ?? "C:\\Users\\WDAGUtilityAccount\\AppData\\Local";
34312
34517
  }
34313
34518
  function accountsRoot() {
34314
- return path76.join(localAppData(), "AgentSandbox", "accounts");
34519
+ return path79.join(localAppData(), "AgentSandbox", "accounts");
34315
34520
  }
34316
34521
  function notAvailableYet2(kind) {
34317
34522
  return { summary: kind + ": using a saved sign-in is not available yet (it is not used)" };
@@ -34334,8 +34539,8 @@ var cfxAdapter = {
34334
34539
  };
34335
34540
 
34336
34541
  // src/guest/accounts/kinds/epic.ts
34337
- import fs61 from "node:fs";
34338
- import path77 from "node:path";
34542
+ import fs62 from "node:fs";
34543
+ import path80 from "node:path";
34339
34544
 
34340
34545
  // src/shared/accounts/kinds/epic.ts
34341
34546
  var MAX_EPIC_INI_BYTES = 1024 * 1024;
@@ -34388,8 +34593,8 @@ var epicAdapter = {
34388
34593
  const file3 = settingsFile();
34389
34594
  const bytes = readBoundedFile(file3, MAX_EPIC_INI_BYTES);
34390
34595
  const read = bytes ? decodeText(bytes) : { text: "", encoding: "utf8" };
34391
- fs61.mkdirSync(path77.dirname(file3), { recursive: true });
34392
- fs61.writeFileSync(file3, encodeText(withEpicLogin(read.text, p), read.encoding));
34596
+ fs62.mkdirSync(path80.dirname(file3), { recursive: true });
34597
+ fs62.writeFileSync(file3, encodeText(withEpicLogin(read.text, p), read.encoding));
34393
34598
  return { summary: "Epic Games Launcher: signed in with your saved sign-in" };
34394
34599
  },
34395
34600
  current() {
@@ -34456,13 +34661,13 @@ var ADAPTERS = {
34456
34661
  };
34457
34662
 
34458
34663
  // src/guest/accounts/apply.ts
34459
- import path78 from "node:path";
34664
+ import path81 from "node:path";
34460
34665
  var DeliveredSchema = external_exports.object({
34461
34666
  fingerprints: external_exports.partialRecord(external_exports.enum(SERVICE_KINDS), external_exports.string().max(128)),
34462
34667
  leased: external_exports.array(external_exports.enum(SERVICE_KINDS))
34463
34668
  });
34464
34669
  function deliveredFile(root = accountsRoot()) {
34465
- return path78.join(root, "delivered.json");
34670
+ return path81.join(root, "delivered.json");
34466
34671
  }
34467
34672
  function readDelivered(root = accountsRoot()) {
34468
34673
  return readValid(DeliveredSchema, deliveredFile(root)) ?? { fingerprints: {}, leased: [] };
@@ -34502,8 +34707,8 @@ var AccountWatch = class {
34502
34707
  if (!now2) return false;
34503
34708
  const print = fingerprint2(now2);
34504
34709
  if (print === this.last.get(kind)) return false;
34505
- const file3 = path79.join(this.o.dataDir, ...HANDOFF_PARTS, kind + ".json");
34506
- fs62.mkdirSync(path79.dirname(file3), { recursive: true });
34710
+ const file3 = path82.join(this.o.dataDir, ...HANDOFF_PARTS, kind + ".json");
34711
+ fs63.mkdirSync(path82.dirname(file3), { recursive: true });
34507
34712
  writeJsonAtomic(file3, { kind, launchId: this.o.launchId, payload: now2 });
34508
34713
  this.last.set(kind, print);
34509
34714
  return true;
@@ -34673,9 +34878,9 @@ var GovernorCore = class {
34673
34878
  };
34674
34879
 
34675
34880
  // src/guest/governor/governor.ts
34676
- import fs63 from "node:fs";
34881
+ import fs64 from "node:fs";
34677
34882
  import os13 from "node:os";
34678
- import path80 from "node:path";
34883
+ import path83 from "node:path";
34679
34884
  import { spawn as spawn8 } from "node:child_process";
34680
34885
  import { createInterface } from "node:readline";
34681
34886
  var SampleSchema = external_exports.object({
@@ -34748,12 +34953,12 @@ var MemGovProcess = class {
34748
34953
  };
34749
34954
  function appendToMemoryLog(line) {
34750
34955
  try {
34751
- const logs = path80.join(dataDir, "logs");
34752
- const newest = fs63.readdirSync(logs).filter((f) => /^memory-\d{8}-\d{6}\.log$/.test(f)).sort().pop();
34956
+ const logs = path83.join(dataDir, "logs");
34957
+ const newest = fs64.readdirSync(logs).filter((f) => /^memory-\d{8}-\d{6}\.log$/.test(f)).sort().pop();
34753
34958
  if (!newest) return;
34754
34959
  const t = /* @__PURE__ */ new Date();
34755
34960
  const stamp = [t.getHours(), t.getMinutes(), t.getSeconds()].map((n) => String(n).padStart(2, "0")).join(":");
34756
- fs63.appendFileSync(path80.join(logs, newest), stamp + " | " + line + "\r\n");
34961
+ fs64.appendFileSync(path83.join(logs, newest), stamp + " | " + line + "\r\n");
34757
34962
  } catch {
34758
34963
  }
34759
34964
  }
@@ -34870,8 +35075,8 @@ var IdleShutdown = class {
34870
35075
  var CLOSE_WAIT_MS = 8e3;
34871
35076
  var ROOTS_KEPT_MS = 10 * 60 * 1e3;
34872
35077
  function terminalTab(id, title, cwd) {
34873
- const view = [process.execPath, path81.join(path81.dirname(process.argv[1]), "view.js"), id];
34874
- const wt = path81.join(toolsDir, "terminal", "wt.exe");
35078
+ const view = [process.execPath, path84.join(path84.dirname(process.argv[1]), "view.js"), id];
35079
+ const wt = path84.join(toolsDir, "terminal", "wt.exe");
34875
35080
  if (exists(wt))
34876
35081
  spawn9(wt, ["-w", "0", "nt", "--title", title, "-d", cwd, ...view], { detached: true, stdio: "ignore" }).unref();
34877
35082
  else spawn9(SYSTEM.cmd(), ["/d", "/c", "start", title, ...view], { detached: true, stdio: "ignore", cwd }).unref();
@@ -34918,7 +35123,7 @@ var agentProgram = async (req, env, say) => {
34918
35123
  say("Preparing " + req.harness);
34919
35124
  await agents.provision(req.harness, harness, env, false);
34920
35125
  const launch = agents.resolveLaunch(req.harness, harness);
34921
- const base = [...launch.args, ...harness.arguments];
35126
+ const base = [...launch.args, ...agentArguments(req.harness, harness, session.codex)];
34922
35127
  return {
34923
35128
  command: commandLine(launch.file, [...base, ...req.args]),
34924
35129
  restartCommand: commandLine(launch.file, [...base, ...harness.resumeArguments ?? []]),
@@ -34927,10 +35132,10 @@ var agentProgram = async (req, env, say) => {
34927
35132
  };
34928
35133
  function shellPaths() {
34929
35134
  const candidates = [
34930
- path81.join(pwshDir(), "pwsh.exe"),
34931
- path81.join(process.env.ProgramFiles ?? "C:\\Program Files", "PowerShell", "7", "pwsh.exe")
35135
+ path84.join(pwshDir(), "pwsh.exe"),
35136
+ path84.join(process.env.ProgramFiles ?? "C:\\Program Files", "PowerShell", "7", "pwsh.exe")
34932
35137
  ];
34933
- return { pwsh: candidates.find((f) => fs64.existsSync(f)) ?? null, powershell: SYSTEM.powershell(), cmd: SYSTEM.cmd() };
35138
+ return { pwsh: candidates.find((f) => fs65.existsSync(f)) ?? null, powershell: SYSTEM.powershell(), cmd: SYSTEM.cmd() };
34934
35139
  }
34935
35140
  var shellProgram = (shell) => {
34936
35141
  const line = commandLine(shell.file, shell.args);
@@ -34964,7 +35169,7 @@ var launchPtyHost = async (req, program, remote, env, sessions2, onSpawn) => {
34964
35169
  } catch (e) {
34965
35170
  const tail = ptyHostLogTail(req.id);
34966
35171
  throw new Error(
34967
- errMsg(e) + (tail ? ". From its log:\n" + tail : "") + "\nLog: " + path81.join(dataDir, "logs", "ptyhost-" + req.id + ".log")
35172
+ errMsg(e) + (tail ? ". From its log:\n" + tail : "") + "\nLog: " + path84.join(dataDir, "logs", "ptyhost-" + req.id + ".log")
34968
35173
  );
34969
35174
  }
34970
35175
  return { child, port, token };
@@ -35078,7 +35283,7 @@ var SessionManager = class {
35078
35283
  };
35079
35284
  this.starting++;
35080
35285
  if (req.id !== session.launchId && process.env.AGENT_NO_TABS !== "1")
35081
- safely("terminal tab", () => terminalTab(req.id, name + " " + path81.basename(req.cwd), req.cwd));
35286
+ safely("terminal tab", () => terminalTab(req.id, name + " " + path84.basename(req.cwd), req.cwd));
35082
35287
  try {
35083
35288
  if (problem) throw new Error(problem);
35084
35289
  const place = await placeFor(req, say);
@@ -35247,13 +35452,13 @@ var SessionManager = class {
35247
35452
  var sessions = new SessionManager();
35248
35453
 
35249
35454
  // src/guest/daemon/live.ts
35250
- import fs66 from "node:fs";
35251
- import path83 from "node:path";
35455
+ import fs67 from "node:fs";
35456
+ import path86 from "node:path";
35252
35457
  import { spawnSync as spawnSync7 } from "node:child_process";
35253
35458
 
35254
35459
  // src/guest/daemon/live-folders.ts
35255
- import fs65 from "node:fs";
35256
- import path82 from "node:path";
35460
+ import fs66 from "node:fs";
35461
+ import path85 from "node:path";
35257
35462
 
35258
35463
  // src/shared/channel/live.ts
35259
35464
  import crypto6 from "node:crypto";
@@ -35346,7 +35551,7 @@ var LiveFolderHandler = class {
35346
35551
  }
35347
35552
  read() {
35348
35553
  try {
35349
- const text = fs65.readFileSync(this.o.stateFile, "utf8");
35554
+ const text = fs66.readFileSync(this.o.stateFile, "utf8");
35350
35555
  const parsed = StateSchema.safeParse(JSON.parse(text));
35351
35556
  if (parsed.success && parsed.data.launchId === this.o.launchId) return parsed.data;
35352
35557
  } catch {
@@ -35354,7 +35559,7 @@ var LiveFolderHandler = class {
35354
35559
  return { key: null, launchId: this.o.launchId, seen: [], mappings: [] };
35355
35560
  }
35356
35561
  save(state) {
35357
- fs65.mkdirSync(path82.dirname(this.o.stateFile), { recursive: true });
35562
+ fs66.mkdirSync(path85.dirname(this.o.stateFile), { recursive: true });
35358
35563
  writeJsonAtomic(this.o.stateFile, state);
35359
35564
  }
35360
35565
  /** The key the boot handed over (from the one-shot secrets file). */
@@ -35365,30 +35570,30 @@ var LiveFolderHandler = class {
35365
35570
  /** C:\Workspace\<name> from a checked name only. */
35366
35571
  folderPath(name) {
35367
35572
  if (!LIVE_FOLDER_NAME.test(name)) throw new Error("not a plain folder name");
35368
- return path82.win32.join(this.o.workspaces ?? WORKSPACES_GUEST, name);
35573
+ return path85.win32.join(this.o.workspaces ?? WORKSPACES_GUEST, name);
35369
35574
  }
35370
35575
  /** One pass over run\live: every file is claimed (deleted) at once; valid ones are handled one after another. */
35371
35576
  tick() {
35372
35577
  const dir = this.o.run.liveDir;
35373
35578
  let names;
35374
35579
  try {
35375
- names = fs65.readdirSync(dir);
35580
+ names = fs66.readdirSync(dir);
35376
35581
  } catch {
35377
35582
  return;
35378
35583
  }
35379
35584
  for (const name of names.slice(0, 64)) {
35380
35585
  if (name.endsWith(".tmp")) continue;
35381
- const file3 = path82.join(dir, name);
35586
+ const file3 = path85.join(dir, name);
35382
35587
  let envelope = null;
35383
35588
  try {
35384
- const stat = fs65.lstatSync(file3);
35589
+ const stat = fs66.lstatSync(file3);
35385
35590
  if (stat.isFile() && stat.size <= MAX_REQUEST_BYTES && /^[A-Za-z0-9_-]{1,64}\.json$/.test(name))
35386
- envelope = JSON.parse(fs65.readFileSync(file3, "utf8"));
35591
+ envelope = JSON.parse(fs66.readFileSync(file3, "utf8"));
35387
35592
  } catch {
35388
35593
  envelope = null;
35389
35594
  } finally {
35390
35595
  try {
35391
- fs65.rmSync(file3, { recursive: true, force: true });
35596
+ fs66.rmSync(file3, { recursive: true, force: true });
35392
35597
  } catch {
35393
35598
  }
35394
35599
  }
@@ -35425,7 +35630,7 @@ var LiveFolderHandler = class {
35425
35630
  }
35426
35631
  reply(id, r) {
35427
35632
  try {
35428
- fs65.mkdirSync(this.o.run.liveRepliesDir, { recursive: true });
35633
+ fs66.mkdirSync(this.o.run.liveRepliesDir, { recursive: true });
35429
35634
  writeJsonAtomic(this.o.run.liveReplyFile(id), { id, ...r, finishedAt: new Date(this.now()).toISOString() });
35430
35635
  } catch (e) {
35431
35636
  this.log("live folder reply not written: " + errMsg(e));
@@ -35446,14 +35651,14 @@ var LiveFolderHandler = class {
35446
35651
  assertFree(folder) {
35447
35652
  let exists2 = true;
35448
35653
  try {
35449
- fs65.lstatSync(folder);
35654
+ fs66.lstatSync(folder);
35450
35655
  } catch {
35451
35656
  exists2 = false;
35452
35657
  }
35453
35658
  if (exists2) throw new Error(folder + " exists already");
35454
- const parent = path82.dirname(folder);
35455
- fs65.mkdirSync(parent, { recursive: true });
35456
- if (!fs65.lstatSync(parent).isDirectory()) throw new Error(parent + " is not a plain folder");
35659
+ const parent = path85.dirname(folder);
35660
+ fs66.mkdirSync(parent, { recursive: true });
35661
+ if (!fs66.lstatSync(parent).isDirectory()) throw new Error(parent + " is not a plain folder");
35457
35662
  }
35458
35663
  async act(p) {
35459
35664
  const folder = this.folderPath(p.folder);
@@ -35474,9 +35679,9 @@ var LiveFolderHandler = class {
35474
35679
  const code2 = await this.mapWithRetry(folder, share2, true);
35475
35680
  if (code2 !== EXIT_OK) return { ok: false, message: "the test share could not be shown (" + code2 + ")" };
35476
35681
  try {
35477
- const file3 = path82.join(folder, "token.txt");
35478
- const stat = fs65.statSync(file3);
35479
- const token = stat.size <= 64 ? fs65.readFileSync(file3, "utf8").trim() : "";
35682
+ const file3 = path85.join(folder, "token.txt");
35683
+ const stat = fs66.statSync(file3);
35684
+ const token = stat.size <= 64 ? fs66.readFileSync(file3, "utf8").trim() : "";
35480
35685
  return LIVE_TOKEN.test(token) ? { ok: true, message: "read the test share", token } : { ok: false, message: "the test share holds no token" };
35481
35686
  } finally {
35482
35687
  this.o.bind.unmap(folder);
@@ -35504,7 +35709,7 @@ var LiveFolderHandler = class {
35504
35709
  for (const m of this.read().mappings) {
35505
35710
  const folder = this.folderPath(m.folder);
35506
35711
  if (this.o.bind.mapped(folder) === EXIT_OK) continue;
35507
- fs65.mkdirSync(path82.dirname(folder), { recursive: true });
35712
+ fs66.mkdirSync(path85.dirname(folder), { recursive: true });
35508
35713
  if (this.o.bind.map(folder, m.share, m.readOnly) === EXIT_OK) done++;
35509
35714
  else this.log("live folder " + folder + " could not be shown again");
35510
35715
  }
@@ -35515,7 +35720,7 @@ var LiveFolderHandler = class {
35515
35720
  // src/guest/daemon/live.ts
35516
35721
  var BIND_TIMEOUT_MS = 3e4;
35517
35722
  var testing = Boolean(process.env.AGENT_DAEMON_STATE_DIR || process.env.AGENT_LOCAL_DIR);
35518
- var stateDir2 = process.env.AGENT_DAEMON_STATE_DIR ?? (process.env.AGENT_LOCAL_DIR ? path83.join(localDir, "daemon-state") : path83.join(process.env.ProgramData ?? "C:\\ProgramData", "AgentSandboxDaemon"));
35723
+ var stateDir2 = process.env.AGENT_DAEMON_STATE_DIR ?? (process.env.AGENT_LOCAL_DIR ? path86.join(localDir, "daemon-state") : path86.join(process.env.ProgramData ?? "C:\\ProgramData", "AgentSandboxDaemon"));
35519
35724
  function bindMount(args) {
35520
35725
  const r = spawnSync7(ensureCompiled("bindmount"), args, {
35521
35726
  windowsHide: true,
@@ -35530,7 +35735,7 @@ var realBind = {
35530
35735
  mapped: (folder) => bindMount(["mapped", folder])
35531
35736
  };
35532
35737
  function protectStateDir() {
35533
- fs66.mkdirSync(stateDir2, { recursive: true });
35738
+ fs67.mkdirSync(stateDir2, { recursive: true });
35534
35739
  if (!isWin || testMode || testing) return;
35535
35740
  spawnSync7(
35536
35741
  SYSTEM.icacls(),
@@ -35543,7 +35748,7 @@ function protectStateDir() {
35543
35748
  }
35544
35749
  var liveFolders = new LiveFolderHandler({
35545
35750
  run,
35546
- stateFile: path83.join(stateDir2, "live-folders.json"),
35751
+ stateFile: path86.join(stateDir2, "live-folders.json"),
35547
35752
  launchId: session.launchId,
35548
35753
  bind: realBind,
35549
35754
  log: warn
@@ -35573,9 +35778,9 @@ var Daemon = class {
35573
35778
  tick() {
35574
35779
  const { valid, invalid } = run.scanRequests();
35575
35780
  for (const file3 of invalid)
35576
- safely("removing an invalid request", () => fs67.rmSync(file3, { recursive: true, force: true }));
35781
+ safely("removing an invalid request", () => fs68.rmSync(file3, { recursive: true, force: true }));
35577
35782
  for (const req of valid) {
35578
- safely("claiming a request", () => fs67.rmSync(run.requestFile(req.id), { force: true }));
35783
+ safely("claiming a request", () => fs68.rmSync(run.requestFile(req.id), { force: true }));
35579
35784
  if (run.readSession(req.id)) continue;
35580
35785
  void Promise.resolve(this.handle(withRequestSecrets(req))).catch(
35581
35786
  (e) => respond(req.id, { ok: false, message: errMsg(e) })