windows-development-sandbox 1.13.0 → 1.13.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.
Files changed (50) hide show
  1. package/dist/app/features/accounts/accounts.def.d.ts +1 -0
  2. package/dist/app/features/accounts/accounts.def.js +12 -3
  3. package/dist/app/features/accounts/accounts.run.d.ts +1 -0
  4. package/dist/app/features/accounts/accounts.run.js +20 -11
  5. package/dist/app/features/defs.d.ts +1 -0
  6. package/dist/app/features/settings/settings-file.d.ts +7 -0
  7. package/dist/app/features/settings/settings-file.js +19 -2
  8. package/dist/app/features/settings/settings-rows.js +9 -1
  9. package/dist/bin/agent-sandbox.js +7 -1
  10. package/dist/bin/chunk-IL7BXJF2.js +7 -0
  11. package/dist/bin/chunk-K4SU3MHJ.js +10432 -0
  12. package/dist/bin/chunk-VENWSGX2.js +78437 -0
  13. package/dist/bin/claude-host.js +10 -4
  14. package/dist/bin/claude-sbx.js +8 -2
  15. package/dist/bin/codex-sbx.js +8 -2
  16. package/dist/bin/gemini-sbx.js +8 -2
  17. package/dist/bin/sandbox.js +7 -2
  18. package/dist/bin/sbx-hide.js +8 -2
  19. package/dist/bin/sbx-show.js +8 -2
  20. package/dist/cli/commands/launch/prepare.js +24 -7
  21. package/dist/cli/commands/launch/running.js +4 -0
  22. package/dist/cli/commands/storage/offer.js +1 -1
  23. package/dist/cli/menu/live.d.ts +29 -0
  24. package/dist/cli/menu/live.js +92 -21
  25. package/dist/cli/menu/menu.d.ts +2 -1
  26. package/dist/cli/menu/menu.js +16 -2
  27. package/dist/cli/menu/pages/list-page.d.ts +5 -0
  28. package/dist/cli/menu/pages/list-page.js +19 -0
  29. package/dist/cli/menu/shell.d.ts +2 -0
  30. package/dist/cli/menu/shell.js +1 -1
  31. package/dist/cli/services/accounts-service.d.ts +7 -0
  32. package/dist/cli/services/accounts-service.js +20 -0
  33. package/dist/cli/tui/app.d.ts +4 -0
  34. package/dist/cli/tui/app.js +5 -0
  35. package/dist/cli/tui/terminal.d.ts +6 -0
  36. package/dist/cli/tui/terminal.js +8 -1
  37. package/dist/cli/validate.js +8 -4
  38. package/dist/core/package-info.js +1 -1
  39. package/dist/host/sandbox/platform.d.ts +2 -0
  40. package/dist/host/sandbox/platform.js +19 -4
  41. package/dist/host/storage/contained/state.d.ts +3 -2
  42. package/dist/host/storage/contained/state.js +5 -2
  43. package/dist/selftest/layout.test.js +10 -1
  44. package/dist/selftest/menu-perf.test.js +198 -12
  45. package/dist/selftest/menu.test.js +4 -0
  46. package/dist/web/index.html +1 -1
  47. package/dist/web/{main-Z2WYAE2Z.js → main-NBQ3LF4E.js} +1 -1
  48. package/native/csharp/HcsHost/AssemblyInfo.cs +3 -3
  49. package/native/csharp/HostTools/AssemblyInfo.cs +3 -3
  50. package/package.json +1 -1
@@ -76,6 +76,7 @@ export declare const useAccount: import("../../kernel/define.js").OperationDef<z
76
76
  export declare const defaultAccount: import("../../kernel/define.js").OperationDef<z.ZodObject<{
77
77
  agent: z.ZodDefault<z.ZodString>;
78
78
  name: z.ZodOptional<z.ZodString>;
79
+ noRestart: z.ZodDefault<z.ZodBoolean>;
79
80
  }, z.core.$strip>, z.ZodObject<{
80
81
  message: z.ZodString;
81
82
  }, z.core.$strip>, "accounts.default">;
