windows-development-sandbox 1.1.0 → 1.4.1
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/.sandbox-config.example.json +2 -1
- package/README.md +3 -2
- package/config.example.json +39 -5
- package/dist/cli/args.d.ts +3 -0
- package/dist/cli/args.js +3 -1
- package/dist/cli/boot-progress.d.ts +22 -0
- package/dist/cli/boot-progress.js +59 -0
- 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.d.ts +5 -2
- package/dist/cli/commands/launch.js +113 -25
- package/dist/cli/commands/maintenance.d.ts +2 -0
- package/dist/cli/commands/maintenance.js +70 -4
- package/dist/cli/commands/project.d.ts +10 -6
- package/dist/cli/commands/project.js +42 -3
- package/dist/cli/commands/restart.js +17 -7
- package/dist/cli/commands/sessions.js +5 -4
- package/dist/cli/commands/user-config.js +1 -1
- package/dist/cli/index.js +6 -4
- package/dist/cli/manifest.js +6 -1
- 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/progress.d.ts +15 -0
- package/dist/cli/progress.js +52 -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 +10 -7
- package/dist/core/local-config.d.ts +31 -1
- package/dist/core/local-config.js +72 -7
- package/dist/core/project-policy.d.ts +50 -3
- package/dist/core/project-policy.js +90 -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 +69 -3
- 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/projects.d.ts +1 -0
- package/dist/core/schema/projects.js +1 -0
- package/dist/core/schema/sandbox.d.ts +29 -1
- package/dist/core/schema/sandbox.js +29 -1
- package/dist/core/schema/toolchains.d.ts +3 -0
- package/dist/core/schema/toolchains.js +6 -1
- package/dist/core/types.d.ts +24 -1
- package/dist/core/util.d.ts +2 -0
- package/dist/core/util.js +2 -0
- package/dist/core/workspace.d.ts +21 -4
- package/dist/core/workspace.js +99 -21
- 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 +7 -2
- package/dist/guest/env.js +17 -3
- package/dist/guest/helpers.d.ts +1 -1
- package/dist/guest/main.js +20 -3
- 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/index.js +29 -3
- 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/channel.d.ts +2 -2
- package/dist/host/channel.js +3 -2
- package/dist/host/generate.d.ts +7 -1
- package/dist/host/generate.js +23 -6
- package/dist/host/join.d.ts +7 -0
- package/dist/host/join.js +23 -9
- package/dist/host/launch/mappings.d.ts +7 -2
- package/dist/host/launch/mappings.js +68 -18
- package/dist/host/launch/projects.d.ts +2 -0
- package/dist/host/launch/projects.js +11 -5
- 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/projects.d.ts +25 -2
- package/dist/host/projects.js +54 -5
- 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 +1387 -558
- package/dist/runtime/db.js +199 -14
- package/dist/runtime/main.js +3082 -631
- package/dist/runtime/netproxy.js +25948 -0
- package/dist/runtime/view.js +531 -148
- package/dist/selftest/audit.test.d.ts +2 -0
- package/dist/selftest/audit.test.js +57 -0
- package/dist/selftest/channel.test.js +45 -2
- package/dist/selftest/cli.test.js +47 -17
- package/dist/selftest/fixtures.d.ts +47 -1
- package/dist/selftest/fixtures.js +3 -1
- package/dist/selftest/generate.test.js +7 -2
- package/dist/selftest/index.js +6 -2
- package/dist/selftest/live-network.test.d.ts +2 -0
- package/dist/selftest/live-network.test.js +63 -0
- package/dist/selftest/live-terminal.test.d.ts +2 -0
- package/dist/selftest/live-terminal.test.js +169 -0
- package/dist/selftest/local-config.test.js +42 -4
- package/dist/selftest/mirror.test.js +36 -7
- package/dist/selftest/network.test.js +12 -0
- package/dist/selftest/projects.test.js +77 -8
- 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/console-input.d.ts +11 -0
- package/dist/shared/console-input.js +61 -0
- package/dist/shared/download.d.ts +3 -0
- package/dist/shared/download.js +25 -2
- package/dist/shared/guest-paths.d.ts +27 -0
- package/dist/shared/guest-paths.js +68 -0
- package/dist/shared/netpolicy.d.ts +27 -0
- package/dist/shared/netpolicy.js +51 -0
- package/dist/shared/projects.d.ts +27 -4
- package/dist/shared/projects.js +72 -13
- package/dist/shared/pty-client.d.ts +26 -4
- package/dist/shared/pty-client.js +204 -25
- package/dist/shared/rundir.d.ts +2 -0
- package/dist/shared/rundir.js +2 -0
- package/dist/shared/schema.d.ts +34 -0
- package/dist/shared/schema.js +14 -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 +162 -7
- package/schemas/config.schema.json +318 -3
- package/schemas/sandbox-config.schema.json +129 -14
- 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,15 +25310,17 @@ 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
|
|
25318
25320
|
var GuestWorkspace = external_exports.union([external_exports.literal("auto"), external_exports.literal("mirror"), GuestPath]).describe('Where the workspace appears inside the sandbox. "auto" = C:\\Workspace\\<folder name>. "mirror" = the same path as on this PC, so absolute paths in configs and build caches match (another drive letter such as F: is a subst drive onto C:\\Mirror\\F); paths the sandbox reserves (C:\\Users\\..., C:\\Program Files\\...) fall back to "auto".');
|
|
25319
25321
|
var Mapping = external_exports.strictObject({
|
|
25320
25322
|
host: external_exports.string().min(1).describe("Folder on this PC (relative paths are relative to the config file)."),
|
|
25321
|
-
guest:
|
|
25323
|
+
guest: external_exports.string().min(1).max(1024).optional().describe("Where it appears inside the sandbox, e.g. C:\\Assets, or on another drive letter (D: to Z:) such as F:\\SteamLibrary\\steamapps\\common\\Game (shown as F: at boot). Leave it out to use the same path as on this PC (a folder inside the project stays where it is in the project). A path the sandbox cannot use (C:\\Windows\\..., C:\\Users\\..., one already in use) goes to C:\\Mapped\\<drive>\\<path> instead, and the launch says so."),
|
|
25322
25324
|
readOnly: external_exports.boolean().describe("true = the agent can only read it."),
|
|
25323
25325
|
optional: external_exports.boolean().optional().describe("true = skip it quietly when the host folder does not exist.")
|
|
25324
25326
|
});
|
|
@@ -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."),
|
|
@@ -25438,6 +25608,7 @@ var Projects = external_exports.strictObject({
|
|
|
25438
25608
|
roots: external_exports.array(external_exports.string().min(1)).describe('Folders whose subfolders are your projects (e.g. "F:\\\\Code"), mapped read/write at every start. Any project inside one, including ones you create later, opens in the running sandbox at once, without a restart. Every agent in the sandbox can see all of them.'),
|
|
25439
25609
|
askToAddRoot: external_exports.boolean().describe("When you start a project whose parent folder is not a root yet, ask once whether to add it."),
|
|
25440
25610
|
declinedRoots: external_exports.array(external_exports.string().min(1)).describe("Parent folders you said no to (not asked again)."),
|
|
25611
|
+
allowOutsideMappings: external_exports.union([external_exports.literal("ask"), external_exports.boolean()]).describe(`A project's .sandbox-config.json may map folders from outside the project (e.g. a game folder on another drive). "ask" = an interactive launch asks once per project and set of folders, and remembers your answer; true = always allowed (still listed when you approve the file); false = never (the launch stops and says which folders). Only your own settings decide this, never a project file.`),
|
|
25441
25612
|
wsbShare: external_exports.boolean().describe("On Windows 11 24H2+ with the Windows Sandbox command line (wsb), add other folders to the running sandbox with `wsb share` (untested). Otherwise starting a project outside every root offers a restart.")
|
|
25442
25613
|
});
|
|
25443
25614
|
|
|
@@ -25447,14 +25618,18 @@ var Config = external_exports.strictObject({
|
|
|
25447
25618
|
defaultHarness: Name.describe("Agent started by `sandbox launch` (sandbox claude always runs claude)."),
|
|
25448
25619
|
guestWorkspace: GuestWorkspace,
|
|
25449
25620
|
readOnly: external_exports.boolean().describe("Map the workspace read-only."),
|
|
25621
|
+
workspaceFilter: WorkspaceFilter,
|
|
25622
|
+
audit: Audit,
|
|
25450
25623
|
mappings: external_exports.array(Mapping).describe("Extra folders from this PC."),
|
|
25451
25624
|
sandbox: Sandbox,
|
|
25452
25625
|
storage: external_exports.strictObject({
|
|
25453
25626
|
root: external_exports.string().min(1).describe("Where everything is kept on this PC (tools, databases, logins, launches)."),
|
|
25454
25627
|
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.")
|
|
25628
|
+
dataName: Name.describe("Name of the persistent data set (C:\\AgentData) shared by all workspaces."),
|
|
25629
|
+
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.`),
|
|
25630
|
+
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
25631
|
}),
|
|
25457
|
-
network:
|
|
25632
|
+
network: Network,
|
|
25458
25633
|
provisioning: Provisioning,
|
|
25459
25634
|
downloads: Downloads,
|
|
25460
25635
|
toolchains: Toolchains,
|
|
@@ -25463,6 +25638,7 @@ var Config = external_exports.strictObject({
|
|
|
25463
25638
|
agentCommands: AgentCommands,
|
|
25464
25639
|
secrets: Secrets,
|
|
25465
25640
|
personalization: toggle("Copy your desktop look (theme, accent, taskbar, wallpaper, ...) into the sandbox."),
|
|
25641
|
+
apps: Apps,
|
|
25466
25642
|
claudeProfile: ClaudeProfile,
|
|
25467
25643
|
harnesses: external_exports.record(Name, Harness).describe("Agents that can run in the sandbox."),
|
|
25468
25644
|
hooks: external_exports.strictObject({ failFast: external_exports.boolean().describe("Stop when a hook script fails.") }),
|
|
@@ -25473,10 +25649,14 @@ var LocalOverrides = external_exports.strictObject({
|
|
|
25473
25649
|
harness: Name.describe("Agent for this project."),
|
|
25474
25650
|
guestWorkspace: GuestWorkspace,
|
|
25475
25651
|
readOnly: external_exports.boolean().describe("Map this project read-only."),
|
|
25476
|
-
|
|
25652
|
+
// A project may turn the filter on and keep more out, never let ignored files in.
|
|
25653
|
+
workspaceFilter: WorkspaceFilter.pick({ enabled: true, exclude: true }).partial(),
|
|
25654
|
+
mappings: external_exports.array(Mapping).describe("Extra folders (relative paths are relative to this file), e.g. a read-only data folder at another place in the sandbox. Folders outside the project are used only as your projects.allowOutsideMappings setting allows (by default you are asked once)."),
|
|
25477
25655
|
scripts: Strings.describe("Scripts (.ps1 / .mjs / .cmd, relative to this file) run inside the sandbox before the agent."),
|
|
25478
|
-
|
|
25479
|
-
|
|
25656
|
+
// This PC's resources are yours to share: CPU and paging file (this PC's disk) are not a project's to set.
|
|
25657
|
+
sandbox: Sandbox.omit({ cpuLimit: true, pageFileMb: true }).partial(),
|
|
25658
|
+
// A project may block more (the LAN, hosts); it never opens hosts, ports, DNS or a proxy.
|
|
25659
|
+
network: Network.pick({ blockPrivateRanges: true, blockHosts: true }).partial(),
|
|
25480
25660
|
provisioning: Provisioning.pick({ copyFromHost: true, fallbackToInstall: true, refresh: true }).extend({ git: Git.partial(), terminal: toggle("Windows Terminal as the sandbox window.").partial() }).partial(),
|
|
25481
25661
|
downloads: Downloads.partial(),
|
|
25482
25662
|
// Every toolchain setting, each one optional (a project usually only switches languages on or pins a version).
|
|
@@ -25487,7 +25667,9 @@ var LocalOverrides = external_exports.strictObject({
|
|
|
25487
25667
|
databases: external_exports.strictObject(import_lodash.default.mapValues(Databases.shape, (shape) => shape.partial())).partial(),
|
|
25488
25668
|
attach: Attach.partial(),
|
|
25489
25669
|
personalization: toggle("Copy your desktop look into the sandbox.").partial(),
|
|
25490
|
-
|
|
25670
|
+
// Catalogue apps only (a vetted list): your own programs (apps.custom) download anything, so a repo cannot add them.
|
|
25671
|
+
apps: Apps.pick({ install: true }).partial(),
|
|
25672
|
+
claudeProfile: ClaudeProfile.pick({ enabled: true, overwrite: true, copyCredentials: true, syncHistory: true, syncClaudeMem: true }).partial(),
|
|
25491
25673
|
hooks: external_exports.strictObject({ failFast: external_exports.boolean() }).partial()
|
|
25492
25674
|
}).partial();
|
|
25493
25675
|
|
|
@@ -25500,6 +25682,15 @@ var AttachEndpoint = external_exports.strictObject({
|
|
|
25500
25682
|
port: external_exports.number().int().min(1024).max(65535),
|
|
25501
25683
|
token: Text(256)
|
|
25502
25684
|
});
|
|
25685
|
+
var BootProgress = external_exports.strictObject({
|
|
25686
|
+
step: external_exports.number().int().min(1).max(32),
|
|
25687
|
+
steps: external_exports.number().int().min(1).max(32),
|
|
25688
|
+
title: Text(120),
|
|
25689
|
+
/** Being set up now; percent while it downloads (when the size is known). */
|
|
25690
|
+
active: external_exports.array(external_exports.strictObject({ name: Text(64), percent: external_exports.number().int().min(0).max(100).optional() })).max(8),
|
|
25691
|
+
done: external_exports.number().int().min(0).max(1e3),
|
|
25692
|
+
total: external_exports.number().int().min(0).max(1e3)
|
|
25693
|
+
});
|
|
25503
25694
|
var SandboxStatus = external_exports.object({
|
|
25504
25695
|
launchId: Text(64),
|
|
25505
25696
|
phase: external_exports.enum(["booting", "provisioning", "ready", "failed"]),
|
|
@@ -25507,7 +25698,11 @@ var SandboxStatus = external_exports.object({
|
|
|
25507
25698
|
updatedAt: Time,
|
|
25508
25699
|
workspaceHost: Text(),
|
|
25509
25700
|
guestWorkspace: Text(),
|
|
25510
|
-
headless: external_exports.boolean()
|
|
25701
|
+
headless: external_exports.boolean(),
|
|
25702
|
+
/** The sandbox's IPv4 addresses (for network.forwardPorts; the host only uses ones on its Hyper-V network). */
|
|
25703
|
+
addresses: external_exports.array(external_exports.string().max(45)).max(8).optional(),
|
|
25704
|
+
/** A malformed progress is dropped, never the status (the phase still counts). */
|
|
25705
|
+
progress: BootProgress.optional().catch(void 0)
|
|
25511
25706
|
});
|
|
25512
25707
|
var Version = external_exports.strictObject({ spec: Text(128), source: Text(256) });
|
|
25513
25708
|
var DatabasePlan = external_exports.strictObject({
|
|
@@ -25615,6 +25810,8 @@ var runPaths = (dataDir2) => {
|
|
|
25615
25810
|
responses: path2.join(run2, "responses"),
|
|
25616
25811
|
sessions: path2.join(run2, "sessions"),
|
|
25617
25812
|
projects: path2.join(run2, "projects"),
|
|
25813
|
+
/** audit.processes: programs the sandbox started, in small .jsonl files the host takes in and deletes. */
|
|
25814
|
+
audit: path2.join(run2, "audit"),
|
|
25618
25815
|
request: file3("requests"),
|
|
25619
25816
|
response: file3("responses"),
|
|
25620
25817
|
session: file3("sessions"),
|
|
@@ -25674,7 +25871,7 @@ var now = () => (/* @__PURE__ */ new Date()).toISOString();
|
|
|
25674
25871
|
|
|
25675
25872
|
// src/guest/setup/claude.ts
|
|
25676
25873
|
import fs6 from "node:fs";
|
|
25677
|
-
import
|
|
25874
|
+
import os4 from "node:os";
|
|
25678
25875
|
import path7 from "node:path";
|
|
25679
25876
|
|
|
25680
25877
|
// src/shared/safe-remove.ts
|
|
@@ -25738,6 +25935,7 @@ var safeRemove = (target, root) => {
|
|
|
25738
25935
|
|
|
25739
25936
|
// src/guest/env.ts
|
|
25740
25937
|
import fs5 from "node:fs";
|
|
25938
|
+
import os3 from "node:os";
|
|
25741
25939
|
import path6 from "node:path";
|
|
25742
25940
|
import { spawnSync } from "node:child_process";
|
|
25743
25941
|
|
|
@@ -25765,7 +25963,8 @@ var SYSTEM = {
|
|
|
25765
25963
|
ipconfig: () => system32("ipconfig.exe"),
|
|
25766
25964
|
robocopy: () => system32("Robocopy.exe"),
|
|
25767
25965
|
shutdown: () => system32("shutdown.exe"),
|
|
25768
|
-
dism: () => system32("Dism.exe")
|
|
25966
|
+
dism: () => system32("Dism.exe"),
|
|
25967
|
+
msiexec: () => system32("msiexec.exe")
|
|
25769
25968
|
};
|
|
25770
25969
|
|
|
25771
25970
|
// src/shared/download.ts
|
|
@@ -25797,6 +25996,10 @@ var checksumRequired = false;
|
|
|
25797
25996
|
var setChecksumRequired = (on) => {
|
|
25798
25997
|
checksumRequired = on;
|
|
25799
25998
|
};
|
|
25999
|
+
var downloadWatcher = null;
|
|
26000
|
+
var watchDownloads = (watcher) => {
|
|
26001
|
+
downloadWatcher = watcher;
|
|
26002
|
+
};
|
|
25800
26003
|
var download = async (url2, destination, expected = null) => {
|
|
25801
26004
|
const sums = typeof expected === "string" || expected === null ? { sha256: expected } : expected;
|
|
25802
26005
|
if (checksumRequired && !sums.sha256?.trim() && !sums.sha512?.trim()) {
|
|
@@ -25809,8 +26012,25 @@ var download = async (url2, destination, expected = null) => {
|
|
|
25809
26012
|
const want = sums[kind]?.trim().toLowerCase();
|
|
25810
26013
|
return want ? [{ want, hash: crypto.createHash(kind) }] : [];
|
|
25811
26014
|
});
|
|
26015
|
+
const size = Number(response.headers.get("content-length")) || 0;
|
|
26016
|
+
const report = size > 0 ? downloadWatcher?.() ?? null : null;
|
|
26017
|
+
let received = 0;
|
|
26018
|
+
let tenth = 0;
|
|
26019
|
+
let reportedAt = Date.now();
|
|
25812
26020
|
const tap = new Transform({ transform(chunk, _encoding, done) {
|
|
25813
26021
|
for (const c of checks) c.hash.update(chunk);
|
|
26022
|
+
if (report) {
|
|
26023
|
+
received += chunk.length;
|
|
26024
|
+
const now2 = Math.floor(received * 10 / size);
|
|
26025
|
+
if (now2 !== tenth || Date.now() - reportedAt > 5e3) {
|
|
26026
|
+
tenth = now2;
|
|
26027
|
+
reportedAt = Date.now();
|
|
26028
|
+
try {
|
|
26029
|
+
report(Math.min(1, received / size));
|
|
26030
|
+
} catch {
|
|
26031
|
+
}
|
|
26032
|
+
}
|
|
26033
|
+
}
|
|
25814
26034
|
done(null, chunk);
|
|
25815
26035
|
} });
|
|
25816
26036
|
const partial2 = destination + ".part";
|
|
@@ -25823,10 +26043,10 @@ var download = async (url2, destination, expected = null) => {
|
|
|
25823
26043
|
fs4.rmSync(partial2, { force: true });
|
|
25824
26044
|
}
|
|
25825
26045
|
};
|
|
25826
|
-
var spawnAsync = (file3, args, options = {}) => new Promise((
|
|
26046
|
+
var spawnAsync = (file3, args, options = {}) => new Promise((resolve2, reject) => {
|
|
25827
26047
|
const child = spawn(file3, args, { stdio: "ignore", windowsHide: true, ...options });
|
|
25828
26048
|
child.once("error", reject);
|
|
25829
|
-
child.once("close", (code) =>
|
|
26049
|
+
child.once("close", (code) => resolve2(code ?? -1));
|
|
25830
26050
|
});
|
|
25831
26051
|
var toAsset = (asset) => ({ url: asset.browser_download_url, name: asset.name, sha256: asset.digest?.startsWith("sha256:") ? asset.digest.slice(7) : null });
|
|
25832
26052
|
var githubAsset = async (repo, pattern, searchOlder = false) => {
|
|
@@ -25958,15 +26178,25 @@ var mkdirp = (p) => {
|
|
|
25958
26178
|
fs5.mkdirSync(p, { recursive: true });
|
|
25959
26179
|
return p;
|
|
25960
26180
|
};
|
|
25961
|
-
var
|
|
26181
|
+
var progress;
|
|
26182
|
+
var setSandboxStatus = (phase, message, update) => {
|
|
25962
26183
|
try {
|
|
26184
|
+
if (update) progress = fitProgress({ step: 1, steps: 1, title: "", active: [], done: 0, total: 0, ...progress, ...update });
|
|
25963
26185
|
writeJsonAtomicChecked(phase, message);
|
|
25964
26186
|
} catch (e) {
|
|
25965
26187
|
warn("Could not update sandbox status: " + errMsg(e));
|
|
25966
26188
|
}
|
|
25967
26189
|
};
|
|
26190
|
+
var fitProgress = (p) => ({
|
|
26191
|
+
...p,
|
|
26192
|
+
title: p.title.slice(0, 120),
|
|
26193
|
+
done: Math.min(p.done, 1e3),
|
|
26194
|
+
total: Math.min(p.total, 1e3),
|
|
26195
|
+
active: p.active.slice(0, 8).map((a) => ({ name: a.name.slice(0, 64), ...a.percent === void 0 ? {} : { percent: Math.max(0, Math.min(100, Math.round(a.percent))) } }))
|
|
26196
|
+
});
|
|
26197
|
+
var ownAddresses = () => Object.values(os3.networkInterfaces()).flat().filter((i) => Boolean(i) && i.family === "IPv4" && !i.internal).map((i) => i.address).slice(0, 8);
|
|
25968
26198
|
var writeJsonAtomicChecked = (phase, message) => {
|
|
25969
|
-
writeJsonAtomic(run.sandbox, { launchId: session.launchId, phase, message, updatedAt: now(), workspaceHost: session.workspaceHost, guestWorkspace: workspace, headless: session.headless });
|
|
26199
|
+
writeJsonAtomic(run.sandbox, { launchId: session.launchId, phase, message, updatedAt: now(), workspaceHost: session.workspaceHost, guestWorkspace: workspace, headless: session.headless, addresses: ownAddresses(), ...progress ? { progress } : {} });
|
|
25970
26200
|
};
|
|
25971
26201
|
var exec = (file3, args, options = {}) => {
|
|
25972
26202
|
const result = spawnSync(file3, args, { stdio: "inherit", windowsHide: true, ...options });
|
|
@@ -26008,7 +26238,7 @@ var copyNode = (from, to) => {
|
|
|
26008
26238
|
};
|
|
26009
26239
|
|
|
26010
26240
|
// src/guest/setup/claude.ts
|
|
26011
|
-
var claudeMemPaths = { store: path7.join(stateDir, "claude-mem"), local: path7.join(
|
|
26241
|
+
var claudeMemPaths = { store: path7.join(stateDir, "claude-mem"), local: path7.join(os4.homedir(), ".claude-mem") };
|
|
26012
26242
|
var claudeMemEnabled = () => session.claudeProfile.syncClaudeMem && !dryRun;
|
|
26013
26243
|
var databaseFingerprint = (dir) => {
|
|
26014
26244
|
const parts = [];
|
|
@@ -26026,11 +26256,39 @@ var databaseFingerprint = (dir) => {
|
|
|
26026
26256
|
return parts.sort().join("|");
|
|
26027
26257
|
};
|
|
26028
26258
|
var lastSaved = null;
|
|
26259
|
+
var SQLITE_HEADER = "SQLite format 3\0";
|
|
26260
|
+
var looksLikeSqlite = (file3) => {
|
|
26261
|
+
if (!exists(file3)) return true;
|
|
26262
|
+
const fd = fs6.openSync(file3, "r");
|
|
26263
|
+
try {
|
|
26264
|
+
const head = Buffer.alloc(16);
|
|
26265
|
+
return fs6.readSync(fd, head, 0, 16, 0) === 16 && head.toString("latin1") === SQLITE_HEADER;
|
|
26266
|
+
} finally {
|
|
26267
|
+
fs6.closeSync(fd);
|
|
26268
|
+
}
|
|
26269
|
+
};
|
|
26270
|
+
var MAX_BACKUPS = 3;
|
|
26271
|
+
var BACKUP_EVERY_MS = 6 * 3600 * 1e3;
|
|
26272
|
+
var keepBackup = (previous, dir) => {
|
|
26273
|
+
if (!exists(previous)) return;
|
|
26274
|
+
const backups = exists(dir) ? fs6.readdirSync(dir).filter((n) => /^\d{13}$/.test(n)).sort() : [];
|
|
26275
|
+
const newest = Number(backups[backups.length - 1] ?? 0);
|
|
26276
|
+
if (Date.now() - newest < BACKUP_EVERY_MS) {
|
|
26277
|
+
fs6.rmSync(previous, { recursive: true, force: true });
|
|
26278
|
+
return;
|
|
26279
|
+
}
|
|
26280
|
+
fs6.renameSync(previous, path7.join(mkdirp(dir), String(Date.now())));
|
|
26281
|
+
for (const old of [...backups, String(Date.now())].slice(0, -MAX_BACKUPS)) fs6.rmSync(path7.join(dir, old), { recursive: true, force: true });
|
|
26282
|
+
};
|
|
26029
26283
|
var saveClaudeMem = () => {
|
|
26030
26284
|
if (!claudeMemEnabled() || !exists(claudeMemPaths.local)) return;
|
|
26031
26285
|
const { store: store2, local } = claudeMemPaths;
|
|
26032
26286
|
const fingerprint = databaseFingerprint(local);
|
|
26033
26287
|
if (fingerprint === lastSaved && exists(store2)) return;
|
|
26288
|
+
if (!looksLikeSqlite(path7.join(local, "claude-mem.db"))) {
|
|
26289
|
+
warn("claude-mem: the local database does not look valid, so it was not saved over the stored copy (" + local + ").");
|
|
26290
|
+
return;
|
|
26291
|
+
}
|
|
26034
26292
|
const incoming = store2 + ".incoming";
|
|
26035
26293
|
const previous = store2 + ".previous";
|
|
26036
26294
|
fs6.rmSync(incoming, { recursive: true, force: true });
|
|
@@ -26043,7 +26301,7 @@ var saveClaudeMem = () => {
|
|
|
26043
26301
|
if (exists(previous)) fs6.renameSync(previous, store2);
|
|
26044
26302
|
throw e;
|
|
26045
26303
|
}
|
|
26046
|
-
|
|
26304
|
+
keepBackup(previous, store2 + ".backups");
|
|
26047
26305
|
lastSaved = fingerprint;
|
|
26048
26306
|
};
|
|
26049
26307
|
|
|
@@ -26051,12 +26309,13 @@ var saveClaudeMem = () => {
|
|
|
26051
26309
|
import { spawn as spawn5 } from "node:child_process";
|
|
26052
26310
|
|
|
26053
26311
|
// src/guest/daemon/project.ts
|
|
26054
|
-
import
|
|
26055
|
-
import
|
|
26312
|
+
import fs32 from "node:fs";
|
|
26313
|
+
import path45 from "node:path";
|
|
26056
26314
|
|
|
26057
26315
|
// src/shared/projects.ts
|
|
26058
26316
|
import path8 from "node:path";
|
|
26059
26317
|
var PROJECTS_GUEST = "C:\\Projects";
|
|
26318
|
+
var WORKSPACES_GUEST = "C:\\Workspace";
|
|
26060
26319
|
var norm2 = (p) => path8.win32.resolve(p).replace(/[\\/]+$/, "").toLowerCase();
|
|
26061
26320
|
var isWithin = (parent, child) => {
|
|
26062
26321
|
const a = norm2(parent);
|
|
@@ -26070,7 +26329,7 @@ var hubName = (hostDir, taken) => {
|
|
|
26070
26329
|
for (let i = 2; ; i++) if (!used.has((base + "-" + i).toLowerCase())) return base + "-" + i;
|
|
26071
26330
|
};
|
|
26072
26331
|
var isBelow = (parent, child) => isWithin(parent, child) && norm2(parent) !== norm2(child);
|
|
26073
|
-
var insideProjects = (guestDir, roots = [], projectsDir = PROJECTS_GUEST) => isBelow(projectsDir, guestDir) || roots.some((r) => isWithin(r, guestDir));
|
|
26332
|
+
var insideProjects = (guestDir, roots = [], projectsDir = PROJECTS_GUEST) => isBelow(projectsDir, guestDir) || isBelow(WORKSPACES_GUEST, guestDir) || roots.some((r) => isWithin(r, guestDir));
|
|
26074
26333
|
|
|
26075
26334
|
// src/guest/daemon/state.ts
|
|
26076
26335
|
import path9 from "node:path";
|
|
@@ -26294,6 +26553,9 @@ var runHooksAsync = async (stage, env, target) => {
|
|
|
26294
26553
|
}
|
|
26295
26554
|
};
|
|
26296
26555
|
|
|
26556
|
+
// src/guest/toolchains/index.ts
|
|
26557
|
+
import { AsyncLocalStorage as AsyncLocalStorage2 } from "node:async_hooks";
|
|
26558
|
+
|
|
26297
26559
|
// src/guest/toolchains/common.ts
|
|
26298
26560
|
import fs10 from "node:fs";
|
|
26299
26561
|
import path14 from "node:path";
|
|
@@ -26387,11 +26649,11 @@ var remembered = () => Object.fromEntries(Object.entries(readState(resolvedFile(
|
|
|
26387
26649
|
var FRESH_MS = 24 * 60 * 60 * 1e3;
|
|
26388
26650
|
var offline = false;
|
|
26389
26651
|
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,
|
|
26652
|
+
var resolveCached = async (key, resolve2) => {
|
|
26391
26653
|
const cached2 = remembered()[key];
|
|
26392
26654
|
if (cached2 && (offline || !session.provisioning.refresh && Date.now() - cached2.at < FRESH_MS)) return cached2.value;
|
|
26393
26655
|
try {
|
|
26394
|
-
const value = await
|
|
26656
|
+
const value = await resolve2();
|
|
26395
26657
|
fs10.mkdirSync(toolsDir, { recursive: true });
|
|
26396
26658
|
writeJsonAtomic(resolvedFile(), { ...remembered(), [key]: { value, at: Date.now() } });
|
|
26397
26659
|
return value;
|
|
@@ -26445,11 +26707,11 @@ var workspaceEntries = () => {
|
|
|
26445
26707
|
return found;
|
|
26446
26708
|
};
|
|
26447
26709
|
var wanted = (setting, toolchain) => setting === "auto" ? projectUses(workspaceEntries(), MARKERS[toolchain] ?? []) : setting;
|
|
26448
|
-
var versionFromFiles = (files,
|
|
26710
|
+
var versionFromFiles = (files, parse5 = (t) => specFromVersionFile(t)) => {
|
|
26449
26711
|
for (const name of files) {
|
|
26450
26712
|
const file3 = path14.join(projectWorkspace(), name);
|
|
26451
26713
|
if (!exists(file3)) continue;
|
|
26452
|
-
const spec =
|
|
26714
|
+
const spec = parse5(fs10.readFileSync(file3, "utf8"), name);
|
|
26453
26715
|
if (spec) return { spec, source: name };
|
|
26454
26716
|
}
|
|
26455
26717
|
return null;
|
|
@@ -26472,16 +26734,280 @@ var installOnce = async (env, group, packages, install) => {
|
|
|
26472
26734
|
};
|
|
26473
26735
|
|
|
26474
26736
|
// src/guest/toolchains/plan.ts
|
|
26475
|
-
import
|
|
26737
|
+
import fs31 from "node:fs";
|
|
26738
|
+
import os8 from "node:os";
|
|
26739
|
+
import path44 from "node:path";
|
|
26740
|
+
|
|
26741
|
+
// src/guest/apps/index.ts
|
|
26742
|
+
import fs11 from "node:fs";
|
|
26743
|
+
import os5 from "node:os";
|
|
26744
|
+
import path15 from "node:path";
|
|
26745
|
+
|
|
26746
|
+
// src/guest/apps/resolvers.ts
|
|
26747
|
+
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;
|
|
26748
|
+
var firstHash = (text) => /\b([0-9a-f]{64})\b/i.exec(text)?.[1].toLowerCase() ?? null;
|
|
26749
|
+
var stripV = (tag) => tag.replace(/^v/, "");
|
|
26750
|
+
var RESOLVERS = {
|
|
26751
|
+
sublime: async () => {
|
|
26752
|
+
const { latest_version: build } = await fetchJson("https://www.sublimetext.com/updates/4/stable_update_check");
|
|
26753
|
+
return { url: "https://download.sublimetext.com/sublime_text_build_" + build + "_x64.zip", fileName: "sublime_text_" + build + ".zip" };
|
|
26754
|
+
},
|
|
26755
|
+
pgadmin: async () => {
|
|
26756
|
+
const versions = (await fetchJson("https://www.postgresql.org/versions.json")).filter((v) => v.supported);
|
|
26757
|
+
const current = versions.find((v) => v.current) ?? versions[versions.length - 1];
|
|
26758
|
+
const exact = current.major + "." + current.latestMinor;
|
|
26759
|
+
return { url: "https://get.enterprisedb.com/postgresql/postgresql-" + exact + "-1-windows-x64-binaries.zip", fileName: "postgresql-" + exact + ".zip", members: ["pgsql/pgAdmin 4"] };
|
|
26760
|
+
},
|
|
26761
|
+
everything: async () => {
|
|
26762
|
+
const page = await fetchText("https://www.voidtools.com/downloads/");
|
|
26763
|
+
const version2 = /Everything-([\d.]+)\.x64\.zip/.exec(page)?.[1];
|
|
26764
|
+
if (!version2) throw new Error("could not find the Everything download on voidtools.com");
|
|
26765
|
+
const file3 = "Everything-" + version2 + ".x64.zip";
|
|
26766
|
+
const sums = await fetchText("https://www.voidtools.com/Everything-" + version2 + ".sha256").catch(() => "");
|
|
26767
|
+
return { url: "https://www.voidtools.com/" + file3, fileName: file3, sha256: sumFor(sums, file3) };
|
|
26768
|
+
},
|
|
26769
|
+
chrome: async () => {
|
|
26770
|
+
const data = await fetchJson("https://googlechromelabs.github.io/chrome-for-testing/last-known-good-versions-with-downloads.json");
|
|
26771
|
+
const hit = data.channels.Stable.downloads.chrome.find((d) => d.platform === "win64");
|
|
26772
|
+
if (!hit) throw new Error("no win64 Chrome for Testing build listed");
|
|
26773
|
+
return { url: hit.url, fileName: "chrome-win64.zip" };
|
|
26774
|
+
},
|
|
26775
|
+
firefox: async () => {
|
|
26776
|
+
const { LATEST_FIREFOX_VERSION: v } = await fetchJson("https://product-details.mozilla.org/1.0/firefox_versions.json");
|
|
26777
|
+
const base = "https://archive.mozilla.org/pub/firefox/releases/" + v + "/";
|
|
26778
|
+
const sums = await fetchText(base + "SHA256SUMS");
|
|
26779
|
+
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") };
|
|
26780
|
+
},
|
|
26781
|
+
blender: async () => {
|
|
26782
|
+
const releases = await fetchText("https://download.blender.org/release/");
|
|
26783
|
+
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();
|
|
26784
|
+
if (!series) throw new Error("could not list Blender releases");
|
|
26785
|
+
const folder = "https://download.blender.org/release/Blender" + series[0] + "." + series[1] + "/";
|
|
26786
|
+
const listing = await fetchText(folder);
|
|
26787
|
+
const files = [...listing.matchAll(/href="(blender-([\d.]+)-windows-x64\.zip)"/g)].map((m) => ({ file: m[1], v: m[2].split(".").map(Number) }));
|
|
26788
|
+
const latest = files.sort((a, b) => a.v[2] - b.v[2]).pop();
|
|
26789
|
+
if (!latest) throw new Error("no Windows build in " + folder);
|
|
26790
|
+
const sums = await fetchText(folder + "blender-" + latest.v.join(".") + ".sha256").catch(() => "");
|
|
26791
|
+
return { url: folder + latest.file, fileName: latest.file, sha256: sumFor(sums, latest.file) };
|
|
26792
|
+
},
|
|
26793
|
+
kubectl: async () => {
|
|
26794
|
+
const v = (await fetchText("https://dl.k8s.io/release/stable.txt")).trim();
|
|
26795
|
+
const url2 = "https://dl.k8s.io/release/" + v + "/bin/windows/amd64/kubectl.exe";
|
|
26796
|
+
return { url: url2, fileName: "kubectl.exe", sha256: firstHash(await fetchText(url2 + ".sha256")) };
|
|
26797
|
+
},
|
|
26798
|
+
helm: async () => {
|
|
26799
|
+
const v = await latestGithubTag("helm/helm");
|
|
26800
|
+
const url2 = "https://get.helm.sh/helm-" + v + "-windows-amd64.zip";
|
|
26801
|
+
return { url: url2, fileName: "helm-" + v + ".zip", sha256: firstHash(await fetchText(url2 + ".sha256sum")) };
|
|
26802
|
+
},
|
|
26803
|
+
terraform: async () => {
|
|
26804
|
+
const { current_version: v } = await fetchJson("https://checkpoint-api.hashicorp.com/v1/check/terraform");
|
|
26805
|
+
const base = "https://releases.hashicorp.com/terraform/" + v + "/";
|
|
26806
|
+
const file3 = "terraform_" + v + "_windows_amd64.zip";
|
|
26807
|
+
return { url: base + file3, fileName: file3, sha256: sumFor(await fetchText(base + "terraform_" + v + "_SHA256SUMS"), file3) };
|
|
26808
|
+
},
|
|
26809
|
+
mitmproxy: async () => {
|
|
26810
|
+
const v = stripV(await latestGithubTag("mitmproxy/mitmproxy"));
|
|
26811
|
+
return { url: "https://downloads.mitmproxy.org/" + v + "/mitmproxy-" + v + "-windows-x86_64.zip", fileName: "mitmproxy-" + v + ".zip" };
|
|
26812
|
+
},
|
|
26813
|
+
sqlite: async () => {
|
|
26814
|
+
const page = await fetchText("https://sqlite.org/download.html");
|
|
26815
|
+
const file3 = /PRODUCT,[^,]+,(\d{4}\/sqlite-tools-win-x64-\d+\.zip),/.exec(page)?.[1];
|
|
26816
|
+
if (!file3) throw new Error("could not find the sqlite tools download on sqlite.org");
|
|
26817
|
+
return { url: "https://sqlite.org/" + file3, fileName: file3.split("/")[1] };
|
|
26818
|
+
},
|
|
26819
|
+
"7zip": async () => {
|
|
26820
|
+
const asset = await githubAsset("ip7z/7zip", /^7z\d+-x64\.exe$/);
|
|
26821
|
+
return { url: asset.url, fileName: asset.name, sha256: asset.sha256 };
|
|
26822
|
+
}
|
|
26823
|
+
};
|
|
26824
|
+
|
|
26825
|
+
// src/guest/apps/index.ts
|
|
26826
|
+
var MARKER = ".agent-sandbox-app";
|
|
26827
|
+
var PARALLEL = 3;
|
|
26828
|
+
var sevenZip = () => tool("apps", "7zip", "7z.exe");
|
|
26829
|
+
var resolve = async (entry) => {
|
|
26830
|
+
const s = entry.source;
|
|
26831
|
+
if ("github" in s) {
|
|
26832
|
+
const a = await githubAsset(s.github, new RegExp(s.asset), true);
|
|
26833
|
+
return { url: a.url, fileName: a.name, sha256: a.sha256 };
|
|
26834
|
+
}
|
|
26835
|
+
if ("url" in s) {
|
|
26836
|
+
const name = decodeURIComponent(new URL(s.url).pathname.split("/").pop() || entry.id);
|
|
26837
|
+
return { url: s.url, fileName: /\.\w{2,5}$/.test(name) ? name : name + ".zip" };
|
|
26838
|
+
}
|
|
26839
|
+
if ("resolve" in s && RESOLVERS[s.resolve]) return RESOLVERS[s.resolve]();
|
|
26840
|
+
throw new Error("no download source for " + entry.name);
|
|
26841
|
+
};
|
|
26842
|
+
var findExe = (root, exe) => {
|
|
26843
|
+
const match = exeMatcher(exe);
|
|
26844
|
+
let queue = [root];
|
|
26845
|
+
let seen = 0;
|
|
26846
|
+
for (let depth = 0; depth < 7 && queue.length; depth++) {
|
|
26847
|
+
const next = [];
|
|
26848
|
+
for (const dir of queue) {
|
|
26849
|
+
let entries2;
|
|
26850
|
+
try {
|
|
26851
|
+
entries2 = fs11.readdirSync(dir, { withFileTypes: true });
|
|
26852
|
+
} catch {
|
|
26853
|
+
continue;
|
|
26854
|
+
}
|
|
26855
|
+
const hit = entries2.find((e) => e.isFile() && match(e.name));
|
|
26856
|
+
if (hit) return path15.join(dir, hit.name);
|
|
26857
|
+
next.push(...entries2.filter((e) => e.isDirectory() && !e.isSymbolicLink()).map((e) => path15.join(dir, e.name)));
|
|
26858
|
+
if ((seen += entries2.length) > 5e4) return null;
|
|
26859
|
+
}
|
|
26860
|
+
queue = next;
|
|
26861
|
+
}
|
|
26862
|
+
return null;
|
|
26863
|
+
};
|
|
26864
|
+
var installApp = async (entry, dest) => {
|
|
26865
|
+
const work = stagingFolder(dest);
|
|
26866
|
+
const out = path15.join(work, "out");
|
|
26867
|
+
try {
|
|
26868
|
+
if ("npm" in entry.source) {
|
|
26869
|
+
const npmCli = path15.join(path15.dirname(process.execPath), "node_modules", "npm", "bin", "npm-cli.js");
|
|
26870
|
+
log("Installing " + entry.name + " (npm) ...");
|
|
26871
|
+
await execAsync(process.execPath, [npmCli, "install", "--prefix", mkdirp(out), "--no-audit", "--no-fund", "--loglevel=error", entry.source.npm]);
|
|
26872
|
+
} else {
|
|
26873
|
+
const d = await resolve(entry);
|
|
26874
|
+
log("Downloading " + entry.name + " (" + d.fileName + ", ~" + entry.size + " once) ...");
|
|
26875
|
+
const file3 = path15.join(mkdirp(work), d.fileName.replace(/[\\/:*?"<>|]/g, "_"));
|
|
26876
|
+
await download(d.url, file3, { sha256: d.sha256 ?? null });
|
|
26877
|
+
await unpack(entry, file3, out, d);
|
|
26878
|
+
}
|
|
26879
|
+
fs11.writeFileSync(path15.join(out, MARKER), JSON.stringify({ id: entry.id, at: (/* @__PURE__ */ new Date()).toISOString() }));
|
|
26880
|
+
moveIntoPlace(out, dest);
|
|
26881
|
+
} finally {
|
|
26882
|
+
safeRemove(work, path15.dirname(work));
|
|
26883
|
+
}
|
|
26884
|
+
};
|
|
26885
|
+
var unpack = async (entry, file3, out, d) => {
|
|
26886
|
+
if (entry.id === "7zip") {
|
|
26887
|
+
const sevenZr = path15.join(path15.dirname(file3), "7zr.exe");
|
|
26888
|
+
const zr = await githubAsset("ip7z/7zip", /^7zr\.exe$/);
|
|
26889
|
+
await download(zr.url, sevenZr, zr.sha256);
|
|
26890
|
+
await execAsync(sevenZr, ["x", "-y", "-o" + out, file3], { stdio: "ignore" });
|
|
26891
|
+
return;
|
|
26892
|
+
}
|
|
26893
|
+
switch (entry.unpack ?? "archive") {
|
|
26894
|
+
case "file": {
|
|
26895
|
+
mkdirp(out);
|
|
26896
|
+
fs11.renameSync(file3, path15.join(out, /^\//.test(entry.exe) ? path15.basename(file3) : entry.exe));
|
|
26897
|
+
return;
|
|
26898
|
+
}
|
|
26899
|
+
case "nsis": {
|
|
26900
|
+
if (!exists(sevenZip())) throw new Error("7-Zip is needed to unpack " + entry.name + " and could not be installed");
|
|
26901
|
+
const raw = path15.join(path15.dirname(out), "raw");
|
|
26902
|
+
await execAsync(sevenZip(), ["x", "-y", "-o" + raw, file3], { stdio: "ignore" });
|
|
26903
|
+
const inner = findExe(raw, "/^app-64\\.7z$/");
|
|
26904
|
+
if (inner) await execAsync(sevenZip(), ["x", "-y", "-o" + out, inner], { stdio: "ignore" });
|
|
26905
|
+
else fs11.renameSync(raw, out);
|
|
26906
|
+
return;
|
|
26907
|
+
}
|
|
26908
|
+
case "msi": {
|
|
26909
|
+
mkdirp(out);
|
|
26910
|
+
await execAsync(SYSTEM.msiexec(), ["/a", file3, "/qn", "TARGETDIR=" + out], { stdio: "ignore" });
|
|
26911
|
+
return;
|
|
26912
|
+
}
|
|
26913
|
+
default:
|
|
26914
|
+
await extractArchive(file3, out, d.members);
|
|
26915
|
+
}
|
|
26916
|
+
};
|
|
26917
|
+
var afterInstall = async (entry, exe) => {
|
|
26918
|
+
const dir = path15.dirname(exe);
|
|
26919
|
+
if (entry.needs?.includes("mesa")) {
|
|
26920
|
+
const mesa = tool("mesa", arch === "arm64" ? "arm64" : "x64");
|
|
26921
|
+
for (const dll of ["opengl32.dll", "libgallium_wgl.dll", "dxil.dll"]) {
|
|
26922
|
+
if (exists(path15.join(mesa, dll)) && !exists(path15.join(dir, dll))) fs11.copyFileSync(path15.join(mesa, dll), path15.join(dir, dll));
|
|
26923
|
+
}
|
|
26924
|
+
}
|
|
26925
|
+
if (entry.id === "godot" && !exists(path15.join(dir, "._sc_"))) fs11.writeFileSync(path15.join(dir, "._sc_"), "");
|
|
26926
|
+
if (entry.id === "sublime") mkdirp(path15.join(dir, "Data"));
|
|
26927
|
+
if (entry.id === "sysinternals") {
|
|
26928
|
+
for (const name of ["Process Explorer", "Process Monitor", "Autoruns", "TCPView", "PsExec", "PsList", "PsKill", "Handle", "ListDLLs", "Sigcheck", "Strings", "VMMap", "RAMMap", "DebugView", "Disk2vhd", "Du", "ZoomIt"]) {
|
|
26929
|
+
await execAsync(SYSTEM.reg(), ["add", "HKCU\\Software\\Sysinternals\\" + name, "/v", "EulaAccepted", "/t", "REG_DWORD", "/d", "1", "/f"], { stdio: "ignore" }).catch(() => void 0);
|
|
26930
|
+
}
|
|
26931
|
+
}
|
|
26932
|
+
};
|
|
26933
|
+
var shortcuts = (apps) => {
|
|
26934
|
+
if (!apps.length) return;
|
|
26935
|
+
const q = (s) => "'" + s.replace(/'/g, "''") + "'";
|
|
26936
|
+
const desktop = path15.join(os5.homedir(), "Desktop");
|
|
26937
|
+
const start = path15.join(process.env.APPDATA ?? path15.join(os5.homedir(), "AppData", "Roaming"), "Microsoft", "Windows", "Start Menu", "Programs", "Sandbox apps");
|
|
26938
|
+
const lines = ["$w = New-Object -ComObject WScript.Shell", "New-Item -ItemType Directory -Force -Path " + q(start) + " | Out-Null"];
|
|
26939
|
+
for (const app of apps) {
|
|
26940
|
+
for (const folder of [desktop, start]) {
|
|
26941
|
+
const name = app.name.replace(/[\\/:*?"<>|]/g, "");
|
|
26942
|
+
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()");
|
|
26943
|
+
}
|
|
26944
|
+
}
|
|
26945
|
+
powershell(lines.join("\n"));
|
|
26946
|
+
};
|
|
26947
|
+
var setupApps = async (env, apps, o) => {
|
|
26948
|
+
const { entries: entries2, skipped } = appsToInstall(apps, o.gitAccess);
|
|
26949
|
+
for (const s of skipped) env.summary.push("app skipped: " + s);
|
|
26950
|
+
if (dryRun) {
|
|
26951
|
+
log("(dry run) would install apps: " + entries2.map((e) => e.name).join(", "));
|
|
26952
|
+
return;
|
|
26953
|
+
}
|
|
26954
|
+
const gui = [];
|
|
26955
|
+
const installed2 = [];
|
|
26956
|
+
const one = async (entry) => {
|
|
26957
|
+
try {
|
|
26958
|
+
const dest = tool("apps", ...entry.id.split("/"));
|
|
26959
|
+
if (!exists(path15.join(dest, MARKER)) || o.refresh) await installApp(entry, dest);
|
|
26960
|
+
const exe = findExe(dest, entry.exe);
|
|
26961
|
+
if (!exe) throw new Error(entry.exe + " not found in the download");
|
|
26962
|
+
await afterInstall(entry, exe);
|
|
26963
|
+
if (entry.cli || entry.id === "sysinternals") env.prepend.push(path15.dirname(exe));
|
|
26964
|
+
if (!entry.cli) gui.push({ name: entry.name, exe });
|
|
26965
|
+
installed2.push(entry.name);
|
|
26966
|
+
} catch (e) {
|
|
26967
|
+
warn(entry.name + " could not be installed and is skipped; the other apps are not affected. Reason: " + errMsg(e));
|
|
26968
|
+
env.summary.push(entry.name + ": FAILED");
|
|
26969
|
+
}
|
|
26970
|
+
};
|
|
26971
|
+
const [first, rest] = entries2[0]?.id === "7zip" ? [[entries2[0]], entries2.slice(1)] : [[], entries2];
|
|
26972
|
+
for (const e of first) await one(e);
|
|
26973
|
+
const queue = [...rest];
|
|
26974
|
+
await Promise.all(Array.from({ length: Math.min(PARALLEL, queue.length) }, async () => {
|
|
26975
|
+
for (let e = queue.shift(); e; e = queue.shift()) await one(e);
|
|
26976
|
+
}));
|
|
26977
|
+
try {
|
|
26978
|
+
shortcuts(gui);
|
|
26979
|
+
} catch (e) {
|
|
26980
|
+
warn("App shortcuts could not be created: " + errMsg(e));
|
|
26981
|
+
}
|
|
26982
|
+
if (installed2.length) env.summary.push("apps: " + installed2.join(", ") + " (shortcuts on the desktop and in Start > Sandbox apps)");
|
|
26983
|
+
};
|
|
26984
|
+
|
|
26985
|
+
// src/guest/helpers.ts
|
|
26986
|
+
import fs12 from "node:fs";
|
|
26987
|
+
import os6 from "node:os";
|
|
26988
|
+
import path16 from "node:path";
|
|
26989
|
+
import crypto2 from "node:crypto";
|
|
26990
|
+
import { spawnSync as spawnSync3 } from "node:child_process";
|
|
26991
|
+
var CSC = path16.join(process.env.WINDIR ?? "C:\\Windows", "Microsoft.NET", "Framework64", "v4.0.30319", "csc.exe");
|
|
26992
|
+
var sourceHash = (name) => crypto2.createHash("sha256").update(fs12.readFileSync(path16.join(launchDir, "sandbox", name + ".cs"))).digest("hex").slice(0, 12);
|
|
26993
|
+
var ensureCompiled = (name) => {
|
|
26994
|
+
const exe = path16.join(os6.tmpdir(), "agent-sandbox", name + "-" + sourceHash(name) + ".exe");
|
|
26995
|
+
if (exists(exe)) return exe;
|
|
26996
|
+
if (!exists(CSC)) throw new Error("The .NET Framework C# compiler was not found at " + CSC + " (it ships with Windows 10/11).");
|
|
26997
|
+
mkdirp(path16.dirname(exe));
|
|
26998
|
+
const result = spawnSync3(CSC, ["/nologo", "/optimize", "/target:exe", "/out:" + exe, path16.join(launchDir, "sandbox", name + ".cs")], { encoding: "utf8", windowsHide: true });
|
|
26999
|
+
if (result.status !== 0) throw new Error("Compiling " + name + " failed: " + ((result.stdout ?? "") + (result.stderr ?? "")).trim().slice(0, 1500));
|
|
27000
|
+
return exe;
|
|
27001
|
+
};
|
|
26476
27002
|
|
|
26477
27003
|
// src/guest/toolchains/databases/dynamodb.ts
|
|
26478
|
-
import
|
|
26479
|
-
import
|
|
27004
|
+
import fs15 from "node:fs";
|
|
27005
|
+
import path19 from "node:path";
|
|
26480
27006
|
import { spawn as spawn3 } from "node:child_process";
|
|
26481
27007
|
|
|
26482
27008
|
// src/guest/toolchains/java.ts
|
|
26483
|
-
import
|
|
26484
|
-
import
|
|
27009
|
+
import fs13 from "node:fs";
|
|
27010
|
+
import path17 from "node:path";
|
|
26485
27011
|
var ADOPTIUM = "https://api.adoptium.net/v3";
|
|
26486
27012
|
var MAVEN = "https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/";
|
|
26487
27013
|
var temurin = async (major) => {
|
|
@@ -26500,19 +27026,19 @@ var setupJdk = async (env, config2) => {
|
|
|
26500
27026
|
const { major, source } = await javaMajor(config2);
|
|
26501
27027
|
const release = await resolveCached("java:" + major, async () => (await temurin(major)).release_name);
|
|
26502
27028
|
const home = tool("java", release.replace(/[^A-Za-z0-9.-]/g, "_"));
|
|
26503
|
-
if (!exists(
|
|
27029
|
+
if (!exists(path17.join(home, "bin", "java.exe"))) {
|
|
26504
27030
|
const asset = await temurin(major);
|
|
26505
27031
|
log("Downloading Java " + release + " (JDK, ~200 MB once) ...");
|
|
26506
27032
|
await installArchive(asset.binary.package.link, home, { sha256: asset.binary.package.checksum, locate: "release", fileName: asset.binary.package.name });
|
|
26507
27033
|
}
|
|
26508
27034
|
env.vars.JAVA_HOME = home;
|
|
26509
|
-
env.prepend.push(
|
|
27035
|
+
env.prepend.push(path17.join(home, "bin"));
|
|
26510
27036
|
env.summary.push("java: " + release + " (Temurin, from " + source + ")");
|
|
26511
27037
|
};
|
|
26512
27038
|
var ensureJdk = async () => {
|
|
26513
27039
|
const root = tool("java");
|
|
26514
|
-
const installed2 = exists(root) ?
|
|
26515
|
-
if (installed2.length) return
|
|
27040
|
+
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 })) : [];
|
|
27041
|
+
if (installed2.length) return path17.join(root, installed2[0]);
|
|
26516
27042
|
const scratch = emptyEnv();
|
|
26517
27043
|
await setupJdk(scratch, { enabled: true, version: "lts", maven: false, gradle: false });
|
|
26518
27044
|
return scratch.vars.JAVA_HOME;
|
|
@@ -26523,29 +27049,29 @@ var setupMaven = async (env) => {
|
|
|
26523
27049
|
return pickPackageVersion(versions, "3") ?? Promise.reject(new Error("No Maven 3 release found"));
|
|
26524
27050
|
});
|
|
26525
27051
|
const home = tool("maven", version2);
|
|
26526
|
-
if (!exists(
|
|
27052
|
+
if (!exists(path17.join(home, "bin", "mvn.cmd"))) {
|
|
26527
27053
|
const url2 = MAVEN + version2 + "/apache-maven-" + version2 + "-bin.zip";
|
|
26528
27054
|
log("Downloading Maven " + version2 + " (~10 MB once) ...");
|
|
26529
27055
|
await installArchive(url2, home, { sha512: (await fetchText(url2 + ".sha512")).trim().split(/\s+/)[0], locate: "LICENSE" });
|
|
26530
27056
|
}
|
|
26531
27057
|
const repo = tool("maven-repository");
|
|
26532
27058
|
Object.assign(env.vars, { MAVEN_HOME: home, M2_HOME: home, MAVEN_OPTS: "-Dmaven.repo.local=" + repo });
|
|
26533
|
-
env.prepend.push(
|
|
27059
|
+
env.prepend.push(path17.join(home, "bin"));
|
|
26534
27060
|
env.summary.push("maven: " + version2);
|
|
26535
27061
|
};
|
|
26536
27062
|
var setupGradle = async (env) => {
|
|
26537
27063
|
const current = await fetchJson("https://services.gradle.org/versions/current").catch(() => null);
|
|
26538
27064
|
const version2 = await resolveCached("gradle", async () => current?.version ?? Promise.reject(new Error("Gradle version lookup failed")));
|
|
26539
27065
|
const home = tool("gradle", version2);
|
|
26540
|
-
if (!exists(
|
|
27066
|
+
if (!exists(path17.join(home, "bin", "gradle.bat"))) {
|
|
26541
27067
|
if (!current || current.version !== version2) throw new Error("Gradle " + version2 + " is not installed and cannot be downloaded right now");
|
|
26542
27068
|
log("Downloading Gradle " + version2 + " (~130 MB once) ...");
|
|
26543
27069
|
await installArchive(current.downloadUrl, home, { sha256: (await fetchText(current.checksumUrl)).trim(), locate: "LICENSE", fileName: "gradle-" + version2 + ".zip" });
|
|
26544
27070
|
}
|
|
26545
27071
|
const userHome = tool("gradle-home");
|
|
26546
|
-
|
|
27072
|
+
fs13.mkdirSync(userHome, { recursive: true });
|
|
26547
27073
|
Object.assign(env.vars, { GRADLE_HOME: home, GRADLE_USER_HOME: userHome, GRADLE_OPTS: "-Dorg.gradle.vfs.watch=false" });
|
|
26548
|
-
env.prepend.push(
|
|
27074
|
+
env.prepend.push(path17.join(home, "bin"));
|
|
26549
27075
|
env.summary.push("gradle: " + version2);
|
|
26550
27076
|
};
|
|
26551
27077
|
var setupJava = async (env, config2) => {
|
|
@@ -26564,20 +27090,20 @@ var setupJava = async (env, config2) => {
|
|
|
26564
27090
|
|
|
26565
27091
|
// src/guest/ports.ts
|
|
26566
27092
|
import net from "node:net";
|
|
26567
|
-
var freePort = () => new Promise((
|
|
27093
|
+
var freePort = () => new Promise((resolve2, reject) => {
|
|
26568
27094
|
const server = net.createServer();
|
|
26569
27095
|
server.once("error", reject);
|
|
26570
27096
|
server.listen(0, "127.0.0.1", () => {
|
|
26571
27097
|
const { port } = server.address();
|
|
26572
|
-
server.close(() =>
|
|
27098
|
+
server.close(() => resolve2(port));
|
|
26573
27099
|
});
|
|
26574
27100
|
});
|
|
26575
|
-
var portOpen = (port) => new Promise((
|
|
27101
|
+
var portOpen = (port) => new Promise((resolve2) => {
|
|
26576
27102
|
const socket = net.connect({ host: "127.0.0.1", port }, () => {
|
|
26577
27103
|
socket.destroy();
|
|
26578
|
-
|
|
27104
|
+
resolve2(true);
|
|
26579
27105
|
});
|
|
26580
|
-
socket.once("error", () =>
|
|
27106
|
+
socket.once("error", () => resolve2(false));
|
|
26581
27107
|
});
|
|
26582
27108
|
var waitForPort = async (port, seconds) => {
|
|
26583
27109
|
for (const end = Date.now() + seconds * 1e3; Date.now() < end; ) {
|
|
@@ -26588,26 +27114,26 @@ var waitForPort = async (port, seconds) => {
|
|
|
26588
27114
|
};
|
|
26589
27115
|
|
|
26590
27116
|
// src/guest/toolchains/databases/server.ts
|
|
26591
|
-
import
|
|
26592
|
-
import
|
|
27117
|
+
import fs14 from "node:fs";
|
|
27118
|
+
import path18 from "node:path";
|
|
26593
27119
|
import { spawn as spawn2 } from "node:child_process";
|
|
26594
|
-
var dataFor = (name) =>
|
|
27120
|
+
var dataFor = (name) => path18.join(dataDir, "databases", name);
|
|
26595
27121
|
var startServer = async (name, exe, args, port) => {
|
|
26596
27122
|
if (await portOpen(port)) throw new Error("port " + port + " is already in use (change databases." + name + ".port)");
|
|
26597
|
-
const logFile2 =
|
|
26598
|
-
const out =
|
|
27123
|
+
const logFile2 = path18.join(logsDir, name + ".log");
|
|
27124
|
+
const out = fs14.openSync(logFile2, "a");
|
|
26599
27125
|
spawn2(exe, args, { detached: true, stdio: ["ignore", out, out], windowsHide: true }).unref();
|
|
26600
|
-
|
|
27126
|
+
fs14.closeSync(out);
|
|
26601
27127
|
if (!await waitForPort(port, 60)) throw new Error(name + " did not start listening on port " + port + "; see " + logFile2);
|
|
26602
27128
|
};
|
|
26603
27129
|
var clearStaleLocks = async (dir, files, port) => {
|
|
26604
27130
|
if (await portOpen(port)) return;
|
|
26605
|
-
for (const f of files)
|
|
27131
|
+
for (const f of files) fs14.rmSync(path18.join(dir, f), { force: true });
|
|
26606
27132
|
};
|
|
26607
27133
|
var createOnce = async (data, marker, create) => {
|
|
26608
|
-
if (exists(
|
|
27134
|
+
if (exists(path18.join(data, marker))) return;
|
|
26609
27135
|
const existed = exists(data);
|
|
26610
|
-
mkdirp(
|
|
27136
|
+
mkdirp(path18.dirname(data));
|
|
26611
27137
|
try {
|
|
26612
27138
|
await create();
|
|
26613
27139
|
} catch (e) {
|
|
@@ -26624,40 +27150,40 @@ var createOnce = async (data, marker, create) => {
|
|
|
26624
27150
|
// src/guest/toolchains/databases/dynamodb.ts
|
|
26625
27151
|
var DYNAMO_ZIP = "https://d1ni2b6xgvw0s0.cloudfront.net/v2.x/dynamodb_local_latest.zip";
|
|
26626
27152
|
var setupDynamo = async (env, plan2) => {
|
|
26627
|
-
const java =
|
|
27153
|
+
const java = path19.join(await ensureJdk(), "bin", "java.exe");
|
|
26628
27154
|
const home = tool("dynamodb-local");
|
|
26629
|
-
if (!exists(
|
|
27155
|
+
if (!exists(path19.join(home, "DynamoDBLocal.jar"))) {
|
|
26630
27156
|
log("Downloading DynamoDB Local (~60 MB once) ...");
|
|
26631
27157
|
const sha256 = (await fetchText(DYNAMO_ZIP + ".sha256")).trim().split(/\s+/)[0];
|
|
26632
27158
|
await installArchive(DYNAMO_ZIP, home, { sha256, locate: "DynamoDBLocal.jar", fileName: "dynamodb_local.zip" });
|
|
26633
27159
|
}
|
|
26634
27160
|
const data = mkdirp(dataFor("dynamodb"));
|
|
26635
|
-
await startServer("dynamodb", java, ["-Djava.library.path=" +
|
|
27161
|
+
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
27162
|
const endpoint = "http://localhost:" + plan2.port;
|
|
26637
27163
|
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
27164
|
Object.assign(env.vars, aws);
|
|
26639
27165
|
env.summary.push("dynamodb (DynamoDB Local): " + endpoint + " (AWS SDKs use it automatically via AWS_ENDPOINT_URL_DYNAMODB; dummy credentials)");
|
|
26640
27166
|
if (!plan2.adminPort) return;
|
|
26641
27167
|
const prefix = tool("dynamodb-admin");
|
|
26642
|
-
const script =
|
|
27168
|
+
const script = path19.join(prefix, "node_modules", "dynamodb-admin", "dist", "dynamodb-admin.js");
|
|
26643
27169
|
if (!exists(script)) {
|
|
26644
27170
|
log("Installing dynamodb-admin, the DynamoDB web UI (~20 MB once) ...");
|
|
26645
|
-
const npmCli =
|
|
27171
|
+
const npmCli = path19.join(path19.dirname(process.execPath), "node_modules", "npm", "bin", "npm-cli.js");
|
|
26646
27172
|
await execAsync(process.execPath, [npmCli, "install", "--global", "--prefix", prefix, "dynamodb-admin", "--no-fund", "--no-audit"], { stdio: "ignore" });
|
|
26647
27173
|
}
|
|
26648
27174
|
if (await portOpen(plan2.adminPort)) {
|
|
26649
27175
|
env.summary.push("dynamodb-admin: NOT started, port " + plan2.adminPort + " is in use (change databases.dynamodb.adminPort)");
|
|
26650
27176
|
return;
|
|
26651
27177
|
}
|
|
26652
|
-
const out =
|
|
27178
|
+
const out = fs15.openSync(path19.join(logsDir, "dynamodb-admin.log"), "a");
|
|
26653
27179
|
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 " +
|
|
27180
|
+
fs15.closeSync(out);
|
|
27181
|
+
if (!await waitForPort(plan2.adminPort, 30)) throw new Error("dynamodb-admin did not start; see " + path19.join(logsDir, "dynamodb-admin.log"));
|
|
26656
27182
|
env.summary.push("dynamodb-admin: http://localhost:" + plan2.adminPort + " (browse and edit tables in the sandbox's browser)");
|
|
26657
27183
|
};
|
|
26658
27184
|
|
|
26659
27185
|
// src/guest/toolchains/databases/mongodb.ts
|
|
26660
|
-
import
|
|
27186
|
+
import path20 from "node:path";
|
|
26661
27187
|
var setupMongo = async (env, plan2) => {
|
|
26662
27188
|
const find = async () => {
|
|
26663
27189
|
const { versions } = await fetchJson("https://downloads.mongodb.org/full.json");
|
|
@@ -26668,24 +27194,24 @@ var setupMongo = async (env, plan2) => {
|
|
|
26668
27194
|
};
|
|
26669
27195
|
const version2 = await resolveCached("mongodb:" + plan2.version, async () => (await find()).version);
|
|
26670
27196
|
const home = tool("mongodb", version2);
|
|
26671
|
-
if (!exists(
|
|
27197
|
+
if (!exists(path20.join(home, "bin", "mongod.exe"))) {
|
|
26672
27198
|
const { archive } = await find();
|
|
26673
27199
|
log("Downloading MongoDB " + version2 + " (~400 MB once) ...");
|
|
26674
27200
|
await installArchive(archive.url, home, { sha256: archive.sha256, locate: "mongod.exe", up: 1 });
|
|
26675
27201
|
}
|
|
26676
27202
|
const shell = tool("mongosh");
|
|
26677
|
-
if (!exists(
|
|
27203
|
+
if (!exists(path20.join(shell, "mongosh.exe"))) {
|
|
26678
27204
|
await installFromGithub("mongodb-js/mongosh", /^mongosh-[\d.]+-win32-x64\.zip$/, { dest: shell, what: "mongosh, the MongoDB shell (~50 MB once)", locate: "mongosh.exe" });
|
|
26679
27205
|
}
|
|
26680
27206
|
const data = mkdirp(dataFor("mongodb"));
|
|
26681
27207
|
await clearStaleLocks(data, ["mongod.lock"], plan2.port);
|
|
26682
|
-
await startServer("mongodb",
|
|
26683
|
-
env.prepend.push(
|
|
27208
|
+
await startServer("mongodb", path20.join(home, "bin", "mongod.exe"), ["--dbpath", data, "--bind_ip", "127.0.0.1", "--port", String(plan2.port)], plan2.port);
|
|
27209
|
+
env.prepend.push(path20.join(home, "bin"), shell);
|
|
26684
27210
|
env.summary.push("mongodb " + version2 + ": mongodb://127.0.0.1:" + plan2.port + " (mongosh on PATH)");
|
|
26685
27211
|
};
|
|
26686
27212
|
|
|
26687
27213
|
// src/guest/toolchains/databases/mysql.ts
|
|
26688
|
-
import
|
|
27214
|
+
import path21 from "node:path";
|
|
26689
27215
|
var MARIA = "https://downloads.mariadb.org/rest-api/mariadb/";
|
|
26690
27216
|
var setupMysql = async (env, plan2) => {
|
|
26691
27217
|
const series = await resolveCached("mariadb:" + plan2.version, async () => {
|
|
@@ -26701,8 +27227,8 @@ var setupMysql = async (env, plan2) => {
|
|
|
26701
27227
|
};
|
|
26702
27228
|
const version2 = await resolveCached("mariadb-version:" + series, async () => (await latest()).version);
|
|
26703
27229
|
const home = tool("mariadb", version2);
|
|
26704
|
-
const bin =
|
|
26705
|
-
if (!exists(
|
|
27230
|
+
const bin = path21.join(home, "bin");
|
|
27231
|
+
if (!exists(path21.join(bin, "mariadbd.exe"))) {
|
|
26706
27232
|
const { zip } = await latest();
|
|
26707
27233
|
log("Downloading MariaDB " + version2 + " (~90 MB once) ...");
|
|
26708
27234
|
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 +27236,16 @@ var setupMysql = async (env, plan2) => {
|
|
|
26710
27236
|
const data = dataFor("mariadb");
|
|
26711
27237
|
await createOnce(data, "mysql", async () => {
|
|
26712
27238
|
log("Creating the MariaDB database (first start) ...");
|
|
26713
|
-
await execAsync(
|
|
27239
|
+
await execAsync(path21.join(bin, "mariadb-install-db.exe"), ["--datadir=" + data, "--port=" + plan2.port], { stdio: "ignore" });
|
|
26714
27240
|
});
|
|
26715
|
-
await startServer("mysql",
|
|
27241
|
+
await startServer("mysql", path21.join(bin, "mariadbd.exe"), ["--datadir=" + data, "--port=" + plan2.port, "--bind-address=127.0.0.1", "--console"], plan2.port);
|
|
26716
27242
|
Object.assign(env.vars, { MYSQL_HOST: "127.0.0.1", MYSQL_TCP_PORT: String(plan2.port) });
|
|
26717
27243
|
env.prepend.push(bin);
|
|
26718
27244
|
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
27245
|
};
|
|
26720
27246
|
|
|
26721
27247
|
// src/guest/toolchains/databases/postgres.ts
|
|
26722
|
-
import
|
|
27248
|
+
import path22 from "node:path";
|
|
26723
27249
|
var postgresData = (version2) => dataFor("postgres-" + version2.split(".")[0]);
|
|
26724
27250
|
var setupPostgres = async (env, plan2) => {
|
|
26725
27251
|
const exact = await resolveCached("postgres:" + plan2.version, async () => {
|
|
@@ -26728,8 +27254,8 @@ var setupPostgres = async (env, plan2) => {
|
|
|
26728
27254
|
return hit ? hit.major + "." + hit.latestMinor : Promise.reject(new Error("No supported PostgreSQL " + plan2.version));
|
|
26729
27255
|
});
|
|
26730
27256
|
const home = tool("postgres", exact);
|
|
26731
|
-
const bin =
|
|
26732
|
-
if (!exists(
|
|
27257
|
+
const bin = path22.join(home, "bin");
|
|
27258
|
+
if (!exists(path22.join(bin, "pg_ctl.exe"))) {
|
|
26733
27259
|
log("Downloading PostgreSQL " + exact + " (~330 MB once) ...");
|
|
26734
27260
|
await installArchive("https://get.enterprisedb.com/postgresql/postgresql-" + exact + "-1-windows-x64-binaries.zip", home, {
|
|
26735
27261
|
locate: "pg_ctl.exe",
|
|
@@ -26741,25 +27267,25 @@ var setupPostgres = async (env, plan2) => {
|
|
|
26741
27267
|
const data = postgresData(exact);
|
|
26742
27268
|
await createOnce(data, "PG_VERSION", async () => {
|
|
26743
27269
|
log("Creating the PostgreSQL database (first start) ...");
|
|
26744
|
-
await execAsync(
|
|
27270
|
+
await execAsync(path22.join(bin, "initdb.exe"), ["-D", data, "-U", "postgres", "-A", "trust", "-E", "UTF8", "--locale=C"], { stdio: "ignore" });
|
|
26745
27271
|
});
|
|
26746
27272
|
if (await portOpen(plan2.port)) throw new Error("port " + plan2.port + " is already in use (change databases.postgres.port)");
|
|
26747
27273
|
await clearStaleLocks(data, ["postmaster.pid"], plan2.port);
|
|
26748
|
-
await execAsync(
|
|
27274
|
+
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
27275
|
Object.assign(env.vars, { PGHOST: "localhost", PGPORT: String(plan2.port), PGUSER: "postgres" });
|
|
26750
27276
|
env.prepend.push(bin);
|
|
26751
27277
|
env.summary.push("postgres " + exact + ": localhost:" + plan2.port + ", user postgres, no password (postgres://postgres@localhost:" + plan2.port + "/postgres)");
|
|
26752
27278
|
};
|
|
26753
27279
|
|
|
26754
27280
|
// src/guest/toolchains/databases/redis.ts
|
|
26755
|
-
import
|
|
27281
|
+
import path23 from "node:path";
|
|
26756
27282
|
var setupRedis = async (env, plan2) => {
|
|
26757
27283
|
const home = tool("redis");
|
|
26758
|
-
if (!exists(
|
|
27284
|
+
if (!exists(path23.join(home, "redis-server.exe"))) {
|
|
26759
27285
|
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
27286
|
}
|
|
26761
27287
|
const data = mkdirp(dataFor("redis"));
|
|
26762
|
-
await startServer("redis",
|
|
27288
|
+
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
27289
|
env.prepend.push(home);
|
|
26764
27290
|
env.summary.push("redis: redis://127.0.0.1:" + plan2.port + " (redis-cli on PATH)");
|
|
26765
27291
|
};
|
|
@@ -26784,28 +27310,8 @@ var setupDatabase = async (env, plan2) => {
|
|
|
26784
27310
|
};
|
|
26785
27311
|
|
|
26786
27312
|
// 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
|
|
27313
|
+
import fs16 from "node:fs";
|
|
27314
|
+
import path24 from "node:path";
|
|
26809
27315
|
var BLOCKED_HOOKS = ["pre-commit", "commit-msg", "pre-merge-commit", "pre-push", "pre-rebase", "pre-applypatch", "applypatch-msg"];
|
|
26810
27316
|
var posix = (p) => p.replace(/\\/g, "/");
|
|
26811
27317
|
var installPortableGit = async (root) => {
|
|
@@ -26816,50 +27322,50 @@ var installPortableGit = async (root) => {
|
|
|
26816
27322
|
await download(asset.url, sfx, asset.sha256);
|
|
26817
27323
|
await execAsync(sfx, ["-o" + root, "-y"], { stdio: "ignore" });
|
|
26818
27324
|
} finally {
|
|
26819
|
-
|
|
27325
|
+
fs16.rmSync(sfx, { force: true });
|
|
26820
27326
|
}
|
|
26821
27327
|
};
|
|
26822
27328
|
var installGuard = (env, access, realGit) => {
|
|
26823
27329
|
const dir = mkdirp(tool("gitguard"));
|
|
26824
|
-
const guard =
|
|
26825
|
-
if (duringSession() && (exists(
|
|
27330
|
+
const guard = path24.join(launchDir, "runtime", "gitguard.js");
|
|
27331
|
+
if (duringSession() && (exists(path24.join(dir, "git.exe")) || exists(path24.join(dir, "git.cmd")))) {
|
|
26826
27332
|
} else try {
|
|
26827
|
-
|
|
26828
|
-
|
|
27333
|
+
fs16.copyFileSync(ensureCompiled("gitshim"), path24.join(dir, "git.exe"));
|
|
27334
|
+
fs16.rmSync(path24.join(dir, "git.cmd"), { force: true });
|
|
26829
27335
|
} catch (e) {
|
|
26830
27336
|
warn("git guard: falling back to git.cmd (" + errMsg(e) + ")");
|
|
26831
|
-
|
|
27337
|
+
fs16.writeFileSync(path24.join(dir, "git.cmd"), '@"' + process.execPath + '" "' + guard + '" %*\r\n');
|
|
26832
27338
|
}
|
|
26833
|
-
|
|
27339
|
+
fs16.writeFileSync(path24.join(dir, "bashenv.sh"), 'git() { "' + posix(process.execPath) + '" "' + posix(guard) + '" "$@"; }\nexport -f git\n');
|
|
26834
27340
|
env.prepend.unshift(dir);
|
|
26835
27341
|
Object.assign(env.vars, {
|
|
26836
27342
|
AGENT_GIT_ACCESS: access,
|
|
26837
27343
|
AGENT_REAL_GIT: access === "readonly" ? realGit : "",
|
|
26838
27344
|
AGENT_GUARD_NODE: process.execPath,
|
|
26839
27345
|
AGENT_GUARD_SCRIPT: guard,
|
|
26840
|
-
BASH_ENV: posix(
|
|
27346
|
+
BASH_ENV: posix(path24.join(dir, "bashenv.sh"))
|
|
26841
27347
|
});
|
|
26842
27348
|
if (access === "readonly") {
|
|
26843
|
-
const hooks = mkdirp(
|
|
26844
|
-
for (const hook of BLOCKED_HOOKS)
|
|
27349
|
+
const hooks = mkdirp(path24.join(dir, "hooks"));
|
|
27350
|
+
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
27351
|
Object.assign(env.vars, { GIT_CONFIG_COUNT: "1", GIT_CONFIG_KEY_0: "core.hooksPath", GIT_CONFIG_VALUE_0: posix(hooks) });
|
|
26846
27352
|
} else {
|
|
26847
|
-
env.vars.GIT_DIR =
|
|
27353
|
+
env.vars.GIT_DIR = path24.join(dataDir, "git-disabled");
|
|
26848
27354
|
}
|
|
26849
27355
|
};
|
|
26850
27356
|
var pointAtOwnCertificates = (root) => {
|
|
26851
|
-
const config2 =
|
|
26852
|
-
const bundle =
|
|
27357
|
+
const config2 = path24.join(root, "etc", "gitconfig");
|
|
27358
|
+
const bundle = path24.join(root, "mingw64", "etc", "ssl", "certs", "ca-bundle.crt");
|
|
26853
27359
|
if (!exists(config2) || !exists(bundle)) return;
|
|
26854
|
-
const text =
|
|
27360
|
+
const text = fs16.readFileSync(config2, "utf8");
|
|
26855
27361
|
const fixed = text.replace(/^(\s*sslCAInfo\s*=\s*).*$/gim, (_m, key) => key + posix(bundle));
|
|
26856
|
-
if (fixed !== text)
|
|
27362
|
+
if (fixed !== text) fs16.writeFileSync(config2, fixed);
|
|
26857
27363
|
};
|
|
26858
27364
|
var setupGit = async (env, hostCopy, refresh, access) => {
|
|
26859
27365
|
const root = tool("git");
|
|
26860
|
-
const bash =
|
|
26861
|
-
const gitExe =
|
|
26862
|
-
const hostGit =
|
|
27366
|
+
const bash = path24.join(root, "bin", "bash.exe");
|
|
27367
|
+
const gitExe = path24.join(root, "cmd", "git.exe");
|
|
27368
|
+
const hostGit = path24.join(hostToolsDir, "git");
|
|
26863
27369
|
if (exists(root) && !exists(bash)) {
|
|
26864
27370
|
log("Replacing the old MinGit (no bash) with full Git for Windows.");
|
|
26865
27371
|
safeRemove(root, toolsDir);
|
|
@@ -26871,11 +27377,11 @@ var setupGit = async (env, hostCopy, refresh, access) => {
|
|
|
26871
27377
|
}
|
|
26872
27378
|
const work = stagingFolder(root);
|
|
26873
27379
|
try {
|
|
26874
|
-
if (hostCopy && exists(
|
|
27380
|
+
if (hostCopy && exists(path24.join(hostGit, "bin", "bash.exe"))) {
|
|
26875
27381
|
log("Copying Git for Windows from this PC ...");
|
|
26876
27382
|
robocopy(hostGit, work);
|
|
26877
27383
|
} else await installPortableGit(work);
|
|
26878
|
-
if (!exists(
|
|
27384
|
+
if (!exists(path24.join(work, "bin", "bash.exe"))) throw new Error("bash.exe missing after installing Git");
|
|
26879
27385
|
moveIntoPlace(work, root);
|
|
26880
27386
|
} finally {
|
|
26881
27387
|
safeRemove(work, toolsDir);
|
|
@@ -26884,10 +27390,10 @@ var setupGit = async (env, hostCopy, refresh, access) => {
|
|
|
26884
27390
|
if (!exists(bash)) throw new Error("bash.exe missing after installing Git");
|
|
26885
27391
|
pointAtOwnCertificates(root);
|
|
26886
27392
|
env.vars.CLAUDE_CODE_GIT_BASH_PATH = bash;
|
|
26887
|
-
env.append.push(
|
|
27393
|
+
env.append.push(path24.join(root, "usr", "bin"));
|
|
26888
27394
|
const version2 = execOutput(gitExe, ["--version"]).replace(/^git version /, "");
|
|
26889
27395
|
if (access === "full") {
|
|
26890
|
-
env.prepend.push(
|
|
27396
|
+
env.prepend.push(path24.join(root, "cmd"));
|
|
26891
27397
|
env.summary.push("git: " + version2);
|
|
26892
27398
|
return;
|
|
26893
27399
|
}
|
|
@@ -26896,8 +27402,8 @@ var setupGit = async (env, hostCopy, refresh, access) => {
|
|
|
26896
27402
|
};
|
|
26897
27403
|
|
|
26898
27404
|
// src/guest/toolchains/go.ts
|
|
26899
|
-
import
|
|
26900
|
-
import
|
|
27405
|
+
import fs17 from "node:fs";
|
|
27406
|
+
import path25 from "node:path";
|
|
26901
27407
|
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
27408
|
var setupGo = async (env, config2) => {
|
|
26903
27409
|
if (dryRun) {
|
|
@@ -26906,7 +27412,7 @@ var setupGo = async (env, config2) => {
|
|
|
26906
27412
|
}
|
|
26907
27413
|
const version2 = await resolveCached("go:" + config2.version, async () => (await findRelease(config2.version)).version);
|
|
26908
27414
|
const root = tool("go", version2);
|
|
26909
|
-
if (!exists(
|
|
27415
|
+
if (!exists(path25.join(root, "bin", "go.exe"))) {
|
|
26910
27416
|
const goArch = arch === "arm64" ? "arm64" : "amd64";
|
|
26911
27417
|
const file3 = (await findRelease(version2)).files.find((f) => f.os === "windows" && f.arch === goArch && f.kind === "archive");
|
|
26912
27418
|
if (!file3) throw new Error(version2 + " has no Windows " + goArch + " zip");
|
|
@@ -26914,18 +27420,18 @@ var setupGo = async (env, config2) => {
|
|
|
26914
27420
|
await installArchive("https://go.dev/dl/" + file3.filename, root, { sha256: file3.sha256, locate: "VERSION", fileName: file3.filename });
|
|
26915
27421
|
}
|
|
26916
27422
|
const GOPATH = tool("go-path");
|
|
26917
|
-
const vars = { GOROOT: root, GOPATH, GOBIN:
|
|
26918
|
-
|
|
27423
|
+
const vars = { GOROOT: root, GOPATH, GOBIN: path25.join(GOPATH, "bin"), GOMODCACHE: path25.join(GOPATH, "pkg", "mod"), GOCACHE: tool("go-cache"), GOTOOLCHAIN: "auto", GOTELEMETRY: "off" };
|
|
27424
|
+
fs17.mkdirSync(vars.GOBIN, { recursive: true });
|
|
26919
27425
|
Object.assign(env.vars, vars);
|
|
26920
|
-
env.prepend.push(
|
|
26921
|
-
const go =
|
|
27426
|
+
env.prepend.push(path25.join(root, "bin"), vars.GOBIN);
|
|
27427
|
+
const go = path25.join(root, "bin", "go.exe");
|
|
26922
27428
|
env.summary.push("go: " + versionOf(go, ["version"]));
|
|
26923
27429
|
await installOnce(env, "go", config2.tools, (pkg) => execAsync(go, ["install", pkg.includes("@") ? pkg : pkg + "@latest"], { env: { ...process.env, ...vars } }));
|
|
26924
27430
|
};
|
|
26925
27431
|
|
|
26926
27432
|
// src/guest/toolchains/cli.ts
|
|
26927
|
-
import
|
|
26928
|
-
import
|
|
27433
|
+
import fs18 from "node:fs";
|
|
27434
|
+
import path27 from "node:path";
|
|
26929
27435
|
|
|
26930
27436
|
// src/guest/toolchains/catalogue.ts
|
|
26931
27437
|
var pwshAsset = (arch2) => arch2 === "arm64" ? /^PowerShell-\d+\.\d+\.\d+-win-arm64\.zip$/ : /^PowerShell-\d+\.\d+\.\d+-win-x64\.zip$/;
|
|
@@ -26950,14 +27456,14 @@ var decideCli = (settings, ctx) => {
|
|
|
26950
27456
|
};
|
|
26951
27457
|
|
|
26952
27458
|
// src/guest/toolchains/runtimes.ts
|
|
26953
|
-
import
|
|
27459
|
+
import path26 from "node:path";
|
|
26954
27460
|
var setupSingleExe = async (env, name, repo, pattern, exeName, dir, options = {}) => {
|
|
26955
27461
|
if (dryRun) {
|
|
26956
27462
|
log("(dry run) would provision " + name);
|
|
26957
27463
|
return;
|
|
26958
27464
|
}
|
|
26959
|
-
const bin = options.subdir ?
|
|
26960
|
-
const exe =
|
|
27465
|
+
const bin = options.subdir ? path26.join(dir, options.subdir) : dir;
|
|
27466
|
+
const exe = path26.join(bin, exeName);
|
|
26961
27467
|
if (!exists(exe) || options.refresh) {
|
|
26962
27468
|
const size = options.size ? ", ~" + options.size : "";
|
|
26963
27469
|
await installFromGithub(repo, pattern, { dest: dir, what: (a) => name + " (" + a.name + size + " once)", ...options.subdir ? {} : { locate: exeName } });
|
|
@@ -26968,7 +27474,7 @@ var setupSingleExe = async (env, name, repo, pattern, exeName, dir, options = {}
|
|
|
26968
27474
|
};
|
|
26969
27475
|
var setupBun = async (env) => {
|
|
26970
27476
|
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:
|
|
27477
|
+
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
27478
|
};
|
|
26973
27479
|
var setupDeno = async (env) => {
|
|
26974
27480
|
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 +27488,7 @@ var setupUv = async (env) => {
|
|
|
26982
27488
|
};
|
|
26983
27489
|
|
|
26984
27490
|
// src/guest/toolchains/cli.ts
|
|
26985
|
-
var ghConfigDir = () =>
|
|
27491
|
+
var ghConfigDir = () => path27.join(stateDir, "gh");
|
|
26986
27492
|
var toolVars = {
|
|
26987
27493
|
gh: () => ({ GH_CONFIG_DIR: mkdirp(ghConfigDir()), GH_NO_UPDATE_NOTIFIER: "1", GH_NO_EXTENSION_UPDATE_NOTIFIER: "1" })
|
|
26988
27494
|
};
|
|
@@ -26992,16 +27498,16 @@ var shimOpenssl = (env) => {
|
|
|
26992
27498
|
return;
|
|
26993
27499
|
}
|
|
26994
27500
|
const shims = mkdirp(tool("shims"));
|
|
26995
|
-
|
|
26996
|
-
|
|
27501
|
+
fs18.copyFileSync(ensureCompiled("openssl"), path27.join(shims, "openssl.exe"));
|
|
27502
|
+
fs18.rmSync(path27.join(shims, "openssl.cmd"), { force: true });
|
|
26997
27503
|
env.prepend.push(shims);
|
|
26998
27504
|
env.summary.push("openssl: Git for Windows' copy");
|
|
26999
27505
|
};
|
|
27000
27506
|
var setupCli = async (env, settings, gitAccess, refresh = false) => {
|
|
27001
|
-
const decisions = decideCli(settings, { gitAccess, hasGithubDir: exists(
|
|
27507
|
+
const decisions = decideCli(settings, { gitAccess, hasGithubDir: exists(path27.join(projectWorkspace(), ".github")) });
|
|
27002
27508
|
if (settings.gh && !decisions.gh.on) {
|
|
27003
27509
|
env.summary.push("gh: off (" + decisions.gh.reason + ")");
|
|
27004
|
-
if (exists(
|
|
27510
|
+
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
27511
|
}
|
|
27006
27512
|
if (dryRun) {
|
|
27007
27513
|
log("(dry run) would provision CLI tools: " + Object.entries(decisions).filter(([, d]) => d.on).map(([n]) => n).join(", "));
|
|
@@ -27029,11 +27535,11 @@ var setupCli = async (env, settings, gitAccess, refresh = false) => {
|
|
|
27029
27535
|
};
|
|
27030
27536
|
|
|
27031
27537
|
// src/guest/toolchains/managers.ts
|
|
27032
|
-
import
|
|
27033
|
-
import
|
|
27538
|
+
import fs19 from "node:fs";
|
|
27539
|
+
import path28 from "node:path";
|
|
27034
27540
|
var voltaPins = () => {
|
|
27035
27541
|
try {
|
|
27036
|
-
const pkg = JSON.parse(
|
|
27542
|
+
const pkg = JSON.parse(fs19.readFileSync(path28.join(projectWorkspace(), "package.json"), "utf8").replace(/^/, ""));
|
|
27037
27543
|
return Object.fromEntries(Object.entries(pkg.volta ?? {}).filter((e) => ["node", "npm", "yarn", "pnpm"].includes(e[0]) && typeof e[1] === "string"));
|
|
27038
27544
|
} catch {
|
|
27039
27545
|
return {};
|
|
@@ -27047,22 +27553,22 @@ var setupVolta = async (env) => {
|
|
|
27047
27553
|
return;
|
|
27048
27554
|
}
|
|
27049
27555
|
const dir = tool("volta");
|
|
27050
|
-
if (!exists(
|
|
27556
|
+
if (!exists(path28.join(dir, "volta.exe"))) {
|
|
27051
27557
|
const pattern = arch === "arm64" ? /^volta-[\d.]+-windows-arm64\.zip$/ : /^volta-[\d.]+-windows\.zip$/;
|
|
27052
27558
|
await installFromGithub("volta-cli/volta", pattern, { dest: dir, what: "Volta (~15 MB once)", locate: "volta.exe" });
|
|
27053
27559
|
}
|
|
27054
27560
|
for (const shim3 of ["node", "npm", "npx", "pnpm", "pnpx", "yarn", "yarnpkg"]) {
|
|
27055
|
-
const target =
|
|
27056
|
-
if (!exists(target))
|
|
27561
|
+
const target = path28.join(dir, shim3 + ".exe");
|
|
27562
|
+
if (!exists(target)) fs19.copyFileSync(path28.join(dir, "volta-shim.exe"), target);
|
|
27057
27563
|
}
|
|
27058
27564
|
const home = mkdirp(tool("volta-home"));
|
|
27059
|
-
const shims = mkdirp(
|
|
27565
|
+
const shims = mkdirp(path28.join(home, "bin"));
|
|
27060
27566
|
const vars = { VOLTA_HOME: home, VOLTA_FEATURE_PNPM: "1" };
|
|
27061
27567
|
Object.assign(env.vars, vars);
|
|
27062
27568
|
const pins = voltaPins();
|
|
27063
27569
|
if (Object.keys(pins).length) env.prepend.push(dir, shims);
|
|
27064
27570
|
else env.append.push(dir, shims);
|
|
27065
|
-
const volta =
|
|
27571
|
+
const volta = path28.join(dir, "volta.exe");
|
|
27066
27572
|
for (const [toolName, version2] of Object.entries(pins)) {
|
|
27067
27573
|
try {
|
|
27068
27574
|
await execAsync(volta, ["install", toolName + "@" + version2], { env: { ...process.env, ...vars }, cwd: projectWorkspace(), stdio: "ignore" });
|
|
@@ -27080,22 +27586,22 @@ var setupPyenv = async (env) => {
|
|
|
27080
27586
|
return;
|
|
27081
27587
|
}
|
|
27082
27588
|
const root = tool("pyenv", "pyenv-win");
|
|
27083
|
-
if (!exists(
|
|
27589
|
+
if (!exists(path28.join(root, "bin", "pyenv.bat"))) {
|
|
27084
27590
|
const tag = await resolveCached("pyenv-win", () => latestGithubTag("pyenv-win/pyenv-win"));
|
|
27085
27591
|
log("Downloading pyenv-win " + tag + " (~5 MB once) ...");
|
|
27086
27592
|
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
27593
|
}
|
|
27088
|
-
const home = root +
|
|
27594
|
+
const home = root + path28.sep;
|
|
27089
27595
|
Object.assign(env.vars, { PYENV: home, PYENV_ROOT: home, PYENV_HOME: home });
|
|
27090
|
-
env.append.push(
|
|
27596
|
+
env.append.push(path28.join(root, "bin"), path28.join(root, "shims"));
|
|
27091
27597
|
env.summary.push("pyenv-win: pyenv install <version> / pyenv local <version> (versions persist)");
|
|
27092
27598
|
};
|
|
27093
27599
|
|
|
27094
27600
|
// src/guest/toolchains/native/cpp.ts
|
|
27095
|
-
import
|
|
27601
|
+
import path29 from "node:path";
|
|
27096
27602
|
var setupCpp = async (env, config2) => {
|
|
27097
27603
|
const bin = tool("mingw", "mingw64", "bin");
|
|
27098
|
-
const gcc =
|
|
27604
|
+
const gcc = path29.join(bin, "gcc.exe");
|
|
27099
27605
|
if (dryRun) {
|
|
27100
27606
|
log("(dry run) would provision MinGW-w64 GCC");
|
|
27101
27607
|
return;
|
|
@@ -27107,27 +27613,27 @@ var setupCpp = async (env, config2) => {
|
|
|
27107
27613
|
if (!exists(gcc)) throw new Error("gcc.exe missing after installing MinGW");
|
|
27108
27614
|
env.append.unshift(bin);
|
|
27109
27615
|
env.vars.CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER = gcc;
|
|
27110
|
-
const cmake = versionOf(
|
|
27616
|
+
const cmake = versionOf(path29.join(bin, "cmake.exe"));
|
|
27111
27617
|
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
27618
|
env.summary.push("gcc: " + versionOf(gcc) + " (MinGW-w64, with cmake " + cmake + ", ninja, premake5)");
|
|
27113
27619
|
if (config2.flexBison) await setupFlexBison(env);
|
|
27114
27620
|
};
|
|
27115
27621
|
var setupFlexBison = async (env) => {
|
|
27116
27622
|
const dir = tool("winflexbison");
|
|
27117
|
-
if (!exists(
|
|
27623
|
+
if (!exists(path29.join(dir, "win_bison.exe"))) {
|
|
27118
27624
|
await installFromGithub("lexxmark/winflexbison", /^win_flex_bison-[\d.]+\.zip$/, { dest: dir, what: "win_flex / win_bison (~1 MB once)", locate: "win_bison.exe" });
|
|
27119
27625
|
}
|
|
27120
27626
|
env.append.push(dir);
|
|
27121
|
-
env.summary.push("win_flex/win_bison: " + versionOf(
|
|
27627
|
+
env.summary.push("win_flex/win_bison: " + versionOf(path29.join(dir, "win_bison.exe")));
|
|
27122
27628
|
};
|
|
27123
27629
|
|
|
27124
27630
|
// src/guest/toolchains/native/dotnet.ts
|
|
27125
|
-
import
|
|
27126
|
-
import
|
|
27631
|
+
import fs20 from "node:fs";
|
|
27632
|
+
import path30 from "node:path";
|
|
27127
27633
|
var DotnetMarker = external_exports.record(external_exports.string(), external_exports.boolean());
|
|
27128
27634
|
var setupDotnet = async (env, config2, refresh) => {
|
|
27129
27635
|
const root = tool("dotnet");
|
|
27130
|
-
const marker =
|
|
27636
|
+
const marker = path30.join(root, ".agent-sandbox-installed.json");
|
|
27131
27637
|
const script = tool("dotnet-install.ps1");
|
|
27132
27638
|
if (dryRun) {
|
|
27133
27639
|
log("(dry run) would provision .NET SDK channels " + config2.channels.join(", "));
|
|
@@ -27135,10 +27641,10 @@ var setupDotnet = async (env, config2, refresh) => {
|
|
|
27135
27641
|
}
|
|
27136
27642
|
const recorded = DotnetMarker.safeParse(exists(marker) && !refresh ? readJsonFile(marker) : {});
|
|
27137
27643
|
const done = recorded.success ? recorded.data : {};
|
|
27138
|
-
const globalJson =
|
|
27644
|
+
const globalJson = path30.join(projectWorkspace(), "global.json");
|
|
27139
27645
|
const installs = [
|
|
27140
27646
|
...config2.channels.map((c) => ["channel:" + c, ["-Channel", c]]),
|
|
27141
|
-
...exists(globalJson) ? [["global.json:" +
|
|
27647
|
+
...exists(globalJson) ? [["global.json:" + fs20.readFileSync(globalJson, "utf8").replace(/\s+/g, ""), ["-JSonFile", globalJson]]] : []
|
|
27142
27648
|
];
|
|
27143
27649
|
for (const [key, args] of installs.filter(([k]) => !done[k])) {
|
|
27144
27650
|
await downloadFile("https://dot.net/v1/dotnet-install.ps1", script);
|
|
@@ -27149,10 +27655,10 @@ var setupDotnet = async (env, config2, refresh) => {
|
|
|
27149
27655
|
}
|
|
27150
27656
|
const home = mkdirp(tool("dotnet-home"));
|
|
27151
27657
|
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 +
|
|
27658
|
+
env.prepend.push(root, path30.join(home, ".dotnet", "tools"));
|
|
27659
|
+
env.summary.push("dotnet: " + execOutput(path30.join(root, "dotnet.exe"), ["--list-sdks"]).split(/\r?\n/).map((l) => l.split(" ")[0]).filter(Boolean).join(", "));
|
|
27660
|
+
const dotnet = path30.join(root, "dotnet.exe");
|
|
27661
|
+
const dotnetEnv = { env: { ...process.env, ...env.vars, PATH: root + path30.delimiter + (process.env.PATH ?? "") } };
|
|
27156
27662
|
await installOnce(env, "dotnet workload", config2.workloads, (w) => execAsync(dotnet, ["workload", "install", w, "--skip-manifest-update"], dotnetEnv));
|
|
27157
27663
|
await installOnce(env, "dotnet tool", config2.tools, (t) => execAsync(dotnet, ["tool", "install", "--global", t], dotnetEnv));
|
|
27158
27664
|
await setupFrameworkReferences(env, config2.frameworkTargets);
|
|
@@ -27163,7 +27669,7 @@ var setupFrameworkReferences = async (env, targets) => {
|
|
|
27163
27669
|
const root = tool("netfx-references");
|
|
27164
27670
|
for (const target of targets) {
|
|
27165
27671
|
const id = "microsoft.netframework.referenceassemblies." + target.toLowerCase();
|
|
27166
|
-
const marker =
|
|
27672
|
+
const marker = path30.join(root, ".installed-" + target.toLowerCase());
|
|
27167
27673
|
if (exists(marker)) continue;
|
|
27168
27674
|
const staging = tool("netfx-references-" + target.toLowerCase());
|
|
27169
27675
|
try {
|
|
@@ -27172,17 +27678,17 @@ var setupFrameworkReferences = async (env, targets) => {
|
|
|
27172
27678
|
if (!version2) throw new Error("no stable version of " + id);
|
|
27173
27679
|
log("Downloading the .NET Framework " + target + " reference assemblies (~30 MB once) ...");
|
|
27174
27680
|
await installArchive("https://api.nuget.org/v3-flatcontainer/" + id + "/" + version2 + "/" + id + "." + version2 + ".nupkg", staging, { fileName: id + ".zip" });
|
|
27175
|
-
|
|
27176
|
-
|
|
27681
|
+
fs20.cpSync(path30.join(staging, "build", ".NETFramework"), path30.join(root, ".NETFramework"), { recursive: true });
|
|
27682
|
+
fs20.writeFileSync(marker, version2);
|
|
27177
27683
|
} catch (e) {
|
|
27178
27684
|
warn(".NET Framework " + target + " reference assemblies could not be installed (projects targeting it will not build): " + errMsg(e));
|
|
27179
27685
|
} finally {
|
|
27180
27686
|
safeRemove(staging, dataDir);
|
|
27181
27687
|
}
|
|
27182
27688
|
}
|
|
27183
|
-
if (!exists(
|
|
27184
|
-
env.vars.TargetFrameworkRootPath = root +
|
|
27185
|
-
env.summary.push(".NET Framework targeting: " +
|
|
27689
|
+
if (!exists(path30.join(root, ".NETFramework"))) return;
|
|
27690
|
+
env.vars.TargetFrameworkRootPath = root + path30.sep;
|
|
27691
|
+
env.summary.push(".NET Framework targeting: " + fs20.readdirSync(path30.join(root, ".NETFramework")).join(", "));
|
|
27186
27692
|
};
|
|
27187
27693
|
var setupNetFx35 = async (env) => {
|
|
27188
27694
|
if (execOutput(SYSTEM.reg(), ["query", "HKLM\\SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v3.5", "/v", "Install"]).includes("0x1")) {
|
|
@@ -27200,15 +27706,15 @@ var setupNetFx35 = async (env) => {
|
|
|
27200
27706
|
};
|
|
27201
27707
|
|
|
27202
27708
|
// src/guest/toolchains/native/mesa.ts
|
|
27203
|
-
import
|
|
27709
|
+
import path31 from "node:path";
|
|
27204
27710
|
var setupMesa = async (env, config2) => {
|
|
27205
27711
|
if (dryRun) {
|
|
27206
27712
|
log("(dry run) would provision Mesa 3D");
|
|
27207
27713
|
return;
|
|
27208
27714
|
}
|
|
27209
27715
|
const root = tool("mesa");
|
|
27210
|
-
const dir =
|
|
27211
|
-
if (!exists(
|
|
27716
|
+
const dir = path31.join(root, arch === "arm64" ? "arm64" : "x64");
|
|
27717
|
+
if (!exists(path31.join(dir, "opengl32.dll"))) {
|
|
27212
27718
|
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
27719
|
}
|
|
27214
27720
|
Object.assign(env.vars, { MESA_DIR: dir, GALLIUM_DRIVER: "llvmpipe" });
|
|
@@ -27217,54 +27723,59 @@ var setupMesa = async (env, config2) => {
|
|
|
27217
27723
|
};
|
|
27218
27724
|
var VULKAN_RUNTIME = "https://sdk.lunarg.com/sdk/download/latest/windows/vulkan-runtime-components.zip";
|
|
27219
27725
|
var setupLavapipe = async (env, mesaDir) => {
|
|
27220
|
-
const icd =
|
|
27221
|
-
if (!exists(icd)) throw new Error("this Mesa build has no lavapipe (" +
|
|
27726
|
+
const icd = path31.join(mesaDir, arch === "arm64" ? "lvp_icd.aarch64.json" : "lvp_icd.x86_64.json");
|
|
27727
|
+
if (!exists(icd)) throw new Error("this Mesa build has no lavapipe (" + path31.basename(icd) + ")");
|
|
27222
27728
|
const dir = tool("vulkan");
|
|
27223
|
-
if (!exists(
|
|
27729
|
+
if (!exists(path31.join(dir, "vulkan-1.dll"))) {
|
|
27224
27730
|
log("Downloading the Vulkan loader (~10 MB once) ...");
|
|
27225
27731
|
await installArchive(VULKAN_RUNTIME, dir, { locate: "vulkan-1.dll", fileName: "vulkan-runtime.zip", members: ["*/x64/*"] });
|
|
27226
27732
|
}
|
|
27227
|
-
|
|
27733
|
+
const register = (file3) => execAsync(SYSTEM.reg(), ["add", "HKLM\\SOFTWARE\\Khronos\\Vulkan\\Drivers", "/v", file3, "/t", "REG_DWORD", "/d", "0", "/f"], { stdio: "ignore" });
|
|
27734
|
+
await register(icd);
|
|
27735
|
+
const dozen = path31.join(mesaDir, arch === "arm64" ? "dzn_icd.aarch64.json" : "dzn_icd.x86_64.json");
|
|
27736
|
+
const gpu = hasGpu();
|
|
27737
|
+
if (gpu && exists(dozen)) await register(dozen);
|
|
27228
27738
|
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");
|
|
27739
|
+
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
27740
|
};
|
|
27741
|
+
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
27742
|
|
|
27232
27743
|
// src/guest/toolchains/native/msvc/index.ts
|
|
27233
|
-
import
|
|
27234
|
-
import
|
|
27744
|
+
import fs24 from "node:fs";
|
|
27745
|
+
import path35 from "node:path";
|
|
27235
27746
|
|
|
27236
27747
|
// src/guest/toolchains/native/msvc/environment.ts
|
|
27237
|
-
import
|
|
27238
|
-
import
|
|
27748
|
+
import fs22 from "node:fs";
|
|
27749
|
+
import path33 from "node:path";
|
|
27239
27750
|
|
|
27240
27751
|
// src/guest/toolchains/native/msvc/tree.ts
|
|
27241
|
-
import
|
|
27242
|
-
import
|
|
27752
|
+
import fs21 from "node:fs";
|
|
27753
|
+
import path32 from "node:path";
|
|
27243
27754
|
var ROOT = tool("msvc");
|
|
27244
|
-
var
|
|
27245
|
-
var msvcTools = (msvc, ...parts) =>
|
|
27755
|
+
var MARKER2 = path32.join(ROOT, ".installed.json");
|
|
27756
|
+
var msvcTools = (msvc, ...parts) => path32.join(ROOT, "VC", "Tools", "MSVC", msvc, ...parts);
|
|
27246
27757
|
var hostBin = (msvc, ...parts) => msvcTools(msvc, "bin", "Hostx64", "x64", ...parts);
|
|
27247
27758
|
var hasCompiler = (msvc) => exists(hostBin(msvc, "cl.exe"));
|
|
27248
27759
|
var Installed = external_exports.object({ msvc: external_exports.string().min(1), sdk: external_exports.string().min(1), want: external_exports.string() });
|
|
27249
27760
|
var readInstalled = () => {
|
|
27250
27761
|
try {
|
|
27251
|
-
return Installed.safeParse(JSON.parse(
|
|
27762
|
+
return Installed.safeParse(JSON.parse(fs21.readFileSync(MARKER2, "utf8"))).data ?? null;
|
|
27252
27763
|
} catch {
|
|
27253
27764
|
return null;
|
|
27254
27765
|
}
|
|
27255
27766
|
};
|
|
27256
27767
|
|
|
27257
27768
|
// src/guest/toolchains/native/msvc/environment.ts
|
|
27258
|
-
var VSWHERE_DIR =
|
|
27769
|
+
var VSWHERE_DIR = path33.join(process.env["ProgramFiles(x86)"] ?? "C:\\Program Files (x86)", "Microsoft Visual Studio", "Installer");
|
|
27259
27770
|
var vcvars = (root, msvc, sdk) => {
|
|
27260
|
-
const vc =
|
|
27261
|
-
const kits =
|
|
27262
|
-
const inc = (...p) =>
|
|
27263
|
-
const lib = (...p) =>
|
|
27771
|
+
const vc = path33.join(root, "VC", "Tools", "MSVC", msvc);
|
|
27772
|
+
const kits = path33.join(root, "Windows Kits", "10");
|
|
27773
|
+
const inc = (...p) => path33.join(kits, "Include", sdk, ...p);
|
|
27774
|
+
const lib = (...p) => path33.join(kits, "Lib", sdk, ...p);
|
|
27264
27775
|
return {
|
|
27265
27776
|
vars: {
|
|
27266
27777
|
VSINSTALLDIR: root + "\\",
|
|
27267
|
-
VCINSTALLDIR:
|
|
27778
|
+
VCINSTALLDIR: path33.join(root, "VC") + "\\",
|
|
27268
27779
|
VCToolsInstallDir: vc + "\\",
|
|
27269
27780
|
VCToolsVersion: msvc,
|
|
27270
27781
|
VisualStudioVersion: "17.0",
|
|
@@ -27276,15 +27787,15 @@ var vcvars = (root, msvc, sdk) => {
|
|
|
27276
27787
|
VSCMD_ARG_HOST_ARCH: "x64",
|
|
27277
27788
|
VSCMD_ARG_TGT_ARCH: "x64",
|
|
27278
27789
|
Platform: "x64",
|
|
27279
|
-
INCLUDE: [
|
|
27280
|
-
LIB: [
|
|
27281
|
-
LIBPATH: [
|
|
27790
|
+
INCLUDE: [path33.join(vc, "include"), inc("ucrt"), inc("shared"), inc("um"), inc("winrt"), inc("cppwinrt")].join(";"),
|
|
27791
|
+
LIB: [path33.join(vc, "lib", "x64"), lib("ucrt", "x64"), lib("um", "x64")].join(";"),
|
|
27792
|
+
LIBPATH: [path33.join(vc, "lib", "x64"), path33.join(vc, "lib", "x86", "store", "references")].join(";")
|
|
27282
27793
|
},
|
|
27283
|
-
path: [
|
|
27794
|
+
path: [path33.join(vc, "bin", "Hostx64", "x64"), path33.join(kits, "bin", sdk, "x64")]
|
|
27284
27795
|
};
|
|
27285
27796
|
};
|
|
27286
27797
|
var writeVcvars = (env) => {
|
|
27287
|
-
const dir = mkdirp(
|
|
27798
|
+
const dir = mkdirp(path33.join(ROOT, "VC", "Auxiliary", "Build"));
|
|
27288
27799
|
const lines = [
|
|
27289
27800
|
"@echo off",
|
|
27290
27801
|
"rem Written by Windows Development Sandbox for its portable MSVC (host x64, target x64).",
|
|
@@ -27292,26 +27803,26 @@ var writeVcvars = (env) => {
|
|
|
27292
27803
|
'set "PATH=' + env.path.join(";") + ';%PATH%"',
|
|
27293
27804
|
"exit /b 0"
|
|
27294
27805
|
];
|
|
27295
|
-
|
|
27296
|
-
|
|
27806
|
+
fs22.writeFileSync(path33.join(dir, "vcvars64.bat"), lines.join("\r\n") + "\r\n");
|
|
27807
|
+
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
27808
|
};
|
|
27298
27809
|
var installVswhere = (msvc) => {
|
|
27299
27810
|
mkdirp(VSWHERE_DIR);
|
|
27300
|
-
|
|
27811
|
+
fs22.copyFileSync(ensureCompiled("vswhere"), path33.join(VSWHERE_DIR, "vswhere.exe"));
|
|
27301
27812
|
const [major, minor] = msvc.split(".").slice(2);
|
|
27302
|
-
|
|
27813
|
+
fs22.writeFileSync(path33.join(VSWHERE_DIR, "vswhere.json"), JSON.stringify({ installationPath: ROOT, installationVersion: "17." + (minor ?? "0") + ".0." + (major ?? "0") }));
|
|
27303
27814
|
};
|
|
27304
27815
|
var removeTelemetry = (msvc) => {
|
|
27305
27816
|
try {
|
|
27306
|
-
|
|
27817
|
+
fs22.rmSync(hostBin(msvc, "vctip.exe"), { force: true });
|
|
27307
27818
|
} catch (e) {
|
|
27308
27819
|
warn("Could not remove MSVC's telemetry helper (vctip.exe); it may keep tools\\msvc locked: " + errMsg(e));
|
|
27309
27820
|
}
|
|
27310
27821
|
};
|
|
27311
27822
|
|
|
27312
27823
|
// src/guest/toolchains/native/msvc/packages.ts
|
|
27313
|
-
import
|
|
27314
|
-
import
|
|
27824
|
+
import fs23 from "node:fs";
|
|
27825
|
+
import path34 from "node:path";
|
|
27315
27826
|
var CHANNEL = "https://aka.ms/vs/17/release/channel";
|
|
27316
27827
|
var MANIFEST_DAY_MS = 24 * 60 * 60 * 1e3;
|
|
27317
27828
|
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 +27839,10 @@ var SDK_MSIS = [
|
|
|
27328
27839
|
"Windows SDK Desktop Tools x64-x86_en-us.msi"
|
|
27329
27840
|
];
|
|
27330
27841
|
var manifest = async () => {
|
|
27331
|
-
const cached2 =
|
|
27332
|
-
if (exists(cached2) && Date.now() -
|
|
27842
|
+
const cached2 = path34.join(ROOT, ".manifest.json");
|
|
27843
|
+
if (exists(cached2) && Date.now() - fs23.statSync(cached2).mtimeMs < MANIFEST_DAY_MS) {
|
|
27333
27844
|
try {
|
|
27334
|
-
return JSON.parse(
|
|
27845
|
+
return JSON.parse(fs23.readFileSync(cached2, "utf8"));
|
|
27335
27846
|
} catch {
|
|
27336
27847
|
}
|
|
27337
27848
|
}
|
|
@@ -27340,26 +27851,26 @@ var manifest = async () => {
|
|
|
27340
27851
|
if (!item) throw new Error("the Visual Studio channel has no package manifest");
|
|
27341
27852
|
mkdirp(ROOT);
|
|
27342
27853
|
await download(item.url, cached2);
|
|
27343
|
-
return JSON.parse(
|
|
27854
|
+
return JSON.parse(fs23.readFileSync(cached2, "utf8"));
|
|
27344
27855
|
};
|
|
27345
27856
|
var unpackVsix = async (vsix, work) => {
|
|
27346
|
-
const out = mkdirp(
|
|
27857
|
+
const out = mkdirp(path34.join(work, "vsix-" + path34.basename(vsix)));
|
|
27347
27858
|
await extractArchive(vsix, out, ["Contents"]);
|
|
27348
|
-
const
|
|
27349
|
-
for (const entry of
|
|
27350
|
-
const from =
|
|
27859
|
+
const decode4 = (dir) => {
|
|
27860
|
+
for (const entry of fs23.readdirSync(dir, { withFileTypes: true })) {
|
|
27861
|
+
const from = path34.join(dir, entry.name);
|
|
27351
27862
|
let name = entry.name;
|
|
27352
27863
|
try {
|
|
27353
27864
|
if (name.includes("%")) name = decodeURIComponent(name);
|
|
27354
27865
|
} catch {
|
|
27355
27866
|
}
|
|
27356
|
-
const to =
|
|
27357
|
-
if (to !== from)
|
|
27358
|
-
if (entry.isDirectory())
|
|
27867
|
+
const to = path34.join(dir, name);
|
|
27868
|
+
if (to !== from) fs23.renameSync(from, to);
|
|
27869
|
+
if (entry.isDirectory()) decode4(to);
|
|
27359
27870
|
}
|
|
27360
27871
|
};
|
|
27361
|
-
|
|
27362
|
-
|
|
27872
|
+
decode4(out);
|
|
27873
|
+
fs23.cpSync(path34.join(out, "Contents"), ROOT, { recursive: true, force: true });
|
|
27363
27874
|
safeRemove(out, work);
|
|
27364
27875
|
};
|
|
27365
27876
|
var unpackMsi = async (msi) => {
|
|
@@ -27367,8 +27878,8 @@ var unpackMsi = async (msi) => {
|
|
|
27367
27878
|
try {
|
|
27368
27879
|
await execAsync(system32("msiexec.exe"), ["/a", msi, "/quiet", "/qn", "TARGETDIR=" + ROOT, "/l*v", logFile2], { stdio: "ignore" });
|
|
27369
27880
|
} catch (e) {
|
|
27370
|
-
const lines = exists(logFile2) ?
|
|
27371
|
-
throw new Error(
|
|
27881
|
+
const lines = exists(logFile2) ? fs23.readFileSync(logFile2, "utf16le").split(/\r?\n/).filter((l) => /error|return value 3|failed/i.test(l)).slice(-4).join(" | ") : "";
|
|
27882
|
+
throw new Error(path34.basename(msi) + " did not unpack: " + (e instanceof Error ? e.message : String(e)) + (lines ? " (" + lines.slice(0, 600) + ")" : ""));
|
|
27372
27883
|
}
|
|
27373
27884
|
};
|
|
27374
27885
|
var catalogue = (m) => {
|
|
@@ -27380,13 +27891,13 @@ var catalogue = (m) => {
|
|
|
27380
27891
|
};
|
|
27381
27892
|
};
|
|
27382
27893
|
var payloadFetcher = (work) => async (p) => {
|
|
27383
|
-
const file3 =
|
|
27894
|
+
const file3 = path34.join(work, path34.basename(p.fileName.replace(/\\/g, "/")));
|
|
27384
27895
|
if (!exists(file3)) await download(p.url, file3, p.sha256);
|
|
27385
27896
|
return file3;
|
|
27386
27897
|
};
|
|
27387
27898
|
var unpackedToolset = () => {
|
|
27388
|
-
const toolsRoot =
|
|
27389
|
-
return
|
|
27899
|
+
const toolsRoot = path34.join(ROOT, "VC", "Tools", "MSVC");
|
|
27900
|
+
return fs23.readdirSync(toolsRoot).filter((d) => exists(hostBin(d, "cl.exe"))).sort((a, b) => a.localeCompare(b, void 0, { numeric: true })).pop();
|
|
27390
27901
|
};
|
|
27391
27902
|
var installPackages = async (config2) => {
|
|
27392
27903
|
const { ids, pick: pick2 } = catalogue(await manifest());
|
|
@@ -27394,7 +27905,7 @@ var installPackages = async (config2) => {
|
|
|
27394
27905
|
if (!version2) throw new Error("no MSVC " + config2.msvcVersion + " in the Visual Studio manifest");
|
|
27395
27906
|
const sdk = pickWindowsSdk(ids, config2.sdkVersion);
|
|
27396
27907
|
if (!sdk) throw new Error("no Windows SDK " + config2.sdkVersion + " in the Visual Studio manifest");
|
|
27397
|
-
const work = mkdirp(
|
|
27908
|
+
const work = mkdirp(path34.join(ROOT, ".download"));
|
|
27398
27909
|
const fetchPayload = payloadFetcher(work);
|
|
27399
27910
|
log("Downloading the MSVC " + version2 + " compiler and C/C++ libraries ...");
|
|
27400
27911
|
for (const part of MSVC_PARTS) {
|
|
@@ -27413,16 +27924,16 @@ var installPackages = async (config2) => {
|
|
|
27413
27924
|
if (!p) throw new Error("the Windows SDK package has no " + name);
|
|
27414
27925
|
const file3 = await fetchPayload(p);
|
|
27415
27926
|
msis.push(file3);
|
|
27416
|
-
for (const cab of msiCabs(
|
|
27927
|
+
for (const cab of msiCabs(fs23.readFileSync(file3))) {
|
|
27417
27928
|
const c = payload(cab);
|
|
27418
27929
|
if (c) await fetchPayload(c);
|
|
27419
27930
|
}
|
|
27420
27931
|
}
|
|
27421
27932
|
log("Unpacking the Windows SDK (a few minutes) ...");
|
|
27422
27933
|
for (const msi of msis) await unpackMsi(msi);
|
|
27423
|
-
for (const name of
|
|
27934
|
+
for (const name of fs23.readdirSync(ROOT).filter((n) => n.toLowerCase().endsWith(".msi"))) fs23.rmSync(path34.join(ROOT, name), { force: true });
|
|
27424
27935
|
safeRemove(work, ROOT);
|
|
27425
|
-
const sdkVersion =
|
|
27936
|
+
const sdkVersion = fs23.readdirSync(path34.join(ROOT, "Windows Kits", "10", "Include")).filter((d) => d.startsWith("10.0." + sdk.build)).sort().pop();
|
|
27426
27937
|
if (!sdkVersion) throw new Error("the Windows SDK did not unpack (no Include\\10.0." + sdk.build + ".*)");
|
|
27427
27938
|
const toolset = unpackedToolset();
|
|
27428
27939
|
if (!toolset) throw new Error("MSVC " + version2 + " did not unpack (no cl.exe under VC\\Tools\\MSVC)");
|
|
@@ -27436,7 +27947,7 @@ var installedMsvcEnv = () => {
|
|
|
27436
27947
|
};
|
|
27437
27948
|
var clearTree = () => {
|
|
27438
27949
|
if (!exists(ROOT)) return;
|
|
27439
|
-
for (const name of
|
|
27950
|
+
for (const name of fs24.readdirSync(ROOT).filter((n) => n !== ".manifest.json" && n !== ".download")) safeRemove(path35.join(ROOT, name), ROOT);
|
|
27440
27951
|
};
|
|
27441
27952
|
var setupMsvc = async (env, config2) => {
|
|
27442
27953
|
if (!config2.acceptLicense) {
|
|
@@ -27452,7 +27963,7 @@ var setupMsvc = async (env, config2) => {
|
|
|
27452
27963
|
log("Installing MSVC and the Windows SDK (~1-2 GB, once; licence accepted in toolchains.msvc.acceptLicense) ...");
|
|
27453
27964
|
clearTree();
|
|
27454
27965
|
done = { ...await installPackages(config2), want };
|
|
27455
|
-
writeJsonAtomic(
|
|
27966
|
+
writeJsonAtomic(MARKER2, done);
|
|
27456
27967
|
}
|
|
27457
27968
|
removeTelemetry(done.msvc);
|
|
27458
27969
|
const vc = vcvars(ROOT, done.msvc, done.sdk);
|
|
@@ -27464,20 +27975,20 @@ var setupMsvc = async (env, config2) => {
|
|
|
27464
27975
|
};
|
|
27465
27976
|
|
|
27466
27977
|
// src/guest/toolchains/native/rust.ts
|
|
27467
|
-
import
|
|
27978
|
+
import path37 from "node:path";
|
|
27468
27979
|
|
|
27469
27980
|
// src/guest/toolchains/native/binstall.ts
|
|
27470
|
-
import
|
|
27471
|
-
import
|
|
27981
|
+
import fs25 from "node:fs";
|
|
27982
|
+
import path36 from "node:path";
|
|
27472
27983
|
var ensureBinstall = async (cargoBin) => {
|
|
27473
|
-
const target =
|
|
27984
|
+
const target = path36.join(cargoBin, "cargo-binstall.exe");
|
|
27474
27985
|
if (exists(target)) return true;
|
|
27475
27986
|
try {
|
|
27476
27987
|
const dir = tool("cargo-binstall");
|
|
27477
|
-
if (!exists(
|
|
27988
|
+
if (!exists(path36.join(dir, "cargo-binstall.exe"))) {
|
|
27478
27989
|
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
27990
|
}
|
|
27480
|
-
|
|
27991
|
+
fs25.copyFileSync(path36.join(dir, "cargo-binstall.exe"), target);
|
|
27481
27992
|
return true;
|
|
27482
27993
|
} catch (e) {
|
|
27483
27994
|
warn("cargo-binstall unavailable, compiling crates with cargo install instead: " + errMsg(e));
|
|
@@ -27485,11 +27996,11 @@ var ensureBinstall = async (cargoBin) => {
|
|
|
27485
27996
|
}
|
|
27486
27997
|
};
|
|
27487
27998
|
var crateInstaller = (cargoHome, cargoEnv) => {
|
|
27488
|
-
const cargo =
|
|
27999
|
+
const cargo = path36.join(cargoHome, "bin", "cargo.exe");
|
|
27489
28000
|
let binstall = null;
|
|
27490
28001
|
const binstallEnv = { ...cargoEnv, env: { ...cargoEnv.env ?? process.env, BINSTALL_DISABLE_TELEMETRY: "true" } };
|
|
27491
28002
|
return async (crate) => {
|
|
27492
|
-
binstall ??= ensureBinstall(
|
|
28003
|
+
binstall ??= ensureBinstall(path36.join(cargoHome, "bin"));
|
|
27493
28004
|
if (await binstall) {
|
|
27494
28005
|
try {
|
|
27495
28006
|
await execAsync(cargo, ["binstall", "--no-confirm", "--locked", "--disable-strategies", "compile", crate], binstallEnv);
|
|
@@ -27507,7 +28018,7 @@ var setupRust = async (env, config2, refresh) => {
|
|
|
27507
28018
|
const RUSTUP_HOME = tool("rust", "rustup");
|
|
27508
28019
|
const CARGO_HOME = tool("rust", "cargo");
|
|
27509
28020
|
const rustEnv = { env: { ...process.env, RUSTUP_HOME, CARGO_HOME } };
|
|
27510
|
-
const rustup =
|
|
28021
|
+
const rustup = path37.join(CARGO_HOME, "bin", "rustup.exe");
|
|
27511
28022
|
if (dryRun) {
|
|
27512
28023
|
log("(dry run) would provision Rust " + config2.toolchain + " (" + config2.host + ")");
|
|
27513
28024
|
return;
|
|
@@ -27524,35 +28035,35 @@ var setupRust = async (env, config2, refresh) => {
|
|
|
27524
28035
|
if (refresh) await execAsync(rustup, ["update"], rustEnv);
|
|
27525
28036
|
}
|
|
27526
28037
|
Object.assign(env.vars, { RUSTUP_HOME, CARGO_HOME });
|
|
27527
|
-
env.prepend.push(
|
|
27528
|
-
env.summary.push("rust: " + versionOf(
|
|
28038
|
+
env.prepend.push(path37.join(CARGO_HOME, "bin"));
|
|
28039
|
+
env.summary.push("rust: " + versionOf(path37.join(CARGO_HOME, "bin", "rustc.exe"), ["--version"], rustEnv) + " [" + config2.host + "]");
|
|
27529
28040
|
const toolchainKey = "rustup@" + config2.toolchain;
|
|
27530
28041
|
await installOnce(env, toolchainKey + " components", config2.components, (c) => execAsync(rustup, ["component", "add", c], rustEnv));
|
|
27531
28042
|
await installOnce(env, toolchainKey + " targets", config2.targets, (t) => execAsync(rustup, ["target", "add", t], rustEnv));
|
|
27532
28043
|
const msvc = config2.host.endsWith("-msvc") ? installedMsvcEnv() : null;
|
|
27533
28044
|
const mingw = tool("mingw", "mingw64", "bin");
|
|
27534
|
-
const cargoEnv = msvc ? { env: { ...rustEnv.env, ...msvc.vars, PATH: [
|
|
28045
|
+
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
28046
|
await installOnce(env, "cargo", config2.crates, crateInstaller(CARGO_HOME, cargoEnv));
|
|
27536
28047
|
};
|
|
27537
28048
|
|
|
27538
28049
|
// src/guest/toolchains/node.ts
|
|
27539
|
-
import
|
|
27540
|
-
import
|
|
28050
|
+
import fs26 from "node:fs";
|
|
28051
|
+
import path38 from "node:path";
|
|
27541
28052
|
import { spawn as spawn4 } from "node:child_process";
|
|
27542
28053
|
var NVM_HOME = tool("nvm");
|
|
27543
|
-
var NVM_SYMLINK =
|
|
27544
|
-
var HOST_NVM =
|
|
28054
|
+
var NVM_SYMLINK = path38.join(localDir, "nodejs");
|
|
28055
|
+
var HOST_NVM = path38.join(hostToolsDir, "nvm");
|
|
27545
28056
|
var HOST_VERSIONS_MAX = 3;
|
|
27546
|
-
var hostNvmVersions = () => exists(HOST_NVM) ?
|
|
28057
|
+
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
28058
|
var resolveNode = (spec) => resolveCached("node:" + spec, async () => {
|
|
27548
28059
|
const exact = spec.replace(/^v/, "");
|
|
27549
28060
|
if (/^\d+\.\d+\.\d+$/.test(exact)) return exact;
|
|
27550
28061
|
const releases = await fetchJson("https://nodejs.org/dist/index.json");
|
|
27551
28062
|
return pickNodeVersion(releases, spec) ?? Promise.reject(new Error('No Node.js release matches "' + spec + '"'));
|
|
27552
28063
|
});
|
|
27553
|
-
var NVM_TEMP =
|
|
27554
|
-
var nvm = (args) => new Promise((
|
|
27555
|
-
const child = spawn4(
|
|
28064
|
+
var NVM_TEMP = path38.join(NVM_HOME, ".tmp");
|
|
28065
|
+
var nvm = (args) => new Promise((resolve2) => {
|
|
28066
|
+
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
28067
|
let out = "";
|
|
27557
28068
|
child.stdout.on("data", (d) => {
|
|
27558
28069
|
out += d.toString();
|
|
@@ -27560,16 +28071,16 @@ var nvm = (args) => new Promise((resolve) => {
|
|
|
27560
28071
|
child.stderr.on("data", (d) => {
|
|
27561
28072
|
out += d.toString();
|
|
27562
28073
|
});
|
|
27563
|
-
child.once("error", (e) =>
|
|
27564
|
-
child.once("close", () =>
|
|
28074
|
+
child.once("error", (e) => resolve2(out + e.message));
|
|
28075
|
+
child.once("close", () => resolve2(out));
|
|
27565
28076
|
});
|
|
27566
28077
|
var ensureNvm = async () => {
|
|
27567
|
-
if (exists(
|
|
27568
|
-
if (exists(
|
|
28078
|
+
if (exists(path38.join(NVM_HOME, "nvm.exe"))) return;
|
|
28079
|
+
if (exists(path38.join(HOST_NVM, "nvm.exe"))) {
|
|
27569
28080
|
log("Copying nvm from this PC ...");
|
|
27570
28081
|
mkdirp(NVM_HOME);
|
|
27571
|
-
const files =
|
|
27572
|
-
for (const file3 of files)
|
|
28082
|
+
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"));
|
|
28083
|
+
for (const file3 of files) fs26.copyFileSync(path38.join(HOST_NVM, file3), path38.join(NVM_HOME, file3));
|
|
27573
28084
|
return;
|
|
27574
28085
|
}
|
|
27575
28086
|
const asset = await githubAsset("coreybutler/nvm-windows", /^nvm-noinstall\.zip$/, true);
|
|
@@ -27577,10 +28088,10 @@ var ensureNvm = async () => {
|
|
|
27577
28088
|
await installArchive(asset.url, NVM_HOME, { sha256: asset.sha256, locate: "nvm.exe", fileName: asset.name });
|
|
27578
28089
|
};
|
|
27579
28090
|
var installNodeVersion = async (version2) => {
|
|
27580
|
-
const dir =
|
|
27581
|
-
const fromHost =
|
|
27582
|
-
if (exists(
|
|
27583
|
-
if (exists(
|
|
28091
|
+
const dir = path38.join(NVM_HOME, "v" + version2);
|
|
28092
|
+
const fromHost = path38.join(HOST_NVM, "v" + version2);
|
|
28093
|
+
if (exists(path38.join(dir, "node.exe"))) return;
|
|
28094
|
+
if (exists(path38.join(fromHost, "node.exe"))) {
|
|
27584
28095
|
log("Copying Node " + version2 + " from this PC's nvm (without global packages) ...");
|
|
27585
28096
|
copyNode(fromHost, dir);
|
|
27586
28097
|
return;
|
|
@@ -27593,13 +28104,13 @@ var installNodeVersion = async (version2) => {
|
|
|
27593
28104
|
} finally {
|
|
27594
28105
|
safeRemove(NVM_TEMP, NVM_HOME);
|
|
27595
28106
|
}
|
|
27596
|
-
if (!exists(
|
|
28107
|
+
if (!exists(path38.join(dir, "node.exe"))) throw new Error("nvm install " + version2 + " failed: " + out.trim().split("\n").slice(-2).join(" "));
|
|
27597
28108
|
};
|
|
27598
28109
|
var activate = async (version2) => {
|
|
27599
28110
|
await nvm(["use", version2]);
|
|
27600
|
-
if (exists(
|
|
27601
|
-
|
|
27602
|
-
|
|
28111
|
+
if (exists(path38.join(NVM_SYMLINK, "node.exe"))) return;
|
|
28112
|
+
fs26.rmSync(NVM_SYMLINK, { recursive: true, force: true });
|
|
28113
|
+
fs26.symlinkSync(path38.join(NVM_HOME, "v" + version2), NVM_SYMLINK, "junction");
|
|
27603
28114
|
};
|
|
27604
28115
|
var setupNode = async (env, versions, config2) => {
|
|
27605
28116
|
if (dryRun) {
|
|
@@ -27607,7 +28118,7 @@ var setupNode = async (env, versions, config2) => {
|
|
|
27607
28118
|
return;
|
|
27608
28119
|
}
|
|
27609
28120
|
await ensureNvm();
|
|
27610
|
-
|
|
28121
|
+
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
28122
|
mkdirp(localDir);
|
|
27612
28123
|
for (const extra of versions.nodeExtra) {
|
|
27613
28124
|
try {
|
|
@@ -27626,7 +28137,7 @@ var setupNode = async (env, versions, config2) => {
|
|
|
27626
28137
|
}
|
|
27627
28138
|
}
|
|
27628
28139
|
Object.assign(env.vars, { NVM_HOME, NVM_SYMLINK });
|
|
27629
|
-
if (duringSession()) env.prepend.push(
|
|
28140
|
+
if (duringSession()) env.prepend.push(path38.join(NVM_HOME, "v" + main), NVM_HOME, NVM_SYMLINK);
|
|
27630
28141
|
else {
|
|
27631
28142
|
await activate(main);
|
|
27632
28143
|
env.prepend.push(NVM_HOME, NVM_SYMLINK);
|
|
@@ -27635,10 +28146,10 @@ var setupNode = async (env, versions, config2) => {
|
|
|
27635
28146
|
await packageManagers(env, config2, main);
|
|
27636
28147
|
};
|
|
27637
28148
|
var packageManagers = async (env, config2, version2) => {
|
|
27638
|
-
const dir =
|
|
27639
|
-
const nodeEnv = { ...process.env, PATH: dir +
|
|
27640
|
-
const npm = (args) => execAsync(
|
|
27641
|
-
const corepackJs =
|
|
28149
|
+
const dir = path38.join(NVM_HOME, "v" + version2);
|
|
28150
|
+
const nodeEnv = { ...process.env, PATH: dir + path38.delimiter + (process.env.PATH ?? "") };
|
|
28151
|
+
const npm = (args) => execAsync(path38.join(dir, "node.exe"), [path38.join(dir, "node_modules", "npm", "bin", "npm-cli.js"), ...args], { env: nodeEnv, stdio: "ignore" });
|
|
28152
|
+
const corepackJs = path38.join(dir, "node_modules", "corepack", "dist", "corepack.js");
|
|
27642
28153
|
const extra = config2.corepack && !exists(corepackJs) ? ["corepack"] : [];
|
|
27643
28154
|
await installOnce(env, "npm@" + version2, [...extra, ...config2.globalPackages], (pkg) => npm(["install", "--global", pkg, "--no-fund", "--no-audit"]));
|
|
27644
28155
|
if (!config2.corepack) return;
|
|
@@ -27648,7 +28159,7 @@ var packageManagers = async (env, config2, version2) => {
|
|
|
27648
28159
|
return;
|
|
27649
28160
|
}
|
|
27650
28161
|
try {
|
|
27651
|
-
await execAsync(
|
|
28162
|
+
await execAsync(path38.join(dir, "node.exe"), [corepackJs, "enable", "--install-directory", mkdirp(tool("bin")), "pnpm", "yarn"], { env: nodeEnv, stdio: "ignore" });
|
|
27652
28163
|
env.summary.push('pnpm, yarn: via corepack (package.json "packageManager" picks the version)');
|
|
27653
28164
|
} catch (e) {
|
|
27654
28165
|
warn("corepack enable failed: " + errMsg(e));
|
|
@@ -27663,31 +28174,48 @@ var setupPwsh = async (env, refresh = false) => {
|
|
|
27663
28174
|
};
|
|
27664
28175
|
|
|
27665
28176
|
// src/guest/toolchains/python.ts
|
|
27666
|
-
import
|
|
27667
|
-
import
|
|
28177
|
+
import fs27 from "node:fs";
|
|
28178
|
+
import path39 from "node:path";
|
|
27668
28179
|
var installPython = async (pkg, spec) => {
|
|
27669
28180
|
const version2 = await resolveCached(pkg + ":" + spec, async () => {
|
|
27670
28181
|
const { versions } = await fetchJson("https://api.nuget.org/v3-flatcontainer/" + pkg + "/index.json");
|
|
27671
28182
|
return pickPackageVersion(versions, spec) ?? Promise.reject(new Error("No " + pkg + ' release matches "' + spec + '"'));
|
|
27672
28183
|
});
|
|
27673
28184
|
const dir = tool("python", pkg + "-" + version2);
|
|
27674
|
-
const exe =
|
|
28185
|
+
const exe = path39.join(dir, "python.exe");
|
|
27675
28186
|
if (!exists(exe)) {
|
|
27676
28187
|
log("Downloading Python " + version2 + (pkg === "python2" ? " (Python 2, " : " (") + "~30 MB once) ...");
|
|
27677
28188
|
await installArchive("https://api.nuget.org/v3-flatcontainer/" + pkg + "/" + version2 + "/" + pkg + "." + version2 + ".nupkg", dir, { locate: "python.exe", fileName: pkg + "." + version2 + ".zip" });
|
|
27678
28189
|
}
|
|
27679
|
-
if (!exists(
|
|
28190
|
+
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
28191
|
return dir;
|
|
27681
28192
|
};
|
|
27682
|
-
var shimDir = (dir) => duringSession() ? tool("shims",
|
|
28193
|
+
var shimDir = (dir) => duringSession() ? tool("shims", path39.basename(dir)) : tool("shims");
|
|
27683
28194
|
var shim = (folder, name, command) => {
|
|
27684
|
-
|
|
28195
|
+
fs27.writeFileSync(path39.join(mkdirp(folder), name + ".cmd"), "@echo off\r\n" + command + " %*\r\n");
|
|
27685
28196
|
};
|
|
27686
28197
|
var shimPair = (folder, version2, dir) => {
|
|
27687
|
-
const python = '"' +
|
|
28198
|
+
const python = '"' + path39.join(dir, "python.exe") + '"';
|
|
27688
28199
|
shim(folder, "python" + version2, python);
|
|
27689
28200
|
shim(folder, "pip" + version2, python + " -m pip");
|
|
27690
28201
|
};
|
|
28202
|
+
var pyLauncher = (folder, py3, py2) => {
|
|
28203
|
+
const script = path39.join(mkdirp(folder), "py-launcher.py");
|
|
28204
|
+
fs27.writeFileSync(script, [
|
|
28205
|
+
"import subprocess, sys",
|
|
28206
|
+
"PY3, PY2 = " + JSON.stringify(path39.join(py3, "python.exe")) + ", " + JSON.stringify(py2 ? path39.join(py2, "python.exe") : null),
|
|
28207
|
+
"args = sys.argv[1:]",
|
|
28208
|
+
"exe = PY3",
|
|
28209
|
+
"if args and args[0].startswith('-2'):",
|
|
28210
|
+
' if not PY2: sys.exit("py: Python 2 is not installed (toolchains.python.python2)")',
|
|
28211
|
+
" exe, args = PY2, args[1:]",
|
|
28212
|
+
"elif args and (args[0] == '-3' or args[0].startswith('-3.') or args[0].startswith('-3-')):",
|
|
28213
|
+
" args = args[1:]",
|
|
28214
|
+
"sys.exit(subprocess.call([exe] + args))",
|
|
28215
|
+
""
|
|
28216
|
+
].join("\n"));
|
|
28217
|
+
shim(folder, "py", '"' + path39.join(py3, "python.exe") + '" "' + script + '"');
|
|
28218
|
+
};
|
|
27691
28219
|
var setupPython = async (env, config2, versions) => {
|
|
27692
28220
|
if (dryRun) {
|
|
27693
28221
|
log("(dry run) would provision Python " + versions.python.spec + (config2.python2 ? " and Python 2.7" : ""));
|
|
@@ -27696,22 +28224,26 @@ var setupPython = async (env, config2, versions) => {
|
|
|
27696
28224
|
const py3 = await installPython("python", versions.python.spec);
|
|
27697
28225
|
const shims = shimDir(py3);
|
|
27698
28226
|
shimPair(shims, "3", py3);
|
|
27699
|
-
env.prepend.push(py3,
|
|
28227
|
+
env.prepend.push(py3, path39.join(py3, "Scripts"), shims);
|
|
27700
28228
|
env.vars.PYTHONIOENCODING = "utf-8";
|
|
27701
|
-
env.summary.push("python: " +
|
|
27702
|
-
if (!config2.python2)
|
|
28229
|
+
env.summary.push("python: " + path39.basename(py3).replace("python-", "") + " (from " + versions.python.source + "; py works too)");
|
|
28230
|
+
if (!config2.python2) {
|
|
28231
|
+
pyLauncher(shims, py3, null);
|
|
28232
|
+
return;
|
|
28233
|
+
}
|
|
27703
28234
|
const py2 = await installPython("python2", "2.7");
|
|
27704
28235
|
shimPair(shims, "2", py2);
|
|
27705
|
-
|
|
28236
|
+
pyLauncher(shims, py3, py2);
|
|
28237
|
+
env.summary.push("python2: " + path39.basename(py2).replace("python2-", ""));
|
|
27706
28238
|
};
|
|
27707
28239
|
|
|
27708
28240
|
// src/guest/toolchains/scripting/php.ts
|
|
27709
|
-
import
|
|
27710
|
-
import
|
|
28241
|
+
import fs29 from "node:fs";
|
|
28242
|
+
import path41 from "node:path";
|
|
27711
28243
|
|
|
27712
28244
|
// src/guest/toolchains/scripting/vcruntime.ts
|
|
27713
|
-
import
|
|
27714
|
-
import
|
|
28245
|
+
import fs28 from "node:fs";
|
|
28246
|
+
import path40 from "node:path";
|
|
27715
28247
|
var VC_REDIST = "https://aka.ms/vs/17/release/vc_redist.x64.exe";
|
|
27716
28248
|
var MICROSOFT_SIGNER = "CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US";
|
|
27717
28249
|
var OK_EXIT_CODES = [0, 1638, 3010];
|
|
@@ -27726,8 +28258,8 @@ var setupVcRuntime = async (env, summary = true) => {
|
|
|
27726
28258
|
log("(dry run) would install the Visual C++ runtime");
|
|
27727
28259
|
return false;
|
|
27728
28260
|
}
|
|
27729
|
-
const system322 =
|
|
27730
|
-
const missing = !exists(
|
|
28261
|
+
const system322 = path40.join(process.env.WINDIR ?? "C:\\Windows", "System32");
|
|
28262
|
+
const missing = !exists(path40.join(system322, "vcruntime140.dll")) || !exists(path40.join(system322, "msvcp140.dll"));
|
|
27731
28263
|
if (missing) {
|
|
27732
28264
|
const installer = tool("vcredist", "vc_redist.x64.exe");
|
|
27733
28265
|
if (!exists(installer)) {
|
|
@@ -27735,12 +28267,12 @@ var setupVcRuntime = async (env, summary = true) => {
|
|
|
27735
28267
|
await downloadFile(VC_REDIST, installer);
|
|
27736
28268
|
}
|
|
27737
28269
|
if (signerOf(installer) !== MICROSOFT_SIGNER) {
|
|
27738
|
-
|
|
28270
|
+
fs28.rmSync(installer, { force: true });
|
|
27739
28271
|
throw new Error("vc_redist.x64.exe is not signed by Microsoft; deleted it (it is downloaded again next boot)");
|
|
27740
28272
|
}
|
|
27741
28273
|
log("Installing the Visual C++ runtime ...");
|
|
27742
28274
|
const code = await spawnAsync(installer, ["/install", "/quiet", "/norestart"]);
|
|
27743
|
-
if (!OK_EXIT_CODES.includes(code ?? -1) || !exists(
|
|
28275
|
+
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
28276
|
}
|
|
27745
28277
|
if (summary) env.summary.push("vc++ runtime: installed");
|
|
27746
28278
|
return missing;
|
|
@@ -27758,15 +28290,15 @@ var phpBuild = async (spec) => {
|
|
|
27758
28290
|
return { version: release.version, ...build.zip };
|
|
27759
28291
|
};
|
|
27760
28292
|
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
|
-
|
|
28293
|
+
const ini = path41.join(home, "php.ini");
|
|
28294
|
+
if (exists(ini) || !exists(path41.join(home, "php.ini-development"))) return;
|
|
28295
|
+
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") + '"');
|
|
28296
|
+
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");
|
|
28297
|
+
fs29.writeFileSync(ini + ".tmp", text);
|
|
28298
|
+
fs29.renameSync(ini + ".tmp", ini);
|
|
27767
28299
|
};
|
|
27768
28300
|
var shim2 = (env, name, command) => {
|
|
27769
|
-
|
|
28301
|
+
fs29.writeFileSync(path41.join(mkdirp(tool("shims")), name + ".cmd"), "@echo off\r\n" + command + " %*\r\n");
|
|
27770
28302
|
env.prepend.push(tool("shims"));
|
|
27771
28303
|
};
|
|
27772
28304
|
var setupComposer = async (env, php) => {
|
|
@@ -27778,7 +28310,7 @@ var setupComposer = async (env, php) => {
|
|
|
27778
28310
|
}
|
|
27779
28311
|
const composerHome = tool("composer-home");
|
|
27780
28312
|
env.vars.COMPOSER_HOME = composerHome;
|
|
27781
|
-
env.prepend.push(
|
|
28313
|
+
env.prepend.push(path41.join(composerHome, "vendor", "bin"));
|
|
27782
28314
|
shim2(env, "composer", '"' + php + '" "' + phar + '"');
|
|
27783
28315
|
env.summary.push("composer: " + (/\d+\.\d+\.\d+/.exec(execOutput(php, [phar, "--version", "--no-ansi"]))?.[0] ?? "installed"));
|
|
27784
28316
|
};
|
|
@@ -27791,7 +28323,7 @@ var setupPhp = async (env, config2) => {
|
|
|
27791
28323
|
await setupVcRuntime(env, false);
|
|
27792
28324
|
const version2 = await resolveCached("php:" + wantedSpec.spec, async () => (await phpBuild(wantedSpec.spec)).version);
|
|
27793
28325
|
const home = tool("php", version2);
|
|
27794
|
-
if (!exists(
|
|
28326
|
+
if (!exists(path41.join(home, "php.exe"))) {
|
|
27795
28327
|
const build = await phpBuild(version2);
|
|
27796
28328
|
log("Downloading PHP " + version2 + " (~30 MB once) ...");
|
|
27797
28329
|
await installArchive("https://windows.php.net/downloads/releases/" + build.path, home, { sha256: build.sha256, locate: "php.exe", fileName: build.path });
|
|
@@ -27799,11 +28331,11 @@ var setupPhp = async (env, config2) => {
|
|
|
27799
28331
|
writePhpIni(home);
|
|
27800
28332
|
env.prepend.push(home);
|
|
27801
28333
|
env.summary.push("php: " + version2 + " (from " + wantedSpec.source + ")");
|
|
27802
|
-
if (config2.composer) await setupComposer(env,
|
|
28334
|
+
if (config2.composer) await setupComposer(env, path41.join(home, "php.exe"));
|
|
27803
28335
|
};
|
|
27804
28336
|
|
|
27805
28337
|
// src/guest/toolchains/scripting/ruby.ts
|
|
27806
|
-
import
|
|
28338
|
+
import path42 from "node:path";
|
|
27807
28339
|
var RUBY_ASSET = /^rubyinstaller-(\d+\.\d+\.\d+)-(\d+)-x64\.7z$/;
|
|
27808
28340
|
var buildNumber = (asset) => Number(RUBY_ASSET.exec(asset.name)?.[2] ?? 0);
|
|
27809
28341
|
var rubyBuilds = async () => {
|
|
@@ -27826,7 +28358,7 @@ var setupRuby = async (env, config2) => {
|
|
|
27826
28358
|
}
|
|
27827
28359
|
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
28360
|
const home = tool("ruby", version2);
|
|
27829
|
-
if (!exists(
|
|
28361
|
+
if (!exists(path42.join(home, "bin", "ruby.exe"))) {
|
|
27830
28362
|
const asset = (await rubyBuilds()).get(version2);
|
|
27831
28363
|
if (!asset) throw new Error("RubyInstaller " + version2 + " is no longer published");
|
|
27832
28364
|
log("Downloading Ruby " + version2 + " (~100 MB once) ...");
|
|
@@ -27834,26 +28366,202 @@ var setupRuby = async (env, config2) => {
|
|
|
27834
28366
|
}
|
|
27835
28367
|
const gems = tool("ruby-gems", version2.split(".").slice(0, 2).join("."));
|
|
27836
28368
|
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 =
|
|
28369
|
+
env.prepend.push(path42.join(home, "bin"), path42.join(gems, "bin"));
|
|
28370
|
+
env.summary.push("ruby: " + versionOf(path42.join(home, "bin", "ruby.exe")) + " (from " + wantedSpec.source + "; gems with C extensions need MSYS2, not included)");
|
|
28371
|
+
const gem = path42.join(home, "bin", "gem.cmd");
|
|
27840
28372
|
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
28373
|
};
|
|
27842
28374
|
|
|
27843
28375
|
// src/guest/toolchains/vscode.ts
|
|
27844
|
-
import
|
|
27845
|
-
import
|
|
27846
|
-
import
|
|
28376
|
+
import fs30 from "node:fs";
|
|
28377
|
+
import os7 from "node:os";
|
|
28378
|
+
import path43 from "node:path";
|
|
28379
|
+
|
|
28380
|
+
// node_modules/jsonc-parser/lib/esm/impl/scanner.js
|
|
28381
|
+
var CharacterCodes;
|
|
28382
|
+
(function(CharacterCodes2) {
|
|
28383
|
+
CharacterCodes2[CharacterCodes2["lineFeed"] = 10] = "lineFeed";
|
|
28384
|
+
CharacterCodes2[CharacterCodes2["carriageReturn"] = 13] = "carriageReturn";
|
|
28385
|
+
CharacterCodes2[CharacterCodes2["space"] = 32] = "space";
|
|
28386
|
+
CharacterCodes2[CharacterCodes2["_0"] = 48] = "_0";
|
|
28387
|
+
CharacterCodes2[CharacterCodes2["_1"] = 49] = "_1";
|
|
28388
|
+
CharacterCodes2[CharacterCodes2["_2"] = 50] = "_2";
|
|
28389
|
+
CharacterCodes2[CharacterCodes2["_3"] = 51] = "_3";
|
|
28390
|
+
CharacterCodes2[CharacterCodes2["_4"] = 52] = "_4";
|
|
28391
|
+
CharacterCodes2[CharacterCodes2["_5"] = 53] = "_5";
|
|
28392
|
+
CharacterCodes2[CharacterCodes2["_6"] = 54] = "_6";
|
|
28393
|
+
CharacterCodes2[CharacterCodes2["_7"] = 55] = "_7";
|
|
28394
|
+
CharacterCodes2[CharacterCodes2["_8"] = 56] = "_8";
|
|
28395
|
+
CharacterCodes2[CharacterCodes2["_9"] = 57] = "_9";
|
|
28396
|
+
CharacterCodes2[CharacterCodes2["a"] = 97] = "a";
|
|
28397
|
+
CharacterCodes2[CharacterCodes2["b"] = 98] = "b";
|
|
28398
|
+
CharacterCodes2[CharacterCodes2["c"] = 99] = "c";
|
|
28399
|
+
CharacterCodes2[CharacterCodes2["d"] = 100] = "d";
|
|
28400
|
+
CharacterCodes2[CharacterCodes2["e"] = 101] = "e";
|
|
28401
|
+
CharacterCodes2[CharacterCodes2["f"] = 102] = "f";
|
|
28402
|
+
CharacterCodes2[CharacterCodes2["g"] = 103] = "g";
|
|
28403
|
+
CharacterCodes2[CharacterCodes2["h"] = 104] = "h";
|
|
28404
|
+
CharacterCodes2[CharacterCodes2["i"] = 105] = "i";
|
|
28405
|
+
CharacterCodes2[CharacterCodes2["j"] = 106] = "j";
|
|
28406
|
+
CharacterCodes2[CharacterCodes2["k"] = 107] = "k";
|
|
28407
|
+
CharacterCodes2[CharacterCodes2["l"] = 108] = "l";
|
|
28408
|
+
CharacterCodes2[CharacterCodes2["m"] = 109] = "m";
|
|
28409
|
+
CharacterCodes2[CharacterCodes2["n"] = 110] = "n";
|
|
28410
|
+
CharacterCodes2[CharacterCodes2["o"] = 111] = "o";
|
|
28411
|
+
CharacterCodes2[CharacterCodes2["p"] = 112] = "p";
|
|
28412
|
+
CharacterCodes2[CharacterCodes2["q"] = 113] = "q";
|
|
28413
|
+
CharacterCodes2[CharacterCodes2["r"] = 114] = "r";
|
|
28414
|
+
CharacterCodes2[CharacterCodes2["s"] = 115] = "s";
|
|
28415
|
+
CharacterCodes2[CharacterCodes2["t"] = 116] = "t";
|
|
28416
|
+
CharacterCodes2[CharacterCodes2["u"] = 117] = "u";
|
|
28417
|
+
CharacterCodes2[CharacterCodes2["v"] = 118] = "v";
|
|
28418
|
+
CharacterCodes2[CharacterCodes2["w"] = 119] = "w";
|
|
28419
|
+
CharacterCodes2[CharacterCodes2["x"] = 120] = "x";
|
|
28420
|
+
CharacterCodes2[CharacterCodes2["y"] = 121] = "y";
|
|
28421
|
+
CharacterCodes2[CharacterCodes2["z"] = 122] = "z";
|
|
28422
|
+
CharacterCodes2[CharacterCodes2["A"] = 65] = "A";
|
|
28423
|
+
CharacterCodes2[CharacterCodes2["B"] = 66] = "B";
|
|
28424
|
+
CharacterCodes2[CharacterCodes2["C"] = 67] = "C";
|
|
28425
|
+
CharacterCodes2[CharacterCodes2["D"] = 68] = "D";
|
|
28426
|
+
CharacterCodes2[CharacterCodes2["E"] = 69] = "E";
|
|
28427
|
+
CharacterCodes2[CharacterCodes2["F"] = 70] = "F";
|
|
28428
|
+
CharacterCodes2[CharacterCodes2["G"] = 71] = "G";
|
|
28429
|
+
CharacterCodes2[CharacterCodes2["H"] = 72] = "H";
|
|
28430
|
+
CharacterCodes2[CharacterCodes2["I"] = 73] = "I";
|
|
28431
|
+
CharacterCodes2[CharacterCodes2["J"] = 74] = "J";
|
|
28432
|
+
CharacterCodes2[CharacterCodes2["K"] = 75] = "K";
|
|
28433
|
+
CharacterCodes2[CharacterCodes2["L"] = 76] = "L";
|
|
28434
|
+
CharacterCodes2[CharacterCodes2["M"] = 77] = "M";
|
|
28435
|
+
CharacterCodes2[CharacterCodes2["N"] = 78] = "N";
|
|
28436
|
+
CharacterCodes2[CharacterCodes2["O"] = 79] = "O";
|
|
28437
|
+
CharacterCodes2[CharacterCodes2["P"] = 80] = "P";
|
|
28438
|
+
CharacterCodes2[CharacterCodes2["Q"] = 81] = "Q";
|
|
28439
|
+
CharacterCodes2[CharacterCodes2["R"] = 82] = "R";
|
|
28440
|
+
CharacterCodes2[CharacterCodes2["S"] = 83] = "S";
|
|
28441
|
+
CharacterCodes2[CharacterCodes2["T"] = 84] = "T";
|
|
28442
|
+
CharacterCodes2[CharacterCodes2["U"] = 85] = "U";
|
|
28443
|
+
CharacterCodes2[CharacterCodes2["V"] = 86] = "V";
|
|
28444
|
+
CharacterCodes2[CharacterCodes2["W"] = 87] = "W";
|
|
28445
|
+
CharacterCodes2[CharacterCodes2["X"] = 88] = "X";
|
|
28446
|
+
CharacterCodes2[CharacterCodes2["Y"] = 89] = "Y";
|
|
28447
|
+
CharacterCodes2[CharacterCodes2["Z"] = 90] = "Z";
|
|
28448
|
+
CharacterCodes2[CharacterCodes2["asterisk"] = 42] = "asterisk";
|
|
28449
|
+
CharacterCodes2[CharacterCodes2["backslash"] = 92] = "backslash";
|
|
28450
|
+
CharacterCodes2[CharacterCodes2["closeBrace"] = 125] = "closeBrace";
|
|
28451
|
+
CharacterCodes2[CharacterCodes2["closeBracket"] = 93] = "closeBracket";
|
|
28452
|
+
CharacterCodes2[CharacterCodes2["colon"] = 58] = "colon";
|
|
28453
|
+
CharacterCodes2[CharacterCodes2["comma"] = 44] = "comma";
|
|
28454
|
+
CharacterCodes2[CharacterCodes2["dot"] = 46] = "dot";
|
|
28455
|
+
CharacterCodes2[CharacterCodes2["doubleQuote"] = 34] = "doubleQuote";
|
|
28456
|
+
CharacterCodes2[CharacterCodes2["minus"] = 45] = "minus";
|
|
28457
|
+
CharacterCodes2[CharacterCodes2["openBrace"] = 123] = "openBrace";
|
|
28458
|
+
CharacterCodes2[CharacterCodes2["openBracket"] = 91] = "openBracket";
|
|
28459
|
+
CharacterCodes2[CharacterCodes2["plus"] = 43] = "plus";
|
|
28460
|
+
CharacterCodes2[CharacterCodes2["slash"] = 47] = "slash";
|
|
28461
|
+
CharacterCodes2[CharacterCodes2["formFeed"] = 12] = "formFeed";
|
|
28462
|
+
CharacterCodes2[CharacterCodes2["tab"] = 9] = "tab";
|
|
28463
|
+
})(CharacterCodes || (CharacterCodes = {}));
|
|
28464
|
+
|
|
28465
|
+
// node_modules/jsonc-parser/lib/esm/impl/string-intern.js
|
|
28466
|
+
var cachedSpaces = new Array(20).fill(0).map((_2, index) => {
|
|
28467
|
+
return " ".repeat(index);
|
|
28468
|
+
});
|
|
28469
|
+
var maxCachedValues = 200;
|
|
28470
|
+
var cachedBreakLinesWithSpaces = {
|
|
28471
|
+
" ": {
|
|
28472
|
+
"\n": new Array(maxCachedValues).fill(0).map((_2, index) => {
|
|
28473
|
+
return "\n" + " ".repeat(index);
|
|
28474
|
+
}),
|
|
28475
|
+
"\r": new Array(maxCachedValues).fill(0).map((_2, index) => {
|
|
28476
|
+
return "\r" + " ".repeat(index);
|
|
28477
|
+
}),
|
|
28478
|
+
"\r\n": new Array(maxCachedValues).fill(0).map((_2, index) => {
|
|
28479
|
+
return "\r\n" + " ".repeat(index);
|
|
28480
|
+
})
|
|
28481
|
+
},
|
|
28482
|
+
" ": {
|
|
28483
|
+
"\n": new Array(maxCachedValues).fill(0).map((_2, index) => {
|
|
28484
|
+
return "\n" + " ".repeat(index);
|
|
28485
|
+
}),
|
|
28486
|
+
"\r": new Array(maxCachedValues).fill(0).map((_2, index) => {
|
|
28487
|
+
return "\r" + " ".repeat(index);
|
|
28488
|
+
}),
|
|
28489
|
+
"\r\n": new Array(maxCachedValues).fill(0).map((_2, index) => {
|
|
28490
|
+
return "\r\n" + " ".repeat(index);
|
|
28491
|
+
})
|
|
28492
|
+
}
|
|
28493
|
+
};
|
|
28494
|
+
|
|
28495
|
+
// node_modules/jsonc-parser/lib/esm/impl/parser.js
|
|
28496
|
+
var ParseOptions;
|
|
28497
|
+
(function(ParseOptions2) {
|
|
28498
|
+
ParseOptions2.DEFAULT = {
|
|
28499
|
+
allowTrailingComma: false
|
|
28500
|
+
};
|
|
28501
|
+
})(ParseOptions || (ParseOptions = {}));
|
|
28502
|
+
|
|
28503
|
+
// node_modules/jsonc-parser/lib/esm/main.js
|
|
28504
|
+
var ScanError;
|
|
28505
|
+
(function(ScanError2) {
|
|
28506
|
+
ScanError2[ScanError2["None"] = 0] = "None";
|
|
28507
|
+
ScanError2[ScanError2["UnexpectedEndOfComment"] = 1] = "UnexpectedEndOfComment";
|
|
28508
|
+
ScanError2[ScanError2["UnexpectedEndOfString"] = 2] = "UnexpectedEndOfString";
|
|
28509
|
+
ScanError2[ScanError2["UnexpectedEndOfNumber"] = 3] = "UnexpectedEndOfNumber";
|
|
28510
|
+
ScanError2[ScanError2["InvalidUnicode"] = 4] = "InvalidUnicode";
|
|
28511
|
+
ScanError2[ScanError2["InvalidEscapeCharacter"] = 5] = "InvalidEscapeCharacter";
|
|
28512
|
+
ScanError2[ScanError2["InvalidCharacter"] = 6] = "InvalidCharacter";
|
|
28513
|
+
})(ScanError || (ScanError = {}));
|
|
28514
|
+
var SyntaxKind;
|
|
28515
|
+
(function(SyntaxKind2) {
|
|
28516
|
+
SyntaxKind2[SyntaxKind2["OpenBraceToken"] = 1] = "OpenBraceToken";
|
|
28517
|
+
SyntaxKind2[SyntaxKind2["CloseBraceToken"] = 2] = "CloseBraceToken";
|
|
28518
|
+
SyntaxKind2[SyntaxKind2["OpenBracketToken"] = 3] = "OpenBracketToken";
|
|
28519
|
+
SyntaxKind2[SyntaxKind2["CloseBracketToken"] = 4] = "CloseBracketToken";
|
|
28520
|
+
SyntaxKind2[SyntaxKind2["CommaToken"] = 5] = "CommaToken";
|
|
28521
|
+
SyntaxKind2[SyntaxKind2["ColonToken"] = 6] = "ColonToken";
|
|
28522
|
+
SyntaxKind2[SyntaxKind2["NullKeyword"] = 7] = "NullKeyword";
|
|
28523
|
+
SyntaxKind2[SyntaxKind2["TrueKeyword"] = 8] = "TrueKeyword";
|
|
28524
|
+
SyntaxKind2[SyntaxKind2["FalseKeyword"] = 9] = "FalseKeyword";
|
|
28525
|
+
SyntaxKind2[SyntaxKind2["StringLiteral"] = 10] = "StringLiteral";
|
|
28526
|
+
SyntaxKind2[SyntaxKind2["NumericLiteral"] = 11] = "NumericLiteral";
|
|
28527
|
+
SyntaxKind2[SyntaxKind2["LineCommentTrivia"] = 12] = "LineCommentTrivia";
|
|
28528
|
+
SyntaxKind2[SyntaxKind2["BlockCommentTrivia"] = 13] = "BlockCommentTrivia";
|
|
28529
|
+
SyntaxKind2[SyntaxKind2["LineBreakTrivia"] = 14] = "LineBreakTrivia";
|
|
28530
|
+
SyntaxKind2[SyntaxKind2["Trivia"] = 15] = "Trivia";
|
|
28531
|
+
SyntaxKind2[SyntaxKind2["Unknown"] = 16] = "Unknown";
|
|
28532
|
+
SyntaxKind2[SyntaxKind2["EOF"] = 17] = "EOF";
|
|
28533
|
+
})(SyntaxKind || (SyntaxKind = {}));
|
|
28534
|
+
var ParseErrorCode;
|
|
28535
|
+
(function(ParseErrorCode2) {
|
|
28536
|
+
ParseErrorCode2[ParseErrorCode2["InvalidSymbol"] = 1] = "InvalidSymbol";
|
|
28537
|
+
ParseErrorCode2[ParseErrorCode2["InvalidNumberFormat"] = 2] = "InvalidNumberFormat";
|
|
28538
|
+
ParseErrorCode2[ParseErrorCode2["PropertyNameExpected"] = 3] = "PropertyNameExpected";
|
|
28539
|
+
ParseErrorCode2[ParseErrorCode2["ValueExpected"] = 4] = "ValueExpected";
|
|
28540
|
+
ParseErrorCode2[ParseErrorCode2["ColonExpected"] = 5] = "ColonExpected";
|
|
28541
|
+
ParseErrorCode2[ParseErrorCode2["CommaExpected"] = 6] = "CommaExpected";
|
|
28542
|
+
ParseErrorCode2[ParseErrorCode2["CloseBraceExpected"] = 7] = "CloseBraceExpected";
|
|
28543
|
+
ParseErrorCode2[ParseErrorCode2["CloseBracketExpected"] = 8] = "CloseBracketExpected";
|
|
28544
|
+
ParseErrorCode2[ParseErrorCode2["EndOfFileExpected"] = 9] = "EndOfFileExpected";
|
|
28545
|
+
ParseErrorCode2[ParseErrorCode2["InvalidCommentToken"] = 10] = "InvalidCommentToken";
|
|
28546
|
+
ParseErrorCode2[ParseErrorCode2["UnexpectedEndOfComment"] = 11] = "UnexpectedEndOfComment";
|
|
28547
|
+
ParseErrorCode2[ParseErrorCode2["UnexpectedEndOfString"] = 12] = "UnexpectedEndOfString";
|
|
28548
|
+
ParseErrorCode2[ParseErrorCode2["UnexpectedEndOfNumber"] = 13] = "UnexpectedEndOfNumber";
|
|
28549
|
+
ParseErrorCode2[ParseErrorCode2["InvalidUnicode"] = 14] = "InvalidUnicode";
|
|
28550
|
+
ParseErrorCode2[ParseErrorCode2["InvalidEscapeCharacter"] = 15] = "InvalidEscapeCharacter";
|
|
28551
|
+
ParseErrorCode2[ParseErrorCode2["InvalidCharacter"] = 16] = "InvalidCharacter";
|
|
28552
|
+
})(ParseErrorCode || (ParseErrorCode = {}));
|
|
28553
|
+
|
|
28554
|
+
// src/guest/toolchains/vscode.ts
|
|
27847
28555
|
var VERSION_MARKER = ".agent-sandbox-version";
|
|
27848
28556
|
var desktopShortcut = (exe) => {
|
|
27849
28557
|
if (!isWin) return;
|
|
27850
|
-
const link =
|
|
28558
|
+
const link = path43.join(os7.homedir(), "Desktop", "Visual Studio Code.lnk");
|
|
27851
28559
|
const q = (s) => "'" + s.replace(/'/g, "''") + "'";
|
|
27852
28560
|
powershell("$s = (New-Object -ComObject WScript.Shell).CreateShortcut(" + q(link) + "); $s.TargetPath = " + q(exe) + "; $s.Arguments = " + q('"' + (process.env.AGENT_WORKSPACE ?? "") + '"') + "; $s.Save()");
|
|
27853
28561
|
};
|
|
27854
28562
|
var setupVscode = async (env, refresh) => {
|
|
27855
28563
|
const root = tool("vscode");
|
|
27856
|
-
const exe =
|
|
28564
|
+
const exe = path43.join(root, "Code.exe");
|
|
27857
28565
|
if (dryRun) {
|
|
27858
28566
|
log("(dry run) would provision VS Code");
|
|
27859
28567
|
return;
|
|
@@ -27861,27 +28569,27 @@ var setupVscode = async (env, refresh) => {
|
|
|
27861
28569
|
if (!exists(exe) || refresh) {
|
|
27862
28570
|
const release = await fetchJson("https://update.code.visualstudio.com/api/update/win32-" + (arch === "arm64" ? "arm64" : "x64") + "-archive/stable/latest");
|
|
27863
28571
|
log("Downloading VS Code " + release.productVersion + " (~150 MB once) ...");
|
|
27864
|
-
const keep =
|
|
28572
|
+
const keep = path43.join(root, "data");
|
|
27865
28573
|
const parked = root + "-data";
|
|
27866
28574
|
if (exists(keep)) {
|
|
27867
|
-
|
|
27868
|
-
|
|
28575
|
+
fs30.rmSync(parked, { recursive: true, force: true });
|
|
28576
|
+
fs30.renameSync(keep, parked);
|
|
27869
28577
|
}
|
|
27870
28578
|
try {
|
|
27871
28579
|
await installArchive(release.url, root, { sha256: release.sha256hash, locate: "Code.exe", fileName: "vscode.zip" });
|
|
27872
|
-
|
|
28580
|
+
fs30.writeFileSync(path43.join(root, VERSION_MARKER), release.productVersion);
|
|
27873
28581
|
} finally {
|
|
27874
28582
|
if (exists(parked)) {
|
|
27875
28583
|
mkdirp(root);
|
|
27876
|
-
|
|
27877
|
-
|
|
28584
|
+
fs30.rmSync(keep, { recursive: true, force: true });
|
|
28585
|
+
fs30.renameSync(parked, keep);
|
|
27878
28586
|
}
|
|
27879
28587
|
}
|
|
27880
28588
|
}
|
|
27881
|
-
mkdirp(
|
|
27882
|
-
env.prepend.push(
|
|
28589
|
+
mkdirp(path43.join(root, "data"));
|
|
28590
|
+
env.prepend.push(path43.join(root, "bin"));
|
|
27883
28591
|
desktopShortcut(exe);
|
|
27884
|
-
const version2 = exists(
|
|
28592
|
+
const version2 = exists(path43.join(root, VERSION_MARKER)) ? fs30.readFileSync(path43.join(root, VERSION_MARKER), "utf8").trim() : "installed";
|
|
27885
28593
|
env.summary.push("vscode: " + version2 + " (portable; run code . or use the desktop shortcut)");
|
|
27886
28594
|
};
|
|
27887
28595
|
|
|
@@ -27892,14 +28600,34 @@ var setupPythonTools = async (env, tools) => {
|
|
|
27892
28600
|
await installOnce(env, "uv tool", tools, (pkg) => execAsync(uv, ["tool", "install", pkg], { env: { ...process.env, ...uvVars() } }));
|
|
27893
28601
|
};
|
|
27894
28602
|
var cargoTarget = (targetDir) => {
|
|
27895
|
-
if (targetDir === "shared") return null;
|
|
27896
|
-
if (targetDir === "
|
|
27897
|
-
if (targetDir === "local") return path43.join(localDir, "cargo-target");
|
|
28603
|
+
if (targetDir === "shared" || targetDir === "separate") return null;
|
|
28604
|
+
if (targetDir === "local") return path44.join(localDir, "cargo-target");
|
|
27898
28605
|
return targetDir;
|
|
27899
28606
|
};
|
|
28607
|
+
var cargoShim = (env, rust) => {
|
|
28608
|
+
const real = path44.join(tool("rust", "cargo", "bin"), "cargo.exe");
|
|
28609
|
+
if (rust.targetDir !== "separate" || !exists(real)) return;
|
|
28610
|
+
const dir = mkdirp(tool("shims", "cargo"));
|
|
28611
|
+
fs31.copyFileSync(ensureCompiled("cargoshim"), path44.join(dir, "cargo.exe"));
|
|
28612
|
+
env.prepend.unshift(dir);
|
|
28613
|
+
env.vars.AGENT_REAL_CARGO = real;
|
|
28614
|
+
};
|
|
28615
|
+
var cargoDefaults = (host) => {
|
|
28616
|
+
const file3 = tool("rust", "cargo", "config.toml");
|
|
28617
|
+
if (exists(file3) || !exists(path44.dirname(file3))) return;
|
|
28618
|
+
const jobs = Math.max(2, Math.min(4, Math.floor(os8.cpus().length / 4)));
|
|
28619
|
+
const gnu = host.endsWith("-gnu");
|
|
28620
|
+
fs31.writeFileSync(file3, [
|
|
28621
|
+
"# Written by windows-development-sandbox once; edit freely, it is never overwritten.",
|
|
28622
|
+
"[build]",
|
|
28623
|
+
"jobs = " + jobs,
|
|
28624
|
+
"",
|
|
28625
|
+
...gnu ? ["[profile.dev]", 'debug = "line-tables-only"', "", "[profile.test]", 'debug = "line-tables-only"', ""] : []
|
|
28626
|
+
].join("\n"));
|
|
28627
|
+
};
|
|
27900
28628
|
var rustCaches = (rust) => {
|
|
27901
28629
|
const target = cargoTarget(rust.targetDir);
|
|
27902
|
-
return { ...target ? { CARGO_TARGET_DIR: target } : {}, ...process.env.SCCACHE_DIR ? {} : { SCCACHE_DIR:
|
|
28630
|
+
return { ...target ? { CARGO_TARGET_DIR: target } : {}, ...process.env.SCCACHE_DIR ? {} : { SCCACHE_DIR: path44.join(dataDir, "cache", "sccache") } };
|
|
27903
28631
|
};
|
|
27904
28632
|
var rustHost = (config2) => {
|
|
27905
28633
|
if (config2.rust.host !== "auto") return config2.rust.host;
|
|
@@ -27907,6 +28635,7 @@ var rustHost = (config2) => {
|
|
|
27907
28635
|
return cpu + (wanted(config2.msvc.enabled, "msvc") ? "-pc-windows-msvc" : "-pc-windows-gnu");
|
|
27908
28636
|
};
|
|
27909
28637
|
var plan = (config2, versions, o) => {
|
|
28638
|
+
const apps = Boolean(o.apps && (o.apps.install.length || Object.keys(o.apps.custom).length));
|
|
27910
28639
|
const java = wanted(config2.java.enabled, "java");
|
|
27911
28640
|
const python = wanted(config2.python.enabled, "python");
|
|
27912
28641
|
return [
|
|
@@ -27926,6 +28655,10 @@ var plan = (config2, versions, o) => {
|
|
|
27926
28655
|
run: async (env) => {
|
|
27927
28656
|
await setupRust(env, { ...config2.rust, host: rustHost(config2) }, o.refresh);
|
|
27928
28657
|
Object.assign(env.vars, rustCaches(config2.rust));
|
|
28658
|
+
if (!dryRun) {
|
|
28659
|
+
cargoDefaults(rustHost(config2));
|
|
28660
|
+
cargoShim(env, config2.rust);
|
|
28661
|
+
}
|
|
27929
28662
|
}
|
|
27930
28663
|
},
|
|
27931
28664
|
{ name: ".NET", on: wanted(config2.dotnet.enabled, "dotnet"), run: (env) => setupDotnet(env, config2.dotnet, o.refresh) },
|
|
@@ -27933,7 +28666,8 @@ var plan = (config2, versions, o) => {
|
|
|
27933
28666
|
{ name: "Java", on: java, run: (env) => setupJava(env, config2.java) },
|
|
27934
28667
|
{ name: "Ruby", on: wanted(config2.ruby.enabled, "ruby"), run: (env) => setupRuby(env, config2.ruby) },
|
|
27935
28668
|
// PHP installs the Visual C++ runtime itself: one installer at a time.
|
|
27936
|
-
|
|
28669
|
+
// Many apps (bat, delta, Neovim, most GUIs, your own programs) are built against it too.
|
|
28670
|
+
{ name: "Visual C++ runtime", on: config2.vcRuntime.enabled || apps, shared: true, run: async (env) => {
|
|
27937
28671
|
await setupVcRuntime(env);
|
|
27938
28672
|
} },
|
|
27939
28673
|
{ name: "PHP", on: wanted(config2.php.enabled, "php"), after: ["Visual C++ runtime"], run: (env) => setupPhp(env, config2.php) },
|
|
@@ -27943,8 +28677,10 @@ var plan = (config2, versions, o) => {
|
|
|
27943
28677
|
{ name: "PowerShell 7", on: wanted(config2.pwsh.enabled, "pwsh"), run: (env) => setupPwsh(env, o.refresh) },
|
|
27944
28678
|
// The openssl tool comes from Git's install: after Git.
|
|
27945
28679
|
{ 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) },
|
|
28680
|
+
{ name: "Mesa 3D", on: config2.mesa.enabled || appsNeedMesa(o.apps), shared: true, run: (env) => setupMesa(env, config2.mesa) },
|
|
27947
28681
|
{ name: "VS Code", on: config2.vscode.enabled, shared: true, run: (env) => setupVscode(env, o.refresh) },
|
|
28682
|
+
// Desktop apps and extra tools (apps.install / apps.custom); games and 3D apps copy Mesa's OpenGL next to them.
|
|
28683
|
+
{ 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
28684
|
{ name: "Python tools", on: python && config2.python.tools.length > 0, after: ["Python", "uv"], run: (env) => setupPythonTools(env, config2.python.tools) },
|
|
27949
28685
|
// DynamoDB Local runs on Java: the Java step installs the JDK first instead of racing it.
|
|
27950
28686
|
// One server per database in the sandbox: a project that joins later shares the one the boot started.
|
|
@@ -27953,7 +28689,8 @@ var plan = (config2, versions, o) => {
|
|
|
27953
28689
|
};
|
|
27954
28690
|
|
|
27955
28691
|
// src/guest/toolchains/index.ts
|
|
27956
|
-
var
|
|
28692
|
+
var PARALLEL2 = 4;
|
|
28693
|
+
var currentStep = new AsyncLocalStorage2();
|
|
27957
28694
|
var locks = /* @__PURE__ */ new Map();
|
|
27958
28695
|
var lockKey = (name) => name.split(" ")[0].toLowerCase();
|
|
27959
28696
|
var exclusive = async (name, work) => {
|
|
@@ -27979,10 +28716,19 @@ var runSteps = async (steps, o) => {
|
|
|
27979
28716
|
const running = /* @__PURE__ */ new Set();
|
|
27980
28717
|
const waiting = [];
|
|
27981
28718
|
let done = 0;
|
|
27982
|
-
const
|
|
28719
|
+
const percent = /* @__PURE__ */ new Map();
|
|
28720
|
+
const active = () => [...running].map((name) => ({ name, ...percent.has(name) ? { percent: percent.get(name) } : {} }));
|
|
28721
|
+
const say = o.report ?? ((message) => setSandboxStatus("provisioning", message, { active: active(), done, total: steps.length }));
|
|
27983
28722
|
const report = () => {
|
|
27984
28723
|
if (running.size) say("Installing " + [...running].join(", ") + " (" + done + " of " + steps.length + " done)");
|
|
27985
28724
|
};
|
|
28725
|
+
if (!o.report) watchDownloads(() => {
|
|
28726
|
+
const name = currentStep.getStore();
|
|
28727
|
+
return name ? (fraction) => {
|
|
28728
|
+
percent.set(name, Math.round(fraction * 100));
|
|
28729
|
+
report();
|
|
28730
|
+
} : null;
|
|
28731
|
+
});
|
|
27986
28732
|
for (const s of steps) {
|
|
27987
28733
|
finished.set(s.name, (async () => {
|
|
27988
28734
|
await Promise.all((s.after ?? []).map((name) => finished.get(name)));
|
|
@@ -27992,20 +28738,26 @@ var runSteps = async (steps, o) => {
|
|
|
27992
28738
|
done++;
|
|
27993
28739
|
return;
|
|
27994
28740
|
}
|
|
27995
|
-
while (running.size >=
|
|
28741
|
+
while (running.size >= PARALLEL2) await new Promise((r) => waiting.push(r));
|
|
27996
28742
|
running.add(s.name);
|
|
27997
28743
|
report();
|
|
27998
28744
|
try {
|
|
27999
|
-
await exclusive(s.name, () => step(s.name, envs.get(s.name), async () => s.run(envs.get(s.name))));
|
|
28745
|
+
await currentStep.run(s.name, () => exclusive(s.name, () => step(s.name, envs.get(s.name), async () => s.run(envs.get(s.name)))));
|
|
28000
28746
|
} finally {
|
|
28001
28747
|
running.delete(s.name);
|
|
28748
|
+
percent.delete(s.name);
|
|
28002
28749
|
done++;
|
|
28003
28750
|
report();
|
|
28004
28751
|
waiting.shift()?.();
|
|
28005
28752
|
}
|
|
28006
28753
|
})());
|
|
28007
28754
|
}
|
|
28008
|
-
|
|
28755
|
+
try {
|
|
28756
|
+
await Promise.all(finished.values());
|
|
28757
|
+
} finally {
|
|
28758
|
+
if (!o.report) watchDownloads(null);
|
|
28759
|
+
}
|
|
28760
|
+
if (!o.report) setSandboxStatus("provisioning", "Set up " + steps.length + " toolchains and databases", { active: [], done, total: steps.length });
|
|
28009
28761
|
return envs;
|
|
28010
28762
|
};
|
|
28011
28763
|
var setupToolchains = async (config2, versions, options, run2 = {}) => {
|
|
@@ -28031,14 +28783,14 @@ var provisionedFor = (cwd) => [...ready.values()].filter((p) => isWithin(p.spec.
|
|
|
28031
28783
|
var provisionedProjects = () => [...ready.values()];
|
|
28032
28784
|
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
28785
|
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 ""' +
|
|
28786
|
+
const dir = mkdirp(path45.join(localDir, "projects", spec.name));
|
|
28787
|
+
fs32.writeFileSync(path45.join(dir, "env.cmd"), [...cmdSet(env, [...names, "PATH"]), ""].join("\r\n"));
|
|
28788
|
+
fs32.writeFileSync(path45.join(dir, "shell.cmd"), ['@call "' + path45.join(dir, "env.cmd") + '"', '@cd /d "' + spec.workspace + '"', "@title " + spec.name, ""].join("\r\n"));
|
|
28789
|
+
const bin = mkdirp(path45.join(localDir, "bin"));
|
|
28790
|
+
fs32.writeFileSync(path45.join(bin, "sbx-shell.cmd"), [
|
|
28791
|
+
'@if "%~1"=="" (echo Usage: sbx-shell ^<project^> ^(a terminal in that project with its tools^) & dir /b "' + path45.join(localDir, "projects") + '" & exit /b 2)',
|
|
28792
|
+
'@if not exist "' + path45.join(localDir, "projects") + '\\%~1\\shell.cmd" (echo No project %~1 in this sandbox. & exit /b 2)',
|
|
28793
|
+
'@cmd /k ""' + path45.join(localDir, "projects") + '\\%~1\\shell.cmd""',
|
|
28042
28794
|
""
|
|
28043
28795
|
].join("\r\n"));
|
|
28044
28796
|
};
|
|
@@ -28077,10 +28829,10 @@ var provision = async (spec, say) => {
|
|
|
28077
28829
|
saveProjectStatus(spec.name, spec.workspace, "provisioning", m, spec.databases, []);
|
|
28078
28830
|
say(m);
|
|
28079
28831
|
}, reuse: boot?.steps }));
|
|
28080
|
-
tools.prepend.push(
|
|
28832
|
+
tools.prepend.push(path45.join(localDir, "bin"));
|
|
28081
28833
|
const env = agentEnv(tools, { workspace: spec.workspace, project: spec.name, base });
|
|
28082
|
-
const specFile =
|
|
28083
|
-
|
|
28834
|
+
const specFile = path45.join(mkdirp(path45.join(localDir, "projects", spec.name)), "project.json");
|
|
28835
|
+
fs32.writeFileSync(specFile, JSON.stringify(spec));
|
|
28084
28836
|
env.AGENT_PROJECT_FILE = specFile;
|
|
28085
28837
|
addMachineEnvironment(tools.vars, [...tools.prepend, ...tools.append], true);
|
|
28086
28838
|
try {
|
|
@@ -28154,14 +28906,83 @@ var execCommand = (req) => {
|
|
|
28154
28906
|
});
|
|
28155
28907
|
};
|
|
28156
28908
|
|
|
28909
|
+
// src/guest/daemon/relays.ts
|
|
28910
|
+
import net2 from "node:net";
|
|
28911
|
+
|
|
28912
|
+
// src/shared/netpolicy.ts
|
|
28913
|
+
var relayPort = (index) => 38100 + index;
|
|
28914
|
+
|
|
28915
|
+
// src/guest/daemon/relays.ts
|
|
28916
|
+
var startRelays = () => {
|
|
28917
|
+
(session.network.forwardPorts ?? []).forEach((f, i) => {
|
|
28918
|
+
const server = net2.createServer((client) => {
|
|
28919
|
+
const target = net2.connect(f.sandbox, "127.0.0.1");
|
|
28920
|
+
client.pipe(target).pipe(client);
|
|
28921
|
+
target.on("error", () => client.destroy());
|
|
28922
|
+
client.on("error", () => target.destroy());
|
|
28923
|
+
});
|
|
28924
|
+
server.on("error", (e) => warn("Port forward " + f.pc + " -> " + f.sandbox + " could not start: " + errMsg(e)));
|
|
28925
|
+
server.listen(relayPort(i), "0.0.0.0", () => log("Port forward: the PC's localhost:" + f.pc + " reaches localhost:" + f.sandbox + " here."));
|
|
28926
|
+
});
|
|
28927
|
+
};
|
|
28928
|
+
|
|
28929
|
+
// src/guest/audit.ts
|
|
28930
|
+
import fs33 from "node:fs";
|
|
28931
|
+
import path47 from "node:path";
|
|
28932
|
+
import { spawnSync as spawnSync4 } from "node:child_process";
|
|
28933
|
+
|
|
28934
|
+
// src/guest/audit-parse.ts
|
|
28935
|
+
import path46 from "node:path";
|
|
28936
|
+
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"]);
|
|
28937
|
+
var decode3 = (s) => s.replace(/</g, "<").replace(/>/g, ">").replace(/"/g, '"').replace(/'/g, "'").replace(/&/g, "&");
|
|
28938
|
+
var field = (event, name) => decode3(new RegExp("<Data Name='" + name + "'>([^<]*)</Data>").exec(event)?.[1] ?? "");
|
|
28939
|
+
var parseProcessEvents = (xml) => {
|
|
28940
|
+
const lines = [];
|
|
28941
|
+
let last = 0;
|
|
28942
|
+
for (const event of xml.split("</Event>")) {
|
|
28943
|
+
const id = Number(/<EventRecordID>(\d+)<\/EventRecordID>/.exec(event)?.[1] ?? 0);
|
|
28944
|
+
if (!id) continue;
|
|
28945
|
+
last = Math.max(last, id);
|
|
28946
|
+
const program = field(event, "NewProcessName");
|
|
28947
|
+
if (!program || NOISE.has(path46.win32.basename(program).toLowerCase())) continue;
|
|
28948
|
+
const t = /SystemTime='([^']+)'/.exec(event)?.[1] ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
28949
|
+
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) }));
|
|
28950
|
+
}
|
|
28951
|
+
return { lines, last };
|
|
28952
|
+
};
|
|
28953
|
+
|
|
28954
|
+
// src/guest/audit.ts
|
|
28955
|
+
var MAX_PER_PASS = 2e3;
|
|
28956
|
+
var auditOn = () => Boolean(session.auditProcesses) && isWin && !dryRun;
|
|
28957
|
+
var wevtutil = () => path47.join(process.env.WINDIR ?? "C:\\Windows", "System32", "wevtutil.exe");
|
|
28958
|
+
var newestRecord = () => {
|
|
28959
|
+
const r = spawnSync4(wevtutil(), ["qe", "Security", "/q:*[System[(EventID=4688)]]", "/f:xml", "/c:1", "/rd:true"], { encoding: "utf8", windowsHide: true });
|
|
28960
|
+
return parseProcessEvents(r.stdout ?? "").last;
|
|
28961
|
+
};
|
|
28962
|
+
var startProcessCollector = () => {
|
|
28963
|
+
if (!auditOn()) return;
|
|
28964
|
+
let last = newestRecord();
|
|
28965
|
+
const pass = () => {
|
|
28966
|
+
try {
|
|
28967
|
+
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 });
|
|
28968
|
+
const { lines, last: newest } = parseProcessEvents(r.stdout ?? "");
|
|
28969
|
+
if (newest) last = newest;
|
|
28970
|
+
if (lines.length) fs33.writeFileSync(path47.join(mkdirp(run.audit), Date.now() + "-" + process.pid + ".jsonl"), lines.join("\n") + "\n");
|
|
28971
|
+
} catch (e) {
|
|
28972
|
+
warn("audit: " + errMsg(e));
|
|
28973
|
+
}
|
|
28974
|
+
};
|
|
28975
|
+
setInterval(pass, 15e3).unref?.();
|
|
28976
|
+
};
|
|
28977
|
+
|
|
28157
28978
|
// src/guest/daemon/session.ts
|
|
28158
|
-
import
|
|
28979
|
+
import path52 from "node:path";
|
|
28159
28980
|
import crypto3 from "node:crypto";
|
|
28160
28981
|
import { spawn as spawn7 } from "node:child_process";
|
|
28161
28982
|
|
|
28162
28983
|
// 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 };
|
|
28984
|
+
import net3 from "node:net";
|
|
28985
|
+
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
28986
|
var HelloFlag = { ControlOnly: 1, Query: 2 };
|
|
28166
28987
|
var encodeFrame = (type, payload = Buffer.alloc(0)) => {
|
|
28167
28988
|
const header = Buffer.alloc(5);
|
|
@@ -28178,8 +28999,8 @@ var helloFrame = (token, cols, rows, flags = 0) => {
|
|
|
28178
28999
|
};
|
|
28179
29000
|
var MAX_FRAME_BYTES = 1 << 20;
|
|
28180
29001
|
var connectOnce = (host, port, timeoutMs) => {
|
|
28181
|
-
return new Promise((
|
|
28182
|
-
const socket =
|
|
29002
|
+
return new Promise((resolve2, reject) => {
|
|
29003
|
+
const socket = net3.connect({ host, port });
|
|
28183
29004
|
const timer = setTimeout(() => {
|
|
28184
29005
|
socket.destroy();
|
|
28185
29006
|
reject(new Error("timed out connecting to " + host + ":" + port));
|
|
@@ -28187,7 +29008,7 @@ var connectOnce = (host, port, timeoutMs) => {
|
|
|
28187
29008
|
socket.once("connect", () => {
|
|
28188
29009
|
clearTimeout(timer);
|
|
28189
29010
|
socket.setNoDelay(true);
|
|
28190
|
-
|
|
29011
|
+
resolve2(socket);
|
|
28191
29012
|
});
|
|
28192
29013
|
socket.once("error", (e) => {
|
|
28193
29014
|
clearTimeout(timer);
|
|
@@ -28208,11 +29029,11 @@ var connect = async (endpoint, timeoutMs = 3e3) => {
|
|
|
28208
29029
|
};
|
|
28209
29030
|
var sendControl = async (endpoint, type) => {
|
|
28210
29031
|
const socket = await connect(endpoint);
|
|
28211
|
-
await new Promise((
|
|
29032
|
+
await new Promise((resolve2) => socket.end(Buffer.concat([helloFrame(endpoint.token, 80, 24, HelloFlag.ControlOnly), encodeFrame(type)]), resolve2));
|
|
28212
29033
|
};
|
|
28213
29034
|
|
|
28214
29035
|
// src/guest/cmdline.ts
|
|
28215
|
-
import
|
|
29036
|
+
import path48 from "node:path";
|
|
28216
29037
|
var quoted = (arg) => '"' + arg.replace(/(\\*)"/g, '$1$1\\"').replace(/(\\+)$/, "$1$1") + '"';
|
|
28217
29038
|
var quoteArg = (arg) => arg !== "" && !/[\s"]/.test(arg) ? arg : quoted(arg);
|
|
28218
29039
|
var cmdArgs = (args) => {
|
|
@@ -28223,11 +29044,11 @@ var cmdArgs = (args) => {
|
|
|
28223
29044
|
return !inQuotes && /[&|<>^]/.test(c) ? "^^^" + c : c;
|
|
28224
29045
|
}).join("");
|
|
28225
29046
|
};
|
|
28226
|
-
var commandLine = (file3, args) =>
|
|
29047
|
+
var commandLine = (file3, args) => path48.win32.basename(file3).toLowerCase() === "cmd.exe" ? [quoteArg(file3), cmdArgs(args)].filter(Boolean).join(" ") : [file3, ...args].map(quoteArg).join(" ");
|
|
28227
29048
|
|
|
28228
29049
|
// src/guest/ptyhost.ts
|
|
28229
|
-
import
|
|
28230
|
-
import
|
|
29050
|
+
import fs34 from "node:fs";
|
|
29051
|
+
import path49 from "node:path";
|
|
28231
29052
|
import { spawn as spawn6 } from "node:child_process";
|
|
28232
29053
|
var ensurePtyHost = () => ensureCompiled("ptyhost");
|
|
28233
29054
|
var waitForPtyHost = async (child, port, timeoutMs) => {
|
|
@@ -28243,33 +29064,37 @@ var waitForPtyHost = async (child, port, timeoutMs) => {
|
|
|
28243
29064
|
}
|
|
28244
29065
|
throw new Error("the session host did not start listening on port " + port);
|
|
28245
29066
|
};
|
|
28246
|
-
var ptyHostLog = (id) =>
|
|
29067
|
+
var ptyHostLog = (id) => path49.join(logsDir, "ptyhost-" + id + ".log");
|
|
28247
29068
|
var ptyHostLogTail = (id, lines = 12) => {
|
|
28248
29069
|
try {
|
|
28249
|
-
return
|
|
29070
|
+
return fs34.readFileSync(ptyHostLog(id), "utf8").trim().split(/\r?\n/).slice(-lines).join("\n");
|
|
28250
29071
|
} catch {
|
|
28251
29072
|
return "";
|
|
28252
29073
|
}
|
|
28253
29074
|
};
|
|
28254
|
-
var
|
|
28255
|
-
|
|
28256
|
-
|
|
28257
|
-
|
|
28258
|
-
|
|
28259
|
-
|
|
28260
|
-
|
|
29075
|
+
var conptyDll = () => {
|
|
29076
|
+
const dll = path49.join(toolsDir, "conpty", "conpty.dll");
|
|
29077
|
+
return session.provisioning.conpty?.enabled !== false && fs34.existsSync(dll) && fs34.existsSync(path49.join(toolsDir, "conpty", "OpenConsole.exe")) ? dll : null;
|
|
29078
|
+
};
|
|
29079
|
+
var startPtyHost = (o) => {
|
|
29080
|
+
const env = { ...o.env, PTYHOST_BIND: o.remote ? "any" : "loopback" };
|
|
29081
|
+
delete env.PTYHOST_CONPTY;
|
|
29082
|
+
const dll = conptyDll();
|
|
29083
|
+
if (dll) env.PTYHOST_CONPTY = dll;
|
|
29084
|
+
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 });
|
|
29085
|
+
};
|
|
28261
29086
|
|
|
28262
29087
|
// src/guest/setup/agents.ts
|
|
28263
|
-
import
|
|
28264
|
-
import
|
|
29088
|
+
import fs35 from "node:fs";
|
|
29089
|
+
import path50 from "node:path";
|
|
28265
29090
|
var harnessPaths = (name, harness) => {
|
|
28266
|
-
const dir =
|
|
29091
|
+
const dir = path50.join(toolsDir, "agents", name);
|
|
28267
29092
|
const exe = harness.hostExecutable ?? (harness.uvBin ? harness.uvBin + ".exe" : null);
|
|
28268
|
-
return { dir, exe: exe ?
|
|
29093
|
+
return { dir, exe: exe ? path50.join(dir, exe) : null, cmd: harness.npmBin ? path50.join(dir, harness.npmBin + ".cmd") : null };
|
|
28269
29094
|
};
|
|
28270
29095
|
var installViaNpm = async (name, harness, dir, env) => {
|
|
28271
29096
|
if (!harness.npmPackage) throw new Error("No npmPackage configured for " + name + " and no host executable was available.");
|
|
28272
|
-
const npmCli =
|
|
29097
|
+
const npmCli = path50.join(path50.dirname(process.execPath), "node_modules", "npm", "bin", "npm-cli.js");
|
|
28273
29098
|
const args = [npmCli, "install", "--global", "--prefix", dir, harness.npmPackage, "--no-fund", "--no-audit"];
|
|
28274
29099
|
log("Installing " + harness.npmPackage + " (this can take a minute)...");
|
|
28275
29100
|
if (dryRun) {
|
|
@@ -28280,7 +29105,7 @@ var installViaNpm = async (name, harness, dir, env) => {
|
|
|
28280
29105
|
await execAsync(process.execPath, args, { env });
|
|
28281
29106
|
};
|
|
28282
29107
|
var installViaUv = async (name, harness, dir, env) => {
|
|
28283
|
-
const uv =
|
|
29108
|
+
const uv = path50.join(toolsDir, "uv", "uv.exe");
|
|
28284
29109
|
log("Installing " + harness.uvPackage + " with uv (this can take a minute)...");
|
|
28285
29110
|
if (dryRun) {
|
|
28286
29111
|
log("(dry run) uv tool install " + harness.uvPackage);
|
|
@@ -28306,9 +29131,9 @@ var installHarness = async (name, harness, env, refresh) => {
|
|
|
28306
29131
|
}
|
|
28307
29132
|
mkdirp(p.dir);
|
|
28308
29133
|
if (session.provisioning.copyFromHost && harness.hostExecutable && name === session.harnessName) {
|
|
28309
|
-
const source =
|
|
29134
|
+
const source = path50.join(hostToolsDir, "agents", name, harness.hostExecutable);
|
|
28310
29135
|
if (exists(source) && p.exe) {
|
|
28311
|
-
|
|
29136
|
+
fs35.copyFileSync(source, p.exe);
|
|
28312
29137
|
log("Copied " + name + " from this PC: " + source);
|
|
28313
29138
|
return;
|
|
28314
29139
|
}
|
|
@@ -28327,11 +29152,13 @@ var resolveLaunch = (name, harness) => {
|
|
|
28327
29152
|
};
|
|
28328
29153
|
|
|
28329
29154
|
// src/guest/setup/network.ts
|
|
28330
|
-
import
|
|
28331
|
-
|
|
29155
|
+
import os9 from "node:os";
|
|
29156
|
+
import path51 from "node:path";
|
|
29157
|
+
var HOSTS_FILE = path51.join(process.env.WINDIR ?? "C:\\Windows", "System32", "drivers", "etc", "hosts");
|
|
29158
|
+
var guestAddresses = () => Object.values(os9.networkInterfaces()).flat().filter((i) => Boolean(i) && i.family === "IPv4" && !i.internal).map((i) => i.address);
|
|
28332
29159
|
|
|
28333
29160
|
// src/guest/daemon/shutdown.ts
|
|
28334
|
-
import { spawnSync as
|
|
29161
|
+
import { spawnSync as spawnSync5 } from "node:child_process";
|
|
28335
29162
|
var maybeShutdown = () => {
|
|
28336
29163
|
if (!session.headless || !isWin) return;
|
|
28337
29164
|
const idle = () => live.size === 0 && pending.starting === 0 && scanRequests(dataDir).valid.length === 0;
|
|
@@ -28340,14 +29167,14 @@ var maybeShutdown = () => {
|
|
|
28340
29167
|
if (!idle()) return;
|
|
28341
29168
|
log("Headless sandbox has no sessions left; shutting down.");
|
|
28342
29169
|
safely("claude-mem save", saveClaudeMem);
|
|
28343
|
-
|
|
29170
|
+
spawnSync5(SYSTEM.shutdown(), ["/s", "/t", "5"], { windowsHide: true });
|
|
28344
29171
|
}, 15e3);
|
|
28345
29172
|
};
|
|
28346
29173
|
|
|
28347
29174
|
// src/guest/daemon/session.ts
|
|
28348
29175
|
var terminalTab = (id, title, cwd) => {
|
|
28349
|
-
const view = [process.execPath,
|
|
28350
|
-
const wt =
|
|
29176
|
+
const view = [process.execPath, path52.join(path52.dirname(process.argv[1]), "view.js"), id];
|
|
29177
|
+
const wt = path52.join(toolsDir, "terminal", "wt.exe");
|
|
28351
29178
|
if (exists(wt)) spawn7(wt, ["-w", "0", "nt", "--title", title, "-d", cwd, ...view], { detached: true, stdio: "ignore" }).unref();
|
|
28352
29179
|
else spawn7(SYSTEM.cmd(), ["/d", "/c", "start", title, ...view], { detached: true, stdio: "ignore", cwd }).unref();
|
|
28353
29180
|
};
|
|
@@ -28392,7 +29219,7 @@ var launchPtyHost = async (req, remote, env, say) => {
|
|
|
28392
29219
|
await waitForPtyHost(child, port, 15e3);
|
|
28393
29220
|
} catch (e) {
|
|
28394
29221
|
const tail = ptyHostLogTail(req.id);
|
|
28395
|
-
throw new Error(errMsg(e) + (tail ? ". From its log:\n" + tail : "") + "\nLog: " +
|
|
29222
|
+
throw new Error(errMsg(e) + (tail ? ". From its log:\n" + tail : "") + "\nLog: " + path52.join(dataDir, "logs", "ptyhost-" + req.id + ".log"));
|
|
28396
29223
|
}
|
|
28397
29224
|
return { child, port, token };
|
|
28398
29225
|
};
|
|
@@ -28414,7 +29241,7 @@ var startSession = async (req) => {
|
|
|
28414
29241
|
saveStatus(status);
|
|
28415
29242
|
};
|
|
28416
29243
|
pending.starting++;
|
|
28417
|
-
if (req.id !== session.launchId && process.env.AGENT_NO_TABS !== "1") safely("terminal tab", () => terminalTab(req.id, req.harness + " " +
|
|
29244
|
+
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
29245
|
try {
|
|
28419
29246
|
const place = await placeFor(req, say);
|
|
28420
29247
|
const remote = session.networking && session.attach.enabled;
|
|
@@ -28470,9 +29297,9 @@ var handle = (req) => {
|
|
|
28470
29297
|
};
|
|
28471
29298
|
var tick = () => {
|
|
28472
29299
|
const { valid, invalid } = scanRequests(dataDir);
|
|
28473
|
-
for (const file3 of invalid) safely("removing an invalid request", () =>
|
|
29300
|
+
for (const file3 of invalid) safely("removing an invalid request", () => fs36.rmSync(file3, { recursive: true, force: true }));
|
|
28474
29301
|
for (const req of valid) {
|
|
28475
|
-
safely("claiming a request", () =>
|
|
29302
|
+
safely("claiming a request", () => fs36.rmSync(run.request(req.id), { force: true }));
|
|
28476
29303
|
if (readSession(dataDir, req.id)) continue;
|
|
28477
29304
|
void Promise.resolve(handle(req)).catch((e) => respond(req.id, { ok: false, message: errMsg(e) }));
|
|
28478
29305
|
}
|
|
@@ -28491,4 +29318,6 @@ var loop = () => {
|
|
|
28491
29318
|
}
|
|
28492
29319
|
};
|
|
28493
29320
|
log("Session daemon started (pid " + process.pid + ").");
|
|
29321
|
+
safely("port forwards", startRelays);
|
|
29322
|
+
safely("audit", startProcessCollector);
|
|
28494
29323
|
loop();
|