windows-development-sandbox 1.23.0 → 1.23.2

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.
@@ -2,8 +2,8 @@
2
2
  import { createRequire as __createRequire } from 'node:module'; const require = __createRequire(import.meta.url);
3
3
  import {
4
4
  run
5
- } from "./chunk-JETGP2C3.js";
6
- import "./chunk-ZTTOF5V3.js";
5
+ } from "./chunk-7YPEDAJD.js";
6
+ import "./chunk-USTRSHIE.js";
7
7
 
8
8
  // src/bin/agent-sandbox.ts
9
9
  run(process.argv.slice(2));
@@ -251,7 +251,7 @@ import {
251
251
  withOperationCommands,
252
252
  working,
253
253
  writeJson
254
- } from "./chunk-ZTTOF5V3.js";
254
+ } from "./chunk-USTRSHIE.js";
255
255
 
256
256
  // node_modules/commander/lib/error.js
257
257
  var require_error = __commonJS({
@@ -1,7 +1,7 @@
1
1
  import { createRequire as __createRequire } from 'node:module'; const require = __createRequire(import.meta.url);
2
2
  import {
3
3
  attach
4
- } from "./chunk-ZTTOF5V3.js";
4
+ } from "./chunk-USTRSHIE.js";
5
5
  export {
6
6
  attach
7
7
  };
@@ -56595,14 +56595,14 @@ function cometSummary(p) {
56595
56595
  }
56596
56596
 
56597
56597
  // src/shared/accounts/anthropic.ts
56598
- var ANTHROPIC_KEY_PATTERN = /^sk-ant-(api|usr)\d{2}-[A-Za-z0-9_-]{20,400}$/;
56599
- var ANTHROPIC_KEY_HINT = /^sk-ant-\.\.\.[A-Za-z0-9_-]{4}$/;
56598
+ var ANTHROPIC_KEY_PATTERN = /^[A-Za-z0-9][A-Za-z0-9_.-]{19,511}$/;
56599
+ var ANTHROPIC_KEY_HINT = /^([A-Za-z0-9]{1,8}-?[A-Za-z]*-?)?\.\.\.[A-Za-z0-9_.-]{4}$/;
56600
56600
  function anthropicKeyProblem(key3) {
56601
- if (ANTHROPIC_KEY_PATTERN.test(key3)) return null;
56602
56601
  if (key3.startsWith("sk-ant-oat"))
56603
56602
  return "That is a Claude subscription token (from claude setup-token), not an API key. Save the subscription login instead.";
56604
56603
  if (key3.startsWith("sk-ant-admin")) return "That is an Admin key: it cannot run Claude. Make an API key instead.";
56605
- return "An Anthropic API key starts with sk-ant-api or sk-ant-usr and has only letters, digits, - and _ (copy it from the Claude Console).";
56604
+ if (ANTHROPIC_KEY_PATTERN.test(key3)) return null;
56605
+ return "That does not look like an API key: paste the whole key (letters, digits, - and _, no spaces).";
56606
56606
  }
56607
56607
 
56608
56608
  // src/core/local-config/file.ts
@@ -57556,7 +57556,8 @@ import path70 from "node:path";
57556
57556
  var LOGIN_KINDS = ["subscription", "console", "api-key"];
57557
57557
  var apiKeyProblem = anthropicKeyProblem;
57558
57558
  function maskApiKey(key3) {
57559
- return "sk-ant-..." + key3.slice(-4);
57559
+ const prefix = /^[A-Za-z0-9]{1,8}-[A-Za-z]{1,8}-/.exec(key3)?.[0] ?? "";
57560
+ return prefix + "..." + key3.slice(-4);
57560
57561
  }
57561
57562
  function approvalOf(key3) {
57562
57563
  return key3.trim().slice(-20);
@@ -82441,7 +82442,7 @@ async function attachOpened(ctx, session) {
82441
82442
  nextStep("sandbox attach " + session);
82442
82443
  return 0;
82443
82444
  }
82444
- const { attach: attach2 } = await import("./chunk-XZKOPGNH.js");
82445
+ const { attach: attach2 } = await import("./chunk-QFSJX2KW.js");
82445
82446
  return attach2({ ...ctx, options: { ...ctx.options, positionals: [session] } });
82446
82447
  }
82447
82448
  function definitionHandler(def) {
@@ -2,8 +2,8 @@
2
2
  import { createRequire as __createRequire } from 'node:module'; const require = __createRequire(import.meta.url);
3
3
  import {
4
4
  run
5
- } from "./chunk-JETGP2C3.js";
6
- import "./chunk-ZTTOF5V3.js";
5
+ } from "./chunk-7YPEDAJD.js";
6
+ import "./chunk-USTRSHIE.js";
7
7
 
8
8
  // src/bin/claude-host.ts
9
9
  var args = process.argv.slice(2);
@@ -2,8 +2,8 @@
2
2
  import { createRequire as __createRequire } from 'node:module'; const require = __createRequire(import.meta.url);
3
3
  import {
4
4
  run
5
- } from "./chunk-JETGP2C3.js";
6
- import "./chunk-ZTTOF5V3.js";
5
+ } from "./chunk-7YPEDAJD.js";
6
+ import "./chunk-USTRSHIE.js";
7
7
 
