windows-development-sandbox 1.18.2 → 1.18.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.
Files changed (98) hide show
  1. package/config.example.json +1 -1
  2. package/dist/app/features/defs.d.ts +26 -0
  3. package/dist/app/features/defs.js +2 -1
  4. package/dist/app/features/sandbox/sandbox.def.d.ts +34 -0
  5. package/dist/app/features/sandbox/sandbox.def.js +52 -10
  6. package/dist/app/features/sandbox/sandbox.run.d.ts +24 -0
  7. package/dist/app/features/sandbox/sandbox.run.js +45 -1
  8. package/dist/app/registry.js +2 -1
  9. package/dist/bin/agent-sandbox.js +2 -2
  10. package/dist/bin/{chunk-MQIA7GNB.js → chunk-FRPLQLSY.js} +3188 -2765
  11. package/dist/bin/{chunk-M4OM632I.js → chunk-MY7NLQQY.js} +1 -1
  12. package/dist/bin/{chunk-IIHL7W6B.js → chunk-N4GXYTLV.js} +1 -1
  13. package/dist/bin/claude-host.js +2 -2
  14. package/dist/bin/claude-sbx.js +2 -2
  15. package/dist/bin/codex-sbx.js +2 -2
  16. package/dist/bin/gemini-sbx.js +2 -2
  17. package/dist/bin/sandbox.js +2 -2
  18. package/dist/bin/sbx-hide.js +2 -2
  19. package/dist/bin/sbx-show.js +2 -2
  20. package/dist/cli/commands/launch/launch.js +4 -1
  21. package/dist/cli/commands/launch/leftover-offer.d.ts +3 -0
  22. package/dist/cli/commands/launch/leftover-offer.js +26 -0
  23. package/dist/cli/commands/repair/checks/sandbox.d.ts +3 -1
  24. package/dist/cli/commands/repair/checks/sandbox.js +53 -2
  25. package/dist/core/config/defaults.js +1 -1
  26. package/dist/core/schema/sandbox.js +1 -1
  27. package/dist/core/schema/toolchains.js +2 -2
  28. package/dist/guest/daemon/daemon.js +1 -1
  29. package/dist/guest/daemon/heartbeat.d.ts +11 -0
  30. package/dist/guest/daemon/heartbeat.js +59 -0
  31. package/dist/guest/daemon/idle-shutdown.js +2 -0
  32. package/dist/guest/entries/daemon.js +2 -0
  33. package/dist/guest/governor/core.d.ts +19 -1
  34. package/dist/guest/governor/core.js +23 -1
  35. package/dist/guest/governor/decide.d.ts +14 -0
  36. package/dist/guest/governor/decide.js +52 -7
  37. package/dist/guest/governor/governor.d.ts +4 -1
  38. package/dist/guest/governor/governor.js +9 -2
  39. package/dist/guest/toolchains/native/rust-extras.d.ts +7 -0
  40. package/dist/guest/toolchains/native/rust-extras.js +26 -3
  41. package/dist/guest/toolchains/plan.js +6 -4
  42. package/dist/host/channel/channel.d.ts +1 -1
  43. package/dist/host/channel/channel.js +10 -2
  44. package/dist/host/health/index.d.ts +1 -0
  45. package/dist/host/health/index.js +1 -0
  46. package/dist/host/health/leftovers.d.ts +3 -0
  47. package/dist/host/health/leftovers.js +40 -0
  48. package/dist/host/health/stale.d.ts +48 -0
  49. package/dist/host/health/stale.js +40 -0
  50. package/dist/host/launch/wsb-file.d.ts +6 -1
  51. package/dist/host/launch/wsb-file.js +9 -5
  52. package/dist/host/life/crash-report.d.ts +3 -1
  53. package/dist/host/life/crash-report.js +9 -3
  54. package/dist/host/life/index.d.ts +1 -0
  55. package/dist/host/life/index.js +1 -0
  56. package/dist/host/life/last-end.d.ts +28 -0
  57. package/dist/host/life/last-end.js +91 -0
  58. package/dist/host/life/life-record.d.ts +3 -0
  59. package/dist/host/life/life-record.js +2 -2
  60. package/dist/host/life/stop-events.d.ts +3 -1
  61. package/dist/host/life/stop-events.js +59 -0
  62. package/dist/host/life/stop-warning.js +3 -0
  63. package/dist/host/life/watchdog.d.ts +2 -0
  64. package/dist/host/life/watchdog.js +8 -2
  65. package/dist/host/sandbox/cleanup.d.ts +37 -0
  66. package/dist/host/sandbox/cleanup.js +82 -0
  67. package/dist/host/sandbox/index.d.ts +1 -0
  68. package/dist/host/sandbox/index.js +1 -0
  69. package/dist/host/sandbox/platform.js +1 -1
  70. package/dist/runtime/agent.js +28 -3
  71. package/dist/runtime/daemon.js +629 -479
  72. package/dist/runtime/db.js +28 -3
  73. package/dist/runtime/main.js +59 -11
  74. package/dist/runtime/netproxy.js +28 -3
  75. package/dist/runtime/tool.js +28 -3
  76. package/dist/runtime/view.js +28 -3
  77. package/dist/selftest/heavy-load.test.js +212 -14
  78. package/dist/selftest/live-terminal.test.js +4 -0
  79. package/dist/shared/channel/run-dir.d.ts +4 -1
  80. package/dist/shared/channel/run-dir.js +7 -1
  81. package/dist/shared/channel/schema.d.ts +24 -0
  82. package/dist/shared/channel/schema.js +22 -0
  83. package/dist/shared/memory/policy.d.ts +10 -0
  84. package/dist/shared/memory/policy.js +17 -1
  85. package/dist/shared/system.d.ts +1 -0
  86. package/dist/shared/system.js +1 -0
  87. package/dist/sync/watcher.js +10 -5
  88. package/dist/web/index.html +1 -1
  89. package/dist/web/{main-CWIF4VQI.js → main-GVZWWP4I.js} +63 -63
  90. package/native/csharp/HcsHost/AssemblyInfo.cs +3 -3
  91. package/native/csharp/HostTools/AssemblyInfo.cs +3 -3
  92. package/native/csharp/HostTools/Program.cs +5 -1
  93. package/native/csharp/StorageHelper/AssemblyInfo.cs +3 -3
  94. package/native/scripts/stop-events.ps1 +7 -3
  95. package/package.json +1 -1
  96. package/sandbox/csharp/MemGov.cs +58 -0
  97. package/schemas/config.schema.json +3 -3
  98. package/schemas/sandbox-config.schema.json +3 -3
