windows-development-sandbox 1.17.3 → 1.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/config.example.json +97 -4
- package/dist/app/features/accounts/accounts.def.d.ts +116 -2
- package/dist/app/features/accounts/accounts.def.js +80 -12
- package/dist/app/features/accounts/accounts.run.d.ts +29 -0
- package/dist/app/features/accounts/accounts.run.js +36 -6
- package/dist/app/features/accounts/index.d.ts +2 -0
- package/dist/app/features/accounts/index.js +4 -1
- package/dist/app/features/accounts/services.def.d.ts +111 -0
- package/dist/app/features/accounts/services.def.js +187 -0
- package/dist/app/features/accounts/services.run.d.ts +65 -0
- package/dist/app/features/accounts/services.run.js +212 -0
- package/dist/app/features/defs.d.ts +112 -1
- package/dist/app/features/defs.js +5 -0
- package/dist/app/features/settings/categories.def.js +21 -4
- package/dist/app/registry.js +5 -1
- package/dist/bin/agent-sandbox.js +2 -2
- package/dist/bin/{chunk-QLGGAG3D.js → chunk-BKF43GJ3.js} +51 -16
- package/dist/bin/{chunk-REE3EMHD.js → chunk-YD3A67RS.js} +3812 -1702
- package/dist/bin/{chunk-XYUVIVJT.js → chunk-Z5D32FN3.js} +1 -1
- package/dist/bin/claude-host.js +2 -2
- package/dist/bin/claude-sbx.js +2 -2
- package/dist/bin/codex-sbx.js +2 -2
- package/dist/bin/gemini-sbx.js +2 -2
- package/dist/bin/sandbox.js +2 -2
- package/dist/bin/sbx-hide.js +2 -2
- package/dist/bin/sbx-show.js +2 -2
- package/dist/cli/commands/launch/launch.js +30 -1
- package/dist/cli/manifest.d.ts +93 -65
- package/dist/cli/manifest.js +23 -5
- package/dist/cli/menu/pages/accounts-page.js +31 -16
- package/dist/cli/services/accounts-service.d.ts +14 -4
- package/dist/cli/services/accounts-service.js +19 -6
- package/dist/cli/services/data-collect.js +26 -1
- package/dist/core/config/defaults.js +47 -4
- package/dist/core/detect/toolchains.d.ts +15 -1
- package/dist/core/detect/toolchains.js +45 -12
- package/dist/core/local-config/overrides.js +6 -0
- package/dist/core/schema/accounts.d.ts +27 -0
- package/dist/core/schema/accounts.js +32 -0
- package/dist/core/schema/config.d.ts +239 -0
- package/dist/core/schema/config.js +6 -0
- package/dist/core/schema/pc-installs.d.ts +7 -0
- package/dist/core/schema/pc-installs.js +17 -0
- package/dist/core/schema/toolchains.d.ts +61 -0
- package/dist/core/schema/toolchains.js +106 -0
- package/dist/core/types.d.ts +18 -0
- package/dist/guest/accounts/adapter.d.ts +25 -0
- package/dist/guest/accounts/adapter.js +21 -0
- package/dist/guest/accounts/adapters.d.ts +5 -0
- package/dist/guest/accounts/adapters.js +18 -0
- package/dist/guest/accounts/apply.d.ts +41 -0
- package/dist/guest/accounts/apply.js +47 -0
- package/dist/guest/accounts/kinds/appstore.d.ts +2 -0
- package/dist/guest/accounts/kinds/appstore.js +7 -0
- package/dist/guest/accounts/kinds/cfx.d.ts +2 -0
- package/dist/guest/accounts/kinds/cfx.js +7 -0
- package/dist/guest/accounts/kinds/epic.d.ts +2 -0
- package/dist/guest/accounts/kinds/epic.js +26 -0
- package/dist/guest/accounts/kinds/expo.d.ts +2 -0
- package/dist/guest/accounts/kinds/expo.js +7 -0
- package/dist/guest/accounts/kinds/keystore.d.ts +2 -0
- package/dist/guest/accounts/kinds/keystore.js +7 -0
- package/dist/guest/accounts/kinds/play.d.ts +2 -0
- package/dist/guest/accounts/kinds/play.js +7 -0
- package/dist/guest/accounts/kinds/steam.d.ts +4 -0
- package/dist/guest/accounts/kinds/steam.js +17 -0
- package/dist/guest/accounts/kinds/unity.d.ts +2 -0
- package/dist/guest/accounts/kinds/unity.js +7 -0
- package/dist/guest/accounts/watch.d.ts +28 -0
- package/dist/guest/accounts/watch.js +78 -0
- package/dist/guest/apps/resolvers-gamedev.d.ts +2 -0
- package/dist/guest/apps/resolvers-gamedev.js +1 -0
- package/dist/guest/apps/resolvers-mobile.d.ts +2 -0
- package/dist/guest/apps/resolvers-mobile.js +1 -0
- package/dist/guest/apps/resolvers.js +4 -0
- package/dist/guest/boot/boot.d.ts +5 -0
- package/dist/guest/boot/boot.js +35 -1
- package/dist/guest/daemon/accounts.d.ts +3 -0
- package/dist/guest/daemon/accounts.js +25 -0
- package/dist/guest/daemon/daemon.js +2 -0
- package/dist/guest/daemon/idle-shutdown.js +3 -1
- package/dist/guest/daemon/sessions.js +2 -0
- package/dist/guest/devtools/android.d.ts +2 -0
- package/dist/guest/devtools/android.js +7 -0
- package/dist/guest/devtools/devtool.d.ts +9 -0
- package/dist/guest/devtools/devtool.js +5 -0
- package/dist/guest/devtools/fivem.d.ts +2 -0
- package/dist/guest/devtools/fivem.js +7 -0
- package/dist/guest/devtools/registry.d.ts +6 -0
- package/dist/guest/devtools/registry.js +12 -0
- package/dist/guest/devtools/steam.d.ts +2 -0
- package/dist/guest/devtools/steam.js +228 -0
- package/dist/guest/devtools/unity.d.ts +2 -0
- package/dist/guest/devtools/unity.js +7 -0
- package/dist/guest/entries/daemon.js +2 -0
- package/dist/guest/entries/tool.d.ts +1 -0
- package/dist/guest/entries/tool.js +17 -0
- package/dist/guest/toolchains/engines/godot.d.ts +4 -0
- package/dist/guest/toolchains/engines/godot.js +4 -0
- package/dist/guest/toolchains/engines/unity-release.d.ts +15 -0
- package/dist/guest/toolchains/engines/unity-release.js +6 -0
- package/dist/guest/toolchains/engines/unity.d.ts +4 -0
- package/dist/guest/toolchains/engines/unity.js +4 -0
- package/dist/guest/toolchains/engines/unreal-engines.d.ts +4 -0
- package/dist/guest/toolchains/engines/unreal-engines.js +4 -0
- package/dist/guest/toolchains/fivem/artifacts.d.ts +6 -0
- package/dist/guest/toolchains/fivem/artifacts.js +7 -0
- package/dist/guest/toolchains/fivem/fivem.d.ts +4 -0
- package/dist/guest/toolchains/fivem/fivem.js +4 -0
- package/dist/guest/toolchains/installers.d.ts +12 -0
- package/dist/guest/toolchains/installers.js +39 -0
- package/dist/guest/toolchains/languages/java.js +1 -1
- package/dist/guest/toolchains/languages/kotlin.d.ts +3 -0
- package/dist/guest/toolchains/languages/kotlin.js +6 -0
- package/dist/guest/toolchains/mobile/android-repo.d.ts +11 -0
- package/dist/guest/toolchains/mobile/android-repo.js +10 -0
- package/dist/guest/toolchains/mobile/android.d.ts +17 -0
- package/dist/guest/toolchains/mobile/android.js +16 -0
- package/dist/guest/toolchains/mobile/dart.d.ts +4 -0
- package/dist/guest/toolchains/mobile/dart.js +4 -0
- package/dist/guest/toolchains/mobile/flutter.d.ts +4 -0
- package/dist/guest/toolchains/mobile/flutter.js +4 -0
- package/dist/guest/toolchains/mobile/react-native.d.ts +4 -0
- package/dist/guest/toolchains/mobile/react-native.js +4 -0
- package/dist/guest/toolchains/native/unreal.d.ts +3 -7
- package/dist/guest/toolchains/native/unreal.js +16 -167
- package/dist/guest/toolchains/native/visual-studio.d.ts +15 -0
- package/dist/guest/toolchains/native/visual-studio.js +159 -0
- package/dist/guest/toolchains/native/vs-request.d.ts +19 -0
- package/dist/guest/toolchains/native/vs-request.js +46 -0
- package/dist/guest/toolchains/not-yet.d.ts +2 -0
- package/dist/guest/toolchains/not-yet.js +6 -0
- package/dist/guest/toolchains/persisted.d.ts +48 -0
- package/dist/guest/toolchains/persisted.js +159 -0
- package/dist/guest/toolchains/plan.js +80 -4
- package/dist/guest/toolchains/steam/apps.d.ts +27 -0
- package/dist/guest/toolchains/steam/apps.js +112 -0
- package/dist/guest/toolchains/steam/client.d.ts +5 -0
- package/dist/guest/toolchains/steam/client.js +67 -0
- package/dist/guest/toolchains/steam/commands.d.ts +58 -0
- package/dist/guest/toolchains/steam/commands.js +155 -0
- package/dist/guest/toolchains/steam/steam.d.ts +4 -0
- package/dist/guest/toolchains/steam/steam.js +61 -0
- package/dist/guest/toolchains/steam/steamcmd-install.d.ts +29 -0
- package/dist/guest/toolchains/steam/steamcmd-install.js +177 -0
- package/dist/guest/toolchains/steam/steamcmd.d.ts +6 -0
- package/dist/guest/toolchains/steam/steamcmd.js +23 -0
- package/dist/guest/toolchains/step.d.ts +10 -0
- package/dist/host/accounts/deliver.d.ts +26 -0
- package/dist/host/accounts/deliver.js +80 -0
- package/dist/host/accounts/handoff.d.ts +17 -0
- package/dist/host/accounts/handoff.js +110 -0
- package/dist/host/accounts/index.d.ts +6 -0
- package/dist/host/accounts/index.js +8 -0
- package/dist/host/accounts/kinds/appstore.d.ts +2 -0
- package/dist/host/accounts/kinds/appstore.js +10 -0
- package/dist/host/accounts/kinds/cfx.d.ts +2 -0
- package/dist/host/accounts/kinds/cfx.js +7 -0
- package/dist/host/accounts/kinds/epic.d.ts +2 -0
- package/dist/host/accounts/kinds/epic.js +15 -0
- package/dist/host/accounts/kinds/expo.d.ts +2 -0
- package/dist/host/accounts/kinds/expo.js +7 -0
- package/dist/host/accounts/kinds/keystore.d.ts +2 -0
- package/dist/host/accounts/kinds/keystore.js +7 -0
- package/dist/host/accounts/kinds/play.d.ts +2 -0
- package/dist/host/accounts/kinds/play.js +7 -0
- package/dist/host/accounts/kinds/steam.d.ts +6 -0
- package/dist/host/accounts/kinds/steam.js +31 -0
- package/dist/host/accounts/kinds/unity.d.ts +2 -0
- package/dist/host/accounts/kinds/unity.js +13 -0
- package/dist/host/accounts/leases.d.ts +40 -0
- package/dist/host/accounts/leases.js +62 -0
- package/dist/host/accounts/source.d.ts +21 -0
- package/dist/host/accounts/source.js +15 -0
- package/dist/host/accounts/sources.d.ts +5 -0
- package/dist/host/accounts/sources.js +18 -0
- package/dist/host/accounts/store.d.ts +23 -0
- package/dist/host/accounts/store.js +74 -0
- package/dist/host/audit/log.d.ts +1 -1
- package/dist/host/launch/generate.d.ts +2 -0
- package/dist/host/launch/generate.js +16 -1
- package/dist/host/launch/hints/android.d.ts +3 -0
- package/dist/host/launch/hints/android.js +3 -0
- package/dist/host/launch/hints/engines.d.ts +3 -0
- package/dist/host/launch/hints/engines.js +3 -0
- package/dist/host/launch/hints/fivem.d.ts +3 -0
- package/dist/host/launch/hints/fivem.js +3 -0
- package/dist/host/launch/hints/hint.d.ts +2 -0
- package/dist/host/launch/hints/hint.js +1 -0
- package/dist/host/launch/hints/index.d.ts +5 -0
- package/dist/host/launch/hints/index.js +29 -0
- package/dist/host/launch/hints/mobile.d.ts +3 -0
- package/dist/host/launch/hints/mobile.js +3 -0
- package/dist/host/launch/hints/steam.d.ts +7 -0
- package/dist/host/launch/hints/steam.js +59 -0
- package/dist/host/launch/index.d.ts +2 -2
- package/dist/host/launch/index.js +2 -2
- package/dist/host/launch/mappings.js +2 -0
- package/dist/host/launch/session-file.js +2 -0
- package/dist/host/launch/stage.js +10 -1
- package/dist/host/launch/toolchains.d.ts +7 -0
- package/dist/host/launch/toolchains.js +11 -0
- package/dist/host/pc-installs/discover.d.ts +19 -0
- package/dist/host/pc-installs/discover.js +59 -0
- package/dist/host/pc-installs/epic.d.ts +2 -0
- package/dist/host/pc-installs/epic.js +7 -0
- package/dist/host/pc-installs/index.d.ts +3 -0
- package/dist/host/pc-installs/index.js +2 -0
- package/dist/host/pc-installs/source.d.ts +9 -0
- package/dist/host/pc-installs/source.js +1 -0
- package/dist/host/pc-installs/steam.d.ts +16 -0
- package/dist/host/pc-installs/steam.js +143 -0
- package/dist/host/pc-installs/unity.d.ts +2 -0
- package/dist/host/pc-installs/unity.js +7 -0
- package/dist/host/pc-installs/unreal.d.ts +2 -0
- package/dist/host/pc-installs/unreal.js +7 -0
- package/dist/host/profile/accounts.d.ts +21 -6
- package/dist/host/profile/accounts.js +108 -28
- package/dist/host/profile/claude-login.d.ts +32 -2
- package/dist/host/profile/claude-login.js +100 -8
- package/dist/host/profile/index.d.ts +1 -1
- package/dist/host/profile/index.js +1 -1
- package/dist/host/secrets/launch-secrets.js +1 -0
- package/dist/runtime/agent.js +321 -9
- package/dist/runtime/daemon.js +1987 -604
- package/dist/runtime/db.js +334 -11
- package/dist/runtime/main.js +2519 -723
- package/dist/runtime/netproxy.js +321 -9
- package/dist/runtime/tool.js +28549 -0
- package/dist/runtime/view.js +321 -9
- package/dist/selftest/accounts.test.js +172 -1
- package/dist/selftest/agent-paths.test.js +1 -0
- package/dist/selftest/android.test.d.ts +2 -0
- package/dist/selftest/android.test.js +7 -0
- package/dist/selftest/app.test.js +1 -1
- package/dist/selftest/engines.test.d.ts +2 -0
- package/dist/selftest/engines.test.js +7 -0
- package/dist/selftest/fivem.test.d.ts +2 -0
- package/dist/selftest/fivem.test.js +7 -0
- package/dist/selftest/generate.test.js +1 -1
- package/dist/selftest/index.js +18 -0
- package/dist/selftest/menu-screens.js +1 -0
- package/dist/selftest/menu.test.js +2 -1
- package/dist/selftest/mobile.test.d.ts +2 -0
- package/dist/selftest/mobile.test.js +7 -0
- package/dist/selftest/pc-installs.test.d.ts +2 -0
- package/dist/selftest/pc-installs.test.js +111 -0
- package/dist/selftest/persisted-installs.test.d.ts +2 -0
- package/dist/selftest/persisted-installs.test.js +107 -0
- package/dist/selftest/projects.test.js +6 -4
- package/dist/selftest/service-accounts.test.d.ts +2 -0
- package/dist/selftest/service-accounts.test.js +320 -0
- package/dist/selftest/steam.test.d.ts +2 -0
- package/dist/selftest/steam.test.js +316 -0
- package/dist/selftest/storage-helper.test.js +31 -8
- package/dist/selftest/support/engine-golden.js +3 -0
- package/dist/selftest/support/fixtures.d.ts +87 -0
- package/dist/selftest/support/fixtures.js +4 -3
- package/dist/selftest/support/pc-memory.d.ts +2 -0
- package/dist/selftest/support/pc-memory.js +17 -0
- package/dist/selftest/support/web-preview.js +20 -1
- package/dist/selftest/unity.test.d.ts +2 -0
- package/dist/selftest/unity.test.js +7 -0
- package/dist/shared/accounts/fingerprint.d.ts +1 -0
- package/dist/shared/accounts/fingerprint.js +20 -0
- package/dist/shared/accounts/index.d.ts +5 -0
- package/dist/shared/accounts/index.js +7 -0
- package/dist/shared/accounts/kinds/epic.d.ts +10 -0
- package/dist/shared/accounts/kinds/epic.js +56 -0
- package/dist/shared/accounts/kinds/steam.d.ts +28 -0
- package/dist/shared/accounts/kinds/steam.js +99 -0
- package/dist/shared/accounts/kinds.d.ts +41 -0
- package/dist/shared/accounts/kinds.js +154 -0
- package/dist/shared/accounts/payloads.d.ts +151 -0
- package/dist/shared/accounts/payloads.js +128 -0
- package/dist/shared/apps/catalogue-gamedev.d.ts +2 -0
- package/dist/shared/apps/catalogue-gamedev.js +1 -0
- package/dist/shared/apps/catalogue-mobile.d.ts +2 -0
- package/dist/shared/apps/catalogue-mobile.js +1 -0
- package/dist/shared/apps/catalogue-modding.d.ts +2 -0
- package/dist/shared/apps/catalogue-modding.js +1 -0
- package/dist/shared/apps/catalogue.d.ts +1 -0
- package/dist/shared/apps/catalogue.js +6 -1
- package/dist/shared/channel/schema.d.ts +183 -0
- package/dist/shared/channel/secrets.d.ts +42 -0
- package/dist/shared/channel/secrets.js +3 -0
- package/dist/shared/download/downloader.d.ts +7 -0
- package/dist/shared/download/downloader.js +10 -3
- package/dist/shared/installs.d.ts +19 -0
- package/dist/shared/installs.js +13 -0
- package/dist/shared/io/bounded.d.ts +6 -0
- package/dist/shared/io/bounded.js +38 -0
- package/dist/shared/io/index.d.ts +2 -0
- package/dist/shared/io/index.js +2 -0
- package/dist/shared/io/text.d.ts +9 -0
- package/dist/shared/io/text.js +18 -0
- package/dist/shared/paths/guest-paths.js +1 -1
- package/dist/shared/paths/index.d.ts +1 -0
- package/dist/shared/paths/index.js +1 -0
- package/dist/shared/paths/pc-installs.d.ts +20 -0
- package/dist/shared/paths/pc-installs.js +19 -0
- package/dist/shared/vdf.d.ts +25 -0
- package/dist/shared/vdf.js +151 -0
- package/dist/sync/sync-cycle.js +9 -0
- package/dist/web/index.html +1 -1
- package/dist/web/{main-JTH3FT4O.js → main-CWIF4VQI.js} +63 -61
- package/native/csharp/HcsHost/AssemblyInfo.cs +3 -3
- package/native/csharp/HostTools/AssemblyInfo.cs +3 -3
- package/native/csharp/StorageHelper/AssemblyInfo.cs +3 -3
- package/package.json +1 -1
- package/sandbox/scripts/add-firewall-port.ps1 +13 -0
- package/sandbox/templates/fivem/README.txt +2 -0
- package/schemas/config.schema.json +485 -0
- package/schemas/sandbox-config.schema.json +416 -0
package/dist/runtime/daemon.js
CHANGED
|
@@ -1363,11 +1363,11 @@ var require_lodash = __commonJS({
|
|
|
1363
1363
|
return isFunction(object2[key2]);
|
|
1364
1364
|
});
|
|
1365
1365
|
}
|
|
1366
|
-
function baseGet(object2,
|
|
1367
|
-
|
|
1368
|
-
var index = 0, length =
|
|
1366
|
+
function baseGet(object2, path84) {
|
|
1367
|
+
path84 = castPath(path84, object2);
|
|
1368
|
+
var index = 0, length = path84.length;
|
|
1369
1369
|
while (object2 != null && index < length) {
|
|
1370
|
-
object2 = object2[toKey(
|
|
1370
|
+
object2 = object2[toKey(path84[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, path84, args) {
|
|
1435
|
+
path84 = castPath(path84, object2);
|
|
1436
|
+
object2 = parent(object2, path84);
|
|
1437
|
+
var func = object2 == null ? object2 : object2[toKey(last(path84))];
|
|
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(path84, srcValue) {
|
|
1594
|
+
if (isKey(path84) && isStrictComparable(srcValue)) {
|
|
1595
|
+
return matchesStrictComparable(toKey(path84), 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, path84);
|
|
1599
|
+
return objValue === undefined2 && objValue === srcValue ? hasIn(object2, path84) : 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, path84) {
|
|
1697
|
+
return hasIn(object2, path84);
|
|
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 path84 = paths[index], value = baseGet(object2, path84);
|
|
1704
|
+
if (predicate(value, path84)) {
|
|
1705
|
+
baseSet(result2, castPath(path84, object2), value);
|
|
1706
1706
|
}
|
|
1707
1707
|
}
|
|
1708
1708
|
return result2;
|
|
1709
1709
|
}
|
|
1710
|
-
function basePropertyDeep(
|
|
1710
|
+
function basePropertyDeep(path84) {
|
|
1711
1711
|
return function(object2) {
|
|
1712
|
-
return baseGet(object2,
|
|
1712
|
+
return baseGet(object2, path84);
|
|
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, path84, value, customizer) {
|
|
1787
1787
|
if (!isObject2(object2)) {
|
|
1788
1788
|
return object2;
|
|
1789
1789
|
}
|
|
1790
|
-
|
|
1791
|
-
var index = -1, length =
|
|
1790
|
+
path84 = castPath(path84, object2);
|
|
1791
|
+
var index = -1, length = path84.length, lastIndex = length - 1, nested = object2;
|
|
1792
1792
|
while (nested != null && ++index < length) {
|
|
1793
|
-
var key2 = toKey(
|
|
1793
|
+
var key2 = toKey(path84[index]), newValue = value;
|
|
1794
1794
|
if (key2 === "__proto__" || key2 === "constructor" || key2 === "prototype") {
|
|
1795
1795
|
return object2;
|
|
1796
1796
|
}
|
|
@@ -1798,7 +1798,7 @@ var require_lodash = __commonJS({
|
|
|
1798
1798
|
var objValue = nested[key2];
|
|
1799
1799
|
newValue = customizer ? customizer(objValue, key2, nested) : undefined2;
|
|
1800
1800
|
if (newValue === undefined2) {
|
|
1801
|
-
newValue = isObject2(objValue) ? objValue : isIndex(
|
|
1801
|
+
newValue = isObject2(objValue) ? objValue : isIndex(path84[index + 1]) ? [] : {};
|
|
1802
1802
|
}
|
|
1803
1803
|
}
|
|
1804
1804
|
assignValue(nested, key2, newValue);
|
|
@@ -1964,14 +1964,14 @@ var require_lodash = __commonJS({
|
|
|
1964
1964
|
}
|
|
1965
1965
|
return result2;
|
|
1966
1966
|
}
|
|
1967
|
-
function baseUnset(object2,
|
|
1968
|
-
|
|
1969
|
-
var index = -1, length =
|
|
1967
|
+
function baseUnset(object2, path84) {
|
|
1968
|
+
path84 = castPath(path84, object2);
|
|
1969
|
+
var index = -1, length = path84.length;
|
|
1970
1970
|
if (!length) {
|
|
1971
1971
|
return true;
|
|
1972
1972
|
}
|
|
1973
1973
|
while (++index < length) {
|
|
1974
|
-
var key2 = toKey(
|
|
1974
|
+
var key2 = toKey(path84[index]);
|
|
1975
1975
|
if (key2 === "__proto__" && !hasOwnProperty.call(object2, "__proto__")) {
|
|
1976
1976
|
return false;
|
|
1977
1977
|
}
|
|
@@ -1979,11 +1979,11 @@ var require_lodash = __commonJS({
|
|
|
1979
1979
|
return false;
|
|
1980
1980
|
}
|
|
1981
1981
|
}
|
|
1982
|
-
var obj = parent(object2,
|
|
1983
|
-
return obj == null || delete obj[toKey(last(
|
|
1982
|
+
var obj = parent(object2, path84);
|
|
1983
|
+
return obj == null || delete obj[toKey(last(path84))];
|
|
1984
1984
|
}
|
|
1985
|
-
function baseUpdate(object2,
|
|
1986
|
-
return baseSet(object2,
|
|
1985
|
+
function baseUpdate(object2, path84, updater, customizer) {
|
|
1986
|
+
return baseSet(object2, path84, updater(baseGet(object2, path84)), 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, path84, hasFunc) {
|
|
2870
|
+
path84 = castPath(path84, object2);
|
|
2871
|
+
var index = -1, length = path84.length, result2 = false;
|
|
2872
2872
|
while (++index < length) {
|
|
2873
|
-
var key2 = toKey(
|
|
2873
|
+
var key2 = toKey(path84[index]);
|
|
2874
2874
|
if (!(result2 = object2 != null && hasFunc(object2, key2))) {
|
|
2875
2875
|
break;
|
|
2876
2876
|
}
|
|
@@ -3072,8 +3072,8 @@ var require_lodash = __commonJS({
|
|
|
3072
3072
|
return apply(func, this, otherArgs);
|
|
3073
3073
|
};
|
|
3074
3074
|
}
|
|
3075
|
-
function parent(object2,
|
|
3076
|
-
return
|
|
3075
|
+
function parent(object2, path84) {
|
|
3076
|
+
return path84.length < 2 ? object2 : baseGet(object2, baseSlice(path84, 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, path84, args) {
|
|
3712
|
+
var index = -1, isFunc = typeof path84 == "function", result2 = isArrayLike(collection) ? Array2(collection.length) : [];
|
|
3713
3713
|
baseEach(collection, function(value) {
|
|
3714
|
-
result2[++index] = isFunc ? apply(
|
|
3714
|
+
result2[++index] = isFunc ? apply(path84, value, args) : baseInvoke(value, path84, args);
|
|
3715
3715
|
});
|
|
3716
3716
|
return result2;
|
|
3717
3717
|
});
|
|
@@ -4363,15 +4363,15 @@ var require_lodash = __commonJS({
|
|
|
4363
4363
|
function functionsIn(object2) {
|
|
4364
4364
|
return object2 == null ? [] : baseFunctions(object2, keysIn(object2));
|
|
4365
4365
|
}
|
|
4366
|
-
function get(object2,
|
|
4367
|
-
var result2 = object2 == null ? undefined2 : baseGet(object2,
|
|
4366
|
+
function get(object2, path84, defaultValue) {
|
|
4367
|
+
var result2 = object2 == null ? undefined2 : baseGet(object2, path84);
|
|
4368
4368
|
return result2 === undefined2 ? defaultValue : result2;
|
|
4369
4369
|
}
|
|
4370
|
-
function has(object2,
|
|
4371
|
-
return object2 != null && hasPath(object2,
|
|
4370
|
+
function has(object2, path84) {
|
|
4371
|
+
return object2 != null && hasPath(object2, path84, baseHas);
|
|
4372
4372
|
}
|
|
4373
|
-
function hasIn(object2,
|
|
4374
|
-
return object2 != null && hasPath(object2,
|
|
4373
|
+
function hasIn(object2, path84) {
|
|
4374
|
+
return object2 != null && hasPath(object2, path84, baseHasIn);
|
|
4375
4375
|
}
|
|
4376
4376
|
var invert = createInverter(function(result2, value, key2) {
|
|
4377
4377
|
if (value != null && typeof value.toString != "function") {
|
|
@@ -4424,10 +4424,10 @@ var require_lodash = __commonJS({
|
|
|
4424
4424
|
return result2;
|
|
4425
4425
|
}
|
|
4426
4426
|
var isDeep = false;
|
|
4427
|
-
paths = arrayMap(paths, function(
|
|
4428
|
-
|
|
4429
|
-
isDeep || (isDeep =
|
|
4430
|
-
return
|
|
4427
|
+
paths = arrayMap(paths, function(path84) {
|
|
4428
|
+
path84 = castPath(path84, object2);
|
|
4429
|
+
isDeep || (isDeep = path84.length > 1);
|
|
4430
|
+
return path84;
|
|
4431
4431
|
});
|
|
4432
4432
|
copyObject(object2, getAllKeysIn(object2), result2);
|
|
4433
4433
|
if (isDeep) {
|
|
@@ -4442,7 +4442,7 @@ var require_lodash = __commonJS({
|
|
|
4442
4442
|
function omitBy(object2, predicate) {
|
|
4443
4443
|
return pickBy(object2, negate(getIteratee(predicate)));
|
|
4444
4444
|
}
|
|
4445
|
-
var
|
|
4445
|
+
var pick3 = flatRest(function(object2, paths) {
|
|
4446
4446
|
return object2 == null ? {} : basePick(object2, paths);
|
|
4447
4447
|
});
|
|
4448
4448
|
function pickBy(object2, predicate) {
|
|
@@ -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, path84) {
|
|
4457
|
+
return predicate(value, path84[0]);
|
|
4458
4458
|
});
|
|
4459
4459
|
}
|
|
4460
|
-
function result(object2,
|
|
4461
|
-
|
|
4462
|
-
var index = -1, length =
|
|
4460
|
+
function result(object2, path84, defaultValue) {
|
|
4461
|
+
path84 = castPath(path84, object2);
|
|
4462
|
+
var index = -1, length = path84.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(path84[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, path84, value) {
|
|
4478
|
+
return object2 == null ? object2 : baseSet(object2, path84, value);
|
|
4479
4479
|
}
|
|
4480
|
-
function setWith(object2,
|
|
4480
|
+
function setWith(object2, path84, value, customizer) {
|
|
4481
4481
|
customizer = typeof customizer == "function" ? customizer : undefined2;
|
|
4482
|
-
return object2 == null ? object2 : baseSet(object2,
|
|
4482
|
+
return object2 == null ? object2 : baseSet(object2, path84, 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, path84) {
|
|
4505
|
+
return object2 == null ? true : baseUnset(object2, path84);
|
|
4506
4506
|
}
|
|
4507
|
-
function update(object2,
|
|
4508
|
-
return object2 == null ? object2 : baseUpdate(object2,
|
|
4507
|
+
function update(object2, path84, updater) {
|
|
4508
|
+
return object2 == null ? object2 : baseUpdate(object2, path84, castFunction(updater));
|
|
4509
4509
|
}
|
|
4510
|
-
function updateWith(object2,
|
|
4510
|
+
function updateWith(object2, path84, updater, customizer) {
|
|
4511
4511
|
customizer = typeof customizer == "function" ? customizer : undefined2;
|
|
4512
|
-
return object2 == null ? object2 : baseUpdate(object2,
|
|
4512
|
+
return object2 == null ? object2 : baseUpdate(object2, path84, 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(path84, srcValue) {
|
|
4899
|
+
return baseMatchesProperty(path84, baseClone(srcValue, CLONE_DEEP_FLAG));
|
|
4900
4900
|
}
|
|
4901
|
-
var method = baseRest(function(
|
|
4901
|
+
var method = baseRest(function(path84, args) {
|
|
4902
4902
|
return function(object2) {
|
|
4903
|
-
return baseInvoke(object2,
|
|
4903
|
+
return baseInvoke(object2, path84, args);
|
|
4904
4904
|
};
|
|
4905
4905
|
});
|
|
4906
4906
|
var methodOf = baseRest(function(object2, args) {
|
|
4907
|
-
return function(
|
|
4908
|
-
return baseInvoke(object2,
|
|
4907
|
+
return function(path84) {
|
|
4908
|
+
return baseInvoke(object2, path84, 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(path84) {
|
|
4956
|
+
return isKey(path84) ? baseProperty(toKey(path84)) : basePropertyDeep(path84);
|
|
4957
4957
|
}
|
|
4958
4958
|
function propertyOf(object2) {
|
|
4959
|
-
return function(
|
|
4960
|
-
return object2 == null ? undefined2 : baseGet(object2,
|
|
4959
|
+
return function(path84) {
|
|
4960
|
+
return object2 == null ? undefined2 : baseGet(object2, path84);
|
|
4961
4961
|
};
|
|
4962
4962
|
}
|
|
4963
4963
|
var range = createRange();
|
|
@@ -5125,7 +5125,7 @@ var require_lodash = __commonJS({
|
|
|
5125
5125
|
lodash.partial = partial2;
|
|
5126
5126
|
lodash.partialRight = partialRight;
|
|
5127
5127
|
lodash.partition = partition;
|
|
5128
|
-
lodash.pick =
|
|
5128
|
+
lodash.pick = pick3;
|
|
5129
5129
|
lodash.pickBy = pickBy;
|
|
5130
5130
|
lodash.property = property;
|
|
5131
5131
|
lodash.propertyOf = propertyOf;
|
|
@@ -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(path84, args) {
|
|
5414
|
+
if (typeof path84 == "function") {
|
|
5415
5415
|
return new LazyWrapper(this);
|
|
5416
5416
|
}
|
|
5417
5417
|
return this.map(function(value) {
|
|
5418
|
-
return baseInvoke(value,
|
|
5418
|
+
return baseInvoke(value, path84, args);
|
|
5419
5419
|
});
|
|
5420
5420
|
});
|
|
5421
5421
|
LazyWrapper.prototype.reject = function(predicate) {
|
|
@@ -5540,14 +5540,14 @@ function relayPort(index) {
|
|
|
5540
5540
|
}
|
|
5541
5541
|
|
|
5542
5542
|
// src/guest/runtime/log.ts
|
|
5543
|
-
import
|
|
5543
|
+
import fs7 from "node:fs";
|
|
5544
5544
|
import path9 from "node:path";
|
|
5545
5545
|
|
|
5546
5546
|
// src/guest/runtime/paths.ts
|
|
5547
5547
|
import path8 from "node:path";
|
|
5548
5548
|
|
|
5549
5549
|
// src/shared/channel/run-dir.ts
|
|
5550
|
-
import
|
|
5550
|
+
import fs6 from "node:fs";
|
|
5551
5551
|
import path7 from "node:path";
|
|
5552
5552
|
|
|
5553
5553
|
// node_modules/zod/v4/classic/external.js
|
|
@@ -6366,10 +6366,10 @@ function mergeDefs(...defs) {
|
|
|
6366
6366
|
function cloneDef(schema) {
|
|
6367
6367
|
return mergeDefs(schema._zod.def);
|
|
6368
6368
|
}
|
|
6369
|
-
function getElementAtPath(obj,
|
|
6370
|
-
if (!
|
|
6369
|
+
function getElementAtPath(obj, path84) {
|
|
6370
|
+
if (!path84)
|
|
6371
6371
|
return obj;
|
|
6372
|
-
return
|
|
6372
|
+
return path84.reduce((acc, key2) => acc?.[key2], obj);
|
|
6373
6373
|
}
|
|
6374
6374
|
function promiseAllObject(promisesObj) {
|
|
6375
6375
|
const keys = Object.keys(promisesObj);
|
|
@@ -6709,11 +6709,11 @@ function explicitlyAborted(x, startIndex = 0) {
|
|
|
6709
6709
|
}
|
|
6710
6710
|
return false;
|
|
6711
6711
|
}
|
|
6712
|
-
function prefixIssues(
|
|
6712
|
+
function prefixIssues(path84, issues) {
|
|
6713
6713
|
return issues.map((iss) => {
|
|
6714
6714
|
var _a3;
|
|
6715
6715
|
(_a3 = iss).path ?? (_a3.path = []);
|
|
6716
|
-
iss.path.unshift(
|
|
6716
|
+
iss.path.unshift(path84);
|
|
6717
6717
|
return iss;
|
|
6718
6718
|
});
|
|
6719
6719
|
}
|
|
@@ -6818,8 +6818,8 @@ function cleanEnum(obj) {
|
|
|
6818
6818
|
return Number.isNaN(Number.parseInt(k, 10));
|
|
6819
6819
|
}).map((el) => el[1]);
|
|
6820
6820
|
}
|
|
6821
|
-
function base64ToUint8Array(
|
|
6822
|
-
const binaryString = atob(
|
|
6821
|
+
function base64ToUint8Array(base644) {
|
|
6822
|
+
const binaryString = atob(base644);
|
|
6823
6823
|
const bytes = new Uint8Array(binaryString.length);
|
|
6824
6824
|
for (let i = 0; i < binaryString.length; i++) {
|
|
6825
6825
|
bytes[i] = binaryString.charCodeAt(i);
|
|
@@ -6834,9 +6834,9 @@ function uint8ArrayToBase64(bytes) {
|
|
|
6834
6834
|
return btoa(binaryString);
|
|
6835
6835
|
}
|
|
6836
6836
|
function base64urlToUint8Array(base64url3) {
|
|
6837
|
-
const
|
|
6838
|
-
const padding = "=".repeat((4 -
|
|
6839
|
-
return base64ToUint8Array(
|
|
6837
|
+
const base644 = base64url3.replace(/-/g, "+").replace(/_/g, "/");
|
|
6838
|
+
const padding = "=".repeat((4 - base644.length % 4) % 4);
|
|
6839
|
+
return base64ToUint8Array(base644 + padding);
|
|
6840
6840
|
}
|
|
6841
6841
|
function uint8ArrayToBase64url(bytes) {
|
|
6842
6842
|
return uint8ArrayToBase64(bytes).replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
|
|
@@ -7163,16 +7163,16 @@ function flattenError(error62, mapper = (issue2) => issue2.message) {
|
|
|
7163
7163
|
}
|
|
7164
7164
|
function formatError(error62, mapper = (issue2) => issue2.message) {
|
|
7165
7165
|
const fieldErrors = { _errors: [] };
|
|
7166
|
-
const processError = (error63,
|
|
7166
|
+
const processError = (error63, path84 = []) => {
|
|
7167
7167
|
for (const issue2 of error63.issues) {
|
|
7168
7168
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
7169
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
7169
|
+
issue2.errors.map((issues) => processError({ issues }, [...path84, ...issue2.path]));
|
|
7170
7170
|
} else if (issue2.code === "invalid_key") {
|
|
7171
|
-
processError({ issues: issue2.issues }, [...
|
|
7171
|
+
processError({ issues: issue2.issues }, [...path84, ...issue2.path]);
|
|
7172
7172
|
} else if (issue2.code === "invalid_element") {
|
|
7173
|
-
processError({ issues: issue2.issues }, [...
|
|
7173
|
+
processError({ issues: issue2.issues }, [...path84, ...issue2.path]);
|
|
7174
7174
|
} else {
|
|
7175
|
-
const fullpath = [...
|
|
7175
|
+
const fullpath = [...path84, ...issue2.path];
|
|
7176
7176
|
if (fullpath.length === 0) {
|
|
7177
7177
|
fieldErrors._errors.push(mapper(issue2));
|
|
7178
7178
|
} else {
|
|
@@ -7211,17 +7211,17 @@ function formatError(error62, mapper = (issue2) => issue2.message) {
|
|
|
7211
7211
|
}
|
|
7212
7212
|
function treeifyError(error62, mapper = (issue2) => issue2.message) {
|
|
7213
7213
|
const result = { errors: [] };
|
|
7214
|
-
const processError = (error63,
|
|
7214
|
+
const processError = (error63, path84 = []) => {
|
|
7215
7215
|
var _a3;
|
|
7216
7216
|
for (const issue2 of error63.issues) {
|
|
7217
7217
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
7218
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
7218
|
+
issue2.errors.map((issues) => processError({ issues }, [...path84, ...issue2.path]));
|
|
7219
7219
|
} else if (issue2.code === "invalid_key") {
|
|
7220
|
-
processError({ issues: issue2.issues }, [...
|
|
7220
|
+
processError({ issues: issue2.issues }, [...path84, ...issue2.path]);
|
|
7221
7221
|
} else if (issue2.code === "invalid_element") {
|
|
7222
|
-
processError({ issues: issue2.issues }, [...
|
|
7222
|
+
processError({ issues: issue2.issues }, [...path84, ...issue2.path]);
|
|
7223
7223
|
} else {
|
|
7224
|
-
const fullpath = [...
|
|
7224
|
+
const fullpath = [...path84, ...issue2.path];
|
|
7225
7225
|
if (fullpath.length === 0) {
|
|
7226
7226
|
result.errors.push(mapper(issue2));
|
|
7227
7227
|
continue;
|
|
@@ -7260,8 +7260,8 @@ function treeifyError(error62, mapper = (issue2) => issue2.message) {
|
|
|
7260
7260
|
}
|
|
7261
7261
|
function toDotPath(_path) {
|
|
7262
7262
|
const segs = [];
|
|
7263
|
-
const
|
|
7264
|
-
for (const seg of
|
|
7263
|
+
const path84 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
7264
|
+
for (const seg of path84) {
|
|
7265
7265
|
if (typeof seg === "number")
|
|
7266
7266
|
segs.push(`[${seg}]`);
|
|
7267
7267
|
else if (typeof seg === "symbol")
|
|
@@ -8579,8 +8579,8 @@ var base64urlCharset = /^[A-Za-z0-9_-]*$/;
|
|
|
8579
8579
|
function isValidBase64URL(data) {
|
|
8580
8580
|
if (!base64urlCharset.test(data))
|
|
8581
8581
|
return false;
|
|
8582
|
-
const
|
|
8583
|
-
const padded =
|
|
8582
|
+
const base644 = data.replace(/[-_]/g, (c) => c === "-" ? "+" : "/");
|
|
8583
|
+
const padded = base644.padEnd(Math.ceil(base644.length / 4) * 4, "=");
|
|
8584
8584
|
return isValidBase64(padded);
|
|
8585
8585
|
}
|
|
8586
8586
|
var $ZodBase64URL = /* @__PURE__ */ $constructor("$ZodBase64URL", (inst, def) => {
|
|
@@ -24363,13 +24363,13 @@ function resolveRef(ref, ctx) {
|
|
|
24363
24363
|
if (!ref.startsWith("#")) {
|
|
24364
24364
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
24365
24365
|
}
|
|
24366
|
-
const
|
|
24367
|
-
if (
|
|
24366
|
+
const path84 = ref.slice(1).split("/").filter(Boolean);
|
|
24367
|
+
if (path84.length === 0) {
|
|
24368
24368
|
return ctx.rootSchema;
|
|
24369
24369
|
}
|
|
24370
24370
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
24371
|
-
if (
|
|
24372
|
-
const key2 =
|
|
24371
|
+
if (path84[0] === defsKey) {
|
|
24372
|
+
const key2 = path84[1] === void 0 ? void 0 : decodeJSONPointerSegment(path84[1]);
|
|
24373
24373
|
if (!key2 || !ctx.defs[key2]) {
|
|
24374
24374
|
throw new Error(`Reference not found: ${ref}`);
|
|
24375
24375
|
}
|
|
@@ -25219,7 +25219,7 @@ function date4(params) {
|
|
|
25219
25219
|
}
|
|
25220
25220
|
|
|
25221
25221
|
// src/shared/paths/guest-paths.ts
|
|
25222
|
-
var RESERVED_GUEST = /^C:\\(?:Windows|Program Files|Program Files \(x86\)|ProgramData|Users|AgentLaunch|AgentData|HostTools|nvm|Mirror)(?:\\|$)/i;
|
|
25222
|
+
var RESERVED_GUEST = /^C:\\(?:Windows|Program Files|Program Files \(x86\)|ProgramData|Users|AgentLaunch|AgentData|HostTools|nvm|Mirror|PcInstalls)(?:\\|$)/i;
|
|
25223
25223
|
var MIRROR_ROOT = "C:\\Mirror";
|
|
25224
25224
|
var MIRROR_LETTER = /^[D-Z]$/;
|
|
25225
25225
|
var DRIVE_PATH = /^([A-Za-z]):\\(.*)$/;
|
|
@@ -25680,8 +25680,119 @@ var ToolchainsSchema = external_exports.strictObject({
|
|
|
25680
25680
|
),
|
|
25681
25681
|
keepInstallFiles: external_exports.boolean().describe(
|
|
25682
25682
|
"Keep an offline copy of the Visual Studio install files in tools\\visualstudio (~10 GB, made once), so later boots install without downloading them again. Skipped while that disk has too little room."
|
|
25683
|
+
),
|
|
25684
|
+
persistEngines: external_exports.boolean().describe(
|
|
25685
|
+
"Engines the Epic Games Launcher installs go to tools\\unreal\\engines (kept between sandboxes, 40-60 GB each) and are registered with the launcher again every boot. Off: they go on the sandbox disk and are lost when it closes. Engines installed on this PC can be mapped instead (pcInstalls.unrealEngines)."
|
|
25686
|
+
),
|
|
25687
|
+
derivedDataCache: external_exports.enum(["persisted", "local"]).describe(
|
|
25688
|
+
`"persisted": the engine's local derived data cache (compiled shaders, 10-50 GB) in tools\\unreal\\ddc, kept between sandboxes. "local": Unreal's own place on the sandbox disk (rebuilt every boot).`
|
|
25689
|
+
)
|
|
25690
|
+
}),
|
|
25691
|
+
unity: external_exports.strictObject({
|
|
25692
|
+
enabled: enabled(
|
|
25693
|
+
"Unity: the editor version a project asks for, from Unity's release API (checked against its published hash), installed into tools\\unity\\<version> (6-7 GB each), with the modules you list.",
|
|
25694
|
+
"ProjectSettings/ProjectVersion.txt"
|
|
25695
|
+
),
|
|
25696
|
+
acceptLicense: external_exports.boolean().describe(
|
|
25697
|
+
"Required to install: you accept the Unity terms of service (https://unity.com/legal/terms-of-service), and the editor needs a Unity licence (Personal is free). A project file cannot accept it for you."
|
|
25698
|
+
),
|
|
25699
|
+
version: external_exports.string().min(1).describe(
|
|
25700
|
+
'"project" = the version in ProjectSettings/ProjectVersion.txt, or an editor version such as "6000.0.32f1".'
|
|
25701
|
+
),
|
|
25702
|
+
modules: external_exports.array(external_exports.string().regex(/^[a-z0-9-]+$/)).describe(
|
|
25703
|
+
`Editor modules to add: "android" (4-5 GB, also the Android SDK), "webgl" (1.5 GB), "windows-il2cpp" (adds Visual Studio's C++ parts), "ios" (Xcode project export only: iOS builds need a Mac).`
|
|
25704
|
+
),
|
|
25705
|
+
hub: external_exports.boolean().describe("Also Unity Hub, with the installed editors listed in it."),
|
|
25706
|
+
keepVersions: external_exports.number().int().min(1).max(20).describe(
|
|
25707
|
+
"How many editor versions to keep in tools\\unity; older ones are removed (the least recently used first)."
|
|
25708
|
+
)
|
|
25709
|
+
}),
|
|
25710
|
+
godot: external_exports.strictObject({
|
|
25711
|
+
enabled: enabled(
|
|
25712
|
+
"Godot from its official builds (checked against the published SHA-512 sums), self-contained in tools\\godot\\<version> with `godot` (the console build) on PATH.",
|
|
25713
|
+
"project.godot"
|
|
25714
|
+
),
|
|
25715
|
+
version: external_exports.string().min(1).describe(
|
|
25716
|
+
'"project" = the version project.godot was saved with (else the newest stable), or a version such as "4.3".'
|
|
25717
|
+
),
|
|
25718
|
+
dotnet: EnabledSchema.describe(
|
|
25719
|
+
'The .NET (C#) build of Godot and the .NET SDK: true, false, or "auto" = when the project has a .csproj.'
|
|
25720
|
+
),
|
|
25721
|
+
exportTemplates: external_exports.boolean().describe("Also the export templates for that version (~1.2 GB), for exporting games."),
|
|
25722
|
+
keepVersions: external_exports.number().int().min(1).max(20).describe("How many Godot versions to keep; older ones are removed (the least recently used first).")
|
|
25723
|
+
}),
|
|
25724
|
+
steam: external_exports.strictObject({
|
|
25725
|
+
enabled: enabled(
|
|
25726
|
+
"SteamCMD (`steamcmd` on PATH, Valve-signed, ~0.3 GB) and `sbx-steam` for logging in, downloading apps and workshop items, and uploading builds (ContentBuilder) and workshop items.",
|
|
25727
|
+
"steam_appid.txt, steam_api64.dll, steam_api.dll, or an app_build / workshop_item .vdf"
|
|
25728
|
+
),
|
|
25729
|
+
client: external_exports.boolean().describe(
|
|
25730
|
+
"Also the Steam client (1-1.5 GB, in tools\\steam), for testing the Steamworks API, the overlay or in-game uploads. You sign in to it in each sandbox."
|
|
25731
|
+
),
|
|
25732
|
+
sdkFolder: external_exports.string().describe(
|
|
25733
|
+
"Where the Steamworks SDK is in the sandbox (relative paths are inside the project); it sets STEAMWORKS_SDK. Empty = not set. The SDK is never downloaded (it needs a Steamworks partner login)."
|
|
25734
|
+
)
|
|
25735
|
+
}),
|
|
25736
|
+
fivem: external_exports.strictObject({
|
|
25737
|
+
enabled: enabled(
|
|
25738
|
+
"A FiveM / RedM server (FXServer with txAdmin) for resource development, from the Cfx.re artifacts (the game client is not supported). `sbx-fivem serve` starts it.",
|
|
25739
|
+
"fxmanifest.lua or __resource.lua (up to 3 folders down)"
|
|
25740
|
+
),
|
|
25741
|
+
acceptLicense: external_exports.boolean().describe(
|
|
25742
|
+
"Required to install: you accept the Cfx.re platform terms (https://fivem.net/terms) and the FXServer licence. A project file cannot accept it for you."
|
|
25743
|
+
),
|
|
25744
|
+
game: external_exports.enum(["gta5", "rdr3"]).describe('"gta5" = FiveM, "rdr3" = RedM.'),
|
|
25745
|
+
artifact: external_exports.string().regex(/^(recommended|optional|latest|\d+)$/).describe('The server build: "recommended", "optional", "latest", or a build number.'),
|
|
25746
|
+
txAdmin: external_exports.boolean().describe("Start the server with txAdmin (its web panel on port 40120)."),
|
|
25747
|
+
keepVersions: external_exports.number().int().min(1).max(20).describe("How many server builds to keep in tools\\fivem\\artifacts.")
|
|
25748
|
+
}),
|
|
25749
|
+
android: external_exports.strictObject({
|
|
25750
|
+
enabled: enabled(
|
|
25751
|
+
"The Android SDK (command-line tools, platform-tools, build-tools, platforms, NDK and CMake as needed) in tools\\android-sdk, with a JDK. No emulator (Windows Sandbox cannot run one): use a device over the network, or build only.",
|
|
25752
|
+
"a Gradle build using com.android, an AndroidManifest.xml (up to 3 folders down), a .NET MAUI project, or a Flutter / React Native / Godot Android project"
|
|
25753
|
+
),
|
|
25754
|
+
acceptLicense: external_exports.boolean().describe(
|
|
25755
|
+
"Required to install: you accept the Android SDK licence (https://developer.android.com/studio/terms) and the licences sdkmanager shows. A project file cannot accept them for you."
|
|
25756
|
+
),
|
|
25757
|
+
platforms: StringsSchema.describe(
|
|
25758
|
+
`Platforms to install, e.g. ["android-35"]; "project" = the compileSdk the project's Gradle files ask for.`
|
|
25759
|
+
),
|
|
25760
|
+
buildTools: external_exports.string().min(1).describe('"latest" or a build-tools version such as "35.0.0".'),
|
|
25761
|
+
ndk: external_exports.union([external_exports.literal(false), external_exports.string().min(1)]).describe(
|
|
25762
|
+
'"auto" = when the project uses native code (ndkVersion, CMake or ndk-build), false = never, or a version.'
|
|
25763
|
+
),
|
|
25764
|
+
cmake: external_exports.union([external_exports.literal(false), external_exports.string().min(1)]).describe('"auto" = when the project builds native code with CMake, false = never, or a version.'),
|
|
25765
|
+
packages: Packages("More sdkmanager packages (not the emulator or system images)", '["extras;google;usb_driver"]')
|
|
25766
|
+
}),
|
|
25767
|
+
flutter: external_exports.strictObject({
|
|
25768
|
+
enabled: enabled(
|
|
25769
|
+
"Flutter (with its Dart) from the official releases (checked against their SHA-256), with the Android SDK for Android builds.",
|
|
25770
|
+
"a pubspec.yaml with a flutter: section"
|
|
25771
|
+
),
|
|
25772
|
+
version: external_exports.string().min(1).describe(
|
|
25773
|
+
'"project" = the version in .fvmrc (else the newest stable), "stable", "beta", or a version such as "3.24.5".'
|
|
25774
|
+
),
|
|
25775
|
+
windowsDesktop: external_exports.boolean().describe(
|
|
25776
|
+
"Windows desktop builds: needs Visual Studio Build Tools' C++ parts (a real installer: it runs every boot, ~5 GB on the sandbox disk)."
|
|
25777
|
+
),
|
|
25778
|
+
precache: StringsSchema.describe(
|
|
25779
|
+
'Platforms whose engine files are downloaded ahead (flutter precache), e.g. ["android", "web"].'
|
|
25683
25780
|
)
|
|
25684
25781
|
}),
|
|
25782
|
+
dart: external_exports.strictObject({
|
|
25783
|
+
enabled: enabled(
|
|
25784
|
+
"The Dart SDK (without Flutter), checked against its published SHA-256.",
|
|
25785
|
+
"a pubspec.yaml without a flutter: section"
|
|
25786
|
+
),
|
|
25787
|
+
version: external_exports.string().min(1).describe('"stable", "beta" or a version such as "3.5.4".')
|
|
25788
|
+
}),
|
|
25789
|
+
reactNative: external_exports.strictObject({
|
|
25790
|
+
enabled: enabled(
|
|
25791
|
+
"React Native / Expo: the Android SDK and JDK for Android builds (Node is always there). iOS builds run in EAS Build (the cloud).",
|
|
25792
|
+
"a package.json depending on react-native or expo"
|
|
25793
|
+
),
|
|
25794
|
+
easCli: external_exports.boolean().describe("Also eas-cli (Expo Application Services) as a global npm package.")
|
|
25795
|
+
}),
|
|
25685
25796
|
cpp: external_exports.strictObject({
|
|
25686
25797
|
enabled: enabled(
|
|
25687
25798
|
"MinGW-w64 GCC with CMake, Ninja, premake5 and mingw32-make (also Rust's linker).",
|
|
@@ -25701,7 +25812,8 @@ var ToolchainsSchema = external_exports.strictObject({
|
|
|
25701
25812
|
),
|
|
25702
25813
|
netfx35: external_exports.boolean().describe(
|
|
25703
25814
|
".NET Framework 3.5 runtime (a Windows feature, enabled from Windows Update on every boot; a few minutes)."
|
|
25704
|
-
)
|
|
25815
|
+
),
|
|
25816
|
+
templates: Packages("Project templates (`dotnet new install`)", '["MonoGame.Templates.CSharp"]')
|
|
25705
25817
|
}),
|
|
25706
25818
|
go: external_exports.strictObject({
|
|
25707
25819
|
enabled: enabled("Go.", "go.mod or go.work"),
|
|
@@ -25717,7 +25829,8 @@ var ToolchainsSchema = external_exports.strictObject({
|
|
|
25717
25829
|
),
|
|
25718
25830
|
version: external_exports.string().min(1).describe(`"lts" (newest LTS) or a major version such as "21". A project's .java-version or .sdkmanrc wins.`),
|
|
25719
25831
|
maven: external_exports.boolean().describe("Apache Maven (mvn). A project's mvnw works either way."),
|
|
25720
|
-
gradle: external_exports.boolean().describe("Gradle (gradle). A project's gradlew works either way.")
|
|
25832
|
+
gradle: external_exports.boolean().describe("Gradle (gradle). A project's gradlew works either way."),
|
|
25833
|
+
kotlin: external_exports.boolean().describe("Also the Kotlin compiler (kotlinc) from JetBrains' releases. Gradle builds fetch their own.")
|
|
25721
25834
|
}),
|
|
25722
25835
|
ruby: external_exports.strictObject({
|
|
25723
25836
|
enabled: enabled(
|
|
@@ -25788,6 +25901,15 @@ var ToolchainsSchema = external_exports.strictObject({
|
|
|
25788
25901
|
)
|
|
25789
25902
|
});
|
|
25790
25903
|
|
|
25904
|
+
// src/shared/apps/catalogue-gamedev.ts
|
|
25905
|
+
var GAMEDEV_APPS = [];
|
|
25906
|
+
|
|
25907
|
+
// src/shared/apps/catalogue-mobile.ts
|
|
25908
|
+
var MOBILE_APPS = [];
|
|
25909
|
+
|
|
25910
|
+
// src/shared/apps/catalogue-modding.ts
|
|
25911
|
+
var MODDING_APPS = [];
|
|
25912
|
+
|
|
25791
25913
|
// src/shared/apps/catalogue.ts
|
|
25792
25914
|
var gh = (github, asset) => ({ github, asset });
|
|
25793
25915
|
var RTK_VERSION = "1.0.1";
|
|
@@ -25797,7 +25919,7 @@ var HEADROOM_VERSION = "0.41.0";
|
|
|
25797
25919
|
var CCUSAGE_VERSION = "20.0.36";
|
|
25798
25920
|
var PLAYWRIGHT_MCP_VERSION = "0.0.83";
|
|
25799
25921
|
var CONTEXT7_MCP_VERSION = "4.4.2";
|
|
25800
|
-
var
|
|
25922
|
+
var CORE_APPS = [
|
|
25801
25923
|
// ---- agent add-ons
|
|
25802
25924
|
{
|
|
25803
25925
|
id: "rtk",
|
|
@@ -26620,6 +26742,7 @@ var APPS = [
|
|
|
26620
26742
|
cli: true
|
|
26621
26743
|
}
|
|
26622
26744
|
];
|
|
26745
|
+
var APPS = [...CORE_APPS, ...GAMEDEV_APPS, ...MODDING_APPS, ...MOBILE_APPS];
|
|
26623
26746
|
function appById(id) {
|
|
26624
26747
|
return APPS.find((a) => a.id === id);
|
|
26625
26748
|
}
|
|
@@ -26822,6 +26945,187 @@ var GithubSchema = external_exports.strictObject({
|
|
|
26822
26945
|
)
|
|
26823
26946
|
});
|
|
26824
26947
|
|
|
26948
|
+
// src/shared/accounts/kinds.ts
|
|
26949
|
+
var SERVICE_KINDS = ["epic", "steam", "unity", "cfx", "keystore", "play", "expo", "appstore"];
|
|
26950
|
+
var AGENT_CAN_USE = "The agent in the sandbox can use this sign-in while it is there.";
|
|
26951
|
+
var ONE_PLACE = "It works in one sandbox at a time: a second sandbox starts without it while the first one runs.";
|
|
26952
|
+
var SERVICE_SPECS = {
|
|
26953
|
+
epic: {
|
|
26954
|
+
kind: "epic",
|
|
26955
|
+
label: "Epic Games",
|
|
26956
|
+
usedBy: ["unreal"],
|
|
26957
|
+
sources: ["pc", "sandbox"],
|
|
26958
|
+
singleHolder: true,
|
|
26959
|
+
returns: true,
|
|
26960
|
+
maxBytes: 64 * 1024,
|
|
26961
|
+
warnings: [
|
|
26962
|
+
AGENT_CAN_USE,
|
|
26963
|
+
"A sign-in works in one place at a time: taking this PC's signs the launcher on this PC out the first time a sandbox uses it."
|
|
26964
|
+
],
|
|
26965
|
+
fields: []
|
|
26966
|
+
},
|
|
26967
|
+
steam: {
|
|
26968
|
+
kind: "steam",
|
|
26969
|
+
label: "Steam (SteamCMD)",
|
|
26970
|
+
usedBy: ["steam"],
|
|
26971
|
+
sources: ["file", "sandbox"],
|
|
26972
|
+
singleHolder: true,
|
|
26973
|
+
returns: true,
|
|
26974
|
+
maxBytes: 768 * 1024,
|
|
26975
|
+
warnings: [
|
|
26976
|
+
AGENT_CAN_USE + " It can upload builds and workshop items to your Steam apps.",
|
|
26977
|
+
ONE_PLACE,
|
|
26978
|
+
"No password is kept: sign in once with sbx-steam login in a sandbox (Steam Guard asks there)."
|
|
26979
|
+
],
|
|
26980
|
+
fields: []
|
|
26981
|
+
},
|
|
26982
|
+
unity: {
|
|
26983
|
+
kind: "unity",
|
|
26984
|
+
label: "Unity",
|
|
26985
|
+
usedBy: ["unity"],
|
|
26986
|
+
sources: ["pc", "file", "typed", "sandbox"],
|
|
26987
|
+
singleHolder: true,
|
|
26988
|
+
returns: true,
|
|
26989
|
+
maxBytes: 256 * 1024,
|
|
26990
|
+
warnings: [
|
|
26991
|
+
AGENT_CAN_USE,
|
|
26992
|
+
ONE_PLACE,
|
|
26993
|
+
"A Pro seat is handed back when the sandbox stops cleanly; a sandbox closed abruptly may keep it until you return it."
|
|
26994
|
+
],
|
|
26995
|
+
fields: [
|
|
26996
|
+
{ name: "email", label: "Unity ID email", secret: false, optional: true },
|
|
26997
|
+
{ name: "password", label: "Unity ID password", secret: true, optional: true },
|
|
26998
|
+
{ name: "serial", label: "Serial (Plus or Pro; empty for Personal)", secret: true, optional: true }
|
|
26999
|
+
]
|
|
27000
|
+
},
|
|
27001
|
+
cfx: {
|
|
27002
|
+
kind: "cfx",
|
|
27003
|
+
label: "Cfx.re (FiveM / RedM server key)",
|
|
27004
|
+
usedBy: ["fivem"],
|
|
27005
|
+
sources: ["typed"],
|
|
27006
|
+
singleHolder: false,
|
|
27007
|
+
returns: false,
|
|
27008
|
+
maxBytes: 4 * 1024,
|
|
27009
|
+
warnings: [AGENT_CAN_USE + " Anyone with the key can run a server under your Cfx.re account."],
|
|
27010
|
+
fields: [
|
|
27011
|
+
{ name: "licenseKey", label: "Server licence key (cfxk_...)", secret: true, pattern: /^cfxk_[A-Za-z0-9_]+$/ },
|
|
27012
|
+
{
|
|
27013
|
+
name: "steamWebApiKey",
|
|
27014
|
+
label: "Steam Web API key (optional)",
|
|
27015
|
+
secret: true,
|
|
27016
|
+
optional: true,
|
|
27017
|
+
pattern: /^[A-F0-9]{32}$/
|
|
27018
|
+
}
|
|
27019
|
+
]
|
|
27020
|
+
},
|
|
27021
|
+
keystore: {
|
|
27022
|
+
kind: "keystore",
|
|
27023
|
+
label: "Android upload keystore",
|
|
27024
|
+
usedBy: ["android"],
|
|
27025
|
+
sources: ["file"],
|
|
27026
|
+
singleHolder: false,
|
|
27027
|
+
returns: false,
|
|
27028
|
+
maxBytes: 512 * 1024,
|
|
27029
|
+
warnings: [AGENT_CAN_USE + " It can sign app updates as you; keep a backup of the keystore elsewhere."],
|
|
27030
|
+
fields: [
|
|
27031
|
+
{ name: "storePassword", label: "Keystore password", secret: true },
|
|
27032
|
+
{ name: "keyAlias", label: "Key alias", secret: false },
|
|
27033
|
+
{ name: "keyPassword", label: "Key password", secret: true }
|
|
27034
|
+
]
|
|
27035
|
+
},
|
|
27036
|
+
play: {
|
|
27037
|
+
kind: "play",
|
|
27038
|
+
label: "Google Play (service account)",
|
|
27039
|
+
usedBy: ["android"],
|
|
27040
|
+
sources: ["file"],
|
|
27041
|
+
singleHolder: false,
|
|
27042
|
+
returns: false,
|
|
27043
|
+
maxBytes: 128 * 1024,
|
|
27044
|
+
warnings: [AGENT_CAN_USE + " It can publish to Google Play with what the service account is allowed."],
|
|
27045
|
+
fields: []
|
|
27046
|
+
},
|
|
27047
|
+
expo: {
|
|
27048
|
+
kind: "expo",
|
|
27049
|
+
label: "Expo (EAS)",
|
|
27050
|
+
usedBy: ["reactNative"],
|
|
27051
|
+
sources: ["typed"],
|
|
27052
|
+
singleHolder: false,
|
|
27053
|
+
returns: false,
|
|
27054
|
+
maxBytes: 4 * 1024,
|
|
27055
|
+
warnings: [AGENT_CAN_USE + " It can start EAS builds and submissions on your Expo account."],
|
|
27056
|
+
fields: [{ name: "token", label: "Expo access token", secret: true }]
|
|
27057
|
+
},
|
|
27058
|
+
appstore: {
|
|
27059
|
+
kind: "appstore",
|
|
27060
|
+
label: "App Store Connect API key",
|
|
27061
|
+
usedBy: ["reactNative", "flutter"],
|
|
27062
|
+
sources: ["file", "typed"],
|
|
27063
|
+
singleHolder: false,
|
|
27064
|
+
returns: false,
|
|
27065
|
+
maxBytes: 16 * 1024,
|
|
27066
|
+
warnings: [AGENT_CAN_USE + " It can upload and submit apps with what the key is allowed."],
|
|
27067
|
+
fields: [
|
|
27068
|
+
{ name: "issuerId", label: "Issuer ID", secret: false },
|
|
27069
|
+
{ name: "keyId", label: "Key ID", secret: false, pattern: /^[A-Z0-9]{10}$/ }
|
|
27070
|
+
]
|
|
27071
|
+
}
|
|
27072
|
+
};
|
|
27073
|
+
var HANDOFF_PARTS = ["state", "accounts"];
|
|
27074
|
+
|
|
27075
|
+
// src/core/schema/accounts.ts
|
|
27076
|
+
function share(kind, how) {
|
|
27077
|
+
const spec = SERVICE_SPECS[kind];
|
|
27078
|
+
return external_exports.strictObject({
|
|
27079
|
+
share: external_exports.boolean().describe(
|
|
27080
|
+
"Hand your saved " + spec.label + " sign-in to sandboxes that use " + spec.usedBy.join(" or ") + " (" + how + "). Kept encrypted on this PC; " + spec.warnings.join(" ") + " Yours only: a project file can only turn it off."
|
|
27081
|
+
)
|
|
27082
|
+
});
|
|
27083
|
+
}
|
|
27084
|
+
var AccountsSchema = external_exports.strictObject({
|
|
27085
|
+
epic: share("epic", "sign in to the launcher once in a sandbox, or take this PC's: sandbox account import epic"),
|
|
27086
|
+
steam: share(
|
|
27087
|
+
"steam",
|
|
27088
|
+
"sign in once with sbx-steam login, or: sandbox account import steam --from <steamcmd folder>"
|
|
27089
|
+
),
|
|
27090
|
+
unity: share("unity", "sign in once in a sandbox, or take this PC's licence: sandbox account import unity"),
|
|
27091
|
+
cfx: share("cfx", "sandbox account login cfx"),
|
|
27092
|
+
keystore: share("keystore", "sandbox account import keystore --from <upload.jks>"),
|
|
27093
|
+
play: share("play", "sandbox account import play --from <service-account.json>"),
|
|
27094
|
+
expo: share("expo", "sandbox account login expo"),
|
|
27095
|
+
appstore: share("appstore", "sandbox account import appstore --from <AuthKey.p8>")
|
|
27096
|
+
}).describe(
|
|
27097
|
+
"Service sign-ins for sandboxes (game stores, engines, app signing). Manage them in Accounts: sandbox account status."
|
|
27098
|
+
);
|
|
27099
|
+
|
|
27100
|
+
// src/core/schema/pc-installs.ts
|
|
27101
|
+
var pick2 = (item, what, example) => external_exports.union([external_exports.boolean(), external_exports.array(item)]).describe(
|
|
27102
|
+
what + " of this PC, read-only in the sandbox under C:\\PcInstalls: true = all of them, false = none, or a list (e.g. " + example + "). The agent can read their files."
|
|
27103
|
+
);
|
|
27104
|
+
var PcInstallsSchema = external_exports.strictObject({
|
|
27105
|
+
steamGames: pick2(
|
|
27106
|
+
external_exports.number().int().positive(),
|
|
27107
|
+
"Steam games (true maps each library; a list of app IDs maps only those games)",
|
|
27108
|
+
"[480, 730]"
|
|
27109
|
+
),
|
|
27110
|
+
epicGames: pick2(
|
|
27111
|
+
external_exports.string().regex(/^[A-Za-z0-9._-]{1,100}$/),
|
|
27112
|
+
"Epic Games Launcher games (by their app name)",
|
|
27113
|
+
'["Fortnite"]'
|
|
27114
|
+
),
|
|
27115
|
+
unrealEngines: pick2(
|
|
27116
|
+
external_exports.string().regex(/^(UE_)?\d+\.\d+$/),
|
|
27117
|
+
"Unreal Engine versions installed with the Epic Games Launcher",
|
|
27118
|
+
'["5.4"]'
|
|
27119
|
+
),
|
|
27120
|
+
unityEditors: pick2(
|
|
27121
|
+
external_exports.string().regex(/^\d+\.\d+\.\d+[abfp]\d+$/),
|
|
27122
|
+
"Unity editors installed with Unity Hub",
|
|
27123
|
+
'["6000.0.32f1"]'
|
|
27124
|
+
)
|
|
27125
|
+
}).describe(
|
|
27126
|
+
"Games, engines and editors installed on this PC, mapped read-only into sandboxes (no copy, no room on the sandbox's disk)."
|
|
27127
|
+
);
|
|
27128
|
+
|
|
26825
27129
|
// src/core/schema/config.ts
|
|
26826
27130
|
var RESERVED_ENV_PREFIX = /^(AGENT_|GIT_|GH_|GITHUB_|NODE_|NPM_CONFIG_(USERCONFIG|GLOBALCONFIG|PREFIX|SCRIPT_SHELL)|SSL_|CLAUDE|ANTHROPIC_|OPENAI_|CODEX_|GEMINI_|GOOGLE_|COPILOT_|AWS_|AZURE_)/i;
|
|
26827
27131
|
var RESERVED_ENV_SUFFIX = /(_PROXY|_BASE_URL|_ENDPOINT|_CA_BUNDLE|_CA_CERTS)$/i;
|
|
@@ -26883,6 +27187,8 @@ var ConfigSchema = external_exports.strictObject({
|
|
|
26883
27187
|
network: NetworkSchema,
|
|
26884
27188
|
vpn: VpnSchema,
|
|
26885
27189
|
github: GithubSchema,
|
|
27190
|
+
accounts: AccountsSchema,
|
|
27191
|
+
pcInstalls: PcInstallsSchema,
|
|
26886
27192
|
provisioning: ProvisioningSchema,
|
|
26887
27193
|
downloads: DownloadsSchema,
|
|
26888
27194
|
toolchains: ToolchainsSchema,
|
|
@@ -26935,6 +27241,8 @@ var LocalOverridesSchema = external_exports.strictObject({
|
|
|
26935
27241
|
network: NetworkSchema.pick({ blockPrivateRanges: true, blockHosts: true }).partial(),
|
|
26936
27242
|
// A project may turn the kill switch on, never off, and never choose a VPN, a server, a file or a login.
|
|
26937
27243
|
vpn: VpnSchema.pick({ killSwitch: true }).partial(),
|
|
27244
|
+
// A project may only turn a sign-in off (policy: OFF_IS_SAFER); pcInstalls is never here (folders of this PC).
|
|
27245
|
+
accounts: external_exports.strictObject(import_lodash.default.mapValues(AccountsSchema.shape, (shape) => shape.partial())).partial(),
|
|
26938
27246
|
provisioning: ProvisioningSchema.pick({ copyFromHost: true, fallbackToInstall: true, refresh: true }).extend({ git: GitSchema.partial(), terminal: toggle("Windows Terminal as the sandbox window.").partial() }).partial(),
|
|
26939
27247
|
downloads: DownloadsSchema.partial(),
|
|
26940
27248
|
// Every toolchain setting, each one optional (a project usually only switches languages on or pins a version).
|
|
@@ -27323,6 +27631,49 @@ function copyTreeTolerant(from, to, skip = () => false) {
|
|
|
27323
27631
|
return { copied, vanished };
|
|
27324
27632
|
}
|
|
27325
27633
|
|
|
27634
|
+
// src/shared/io/bounded.ts
|
|
27635
|
+
import fs5 from "node:fs";
|
|
27636
|
+
function readBoundedFile(file3, max, hooks = {}) {
|
|
27637
|
+
try {
|
|
27638
|
+
if (!fs5.lstatSync(file3).isFile()) return null;
|
|
27639
|
+
} catch {
|
|
27640
|
+
return null;
|
|
27641
|
+
}
|
|
27642
|
+
let fd = null;
|
|
27643
|
+
try {
|
|
27644
|
+
fd = fs5.openSync(file3, "r");
|
|
27645
|
+
const stat = fs5.fstatSync(fd);
|
|
27646
|
+
if (!stat.isFile() || stat.size > max) return null;
|
|
27647
|
+
hooks.afterStat?.();
|
|
27648
|
+
const buffer = Buffer.alloc(max + 1);
|
|
27649
|
+
let total = 0;
|
|
27650
|
+
while (total < buffer.length) {
|
|
27651
|
+
const read = fs5.readSync(fd, buffer, total, buffer.length - total, total);
|
|
27652
|
+
if (read === 0) break;
|
|
27653
|
+
total += read;
|
|
27654
|
+
}
|
|
27655
|
+
return total > max ? null : buffer.subarray(0, total);
|
|
27656
|
+
} catch {
|
|
27657
|
+
return null;
|
|
27658
|
+
} finally {
|
|
27659
|
+
if (fd !== null) fs5.closeSync(fd);
|
|
27660
|
+
}
|
|
27661
|
+
}
|
|
27662
|
+
|
|
27663
|
+
// src/shared/io/text.ts
|
|
27664
|
+
function decodeText(bytes) {
|
|
27665
|
+
if (bytes.length >= 2 && bytes[0] === 255 && bytes[1] === 254)
|
|
27666
|
+
return { text: bytes.subarray(2).toString("utf16le"), encoding: "utf16le" };
|
|
27667
|
+
if (bytes.length >= 3 && bytes[0] === 239 && bytes[1] === 187 && bytes[2] === 191)
|
|
27668
|
+
return { text: bytes.subarray(3).toString("utf8"), encoding: "utf8bom" };
|
|
27669
|
+
return { text: bytes.toString("utf8"), encoding: "utf8" };
|
|
27670
|
+
}
|
|
27671
|
+
function encodeText(text, encoding) {
|
|
27672
|
+
if (encoding === "utf16le") return Buffer.concat([Buffer.from([255, 254]), Buffer.from(text, "utf16le")]);
|
|
27673
|
+
if (encoding === "utf8bom") return Buffer.concat([Buffer.from([239, 187, 191]), Buffer.from(text, "utf8")]);
|
|
27674
|
+
return Buffer.from(text, "utf8");
|
|
27675
|
+
}
|
|
27676
|
+
|
|
27326
27677
|
// src/shared/channel/run-dir.ts
|
|
27327
27678
|
function safeId(id) {
|
|
27328
27679
|
return IdSchema.parse(id);
|
|
@@ -27331,10 +27682,10 @@ function now() {
|
|
|
27331
27682
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
27332
27683
|
}
|
|
27333
27684
|
var scan = (schema, dir) => {
|
|
27334
|
-
if (!
|
|
27685
|
+
if (!fs6.existsSync(dir)) return { valid: [], invalid: [] };
|
|
27335
27686
|
const valid = [];
|
|
27336
27687
|
const invalid = [];
|
|
27337
|
-
for (const name of
|
|
27688
|
+
for (const name of fs6.readdirSync(dir)) {
|
|
27338
27689
|
if (name.endsWith(".tmp")) continue;
|
|
27339
27690
|
const message = /^[A-Za-z0-9_-]{1,64}\.json$/.test(name) ? readValid(schema, path7.join(dir, name)) : null;
|
|
27340
27691
|
if (message) valid.push(message);
|
|
@@ -27448,14 +27799,14 @@ var logsDir = path8.join(dataDir, "logs");
|
|
|
27448
27799
|
var run = new RunDir(dataDir);
|
|
27449
27800
|
|
|
27450
27801
|
// src/guest/runtime/log.ts
|
|
27451
|
-
|
|
27802
|
+
fs7.mkdirSync(logsDir, { recursive: true });
|
|
27452
27803
|
var logFile = path9.join(
|
|
27453
27804
|
logsDir,
|
|
27454
27805
|
(process.env.AGENT_LOG_PREFIX ?? "guest") + "-" + (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-") + ".log"
|
|
27455
27806
|
);
|
|
27456
27807
|
var append = (line) => {
|
|
27457
27808
|
try {
|
|
27458
|
-
|
|
27809
|
+
fs7.appendFileSync(logFile, line + "\n");
|
|
27459
27810
|
} catch {
|
|
27460
27811
|
}
|
|
27461
27812
|
};
|
|
@@ -27469,7 +27820,7 @@ function warn(message) {
|
|
|
27469
27820
|
}
|
|
27470
27821
|
|
|
27471
27822
|
// src/guest/runtime/session.ts
|
|
27472
|
-
import
|
|
27823
|
+
import fs11 from "node:fs";
|
|
27473
27824
|
import path14 from "node:path";
|
|
27474
27825
|
|
|
27475
27826
|
// src/shared/download/http.ts
|
|
@@ -27501,7 +27852,7 @@ async function fetchText(url2) {
|
|
|
27501
27852
|
}
|
|
27502
27853
|
|
|
27503
27854
|
// src/shared/download/archive.ts
|
|
27504
|
-
import
|
|
27855
|
+
import fs9 from "node:fs";
|
|
27505
27856
|
import path12 from "node:path";
|
|
27506
27857
|
import crypto from "node:crypto";
|
|
27507
27858
|
|
|
@@ -27533,13 +27884,13 @@ var SYSTEM = {
|
|
|
27533
27884
|
};
|
|
27534
27885
|
|
|
27535
27886
|
// src/shared/scripts.ts
|
|
27536
|
-
import
|
|
27887
|
+
import fs8 from "node:fs";
|
|
27537
27888
|
import path11 from "node:path";
|
|
27538
27889
|
import { fileURLToPath } from "node:url";
|
|
27539
27890
|
var HERE = path11.dirname(fileURLToPath(import.meta.url));
|
|
27540
27891
|
function sandboxScriptsDir() {
|
|
27541
27892
|
const candidates = [path11.resolve(HERE, "..", "sandbox"), path11.resolve(HERE, "..", "..", "sandbox")];
|
|
27542
|
-
return candidates.find((dir) =>
|
|
27893
|
+
return candidates.find((dir) => fs8.existsSync(path11.join(dir, "boot", "bootstrap.ps1"))) ?? candidates[candidates.length - 1];
|
|
27543
27894
|
}
|
|
27544
27895
|
function scriptArgs(name, args = []) {
|
|
27545
27896
|
return [
|
|
@@ -27570,15 +27921,15 @@ function stagingFolder(destination) {
|
|
|
27570
27921
|
}
|
|
27571
27922
|
function moveIntoPlace(work, destination) {
|
|
27572
27923
|
safeRemove(destination, path12.dirname(destination));
|
|
27573
|
-
|
|
27574
|
-
|
|
27924
|
+
fs9.mkdirSync(path12.dirname(destination), { recursive: true });
|
|
27925
|
+
fs9.renameSync(work, destination);
|
|
27575
27926
|
}
|
|
27576
27927
|
async function extractArchive(archive, destination, members2 = []) {
|
|
27577
|
-
|
|
27928
|
+
fs9.mkdirSync(destination, { recursive: true });
|
|
27578
27929
|
let status = await spawnAsync(SYSTEM.tar(), ["-xf", archive, "-C", destination, ...members2]);
|
|
27579
27930
|
if (status !== 0 && /\.(zip|nupkg)$/i.test(archive)) {
|
|
27580
27931
|
const zip = archive.endsWith(".zip") ? archive : archive + ".zip";
|
|
27581
|
-
if (zip !== archive)
|
|
27932
|
+
if (zip !== archive) fs9.copyFileSync(archive, zip);
|
|
27582
27933
|
status = await spawnAsync(
|
|
27583
27934
|
SYSTEM.powershell(),
|
|
27584
27935
|
scriptArgs("expand-archive.ps1", ["-Archive", zip, "-Destination", destination])
|
|
@@ -27587,8 +27938,8 @@ async function extractArchive(archive, destination, members2 = []) {
|
|
|
27587
27938
|
if (status !== 0) throw new Error("Could not extract " + archive);
|
|
27588
27939
|
}
|
|
27589
27940
|
function findFile(root, name, maxDepth = 4) {
|
|
27590
|
-
if (maxDepth < 0 || !
|
|
27591
|
-
const entries2 =
|
|
27941
|
+
if (maxDepth < 0 || !fs9.existsSync(root)) return null;
|
|
27942
|
+
const entries2 = fs9.readdirSync(root, { withFileTypes: true });
|
|
27592
27943
|
for (const entry of entries2)
|
|
27593
27944
|
if (entry.isFile() && entry.name.toLowerCase() === name.toLowerCase()) return path12.join(root, entry.name);
|
|
27594
27945
|
for (const entry of entries2)
|
|
@@ -27600,7 +27951,7 @@ function findFile(root, name, maxDepth = 4) {
|
|
|
27600
27951
|
}
|
|
27601
27952
|
|
|
27602
27953
|
// src/shared/download/downloader.ts
|
|
27603
|
-
import
|
|
27954
|
+
import fs10 from "node:fs";
|
|
27604
27955
|
import path13 from "node:path";
|
|
27605
27956
|
import crypto2 from "node:crypto";
|
|
27606
27957
|
import { Readable, Transform } from "node:stream";
|
|
@@ -27620,15 +27971,15 @@ var Downloader = class {
|
|
|
27620
27971
|
*/
|
|
27621
27972
|
async file(url2, destination, expected = null) {
|
|
27622
27973
|
const sums = typeof expected === "string" || expected === null ? { sha256: expected } : expected;
|
|
27623
|
-
if (this.requireChecksum && !sums.sha256?.trim() && !sums.sha512?.trim()) {
|
|
27974
|
+
if (this.requireChecksum && !sums.sha256?.trim() && !sums.sha512?.trim() && !sums.sha1?.trim() && !sums.verify) {
|
|
27624
27975
|
throw new Error(
|
|
27625
27976
|
"Refusing to download " + path13.basename(destination) + " (" + url2 + "): no checksum is published for it, and downloads.requireChecksum is on. Turn that setting off to allow downloads that cannot be verified."
|
|
27626
27977
|
);
|
|
27627
27978
|
}
|
|
27628
27979
|
const response = await fetchRetry(url2, {}, 3, 20 * 60 * 1e3);
|
|
27629
27980
|
if (!response.body) throw new Error("Empty response for " + url2);
|
|
27630
|
-
|
|
27631
|
-
const checks = ["sha256", "sha512"].flatMap((kind) => {
|
|
27981
|
+
fs10.mkdirSync(path13.dirname(destination), { recursive: true });
|
|
27982
|
+
const checks = ["sha256", "sha512", "sha1"].flatMap((kind) => {
|
|
27632
27983
|
const want = sums[kind]?.trim().toLowerCase();
|
|
27633
27984
|
return want ? [{ want, hash: crypto2.createHash(kind) }] : [];
|
|
27634
27985
|
});
|
|
@@ -27657,12 +28008,13 @@ var Downloader = class {
|
|
|
27657
28008
|
});
|
|
27658
28009
|
const partial2 = destination + ".part";
|
|
27659
28010
|
try {
|
|
27660
|
-
await pipeline(Readable.fromWeb(response.body), tap,
|
|
28011
|
+
await pipeline(Readable.fromWeb(response.body), tap, fs10.createWriteStream(partial2));
|
|
27661
28012
|
if (checks.some((c) => c.hash.digest("hex") !== c.want)) throw new Error("Checksum mismatch for " + url2);
|
|
27662
|
-
|
|
27663
|
-
|
|
28013
|
+
if (sums.verify) await sums.verify(partial2);
|
|
28014
|
+
fs10.rmSync(destination, { force: true });
|
|
28015
|
+
fs10.renameSync(partial2, destination);
|
|
27664
28016
|
} finally {
|
|
27665
|
-
|
|
28017
|
+
fs10.rmSync(partial2, { force: true });
|
|
27666
28018
|
}
|
|
27667
28019
|
}
|
|
27668
28020
|
/**
|
|
@@ -27673,7 +28025,12 @@ var Downloader = class {
|
|
|
27673
28025
|
const work = stagingFolder(destination);
|
|
27674
28026
|
try {
|
|
27675
28027
|
const archive = path13.join(work, options.fileName ?? path13.basename(new URL(url2).pathname));
|
|
27676
|
-
await this.file(url2, archive, {
|
|
28028
|
+
await this.file(url2, archive, {
|
|
28029
|
+
sha256: options.sha256,
|
|
28030
|
+
sha512: options.sha512,
|
|
28031
|
+
sha1: options.sha1,
|
|
28032
|
+
...options.verify ? { verify: options.verify } : {}
|
|
28033
|
+
});
|
|
27677
28034
|
const extracted = path13.join(work, "x");
|
|
27678
28035
|
await extractArchive(archive, extracted, options.members);
|
|
27679
28036
|
let root = extracted;
|
|
@@ -27764,7 +28121,7 @@ var githubAssetFromPage = async (repo, pattern, searchOlder) => {
|
|
|
27764
28121
|
|
|
27765
28122
|
// src/guest/runtime/session.ts
|
|
27766
28123
|
var session = JSON.parse(
|
|
27767
|
-
|
|
28124
|
+
fs11.readFileSync(path14.join(launchDir, "session.json"), "utf8").replace(/^\uFEFF/, "")
|
|
27768
28125
|
);
|
|
27769
28126
|
downloader.requireChecksum = session.downloads?.requireChecksum === true;
|
|
27770
28127
|
var workspace = process.env.AGENT_WORKSPACE ?? session.workspace;
|
|
@@ -27795,7 +28152,7 @@ function startRelays() {
|
|
|
27795
28152
|
}
|
|
27796
28153
|
|
|
27797
28154
|
// src/guest/audit/process-audit.ts
|
|
27798
|
-
import
|
|
28155
|
+
import fs13 from "node:fs";
|
|
27799
28156
|
import path16 from "node:path";
|
|
27800
28157
|
import { spawnSync } from "node:child_process";
|
|
27801
28158
|
|
|
@@ -27877,12 +28234,12 @@ function parseProcessEvents(xml, attribution) {
|
|
|
27877
28234
|
}
|
|
27878
28235
|
|
|
27879
28236
|
// src/guest/runtime/fs.ts
|
|
27880
|
-
import
|
|
28237
|
+
import fs12 from "node:fs";
|
|
27881
28238
|
function exists(p) {
|
|
27882
|
-
return
|
|
28239
|
+
return fs12.existsSync(p);
|
|
27883
28240
|
}
|
|
27884
28241
|
function mkdirp(p) {
|
|
27885
|
-
|
|
28242
|
+
fs12.mkdirSync(p, { recursive: true });
|
|
27886
28243
|
return p;
|
|
27887
28244
|
}
|
|
27888
28245
|
|
|
@@ -27917,7 +28274,7 @@ function startProcessCollector(roots = () => []) {
|
|
|
27917
28274
|
const { lines, last: newest } = parseProcessEvents(r.stdout ?? "", { attributor, roots: roots() });
|
|
27918
28275
|
if (newest) last = newest;
|
|
27919
28276
|
if (lines.length)
|
|
27920
|
-
|
|
28277
|
+
fs13.writeFileSync(
|
|
27921
28278
|
path16.join(mkdirp(run.auditDir), Date.now() + "-" + process.pid + ".jsonl"),
|
|
27922
28279
|
lines.join("\n") + "\n"
|
|
27923
28280
|
);
|
|
@@ -27960,7 +28317,68 @@ function safely(what, work) {
|
|
|
27960
28317
|
}
|
|
27961
28318
|
|
|
27962
28319
|
// src/guest/runtime/secrets.ts
|
|
27963
|
-
import
|
|
28320
|
+
import fs14 from "node:fs";
|
|
28321
|
+
|
|
28322
|
+
// src/shared/accounts/payloads.ts
|
|
28323
|
+
var KB = 1024;
|
|
28324
|
+
var base643 = (maxBytes) => external_exports.string().min(4).max(maxBytes).regex(/^[A-Za-z0-9+/]+={0,2}$/);
|
|
28325
|
+
var secretText = (max) => external_exports.string().min(1).max(max).regex(/^[^\r\n]+$/);
|
|
28326
|
+
var EpicPayloadSchema = external_exports.strictObject({
|
|
28327
|
+
data: external_exports.string().min(16).max(16384).regex(/^[A-Za-z0-9+/=_-]+$/)
|
|
28328
|
+
});
|
|
28329
|
+
var SteamPayloadSchema = external_exports.strictObject({
|
|
28330
|
+
account: external_exports.string().regex(/^[A-Za-z0-9_]{1,64}$/),
|
|
28331
|
+
configVdf: external_exports.string().min(1).max(256 * KB),
|
|
28332
|
+
sentries: external_exports.array(external_exports.strictObject({ name: external_exports.string().regex(/^ssfn\d{1,40}$/), base64: base643(64 * KB) })).max(4),
|
|
28333
|
+
/** Reserved for the Steam client's own login (very likely not portable between Windows users). */
|
|
28334
|
+
client: base643(256 * KB).optional()
|
|
28335
|
+
});
|
|
28336
|
+
var UnityPayloadSchema = external_exports.strictObject({
|
|
28337
|
+
ulf: external_exports.string().min(1).max(128 * KB).optional(),
|
|
28338
|
+
email: external_exports.string().email().max(256).optional(),
|
|
28339
|
+
password: secretText(1024).optional(),
|
|
28340
|
+
serial: secretText(64).optional()
|
|
28341
|
+
});
|
|
28342
|
+
var CfxPayloadSchema = external_exports.strictObject({
|
|
28343
|
+
licenseKey: external_exports.string().max(256).regex(/^cfxk_[A-Za-z0-9_]+$/),
|
|
28344
|
+
steamWebApiKey: external_exports.string().regex(/^[A-F0-9]{32}$/).optional()
|
|
28345
|
+
});
|
|
28346
|
+
var KeystorePayloadSchema = external_exports.strictObject({
|
|
28347
|
+
fileName: external_exports.string().regex(/^[A-Za-z0-9._-]{1,100}\.(jks|keystore|p12)$/i),
|
|
28348
|
+
jksBase64: base643(256 * KB),
|
|
28349
|
+
storePassword: secretText(1024),
|
|
28350
|
+
keyAlias: secretText(256),
|
|
28351
|
+
keyPassword: secretText(1024)
|
|
28352
|
+
});
|
|
28353
|
+
var PlayPayloadSchema = external_exports.strictObject({
|
|
28354
|
+
serviceAccountJson: external_exports.string().min(2).max(64 * KB).refine((text) => {
|
|
28355
|
+
try {
|
|
28356
|
+
const parsed = JSON.parse(text);
|
|
28357
|
+
return typeof parsed === "object" && parsed !== null && parsed.type === "service_account";
|
|
28358
|
+
} catch {
|
|
28359
|
+
return false;
|
|
28360
|
+
}
|
|
28361
|
+
}, 'not a Google service account key (its "type" is not "service_account")')
|
|
28362
|
+
});
|
|
28363
|
+
var ExpoPayloadSchema = external_exports.strictObject({
|
|
28364
|
+
token: external_exports.string().regex(/^[A-Za-z0-9_-]{8,512}$/)
|
|
28365
|
+
});
|
|
28366
|
+
var AppstorePayloadSchema = external_exports.strictObject({
|
|
28367
|
+
issuerId: external_exports.string().uuid(),
|
|
28368
|
+
keyId: external_exports.string().regex(/^[A-Z0-9]{10}$/),
|
|
28369
|
+
p8: external_exports.string().max(8 * KB).regex(/^-----BEGIN PRIVATE KEY-----\r?\n[A-Za-z0-9+/=\r\n]+-----END PRIVATE KEY-----\s*$/)
|
|
28370
|
+
});
|
|
28371
|
+
var ServiceAccountsSchema = external_exports.strictObject({
|
|
28372
|
+
epic: EpicPayloadSchema.optional(),
|
|
28373
|
+
steam: SteamPayloadSchema.optional(),
|
|
28374
|
+
unity: UnityPayloadSchema.optional(),
|
|
28375
|
+
cfx: CfxPayloadSchema.optional(),
|
|
28376
|
+
keystore: KeystorePayloadSchema.optional(),
|
|
28377
|
+
play: PlayPayloadSchema.optional(),
|
|
28378
|
+
expo: ExpoPayloadSchema.optional(),
|
|
28379
|
+
appstore: AppstorePayloadSchema.optional()
|
|
28380
|
+
});
|
|
28381
|
+
var LaunchIdSchema = external_exports.string().regex(/^[A-Za-z0-9-]{1,64}$/);
|
|
27964
28382
|
|
|
27965
28383
|
// src/shared/github/token.ts
|
|
27966
28384
|
var MIN_LENGTH = 20;
|
|
@@ -27985,6 +28403,8 @@ var SecretsFileSchema = external_exports.strictObject({
|
|
|
27985
28403
|
wireguardConfig: external_exports.string().min(1).max(32 * 1024).optional(),
|
|
27986
28404
|
/** The GitHub token you saved for sandboxes (github.shareToken), only with git access "full". */
|
|
27987
28405
|
githubToken: GithubTokenSchema.optional(),
|
|
28406
|
+
/** Your saved service sign-ins (accounts.<kind>.share): each goes to its tool's own files at boot. */
|
|
28407
|
+
serviceAccounts: ServiceAccountsSchema.optional(),
|
|
27988
28408
|
/** projects.liveFolders "hcs": this launch's key for signed live-folder requests (live.ts). */
|
|
27989
28409
|
liveFoldersKey: external_exports.string().regex(/^[0-9a-f]{64}$/).optional()
|
|
27990
28410
|
});
|
|
@@ -28015,12 +28435,12 @@ function takeSecrets(id) {
|
|
|
28015
28435
|
const file3 = run.secretFile(id);
|
|
28016
28436
|
let text;
|
|
28017
28437
|
try {
|
|
28018
|
-
if (
|
|
28019
|
-
text =
|
|
28438
|
+
if (fs14.statSync(file3).size > MAX_BYTES) throw new Error("too big");
|
|
28439
|
+
text = fs14.readFileSync(file3, "utf8").replace(/^\uFEFF/, "");
|
|
28020
28440
|
} catch {
|
|
28021
28441
|
return {};
|
|
28022
28442
|
} finally {
|
|
28023
|
-
|
|
28443
|
+
fs14.rmSync(file3, { force: true });
|
|
28024
28444
|
}
|
|
28025
28445
|
try {
|
|
28026
28446
|
const parsed = SecretsFileSchema.safeParse(JSON.parse(text));
|
|
@@ -28056,15 +28476,15 @@ function withRequestSecrets(req) {
|
|
|
28056
28476
|
}
|
|
28057
28477
|
|
|
28058
28478
|
// src/guest/daemon/daemon.ts
|
|
28059
|
-
import
|
|
28479
|
+
import fs67 from "node:fs";
|
|
28060
28480
|
|
|
28061
28481
|
// src/guest/setup/claude-mem.ts
|
|
28062
|
-
import
|
|
28482
|
+
import fs16 from "node:fs";
|
|
28063
28483
|
import os4 from "node:os";
|
|
28064
28484
|
import path19 from "node:path";
|
|
28065
28485
|
|
|
28066
28486
|
// src/guest/runtime/process.ts
|
|
28067
|
-
import
|
|
28487
|
+
import fs15 from "node:fs";
|
|
28068
28488
|
import os3 from "node:os";
|
|
28069
28489
|
import path18 from "node:path";
|
|
28070
28490
|
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
@@ -28093,24 +28513,24 @@ function scriptOutput(name, args = [], options = {}) {
|
|
|
28093
28513
|
return execOutput(SYSTEM.powershell(), scriptArgs(name, args), options);
|
|
28094
28514
|
}
|
|
28095
28515
|
function runScriptWithJson(name, param, data, args = []) {
|
|
28096
|
-
const dir =
|
|
28516
|
+
const dir = fs15.mkdtempSync(path18.join(os3.tmpdir(), "sbx-"));
|
|
28097
28517
|
const file3 = path18.join(dir, "input.json");
|
|
28098
28518
|
try {
|
|
28099
|
-
|
|
28519
|
+
fs15.writeFileSync(file3, JSON.stringify(data), "utf8");
|
|
28100
28520
|
runScript(name, ["-" + param, file3, ...args]);
|
|
28101
28521
|
} finally {
|
|
28102
|
-
|
|
28522
|
+
fs15.rmSync(dir, { recursive: true, force: true });
|
|
28103
28523
|
}
|
|
28104
28524
|
}
|
|
28105
28525
|
function robocopy(from, to, files = []) {
|
|
28106
28526
|
if (!isWin) {
|
|
28107
28527
|
if (!files.length) {
|
|
28108
|
-
|
|
28528
|
+
fs15.cpSync(from, to, { recursive: true });
|
|
28109
28529
|
return;
|
|
28110
28530
|
}
|
|
28111
|
-
|
|
28112
|
-
for (const f of files.filter((f2) =>
|
|
28113
|
-
|
|
28531
|
+
fs15.mkdirSync(to, { recursive: true });
|
|
28532
|
+
for (const f of files.filter((f2) => fs15.existsSync(path18.join(from, f2))))
|
|
28533
|
+
fs15.copyFileSync(path18.join(from, f), path18.join(to, f));
|
|
28114
28534
|
return;
|
|
28115
28535
|
}
|
|
28116
28536
|
const what = files.length ? files : ["/E"];
|
|
@@ -28168,12 +28588,12 @@ var claudeMemEnabled = () => session.claudeProfile.syncClaudeMem && !dryRun;
|
|
|
28168
28588
|
var databaseFingerprint = (dir) => {
|
|
28169
28589
|
const parts2 = [];
|
|
28170
28590
|
const walk = (folder) => {
|
|
28171
|
-
for (const entry of
|
|
28591
|
+
for (const entry of fs16.readdirSync(folder, { withFileTypes: true })) {
|
|
28172
28592
|
const full = path19.join(folder, entry.name);
|
|
28173
28593
|
if (entry.isDirectory()) walk(full);
|
|
28174
28594
|
else if (entry.isFile() && /\.(db|sqlite3?)(-wal)?$/i.test(entry.name)) {
|
|
28175
28595
|
try {
|
|
28176
|
-
const s =
|
|
28596
|
+
const s = fs16.statSync(full);
|
|
28177
28597
|
parts2.push(full + ":" + s.size + ":" + s.mtimeMs);
|
|
28178
28598
|
} catch {
|
|
28179
28599
|
}
|
|
@@ -28187,33 +28607,33 @@ var lastSaved = null;
|
|
|
28187
28607
|
var SQLITE_HEADER = "SQLite format 3\0";
|
|
28188
28608
|
var looksLikeSqlite = (file3) => {
|
|
28189
28609
|
if (!exists(file3)) return true;
|
|
28190
|
-
const fd =
|
|
28610
|
+
const fd = fs16.openSync(file3, "r");
|
|
28191
28611
|
try {
|
|
28192
28612
|
const head = Buffer.alloc(16);
|
|
28193
|
-
return
|
|
28613
|
+
return fs16.readSync(fd, head, 0, 16, 0) === 16 && head.toString("latin1") === SQLITE_HEADER;
|
|
28194
28614
|
} finally {
|
|
28195
|
-
|
|
28615
|
+
fs16.closeSync(fd);
|
|
28196
28616
|
}
|
|
28197
28617
|
};
|
|
28198
28618
|
var MAX_BACKUPS = 3;
|
|
28199
28619
|
var BACKUP_EVERY_MS = 6 * 3600 * 1e3;
|
|
28200
28620
|
var keepBackup = (previous, dir) => {
|
|
28201
28621
|
if (!exists(previous)) return;
|
|
28202
|
-
const backups = exists(dir) ?
|
|
28622
|
+
const backups = exists(dir) ? fs16.readdirSync(dir).filter((n) => /^\d{13}$/.test(n)).sort() : [];
|
|
28203
28623
|
const newest = Number(backups[backups.length - 1] ?? 0);
|
|
28204
28624
|
if (Date.now() - newest < BACKUP_EVERY_MS) {
|
|
28205
|
-
|
|
28625
|
+
fs16.rmSync(previous, { recursive: true, force: true });
|
|
28206
28626
|
return;
|
|
28207
28627
|
}
|
|
28208
|
-
|
|
28628
|
+
fs16.renameSync(previous, path19.join(mkdirp(dir), String(Date.now())));
|
|
28209
28629
|
for (const old of [...backups, String(Date.now())].slice(0, -MAX_BACKUPS))
|
|
28210
|
-
|
|
28630
|
+
fs16.rmSync(path19.join(dir, old), { recursive: true, force: true });
|
|
28211
28631
|
};
|
|
28212
28632
|
function saveClaudeMem() {
|
|
28213
28633
|
if (!claudeMemEnabled() || !exists(claudeMemPaths.local)) return;
|
|
28214
28634
|
const { store: store2, local } = claudeMemPaths;
|
|
28215
|
-
const
|
|
28216
|
-
if (
|
|
28635
|
+
const fingerprint3 = databaseFingerprint(local);
|
|
28636
|
+
if (fingerprint3 === lastSaved && exists(store2)) return;
|
|
28217
28637
|
if (!looksLikeSqlite(path19.join(local, "claude-mem.db"))) {
|
|
28218
28638
|
warn(
|
|
28219
28639
|
"claude-mem: the local database does not look valid, so it was not saved over the stored copy (" + local + ")."
|
|
@@ -28222,22 +28642,22 @@ function saveClaudeMem() {
|
|
|
28222
28642
|
}
|
|
28223
28643
|
const incoming = store2 + ".incoming";
|
|
28224
28644
|
const previous = store2 + ".previous";
|
|
28225
|
-
|
|
28645
|
+
fs16.rmSync(incoming, { recursive: true, force: true });
|
|
28226
28646
|
copyTreeTolerant(local, incoming, (name) => /\.(pid|lock)$|-journal$|-shm$/i.test(name));
|
|
28227
|
-
|
|
28228
|
-
if (exists(store2))
|
|
28647
|
+
fs16.rmSync(previous, { recursive: true, force: true });
|
|
28648
|
+
if (exists(store2)) fs16.renameSync(store2, previous);
|
|
28229
28649
|
try {
|
|
28230
|
-
|
|
28650
|
+
fs16.renameSync(incoming, store2);
|
|
28231
28651
|
} catch (e) {
|
|
28232
|
-
if (exists(previous))
|
|
28652
|
+
if (exists(previous)) fs16.renameSync(previous, store2);
|
|
28233
28653
|
throw e;
|
|
28234
28654
|
}
|
|
28235
28655
|
keepBackup(previous, store2 + ".backups");
|
|
28236
|
-
lastSaved =
|
|
28656
|
+
lastSaved = fingerprint3;
|
|
28237
28657
|
}
|
|
28238
28658
|
|
|
28239
28659
|
// src/guest/agents/local-state.ts
|
|
28240
|
-
import
|
|
28660
|
+
import fs17 from "node:fs";
|
|
28241
28661
|
import path21 from "node:path";
|
|
28242
28662
|
|
|
28243
28663
|
// src/guest/agents/agent-files.ts
|
|
@@ -28278,32 +28698,32 @@ function agentLocalStates() {
|
|
|
28278
28698
|
function localStateVars() {
|
|
28279
28699
|
return Object.fromEntries(agentLocalStates().map((s) => [s.env, s.local]));
|
|
28280
28700
|
}
|
|
28281
|
-
var databaseFiles = (dir, keep) => exists(dir) ?
|
|
28701
|
+
var databaseFiles = (dir, keep) => exists(dir) ? fs17.readdirSync(dir, { withFileTypes: true }).flatMap((e) => e.isFile() && keep(e.name) ? [e.name] : []) : [];
|
|
28282
28702
|
var looksLikeSqlite2 = (file3) => {
|
|
28283
|
-
const fd =
|
|
28703
|
+
const fd = fs17.openSync(file3, "r");
|
|
28284
28704
|
try {
|
|
28285
28705
|
const head = Buffer.alloc(16);
|
|
28286
|
-
return
|
|
28706
|
+
return fs17.readSync(fd, head, 0, 16, 0) === 16 && head.toString("latin1") === SQLITE_HEADER2;
|
|
28287
28707
|
} finally {
|
|
28288
|
-
|
|
28708
|
+
fs17.closeSync(fd);
|
|
28289
28709
|
}
|
|
28290
28710
|
};
|
|
28291
28711
|
var copyFiles = (from, to, names) => {
|
|
28292
|
-
|
|
28712
|
+
fs17.rmSync(to, { recursive: true, force: true });
|
|
28293
28713
|
mkdirp(to);
|
|
28294
|
-
for (const name of names)
|
|
28714
|
+
for (const name of names) fs17.copyFileSync(path21.join(from, name), path21.join(to, name));
|
|
28295
28715
|
};
|
|
28296
28716
|
var swapIn = (incoming, store2) => {
|
|
28297
28717
|
const previous = store2 + ".previous";
|
|
28298
|
-
|
|
28299
|
-
if (exists(store2))
|
|
28718
|
+
fs17.rmSync(previous, { recursive: true, force: true });
|
|
28719
|
+
if (exists(store2)) fs17.renameSync(store2, previous);
|
|
28300
28720
|
try {
|
|
28301
|
-
|
|
28721
|
+
fs17.renameSync(incoming, store2);
|
|
28302
28722
|
} catch (e) {
|
|
28303
|
-
if (exists(previous))
|
|
28723
|
+
if (exists(previous)) fs17.renameSync(previous, store2);
|
|
28304
28724
|
throw e;
|
|
28305
28725
|
}
|
|
28306
|
-
|
|
28726
|
+
fs17.rmSync(previous, { recursive: true, force: true });
|
|
28307
28727
|
};
|
|
28308
28728
|
function held(s) {
|
|
28309
28729
|
if (!isWin) return false;
|
|
@@ -28312,7 +28732,7 @@ function held(s) {
|
|
|
28312
28732
|
);
|
|
28313
28733
|
}
|
|
28314
28734
|
var fingerprint = (dir) => databaseFiles(dir, isCopyableDatabaseFile).sort().map((n) => {
|
|
28315
|
-
const st =
|
|
28735
|
+
const st = fs17.statSync(path21.join(dir, n));
|
|
28316
28736
|
return n + ":" + st.size + ":" + st.mtimeMs;
|
|
28317
28737
|
}).join("|");
|
|
28318
28738
|
var saved = /* @__PURE__ */ new Map();
|
|
@@ -28331,7 +28751,7 @@ function snapshotWhileRunning(s, print) {
|
|
|
28331
28751
|
return;
|
|
28332
28752
|
}
|
|
28333
28753
|
const incoming = s.store + ".incoming";
|
|
28334
|
-
|
|
28754
|
+
fs17.rmSync(incoming, { recursive: true, force: true });
|
|
28335
28755
|
mkdirp(incoming);
|
|
28336
28756
|
for (const name of databaseFiles(s.local, (n) => isCopyableDatabaseFile(n) && !/-wal$/i.test(n))) {
|
|
28337
28757
|
const db = new sqlite.DatabaseSync(path21.join(s.local, name), { readOnly: true });
|
|
@@ -28378,7 +28798,7 @@ function saveLocalState() {
|
|
|
28378
28798
|
}
|
|
28379
28799
|
|
|
28380
28800
|
// src/guest/daemon/exec.ts
|
|
28381
|
-
import { spawn as
|
|
28801
|
+
import { spawn as spawn6 } from "node:child_process";
|
|
28382
28802
|
|
|
28383
28803
|
// src/guest/setup/environment.ts
|
|
28384
28804
|
import path23 from "node:path";
|
|
@@ -28497,11 +28917,11 @@ function withRegistryPath(env) {
|
|
|
28497
28917
|
}
|
|
28498
28918
|
|
|
28499
28919
|
// src/guest/daemon/project-provisioner.ts
|
|
28500
|
-
import
|
|
28501
|
-
import
|
|
28920
|
+
import fs57 from "node:fs";
|
|
28921
|
+
import path71 from "node:path";
|
|
28502
28922
|
|
|
28503
28923
|
// src/guest/boot/boot-env.ts
|
|
28504
|
-
import
|
|
28924
|
+
import fs18 from "node:fs";
|
|
28505
28925
|
import path24 from "node:path";
|
|
28506
28926
|
|
|
28507
28927
|
// src/guest/boot/project-env.ts
|
|
@@ -28535,18 +28955,18 @@ function baseEnvFor(boot, current = process.env) {
|
|
|
28535
28955
|
var file2 = () => path24.join(localDir, "boot-env.json");
|
|
28536
28956
|
function readBootEnv() {
|
|
28537
28957
|
try {
|
|
28538
|
-
return BootEnvSchema.safeParse(JSON.parse(
|
|
28958
|
+
return BootEnvSchema.safeParse(JSON.parse(fs18.readFileSync(file2(), "utf8"))).data ?? null;
|
|
28539
28959
|
} catch {
|
|
28540
28960
|
return null;
|
|
28541
28961
|
}
|
|
28542
28962
|
}
|
|
28543
28963
|
|
|
28544
28964
|
// src/guest/boot/guide.ts
|
|
28545
|
-
import
|
|
28965
|
+
import fs20 from "node:fs";
|
|
28546
28966
|
import path27 from "node:path";
|
|
28547
28967
|
|
|
28548
28968
|
// src/guest/apps/find-exe.ts
|
|
28549
|
-
import
|
|
28969
|
+
import fs19 from "node:fs";
|
|
28550
28970
|
import path25 from "node:path";
|
|
28551
28971
|
var MAX_DEPTH = 7;
|
|
28552
28972
|
var MAX_ENTRIES = 5e4;
|
|
@@ -28562,7 +28982,7 @@ function findExe(root, exe) {
|
|
|
28562
28982
|
for (const dir of queue) {
|
|
28563
28983
|
let entries2;
|
|
28564
28984
|
try {
|
|
28565
|
-
entries2 =
|
|
28985
|
+
entries2 = fs19.readdirSync(dir, { withFileTypes: true });
|
|
28566
28986
|
} catch {
|
|
28567
28987
|
continue;
|
|
28568
28988
|
}
|
|
@@ -28605,7 +29025,7 @@ function installedRtk() {
|
|
|
28605
29025
|
var BEGIN = "<!-- agent-sandbox:begin (generated every boot, do not edit) -->";
|
|
28606
29026
|
var END = "<!-- agent-sandbox:end -->";
|
|
28607
29027
|
var mirrorLine = () => {
|
|
28608
|
-
const drives = (session.substDrives ?? []).filter((d) =>
|
|
29028
|
+
const drives = (session.substDrives ?? []).filter((d) => fs20.existsSync(d.letter + ":\\"));
|
|
28609
29029
|
if (!drives.length) return [];
|
|
28610
29030
|
return [
|
|
28611
29031
|
"- " + drives.map((d) => d.letter + ":").join(", ") + " = mapped folders at their PC paths (subst onto `" + drives.map((d) => d.target).join("`, `") + "`; real-path tools may print that form)."
|
|
@@ -28635,12 +29055,12 @@ function sandboxGuide(toolSummary, lan = "blocked", projects = [], addons = [])
|
|
|
28635
29055
|
].join("\n");
|
|
28636
29056
|
}
|
|
28637
29057
|
function upsertGuide(file3, guide) {
|
|
28638
|
-
|
|
28639
|
-
const current =
|
|
29058
|
+
fs20.mkdirSync(path27.dirname(file3), { recursive: true });
|
|
29059
|
+
const current = fs20.existsSync(file3) ? fs20.readFileSync(file3, "utf8") : "";
|
|
28640
29060
|
const start = current.indexOf(BEGIN);
|
|
28641
29061
|
const end = current.indexOf(END);
|
|
28642
29062
|
const without = start >= 0 && end > start ? current.slice(0, start) + current.slice(end + END.length) : current;
|
|
28643
|
-
|
|
29063
|
+
fs20.writeFileSync(file3, without.trimEnd() + (without.trim() ? "\n\n" : "") + guide + "\n", "utf8");
|
|
28644
29064
|
}
|
|
28645
29065
|
function managedClaudeMd() {
|
|
28646
29066
|
return path27.join(
|
|
@@ -28651,7 +29071,7 @@ function managedClaudeMd() {
|
|
|
28651
29071
|
var headroomRuns = () => {
|
|
28652
29072
|
try {
|
|
28653
29073
|
const file3 = path27.join(path27.dirname(managedClaudeMd()), "managed-settings.json");
|
|
28654
|
-
const settings = JSON.parse(
|
|
29074
|
+
const settings = JSON.parse(fs20.readFileSync(file3, "utf8"));
|
|
28655
29075
|
return typeof settings.env?.ANTHROPIC_BASE_URL === "string";
|
|
28656
29076
|
} catch {
|
|
28657
29077
|
return false;
|
|
@@ -28668,21 +29088,21 @@ function addonLines() {
|
|
|
28668
29088
|
function writeGuides(toolSummary, lan, projects = []) {
|
|
28669
29089
|
const guide = sandboxGuide(toolSummary, lan, projects, addonLines());
|
|
28670
29090
|
const managed = managedClaudeMd();
|
|
28671
|
-
|
|
28672
|
-
|
|
28673
|
-
|
|
29091
|
+
fs20.mkdirSync(path27.dirname(managed), { recursive: true });
|
|
29092
|
+
fs20.writeFileSync(managed, guide + "\n", "utf8");
|
|
29093
|
+
fs20.writeFileSync(path27.join(dataDir, "SANDBOX.md"), guide + "\n", "utf8");
|
|
28674
29094
|
upsertGuide(path27.join(stateDir, "codex", "AGENTS.md"), guide);
|
|
28675
29095
|
upsertGuide(path27.join(stateDir, "gemini", ".gemini", "GEMINI.md"), guide);
|
|
28676
29096
|
removeGuide(path27.join(claudeDir, "CLAUDE.md"));
|
|
28677
29097
|
return managed;
|
|
28678
29098
|
}
|
|
28679
29099
|
var removeGuide = (file3) => {
|
|
28680
|
-
if (!
|
|
28681
|
-
const current =
|
|
29100
|
+
if (!fs20.existsSync(file3)) return;
|
|
29101
|
+
const current = fs20.readFileSync(file3, "utf8");
|
|
28682
29102
|
const start = current.indexOf(BEGIN);
|
|
28683
29103
|
const end = current.indexOf(END);
|
|
28684
29104
|
if (start >= 0 && end > start)
|
|
28685
|
-
|
|
29105
|
+
fs20.writeFileSync(file3, (current.slice(0, start) + current.slice(end + END.length)).trim() + "\n", "utf8");
|
|
28686
29106
|
};
|
|
28687
29107
|
|
|
28688
29108
|
// src/guest/runtime/project-context.ts
|
|
@@ -28719,7 +29139,7 @@ function saveProjectStatus(name, workspace2, phase, message, databases, summary)
|
|
|
28719
29139
|
}
|
|
28720
29140
|
|
|
28721
29141
|
// src/guest/setup/hooks.ts
|
|
28722
|
-
import
|
|
29142
|
+
import fs21 from "node:fs";
|
|
28723
29143
|
import path28 from "node:path";
|
|
28724
29144
|
import { spawnSync as spawnSync3 } from "node:child_process";
|
|
28725
29145
|
var commandFor = (file3) => {
|
|
@@ -28741,7 +29161,7 @@ function projectHooks(name, cwd) {
|
|
|
28741
29161
|
var hooksOf = (stage, target) => {
|
|
28742
29162
|
const dir = path28.join(target.root, stage);
|
|
28743
29163
|
if (!exists(dir)) return [];
|
|
28744
|
-
return
|
|
29164
|
+
return fs21.readdirSync(dir).sort().flatMap((name) => {
|
|
28745
29165
|
const command = commandFor(path28.join(dir, name));
|
|
28746
29166
|
return command ? [{ name, command }] : [];
|
|
28747
29167
|
});
|
|
@@ -28772,22 +29192,22 @@ async function runHooksAsync(stage, env, target) {
|
|
|
28772
29192
|
}
|
|
28773
29193
|
|
|
28774
29194
|
// src/guest/apps/app-installer.ts
|
|
28775
|
-
import
|
|
29195
|
+
import fs25 from "node:fs";
|
|
28776
29196
|
import path33 from "node:path";
|
|
28777
29197
|
|
|
28778
29198
|
// src/guest/toolchains/runtimes.ts
|
|
28779
29199
|
import path29 from "node:path";
|
|
28780
29200
|
|
|
28781
29201
|
// src/guest/toolchains/install.ts
|
|
28782
|
-
import
|
|
29202
|
+
import fs22 from "node:fs";
|
|
28783
29203
|
async function downloadFile(url2, file3, sha256 = null) {
|
|
28784
29204
|
const part = file3 + ".part";
|
|
28785
29205
|
try {
|
|
28786
29206
|
await downloader.file(url2, part, sha256);
|
|
28787
|
-
|
|
28788
|
-
|
|
29207
|
+
fs22.rmSync(file3, { force: true });
|
|
29208
|
+
fs22.renameSync(part, file3);
|
|
28789
29209
|
} finally {
|
|
28790
|
-
|
|
29210
|
+
fs22.rmSync(part, { force: true });
|
|
28791
29211
|
}
|
|
28792
29212
|
}
|
|
28793
29213
|
async function installFromGithub(repo, pattern, o) {
|
|
@@ -28872,7 +29292,7 @@ async function setupUv(env) {
|
|
|
28872
29292
|
}
|
|
28873
29293
|
|
|
28874
29294
|
// src/guest/apps/after-install.ts
|
|
28875
|
-
import
|
|
29295
|
+
import fs23 from "node:fs";
|
|
28876
29296
|
import path30 from "node:path";
|
|
28877
29297
|
var SYSINTERNALS_TOOLS = [
|
|
28878
29298
|
"Process Explorer",
|
|
@@ -28899,10 +29319,10 @@ async function afterInstall(entry, exe) {
|
|
|
28899
29319
|
const mesa = tool("mesa", arch === "arm64" ? "arm64" : "x64");
|
|
28900
29320
|
for (const dll of ["opengl32.dll", "libgallium_wgl.dll", "dxil.dll"]) {
|
|
28901
29321
|
if (exists(path30.join(mesa, dll)) && !exists(path30.join(dir, dll)))
|
|
28902
|
-
|
|
29322
|
+
fs23.copyFileSync(path30.join(mesa, dll), path30.join(dir, dll));
|
|
28903
29323
|
}
|
|
28904
29324
|
}
|
|
28905
|
-
if (entry.id === "godot" && !exists(path30.join(dir, "._sc_")))
|
|
29325
|
+
if (entry.id === "godot" && !exists(path30.join(dir, "._sc_"))) fs23.writeFileSync(path30.join(dir, "._sc_"), "");
|
|
28906
29326
|
if (entry.id === "sublime") mkdirp(path30.join(dir, "Data"));
|
|
28907
29327
|
if (entry.id === "sysinternals") {
|
|
28908
29328
|
for (const name of SYSINTERNALS_TOOLS) {
|
|
@@ -28940,11 +29360,19 @@ function shortcuts(apps) {
|
|
|
28940
29360
|
runScriptWithJson("new-shortcuts.ps1", "ListFile", links);
|
|
28941
29361
|
}
|
|
28942
29362
|
|
|
29363
|
+
// src/guest/apps/resolvers-gamedev.ts
|
|
29364
|
+
var GAMEDEV_RESOLVERS = {};
|
|
29365
|
+
|
|
29366
|
+
// src/guest/apps/resolvers-mobile.ts
|
|
29367
|
+
var MOBILE_RESOLVERS = {};
|
|
29368
|
+
|
|
28943
29369
|
// src/guest/apps/resolvers.ts
|
|
28944
29370
|
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;
|
|
28945
29371
|
var firstHash = (text) => /\b([0-9a-f]{64})\b/i.exec(text)?.[1].toLowerCase() ?? null;
|
|
28946
29372
|
var stripV = (tag) => tag.replace(/^v/, "");
|
|
28947
29373
|
var RESOLVERS = {
|
|
29374
|
+
...GAMEDEV_RESOLVERS,
|
|
29375
|
+
...MOBILE_RESOLVERS,
|
|
28948
29376
|
sublime: async () => {
|
|
28949
29377
|
const { latest_version: build } = await fetchJson(
|
|
28950
29378
|
"https://www.sublimetext.com/updates/4/stable_update_check"
|
|
@@ -29066,7 +29494,7 @@ async function resolve(entry) {
|
|
|
29066
29494
|
}
|
|
29067
29495
|
|
|
29068
29496
|
// src/guest/apps/unpack.ts
|
|
29069
|
-
import
|
|
29497
|
+
import fs24 from "node:fs";
|
|
29070
29498
|
import path32 from "node:path";
|
|
29071
29499
|
var sevenZip = () => tool("apps", "7zip", "7z.exe");
|
|
29072
29500
|
async function unpack(entry, file3, out, d) {
|
|
@@ -29080,7 +29508,7 @@ async function unpack(entry, file3, out, d) {
|
|
|
29080
29508
|
switch (entry.unpack ?? "archive") {
|
|
29081
29509
|
case "file": {
|
|
29082
29510
|
mkdirp(out);
|
|
29083
|
-
|
|
29511
|
+
fs24.renameSync(file3, path32.join(out, /^\//.test(entry.exe) ? path32.basename(file3) : entry.exe));
|
|
29084
29512
|
return;
|
|
29085
29513
|
}
|
|
29086
29514
|
case "nsis": {
|
|
@@ -29090,7 +29518,7 @@ async function unpack(entry, file3, out, d) {
|
|
|
29090
29518
|
await execAsync(sevenZip(), ["x", "-y", "-o" + raw, file3], { stdio: "ignore" });
|
|
29091
29519
|
const inner = findExe(raw, "/^app-64\\.7z$/");
|
|
29092
29520
|
if (inner) await execAsync(sevenZip(), ["x", "-y", "-o" + out, inner], { stdio: "ignore" });
|
|
29093
|
-
else
|
|
29521
|
+
else fs24.renameSync(raw, out);
|
|
29094
29522
|
return;
|
|
29095
29523
|
}
|
|
29096
29524
|
case "msi": {
|
|
@@ -29182,7 +29610,7 @@ var AppInstaller = class {
|
|
|
29182
29610
|
await downloader.file(d.url, file3, { sha256: d.sha256 ?? null });
|
|
29183
29611
|
await unpack(entry, file3, out, d);
|
|
29184
29612
|
}
|
|
29185
|
-
|
|
29613
|
+
fs25.writeFileSync(path33.join(out, MARKER), JSON.stringify({ id: entry.id, at: (/* @__PURE__ */ new Date()).toISOString() }));
|
|
29186
29614
|
moveIntoPlace(out, dest);
|
|
29187
29615
|
} finally {
|
|
29188
29616
|
safeRemove(work, path33.dirname(work));
|
|
@@ -29193,7 +29621,7 @@ var LOCKED_PYTHON = "3.13";
|
|
|
29193
29621
|
async function installLocked(id, kind, out) {
|
|
29194
29622
|
const lock = path33.join(launchDir, "sandbox", "addons", id);
|
|
29195
29623
|
if (kind === "npm") {
|
|
29196
|
-
for (const f of ["package.json", "package-lock.json"])
|
|
29624
|
+
for (const f of ["package.json", "package-lock.json"]) fs25.copyFileSync(path33.join(lock, f), path33.join(out, f));
|
|
29197
29625
|
const npmCli = path33.join(path33.dirname(process.execPath), "node_modules", "npm", "bin", "npm-cli.js");
|
|
29198
29626
|
await execAsync(
|
|
29199
29627
|
process.execPath,
|
|
@@ -29243,7 +29671,7 @@ async function setupApps(env, apps, o) {
|
|
|
29243
29671
|
}
|
|
29244
29672
|
|
|
29245
29673
|
// src/guest/toolchains/detect.ts
|
|
29246
|
-
import
|
|
29674
|
+
import fs26 from "node:fs";
|
|
29247
29675
|
import path34 from "node:path";
|
|
29248
29676
|
|
|
29249
29677
|
// src/core/detect/versions.ts
|
|
@@ -29328,6 +29756,16 @@ var MARKERS = {
|
|
|
29328
29756
|
rust: ["Cargo.toml", "rust-toolchain", "rust-toolchain.toml"],
|
|
29329
29757
|
msvc: ["*.vcxproj", "CMakePresets.json", "CMakeUserPresets.json"],
|
|
29330
29758
|
unreal: ["*.uproject", "*.uplugin"],
|
|
29759
|
+
unity: ["ProjectVersion.txt"],
|
|
29760
|
+
godot: ["project.godot"],
|
|
29761
|
+
steam: ["steam_appid.txt", "steam_api64.dll", "steam_api.dll"],
|
|
29762
|
+
fivem: ["fxmanifest.lua", "__resource.lua"],
|
|
29763
|
+
// Decided from file contents (host/launch/hints): Gradle's com.android plugin, an AndroidManifest.xml deeper down,
|
|
29764
|
+
// <UseMaui>, a pubspec's flutter: section, react-native / expo in package.json.
|
|
29765
|
+
android: [],
|
|
29766
|
+
flutter: [],
|
|
29767
|
+
dart: [],
|
|
29768
|
+
reactNative: [],
|
|
29331
29769
|
cpp: [
|
|
29332
29770
|
"CMakeLists.txt",
|
|
29333
29771
|
"Makefile",
|
|
@@ -29353,7 +29791,8 @@ var MARKERS = {
|
|
|
29353
29791
|
"gradlew",
|
|
29354
29792
|
".java-version",
|
|
29355
29793
|
".sdkmanrc",
|
|
29356
|
-
"*.java"
|
|
29794
|
+
"*.java",
|
|
29795
|
+
"*.kt"
|
|
29357
29796
|
],
|
|
29358
29797
|
ruby: ["Gemfile", "*.gemspec", ".ruby-version", "*.rb"],
|
|
29359
29798
|
php: ["composer.json", "artisan", ".php-version", "*.php"],
|
|
@@ -29377,7 +29816,7 @@ function workspaceEntries() {
|
|
|
29377
29816
|
if (known) return known;
|
|
29378
29817
|
const list = (dir) => {
|
|
29379
29818
|
try {
|
|
29380
|
-
return
|
|
29819
|
+
return fs26.readdirSync(dir, { withFileTypes: true });
|
|
29381
29820
|
} catch {
|
|
29382
29821
|
return [];
|
|
29383
29822
|
}
|
|
@@ -29397,7 +29836,7 @@ function versionFromFiles(files, parse5 = (t) => specFromVersionFile(t)) {
|
|
|
29397
29836
|
for (const name of files) {
|
|
29398
29837
|
const file3 = path34.join(projectWorkspace(), name);
|
|
29399
29838
|
if (!exists(file3)) continue;
|
|
29400
|
-
const spec = parse5(
|
|
29839
|
+
const spec = parse5(fs26.readFileSync(file3, "utf8"), name);
|
|
29401
29840
|
if (spec) return { spec, source: name };
|
|
29402
29841
|
}
|
|
29403
29842
|
return null;
|
|
@@ -29470,22 +29909,22 @@ var DatabaseServer = class {
|
|
|
29470
29909
|
};
|
|
29471
29910
|
|
|
29472
29911
|
// src/guest/databases/dynamodb.ts
|
|
29473
|
-
import
|
|
29912
|
+
import fs31 from "node:fs";
|
|
29474
29913
|
import path37 from "node:path";
|
|
29475
29914
|
import { spawn as spawn3 } from "node:child_process";
|
|
29476
29915
|
|
|
29477
29916
|
// src/guest/toolchains/languages/java.ts
|
|
29478
|
-
import
|
|
29917
|
+
import fs29 from "node:fs";
|
|
29479
29918
|
import path35 from "node:path";
|
|
29480
29919
|
|
|
29481
29920
|
// src/guest/toolchains/version-cache.ts
|
|
29482
|
-
import
|
|
29921
|
+
import fs28 from "node:fs";
|
|
29483
29922
|
|
|
29484
29923
|
// src/guest/toolchains/state-file.ts
|
|
29485
|
-
import
|
|
29924
|
+
import fs27 from "node:fs";
|
|
29486
29925
|
function readState(file3, schema, empty) {
|
|
29487
29926
|
try {
|
|
29488
|
-
return schema.safeParse(JSON.parse(
|
|
29927
|
+
return schema.safeParse(JSON.parse(fs27.readFileSync(file3, "utf8").replace(/^\uFEFF/, ""))).data ?? empty;
|
|
29489
29928
|
} catch {
|
|
29490
29929
|
return empty;
|
|
29491
29930
|
}
|
|
@@ -29520,7 +29959,7 @@ var VersionCache = class {
|
|
|
29520
29959
|
return cached2.value;
|
|
29521
29960
|
try {
|
|
29522
29961
|
const value = await resolve2();
|
|
29523
|
-
|
|
29962
|
+
fs28.mkdirSync(toolsDir, { recursive: true });
|
|
29524
29963
|
writeJsonAtomic(this.file(), { ...this.remembered(), [key2]: { value, at: Date.now() } });
|
|
29525
29964
|
return value;
|
|
29526
29965
|
} catch (e) {
|
|
@@ -29588,10 +30027,10 @@ var setupJdk = async (env, config2) => {
|
|
|
29588
30027
|
};
|
|
29589
30028
|
async function ensureJdk() {
|
|
29590
30029
|
const root = tool("java");
|
|
29591
|
-
const installed = exists(root) ?
|
|
30030
|
+
const installed = exists(root) ? fs29.readdirSync(root).filter((d) => exists(path35.join(root, d, "bin", "java.exe"))).sort((a, b) => b.localeCompare(a, void 0, { numeric: true })) : [];
|
|
29592
30031
|
if (installed.length) return path35.join(root, installed[0]);
|
|
29593
30032
|
const scratch = emptyEnv();
|
|
29594
|
-
await setupJdk(scratch, { enabled: true, version: "lts", maven: false, gradle: false });
|
|
30033
|
+
await setupJdk(scratch, { enabled: true, version: "lts", maven: false, gradle: false, kotlin: false });
|
|
29595
30034
|
return scratch.vars.JAVA_HOME;
|
|
29596
30035
|
}
|
|
29597
30036
|
var setupMaven = async (env) => {
|
|
@@ -29635,7 +30074,7 @@ var setupGradle = async (env) => {
|
|
|
29635
30074
|
});
|
|
29636
30075
|
}
|
|
29637
30076
|
const userHome = tool("gradle-home");
|
|
29638
|
-
|
|
30077
|
+
fs29.mkdirSync(userHome, { recursive: true });
|
|
29639
30078
|
Object.assign(env.vars, {
|
|
29640
30079
|
GRADLE_HOME: home,
|
|
29641
30080
|
GRADLE_USER_HOME: userHome,
|
|
@@ -29665,7 +30104,7 @@ async function setupJava(env, config2) {
|
|
|
29665
30104
|
}
|
|
29666
30105
|
|
|
29667
30106
|
// src/guest/databases/server.ts
|
|
29668
|
-
import
|
|
30107
|
+
import fs30 from "node:fs";
|
|
29669
30108
|
import path36 from "node:path";
|
|
29670
30109
|
import { spawn as spawn2 } from "node:child_process";
|
|
29671
30110
|
function dataFor(name) {
|
|
@@ -29674,15 +30113,15 @@ function dataFor(name) {
|
|
|
29674
30113
|
async function startServer(name, exe, args, port) {
|
|
29675
30114
|
if (await portOpen(port)) throw new Error("port " + port + " is already in use (change databases." + name + ".port)");
|
|
29676
30115
|
const logFile2 = path36.join(logsDir, name + ".log");
|
|
29677
|
-
const out =
|
|
30116
|
+
const out = fs30.openSync(logFile2, "a");
|
|
29678
30117
|
spawn2(exe, args, { detached: true, stdio: ["ignore", out, out], windowsHide: true }).unref();
|
|
29679
|
-
|
|
30118
|
+
fs30.closeSync(out);
|
|
29680
30119
|
if (!await waitForPort(port, 60))
|
|
29681
30120
|
throw new Error(name + " did not start listening on port " + port + "; see " + logFile2);
|
|
29682
30121
|
}
|
|
29683
30122
|
async function clearStaleLocks(dir, files, port) {
|
|
29684
30123
|
if (await portOpen(port)) return;
|
|
29685
|
-
for (const f of files)
|
|
30124
|
+
for (const f of files) fs30.rmSync(path36.join(dir, f), { force: true });
|
|
29686
30125
|
}
|
|
29687
30126
|
async function createOnce(data, marker, create) {
|
|
29688
30127
|
if (exists(path36.join(data, marker))) return;
|
|
@@ -29769,13 +30208,13 @@ var DynamoServer = class extends DatabaseServer {
|
|
|
29769
30208
|
);
|
|
29770
30209
|
return;
|
|
29771
30210
|
}
|
|
29772
|
-
const out =
|
|
30211
|
+
const out = fs31.openSync(path37.join(logsDir, "dynamodb-admin.log"), "a");
|
|
29773
30212
|
spawn3(
|
|
29774
30213
|
process.execPath,
|
|
29775
30214
|
[script, "--port", String(plan2.adminPort), "--dynamo-endpoint", endpoint, "--skip-default-credentials"],
|
|
29776
30215
|
{ detached: true, stdio: ["ignore", out, out], windowsHide: true, env: { ...process.env, ...aws } }
|
|
29777
30216
|
).unref();
|
|
29778
|
-
|
|
30217
|
+
fs31.closeSync(out);
|
|
29779
30218
|
if (!await waitForPort(plan2.adminPort, 30))
|
|
29780
30219
|
throw new Error("dynamodb-admin did not start; see " + path37.join(logsDir, "dynamodb-admin.log"));
|
|
29781
30220
|
env.summary.push(
|
|
@@ -29878,7 +30317,7 @@ var MysqlServer = class extends DatabaseServer {
|
|
|
29878
30317
|
};
|
|
29879
30318
|
|
|
29880
30319
|
// src/guest/databases/postgres.ts
|
|
29881
|
-
import
|
|
30320
|
+
import fs32 from "node:fs";
|
|
29882
30321
|
import path40 from "node:path";
|
|
29883
30322
|
function postgresData(version2) {
|
|
29884
30323
|
return dataFor("postgres-" + version2.split(".")[0]);
|
|
@@ -29945,7 +30384,7 @@ var PostgresServer = class extends DatabaseServer {
|
|
|
29945
30384
|
/** Every installed version's cluster shuts down cleanly through pg_ctl first. */
|
|
29946
30385
|
async stop(plan2) {
|
|
29947
30386
|
if (exists(tool("postgres"))) {
|
|
29948
|
-
for (const version2 of
|
|
30387
|
+
for (const version2 of fs32.readdirSync(tool("postgres"))) {
|
|
29949
30388
|
const data = postgresData(version2);
|
|
29950
30389
|
const pgCtl = path40.join(tool("postgres", version2), "bin", "pg_ctl.exe");
|
|
29951
30390
|
if (exists(path40.join(data, "postmaster.pid")) && exists(pgCtl))
|
|
@@ -30010,11 +30449,11 @@ async function setupDatabase(env, plan2) {
|
|
|
30010
30449
|
}
|
|
30011
30450
|
|
|
30012
30451
|
// src/guest/toolchains/tools/git.ts
|
|
30013
|
-
import
|
|
30452
|
+
import fs34 from "node:fs";
|
|
30014
30453
|
import path43 from "node:path";
|
|
30015
30454
|
|
|
30016
30455
|
// src/guest/runtime/csc.ts
|
|
30017
|
-
import
|
|
30456
|
+
import fs33 from "node:fs";
|
|
30018
30457
|
import os6 from "node:os";
|
|
30019
30458
|
import path42 from "node:path";
|
|
30020
30459
|
import crypto3 from "node:crypto";
|
|
@@ -30035,7 +30474,7 @@ function sourceOf(name) {
|
|
|
30035
30474
|
return path42.join(launchDir, "sandbox", "csharp", SOURCES[name]);
|
|
30036
30475
|
}
|
|
30037
30476
|
function sourceHash(name) {
|
|
30038
|
-
return crypto3.createHash("sha256").update(
|
|
30477
|
+
return crypto3.createHash("sha256").update(fs33.readFileSync(sourceOf(name))).digest("hex").slice(0, 12);
|
|
30039
30478
|
}
|
|
30040
30479
|
function ensureCompiled(name) {
|
|
30041
30480
|
const exe = path42.join(os6.tmpdir(), "agent-sandbox", name + "-" + sourceHash(name) + ".exe");
|
|
@@ -30076,7 +30515,7 @@ var installPortableGit = async (root) => {
|
|
|
30076
30515
|
await downloader.file(asset.url, sfx, asset.sha256);
|
|
30077
30516
|
await execAsync(sfx, ["-o" + root, "-y"], { stdio: "ignore" });
|
|
30078
30517
|
} finally {
|
|
30079
|
-
|
|
30518
|
+
fs34.rmSync(sfx, { force: true });
|
|
30080
30519
|
}
|
|
30081
30520
|
};
|
|
30082
30521
|
var installGuard = (env, access, realGit) => {
|
|
@@ -30085,13 +30524,13 @@ var installGuard = (env, access, realGit) => {
|
|
|
30085
30524
|
if (duringSession() && (exists(path43.join(dir, "git.exe")) || exists(path43.join(dir, "git.cmd")))) {
|
|
30086
30525
|
} else
|
|
30087
30526
|
try {
|
|
30088
|
-
|
|
30089
|
-
|
|
30527
|
+
fs34.copyFileSync(ensureCompiled("gitshim"), path43.join(dir, "git.exe"));
|
|
30528
|
+
fs34.rmSync(path43.join(dir, "git.cmd"), { force: true });
|
|
30090
30529
|
} catch (e) {
|
|
30091
30530
|
warn("git guard: falling back to git.cmd (" + errMsg(e) + ")");
|
|
30092
|
-
|
|
30531
|
+
fs34.writeFileSync(path43.join(dir, "git.cmd"), '@"' + process.execPath + '" "' + guard + '" %*\r\n');
|
|
30093
30532
|
}
|
|
30094
|
-
|
|
30533
|
+
fs34.writeFileSync(
|
|
30095
30534
|
path43.join(dir, "bashenv.sh"),
|
|
30096
30535
|
'git() { "' + posix(process.execPath) + '" "' + posix(guard) + '" "$@"; }\nexport -f git\n'
|
|
30097
30536
|
);
|
|
@@ -30106,7 +30545,7 @@ var installGuard = (env, access, realGit) => {
|
|
|
30106
30545
|
if (access === "readonly") {
|
|
30107
30546
|
const hooks = mkdirp(path43.join(dir, "hooks"));
|
|
30108
30547
|
for (const hook of BLOCKED_HOOKS)
|
|
30109
|
-
|
|
30548
|
+
fs34.writeFileSync(
|
|
30110
30549
|
path43.join(hooks, hook),
|
|
30111
30550
|
'#!/bin/sh\necho "git is read-only in this sandbox: ' + hook + ' refused." >&2\nexit 1\n'
|
|
30112
30551
|
);
|
|
@@ -30123,9 +30562,9 @@ var pointAtOwnCertificates = (root) => {
|
|
|
30123
30562
|
const config2 = path43.join(root, "etc", "gitconfig");
|
|
30124
30563
|
const bundle = path43.join(root, "mingw64", "etc", "ssl", "certs", "ca-bundle.crt");
|
|
30125
30564
|
if (!exists(config2) || !exists(bundle)) return;
|
|
30126
|
-
const text =
|
|
30565
|
+
const text = fs34.readFileSync(config2, "utf8");
|
|
30127
30566
|
const fixed = text.replace(/^(\s*sslCAInfo\s*=\s*).*$/gim, (_m, key2) => key2 + posix(bundle));
|
|
30128
|
-
if (fixed !== text)
|
|
30567
|
+
if (fixed !== text) fs34.writeFileSync(config2, fixed);
|
|
30129
30568
|
};
|
|
30130
30569
|
async function setupGit(env, hostCopy, refresh, access) {
|
|
30131
30570
|
const root = tool("git");
|
|
@@ -30172,7 +30611,7 @@ async function setupGit(env, hostCopy, refresh, access) {
|
|
|
30172
30611
|
}
|
|
30173
30612
|
|
|
30174
30613
|
// src/guest/toolchains/languages/go.ts
|
|
30175
|
-
import
|
|
30614
|
+
import fs35 from "node:fs";
|
|
30176
30615
|
import path44 from "node:path";
|
|
30177
30616
|
|
|
30178
30617
|
// src/guest/toolchains/package-ledger.ts
|
|
@@ -30193,12 +30632,12 @@ var PackageLedger = class {
|
|
|
30193
30632
|
* Installs each package that is not installed yet (group e.g. "npm@22.11.0"). One failing package is reported and
|
|
30194
30633
|
* skipped; it is tried again next boot.
|
|
30195
30634
|
*/
|
|
30196
|
-
async installOnce(env, group, packages,
|
|
30635
|
+
async installOnce(env, group, packages, install2) {
|
|
30197
30636
|
const todo = packages.filter((p) => !this.has(group, p));
|
|
30198
30637
|
for (const pkg of todo) {
|
|
30199
30638
|
try {
|
|
30200
30639
|
log("Installing " + pkg + " (" + group + ") ...");
|
|
30201
|
-
await
|
|
30640
|
+
await install2(pkg);
|
|
30202
30641
|
this.mark(group, pkg);
|
|
30203
30642
|
} catch (e) {
|
|
30204
30643
|
warn(
|
|
@@ -30214,8 +30653,8 @@ var PackageLedger = class {
|
|
|
30214
30653
|
}
|
|
30215
30654
|
};
|
|
30216
30655
|
var packageLedger = new PackageLedger();
|
|
30217
|
-
function installOnce(env, group, packages,
|
|
30218
|
-
return packageLedger.installOnce(env, group, packages,
|
|
30656
|
+
function installOnce(env, group, packages, install2) {
|
|
30657
|
+
return packageLedger.installOnce(env, group, packages, install2);
|
|
30219
30658
|
}
|
|
30220
30659
|
|
|
30221
30660
|
// src/guest/toolchains/languages/go.ts
|
|
@@ -30250,7 +30689,7 @@ async function setupGo(env, config2) {
|
|
|
30250
30689
|
GOTOOLCHAIN: "auto",
|
|
30251
30690
|
GOTELEMETRY: "off"
|
|
30252
30691
|
};
|
|
30253
|
-
|
|
30692
|
+
fs35.mkdirSync(vars.GOBIN, { recursive: true });
|
|
30254
30693
|
Object.assign(env.vars, vars);
|
|
30255
30694
|
env.prepend.push(path44.join(root, "bin"), vars.GOBIN);
|
|
30256
30695
|
const go = path44.join(root, "bin", "go.exe");
|
|
@@ -30264,7 +30703,7 @@ async function setupGo(env, config2) {
|
|
|
30264
30703
|
}
|
|
30265
30704
|
|
|
30266
30705
|
// src/guest/toolchains/tools/cli.ts
|
|
30267
|
-
import
|
|
30706
|
+
import fs36 from "node:fs";
|
|
30268
30707
|
import path45 from "node:path";
|
|
30269
30708
|
|
|
30270
30709
|
// src/guest/toolchains/catalogue.ts
|
|
@@ -30321,7 +30760,7 @@ function deliveredGhConfigDir() {
|
|
|
30321
30760
|
var GH_NOTE = " (log in once with: gh auth login --web --insecure-storage; it is kept between sandboxes)";
|
|
30322
30761
|
function warnKeyringLogin() {
|
|
30323
30762
|
try {
|
|
30324
|
-
const hosts =
|
|
30763
|
+
const hosts = fs36.readFileSync(path45.join(ghConfigDir(), "hosts.yml"), "utf8");
|
|
30325
30764
|
if (/^\s*user:/m.test(hosts) && !/oauth_token:/.test(hosts))
|
|
30326
30765
|
warn(
|
|
30327
30766
|
"gh: the GitHub login from an earlier sandbox was kept in Windows Credential Manager, which is wiped with each sandbox. Log in again with: gh auth login --web --insecure-storage (then it lasts)."
|
|
@@ -30342,8 +30781,8 @@ var shimOpenssl = (env) => {
|
|
|
30342
30781
|
return;
|
|
30343
30782
|
}
|
|
30344
30783
|
const shims = mkdirp(tool("shims"));
|
|
30345
|
-
|
|
30346
|
-
|
|
30784
|
+
fs36.copyFileSync(ensureCompiled("openssl"), path45.join(shims, "openssl.exe"));
|
|
30785
|
+
fs36.rmSync(path45.join(shims, "openssl.cmd"), { force: true });
|
|
30347
30786
|
env.prepend.push(shims);
|
|
30348
30787
|
env.summary.push("openssl: Git for Windows' copy");
|
|
30349
30788
|
};
|
|
@@ -30390,12 +30829,12 @@ async function setupCli(env, settings, gitAccess, refresh = false) {
|
|
|
30390
30829
|
}
|
|
30391
30830
|
|
|
30392
30831
|
// src/guest/toolchains/managers.ts
|
|
30393
|
-
import
|
|
30832
|
+
import fs37 from "node:fs";
|
|
30394
30833
|
import path46 from "node:path";
|
|
30395
30834
|
function voltaPins() {
|
|
30396
30835
|
try {
|
|
30397
30836
|
const pkg = JSON.parse(
|
|
30398
|
-
|
|
30837
|
+
fs37.readFileSync(path46.join(projectWorkspace(), "package.json"), "utf8").replace(/^\uFEFF/, "")
|
|
30399
30838
|
);
|
|
30400
30839
|
return Object.fromEntries(
|
|
30401
30840
|
Object.entries(pkg.volta ?? {}).filter(
|
|
@@ -30428,7 +30867,7 @@ async function setupVolta(env) {
|
|
|
30428
30867
|
}
|
|
30429
30868
|
for (const shim3 of ["node", "npm", "npx", "pnpm", "pnpx", "yarn", "yarnpkg"]) {
|
|
30430
30869
|
const target = path46.join(dir, shim3 + ".exe");
|
|
30431
|
-
if (!exists(target))
|
|
30870
|
+
if (!exists(target)) fs37.copyFileSync(path46.join(dir, "volta-shim.exe"), target);
|
|
30432
30871
|
}
|
|
30433
30872
|
const home = mkdirp(tool("volta-home"));
|
|
30434
30873
|
const shims = mkdirp(path46.join(home, "bin"));
|
|
@@ -30516,7 +30955,7 @@ var setupFlexBison = async (env) => {
|
|
|
30516
30955
|
};
|
|
30517
30956
|
|
|
30518
30957
|
// src/guest/toolchains/native/dotnet.ts
|
|
30519
|
-
import
|
|
30958
|
+
import fs38 from "node:fs";
|
|
30520
30959
|
import path48 from "node:path";
|
|
30521
30960
|
var DotnetMarkerSchema = external_exports.record(external_exports.string(), external_exports.boolean());
|
|
30522
30961
|
async function setupDotnet(env, config2, refresh) {
|
|
@@ -30533,7 +30972,7 @@ async function setupDotnet(env, config2, refresh) {
|
|
|
30533
30972
|
const installs = [
|
|
30534
30973
|
...config2.channels.map((c) => ["channel:" + c, ["-Channel", c]]),
|
|
30535
30974
|
...exists(globalJson) ? [
|
|
30536
|
-
["global.json:" +
|
|
30975
|
+
["global.json:" + fs38.readFileSync(globalJson, "utf8").replace(/\s+/g, ""), ["-JSonFile", globalJson]]
|
|
30537
30976
|
] : []
|
|
30538
30977
|
];
|
|
30539
30978
|
for (const [key2, args] of installs.filter(([k]) => !done[k])) {
|
|
@@ -30606,8 +31045,8 @@ var setupFrameworkReferences = async (env, targets) => {
|
|
|
30606
31045
|
staging,
|
|
30607
31046
|
{ fileName: id + ".zip" }
|
|
30608
31047
|
);
|
|
30609
|
-
|
|
30610
|
-
|
|
31048
|
+
fs38.cpSync(path48.join(staging, "build", ".NETFramework"), path48.join(root, ".NETFramework"), { recursive: true });
|
|
31049
|
+
fs38.writeFileSync(marker, version2);
|
|
30611
31050
|
} catch (e) {
|
|
30612
31051
|
warn(
|
|
30613
31052
|
".NET Framework " + target + " reference assemblies could not be installed (projects targeting it will not build): " + errMsg(e)
|
|
@@ -30618,7 +31057,7 @@ var setupFrameworkReferences = async (env, targets) => {
|
|
|
30618
31057
|
}
|
|
30619
31058
|
if (!exists(path48.join(root, ".NETFramework"))) return;
|
|
30620
31059
|
env.vars.TargetFrameworkRootPath = root + path48.sep;
|
|
30621
|
-
env.summary.push(".NET Framework targeting: " +
|
|
31060
|
+
env.summary.push(".NET Framework targeting: " + fs38.readdirSync(path48.join(root, ".NETFramework")).join(", "));
|
|
30622
31061
|
};
|
|
30623
31062
|
var setupNetFx35 = async (env) => {
|
|
30624
31063
|
if (execOutput(SYSTEM.reg(), [
|
|
@@ -30697,15 +31136,15 @@ var setupLavapipe = async (env, mesaDir) => {
|
|
|
30697
31136
|
var hasGpu = () => scriptOutput("get-gpu-names.ps1", [], { timeout: 3e4 }).split(/\r?\n/).map((n) => n.trim()).some((n) => n && !/^Microsoft (Remote Display|Basic (Render|Display))/i.test(n));
|
|
30698
31137
|
|
|
30699
31138
|
// src/guest/toolchains/native/msvc/index.ts
|
|
30700
|
-
import
|
|
31139
|
+
import fs42 from "node:fs";
|
|
30701
31140
|
import path53 from "node:path";
|
|
30702
31141
|
|
|
30703
31142
|
// src/guest/toolchains/native/msvc/environment.ts
|
|
30704
|
-
import
|
|
31143
|
+
import fs40 from "node:fs";
|
|
30705
31144
|
import path51 from "node:path";
|
|
30706
31145
|
|
|
30707
31146
|
// src/guest/toolchains/native/msvc/tree.ts
|
|
30708
|
-
import
|
|
31147
|
+
import fs39 from "node:fs";
|
|
30709
31148
|
import path50 from "node:path";
|
|
30710
31149
|
var ROOT = tool("msvc");
|
|
30711
31150
|
var MARKER2 = path50.join(ROOT, ".installed.json");
|
|
@@ -30721,7 +31160,7 @@ function hasCompiler(msvc) {
|
|
|
30721
31160
|
var InstalledSchema = external_exports.object({ msvc: external_exports.string().min(1), sdk: external_exports.string().min(1), want: external_exports.string() });
|
|
30722
31161
|
function readInstalled() {
|
|
30723
31162
|
try {
|
|
30724
|
-
return InstalledSchema.safeParse(JSON.parse(
|
|
31163
|
+
return InstalledSchema.safeParse(JSON.parse(fs39.readFileSync(MARKER2, "utf8"))).data ?? null;
|
|
30725
31164
|
} catch {
|
|
30726
31165
|
return null;
|
|
30727
31166
|
}
|
|
@@ -30771,8 +31210,8 @@ function writeVcvars(env) {
|
|
|
30771
31210
|
'set "PATH=' + env.path.join(";") + ';%PATH%"',
|
|
30772
31211
|
"exit /b 0"
|
|
30773
31212
|
];
|
|
30774
|
-
|
|
30775
|
-
|
|
31213
|
+
fs40.writeFileSync(path51.join(dir, "vcvars64.bat"), lines.join("\r\n") + "\r\n");
|
|
31214
|
+
fs40.writeFileSync(
|
|
30776
31215
|
path51.join(dir, "vcvarsall.bat"),
|
|
30777
31216
|
["@echo off", "rem Only x64 (amd64) is installed.", 'call "%~dp0vcvars64.bat"', "exit /b %errorlevel%"].join(
|
|
30778
31217
|
"\r\n"
|
|
@@ -30781,23 +31220,23 @@ function writeVcvars(env) {
|
|
|
30781
31220
|
}
|
|
30782
31221
|
function installVswhere(msvc) {
|
|
30783
31222
|
mkdirp(VSWHERE_DIR);
|
|
30784
|
-
|
|
31223
|
+
fs40.copyFileSync(ensureCompiled("vswhere"), path51.join(VSWHERE_DIR, "vswhere.exe"));
|
|
30785
31224
|
const [major, minor] = msvc.split(".").slice(2);
|
|
30786
|
-
|
|
31225
|
+
fs40.writeFileSync(
|
|
30787
31226
|
path51.join(VSWHERE_DIR, "vswhere.json"),
|
|
30788
31227
|
JSON.stringify({ installationPath: ROOT, installationVersion: "17." + (minor ?? "0") + ".0." + (major ?? "0") })
|
|
30789
31228
|
);
|
|
30790
31229
|
}
|
|
30791
31230
|
function removeTelemetry(msvc) {
|
|
30792
31231
|
try {
|
|
30793
|
-
|
|
31232
|
+
fs40.rmSync(hostBin(msvc, "vctip.exe"), { force: true });
|
|
30794
31233
|
} catch (e) {
|
|
30795
31234
|
warn("Could not remove MSVC's telemetry helper (vctip.exe); it may keep tools\\msvc locked: " + errMsg(e));
|
|
30796
31235
|
}
|
|
30797
31236
|
}
|
|
30798
31237
|
|
|
30799
31238
|
// src/guest/toolchains/native/msvc/packages.ts
|
|
30800
|
-
import
|
|
31239
|
+
import fs41 from "node:fs";
|
|
30801
31240
|
import path52 from "node:path";
|
|
30802
31241
|
var CHANNEL = "https://aka.ms/vs/17/release/channel";
|
|
30803
31242
|
var MANIFEST_DAY_MS = 24 * 60 * 60 * 1e3;
|
|
@@ -30825,9 +31264,9 @@ var SDK_MSIS = [
|
|
|
30825
31264
|
];
|
|
30826
31265
|
var manifest = async () => {
|
|
30827
31266
|
const cached2 = path52.join(ROOT, ".manifest.json");
|
|
30828
|
-
if (exists(cached2) && Date.now() -
|
|
31267
|
+
if (exists(cached2) && Date.now() - fs41.statSync(cached2).mtimeMs < MANIFEST_DAY_MS) {
|
|
30829
31268
|
try {
|
|
30830
|
-
return JSON.parse(
|
|
31269
|
+
return JSON.parse(fs41.readFileSync(cached2, "utf8"));
|
|
30831
31270
|
} catch {
|
|
30832
31271
|
}
|
|
30833
31272
|
}
|
|
@@ -30836,13 +31275,13 @@ var manifest = async () => {
|
|
|
30836
31275
|
if (!item) throw new Error("the Visual Studio channel has no package manifest");
|
|
30837
31276
|
mkdirp(ROOT);
|
|
30838
31277
|
await downloader.file(item.url, cached2);
|
|
30839
|
-
return JSON.parse(
|
|
31278
|
+
return JSON.parse(fs41.readFileSync(cached2, "utf8"));
|
|
30840
31279
|
};
|
|
30841
31280
|
var unpackVsix = async (vsix, work) => {
|
|
30842
31281
|
const out = mkdirp(path52.join(work, "vsix-" + path52.basename(vsix)));
|
|
30843
31282
|
await extractArchive(vsix, out, ["Contents"]);
|
|
30844
31283
|
const decode4 = (dir) => {
|
|
30845
|
-
for (const entry of
|
|
31284
|
+
for (const entry of fs41.readdirSync(dir, { withFileTypes: true })) {
|
|
30846
31285
|
const from = path52.join(dir, entry.name);
|
|
30847
31286
|
let name = entry.name;
|
|
30848
31287
|
try {
|
|
@@ -30850,12 +31289,12 @@ var unpackVsix = async (vsix, work) => {
|
|
|
30850
31289
|
} catch {
|
|
30851
31290
|
}
|
|
30852
31291
|
const to = path52.join(dir, name);
|
|
30853
|
-
if (to !== from)
|
|
31292
|
+
if (to !== from) fs41.renameSync(from, to);
|
|
30854
31293
|
if (entry.isDirectory()) decode4(to);
|
|
30855
31294
|
}
|
|
30856
31295
|
};
|
|
30857
31296
|
decode4(out);
|
|
30858
|
-
|
|
31297
|
+
fs41.cpSync(path52.join(out, "Contents"), ROOT, { recursive: true, force: true });
|
|
30859
31298
|
safeRemove(out, work);
|
|
30860
31299
|
};
|
|
30861
31300
|
var unpackMsi = async (msi) => {
|
|
@@ -30865,7 +31304,7 @@ var unpackMsi = async (msi) => {
|
|
|
30865
31304
|
stdio: "ignore"
|
|
30866
31305
|
});
|
|
30867
31306
|
} catch (e) {
|
|
30868
|
-
const lines = exists(logFile2) ?
|
|
31307
|
+
const lines = exists(logFile2) ? fs41.readFileSync(logFile2, "utf16le").split(/\r?\n/).filter((l) => /error|return value 3|failed/i.test(l)).slice(-4).join(" | ") : "";
|
|
30869
31308
|
throw new Error(
|
|
30870
31309
|
path52.basename(msi) + " did not unpack: " + (e instanceof Error ? e.message : String(e)) + (lines ? " (" + lines.slice(0, 600) + ")" : "")
|
|
30871
31310
|
);
|
|
@@ -30886,10 +31325,10 @@ var payloadFetcher = (work) => async (p) => {
|
|
|
30886
31325
|
};
|
|
30887
31326
|
var unpackedToolset = () => {
|
|
30888
31327
|
const toolsRoot = path52.join(ROOT, "VC", "Tools", "MSVC");
|
|
30889
|
-
return
|
|
31328
|
+
return fs41.readdirSync(toolsRoot).filter((d) => exists(hostBin(d, "cl.exe"))).sort((a, b) => a.localeCompare(b, void 0, { numeric: true })).pop();
|
|
30890
31329
|
};
|
|
30891
31330
|
async function installPackages(config2) {
|
|
30892
|
-
const { ids, pick:
|
|
31331
|
+
const { ids, pick: pick3 } = catalogue(await manifest());
|
|
30893
31332
|
const version2 = pickMsvcVersion(ids, config2.msvcVersion);
|
|
30894
31333
|
if (!version2) throw new Error("no MSVC " + config2.msvcVersion + " in the Visual Studio manifest");
|
|
30895
31334
|
const sdk = pickWindowsSdk(ids, config2.sdkVersion);
|
|
@@ -30898,13 +31337,13 @@ async function installPackages(config2) {
|
|
|
30898
31337
|
const fetchPayload = payloadFetcher(work);
|
|
30899
31338
|
log("Downloading the MSVC " + version2 + " compiler and C/C++ libraries ...");
|
|
30900
31339
|
for (const part of MSVC_PARTS) {
|
|
30901
|
-
const p =
|
|
31340
|
+
const p = pick3("microsoft.vc." + version2 + "." + part);
|
|
30902
31341
|
if (!p && REQUIRED_PARTS.some((r) => part.startsWith(r))) throw new Error("MSVC " + version2 + " has no " + part);
|
|
30903
31342
|
for (const payload2 of p?.payloads ?? []) await unpackVsix(await fetchPayload(payload2), work);
|
|
30904
31343
|
}
|
|
30905
|
-
for (const payload2 of
|
|
31344
|
+
for (const payload2 of pick3("microsoft.visualcpp.dia.sdk")?.payloads ?? [])
|
|
30906
31345
|
await unpackVsix(await fetchPayload(payload2), work);
|
|
30907
|
-
const sdkPackage =
|
|
31346
|
+
const sdkPackage = pick3(Object.keys(pick3(sdk.componentId)?.dependencies ?? {})[0] ?? "");
|
|
30908
31347
|
if (!sdkPackage?.payloads) throw new Error("the Windows SDK " + sdk.build + " package has no payloads");
|
|
30909
31348
|
log("Downloading the Windows SDK " + sdk.build + " (headers, libraries; the biggest part) ...");
|
|
30910
31349
|
const payload = (name) => sdkPackage.payloads.find((p) => p.fileName.toLowerCase() === ("installers\\" + name).toLowerCase());
|
|
@@ -30914,17 +31353,17 @@ async function installPackages(config2) {
|
|
|
30914
31353
|
if (!p) throw new Error("the Windows SDK package has no " + name);
|
|
30915
31354
|
const file3 = await fetchPayload(p);
|
|
30916
31355
|
msis.push(file3);
|
|
30917
|
-
for (const cab of msiCabs(
|
|
31356
|
+
for (const cab of msiCabs(fs41.readFileSync(file3))) {
|
|
30918
31357
|
const c = payload(cab);
|
|
30919
31358
|
if (c) await fetchPayload(c);
|
|
30920
31359
|
}
|
|
30921
31360
|
}
|
|
30922
31361
|
log("Unpacking the Windows SDK (a few minutes) ...");
|
|
30923
31362
|
for (const msi of msis) await unpackMsi(msi);
|
|
30924
|
-
for (const name of
|
|
30925
|
-
|
|
31363
|
+
for (const name of fs41.readdirSync(ROOT).filter((n) => n.toLowerCase().endsWith(".msi")))
|
|
31364
|
+
fs41.rmSync(path52.join(ROOT, name), { force: true });
|
|
30926
31365
|
safeRemove(work, ROOT);
|
|
30927
|
-
const sdkVersion =
|
|
31366
|
+
const sdkVersion = fs41.readdirSync(path52.join(ROOT, "Windows Kits", "10", "Include")).filter((d) => d.startsWith("10.0." + sdk.build)).sort().pop();
|
|
30928
31367
|
if (!sdkVersion) throw new Error("the Windows SDK did not unpack (no Include\\10.0." + sdk.build + ".*)");
|
|
30929
31368
|
const toolset = unpackedToolset();
|
|
30930
31369
|
if (!toolset) throw new Error("MSVC " + version2 + " did not unpack (no cl.exe under VC\\Tools\\MSVC)");
|
|
@@ -30938,7 +31377,7 @@ function installedMsvcEnv() {
|
|
|
30938
31377
|
}
|
|
30939
31378
|
var clearTree = () => {
|
|
30940
31379
|
if (!exists(ROOT)) return;
|
|
30941
|
-
for (const name of
|
|
31380
|
+
for (const name of fs42.readdirSync(ROOT).filter((n) => n !== ".manifest.json" && n !== ".download"))
|
|
30942
31381
|
safeRemove(path53.join(ROOT, name), ROOT);
|
|
30943
31382
|
};
|
|
30944
31383
|
async function setupMsvc(env, config2) {
|
|
@@ -30969,12 +31408,26 @@ async function setupMsvc(env, config2) {
|
|
|
30969
31408
|
}
|
|
30970
31409
|
|
|
30971
31410
|
// src/guest/toolchains/native/unreal.ts
|
|
30972
|
-
import
|
|
30973
|
-
import
|
|
31411
|
+
import os8 from "node:os";
|
|
31412
|
+
import path57 from "node:path";
|
|
31413
|
+
|
|
31414
|
+
// src/guest/toolchains/not-yet.ts
|
|
31415
|
+
function notAvailableYet(env, what) {
|
|
31416
|
+
log(what + ": not available yet (nothing installed)");
|
|
31417
|
+
env.summary.push(what + ": not available yet");
|
|
31418
|
+
}
|
|
31419
|
+
|
|
31420
|
+
// src/guest/toolchains/engines/unreal-engines.ts
|
|
31421
|
+
async function setupUnrealEngines(env, _config, _ctx) {
|
|
31422
|
+
notAvailableYet(env, "Unreal engines");
|
|
31423
|
+
}
|
|
31424
|
+
|
|
31425
|
+
// src/guest/toolchains/installers.ts
|
|
31426
|
+
import fs44 from "node:fs";
|
|
30974
31427
|
import path55 from "node:path";
|
|
30975
31428
|
|
|
30976
31429
|
// src/guest/toolchains/native/vcruntime.ts
|
|
30977
|
-
import
|
|
31430
|
+
import fs43 from "node:fs";
|
|
30978
31431
|
import path54 from "node:path";
|
|
30979
31432
|
var VC_REDIST = "https://aka.ms/vs/17/release/vc_redist.x64.exe";
|
|
30980
31433
|
var MICROSOFT_SIGNER = "CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US";
|
|
@@ -30994,7 +31447,7 @@ async function setupVcRuntime(env, summary = true) {
|
|
|
30994
31447
|
await downloadFile(VC_REDIST, installer);
|
|
30995
31448
|
}
|
|
30996
31449
|
if (signerOf(installer) !== MICROSOFT_SIGNER) {
|
|
30997
|
-
|
|
31450
|
+
fs43.rmSync(installer, { force: true });
|
|
30998
31451
|
throw new Error("vc_redist.x64.exe is not signed by Microsoft; deleted it (it is downloaded again next boot)");
|
|
30999
31452
|
}
|
|
31000
31453
|
log("Installing the Visual C++ runtime ...");
|
|
@@ -31006,9 +31459,85 @@ async function setupVcRuntime(env, summary = true) {
|
|
|
31006
31459
|
return missing;
|
|
31007
31460
|
}
|
|
31008
31461
|
|
|
31009
|
-
// src/guest/toolchains/
|
|
31010
|
-
var
|
|
31011
|
-
|
|
31462
|
+
// src/guest/toolchains/installers.ts
|
|
31463
|
+
var SIGNERS = {
|
|
31464
|
+
microsoft: MICROSOFT_SIGNER,
|
|
31465
|
+
valve: /^CN="?Valve(,| Corp)/,
|
|
31466
|
+
unity: /^CN="?Unity Technologies/
|
|
31467
|
+
};
|
|
31468
|
+
function signedBy(file3, signer) {
|
|
31469
|
+
const subject = signerOf(file3);
|
|
31470
|
+
return typeof signer === "string" ? subject === signer : signer.test(subject);
|
|
31471
|
+
}
|
|
31472
|
+
function signatureCheck(signer, what) {
|
|
31473
|
+
return (file3) => {
|
|
31474
|
+
if (!signedBy(file3, signer)) throw new Error(what + " is not signed by its vendor");
|
|
31475
|
+
};
|
|
31476
|
+
}
|
|
31477
|
+
async function signedInstaller(url2, file3, what, signer, sha256 = null) {
|
|
31478
|
+
if (!exists(file3)) {
|
|
31479
|
+
log("Downloading " + what + " ...");
|
|
31480
|
+
mkdirp(path55.dirname(file3));
|
|
31481
|
+
await downloader.file(url2, file3, { sha256, verify: signatureCheck(signer, path55.basename(file3)) });
|
|
31482
|
+
}
|
|
31483
|
+
if (!signedBy(file3, signer)) {
|
|
31484
|
+
fs44.rmSync(file3, { force: true });
|
|
31485
|
+
throw new Error(
|
|
31486
|
+
path55.basename(file3) + " is not signed by its vendor; deleted it (it is downloaded again next boot)"
|
|
31487
|
+
);
|
|
31488
|
+
}
|
|
31489
|
+
return file3;
|
|
31490
|
+
}
|
|
31491
|
+
|
|
31492
|
+
// src/guest/toolchains/native/visual-studio.ts
|
|
31493
|
+
import fs46 from "node:fs";
|
|
31494
|
+
import os7 from "node:os";
|
|
31495
|
+
import path56 from "node:path";
|
|
31496
|
+
|
|
31497
|
+
// src/guest/toolchains/persisted.ts
|
|
31498
|
+
import fs45 from "node:fs";
|
|
31499
|
+
|
|
31500
|
+
// src/shared/installs.ts
|
|
31501
|
+
var InstallRecordSchema = external_exports.object({
|
|
31502
|
+
name: external_exports.string().max(100),
|
|
31503
|
+
version: external_exports.string().max(100),
|
|
31504
|
+
sizeBytes: external_exports.number().nonnegative().nullable(),
|
|
31505
|
+
installedAt: external_exports.string().max(64),
|
|
31506
|
+
usedAt: external_exports.string().max(64)
|
|
31507
|
+
});
|
|
31508
|
+
var InstallRecordsSchema = external_exports.object({ installs: external_exports.array(InstallRecordSchema).max(1e3) });
|
|
31509
|
+
|
|
31510
|
+
// src/guest/toolchains/persisted.ts
|
|
31511
|
+
var GB = 1024 ** 3;
|
|
31512
|
+
var LOCAL_RESERVE_BYTES = 13 * GB;
|
|
31513
|
+
function freeBytes(dir, deps = {}) {
|
|
31514
|
+
try {
|
|
31515
|
+
const s = (deps.statfs ?? fs45.statfsSync)(dir);
|
|
31516
|
+
return s.bavail * s.bsize;
|
|
31517
|
+
} catch {
|
|
31518
|
+
return 0;
|
|
31519
|
+
}
|
|
31520
|
+
}
|
|
31521
|
+
var gb = (bytes) => (bytes / GB).toFixed(1) + " GB";
|
|
31522
|
+
function assertRoom(dir, needBytes, what, fix, deps = {}) {
|
|
31523
|
+
const free = freeBytes(dir, deps);
|
|
31524
|
+
if (free < needBytes)
|
|
31525
|
+
throw new Error(
|
|
31526
|
+
"not installing " + what + ": " + gb(free) + " free where it goes, it needs " + gb(needBytes) + ". " + fix
|
|
31527
|
+
);
|
|
31528
|
+
}
|
|
31529
|
+
function assertLocalRoom(needBytes, what, deps = {}) {
|
|
31530
|
+
const drive = deps.localDir ?? (process.env.SystemDrive ?? "C:") + "\\";
|
|
31531
|
+
assertRoom(
|
|
31532
|
+
drive,
|
|
31533
|
+
needBytes + LOCAL_RESERVE_BYTES,
|
|
31534
|
+
what,
|
|
31535
|
+
"The sandbox's own disk also holds the paging file and every build: give the sandbox less to install, or a smaller sandbox.pageFileMb.",
|
|
31536
|
+
deps
|
|
31537
|
+
);
|
|
31538
|
+
}
|
|
31539
|
+
|
|
31540
|
+
// src/guest/toolchains/native/vs-request.ts
|
|
31012
31541
|
var UNREAL_COMPONENTS = [
|
|
31013
31542
|
"Microsoft.VisualStudio.Workload.NativeGame",
|
|
31014
31543
|
"Microsoft.VisualStudio.Component.VC.Tools.x86.x64",
|
|
@@ -31019,17 +31548,59 @@ var UNREAL_COMPONENTS = [
|
|
|
31019
31548
|
"Component.Unreal.Ide",
|
|
31020
31549
|
"Component.Unreal"
|
|
31021
31550
|
];
|
|
31022
|
-
var
|
|
31023
|
-
|
|
31024
|
-
|
|
31025
|
-
|
|
31026
|
-
|
|
31027
|
-
var
|
|
31028
|
-
|
|
31029
|
-
|
|
31030
|
-
|
|
31031
|
-
|
|
31032
|
-
|
|
31551
|
+
var BUILD_TOOLS_COMPONENTS = [
|
|
31552
|
+
"Microsoft.VisualStudio.Workload.VCTools",
|
|
31553
|
+
"Microsoft.VisualStudio.Component.VC.Tools.x86.x64",
|
|
31554
|
+
"Microsoft.VisualStudio.Component.Windows11SDK.22621"
|
|
31555
|
+
];
|
|
31556
|
+
var isOn = (setting) => setting === true;
|
|
31557
|
+
function visualStudioWanted(t, on = isOn) {
|
|
31558
|
+
const unreal = on(t.unreal.enabled, "unreal");
|
|
31559
|
+
const flutter = on(t.flutter.enabled, "flutter") && t.flutter.windowsDesktop;
|
|
31560
|
+
const unity = on(t.unity.enabled, "unity") && t.unity.modules.includes("windows-il2cpp");
|
|
31561
|
+
const users = [...unreal ? ["unreal"] : [], ...flutter ? ["flutter"] : [], ...unity ? ["unity"] : []];
|
|
31562
|
+
if (!users.length) return null;
|
|
31563
|
+
if (unreal)
|
|
31564
|
+
return {
|
|
31565
|
+
product: "community",
|
|
31566
|
+
components: [.../* @__PURE__ */ new Set([...UNREAL_COMPONENTS, ...t.unreal.components])],
|
|
31567
|
+
for: users,
|
|
31568
|
+
licence: "toolchains.unreal.acceptLicense",
|
|
31569
|
+
accepted: t.unreal.acceptLicense
|
|
31570
|
+
};
|
|
31571
|
+
return {
|
|
31572
|
+
product: "buildtools",
|
|
31573
|
+
components: [...BUILD_TOOLS_COMPONENTS],
|
|
31574
|
+
for: users,
|
|
31575
|
+
licence: "toolchains.msvc.acceptLicense",
|
|
31576
|
+
accepted: t.msvc.acceptLicense
|
|
31577
|
+
};
|
|
31578
|
+
}
|
|
31579
|
+
|
|
31580
|
+
// src/guest/toolchains/native/visual-studio.ts
|
|
31581
|
+
var BOOTSTRAPPERS = {
|
|
31582
|
+
community: {
|
|
31583
|
+
url: "https://aka.ms/vs/17/release/vs_community.exe",
|
|
31584
|
+
file: "vs_community.exe",
|
|
31585
|
+
name: "Visual Studio Community 2022"
|
|
31586
|
+
},
|
|
31587
|
+
buildtools: {
|
|
31588
|
+
url: "https://aka.ms/vs/17/release/vs_buildtools.exe",
|
|
31589
|
+
file: "vs_buildtools.exe",
|
|
31590
|
+
name: "Visual Studio Build Tools 2022"
|
|
31591
|
+
}
|
|
31592
|
+
};
|
|
31593
|
+
var INSTALL_BYTES = {
|
|
31594
|
+
community: 7 * 1024 ** 3,
|
|
31595
|
+
buildtools: 5 * 1024 ** 3
|
|
31596
|
+
};
|
|
31597
|
+
var OK_EXIT_CODES2 = [0, 3010];
|
|
31598
|
+
var LAYOUT_ROOM_BYTES = 15 * 1024 ** 3;
|
|
31599
|
+
var ID = /^[A-Za-z0-9][A-Za-z0-9._-]{0,199}$/;
|
|
31600
|
+
var VS_DIR = tool("visualstudio");
|
|
31601
|
+
var LayoutSchema = external_exports.object({ components: external_exports.array(external_exports.string()) });
|
|
31602
|
+
var VSWHERE = path56.join(
|
|
31603
|
+
process.env["ProgramFiles(x86)"] ?? "C:\\Program Files (x86)",
|
|
31033
31604
|
"Microsoft Visual Studio",
|
|
31034
31605
|
"Installer",
|
|
31035
31606
|
"vswhere.exe"
|
|
@@ -31048,150 +31619,153 @@ function installedVs() {
|
|
|
31048
31619
|
const at = ask("installationPath");
|
|
31049
31620
|
return at ? { path: at, version: ask("installationVersion") || "installed" } : null;
|
|
31050
31621
|
}
|
|
31051
|
-
|
|
31052
|
-
|
|
31053
|
-
log("Downloading " + what + " ...");
|
|
31054
|
-
mkdirp(path55.dirname(file3));
|
|
31055
|
-
await downloadFile(url2, file3);
|
|
31056
|
-
}
|
|
31057
|
-
if (signerOf(file3) !== MICROSOFT_SIGNER) {
|
|
31058
|
-
fs43.rmSync(file3, { force: true });
|
|
31059
|
-
throw new Error(path55.basename(file3) + " is not signed by Microsoft; deleted it (it is downloaded again next boot)");
|
|
31060
|
-
}
|
|
31061
|
-
return file3;
|
|
31622
|
+
function layoutDir(product) {
|
|
31623
|
+
return path56.join(VS_DIR, product === "community" ? "layout" : "layout-buildtools");
|
|
31062
31624
|
}
|
|
31063
|
-
function
|
|
31064
|
-
|
|
31065
|
-
|
|
31066
|
-
|
|
31067
|
-
} catch {
|
|
31068
|
-
return 0;
|
|
31069
|
-
}
|
|
31070
|
-
}
|
|
31071
|
-
async function layoutInstaller(bootstrapper, ids) {
|
|
31072
|
-
const installer = path55.join(LAYOUT, "vs_community.exe");
|
|
31625
|
+
async function layoutInstaller(req, bootstrapper) {
|
|
31626
|
+
const layout = layoutDir(req.product);
|
|
31627
|
+
const marker = path56.join(layout, ".complete.json");
|
|
31628
|
+
const installer = path56.join(layout, BOOTSTRAPPERS[req.product].file);
|
|
31073
31629
|
const has = () => {
|
|
31074
|
-
if (!exists(
|
|
31630
|
+
if (!exists(marker) || !exists(installer)) return false;
|
|
31075
31631
|
try {
|
|
31076
|
-
const done = LayoutSchema.parse(JSON.parse(
|
|
31077
|
-
return
|
|
31632
|
+
const done = LayoutSchema.parse(JSON.parse(fs46.readFileSync(marker, "utf8")));
|
|
31633
|
+
return req.components.every((id) => done.components.includes(id));
|
|
31078
31634
|
} catch {
|
|
31079
31635
|
return false;
|
|
31080
31636
|
}
|
|
31081
31637
|
};
|
|
31082
31638
|
if (has()) return installer;
|
|
31083
31639
|
if (freeBytes(mkdirp(VS_DIR)) < LAYOUT_ROOM_BYTES) {
|
|
31084
|
-
warn(
|
|
31640
|
+
warn(
|
|
31641
|
+
"Visual Studio: not keeping the install files (less than 15 GB free in " + VS_DIR + "); downloading this boot"
|
|
31642
|
+
);
|
|
31085
31643
|
return null;
|
|
31086
31644
|
}
|
|
31087
31645
|
log("Saving the Visual Studio install files for later boots (~10 GB, once) ...");
|
|
31088
|
-
|
|
31646
|
+
fs46.rmSync(marker, { force: true });
|
|
31089
31647
|
const code = await spawnAsync(bootstrapper, [
|
|
31090
31648
|
"--layout",
|
|
31091
|
-
|
|
31649
|
+
layout,
|
|
31092
31650
|
"--lang",
|
|
31093
31651
|
"en-US",
|
|
31094
31652
|
"--quiet",
|
|
31095
31653
|
"--wait",
|
|
31096
|
-
...
|
|
31654
|
+
...req.components.flatMap((id) => ["--add", id])
|
|
31097
31655
|
]);
|
|
31098
31656
|
if (!OK_EXIT_CODES2.includes(code) || !exists(installer)) {
|
|
31099
|
-
warn("
|
|
31657
|
+
warn("Visual Studio: saving the install files failed (exit " + code + "); downloading this boot");
|
|
31100
31658
|
return null;
|
|
31101
31659
|
}
|
|
31102
|
-
writeJsonAtomic(
|
|
31660
|
+
writeJsonAtomic(marker, { components: [...req.components] });
|
|
31103
31661
|
return installer;
|
|
31104
31662
|
}
|
|
31105
|
-
async function
|
|
31106
|
-
const
|
|
31663
|
+
async function install(req, keepInstallFiles) {
|
|
31664
|
+
const boot = BOOTSTRAPPERS[req.product];
|
|
31665
|
+
const bootstrapper = await signedInstaller(
|
|
31666
|
+
boot.url,
|
|
31667
|
+
path56.join(VS_DIR, boot.file),
|
|
31668
|
+
"the " + boot.name + " installer",
|
|
31669
|
+
SIGNERS.microsoft
|
|
31670
|
+
);
|
|
31107
31671
|
let installer = null;
|
|
31108
|
-
if (
|
|
31672
|
+
if (keepInstallFiles) {
|
|
31109
31673
|
try {
|
|
31110
|
-
installer = await layoutInstaller(
|
|
31674
|
+
installer = await layoutInstaller(req, bootstrapper);
|
|
31111
31675
|
} catch (e) {
|
|
31112
|
-
warn("
|
|
31676
|
+
warn("Visual Studio: the offline copy failed (" + errMsg(e) + "); downloading this boot");
|
|
31113
31677
|
}
|
|
31114
31678
|
}
|
|
31115
|
-
log(
|
|
31116
|
-
"Installing Visual Studio Community 2022 with the C++ game workload" + (installer ? " from the saved install files" : " (downloads ~5-8 GB)") + " ..."
|
|
31117
|
-
);
|
|
31679
|
+
log("Installing " + boot.name + (installer ? " from the saved install files" : " (downloads ~5-8 GB)") + " ...");
|
|
31118
31680
|
const code = await spawnAsync(installer ?? bootstrapper, [
|
|
31119
31681
|
"--quiet",
|
|
31120
31682
|
"--wait",
|
|
31121
31683
|
"--norestart",
|
|
31122
31684
|
"--nocache",
|
|
31123
31685
|
...installer ? ["--noWeb"] : [],
|
|
31124
|
-
...
|
|
31686
|
+
...req.components.flatMap((id) => ["--add", id])
|
|
31125
31687
|
]);
|
|
31126
31688
|
if (!OK_EXIT_CODES2.includes(code) || !installedVs())
|
|
31127
31689
|
throw new Error(
|
|
31128
31690
|
"the Visual Studio installer failed (exit " + code + "); its logs are the dd_*.log files in " + os7.tmpdir()
|
|
31129
31691
|
);
|
|
31130
31692
|
}
|
|
31693
|
+
async function ensureVisualStudio(env, req, o) {
|
|
31694
|
+
if (!req.accepted)
|
|
31695
|
+
throw new Error(
|
|
31696
|
+
"Visual Studio (for " + req.for.join(", ") + ") is installed only with " + req.licence + " = true: it comes under Microsoft licence terms (https://visualstudio.microsoft.com/license-terms/)"
|
|
31697
|
+
);
|
|
31698
|
+
const bad = req.components.find((id) => !ID.test(id));
|
|
31699
|
+
if (bad) throw new Error('"' + bad + '" is not a Visual Studio component ID');
|
|
31700
|
+
const have = installedVs();
|
|
31701
|
+
if (have) return have;
|
|
31702
|
+
if (duringSession())
|
|
31703
|
+
throw new Error("Visual Studio is installed when the sandbox starts: restart it (sandbox restart) to get it");
|
|
31704
|
+
assertLocalRoom(INSTALL_BYTES[req.product], BOOTSTRAPPERS[req.product].name);
|
|
31705
|
+
await install(req, o.keepInstallFiles);
|
|
31706
|
+
const vs = installedVs();
|
|
31707
|
+
env.summary.push(
|
|
31708
|
+
"visual studio: " + BOOTSTRAPPERS[req.product].name + " " + vs.version + " at " + vs.path + " (for " + req.for.join(", ") + ")"
|
|
31709
|
+
);
|
|
31710
|
+
return vs;
|
|
31711
|
+
}
|
|
31712
|
+
|
|
31713
|
+
// src/guest/toolchains/native/unreal.ts
|
|
31714
|
+
var DIRECTX_URL = "https://download.microsoft.com/download/8/4/A/84A35BF1-DAFE-4AE8-82AF-AD2AE20B6B14/directx_Jun2010_redist.exe";
|
|
31131
31715
|
async function installDirectX() {
|
|
31132
|
-
const system322 =
|
|
31133
|
-
if (exists(
|
|
31716
|
+
const system322 = path57.join(process.env.WINDIR ?? "C:\\Windows", "System32");
|
|
31717
|
+
if (exists(path57.join(system322, "d3dx9_43.dll")) && exists(path57.join(system322, "XAudio2_7.dll"))) return;
|
|
31134
31718
|
const redist = await signedInstaller(
|
|
31135
31719
|
DIRECTX_URL,
|
|
31136
|
-
|
|
31137
|
-
"the DirectX End-User Runtime (~95 MB once)"
|
|
31720
|
+
path57.join(tool("visualstudio"), "directx_Jun2010_redist.exe"),
|
|
31721
|
+
"the DirectX End-User Runtime (~95 MB once)",
|
|
31722
|
+
SIGNERS.microsoft
|
|
31138
31723
|
);
|
|
31139
|
-
const unpacked =
|
|
31140
|
-
safeRemove(unpacked,
|
|
31724
|
+
const unpacked = path57.join(os8.tmpdir(), "directx-redist");
|
|
31725
|
+
safeRemove(unpacked, os8.tmpdir());
|
|
31141
31726
|
mkdirp(unpacked);
|
|
31142
|
-
if (await spawnAsync(redist, ["/Q", "/T:" + unpacked]) !== 0 || !exists(
|
|
31727
|
+
if (await spawnAsync(redist, ["/Q", "/T:" + unpacked]) !== 0 || !exists(path57.join(unpacked, "DXSETUP.exe")))
|
|
31143
31728
|
throw new Error("could not unpack the DirectX End-User Runtime");
|
|
31144
|
-
const code = await spawnAsync(
|
|
31145
|
-
safeRemove(unpacked,
|
|
31729
|
+
const code = await spawnAsync(path57.join(unpacked, "DXSETUP.exe"), ["/silent"]);
|
|
31730
|
+
safeRemove(unpacked, os8.tmpdir());
|
|
31146
31731
|
if (code !== 0) throw new Error("the DirectX End-User Runtime installer failed (exit " + code + ")");
|
|
31147
31732
|
}
|
|
31148
|
-
async function setupUnreal(env, config2) {
|
|
31733
|
+
async function setupUnreal(env, config2, ctx) {
|
|
31149
31734
|
if (!config2.acceptLicense)
|
|
31150
31735
|
throw new Error(
|
|
31151
31736
|
"Unreal tools are installed only with toolchains.unreal.acceptLicense = true: Visual Studio Community and the DirectX End-User Runtime come under Microsoft licence terms (https://visualstudio.microsoft.com/license-terms/)"
|
|
31152
31737
|
);
|
|
31153
|
-
const bad = config2.components.find((id) => !ID.test(id));
|
|
31154
|
-
if (bad) throw new Error('toolchains.unreal.components: "' + bad + '" is not a Visual Studio component ID');
|
|
31155
|
-
const ids = [.../* @__PURE__ */ new Set([...UNREAL_COMPONENTS, ...config2.components])];
|
|
31156
31738
|
if (dryRun) {
|
|
31157
|
-
log("(dry run) would install
|
|
31739
|
+
log("(dry run) would install the DirectX End-User Runtime and set up the Unreal engines");
|
|
31158
31740
|
return;
|
|
31159
31741
|
}
|
|
31160
|
-
if (!installedVs()) {
|
|
31161
|
-
const programFiles = process.env.ProgramFiles ?? "C:\\Program Files";
|
|
31162
|
-
const free = freeBytes(programFiles);
|
|
31163
|
-
if (free < INSTALL_ROOM_BYTES)
|
|
31164
|
-
throw new Error(
|
|
31165
|
-
"not installing Visual Studio: the sandbox disk has " + (free / 1024 ** 3).toFixed(1) + " GB free and it needs 20 GB (7 GB for Visual Studio, the rest for builds and the paging file)"
|
|
31166
|
-
);
|
|
31167
|
-
await installVisualStudio(config2, ids);
|
|
31168
|
-
}
|
|
31169
31742
|
await installDirectX();
|
|
31743
|
+
await setupUnrealEngines(env, config2, ctx);
|
|
31170
31744
|
const vs = installedVs();
|
|
31171
31745
|
env.summary.push(
|
|
31172
|
-
"unreal: Visual Studio
|
|
31746
|
+
"unreal: " + (vs ? "Visual Studio " + vs.version + " (C++ game workload, Windows 11 SDK, Unreal support); " : "") + "DirectX End-User Runtime; get the engine from the Epic Games Launcher (Start menu)"
|
|
31173
31747
|
);
|
|
31174
31748
|
}
|
|
31175
31749
|
|
|
31176
31750
|
// src/guest/toolchains/native/rust.ts
|
|
31177
|
-
import
|
|
31751
|
+
import path59 from "node:path";
|
|
31178
31752
|
|
|
31179
31753
|
// src/guest/toolchains/native/binstall.ts
|
|
31180
|
-
import
|
|
31181
|
-
import
|
|
31754
|
+
import fs47 from "node:fs";
|
|
31755
|
+
import path58 from "node:path";
|
|
31182
31756
|
var ensureBinstall = async (cargoBin) => {
|
|
31183
|
-
const target =
|
|
31757
|
+
const target = path58.join(cargoBin, "cargo-binstall.exe");
|
|
31184
31758
|
if (exists(target)) return true;
|
|
31185
31759
|
try {
|
|
31186
31760
|
const dir = tool("cargo-binstall");
|
|
31187
|
-
if (!exists(
|
|
31761
|
+
if (!exists(path58.join(dir, "cargo-binstall.exe"))) {
|
|
31188
31762
|
await installFromGithub("cargo-bins/cargo-binstall", binstallAsset(arch), {
|
|
31189
31763
|
dest: dir,
|
|
31190
31764
|
what: "cargo-binstall for prebuilt Rust tools (~10 MB once)",
|
|
31191
31765
|
locate: "cargo-binstall.exe"
|
|
31192
31766
|
});
|
|
31193
31767
|
}
|
|
31194
|
-
|
|
31768
|
+
fs47.copyFileSync(path58.join(dir, "cargo-binstall.exe"), target);
|
|
31195
31769
|
return true;
|
|
31196
31770
|
} catch (e) {
|
|
31197
31771
|
warn("cargo-binstall unavailable, compiling crates with cargo install instead: " + errMsg(e));
|
|
@@ -31199,14 +31773,14 @@ var ensureBinstall = async (cargoBin) => {
|
|
|
31199
31773
|
}
|
|
31200
31774
|
};
|
|
31201
31775
|
function crateInstaller(cargoHome, cargoEnv) {
|
|
31202
|
-
const cargo =
|
|
31776
|
+
const cargo = path58.join(cargoHome, "bin", "cargo.exe");
|
|
31203
31777
|
let binstall = null;
|
|
31204
31778
|
const binstallEnv = {
|
|
31205
31779
|
...cargoEnv,
|
|
31206
31780
|
env: { ...cargoEnv.env ?? process.env, BINSTALL_DISABLE_TELEMETRY: "true" }
|
|
31207
31781
|
};
|
|
31208
31782
|
return async (crate) => {
|
|
31209
|
-
binstall ??= ensureBinstall(
|
|
31783
|
+
binstall ??= ensureBinstall(path58.join(cargoHome, "bin"));
|
|
31210
31784
|
if (await binstall) {
|
|
31211
31785
|
try {
|
|
31212
31786
|
await execAsync(
|
|
@@ -31228,7 +31802,7 @@ async function setupRust(env, config2, refresh) {
|
|
|
31228
31802
|
const RUSTUP_HOME = tool("rust", "rustup");
|
|
31229
31803
|
const CARGO_HOME = tool("rust", "cargo");
|
|
31230
31804
|
const rustEnv = { env: { ...process.env, RUSTUP_HOME, CARGO_HOME } };
|
|
31231
|
-
const rustup =
|
|
31805
|
+
const rustup = path59.join(CARGO_HOME, "bin", "rustup.exe");
|
|
31232
31806
|
if (dryRun) {
|
|
31233
31807
|
log("(dry run) would provision Rust " + config2.toolchain + " (" + config2.host + ")");
|
|
31234
31808
|
return;
|
|
@@ -31264,9 +31838,9 @@ async function setupRust(env, config2, refresh) {
|
|
|
31264
31838
|
if (refresh) await execAsync(rustup, ["update"], rustEnv);
|
|
31265
31839
|
}
|
|
31266
31840
|
Object.assign(env.vars, { RUSTUP_HOME, CARGO_HOME });
|
|
31267
|
-
env.prepend.push(
|
|
31841
|
+
env.prepend.push(path59.join(CARGO_HOME, "bin"));
|
|
31268
31842
|
env.summary.push(
|
|
31269
|
-
"rust: " + versionOf(
|
|
31843
|
+
"rust: " + versionOf(path59.join(CARGO_HOME, "bin", "rustc.exe"), ["--version"], rustEnv) + " [" + config2.host + "]"
|
|
31270
31844
|
);
|
|
31271
31845
|
const toolchainKey = "rustup@" + config2.toolchain;
|
|
31272
31846
|
await installOnce(
|
|
@@ -31287,36 +31861,36 @@ async function setupRust(env, config2, refresh) {
|
|
|
31287
31861
|
env: {
|
|
31288
31862
|
...rustEnv.env,
|
|
31289
31863
|
...msvc.vars,
|
|
31290
|
-
PATH: [
|
|
31864
|
+
PATH: [path59.join(CARGO_HOME, "bin"), ...msvc.path, process.env.PATH ?? ""].join(path59.delimiter)
|
|
31291
31865
|
}
|
|
31292
31866
|
} : {
|
|
31293
31867
|
env: {
|
|
31294
31868
|
...rustEnv.env,
|
|
31295
|
-
CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER:
|
|
31296
|
-
PATH: [
|
|
31869
|
+
CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER: path59.join(mingw, "gcc.exe"),
|
|
31870
|
+
PATH: [path59.join(CARGO_HOME, "bin"), mingw, process.env.PATH ?? ""].join(path59.delimiter)
|
|
31297
31871
|
}
|
|
31298
31872
|
};
|
|
31299
31873
|
await installOnce(env, "cargo", config2.crates, crateInstaller(CARGO_HOME, cargoEnv));
|
|
31300
31874
|
}
|
|
31301
31875
|
|
|
31302
31876
|
// src/guest/toolchains/languages/node.ts
|
|
31303
|
-
import
|
|
31304
|
-
import
|
|
31877
|
+
import fs48 from "node:fs";
|
|
31878
|
+
import path60 from "node:path";
|
|
31305
31879
|
import { spawn as spawn4 } from "node:child_process";
|
|
31306
31880
|
var NVM_HOME = tool("nvm");
|
|
31307
|
-
var NVM_SYMLINK =
|
|
31308
|
-
var HOST_NVM =
|
|
31881
|
+
var NVM_SYMLINK = path60.join(localDir, "nodejs");
|
|
31882
|
+
var HOST_NVM = path60.join(hostToolsDir, "nvm");
|
|
31309
31883
|
var HOST_VERSIONS_MAX = 3;
|
|
31310
|
-
var hostNvmVersions = () => exists(HOST_NVM) ?
|
|
31884
|
+
var hostNvmVersions = () => exists(HOST_NVM) ? fs48.readdirSync(HOST_NVM).filter((d) => /^v\d+\.\d+\.\d+$/.test(d) && exists(path60.join(HOST_NVM, d, "node.exe"))).map((d) => d.slice(1)) : [];
|
|
31311
31885
|
var resolveNode = (spec) => resolveCached("node:" + spec, async () => {
|
|
31312
31886
|
const exact = spec.replace(/^v/, "");
|
|
31313
31887
|
if (/^\d+\.\d+\.\d+$/.test(exact)) return exact;
|
|
31314
31888
|
const releases = await fetchJson("https://nodejs.org/dist/index.json");
|
|
31315
31889
|
return pickNodeVersion(releases, spec) ?? Promise.reject(new Error('No Node.js release matches "' + spec + '"'));
|
|
31316
31890
|
});
|
|
31317
|
-
var NVM_TEMP =
|
|
31891
|
+
var NVM_TEMP = path60.join(NVM_HOME, ".tmp");
|
|
31318
31892
|
var nvm = (args) => new Promise((resolve2) => {
|
|
31319
|
-
const child = spawn4(
|
|
31893
|
+
const child = spawn4(path60.join(NVM_HOME, "nvm.exe"), args, {
|
|
31320
31894
|
windowsHide: true,
|
|
31321
31895
|
env: { ...process.env, NVM_HOME, NVM_SYMLINK, TEMP: NVM_TEMP, TMP: NVM_TEMP }
|
|
31322
31896
|
});
|
|
@@ -31331,12 +31905,12 @@ var nvm = (args) => new Promise((resolve2) => {
|
|
|
31331
31905
|
child.once("close", () => resolve2(out));
|
|
31332
31906
|
});
|
|
31333
31907
|
var ensureNvm = async () => {
|
|
31334
|
-
if (exists(
|
|
31335
|
-
if (exists(
|
|
31908
|
+
if (exists(path60.join(NVM_HOME, "nvm.exe"))) return;
|
|
31909
|
+
if (exists(path60.join(HOST_NVM, "nvm.exe"))) {
|
|
31336
31910
|
log("Copying nvm from this PC ...");
|
|
31337
31911
|
mkdirp(NVM_HOME);
|
|
31338
|
-
const files =
|
|
31339
|
-
for (const file3 of files)
|
|
31912
|
+
const files = fs48.readdirSync(HOST_NVM).filter((f) => /\.(exe|cmd|vbs)$/i.test(f)).sort((a, b) => Number(a.toLowerCase() === "nvm.exe") - Number(b.toLowerCase() === "nvm.exe"));
|
|
31913
|
+
for (const file3 of files) fs48.copyFileSync(path60.join(HOST_NVM, file3), path60.join(NVM_HOME, file3));
|
|
31340
31914
|
return;
|
|
31341
31915
|
}
|
|
31342
31916
|
const asset = await githubAsset("coreybutler/nvm-windows", /^nvm-noinstall\.zip$/, true);
|
|
@@ -31344,14 +31918,14 @@ var ensureNvm = async () => {
|
|
|
31344
31918
|
await downloader.archive(asset.url, NVM_HOME, { sha256: asset.sha256, locate: "nvm.exe", fileName: asset.name });
|
|
31345
31919
|
};
|
|
31346
31920
|
var hostNodeFolder = (version2) => {
|
|
31347
|
-
const dir =
|
|
31348
|
-
return session.hostTools.nodeVersion?.replace(/^v/, "") === version2 && exists(
|
|
31921
|
+
const dir = path60.join(hostToolsDir, "node");
|
|
31922
|
+
return session.hostTools.nodeVersion?.replace(/^v/, "") === version2 && exists(path60.join(dir, "node.exe")) ? dir : null;
|
|
31349
31923
|
};
|
|
31350
31924
|
var installNodeVersion = async (version2) => {
|
|
31351
|
-
const dir =
|
|
31352
|
-
const fromHost =
|
|
31353
|
-
if (exists(
|
|
31354
|
-
if (exists(
|
|
31925
|
+
const dir = path60.join(NVM_HOME, "v" + version2);
|
|
31926
|
+
const fromHost = path60.join(HOST_NVM, "v" + version2);
|
|
31927
|
+
if (exists(path60.join(dir, "node.exe"))) return;
|
|
31928
|
+
if (exists(path60.join(fromHost, "node.exe"))) {
|
|
31355
31929
|
log("Copying Node " + version2 + " from this PC's nvm (without global packages) ...");
|
|
31356
31930
|
copyNode(fromHost, dir);
|
|
31357
31931
|
return;
|
|
@@ -31370,19 +31944,19 @@ var installNodeVersion = async (version2) => {
|
|
|
31370
31944
|
} finally {
|
|
31371
31945
|
safeRemove(NVM_TEMP, NVM_HOME);
|
|
31372
31946
|
}
|
|
31373
|
-
if (!exists(
|
|
31947
|
+
if (!exists(path60.join(dir, "node.exe"))) {
|
|
31374
31948
|
const tail = out.trim().split(/\r?\n/).filter(Boolean).slice(-3).join(" ");
|
|
31375
31949
|
const why = /complete/i.test(out) ? "nvm said it finished, but its move into the data folder did not happen" : "nvm could not download or unpack it: check the internet connection and the free disk space";
|
|
31376
31950
|
throw new Error(
|
|
31377
|
-
"nvm install " + version2 + " did not leave " +
|
|
31951
|
+
"nvm install " + version2 + " did not leave " + path60.join(dir, "node.exe") + " (" + why + ")" + (tail ? ". nvm printed: " + tail : "")
|
|
31378
31952
|
);
|
|
31379
31953
|
}
|
|
31380
31954
|
};
|
|
31381
31955
|
var activate = async (version2) => {
|
|
31382
31956
|
await nvm(["use", version2]);
|
|
31383
|
-
if (exists(
|
|
31384
|
-
|
|
31385
|
-
|
|
31957
|
+
if (exists(path60.join(NVM_SYMLINK, "node.exe"))) return;
|
|
31958
|
+
fs48.rmSync(NVM_SYMLINK, { recursive: true, force: true });
|
|
31959
|
+
fs48.symlinkSync(path60.join(NVM_HOME, "v" + version2), NVM_SYMLINK, "junction");
|
|
31386
31960
|
};
|
|
31387
31961
|
var PLAYWRIGHT_VARS = () => ({
|
|
31388
31962
|
PLAYWRIGHT_BROWSERS_PATH: tool("ms-playwright"),
|
|
@@ -31394,8 +31968,8 @@ async function setupNode(env, versions, config2) {
|
|
|
31394
31968
|
return;
|
|
31395
31969
|
}
|
|
31396
31970
|
await ensureNvm();
|
|
31397
|
-
|
|
31398
|
-
|
|
31971
|
+
fs48.writeFileSync(
|
|
31972
|
+
path60.join(NVM_HOME, "settings.txt"),
|
|
31399
31973
|
[
|
|
31400
31974
|
"root: " + NVM_HOME,
|
|
31401
31975
|
"path: " + NVM_SYMLINK,
|
|
@@ -31422,7 +31996,7 @@ async function setupNode(env, versions, config2) {
|
|
|
31422
31996
|
}
|
|
31423
31997
|
}
|
|
31424
31998
|
Object.assign(env.vars, { NVM_HOME, NVM_SYMLINK, ...PLAYWRIGHT_VARS() });
|
|
31425
|
-
if (duringSession()) env.prepend.push(
|
|
31999
|
+
if (duringSession()) env.prepend.push(path60.join(NVM_HOME, "v" + main), NVM_HOME, NVM_SYMLINK);
|
|
31426
32000
|
else {
|
|
31427
32001
|
await activate(main);
|
|
31428
32002
|
env.prepend.push(NVM_HOME, NVM_SYMLINK);
|
|
@@ -31432,13 +32006,13 @@ async function setupNode(env, versions, config2) {
|
|
|
31432
32006
|
await packageManagers(env, config2, main);
|
|
31433
32007
|
}
|
|
31434
32008
|
var packageManagers = async (env, config2, version2) => {
|
|
31435
|
-
const dir =
|
|
31436
|
-
const nodeEnv = { ...process.env, PATH: dir +
|
|
31437
|
-
const npm = (args) => execAsync(
|
|
32009
|
+
const dir = path60.join(NVM_HOME, "v" + version2);
|
|
32010
|
+
const nodeEnv = { ...process.env, PATH: dir + path60.delimiter + (process.env.PATH ?? "") };
|
|
32011
|
+
const npm = (args) => execAsync(path60.join(dir, "node.exe"), [path60.join(dir, "node_modules", "npm", "bin", "npm-cli.js"), ...args], {
|
|
31438
32012
|
env: nodeEnv,
|
|
31439
32013
|
stdio: "ignore"
|
|
31440
32014
|
});
|
|
31441
|
-
const corepackJs =
|
|
32015
|
+
const corepackJs = path60.join(dir, "node_modules", "corepack", "dist", "corepack.js");
|
|
31442
32016
|
const extra = config2.corepack && !exists(corepackJs) ? ["corepack"] : [];
|
|
31443
32017
|
await installOnce(
|
|
31444
32018
|
env,
|
|
@@ -31459,7 +32033,7 @@ var packageManagers = async (env, config2, version2) => {
|
|
|
31459
32033
|
}
|
|
31460
32034
|
try {
|
|
31461
32035
|
await execAsync(
|
|
31462
|
-
|
|
32036
|
+
path60.join(dir, "node.exe"),
|
|
31463
32037
|
[corepackJs, "enable", "--install-directory", mkdirp(tool("bin")), "pnpm", "yarn"],
|
|
31464
32038
|
{ env: nodeEnv, stdio: "ignore" }
|
|
31465
32039
|
);
|
|
@@ -31484,8 +32058,8 @@ async function setupPwsh(env, refresh = false) {
|
|
|
31484
32058
|
}
|
|
31485
32059
|
|
|
31486
32060
|
// src/guest/toolchains/languages/python.ts
|
|
31487
|
-
import
|
|
31488
|
-
import
|
|
32061
|
+
import fs49 from "node:fs";
|
|
32062
|
+
import path61 from "node:path";
|
|
31489
32063
|
var installPython = async (pkg, spec) => {
|
|
31490
32064
|
const version2 = await resolveCached(pkg + ":" + spec, async () => {
|
|
31491
32065
|
const { versions } = await fetchJson(
|
|
@@ -31494,7 +32068,7 @@ var installPython = async (pkg, spec) => {
|
|
|
31494
32068
|
return pickPackageVersion(versions, spec) ?? Promise.reject(new Error("No " + pkg + ' release matches "' + spec + '"'));
|
|
31495
32069
|
});
|
|
31496
32070
|
const dir = tool("python", pkg + "-" + version2);
|
|
31497
|
-
const exe =
|
|
32071
|
+
const exe = path61.join(dir, "python.exe");
|
|
31498
32072
|
if (!exists(exe)) {
|
|
31499
32073
|
log("Downloading Python " + version2 + (pkg === "python2" ? " (Python 2, " : " (") + "~30 MB once) ...");
|
|
31500
32074
|
await downloader.archive(
|
|
@@ -31503,32 +32077,32 @@ var installPython = async (pkg, spec) => {
|
|
|
31503
32077
|
{ locate: "python.exe", fileName: pkg + "." + version2 + ".zip" }
|
|
31504
32078
|
);
|
|
31505
32079
|
}
|
|
31506
|
-
if (!exists(
|
|
32080
|
+
if (!exists(path61.join(dir, "Scripts", "pip.exe")) && !exists(path61.join(dir, "Scripts", "pip2.exe")))
|
|
31507
32081
|
await execAsync(exe, ["-m", "ensurepip", "--default-pip"], { stdio: "ignore" });
|
|
31508
32082
|
return dir;
|
|
31509
32083
|
};
|
|
31510
|
-
var shimDir = (dir) => duringSession() ? tool("shims",
|
|
32084
|
+
var shimDir = (dir) => duringSession() ? tool("shims", path61.basename(dir)) : tool("shims");
|
|
31511
32085
|
var shim = (folder, name, program, args = []) => {
|
|
31512
32086
|
const fixed = [program, ...args];
|
|
31513
|
-
|
|
31514
|
-
|
|
32087
|
+
fs49.writeFileSync(
|
|
32088
|
+
path61.join(mkdirp(folder), name + ".cmd"),
|
|
31515
32089
|
"@echo off\r\n" + fixed.map((a) => '"' + a + '"').join(" ") + " %*\r\n"
|
|
31516
32090
|
);
|
|
31517
32091
|
const sh = fixed.map((a) => "'" + a.replace(/\\/g, "/").replace(/'/g, "'\\''") + "'").join(" ");
|
|
31518
|
-
|
|
32092
|
+
fs49.writeFileSync(path61.join(folder, name), "#!/bin/sh\nexec " + sh + ' "$@"\n');
|
|
31519
32093
|
};
|
|
31520
32094
|
var shimPair = (folder, version2, dir) => {
|
|
31521
|
-
const python =
|
|
32095
|
+
const python = path61.join(dir, "python.exe");
|
|
31522
32096
|
shim(folder, "python" + version2, python);
|
|
31523
32097
|
shim(folder, "pip" + version2, python, ["-m", "pip"]);
|
|
31524
32098
|
};
|
|
31525
32099
|
var pyLauncher = (folder, py3, py2) => {
|
|
31526
|
-
const script =
|
|
31527
|
-
|
|
32100
|
+
const script = path61.join(mkdirp(folder), "py-launcher.py");
|
|
32101
|
+
fs49.writeFileSync(
|
|
31528
32102
|
script,
|
|
31529
32103
|
[
|
|
31530
32104
|
"import subprocess, sys",
|
|
31531
|
-
"PY3, PY2 = " + JSON.stringify(
|
|
32105
|
+
"PY3, PY2 = " + JSON.stringify(path61.join(py3, "python.exe")) + ", " + JSON.stringify(py2 ? path61.join(py2, "python.exe") : null),
|
|
31532
32106
|
"args = sys.argv[1:]",
|
|
31533
32107
|
"exe = PY3",
|
|
31534
32108
|
"if args and args[0].startswith('-2'):",
|
|
@@ -31540,7 +32114,7 @@ var pyLauncher = (folder, py3, py2) => {
|
|
|
31540
32114
|
""
|
|
31541
32115
|
].join("\n")
|
|
31542
32116
|
);
|
|
31543
|
-
shim(folder, "py",
|
|
32117
|
+
shim(folder, "py", path61.join(py3, "python.exe"), [script]);
|
|
31544
32118
|
};
|
|
31545
32119
|
async function setupPython(env, config2, versions) {
|
|
31546
32120
|
if (dryRun) {
|
|
@@ -31550,10 +32124,10 @@ async function setupPython(env, config2, versions) {
|
|
|
31550
32124
|
const py3 = await installPython("python", versions.python.spec);
|
|
31551
32125
|
const shims = shimDir(py3);
|
|
31552
32126
|
shimPair(shims, "3", py3);
|
|
31553
|
-
env.prepend.push(py3, mkdirp(
|
|
32127
|
+
env.prepend.push(py3, mkdirp(path61.join(py3, "Scripts")), shims);
|
|
31554
32128
|
env.vars.PYTHONIOENCODING = "utf-8";
|
|
31555
32129
|
env.summary.push(
|
|
31556
|
-
"python: " +
|
|
32130
|
+
"python: " + path61.basename(py3).replace("python-", "") + " (from " + versions.python.source + "; py works too)"
|
|
31557
32131
|
);
|
|
31558
32132
|
if (!config2.python2) {
|
|
31559
32133
|
pyLauncher(shims, py3, null);
|
|
@@ -31562,12 +32136,12 @@ async function setupPython(env, config2, versions) {
|
|
|
31562
32136
|
const py2 = await installPython("python2", "2.7");
|
|
31563
32137
|
shimPair(shims, "2", py2);
|
|
31564
32138
|
pyLauncher(shims, py3, py2);
|
|
31565
|
-
env.summary.push("python2: " +
|
|
32139
|
+
env.summary.push("python2: " + path61.basename(py2).replace("python2-", ""));
|
|
31566
32140
|
}
|
|
31567
32141
|
|
|
31568
32142
|
// src/guest/toolchains/languages/php.ts
|
|
31569
|
-
import
|
|
31570
|
-
import
|
|
32143
|
+
import fs50 from "node:fs";
|
|
32144
|
+
import path62 from "node:path";
|
|
31571
32145
|
var PHP_EXTENSIONS = [
|
|
31572
32146
|
"curl",
|
|
31573
32147
|
"fileinfo",
|
|
@@ -31585,11 +32159,11 @@ var PHP_EXTENSIONS = [
|
|
|
31585
32159
|
var COMPOSER = "https://getcomposer.org/download/latest-stable/composer.phar";
|
|
31586
32160
|
var phpBuild = async (spec) => {
|
|
31587
32161
|
const releases = await fetchJson("https://windows.php.net/downloads/releases/releases.json");
|
|
31588
|
-
const
|
|
32162
|
+
const pick3 = pickPackageVersion(
|
|
31589
32163
|
Object.values(releases).map((r) => r.version),
|
|
31590
32164
|
spec
|
|
31591
32165
|
);
|
|
31592
|
-
const release = Object.values(releases).find((r) => r.version ===
|
|
32166
|
+
const release = Object.values(releases).find((r) => r.version === pick3);
|
|
31593
32167
|
const build = release && Object.entries(release).find(
|
|
31594
32168
|
([key2, value]) => /^nts-vs\d+-x64$/.test(key2) && typeof value === "object" && value.zip
|
|
31595
32169
|
)?.[1];
|
|
@@ -31598,16 +32172,16 @@ var phpBuild = async (spec) => {
|
|
|
31598
32172
|
return { version: release.version, ...build.zip };
|
|
31599
32173
|
};
|
|
31600
32174
|
var writePhpIni = (home) => {
|
|
31601
|
-
const ini =
|
|
31602
|
-
if (exists(ini) || !exists(
|
|
31603
|
-
let text =
|
|
31604
|
-
for (const ext of PHP_EXTENSIONS.filter((e) => exists(
|
|
32175
|
+
const ini = path62.join(home, "php.ini");
|
|
32176
|
+
if (exists(ini) || !exists(path62.join(home, "php.ini-development"))) return;
|
|
32177
|
+
let text = fs50.readFileSync(path62.join(home, "php.ini-development"), "utf8").replace(/^;\s*extension_dir\s*=\s*"ext"/m, 'extension_dir = "' + path62.join(home, "ext") + '"');
|
|
32178
|
+
for (const ext of PHP_EXTENSIONS.filter((e) => exists(path62.join(home, "ext", "php_" + e + ".dll"))))
|
|
31605
32179
|
text = text.replace(new RegExp("^;(extension=" + ext + ")\\s*$", "m"), "$1");
|
|
31606
|
-
|
|
31607
|
-
|
|
32180
|
+
fs50.writeFileSync(ini + ".tmp", text);
|
|
32181
|
+
fs50.renameSync(ini + ".tmp", ini);
|
|
31608
32182
|
};
|
|
31609
32183
|
var shim2 = (env, name, command) => {
|
|
31610
|
-
|
|
32184
|
+
fs50.writeFileSync(path62.join(mkdirp(tool("shims")), name + ".cmd"), "@echo off\r\n" + command + " %*\r\n");
|
|
31611
32185
|
env.prepend.push(tool("shims"));
|
|
31612
32186
|
};
|
|
31613
32187
|
var setupComposer = async (env, php) => {
|
|
@@ -31619,7 +32193,7 @@ var setupComposer = async (env, php) => {
|
|
|
31619
32193
|
}
|
|
31620
32194
|
const composerHome = tool("composer-home");
|
|
31621
32195
|
env.vars.COMPOSER_HOME = composerHome;
|
|
31622
|
-
env.prepend.push(
|
|
32196
|
+
env.prepend.push(path62.join(composerHome, "vendor", "bin"));
|
|
31623
32197
|
shim2(env, "composer", '"' + php + '" "' + phar + '"');
|
|
31624
32198
|
env.summary.push(
|
|
31625
32199
|
"composer: " + (/\d+\.\d+\.\d+/.exec(execOutput(php, [phar, "--version", "--no-ansi"]))?.[0] ?? "installed")
|
|
@@ -31634,7 +32208,7 @@ async function setupPhp(env, config2) {
|
|
|
31634
32208
|
await setupVcRuntime(env, false);
|
|
31635
32209
|
const version2 = await resolveCached("php:" + wantedSpec.spec, async () => (await phpBuild(wantedSpec.spec)).version);
|
|
31636
32210
|
const home = tool("php", version2);
|
|
31637
|
-
if (!exists(
|
|
32211
|
+
if (!exists(path62.join(home, "php.exe"))) {
|
|
31638
32212
|
const build = await phpBuild(version2);
|
|
31639
32213
|
log("Downloading PHP " + version2 + " (~30 MB once) ...");
|
|
31640
32214
|
await downloader.archive("https://windows.php.net/downloads/releases/" + build.path, home, {
|
|
@@ -31646,11 +32220,11 @@ async function setupPhp(env, config2) {
|
|
|
31646
32220
|
writePhpIni(home);
|
|
31647
32221
|
env.prepend.push(home);
|
|
31648
32222
|
env.summary.push("php: " + version2 + " (from " + wantedSpec.source + ")");
|
|
31649
|
-
if (config2.composer) await setupComposer(env,
|
|
32223
|
+
if (config2.composer) await setupComposer(env, path62.join(home, "php.exe"));
|
|
31650
32224
|
}
|
|
31651
32225
|
|
|
31652
32226
|
// src/guest/toolchains/languages/ruby.ts
|
|
31653
|
-
import
|
|
32227
|
+
import path63 from "node:path";
|
|
31654
32228
|
var RUBY_ASSET = /^rubyinstaller-(\d+\.\d+\.\d+)-(\d+)-x64\.7z$/;
|
|
31655
32229
|
var buildNumber = (asset) => Number(RUBY_ASSET.exec(asset.name)?.[2] ?? 0);
|
|
31656
32230
|
var rubyBuilds = async () => {
|
|
@@ -31678,7 +32252,7 @@ async function setupRuby(env, config2) {
|
|
|
31678
32252
|
async () => pickPackageVersion([...(await rubyBuilds()).keys()], wantedSpec.spec) ?? Promise.reject(new Error('No RubyInstaller build matches "' + wantedSpec.spec + '"'))
|
|
31679
32253
|
);
|
|
31680
32254
|
const home = tool("ruby", version2);
|
|
31681
|
-
if (!exists(
|
|
32255
|
+
if (!exists(path63.join(home, "bin", "ruby.exe"))) {
|
|
31682
32256
|
const asset = (await rubyBuilds()).get(version2);
|
|
31683
32257
|
if (!asset) throw new Error("RubyInstaller " + version2 + " is no longer published");
|
|
31684
32258
|
log("Downloading Ruby " + version2 + " (~100 MB once) ...");
|
|
@@ -31691,11 +32265,11 @@ async function setupRuby(env, config2) {
|
|
|
31691
32265
|
}
|
|
31692
32266
|
const gems = tool("ruby-gems", version2.split(".").slice(0, 2).join("."));
|
|
31693
32267
|
Object.assign(env.vars, { GEM_HOME: gems, BUNDLE_USER_HOME: tool("bundle-home") });
|
|
31694
|
-
env.prepend.push(
|
|
32268
|
+
env.prepend.push(path63.join(home, "bin"), path63.join(gems, "bin"));
|
|
31695
32269
|
env.summary.push(
|
|
31696
|
-
"ruby: " + versionOf(
|
|
32270
|
+
"ruby: " + versionOf(path63.join(home, "bin", "ruby.exe")) + " (from " + wantedSpec.source + "; gems with C extensions need MSYS2, not included)"
|
|
31697
32271
|
);
|
|
31698
|
-
const gem =
|
|
32272
|
+
const gem = path63.join(home, "bin", "gem.cmd");
|
|
31699
32273
|
await installOnce(
|
|
31700
32274
|
env,
|
|
31701
32275
|
"gem@" + version2,
|
|
@@ -31707,9 +32281,9 @@ async function setupRuby(env, config2) {
|
|
|
31707
32281
|
}
|
|
31708
32282
|
|
|
31709
32283
|
// src/guest/toolchains/tools/vscode.ts
|
|
31710
|
-
import
|
|
31711
|
-
import
|
|
31712
|
-
import
|
|
32284
|
+
import fs51 from "node:fs";
|
|
32285
|
+
import os9 from "node:os";
|
|
32286
|
+
import path64 from "node:path";
|
|
31713
32287
|
|
|
31714
32288
|
// node_modules/jsonc-parser/lib/esm/impl/scanner.js
|
|
31715
32289
|
var CharacterCodes;
|
|
@@ -31889,14 +32463,14 @@ var ParseErrorCode;
|
|
|
31889
32463
|
var VERSION_MARKER = ".agent-sandbox-version";
|
|
31890
32464
|
var desktopShortcut = (exe) => {
|
|
31891
32465
|
if (!isWin) return;
|
|
31892
|
-
const link =
|
|
32466
|
+
const link = path64.join(os9.homedir(), "Desktop", "Visual Studio Code.lnk");
|
|
31893
32467
|
runScriptWithJson("new-shortcuts.ps1", "ListFile", [
|
|
31894
32468
|
{ link, target: exe, arguments: '"' + (process.env.AGENT_WORKSPACE ?? "") + '"' }
|
|
31895
32469
|
]);
|
|
31896
32470
|
};
|
|
31897
32471
|
async function setupVscode(env, refresh) {
|
|
31898
32472
|
const root = tool("vscode");
|
|
31899
|
-
const exe =
|
|
32473
|
+
const exe = path64.join(root, "Code.exe");
|
|
31900
32474
|
if (dryRun) {
|
|
31901
32475
|
log("(dry run) would provision VS Code");
|
|
31902
32476
|
return;
|
|
@@ -31906,11 +32480,11 @@ async function setupVscode(env, refresh) {
|
|
|
31906
32480
|
"https://update.code.visualstudio.com/api/update/win32-" + (arch === "arm64" ? "arm64" : "x64") + "-archive/stable/latest"
|
|
31907
32481
|
);
|
|
31908
32482
|
log("Downloading VS Code " + release.productVersion + " (~150 MB once) ...");
|
|
31909
|
-
const keep =
|
|
32483
|
+
const keep = path64.join(root, "data");
|
|
31910
32484
|
const parked = root + "-data";
|
|
31911
32485
|
if (exists(keep)) {
|
|
31912
|
-
|
|
31913
|
-
|
|
32486
|
+
fs51.rmSync(parked, { recursive: true, force: true });
|
|
32487
|
+
fs51.renameSync(keep, parked);
|
|
31914
32488
|
}
|
|
31915
32489
|
try {
|
|
31916
32490
|
await downloader.archive(release.url, root, {
|
|
@@ -31918,26 +32492,511 @@ async function setupVscode(env, refresh) {
|
|
|
31918
32492
|
locate: "Code.exe",
|
|
31919
32493
|
fileName: "vscode.zip"
|
|
31920
32494
|
});
|
|
31921
|
-
|
|
32495
|
+
fs51.writeFileSync(path64.join(root, VERSION_MARKER), release.productVersion);
|
|
31922
32496
|
} finally {
|
|
31923
32497
|
if (exists(parked)) {
|
|
31924
32498
|
mkdirp(root);
|
|
31925
|
-
|
|
31926
|
-
|
|
32499
|
+
fs51.rmSync(keep, { recursive: true, force: true });
|
|
32500
|
+
fs51.renameSync(parked, keep);
|
|
31927
32501
|
}
|
|
31928
32502
|
}
|
|
31929
32503
|
}
|
|
31930
|
-
mkdirp(
|
|
31931
|
-
env.prepend.push(
|
|
32504
|
+
mkdirp(path64.join(root, "data"));
|
|
32505
|
+
env.prepend.push(path64.join(root, "bin"));
|
|
31932
32506
|
desktopShortcut(exe);
|
|
31933
|
-
const version2 = exists(
|
|
32507
|
+
const version2 = exists(path64.join(root, VERSION_MARKER)) ? fs51.readFileSync(path64.join(root, VERSION_MARKER), "utf8").trim() : "installed";
|
|
31934
32508
|
env.summary.push("vscode: " + version2 + " (portable; run code . or use the desktop shortcut)");
|
|
31935
32509
|
}
|
|
31936
32510
|
|
|
32511
|
+
// src/guest/toolchains/steam/steam.ts
|
|
32512
|
+
import fs55 from "node:fs";
|
|
32513
|
+
import path69 from "node:path";
|
|
32514
|
+
|
|
32515
|
+
// src/shared/accounts/kinds/steam.ts
|
|
32516
|
+
import fs52 from "node:fs";
|
|
32517
|
+
import path65 from "node:path";
|
|
32518
|
+
|
|
32519
|
+
// src/shared/vdf.ts
|
|
32520
|
+
var DEFAULT_MAX_BYTES = 1024 * 1024;
|
|
32521
|
+
var DEFAULT_MAX_DEPTH = 32;
|
|
32522
|
+
var DEFAULT_MAX_KEYS = 1e5;
|
|
32523
|
+
var isSpace = (c) => c === " " || c === " " || c === "\r" || c === "\n" || c === "\f";
|
|
32524
|
+
var ESCAPED = { "\\": "\\", '"': '"', n: "\n", t: " " };
|
|
32525
|
+
function tokenize(text, escapes) {
|
|
32526
|
+
const tokens = [];
|
|
32527
|
+
let i = 0;
|
|
32528
|
+
const n = text.length;
|
|
32529
|
+
while (i < n) {
|
|
32530
|
+
const c = text[i];
|
|
32531
|
+
if (isSpace(c)) {
|
|
32532
|
+
i++;
|
|
32533
|
+
} else if (c === "/" && text[i + 1] === "/") {
|
|
32534
|
+
while (i < n && text[i] !== "\n") i++;
|
|
32535
|
+
} else if (c === "{") {
|
|
32536
|
+
tokens.push({ kind: "open" });
|
|
32537
|
+
i++;
|
|
32538
|
+
} else if (c === "}") {
|
|
32539
|
+
tokens.push({ kind: "close" });
|
|
32540
|
+
i++;
|
|
32541
|
+
} else if (c === "[") {
|
|
32542
|
+
const end = text.indexOf("]", i);
|
|
32543
|
+
if (end < 0) return null;
|
|
32544
|
+
i = end + 1;
|
|
32545
|
+
} else if (c === '"') {
|
|
32546
|
+
let out = "";
|
|
32547
|
+
let start = ++i;
|
|
32548
|
+
for (; ; ) {
|
|
32549
|
+
if (i >= n) return null;
|
|
32550
|
+
const d = text[i];
|
|
32551
|
+
if (d === '"') break;
|
|
32552
|
+
if (escapes && d === "\\" && i + 1 < n && ESCAPED[text[i + 1]] !== void 0) {
|
|
32553
|
+
out += text.slice(start, i) + ESCAPED[text[i + 1]];
|
|
32554
|
+
i += 2;
|
|
32555
|
+
start = i;
|
|
32556
|
+
continue;
|
|
32557
|
+
}
|
|
32558
|
+
i++;
|
|
32559
|
+
}
|
|
32560
|
+
tokens.push({ kind: "text", text: out + text.slice(start, i) });
|
|
32561
|
+
i++;
|
|
32562
|
+
} else {
|
|
32563
|
+
const start = i;
|
|
32564
|
+
while (i < n && !isSpace(text[i]) && text[i] !== "{" && text[i] !== "}" && text[i] !== '"') i++;
|
|
32565
|
+
tokens.push({ kind: "text", text: text.slice(start, i) });
|
|
32566
|
+
}
|
|
32567
|
+
}
|
|
32568
|
+
return tokens;
|
|
32569
|
+
}
|
|
32570
|
+
function open2() {
|
|
32571
|
+
return { target: /* @__PURE__ */ Object.create(null), seen: /* @__PURE__ */ new Set() };
|
|
32572
|
+
}
|
|
32573
|
+
function setFirst(o, key2, value) {
|
|
32574
|
+
const lower = key2.toLowerCase();
|
|
32575
|
+
if (o.seen.has(lower)) return false;
|
|
32576
|
+
o.seen.add(lower);
|
|
32577
|
+
o.target[key2] = value;
|
|
32578
|
+
return true;
|
|
32579
|
+
}
|
|
32580
|
+
function parseVdf(text, limits = {}) {
|
|
32581
|
+
const maxBytes = limits.maxBytes ?? DEFAULT_MAX_BYTES;
|
|
32582
|
+
const maxDepth = limits.maxDepth ?? DEFAULT_MAX_DEPTH;
|
|
32583
|
+
const maxKeys = limits.maxKeys ?? DEFAULT_MAX_KEYS;
|
|
32584
|
+
if (typeof text !== "string" || text.length > maxBytes) return null;
|
|
32585
|
+
const tokens = tokenize(text.charCodeAt(0) === 65279 ? text.slice(1) : text, limits.escapes ?? true);
|
|
32586
|
+
if (!tokens) return null;
|
|
32587
|
+
const root = open2();
|
|
32588
|
+
const stack = [root];
|
|
32589
|
+
let keys = 0;
|
|
32590
|
+
let i = 0;
|
|
32591
|
+
while (i < tokens.length) {
|
|
32592
|
+
const token = tokens[i];
|
|
32593
|
+
const current = stack[stack.length - 1];
|
|
32594
|
+
if (token.kind === "close") {
|
|
32595
|
+
if (stack.length === 1) return null;
|
|
32596
|
+
stack.pop();
|
|
32597
|
+
i++;
|
|
32598
|
+
continue;
|
|
32599
|
+
}
|
|
32600
|
+
if (token.kind === "open") return null;
|
|
32601
|
+
if (++keys > maxKeys) return null;
|
|
32602
|
+
const next = tokens[i + 1];
|
|
32603
|
+
if (!next || next.kind === "close") return null;
|
|
32604
|
+
if (next.kind === "open") {
|
|
32605
|
+
if (stack.length > maxDepth) return null;
|
|
32606
|
+
const child = open2();
|
|
32607
|
+
setFirst(current, token.text, child.target);
|
|
32608
|
+
stack.push(child);
|
|
32609
|
+
} else {
|
|
32610
|
+
setFirst(current, token.text, next.text);
|
|
32611
|
+
}
|
|
32612
|
+
i += 2;
|
|
32613
|
+
}
|
|
32614
|
+
return stack.length === 1 ? root.target : null;
|
|
32615
|
+
}
|
|
32616
|
+
function vdfGet(root, ...keys) {
|
|
32617
|
+
let at = root ?? void 0;
|
|
32618
|
+
for (const key2 of keys) {
|
|
32619
|
+
if (at === void 0 || typeof at === "string") return void 0;
|
|
32620
|
+
const lower = key2.toLowerCase();
|
|
32621
|
+
let found;
|
|
32622
|
+
for (const k in at)
|
|
32623
|
+
if (k.toLowerCase() === lower) {
|
|
32624
|
+
found = at[k];
|
|
32625
|
+
break;
|
|
32626
|
+
}
|
|
32627
|
+
at = found;
|
|
32628
|
+
}
|
|
32629
|
+
return at;
|
|
32630
|
+
}
|
|
32631
|
+
function vdfObject(root, ...keys) {
|
|
32632
|
+
const value = vdfGet(root, ...keys);
|
|
32633
|
+
return value !== void 0 && typeof value !== "string" ? value : void 0;
|
|
32634
|
+
}
|
|
32635
|
+
|
|
32636
|
+
// src/shared/accounts/kinds/steam.ts
|
|
32637
|
+
var MAX_STEAM_CONFIG_BYTES = 256 * 1024;
|
|
32638
|
+
var MAX_SENTRY_BYTES = 48 * 1024;
|
|
32639
|
+
var MAX_SENTRIES = 4;
|
|
32640
|
+
var MAX_ENTRIES2 = 5e3;
|
|
32641
|
+
var SENTRY = /^ssfn\d{1,40}$/;
|
|
32642
|
+
var STEAM_ACCOUNT = /^[A-Za-z0-9_]{1,64}$/;
|
|
32643
|
+
var STEAM_ACCOUNT_FILE = "sbx-account.txt";
|
|
32644
|
+
function steamConfigFile(steamcmdDir) {
|
|
32645
|
+
return path65.join(steamcmdDir, "config", "config.vdf");
|
|
32646
|
+
}
|
|
32647
|
+
function steamKey(root) {
|
|
32648
|
+
return vdfObject(root, "InstallConfigStore", "Software", "Valve", "Steam");
|
|
32649
|
+
}
|
|
32650
|
+
function hasCachedLogin(configVdf) {
|
|
32651
|
+
const cache = vdfObject(steamKey(parseVdf(configVdf, { maxBytes: MAX_STEAM_CONFIG_BYTES })), "ConnectCache");
|
|
32652
|
+
return cache !== void 0 && Object.keys(cache).length > 0;
|
|
32653
|
+
}
|
|
32654
|
+
function steamAccounts(configVdf) {
|
|
32655
|
+
const accounts = vdfObject(steamKey(parseVdf(configVdf, { maxBytes: MAX_STEAM_CONFIG_BYTES })), "Accounts");
|
|
32656
|
+
return accounts ? Object.keys(accounts).filter((a) => STEAM_ACCOUNT.test(a)) : [];
|
|
32657
|
+
}
|
|
32658
|
+
function readSteamAccountFile(steamcmdDir) {
|
|
32659
|
+
const bytes = readBoundedFile(path65.join(steamcmdDir, "config", STEAM_ACCOUNT_FILE), 256);
|
|
32660
|
+
const name = bytes ? decodeText(bytes).text.trim() : "";
|
|
32661
|
+
return STEAM_ACCOUNT.test(name) ? name : null;
|
|
32662
|
+
}
|
|
32663
|
+
function readSentries(steamcmdDir) {
|
|
32664
|
+
let names;
|
|
32665
|
+
try {
|
|
32666
|
+
names = fs52.readdirSync(steamcmdDir).slice(0, MAX_ENTRIES2).filter((n) => SENTRY.test(n));
|
|
32667
|
+
} catch {
|
|
32668
|
+
return [];
|
|
32669
|
+
}
|
|
32670
|
+
const mtime = (name) => {
|
|
32671
|
+
try {
|
|
32672
|
+
return fs52.lstatSync(path65.join(steamcmdDir, name)).mtimeMs;
|
|
32673
|
+
} catch {
|
|
32674
|
+
return 0;
|
|
32675
|
+
}
|
|
32676
|
+
};
|
|
32677
|
+
const found = [];
|
|
32678
|
+
for (const name of names.sort((a, b) => mtime(b) - mtime(a))) {
|
|
32679
|
+
if (found.length >= MAX_SENTRIES) break;
|
|
32680
|
+
const bytes = readBoundedFile(path65.join(steamcmdDir, name), MAX_SENTRY_BYTES);
|
|
32681
|
+
if (bytes && bytes.length) found.push({ name, base64: bytes.toString("base64") });
|
|
32682
|
+
}
|
|
32683
|
+
return found.sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0);
|
|
32684
|
+
}
|
|
32685
|
+
function readSteamCmdLogin(steamcmdDir, account) {
|
|
32686
|
+
const bytes = readBoundedFile(steamConfigFile(steamcmdDir), MAX_STEAM_CONFIG_BYTES);
|
|
32687
|
+
if (!bytes) return null;
|
|
32688
|
+
const configVdf = decodeText(bytes).text;
|
|
32689
|
+
if (!hasCachedLogin(configVdf)) return null;
|
|
32690
|
+
const name = readSteamAccountFile(steamcmdDir) ?? steamAccounts(configVdf)[0] ?? account;
|
|
32691
|
+
if (!name) return null;
|
|
32692
|
+
const parsed = SteamPayloadSchema.safeParse({ account: name, configVdf, sentries: readSentries(steamcmdDir) });
|
|
32693
|
+
return parsed.success ? parsed.data : null;
|
|
32694
|
+
}
|
|
32695
|
+
function writeSteamCmdLogin(steamcmdDir, p) {
|
|
32696
|
+
const login = SteamPayloadSchema.parse(p);
|
|
32697
|
+
const config2 = path65.dirname(steamConfigFile(steamcmdDir));
|
|
32698
|
+
fs52.mkdirSync(config2, { recursive: true });
|
|
32699
|
+
fs52.writeFileSync(steamConfigFile(steamcmdDir), login.configVdf, "utf8");
|
|
32700
|
+
fs52.writeFileSync(path65.join(config2, STEAM_ACCOUNT_FILE), login.account, "utf8");
|
|
32701
|
+
for (const s of login.sentries) fs52.writeFileSync(path65.join(steamcmdDir, s.name), Buffer.from(s.base64, "base64"));
|
|
32702
|
+
}
|
|
32703
|
+
|
|
32704
|
+
// src/guest/toolchains/steam/client.ts
|
|
32705
|
+
import fs53 from "node:fs";
|
|
32706
|
+
import path67 from "node:path";
|
|
32707
|
+
|
|
32708
|
+
// src/guest/toolchains/steam/commands.ts
|
|
32709
|
+
import path66 from "node:path";
|
|
32710
|
+
var STEAMCMD_DIR = "C:\\SteamCMD";
|
|
32711
|
+
var STEAMCMD_URL = "https://steamcdn-a.akamaihd.net/client/installer/steamcmd.zip";
|
|
32712
|
+
var STEAM_CLIENT_URL = "https://steamcdn-a.akamaihd.net/client/installer/SteamSetup.exe";
|
|
32713
|
+
function steamCmdStore(tools = toolsDir) {
|
|
32714
|
+
return path66.join(tools, "steamcmd");
|
|
32715
|
+
}
|
|
32716
|
+
function steamClientDir(tools = toolsDir) {
|
|
32717
|
+
return path66.join(tools, "steam");
|
|
32718
|
+
}
|
|
32719
|
+
var MAX_SCRIPT_BYTES = 256 * 1024;
|
|
32720
|
+
|
|
32721
|
+
// src/guest/toolchains/steam/client.ts
|
|
32722
|
+
var GB2 = 1024 ** 3;
|
|
32723
|
+
var CLIENT_NEED_BYTES = 2 * GB2;
|
|
32724
|
+
var SETUP_TIMEOUT_MS = 10 * 60 * 1e3;
|
|
32725
|
+
function installedSteamClient() {
|
|
32726
|
+
const exe = path67.join(steamClientDir(), "steam.exe");
|
|
32727
|
+
return exists(exe) && signedBy(exe, SIGNERS.valve) ? exe : null;
|
|
32728
|
+
}
|
|
32729
|
+
async function installSteamClient() {
|
|
32730
|
+
const dir = steamClientDir();
|
|
32731
|
+
const exe = path67.join(dir, "steam.exe");
|
|
32732
|
+
if (exists(exe)) {
|
|
32733
|
+
if (!signedBy(exe, SIGNERS.valve)) throw new Error("tools\\steam\\steam.exe is not signed by Valve");
|
|
32734
|
+
return exe;
|
|
32735
|
+
}
|
|
32736
|
+
fs53.mkdirSync(toolsDir, { recursive: true });
|
|
32737
|
+
assertRoom(toolsDir, CLIENT_NEED_BYTES, "the Steam client", "Free room on the data disk.");
|
|
32738
|
+
const setup = await signedInstaller(
|
|
32739
|
+
STEAM_CLIENT_URL,
|
|
32740
|
+
path67.join(tool("steam-setup"), "SteamSetup.exe"),
|
|
32741
|
+
"the Steam client installer (~2 MB once)",
|
|
32742
|
+
SIGNERS.valve
|
|
32743
|
+
);
|
|
32744
|
+
const work = stagingFolder(dir);
|
|
32745
|
+
fs53.mkdirSync(work, { recursive: true });
|
|
32746
|
+
try {
|
|
32747
|
+
log("Unpacking the Steam client into tools\\steam ...");
|
|
32748
|
+
const code = await spawnAsync(setup, ["/S", "/D=" + work], { timeout: SETUP_TIMEOUT_MS });
|
|
32749
|
+
const unpacked = path67.join(work, "steam.exe");
|
|
32750
|
+
if (!exists(unpacked)) throw new Error("SteamSetup.exe did not unpack steam.exe (exit code " + code + ")");
|
|
32751
|
+
if (!signedBy(unpacked, SIGNERS.valve)) throw new Error("the unpacked steam.exe is not signed by Valve");
|
|
32752
|
+
moveIntoPlace(work, dir);
|
|
32753
|
+
} finally {
|
|
32754
|
+
if (fs53.existsSync(work)) safeRemove(work, path67.dirname(work));
|
|
32755
|
+
}
|
|
32756
|
+
return exe;
|
|
32757
|
+
}
|
|
32758
|
+
async function ensureSteamClient(env) {
|
|
32759
|
+
try {
|
|
32760
|
+
const exe = await installSteamClient();
|
|
32761
|
+
env.summary.push("steam client: tools\\steam (start it with sbx-steam client; sign in there in each sandbox)");
|
|
32762
|
+
return exe;
|
|
32763
|
+
} catch (e) {
|
|
32764
|
+
log("Steam client: not set up: " + errMsg(e));
|
|
32765
|
+
env.summary.push("steam client: not set up (" + errMsg(e) + ")");
|
|
32766
|
+
return null;
|
|
32767
|
+
}
|
|
32768
|
+
}
|
|
32769
|
+
|
|
32770
|
+
// src/guest/toolchains/steam/steamcmd-install.ts
|
|
32771
|
+
import { spawn as spawn5 } from "node:child_process";
|
|
32772
|
+
import fs54 from "node:fs";
|
|
32773
|
+
import path68 from "node:path";
|
|
32774
|
+
var MB = 1024 ** 2;
|
|
32775
|
+
var STEAMCMD_NEED_BYTES = 600 * MB;
|
|
32776
|
+
var STEAMCMD_UPDATE_TIMEOUT_MS = 15 * 60 * 1e3;
|
|
32777
|
+
var PRIVATE_DIRS = /* @__PURE__ */ new Set(["config", "logs", "dumps", "userdata", "steamapps", "appcache", "depotcache"]);
|
|
32778
|
+
var isPrivate = (name) => PRIVATE_DIRS.has(name.toLowerCase()) || /^ssfn/i.test(name);
|
|
32779
|
+
var BOOTSTRAPPED = ["steamclient.dll", "steamclient64.dll"];
|
|
32780
|
+
function runWithTimeout(exe, args, cwd, timeoutMs) {
|
|
32781
|
+
return new Promise((resolve2, reject) => {
|
|
32782
|
+
const child = spawn5(exe, args, { cwd, stdio: "ignore", windowsHide: true });
|
|
32783
|
+
let timedOut = false;
|
|
32784
|
+
const timer = setTimeout(() => {
|
|
32785
|
+
timedOut = true;
|
|
32786
|
+
child.kill();
|
|
32787
|
+
}, timeoutMs);
|
|
32788
|
+
child.once("error", (e) => {
|
|
32789
|
+
clearTimeout(timer);
|
|
32790
|
+
reject(e);
|
|
32791
|
+
});
|
|
32792
|
+
child.once("close", (code) => {
|
|
32793
|
+
clearTimeout(timer);
|
|
32794
|
+
resolve2({ code: code ?? -1, timedOut });
|
|
32795
|
+
});
|
|
32796
|
+
});
|
|
32797
|
+
}
|
|
32798
|
+
var notSigned = (file3) => new Error(path68.basename(file3) + " is not signed by Valve: not running it (it is downloaded again next boot)");
|
|
32799
|
+
async function fetchSteamCmd(store2, deps) {
|
|
32800
|
+
fs54.mkdirSync(path68.dirname(store2), { recursive: true });
|
|
32801
|
+
assertRoom(path68.dirname(store2), STEAMCMD_NEED_BYTES, "SteamCMD", "Free room on the data disk.", deps);
|
|
32802
|
+
const work = stagingFolder(store2);
|
|
32803
|
+
const unpacked = path68.join(work, "x");
|
|
32804
|
+
const extract = deps.extract ?? extractArchive;
|
|
32805
|
+
try {
|
|
32806
|
+
fs54.mkdirSync(work, { recursive: true });
|
|
32807
|
+
const verify = async (part) => {
|
|
32808
|
+
await extract(part, unpacked);
|
|
32809
|
+
const exe = path68.join(unpacked, "steamcmd.exe");
|
|
32810
|
+
if (!fs54.existsSync(exe)) throw new Error("steamcmd.zip has no steamcmd.exe");
|
|
32811
|
+
if (!deps.signed(exe)) throw notSigned(exe);
|
|
32812
|
+
};
|
|
32813
|
+
const zip = path68.join(work, "steamcmd.zip");
|
|
32814
|
+
if (deps.download) await deps.download(STEAMCMD_URL, zip, verify);
|
|
32815
|
+
else await downloader.file(STEAMCMD_URL, zip, { verify });
|
|
32816
|
+
moveIntoPlace(unpacked, store2);
|
|
32817
|
+
} finally {
|
|
32818
|
+
if (fs54.existsSync(work)) safeRemove(work, path68.dirname(work));
|
|
32819
|
+
}
|
|
32820
|
+
}
|
|
32821
|
+
async function copyBinaries(from, to) {
|
|
32822
|
+
fs54.mkdirSync(to, { recursive: true });
|
|
32823
|
+
for (const entry of fs54.readdirSync(from, { withFileTypes: true })) {
|
|
32824
|
+
if (isPrivate(entry.name) || entry.isSymbolicLink()) continue;
|
|
32825
|
+
if (!entry.isFile() && !entry.isDirectory()) continue;
|
|
32826
|
+
await fs54.promises.cp(path68.join(from, entry.name), path68.join(to, entry.name), {
|
|
32827
|
+
recursive: true,
|
|
32828
|
+
force: true,
|
|
32829
|
+
verbatimSymlinks: true,
|
|
32830
|
+
filter: (source) => {
|
|
32831
|
+
try {
|
|
32832
|
+
return !fs54.lstatSync(source).isSymbolicLink();
|
|
32833
|
+
} catch {
|
|
32834
|
+
return false;
|
|
32835
|
+
}
|
|
32836
|
+
}
|
|
32837
|
+
});
|
|
32838
|
+
}
|
|
32839
|
+
}
|
|
32840
|
+
function snapshot(dir) {
|
|
32841
|
+
try {
|
|
32842
|
+
return fs54.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && !isPrivate(e.name) && /\.(exe|dll)$/i.test(e.name)).map((e) => {
|
|
32843
|
+
const s = fs54.statSync(path68.join(dir, e.name));
|
|
32844
|
+
return e.name.toLowerCase() + ":" + s.size + ":" + Math.floor(s.mtimeMs / 1e3);
|
|
32845
|
+
}).sort().join("|");
|
|
32846
|
+
} catch {
|
|
32847
|
+
return "";
|
|
32848
|
+
}
|
|
32849
|
+
}
|
|
32850
|
+
var bootstrapped = (dir) => BOOTSTRAPPED.some((f) => fs54.existsSync(path68.join(dir, f)));
|
|
32851
|
+
function scrubStore(store2) {
|
|
32852
|
+
let names = [];
|
|
32853
|
+
try {
|
|
32854
|
+
names = fs54.readdirSync(store2);
|
|
32855
|
+
} catch {
|
|
32856
|
+
return;
|
|
32857
|
+
}
|
|
32858
|
+
for (const name of names.filter(isPrivate)) safeRemove(path68.join(store2, name), store2);
|
|
32859
|
+
}
|
|
32860
|
+
async function prepareSteamCmd(deps) {
|
|
32861
|
+
const store2 = deps.storeDir ?? steamCmdStore(deps.toolsDir);
|
|
32862
|
+
const work = deps.workDir ?? STEAMCMD_DIR;
|
|
32863
|
+
const log2 = deps.log ?? (() => void 0);
|
|
32864
|
+
const exe = path68.join(work, "steamcmd.exe");
|
|
32865
|
+
if (fs54.existsSync(exe) && bootstrapped(work)) {
|
|
32866
|
+
if (!deps.signed(exe)) throw notSigned(exe);
|
|
32867
|
+
return exe;
|
|
32868
|
+
}
|
|
32869
|
+
if (!fs54.existsSync(path68.join(store2, "steamcmd.exe"))) {
|
|
32870
|
+
log2("Downloading SteamCMD (~3 MB once; it fetches ~300 MB on its first run) ...");
|
|
32871
|
+
await fetchSteamCmd(store2, deps);
|
|
32872
|
+
}
|
|
32873
|
+
scrubStore(store2);
|
|
32874
|
+
await copyBinaries(store2, work);
|
|
32875
|
+
if (!deps.signed(exe)) {
|
|
32876
|
+
safeRemove(store2, path68.dirname(store2));
|
|
32877
|
+
throw notSigned(exe);
|
|
32878
|
+
}
|
|
32879
|
+
const before = snapshot(work);
|
|
32880
|
+
const run2 = deps.run ?? runWithTimeout;
|
|
32881
|
+
const limit = deps.updateTimeoutMs ?? STEAMCMD_UPDATE_TIMEOUT_MS;
|
|
32882
|
+
for (let attempt = 1; attempt <= 2; attempt++) {
|
|
32883
|
+
log2(attempt === 1 ? "SteamCMD: checking for updates ..." : "SteamCMD: trying its update once more ...");
|
|
32884
|
+
const result = await run2(exe, ["+quit"], work, limit);
|
|
32885
|
+
if (result.timedOut)
|
|
32886
|
+
throw new Error("SteamCMD did not finish updating itself in " + Math.round(limit / 6e4) + " minutes");
|
|
32887
|
+
if (bootstrapped(work)) break;
|
|
32888
|
+
if (attempt === 2) throw new Error("SteamCMD did not finish its first run (exit code " + result.code + ")");
|
|
32889
|
+
}
|
|
32890
|
+
if (!deps.signed(exe)) throw notSigned(exe);
|
|
32891
|
+
if (snapshot(work) !== before || !bootstrapped(store2)) {
|
|
32892
|
+
const staging = stagingFolder(store2);
|
|
32893
|
+
try {
|
|
32894
|
+
await copyBinaries(work, staging);
|
|
32895
|
+
moveIntoPlace(staging, store2);
|
|
32896
|
+
} finally {
|
|
32897
|
+
if (fs54.existsSync(staging)) safeRemove(staging, path68.dirname(staging));
|
|
32898
|
+
}
|
|
32899
|
+
}
|
|
32900
|
+
return exe;
|
|
32901
|
+
}
|
|
32902
|
+
|
|
32903
|
+
// src/guest/toolchains/steam/steamcmd.ts
|
|
32904
|
+
function installSteamCmd() {
|
|
32905
|
+
return prepareSteamCmd({ signed: (file3) => signedBy(file3, SIGNERS.valve), log });
|
|
32906
|
+
}
|
|
32907
|
+
|
|
32908
|
+
// src/guest/toolchains/steam/steam.ts
|
|
32909
|
+
function signedInAs() {
|
|
32910
|
+
const bytes = readBoundedFile(steamConfigFile(STEAMCMD_DIR), 256 * 1024);
|
|
32911
|
+
if (!bytes || !hasCachedLogin(bytes.toString("utf8"))) return null;
|
|
32912
|
+
return readSteamAccountFile(STEAMCMD_DIR) ?? "your account";
|
|
32913
|
+
}
|
|
32914
|
+
function sdkFolder(env, setting) {
|
|
32915
|
+
if (!setting.trim()) return;
|
|
32916
|
+
const dir = path69.resolve(projectWorkspace(), setting.trim());
|
|
32917
|
+
let ok = false;
|
|
32918
|
+
try {
|
|
32919
|
+
ok = fs55.statSync(dir).isDirectory();
|
|
32920
|
+
} catch {
|
|
32921
|
+
}
|
|
32922
|
+
if (!ok) {
|
|
32923
|
+
log("Steamworks SDK: " + dir + " is not there (toolchains.steam.sdkFolder); STEAMWORKS_SDK is not set");
|
|
32924
|
+
env.summary.push("steamworks sdk: " + dir + " not found");
|
|
32925
|
+
return;
|
|
32926
|
+
}
|
|
32927
|
+
env.vars.STEAMWORKS_SDK = dir;
|
|
32928
|
+
env.summary.push("steamworks sdk: STEAMWORKS_SDK=" + dir);
|
|
32929
|
+
}
|
|
32930
|
+
async function setupSteam(env, config2, ctx) {
|
|
32931
|
+
if (dryRun) {
|
|
32932
|
+
log("(dry run) would set up SteamCMD" + (config2.client ? " and the Steam client" : ""));
|
|
32933
|
+
return;
|
|
32934
|
+
}
|
|
32935
|
+
const exe = await installSteamCmd();
|
|
32936
|
+
env.append.push(STEAMCMD_DIR);
|
|
32937
|
+
env.vars.STEAMCMD = exe;
|
|
32938
|
+
const user = signedInAs();
|
|
32939
|
+
env.summary.push(
|
|
32940
|
+
"steamcmd: C:\\SteamCMD, " + (user ? "signed in as " + user : "not signed in (sbx-steam login <account>)")
|
|
32941
|
+
);
|
|
32942
|
+
sdkFolder(env, config2.sdkFolder);
|
|
32943
|
+
const fromPc = ctx.pcInstalls.items.filter((i) => i.kind === "steam-game" || i.kind === "steam-library");
|
|
32944
|
+
if (fromPc.length)
|
|
32945
|
+
env.summary.push(
|
|
32946
|
+
"steam: " + fromPc.length + " of this PC's games or libraries, read-only in C:\\PcInstalls\\steam"
|
|
32947
|
+
);
|
|
32948
|
+
if (!config2.client) return;
|
|
32949
|
+
if (ctx.duringSession && !installedSteamClient()) {
|
|
32950
|
+
env.summary.push("steam client: restart the sandbox to install it");
|
|
32951
|
+
return;
|
|
32952
|
+
}
|
|
32953
|
+
await ensureSteamClient(env);
|
|
32954
|
+
}
|
|
32955
|
+
|
|
32956
|
+
// src/guest/toolchains/engines/godot.ts
|
|
32957
|
+
async function setupGodot(env, _config, _ctx) {
|
|
32958
|
+
notAvailableYet(env, "Godot");
|
|
32959
|
+
}
|
|
32960
|
+
|
|
32961
|
+
// src/guest/toolchains/engines/unity.ts
|
|
32962
|
+
async function setupUnity(env, _config, _ctx) {
|
|
32963
|
+
notAvailableYet(env, "Unity");
|
|
32964
|
+
}
|
|
32965
|
+
|
|
32966
|
+
// src/guest/toolchains/fivem/fivem.ts
|
|
32967
|
+
async function setupFivem(env, _config, _ctx) {
|
|
32968
|
+
notAvailableYet(env, "FiveM server");
|
|
32969
|
+
}
|
|
32970
|
+
|
|
32971
|
+
// src/guest/toolchains/mobile/android.ts
|
|
32972
|
+
async function setupAndroid(env, _config, _ctx) {
|
|
32973
|
+
notAvailableYet(env, "Android SDK");
|
|
32974
|
+
}
|
|
32975
|
+
|
|
32976
|
+
// src/guest/toolchains/mobile/flutter.ts
|
|
32977
|
+
async function setupFlutter(env, _config, _ctx) {
|
|
32978
|
+
notAvailableYet(env, "Flutter");
|
|
32979
|
+
}
|
|
32980
|
+
|
|
32981
|
+
// src/guest/toolchains/mobile/dart.ts
|
|
32982
|
+
async function setupDart(env, _config, _ctx) {
|
|
32983
|
+
notAvailableYet(env, "Dart");
|
|
32984
|
+
}
|
|
32985
|
+
|
|
32986
|
+
// src/guest/toolchains/mobile/react-native.ts
|
|
32987
|
+
async function setupReactNative(env, _config, _ctx) {
|
|
32988
|
+
notAvailableYet(env, "React Native");
|
|
32989
|
+
}
|
|
32990
|
+
|
|
32991
|
+
// src/guest/toolchains/languages/kotlin.ts
|
|
32992
|
+
async function setupKotlin(env, _ctx) {
|
|
32993
|
+
notAvailableYet(env, "Kotlin");
|
|
32994
|
+
}
|
|
32995
|
+
|
|
31937
32996
|
// src/guest/toolchains/native/rust-extras.ts
|
|
31938
|
-
import
|
|
31939
|
-
import
|
|
31940
|
-
import
|
|
32997
|
+
import fs56 from "node:fs";
|
|
32998
|
+
import os10 from "node:os";
|
|
32999
|
+
import path70 from "node:path";
|
|
31941
33000
|
|
|
31942
33001
|
// src/shared/memory/policy.ts
|
|
31943
33002
|
var DIAL_STEPS = {
|
|
@@ -31986,41 +33045,41 @@ function maxCompilers(cpus, profile) {
|
|
|
31986
33045
|
// src/guest/toolchains/native/rust-extras.ts
|
|
31987
33046
|
var cargoTarget = (targetDir) => {
|
|
31988
33047
|
if (targetDir === "shared" || targetDir === "separate") return null;
|
|
31989
|
-
if (targetDir === "local") return
|
|
33048
|
+
if (targetDir === "local") return path70.join(localDir, "cargo-target");
|
|
31990
33049
|
return targetDir;
|
|
31991
33050
|
};
|
|
31992
33051
|
function cargoShim(env, rust) {
|
|
31993
|
-
const real =
|
|
33052
|
+
const real = path70.join(tool("rust", "cargo", "bin"), "cargo.exe");
|
|
31994
33053
|
if (rust.targetDir !== "separate" || !exists(real)) return;
|
|
31995
33054
|
const dir = mkdirp(tool("shims", "cargo"));
|
|
31996
|
-
|
|
33055
|
+
fs56.copyFileSync(ensureCompiled("cargoshim"), path70.join(dir, "cargo.exe"));
|
|
31997
33056
|
env.prepend.unshift(dir);
|
|
31998
33057
|
env.vars.AGENT_REAL_CARGO = real;
|
|
31999
33058
|
}
|
|
32000
33059
|
function linkGate(env, rust, host) {
|
|
32001
33060
|
const gcc = tool("mingw", "mingw64", "bin", "gcc.exe");
|
|
32002
33061
|
if (!host.endsWith("-pc-windows-gnu") || !exists(gcc)) return;
|
|
32003
|
-
const gate =
|
|
32004
|
-
|
|
32005
|
-
const memoryGb =
|
|
33062
|
+
const gate = path70.join(mkdirp(tool("shims")), "linkgate.exe");
|
|
33063
|
+
fs56.copyFileSync(ensureCompiled("linkgate"), gate);
|
|
33064
|
+
const memoryGb = os10.totalmem() / 1024 ** 3;
|
|
32006
33065
|
const slots = rust.linkSlots === "auto" ? linkSlotsFor(memoryGb) : rust.linkSlots;
|
|
32007
33066
|
env.vars.AGENT_LINK_SLOTS = String(slots);
|
|
32008
33067
|
env.vars.AGENT_REAL_LINKER = gcc;
|
|
32009
33068
|
env.vars.CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER = gate;
|
|
32010
33069
|
const rustEnv = { ...process.env, RUSTUP_HOME: tool("rust", "rustup"), CARGO_HOME: tool("rust", "cargo") };
|
|
32011
33070
|
const sysroot = rust.linker === "lld" ? execOutput(tool("rust", "cargo", "bin", "rustc.exe"), ["--print", "sysroot"], { env: rustEnv }) : "";
|
|
32012
|
-
const lld = sysroot ?
|
|
32013
|
-
if (lld && exists(
|
|
33071
|
+
const lld = sysroot ? path70.join(sysroot, "lib", "rustlib", host, "bin", "gcc-ld") : "";
|
|
33072
|
+
if (lld && exists(path70.join(lld, "ld.lld.exe"))) env.vars.AGENT_LLD_DIR = lld;
|
|
32014
33073
|
env.summary.push(
|
|
32015
33074
|
"rust linking: " + (env.vars.AGENT_LLD_DIR ? "lld" : "GNU ld") + ", at most " + env.vars.AGENT_LINK_SLOTS + " at once"
|
|
32016
33075
|
);
|
|
32017
33076
|
}
|
|
32018
33077
|
function cargoDefaults(host) {
|
|
32019
33078
|
const file3 = tool("rust", "cargo", "config.toml");
|
|
32020
|
-
if (exists(file3) || !exists(
|
|
32021
|
-
const jobs = cargoJobs(
|
|
33079
|
+
if (exists(file3) || !exists(path70.dirname(file3))) return;
|
|
33080
|
+
const jobs = cargoJobs(os10.cpus().length, os10.totalmem() / 1024 ** 3, 1);
|
|
32022
33081
|
const gnu = host.endsWith("-gnu");
|
|
32023
|
-
|
|
33082
|
+
fs56.writeFileSync(
|
|
32024
33083
|
file3,
|
|
32025
33084
|
[
|
|
32026
33085
|
"# Written by windows-development-sandbox once; edit freely, it is never overwritten.",
|
|
@@ -32035,7 +33094,7 @@ function rustCaches(rust) {
|
|
|
32035
33094
|
const target = cargoTarget(rust.targetDir);
|
|
32036
33095
|
return {
|
|
32037
33096
|
...target ? { CARGO_TARGET_DIR: target } : {},
|
|
32038
|
-
...process.env.SCCACHE_DIR ? {} : { SCCACHE_DIR:
|
|
33097
|
+
...process.env.SCCACHE_DIR ? {} : { SCCACHE_DIR: path70.join(dataDir, "cache", "sccache") }
|
|
32039
33098
|
};
|
|
32040
33099
|
}
|
|
32041
33100
|
function rustHost(config2) {
|
|
@@ -32063,6 +33122,13 @@ function plan(config2, versions, o) {
|
|
|
32063
33122
|
const java = wanted(config2.java.enabled, "java");
|
|
32064
33123
|
const python = wanted(config2.python.enabled, "python");
|
|
32065
33124
|
const unreal = wanted(config2.unreal.enabled, "unreal");
|
|
33125
|
+
const android = wanted(config2.android.enabled, "android");
|
|
33126
|
+
const vs = visualStudioWanted(config2, (setting, name) => wanted(setting, name));
|
|
33127
|
+
const ctx = {
|
|
33128
|
+
refresh: o.refresh,
|
|
33129
|
+
pcInstalls: o.pcInstalls ?? { items: [] },
|
|
33130
|
+
duringSession: duringSession()
|
|
33131
|
+
};
|
|
32066
33132
|
return [
|
|
32067
33133
|
{
|
|
32068
33134
|
name: "Git",
|
|
@@ -32080,18 +33146,32 @@ function plan(config2, versions, o) {
|
|
|
32080
33146
|
enabled: wanted(config2.cpp.enabled, "cpp") || wanted(config2.rust.enabled, "rust"),
|
|
32081
33147
|
install: (env) => setupCpp(env, config2.cpp)
|
|
32082
33148
|
},
|
|
32083
|
-
//
|
|
32084
|
-
{
|
|
33149
|
+
// Visual Studio brings MSVC and the real vswhere: the portable MSVC (and its stand-in vswhere) stays out.
|
|
33150
|
+
{
|
|
33151
|
+
name: "Visual Studio",
|
|
33152
|
+
enabled: vs !== null,
|
|
33153
|
+
shared: true,
|
|
33154
|
+
install: async (env) => {
|
|
33155
|
+
await ensureVisualStudio(env, vs, { keepInstallFiles: config2.unreal.keepInstallFiles });
|
|
33156
|
+
}
|
|
33157
|
+
},
|
|
33158
|
+
{
|
|
33159
|
+
name: "Unreal",
|
|
33160
|
+
enabled: unreal,
|
|
33161
|
+
shared: true,
|
|
33162
|
+
after: ["Visual Studio"],
|
|
33163
|
+
install: (env) => setupUnreal(env, config2.unreal, ctx)
|
|
33164
|
+
},
|
|
32085
33165
|
{
|
|
32086
33166
|
name: "MSVC",
|
|
32087
|
-
enabled: wanted(config2.msvc.enabled, "msvc") &&
|
|
33167
|
+
enabled: wanted(config2.msvc.enabled, "msvc") && vs === null,
|
|
32088
33168
|
install: (env) => setupMsvc(env, config2.msvc)
|
|
32089
33169
|
},
|
|
32090
33170
|
// Rust links with MSVC (msvc host) or MinGW's gcc (GNU host): whichever it uses goes first.
|
|
32091
33171
|
{
|
|
32092
33172
|
name: "Rust",
|
|
32093
33173
|
enabled: wanted(config2.rust.enabled, "rust"),
|
|
32094
|
-
after: ["C/C++", "MSVC", "Unreal"],
|
|
33174
|
+
after: ["C/C++", "MSVC", "Visual Studio", "Unreal"],
|
|
32095
33175
|
install: async (env) => {
|
|
32096
33176
|
await setupRust(env, { ...config2.rust, host: rustHost(config2) }, o.refresh);
|
|
32097
33177
|
Object.assign(env.vars, rustCaches(config2.rust));
|
|
@@ -32109,6 +33189,49 @@ function plan(config2, versions, o) {
|
|
|
32109
33189
|
},
|
|
32110
33190
|
{ name: "Go", enabled: wanted(config2.go.enabled, "go"), install: (env) => setupGo(env, config2.go) },
|
|
32111
33191
|
{ name: "Java", enabled: java, install: (env) => setupJava(env, config2.java) },
|
|
33192
|
+
{ name: "Kotlin", enabled: java && config2.java.kotlin, after: ["Java"], install: (env) => setupKotlin(env, ctx) },
|
|
33193
|
+
// Game engines, stores and mobile: each module keeps its big installs in tools (persisted.ts).
|
|
33194
|
+
{
|
|
33195
|
+
name: "Android SDK",
|
|
33196
|
+
enabled: android,
|
|
33197
|
+
after: ["Java"],
|
|
33198
|
+
install: (env) => setupAndroid(env, config2.android, ctx)
|
|
33199
|
+
},
|
|
33200
|
+
{
|
|
33201
|
+
name: "Steam",
|
|
33202
|
+
enabled: wanted(config2.steam.enabled, "steam"),
|
|
33203
|
+
install: (env) => setupSteam(env, config2.steam, ctx)
|
|
33204
|
+
},
|
|
33205
|
+
{
|
|
33206
|
+
name: "Unity",
|
|
33207
|
+
enabled: wanted(config2.unity.enabled, "unity"),
|
|
33208
|
+
after: ["Visual Studio", "Android SDK"],
|
|
33209
|
+
install: (env) => setupUnity(env, config2.unity, ctx)
|
|
33210
|
+
},
|
|
33211
|
+
{
|
|
33212
|
+
name: "Godot",
|
|
33213
|
+
enabled: wanted(config2.godot.enabled, "godot"),
|
|
33214
|
+
after: [".NET", "Android SDK"],
|
|
33215
|
+
install: (env) => setupGodot(env, config2.godot, ctx)
|
|
33216
|
+
},
|
|
33217
|
+
{
|
|
33218
|
+
name: "FiveM server",
|
|
33219
|
+
enabled: wanted(config2.fivem.enabled, "fivem"),
|
|
33220
|
+
install: (env) => setupFivem(env, config2.fivem, ctx)
|
|
33221
|
+
},
|
|
33222
|
+
{
|
|
33223
|
+
name: "Flutter",
|
|
33224
|
+
enabled: wanted(config2.flutter.enabled, "flutter"),
|
|
33225
|
+
after: ["Visual Studio", "Android SDK"],
|
|
33226
|
+
install: (env) => setupFlutter(env, config2.flutter, ctx)
|
|
33227
|
+
},
|
|
33228
|
+
{ name: "Dart", enabled: wanted(config2.dart.enabled, "dart"), install: (env) => setupDart(env, config2.dart, ctx) },
|
|
33229
|
+
{
|
|
33230
|
+
name: "React Native",
|
|
33231
|
+
enabled: wanted(config2.reactNative.enabled, "reactNative"),
|
|
33232
|
+
after: ["Android SDK"],
|
|
33233
|
+
install: (env) => setupReactNative(env, config2.reactNative, ctx)
|
|
33234
|
+
},
|
|
32112
33235
|
{ name: "Ruby", enabled: wanted(config2.ruby.enabled, "ruby"), install: (env) => setupRuby(env, config2.ruby) },
|
|
32113
33236
|
// PHP installs the Visual C++ runtime itself: one installer at a time.
|
|
32114
33237
|
// Many apps (bat, delta, Neovim, most GUIs, your own programs) are built against it too.
|
|
@@ -32184,7 +33307,7 @@ function plan(config2, versions, o) {
|
|
|
32184
33307
|
import { AsyncLocalStorage as AsyncLocalStorage2 } from "node:async_hooks";
|
|
32185
33308
|
|
|
32186
33309
|
// src/guest/runtime/status.ts
|
|
32187
|
-
import
|
|
33310
|
+
import os11 from "node:os";
|
|
32188
33311
|
var progress;
|
|
32189
33312
|
function setSandboxStatus(phase, message, update) {
|
|
32190
33313
|
try {
|
|
@@ -32208,7 +33331,7 @@ function fitProgress(p) {
|
|
|
32208
33331
|
};
|
|
32209
33332
|
}
|
|
32210
33333
|
function ownAddresses() {
|
|
32211
|
-
return Object.values(
|
|
33334
|
+
return Object.values(os11.networkInterfaces()).flat().filter((i) => Boolean(i) && i.family === "IPv4" && !i.internal).map((i) => i.address).slice(0, 8);
|
|
32212
33335
|
}
|
|
32213
33336
|
function writeStatus(phase, message) {
|
|
32214
33337
|
writeJsonAtomic(run.sandboxFile, {
|
|
@@ -32353,21 +33476,21 @@ function cmdSet(env, names) {
|
|
|
32353
33476
|
return names.filter((n) => env[n] !== void 0 && !/[\r\n]/.test(String(env[n]))).map((n) => '@set "' + n + "=" + String(env[n]).replace(/%/g, "%%") + '"');
|
|
32354
33477
|
}
|
|
32355
33478
|
function writeShell(spec, env, names) {
|
|
32356
|
-
const dir = mkdirp(
|
|
32357
|
-
|
|
32358
|
-
|
|
32359
|
-
|
|
32360
|
-
['@call "' +
|
|
33479
|
+
const dir = mkdirp(path71.join(localDir, "projects", spec.name));
|
|
33480
|
+
fs57.writeFileSync(path71.join(dir, "env.cmd"), [...cmdSet(env, [...names, "PATH"]), ""].join("\r\n"));
|
|
33481
|
+
fs57.writeFileSync(
|
|
33482
|
+
path71.join(dir, "shell.cmd"),
|
|
33483
|
+
['@call "' + path71.join(dir, "env.cmd") + '"', '@cd /d "' + spec.workspace + '"', "@title " + spec.name, ""].join(
|
|
32361
33484
|
"\r\n"
|
|
32362
33485
|
)
|
|
32363
33486
|
);
|
|
32364
|
-
const bin = mkdirp(
|
|
32365
|
-
|
|
32366
|
-
|
|
33487
|
+
const bin = mkdirp(path71.join(localDir, "bin"));
|
|
33488
|
+
fs57.writeFileSync(
|
|
33489
|
+
path71.join(bin, "sbx-shell.cmd"),
|
|
32367
33490
|
[
|
|
32368
|
-
'@if "%~1"=="" (echo Usage: sbx-shell ^<project^> ^(a terminal in that project with its tools^) & dir /b "' +
|
|
32369
|
-
'@if not exist "' +
|
|
32370
|
-
'@cmd /k ""' +
|
|
33491
|
+
'@if "%~1"=="" (echo Usage: sbx-shell ^<project^> ^(a terminal in that project with its tools^) & dir /b "' + path71.join(localDir, "projects") + '" & exit /b 2)',
|
|
33492
|
+
'@if not exist "' + path71.join(localDir, "projects") + '\\%~1\\shell.cmd" (echo No project %~1 in this sandbox. & exit /b 2)',
|
|
33493
|
+
'@cmd /k ""' + path71.join(localDir, "projects") + '\\%~1\\shell.cmd""',
|
|
32371
33494
|
""
|
|
32372
33495
|
].join("\r\n")
|
|
32373
33496
|
);
|
|
@@ -32420,10 +33543,10 @@ async function setUp(spec, say) {
|
|
|
32420
33543
|
}
|
|
32421
33544
|
)
|
|
32422
33545
|
);
|
|
32423
|
-
tools.prepend.push(
|
|
33546
|
+
tools.prepend.push(path71.join(localDir, "bin"));
|
|
32424
33547
|
const env = agentEnv(tools, { workspace: spec.workspace, project: spec.name, base });
|
|
32425
|
-
const specFile =
|
|
32426
|
-
|
|
33548
|
+
const specFile = path71.join(mkdirp(path71.join(localDir, "projects", spec.name)), "project.json");
|
|
33549
|
+
fs57.writeFileSync(specFile, JSON.stringify(spec));
|
|
32427
33550
|
env.AGENT_PROJECT_FILE = specFile;
|
|
32428
33551
|
addMachineEnvironment(tools.vars, [...tools.prepend, ...tools.append], true);
|
|
32429
33552
|
try {
|
|
@@ -32511,7 +33634,7 @@ function execCommand(req) {
|
|
|
32511
33634
|
return;
|
|
32512
33635
|
}
|
|
32513
33636
|
const env = withRegistryPath(provisioner.provisionedFor(req.cwd)?.env ?? process.env);
|
|
32514
|
-
const child =
|
|
33637
|
+
const child = spawn6(
|
|
32515
33638
|
SYSTEM.cmd(),
|
|
32516
33639
|
["/d", "/s", "/c", '"chcp 65001>nul & ' + req.command.map(quoteForCmd).join(" ") + '"'],
|
|
32517
33640
|
{ cwd: req.cwd, env, windowsHide: true, windowsVerbatimArguments: true }
|
|
@@ -32540,11 +33663,11 @@ function execCommand(req) {
|
|
|
32540
33663
|
}
|
|
32541
33664
|
|
|
32542
33665
|
// src/guest/daemon/sessions.ts
|
|
32543
|
-
import
|
|
32544
|
-
import
|
|
32545
|
-
import
|
|
32546
|
-
import
|
|
32547
|
-
import { spawn as
|
|
33666
|
+
import fs63 from "node:fs";
|
|
33667
|
+
import path80 from "node:path";
|
|
33668
|
+
import crypto5 from "node:crypto";
|
|
33669
|
+
import os13 from "node:os";
|
|
33670
|
+
import { spawn as spawn8 } from "node:child_process";
|
|
32548
33671
|
|
|
32549
33672
|
// src/shared/pty/protocol.ts
|
|
32550
33673
|
var FrameType = {
|
|
@@ -32622,7 +33745,7 @@ async function sendControl(endpoint, type) {
|
|
|
32622
33745
|
var MAX_CLIPBOARD_STRING = 1024 * 1024;
|
|
32623
33746
|
|
|
32624
33747
|
// src/guest/sessions/cmdline.ts
|
|
32625
|
-
import
|
|
33748
|
+
import path72 from "node:path";
|
|
32626
33749
|
var quoted = (arg) => '"' + arg.replace(/(\\*)"/g, '$1$1\\"').replace(/(\\+)$/, "$1$1") + '"';
|
|
32627
33750
|
function quoteArg(arg) {
|
|
32628
33751
|
return arg !== "" && !/[\s"]/.test(arg) ? arg : quoted(arg);
|
|
@@ -32636,7 +33759,7 @@ function cmdArgs(args) {
|
|
|
32636
33759
|
}).join("");
|
|
32637
33760
|
}
|
|
32638
33761
|
function commandLine(file3, args) {
|
|
32639
|
-
return
|
|
33762
|
+
return path72.win32.basename(file3).toLowerCase() === "cmd.exe" ? [quoteArg(file3), cmdArgs(args)].filter(Boolean).join(" ") : [file3, ...args].map(quoteArg).join(" ");
|
|
32640
33763
|
}
|
|
32641
33764
|
function shellLaunch(asked, paths) {
|
|
32642
33765
|
if (asked === "cmd") return { name: "cmd", file: paths.cmd, args: [] };
|
|
@@ -32650,9 +33773,9 @@ function shellLaunch(asked, paths) {
|
|
|
32650
33773
|
}
|
|
32651
33774
|
|
|
32652
33775
|
// src/guest/sessions/pty-host.ts
|
|
32653
|
-
import
|
|
32654
|
-
import
|
|
32655
|
-
import { execFile, spawn as
|
|
33776
|
+
import fs58 from "node:fs";
|
|
33777
|
+
import path73 from "node:path";
|
|
33778
|
+
import { execFile, spawn as spawn7 } from "node:child_process";
|
|
32656
33779
|
function ensurePtyHost() {
|
|
32657
33780
|
return ensureCompiled("ptyhost");
|
|
32658
33781
|
}
|
|
@@ -32670,21 +33793,21 @@ async function waitForPtyHost(child, port, timeoutMs) {
|
|
|
32670
33793
|
throw new Error("the session host did not start listening on port " + port);
|
|
32671
33794
|
}
|
|
32672
33795
|
function ptyHostLog(id) {
|
|
32673
|
-
return
|
|
33796
|
+
return path73.join(logsDir, "ptyhost-" + id + ".log");
|
|
32674
33797
|
}
|
|
32675
33798
|
function ptyHostLogTail(id, lines = 12) {
|
|
32676
33799
|
try {
|
|
32677
|
-
return
|
|
33800
|
+
return fs58.readFileSync(ptyHostLog(id), "utf8").trim().split(/\r?\n/).slice(-lines).join("\n");
|
|
32678
33801
|
} catch {
|
|
32679
33802
|
return "";
|
|
32680
33803
|
}
|
|
32681
33804
|
}
|
|
32682
33805
|
var conptyDll = () => {
|
|
32683
|
-
const dll =
|
|
32684
|
-
return session.provisioning.conpty?.enabled !== false &&
|
|
33806
|
+
const dll = path73.join(toolsDir, "conpty", "conpty.dll");
|
|
33807
|
+
return session.provisioning.conpty?.enabled !== false && fs58.existsSync(dll) && fs58.existsSync(path73.join(toolsDir, "conpty", "OpenConsole.exe")) ? dll : null;
|
|
32685
33808
|
};
|
|
32686
33809
|
function startPtyHost(o) {
|
|
32687
|
-
|
|
33810
|
+
fs58.mkdirSync(run.treesDir, { recursive: true });
|
|
32688
33811
|
const env = {
|
|
32689
33812
|
...o.env,
|
|
32690
33813
|
PTYHOST_BIND: o.remote ? "any" : "loopback",
|
|
@@ -32693,7 +33816,7 @@ function startPtyHost(o) {
|
|
|
32693
33816
|
delete env.PTYHOST_CONPTY;
|
|
32694
33817
|
const dll = conptyDll();
|
|
32695
33818
|
if (dll) env.PTYHOST_CONPTY = dll;
|
|
32696
|
-
return
|
|
33819
|
+
return spawn7(
|
|
32697
33820
|
o.exe,
|
|
32698
33821
|
[String(o.port), o.token, String(o.cols), String(o.rows), ptyHostLog(o.id), o.command, o.restartCommand],
|
|
32699
33822
|
{ cwd: o.cwd, env, detached: true, stdio: "ignore", windowsHide: true }
|
|
@@ -32702,13 +33825,13 @@ function startPtyHost(o) {
|
|
|
32702
33825
|
var END_TREE_MS = 3e4;
|
|
32703
33826
|
function endLeftoverTree(id, exe = ensurePtyHost()) {
|
|
32704
33827
|
const file3 = run.treeFile(id);
|
|
32705
|
-
if (!
|
|
33828
|
+
if (!fs58.existsSync(file3)) return Promise.resolve(null);
|
|
32706
33829
|
return new Promise((resolve2) => {
|
|
32707
33830
|
execFile(exe, ["--end-tree", file3], { timeout: END_TREE_MS, windowsHide: true }, (error62, stdout) => {
|
|
32708
33831
|
const code = error62 ? typeof error62.code === "number" ? error62.code : -1 : 0;
|
|
32709
33832
|
if (code !== 3)
|
|
32710
33833
|
try {
|
|
32711
|
-
|
|
33834
|
+
fs58.rmSync(file3, { force: true });
|
|
32712
33835
|
} catch {
|
|
32713
33836
|
}
|
|
32714
33837
|
resolve2(code === 0 ? stdout.trim().slice(0, 200) : code === 3 ? null : "could not end them (code " + code + ")");
|
|
@@ -32717,15 +33840,15 @@ function endLeftoverTree(id, exe = ensurePtyHost()) {
|
|
|
32717
33840
|
}
|
|
32718
33841
|
function recordedTrees() {
|
|
32719
33842
|
try {
|
|
32720
|
-
return
|
|
33843
|
+
return fs58.readdirSync(run.treesDir).filter((n) => /^[A-Za-z0-9_-]{1,64}\.json$/.test(n)).map((n) => n.slice(0, -".json".length));
|
|
32721
33844
|
} catch {
|
|
32722
33845
|
return [];
|
|
32723
33846
|
}
|
|
32724
33847
|
}
|
|
32725
33848
|
|
|
32726
33849
|
// src/guest/agents/agent-installer.ts
|
|
32727
|
-
import
|
|
32728
|
-
import
|
|
33850
|
+
import fs59 from "node:fs";
|
|
33851
|
+
import path74 from "node:path";
|
|
32729
33852
|
|
|
32730
33853
|
// src/guest/agents/profile-links.ts
|
|
32731
33854
|
var profileRoot = () => process.env.USERPROFILE ?? "";
|
|
@@ -32751,7 +33874,7 @@ var agentPaths2 = (name, harness) => agentPaths(toolsDir, name, harness);
|
|
|
32751
33874
|
async function installViaNpm(name, harness, dir, env) {
|
|
32752
33875
|
if (!harness.npmPackage)
|
|
32753
33876
|
throw new Error("No npmPackage configured for " + name + " and no host executable was available.");
|
|
32754
|
-
const npmCli =
|
|
33877
|
+
const npmCli = path74.join(path74.dirname(process.execPath), "node_modules", "npm", "bin", "npm-cli.js");
|
|
32755
33878
|
const args = [npmCli, "install", "--global", "--prefix", dir, harness.npmPackage, "--no-fund", "--no-audit"];
|
|
32756
33879
|
log("Installing " + harness.npmPackage + " (this can take a minute)...");
|
|
32757
33880
|
if (dryRun) {
|
|
@@ -32762,7 +33885,7 @@ async function installViaNpm(name, harness, dir, env) {
|
|
|
32762
33885
|
await execAsync(process.execPath, args, { env });
|
|
32763
33886
|
}
|
|
32764
33887
|
async function installViaUv(name, harness, dir, env) {
|
|
32765
|
-
const uv =
|
|
33888
|
+
const uv = path74.join(toolsDir, "uv", "uv.exe");
|
|
32766
33889
|
log("Installing " + harness.uvPackage + " with uv (this can take a minute)...");
|
|
32767
33890
|
if (dryRun) {
|
|
32768
33891
|
log("(dry run) uv tool install " + harness.uvPackage);
|
|
@@ -32777,8 +33900,8 @@ async function installViaUv(name, harness, dir, env) {
|
|
|
32777
33900
|
});
|
|
32778
33901
|
}
|
|
32779
33902
|
function putOnPath(dir, env) {
|
|
32780
|
-
const parts2 = (env.PATH ?? "").split(
|
|
32781
|
-
if (!parts2.some((p) => p.toLowerCase() === dir.toLowerCase())) env.PATH = [...parts2, dir].join(
|
|
33903
|
+
const parts2 = (env.PATH ?? "").split(path74.delimiter);
|
|
33904
|
+
if (!parts2.some((p) => p.toLowerCase() === dir.toLowerCase())) env.PATH = [...parts2, dir].join(path74.delimiter);
|
|
32782
33905
|
addMachineEnvironment({}, [dir], true);
|
|
32783
33906
|
}
|
|
32784
33907
|
var AgentInstaller = class {
|
|
@@ -32819,9 +33942,9 @@ var AgentInstaller = class {
|
|
|
32819
33942
|
}
|
|
32820
33943
|
mkdirp(p.dir);
|
|
32821
33944
|
if (this.sourceOf(name, harness) === "host") {
|
|
32822
|
-
const source =
|
|
33945
|
+
const source = path74.join(hostToolsDir, "agents", name, harness.hostExecutable);
|
|
32823
33946
|
if (exists(source) && p.exe) {
|
|
32824
|
-
|
|
33947
|
+
fs59.copyFileSync(source, p.exe);
|
|
32825
33948
|
log("Copied " + name + " from this PC: " + source);
|
|
32826
33949
|
return;
|
|
32827
33950
|
}
|
|
@@ -32836,28 +33959,28 @@ var AgentInstaller = class {
|
|
|
32836
33959
|
var agents = new AgentInstaller();
|
|
32837
33960
|
|
|
32838
33961
|
// src/guest/network/addresses.ts
|
|
32839
|
-
import
|
|
33962
|
+
import os12 from "node:os";
|
|
32840
33963
|
function guestAddresses() {
|
|
32841
|
-
return Object.values(
|
|
33964
|
+
return Object.values(os12.networkInterfaces()).flat().filter((i) => Boolean(i) && i.family === "IPv4" && !i.internal).map((i) => i.address);
|
|
32842
33965
|
}
|
|
32843
33966
|
|
|
32844
33967
|
// src/guest/sessions/conversation.ts
|
|
32845
|
-
import
|
|
32846
|
-
import
|
|
33968
|
+
import fs60 from "node:fs";
|
|
33969
|
+
import path75 from "node:path";
|
|
32847
33970
|
var MAX_FILES = 2e3;
|
|
32848
33971
|
function conversationFiles(claudeDir2, cwd) {
|
|
32849
33972
|
const names = /* @__PURE__ */ new Set([projectFolderName(cwd), projectFolderName(sandboxFolder(cwd))]);
|
|
32850
33973
|
return [...names].flatMap((name) => {
|
|
32851
|
-
const dir =
|
|
33974
|
+
const dir = path75.join(claudeDir2, "projects", name);
|
|
32852
33975
|
let entries2;
|
|
32853
33976
|
try {
|
|
32854
|
-
entries2 =
|
|
33977
|
+
entries2 = fs60.readdirSync(dir);
|
|
32855
33978
|
} catch {
|
|
32856
33979
|
return [];
|
|
32857
33980
|
}
|
|
32858
33981
|
return entries2.filter((e) => e.endsWith(".jsonl") && isConversationId(e.slice(0, -".jsonl".length))).slice(0, MAX_FILES).flatMap((e) => {
|
|
32859
33982
|
try {
|
|
32860
|
-
return [{ id: e.slice(0, -".jsonl".length), createdMs:
|
|
33983
|
+
return [{ id: e.slice(0, -".jsonl".length), createdMs: fs60.statSync(path75.join(dir, e)).birthtimeMs }];
|
|
32861
33984
|
} catch {
|
|
32862
33985
|
return [];
|
|
32863
33986
|
}
|
|
@@ -32870,6 +33993,263 @@ function findConversation(claudeDir2, cwd, sessionStartMs, claimed) {
|
|
|
32870
33993
|
|
|
32871
33994
|
// src/guest/daemon/idle-shutdown.ts
|
|
32872
33995
|
import { spawnSync as spawnSync6 } from "node:child_process";
|
|
33996
|
+
|
|
33997
|
+
// src/guest/accounts/watch.ts
|
|
33998
|
+
import fs62 from "node:fs";
|
|
33999
|
+
import path79 from "node:path";
|
|
34000
|
+
|
|
34001
|
+
// src/shared/accounts/fingerprint.ts
|
|
34002
|
+
import crypto4 from "node:crypto";
|
|
34003
|
+
function canonical2(value) {
|
|
34004
|
+
if (Array.isArray(value)) return "[" + value.map(canonical2).join(",") + "]";
|
|
34005
|
+
if (value && typeof value === "object")
|
|
34006
|
+
return "{" + Object.keys(value).filter((k) => value[k] !== void 0).sort().map((k) => JSON.stringify(k) + ":" + canonical2(value[k])).join(",") + "}";
|
|
34007
|
+
return JSON.stringify(value) ?? "null";
|
|
34008
|
+
}
|
|
34009
|
+
function fingerprint2(payload) {
|
|
34010
|
+
return crypto4.createHash("sha256").update(canonical2(payload)).digest("hex");
|
|
34011
|
+
}
|
|
34012
|
+
|
|
34013
|
+
// src/guest/accounts/adapter.ts
|
|
34014
|
+
import path76 from "node:path";
|
|
34015
|
+
function localAppData() {
|
|
34016
|
+
return process.env.LOCALAPPDATA ?? "C:\\Users\\WDAGUtilityAccount\\AppData\\Local";
|
|
34017
|
+
}
|
|
34018
|
+
function accountsRoot() {
|
|
34019
|
+
return path76.join(localAppData(), "AgentSandbox", "accounts");
|
|
34020
|
+
}
|
|
34021
|
+
function notAvailableYet2(kind) {
|
|
34022
|
+
return { summary: kind + ": using a saved sign-in is not available yet (it is not used)" };
|
|
34023
|
+
}
|
|
34024
|
+
|
|
34025
|
+
// src/guest/accounts/kinds/appstore.ts
|
|
34026
|
+
var appstoreAdapter = {
|
|
34027
|
+
kind: "appstore",
|
|
34028
|
+
apply(_p) {
|
|
34029
|
+
return notAvailableYet2("appstore");
|
|
34030
|
+
}
|
|
34031
|
+
};
|
|
34032
|
+
|
|
34033
|
+
// src/guest/accounts/kinds/cfx.ts
|
|
34034
|
+
var cfxAdapter = {
|
|
34035
|
+
kind: "cfx",
|
|
34036
|
+
apply(_p) {
|
|
34037
|
+
return notAvailableYet2("cfx");
|
|
34038
|
+
}
|
|
34039
|
+
};
|
|
34040
|
+
|
|
34041
|
+
// src/guest/accounts/kinds/epic.ts
|
|
34042
|
+
import fs61 from "node:fs";
|
|
34043
|
+
import path77 from "node:path";
|
|
34044
|
+
|
|
34045
|
+
// src/shared/accounts/kinds/epic.ts
|
|
34046
|
+
var MAX_EPIC_INI_BYTES = 1024 * 1024;
|
|
34047
|
+
var SECTION = "[rememberme]";
|
|
34048
|
+
function epicSettingsFile(localAppData2) {
|
|
34049
|
+
return localAppData2 + "\\EpicGamesLauncher\\Saved\\Config\\Windows\\GameUserSettings.ini";
|
|
34050
|
+
}
|
|
34051
|
+
var isHeader = (line) => line.trimStart().startsWith("[");
|
|
34052
|
+
function readEpicLogin(ini) {
|
|
34053
|
+
let inSection = false;
|
|
34054
|
+
let enabled2 = true;
|
|
34055
|
+
let data = null;
|
|
34056
|
+
for (const raw of ini.split(/\r?\n/)) {
|
|
34057
|
+
const line = raw.trim();
|
|
34058
|
+
if (isHeader(line)) {
|
|
34059
|
+
inSection = line.toLowerCase() === SECTION;
|
|
34060
|
+
continue;
|
|
34061
|
+
}
|
|
34062
|
+
if (!inSection) continue;
|
|
34063
|
+
const at = line.indexOf("=");
|
|
34064
|
+
if (at < 0) continue;
|
|
34065
|
+
const key2 = line.slice(0, at).trim().toLowerCase();
|
|
34066
|
+
const value = line.slice(at + 1).trim();
|
|
34067
|
+
if (key2 === "enable") enabled2 = value.toLowerCase() === "true";
|
|
34068
|
+
else if (key2 === "data") data = value;
|
|
34069
|
+
}
|
|
34070
|
+
if (!enabled2 || !data) return null;
|
|
34071
|
+
const parsed = EpicPayloadSchema.safeParse({ data });
|
|
34072
|
+
return parsed.success ? parsed.data : null;
|
|
34073
|
+
}
|
|
34074
|
+
function withEpicLogin(ini, login) {
|
|
34075
|
+
const kept = [];
|
|
34076
|
+
let inSection = false;
|
|
34077
|
+
for (const line of ini.split(/\r?\n/)) {
|
|
34078
|
+
if (isHeader(line)) inSection = line.trim().toLowerCase() === SECTION;
|
|
34079
|
+
if (!inSection) kept.push(line);
|
|
34080
|
+
}
|
|
34081
|
+
while (kept.length && kept[kept.length - 1].trim() === "") kept.pop();
|
|
34082
|
+
const section = ["[RememberMe]", "Enable=True", "Data=" + EpicPayloadSchema.parse(login).data];
|
|
34083
|
+
return [...kept, ...kept.length ? [""] : [], ...section, ""].join("\r\n");
|
|
34084
|
+
}
|
|
34085
|
+
|
|
34086
|
+
// src/guest/accounts/kinds/epic.ts
|
|
34087
|
+
function settingsFile() {
|
|
34088
|
+
return epicSettingsFile(localAppData());
|
|
34089
|
+
}
|
|
34090
|
+
var epicAdapter = {
|
|
34091
|
+
kind: "epic",
|
|
34092
|
+
apply(p) {
|
|
34093
|
+
const file3 = settingsFile();
|
|
34094
|
+
const bytes = readBoundedFile(file3, MAX_EPIC_INI_BYTES);
|
|
34095
|
+
const read = bytes ? decodeText(bytes) : { text: "", encoding: "utf8" };
|
|
34096
|
+
fs61.mkdirSync(path77.dirname(file3), { recursive: true });
|
|
34097
|
+
fs61.writeFileSync(file3, encodeText(withEpicLogin(read.text, p), read.encoding));
|
|
34098
|
+
return { summary: "Epic Games Launcher: signed in with your saved sign-in" };
|
|
34099
|
+
},
|
|
34100
|
+
current() {
|
|
34101
|
+
const bytes = readBoundedFile(settingsFile(), MAX_EPIC_INI_BYTES);
|
|
34102
|
+
return bytes ? readEpicLogin(decodeText(bytes).text) : null;
|
|
34103
|
+
}
|
|
34104
|
+
};
|
|
34105
|
+
|
|
34106
|
+
// src/guest/accounts/kinds/expo.ts
|
|
34107
|
+
var expoAdapter = {
|
|
34108
|
+
kind: "expo",
|
|
34109
|
+
apply(_p) {
|
|
34110
|
+
return notAvailableYet2("expo");
|
|
34111
|
+
}
|
|
34112
|
+
};
|
|
34113
|
+
|
|
34114
|
+
// src/guest/accounts/kinds/keystore.ts
|
|
34115
|
+
var keystoreAdapter = {
|
|
34116
|
+
kind: "keystore",
|
|
34117
|
+
apply(_p) {
|
|
34118
|
+
return notAvailableYet2("keystore");
|
|
34119
|
+
}
|
|
34120
|
+
};
|
|
34121
|
+
|
|
34122
|
+
// src/guest/accounts/kinds/play.ts
|
|
34123
|
+
var playAdapter = {
|
|
34124
|
+
kind: "play",
|
|
34125
|
+
apply(_p) {
|
|
34126
|
+
return notAvailableYet2("play");
|
|
34127
|
+
}
|
|
34128
|
+
};
|
|
34129
|
+
|
|
34130
|
+
// src/guest/accounts/kinds/steam.ts
|
|
34131
|
+
function steamAdapterFor(steamcmdDir) {
|
|
34132
|
+
return {
|
|
34133
|
+
kind: "steam",
|
|
34134
|
+
apply(p) {
|
|
34135
|
+
writeSteamCmdLogin(steamcmdDir, p);
|
|
34136
|
+
return { summary: "SteamCMD: signed in as " + p.account + " with your saved sign-in" };
|
|
34137
|
+
},
|
|
34138
|
+
current: () => readSteamCmdLogin(steamcmdDir)
|
|
34139
|
+
};
|
|
34140
|
+
}
|
|
34141
|
+
var steamAdapter = steamAdapterFor(STEAMCMD_DIR);
|
|
34142
|
+
|
|
34143
|
+
// src/guest/accounts/kinds/unity.ts
|
|
34144
|
+
var unityAdapter = {
|
|
34145
|
+
kind: "unity",
|
|
34146
|
+
apply(_p) {
|
|
34147
|
+
return notAvailableYet2("unity");
|
|
34148
|
+
}
|
|
34149
|
+
};
|
|
34150
|
+
|
|
34151
|
+
// src/guest/accounts/adapters.ts
|
|
34152
|
+
var ADAPTERS = {
|
|
34153
|
+
epic: epicAdapter,
|
|
34154
|
+
steam: steamAdapter,
|
|
34155
|
+
unity: unityAdapter,
|
|
34156
|
+
cfx: cfxAdapter,
|
|
34157
|
+
keystore: keystoreAdapter,
|
|
34158
|
+
play: playAdapter,
|
|
34159
|
+
expo: expoAdapter,
|
|
34160
|
+
appstore: appstoreAdapter
|
|
34161
|
+
};
|
|
34162
|
+
|
|
34163
|
+
// src/guest/accounts/apply.ts
|
|
34164
|
+
import path78 from "node:path";
|
|
34165
|
+
var DeliveredSchema = external_exports.object({
|
|
34166
|
+
fingerprints: external_exports.partialRecord(external_exports.enum(SERVICE_KINDS), external_exports.string().max(128)),
|
|
34167
|
+
leased: external_exports.array(external_exports.enum(SERVICE_KINDS))
|
|
34168
|
+
});
|
|
34169
|
+
function deliveredFile(root = accountsRoot()) {
|
|
34170
|
+
return path78.join(root, "delivered.json");
|
|
34171
|
+
}
|
|
34172
|
+
function readDelivered(root = accountsRoot()) {
|
|
34173
|
+
return readValid(DeliveredSchema, deliveredFile(root)) ?? { fingerprints: {}, leased: [] };
|
|
34174
|
+
}
|
|
34175
|
+
|
|
34176
|
+
// src/guest/accounts/watch.ts
|
|
34177
|
+
var DEFAULT_CHECK_MS = 6e4;
|
|
34178
|
+
var AccountWatch = class {
|
|
34179
|
+
constructor(kinds, o) {
|
|
34180
|
+
this.o = o;
|
|
34181
|
+
this.kinds = kinds.filter((k) => SERVICE_SPECS[k].returns && this.adapter(k).current);
|
|
34182
|
+
const delivered = readDelivered(o.root);
|
|
34183
|
+
for (const kind of this.kinds) this.last.set(kind, delivered.fingerprints[kind] ?? null);
|
|
34184
|
+
}
|
|
34185
|
+
o;
|
|
34186
|
+
last = /* @__PURE__ */ new Map();
|
|
34187
|
+
timers = [];
|
|
34188
|
+
kinds;
|
|
34189
|
+
adapter(kind) {
|
|
34190
|
+
return this.o.adapters?.[kind] ?? ADAPTERS[kind];
|
|
34191
|
+
}
|
|
34192
|
+
/** The kinds being watched. */
|
|
34193
|
+
watched() {
|
|
34194
|
+
return this.kinds;
|
|
34195
|
+
}
|
|
34196
|
+
start() {
|
|
34197
|
+
for (const kind of this.kinds) {
|
|
34198
|
+
const timer = setInterval(() => this.check(kind), this.adapter(kind).checkMs ?? DEFAULT_CHECK_MS);
|
|
34199
|
+
timer.unref();
|
|
34200
|
+
this.timers.push(timer);
|
|
34201
|
+
}
|
|
34202
|
+
}
|
|
34203
|
+
/** One look at one kind; true when a handoff was written. */
|
|
34204
|
+
check(kind) {
|
|
34205
|
+
try {
|
|
34206
|
+
const now2 = this.adapter(kind).current?.() ?? null;
|
|
34207
|
+
if (!now2) return false;
|
|
34208
|
+
const print = fingerprint2(now2);
|
|
34209
|
+
if (print === this.last.get(kind)) return false;
|
|
34210
|
+
const file3 = path79.join(this.o.dataDir, ...HANDOFF_PARTS, kind + ".json");
|
|
34211
|
+
fs62.mkdirSync(path79.dirname(file3), { recursive: true });
|
|
34212
|
+
writeJsonAtomic(file3, { kind, launchId: this.o.launchId, payload: now2 });
|
|
34213
|
+
this.last.set(kind, print);
|
|
34214
|
+
return true;
|
|
34215
|
+
} catch (e) {
|
|
34216
|
+
this.o.warn?.(SERVICE_SPECS[kind].label + " sign-in: could not keep it for the next sandbox: " + errMsg(e));
|
|
34217
|
+
return false;
|
|
34218
|
+
}
|
|
34219
|
+
}
|
|
34220
|
+
/** Looks at every kind now; with `final` (the sandbox stops) each adapter also lets go of what it holds. */
|
|
34221
|
+
async flush(final = false) {
|
|
34222
|
+
for (const kind of this.kinds) this.check(kind);
|
|
34223
|
+
if (!final) return;
|
|
34224
|
+
for (const timer of this.timers) clearInterval(timer);
|
|
34225
|
+
for (const kind of this.kinds) {
|
|
34226
|
+
try {
|
|
34227
|
+
await this.adapter(kind).release?.();
|
|
34228
|
+
} catch (e) {
|
|
34229
|
+
this.o.warn?.(SERVICE_SPECS[kind].label + ": could not let go of the sign-in: " + errMsg(e));
|
|
34230
|
+
}
|
|
34231
|
+
}
|
|
34232
|
+
}
|
|
34233
|
+
};
|
|
34234
|
+
|
|
34235
|
+
// src/guest/daemon/accounts.ts
|
|
34236
|
+
var watch = null;
|
|
34237
|
+
function startAccountWatch() {
|
|
34238
|
+
const kinds = session.accountLeases ?? [];
|
|
34239
|
+
if (!kinds.length) return;
|
|
34240
|
+
watch = new AccountWatch(kinds, { dataDir, launchId: session.launchId, warn });
|
|
34241
|
+
watch.start();
|
|
34242
|
+
if (watch.watched().length) log("Service sign-ins kept for the next sandbox: " + watch.watched().join(", "));
|
|
34243
|
+
}
|
|
34244
|
+
async function flushAccounts(final = false) {
|
|
34245
|
+
try {
|
|
34246
|
+
await watch?.flush(final);
|
|
34247
|
+
} catch (e) {
|
|
34248
|
+
warn("service sign-ins: " + String(e));
|
|
34249
|
+
}
|
|
34250
|
+
}
|
|
34251
|
+
|
|
34252
|
+
// src/guest/daemon/idle-shutdown.ts
|
|
32873
34253
|
var GRACE_MS = 15e3;
|
|
32874
34254
|
var IdleShutdown = class {
|
|
32875
34255
|
/** `busy`: a session runs or is starting. */
|
|
@@ -32886,7 +34266,7 @@ var IdleShutdown = class {
|
|
|
32886
34266
|
log("Headless sandbox has no sessions left; shutting down.");
|
|
32887
34267
|
safely("claude-mem save", saveClaudeMem);
|
|
32888
34268
|
safely("agent databases save", saveLocalState);
|
|
32889
|
-
spawnSync6(SYSTEM.shutdown(), ["/s", "/t", "5"], { windowsHide: true });
|
|
34269
|
+
void flushAccounts(true).finally(() => spawnSync6(SYSTEM.shutdown(), ["/s", "/t", "5"], { windowsHide: true }));
|
|
32890
34270
|
}, GRACE_MS);
|
|
32891
34271
|
}
|
|
32892
34272
|
idle() {
|
|
@@ -32898,11 +34278,11 @@ var IdleShutdown = class {
|
|
|
32898
34278
|
var CLOSE_WAIT_MS = 8e3;
|
|
32899
34279
|
var ROOTS_KEPT_MS = 10 * 60 * 1e3;
|
|
32900
34280
|
function terminalTab(id, title, cwd) {
|
|
32901
|
-
const view = [process.execPath,
|
|
32902
|
-
const wt =
|
|
34281
|
+
const view = [process.execPath, path80.join(path80.dirname(process.argv[1]), "view.js"), id];
|
|
34282
|
+
const wt = path80.join(toolsDir, "terminal", "wt.exe");
|
|
32903
34283
|
if (exists(wt))
|
|
32904
|
-
|
|
32905
|
-
else
|
|
34284
|
+
spawn8(wt, ["-w", "0", "nt", "--title", title, "-d", cwd, ...view], { detached: true, stdio: "ignore" }).unref();
|
|
34285
|
+
else spawn8(SYSTEM.cmd(), ["/d", "/c", "start", title, ...view], { detached: true, stdio: "ignore", cwd }).unref();
|
|
32906
34286
|
}
|
|
32907
34287
|
var harnessFor = (req) => {
|
|
32908
34288
|
if (req.harness === session.harnessName && session.harness) return session.harness;
|
|
@@ -32915,8 +34295,8 @@ var harnessFor = (req) => {
|
|
|
32915
34295
|
function memoryEnv(env, sessions2) {
|
|
32916
34296
|
const out = {};
|
|
32917
34297
|
out.PTYHOST_BACKSTOP_MB = String(session.agentBackstop ?? "auto");
|
|
32918
|
-
const cpus = usableCpus(
|
|
32919
|
-
const memoryGb =
|
|
34298
|
+
const cpus = usableCpus(os13.cpus().length, session.cpuLimitPercent ?? null);
|
|
34299
|
+
const memoryGb = os13.totalmem() / 1024 ** 3;
|
|
32920
34300
|
const jobs = cargoJobs(cpus, memoryGb, sessions2);
|
|
32921
34301
|
out.NUMBER_OF_PROCESSORS = String(cpus);
|
|
32922
34302
|
if (!env.CARGO_BUILD_JOBS) out.CARGO_BUILD_JOBS = String(jobs);
|
|
@@ -32955,10 +34335,10 @@ var agentProgram = async (req, env, say) => {
|
|
|
32955
34335
|
};
|
|
32956
34336
|
function shellPaths() {
|
|
32957
34337
|
const candidates = [
|
|
32958
|
-
|
|
32959
|
-
|
|
34338
|
+
path80.join(pwshDir(), "pwsh.exe"),
|
|
34339
|
+
path80.join(process.env.ProgramFiles ?? "C:\\Program Files", "PowerShell", "7", "pwsh.exe")
|
|
32960
34340
|
];
|
|
32961
|
-
return { pwsh: candidates.find((f) =>
|
|
34341
|
+
return { pwsh: candidates.find((f) => fs63.existsSync(f)) ?? null, powershell: SYSTEM.powershell(), cmd: SYSTEM.cmd() };
|
|
32962
34342
|
}
|
|
32963
34343
|
var shellProgram = (shell) => {
|
|
32964
34344
|
const line = commandLine(shell.file, shell.args);
|
|
@@ -32966,7 +34346,7 @@ var shellProgram = (shell) => {
|
|
|
32966
34346
|
};
|
|
32967
34347
|
var launchPtyHost = async (req, program, remote, env, sessions2, onSpawn) => {
|
|
32968
34348
|
const port = await freePort();
|
|
32969
|
-
const token =
|
|
34349
|
+
const token = crypto5.randomBytes(24).toString("base64url");
|
|
32970
34350
|
const sessionEnv = {
|
|
32971
34351
|
...withRegistryPath(env),
|
|
32972
34352
|
...program.environment,
|
|
@@ -32992,7 +34372,7 @@ var launchPtyHost = async (req, program, remote, env, sessions2, onSpawn) => {
|
|
|
32992
34372
|
} catch (e) {
|
|
32993
34373
|
const tail = ptyHostLogTail(req.id);
|
|
32994
34374
|
throw new Error(
|
|
32995
|
-
errMsg(e) + (tail ? ". From its log:\n" + tail : "") + "\nLog: " +
|
|
34375
|
+
errMsg(e) + (tail ? ". From its log:\n" + tail : "") + "\nLog: " + path80.join(dataDir, "logs", "ptyhost-" + req.id + ".log")
|
|
32996
34376
|
);
|
|
32997
34377
|
}
|
|
32998
34378
|
return { child, port, token };
|
|
@@ -33106,7 +34486,7 @@ var SessionManager = class {
|
|
|
33106
34486
|
};
|
|
33107
34487
|
this.starting++;
|
|
33108
34488
|
if (req.id !== session.launchId && process.env.AGENT_NO_TABS !== "1")
|
|
33109
|
-
safely("terminal tab", () => terminalTab(req.id, name + " " +
|
|
34489
|
+
safely("terminal tab", () => terminalTab(req.id, name + " " + path80.basename(req.cwd), req.cwd));
|
|
33110
34490
|
try {
|
|
33111
34491
|
if (problem) throw new Error(problem);
|
|
33112
34492
|
const place = await placeFor(req, say);
|
|
@@ -33268,6 +34648,7 @@ var SessionManager = class {
|
|
|
33268
34648
|
else safely("post-agent hooks", () => runHooks("post-agent", process.env));
|
|
33269
34649
|
safely("claude-mem save", saveClaudeMem);
|
|
33270
34650
|
safely("agent databases save", saveLocalState);
|
|
34651
|
+
void flushAccounts();
|
|
33271
34652
|
this.idle.check();
|
|
33272
34653
|
}
|
|
33273
34654
|
};
|
|
@@ -33600,10 +34981,10 @@ var GovernorCore = class {
|
|
|
33600
34981
|
};
|
|
33601
34982
|
|
|
33602
34983
|
// src/guest/governor/governor.ts
|
|
33603
|
-
import
|
|
33604
|
-
import
|
|
33605
|
-
import
|
|
33606
|
-
import { spawn as
|
|
34984
|
+
import fs64 from "node:fs";
|
|
34985
|
+
import os14 from "node:os";
|
|
34986
|
+
import path81 from "node:path";
|
|
34987
|
+
import { spawn as spawn9 } from "node:child_process";
|
|
33607
34988
|
import { createInterface } from "node:readline";
|
|
33608
34989
|
var SampleSchema = external_exports.object({
|
|
33609
34990
|
ramTotalMb: external_exports.number(),
|
|
@@ -33627,7 +35008,7 @@ var MemGovProcess = class {
|
|
|
33627
35008
|
child = null;
|
|
33628
35009
|
start() {
|
|
33629
35010
|
try {
|
|
33630
|
-
const child =
|
|
35011
|
+
const child = spawn9(ensureCompiled("memgov"), ["serve", "--interval", "2"], {
|
|
33631
35012
|
stdio: ["pipe", "pipe", "ignore"],
|
|
33632
35013
|
windowsHide: true
|
|
33633
35014
|
});
|
|
@@ -33672,12 +35053,12 @@ var MemGovProcess = class {
|
|
|
33672
35053
|
};
|
|
33673
35054
|
function appendToMemoryLog(line) {
|
|
33674
35055
|
try {
|
|
33675
|
-
const logs =
|
|
33676
|
-
const newest =
|
|
35056
|
+
const logs = path81.join(dataDir, "logs");
|
|
35057
|
+
const newest = fs64.readdirSync(logs).filter((f) => /^memory-\d{8}-\d{6}\.log$/.test(f)).sort().pop();
|
|
33677
35058
|
if (!newest) return;
|
|
33678
35059
|
const t = /* @__PURE__ */ new Date();
|
|
33679
35060
|
const stamp = [t.getHours(), t.getMinutes(), t.getSeconds()].map((n) => String(n).padStart(2, "0")).join(":");
|
|
33680
|
-
|
|
35061
|
+
fs64.appendFileSync(path81.join(logs, newest), stamp + " | " + line + "\r\n");
|
|
33681
35062
|
} catch {
|
|
33682
35063
|
}
|
|
33683
35064
|
}
|
|
@@ -33695,7 +35076,7 @@ var Governor = class {
|
|
|
33695
35076
|
this.core = new GovernorCore({
|
|
33696
35077
|
port: proc,
|
|
33697
35078
|
profile,
|
|
33698
|
-
maxCompilers: maxCompilers(
|
|
35079
|
+
maxCompilers: maxCompilers(os14.cpus().length, profile),
|
|
33699
35080
|
now: () => Date.now(),
|
|
33700
35081
|
logLine: appendToMemoryLog,
|
|
33701
35082
|
warn,
|
|
@@ -33717,16 +35098,16 @@ var Governor = class {
|
|
|
33717
35098
|
var governor = new Governor();
|
|
33718
35099
|
|
|
33719
35100
|
// src/guest/daemon/live.ts
|
|
33720
|
-
import
|
|
33721
|
-
import
|
|
35101
|
+
import fs66 from "node:fs";
|
|
35102
|
+
import path83 from "node:path";
|
|
33722
35103
|
import { spawnSync as spawnSync7 } from "node:child_process";
|
|
33723
35104
|
|
|
33724
35105
|
// src/guest/daemon/live-folders.ts
|
|
33725
|
-
import
|
|
33726
|
-
import
|
|
35106
|
+
import fs65 from "node:fs";
|
|
35107
|
+
import path82 from "node:path";
|
|
33727
35108
|
|
|
33728
35109
|
// src/shared/channel/live.ts
|
|
33729
|
-
import
|
|
35110
|
+
import crypto6 from "node:crypto";
|
|
33730
35111
|
var LIVE_SHARE_NAME = /^agentsbx-[0-9a-f]{8,32}$/;
|
|
33731
35112
|
var LIVE_FOLDER_NAME = /^[a-z0-9][a-z0-9_-]{0,63}$/;
|
|
33732
35113
|
var LIVE_KEY = /^[0-9a-f]{64}$/;
|
|
@@ -33756,7 +35137,7 @@ var LiveReplySchema = external_exports.strictObject({
|
|
|
33756
35137
|
finishedAt: external_exports.string().max(64)
|
|
33757
35138
|
});
|
|
33758
35139
|
function mac3(key2, payload) {
|
|
33759
|
-
return
|
|
35140
|
+
return crypto6.createHmac("sha256", Buffer.from(key2, "hex")).update(payload, "utf8").digest("hex");
|
|
33760
35141
|
}
|
|
33761
35142
|
function openLive(key2, envelope, o) {
|
|
33762
35143
|
if (!key2 || !LIVE_KEY.test(key2))
|
|
@@ -33765,7 +35146,7 @@ function openLive(key2, envelope, o) {
|
|
|
33765
35146
|
if (!env.success) return { refused: "not a live-folder request" };
|
|
33766
35147
|
const want = Buffer.from(mac3(key2, env.data.payload), "hex");
|
|
33767
35148
|
const got = Buffer.from(env.data.mac, "hex");
|
|
33768
|
-
if (want.length !== got.length || !
|
|
35149
|
+
if (want.length !== got.length || !crypto6.timingSafeEqual(want, got))
|
|
33769
35150
|
return { refused: "the signature does not match" };
|
|
33770
35151
|
let json2;
|
|
33771
35152
|
try {
|
|
@@ -33816,7 +35197,7 @@ var LiveFolderHandler = class {
|
|
|
33816
35197
|
}
|
|
33817
35198
|
read() {
|
|
33818
35199
|
try {
|
|
33819
|
-
const text =
|
|
35200
|
+
const text = fs65.readFileSync(this.o.stateFile, "utf8");
|
|
33820
35201
|
const parsed = StateSchema.safeParse(JSON.parse(text));
|
|
33821
35202
|
if (parsed.success && parsed.data.launchId === this.o.launchId) return parsed.data;
|
|
33822
35203
|
} catch {
|
|
@@ -33824,7 +35205,7 @@ var LiveFolderHandler = class {
|
|
|
33824
35205
|
return { key: null, launchId: this.o.launchId, seen: [], mappings: [] };
|
|
33825
35206
|
}
|
|
33826
35207
|
save(state) {
|
|
33827
|
-
|
|
35208
|
+
fs65.mkdirSync(path82.dirname(this.o.stateFile), { recursive: true });
|
|
33828
35209
|
writeJsonAtomic(this.o.stateFile, state);
|
|
33829
35210
|
}
|
|
33830
35211
|
/** The key the boot handed over (from the one-shot secrets file). */
|
|
@@ -33835,30 +35216,30 @@ var LiveFolderHandler = class {
|
|
|
33835
35216
|
/** C:\Workspace\<name> from a checked name only. */
|
|
33836
35217
|
folderPath(name) {
|
|
33837
35218
|
if (!LIVE_FOLDER_NAME.test(name)) throw new Error("not a plain folder name");
|
|
33838
|
-
return
|
|
35219
|
+
return path82.win32.join(this.o.workspaces ?? WORKSPACES_GUEST, name);
|
|
33839
35220
|
}
|
|
33840
35221
|
/** One pass over run\live: every file is claimed (deleted) at once; valid ones are handled one after another. */
|
|
33841
35222
|
tick() {
|
|
33842
35223
|
const dir = this.o.run.liveDir;
|
|
33843
35224
|
let names;
|
|
33844
35225
|
try {
|
|
33845
|
-
names =
|
|
35226
|
+
names = fs65.readdirSync(dir);
|
|
33846
35227
|
} catch {
|
|
33847
35228
|
return;
|
|
33848
35229
|
}
|
|
33849
35230
|
for (const name of names.slice(0, 64)) {
|
|
33850
35231
|
if (name.endsWith(".tmp")) continue;
|
|
33851
|
-
const file3 =
|
|
35232
|
+
const file3 = path82.join(dir, name);
|
|
33852
35233
|
let envelope = null;
|
|
33853
35234
|
try {
|
|
33854
|
-
const stat =
|
|
35235
|
+
const stat = fs65.lstatSync(file3);
|
|
33855
35236
|
if (stat.isFile() && stat.size <= MAX_REQUEST_BYTES && /^[A-Za-z0-9_-]{1,64}\.json$/.test(name))
|
|
33856
|
-
envelope = JSON.parse(
|
|
35237
|
+
envelope = JSON.parse(fs65.readFileSync(file3, "utf8"));
|
|
33857
35238
|
} catch {
|
|
33858
35239
|
envelope = null;
|
|
33859
35240
|
} finally {
|
|
33860
35241
|
try {
|
|
33861
|
-
|
|
35242
|
+
fs65.rmSync(file3, { recursive: true, force: true });
|
|
33862
35243
|
} catch {
|
|
33863
35244
|
}
|
|
33864
35245
|
}
|
|
@@ -33895,18 +35276,18 @@ var LiveFolderHandler = class {
|
|
|
33895
35276
|
}
|
|
33896
35277
|
reply(id, r) {
|
|
33897
35278
|
try {
|
|
33898
|
-
|
|
35279
|
+
fs65.mkdirSync(this.o.run.liveRepliesDir, { recursive: true });
|
|
33899
35280
|
writeJsonAtomic(this.o.run.liveReplyFile(id), { id, ...r, finishedAt: new Date(this.now()).toISOString() });
|
|
33900
35281
|
} catch (e) {
|
|
33901
35282
|
this.log("live folder reply not written: " + errMsg(e));
|
|
33902
35283
|
}
|
|
33903
35284
|
}
|
|
33904
35285
|
/** map with retries while the share is not there yet. */
|
|
33905
|
-
async mapWithRetry(folder,
|
|
35286
|
+
async mapWithRetry(folder, share2, readOnly) {
|
|
33906
35287
|
const tries = this.o.tries ?? 20;
|
|
33907
35288
|
let code = EXIT_NO_SHARE;
|
|
33908
35289
|
for (let i = 0; i < tries; i++) {
|
|
33909
|
-
code = this.o.bind.map(folder,
|
|
35290
|
+
code = this.o.bind.map(folder, share2, readOnly);
|
|
33910
35291
|
if (code !== EXIT_NO_SHARE) return code;
|
|
33911
35292
|
await (this.o.sleep ?? wait)(500);
|
|
33912
35293
|
}
|
|
@@ -33916,14 +35297,14 @@ var LiveFolderHandler = class {
|
|
|
33916
35297
|
assertFree(folder) {
|
|
33917
35298
|
let exists2 = true;
|
|
33918
35299
|
try {
|
|
33919
|
-
|
|
35300
|
+
fs65.lstatSync(folder);
|
|
33920
35301
|
} catch {
|
|
33921
35302
|
exists2 = false;
|
|
33922
35303
|
}
|
|
33923
35304
|
if (exists2) throw new Error(folder + " exists already");
|
|
33924
|
-
const parent =
|
|
33925
|
-
|
|
33926
|
-
if (!
|
|
35305
|
+
const parent = path82.dirname(folder);
|
|
35306
|
+
fs65.mkdirSync(parent, { recursive: true });
|
|
35307
|
+
if (!fs65.lstatSync(parent).isDirectory()) throw new Error(parent + " is not a plain folder");
|
|
33927
35308
|
}
|
|
33928
35309
|
async act(p) {
|
|
33929
35310
|
const folder = this.folderPath(p.folder);
|
|
@@ -33938,21 +35319,21 @@ var LiveFolderHandler = class {
|
|
|
33938
35319
|
this.save({ ...after, mappings: after.mappings.filter((m) => m.folder !== p.folder) });
|
|
33939
35320
|
return { ok: true, message: "hidden: " + folder };
|
|
33940
35321
|
}
|
|
33941
|
-
const
|
|
35322
|
+
const share2 = p.share ?? "";
|
|
33942
35323
|
this.assertFree(folder);
|
|
33943
35324
|
if (p.kind === "canary") {
|
|
33944
|
-
const code2 = await this.mapWithRetry(folder,
|
|
35325
|
+
const code2 = await this.mapWithRetry(folder, share2, true);
|
|
33945
35326
|
if (code2 !== EXIT_OK) return { ok: false, message: "the test share could not be shown (" + code2 + ")" };
|
|
33946
35327
|
try {
|
|
33947
|
-
const file3 =
|
|
33948
|
-
const stat =
|
|
33949
|
-
const token = stat.size <= 64 ?
|
|
35328
|
+
const file3 = path82.join(folder, "token.txt");
|
|
35329
|
+
const stat = fs65.statSync(file3);
|
|
35330
|
+
const token = stat.size <= 64 ? fs65.readFileSync(file3, "utf8").trim() : "";
|
|
33950
35331
|
return LIVE_TOKEN.test(token) ? { ok: true, message: "read the test share", token } : { ok: false, message: "the test share holds no token" };
|
|
33951
35332
|
} finally {
|
|
33952
35333
|
this.o.bind.unmap(folder);
|
|
33953
35334
|
}
|
|
33954
35335
|
}
|
|
33955
|
-
const code = await this.mapWithRetry(folder,
|
|
35336
|
+
const code = await this.mapWithRetry(folder, share2, p.readOnly);
|
|
33956
35337
|
if (code !== EXIT_OK)
|
|
33957
35338
|
return {
|
|
33958
35339
|
ok: false,
|
|
@@ -33963,7 +35344,7 @@ var LiveFolderHandler = class {
|
|
|
33963
35344
|
...state,
|
|
33964
35345
|
mappings: [
|
|
33965
35346
|
...state.mappings.filter((m) => m.folder !== p.folder),
|
|
33966
|
-
{ folder: p.folder, share, readOnly: p.readOnly }
|
|
35347
|
+
{ folder: p.folder, share: share2, readOnly: p.readOnly }
|
|
33967
35348
|
]
|
|
33968
35349
|
});
|
|
33969
35350
|
return { ok: true, message: "shown at " + folder };
|
|
@@ -33974,7 +35355,7 @@ var LiveFolderHandler = class {
|
|
|
33974
35355
|
for (const m of this.read().mappings) {
|
|
33975
35356
|
const folder = this.folderPath(m.folder);
|
|
33976
35357
|
if (this.o.bind.mapped(folder) === EXIT_OK) continue;
|
|
33977
|
-
|
|
35358
|
+
fs65.mkdirSync(path82.dirname(folder), { recursive: true });
|
|
33978
35359
|
if (this.o.bind.map(folder, m.share, m.readOnly) === EXIT_OK) done++;
|
|
33979
35360
|
else this.log("live folder " + folder + " could not be shown again");
|
|
33980
35361
|
}
|
|
@@ -33985,7 +35366,7 @@ var LiveFolderHandler = class {
|
|
|
33985
35366
|
// src/guest/daemon/live.ts
|
|
33986
35367
|
var BIND_TIMEOUT_MS = 3e4;
|
|
33987
35368
|
var testing = Boolean(process.env.AGENT_DAEMON_STATE_DIR || process.env.AGENT_LOCAL_DIR);
|
|
33988
|
-
var stateDir2 = process.env.AGENT_DAEMON_STATE_DIR ?? (process.env.AGENT_LOCAL_DIR ?
|
|
35369
|
+
var stateDir2 = process.env.AGENT_DAEMON_STATE_DIR ?? (process.env.AGENT_LOCAL_DIR ? path83.join(localDir, "daemon-state") : path83.join(process.env.ProgramData ?? "C:\\ProgramData", "AgentSandboxDaemon"));
|
|
33989
35370
|
function bindMount(args) {
|
|
33990
35371
|
const r = spawnSync7(ensureCompiled("bindmount"), args, {
|
|
33991
35372
|
windowsHide: true,
|
|
@@ -33995,12 +35376,12 @@ function bindMount(args) {
|
|
|
33995
35376
|
return r.status ?? 1;
|
|
33996
35377
|
}
|
|
33997
35378
|
var realBind = {
|
|
33998
|
-
map: (folder,
|
|
35379
|
+
map: (folder, share2, readOnly) => bindMount(["map", folder, share2, ...readOnly ? [] : ["rw"]]),
|
|
33999
35380
|
unmap: (folder) => bindMount(["unmap", folder]),
|
|
34000
35381
|
mapped: (folder) => bindMount(["mapped", folder])
|
|
34001
35382
|
};
|
|
34002
35383
|
function protectStateDir() {
|
|
34003
|
-
|
|
35384
|
+
fs66.mkdirSync(stateDir2, { recursive: true });
|
|
34004
35385
|
if (!isWin || testMode || testing) return;
|
|
34005
35386
|
spawnSync7(
|
|
34006
35387
|
SYSTEM.icacls(),
|
|
@@ -34013,7 +35394,7 @@ function protectStateDir() {
|
|
|
34013
35394
|
}
|
|
34014
35395
|
var liveFolders = new LiveFolderHandler({
|
|
34015
35396
|
run,
|
|
34016
|
-
stateFile:
|
|
35397
|
+
stateFile: path83.join(stateDir2, "live-folders.json"),
|
|
34017
35398
|
launchId: session.launchId,
|
|
34018
35399
|
bind: realBind,
|
|
34019
35400
|
log: warn
|
|
@@ -34043,9 +35424,9 @@ var Daemon = class {
|
|
|
34043
35424
|
tick() {
|
|
34044
35425
|
const { valid, invalid } = run.scanRequests();
|
|
34045
35426
|
for (const file3 of invalid)
|
|
34046
|
-
safely("removing an invalid request", () =>
|
|
35427
|
+
safely("removing an invalid request", () => fs67.rmSync(file3, { recursive: true, force: true }));
|
|
34047
35428
|
for (const req of valid) {
|
|
34048
|
-
safely("claiming a request", () =>
|
|
35429
|
+
safely("claiming a request", () => fs67.rmSync(run.requestFile(req.id), { force: true }));
|
|
34049
35430
|
if (run.readSession(req.id)) continue;
|
|
34050
35431
|
void Promise.resolve(this.handle(withRequestSecrets(req))).catch(
|
|
34051
35432
|
(e) => respond(req.id, { ok: false, message: errMsg(e) })
|
|
@@ -34056,6 +35437,7 @@ var Daemon = class {
|
|
|
34056
35437
|
this.lastMemSave = Date.now();
|
|
34057
35438
|
safely("claude-mem save", saveClaudeMem);
|
|
34058
35439
|
safely("agent databases save", saveLocalState);
|
|
35440
|
+
void flushAccounts();
|
|
34059
35441
|
}
|
|
34060
35442
|
}
|
|
34061
35443
|
handle(req) {
|
|
@@ -34089,4 +35471,5 @@ safely("audit", () => startProcessCollector(() => sessions.roots()));
|
|
|
34089
35471
|
safely("leftover processes", () => sessions.sweepLeftovers());
|
|
34090
35472
|
safely("memory governor", () => governor.start());
|
|
34091
35473
|
log("Memory governor: " + governor.describe());
|
|
35474
|
+
safely("service sign-ins", startAccountWatch);
|
|
34092
35475
|
new Daemon().start();
|