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
@@ -37,6 +37,14 @@ export const VpnStatusSchema = z.object({
37
37
  })
38
38
  .nullable()
39
39
  .describe("The running sandbox's tunnel, when one runs with the VPN on"),
40
+ lastFailure: z
41
+ .object({
42
+ code: z.enum(['auth', 'unreachable', 'driver', 'timeout', 'other']).describe('Why the last attempt failed'),
43
+ text: z.string().describe('The reason in plain words'),
44
+ at: z.string().describe('When (ISO date and time)'),
45
+ })
46
+ .nullable()
47
+ .describe("The last sandbox's VPN attempt, when it failed (kept after the sandbox closed)"),
40
48
  });
41
49
  export const vpnStatus = defineQuery({
42
50
  id: 'vpn.status',
@@ -125,6 +133,16 @@ export function vpnPage(s) {
125
133
  wireguard
126
134
  ? { id: 'login', label: 'Login', value: 'not needed (the keys are in your config)', tone: 'muted' }
127
135
  : { id: 'login', label: 'Login', value: LOGIN_TEXT[s.login] + savedDate, tone: LOGIN_TONE[s.login] },
136
+ ...(s.lastFailure
137
+ ? [
138
+ {
139
+ id: 'lastAttempt',
140
+ label: 'Last attempt',
141
+ value: s.lastFailure.text + ' (' + s.lastFailure.at.slice(0, 16).replace('T', ' ') + ')',
142
+ tone: 'danger',
143
+ },
144
+ ]
145
+ : []),
128
146
  ...(s.running
129
147
  ? [
130
148
  {
@@ -137,14 +155,14 @@ export function vpnPage(s) {
137
155
  : []),
138
156
  ];
139
157
  const notes = [
140
- ...(!wireguard && s.login === 'none'
141
- ? [{ text: 'Next: sandbox vpn login', tone: 'muted', only: 'cli' }]
142
- : []),
143
158
  ...(s.login === 'unreadable'
159
+ ? [{ text: 'Only the Windows user that saved it can read it. Save it again.', tone: 'muted' }]
160
+ : []),
161
+ ...(s.lastFailure?.code === 'auth' && s.provider === 'nordvpn'
144
162
  ? [
145
163
  {
146
- text: 'Only the Windows user that saved it can read it. Save it again: sandbox vpn login',
147
- tone: 'muted',
164
+ text: 'NordVPN refused the login. It needs the service credentials (Nord Account > NordVPN > Manual setup), not your e-mail and password.',
165
+ tone: 'warn',
148
166
  },
149
167
  ]
150
168
  : []),
@@ -152,12 +170,18 @@ export function vpnPage(s) {
152
170
  ];
153
171
  // Turning it on or off is the vpn.enabled setting (it applies from the next start).
154
172
  const toggle = action(setSetting, { scope: 'user', key: 'vpn.enabled', value: !s.enabled }, { label: s.enabled ? 'Turn the VPN off' : 'Turn the VPN on', verb: s.enabled ? 'turn off' : 'turn on', key: 'o' });
173
+ const refused = s.lastFailure?.code === 'auth';
155
174
  const actions = [
156
175
  toggle,
176
+ ...(s.lastFailure?.code === 'unreachable' && s.protocol === 'udp'
177
+ ? [
178
+ action(setSetting, { scope: 'user', key: 'vpn.protocol', value: 'tcp' }, { label: 'Try TCP instead of UDP', verb: 'use tcp', key: 't' }),
179
+ ]
180
+ : []),
157
181
  ...(wireguard
158
182
  ? []
159
183
  : [
160
- action(vpnLogin, {}, { key: 'v', verb: 'save login' }),
184
+ action(vpnLogin, {}, { key: 'v', verb: 'save login', ...(refused ? { label: 'Save the login again…' } : {}) }),
161
185
  ...(s.login !== 'none' ? [action(vpnLogout, {}, { key: 'x', verb: 'delete login' })] : []),
162
186
  ]),
163
187
  ];
@@ -27,6 +27,17 @@ export declare const vpnStatusRun: import("../../kernel/define.js").Implementati
27
27
  }>;
28
28
  text: import("zod").ZodString;
29
29
  }, import("zod/v4/core").$strip>>;
30
+ lastFailure: import("zod").ZodNullable<import("zod").ZodObject<{
31
+ code: import("zod").ZodEnum<{
32
+ auth: "auth";
33
+ unreachable: "unreachable";
34
+ driver: "driver";
35
+ timeout: "timeout";
36
+ other: "other";
37
+ }>;
38
+ text: import("zod").ZodString;
39
+ at: import("zod").ZodString;
40
+ }, import("zod/v4/core").$strip>>;
30
41
  }, import("zod/v4/core").$strip>, "vpn.status">, import("../../../cli/commands/context.js").Context>;
31
42
  export declare const vpnLoginRun: import("../../kernel/define.js").Implementation<import("../../kernel/define.js").OperationDef<import("zod").ZodObject<{}, import("zod/v4/core").$strict>, import("zod").ZodObject<{
32
43
  message: import("zod").ZodString;
@@ -32,8 +32,11 @@ export const vpnLoginRun = implement(vpnLogin, async (ctx, _input, io) => {
32
32
  if (password === undefined)
33
33
  cancelled();
34
34
  service.save({ username, password });
35
+ const warning = service.warning({ username, password });
36
+ if (warning)
37
+ io.log(warning, 'warn');
35
38
  VPN_WARNINGS.forEach((w) => io.log(w, 'muted'));
36
- return { message: 'Saved. Turn the VPN on with: sandbox config set vpn.enabled true' };
39
+ return { message: 'Saved. Use "Turn the VPN on" on the VPN page to use it from the next start.' };
37
40
  });
38
41
  export const vpnLogoutRun = implement(vpnLogout, async (ctx, _input, io) => {
39
42
  requireOnPc('vpn logout');
@@ -57,8 +57,8 @@ export declare const ServerMessageSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
57
57
  text: z.ZodString;
58
58
  tone: z.ZodOptional<z.ZodEnum<{
59
59
  ok: "ok";
60
- muted: "muted";
61
60
  warn: "warn";
61
+ muted: "muted";
62
62
  danger: "danger";
63
63
  accent: "accent";
64
64
  }>>;
@@ -1,6 +1,6 @@
1
1
  import { fail } from '../core/util/errors.js';
2
2
  import { accessNeeded, allows, invoke, OWNER, refusalText, NO_QUESTIONS, onSurface, } from './kernel/index.js';
3
- import { addAgentRun, listAgentsRun, makeDefaultAgentRun, removeAgentRun, startAgentRun, } from './features/agents/index.js';
3
+ import { addAgentRun, agentEnvRun, agentsEnvSetRun, listAgentsRun, makeDefaultAgentRun, removeAgentRun, startAgentRun, } from './features/agents/index.js';
4
4
  import { defaultAccountRun, listAccountsRun, removeAccountRun, renameAccountRun, saveAccountRun, useAccountRun, listServicesRun, serviceImportRun, serviceLoginRun, serviceLogoutRun, } from './features/accounts/index.js';
5
5
  import { listAppsRun, requestAppRun, setCustomAppsRun, toggleAppRun } from './features/apps/index.js';
6
6
  import { browseFolderRun } from './features/files/index.js';
@@ -16,6 +16,7 @@ import { exportConfigRun, getSettingRun, importConfigRun, listSettingsRun, reset
16
16
  import { migrateSettingsRun, runUpdateRun, updatesStatusRun } from './features/updates/index.js';
17
17
  import { checkEngineRun, cleanEngineRun, engineLeftoversRun, engineStatusRun } from './features/engine/index.js';
18
18
  import { openWebRun, startWebRun, stopWebRun, webStatusRun } from './features/web/index.js';
19
+ import { agentCommandsOffRun, agentCommandsOnRun, agentCommandsStatusRun } from './features/agent-commands/index.js';
19
20
  import { vpnLoginRun, vpnLogoutRun, vpnStatusRun } from './features/vpn/index.js';
20
21
  import { githubLoginRun, githubLogoutRun, githubStatusRun } from './features/github/index.js';
21
22
  import { accessStatusRun, allowDeviceRun, lanOffRun, lanOnRun, revokeAccessRun, revokeAllAccessRun, } from './features/access/index.js';
@@ -34,6 +35,8 @@ export const IMPLEMENTATIONS = [
34
35
  makeDefaultAgentRun,
35
36
  removeAgentRun,
36
37
  listAgentsRun,
38
+ agentEnvRun,
39
+ agentsEnvSetRun,
37
40
  listSettingsRun,
38
41
  getSettingRun,
39
42
  setSettingRun,
@@ -89,6 +92,9 @@ export const IMPLEMENTATIONS = [
89
92
  vpnStatusRun,
90
93
  vpnLoginRun,
91
94
  vpnLogoutRun,
95
+ agentCommandsStatusRun,
96
+ agentCommandsOnRun,
97
+ agentCommandsOffRun,
92
98
  githubStatusRun,
93
99
  githubLoginRun,
94
100
  githubLogoutRun,
@@ -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-N4GXYTLV.js";
6
- import "./chunk-FRPLQLSY.js";
5
+ } from "./chunk-DK4NTBUF.js";
6
+ import "./chunk-Z2P5OGKL.js";
7
7
 
8
8
  // src/bin/agent-sandbox.ts
9
9
  run(process.argv.slice(2));
@@ -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-FRPLQLSY.js";
4
+ } from "./chunk-Z2P5OGKL.js";
5
5
  export {
6
6
  attach
7
7
  };
@@ -45,7 +45,9 @@ import {
45
45
  __require,
46
46
  __toESM,
47
47
  action,
48
- agentCommandsCommand,
48
+ agentCommandsStatus,
49
+ agentEnv,
50
+ agentEnvPage,
49
51
  agentPage,
50
52
  agentsPage,
51
53
  allowStorePath,
@@ -228,7 +230,7 @@ import {
228
230
  withOperationCommands,
229
231
  working,
230
232
  writeJson
231
- } from "./chunk-FRPLQLSY.js";
233
+ } from "./chunk-Z2P5OGKL.js";
232
234
 
233
235
  // node_modules/commander/lib/error.js
234
236
  var require_error = __commonJS({
@@ -4153,7 +4155,7 @@ var COMMAND_LIST = [
4153
4155
  },
4154
4156
  {
4155
4157
  name: "agent-commands",
4156
- summary: "(Beta) make claude, codex ... on this PC start in a hidden sandbox and attach",
4158
+ summary: "make claude, codex ... on this PC start in a hidden sandbox and attach",
4157
4159
  group: "Advanced",
4158
4160
  args: [{ name: "action", description: "on, off or status", required: false, choices: ["status", "on", "off"] }],
4159
4161
  options: []
@@ -4887,7 +4889,9 @@ var TextScreen = class {
4887
4889
  }
4888
4890
  if (key.text) {
4889
4891
  const accept = this.o.accept;
4890
- const add = [...key.text.replace(/[\r\n]/g, "")].filter((c2) => !accept || accept.test(c2));
4892
+ const add = [...key.text.replace(/\x1b?\[20[01]~/g, "").replace(/[\r\n]/g, "")].filter(
4893
+ (c2) => !accept || accept.test(c2)
4894
+ );
4891
4895
  if (!add.length) return;
4892
4896
  set([...chars.slice(0, this.cursor), ...add, ...chars.slice(this.cursor)], this.cursor + add.length);
4893
4897
  }
@@ -6054,9 +6058,10 @@ var Terminal = class {
6054
6058
  });
6055
6059
  }
6056
6060
  push(str, key) {
6061
+ const marker = key?.name === "paste-start" || key?.name === "paste-end";
6057
6062
  const event = {
6058
6063
  name: key?.name ?? "",
6059
- text: str && !key?.ctrl && !key?.meta && str.length >= 1 && str >= " " && str !== "\x7F" ? str : "",
6064
+ text: str && !marker && !key?.ctrl && !key?.meta && str.length >= 1 && str >= " " && str !== "\x7F" ? str : "",
6060
6065
  ctrl: Boolean(key?.ctrl),
6061
6066
  meta: Boolean(key?.meta),
6062
6067
  shift: Boolean(key?.shift)
@@ -7714,6 +7719,9 @@ var SeveralAgents = class {
7714
7719
  };
7715
7720
 
7716
7721
  // src/cli/menu/pages/agents-page.ts
7722
+ function commandsOf(m) {
7723
+ return m.agentCommands ?? { enabled: m.hostAgents.length > 0, dir: "", found: [] };
7724
+ }
7717
7725
  function agentsList(m) {
7718
7726
  const removable = m.removable ?? [];
7719
7727
  return {
@@ -7728,7 +7736,12 @@ function agentsList(m) {
7728
7736
  };
7729
7737
  }
7730
7738
  function startView(m) {
7731
- return menuView(agentsPage(agentsList(m)), { category: "start", refresh: false });
7739
+ const page = agentsPage(agentsList(m), commandsOf(m));
7740
+ return menuView({ ...page, sections: page.sections.slice(0, 1) }, { category: "start", refresh: false });
7741
+ }
7742
+ function commandsView(m) {
7743
+ const page = agentsPage(agentsList(m), commandsOf(m));
7744
+ return menuView({ ...page, sections: page.sections.slice(1) }, { category: "host", refresh: false });
7732
7745
  }
7733
7746
  function hostAgentsToShow(enabled, found) {
7734
7747
  return enabled ? found.map((a) => a.harness) : [];
@@ -7754,14 +7767,19 @@ function agentCategories(m) {
7754
7767
  label: "Start",
7755
7768
  description: "Agents you can start in " + m.folder + ". Add an agent at the end of the list."
7756
7769
  },
7757
- { id: "options", label: "Options", description: "How a start goes, and the other ways to start." },
7758
- ...m.hostAgents.length ? [
7770
+ ...m.claudeEnv ? [
7759
7771
  {
7760
- id: "host",
7761
- label: "On this PC",
7762
- description: "The real agents on this PC, with no sandbox around them."
7772
+ id: "env",
7773
+ label: "Claude environment",
7774
+ description: "Models, limits, how many subagents run at once, and other variables of Claude."
7763
7775
  }
7764
- ] : []
7776
+ ] : [],
7777
+ { id: "options", label: "Options", description: "How a start goes, and the other ways to start." },
7778
+ {
7779
+ id: "host",
7780
+ label: "On this PC",
7781
+ description: "Agent commands: typing claude, codex ... here starts them in a sandbox. The real agents are listed too."
7782
+ }
7765
7783
  ];
7766
7784
  }
7767
7785
  function startRow(item2, m, cwd) {
@@ -7773,8 +7791,13 @@ function startRow(item2, m, cwd) {
7773
7791
  details: [Theme.muted("Command ") + commandLine(startArgv(m, name, cwd))]
7774
7792
  };
7775
7793
  }
7794
+ function envView(m) {
7795
+ return m.claudeEnv ? menuView(agentEnvPage(m.claudeEnv), { category: "env", refresh: false }) : void 0;
7796
+ }
7776
7797
  function agentsOptions(m, cwd = process.cwd()) {
7777
7798
  const view2 = startView(m);
7799
+ const env = envView(m);
7800
+ const commands = commandsView(m);
7778
7801
  return {
7779
7802
  path: [],
7780
7803
  categories: agentCategories(m),
@@ -7790,6 +7813,8 @@ function agentsOptions(m, cwd = process.cwd()) {
7790
7813
  }
7791
7814
  ] : [],
7792
7815
  ...view2.items.map((item2) => startRow(item2, m, cwd)),
7816
+ ...env?.items ?? [],
7817
+ ...commands.items,
7793
7818
  {
7794
7819
  value: "opt:attach",
7795
7820
  label: "Attach this terminal",
@@ -7843,8 +7868,8 @@ function agentsOptions(m, cwd = process.cwd()) {
7843
7868
  description: "Runs the real " + agent + " on this PC, with no sandbox around it."
7844
7869
  }))
7845
7870
  ],
7846
- enterLabel: (_category, id) => ENTER[id ?? ""] ?? (id?.startsWith("agent:") ? "start" : id?.startsWith("host:") ? "run" : "open"),
7847
- actions: (category) => category === "start" ? view2.actions : []
7871
+ enterLabel: (category, id) => ENTER[id ?? ""] ?? (id?.startsWith("agent:") ? "start" : id?.startsWith("host:") ? "run" : category === "host" ? commands.enterLabel(category, id) : "open"),
7872
+ actions: (category) => category === "start" ? view2.actions : category === "env" ? env?.actions ?? [] : category === "host" ? commands.actions : []
7848
7873
  };
7849
7874
  }
7850
7875
  var ENTER = {
@@ -7875,7 +7900,7 @@ var AgentsPage = class extends ListPage {
7875
7900
  facts;
7876
7901
  current() {
7877
7902
  if (!this.facts) throw new Error("The agents tab was not loaded");
7878
- const { agents, commands, last } = this.facts;
7903
+ const { agents, commands, last, env } = this.facts;
7879
7904
  return {
7880
7905
  folder: this.folder,
7881
7906
  defaultAgent: agents.defaultAgent,
@@ -7884,7 +7909,13 @@ var AgentsPage = class extends ListPage {
7884
7909
  attach: this.attach,
7885
7910
  window: this.window,
7886
7911
  hostAgents: hostAgentsToShow(commands.enabled, commands.found),
7887
- removable: agents.agents.filter((a) => a.removable).map((a) => a.name)
7912
+ agentCommands: {
7913
+ enabled: commands.enabled,
7914
+ dir: commands.dir,
7915
+ found: commands.found.map((a) => ({ command: a.command, harness: a.harness, real: a.real }))
7916
+ },
7917
+ removable: agents.agents.filter((a) => a.removable).map((a) => a.name),
7918
+ ...env ? { claudeEnv: env } : {}
7888
7919
  };
7889
7920
  }
7890
7921
  /** The cursor starts on the default agent. */
@@ -7895,7 +7926,8 @@ var AgentsPage = class extends ListPage {
7895
7926
  this.facts = {
7896
7927
  agents: await readQuery(listAgents, this.ctx),
7897
7928
  commands: await new AgentCommandsService(this.ctx).statusAsync(),
7898
- last: readHistory()[0]?.argv
7929
+ last: readHistory()[0]?.argv,
7930
+ env: "claude" in this.ctx.loaded.config.harnesses ? await readQuery(agentEnv, this.ctx, { agent: "claude" }) : void 0
7899
7931
  };
7900
7932
  this.model = this.current();
7901
7933
  }
@@ -7905,9 +7937,19 @@ var AgentsPage = class extends ListPage {
7905
7937
  }
7906
7938
  async act(result) {
7907
7939
  const model = this.current();
7908
- const chosen = startView(model).resolve(result);
7940
+ const env = this.category === "env" ? envView(model) : void 0;
7941
+ if (env) {
7942
+ const picked = env.resolve(result);
7943
+ if (picked?.kind === "action") return this.operate(picked.action);
7944
+ return {};
7945
+ }
7946
+ const chosen = startView(model).resolve(result) ?? commandsView(model).resolve(result);
7909
7947
  if (chosen?.kind === "action") {
7910
7948
  const { action: action2 } = chosen;
7949
+ if (action2.kind === "link" && action2.target.kind === "view") {
7950
+ await this.selectCategory("env");
7951
+ return {};
7952
+ }
7911
7953
  if (action2.kind === "link" && action2.target.kind === "start-agent")
7912
7954
  return { exit: { kind: "run", argv: startArgv(model, action2.target.agent, process.cwd()) } };
7913
7955
  return this.operate(action2);
@@ -8158,15 +8200,14 @@ var CATEGORIES2 = [
8158
8200
  },
8159
8201
  { id: "more", label: "More commands", description: "Less common commands." }
8160
8202
  ];
8161
- var MORE_COMMANDS = ["sync", "config", "generate", "exec", "agent-commands"];
8203
+ var MORE_COMMANDS = ["sync", "config", "generate", "exec"];
8162
8204
  var NO_LOGS = { folder: "", files: [], crash: false };
8163
8205
  var NO_WEB = { running: false, port: null, address: null };
8164
8206
  var MORE_LABELS = {
8165
8207
  sync: "Copy history back now",
8166
8208
  config: "Your settings file",
8167
8209
  generate: "Preview a start",
8168
- exec: "Run a command in the sandbox",
8169
- "agent-commands": "Agent commands (Beta)"
8210
+ exec: "Run a command in the sandbox"
8170
8211
  };
8171
8212
  function dataMenuView(data) {
8172
8213
  return data ? menuView(dataPage(data), { category: "data", prefix: "data:", refresh: false }) : void 0;
@@ -8781,7 +8822,8 @@ var SettingsPage = class extends ListPage {
8781
8822
  killSwitch: true,
8782
8823
  login: "none",
8783
8824
  loginSavedAt: null,
8784
- running: null
8825
+ running: null,
8826
+ lastFailure: null
8785
8827
  };
8786
8828
  /** Whether a GitHub token is saved (never the token): the token row needs only its state. */
8787
8829
  github = { shareToken: false, gitAccess: "full", token: "none", kind: null, savedAt: null };
@@ -9400,7 +9442,7 @@ var Menu = class {
9400
9442
  await pressAnyKey(Theme.muted("Press any key for the menu\u2026"));
9401
9443
  });
9402
9444
  }
9403
- /** After a save: agent commands (Beta) may have been switched, which changes this PC. */
9445
+ /** After a save: agent commands may have been switched, which changes this PC. */
9404
9446
  applyAgentCommands(saved) {
9405
9447
  if (!saved.files.some((f) => !f.isProject)) return void 0;
9406
9448
  try {
@@ -9408,9 +9450,9 @@ var Menu = class {
9408
9450
  loadConfig(this.ctx.loaded.configPath ?? void 0).config
9409
9451
  );
9410
9452
  if (!result?.changed) return void 0;
9411
- return result.on ? "Agent commands (Beta) are on: open a new terminal." : "Agent commands are off: claude, codex ... run on this PC again (open a new terminal).";
9453
+ return result.on ? "Agent commands are on: open a new terminal." : "Agent commands are off: claude, codex ... run on this PC again (open a new terminal).";
9412
9454
  } catch (e) {
9413
- return "Agent commands (Beta): " + errMsg(e);
9455
+ return "Agent commands: " + errMsg(e);
9414
9456
  }
9415
9457
  }
9416
9458
  };
@@ -10282,7 +10324,6 @@ var HANDLERS = {
10282
10324
  generate: (ctx) => launch(ctx, true),
10283
10325
  attach,
10284
10326
  exec,
10285
- "agent-commands": agentCommandsCommand,
10286
10327
  db,
10287
10328
  resume,
10288
10329
  // The bare command lists; its actions (save, use ...) are the operations' hints.
@@ -10317,6 +10358,8 @@ var HANDLERS = {
10317
10358
  "host-claude": claudeHost,
10318
10359
  host: hostCommand,
10319
10360
  _watch: watcher,
10361
+ // The bare command shows the status; on and off are the operations' hints (src/app/features/agent-commands).
10362
+ "agent-commands": definitionHandler(agentCommandsStatus),
10320
10363
  vpn,
10321
10364
  github,
10322
10365
  web,