windows-development-sandbox 1.18.3 → 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 (216) 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 +150 -1
  28. package/dist/app/features/defs.js +11 -1
  29. package/dist/app/features/sandbox/sandbox.def.d.ts +22 -0
  30. package/dist/app/features/sandbox/sandbox.def.js +41 -14
  31. package/dist/app/features/sandbox/sandbox.run.d.ts +20 -0
  32. package/dist/app/features/sandbox/sandbox.run.js +41 -1
  33. package/dist/app/features/settings/categories.def.js +5 -2
  34. package/dist/app/features/settings/settings-rows.js +5 -1
  35. package/dist/app/features/settings/settings.run.d.ts +8 -0
  36. package/dist/app/features/settings/settings.run.js +9 -0
  37. package/dist/app/features/updates/updates.run.js +12 -2
  38. package/dist/app/features/vpn/vpn.def.d.ts +33 -0
  39. package/dist/app/features/vpn/vpn.def.js +30 -6
  40. package/dist/app/features/vpn/vpn.run.d.ts +11 -0
  41. package/dist/app/features/vpn/vpn.run.js +4 -1
  42. package/dist/app/kernel/rpc.d.ts +1 -1
  43. package/dist/app/registry.js +9 -2
  44. package/dist/bin/agent-sandbox.js +2 -2
  45. package/dist/bin/{chunk-M6XUQK53.js → chunk-2IMT7ZCT.js} +1 -1
  46. package/dist/bin/{chunk-3G53NNZP.js → chunk-DK4NTBUF.js} +69 -26
  47. package/dist/bin/{chunk-FQWYCF6L.js → chunk-Z2P5OGKL.js} +6427 -5259
  48. package/dist/bin/claude-host.js +2 -2
  49. package/dist/bin/claude-sbx.js +2 -2
  50. package/dist/bin/codex-sbx.js +2 -2
  51. package/dist/bin/gemini-sbx.js +2 -2
  52. package/dist/bin/sandbox.js +2 -2
  53. package/dist/bin/sbx-hide.js +2 -2
  54. package/dist/bin/sbx-show.js +2 -2
  55. package/dist/cli/commands/agent-commands.d.ts +0 -1
  56. package/dist/cli/commands/agent-commands.js +2 -32
  57. package/dist/cli/commands/index.d.ts +1 -1
  58. package/dist/cli/commands/index.js +1 -1
  59. package/dist/cli/commands/launch/launch.js +6 -3
  60. package/dist/cli/commands/launch/leftover-offer.d.ts +3 -0
  61. package/dist/cli/commands/launch/leftover-offer.js +26 -0
  62. package/dist/cli/commands/registry.js +3 -2
  63. package/dist/cli/commands/repair/checks/sandbox.js +29 -2
  64. package/dist/cli/manifest.d.ts +1 -1
  65. package/dist/cli/manifest.js +1 -1
  66. package/dist/cli/menu/menu.d.ts +1 -1
  67. package/dist/cli/menu/menu.js +3 -3
  68. package/dist/cli/menu/pages/agents-page.d.ts +7 -2
  69. package/dist/cli/menu/pages/agents-page.js +67 -11
  70. package/dist/cli/menu/pages/maintenance-page.js +1 -2
  71. package/dist/cli/menu/pages/settings-page.js +1 -0
  72. package/dist/cli/menu/views.js +2 -1
  73. package/dist/cli/services/agent-commands-service.d.ts +2 -0
  74. package/dist/cli/services/agent-commands-service.js +13 -7
  75. package/dist/cli/services/vpn-service.d.ts +5 -1
  76. package/dist/cli/services/vpn-service.js +6 -1
  77. package/dist/cli/tui/dialogs/text-screen.js +2 -1
  78. package/dist/cli/tui/terminal.js +3 -1
  79. package/dist/core/config/defaults.js +9 -0
  80. package/dist/core/detect/toolchains.js +9 -0
  81. package/dist/core/disk.d.ts +1 -5
  82. package/dist/core/disk.js +1 -16
  83. package/dist/core/schema/codex.d.ts +29 -0
  84. package/dist/core/schema/codex.js +24 -0
  85. package/dist/core/schema/config.d.ts +46 -14
  86. package/dist/core/schema/config.js +2 -0
  87. package/dist/core/schema/index.d.ts +1 -0
  88. package/dist/core/schema/index.js +1 -0
  89. package/dist/core/schema/toolchains.d.ts +4 -0
  90. package/dist/core/schema/toolchains.js +3 -0
  91. package/dist/core/types.d.ts +2 -0
  92. package/dist/guest/accounts/apply.d.ts +6 -6
  93. package/dist/guest/agents/agent-files.d.ts +26 -6
  94. package/dist/guest/agents/agent-files.js +84 -14
  95. package/dist/guest/agents/local-state.d.ts +5 -2
  96. package/dist/guest/agents/local-state.js +24 -10
  97. package/dist/guest/boot/boot.js +10 -5
  98. package/dist/guest/daemon/heartbeat.d.ts +7 -2
  99. package/dist/guest/daemon/heartbeat.js +34 -15
  100. package/dist/guest/daemon/idle-shutdown.js +2 -0
  101. package/dist/guest/daemon/sessions.js +2 -1
  102. package/dist/guest/entries/daemon.js +1 -1
  103. package/dist/guest/toolchains/installers.d.ts +6 -10
  104. package/dist/guest/toolchains/installers.js +4 -12
  105. package/dist/guest/toolchains/native/autosdk.d.ts +3 -0
  106. package/dist/guest/toolchains/native/autosdk.js +50 -0
  107. package/dist/guest/toolchains/native/unreal.js +3 -0
  108. package/dist/guest/toolchains/native/vcruntime.d.ts +0 -3
  109. package/dist/guest/toolchains/native/vcruntime.js +2 -5
  110. package/dist/guest/toolchains/native/visual-studio.d.ts +2 -2
  111. package/dist/guest/toolchains/native/visual-studio.js +100 -16
  112. package/dist/guest/toolchains/native/vs-request.d.ts +21 -0
  113. package/dist/guest/toolchains/native/vs-request.js +60 -1
  114. package/dist/guest/toolchains/not-yet.d.ts +1 -1
  115. package/dist/guest/toolchains/not-yet.js +3 -3
  116. package/dist/guest/toolchains/persisted.js +2 -7
  117. package/dist/guest/toolchains/plan.js +9 -4
  118. package/dist/guest/toolchains/signature.d.ts +5 -0
  119. package/dist/guest/toolchains/signature.js +22 -0
  120. package/dist/guest/vpn/tunnel.d.ts +3 -0
  121. package/dist/guest/vpn/tunnel.js +10 -12
  122. package/dist/guest/vpn/vpn.js +6 -1
  123. package/dist/host/accounts/leases.d.ts +3 -3
  124. package/dist/host/accounts/source.js +1 -1
  125. package/dist/host/agent-commands/commands.js +1 -1
  126. package/dist/host/agent-commands/forwarders.d.ts +14 -2
  127. package/dist/host/agent-commands/forwarders.js +31 -13
  128. package/dist/host/agent-commands/reconcile.d.ts +2 -1
  129. package/dist/host/agent-commands/reconcile.js +7 -8
  130. package/dist/host/agent-commands/user-path.d.ts +5 -0
  131. package/dist/host/agent-commands/user-path.js +13 -0
  132. package/dist/host/health/index.d.ts +1 -0
  133. package/dist/host/health/index.js +1 -0
  134. package/dist/host/health/leftovers.d.ts +3 -0
  135. package/dist/host/health/leftovers.js +40 -0
  136. package/dist/host/health/stale.d.ts +48 -0
  137. package/dist/host/health/stale.js +40 -0
  138. package/dist/host/launch/session-file.js +1 -0
  139. package/dist/host/life/crash-report.d.ts +1 -1
  140. package/dist/host/life/crash-report.js +5 -3
  141. package/dist/host/life/last-end.d.ts +7 -0
  142. package/dist/host/life/last-end.js +21 -0
  143. package/dist/host/life/life-record.d.ts +3 -0
  144. package/dist/host/life/life-record.js +2 -2
  145. package/dist/host/life/stop-events.d.ts +3 -1
  146. package/dist/host/life/stop-events.js +59 -0
  147. package/dist/host/life/stop-warning.js +3 -0
  148. package/dist/host/profile/accounts.js +2 -4
  149. package/dist/host/profile/claude-login.d.ts +3 -2
  150. package/dist/host/profile/claude-login.js +3 -13
  151. package/dist/host/sandbox/cleanup.d.ts +37 -0
  152. package/dist/host/sandbox/cleanup.js +82 -0
  153. package/dist/host/sandbox/index.d.ts +1 -0
  154. package/dist/host/sandbox/index.js +1 -0
  155. package/dist/host/sandbox/platform.js +1 -1
  156. package/dist/host/vpn/index.d.ts +2 -1
  157. package/dist/host/vpn/index.js +2 -1
  158. package/dist/host/vpn/last.d.ts +28 -0
  159. package/dist/host/vpn/last.js +43 -0
  160. package/dist/host/vpn/login.d.ts +3 -1
  161. package/dist/host/vpn/login.js +17 -3
  162. package/dist/runtime/agent.js +31 -1
  163. package/dist/runtime/daemon.js +1419 -1197
  164. package/dist/runtime/db.js +33 -1
  165. package/dist/runtime/main.js +1311 -1037
  166. package/dist/runtime/netproxy.js +25 -1
  167. package/dist/runtime/tool.js +241 -209
  168. package/dist/runtime/view.js +25 -1
  169. package/dist/selftest/agent-commands.test.js +45 -7
  170. package/dist/selftest/agent-paths.test.js +1 -12
  171. package/dist/selftest/agent-settings.test.d.ts +2 -0
  172. package/dist/selftest/agent-settings.test.js +94 -0
  173. package/dist/selftest/app.test.js +2 -1
  174. package/dist/selftest/cli.test.js +4 -0
  175. package/dist/selftest/heavy-load.test.js +119 -2
  176. package/dist/selftest/index.js +2 -0
  177. package/dist/selftest/menu.test.js +5 -3
  178. package/dist/selftest/pc-installs.test.js +5 -0
  179. package/dist/selftest/persisted-installs.test.js +69 -0
  180. package/dist/selftest/service-accounts.test.js +1 -1
  181. package/dist/selftest/support/engine-golden.js +1 -1
  182. package/dist/selftest/support/fixtures.d.ts +9 -0
  183. package/dist/selftest/vpn.test.js +51 -3
  184. package/dist/shared/accounts/anthropic.d.ts +5 -0
  185. package/dist/shared/accounts/anthropic.js +15 -0
  186. package/dist/shared/accounts/index.d.ts +1 -0
  187. package/dist/shared/accounts/index.js +1 -0
  188. package/dist/shared/channel/schema.d.ts +20 -0
  189. package/dist/shared/channel/schema.js +4 -1
  190. package/dist/shared/io/disk.d.ts +9 -0
  191. package/dist/shared/io/disk.js +19 -0
  192. package/dist/shared/io/index.d.ts +1 -0
  193. package/dist/shared/io/index.js +1 -0
  194. package/dist/shared/readiness.d.ts +9 -0
  195. package/dist/shared/readiness.js +11 -0
  196. package/dist/shared/signer.d.ts +24 -0
  197. package/dist/shared/signer.js +15 -0
  198. package/dist/shared/system.d.ts +1 -0
  199. package/dist/shared/system.js +1 -0
  200. package/dist/shared/vpn/failure.d.ts +10 -0
  201. package/dist/shared/vpn/failure.js +28 -0
  202. package/dist/sync/watcher.js +11 -4
  203. package/dist/web/index.html +1 -1
  204. package/dist/web/{main-6XYO5FZC.js → main-OUUQYNK4.js} +75 -74
  205. package/native/csharp/HcsHost/AssemblyInfo.cs +3 -3
  206. package/native/csharp/HostTools/AssemblyInfo.cs +3 -3
  207. package/native/csharp/HostTools/Program.cs +19 -2
  208. package/native/csharp/HostTools/UserPath.cs +17 -0
  209. package/native/csharp/StorageHelper/AssemblyInfo.cs +3 -3
  210. package/native/scripts/edit-user-path.ps1 +6 -2
  211. package/native/scripts/stop-events.ps1 +7 -3
  212. package/package.json +1 -1
  213. package/sandbox/scripts/get-signature.ps1 +13 -0
  214. package/schemas/config.schema.json +64 -0
  215. package/schemas/sandbox-config.schema.json +8 -0
  216. 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';
