windows-development-sandbox 1.28.0 → 1.29.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 +5 -4
- package/dist/app/features/sandbox/sandbox.run.js +1 -1
- package/dist/bin/{chunk-UZ5S3EMB.js → chunk-O4EL32TM.js} +1 -1
- package/dist/bin/{chunk-CB44HTTN.js → chunk-QYRRWGFY.js} +1442 -1280
- package/dist/bin/sandbox.js +10772 -3
- package/dist/cli/commands/launch/launch.js +1 -1
- package/dist/cli/commands/launch/running.js +2 -2
- package/dist/cli/index.js +1 -1
- package/dist/cli/menu/pages/agents-page.js +1 -1
- package/dist/cli/services/sandbox-service.js +1 -1
- package/dist/core/schema/sandbox.js +1 -1
- package/dist/guest/apps/app-installer.js +1 -1
- package/dist/guest/apps/store-check.d.ts +2 -0
- package/dist/guest/apps/store-check.js +3 -1
- package/dist/guest/boot/guide-lines.d.ts +2 -0
- package/dist/guest/boot/guide-lines.js +7 -0
- package/dist/guest/boot/guide.js +2 -1
- package/dist/guest/toolchains/native/unreal.js +3 -22
- package/dist/host/accounts/deliver.js +16 -2
- package/dist/host/apps/store-package.d.ts +2 -0
- package/dist/host/apps/store-package.js +16 -15
- package/dist/host/channel/attach.js +1 -1
- package/dist/host/channel/channel.js +3 -3
- package/dist/host/guard/commands.js +1 -0
- package/dist/host/health/path-copies.d.ts +1 -1
- package/dist/host/health/path-copies.js +2 -2
- package/dist/host/install/index.d.ts +1 -1
- package/dist/host/install/index.js +1 -1
- package/dist/host/install/shims.d.ts +8 -1
- package/dist/host/install/shims.js +39 -1
- package/dist/host/launch/generate.js +4 -0
- package/dist/host/launch/index.d.ts +1 -0
- package/dist/host/launch/index.js +1 -0
- package/dist/host/launch/pc-logs.d.ts +6 -0
- package/dist/host/launch/pc-logs.js +129 -0
- package/dist/host/sandbox/platform.js +1 -1
- package/dist/host/sandbox/window.js +1 -1
- package/dist/runtime/agent.js +1 -1
- package/dist/runtime/daemon.js +72 -90
- package/dist/runtime/db.js +1 -1
- package/dist/runtime/main.js +35 -57
- package/dist/runtime/netproxy.js +1 -1
- package/dist/runtime/tool.js +1 -1
- package/dist/runtime/view.js +1 -1
- package/dist/selftest/cli.test.js +5 -5
- package/dist/selftest/config.test.js +1 -1
- package/dist/selftest/credentials.test.js +1 -1
- package/dist/selftest/engine.test.js +1 -1
- package/dist/selftest/generate.test.js +66 -1
- package/dist/selftest/hcs.test.js +1 -1
- package/dist/selftest/health.test.js +21 -10
- package/dist/selftest/heavy-load.test.js +1 -5
- package/dist/selftest/host-sim.test.js +13 -14
- package/dist/selftest/install.test.js +6 -2
- package/dist/selftest/store-app.test.js +62 -4
- package/dist/selftest/support/web-preview.js +2 -2
- package/dist/shared/accounts/kinds.d.ts +5 -0
- package/dist/shared/accounts/kinds.js +8 -0
- package/dist/shared/apps/index.d.ts +1 -1
- package/dist/shared/apps/index.js +1 -1
- package/dist/shared/apps/selection.d.ts +1 -0
- package/dist/shared/apps/selection.js +4 -3
- package/dist/shared/apps/store-package.d.ts +13 -0
- package/dist/shared/apps/store-package.js +24 -0
- package/dist/shared/memory/index.d.ts +0 -1
- package/dist/shared/memory/index.js +0 -1
- package/native/csharp/HcsHost/AssemblyInfo.cs +3 -3
- package/native/csharp/HostTools/AssemblyInfo.cs +3 -3
- package/native/csharp/HostTools/Window.cs +1 -1
- package/native/csharp/StorageHelper/AssemblyInfo.cs +3 -3
- package/native/scripts/get-store-package.ps1 +24 -13
- package/package.json +4 -14
- package/sandbox/scripts/install-store-package.ps1 +11 -4
- package/schemas/config.schema.json +1 -1
- package/schemas/sandbox-config.schema.json +1 -1
- package/dist/bin/agent-sandbox.d.ts +0 -2
- package/dist/bin/agent-sandbox.js +0 -9
- package/dist/bin/chunk-ZMZI3625.js +0 -10778
- package/dist/bin/claude-host.d.ts +0 -2
- package/dist/bin/claude-host.js +0 -11
- package/dist/bin/claude-sbx.d.ts +0 -2
- package/dist/bin/claude-sbx.js +0 -9
- package/dist/bin/codex-sbx.d.ts +0 -2
- package/dist/bin/codex-sbx.js +0 -9
- package/dist/bin/gemini-sbx.d.ts +0 -2
- package/dist/bin/gemini-sbx.js +0 -9
- package/dist/bin/sbx-hide.d.ts +0 -2
- package/dist/bin/sbx-hide.js +0 -9
- package/dist/bin/sbx-show.d.ts +0 -2
- package/dist/bin/sbx-show.js +0 -9
- package/dist/shared/memory/unreal-build.d.ts +0 -2
- package/dist/shared/memory/unreal-build.js +0 -21
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
// PC logs for developing the sandbox inside a sandbox: when a launch includes this very source repo, the PC's recent
|
|
2
|
+
// crash reports and logs are copied into <launch>\pc-logs (C:\AgentLaunch\pc-logs, read-only, gone with the sandbox).
|
|
3
|
+
// The gate is the repository url: a repo that only claims the package name does not pass. If one ever did, it would
|
|
4
|
+
// see the owner's crash diagnostics (memory numbers, Windows events, process names), which hold no secrets.
|
|
5
|
+
// Nothing else from <storage> is copied: no state files, logins, secrets or session ledger.
|
|
6
|
+
import fs from 'node:fs';
|
|
7
|
+
import path from 'node:path';
|
|
8
|
+
import { z } from 'zod';
|
|
9
|
+
import { assertNoLinks, ensureDir } from '../../core/util/index.js';
|
|
10
|
+
const PACKAGE_NAME = 'windows-development-sandbox';
|
|
11
|
+
const MAX_PACKAGE_JSON_BYTES = 256 * 1024;
|
|
12
|
+
const MAX_REPORTS = 10;
|
|
13
|
+
const MAX_REPORT_BYTES = 64 * 1024;
|
|
14
|
+
const TAIL_BYTES = 256 * 1024;
|
|
15
|
+
const PackageSchema = z.object({
|
|
16
|
+
name: z.string(),
|
|
17
|
+
repository: z.union([z.string(), z.object({ url: z.string().optional() }).passthrough()]).optional(),
|
|
18
|
+
});
|
|
19
|
+
function repoUrl(pkg) {
|
|
20
|
+
const url = typeof pkg.repository === 'string' ? pkg.repository : pkg.repository?.url;
|
|
21
|
+
if (!url)
|
|
22
|
+
return null;
|
|
23
|
+
return url
|
|
24
|
+
.trim()
|
|
25
|
+
.toLowerCase()
|
|
26
|
+
.replace(/^git\+/, '')
|
|
27
|
+
.replace(/\.git$/, '')
|
|
28
|
+
.replace(/\/+$/, '');
|
|
29
|
+
}
|
|
30
|
+
/** The package.json in a folder, read with a size cap and no links; null when missing, too big or not valid. */
|
|
31
|
+
function readPackage(folder) {
|
|
32
|
+
try {
|
|
33
|
+
const file = path.join(folder, 'package.json');
|
|
34
|
+
assertNoLinks(folder, file);
|
|
35
|
+
const stat = fs.lstatSync(file);
|
|
36
|
+
if (!stat.isFile() || stat.size > MAX_PACKAGE_JSON_BYTES)
|
|
37
|
+
return null;
|
|
38
|
+
const parsed = PackageSchema.safeParse(JSON.parse(fs.readFileSync(file, 'utf8')));
|
|
39
|
+
return parsed.success ? parsed.data : null;
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
// No package.json, a link, or not JSON: not the sandbox's source.
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/** Whether a folder is a checkout (or git worktree) of this sandbox's own source repo, judged by the installed copy. */
|
|
47
|
+
export function isSandboxSourceRepo(folder, packageRoot) {
|
|
48
|
+
const own = readPackage(packageRoot);
|
|
49
|
+
const ownUrl = own ? repoUrl(own) : null;
|
|
50
|
+
if (!ownUrl)
|
|
51
|
+
return false;
|
|
52
|
+
const pkg = readPackage(folder);
|
|
53
|
+
return pkg !== null && pkg.name === PACKAGE_NAME && repoUrl(pkg) === ownUrl;
|
|
54
|
+
}
|
|
55
|
+
/** Plain file, no links on the way: its first `max` bytes (head) or last `max` bytes (tail); null when unreadable. */
|
|
56
|
+
function readBounded(root, file, max, from) {
|
|
57
|
+
try {
|
|
58
|
+
assertNoLinks(root, file);
|
|
59
|
+
const stat = fs.lstatSync(file);
|
|
60
|
+
if (!stat.isFile())
|
|
61
|
+
return null;
|
|
62
|
+
const length = Math.min(stat.size, max);
|
|
63
|
+
const buffer = Buffer.alloc(length);
|
|
64
|
+
const fd = fs.openSync(file, 'r');
|
|
65
|
+
try {
|
|
66
|
+
fs.readSync(fd, buffer, 0, length, from === 'tail' ? stat.size - length : 0);
|
|
67
|
+
}
|
|
68
|
+
finally {
|
|
69
|
+
fs.closeSync(fd);
|
|
70
|
+
}
|
|
71
|
+
return buffer;
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
// Missing or unreadable: left out.
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
const README = [
|
|
79
|
+
'These files come from the PC that started this sandbox: its recent crash reports and logs, for developing the',
|
|
80
|
+
'sandbox itself. They are read-only here and gone when the sandbox closes.',
|
|
81
|
+
'',
|
|
82
|
+
'They are not part of the repo: never copy them into the workspace and never commit them.',
|
|
83
|
+
'',
|
|
84
|
+
'crashes\\ the newest crash reports (what Windows logged when a sandbox ended, plus the memory log)',
|
|
85
|
+
'*.log the last 256 KB of the PC memory log, the host watcher log and the live-folders log',
|
|
86
|
+
'',
|
|
87
|
+
].join('\r\n');
|
|
88
|
+
/** Whether this launch has the sandbox's own source repo among its projects (the launch folder or a mapped project). */
|
|
89
|
+
export function launchHasSandboxSource(folders, packageRoot) {
|
|
90
|
+
return folders.some((f) => isSandboxSourceRepo(f, packageRoot));
|
|
91
|
+
}
|
|
92
|
+
/** Copies the PC's recent crash reports and log tails into <launchPath>\pc-logs. Returns the folder. */
|
|
93
|
+
export function stagePcLogs(storageRoot, dataPath, launchPath) {
|
|
94
|
+
const target = path.join(launchPath, 'pc-logs');
|
|
95
|
+
ensureDir(target);
|
|
96
|
+
fs.writeFileSync(path.join(target, 'README.txt'), README, 'utf8');
|
|
97
|
+
const crashes = path.join(storageRoot, 'logs', 'crashes');
|
|
98
|
+
let names = [];
|
|
99
|
+
try {
|
|
100
|
+
assertNoLinks(storageRoot, crashes);
|
|
101
|
+
names = fs
|
|
102
|
+
.readdirSync(crashes)
|
|
103
|
+
.filter((f) => /^crash-[\w.-]+\.txt$/.test(f))
|
|
104
|
+
.sort()
|
|
105
|
+
.slice(-MAX_REPORTS);
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
// No reports folder yet: none to copy.
|
|
109
|
+
}
|
|
110
|
+
for (const name of names) {
|
|
111
|
+
const text = readBounded(storageRoot, path.join(crashes, name), MAX_REPORT_BYTES, 'head');
|
|
112
|
+
if (!text)
|
|
113
|
+
continue;
|
|
114
|
+
ensureDir(path.join(target, 'crashes'));
|
|
115
|
+
fs.writeFileSync(path.join(target, 'crashes', name), text);
|
|
116
|
+
}
|
|
117
|
+
const data = path.basename(dataPath);
|
|
118
|
+
const tails = [
|
|
119
|
+
[path.join(storageRoot, 'logs', 'host-memory-' + data + '.log'), 'host-memory.log'],
|
|
120
|
+
[path.join(storageRoot, 'logs', 'host-sync-' + data + '.log'), 'host-sync.log'],
|
|
121
|
+
[path.join(storageRoot, 'state', 'live-folders.log'), 'live-folders.log'],
|
|
122
|
+
];
|
|
123
|
+
for (const [source, name] of tails) {
|
|
124
|
+
const text = readBounded(storageRoot, source, TAIL_BYTES, 'tail');
|
|
125
|
+
if (text)
|
|
126
|
+
fs.writeFileSync(path.join(target, name), text);
|
|
127
|
+
}
|
|
128
|
+
return target;
|
|
129
|
+
}
|
|
@@ -63,7 +63,7 @@ export function assertCanLaunch(owner) {
|
|
|
63
63
|
? other + ' (Windows allows one per PC).'
|
|
64
64
|
: 'A Windows Sandbox is already running (Windows allows one at a time).', other
|
|
65
65
|
? 'Use it with sandbox attach if it is shared with you, or start yours after it stops.'
|
|
66
|
-
: 'Attach to it with sandbox claude -t, show it with
|
|
66
|
+
: 'Attach to it with sandbox claude -t, show it with sandbox show, or shut it down with sandbox stop.');
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
69
|
/** cmd.exe expands %VAR% and ^ even inside quotes, and a quote ends them: such a path could run something else. */
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// Headless mode: Windows Sandbox always opens its client window, so we hide it (ShowWindow SW_HIDE) as soon as it
|
|
2
|
-
// appears. The VM and the logged-in session keep running; `
|
|
2
|
+
// appears. The VM and the logged-in session keep running; `sandbox show` brings the window back. The work is done by
|
|
3
3
|
// HostTools.exe (native\csharp\HostTools\Window.cs), else by native\scripts\*-window.ps1 with the same C#.
|
|
4
4
|
import path from 'node:path';
|
|
5
5
|
import { spawn, spawnSync } from 'node:child_process';
|
package/dist/runtime/agent.js
CHANGED
|
@@ -25516,7 +25516,7 @@ var SandboxSchema = external_exports.strictObject({
|
|
|
25516
25516
|
printerRedirection: external_exports.boolean().describe("Printers from this PC."),
|
|
25517
25517
|
protectedClient: external_exports.boolean().describe("Run the sandbox window in Protected Client mode (recommended)."),
|
|
25518
25518
|
headless: external_exports.boolean().describe(
|
|
25519
|
-
|
|
25519
|
+
'Hide the sandbox window ("Show the window" brings it back). A headless sandbox shuts down when its last session ends.'
|
|
25520
25520
|
),
|
|
25521
25521
|
keepAwake: external_exports.boolean().describe(
|
|
25522
25522
|
"Keep this PC from sleeping while a sandbox runs, so agents left working overnight keep going (the screen may still turn off; closing a laptop lid still sleeps it)."
|
package/dist/runtime/daemon.js
CHANGED
|
@@ -25535,7 +25535,7 @@ var SandboxSchema = external_exports.strictObject({
|
|
|
25535
25535
|
printerRedirection: external_exports.boolean().describe("Printers from this PC."),
|
|
25536
25536
|
protectedClient: external_exports.boolean().describe("Run the sandbox window in Protected Client mode (recommended)."),
|
|
25537
25537
|
headless: external_exports.boolean().describe(
|
|
25538
|
-
|
|
25538
|
+
'Hide the sandbox window ("Show the window" brings it back). A headless sandbox shuts down when its last session ends.'
|
|
25539
25539
|
),
|
|
25540
25540
|
keepAwake: external_exports.boolean().describe(
|
|
25541
25541
|
"Keep this PC from sleeping while a sandbox runs, so agents left working overnight keep going (the screen may still turn off; closing a laptop lid still sleeps it)."
|
|
@@ -30040,6 +30040,10 @@ function toolLines(primaryName, toolSummary, projects) {
|
|
|
30040
30040
|
"- Tools by project: each project gets the tools its own files ask for; python and rust already installed here are on every project's PATH."
|
|
30041
30041
|
];
|
|
30042
30042
|
}
|
|
30043
|
+
function pcLogsGuideLine(launchDir2, exists2) {
|
|
30044
|
+
const dir = path31.win32.join(launchDir2, "pc-logs");
|
|
30045
|
+
return exists2(dir) ? ["- PC crash reports and logs (this project only, read-only, never commit them): `" + dir + "`"] : [];
|
|
30046
|
+
}
|
|
30043
30047
|
|
|
30044
30048
|
// src/shared/unreal/engines.ts
|
|
30045
30049
|
import crypto3 from "node:crypto";
|
|
@@ -31915,6 +31919,7 @@ function sandboxGuide(toolSummary, lan = "blocked", projects = [], addons = [])
|
|
|
31915
31919
|
"- RW, persists: `" + stateDir + "` (agent config/history; do not edit logins) \xB7 logs: `" + path46.join(dataDir, "logs") + "`",
|
|
31916
31920
|
"- RO: `" + launchDir + "` (this boot's scripts) \xB7 lost on close: everything else, incl. `C:\\nvm` (Node symlink)",
|
|
31917
31921
|
...mirrorLine(),
|
|
31922
|
+
...pcLogsGuideLine(launchDir, fs28.existsSync),
|
|
31918
31923
|
...toolLines(session.project, toolSummary, projects),
|
|
31919
31924
|
...unrealLines(projects),
|
|
31920
31925
|
...unityLines(projects),
|
|
@@ -32690,9 +32695,10 @@ function fileSha256(file3) {
|
|
|
32690
32695
|
stream.on("end", () => resolve2(hash2.digest("hex")));
|
|
32691
32696
|
});
|
|
32692
32697
|
}
|
|
32698
|
+
var MISSING_PACKAGE = 'this PC did not hand over its package (it could not fetch it: see the launch notes). Fix: on this PC run "winget download --id <product id> --source msstore", then launch again';
|
|
32693
32699
|
async function checkedPackage(dir) {
|
|
32694
32700
|
const manifest2 = readValid(StorePackageManifestSchema, path55.join(dir, STORE_PACKAGE_MANIFEST));
|
|
32695
|
-
if (!manifest2) throw new Error(
|
|
32701
|
+
if (!manifest2) throw new Error(MISSING_PACKAGE);
|
|
32696
32702
|
for (const f of manifest2.files) {
|
|
32697
32703
|
if (await fileSha256(path55.join(dir, f.name)).catch(() => "") !== f.sha256)
|
|
32698
32704
|
throw new Error(f.name + " is missing or changed");
|
|
@@ -33072,7 +33078,9 @@ var AppInstaller = class {
|
|
|
33072
33078
|
warn(
|
|
33073
33079
|
entry.name + " could not be installed and is skipped; the other apps are not affected. Reason: " + errMsg(e)
|
|
33074
33080
|
);
|
|
33075
|
-
this.env.summary.push(
|
|
33081
|
+
this.env.summary.push(
|
|
33082
|
+
"store" in entry.source ? entry.name + ": not installed - " + errMsg(e).slice(0, 300) : entry.name + ": FAILED"
|
|
33083
|
+
);
|
|
33076
33084
|
}
|
|
33077
33085
|
}
|
|
33078
33086
|
/** The command line an app's shortcut starts it with (Comet: its own profile, DevTools on 127.0.0.1). */
|
|
@@ -34957,82 +34965,6 @@ import fs58 from "node:fs";
|
|
|
34957
34965
|
import os10 from "node:os";
|
|
34958
34966
|
import path83 from "node:path";
|
|
34959
34967
|
|
|
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
|
-
|
|
35036
34968
|
// src/guest/toolchains/native/debuggers.ts
|
|
35037
34969
|
import path79 from "node:path";
|
|
35038
34970
|
var SDK_SETUP_URL = "https://go.microsoft.com/fwlink/?linkid=2311806";
|
|
@@ -35810,14 +35742,6 @@ async function checkVisualStudio() {
|
|
|
35810
35742
|
fs58.rmSync(dir, { recursive: true, force: true });
|
|
35811
35743
|
}
|
|
35812
35744
|
}
|
|
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
|
-
}
|
|
35821
35745
|
async function part(what, work, fallback) {
|
|
35822
35746
|
try {
|
|
35823
35747
|
return await work();
|
|
@@ -35836,8 +35760,6 @@ async function setupUnreal(env, config2, _ctx) {
|
|
|
35836
35760
|
return;
|
|
35837
35761
|
}
|
|
35838
35762
|
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)");
|
|
35841
35763
|
await part("the DirectX End-User Runtime", installDirectX, void 0);
|
|
35842
35764
|
const launcher = await part("the Epic Games Launcher", ensureLauncher, null);
|
|
35843
35765
|
const place = placeEngines(config2.persistEngines);
|
|
@@ -35873,7 +35795,7 @@ async function setupUnreal(env, config2, _ctx) {
|
|
|
35873
35795
|
debugger: debuggers ? path83.join(debuggers, "cdb.exe") : null
|
|
35874
35796
|
}));
|
|
35875
35797
|
env.summary.push(
|
|
35876
|
-
"unreal tools: " + (vs ? "Visual Studio " + vs.version + (check2.ok ? " (UnrealBuildTool finds it)" : " (UnrealBuildTool would NOT find it)") : "no Visual Studio") +
|
|
35798
|
+
"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" : "")
|
|
35877
35799
|
);
|
|
35878
35800
|
}
|
|
35879
35801
|
|
|
@@ -37720,6 +37642,66 @@ import fs72 from "node:fs";
|
|
|
37720
37642
|
import os12 from "node:os";
|
|
37721
37643
|
import path104 from "node:path";
|
|
37722
37644
|
|
|
37645
|
+
// src/shared/memory/policy.ts
|
|
37646
|
+
var DIAL_STEPS = {
|
|
37647
|
+
normal: [
|
|
37648
|
+
{ availablePercent: 15, commitPercent: 80 },
|
|
37649
|
+
{ availablePercent: 10, commitPercent: 88 },
|
|
37650
|
+
{ availablePercent: 6, commitPercent: 94, secondsToLimit: 20 },
|
|
37651
|
+
{ availablePercent: 4, commitPercent: 97, secondsToLimit: 8 }
|
|
37652
|
+
],
|
|
37653
|
+
gentle: [
|
|
37654
|
+
{ availablePercent: 20, commitPercent: 75 },
|
|
37655
|
+
{ availablePercent: 15, commitPercent: 85 },
|
|
37656
|
+
{ availablePercent: 8, commitPercent: 92, secondsToLimit: 25 },
|
|
37657
|
+
{ availablePercent: 5, commitPercent: 96, secondsToLimit: 10 }
|
|
37658
|
+
]
|
|
37659
|
+
};
|
|
37660
|
+
var DIAL_EXIT_MARGIN = { availablePercent: 5, commitPercent: 4 };
|
|
37661
|
+
var DIAL_CALM_SAMPLES = 3;
|
|
37662
|
+
var DIAL_CPU_RATE = [100, 100, 60, 35, 15];
|
|
37663
|
+
function compilersAllowed(step, running) {
|
|
37664
|
+
if (step <= 1 || running <= 1) return running;
|
|
37665
|
+
if (step === 2) return Math.max(1, Math.ceil(running * 0.6));
|
|
37666
|
+
if (step === 3) return Math.max(1, Math.ceil(running / 3));
|
|
37667
|
+
return 1;
|
|
37668
|
+
}
|
|
37669
|
+
function buildJobs(cpus, memoryGb) {
|
|
37670
|
+
return Math.max(2, Math.min(cpus, Math.floor((memoryGb - 6) / 3)));
|
|
37671
|
+
}
|
|
37672
|
+
function linkSlotsFor(memoryGb) {
|
|
37673
|
+
return Math.max(2, Math.min(8, Math.floor((memoryGb - 6) / 3)));
|
|
37674
|
+
}
|
|
37675
|
+
function usableCpus(cpus, percent) {
|
|
37676
|
+
if (percent === null || percent >= 100) return cpus;
|
|
37677
|
+
return Math.max(2, Math.min(cpus, Math.floor(cpus * percent / 100)));
|
|
37678
|
+
}
|
|
37679
|
+
function cargoJobs(cpus, memoryGb, sessions2) {
|
|
37680
|
+
const byCpu = Math.max(2, Math.min(8, Math.floor(cpus / 4)));
|
|
37681
|
+
const byMemory = Math.max(1, Math.floor(memoryGb / 4));
|
|
37682
|
+
const jobs = Math.min(byCpu, byMemory);
|
|
37683
|
+
return Math.max(1, Math.min(jobs, Math.floor(buildJobs(cpus, memoryGb) / Math.max(1, sessions2))));
|
|
37684
|
+
}
|
|
37685
|
+
var LOCAL_TARGET_MIN_BYTES = 25 * 1024 ** 3;
|
|
37686
|
+
function chooseTargetDir(targetDir, freeBytes2) {
|
|
37687
|
+
if (targetDir !== "auto") return { targetDir };
|
|
37688
|
+
if (freeBytes2 >= LOCAL_TARGET_MIN_BYTES) return { targetDir: "local" };
|
|
37689
|
+
return {
|
|
37690
|
+
targetDir: "separate",
|
|
37691
|
+
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)"
|
|
37692
|
+
};
|
|
37693
|
+
}
|
|
37694
|
+
function maxCompilers(cpus, profile) {
|
|
37695
|
+
return profile === "gentle" ? Math.min(4, Math.max(2, Math.floor(cpus / 4))) : null;
|
|
37696
|
+
}
|
|
37697
|
+
function cargoLinkerVar(host) {
|
|
37698
|
+
return "CARGO_TARGET_" + host.toUpperCase().replace(/[^A-Z0-9]/g, "_") + "_LINKER";
|
|
37699
|
+
}
|
|
37700
|
+
var BURST_GATE = {
|
|
37701
|
+
normal: { growthMb: 4096, windowMs: 3e3, releaseMs: 1500, maxHoldMs: 3e4 },
|
|
37702
|
+
gentle: { growthMb: 3072, windowMs: 3e3, releaseMs: 2e3, maxHoldMs: 3e4 }
|
|
37703
|
+
};
|
|
37704
|
+
|
|
37723
37705
|
// src/guest/governor/decide.ts
|
|
37724
37706
|
var COMPILERS = /* @__PURE__ */ new Set([
|
|
37725
37707
|
"rustc",
|
package/dist/runtime/db.js
CHANGED
|
@@ -25492,7 +25492,7 @@ var SandboxSchema = external_exports.strictObject({
|
|
|
25492
25492
|
printerRedirection: external_exports.boolean().describe("Printers from this PC."),
|
|
25493
25493
|
protectedClient: external_exports.boolean().describe("Run the sandbox window in Protected Client mode (recommended)."),
|
|
25494
25494
|
headless: external_exports.boolean().describe(
|
|
25495
|
-
|
|
25495
|
+
'Hide the sandbox window ("Show the window" brings it back). A headless sandbox shuts down when its last session ends.'
|
|
25496
25496
|
),
|
|
25497
25497
|
keepAwake: external_exports.boolean().describe(
|
|
25498
25498
|
"Keep this PC from sleeping while a sandbox runs, so agents left working overnight keep going (the screen may still turn off; closing a laptop lid still sleeps it)."
|
package/dist/runtime/main.js
CHANGED
|
@@ -25508,7 +25508,7 @@ var SandboxSchema = external_exports.strictObject({
|
|
|
25508
25508
|
printerRedirection: external_exports.boolean().describe("Printers from this PC."),
|
|
25509
25509
|
protectedClient: external_exports.boolean().describe("Run the sandbox window in Protected Client mode (recommended)."),
|
|
25510
25510
|
headless: external_exports.boolean().describe(
|
|
25511
|
-
|
|
25511
|
+
'Hide the sandbox window ("Show the window" brings it back). A headless sandbox shuts down when its last session ends.'
|
|
25512
25512
|
),
|
|
25513
25513
|
keepAwake: external_exports.boolean().describe(
|
|
25514
25514
|
"Keep this PC from sleeping while a sandbox runs, so agents left working overnight keep going (the screen may still turn off; closing a laptop lid still sleeps it)."
|
|
@@ -29168,6 +29168,10 @@ function toolLines(primaryName, toolSummary, projects) {
|
|
|
29168
29168
|
"- Tools by project: each project gets the tools its own files ask for; python and rust already installed here are on every project's PATH."
|
|
29169
29169
|
];
|
|
29170
29170
|
}
|
|
29171
|
+
function pcLogsGuideLine(launchDir2, exists2) {
|
|
29172
|
+
const dir = path20.win32.join(launchDir2, "pc-logs");
|
|
29173
|
+
return exists2(dir) ? ["- PC crash reports and logs (this project only, read-only, never commit them): `" + dir + "`"] : [];
|
|
29174
|
+
}
|
|
29171
29175
|
|
|
29172
29176
|
// src/shared/unreal/engines.ts
|
|
29173
29177
|
import crypto3 from "node:crypto";
|
|
@@ -31194,6 +31198,7 @@ function sandboxGuide(toolSummary, lan = "blocked", projects = [], addons = [])
|
|
|
31194
31198
|
"- RW, persists: `" + stateDir + "` (agent config/history; do not edit logins) \xB7 logs: `" + path36.join(dataDir, "logs") + "`",
|
|
31195
31199
|
"- RO: `" + launchDir + "` (this boot's scripts) \xB7 lost on close: everything else, incl. `C:\\nvm` (Node symlink)",
|
|
31196
31200
|
...mirrorLine(),
|
|
31201
|
+
...pcLogsGuideLine(launchDir, fs23.existsSync),
|
|
31197
31202
|
...toolLines(session.project, toolSummary, projects),
|
|
31198
31203
|
...unrealLines(projects),
|
|
31199
31204
|
...unityLines(projects),
|
|
@@ -31981,9 +31986,10 @@ function fileSha256(file3) {
|
|
|
31981
31986
|
stream.on("end", () => resolve2(hash2.digest("hex")));
|
|
31982
31987
|
});
|
|
31983
31988
|
}
|
|
31989
|
+
var MISSING_PACKAGE = 'this PC did not hand over its package (it could not fetch it: see the launch notes). Fix: on this PC run "winget download --id <product id> --source msstore", then launch again';
|
|
31984
31990
|
async function checkedPackage(dir) {
|
|
31985
31991
|
const manifest2 = readValid(StorePackageManifestSchema, path45.join(dir, STORE_PACKAGE_MANIFEST));
|
|
31986
|
-
if (!manifest2) throw new Error(
|
|
31992
|
+
if (!manifest2) throw new Error(MISSING_PACKAGE);
|
|
31987
31993
|
for (const f of manifest2.files) {
|
|
31988
31994
|
if (await fileSha256(path45.join(dir, f.name)).catch(() => "") !== f.sha256)
|
|
31989
31995
|
throw new Error(f.name + " is missing or changed");
|
|
@@ -32363,7 +32369,9 @@ var AppInstaller = class {
|
|
|
32363
32369
|
warn(
|
|
32364
32370
|
entry.name + " could not be installed and is skipped; the other apps are not affected. Reason: " + errMsg(e)
|
|
32365
32371
|
);
|
|
32366
|
-
this.env.summary.push(
|
|
32372
|
+
this.env.summary.push(
|
|
32373
|
+
"store" in entry.source ? entry.name + ": not installed - " + errMsg(e).slice(0, 300) : entry.name + ": FAILED"
|
|
32374
|
+
);
|
|
32367
32375
|
}
|
|
32368
32376
|
}
|
|
32369
32377
|
/** The command line an app's shortcut starts it with (Comet: its own profile, DevTools on 127.0.0.1). */
|
|
@@ -34243,49 +34251,6 @@ import fs52 from "node:fs";
|
|
|
34243
34251
|
import os9 from "node:os";
|
|
34244
34252
|
import path73 from "node:path";
|
|
34245
34253
|
|
|
34246
|
-
// src/shared/memory/policy.ts
|
|
34247
|
-
function buildJobs(cpus, memoryGb) {
|
|
34248
|
-
return Math.max(2, Math.min(cpus, Math.floor((memoryGb - 6) / 3)));
|
|
34249
|
-
}
|
|
34250
|
-
function usableCpus(cpus, percent) {
|
|
34251
|
-
if (percent === null || percent >= 100) return cpus;
|
|
34252
|
-
return Math.max(2, Math.min(cpus, Math.floor(cpus * percent / 100)));
|
|
34253
|
-
}
|
|
34254
|
-
function cargoJobs(cpus, memoryGb, sessions) {
|
|
34255
|
-
const byCpu = Math.max(2, Math.min(8, Math.floor(cpus / 4)));
|
|
34256
|
-
const byMemory = Math.max(1, Math.floor(memoryGb / 4));
|
|
34257
|
-
const jobs = Math.min(byCpu, byMemory);
|
|
34258
|
-
return Math.max(1, Math.min(jobs, Math.floor(buildJobs(cpus, memoryGb) / Math.max(1, sessions))));
|
|
34259
|
-
}
|
|
34260
|
-
var LOCAL_TARGET_MIN_BYTES = 25 * 1024 ** 3;
|
|
34261
|
-
function chooseTargetDir(targetDir, freeBytes2) {
|
|
34262
|
-
if (targetDir !== "auto") return { targetDir };
|
|
34263
|
-
if (freeBytes2 >= LOCAL_TARGET_MIN_BYTES) return { targetDir: "local" };
|
|
34264
|
-
return {
|
|
34265
|
-
targetDir: "separate",
|
|
34266
|
-
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)"
|
|
34267
|
-
};
|
|
34268
|
-
}
|
|
34269
|
-
function cargoLinkerVar(host) {
|
|
34270
|
-
return "CARGO_TARGET_" + host.toUpperCase().replace(/[^A-Z0-9]/g, "_") + "_LINKER";
|
|
34271
|
-
}
|
|
34272
|
-
|
|
34273
|
-
// src/shared/memory/unreal-build.ts
|
|
34274
|
-
var NAMESPACE = "https://www.unrealengine.com/BuildConfiguration";
|
|
34275
|
-
function ubtBuildConfiguration(jobs) {
|
|
34276
|
-
const max = Math.max(1, Math.floor(jobs));
|
|
34277
|
-
return [
|
|
34278
|
-
'<?xml version="1.0" encoding="utf-8"?>',
|
|
34279
|
-
"<!-- Written by the sandbox at boot: compiles at once from the build budget (run\\budget.json, buildJobs). -->",
|
|
34280
|
-
'<Configuration xmlns="' + NAMESPACE + '">',
|
|
34281
|
-
" <BuildConfiguration>",
|
|
34282
|
-
" <MaxParallelActions>" + max + "</MaxParallelActions>",
|
|
34283
|
-
" </BuildConfiguration>",
|
|
34284
|
-
"</Configuration>",
|
|
34285
|
-
""
|
|
34286
|
-
].join("\r\n");
|
|
34287
|
-
}
|
|
34288
|
-
|
|
34289
34254
|
// src/guest/toolchains/native/debuggers.ts
|
|
34290
34255
|
import path69 from "node:path";
|
|
34291
34256
|
var SDK_SETUP_URL = "https://go.microsoft.com/fwlink/?linkid=2311806";
|
|
@@ -35015,14 +34980,6 @@ async function checkVisualStudio() {
|
|
|
35015
34980
|
fs52.rmSync(dir, { recursive: true, force: true });
|
|
35016
34981
|
}
|
|
35017
34982
|
}
|
|
35018
|
-
function capUnrealBuilds() {
|
|
35019
|
-
const cpus = usableCpus(os9.cpus().length, session.cpuLimitPercent ?? null);
|
|
35020
|
-
const jobs = buildJobs(cpus, os9.totalmem() / 1024 ** 3);
|
|
35021
|
-
const appData = process.env.APPDATA ?? "C:\\Users\\WDAGUtilityAccount\\AppData\\Roaming";
|
|
35022
|
-
const dir = mkdirp(path73.join(appData, "Unreal Engine", "UnrealBuildTool"));
|
|
35023
|
-
fs52.writeFileSync(path73.join(dir, "BuildConfiguration.xml"), ubtBuildConfiguration(jobs), "utf8");
|
|
35024
|
-
return jobs;
|
|
35025
|
-
}
|
|
35026
34983
|
async function part(what, work, fallback) {
|
|
35027
34984
|
try {
|
|
35028
34985
|
return await work();
|
|
@@ -35041,8 +34998,6 @@ async function setupUnreal(env, config3, _ctx) {
|
|
|
35041
34998
|
return;
|
|
35042
34999
|
}
|
|
35043
35000
|
resetUnrealStatus();
|
|
35044
|
-
const jobs = await part("capping parallel compiles", async () => capUnrealBuilds(), 0);
|
|
35045
|
-
if (jobs) log("Unreal: UnrealBuildTool runs at most " + jobs + " compiles at once (the build budget)");
|
|
35046
35001
|
await part("the DirectX End-User Runtime", installDirectX, void 0);
|
|
35047
35002
|
const launcher = await part("the Epic Games Launcher", ensureLauncher, null);
|
|
35048
35003
|
const place = placeEngines(config3.persistEngines);
|
|
@@ -35078,7 +35033,7 @@ async function setupUnreal(env, config3, _ctx) {
|
|
|
35078
35033
|
debugger: debuggers ? path73.join(debuggers, "cdb.exe") : null
|
|
35079
35034
|
}));
|
|
35080
35035
|
env.summary.push(
|
|
35081
|
-
"unreal tools: " + (vs ? "Visual Studio " + vs.version + (check2.ok ? " (UnrealBuildTool finds it)" : " (UnrealBuildTool would NOT find it)") : "no Visual Studio") +
|
|
35036
|
+
"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" : "")
|
|
35082
35037
|
);
|
|
35083
35038
|
}
|
|
35084
35039
|
|
|
@@ -38405,6 +38360,29 @@ import fs67 from "node:fs";
|
|
|
38405
38360
|
import os11 from "node:os";
|
|
38406
38361
|
import path94 from "node:path";
|
|
38407
38362
|
|
|
38363
|
+
// src/shared/memory/policy.ts
|
|
38364
|
+
function buildJobs(cpus, memoryGb) {
|
|
38365
|
+
return Math.max(2, Math.min(cpus, Math.floor((memoryGb - 6) / 3)));
|
|
38366
|
+
}
|
|
38367
|
+
function cargoJobs(cpus, memoryGb, sessions) {
|
|
38368
|
+
const byCpu = Math.max(2, Math.min(8, Math.floor(cpus / 4)));
|
|
38369
|
+
const byMemory = Math.max(1, Math.floor(memoryGb / 4));
|
|
38370
|
+
const jobs = Math.min(byCpu, byMemory);
|
|
38371
|
+
return Math.max(1, Math.min(jobs, Math.floor(buildJobs(cpus, memoryGb) / Math.max(1, sessions))));
|
|
38372
|
+
}
|
|
38373
|
+
var LOCAL_TARGET_MIN_BYTES = 25 * 1024 ** 3;
|
|
38374
|
+
function chooseTargetDir(targetDir, freeBytes2) {
|
|
38375
|
+
if (targetDir !== "auto") return { targetDir };
|
|
38376
|
+
if (freeBytes2 >= LOCAL_TARGET_MIN_BYTES) return { targetDir: "local" };
|
|
38377
|
+
return {
|
|
38378
|
+
targetDir: "separate",
|
|
38379
|
+
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)"
|
|
38380
|
+
};
|
|
38381
|
+
}
|
|
38382
|
+
function cargoLinkerVar(host) {
|
|
38383
|
+
return "CARGO_TARGET_" + host.toUpperCase().replace(/[^A-Z0-9]/g, "_") + "_LINKER";
|
|
38384
|
+
}
|
|
38385
|
+
|
|
38408
38386
|
// src/guest/governor/decide.ts
|
|
38409
38387
|
var COMPILERS = /* @__PURE__ */ new Set([
|
|
38410
38388
|
"rustc",
|
package/dist/runtime/netproxy.js
CHANGED
|
@@ -25544,7 +25544,7 @@ var SandboxSchema = external_exports.strictObject({
|
|
|
25544
25544
|
printerRedirection: external_exports.boolean().describe("Printers from this PC."),
|
|
25545
25545
|
protectedClient: external_exports.boolean().describe("Run the sandbox window in Protected Client mode (recommended)."),
|
|
25546
25546
|
headless: external_exports.boolean().describe(
|
|
25547
|
-
|
|
25547
|
+
'Hide the sandbox window ("Show the window" brings it back). A headless sandbox shuts down when its last session ends.'
|
|
25548
25548
|
),
|
|
25549
25549
|
keepAwake: external_exports.boolean().describe(
|
|
25550
25550
|
"Keep this PC from sleeping while a sandbox runs, so agents left working overnight keep going (the screen may still turn off; closing a laptop lid still sleeps it)."
|
package/dist/runtime/tool.js
CHANGED
|
@@ -25930,7 +25930,7 @@ var SandboxSchema = external_exports.strictObject({
|
|
|
25930
25930
|
printerRedirection: external_exports.boolean().describe("Printers from this PC."),
|
|
25931
25931
|
protectedClient: external_exports.boolean().describe("Run the sandbox window in Protected Client mode (recommended)."),
|
|
25932
25932
|
headless: external_exports.boolean().describe(
|
|
25933
|
-
|
|
25933
|
+
'Hide the sandbox window ("Show the window" brings it back). A headless sandbox shuts down when its last session ends.'
|
|
25934
25934
|
),
|
|
25935
25935
|
keepAwake: external_exports.boolean().describe(
|
|
25936
25936
|
"Keep this PC from sleeping while a sandbox runs, so agents left working overnight keep going (the screen may still turn off; closing a laptop lid still sleeps it)."
|
package/dist/runtime/view.js
CHANGED
|
@@ -26214,7 +26214,7 @@ var SandboxSchema = external_exports.strictObject({
|
|
|
26214
26214
|
printerRedirection: external_exports.boolean().describe("Printers from this PC."),
|
|
26215
26215
|
protectedClient: external_exports.boolean().describe("Run the sandbox window in Protected Client mode (recommended)."),
|
|
26216
26216
|
headless: external_exports.boolean().describe(
|
|
26217
|
-
|
|
26217
|
+
'Hide the sandbox window ("Show the window" brings it back). A headless sandbox shuts down when its last session ends.'
|
|
26218
26218
|
),
|
|
26219
26219
|
keepAwake: external_exports.boolean().describe(
|
|
26220
26220
|
"Keep this PC from sleeping while a sandbox runs, so agents left working overnight keep going (the screen may still turn off; closing a laptop lid still sleeps it)."
|
|
@@ -47,17 +47,17 @@ export const cliSuite = {
|
|
|
47
47
|
['postgres', 'redis', 'mongodb'],
|
|
48
48
|
['--continue'],
|
|
49
49
|
], '`start` is launch without an agent; positionals, repeated lists and arguments after -- parse');
|
|
50
|
-
t.section('parser: agent
|
|
50
|
+
t.section('parser: agent mode (sandbox claude ...) and plain commands');
|
|
51
51
|
const wrapped = parseCli(['--terminal', '--continue', '--headless', '--node', '20', '--', '--terminal'], true);
|
|
52
|
-
t.equal([wrapped.command, wrapped.terminal, wrapped.headless, wrapped.node, wrapped.passthrough], ['launch', true, true, '20', ['--continue', '--terminal']], '
|
|
53
|
-
await t.throws(() => parseCli(['status', '--bogus']), 'unknown option', '
|
|
52
|
+
t.equal([wrapped.command, wrapped.terminal, wrapped.headless, wrapped.node, wrapped.passthrough], ['launch', true, true, '20', ['--continue', '--terminal']], 'agent mode: sandbox flags are consumed, everything else goes to the agent');
|
|
53
|
+
await t.throws(() => parseCli(['status', '--bogus']), 'unknown option', 'plain commands: unknown options are errors');
|
|
54
54
|
const agentFlags = parseCli(['--model', 'opus', '-p', 'fix it', '--json', '-f', 'x', '--timeout', '5', '--resume', 'abc'], true);
|
|
55
55
|
t.check(agentFlags.passthrough.join('|') === '--model|opus|-p|fix it|--json|-f|x|--timeout|5|--resume|abc' &&
|
|
56
56
|
!agentFlags.json &&
|
|
57
57
|
!agentFlags.follow &&
|
|
58
|
-
agentFlags.timeout === 600, '
|
|
58
|
+
agentFlags.timeout === 600, 'agent mode: any flag that is not a launch option goes to the agent in order and sets no sandbox option');
|
|
59
59
|
const reserved = parseCli(['--sbx-terminal', '--terminal', '--sbx-node=18'], true);
|
|
60
|
-
t.equal([reserved.terminal, reserved.node, reserved.passthrough], [true, '18', []], '--sbx-<option> always means
|
|
60
|
+
t.equal([reserved.terminal, reserved.node, reserved.passthrough], [true, '18', []], '--sbx-<option> always means the sandbox option');
|
|
61
61
|
await t.throws(() => parseCli(['--sbx-nope'], true), 'Unknown option: --sbx-nope', 'an unknown --sbx-<option> is an error');
|
|
62
62
|
t.section('menu helpers');
|
|
63
63
|
t.check(splitArgs('--model "big one" -c \'x y\'').join('|') === '--model|big one|-c|x y' &&
|
|
@@ -75,7 +75,7 @@ export const configSuite = {
|
|
|
75
75
|
});
|
|
76
76
|
const sharedFile = t.at('share', 'theirs.json');
|
|
77
77
|
fs.writeFileSync(sharedFile, shared);
|
|
78
|
-
const bin = (args) => f.runBin('
|
|
78
|
+
const bin = (args) => f.runBin('sandbox', [...args, '--config', yours], { cwd: f.workA, env });
|
|
79
79
|
const outFile = t.at('share', 'out.json');
|
|
80
80
|
const exportRun = await bin(['config', 'export', outFile]);
|
|
81
81
|
const written = readJsonc(outFile);
|
|
@@ -191,7 +191,7 @@ export const credentialsSuite = {
|
|
|
191
191
|
['vpn', 'status', '--json'],
|
|
192
192
|
['status', '--json'],
|
|
193
193
|
]) {
|
|
194
|
-
const out = await f.runBin('
|
|
194
|
+
const out = await f.runBin('sandbox', [...args, '--config', cliConfig], { cwd: f.workA, env });
|
|
195
195
|
t.check(!out.out.includes(API_KEY) && (args[0] !== 'config' || out.out.includes('***')), 'sandbox ' + args.join(' ') + ' never prints the planted key' + (args[0] === 'config' ? ' (it shows ***)' : ''), out.out.slice(0, 400));
|
|
196
196
|
}
|
|
197
197
|
},
|
|
@@ -117,7 +117,7 @@ export const engineSuite = {
|
|
|
117
117
|
!LocalOverridesSchema.safeParse({ storage: { containedMaxGb: 8 } }).success, "a project's .sandbox-config.json cannot set sandbox.engine, storage.contained or storage.containedMaxGb");
|
|
118
118
|
t.check(LocalOverridesSchema.safeParse({ sandbox: { vGpu: false } }).success, 'other sandbox settings are still allowed in a project file');
|
|
119
119
|
t.section('sandbox engine');
|
|
120
|
-
const run = await f.runBin('
|
|
120
|
+
const run = await f.runBin('sandbox', ['engine', '--json', '--config', t.writeJson(t.at('engine-config.json'), {})], {
|
|
121
121
|
cwd: f.workA,
|
|
122
122
|
env: { ...process.env, NO_COLOR: '1', AGENT_SANDBOX_HOME: t.dir('engine-home'), AGENT_SANDBOX_HOST_ONLY: '1' },
|
|
123
123
|
});
|