windows-development-sandbox 1.17.0 → 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 +92 -92
- 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/agents/agent-files.d.ts +6 -0
- package/dist/guest/agents/agent-files.js +14 -0
- package/dist/guest/agents/local-state.d.ts +2 -0
- package/dist/guest/agents/local-state.js +13 -1
- 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 +36 -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 -155
- 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 -595
- package/dist/runtime/db.js +334 -11
- package/dist/runtime/main.js +2530 -709
- 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 +13 -1
- 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,16 +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
|
-
|
|
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)",
|
|
31032
31604
|
"Microsoft Visual Studio",
|
|
31033
31605
|
"Installer",
|
|
31034
31606
|
"vswhere.exe"
|
|
@@ -31047,142 +31619,153 @@ function installedVs() {
|
|
|
31047
31619
|
const at = ask("installationPath");
|
|
31048
31620
|
return at ? { path: at, version: ask("installationVersion") || "installed" } : null;
|
|
31049
31621
|
}
|
|
31050
|
-
|
|
31051
|
-
|
|
31052
|
-
log("Downloading " + what + " ...");
|
|
31053
|
-
mkdirp(path55.dirname(file3));
|
|
31054
|
-
await downloadFile(url2, file3);
|
|
31055
|
-
}
|
|
31056
|
-
if (signerOf(file3) !== MICROSOFT_SIGNER) {
|
|
31057
|
-
fs43.rmSync(file3, { force: true });
|
|
31058
|
-
throw new Error(path55.basename(file3) + " is not signed by Microsoft; deleted it (it is downloaded again next boot)");
|
|
31059
|
-
}
|
|
31060
|
-
return file3;
|
|
31622
|
+
function layoutDir(product) {
|
|
31623
|
+
return path56.join(VS_DIR, product === "community" ? "layout" : "layout-buildtools");
|
|
31061
31624
|
}
|
|
31062
|
-
function
|
|
31063
|
-
|
|
31064
|
-
|
|
31065
|
-
|
|
31066
|
-
} catch {
|
|
31067
|
-
return 0;
|
|
31068
|
-
}
|
|
31069
|
-
}
|
|
31070
|
-
async function layoutInstaller(bootstrapper, ids) {
|
|
31071
|
-
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);
|
|
31072
31629
|
const has = () => {
|
|
31073
|
-
if (!exists(
|
|
31630
|
+
if (!exists(marker) || !exists(installer)) return false;
|
|
31074
31631
|
try {
|
|
31075
|
-
const done = LayoutSchema.parse(JSON.parse(
|
|
31076
|
-
return
|
|
31632
|
+
const done = LayoutSchema.parse(JSON.parse(fs46.readFileSync(marker, "utf8")));
|
|
31633
|
+
return req.components.every((id) => done.components.includes(id));
|
|
31077
31634
|
} catch {
|
|
31078
31635
|
return false;
|
|
31079
31636
|
}
|
|
31080
31637
|
};
|
|
31081
31638
|
if (has()) return installer;
|
|
31082
31639
|
if (freeBytes(mkdirp(VS_DIR)) < LAYOUT_ROOM_BYTES) {
|
|
31083
|
-
warn(
|
|
31640
|
+
warn(
|
|
31641
|
+
"Visual Studio: not keeping the install files (less than 15 GB free in " + VS_DIR + "); downloading this boot"
|
|
31642
|
+
);
|
|
31084
31643
|
return null;
|
|
31085
31644
|
}
|
|
31086
31645
|
log("Saving the Visual Studio install files for later boots (~10 GB, once) ...");
|
|
31087
|
-
|
|
31646
|
+
fs46.rmSync(marker, { force: true });
|
|
31088
31647
|
const code = await spawnAsync(bootstrapper, [
|
|
31089
31648
|
"--layout",
|
|
31090
|
-
|
|
31649
|
+
layout,
|
|
31091
31650
|
"--lang",
|
|
31092
31651
|
"en-US",
|
|
31093
31652
|
"--quiet",
|
|
31094
31653
|
"--wait",
|
|
31095
|
-
...
|
|
31654
|
+
...req.components.flatMap((id) => ["--add", id])
|
|
31096
31655
|
]);
|
|
31097
31656
|
if (!OK_EXIT_CODES2.includes(code) || !exists(installer)) {
|
|
31098
|
-
warn("
|
|
31657
|
+
warn("Visual Studio: saving the install files failed (exit " + code + "); downloading this boot");
|
|
31099
31658
|
return null;
|
|
31100
31659
|
}
|
|
31101
|
-
writeJsonAtomic(
|
|
31660
|
+
writeJsonAtomic(marker, { components: [...req.components] });
|
|
31102
31661
|
return installer;
|
|
31103
31662
|
}
|
|
31104
|
-
async function
|
|
31105
|
-
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
|
+
);
|
|
31106
31671
|
let installer = null;
|
|
31107
|
-
if (
|
|
31672
|
+
if (keepInstallFiles) {
|
|
31108
31673
|
try {
|
|
31109
|
-
installer = await layoutInstaller(
|
|
31674
|
+
installer = await layoutInstaller(req, bootstrapper);
|
|
31110
31675
|
} catch (e) {
|
|
31111
|
-
warn("
|
|
31676
|
+
warn("Visual Studio: the offline copy failed (" + errMsg(e) + "); downloading this boot");
|
|
31112
31677
|
}
|
|
31113
31678
|
}
|
|
31114
|
-
log(
|
|
31115
|
-
"Installing Visual Studio Community 2022 with the C++ game workload" + (installer ? " from the saved install files" : " (downloads ~5-8 GB)") + " ..."
|
|
31116
|
-
);
|
|
31679
|
+
log("Installing " + boot.name + (installer ? " from the saved install files" : " (downloads ~5-8 GB)") + " ...");
|
|
31117
31680
|
const code = await spawnAsync(installer ?? bootstrapper, [
|
|
31118
31681
|
"--quiet",
|
|
31119
31682
|
"--wait",
|
|
31120
31683
|
"--norestart",
|
|
31121
31684
|
"--nocache",
|
|
31122
31685
|
...installer ? ["--noWeb"] : [],
|
|
31123
|
-
...
|
|
31686
|
+
...req.components.flatMap((id) => ["--add", id])
|
|
31124
31687
|
]);
|
|
31125
31688
|
if (!OK_EXIT_CODES2.includes(code) || !installedVs())
|
|
31126
31689
|
throw new Error(
|
|
31127
31690
|
"the Visual Studio installer failed (exit " + code + "); its logs are the dd_*.log files in " + os7.tmpdir()
|
|
31128
31691
|
);
|
|
31129
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";
|
|
31130
31715
|
async function installDirectX() {
|
|
31131
|
-
const system322 =
|
|
31132
|
-
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;
|
|
31133
31718
|
const redist = await signedInstaller(
|
|
31134
31719
|
DIRECTX_URL,
|
|
31135
|
-
|
|
31136
|
-
"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
|
|
31137
31723
|
);
|
|
31138
|
-
const unpacked =
|
|
31139
|
-
safeRemove(unpacked,
|
|
31724
|
+
const unpacked = path57.join(os8.tmpdir(), "directx-redist");
|
|
31725
|
+
safeRemove(unpacked, os8.tmpdir());
|
|
31140
31726
|
mkdirp(unpacked);
|
|
31141
|
-
if (await spawnAsync(redist, ["/Q", "/T:" + unpacked]) !== 0 || !exists(
|
|
31727
|
+
if (await spawnAsync(redist, ["/Q", "/T:" + unpacked]) !== 0 || !exists(path57.join(unpacked, "DXSETUP.exe")))
|
|
31142
31728
|
throw new Error("could not unpack the DirectX End-User Runtime");
|
|
31143
|
-
const code = await spawnAsync(
|
|
31144
|
-
safeRemove(unpacked,
|
|
31729
|
+
const code = await spawnAsync(path57.join(unpacked, "DXSETUP.exe"), ["/silent"]);
|
|
31730
|
+
safeRemove(unpacked, os8.tmpdir());
|
|
31145
31731
|
if (code !== 0) throw new Error("the DirectX End-User Runtime installer failed (exit " + code + ")");
|
|
31146
31732
|
}
|
|
31147
|
-
async function setupUnreal(env, config2) {
|
|
31733
|
+
async function setupUnreal(env, config2, ctx) {
|
|
31148
31734
|
if (!config2.acceptLicense)
|
|
31149
31735
|
throw new Error(
|
|
31150
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/)"
|
|
31151
31737
|
);
|
|
31152
|
-
const bad = config2.components.find((id) => !ID.test(id));
|
|
31153
|
-
if (bad) throw new Error('toolchains.unreal.components: "' + bad + '" is not a Visual Studio component ID');
|
|
31154
|
-
const ids = [.../* @__PURE__ */ new Set([...UNREAL_COMPONENTS, ...config2.components])];
|
|
31155
31738
|
if (dryRun) {
|
|
31156
|
-
log("(dry run) would install
|
|
31739
|
+
log("(dry run) would install the DirectX End-User Runtime and set up the Unreal engines");
|
|
31157
31740
|
return;
|
|
31158
31741
|
}
|
|
31159
|
-
if (!installedVs()) await installVisualStudio(config2, ids);
|
|
31160
31742
|
await installDirectX();
|
|
31743
|
+
await setupUnrealEngines(env, config2, ctx);
|
|
31161
31744
|
const vs = installedVs();
|
|
31162
31745
|
env.summary.push(
|
|
31163
|
-
"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)"
|
|
31164
31747
|
);
|
|
31165
31748
|
}
|
|
31166
31749
|
|
|
31167
31750
|
// src/guest/toolchains/native/rust.ts
|
|
31168
|
-
import
|
|
31751
|
+
import path59 from "node:path";
|
|
31169
31752
|
|
|
31170
31753
|
// src/guest/toolchains/native/binstall.ts
|
|
31171
|
-
import
|
|
31172
|
-
import
|
|
31754
|
+
import fs47 from "node:fs";
|
|
31755
|
+
import path58 from "node:path";
|
|
31173
31756
|
var ensureBinstall = async (cargoBin) => {
|
|
31174
|
-
const target =
|
|
31757
|
+
const target = path58.join(cargoBin, "cargo-binstall.exe");
|
|
31175
31758
|
if (exists(target)) return true;
|
|
31176
31759
|
try {
|
|
31177
31760
|
const dir = tool("cargo-binstall");
|
|
31178
|
-
if (!exists(
|
|
31761
|
+
if (!exists(path58.join(dir, "cargo-binstall.exe"))) {
|
|
31179
31762
|
await installFromGithub("cargo-bins/cargo-binstall", binstallAsset(arch), {
|
|
31180
31763
|
dest: dir,
|
|
31181
31764
|
what: "cargo-binstall for prebuilt Rust tools (~10 MB once)",
|
|
31182
31765
|
locate: "cargo-binstall.exe"
|
|
31183
31766
|
});
|
|
31184
31767
|
}
|
|
31185
|
-
|
|
31768
|
+
fs47.copyFileSync(path58.join(dir, "cargo-binstall.exe"), target);
|
|
31186
31769
|
return true;
|
|
31187
31770
|
} catch (e) {
|
|
31188
31771
|
warn("cargo-binstall unavailable, compiling crates with cargo install instead: " + errMsg(e));
|
|
@@ -31190,14 +31773,14 @@ var ensureBinstall = async (cargoBin) => {
|
|
|
31190
31773
|
}
|
|
31191
31774
|
};
|
|
31192
31775
|
function crateInstaller(cargoHome, cargoEnv) {
|
|
31193
|
-
const cargo =
|
|
31776
|
+
const cargo = path58.join(cargoHome, "bin", "cargo.exe");
|
|
31194
31777
|
let binstall = null;
|
|
31195
31778
|
const binstallEnv = {
|
|
31196
31779
|
...cargoEnv,
|
|
31197
31780
|
env: { ...cargoEnv.env ?? process.env, BINSTALL_DISABLE_TELEMETRY: "true" }
|
|
31198
31781
|
};
|
|
31199
31782
|
return async (crate) => {
|
|
31200
|
-
binstall ??= ensureBinstall(
|
|
31783
|
+
binstall ??= ensureBinstall(path58.join(cargoHome, "bin"));
|
|
31201
31784
|
if (await binstall) {
|
|
31202
31785
|
try {
|
|
31203
31786
|
await execAsync(
|
|
@@ -31219,7 +31802,7 @@ async function setupRust(env, config2, refresh) {
|
|
|
31219
31802
|
const RUSTUP_HOME = tool("rust", "rustup");
|
|
31220
31803
|
const CARGO_HOME = tool("rust", "cargo");
|
|
31221
31804
|
const rustEnv = { env: { ...process.env, RUSTUP_HOME, CARGO_HOME } };
|
|
31222
|
-
const rustup =
|
|
31805
|
+
const rustup = path59.join(CARGO_HOME, "bin", "rustup.exe");
|
|
31223
31806
|
if (dryRun) {
|
|
31224
31807
|
log("(dry run) would provision Rust " + config2.toolchain + " (" + config2.host + ")");
|
|
31225
31808
|
return;
|
|
@@ -31255,9 +31838,9 @@ async function setupRust(env, config2, refresh) {
|
|
|
31255
31838
|
if (refresh) await execAsync(rustup, ["update"], rustEnv);
|
|
31256
31839
|
}
|
|
31257
31840
|
Object.assign(env.vars, { RUSTUP_HOME, CARGO_HOME });
|
|
31258
|
-
env.prepend.push(
|
|
31841
|
+
env.prepend.push(path59.join(CARGO_HOME, "bin"));
|
|
31259
31842
|
env.summary.push(
|
|
31260
|
-
"rust: " + versionOf(
|
|
31843
|
+
"rust: " + versionOf(path59.join(CARGO_HOME, "bin", "rustc.exe"), ["--version"], rustEnv) + " [" + config2.host + "]"
|
|
31261
31844
|
);
|
|
31262
31845
|
const toolchainKey = "rustup@" + config2.toolchain;
|
|
31263
31846
|
await installOnce(
|
|
@@ -31278,36 +31861,36 @@ async function setupRust(env, config2, refresh) {
|
|
|
31278
31861
|
env: {
|
|
31279
31862
|
...rustEnv.env,
|
|
31280
31863
|
...msvc.vars,
|
|
31281
|
-
PATH: [
|
|
31864
|
+
PATH: [path59.join(CARGO_HOME, "bin"), ...msvc.path, process.env.PATH ?? ""].join(path59.delimiter)
|
|
31282
31865
|
}
|
|
31283
31866
|
} : {
|
|
31284
31867
|
env: {
|
|
31285
31868
|
...rustEnv.env,
|
|
31286
|
-
CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER:
|
|
31287
|
-
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)
|
|
31288
31871
|
}
|
|
31289
31872
|
};
|
|
31290
31873
|
await installOnce(env, "cargo", config2.crates, crateInstaller(CARGO_HOME, cargoEnv));
|
|
31291
31874
|
}
|
|
31292
31875
|
|
|
31293
31876
|
// src/guest/toolchains/languages/node.ts
|
|
31294
|
-
import
|
|
31295
|
-
import
|
|
31877
|
+
import fs48 from "node:fs";
|
|
31878
|
+
import path60 from "node:path";
|
|
31296
31879
|
import { spawn as spawn4 } from "node:child_process";
|
|
31297
31880
|
var NVM_HOME = tool("nvm");
|
|
31298
|
-
var NVM_SYMLINK =
|
|
31299
|
-
var HOST_NVM =
|
|
31881
|
+
var NVM_SYMLINK = path60.join(localDir, "nodejs");
|
|
31882
|
+
var HOST_NVM = path60.join(hostToolsDir, "nvm");
|
|
31300
31883
|
var HOST_VERSIONS_MAX = 3;
|
|
31301
|
-
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)) : [];
|
|
31302
31885
|
var resolveNode = (spec) => resolveCached("node:" + spec, async () => {
|
|
31303
31886
|
const exact = spec.replace(/^v/, "");
|
|
31304
31887
|
if (/^\d+\.\d+\.\d+$/.test(exact)) return exact;
|
|
31305
31888
|
const releases = await fetchJson("https://nodejs.org/dist/index.json");
|
|
31306
31889
|
return pickNodeVersion(releases, spec) ?? Promise.reject(new Error('No Node.js release matches "' + spec + '"'));
|
|
31307
31890
|
});
|
|
31308
|
-
var NVM_TEMP =
|
|
31891
|
+
var NVM_TEMP = path60.join(NVM_HOME, ".tmp");
|
|
31309
31892
|
var nvm = (args) => new Promise((resolve2) => {
|
|
31310
|
-
const child = spawn4(
|
|
31893
|
+
const child = spawn4(path60.join(NVM_HOME, "nvm.exe"), args, {
|
|
31311
31894
|
windowsHide: true,
|
|
31312
31895
|
env: { ...process.env, NVM_HOME, NVM_SYMLINK, TEMP: NVM_TEMP, TMP: NVM_TEMP }
|
|
31313
31896
|
});
|
|
@@ -31322,12 +31905,12 @@ var nvm = (args) => new Promise((resolve2) => {
|
|
|
31322
31905
|
child.once("close", () => resolve2(out));
|
|
31323
31906
|
});
|
|
31324
31907
|
var ensureNvm = async () => {
|
|
31325
|
-
if (exists(
|
|
31326
|
-
if (exists(
|
|
31908
|
+
if (exists(path60.join(NVM_HOME, "nvm.exe"))) return;
|
|
31909
|
+
if (exists(path60.join(HOST_NVM, "nvm.exe"))) {
|
|
31327
31910
|
log("Copying nvm from this PC ...");
|
|
31328
31911
|
mkdirp(NVM_HOME);
|
|
31329
|
-
const files =
|
|
31330
|
-
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));
|
|
31331
31914
|
return;
|
|
31332
31915
|
}
|
|
31333
31916
|
const asset = await githubAsset("coreybutler/nvm-windows", /^nvm-noinstall\.zip$/, true);
|
|
@@ -31335,14 +31918,14 @@ var ensureNvm = async () => {
|
|
|
31335
31918
|
await downloader.archive(asset.url, NVM_HOME, { sha256: asset.sha256, locate: "nvm.exe", fileName: asset.name });
|
|
31336
31919
|
};
|
|
31337
31920
|
var hostNodeFolder = (version2) => {
|
|
31338
|
-
const dir =
|
|
31339
|
-
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;
|
|
31340
31923
|
};
|
|
31341
31924
|
var installNodeVersion = async (version2) => {
|
|
31342
|
-
const dir =
|
|
31343
|
-
const fromHost =
|
|
31344
|
-
if (exists(
|
|
31345
|
-
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"))) {
|
|
31346
31929
|
log("Copying Node " + version2 + " from this PC's nvm (without global packages) ...");
|
|
31347
31930
|
copyNode(fromHost, dir);
|
|
31348
31931
|
return;
|
|
@@ -31361,19 +31944,19 @@ var installNodeVersion = async (version2) => {
|
|
|
31361
31944
|
} finally {
|
|
31362
31945
|
safeRemove(NVM_TEMP, NVM_HOME);
|
|
31363
31946
|
}
|
|
31364
|
-
if (!exists(
|
|
31947
|
+
if (!exists(path60.join(dir, "node.exe"))) {
|
|
31365
31948
|
const tail = out.trim().split(/\r?\n/).filter(Boolean).slice(-3).join(" ");
|
|
31366
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";
|
|
31367
31950
|
throw new Error(
|
|
31368
|
-
"nvm install " + version2 + " did not leave " +
|
|
31951
|
+
"nvm install " + version2 + " did not leave " + path60.join(dir, "node.exe") + " (" + why + ")" + (tail ? ". nvm printed: " + tail : "")
|
|
31369
31952
|
);
|
|
31370
31953
|
}
|
|
31371
31954
|
};
|
|
31372
31955
|
var activate = async (version2) => {
|
|
31373
31956
|
await nvm(["use", version2]);
|
|
31374
|
-
if (exists(
|
|
31375
|
-
|
|
31376
|
-
|
|
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");
|
|
31377
31960
|
};
|
|
31378
31961
|
var PLAYWRIGHT_VARS = () => ({
|
|
31379
31962
|
PLAYWRIGHT_BROWSERS_PATH: tool("ms-playwright"),
|
|
@@ -31385,8 +31968,8 @@ async function setupNode(env, versions, config2) {
|
|
|
31385
31968
|
return;
|
|
31386
31969
|
}
|
|
31387
31970
|
await ensureNvm();
|
|
31388
|
-
|
|
31389
|
-
|
|
31971
|
+
fs48.writeFileSync(
|
|
31972
|
+
path60.join(NVM_HOME, "settings.txt"),
|
|
31390
31973
|
[
|
|
31391
31974
|
"root: " + NVM_HOME,
|
|
31392
31975
|
"path: " + NVM_SYMLINK,
|
|
@@ -31413,7 +31996,7 @@ async function setupNode(env, versions, config2) {
|
|
|
31413
31996
|
}
|
|
31414
31997
|
}
|
|
31415
31998
|
Object.assign(env.vars, { NVM_HOME, NVM_SYMLINK, ...PLAYWRIGHT_VARS() });
|
|
31416
|
-
if (duringSession()) env.prepend.push(
|
|
31999
|
+
if (duringSession()) env.prepend.push(path60.join(NVM_HOME, "v" + main), NVM_HOME, NVM_SYMLINK);
|
|
31417
32000
|
else {
|
|
31418
32001
|
await activate(main);
|
|
31419
32002
|
env.prepend.push(NVM_HOME, NVM_SYMLINK);
|
|
@@ -31423,13 +32006,13 @@ async function setupNode(env, versions, config2) {
|
|
|
31423
32006
|
await packageManagers(env, config2, main);
|
|
31424
32007
|
}
|
|
31425
32008
|
var packageManagers = async (env, config2, version2) => {
|
|
31426
|
-
const dir =
|
|
31427
|
-
const nodeEnv = { ...process.env, PATH: dir +
|
|
31428
|
-
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], {
|
|
31429
32012
|
env: nodeEnv,
|
|
31430
32013
|
stdio: "ignore"
|
|
31431
32014
|
});
|
|
31432
|
-
const corepackJs =
|
|
32015
|
+
const corepackJs = path60.join(dir, "node_modules", "corepack", "dist", "corepack.js");
|
|
31433
32016
|
const extra = config2.corepack && !exists(corepackJs) ? ["corepack"] : [];
|
|
31434
32017
|
await installOnce(
|
|
31435
32018
|
env,
|
|
@@ -31450,7 +32033,7 @@ var packageManagers = async (env, config2, version2) => {
|
|
|
31450
32033
|
}
|
|
31451
32034
|
try {
|
|
31452
32035
|
await execAsync(
|
|
31453
|
-
|
|
32036
|
+
path60.join(dir, "node.exe"),
|
|
31454
32037
|
[corepackJs, "enable", "--install-directory", mkdirp(tool("bin")), "pnpm", "yarn"],
|
|
31455
32038
|
{ env: nodeEnv, stdio: "ignore" }
|
|
31456
32039
|
);
|
|
@@ -31475,8 +32058,8 @@ async function setupPwsh(env, refresh = false) {
|
|
|
31475
32058
|
}
|
|
31476
32059
|
|
|
31477
32060
|
// src/guest/toolchains/languages/python.ts
|
|
31478
|
-
import
|
|
31479
|
-
import
|
|
32061
|
+
import fs49 from "node:fs";
|
|
32062
|
+
import path61 from "node:path";
|
|
31480
32063
|
var installPython = async (pkg, spec) => {
|
|
31481
32064
|
const version2 = await resolveCached(pkg + ":" + spec, async () => {
|
|
31482
32065
|
const { versions } = await fetchJson(
|
|
@@ -31485,7 +32068,7 @@ var installPython = async (pkg, spec) => {
|
|
|
31485
32068
|
return pickPackageVersion(versions, spec) ?? Promise.reject(new Error("No " + pkg + ' release matches "' + spec + '"'));
|
|
31486
32069
|
});
|
|
31487
32070
|
const dir = tool("python", pkg + "-" + version2);
|
|
31488
|
-
const exe =
|
|
32071
|
+
const exe = path61.join(dir, "python.exe");
|
|
31489
32072
|
if (!exists(exe)) {
|
|
31490
32073
|
log("Downloading Python " + version2 + (pkg === "python2" ? " (Python 2, " : " (") + "~30 MB once) ...");
|
|
31491
32074
|
await downloader.archive(
|
|
@@ -31494,32 +32077,32 @@ var installPython = async (pkg, spec) => {
|
|
|
31494
32077
|
{ locate: "python.exe", fileName: pkg + "." + version2 + ".zip" }
|
|
31495
32078
|
);
|
|
31496
32079
|
}
|
|
31497
|
-
if (!exists(
|
|
32080
|
+
if (!exists(path61.join(dir, "Scripts", "pip.exe")) && !exists(path61.join(dir, "Scripts", "pip2.exe")))
|
|
31498
32081
|
await execAsync(exe, ["-m", "ensurepip", "--default-pip"], { stdio: "ignore" });
|
|
31499
32082
|
return dir;
|
|
31500
32083
|
};
|
|
31501
|
-
var shimDir = (dir) => duringSession() ? tool("shims",
|
|
32084
|
+
var shimDir = (dir) => duringSession() ? tool("shims", path61.basename(dir)) : tool("shims");
|
|
31502
32085
|
var shim = (folder, name, program, args = []) => {
|
|
31503
32086
|
const fixed = [program, ...args];
|
|
31504
|
-
|
|
31505
|
-
|
|
32087
|
+
fs49.writeFileSync(
|
|
32088
|
+
path61.join(mkdirp(folder), name + ".cmd"),
|
|
31506
32089
|
"@echo off\r\n" + fixed.map((a) => '"' + a + '"').join(" ") + " %*\r\n"
|
|
31507
32090
|
);
|
|
31508
32091
|
const sh = fixed.map((a) => "'" + a.replace(/\\/g, "/").replace(/'/g, "'\\''") + "'").join(" ");
|
|
31509
|
-
|
|
32092
|
+
fs49.writeFileSync(path61.join(folder, name), "#!/bin/sh\nexec " + sh + ' "$@"\n');
|
|
31510
32093
|
};
|
|
31511
32094
|
var shimPair = (folder, version2, dir) => {
|
|
31512
|
-
const python =
|
|
32095
|
+
const python = path61.join(dir, "python.exe");
|
|
31513
32096
|
shim(folder, "python" + version2, python);
|
|
31514
32097
|
shim(folder, "pip" + version2, python, ["-m", "pip"]);
|
|
31515
32098
|
};
|
|
31516
32099
|
var pyLauncher = (folder, py3, py2) => {
|
|
31517
|
-
const script =
|
|
31518
|
-
|
|
32100
|
+
const script = path61.join(mkdirp(folder), "py-launcher.py");
|
|
32101
|
+
fs49.writeFileSync(
|
|
31519
32102
|
script,
|
|
31520
32103
|
[
|
|
31521
32104
|
"import subprocess, sys",
|
|
31522
|
-
"PY3, PY2 = " + JSON.stringify(
|
|
32105
|
+
"PY3, PY2 = " + JSON.stringify(path61.join(py3, "python.exe")) + ", " + JSON.stringify(py2 ? path61.join(py2, "python.exe") : null),
|
|
31523
32106
|
"args = sys.argv[1:]",
|
|
31524
32107
|
"exe = PY3",
|
|
31525
32108
|
"if args and args[0].startswith('-2'):",
|
|
@@ -31531,7 +32114,7 @@ var pyLauncher = (folder, py3, py2) => {
|
|
|
31531
32114
|
""
|
|
31532
32115
|
].join("\n")
|
|
31533
32116
|
);
|
|
31534
|
-
shim(folder, "py",
|
|
32117
|
+
shim(folder, "py", path61.join(py3, "python.exe"), [script]);
|
|
31535
32118
|
};
|
|
31536
32119
|
async function setupPython(env, config2, versions) {
|
|
31537
32120
|
if (dryRun) {
|
|
@@ -31541,10 +32124,10 @@ async function setupPython(env, config2, versions) {
|
|
|
31541
32124
|
const py3 = await installPython("python", versions.python.spec);
|
|
31542
32125
|
const shims = shimDir(py3);
|
|
31543
32126
|
shimPair(shims, "3", py3);
|
|
31544
|
-
env.prepend.push(py3, mkdirp(
|
|
32127
|
+
env.prepend.push(py3, mkdirp(path61.join(py3, "Scripts")), shims);
|
|
31545
32128
|
env.vars.PYTHONIOENCODING = "utf-8";
|
|
31546
32129
|
env.summary.push(
|
|
31547
|
-
"python: " +
|
|
32130
|
+
"python: " + path61.basename(py3).replace("python-", "") + " (from " + versions.python.source + "; py works too)"
|
|
31548
32131
|
);
|
|
31549
32132
|
if (!config2.python2) {
|
|
31550
32133
|
pyLauncher(shims, py3, null);
|
|
@@ -31553,12 +32136,12 @@ async function setupPython(env, config2, versions) {
|
|
|
31553
32136
|
const py2 = await installPython("python2", "2.7");
|
|
31554
32137
|
shimPair(shims, "2", py2);
|
|
31555
32138
|
pyLauncher(shims, py3, py2);
|
|
31556
|
-
env.summary.push("python2: " +
|
|
32139
|
+
env.summary.push("python2: " + path61.basename(py2).replace("python2-", ""));
|
|
31557
32140
|
}
|
|
31558
32141
|
|
|
31559
32142
|
// src/guest/toolchains/languages/php.ts
|
|
31560
|
-
import
|
|
31561
|
-
import
|
|
32143
|
+
import fs50 from "node:fs";
|
|
32144
|
+
import path62 from "node:path";
|
|
31562
32145
|
var PHP_EXTENSIONS = [
|
|
31563
32146
|
"curl",
|
|
31564
32147
|
"fileinfo",
|
|
@@ -31576,11 +32159,11 @@ var PHP_EXTENSIONS = [
|
|
|
31576
32159
|
var COMPOSER = "https://getcomposer.org/download/latest-stable/composer.phar";
|
|
31577
32160
|
var phpBuild = async (spec) => {
|
|
31578
32161
|
const releases = await fetchJson("https://windows.php.net/downloads/releases/releases.json");
|
|
31579
|
-
const
|
|
32162
|
+
const pick3 = pickPackageVersion(
|
|
31580
32163
|
Object.values(releases).map((r) => r.version),
|
|
31581
32164
|
spec
|
|
31582
32165
|
);
|
|
31583
|
-
const release = Object.values(releases).find((r) => r.version ===
|
|
32166
|
+
const release = Object.values(releases).find((r) => r.version === pick3);
|
|
31584
32167
|
const build = release && Object.entries(release).find(
|
|
31585
32168
|
([key2, value]) => /^nts-vs\d+-x64$/.test(key2) && typeof value === "object" && value.zip
|
|
31586
32169
|
)?.[1];
|
|
@@ -31589,16 +32172,16 @@ var phpBuild = async (spec) => {
|
|
|
31589
32172
|
return { version: release.version, ...build.zip };
|
|
31590
32173
|
};
|
|
31591
32174
|
var writePhpIni = (home) => {
|
|
31592
|
-
const ini =
|
|
31593
|
-
if (exists(ini) || !exists(
|
|
31594
|
-
let text =
|
|
31595
|
-
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"))))
|
|
31596
32179
|
text = text.replace(new RegExp("^;(extension=" + ext + ")\\s*$", "m"), "$1");
|
|
31597
|
-
|
|
31598
|
-
|
|
32180
|
+
fs50.writeFileSync(ini + ".tmp", text);
|
|
32181
|
+
fs50.renameSync(ini + ".tmp", ini);
|
|
31599
32182
|
};
|
|
31600
32183
|
var shim2 = (env, name, command) => {
|
|
31601
|
-
|
|
32184
|
+
fs50.writeFileSync(path62.join(mkdirp(tool("shims")), name + ".cmd"), "@echo off\r\n" + command + " %*\r\n");
|
|
31602
32185
|
env.prepend.push(tool("shims"));
|
|
31603
32186
|
};
|
|
31604
32187
|
var setupComposer = async (env, php) => {
|
|
@@ -31610,7 +32193,7 @@ var setupComposer = async (env, php) => {
|
|
|
31610
32193
|
}
|
|
31611
32194
|
const composerHome = tool("composer-home");
|
|
31612
32195
|
env.vars.COMPOSER_HOME = composerHome;
|
|
31613
|
-
env.prepend.push(
|
|
32196
|
+
env.prepend.push(path62.join(composerHome, "vendor", "bin"));
|
|
31614
32197
|
shim2(env, "composer", '"' + php + '" "' + phar + '"');
|
|
31615
32198
|
env.summary.push(
|
|
31616
32199
|
"composer: " + (/\d+\.\d+\.\d+/.exec(execOutput(php, [phar, "--version", "--no-ansi"]))?.[0] ?? "installed")
|
|
@@ -31625,7 +32208,7 @@ async function setupPhp(env, config2) {
|
|
|
31625
32208
|
await setupVcRuntime(env, false);
|
|
31626
32209
|
const version2 = await resolveCached("php:" + wantedSpec.spec, async () => (await phpBuild(wantedSpec.spec)).version);
|
|
31627
32210
|
const home = tool("php", version2);
|
|
31628
|
-
if (!exists(
|
|
32211
|
+
if (!exists(path62.join(home, "php.exe"))) {
|
|
31629
32212
|
const build = await phpBuild(version2);
|
|
31630
32213
|
log("Downloading PHP " + version2 + " (~30 MB once) ...");
|
|
31631
32214
|
await downloader.archive("https://windows.php.net/downloads/releases/" + build.path, home, {
|
|
@@ -31637,11 +32220,11 @@ async function setupPhp(env, config2) {
|
|
|
31637
32220
|
writePhpIni(home);
|
|
31638
32221
|
env.prepend.push(home);
|
|
31639
32222
|
env.summary.push("php: " + version2 + " (from " + wantedSpec.source + ")");
|
|
31640
|
-
if (config2.composer) await setupComposer(env,
|
|
32223
|
+
if (config2.composer) await setupComposer(env, path62.join(home, "php.exe"));
|
|
31641
32224
|
}
|
|
31642
32225
|
|
|
31643
32226
|
// src/guest/toolchains/languages/ruby.ts
|
|
31644
|
-
import
|
|
32227
|
+
import path63 from "node:path";
|
|
31645
32228
|
var RUBY_ASSET = /^rubyinstaller-(\d+\.\d+\.\d+)-(\d+)-x64\.7z$/;
|
|
31646
32229
|
var buildNumber = (asset) => Number(RUBY_ASSET.exec(asset.name)?.[2] ?? 0);
|
|
31647
32230
|
var rubyBuilds = async () => {
|
|
@@ -31669,7 +32252,7 @@ async function setupRuby(env, config2) {
|
|
|
31669
32252
|
async () => pickPackageVersion([...(await rubyBuilds()).keys()], wantedSpec.spec) ?? Promise.reject(new Error('No RubyInstaller build matches "' + wantedSpec.spec + '"'))
|
|
31670
32253
|
);
|
|
31671
32254
|
const home = tool("ruby", version2);
|
|
31672
|
-
if (!exists(
|
|
32255
|
+
if (!exists(path63.join(home, "bin", "ruby.exe"))) {
|
|
31673
32256
|
const asset = (await rubyBuilds()).get(version2);
|
|
31674
32257
|
if (!asset) throw new Error("RubyInstaller " + version2 + " is no longer published");
|
|
31675
32258
|
log("Downloading Ruby " + version2 + " (~100 MB once) ...");
|
|
@@ -31682,11 +32265,11 @@ async function setupRuby(env, config2) {
|
|
|
31682
32265
|
}
|
|
31683
32266
|
const gems = tool("ruby-gems", version2.split(".").slice(0, 2).join("."));
|
|
31684
32267
|
Object.assign(env.vars, { GEM_HOME: gems, BUNDLE_USER_HOME: tool("bundle-home") });
|
|
31685
|
-
env.prepend.push(
|
|
32268
|
+
env.prepend.push(path63.join(home, "bin"), path63.join(gems, "bin"));
|
|
31686
32269
|
env.summary.push(
|
|
31687
|
-
"ruby: " + versionOf(
|
|
32270
|
+
"ruby: " + versionOf(path63.join(home, "bin", "ruby.exe")) + " (from " + wantedSpec.source + "; gems with C extensions need MSYS2, not included)"
|
|
31688
32271
|
);
|
|
31689
|
-
const gem =
|
|
32272
|
+
const gem = path63.join(home, "bin", "gem.cmd");
|
|
31690
32273
|
await installOnce(
|
|
31691
32274
|
env,
|
|
31692
32275
|
"gem@" + version2,
|
|
@@ -31698,9 +32281,9 @@ async function setupRuby(env, config2) {
|
|
|
31698
32281
|
}
|
|
31699
32282
|
|
|
31700
32283
|
// src/guest/toolchains/tools/vscode.ts
|
|
31701
|
-
import
|
|
31702
|
-
import
|
|
31703
|
-
import
|
|
32284
|
+
import fs51 from "node:fs";
|
|
32285
|
+
import os9 from "node:os";
|
|
32286
|
+
import path64 from "node:path";
|
|
31704
32287
|
|
|
31705
32288
|
// node_modules/jsonc-parser/lib/esm/impl/scanner.js
|
|
31706
32289
|
var CharacterCodes;
|
|
@@ -31880,14 +32463,14 @@ var ParseErrorCode;
|
|
|
31880
32463
|
var VERSION_MARKER = ".agent-sandbox-version";
|
|
31881
32464
|
var desktopShortcut = (exe) => {
|
|
31882
32465
|
if (!isWin) return;
|
|
31883
|
-
const link =
|
|
32466
|
+
const link = path64.join(os9.homedir(), "Desktop", "Visual Studio Code.lnk");
|
|
31884
32467
|
runScriptWithJson("new-shortcuts.ps1", "ListFile", [
|
|
31885
32468
|
{ link, target: exe, arguments: '"' + (process.env.AGENT_WORKSPACE ?? "") + '"' }
|
|
31886
32469
|
]);
|
|
31887
32470
|
};
|
|
31888
32471
|
async function setupVscode(env, refresh) {
|
|
31889
32472
|
const root = tool("vscode");
|
|
31890
|
-
const exe =
|
|
32473
|
+
const exe = path64.join(root, "Code.exe");
|
|
31891
32474
|
if (dryRun) {
|
|
31892
32475
|
log("(dry run) would provision VS Code");
|
|
31893
32476
|
return;
|
|
@@ -31897,11 +32480,11 @@ async function setupVscode(env, refresh) {
|
|
|
31897
32480
|
"https://update.code.visualstudio.com/api/update/win32-" + (arch === "arm64" ? "arm64" : "x64") + "-archive/stable/latest"
|
|
31898
32481
|
);
|
|
31899
32482
|
log("Downloading VS Code " + release.productVersion + " (~150 MB once) ...");
|
|
31900
|
-
const keep =
|
|
32483
|
+
const keep = path64.join(root, "data");
|
|
31901
32484
|
const parked = root + "-data";
|
|
31902
32485
|
if (exists(keep)) {
|
|
31903
|
-
|
|
31904
|
-
|
|
32486
|
+
fs51.rmSync(parked, { recursive: true, force: true });
|
|
32487
|
+
fs51.renameSync(keep, parked);
|
|
31905
32488
|
}
|
|
31906
32489
|
try {
|
|
31907
32490
|
await downloader.archive(release.url, root, {
|
|
@@ -31909,26 +32492,511 @@ async function setupVscode(env, refresh) {
|
|
|
31909
32492
|
locate: "Code.exe",
|
|
31910
32493
|
fileName: "vscode.zip"
|
|
31911
32494
|
});
|
|
31912
|
-
|
|
32495
|
+
fs51.writeFileSync(path64.join(root, VERSION_MARKER), release.productVersion);
|
|
31913
32496
|
} finally {
|
|
31914
32497
|
if (exists(parked)) {
|
|
31915
32498
|
mkdirp(root);
|
|
31916
|
-
|
|
31917
|
-
|
|
32499
|
+
fs51.rmSync(keep, { recursive: true, force: true });
|
|
32500
|
+
fs51.renameSync(parked, keep);
|
|
31918
32501
|
}
|
|
31919
32502
|
}
|
|
31920
32503
|
}
|
|
31921
|
-
mkdirp(
|
|
31922
|
-
env.prepend.push(
|
|
32504
|
+
mkdirp(path64.join(root, "data"));
|
|
32505
|
+
env.prepend.push(path64.join(root, "bin"));
|
|
31923
32506
|
desktopShortcut(exe);
|
|
31924
|
-
const version2 = exists(
|
|
32507
|
+
const version2 = exists(path64.join(root, VERSION_MARKER)) ? fs51.readFileSync(path64.join(root, VERSION_MARKER), "utf8").trim() : "installed";
|
|
31925
32508
|
env.summary.push("vscode: " + version2 + " (portable; run code . or use the desktop shortcut)");
|
|
31926
32509
|
}
|
|
31927
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
|
+
|
|
31928
32996
|
// src/guest/toolchains/native/rust-extras.ts
|
|
31929
|
-
import
|
|
31930
|
-
import
|
|
31931
|
-
import
|
|
32997
|
+
import fs56 from "node:fs";
|
|
32998
|
+
import os10 from "node:os";
|
|
32999
|
+
import path70 from "node:path";
|
|
31932
33000
|
|
|
31933
33001
|
// src/shared/memory/policy.ts
|
|
31934
33002
|
var DIAL_STEPS = {
|
|
@@ -31977,41 +33045,41 @@ function maxCompilers(cpus, profile) {
|
|
|
31977
33045
|
// src/guest/toolchains/native/rust-extras.ts
|
|
31978
33046
|
var cargoTarget = (targetDir) => {
|
|
31979
33047
|
if (targetDir === "shared" || targetDir === "separate") return null;
|
|
31980
|
-
if (targetDir === "local") return
|
|
33048
|
+
if (targetDir === "local") return path70.join(localDir, "cargo-target");
|
|
31981
33049
|
return targetDir;
|
|
31982
33050
|
};
|
|
31983
33051
|
function cargoShim(env, rust) {
|
|
31984
|
-
const real =
|
|
33052
|
+
const real = path70.join(tool("rust", "cargo", "bin"), "cargo.exe");
|
|
31985
33053
|
if (rust.targetDir !== "separate" || !exists(real)) return;
|
|
31986
33054
|
const dir = mkdirp(tool("shims", "cargo"));
|
|
31987
|
-
|
|
33055
|
+
fs56.copyFileSync(ensureCompiled("cargoshim"), path70.join(dir, "cargo.exe"));
|
|
31988
33056
|
env.prepend.unshift(dir);
|
|
31989
33057
|
env.vars.AGENT_REAL_CARGO = real;
|
|
31990
33058
|
}
|
|
31991
33059
|
function linkGate(env, rust, host) {
|
|
31992
33060
|
const gcc = tool("mingw", "mingw64", "bin", "gcc.exe");
|
|
31993
33061
|
if (!host.endsWith("-pc-windows-gnu") || !exists(gcc)) return;
|
|
31994
|
-
const gate =
|
|
31995
|
-
|
|
31996
|
-
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;
|
|
31997
33065
|
const slots = rust.linkSlots === "auto" ? linkSlotsFor(memoryGb) : rust.linkSlots;
|
|
31998
33066
|
env.vars.AGENT_LINK_SLOTS = String(slots);
|
|
31999
33067
|
env.vars.AGENT_REAL_LINKER = gcc;
|
|
32000
33068
|
env.vars.CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER = gate;
|
|
32001
33069
|
const rustEnv = { ...process.env, RUSTUP_HOME: tool("rust", "rustup"), CARGO_HOME: tool("rust", "cargo") };
|
|
32002
33070
|
const sysroot = rust.linker === "lld" ? execOutput(tool("rust", "cargo", "bin", "rustc.exe"), ["--print", "sysroot"], { env: rustEnv }) : "";
|
|
32003
|
-
const lld = sysroot ?
|
|
32004
|
-
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;
|
|
32005
33073
|
env.summary.push(
|
|
32006
33074
|
"rust linking: " + (env.vars.AGENT_LLD_DIR ? "lld" : "GNU ld") + ", at most " + env.vars.AGENT_LINK_SLOTS + " at once"
|
|
32007
33075
|
);
|
|
32008
33076
|
}
|
|
32009
33077
|
function cargoDefaults(host) {
|
|
32010
33078
|
const file3 = tool("rust", "cargo", "config.toml");
|
|
32011
|
-
if (exists(file3) || !exists(
|
|
32012
|
-
const jobs = cargoJobs(
|
|
33079
|
+
if (exists(file3) || !exists(path70.dirname(file3))) return;
|
|
33080
|
+
const jobs = cargoJobs(os10.cpus().length, os10.totalmem() / 1024 ** 3, 1);
|
|
32013
33081
|
const gnu = host.endsWith("-gnu");
|
|
32014
|
-
|
|
33082
|
+
fs56.writeFileSync(
|
|
32015
33083
|
file3,
|
|
32016
33084
|
[
|
|
32017
33085
|
"# Written by windows-development-sandbox once; edit freely, it is never overwritten.",
|
|
@@ -32026,7 +33094,7 @@ function rustCaches(rust) {
|
|
|
32026
33094
|
const target = cargoTarget(rust.targetDir);
|
|
32027
33095
|
return {
|
|
32028
33096
|
...target ? { CARGO_TARGET_DIR: target } : {},
|
|
32029
|
-
...process.env.SCCACHE_DIR ? {} : { SCCACHE_DIR:
|
|
33097
|
+
...process.env.SCCACHE_DIR ? {} : { SCCACHE_DIR: path70.join(dataDir, "cache", "sccache") }
|
|
32030
33098
|
};
|
|
32031
33099
|
}
|
|
32032
33100
|
function rustHost(config2) {
|
|
@@ -32054,6 +33122,13 @@ function plan(config2, versions, o) {
|
|
|
32054
33122
|
const java = wanted(config2.java.enabled, "java");
|
|
32055
33123
|
const python = wanted(config2.python.enabled, "python");
|
|
32056
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
|
+
};
|
|
32057
33132
|
return [
|
|
32058
33133
|
{
|
|
32059
33134
|
name: "Git",
|
|
@@ -32071,18 +33146,32 @@ function plan(config2, versions, o) {
|
|
|
32071
33146
|
enabled: wanted(config2.cpp.enabled, "cpp") || wanted(config2.rust.enabled, "rust"),
|
|
32072
33147
|
install: (env) => setupCpp(env, config2.cpp)
|
|
32073
33148
|
},
|
|
32074
|
-
//
|
|
32075
|
-
{
|
|
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
|
+
},
|
|
32076
33165
|
{
|
|
32077
33166
|
name: "MSVC",
|
|
32078
|
-
enabled: wanted(config2.msvc.enabled, "msvc") &&
|
|
33167
|
+
enabled: wanted(config2.msvc.enabled, "msvc") && vs === null,
|
|
32079
33168
|
install: (env) => setupMsvc(env, config2.msvc)
|
|
32080
33169
|
},
|
|
32081
33170
|
// Rust links with MSVC (msvc host) or MinGW's gcc (GNU host): whichever it uses goes first.
|
|
32082
33171
|
{
|
|
32083
33172
|
name: "Rust",
|
|
32084
33173
|
enabled: wanted(config2.rust.enabled, "rust"),
|
|
32085
|
-
after: ["C/C++", "MSVC", "Unreal"],
|
|
33174
|
+
after: ["C/C++", "MSVC", "Visual Studio", "Unreal"],
|
|
32086
33175
|
install: async (env) => {
|
|
32087
33176
|
await setupRust(env, { ...config2.rust, host: rustHost(config2) }, o.refresh);
|
|
32088
33177
|
Object.assign(env.vars, rustCaches(config2.rust));
|
|
@@ -32100,6 +33189,49 @@ function plan(config2, versions, o) {
|
|
|
32100
33189
|
},
|
|
32101
33190
|
{ name: "Go", enabled: wanted(config2.go.enabled, "go"), install: (env) => setupGo(env, config2.go) },
|
|
32102
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
|
+
},
|
|
32103
33235
|
{ name: "Ruby", enabled: wanted(config2.ruby.enabled, "ruby"), install: (env) => setupRuby(env, config2.ruby) },
|
|
32104
33236
|
// PHP installs the Visual C++ runtime itself: one installer at a time.
|
|
32105
33237
|
// Many apps (bat, delta, Neovim, most GUIs, your own programs) are built against it too.
|
|
@@ -32175,7 +33307,7 @@ function plan(config2, versions, o) {
|
|
|
32175
33307
|
import { AsyncLocalStorage as AsyncLocalStorage2 } from "node:async_hooks";
|
|
32176
33308
|
|
|
32177
33309
|
// src/guest/runtime/status.ts
|
|
32178
|
-
import
|
|
33310
|
+
import os11 from "node:os";
|
|
32179
33311
|
var progress;
|
|
32180
33312
|
function setSandboxStatus(phase, message, update) {
|
|
32181
33313
|
try {
|
|
@@ -32199,7 +33331,7 @@ function fitProgress(p) {
|
|
|
32199
33331
|
};
|
|
32200
33332
|
}
|
|
32201
33333
|
function ownAddresses() {
|
|
32202
|
-
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);
|
|
32203
33335
|
}
|
|
32204
33336
|
function writeStatus(phase, message) {
|
|
32205
33337
|
writeJsonAtomic(run.sandboxFile, {
|
|
@@ -32344,21 +33476,21 @@ function cmdSet(env, names) {
|
|
|
32344
33476
|
return names.filter((n) => env[n] !== void 0 && !/[\r\n]/.test(String(env[n]))).map((n) => '@set "' + n + "=" + String(env[n]).replace(/%/g, "%%") + '"');
|
|
32345
33477
|
}
|
|
32346
33478
|
function writeShell(spec, env, names) {
|
|
32347
|
-
const dir = mkdirp(
|
|
32348
|
-
|
|
32349
|
-
|
|
32350
|
-
|
|
32351
|
-
['@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(
|
|
32352
33484
|
"\r\n"
|
|
32353
33485
|
)
|
|
32354
33486
|
);
|
|
32355
|
-
const bin = mkdirp(
|
|
32356
|
-
|
|
32357
|
-
|
|
33487
|
+
const bin = mkdirp(path71.join(localDir, "bin"));
|
|
33488
|
+
fs57.writeFileSync(
|
|
33489
|
+
path71.join(bin, "sbx-shell.cmd"),
|
|
32358
33490
|
[
|
|
32359
|
-
'@if "%~1"=="" (echo Usage: sbx-shell ^<project^> ^(a terminal in that project with its tools^) & dir /b "' +
|
|
32360
|
-
'@if not exist "' +
|
|
32361
|
-
'@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""',
|
|
32362
33494
|
""
|
|
32363
33495
|
].join("\r\n")
|
|
32364
33496
|
);
|
|
@@ -32411,10 +33543,10 @@ async function setUp(spec, say) {
|
|
|
32411
33543
|
}
|
|
32412
33544
|
)
|
|
32413
33545
|
);
|
|
32414
|
-
tools.prepend.push(
|
|
33546
|
+
tools.prepend.push(path71.join(localDir, "bin"));
|
|
32415
33547
|
const env = agentEnv(tools, { workspace: spec.workspace, project: spec.name, base });
|
|
32416
|
-
const specFile =
|
|
32417
|
-
|
|
33548
|
+
const specFile = path71.join(mkdirp(path71.join(localDir, "projects", spec.name)), "project.json");
|
|
33549
|
+
fs57.writeFileSync(specFile, JSON.stringify(spec));
|
|
32418
33550
|
env.AGENT_PROJECT_FILE = specFile;
|
|
32419
33551
|
addMachineEnvironment(tools.vars, [...tools.prepend, ...tools.append], true);
|
|
32420
33552
|
try {
|
|
@@ -32502,7 +33634,7 @@ function execCommand(req) {
|
|
|
32502
33634
|
return;
|
|
32503
33635
|
}
|
|
32504
33636
|
const env = withRegistryPath(provisioner.provisionedFor(req.cwd)?.env ?? process.env);
|
|
32505
|
-
const child =
|
|
33637
|
+
const child = spawn6(
|
|
32506
33638
|
SYSTEM.cmd(),
|
|
32507
33639
|
["/d", "/s", "/c", '"chcp 65001>nul & ' + req.command.map(quoteForCmd).join(" ") + '"'],
|
|
32508
33640
|
{ cwd: req.cwd, env, windowsHide: true, windowsVerbatimArguments: true }
|
|
@@ -32531,11 +33663,11 @@ function execCommand(req) {
|
|
|
32531
33663
|
}
|
|
32532
33664
|
|
|
32533
33665
|
// src/guest/daemon/sessions.ts
|
|
32534
|
-
import
|
|
32535
|
-
import
|
|
32536
|
-
import
|
|
32537
|
-
import
|
|
32538
|
-
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";
|
|
32539
33671
|
|
|
32540
33672
|
// src/shared/pty/protocol.ts
|
|
32541
33673
|
var FrameType = {
|
|
@@ -32613,7 +33745,7 @@ async function sendControl(endpoint, type) {
|
|
|
32613
33745
|
var MAX_CLIPBOARD_STRING = 1024 * 1024;
|
|
32614
33746
|
|
|
32615
33747
|
// src/guest/sessions/cmdline.ts
|
|
32616
|
-
import
|
|
33748
|
+
import path72 from "node:path";
|
|
32617
33749
|
var quoted = (arg) => '"' + arg.replace(/(\\*)"/g, '$1$1\\"').replace(/(\\+)$/, "$1$1") + '"';
|
|
32618
33750
|
function quoteArg(arg) {
|
|
32619
33751
|
return arg !== "" && !/[\s"]/.test(arg) ? arg : quoted(arg);
|
|
@@ -32627,7 +33759,7 @@ function cmdArgs(args) {
|
|
|
32627
33759
|
}).join("");
|
|
32628
33760
|
}
|
|
32629
33761
|
function commandLine(file3, args) {
|
|
32630
|
-
return
|
|
33762
|
+
return path72.win32.basename(file3).toLowerCase() === "cmd.exe" ? [quoteArg(file3), cmdArgs(args)].filter(Boolean).join(" ") : [file3, ...args].map(quoteArg).join(" ");
|
|
32631
33763
|
}
|
|
32632
33764
|
function shellLaunch(asked, paths) {
|
|
32633
33765
|
if (asked === "cmd") return { name: "cmd", file: paths.cmd, args: [] };
|
|
@@ -32641,9 +33773,9 @@ function shellLaunch(asked, paths) {
|
|
|
32641
33773
|
}
|
|
32642
33774
|
|
|
32643
33775
|
// src/guest/sessions/pty-host.ts
|
|
32644
|
-
import
|
|
32645
|
-
import
|
|
32646
|
-
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";
|
|
32647
33779
|
function ensurePtyHost() {
|
|
32648
33780
|
return ensureCompiled("ptyhost");
|
|
32649
33781
|
}
|
|
@@ -32661,21 +33793,21 @@ async function waitForPtyHost(child, port, timeoutMs) {
|
|
|
32661
33793
|
throw new Error("the session host did not start listening on port " + port);
|
|
32662
33794
|
}
|
|
32663
33795
|
function ptyHostLog(id) {
|
|
32664
|
-
return
|
|
33796
|
+
return path73.join(logsDir, "ptyhost-" + id + ".log");
|
|
32665
33797
|
}
|
|
32666
33798
|
function ptyHostLogTail(id, lines = 12) {
|
|
32667
33799
|
try {
|
|
32668
|
-
return
|
|
33800
|
+
return fs58.readFileSync(ptyHostLog(id), "utf8").trim().split(/\r?\n/).slice(-lines).join("\n");
|
|
32669
33801
|
} catch {
|
|
32670
33802
|
return "";
|
|
32671
33803
|
}
|
|
32672
33804
|
}
|
|
32673
33805
|
var conptyDll = () => {
|
|
32674
|
-
const dll =
|
|
32675
|
-
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;
|
|
32676
33808
|
};
|
|
32677
33809
|
function startPtyHost(o) {
|
|
32678
|
-
|
|
33810
|
+
fs58.mkdirSync(run.treesDir, { recursive: true });
|
|
32679
33811
|
const env = {
|
|
32680
33812
|
...o.env,
|
|
32681
33813
|
PTYHOST_BIND: o.remote ? "any" : "loopback",
|
|
@@ -32684,7 +33816,7 @@ function startPtyHost(o) {
|
|
|
32684
33816
|
delete env.PTYHOST_CONPTY;
|
|
32685
33817
|
const dll = conptyDll();
|
|
32686
33818
|
if (dll) env.PTYHOST_CONPTY = dll;
|
|
32687
|
-
return
|
|
33819
|
+
return spawn7(
|
|
32688
33820
|
o.exe,
|
|
32689
33821
|
[String(o.port), o.token, String(o.cols), String(o.rows), ptyHostLog(o.id), o.command, o.restartCommand],
|
|
32690
33822
|
{ cwd: o.cwd, env, detached: true, stdio: "ignore", windowsHide: true }
|
|
@@ -32693,13 +33825,13 @@ function startPtyHost(o) {
|
|
|
32693
33825
|
var END_TREE_MS = 3e4;
|
|
32694
33826
|
function endLeftoverTree(id, exe = ensurePtyHost()) {
|
|
32695
33827
|
const file3 = run.treeFile(id);
|
|
32696
|
-
if (!
|
|
33828
|
+
if (!fs58.existsSync(file3)) return Promise.resolve(null);
|
|
32697
33829
|
return new Promise((resolve2) => {
|
|
32698
33830
|
execFile(exe, ["--end-tree", file3], { timeout: END_TREE_MS, windowsHide: true }, (error62, stdout) => {
|
|
32699
33831
|
const code = error62 ? typeof error62.code === "number" ? error62.code : -1 : 0;
|
|
32700
33832
|
if (code !== 3)
|
|
32701
33833
|
try {
|
|
32702
|
-
|
|
33834
|
+
fs58.rmSync(file3, { force: true });
|
|
32703
33835
|
} catch {
|
|
32704
33836
|
}
|
|
32705
33837
|
resolve2(code === 0 ? stdout.trim().slice(0, 200) : code === 3 ? null : "could not end them (code " + code + ")");
|
|
@@ -32708,15 +33840,15 @@ function endLeftoverTree(id, exe = ensurePtyHost()) {
|
|
|
32708
33840
|
}
|
|
32709
33841
|
function recordedTrees() {
|
|
32710
33842
|
try {
|
|
32711
|
-
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));
|
|
32712
33844
|
} catch {
|
|
32713
33845
|
return [];
|
|
32714
33846
|
}
|
|
32715
33847
|
}
|
|
32716
33848
|
|
|
32717
33849
|
// src/guest/agents/agent-installer.ts
|
|
32718
|
-
import
|
|
32719
|
-
import
|
|
33850
|
+
import fs59 from "node:fs";
|
|
33851
|
+
import path74 from "node:path";
|
|
32720
33852
|
|
|
32721
33853
|
// src/guest/agents/profile-links.ts
|
|
32722
33854
|
var profileRoot = () => process.env.USERPROFILE ?? "";
|
|
@@ -32742,7 +33874,7 @@ var agentPaths2 = (name, harness) => agentPaths(toolsDir, name, harness);
|
|
|
32742
33874
|
async function installViaNpm(name, harness, dir, env) {
|
|
32743
33875
|
if (!harness.npmPackage)
|
|
32744
33876
|
throw new Error("No npmPackage configured for " + name + " and no host executable was available.");
|
|
32745
|
-
const npmCli =
|
|
33877
|
+
const npmCli = path74.join(path74.dirname(process.execPath), "node_modules", "npm", "bin", "npm-cli.js");
|
|
32746
33878
|
const args = [npmCli, "install", "--global", "--prefix", dir, harness.npmPackage, "--no-fund", "--no-audit"];
|
|
32747
33879
|
log("Installing " + harness.npmPackage + " (this can take a minute)...");
|
|
32748
33880
|
if (dryRun) {
|
|
@@ -32753,7 +33885,7 @@ async function installViaNpm(name, harness, dir, env) {
|
|
|
32753
33885
|
await execAsync(process.execPath, args, { env });
|
|
32754
33886
|
}
|
|
32755
33887
|
async function installViaUv(name, harness, dir, env) {
|
|
32756
|
-
const uv =
|
|
33888
|
+
const uv = path74.join(toolsDir, "uv", "uv.exe");
|
|
32757
33889
|
log("Installing " + harness.uvPackage + " with uv (this can take a minute)...");
|
|
32758
33890
|
if (dryRun) {
|
|
32759
33891
|
log("(dry run) uv tool install " + harness.uvPackage);
|
|
@@ -32768,8 +33900,8 @@ async function installViaUv(name, harness, dir, env) {
|
|
|
32768
33900
|
});
|
|
32769
33901
|
}
|
|
32770
33902
|
function putOnPath(dir, env) {
|
|
32771
|
-
const parts2 = (env.PATH ?? "").split(
|
|
32772
|
-
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);
|
|
32773
33905
|
addMachineEnvironment({}, [dir], true);
|
|
32774
33906
|
}
|
|
32775
33907
|
var AgentInstaller = class {
|
|
@@ -32810,9 +33942,9 @@ var AgentInstaller = class {
|
|
|
32810
33942
|
}
|
|
32811
33943
|
mkdirp(p.dir);
|
|
32812
33944
|
if (this.sourceOf(name, harness) === "host") {
|
|
32813
|
-
const source =
|
|
33945
|
+
const source = path74.join(hostToolsDir, "agents", name, harness.hostExecutable);
|
|
32814
33946
|
if (exists(source) && p.exe) {
|
|
32815
|
-
|
|
33947
|
+
fs59.copyFileSync(source, p.exe);
|
|
32816
33948
|
log("Copied " + name + " from this PC: " + source);
|
|
32817
33949
|
return;
|
|
32818
33950
|
}
|
|
@@ -32827,28 +33959,28 @@ var AgentInstaller = class {
|
|
|
32827
33959
|
var agents = new AgentInstaller();
|
|
32828
33960
|
|
|
32829
33961
|
// src/guest/network/addresses.ts
|
|
32830
|
-
import
|
|
33962
|
+
import os12 from "node:os";
|
|
32831
33963
|
function guestAddresses() {
|
|
32832
|
-
return Object.values(
|
|
33964
|
+
return Object.values(os12.networkInterfaces()).flat().filter((i) => Boolean(i) && i.family === "IPv4" && !i.internal).map((i) => i.address);
|
|
32833
33965
|
}
|
|
32834
33966
|
|
|
32835
33967
|
// src/guest/sessions/conversation.ts
|
|
32836
|
-
import
|
|
32837
|
-
import
|
|
33968
|
+
import fs60 from "node:fs";
|
|
33969
|
+
import path75 from "node:path";
|
|
32838
33970
|
var MAX_FILES = 2e3;
|
|
32839
33971
|
function conversationFiles(claudeDir2, cwd) {
|
|
32840
33972
|
const names = /* @__PURE__ */ new Set([projectFolderName(cwd), projectFolderName(sandboxFolder(cwd))]);
|
|
32841
33973
|
return [...names].flatMap((name) => {
|
|
32842
|
-
const dir =
|
|
33974
|
+
const dir = path75.join(claudeDir2, "projects", name);
|
|
32843
33975
|
let entries2;
|
|
32844
33976
|
try {
|
|
32845
|
-
entries2 =
|
|
33977
|
+
entries2 = fs60.readdirSync(dir);
|
|
32846
33978
|
} catch {
|
|
32847
33979
|
return [];
|
|
32848
33980
|
}
|
|
32849
33981
|
return entries2.filter((e) => e.endsWith(".jsonl") && isConversationId(e.slice(0, -".jsonl".length))).slice(0, MAX_FILES).flatMap((e) => {
|
|
32850
33982
|
try {
|
|
32851
|
-
return [{ id: e.slice(0, -".jsonl".length), createdMs:
|
|
33983
|
+
return [{ id: e.slice(0, -".jsonl".length), createdMs: fs60.statSync(path75.join(dir, e)).birthtimeMs }];
|
|
32852
33984
|
} catch {
|
|
32853
33985
|
return [];
|
|
32854
33986
|
}
|
|
@@ -32861,6 +33993,263 @@ function findConversation(claudeDir2, cwd, sessionStartMs, claimed) {
|
|
|
32861
33993
|
|
|
32862
33994
|
// src/guest/daemon/idle-shutdown.ts
|
|
32863
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
|
|
32864
34253
|
var GRACE_MS = 15e3;
|
|
32865
34254
|
var IdleShutdown = class {
|
|
32866
34255
|
/** `busy`: a session runs or is starting. */
|
|
@@ -32877,7 +34266,7 @@ var IdleShutdown = class {
|
|
|
32877
34266
|
log("Headless sandbox has no sessions left; shutting down.");
|
|
32878
34267
|
safely("claude-mem save", saveClaudeMem);
|
|
32879
34268
|
safely("agent databases save", saveLocalState);
|
|
32880
|
-
spawnSync6(SYSTEM.shutdown(), ["/s", "/t", "5"], { windowsHide: true });
|
|
34269
|
+
void flushAccounts(true).finally(() => spawnSync6(SYSTEM.shutdown(), ["/s", "/t", "5"], { windowsHide: true }));
|
|
32881
34270
|
}, GRACE_MS);
|
|
32882
34271
|
}
|
|
32883
34272
|
idle() {
|
|
@@ -32889,11 +34278,11 @@ var IdleShutdown = class {
|
|
|
32889
34278
|
var CLOSE_WAIT_MS = 8e3;
|
|
32890
34279
|
var ROOTS_KEPT_MS = 10 * 60 * 1e3;
|
|
32891
34280
|
function terminalTab(id, title, cwd) {
|
|
32892
|
-
const view = [process.execPath,
|
|
32893
|
-
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");
|
|
32894
34283
|
if (exists(wt))
|
|
32895
|
-
|
|
32896
|
-
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();
|
|
32897
34286
|
}
|
|
32898
34287
|
var harnessFor = (req) => {
|
|
32899
34288
|
if (req.harness === session.harnessName && session.harness) return session.harness;
|
|
@@ -32906,8 +34295,8 @@ var harnessFor = (req) => {
|
|
|
32906
34295
|
function memoryEnv(env, sessions2) {
|
|
32907
34296
|
const out = {};
|
|
32908
34297
|
out.PTYHOST_BACKSTOP_MB = String(session.agentBackstop ?? "auto");
|
|
32909
|
-
const cpus = usableCpus(
|
|
32910
|
-
const memoryGb =
|
|
34298
|
+
const cpus = usableCpus(os13.cpus().length, session.cpuLimitPercent ?? null);
|
|
34299
|
+
const memoryGb = os13.totalmem() / 1024 ** 3;
|
|
32911
34300
|
const jobs = cargoJobs(cpus, memoryGb, sessions2);
|
|
32912
34301
|
out.NUMBER_OF_PROCESSORS = String(cpus);
|
|
32913
34302
|
if (!env.CARGO_BUILD_JOBS) out.CARGO_BUILD_JOBS = String(jobs);
|
|
@@ -32946,10 +34335,10 @@ var agentProgram = async (req, env, say) => {
|
|
|
32946
34335
|
};
|
|
32947
34336
|
function shellPaths() {
|
|
32948
34337
|
const candidates = [
|
|
32949
|
-
|
|
32950
|
-
|
|
34338
|
+
path80.join(pwshDir(), "pwsh.exe"),
|
|
34339
|
+
path80.join(process.env.ProgramFiles ?? "C:\\Program Files", "PowerShell", "7", "pwsh.exe")
|
|
32951
34340
|
];
|
|
32952
|
-
return { pwsh: candidates.find((f) =>
|
|
34341
|
+
return { pwsh: candidates.find((f) => fs63.existsSync(f)) ?? null, powershell: SYSTEM.powershell(), cmd: SYSTEM.cmd() };
|
|
32953
34342
|
}
|
|
32954
34343
|
var shellProgram = (shell) => {
|
|
32955
34344
|
const line = commandLine(shell.file, shell.args);
|
|
@@ -32957,7 +34346,7 @@ var shellProgram = (shell) => {
|
|
|
32957
34346
|
};
|
|
32958
34347
|
var launchPtyHost = async (req, program, remote, env, sessions2, onSpawn) => {
|
|
32959
34348
|
const port = await freePort();
|
|
32960
|
-
const token =
|
|
34349
|
+
const token = crypto5.randomBytes(24).toString("base64url");
|
|
32961
34350
|
const sessionEnv = {
|
|
32962
34351
|
...withRegistryPath(env),
|
|
32963
34352
|
...program.environment,
|
|
@@ -32983,7 +34372,7 @@ var launchPtyHost = async (req, program, remote, env, sessions2, onSpawn) => {
|
|
|
32983
34372
|
} catch (e) {
|
|
32984
34373
|
const tail = ptyHostLogTail(req.id);
|
|
32985
34374
|
throw new Error(
|
|
32986
|
-
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")
|
|
32987
34376
|
);
|
|
32988
34377
|
}
|
|
32989
34378
|
return { child, port, token };
|
|
@@ -33097,7 +34486,7 @@ var SessionManager = class {
|
|
|
33097
34486
|
};
|
|
33098
34487
|
this.starting++;
|
|
33099
34488
|
if (req.id !== session.launchId && process.env.AGENT_NO_TABS !== "1")
|
|
33100
|
-
safely("terminal tab", () => terminalTab(req.id, name + " " +
|
|
34489
|
+
safely("terminal tab", () => terminalTab(req.id, name + " " + path80.basename(req.cwd), req.cwd));
|
|
33101
34490
|
try {
|
|
33102
34491
|
if (problem) throw new Error(problem);
|
|
33103
34492
|
const place = await placeFor(req, say);
|
|
@@ -33259,6 +34648,7 @@ var SessionManager = class {
|
|
|
33259
34648
|
else safely("post-agent hooks", () => runHooks("post-agent", process.env));
|
|
33260
34649
|
safely("claude-mem save", saveClaudeMem);
|
|
33261
34650
|
safely("agent databases save", saveLocalState);
|
|
34651
|
+
void flushAccounts();
|
|
33262
34652
|
this.idle.check();
|
|
33263
34653
|
}
|
|
33264
34654
|
};
|
|
@@ -33591,10 +34981,10 @@ var GovernorCore = class {
|
|
|
33591
34981
|
};
|
|
33592
34982
|
|
|
33593
34983
|
// src/guest/governor/governor.ts
|
|
33594
|
-
import
|
|
33595
|
-
import
|
|
33596
|
-
import
|
|
33597
|
-
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";
|
|
33598
34988
|
import { createInterface } from "node:readline";
|
|
33599
34989
|
var SampleSchema = external_exports.object({
|
|
33600
34990
|
ramTotalMb: external_exports.number(),
|
|
@@ -33618,7 +35008,7 @@ var MemGovProcess = class {
|
|
|
33618
35008
|
child = null;
|
|
33619
35009
|
start() {
|
|
33620
35010
|
try {
|
|
33621
|
-
const child =
|
|
35011
|
+
const child = spawn9(ensureCompiled("memgov"), ["serve", "--interval", "2"], {
|
|
33622
35012
|
stdio: ["pipe", "pipe", "ignore"],
|
|
33623
35013
|
windowsHide: true
|
|
33624
35014
|
});
|
|
@@ -33663,12 +35053,12 @@ var MemGovProcess = class {
|
|
|
33663
35053
|
};
|
|
33664
35054
|
function appendToMemoryLog(line) {
|
|
33665
35055
|
try {
|
|
33666
|
-
const logs =
|
|
33667
|
-
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();
|
|
33668
35058
|
if (!newest) return;
|
|
33669
35059
|
const t = /* @__PURE__ */ new Date();
|
|
33670
35060
|
const stamp = [t.getHours(), t.getMinutes(), t.getSeconds()].map((n) => String(n).padStart(2, "0")).join(":");
|
|
33671
|
-
|
|
35061
|
+
fs64.appendFileSync(path81.join(logs, newest), stamp + " | " + line + "\r\n");
|
|
33672
35062
|
} catch {
|
|
33673
35063
|
}
|
|
33674
35064
|
}
|
|
@@ -33686,7 +35076,7 @@ var Governor = class {
|
|
|
33686
35076
|
this.core = new GovernorCore({
|
|
33687
35077
|
port: proc,
|
|
33688
35078
|
profile,
|
|
33689
|
-
maxCompilers: maxCompilers(
|
|
35079
|
+
maxCompilers: maxCompilers(os14.cpus().length, profile),
|
|
33690
35080
|
now: () => Date.now(),
|
|
33691
35081
|
logLine: appendToMemoryLog,
|
|
33692
35082
|
warn,
|
|
@@ -33708,16 +35098,16 @@ var Governor = class {
|
|
|
33708
35098
|
var governor = new Governor();
|
|
33709
35099
|
|
|
33710
35100
|
// src/guest/daemon/live.ts
|
|
33711
|
-
import
|
|
33712
|
-
import
|
|
35101
|
+
import fs66 from "node:fs";
|
|
35102
|
+
import path83 from "node:path";
|
|
33713
35103
|
import { spawnSync as spawnSync7 } from "node:child_process";
|
|
33714
35104
|
|
|
33715
35105
|
// src/guest/daemon/live-folders.ts
|
|
33716
|
-
import
|
|
33717
|
-
import
|
|
35106
|
+
import fs65 from "node:fs";
|
|
35107
|
+
import path82 from "node:path";
|
|
33718
35108
|
|
|
33719
35109
|
// src/shared/channel/live.ts
|
|
33720
|
-
import
|
|
35110
|
+
import crypto6 from "node:crypto";
|
|
33721
35111
|
var LIVE_SHARE_NAME = /^agentsbx-[0-9a-f]{8,32}$/;
|
|
33722
35112
|
var LIVE_FOLDER_NAME = /^[a-z0-9][a-z0-9_-]{0,63}$/;
|
|
33723
35113
|
var LIVE_KEY = /^[0-9a-f]{64}$/;
|
|
@@ -33747,7 +35137,7 @@ var LiveReplySchema = external_exports.strictObject({
|
|
|
33747
35137
|
finishedAt: external_exports.string().max(64)
|
|
33748
35138
|
});
|
|
33749
35139
|
function mac3(key2, payload) {
|
|
33750
|
-
return
|
|
35140
|
+
return crypto6.createHmac("sha256", Buffer.from(key2, "hex")).update(payload, "utf8").digest("hex");
|
|
33751
35141
|
}
|
|
33752
35142
|
function openLive(key2, envelope, o) {
|
|
33753
35143
|
if (!key2 || !LIVE_KEY.test(key2))
|
|
@@ -33756,7 +35146,7 @@ function openLive(key2, envelope, o) {
|
|
|
33756
35146
|
if (!env.success) return { refused: "not a live-folder request" };
|
|
33757
35147
|
const want = Buffer.from(mac3(key2, env.data.payload), "hex");
|
|
33758
35148
|
const got = Buffer.from(env.data.mac, "hex");
|
|
33759
|
-
if (want.length !== got.length || !
|
|
35149
|
+
if (want.length !== got.length || !crypto6.timingSafeEqual(want, got))
|
|
33760
35150
|
return { refused: "the signature does not match" };
|
|
33761
35151
|
let json2;
|
|
33762
35152
|
try {
|
|
@@ -33807,7 +35197,7 @@ var LiveFolderHandler = class {
|
|
|
33807
35197
|
}
|
|
33808
35198
|
read() {
|
|
33809
35199
|
try {
|
|
33810
|
-
const text =
|
|
35200
|
+
const text = fs65.readFileSync(this.o.stateFile, "utf8");
|
|
33811
35201
|
const parsed = StateSchema.safeParse(JSON.parse(text));
|
|
33812
35202
|
if (parsed.success && parsed.data.launchId === this.o.launchId) return parsed.data;
|
|
33813
35203
|
} catch {
|
|
@@ -33815,7 +35205,7 @@ var LiveFolderHandler = class {
|
|
|
33815
35205
|
return { key: null, launchId: this.o.launchId, seen: [], mappings: [] };
|
|
33816
35206
|
}
|
|
33817
35207
|
save(state) {
|
|
33818
|
-
|
|
35208
|
+
fs65.mkdirSync(path82.dirname(this.o.stateFile), { recursive: true });
|
|
33819
35209
|
writeJsonAtomic(this.o.stateFile, state);
|
|
33820
35210
|
}
|
|
33821
35211
|
/** The key the boot handed over (from the one-shot secrets file). */
|
|
@@ -33826,30 +35216,30 @@ var LiveFolderHandler = class {
|
|
|
33826
35216
|
/** C:\Workspace\<name> from a checked name only. */
|
|
33827
35217
|
folderPath(name) {
|
|
33828
35218
|
if (!LIVE_FOLDER_NAME.test(name)) throw new Error("not a plain folder name");
|
|
33829
|
-
return
|
|
35219
|
+
return path82.win32.join(this.o.workspaces ?? WORKSPACES_GUEST, name);
|
|
33830
35220
|
}
|
|
33831
35221
|
/** One pass over run\live: every file is claimed (deleted) at once; valid ones are handled one after another. */
|
|
33832
35222
|
tick() {
|
|
33833
35223
|
const dir = this.o.run.liveDir;
|
|
33834
35224
|
let names;
|
|
33835
35225
|
try {
|
|
33836
|
-
names =
|
|
35226
|
+
names = fs65.readdirSync(dir);
|
|
33837
35227
|
} catch {
|
|
33838
35228
|
return;
|
|
33839
35229
|
}
|
|
33840
35230
|
for (const name of names.slice(0, 64)) {
|
|
33841
35231
|
if (name.endsWith(".tmp")) continue;
|
|
33842
|
-
const file3 =
|
|
35232
|
+
const file3 = path82.join(dir, name);
|
|
33843
35233
|
let envelope = null;
|
|
33844
35234
|
try {
|
|
33845
|
-
const stat =
|
|
35235
|
+
const stat = fs65.lstatSync(file3);
|
|
33846
35236
|
if (stat.isFile() && stat.size <= MAX_REQUEST_BYTES && /^[A-Za-z0-9_-]{1,64}\.json$/.test(name))
|
|
33847
|
-
envelope = JSON.parse(
|
|
35237
|
+
envelope = JSON.parse(fs65.readFileSync(file3, "utf8"));
|
|
33848
35238
|
} catch {
|
|
33849
35239
|
envelope = null;
|
|
33850
35240
|
} finally {
|
|
33851
35241
|
try {
|
|
33852
|
-
|
|
35242
|
+
fs65.rmSync(file3, { recursive: true, force: true });
|
|
33853
35243
|
} catch {
|
|
33854
35244
|
}
|
|
33855
35245
|
}
|
|
@@ -33886,18 +35276,18 @@ var LiveFolderHandler = class {
|
|
|
33886
35276
|
}
|
|
33887
35277
|
reply(id, r) {
|
|
33888
35278
|
try {
|
|
33889
|
-
|
|
35279
|
+
fs65.mkdirSync(this.o.run.liveRepliesDir, { recursive: true });
|
|
33890
35280
|
writeJsonAtomic(this.o.run.liveReplyFile(id), { id, ...r, finishedAt: new Date(this.now()).toISOString() });
|
|
33891
35281
|
} catch (e) {
|
|
33892
35282
|
this.log("live folder reply not written: " + errMsg(e));
|
|
33893
35283
|
}
|
|
33894
35284
|
}
|
|
33895
35285
|
/** map with retries while the share is not there yet. */
|
|
33896
|
-
async mapWithRetry(folder,
|
|
35286
|
+
async mapWithRetry(folder, share2, readOnly) {
|
|
33897
35287
|
const tries = this.o.tries ?? 20;
|
|
33898
35288
|
let code = EXIT_NO_SHARE;
|
|
33899
35289
|
for (let i = 0; i < tries; i++) {
|
|
33900
|
-
code = this.o.bind.map(folder,
|
|
35290
|
+
code = this.o.bind.map(folder, share2, readOnly);
|
|
33901
35291
|
if (code !== EXIT_NO_SHARE) return code;
|
|
33902
35292
|
await (this.o.sleep ?? wait)(500);
|
|
33903
35293
|
}
|
|
@@ -33907,14 +35297,14 @@ var LiveFolderHandler = class {
|
|
|
33907
35297
|
assertFree(folder) {
|
|
33908
35298
|
let exists2 = true;
|
|
33909
35299
|
try {
|
|
33910
|
-
|
|
35300
|
+
fs65.lstatSync(folder);
|
|
33911
35301
|
} catch {
|
|
33912
35302
|
exists2 = false;
|
|
33913
35303
|
}
|
|
33914
35304
|
if (exists2) throw new Error(folder + " exists already");
|
|
33915
|
-
const parent =
|
|
33916
|
-
|
|
33917
|
-
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");
|
|
33918
35308
|
}
|
|
33919
35309
|
async act(p) {
|
|
33920
35310
|
const folder = this.folderPath(p.folder);
|
|
@@ -33929,21 +35319,21 @@ var LiveFolderHandler = class {
|
|
|
33929
35319
|
this.save({ ...after, mappings: after.mappings.filter((m) => m.folder !== p.folder) });
|
|
33930
35320
|
return { ok: true, message: "hidden: " + folder };
|
|
33931
35321
|
}
|
|
33932
|
-
const
|
|
35322
|
+
const share2 = p.share ?? "";
|
|
33933
35323
|
this.assertFree(folder);
|
|
33934
35324
|
if (p.kind === "canary") {
|
|
33935
|
-
const code2 = await this.mapWithRetry(folder,
|
|
35325
|
+
const code2 = await this.mapWithRetry(folder, share2, true);
|
|
33936
35326
|
if (code2 !== EXIT_OK) return { ok: false, message: "the test share could not be shown (" + code2 + ")" };
|
|
33937
35327
|
try {
|
|
33938
|
-
const file3 =
|
|
33939
|
-
const stat =
|
|
33940
|
-
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() : "";
|
|
33941
35331
|
return LIVE_TOKEN.test(token) ? { ok: true, message: "read the test share", token } : { ok: false, message: "the test share holds no token" };
|
|
33942
35332
|
} finally {
|
|
33943
35333
|
this.o.bind.unmap(folder);
|
|
33944
35334
|
}
|
|
33945
35335
|
}
|
|
33946
|
-
const code = await this.mapWithRetry(folder,
|
|
35336
|
+
const code = await this.mapWithRetry(folder, share2, p.readOnly);
|
|
33947
35337
|
if (code !== EXIT_OK)
|
|
33948
35338
|
return {
|
|
33949
35339
|
ok: false,
|
|
@@ -33954,7 +35344,7 @@ var LiveFolderHandler = class {
|
|
|
33954
35344
|
...state,
|
|
33955
35345
|
mappings: [
|
|
33956
35346
|
...state.mappings.filter((m) => m.folder !== p.folder),
|
|
33957
|
-
{ folder: p.folder, share, readOnly: p.readOnly }
|
|
35347
|
+
{ folder: p.folder, share: share2, readOnly: p.readOnly }
|
|
33958
35348
|
]
|
|
33959
35349
|
});
|
|
33960
35350
|
return { ok: true, message: "shown at " + folder };
|
|
@@ -33965,7 +35355,7 @@ var LiveFolderHandler = class {
|
|
|
33965
35355
|
for (const m of this.read().mappings) {
|
|
33966
35356
|
const folder = this.folderPath(m.folder);
|
|
33967
35357
|
if (this.o.bind.mapped(folder) === EXIT_OK) continue;
|
|
33968
|
-
|
|
35358
|
+
fs65.mkdirSync(path82.dirname(folder), { recursive: true });
|
|
33969
35359
|
if (this.o.bind.map(folder, m.share, m.readOnly) === EXIT_OK) done++;
|
|
33970
35360
|
else this.log("live folder " + folder + " could not be shown again");
|
|
33971
35361
|
}
|
|
@@ -33976,7 +35366,7 @@ var LiveFolderHandler = class {
|
|
|
33976
35366
|
// src/guest/daemon/live.ts
|
|
33977
35367
|
var BIND_TIMEOUT_MS = 3e4;
|
|
33978
35368
|
var testing = Boolean(process.env.AGENT_DAEMON_STATE_DIR || process.env.AGENT_LOCAL_DIR);
|
|
33979
|
-
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"));
|
|
33980
35370
|
function bindMount(args) {
|
|
33981
35371
|
const r = spawnSync7(ensureCompiled("bindmount"), args, {
|
|
33982
35372
|
windowsHide: true,
|
|
@@ -33986,12 +35376,12 @@ function bindMount(args) {
|
|
|
33986
35376
|
return r.status ?? 1;
|
|
33987
35377
|
}
|
|
33988
35378
|
var realBind = {
|
|
33989
|
-
map: (folder,
|
|
35379
|
+
map: (folder, share2, readOnly) => bindMount(["map", folder, share2, ...readOnly ? [] : ["rw"]]),
|
|
33990
35380
|
unmap: (folder) => bindMount(["unmap", folder]),
|
|
33991
35381
|
mapped: (folder) => bindMount(["mapped", folder])
|
|
33992
35382
|
};
|
|
33993
35383
|
function protectStateDir() {
|
|
33994
|
-
|
|
35384
|
+
fs66.mkdirSync(stateDir2, { recursive: true });
|
|
33995
35385
|
if (!isWin || testMode || testing) return;
|
|
33996
35386
|
spawnSync7(
|
|
33997
35387
|
SYSTEM.icacls(),
|
|
@@ -34004,7 +35394,7 @@ function protectStateDir() {
|
|
|
34004
35394
|
}
|
|
34005
35395
|
var liveFolders = new LiveFolderHandler({
|
|
34006
35396
|
run,
|
|
34007
|
-
stateFile:
|
|
35397
|
+
stateFile: path83.join(stateDir2, "live-folders.json"),
|
|
34008
35398
|
launchId: session.launchId,
|
|
34009
35399
|
bind: realBind,
|
|
34010
35400
|
log: warn
|
|
@@ -34034,9 +35424,9 @@ var Daemon = class {
|
|
|
34034
35424
|
tick() {
|
|
34035
35425
|
const { valid, invalid } = run.scanRequests();
|
|
34036
35426
|
for (const file3 of invalid)
|
|
34037
|
-
safely("removing an invalid request", () =>
|
|
35427
|
+
safely("removing an invalid request", () => fs67.rmSync(file3, { recursive: true, force: true }));
|
|
34038
35428
|
for (const req of valid) {
|
|
34039
|
-
safely("claiming a request", () =>
|
|
35429
|
+
safely("claiming a request", () => fs67.rmSync(run.requestFile(req.id), { force: true }));
|
|
34040
35430
|
if (run.readSession(req.id)) continue;
|
|
34041
35431
|
void Promise.resolve(this.handle(withRequestSecrets(req))).catch(
|
|
34042
35432
|
(e) => respond(req.id, { ok: false, message: errMsg(e) })
|
|
@@ -34047,6 +35437,7 @@ var Daemon = class {
|
|
|
34047
35437
|
this.lastMemSave = Date.now();
|
|
34048
35438
|
safely("claude-mem save", saveClaudeMem);
|
|
34049
35439
|
safely("agent databases save", saveLocalState);
|
|
35440
|
+
void flushAccounts();
|
|
34050
35441
|
}
|
|
34051
35442
|
}
|
|
34052
35443
|
handle(req) {
|
|
@@ -34080,4 +35471,5 @@ safely("audit", () => startProcessCollector(() => sessions.roots()));
|
|
|
34080
35471
|
safely("leftover processes", () => sessions.sweepLeftovers());
|
|
34081
35472
|
safely("memory governor", () => governor.start());
|
|
34082
35473
|
log("Memory governor: " + governor.describe());
|
|
35474
|
+
safely("service sign-ins", startAccountWatch);
|
|
34083
35475
|
new Daemon().start();
|