windows-development-sandbox 1.14.0 → 1.15.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/config.example.json +2 -1
- package/dist/app/features/defs.d.ts +1 -1
- package/dist/app/features/projects/projects.def.d.ts +1 -1
- package/dist/app/features/projects/projects.run.d.ts +1 -1
- package/dist/app/features/projects/projects.run.js +10 -2
- package/dist/app/features/sandbox/sandbox.def.js +3 -1
- package/dist/app/features/settings/categories.def.js +1 -0
- package/dist/bin/agent-sandbox.js +2 -2
- package/dist/bin/{chunk-BQ23GBLC.js → chunk-D7CM63BS.js} +1893 -1405
- package/dist/bin/{chunk-F7IMME5G.js → chunk-HTQT5SBY.js} +1 -1
- package/dist/bin/{chunk-LQHEUN2A.js → chunk-RQ4BWBYX.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/projects/here.js +2 -0
- package/dist/cli/services/health-service.js +15 -3
- package/dist/cli/services/projects-service.d.ts +8 -3
- package/dist/cli/services/projects-service.js +21 -4
- package/dist/core/config/defaults.js +1 -0
- package/dist/core/schema/config.d.ts +4 -0
- package/dist/core/schema/projects.d.ts +4 -0
- package/dist/core/schema/projects.js +3 -0
- package/dist/guest/boot/boot.js +8 -2
- package/dist/guest/daemon/daemon.js +3 -0
- package/dist/guest/daemon/live-folders.d.ts +48 -0
- package/dist/guest/daemon/live-folders.js +245 -0
- package/dist/guest/daemon/live.d.ts +4 -0
- package/dist/guest/daemon/live.js +57 -0
- package/dist/guest/entries/daemon.js +4 -2
- package/dist/guest/runtime/csc.d.ts +1 -0
- package/dist/guest/runtime/csc.js +1 -0
- package/dist/guest/runtime/secrets.d.ts +5 -2
- package/dist/guest/runtime/secrets.js +12 -5
- package/dist/host/engines/hcs/live-folders.d.ts +117 -0
- package/dist/host/engines/hcs/live-folders.js +347 -0
- package/dist/host/engines/index.d.ts +1 -0
- package/dist/host/engines/index.js +1 -0
- package/dist/host/launch/generate.js +8 -1
- package/dist/host/projects/join.d.ts +4 -0
- package/dist/host/projects/join.js +11 -3
- package/dist/host/projects/mapper.d.ts +34 -5
- package/dist/host/projects/mapper.js +88 -20
- package/dist/host/projects/registry.d.ts +2 -0
- package/dist/host/projects/registry.js +1 -1
- package/dist/host/secrets/launch-secrets.js +2 -1
- package/dist/runtime/agent.js +14 -0
- package/dist/runtime/daemon.js +466 -132
- package/dist/runtime/db.js +14 -0
- package/dist/runtime/main.js +26 -3
- package/dist/runtime/netproxy.js +14 -0
- package/dist/runtime/view.js +14 -0
- package/dist/selftest/index.js +2 -0
- package/dist/selftest/layout.test.js +1 -0
- package/dist/selftest/live-folders.test.d.ts +2 -0
- package/dist/selftest/live-folders.test.js +588 -0
- package/dist/selftest/projects.test.js +7 -7
- package/dist/selftest/support/engine-golden.js +1 -0
- package/dist/selftest/support/fixtures.d.ts +1 -0
- package/dist/selftest/support/live.js +2 -0
- package/dist/shared/channel/index.d.ts +1 -0
- package/dist/shared/channel/index.js +1 -0
- package/dist/shared/channel/live.d.ts +53 -0
- package/dist/shared/channel/live.js +92 -0
- package/dist/shared/channel/run-dir.d.ts +5 -0
- package/dist/shared/channel/run-dir.js +11 -0
- package/dist/shared/channel/secrets.d.ts +1 -0
- package/dist/shared/channel/secrets.js +5 -0
- package/dist/shared/paths/projects.d.ts +6 -1
- package/dist/shared/paths/projects.js +21 -1
- package/dist/sync/watcher.js +9 -0
- package/dist/web/index.html +1 -1
- package/dist/web/{main-6XNBTJLT.js → main-7DJZ2M27.js} +1 -1
- package/native/csharp/HcsHost/AssemblyInfo.cs +4 -4
- package/native/csharp/HcsHost/FolderAccess.cs +361 -0
- package/native/csharp/HcsHost/Hcs.cs +31 -3
- package/native/csharp/HcsHost/Program.cs +54 -6
- package/native/csharp/HcsHost/Share.cs +64 -11
- package/native/csharp/HcsHost/WsbGuard.cs +130 -0
- package/native/csharp/HcsHost/WsbShare.cs +295 -0
- package/native/csharp/HostTools/AssemblyInfo.cs +3 -3
- package/native/csharp/StorageHelper/AssemblyInfo.cs +3 -3
- package/native/scripts/contained-common.ps1 +4 -0
- package/native/scripts/hcs-live-share.ps1 +191 -0
- package/package.json +1 -1
- package/sandbox/csharp/BindMount.cs +120 -0
- package/schemas/config.schema.json +8 -0
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
// Live folders, guest side (docs/design/hcs-live-folders.md): shows a vSMB share the host added to this running sandbox
|
|
2
|
+
// at C:\Workspace\<name> with the bind filter, the way Windows Sandbox's own guest agent shows .wsb mapped folders, so
|
|
3
|
+
// tools see a plain folder (not a link). Run by the session daemon (an administrator) by path; compiled inside the
|
|
4
|
+
// sandbox with the .NET Framework csc.exe (C# 5). Verbs (exit 0 = done, 1 = failed, 2 = refused, 3 = no such share yet):
|
|
5
|
+
// BindMount map <C:\Workspace\name> <agentsbx-share> [rw] the folder shows the share (read-only unless rw)
|
|
6
|
+
// BindMount unmap <C:\Workspace\name> removes that mapping again
|
|
7
|
+
// BindMount mapped <C:\Workspace\name> exit 0 when the bind filter has a mapping there, else 4
|
|
8
|
+
// Only share names with this tool's prefix and only C:\Workspace\<plain name> (no dots or spaces, so no "..", "foo."
|
|
9
|
+
// or "foo " aliases of other folders), so it can never re-point a folder Windows Sandbox mapped. Flag names and the
|
|
10
|
+
// BfGetMappings layout: go-winio pkg/bindfilter (vendored in microsoft/hcsshim) and BuildXL's NativeContainerUtilities.
|
|
11
|
+
using System;
|
|
12
|
+
using System.IO;
|
|
13
|
+
using System.Runtime.InteropServices;
|
|
14
|
+
using System.Text;
|
|
15
|
+
using System.Text.RegularExpressions;
|
|
16
|
+
|
|
17
|
+
static class BindMount
|
|
18
|
+
{
|
|
19
|
+
private const string VsmbRoot = "\\\\?\\GLOBALROOT\\Device\\vmsmb\\VSMB-{dcc079ae-60ba-4d07-847c-3493609c0870}\\";
|
|
20
|
+
private const uint ReadOnlyMapping = 0x1;
|
|
21
|
+
private const uint NoMultipleTargets = 0x40;
|
|
22
|
+
private const uint GetMappingsVolume = 0x1;
|
|
23
|
+
/// <summary>
|
|
24
|
+
/// A share that has not arrived: ERROR_NOT_FOUND (seen in a Windows Sandbox, 2026-10-23, with C:\Workspace there) or
|
|
25
|
+
/// ERROR_FILE_NOT_FOUND (what the design note recorded; also the answer when C:\Workspace itself is missing).
|
|
26
|
+
/// </summary>
|
|
27
|
+
private const int NotFound = unchecked((int)0x80070490);
|
|
28
|
+
private const int FileNotFound = unchecked((int)0x80070002);
|
|
29
|
+
private const int ExitOk = 0;
|
|
30
|
+
private const int ExitFailed = 1;
|
|
31
|
+
private const int ExitRefused = 2;
|
|
32
|
+
private const int ExitNoShare = 3;
|
|
33
|
+
private const int ExitNotMapped = 4;
|
|
34
|
+
private static readonly Regex ShareName = new Regex("^agentsbx-[0-9a-f]{8,32}$");
|
|
35
|
+
private static readonly Regex GuestFolder = new Regex("^C:\\\\Workspace\\\\[a-z0-9][a-z0-9_-]{0,63}$", RegexOptions.IgnoreCase);
|
|
36
|
+
|
|
37
|
+
private static class NativeMethods
|
|
38
|
+
{
|
|
39
|
+
[DllImport("bindfltapi.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
|
|
40
|
+
public static extern int BfSetupFilter(IntPtr job, uint flags, string virtRoot, string target, IntPtr exceptions, uint exceptionCount);
|
|
41
|
+
|
|
42
|
+
[DllImport("bindfltapi.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
|
|
43
|
+
public static extern int BfRemoveMapping(IntPtr job, string virtRoot);
|
|
44
|
+
|
|
45
|
+
[DllImport("bindfltapi.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
|
|
46
|
+
public static extern int BfGetMappings(uint flags, IntPtr job, string virtRoot, IntPtr sid, ref uint bufferSize, byte[] buffer);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
static int Main(string[] args)
|
|
50
|
+
{
|
|
51
|
+
if ((args.Length == 3 || args.Length == 4) && args[0] == "map")
|
|
52
|
+
{
|
|
53
|
+
if (!GuestFolder.IsMatch(args[1]) || !ShareName.IsMatch(args[2]) || (args.Length == 4 && args[3] != "rw"))
|
|
54
|
+
{
|
|
55
|
+
Console.WriteLine("Refused: map C:\\Workspace\\<plain name> to an agentsbx- share only");
|
|
56
|
+
return ExitRefused;
|
|
57
|
+
}
|
|
58
|
+
if (Directory.Exists(args[1]) || File.Exists(args[1]))
|
|
59
|
+
{
|
|
60
|
+
Console.WriteLine("Refused: " + args[1] + " exists already");
|
|
61
|
+
return ExitRefused;
|
|
62
|
+
}
|
|
63
|
+
uint flags = NoMultipleTargets | (args.Length == 4 ? 0u : ReadOnlyMapping);
|
|
64
|
+
int hr = NativeMethods.BfSetupFilter(IntPtr.Zero, flags, args[1], VsmbRoot + args[2] + "\\", IntPtr.Zero, 0);
|
|
65
|
+
Console.WriteLine("BfSetupFilter 0x" + hr.ToString("X8"));
|
|
66
|
+
return hr == 0 ? ExitOk : (hr == NotFound || hr == FileNotFound ? ExitNoShare : ExitFailed);
|
|
67
|
+
}
|
|
68
|
+
if (args.Length == 2 && (args[0] == "unmap" || args[0] == "mapped"))
|
|
69
|
+
{
|
|
70
|
+
if (!GuestFolder.IsMatch(args[1]))
|
|
71
|
+
{
|
|
72
|
+
Console.WriteLine("Refused: only C:\\Workspace\\<plain name>");
|
|
73
|
+
return ExitRefused;
|
|
74
|
+
}
|
|
75
|
+
if (args[0] == "mapped")
|
|
76
|
+
{
|
|
77
|
+
bool found;
|
|
78
|
+
int listed = HasMapping(args[1], out found);
|
|
79
|
+
Console.WriteLine("BfGetMappings 0x" + listed.ToString("X8") + (found ? " mapped" : " not mapped"));
|
|
80
|
+
return listed != 0 ? ExitFailed : (found ? ExitOk : ExitNotMapped);
|
|
81
|
+
}
|
|
82
|
+
int hr = NativeMethods.BfRemoveMapping(IntPtr.Zero, args[1]);
|
|
83
|
+
Console.WriteLine("BfRemoveMapping 0x" + hr.ToString("X8"));
|
|
84
|
+
return hr == 0 ? ExitOk : ExitFailed;
|
|
85
|
+
}
|
|
86
|
+
Console.WriteLine("Usage: BindMount map <folder> <share> [rw] | unmap <folder> | mapped <folder>");
|
|
87
|
+
return ExitRefused;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/// <summary>Whether the bind filter has a mapping whose virtual root is `folder` (BfGetMappings on C:).</summary>
|
|
91
|
+
private static int HasMapping(string folder, out bool found)
|
|
92
|
+
{
|
|
93
|
+
found = false;
|
|
94
|
+
uint size = 1024 * 1024;
|
|
95
|
+
byte[] buffer = new byte[size];
|
|
96
|
+
int hr = NativeMethods.BfGetMappings(GetMappingsVolume, IntPtr.Zero, "C:\\", IntPtr.Zero, ref size, buffer);
|
|
97
|
+
if (hr != 0 || size < 12)
|
|
98
|
+
{
|
|
99
|
+
return hr != 0 ? hr : ExitFailed;
|
|
100
|
+
}
|
|
101
|
+
uint count = BitConverter.ToUInt32(buffer, 8);
|
|
102
|
+
string wanted = "\\" + folder.Substring(3).TrimEnd('\\');
|
|
103
|
+
for (int i = 0; i < count && 12 + (i * 20) + 20 <= buffer.Length; i++)
|
|
104
|
+
{
|
|
105
|
+
int entry = 12 + (i * 20);
|
|
106
|
+
uint length = BitConverter.ToUInt32(buffer, entry);
|
|
107
|
+
uint offset = BitConverter.ToUInt32(buffer, entry + 4);
|
|
108
|
+
if (offset + length > buffer.Length)
|
|
109
|
+
{
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
string root = Encoding.Unicode.GetString(buffer, (int)offset, (int)length).TrimEnd('\\');
|
|
113
|
+
if (root.EndsWith(wanted, StringComparison.OrdinalIgnoreCase))
|
|
114
|
+
{
|
|
115
|
+
found = true;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return 0;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
@@ -1801,6 +1801,14 @@
|
|
|
1801
1801
|
"wsbShare": {
|
|
1802
1802
|
"type": "boolean",
|
|
1803
1803
|
"description": "On Windows 11 24H2+ with the Windows Sandbox command line (wsb), add other folders to the running sandbox with `wsb share` (untested). Otherwise starting a project outside every root offers a restart."
|
|
1804
|
+
},
|
|
1805
|
+
"liveFolders": {
|
|
1806
|
+
"type": "string",
|
|
1807
|
+
"enum": [
|
|
1808
|
+
"off",
|
|
1809
|
+
"hcs"
|
|
1810
|
+
],
|
|
1811
|
+
"description": "ALPHA, UNTESTED ON A REAL PC: \"hcs\" adds a project folder to the running sandbox through the Host Compute Service where `wsb share` is missing (one administrator prompt per add or remove; always read-only in this alpha). If it fails, the sandbox may close: save your work first. Turn it on before the sandbox starts. \"off\" (default) offers a restart instead. The real-PC tests still to pass are in docs/design/hcs-live-folders.md (\"Test plan\")."
|
|
1804
1812
|
}
|
|
1805
1813
|
},
|
|
1806
1814
|
"additionalProperties": false,
|