@@ -26,6 +26,18 @@ export declare const OPERATIONS: readonly [OperationDef<import("zod").ZodObject<
26
26
  stopped: import("zod").ZodBoolean;
27
27
  message: import("zod").ZodString;
28
28
  }, import("zod/v4/core").$strip>, "sandbox.stop">, OperationDef<import("zod").ZodObject<{
29
+ service: import("zod").ZodOptional<import("zod").ZodBoolean>;
30
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
31
+ outcome: import("zod").ZodEnum<{
32
+ failed: "failed";
33
+ nothing: "nothing";
34
+ alive: "alive";
35
+ declined: "declined";
36
+ cleaned: "cleaned";
37
+ "service-restarted": "service-restarted";
38
+ }>;
39
+ message: import("zod").ZodString;
40
+ }, import("zod/v4/core").$strip>, "sandbox.cleanUp">, OperationDef<import("zod").ZodObject<{
29
41
  harness: import("zod").ZodOptional<import("zod").ZodString>;
30
42
  all: import("zod").ZodDefault<import("zod").ZodBoolean>;
31
43
  }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
@@ -64,6 +76,12 @@ export declare const OPERATIONS: readonly [OperationDef<import("zod").ZodObject<
64
76
  }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
65
77
  message: import("zod").ZodString;
