windows-development-sandbox 1.10.0 → 1.11.3
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 +64 -17
- package/config.example.json +5 -1
- package/dist/app/features/accounts/accounts.def.d.ts +122 -0
- package/dist/app/features/accounts/accounts.def.js +243 -0
- package/dist/app/features/accounts/accounts.run.d.ts +51 -0
- package/dist/app/features/accounts/accounts.run.js +125 -0
- package/dist/app/features/accounts/index.d.ts +2 -0
- package/dist/app/features/accounts/index.js +3 -0
- package/dist/app/features/agents/agent-entry.d.ts +17 -0
- package/dist/app/features/agents/agent-entry.js +50 -0
- package/dist/app/features/agents/agents.def.d.ts +65 -0
- package/dist/app/features/agents/agents.def.js +142 -0
- package/dist/app/features/agents/agents.run.d.ts +31 -0
- package/dist/app/features/agents/agents.run.js +189 -0
- package/dist/app/features/agents/index.d.ts +3 -0
- package/dist/app/features/agents/index.js +4 -0
- package/dist/app/features/apps/apps-rows.d.ts +31 -0
- package/dist/app/features/apps/apps-rows.js +73 -0
- package/dist/app/features/apps/apps.def.d.ts +181 -0
- package/dist/app/features/apps/apps.def.js +264 -0
- package/dist/app/features/apps/apps.run.d.ts +58 -0
- package/dist/app/features/apps/apps.run.js +76 -0
- package/dist/app/features/apps/index.d.ts +3 -0
- package/dist/app/features/apps/index.js +4 -0
- package/dist/app/features/data/data.def.d.ts +154 -0
- package/dist/app/features/data/data.def.js +201 -0
- package/dist/app/features/data/data.run.d.ts +46 -0
- package/dist/app/features/data/data.run.js +141 -0
- package/dist/app/features/data/index.d.ts +2 -0
- package/dist/app/features/data/index.js +3 -0
- package/dist/app/features/defs.d.ts +952 -4
- package/dist/app/features/defs.js +147 -10
- package/dist/app/features/engine/engine.def.d.ts +228 -0
- package/dist/app/features/engine/engine.def.js +194 -0
- package/dist/app/features/engine/engine.run.d.ts +72 -0
- package/dist/app/features/engine/engine.run.js +77 -0
- package/dist/app/features/engine/index.d.ts +2 -0
- package/dist/app/features/engine/index.js +4 -0
- package/dist/app/features/files/files.def.d.ts +51 -0
- package/dist/app/features/files/files.def.js +38 -0
- package/dist/app/features/files/files.run.d.ts +20 -0
- package/dist/app/features/files/files.run.js +59 -0
- package/dist/app/features/files/index.d.ts +2 -0
- package/dist/app/features/files/index.js +3 -0
- package/dist/app/features/github/github.def.d.ts +80 -0
- package/dist/app/features/github/github.def.js +142 -0
- package/dist/app/features/github/github.run.d.ts +36 -0
- package/dist/app/features/github/github.run.js +59 -0
- package/dist/app/features/github/index.d.ts +2 -0
- package/dist/app/features/github/index.js +3 -0
- package/dist/app/features/health/health.def.d.ts +275 -0
- package/dist/app/features/health/health.def.js +281 -0
- package/dist/app/features/health/health.run.d.ts +125 -0
- package/dist/app/features/health/health.run.js +204 -0
- package/dist/app/features/health/index.d.ts +2 -0
- package/dist/app/features/health/index.js +3 -0
- package/dist/app/features/logs/index.d.ts +2 -0
- package/dist/app/features/logs/index.js +3 -0
- package/dist/app/features/logs/logs.def.d.ts +78 -0
- package/dist/app/features/logs/logs.def.js +115 -0
- package/dist/app/features/logs/logs.run.d.ts +20 -0
- package/dist/app/features/logs/logs.run.js +42 -0
- package/dist/app/features/projects/index.d.ts +2 -0
- package/dist/app/features/projects/index.js +3 -0
- package/dist/app/features/projects/projects.def.d.ts +101 -0
- package/dist/app/features/projects/projects.def.js +208 -0
- package/dist/app/features/projects/projects.run.d.ts +56 -0
- package/dist/app/features/projects/projects.run.js +155 -0
- package/dist/app/features/sandbox/sandbox.def.js +11 -5
- package/dist/app/features/sessions/sessions.def.js +3 -0
- package/dist/app/features/settings/categories.def.js +3 -2
- package/dist/{cli/menu/settings/share.d.ts → app/features/settings/settings-share.d.ts} +1 -1
- package/dist/{cli/menu/settings/share.js → app/features/settings/settings-share.js} +3 -2
- package/dist/app/features/settings/settings.def.d.ts +22 -5
- package/dist/app/features/settings/settings.def.js +81 -6
- package/dist/app/features/settings/settings.run.d.ts +17 -0
- package/dist/app/features/settings/settings.run.js +89 -4
- package/dist/app/features/storage/index.d.ts +2 -0
- package/dist/app/features/storage/index.js +3 -0
- package/dist/app/features/storage/storage.def.d.ts +133 -0
- package/dist/app/features/storage/storage.def.js +225 -0
- package/dist/app/features/storage/storage.run.d.ts +62 -0
- package/dist/app/features/storage/storage.run.js +370 -0
- package/dist/app/features/updates/index.d.ts +3 -0
- package/dist/app/features/updates/index.js +4 -0
- package/dist/app/features/updates/update-lines.d.ts +13 -0
- package/dist/app/features/updates/update-lines.js +61 -0
- package/dist/app/features/updates/updates.def.d.ts +89 -0
- package/dist/app/features/updates/updates.def.js +225 -0
- package/dist/app/features/updates/updates.run.d.ts +48 -0
- package/dist/app/features/updates/updates.run.js +154 -0
- package/dist/app/features/vpn/index.d.ts +2 -0
- package/dist/app/features/vpn/index.js +3 -0
- package/dist/app/features/vpn/vpn.def.d.ts +112 -0
- package/dist/app/features/vpn/vpn.def.js +174 -0
- package/dist/app/features/vpn/vpn.run.d.ts +37 -0
- package/dist/app/features/vpn/vpn.run.js +54 -0
- package/dist/app/features/web/index.d.ts +2 -0
- package/dist/app/features/web/index.js +3 -0
- package/dist/app/features/web/web.def.d.ts +33 -0
- package/dist/app/features/web/web.def.js +90 -0
- package/dist/app/features/web/web.run.d.ts +24 -0
- package/dist/app/features/web/web.run.js +93 -0
- package/dist/app/kernel/define.d.ts +10 -1
- package/dist/app/kernel/io.d.ts +34 -0
- package/dist/app/kernel/io.js +9 -0
- package/dist/app/kernel/rpc.d.ts +17 -0
- package/dist/app/kernel/text.d.ts +2 -0
- package/dist/app/kernel/text.js +7 -0
- package/dist/app/kernel/view.d.ts +24 -1
- package/dist/app/kernel/view.js +1 -1
- package/dist/app/registry.js +74 -1
- package/dist/cli/args.js +1 -1
- package/dist/cli/commands/context.d.ts +7 -0
- package/dist/cli/commands/context.js +29 -2
- package/dist/cli/commands/engine.js +5 -58
- package/dist/cli/commands/github.d.ts +2 -0
- package/dist/cli/commands/github.js +11 -0
- package/dist/cli/commands/index.d.ts +3 -5
- package/dist/cli/commands/index.js +3 -5
- package/dist/cli/commands/launch/launch.js +21 -4
- package/dist/cli/commands/launch/running.js +4 -1
- package/dist/cli/commands/maintenance/config.js +1 -6
- package/dist/cli/commands/maintenance/index.d.ts +0 -1
- package/dist/cli/commands/maintenance/index.js +1 -2
- package/dist/cli/commands/maintenance/logs.js +27 -32
- package/dist/cli/commands/maintenance/migrate.d.ts +0 -8
- package/dist/cli/commands/maintenance/migrate.js +2 -44
- package/dist/cli/commands/maintenance/update.d.ts +0 -19
- package/dist/cli/commands/maintenance/update.js +1 -99
- package/dist/cli/commands/projects/index.d.ts +0 -1
- package/dist/cli/commands/projects/index.js +0 -1
- package/dist/cli/commands/registry.d.ts +1 -1
- package/dist/cli/commands/registry.js +29 -11
- package/dist/cli/commands/repair/checks/data.js +1 -1
- package/dist/cli/commands/repair/checks/hcs.js +28 -1
- package/dist/cli/commands/repair/checks/sandbox.js +1 -1
- package/dist/cli/commands/repair/health-run.d.ts +30 -0
- package/dist/cli/commands/repair/health-run.js +32 -0
- package/dist/cli/commands/repair/printer.d.ts +2 -2
- package/dist/cli/commands/repair/printer.js +2 -11
- package/dist/cli/commands/repair/run.d.ts +1 -21
- package/dist/cli/commands/repair/run.js +13 -70
- package/dist/cli/commands/storage/index.d.ts +0 -1
- package/dist/cli/commands/storage/index.js +0 -1
- package/dist/cli/commands/storage/offer.js +6 -2
- package/dist/cli/commands/vpn.d.ts +1 -3
- package/dist/cli/commands/vpn.js +8 -89
- package/dist/cli/commands/web.d.ts +2 -1
- package/dist/cli/commands/web.js +14 -78
- package/dist/cli/index.js +3 -2
- package/dist/cli/manifest.d.ts +16 -153
- package/dist/cli/manifest.js +20 -50
- package/dist/cli/menu/command-form.js +1 -2
- package/dist/cli/menu/io-menu.d.ts +2 -2
- package/dist/cli/menu/io-menu.js +6 -4
- package/dist/cli/menu/menu.js +1 -1
- package/dist/cli/menu/pages/accounts-page.d.ts +5 -17
- package/dist/cli/menu/pages/accounts-page.js +28 -170
- package/dist/cli/menu/pages/agents-page.d.ts +17 -18
- package/dist/cli/menu/pages/agents-page.js +67 -124
- package/dist/cli/menu/pages/apps-page.d.ts +15 -8
- package/dist/cli/menu/pages/apps-page.js +121 -29
- package/dist/cli/menu/pages/list-page.js +10 -1
- package/dist/cli/menu/pages/maintenance-page.d.ts +51 -52
- package/dist/cli/menu/pages/maintenance-page.js +246 -427
- package/dist/cli/menu/pages/sandbox-page.d.ts +3 -5
- package/dist/cli/menu/pages/sandbox-page.js +34 -112
- package/dist/cli/menu/pages/settings-page.d.ts +21 -3
- package/dist/cli/menu/pages/settings-page.js +89 -17
- package/dist/cli/menu/render-view.js +2 -1
- package/dist/cli/menu/settings/index.d.ts +0 -1
- package/dist/cli/menu/settings/index.js +3 -3
- package/dist/cli/menu/views.js +28 -0
- package/dist/cli/operations/handler.js +7 -3
- package/dist/cli/operations/input.d.ts +1 -1
- package/dist/cli/operations/input.js +29 -5
- package/dist/cli/operations/io-cli.js +9 -1
- package/dist/cli/operations/spec.js +8 -2
- package/dist/cli/output/render-view.js +2 -0
- package/dist/cli/{commands/data/collect.js → services/data-collect.js} +2 -2
- package/dist/cli/{commands/data/remove.js → services/data-remove.js} +2 -2
- package/dist/cli/services/data-service.d.ts +1 -1
- package/dist/cli/services/data-service.js +2 -2
- package/dist/cli/services/databases-service.d.ts +5 -0
- package/dist/cli/services/databases-service.js +15 -0
- package/dist/cli/services/health-service.d.ts +8 -4
- package/dist/cli/services/health-service.js +10 -8
- package/dist/cli/services/index.d.ts +4 -1
- package/dist/cli/services/index.js +4 -1
- package/dist/cli/services/logs-service.d.ts +7 -0
- package/dist/cli/services/logs-service.js +13 -0
- package/dist/cli/services/storage-service.d.ts +19 -0
- package/dist/cli/services/storage-service.js +71 -0
- package/dist/cli/services/vpn-service.d.ts +6 -4
- package/dist/cli/services/vpn-service.js +5 -11
- package/dist/cli/services/web-service.d.ts +4 -3
- package/dist/cli/services/web-service.js +12 -32
- package/dist/core/config/defaults.js +2 -1
- package/dist/core/schema/config.d.ts +5 -0
- package/dist/core/schema/config.js +2 -0
- package/dist/core/schema/github.d.ts +4 -0
- package/dist/core/schema/github.js +7 -0
- package/dist/core/schema/index.d.ts +1 -0
- package/dist/core/schema/index.js +1 -0
- package/dist/core/schema/profile.d.ts +1 -0
- package/dist/core/schema/profile.js +3 -0
- package/dist/core/schema/sandbox.js +3 -3
- package/dist/core/schema/toolchains.js +2 -2
- package/dist/core/types.d.ts +6 -3
- package/dist/guest/boot/boot.js +8 -0
- package/dist/guest/daemon/daemon.js +1 -1
- package/dist/guest/daemon/sessions.d.ts +3 -2
- package/dist/guest/daemon/sessions.js +38 -7
- package/dist/guest/governor/core.d.ts +44 -0
- package/dist/guest/governor/core.js +124 -0
- package/dist/guest/governor/decide.d.ts +46 -18
- package/dist/guest/governor/decide.js +136 -82
- package/dist/guest/governor/governor.d.ts +2 -38
- package/dist/guest/governor/governor.js +33 -113
- package/dist/guest/governor/index.d.ts +1 -0
- package/dist/guest/governor/index.js +1 -0
- package/dist/guest/network/firewall.d.ts +2 -0
- package/dist/guest/network/firewall.js +3 -3
- package/dist/guest/sessions/viewer.js +5 -1
- package/dist/guest/setup/github-token.d.ts +7 -0
- package/dist/guest/setup/github-token.js +65 -0
- package/dist/guest/toolchains/languages/node.js +11 -1
- package/dist/guest/toolchains/native/rust-extras.js +2 -2
- package/dist/guest/toolchains/tools/cli.d.ts +8 -0
- package/dist/guest/toolchains/tools/cli.js +16 -2
- package/dist/guest/vpn/openvpn.d.ts +5 -0
- package/dist/guest/vpn/openvpn.js +14 -1
- package/dist/guest/vpn/vpn.js +55 -16
- package/dist/guest/vpn/wireguard.js +2 -0
- package/dist/host/channel/attach.d.ts +1 -0
- package/dist/host/channel/attach.js +1 -0
- package/dist/host/channel/channel.d.ts +1 -1
- package/dist/host/channel/channel.js +2 -2
- package/dist/host/engines/hcs/check.d.ts +1 -0
- package/dist/host/engines/hcs/check.js +1 -1
- package/dist/host/engines/hcs/engine.d.ts +1 -1
- package/dist/host/engines/hcs/engine.js +6 -4
- package/dist/host/engines/hcs/helper.d.ts +11 -0
- package/dist/host/engines/hcs/helper.js +31 -2
- package/dist/host/engines/hcs/leftovers.d.ts +42 -0
- package/dist/host/engines/hcs/leftovers.js +101 -0
- package/dist/host/engines/index.d.ts +1 -0
- package/dist/host/engines/index.js +1 -0
- package/dist/host/github/deliver.d.ts +13 -0
- package/dist/host/github/deliver.js +51 -0
- package/dist/host/github/index.d.ts +2 -0
- package/dist/host/github/index.js +3 -0
- package/dist/host/github/token.d.ts +21 -0
- package/dist/host/github/token.js +74 -0
- package/dist/host/launch/generate.js +11 -5
- package/dist/host/launch/index.d.ts +1 -1
- package/dist/host/launch/index.js +1 -1
- package/dist/host/launch/session-file.js +1 -2
- package/dist/host/launch/wsb-file.d.ts +11 -7
- package/dist/host/launch/wsb-file.js +30 -12
- package/dist/host/life/watchdog.d.ts +9 -0
- package/dist/host/life/watchdog.js +17 -1
- package/dist/host/sandbox/tasklist.d.ts +6 -0
- package/dist/host/sandbox/tasklist.js +37 -0
- package/dist/host/secrets/launch-secrets.d.ts +2 -1
- package/dist/host/secrets/launch-secrets.js +4 -2
- package/dist/host/vpn/status.js +13 -3
- package/dist/host/web/backend.d.ts +1 -3
- package/dist/host/web/index.d.ts +2 -1
- package/dist/host/web/index.js +2 -1
- package/dist/host/web/live.d.ts +23 -0
- package/dist/host/web/live.js +107 -0
- package/dist/host/web/rpc.d.ts +6 -1
- package/dist/host/web/rpc.js +23 -31
- package/dist/host/web/runner.d.ts +4 -0
- package/dist/host/web/runner.js +12 -1
- package/dist/host/web/server.d.ts +30 -2
- package/dist/host/web/server.js +87 -29
- package/dist/host/web/state.d.ts +1 -0
- package/dist/host/web/state.js +2 -0
- package/dist/runtime/agent.js +30 -6
- package/dist/runtime/daemon.js +323 -176
- package/dist/runtime/db.js +30 -6
- package/dist/runtime/main.js +375 -76
- package/dist/runtime/netproxy.js +30 -6
- package/dist/runtime/view.js +495 -146
- package/dist/selftest/app.test.js +620 -12
- package/dist/selftest/channel.test.js +18 -1
- package/dist/selftest/cli.test.js +1 -1
- package/dist/selftest/config.test.js +1 -1
- package/dist/selftest/contained.test.js +1 -1
- package/dist/selftest/data.test.js +1 -2
- package/dist/selftest/engine.test.js +3 -1
- package/dist/selftest/github.test.d.ts +2 -0
- package/dist/selftest/github.test.js +243 -0
- package/dist/selftest/hcs.test.js +105 -8
- package/dist/selftest/health.test.js +71 -0
- package/dist/selftest/heavy-load.test.js +132 -72
- package/dist/selftest/index.js +4 -0
- package/dist/selftest/layout.test.js +8 -0
- package/dist/selftest/live-terminal.test.js +74 -0
- package/dist/selftest/menu-screens.js +171 -56
- package/dist/selftest/menu.test.js +54 -37
- package/dist/selftest/migrate.test.js +14 -12
- package/dist/selftest/powershell-variables.test.d.ts +2 -0
- package/dist/selftest/powershell-variables.test.js +61 -0
- package/dist/selftest/support/engine-golden.js +1 -0
- package/dist/selftest/support/fixtures.d.ts +4 -0
- package/dist/selftest/support/web-preview.d.ts +1 -0
- package/dist/selftest/support/web-preview.js +856 -0
- package/dist/selftest/update-service.test.js +15 -8
- package/dist/selftest/vpn.test.js +86 -2
- package/dist/selftest/web.test.js +58 -11
- package/dist/shared/channel/run-dir.d.ts +2 -0
- package/dist/shared/channel/run-dir.js +3 -0
- package/dist/shared/channel/schema.d.ts +7 -0
- package/dist/shared/channel/schema.js +9 -1
- package/dist/shared/channel/secrets.d.ts +1 -0
- package/dist/shared/channel/secrets.js +3 -0
- package/dist/shared/github/index.d.ts +1 -0
- package/dist/shared/github/index.js +2 -0
- package/dist/shared/github/token.d.ts +29 -0
- package/dist/shared/github/token.js +89 -0
- package/dist/shared/memory/policy.d.ts +33 -12
- package/dist/shared/memory/policy.js +50 -19
- package/dist/shared/pty/ctrl-c.d.ts +18 -0
- package/dist/shared/pty/ctrl-c.js +36 -0
- package/dist/shared/pty/index.d.ts +1 -0
- package/dist/shared/pty/index.js +1 -0
- package/dist/shared/pty/terminal.d.ts +2 -0
- package/dist/shared/pty/terminal.js +21 -2
- package/dist/shared/vpn/kill-switch.d.ts +13 -2
- package/dist/shared/vpn/kill-switch.js +88 -8
- package/dist/shared/web/protocol.d.ts +0 -4
- package/dist/sync/watcher.js +1 -1
- package/dist/web/index.html +2 -2
- package/dist/web/{main-T5DMCHYV.css → main-6JF3ASB5.css} +1 -1
- package/dist/web/main-Z645W45E.js +219 -0
- package/native/csharp/HcsHost/AssemblyInfo.cs +3 -3
- package/native/csharp/HostTools/AssemblyInfo.cs +3 -3
- package/package.json +10 -3
- package/sandbox/csharp/MemGov.cs +240 -38
- package/sandbox/csharp/PtyHost.cs +104 -15
- package/sandbox/csharp/SandboxTools/CpuCap.cs +50 -1
- package/sandbox/csharp/SandboxTools/Program.cs +1 -1
- package/sandbox/scripts/repair-wmi-services.ps1 +26 -0
- package/schemas/config.schema.json +19 -5
- package/schemas/sandbox-config.schema.json +7 -3
- package/dist/cli/commands/accounts.d.ts +0 -2
- package/dist/cli/commands/accounts.js +0 -96
- package/dist/cli/commands/data/clean.d.ts +0 -3
- package/dist/cli/commands/data/clean.js +0 -60
- package/dist/cli/commands/data/index.d.ts +0 -4
- package/dist/cli/commands/data/index.js +0 -62
- package/dist/cli/commands/maintenance/clean.d.ts +0 -2
- package/dist/cli/commands/maintenance/clean.js +0 -24
- package/dist/cli/commands/maintenance/config-share.d.ts +0 -12
- package/dist/cli/commands/maintenance/config-share.js +0 -80
- package/dist/cli/commands/projects/projects.d.ts +0 -2
- package/dist/cli/commands/projects/projects.js +0 -162
- package/dist/cli/commands/storage/contained.d.ts +0 -3
- package/dist/cli/commands/storage/contained.js +0 -179
- package/dist/cli/commands/storage/storage.d.ts +0 -8
- package/dist/cli/commands/storage/storage.js +0 -179
- package/dist/cli/menu/add-agent.d.ts +0 -47
- package/dist/cli/menu/add-agent.js +0 -168
- package/dist/cli/menu/apps.d.ts +0 -69
- package/dist/cli/menu/apps.js +0 -214
- package/dist/cli/menu/data-folder.d.ts +0 -18
- package/dist/cli/menu/data-folder.js +0 -99
- package/dist/cli/menu/share-settings.d.ts +0 -21
- package/dist/cli/menu/share-settings.js +0 -112
- package/dist/cli/menu/vpn-login.d.ts +0 -16
- package/dist/cli/menu/vpn-login.js +0 -74
- package/dist/web/main-NRRS5O6Z.js +0 -157
- /package/dist/cli/{commands/data/collect.d.ts → services/data-collect.d.ts} +0 -0
- /package/dist/cli/{commands/data/remove.d.ts → services/data-remove.d.ts} +0 -0
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
// Section 7: keeping things in shape. Updates (the program and your saved settings), Data & storage (the data folder,
|
|
2
2
|
// what is stored, clean-up), Health (doctor, repair and this PC's setup together), the logs, and the less common
|
|
3
3
|
// commands. Each is a category on the left and loads when you open it.
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
4
|
+
import { dataPage, showData } from '../../../app/features/data/index.js';
|
|
5
|
+
import { readQuery } from '../../../app/registry.js';
|
|
6
|
+
import { errMsg } from '../../../core/util/index.js';
|
|
7
|
+
import { enginePage, engineLeftovers, engineStatus, } from '../../../app/features/engine/index.js';
|
|
8
|
+
import { healthPage, lastHealth } from '../../../app/features/health/index.js';
|
|
9
|
+
import { containedStatus, showStorage, storagePage, } from '../../../app/features/storage/index.js';
|
|
10
|
+
import { CRASH, listLogs, logsPage } from '../../../app/features/logs/index.js';
|
|
11
|
+
import { updatesPage, updatesStatus } from '../../../app/features/updates/updates.def.js';
|
|
12
|
+
import { webPage, webStatus } from '../../../app/features/web/index.js';
|
|
9
13
|
import { commandSpec } from '../../manifest.js';
|
|
10
|
-
import { ago } from '../../output/index.js';
|
|
11
|
-
import { DataService, HealthService, LogsService, MigrateService, NPM_UPDATE_COMMAND, UpdateService, } from '../../services/index.js';
|
|
12
|
-
import { describeResult } from '../../commands/maintenance/update.js';
|
|
13
14
|
import { Text, Theme, } from '../../tui/index.js';
|
|
14
15
|
import { CommandForm } from '../command-form.js';
|
|
15
|
-
import {
|
|
16
|
+
import { MenuOperations } from '../io-menu.js';
|
|
17
|
+
import { menuView } from '../render-view.js';
|
|
16
18
|
import { ListPage } from './list-page.js';
|
|
17
19
|
const CATEGORIES = [
|
|
18
20
|
{
|
|
@@ -31,9 +33,22 @@ const CATEGORIES = [
|
|
|
31
33
|
description: 'Checks this PC and your settings, repairs problems, and sets up Windows Sandbox.',
|
|
32
34
|
},
|
|
33
35
|
{ id: 'logs', label: 'Logs', description: "The sandbox's own logs." },
|
|
36
|
+
{
|
|
37
|
+
id: 'web',
|
|
38
|
+
label: 'Web UI',
|
|
39
|
+
description: 'The web UI server on this PC: start it, open it in your browser, stop it.',
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
id: 'engine',
|
|
43
|
+
label: 'Engine',
|
|
44
|
+
description: 'What runs your sandbox, and what each engine can do on this PC.',
|
|
45
|
+
},
|
|
34
46
|
{ id: 'more', label: 'More commands', description: 'Less common commands.' },
|
|
35
47
|
];
|
|
36
48
|
const MORE_COMMANDS = ['sync', 'audit', 'config', 'generate', 'exec', 'agent-commands'];
|
|
49
|
+
const NO_LOGS = { folder: '', files: [], crash: false };
|
|
50
|
+
/** Until the status is read: the server counts as not running. */
|
|
51
|
+
const NO_WEB = { running: false, port: null, address: null };
|
|
37
52
|
/** Plain names for the commands under More commands. */
|
|
38
53
|
const MORE_LABELS = {
|
|
39
54
|
sync: 'Copy history back now',
|
|
@@ -43,33 +58,21 @@ const MORE_LABELS = {
|
|
|
43
58
|
exec: 'Run a command in the sandbox',
|
|
44
59
|
'agent-commands': 'Agent commands (Beta)',
|
|
45
60
|
};
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
state: 'Agent state',
|
|
57
|
-
logs: 'Logs',
|
|
58
|
-
data: 'Other',
|
|
59
|
-
host: 'On this PC',
|
|
60
|
-
};
|
|
61
|
+
/** The Data & storage category's rows and keys once measured: the data view (src/app/features/data) as menu rows. */
|
|
62
|
+
function dataMenuView(data) {
|
|
63
|
+
return data ? menuView(dataPage(data), { category: 'data', prefix: 'data:', refresh: false }) : undefined;
|
|
64
|
+
}
|
|
65
|
+
/** The storage view (the data folder, contained storage) as menu rows, drawn above the data rows. */
|
|
66
|
+
function storageMenu(s) {
|
|
67
|
+
return s
|
|
68
|
+
? menuView(storagePage(s.show, s.contained), { category: 'data', prefix: 'storage:', refresh: false })
|
|
69
|
+
: undefined;
|
|
70
|
+
}
|
|
61
71
|
function dataItems(m) {
|
|
62
|
-
const
|
|
63
|
-
const clean = {
|
|
64
|
-
value: 'data:clean',
|
|
65
|
-
label: 'Clean up…',
|
|
66
|
-
category: 'data',
|
|
67
|
-
section: 'Clean up',
|
|
68
|
-
description: 'Delete caches, old sandboxes and other leftovers (the clean command, with its options).',
|
|
69
|
-
};
|
|
72
|
+
const storage = storageMenu(m.storage)?.items ?? [];
|
|
70
73
|
if (!m.data)
|
|
71
74
|
return [
|
|
72
|
-
|
|
75
|
+
...storage,
|
|
73
76
|
{
|
|
74
77
|
value: 'data:measure',
|
|
75
78
|
label: 'Measure what is stored',
|
|
@@ -77,157 +80,46 @@ function dataItems(m) {
|
|
|
77
80
|
section: 'Stored data',
|
|
78
81
|
description: 'Adds up the size of every folder. A big data folder takes a minute or more.',
|
|
79
82
|
},
|
|
80
|
-
clean,
|
|
81
83
|
];
|
|
82
|
-
return [
|
|
83
|
-
folder,
|
|
84
|
-
...m.data.disks.map((d) => ({
|
|
85
|
-
value: 'disk:' + d.drive,
|
|
86
|
-
label: d.drive,
|
|
87
|
-
category: 'data',
|
|
88
|
-
section: 'Disks',
|
|
89
|
-
hint: humanBytes(d.usedBytes) + ' used · ' + humanBytes(d.freeBytes) + ' free of ' + humanBytes(d.totalBytes),
|
|
90
|
-
description: d.holdsStorage ? 'The sandbox keeps its files on this drive.' : undefined,
|
|
91
|
-
})),
|
|
92
|
-
...m.data.entries.map((e, i) => ({
|
|
93
|
-
value: 'entry:' + i,
|
|
94
|
-
label: e.name,
|
|
95
|
-
category: 'data',
|
|
96
|
-
section: AREA_LABEL[e.area],
|
|
97
|
-
hint: humanBytes(e.bytes),
|
|
98
|
-
description: cleanTargetOf(e) ? 'x deletes it.' : 'Kept on this PC on purpose; it is not deleted here.',
|
|
99
|
-
details: [Theme.muted('Folder ') + e.path],
|
|
100
|
-
})),
|
|
101
|
-
clean,
|
|
102
|
-
];
|
|
84
|
+
return [...storage, ...(dataMenuView(m.data)?.items ?? [])];
|
|
103
85
|
}
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
if (u.autoOffText)
|
|
132
|
-
rows.push(row('autooff', 'Automatic updates turned off', Theme.warn('off'), u.autoOffText, [u.autoOffText]));
|
|
133
|
-
if (u.state.previous)
|
|
134
|
-
rows.push(row('previous', 'Previous version', u.state.previous, 'Enter goes back to it.'));
|
|
135
|
-
if (u.state.failed)
|
|
136
|
-
rows.push(row('failed', 'Last failed update', Theme.error(u.state.failed.version), u.state.failed.reason, [
|
|
137
|
-
u.state.failed.reason,
|
|
138
|
-
'It is not tried again until a newer version is released.',
|
|
139
|
-
]));
|
|
140
|
-
return rows;
|
|
86
|
+
/** The Updates view (src/app/features/updates) as the menu's rows, keys and Enter labels, for the Updates category. */
|
|
87
|
+
function updatesMenu(m) {
|
|
88
|
+
return menuView(updatesPage(m.updates.status, m.updates.latest), { category: 'updates', refresh: false });
|
|
89
|
+
}
|
|
90
|
+
/** A value the page shows before the first read (the status is read when the page loads). */
|
|
91
|
+
const NO_UPDATES = {
|
|
92
|
+
managed: false,
|
|
93
|
+
version: '',
|
|
94
|
+
scope: null,
|
|
95
|
+
autoUpdate: false,
|
|
96
|
+
autoOffText: null,
|
|
97
|
+
previous: null,
|
|
98
|
+
failed: null,
|
|
99
|
+
npmCommand: '',
|
|
100
|
+
error: null,
|
|
101
|
+
settings: { pending: [], error: null },
|
|
102
|
+
};
|
|
103
|
+
/**
|
|
104
|
+
* The logs view's rows and keys for the Logs category (its own empty row is left out: the category shows the page's
|
|
105
|
+
* "Nothing here yet.").
|
|
106
|
+
*/
|
|
107
|
+
function logsMenu(files) {
|
|
108
|
+
return menuView({ ...logsPage(files), empty: undefined }, { category: 'logs', refresh: false });
|
|
109
|
+
}
|
|
110
|
+
/** The Web UI view (src/app/features/web) as the menu's rows, keys and Enter labels, for the Web UI category. */
|
|
111
|
+
function webMenu(m) {
|
|
112
|
+
return menuView(webPage(m.web), { category: 'web', prefix: 'web:', refresh: false });
|
|
141
113
|
}
|
|
142
114
|
/** The list for the maintenance tab. Pure. */
|
|
143
115
|
export function maintenanceOptions(m) {
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
// The checks take seconds (programs are run), so they are not made while you move through the categories.
|
|
152
|
-
const check = m.doctor === null && m.setup === null
|
|
153
|
-
? [
|
|
154
|
-
{
|
|
155
|
-
value: 'health:check',
|
|
156
|
-
label: 'Check this PC',
|
|
157
|
-
category: 'health',
|
|
158
|
-
section: 'Doctor',
|
|
159
|
-
description: 'Looks at this PC: Windows features, the install, the folders and the sandbox. It takes a few seconds, so it only runs when you ask.',
|
|
160
|
-
},
|
|
161
|
-
]
|
|
162
|
-
: [];
|
|
163
|
-
const doctor = (m.doctor ?? []).map(([name, detail], i) => ({
|
|
164
|
-
value: 'doctor:' + i,
|
|
165
|
-
label: name,
|
|
166
|
-
category: 'health',
|
|
167
|
-
section: 'Doctor',
|
|
168
|
-
hint: Text.truncate(detail, 50),
|
|
169
|
-
details: [detail],
|
|
170
|
-
}));
|
|
171
|
-
const repair = m.repair
|
|
172
|
-
? m.repair.map((r, i) => {
|
|
173
|
-
const [text, paint] = REPAIR_LABEL[r.status];
|
|
174
|
-
return {
|
|
175
|
-
value: 'repair:' + i,
|
|
176
|
-
label: r.name,
|
|
177
|
-
category: 'health',
|
|
178
|
-
section: 'Repair',
|
|
179
|
-
hint: paint(text),
|
|
180
|
-
description: r.detail,
|
|
181
|
-
};
|
|
182
|
-
})
|
|
183
|
-
: [
|
|
184
|
-
{
|
|
185
|
-
value: 'repair:run',
|
|
186
|
-
label: 'Run the checks and fix what can be fixed',
|
|
187
|
-
category: 'health',
|
|
188
|
-
section: 'Repair',
|
|
189
|
-
description: 'Checks the install, data folder, settings and sandbox, lists what it would change, and asks before it fixes anything.',
|
|
190
|
-
},
|
|
191
|
-
];
|
|
192
|
-
const setup = m.setup === null
|
|
193
|
-
? []
|
|
194
|
-
: 'error' in m.setup
|
|
195
|
-
? [{ value: 'setup:error', label: m.setup.error, category: 'health', section: 'Set up this PC' }]
|
|
196
|
-
: m.setup.checks.map((c, i) => ({
|
|
197
|
-
value: 'setup:' + i,
|
|
198
|
-
label: c.name,
|
|
199
|
-
category: 'health',
|
|
200
|
-
section: 'Set up this PC',
|
|
201
|
-
hint: c.status === 'ok'
|
|
202
|
-
? Theme.ok('OK')
|
|
203
|
-
: c.status === 'warn'
|
|
204
|
-
? Theme.warn('WARNING')
|
|
205
|
-
: Theme.error('ACTION NEEDED'),
|
|
206
|
-
description: c.detail,
|
|
207
|
-
}));
|
|
208
|
-
const settings = 'error' in m.settings
|
|
209
|
-
? [{ value: 'settings:error', label: m.settings.error, category: 'updates', section: 'Saved settings' }]
|
|
210
|
-
: m.settings.pending.length
|
|
211
|
-
? m.settings.pending.map((line, i) => ({
|
|
212
|
-
value: 'settings:' + i,
|
|
213
|
-
label: line.split(':')[0],
|
|
214
|
-
category: 'updates',
|
|
215
|
-
section: 'Saved settings',
|
|
216
|
-
hint: Theme.warn('to update'),
|
|
217
|
-
description: 'Enter updates your saved settings (a backup is kept first).',
|
|
218
|
-
details: [line],
|
|
219
|
-
}))
|
|
220
|
-
: [
|
|
221
|
-
{
|
|
222
|
-
value: 'settings:none',
|
|
223
|
-
label: 'Up to date',
|
|
224
|
-
category: 'updates',
|
|
225
|
-
section: 'Saved settings',
|
|
226
|
-
hint: Theme.ok('OK'),
|
|
227
|
-
description: 'Nothing to update.',
|
|
228
|
-
},
|
|
229
|
-
];
|
|
230
|
-
const updates = updateItems(m);
|
|
116
|
+
// The logs rows have no section heading of their own: the category is their heading.
|
|
117
|
+
const logs = logsMenu(m.logs).items.map(({ section: _section, ...row }) => row);
|
|
118
|
+
// The checks take seconds (programs are run), so they only run when you ask: the page shows the saved results.
|
|
119
|
+
const health = healthMenu(m);
|
|
120
|
+
const updates = updatesMenu(m);
|
|
121
|
+
const engine = engineMenu(m);
|
|
122
|
+
const web = webMenu(m);
|
|
231
123
|
const more = m.more.map((c) => ({
|
|
232
124
|
value: 'more:' + c.name,
|
|
233
125
|
label: MORE_LABELS[c.name] ?? Text.humanize(c.name),
|
|
@@ -237,32 +129,53 @@ export function maintenanceOptions(m) {
|
|
|
237
129
|
return {
|
|
238
130
|
path: [],
|
|
239
131
|
categories: CATEGORIES,
|
|
240
|
-
items: [...updates, ...
|
|
132
|
+
items: [...updates.items, ...dataItems(m), ...health.items, ...logs, ...web.items, ...engine.items, ...more],
|
|
241
133
|
empty: 'Nothing here yet.',
|
|
242
134
|
actions: maintenanceActions(m),
|
|
243
|
-
enterLabel: (
|
|
135
|
+
enterLabel: (category, id) => category === 'health'
|
|
136
|
+
? health.enterLabel(category, id)
|
|
137
|
+
: category === 'updates'
|
|
138
|
+
? updates.enterLabel(category, id)
|
|
139
|
+
: category === 'engine'
|
|
140
|
+
? engine.enterLabel(category, id)
|
|
141
|
+
: category === 'web'
|
|
142
|
+
? web.enterLabel(category, id)
|
|
143
|
+
: (category === 'data'
|
|
144
|
+
? storageMenu(m.storage)?.enterLabel(category, id) || dataMenuView(m.data)?.enterLabel(category, id)
|
|
145
|
+
: undefined) || enterLabel(id ?? ''),
|
|
244
146
|
};
|
|
245
147
|
}
|
|
148
|
+
/**
|
|
149
|
+
* The Engine category: before the first read, one row that reads the engines on Enter (the checks run programs, so
|
|
150
|
+
* they are not made just by opening the category); after it, the engine view's rows.
|
|
151
|
+
*/
|
|
152
|
+
function engineMenu(m) {
|
|
153
|
+
if (!m.engine) {
|
|
154
|
+
const load = {
|
|
155
|
+
value: 'engine:load',
|
|
156
|
+
label: 'Look at the engines',
|
|
157
|
+
category: 'engine',
|
|
158
|
+
section: 'Engines',
|
|
159
|
+
description: 'Checks what each engine needs on this PC. It runs a few Windows programs, so it only runs when asked.',
|
|
160
|
+
};
|
|
161
|
+
return { items: [load], actions: [], enterLabel: () => 'check', resolve: () => undefined };
|
|
162
|
+
}
|
|
163
|
+
return menuView(enginePage(m.engine, m.leftovers ?? undefined), {
|
|
164
|
+
category: 'engine',
|
|
165
|
+
prefix: 'engine:',
|
|
166
|
+
refresh: false,
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
/** The Health category: the health view's rows and keys, drawn only while that category is open. */
|
|
170
|
+
function healthMenu(m) {
|
|
171
|
+
return menuView(healthPage({ last: m.health.last }), { category: 'health', refresh: false });
|
|
172
|
+
}
|
|
246
173
|
/** What Enter does on a row ("" = the row only shows information). */
|
|
247
|
-
function enterLabel(id
|
|
248
|
-
if (id === 'data:folder')
|
|
249
|
-
return 'change';
|
|
174
|
+
function enterLabel(id) {
|
|
250
175
|
if (id === 'data:measure')
|
|
251
176
|
return 'measure';
|
|
252
|
-
if (id === '
|
|
253
|
-
return 'choose what';
|
|
254
|
-
if (id === 'repair:run')
|
|
255
|
-
return 'check and fix';
|
|
256
|
-
if (id === 'health:check')
|
|
177
|
+
if (id === 'engine:load')
|
|
257
178
|
return 'check';
|
|
258
|
-
if (id === 'updates:latest')
|
|
259
|
-
return m.latest ? 'install' : 'look';
|
|
260
|
-
if (id === 'updates:auto')
|
|
261
|
-
return 'switch';
|
|
262
|
-
if (id === 'updates:previous')
|
|
263
|
-
return 'go back';
|
|
264
|
-
if (id.startsWith('settings:') && id !== 'settings:none' && id !== 'settings:error')
|
|
265
|
-
return 'update';
|
|
266
179
|
if (id.startsWith('log:'))
|
|
267
180
|
return 'show';
|
|
268
181
|
if (id.startsWith('more:'))
|
|
@@ -272,48 +185,22 @@ function enterLabel(id, m) {
|
|
|
272
185
|
function maintenanceActions(m) {
|
|
273
186
|
return (category) => {
|
|
274
187
|
switch (category) {
|
|
275
|
-
case 'data':
|
|
276
|
-
const deletable = new Set((m.data?.entries ?? []).flatMap((e, i) => (cleanTargetOf(e) ? ['entry:' + i] : [])));
|
|
188
|
+
case 'data':
|
|
277
189
|
return [
|
|
278
190
|
{ key: 'm', label: 'measure again' },
|
|
279
|
-
|
|
191
|
+
...(storageMenu(m.storage)?.actions ?? []),
|
|
192
|
+
...(dataMenuView(m.data)?.actions ?? []),
|
|
280
193
|
];
|
|
281
|
-
}
|
|
282
194
|
case 'logs':
|
|
283
|
-
return
|
|
284
|
-
case 'health':
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
case 'updates': {
|
|
293
|
-
const managed = !('error' in m.updates) && m.updates.managed;
|
|
294
|
-
const previous = !('error' in m.updates) && Boolean(m.updates.state.previous);
|
|
295
|
-
return [
|
|
296
|
-
...(managed
|
|
297
|
-
? [
|
|
298
|
-
{ key: 'c', label: 'check now' },
|
|
299
|
-
{ key: 'u', label: 'update now' },
|
|
300
|
-
{ key: 'a', label: 'automatic on/off', applies: (id) => id === 'updates:auto' },
|
|
301
|
-
...(previous
|
|
302
|
-
? [{ key: 'r', label: 'roll back', applies: (id) => id === 'updates:previous' }]
|
|
303
|
-
: []),
|
|
304
|
-
]
|
|
305
|
-
: []),
|
|
306
|
-
...('pending' in m.settings && m.settings.pending.length
|
|
307
|
-
? [
|
|
308
|
-
{
|
|
309
|
-
key: 's',
|
|
310
|
-
label: 'update saved settings',
|
|
311
|
-
applies: (id) => id.startsWith('settings:') && id !== 'settings:none',
|
|
312
|
-
},
|
|
313
|
-
]
|
|
314
|
-
: []),
|
|
315
|
-
];
|
|
316
|
-
}
|
|
195
|
+
return logsMenu(m.logs).actions;
|
|
196
|
+
case 'health':
|
|
197
|
+
return healthMenu(m).actions;
|
|
198
|
+
case 'updates':
|
|
199
|
+
return updatesMenu(m).actions;
|
|
200
|
+
case 'engine':
|
|
201
|
+
return [{ key: 'l', label: m.engine ? 'check again' : 'check' }, ...engineMenu(m).actions];
|
|
202
|
+
case 'web':
|
|
203
|
+
return webMenu(m).actions;
|
|
317
204
|
default:
|
|
318
205
|
return [];
|
|
319
206
|
}
|
|
@@ -323,181 +210,122 @@ export class MaintenancePage extends ListPage {
|
|
|
323
210
|
ctx;
|
|
324
211
|
label = 'Maintenance';
|
|
325
212
|
data = null;
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
213
|
+
storage = null;
|
|
214
|
+
logs = NO_LOGS;
|
|
215
|
+
last = null;
|
|
216
|
+
updates = NO_UPDATES;
|
|
217
|
+
engine = null;
|
|
218
|
+
leftovers = null;
|
|
219
|
+
web = NO_WEB;
|
|
220
|
+
operations;
|
|
221
|
+
/** The newer version the last check found (null: none, or not looked yet). */
|
|
335
222
|
latest = null;
|
|
336
223
|
constructor(app, ctx) {
|
|
337
224
|
super(app);
|
|
338
225
|
this.ctx = ctx;
|
|
339
|
-
this.
|
|
340
|
-
this.health = new HealthService(ctx);
|
|
341
|
-
this.migrate = new MigrateService({
|
|
342
|
-
storageRoot: ctx.storageRoot,
|
|
343
|
-
userDir: userDir(),
|
|
344
|
-
configPath: ctx.loaded.configPath,
|
|
345
|
-
});
|
|
346
|
-
this.dataService = new DataService(ctx);
|
|
226
|
+
this.operations = new MenuOperations(app, ctx);
|
|
347
227
|
}
|
|
348
228
|
model() {
|
|
349
229
|
return {
|
|
350
|
-
|
|
230
|
+
storage: this.storage,
|
|
351
231
|
data: this.data,
|
|
352
232
|
logs: this.logs,
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
latest: this.latest,
|
|
233
|
+
health: { last: this.last },
|
|
234
|
+
updates: { status: this.updates, latest: this.latest },
|
|
235
|
+
engine: this.engine,
|
|
236
|
+
leftovers: this.leftovers,
|
|
237
|
+
web: this.web,
|
|
359
238
|
more: MORE_COMMANDS.flatMap((name) => {
|
|
360
239
|
const spec = commandSpec(name);
|
|
361
240
|
return spec ? [{ name, summary: spec.summary }] : [];
|
|
362
241
|
}),
|
|
363
242
|
};
|
|
364
243
|
}
|
|
365
|
-
load() {
|
|
244
|
+
async load() {
|
|
366
245
|
try {
|
|
367
|
-
this.
|
|
246
|
+
this.storage = {
|
|
247
|
+
show: await readQuery(showStorage, this.ctx, { measure: false }),
|
|
248
|
+
contained: await readQuery(containedStatus, this.ctx),
|
|
249
|
+
};
|
|
368
250
|
}
|
|
369
251
|
catch {
|
|
370
|
-
this.
|
|
252
|
+
this.storage = null;
|
|
371
253
|
}
|
|
372
|
-
this.readSettings();
|
|
373
|
-
return Promise.resolve();
|
|
374
|
-
}
|
|
375
|
-
options() {
|
|
376
|
-
return maintenanceOptions(this.model());
|
|
377
|
-
}
|
|
378
|
-
readSettings() {
|
|
379
|
-
try {
|
|
380
|
-
this.settings = { pending: this.migrate.plan() };
|
|
381
|
-
}
|
|
382
|
-
catch (e) {
|
|
383
|
-
this.settings = { error: errMsg(e) };
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
updateStatus() {
|
|
387
254
|
try {
|
|
388
|
-
|
|
255
|
+
this.logs = await readQuery(listLogs, this.ctx);
|
|
389
256
|
}
|
|
390
|
-
catch
|
|
391
|
-
|
|
392
|
-
}
|
|
393
|
-
}
|
|
394
|
-
/** The Updates category: look, install, go back, switch automatic updates. */
|
|
395
|
-
async updates(key) {
|
|
396
|
-
const service = this.updateService;
|
|
397
|
-
if (!service.managed)
|
|
398
|
-
return { notice: Theme.muted('Installed with npm: update it with ' + NPM_UPDATE_COMMAND + '.') };
|
|
399
|
-
if (key === 'a') {
|
|
400
|
-
const on = !service.status().autoUpdate;
|
|
401
|
-
this.busy(on ? 'Turning automatic updates on…' : 'Turning automatic updates off…');
|
|
402
|
-
service.setAuto(on);
|
|
403
|
-
return { notice: Theme.ok(Theme.glyph.ok + ' Automatic updates are ' + (on ? 'on.' : 'off.')) };
|
|
404
|
-
}
|
|
405
|
-
if (key === 'r') {
|
|
406
|
-
const target = service.status().state.previous;
|
|
407
|
-
if (!target)
|
|
408
|
-
return { notice: Theme.muted('There is no earlier version to go back to.') };
|
|
409
|
-
if (!(await this.app.ask('Go back to version ' + target + '?', ['Takes effect the next time you start it.'], 'Go back')))
|
|
410
|
-
return {};
|
|
411
|
-
return { notice: Theme.ok(Theme.glyph.ok + ' Went back to version ' + service.rollback() + '.') };
|
|
412
|
-
}
|
|
413
|
-
if (key === 'c') {
|
|
414
|
-
this.busy('Looking for a newer version…');
|
|
415
|
-
const found = await service.check();
|
|
416
|
-
this.latest = found.available && found.latest ? found.latest.version : null;
|
|
417
|
-
return {
|
|
418
|
-
notice: this.latest
|
|
419
|
-
? Theme.warn('Version ' + this.latest + ' is available.')
|
|
420
|
-
: Theme.ok(Theme.glyph.ok + ' You have the newest version.'),
|
|
421
|
-
};
|
|
257
|
+
catch {
|
|
258
|
+
this.logs = NO_LOGS;
|
|
422
259
|
}
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
this.busy('Installing the newest version…');
|
|
426
|
-
const done = describeResult(await service.run(), false);
|
|
427
|
-
this.latest = null;
|
|
428
|
-
return {
|
|
429
|
-
notice: done.code === 0 ? Theme.ok(Theme.glyph.ok + ' ' + done.line) : Theme.error(Theme.glyph.cross + ' ' + done.line),
|
|
430
|
-
};
|
|
431
|
-
}
|
|
432
|
-
async updateSettings() {
|
|
433
|
-
if (!('pending' in this.settings) || !this.settings.pending.length)
|
|
434
|
-
return { notice: Theme.muted('Your saved settings are up to date.') };
|
|
435
|
-
this.busy('Updating your saved settings…');
|
|
436
|
-
const notes = [];
|
|
437
|
-
const result = await this.migrate.run((line) => notes.push(line));
|
|
438
|
-
this.readSettings();
|
|
439
|
-
return {
|
|
440
|
-
notice: result.postponed.length
|
|
441
|
-
? Theme.warn('Waiting until no sandbox runs: ' + result.postponed.join(', ') + '.')
|
|
442
|
-
: Theme.ok(Theme.glyph.ok + ' Saved settings updated.'),
|
|
443
|
-
};
|
|
444
|
-
}
|
|
445
|
-
async loadDoctor() {
|
|
446
|
-
this.busy('Checking this PC…');
|
|
260
|
+
this.last = (await readQuery(lastHealth, this.ctx)).last;
|
|
261
|
+
this.updates = await readQuery(updatesStatus, this.ctx);
|
|
447
262
|
try {
|
|
448
|
-
this.
|
|
263
|
+
this.web = await readQuery(webStatus, this.ctx);
|
|
449
264
|
}
|
|
450
|
-
catch
|
|
451
|
-
this
|
|
265
|
+
catch {
|
|
266
|
+
// Not on this PC (a sandbox cannot start the web UI): the category shows it as not running.
|
|
267
|
+
this.web = NO_WEB;
|
|
452
268
|
}
|
|
453
269
|
}
|
|
454
|
-
|
|
455
|
-
this.
|
|
456
|
-
try {
|
|
457
|
-
this.health.assertWindows();
|
|
458
|
-
this.setupReport = this.health.setupReport();
|
|
459
|
-
}
|
|
460
|
-
catch (e) {
|
|
461
|
-
this.setupReport = { error: errMsg(e) };
|
|
462
|
-
}
|
|
463
|
-
return Promise.resolve();
|
|
270
|
+
options() {
|
|
271
|
+
return maintenanceOptions(this.model());
|
|
464
272
|
}
|
|
465
273
|
async act(result) {
|
|
466
274
|
const id = result.kind === 'pick' || result.kind === 'action' ? result.value : undefined;
|
|
467
275
|
const key = result.kind === 'action' ? result.key : undefined;
|
|
468
276
|
try {
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
277
|
+
// The open category's rows and keys only (a key of one category must not fire in another).
|
|
278
|
+
if (this.category === 'data') {
|
|
279
|
+
const stored = storageMenu(this.storage)?.resolve(result);
|
|
280
|
+
if (stored?.kind === 'action')
|
|
281
|
+
return await this.dataAction(stored.action);
|
|
282
|
+
const chosen = dataMenuView(this.data)?.resolve(result);
|
|
283
|
+
if (chosen?.kind === 'action')
|
|
284
|
+
return await this.dataAction(chosen.action);
|
|
474
285
|
}
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
286
|
+
// The Engine category reads the engines on Enter on its row, or on l (check again) once they were read.
|
|
287
|
+
if (this.category === 'engine' && ((result.kind === 'pick' && id === 'engine:load') || key === 'l')) {
|
|
288
|
+
this.busy('Checking the engines…');
|
|
289
|
+
this.engine = await readQuery(engineStatus, this.ctx);
|
|
290
|
+
this.leftovers = await readQuery(engineLeftovers, this.ctx);
|
|
291
|
+
return {};
|
|
292
|
+
}
|
|
293
|
+
// Stopping the leftover HCS systems (x): the operation lists them and asks first, then they are looked up again.
|
|
294
|
+
if (this.category === 'engine') {
|
|
295
|
+
const chosen = engineMenu(this.model()).resolve(result);
|
|
296
|
+
if (chosen?.kind !== 'action')
|
|
297
|
+
return {};
|
|
298
|
+
const done = await this.operations.perform(chosen.action, [this.label], (text) => this.busy(text));
|
|
299
|
+
this.leftovers = await readQuery(engineLeftovers, this.ctx);
|
|
300
|
+
return done;
|
|
478
301
|
}
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
302
|
+
// The Web UI's keys (s, o, x) only in its category; the operation reports and the page reloads its facts.
|
|
303
|
+
if (this.category === 'web') {
|
|
304
|
+
const chosen = webMenu(this.model()).resolve(result);
|
|
305
|
+
if (chosen?.kind === 'action')
|
|
306
|
+
return await this.operations.perform(chosen.action, [this.label], (text) => this.busy(text));
|
|
307
|
+
return {};
|
|
308
|
+
}
|
|
309
|
+
if (key === 'm' || id === 'data:measure')
|
|
310
|
+
return await this.measure();
|
|
311
|
+
// Only the open category's rows and keys: `f` and Enter mean something else in Health.
|
|
312
|
+
if (this.category === 'logs') {
|
|
313
|
+
const chosen = logsMenu(this.logs).resolve(result);
|
|
314
|
+
if (chosen?.kind === 'action')
|
|
315
|
+
return this.showLog(chosen.action);
|
|
316
|
+
}
|
|
317
|
+
if (this.category === 'updates') {
|
|
318
|
+
const chosen = updatesMenu(this.model()).resolve(result);
|
|
319
|
+
if (chosen?.kind === 'action')
|
|
320
|
+
return await this.runUpdates(chosen.action);
|
|
321
|
+
return {};
|
|
486
322
|
}
|
|
487
|
-
|
|
488
|
-
return await this.updateSettings();
|
|
489
|
-
if (this.category === 'updates')
|
|
490
|
-
return await this.updates(key ?? this.updateKey(id));
|
|
323
|
+
// Only the open category's rows and keys: a key of one category must not fire in another.
|
|
491
324
|
if (this.category === 'health') {
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
await this.loadSetup();
|
|
497
|
-
return {};
|
|
498
|
-
}
|
|
499
|
-
if (key === 'e')
|
|
500
|
-
return await this.enable();
|
|
325
|
+
const chosen = healthMenu(this.model()).resolve(result);
|
|
326
|
+
if (chosen?.kind === 'action')
|
|
327
|
+
return await this.operations.perform(chosen.action, [this.label], (text) => this.busy(text));
|
|
328
|
+
return {};
|
|
501
329
|
}
|
|
502
330
|
if (id?.startsWith('more:') && result.kind === 'pick') {
|
|
503
331
|
const spec = commandSpec(id.slice(5));
|
|
@@ -510,61 +338,52 @@ export class MaintenancePage extends ListPage {
|
|
|
510
338
|
}
|
|
511
339
|
return {};
|
|
512
340
|
}
|
|
513
|
-
/**
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
if (id === 'updates:previous')
|
|
520
|
-
return 'r';
|
|
521
|
-
return undefined;
|
|
522
|
-
}
|
|
523
|
-
measure() {
|
|
524
|
-
this.busy('Measuring what is stored… this can take a minute or more');
|
|
525
|
-
const report = this.dataService.report();
|
|
526
|
-
this.data = { entries: report.entries, disks: report.disks, total: report.totalBytes };
|
|
527
|
-
return { notice: Theme.ok(Theme.glyph.ok + ' Total stored: ' + humanBytes(report.totalBytes) + '.') };
|
|
528
|
-
}
|
|
529
|
-
async remove(id) {
|
|
530
|
-
const entry = id?.startsWith('entry:') ? this.data?.entries[Number(id.slice(6))] : undefined;
|
|
531
|
-
if (!entry || !this.data)
|
|
341
|
+
/**
|
|
342
|
+
* A Logs row or key: the crash report or the end of a log, on the normal screen (the menu's own view shows a log
|
|
343
|
+
* there). Only names from the listing are looked up, never a path of their own.
|
|
344
|
+
*/
|
|
345
|
+
showLog(action) {
|
|
346
|
+
if (action.kind !== 'link')
|
|
532
347
|
return {};
|
|
533
|
-
const target =
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
const ok = await this.app.ask('Delete ' + target + '?', [
|
|
538
|
-
humanBytes(plan.totalBytes) + ' in ' + entry.path + '.',
|
|
539
|
-
...plan.present.flatMap((t) => (t.warning ? [t.target + ' ' + t.warning + '.'] : [])),
|
|
540
|
-
'This cannot be undone.',
|
|
541
|
-
], 'Delete', true);
|
|
542
|
-
if (!ok)
|
|
348
|
+
const target = action.target;
|
|
349
|
+
if (target.kind === 'command')
|
|
350
|
+
return { exit: { kind: 'run', argv: [...target.argv] } };
|
|
351
|
+
if (target.kind !== 'view')
|
|
543
352
|
return {};
|
|
544
|
-
const
|
|
545
|
-
if (
|
|
546
|
-
return {
|
|
547
|
-
const
|
|
548
|
-
|
|
549
|
-
return { notice: Theme.ok(Theme.glyph.ok + ' Freed ' + humanBytes(outcome.freedBytes) + '.') };
|
|
353
|
+
const name = target.params?.name;
|
|
354
|
+
if (name === CRASH)
|
|
355
|
+
return { exit: { kind: 'run', argv: ['logs', '--crash'] } };
|
|
356
|
+
const file = this.logs.files.find((f) => f.name === name);
|
|
357
|
+
return file ? { exit: { kind: 'view', file: file.path } } : {};
|
|
550
358
|
}
|
|
551
|
-
/**
|
|
552
|
-
|
|
553
|
-
|
|
359
|
+
/**
|
|
360
|
+
* An Updates row or key: runs its operation as the command line does (the operation asks what it must). A check and
|
|
361
|
+
* an install tell the page the newer version they found (or that none is left), the rest leave it alone.
|
|
362
|
+
*/
|
|
363
|
+
runUpdates(action) {
|
|
364
|
+
const input = action.kind === 'operation' ? action.input : {};
|
|
365
|
+
const checks = input.check === true;
|
|
366
|
+
const installs = !checks && input.rollback === undefined && input.auto === undefined;
|
|
367
|
+
const remember = checks || installs
|
|
368
|
+
? (output) => {
|
|
369
|
+
this.latest = output.latest;
|
|
370
|
+
}
|
|
371
|
+
: undefined;
|
|
372
|
+
return this.operations.perform(action, [this.label], (text) => this.busy(text), remember);
|
|
554
373
|
}
|
|
555
|
-
async
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
374
|
+
async measure() {
|
|
375
|
+
this.busy('Measuring what is stored… this can take a minute or more');
|
|
376
|
+
this.data = await readQuery(showData, this.ctx);
|
|
377
|
+
return { notice: Theme.ok(Theme.glyph.ok + ' Total stored: ' + this.data.total + '.') };
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* Delete one stored folder, or clean up: the operation asks and reports as on the command line. After it ran, the
|
|
381
|
+
* sizes shown are out of date, so the list goes back to "Measure what is stored" (a declined question keeps it).
|
|
382
|
+
*/
|
|
383
|
+
async dataAction(action) {
|
|
384
|
+
const outcome = await this.operations.perform(action, [this.label], (text) => this.busy(text));
|
|
385
|
+
if (outcome.reload)
|
|
386
|
+
this.data = null;
|
|
387
|
+
return outcome;
|
|
569
388
|
}
|
|
570
389
|
}
|