windows-development-sandbox 1.27.3 → 1.29.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. package/README.md +5 -4
  2. package/dist/app/features/sandbox/sandbox.run.js +1 -1
  3. package/dist/bin/{chunk-FA5VWLP4.js → chunk-O4EL32TM.js} +1 -1
  4. package/dist/bin/{chunk-RU7XRN62.js → chunk-QYRRWGFY.js} +1637 -1354
  5. package/dist/bin/sandbox.js +10772 -3
  6. package/dist/cli/commands/launch/launch.js +1 -1
  7. package/dist/cli/commands/launch/running.js +2 -2
  8. package/dist/cli/index.js +1 -1
  9. package/dist/cli/menu/pages/agents-page.js +1 -1
  10. package/dist/cli/services/sandbox-service.js +1 -1
  11. package/dist/core/schema/sandbox.js +2 -2
  12. package/dist/guest/apps/app-installer.js +1 -1
  13. package/dist/guest/apps/store-check.d.ts +2 -0
  14. package/dist/guest/apps/store-check.js +3 -1
  15. package/dist/guest/boot/guide-lines.d.ts +2 -0
  16. package/dist/guest/boot/guide-lines.js +7 -0
  17. package/dist/guest/boot/guide.js +2 -1
  18. package/dist/guest/daemon/heartbeat.js +1 -0
  19. package/dist/guest/governor/core.d.ts +53 -1
  20. package/dist/guest/governor/core.js +95 -1
  21. package/dist/guest/governor/decide.d.ts +4 -0
  22. package/dist/guest/governor/decide.js +2 -0
  23. package/dist/guest/governor/governor.js +23 -9
  24. package/dist/guest/toolchains/runtimes.js +7 -6
  25. package/dist/host/accounts/deliver.js +16 -2
  26. package/dist/host/apps/store-package.d.ts +2 -0
  27. package/dist/host/apps/store-package.js +16 -15
  28. package/dist/host/channel/attach.js +1 -1
  29. package/dist/host/channel/channel.js +3 -3
  30. package/dist/host/guard/commands.js +1 -0
  31. package/dist/host/health/path-copies.d.ts +1 -1
  32. package/dist/host/health/path-copies.js +2 -2
  33. package/dist/host/install/index.d.ts +1 -1
  34. package/dist/host/install/index.js +1 -1
  35. package/dist/host/install/shims.d.ts +8 -1
  36. package/dist/host/install/shims.js +39 -1
  37. package/dist/host/launch/generate.js +4 -0
  38. package/dist/host/launch/index.d.ts +1 -0
  39. package/dist/host/launch/index.js +1 -0
  40. package/dist/host/launch/pc-logs.d.ts +6 -0
  41. package/dist/host/launch/pc-logs.js +129 -0
  42. package/dist/host/life/crash-report.d.ts +4 -0
  43. package/dist/host/life/crash-report.js +30 -1
  44. package/dist/host/life/last-end.js +1 -0
  45. package/dist/host/sandbox/platform.js +1 -1
  46. package/dist/host/sandbox/window.js +1 -1
  47. package/dist/host/tools/windows-terminal.d.ts +4 -1
  48. package/dist/host/tools/windows-terminal.js +25 -9
  49. package/dist/runtime/agent.js +6 -2
  50. package/dist/runtime/daemon.js +111 -16
  51. package/dist/runtime/db.js +6 -2
  52. package/dist/runtime/main.js +199 -35
  53. package/dist/runtime/netproxy.js +6 -2
  54. package/dist/runtime/tool.js +6 -2
  55. package/dist/runtime/view.js +126 -28
  56. package/dist/selftest/agent-paths.test.js +3 -1
  57. package/dist/selftest/channel.test.js +33 -0
  58. package/dist/selftest/cli.test.js +5 -5
  59. package/dist/selftest/config.test.js +1 -1
  60. package/dist/selftest/credentials.test.js +1 -1
  61. package/dist/selftest/engine.test.js +1 -1
  62. package/dist/selftest/generate.test.js +66 -1
  63. package/dist/selftest/hcs.test.js +1 -1
  64. package/dist/selftest/health.test.js +21 -10
  65. package/dist/selftest/heavy-load.test.js +112 -4
  66. package/dist/selftest/host-sim.test.js +13 -14
  67. package/dist/selftest/install.test.js +6 -2
  68. package/dist/selftest/live-terminal.test.js +103 -0
  69. package/dist/selftest/personalization.test.js +2 -1
  70. package/dist/selftest/store-app.test.js +62 -4
  71. package/dist/selftest/support/engine-golden.js +2 -0
  72. package/dist/selftest/support/web-preview.js +2 -2
  73. package/dist/shared/accounts/kinds.d.ts +5 -0
  74. package/dist/shared/accounts/kinds.js +8 -0
  75. package/dist/shared/apps/index.d.ts +1 -1
  76. package/dist/shared/apps/index.js +1 -1
  77. package/dist/shared/apps/selection.d.ts +1 -0
  78. package/dist/shared/apps/selection.js +4 -3
  79. package/dist/shared/apps/store-package.d.ts +13 -0
  80. package/dist/shared/apps/store-package.js +24 -0
  81. package/dist/shared/channel/schema.d.ts +2 -0
  82. package/dist/shared/channel/schema.js +4 -0
  83. package/dist/shared/memory/policy.d.ts +12 -0
  84. package/dist/shared/memory/policy.js +4 -0
  85. package/dist/shared/pty/clipboard-watch.d.ts +4 -0
  86. package/dist/shared/pty/clipboard-watch.js +40 -0
  87. package/dist/shared/pty/ctrl-c.d.ts +13 -7
  88. package/dist/shared/pty/ctrl-c.js +35 -19
  89. package/dist/shared/pty/index.d.ts +1 -0
  90. package/dist/shared/pty/index.js +1 -0
  91. package/dist/shared/pty/terminal.d.ts +1 -1
  92. package/dist/shared/pty/terminal.js +16 -13
  93. package/dist/shared/web/ctrl-c.d.ts +26 -0
  94. package/dist/shared/web/ctrl-c.js +64 -0
  95. package/dist/shared/web/index.d.ts +1 -0
  96. package/dist/shared/web/index.js +1 -0
  97. package/dist/web/index.html +1 -1
  98. package/dist/web/{main-NKM7ECSB.js → main-7NY4X6YU.js} +67 -67
  99. package/native/csharp/HcsHost/AssemblyInfo.cs +3 -3
  100. package/native/csharp/HostTools/AssemblyInfo.cs +3 -3
  101. package/native/csharp/HostTools/Window.cs +1 -1
  102. package/native/csharp/StorageHelper/AssemblyInfo.cs +3 -3
  103. package/native/scripts/get-store-package.ps1 +24 -13
  104. package/package.json +4 -14
  105. package/sandbox/csharp/ClipboardWatch.cs +59 -0
  106. package/sandbox/csharp/MemGov.cs +752 -7
  107. package/sandbox/scripts/install-store-package.ps1 +11 -4
  108. package/sandbox/scripts/watch-clipboard.ps1 +8 -0
  109. package/schemas/config.schema.json +2 -2
  110. package/schemas/sandbox-config.schema.json +1 -1
  111. package/dist/bin/agent-sandbox.d.ts +0 -2
  112. package/dist/bin/agent-sandbox.js +0 -9
  113. package/dist/bin/chunk-4M5SZZ5P.js +0 -10778
  114. package/dist/bin/claude-host.d.ts +0 -2
  115. package/dist/bin/claude-host.js +0 -11
  116. package/dist/bin/claude-sbx.d.ts +0 -2
  117. package/dist/bin/claude-sbx.js +0 -9
  118. package/dist/bin/codex-sbx.d.ts +0 -2
  119. package/dist/bin/codex-sbx.js +0 -9
  120. package/dist/bin/gemini-sbx.d.ts +0 -2
  121. package/dist/bin/gemini-sbx.js +0 -9
  122. package/dist/bin/sbx-hide.d.ts +0 -2
  123. package/dist/bin/sbx-hide.js +0 -9
  124. package/dist/bin/sbx-show.d.ts +0 -2
  125. package/dist/bin/sbx-show.js +0 -9