8
8
  // src/bin/claude-sbx.ts
9
9
  run(process.argv.slice(2), { harness: "claude" });
@@ -2,8 +2,8 @@
2
2
  import { createRequire as __createRequire } from 'node:module'; const require = __createRequire(import.meta.url);
3
3
  import {
4
4
  run
5
- } from "./chunk-JETGP2C3.js";
6
- import "./chunk-ZTTOF5V3.js";
5
+ } from "./chunk-7YPEDAJD.js";
6
+ import "./chunk-USTRSHIE.js";
7
7
 
8
8
  // src/bin/codex-sbx.ts
9
9
  run(process.argv.slice(2), { harness: "codex" });
@@ -2,8 +2,8 @@
2
2
  import { createRequire as __createRequire } from 'node:module'; const require = __createRequire(import.meta.url);
3
3
  import {
4
4
  run
5
- } from "./chunk-JETGP2C3.js";
6
- import "./chunk-ZTTOF5V3.js";
5
+ } from "./chunk-7YPEDAJD.js";
6
+ import "./chunk-USTRSHIE.js";
7
7
 
8
8
  // src/bin/gemini-sbx.ts
9
9
  run(process.argv.slice(2), { harness: "gemini" });
@@ -2,8 +2,8 @@
2
2
  import { createRequire as __createRequire } from 'node:module'; const require = __createRequire(import.meta.url);
3
3
  import {
4
4
  run
5
- } from "./chunk-JETGP2C3.js";
6
- import "./chunk-ZTTOF5V3.js";
5
+ } from "./chunk-7YPEDAJD.js";
6
+ import "./chunk-USTRSHIE.js";
7
7
 
8
8
  // src/bin/sandbox.ts
9
9
  run(process.argv.slice(2));
@@ -2,8 +2,8 @@
2
2
  import { createRequire as __createRequire } from 'node:module'; const require = __createRequire(import.meta.url);
3
3
  import {
4
4
  run
5
- } from "./chunk-JETGP2C3.js";
6
- import "./chunk-ZTTOF5V3.js";
5
+ } from "./chunk-7YPEDAJD.js";
6
+ import "./chunk-USTRSHIE.js";
7
7
 
8
8
  // src/bin/sbx-hide.ts
9
9
  run(process.argv.slice(2), { command: "hide" });
@@ -2,8 +2,8 @@
2
2
  import { createRequire as __createRequire } from 'node:module'; const require = __createRequire(import.meta.url);
3
3
  import {
4
4
  run
5
- } from "./chunk-JETGP2C3.js";
6
- import "./chunk-ZTTOF5V3.js";
5
+ } from "./chunk-7YPEDAJD.js";
6
+ import "./chunk-USTRSHIE.js";
7
7
 
8
8
  // src/bin/sbx-show.ts
9
9
  run(process.argv.slice(2), { command: "show" });