@@ -5546,6 +5546,7 @@ var SYSTEM = {
5546
5546
  cmd: () => system32("cmd.exe"),
5547
5547
  powershell: () => system32("WindowsPowerShell\\v1.0\\powershell.exe"),
5548
5548
  tasklist: () => system32("tasklist.exe"),
5549
+ taskkill: () => system32("taskkill.exe"),
5549
5550
  whoami: () => system32("whoami.exe"),
5550
5551
  icacls: () => system32("icacls.exe"),
5551
5552
  tar: () => system32("tar.exe"),
@@ -25442,7 +25443,7 @@ var SandboxSchema = external_exports.strictObject({
25442
25443
  '(alpha) What runs the sandbox. "windows-sandbox" = Windows Sandbox (the default: desktop, Windows Terminal, GPU, clipboard, audio, printers). "hcs" = a headless Hyper-V isolated Server Core container for agents (no desktop, GPU or clipboard); it needs Windows features and an image on this PC (sandbox engine check hcs lists what is missing), and starting it is not enabled yet in this alpha. sandbox engine shows what each engine can do. Yours only: a project file (.sandbox-config.json) cannot set it.'
25443
25444
  ),
25444
25445
  memoryMb: external_exports.union([external_exports.literal("auto"), external_exports.number().int().min(2048)]).describe(
25445
- 'Sandbox RAM in MB (>= 2048), or "auto": free RAM minus reserveHostMb, capped at maxMemoryMb. Never more than this PC can keep in RAM for it (its RAM minus the larger of reserveHostMb and 25 %, 2 GB more with vGPU): a bigger value is lowered.'
25446
+ 'Sandbox RAM in MB (>= 2048), or "auto": free RAM minus reserveHostMb, capped at maxMemoryMb. Never more than this PC can keep in RAM for it (its RAM minus the larger of reserveHostMb and 25 %, 4 GB more with vGPU): a bigger value is lowered.'
25446
25447
  ),
25447
25448
  maxMemoryMb: external_exports.number().int().positive().describe('Upper limit for memoryMb "auto".'),
25448
25449
  maxMemoryPercent: external_exports.number().int().min(10).max(100).describe(`memoryMb "auto" never takes more than this share of this PC's total RAM (percent).`),
@@ -25604,13 +25605,13 @@ var ToolchainsSchema = external_exports.strictObject({
25604
25605
  '["sccache", "cargo-nextest", "cargo-deny"]'
25605
25606
  ),
25606
25607
  targetDir: external_exports.string().min(1).describe(
25607
- `"shared": cargo's default target\\ (shared with builds on this PC, so builds on either side invalidate the other), "separate": <workspace>\\target\\sandbox (kept, no cross-talk), "local": on the sandbox's own disk (fastest, lost every boot), or a guest path.`
25608
+ `"auto" (default): on the sandbox's own disk when C: has 25 GB free at boot, else "separate" (builds then write through the mapped workspace, which can overload this PC's disk). "shared": cargo's default target\\ (shared with builds on this PC, so builds on either side invalidate the other), "separate": <workspace>\\target\\sandbox (kept, no cross-talk), "local": on the sandbox's own disk (fastest, lost every boot), or a guest path.`
25608
25609
  ),
25609
25610
  linker: external_exports.enum(["lld", "gnu"]).describe(
25610
25611
  `GNU host: "lld" links with Rust's own lld through MinGW's gcc (much less memory than GNU ld), "gnu" with GNU ld.`
25611
25612
  ),
25612
25613
  linkSlots: external_exports.union([external_exports.literal("auto"), external_exports.number().int().min(1).max(32)]).describe(
25613
- 'GNU host: how many programs may link at the same time in the whole sandbox (other links wait). "auto" = one per 3 GB of sandbox memory after 6 GB, 2 to 8 (the memory governor slows links down too when memory runs short).'
25614
+ 'GNU host: how many programs may link at the same time in the whole sandbox (other links wait). "auto" = one per 6 GB of sandbox memory, 1 to 4 (the memory governor slows links down too when memory runs short).'
25614
25615
  )
25615
25616
  }),
25616
25617
  msvc: external_exports.strictObject({
@@ -27258,6 +27259,8 @@ var GuestRequestSchema = external_exports.discriminatedUnion("kind", [
27258
27259
  seconds: external_exports.number().int().min(10).max(300),
27259
27260
  /** "severe": the PC is nearly out of memory; builds go to the governor's last step at once. */
27260
27261
  level: external_exports.enum(["slow", "severe"]).optional(),
27262
+ /** The disk queue the PC reported (shown in the heartbeat). */
27263
+ diskQueue: external_exports.number().min(0).max(1e5).optional(),
27261
27264
  createdAt: TimeSchema
27262
27265
  })
27263
27266
  ]);
@@ -27280,6 +27283,22 @@ var PressureStatusSchema = external_exports.object({
27280
27283
  lastAction: Text(300),
27281
27284
  updatedAt: TimeSchema
27282
27285
  });
27286
+ var HeartbeatSchema = external_exports.object({
27287
+ at: TimeSchema,
27288
+ /** Seconds since the sandbox booted. */
27289
+ uptimeS: external_exports.number().int().min(0).max(1e9),
27290
+ ramFreePct: external_exports.number().min(0).max(100),
27291
+ commitPct: external_exports.number().min(0).max(100),
27292
+ /** The governor's dial now, and the step this PC asked for. */
27293
+ step: external_exports.number().int().min(0).max(4),
27294
+ hostStep: external_exports.number().int().min(0).max(4),
27295
+ /** The biggest programs in the agents' job. */
27296
+ topProcesses: external_exports.array(external_exports.object({ name: Text(64), privateMb: external_exports.number().int().min(0).max(1e7) })).max(5),
27297
+ /** The disk queue this PC last reported while asking the sandbox to slow down. */
27298
+ diskQueueReported: external_exports.number().min(0).max(1e5).optional(),
27299
+ /** "ending": the sandbox is shutting down in order (idle shutdown, sandbox stop, Windows shutting down). */
27300
+ phase: external_exports.enum(["ready", "working", "ending"])
27301
+ });
27283
27302
  var GuestResponseSchema = external_exports.object({
27284
27303
  id: IdSchema,
27285
27304
  ok: external_exports.boolean(),
@@ -27527,6 +27546,8 @@ var RunDir = class {
27527
27546
  vpnFile;
27528
27547
  /** What the memory governor in the sandbox is doing (pressure.json). */
27529
27548
  pressureFile;
27549
+ /** The daemon's heartbeat every 10 seconds (heartbeat.json): what the sandbox did last. */
27550
+ heartbeatFile;
27530
27551
  /** What the sandbox's programs may really use (budget.json): processors, memory, build jobs, link slots. */
27531
27552
  budgetFile;
27532
27553
  requestsDir;
@@ -27550,6 +27571,7 @@ var RunDir = class {
27550
27571
  this.sandboxFile = path5.join(this.root, "sandbox.json");
27551
27572
  this.vpnFile = path5.join(this.root, "vpn.json");
27552
27573
  this.pressureFile = path5.join(this.root, "pressure.json");
27574
+ this.heartbeatFile = path5.join(this.root, "heartbeat.json");
27553
27575
  this.budgetFile = path5.join(this.root, "budget.json");
27554
27576
  this.requestsDir = path5.join(this.root, "requests");
27555
27577
  this.responsesDir = path5.join(this.root, "responses");
@@ -27594,6 +27616,9 @@ var RunDir = class {
27594
27616
  readPressure() {
27595
27617
  return readValid(PressureStatusSchema, this.pressureFile);
27596
27618
  }
27619
+ readHeartbeat() {
27620
+ return readValid(HeartbeatSchema, this.heartbeatFile);
27621
+ }
27597
27622
  readSession(id) {
27598
27623
  return readValid(SessionStatusSchema, this.sessionFile(id));
27599
27624
  }
@@ -25459,7 +25459,7 @@ var SandboxSchema = external_exports.strictObject({
25459
25459
  '(alpha) What runs the sandbox. "windows-sandbox" = Windows Sandbox (the default: desktop, Windows Terminal, GPU, clipboard, audio, printers). "hcs" = a headless Hyper-V isolated Server Core container for agents (no desktop, GPU or clipboard); it needs Windows features and an image on this PC (sandbox engine check hcs lists what is missing), and starting it is not enabled yet in this alpha. sandbox engine shows what each engine can do. Yours only: a project file (.sandbox-config.json) cannot set it.'
25460
25460
  ),
25461
25461
  memoryMb: external_exports.union([external_exports.literal("auto"), external_exports.number().int().min(2048)]).describe(
25462
- 'Sandbox RAM in MB (>= 2048), or "auto": free RAM minus reserveHostMb, capped at maxMemoryMb. Never more than this PC can keep in RAM for it (its RAM minus the larger of reserveHostMb and 25 %, 2 GB more with vGPU): a bigger value is lowered.'
25462
+ 'Sandbox RAM in MB (>= 2048), or "auto": free RAM minus reserveHostMb, capped at maxMemoryMb. Never more than this PC can keep in RAM for it (its RAM minus the larger of reserveHostMb and 25 %, 4 GB more with vGPU): a bigger value is lowered.'
25463
25463
  ),
25464
25464
  maxMemoryMb: external_exports.number().int().positive().describe('Upper limit for memoryMb "auto".'),
25465
25465
  maxMemoryPercent: external_exports.number().int().min(10).max(100).describe(`memoryMb "auto" never takes more than this share of this PC's total RAM (percent).`),
@@ -25621,13 +25621,13 @@ var ToolchainsSchema = external_exports.strictObject({
25621
25621
  '["sccache", "cargo-nextest", "cargo-deny"]'
25622
25622
  ),
25623
25623
  targetDir: external_exports.string().min(1).describe(
25624
- `"shared": cargo's default target\\ (shared with builds on this PC, so builds on either side invalidate the other), "separate": <workspace>\\target\\sandbox (kept, no cross-talk), "local": on the sandbox's own disk (fastest, lost every boot), or a guest path.`
25624
+ `"auto" (default): on the sandbox's own disk when C: has 25 GB free at boot, else "separate" (builds then write through the mapped workspace, which can overload this PC's disk). "shared": cargo's default target\\ (shared with builds on this PC, so builds on either side invalidate the other), "separate": <workspace>\\target\\sandbox (kept, no cross-talk), "local": on the sandbox's own disk (fastest, lost every boot), or a guest path.`
25625
25625
  ),
25626
25626
  linker: external_exports.enum(["lld", "gnu"]).describe(
25627
25627
  `GNU host: "lld" links with Rust's own lld through MinGW's gcc (much less memory than GNU ld), "gnu" with GNU ld.`
25628
25628
  ),
25629
25629
  linkSlots: external_exports.union([external_exports.literal("auto"), external_exports.number().int().min(1).max(32)]).describe(
25630
- 'GNU host: how many programs may link at the same time in the whole sandbox (other links wait). "auto" = one per 3 GB of sandbox memory after 6 GB, 2 to 8 (the memory governor slows links down too when memory runs short).'
25630
+ 'GNU host: how many programs may link at the same time in the whole sandbox (other links wait). "auto" = one per 6 GB of sandbox memory, 1 to 4 (the memory governor slows links down too when memory runs short).'
25631
25631
  )
25632
25632
  }),
25633
25633
  msvc: external_exports.strictObject({
@@ -27388,6 +27388,8 @@ var GuestRequestSchema = external_exports.discriminatedUnion("kind", [
27388
27388
  seconds: external_exports.number().int().min(10).max(300),
27389
27389
  /** "severe": the PC is nearly out of memory; builds go to the governor's last step at once. */
27390
27390
  level: external_exports.enum(["slow", "severe"]).optional(),
27391
+ /** The disk queue the PC reported (shown in the heartbeat). */
27392
+ diskQueue: external_exports.number().min(0).max(1e5).optional(),
27391
27393
  createdAt: TimeSchema
27392
27394
  })
27393
27395
  ]);
@@ -27410,6 +27412,22 @@ var PressureStatusSchema = external_exports.object({
27410
27412
  lastAction: Text(300),
27411
27413
  updatedAt: TimeSchema
27412
27414
  });
27415
+ var HeartbeatSchema = external_exports.object({
27416
+ at: TimeSchema,
27417
+ /** Seconds since the sandbox booted. */
27418
+ uptimeS: external_exports.number().int().min(0).max(1e9),
27419
+ ramFreePct: external_exports.number().min(0).max(100),
27420
+ commitPct: external_exports.number().min(0).max(100),
27421
+ /** The governor's dial now, and the step this PC asked for. */
27422
+ step: external_exports.number().int().min(0).max(4),
27423
+ hostStep: external_exports.number().int().min(0).max(4),
27424
+ /** The biggest programs in the agents' job. */
27425
+ topProcesses: external_exports.array(external_exports.object({ name: Text(64), privateMb: external_exports.number().int().min(0).max(1e7) })).max(5),
27426
+ /** The disk queue this PC last reported while asking the sandbox to slow down. */
27427
+ diskQueueReported: external_exports.number().min(0).max(1e5).optional(),
27428
+ /** "ending": the sandbox is shutting down in order (idle shutdown, sandbox stop, Windows shutting down). */
27429
+ phase: external_exports.enum(["ready", "working", "ending"])
27430
+ });
27413
27431
  var GuestResponseSchema = external_exports.object({
27414
27432
  id: IdSchema,
27415
27433
  ok: external_exports.boolean(),
@@ -27682,6 +27700,8 @@ var RunDir = class {
27682
27700
  vpnFile;
27683
27701
  /** What the memory governor in the sandbox is doing (pressure.json). */
27684
27702
  pressureFile;
27703
+ /** The daemon's heartbeat every 10 seconds (heartbeat.json): what the sandbox did last. */
27704
+ heartbeatFile;
27685
27705
  /** What the sandbox's programs may really use (budget.json): processors, memory, build jobs, link slots. */
27686
27706
  budgetFile;
27687
27707
  requestsDir;
@@ -27705,6 +27725,7 @@ var RunDir = class {
27705
27725
  this.sandboxFile = path6.join(this.root, "sandbox.json");
27706
27726
  this.vpnFile = path6.join(this.root, "vpn.json");
27707
27727
  this.pressureFile = path6.join(this.root, "pressure.json");
27728
+ this.heartbeatFile = path6.join(this.root, "heartbeat.json");
27708
27729
  this.budgetFile = path6.join(this.root, "budget.json");
27709
27730
  this.requestsDir = path6.join(this.root, "requests");
27710
27731
  this.responsesDir = path6.join(this.root, "responses");
@@ -27749,6 +27770,9 @@ var RunDir = class {
27749
27770
  readPressure() {
27750
27771
  return readValid(PressureStatusSchema, this.pressureFile);
27751
27772
  }
27773
+ readHeartbeat() {
27774
+ return readValid(HeartbeatSchema, this.heartbeatFile);
27775
+ }
27752
27776
  readSession(id) {
27753
27777
  return readValid(SessionStatusSchema, this.sessionFile(id));
27754
27778
  }
@@ -27860,6 +27884,7 @@ var SYSTEM = {
27860
27884
  cmd: () => system32("cmd.exe"),
27861
27885
  powershell: () => system32("WindowsPowerShell\\v1.0\\powershell.exe"),
27862
27886
  tasklist: () => system32("tasklist.exe"),
27887
+ taskkill: () => system32("taskkill.exe"),
27863
27888
  whoami: () => system32("whoami.exe"),
27864
27889
  icacls: () => system32("icacls.exe"),
27865
27890
  tar: () => system32("tar.exe"),
@@ -33786,17 +33811,39 @@ import path60 from "node:path";
33786
33811
  function buildJobs(cpus, memoryGb) {
33787
33812
  return Math.max(2, Math.min(cpus, Math.floor((memoryGb - 6) / 3)));
33788
33813
  }
33789
- function linkSlotsFor(memoryGb) {
33790
- return Math.max(2, Math.min(8, Math.floor((memoryGb - 6) / 3)));
33791
- }
33792
33814
  function cargoJobs(cpus, memoryGb, sessions) {
33793
33815
  const byCpu = Math.max(2, Math.min(8, Math.floor(cpus / 4)));
33794
33816
  const byMemory = Math.max(1, Math.floor(memoryGb / 4));
33795
33817
  const jobs = Math.min(byCpu, byMemory);
33796
33818
  return Math.max(1, Math.min(jobs, Math.floor(buildJobs(cpus, memoryGb) / Math.max(1, sessions))));
33797
33819
  }
33820
+ var LOCAL_TARGET_MIN_BYTES = 25 * 1024 ** 3;
33821
+ function chooseTargetDir(targetDir, freeBytes2) {
33822
+ if (targetDir !== "auto") return { targetDir };
33823
+ if (freeBytes2 >= LOCAL_TARGET_MIN_BYTES) return { targetDir: "local" };
33824
+ return {
33825
+ targetDir: "separate",
33826
+ 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)"
33827
+ };
33828
+ }
33829
+
33830
+ // src/guest/governor/decide.ts
33831
+ function linkerSlots(totalMb, cpus) {
33832
+ return Math.max(1, Math.min(4, Math.max(1, Math.floor(cpus)), Math.floor(totalMb / 6144)));
33833
+ }
33798
33834
 
33799
33835
  // src/guest/toolchains/native/rust-extras.ts
33836
+ function resolveTargetDir(rust, free = freeBytes((process.env.SystemDrive ?? "C:") + "\\"), note = warn) {
33837
+ if (rust.targetDir !== "auto") return rust;
33838
+ const chosen = chooseTargetDir(rust.targetDir, free);
33839
+ if (chosen.warning) note(chosen.warning);
33840
+ return { ...rust, targetDir: chosen.targetDir };
33841
+ }
33842
+ function targetSummary(rust) {
33843
+ const target = cargoTarget(rust.targetDir);
33844
+ if (target) return "rust builds: " + target + " (CARGO_TARGET_DIR)";
33845
+ return rust.targetDir === "shared" ? "rust builds: target\\ in each project (shared with this PC)" : "rust builds: target\\sandbox in each project (on the mapped workspace)";
33846
+ }
33800
33847
  var cargoTarget = (targetDir) => {
33801
33848
  if (targetDir === "shared" || targetDir === "separate") return null;
33802
33849
  if (targetDir === "local") return path60.join(localDir, "cargo-target");
@@ -33815,8 +33862,7 @@ function linkGate(env, rust, host) {
33815
33862
  if (!host.endsWith("-pc-windows-gnu") || !exists(gcc)) return;
33816
33863
  const gate = path60.join(mkdirp(tool("shims")), "linkgate.exe");
33817
33864
  fs50.copyFileSync(ensureCompiled("linkgate"), gate);
33818
- const memoryGb = os10.totalmem() / 1024 ** 3;
33819
- const slots = rust.linkSlots === "auto" ? linkSlotsFor(memoryGb) : rust.linkSlots;
33865
+ const slots = rust.linkSlots === "auto" ? linkerSlots(os10.totalmem() / 1024 ** 2, os10.cpus().length) : rust.linkSlots;
33820
33866
  env.vars.AGENT_LINK_SLOTS = String(slots);
33821
33867
  env.vars.AGENT_REAL_LINKER = gcc;
33822
33868
  env.vars.CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER = gate;
@@ -33928,11 +33974,13 @@ function plan(config2, versions, o) {
33928
33974
  after: ["C/C++", "MSVC", "Visual Studio", "Unreal"],
33929
33975
  install: async (env) => {
33930
33976
  await setupRust(env, { ...config2.rust, host: rustHost(config2) }, o.refresh);
33931
- Object.assign(env.vars, rustCaches(config2.rust));
33977
+ const rust = resolveTargetDir(config2.rust);
33978
+ Object.assign(env.vars, rustCaches(rust));
33979
+ env.summary.push(targetSummary(rust));
33932
33980
  if (!dryRun) {
33933
33981
  cargoDefaults(rustHost(config2));
33934
- cargoShim(env, config2.rust);
33935
- linkGate(env, config2.rust, rustHost(config2));
33982
+ cargoShim(env, rust);
33983
+ linkGate(env, rust, rustHost(config2));
33936
33984
  }
33937
33985
  }
33938
33986
  },
@@ -25495,7 +25495,7 @@ var SandboxSchema = external_exports.strictObject({
25495
25495
  '(alpha) What runs the sandbox. "windows-sandbox" = Windows Sandbox (the default: desktop, Windows Terminal, GPU, clipboard, audio, printers). "hcs" = a headless Hyper-V isolated Server Core container for agents (no desktop, GPU or clipboard); it needs Windows features and an image on this PC (sandbox engine check hcs lists what is missing), and starting it is not enabled yet in this alpha. sandbox engine shows what each engine can do. Yours only: a project file (.sandbox-config.json) cannot set it.'
25496
25496
  ),
25497
25497
  memoryMb: external_exports.union([external_exports.literal("auto"), external_exports.number().int().min(2048)]).describe(
25498
- 'Sandbox RAM in MB (>= 2048), or "auto": free RAM minus reserveHostMb, capped at maxMemoryMb. Never more than this PC can keep in RAM for it (its RAM minus the larger of reserveHostMb and 25 %, 2 GB more with vGPU): a bigger value is lowered.'
25498
+ 'Sandbox RAM in MB (>= 2048), or "auto": free RAM minus reserveHostMb, capped at maxMemoryMb. Never more than this PC can keep in RAM for it (its RAM minus the larger of reserveHostMb and 25 %, 4 GB more with vGPU): a bigger value is lowered.'
25499
25499
  ),
25500
25500
  maxMemoryMb: external_exports.number().int().positive().describe('Upper limit for memoryMb "auto".'),
25501
25501
  maxMemoryPercent: external_exports.number().int().min(10).max(100).describe(`memoryMb "auto" never takes more than this share of this PC's total RAM (percent).`),
@@ -25657,13 +25657,13 @@ var ToolchainsSchema = external_exports.strictObject({
25657
25657
  '["sccache", "cargo-nextest", "cargo-deny"]'
25658
25658
  ),
25659
25659
  targetDir: external_exports.string().min(1).describe(
25660
- `"shared": cargo's default target\\ (shared with builds on this PC, so builds on either side invalidate the other), "separate": <workspace>\\target\\sandbox (kept, no cross-talk), "local": on the sandbox's own disk (fastest, lost every boot), or a guest path.`
25660
+ `"auto" (default): on the sandbox's own disk when C: has 25 GB free at boot, else "separate" (builds then write through the mapped workspace, which can overload this PC's disk). "shared": cargo's default target\\ (shared with builds on this PC, so builds on either side invalidate the other), "separate": <workspace>\\target\\sandbox (kept, no cross-talk), "local": on the sandbox's own disk (fastest, lost every boot), or a guest path.`
25661
25661
  ),
25662
25662
  linker: external_exports.enum(["lld", "gnu"]).describe(
25663
25663
  `GNU host: "lld" links with Rust's own lld through MinGW's gcc (much less memory than GNU ld), "gnu" with GNU ld.`
25664
25664
  ),
25665
25665
  linkSlots: external_exports.union([external_exports.literal("auto"), external_exports.number().int().min(1).max(32)]).describe(
25666
- 'GNU host: how many programs may link at the same time in the whole sandbox (other links wait). "auto" = one per 3 GB of sandbox memory after 6 GB, 2 to 8 (the memory governor slows links down too when memory runs short).'
25666
+ 'GNU host: how many programs may link at the same time in the whole sandbox (other links wait). "auto" = one per 6 GB of sandbox memory, 1 to 4 (the memory governor slows links down too when memory runs short).'
25667
25667
  )
25668
25668
  }),
25669
25669
  msvc: external_exports.strictObject({
@@ -27311,6 +27311,8 @@ var GuestRequestSchema = external_exports.discriminatedUnion("kind", [
27311
27311
  seconds: external_exports.number().int().min(10).max(300),
27312
27312
  /** "severe": the PC is nearly out of memory; builds go to the governor's last step at once. */
27313
27313
  level: external_exports.enum(["slow", "severe"]).optional(),
27314
+ /** The disk queue the PC reported (shown in the heartbeat). */
27315
+ diskQueue: external_exports.number().min(0).max(1e5).optional(),
27314
27316
  createdAt: TimeSchema
27315
27317
  })
27316
27318
  ]);
@@ -27333,6 +27335,22 @@ var PressureStatusSchema = external_exports.object({
27333
27335
  lastAction: Text(300),
27334
27336
  updatedAt: TimeSchema
27335
27337
  });
27338
+ var HeartbeatSchema = external_exports.object({
27339
+ at: TimeSchema,
27340
+ /** Seconds since the sandbox booted. */
27341
+ uptimeS: external_exports.number().int().min(0).max(1e9),
27342
+ ramFreePct: external_exports.number().min(0).max(100),
27343
+ commitPct: external_exports.number().min(0).max(100),
27344
+ /** The governor's dial now, and the step this PC asked for. */
27345
+ step: external_exports.number().int().min(0).max(4),
27346
+ hostStep: external_exports.number().int().min(0).max(4),
27347
+ /** The biggest programs in the agents' job. */
27348
+ topProcesses: external_exports.array(external_exports.object({ name: Text(64), privateMb: external_exports.number().int().min(0).max(1e7) })).max(5),
27349
+ /** The disk queue this PC last reported while asking the sandbox to slow down. */
27350
+ diskQueueReported: external_exports.number().min(0).max(1e5).optional(),
27351
+ /** "ending": the sandbox is shutting down in order (idle shutdown, sandbox stop, Windows shutting down). */
27352
+ phase: external_exports.enum(["ready", "working", "ending"])
27353
+ });
27336
27354
  var GuestResponseSchema = external_exports.object({
27337
27355
  id: IdSchema,
27338
27356
  ok: external_exports.boolean(),
@@ -27518,6 +27536,8 @@ var RunDir = class {
27518
27536
  vpnFile;
27519
27537
  /** What the memory governor in the sandbox is doing (pressure.json). */
27520
27538
  pressureFile;
27539
+ /** The daemon's heartbeat every 10 seconds (heartbeat.json): what the sandbox did last. */
27540
+ heartbeatFile;
27521
27541
  /** What the sandbox's programs may really use (budget.json): processors, memory, build jobs, link slots. */
27522
27542
  budgetFile;
27523
27543
  requestsDir;
@@ -27541,6 +27561,7 @@ var RunDir = class {
27541
27561
  this.sandboxFile = path3.join(this.root, "sandbox.json");
27542
27562
  this.vpnFile = path3.join(this.root, "vpn.json");
27543
27563
  this.pressureFile = path3.join(this.root, "pressure.json");
27564
+ this.heartbeatFile = path3.join(this.root, "heartbeat.json");
27544
27565
  this.budgetFile = path3.join(this.root, "budget.json");
27545
27566
  this.requestsDir = path3.join(this.root, "requests");
27546
27567
  this.responsesDir = path3.join(this.root, "responses");
@@ -27585,6 +27606,9 @@ var RunDir = class {
27585
27606
  readPressure() {
27586
27607
  return readValid(PressureStatusSchema, this.pressureFile);
27587
27608
  }
27609
+ readHeartbeat() {
27610
+ return readValid(HeartbeatSchema, this.heartbeatFile);
27611
+ }
27588
27612
  readSession(id) {
27589
27613
  return readValid(SessionStatusSchema, this.sessionFile(id));
27590
27614
  }
@@ -27658,6 +27682,7 @@ var SYSTEM = {
27658
27682
  cmd: () => system32("cmd.exe"),
27659
27683
  powershell: () => system32("WindowsPowerShell\\v1.0\\powershell.exe"),
27660
27684
  tasklist: () => system32("tasklist.exe"),
27685
+ taskkill: () => system32("taskkill.exe"),
27661
27686
  whoami: () => system32("whoami.exe"),
27662
27687
  icacls: () => system32("icacls.exe"),
27663
27688
  tar: () => system32("tar.exe"),
@@ -25775,6 +25775,7 @@ var SYSTEM = {
25775
25775
  cmd: () => system32("cmd.exe"),
25776
25776
  powershell: () => system32("WindowsPowerShell\\v1.0\\powershell.exe"),
25777
25777
  tasklist: () => system32("tasklist.exe"),
25778
+ taskkill: () => system32("taskkill.exe"),
25778
25779
  whoami: () => system32("whoami.exe"),
25779
25780
  icacls: () => system32("icacls.exe"),
25780
25781
  tar: () => system32("tar.exe"),
@@ -26174,7 +26175,7 @@ var SandboxSchema = external_exports.strictObject({
26174
26175
  '(alpha) What runs the sandbox. "windows-sandbox" = Windows Sandbox (the default: desktop, Windows Terminal, GPU, clipboard, audio, printers). "hcs" = a headless Hyper-V isolated Server Core container for agents (no desktop, GPU or clipboard); it needs Windows features and an image on this PC (sandbox engine check hcs lists what is missing), and starting it is not enabled yet in this alpha. sandbox engine shows what each engine can do. Yours only: a project file (.sandbox-config.json) cannot set it.'
26175
26176
  ),
26176
26177
  memoryMb: external_exports.union([external_exports.literal("auto"), external_exports.number().int().min(2048)]).describe(
26177
- 'Sandbox RAM in MB (>= 2048), or "auto": free RAM minus reserveHostMb, capped at maxMemoryMb. Never more than this PC can keep in RAM for it (its RAM minus the larger of reserveHostMb and 25 %, 2 GB more with vGPU): a bigger value is lowered.'
26178
+ 'Sandbox RAM in MB (>= 2048), or "auto": free RAM minus reserveHostMb, capped at maxMemoryMb. Never more than this PC can keep in RAM for it (its RAM minus the larger of reserveHostMb and 25 %, 4 GB more with vGPU): a bigger value is lowered.'
26178
26179
  ),
26179
26180
  maxMemoryMb: external_exports.number().int().positive().describe('Upper limit for memoryMb "auto".'),
26180
26181
  maxMemoryPercent: external_exports.number().int().min(10).max(100).describe(`memoryMb "auto" never takes more than this share of this PC's total RAM (percent).`),
@@ -26336,13 +26337,13 @@ var ToolchainsSchema = external_exports.strictObject({
26336
26337
  '["sccache", "cargo-nextest", "cargo-deny"]'
26337
26338
  ),
26338
26339
  targetDir: external_exports.string().min(1).describe(
26339
- `"shared": cargo's default target\\ (shared with builds on this PC, so builds on either side invalidate the other), "separate": <workspace>\\target\\sandbox (kept, no cross-talk), "local": on the sandbox's own disk (fastest, lost every boot), or a guest path.`
26340
+ `"auto" (default): on the sandbox's own disk when C: has 25 GB free at boot, else "separate" (builds then write through the mapped workspace, which can overload this PC's disk). "shared": cargo's default target\\ (shared with builds on this PC, so builds on either side invalidate the other), "separate": <workspace>\\target\\sandbox (kept, no cross-talk), "local": on the sandbox's own disk (fastest, lost every boot), or a guest path.`
26340
26341
  ),
26341
26342
  linker: external_exports.enum(["lld", "gnu"]).describe(
26342
26343
  `GNU host: "lld" links with Rust's own lld through MinGW's gcc (much less memory than GNU ld), "gnu" with GNU ld.`
26343
26344
  ),
26344
26345
  linkSlots: external_exports.union([external_exports.literal("auto"), external_exports.number().int().min(1).max(32)]).describe(
26345
- 'GNU host: how many programs may link at the same time in the whole sandbox (other links wait). "auto" = one per 3 GB of sandbox memory after 6 GB, 2 to 8 (the memory governor slows links down too when memory runs short).'
26346
+ 'GNU host: how many programs may link at the same time in the whole sandbox (other links wait). "auto" = one per 6 GB of sandbox memory, 1 to 4 (the memory governor slows links down too when memory runs short).'
26346
26347
  )
26347
26348
  }),
26348
26349
  msvc: external_exports.strictObject({
@@ -27865,6 +27866,8 @@ var GuestRequestSchema = external_exports.discriminatedUnion("kind", [
27865
27866
  seconds: external_exports.number().int().min(10).max(300),
27866
27867
  /** "severe": the PC is nearly out of memory; builds go to the governor's last step at once. */
27867
27868
  level: external_exports.enum(["slow", "severe"]).optional(),
27869
+ /** The disk queue the PC reported (shown in the heartbeat). */
27870
+ diskQueue: external_exports.number().min(0).max(1e5).optional(),
27868
27871
  createdAt: TimeSchema
27869
27872
  })
27870
27873
  ]);
@@ -27887,6 +27890,22 @@ var PressureStatusSchema = external_exports.object({
27887
27890
  lastAction: Text(300),
27888
27891
  updatedAt: TimeSchema
27889
27892
  });
27893
+ var HeartbeatSchema = external_exports.object({
27894
+ at: TimeSchema,
27895
+ /** Seconds since the sandbox booted. */
27896
+ uptimeS: external_exports.number().int().min(0).max(1e9),
27897
+ ramFreePct: external_exports.number().min(0).max(100),
27898
+ commitPct: external_exports.number().min(0).max(100),
27899
+ /** The governor's dial now, and the step this PC asked for. */
27900
+ step: external_exports.number().int().min(0).max(4),
27901
+ hostStep: external_exports.number().int().min(0).max(4),
27902
+ /** The biggest programs in the agents' job. */
27903
+ topProcesses: external_exports.array(external_exports.object({ name: Text(64), privateMb: external_exports.number().int().min(0).max(1e7) })).max(5),
27904
+ /** The disk queue this PC last reported while asking the sandbox to slow down. */
27905
+ diskQueueReported: external_exports.number().min(0).max(1e5).optional(),
27906
+ /** "ending": the sandbox is shutting down in order (idle shutdown, sandbox stop, Windows shutting down). */
27907
+ phase: external_exports.enum(["ready", "working", "ending"])
27908
+ });
27890
27909
  var GuestResponseSchema = external_exports.object({
27891
27910
  id: IdSchema,
27892
27911
  ok: external_exports.boolean(),
@@ -27958,6 +27977,8 @@ var RunDir = class {
27958
27977
  vpnFile;
27959
27978
  /** What the memory governor in the sandbox is doing (pressure.json). */
27960
27979
  pressureFile;
27980
+ /** The daemon's heartbeat every 10 seconds (heartbeat.json): what the sandbox did last. */
27981
+ heartbeatFile;
27961
27982
  /** What the sandbox's programs may really use (budget.json): processors, memory, build jobs, link slots. */
27962
27983
  budgetFile;
27963
27984
  requestsDir;
@@ -27981,6 +28002,7 @@ var RunDir = class {
27981
28002
  this.sandboxFile = path9.join(this.root, "sandbox.json");
27982
28003
  this.vpnFile = path9.join(this.root, "vpn.json");
27983
28004
  this.pressureFile = path9.join(this.root, "pressure.json");
28005
+ this.heartbeatFile = path9.join(this.root, "heartbeat.json");
27984
28006
  this.budgetFile = path9.join(this.root, "budget.json");
27985
28007
  this.requestsDir = path9.join(this.root, "requests");
27986
28008
  this.responsesDir = path9.join(this.root, "responses");
@@ -28025,6 +28047,9 @@ var RunDir = class {
28025
28047
  readPressure() {
28026
28048
  return readValid(PressureStatusSchema, this.pressureFile);
28027
28049
  }
28050
+ readHeartbeat() {
28051
+ return readValid(HeartbeatSchema, this.heartbeatFile);
28052
+ }
28028
28053
  readSession(id) {
28029
28054
  return readValid(SessionStatusSchema, this.sessionFile(id));
28030
28055
  }
@@ -5756,6 +5756,7 @@ var SYSTEM = {
5756
5756
  cmd: () => system32("cmd.exe"),
5757
5757
  powershell: () => system32("WindowsPowerShell\\v1.0\\powershell.exe"),
5758
5758
  tasklist: () => system32("tasklist.exe"),
5759
+ taskkill: () => system32("taskkill.exe"),
5759
5760
  whoami: () => system32("whoami.exe"),
5760
5761
  icacls: () => system32("icacls.exe"),
5761
5762
  tar: () => system32("tar.exe"),
@@ -26070,7 +26071,7 @@ var SandboxSchema = external_exports.strictObject({
26070
26071
  '(alpha) What runs the sandbox. "windows-sandbox" = Windows Sandbox (the default: desktop, Windows Terminal, GPU, clipboard, audio, printers). "hcs" = a headless Hyper-V isolated Server Core container for agents (no desktop, GPU or clipboard); it needs Windows features and an image on this PC (sandbox engine check hcs lists what is missing), and starting it is not enabled yet in this alpha. sandbox engine shows what each engine can do. Yours only: a project file (.sandbox-config.json) cannot set it.'
26071
26072
  ),
26072
26073
  memoryMb: external_exports.union([external_exports.literal("auto"), external_exports.number().int().min(2048)]).describe(
26073
- 'Sandbox RAM in MB (>= 2048), or "auto": free RAM minus reserveHostMb, capped at maxMemoryMb. Never more than this PC can keep in RAM for it (its RAM minus the larger of reserveHostMb and 25 %, 2 GB more with vGPU): a bigger value is lowered.'
26074
+ 'Sandbox RAM in MB (>= 2048), or "auto": free RAM minus reserveHostMb, capped at maxMemoryMb. Never more than this PC can keep in RAM for it (its RAM minus the larger of reserveHostMb and 25 %, 4 GB more with vGPU): a bigger value is lowered.'
26074
26075
  ),
26075
26076
  maxMemoryMb: external_exports.number().int().positive().describe('Upper limit for memoryMb "auto".'),
26076
26077
  maxMemoryPercent: external_exports.number().int().min(10).max(100).describe(`memoryMb "auto" never takes more than this share of this PC's total RAM (percent).`),
@@ -26232,13 +26233,13 @@ var ToolchainsSchema = external_exports.strictObject({
26232
26233
  '["sccache", "cargo-nextest", "cargo-deny"]'
26233
26234
  ),
26234
26235
  targetDir: external_exports.string().min(1).describe(
26235
- `"shared": cargo's default target\\ (shared with builds on this PC, so builds on either side invalidate the other), "separate": <workspace>\\target\\sandbox (kept, no cross-talk), "local": on the sandbox's own disk (fastest, lost every boot), or a guest path.`
26236
+ `"auto" (default): on the sandbox's own disk when C: has 25 GB free at boot, else "separate" (builds then write through the mapped workspace, which can overload this PC's disk). "shared": cargo's default target\\ (shared with builds on this PC, so builds on either side invalidate the other), "separate": <workspace>\\target\\sandbox (kept, no cross-talk), "local": on the sandbox's own disk (fastest, lost every boot), or a guest path.`
26236
26237
  ),
26237
26238
  linker: external_exports.enum(["lld", "gnu"]).describe(
26238
26239
  `GNU host: "lld" links with Rust's own lld through MinGW's gcc (much less memory than GNU ld), "gnu" with GNU ld.`
26239
26240
  ),
26240
26241
  linkSlots: external_exports.union([external_exports.literal("auto"), external_exports.number().int().min(1).max(32)]).describe(
26241
- 'GNU host: how many programs may link at the same time in the whole sandbox (other links wait). "auto" = one per 3 GB of sandbox memory after 6 GB, 2 to 8 (the memory governor slows links down too when memory runs short).'
26242
+ 'GNU host: how many programs may link at the same time in the whole sandbox (other links wait). "auto" = one per 6 GB of sandbox memory, 1 to 4 (the memory governor slows links down too when memory runs short).'
26242
26243
  )
26243
26244
  }),
26244
26245
  msvc: external_exports.strictObject({
@@ -27886,6 +27887,8 @@ var GuestRequestSchema = external_exports.discriminatedUnion("kind", [
27886
27887
  seconds: external_exports.number().int().min(10).max(300),
27887
27888
  /** "severe": the PC is nearly out of memory; builds go to the governor's last step at once. */
27888
27889
  level: external_exports.enum(["slow", "severe"]).optional(),
27890
+ /** The disk queue the PC reported (shown in the heartbeat). */
27891
+ diskQueue: external_exports.number().min(0).max(1e5).optional(),
27889
27892
  createdAt: TimeSchema
27890
27893
  })
27891
27894
  ]);
@@ -27908,6 +27911,22 @@ var PressureStatusSchema = external_exports.object({
27908
27911
  lastAction: Text(300),
27909
27912
  updatedAt: TimeSchema
27910
27913
  });
27914
+ var HeartbeatSchema = external_exports.object({
27915
+ at: TimeSchema,
27916
+ /** Seconds since the sandbox booted. */
27917
+ uptimeS: external_exports.number().int().min(0).max(1e9),
27918
+ ramFreePct: external_exports.number().min(0).max(100),
27919
+ commitPct: external_exports.number().min(0).max(100),
27920
+ /** The governor's dial now, and the step this PC asked for. */
27921
+ step: external_exports.number().int().min(0).max(4),
27922
+ hostStep: external_exports.number().int().min(0).max(4),
27923
+ /** The biggest programs in the agents' job. */
27924
+ topProcesses: external_exports.array(external_exports.object({ name: Text(64), privateMb: external_exports.number().int().min(0).max(1e7) })).max(5),
27925
+ /** The disk queue this PC last reported while asking the sandbox to slow down. */
27926
+ diskQueueReported: external_exports.number().min(0).max(1e5).optional(),
27927
+ /** "ending": the sandbox is shutting down in order (idle shutdown, sandbox stop, Windows shutting down). */
27928
+ phase: external_exports.enum(["ready", "working", "ending"])
27929
+ });
27911
27930
  var GuestResponseSchema = external_exports.object({
27912
27931
  id: IdSchema,
27913
27932
  ok: external_exports.boolean(),
@@ -28093,6 +28112,8 @@ var RunDir = class {
28093
28112
  vpnFile;
28094
28113
  /** What the memory governor in the sandbox is doing (pressure.json). */
28095
28114
  pressureFile;
28115
+ /** The daemon's heartbeat every 10 seconds (heartbeat.json): what the sandbox did last. */
28116
+ heartbeatFile;
28096
28117
  /** What the sandbox's programs may really use (budget.json): processors, memory, build jobs, link slots. */
28097
28118
  budgetFile;
28098
28119
  requestsDir;
@@ -28116,6 +28137,7 @@ var RunDir = class {
28116
28137
  this.sandboxFile = path5.join(this.root, "sandbox.json");
28117
28138
  this.vpnFile = path5.join(this.root, "vpn.json");
28118
28139
  this.pressureFile = path5.join(this.root, "pressure.json");
28140
+ this.heartbeatFile = path5.join(this.root, "heartbeat.json");
28119
28141
  this.budgetFile = path5.join(this.root, "budget.json");
28120
28142
  this.requestsDir = path5.join(this.root, "requests");
28121
28143
  this.responsesDir = path5.join(this.root, "responses");
@@ -28160,6 +28182,9 @@ var RunDir = class {
28160
28182
  readPressure() {
28161
28183
  return readValid(PressureStatusSchema, this.pressureFile);
28162
28184
  }
28185
+ readHeartbeat() {
28186
+ return readValid(HeartbeatSchema, this.heartbeatFile);
28187
+ }
28163
28188
  readSession(id) {
28164
28189
  return readValid(SessionStatusSchema, this.sessionFile(id));
28165
28190
  }