windows-development-sandbox 1.7.0 → 1.9.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/config.example.json +10 -0
- package/dist/app/context.d.ts +8 -0
- package/dist/app/context.js +12 -0
- package/dist/app/features/defs.d.ts +322 -0
- package/dist/app/features/defs.js +28 -0
- package/dist/app/features/sandbox/index.d.ts +2 -0
- package/dist/app/features/sandbox/index.js +3 -0
- package/dist/app/features/sandbox/sandbox.def.d.ts +193 -0
- package/dist/app/features/sandbox/sandbox.def.js +245 -0
- package/dist/app/features/sandbox/sandbox.run.d.ts +72 -0
- package/dist/app/features/sandbox/sandbox.run.js +98 -0
- package/dist/app/features/sessions/index.d.ts +2 -0
- package/dist/app/features/sessions/index.js +3 -0
- package/dist/app/features/sessions/sessions.def.d.ts +141 -0
- package/dist/app/features/sessions/sessions.def.js +176 -0
- package/dist/app/features/sessions/sessions.run.d.ts +39 -0
- package/dist/app/features/sessions/sessions.run.js +58 -0
- package/dist/{cli/menu/settings/categories.d.ts → app/features/settings/categories.def.d.ts} +2 -0
- package/dist/{cli/menu/settings/categories.js → app/features/settings/categories.def.js} +24 -5
- package/dist/app/features/settings/index.d.ts +5 -0
- package/dist/app/features/settings/index.js +6 -0
- package/dist/{cli/menu/settings/config-file.d.ts → app/features/settings/settings-file.d.ts} +1 -1
- package/dist/{cli/menu/settings/config-file.js → app/features/settings/settings-file.js} +1 -1
- package/dist/app/features/settings/settings-rows.d.ts +35 -0
- package/dist/app/features/settings/settings-rows.js +94 -0
- package/dist/app/features/settings/settings.def.d.ts +157 -0
- package/dist/app/features/settings/settings.def.js +179 -0
- package/dist/app/features/settings/settings.run.d.ts +67 -0
- package/dist/app/features/settings/settings.run.js +84 -0
- package/dist/app/kernel/define.d.ts +143 -0
- package/dist/app/kernel/define.js +42 -0
- package/dist/app/kernel/errors.d.ts +34 -0
- package/dist/app/kernel/errors.js +45 -0
- package/dist/app/kernel/fields.d.ts +70 -0
- package/dist/app/kernel/fields.js +243 -0
- package/dist/app/kernel/index.d.ts +8 -0
- package/dist/app/kernel/index.js +10 -0
- package/dist/app/kernel/io.d.ts +193 -0
- package/dist/app/kernel/io.js +126 -0
- package/dist/app/kernel/rpc.d.ts +156 -0
- package/dist/app/kernel/rpc.js +47 -0
- package/dist/app/kernel/text.d.ts +6 -0
- package/dist/app/kernel/text.js +57 -0
- package/dist/app/kernel/view.d.ts +146 -0
- package/dist/app/kernel/view.js +28 -0
- package/dist/app/registry.d.ts +10 -0
- package/dist/app/registry.js +50 -0
- package/dist/cli/args.d.ts +5 -0
- package/dist/cli/args.js +6 -0
- package/dist/cli/commands/engine.d.ts +2 -0
- package/dist/cli/commands/engine.js +60 -0
- package/dist/cli/commands/index.d.ts +1 -1
- package/dist/cli/commands/index.js +1 -1
- package/dist/cli/commands/launch/launch.js +47 -7
- package/dist/cli/commands/launch/prepare.js +3 -3
- package/dist/cli/commands/launch/running.js +2 -1
- package/dist/cli/commands/launch/summary.d.ts +2 -0
- package/dist/cli/commands/maintenance/config-share.d.ts +12 -0
- package/dist/cli/commands/maintenance/config-share.js +80 -0
- package/dist/cli/commands/maintenance/config.js +8 -82
- package/dist/cli/commands/maintenance/logs.js +14 -0
- package/dist/cli/commands/registry.js +3 -7
- package/dist/cli/commands/repair/checks/contained.d.ts +2 -0
- package/dist/cli/commands/repair/checks/contained.js +139 -0
- package/dist/cli/commands/repair/checks/hcs.d.ts +7 -0
- package/dist/cli/commands/repair/checks/hcs.js +28 -0
- package/dist/cli/commands/repair/checks/index.js +4 -0
- package/dist/cli/commands/repair/checks/pc.js +32 -1
- package/dist/cli/commands/repair/checks/sandbox.js +16 -1
- package/dist/cli/commands/repair/checks/vpn.js +34 -9
- package/dist/cli/commands/repair/env.js +2 -1
- package/dist/cli/commands/sessions/index.d.ts +0 -4
- package/dist/cli/commands/sessions/index.js +3 -7
- package/dist/cli/commands/shared-use.d.ts +5 -2
- package/dist/cli/commands/shared-use.js +11 -8
- package/dist/cli/commands/storage/contained.d.ts +3 -0
- package/dist/cli/commands/storage/contained.js +179 -0
- package/dist/cli/commands/storage/offer.js +7 -1
- package/dist/cli/commands/storage/storage.js +10 -2
- package/dist/cli/commands/user-config.js +1 -1
- package/dist/cli/commands/vpn.js +19 -3
- package/dist/cli/commands/web.js +2 -0
- package/dist/cli/index.js +2 -1
- package/dist/cli/manifest.d.ts +72 -104
- package/dist/cli/manifest.js +64 -39
- package/dist/cli/menu/add-agent.d.ts +1 -1
- package/dist/cli/menu/add-agent.js +1 -1
- package/dist/cli/menu/apps.d.ts +7 -1
- package/dist/cli/menu/apps.js +36 -0
- package/dist/cli/menu/command-fields.d.ts +1 -1
- package/dist/cli/menu/command-form.js +2 -2
- package/dist/cli/menu/io-menu.d.ts +29 -0
- package/dist/cli/menu/io-menu.js +126 -0
- package/dist/cli/menu/live.d.ts +27 -0
- package/dist/cli/menu/live.js +69 -0
- package/dist/cli/menu/memory.d.ts +19 -0
- package/dist/cli/menu/memory.js +53 -0
- package/dist/cli/menu/menu.d.ts +10 -1
- package/dist/cli/menu/menu.js +27 -9
- package/dist/cli/menu/pages/agents-page.d.ts +3 -1
- package/dist/cli/menu/pages/agents-page.js +12 -5
- package/dist/cli/menu/pages/apps-page.d.ts +3 -1
- package/dist/cli/menu/pages/apps-page.js +19 -2
- package/dist/cli/menu/pages/list-page.d.ts +27 -0
- package/dist/cli/menu/pages/list-page.js +109 -7
- package/dist/cli/menu/pages/maintenance-page.d.ts +0 -5
- package/dist/cli/menu/pages/maintenance-page.js +17 -19
- package/dist/cli/menu/pages/sandbox-page.d.ts +4 -6
- package/dist/cli/menu/pages/sandbox-page.js +26 -118
- package/dist/cli/menu/pages/scopes.d.ts +1 -1
- package/dist/cli/menu/pages/sessions-page.d.ts +5 -11
- package/dist/cli/menu/pages/sessions-page.js +19 -88
- package/dist/cli/menu/pages/settings-page.d.ts +2 -10
- package/dist/cli/menu/pages/settings-page.js +64 -94
- package/dist/cli/menu/render-view.d.ts +28 -0
- package/dist/cli/menu/render-view.js +112 -0
- package/dist/cli/menu/settings/{path-kind.d.ts → ask-path.d.ts} +1 -7
- package/dist/cli/menu/settings/ask-path.js +14 -0
- package/dist/cli/menu/settings/collections/collection-editor.d.ts +1 -1
- package/dist/cli/menu/settings/collections/string-list-editor.d.ts +1 -2
- package/dist/cli/menu/settings/collections/string-list-editor.js +1 -1
- package/dist/cli/menu/settings/draft.d.ts +1 -1
- package/dist/cli/menu/settings/format.d.ts +1 -3
- package/dist/cli/menu/settings/format.js +6 -36
- package/dist/cli/menu/settings/index.d.ts +1 -3
- package/dist/cli/menu/settings/index.js +3 -3
- package/dist/cli/menu/settings/object-editor.d.ts +1 -1
- package/dist/cli/menu/settings/share.d.ts +36 -0
- package/dist/cli/menu/settings/share.js +131 -0
- package/dist/cli/menu/settings/value-editor.d.ts +5 -1
- package/dist/cli/menu/settings/value-editor.js +57 -54
- package/dist/cli/menu/several.js +1 -1
- package/dist/cli/menu/share-settings.d.ts +21 -0
- package/dist/cli/menu/share-settings.js +112 -0
- package/dist/cli/menu/shell.d.ts +21 -5
- package/dist/cli/menu/shell.js +31 -6
- package/dist/cli/menu/views.d.ts +7 -0
- package/dist/cli/menu/views.js +11 -0
- package/dist/cli/menu/vpn-login.js +8 -0
- package/dist/cli/operations/handler.d.ts +6 -0
- package/dist/cli/operations/handler.js +61 -0
- package/dist/cli/operations/index.d.ts +4 -0
- package/dist/cli/operations/index.js +5 -0
- package/dist/cli/operations/input.d.ts +6 -0
- package/dist/cli/operations/input.js +37 -0
- package/dist/cli/operations/io-cli.d.ts +7 -0
- package/dist/cli/operations/io-cli.js +62 -0
- package/dist/cli/operations/spec.d.ts +18 -0
- package/dist/cli/operations/spec.js +108 -0
- package/dist/cli/output/colors.d.ts +2 -2
- package/dist/cli/output/colors.js +2 -11
- package/dist/cli/output/index.d.ts +1 -0
- package/dist/cli/output/index.js +1 -0
- package/dist/cli/output/print.d.ts +3 -1
- package/dist/cli/output/print.js +7 -3
- package/dist/cli/output/progress.d.ts +15 -0
- package/dist/cli/output/progress.js +44 -0
- package/dist/cli/output/render-view.d.ts +4 -0
- package/dist/cli/output/render-view.js +63 -0
- package/dist/cli/services/agent-commands-service.d.ts +2 -0
- package/dist/cli/services/agent-commands-service.js +11 -2
- package/dist/cli/services/logs-service.js +4 -3
- package/dist/cli/tui/app.d.ts +6 -1
- package/dist/cli/tui/app.js +26 -4
- package/dist/cli/tui/list/list-screen.d.ts +14 -0
- package/dist/cli/tui/list/list-screen.js +64 -36
- package/dist/cli/tui/list/list-types.d.ts +2 -0
- package/dist/cli/tui/terminal.d.ts +7 -0
- package/dist/cli/tui/terminal.js +30 -10
- package/dist/core/config/defaults.js +8 -0
- package/dist/core/schema/config.d.ts +13 -0
- package/dist/core/schema/config.js +16 -1
- package/dist/core/schema/harness.d.ts +1 -0
- package/dist/core/schema/harness.js +5 -0
- package/dist/core/schema/sandbox.d.ts +6 -0
- package/dist/core/schema/sandbox.js +20 -3
- package/dist/core/schema/vpn.d.ts +2 -1
- package/dist/core/schema/vpn.js +3 -3
- package/dist/core/types.d.ts +23 -5
- package/dist/core/util/fs.d.ts +2 -0
- package/dist/core/util/fs.js +9 -0
- package/dist/core/util/index.d.ts +1 -1
- package/dist/core/util/index.js +1 -1
- package/dist/guest/agents/agent-files.d.ts +5 -0
- package/dist/guest/agents/agent-files.js +4 -0
- package/dist/guest/agents/local-state.d.ts +2 -0
- package/dist/guest/agents/local-state.js +21 -1
- package/dist/guest/boot/boot.js +2 -1
- package/dist/guest/daemon/daemon.js +4 -0
- package/dist/guest/daemon/sessions.d.ts +5 -0
- package/dist/guest/daemon/sessions.js +17 -3
- package/dist/guest/entries/daemon.js +3 -0
- package/dist/guest/governor/decide.d.ts +61 -0
- package/dist/guest/governor/decide.js +182 -0
- package/dist/guest/governor/governor.d.ts +42 -0
- package/dist/guest/governor/governor.js +214 -0
- package/dist/guest/governor/index.d.ts +2 -0
- package/dist/guest/governor/index.js +2 -0
- package/dist/guest/runtime/csc.d.ts +1 -0
- package/dist/guest/runtime/csc.js +1 -0
- package/dist/guest/sessions/viewer.js +3 -1
- package/dist/guest/toolchains/native/rust-extras.js +4 -2
- package/dist/guest/vpn/vpn.js +69 -21
- package/dist/guest/vpn/wireguard.d.ts +32 -0
- package/dist/guest/vpn/wireguard.js +132 -0
- package/dist/host/agent-commands/commands.d.ts +4 -0
- package/dist/host/agent-commands/commands.js +31 -7
- package/dist/host/audit/log.d.ts +1 -1
- package/dist/host/channel/attach.d.ts +3 -1
- package/dist/host/channel/attach.js +5 -2
- package/dist/host/channel/channel.d.ts +2 -0
- package/dist/host/channel/channel.js +4 -0
- package/dist/host/engines/engine.d.ts +12 -0
- package/dist/host/engines/engine.js +1 -0
- package/dist/host/engines/hcs/check.d.ts +25 -0
- package/dist/host/engines/hcs/check.js +95 -0
- package/dist/host/engines/hcs/documents.d.ts +44 -0
- package/dist/host/engines/hcs/documents.js +155 -0
- package/dist/host/engines/hcs/engine.d.ts +39 -0
- package/dist/host/engines/hcs/engine.js +171 -0
- package/dist/host/engines/hcs/helper.d.ts +43 -0
- package/dist/host/engines/hcs/helper.js +173 -0
- package/dist/host/engines/hcs/images.d.ts +37 -0
- package/dist/host/engines/hcs/images.js +152 -0
- package/dist/host/engines/index.d.ts +7 -0
- package/dist/host/engines/index.js +5 -0
- package/dist/host/engines/registry.d.ts +16 -0
- package/dist/host/engines/registry.js +30 -0
- package/dist/host/engines/types.d.ts +58 -0
- package/dist/host/engines/types.js +1 -0
- package/dist/host/engines/windows-sandbox/engine.d.ts +16 -0
- package/dist/host/engines/windows-sandbox/engine.js +63 -0
- package/dist/host/engines/windows-sandbox/wsb-text.d.ts +2 -0
- package/dist/host/engines/windows-sandbox/wsb-text.js +29 -0
- package/dist/host/launch/generate.d.ts +5 -1
- package/dist/host/launch/generate.js +50 -8
- package/dist/host/launch/index.d.ts +3 -1
- package/dist/host/launch/index.js +3 -1
- package/dist/host/launch/launch-plan.d.ts +13 -0
- package/dist/host/launch/launch-plan.js +26 -0
- package/dist/host/launch/mappings.js +2 -1
- package/dist/host/launch/risk-notes.d.ts +10 -0
- package/dist/host/launch/risk-notes.js +18 -0
- package/dist/host/launch/session-file.d.ts +2 -0
- package/dist/host/launch/session-file.js +7 -1
- package/dist/host/launch/wsb-file.d.ts +28 -4
- package/dist/host/launch/wsb-file.js +61 -42
- package/dist/host/life/crash-report.d.ts +27 -1
- package/dist/host/life/crash-report.js +173 -7
- package/dist/host/life/host-memory.d.ts +40 -0
- package/dist/host/life/host-memory.js +137 -0
- package/dist/host/life/index.d.ts +2 -0
- package/dist/host/life/index.js +2 -0
- package/dist/host/life/stop-events.d.ts +2 -0
- package/dist/host/life/stop-events.js +20 -3
- package/dist/host/life/stop-warning.js +1 -1
- package/dist/host/life/watchdog.d.ts +54 -0
- package/dist/host/life/watchdog.js +108 -0
- package/dist/host/native.d.ts +3 -2
- package/dist/host/native.js +22 -3
- package/dist/host/profile/claude-login.js +3 -2
- package/dist/host/sandbox/contained-deps.d.ts +2 -0
- package/dist/host/sandbox/contained-deps.js +17 -0
- package/dist/host/sandbox/index.d.ts +2 -0
- package/dist/host/sandbox/index.js +2 -0
- package/dist/host/sandbox/platform.d.ts +2 -0
- package/dist/host/sandbox/platform.js +7 -7
- package/dist/host/sandbox/tasklist.d.ts +13 -0
- package/dist/host/sandbox/tasklist.js +47 -0
- package/dist/host/secrets/launch-secrets.js +2 -1
- package/dist/host/sharing/current.js +2 -6
- package/dist/host/storage/contained/check.d.ts +9 -0
- package/dist/host/storage/contained/check.js +37 -0
- package/dist/host/storage/contained/contained-storage.d.ts +66 -0
- package/dist/host/storage/contained/contained-storage.js +168 -0
- package/dist/host/storage/contained/disk-port.d.ts +43 -0
- package/dist/host/storage/contained/disk-port.js +122 -0
- package/dist/host/storage/contained/index.d.ts +9 -0
- package/dist/host/storage/contained/index.js +8 -0
- package/dist/host/storage/contained/layout.d.ts +28 -0
- package/dist/host/storage/contained/layout.js +45 -0
- package/dist/host/storage/contained/resolve.d.ts +4 -0
- package/dist/host/storage/contained/resolve.js +30 -0
- package/dist/host/storage/contained/setting.d.ts +1 -0
- package/dist/host/storage/contained/setting.js +5 -0
- package/dist/host/storage/contained/state.d.ts +89 -0
- package/dist/host/storage/contained/state.js +166 -0
- package/dist/host/storage/contained/transfer.d.ts +24 -0
- package/dist/host/storage/contained/transfer.js +121 -0
- package/dist/host/storage/index.d.ts +2 -0
- package/dist/host/storage/index.js +2 -0
- package/dist/host/storage/providers/contained.d.ts +15 -0
- package/dist/host/storage/providers/contained.js +39 -0
- package/dist/host/storage/providers/folder.d.ts +12 -0
- package/dist/host/storage/providers/folder.js +20 -0
- package/dist/host/storage/providers/index.d.ts +4 -0
- package/dist/host/storage/providers/index.js +3 -0
- package/dist/host/storage/providers/registry.d.ts +9 -0
- package/dist/host/storage/providers/registry.js +14 -0
- package/dist/host/storage/providers/types.d.ts +33 -0
- package/dist/host/storage/providers/types.js +1 -0
- package/dist/host/tools/conpty.js +3 -2
- package/dist/host/tools/windows-terminal.js +8 -7
- package/dist/host/vpn/index.d.ts +1 -1
- package/dist/host/vpn/index.js +1 -1
- package/dist/host/vpn/prepare.d.ts +2 -0
- package/dist/host/vpn/prepare.js +63 -2
- package/dist/host/web/browser.d.ts +2 -0
- package/dist/host/web/browser.js +14 -1
- package/dist/host/web/index.d.ts +3 -2
- package/dist/host/web/index.js +3 -2
- package/dist/host/web/rpc.d.ts +24 -0
- package/dist/host/web/rpc.js +149 -0
- package/dist/host/web/runner.d.ts +2 -0
- package/dist/host/web/runner.js +1 -2
- package/dist/host/web/server.d.ts +7 -0
- package/dist/host/web/server.js +23 -3
- package/dist/runtime/agent.js +69 -8
- package/dist/runtime/daemon.js +1058 -624
- package/dist/runtime/db.js +69 -8
- package/dist/runtime/main.js +624 -182
- package/dist/runtime/netproxy.js +69 -8
- package/dist/runtime/view.js +87 -13
- package/dist/selftest/agent-paths.test.js +11 -1
- package/dist/selftest/app.test.d.ts +2 -0
- package/dist/selftest/app.test.js +324 -0
- package/dist/selftest/channel.test.js +13 -0
- package/dist/selftest/cli.test.js +2 -1
- package/dist/selftest/config.test.js +59 -0
- package/dist/selftest/contained.test.d.ts +2 -0
- package/dist/selftest/contained.test.js +544 -0
- package/dist/selftest/credentials.test.js +1 -1
- package/dist/selftest/engine.test.d.ts +2 -0
- package/dist/selftest/engine.test.js +127 -0
- package/dist/selftest/hcs.test.d.ts +2 -0
- package/dist/selftest/hcs.test.js +482 -0
- package/dist/selftest/heavy-load.test.d.ts +2 -0
- package/dist/selftest/heavy-load.test.js +329 -0
- package/dist/selftest/index.js +12 -0
- package/dist/selftest/layout.test.js +12 -0
- package/dist/selftest/menu-perf.test.d.ts +2 -0
- package/dist/selftest/menu-perf.test.js +248 -0
- package/dist/selftest/menu-screens.js +4 -2
- package/dist/selftest/menu.test.js +36 -8
- package/dist/selftest/support/engine-cases.d.ts +8 -0
- package/dist/selftest/support/engine-cases.js +65 -0
- package/dist/selftest/support/engine-golden.d.ts +3 -0
- package/dist/selftest/support/engine-golden.js +66 -0
- package/dist/selftest/support/fixtures.d.ts +7 -1
- package/dist/selftest/support/hcs-probes.d.ts +17 -0
- package/dist/selftest/support/hcs-probes.js +41 -0
- package/dist/selftest/vpn.test.js +136 -3
- package/dist/selftest/web.test.js +101 -3
- 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 +35 -1
- package/dist/shared/channel/schema.js +27 -0
- package/dist/shared/channel/secrets.d.ts +1 -0
- package/dist/shared/channel/secrets.js +6 -0
- package/dist/shared/memory/index.d.ts +1 -0
- package/dist/shared/memory/index.js +1 -0
- package/dist/shared/memory/policy.d.ts +33 -0
- package/dist/shared/memory/policy.js +55 -0
- package/dist/shared/pty/output-filter.d.ts +14 -1
- package/dist/shared/pty/output-filter.js +22 -4
- package/dist/shared/pty/terminal.d.ts +4 -1
- package/dist/shared/pty/terminal.js +4 -2
- package/dist/shared/system.d.ts +1 -0
- package/dist/shared/system.js +1 -0
- package/dist/shared/vpn/download.d.ts +16 -0
- package/dist/shared/vpn/download.js +16 -0
- package/dist/shared/vpn/wireguard.d.ts +51 -0
- package/dist/shared/vpn/wireguard.js +227 -0
- package/dist/sync/sync-cycle.js +5 -5
- package/dist/sync/watcher.d.ts +13 -0
- package/dist/sync/watcher.js +92 -3
- package/dist/web/index.html +4 -3
- package/dist/web/main-NRRS5O6Z.js +157 -0
- package/dist/web/main-T5DMCHYV.css +1 -0
- package/native/csharp/HcsHost/AssemblyInfo.cs +14 -0
- package/native/csharp/HcsHost/Guard.cs +100 -0
- package/native/csharp/HcsHost/Hcs.cs +256 -0
- package/native/csharp/HcsHost/Json.cs +78 -0
- package/native/csharp/HcsHost/Program.cs +185 -0
- package/native/csharp/HcsHost/VirtualDisk.cs +95 -0
- package/native/csharp/HostTools/AssemblyInfo.cs +14 -0
- package/native/csharp/HostTools/MemoryStatus.cs +107 -0
- package/native/csharp/HostTools/Program.cs +58 -17
- package/native/scripts/check-contained.ps1 +28 -0
- package/native/scripts/contained-common.ps1 +241 -0
- package/native/scripts/dismount-contained.ps1 +66 -0
- package/native/scripts/memory-status.ps1 +34 -0
- package/native/scripts/mount-contained.ps1 +139 -0
- package/native/scripts/run-elevated.ps1 +17 -4
- package/native/scripts/stop-events.ps1 +23 -8
- package/package.json +9 -2
- package/sandbox/csharp/MemGov.cs +398 -0
- package/sandbox/csharp/PtyHost.cs +111 -5
- package/schemas/config.schema.json +60 -6
- package/schemas/sandbox-config.schema.json +3 -3
- package/dist/cli/commands/sessions/control.d.ts +0 -4
- package/dist/cli/commands/sessions/control.js +0 -66
- package/dist/cli/commands/sessions/list.d.ts +0 -2
- package/dist/cli/commands/sessions/list.js +0 -48
- package/dist/cli/commands/sessions/status.d.ts +0 -4
- package/dist/cli/commands/sessions/status.js +0 -114
- package/dist/cli/commands/sessions/window.d.ts +0 -3
- package/dist/cli/commands/sessions/window.js +0 -18
- package/dist/cli/menu/settings/path-kind.js +0 -44
- package/dist/web/main-CXESL347.js +0 -45
- package/dist/web/main-VLR7DVQ4.css +0 -1
- /package/dist/{cli/menu/settings → app/kernel}/schema-node.d.ts +0 -0
- /package/dist/{cli/menu/settings → app/kernel}/schema-node.js +0 -0
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
// This PC: Windows itself, what Windows Sandbox needs of it, and whether Windows wants a restart. The hardware and
|
|
2
2
|
// edition answers come from the same look `sandbox setup` takes (once per run).
|
|
3
3
|
import { isWin } from '../../../../core/util/index.js';
|
|
4
|
-
import { updateRestartPending } from '../../../../host/life/index.js';
|
|
4
|
+
import { pageFileRisk, readHostMemory, updateRestartPending } from '../../../../host/life/index.js';
|
|
5
|
+
import { decideMemory } from '../../../../host/launch/index.js';
|
|
5
6
|
import { buildChecks } from '../../setup/checks.js';
|
|
6
7
|
import { ok } from './common.js';
|
|
7
8
|
const STATUS = { ok: 'ok', warn: 'warn', action: 'needs-you' };
|
|
@@ -38,6 +39,36 @@ export const PC_CHECKS = [
|
|
|
38
39
|
fromFacts('pc-virtualization', 'This PC', 'CPU virtualization', 'CPU virtualization'),
|
|
39
40
|
fromFacts('pc-memory', 'This PC', 'Memory', 'Memory'),
|
|
40
41
|
fromFacts('pc-node', 'This PC', 'Node.js', 'Node.js'),
|
|
42
|
+
{
|
|
43
|
+
id: 'pc-commit',
|
|
44
|
+
group: 'This PC',
|
|
45
|
+
name: 'Memory for the sandbox',
|
|
46
|
+
timeoutMs: 40_000,
|
|
47
|
+
run: (env) => {
|
|
48
|
+
const memory = readHostMemory(env.storageRoot);
|
|
49
|
+
if (!memory)
|
|
50
|
+
return { status: 'skipped', detail: 'the memory of this PC could not be read' };
|
|
51
|
+
const sandbox = env.ctx.loaded.config.sandbox;
|
|
52
|
+
const planned = sandbox.memoryMb === 'auto'
|
|
53
|
+
? decideMemory(sandbox, memory.availableMb, memory.totalMb, memory.commitAvailableMb).mb
|
|
54
|
+
: sandbox.memoryMb;
|
|
55
|
+
const detail = Math.floor(memory.commitAvailableMb / 1024) +
|
|
56
|
+
' GB of RAM plus paging file free, page file ' +
|
|
57
|
+
memory.pageFile +
|
|
58
|
+
', the next sandbox gets ' +
|
|
59
|
+
Math.floor(planned / 1024) +
|
|
60
|
+
' GB';
|
|
61
|
+
const risk = pageFileRisk(memory, planned);
|
|
62
|
+
return risk
|
|
63
|
+
? {
|
|
64
|
+
status: 'warn',
|
|
65
|
+
detail,
|
|
66
|
+
means: risk.text,
|
|
67
|
+
fix: 'Nothing is changed for you: set the page file as above (Windows keeps working either way).',
|
|
68
|
+
}
|
|
69
|
+
: ok(detail);
|
|
70
|
+
},
|
|
71
|
+
},
|
|
41
72
|
{
|
|
42
73
|
id: 'pc-restart-pending',
|
|
43
74
|
group: 'This PC',
|
|
@@ -6,6 +6,7 @@ import path from 'node:path';
|
|
|
6
6
|
import { dirExists, fileExists, isLink } from '../../../../core/util/index.js';
|
|
7
7
|
import { SandboxChannel } from '../../../../host/channel/index.js';
|
|
8
8
|
import { orphanWatchers, runStateProblems, staleLaunchFolders, watcherRecords } from '../../../../host/health/index.js';
|
|
9
|
+
import { vgpuSource, vgpuWarning } from '../../../../host/launch/index.js';
|
|
9
10
|
import { hostToolsExe } from '../../../../host/native.js';
|
|
10
11
|
import { sandboxFeatureInstalled } from '../../../../host/sandbox/index.js';
|
|
11
12
|
import { assertTestWritable, refuseInSelfTest } from '../../../../host/test-guard.js';
|
|
@@ -19,6 +20,19 @@ import { ok, plural, rel } from './common.js';
|
|
|
19
20
|
const LAUNCH_DAYS = 7;
|
|
20
21
|
const hiddenWindowsFile = (env) => path.join(env.storageRoot, 'run', 'hidden-windows.json');
|
|
21
22
|
export const SANDBOX_CHECKS = [
|
|
23
|
+
{
|
|
24
|
+
id: 'sandbox-vgpu',
|
|
25
|
+
group: 'Sandbox',
|
|
26
|
+
name: 'vGPU',
|
|
27
|
+
run: (env) => env.ctx.loaded.config.sandbox.vGpu
|
|
28
|
+
? {
|
|
29
|
+
status: 'warn',
|
|
30
|
+
detail: 'vGPU is on in your settings',
|
|
31
|
+
means: vgpuWarning(vgpuSource(true)),
|
|
32
|
+
fix: 'Run: sandbox config set sandbox.vGpu false',
|
|
33
|
+
}
|
|
34
|
+
: ok('off'),
|
|
35
|
+
},
|
|
22
36
|
{
|
|
23
37
|
id: 'sandbox-exe',
|
|
24
38
|
group: 'Sandbox',
|
|
@@ -198,7 +212,8 @@ export const SANDBOX_CHECKS = [
|
|
|
198
212
|
timeoutMs: 150_000,
|
|
199
213
|
run: (env) => {
|
|
200
214
|
const bin = path.join(env.storageRoot, 'bin');
|
|
201
|
-
const built = dirExists(bin) &&
|
|
215
|
+
const built = dirExists(bin) &&
|
|
216
|
+
fs.readdirSync(bin).some((n) => /^[0-9a-f]{12}$/i.test(n) && fs.existsSync(path.join(bin, n, 'HostTools.exe')));
|
|
202
217
|
if (built)
|
|
203
218
|
return ok('built in ' + bin);
|
|
204
219
|
return {
|
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
// The VPN, when it is on: is the login saved and readable, can the OpenVPN download be reached. Not shown when the
|
|
2
2
|
// VPN is off. (That the storage folder is private is checked with the data folder.)
|
|
3
|
-
import { VpnLogin } from '../../../../host/vpn/index.js';
|
|
4
|
-
import { OPENVPN_MSI } from '../../../../shared/vpn/download.js';
|
|
3
|
+
import { VpnLogin, wireguardFileProblem } from '../../../../host/vpn/index.js';
|
|
4
|
+
import { OPENVPN_MSI, WIREGUARD_MSI } from '../../../../shared/vpn/download.js';
|
|
5
5
|
import { ok } from './common.js';
|
|
6
6
|
const REACH_MS = 6000;
|
|
7
7
|
const vpnOn = (env) => env.ctx.loaded.config.vpn.enabled;
|
|
8
|
+
const wireguard = (env) => env.ctx.loaded.config.vpn.provider === 'wireguard-file';
|
|
9
|
+
const loginNeeded = (env) => vpnOn(env) && !wireguard(env);
|
|
10
|
+
const wireguardOn = (env) => vpnOn(env) && wireguard(env);
|
|
8
11
|
export const VPN_CHECKS = [
|
|
9
12
|
{
|
|
10
13
|
id: 'vpn-login',
|
|
11
14
|
group: 'Network',
|
|
12
15
|
name: 'VPN login',
|
|
13
16
|
checking: 'the saved VPN login',
|
|
14
|
-
applies:
|
|
17
|
+
applies: loginNeeded,
|
|
15
18
|
run: (env) => {
|
|
16
19
|
const { provider } = env.ctx.loaded.config.vpn;
|
|
17
20
|
const state = new VpnLogin(env.storageRoot).state(provider);
|
|
@@ -32,20 +35,42 @@ export const VPN_CHECKS = [
|
|
|
32
35
|
};
|
|
33
36
|
},
|
|
34
37
|
},
|
|
38
|
+
{
|
|
39
|
+
id: 'vpn-config',
|
|
40
|
+
group: 'Network',
|
|
41
|
+
name: 'WireGuard config',
|
|
42
|
+
checking: 'the WireGuard config file',
|
|
43
|
+
applies: wireguardOn,
|
|
44
|
+
run: (env) => {
|
|
45
|
+
const problem = wireguardFileProblem(env.ctx.loaded.config.vpn.configFile, process.cwd());
|
|
46
|
+
return problem
|
|
47
|
+
? {
|
|
48
|
+
status: 'needs-you',
|
|
49
|
+
detail: problem,
|
|
50
|
+
means: 'The sandbox cannot start its VPN, so a launch stops.',
|
|
51
|
+
fix: 'Set vpn.configFile to a plain WireGuard .conf (no PostUp, PreUp or other script lines).',
|
|
52
|
+
}
|
|
53
|
+
: ok('readable and plain (keys are not shown)');
|
|
54
|
+
},
|
|
55
|
+
},
|
|
35
56
|
{
|
|
36
57
|
id: 'vpn-download',
|
|
37
58
|
group: 'Network',
|
|
38
|
-
name: '
|
|
39
|
-
checking: 'whether the
|
|
59
|
+
name: 'VPN download',
|
|
60
|
+
checking: 'whether the VPN software download can be reached',
|
|
40
61
|
applies: vpnOn,
|
|
41
62
|
timeoutMs: REACH_MS + 4000,
|
|
42
63
|
run: async (env) => {
|
|
43
|
-
|
|
44
|
-
|
|
64
|
+
const [name, base] = wireguard(env)
|
|
65
|
+
? ['WireGuard', WIREGUARD_MSI.base]
|
|
66
|
+
: ['OpenVPN', OPENVPN_MSI.base];
|
|
67
|
+
const host = new URL(base).host;
|
|
68
|
+
if (await env.system.reachable(base, REACH_MS))
|
|
69
|
+
return ok(host + ' answers');
|
|
45
70
|
return {
|
|
46
71
|
status: 'warn',
|
|
47
|
-
detail: '
|
|
48
|
-
means: 'The sandbox downloads
|
|
72
|
+
detail: host + ' did not answer within ' + REACH_MS / 1000 + ' seconds',
|
|
73
|
+
means: 'The sandbox downloads ' + name + ' there at its first VPN start (it is kept afterwards).',
|
|
49
74
|
fix: 'Check your internet connection or proxy, then run this again.',
|
|
50
75
|
};
|
|
51
76
|
},
|
|
@@ -6,6 +6,7 @@ import { WindowsProbe } from '../../../host/health/index.js';
|
|
|
6
6
|
import { InstallLayout, InstallRecordFile } from '../../../host/install/index.js';
|
|
7
7
|
import { MIGRATIONS } from '../../../host/migrate/index.js';
|
|
8
8
|
import { isSandboxRunning } from '../../../host/sandbox/index.js';
|
|
9
|
+
import { hostDataFolder } from '../../../host/storage/index.js';
|
|
9
10
|
import { gatherFacts } from '../setup/facts.js';
|
|
10
11
|
/** The settings file in use: --config, AGENT_SANDBOX_CONFIG, else the user's config.json. */
|
|
11
12
|
export function configFileOf(ctx) {
|
|
@@ -33,7 +34,7 @@ export function buildEnv(ctx, configError = null, system = new WindowsProbe()) {
|
|
|
33
34
|
running: isSandboxRunning(),
|
|
34
35
|
dataPath: ctx.dataPath,
|
|
35
36
|
storageRoot: ctx.storageRoot,
|
|
36
|
-
toolsDir:
|
|
37
|
+
toolsDir: hostDataFolder(ctx.dataPath, 'tools'),
|
|
37
38
|
configError: configProblem(ctx, configError),
|
|
38
39
|
layout,
|
|
39
40
|
record: layout ? new InstallRecordFile(layout.root).read() : null,
|
|
@@ -1,9 +1,5 @@
|
|
|
1
|
-
// Working with a running sandbox: attach
|
|
2
|
-
//
|
|
3
|
-
//
|
|
1
|
+
// Working with a running sandbox: attach and exec. Each knows which project you run it from (projects/here.ts): attach
|
|
2
|
+
// puts that project's sessions first, exec and db run in it. Status, sessions, restart, stop and show/hide are the
|
|
3
|
+
// shared core's (src/app/features/sandbox and sessions).
|
|
4
4
|
export * from './attach.js';
|
|
5
|
-
export * from './list.js';
|
|
6
|
-
export * from './status.js';
|
|
7
5
|
export * from './exec.js';
|
|
8
|
-
export * from './control.js';
|
|
9
|
-
export * from './window.js';
|
|
@@ -21,9 +21,12 @@ export interface SandboxView {
|
|
|
21
21
|
}
|
|
22
22
|
/** For status and sessions: they work for anyone, and say whose sandbox this is. */
|
|
23
23
|
export declare function lookAtSandbox(ctx: Context): SandboxView;
|
|
24
|
+
/** Asks for a typed confirmation ("Type alice to confirm"); true when it was typed. */
|
|
25
|
+
export type TypedConfirm = (prompt: string, expected: string) => Promise<boolean>;
|
|
24
26
|
/**
|
|
25
27
|
* For a command that acts on the running sandbox: refuses with the reason when this user may not, asks for the typed
|
|
26
|
-
* confirmation when the rule wants one (--yes in a script
|
|
28
|
+
* confirmation when the rule wants one (--yes in a script; `confirm` asks it, by default on the terminal), and returns
|
|
29
|
+
* the context to use.
|
|
27
30
|
*/
|
|
28
|
-
export declare function useSharedSandbox(ctx: Context, action: OwnerAction | ((shared: Context) => OwnerAction)): Promise<Context>;
|
|
31
|
+
export declare function useSharedSandbox(ctx: Context, action: OwnerAction | ((shared: Context) => OwnerAction), confirm?: TypedConfirm): Promise<Context>;
|
|
29
32
|
export {};
|
|
@@ -47,11 +47,18 @@ export function lookAtSandbox(ctx) {
|
|
|
47
47
|
return { ctx: borrowedContext(ctx, owner), line, limited: false, owner };
|
|
48
48
|
return { ctx, line, limited: owner.kind !== 'mine' && owner.kind !== 'none', owner };
|
|
49
49
|
}
|
|
50
|
+
/** On the terminal: no terminal fails and says how to do it in a script. */
|
|
51
|
+
const terminalTypedConfirm = async (prompt, expected) => {
|
|
52
|
+
if (!(process.stdin.isTTY && process.stdout.isTTY))
|
|
53
|
+
fail(prompt + ' It was not stopped.', 'In a script, add --yes to do it anyway.');
|
|
54
|
+
return askTyped(prompt, expected);
|
|
55
|
+
};
|
|
50
56
|
/**
|
|
51
57
|
* For a command that acts on the running sandbox: refuses with the reason when this user may not, asks for the typed
|
|
52
|
-
* confirmation when the rule wants one (--yes in a script
|
|
58
|
+
* confirmation when the rule wants one (--yes in a script; `confirm` asks it, by default on the terminal), and returns
|
|
59
|
+
* the context to use.
|
|
53
60
|
*/
|
|
54
|
-
export async function useSharedSandbox(ctx, action) {
|
|
61
|
+
export async function useSharedSandbox(ctx, action, confirm = terminalTypedConfirm) {
|
|
55
62
|
const owner = ownerNow();
|
|
56
63
|
if (!owner || owner.kind === 'mine' || owner.kind === 'none')
|
|
57
64
|
return ctx;
|
|
@@ -59,11 +66,7 @@ export async function useSharedSandbox(ctx, action) {
|
|
|
59
66
|
const rule = ownerRule(owner, typeof action === 'function' ? action(target) : action);
|
|
60
67
|
if (rule.kind === 'refuse')
|
|
61
68
|
return fail(rule.reason, rule.fix);
|
|
62
|
-
if (rule.kind === 'confirm' && !ctx.options.yes)
|
|
63
|
-
|
|
64
|
-
fail(rule.prompt + ' It was not stopped.', 'In a script, add --yes to do it anyway.');
|
|
65
|
-
if (!(await askTyped(rule.prompt, rule.expected)))
|
|
66
|
-
fail('Nothing changed.');
|
|
67
|
-
}
|
|
69
|
+
if (rule.kind === 'confirm' && !ctx.options.yes && !(await confirm(rule.prompt, rule.expected)))
|
|
70
|
+
fail('Nothing changed.');
|
|
68
71
|
return target;
|
|
69
72
|
}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
// `sandbox storage contained on|off|status` (beta): keep the data set's tools, state and logs in a
|
|
2
|
+
// disk image that is mounted only while a sandbox runs. The work is in host/storage/contained; this file asks, shows
|
|
3
|
+
// size and time, and prints.
|
|
4
|
+
import fs from 'node:fs';
|
|
5
|
+
import { userConfigPath } from '../../../core/config/index.js';
|
|
6
|
+
import { humanBytes } from '../../../core/disk.js';
|
|
7
|
+
import { askRequired } from '../../../core/prompt.js';
|
|
8
|
+
import { fail } from '../../../core/util/index.js';
|
|
9
|
+
import { isSandboxRunning, realContainedDeps } from '../../../host/sandbox/index.js';
|
|
10
|
+
import { assertTargetsFree, containedAvailability, ContainedStorage, describeDuration, describeSize, planTransfer, runTransfer, setStateOf, StateFile, writeContainedSetting, } from '../../../host/storage/index.js';
|
|
11
|
+
import { c, printJson, working } from '../../output/index.js';
|
|
12
|
+
const BETA = 'Beta, and not yet tested on a real PC. ';
|
|
13
|
+
function storageFor(ctx) {
|
|
14
|
+
const { config } = ctx.loaded;
|
|
15
|
+
return new ContainedStorage(realContainedDeps(ctx.storageRoot, config.storage.containedMaxGb), config.storage.dataName);
|
|
16
|
+
}
|
|
17
|
+
function requireAvailable() {
|
|
18
|
+
const check = containedAvailability();
|
|
19
|
+
if (!check.available)
|
|
20
|
+
fail('Contained storage cannot be used: ' + check.reasons.join(' '), check.fixes.join(' '));
|
|
21
|
+
}
|
|
22
|
+
function requireNoSandbox() {
|
|
23
|
+
if (isSandboxRunning())
|
|
24
|
+
fail('A sandbox is running.', 'Close it (sandbox stop) first: the folders in the image are in use.');
|
|
25
|
+
}
|
|
26
|
+
async function status(ctx) {
|
|
27
|
+
const storage = storageFor(ctx);
|
|
28
|
+
const check = containedAvailability();
|
|
29
|
+
const state = new StateFile(storage.paths).read();
|
|
30
|
+
const record = setStateOf(state, storage.set);
|
|
31
|
+
const reality = check.available && storage.imageExists() ? await storage.reality() : null;
|
|
32
|
+
const answer = {
|
|
33
|
+
setting: ctx.loaded.config.storage.contained,
|
|
34
|
+
maxGb: ctx.loaded.config.storage.containedMaxGb,
|
|
35
|
+
available: check.available,
|
|
36
|
+
reasons: check.reasons,
|
|
37
|
+
image: storage.paths.image,
|
|
38
|
+
imageExists: storage.imageExists(),
|
|
39
|
+
imageBytes: reality?.imageBytes ?? null,
|
|
40
|
+
mountFolder: storage.paths.mount,
|
|
41
|
+
recordedMounted: record.mounted,
|
|
42
|
+
holders: record.holders.length,
|
|
43
|
+
mountedNow: reality?.mountIsMountPoint ?? null,
|
|
44
|
+
};
|
|
45
|
+
if (printJson(ctx, answer))
|
|
46
|
+
return 0;
|
|
47
|
+
console.log(c.yellow('Contained storage (beta, untested on a real PC)'));
|
|
48
|
+
console.log(' setting: storage.contained = ' + answer.setting + ' (limit ' + answer.maxGb + ' GB)');
|
|
49
|
+
console.log(' this PC: ' +
|
|
50
|
+
(check.available ? 'can use it' : 'cannot use it: ' + check.reasons.join(' ') + ' ' + check.fixes.join(' ')));
|
|
51
|
+
console.log(' image: ' +
|
|
52
|
+
answer.image +
|
|
53
|
+
(answer.imageExists ? ' (' + humanBytes(answer.imageBytes ?? 0) + ' on disk)' : ' (not made yet)'));
|
|
54
|
+
console.log(' mount folder: ' + answer.mountFolder);
|
|
55
|
+
if (reality)
|
|
56
|
+
console.log(' mounted now: ' +
|
|
57
|
+
(reality.mountIsMountPoint ? 'yes' : 'no') +
|
|
58
|
+
(record.mounted !== reality.mountIsMountPoint
|
|
59
|
+
? ' (the record says ' + (record.mounted ? 'yes' : 'no') + '; sandbox doctor looks into it)'
|
|
60
|
+
: ''));
|
|
61
|
+
console.log('\nTurn it on with: sandbox storage contained on Turn it off with: sandbox storage contained off');
|
|
62
|
+
return 0;
|
|
63
|
+
}
|
|
64
|
+
function printPlan(plan, to) {
|
|
65
|
+
for (const f of plan.folders)
|
|
66
|
+
console.log(' ' + f.name + ': ' + describeSize(f.measured));
|
|
67
|
+
console.log(' total: ' + describeSize(plan.total) + ' to ' + to);
|
|
68
|
+
console.log(' time: about ' + describeDuration(plan.estimate.seconds) + ' (copied, then the originals are removed)');
|
|
69
|
+
if (!plan.estimate.fits)
|
|
70
|
+
fail('Not enough free space for the copy.', 'Free some space on that drive and try again.');
|
|
71
|
+
}
|
|
72
|
+
async function turnOn(ctx) {
|
|
73
|
+
requireAvailable();
|
|
74
|
+
requireNoSandbox();
|
|
75
|
+
const storage = storageFor(ctx);
|
|
76
|
+
const { config } = ctx.loaded;
|
|
77
|
+
const configFile = ctx.loaded.configPath ?? userConfigPath();
|
|
78
|
+
console.log(c.yellow(BETA + 'Contained storage keeps the sandbox tools, state and logs in one disk image file.'));
|
|
79
|
+
console.log(' image: ' + storage.paths.image + (storage.imageExists() ? ' (exists, it is used as it is)' : ''));
|
|
80
|
+
console.log(' limit: ' + config.storage.containedMaxGb + ' GB (storage.containedMaxGb; the file grows only as it fills)');
|
|
81
|
+
console.log(' Windows asks for permission to mount it each time a sandbox starts (and once when it closes).');
|
|
82
|
+
if (!ctx.options.yes &&
|
|
83
|
+
!(await askRequired('Turn contained storage on?', 'Add --yes to turn it on without asking.', true)))
|
|
84
|
+
return fail('Nothing was changed.', 'Run sandbox storage contained on when you want it.');
|
|
85
|
+
const mount = await working('Making and mounting the image (Windows asks for permission)', () => storage.acquire({ id: 'cli', pid: process.pid }, { create: true }));
|
|
86
|
+
try {
|
|
87
|
+
const plan = planTransfer(ctx.dataPath, mount, ctx.storageRoot);
|
|
88
|
+
if (plan.folders.length > 0) {
|
|
89
|
+
console.log('\nThese folders hold your tools, state and logs now:');
|
|
90
|
+
printPlan(plan, 'the image');
|
|
91
|
+
assertTargetsFree(plan);
|
|
92
|
+
const move = ctx.options.yes || (await askRequired('Move them into the image?', 'Add --yes to move without asking.', true));
|
|
93
|
+
if (move) {
|
|
94
|
+
let line = 'Copying';
|
|
95
|
+
const result = await working(() => line, () => runTransfer(plan, ctx.dataPath, (p) => {
|
|
96
|
+
line = 'Copying: ' + p.files.toLocaleString('en-US') + ' files, ' + humanBytes(p.bytes);
|
|
97
|
+
}));
|
|
98
|
+
console.log('Moved ' + result.files.toLocaleString('en-US') + ' files into the image.');
|
|
99
|
+
for (const note of result.notes)
|
|
100
|
+
console.log(c.yellow(note));
|
|
101
|
+
}
|
|
102
|
+
else
|
|
103
|
+
console.log('They stay where they are and are not used: tools are downloaded again into the image. Delete them later with sandbox data clean.');
|
|
104
|
+
}
|
|
105
|
+
writeContainedSetting(configFile, 'vhdx');
|
|
106
|
+
}
|
|
107
|
+
finally {
|
|
108
|
+
const done = await working('Dismounting the image (Windows asks for permission)', () => storage.release('cli'));
|
|
109
|
+
if (!done.dismounted)
|
|
110
|
+
console.log(c.yellow('The image stays mounted (' + (done.note ?? '') + '). sandbox repair dismounts it.'));
|
|
111
|
+
}
|
|
112
|
+
console.log('Contained storage is on. sandbox launch mounts the image first.');
|
|
113
|
+
return 0;
|
|
114
|
+
}
|
|
115
|
+
async function turnOff(ctx) {
|
|
116
|
+
requireAvailable();
|
|
117
|
+
requireNoSandbox();
|
|
118
|
+
const storage = storageFor(ctx);
|
|
119
|
+
const configFile = ctx.loaded.configPath ?? userConfigPath();
|
|
120
|
+
console.log(c.yellow(BETA + 'Turning contained storage off moves the files back into plain folders.'));
|
|
121
|
+
if (!storage.imageExists()) {
|
|
122
|
+
writeContainedSetting(configFile, 'off');
|
|
123
|
+
console.log('There is no image, so there was nothing to move. Contained storage is off.');
|
|
124
|
+
return 0;
|
|
125
|
+
}
|
|
126
|
+
const mount = await working('Mounting the image (Windows asks for permission)', () => storage.acquire({ id: 'cli', pid: process.pid }));
|
|
127
|
+
let moved = false;
|
|
128
|
+
try {
|
|
129
|
+
const plan = planTransfer(mount, ctx.dataPath, ctx.dataPath);
|
|
130
|
+
if (plan.folders.length > 0) {
|
|
131
|
+
console.log('\nIn the image:');
|
|
132
|
+
printPlan(plan, ctx.dataPath);
|
|
133
|
+
assertTargetsFree(plan);
|
|
134
|
+
if (!ctx.options.yes &&
|
|
135
|
+
!(await askRequired('Move them back out of the image?', 'Add --yes to move without asking.', true)))
|
|
136
|
+
return fail('Nothing was moved.', 'Contained storage is still on.');
|
|
137
|
+
let line = 'Copying';
|
|
138
|
+
const result = await working(() => line, () => runTransfer(plan, mount, (p) => {
|
|
139
|
+
line = 'Copying: ' + p.files.toLocaleString('en-US') + ' files, ' + humanBytes(p.bytes);
|
|
140
|
+
}));
|
|
141
|
+
console.log('Moved ' + result.files.toLocaleString('en-US') + ' files back.');
|
|
142
|
+
for (const note of result.notes)
|
|
143
|
+
console.log(c.yellow(note));
|
|
144
|
+
}
|
|
145
|
+
writeContainedSetting(configFile, 'off');
|
|
146
|
+
moved = true;
|
|
147
|
+
}
|
|
148
|
+
finally {
|
|
149
|
+
const done = await working('Dismounting the image (Windows asks for permission)', () => storage.release('cli'));
|
|
150
|
+
if (!done.dismounted)
|
|
151
|
+
console.log(c.yellow('The image stays mounted (' + (done.note ?? '') + '). sandbox repair dismounts it.'));
|
|
152
|
+
else if (!moved)
|
|
153
|
+
console.log('The image was dismounted; contained storage is still on.');
|
|
154
|
+
}
|
|
155
|
+
console.log('Contained storage is off: tools, state and logs are plain folders in ' + ctx.dataPath + '.');
|
|
156
|
+
const bytes = fs.statSync(storage.paths.image).size;
|
|
157
|
+
if (!ctx.options.yes &&
|
|
158
|
+
(await askRequired('Delete the image file now (' + humanBytes(bytes) + ')? Everything in it was moved out.', 'Answer no to keep it.', false))) {
|
|
159
|
+
await storage.deleteImage();
|
|
160
|
+
console.log('Deleted ' + storage.paths.image + '.');
|
|
161
|
+
}
|
|
162
|
+
else
|
|
163
|
+
console.log('The image file is kept: ' + storage.paths.image + ' (delete it yourself when you are sure).');
|
|
164
|
+
return 0;
|
|
165
|
+
}
|
|
166
|
+
/** `sandbox storage contained [status|on|off]`. */
|
|
167
|
+
export function contained(ctx) {
|
|
168
|
+
const [, mode = 'status'] = ctx.options.positionals;
|
|
169
|
+
switch (mode) {
|
|
170
|
+
case 'status':
|
|
171
|
+
return status(ctx);
|
|
172
|
+
case 'on':
|
|
173
|
+
return turnOn(ctx);
|
|
174
|
+
case 'off':
|
|
175
|
+
return turnOff(ctx);
|
|
176
|
+
default:
|
|
177
|
+
return Promise.resolve(fail('Unknown action "' + mode + '" for contained storage.', 'Use: sandbox storage contained on, off or status'));
|
|
178
|
+
}
|
|
179
|
+
}
|
|
@@ -5,7 +5,7 @@ import { userDir } from '../../../core/config/index.js';
|
|
|
5
5
|
import { errMsg } from '../../../core/util/index.js';
|
|
6
6
|
import { isSandboxRunning, insideSandbox } from '../../../host/sandbox/index.js';
|
|
7
7
|
import { protectPrivateFolder } from '../../../host/sharing/index.js';
|
|
8
|
-
import { describeDuration, describeSize, ensureStorageRoot, estimate, measureFolder, moveWarning, planOffer, StorageHistory, } from '../../../host/storage/index.js';
|
|
8
|
+
import { describeDuration, describeSize, ensureStorageRoot, estimate, measureFolder, moveWarning, planOffer, staleMountNote, StorageHistory, } from '../../../host/storage/index.js';
|
|
9
9
|
import { c, working } from '../../output/index.js';
|
|
10
10
|
import { refreshStorage } from '../context.js';
|
|
11
11
|
import { performMove } from './storage.js';
|
|
@@ -82,4 +82,10 @@ export async function storageBeforeCommand(ctx, command) {
|
|
|
82
82
|
}
|
|
83
83
|
}
|
|
84
84
|
ensureStorageRoot(ctx.storageRoot, protectPrivateFolder);
|
|
85
|
+
// Contained storage (beta): a mount an earlier sandbox left behind is only mentioned here; repair fixes it.
|
|
86
|
+
if (command !== 'launch' && !ctx.options.json) {
|
|
87
|
+
const stale = staleMountNote(ctx.storageRoot, ctx.loaded.config.storage.dataName, isSandboxRunning());
|
|
88
|
+
if (stale)
|
|
89
|
+
console.error(c.yellow(stale));
|
|
90
|
+
}
|
|
85
91
|
}
|
|
@@ -6,14 +6,20 @@ import { userConfigPath, userDir } from '../../../core/config/index.js';
|
|
|
6
6
|
import { diskUsage, humanBytes } from '../../../core/disk.js';
|
|
7
7
|
import { askChoice, askName, askRequired } from '../../../core/prompt.js';
|
|
8
8
|
import { expandPath, fail } from '../../../core/util/index.js';
|
|
9
|
-
import { describeDuration, describeSize, estimate, holdsData, measureFolder, moveWarning, otherDataFolders, sharedDefaultRoot, StorageHistory, StorageMove, } from '../../../host/storage/index.js';
|
|
9
|
+
import { describeDuration, describeSize, estimate, holdsData, measureFolder, mountedSets, moveWarning, otherDataFolders, sharedDefaultRoot, StorageHistory, StorageMove, } from '../../../host/storage/index.js';
|
|
10
10
|
import { isSandboxRunning } from '../../../host/sandbox/index.js';
|
|
11
11
|
import { protectPrivateFolder } from '../../../host/sharing/index.js';
|
|
12
12
|
import { watcherRunning } from '../../../sync/index.js';
|
|
13
13
|
import { printJson, working } from '../../output/index.js';
|
|
14
14
|
import { requireOnPc } from '../context.js';
|
|
15
|
+
import { contained } from './contained.js';
|
|
15
16
|
/** Why a move cannot start (a background sync is still on a data folder in the old storage), or null. */
|
|
16
17
|
export function storageBusy(root) {
|
|
18
|
+
const mounted = mountedSets(root);
|
|
19
|
+
if (mounted.length > 0)
|
|
20
|
+
return ('The contained storage of "' +
|
|
21
|
+
mounted.join('", "') +
|
|
22
|
+
'" is mounted (a disk image; moving now would reach into it).');
|
|
17
23
|
const data = path.join(root, 'data');
|
|
18
24
|
try {
|
|
19
25
|
for (const name of fs.readdirSync(data))
|
|
@@ -165,7 +171,9 @@ export function storage(ctx) {
|
|
|
165
171
|
return move(ctx);
|
|
166
172
|
case 'use':
|
|
167
173
|
return use(ctx);
|
|
174
|
+
case 'contained':
|
|
175
|
+
return contained(ctx);
|
|
168
176
|
default:
|
|
169
|
-
return fail('Unknown storage action "' + action + '".', 'Use: sandbox storage, sandbox storage move <folder
|
|
177
|
+
return fail('Unknown storage action "' + action + '".', 'Use: sandbox storage, sandbox storage move <folder>, sandbox storage use <folder> or sandbox storage contained on|off|status');
|
|
170
178
|
}
|
|
171
179
|
}
|
|
@@ -6,7 +6,7 @@ import { parse } from 'jsonc-parser';
|
|
|
6
6
|
import _ from 'lodash';
|
|
7
7
|
import { userConfigPath } from '../../core/config/index.js';
|
|
8
8
|
import { fail } from '../../core/util/index.js';
|
|
9
|
-
import { editConfigText } from '
|
|
9
|
+
import { editConfigText } from '../../app/features/settings/index.js';
|
|
10
10
|
export function configFile(ctx) {
|
|
11
11
|
return ctx.loaded.configPath ?? userConfigPath();
|
|
12
12
|
}
|
package/dist/cli/commands/vpn.js
CHANGED
|
@@ -21,14 +21,26 @@ async function status(ctx) {
|
|
|
21
21
|
return 0;
|
|
22
22
|
table([
|
|
23
23
|
['VPN', report.enabled ? c.green('on') : 'off (turn on: sandbox config set vpn.enabled true)'],
|
|
24
|
-
[
|
|
24
|
+
[
|
|
25
|
+
'Provider',
|
|
26
|
+
report.provider === 'nordvpn'
|
|
27
|
+
? 'NordVPN'
|
|
28
|
+
: report.provider === 'wireguard-file'
|
|
29
|
+
? 'your own WireGuard .conf'
|
|
30
|
+
: 'your own .ovpn file',
|
|
31
|
+
],
|
|
25
32
|
['Protocol', report.protocol],
|
|
26
33
|
['Country', report.country || 'best available'],
|
|
27
34
|
['Kill switch', report.killSwitch ? 'on (no internet if the tunnel fails)' : c.yellow('off')],
|
|
28
|
-
[
|
|
35
|
+
[
|
|
36
|
+
'Login',
|
|
37
|
+
report.provider === 'wireguard-file'
|
|
38
|
+
? c.dim('not needed (the keys are in your config)')
|
|
39
|
+
: LOGIN_TEXT[report.login] + (report.loginSavedAt ? c.dim(' ' + report.loginSavedAt.slice(0, 10)) : ''),
|
|
40
|
+
],
|
|
29
41
|
...(report.running ? [['Running now', report.running.text]] : []),
|
|
30
42
|
]);
|
|
31
|
-
if (report.login === 'none')
|
|
43
|
+
if (report.provider !== 'wireguard-file' && report.login === 'none')
|
|
32
44
|
nextStep('sandbox vpn login');
|
|
33
45
|
if (report.login === 'unreadable')
|
|
34
46
|
console.log(c.dim('Only the Windows user that saved it can read it. Save it again: sandbox vpn login'));
|
|
@@ -39,6 +51,10 @@ async function status(ctx) {
|
|
|
39
51
|
async function login(ctx) {
|
|
40
52
|
requireOnPc('vpn login');
|
|
41
53
|
const service = new VpnService(ctx);
|
|
54
|
+
if (service.provider === 'wireguard-file') {
|
|
55
|
+
console.log('A WireGuard config needs no login: the keys are in the file vpn.configFile points to.');
|
|
56
|
+
return 0;
|
|
57
|
+
}
|
|
42
58
|
const nord = service.provider === 'nordvpn';
|
|
43
59
|
console.log(nord
|
|
44
60
|
? 'NordVPN needs its service credentials, not your usual login. To get them:'
|
package/dist/cli/commands/web.js
CHANGED
|
@@ -6,6 +6,7 @@ import { fail, sleep } from '../../core/util/index.js';
|
|
|
6
6
|
import { spawnDetached } from '../../host/sandbox/index.js';
|
|
7
7
|
import { openBrowser, WebControl, WebRunner, WebStore } from '../../host/web/index.js';
|
|
8
8
|
import { printJson } from '../output/index.js';
|
|
9
|
+
import { createRpcHost } from '../../app/registry.js';
|
|
9
10
|
import { WebService } from '../services/index.js';
|
|
10
11
|
import { requireOnPc } from './context.js';
|
|
11
12
|
const START_WAIT_MS = 15000;
|
|
@@ -89,6 +90,7 @@ export async function webServer(ctx) {
|
|
|
89
90
|
storageRoot: ctx.storageRoot,
|
|
90
91
|
port: ctx.loaded.config.web.port,
|
|
91
92
|
backend: new WebService(ctx),
|
|
93
|
+
rpc: createRpcHost(ctx),
|
|
92
94
|
staticRoot,
|
|
93
95
|
}).run();
|
|
94
96
|
process.exit(0);
|
package/dist/cli/index.js
CHANGED
|
@@ -15,6 +15,7 @@ import { withConfig, hoistConfig, withoutConfig } from './argv.js';
|
|
|
15
15
|
import { report } from './report.js';
|
|
16
16
|
import { versionText } from './version.js';
|
|
17
17
|
import { HANDLERS } from './commands/index.js';
|
|
18
|
+
import { operationHandler } from './operations/index.js';
|
|
18
19
|
const entry = path.join(PACKAGE_ROOT, 'dist', 'bin', 'agent-sandbox.js');
|
|
19
20
|
/** A first word that is no command and no agent, but close to one: "Did you mean: sandbox status?". */
|
|
20
21
|
function failOnTypo(word, agents) {
|
|
@@ -103,7 +104,7 @@ export async function main(rawArgv, preset = {}) {
|
|
|
103
104
|
// update works on the install, not on a sandbox: it needs no settings (and a broken file must not stop it).
|
|
104
105
|
if (options.command === 'update')
|
|
105
106
|
return commands.update(options);
|
|
106
|
-
const handler = HANDLERS[options.command];
|
|
107
|
+
const handler = operationHandler(options.command, options.positionals) ?? HANDLERS[options.command];
|
|
107
108
|
if (!handler)
|
|
108
109
|
return fail('Unknown command "' + options.command + '".', 'Run sandbox --help for the list of commands, or sandbox for the menu.');
|
|
109
110
|
const ctx = commands.createContext(PACKAGE_ROOT, entry, options);
|