66
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<{
67
85
  scope: import("zod").ZodDefault<import("zod").ZodEnum<{
68
86
  project: "project";
69
87
  user: "user";
@@ -273,6 +291,14 @@ export declare const OPERATIONS: readonly [OperationDef<import("zod").ZodObject<
273
291
  deleted: import("zod").ZodBoolean;
274
292
  message: import("zod").ZodString;
275
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<{
276
302
  message: import("zod").ZodString;
277
303
  }, import("zod/v4/core").$strip>, "github.login">, OperationDef<import("zod").ZodObject<{}, import("zod/v4/core").$strict>, import("zod").ZodObject<{
278
304
  deleted: import("zod").ZodBoolean;
@@ -378,6 +404,9 @@ export declare const QUERIES: readonly [QueryDef<import("zod").ZodObject<{}, imp
378
404
  text: import("zod").ZodString;
379
405
  at: import("zod").ZodString;
380
406
  }, import("zod/v4/core").$strip>>;
407
+ leftover: import("zod").ZodOptional<import("zod").ZodObject<{
408
+ text: import("zod").ZodString;
409
+ }, import("zod/v4/core").$strip>>;
381
410
  }, import("zod/v4/core").$strip>, "sandbox.status">, QueryDef<import("zod").ZodObject<{
382
411
  wide: import("zod").ZodDefault<import("zod").ZodBoolean>;
383
412
  }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
@@ -423,7 +452,43 @@ export declare const QUERIES: readonly [QueryDef<import("zod").ZodObject<{}, imp
423
452
  isDefault: import("zod").ZodBoolean;
424
453
  removable: import("zod").ZodBoolean;
425
454
  }, import("zod/v4/core").$strip>>;
455
+ subagents: import("zod").ZodOptional<import("zod").ZodNullable<import("zod").ZodNumber>>;
426
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<{
427
492
  scope: import("zod").ZodDefault<import("zod").ZodEnum<{
428
493
  project: "project";
429
494
  user: "user";
@@ -521,6 +586,7 @@ export declare const QUERIES: readonly [QueryDef<import("zod").ZodObject<{}, imp
521
586
  canImport: import("zod").ZodBoolean;
522
587
  canLogin: import("zod").ZodBoolean;
523
588
  needsFile: import("zod").ZodBoolean;
589
+ ready: import("zod").ZodBoolean;
524
590
  }, import("zod/v4/core").$strip>>;
525
591
  }, import("zod/v4/core").$strip>, "accounts.list">, QueryDef<import("zod").ZodObject<{
526
592
  scope: import("zod").ZodDefault<import("zod").ZodEnum<{
@@ -926,7 +992,26 @@ export declare const QUERIES: readonly [QueryDef<import("zod").ZodObject<{}, imp
926
992
  }>;
927
993
  text: import("zod").ZodString;
928
994
  }, import("zod/v4/core").$strip>>;
929
- }, 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<{
930
1015
  shareToken: import("zod").ZodBoolean;
931
1016
  gitAccess: import("zod").ZodEnum<{
932
1017
  readonly: "readonly";
@@ -964,6 +1049,7 @@ export declare const QUERIES: readonly [QueryDef<import("zod").ZodObject<{}, imp
964
1049
  canImport: import("zod").ZodBoolean;
965
1050
  canLogin: import("zod").ZodBoolean;
966
1051
  needsFile: import("zod").ZodBoolean;
1052
+ ready: import("zod").ZodBoolean;
967
1053
  }, import("zod/v4/core").$strip>>;
968
1054
  }, import("zod/v4/core").$strip>, "accounts.services">, QueryDef<import("zod").ZodObject<{}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
969
1055
  lan: import("zod").ZodObject<{
@@ -1072,6 +1158,9 @@ export declare const VIEWS: readonly [import("../kernel/define.js").ViewDef<{
1072
1158
  text: import("zod").ZodString;
1073
1159
  at: import("zod").ZodString;
1074
1160
  }, import("zod/v4/core").$strip>>;
1161
+ leftover: import("zod").ZodOptional<import("zod").ZodObject<{
1162
+ text: import("zod").ZodString;
1163
+ }, import("zod/v4/core").$strip>>;
1075
1164
  }, import("zod/v4/core").$strip>, "sandbox.status">;
1076
1165
  }, Record<string, never>, "sandbox">, import("../kernel/define.js").ViewDef<{
1077
1166
  sessions: QueryDef<import("zod").ZodObject<{
@@ -1121,8 +1210,55 @@ export declare const VIEWS: readonly [import("../kernel/define.js").ViewDef<{
1121
1210
  isDefault: import("zod").ZodBoolean;
1122
1211
  removable: import("zod").ZodBoolean;
1123
1212
  }, import("zod/v4/core").$strip>>;
1213
+ subagents: import("zod").ZodOptional<import("zod").ZodNullable<import("zod").ZodNumber>>;
1124
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">;
1125
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<{
1126
1262
  settings: QueryDef<import("zod").ZodObject<{
1127
1263
  scope: import("zod").ZodDefault<import("zod").ZodEnum<{
1128
1264
  project: "project";
@@ -1201,6 +1337,7 @@ export declare const VIEWS: readonly [import("../kernel/define.js").ViewDef<{
1201
1337
  canImport: import("zod").ZodBoolean;
1202
1338
  canLogin: import("zod").ZodBoolean;
1203
1339
  needsFile: import("zod").ZodBoolean;
1340
+ ready: import("zod").ZodBoolean;
1204
1341
  }, import("zod/v4/core").$strip>>;
1205
1342
  }, import("zod/v4/core").$strip>, "accounts.list">;
1206
1343
  services: QueryDef<import("zod").ZodObject<{
@@ -1224,6 +1361,7 @@ export declare const VIEWS: readonly [import("../kernel/define.js").ViewDef<{
1224
1361
  canImport: import("zod").ZodBoolean;
1225
1362
  canLogin: import("zod").ZodBoolean;
1226
1363
  needsFile: import("zod").ZodBoolean;
1364
+ ready: import("zod").ZodBoolean;
1227
1365
  }, import("zod/v4/core").$strip>>;
1228
1366
  }, import("zod/v4/core").$strip>, "accounts.services">;
1229
1367
  }, Record<string, never>, "accounts">, import("../kernel/define.js").ViewDef<{
@@ -1631,6 +1769,17 @@ export declare const VIEWS: readonly [import("../kernel/define.js").ViewDef<{
1631
1769
  }>;
1632
1770
  text: import("zod").ZodString;
1633
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>>;
1634
1783
  }, import("zod/v4/core").$strip>, "vpn.status">;
1635
1784
  }, Record<string, never>, "vpn">, import("../kernel/define.js").ViewDef<{
1636
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';
@@ -7,11 +8,12 @@ import { checkEngine, cleanEngine, engineLeftovers, engineStatus, engineView } f
7
8
  import { checkHealth, enableSandbox, healthView, lastHealth, repairHealth } from './health/health.def.js';
8
9
  import { cleanData, dataView, pruneStorage, showData } from './data/data.def.js';
9
10
  import { changeDataFolder, containedOff, containedOn, containedStatus, moveStorage, showStorage, storageView, useStorage, } from './storage/storage.def.js';
10
- import { hideWindow, sandboxStatus, sandboxView, showWindow, stopSandbox } from './sandbox/sandbox.def.js';
11
+ import { cleanUpSandbox, hideWindow, sandboxStatus, sandboxView, showWindow, stopSandbox, } from './sandbox/sandbox.def.js';
11
12
  import { addProject, allProjects, chooseProjects, excludeProject, includeProject, listProjects, projectRoots, projectsView, removeProject, } from './projects/projects.def.js';
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';
@@ -23,6 +25,7 @@ export const OPERATIONS = [
23
25
  showWindow,
24
26
  hideWindow,
25
27
  stopSandbox,
28
+ cleanUpSandbox,
26
29
  restartSessions,
27
30
  startShell,
28
31
  closeSession,
@@ -30,6 +33,7 @@ export const OPERATIONS = [
30
33
  addAgent,
31
34
  makeDefaultAgent,
32
35
  removeAgent,
36
+ agentsEnvSet,
33
37
  setSetting,
34
38
  resetSetting,
35
39
  exportConfig,
@@ -66,6 +70,8 @@ export const OPERATIONS = [
66
70
  stopWeb,
67
71
  vpnLogin,
68
72
  vpnLogout,
73
+ agentCommandsOn,
74
+ agentCommandsOff,
69
75
  githubLogin,
70
76
  githubLogout,
71
77
  serviceImport,
@@ -81,6 +87,7 @@ export const QUERIES = [
81
87
  sandboxStatus,
82
88
  listSessions,
83
89
  listAgents,
90
+ agentEnv,
84
91
  listSettings,
85
92
  getSetting,
86
93
  browseFolder,
@@ -100,6 +107,7 @@ export const QUERIES = [
100
107
  engineLeftovers,
101
108
  webStatus,
102
109
  vpnStatus,
110
+ agentCommandsStatus,
103
111
  githubStatus,
104
112
  listServices,
105
113
  accessStatus,
@@ -108,6 +116,7 @@ export const VIEWS = [
108
116
  sandboxView,
109
117
  sessionsView,
110
118
  agentsView,
119
+ agentEnvView,
111
120
  settingsView,
112
121
  accountsView,
113
122
  appsView,
@@ -158,6 +167,7 @@ export const NAV = [
158
167
  label: 'Workspace',
159
168
  children: [
160
169
  { label: 'Agents', view: 'agents' },
170
+ { label: 'Claude environment', view: 'agentEnv' },
161
171
  { label: 'Sessions', view: 'sessions' },
162
172
  { label: 'Activity', view: 'audit' },
163
173
  ],
@@ -61,6 +61,9 @@ export declare const SandboxStatusSchema: z.ZodObject<{
61
61
  text: z.ZodString;
62
62
  at: z.ZodString;
63
63
  }, z.core.$strip>>;
64
+ leftover: z.ZodOptional<z.ZodObject<{
65
+ text: z.ZodString;
66
+ }, z.core.$strip>>;
64
67
  }, z.core.$strip>;
65
68
  export type SandboxStatus = z.output<typeof SandboxStatusSchema>;
66
69
  /** "pong (2 session(s) running)" from the helper in the sandbox, in plain words. */
@@ -126,6 +129,9 @@ export declare const sandboxStatus: import("../../kernel/define.js").QueryDef<z.
126
129
  text: z.ZodString;
127
130
  at: z.ZodString;
128
131
  }, z.core.$strip>>;
132
+ leftover: z.ZodOptional<z.ZodObject<{
133
+ text: z.ZodString;
134
+ }, z.core.$strip>>;
129
135
  }, z.core.$strip>, "sandbox.status">;
130
136
  export declare const showWindow: import("../../kernel/define.js").OperationDef<z.ZodObject<{}, z.core.$strip>, z.ZodObject<{
131
137
  message: z.ZodString;
@@ -133,6 +139,19 @@ export declare const showWindow: import("../../kernel/define.js").OperationDef<z
133
139
  export declare const hideWindow: import("../../kernel/define.js").OperationDef<z.ZodObject<{}, z.core.$strip>, z.ZodObject<{
134
140
  message: z.ZodString;
135
141
  }, z.core.$strip>, "sandbox.hideWindow">;
142
+ export declare const cleanUpSandbox: import("../../kernel/define.js").OperationDef<z.ZodObject<{
143
+ service: z.ZodOptional<z.ZodBoolean>;
144
+ }, z.core.$strip>, z.ZodObject<{
145
+ outcome: z.ZodEnum<{
146
+ failed: "failed";
147
+ nothing: "nothing";
148
+ alive: "alive";
149
+ declined: "declined";
150
+ cleaned: "cleaned";
151
+ "service-restarted": "service-restarted";
152
+ }>;
153
+ message: z.ZodString;
154
+ }, z.core.$strip>, "sandbox.cleanUp">;
136
155
  export declare const stopSandbox: import("../../kernel/define.js").OperationDef<z.ZodObject<{}, z.core.$strip>, z.ZodObject<{
137
156
  stopped: z.ZodBoolean;
138
157
  message: z.ZodString;
@@ -201,5 +220,8 @@ export declare const sandboxView: import("../../kernel/define.js").ViewDef<{
201
220
  text: z.ZodString;
202
221
  at: z.ZodString;
203
222
  }, z.core.$strip>>;
223
+ leftover: z.ZodOptional<z.ZodObject<{
224
+ text: z.ZodString;
225
+ }, z.core.$strip>>;
204
226
  }, z.core.$strip>, "sandbox.status">;
205
227
  }, Record<string, never>, "sandbox">;
@@ -44,6 +44,11 @@ export const SandboxStatusSchema = z.object({
44
44
  .object({ text: z.string().describe('What happened'), at: z.string().describe('When (ISO time)') })
45
45
  .optional()
46
46
  .describe('The last sandbox ended unexpectedly'),
47
+ /** Windows Sandbox programs left behind by a sandbox that is gone (Windows then refuses to start a new one). */
48
+ leftover: z
49
+ .object({ text: z.string().describe('What was found') })
50
+ .optional()
51
+ .describe('Windows Sandbox programs are left over from a sandbox that is gone'),
47
52
  });
48
53
  const MessageSchema = z.object({ message: z.string().describe('What happened') });
49
54
  /** "pong (2 session(s) running)" from the helper in the sandbox, in plain words. */
@@ -92,6 +97,7 @@ export const sandboxStatus = defineQuery({
92
97
  otherSessions: o.otherSessions,
93
98
  repoGuard: o.repoGuard,
94
99
  ...(o.lastEnd ? { lastEnd: o.lastEnd } : {}),
100
+ ...(o.leftover ? { leftover: o.leftover } : {}),
95
101
  };
96
102
  },
97
103
  },
@@ -116,6 +122,23 @@ export const hideWindow = defineOperation({
116
122
  text: (o) => o.message,
117
123
  cli: { name: 'hide', group: 'Sessions' },
118
124
  });
125
+ export const cleanUpSandbox = defineOperation({
126
+ id: 'sandbox.cleanUp',
127
+ title: 'Clean up Windows Sandbox…',
128
+ summary: 'close the Windows Sandbox programs a dead sandbox left behind, so a new one can start',
129
+ input: z.object({
130
+ service: z
131
+ .boolean()
132
+ .optional()
133
+ .describe('Also restart the Windows Sandbox service (Windows asks for administrator permission)'),
134
+ }),
135
+ output: z.object({
136
+ outcome: z.enum(['nothing', 'alive', 'declined', 'cleaned', 'service-restarted', 'failed']),
137
+ message: z.string(),
138
+ }),
139
+ text: (o) => o.message,
140
+ cli: { name: 'cleanup', group: 'Sessions' },
141
+ });
119
142
  export const stopSandbox = defineOperation({
120
143
  id: 'sandbox.stop',
121
144
  access: 'control',
@@ -175,6 +198,7 @@ function facts(o) {
175
198
  fact('sessions', 'Sessions', String(sessions)),
176
199
  ]
177
200
  : []),
201
+ ...(o.leftover ? [fact('leftover', 'Windows Sandbox', o.leftover.text, { tone: 'warn' })] : []),
178
202
  ...(o.lastEnd ? [fact('lastEnd', 'Last sandbox', o.lastEnd.text, { tone: 'warn' })] : []),
179
203
  fact('account', 'Account', s.account ?? 'none selected (sandbox account use)'),
180
204
  fact('sync', 'Background sync', s.syncWatcher ? 'on' : 'off'),
@@ -229,21 +253,24 @@ export function sandboxPage(o) {
229
253
  title: 'Status',
230
254
  facts: facts(o),
231
255
  // Only the window action that changes something: show a hidden window, hide a shown one.
232
- actions: running
233
- ? [
234
- o.sandbox.headless
235
- ? action(showWindow, {}, { key: 'w', verb: 'show', importance: 3 })
236
- : action(hideWindow, {}, { key: 'h', verb: 'hide', importance: 3 }),
237
- action(stopSandbox, {}, { key: 'x', verb: 'stop', importance: 1 }),
238
- ]
239
- : o.lastEnd
256
+ actions: [
257
+ ...(o.leftover ? [action(cleanUpSandbox, {}, { key: 'c', verb: 'clean up', importance: 1 })] : []),
258
+ ...(running
240
259
  ? [
241
- link({ kind: 'view', view: 'logs', params: { name: CRASH } }, 'Show crash report', {
242
- verb: 'show',
243
- importance: 2,
244
- }),
260
+ o.sandbox.headless
261
+ ? action(showWindow, {}, { key: 'w', verb: 'show', importance: 3 })
262
+ : action(hideWindow, {}, { key: 'h', verb: 'hide', importance: 3 }),
263
+ action(stopSandbox, {}, { key: 'x', verb: 'stop', importance: 1 }),
245
264
  ]
246
- : [],
265
+ : o.lastEnd
266
+ ? [
267
+ link({ kind: 'view', view: 'logs', params: { name: CRASH } }, 'Show crash report', {
268
+ verb: 'show',
269
+ importance: 2,
270
+ }),
271
+ ]
272
+ : []),
273
+ ],
247
274
  };
248
275
  const others = {
249
276
  id: 'other-sessions',
@@ -270,6 +297,6 @@ export const sandboxView = defineView({
270
297
  title: 'Sandbox',
271
298
  summary: 'Status, projects and controls of the running sandbox.',
272
299
  queries: { status: sandboxStatus },
273
- operations: [showWindow, hideWindow, stopSandbox],
300
+ operations: [showWindow, hideWindow, stopSandbox, cleanUpSandbox],
274
301
  build: ({ status }) => sandboxPage(status),
275
302
  });
@@ -59,6 +59,9 @@ export declare const sandboxStatusRun: import("../../kernel/define.js").Implemen
59
59
  text: import("zod").ZodString;
60
60
  at: import("zod").ZodString;
61
61
  }, import("zod/v4/core").$strip>>;
62
+ leftover: import("zod").ZodOptional<import("zod").ZodObject<{
63
+ text: import("zod").ZodString;
64
+ }, import("zod/v4/core").$strip>>;
62
65
  }, import("zod/v4/core").$strip>, "sandbox.status">, import("../../../cli/commands/context.js").Context>;
63
66
  export declare const showWindowRun: import("../../kernel/define.js").Implementation<import("../../kernel/define.js").OperationDef<import("zod").ZodObject<{}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
64
67
  message: import("zod").ZodString;
@@ -66,6 +69,23 @@ export declare const showWindowRun: import("../../kernel/define.js").Implementat
66
69
  export declare const hideWindowRun: import("../../kernel/define.js").Implementation<import("../../kernel/define.js").OperationDef<import("zod").ZodObject<{}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
67
70
  message: import("zod").ZodString;
68
71
  }, import("zod/v4/core").$strip>, "sandbox.hideWindow">, import("../../../cli/commands/context.js").Context>;
72
+ /**
73
+ * A dead sandbox leaves Windows Sandbox programs behind and Windows then refuses to start a new one ("signed out"):
74
+ * ends them after asking, and restarts the Windows Sandbox service when asked to (or when they will not go).
75
+ */
76
+ export declare const cleanUpSandboxRun: import("../../kernel/define.js").Implementation<import("../../kernel/define.js").OperationDef<import("zod").ZodObject<{
77
+ service: import("zod").ZodOptional<import("zod").ZodBoolean>;
78
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
79
+ outcome: import("zod").ZodEnum<{
80
+ failed: "failed";
81
+ nothing: "nothing";
82
+ alive: "alive";
83
+ declined: "declined";
84
+ cleaned: "cleaned";
85
+ "service-restarted": "service-restarted";
86
+ }>;
87
+ message: import("zod").ZodString;
88
+ }, import("zod/v4/core").$strip>, "sandbox.cleanUp">, import("../../../cli/commands/context.js").Context>;
69
89
  /**
70
90
  * Stopping ends every project's sessions: it says which, and the sessions of other projects need a yes (also on the
71
91
  * command line, where --yes gives it; a script without it fails rather than end them by accident).