windows-development-sandbox 1.18.2 → 1.18.4
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.
- package/config.example.json +1 -1
- package/dist/app/features/defs.d.ts +26 -0
- package/dist/app/features/defs.js +2 -1
- package/dist/app/features/sandbox/sandbox.def.d.ts +34 -0
- package/dist/app/features/sandbox/sandbox.def.js +52 -10
- package/dist/app/features/sandbox/sandbox.run.d.ts +24 -0
- package/dist/app/features/sandbox/sandbox.run.js +45 -1
- package/dist/app/registry.js +2 -1
- package/dist/bin/agent-sandbox.js +2 -2
- package/dist/bin/{chunk-MQIA7GNB.js → chunk-FRPLQLSY.js} +3188 -2765
- package/dist/bin/{chunk-M4OM632I.js → chunk-MY7NLQQY.js} +1 -1
- package/dist/bin/{chunk-IIHL7W6B.js → chunk-N4GXYTLV.js} +1 -1
- package/dist/bin/claude-host.js +2 -2
- package/dist/bin/claude-sbx.js +2 -2
- package/dist/bin/codex-sbx.js +2 -2
- package/dist/bin/gemini-sbx.js +2 -2
- package/dist/bin/sandbox.js +2 -2
- package/dist/bin/sbx-hide.js +2 -2
- package/dist/bin/sbx-show.js +2 -2
- package/dist/cli/commands/launch/launch.js +4 -1
- package/dist/cli/commands/launch/leftover-offer.d.ts +3 -0
- package/dist/cli/commands/launch/leftover-offer.js +26 -0
- package/dist/cli/commands/repair/checks/sandbox.d.ts +3 -1
- package/dist/cli/commands/repair/checks/sandbox.js +53 -2
- package/dist/core/config/defaults.js +1 -1
- package/dist/core/schema/sandbox.js +1 -1
- package/dist/core/schema/toolchains.js +2 -2
- package/dist/guest/daemon/daemon.js +1 -1
- package/dist/guest/daemon/heartbeat.d.ts +11 -0
- package/dist/guest/daemon/heartbeat.js +59 -0
- package/dist/guest/daemon/idle-shutdown.js +2 -0
- package/dist/guest/entries/daemon.js +2 -0
- package/dist/guest/governor/core.d.ts +19 -1
- package/dist/guest/governor/core.js +23 -1
- package/dist/guest/governor/decide.d.ts +14 -0
- package/dist/guest/governor/decide.js +52 -7
- package/dist/guest/governor/governor.d.ts +4 -1
- package/dist/guest/governor/governor.js +9 -2
- package/dist/guest/toolchains/native/rust-extras.d.ts +7 -0
- package/dist/guest/toolchains/native/rust-extras.js +26 -3
- package/dist/guest/toolchains/plan.js +6 -4
- package/dist/host/channel/channel.d.ts +1 -1
- package/dist/host/channel/channel.js +10 -2
- package/dist/host/health/index.d.ts +1 -0
- package/dist/host/health/index.js +1 -0
- package/dist/host/health/leftovers.d.ts +3 -0
- package/dist/host/health/leftovers.js +40 -0
- package/dist/host/health/stale.d.ts +48 -0
- package/dist/host/health/stale.js +40 -0
- package/dist/host/launch/wsb-file.d.ts +6 -1
- package/dist/host/launch/wsb-file.js +9 -5
- package/dist/host/life/crash-report.d.ts +3 -1
- package/dist/host/life/crash-report.js +9 -3
- package/dist/host/life/index.d.ts +1 -0
- package/dist/host/life/index.js +1 -0
- package/dist/host/life/last-end.d.ts +28 -0
- package/dist/host/life/last-end.js +91 -0
- package/dist/host/life/life-record.d.ts +3 -0
- package/dist/host/life/life-record.js +2 -2
- package/dist/host/life/stop-events.d.ts +3 -1
- package/dist/host/life/stop-events.js +59 -0
- package/dist/host/life/stop-warning.js +3 -0
- package/dist/host/life/watchdog.d.ts +2 -0
- package/dist/host/life/watchdog.js +8 -2
- package/dist/host/sandbox/cleanup.d.ts +37 -0
- package/dist/host/sandbox/cleanup.js +82 -0
- package/dist/host/sandbox/index.d.ts +1 -0
- package/dist/host/sandbox/index.js +1 -0
- package/dist/host/sandbox/platform.js +1 -1
- package/dist/runtime/agent.js +28 -3
- package/dist/runtime/daemon.js +629 -479
- package/dist/runtime/db.js +28 -3
- package/dist/runtime/main.js +59 -11
- package/dist/runtime/netproxy.js +28 -3
- package/dist/runtime/tool.js +28 -3
- package/dist/runtime/view.js +28 -3
- package/dist/selftest/heavy-load.test.js +212 -14
- package/dist/selftest/live-terminal.test.js +4 -0
- package/dist/shared/channel/run-dir.d.ts +4 -1
- package/dist/shared/channel/run-dir.js +7 -1
- package/dist/shared/channel/schema.d.ts +24 -0
- package/dist/shared/channel/schema.js +22 -0
- package/dist/shared/memory/policy.d.ts +10 -0
- package/dist/shared/memory/policy.js +17 -1
- package/dist/shared/system.d.ts +1 -0
- package/dist/shared/system.js +1 -0
- package/dist/sync/watcher.js +10 -5
- package/dist/web/index.html +1 -1
- package/dist/web/{main-CWIF4VQI.js → main-GVZWWP4I.js} +63 -63
- package/native/csharp/HcsHost/AssemblyInfo.cs +3 -3
- package/native/csharp/HostTools/AssemblyInfo.cs +3 -3
- package/native/csharp/HostTools/Program.cs +5 -1
- package/native/csharp/StorageHelper/AssemblyInfo.cs +3 -3
- package/native/scripts/stop-events.ps1 +7 -3
- package/package.json +1 -1
- package/sandbox/csharp/MemGov.cs +58 -0
- package/schemas/config.schema.json +3 -3
- package/schemas/sandbox-config.schema.json +3 -3
package/config.example.json
CHANGED
|
@@ -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<{
|
|
@@ -374,6 +386,13 @@ export declare const QUERIES: readonly [QueryDef<import("zod").ZodObject<{}, imp
|
|
|
374
386
|
guarded: import("zod").ZodNumber;
|
|
375
387
|
findings: import("zod").ZodArray<import("zod").ZodString>;
|
|
376
388
|
}, import("zod/v4/core").$strip>;
|
|
389
|
+
lastEnd: import("zod").ZodOptional<import("zod").ZodObject<{
|
|
390
|
+
text: import("zod").ZodString;
|
|
391
|
+
at: import("zod").ZodString;
|
|
392
|
+
}, import("zod/v4/core").$strip>>;
|
|
393
|
+
leftover: import("zod").ZodOptional<import("zod").ZodObject<{
|
|
394
|
+
text: import("zod").ZodString;
|
|
395
|
+
}, import("zod/v4/core").$strip>>;
|
|
377
396
|
}, import("zod/v4/core").$strip>, "sandbox.status">, QueryDef<import("zod").ZodObject<{
|
|
378
397
|
wide: import("zod").ZodDefault<import("zod").ZodBoolean>;
|
|
379
398
|
}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
|
|
@@ -1064,6 +1083,13 @@ export declare const VIEWS: readonly [import("../kernel/define.js").ViewDef<{
|
|
|
1064
1083
|
guarded: import("zod").ZodNumber;
|
|
1065
1084
|
findings: import("zod").ZodArray<import("zod").ZodString>;
|
|
1066
1085
|
}, import("zod/v4/core").$strip>;
|
|
1086
|
+
lastEnd: import("zod").ZodOptional<import("zod").ZodObject<{
|
|
1087
|
+
text: import("zod").ZodString;
|
|
1088
|
+
at: import("zod").ZodString;
|
|
1089
|
+
}, import("zod/v4/core").$strip>>;
|
|
1090
|
+
leftover: import("zod").ZodOptional<import("zod").ZodObject<{
|
|
1091
|
+
text: import("zod").ZodString;
|
|
1092
|
+
}, import("zod/v4/core").$strip>>;
|
|
1067
1093
|
}, import("zod/v4/core").$strip>, "sandbox.status">;
|
|
1068
1094
|
}, Record<string, never>, "sandbox">, import("../kernel/define.js").ViewDef<{
|
|
1069
1095
|
sessions: QueryDef<import("zod").ZodObject<{
|
|
@@ -7,7 +7,7 @@ import { checkEngine, cleanEngine, engineLeftovers, engineStatus, engineView } f
|
|
|
7
7
|
import { checkHealth, enableSandbox, healthView, lastHealth, repairHealth } from './health/health.def.js';
|
|
8
8
|
import { cleanData, dataView, pruneStorage, showData } from './data/data.def.js';
|
|
9
9
|
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';
|
|
10
|
+
import { cleanUpSandbox, hideWindow, sandboxStatus, sandboxView, showWindow, stopSandbox, } from './sandbox/sandbox.def.js';
|
|
11
11
|
import { addProject, allProjects, chooseProjects, excludeProject, includeProject, listProjects, projectRoots, projectsView, removeProject, } from './projects/projects.def.js';
|
|
12
12
|
import { listLogs, logsView, tailLog } from './logs/logs.def.js';
|
|
13
13
|
import { auditView, listAudit } from './audit/audit.def.js';
|
|
@@ -23,6 +23,7 @@ export const OPERATIONS = [
|
|
|
23
23
|
showWindow,
|
|
24
24
|
hideWindow,
|
|
25
25
|
stopSandbox,
|
|
26
|
+
cleanUpSandbox,
|
|
26
27
|
restartSessions,
|
|
27
28
|
startShell,
|
|
28
29
|
closeSession,
|
|
@@ -57,6 +57,13 @@ export declare const SandboxStatusSchema: z.ZodObject<{
|
|
|
57
57
|
guarded: z.ZodNumber;
|
|
58
58
|
findings: z.ZodArray<z.ZodString>;
|
|
59
59
|
}, z.core.$strip>;
|
|
60
|
+
lastEnd: z.ZodOptional<z.ZodObject<{
|
|
61
|
+
text: z.ZodString;
|
|
62
|
+
at: z.ZodString;
|
|
63
|
+
}, z.core.$strip>>;
|
|
64
|
+
leftover: z.ZodOptional<z.ZodObject<{
|
|
65
|
+
text: z.ZodString;
|
|
66
|
+
}, z.core.$strip>>;
|
|
60
67
|
}, z.core.$strip>;
|
|
61
68
|
export type SandboxStatus = z.output<typeof SandboxStatusSchema>;
|
|
62
69
|
/** "pong (2 session(s) running)" from the helper in the sandbox, in plain words. */
|
|
@@ -118,6 +125,13 @@ export declare const sandboxStatus: import("../../kernel/define.js").QueryDef<z.
|
|
|
118
125
|
guarded: z.ZodNumber;
|
|
119
126
|
findings: z.ZodArray<z.ZodString>;
|
|
120
127
|
}, z.core.$strip>;
|
|
128
|
+
lastEnd: z.ZodOptional<z.ZodObject<{
|
|
129
|
+
text: z.ZodString;
|
|
130
|
+
at: z.ZodString;
|
|
131
|
+
}, z.core.$strip>>;
|
|
132
|
+
leftover: z.ZodOptional<z.ZodObject<{
|
|
133
|
+
text: z.ZodString;
|
|
134
|
+
}, z.core.$strip>>;
|
|
121
135
|
}, z.core.$strip>, "sandbox.status">;
|
|
122
136
|
export declare const showWindow: import("../../kernel/define.js").OperationDef<z.ZodObject<{}, z.core.$strip>, z.ZodObject<{
|
|
123
137
|
message: z.ZodString;
|
|
@@ -125,6 +139,19 @@ export declare const showWindow: import("../../kernel/define.js").OperationDef<z
|
|
|
125
139
|
export declare const hideWindow: import("../../kernel/define.js").OperationDef<z.ZodObject<{}, z.core.$strip>, z.ZodObject<{
|
|
126
140
|
message: z.ZodString;
|
|
127
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">;
|
|
128
155
|
export declare const stopSandbox: import("../../kernel/define.js").OperationDef<z.ZodObject<{}, z.core.$strip>, z.ZodObject<{
|
|
129
156
|
stopped: z.ZodBoolean;
|
|
130
157
|
message: z.ZodString;
|
|
@@ -189,5 +216,12 @@ export declare const sandboxView: import("../../kernel/define.js").ViewDef<{
|
|
|
189
216
|
guarded: z.ZodNumber;
|
|
190
217
|
findings: z.ZodArray<z.ZodString>;
|
|
191
218
|
}, z.core.$strip>;
|
|
219
|
+
lastEnd: z.ZodOptional<z.ZodObject<{
|
|
220
|
+
text: z.ZodString;
|
|
221
|
+
at: z.ZodString;
|
|
222
|
+
}, z.core.$strip>>;
|
|
223
|
+
leftover: z.ZodOptional<z.ZodObject<{
|
|
224
|
+
text: z.ZodString;
|
|
225
|
+
}, z.core.$strip>>;
|
|
192
226
|
}, z.core.$strip>, "sandbox.status">;
|
|
193
227
|
}, Record<string, never>, "sandbox">;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
// The running sandbox as a whole: what it is doing (a live query), its window, and stopping it. Pure: schemas, labels
|
|
2
2
|
// and the view; sandbox.run.ts does the work.
|
|
3
3
|
import { z } from 'zod';
|
|
4
|
-
import { action, ago, defineOperation, defineQuery, defineView, plural, } from '../../kernel/index.js';
|
|
4
|
+
import { action, ago, defineOperation, defineQuery, defineView, link, plural, } from '../../kernel/index.js';
|
|
5
|
+
import { CRASH } from '../logs/logs.def.js';
|
|
5
6
|
const ProjectSchema = z.object({
|
|
6
7
|
name: z.string().describe('The project'),
|
|
7
8
|
host: z.string().describe('Its folder on this PC'),
|
|
@@ -38,6 +39,16 @@ export const SandboxStatusSchema = z.object({
|
|
|
38
39
|
projects: z.array(ProjectSchema),
|
|
39
40
|
otherSessions: z.array(z.object({ id: z.string(), harness: z.string(), cwd: z.string() })),
|
|
40
41
|
repoGuard: z.object({ guarded: z.number(), findings: z.array(z.string()) }),
|
|
42
|
+
/** How the last sandbox ended when nobody closed it (it is not running now). */
|
|
43
|
+
lastEnd: z
|
|
44
|
+
.object({ text: z.string().describe('What happened'), at: z.string().describe('When (ISO time)') })
|
|
45
|
+
.optional()
|
|
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'),
|
|
41
52
|
});
|
|
42
53
|
const MessageSchema = z.object({ message: z.string().describe('What happened') });
|
|
43
54
|
/** "pong (2 session(s) running)" from the helper in the sandbox, in plain words. */
|
|
@@ -85,6 +96,8 @@ export const sandboxStatus = defineQuery({
|
|
|
85
96
|
projects: o.projects,
|
|
86
97
|
otherSessions: o.otherSessions,
|
|
87
98
|
repoGuard: o.repoGuard,
|
|
99
|
+
...(o.lastEnd ? { lastEnd: o.lastEnd } : {}),
|
|
100
|
+
...(o.leftover ? { leftover: o.leftover } : {}),
|
|
88
101
|
};
|
|
89
102
|
},
|
|
90
103
|
},
|
|
@@ -109,6 +122,23 @@ export const hideWindow = defineOperation({
|
|
|
109
122
|
text: (o) => o.message,
|
|
110
123
|
cli: { name: 'hide', group: 'Sessions' },
|
|
111
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
|
+
});
|
|
112
142
|
export const stopSandbox = defineOperation({
|
|
113
143
|
id: 'sandbox.stop',
|
|
114
144
|
access: 'control',
|
|
@@ -168,6 +198,8 @@ function facts(o) {
|
|
|
168
198
|
fact('sessions', 'Sessions', String(sessions)),
|
|
169
199
|
]
|
|
170
200
|
: []),
|
|
201
|
+
...(o.leftover ? [fact('leftover', 'Windows Sandbox', o.leftover.text, { tone: 'warn' })] : []),
|
|
202
|
+
...(o.lastEnd ? [fact('lastEnd', 'Last sandbox', o.lastEnd.text, { tone: 'warn' })] : []),
|
|
171
203
|
fact('account', 'Account', s.account ?? 'none selected (sandbox account use)'),
|
|
172
204
|
fact('sync', 'Background sync', s.syncWatcher ? 'on' : 'off'),
|
|
173
205
|
];
|
|
@@ -221,14 +253,24 @@ export function sandboxPage(o) {
|
|
|
221
253
|
title: 'Status',
|
|
222
254
|
facts: facts(o),
|
|
223
255
|
// Only the window action that changes something: show a hidden window, hide a shown one.
|
|
224
|
-
actions:
|
|
225
|
-
? [
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
256
|
+
actions: [
|
|
257
|
+
...(o.leftover ? [action(cleanUpSandbox, {}, { key: 'c', verb: 'clean up', importance: 1 })] : []),
|
|
258
|
+
...(running
|
|
259
|
+
? [
|
|
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 }),
|
|
264
|
+
]
|
|
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
|
+
],
|
|
232
274
|
};
|
|
233
275
|
const others = {
|
|
234
276
|
id: 'other-sessions',
|
|
@@ -255,6 +297,6 @@ export const sandboxView = defineView({
|
|
|
255
297
|
title: 'Sandbox',
|
|
256
298
|
summary: 'Status, projects and controls of the running sandbox.',
|
|
257
299
|
queries: { status: sandboxStatus },
|
|
258
|
-
operations: [showWindow, hideWindow, stopSandbox],
|
|
300
|
+
operations: [showWindow, hideWindow, stopSandbox, cleanUpSandbox],
|
|
259
301
|
build: ({ status }) => sandboxPage(status),
|
|
260
302
|
});
|
|
@@ -55,6 +55,13 @@ export declare const sandboxStatusRun: import("../../kernel/define.js").Implemen
|
|
|
55
55
|
guarded: import("zod").ZodNumber;
|
|
56
56
|
findings: import("zod").ZodArray<import("zod").ZodString>;
|
|
57
57
|
}, import("zod/v4/core").$strip>;
|
|
58
|
+
lastEnd: import("zod").ZodOptional<import("zod").ZodObject<{
|
|
59
|
+
text: import("zod").ZodString;
|
|
60
|
+
at: import("zod").ZodString;
|
|
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>>;
|
|
58
65
|
}, import("zod/v4/core").$strip>, "sandbox.status">, import("../../../cli/commands/context.js").Context>;
|
|
59
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<{
|
|
60
67
|
message: import("zod").ZodString;
|
|
@@ -62,6 +69,23 @@ export declare const showWindowRun: import("../../kernel/define.js").Implementat
|
|
|
62
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<{
|
|
63
70
|
message: import("zod").ZodString;
|
|
64
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>;
|
|
65
89
|
/**
|
|
66
90
|
* Stopping ends every project's sessions: it says which, and the sessions of other projects need a yes (also on the
|
|
67
91
|
* command line, where --yes gives it; a script without it fails rather than end them by accident).
|
|
@@ -3,6 +3,10 @@
|
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
import { safeText } from '../../../core/util/index.js';
|
|
5
5
|
import { SandboxChannel } from '../../../host/channel/index.js';
|
|
6
|
+
import { readSandboxFacts } from '../../../host/health/index.js';
|
|
7
|
+
import { LifeRecord, readLastEnd } from '../../../host/life/index.js';
|
|
8
|
+
import { cleanUpLeftovers, endSandboxPrograms, restartSandboxService } from '../../../host/sandbox/index.js';
|
|
9
|
+
import { judgeSandbox } from '../../../host/health/index.js';
|
|
6
10
|
import { runningOwner } from '../../../host/sharing/index.js';
|
|
7
11
|
import { requireOnPc, requireRunning } from '../../../cli/commands/context.js';
|
|
8
12
|
import { hereDir } from '../../../cli/commands/projects/here.js';
|
|
@@ -10,7 +14,7 @@ import { lookAtSandbox, useSharedSandbox } from '../../../cli/commands/shared-us
|
|
|
10
14
|
import { SandboxService } from '../../../cli/services/index.js';
|
|
11
15
|
import { implement, typedConfirm } from '../../context.js';
|
|
12
16
|
import { cancelled } from '../../kernel/index.js';
|
|
13
|
-
import { hideWindow, sandboxStatus, showWindow, stopSandbox } from './sandbox.def.js';
|
|
17
|
+
import { cleanUpSandbox, hideWindow, sandboxStatus, showWindow, stopSandbox, } from './sandbox.def.js';
|
|
14
18
|
/** Another user's sandbox that is not shared: whose it is, and nothing else. */
|
|
15
19
|
function limitedStatus(view, folder) {
|
|
16
20
|
const owner = view.owner;
|
|
@@ -36,7 +40,12 @@ export const sandboxStatusRun = implement(sandboxStatus, async (asked) => {
|
|
|
36
40
|
if (view.limited)
|
|
37
41
|
return limitedStatus(view, hereDir(asked));
|
|
38
42
|
const report = await new SandboxService(view.ctx).status();
|
|
43
|
+
const { storageRoot, dataPath } = view.ctx;
|
|
44
|
+
const lastEnd = readLastEnd(() => new LifeRecord(storageRoot, dataPath).read(), dataPath, report.sandbox.running);
|
|
45
|
+
const leftover = report.sandbox.running ? judgeSandbox(await readSandboxFacts(storageRoot, dataPath, false)) : null;
|
|
39
46
|
return {
|
|
47
|
+
...(lastEnd ? { lastEnd } : {}),
|
|
48
|
+
...(leftover?.state === 'leftover' ? { leftover: { text: leftover.why } } : {}),
|
|
40
49
|
...(view.line ? { shared: { line: view.line, limited: false, startedBy: view.ctx.borrowed?.user ?? null } } : {}),
|
|
41
50
|
...report,
|
|
42
51
|
sandbox: { ...report.sandbox, daemon: safeText(report.sandbox.daemon) },
|
|
@@ -57,6 +66,41 @@ export const hideWindowRun = implement(hideWindow, async (ctx, _input, io) => {
|
|
|
57
66
|
await new SandboxService(ctx).hideWindow();
|
|
58
67
|
return { message: 'Sandbox window hidden. Bring it back with: sbx-show' };
|
|
59
68
|
});
|
|
69
|
+
/**
|
|
70
|
+
* A dead sandbox leaves Windows Sandbox programs behind and Windows then refuses to start a new one ("signed out"):
|
|
71
|
+
* ends them after asking, and restarts the Windows Sandbox service when asked to (or when they will not go).
|
|
72
|
+
*/
|
|
73
|
+
export const cleanUpSandboxRun = implement(cleanUpSandbox, async (ctx, input, io) => {
|
|
74
|
+
requireOnPc('cleanup');
|
|
75
|
+
const { storageRoot, dataPath } = ctx;
|
|
76
|
+
const lines = [];
|
|
77
|
+
const outcome = await cleanUpLeftovers({
|
|
78
|
+
facts: () => readSandboxFacts(storageRoot, dataPath, true),
|
|
79
|
+
end: endSandboxPrograms,
|
|
80
|
+
restartService: restartSandboxService,
|
|
81
|
+
confirm: (q) => io.confirm({
|
|
82
|
+
...q,
|
|
83
|
+
danger: true,
|
|
84
|
+
noTerminal: { message: 'Nothing was closed.', fix: 'Add --yes to answer yes.' },
|
|
85
|
+
}),
|
|
86
|
+
say: (line) => {
|
|
87
|
+
lines.push(line);
|
|
88
|
+
io.log(line);
|
|
89
|
+
},
|
|
90
|
+
alsoService: input.service === true,
|
|
91
|
+
});
|
|
92
|
+
if (outcome === 'cleaned' || outcome === 'service-restarted')
|
|
93
|
+
new SandboxChannel(dataPath, () => false).reset();
|
|
94
|
+
const message = {
|
|
95
|
+
nothing: 'No Windows Sandbox program is left over.',
|
|
96
|
+
alive: lines[lines.length - 1] ?? 'A sandbox is working; nothing was closed.',
|
|
97
|
+
declined: 'Nothing was closed.',
|
|
98
|
+
cleaned: 'The leftover Windows Sandbox programs are closed. A new sandbox can start now.',
|
|
99
|
+
'service-restarted': 'The Windows Sandbox service was restarted. A new sandbox can start now.',
|
|
100
|
+
failed: 'The Windows Sandbox service could not be restarted.',
|
|
101
|
+
}[outcome];
|
|
102
|
+
return { outcome, message };
|
|
103
|
+
});
|
|
60
104
|
/**
|
|
61
105
|
* Stopping ends every project's sessions: it says which, and the sessions of other projects need a yes (also on the
|
|
62
106
|
* command line, where --yes gives it; a script without it fails rather than end them by accident).
|
package/dist/app/registry.js
CHANGED
|
@@ -8,7 +8,7 @@ import { cleanDataRun, pruneStorageRun, showDataRun } from './features/data/inde
|
|
|
8
8
|
import { changeDataFolderRun, containedOffRun, containedOnRun, containedStatusRun, moveStorageRun, showStorageRun, useStorageRun, } from './features/storage/index.js';
|
|
9
9
|
import { addProjectRun, allProjectsRun, chooseProjectsRun, excludeProjectRun, includeProjectRun, listProjectsRun, projectRootsRun, removeProjectRun, } from './features/projects/index.js';
|
|
10
10
|
import { checkHealthRun, enableSandboxRun, lastHealthRun, repairHealthRun } from './features/health/index.js';
|
|
11
|
-
import { hideWindowRun, sandboxStatusRun, showWindowRun, stopSandboxRun } from './features/sandbox/index.js';
|
|
11
|
+
import { cleanUpSandboxRun, hideWindowRun, sandboxStatusRun, showWindowRun, stopSandboxRun, } from './features/sandbox/index.js';
|
|
12
12
|
import { listLogsRun, tailLogRun } from './features/logs/index.js';
|
|
13
13
|
import { listAuditRun } from './features/audit/index.js';
|
|
14
14
|
import { closeSessionRun, listSessionsRun, restartSessionsRun, startShellRun } from './features/sessions/index.js';
|
|
@@ -24,6 +24,7 @@ export const IMPLEMENTATIONS = [
|
|
|
24
24
|
showWindowRun,
|
|
25
25
|
hideWindowRun,
|
|
26
26
|
stopSandboxRun,
|
|
27
|
+
cleanUpSandboxRun,
|
|
27
28
|
listSessionsRun,
|
|
28
29
|
restartSessionsRun,
|
|
29
30
|
startShellRun,
|
|
@@ -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-
|
|
6
|
-
import "./chunk-
|
|
5
|
+
} from "./chunk-N4GXYTLV.js";
|
|
6
|
+
import "./chunk-FRPLQLSY.js";
|
|
7
7
|
|
|
8
8
|
// src/bin/agent-sandbox.ts
|
|
9
9
|
run(process.argv.slice(2));
|