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.
- package/README.md +1 -1
- package/config.example.json +9 -0
- package/dist/app/features/accounts/accounts.def.d.ts +4 -0
- package/dist/app/features/accounts/accounts.run.d.ts +1 -0
- package/dist/app/features/accounts/services.def.d.ts +3 -0
- package/dist/app/features/accounts/services.def.js +4 -2
- package/dist/app/features/accounts/services.run.d.ts +1 -0
- package/dist/app/features/accounts/services.run.js +3 -1
- package/dist/app/features/agent-commands/agent-commands.def.d.ts +37 -0
- package/dist/app/features/agent-commands/agent-commands.def.js +91 -0
- package/dist/app/features/agent-commands/agent-commands.run.d.ts +28 -0
- package/dist/app/features/agent-commands/agent-commands.run.js +35 -0
- package/dist/app/features/agent-commands/index.d.ts +2 -0
- package/dist/app/features/agent-commands/index.js +3 -0
- package/dist/app/features/agents/agents.def.d.ts +14 -1
- package/dist/app/features/agents/agents.def.js +61 -6
- package/dist/app/features/agents/agents.run.d.ts +1 -0
- package/dist/app/features/agents/agents.run.js +8 -1
- package/dist/app/features/agents/claude-env.def.d.ts +36 -0
- package/dist/app/features/agents/claude-env.def.js +305 -0
- package/dist/app/features/agents/env.def.d.ts +163 -0
- package/dist/app/features/agents/env.def.js +184 -0
- package/dist/app/features/agents/env.run.d.ts +43 -0
- package/dist/app/features/agents/env.run.js +86 -0
- package/dist/app/features/agents/index.d.ts +2 -0
- package/dist/app/features/agents/index.js +2 -0
- package/dist/app/features/defs.d.ts +150 -1
- package/dist/app/features/defs.js +11 -1
- package/dist/app/features/sandbox/sandbox.def.d.ts +22 -0
- package/dist/app/features/sandbox/sandbox.def.js +41 -14
- package/dist/app/features/sandbox/sandbox.run.d.ts +20 -0
- package/dist/app/features/sandbox/sandbox.run.js +41 -1
- package/dist/app/features/settings/categories.def.js +5 -2
- package/dist/app/features/settings/settings-rows.js +5 -1
- package/dist/app/features/settings/settings.run.d.ts +8 -0
- package/dist/app/features/settings/settings.run.js +9 -0
- package/dist/app/features/updates/updates.run.js +12 -2
- package/dist/app/features/vpn/vpn.def.d.ts +33 -0
- package/dist/app/features/vpn/vpn.def.js +30 -6
- package/dist/app/features/vpn/vpn.run.d.ts +11 -0
- package/dist/app/features/vpn/vpn.run.js +4 -1
- package/dist/app/kernel/rpc.d.ts +1 -1
- package/dist/app/registry.js +9 -2
- package/dist/bin/agent-sandbox.js +2 -2
- package/dist/bin/{chunk-M6XUQK53.js → chunk-2IMT7ZCT.js} +1 -1
- package/dist/bin/{chunk-3G53NNZP.js → chunk-DK4NTBUF.js} +69 -26
- package/dist/bin/{chunk-FQWYCF6L.js → chunk-Z2P5OGKL.js} +6427 -5259
- 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/agent-commands.d.ts +0 -1
- package/dist/cli/commands/agent-commands.js +2 -32
- package/dist/cli/commands/index.d.ts +1 -1
- package/dist/cli/commands/index.js +1 -1
- package/dist/cli/commands/launch/launch.js +6 -3
- 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/registry.js +3 -2
- package/dist/cli/commands/repair/checks/sandbox.js +29 -2
- package/dist/cli/manifest.d.ts +1 -1
- package/dist/cli/manifest.js +1 -1
- package/dist/cli/menu/menu.d.ts +1 -1
- package/dist/cli/menu/menu.js +3 -3
- package/dist/cli/menu/pages/agents-page.d.ts +7 -2
- package/dist/cli/menu/pages/agents-page.js +67 -11
- package/dist/cli/menu/pages/maintenance-page.js +1 -2
- package/dist/cli/menu/pages/settings-page.js +1 -0
- package/dist/cli/menu/views.js +2 -1
- package/dist/cli/services/agent-commands-service.d.ts +2 -0
- package/dist/cli/services/agent-commands-service.js +13 -7
- package/dist/cli/services/vpn-service.d.ts +5 -1
- package/dist/cli/services/vpn-service.js +6 -1
- package/dist/cli/tui/dialogs/text-screen.js +2 -1
- package/dist/cli/tui/terminal.js +3 -1
- package/dist/core/config/defaults.js +9 -0
- package/dist/core/detect/toolchains.js +9 -0
- package/dist/core/disk.d.ts +1 -5
- package/dist/core/disk.js +1 -16
- package/dist/core/schema/codex.d.ts +29 -0
- package/dist/core/schema/codex.js +24 -0
- package/dist/core/schema/config.d.ts +46 -14
- package/dist/core/schema/config.js +2 -0
- package/dist/core/schema/index.d.ts +1 -0
- package/dist/core/schema/index.js +1 -0
- package/dist/core/schema/toolchains.d.ts +4 -0
- package/dist/core/schema/toolchains.js +3 -0
- package/dist/core/types.d.ts +2 -0
- package/dist/guest/accounts/apply.d.ts +6 -6
- package/dist/guest/agents/agent-files.d.ts +26 -6
- package/dist/guest/agents/agent-files.js +84 -14
- package/dist/guest/agents/local-state.d.ts +5 -2
- package/dist/guest/agents/local-state.js +24 -10
- package/dist/guest/boot/boot.js +10 -5
- package/dist/guest/daemon/heartbeat.d.ts +7 -2
- package/dist/guest/daemon/heartbeat.js +34 -15
- package/dist/guest/daemon/idle-shutdown.js +2 -0
- package/dist/guest/daemon/sessions.js +2 -1
- package/dist/guest/entries/daemon.js +1 -1
- package/dist/guest/toolchains/installers.d.ts +6 -10
- package/dist/guest/toolchains/installers.js +4 -12
- package/dist/guest/toolchains/native/autosdk.d.ts +3 -0
- package/dist/guest/toolchains/native/autosdk.js +50 -0
- package/dist/guest/toolchains/native/unreal.js +3 -0
- package/dist/guest/toolchains/native/vcruntime.d.ts +0 -3
- package/dist/guest/toolchains/native/vcruntime.js +2 -5
- package/dist/guest/toolchains/native/visual-studio.d.ts +2 -2
- package/dist/guest/toolchains/native/visual-studio.js +100 -16
- package/dist/guest/toolchains/native/vs-request.d.ts +21 -0
- package/dist/guest/toolchains/native/vs-request.js +60 -1
- package/dist/guest/toolchains/not-yet.d.ts +1 -1
- package/dist/guest/toolchains/not-yet.js +3 -3
- package/dist/guest/toolchains/persisted.js +2 -7
- package/dist/guest/toolchains/plan.js +9 -4
- package/dist/guest/toolchains/signature.d.ts +5 -0
- package/dist/guest/toolchains/signature.js +22 -0
- package/dist/guest/vpn/tunnel.d.ts +3 -0
- package/dist/guest/vpn/tunnel.js +10 -12
- package/dist/guest/vpn/vpn.js +6 -1
- package/dist/host/accounts/leases.d.ts +3 -3
- package/dist/host/accounts/source.js +1 -1
- package/dist/host/agent-commands/commands.js +1 -1
- package/dist/host/agent-commands/forwarders.d.ts +14 -2
- package/dist/host/agent-commands/forwarders.js +31 -13
- package/dist/host/agent-commands/reconcile.d.ts +2 -1
- package/dist/host/agent-commands/reconcile.js +7 -8
- package/dist/host/agent-commands/user-path.d.ts +5 -0
- package/dist/host/agent-commands/user-path.js +13 -0
- 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/session-file.js +1 -0
- package/dist/host/life/crash-report.d.ts +1 -1
- package/dist/host/life/crash-report.js +5 -3
- package/dist/host/life/last-end.d.ts +7 -0
- package/dist/host/life/last-end.js +21 -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/profile/accounts.js +2 -4
- package/dist/host/profile/claude-login.d.ts +3 -2
- package/dist/host/profile/claude-login.js +3 -13
- 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/host/vpn/index.d.ts +2 -1
- package/dist/host/vpn/index.js +2 -1
- package/dist/host/vpn/last.d.ts +28 -0
- package/dist/host/vpn/last.js +43 -0
- package/dist/host/vpn/login.d.ts +3 -1
- package/dist/host/vpn/login.js +17 -3
- package/dist/runtime/agent.js +31 -1
- package/dist/runtime/daemon.js +1419 -1197
- package/dist/runtime/db.js +33 -1
- package/dist/runtime/main.js +1311 -1037
- package/dist/runtime/netproxy.js +25 -1
- package/dist/runtime/tool.js +241 -209
- package/dist/runtime/view.js +25 -1
- package/dist/selftest/agent-commands.test.js +45 -7
- package/dist/selftest/agent-paths.test.js +1 -12
- package/dist/selftest/agent-settings.test.d.ts +2 -0
- package/dist/selftest/agent-settings.test.js +94 -0
- package/dist/selftest/app.test.js +2 -1
- package/dist/selftest/cli.test.js +4 -0
- package/dist/selftest/heavy-load.test.js +119 -2
- package/dist/selftest/index.js +2 -0
- package/dist/selftest/menu.test.js +5 -3
- package/dist/selftest/pc-installs.test.js +5 -0
- package/dist/selftest/persisted-installs.test.js +69 -0
- package/dist/selftest/service-accounts.test.js +1 -1
- package/dist/selftest/support/engine-golden.js +1 -1
- package/dist/selftest/support/fixtures.d.ts +9 -0
- package/dist/selftest/vpn.test.js +51 -3
- package/dist/shared/accounts/anthropic.d.ts +5 -0
- package/dist/shared/accounts/anthropic.js +15 -0
- package/dist/shared/accounts/index.d.ts +1 -0
- package/dist/shared/accounts/index.js +1 -0
- package/dist/shared/channel/schema.d.ts +20 -0
- package/dist/shared/channel/schema.js +4 -1
- package/dist/shared/io/disk.d.ts +9 -0
- package/dist/shared/io/disk.js +19 -0
- package/dist/shared/io/index.d.ts +1 -0
- package/dist/shared/io/index.js +1 -0
- package/dist/shared/readiness.d.ts +9 -0
- package/dist/shared/readiness.js +11 -0
- package/dist/shared/signer.d.ts +24 -0
- package/dist/shared/signer.js +15 -0
- package/dist/shared/system.d.ts +1 -0
- package/dist/shared/system.js +1 -0
- package/dist/shared/vpn/failure.d.ts +10 -0
- package/dist/shared/vpn/failure.js +28 -0
- package/dist/sync/watcher.js +11 -4
- package/dist/web/index.html +1 -1
- package/dist/web/{main-6XYO5FZC.js → main-OUUQYNK4.js} +75 -74
- package/native/csharp/HcsHost/AssemblyInfo.cs +3 -3
- package/native/csharp/HostTools/AssemblyInfo.cs +3 -3
- package/native/csharp/HostTools/Program.cs +19 -2
- package/native/csharp/HostTools/UserPath.cs +17 -0
- package/native/csharp/StorageHelper/AssemblyInfo.cs +3 -3
- package/native/scripts/edit-user-path.ps1 +6 -2
- package/native/scripts/stop-events.ps1 +7 -3
- package/package.json +1 -1
- package/sandbox/scripts/get-signature.ps1 +13 -0
- package/schemas/config.schema.json +64 -0
- package/schemas/sandbox-config.schema.json +8 -0
- package/sandbox/scripts/get-signer.ps1 +0 -8
|
@@ -3,7 +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';
|
|
6
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';
|
|
7
10
|
import { runningOwner } from '../../../host/sharing/index.js';
|
|
8
11
|
import { requireOnPc, requireRunning } from '../../../cli/commands/context.js';
|
|
9
12
|
import { hereDir } from '../../../cli/commands/projects/here.js';
|
|
@@ -11,7 +14,7 @@ import { lookAtSandbox, useSharedSandbox } from '../../../cli/commands/shared-us
|
|
|
11
14
|
import { SandboxService } from '../../../cli/services/index.js';
|
|
12
15
|
import { implement, typedConfirm } from '../../context.js';
|
|
13
16
|
import { cancelled } from '../../kernel/index.js';
|
|
14
|
-
import { hideWindow, sandboxStatus, showWindow, stopSandbox } from './sandbox.def.js';
|
|
17
|
+
import { cleanUpSandbox, hideWindow, sandboxStatus, showWindow, stopSandbox, } from './sandbox.def.js';
|
|
15
18
|
/** Another user's sandbox that is not shared: whose it is, and nothing else. */
|
|
16
19
|
function limitedStatus(view, folder) {
|
|
17
20
|
const owner = view.owner;
|
|
@@ -39,8 +42,10 @@ export const sandboxStatusRun = implement(sandboxStatus, async (asked) => {
|
|
|
39
42
|
const report = await new SandboxService(view.ctx).status();
|
|
40
43
|
const { storageRoot, dataPath } = view.ctx;
|
|
41
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;
|
|
42
46
|
return {
|
|
43
47
|
...(lastEnd ? { lastEnd } : {}),
|
|
48
|
+
...(leftover?.state === 'leftover' ? { leftover: { text: leftover.why } } : {}),
|
|
44
49
|
...(view.line ? { shared: { line: view.line, limited: false, startedBy: view.ctx.borrowed?.user ?? null } } : {}),
|
|
45
50
|
...report,
|
|
46
51
|
sandbox: { ...report.sandbox, daemon: safeText(report.sandbox.daemon) },
|
|
@@ -61,6 +66,41 @@ export const hideWindowRun = implement(hideWindow, async (ctx, _input, io) => {
|
|
|
61
66
|
await new SandboxService(ctx).hideWindow();
|
|
62
67
|
return { message: 'Sandbox window hidden. Bring it back with: sbx-show' };
|
|
63
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
|
+
});
|
|
64
104
|
/**
|
|
65
105
|
* Stopping ends every project's sessions: it says which, and the sessions of other projects need a yes (also on the
|
|
66
106
|
* command line, where --yes gives it; a script without it fails rather than end them by accident).
|
|
@@ -31,7 +31,7 @@ export const CATEGORIES = [
|
|
|
31
31
|
id: 'agents',
|
|
32
32
|
label: 'Agents & sessions',
|
|
33
33
|
description: 'The agents you can start (also: Agents section), attaching your terminal to them, the (Beta) web UI and agent commands, which of your Claude settings are copied in, and reopening sessions.',
|
|
34
|
-
keys: ['harnesses', 'attach', 'web', 'agentCommands', 'claudeProfile', 'resume'],
|
|
34
|
+
keys: ['harnesses', 'codex', 'attach', 'web', 'agentCommands', 'claudeProfile', 'resume'],
|
|
35
35
|
},
|
|
36
36
|
{
|
|
37
37
|
id: 'network',
|
|
@@ -58,7 +58,7 @@ export const SETTINGS_ELSEWHERE = ['apps'];
|
|
|
58
58
|
const NAMES = {
|
|
59
59
|
sandbox: 'Sandbox machine',
|
|
60
60
|
attach: 'Attaching your terminal',
|
|
61
|
-
agentCommands: 'Agent commands
|
|
61
|
+
agentCommands: 'Agent commands',
|
|
62
62
|
web: 'Web UI (Beta)',
|
|
63
63
|
provisioning: 'Provisioning',
|
|
64
64
|
downloads: 'Downloads',
|
|
@@ -90,6 +90,7 @@ const NAMES = {
|
|
|
90
90
|
projects: 'Projects',
|
|
91
91
|
resume: 'Reopening sessions',
|
|
92
92
|
harnesses: 'Agents',
|
|
93
|
+
codex: 'Codex',
|
|
93
94
|
databases: 'Databases',
|
|
94
95
|
toolchains: 'Toolchains',
|
|
95
96
|
git: 'Git',
|
|
@@ -142,6 +143,8 @@ const LABELS = {
|
|
|
142
143
|
'projects.wsbShare': 'Add folders while the sandbox runs',
|
|
143
144
|
'projects.liveFolders': 'Add folders through HCS (alpha, untested)',
|
|
144
145
|
'projects.all': 'Map all known projects at start',
|
|
146
|
+
'codex.sandboxMode': "Codex's own sandbox",
|
|
147
|
+
'codex.windowsSandbox': 'Windows sandbox mode for Codex',
|
|
145
148
|
'claudeProfile.hostDir': 'Claude folder on this PC',
|
|
146
149
|
'claudeProfile.globalStateFile': 'Claude state file on this PC',
|
|
147
150
|
};
|
|
@@ -6,6 +6,7 @@ import { NEVER_LOOSER } from '../../../core/local-config/index.js';
|
|
|
6
6
|
import { redactSecrets } from '../../../core/schema/index.js';
|
|
7
7
|
import { fail } from '../../../core/util/index.js';
|
|
8
8
|
import { closest } from '../../../cli/validate.js';
|
|
9
|
+
import { isToolchainReady } from '../../../shared/readiness.js';
|
|
9
10
|
import { fieldOf } from '../../kernel/index.js';
|
|
10
11
|
import { categoryOf, labelOf, nameOf } from './categories.def.js';
|
|
11
12
|
/** Every editable setting of a file, each in its category (settings covered by another section are left out). */
|
|
@@ -24,7 +25,10 @@ export function settingsOf(file) {
|
|
|
24
25
|
section: several && category.id !== 'general' ? nameOf(top) : undefined,
|
|
25
26
|
},
|
|
26
27
|
];
|
|
27
|
-
return node
|
|
28
|
+
return node
|
|
29
|
+
.leaves([top])
|
|
30
|
+
.filter(({ key }) => top !== 'toolchains' || isToolchainReady(key[1]))
|
|
31
|
+
.map(({ key, node: leaf }) => {
|
|
28
32
|
const heading = [
|
|
29
33
|
several ? nameOf(top) : undefined,
|
|
30
34
|
key.length > 2 ? key.slice(1, -1).map(nameOf).join(' › ') : undefined,
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import type { Config } from '../../../core/types.js';
|
|
1
2
|
import { type AppContext } from '../../context.js';
|
|
2
3
|
import { type SettingsFiles } from './settings-rows.js';
|
|
4
|
+
import { type Scope } from './settings.def.js';
|
|
3
5
|
/** The file `sandbox config export` writes when none is named. */
|
|
4
6
|
export declare const DEFAULT_EXPORT = "sandbox-settings.json";
|
|
5
7
|
/** Your own settings file (the one --config names) and the project file of the current folder. */
|
|
@@ -48,6 +50,12 @@ export declare const getSettingRun: import("../../kernel/define.js").Implementat
|
|
|
48
50
|
/** The file of a scope, and the setting a key names in it. */
|
|
49
51
|
/** incoming with every *** that stands where saved has a text replaced by that saved text. Pure. */
|
|
50
52
|
export declare function keepShownSecrets(saved: unknown, incoming: unknown): unknown;
|
|
53
|
+
/** What brings this PC in line with a changed agentCommands setting (the real service, or a fake in a test). */
|
|
54
|
+
export interface AgentCommandsReconciler {
|
|
55
|
+
reconcile(config: Config): unknown;
|
|
56
|
+
}
|
|
57
|
+
/** After your own settings change: a key under agentCommands also changes this PC (files, PATH), on every surface. */
|
|
58
|
+
export declare function applyAgentCommandsChange(ctx: AppContext, scope: Scope, key: string, service?: AgentCommandsReconciler): void;
|
|
51
59
|
export declare const setSettingRun: import("../../kernel/define.js").Implementation<import("../../kernel/define.js").OperationDef<import("zod").ZodObject<{
|
|
52
60
|
scope: import("zod").ZodDefault<import("zod").ZodEnum<{
|
|
53
61
|
project: "project";
|
|
@@ -7,6 +7,7 @@ import { loadConfig } from '../../../core/config/index.js';
|
|
|
7
7
|
import { REDACTED, redactSecrets } from '../../../core/schema/index.js';
|
|
8
8
|
import { fail, safeText, writeJson } from '../../../core/util/index.js';
|
|
9
9
|
import { hereDir } from '../../../cli/commands/projects/here.js';
|
|
10
|
+
import { AgentCommandsService } from '../../../cli/services/agent-commands-service.js';
|
|
10
11
|
import { implement } from '../../context.js';
|
|
11
12
|
import { allowedText, cancelled, valueFromText } from '../../kernel/index.js';
|
|
12
13
|
import { CATEGORIES } from './categories.def.js';
|
|
@@ -66,6 +67,12 @@ function target(ctx, scope, name) {
|
|
|
66
67
|
const file = settingsFiles(ctx)[scope];
|
|
67
68
|
return { ...findSetting(file, name), file };
|
|
68
69
|
}
|
|
70
|
+
/** After your own settings change: a key under agentCommands also changes this PC (files, PATH), on every surface. */
|
|
71
|
+
export function applyAgentCommandsChange(ctx, scope, key, service = new AgentCommandsService(ctx)) {
|
|
72
|
+
if (scope !== 'user' || !/^agentCommands(\.|$)/.test(key))
|
|
73
|
+
return;
|
|
74
|
+
service.reconcile(freshConfig(ctx));
|
|
75
|
+
}
|
|
69
76
|
export const setSettingRun = implement(setSetting, (ctx, input) => {
|
|
70
77
|
const { key, node, file } = target(ctx, input.scope, input.key);
|
|
71
78
|
if (node.isSection)
|
|
@@ -81,6 +88,7 @@ export const setSettingRun = implement(setSetting, (ctx, input) => {
|
|
|
81
88
|
const outcome = file.set(key, value);
|
|
82
89
|
if (typeof outcome === 'object')
|
|
83
90
|
fail('Could not change ' + input.key + ': ' + outcome.problems.join('; '), 'Nothing was written.');
|
|
91
|
+
applyAgentCommandsChange(ctx, input.scope, input.key);
|
|
84
92
|
return {
|
|
85
93
|
key: input.key,
|
|
86
94
|
changed: outcome === 'saved',
|
|
@@ -96,6 +104,7 @@ export const resetSettingRun = implement(resetSetting, (ctx, input) => {
|
|
|
96
104
|
const outcome = file.set(key, undefined);
|
|
97
105
|
if (typeof outcome === 'object')
|
|
98
106
|
fail('Could not reset ' + input.key + ': ' + outcome.problems.join('; '), 'Nothing was written.');
|
|
107
|
+
applyAgentCommandsChange(ctx, input.scope, input.key);
|
|
99
108
|
return {
|
|
100
109
|
key: input.key,
|
|
101
110
|
changed: outcome === 'saved',
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// runs, rollback on failure) stays in host/update.
|
|
4
4
|
import { userDir } from '../../../core/config/index.js';
|
|
5
5
|
import { errMsg, fail } from '../../../core/util/index.js';
|
|
6
|
-
import { MigrateService, NPM_UPDATE_COMMAND, UpdateService } from '../../../cli/services/index.js';
|
|
6
|
+
import { AgentCommandsService, MigrateService, NPM_UPDATE_COMMAND, UpdateService, } from '../../../cli/services/index.js';
|
|
7
7
|
import { implement } from '../../context.js';
|
|
8
8
|
import { cancelled } from '../../kernel/index.js';
|
|
9
9
|
import { describeResult, whereOf } from './update-lines.js';
|
|
@@ -73,7 +73,17 @@ export const runUpdateRun = implement(runUpdate, async (ctx, input, io) => {
|
|
|
73
73
|
// A folder of the user's choosing is installed from only on the command line (the web and the menu send no feed).
|
|
74
74
|
if (input.feed !== undefined && input.feed !== ctx.options.feed)
|
|
75
75
|
fail('--feed works only on the command line.');
|
|
76
|
-
|
|
76
|
+
const result = await updateWith(UpdateService.forPackage(ctx.packageRoot, input.feed, { userDir: userDir() }), input, io);
|
|
77
|
+
// The agent commands (claude, codex ...) point at the program: bring them in line with what is installed now.
|
|
78
|
+
if (ctx.loaded.config.agentCommands.enabled && !input.check && !input.rollback && !input.auto) {
|
|
79
|
+
try {
|
|
80
|
+
new AgentCommandsService(ctx).reconcile(ctx.loaded.config);
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
// The update itself worked; the agent commands are put right at the next launch.
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return result;
|
|
77
87
|
});
|
|
78
88
|
/** sandbox migrate's work, given the service (tests pass their own). */
|
|
79
89
|
export async function migrateWith(service, input, io) {
|
|
@@ -31,6 +31,17 @@ export declare const VpnStatusSchema: z.ZodObject<{
|
|
|
31
31
|
}>;
|
|
32
32
|
text: z.ZodString;
|
|
33
33
|
}, z.core.$strip>>;
|
|
34
|
+
lastFailure: z.ZodNullable<z.ZodObject<{
|
|
35
|
+
code: z.ZodEnum<{
|
|
36
|
+
auth: "auth";
|
|
37
|
+
unreachable: "unreachable";
|
|
38
|
+
driver: "driver";
|
|
39
|
+
timeout: "timeout";
|
|
40
|
+
other: "other";
|
|
41
|
+
}>;
|
|
42
|
+
text: z.ZodString;
|
|
43
|
+
at: z.ZodString;
|
|
44
|
+
}, z.core.$strip>>;
|
|
34
45
|
}, z.core.$strip>;
|
|
35
46
|
export type VpnStatus = z.output<typeof VpnStatusSchema>;
|
|
36
47
|
export declare const vpnStatus: import("../../kernel/define.js").QueryDef<z.ZodObject<{
|
|
@@ -62,6 +73,17 @@ export declare const vpnStatus: import("../../kernel/define.js").QueryDef<z.ZodO
|
|
|
62
73
|
}>;
|
|
63
74
|
text: z.ZodString;
|
|
64
75
|
}, z.core.$strip>>;
|
|
76
|
+
lastFailure: z.ZodNullable<z.ZodObject<{
|
|
77
|
+
code: z.ZodEnum<{
|
|
78
|
+
auth: "auth";
|
|
79
|
+
unreachable: "unreachable";
|
|
80
|
+
driver: "driver";
|
|
81
|
+
timeout: "timeout";
|
|
82
|
+
other: "other";
|
|
83
|
+
}>;
|
|
84
|
+
text: z.ZodString;
|
|
85
|
+
at: z.ZodString;
|
|
86
|
+
}, z.core.$strip>>;
|
|
65
87
|
}, z.core.$strip>, "vpn.status">;
|
|
66
88
|
export declare const vpnLogin: import("../../kernel/define.js").OperationDef<z.ZodObject<{}, z.core.$strict>, z.ZodObject<{
|
|
67
89
|
message: z.ZodString;
|
|
@@ -108,5 +130,16 @@ export declare const vpnView: import("../../kernel/define.js").ViewDef<{
|
|
|
108
130
|
}>;
|
|
109
131
|
text: z.ZodString;
|
|
110
132
|
}, z.core.$strip>>;
|
|
133
|
+
lastFailure: z.ZodNullable<z.ZodObject<{
|
|
134
|
+
code: z.ZodEnum<{
|
|
135
|
+
auth: "auth";
|
|
136
|
+
unreachable: "unreachable";
|
|
137
|
+
driver: "driver";
|
|
138
|
+
timeout: "timeout";
|
|
139
|
+
other: "other";
|
|
140
|
+
}>;
|
|
141
|
+
text: z.ZodString;
|
|
142
|
+
at: z.ZodString;
|
|
143
|
+
}, z.core.$strip>>;
|
|
111
144
|
}, z.core.$strip>, "vpn.status">;
|
|
112
145
|
}, Record<string, never>, "vpn">;
|
|
@@ -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: '
|
|
147
|
-
tone: '
|
|
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
|
|
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');
|
package/dist/app/kernel/rpc.d.ts
CHANGED
package/dist/app/registry.js
CHANGED
|
@@ -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';
|
|
@@ -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';
|
|
@@ -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';
|
|
@@ -24,6 +25,7 @@ export const IMPLEMENTATIONS = [
|
|
|
24
25
|
showWindowRun,
|
|
25
26
|
hideWindowRun,
|
|
26
27
|
stopSandboxRun,
|
|
28
|
+
cleanUpSandboxRun,
|
|
27
29
|
listSessionsRun,
|
|
28
30
|
restartSessionsRun,
|
|
29
31
|
startShellRun,
|
|
@@ -33,6 +35,8 @@ export const IMPLEMENTATIONS = [
|
|
|
33
35
|
makeDefaultAgentRun,
|
|
34
36
|
removeAgentRun,
|
|
35
37
|
listAgentsRun,
|
|
38
|
+
agentEnvRun,
|
|
39
|
+
agentsEnvSetRun,
|
|
36
40
|
listSettingsRun,
|
|
37
41
|
getSettingRun,
|
|
38
42
|
setSettingRun,
|
|
@@ -88,6 +92,9 @@ export const IMPLEMENTATIONS = [
|
|
|
88
92
|
vpnStatusRun,
|
|
89
93
|
vpnLoginRun,
|
|
90
94
|
vpnLogoutRun,
|
|
95
|
+
agentCommandsStatusRun,
|
|
96
|
+
agentCommandsOnRun,
|
|
97
|
+
agentCommandsOffRun,
|
|
91
98
|
githubStatusRun,
|
|
92
99
|
githubLoginRun,
|
|
93
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-
|
|
6
|
-
import "./chunk-
|
|
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));
|