@@ -21,7 +21,11 @@ export declare function visualStudioWanted(t: Toolchains, on?: (setting: boolean
21
21
  export declare function unrealUsesAutosdk(t: Toolchains, on?: (setting: boolean | 'auto', name: string) => boolean): boolean;
22
22
  /** The Visual Studio installer's exit code in plain words (it is a uint32: -1 and 4294967295 are the same). */
23
23
  export declare function vsExitText(code: number): string;
24
- /** Room the staging copy of the layout needs on the sandbox's own disk, on top of the reserve. */
24
+ /**
25
+ * Room the staging copy of the layout needs on the sandbox's own disk, on top of the reserve. The layout of the Unreal
26
+ * components is about the size of their download (5-8 GB); the sandbox's ~40 GB disk has about 14 GB free at boot
27
+ * (a fixed paging file takes 16 GB), so the estimate must stay under that. A layout that outgrows it fails cleanly.
28
+ */
25
29
  export declare const LAYOUT_STAGING_BYTES: number;
26
30
  /** Spare room on the sandbox's disk while the layout is built there (before Visual Studio is installed). */
27
31
  export declare const STAGING_RESERVE_BYTES: number;
@@ -74,10 +74,14 @@ export function vsExitText(code) {
74
74
  return 'the installer failed with exit ' + c + ' (0x' + c.toString(16).toUpperCase() + ')';
75
75
  }
76
76
  }
77
- /** Room the staging copy of the layout needs on the sandbox's own disk, on top of the reserve. */
78
- export const LAYOUT_STAGING_BYTES = 12 * 1024 ** 3;
77
+ /**
78
+ * Room the staging copy of the layout needs on the sandbox's own disk, on top of the reserve. The layout of the Unreal
79
+ * components is about the size of their download (5-8 GB); the sandbox's ~40 GB disk has about 14 GB free at boot
80
+ * (a fixed paging file takes 16 GB), so the estimate must stay under that. A layout that outgrows it fails cleanly.
81
+ */
82
+ export const LAYOUT_STAGING_BYTES = 8 * 1024 ** 3;
79
83
  /** Spare room on the sandbox's disk while the layout is built there (before Visual Studio is installed). */
80
- export const STAGING_RESERVE_BYTES = 3 * 1024 ** 3;
84
+ export const STAGING_RESERVE_BYTES = 1.5 * 1024 ** 3;
81
85
  /**
82
86
  * What to do after the layout attempt in the data disk: 'done' when it worked, 'stage' (build it on the sandbox's
83
87
  * own disk and copy it over) when it failed and that disk has room, 'skip' (download this boot) otherwise.
@@ -17,9 +17,9 @@ export interface CaptureOptions {
17
17
  /** ANTHROPIC_API_KEY of this PC: the last place looked at (--from-host only). */
18
18
  readonly envKey?: string | null;
19
19
  }
20
- /** What is wrong with a typed or found API key (sk-ant-api or sk-ant-usr), or null. Never quotes the key. */
20
+ /** What is wrong with a typed or found API key (any Claude Console key), or null. Never quotes the key. */
21
21
  export declare const apiKeyProblem: typeof anthropicKeyProblem;
22
- /** The most of a key that is ever shown: sk-ant-...abcd. */
22
+ /** The most of a key that is ever shown: its prefix (sk-ant-...abcd, skt-ant-...abcd), then its last 4 characters. */
23
23
  export declare function maskApiKey(key: string): string;
