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