windows-development-sandbox 1.27.1 → 1.28.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/dist/app/context.d.ts +5 -0
- package/dist/app/context.js +13 -0
- package/dist/app/features/accounts/accounts.def.d.ts +16 -0
- package/dist/app/features/accounts/accounts.run.d.ts +4 -0
- package/dist/app/features/accounts/services.def.d.ts +15 -1
- package/dist/app/features/accounts/services.def.js +67 -31
- package/dist/app/features/accounts/services.run.d.ts +7 -2
- package/dist/app/features/accounts/services.run.js +25 -6
- package/dist/app/features/defs.d.ts +17 -0
- package/dist/app/registry.d.ts +1 -1
- package/dist/app/registry.js +15 -2
- package/dist/bin/agent-sandbox.js +2 -2
- package/dist/bin/{chunk-RSIX7C6D.js → chunk-CB44HTTN.js} +444 -175
- package/dist/bin/{chunk-4TLSWPG7.js → chunk-UZ5S3EMB.js} +1 -1
- package/dist/bin/{chunk-QUHNXHVG.js → chunk-ZMZI3625.js} +46 -41
- 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/menu/menu.js +6 -1
- package/dist/cli/menu/pages/accounts-page.js +9 -5
- package/dist/core/schema/sandbox.js +1 -1
- package/dist/guest/apps/app-installer.js +7 -5
- package/dist/guest/apps/comet-unpack.js +2 -2
- package/dist/guest/daemon/heartbeat.js +1 -0
- package/dist/guest/governor/core.d.ts +53 -1
- package/dist/guest/governor/core.js +95 -1
- package/dist/guest/governor/decide.d.ts +4 -0
- package/dist/guest/governor/decide.js +2 -0
- package/dist/guest/governor/governor.js +23 -9
- package/dist/guest/runtime/pools.d.ts +4 -4
- package/dist/guest/runtime/pools.js +4 -15
- package/dist/guest/runtime/process.d.ts +5 -2
- package/dist/guest/runtime/process.js +23 -3
- package/dist/guest/toolchains/engines/epic-launcher.d.ts +6 -0
- package/dist/guest/toolchains/engines/epic-launcher.js +19 -1
- package/dist/guest/toolchains/engines/unreal-engines.js +2 -1
- package/dist/guest/toolchains/installers.d.ts +3 -3
- package/dist/guest/toolchains/installers.js +5 -5
- package/dist/guest/toolchains/native/unreal.js +22 -3
- package/dist/guest/toolchains/native/vcruntime.js +2 -2
- package/dist/guest/toolchains/native/vs-persist.d.ts +2 -2
- package/dist/guest/toolchains/runtimes.js +7 -6
- package/dist/guest/toolchains/signature.d.ts +2 -0
- package/dist/guest/toolchains/signature.js +9 -2
- package/dist/guest/toolchains/step-scheduler.js +1 -1
- package/dist/host/accounts/deliver.js +15 -7
- package/dist/host/life/crash-report.d.ts +4 -0
- package/dist/host/life/crash-report.js +30 -1
- package/dist/host/life/last-end.js +1 -0
- package/dist/host/pc-installs/discover.js +5 -2
- package/dist/host/pc-installs/unreal.d.ts +3 -1
- package/dist/host/pc-installs/unreal.js +27 -1
- package/dist/host/tools/windows-terminal.d.ts +4 -1
- package/dist/host/tools/windows-terminal.js +25 -9
- package/dist/runtime/agent.js +39 -23
- package/dist/runtime/daemon.js +279 -121
- package/dist/runtime/db.js +37 -17
- package/dist/runtime/main.js +340 -109
- package/dist/runtime/netproxy.js +31 -13
- package/dist/runtime/tool.js +37 -16
- package/dist/runtime/view.js +150 -38
- package/dist/selftest/agent-paths.test.js +3 -1
- package/dist/selftest/app.test.js +20 -2
- package/dist/selftest/boot-runner.test.js +15 -1
- package/dist/selftest/channel.test.js +33 -0
- package/dist/selftest/engines.test.js +22 -1
- package/dist/selftest/heavy-load.test.js +116 -4
- package/dist/selftest/live-terminal.test.js +103 -0
- package/dist/selftest/menu-screens.js +52 -1
- package/dist/selftest/menu.test.js +29 -3
- package/dist/selftest/personalization.test.js +2 -1
- package/dist/selftest/service-accounts.test.js +77 -2
- package/dist/selftest/support/engine-golden.js +2 -0
- package/dist/selftest/ui-text.test.js +4 -0
- package/dist/shared/accounts/kinds.js +9 -9
- package/dist/shared/apps/catalogue-gamedev.js +1 -0
- package/dist/shared/apps/catalogue.d.ts +2 -0
- package/dist/shared/channel/schema.d.ts +2 -0
- package/dist/shared/channel/schema.js +4 -0
- package/dist/shared/concurrency/pools.js +1 -1
- package/dist/shared/download/archive.js +4 -2
- package/dist/shared/download/index.d.ts +1 -1
- package/dist/shared/download/index.js +1 -1
- package/dist/shared/download/spawn.d.ts +7 -1
- package/dist/shared/download/spawn.js +16 -1
- package/dist/shared/memory/index.d.ts +1 -0
- package/dist/shared/memory/index.js +1 -0
- package/dist/shared/memory/policy.d.ts +12 -0
- package/dist/shared/memory/policy.js +4 -0
- package/dist/shared/memory/unreal-build.d.ts +2 -0
- package/dist/shared/memory/unreal-build.js +21 -0
- package/dist/shared/paths/pc-installs.d.ts +8 -0
- package/dist/shared/pty/clipboard-watch.d.ts +4 -0
- package/dist/shared/pty/clipboard-watch.js +40 -0
- package/dist/shared/pty/ctrl-c.d.ts +13 -7
- package/dist/shared/pty/ctrl-c.js +35 -19
- package/dist/shared/pty/index.d.ts +1 -0
- package/dist/shared/pty/index.js +1 -0
- package/dist/shared/pty/terminal.d.ts +1 -1
- package/dist/shared/pty/terminal.js +16 -13
- package/dist/shared/unreal/launcher-files.d.ts +7 -0
- package/dist/shared/unreal/launcher-files.js +32 -1
- package/dist/shared/web/ctrl-c.d.ts +26 -0
- package/dist/shared/web/ctrl-c.js +64 -0
- package/dist/shared/web/index.d.ts +1 -0
- package/dist/shared/web/index.js +1 -0
- package/dist/web/index.html +1 -1
- package/dist/web/{main-VPMYTSUL.js → main-7NY4X6YU.js} +67 -67
- 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/csharp/ClipboardWatch.cs +59 -0
- package/sandbox/csharp/MemGov.cs +752 -7
- package/sandbox/scripts/watch-clipboard.ps1 +8 -0
- package/schemas/config.schema.json +10 -10
- package/schemas/sandbox-config.schema.json +9 -9
package/dist/runtime/daemon.js
CHANGED
|
@@ -25521,7 +25521,7 @@ var SandboxSchema = external_exports.strictObject({
|
|
|
25521
25521
|
'The last resort that keeps the sandbox up, in MB below its commit limit (RAM plus paging file): builds are slowed down long before (sandbox.pressureResponse); only if everything the agents start together would take the sandbox to the very edge of its memory, where Windows inside it would start failing, is a build refused memory instead of Windows. "auto" = the larger of 1536 MB and 3 % of the commit limit; "none" = no backstop. Yours only: a project file cannot change it.'
|
|
25522
25522
|
),
|
|
25523
25523
|
pressureResponse: external_exports.boolean().describe(
|
|
25524
|
-
"When the sandbox (or this PC) runs low on memory, slow builds down in steps, like a PC that gets slower instead of failing: build programs get lower CPU and memory priority, then less CPU, then compilers take turns (the waiting ones briefly suspended and trimmed to the paging file). Nothing is stopped or killed, and the agents themselves are never touched. Yours only: a project file cannot change it."
|
|
25524
|
+
"When the sandbox (or this PC) runs low on memory, slow builds down in steps, like a PC that gets slower instead of failing: build programs get lower CPU and memory priority, then less CPU, then compilers take turns (the waiting ones briefly suspended and trimmed to the paging file). Nothing is stopped or killed, and the agents themselves are never touched. A memory gate also holds new compilers and linkers for a moment when the memory of the build programs grows faster than 4 GB in 3 seconds (3 GB with vGPU), and lets them go one at a time. Yours only: a project file cannot change it."
|
|
25525
25525
|
),
|
|
25526
25526
|
vGpu: external_exports.boolean().describe(
|
|
25527
25527
|
"Virtual GPU. Off by default: Microsoft notes it widens the sandbox attack surface. The sandbox then uses this PC's graphics card, and with some graphics drivers heavy use can freeze the whole PC: turn it on only when a program in the sandbox needs the GPU (the mesa toolchain gives software OpenGL without it). Browsers in the sandbox never use it (they draw in software)."
|
|
@@ -26113,6 +26113,7 @@ var GAMEDEV_APPS = [
|
|
|
26113
26113
|
size: "100 MB",
|
|
26114
26114
|
source: { github: "f3d-app/f3d", asset: "^F3D-[\\d.]+-Windows-x86_64\\.zip$" },
|
|
26115
26115
|
exe: "f3d.exe",
|
|
26116
|
+
onPath: true,
|
|
26116
26117
|
needs: ["mesa"]
|
|
26117
26118
|
},
|
|
26118
26119
|
{
|
|
@@ -27413,7 +27414,7 @@ var SERVICE_SPECS = {
|
|
|
27413
27414
|
},
|
|
27414
27415
|
steam: {
|
|
27415
27416
|
kind: "steam",
|
|
27416
|
-
label: "Steam
|
|
27417
|
+
label: "Steam",
|
|
27417
27418
|
usedBy: ["steam"],
|
|
27418
27419
|
sources: ["file", "sandbox"],
|
|
27419
27420
|
singleHolder: true,
|
|
@@ -27449,7 +27450,7 @@ var SERVICE_SPECS = {
|
|
|
27449
27450
|
},
|
|
27450
27451
|
cfx: {
|
|
27451
27452
|
kind: "cfx",
|
|
27452
|
-
label: "
|
|
27453
|
+
label: "FiveM key",
|
|
27453
27454
|
usedBy: ["fivem"],
|
|
27454
27455
|
sources: ["typed", "file"],
|
|
27455
27456
|
singleHolder: false,
|
|
@@ -27478,7 +27479,7 @@ var SERVICE_SPECS = {
|
|
|
27478
27479
|
},
|
|
27479
27480
|
keystore: {
|
|
27480
27481
|
kind: "keystore",
|
|
27481
|
-
label: "Android
|
|
27482
|
+
label: "Android keystore",
|
|
27482
27483
|
usedBy: ["android"],
|
|
27483
27484
|
sources: ["file"],
|
|
27484
27485
|
singleHolder: false,
|
|
@@ -27493,7 +27494,7 @@ var SERVICE_SPECS = {
|
|
|
27493
27494
|
},
|
|
27494
27495
|
play: {
|
|
27495
27496
|
kind: "play",
|
|
27496
|
-
label: "Google Play
|
|
27497
|
+
label: "Google Play",
|
|
27497
27498
|
usedBy: ["android"],
|
|
27498
27499
|
sources: ["file"],
|
|
27499
27500
|
singleHolder: false,
|
|
@@ -27504,7 +27505,7 @@ var SERVICE_SPECS = {
|
|
|
27504
27505
|
},
|
|
27505
27506
|
expo: {
|
|
27506
27507
|
kind: "expo",
|
|
27507
|
-
label: "Expo
|
|
27508
|
+
label: "Expo",
|
|
27508
27509
|
usedBy: ["reactNative"],
|
|
27509
27510
|
sources: ["typed"],
|
|
27510
27511
|
singleHolder: false,
|
|
@@ -27515,7 +27516,7 @@ var SERVICE_SPECS = {
|
|
|
27515
27516
|
},
|
|
27516
27517
|
appstore: {
|
|
27517
27518
|
kind: "appstore",
|
|
27518
|
-
label: "App Store Connect
|
|
27519
|
+
label: "App Store Connect",
|
|
27519
27520
|
usedBy: ["reactNative", "flutter"],
|
|
27520
27521
|
sources: ["file", "typed"],
|
|
27521
27522
|
singleHolder: false,
|
|
@@ -27529,7 +27530,7 @@ var SERVICE_SPECS = {
|
|
|
27529
27530
|
},
|
|
27530
27531
|
perplexity: {
|
|
27531
27532
|
kind: "perplexity",
|
|
27532
|
-
label: "Perplexity API
|
|
27533
|
+
label: "Perplexity API",
|
|
27533
27534
|
usedBy: ["perplexity"],
|
|
27534
27535
|
sources: ["pc", "file", "typed"],
|
|
27535
27536
|
singleHolder: false,
|
|
@@ -27553,7 +27554,7 @@ var SERVICE_SPECS = {
|
|
|
27553
27554
|
},
|
|
27554
27555
|
comet: {
|
|
27555
27556
|
kind: "comet",
|
|
27556
|
-
label: "Comet
|
|
27557
|
+
label: "Comet",
|
|
27557
27558
|
usedBy: ["comet"],
|
|
27558
27559
|
sources: ["sandbox"],
|
|
27559
27560
|
singleHolder: false,
|
|
@@ -27569,7 +27570,7 @@ var SERVICE_SPECS = {
|
|
|
27569
27570
|
},
|
|
27570
27571
|
perplexityapp: {
|
|
27571
27572
|
kind: "perplexityapp",
|
|
27572
|
-
label: "Perplexity
|
|
27573
|
+
label: "Perplexity app",
|
|
27573
27574
|
usedBy: ["perplexityapp"],
|
|
27574
27575
|
sources: ["sandbox"],
|
|
27575
27576
|
singleHolder: false,
|
|
@@ -27921,6 +27922,8 @@ var PressureStatusSchema = external_exports.object({
|
|
|
27921
27922
|
lowered: external_exports.number().int().min(0).max(1024),
|
|
27922
27923
|
/** Compilers waiting their turn right now (name, process id, seconds until they may go on). */
|
|
27923
27924
|
paused: external_exports.array(external_exports.object({ name: Text(64), pid: external_exports.number().int(), seconds: external_exports.number().int().min(0).max(60) })).max(8),
|
|
27925
|
+
/** Build programs the memory gate holds right now (let go one at a time). */
|
|
27926
|
+
held: external_exports.number().int().min(0).max(1024).optional(),
|
|
27924
27927
|
/** The CPU share the compilers get together (percent; 100 = no cap). */
|
|
27925
27928
|
cpuPercent: external_exports.number().int().min(0).max(100).optional(),
|
|
27926
27929
|
/** The PC itself asked for slowing down (its memory or CPU is low). */
|
|
@@ -27941,6 +27944,8 @@ var HeartbeatSchema = external_exports.object({
|
|
|
27941
27944
|
topProcesses: external_exports.array(external_exports.object({ name: Text(64), privateMb: external_exports.number().int().min(0).max(1e7) })).max(5),
|
|
27942
27945
|
/** The disk queue this PC last reported while asking the sandbox to slow down. */
|
|
27943
27946
|
diskQueueReported: external_exports.number().min(0).max(1e5).optional(),
|
|
27947
|
+
/** Build programs the memory gate holds right now (let go one at a time). */
|
|
27948
|
+
held: external_exports.number().int().min(0).max(1024).optional(),
|
|
27944
27949
|
/** "ending": the sandbox is shutting down in order (idle shutdown, sandbox stop, Windows shutting down). */
|
|
27945
27950
|
phase: external_exports.enum(["ready", "working", "ending"])
|
|
27946
27951
|
});
|
|
@@ -28531,10 +28536,20 @@ function scriptArgs(name, args = []) {
|
|
|
28531
28536
|
}
|
|
28532
28537
|
|
|
28533
28538
|
// src/shared/download/spawn.ts
|
|
28539
|
+
import os3 from "node:os";
|
|
28534
28540
|
import { spawn } from "node:child_process";
|
|
28541
|
+
function lowerPriority(pid) {
|
|
28542
|
+
if (pid === void 0) return;
|
|
28543
|
+
try {
|
|
28544
|
+
os3.setPriority(pid, os3.constants.priority.PRIORITY_BELOW_NORMAL);
|
|
28545
|
+
} catch {
|
|
28546
|
+
}
|
|
28547
|
+
}
|
|
28535
28548
|
function spawnAsync(file3, args, options = {}) {
|
|
28549
|
+
const { lowPriority, ...spawnOptions } = options;
|
|
28536
28550
|
return new Promise((resolve2, reject) => {
|
|
28537
|
-
const child = spawn(file3, args, { stdio: "ignore", windowsHide: true, ...
|
|
28551
|
+
const child = spawn(file3, args, { stdio: "ignore", windowsHide: true, ...spawnOptions });
|
|
28552
|
+
if (lowPriority) lowerPriority(child.pid);
|
|
28538
28553
|
child.once("error", reject);
|
|
28539
28554
|
child.once("close", (code) => resolve2(code ?? -1));
|
|
28540
28555
|
});
|
|
@@ -28558,13 +28573,16 @@ function extractArchive(archive, destination, members2 = []) {
|
|
|
28558
28573
|
}
|
|
28559
28574
|
async function extract(archive, destination, members2) {
|
|
28560
28575
|
fs10.mkdirSync(destination, { recursive: true });
|
|
28561
|
-
let status = await spawnAsync(SYSTEM.tar(), ["-xf", archive, "-C", destination, ...members2]
|
|
28576
|
+
let status = await spawnAsync(SYSTEM.tar(), ["-xf", archive, "-C", destination, ...members2], {
|
|
28577
|
+
lowPriority: true
|
|
28578
|
+
});
|
|
28562
28579
|
if (status !== 0 && /\.(zip|nupkg)$/i.test(archive)) {
|
|
28563
28580
|
const zip = archive.endsWith(".zip") ? archive : archive + ".zip";
|
|
28564
28581
|
if (zip !== archive) fs10.copyFileSync(archive, zip);
|
|
28565
28582
|
status = await spawnAsync(
|
|
28566
28583
|
SYSTEM.powershell(),
|
|
28567
|
-
scriptArgs("expand-archive.ps1", ["-Archive", zip, "-Destination", destination])
|
|
28584
|
+
scriptArgs("expand-archive.ps1", ["-Archive", zip, "-Destination", destination]),
|
|
28585
|
+
{ lowPriority: true }
|
|
28568
28586
|
);
|
|
28569
28587
|
}
|
|
28570
28588
|
if (status !== 0) throw new Error("Could not extract " + archive);
|
|
@@ -29160,7 +29178,6 @@ function withRequestSecrets(req) {
|
|
|
29160
29178
|
}
|
|
29161
29179
|
|
|
29162
29180
|
// src/guest/runtime/pools.ts
|
|
29163
|
-
import os4 from "node:os";
|
|
29164
29181
|
import { spawn as spawn3 } from "node:child_process";
|
|
29165
29182
|
import path21 from "node:path";
|
|
29166
29183
|
|
|
@@ -29234,13 +29251,13 @@ function installerRetry(code, attempt) {
|
|
|
29234
29251
|
}
|
|
29235
29252
|
|
|
29236
29253
|
// src/shared/concurrency/pools.ts
|
|
29237
|
-
var net2 = new Limiter(
|
|
29254
|
+
var net2 = new Limiter(3, "net");
|
|
29238
29255
|
var heavy = new Limiter(2, "heavy");
|
|
29239
29256
|
var installer = new Limiter(1, "installer");
|
|
29240
29257
|
|
|
29241
29258
|
// src/guest/runtime/process.ts
|
|
29242
29259
|
import fs16 from "node:fs";
|
|
29243
|
-
import
|
|
29260
|
+
import os4 from "node:os";
|
|
29244
29261
|
import path20 from "node:path";
|
|
29245
29262
|
import { spawn as spawn2, spawnSync as spawnSync2 } from "node:child_process";
|
|
29246
29263
|
var outputSink = null;
|
|
@@ -29262,13 +29279,15 @@ function logLines(stream) {
|
|
|
29262
29279
|
stream.on("end", () => logOutput(partial2));
|
|
29263
29280
|
}
|
|
29264
29281
|
async function execAsync(file3, args, options = {}) {
|
|
29282
|
+
const { lowPriority, ...spawnOptions } = options;
|
|
29265
29283
|
const code = captureOutput() ? await new Promise((resolve2, reject) => {
|
|
29266
|
-
const child = spawn2(file3, args, { stdio: ["inherit", "pipe", "pipe"], windowsHide: true, ...
|
|
29284
|
+
const child = spawn2(file3, args, { stdio: ["inherit", "pipe", "pipe"], windowsHide: true, ...spawnOptions });
|
|
29285
|
+
if (lowPriority) lowerPriority(child.pid);
|
|
29267
29286
|
logLines(child.stdout);
|
|
29268
29287
|
logLines(child.stderr);
|
|
29269
29288
|
child.once("error", reject);
|
|
29270
29289
|
child.once("close", (c) => resolve2(c ?? -1));
|
|
29271
|
-
}) : await spawnAsync(file3, args, { stdio: "inherit", ...
|
|
29290
|
+
}) : await spawnAsync(file3, args, { stdio: "inherit", ...spawnOptions, ...lowPriority ? { lowPriority } : {} });
|
|
29272
29291
|
if (code !== 0)
|
|
29273
29292
|
throw new Error(path20.basename(file3) + " " + args.slice(0, 3).join(" ") + " failed with exit code " + code);
|
|
29274
29293
|
}
|
|
@@ -29322,8 +29341,23 @@ function runScriptAsync(name, args = []) {
|
|
|
29322
29341
|
function scriptOutput(name, args = [], options = {}) {
|
|
29323
29342
|
return execOutput(SYSTEM.powershell(), scriptArgs(name, args), options);
|
|
29324
29343
|
}
|
|
29344
|
+
function scriptOutputAsync(name, args = []) {
|
|
29345
|
+
return new Promise((resolve2) => {
|
|
29346
|
+
const child = spawn2(SYSTEM.powershell(), scriptArgs(name, args), {
|
|
29347
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
29348
|
+
windowsHide: true
|
|
29349
|
+
});
|
|
29350
|
+
let out = "";
|
|
29351
|
+
child.stdout?.setEncoding("utf8");
|
|
29352
|
+
child.stdout?.on("data", (chunk) => {
|
|
29353
|
+
if (out.length < CAPTURE_BYTES) out += chunk;
|
|
29354
|
+
});
|
|
29355
|
+
child.once("error", () => resolve2(""));
|
|
29356
|
+
child.once("close", (code) => resolve2(code === 0 ? out.trim() : ""));
|
|
29357
|
+
});
|
|
29358
|
+
}
|
|
29325
29359
|
function runScriptWithJson(name, param, data, args = []) {
|
|
29326
|
-
const dir = fs16.mkdtempSync(path20.join(
|
|
29360
|
+
const dir = fs16.mkdtempSync(path20.join(os4.tmpdir(), "sbx-"));
|
|
29327
29361
|
const file3 = path20.join(dir, "input.json");
|
|
29328
29362
|
try {
|
|
29329
29363
|
fs16.writeFileSync(file3, JSON.stringify(data), "utf8");
|
|
@@ -29333,7 +29367,7 @@ function runScriptWithJson(name, param, data, args = []) {
|
|
|
29333
29367
|
}
|
|
29334
29368
|
}
|
|
29335
29369
|
async function runScriptWithJsonAsync(name, param, data, args = []) {
|
|
29336
|
-
const dir = fs16.mkdtempSync(path20.join(
|
|
29370
|
+
const dir = fs16.mkdtempSync(path20.join(os4.tmpdir(), "sbx-"));
|
|
29337
29371
|
const file3 = path20.join(dir, "input.json");
|
|
29338
29372
|
try {
|
|
29339
29373
|
fs16.writeFileSync(file3, JSON.stringify(data), "utf8");
|
|
@@ -29404,14 +29438,7 @@ function installPools() {
|
|
|
29404
29438
|
downloader.limit = net2;
|
|
29405
29439
|
limitExtraction(heavy);
|
|
29406
29440
|
}
|
|
29407
|
-
var
|
|
29408
|
-
function belowNormal(pid) {
|
|
29409
|
-
if (pid === void 0) return;
|
|
29410
|
-
try {
|
|
29411
|
-
os4.setPriority(pid, BELOW_NORMAL);
|
|
29412
|
-
} catch {
|
|
29413
|
-
}
|
|
29414
|
-
}
|
|
29441
|
+
var belowNormal = lowerPriority;
|
|
29415
29442
|
async function runInstaller(file3, args, o = {}) {
|
|
29416
29443
|
for (let attempt = 1; ; attempt++) {
|
|
29417
29444
|
const code = await installer.run(
|
|
@@ -29437,7 +29464,7 @@ async function runInstallerChecked(file3, args, o = {}) {
|
|
|
29437
29464
|
throw new Error(path21.basename(file3) + " " + args.slice(0, 3).join(" ") + " failed with exit code " + code);
|
|
29438
29465
|
}
|
|
29439
29466
|
function execHeavy(file3, args, options = {}) {
|
|
29440
|
-
return heavy.run(() => execAsync(file3, args, options));
|
|
29467
|
+
return heavy.run(() => execAsync(file3, args, { ...options, lowPriority: true }));
|
|
29441
29468
|
}
|
|
29442
29469
|
|
|
29443
29470
|
// src/guest/daemon/daemon.ts
|
|
@@ -30361,13 +30388,14 @@ function itemSizes(saved2) {
|
|
|
30361
30388
|
}
|
|
30362
30389
|
return sizes;
|
|
30363
30390
|
}
|
|
30391
|
+
var ITEM_NAME = /^[A-Za-z0-9_-]{1,80}\.item$/;
|
|
30364
30392
|
function isItemUnder(text2, root) {
|
|
30365
30393
|
const at = itemInstallLocation(text2);
|
|
30366
30394
|
return at !== null && isWithin2(root, at) && win2.resolve(at) !== win2.resolve(root);
|
|
30367
30395
|
}
|
|
30368
30396
|
function itemFiles(dir) {
|
|
30369
30397
|
try {
|
|
30370
|
-
return fs22.readdirSync(dir).filter((f) =>
|
|
30398
|
+
return fs22.readdirSync(dir).filter((f) => ITEM_NAME.test(f));
|
|
30371
30399
|
} catch {
|
|
30372
30400
|
return [];
|
|
30373
30401
|
}
|
|
@@ -31525,7 +31553,10 @@ import path42 from "node:path";
|
|
|
31525
31553
|
// src/guest/toolchains/signature.ts
|
|
31526
31554
|
var SignatureSchema = external_exports.object({ subject: external_exports.string().max(4096), issuer: external_exports.string().max(4096) });
|
|
31527
31555
|
function signatureOf(file3) {
|
|
31528
|
-
|
|
31556
|
+
return parseSignature(scriptOutput("get-signature.ps1", ["-Path", file3]));
|
|
31557
|
+
}
|
|
31558
|
+
function parseSignature(output2) {
|
|
31559
|
+
const text2 = output2.trim();
|
|
31529
31560
|
if (!text2) return null;
|
|
31530
31561
|
try {
|
|
31531
31562
|
const parsed = SignatureSchema.safeParse(JSON.parse(text2));
|
|
@@ -31537,11 +31568,14 @@ function signatureOf(file3) {
|
|
|
31537
31568
|
function signedBy(file3, signer) {
|
|
31538
31569
|
return signerMatches(signatureOf(file3), signer);
|
|
31539
31570
|
}
|
|
31571
|
+
async function signedByAsync(file3, signer) {
|
|
31572
|
+
return signerMatches(parseSignature(await scriptOutputAsync("get-signature.ps1", ["-Path", file3])), signer);
|
|
31573
|
+
}
|
|
31540
31574
|
|
|
31541
31575
|
// src/guest/toolchains/installers.ts
|
|
31542
31576
|
function signatureCheck(signer, what) {
|
|
31543
|
-
return (file3) => {
|
|
31544
|
-
if (!
|
|
31577
|
+
return async (file3) => {
|
|
31578
|
+
if (!await signedByAsync(file3, signer)) throw new Error(what + " is not signed by its vendor");
|
|
31545
31579
|
};
|
|
31546
31580
|
}
|
|
31547
31581
|
async function signedInstaller(url2, file3, what, signer, sha256 = null) {
|
|
@@ -31550,7 +31584,7 @@ async function signedInstaller(url2, file3, what, signer, sha256 = null) {
|
|
|
31550
31584
|
mkdirp(path42.dirname(file3));
|
|
31551
31585
|
await downloader.file(url2, file3, { sha256, verify: signatureCheck(signer, path42.basename(file3)) });
|
|
31552
31586
|
}
|
|
31553
|
-
if (!
|
|
31587
|
+
if (!await signedByAsync(file3, signer)) {
|
|
31554
31588
|
fs25.rmSync(file3, { force: true });
|
|
31555
31589
|
throw new Error(
|
|
31556
31590
|
path42.basename(file3) + " is not signed by its vendor; deleted it (it is downloaded again next boot)"
|
|
@@ -31658,6 +31692,18 @@ function savedEntries() {
|
|
|
31658
31692
|
function restoreLauncherItems() {
|
|
31659
31693
|
return restoreItems(SAVED_MANIFESTS, launcherManifestsDir(programData()), ENGINES_DIR, exists);
|
|
31660
31694
|
}
|
|
31695
|
+
function writePcLauncherItems(items) {
|
|
31696
|
+
const dir = launcherManifestsDir(programData());
|
|
31697
|
+
let written = 0;
|
|
31698
|
+
for (const i of items) {
|
|
31699
|
+
if (i.kind !== "unreal" || !i.launcherItem || !ITEM_NAME.test(i.launcherItem.name)) continue;
|
|
31700
|
+
const at = itemInstallLocation(i.launcherItem.text);
|
|
31701
|
+
if (!at || path44.win32.resolve(at).toLowerCase() !== path44.win32.resolve(i.guest).toLowerCase()) continue;
|
|
31702
|
+
fs26.writeFileSync(path44.join(mkdirp(dir), i.launcherItem.name), i.launcherItem.text, "utf8");
|
|
31703
|
+
written++;
|
|
31704
|
+
}
|
|
31705
|
+
return written;
|
|
31706
|
+
}
|
|
31661
31707
|
function writeLauncherEntries(entries2) {
|
|
31662
31708
|
if (!entries2.length) return;
|
|
31663
31709
|
const file3 = launcherInstalledFile(programData());
|
|
@@ -31741,6 +31787,7 @@ async function registerEngines(engines, selectorFrom, ctx, aliases = []) {
|
|
|
31741
31787
|
];
|
|
31742
31788
|
if (values.length) await runScriptWithJsonAsync("set-registry-values.ps1", "PlanFile", { values });
|
|
31743
31789
|
try {
|
|
31790
|
+
writePcLauncherItems(ctx.pcInstalls.items);
|
|
31744
31791
|
writeLauncherEntries(launcherEntries(engines, ctx));
|
|
31745
31792
|
} catch (e) {
|
|
31746
31793
|
warn("Unreal: the Epic Games Launcher's LauncherInstalled.dat was left as it is (" + errMsg(e) + ")");
|
|
@@ -32066,11 +32113,10 @@ async function setupBun(env) {
|
|
|
32066
32113
|
tool("bun", "bin"),
|
|
32067
32114
|
{ size: "35 MB" }
|
|
32068
32115
|
);
|
|
32069
|
-
|
|
32070
|
-
|
|
32071
|
-
|
|
32072
|
-
|
|
32073
|
-
});
|
|
32116
|
+
const cache = path48.join(localDir, "bun-cache");
|
|
32117
|
+
const temp = path48.join(localDir, "bun-tmp");
|
|
32118
|
+
if (!dryRun) [cache, temp].forEach((dir) => mkdirp(dir));
|
|
32119
|
+
Object.assign(env.vars, { BUN_INSTALL: tool("bun"), BUN_INSTALL_CACHE_DIR: cache, BUN_TMPDIR: temp });
|
|
32074
32120
|
}
|
|
32075
32121
|
async function setupDeno(env) {
|
|
32076
32122
|
await setupSingleExe(
|
|
@@ -32621,7 +32667,7 @@ async function installFromKept(dest, signer, what) {
|
|
|
32621
32667
|
if (!installer2) return null;
|
|
32622
32668
|
const installed = installedCometExe();
|
|
32623
32669
|
if (fs35.existsSync(installed)) return installed;
|
|
32624
|
-
if (!
|
|
32670
|
+
if (!await signedByAsync(installer2, signer)) {
|
|
32625
32671
|
fs35.rmSync(path54.join(dest, ".agent-sandbox-app"), { force: true });
|
|
32626
32672
|
fs35.rmSync(installer2, { force: true });
|
|
32627
32673
|
throw new Error(what + "'s installer is not signed by its vendor; deleted it (it is downloaded again next boot)");
|
|
@@ -32923,7 +32969,7 @@ var MARKER = ".agent-sandbox-app";
|
|
|
32923
32969
|
function prefetchedFile(entry, fileName) {
|
|
32924
32970
|
return path58.join(tool("apps", ...entry.id.split("/")) + ".download", fileName.replace(/[\\/:*?"<>|]/g, "_"));
|
|
32925
32971
|
}
|
|
32926
|
-
var PARALLEL =
|
|
32972
|
+
var PARALLEL = 2;
|
|
32927
32973
|
var AppInstaller = class {
|
|
32928
32974
|
constructor(env, options, parallel = PARALLEL) {
|
|
32929
32975
|
this.env = env;
|
|
@@ -32944,19 +32990,21 @@ var AppInstaller = class {
|
|
|
32944
32990
|
const todo = entries2.filter(
|
|
32945
32991
|
(e) => !("remote" in e.source) && !("locked" in e.source) && !("store" in e.source) && !("npm" in e.source) && e.id !== "7zip" && (this.options.refresh || !exists(path58.join(tool("apps", ...e.id.split("/")), MARKER)))
|
|
32946
32992
|
);
|
|
32947
|
-
await
|
|
32948
|
-
|
|
32949
|
-
|
|
32950
|
-
|
|
32951
|
-
|
|
32952
|
-
|
|
32953
|
-
|
|
32954
|
-
|
|
32955
|
-
|
|
32956
|
-
|
|
32957
|
-
|
|
32958
|
-
|
|
32959
|
-
|
|
32993
|
+
await asBackground(
|
|
32994
|
+
() => Promise.all(
|
|
32995
|
+
todo.map(async (entry) => {
|
|
32996
|
+
try {
|
|
32997
|
+
const d = await resolve(entry);
|
|
32998
|
+
const file3 = prefetchedFile(entry, d.fileName);
|
|
32999
|
+
if (exists(file3)) return;
|
|
33000
|
+
await downloader.file(d.url, file3, {
|
|
33001
|
+
sha256: d.sha256 ?? null,
|
|
33002
|
+
...entry.signer ? { verify: signatureCheck(entry.signer, d.fileName) } : {}
|
|
33003
|
+
});
|
|
33004
|
+
} catch {
|
|
33005
|
+
}
|
|
33006
|
+
})
|
|
33007
|
+
)
|
|
32960
33008
|
);
|
|
32961
33009
|
}
|
|
32962
33010
|
/** Installs the entries (7-Zip first: the NSIS apps need it to unpack), then their shortcuts. */
|
|
@@ -33013,7 +33061,7 @@ var AppInstaller = class {
|
|
|
33013
33061
|
const exe = findExe(dest, entry.exe) ?? (entry.unpack === "chromium" && entry.signer ? await installFromKept(dest, entry.signer, entry.name) : null);
|
|
33014
33062
|
if (!exe) throw new Error(entry.exe + " not found in the download");
|
|
33015
33063
|
await afterInstall(entry, exe);
|
|
33016
|
-
if (!entry.service && (entry.cli || entry.id === "sysinternals")) {
|
|
33064
|
+
if (!entry.service && (entry.cli || entry.onPath || entry.id === "sysinternals")) {
|
|
33017
33065
|
if (entry.id === "rust-analyzer") this.env.prepend.unshift(path58.dirname(exe));
|
|
33018
33066
|
else this.env.prepend.push(path58.dirname(exe));
|
|
33019
33067
|
}
|
|
@@ -34909,6 +34957,82 @@ import fs58 from "node:fs";
|
|
|
34909
34957
|
import os10 from "node:os";
|
|
34910
34958
|
import path83 from "node:path";
|
|
34911
34959
|
|
|
34960
|
+
// src/shared/memory/policy.ts
|
|
34961
|
+
var DIAL_STEPS = {
|
|
34962
|
+
normal: [
|
|
34963
|
+
{ availablePercent: 15, commitPercent: 80 },
|
|
34964
|
+
{ availablePercent: 10, commitPercent: 88 },
|
|
34965
|
+
{ availablePercent: 6, commitPercent: 94, secondsToLimit: 20 },
|
|
34966
|
+
{ availablePercent: 4, commitPercent: 97, secondsToLimit: 8 }
|
|
34967
|
+
],
|
|
34968
|
+
gentle: [
|
|
34969
|
+
{ availablePercent: 20, commitPercent: 75 },
|
|
34970
|
+
{ availablePercent: 15, commitPercent: 85 },
|
|
34971
|
+
{ availablePercent: 8, commitPercent: 92, secondsToLimit: 25 },
|
|
34972
|
+
{ availablePercent: 5, commitPercent: 96, secondsToLimit: 10 }
|
|
34973
|
+
]
|
|
34974
|
+
};
|
|
34975
|
+
var DIAL_EXIT_MARGIN = { availablePercent: 5, commitPercent: 4 };
|
|
34976
|
+
var DIAL_CALM_SAMPLES = 3;
|
|
34977
|
+
var DIAL_CPU_RATE = [100, 100, 60, 35, 15];
|
|
34978
|
+
function compilersAllowed(step, running) {
|
|
34979
|
+
if (step <= 1 || running <= 1) return running;
|
|
34980
|
+
if (step === 2) return Math.max(1, Math.ceil(running * 0.6));
|
|
34981
|
+
if (step === 3) return Math.max(1, Math.ceil(running / 3));
|
|
34982
|
+
return 1;
|
|
34983
|
+
}
|
|
34984
|
+
function buildJobs(cpus, memoryGb) {
|
|
34985
|
+
return Math.max(2, Math.min(cpus, Math.floor((memoryGb - 6) / 3)));
|
|
34986
|
+
}
|
|
34987
|
+
function linkSlotsFor(memoryGb) {
|
|
34988
|
+
return Math.max(2, Math.min(8, Math.floor((memoryGb - 6) / 3)));
|
|
34989
|
+
}
|
|
34990
|
+
function usableCpus(cpus, percent) {
|
|
34991
|
+
if (percent === null || percent >= 100) return cpus;
|
|
34992
|
+
return Math.max(2, Math.min(cpus, Math.floor(cpus * percent / 100)));
|
|
34993
|
+
}
|
|
34994
|
+
function cargoJobs(cpus, memoryGb, sessions2) {
|
|
34995
|
+
const byCpu = Math.max(2, Math.min(8, Math.floor(cpus / 4)));
|
|
34996
|
+
const byMemory = Math.max(1, Math.floor(memoryGb / 4));
|
|
34997
|
+
const jobs = Math.min(byCpu, byMemory);
|
|
34998
|
+
return Math.max(1, Math.min(jobs, Math.floor(buildJobs(cpus, memoryGb) / Math.max(1, sessions2))));
|
|
34999
|
+
}
|
|
35000
|
+
var LOCAL_TARGET_MIN_BYTES = 25 * 1024 ** 3;
|
|
35001
|
+
function chooseTargetDir(targetDir, freeBytes2) {
|
|
35002
|
+
if (targetDir !== "auto") return { targetDir };
|
|
35003
|
+
if (freeBytes2 >= LOCAL_TARGET_MIN_BYTES) return { targetDir: "local" };
|
|
35004
|
+
return {
|
|
35005
|
+
targetDir: "separate",
|
|
35006
|
+
warning: "Rust builds write through the mapped workspace; this can overload your PC's disk (C: has less than 25 GB free for a local build folder)"
|
|
35007
|
+
};
|
|
35008
|
+
}
|
|
35009
|
+
function maxCompilers(cpus, profile) {
|
|
35010
|
+
return profile === "gentle" ? Math.min(4, Math.max(2, Math.floor(cpus / 4))) : null;
|
|
35011
|
+
}
|
|
35012
|
+
function cargoLinkerVar(host) {
|
|
35013
|
+
return "CARGO_TARGET_" + host.toUpperCase().replace(/[^A-Z0-9]/g, "_") + "_LINKER";
|
|
35014
|
+
}
|
|
35015
|
+
var BURST_GATE = {
|
|
35016
|
+
normal: { growthMb: 4096, windowMs: 3e3, releaseMs: 1500, maxHoldMs: 3e4 },
|
|
35017
|
+
gentle: { growthMb: 3072, windowMs: 3e3, releaseMs: 2e3, maxHoldMs: 3e4 }
|
|
35018
|
+
};
|
|
35019
|
+
|
|
35020
|
+
// src/shared/memory/unreal-build.ts
|
|
35021
|
+
var NAMESPACE = "https://www.unrealengine.com/BuildConfiguration";
|
|
35022
|
+
function ubtBuildConfiguration(jobs) {
|
|
35023
|
+
const max = Math.max(1, Math.floor(jobs));
|
|
35024
|
+
return [
|
|
35025
|
+
'<?xml version="1.0" encoding="utf-8"?>',
|
|
35026
|
+
"<!-- Written by the sandbox at boot: compiles at once from the build budget (run\\budget.json, buildJobs). -->",
|
|
35027
|
+
'<Configuration xmlns="' + NAMESPACE + '">',
|
|
35028
|
+
" <BuildConfiguration>",
|
|
35029
|
+
" <MaxParallelActions>" + max + "</MaxParallelActions>",
|
|
35030
|
+
" </BuildConfiguration>",
|
|
35031
|
+
"</Configuration>",
|
|
35032
|
+
""
|
|
35033
|
+
].join("\r\n");
|
|
35034
|
+
}
|
|
35035
|
+
|
|
34912
35036
|
// src/guest/toolchains/native/debuggers.ts
|
|
34913
35037
|
import path79 from "node:path";
|
|
34914
35038
|
var SDK_SETUP_URL = "https://go.microsoft.com/fwlink/?linkid=2311806";
|
|
@@ -35686,6 +35810,14 @@ async function checkVisualStudio() {
|
|
|
35686
35810
|
fs58.rmSync(dir, { recursive: true, force: true });
|
|
35687
35811
|
}
|
|
35688
35812
|
}
|
|
35813
|
+
function capUnrealBuilds() {
|
|
35814
|
+
const cpus = usableCpus(os10.cpus().length, session.cpuLimitPercent ?? null);
|
|
35815
|
+
const jobs = buildJobs(cpus, os10.totalmem() / 1024 ** 3);
|
|
35816
|
+
const appData = process.env.APPDATA ?? "C:\\Users\\WDAGUtilityAccount\\AppData\\Roaming";
|
|
35817
|
+
const dir = mkdirp(path83.join(appData, "Unreal Engine", "UnrealBuildTool"));
|
|
35818
|
+
fs58.writeFileSync(path83.join(dir, "BuildConfiguration.xml"), ubtBuildConfiguration(jobs), "utf8");
|
|
35819
|
+
return jobs;
|
|
35820
|
+
}
|
|
35689
35821
|
async function part(what, work, fallback) {
|
|
35690
35822
|
try {
|
|
35691
35823
|
return await work();
|
|
@@ -35704,6 +35836,8 @@ async function setupUnreal(env, config2, _ctx) {
|
|
|
35704
35836
|
return;
|
|
35705
35837
|
}
|
|
35706
35838
|
resetUnrealStatus();
|
|
35839
|
+
const jobs = await part("capping parallel compiles", async () => capUnrealBuilds(), 0);
|
|
35840
|
+
if (jobs) log("Unreal: UnrealBuildTool runs at most " + jobs + " compiles at once (the build budget)");
|
|
35707
35841
|
await part("the DirectX End-User Runtime", installDirectX, void 0);
|
|
35708
35842
|
const launcher = await part("the Epic Games Launcher", ensureLauncher, null);
|
|
35709
35843
|
const place = placeEngines(config2.persistEngines);
|
|
@@ -35739,7 +35873,7 @@ async function setupUnreal(env, config2, _ctx) {
|
|
|
35739
35873
|
debugger: debuggers ? path83.join(debuggers, "cdb.exe") : null
|
|
35740
35874
|
}));
|
|
35741
35875
|
env.summary.push(
|
|
35742
|
-
"unreal tools: " + (vs ? "Visual Studio " + vs.version + (check2.ok ? " (UnrealBuildTool finds it)" : " (UnrealBuildTool would NOT find it)") : "no Visual Studio") + ", DirectX End-User Runtime" + (launcher ? ", Epic Games Launcher" : "") + (debuggers ? ", cdb/windbg" : "")
|
|
35876
|
+
"unreal tools: " + (vs ? "Visual Studio " + vs.version + (check2.ok ? " (UnrealBuildTool finds it)" : " (UnrealBuildTool would NOT find it)") : "no Visual Studio") + (jobs ? ", at most " + jobs + " compiles at once" : "") + ", DirectX End-User Runtime" + (launcher ? ", Epic Games Launcher" : "") + (debuggers ? ", cdb/windbg" : "")
|
|
35743
35877
|
);
|
|
35744
35878
|
}
|
|
35745
35879
|
|
|
@@ -36168,7 +36302,7 @@ async function setupVcRuntime(env, summary = true) {
|
|
|
36168
36302
|
log("Downloading the Visual C++ runtime (~25 MB once) ...");
|
|
36169
36303
|
await downloadFile(VC_REDIST, installer2);
|
|
36170
36304
|
}
|
|
36171
|
-
if (!
|
|
36305
|
+
if (!await signedByAsync(installer2, SIGNERS.microsoft)) {
|
|
36172
36306
|
fs62.rmSync(installer2, { force: true });
|
|
36173
36307
|
throw new Error("vc_redist.x64.exe is not signed by Microsoft; deleted it (it is downloaded again next boot)");
|
|
36174
36308
|
}
|
|
@@ -37586,62 +37720,6 @@ import fs72 from "node:fs";
|
|
|
37586
37720
|
import os12 from "node:os";
|
|
37587
37721
|
import path104 from "node:path";
|
|
37588
37722
|
|
|
37589
|
-
// src/shared/memory/policy.ts
|
|
37590
|
-
var DIAL_STEPS = {
|
|
37591
|
-
normal: [
|
|
37592
|
-
{ availablePercent: 15, commitPercent: 80 },
|
|
37593
|
-
{ availablePercent: 10, commitPercent: 88 },
|
|
37594
|
-
{ availablePercent: 6, commitPercent: 94, secondsToLimit: 20 },
|
|
37595
|
-
{ availablePercent: 4, commitPercent: 97, secondsToLimit: 8 }
|
|
37596
|
-
],
|
|
37597
|
-
gentle: [
|
|
37598
|
-
{ availablePercent: 20, commitPercent: 75 },
|
|
37599
|
-
{ availablePercent: 15, commitPercent: 85 },
|
|
37600
|
-
{ availablePercent: 8, commitPercent: 92, secondsToLimit: 25 },
|
|
37601
|
-
{ availablePercent: 5, commitPercent: 96, secondsToLimit: 10 }
|
|
37602
|
-
]
|
|
37603
|
-
};
|
|
37604
|
-
var DIAL_EXIT_MARGIN = { availablePercent: 5, commitPercent: 4 };
|
|
37605
|
-
var DIAL_CALM_SAMPLES = 3;
|
|
37606
|
-
var DIAL_CPU_RATE = [100, 100, 60, 35, 15];
|
|
37607
|
-
function compilersAllowed(step, running) {
|
|
37608
|
-
if (step <= 1 || running <= 1) return running;
|
|
37609
|
-
if (step === 2) return Math.max(1, Math.ceil(running * 0.6));
|
|
37610
|
-
if (step === 3) return Math.max(1, Math.ceil(running / 3));
|
|
37611
|
-
return 1;
|
|
37612
|
-
}
|
|
37613
|
-
function buildJobs(cpus, memoryGb) {
|
|
37614
|
-
return Math.max(2, Math.min(cpus, Math.floor((memoryGb - 6) / 3)));
|
|
37615
|
-
}
|
|
37616
|
-
function linkSlotsFor(memoryGb) {
|
|
37617
|
-
return Math.max(2, Math.min(8, Math.floor((memoryGb - 6) / 3)));
|
|
37618
|
-
}
|
|
37619
|
-
function usableCpus(cpus, percent) {
|
|
37620
|
-
if (percent === null || percent >= 100) return cpus;
|
|
37621
|
-
return Math.max(2, Math.min(cpus, Math.floor(cpus * percent / 100)));
|
|
37622
|
-
}
|
|
37623
|
-
function cargoJobs(cpus, memoryGb, sessions2) {
|
|
37624
|
-
const byCpu = Math.max(2, Math.min(8, Math.floor(cpus / 4)));
|
|
37625
|
-
const byMemory = Math.max(1, Math.floor(memoryGb / 4));
|
|
37626
|
-
const jobs = Math.min(byCpu, byMemory);
|
|
37627
|
-
return Math.max(1, Math.min(jobs, Math.floor(buildJobs(cpus, memoryGb) / Math.max(1, sessions2))));
|
|
37628
|
-
}
|
|
37629
|
-
var LOCAL_TARGET_MIN_BYTES = 25 * 1024 ** 3;
|
|
37630
|
-
function chooseTargetDir(targetDir, freeBytes2) {
|
|
37631
|
-
if (targetDir !== "auto") return { targetDir };
|
|
37632
|
-
if (freeBytes2 >= LOCAL_TARGET_MIN_BYTES) return { targetDir: "local" };
|
|
37633
|
-
return {
|
|
37634
|
-
targetDir: "separate",
|
|
37635
|
-
warning: "Rust builds write through the mapped workspace; this can overload your PC's disk (C: has less than 25 GB free for a local build folder)"
|
|
37636
|
-
};
|
|
37637
|
-
}
|
|
37638
|
-
function maxCompilers(cpus, profile) {
|
|
37639
|
-
return profile === "gentle" ? Math.min(4, Math.max(2, Math.floor(cpus / 4))) : null;
|
|
37640
|
-
}
|
|
37641
|
-
function cargoLinkerVar(host) {
|
|
37642
|
-
return "CARGO_TARGET_" + host.toUpperCase().replace(/[^A-Z0-9]/g, "_") + "_LINKER";
|
|
37643
|
-
}
|
|
37644
|
-
|
|
37645
37723
|
// src/guest/governor/decide.ts
|
|
37646
37724
|
var COMPILERS = /* @__PURE__ */ new Set([
|
|
37647
37725
|
"rustc",
|
|
@@ -37741,6 +37819,7 @@ function linkerSlots(totalMb, cpus) {
|
|
|
37741
37819
|
}
|
|
37742
37820
|
var isHeavyCompiler = (name) => !isNeverTouched(name) && HEAVY.has(key(name));
|
|
37743
37821
|
var canPause = (name) => !isNeverTouched(name) && COMPILERS.has(key(name));
|
|
37822
|
+
var GATE_NAMES = [...COMPILERS, "shadercompileworker"].filter((n) => !NEVER2.has(n)).sort();
|
|
37744
37823
|
var INITIAL_STATE = {
|
|
37745
37824
|
step: 0,
|
|
37746
37825
|
calm: 0,
|
|
@@ -38204,7 +38283,7 @@ function plan(config2, versions, o) {
|
|
|
38204
38283
|
|
|
38205
38284
|
// src/guest/toolchains/step-scheduler.ts
|
|
38206
38285
|
import { AsyncLocalStorage as AsyncLocalStorage4 } from "node:async_hooks";
|
|
38207
|
-
var PARALLEL2 =
|
|
38286
|
+
var PARALLEL2 = 3;
|
|
38208
38287
|
async function runReported(sink2, name, env, work) {
|
|
38209
38288
|
try {
|
|
38210
38289
|
await work();
|
|
@@ -38703,6 +38782,9 @@ async function sendControl(endpoint, type) {
|
|
|
38703
38782
|
// src/shared/pty/output-filter.ts
|
|
38704
38783
|
var MAX_CLIPBOARD_STRING = 1024 * 1024;
|
|
38705
38784
|
|
|
38785
|
+
// src/shared/web/protocol.ts
|
|
38786
|
+
var MAX_CLIENT_MESSAGE_BYTES = 256 * 1024;
|
|
38787
|
+
|
|
38706
38788
|
// src/guest/sessions/cmdline.ts
|
|
38707
38789
|
import path106 from "node:path";
|
|
38708
38790
|
var quoted = (arg) => '"' + arg.replace(/(\\*)"/g, '$1$1\\"').replace(/(\\+)$/, "$1$1") + '"';
|
|
@@ -39195,6 +39277,63 @@ async function flushAccounts(final = false) {
|
|
|
39195
39277
|
import os15 from "node:os";
|
|
39196
39278
|
|
|
39197
39279
|
// src/guest/governor/core.ts
|
|
39280
|
+
function memgovArgs(profile) {
|
|
39281
|
+
const g = BURST_GATE[profile];
|
|
39282
|
+
return [
|
|
39283
|
+
"serve",
|
|
39284
|
+
"--interval",
|
|
39285
|
+
"2",
|
|
39286
|
+
"--gate",
|
|
39287
|
+
[g.growthMb, g.windowMs, g.releaseMs, g.maxHoldMs].join(":"),
|
|
39288
|
+
"--gate-names",
|
|
39289
|
+
GATE_NAMES.join(",")
|
|
39290
|
+
];
|
|
39291
|
+
}
|
|
39292
|
+
var GateBase = { event: external_exports.literal("gate"), at: external_exports.number() };
|
|
39293
|
+
var GateName = external_exports.string().max(128);
|
|
39294
|
+
var GateCount = external_exports.number().int().min(0);
|
|
39295
|
+
var GateEventSchema = external_exports.discriminatedUnion("kind", [
|
|
39296
|
+
external_exports.strictObject({
|
|
39297
|
+
...GateBase,
|
|
39298
|
+
kind: external_exports.literal("ready"),
|
|
39299
|
+
mode: external_exports.enum(["notify", "poll"]),
|
|
39300
|
+
growthMb: GateCount,
|
|
39301
|
+
windowMs: GateCount
|
|
39302
|
+
}),
|
|
39303
|
+
external_exports.strictObject({ ...GateBase, kind: external_exports.literal("off"), reason: external_exports.string().max(200) }),
|
|
39304
|
+
external_exports.strictObject({
|
|
39305
|
+
...GateBase,
|
|
39306
|
+
kind: external_exports.literal("trip"),
|
|
39307
|
+
grewMb: GateCount,
|
|
39308
|
+
ms: GateCount,
|
|
39309
|
+
jobMb: GateCount,
|
|
39310
|
+
held: external_exports.array(external_exports.strictObject({ pid: external_exports.number().int(), name: GateName })).max(64)
|
|
39311
|
+
}),
|
|
39312
|
+
external_exports.strictObject({ ...GateBase, kind: external_exports.literal("hold"), pid: external_exports.number().int(), name: GateName }),
|
|
39313
|
+
external_exports.strictObject({
|
|
39314
|
+
...GateBase,
|
|
39315
|
+
kind: external_exports.literal("release"),
|
|
39316
|
+
pid: external_exports.number().int(),
|
|
39317
|
+
name: GateName,
|
|
39318
|
+
heldMs: GateCount,
|
|
39319
|
+
forced: external_exports.boolean()
|
|
39320
|
+
})
|
|
39321
|
+
]);
|
|
39322
|
+
function gateLine(e) {
|
|
39323
|
+
const cut = (s) => s.slice(0, 64);
|
|
39324
|
+
switch (e.kind) {
|
|
39325
|
+
case "ready":
|
|
39326
|
+
return "gate: on (" + e.mode + "): new compilers wait when the agents' programs grow by more than " + e.growthMb + " MB within " + e.windowMs / 1e3 + " s";
|
|
39327
|
+
case "off":
|
|
39328
|
+
return "gate: off (" + e.reason + "): builds are only slowed down by the dial";
|
|
39329
|
+
case "trip":
|
|
39330
|
+
return "gate: the agents' programs grew " + e.grewMb + " MB in " + (e.ms / 1e3).toFixed(1) + " s (now " + e.jobMb + " MB); holding " + e.held.length + ": " + e.held.slice(0, 8).map((p) => cut(p.name) + " (" + p.pid + ")").join(", ") + (e.held.length > 8 ? " \u2026" : "");
|
|
39331
|
+
case "hold":
|
|
39332
|
+
return "gate: " + cut(e.name) + " (" + e.pid + ") waits at start while a build burst goes through in turn";
|
|
39333
|
+
case "release":
|
|
39334
|
+
return "gate: " + cut(e.name) + " (" + e.pid + ") goes on after " + (e.heldMs / 1e3).toFixed(1) + " s" + (e.forced ? " (the longest it may wait)" : "");
|
|
39335
|
+
}
|
|
39336
|
+
}
|
|
39198
39337
|
var STEP_TEXT = [
|
|
39199
39338
|
"builds back to normal",
|
|
39200
39339
|
"build programs at lower priority",
|
|
@@ -39244,6 +39383,7 @@ var GovernorCore = class {
|
|
|
39244
39383
|
commitPercent: d.commitPercent,
|
|
39245
39384
|
step: d.state.step,
|
|
39246
39385
|
hostStep: nowMs < d.state.hostUntil ? d.state.hostStep : 0,
|
|
39386
|
+
held: sample.gateHeld ?? 0,
|
|
39247
39387
|
diskQueue: null,
|
|
39248
39388
|
top: [...sample.procs].sort((a, b) => b.mb - a.mb).slice(0, 5).map((p) => ({ name: p.name.slice(0, 64), mb: Math.round(p.mb) }))
|
|
39249
39389
|
};
|
|
@@ -39265,6 +39405,7 @@ var GovernorCore = class {
|
|
|
39265
39405
|
commitPercent: Math.max(0, Math.min(100, d.commitPercent)),
|
|
39266
39406
|
lowered: Object.keys(d.state.lowered).length,
|
|
39267
39407
|
paused: [...this.held].slice(0, 8).map(([pid, name]) => ({ name: name.slice(0, 64), pid, seconds: HOLD_MS / 1e3 })),
|
|
39408
|
+
held: sample.gateHeld ?? 0,
|
|
39268
39409
|
cpuPercent: d.state.cpuRate,
|
|
39269
39410
|
pcLow: nowMs < d.state.hostUntil,
|
|
39270
39411
|
lastAction: this.lastAction.slice(0, 300),
|
|
@@ -39277,6 +39418,10 @@ var GovernorCore = class {
|
|
|
39277
39418
|
this.deps.saveStatus(status);
|
|
39278
39419
|
}
|
|
39279
39420
|
}
|
|
39421
|
+
/** An event from the memory gate in memgov: goes to the memory log. */
|
|
39422
|
+
onGate(event) {
|
|
39423
|
+
this.note(gateLine(event));
|
|
39424
|
+
}
|
|
39280
39425
|
apply(action) {
|
|
39281
39426
|
const port = this.deps.port;
|
|
39282
39427
|
try {
|
|
@@ -39337,26 +39482,34 @@ var SampleSchema = external_exports.object({
|
|
|
39337
39482
|
mb: external_exports.number(),
|
|
39338
39483
|
prio: external_exports.enum(["idle", "below", "normal"]).catch("normal")
|
|
39339
39484
|
})
|
|
39340
|
-
).max(1024)
|
|
39485
|
+
).max(1024),
|
|
39486
|
+
gateHeld: external_exports.number().int().min(0).max(1024).optional().catch(void 0)
|
|
39341
39487
|
});
|
|
39342
39488
|
var MemGovProcess = class {
|
|
39343
|
-
constructor(onSample) {
|
|
39489
|
+
constructor(args, onSample, onGate) {
|
|
39490
|
+
this.args = args;
|
|
39344
39491
|
this.onSample = onSample;
|
|
39492
|
+
this.onGate = onGate;
|
|
39345
39493
|
}
|
|
39494
|
+
args;
|
|
39346
39495
|
onSample;
|
|
39496
|
+
onGate;
|
|
39347
39497
|
child = null;
|
|
39348
39498
|
start() {
|
|
39349
39499
|
try {
|
|
39350
|
-
const child = spawn12(ensureCompiled("memgov"), [
|
|
39500
|
+
const child = spawn12(ensureCompiled("memgov"), [...this.args], {
|
|
39351
39501
|
stdio: ["pipe", "pipe", "ignore"],
|
|
39352
39502
|
windowsHide: true
|
|
39353
39503
|
});
|
|
39354
39504
|
this.child = child;
|
|
39355
39505
|
createInterface({ input: child.stdout }).on("line", (line) => {
|
|
39356
39506
|
try {
|
|
39357
|
-
|
|
39507
|
+
const raw = JSON.parse(line);
|
|
39508
|
+
if (typeof raw === "object" && raw !== null && raw.event === "gate")
|
|
39509
|
+
this.onGate(GateEventSchema.parse(raw));
|
|
39510
|
+
else this.onSample(SampleSchema.parse(raw));
|
|
39358
39511
|
} catch (e) {
|
|
39359
|
-
warn("governor: bad
|
|
39512
|
+
warn("governor: bad line from memgov: " + errMsg(e));
|
|
39360
39513
|
}
|
|
39361
39514
|
});
|
|
39362
39515
|
child.stdin.on("error", () => void 0);
|
|
@@ -39409,12 +39562,16 @@ var Governor = class {
|
|
|
39409
39562
|
describe() {
|
|
39410
39563
|
const profile = session.loadProfile === "gentle" ? "gentle" : "normal";
|
|
39411
39564
|
const first = DIAL_STEPS[profile][0];
|
|
39412
|
-
return session.pressureResponse === false ? "off (sandbox.pressureResponse)" : profile + " profile: slows builds down from " + first.availablePercent + "% free RAM or " + first.commitPercent + "% commit, in steps";
|
|
39565
|
+
return session.pressureResponse === false ? "off (sandbox.pressureResponse)" : profile + " profile: slows builds down from " + first.availablePercent + "% free RAM or " + first.commitPercent + "% commit, in steps; holds new compilers when memory grows faster than " + BURST_GATE[profile].growthMb + " MB in " + BURST_GATE[profile].windowMs / 1e3 + " s";
|
|
39413
39566
|
}
|
|
39414
39567
|
start() {
|
|
39415
39568
|
if (session.pressureResponse === false) return;
|
|
39416
39569
|
const profile = session.loadProfile === "gentle" ? "gentle" : "normal";
|
|
39417
|
-
const proc = new MemGovProcess(
|
|
39570
|
+
const proc = new MemGovProcess(
|
|
39571
|
+
memgovArgs(profile),
|
|
39572
|
+
(s) => this.core?.onSample(s),
|
|
39573
|
+
(e) => this.core?.onGate(e)
|
|
39574
|
+
);
|
|
39418
39575
|
this.core = new GovernorCore({
|
|
39419
39576
|
port: proc,
|
|
39420
39577
|
profile,
|
|
@@ -39457,6 +39614,7 @@ function buildHeartbeat(snapshot2, sessionCount, uptimeSeconds, freeBytes2, tota
|
|
|
39457
39614
|
hostStep: clamp(snapshot2?.hostStep ?? 0, 0, 4),
|
|
39458
39615
|
topProcesses: (snapshot2?.top ?? []).slice(0, 5).map((p) => ({ name: p.name.slice(0, 64), privateMb: p.mb })),
|
|
39459
39616
|
...snapshot2?.diskQueue !== null && snapshot2?.diskQueue !== void 0 ? { diskQueueReported: snapshot2.diskQueue } : {},
|
|
39617
|
+
...snapshot2 && snapshot2.held > 0 ? { held: Math.min(1024, snapshot2.held) } : {},
|
|
39460
39618
|
phase: ending ? "ending" : sessionCount > 0 ? "working" : "ready"
|
|
39461
39619
|
};
|
|
39462
39620
|
}
|