24
24
  export interface LoginFiles {
25
25
  readonly claudeDir: string;
@@ -14,11 +14,12 @@ import { assertTestWritable } from '../test-guard.js';
14
14
  import { hostDataFolder, hostDataRoot } from '../storage/index.js';
15
15
  import { assertNoLinks, fail, fileExists, isLink, removeLink, tryReadJson, writeJson } from '../../core/util/index.js';
16
16
  export const LOGIN_KINDS = ['subscription', 'console', 'api-key'];
17
- /** What is wrong with a typed or found API key (sk-ant-api or sk-ant-usr), or null. Never quotes the key. */
17
+ /** What is wrong with a typed or found API key (any Claude Console key), or null. Never quotes the key. */
18
18
  export const apiKeyProblem = anthropicKeyProblem;
19
- /** The most of a key that is ever shown: sk-ant-...abcd. */
19
+ /** The most of a key that is ever shown: its prefix (sk-ant-...abcd, skt-ant-...abcd), then its last 4 characters. */
20
20
  export function maskApiKey(key) {
21
- return 'sk-ant-...' + key.slice(-4);
21
+ const prefix = /^[A-Za-z0-9]{1,8}-[A-Za-z]{1,8}-/.exec(key)?.[0] ?? '';
22
+ return prefix + '...' + key.slice(-4);
22
23
  }
23
24
  /** What Claude Code records in customApiKeyResponses for a key it may use (its last 20 characters). */
24
25
  function approvalOf(key) {
@@ -32993,8 +32993,8 @@ function vsExitText(code) {
32993
32993
  return "the installer failed with exit " + c + " (0x" + c.toString(16).toUpperCase() + ")";
32994
32994
  }
32995
32995
  }
32996
- var LAYOUT_STAGING_BYTES = 12 * 1024 ** 3;
32997
- var STAGING_RESERVE_BYTES = 3 * 1024 ** 3;
32996
+ var LAYOUT_STAGING_BYTES = 8 * 1024 ** 3;
32997
+ var STAGING_RESERVE_BYTES = 1.5 * 1024 ** 3;
32998
32998
  function layoutNextStep(exit, localFreeBytes, reserveBytes) {
32999
32999
  if (exit !== null && (exit === 0 || exit === 3010)) return "done";
33000
33000
  return localFreeBytes >= LAYOUT_STAGING_BYTES + reserveBytes ? "stage" : "skip";
@@ -32442,8 +32442,8 @@ function vsExitText(code) {
32442
32442
  return "the installer failed with exit " + c + " (0x" + c.toString(16).toUpperCase() + ")";
32443
32443
  }
32444
32444
  }
32445
- var LAYOUT_STAGING_BYTES = 12 * 1024 ** 3;
32446
- var STAGING_RESERVE_BYTES = 3 * 1024 ** 3;
32445
+ var LAYOUT_STAGING_BYTES = 8 * 1024 ** 3;
32446
+ var STAGING_RESERVE_BYTES = 1.5 * 1024 ** 3;
32447
32447
  function layoutNextStep(exit, localFreeBytes, reserveBytes) {
32448
32448
  if (exit !== null && (exit === 0 || exit === 3010)) return "done";
32449
32449
  return localFreeBytes >= LAYOUT_STAGING_BYTES + reserveBytes ? "stage" : "skip";
@@ -263,7 +263,7 @@ async function apiKeyAccounts(t, f) {
263
263
  const said = JSON.stringify([out, asked.seen]);
264
264
  t.check(asked.seen.questions.length === 2 &&
265
265
  asked.seen.questions.every((q) => q.kind === 'secret') &&
266
- asked.seen.questions[1].problem?.includes('sk-ant-api') === true &&
266
+ asked.seen.questions[1].problem?.includes('does not look like an API key') === true &&
267
267
  out.message === 'Saved account "typed" (API key sk-ant-...Type).' &&
268
268
  !said.includes(TYPED_KEY.slice(13)), 'save --api-key asks for the key hidden, asks again on a bad one, and says only sk-ant-...last4', said);
269
269
  await t.throws(() => runDefinition('accounts.save', ctx, { agent: 'codex', name: 'x', apiKey: true }, fakeIO([]).io), 'for Claude accounts only', 'save --api-key is refused for another agent');
@@ -43,6 +43,12 @@ export const agentSettingsSuite = {
43
43
  t.check(ANTHROPIC_KEY_PATTERN.test('sk-ant-usr01-' + body) && ANTHROPIC_KEY_PATTERN.test('sk-ant-api03-' + body), 'sk-ant-api03- and sk-ant-usr01- keys are accepted');
44
44
  t.check(!ANTHROPIC_KEY_PATTERN.test('sk-ant-usr1-x') && anthropicKeyProblem('sk-ant-usr1-x') !== null, 'a short or malformed key is refused');
45
45
  t.check(anthropicKeyProblem('sk-ant-usr01-' + body) === null, 'no problem for a user-workspace key');
46
+ t.check(anthropicKeyProblem('skt-ant-usr-' + 'b'.repeat(40)) === null &&
47
+ ANTHROPIC_KEY_PATTERN.test('skt-ant-usr-' + 'b'.repeat(40)), 'a key with any Console prefix (skt-ant-usr-...) is accepted');
48
+ t.check(anthropicKeyProblem('sk-ant-api03-' + 'c'.repeat(20) + ' x') !== null &&
49
+ anthropicKeyProblem('k'.repeat(19)) !== null, 'a key with a space, or under 20 characters, is refused');
50
+ t.check(anthropicKeyProblem('sk-ant-oat01-' + body)?.includes('subscription token') === true &&
51
+ anthropicKeyProblem('sk-ant-admin01-' + body)?.includes('Admin key') === true, 'a subscription token and an Admin key still get their own messages');
46
52
  t.section('Claude environment catalogue');
47
53
  const names = CLAUDE_ENV.map((s) => s.name);
48
54
  t.check(new Set(names).size === names.length, 'names are unique');
@@ -144,9 +144,10 @@ export const persistedInstallsSuite = {
144
144
  t.check(layoutNextStep(0, 0, reserve) === 'done' &&
145
145
  layoutNextStep(3762504530, room(40 * GB), reserve) === 'stage' &&
146
146
  layoutNextStep(3762504530, room(20 * GB), reserve) === 'skip' &&
147
- layoutNextStep(null, room(40 * GB), reserve) === 'stage', 'a failed layout is built on the sandbox disk only with room for it (12 GB plus the reserve)');
148
- t.check(layoutNextStep(null, room(15 * GB), STAGING_RESERVE_BYTES) === 'stage' &&
149
- layoutNextStep(null, room(14 * GB), STAGING_RESERVE_BYTES) === 'skip', 'before Visual Studio is installed, 15 GB free on C: is enough to build the install files there');
147
+ layoutNextStep(null, room(40 * GB), reserve) === 'stage', 'a failed layout is built on the sandbox disk only with room for it (8 GB plus the reserve)');
148
+ t.check(layoutNextStep(null, room(14 * GB), STAGING_RESERVE_BYTES) === 'stage' &&
149
+ layoutNextStep(null, room(9.5 * GB), STAGING_RESERVE_BYTES) === 'stage' &&
150
+ layoutNextStep(null, room(9 * GB), STAGING_RESERVE_BYTES) === 'skip', 'before Visual Studio is installed, the ~14 GB free at boot is enough to build the install files (9.5 GB needed)');
150
151
  t.equal(freeBytesAt(path.join(t.dir('layout-room'), 'not', 'there'), () => ({ bavail: 3, bsize: 2 })), 6, 'free room of a folder that does not exist asks its parent');
151
152
  t.equal(freeBytesAt(t.dir('layout-room'), () => {
152
153
  throw new Error('no');
@@ -1,5 +1,5 @@
1
1
  export declare const ANTHROPIC_KEY_PATTERN: RegExp;
2
- /** The only part of a key ever shown: sk-ant-...abcd. */
2
+ /** The only part of a key ever shown: its own prefix (sk-ant-, skt-ant-), then ..., then its last 4 characters. */
3
3
  export declare const ANTHROPIC_KEY_HINT: RegExp;
4
4
  /** What is wrong with a typed or found API key, or null when it has the right shape. Never quotes the key. */
5
5
  export declare function anthropicKeyProblem(key: string): string | null;
@@ -1,15 +1,16 @@
1
- // The one shape of an Anthropic API key, for the host and the web (no node imports). A key from the Claude Console
2
- // starts with sk-ant-api, a key from a user workspace with sk-ant-usr.
3
- export const ANTHROPIC_KEY_PATTERN = /^sk-ant-(api|usr)\d{2}-[A-Za-z0-9_-]{20,400}$/;
4
- /** The only part of a key ever shown: sk-ant-...abcd. */
5
- export const ANTHROPIC_KEY_HINT = /^sk-ant-\.\.\.[A-Za-z0-9_-]{4}$/;
1
+ // The shape of an Anthropic API key, for the host and the web (no node imports). Any key from the Claude Console is
2
+ // accepted, whatever its prefix (sk-ant-api03-..., skt-ant-usr-... and others): only text with spaces or other odd
3
+ // characters, or under 20 characters, is refused. Subscription tokens and Admin keys are refused by name.
4
+ export const ANTHROPIC_KEY_PATTERN = /^[A-Za-z0-9][A-Za-z0-9_.-]{19,511}$/;
5
+ /** The only part of a key ever shown: its own prefix (sk-ant-, skt-ant-), then ..., then its last 4 characters. */
6
+ export const ANTHROPIC_KEY_HINT = /^([A-Za-z0-9]{1,8}-?[A-Za-z]*-?)?\.\.\.[A-Za-z0-9_.-]{4}$/;
6
7
  /** What is wrong with a typed or found API key, or null when it has the right shape. Never quotes the key. */
7
8
  export function anthropicKeyProblem(key) {
8
- if (ANTHROPIC_KEY_PATTERN.test(key))
9
- return null;
10
9
  if (key.startsWith('sk-ant-oat'))
11
10
  return 'That is a Claude subscription token (from claude setup-token), not an API key. Save the subscription login instead.';
12
11
  if (key.startsWith('sk-ant-admin'))
13
12
  return 'That is an Admin key: it cannot run Claude. Make an API key instead.';
14
- return 'An Anthropic API key starts with sk-ant-api or sk-ant-usr and has only letters, digits, - and _ (copy it from the Claude Console).';
13
+ if (ANTHROPIC_KEY_PATTERN.test(key))
14
+ return null;
15
+ return 'That does not look like an API key: paste the whole key (letters, digits, - and _, no spaces).';
15
16
  }
@@ -8,9 +8,9 @@ using System.Runtime.InteropServices;
8
8
  [assembly: AssemblyCompany("windows-development-sandbox (open source)")]
9
9
  [assembly: AssemblyProduct("Windows Development Sandbox")]
10
10
  [assembly: AssemblyCopyright("MIT License, windows-development-sandbox contributors")]
11
- [assembly: AssemblyVersion("1.23.0.0")]
12
- [assembly: AssemblyFileVersion("1.23.0.0")]
13
- [assembly: AssemblyInformationalVersion("1.23.0")]
11
+ [assembly: AssemblyVersion("1.23.2.0")]
12
+ [assembly: AssemblyFileVersion("1.23.2.0")]
13
+ [assembly: AssemblyInformationalVersion("1.23.2")]
14
14
  [assembly: ComVisible(false)]
15
15
  // computecore.dll and computestorage.dll are not KnownDLLs: load them from System32 only, never from the exe's folder.
16
16
  [assembly: DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
@@ -8,7 +8,7 @@ using System.Runtime.InteropServices;
8
8
  [assembly: AssemblyCompany("windows-development-sandbox (open source)")]
9
9
  [assembly: AssemblyProduct("Windows Development Sandbox")]
10
10
  [assembly: AssemblyCopyright("MIT License, windows-development-sandbox contributors")]
11
- [assembly: AssemblyVersion("1.23.0.0")]
12
- [assembly: AssemblyFileVersion("1.23.0.0")]
13
- [assembly: AssemblyInformationalVersion("1.23.0")]
11
+ [assembly: AssemblyVersion("1.23.2.0")]
12
+ [assembly: AssemblyFileVersion("1.23.2.0")]
13
+ [assembly: AssemblyInformationalVersion("1.23.2")]
14
14
  [assembly: ComVisible(false)]
@@ -9,7 +9,7 @@ using System.Runtime.InteropServices;
9
9
  [assembly: AssemblyCompany("windows-development-sandbox (open source)")]
10
10
  [assembly: AssemblyProduct("Windows Development Sandbox")]
11
11
  [assembly: AssemblyCopyright("MIT License, windows-development-sandbox contributors")]
12
- [assembly: AssemblyVersion("1.23.0.0")]
13
- [assembly: AssemblyFileVersion("1.23.0.0")]
14
- [assembly: AssemblyInformationalVersion("1.23.0")]
12
+ [assembly: AssemblyVersion("1.23.2.0")]
13
+ [assembly: AssemblyFileVersion("1.23.2.0")]
14
+ [assembly: AssemblyInformationalVersion("1.23.2")]
15
15
  [assembly: ComVisible(false)]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "windows-development-sandbox",
3
- "version": "1.23.0",
3
+ "version": "1.23.2",
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",