windows-development-sandbox 1.18.4 → 1.20.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 (181) hide show
  1. package/README.md +1 -1
  2. package/config.example.json +9 -0
  3. package/dist/app/features/accounts/accounts.def.d.ts +4 -0
  4. package/dist/app/features/accounts/accounts.run.d.ts +1 -0
  5. package/dist/app/features/accounts/services.def.d.ts +3 -0
  6. package/dist/app/features/accounts/services.def.js +4 -2
  7. package/dist/app/features/accounts/services.run.d.ts +1 -0
  8. package/dist/app/features/accounts/services.run.js +3 -1
  9. package/dist/app/features/agent-commands/agent-commands.def.d.ts +37 -0
  10. package/dist/app/features/agent-commands/agent-commands.def.js +91 -0
  11. package/dist/app/features/agent-commands/agent-commands.run.d.ts +28 -0
  12. package/dist/app/features/agent-commands/agent-commands.run.js +35 -0
  13. package/dist/app/features/agent-commands/index.d.ts +2 -0
  14. package/dist/app/features/agent-commands/index.js +3 -0
  15. package/dist/app/features/agents/agents.def.d.ts +14 -1
  16. package/dist/app/features/agents/agents.def.js +61 -6
  17. package/dist/app/features/agents/agents.run.d.ts +1 -0
  18. package/dist/app/features/agents/agents.run.js +8 -1
  19. package/dist/app/features/agents/claude-env.def.d.ts +36 -0
  20. package/dist/app/features/agents/claude-env.def.js +305 -0
  21. package/dist/app/features/agents/env.def.d.ts +163 -0
  22. package/dist/app/features/agents/env.def.js +184 -0
  23. package/dist/app/features/agents/env.run.d.ts +43 -0
  24. package/dist/app/features/agents/env.run.js +86 -0
  25. package/dist/app/features/agents/index.d.ts +2 -0
  26. package/dist/app/features/agents/index.js +2 -0
  27. package/dist/app/features/defs.d.ts +132 -1
  28. package/dist/app/features/defs.js +9 -0
  29. package/dist/app/features/settings/categories.def.js +5 -2
  30. package/dist/app/features/settings/settings-rows.js +5 -1
  31. package/dist/app/features/settings/settings.run.d.ts +8 -0
  32. package/dist/app/features/settings/settings.run.js +9 -0
  33. package/dist/app/features/updates/updates.run.js +12 -2
  34. package/dist/app/features/vpn/vpn.def.d.ts +33 -0
  35. package/dist/app/features/vpn/vpn.def.js +30 -6
  36. package/dist/app/features/vpn/vpn.run.d.ts +11 -0
  37. package/dist/app/features/vpn/vpn.run.js +4 -1
  38. package/dist/app/kernel/rpc.d.ts +1 -1
  39. package/dist/app/registry.js +7 -1
  40. package/dist/bin/agent-sandbox.js +2 -2
  41. package/dist/bin/{chunk-MY7NLQQY.js → chunk-2IMT7ZCT.js} +1 -1
  42. package/dist/bin/{chunk-N4GXYTLV.js → chunk-DK4NTBUF.js} +69 -26
  43. package/dist/bin/{chunk-FRPLQLSY.js → chunk-Z2P5OGKL.js} +4323 -3463
  44. package/dist/bin/claude-host.js +2 -2
  45. package/dist/bin/claude-sbx.js +2 -2
  46. package/dist/bin/codex-sbx.js +2 -2
  47. package/dist/bin/gemini-sbx.js +2 -2
  48. package/dist/bin/sandbox.js +2 -2
  49. package/dist/bin/sbx-hide.js +2 -2
  50. package/dist/bin/sbx-show.js +2 -2
  51. package/dist/cli/commands/agent-commands.d.ts +0 -1
  52. package/dist/cli/commands/agent-commands.js +2 -32
  53. package/dist/cli/commands/index.d.ts +1 -1
  54. package/dist/cli/commands/index.js +1 -1
  55. package/dist/cli/commands/launch/launch.js +2 -2
  56. package/dist/cli/commands/registry.js +3 -2
  57. package/dist/cli/manifest.d.ts +1 -1
  58. package/dist/cli/manifest.js +1 -1
  59. package/dist/cli/menu/menu.d.ts +1 -1
  60. package/dist/cli/menu/menu.js +3 -3
  61. package/dist/cli/menu/pages/agents-page.d.ts +7 -2
  62. package/dist/cli/menu/pages/agents-page.js +67 -11
  63. package/dist/cli/menu/pages/maintenance-page.js +1 -2
  64. package/dist/cli/menu/pages/settings-page.js +1 -0
  65. package/dist/cli/menu/views.js +2 -1
  66. package/dist/cli/services/agent-commands-service.d.ts +2 -0
  67. package/dist/cli/services/agent-commands-service.js +13 -7
  68. package/dist/cli/services/vpn-service.d.ts +5 -1
  69. package/dist/cli/services/vpn-service.js +6 -1
  70. package/dist/cli/tui/dialogs/text-screen.js +2 -1
  71. package/dist/cli/tui/terminal.js +3 -1
  72. package/dist/core/config/defaults.js +9 -0
  73. package/dist/core/detect/toolchains.js +9 -0
  74. package/dist/core/disk.d.ts +1 -5
  75. package/dist/core/disk.js +1 -16
  76. package/dist/core/schema/codex.d.ts +29 -0
  77. package/dist/core/schema/codex.js +24 -0
  78. package/dist/core/schema/config.d.ts +46 -14
  79. package/dist/core/schema/config.js +2 -0
  80. package/dist/core/schema/index.d.ts +1 -0
  81. package/dist/core/schema/index.js +1 -0
  82. package/dist/core/schema/toolchains.d.ts +4 -0
  83. package/dist/core/schema/toolchains.js +3 -0
  84. package/dist/core/types.d.ts +2 -0
  85. package/dist/guest/accounts/apply.d.ts +6 -6
  86. package/dist/guest/agents/agent-files.d.ts +26 -6
  87. package/dist/guest/agents/agent-files.js +84 -14
  88. package/dist/guest/agents/local-state.d.ts +5 -2
  89. package/dist/guest/agents/local-state.js +24 -10
  90. package/dist/guest/boot/boot.js +10 -5
  91. package/dist/guest/daemon/sessions.js +2 -1
  92. package/dist/guest/toolchains/installers.d.ts +6 -10
  93. package/dist/guest/toolchains/installers.js +4 -12
  94. package/dist/guest/toolchains/native/autosdk.d.ts +3 -0
  95. package/dist/guest/toolchains/native/autosdk.js +50 -0
  96. package/dist/guest/toolchains/native/unreal.js +3 -0
  97. package/dist/guest/toolchains/native/vcruntime.d.ts +0 -3
  98. package/dist/guest/toolchains/native/vcruntime.js +2 -5
  99. package/dist/guest/toolchains/native/visual-studio.d.ts +2 -2
  100. package/dist/guest/toolchains/native/visual-studio.js +100 -16
  101. package/dist/guest/toolchains/native/vs-request.d.ts +21 -0
  102. package/dist/guest/toolchains/native/vs-request.js +60 -1
  103. package/dist/guest/toolchains/not-yet.d.ts +1 -1
  104. package/dist/guest/toolchains/not-yet.js +3 -3
  105. package/dist/guest/toolchains/persisted.js +2 -7
  106. package/dist/guest/toolchains/plan.js +9 -4
  107. package/dist/guest/toolchains/signature.d.ts +5 -0
  108. package/dist/guest/toolchains/signature.js +22 -0
  109. package/dist/guest/vpn/tunnel.d.ts +3 -0
  110. package/dist/guest/vpn/tunnel.js +10 -12
  111. package/dist/guest/vpn/vpn.js +6 -1
  112. package/dist/host/accounts/leases.d.ts +3 -3
  113. package/dist/host/accounts/source.js +1 -1
  114. package/dist/host/agent-commands/commands.js +1 -1
  115. package/dist/host/agent-commands/forwarders.d.ts +14 -2
  116. package/dist/host/agent-commands/forwarders.js +31 -13
  117. package/dist/host/agent-commands/reconcile.d.ts +2 -1
  118. package/dist/host/agent-commands/reconcile.js +7 -8
  119. package/dist/host/agent-commands/user-path.d.ts +5 -0
  120. package/dist/host/agent-commands/user-path.js +13 -0
  121. package/dist/host/launch/session-file.js +1 -0
  122. package/dist/host/profile/accounts.js +2 -4
  123. package/dist/host/profile/claude-login.d.ts +3 -2
  124. package/dist/host/profile/claude-login.js +3 -13
  125. package/dist/host/vpn/index.d.ts +2 -1
  126. package/dist/host/vpn/index.js +2 -1
  127. package/dist/host/vpn/last.d.ts +28 -0
  128. package/dist/host/vpn/last.js +43 -0
  129. package/dist/host/vpn/login.d.ts +3 -1
  130. package/dist/host/vpn/login.js +17 -3
  131. package/dist/runtime/agent.js +28 -0
  132. package/dist/runtime/daemon.js +1117 -912
  133. package/dist/runtime/db.js +30 -0
  134. package/dist/runtime/main.js +1308 -1036
  135. package/dist/runtime/netproxy.js +22 -0
  136. package/dist/runtime/tool.js +238 -208
  137. package/dist/runtime/view.js +22 -0
  138. package/dist/selftest/agent-commands.test.js +45 -7
  139. package/dist/selftest/agent-paths.test.js +1 -12
  140. package/dist/selftest/agent-settings.test.d.ts +2 -0
  141. package/dist/selftest/agent-settings.test.js +94 -0
  142. package/dist/selftest/app.test.js +2 -1
  143. package/dist/selftest/cli.test.js +4 -0
  144. package/dist/selftest/index.js +2 -0
  145. package/dist/selftest/menu.test.js +5 -3
  146. package/dist/selftest/pc-installs.test.js +5 -0
  147. package/dist/selftest/persisted-installs.test.js +69 -0
  148. package/dist/selftest/service-accounts.test.js +1 -1
  149. package/dist/selftest/support/engine-golden.js +1 -1
  150. package/dist/selftest/support/fixtures.d.ts +9 -0
  151. package/dist/selftest/vpn.test.js +51 -3
  152. package/dist/shared/accounts/anthropic.d.ts +5 -0
  153. package/dist/shared/accounts/anthropic.js +15 -0
  154. package/dist/shared/accounts/index.d.ts +1 -0
  155. package/dist/shared/accounts/index.js +1 -0
  156. package/dist/shared/channel/schema.d.ts +19 -0
  157. package/dist/shared/channel/schema.js +2 -0
  158. package/dist/shared/io/disk.d.ts +9 -0
  159. package/dist/shared/io/disk.js +19 -0
  160. package/dist/shared/io/index.d.ts +1 -0
  161. package/dist/shared/io/index.js +1 -0
  162. package/dist/shared/readiness.d.ts +9 -0
  163. package/dist/shared/readiness.js +11 -0
  164. package/dist/shared/signer.d.ts +24 -0
  165. package/dist/shared/signer.js +15 -0
  166. package/dist/shared/vpn/failure.d.ts +10 -0
  167. package/dist/shared/vpn/failure.js +28 -0
  168. package/dist/sync/watcher.js +2 -0
  169. package/dist/web/index.html +1 -1
  170. package/dist/web/{main-GVZWWP4I.js → main-OUUQYNK4.js} +75 -74
  171. package/native/csharp/HcsHost/AssemblyInfo.cs +3 -3
  172. package/native/csharp/HostTools/AssemblyInfo.cs +3 -3
  173. package/native/csharp/HostTools/Program.cs +14 -1
  174. package/native/csharp/HostTools/UserPath.cs +17 -0
  175. package/native/csharp/StorageHelper/AssemblyInfo.cs +3 -3
  176. package/native/scripts/edit-user-path.ps1 +6 -2
  177. package/package.json +1 -1
  178. package/sandbox/scripts/get-signature.ps1 +13 -0
  179. package/schemas/config.schema.json +64 -0
  180. package/schemas/sandbox-config.schema.json +8 -0
  181. package/sandbox/scripts/get-signer.ps1 +0 -8