@@ -103,11 +103,20 @@ export const useAccount = defineOperation({
103
103
  export const defaultAccount = defineOperation({
104
104
  id: 'accounts.default',
105
105
  title: 'Make default',
106
- summary: 'the login new launches start with',
107
- input: z.object({ agent: AgentSchema, name: NameSchema }),
106
+ summary: 'the login every launch starts with; the sandbox switches to it now too',
107
+ input: z.object({
108
+ agent: AgentSchema,
109
+ name: NameSchema,
110
+ noRestart: z.boolean().default(false).describe('(default) do not restart running sessions'),
111
+ }),
108
112
  output: MessageSchema,
109
113
  text: (o) => o.message,
110
- cli: { name: 'account', action: 'default', positional: ['name'], flags: { agent: { flag: '--agent' } } },
114
+ cli: {
115
+ name: 'account',
116
+ action: 'default',
117
+ positional: ['name'],
118
+ flags: { agent: { flag: '--agent' }, noRestart: { flag: '--no-restart' } },
119
+ },
111
120
  });
112
121
  export const renameAccount = defineOperation({
113
122
  id: 'accounts.rename',
@@ -33,6 +33,7 @@ export declare const useAccountRun: import("../../kernel/define.js").Implementat
33
33
  export declare const defaultAccountRun: import("../../kernel/define.js").Implementation<import("../../kernel/define.js").OperationDef<import("zod").ZodObject<{
34
34
  agent: import("zod").ZodDefault<import("zod").ZodString>;
35
35
  name: import("zod").ZodOptional<import("zod").ZodString>;
36
+ noRestart: import("zod").ZodDefault<import("zod").ZodBoolean>;
36
37
  }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
37
38
  message: import("zod").ZodString;
38
39
  }, import("zod/v4/core").$strip>, "accounts.default">, import("../../../cli/commands/context.js").Context>;
@@ -71,32 +71,41 @@ export const saveAccountRun = implement(saveAccount, async (ctx, input, io) => {
71
71
  const saved = service.save(name, input.fromHost, input.agent);
72
72
  return { name: saved.name, message: 'Saved account ' + label(saved) + '.' };
73
73
  });
74
- export const useAccountRun = implement(useAccount, async (ctx, input, io) => {
75
- const service = new AccountsService(ctx);
76
- const name = await accountName(io, service, 'use', input.agent, input.name);
77
- // The switch is done before the question: a "no" to the restart keeps the new login and only skips the restart.
78
- const used = service.activate(name, input.agent);
74
+ /**
75
+ * Makes the sandbox use a saved login, then offers to restart the agent's running sessions. The switch is done before
76
+ * the question: a "no" keeps the new login and only skips the restart.
77
+ */
78
+ async function switchTo(io, service, name, agent, noRestart) {
79
+ const used = service.activate(name, agent);
79
80
  const lines = ['Sandbox now uses ' + label(used) + '.'];
80
81
  if (used.note)
81
82
  lines.push(safeText(used.note));
82
- if (service.hasRunningSessions(input.agent) && !input.noRestart) {
83
+ if (service.hasRunningSessions(agent) && !noRestart) {
83
84
  const restart = await io.confirm({
84
- title: 'Restart the running ' + input.agent + ' sessions?',
85
+ title: 'Restart the running ' + agent + ' sessions?',
85
86
  lines: ['They restart and continue their conversation where the agent can, now under the new login.'],
86
87
  yes: 'Restart',
87
88
  implied: true,
88
89
  });
89
90
  if (restart)
90
- lines.push(safeText(await service.restart(input.agent)) +
91
- ' with --continue; the conversation carries on under the new account.');
91
+ lines.push(safeText(await service.restart(agent)) + ' with --continue; the conversation carries on under the new account.');
92
92
  }
93
- return { lines };
93
+ return lines;
94
+ }
95
+ export const useAccountRun = implement(useAccount, async (ctx, input, io) => {
96
+ const service = new AccountsService(ctx);
97
+ const name = await accountName(io, service, 'use', input.agent, input.name);
98
+ return { lines: await switchTo(io, service, name, input.agent, input.noRestart) };
94
99
  });
95
100
  export const defaultAccountRun = implement(defaultAccount, async (ctx, input, io) => {
96
101
  const service = new AccountsService(ctx);
97
102
  const name = await accountName(io, service, 'default', input.agent, input.name);
98
103
  service.setDefault(name, input.agent);
99
- return { message: 'Default account: ' + name };
104
+ const lines = ['Default account: ' + name];
105
+ // The sandbox follows the new default at once (not only from the next launch).
106
+ if (service.activeName(input.agent) !== name)
107
+ lines.push(...(await switchTo(io, service, name, input.agent, input.noRestart)));
108
+ return { message: lines.join('\n') };
100
109
  });
101
110
  export const renameAccountRun = implement(renameAccount, async (ctx, input, io) => {
102
111
  const service = new AccountsService(ctx);
@@ -111,6 +111,7 @@ export declare const OPERATIONS: readonly [OperationDef<import("zod").ZodObject<
111
111
  }, import("zod/v4/core").$strip>, "accounts.use">, OperationDef<import("zod").ZodObject<{
112
112
  agent: import("zod").ZodDefault<import("zod").ZodString>;
113
113
  name: import("zod").ZodOptional<import("zod").ZodString>;
114
+ noRestart: import("zod").ZodDefault<import("zod").ZodBoolean>;
114
115
  }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
115
116
  message: import("zod").ZodString;
116
117
  }, import("zod/v4/core").$strip>, "accounts.default">, OperationDef<import("zod").ZodObject<{
@@ -22,6 +22,8 @@ export declare class ConfigFile {
22
22
  readonly target: SettingsTarget;
23
23
  readonly file: string;
24
24
  readonly schema: SchemaNode;
25
+ /** The file as read in this synchronous run (see read). */
26
+ private snapshot;
25
27
  constructor(target: SettingsTarget, file: string);
26
28
  static user(configPath: string | null): ConfigFile;
27
29
  static project(dir: string): ConfigFile;
@@ -30,6 +32,11 @@ export declare class ConfigFile {
30
32
  text(): string;
31
33
  /** The value written in this file (undefined = not set here). */
32
34
  valueInFile(key: string[]): unknown;
35
+ /**
36
+ * The file's text and what it parses to, read once per synchronous run: the settings list asks for every setting's
37
+ * value (hundreds of reads), and the next run (after a key, a save or a change outside) reads the file again.
38
+ */
39
+ private read;
33
40
  /** Your own settings with the built-in defaults filled in (what a sandbox uses without a project file). */
34
41
  userConfig(): Config;
35
42
  /** What is in effect: for your file the merged config, for a project file only what the file sets. */
@@ -34,6 +34,8 @@ export class ConfigFile {
34
34
  target;
35
35
  file;
36
36
  schema;
37
+ /** The file as read in this synchronous run (see read). */
38
+ snapshot;
37
39
  constructor(target, file) {
38
40
  this.target = target;
39
41
  this.file = file;
@@ -52,11 +54,25 @@ export class ConfigFile {
52
54
  return fs.existsSync(this.file);
53
55
  }
54
56
  text() {
55
- return this.exists ? fs.readFileSync(this.file, 'utf8') : '';
57
+ return this.read().text;
56
58
  }
57
59
  /** The value written in this file (undefined = not set here). */
58
60
  valueInFile(key) {
59
- return fileValue(this.text(), key);
61
+ const value = _.get(this.read().parsed, key);
62
+ // A copy: the parsed file is shared by every read in this run.
63
+ return value !== null && typeof value === 'object' ? structuredClone(value) : value;
64
+ }
65
+ /**
66
+ * The file's text and what it parses to, read once per synchronous run: the settings list asks for every setting's
67
+ * value (hundreds of reads), and the next run (after a key, a save or a change outside) reads the file again.
68
+ */
69
+ read() {
70
+ if (!this.snapshot) {
71
+ const text = this.exists ? fs.readFileSync(this.file, 'utf8') : '';
72
+ this.snapshot = { text, parsed: parse(text) ?? {} };
73
+ queueMicrotask(() => (this.snapshot = undefined));
74
+ }
75
+ return this.snapshot;
60
76
  }
61
77
  /** Your own settings with the built-in defaults filled in (what a sandbox uses without a project file). */
62
78
  userConfig() {
@@ -100,6 +116,7 @@ export class ConfigFile {
100
116
  return 'unchanged';
101
117
  fs.mkdirSync(path.dirname(this.file), { recursive: true });
102
118
  fs.writeFileSync(this.file, text, 'utf8');
119
+ this.snapshot = undefined;
103
120
  return 'saved';
104
121
  }
105
122
  }
@@ -46,9 +46,17 @@ export function masked(key, value) {
46
46
  return undefined;
47
47
  return _.get(redactSecrets(_.set({}, key, structuredClone(value))), key);
48
48
  }
49
+ /** The keys a project file's schema can set, worked out once per schema (a list asks for it on every row). */
50
+ const projectKeysOf = new WeakMap();
49
51
  /** The keys a project file can set. */
50
52
  function projectKeys(files) {
51
- return new Set(files.project.schema.leaves().map((l) => l.key.join('.')));
53
+ const schema = files.project.schema;
54
+ let keys = projectKeysOf.get(schema);
55
+ if (!keys) {
56
+ keys = new Set(schema.leaves().map((l) => l.key.join('.')));
57
+ projectKeysOf.set(schema, keys);
58
+ }
59
+ return keys;
52
60
  }
53
61
  /** One setting's row in a scope (`config` and `inProject` can be passed when making many rows). */
54
62
  export function settingRow(s, files, scope, source = SAVED, config = files.user.userConfig(), inProject = projectKeys(files)) {
@@ -1,3 +1,9 @@
1
1
  #!/usr/bin/env node
2
- import { run } from '../cli/index.js';
2
+ import { createRequire as __createRequire } from 'node:module'; const require = __createRequire(import.meta.url);
3
+ import {
4
+ run
5
+ } from "./chunk-K4SU3MHJ.js";
6
+ import "./chunk-VENWSGX2.js";
7
+
8
+ // src/bin/agent-sandbox.ts
3
9
  run(process.argv.slice(2));
@@ -0,0 +1,7 @@
1
+ import { createRequire as __createRequire } from 'node:module'; const require = __createRequire(import.meta.url);
2
+ import {
3
+ attach
4
+ } from "./chunk-VENWSGX2.js";
5
+ export {
6
+ attach
7
+ };