@@ -25494,7 +25494,7 @@ var SandboxSchema = external_exports.strictObject({
25494
25494
  'The last resort that keeps the sandbox up, in MB below its commit limit (RAM plus paging file): builds are slowed down long before (sandbox.pressureResponse); only if everything the agents start together would take the sandbox to the very edge of its memory, where Windows inside it would start failing, is a build refused memory instead of Windows. "auto" = the larger of 1536 MB and 3 % of the commit limit; "none" = no backstop. Yours only: a project file cannot change it.'
25495
25495
  ),
25496
25496
  pressureResponse: external_exports.boolean().describe(
25497
- "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."
25497
+ "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. A memory gate also holds new compilers and linkers for a moment when the memory of the build programs grows faster than 4 GB in 3 seconds (3 GB with vGPU), and lets them go one at a time. Yours only: a project file cannot change it."
25498
25498
  ),
25499
25499
  vGpu: external_exports.boolean().describe(
25500
25500
  "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)."
@@ -25508,7 +25508,7 @@ var SandboxSchema = external_exports.strictObject({
25508
25508
  printerRedirection: external_exports.boolean().describe("Printers from this PC."),
25509
25509
  protectedClient: external_exports.boolean().describe("Run the sandbox window in Protected Client mode (recommended)."),
25510
25510
  headless: external_exports.boolean().describe(
25511
- "Hide the sandbox window (sbx-show brings it back). A headless sandbox shuts down when its last session ends."
25511
+ 'Hide the sandbox window ("Show the window" brings it back). A headless sandbox shuts down when its last session ends.'
25512
25512
  ),
25513
25513
  keepAwake: external_exports.boolean().describe(
25514
25514
  "Keep this PC from sleeping while a sandbox runs, so agents left working overnight keep going (the screen may still turn off; closing a laptop lid still sleeps it)."
@@ -27934,6 +27934,8 @@ var PressureStatusSchema = external_exports.object({
27934
27934
  lowered: external_exports.number().int().min(0).max(1024),
27935
27935
  /** Compilers waiting their turn right now (name, process id, seconds until they may go on). */
27936
27936
  paused: external_exports.array(external_exports.object({ name: Text(64), pid: external_exports.number().int(), seconds: external_exports.number().int().min(0).max(60) })).max(8),
27937
+ /** Build programs the memory gate holds right now (let go one at a time). */
27938
+ held: external_exports.number().int().min(0).max(1024).optional(),
27937
27939
  /** The CPU share the compilers get together (percent; 100 = no cap). */
27938
27940
  cpuPercent: external_exports.number().int().min(0).max(100).optional(),
27939
27941
  /** The PC itself asked for slowing down (its memory or CPU is low). */
@@ -27954,6 +27956,8 @@ var HeartbeatSchema = external_exports.object({
27954
27956
  topProcesses: external_exports.array(external_exports.object({ name: Text(64), privateMb: external_exports.number().int().min(0).max(1e7) })).max(5),
27955
27957
  /** The disk queue this PC last reported while asking the sandbox to slow down. */
27956
27958
  diskQueueReported: external_exports.number().min(0).max(1e5).optional(),
27959
+ /** Build programs the memory gate holds right now (let go one at a time). */
27960
+ held: external_exports.number().int().min(0).max(1024).optional(),
27957
27961
  /** "ending": the sandbox is shutting down in order (idle shutdown, sandbox stop, Windows shutting down). */
27958
27962
  phase: external_exports.enum(["ready", "working", "ending"])
27959
27963
  });
@@ -28859,7 +28863,7 @@ function writeStatus(phase, message) {
28859
28863
  // src/guest/boot/boot.ts
28860
28864
  import fs95 from "node:fs";
28861
28865
  import path126 from "node:path";
28862
- import { spawn as spawn16 } from "node:child_process";
28866
+ import { spawn as spawn17 } from "node:child_process";
28863
28867
 
28864
28868
  // src/guest/boot/guide.ts
28865
28869
  import fs23 from "node:fs";
@@ -29164,6 +29168,10 @@ function toolLines(primaryName, toolSummary, projects) {
29164
29168
  "- Tools by project: each project gets the tools its own files ask for; python and rust already installed here are on every project's PATH."
29165
29169
  ];
29166
29170
  }
29171
+ function pcLogsGuideLine(launchDir2, exists2) {
29172
+ const dir = path20.win32.join(launchDir2, "pc-logs");
29173
+ return exists2(dir) ? ["- PC crash reports and logs (this project only, read-only, never commit them): `" + dir + "`"] : [];
29174
+ }
29167
29175
 
29168
29176
  // src/shared/unreal/engines.ts
29169
29177
  import crypto3 from "node:crypto";
@@ -31190,6 +31198,7 @@ function sandboxGuide(toolSummary, lan = "blocked", projects = [], addons = [])
31190
31198
  "- RW, persists: `" + stateDir + "` (agent config/history; do not edit logins) \xB7 logs: `" + path36.join(dataDir, "logs") + "`",
31191
31199
  "- RO: `" + launchDir + "` (this boot's scripts) \xB7 lost on close: everything else, incl. `C:\\nvm` (Node symlink)",
31192
31200
  ...mirrorLine(),
31201
+ ...pcLogsGuideLine(launchDir, fs23.existsSync),
31193
31202
  ...toolLines(session.project, toolSummary, projects),
31194
31203
  ...unrealLines(projects),
31195
31204
  ...unityLines(projects),
@@ -31396,11 +31405,10 @@ async function setupBun(env) {
31396
31405
  tool("bun", "bin"),
31397
31406
  { size: "35 MB" }
31398
31407
  );
31399
- Object.assign(env.vars, {
31400
- BUN_INSTALL: tool("bun"),
31401
- BUN_INSTALL_CACHE_DIR: path38.join(localDir, "bun-cache"),
31402
- BUN_TMPDIR: path38.join(localDir, "bun-tmp")
31403
- });
31408
+ const cache = path38.join(localDir, "bun-cache");
31409
+ const temp = path38.join(localDir, "bun-tmp");
31410
+ if (!dryRun) [cache, temp].forEach((dir) => mkdirp(dir));
31411
+ Object.assign(env.vars, { BUN_INSTALL: tool("bun"), BUN_INSTALL_CACHE_DIR: cache, BUN_TMPDIR: temp });
31404
31412
  }
31405
31413
  async function setupDeno(env) {
31406
31414
  await setupSingleExe(
@@ -31978,9 +31986,10 @@ function fileSha256(file3) {
31978
31986
  stream.on("end", () => resolve2(hash2.digest("hex")));
31979
31987
  });
31980
31988
  }
31989
+ var MISSING_PACKAGE = 'this PC did not hand over its package (it could not fetch it: see the launch notes). Fix: on this PC run "winget download --id <product id> --source msstore", then launch again';
31981
31990
  async function checkedPackage(dir) {
31982
31991
  const manifest2 = readValid(StorePackageManifestSchema, path45.join(dir, STORE_PACKAGE_MANIFEST));
31983
- if (!manifest2) throw new Error("the package was not handed over (this PC could not fetch it: see the launch notes)");
31992
+ if (!manifest2) throw new Error(MISSING_PACKAGE);
31984
31993
  for (const f of manifest2.files) {
31985
31994
  if (await fileSha256(path45.join(dir, f.name)).catch(() => "") !== f.sha256)
31986
31995
  throw new Error(f.name + " is missing or changed");
@@ -32360,7 +32369,9 @@ var AppInstaller = class {
32360
32369
  warn(
32361
32370
  entry.name + " could not be installed and is skipped; the other apps are not affected. Reason: " + errMsg(e)
32362
32371
  );
32363
- this.env.summary.push(entry.name + ": FAILED");
32372
+ this.env.summary.push(
32373
+ "store" in entry.source ? entry.name + ": not installed - " + errMsg(e).slice(0, 300) : entry.name + ": FAILED"
32374
+ );
32364
32375
  }
32365
32376
  }
32366
32377
  /** The command line an app's shortcut starts it with (Comet: its own profile, DevTools on 127.0.0.1). */
@@ -38373,9 +38384,68 @@ function cargoLinkerVar(host) {
38373
38384
  }
38374
38385
 
38375
38386
  // src/guest/governor/decide.ts
38387
+ var COMPILERS = /* @__PURE__ */ new Set([
38388
+ "rustc",
38389
+ "clippy-driver",
38390
+ "rustdoc",
38391
+ "cc1",
38392
+ "cc1plus",
38393
+ "cc1obj",
38394
+ "collect2",
38395
+ "gcc",
38396
+ "g++",
38397
+ "c++",
38398
+ "cc",
38399
+ "clang",
38400
+ "clang++",
38401
+ "clang-cl",
38402
+ "cl",
38403
+ "link",
38404
+ "lld",
38405
+ "lld-link",
38406
+ "ld",
38407
+ "ld.lld",
38408
+ "as",
38409
+ "tsc",
38410
+ "javac"
38411
+ ]);
38412
+ var NEVER2 = /* @__PURE__ */ new Set([
38413
+ "claude",
38414
+ "codex",
38415
+ "gemini",
38416
+ "opencode",
38417
+ "aider",
38418
+ "cursor-agent",
38419
+ "cmd",
38420
+ "powershell",
38421
+ "pwsh",
38422
+ "bash",
38423
+ "sh",
38424
+ "zsh",
38425
+ "git",
38426
+ "conhost",
38427
+ "openconsole",
38428
+ "windowsterminal",
38429
+ "wt",
38430
+ "ptyhost",
38431
+ "memgov",
38432
+ "sandboxtools",
38433
+ "sbx-db",
38434
+ "explorer",
38435
+ "csrss",
38436
+ "wininit",
38437
+ "winlogon",
38438
+ "services",
38439
+ "svchost",
38440
+ "lsass",
38441
+ "system",
38442
+ "smss",
38443
+ "dwm"
38444
+ ]);
38376
38445
  function linkerSlots(totalMb, cpus) {
38377
38446
  return Math.max(1, Math.min(4, Math.max(1, Math.floor(cpus)), Math.floor(totalMb / 6144)));
38378
38447
  }
38448
+ var GATE_NAMES = [...COMPILERS, "shadercompileworker"].filter((n) => !NEVER2.has(n)).sort();
38379
38449
 
38380
38450
  // src/guest/toolchains/native/rust-extras.ts
38381
38451
  function resolveTargetDir(rust, free = freeBytes((process.env.SystemDrive ?? "C:") + "\\"), note = warn) {
@@ -42395,8 +42465,37 @@ var OutputFilter = class {
42395
42465
  }
42396
42466
  };
42397
42467
 
42398
- // src/shared/pty/console-input.ts
42468
+ // src/shared/pty/clipboard-watch.ts
42399
42469
  import { spawn as spawn15 } from "node:child_process";
42470
+ var MAX_PENDING = 1024;
42471
+ function watchClipboard(onChange) {
42472
+ if (process.platform !== "win32") return { stop: () => void 0 };
42473
+ let child = null;
42474
+ try {
42475
+ child = spawn15(SYSTEM.powershell(), scriptArgs("watch-clipboard.ps1", ["-ProcessId", String(process.pid)]), {
42476
+ stdio: ["ignore", "pipe", "ignore"],
42477
+ windowsHide: true
42478
+ });
42479
+ } catch {
42480
+ return { stop: () => void 0 };
42481
+ }
42482
+ let pending = "";
42483
+ child.stdout?.setEncoding("latin1");
42484
+ child.stdout?.on("data", (text2) => {
42485
+ const lines = (pending + text2).split("\n");
42486
+ pending = (lines.pop() ?? "").slice(-MAX_PENDING);
42487
+ for (const line of lines) if (line.trim() === "changed") onChange();
42488
+ });
42489
+ child.on("error", () => void 0);
42490
+ return {
42491
+ stop: () => {
42492
+ if (child && child.exitCode === null && child.signalCode === null) child.kill();
42493
+ }
42494
+ };
42495
+ }
42496
+
42497
+ // src/shared/pty/console-input.ts
42498
+ import { spawn as spawn16 } from "node:child_process";
42400
42499
  function enableVtInput() {
42401
42500
  if (process.platform !== "win32" || !process.stdin.isTTY)
42402
42501
  return { ready: Promise.resolve(false), stop: () => Promise.resolve() };
@@ -42404,7 +42503,7 @@ function enableVtInput() {
42404
42503
  let exited2 = Promise.resolve();
42405
42504
  const ready = new Promise((resolve2) => {
42406
42505
  try {
42407
- child = spawn15(SYSTEM.powershell(), scriptArgs("enable-vt-input.ps1", ["-ProcessId", String(process.pid)]), {
42506
+ child = spawn16(SYSTEM.powershell(), scriptArgs("enable-vt-input.ps1", ["-ProcessId", String(process.pid)]), {
42408
42507
  stdio: "ignore",
42409
42508
  windowsHide: true
42410
42509
  });
@@ -42463,30 +42562,94 @@ function unfinishedSequence(data) {
42463
42562
  return data.length;
42464
42563
  }
42465
42564
 
42466
- // src/shared/pty/ctrl-c.ts
42565
+ // src/shared/web/protocol.ts
42566
+ var MAX_CLIENT_MESSAGE_BYTES = 256 * 1024;
42567
+
42568
+ // src/shared/web/ctrl-c.ts
42467
42569
  var CTRL_C_CONFIRM_MS = 1500;
42468
42570
  var CTRL_C_HINT = "Ctrl+C again to send it to the program (Esc stops an agent)";
42469
- var OSC_TITLE = /\x1b\][02];([^\x07\x1b]{0,256})(?:\x07|\x1b\\)/g;
42470
- var CtrlCGuard = class {
42571
+ var CTRL_C_COPY_HINT = "Copied: Ctrl+C after selecting text is not sent to the program (Esc stops an agent)";
42572
+ var CtrlCDecider = class {
42573
+ constructor(confirm = true) {
42574
+ this.confirm = confirm;
42575
+ }
42576
+ confirm;
42471
42577
  armedAt = Number.NEGATIVE_INFINITY;
42472
- lastTitle = "";
42473
- /** What to send for one read from the keyboard: a lone Ctrl+C only when another came just before. */
42474
- push(chunk, nowMs) {
42475
- if (chunk.length !== 1 || chunk[0] !== 3) return { send: chunk, held: false };
42578
+ selected = false;
42579
+ /** Text was selected in the program: Ctrl+C is "copy" from now on. */
42580
+ selection() {
42581
+ this.selected = true;
42582
+ this.armedAt = Number.NEGATIVE_INFINITY;
42583
+ }
42584
+ /** Any other key or a click: Ctrl+C is an interrupt again. */
42585
+ otherInput() {
42586
+ this.selected = false;
42587
+ }
42588
+ /** What to do with a lone Ctrl+C pressed at `nowMs`. */
42589
+ ctrlC(nowMs) {
42590
+ if (this.selected) return "copy";
42591
+ if (!this.confirm) return "send";
42476
42592
  if (nowMs - this.armedAt <= CTRL_C_CONFIRM_MS) {
42477
42593
  this.armedAt = Number.NEGATIVE_INFINITY;
42478
- return { send: chunk, held: false };
42594
+ return "send";
42479
42595
  }
42480
42596
  this.armedAt = nowMs;
42481
- return { send: Buffer.alloc(0), held: true };
42597
+ return "hold";
42598
+ }
42599
+ };
42600
+ var MOUSE_REPORT = /\x1b\[<(\d{1,4});\d{1,5};\d{1,5}([Mm])|\x1b\[M([\s\S])[\s\S]{2}/g;
42601
+ function classifyInput(text2) {
42602
+ let drag = false;
42603
+ let click = false;
42604
+ for (const m of text2.matchAll(MOUSE_REPORT)) {
42605
+ const sgr = m[1] !== void 0;
42606
+ const b = sgr ? Number(m[1]) : (m[3] ?? " ").charCodeAt(0) - 32;
42607
+ if (b & 64) continue;
42608
+ if (b & 32) {
42609
+ if ((b & 3) !== 3) drag = true;
42610
+ } else if (sgr ? m[2] === "M" : (b & 3) !== 3) click = true;
42611
+ }
42612
+ return { mouse: drag ? "drag" : click ? "click" : null, keys: text2.replace(MOUSE_REPORT, "").length > 0 };
42613
+ }
42614
+ function hasClipboardWrite(text2) {
42615
+ return /\x1b\]0{0,2}52;/.test(text2) || /\u009d0{0,2}52;/.test(text2);
42616
+ }
42617
+
42618
+ // src/shared/pty/ctrl-c.ts
42619
+ var OSC_TITLE = /\x1b\][02];([^\x07\x1b]{0,256})(?:\x07|\x1b\\)/g;
42620
+ var CtrlCGuard = class {
42621
+ decider;
42622
+ lastTitle = "";
42623
+ constructor(options = {}) {
42624
+ this.decider = new CtrlCDecider(options.confirm !== false);
42625
+ }
42626
+ /** What to send for one read from the keyboard: a lone Ctrl+C only when it is not held back or taken as "copy". */
42627
+ push(chunk, nowMs) {
42628
+ if (chunk.length === 1 && chunk[0] === 3) {
42629
+ const action = this.decider.ctrlC(nowMs);
42630
+ if (action === "send") return { send: chunk, held: false, copied: false };
42631
+ return { send: Buffer.alloc(0), held: action === "hold", copied: action === "copy" };
42632
+ }
42633
+ const c = classifyInput(chunk.toString("latin1"));
42634
+ if (c.keys || c.mouse === "click") this.decider.otherInput();
42635
+ else if (c.mouse === "drag") this.decider.selection();
42636
+ return { send: chunk, held: false, copied: false };
42637
+ }
42638
+ /** The clipboard changed since the last key: you just copied. */
42639
+ clipboardChanged() {
42640
+ this.decider.selection();
42641
+ }
42642
+ /** The program wrote to the clipboard: that is a selection too. */
42643
+ watchClipboard(raw) {
42644
+ if (hasClipboardWrite(raw)) this.decider.selection();
42482
42645
  }
42483
42646
  /** Remembers the title the program last set (from its output), to put it back after the hint. */
42484
42647
  watchOutput(text2) {
42485
42648
  for (const m of text2.matchAll(OSC_TITLE)) this.lastTitle = m[1];
42486
42649
  }
42487
42650
  /** The escape sequence that shows the hint, and the one that puts the program's title back. */
42488
- hintTitle() {
42489
- return "\x1B]0;" + CTRL_C_HINT + "\x07";
42651
+ hintTitle(kind = "hold") {
42652
+ return "\x1B]0;" + (kind === "copy" ? CTRL_C_COPY_HINT : CTRL_C_HINT) + "\x07";
42490
42653
  }
42491
42654
  restoreTitle() {
42492
42655
  return "\x1B]0;" + this.lastTitle.replace(/[\x00-\x1f\x7f]/g, "") + "\x07";
@@ -42690,6 +42853,7 @@ function runTerminalClient(socket, token, options = {}) {
42690
42853
  clearTimeout(joinTimer);
42691
42854
  clearTimeout(hintTimer);
42692
42855
  clearTimeout(vtTimer);
42856
+ clipboard.stop();
42693
42857
  socket.destroy();
42694
42858
  const tracked = mouse.tracking();
42695
42859
  const reset = "\x1B[0m\x1B[?25h" + MOUSE_OFF + (mouse.has(2004) ? "\x1B[?2004l" : "") + "\r\n";
@@ -42707,23 +42871,22 @@ function runTerminalClient(socket, token, options = {}) {
42707
42871
  if (data.length && !done) socket.write(encodeFrame2(FrameType.Input, data));
42708
42872
  };
42709
42873
  const sendInput = (data) => write(keys.push(passthrough ? mouse.filter(data) : data));
42710
- const guard = options.confirmCtrlC ? new CtrlCGuard() : null;
42874
+ const guard = new CtrlCGuard({ confirm: options.confirmCtrlC !== false });
42711
42875
  let hintTimer;
42876
+ const clipboard = watchClipboard(() => guard.clipboardChanged());
42712
42877
  const onInput = (chunk) => {
42713
42878
  if (options.detachKey !== void 0 && chunk.includes(options.detachKey)) {
42714
42879
  finish({ reason: "detach" });
42715
42880
  return;
42716
42881
  }
42717
- if (guard) {
42718
- const decided = guard.push(chunk, Date.now());
42719
- clearTimeout(hintTimer);
42720
- if (decided.held) {
42721
- stdout.write(guard.hintTitle());
42722
- hintTimer = setTimeout(() => stdout.write(guard.restoreTitle()), CTRL_C_CONFIRM_MS);
42723
- return;
42724
- }
42725
- if (decided.send.length === 1 && decided.send[0] === 3) stdout.write(guard.restoreTitle());
42882
+ const decided = guard.push(chunk, Date.now());
42883
+ clearTimeout(hintTimer);
42884
+ if (decided.held || decided.copied) {
42885
+ stdout.write(guard.hintTitle(decided.copied ? "copy" : "hold"));
42886
+ hintTimer = setTimeout(() => stdout.write(guard.restoreTitle()), CTRL_C_CONFIRM_MS);
42887
+ return;
42726
42888
  }
42889
+ if (decided.send.length === 1 && decided.send[0] === 3) stdout.write(guard.restoreTitle());
42727
42890
  clearTimeout(joinTimer);
42728
42891
  sendInput(joiner.push(chunk));
42729
42892
  if (joiner.holding()) joinTimer = setTimeout(() => sendInput(joiner.flush()), JOIN_MS);
@@ -42756,9 +42919,10 @@ function runTerminalClient(socket, token, options = {}) {
42756
42919
  }
42757
42920
  for (const frame of frames) {
42758
42921
  if (frame.type === FrameType.Output) {
42922
+ guard.watchClipboard(frame.payload.toString("latin1"));
42759
42923
  const out = filter.push(frame.payload);
42760
42924
  mouse.watch(out);
42761
- guard?.watchOutput(out.toString("latin1"));
42925
+ guard.watchOutput(out.toString("latin1"));
42762
42926
  stdout.write(out);
42763
42927
  } else if (frame.type === FrameType.Console) passthrough = frame.payload.toString("latin1") === "conpty.dll";
42764
42928
  else if (frame.type === FrameType.Restarting) {
@@ -43851,7 +44015,7 @@ var VSCODE_LANGUAGES = [
43851
44015
  "pwsh"
43852
44016
  ];
43853
44017
  function startDaemon(env, secrets) {
43854
- spawn16(process.execPath, [path126.join(path126.dirname(process.argv[1]), "daemon.js")], {
44018
+ spawn17(process.execPath, [path126.join(path126.dirname(process.argv[1]), "daemon.js")], {
43855
44019
  detached: true,
43856
44020
  stdio: "ignore",
43857
44021
  windowsHide: true,
@@ -25530,7 +25530,7 @@ var SandboxSchema = external_exports.strictObject({
25530
25530
  'The last resort that keeps the sandbox up, in MB below its commit limit (RAM plus paging file): builds are slowed down long before (sandbox.pressureResponse); only if everything the agents start together would take the sandbox to the very edge of its memory, where Windows inside it would start failing, is a build refused memory instead of Windows. "auto" = the larger of 1536 MB and 3 % of the commit limit; "none" = no backstop. Yours only: a project file cannot change it.'
25531
25531
  ),
25532
25532
  pressureResponse: external_exports.boolean().describe(
25533
- "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."
25533
+ "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. A memory gate also holds new compilers and linkers for a moment when the memory of the build programs grows faster than 4 GB in 3 seconds (3 GB with vGPU), and lets them go one at a time. Yours only: a project file cannot change it."
25534
25534
  ),
25535
25535
  vGpu: external_exports.boolean().describe(
25536
25536
  "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)."
@@ -25544,7 +25544,7 @@ var SandboxSchema = external_exports.strictObject({
25544
25544
  printerRedirection: external_exports.boolean().describe("Printers from this PC."),
25545
25545
  protectedClient: external_exports.boolean().describe("Run the sandbox window in Protected Client mode (recommended)."),
25546
25546
  headless: external_exports.boolean().describe(
25547
- "Hide the sandbox window (sbx-show brings it back). A headless sandbox shuts down when its last session ends."
25547
+ 'Hide the sandbox window ("Show the window" brings it back). A headless sandbox shuts down when its last session ends.'
25548
25548
  ),
25549
25549
  keepAwake: external_exports.boolean().describe(
25550
25550
  "Keep this PC from sleeping while a sandbox runs, so agents left working overnight keep going (the screen may still turn off; closing a laptop lid still sleeps it)."
@@ -27728,6 +27728,8 @@ var PressureStatusSchema = external_exports.object({
27728
27728
  lowered: external_exports.number().int().min(0).max(1024),
27729
27729
  /** Compilers waiting their turn right now (name, process id, seconds until they may go on). */
27730
27730
  paused: external_exports.array(external_exports.object({ name: Text(64), pid: external_exports.number().int(), seconds: external_exports.number().int().min(0).max(60) })).max(8),
27731
+ /** Build programs the memory gate holds right now (let go one at a time). */
27732
+ held: external_exports.number().int().min(0).max(1024).optional(),
27731
27733
  /** The CPU share the compilers get together (percent; 100 = no cap). */
27732
27734
  cpuPercent: external_exports.number().int().min(0).max(100).optional(),
27733
27735
  /** The PC itself asked for slowing down (its memory or CPU is low). */
@@ -27748,6 +27750,8 @@ var HeartbeatSchema = external_exports.object({
27748
27750
  topProcesses: external_exports.array(external_exports.object({ name: Text(64), privateMb: external_exports.number().int().min(0).max(1e7) })).max(5),
27749
27751
  /** The disk queue this PC last reported while asking the sandbox to slow down. */
27750
27752
  diskQueueReported: external_exports.number().min(0).max(1e5).optional(),
27753
+ /** Build programs the memory gate holds right now (let go one at a time). */
27754
+ held: external_exports.number().int().min(0).max(1024).optional(),
27751
27755
  /** "ending": the sandbox is shutting down in order (idle shutdown, sandbox stop, Windows shutting down). */
27752
27756
  phase: external_exports.enum(["ready", "working", "ending"])
27753
27757
  });
@@ -25916,7 +25916,7 @@ var SandboxSchema = external_exports.strictObject({
25916
25916
  'The last resort that keeps the sandbox up, in MB below its commit limit (RAM plus paging file): builds are slowed down long before (sandbox.pressureResponse); only if everything the agents start together would take the sandbox to the very edge of its memory, where Windows inside it would start failing, is a build refused memory instead of Windows. "auto" = the larger of 1536 MB and 3 % of the commit limit; "none" = no backstop. Yours only: a project file cannot change it.'
25917
25917
  ),
25918
25918
  pressureResponse: external_exports.boolean().describe(
25919
- "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."
25919
+ "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. A memory gate also holds new compilers and linkers for a moment when the memory of the build programs grows faster than 4 GB in 3 seconds (3 GB with vGPU), and lets them go one at a time. Yours only: a project file cannot change it."
25920
25920
  ),
25921
25921
  vGpu: external_exports.boolean().describe(
25922
25922
  "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)."
@@ -25930,7 +25930,7 @@ var SandboxSchema = external_exports.strictObject({
25930
25930
  printerRedirection: external_exports.boolean().describe("Printers from this PC."),
25931
25931
  protectedClient: external_exports.boolean().describe("Run the sandbox window in Protected Client mode (recommended)."),
25932
25932
  headless: external_exports.boolean().describe(
25933
- "Hide the sandbox window (sbx-show brings it back). A headless sandbox shuts down when its last session ends."
25933
+ 'Hide the sandbox window ("Show the window" brings it back). A headless sandbox shuts down when its last session ends.'
25934
25934
  ),
25935
25935
  keepAwake: external_exports.boolean().describe(
25936
25936
  "Keep this PC from sleeping while a sandbox runs, so agents left working overnight keep going (the screen may still turn off; closing a laptop lid still sleeps it)."
@@ -28114,6 +28114,8 @@ var PressureStatusSchema = external_exports.object({
28114
28114
  lowered: external_exports.number().int().min(0).max(1024),
28115
28115
  /** Compilers waiting their turn right now (name, process id, seconds until they may go on). */
28116
28116
  paused: external_exports.array(external_exports.object({ name: Text(64), pid: external_exports.number().int(), seconds: external_exports.number().int().min(0).max(60) })).max(8),
28117
+ /** Build programs the memory gate holds right now (let go one at a time). */
28118
+ held: external_exports.number().int().min(0).max(1024).optional(),
28117
28119
  /** The CPU share the compilers get together (percent; 100 = no cap). */
28118
28120
  cpuPercent: external_exports.number().int().min(0).max(100).optional(),
28119
28121
  /** The PC itself asked for slowing down (its memory or CPU is low). */
@@ -28134,6 +28136,8 @@ var HeartbeatSchema = external_exports.object({
28134
28136
  topProcesses: external_exports.array(external_exports.object({ name: Text(64), privateMb: external_exports.number().int().min(0).max(1e7) })).max(5),
28135
28137
  /** The disk queue this PC last reported while asking the sandbox to slow down. */
28136
28138
  diskQueueReported: external_exports.number().min(0).max(1e5).optional(),
28139
+ /** Build programs the memory gate holds right now (let go one at a time). */
28140
+ held: external_exports.number().int().min(0).max(1024).optional(),
28137
28141
  /** "ending": the sandbox is shutting down in order (idle shutdown, sandbox stop, Windows shutting down). */
28138
28142
  phase: external_exports.enum(["ready", "working", "ending"])
28139
28143
  });