windows-development-sandbox 1.16.0 → 1.17.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +92 -92
- package/config.example.json +6 -0
- package/dist/app/features/access/access.run.js +1 -1
- package/dist/bin/agent-sandbox.js +2 -2
- package/dist/bin/{chunk-7EXDUNE7.js → chunk-QLGGAG3D.js} +1 -1
- package/dist/bin/{chunk-HIC4CUMY.js → chunk-REE3EMHD.js} +73 -16
- package/dist/bin/{chunk-PXTLKIV4.js → chunk-XYUVIVJT.js} +1 -1
- package/dist/bin/claude-host.js +2 -2
- package/dist/bin/claude-sbx.js +2 -2
- package/dist/bin/codex-sbx.js +2 -2
- package/dist/bin/gemini-sbx.js +2 -2
- package/dist/bin/sandbox.js +2 -2
- package/dist/bin/sbx-hide.js +2 -2
- package/dist/bin/sbx-show.js +2 -2
- package/dist/cli/commands/web.js +1 -1
- package/dist/core/config/defaults.js +1 -0
- package/dist/core/detect/toolchains.d.ts +1 -0
- package/dist/core/detect/toolchains.js +7 -0
- package/dist/core/schema/config.d.ts +21 -0
- package/dist/core/schema/sandbox.js +1 -1
- package/dist/core/schema/toolchains.d.ts +6 -0
- package/dist/core/schema/toolchains.js +10 -0
- package/dist/guest/agents/agent-files.d.ts +6 -0
- package/dist/guest/agents/agent-files.js +14 -0
- package/dist/guest/agents/local-state.d.ts +2 -0
- package/dist/guest/agents/local-state.js +13 -1
- package/dist/guest/boot/boot.js +4 -1
- package/dist/guest/setup/browser-gpu.d.ts +1 -0
- package/dist/guest/setup/browser-gpu.js +18 -0
- package/dist/guest/toolchains/native/rust-extras.js +3 -1
- package/dist/guest/toolchains/native/unreal.d.ts +9 -0
- package/dist/guest/toolchains/native/unreal.js +198 -0
- package/dist/guest/toolchains/native/vcruntime.d.ts +3 -0
- package/dist/guest/toolchains/native/vcruntime.js +2 -2
- package/dist/guest/toolchains/plan.js +10 -2
- package/dist/host/engines/hcs/live-folders.js +1 -1
- package/dist/host/github/token.js +1 -1
- package/dist/host/profile/accounts.js +1 -1
- package/dist/host/profile/agent-accounts.js +1 -1
- package/dist/host/profile/plugin-share.d.ts +5 -0
- package/dist/host/profile/plugin-share.js +22 -1
- package/dist/host/secrets/secret-store.d.ts +3 -3
- package/dist/host/secrets/secret-store.js +37 -10
- package/dist/host/vpn/login.js +1 -1
- package/dist/runtime/agent.js +16 -1
- package/dist/runtime/daemon.js +531 -337
- package/dist/runtime/db.js +17 -1
- package/dist/runtime/main.js +694 -472
- package/dist/runtime/netproxy.js +16 -1
- package/dist/runtime/view.js +16 -1
- package/dist/selftest/accounts.test.js +7 -0
- package/dist/selftest/agent-paths.test.js +12 -1
- package/dist/selftest/detect.test.js +7 -0
- package/dist/selftest/live-network.test.js +5 -0
- package/dist/selftest/support/fixtures.d.ts +6 -0
- package/dist/shared/channel/schema.d.ts +18 -0
- package/native/csharp/HcsHost/AssemblyInfo.cs +3 -3
- package/native/csharp/HostTools/AssemblyInfo.cs +3 -3
- package/native/csharp/HostTools/Program.cs +6 -1
- package/native/csharp/HostTools/Protect.cs +41 -0
- package/native/csharp/StorageHelper/AssemblyInfo.cs +3 -3
- package/package.json +1 -1
- package/schemas/config.schema.json +34 -1
- package/schemas/sandbox-config.schema.json +34 -1
package/dist/runtime/netproxy.js
CHANGED
|
@@ -25515,7 +25515,7 @@ var SandboxSchema = external_exports.strictObject({
|
|
|
25515
25515
|
"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."
|
|
25516
25516
|
),
|
|
25517
25517
|
vGpu: external_exports.boolean().describe(
|
|
25518
|
-
"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)."
|
|
25518
|
+
"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)."
|
|
25519
25519
|
),
|
|
25520
25520
|
networking: external_exports.boolean().describe("Internet access. false is the only hard network isolation Windows Sandbox offers."),
|
|
25521
25521
|
clipboard: external_exports.boolean().describe(
|
|
@@ -25677,6 +25677,21 @@ var ToolchainsSchema = external_exports.strictObject({
|
|
|
25677
25677
|
msvcVersion: external_exports.string().min(1).describe('"latest" or an MSVC tools version prefix, e.g. "14.44".'),
|
|
25678
25678
|
sdkVersion: external_exports.string().min(1).describe('"latest" or a Windows SDK build, e.g. "26100" or "10.0.22621".')
|
|
25679
25679
|
}),
|
|
25680
|
+
unreal: external_exports.strictObject({
|
|
25681
|
+
enabled: enabled(
|
|
25682
|
+
"Unreal Engine development: Visual Studio Community 2022 with the C++ game workload (MSVC, a Windows 11 SDK, .NET Framework targeting packs, Unreal integration and the Epic Games Launcher) and the DirectX End-User Runtime. A real installer: it runs every boot (~10 GB on the sandbox disk). The engine itself comes from the Epic Games Launcher or its source.",
|
|
25683
|
+
"a .uproject or .uplugin"
|
|
25684
|
+
),
|
|
25685
|
+
acceptLicense: external_exports.boolean().describe(
|
|
25686
|
+
"Required to install: you accept the Visual Studio Community licence terms (https://visualstudio.microsoft.com/license-terms/) and the DirectX End-User Runtime licence."
|
|
25687
|
+
),
|
|
25688
|
+
components: StringsSchema.describe(
|
|
25689
|
+
'More Visual Studio workload or component IDs to add, e.g. ["Microsoft.VisualStudio.Component.VC.Llvm.Clang"].'
|
|
25690
|
+
),
|
|
25691
|
+
keepInstallFiles: external_exports.boolean().describe(
|
|
25692
|
+
"Keep an offline copy of the Visual Studio install files in tools\\visualstudio (~10 GB, made once), so later boots install without downloading them again. Skipped while that disk has too little room."
|
|
25693
|
+
)
|
|
25694
|
+
}),
|
|
25680
25695
|
cpp: external_exports.strictObject({
|
|
25681
25696
|
enabled: enabled(
|
|
25682
25697
|
"MinGW-w64 GCC with CMake, Ninja, premake5 and mingw32-make (also Rust's linker).",
|
package/dist/runtime/view.js
CHANGED
|
@@ -26090,7 +26090,7 @@ var SandboxSchema = external_exports.strictObject({
|
|
|
26090
26090
|
"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."
|
|
26091
26091
|
),
|
|
26092
26092
|
vGpu: external_exports.boolean().describe(
|
|
26093
|
-
"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)."
|
|
26093
|
+
"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)."
|
|
26094
26094
|
),
|
|
26095
26095
|
networking: external_exports.boolean().describe("Internet access. false is the only hard network isolation Windows Sandbox offers."),
|
|
26096
26096
|
clipboard: external_exports.boolean().describe(
|
|
@@ -26252,6 +26252,21 @@ var ToolchainsSchema = external_exports.strictObject({
|
|
|
26252
26252
|
msvcVersion: external_exports.string().min(1).describe('"latest" or an MSVC tools version prefix, e.g. "14.44".'),
|
|
26253
26253
|
sdkVersion: external_exports.string().min(1).describe('"latest" or a Windows SDK build, e.g. "26100" or "10.0.22621".')
|
|
26254
26254
|
}),
|
|
26255
|
+
unreal: external_exports.strictObject({
|
|
26256
|
+
enabled: enabled(
|
|
26257
|
+
"Unreal Engine development: Visual Studio Community 2022 with the C++ game workload (MSVC, a Windows 11 SDK, .NET Framework targeting packs, Unreal integration and the Epic Games Launcher) and the DirectX End-User Runtime. A real installer: it runs every boot (~10 GB on the sandbox disk). The engine itself comes from the Epic Games Launcher or its source.",
|
|
26258
|
+
"a .uproject or .uplugin"
|
|
26259
|
+
),
|
|
26260
|
+
acceptLicense: external_exports.boolean().describe(
|
|
26261
|
+
"Required to install: you accept the Visual Studio Community licence terms (https://visualstudio.microsoft.com/license-terms/) and the DirectX End-User Runtime licence."
|
|
26262
|
+
),
|
|
26263
|
+
components: StringsSchema.describe(
|
|
26264
|
+
'More Visual Studio workload or component IDs to add, e.g. ["Microsoft.VisualStudio.Component.VC.Llvm.Clang"].'
|
|
26265
|
+
),
|
|
26266
|
+
keepInstallFiles: external_exports.boolean().describe(
|
|
26267
|
+
"Keep an offline copy of the Visual Studio install files in tools\\visualstudio (~10 GB, made once), so later boots install without downloading them again. Skipped while that disk has too little room."
|
|
26268
|
+
)
|
|
26269
|
+
}),
|
|
26255
26270
|
cpp: external_exports.strictObject({
|
|
26256
26271
|
enabled: enabled(
|
|
26257
26272
|
"MinGW-w64 GCC with CMake, Ninja, premake5 and mingw32-make (also Rust's linker).",
|
|
@@ -79,6 +79,13 @@ export const accountsSuite = {
|
|
|
79
79
|
settingsB.enabledPlugins['p@m'] === true &&
|
|
80
80
|
settingsB.enabledPlugins['q@m'] === false &&
|
|
81
81
|
!fs.existsSync(path.join(storage, 'accounts', 'shared-plugins', '.credentials.json')), 'on: plugins and enabledPlugins reach the other data set; its own settings win and no login travels');
|
|
82
|
+
const sentinel = path.join(storage, 'accounts', 'shared-plugins', 'plugins', 'cache', 'kept.js');
|
|
83
|
+
t.write(sentinel, 'k');
|
|
84
|
+
on.activate(dataP('p1'), 'one');
|
|
85
|
+
t.check(fs.existsSync(sentinel), 'switching with the same plugins does not copy the plugins folder again');
|
|
86
|
+
t.write(path.join(plugA, 'plugins', 'installed_plugins.json'), '{"version":2,"plugins":{"p@m":[]}}');
|
|
87
|
+
on.activate(dataP('p1'), 'one');
|
|
88
|
+
t.check(!fs.existsSync(sentinel), 'once a plugin changed, the switch refreshes the shared set');
|
|
82
89
|
t.write(path.join(plugC, 'plugins', 'installed_plugins.json'), '{}');
|
|
83
90
|
const outside = t.dir('plugin-victim');
|
|
84
91
|
t.write(path.join(outside, 'secret.txt'), 's');
|
|
@@ -5,7 +5,7 @@ import path from 'node:path';
|
|
|
5
5
|
import { DEFAULTS, mergeConfig, validateConfig } from '../core/config/index.js';
|
|
6
6
|
import { isWin } from '../core/util/index.js';
|
|
7
7
|
import { SYSTEM } from '../shared/system.js';
|
|
8
|
-
import { agentCommand, agentShims, bootResetPaths, isCopyableDatabaseFile, isDatabaseFile, localStateEntries, shimText, } from '../guest/agents/agent-files.js';
|
|
8
|
+
import { agentCommand, agentShims, bootResetPaths, codexConfigWithoutSandbox, isCopyableDatabaseFile, isDatabaseFile, localStateEntries, shimText, } from '../guest/agents/agent-files.js';
|
|
9
9
|
import { appendMissing, expandVars, isPinnedNodeDir, parseRegPath, pathKey, planPath, rebuildPath, splitPath, } from '../guest/setup/path-plan.js';
|
|
10
10
|
import { withReloadEnvironment } from '../host/tools/index.js';
|
|
11
11
|
import { HarnessSchema } from '../core/schema/index.js';
|
|
@@ -58,6 +58,17 @@ export const agentPathsSuite = {
|
|
|
58
58
|
], "codex's DPAPI-sealed sandbox users and setup marker are removed at boot (CryptUnprotectData otherwise)");
|
|
59
59
|
t.check(HarnessSchema.safeParse({ ...DEFAULTS.harnesses.codex, bootReset: ['..\\login'] }).success === false &&
|
|
60
60
|
HarnessSchema.safeParse({ ...DEFAULTS.harnesses.codex, bootReset: ['C:\\Windows'] }).success === false, 'bootReset takes only plain paths below the agent state folder');
|
|
61
|
+
t.section('codex without its own command sandbox');
|
|
62
|
+
const userToml = '[tui]\nscreen_reader_detection_done = true\n\n[windows]\nsandbox = "elevated"\n';
|
|
63
|
+
const off = codexConfigWithoutSandbox(userToml) ?? '';
|
|
64
|
+
t.check(off.split('\n').find((l) => !l.startsWith('#')) === 'sandbox_mode = "danger-full-access"' &&
|
|
65
|
+
off.endsWith(userToml), 'sandbox_mode goes above the first table, the rest of the file is kept');
|
|
66
|
+
t.check(codexConfigWithoutSandbox('') === off.slice(0, off.indexOf('\n\n') + 1), 'a missing config.toml gets just the setting');
|
|
67
|
+
t.equal([
|
|
68
|
+
codexConfigWithoutSandbox(off),
|
|
69
|
+
codexConfigWithoutSandbox('model = "o3"\nsandbox_mode = "workspace-write"\n[windows]\n'),
|
|
70
|
+
], [null, null], 'a sandbox_mode already set (by the sandbox or by the user) is left alone');
|
|
71
|
+
t.check(codexConfigWithoutSandbox('[profiles.x]\nsandbox_mode = "read-only"\n') !== null, 'a sandbox_mode inside a table does not count as the top-level one');
|
|
61
72
|
t.section('PATH planner');
|
|
62
73
|
const present = new Set(['c:\\a', 'c:\\b', 'c:\\c\\d', 'c:\\nvm\\v24.1.0']);
|
|
63
74
|
const exists = (f) => present.has(pathKey(f));
|
|
@@ -66,6 +66,13 @@ export const detectSuite = {
|
|
|
66
66
|
t.check(fresh.python.on && fresh.dotnet.on && !fresh.go.on && fresh.python.reason.includes('this PC'), 'a folder that is no project yet gets the languages this PC has, and the reason names this PC');
|
|
67
67
|
const rusty = decideToolchains({ ...tc, python: { ...tc.python, enabled: true } }, ['Cargo.toml'], []);
|
|
68
68
|
t.check(rusty.rust.on && rusty.cpp.on && rusty.python.on && rusty.python.reason === 'enabled in config', 'Rust brings its C/C++ linker; true in config always wins');
|
|
69
|
+
const game = ['ZombieGame.uproject', 'Source/ZombieGame.Target.cs'];
|
|
70
|
+
const accepted = { ...tc, unreal: { ...tc.unreal, acceptLicense: true } };
|
|
71
|
+
t.check(decideToolchains(accepted, game, []).unreal.on &&
|
|
72
|
+
decideToolchains(accepted, ['Plugins/Kit.uplugin'], []).unreal.on &&
|
|
73
|
+
!decideToolchains(accepted, ['go.mod'], []).unreal.on, 'Unreal: "auto" follows a .uproject or .uplugin');
|
|
74
|
+
const unaccepted = decideToolchains(tc, game, []).unreal;
|
|
75
|
+
t.check(!unaccepted.on && unaccepted.reason.includes('toolchains.unreal.acceptLicense'), 'Unreal is not installed until its licence is accepted, and the reason says how');
|
|
69
76
|
const resolved = resolveToolchains(tc, goProject);
|
|
70
77
|
t.check(resolved.go.enabled === true && resolved.python.enabled === false, 'the sandbox gets plain decisions instead of "auto"');
|
|
71
78
|
t.section('optional tools: Bun, uv, VS Code');
|
|
@@ -122,6 +122,11 @@ export const liveNetworkSuite = {
|
|
|
122
122
|
typeof e.id === 'number' &&
|
|
123
123
|
typeof e.provider === 'string' &&
|
|
124
124
|
typeof e.process === 'string'), 'HostTools stop-events prints a JSON list of { at, id, provider, process }', events.stdout.slice(0, 500) + events.stderr);
|
|
125
|
+
const plain = Buffer.from('a saved login').toString('base64');
|
|
126
|
+
const sealed = spawnSync(hostTools, ['protect'], { encoding: 'utf8', input: plain });
|
|
127
|
+
const opened = spawnSync(hostTools, ['unprotect'], { encoding: 'utf8', input: sealed.stdout });
|
|
128
|
+
t.check(sealed.status === 0 && sealed.stdout !== plain && opened.status === 0 && opened.stdout === plain, 'HostTools protect and unprotect round-trip through DPAPI', sealed.stderr + opened.stderr);
|
|
129
|
+
t.equal(spawnSync(hostTools, ['unprotect'], { encoding: 'utf8', input: 'not base64!' }).status, 1, 'HostTools unprotect refuses bad input');
|
|
125
130
|
t.equal(spawnSync(hostTools, ['stop-events'], { encoding: 'utf8' }).status, 2, 'HostTools without --since prints its usage');
|
|
126
131
|
},
|
|
127
132
|
};
|
|
@@ -157,6 +157,12 @@ export declare function createFixtures(t: Harness): {
|
|
|
157
157
|
msvcVersion: string;
|
|
158
158
|
sdkVersion: string;
|
|
159
159
|
};
|
|
160
|
+
unreal: {
|
|
161
|
+
enabled: boolean | "auto";
|
|
162
|
+
acceptLicense: boolean;
|
|
163
|
+
components: string[];
|
|
164
|
+
keepInstallFiles: boolean;
|
|
165
|
+
};
|
|
160
166
|
cpp: {
|
|
161
167
|
enabled: boolean | "auto";
|
|
162
168
|
flexBison: boolean;
|
|
@@ -88,6 +88,12 @@ export declare const ProjectSpecSchema: z.ZodObject<{
|
|
|
88
88
|
msvcVersion: z.ZodString;
|
|
89
89
|
sdkVersion: z.ZodString;
|
|
90
90
|
}, z.core.$strict>;
|
|
91
|
+
unreal: z.ZodObject<{
|
|
92
|
+
enabled: z.ZodUnion<readonly [z.ZodBoolean, z.ZodLiteral<"auto">]>;
|
|
93
|
+
acceptLicense: z.ZodBoolean;
|
|
94
|
+
components: z.ZodArray<z.ZodString>;
|
|
95
|
+
keepInstallFiles: z.ZodBoolean;
|
|
96
|
+
}, z.core.$strict>;
|
|
91
97
|
cpp: z.ZodObject<{
|
|
92
98
|
enabled: z.ZodUnion<readonly [z.ZodBoolean, z.ZodLiteral<"auto">]>;
|
|
93
99
|
flexBison: z.ZodBoolean;
|
|
@@ -254,6 +260,12 @@ export declare const GuestRequestSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
254
260
|
msvcVersion: z.ZodString;
|
|
255
261
|
sdkVersion: z.ZodString;
|
|
256
262
|
}, z.core.$strict>;
|
|
263
|
+
unreal: z.ZodObject<{
|
|
264
|
+
enabled: z.ZodUnion<readonly [z.ZodBoolean, z.ZodLiteral<"auto">]>;
|
|
265
|
+
acceptLicense: z.ZodBoolean;
|
|
266
|
+
components: z.ZodArray<z.ZodString>;
|
|
267
|
+
keepInstallFiles: z.ZodBoolean;
|
|
268
|
+
}, z.core.$strict>;
|
|
257
269
|
cpp: z.ZodObject<{
|
|
258
270
|
enabled: z.ZodUnion<readonly [z.ZodBoolean, z.ZodLiteral<"auto">]>;
|
|
259
271
|
flexBison: z.ZodBoolean;
|
|
@@ -440,6 +452,12 @@ export declare const GuestRequestSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
440
452
|
msvcVersion: z.ZodString;
|
|
441
453
|
sdkVersion: z.ZodString;
|
|
442
454
|
}, z.core.$strict>;
|
|
455
|
+
unreal: z.ZodObject<{
|
|
456
|
+
enabled: z.ZodUnion<readonly [z.ZodBoolean, z.ZodLiteral<"auto">]>;
|
|
457
|
+
acceptLicense: z.ZodBoolean;
|
|
458
|
+
components: z.ZodArray<z.ZodString>;
|
|
459
|
+
keepInstallFiles: z.ZodBoolean;
|
|
460
|
+
}, z.core.$strict>;
|
|
443
461
|
cpp: z.ZodObject<{
|
|
444
462
|
enabled: z.ZodUnion<readonly [z.ZodBoolean, z.ZodLiteral<"auto">]>;
|
|
445
463
|
flexBison: z.ZodBoolean;
|
|
@@ -8,9 +8,9 @@ using System.Runtime.InteropServices;
|
|
|
8
8
|
[assembly: AssemblyCompany("windows-development-sandbox (open source)")]
|
|
9
9
|
[assembly: AssemblyProduct("Windows Development Sandbox")]
|
|
10
10
|
[assembly: AssemblyCopyright("MIT License, windows-development-sandbox contributors")]
|
|
11
|
-
[assembly: AssemblyVersion("1.
|
|
12
|
-
[assembly: AssemblyFileVersion("1.
|
|
13
|
-
[assembly: AssemblyInformationalVersion("1.
|
|
11
|
+
[assembly: AssemblyVersion("1.17.3.0")]
|
|
12
|
+
[assembly: AssemblyFileVersion("1.17.3.0")]
|
|
13
|
+
[assembly: AssemblyInformationalVersion("1.17.3")]
|
|
14
14
|
[assembly: ComVisible(false)]
|
|
15
15
|
// computecore.dll and computestorage.dll are not KnownDLLs: load them from System32 only, never from the exe's folder.
|
|
16
16
|
[assembly: DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
|
|
@@ -8,7 +8,7 @@ using System.Runtime.InteropServices;
|
|
|
8
8
|
[assembly: AssemblyCompany("windows-development-sandbox (open source)")]
|
|
9
9
|
[assembly: AssemblyProduct("Windows Development Sandbox")]
|
|
10
10
|
[assembly: AssemblyCopyright("MIT License, windows-development-sandbox contributors")]
|
|
11
|
-
[assembly: AssemblyVersion("1.
|
|
12
|
-
[assembly: AssemblyFileVersion("1.
|
|
13
|
-
[assembly: AssemblyInformationalVersion("1.
|
|
11
|
+
[assembly: AssemblyVersion("1.17.3.0")]
|
|
12
|
+
[assembly: AssemblyFileVersion("1.17.3.0")]
|
|
13
|
+
[assembly: AssemblyInformationalVersion("1.17.3")]
|
|
14
14
|
[assembly: ComVisible(false)]
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
// user-path --add|--remove D D first on, or off, your PATH; exit 3 when PATH would be too long
|
|
9
9
|
// web-helper --pipe P --server-pid N Windows sign-in for the web UI (WebHelper.cs), until stdin closes
|
|
10
10
|
// door-client --owner USER another user's side of that sign-in: prints the answer
|
|
11
|
+
// protect | unprotect DPAPI for the current user (Protect.cs): base64 on stdin, base64 on stdout
|
|
11
12
|
using System;
|
|
12
13
|
using System.Collections.Generic;
|
|
13
14
|
using System.Diagnostics;
|
|
@@ -112,6 +113,10 @@ static class Program
|
|
|
112
113
|
return Usage();
|
|
113
114
|
}
|
|
114
115
|
return AgentSandbox.WebHelper.Client(value);
|
|
116
|
+
case "protect":
|
|
117
|
+
return AgentSandbox.Protect.Run(true);
|
|
118
|
+
case "unprotect":
|
|
119
|
+
return AgentSandbox.Protect.Run(false);
|
|
115
120
|
default:
|
|
116
121
|
return Usage();
|
|
117
122
|
}
|
|
@@ -119,7 +124,7 @@ static class Program
|
|
|
119
124
|
|
|
120
125
|
static int Usage()
|
|
121
126
|
{
|
|
122
|
-
Console.Error.WriteLine("Usage: HostTools keep-awake --owner-pid N | stop-events --since <ISO time> | memory-status | hide-window --wait S | show-window [--handles a,b] | user-path --add|--remove <folder> | web-helper --pipe P --server-pid N | door-client --owner USER");
|
|
127
|
+
Console.Error.WriteLine("Usage: HostTools keep-awake --owner-pid N | stop-events --since <ISO time> | memory-status | hide-window --wait S | show-window [--handles a,b] | user-path --add|--remove <folder> | web-helper --pipe P --server-pid N | door-client --owner USER | protect | unprotect");
|
|
123
128
|
return 2;
|
|
124
129
|
}
|
|
125
130
|
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// HostTools protect / unprotect: Windows DPAPI for the current user, as native\scripts\protect-data.ps1 does it (same
|
|
2
|
+
// entropy, same format), without starting PowerShell. Standard input: base64 of the bytes; standard output: base64 of
|
|
3
|
+
// the result. Nothing goes on the command line or to disk.
|
|
4
|
+
using System;
|
|
5
|
+
using System.IO;
|
|
6
|
+
using System.Security.Cryptography;
|
|
7
|
+
using System.Text;
|
|
8
|
+
|
|
9
|
+
namespace AgentSandbox
|
|
10
|
+
{
|
|
11
|
+
static class Protect
|
|
12
|
+
{
|
|
13
|
+
/// <summary>The fixed extra secret of protect-data.ps1: another program that calls DPAPI without it cannot open these.</summary>
|
|
14
|
+
private const string Entropy = "agent-sandbox/secret-store/v1";
|
|
15
|
+
|
|
16
|
+
public static int Run(bool protect)
|
|
17
|
+
{
|
|
18
|
+
try
|
|
19
|
+
{
|
|
20
|
+
string text;
|
|
21
|
+
using (Stream input = Console.OpenStandardInput())
|
|
22
|
+
using (StreamReader reader = new StreamReader(input, Encoding.ASCII))
|
|
23
|
+
{
|
|
24
|
+
text = reader.ReadToEnd().Trim();
|
|
25
|
+
}
|
|
26
|
+
byte[] data = Convert.FromBase64String(text);
|
|
27
|
+
byte[] entropy = Encoding.UTF8.GetBytes(Entropy);
|
|
28
|
+
byte[] result = protect
|
|
29
|
+
? ProtectedData.Protect(data, entropy, DataProtectionScope.CurrentUser)
|
|
30
|
+
: ProtectedData.Unprotect(data, entropy, DataProtectionScope.CurrentUser);
|
|
31
|
+
Console.Out.Write(Convert.ToBase64String(result));
|
|
32
|
+
return 0;
|
|
33
|
+
}
|
|
34
|
+
catch (Exception e)
|
|
35
|
+
{
|
|
36
|
+
Console.Error.WriteLine(e.Message);
|
|
37
|
+
return 1;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -9,7 +9,7 @@ using System.Runtime.InteropServices;
|
|
|
9
9
|
[assembly: AssemblyCompany("windows-development-sandbox (open source)")]
|
|
10
10
|
[assembly: AssemblyProduct("Windows Development Sandbox")]
|
|
11
11
|
[assembly: AssemblyCopyright("MIT License, windows-development-sandbox contributors")]
|
|
12
|
-
[assembly: AssemblyVersion("1.
|
|
13
|
-
[assembly: AssemblyFileVersion("1.
|
|
14
|
-
[assembly: AssemblyInformationalVersion("1.
|
|
12
|
+
[assembly: AssemblyVersion("1.17.3.0")]
|
|
13
|
+
[assembly: AssemblyFileVersion("1.17.3.0")]
|
|
14
|
+
[assembly: AssemblyInformationalVersion("1.17.3")]
|
|
15
15
|
[assembly: ComVisible(false)]
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "windows-development-sandbox",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.17.3",
|
|
4
4
|
"description": "A disposable Windows Sandbox for development, with or without an AI agent (Claude Code, Codex, Gemini, opencode, ...): the folder you run it from is the workspace, toolchains and databases for your project install themselves, and nothing else on your PC is reachable.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -208,7 +208,7 @@
|
|
|
208
208
|
},
|
|
209
209
|
"vGpu": {
|
|
210
210
|
"type": "boolean",
|
|
211
|
-
"description": "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)."
|
|
211
|
+
"description": "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)."
|
|
212
212
|
},
|
|
213
213
|
"networking": {
|
|
214
214
|
"type": "boolean",
|
|
@@ -676,6 +676,39 @@
|
|
|
676
676
|
},
|
|
677
677
|
"additionalProperties": false
|
|
678
678
|
},
|
|
679
|
+
"unreal": {
|
|
680
|
+
"type": "object",
|
|
681
|
+
"properties": {
|
|
682
|
+
"enabled": {
|
|
683
|
+
"anyOf": [
|
|
684
|
+
{
|
|
685
|
+
"type": "boolean"
|
|
686
|
+
},
|
|
687
|
+
{
|
|
688
|
+
"type": "string",
|
|
689
|
+
"const": "auto"
|
|
690
|
+
}
|
|
691
|
+
],
|
|
692
|
+
"description": "Unreal Engine development: Visual Studio Community 2022 with the C++ game workload (MSVC, a Windows 11 SDK, .NET Framework targeting packs, Unreal integration and the Epic Games Launcher) and the DirectX End-User Runtime. A real installer: it runs every boot (~10 GB on the sandbox disk). The engine itself comes from the Epic Games Launcher or its source. true, false, or \"auto\" = only when the project has a .uproject or .uplugin."
|
|
693
|
+
},
|
|
694
|
+
"acceptLicense": {
|
|
695
|
+
"type": "boolean",
|
|
696
|
+
"description": "Required to install: you accept the Visual Studio Community licence terms (https://visualstudio.microsoft.com/license-terms/) and the DirectX End-User Runtime licence."
|
|
697
|
+
},
|
|
698
|
+
"components": {
|
|
699
|
+
"type": "array",
|
|
700
|
+
"items": {
|
|
701
|
+
"type": "string"
|
|
702
|
+
},
|
|
703
|
+
"description": "More Visual Studio workload or component IDs to add, e.g. [\"Microsoft.VisualStudio.Component.VC.Llvm.Clang\"]."
|
|
704
|
+
},
|
|
705
|
+
"keepInstallFiles": {
|
|
706
|
+
"type": "boolean",
|
|
707
|
+
"description": "Keep an offline copy of the Visual Studio install files in tools\\visualstudio (~10 GB, made once), so later boots install without downloading them again. Skipped while that disk has too little room."
|
|
708
|
+
}
|
|
709
|
+
},
|
|
710
|
+
"additionalProperties": false
|
|
711
|
+
},
|
|
679
712
|
"cpp": {
|
|
680
713
|
"type": "object",
|
|
681
714
|
"properties": {
|
|
@@ -109,7 +109,7 @@
|
|
|
109
109
|
},
|
|
110
110
|
"vGpu": {
|
|
111
111
|
"type": "boolean",
|
|
112
|
-
"description": "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)."
|
|
112
|
+
"description": "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)."
|
|
113
113
|
},
|
|
114
114
|
"networking": {
|
|
115
115
|
"type": "boolean",
|
|
@@ -430,6 +430,39 @@
|
|
|
430
430
|
},
|
|
431
431
|
"additionalProperties": false
|
|
432
432
|
},
|
|
433
|
+
"unreal": {
|
|
434
|
+
"type": "object",
|
|
435
|
+
"properties": {
|
|
436
|
+
"enabled": {
|
|
437
|
+
"anyOf": [
|
|
438
|
+
{
|
|
439
|
+
"type": "boolean"
|
|
440
|
+
},
|
|
441
|
+
{
|
|
442
|
+
"type": "string",
|
|
443
|
+
"const": "auto"
|
|
444
|
+
}
|
|
445
|
+
],
|
|
446
|
+
"description": "Unreal Engine development: Visual Studio Community 2022 with the C++ game workload (MSVC, a Windows 11 SDK, .NET Framework targeting packs, Unreal integration and the Epic Games Launcher) and the DirectX End-User Runtime. A real installer: it runs every boot (~10 GB on the sandbox disk). The engine itself comes from the Epic Games Launcher or its source. true, false, or \"auto\" = only when the project has a .uproject or .uplugin."
|
|
447
|
+
},
|
|
448
|
+
"acceptLicense": {
|
|
449
|
+
"type": "boolean",
|
|
450
|
+
"description": "Required to install: you accept the Visual Studio Community licence terms (https://visualstudio.microsoft.com/license-terms/) and the DirectX End-User Runtime licence."
|
|
451
|
+
},
|
|
452
|
+
"components": {
|
|
453
|
+
"type": "array",
|
|
454
|
+
"items": {
|
|
455
|
+
"type": "string"
|
|
456
|
+
},
|
|
457
|
+
"description": "More Visual Studio workload or component IDs to add, e.g. [\"Microsoft.VisualStudio.Component.VC.Llvm.Clang\"]."
|
|
458
|
+
},
|
|
459
|
+
"keepInstallFiles": {
|
|
460
|
+
"type": "boolean",
|
|
461
|
+
"description": "Keep an offline copy of the Visual Studio install files in tools\\visualstudio (~10 GB, made once), so later boots install without downloading them again. Skipped while that disk has too little room."
|
|
462
|
+
}
|
|
463
|
+
},
|
|
464
|
+
"additionalProperties": false
|
|
465
|
+
},
|
|
433
466
|
"cpp": {
|
|
434
467
|
"type": "object",
|
|
435
468
|
"properties": {
|