@@ -0,0 +1,43 @@
1
+ export declare const agentEnvRun: import("../../kernel/define.js").Implementation<import("../../kernel/define.js").QueryDef<import("zod").ZodObject<{
2
+ agent: import("zod").ZodDefault<import("zod").ZodString>;
3
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
4
+ agent: import("zod").ZodString;
5
+ rows: import("zod").ZodArray<import("zod").ZodObject<{
6
+ name: import("zod").ZodString;
7
+ group: import("zod").ZodEnum<{
8
+ Subagents: "Subagents";
9
+ Models: "Models";
10
+ Limits: "Limits";
11
+ Behaviour: "Behaviour";
12
+ Privacy: "Privacy";
13
+ Network: "Network";
14
+ Providers: "Providers";
15
+ }>;
16
+ label: import("zod").ZodString;
17
+ kind: import("zod").ZodEnum<{
18
+ number: "number";
19
+ enum: "enum";
20
+ flag: "flag";
21
+ text: "text";
22
+ }>;
23
+ description: import("zod").ZodString;
24
+ choices: import("zod").ZodOptional<import("zod").ZodArray<import("zod").ZodString>>;
25
+ range: import("zod").ZodOptional<import("zod").ZodString>;
26
+ secret: import("zod").ZodBoolean;
27
+ defaultText: import("zod").ZodOptional<import("zod").ZodString>;
28
+ value: import("zod").ZodNullable<import("zod").ZodString>;
29
+ set: import("zod").ZodBoolean;
30
+ fromSandbox: import("zod").ZodBoolean;
31
+ }, import("zod/v4/core").$strip>>;
32
+ custom: import("zod").ZodArray<import("zod").ZodObject<{
33
+ name: import("zod").ZodString;
34
+ fromSandbox: import("zod").ZodBoolean;
35
+ }, import("zod/v4/core").$strip>>;
36
+ }, import("zod/v4/core").$strip>, "agents.env">, import("../../../cli/commands/context.js").Context>;
37
+ export declare const agentsEnvSetRun: import("../../kernel/define.js").Implementation<import("../../kernel/define.js").OperationDef<import("zod").ZodObject<{
38
+ agent: import("zod").ZodString;
39
+ name: import("zod").ZodString;
40
+ value: import("zod").ZodDefault<import("zod").ZodNullable<import("zod").ZodString>>;
41
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
42
+ message: import("zod").ZodString;
43
+ }, import("zod/v4/core").$strip>, "agents.env.set">, import("../../../cli/commands/context.js").Context>;
@@ -0,0 +1,86 @@
1
+ // The work of the agent environment editor: reads an agent's variables from your settings (secrets never leave this
2
+ // file), and sets or removes one through the same config file the settings use. Talks only through io.
3
+ import _ from 'lodash';
4
+ import { DEFAULTS } from '../../../core/config/index.js';
5
+ import { fail } from '../../../core/util/index.js';
6
+ import { CLAUDE_ENV, envSpec, envValue } from './claude-env.def.js';
7
+ import { anthropicKeyProblem } from '../../../shared/accounts/index.js';
8
+ import { implement } from '../../context.js';
9
+ import { ConfigFile } from '../settings/settings-file.js';
10
+ import { agentEnv, agentsEnvSet } from './env.def.js';
11
+ /** The variables written in your own settings file for an agent (a value that is not text is ignored). */
12
+ function ownVariables(file, agent) {
13
+ const raw = file.valueInFile(['harnesses', agent, 'environment']);
14
+ if (!_.isPlainObject(raw))
15
+ return {};
16
+ return Object.fromEntries(Object.entries(raw).filter(([, v]) => typeof v === 'string'));
17
+ }
18
+ function rangeText(spec) {
19
+ if (spec.kind !== 'number')
20
+ return undefined;
21
+ const min = spec.min ?? 0;
22
+ return 'A whole number from ' + min + (spec.max !== undefined ? ' to ' + spec.max : ' up') + '.';
23
+ }
24
+ /** The agent must be one of your settings' agents. */
25
+ function knownAgent(file, agent) {
26
+ if (!(agent in file.userConfig().harnesses))
27
+ fail('There is no agent called "' + agent + '".');
28
+ }
29
+ export const agentEnvRun = implement(agentEnv, (ctx, input) => {
30
+ const file = ConfigFile.user(ctx.loaded.configPath);
31
+ knownAgent(file, input.agent);
32
+ const mine = ownVariables(file, input.agent);
33
+ const base = DEFAULTS.harnesses[input.agent]?.environment ?? {};
34
+ const names = new Set([...Object.keys(base), ...Object.keys(mine)]);
35
+ const catalogue = input.agent === 'claude' ? CLAUDE_ENV : [];
36
+ const rows = catalogue.map((spec) => {
37
+ const value = mine[spec.name] ?? base[spec.name];
38
+ return {
39
+ name: spec.name,
40
+ group: spec.group,
41
+ label: spec.label,
42
+ kind: spec.kind,
43
+ description: spec.description,
44
+ ...(spec.choices ? { choices: [...spec.choices] } : {}),
45
+ ...(rangeText(spec) ? { range: rangeText(spec) } : {}),
46
+ secret: spec.secret === true,
47
+ ...(spec.defaultText ? { defaultText: spec.defaultText } : {}),
48
+ // A secret's value stays here.
49
+ value: value === undefined || spec.secret ? null : value,
50
+ set: value !== undefined,
51
+ fromSandbox: mine[spec.name] === undefined && base[spec.name] !== undefined,
52
+ };
53
+ });
54
+ const known = new Set(catalogue.map((s) => s.name));
55
+ const custom = [...names]
56
+ .filter((n) => !known.has(n))
57
+ .sort()
58
+ .map((name) => ({ name, fromSandbox: mine[name] === undefined }));
59
+ return { agent: input.agent, rows, custom };
60
+ });
61
+ export const agentsEnvSetRun = implement(agentsEnvSet, (ctx, input) => {
62
+ const file = ConfigFile.user(ctx.loaded.configPath);
63
+ knownAgent(file, input.agent);
64
+ const spec = input.agent === 'claude' ? envSpec(input.name) : undefined;
65
+ const shownName = spec?.label ?? input.name;
66
+ const checked = envValue(spec, input.value, anthropicKeyProblem);
67
+ if ('problem' in checked)
68
+ fail(shownName + ': ' + checked.problem);
69
+ const mine = ownVariables(file, input.agent);
70
+ if (checked.save === null && mine[input.name] === undefined) {
71
+ const sandbox = DEFAULTS.harnesses[input.agent]?.environment?.[input.name] !== undefined;
72
+ return {
73
+ message: sandbox
74
+ ? shownName + ' is set by the sandbox; give it another value to change it.'
75
+ : shownName + ' was not set.',
76
+ };
77
+ }
78
+ const result = file.set(['harnesses', input.agent, 'environment', input.name], checked.save ?? undefined);
79
+ if (typeof result === 'object')
80
+ fail('It could not be saved: ' + result.problems.join('; '));
81
+ if (checked.save === null)
82
+ return { message: shownName + ' is removed.' };
83
+ // Only the value of a plain catalogue entry is said back: everything else may hold a login.
84
+ const said = spec && !spec.secret ? (spec.kind === 'flag' ? 'on' : checked.save) : 'saved';
85
+ return { message: shownName + (said === 'saved' ? ' is saved.' : ' is ' + said + '.') };
86
+ });
@@ -1,3 +1,5 @@
1
1
  export * from './agents.def.js';
