windows-development-sandbox 1.1.0 → 1.4.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/README.md +3 -2
- package/config.example.json +38 -5
- package/dist/cli/args.d.ts +3 -0
- package/dist/cli/args.js +3 -1
- package/dist/cli/commands/accounts.js +2 -2
- package/dist/cli/commands/agent-commands.js +1 -1
- package/dist/cli/commands/context.js +2 -1
- package/dist/cli/commands/data/clean.js +6 -1
- package/dist/cli/commands/data/collect.js +3 -3
- package/dist/cli/commands/index.d.ts +1 -1
- package/dist/cli/commands/index.js +1 -1
- package/dist/cli/commands/launch.js +36 -3
- package/dist/cli/commands/maintenance.d.ts +2 -0
- package/dist/cli/commands/maintenance.js +35 -2
- package/dist/cli/commands/sessions.js +3 -3
- package/dist/cli/commands/user-config.js +1 -1
- package/dist/cli/index.js +6 -4
- package/dist/cli/manifest.js +5 -0
- package/dist/cli/menu/apps.d.ts +21 -0
- package/dist/cli/menu/apps.js +122 -0
- package/dist/cli/menu/command-form.d.ts +28 -0
- package/dist/cli/menu/command-form.js +219 -0
- package/dist/cli/menu/index.d.ts +26 -0
- package/dist/cli/menu/index.js +180 -0
- package/dist/cli/menu/settings/categories.d.ts +9 -0
- package/dist/cli/menu/settings/categories.js +28 -0
- package/dist/cli/menu/settings/config-file.d.ts +40 -0
- package/dist/cli/menu/settings/config-file.js +71 -0
- package/dist/cli/menu/settings/editors.d.ts +30 -0
- package/dist/cli/menu/settings/editors.js +305 -0
- package/dist/cli/menu/settings/index.d.ts +32 -0
- package/dist/cli/menu/settings/index.js +136 -0
- package/dist/cli/menu/settings/schema-node.d.ts +62 -0
- package/dist/cli/menu/settings/schema-node.js +104 -0
- package/dist/cli/{menu-multi.d.ts → menu/several.d.ts} +10 -2
- package/dist/cli/menu/several.js +102 -0
- package/dist/cli/tui/app.d.ts +39 -0
- package/dist/cli/tui/app.js +52 -0
- package/dist/cli/tui/dialogs.d.ts +57 -0
- package/dist/cli/tui/dialogs.js +162 -0
- package/dist/cli/tui/frame.d.ts +18 -0
- package/dist/cli/tui/frame.js +27 -0
- package/dist/cli/tui/index.d.ts +7 -0
- package/dist/cli/tui/index.js +8 -0
- package/dist/cli/tui/list-screen.d.ts +101 -0
- package/dist/cli/tui/list-screen.js +299 -0
- package/dist/cli/tui/terminal.d.ts +37 -0
- package/dist/cli/tui/terminal.js +89 -0
- package/dist/cli/tui/text.d.ts +20 -0
- package/dist/cli/tui/text.js +105 -0
- package/dist/cli/tui/theme.d.ts +45 -0
- package/dist/cli/tui/theme.js +30 -0
- package/dist/core/config.js +9 -6
- package/dist/core/local-config.d.ts +15 -0
- package/dist/core/local-config.js +63 -4
- package/dist/core/schema/apps.d.ts +40 -0
- package/dist/core/schema/apps.js +27 -0
- package/dist/core/schema/config.d.ts +66 -1
- package/dist/core/schema/config.js +18 -6
- package/dist/core/schema/profile.d.ts +5 -0
- package/dist/core/schema/profile.js +4 -2
- package/dist/core/schema/sandbox.d.ts +28 -0
- package/dist/core/schema/sandbox.js +28 -0
- package/dist/core/schema/toolchains.d.ts +3 -0
- package/dist/core/schema/toolchains.js +6 -1
- package/dist/core/types.d.ts +6 -0
- package/dist/core/util.d.ts +2 -0
- package/dist/core/util.js +2 -0
- package/dist/core/workspace.js +22 -5
- package/dist/guest/apps/index.d.ts +10 -0
- package/dist/guest/apps/index.js +206 -0
- package/dist/guest/apps/resolvers.d.ts +8 -0
- package/dist/guest/apps/resolvers.js +90 -0
- package/dist/guest/audit-parse.d.ts +7 -0
- package/dist/guest/audit-parse.js +24 -0
- package/dist/guest/audit.d.ts +4 -0
- package/dist/guest/audit.js +47 -0
- package/dist/guest/daemon/relays.d.ts +1 -0
- package/dist/guest/daemon/relays.js +18 -0
- package/dist/guest/daemon.js +4 -0
- package/dist/guest/env.d.ts +1 -0
- package/dist/guest/env.js +3 -1
- package/dist/guest/helpers.d.ts +1 -1
- package/dist/guest/main.js +15 -2
- package/dist/guest/netproxy.d.ts +1 -0
- package/dist/guest/netproxy.js +100 -0
- package/dist/guest/ptyhost.js +14 -4
- package/dist/guest/setup/claude.d.ts +0 -4
- package/dist/guest/setup/claude.js +48 -2
- package/dist/guest/setup/network.d.ts +9 -0
- package/dist/guest/setup/network.js +97 -4
- package/dist/guest/setup/user.js +4 -0
- package/dist/guest/toolchains/native/mesa.js +13 -3
- package/dist/guest/toolchains/plan.d.ts +3 -1
- package/dist/guest/toolchains/plan.js +53 -9
- package/dist/guest/toolchains/python.js +26 -2
- package/dist/guest/toolchains/vscode-profile.d.ts +30 -0
- package/dist/guest/toolchains/vscode-profile.js +69 -0
- package/dist/guest/toolchains/vscode.d.ts +17 -0
- package/dist/guest/toolchains/vscode.js +87 -1
- package/dist/host/attach.js +2 -1
- package/dist/host/audit/collect.d.ts +34 -0
- package/dist/host/audit/collect.js +126 -0
- package/dist/host/audit/log.d.ts +46 -0
- package/dist/host/audit/log.js +143 -0
- package/dist/host/generate.d.ts +6 -0
- package/dist/host/generate.js +10 -0
- package/dist/host/launch/mappings.js +5 -1
- package/dist/host/launch/stage.js +1 -1
- package/dist/host/motw.d.ts +17 -0
- package/dist/host/motw.js +74 -0
- package/dist/host/platform.js +3 -0
- package/dist/host/port-forward.d.ts +8 -0
- package/dist/host/port-forward.js +37 -0
- package/dist/host/repo-guard.d.ts +10 -3
- package/dist/host/repo-guard.js +142 -14
- package/dist/host/stops.d.ts +67 -0
- package/dist/host/stops.js +126 -0
- package/dist/host/terminal.d.ts +8 -0
- package/dist/host/terminal.js +45 -1
- package/dist/host/workspace-view/index.d.ts +20 -0
- package/dist/host/workspace-view/index.js +53 -0
- package/dist/host/workspace-view/rules.d.ts +26 -0
- package/dist/host/workspace-view/rules.js +93 -0
- package/dist/host/workspace-view/view.d.ts +50 -0
- package/dist/host/workspace-view/view.js +281 -0
- package/dist/runtime/daemon.js +1319 -552
- package/dist/runtime/db.js +168 -13
- package/dist/runtime/main.js +2898 -608
- package/dist/runtime/netproxy.js +25936 -0
- package/dist/runtime/view.js +272 -23
- package/dist/selftest/audit.test.d.ts +2 -0
- package/dist/selftest/audit.test.js +57 -0
- package/dist/selftest/channel.test.js +7 -0
- package/dist/selftest/cli.test.js +47 -17
- package/dist/selftest/fixtures.d.ts +45 -0
- package/dist/selftest/fixtures.js +3 -1
- package/dist/selftest/generate.test.js +7 -2
- package/dist/selftest/index.js +5 -2
- package/dist/selftest/live-network.test.d.ts +2 -0
- package/dist/selftest/live-network.test.js +63 -0
- package/dist/selftest/local-config.test.js +16 -3
- package/dist/selftest/network.test.js +12 -0
- package/dist/selftest/projects.test.js +1 -1
- package/dist/selftest/repo-guard.test.js +59 -1
- package/dist/selftest/sync.test.js +50 -10
- package/dist/selftest/toolchains.test.js +30 -0
- package/dist/selftest/workspace-view.test.d.ts +2 -0
- package/dist/selftest/workspace-view.test.js +89 -0
- package/dist/shared/apps.d.ts +49 -0
- package/dist/shared/apps.js +114 -0
- package/dist/shared/netpolicy.d.ts +27 -0
- package/dist/shared/netpolicy.js +51 -0
- package/dist/shared/pty-client.d.ts +9 -4
- package/dist/shared/pty-client.js +139 -17
- package/dist/shared/rundir.d.ts +2 -0
- package/dist/shared/rundir.js +2 -0
- package/dist/shared/schema.d.ts +10 -0
- package/dist/shared/schema.js +2 -0
- package/dist/shared/system.d.ts +1 -0
- package/dist/shared/system.js +1 -0
- package/dist/sync/claude-mem.js +3 -2
- package/dist/sync/history.d.ts +6 -0
- package/dist/sync/history.js +26 -11
- package/dist/sync/watcher.js +78 -6
- package/package.json +2 -1
- package/sandbox/cargoshim.cs +56 -0
- package/sandbox/cpucap.cs +33 -0
- package/sandbox/cpucap.ps1 +4 -35
- package/sandbox/logon.cmd +6 -0
- package/sandbox/memlog.ps1 +34 -0
- package/sandbox/pagefile.cs +31 -0
- package/sandbox/pagefile.ps1 +21 -0
- package/sandbox/ptyhost.cs +105 -7
- package/schemas/config.schema.json +303 -2
- package/schemas/sandbox-config.schema.json +126 -12
- package/dist/cli/menu-multi.js +0 -82
- package/dist/cli/menu.d.ts +0 -14
- package/dist/cli/menu.js +0 -290
- package/dist/cli/settings/edit.d.ts +0 -13
- package/dist/cli/settings/edit.js +0 -19
- package/dist/cli/settings/index.d.ts +0 -8
- package/dist/cli/settings/index.js +0 -131
- package/dist/cli/settings/prompts.d.ts +0 -7
- package/dist/cli/settings/prompts.js +0 -48
- package/dist/cli/settings/schema.d.ts +0 -33
- package/dist/cli/settings/schema.js +0 -29
package/dist/runtime/daemon.js
CHANGED
|
@@ -1363,11 +1363,11 @@ var require_lodash = __commonJS({
|
|
|
1363
1363
|
return isFunction(object2[key]);
|
|
1364
1364
|
});
|
|
1365
1365
|
}
|
|
1366
|
-
function baseGet(object2,
|
|
1367
|
-
|
|
1368
|
-
var index = 0, length =
|
|
1366
|
+
function baseGet(object2, path53) {
|
|
1367
|
+
path53 = castPath(path53, object2);
|
|
1368
|
+
var index = 0, length = path53.length;
|
|
1369
1369
|
while (object2 != null && index < length) {
|
|
1370
|
-
object2 = object2[toKey(
|
|
1370
|
+
object2 = object2[toKey(path53[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, path53, args) {
|
|
1435
|
+
path53 = castPath(path53, object2);
|
|
1436
|
+
object2 = parent(object2, path53);
|
|
1437
|
+
var func = object2 == null ? object2 : object2[toKey(last(path53))];
|
|
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(path53, srcValue) {
|
|
1594
|
+
if (isKey(path53) && isStrictComparable(srcValue)) {
|
|
1595
|
+
return matchesStrictComparable(toKey(path53), 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, path53);
|
|
1599
|
+
return objValue === undefined2 && objValue === srcValue ? hasIn(object2, path53) : 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, path53) {
|
|
1697
|
+
return hasIn(object2, path53);
|
|
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 path53 = paths[index], value = baseGet(object2, path53);
|
|
1704
|
+
if (predicate(value, path53)) {
|
|
1705
|
+
baseSet(result2, castPath(path53, object2), value);
|
|
1706
1706
|
}
|
|
1707
1707
|
}
|
|
1708
1708
|
return result2;
|
|
1709
1709
|
}
|
|
1710
|
-
function basePropertyDeep(
|
|
1710
|
+
function basePropertyDeep(path53) {
|
|
1711
1711
|
return function(object2) {
|
|
1712
|
-
return baseGet(object2,
|
|
1712
|
+
return baseGet(object2, path53);
|
|
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, path53, value, customizer) {
|
|
1787
1787
|
if (!isObject2(object2)) {
|
|
1788
1788
|
return object2;
|
|
1789
1789
|
}
|
|
1790
|
-
|
|
1791
|
-
var index = -1, length =
|
|
1790
|
+
path53 = castPath(path53, object2);
|
|
1791
|
+
var index = -1, length = path53.length, lastIndex = length - 1, nested = object2;
|
|
1792
1792
|
while (nested != null && ++index < length) {
|
|
1793
|
-
var key = toKey(
|
|
1793
|
+
var key = toKey(path53[index]), newValue = value;
|
|
1794
1794
|
if (key === "__proto__" || key === "constructor" || key === "prototype") {
|
|
1795
1795
|
return object2;
|
|
1796
1796
|
}
|
|
@@ -1798,7 +1798,7 @@ var require_lodash = __commonJS({
|
|
|
1798
1798
|
var objValue = nested[key];
|
|
1799
1799
|
newValue = customizer ? customizer(objValue, key, nested) : undefined2;
|
|
1800
1800
|
if (newValue === undefined2) {
|
|
1801
|
-
newValue = isObject2(objValue) ? objValue : isIndex(
|
|
1801
|
+
newValue = isObject2(objValue) ? objValue : isIndex(path53[index + 1]) ? [] : {};
|
|
1802
1802
|
}
|
|
1803
1803
|
}
|
|
1804
1804
|
assignValue(nested, key, 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, path53) {
|
|
1968
|
+
path53 = castPath(path53, object2);
|
|
1969
|
+
var index = -1, length = path53.length;
|
|
1970
1970
|
if (!length) {
|
|
1971
1971
|
return true;
|
|
1972
1972
|
}
|
|
1973
1973
|
while (++index < length) {
|
|
1974
|
-
var key = toKey(
|
|
1974
|
+
var key = toKey(path53[index]);
|
|
1975
1975
|
if (key === "__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, path53);
|
|
1983
|
+
return obj == null || delete obj[toKey(last(path53))];
|
|
1984
1984
|
}
|
|
1985
|
-
function baseUpdate(object2,
|
|
1986
|
-
return baseSet(object2,
|
|
1985
|
+
function baseUpdate(object2, path53, updater, customizer) {
|
|
1986
|
+
return baseSet(object2, path53, updater(baseGet(object2, path53)), 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, path53, hasFunc) {
|
|
2870
|
+
path53 = castPath(path53, object2);
|
|
2871
|
+
var index = -1, length = path53.length, result2 = false;
|
|
2872
2872
|
while (++index < length) {
|
|
2873
|
-
var key = toKey(
|
|
2873
|
+
var key = toKey(path53[index]);
|
|
2874
2874
|
if (!(result2 = object2 != null && hasFunc(object2, key))) {
|
|
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, path53) {
|
|
3076
|
+
return path53.length < 2 ? object2 : baseGet(object2, baseSlice(path53, 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, path53, args) {
|
|
3712
|
+
var index = -1, isFunc = typeof path53 == "function", result2 = isArrayLike(collection) ? Array2(collection.length) : [];
|
|
3713
3713
|
baseEach(collection, function(value) {
|
|
3714
|
-
result2[++index] = isFunc ? apply(
|
|
3714
|
+
result2[++index] = isFunc ? apply(path53, value, args) : baseInvoke(value, path53, args);
|
|
3715
3715
|
});
|
|
3716
3716
|
return result2;
|
|
3717
3717
|
});
|
|
@@ -4175,7 +4175,7 @@ var require_lodash = __commonJS({
|
|
|
4175
4175
|
customizer = typeof customizer == "function" ? customizer : undefined2;
|
|
4176
4176
|
return baseIsMatch(object2, source, getMatchData(source), customizer);
|
|
4177
4177
|
}
|
|
4178
|
-
function
|
|
4178
|
+
function isNaN2(value) {
|
|
4179
4179
|
return isNumber(value) && value != +value;
|
|
4180
4180
|
}
|
|
4181
4181
|
function isNative(value) {
|
|
@@ -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, path53, defaultValue) {
|
|
4367
|
+
var result2 = object2 == null ? undefined2 : baseGet(object2, path53);
|
|
4368
4368
|
return result2 === undefined2 ? defaultValue : result2;
|
|
4369
4369
|
}
|
|
4370
|
-
function has(object2,
|
|
4371
|
-
return object2 != null && hasPath(object2,
|
|
4370
|
+
function has(object2, path53) {
|
|
4371
|
+
return object2 != null && hasPath(object2, path53, baseHas);
|
|
4372
4372
|
}
|
|
4373
|
-
function hasIn(object2,
|
|
4374
|
-
return object2 != null && hasPath(object2,
|
|
4373
|
+
function hasIn(object2, path53) {
|
|
4374
|
+
return object2 != null && hasPath(object2, path53, baseHasIn);
|
|
4375
4375
|
}
|
|
4376
4376
|
var invert = createInverter(function(result2, value, key) {
|
|
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(path53) {
|
|
4428
|
+
path53 = castPath(path53, object2);
|
|
4429
|
+
isDeep || (isDeep = path53.length > 1);
|
|
4430
|
+
return path53;
|
|
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, path53) {
|
|
4457
|
+
return predicate(value, path53[0]);
|
|
4458
4458
|
});
|
|
4459
4459
|
}
|
|
4460
|
-
function result(object2,
|
|
4461
|
-
|
|
4462
|
-
var index = -1, length =
|
|
4460
|
+
function result(object2, path53, defaultValue) {
|
|
4461
|
+
path53 = castPath(path53, object2);
|
|
4462
|
+
var index = -1, length = path53.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(path53[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, path53, value) {
|
|
4478
|
+
return object2 == null ? object2 : baseSet(object2, path53, value);
|
|
4479
4479
|
}
|
|
4480
|
-
function setWith(object2,
|
|
4480
|
+
function setWith(object2, path53, value, customizer) {
|
|
4481
4481
|
customizer = typeof customizer == "function" ? customizer : undefined2;
|
|
4482
|
-
return object2 == null ? object2 : baseSet(object2,
|
|
4482
|
+
return object2 == null ? object2 : baseSet(object2, path53, 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, path53) {
|
|
4505
|
+
return object2 == null ? true : baseUnset(object2, path53);
|
|
4506
4506
|
}
|
|
4507
|
-
function update(object2,
|
|
4508
|
-
return object2 == null ? object2 : baseUpdate(object2,
|
|
4507
|
+
function update(object2, path53, updater) {
|
|
4508
|
+
return object2 == null ? object2 : baseUpdate(object2, path53, castFunction(updater));
|
|
4509
4509
|
}
|
|
4510
|
-
function updateWith(object2,
|
|
4510
|
+
function updateWith(object2, path53, updater, customizer) {
|
|
4511
4511
|
customizer = typeof customizer == "function" ? customizer : undefined2;
|
|
4512
|
-
return object2 == null ? object2 : baseUpdate(object2,
|
|
4512
|
+
return object2 == null ? object2 : baseUpdate(object2, path53, 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(path53, srcValue) {
|
|
4899
|
+
return baseMatchesProperty(path53, baseClone(srcValue, CLONE_DEEP_FLAG));
|
|
4900
4900
|
}
|
|
4901
|
-
var method = baseRest(function(
|
|
4901
|
+
var method = baseRest(function(path53, args) {
|
|
4902
4902
|
return function(object2) {
|
|
4903
|
-
return baseInvoke(object2,
|
|
4903
|
+
return baseInvoke(object2, path53, args);
|
|
4904
4904
|
};
|
|
4905
4905
|
});
|
|
4906
4906
|
var methodOf = baseRest(function(object2, args) {
|
|
4907
|
-
return function(
|
|
4908
|
-
return baseInvoke(object2,
|
|
4907
|
+
return function(path53) {
|
|
4908
|
+
return baseInvoke(object2, path53, 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(path53) {
|
|
4956
|
+
return isKey(path53) ? baseProperty(toKey(path53)) : basePropertyDeep(path53);
|
|
4957
4957
|
}
|
|
4958
4958
|
function propertyOf(object2) {
|
|
4959
|
-
return function(
|
|
4960
|
-
return object2 == null ? undefined2 : baseGet(object2,
|
|
4959
|
+
return function(path53) {
|
|
4960
|
+
return object2 == null ? undefined2 : baseGet(object2, path53);
|
|
4961
4961
|
};
|
|
4962
4962
|
}
|
|
4963
4963
|
var range = createRange();
|
|
@@ -5257,7 +5257,7 @@ var require_lodash = __commonJS({
|
|
|
5257
5257
|
lodash.isMap = isMap;
|
|
5258
5258
|
lodash.isMatch = isMatch;
|
|
5259
5259
|
lodash.isMatchWith = isMatchWith;
|
|
5260
|
-
lodash.isNaN =
|
|
5260
|
+
lodash.isNaN = isNaN2;
|
|
5261
5261
|
lodash.isNative = isNative;
|
|
5262
5262
|
lodash.isNil = isNil;
|
|
5263
5263
|
lodash.isNull = isNull;
|
|
@@ -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(path53, args) {
|
|
5414
|
+
if (typeof path53 == "function") {
|
|
5415
5415
|
return new LazyWrapper(this);
|
|
5416
5416
|
}
|
|
5417
5417
|
return this.map(function(value) {
|
|
5418
|
-
return baseInvoke(value,
|
|
5418
|
+
return baseInvoke(value, path53, args);
|
|
5419
5419
|
});
|
|
5420
5420
|
});
|
|
5421
5421
|
LazyWrapper.prototype.reject = function(predicate) {
|
|
@@ -5532,7 +5532,7 @@ var require_lodash = __commonJS({
|
|
|
5532
5532
|
});
|
|
5533
5533
|
|
|
5534
5534
|
// src/guest/daemon.ts
|
|
5535
|
-
import
|
|
5535
|
+
import fs36 from "node:fs";
|
|
5536
5536
|
|
|
5537
5537
|
// src/shared/rundir.ts
|
|
5538
5538
|
import fs2 from "node:fs";
|
|
@@ -6354,10 +6354,10 @@ function mergeDefs(...defs) {
|
|
|
6354
6354
|
function cloneDef(schema) {
|
|
6355
6355
|
return mergeDefs(schema._zod.def);
|
|
6356
6356
|
}
|
|
6357
|
-
function getElementAtPath(obj,
|
|
6358
|
-
if (!
|
|
6357
|
+
function getElementAtPath(obj, path53) {
|
|
6358
|
+
if (!path53)
|
|
6359
6359
|
return obj;
|
|
6360
|
-
return
|
|
6360
|
+
return path53.reduce((acc, key) => acc?.[key], obj);
|
|
6361
6361
|
}
|
|
6362
6362
|
function promiseAllObject(promisesObj) {
|
|
6363
6363
|
const keys = Object.keys(promisesObj);
|
|
@@ -6697,11 +6697,11 @@ function explicitlyAborted(x, startIndex = 0) {
|
|
|
6697
6697
|
}
|
|
6698
6698
|
return false;
|
|
6699
6699
|
}
|
|
6700
|
-
function prefixIssues(
|
|
6700
|
+
function prefixIssues(path53, issues) {
|
|
6701
6701
|
return issues.map((iss) => {
|
|
6702
6702
|
var _a3;
|
|
6703
6703
|
(_a3 = iss).path ?? (_a3.path = []);
|
|
6704
|
-
iss.path.unshift(
|
|
6704
|
+
iss.path.unshift(path53);
|
|
6705
6705
|
return iss;
|
|
6706
6706
|
});
|
|
6707
6707
|
}
|
|
@@ -7151,16 +7151,16 @@ function flattenError(error62, mapper = (issue2) => issue2.message) {
|
|
|
7151
7151
|
}
|
|
7152
7152
|
function formatError(error62, mapper = (issue2) => issue2.message) {
|
|
7153
7153
|
const fieldErrors = { _errors: [] };
|
|
7154
|
-
const processError = (error63,
|
|
7154
|
+
const processError = (error63, path53 = []) => {
|
|
7155
7155
|
for (const issue2 of error63.issues) {
|
|
7156
7156
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
7157
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
7157
|
+
issue2.errors.map((issues) => processError({ issues }, [...path53, ...issue2.path]));
|
|
7158
7158
|
} else if (issue2.code === "invalid_key") {
|
|
7159
|
-
processError({ issues: issue2.issues }, [...
|
|
7159
|
+
processError({ issues: issue2.issues }, [...path53, ...issue2.path]);
|
|
7160
7160
|
} else if (issue2.code === "invalid_element") {
|
|
7161
|
-
processError({ issues: issue2.issues }, [...
|
|
7161
|
+
processError({ issues: issue2.issues }, [...path53, ...issue2.path]);
|
|
7162
7162
|
} else {
|
|
7163
|
-
const fullpath = [...
|
|
7163
|
+
const fullpath = [...path53, ...issue2.path];
|
|
7164
7164
|
if (fullpath.length === 0) {
|
|
7165
7165
|
fieldErrors._errors.push(mapper(issue2));
|
|
7166
7166
|
} else {
|
|
@@ -7199,17 +7199,17 @@ function formatError(error62, mapper = (issue2) => issue2.message) {
|
|
|
7199
7199
|
}
|
|
7200
7200
|
function treeifyError(error62, mapper = (issue2) => issue2.message) {
|
|
7201
7201
|
const result = { errors: [] };
|
|
7202
|
-
const processError = (error63,
|
|
7202
|
+
const processError = (error63, path53 = []) => {
|
|
7203
7203
|
var _a3;
|
|
7204
7204
|
for (const issue2 of error63.issues) {
|
|
7205
7205
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
7206
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
7206
|
+
issue2.errors.map((issues) => processError({ issues }, [...path53, ...issue2.path]));
|
|
7207
7207
|
} else if (issue2.code === "invalid_key") {
|
|
7208
|
-
processError({ issues: issue2.issues }, [...
|
|
7208
|
+
processError({ issues: issue2.issues }, [...path53, ...issue2.path]);
|
|
7209
7209
|
} else if (issue2.code === "invalid_element") {
|
|
7210
|
-
processError({ issues: issue2.issues }, [...
|
|
7210
|
+
processError({ issues: issue2.issues }, [...path53, ...issue2.path]);
|
|
7211
7211
|
} else {
|
|
7212
|
-
const fullpath = [...
|
|
7212
|
+
const fullpath = [...path53, ...issue2.path];
|
|
7213
7213
|
if (fullpath.length === 0) {
|
|
7214
7214
|
result.errors.push(mapper(issue2));
|
|
7215
7215
|
continue;
|
|
@@ -7248,8 +7248,8 @@ function treeifyError(error62, mapper = (issue2) => issue2.message) {
|
|
|
7248
7248
|
}
|
|
7249
7249
|
function toDotPath(_path) {
|
|
7250
7250
|
const segs = [];
|
|
7251
|
-
const
|
|
7252
|
-
for (const seg of
|
|
7251
|
+
const path53 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
7252
|
+
for (const seg of path53) {
|
|
7253
7253
|
if (typeof seg === "number")
|
|
7254
7254
|
segs.push(`[${seg}]`);
|
|
7255
7255
|
else if (typeof seg === "symbol")
|
|
@@ -7383,18 +7383,18 @@ var validateAsync = async (schema, value, _ctx) => {
|
|
|
7383
7383
|
return result.issues.length === 0;
|
|
7384
7384
|
};
|
|
7385
7385
|
var _encode = (_Err) => {
|
|
7386
|
-
const
|
|
7386
|
+
const parse5 = _parse(_Err);
|
|
7387
7387
|
const fn = (schema, value, _ctx, _params) => {
|
|
7388
7388
|
const ctx = _ctx ? { ..._ctx, direction: "backward" } : { direction: "backward" };
|
|
7389
|
-
return
|
|
7389
|
+
return parse5(schema, value, ctx, finalizeParams(fn, _params));
|
|
7390
7390
|
};
|
|
7391
7391
|
return fn;
|
|
7392
7392
|
};
|
|
7393
7393
|
var encode = /* @__PURE__ */ _encode($ZodRealError);
|
|
7394
7394
|
var _decode = (_Err) => {
|
|
7395
|
-
const
|
|
7395
|
+
const parse5 = _parse(_Err);
|
|
7396
7396
|
const fn = (schema, value, _ctx, _params) => {
|
|
7397
|
-
return
|
|
7397
|
+
return parse5(schema, value, _ctx, finalizeParams(fn, _params));
|
|
7398
7398
|
};
|
|
7399
7399
|
return fn;
|
|
7400
7400
|
};
|
|
@@ -9048,14 +9048,14 @@ var $ZodObject = /* @__PURE__ */ $constructor("$ZodObject", (inst, def) => {
|
|
|
9048
9048
|
const shape = zod.def.shape;
|
|
9049
9049
|
const propValues = {};
|
|
9050
9050
|
for (const key in shape) {
|
|
9051
|
-
const
|
|
9052
|
-
if (
|
|
9051
|
+
const field2 = shape[key]._zod;
|
|
9052
|
+
if (field2.values) {
|
|
9053
9053
|
if (!Object.prototype.hasOwnProperty.call(propValues, key)) {
|
|
9054
9054
|
assignProp(propValues, key, /* @__PURE__ */ new Set());
|
|
9055
9055
|
}
|
|
9056
|
-
for (const v of
|
|
9056
|
+
for (const v of field2.values)
|
|
9057
9057
|
propValues[key].add(v);
|
|
9058
|
-
if (
|
|
9058
|
+
if (field2.optin !== void 0)
|
|
9059
9059
|
propValues[key].add(void 0);
|
|
9060
9060
|
}
|
|
9061
9061
|
}
|
|
@@ -10564,7 +10564,7 @@ var recursive = /* @__PURE__ */ new WeakMap();
|
|
|
10564
10564
|
var NONE = 0;
|
|
10565
10565
|
var ASSUMED = 1;
|
|
10566
10566
|
var PROVEN = 2;
|
|
10567
|
-
function isRecursive(inst, stack,
|
|
10567
|
+
function isRecursive(inst, stack, resolve2) {
|
|
10568
10568
|
const cached2 = recursive.get(inst);
|
|
10569
10569
|
if (cached2 !== void 0)
|
|
10570
10570
|
return cached2 ? PROVEN : NONE;
|
|
@@ -10574,7 +10574,7 @@ function isRecursive(inst, stack, resolve) {
|
|
|
10574
10574
|
let result = NONE;
|
|
10575
10575
|
const check2 = (child) => {
|
|
10576
10576
|
if (result !== PROVEN && child?._zod) {
|
|
10577
|
-
const answer = isRecursive(child, stack,
|
|
10577
|
+
const answer = isRecursive(child, stack, resolve2);
|
|
10578
10578
|
if (answer > result)
|
|
10579
10579
|
result = answer;
|
|
10580
10580
|
}
|
|
@@ -10585,7 +10585,7 @@ function isRecursive(inst, stack, resolve) {
|
|
|
10585
10585
|
const desc = Object.getOwnPropertyDescriptor(sh, key);
|
|
10586
10586
|
if (spread && !desc.enumerable)
|
|
10587
10587
|
continue;
|
|
10588
|
-
const child = desc.get ? ASSUMED : desc.value?._zod ? isRecursive(desc.value, stack,
|
|
10588
|
+
const child = desc.get ? ASSUMED : desc.value?._zod ? isRecursive(desc.value, stack, resolve2) : NONE;
|
|
10589
10589
|
if (child > answer)
|
|
10590
10590
|
answer = child;
|
|
10591
10591
|
}
|
|
@@ -10649,7 +10649,7 @@ function isRecursive(inst, stack, resolve) {
|
|
|
10649
10649
|
break;
|
|
10650
10650
|
// `$ZodLazy` caches its inner on the def, so a resolved edge is followed exactly
|
|
10651
10651
|
case "lazy": {
|
|
10652
|
-
const inner = def._cachedInner ?? (
|
|
10652
|
+
const inner = def._cachedInner ?? (resolve2 ? inst._zod.innerType : void 0);
|
|
10653
10653
|
merge2(inner ? isRecursive(inner, stack, false) : ASSUMED);
|
|
10654
10654
|
break;
|
|
10655
10655
|
}
|
|
@@ -18759,8 +18759,8 @@ function generateMultipleOfCheck(doc, ctx, def, accessor) {
|
|
|
18759
18759
|
}
|
|
18760
18760
|
}
|
|
18761
18761
|
function generateNumberFormatCheck(doc, def, accessor) {
|
|
18762
|
-
const
|
|
18763
|
-
switch (
|
|
18762
|
+
const format2 = def.format;
|
|
18763
|
+
switch (format2) {
|
|
18764
18764
|
case "safeint":
|
|
18765
18765
|
doc.write(`if (!Number.isSafeInteger(${accessor})) return INVALID;`);
|
|
18766
18766
|
break;
|
|
@@ -18777,16 +18777,16 @@ function generateNumberFormatCheck(doc, def, accessor) {
|
|
|
18777
18777
|
doc.write(`if (!Number.isFinite(${accessor})) return INVALID;`);
|
|
18778
18778
|
break;
|
|
18779
18779
|
default: {
|
|
18780
|
-
void
|
|
18781
|
-
throw new ZodCompileUnsupportedError(`number format ${
|
|
18780
|
+
void format2;
|
|
18781
|
+
throw new ZodCompileUnsupportedError(`number format ${format2}`);
|
|
18782
18782
|
}
|
|
18783
18783
|
}
|
|
18784
18784
|
}
|
|
18785
18785
|
function generateBigIntFormatCheck(doc, def, accessor) {
|
|
18786
|
-
const
|
|
18787
|
-
if (!
|
|
18786
|
+
const format2 = def.format;
|
|
18787
|
+
if (!format2)
|
|
18788
18788
|
return;
|
|
18789
|
-
switch (
|
|
18789
|
+
switch (format2) {
|
|
18790
18790
|
case "int64":
|
|
18791
18791
|
doc.write(`if (${accessor} < -9223372036854775808n || ${accessor} > 9223372036854775807n) return INVALID;`);
|
|
18792
18792
|
break;
|
|
@@ -18794,8 +18794,8 @@ function generateBigIntFormatCheck(doc, def, accessor) {
|
|
|
18794
18794
|
doc.write(`if (${accessor} < 0n || ${accessor} > 18446744073709551615n) return INVALID;`);
|
|
18795
18795
|
break;
|
|
18796
18796
|
default: {
|
|
18797
|
-
void
|
|
18798
|
-
throw new ZodCompileUnsupportedError(`bigint format ${
|
|
18797
|
+
void format2;
|
|
18798
|
+
throw new ZodCompileUnsupportedError(`bigint format ${format2}`);
|
|
18799
18799
|
}
|
|
18800
18800
|
}
|
|
18801
18801
|
}
|
|
@@ -18976,8 +18976,8 @@ function generateStringFormatCheck(doc, ctx, def, accessor, needsValue = true) {
|
|
|
18976
18976
|
doc.write(`if (!${patternConst}.test(${accessor})) return INVALID;`);
|
|
18977
18977
|
return accessor;
|
|
18978
18978
|
}
|
|
18979
|
-
const
|
|
18980
|
-
switch (
|
|
18979
|
+
const format2 = def.format;
|
|
18980
|
+
switch (format2) {
|
|
18981
18981
|
case "regex":
|
|
18982
18982
|
throw new ZodCompileUnsupportedError("regex format without a pattern");
|
|
18983
18983
|
case "lowercase":
|
|
@@ -19000,8 +19000,8 @@ function generateStringFormatCheck(doc, ctx, def, accessor, needsValue = true) {
|
|
|
19000
19000
|
break;
|
|
19001
19001
|
}
|
|
19002
19002
|
default: {
|
|
19003
|
-
void
|
|
19004
|
-
throw new ZodCompileUnsupportedError(`string format ${
|
|
19003
|
+
void format2;
|
|
19004
|
+
throw new ZodCompileUnsupportedError(`string format ${format2}`);
|
|
19005
19005
|
}
|
|
19006
19006
|
}
|
|
19007
19007
|
return accessor;
|
|
@@ -21084,12 +21084,12 @@ function _stringbool(Classes, _params) {
|
|
|
21084
21084
|
return codec2;
|
|
21085
21085
|
}
|
|
21086
21086
|
// @__NO_SIDE_EFFECTS__
|
|
21087
|
-
function _stringFormat(Class2,
|
|
21087
|
+
function _stringFormat(Class2, format2, fnOrRegex, _params = {}) {
|
|
21088
21088
|
const params = normalizeParams(_params);
|
|
21089
21089
|
const def = {
|
|
21090
21090
|
check: "string_format",
|
|
21091
21091
|
type: "string",
|
|
21092
|
-
format,
|
|
21092
|
+
format: format2,
|
|
21093
21093
|
fn: typeof fnOrRegex === "function" ? fnOrRegex : (val) => fnOrRegex.test(val),
|
|
21094
21094
|
...params
|
|
21095
21095
|
};
|
|
@@ -21655,9 +21655,9 @@ var addPattern = (agg, pattern) => {
|
|
|
21655
21655
|
var intersectMime = (agg, mime) => {
|
|
21656
21656
|
agg.mime = agg.mime ? agg.mime.filter((m) => mime.includes(m)) : [...mime];
|
|
21657
21657
|
};
|
|
21658
|
-
var setFormat = (agg,
|
|
21659
|
-
agg.format =
|
|
21660
|
-
if (
|
|
21658
|
+
var setFormat = (agg, format2) => {
|
|
21659
|
+
agg.format = format2;
|
|
21660
|
+
if (format2.includes("int"))
|
|
21661
21661
|
agg.isInt = true;
|
|
21662
21662
|
};
|
|
21663
21663
|
var minContributor = (agg, def) => narrowMin(agg, "minimum", def.minimum);
|
|
@@ -21735,16 +21735,16 @@ var exactPattern = (p) => exactPatterns.get(p) ?? p;
|
|
|
21735
21735
|
var stringProcessor = (schema, ctx, _json, _params) => {
|
|
21736
21736
|
const json2 = _json;
|
|
21737
21737
|
json2.type = "string";
|
|
21738
|
-
const { minimum, maximum, format, patterns, contentEncoding, laxFormat } = aggregateChecks(schema);
|
|
21738
|
+
const { minimum, maximum, format: format2, patterns, contentEncoding, laxFormat } = aggregateChecks(schema);
|
|
21739
21739
|
if (typeof minimum === "number")
|
|
21740
21740
|
json2.minLength = minimum;
|
|
21741
21741
|
if (typeof maximum === "number")
|
|
21742
21742
|
json2.maxLength = maximum;
|
|
21743
|
-
if (
|
|
21744
|
-
json2.format = formatMap[
|
|
21743
|
+
if (format2) {
|
|
21744
|
+
json2.format = formatMap[format2] ?? format2;
|
|
21745
21745
|
if (json2.format === "")
|
|
21746
21746
|
delete json2.format;
|
|
21747
|
-
if (
|
|
21747
|
+
if (format2 === "time" || laxFormat) {
|
|
21748
21748
|
delete json2.format;
|
|
21749
21749
|
}
|
|
21750
21750
|
}
|
|
@@ -21983,8 +21983,8 @@ var objectProcessor = (schema, ctx, _json, params) => {
|
|
|
21983
21983
|
}
|
|
21984
21984
|
const requiredKeys = [];
|
|
21985
21985
|
for (const key of Object.keys(shape)) {
|
|
21986
|
-
const
|
|
21987
|
-
if (ctx.io === "input" ? inputOptin(
|
|
21986
|
+
const field2 = def.shape[key];
|
|
21987
|
+
if (ctx.io === "input" ? inputOptin(field2) === void 0 : field2._zod.optout === void 0) {
|
|
21988
21988
|
requiredKeys.push(key);
|
|
21989
21989
|
}
|
|
21990
21990
|
}
|
|
@@ -22122,7 +22122,7 @@ function stringifyKeyNames(bySchema, json2, visited) {
|
|
|
22122
22122
|
const values = json2.enum ?? (json2.const !== void 0 ? [json2.const] : void 0);
|
|
22123
22123
|
if (!numericType && !values?.some((v) => typeof v === "number"))
|
|
22124
22124
|
return json2;
|
|
22125
|
-
const { minimum, maximum, exclusiveMinimum, exclusiveMaximum, multipleOf, format, id, ...rest } = json2;
|
|
22125
|
+
const { minimum, maximum, exclusiveMinimum, exclusiveMaximum, multipleOf, format: format2, id, ...rest } = json2;
|
|
22126
22126
|
if (rest.enum)
|
|
22127
22127
|
rest.enum = rest.enum.map((v) => typeof v === "number" ? String(v) : v);
|
|
22128
22128
|
else if (typeof rest.const === "number")
|
|
@@ -23258,8 +23258,8 @@ var ZodCustomStringFormat = /* @__PURE__ */ $constructor("ZodCustomStringFormat"
|
|
|
23258
23258
|
$ZodCustomStringFormat.init(inst, def);
|
|
23259
23259
|
ZodStringFormat.init(inst, def);
|
|
23260
23260
|
});
|
|
23261
|
-
function stringFormat(
|
|
23262
|
-
return _stringFormat(ZodCustomStringFormat,
|
|
23261
|
+
function stringFormat(format2, fnOrRegex, _params = {}) {
|
|
23262
|
+
return _stringFormat(ZodCustomStringFormat, format2, fnOrRegex, _params);
|
|
23263
23263
|
}
|
|
23264
23264
|
function hostname2(_params) {
|
|
23265
23265
|
return _stringFormat(ZodCustomStringFormat, "hostname", hostname, _params);
|
|
@@ -23272,11 +23272,11 @@ function currencyCode2(_params) {
|
|
|
23272
23272
|
}
|
|
23273
23273
|
function hash(alg, params) {
|
|
23274
23274
|
const enc = params?.enc ?? "hex";
|
|
23275
|
-
const
|
|
23276
|
-
const regex = regexes_exports[
|
|
23275
|
+
const format2 = `${alg}_${enc}`;
|
|
23276
|
+
const regex = regexes_exports[format2];
|
|
23277
23277
|
if (!regex)
|
|
23278
|
-
throw new Error(`Unrecognized hash format: ${
|
|
23279
|
-
return _stringFormat(ZodCustomStringFormat,
|
|
23278
|
+
throw new Error(`Unrecognized hash format: ${format2}`);
|
|
23279
|
+
return _stringFormat(ZodCustomStringFormat, format2, regex, params);
|
|
23280
23280
|
}
|
|
23281
23281
|
var ZodNumber = /* @__PURE__ */ $constructor(
|
|
23282
23282
|
"ZodNumber",
|
|
@@ -24351,13 +24351,13 @@ function resolveRef(ref, ctx) {
|
|
|
24351
24351
|
if (!ref.startsWith("#")) {
|
|
24352
24352
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
24353
24353
|
}
|
|
24354
|
-
const
|
|
24355
|
-
if (
|
|
24354
|
+
const path53 = ref.slice(1).split("/").filter(Boolean);
|
|
24355
|
+
if (path53.length === 0) {
|
|
24356
24356
|
return ctx.rootSchema;
|
|
24357
24357
|
}
|
|
24358
24358
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
24359
|
-
if (
|
|
24360
|
-
const key =
|
|
24359
|
+
if (path53[0] === defsKey) {
|
|
24360
|
+
const key = path53[1] === void 0 ? void 0 : decodeJSONPointerSegment(path53[1]);
|
|
24361
24361
|
if (!key || !ctx.defs[key]) {
|
|
24362
24362
|
throw new Error(`Reference not found: ${ref}`);
|
|
24363
24363
|
}
|
|
@@ -24641,58 +24641,58 @@ function convertBaseSchema(schema, ctx) {
|
|
|
24641
24641
|
case "string": {
|
|
24642
24642
|
let stringSchema = z.string();
|
|
24643
24643
|
if (schema.format) {
|
|
24644
|
-
const
|
|
24645
|
-
if (
|
|
24644
|
+
const format2 = schema.format;
|
|
24645
|
+
if (format2 === "email") {
|
|
24646
24646
|
stringSchema = stringSchema.check(z.email());
|
|
24647
|
-
} else if (
|
|
24647
|
+
} else if (format2 === "uri" || format2 === "uri-reference") {
|
|
24648
24648
|
stringSchema = stringSchema.check(z.url());
|
|
24649
|
-
} else if (
|
|
24649
|
+
} else if (format2 === "uuid" || format2 === "guid") {
|
|
24650
24650
|
stringSchema = stringSchema.check(z.uuid());
|
|
24651
|
-
} else if (
|
|
24651
|
+
} else if (format2 === "date-time") {
|
|
24652
24652
|
stringSchema = stringSchema.check(z.iso.datetime({ offset: true }));
|
|
24653
|
-
} else if (
|
|
24653
|
+
} else if (format2 === "date") {
|
|
24654
24654
|
stringSchema = stringSchema.check(z.iso.date());
|
|
24655
|
-
} else if (
|
|
24655
|
+
} else if (format2 === "time") {
|
|
24656
24656
|
stringSchema = stringSchema.check(z.regex(fullTime));
|
|
24657
|
-
} else if (
|
|
24657
|
+
} else if (format2 === "duration") {
|
|
24658
24658
|
stringSchema = stringSchema.check(z.iso.duration());
|
|
24659
|
-
} else if (
|
|
24659
|
+
} else if (format2 === "hostname") {
|
|
24660
24660
|
stringSchema = stringSchema.check(z.hostname());
|
|
24661
|
-
} else if (
|
|
24661
|
+
} else if (format2 === "ipv4") {
|
|
24662
24662
|
stringSchema = stringSchema.check(z.ipv4());
|
|
24663
|
-
} else if (
|
|
24663
|
+
} else if (format2 === "ipv6") {
|
|
24664
24664
|
stringSchema = stringSchema.check(z.ipv6());
|
|
24665
|
-
} else if (
|
|
24665
|
+
} else if (format2 === "mac") {
|
|
24666
24666
|
stringSchema = stringSchema.check(z.mac());
|
|
24667
|
-
} else if (
|
|
24667
|
+
} else if (format2 === "cidr") {
|
|
24668
24668
|
stringSchema = stringSchema.check(z.cidrv4());
|
|
24669
|
-
} else if (
|
|
24669
|
+
} else if (format2 === "cidr-v6") {
|
|
24670
24670
|
stringSchema = stringSchema.check(z.cidrv6());
|
|
24671
|
-
} else if (
|
|
24671
|
+
} else if (format2 === "base64") {
|
|
24672
24672
|
stringSchema = stringSchema.check(z.base64());
|
|
24673
|
-
} else if (
|
|
24673
|
+
} else if (format2 === "base64url") {
|
|
24674
24674
|
stringSchema = stringSchema.check(z.base64url());
|
|
24675
|
-
} else if (
|
|
24675
|
+
} else if (format2 === "e164") {
|
|
24676
24676
|
stringSchema = stringSchema.check(z.e164());
|
|
24677
|
-
} else if (
|
|
24677
|
+
} else if (format2 === "credit_card") {
|
|
24678
24678
|
stringSchema = stringSchema.check(z.creditCard());
|
|
24679
|
-
} else if (
|
|
24679
|
+
} else if (format2 === "iban") {
|
|
24680
24680
|
stringSchema = stringSchema.check(z.iban());
|
|
24681
|
-
} else if (
|
|
24681
|
+
} else if (format2 === "jwt") {
|
|
24682
24682
|
stringSchema = stringSchema.check(z.jwt());
|
|
24683
|
-
} else if (
|
|
24683
|
+
} else if (format2 === "emoji") {
|
|
24684
24684
|
stringSchema = stringSchema.check(z.emoji());
|
|
24685
|
-
} else if (
|
|
24685
|
+
} else if (format2 === "nanoid") {
|
|
24686
24686
|
stringSchema = stringSchema.check(z.nanoid());
|
|
24687
|
-
} else if (
|
|
24687
|
+
} else if (format2 === "cuid") {
|
|
24688
24688
|
stringSchema = stringSchema.check(z.cuid());
|
|
24689
|
-
} else if (
|
|
24689
|
+
} else if (format2 === "cuid2") {
|
|
24690
24690
|
stringSchema = stringSchema.check(z.cuid2());
|
|
24691
|
-
} else if (
|
|
24691
|
+
} else if (format2 === "ulid") {
|
|
24692
24692
|
stringSchema = stringSchema.check(z.ulid());
|
|
24693
|
-
} else if (
|
|
24693
|
+
} else if (format2 === "xid") {
|
|
24694
24694
|
stringSchema = stringSchema.check(z.xid());
|
|
24695
|
-
} else if (
|
|
24695
|
+
} else if (format2 === "ksuid") {
|
|
24696
24696
|
stringSchema = stringSchema.check(z.ksuid());
|
|
24697
24697
|
}
|
|
24698
24698
|
}
|
|
@@ -25310,8 +25310,10 @@ var ClaudeProfile = external_exports.strictObject({
|
|
|
25310
25310
|
globalStateFile: external_exports.string().describe('Your .claude.json, or "auto". Empty string = do not copy.'),
|
|
25311
25311
|
copyCredentials: external_exports.boolean().describe("Copy your Claude LOGIN into the sandbox. Prefer sandbox account instead."),
|
|
25312
25312
|
overwrite: external_exports.boolean().describe("Refresh these settings from this PC on every launch."),
|
|
25313
|
-
syncHistory: external_exports.boolean().describe("Bring
|
|
25314
|
-
|
|
25313
|
+
syncHistory: external_exports.boolean().describe("Bring conversation history in, and sync new history back (path-translated)."),
|
|
25314
|
+
historyScope: external_exports.enum(["project", "all"]).describe(`Which history comes in: "project" = only the projects in this sandbox (other projects' conversations, file backups and prompts stay on this PC), "all" = everything. Only this sandbox's projects ever sync back.`),
|
|
25315
|
+
syncClaudeMem: external_exports.boolean().describe("Bring claude-mem data into the sandbox (its settings and backups stay on this PC)."),
|
|
25316
|
+
syncClaudeMemBack: external_exports.boolean().describe("Also copy claude-mem's database back to this PC when the sandbox closes. Off by default: what is in it is loaded into every Claude session on this PC, so a compromised agent could plant instructions there.")
|
|
25315
25317
|
});
|
|
25316
25318
|
|
|
25317
25319
|
// src/core/schema/sandbox.ts
|
|
@@ -25327,6 +25329,7 @@ var Sandbox = external_exports.strictObject({
|
|
|
25327
25329
|
maxMemoryMb: external_exports.number().int().positive().describe('Upper limit for memoryMb "auto".'),
|
|
25328
25330
|
maxMemoryPercent: external_exports.number().int().min(10).max(100).describe(`memoryMb "auto" never takes more than this share of this PC's total RAM (percent).`),
|
|
25329
25331
|
cpuLimit: external_exports.union([external_exports.literal("none"), external_exports.number().int().min(5).max(100)]).describe(`Most of this PC's CPU the sandbox may use, in percent (5-100), e.g. 50 keeps half free for you; "none" = no cap (Windows Sandbox would take every processor). Covers everything this tool starts in the sandbox (agents, installs, builds, its terminal).`),
|
|
25332
|
+
pageFileMb: external_exports.number().int().min(0).max(262144).describe(`Size of the sandbox's paging file in MB, created at full size when it starts so it never grows while builds run (8 GB of its disk always stays free). Windows Sandbox starts with about 1 GB: parallel builds then fail with "The paging file is too small", and Windows grows the file under load. 0 = leave Windows' own.`),
|
|
25330
25333
|
reserveHostMb: external_exports.number().int().nonnegative().describe('RAM always left for this PC when memoryMb is "auto".'),
|
|
25331
25334
|
vGpu: external_exports.boolean().describe("Virtual GPU. Off by default: Microsoft notes it widens the sandbox attack surface."),
|
|
25332
25335
|
networking: external_exports.boolean().describe("Internet access. false is the only hard network isolation Windows Sandbox offers."),
|
|
@@ -25335,7 +25338,33 @@ var Sandbox = external_exports.strictObject({
|
|
|
25335
25338
|
videoInput: external_exports.boolean().describe("Camera access."),
|
|
25336
25339
|
printerRedirection: external_exports.boolean().describe("Printers from this PC."),
|
|
25337
25340
|
protectedClient: external_exports.boolean().describe("Run the sandbox window in Protected Client mode (recommended)."),
|
|
25338
|
-
headless: external_exports.boolean().describe("Hide the sandbox window (sbx-show brings it back). A headless sandbox shuts down when its last session ends.")
|
|
25341
|
+
headless: external_exports.boolean().describe("Hide the sandbox window (sbx-show brings it back). A headless sandbox shuts down when its last session ends."),
|
|
25342
|
+
keepAwake: external_exports.boolean().describe("Keep this PC from sleeping while a sandbox runs, so agents left working overnight keep going (the screen may still turn off; closing a laptop lid still sleeps it).")
|
|
25343
|
+
});
|
|
25344
|
+
var Port2 = external_exports.number().int().min(1).max(65535);
|
|
25345
|
+
var HostEntry = external_exports.string().max(253).regex(/^(@developer|(\*\.)?([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+)$/, "a host name like example.com, *.example.com, or @developer");
|
|
25346
|
+
var Network = external_exports.strictObject({
|
|
25347
|
+
blockPrivateRanges: external_exports.boolean().describe("Block your LAN (10/8, 172.16/12, 192.168/16, SMB) from inside the sandbox."),
|
|
25348
|
+
allowOnly: external_exports.array(HostEntry).describe("Only these hosts can be reached once the sandbox is set up (tools still download first). *.example.com covers its subdomains; @developer adds package registries, GitHub, toolchain downloads and the AI providers. Programs go through a proxy in the sandbox (HTTP_PROXY); anything else is blocked by its firewall. Empty = no limit."),
|
|
25349
|
+
blockHosts: external_exports.array(external_exports.string().max(253).regex(/^([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+$/, "a host name like telemetry.example.com")).describe("Never reachable from the sandbox, e.g. production servers or telemetry (each exact name; the sandbox's hosts file sends them nowhere)."),
|
|
25350
|
+
forwardPorts: external_exports.array(external_exports.strictObject({
|
|
25351
|
+
pc: Port2.describe("The port on this PC (localhost only)."),
|
|
25352
|
+
sandbox: Port2.describe("The port inside the sandbox (a server there may listen on localhost only).")
|
|
25353
|
+
})).describe("Reach servers in the sandbox from this PC: http://localhost:<pc> here goes to <sandbox> inside, while it runs. Nothing else on your network can use them."),
|
|
25354
|
+
dns: external_exports.array(external_exports.string().regex(/^\d{1,3}(\.\d{1,3}){3}$/, "an IPv4 address like 1.1.1.1")).describe("DNS servers for the sandbox instead of your network's, e.g. 1.1.1.1 and 9.9.9.9."),
|
|
25355
|
+
proxy: external_exports.string().regex(/^(https?:\/\/[^\s]+)?$/, "http://host:port").describe("An HTTP proxy the sandbox uses to reach the internet (HTTP_PROXY / HTTPS_PROXY for everything in it), e.g. http://proxy.corp:8080. Empty = none.")
|
|
25356
|
+
});
|
|
25357
|
+
var Audit = external_exports.strictObject({
|
|
25358
|
+
enabled: external_exports.boolean().describe("Keep an audit log on this PC of what happened in your sandboxes: programs started (with their command lines), files changed in the project, sessions, and what the repo guard caught. The sandbox cannot change it. Read it with sandbox audit."),
|
|
25359
|
+
days: external_exports.number().int().min(1).max(365).describe("Days the audit log is kept."),
|
|
25360
|
+
maxMb: external_exports.number().int().min(5).max(5e3).describe("Most space the audit log may take, in MB (older days go first). Days before today are compressed."),
|
|
25361
|
+
processes: external_exports.boolean().describe("Record every program started in the sandbox with its command line (Windows process auditing; repeated runs are counted, not listed)."),
|
|
25362
|
+
files: external_exports.boolean().describe("Record the files changed in the project while the sandbox runs.")
|
|
25363
|
+
});
|
|
25364
|
+
var WorkspaceFilter = external_exports.strictObject({
|
|
25365
|
+
enabled: external_exports.boolean().describe("Keep what your .gitignore lists (.env files, node_modules, build output ...) out of the sandbox. The sandbox works on a copy of the project without those files, kept in step with it both ways within about a second; what it creates that is ignored (its own node_modules, builds) stays in the sandbox. Git works as usual. Off = the project folder itself is mapped."),
|
|
25366
|
+
exclude: external_exports.array(external_exports.string().max(500)).describe("Also keep these out, as .gitignore patterns, e.g. secrets/, *.pem, data/private/."),
|
|
25367
|
+
include: external_exports.array(external_exports.string().max(500)).describe("Let these in although .gitignore lists them, e.g. .env.example, data/fixtures/.")
|
|
25339
25368
|
});
|
|
25340
25369
|
var Git = external_exports.strictObject({ enabled: external_exports.boolean().describe("Provide Git for Windows (and Git Bash, which Claude Code needs)."), access: GitAccess });
|
|
25341
25370
|
var Provisioning = external_exports.strictObject({
|
|
@@ -25343,7 +25372,8 @@ var Provisioning = external_exports.strictObject({
|
|
|
25343
25372
|
fallbackToInstall: external_exports.boolean().describe("Download anything that cannot be copied from this PC."),
|
|
25344
25373
|
refresh: external_exports.boolean().describe("Re-copy / re-download everything on the next launch."),
|
|
25345
25374
|
git: Git,
|
|
25346
|
-
terminal: toggle("Windows Terminal as the sandbox window (downloaded once).")
|
|
25375
|
+
terminal: toggle("Windows Terminal as the sandbox window (downloaded once)."),
|
|
25376
|
+
conpty: toggle("Agent sessions use Microsoft's newer pseudo console (conpty.dll, downloaded once) instead of the one built into Windows: no garbled screen after resizing, real scrollback for the mouse wheel. Off = the one built into Windows.")
|
|
25347
25377
|
});
|
|
25348
25378
|
var Downloads = external_exports.strictObject({
|
|
25349
25379
|
requireChecksum: external_exports.boolean().describe("Refuse any toolchain, database or tool download that has no published checksum (SHA-256/SHA-512) to verify it against. false = allow those, as before. Downloads that do have a published checksum are always verified. A project's .sandbox-config.json can only turn this on.")
|
|
@@ -25427,10 +25457,150 @@ var Toolchains = external_exports.strictObject({
|
|
|
25427
25457
|
enabled: external_exports.boolean().describe("Mesa 3D (llvmpipe): OpenGL 4.5 in software for games and apps when there is no GPU (sandbox.vGpu off). Copy opengl32.dll and libgallium_wgl.dll from %MESA_DIR% next to the program's .exe."),
|
|
25428
25458
|
vulkan: external_exports.boolean().describe("Also software Vulkan 1.4 (Mesa lavapipe) with the Khronos loader, registered for every program; for wgpu set WGPU_BACKEND=vulkan.")
|
|
25429
25459
|
}),
|
|
25430
|
-
vscode:
|
|
25460
|
+
vscode: external_exports.strictObject({
|
|
25461
|
+
enabled: external_exports.boolean().describe("Portable VS Code inside the sandbox (code on PATH, desktop shortcut); its settings and extensions persist."),
|
|
25462
|
+
setup: external_exports.boolean().describe("Point VS Code at the sandbox's own tools (JDK, Python, Go, compilers, .NET, Git, PowerShell 7 and Git Bash terminals) and install the language extensions for the toolchains in use."),
|
|
25463
|
+
recommended: external_exports.boolean().describe("Also install the extensions a project recommends in its .vscode/extensions.json."),
|
|
25464
|
+
extensions: external_exports.array(external_exports.string().regex(/^[\w-]+\.[\w-]+$/, "publisher.name, e.g. eamodio.gitlens")).describe("More extensions to install in every sandbox, e.g. eamodio.gitlens, ms-azuretools.vscode-docker.")
|
|
25465
|
+
}),
|
|
25431
25466
|
environment: external_exports.record(external_exports.string().regex(/^[A-Za-z_][A-Za-z0-9_]*$/, "letters, digits and _ only"), external_exports.string()).describe('Extra environment variables for the agent and every terminal, e.g. registry mirrors: {"NPM_CONFIG_REGISTRY": "https://...", "PIP_INDEX_URL": "https://..."}.')
|
|
25432
25467
|
});
|
|
25433
25468
|
|
|
25469
|
+
// src/shared/apps.ts
|
|
25470
|
+
var gh = (github, asset) => ({ github, asset });
|
|
25471
|
+
var APPS = [
|
|
25472
|
+
// ---- editors
|
|
25473
|
+
{ id: "vscode", name: "Visual Studio Code", category: "editors", about: "Code editor with debugging, set up for the sandbox's languages.", size: "150 MB", source: { resolve: "setting" }, exe: "Code.exe", setting: "toolchains.vscode.enabled" },
|
|
25474
|
+
{ id: "windows-terminal", name: "Windows Terminal", category: "utilities", about: "The sandbox window: tabs, panes, PowerShell 7 profile.", size: "40 MB", source: { resolve: "setting" }, exe: "WindowsTerminal.exe", setting: "provisioning.terminal.enabled" },
|
|
25475
|
+
{ id: "notepadpp", name: "Notepad++", category: "editors", about: "Fast text and code editor.", size: "8 MB", source: gh("notepad-plus-plus/notepad-plus-plus", "^npp\\.[\\d.]+\\.portable\\.x64\\.zip$"), exe: "notepad++.exe" },
|
|
25476
|
+
{ id: "sublime", name: "Sublime Text", category: "editors", about: "Fast code editor (paid licence, free to evaluate).", size: "28 MB", source: { resolve: "sublime" }, exe: "sublime_text.exe" },
|
|
25477
|
+
{ id: "neovim", name: "Neovim", category: "editors", about: "Terminal text editor (nvim).", size: "12 MB", source: gh("neovim/neovim", "^nvim-win64\\.zip$"), exe: "nvim.exe", cli: true },
|
|
25478
|
+
// ---- database clients
|
|
25479
|
+
{ id: "dbeaver", name: "DBeaver Community", category: "databases", about: "Universal database client: PostgreSQL, MySQL, SQLite, SQL Server and more.", size: "120 MB", source: gh("dbeaver/dbeaver", "^dbeaver-ce-[\\d.]+-windows-x86_64\\.zip$"), exe: "dbeaver.exe" },
|
|
25480
|
+
{ id: "pgadmin", name: "pgAdmin 4", category: "databases", about: "The PostgreSQL admin GUI (from the PostgreSQL binaries zip).", size: "330 MB", source: { resolve: "pgadmin" }, exe: "pgAdmin4.exe" },
|
|
25481
|
+
{ id: "heidisql", name: "HeidiSQL", category: "databases", about: "Light client for MySQL, MariaDB, PostgreSQL and SQL Server.", size: "28 MB", source: gh("HeidiSQL/HeidiSQL", "^HeidiSQL_[\\d.]+_64_Portable\\.zip$"), exe: "heidisql.exe" },
|
|
25482
|
+
{ id: "sqlitebrowser", name: "DB Browser for SQLite", category: "databases", about: "Open, browse and edit SQLite files.", size: "21 MB", source: gh("sqlitebrowser/sqlitebrowser", "^DB\\.Browser\\.for\\.SQLite-v?[\\d.]+-win64\\.zip$"), exe: "DB Browser for SQLite.exe" },
|
|
25483
|
+
{ id: "compass", name: "MongoDB Compass", category: "databases", about: "The MongoDB GUI.", size: "220 MB", source: gh("mongodb-js/compass", "^mongodb-compass-[\\d.]+-win32-x64\\.zip$"), exe: "MongoDBCompass.exe" },
|
|
25484
|
+
{ id: "redisinsight", name: "Redis Insight", category: "databases", about: "The Redis GUI.", size: "110 MB", source: gh("redis/RedisInsight", "^Redis-Insight-win-installer\\.exe$"), unpack: "nsis", exe: "Redis Insight.exe", needs: ["7zip"] },
|
|
25485
|
+
{ id: "dbgate", name: "DbGate", category: "databases", about: "Database manager for SQL and NoSQL databases.", size: "180 MB", source: gh("dbgate/dbgate", "^dbgate-[\\d.]+-win_x64\\.zip$"), exe: "DbGate.exe" },
|
|
25486
|
+
{ id: "beekeeper", name: "Beekeeper Studio", category: "databases", about: "SQL editor and database manager.", size: "245 MB", source: gh("beekeeper-studio/beekeeper-studio", "^Beekeeper-Studio-[\\d.]+-portable\\.exe$"), unpack: "nsis", exe: "Beekeeper Studio.exe", needs: ["7zip"] },
|
|
25487
|
+
{ id: "dynamodb-admin", name: "dynamodb-admin", category: "databases", about: "Web GUI for DynamoDB Local: run dynamodb-admin, then open http://localhost:8001.", size: "5 MB", source: { npm: "dynamodb-admin" }, exe: "dynamodb-admin.cmd", cli: true },
|
|
25488
|
+
// ---- API clients
|
|
25489
|
+
{ id: "bruno", name: "Bruno", category: "api", about: "Offline, git-friendly API client (collections are files in your repo).", size: "175 MB", source: gh("usebruno/bruno", "^bruno_[\\d.]+_x64_win\\.zip$"), exe: "Bruno.exe" },
|
|
25490
|
+
{ id: "insomnia", name: "Insomnia", category: "api", about: "REST, GraphQL and gRPC client.", size: "590 MB", source: gh("Kong/insomnia", "^insomnia-[\\d.]+-full\\.nupkg$"), exe: "Insomnia.exe" },
|
|
25491
|
+
// ---- git
|
|
25492
|
+
{ id: "sourcegit", name: "SourceGit", category: "git", about: "Fast open-source Git GUI.", size: "26 MB", source: gh("sourcegit-scm/sourcegit", "^sourcegit_[\\d.]+\\.win-x64\\.zip$"), exe: "SourceGit.exe" },
|
|
25493
|
+
{ id: "githubdesktop", name: "GitHub Desktop", category: "git", about: 'Simple Git GUI from GitHub. It has its own git, so it needs provisioning.git.access "full".', size: "300 MB", source: gh("desktop/desktop", "^GitHubDesktop-[\\d.]+-x64-full\\.nupkg$"), exe: "GitHubDesktop.exe", fullGitOnly: true },
|
|
25494
|
+
{ id: "lazygit", name: "lazygit", category: "git", about: "Git in the terminal.", size: "7 MB", source: gh("jesseduffield/lazygit", "^lazygit_[\\d.]+_windows_x86_64\\.zip$"), exe: "lazygit.exe", cli: true },
|
|
25495
|
+
// ---- utilities
|
|
25496
|
+
{ id: "7zip", name: "7-Zip", category: "utilities", about: "Archive manager (7z, zip, rar, tar ...). Also unpacks installers for other apps.", size: "2 MB", source: { resolve: "7zip" }, exe: "7zFM.exe" },
|
|
25497
|
+
{ id: "winmerge", name: "WinMerge", category: "utilities", about: "Compare and merge files and folders.", size: "23 MB", source: gh("WinMerge/winmerge", "^winmerge-[\\d.]+-x64-exe\\.zip$"), exe: "WinMergeU.exe" },
|
|
25498
|
+
{ id: "everything", name: "Everything", category: "utilities", about: "Finds files by name instantly.", size: "2 MB", source: { resolve: "everything" }, exe: "Everything.exe" },
|
|
25499
|
+
{ id: "sysinternals", name: "Sysinternals Suite", category: "utilities", about: "Process Explorer, Process Monitor, Autoruns, TCPView and more (on PATH).", size: "200 MB", source: { url: "https://download.sysinternals.com/files/SysinternalsSuite.zip" }, exe: "procexp64.exe" },
|
|
25500
|
+
{ id: "imhex", name: "ImHex", category: "utilities", about: "Hex editor for reverse engineering and binary formats.", size: "80 MB", source: gh("WerWolv/ImHex", "^imhex-[\\d.]+-Windows-Portable-NoGPU-x86_64\\.zip$"), exe: "imhex-gui.exe" },
|
|
25501
|
+
// ---- browsers
|
|
25502
|
+
{ id: "chrome", name: "Chrome for Testing", category: "browsers", about: "Chrome build made for automated tests (with chromedriver on PATH).", size: "170 MB", source: { resolve: "chrome" }, exe: "chrome.exe" },
|
|
25503
|
+
{ id: "firefox", name: "Firefox", category: "browsers", about: "Firefox for testing.", size: "75 MB", source: { resolve: "firefox" }, unpack: "nsis", exe: "firefox.exe", needs: ["7zip"] },
|
|
25504
|
+
// ---- game development
|
|
25505
|
+
{ id: "godot", name: "Godot", category: "gamedev", about: "Open-source 2D and 3D game engine.", size: "80 MB", source: gh("godotengine/godot", "^Godot_v[\\d.]+-stable_win64\\.exe\\.zip$"), exe: "/^Godot_v[\\d.]+-stable_win64\\.exe$/", needs: ["mesa"] },
|
|
25506
|
+
{ id: "blender", name: "Blender", category: "gamedev", about: "3D modelling, animation and rendering.", size: "400 MB", source: { resolve: "blender" }, exe: "blender.exe", needs: ["mesa"] },
|
|
25507
|
+
{ id: "love", name: "L\xD6VE", category: "gamedev", about: "Lua framework for 2D games.", size: "4 MB", source: gh("love2d/love", "^love-[\\d.]+-win64\\.zip$"), exe: "love.exe", needs: ["mesa"] },
|
|
25508
|
+
{ id: "defold", name: "Defold", category: "gamedev", about: "Free 2D/3D game engine and editor.", size: "330 MB", source: gh("defold/defold", "^Defold-x86_64-win32\\.zip$"), exe: "Defold.exe", needs: ["mesa"] },
|
|
25509
|
+
{ id: "pixelorama", name: "Pixelorama", category: "gamedev", about: "Pixel-art and sprite editor.", size: "40 MB", source: gh("Orama-Interactive/Pixelorama", "^Pixelorama-Windows-64bit\\.zip$"), exe: "Pixelorama.exe", needs: ["mesa"] },
|
|
25510
|
+
{ id: "tiled", name: "Tiled", category: "gamedev", about: "Tile map editor.", size: "22 MB", source: gh("mapeditor/tiled", "^Tiled-[\\d.]+_Windows-10\\+_x86_64\\.msi$"), unpack: "msi", exe: "tiled.exe" },
|
|
25511
|
+
// ---- cloud
|
|
25512
|
+
{ id: "kubectl", name: "kubectl", category: "cloud", about: "Kubernetes command line.", size: "60 MB", source: { resolve: "kubectl" }, unpack: "file", exe: "kubectl.exe", cli: true },
|
|
25513
|
+
{ id: "helm", name: "Helm", category: "cloud", about: "Kubernetes package manager.", size: "20 MB", source: { resolve: "helm" }, exe: "helm.exe", cli: true },
|
|
25514
|
+
{ id: "k9s", name: "k9s", category: "cloud", about: "Kubernetes cluster UI in the terminal.", size: "40 MB", source: gh("derailed/k9s", "^k9s_Windows_amd64\\.zip$"), exe: "k9s.exe", cli: true },
|
|
25515
|
+
{ id: "terraform", name: "Terraform", category: "cloud", about: "Infrastructure as code.", size: "30 MB", source: { resolve: "terraform" }, exe: "terraform.exe", cli: true },
|
|
25516
|
+
{ id: "azure-cli", name: "Azure CLI", category: "cloud", about: "Manage Azure (az).", size: "90 MB", source: { url: "https://aka.ms/installazurecliwindowszipx64" }, exe: "az.cmd", cli: true },
|
|
25517
|
+
{ id: "gcloud", name: "Google Cloud CLI", category: "cloud", about: "Manage Google Cloud (gcloud, gsutil, bq).", size: "120 MB", source: { url: "https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/google-cloud-cli-windows-x86_64-bundled-python.zip" }, exe: "gcloud.cmd", cli: true },
|
|
25518
|
+
{ id: "aws-cli", name: "AWS CLI", category: "cloud", about: "Manage AWS (aws).", size: "50 MB", source: { url: "https://awscli.amazonaws.com/AWSCLIV2.msi" }, unpack: "msi", exe: "aws.exe", cli: true },
|
|
25519
|
+
// ---- diagrams and docs
|
|
25520
|
+
{ id: "drawio", name: "draw.io", category: "diagrams", about: "Diagram editor (flowcharts, architecture, UML).", size: "170 MB", source: gh("jgraph/drawio-desktop", "^draw\\.io-[\\d.]+-windows\\.zip$"), exe: "draw.io.exe" },
|
|
25521
|
+
{ id: "pandoc", name: "Pandoc", category: "diagrams", about: "Convert documents between Markdown, HTML, Word, PDF ...", size: "35 MB", source: gh("jgm/pandoc", "^pandoc-[\\d.]+-windows-x86_64\\.zip$"), exe: "pandoc.exe", cli: true },
|
|
25522
|
+
// ---- network
|
|
25523
|
+
{ id: "mitmproxy", name: "mitmproxy", category: "network", about: "Intercepting HTTPS proxy (mitmweb opens a web UI).", size: "90 MB", source: { resolve: "mitmproxy" }, exe: "mitmweb.exe", cli: true },
|
|
25524
|
+
{ id: "xh", name: "xh", category: "network", about: "Friendly HTTP requests from the terminal (like HTTPie).", size: "5 MB", source: gh("ducaale/xh", "^xh-v[\\d.]+-x86_64-pc-windows-msvc\\.zip$"), exe: "xh.exe", cli: true },
|
|
25525
|
+
{ id: "grpcurl", name: "grpcurl", category: "network", about: "curl for gRPC servers.", size: "10 MB", source: gh("fullstorydev/grpcurl", "^grpcurl_[\\d.]+_windows_x86_64\\.zip$"), exe: "grpcurl.exe", cli: true },
|
|
25526
|
+
{ id: "k6", name: "k6", category: "network", about: "Load testing with JavaScript scripts.", size: "30 MB", source: gh("grafana/k6", "^k6-v[\\d.]+-windows-amd64\\.zip$"), exe: "k6.exe", cli: true },
|
|
25527
|
+
// ---- command-line tools
|
|
25528
|
+
{ id: "jq", name: "jq", category: "cli", about: "Query and reshape JSON.", size: "1 MB", source: gh("jqlang/jq", "^jq-windows-amd64\\.exe$"), unpack: "file", exe: "jq.exe", cli: true },
|
|
25529
|
+
{ id: "yq", name: "yq", category: "cli", about: "Query and edit YAML, JSON, XML and TOML.", size: "10 MB", source: gh("mikefarah/yq", "^yq_windows_amd64\\.exe$"), unpack: "file", exe: "yq.exe", cli: true },
|
|
25530
|
+
{ id: "ripgrep", name: "ripgrep", category: "cli", about: "Very fast recursive search (rg).", size: "2 MB", source: gh("BurntSushi/ripgrep", "^ripgrep-[\\d.]+-x86_64-pc-windows-msvc\\.zip$"), exe: "rg.exe", cli: true },
|
|
25531
|
+
{ id: "fd", name: "fd", category: "cli", about: "Fast, friendly alternative to find.", size: "2 MB", source: gh("sharkdp/fd", "^fd-v[\\d.]+-x86_64-pc-windows-msvc\\.zip$"), exe: "fd.exe", cli: true },
|
|
25532
|
+
{ id: "bat", name: "bat", category: "cli", about: "cat with syntax highlighting and git changes.", size: "3 MB", source: gh("sharkdp/bat", "^bat-v[\\d.]+-x86_64-pc-windows-msvc\\.zip$"), exe: "bat.exe", cli: true },
|
|
25533
|
+
{ id: "fzf", name: "fzf", category: "cli", about: "Fuzzy finder for the terminal.", size: "2 MB", source: gh("junegunn/fzf", "^fzf-[\\d.]+-windows_amd64\\.zip$"), exe: "fzf.exe", cli: true },
|
|
25534
|
+
{ id: "delta", name: "delta", category: "cli", about: "Readable git diffs with syntax highlighting.", size: "3 MB", source: gh("dandavison/delta", "^delta-[\\d.]+-x86_64-pc-windows-msvc\\.zip$"), exe: "delta.exe", cli: true },
|
|
25535
|
+
{ id: "just", name: "just", category: "cli", about: "Command runner (a simpler make for project tasks).", size: "2 MB", source: gh("casey/just", "^just-[\\d.]+-x86_64-pc-windows-msvc\\.zip$"), exe: "just.exe", cli: true },
|
|
25536
|
+
{ id: "hyperfine", name: "hyperfine", category: "cli", about: "Benchmark commands.", size: "1 MB", source: gh("sharkdp/hyperfine", "^hyperfine-v[\\d.]+-x86_64-pc-windows-msvc\\.zip$"), exe: "hyperfine.exe", cli: true },
|
|
25537
|
+
{ id: "watchexec", name: "watchexec", category: "cli", about: "Run a command when files change.", size: "5 MB", source: gh("watchexec/watchexec", "^watchexec-[\\d.]+-x86_64-pc-windows-msvc\\.zip$"), exe: "watchexec.exe", cli: true },
|
|
25538
|
+
{ id: "protoc", name: "protoc", category: "cli", about: "Protocol Buffers compiler.", size: "3 MB", source: gh("protocolbuffers/protobuf", "^protoc-[\\d.]+-win64\\.zip$"), exe: "protoc.exe", cli: true },
|
|
25539
|
+
{ id: "ninja", name: "Ninja", category: "cli", about: "Small, fast build system (CMake's favourite generator).", size: "1 MB", source: gh("ninja-build/ninja", "^ninja-win\\.zip$"), exe: "ninja.exe", cli: true },
|
|
25540
|
+
{ id: "ffmpeg", name: "FFmpeg", category: "cli", about: "Convert and process audio and video.", size: "200 MB", source: gh("BtbN/FFmpeg-Builds", "^ffmpeg-master-latest-win64-gpl\\.zip$"), exe: "ffmpeg.exe", cli: true },
|
|
25541
|
+
{ id: "sqlite", name: "SQLite tools", category: "cli", about: "sqlite3 command-line shell.", size: "5 MB", source: { resolve: "sqlite" }, exe: "sqlite3.exe", cli: true },
|
|
25542
|
+
{ id: "shellcheck", name: "ShellCheck", category: "cli", about: "Finds bugs in shell scripts.", size: "10 MB", source: gh("koalaman/shellcheck", "^shellcheck-v[\\d.]+\\.zip$"), exe: "shellcheck.exe", cli: true },
|
|
25543
|
+
{ id: "gitleaks", name: "Gitleaks", category: "cli", about: "Finds secrets committed to git.", size: "8 MB", source: gh("gitleaks/gitleaks", "^gitleaks_[\\d.]+_windows_x64\\.zip$"), exe: "gitleaks.exe", cli: true }
|
|
25544
|
+
];
|
|
25545
|
+
var appById = (id) => APPS.find((a) => a.id === id);
|
|
25546
|
+
var exeMatcher = (exe) => {
|
|
25547
|
+
const regex = /^\/(.+)\/$/.exec(exe);
|
|
25548
|
+
if (regex) {
|
|
25549
|
+
const r = new RegExp(regex[1], "i");
|
|
25550
|
+
return (name) => r.test(name);
|
|
25551
|
+
}
|
|
25552
|
+
return (name) => name.toLowerCase() === exe.toLowerCase();
|
|
25553
|
+
};
|
|
25554
|
+
var customEntry = (id, app) => ({
|
|
25555
|
+
id: "custom/" + id,
|
|
25556
|
+
name: app.name,
|
|
25557
|
+
category: "utilities",
|
|
25558
|
+
about: "Your own program.",
|
|
25559
|
+
size: "?",
|
|
25560
|
+
source: app.github && app.asset ? { github: app.github, asset: app.asset } : { url: app.url },
|
|
25561
|
+
unpack: app.unpack,
|
|
25562
|
+
exe: app.exe,
|
|
25563
|
+
cli: app.cli
|
|
25564
|
+
});
|
|
25565
|
+
var appsToInstall = (apps, gitAccess) => {
|
|
25566
|
+
const chosen = apps.install.flatMap((id) => {
|
|
25567
|
+
const e = appById(id);
|
|
25568
|
+
return e && !e.setting ? [e] : [];
|
|
25569
|
+
});
|
|
25570
|
+
const skipped = chosen.filter((e) => e.fullGitOnly && gitAccess !== "full").map((e) => e.name + ' (needs provisioning.git.access "full")');
|
|
25571
|
+
const allowed = [...chosen.filter((e) => !(e.fullGitOnly && gitAccess !== "full")), ...Object.entries(apps.custom).map(([id, app]) => customEntry(id, app))];
|
|
25572
|
+
const needs7zip = allowed.some((e) => e.needs?.includes("7zip") || e.unpack === "nsis") && !allowed.some((e) => e.id === "7zip");
|
|
25573
|
+
return { entries: [...needs7zip ? [appById("7zip")] : [], ...allowed], skipped };
|
|
25574
|
+
};
|
|
25575
|
+
var appsNeedMesa = (apps) => Boolean(apps?.install.some((id) => appById(id)?.needs?.includes("mesa")));
|
|
25576
|
+
|
|
25577
|
+
// src/core/schema/apps.ts
|
|
25578
|
+
var CATALOGUE_IDS = APPS.filter((a) => !a.setting).map((a) => a.id);
|
|
25579
|
+
var AppId = external_exports.enum(CATALOGUE_IDS);
|
|
25580
|
+
var CustomAppId = external_exports.string().regex(/^[a-z0-9][a-z0-9-]{0,40}$/, "lower-case letters, digits and - only");
|
|
25581
|
+
var compiles = (pattern) => {
|
|
25582
|
+
try {
|
|
25583
|
+
new RegExp(pattern);
|
|
25584
|
+
return true;
|
|
25585
|
+
} catch {
|
|
25586
|
+
return false;
|
|
25587
|
+
}
|
|
25588
|
+
};
|
|
25589
|
+
var CustomApp = external_exports.strictObject({
|
|
25590
|
+
name: external_exports.string().min(1).max(80).describe('The name on the desktop shortcut, e.g. "My Tool".'),
|
|
25591
|
+
github: external_exports.string().regex(/^[\w.-]+\/[\w.-]+$/, "owner/repo, e.g. sharkdp/bat").optional().describe("GitHub repository (owner/repo): the file comes from its latest release."),
|
|
25592
|
+
asset: external_exports.string().max(200).refine(compiles, "not a valid pattern").optional().describe("With github: a pattern (regular expression) matching the release file, e.g. windows.*x64\\.zip$"),
|
|
25593
|
+
url: external_exports.string().url().startsWith("https://", "https:// only").optional().describe("Or a direct https:// download link (zip, 7z, exe or msi)."),
|
|
25594
|
+
sha256: external_exports.string().regex(/^[0-9a-fA-F]{64}$/, "64 hex characters").optional().describe("SHA-256 of the download (GitHub releases usually publish one; then this is not needed)."),
|
|
25595
|
+
unpack: external_exports.enum(["archive", "file", "nsis", "msi"]).optional().describe("archive (zip, 7z, tar: the default), file (a single .exe), nsis (an installer 7-Zip can open) or msi."),
|
|
25596
|
+
exe: external_exports.string().min(1).max(200).describe("The program to start (found anywhere in the download), e.g. mytool.exe."),
|
|
25597
|
+
cli: external_exports.boolean().optional().describe("A command-line tool: its folder goes on PATH instead of getting a desktop shortcut.")
|
|
25598
|
+
}).refine((a) => a.github && a.asset ? !a.url : Boolean(a.url) && !a.github && !a.asset, { message: "give github + asset, or url (not both)" });
|
|
25599
|
+
var Apps = external_exports.strictObject({
|
|
25600
|
+
install: external_exports.array(AppId).describe("Apps from the catalogue to install in every sandbox (the Apps screen in the menu lists them by category). Each is downloaded once and kept."),
|
|
25601
|
+
custom: external_exports.record(CustomAppId, CustomApp).describe("Programs of your own: a GitHub release or a download link, and the program to start. Installed like the catalogue apps.")
|
|
25602
|
+
});
|
|
25603
|
+
|
|
25434
25604
|
// src/core/schema/projects.ts
|
|
25435
25605
|
var Projects = external_exports.strictObject({
|
|
25436
25606
|
all: external_exports.boolean().describe("Map every project you have started before (and every folder in your roots) at every start, except those in exclude, so all of them open in the running sandbox without a restart. Every agent in the sandbox can then see all of them. Each one is still only set up when you first use it."),
|
|
@@ -25447,14 +25617,18 @@ var Config = external_exports.strictObject({
|
|
|
25447
25617
|
defaultHarness: Name.describe("Agent started by `sandbox launch` (sandbox claude always runs claude)."),
|
|
25448
25618
|
guestWorkspace: GuestWorkspace,
|
|
25449
25619
|
readOnly: external_exports.boolean().describe("Map the workspace read-only."),
|
|
25620
|
+
workspaceFilter: WorkspaceFilter,
|
|
25621
|
+
audit: Audit,
|
|
25450
25622
|
mappings: external_exports.array(Mapping).describe("Extra folders from this PC."),
|
|
25451
25623
|
sandbox: Sandbox,
|
|
25452
25624
|
storage: external_exports.strictObject({
|
|
25453
25625
|
root: external_exports.string().min(1).describe("Where everything is kept on this PC (tools, databases, logins, launches)."),
|
|
25454
25626
|
persistAgentState: external_exports.boolean().describe("Keep agent logins and history between sandboxes."),
|
|
25455
|
-
dataName: Name.describe("Name of the persistent data set (C:\\AgentData) shared by all workspaces.")
|
|
25627
|
+
dataName: Name.describe("Name of the persistent data set (C:\\AgentData) shared by all workspaces."),
|
|
25628
|
+
markSandboxFiles: external_exports.boolean().describe(`Programs and scripts (.exe, .ps1, .bat, .cmd, .msi, .lnk ...) that appear or change in your project while a sandbox runs get Windows' "downloaded from the internet" mark, so SmartScreen and PowerShell ask before they run on this PC.`),
|
|
25629
|
+
warnDataGb: external_exports.number().min(0).describe("Say at launch when the persisted data (tools, databases, logins) is bigger than this many GB; 0 = never. sandbox data shows what takes the space.")
|
|
25456
25630
|
}),
|
|
25457
|
-
network:
|
|
25631
|
+
network: Network,
|
|
25458
25632
|
provisioning: Provisioning,
|
|
25459
25633
|
downloads: Downloads,
|
|
25460
25634
|
toolchains: Toolchains,
|
|
@@ -25463,6 +25637,7 @@ var Config = external_exports.strictObject({
|
|
|
25463
25637
|
agentCommands: AgentCommands,
|
|
25464
25638
|
secrets: Secrets,
|
|
25465
25639
|
personalization: toggle("Copy your desktop look (theme, accent, taskbar, wallpaper, ...) into the sandbox."),
|
|
25640
|
+
apps: Apps,
|
|
25466
25641
|
claudeProfile: ClaudeProfile,
|
|
25467
25642
|
harnesses: external_exports.record(Name, Harness).describe("Agents that can run in the sandbox."),
|
|
25468
25643
|
hooks: external_exports.strictObject({ failFast: external_exports.boolean().describe("Stop when a hook script fails.") }),
|
|
@@ -25473,10 +25648,14 @@ var LocalOverrides = external_exports.strictObject({
|
|
|
25473
25648
|
harness: Name.describe("Agent for this project."),
|
|
25474
25649
|
guestWorkspace: GuestWorkspace,
|
|
25475
25650
|
readOnly: external_exports.boolean().describe("Map this project read-only."),
|
|
25476
|
-
|
|
25651
|
+
// A project may turn the filter on and keep more out, never let ignored files in.
|
|
25652
|
+
workspaceFilter: WorkspaceFilter.pick({ enabled: true, exclude: true }).partial(),
|
|
25653
|
+
mappings: external_exports.array(Mapping).describe("Extra folders inside this project (relative to this file), e.g. a read-only data folder at another place in the sandbox."),
|
|
25477
25654
|
scripts: Strings.describe("Scripts (.ps1 / .mjs / .cmd, relative to this file) run inside the sandbox before the agent."),
|
|
25478
|
-
|
|
25479
|
-
|
|
25655
|
+
// This PC's resources are yours to share: CPU and paging file (this PC's disk) are not a project's to set.
|
|
25656
|
+
sandbox: Sandbox.omit({ cpuLimit: true, pageFileMb: true }).partial(),
|
|
25657
|
+
// A project may block more (the LAN, hosts); it never opens hosts, ports, DNS or a proxy.
|
|
25658
|
+
network: Network.pick({ blockPrivateRanges: true, blockHosts: true }).partial(),
|
|
25480
25659
|
provisioning: Provisioning.pick({ copyFromHost: true, fallbackToInstall: true, refresh: true }).extend({ git: Git.partial(), terminal: toggle("Windows Terminal as the sandbox window.").partial() }).partial(),
|
|
25481
25660
|
downloads: Downloads.partial(),
|
|
25482
25661
|
// Every toolchain setting, each one optional (a project usually only switches languages on or pins a version).
|
|
@@ -25487,7 +25666,9 @@ var LocalOverrides = external_exports.strictObject({
|
|
|
25487
25666
|
databases: external_exports.strictObject(import_lodash.default.mapValues(Databases.shape, (shape) => shape.partial())).partial(),
|
|
25488
25667
|
attach: Attach.partial(),
|
|
25489
25668
|
personalization: toggle("Copy your desktop look into the sandbox.").partial(),
|
|
25490
|
-
|
|
25669
|
+
// Catalogue apps only (a vetted list): your own programs (apps.custom) download anything, so a repo cannot add them.
|
|
25670
|
+
apps: Apps.pick({ install: true }).partial(),
|
|
25671
|
+
claudeProfile: ClaudeProfile.pick({ enabled: true, overwrite: true, copyCredentials: true, syncHistory: true, syncClaudeMem: true }).partial(),
|
|
25491
25672
|
hooks: external_exports.strictObject({ failFast: external_exports.boolean() }).partial()
|
|
25492
25673
|
}).partial();
|
|
25493
25674
|
|
|
@@ -25507,7 +25688,9 @@ var SandboxStatus = external_exports.object({
|
|
|
25507
25688
|
updatedAt: Time,
|
|
25508
25689
|
workspaceHost: Text(),
|
|
25509
25690
|
guestWorkspace: Text(),
|
|
25510
|
-
headless: external_exports.boolean()
|
|
25691
|
+
headless: external_exports.boolean(),
|
|
25692
|
+
/** The sandbox's IPv4 addresses (for network.forwardPorts; the host only uses ones on its Hyper-V network). */
|
|
25693
|
+
addresses: external_exports.array(external_exports.string().max(45)).max(8).optional()
|
|
25511
25694
|
});
|
|
25512
25695
|
var Version = external_exports.strictObject({ spec: Text(128), source: Text(256) });
|
|
25513
25696
|
var DatabasePlan = external_exports.strictObject({
|
|
@@ -25615,6 +25798,8 @@ var runPaths = (dataDir2) => {
|
|
|
25615
25798
|
responses: path2.join(run2, "responses"),
|
|
25616
25799
|
sessions: path2.join(run2, "sessions"),
|
|
25617
25800
|
projects: path2.join(run2, "projects"),
|
|
25801
|
+
/** audit.processes: programs the sandbox started, in small .jsonl files the host takes in and deletes. */
|
|
25802
|
+
audit: path2.join(run2, "audit"),
|
|
25618
25803
|
request: file3("requests"),
|
|
25619
25804
|
response: file3("responses"),
|
|
25620
25805
|
session: file3("sessions"),
|
|
@@ -25674,7 +25859,7 @@ var now = () => (/* @__PURE__ */ new Date()).toISOString();
|
|
|
25674
25859
|
|
|
25675
25860
|
// src/guest/setup/claude.ts
|
|
25676
25861
|
import fs6 from "node:fs";
|
|
25677
|
-
import
|
|
25862
|
+
import os4 from "node:os";
|
|
25678
25863
|
import path7 from "node:path";
|
|
25679
25864
|
|
|
25680
25865
|
// src/shared/safe-remove.ts
|
|
@@ -25738,6 +25923,7 @@ var safeRemove = (target, root) => {
|
|
|
25738
25923
|
|
|
25739
25924
|
// src/guest/env.ts
|
|
25740
25925
|
import fs5 from "node:fs";
|
|
25926
|
+
import os3 from "node:os";
|
|
25741
25927
|
import path6 from "node:path";
|
|
25742
25928
|
import { spawnSync } from "node:child_process";
|
|
25743
25929
|
|
|
@@ -25765,7 +25951,8 @@ var SYSTEM = {
|
|
|
25765
25951
|
ipconfig: () => system32("ipconfig.exe"),
|
|
25766
25952
|
robocopy: () => system32("Robocopy.exe"),
|
|
25767
25953
|
shutdown: () => system32("shutdown.exe"),
|
|
25768
|
-
dism: () => system32("Dism.exe")
|
|
25954
|
+
dism: () => system32("Dism.exe"),
|
|
25955
|
+
msiexec: () => system32("msiexec.exe")
|
|
25769
25956
|
};
|
|
25770
25957
|
|
|
25771
25958
|
// src/shared/download.ts
|
|
@@ -25823,10 +26010,10 @@ var download = async (url2, destination, expected = null) => {
|
|
|
25823
26010
|
fs4.rmSync(partial2, { force: true });
|
|
25824
26011
|
}
|
|
25825
26012
|
};
|
|
25826
|
-
var spawnAsync = (file3, args, options = {}) => new Promise((
|
|
26013
|
+
var spawnAsync = (file3, args, options = {}) => new Promise((resolve2, reject) => {
|
|
25827
26014
|
const child = spawn(file3, args, { stdio: "ignore", windowsHide: true, ...options });
|
|
25828
26015
|
child.once("error", reject);
|
|
25829
|
-
child.once("close", (code) =>
|
|
26016
|
+
child.once("close", (code) => resolve2(code ?? -1));
|
|
25830
26017
|
});
|
|
25831
26018
|
var toAsset = (asset) => ({ url: asset.browser_download_url, name: asset.name, sha256: asset.digest?.startsWith("sha256:") ? asset.digest.slice(7) : null });
|
|
25832
26019
|
var githubAsset = async (repo, pattern, searchOlder = false) => {
|
|
@@ -25965,8 +26152,9 @@ var setSandboxStatus = (phase, message) => {
|
|
|
25965
26152
|
warn("Could not update sandbox status: " + errMsg(e));
|
|
25966
26153
|
}
|
|
25967
26154
|
};
|
|
26155
|
+
var ownAddresses = () => Object.values(os3.networkInterfaces()).flat().filter((i) => Boolean(i) && i.family === "IPv4" && !i.internal).map((i) => i.address).slice(0, 8);
|
|
25968
26156
|
var writeJsonAtomicChecked = (phase, message) => {
|
|
25969
|
-
writeJsonAtomic(run.sandbox, { launchId: session.launchId, phase, message, updatedAt: now(), workspaceHost: session.workspaceHost, guestWorkspace: workspace, headless: session.headless });
|
|
26157
|
+
writeJsonAtomic(run.sandbox, { launchId: session.launchId, phase, message, updatedAt: now(), workspaceHost: session.workspaceHost, guestWorkspace: workspace, headless: session.headless, addresses: ownAddresses() });
|
|
25970
26158
|
};
|
|
25971
26159
|
var exec = (file3, args, options = {}) => {
|
|
25972
26160
|
const result = spawnSync(file3, args, { stdio: "inherit", windowsHide: true, ...options });
|
|
@@ -26008,7 +26196,7 @@ var copyNode = (from, to) => {
|
|
|
26008
26196
|
};
|
|
26009
26197
|
|
|
26010
26198
|
// src/guest/setup/claude.ts
|
|
26011
|
-
var claudeMemPaths = { store: path7.join(stateDir, "claude-mem"), local: path7.join(
|
|
26199
|
+
var claudeMemPaths = { store: path7.join(stateDir, "claude-mem"), local: path7.join(os4.homedir(), ".claude-mem") };
|
|
26012
26200
|
var claudeMemEnabled = () => session.claudeProfile.syncClaudeMem && !dryRun;
|
|
26013
26201
|
var databaseFingerprint = (dir) => {
|
|
26014
26202
|
const parts = [];
|
|
@@ -26026,11 +26214,39 @@ var databaseFingerprint = (dir) => {
|
|
|
26026
26214
|
return parts.sort().join("|");
|
|
26027
26215
|
};
|
|
26028
26216
|
var lastSaved = null;
|
|
26217
|
+
var SQLITE_HEADER = "SQLite format 3\0";
|
|
26218
|
+
var looksLikeSqlite = (file3) => {
|
|
26219
|
+
if (!exists(file3)) return true;
|
|
26220
|
+
const fd = fs6.openSync(file3, "r");
|
|
26221
|
+
try {
|
|
26222
|
+
const head = Buffer.alloc(16);
|
|
26223
|
+
return fs6.readSync(fd, head, 0, 16, 0) === 16 && head.toString("latin1") === SQLITE_HEADER;
|
|
26224
|
+
} finally {
|
|
26225
|
+
fs6.closeSync(fd);
|
|
26226
|
+
}
|
|
26227
|
+
};
|
|
26228
|
+
var MAX_BACKUPS = 3;
|
|
26229
|
+
var BACKUP_EVERY_MS = 6 * 3600 * 1e3;
|
|
26230
|
+
var keepBackup = (previous, dir) => {
|
|
26231
|
+
if (!exists(previous)) return;
|
|
26232
|
+
const backups = exists(dir) ? fs6.readdirSync(dir).filter((n) => /^\d{13}$/.test(n)).sort() : [];
|
|
26233
|
+
const newest = Number(backups[backups.length - 1] ?? 0);
|
|
26234
|
+
if (Date.now() - newest < BACKUP_EVERY_MS) {
|
|
26235
|
+
fs6.rmSync(previous, { recursive: true, force: true });
|
|
26236
|
+
return;
|
|
26237
|
+
}
|
|
26238
|
+
fs6.renameSync(previous, path7.join(mkdirp(dir), String(Date.now())));
|
|
26239
|
+
for (const old of [...backups, String(Date.now())].slice(0, -MAX_BACKUPS)) fs6.rmSync(path7.join(dir, old), { recursive: true, force: true });
|
|
26240
|
+
};
|
|
26029
26241
|
var saveClaudeMem = () => {
|
|
26030
26242
|
if (!claudeMemEnabled() || !exists(claudeMemPaths.local)) return;
|
|
26031
26243
|
const { store: store2, local } = claudeMemPaths;
|
|
26032
26244
|
const fingerprint = databaseFingerprint(local);
|
|
26033
26245
|
if (fingerprint === lastSaved && exists(store2)) return;
|
|
26246
|
+
if (!looksLikeSqlite(path7.join(local, "claude-mem.db"))) {
|
|
26247
|
+
warn("claude-mem: the local database does not look valid, so it was not saved over the stored copy (" + local + ").");
|
|
26248
|
+
return;
|
|
26249
|
+
}
|
|
26034
26250
|
const incoming = store2 + ".incoming";
|
|
26035
26251
|
const previous = store2 + ".previous";
|
|
26036
26252
|
fs6.rmSync(incoming, { recursive: true, force: true });
|
|
@@ -26043,7 +26259,7 @@ var saveClaudeMem = () => {
|
|
|
26043
26259
|
if (exists(previous)) fs6.renameSync(previous, store2);
|
|
26044
26260
|
throw e;
|
|
26045
26261
|
}
|
|
26046
|
-
|
|
26262
|
+
keepBackup(previous, store2 + ".backups");
|
|
26047
26263
|
lastSaved = fingerprint;
|
|
26048
26264
|
};
|
|
26049
26265
|
|
|
@@ -26051,8 +26267,8 @@ var saveClaudeMem = () => {
|
|
|
26051
26267
|
import { spawn as spawn5 } from "node:child_process";
|
|
26052
26268
|
|
|
26053
26269
|
// src/guest/daemon/project.ts
|
|
26054
|
-
import
|
|
26055
|
-
import
|
|
26270
|
+
import fs32 from "node:fs";
|
|
26271
|
+
import path45 from "node:path";
|
|
26056
26272
|
|
|
26057
26273
|
// src/shared/projects.ts
|
|
26058
26274
|
import path8 from "node:path";
|
|
@@ -26387,11 +26603,11 @@ var remembered = () => Object.fromEntries(Object.entries(readState(resolvedFile(
|
|
|
26387
26603
|
var FRESH_MS = 24 * 60 * 60 * 1e3;
|
|
26388
26604
|
var offline = false;
|
|
26389
26605
|
var networkError = (e) => /fetch failed|timed? ?out|aborted|ENOTFOUND|EAI_AGAIN|ECONN|ENETUNREACH|EHOSTUNREACH|HTTP 5\d\d|socket/i.test(errMsg(e) + " " + String(e?.cause ?? ""));
|
|
26390
|
-
var resolveCached = async (key,
|
|
26606
|
+
var resolveCached = async (key, resolve2) => {
|
|
26391
26607
|
const cached2 = remembered()[key];
|
|
26392
26608
|
if (cached2 && (offline || !session.provisioning.refresh && Date.now() - cached2.at < FRESH_MS)) return cached2.value;
|
|
26393
26609
|
try {
|
|
26394
|
-
const value = await
|
|
26610
|
+
const value = await resolve2();
|
|
26395
26611
|
fs10.mkdirSync(toolsDir, { recursive: true });
|
|
26396
26612
|
writeJsonAtomic(resolvedFile(), { ...remembered(), [key]: { value, at: Date.now() } });
|
|
26397
26613
|
return value;
|
|
@@ -26445,11 +26661,11 @@ var workspaceEntries = () => {
|
|
|
26445
26661
|
return found;
|
|
26446
26662
|
};
|
|
26447
26663
|
var wanted = (setting, toolchain) => setting === "auto" ? projectUses(workspaceEntries(), MARKERS[toolchain] ?? []) : setting;
|
|
26448
|
-
var versionFromFiles = (files,
|
|
26664
|
+
var versionFromFiles = (files, parse5 = (t) => specFromVersionFile(t)) => {
|
|
26449
26665
|
for (const name of files) {
|
|
26450
26666
|
const file3 = path14.join(projectWorkspace(), name);
|
|
26451
26667
|
if (!exists(file3)) continue;
|
|
26452
|
-
const spec =
|
|
26668
|
+
const spec = parse5(fs10.readFileSync(file3, "utf8"), name);
|
|
26453
26669
|
if (spec) return { spec, source: name };
|
|
26454
26670
|
}
|
|
26455
26671
|
return null;
|
|
@@ -26472,16 +26688,280 @@ var installOnce = async (env, group, packages, install) => {
|
|
|
26472
26688
|
};
|
|
26473
26689
|
|
|
26474
26690
|
// src/guest/toolchains/plan.ts
|
|
26475
|
-
import
|
|
26691
|
+
import fs31 from "node:fs";
|
|
26692
|
+
import os8 from "node:os";
|
|
26693
|
+
import path44 from "node:path";
|
|
26694
|
+
|
|
26695
|
+
// src/guest/apps/index.ts
|
|
26696
|
+
import fs11 from "node:fs";
|
|
26697
|
+
import os5 from "node:os";
|
|
26698
|
+
import path15 from "node:path";
|
|
26699
|
+
|
|
26700
|
+
// src/guest/apps/resolvers.ts
|
|
26701
|
+
var sumFor = (sums, file3) => sums.split(/\r?\n/).map((l) => /^([0-9a-f]{64})\s+\*?(.+)$/i.exec(l.trim())).find((m) => m && m[2].trim().endsWith(file3))?.[1].toLowerCase() ?? null;
|
|
26702
|
+
var firstHash = (text) => /\b([0-9a-f]{64})\b/i.exec(text)?.[1].toLowerCase() ?? null;
|
|
26703
|
+
var stripV = (tag) => tag.replace(/^v/, "");
|
|
26704
|
+
var RESOLVERS = {
|
|
26705
|
+
sublime: async () => {
|
|
26706
|
+
const { latest_version: build } = await fetchJson("https://www.sublimetext.com/updates/4/stable_update_check");
|
|
26707
|
+
return { url: "https://download.sublimetext.com/sublime_text_build_" + build + "_x64.zip", fileName: "sublime_text_" + build + ".zip" };
|
|
26708
|
+
},
|
|
26709
|
+
pgadmin: async () => {
|
|
26710
|
+
const versions = (await fetchJson("https://www.postgresql.org/versions.json")).filter((v) => v.supported);
|
|
26711
|
+
const current = versions.find((v) => v.current) ?? versions[versions.length - 1];
|
|
26712
|
+
const exact = current.major + "." + current.latestMinor;
|
|
26713
|
+
return { url: "https://get.enterprisedb.com/postgresql/postgresql-" + exact + "-1-windows-x64-binaries.zip", fileName: "postgresql-" + exact + ".zip", members: ["pgsql/pgAdmin 4"] };
|
|
26714
|
+
},
|
|
26715
|
+
everything: async () => {
|
|
26716
|
+
const page = await fetchText("https://www.voidtools.com/downloads/");
|
|
26717
|
+
const version2 = /Everything-([\d.]+)\.x64\.zip/.exec(page)?.[1];
|
|
26718
|
+
if (!version2) throw new Error("could not find the Everything download on voidtools.com");
|
|
26719
|
+
const file3 = "Everything-" + version2 + ".x64.zip";
|
|
26720
|
+
const sums = await fetchText("https://www.voidtools.com/Everything-" + version2 + ".sha256").catch(() => "");
|
|
26721
|
+
return { url: "https://www.voidtools.com/" + file3, fileName: file3, sha256: sumFor(sums, file3) };
|
|
26722
|
+
},
|
|
26723
|
+
chrome: async () => {
|
|
26724
|
+
const data = await fetchJson("https://googlechromelabs.github.io/chrome-for-testing/last-known-good-versions-with-downloads.json");
|
|
26725
|
+
const hit = data.channels.Stable.downloads.chrome.find((d) => d.platform === "win64");
|
|
26726
|
+
if (!hit) throw new Error("no win64 Chrome for Testing build listed");
|
|
26727
|
+
return { url: hit.url, fileName: "chrome-win64.zip" };
|
|
26728
|
+
},
|
|
26729
|
+
firefox: async () => {
|
|
26730
|
+
const { LATEST_FIREFOX_VERSION: v } = await fetchJson("https://product-details.mozilla.org/1.0/firefox_versions.json");
|
|
26731
|
+
const base = "https://archive.mozilla.org/pub/firefox/releases/" + v + "/";
|
|
26732
|
+
const sums = await fetchText(base + "SHA256SUMS");
|
|
26733
|
+
return { url: base + "win64/en-US/Firefox%20Setup%20" + v + ".exe", fileName: "firefox-setup-" + v + ".exe", sha256: sumFor(sums, "win64/en-US/Firefox Setup " + v + ".exe") };
|
|
26734
|
+
},
|
|
26735
|
+
blender: async () => {
|
|
26736
|
+
const releases = await fetchText("https://download.blender.org/release/");
|
|
26737
|
+
const series = [...releases.matchAll(/href="Blender(\d+)\.(\d+)\/"/g)].map((m) => [Number(m[1]), Number(m[2])]).sort((a, b) => a[0] - b[0] || a[1] - b[1]).pop();
|
|
26738
|
+
if (!series) throw new Error("could not list Blender releases");
|
|
26739
|
+
const folder = "https://download.blender.org/release/Blender" + series[0] + "." + series[1] + "/";
|
|
26740
|
+
const listing = await fetchText(folder);
|
|
26741
|
+
const files = [...listing.matchAll(/href="(blender-([\d.]+)-windows-x64\.zip)"/g)].map((m) => ({ file: m[1], v: m[2].split(".").map(Number) }));
|
|
26742
|
+
const latest = files.sort((a, b) => a.v[2] - b.v[2]).pop();
|
|
26743
|
+
if (!latest) throw new Error("no Windows build in " + folder);
|
|
26744
|
+
const sums = await fetchText(folder + "blender-" + latest.v.join(".") + ".sha256").catch(() => "");
|
|
26745
|
+
return { url: folder + latest.file, fileName: latest.file, sha256: sumFor(sums, latest.file) };
|
|
26746
|
+
},
|
|
26747
|
+
kubectl: async () => {
|
|
26748
|
+
const v = (await fetchText("https://dl.k8s.io/release/stable.txt")).trim();
|
|
26749
|
+
const url2 = "https://dl.k8s.io/release/" + v + "/bin/windows/amd64/kubectl.exe";
|
|
26750
|
+
return { url: url2, fileName: "kubectl.exe", sha256: firstHash(await fetchText(url2 + ".sha256")) };
|
|
26751
|
+
},
|
|
26752
|
+
helm: async () => {
|
|
26753
|
+
const v = await latestGithubTag("helm/helm");
|
|
26754
|
+
const url2 = "https://get.helm.sh/helm-" + v + "-windows-amd64.zip";
|
|
26755
|
+
return { url: url2, fileName: "helm-" + v + ".zip", sha256: firstHash(await fetchText(url2 + ".sha256sum")) };
|
|
26756
|
+
},
|
|
26757
|
+
terraform: async () => {
|
|
26758
|
+
const { current_version: v } = await fetchJson("https://checkpoint-api.hashicorp.com/v1/check/terraform");
|
|
26759
|
+
const base = "https://releases.hashicorp.com/terraform/" + v + "/";
|
|
26760
|
+
const file3 = "terraform_" + v + "_windows_amd64.zip";
|
|
26761
|
+
return { url: base + file3, fileName: file3, sha256: sumFor(await fetchText(base + "terraform_" + v + "_SHA256SUMS"), file3) };
|
|
26762
|
+
},
|
|
26763
|
+
mitmproxy: async () => {
|
|
26764
|
+
const v = stripV(await latestGithubTag("mitmproxy/mitmproxy"));
|
|
26765
|
+
return { url: "https://downloads.mitmproxy.org/" + v + "/mitmproxy-" + v + "-windows-x86_64.zip", fileName: "mitmproxy-" + v + ".zip" };
|
|
26766
|
+
},
|
|
26767
|
+
sqlite: async () => {
|
|
26768
|
+
const page = await fetchText("https://sqlite.org/download.html");
|
|
26769
|
+
const file3 = /PRODUCT,[^,]+,(\d{4}\/sqlite-tools-win-x64-\d+\.zip),/.exec(page)?.[1];
|
|
26770
|
+
if (!file3) throw new Error("could not find the sqlite tools download on sqlite.org");
|
|
26771
|
+
return { url: "https://sqlite.org/" + file3, fileName: file3.split("/")[1] };
|
|
26772
|
+
},
|
|
26773
|
+
"7zip": async () => {
|
|
26774
|
+
const asset = await githubAsset("ip7z/7zip", /^7z\d+-x64\.exe$/);
|
|
26775
|
+
return { url: asset.url, fileName: asset.name, sha256: asset.sha256 };
|
|
26776
|
+
}
|
|
26777
|
+
};
|
|
26778
|
+
|
|
26779
|
+
// src/guest/apps/index.ts
|
|
26780
|
+
var MARKER = ".agent-sandbox-app";
|
|
26781
|
+
var PARALLEL = 3;
|
|
26782
|
+
var sevenZip = () => tool("apps", "7zip", "7z.exe");
|
|
26783
|
+
var resolve = async (entry) => {
|
|
26784
|
+
const s = entry.source;
|
|
26785
|
+
if ("github" in s) {
|
|
26786
|
+
const a = await githubAsset(s.github, new RegExp(s.asset), true);
|
|
26787
|
+
return { url: a.url, fileName: a.name, sha256: a.sha256 };
|
|
26788
|
+
}
|
|
26789
|
+
if ("url" in s) {
|
|
26790
|
+
const name = decodeURIComponent(new URL(s.url).pathname.split("/").pop() || entry.id);
|
|
26791
|
+
return { url: s.url, fileName: /\.\w{2,5}$/.test(name) ? name : name + ".zip" };
|
|
26792
|
+
}
|
|
26793
|
+
if ("resolve" in s && RESOLVERS[s.resolve]) return RESOLVERS[s.resolve]();
|
|
26794
|
+
throw new Error("no download source for " + entry.name);
|
|
26795
|
+
};
|
|
26796
|
+
var findExe = (root, exe) => {
|
|
26797
|
+
const match = exeMatcher(exe);
|
|
26798
|
+
let queue = [root];
|
|
26799
|
+
let seen = 0;
|
|
26800
|
+
for (let depth = 0; depth < 7 && queue.length; depth++) {
|
|
26801
|
+
const next = [];
|
|
26802
|
+
for (const dir of queue) {
|
|
26803
|
+
let entries2;
|
|
26804
|
+
try {
|
|
26805
|
+
entries2 = fs11.readdirSync(dir, { withFileTypes: true });
|
|
26806
|
+
} catch {
|
|
26807
|
+
continue;
|
|
26808
|
+
}
|
|
26809
|
+
const hit = entries2.find((e) => e.isFile() && match(e.name));
|
|
26810
|
+
if (hit) return path15.join(dir, hit.name);
|
|
26811
|
+
next.push(...entries2.filter((e) => e.isDirectory() && !e.isSymbolicLink()).map((e) => path15.join(dir, e.name)));
|
|
26812
|
+
if ((seen += entries2.length) > 5e4) return null;
|
|
26813
|
+
}
|
|
26814
|
+
queue = next;
|
|
26815
|
+
}
|
|
26816
|
+
return null;
|
|
26817
|
+
};
|
|
26818
|
+
var installApp = async (entry, dest) => {
|
|
26819
|
+
const work = stagingFolder(dest);
|
|
26820
|
+
const out = path15.join(work, "out");
|
|
26821
|
+
try {
|
|
26822
|
+
if ("npm" in entry.source) {
|
|
26823
|
+
const npmCli = path15.join(path15.dirname(process.execPath), "node_modules", "npm", "bin", "npm-cli.js");
|
|
26824
|
+
log("Installing " + entry.name + " (npm) ...");
|
|
26825
|
+
await execAsync(process.execPath, [npmCli, "install", "--prefix", mkdirp(out), "--no-audit", "--no-fund", "--loglevel=error", entry.source.npm]);
|
|
26826
|
+
} else {
|
|
26827
|
+
const d = await resolve(entry);
|
|
26828
|
+
log("Downloading " + entry.name + " (" + d.fileName + ", ~" + entry.size + " once) ...");
|
|
26829
|
+
const file3 = path15.join(mkdirp(work), d.fileName.replace(/[\\/:*?"<>|]/g, "_"));
|
|
26830
|
+
await download(d.url, file3, { sha256: d.sha256 ?? null });
|
|
26831
|
+
await unpack(entry, file3, out, d);
|
|
26832
|
+
}
|
|
26833
|
+
fs11.writeFileSync(path15.join(out, MARKER), JSON.stringify({ id: entry.id, at: (/* @__PURE__ */ new Date()).toISOString() }));
|
|
26834
|
+
moveIntoPlace(out, dest);
|
|
26835
|
+
} finally {
|
|
26836
|
+
safeRemove(work, path15.dirname(work));
|
|
26837
|
+
}
|
|
26838
|
+
};
|
|
26839
|
+
var unpack = async (entry, file3, out, d) => {
|
|
26840
|
+
if (entry.id === "7zip") {
|
|
26841
|
+
const sevenZr = path15.join(path15.dirname(file3), "7zr.exe");
|
|
26842
|
+
const zr = await githubAsset("ip7z/7zip", /^7zr\.exe$/);
|
|
26843
|
+
await download(zr.url, sevenZr, zr.sha256);
|
|
26844
|
+
await execAsync(sevenZr, ["x", "-y", "-o" + out, file3], { stdio: "ignore" });
|
|
26845
|
+
return;
|
|
26846
|
+
}
|
|
26847
|
+
switch (entry.unpack ?? "archive") {
|
|
26848
|
+
case "file": {
|
|
26849
|
+
mkdirp(out);
|
|
26850
|
+
fs11.renameSync(file3, path15.join(out, /^\//.test(entry.exe) ? path15.basename(file3) : entry.exe));
|
|
26851
|
+
return;
|
|
26852
|
+
}
|
|
26853
|
+
case "nsis": {
|
|
26854
|
+
if (!exists(sevenZip())) throw new Error("7-Zip is needed to unpack " + entry.name + " and could not be installed");
|
|
26855
|
+
const raw = path15.join(path15.dirname(out), "raw");
|
|
26856
|
+
await execAsync(sevenZip(), ["x", "-y", "-o" + raw, file3], { stdio: "ignore" });
|
|
26857
|
+
const inner = findExe(raw, "/^app-64\\.7z$/");
|
|
26858
|
+
if (inner) await execAsync(sevenZip(), ["x", "-y", "-o" + out, inner], { stdio: "ignore" });
|
|
26859
|
+
else fs11.renameSync(raw, out);
|
|
26860
|
+
return;
|
|
26861
|
+
}
|
|
26862
|
+
case "msi": {
|
|
26863
|
+
mkdirp(out);
|
|
26864
|
+
await execAsync(SYSTEM.msiexec(), ["/a", file3, "/qn", "TARGETDIR=" + out], { stdio: "ignore" });
|
|
26865
|
+
return;
|
|
26866
|
+
}
|
|
26867
|
+
default:
|
|
26868
|
+
await extractArchive(file3, out, d.members);
|
|
26869
|
+
}
|
|
26870
|
+
};
|
|
26871
|
+
var afterInstall = async (entry, exe) => {
|
|
26872
|
+
const dir = path15.dirname(exe);
|
|
26873
|
+
if (entry.needs?.includes("mesa")) {
|
|
26874
|
+
const mesa = tool("mesa", arch === "arm64" ? "arm64" : "x64");
|
|
26875
|
+
for (const dll of ["opengl32.dll", "libgallium_wgl.dll", "dxil.dll"]) {
|
|
26876
|
+
if (exists(path15.join(mesa, dll)) && !exists(path15.join(dir, dll))) fs11.copyFileSync(path15.join(mesa, dll), path15.join(dir, dll));
|
|
26877
|
+
}
|
|
26878
|
+
}
|
|
26879
|
+
if (entry.id === "godot" && !exists(path15.join(dir, "._sc_"))) fs11.writeFileSync(path15.join(dir, "._sc_"), "");
|
|
26880
|
+
if (entry.id === "sublime") mkdirp(path15.join(dir, "Data"));
|
|
26881
|
+
if (entry.id === "sysinternals") {
|
|
26882
|
+
for (const name of ["Process Explorer", "Process Monitor", "Autoruns", "TCPView", "PsExec", "PsList", "PsKill", "Handle", "ListDLLs", "Sigcheck", "Strings", "VMMap", "RAMMap", "DebugView", "Disk2vhd", "Du", "ZoomIt"]) {
|
|
26883
|
+
await execAsync(SYSTEM.reg(), ["add", "HKCU\\Software\\Sysinternals\\" + name, "/v", "EulaAccepted", "/t", "REG_DWORD", "/d", "1", "/f"], { stdio: "ignore" }).catch(() => void 0);
|
|
26884
|
+
}
|
|
26885
|
+
}
|
|
26886
|
+
};
|
|
26887
|
+
var shortcuts = (apps) => {
|
|
26888
|
+
if (!apps.length) return;
|
|
26889
|
+
const q = (s) => "'" + s.replace(/'/g, "''") + "'";
|
|
26890
|
+
const desktop = path15.join(os5.homedir(), "Desktop");
|
|
26891
|
+
const start = path15.join(process.env.APPDATA ?? path15.join(os5.homedir(), "AppData", "Roaming"), "Microsoft", "Windows", "Start Menu", "Programs", "Sandbox apps");
|
|
26892
|
+
const lines = ["$w = New-Object -ComObject WScript.Shell", "New-Item -ItemType Directory -Force -Path " + q(start) + " | Out-Null"];
|
|
26893
|
+
for (const app of apps) {
|
|
26894
|
+
for (const folder of [desktop, start]) {
|
|
26895
|
+
const name = app.name.replace(/[\\/:*?"<>|]/g, "");
|
|
26896
|
+
lines.push("$s = $w.CreateShortcut(" + q(path15.join(folder, name + ".lnk")) + "); $s.TargetPath = " + q(app.exe) + "; $s.WorkingDirectory = " + q(path15.dirname(app.exe)) + "; $s.Save()");
|
|
26897
|
+
}
|
|
26898
|
+
}
|
|
26899
|
+
powershell(lines.join("\n"));
|
|
26900
|
+
};
|
|
26901
|
+
var setupApps = async (env, apps, o) => {
|
|
26902
|
+
const { entries: entries2, skipped } = appsToInstall(apps, o.gitAccess);
|
|
26903
|
+
for (const s of skipped) env.summary.push("app skipped: " + s);
|
|
26904
|
+
if (dryRun) {
|
|
26905
|
+
log("(dry run) would install apps: " + entries2.map((e) => e.name).join(", "));
|
|
26906
|
+
return;
|
|
26907
|
+
}
|
|
26908
|
+
const gui = [];
|
|
26909
|
+
const installed2 = [];
|
|
26910
|
+
const one = async (entry) => {
|
|
26911
|
+
try {
|
|
26912
|
+
const dest = tool("apps", ...entry.id.split("/"));
|
|
26913
|
+
if (!exists(path15.join(dest, MARKER)) || o.refresh) await installApp(entry, dest);
|
|
26914
|
+
const exe = findExe(dest, entry.exe);
|
|
26915
|
+
if (!exe) throw new Error(entry.exe + " not found in the download");
|
|
26916
|
+
await afterInstall(entry, exe);
|
|
26917
|
+
if (entry.cli || entry.id === "sysinternals") env.prepend.push(path15.dirname(exe));
|
|
26918
|
+
if (!entry.cli) gui.push({ name: entry.name, exe });
|
|
26919
|
+
installed2.push(entry.name);
|
|
26920
|
+
} catch (e) {
|
|
26921
|
+
warn(entry.name + " could not be installed and is skipped; the other apps are not affected. Reason: " + errMsg(e));
|
|
26922
|
+
env.summary.push(entry.name + ": FAILED");
|
|
26923
|
+
}
|
|
26924
|
+
};
|
|
26925
|
+
const [first, rest] = entries2[0]?.id === "7zip" ? [[entries2[0]], entries2.slice(1)] : [[], entries2];
|
|
26926
|
+
for (const e of first) await one(e);
|
|
26927
|
+
const queue = [...rest];
|
|
26928
|
+
await Promise.all(Array.from({ length: Math.min(PARALLEL, queue.length) }, async () => {
|
|
26929
|
+
for (let e = queue.shift(); e; e = queue.shift()) await one(e);
|
|
26930
|
+
}));
|
|
26931
|
+
try {
|
|
26932
|
+
shortcuts(gui);
|
|
26933
|
+
} catch (e) {
|
|
26934
|
+
warn("App shortcuts could not be created: " + errMsg(e));
|
|
26935
|
+
}
|
|
26936
|
+
if (installed2.length) env.summary.push("apps: " + installed2.join(", ") + " (shortcuts on the desktop and in Start > Sandbox apps)");
|
|
26937
|
+
};
|
|
26938
|
+
|
|
26939
|
+
// src/guest/helpers.ts
|
|
26940
|
+
import fs12 from "node:fs";
|
|
26941
|
+
import os6 from "node:os";
|
|
26942
|
+
import path16 from "node:path";
|
|
26943
|
+
import crypto2 from "node:crypto";
|
|
26944
|
+
import { spawnSync as spawnSync3 } from "node:child_process";
|
|
26945
|
+
var CSC = path16.join(process.env.WINDIR ?? "C:\\Windows", "Microsoft.NET", "Framework64", "v4.0.30319", "csc.exe");
|
|
26946
|
+
var sourceHash = (name) => crypto2.createHash("sha256").update(fs12.readFileSync(path16.join(launchDir, "sandbox", name + ".cs"))).digest("hex").slice(0, 12);
|
|
26947
|
+
var ensureCompiled = (name) => {
|
|
26948
|
+
const exe = path16.join(os6.tmpdir(), "agent-sandbox", name + "-" + sourceHash(name) + ".exe");
|
|
26949
|
+
if (exists(exe)) return exe;
|
|
26950
|
+
if (!exists(CSC)) throw new Error("The .NET Framework C# compiler was not found at " + CSC + " (it ships with Windows 10/11).");
|
|
26951
|
+
mkdirp(path16.dirname(exe));
|
|
26952
|
+
const result = spawnSync3(CSC, ["/nologo", "/optimize", "/target:exe", "/out:" + exe, path16.join(launchDir, "sandbox", name + ".cs")], { encoding: "utf8", windowsHide: true });
|
|
26953
|
+
if (result.status !== 0) throw new Error("Compiling " + name + " failed: " + ((result.stdout ?? "") + (result.stderr ?? "")).trim().slice(0, 1500));
|
|
26954
|
+
return exe;
|
|
26955
|
+
};
|
|
26476
26956
|
|
|
26477
26957
|
// src/guest/toolchains/databases/dynamodb.ts
|
|
26478
|
-
import
|
|
26479
|
-
import
|
|
26958
|
+
import fs15 from "node:fs";
|
|
26959
|
+
import path19 from "node:path";
|
|
26480
26960
|
import { spawn as spawn3 } from "node:child_process";
|
|
26481
26961
|
|
|
26482
26962
|
// src/guest/toolchains/java.ts
|
|
26483
|
-
import
|
|
26484
|
-
import
|
|
26963
|
+
import fs13 from "node:fs";
|
|
26964
|
+
import path17 from "node:path";
|
|
26485
26965
|
var ADOPTIUM = "https://api.adoptium.net/v3";
|
|
26486
26966
|
var MAVEN = "https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/";
|
|
26487
26967
|
var temurin = async (major) => {
|
|
@@ -26500,19 +26980,19 @@ var setupJdk = async (env, config2) => {
|
|
|
26500
26980
|
const { major, source } = await javaMajor(config2);
|
|
26501
26981
|
const release = await resolveCached("java:" + major, async () => (await temurin(major)).release_name);
|
|
26502
26982
|
const home = tool("java", release.replace(/[^A-Za-z0-9.-]/g, "_"));
|
|
26503
|
-
if (!exists(
|
|
26983
|
+
if (!exists(path17.join(home, "bin", "java.exe"))) {
|
|
26504
26984
|
const asset = await temurin(major);
|
|
26505
26985
|
log("Downloading Java " + release + " (JDK, ~200 MB once) ...");
|
|
26506
26986
|
await installArchive(asset.binary.package.link, home, { sha256: asset.binary.package.checksum, locate: "release", fileName: asset.binary.package.name });
|
|
26507
26987
|
}
|
|
26508
26988
|
env.vars.JAVA_HOME = home;
|
|
26509
|
-
env.prepend.push(
|
|
26989
|
+
env.prepend.push(path17.join(home, "bin"));
|
|
26510
26990
|
env.summary.push("java: " + release + " (Temurin, from " + source + ")");
|
|
26511
26991
|
};
|
|
26512
26992
|
var ensureJdk = async () => {
|
|
26513
26993
|
const root = tool("java");
|
|
26514
|
-
const installed2 = exists(root) ?
|
|
26515
|
-
if (installed2.length) return
|
|
26994
|
+
const installed2 = exists(root) ? fs13.readdirSync(root).filter((d) => exists(path17.join(root, d, "bin", "java.exe"))).sort((a, b) => b.localeCompare(a, void 0, { numeric: true })) : [];
|
|
26995
|
+
if (installed2.length) return path17.join(root, installed2[0]);
|
|
26516
26996
|
const scratch = emptyEnv();
|
|
26517
26997
|
await setupJdk(scratch, { enabled: true, version: "lts", maven: false, gradle: false });
|
|
26518
26998
|
return scratch.vars.JAVA_HOME;
|
|
@@ -26523,29 +27003,29 @@ var setupMaven = async (env) => {
|
|
|
26523
27003
|
return pickPackageVersion(versions, "3") ?? Promise.reject(new Error("No Maven 3 release found"));
|
|
26524
27004
|
});
|
|
26525
27005
|
const home = tool("maven", version2);
|
|
26526
|
-
if (!exists(
|
|
27006
|
+
if (!exists(path17.join(home, "bin", "mvn.cmd"))) {
|
|
26527
27007
|
const url2 = MAVEN + version2 + "/apache-maven-" + version2 + "-bin.zip";
|
|
26528
27008
|
log("Downloading Maven " + version2 + " (~10 MB once) ...");
|
|
26529
27009
|
await installArchive(url2, home, { sha512: (await fetchText(url2 + ".sha512")).trim().split(/\s+/)[0], locate: "LICENSE" });
|
|
26530
27010
|
}
|
|
26531
27011
|
const repo = tool("maven-repository");
|
|
26532
27012
|
Object.assign(env.vars, { MAVEN_HOME: home, M2_HOME: home, MAVEN_OPTS: "-Dmaven.repo.local=" + repo });
|
|
26533
|
-
env.prepend.push(
|
|
27013
|
+
env.prepend.push(path17.join(home, "bin"));
|
|
26534
27014
|
env.summary.push("maven: " + version2);
|
|
26535
27015
|
};
|
|
26536
27016
|
var setupGradle = async (env) => {
|
|
26537
27017
|
const current = await fetchJson("https://services.gradle.org/versions/current").catch(() => null);
|
|
26538
27018
|
const version2 = await resolveCached("gradle", async () => current?.version ?? Promise.reject(new Error("Gradle version lookup failed")));
|
|
26539
27019
|
const home = tool("gradle", version2);
|
|
26540
|
-
if (!exists(
|
|
27020
|
+
if (!exists(path17.join(home, "bin", "gradle.bat"))) {
|
|
26541
27021
|
if (!current || current.version !== version2) throw new Error("Gradle " + version2 + " is not installed and cannot be downloaded right now");
|
|
26542
27022
|
log("Downloading Gradle " + version2 + " (~130 MB once) ...");
|
|
26543
27023
|
await installArchive(current.downloadUrl, home, { sha256: (await fetchText(current.checksumUrl)).trim(), locate: "LICENSE", fileName: "gradle-" + version2 + ".zip" });
|
|
26544
27024
|
}
|
|
26545
27025
|
const userHome = tool("gradle-home");
|
|
26546
|
-
|
|
27026
|
+
fs13.mkdirSync(userHome, { recursive: true });
|
|
26547
27027
|
Object.assign(env.vars, { GRADLE_HOME: home, GRADLE_USER_HOME: userHome, GRADLE_OPTS: "-Dorg.gradle.vfs.watch=false" });
|
|
26548
|
-
env.prepend.push(
|
|
27028
|
+
env.prepend.push(path17.join(home, "bin"));
|
|
26549
27029
|
env.summary.push("gradle: " + version2);
|
|
26550
27030
|
};
|
|
26551
27031
|
var setupJava = async (env, config2) => {
|
|
@@ -26564,20 +27044,20 @@ var setupJava = async (env, config2) => {
|
|
|
26564
27044
|
|
|
26565
27045
|
// src/guest/ports.ts
|
|
26566
27046
|
import net from "node:net";
|
|
26567
|
-
var freePort = () => new Promise((
|
|
27047
|
+
var freePort = () => new Promise((resolve2, reject) => {
|
|
26568
27048
|
const server = net.createServer();
|
|
26569
27049
|
server.once("error", reject);
|
|
26570
27050
|
server.listen(0, "127.0.0.1", () => {
|
|
26571
27051
|
const { port } = server.address();
|
|
26572
|
-
server.close(() =>
|
|
27052
|
+
server.close(() => resolve2(port));
|
|
26573
27053
|
});
|
|
26574
27054
|
});
|
|
26575
|
-
var portOpen = (port) => new Promise((
|
|
27055
|
+
var portOpen = (port) => new Promise((resolve2) => {
|
|
26576
27056
|
const socket = net.connect({ host: "127.0.0.1", port }, () => {
|
|
26577
27057
|
socket.destroy();
|
|
26578
|
-
|
|
27058
|
+
resolve2(true);
|
|
26579
27059
|
});
|
|
26580
|
-
socket.once("error", () =>
|
|
27060
|
+
socket.once("error", () => resolve2(false));
|
|
26581
27061
|
});
|
|
26582
27062
|
var waitForPort = async (port, seconds) => {
|
|
26583
27063
|
for (const end = Date.now() + seconds * 1e3; Date.now() < end; ) {
|
|
@@ -26588,26 +27068,26 @@ var waitForPort = async (port, seconds) => {
|
|
|
26588
27068
|
};
|
|
26589
27069
|
|
|
26590
27070
|
// src/guest/toolchains/databases/server.ts
|
|
26591
|
-
import
|
|
26592
|
-
import
|
|
27071
|
+
import fs14 from "node:fs";
|
|
27072
|
+
import path18 from "node:path";
|
|
26593
27073
|
import { spawn as spawn2 } from "node:child_process";
|
|
26594
|
-
var dataFor = (name) =>
|
|
27074
|
+
var dataFor = (name) => path18.join(dataDir, "databases", name);
|
|
26595
27075
|
var startServer = async (name, exe, args, port) => {
|
|
26596
27076
|
if (await portOpen(port)) throw new Error("port " + port + " is already in use (change databases." + name + ".port)");
|
|
26597
|
-
const logFile2 =
|
|
26598
|
-
const out =
|
|
27077
|
+
const logFile2 = path18.join(logsDir, name + ".log");
|
|
27078
|
+
const out = fs14.openSync(logFile2, "a");
|
|
26599
27079
|
spawn2(exe, args, { detached: true, stdio: ["ignore", out, out], windowsHide: true }).unref();
|
|
26600
|
-
|
|
27080
|
+
fs14.closeSync(out);
|
|
26601
27081
|
if (!await waitForPort(port, 60)) throw new Error(name + " did not start listening on port " + port + "; see " + logFile2);
|
|
26602
27082
|
};
|
|
26603
27083
|
var clearStaleLocks = async (dir, files, port) => {
|
|
26604
27084
|
if (await portOpen(port)) return;
|
|
26605
|
-
for (const f of files)
|
|
27085
|
+
for (const f of files) fs14.rmSync(path18.join(dir, f), { force: true });
|
|
26606
27086
|
};
|
|
26607
27087
|
var createOnce = async (data, marker, create) => {
|
|
26608
|
-
if (exists(
|
|
27088
|
+
if (exists(path18.join(data, marker))) return;
|
|
26609
27089
|
const existed = exists(data);
|
|
26610
|
-
mkdirp(
|
|
27090
|
+
mkdirp(path18.dirname(data));
|
|
26611
27091
|
try {
|
|
26612
27092
|
await create();
|
|
26613
27093
|
} catch (e) {
|
|
@@ -26624,40 +27104,40 @@ var createOnce = async (data, marker, create) => {
|
|
|
26624
27104
|
// src/guest/toolchains/databases/dynamodb.ts
|
|
26625
27105
|
var DYNAMO_ZIP = "https://d1ni2b6xgvw0s0.cloudfront.net/v2.x/dynamodb_local_latest.zip";
|
|
26626
27106
|
var setupDynamo = async (env, plan2) => {
|
|
26627
|
-
const java =
|
|
27107
|
+
const java = path19.join(await ensureJdk(), "bin", "java.exe");
|
|
26628
27108
|
const home = tool("dynamodb-local");
|
|
26629
|
-
if (!exists(
|
|
27109
|
+
if (!exists(path19.join(home, "DynamoDBLocal.jar"))) {
|
|
26630
27110
|
log("Downloading DynamoDB Local (~60 MB once) ...");
|
|
26631
27111
|
const sha256 = (await fetchText(DYNAMO_ZIP + ".sha256")).trim().split(/\s+/)[0];
|
|
26632
27112
|
await installArchive(DYNAMO_ZIP, home, { sha256, locate: "DynamoDBLocal.jar", fileName: "dynamodb_local.zip" });
|
|
26633
27113
|
}
|
|
26634
27114
|
const data = mkdirp(dataFor("dynamodb"));
|
|
26635
|
-
await startServer("dynamodb", java, ["-Djava.library.path=" +
|
|
27115
|
+
await startServer("dynamodb", java, ["-Djava.library.path=" + path19.join(home, "DynamoDBLocal_lib"), "-jar", path19.join(home, "DynamoDBLocal.jar"), "-sharedDb", "-dbPath", data, "-port", String(plan2.port)], plan2.port);
|
|
26636
27116
|
const endpoint = "http://localhost:" + plan2.port;
|
|
26637
27117
|
const aws = { AWS_ENDPOINT_URL_DYNAMODB: endpoint, DYNAMO_ENDPOINT: endpoint, AWS_ACCESS_KEY_ID: "local", AWS_SECRET_ACCESS_KEY: "local", AWS_REGION: "us-east-1", AWS_DEFAULT_REGION: "us-east-1" };
|
|
26638
27118
|
Object.assign(env.vars, aws);
|
|
26639
27119
|
env.summary.push("dynamodb (DynamoDB Local): " + endpoint + " (AWS SDKs use it automatically via AWS_ENDPOINT_URL_DYNAMODB; dummy credentials)");
|
|
26640
27120
|
if (!plan2.adminPort) return;
|
|
26641
27121
|
const prefix = tool("dynamodb-admin");
|
|
26642
|
-
const script =
|
|
27122
|
+
const script = path19.join(prefix, "node_modules", "dynamodb-admin", "dist", "dynamodb-admin.js");
|
|
26643
27123
|
if (!exists(script)) {
|
|
26644
27124
|
log("Installing dynamodb-admin, the DynamoDB web UI (~20 MB once) ...");
|
|
26645
|
-
const npmCli =
|
|
27125
|
+
const npmCli = path19.join(path19.dirname(process.execPath), "node_modules", "npm", "bin", "npm-cli.js");
|
|
26646
27126
|
await execAsync(process.execPath, [npmCli, "install", "--global", "--prefix", prefix, "dynamodb-admin", "--no-fund", "--no-audit"], { stdio: "ignore" });
|
|
26647
27127
|
}
|
|
26648
27128
|
if (await portOpen(plan2.adminPort)) {
|
|
26649
27129
|
env.summary.push("dynamodb-admin: NOT started, port " + plan2.adminPort + " is in use (change databases.dynamodb.adminPort)");
|
|
26650
27130
|
return;
|
|
26651
27131
|
}
|
|
26652
|
-
const out =
|
|
27132
|
+
const out = fs15.openSync(path19.join(logsDir, "dynamodb-admin.log"), "a");
|
|
26653
27133
|
spawn3(process.execPath, [script, "--port", String(plan2.adminPort), "--dynamo-endpoint", endpoint, "--skip-default-credentials"], { detached: true, stdio: ["ignore", out, out], windowsHide: true, env: { ...process.env, ...aws } }).unref();
|
|
26654
|
-
|
|
26655
|
-
if (!await waitForPort(plan2.adminPort, 30)) throw new Error("dynamodb-admin did not start; see " +
|
|
27134
|
+
fs15.closeSync(out);
|
|
27135
|
+
if (!await waitForPort(plan2.adminPort, 30)) throw new Error("dynamodb-admin did not start; see " + path19.join(logsDir, "dynamodb-admin.log"));
|
|
26656
27136
|
env.summary.push("dynamodb-admin: http://localhost:" + plan2.adminPort + " (browse and edit tables in the sandbox's browser)");
|
|
26657
27137
|
};
|
|
26658
27138
|
|
|
26659
27139
|
// src/guest/toolchains/databases/mongodb.ts
|
|
26660
|
-
import
|
|
27140
|
+
import path20 from "node:path";
|
|
26661
27141
|
var setupMongo = async (env, plan2) => {
|
|
26662
27142
|
const find = async () => {
|
|
26663
27143
|
const { versions } = await fetchJson("https://downloads.mongodb.org/full.json");
|
|
@@ -26668,24 +27148,24 @@ var setupMongo = async (env, plan2) => {
|
|
|
26668
27148
|
};
|
|
26669
27149
|
const version2 = await resolveCached("mongodb:" + plan2.version, async () => (await find()).version);
|
|
26670
27150
|
const home = tool("mongodb", version2);
|
|
26671
|
-
if (!exists(
|
|
27151
|
+
if (!exists(path20.join(home, "bin", "mongod.exe"))) {
|
|
26672
27152
|
const { archive } = await find();
|
|
26673
27153
|
log("Downloading MongoDB " + version2 + " (~400 MB once) ...");
|
|
26674
27154
|
await installArchive(archive.url, home, { sha256: archive.sha256, locate: "mongod.exe", up: 1 });
|
|
26675
27155
|
}
|
|
26676
27156
|
const shell = tool("mongosh");
|
|
26677
|
-
if (!exists(
|
|
27157
|
+
if (!exists(path20.join(shell, "mongosh.exe"))) {
|
|
26678
27158
|
await installFromGithub("mongodb-js/mongosh", /^mongosh-[\d.]+-win32-x64\.zip$/, { dest: shell, what: "mongosh, the MongoDB shell (~50 MB once)", locate: "mongosh.exe" });
|
|
26679
27159
|
}
|
|
26680
27160
|
const data = mkdirp(dataFor("mongodb"));
|
|
26681
27161
|
await clearStaleLocks(data, ["mongod.lock"], plan2.port);
|
|
26682
|
-
await startServer("mongodb",
|
|
26683
|
-
env.prepend.push(
|
|
27162
|
+
await startServer("mongodb", path20.join(home, "bin", "mongod.exe"), ["--dbpath", data, "--bind_ip", "127.0.0.1", "--port", String(plan2.port)], plan2.port);
|
|
27163
|
+
env.prepend.push(path20.join(home, "bin"), shell);
|
|
26684
27164
|
env.summary.push("mongodb " + version2 + ": mongodb://127.0.0.1:" + plan2.port + " (mongosh on PATH)");
|
|
26685
27165
|
};
|
|
26686
27166
|
|
|
26687
27167
|
// src/guest/toolchains/databases/mysql.ts
|
|
26688
|
-
import
|
|
27168
|
+
import path21 from "node:path";
|
|
26689
27169
|
var MARIA = "https://downloads.mariadb.org/rest-api/mariadb/";
|
|
26690
27170
|
var setupMysql = async (env, plan2) => {
|
|
26691
27171
|
const series = await resolveCached("mariadb:" + plan2.version, async () => {
|
|
@@ -26701,8 +27181,8 @@ var setupMysql = async (env, plan2) => {
|
|
|
26701
27181
|
};
|
|
26702
27182
|
const version2 = await resolveCached("mariadb-version:" + series, async () => (await latest()).version);
|
|
26703
27183
|
const home = tool("mariadb", version2);
|
|
26704
|
-
const bin =
|
|
26705
|
-
if (!exists(
|
|
27184
|
+
const bin = path21.join(home, "bin");
|
|
27185
|
+
if (!exists(path21.join(bin, "mariadbd.exe"))) {
|
|
26706
27186
|
const { zip } = await latest();
|
|
26707
27187
|
log("Downloading MariaDB " + version2 + " (~90 MB once) ...");
|
|
26708
27188
|
await installArchive(zip.file_download_url.replace(/^http:/, "https:"), home, { sha256: zip.checksum?.sha256sum ?? null, locate: "mariadbd.exe", up: 1, fileName: zip.file_name });
|
|
@@ -26710,16 +27190,16 @@ var setupMysql = async (env, plan2) => {
|
|
|
26710
27190
|
const data = dataFor("mariadb");
|
|
26711
27191
|
await createOnce(data, "mysql", async () => {
|
|
26712
27192
|
log("Creating the MariaDB database (first start) ...");
|
|
26713
|
-
await execAsync(
|
|
27193
|
+
await execAsync(path21.join(bin, "mariadb-install-db.exe"), ["--datadir=" + data, "--port=" + plan2.port], { stdio: "ignore" });
|
|
26714
27194
|
});
|
|
26715
|
-
await startServer("mysql",
|
|
27195
|
+
await startServer("mysql", path21.join(bin, "mariadbd.exe"), ["--datadir=" + data, "--port=" + plan2.port, "--bind-address=127.0.0.1", "--console"], plan2.port);
|
|
26716
27196
|
Object.assign(env.vars, { MYSQL_HOST: "127.0.0.1", MYSQL_TCP_PORT: String(plan2.port) });
|
|
26717
27197
|
env.prepend.push(bin);
|
|
26718
27198
|
env.summary.push("mysql (MariaDB " + version2 + "): 127.0.0.1:" + plan2.port + ", user root, no password (mysql://root@127.0.0.1:" + plan2.port + ")");
|
|
26719
27199
|
};
|
|
26720
27200
|
|
|
26721
27201
|
// src/guest/toolchains/databases/postgres.ts
|
|
26722
|
-
import
|
|
27202
|
+
import path22 from "node:path";
|
|
26723
27203
|
var postgresData = (version2) => dataFor("postgres-" + version2.split(".")[0]);
|
|
26724
27204
|
var setupPostgres = async (env, plan2) => {
|
|
26725
27205
|
const exact = await resolveCached("postgres:" + plan2.version, async () => {
|
|
@@ -26728,8 +27208,8 @@ var setupPostgres = async (env, plan2) => {
|
|
|
26728
27208
|
return hit ? hit.major + "." + hit.latestMinor : Promise.reject(new Error("No supported PostgreSQL " + plan2.version));
|
|
26729
27209
|
});
|
|
26730
27210
|
const home = tool("postgres", exact);
|
|
26731
|
-
const bin =
|
|
26732
|
-
if (!exists(
|
|
27211
|
+
const bin = path22.join(home, "bin");
|
|
27212
|
+
if (!exists(path22.join(bin, "pg_ctl.exe"))) {
|
|
26733
27213
|
log("Downloading PostgreSQL " + exact + " (~330 MB once) ...");
|
|
26734
27214
|
await installArchive("https://get.enterprisedb.com/postgresql/postgresql-" + exact + "-1-windows-x64-binaries.zip", home, {
|
|
26735
27215
|
locate: "pg_ctl.exe",
|
|
@@ -26741,25 +27221,25 @@ var setupPostgres = async (env, plan2) => {
|
|
|
26741
27221
|
const data = postgresData(exact);
|
|
26742
27222
|
await createOnce(data, "PG_VERSION", async () => {
|
|
26743
27223
|
log("Creating the PostgreSQL database (first start) ...");
|
|
26744
|
-
await execAsync(
|
|
27224
|
+
await execAsync(path22.join(bin, "initdb.exe"), ["-D", data, "-U", "postgres", "-A", "trust", "-E", "UTF8", "--locale=C"], { stdio: "ignore" });
|
|
26745
27225
|
});
|
|
26746
27226
|
if (await portOpen(plan2.port)) throw new Error("port " + plan2.port + " is already in use (change databases.postgres.port)");
|
|
26747
27227
|
await clearStaleLocks(data, ["postmaster.pid"], plan2.port);
|
|
26748
|
-
await execAsync(
|
|
27228
|
+
await execAsync(path22.join(bin, "pg_ctl.exe"), ["start", "-D", data, "-w", "-t", "60", "-l", path22.join(logsDir, "postgres.log"), "-o", "-p " + plan2.port + " -c listen_addresses=localhost"], { stdio: "ignore" });
|
|
26749
27229
|
Object.assign(env.vars, { PGHOST: "localhost", PGPORT: String(plan2.port), PGUSER: "postgres" });
|
|
26750
27230
|
env.prepend.push(bin);
|
|
26751
27231
|
env.summary.push("postgres " + exact + ": localhost:" + plan2.port + ", user postgres, no password (postgres://postgres@localhost:" + plan2.port + "/postgres)");
|
|
26752
27232
|
};
|
|
26753
27233
|
|
|
26754
27234
|
// src/guest/toolchains/databases/redis.ts
|
|
26755
|
-
import
|
|
27235
|
+
import path23 from "node:path";
|
|
26756
27236
|
var setupRedis = async (env, plan2) => {
|
|
26757
27237
|
const home = tool("redis");
|
|
26758
|
-
if (!exists(
|
|
27238
|
+
if (!exists(path23.join(home, "redis-server.exe"))) {
|
|
26759
27239
|
await installFromGithub("redis-windows/redis-windows", /^Redis-[\d.]+-Windows-x64-msys2\.zip$/, { dest: home, what: (a) => "Redis (" + a.name + ", ~10 MB once)", locate: "redis-server.exe" });
|
|
26760
27240
|
}
|
|
26761
27241
|
const data = mkdirp(dataFor("redis"));
|
|
26762
|
-
await startServer("redis",
|
|
27242
|
+
await startServer("redis", path23.join(home, "redis-server.exe"), ["--port", String(plan2.port), "--bind", "127.0.0.1", "--dir", data.replace(/\\/g, "/"), "--appendonly", "yes"], plan2.port);
|
|
26763
27243
|
env.prepend.push(home);
|
|
26764
27244
|
env.summary.push("redis: redis://127.0.0.1:" + plan2.port + " (redis-cli on PATH)");
|
|
26765
27245
|
};
|
|
@@ -26784,28 +27264,8 @@ var setupDatabase = async (env, plan2) => {
|
|
|
26784
27264
|
};
|
|
26785
27265
|
|
|
26786
27266
|
// src/guest/toolchains/git.ts
|
|
26787
|
-
import
|
|
26788
|
-
import
|
|
26789
|
-
|
|
26790
|
-
// src/guest/helpers.ts
|
|
26791
|
-
import fs14 from "node:fs";
|
|
26792
|
-
import os4 from "node:os";
|
|
26793
|
-
import path22 from "node:path";
|
|
26794
|
-
import crypto2 from "node:crypto";
|
|
26795
|
-
import { spawnSync as spawnSync3 } from "node:child_process";
|
|
26796
|
-
var CSC = path22.join(process.env.WINDIR ?? "C:\\Windows", "Microsoft.NET", "Framework64", "v4.0.30319", "csc.exe");
|
|
26797
|
-
var sourceHash = (name) => crypto2.createHash("sha256").update(fs14.readFileSync(path22.join(launchDir, "sandbox", name + ".cs"))).digest("hex").slice(0, 12);
|
|
26798
|
-
var ensureCompiled = (name) => {
|
|
26799
|
-
const exe = path22.join(os4.tmpdir(), "agent-sandbox", name + "-" + sourceHash(name) + ".exe");
|
|
26800
|
-
if (exists(exe)) return exe;
|
|
26801
|
-
if (!exists(CSC)) throw new Error("The .NET Framework C# compiler was not found at " + CSC + " (it ships with Windows 10/11).");
|
|
26802
|
-
mkdirp(path22.dirname(exe));
|
|
26803
|
-
const result = spawnSync3(CSC, ["/nologo", "/optimize", "/target:exe", "/out:" + exe, path22.join(launchDir, "sandbox", name + ".cs")], { encoding: "utf8", windowsHide: true });
|
|
26804
|
-
if (result.status !== 0) throw new Error("Compiling " + name + " failed: " + ((result.stdout ?? "") + (result.stderr ?? "")).trim().slice(0, 1500));
|
|
26805
|
-
return exe;
|
|
26806
|
-
};
|
|
26807
|
-
|
|
26808
|
-
// src/guest/toolchains/git.ts
|
|
27267
|
+
import fs16 from "node:fs";
|
|
27268
|
+
import path24 from "node:path";
|
|
26809
27269
|
var BLOCKED_HOOKS = ["pre-commit", "commit-msg", "pre-merge-commit", "pre-push", "pre-rebase", "pre-applypatch", "applypatch-msg"];
|
|
26810
27270
|
var posix = (p) => p.replace(/\\/g, "/");
|
|
26811
27271
|
var installPortableGit = async (root) => {
|
|
@@ -26816,50 +27276,50 @@ var installPortableGit = async (root) => {
|
|
|
26816
27276
|
await download(asset.url, sfx, asset.sha256);
|
|
26817
27277
|
await execAsync(sfx, ["-o" + root, "-y"], { stdio: "ignore" });
|
|
26818
27278
|
} finally {
|
|
26819
|
-
|
|
27279
|
+
fs16.rmSync(sfx, { force: true });
|
|
26820
27280
|
}
|
|
26821
27281
|
};
|
|
26822
27282
|
var installGuard = (env, access, realGit) => {
|
|
26823
27283
|
const dir = mkdirp(tool("gitguard"));
|
|
26824
|
-
const guard =
|
|
26825
|
-
if (duringSession() && (exists(
|
|
27284
|
+
const guard = path24.join(launchDir, "runtime", "gitguard.js");
|
|
27285
|
+
if (duringSession() && (exists(path24.join(dir, "git.exe")) || exists(path24.join(dir, "git.cmd")))) {
|
|
26826
27286
|
} else try {
|
|
26827
|
-
|
|
26828
|
-
|
|
27287
|
+
fs16.copyFileSync(ensureCompiled("gitshim"), path24.join(dir, "git.exe"));
|
|
27288
|
+
fs16.rmSync(path24.join(dir, "git.cmd"), { force: true });
|
|
26829
27289
|
} catch (e) {
|
|
26830
27290
|
warn("git guard: falling back to git.cmd (" + errMsg(e) + ")");
|
|
26831
|
-
|
|
27291
|
+
fs16.writeFileSync(path24.join(dir, "git.cmd"), '@"' + process.execPath + '" "' + guard + '" %*\r\n');
|
|
26832
27292
|
}
|
|
26833
|
-
|
|
27293
|
+
fs16.writeFileSync(path24.join(dir, "bashenv.sh"), 'git() { "' + posix(process.execPath) + '" "' + posix(guard) + '" "$@"; }\nexport -f git\n');
|
|
26834
27294
|
env.prepend.unshift(dir);
|
|
26835
27295
|
Object.assign(env.vars, {
|
|
26836
27296
|
AGENT_GIT_ACCESS: access,
|
|
26837
27297
|
AGENT_REAL_GIT: access === "readonly" ? realGit : "",
|
|
26838
27298
|
AGENT_GUARD_NODE: process.execPath,
|
|
26839
27299
|
AGENT_GUARD_SCRIPT: guard,
|
|
26840
|
-
BASH_ENV: posix(
|
|
27300
|
+
BASH_ENV: posix(path24.join(dir, "bashenv.sh"))
|
|
26841
27301
|
});
|
|
26842
27302
|
if (access === "readonly") {
|
|
26843
|
-
const hooks = mkdirp(
|
|
26844
|
-
for (const hook of BLOCKED_HOOKS)
|
|
27303
|
+
const hooks = mkdirp(path24.join(dir, "hooks"));
|
|
27304
|
+
for (const hook of BLOCKED_HOOKS) fs16.writeFileSync(path24.join(hooks, hook), '#!/bin/sh\necho "git is read-only in this sandbox: ' + hook + ' refused." >&2\nexit 1\n');
|
|
26845
27305
|
Object.assign(env.vars, { GIT_CONFIG_COUNT: "1", GIT_CONFIG_KEY_0: "core.hooksPath", GIT_CONFIG_VALUE_0: posix(hooks) });
|
|
26846
27306
|
} else {
|
|
26847
|
-
env.vars.GIT_DIR =
|
|
27307
|
+
env.vars.GIT_DIR = path24.join(dataDir, "git-disabled");
|
|
26848
27308
|
}
|
|
26849
27309
|
};
|
|
26850
27310
|
var pointAtOwnCertificates = (root) => {
|
|
26851
|
-
const config2 =
|
|
26852
|
-
const bundle =
|
|
27311
|
+
const config2 = path24.join(root, "etc", "gitconfig");
|
|
27312
|
+
const bundle = path24.join(root, "mingw64", "etc", "ssl", "certs", "ca-bundle.crt");
|
|
26853
27313
|
if (!exists(config2) || !exists(bundle)) return;
|
|
26854
|
-
const text =
|
|
27314
|
+
const text = fs16.readFileSync(config2, "utf8");
|
|
26855
27315
|
const fixed = text.replace(/^(\s*sslCAInfo\s*=\s*).*$/gim, (_m, key) => key + posix(bundle));
|
|
26856
|
-
if (fixed !== text)
|
|
27316
|
+
if (fixed !== text) fs16.writeFileSync(config2, fixed);
|
|
26857
27317
|
};
|
|
26858
27318
|
var setupGit = async (env, hostCopy, refresh, access) => {
|
|
26859
27319
|
const root = tool("git");
|
|
26860
|
-
const bash =
|
|
26861
|
-
const gitExe =
|
|
26862
|
-
const hostGit =
|
|
27320
|
+
const bash = path24.join(root, "bin", "bash.exe");
|
|
27321
|
+
const gitExe = path24.join(root, "cmd", "git.exe");
|
|
27322
|
+
const hostGit = path24.join(hostToolsDir, "git");
|
|
26863
27323
|
if (exists(root) && !exists(bash)) {
|
|
26864
27324
|
log("Replacing the old MinGit (no bash) with full Git for Windows.");
|
|
26865
27325
|
safeRemove(root, toolsDir);
|
|
@@ -26871,11 +27331,11 @@ var setupGit = async (env, hostCopy, refresh, access) => {
|
|
|
26871
27331
|
}
|
|
26872
27332
|
const work = stagingFolder(root);
|
|
26873
27333
|
try {
|
|
26874
|
-
if (hostCopy && exists(
|
|
27334
|
+
if (hostCopy && exists(path24.join(hostGit, "bin", "bash.exe"))) {
|
|
26875
27335
|
log("Copying Git for Windows from this PC ...");
|
|
26876
27336
|
robocopy(hostGit, work);
|
|
26877
27337
|
} else await installPortableGit(work);
|
|
26878
|
-
if (!exists(
|
|
27338
|
+
if (!exists(path24.join(work, "bin", "bash.exe"))) throw new Error("bash.exe missing after installing Git");
|
|
26879
27339
|
moveIntoPlace(work, root);
|
|
26880
27340
|
} finally {
|
|
26881
27341
|
safeRemove(work, toolsDir);
|
|
@@ -26884,10 +27344,10 @@ var setupGit = async (env, hostCopy, refresh, access) => {
|
|
|
26884
27344
|
if (!exists(bash)) throw new Error("bash.exe missing after installing Git");
|
|
26885
27345
|
pointAtOwnCertificates(root);
|
|
26886
27346
|
env.vars.CLAUDE_CODE_GIT_BASH_PATH = bash;
|
|
26887
|
-
env.append.push(
|
|
27347
|
+
env.append.push(path24.join(root, "usr", "bin"));
|
|
26888
27348
|
const version2 = execOutput(gitExe, ["--version"]).replace(/^git version /, "");
|
|
26889
27349
|
if (access === "full") {
|
|
26890
|
-
env.prepend.push(
|
|
27350
|
+
env.prepend.push(path24.join(root, "cmd"));
|
|
26891
27351
|
env.summary.push("git: " + version2);
|
|
26892
27352
|
return;
|
|
26893
27353
|
}
|
|
@@ -26896,8 +27356,8 @@ var setupGit = async (env, hostCopy, refresh, access) => {
|
|
|
26896
27356
|
};
|
|
26897
27357
|
|
|
26898
27358
|
// src/guest/toolchains/go.ts
|
|
26899
|
-
import
|
|
26900
|
-
import
|
|
27359
|
+
import fs17 from "node:fs";
|
|
27360
|
+
import path25 from "node:path";
|
|
26901
27361
|
var findRelease = async (spec) => pickGoRelease(await fetchJson("https://go.dev/dl/?mode=json&include=all"), spec) ?? Promise.reject(new Error('No Go release matches "' + spec + '"'));
|
|
26902
27362
|
var setupGo = async (env, config2) => {
|
|
26903
27363
|
if (dryRun) {
|
|
@@ -26906,7 +27366,7 @@ var setupGo = async (env, config2) => {
|
|
|
26906
27366
|
}
|
|
26907
27367
|
const version2 = await resolveCached("go:" + config2.version, async () => (await findRelease(config2.version)).version);
|
|
26908
27368
|
const root = tool("go", version2);
|
|
26909
|
-
if (!exists(
|
|
27369
|
+
if (!exists(path25.join(root, "bin", "go.exe"))) {
|
|
26910
27370
|
const goArch = arch === "arm64" ? "arm64" : "amd64";
|
|
26911
27371
|
const file3 = (await findRelease(version2)).files.find((f) => f.os === "windows" && f.arch === goArch && f.kind === "archive");
|
|
26912
27372
|
if (!file3) throw new Error(version2 + " has no Windows " + goArch + " zip");
|
|
@@ -26914,18 +27374,18 @@ var setupGo = async (env, config2) => {
|
|
|
26914
27374
|
await installArchive("https://go.dev/dl/" + file3.filename, root, { sha256: file3.sha256, locate: "VERSION", fileName: file3.filename });
|
|
26915
27375
|
}
|
|
26916
27376
|
const GOPATH = tool("go-path");
|
|
26917
|
-
const vars = { GOROOT: root, GOPATH, GOBIN:
|
|
26918
|
-
|
|
27377
|
+
const vars = { GOROOT: root, GOPATH, GOBIN: path25.join(GOPATH, "bin"), GOMODCACHE: path25.join(GOPATH, "pkg", "mod"), GOCACHE: tool("go-cache"), GOTOOLCHAIN: "auto", GOTELEMETRY: "off" };
|
|
27378
|
+
fs17.mkdirSync(vars.GOBIN, { recursive: true });
|
|
26919
27379
|
Object.assign(env.vars, vars);
|
|
26920
|
-
env.prepend.push(
|
|
26921
|
-
const go =
|
|
27380
|
+
env.prepend.push(path25.join(root, "bin"), vars.GOBIN);
|
|
27381
|
+
const go = path25.join(root, "bin", "go.exe");
|
|
26922
27382
|
env.summary.push("go: " + versionOf(go, ["version"]));
|
|
26923
27383
|
await installOnce(env, "go", config2.tools, (pkg) => execAsync(go, ["install", pkg.includes("@") ? pkg : pkg + "@latest"], { env: { ...process.env, ...vars } }));
|
|
26924
27384
|
};
|
|
26925
27385
|
|
|
26926
27386
|
// src/guest/toolchains/cli.ts
|
|
26927
|
-
import
|
|
26928
|
-
import
|
|
27387
|
+
import fs18 from "node:fs";
|
|
27388
|
+
import path27 from "node:path";
|
|
26929
27389
|
|
|
26930
27390
|
// src/guest/toolchains/catalogue.ts
|
|
26931
27391
|
var pwshAsset = (arch2) => arch2 === "arm64" ? /^PowerShell-\d+\.\d+\.\d+-win-arm64\.zip$/ : /^PowerShell-\d+\.\d+\.\d+-win-x64\.zip$/;
|
|
@@ -26950,14 +27410,14 @@ var decideCli = (settings, ctx) => {
|
|
|
26950
27410
|
};
|
|
26951
27411
|
|
|
26952
27412
|
// src/guest/toolchains/runtimes.ts
|
|
26953
|
-
import
|
|
27413
|
+
import path26 from "node:path";
|
|
26954
27414
|
var setupSingleExe = async (env, name, repo, pattern, exeName, dir, options = {}) => {
|
|
26955
27415
|
if (dryRun) {
|
|
26956
27416
|
log("(dry run) would provision " + name);
|
|
26957
27417
|
return;
|
|
26958
27418
|
}
|
|
26959
|
-
const bin = options.subdir ?
|
|
26960
|
-
const exe =
|
|
27419
|
+
const bin = options.subdir ? path26.join(dir, options.subdir) : dir;
|
|
27420
|
+
const exe = path26.join(bin, exeName);
|
|
26961
27421
|
if (!exists(exe) || options.refresh) {
|
|
26962
27422
|
const size = options.size ? ", ~" + options.size : "";
|
|
26963
27423
|
await installFromGithub(repo, pattern, { dest: dir, what: (a) => name + " (" + a.name + size + " once)", ...options.subdir ? {} : { locate: exeName } });
|
|
@@ -26968,7 +27428,7 @@ var setupSingleExe = async (env, name, repo, pattern, exeName, dir, options = {}
|
|
|
26968
27428
|
};
|
|
26969
27429
|
var setupBun = async (env) => {
|
|
26970
27430
|
await setupSingleExe(env, "bun", "oven-sh/bun", arch === "arm64" ? /^bun-windows-aarch64\.zip$/ : /^bun-windows-x64\.zip$/, "bun.exe", tool("bun", "bin"), { size: "35 MB" });
|
|
26971
|
-
Object.assign(env.vars, { BUN_INSTALL: tool("bun"), BUN_INSTALL_CACHE_DIR:
|
|
27431
|
+
Object.assign(env.vars, { BUN_INSTALL: tool("bun"), BUN_INSTALL_CACHE_DIR: path26.join(localDir, "bun-cache"), BUN_TMPDIR: path26.join(localDir, "bun-tmp") });
|
|
26972
27432
|
};
|
|
26973
27433
|
var setupDeno = async (env) => {
|
|
26974
27434
|
await setupSingleExe(env, "deno", "denoland/deno", arch === "arm64" ? /^deno-aarch64-pc-windows-msvc[.]zip$/ : /^deno-x86_64-pc-windows-msvc[.]zip$/, "deno.exe", tool("deno", "bin"), { size: "40 MB" });
|
|
@@ -26982,7 +27442,7 @@ var setupUv = async (env) => {
|
|
|
26982
27442
|
};
|
|
26983
27443
|
|
|
26984
27444
|
// src/guest/toolchains/cli.ts
|
|
26985
|
-
var ghConfigDir = () =>
|
|
27445
|
+
var ghConfigDir = () => path27.join(stateDir, "gh");
|
|
26986
27446
|
var toolVars = {
|
|
26987
27447
|
gh: () => ({ GH_CONFIG_DIR: mkdirp(ghConfigDir()), GH_NO_UPDATE_NOTIFIER: "1", GH_NO_EXTENSION_UPDATE_NOTIFIER: "1" })
|
|
26988
27448
|
};
|
|
@@ -26992,16 +27452,16 @@ var shimOpenssl = (env) => {
|
|
|
26992
27452
|
return;
|
|
26993
27453
|
}
|
|
26994
27454
|
const shims = mkdirp(tool("shims"));
|
|
26995
|
-
|
|
26996
|
-
|
|
27455
|
+
fs18.copyFileSync(ensureCompiled("openssl"), path27.join(shims, "openssl.exe"));
|
|
27456
|
+
fs18.rmSync(path27.join(shims, "openssl.cmd"), { force: true });
|
|
26997
27457
|
env.prepend.push(shims);
|
|
26998
27458
|
env.summary.push("openssl: Git for Windows' copy");
|
|
26999
27459
|
};
|
|
27000
27460
|
var setupCli = async (env, settings, gitAccess, refresh = false) => {
|
|
27001
|
-
const decisions = decideCli(settings, { gitAccess, hasGithubDir: exists(
|
|
27461
|
+
const decisions = decideCli(settings, { gitAccess, hasGithubDir: exists(path27.join(projectWorkspace(), ".github")) });
|
|
27002
27462
|
if (settings.gh && !decisions.gh.on) {
|
|
27003
27463
|
env.summary.push("gh: off (" + decisions.gh.reason + ")");
|
|
27004
|
-
if (exists(
|
|
27464
|
+
if (exists(path27.join(ghConfigDir(), "hosts.yml"))) warn('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.");
|
|
27005
27465
|
}
|
|
27006
27466
|
if (dryRun) {
|
|
27007
27467
|
log("(dry run) would provision CLI tools: " + Object.entries(decisions).filter(([, d]) => d.on).map(([n]) => n).join(", "));
|
|
@@ -27029,11 +27489,11 @@ var setupCli = async (env, settings, gitAccess, refresh = false) => {
|
|
|
27029
27489
|
};
|
|
27030
27490
|
|
|
27031
27491
|
// src/guest/toolchains/managers.ts
|
|
27032
|
-
import
|
|
27033
|
-
import
|
|
27492
|
+
import fs19 from "node:fs";
|
|
27493
|
+
import path28 from "node:path";
|
|
27034
27494
|
var voltaPins = () => {
|
|
27035
27495
|
try {
|
|
27036
|
-
const pkg = JSON.parse(
|
|
27496
|
+
const pkg = JSON.parse(fs19.readFileSync(path28.join(projectWorkspace(), "package.json"), "utf8").replace(/^/, ""));
|
|
27037
27497
|
return Object.fromEntries(Object.entries(pkg.volta ?? {}).filter((e) => ["node", "npm", "yarn", "pnpm"].includes(e[0]) && typeof e[1] === "string"));
|
|
27038
27498
|
} catch {
|
|
27039
27499
|
return {};
|
|
@@ -27047,22 +27507,22 @@ var setupVolta = async (env) => {
|
|
|
27047
27507
|
return;
|
|
27048
27508
|
}
|
|
27049
27509
|
const dir = tool("volta");
|
|
27050
|
-
if (!exists(
|
|
27510
|
+
if (!exists(path28.join(dir, "volta.exe"))) {
|
|
27051
27511
|
const pattern = arch === "arm64" ? /^volta-[\d.]+-windows-arm64\.zip$/ : /^volta-[\d.]+-windows\.zip$/;
|
|
27052
27512
|
await installFromGithub("volta-cli/volta", pattern, { dest: dir, what: "Volta (~15 MB once)", locate: "volta.exe" });
|
|
27053
27513
|
}
|
|
27054
27514
|
for (const shim3 of ["node", "npm", "npx", "pnpm", "pnpx", "yarn", "yarnpkg"]) {
|
|
27055
|
-
const target =
|
|
27056
|
-
if (!exists(target))
|
|
27515
|
+
const target = path28.join(dir, shim3 + ".exe");
|
|
27516
|
+
if (!exists(target)) fs19.copyFileSync(path28.join(dir, "volta-shim.exe"), target);
|
|
27057
27517
|
}
|
|
27058
27518
|
const home = mkdirp(tool("volta-home"));
|
|
27059
|
-
const shims = mkdirp(
|
|
27519
|
+
const shims = mkdirp(path28.join(home, "bin"));
|
|
27060
27520
|
const vars = { VOLTA_HOME: home, VOLTA_FEATURE_PNPM: "1" };
|
|
27061
27521
|
Object.assign(env.vars, vars);
|
|
27062
27522
|
const pins = voltaPins();
|
|
27063
27523
|
if (Object.keys(pins).length) env.prepend.push(dir, shims);
|
|
27064
27524
|
else env.append.push(dir, shims);
|
|
27065
|
-
const volta =
|
|
27525
|
+
const volta = path28.join(dir, "volta.exe");
|
|
27066
27526
|
for (const [toolName, version2] of Object.entries(pins)) {
|
|
27067
27527
|
try {
|
|
27068
27528
|
await execAsync(volta, ["install", toolName + "@" + version2], { env: { ...process.env, ...vars }, cwd: projectWorkspace(), stdio: "ignore" });
|
|
@@ -27080,22 +27540,22 @@ var setupPyenv = async (env) => {
|
|
|
27080
27540
|
return;
|
|
27081
27541
|
}
|
|
27082
27542
|
const root = tool("pyenv", "pyenv-win");
|
|
27083
|
-
if (!exists(
|
|
27543
|
+
if (!exists(path28.join(root, "bin", "pyenv.bat"))) {
|
|
27084
27544
|
const tag = await resolveCached("pyenv-win", () => latestGithubTag("pyenv-win/pyenv-win"));
|
|
27085
27545
|
log("Downloading pyenv-win " + tag + " (~5 MB once) ...");
|
|
27086
27546
|
await installArchive("https://github.com/pyenv-win/pyenv-win/archive/refs/tags/" + encodeURIComponent(tag) + ".zip", root, { locate: "pyenv.bat", up: 1, fileName: "pyenv-win.zip" });
|
|
27087
27547
|
}
|
|
27088
|
-
const home = root +
|
|
27548
|
+
const home = root + path28.sep;
|
|
27089
27549
|
Object.assign(env.vars, { PYENV: home, PYENV_ROOT: home, PYENV_HOME: home });
|
|
27090
|
-
env.append.push(
|
|
27550
|
+
env.append.push(path28.join(root, "bin"), path28.join(root, "shims"));
|
|
27091
27551
|
env.summary.push("pyenv-win: pyenv install <version> / pyenv local <version> (versions persist)");
|
|
27092
27552
|
};
|
|
27093
27553
|
|
|
27094
27554
|
// src/guest/toolchains/native/cpp.ts
|
|
27095
|
-
import
|
|
27555
|
+
import path29 from "node:path";
|
|
27096
27556
|
var setupCpp = async (env, config2) => {
|
|
27097
27557
|
const bin = tool("mingw", "mingw64", "bin");
|
|
27098
|
-
const gcc =
|
|
27558
|
+
const gcc = path29.join(bin, "gcc.exe");
|
|
27099
27559
|
if (dryRun) {
|
|
27100
27560
|
log("(dry run) would provision MinGW-w64 GCC");
|
|
27101
27561
|
return;
|
|
@@ -27107,27 +27567,27 @@ var setupCpp = async (env, config2) => {
|
|
|
27107
27567
|
if (!exists(gcc)) throw new Error("gcc.exe missing after installing MinGW");
|
|
27108
27568
|
env.append.unshift(bin);
|
|
27109
27569
|
env.vars.CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER = gcc;
|
|
27110
|
-
const cmake = versionOf(
|
|
27570
|
+
const cmake = versionOf(path29.join(bin, "cmake.exe"));
|
|
27111
27571
|
if (cmakeTooOld(cmake)) warn("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.");
|
|
27112
27572
|
env.summary.push("gcc: " + versionOf(gcc) + " (MinGW-w64, with cmake " + cmake + ", ninja, premake5)");
|
|
27113
27573
|
if (config2.flexBison) await setupFlexBison(env);
|
|
27114
27574
|
};
|
|
27115
27575
|
var setupFlexBison = async (env) => {
|
|
27116
27576
|
const dir = tool("winflexbison");
|
|
27117
|
-
if (!exists(
|
|
27577
|
+
if (!exists(path29.join(dir, "win_bison.exe"))) {
|
|
27118
27578
|
await installFromGithub("lexxmark/winflexbison", /^win_flex_bison-[\d.]+\.zip$/, { dest: dir, what: "win_flex / win_bison (~1 MB once)", locate: "win_bison.exe" });
|
|
27119
27579
|
}
|
|
27120
27580
|
env.append.push(dir);
|
|
27121
|
-
env.summary.push("win_flex/win_bison: " + versionOf(
|
|
27581
|
+
env.summary.push("win_flex/win_bison: " + versionOf(path29.join(dir, "win_bison.exe")));
|
|
27122
27582
|
};
|
|
27123
27583
|
|
|
27124
27584
|
// src/guest/toolchains/native/dotnet.ts
|
|
27125
|
-
import
|
|
27126
|
-
import
|
|
27585
|
+
import fs20 from "node:fs";
|
|
27586
|
+
import path30 from "node:path";
|
|
27127
27587
|
var DotnetMarker = external_exports.record(external_exports.string(), external_exports.boolean());
|
|
27128
27588
|
var setupDotnet = async (env, config2, refresh) => {
|
|
27129
27589
|
const root = tool("dotnet");
|
|
27130
|
-
const marker =
|
|
27590
|
+
const marker = path30.join(root, ".agent-sandbox-installed.json");
|
|
27131
27591
|
const script = tool("dotnet-install.ps1");
|
|
27132
27592
|
if (dryRun) {
|
|
27133
27593
|
log("(dry run) would provision .NET SDK channels " + config2.channels.join(", "));
|
|
@@ -27135,10 +27595,10 @@ var setupDotnet = async (env, config2, refresh) => {
|
|
|
27135
27595
|
}
|
|
27136
27596
|
const recorded = DotnetMarker.safeParse(exists(marker) && !refresh ? readJsonFile(marker) : {});
|
|
27137
27597
|
const done = recorded.success ? recorded.data : {};
|
|
27138
|
-
const globalJson =
|
|
27598
|
+
const globalJson = path30.join(projectWorkspace(), "global.json");
|
|
27139
27599
|
const installs = [
|
|
27140
27600
|
...config2.channels.map((c) => ["channel:" + c, ["-Channel", c]]),
|
|
27141
|
-
...exists(globalJson) ? [["global.json:" +
|
|
27601
|
+
...exists(globalJson) ? [["global.json:" + fs20.readFileSync(globalJson, "utf8").replace(/\s+/g, ""), ["-JSonFile", globalJson]]] : []
|
|
27142
27602
|
];
|
|
27143
27603
|
for (const [key, args] of installs.filter(([k]) => !done[k])) {
|
|
27144
27604
|
await downloadFile("https://dot.net/v1/dotnet-install.ps1", script);
|
|
@@ -27149,10 +27609,10 @@ var setupDotnet = async (env, config2, refresh) => {
|
|
|
27149
27609
|
}
|
|
27150
27610
|
const home = mkdirp(tool("dotnet-home"));
|
|
27151
27611
|
Object.assign(env.vars, { DOTNET_ROOT: root, DOTNET_CLI_HOME: home, DOTNET_CLI_TELEMETRY_OPTOUT: "1", DOTNET_NOLOGO: "1", DOTNET_SKIP_FIRST_TIME_EXPERIENCE: "1", NUGET_PACKAGES: tool("nuget", "packages") });
|
|
27152
|
-
env.prepend.push(root,
|
|
27153
|
-
env.summary.push("dotnet: " + execOutput(
|
|
27154
|
-
const dotnet =
|
|
27155
|
-
const dotnetEnv = { env: { ...process.env, ...env.vars, PATH: root +
|
|
27612
|
+
env.prepend.push(root, path30.join(home, ".dotnet", "tools"));
|
|
27613
|
+
env.summary.push("dotnet: " + execOutput(path30.join(root, "dotnet.exe"), ["--list-sdks"]).split(/\r?\n/).map((l) => l.split(" ")[0]).filter(Boolean).join(", "));
|
|
27614
|
+
const dotnet = path30.join(root, "dotnet.exe");
|
|
27615
|
+
const dotnetEnv = { env: { ...process.env, ...env.vars, PATH: root + path30.delimiter + (process.env.PATH ?? "") } };
|
|
27156
27616
|
await installOnce(env, "dotnet workload", config2.workloads, (w) => execAsync(dotnet, ["workload", "install", w, "--skip-manifest-update"], dotnetEnv));
|
|
27157
27617
|
await installOnce(env, "dotnet tool", config2.tools, (t) => execAsync(dotnet, ["tool", "install", "--global", t], dotnetEnv));
|
|
27158
27618
|
await setupFrameworkReferences(env, config2.frameworkTargets);
|
|
@@ -27163,7 +27623,7 @@ var setupFrameworkReferences = async (env, targets) => {
|
|
|
27163
27623
|
const root = tool("netfx-references");
|
|
27164
27624
|
for (const target of targets) {
|
|
27165
27625
|
const id = "microsoft.netframework.referenceassemblies." + target.toLowerCase();
|
|
27166
|
-
const marker =
|
|
27626
|
+
const marker = path30.join(root, ".installed-" + target.toLowerCase());
|
|
27167
27627
|
if (exists(marker)) continue;
|
|
27168
27628
|
const staging = tool("netfx-references-" + target.toLowerCase());
|
|
27169
27629
|
try {
|
|
@@ -27172,17 +27632,17 @@ var setupFrameworkReferences = async (env, targets) => {
|
|
|
27172
27632
|
if (!version2) throw new Error("no stable version of " + id);
|
|
27173
27633
|
log("Downloading the .NET Framework " + target + " reference assemblies (~30 MB once) ...");
|
|
27174
27634
|
await installArchive("https://api.nuget.org/v3-flatcontainer/" + id + "/" + version2 + "/" + id + "." + version2 + ".nupkg", staging, { fileName: id + ".zip" });
|
|
27175
|
-
|
|
27176
|
-
|
|
27635
|
+
fs20.cpSync(path30.join(staging, "build", ".NETFramework"), path30.join(root, ".NETFramework"), { recursive: true });
|
|
27636
|
+
fs20.writeFileSync(marker, version2);
|
|
27177
27637
|
} catch (e) {
|
|
27178
27638
|
warn(".NET Framework " + target + " reference assemblies could not be installed (projects targeting it will not build): " + errMsg(e));
|
|
27179
27639
|
} finally {
|
|
27180
27640
|
safeRemove(staging, dataDir);
|
|
27181
27641
|
}
|
|
27182
27642
|
}
|
|
27183
|
-
if (!exists(
|
|
27184
|
-
env.vars.TargetFrameworkRootPath = root +
|
|
27185
|
-
env.summary.push(".NET Framework targeting: " +
|
|
27643
|
+
if (!exists(path30.join(root, ".NETFramework"))) return;
|
|
27644
|
+
env.vars.TargetFrameworkRootPath = root + path30.sep;
|
|
27645
|
+
env.summary.push(".NET Framework targeting: " + fs20.readdirSync(path30.join(root, ".NETFramework")).join(", "));
|
|
27186
27646
|
};
|
|
27187
27647
|
var setupNetFx35 = async (env) => {
|
|
27188
27648
|
if (execOutput(SYSTEM.reg(), ["query", "HKLM\\SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v3.5", "/v", "Install"]).includes("0x1")) {
|
|
@@ -27200,15 +27660,15 @@ var setupNetFx35 = async (env) => {
|
|
|
27200
27660
|
};
|
|
27201
27661
|
|
|
27202
27662
|
// src/guest/toolchains/native/mesa.ts
|
|
27203
|
-
import
|
|
27663
|
+
import path31 from "node:path";
|
|
27204
27664
|
var setupMesa = async (env, config2) => {
|
|
27205
27665
|
if (dryRun) {
|
|
27206
27666
|
log("(dry run) would provision Mesa 3D");
|
|
27207
27667
|
return;
|
|
27208
27668
|
}
|
|
27209
27669
|
const root = tool("mesa");
|
|
27210
|
-
const dir =
|
|
27211
|
-
if (!exists(
|
|
27670
|
+
const dir = path31.join(root, arch === "arm64" ? "arm64" : "x64");
|
|
27671
|
+
if (!exists(path31.join(dir, "opengl32.dll"))) {
|
|
27212
27672
|
await installFromGithub("pal1000/mesa-dist-win", /^mesa3d-[\d.]+-release-msvc\.7z$/, { dest: root, what: "Mesa 3D for software OpenGL (~100 MB once)", locate: "opengl32.dll", up: 1 });
|
|
27213
27673
|
}
|
|
27214
27674
|
Object.assign(env.vars, { MESA_DIR: dir, GALLIUM_DRIVER: "llvmpipe" });
|
|
@@ -27217,54 +27677,59 @@ var setupMesa = async (env, config2) => {
|
|
|
27217
27677
|
};
|
|
27218
27678
|
var VULKAN_RUNTIME = "https://sdk.lunarg.com/sdk/download/latest/windows/vulkan-runtime-components.zip";
|
|
27219
27679
|
var setupLavapipe = async (env, mesaDir) => {
|
|
27220
|
-
const icd =
|
|
27221
|
-
if (!exists(icd)) throw new Error("this Mesa build has no lavapipe (" +
|
|
27680
|
+
const icd = path31.join(mesaDir, arch === "arm64" ? "lvp_icd.aarch64.json" : "lvp_icd.x86_64.json");
|
|
27681
|
+
if (!exists(icd)) throw new Error("this Mesa build has no lavapipe (" + path31.basename(icd) + ")");
|
|
27222
27682
|
const dir = tool("vulkan");
|
|
27223
|
-
if (!exists(
|
|
27683
|
+
if (!exists(path31.join(dir, "vulkan-1.dll"))) {
|
|
27224
27684
|
log("Downloading the Vulkan loader (~10 MB once) ...");
|
|
27225
27685
|
await installArchive(VULKAN_RUNTIME, dir, { locate: "vulkan-1.dll", fileName: "vulkan-runtime.zip", members: ["*/x64/*"] });
|
|
27226
27686
|
}
|
|
27227
|
-
|
|
27687
|
+
const register = (file3) => execAsync(SYSTEM.reg(), ["add", "HKLM\\SOFTWARE\\Khronos\\Vulkan\\Drivers", "/v", file3, "/t", "REG_DWORD", "/d", "0", "/f"], { stdio: "ignore" });
|
|
27688
|
+
await register(icd);
|
|
27689
|
+
const dozen = path31.join(mesaDir, arch === "arm64" ? "dzn_icd.aarch64.json" : "dzn_icd.x86_64.json");
|
|
27690
|
+
const gpu = hasGpu();
|
|
27691
|
+
if (gpu && exists(dozen)) await register(dozen);
|
|
27228
27692
|
env.prepend.push(dir);
|
|
27229
|
-
env.summary.push("vulkan: lavapipe (software Vulkan 1.4 on the CPU), vulkaninfo on PATH; WGPU_BACKEND=vulkan for wgpu");
|
|
27693
|
+
env.summary.push("vulkan: " + (gpu && exists(dozen) ? "Dozen (Vulkan on the GPU via Direct3D 12) and " : "") + "lavapipe (software Vulkan 1.4 on the CPU), vulkaninfo on PATH; WGPU_BACKEND=vulkan for wgpu");
|
|
27230
27694
|
};
|
|
27695
|
+
var hasGpu = () => execOutput(SYSTEM.powershell(), ["-NoProfile", "-NonInteractive", "-Command", "(Get-CimInstance Win32_VideoController).Name"], { timeout: 3e4 }).split(/\r?\n/).map((n) => n.trim()).some((n) => n && !/^Microsoft (Remote Display|Basic (Render|Display))/i.test(n));
|
|
27231
27696
|
|
|
27232
27697
|
// src/guest/toolchains/native/msvc/index.ts
|
|
27233
|
-
import
|
|
27234
|
-
import
|
|
27698
|
+
import fs24 from "node:fs";
|
|
27699
|
+
import path35 from "node:path";
|
|
27235
27700
|
|
|
27236
27701
|
// src/guest/toolchains/native/msvc/environment.ts
|
|
27237
|
-
import
|
|
27238
|
-
import
|
|
27702
|
+
import fs22 from "node:fs";
|
|
27703
|
+
import path33 from "node:path";
|
|
27239
27704
|
|
|
27240
27705
|
// src/guest/toolchains/native/msvc/tree.ts
|
|
27241
|
-
import
|
|
27242
|
-
import
|
|
27706
|
+
import fs21 from "node:fs";
|
|
27707
|
+
import path32 from "node:path";
|
|
27243
27708
|
var ROOT = tool("msvc");
|
|
27244
|
-
var
|
|
27245
|
-
var msvcTools = (msvc, ...parts) =>
|
|
27709
|
+
var MARKER2 = path32.join(ROOT, ".installed.json");
|
|
27710
|
+
var msvcTools = (msvc, ...parts) => path32.join(ROOT, "VC", "Tools", "MSVC", msvc, ...parts);
|
|
27246
27711
|
var hostBin = (msvc, ...parts) => msvcTools(msvc, "bin", "Hostx64", "x64", ...parts);
|
|
27247
27712
|
var hasCompiler = (msvc) => exists(hostBin(msvc, "cl.exe"));
|
|
27248
27713
|
var Installed = external_exports.object({ msvc: external_exports.string().min(1), sdk: external_exports.string().min(1), want: external_exports.string() });
|
|
27249
27714
|
var readInstalled = () => {
|
|
27250
27715
|
try {
|
|
27251
|
-
return Installed.safeParse(JSON.parse(
|
|
27716
|
+
return Installed.safeParse(JSON.parse(fs21.readFileSync(MARKER2, "utf8"))).data ?? null;
|
|
27252
27717
|
} catch {
|
|
27253
27718
|
return null;
|
|
27254
27719
|
}
|
|
27255
27720
|
};
|
|
27256
27721
|
|
|
27257
27722
|
// src/guest/toolchains/native/msvc/environment.ts
|
|
27258
|
-
var VSWHERE_DIR =
|
|
27723
|
+
var VSWHERE_DIR = path33.join(process.env["ProgramFiles(x86)"] ?? "C:\\Program Files (x86)", "Microsoft Visual Studio", "Installer");
|
|
27259
27724
|
var vcvars = (root, msvc, sdk) => {
|
|
27260
|
-
const vc =
|
|
27261
|
-
const kits =
|
|
27262
|
-
const inc = (...p) =>
|
|
27263
|
-
const lib = (...p) =>
|
|
27725
|
+
const vc = path33.join(root, "VC", "Tools", "MSVC", msvc);
|
|
27726
|
+
const kits = path33.join(root, "Windows Kits", "10");
|
|
27727
|
+
const inc = (...p) => path33.join(kits, "Include", sdk, ...p);
|
|
27728
|
+
const lib = (...p) => path33.join(kits, "Lib", sdk, ...p);
|
|
27264
27729
|
return {
|
|
27265
27730
|
vars: {
|
|
27266
27731
|
VSINSTALLDIR: root + "\\",
|
|
27267
|
-
VCINSTALLDIR:
|
|
27732
|
+
VCINSTALLDIR: path33.join(root, "VC") + "\\",
|
|
27268
27733
|
VCToolsInstallDir: vc + "\\",
|
|
27269
27734
|
VCToolsVersion: msvc,
|
|
27270
27735
|
VisualStudioVersion: "17.0",
|
|
@@ -27276,15 +27741,15 @@ var vcvars = (root, msvc, sdk) => {
|
|
|
27276
27741
|
VSCMD_ARG_HOST_ARCH: "x64",
|
|
27277
27742
|
VSCMD_ARG_TGT_ARCH: "x64",
|
|
27278
27743
|
Platform: "x64",
|
|
27279
|
-
INCLUDE: [
|
|
27280
|
-
LIB: [
|
|
27281
|
-
LIBPATH: [
|
|
27744
|
+
INCLUDE: [path33.join(vc, "include"), inc("ucrt"), inc("shared"), inc("um"), inc("winrt"), inc("cppwinrt")].join(";"),
|
|
27745
|
+
LIB: [path33.join(vc, "lib", "x64"), lib("ucrt", "x64"), lib("um", "x64")].join(";"),
|
|
27746
|
+
LIBPATH: [path33.join(vc, "lib", "x64"), path33.join(vc, "lib", "x86", "store", "references")].join(";")
|
|
27282
27747
|
},
|
|
27283
|
-
path: [
|
|
27748
|
+
path: [path33.join(vc, "bin", "Hostx64", "x64"), path33.join(kits, "bin", sdk, "x64")]
|
|
27284
27749
|
};
|
|
27285
27750
|
};
|
|
27286
27751
|
var writeVcvars = (env) => {
|
|
27287
|
-
const dir = mkdirp(
|
|
27752
|
+
const dir = mkdirp(path33.join(ROOT, "VC", "Auxiliary", "Build"));
|
|
27288
27753
|
const lines = [
|
|
27289
27754
|
"@echo off",
|
|
27290
27755
|
"rem Written by Windows Development Sandbox for its portable MSVC (host x64, target x64).",
|
|
@@ -27292,26 +27757,26 @@ var writeVcvars = (env) => {
|
|
|
27292
27757
|
'set "PATH=' + env.path.join(";") + ';%PATH%"',
|
|
27293
27758
|
"exit /b 0"
|
|
27294
27759
|
];
|
|
27295
|
-
|
|
27296
|
-
|
|
27760
|
+
fs22.writeFileSync(path33.join(dir, "vcvars64.bat"), lines.join("\r\n") + "\r\n");
|
|
27761
|
+
fs22.writeFileSync(path33.join(dir, "vcvarsall.bat"), ["@echo off", "rem Only x64 (amd64) is installed.", 'call "%~dp0vcvars64.bat"', "exit /b %errorlevel%"].join("\r\n") + "\r\n");
|
|
27297
27762
|
};
|
|
27298
27763
|
var installVswhere = (msvc) => {
|
|
27299
27764
|
mkdirp(VSWHERE_DIR);
|
|
27300
|
-
|
|
27765
|
+
fs22.copyFileSync(ensureCompiled("vswhere"), path33.join(VSWHERE_DIR, "vswhere.exe"));
|
|
27301
27766
|
const [major, minor] = msvc.split(".").slice(2);
|
|
27302
|
-
|
|
27767
|
+
fs22.writeFileSync(path33.join(VSWHERE_DIR, "vswhere.json"), JSON.stringify({ installationPath: ROOT, installationVersion: "17." + (minor ?? "0") + ".0." + (major ?? "0") }));
|
|
27303
27768
|
};
|
|
27304
27769
|
var removeTelemetry = (msvc) => {
|
|
27305
27770
|
try {
|
|
27306
|
-
|
|
27771
|
+
fs22.rmSync(hostBin(msvc, "vctip.exe"), { force: true });
|
|
27307
27772
|
} catch (e) {
|
|
27308
27773
|
warn("Could not remove MSVC's telemetry helper (vctip.exe); it may keep tools\\msvc locked: " + errMsg(e));
|
|
27309
27774
|
}
|
|
27310
27775
|
};
|
|
27311
27776
|
|
|
27312
27777
|
// src/guest/toolchains/native/msvc/packages.ts
|
|
27313
|
-
import
|
|
27314
|
-
import
|
|
27778
|
+
import fs23 from "node:fs";
|
|
27779
|
+
import path34 from "node:path";
|
|
27315
27780
|
var CHANNEL = "https://aka.ms/vs/17/release/channel";
|
|
27316
27781
|
var MANIFEST_DAY_MS = 24 * 60 * 60 * 1e3;
|
|
27317
27782
|
var MSVC_PARTS = ["tools.hostx64.targetx64.base", "tools.hostx64.targetx64.res.base", "crt.headers.base", "crt.x64.desktop.base", "crt.x64.store.base", "crt.source.base", "asan.headers.base", "pgo.headers.base"];
|
|
@@ -27328,10 +27793,10 @@ var SDK_MSIS = [
|
|
|
27328
27793
|
"Windows SDK Desktop Tools x64-x86_en-us.msi"
|
|
27329
27794
|
];
|
|
27330
27795
|
var manifest = async () => {
|
|
27331
|
-
const cached2 =
|
|
27332
|
-
if (exists(cached2) && Date.now() -
|
|
27796
|
+
const cached2 = path34.join(ROOT, ".manifest.json");
|
|
27797
|
+
if (exists(cached2) && Date.now() - fs23.statSync(cached2).mtimeMs < MANIFEST_DAY_MS) {
|
|
27333
27798
|
try {
|
|
27334
|
-
return JSON.parse(
|
|
27799
|
+
return JSON.parse(fs23.readFileSync(cached2, "utf8"));
|
|
27335
27800
|
} catch {
|
|
27336
27801
|
}
|
|
27337
27802
|
}
|
|
@@ -27340,26 +27805,26 @@ var manifest = async () => {
|
|
|
27340
27805
|
if (!item) throw new Error("the Visual Studio channel has no package manifest");
|
|
27341
27806
|
mkdirp(ROOT);
|
|
27342
27807
|
await download(item.url, cached2);
|
|
27343
|
-
return JSON.parse(
|
|
27808
|
+
return JSON.parse(fs23.readFileSync(cached2, "utf8"));
|
|
27344
27809
|
};
|
|
27345
27810
|
var unpackVsix = async (vsix, work) => {
|
|
27346
|
-
const out = mkdirp(
|
|
27811
|
+
const out = mkdirp(path34.join(work, "vsix-" + path34.basename(vsix)));
|
|
27347
27812
|
await extractArchive(vsix, out, ["Contents"]);
|
|
27348
|
-
const
|
|
27349
|
-
for (const entry of
|
|
27350
|
-
const from =
|
|
27813
|
+
const decode4 = (dir) => {
|
|
27814
|
+
for (const entry of fs23.readdirSync(dir, { withFileTypes: true })) {
|
|
27815
|
+
const from = path34.join(dir, entry.name);
|
|
27351
27816
|
let name = entry.name;
|
|
27352
27817
|
try {
|
|
27353
27818
|
if (name.includes("%")) name = decodeURIComponent(name);
|
|
27354
27819
|
} catch {
|
|
27355
27820
|
}
|
|
27356
|
-
const to =
|
|
27357
|
-
if (to !== from)
|
|
27358
|
-
if (entry.isDirectory())
|
|
27821
|
+
const to = path34.join(dir, name);
|
|
27822
|
+
if (to !== from) fs23.renameSync(from, to);
|
|
27823
|
+
if (entry.isDirectory()) decode4(to);
|
|
27359
27824
|
}
|
|
27360
27825
|
};
|
|
27361
|
-
|
|
27362
|
-
|
|
27826
|
+
decode4(out);
|
|
27827
|
+
fs23.cpSync(path34.join(out, "Contents"), ROOT, { recursive: true, force: true });
|
|
27363
27828
|
safeRemove(out, work);
|
|
27364
27829
|
};
|
|
27365
27830
|
var unpackMsi = async (msi) => {
|
|
@@ -27367,8 +27832,8 @@ var unpackMsi = async (msi) => {
|
|
|
27367
27832
|
try {
|
|
27368
27833
|
await execAsync(system32("msiexec.exe"), ["/a", msi, "/quiet", "/qn", "TARGETDIR=" + ROOT, "/l*v", logFile2], { stdio: "ignore" });
|
|
27369
27834
|
} catch (e) {
|
|
27370
|
-
const lines = exists(logFile2) ?
|
|
27371
|
-
throw new Error(
|
|
27835
|
+
const lines = exists(logFile2) ? fs23.readFileSync(logFile2, "utf16le").split(/\r?\n/).filter((l) => /error|return value 3|failed/i.test(l)).slice(-4).join(" | ") : "";
|
|
27836
|
+
throw new Error(path34.basename(msi) + " did not unpack: " + (e instanceof Error ? e.message : String(e)) + (lines ? " (" + lines.slice(0, 600) + ")" : ""));
|
|
27372
27837
|
}
|
|
27373
27838
|
};
|
|
27374
27839
|
var catalogue = (m) => {
|
|
@@ -27380,13 +27845,13 @@ var catalogue = (m) => {
|
|
|
27380
27845
|
};
|
|
27381
27846
|
};
|
|
27382
27847
|
var payloadFetcher = (work) => async (p) => {
|
|
27383
|
-
const file3 =
|
|
27848
|
+
const file3 = path34.join(work, path34.basename(p.fileName.replace(/\\/g, "/")));
|
|
27384
27849
|
if (!exists(file3)) await download(p.url, file3, p.sha256);
|
|
27385
27850
|
return file3;
|
|
27386
27851
|
};
|
|
27387
27852
|
var unpackedToolset = () => {
|
|
27388
|
-
const toolsRoot =
|
|
27389
|
-
return
|
|
27853
|
+
const toolsRoot = path34.join(ROOT, "VC", "Tools", "MSVC");
|
|
27854
|
+
return fs23.readdirSync(toolsRoot).filter((d) => exists(hostBin(d, "cl.exe"))).sort((a, b) => a.localeCompare(b, void 0, { numeric: true })).pop();
|
|
27390
27855
|
};
|
|
27391
27856
|
var installPackages = async (config2) => {
|
|
27392
27857
|
const { ids, pick: pick2 } = catalogue(await manifest());
|
|
@@ -27394,7 +27859,7 @@ var installPackages = async (config2) => {
|
|
|
27394
27859
|
if (!version2) throw new Error("no MSVC " + config2.msvcVersion + " in the Visual Studio manifest");
|
|
27395
27860
|
const sdk = pickWindowsSdk(ids, config2.sdkVersion);
|
|
27396
27861
|
if (!sdk) throw new Error("no Windows SDK " + config2.sdkVersion + " in the Visual Studio manifest");
|
|
27397
|
-
const work = mkdirp(
|
|
27862
|
+
const work = mkdirp(path34.join(ROOT, ".download"));
|
|
27398
27863
|
const fetchPayload = payloadFetcher(work);
|
|
27399
27864
|
log("Downloading the MSVC " + version2 + " compiler and C/C++ libraries ...");
|
|
27400
27865
|
for (const part of MSVC_PARTS) {
|
|
@@ -27413,16 +27878,16 @@ var installPackages = async (config2) => {
|
|
|
27413
27878
|
if (!p) throw new Error("the Windows SDK package has no " + name);
|
|
27414
27879
|
const file3 = await fetchPayload(p);
|
|
27415
27880
|
msis.push(file3);
|
|
27416
|
-
for (const cab of msiCabs(
|
|
27881
|
+
for (const cab of msiCabs(fs23.readFileSync(file3))) {
|
|
27417
27882
|
const c = payload(cab);
|
|
27418
27883
|
if (c) await fetchPayload(c);
|
|
27419
27884
|
}
|
|
27420
27885
|
}
|
|
27421
27886
|
log("Unpacking the Windows SDK (a few minutes) ...");
|
|
27422
27887
|
for (const msi of msis) await unpackMsi(msi);
|
|
27423
|
-
for (const name of
|
|
27888
|
+
for (const name of fs23.readdirSync(ROOT).filter((n) => n.toLowerCase().endsWith(".msi"))) fs23.rmSync(path34.join(ROOT, name), { force: true });
|
|
27424
27889
|
safeRemove(work, ROOT);
|
|
27425
|
-
const sdkVersion =
|
|
27890
|
+
const sdkVersion = fs23.readdirSync(path34.join(ROOT, "Windows Kits", "10", "Include")).filter((d) => d.startsWith("10.0." + sdk.build)).sort().pop();
|
|
27426
27891
|
if (!sdkVersion) throw new Error("the Windows SDK did not unpack (no Include\\10.0." + sdk.build + ".*)");
|
|
27427
27892
|
const toolset = unpackedToolset();
|
|
27428
27893
|
if (!toolset) throw new Error("MSVC " + version2 + " did not unpack (no cl.exe under VC\\Tools\\MSVC)");
|
|
@@ -27436,7 +27901,7 @@ var installedMsvcEnv = () => {
|
|
|
27436
27901
|
};
|
|
27437
27902
|
var clearTree = () => {
|
|
27438
27903
|
if (!exists(ROOT)) return;
|
|
27439
|
-
for (const name of
|
|
27904
|
+
for (const name of fs24.readdirSync(ROOT).filter((n) => n !== ".manifest.json" && n !== ".download")) safeRemove(path35.join(ROOT, name), ROOT);
|
|
27440
27905
|
};
|
|
27441
27906
|
var setupMsvc = async (env, config2) => {
|
|
27442
27907
|
if (!config2.acceptLicense) {
|
|
@@ -27452,7 +27917,7 @@ var setupMsvc = async (env, config2) => {
|
|
|
27452
27917
|
log("Installing MSVC and the Windows SDK (~1-2 GB, once; licence accepted in toolchains.msvc.acceptLicense) ...");
|
|
27453
27918
|
clearTree();
|
|
27454
27919
|
done = { ...await installPackages(config2), want };
|
|
27455
|
-
writeJsonAtomic(
|
|
27920
|
+
writeJsonAtomic(MARKER2, done);
|
|
27456
27921
|
}
|
|
27457
27922
|
removeTelemetry(done.msvc);
|
|
27458
27923
|
const vc = vcvars(ROOT, done.msvc, done.sdk);
|
|
@@ -27464,20 +27929,20 @@ var setupMsvc = async (env, config2) => {
|
|
|
27464
27929
|
};
|
|
27465
27930
|
|
|
27466
27931
|
// src/guest/toolchains/native/rust.ts
|
|
27467
|
-
import
|
|
27932
|
+
import path37 from "node:path";
|
|
27468
27933
|
|
|
27469
27934
|
// src/guest/toolchains/native/binstall.ts
|
|
27470
|
-
import
|
|
27471
|
-
import
|
|
27935
|
+
import fs25 from "node:fs";
|
|
27936
|
+
import path36 from "node:path";
|
|
27472
27937
|
var ensureBinstall = async (cargoBin) => {
|
|
27473
|
-
const target =
|
|
27938
|
+
const target = path36.join(cargoBin, "cargo-binstall.exe");
|
|
27474
27939
|
if (exists(target)) return true;
|
|
27475
27940
|
try {
|
|
27476
27941
|
const dir = tool("cargo-binstall");
|
|
27477
|
-
if (!exists(
|
|
27942
|
+
if (!exists(path36.join(dir, "cargo-binstall.exe"))) {
|
|
27478
27943
|
await installFromGithub("cargo-bins/cargo-binstall", binstallAsset(arch), { dest: dir, what: "cargo-binstall for prebuilt Rust tools (~10 MB once)", locate: "cargo-binstall.exe" });
|
|
27479
27944
|
}
|
|
27480
|
-
|
|
27945
|
+
fs25.copyFileSync(path36.join(dir, "cargo-binstall.exe"), target);
|
|
27481
27946
|
return true;
|
|
27482
27947
|
} catch (e) {
|
|
27483
27948
|
warn("cargo-binstall unavailable, compiling crates with cargo install instead: " + errMsg(e));
|
|
@@ -27485,11 +27950,11 @@ var ensureBinstall = async (cargoBin) => {
|
|
|
27485
27950
|
}
|
|
27486
27951
|
};
|
|
27487
27952
|
var crateInstaller = (cargoHome, cargoEnv) => {
|
|
27488
|
-
const cargo =
|
|
27953
|
+
const cargo = path36.join(cargoHome, "bin", "cargo.exe");
|
|
27489
27954
|
let binstall = null;
|
|
27490
27955
|
const binstallEnv = { ...cargoEnv, env: { ...cargoEnv.env ?? process.env, BINSTALL_DISABLE_TELEMETRY: "true" } };
|
|
27491
27956
|
return async (crate) => {
|
|
27492
|
-
binstall ??= ensureBinstall(
|
|
27957
|
+
binstall ??= ensureBinstall(path36.join(cargoHome, "bin"));
|
|
27493
27958
|
if (await binstall) {
|
|
27494
27959
|
try {
|
|
27495
27960
|
await execAsync(cargo, ["binstall", "--no-confirm", "--locked", "--disable-strategies", "compile", crate], binstallEnv);
|
|
@@ -27507,7 +27972,7 @@ var setupRust = async (env, config2, refresh) => {
|
|
|
27507
27972
|
const RUSTUP_HOME = tool("rust", "rustup");
|
|
27508
27973
|
const CARGO_HOME = tool("rust", "cargo");
|
|
27509
27974
|
const rustEnv = { env: { ...process.env, RUSTUP_HOME, CARGO_HOME } };
|
|
27510
|
-
const rustup =
|
|
27975
|
+
const rustup = path37.join(CARGO_HOME, "bin", "rustup.exe");
|
|
27511
27976
|
if (dryRun) {
|
|
27512
27977
|
log("(dry run) would provision Rust " + config2.toolchain + " (" + config2.host + ")");
|
|
27513
27978
|
return;
|
|
@@ -27524,35 +27989,35 @@ var setupRust = async (env, config2, refresh) => {
|
|
|
27524
27989
|
if (refresh) await execAsync(rustup, ["update"], rustEnv);
|
|
27525
27990
|
}
|
|
27526
27991
|
Object.assign(env.vars, { RUSTUP_HOME, CARGO_HOME });
|
|
27527
|
-
env.prepend.push(
|
|
27528
|
-
env.summary.push("rust: " + versionOf(
|
|
27992
|
+
env.prepend.push(path37.join(CARGO_HOME, "bin"));
|
|
27993
|
+
env.summary.push("rust: " + versionOf(path37.join(CARGO_HOME, "bin", "rustc.exe"), ["--version"], rustEnv) + " [" + config2.host + "]");
|
|
27529
27994
|
const toolchainKey = "rustup@" + config2.toolchain;
|
|
27530
27995
|
await installOnce(env, toolchainKey + " components", config2.components, (c) => execAsync(rustup, ["component", "add", c], rustEnv));
|
|
27531
27996
|
await installOnce(env, toolchainKey + " targets", config2.targets, (t) => execAsync(rustup, ["target", "add", t], rustEnv));
|
|
27532
27997
|
const msvc = config2.host.endsWith("-msvc") ? installedMsvcEnv() : null;
|
|
27533
27998
|
const mingw = tool("mingw", "mingw64", "bin");
|
|
27534
|
-
const cargoEnv = msvc ? { env: { ...rustEnv.env, ...msvc.vars, PATH: [
|
|
27999
|
+
const cargoEnv = msvc ? { env: { ...rustEnv.env, ...msvc.vars, PATH: [path37.join(CARGO_HOME, "bin"), ...msvc.path, process.env.PATH ?? ""].join(path37.delimiter) } } : { env: { ...rustEnv.env, CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER: path37.join(mingw, "gcc.exe"), PATH: [path37.join(CARGO_HOME, "bin"), mingw, process.env.PATH ?? ""].join(path37.delimiter) } };
|
|
27535
28000
|
await installOnce(env, "cargo", config2.crates, crateInstaller(CARGO_HOME, cargoEnv));
|
|
27536
28001
|
};
|
|
27537
28002
|
|
|
27538
28003
|
// src/guest/toolchains/node.ts
|
|
27539
|
-
import
|
|
27540
|
-
import
|
|
28004
|
+
import fs26 from "node:fs";
|
|
28005
|
+
import path38 from "node:path";
|
|
27541
28006
|
import { spawn as spawn4 } from "node:child_process";
|
|
27542
28007
|
var NVM_HOME = tool("nvm");
|
|
27543
|
-
var NVM_SYMLINK =
|
|
27544
|
-
var HOST_NVM =
|
|
28008
|
+
var NVM_SYMLINK = path38.join(localDir, "nodejs");
|
|
28009
|
+
var HOST_NVM = path38.join(hostToolsDir, "nvm");
|
|
27545
28010
|
var HOST_VERSIONS_MAX = 3;
|
|
27546
|
-
var hostNvmVersions = () => exists(HOST_NVM) ?
|
|
28011
|
+
var hostNvmVersions = () => exists(HOST_NVM) ? fs26.readdirSync(HOST_NVM).filter((d) => /^v\d+\.\d+\.\d+$/.test(d) && exists(path38.join(HOST_NVM, d, "node.exe"))).map((d) => d.slice(1)) : [];
|
|
27547
28012
|
var resolveNode = (spec) => resolveCached("node:" + spec, async () => {
|
|
27548
28013
|
const exact = spec.replace(/^v/, "");
|
|
27549
28014
|
if (/^\d+\.\d+\.\d+$/.test(exact)) return exact;
|
|
27550
28015
|
const releases = await fetchJson("https://nodejs.org/dist/index.json");
|
|
27551
28016
|
return pickNodeVersion(releases, spec) ?? Promise.reject(new Error('No Node.js release matches "' + spec + '"'));
|
|
27552
28017
|
});
|
|
27553
|
-
var NVM_TEMP =
|
|
27554
|
-
var nvm = (args) => new Promise((
|
|
27555
|
-
const child = spawn4(
|
|
28018
|
+
var NVM_TEMP = path38.join(NVM_HOME, ".tmp");
|
|
28019
|
+
var nvm = (args) => new Promise((resolve2) => {
|
|
28020
|
+
const child = spawn4(path38.join(NVM_HOME, "nvm.exe"), args, { windowsHide: true, env: { ...process.env, NVM_HOME, NVM_SYMLINK, TEMP: NVM_TEMP, TMP: NVM_TEMP } });
|
|
27556
28021
|
let out = "";
|
|
27557
28022
|
child.stdout.on("data", (d) => {
|
|
27558
28023
|
out += d.toString();
|
|
@@ -27560,16 +28025,16 @@ var nvm = (args) => new Promise((resolve) => {
|
|
|
27560
28025
|
child.stderr.on("data", (d) => {
|
|
27561
28026
|
out += d.toString();
|
|
27562
28027
|
});
|
|
27563
|
-
child.once("error", (e) =>
|
|
27564
|
-
child.once("close", () =>
|
|
28028
|
+
child.once("error", (e) => resolve2(out + e.message));
|
|
28029
|
+
child.once("close", () => resolve2(out));
|
|
27565
28030
|
});
|
|
27566
28031
|
var ensureNvm = async () => {
|
|
27567
|
-
if (exists(
|
|
27568
|
-
if (exists(
|
|
28032
|
+
if (exists(path38.join(NVM_HOME, "nvm.exe"))) return;
|
|
28033
|
+
if (exists(path38.join(HOST_NVM, "nvm.exe"))) {
|
|
27569
28034
|
log("Copying nvm from this PC ...");
|
|
27570
28035
|
mkdirp(NVM_HOME);
|
|
27571
|
-
const files =
|
|
27572
|
-
for (const file3 of files)
|
|
28036
|
+
const files = fs26.readdirSync(HOST_NVM).filter((f) => /\.(exe|cmd|vbs)$/i.test(f)).sort((a, b) => Number(a.toLowerCase() === "nvm.exe") - Number(b.toLowerCase() === "nvm.exe"));
|
|
28037
|
+
for (const file3 of files) fs26.copyFileSync(path38.join(HOST_NVM, file3), path38.join(NVM_HOME, file3));
|
|
27573
28038
|
return;
|
|
27574
28039
|
}
|
|
27575
28040
|
const asset = await githubAsset("coreybutler/nvm-windows", /^nvm-noinstall\.zip$/, true);
|
|
@@ -27577,10 +28042,10 @@ var ensureNvm = async () => {
|
|
|
27577
28042
|
await installArchive(asset.url, NVM_HOME, { sha256: asset.sha256, locate: "nvm.exe", fileName: asset.name });
|
|
27578
28043
|
};
|
|
27579
28044
|
var installNodeVersion = async (version2) => {
|
|
27580
|
-
const dir =
|
|
27581
|
-
const fromHost =
|
|
27582
|
-
if (exists(
|
|
27583
|
-
if (exists(
|
|
28045
|
+
const dir = path38.join(NVM_HOME, "v" + version2);
|
|
28046
|
+
const fromHost = path38.join(HOST_NVM, "v" + version2);
|
|
28047
|
+
if (exists(path38.join(dir, "node.exe"))) return;
|
|
28048
|
+
if (exists(path38.join(fromHost, "node.exe"))) {
|
|
27584
28049
|
log("Copying Node " + version2 + " from this PC's nvm (without global packages) ...");
|
|
27585
28050
|
copyNode(fromHost, dir);
|
|
27586
28051
|
return;
|
|
@@ -27593,13 +28058,13 @@ var installNodeVersion = async (version2) => {
|
|
|
27593
28058
|
} finally {
|
|
27594
28059
|
safeRemove(NVM_TEMP, NVM_HOME);
|
|
27595
28060
|
}
|
|
27596
|
-
if (!exists(
|
|
28061
|
+
if (!exists(path38.join(dir, "node.exe"))) throw new Error("nvm install " + version2 + " failed: " + out.trim().split("\n").slice(-2).join(" "));
|
|
27597
28062
|
};
|
|
27598
28063
|
var activate = async (version2) => {
|
|
27599
28064
|
await nvm(["use", version2]);
|
|
27600
|
-
if (exists(
|
|
27601
|
-
|
|
27602
|
-
|
|
28065
|
+
if (exists(path38.join(NVM_SYMLINK, "node.exe"))) return;
|
|
28066
|
+
fs26.rmSync(NVM_SYMLINK, { recursive: true, force: true });
|
|
28067
|
+
fs26.symlinkSync(path38.join(NVM_HOME, "v" + version2), NVM_SYMLINK, "junction");
|
|
27603
28068
|
};
|
|
27604
28069
|
var setupNode = async (env, versions, config2) => {
|
|
27605
28070
|
if (dryRun) {
|
|
@@ -27607,7 +28072,7 @@ var setupNode = async (env, versions, config2) => {
|
|
|
27607
28072
|
return;
|
|
27608
28073
|
}
|
|
27609
28074
|
await ensureNvm();
|
|
27610
|
-
|
|
28075
|
+
fs26.writeFileSync(path38.join(NVM_HOME, "settings.txt"), ["root: " + NVM_HOME, "path: " + NVM_SYMLINK, "arch: " + (arch === "arm64" ? "arm64" : "64"), "proxy: none", ""].join("\r\n"));
|
|
27611
28076
|
mkdirp(localDir);
|
|
27612
28077
|
for (const extra of versions.nodeExtra) {
|
|
27613
28078
|
try {
|
|
@@ -27626,7 +28091,7 @@ var setupNode = async (env, versions, config2) => {
|
|
|
27626
28091
|
}
|
|
27627
28092
|
}
|
|
27628
28093
|
Object.assign(env.vars, { NVM_HOME, NVM_SYMLINK });
|
|
27629
|
-
if (duringSession()) env.prepend.push(
|
|
28094
|
+
if (duringSession()) env.prepend.push(path38.join(NVM_HOME, "v" + main), NVM_HOME, NVM_SYMLINK);
|
|
27630
28095
|
else {
|
|
27631
28096
|
await activate(main);
|
|
27632
28097
|
env.prepend.push(NVM_HOME, NVM_SYMLINK);
|
|
@@ -27635,10 +28100,10 @@ var setupNode = async (env, versions, config2) => {
|
|
|
27635
28100
|
await packageManagers(env, config2, main);
|
|
27636
28101
|
};
|
|
27637
28102
|
var packageManagers = async (env, config2, version2) => {
|
|
27638
|
-
const dir =
|
|
27639
|
-
const nodeEnv = { ...process.env, PATH: dir +
|
|
27640
|
-
const npm = (args) => execAsync(
|
|
27641
|
-
const corepackJs =
|
|
28103
|
+
const dir = path38.join(NVM_HOME, "v" + version2);
|
|
28104
|
+
const nodeEnv = { ...process.env, PATH: dir + path38.delimiter + (process.env.PATH ?? "") };
|
|
28105
|
+
const npm = (args) => execAsync(path38.join(dir, "node.exe"), [path38.join(dir, "node_modules", "npm", "bin", "npm-cli.js"), ...args], { env: nodeEnv, stdio: "ignore" });
|
|
28106
|
+
const corepackJs = path38.join(dir, "node_modules", "corepack", "dist", "corepack.js");
|
|
27642
28107
|
const extra = config2.corepack && !exists(corepackJs) ? ["corepack"] : [];
|
|
27643
28108
|
await installOnce(env, "npm@" + version2, [...extra, ...config2.globalPackages], (pkg) => npm(["install", "--global", pkg, "--no-fund", "--no-audit"]));
|
|
27644
28109
|
if (!config2.corepack) return;
|
|
@@ -27648,7 +28113,7 @@ var packageManagers = async (env, config2, version2) => {
|
|
|
27648
28113
|
return;
|
|
27649
28114
|
}
|
|
27650
28115
|
try {
|
|
27651
|
-
await execAsync(
|
|
28116
|
+
await execAsync(path38.join(dir, "node.exe"), [corepackJs, "enable", "--install-directory", mkdirp(tool("bin")), "pnpm", "yarn"], { env: nodeEnv, stdio: "ignore" });
|
|
27652
28117
|
env.summary.push('pnpm, yarn: via corepack (package.json "packageManager" picks the version)');
|
|
27653
28118
|
} catch (e) {
|
|
27654
28119
|
warn("corepack enable failed: " + errMsg(e));
|
|
@@ -27663,31 +28128,48 @@ var setupPwsh = async (env, refresh = false) => {
|
|
|
27663
28128
|
};
|
|
27664
28129
|
|
|
27665
28130
|
// src/guest/toolchains/python.ts
|
|
27666
|
-
import
|
|
27667
|
-
import
|
|
28131
|
+
import fs27 from "node:fs";
|
|
28132
|
+
import path39 from "node:path";
|
|
27668
28133
|
var installPython = async (pkg, spec) => {
|
|
27669
28134
|
const version2 = await resolveCached(pkg + ":" + spec, async () => {
|
|
27670
28135
|
const { versions } = await fetchJson("https://api.nuget.org/v3-flatcontainer/" + pkg + "/index.json");
|
|
27671
28136
|
return pickPackageVersion(versions, spec) ?? Promise.reject(new Error("No " + pkg + ' release matches "' + spec + '"'));
|
|
27672
28137
|
});
|
|
27673
28138
|
const dir = tool("python", pkg + "-" + version2);
|
|
27674
|
-
const exe =
|
|
28139
|
+
const exe = path39.join(dir, "python.exe");
|
|
27675
28140
|
if (!exists(exe)) {
|
|
27676
28141
|
log("Downloading Python " + version2 + (pkg === "python2" ? " (Python 2, " : " (") + "~30 MB once) ...");
|
|
27677
28142
|
await installArchive("https://api.nuget.org/v3-flatcontainer/" + pkg + "/" + version2 + "/" + pkg + "." + version2 + ".nupkg", dir, { locate: "python.exe", fileName: pkg + "." + version2 + ".zip" });
|
|
27678
28143
|
}
|
|
27679
|
-
if (!exists(
|
|
28144
|
+
if (!exists(path39.join(dir, "Scripts", "pip.exe")) && !exists(path39.join(dir, "Scripts", "pip2.exe"))) await execAsync(exe, ["-m", "ensurepip", "--default-pip"], { stdio: "ignore" });
|
|
27680
28145
|
return dir;
|
|
27681
28146
|
};
|
|
27682
|
-
var shimDir = (dir) => duringSession() ? tool("shims",
|
|
28147
|
+
var shimDir = (dir) => duringSession() ? tool("shims", path39.basename(dir)) : tool("shims");
|
|
27683
28148
|
var shim = (folder, name, command) => {
|
|
27684
|
-
|
|
28149
|
+
fs27.writeFileSync(path39.join(mkdirp(folder), name + ".cmd"), "@echo off\r\n" + command + " %*\r\n");
|
|
27685
28150
|
};
|
|
27686
28151
|
var shimPair = (folder, version2, dir) => {
|
|
27687
|
-
const python = '"' +
|
|
28152
|
+
const python = '"' + path39.join(dir, "python.exe") + '"';
|
|
27688
28153
|
shim(folder, "python" + version2, python);
|
|
27689
28154
|
shim(folder, "pip" + version2, python + " -m pip");
|
|
27690
28155
|
};
|
|
28156
|
+
var pyLauncher = (folder, py3, py2) => {
|
|
28157
|
+
const script = path39.join(mkdirp(folder), "py-launcher.py");
|
|
28158
|
+
fs27.writeFileSync(script, [
|
|
28159
|
+
"import subprocess, sys",
|
|
28160
|
+
"PY3, PY2 = " + JSON.stringify(path39.join(py3, "python.exe")) + ", " + JSON.stringify(py2 ? path39.join(py2, "python.exe") : null),
|
|
28161
|
+
"args = sys.argv[1:]",
|
|
28162
|
+
"exe = PY3",
|
|
28163
|
+
"if args and args[0].startswith('-2'):",
|
|
28164
|
+
' if not PY2: sys.exit("py: Python 2 is not installed (toolchains.python.python2)")',
|
|
28165
|
+
" exe, args = PY2, args[1:]",
|
|
28166
|
+
"elif args and (args[0] == '-3' or args[0].startswith('-3.') or args[0].startswith('-3-')):",
|
|
28167
|
+
" args = args[1:]",
|
|
28168
|
+
"sys.exit(subprocess.call([exe] + args))",
|
|
28169
|
+
""
|
|
28170
|
+
].join("\n"));
|
|
28171
|
+
shim(folder, "py", '"' + path39.join(py3, "python.exe") + '" "' + script + '"');
|
|
28172
|
+
};
|
|
27691
28173
|
var setupPython = async (env, config2, versions) => {
|
|
27692
28174
|
if (dryRun) {
|
|
27693
28175
|
log("(dry run) would provision Python " + versions.python.spec + (config2.python2 ? " and Python 2.7" : ""));
|
|
@@ -27696,22 +28178,26 @@ var setupPython = async (env, config2, versions) => {
|
|
|
27696
28178
|
const py3 = await installPython("python", versions.python.spec);
|
|
27697
28179
|
const shims = shimDir(py3);
|
|
27698
28180
|
shimPair(shims, "3", py3);
|
|
27699
|
-
env.prepend.push(py3,
|
|
28181
|
+
env.prepend.push(py3, path39.join(py3, "Scripts"), shims);
|
|
27700
28182
|
env.vars.PYTHONIOENCODING = "utf-8";
|
|
27701
|
-
env.summary.push("python: " +
|
|
27702
|
-
if (!config2.python2)
|
|
28183
|
+
env.summary.push("python: " + path39.basename(py3).replace("python-", "") + " (from " + versions.python.source + "; py works too)");
|
|
28184
|
+
if (!config2.python2) {
|
|
28185
|
+
pyLauncher(shims, py3, null);
|
|
28186
|
+
return;
|
|
28187
|
+
}
|
|
27703
28188
|
const py2 = await installPython("python2", "2.7");
|
|
27704
28189
|
shimPair(shims, "2", py2);
|
|
27705
|
-
|
|
28190
|
+
pyLauncher(shims, py3, py2);
|
|
28191
|
+
env.summary.push("python2: " + path39.basename(py2).replace("python2-", ""));
|
|
27706
28192
|
};
|
|
27707
28193
|
|
|
27708
28194
|
// src/guest/toolchains/scripting/php.ts
|
|
27709
|
-
import
|
|
27710
|
-
import
|
|
28195
|
+
import fs29 from "node:fs";
|
|
28196
|
+
import path41 from "node:path";
|
|
27711
28197
|
|
|
27712
28198
|
// src/guest/toolchains/scripting/vcruntime.ts
|
|
27713
|
-
import
|
|
27714
|
-
import
|
|
28199
|
+
import fs28 from "node:fs";
|
|
28200
|
+
import path40 from "node:path";
|
|
27715
28201
|
var VC_REDIST = "https://aka.ms/vs/17/release/vc_redist.x64.exe";
|
|
27716
28202
|
var MICROSOFT_SIGNER = "CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US";
|
|
27717
28203
|
var OK_EXIT_CODES = [0, 1638, 3010];
|
|
@@ -27726,8 +28212,8 @@ var setupVcRuntime = async (env, summary = true) => {
|
|
|
27726
28212
|
log("(dry run) would install the Visual C++ runtime");
|
|
27727
28213
|
return false;
|
|
27728
28214
|
}
|
|
27729
|
-
const system322 =
|
|
27730
|
-
const missing = !exists(
|
|
28215
|
+
const system322 = path40.join(process.env.WINDIR ?? "C:\\Windows", "System32");
|
|
28216
|
+
const missing = !exists(path40.join(system322, "vcruntime140.dll")) || !exists(path40.join(system322, "msvcp140.dll"));
|
|
27731
28217
|
if (missing) {
|
|
27732
28218
|
const installer = tool("vcredist", "vc_redist.x64.exe");
|
|
27733
28219
|
if (!exists(installer)) {
|
|
@@ -27735,12 +28221,12 @@ var setupVcRuntime = async (env, summary = true) => {
|
|
|
27735
28221
|
await downloadFile(VC_REDIST, installer);
|
|
27736
28222
|
}
|
|
27737
28223
|
if (signerOf(installer) !== MICROSOFT_SIGNER) {
|
|
27738
|
-
|
|
28224
|
+
fs28.rmSync(installer, { force: true });
|
|
27739
28225
|
throw new Error("vc_redist.x64.exe is not signed by Microsoft; deleted it (it is downloaded again next boot)");
|
|
27740
28226
|
}
|
|
27741
28227
|
log("Installing the Visual C++ runtime ...");
|
|
27742
28228
|
const code = await spawnAsync(installer, ["/install", "/quiet", "/norestart"]);
|
|
27743
|
-
if (!OK_EXIT_CODES.includes(code ?? -1) || !exists(
|
|
28229
|
+
if (!OK_EXIT_CODES.includes(code ?? -1) || !exists(path40.join(system322, "vcruntime140.dll"))) throw new Error("the Visual C++ runtime installer failed (exit " + code + ")");
|
|
27744
28230
|
}
|
|
27745
28231
|
if (summary) env.summary.push("vc++ runtime: installed");
|
|
27746
28232
|
return missing;
|
|
@@ -27758,15 +28244,15 @@ var phpBuild = async (spec) => {
|
|
|
27758
28244
|
return { version: release.version, ...build.zip };
|
|
27759
28245
|
};
|
|
27760
28246
|
var writePhpIni = (home) => {
|
|
27761
|
-
const ini =
|
|
27762
|
-
if (exists(ini) || !exists(
|
|
27763
|
-
let text =
|
|
27764
|
-
for (const ext of PHP_EXTENSIONS.filter((e) => exists(
|
|
27765
|
-
|
|
27766
|
-
|
|
28247
|
+
const ini = path41.join(home, "php.ini");
|
|
28248
|
+
if (exists(ini) || !exists(path41.join(home, "php.ini-development"))) return;
|
|
28249
|
+
let text = fs29.readFileSync(path41.join(home, "php.ini-development"), "utf8").replace(/^;\s*extension_dir\s*=\s*"ext"/m, 'extension_dir = "' + path41.join(home, "ext") + '"');
|
|
28250
|
+
for (const ext of PHP_EXTENSIONS.filter((e) => exists(path41.join(home, "ext", "php_" + e + ".dll")))) text = text.replace(new RegExp("^;(extension=" + ext + ")\\s*$", "m"), "$1");
|
|
28251
|
+
fs29.writeFileSync(ini + ".tmp", text);
|
|
28252
|
+
fs29.renameSync(ini + ".tmp", ini);
|
|
27767
28253
|
};
|
|
27768
28254
|
var shim2 = (env, name, command) => {
|
|
27769
|
-
|
|
28255
|
+
fs29.writeFileSync(path41.join(mkdirp(tool("shims")), name + ".cmd"), "@echo off\r\n" + command + " %*\r\n");
|
|
27770
28256
|
env.prepend.push(tool("shims"));
|
|
27771
28257
|
};
|
|
27772
28258
|
var setupComposer = async (env, php) => {
|
|
@@ -27778,7 +28264,7 @@ var setupComposer = async (env, php) => {
|
|
|
27778
28264
|
}
|
|
27779
28265
|
const composerHome = tool("composer-home");
|
|
27780
28266
|
env.vars.COMPOSER_HOME = composerHome;
|
|
27781
|
-
env.prepend.push(
|
|
28267
|
+
env.prepend.push(path41.join(composerHome, "vendor", "bin"));
|
|
27782
28268
|
shim2(env, "composer", '"' + php + '" "' + phar + '"');
|
|
27783
28269
|
env.summary.push("composer: " + (/\d+\.\d+\.\d+/.exec(execOutput(php, [phar, "--version", "--no-ansi"]))?.[0] ?? "installed"));
|
|
27784
28270
|
};
|
|
@@ -27791,7 +28277,7 @@ var setupPhp = async (env, config2) => {
|
|
|
27791
28277
|
await setupVcRuntime(env, false);
|
|
27792
28278
|
const version2 = await resolveCached("php:" + wantedSpec.spec, async () => (await phpBuild(wantedSpec.spec)).version);
|
|
27793
28279
|
const home = tool("php", version2);
|
|
27794
|
-
if (!exists(
|
|
28280
|
+
if (!exists(path41.join(home, "php.exe"))) {
|
|
27795
28281
|
const build = await phpBuild(version2);
|
|
27796
28282
|
log("Downloading PHP " + version2 + " (~30 MB once) ...");
|
|
27797
28283
|
await installArchive("https://windows.php.net/downloads/releases/" + build.path, home, { sha256: build.sha256, locate: "php.exe", fileName: build.path });
|
|
@@ -27799,11 +28285,11 @@ var setupPhp = async (env, config2) => {
|
|
|
27799
28285
|
writePhpIni(home);
|
|
27800
28286
|
env.prepend.push(home);
|
|
27801
28287
|
env.summary.push("php: " + version2 + " (from " + wantedSpec.source + ")");
|
|
27802
|
-
if (config2.composer) await setupComposer(env,
|
|
28288
|
+
if (config2.composer) await setupComposer(env, path41.join(home, "php.exe"));
|
|
27803
28289
|
};
|
|
27804
28290
|
|
|
27805
28291
|
// src/guest/toolchains/scripting/ruby.ts
|
|
27806
|
-
import
|
|
28292
|
+
import path42 from "node:path";
|
|
27807
28293
|
var RUBY_ASSET = /^rubyinstaller-(\d+\.\d+\.\d+)-(\d+)-x64\.7z$/;
|
|
27808
28294
|
var buildNumber = (asset) => Number(RUBY_ASSET.exec(asset.name)?.[2] ?? 0);
|
|
27809
28295
|
var rubyBuilds = async () => {
|
|
@@ -27826,7 +28312,7 @@ var setupRuby = async (env, config2) => {
|
|
|
27826
28312
|
}
|
|
27827
28313
|
const version2 = await resolveCached("ruby:" + wantedSpec.spec, async () => pickPackageVersion([...(await rubyBuilds()).keys()], wantedSpec.spec) ?? Promise.reject(new Error('No RubyInstaller build matches "' + wantedSpec.spec + '"')));
|
|
27828
28314
|
const home = tool("ruby", version2);
|
|
27829
|
-
if (!exists(
|
|
28315
|
+
if (!exists(path42.join(home, "bin", "ruby.exe"))) {
|
|
27830
28316
|
const asset = (await rubyBuilds()).get(version2);
|
|
27831
28317
|
if (!asset) throw new Error("RubyInstaller " + version2 + " is no longer published");
|
|
27832
28318
|
log("Downloading Ruby " + version2 + " (~100 MB once) ...");
|
|
@@ -27834,26 +28320,202 @@ var setupRuby = async (env, config2) => {
|
|
|
27834
28320
|
}
|
|
27835
28321
|
const gems = tool("ruby-gems", version2.split(".").slice(0, 2).join("."));
|
|
27836
28322
|
Object.assign(env.vars, { GEM_HOME: gems, BUNDLE_USER_HOME: tool("bundle-home") });
|
|
27837
|
-
env.prepend.push(
|
|
27838
|
-
env.summary.push("ruby: " + versionOf(
|
|
27839
|
-
const gem =
|
|
28323
|
+
env.prepend.push(path42.join(home, "bin"), path42.join(gems, "bin"));
|
|
28324
|
+
env.summary.push("ruby: " + versionOf(path42.join(home, "bin", "ruby.exe")) + " (from " + wantedSpec.source + "; gems with C extensions need MSYS2, not included)");
|
|
28325
|
+
const gem = path42.join(home, "bin", "gem.cmd");
|
|
27840
28326
|
await installOnce(env, "gem@" + version2, config2.gems, (pkg) => execAsync(SYSTEM.cmd(), ["/d", "/c", gem, "install", pkg, "--no-document"], { env: { ...process.env, GEM_HOME: gems } }));
|
|
27841
28327
|
};
|
|
27842
28328
|
|
|
27843
28329
|
// src/guest/toolchains/vscode.ts
|
|
27844
|
-
import
|
|
27845
|
-
import
|
|
27846
|
-
import
|
|
28330
|
+
import fs30 from "node:fs";
|
|
28331
|
+
import os7 from "node:os";
|
|
28332
|
+
import path43 from "node:path";
|
|
28333
|
+
|
|
28334
|
+
// node_modules/jsonc-parser/lib/esm/impl/scanner.js
|
|
28335
|
+
var CharacterCodes;
|
|
28336
|
+
(function(CharacterCodes2) {
|
|
28337
|
+
CharacterCodes2[CharacterCodes2["lineFeed"] = 10] = "lineFeed";
|
|
28338
|
+
CharacterCodes2[CharacterCodes2["carriageReturn"] = 13] = "carriageReturn";
|
|
28339
|
+
CharacterCodes2[CharacterCodes2["space"] = 32] = "space";
|
|
28340
|
+
CharacterCodes2[CharacterCodes2["_0"] = 48] = "_0";
|
|
28341
|
+
CharacterCodes2[CharacterCodes2["_1"] = 49] = "_1";
|
|
28342
|
+
CharacterCodes2[CharacterCodes2["_2"] = 50] = "_2";
|
|
28343
|
+
CharacterCodes2[CharacterCodes2["_3"] = 51] = "_3";
|
|
28344
|
+
CharacterCodes2[CharacterCodes2["_4"] = 52] = "_4";
|
|
28345
|
+
CharacterCodes2[CharacterCodes2["_5"] = 53] = "_5";
|
|
28346
|
+
CharacterCodes2[CharacterCodes2["_6"] = 54] = "_6";
|
|
28347
|
+
CharacterCodes2[CharacterCodes2["_7"] = 55] = "_7";
|
|
28348
|
+
CharacterCodes2[CharacterCodes2["_8"] = 56] = "_8";
|
|
28349
|
+
CharacterCodes2[CharacterCodes2["_9"] = 57] = "_9";
|
|
28350
|
+
CharacterCodes2[CharacterCodes2["a"] = 97] = "a";
|
|
28351
|
+
CharacterCodes2[CharacterCodes2["b"] = 98] = "b";
|
|
28352
|
+
CharacterCodes2[CharacterCodes2["c"] = 99] = "c";
|
|
28353
|
+
CharacterCodes2[CharacterCodes2["d"] = 100] = "d";
|
|
28354
|
+
CharacterCodes2[CharacterCodes2["e"] = 101] = "e";
|
|
28355
|
+
CharacterCodes2[CharacterCodes2["f"] = 102] = "f";
|
|
28356
|
+
CharacterCodes2[CharacterCodes2["g"] = 103] = "g";
|
|
28357
|
+
CharacterCodes2[CharacterCodes2["h"] = 104] = "h";
|
|
28358
|
+
CharacterCodes2[CharacterCodes2["i"] = 105] = "i";
|
|
28359
|
+
CharacterCodes2[CharacterCodes2["j"] = 106] = "j";
|
|
28360
|
+
CharacterCodes2[CharacterCodes2["k"] = 107] = "k";
|
|
28361
|
+
CharacterCodes2[CharacterCodes2["l"] = 108] = "l";
|
|
28362
|
+
CharacterCodes2[CharacterCodes2["m"] = 109] = "m";
|
|
28363
|
+
CharacterCodes2[CharacterCodes2["n"] = 110] = "n";
|
|
28364
|
+
CharacterCodes2[CharacterCodes2["o"] = 111] = "o";
|
|
28365
|
+
CharacterCodes2[CharacterCodes2["p"] = 112] = "p";
|
|
28366
|
+
CharacterCodes2[CharacterCodes2["q"] = 113] = "q";
|
|
28367
|
+
CharacterCodes2[CharacterCodes2["r"] = 114] = "r";
|
|
28368
|
+
CharacterCodes2[CharacterCodes2["s"] = 115] = "s";
|
|
28369
|
+
CharacterCodes2[CharacterCodes2["t"] = 116] = "t";
|
|
28370
|
+
CharacterCodes2[CharacterCodes2["u"] = 117] = "u";
|
|
28371
|
+
CharacterCodes2[CharacterCodes2["v"] = 118] = "v";
|
|
28372
|
+
CharacterCodes2[CharacterCodes2["w"] = 119] = "w";
|
|
28373
|
+
CharacterCodes2[CharacterCodes2["x"] = 120] = "x";
|
|
28374
|
+
CharacterCodes2[CharacterCodes2["y"] = 121] = "y";
|
|
28375
|
+
CharacterCodes2[CharacterCodes2["z"] = 122] = "z";
|
|
28376
|
+
CharacterCodes2[CharacterCodes2["A"] = 65] = "A";
|
|
28377
|
+
CharacterCodes2[CharacterCodes2["B"] = 66] = "B";
|
|
28378
|
+
CharacterCodes2[CharacterCodes2["C"] = 67] = "C";
|
|
28379
|
+
CharacterCodes2[CharacterCodes2["D"] = 68] = "D";
|
|
28380
|
+
CharacterCodes2[CharacterCodes2["E"] = 69] = "E";
|
|
28381
|
+
CharacterCodes2[CharacterCodes2["F"] = 70] = "F";
|
|
28382
|
+
CharacterCodes2[CharacterCodes2["G"] = 71] = "G";
|
|
28383
|
+
CharacterCodes2[CharacterCodes2["H"] = 72] = "H";
|
|
28384
|
+
CharacterCodes2[CharacterCodes2["I"] = 73] = "I";
|
|
28385
|
+
CharacterCodes2[CharacterCodes2["J"] = 74] = "J";
|
|
28386
|
+
CharacterCodes2[CharacterCodes2["K"] = 75] = "K";
|
|
28387
|
+
CharacterCodes2[CharacterCodes2["L"] = 76] = "L";
|
|
28388
|
+
CharacterCodes2[CharacterCodes2["M"] = 77] = "M";
|
|
28389
|
+
CharacterCodes2[CharacterCodes2["N"] = 78] = "N";
|
|
28390
|
+
CharacterCodes2[CharacterCodes2["O"] = 79] = "O";
|
|
28391
|
+
CharacterCodes2[CharacterCodes2["P"] = 80] = "P";
|
|
28392
|
+
CharacterCodes2[CharacterCodes2["Q"] = 81] = "Q";
|
|
28393
|
+
CharacterCodes2[CharacterCodes2["R"] = 82] = "R";
|
|
28394
|
+
CharacterCodes2[CharacterCodes2["S"] = 83] = "S";
|
|
28395
|
+
CharacterCodes2[CharacterCodes2["T"] = 84] = "T";
|
|
28396
|
+
CharacterCodes2[CharacterCodes2["U"] = 85] = "U";
|
|
28397
|
+
CharacterCodes2[CharacterCodes2["V"] = 86] = "V";
|
|
28398
|
+
CharacterCodes2[CharacterCodes2["W"] = 87] = "W";
|
|
28399
|
+
CharacterCodes2[CharacterCodes2["X"] = 88] = "X";
|
|
28400
|
+
CharacterCodes2[CharacterCodes2["Y"] = 89] = "Y";
|
|
28401
|
+
CharacterCodes2[CharacterCodes2["Z"] = 90] = "Z";
|
|
28402
|
+
CharacterCodes2[CharacterCodes2["asterisk"] = 42] = "asterisk";
|
|
28403
|
+
CharacterCodes2[CharacterCodes2["backslash"] = 92] = "backslash";
|
|
28404
|
+
CharacterCodes2[CharacterCodes2["closeBrace"] = 125] = "closeBrace";
|
|
28405
|
+
CharacterCodes2[CharacterCodes2["closeBracket"] = 93] = "closeBracket";
|
|
28406
|
+
CharacterCodes2[CharacterCodes2["colon"] = 58] = "colon";
|
|
28407
|
+
CharacterCodes2[CharacterCodes2["comma"] = 44] = "comma";
|
|
28408
|
+
CharacterCodes2[CharacterCodes2["dot"] = 46] = "dot";
|
|
28409
|
+
CharacterCodes2[CharacterCodes2["doubleQuote"] = 34] = "doubleQuote";
|
|
28410
|
+
CharacterCodes2[CharacterCodes2["minus"] = 45] = "minus";
|
|
28411
|
+
CharacterCodes2[CharacterCodes2["openBrace"] = 123] = "openBrace";
|
|
28412
|
+
CharacterCodes2[CharacterCodes2["openBracket"] = 91] = "openBracket";
|
|
28413
|
+
CharacterCodes2[CharacterCodes2["plus"] = 43] = "plus";
|
|
28414
|
+
CharacterCodes2[CharacterCodes2["slash"] = 47] = "slash";
|
|
28415
|
+
CharacterCodes2[CharacterCodes2["formFeed"] = 12] = "formFeed";
|
|
28416
|
+
CharacterCodes2[CharacterCodes2["tab"] = 9] = "tab";
|
|
28417
|
+
})(CharacterCodes || (CharacterCodes = {}));
|
|
28418
|
+
|
|
28419
|
+
// node_modules/jsonc-parser/lib/esm/impl/string-intern.js
|
|
28420
|
+
var cachedSpaces = new Array(20).fill(0).map((_2, index) => {
|
|
28421
|
+
return " ".repeat(index);
|
|
28422
|
+
});
|
|
28423
|
+
var maxCachedValues = 200;
|
|
28424
|
+
var cachedBreakLinesWithSpaces = {
|
|
28425
|
+
" ": {
|
|
28426
|
+
"\n": new Array(maxCachedValues).fill(0).map((_2, index) => {
|
|
28427
|
+
return "\n" + " ".repeat(index);
|
|
28428
|
+
}),
|
|
28429
|
+
"\r": new Array(maxCachedValues).fill(0).map((_2, index) => {
|
|
28430
|
+
return "\r" + " ".repeat(index);
|
|
28431
|
+
}),
|
|
28432
|
+
"\r\n": new Array(maxCachedValues).fill(0).map((_2, index) => {
|
|
28433
|
+
return "\r\n" + " ".repeat(index);
|
|
28434
|
+
})
|
|
28435
|
+
},
|
|
28436
|
+
" ": {
|
|
28437
|
+
"\n": new Array(maxCachedValues).fill(0).map((_2, index) => {
|
|
28438
|
+
return "\n" + " ".repeat(index);
|
|
28439
|
+
}),
|
|
28440
|
+
"\r": new Array(maxCachedValues).fill(0).map((_2, index) => {
|
|
28441
|
+
return "\r" + " ".repeat(index);
|
|
28442
|
+
}),
|
|
28443
|
+
"\r\n": new Array(maxCachedValues).fill(0).map((_2, index) => {
|
|
28444
|
+
return "\r\n" + " ".repeat(index);
|
|
28445
|
+
})
|
|
28446
|
+
}
|
|
28447
|
+
};
|
|
28448
|
+
|
|
28449
|
+
// node_modules/jsonc-parser/lib/esm/impl/parser.js
|
|
28450
|
+
var ParseOptions;
|
|
28451
|
+
(function(ParseOptions2) {
|
|
28452
|
+
ParseOptions2.DEFAULT = {
|
|
28453
|
+
allowTrailingComma: false
|
|
28454
|
+
};
|
|
28455
|
+
})(ParseOptions || (ParseOptions = {}));
|
|
28456
|
+
|
|
28457
|
+
// node_modules/jsonc-parser/lib/esm/main.js
|
|
28458
|
+
var ScanError;
|
|
28459
|
+
(function(ScanError2) {
|
|
28460
|
+
ScanError2[ScanError2["None"] = 0] = "None";
|
|
28461
|
+
ScanError2[ScanError2["UnexpectedEndOfComment"] = 1] = "UnexpectedEndOfComment";
|
|
28462
|
+
ScanError2[ScanError2["UnexpectedEndOfString"] = 2] = "UnexpectedEndOfString";
|
|
28463
|
+
ScanError2[ScanError2["UnexpectedEndOfNumber"] = 3] = "UnexpectedEndOfNumber";
|
|
28464
|
+
ScanError2[ScanError2["InvalidUnicode"] = 4] = "InvalidUnicode";
|
|
28465
|
+
ScanError2[ScanError2["InvalidEscapeCharacter"] = 5] = "InvalidEscapeCharacter";
|
|
28466
|
+
ScanError2[ScanError2["InvalidCharacter"] = 6] = "InvalidCharacter";
|
|
28467
|
+
})(ScanError || (ScanError = {}));
|
|
28468
|
+
var SyntaxKind;
|
|
28469
|
+
(function(SyntaxKind2) {
|
|
28470
|
+
SyntaxKind2[SyntaxKind2["OpenBraceToken"] = 1] = "OpenBraceToken";
|
|
28471
|
+
SyntaxKind2[SyntaxKind2["CloseBraceToken"] = 2] = "CloseBraceToken";
|
|
28472
|
+
SyntaxKind2[SyntaxKind2["OpenBracketToken"] = 3] = "OpenBracketToken";
|
|
28473
|
+
SyntaxKind2[SyntaxKind2["CloseBracketToken"] = 4] = "CloseBracketToken";
|
|
28474
|
+
SyntaxKind2[SyntaxKind2["CommaToken"] = 5] = "CommaToken";
|
|
28475
|
+
SyntaxKind2[SyntaxKind2["ColonToken"] = 6] = "ColonToken";
|
|
28476
|
+
SyntaxKind2[SyntaxKind2["NullKeyword"] = 7] = "NullKeyword";
|
|
28477
|
+
SyntaxKind2[SyntaxKind2["TrueKeyword"] = 8] = "TrueKeyword";
|
|
28478
|
+
SyntaxKind2[SyntaxKind2["FalseKeyword"] = 9] = "FalseKeyword";
|
|
28479
|
+
SyntaxKind2[SyntaxKind2["StringLiteral"] = 10] = "StringLiteral";
|
|
28480
|
+
SyntaxKind2[SyntaxKind2["NumericLiteral"] = 11] = "NumericLiteral";
|
|
28481
|
+
SyntaxKind2[SyntaxKind2["LineCommentTrivia"] = 12] = "LineCommentTrivia";
|
|
28482
|
+
SyntaxKind2[SyntaxKind2["BlockCommentTrivia"] = 13] = "BlockCommentTrivia";
|
|
28483
|
+
SyntaxKind2[SyntaxKind2["LineBreakTrivia"] = 14] = "LineBreakTrivia";
|
|
28484
|
+
SyntaxKind2[SyntaxKind2["Trivia"] = 15] = "Trivia";
|
|
28485
|
+
SyntaxKind2[SyntaxKind2["Unknown"] = 16] = "Unknown";
|
|
28486
|
+
SyntaxKind2[SyntaxKind2["EOF"] = 17] = "EOF";
|
|
28487
|
+
})(SyntaxKind || (SyntaxKind = {}));
|
|
28488
|
+
var ParseErrorCode;
|
|
28489
|
+
(function(ParseErrorCode2) {
|
|
28490
|
+
ParseErrorCode2[ParseErrorCode2["InvalidSymbol"] = 1] = "InvalidSymbol";
|
|
28491
|
+
ParseErrorCode2[ParseErrorCode2["InvalidNumberFormat"] = 2] = "InvalidNumberFormat";
|
|
28492
|
+
ParseErrorCode2[ParseErrorCode2["PropertyNameExpected"] = 3] = "PropertyNameExpected";
|
|
28493
|
+
ParseErrorCode2[ParseErrorCode2["ValueExpected"] = 4] = "ValueExpected";
|
|
28494
|
+
ParseErrorCode2[ParseErrorCode2["ColonExpected"] = 5] = "ColonExpected";
|
|
28495
|
+
ParseErrorCode2[ParseErrorCode2["CommaExpected"] = 6] = "CommaExpected";
|
|
28496
|
+
ParseErrorCode2[ParseErrorCode2["CloseBraceExpected"] = 7] = "CloseBraceExpected";
|
|
28497
|
+
ParseErrorCode2[ParseErrorCode2["CloseBracketExpected"] = 8] = "CloseBracketExpected";
|
|
28498
|
+
ParseErrorCode2[ParseErrorCode2["EndOfFileExpected"] = 9] = "EndOfFileExpected";
|
|
28499
|
+
ParseErrorCode2[ParseErrorCode2["InvalidCommentToken"] = 10] = "InvalidCommentToken";
|
|
28500
|
+
ParseErrorCode2[ParseErrorCode2["UnexpectedEndOfComment"] = 11] = "UnexpectedEndOfComment";
|
|
28501
|
+
ParseErrorCode2[ParseErrorCode2["UnexpectedEndOfString"] = 12] = "UnexpectedEndOfString";
|
|
28502
|
+
ParseErrorCode2[ParseErrorCode2["UnexpectedEndOfNumber"] = 13] = "UnexpectedEndOfNumber";
|
|
28503
|
+
ParseErrorCode2[ParseErrorCode2["InvalidUnicode"] = 14] = "InvalidUnicode";
|
|
28504
|
+
ParseErrorCode2[ParseErrorCode2["InvalidEscapeCharacter"] = 15] = "InvalidEscapeCharacter";
|
|
28505
|
+
ParseErrorCode2[ParseErrorCode2["InvalidCharacter"] = 16] = "InvalidCharacter";
|
|
28506
|
+
})(ParseErrorCode || (ParseErrorCode = {}));
|
|
28507
|
+
|
|
28508
|
+
// src/guest/toolchains/vscode.ts
|
|
27847
28509
|
var VERSION_MARKER = ".agent-sandbox-version";
|
|
27848
28510
|
var desktopShortcut = (exe) => {
|
|
27849
28511
|
if (!isWin) return;
|
|
27850
|
-
const link =
|
|
28512
|
+
const link = path43.join(os7.homedir(), "Desktop", "Visual Studio Code.lnk");
|
|
27851
28513
|
const q = (s) => "'" + s.replace(/'/g, "''") + "'";
|
|
27852
28514
|
powershell("$s = (New-Object -ComObject WScript.Shell).CreateShortcut(" + q(link) + "); $s.TargetPath = " + q(exe) + "; $s.Arguments = " + q('"' + (process.env.AGENT_WORKSPACE ?? "") + '"') + "; $s.Save()");
|
|
27853
28515
|
};
|
|
27854
28516
|
var setupVscode = async (env, refresh) => {
|
|
27855
28517
|
const root = tool("vscode");
|
|
27856
|
-
const exe =
|
|
28518
|
+
const exe = path43.join(root, "Code.exe");
|
|
27857
28519
|
if (dryRun) {
|
|
27858
28520
|
log("(dry run) would provision VS Code");
|
|
27859
28521
|
return;
|
|
@@ -27861,27 +28523,27 @@ var setupVscode = async (env, refresh) => {
|
|
|
27861
28523
|
if (!exists(exe) || refresh) {
|
|
27862
28524
|
const release = await fetchJson("https://update.code.visualstudio.com/api/update/win32-" + (arch === "arm64" ? "arm64" : "x64") + "-archive/stable/latest");
|
|
27863
28525
|
log("Downloading VS Code " + release.productVersion + " (~150 MB once) ...");
|
|
27864
|
-
const keep =
|
|
28526
|
+
const keep = path43.join(root, "data");
|
|
27865
28527
|
const parked = root + "-data";
|
|
27866
28528
|
if (exists(keep)) {
|
|
27867
|
-
|
|
27868
|
-
|
|
28529
|
+
fs30.rmSync(parked, { recursive: true, force: true });
|
|
28530
|
+
fs30.renameSync(keep, parked);
|
|
27869
28531
|
}
|
|
27870
28532
|
try {
|
|
27871
28533
|
await installArchive(release.url, root, { sha256: release.sha256hash, locate: "Code.exe", fileName: "vscode.zip" });
|
|
27872
|
-
|
|
28534
|
+
fs30.writeFileSync(path43.join(root, VERSION_MARKER), release.productVersion);
|
|
27873
28535
|
} finally {
|
|
27874
28536
|
if (exists(parked)) {
|
|
27875
28537
|
mkdirp(root);
|
|
27876
|
-
|
|
27877
|
-
|
|
28538
|
+
fs30.rmSync(keep, { recursive: true, force: true });
|
|
28539
|
+
fs30.renameSync(parked, keep);
|
|
27878
28540
|
}
|
|
27879
28541
|
}
|
|
27880
28542
|
}
|
|
27881
|
-
mkdirp(
|
|
27882
|
-
env.prepend.push(
|
|
28543
|
+
mkdirp(path43.join(root, "data"));
|
|
28544
|
+
env.prepend.push(path43.join(root, "bin"));
|
|
27883
28545
|
desktopShortcut(exe);
|
|
27884
|
-
const version2 = exists(
|
|
28546
|
+
const version2 = exists(path43.join(root, VERSION_MARKER)) ? fs30.readFileSync(path43.join(root, VERSION_MARKER), "utf8").trim() : "installed";
|
|
27885
28547
|
env.summary.push("vscode: " + version2 + " (portable; run code . or use the desktop shortcut)");
|
|
27886
28548
|
};
|
|
27887
28549
|
|
|
@@ -27892,14 +28554,34 @@ var setupPythonTools = async (env, tools) => {
|
|
|
27892
28554
|
await installOnce(env, "uv tool", tools, (pkg) => execAsync(uv, ["tool", "install", pkg], { env: { ...process.env, ...uvVars() } }));
|
|
27893
28555
|
};
|
|
27894
28556
|
var cargoTarget = (targetDir) => {
|
|
27895
|
-
if (targetDir === "shared") return null;
|
|
27896
|
-
if (targetDir === "
|
|
27897
|
-
if (targetDir === "local") return path43.join(localDir, "cargo-target");
|
|
28557
|
+
if (targetDir === "shared" || targetDir === "separate") return null;
|
|
28558
|
+
if (targetDir === "local") return path44.join(localDir, "cargo-target");
|
|
27898
28559
|
return targetDir;
|
|
27899
28560
|
};
|
|
28561
|
+
var cargoShim = (env, rust) => {
|
|
28562
|
+
const real = path44.join(tool("rust", "cargo", "bin"), "cargo.exe");
|
|
28563
|
+
if (rust.targetDir !== "separate" || !exists(real)) return;
|
|
28564
|
+
const dir = mkdirp(tool("shims", "cargo"));
|
|
28565
|
+
fs31.copyFileSync(ensureCompiled("cargoshim"), path44.join(dir, "cargo.exe"));
|
|
28566
|
+
env.prepend.unshift(dir);
|
|
28567
|
+
env.vars.AGENT_REAL_CARGO = real;
|
|
28568
|
+
};
|
|
28569
|
+
var cargoDefaults = (host) => {
|
|
28570
|
+
const file3 = tool("rust", "cargo", "config.toml");
|
|
28571
|
+
if (exists(file3) || !exists(path44.dirname(file3))) return;
|
|
28572
|
+
const jobs = Math.max(2, Math.min(4, Math.floor(os8.cpus().length / 4)));
|
|
28573
|
+
const gnu = host.endsWith("-gnu");
|
|
28574
|
+
fs31.writeFileSync(file3, [
|
|
28575
|
+
"# Written by windows-development-sandbox once; edit freely, it is never overwritten.",
|
|
28576
|
+
"[build]",
|
|
28577
|
+
"jobs = " + jobs,
|
|
28578
|
+
"",
|
|
28579
|
+
...gnu ? ["[profile.dev]", 'debug = "line-tables-only"', "", "[profile.test]", 'debug = "line-tables-only"', ""] : []
|
|
28580
|
+
].join("\n"));
|
|
28581
|
+
};
|
|
27900
28582
|
var rustCaches = (rust) => {
|
|
27901
28583
|
const target = cargoTarget(rust.targetDir);
|
|
27902
|
-
return { ...target ? { CARGO_TARGET_DIR: target } : {}, ...process.env.SCCACHE_DIR ? {} : { SCCACHE_DIR:
|
|
28584
|
+
return { ...target ? { CARGO_TARGET_DIR: target } : {}, ...process.env.SCCACHE_DIR ? {} : { SCCACHE_DIR: path44.join(dataDir, "cache", "sccache") } };
|
|
27903
28585
|
};
|
|
27904
28586
|
var rustHost = (config2) => {
|
|
27905
28587
|
if (config2.rust.host !== "auto") return config2.rust.host;
|
|
@@ -27907,6 +28589,7 @@ var rustHost = (config2) => {
|
|
|
27907
28589
|
return cpu + (wanted(config2.msvc.enabled, "msvc") ? "-pc-windows-msvc" : "-pc-windows-gnu");
|
|
27908
28590
|
};
|
|
27909
28591
|
var plan = (config2, versions, o) => {
|
|
28592
|
+
const apps = Boolean(o.apps && (o.apps.install.length || Object.keys(o.apps.custom).length));
|
|
27910
28593
|
const java = wanted(config2.java.enabled, "java");
|
|
27911
28594
|
const python = wanted(config2.python.enabled, "python");
|
|
27912
28595
|
return [
|
|
@@ -27926,6 +28609,10 @@ var plan = (config2, versions, o) => {
|
|
|
27926
28609
|
run: async (env) => {
|
|
27927
28610
|
await setupRust(env, { ...config2.rust, host: rustHost(config2) }, o.refresh);
|
|
27928
28611
|
Object.assign(env.vars, rustCaches(config2.rust));
|
|
28612
|
+
if (!dryRun) {
|
|
28613
|
+
cargoDefaults(rustHost(config2));
|
|
28614
|
+
cargoShim(env, config2.rust);
|
|
28615
|
+
}
|
|
27929
28616
|
}
|
|
27930
28617
|
},
|
|
27931
28618
|
{ name: ".NET", on: wanted(config2.dotnet.enabled, "dotnet"), run: (env) => setupDotnet(env, config2.dotnet, o.refresh) },
|
|
@@ -27933,7 +28620,8 @@ var plan = (config2, versions, o) => {
|
|
|
27933
28620
|
{ name: "Java", on: java, run: (env) => setupJava(env, config2.java) },
|
|
27934
28621
|
{ name: "Ruby", on: wanted(config2.ruby.enabled, "ruby"), run: (env) => setupRuby(env, config2.ruby) },
|
|
27935
28622
|
// PHP installs the Visual C++ runtime itself: one installer at a time.
|
|
27936
|
-
|
|
28623
|
+
// Many apps (bat, delta, Neovim, most GUIs, your own programs) are built against it too.
|
|
28624
|
+
{ name: "Visual C++ runtime", on: config2.vcRuntime.enabled || apps, shared: true, run: async (env) => {
|
|
27937
28625
|
await setupVcRuntime(env);
|
|
27938
28626
|
} },
|
|
27939
28627
|
{ name: "PHP", on: wanted(config2.php.enabled, "php"), after: ["Visual C++ runtime"], run: (env) => setupPhp(env, config2.php) },
|
|
@@ -27943,8 +28631,10 @@ var plan = (config2, versions, o) => {
|
|
|
27943
28631
|
{ name: "PowerShell 7", on: wanted(config2.pwsh.enabled, "pwsh"), run: (env) => setupPwsh(env, o.refresh) },
|
|
27944
28632
|
// The openssl tool comes from Git's install: after Git.
|
|
27945
28633
|
{ name: "CLI tools", on: Object.values(config2.cli).some((v) => v !== false), after: ["Git"], run: (env) => setupCli(env, config2.cli, o.gitAccess, o.refresh) },
|
|
27946
|
-
{ name: "Mesa 3D", on: config2.mesa.enabled, shared: true, run: (env) => setupMesa(env, config2.mesa) },
|
|
28634
|
+
{ name: "Mesa 3D", on: config2.mesa.enabled || appsNeedMesa(o.apps), shared: true, run: (env) => setupMesa(env, config2.mesa) },
|
|
27947
28635
|
{ name: "VS Code", on: config2.vscode.enabled, shared: true, run: (env) => setupVscode(env, o.refresh) },
|
|
28636
|
+
// Desktop apps and extra tools (apps.install / apps.custom); games and 3D apps copy Mesa's OpenGL next to them.
|
|
28637
|
+
{ name: "Apps", on: apps, shared: true, after: ["Mesa 3D", "Visual C++ runtime"], run: (env) => setupApps(env, o.apps, { gitAccess: o.gitAccess, refresh: o.refresh }) },
|
|
27948
28638
|
{ name: "Python tools", on: python && config2.python.tools.length > 0, after: ["Python", "uv"], run: (env) => setupPythonTools(env, config2.python.tools) },
|
|
27949
28639
|
// DynamoDB Local runs on Java: the Java step installs the JDK first instead of racing it.
|
|
27950
28640
|
// One server per database in the sandbox: a project that joins later shares the one the boot started.
|
|
@@ -27953,7 +28643,7 @@ var plan = (config2, versions, o) => {
|
|
|
27953
28643
|
};
|
|
27954
28644
|
|
|
27955
28645
|
// src/guest/toolchains/index.ts
|
|
27956
|
-
var
|
|
28646
|
+
var PARALLEL2 = 4;
|
|
27957
28647
|
var locks = /* @__PURE__ */ new Map();
|
|
27958
28648
|
var lockKey = (name) => name.split(" ")[0].toLowerCase();
|
|
27959
28649
|
var exclusive = async (name, work) => {
|
|
@@ -27992,7 +28682,7 @@ var runSteps = async (steps, o) => {
|
|
|
27992
28682
|
done++;
|
|
27993
28683
|
return;
|
|
27994
28684
|
}
|
|
27995
|
-
while (running.size >=
|
|
28685
|
+
while (running.size >= PARALLEL2) await new Promise((r) => waiting.push(r));
|
|
27996
28686
|
running.add(s.name);
|
|
27997
28687
|
report();
|
|
27998
28688
|
try {
|
|
@@ -28031,14 +28721,14 @@ var provisionedFor = (cwd) => [...ready.values()].filter((p) => isWithin(p.spec.
|
|
|
28031
28721
|
var provisionedProjects = () => [...ready.values()];
|
|
28032
28722
|
var cmdSet = (env, names) => names.filter((n) => env[n] !== void 0 && !/[\r\n]/.test(String(env[n]))).map((n) => '@set "' + n + "=" + String(env[n]).replace(/%/g, "%%") + '"');
|
|
28033
28723
|
var writeShell = (spec, env, names) => {
|
|
28034
|
-
const dir = mkdirp(
|
|
28035
|
-
|
|
28036
|
-
|
|
28037
|
-
const bin = mkdirp(
|
|
28038
|
-
|
|
28039
|
-
'@if "%~1"=="" (echo Usage: sbx-shell ^<project^> ^(a terminal in that project with its tools^) & dir /b "' +
|
|
28040
|
-
'@if not exist "' +
|
|
28041
|
-
'@cmd /k ""' +
|
|
28724
|
+
const dir = mkdirp(path45.join(localDir, "projects", spec.name));
|
|
28725
|
+
fs32.writeFileSync(path45.join(dir, "env.cmd"), [...cmdSet(env, [...names, "PATH"]), ""].join("\r\n"));
|
|
28726
|
+
fs32.writeFileSync(path45.join(dir, "shell.cmd"), ['@call "' + path45.join(dir, "env.cmd") + '"', '@cd /d "' + spec.workspace + '"', "@title " + spec.name, ""].join("\r\n"));
|
|
28727
|
+
const bin = mkdirp(path45.join(localDir, "bin"));
|
|
28728
|
+
fs32.writeFileSync(path45.join(bin, "sbx-shell.cmd"), [
|
|
28729
|
+
'@if "%~1"=="" (echo Usage: sbx-shell ^<project^> ^(a terminal in that project with its tools^) & dir /b "' + path45.join(localDir, "projects") + '" & exit /b 2)',
|
|
28730
|
+
'@if not exist "' + path45.join(localDir, "projects") + '\\%~1\\shell.cmd" (echo No project %~1 in this sandbox. & exit /b 2)',
|
|
28731
|
+
'@cmd /k ""' + path45.join(localDir, "projects") + '\\%~1\\shell.cmd""',
|
|
28042
28732
|
""
|
|
28043
28733
|
].join("\r\n"));
|
|
28044
28734
|
};
|
|
@@ -28077,10 +28767,10 @@ var provision = async (spec, say) => {
|
|
|
28077
28767
|
saveProjectStatus(spec.name, spec.workspace, "provisioning", m, spec.databases, []);
|
|
28078
28768
|
say(m);
|
|
28079
28769
|
}, reuse: boot?.steps }));
|
|
28080
|
-
tools.prepend.push(
|
|
28770
|
+
tools.prepend.push(path45.join(localDir, "bin"));
|
|
28081
28771
|
const env = agentEnv(tools, { workspace: spec.workspace, project: spec.name, base });
|
|
28082
|
-
const specFile =
|
|
28083
|
-
|
|
28772
|
+
const specFile = path45.join(mkdirp(path45.join(localDir, "projects", spec.name)), "project.json");
|
|
28773
|
+
fs32.writeFileSync(specFile, JSON.stringify(spec));
|
|
28084
28774
|
env.AGENT_PROJECT_FILE = specFile;
|
|
28085
28775
|
addMachineEnvironment(tools.vars, [...tools.prepend, ...tools.append], true);
|
|
28086
28776
|
try {
|
|
@@ -28154,14 +28844,83 @@ var execCommand = (req) => {
|
|
|
28154
28844
|
});
|
|
28155
28845
|
};
|
|
28156
28846
|
|
|
28847
|
+
// src/guest/daemon/relays.ts
|
|
28848
|
+
import net2 from "node:net";
|
|
28849
|
+
|
|
28850
|
+
// src/shared/netpolicy.ts
|
|
28851
|
+
var relayPort = (index) => 38100 + index;
|
|
28852
|
+
|
|
28853
|
+
// src/guest/daemon/relays.ts
|
|
28854
|
+
var startRelays = () => {
|
|
28855
|
+
(session.network.forwardPorts ?? []).forEach((f, i) => {
|
|
28856
|
+
const server = net2.createServer((client) => {
|
|
28857
|
+
const target = net2.connect(f.sandbox, "127.0.0.1");
|
|
28858
|
+
client.pipe(target).pipe(client);
|
|
28859
|
+
target.on("error", () => client.destroy());
|
|
28860
|
+
client.on("error", () => target.destroy());
|
|
28861
|
+
});
|
|
28862
|
+
server.on("error", (e) => warn("Port forward " + f.pc + " -> " + f.sandbox + " could not start: " + errMsg(e)));
|
|
28863
|
+
server.listen(relayPort(i), "0.0.0.0", () => log("Port forward: the PC's localhost:" + f.pc + " reaches localhost:" + f.sandbox + " here."));
|
|
28864
|
+
});
|
|
28865
|
+
};
|
|
28866
|
+
|
|
28867
|
+
// src/guest/audit.ts
|
|
28868
|
+
import fs33 from "node:fs";
|
|
28869
|
+
import path47 from "node:path";
|
|
28870
|
+
import { spawnSync as spawnSync4 } from "node:child_process";
|
|
28871
|
+
|
|
28872
|
+
// src/guest/audit-parse.ts
|
|
28873
|
+
import path46 from "node:path";
|
|
28874
|
+
var NOISE = /* @__PURE__ */ new Set(["conhost.exe", "svchost.exe", "backgroundtaskhost.exe", "runtimebroker.exe", "wmiprvse.exe", "dllhost.exe", "searchprotocolhost.exe", "searchfilterhost.exe", "taskhostw.exe", "sppsvc.exe", "wermgr.exe", "consent.exe", "smartscreen.exe", "mpcmdrun.exe", "compattelrunner.exe", "wevtutil.exe", "audiodg.exe", "ctfmon.exe", "sihost.exe", "werfault.exe", "msmpeng.exe", "nissrv.exe", "usoclient.exe", "musnotification.exe"]);
|
|
28875
|
+
var decode3 = (s) => s.replace(/</g, "<").replace(/>/g, ">").replace(/"/g, '"').replace(/'/g, "'").replace(/&/g, "&");
|
|
28876
|
+
var field = (event, name) => decode3(new RegExp("<Data Name='" + name + "'>([^<]*)</Data>").exec(event)?.[1] ?? "");
|
|
28877
|
+
var parseProcessEvents = (xml) => {
|
|
28878
|
+
const lines = [];
|
|
28879
|
+
let last = 0;
|
|
28880
|
+
for (const event of xml.split("</Event>")) {
|
|
28881
|
+
const id = Number(/<EventRecordID>(\d+)<\/EventRecordID>/.exec(event)?.[1] ?? 0);
|
|
28882
|
+
if (!id) continue;
|
|
28883
|
+
last = Math.max(last, id);
|
|
28884
|
+
const program = field(event, "NewProcessName");
|
|
28885
|
+
if (!program || NOISE.has(path46.win32.basename(program).toLowerCase())) continue;
|
|
28886
|
+
const t = /SystemTime='([^']+)'/.exec(event)?.[1] ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
28887
|
+
lines.push(JSON.stringify({ t, k: "proc", p: program.slice(0, 1024), c: field(event, "CommandLine").slice(0, 2e3), pp: field(event, "ParentProcessName").slice(0, 1024) }));
|
|
28888
|
+
}
|
|
28889
|
+
return { lines, last };
|
|
28890
|
+
};
|
|
28891
|
+
|
|
28892
|
+
// src/guest/audit.ts
|
|
28893
|
+
var MAX_PER_PASS = 2e3;
|
|
28894
|
+
var auditOn = () => Boolean(session.auditProcesses) && isWin && !dryRun;
|
|
28895
|
+
var wevtutil = () => path47.join(process.env.WINDIR ?? "C:\\Windows", "System32", "wevtutil.exe");
|
|
28896
|
+
var newestRecord = () => {
|
|
28897
|
+
const r = spawnSync4(wevtutil(), ["qe", "Security", "/q:*[System[(EventID=4688)]]", "/f:xml", "/c:1", "/rd:true"], { encoding: "utf8", windowsHide: true });
|
|
28898
|
+
return parseProcessEvents(r.stdout ?? "").last;
|
|
28899
|
+
};
|
|
28900
|
+
var startProcessCollector = () => {
|
|
28901
|
+
if (!auditOn()) return;
|
|
28902
|
+
let last = newestRecord();
|
|
28903
|
+
const pass = () => {
|
|
28904
|
+
try {
|
|
28905
|
+
const r = spawnSync4(wevtutil(), ["qe", "Security", "/q:*[System[(EventID=4688) and (EventRecordID>" + last + ")]]", "/f:xml", "/c:" + MAX_PER_PASS], { encoding: "utf8", windowsHide: true, maxBuffer: 64 * 1024 * 1024 });
|
|
28906
|
+
const { lines, last: newest } = parseProcessEvents(r.stdout ?? "");
|
|
28907
|
+
if (newest) last = newest;
|
|
28908
|
+
if (lines.length) fs33.writeFileSync(path47.join(mkdirp(run.audit), Date.now() + "-" + process.pid + ".jsonl"), lines.join("\n") + "\n");
|
|
28909
|
+
} catch (e) {
|
|
28910
|
+
warn("audit: " + errMsg(e));
|
|
28911
|
+
}
|
|
28912
|
+
};
|
|
28913
|
+
setInterval(pass, 15e3).unref?.();
|
|
28914
|
+
};
|
|
28915
|
+
|
|
28157
28916
|
// src/guest/daemon/session.ts
|
|
28158
|
-
import
|
|
28917
|
+
import path52 from "node:path";
|
|
28159
28918
|
import crypto3 from "node:crypto";
|
|
28160
28919
|
import { spawn as spawn7 } from "node:child_process";
|
|
28161
28920
|
|
|
28162
28921
|
// src/shared/pty-client.ts
|
|
28163
|
-
import
|
|
28164
|
-
var FrameType = { Hello: 1, Input: 2, Resize: 3, Restart: 4, Ping: 5, Output: 16, Exit: 17, Error: 18, Restarting: 19, Status: 20 };
|
|
28922
|
+
import net3 from "node:net";
|
|
28923
|
+
var FrameType = { Hello: 1, Input: 2, Resize: 3, Restart: 4, Ping: 5, Output: 16, Exit: 17, Error: 18, Restarting: 19, Status: 20, Console: 21 };
|
|
28165
28924
|
var HelloFlag = { ControlOnly: 1, Query: 2 };
|
|
28166
28925
|
var encodeFrame = (type, payload = Buffer.alloc(0)) => {
|
|
28167
28926
|
const header = Buffer.alloc(5);
|
|
@@ -28178,8 +28937,8 @@ var helloFrame = (token, cols, rows, flags = 0) => {
|
|
|
28178
28937
|
};
|
|
28179
28938
|
var MAX_FRAME_BYTES = 1 << 20;
|
|
28180
28939
|
var connectOnce = (host, port, timeoutMs) => {
|
|
28181
|
-
return new Promise((
|
|
28182
|
-
const socket =
|
|
28940
|
+
return new Promise((resolve2, reject) => {
|
|
28941
|
+
const socket = net3.connect({ host, port });
|
|
28183
28942
|
const timer = setTimeout(() => {
|
|
28184
28943
|
socket.destroy();
|
|
28185
28944
|
reject(new Error("timed out connecting to " + host + ":" + port));
|
|
@@ -28187,7 +28946,7 @@ var connectOnce = (host, port, timeoutMs) => {
|
|
|
28187
28946
|
socket.once("connect", () => {
|
|
28188
28947
|
clearTimeout(timer);
|
|
28189
28948
|
socket.setNoDelay(true);
|
|
28190
|
-
|
|
28949
|
+
resolve2(socket);
|
|
28191
28950
|
});
|
|
28192
28951
|
socket.once("error", (e) => {
|
|
28193
28952
|
clearTimeout(timer);
|
|
@@ -28208,11 +28967,11 @@ var connect = async (endpoint, timeoutMs = 3e3) => {
|
|
|
28208
28967
|
};
|
|
28209
28968
|
var sendControl = async (endpoint, type) => {
|
|
28210
28969
|
const socket = await connect(endpoint);
|
|
28211
|
-
await new Promise((
|
|
28970
|
+
await new Promise((resolve2) => socket.end(Buffer.concat([helloFrame(endpoint.token, 80, 24, HelloFlag.ControlOnly), encodeFrame(type)]), resolve2));
|
|
28212
28971
|
};
|
|
28213
28972
|
|
|
28214
28973
|
// src/guest/cmdline.ts
|
|
28215
|
-
import
|
|
28974
|
+
import path48 from "node:path";
|
|
28216
28975
|
var quoted = (arg) => '"' + arg.replace(/(\\*)"/g, '$1$1\\"').replace(/(\\+)$/, "$1$1") + '"';
|
|
28217
28976
|
var quoteArg = (arg) => arg !== "" && !/[\s"]/.test(arg) ? arg : quoted(arg);
|
|
28218
28977
|
var cmdArgs = (args) => {
|
|
@@ -28223,11 +28982,11 @@ var cmdArgs = (args) => {
|
|
|
28223
28982
|
return !inQuotes && /[&|<>^]/.test(c) ? "^^^" + c : c;
|
|
28224
28983
|
}).join("");
|
|
28225
28984
|
};
|
|
28226
|
-
var commandLine = (file3, args) =>
|
|
28985
|
+
var commandLine = (file3, args) => path48.win32.basename(file3).toLowerCase() === "cmd.exe" ? [quoteArg(file3), cmdArgs(args)].filter(Boolean).join(" ") : [file3, ...args].map(quoteArg).join(" ");
|
|
28227
28986
|
|
|
28228
28987
|
// src/guest/ptyhost.ts
|
|
28229
|
-
import
|
|
28230
|
-
import
|
|
28988
|
+
import fs34 from "node:fs";
|
|
28989
|
+
import path49 from "node:path";
|
|
28231
28990
|
import { spawn as spawn6 } from "node:child_process";
|
|
28232
28991
|
var ensurePtyHost = () => ensureCompiled("ptyhost");
|
|
28233
28992
|
var waitForPtyHost = async (child, port, timeoutMs) => {
|
|
@@ -28243,33 +29002,37 @@ var waitForPtyHost = async (child, port, timeoutMs) => {
|
|
|
28243
29002
|
}
|
|
28244
29003
|
throw new Error("the session host did not start listening on port " + port);
|
|
28245
29004
|
};
|
|
28246
|
-
var ptyHostLog = (id) =>
|
|
29005
|
+
var ptyHostLog = (id) => path49.join(logsDir, "ptyhost-" + id + ".log");
|
|
28247
29006
|
var ptyHostLogTail = (id, lines = 12) => {
|
|
28248
29007
|
try {
|
|
28249
|
-
return
|
|
29008
|
+
return fs34.readFileSync(ptyHostLog(id), "utf8").trim().split(/\r?\n/).slice(-lines).join("\n");
|
|
28250
29009
|
} catch {
|
|
28251
29010
|
return "";
|
|
28252
29011
|
}
|
|
28253
29012
|
};
|
|
28254
|
-
var
|
|
28255
|
-
|
|
28256
|
-
|
|
28257
|
-
|
|
28258
|
-
|
|
28259
|
-
|
|
28260
|
-
|
|
29013
|
+
var conptyDll = () => {
|
|
29014
|
+
const dll = path49.join(toolsDir, "conpty", "conpty.dll");
|
|
29015
|
+
return session.provisioning.conpty?.enabled !== false && fs34.existsSync(dll) && fs34.existsSync(path49.join(toolsDir, "conpty", "OpenConsole.exe")) ? dll : null;
|
|
29016
|
+
};
|
|
29017
|
+
var startPtyHost = (o) => {
|
|
29018
|
+
const env = { ...o.env, PTYHOST_BIND: o.remote ? "any" : "loopback" };
|
|
29019
|
+
delete env.PTYHOST_CONPTY;
|
|
29020
|
+
const dll = conptyDll();
|
|
29021
|
+
if (dll) env.PTYHOST_CONPTY = dll;
|
|
29022
|
+
return spawn6(o.exe, [String(o.port), o.token, String(o.cols), String(o.rows), ptyHostLog(o.id), o.command, o.restartCommand], { cwd: o.cwd, env, detached: true, stdio: "ignore", windowsHide: true });
|
|
29023
|
+
};
|
|
28261
29024
|
|
|
28262
29025
|
// src/guest/setup/agents.ts
|
|
28263
|
-
import
|
|
28264
|
-
import
|
|
29026
|
+
import fs35 from "node:fs";
|
|
29027
|
+
import path50 from "node:path";
|
|
28265
29028
|
var harnessPaths = (name, harness) => {
|
|
28266
|
-
const dir =
|
|
29029
|
+
const dir = path50.join(toolsDir, "agents", name);
|
|
28267
29030
|
const exe = harness.hostExecutable ?? (harness.uvBin ? harness.uvBin + ".exe" : null);
|
|
28268
|
-
return { dir, exe: exe ?
|
|
29031
|
+
return { dir, exe: exe ? path50.join(dir, exe) : null, cmd: harness.npmBin ? path50.join(dir, harness.npmBin + ".cmd") : null };
|
|
28269
29032
|
};
|
|
28270
29033
|
var installViaNpm = async (name, harness, dir, env) => {
|
|
28271
29034
|
if (!harness.npmPackage) throw new Error("No npmPackage configured for " + name + " and no host executable was available.");
|
|
28272
|
-
const npmCli =
|
|
29035
|
+
const npmCli = path50.join(path50.dirname(process.execPath), "node_modules", "npm", "bin", "npm-cli.js");
|
|
28273
29036
|
const args = [npmCli, "install", "--global", "--prefix", dir, harness.npmPackage, "--no-fund", "--no-audit"];
|
|
28274
29037
|
log("Installing " + harness.npmPackage + " (this can take a minute)...");
|
|
28275
29038
|
if (dryRun) {
|
|
@@ -28280,7 +29043,7 @@ var installViaNpm = async (name, harness, dir, env) => {
|
|
|
28280
29043
|
await execAsync(process.execPath, args, { env });
|
|
28281
29044
|
};
|
|
28282
29045
|
var installViaUv = async (name, harness, dir, env) => {
|
|
28283
|
-
const uv =
|
|
29046
|
+
const uv = path50.join(toolsDir, "uv", "uv.exe");
|
|
28284
29047
|
log("Installing " + harness.uvPackage + " with uv (this can take a minute)...");
|
|
28285
29048
|
if (dryRun) {
|
|
28286
29049
|
log("(dry run) uv tool install " + harness.uvPackage);
|
|
@@ -28306,9 +29069,9 @@ var installHarness = async (name, harness, env, refresh) => {
|
|
|
28306
29069
|
}
|
|
28307
29070
|
mkdirp(p.dir);
|
|
28308
29071
|
if (session.provisioning.copyFromHost && harness.hostExecutable && name === session.harnessName) {
|
|
28309
|
-
const source =
|
|
29072
|
+
const source = path50.join(hostToolsDir, "agents", name, harness.hostExecutable);
|
|
28310
29073
|
if (exists(source) && p.exe) {
|
|
28311
|
-
|
|
29074
|
+
fs35.copyFileSync(source, p.exe);
|
|
28312
29075
|
log("Copied " + name + " from this PC: " + source);
|
|
28313
29076
|
return;
|
|
28314
29077
|
}
|
|
@@ -28327,11 +29090,13 @@ var resolveLaunch = (name, harness) => {
|
|
|
28327
29090
|
};
|
|
28328
29091
|
|
|
28329
29092
|
// src/guest/setup/network.ts
|
|
28330
|
-
import
|
|
28331
|
-
|
|
29093
|
+
import os9 from "node:os";
|
|
29094
|
+
import path51 from "node:path";
|
|
29095
|
+
var HOSTS_FILE = path51.join(process.env.WINDIR ?? "C:\\Windows", "System32", "drivers", "etc", "hosts");
|
|
29096
|
+
var guestAddresses = () => Object.values(os9.networkInterfaces()).flat().filter((i) => Boolean(i) && i.family === "IPv4" && !i.internal).map((i) => i.address);
|
|
28332
29097
|
|
|
28333
29098
|
// src/guest/daemon/shutdown.ts
|
|
28334
|
-
import { spawnSync as
|
|
29099
|
+
import { spawnSync as spawnSync5 } from "node:child_process";
|
|
28335
29100
|
var maybeShutdown = () => {
|
|
28336
29101
|
if (!session.headless || !isWin) return;
|
|
28337
29102
|
const idle = () => live.size === 0 && pending.starting === 0 && scanRequests(dataDir).valid.length === 0;
|
|
@@ -28340,14 +29105,14 @@ var maybeShutdown = () => {
|
|
|
28340
29105
|
if (!idle()) return;
|
|
28341
29106
|
log("Headless sandbox has no sessions left; shutting down.");
|
|
28342
29107
|
safely("claude-mem save", saveClaudeMem);
|
|
28343
|
-
|
|
29108
|
+
spawnSync5(SYSTEM.shutdown(), ["/s", "/t", "5"], { windowsHide: true });
|
|
28344
29109
|
}, 15e3);
|
|
28345
29110
|
};
|
|
28346
29111
|
|
|
28347
29112
|
// src/guest/daemon/session.ts
|
|
28348
29113
|
var terminalTab = (id, title, cwd) => {
|
|
28349
|
-
const view = [process.execPath,
|
|
28350
|
-
const wt =
|
|
29114
|
+
const view = [process.execPath, path52.join(path52.dirname(process.argv[1]), "view.js"), id];
|
|
29115
|
+
const wt = path52.join(toolsDir, "terminal", "wt.exe");
|
|
28351
29116
|
if (exists(wt)) spawn7(wt, ["-w", "0", "nt", "--title", title, "-d", cwd, ...view], { detached: true, stdio: "ignore" }).unref();
|
|
28352
29117
|
else spawn7(SYSTEM.cmd(), ["/d", "/c", "start", title, ...view], { detached: true, stdio: "ignore", cwd }).unref();
|
|
28353
29118
|
};
|
|
@@ -28392,7 +29157,7 @@ var launchPtyHost = async (req, remote, env, say) => {
|
|
|
28392
29157
|
await waitForPtyHost(child, port, 15e3);
|
|
28393
29158
|
} catch (e) {
|
|
28394
29159
|
const tail = ptyHostLogTail(req.id);
|
|
28395
|
-
throw new Error(errMsg(e) + (tail ? ". From its log:\n" + tail : "") + "\nLog: " +
|
|
29160
|
+
throw new Error(errMsg(e) + (tail ? ". From its log:\n" + tail : "") + "\nLog: " + path52.join(dataDir, "logs", "ptyhost-" + req.id + ".log"));
|
|
28396
29161
|
}
|
|
28397
29162
|
return { child, port, token };
|
|
28398
29163
|
};
|
|
@@ -28414,7 +29179,7 @@ var startSession = async (req) => {
|
|
|
28414
29179
|
saveStatus(status);
|
|
28415
29180
|
};
|
|
28416
29181
|
pending.starting++;
|
|
28417
|
-
if (req.id !== session.launchId && process.env.AGENT_NO_TABS !== "1") safely("terminal tab", () => terminalTab(req.id, req.harness + " " +
|
|
29182
|
+
if (req.id !== session.launchId && process.env.AGENT_NO_TABS !== "1") safely("terminal tab", () => terminalTab(req.id, req.harness + " " + path52.basename(req.cwd), req.cwd));
|
|
28418
29183
|
try {
|
|
28419
29184
|
const place = await placeFor(req, say);
|
|
28420
29185
|
const remote = session.networking && session.attach.enabled;
|
|
@@ -28470,9 +29235,9 @@ var handle = (req) => {
|
|
|
28470
29235
|
};
|
|
28471
29236
|
var tick = () => {
|
|
28472
29237
|
const { valid, invalid } = scanRequests(dataDir);
|
|
28473
|
-
for (const file3 of invalid) safely("removing an invalid request", () =>
|
|
29238
|
+
for (const file3 of invalid) safely("removing an invalid request", () => fs36.rmSync(file3, { recursive: true, force: true }));
|
|
28474
29239
|
for (const req of valid) {
|
|
28475
|
-
safely("claiming a request", () =>
|
|
29240
|
+
safely("claiming a request", () => fs36.rmSync(run.request(req.id), { force: true }));
|
|
28476
29241
|
if (readSession(dataDir, req.id)) continue;
|
|
28477
29242
|
void Promise.resolve(handle(req)).catch((e) => respond(req.id, { ok: false, message: errMsg(e) }));
|
|
28478
29243
|
}
|
|
@@ -28491,4 +29256,6 @@ var loop = () => {
|
|
|
28491
29256
|
}
|
|
28492
29257
|
};
|
|
28493
29258
|
log("Session daemon started (pid " + process.pid + ").");
|
|
29259
|
+
safely("port forwards", startRelays);
|
|
29260
|
+
safely("audit", startProcessCollector);
|
|
28494
29261
|
loop();
|