windows-development-sandbox 1.11.3 → 1.11.4

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.
@@ -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.11.3.0")]
12
- [assembly: AssemblyFileVersion("1.11.3.0")]
13
- [assembly: AssemblyInformationalVersion("1.11.3")]
11
+ [assembly: AssemblyVersion("1.11.4.0")]
12
+ [assembly: AssemblyFileVersion("1.11.4.0")]
13
+ [assembly: AssemblyInformationalVersion("1.11.4")]
14
14
  [assembly: ComVisible(false)]
@@ -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.11.3.0")]
12
- [assembly: AssemblyFileVersion("1.11.3.0")]
13
- [assembly: AssemblyInformationalVersion("1.11.3")]
11
+ [assembly: AssemblyVersion("1.11.4.0")]
12
+ [assembly: AssemblyFileVersion("1.11.4.0")]
13
+ [assembly: AssemblyInformationalVersion("1.11.4")]
14
14
  [assembly: ComVisible(false)]
@@ -6,6 +6,7 @@ using System.ComponentModel;
6
6
  using System.Diagnostics;
7
7
  using System.Globalization;
8
8
  using System.Runtime.InteropServices;
9
+ using System.Threading;
9
10
  using Microsoft.Win32;
10
11
 
11
12
  namespace AgentSandbox
@@ -108,18 +109,73 @@ namespace AgentSandbox
108
109
  {
109
110
  try
110
111
  {
111
- using (PerformanceCounter counter = new PerformanceCounter("PhysicalDisk", "Current Disk Queue Length", "_Total", true))
112
+ // Made once and kept: creating a performance counter costs far more than reading one.
113
+ if (diskCounter == null && !noDiskCounter)
112
114
  {
113
- return ",\"diskQueue\":" + Math.Round(counter.NextValue()).ToString("0", CultureInfo.InvariantCulture);
115
+ diskCounter = new PerformanceCounter("PhysicalDisk", "Current Disk Queue Length", "_Total", true);
114
116
  }
117
+ if (diskCounter == null)
118
+ {
119
+ return "";
120
+ }
121
+ return ",\"diskQueue\":" + Math.Round(diskCounter.NextValue()).ToString("0", CultureInfo.InvariantCulture);
115
122
  }
116
123
  catch (Exception)
117
124
  {
118
125
  // No performance counters on this PC: the watchdog then looks at memory and CPU only.
126
+ noDiskCounter = true;
127
+ diskCounter = null;
119
128
  return "";
120
129
  }
121
130
  }
122
131
 
132
+ private static PerformanceCounter diskCounter;
133
+ private static bool noDiskCounter;
134
+ private static volatile bool inputClosed;
135
+
136
+ /// <summary>
137
+ /// memory-status --serve S: one JSON line every S seconds until stdin closes (the watcher keeps one of these
138
+ /// instead of starting a program every few seconds). Returns the exit code.
139
+ /// </summary>
140
+ public static int Serve(int seconds)
141
+ {
142
+ Thread reader = new Thread(WaitForInputToClose);
143
+ reader.IsBackground = true;
144
+ reader.Start();
145
+ while (!inputClosed)
146
+ {
147
+ try
148
+ {
149
+ Console.Out.WriteLine(Json());
150
+ Console.Out.Flush();
151
+ }
152
+ catch (Exception)
153
+ {
154
+ // One reading that fails is skipped; the next one tries again.
155
+ }
156
+ for (int waited = 0; waited < seconds * 10 && !inputClosed; waited++)
157
+ {
158
+ Thread.Sleep(100);
159
+ }
160
+ }
161
+ return 0;
162
+ }
163
+
164
+ private static void WaitForInputToClose()
165
+ {
166
+ try
167
+ {
168
+ while (Console.In.ReadLine() != null)
169
+ {
170
+ }
171
+ }
172
+ catch (Exception)
173
+ {
174
+ // A broken input counts as closed.
175
+ }
176
+ inputClosed = true;
177
+ }
178
+
123
179
  private static string Mb(ulong bytes)
124
180
  {
125
181
  return Math.Floor(bytes / BytesPerMb).ToString("0", CultureInfo.InvariantCulture);
@@ -1,7 +1,8 @@
1
1
  // HostTools.exe: what the host side asks of Windows without PowerShell. Built on first use by host/native.ts (csc).
2
2
  // keep-awake --owner-pid N this PC stays awake until process N ends (sandbox.keepAwake)
3
3
  // stop-events --since <iso> the Windows events since then that can end a sandbox, as JSON (host/life)
4
- // memory-status this PC's RAM and commit (what a sandbox's memory is charged against), as JSON
4
+ // memory-status [--serve S] this PC's RAM and commit (what a sandbox's memory is charged against), as JSON; with
5
+ // --serve one line every S seconds until stdin closes
5
6
  // hide-window --wait S hides the sandbox window once it appears; prints the hidden handles as JSON
6
7
  // show-window --handles a,b shows those windows (else any sandbox window); prints how many
7
8
  // user-path --add|--remove D D first on, or off, your PATH; exit 3 when PATH would be too long
@@ -42,6 +43,11 @@ static class Program
42
43
  Console.Out.Write(StopEventsJson(since));
43
44
  return 0;
44
45
  case "memory-status":
46
+ int every;
47
+ if (args.Length >= 3 && args[1] == "--serve" && int.TryParse(args[2], out every) && every >= 1 && every <= 3600)
48
+ {
49
+ return AgentSandbox.HostMemory.Serve(every);
50
+ }
45
51
  try
46
52
  {
47
53
  Console.Out.Write(AgentSandbox.HostMemory.Json());
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "windows-development-sandbox",
3
- "version": "1.11.3",
3
+ "version": "1.11.4",
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",