2
2
  export * from './agents.run.js';
3
+ export * from './env.def.js';
4
+ export * from './env.run.js';
3
5
  export * from './agent-entry.js';
@@ -1,4 +1,6 @@
1
1
  // The agents feature: the list, starting an agent in a project of the running sandbox, and the agents in your settings.
2
2
  export * from './agents.def.js';
3
3
  export * from './agents.run.js';
4
+ export * from './env.def.js';
5
+ export * from './env.run.js';
4
6
  export * from './agent-entry.js';
@@ -76,6 +76,12 @@ export declare const OPERATIONS: readonly [OperationDef<import("zod").ZodObject<
76
76
  }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
77
77
  message: import("zod").ZodString;
78
78
  }, import("zod/v4/core").$strip>, "agents.remove">, OperationDef<import("zod").ZodObject<{
79
+ agent: import("zod").ZodString;
80
+ name: import("zod").ZodString;
81
+ value: import("zod").ZodDefault<import("zod").ZodNullable<import("zod").ZodString>>;
82
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
83
+ message: import("zod").ZodString;
84
+ }, import("zod/v4/core").$strip>, "agents.env.set">, OperationDef<import("zod").ZodObject<{
79
85
  scope: import("zod").ZodDefault<import("zod").ZodEnum<{
80
86
  project: "project";
81
87
  user: "user";
@@ -285,6 +291,14 @@ export declare const OPERATIONS: readonly [OperationDef<import("zod").ZodObject<
285
291
  deleted: import("zod").ZodBoolean;
286
292
  message: import("zod").ZodString;
287
293
  }, import("zod/v4/core").$strip>, "vpn.logout">, OperationDef<import("zod").ZodObject<{}, import("zod/v4/core").$strict>, import("zod").ZodObject<{
294
+ on: import("zod").ZodBoolean;
295
+ commands: import("zod").ZodArray<import("zod").ZodString>;
296
+ message: import("zod").ZodString;
297
+ }, import("zod/v4/core").$strip>, "agentCommands.on">, OperationDef<import("zod").ZodObject<{}, import("zod/v4/core").$strict>, import("zod").ZodObject<{
298
+ on: import("zod").ZodBoolean;
299
+ commands: import("zod").ZodArray<import("zod").ZodString>;
300
+ message: import("zod").ZodString;
301
+ }, import("zod/v4/core").$strip>, "agentCommands.off">, OperationDef<import("zod").ZodObject<{}, import("zod/v4/core").$strict>, import("zod").ZodObject<{
288
302
  message: import("zod").ZodString;
289
303
  }, import("zod/v4/core").$strip>, "github.login">, OperationDef<import("zod").ZodObject<{}, import("zod/v4/core").$strict>, import("zod").ZodObject<{
290
304
  deleted: import("zod").ZodBoolean;
@@ -438,7 +452,43 @@ export declare const QUERIES: readonly [QueryDef<import("zod").ZodObject<{}, imp
438
452
  isDefault: import("zod").ZodBoolean;
439
453
  removable: import("zod").ZodBoolean;
440
454
  }, import("zod/v4/core").$strip>>;
455
+ subagents: import("zod").ZodOptional<import("zod").ZodNullable<import("zod").ZodNumber>>;
441
456
  }, import("zod/v4/core").$strip>, "agents.list">, QueryDef<import("zod").ZodObject<{
457
+ agent: import("zod").ZodDefault<import("zod").ZodString>;
458
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
459
+ agent: import("zod").ZodString;
460
+ rows: import("zod").ZodArray<import("zod").ZodObject<{
461
+ name: import("zod").ZodString;
462
+ group: import("zod").ZodEnum<{
463
+ Subagents: "Subagents";
464
+ Models: "Models";
465
+ Limits: "Limits";
466
+ Behaviour: "Behaviour";
467
+ Privacy: "Privacy";
468
+ Network: "Network";
469
+ Providers: "Providers";
470
+ }>;
471
+ label: import("zod").ZodString;
472
+ kind: import("zod").ZodEnum<{
473
+ number: "number";
474
+ enum: "enum";
475
+ flag: "flag";
476
+ text: "text";
477
+ }>;
478
+ description: import("zod").ZodString;
479
+ choices: import("zod").ZodOptional<import("zod").ZodArray<import("zod").ZodString>>;
480
+ range: import("zod").ZodOptional<import("zod").ZodString>;
481
+ secret: import("zod").ZodBoolean;
482
+ defaultText: import("zod").ZodOptional<import("zod").ZodString>;
483
+ value: import("zod").ZodNullable<import("zod").ZodString>;
484
+ set: import("zod").ZodBoolean;
485
+ fromSandbox: import("zod").ZodBoolean;
486
+ }, import("zod/v4/core").$strip>>;
487
+ custom: import("zod").ZodArray<import("zod").ZodObject<{
488
+ name: import("zod").ZodString;
489
+ fromSandbox: import("zod").ZodBoolean;
490
+ }, import("zod/v4/core").$strip>>;
491
+ }, import("zod/v4/core").$strip>, "agents.env">, QueryDef<import("zod").ZodObject<{
442
492
  scope: import("zod").ZodDefault<import("zod").ZodEnum<{
443
493
  project: "project";
444
494
  user: "user";
@@ -536,6 +586,7 @@ export declare const QUERIES: readonly [QueryDef<import("zod").ZodObject<{}, imp
536
586
  canImport: import("zod").ZodBoolean;
537
587
  canLogin: import("zod").ZodBoolean;
538
588
  needsFile: import("zod").ZodBoolean;
589
+ ready: import("zod").ZodBoolean;
539
590
  }, import("zod/v4/core").$strip>>;
540
591
  }, import("zod/v4/core").$strip>, "accounts.list">, QueryDef<import("zod").ZodObject<{
541
592
  scope: import("zod").ZodDefault<import("zod").ZodEnum<{
@@ -941,7 +992,26 @@ export declare const QUERIES: readonly [QueryDef<import("zod").ZodObject<{}, imp
941
992
  }>;
942
993
  text: import("zod").ZodString;
943
994
  }, import("zod/v4/core").$strip>>;
944
- }, import("zod/v4/core").$strip>, "vpn.status">, QueryDef<import("zod").ZodObject<{}, import("zod/v4/core").$strict>, import("zod").ZodObject<{
995
+ lastFailure: import("zod").ZodNullable<import("zod").ZodObject<{
996
+ code: import("zod").ZodEnum<{
997
+ auth: "auth";
998
+ unreachable: "unreachable";
999
+ driver: "driver";
1000
+ timeout: "timeout";
1001
+ other: "other";
1002
+ }>;
1003
+ text: import("zod").ZodString;
1004
+ at: import("zod").ZodString;
1005
+ }, import("zod/v4/core").$strip>>;
1006
+ }, import("zod/v4/core").$strip>, "vpn.status">, QueryDef<import("zod").ZodObject<{}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
1007
+ enabled: import("zod").ZodBoolean;
1008
+ dir: import("zod").ZodString;
1009
+ found: import("zod").ZodArray<import("zod").ZodObject<{
1010
+ command: import("zod").ZodString;
1011
+ harness: import("zod").ZodString;
1012
+ real: import("zod").ZodString;
1013
+ }, import("zod/v4/core").$strip>>;
1014
+ }, import("zod/v4/core").$strip>, "agentCommands.status">, QueryDef<import("zod").ZodObject<{}, import("zod/v4/core").$strict>, import("zod").ZodObject<{
945
1015
  shareToken: import("zod").ZodBoolean;
946
1016
  gitAccess: import("zod").ZodEnum<{
947
1017
  readonly: "readonly";
@@ -979,6 +1049,7 @@ export declare const QUERIES: readonly [QueryDef<import("zod").ZodObject<{}, imp
979
1049
  canImport: import("zod").ZodBoolean;
980
1050
  canLogin: import("zod").ZodBoolean;
981
1051
  needsFile: import("zod").ZodBoolean;
1052
+ ready: import("zod").ZodBoolean;
982
1053
  }, import("zod/v4/core").$strip>>;
983
1054
  }, import("zod/v4/core").$strip>, "accounts.services">, QueryDef<import("zod").ZodObject<{}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
984
1055
  lan: import("zod").ZodObject<{
@@ -1139,8 +1210,55 @@ export declare const VIEWS: readonly [import("../kernel/define.js").ViewDef<{
1139
1210
  isDefault: import("zod").ZodBoolean;
1140
1211
  removable: import("zod").ZodBoolean;
1141
1212
  }, import("zod/v4/core").$strip>>;
1213
+ subagents: import("zod").ZodOptional<import("zod").ZodNullable<import("zod").ZodNumber>>;
1142
1214
  }, import("zod/v4/core").$strip>, "agents.list">;
1215
+ agentCommands: QueryDef<import("zod").ZodObject<{}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
1216
+ enabled: import("zod").ZodBoolean;
1217
+ dir: import("zod").ZodString;
1218
+ found: import("zod").ZodArray<import("zod").ZodObject<{
1219
+ command: import("zod").ZodString;
1220
+ harness: import("zod").ZodString;
1221
+ real: import("zod").ZodString;
1222
+ }, import("zod/v4/core").$strip>>;
1223
+ }, import("zod/v4/core").$strip>, "agentCommands.status">;
1143
1224
  }, Record<string, never>, "agents">, import("../kernel/define.js").ViewDef<{
1225
+ env: QueryDef<import("zod").ZodObject<{
1226
+ agent: import("zod").ZodDefault<import("zod").ZodString>;
1227
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
1228
+ agent: import("zod").ZodString;
1229
+ rows: import("zod").ZodArray<import("zod").ZodObject<{
1230
+ name: import("zod").ZodString;
1231
+ group: import("zod").ZodEnum<{
1232
+ Subagents: "Subagents";
1233
+ Models: "Models";
1234
+ Limits: "Limits";
1235
+ Behaviour: "Behaviour";
1236
+ Privacy: "Privacy";
1237
+ Network: "Network";
1238
+ Providers: "Providers";
1239
+ }>;
1240
+ label: import("zod").ZodString;
1241
+ kind: import("zod").ZodEnum<{
1242
+ number: "number";
1243
+ enum: "enum";
1244
+ flag: "flag";
1245
+ text: "text";
1246
+ }>;
1247
+ description: import("zod").ZodString;
1248
+ choices: import("zod").ZodOptional<import("zod").ZodArray<import("zod").ZodString>>;
1249
+ range: import("zod").ZodOptional<import("zod").ZodString>;
1250
+ secret: import("zod").ZodBoolean;
1251
+ defaultText: import("zod").ZodOptional<import("zod").ZodString>;
1252
+ value: import("zod").ZodNullable<import("zod").ZodString>;
1253
+ set: import("zod").ZodBoolean;
1254
+ fromSandbox: import("zod").ZodBoolean;
1255
+ }, import("zod/v4/core").$strip>>;
1256
+ custom: import("zod").ZodArray<import("zod").ZodObject<{
1257
+ name: import("zod").ZodString;
1258
+ fromSandbox: import("zod").ZodBoolean;
1259
+ }, import("zod/v4/core").$strip>>;
1260
+ }, import("zod/v4/core").$strip>, "agents.env">;
1261
+ }, import("./agents/env.def.js").AgentEnvParams, "agentEnv">, import("../kernel/define.js").ViewDef<{
1144
1262
  settings: QueryDef<import("zod").ZodObject<{
1145
1263
  scope: import("zod").ZodDefault<import("zod").ZodEnum<{
1146
1264
  project: "project";
@@ -1219,6 +1337,7 @@ export declare const VIEWS: readonly [import("../kernel/define.js").ViewDef<{
1219
1337
  canImport: import("zod").ZodBoolean;
1220
1338
  canLogin: import("zod").ZodBoolean;
1221
1339
  needsFile: import("zod").ZodBoolean;
1340
+ ready: import("zod").ZodBoolean;
1222
1341
  }, import("zod/v4/core").$strip>>;
1223
1342
  }, import("zod/v4/core").$strip>, "accounts.list">;
1224
1343
  services: QueryDef<import("zod").ZodObject<{
@@ -1242,6 +1361,7 @@ export declare const VIEWS: readonly [import("../kernel/define.js").ViewDef<{
1242
1361
  canImport: import("zod").ZodBoolean;
1243
1362
  canLogin: import("zod").ZodBoolean;
1244
1363
  needsFile: import("zod").ZodBoolean;
1364
+ ready: import("zod").ZodBoolean;
1245
1365
  }, import("zod/v4/core").$strip>>;
1246
1366
  }, import("zod/v4/core").$strip>, "accounts.services">;
1247
1367
  }, Record<string, never>, "accounts">, import("../kernel/define.js").ViewDef<{
@@ -1649,6 +1769,17 @@ export declare const VIEWS: readonly [import("../kernel/define.js").ViewDef<{
1649
1769
  }>;
1650
1770
  text: import("zod").ZodString;
1651
1771
  }, import("zod/v4/core").$strip>>;
1772
+ lastFailure: import("zod").ZodNullable<import("zod").ZodObject<{
1773
+ code: import("zod").ZodEnum<{
1774
+ auth: "auth";
1775
+ unreachable: "unreachable";
1776
+ driver: "driver";
1777
+ timeout: "timeout";
1778
+ other: "other";
1779
+ }>;
1780
+ text: import("zod").ZodString;
1781
+ at: import("zod").ZodString;
1782
+ }, import("zod/v4/core").$strip>>;
1652
1783
  }, import("zod/v4/core").$strip>, "vpn.status">;
1653
1784
  }, Record<string, never>, "vpn">, import("../kernel/define.js").ViewDef<{
1654
1785
  status: QueryDef<import("zod").ZodObject<{}, import("zod/v4/core").$strict>, import("zod").ZodObject<{
@@ -1,4 +1,5 @@
1
1
  import { addAgent, agentsView, listAgents, makeDefaultAgent, removeAgent, startAgent } from './agents/agents.def.js';
2
+ import { agentEnv, agentEnvView, agentsEnvSet } from './agents/env.def.js';
2
3
  import { accountsView, defaultAccount, listAccounts, removeAccount, renameAccount, saveAccount, useAccount, } from './accounts/accounts.def.js';
3
4
  import { listServices, serviceImport, serviceLogin, serviceLogout } from './accounts/services.def.js';
4
5
  import { appsView, listApps, requestApp, setCustomApps, toggleApp } from './apps/apps.def.js';
@@ -12,6 +13,7 @@ import { addProject, allProjects, chooseProjects, excludeProject, includeProject
12
13
  import { listLogs, logsView, tailLog } from './logs/logs.def.js';
13
14
  import { auditView, listAudit } from './audit/audit.def.js';
14
15
  import { closeSession, listSessions, restartSessions, sessionsView, startShell } from './sessions/sessions.def.js';
16
+ import { agentCommandsOff, agentCommandsOn, agentCommandsStatus } from './agent-commands/agent-commands.def.js';
15
17
  import { vpnLogin, vpnLogout, vpnStatus, vpnView } from './vpn/vpn.def.js';
16
18
  import { githubLogin, githubLogout, githubStatus, githubView } from './github/github.def.js';
17
19
  import { exportConfig, getSetting, importConfig, listSettings, resetSetting, setSetting, settingsView, } from './settings/settings.def.js';
@@ -31,6 +33,7 @@ export const OPERATIONS = [
31
33
  addAgent,
32
34
  makeDefaultAgent,
33
35
  removeAgent,
36
+ agentsEnvSet,
34
37
  setSetting,
35
38
  resetSetting,
36
39
  exportConfig,
@@ -67,6 +70,8 @@ export const OPERATIONS = [
67
70
  stopWeb,
68
71
  vpnLogin,
69
72
  vpnLogout,
73
+ agentCommandsOn,
74
+ agentCommandsOff,
70
75
  githubLogin,
71
76
  githubLogout,
72
77
  serviceImport,
@@ -82,6 +87,7 @@ export const QUERIES = [
82
87
  sandboxStatus,
83
88
  listSessions,
84
89
  listAgents,
90
+ agentEnv,
85
91
  listSettings,
86
92
  getSetting,
87
93
  browseFolder,
@@ -101,6 +107,7 @@ export const QUERIES = [
101
107
  engineLeftovers,
102
108
  webStatus,
103
109
  vpnStatus,
110
+ agentCommandsStatus,
104
111
  githubStatus,
105
112
  listServices,
106
113
  accessStatus,
@@ -109,6 +116,7 @@ export const VIEWS = [
109
116
  sandboxView,
110
117
  sessionsView,
111
118
  agentsView,
119
+ agentEnvView,
112
120
  settingsView,
113
121
  accountsView,
114
122
  appsView,
@@ -159,6 +167,7 @@ export const NAV = [
159
167
  label: 'Workspace',
160
168
  children: [
161
169
  { label: 'Agents', view: 'agents' },
170
+ { label: 'Claude environment', view: 'agentEnv' },
162
171
  { label: 'Sessions', view: 'sessions' },
163
172
  { label: 'Activity', view: 'audit' },
164
173
  ],
@@ -31,7 +31,7 @@ export const CATEGORIES = [
31
31
  id: 'agents',
32
32
  label: 'Agents & sessions',
33
33
  description: 'The agents you can start (also: Agents section), attaching your terminal to them, the (Beta) web UI and agent commands, which of your Claude settings are copied in, and reopening sessions.',
34
- keys: ['harnesses', 'attach', 'web', 'agentCommands', 'claudeProfile', 'resume'],
34
+ keys: ['harnesses', 'codex', 'attach', 'web', 'agentCommands', 'claudeProfile', 'resume'],
35
35
  },
36
36
  {
37
37
  id: 'network',
@@ -58,7 +58,7 @@ export const SETTINGS_ELSEWHERE = ['apps'];
58
58
  const NAMES = {
59
59
  sandbox: 'Sandbox machine',
60
60
  attach: 'Attaching your terminal',
61
- agentCommands: 'Agent commands (Beta)',
61
+ agentCommands: 'Agent commands',
62
62
  web: 'Web UI (Beta)',
63
63
  provisioning: 'Provisioning',
64
64
  downloads: 'Downloads',
@@ -90,6 +90,7 @@ const NAMES = {
90
90
  projects: 'Projects',
91
91
  resume: 'Reopening sessions',
92
92
  harnesses: 'Agents',
93
+ codex: 'Codex',
93
94
  databases: 'Databases',
94
95
  toolchains: 'Toolchains',
95
96
  git: 'Git',
@@ -142,6 +143,8 @@ const LABELS = {
142
143
  'projects.wsbShare': 'Add folders while the sandbox runs',
143
144
  'projects.liveFolders': 'Add folders through HCS (alpha, untested)',
144
145
  'projects.all': 'Map all known projects at start',
146
+ 'codex.sandboxMode': "Codex's own sandbox",
147
+ 'codex.windowsSandbox': 'Windows sandbox mode for Codex',
145
148
  'claudeProfile.hostDir': 'Claude folder on this PC',
146
149
  'claudeProfile.globalStateFile': 'Claude state file on this PC',
147
150
  };
@@ -6,6 +6,7 @@ import { NEVER_LOOSER } from '../../../core/local-config/index.js';
6
6
  import { redactSecrets } from '../../../core/schema/index.js';
7
7
  import { fail } from '../../../core/util/index.js';
8
8
  import { closest } from '../../../cli/validate.js';
9
+ import { isToolchainReady } from '../../../shared/readiness.js';
9
10
  import { fieldOf } from '../../kernel/index.js';
10
11
  import { categoryOf, labelOf, nameOf } from './categories.def.js';
11
12
  /** Every editable setting of a file, each in its category (settings covered by another section are left out). */
@@ -24,7 +25,10 @@ export function settingsOf(file) {
24
25
  section: several && category.id !== 'general' ? nameOf(top) : undefined,
25
26
  },
26
27
  ];
27
- return node.leaves([top]).map(({ key, node: leaf }) => {
28
+ return node
29
+ .leaves([top])
30
+ .filter(({ key }) => top !== 'toolchains' || isToolchainReady(key[1]))
31
+ .map(({ key, node: leaf }) => {
28
32
  const heading = [
29
33
  several ? nameOf(top) : undefined,
30
34
  key.length > 2 ? key.slice(1, -1).map(nameOf).join(' › ') : undefined,
@@ -1,5 +1,7 @@
1
+ import type { Config } from '../../../core/types.js';
1
2
  import { type AppContext } from '../../context.js';
2
3
  import { type SettingsFiles } from './settings-rows.js';
4
+ import { type Scope } from './settings.def.js';
3
5
  /** The file `sandbox config export` writes when none is named. */
4
6
  export declare const DEFAULT_EXPORT = "sandbox-settings.json";
5
7
  /** Your own settings file (the one --config names) and the project file of the current folder. */
@@ -48,6 +50,12 @@ export declare const getSettingRun: import("../../kernel/define.js").Implementat
48
50
  /** The file of a scope, and the setting a key names in it. */
49
51
  /** incoming with every *** that stands where saved has a text replaced by that saved text. Pure. */
50
52
  export declare function keepShownSecrets(saved: unknown, incoming: unknown): unknown;
53
+ /** What brings this PC in line with a changed agentCommands setting (the real service, or a fake in a test). */
54
+ export interface AgentCommandsReconciler {
55
+ reconcile(config: Config): unknown;
56
+ }
57
+ /** After your own settings change: a key under agentCommands also changes this PC (files, PATH), on every surface. */
58
+ export declare function applyAgentCommandsChange(ctx: AppContext, scope: Scope, key: string, service?: AgentCommandsReconciler): void;
51
59
  export declare const setSettingRun: import("../../kernel/define.js").Implementation<import("../../kernel/define.js").OperationDef<import("zod").ZodObject<{
52
60
  scope: import("zod").ZodDefault<import("zod").ZodEnum<{
53
61
  project: "project";
@@ -7,6 +7,7 @@ import { loadConfig } from '../../../core/config/index.js';
7
7
  import { REDACTED, redactSecrets } from '../../../core/schema/index.js';
8
8
  import { fail, safeText, writeJson } from '../../../core/util/index.js';
9
9
  import { hereDir } from '../../../cli/commands/projects/here.js';
10
+ import { AgentCommandsService } from '../../../cli/services/agent-commands-service.js';
10
11
  import { implement } from '../../context.js';
11
12
  import { allowedText, cancelled, valueFromText } from '../../kernel/index.js';
12
13
  import { CATEGORIES } from './categories.def.js';
@@ -66,6 +67,12 @@ function target(ctx, scope, name) {
66
67
  const file = settingsFiles(ctx)[scope];
67
68
  return { ...findSetting(file, name), file };
68
69
  }
70
+ /** After your own settings change: a key under agentCommands also changes this PC (files, PATH), on every surface. */
71
+ export function applyAgentCommandsChange(ctx, scope, key, service = new AgentCommandsService(ctx)) {
72
+ if (scope !== 'user' || !/^agentCommands(\.|$)/.test(key))
73
+ return;
74
+ service.reconcile(freshConfig(ctx));
75
+ }
69
76
  export const setSettingRun = implement(setSetting, (ctx, input) => {
70
77
  const { key, node, file } = target(ctx, input.scope, input.key);
71
78
  if (node.isSection)
@@ -81,6 +88,7 @@ export const setSettingRun = implement(setSetting, (ctx, input) => {
81
88
  const outcome = file.set(key, value);
82
89
  if (typeof outcome === 'object')
83
90
  fail('Could not change ' + input.key + ': ' + outcome.problems.join('; '), 'Nothing was written.');
91
+ applyAgentCommandsChange(ctx, input.scope, input.key);
84
92
  return {
85
93
  key: input.key,
86
94
  changed: outcome === 'saved',
@@ -96,6 +104,7 @@ export const resetSettingRun = implement(resetSetting, (ctx, input) => {
96
104
  const outcome = file.set(key, undefined);
97
105
  if (typeof outcome === 'object')
98
106
  fail('Could not reset ' + input.key + ': ' + outcome.problems.join('; '), 'Nothing was written.');
107
+ applyAgentCommandsChange(ctx, input.scope, input.key);
99
108
  return {
100
109
  key: input.key,
101
110
  changed: outcome === 'saved',
@@ -3,7 +3,7 @@
3
3
  // runs, rollback on failure) stays in host/update.
4
4
  import { userDir } from '../../../core/config/index.js';
5
5
  import { errMsg, fail } from '../../../core/util/index.js';
6
- import { MigrateService, NPM_UPDATE_COMMAND, UpdateService } from '../../../cli/services/index.js';
6
+ import { AgentCommandsService, MigrateService, NPM_UPDATE_COMMAND, UpdateService, } from '../../../cli/services/index.js';
7
7
  import { implement } from '../../context.js';
8
8
  import { cancelled } from '../../kernel/index.js';
9
9
  import { describeResult, whereOf } from './update-lines.js';
@@ -73,7 +73,17 @@ export const runUpdateRun = implement(runUpdate, async (ctx, input, io) => {
73
73
  // A folder of the user's choosing is installed from only on the command line (the web and the menu send no feed).
74
74
  if (input.feed !== undefined && input.feed !== ctx.options.feed)
75
75
  fail('--feed works only on the command line.');
76
- return updateWith(UpdateService.forPackage(ctx.packageRoot, input.feed, { userDir: userDir() }), input, io);
76
+ const result = await updateWith(UpdateService.forPackage(ctx.packageRoot, input.feed, { userDir: userDir() }), input, io);
77
+ // The agent commands (claude, codex ...) point at the program: bring them in line with what is installed now.
78
+ if (ctx.loaded.config.agentCommands.enabled && !input.check && !input.rollback && !input.auto) {
79
+ try {
80
+ new AgentCommandsService(ctx).reconcile(ctx.loaded.config);
81
+ }
82
+ catch {
83
+ // The update itself worked; the agent commands are put right at the next launch.
84
+ }
85
+ }
86
+ return result;
77
87
  });
78
88
  /** sandbox migrate's work, given the service (tests pass their own). */
79
89
  export async function migrateWith(service, input, io) {
@@ -31,6 +31,17 @@ export declare const VpnStatusSchema: z.ZodObject<{
31
31
  }>;
32
32
  text: z.ZodString;
33
33
  }, z.core.$strip>>;
34
+ lastFailure: z.ZodNullable<z.ZodObject<{
35
+ code: z.ZodEnum<{
36
+ auth: "auth";
37
+ unreachable: "unreachable";
38
+ driver: "driver";
39
+ timeout: "timeout";
40
+ other: "other";
41
+ }>;
42
+ text: z.ZodString;
43
+ at: z.ZodString;
44
+ }, z.core.$strip>>;
34
45
  }, z.core.$strip>;
35
46
  export type VpnStatus = z.output<typeof VpnStatusSchema>;
36
47
  export declare const vpnStatus: import("../../kernel/define.js").QueryDef<z.ZodObject<{
@@ -62,6 +73,17 @@ export declare const vpnStatus: import("../../kernel/define.js").QueryDef<z.ZodO
62
73
  }>;
63
74
  text: z.ZodString;
64
75
  }, z.core.$strip>>;
76
+ lastFailure: z.ZodNullable<z.ZodObject<{
77
+ code: z.ZodEnum<{
78
+ auth: "auth";
79
+ unreachable: "unreachable";
80
+ driver: "driver";
81
+ timeout: "timeout";
82
+ other: "other";
83
+ }>;
84
+ text: z.ZodString;
85
+ at: z.ZodString;
86
+ }, z.core.$strip>>;
65
87
  }, z.core.$strip>, "vpn.status">;
66
88
  export declare const vpnLogin: import("../../kernel/define.js").OperationDef<z.ZodObject<{}, z.core.$strict>, z.ZodObject<{
67
89
  message: z.ZodString;
@@ -108,5 +130,16 @@ export declare const vpnView: import("../../kernel/define.js").ViewDef<{
108
130
  }>;
109
131
  text: z.ZodString;
110
132
  }, z.core.$strip>>;
133
+ lastFailure: z.ZodNullable<z.ZodObject<{
134
+ code: z.ZodEnum<{
135
+ auth: "auth";
136
+ unreachable: "unreachable";
137
+ driver: "driver";
138
+ timeout: "timeout";
139
+ other: "other";
140
+ }>;
141
+ text: z.ZodString;
142
+ at: z.ZodString;
143
+ }, z.core.$strip>>;
111
144
  }, z.core.$strip>, "vpn.status">;
112
145
  }, Record<string, never>, "vpn">;