windows-development-sandbox 1.10.0 → 1.11.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/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 +194 -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 +959 -4
- package/dist/app/features/defs.js +151 -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 +297 -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 +220 -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 +224 -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 +35 -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/host-memory.d.ts +18 -0
- package/dist/host/life/host-memory.js +66 -0
- 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 +337 -177
- package/dist/runtime/db.js +30 -6
- package/dist/runtime/main.js +389 -77
- package/dist/runtime/netproxy.js +30 -6
- package/dist/runtime/view.js +495 -146
- package/dist/selftest/app.test.js +632 -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.d.ts +2 -0
- package/dist/sync/watcher.js +8 -3
- package/dist/web/index.html +2 -2
- package/dist/web/{main-T5DMCHYV.css → main-MU5XWZMS.css} +1 -1
- package/dist/web/main-SLQNJRXD.js +219 -0
- package/native/csharp/HcsHost/AssemblyInfo.cs +3 -3
- package/native/csharp/HostTools/AssemblyInfo.cs +3 -3
- package/native/csharp/HostTools/MemoryStatus.cs +58 -2
- package/native/csharp/HostTools/Program.cs +7 -1
- 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,11 +1,12 @@
|
|
|
1
|
+
import { type ProjectsList } from '../../../app/features/projects/index.js';
|
|
1
2
|
import { type SandboxStatus } from '../../../app/features/sandbox/index.js';
|
|
2
3
|
import type { Context } from '../../commands/context.js';
|
|
3
|
-
import { type DatabaseRow
|
|
4
|
+
import { type DatabaseRow } from '../../services/index.js';
|
|
4
5
|
import { type App, type ListOptions, type ListResult } from '../../tui/index.js';
|
|
5
6
|
import { ListPage, type Outcome } from './list-page.js';
|
|
6
7
|
export interface SandboxModel {
|
|
7
8
|
readonly report: SandboxStatus;
|
|
8
|
-
readonly projects:
|
|
9
|
+
readonly projects: ProjectsList;
|
|
9
10
|
/** Null: the sandbox is not running or did not answer. */
|
|
10
11
|
readonly databases: DatabaseRow[] | null;
|
|
11
12
|
/** The agent "Start the sandbox" offers while nothing runs. */
|
|
@@ -17,7 +18,6 @@ export declare class SandboxPage extends ListPage<string> {
|
|
|
17
18
|
private readonly ctx;
|
|
18
19
|
readonly label = "Sandbox";
|
|
19
20
|
private model;
|
|
20
|
-
private readonly projects;
|
|
21
21
|
private readonly operations;
|
|
22
22
|
constructor(app: App, ctx: Context);
|
|
23
23
|
protected load(): Promise<void>;
|
|
@@ -27,7 +27,5 @@ export declare class SandboxPage extends ListPage<string> {
|
|
|
27
27
|
protected act(result: ListResult<string>): Promise<Outcome<string>>;
|
|
28
28
|
private defaultAgent;
|
|
29
29
|
private noSandbox;
|
|
30
|
-
private addRoot;
|
|
31
|
-
private forget;
|
|
32
30
|
private toggleDatabase;
|
|
33
31
|
}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
// Section 3: the sandbox as a whole. Status (the sandbox view: its facts, the window, stopping it), Projects (
|
|
2
|
-
//
|
|
3
|
-
|
|
4
|
-
import
|
|
1
|
+
// Section 3: the sandbox as a whole. Status (the sandbox view: its facts, the window, stopping it), Projects (the
|
|
2
|
+
// projects view: roots, the projects and the all-projects setting) and Databases (start and stop), each a category on
|
|
3
|
+
// the left.
|
|
4
|
+
import { listProjects, projectsPage } from '../../../app/features/projects/index.js';
|
|
5
5
|
import { sandboxPage, sandboxStatus } from '../../../app/features/sandbox/index.js';
|
|
6
6
|
import { readQuery } from '../../../app/registry.js';
|
|
7
7
|
import { errMsg, safeText } from '../../../core/util/index.js';
|
|
8
8
|
import { RunDir } from '../../../shared/channel/index.js';
|
|
9
|
-
import { DatabasesService
|
|
10
|
-
import {
|
|
9
|
+
import { DatabasesService } from '../../services/index.js';
|
|
10
|
+
import { Theme } from '../../tui/index.js';
|
|
11
11
|
import { MenuOperations } from '../io-menu.js';
|
|
12
12
|
import { menuView } from '../render-view.js';
|
|
13
13
|
import { ListPage } from './list-page.js';
|
|
@@ -24,38 +24,24 @@ const CATEGORIES = [
|
|
|
24
24
|
function statusView(m) {
|
|
25
25
|
return menuView(sandboxPage(m.report), { category: 'status', prefix: 'status:', refresh: false });
|
|
26
26
|
}
|
|
27
|
+
/** The projects category: the projects view's rows and keys (no prefix: `@add-root`, `root:`, `project:`). */
|
|
28
|
+
function projectsView(m) {
|
|
29
|
+
return menuView(projectsPage(m.projects), { category: 'projects', refresh: false });
|
|
30
|
+
}
|
|
31
|
+
/** The category whose rows and keys are open (the one the cursor is in). */
|
|
32
|
+
function viewFor(m, category) {
|
|
33
|
+
if (category === 'projects')
|
|
34
|
+
return projectsView(m);
|
|
35
|
+
if (category === 'status' || category === undefined)
|
|
36
|
+
return statusView(m);
|
|
37
|
+
return undefined;
|
|
38
|
+
}
|
|
27
39
|
/** The list for the sandbox tab. Pure. */
|
|
28
40
|
export function sandboxOptions(m) {
|
|
29
41
|
const running = m.report.sandbox.running;
|
|
30
42
|
const status = statusView(m);
|
|
43
|
+
const projects = projectsView(m);
|
|
31
44
|
const statusItems = [...(running ? [] : startRows(m.defaultAgent, 'status')), ...status.items];
|
|
32
|
-
const addRoot = {
|
|
33
|
-
value: ADD_ROOT,
|
|
34
|
-
label: '+ Add a project root…',
|
|
35
|
-
category: 'projects',
|
|
36
|
-
section: 'Project roots',
|
|
37
|
-
description: 'Pick a folder that holds your projects: every project in it (also new ones) opens without a restart.',
|
|
38
|
-
};
|
|
39
|
-
const roots = m.projects.roots.map((r) => ({
|
|
40
|
-
value: 'root:' + r,
|
|
41
|
-
label: Text.middle(r, 60),
|
|
42
|
-
hint: Theme.muted('root'),
|
|
43
|
-
category: 'projects',
|
|
44
|
-
section: 'Project roots',
|
|
45
|
-
description: 'Every project in this folder (also new ones) opens without a restart. f removes the root.',
|
|
46
|
-
}));
|
|
47
|
-
const projects = m.projects.projects.map((p) => ({
|
|
48
|
-
value: 'project:' + p.folder,
|
|
49
|
-
label: Text.middle(p.folder, 60),
|
|
50
|
-
hint: p.running ?? (p.root ? 'in a root' : p.excluded ? 'excluded' : p.mappedAtStart ? 'mapped' : '-'),
|
|
51
|
-
category: 'projects',
|
|
52
|
-
section: 'Projects',
|
|
53
|
-
description: p.here ? 'This is the folder you started the menu in.' : undefined,
|
|
54
|
-
details: [
|
|
55
|
-
Theme.muted('At start ') + (p.root ? 'root' : p.excluded ? 'excluded' : p.mappedAtStart ? 'mapped' : '-'),
|
|
56
|
-
Theme.muted('In sandbox ') + (p.running ?? '-'),
|
|
57
|
-
],
|
|
58
|
-
}));
|
|
59
45
|
const noDatabases = m.databases
|
|
60
46
|
? []
|
|
61
47
|
: running
|
|
@@ -80,14 +66,17 @@ export function sandboxOptions(m) {
|
|
|
80
66
|
}));
|
|
81
67
|
return {
|
|
82
68
|
path: [],
|
|
83
|
-
items: [...statusItems,
|
|
69
|
+
items: [...statusItems, ...projects.items, ...databases, ...noDatabases],
|
|
84
70
|
categories: CATEGORIES,
|
|
85
71
|
empty: 'Nothing here yet.',
|
|
86
|
-
actions: (category) => category === 'projects'
|
|
87
|
-
|
|
72
|
+
actions: (category) => category === 'projects'
|
|
73
|
+
? [...projects.actions, REFRESH]
|
|
74
|
+
: category === 'databases'
|
|
75
|
+
? [REFRESH]
|
|
76
|
+
: [...status.actions, REFRESH],
|
|
77
|
+
enterLabel: (category, id) => viewFor(m, category)?.enterLabel(category, id) || enterLabel(id ?? '', m),
|
|
88
78
|
};
|
|
89
79
|
}
|
|
90
|
-
const ADD_ROOT = '@add-root';
|
|
91
80
|
const REFRESH = { key: 'l', label: 'refresh', importance: 3 };
|
|
92
81
|
/** The rows that start a sandbox, shown where the sandbox has to run for anything to be there. */
|
|
93
82
|
function startRows(agent, category) {
|
|
@@ -113,32 +102,18 @@ function startRows(agent, category) {
|
|
|
113
102
|
function enterLabel(id, m) {
|
|
114
103
|
if (id.startsWith('act:start'))
|
|
115
104
|
return 'start';
|
|
116
|
-
if (id === ADD_ROOT)
|
|
117
|
-
return 'choose folder';
|
|
118
105
|
if (id.startsWith('db:'))
|
|
119
106
|
return m.databases?.find((d) => 'db:' + d.name === id)?.running ? 'stop' : 'start';
|
|
120
107
|
return '';
|
|
121
108
|
}
|
|
122
|
-
function sandboxActions(category) {
|
|
123
|
-
if (category === 'projects')
|
|
124
|
-
return [
|
|
125
|
-
{ key: 'a', label: 'add root', importance: 1 },
|
|
126
|
-
{ key: 'f', label: 'remove root', importance: 1, applies: (id) => id.startsWith('root:') },
|
|
127
|
-
{ key: 'f', label: 'forget project', importance: 1, applies: (id) => id.startsWith('project:') },
|
|
128
|
-
REFRESH,
|
|
129
|
-
];
|
|
130
|
-
return [REFRESH];
|
|
131
|
-
}
|
|
132
109
|
export class SandboxPage extends ListPage {
|
|
133
110
|
ctx;
|
|
134
111
|
label = 'Sandbox';
|
|
135
112
|
model;
|
|
136
|
-
projects;
|
|
137
113
|
operations;
|
|
138
114
|
constructor(app, ctx) {
|
|
139
115
|
super(app);
|
|
140
116
|
this.ctx = ctx;
|
|
141
|
-
this.projects = new ProjectsService(ctx);
|
|
142
117
|
this.operations = new MenuOperations(app, ctx);
|
|
143
118
|
}
|
|
144
119
|
async load() {
|
|
@@ -153,7 +128,12 @@ export class SandboxPage extends ListPage {
|
|
|
153
128
|
/* the sandbox did not answer: the list stays empty */
|
|
154
129
|
}
|
|
155
130
|
}
|
|
156
|
-
this.model = {
|
|
131
|
+
this.model = {
|
|
132
|
+
report,
|
|
133
|
+
projects: await readQuery(listProjects, this.ctx),
|
|
134
|
+
databases,
|
|
135
|
+
defaultAgent: this.defaultAgent(),
|
|
136
|
+
};
|
|
157
137
|
}
|
|
158
138
|
/** The folder `sbx-db` runs in: the sandbox's own workspace. */
|
|
159
139
|
guestWorkspace() {
|
|
@@ -170,19 +150,14 @@ export class SandboxPage extends ListPage {
|
|
|
170
150
|
try {
|
|
171
151
|
if (key === 'l')
|
|
172
152
|
return { reload: true };
|
|
173
|
-
|
|
153
|
+
// Only the open category's keys and rows: a key of one category must not fire in another.
|
|
154
|
+
const chosen = this.model ? viewFor(this.model, this.category)?.resolve(result) : undefined;
|
|
174
155
|
if (chosen?.kind === 'action')
|
|
175
156
|
return await this.operations.perform(chosen.action, [this.label], (text) => this.busy(text, id));
|
|
176
157
|
if (id === 'act:start' && !key)
|
|
177
158
|
return { exit: { kind: 'run', argv: ['launch', '--harness', this.defaultAgent()] } };
|
|
178
159
|
if (id === 'act:start-bare' && !key)
|
|
179
160
|
return { exit: { kind: 'run', argv: ['start'] } };
|
|
180
|
-
if (id === ADD_ROOT && !key)
|
|
181
|
-
return await this.addRoot();
|
|
182
|
-
if (key === 'a')
|
|
183
|
-
return await this.addRoot();
|
|
184
|
-
if (key === 'f')
|
|
185
|
-
return await this.forget(id);
|
|
186
161
|
if (id?.startsWith('db:') && result.kind === 'pick')
|
|
187
162
|
return await this.toggleDatabase(id.slice(3));
|
|
188
163
|
}
|
|
@@ -197,59 +172,6 @@ export class SandboxPage extends ListPage {
|
|
|
197
172
|
noSandbox() {
|
|
198
173
|
return this.model?.report.sandbox.running ? null : { notice: Theme.warn('No sandbox is running.') };
|
|
199
174
|
}
|
|
200
|
-
async addRoot() {
|
|
201
|
-
const picked = await this.app.pickPath({
|
|
202
|
-
path: ['Sandbox', 'Add a project root'],
|
|
203
|
-
title: 'Choose the folder that holds your projects',
|
|
204
|
-
about: [
|
|
205
|
-
'Every project inside it (also new ones) opens without a restart. Every agent in the sandbox can see them.',
|
|
206
|
-
],
|
|
207
|
-
use: 'add this root',
|
|
208
|
-
validate: (v) => (fs.existsSync(v) ? true : 'That folder does not exist.'),
|
|
209
|
-
});
|
|
210
|
-
if (!picked)
|
|
211
|
-
return {};
|
|
212
|
-
const { dir, added } = this.projects.addRoot(picked);
|
|
213
|
-
return {
|
|
214
|
-
reload: true,
|
|
215
|
-
notice: added
|
|
216
|
-
? Theme.ok(Theme.glyph.ok + ' Added the root ' + dir + '.') + Theme.muted(' It applies from the next start.')
|
|
217
|
-
: Theme.muted(dir + ' is a root already.'),
|
|
218
|
-
};
|
|
219
|
-
}
|
|
220
|
-
async forget(id) {
|
|
221
|
-
const root = id?.startsWith('root:');
|
|
222
|
-
if (!id || (!root && !id.startsWith('project:')))
|
|
223
|
-
return {};
|
|
224
|
-
const folder = id.slice(root ? 5 : 8);
|
|
225
|
-
const ok = await this.app.ask((root ? 'Remove the root ' : 'Forget ') + path.basename(folder) + '?', [
|
|
226
|
-
root
|
|
227
|
-
? 'Its projects are no longer opened without a restart.'
|
|
228
|
-
: 'The project is dropped from your list of projects.',
|
|
229
|
-
'Nothing in ' + folder + ' is touched.',
|
|
230
|
-
], root ? 'Remove' : 'Forget', true);
|
|
231
|
-
if (!ok)
|
|
232
|
-
return {};
|
|
233
|
-
if (id.startsWith('root:')) {
|
|
234
|
-
const { dir, removed } = this.projects.removeRoot(id.slice(5));
|
|
235
|
-
return {
|
|
236
|
-
reload: true,
|
|
237
|
-
notice: removed
|
|
238
|
-
? Theme.ok(Theme.glyph.ok + ' Removed the root ' + dir + '.')
|
|
239
|
-
: Theme.muted(dir + ' was not a root.'),
|
|
240
|
-
};
|
|
241
|
-
}
|
|
242
|
-
if (id?.startsWith('project:')) {
|
|
243
|
-
const { dir, removed } = this.projects.forget(id.slice(8));
|
|
244
|
-
return {
|
|
245
|
-
reload: true,
|
|
246
|
-
notice: removed
|
|
247
|
-
? Theme.ok(Theme.glyph.ok + ' Forgot ' + dir + '.') + Theme.muted(' Nothing in the folder was touched.')
|
|
248
|
-
: Theme.muted(dir + ' was not in your projects.'),
|
|
249
|
-
};
|
|
250
|
-
}
|
|
251
|
-
return {};
|
|
252
|
-
}
|
|
253
175
|
async toggleDatabase(name) {
|
|
254
176
|
const none = this.noSandbox();
|
|
255
177
|
if (none)
|
|
@@ -1,14 +1,27 @@
|
|
|
1
1
|
import { settingsOf, type ConfigFile, type Setting } from '../../../app/features/settings/index.js';
|
|
2
2
|
import type { Context } from '../../commands/context.js';
|
|
3
|
-
import { type App, type ListItem, type ListOptions, type ListResult } from '../../tui/index.js';
|
|
3
|
+
import { type App, type ListAction, type ListItem, type ListOptions, type ListResult } from '../../tui/index.js';
|
|
4
4
|
import type { Draft } from '../settings/draft.js';
|
|
5
5
|
import { type Scope } from './scopes.js';
|
|
6
6
|
import { ListPage, type Outcome } from './list-page.js';
|
|
7
7
|
export { settingsOf, type Setting };
|
|
8
|
-
/** The
|
|
8
|
+
/** The rows in General that export and import your settings (the page's actions of the settings feature). */
|
|
9
|
+
export declare const EXPORT_SETTINGS = "@export-settings";
|
|
10
|
+
export declare const IMPORT_SETTINGS = "@import-settings";
|
|
11
|
+
export declare function shareSettingsRows(): {
|
|
12
|
+
value: string;
|
|
13
|
+
label: string;
|
|
14
|
+
hint: string;
|
|
15
|
+
description: string;
|
|
16
|
+
}[];
|
|
17
|
+
/** The row in General that changes the data folder (your own settings only): the storage area's operation runs it. */
|
|
9
18
|
export declare const DATA_FOLDER = "@data-folder";
|
|
19
|
+
/** The row in Network that sets the VPN login (its operations are the VPN feature's). */
|
|
20
|
+
export declare const VPN_LOGIN = "@vpn-login";
|
|
21
|
+
/** The row in Security that saves the GitHub token for sandboxes (its operations are the GitHub feature's). */
|
|
22
|
+
export declare const GITHUB_TOKEN = "@github-token";
|
|
10
23
|
/** The list for the settings section. Pure (reads the files it is given). `extra` are rows that are not settings. */
|
|
11
|
-
export declare function settingsOptions(files: Record<Scope, ConfigFile>, scope: Scope, draft: Draft, extra?: readonly ListItem<string>[]): ListOptions<string>;
|
|
24
|
+
export declare function settingsOptions(files: Record<Scope, ConfigFile>, scope: Scope, draft: Draft, extra?: readonly ListItem<string>[], extraActions?: readonly ListAction<string>[]): ListOptions<string>;
|
|
12
25
|
export declare class SettingsPage extends ListPage<string> {
|
|
13
26
|
private readonly files;
|
|
14
27
|
private readonly draft;
|
|
@@ -17,6 +30,11 @@ export declare class SettingsPage extends ListPage<string> {
|
|
|
17
30
|
readonly stages = true;
|
|
18
31
|
private scope;
|
|
19
32
|
private readonly editor;
|
|
33
|
+
private readonly operations;
|
|
34
|
+
/** The VPN status without asking the sandbox: the login row needs only the login's state. */
|
|
35
|
+
private vpn;
|
|
36
|
+
/** Whether a GitHub token is saved (never the token): the token row needs only its state. */
|
|
37
|
+
private github;
|
|
20
38
|
constructor(app: App, files: Record<Scope, ConfigFile>, draft: Draft, ctx: Context);
|
|
21
39
|
private get file();
|
|
22
40
|
protected load(): Promise<void>;
|
|
@@ -3,17 +3,38 @@
|
|
|
3
3
|
// ***) are the settings feature's; this page lays the unsaved changes over them: changes are staged in the Draft
|
|
4
4
|
// (marked *) and written with Ctrl+S; Enter edits, r resets to the default, z undoes an unsaved change.
|
|
5
5
|
import _ from 'lodash';
|
|
6
|
-
import { CATEGORIES, labelOf, nameOf, settingRow, settingsOf, } from '../../../app/features/settings/index.js';
|
|
7
|
-
import {
|
|
6
|
+
import { CATEGORIES, labelOf, listSettings, nameOf, settingRow, settingsOf, settingsPage, } from '../../../app/features/settings/index.js';
|
|
7
|
+
import { changeDataFolder } from '../../../app/features/storage/index.js';
|
|
8
|
+
import { vpnLogin, vpnLoginRowOf, vpnLogout, vpnStatus } from '../../../app/features/vpn/index.js';
|
|
9
|
+
import { githubLogin, githubLogout, githubStatus, githubTokenRowOf, } from '../../../app/features/github/index.js';
|
|
10
|
+
import { action, valueText } from '../../../app/kernel/index.js';
|
|
11
|
+
import { readQuery } from '../../../app/registry.js';
|
|
8
12
|
import { errMsg } from '../../../core/util/index.js';
|
|
9
13
|
import { Text, Theme, } from '../../tui/index.js';
|
|
10
|
-
import {
|
|
11
|
-
import { EXPORT_SETTINGS, IMPORT_SETTINGS, ShareSettingsFlow, shareSettingsRows } from '../share-settings.js';
|
|
12
|
-
import { VpnLoginFlow, vpnLoginRow, VPN_LOGIN } from '../vpn-login.js';
|
|
14
|
+
import { MenuOperations } from '../io-menu.js';
|
|
13
15
|
import { ValueEditor } from '../settings/value-editor.js';
|
|
14
16
|
import { SCOPES, scopeStatus } from './scopes.js';
|
|
15
17
|
import { ListPage } from './list-page.js';
|
|
16
18
|
export { settingsOf };
|
|
19
|
+
/** The rows in General that export and import your settings (the page's actions of the settings feature). */
|
|
20
|
+
export const EXPORT_SETTINGS = '@export-settings';
|
|
21
|
+
export const IMPORT_SETTINGS = '@import-settings';
|
|
22
|
+
export function shareSettingsRows() {
|
|
23
|
+
return [
|
|
24
|
+
{
|
|
25
|
+
value: EXPORT_SETTINGS,
|
|
26
|
+
label: 'Export settings…',
|
|
27
|
+
hint: '.json',
|
|
28
|
+
description: 'Write the settings you changed to a .json file you can share with a team. Secrets, the data folder and folders or files of this PC are left out.',
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
value: IMPORT_SETTINGS,
|
|
32
|
+
label: 'Import settings…',
|
|
33
|
+
hint: '.json',
|
|
34
|
+
description: 'Read a settings file someone shared, see what it would change, and apply it once you say yes. Secrets, the data folder and paths in it are never taken.',
|
|
35
|
+
},
|
|
36
|
+
];
|
|
37
|
+
}
|
|
17
38
|
/** The files with the menu's unsaved changes laid over them. */
|
|
18
39
|
function draftSource(draft) {
|
|
19
40
|
const written = (file, key) => draft.has(file, key) ? draft.value(file, key) : file.valueInFile(key);
|
|
@@ -69,10 +90,24 @@ function current(file, draft, key, config) {
|
|
|
69
90
|
const source = draftSource(draft);
|
|
70
91
|
return file.isProject ? (source.written(file, key) ?? _.get(config, key)) : source.effective(file, key, config);
|
|
71
92
|
}
|
|
72
|
-
/** The row in General that
|
|
93
|
+
/** The row in General that changes the data folder (your own settings only): the storage area's operation runs it. */
|
|
73
94
|
export const DATA_FOLDER = '@data-folder';
|
|
95
|
+
/** The row in Network that sets the VPN login (its operations are the VPN feature's). */
|
|
96
|
+
export const VPN_LOGIN = '@vpn-login';
|
|
97
|
+
const VPN_PATH = ['Settings', 'Network', 'VPN login'];
|
|
98
|
+
/** The row in Security that saves the GitHub token for sandboxes (its operations are the GitHub feature's). */
|
|
99
|
+
export const GITHUB_TOKEN = '@github-token';
|
|
100
|
+
const GITHUB_PATH = ['Settings', 'Security & privacy', 'GitHub token'];
|
|
101
|
+
/** The row's words: where the saved data is, and what Enter does. */
|
|
102
|
+
function dataFolderRow(ctx) {
|
|
103
|
+
return {
|
|
104
|
+
label: 'Data folder',
|
|
105
|
+
hint: ctx.storageRoot,
|
|
106
|
+
description: 'Where your tools, logins, history and logs are kept between sandboxes. Press Enter to move them to another folder or drive, or to use a different folder.',
|
|
107
|
+
};
|
|
108
|
+
}
|
|
74
109
|
/** The list for the settings section. Pure (reads the files it is given). `extra` are rows that are not settings. */
|
|
75
|
-
export function settingsOptions(files, scope, draft, extra = []) {
|
|
110
|
+
export function settingsOptions(files, scope, draft, extra = [], extraActions = []) {
|
|
76
111
|
const file = files[scope];
|
|
77
112
|
const config = files.user.userConfig();
|
|
78
113
|
// The Data folder row stands in for the storage folder setting (changing it moves the data, which is asked about).
|
|
@@ -95,8 +130,9 @@ export function settingsOptions(files, scope, draft, extra = []) {
|
|
|
95
130
|
actions: [
|
|
96
131
|
{ key: 'r', label: file.isProject ? 'remove' : 'reset to default', applies: (id) => set.has(id) },
|
|
97
132
|
{ key: 'z', label: 'undo', applies: (id) => unsaved.has(id) },
|
|
133
|
+
...extraActions,
|
|
98
134
|
],
|
|
99
|
-
enterLabel: (_category, id) => id === DATA_FOLDER || id === VPN_LOGIN
|
|
135
|
+
enterLabel: (_category, id) => id === DATA_FOLDER || id === VPN_LOGIN || id === GITHUB_TOKEN
|
|
100
136
|
? 'change'
|
|
101
137
|
: id === EXPORT_SETTINGS || id === IMPORT_SETTINGS
|
|
102
138
|
? 'open'
|
|
@@ -111,11 +147,26 @@ export class SettingsPage extends ListPage {
|
|
|
111
147
|
stages = true;
|
|
112
148
|
scope = 'user';
|
|
113
149
|
editor;
|
|
150
|
+
operations;
|
|
151
|
+
/** The VPN status without asking the sandbox: the login row needs only the login's state. */
|
|
152
|
+
vpn = {
|
|
153
|
+
enabled: false,
|
|
154
|
+
provider: 'nordvpn',
|
|
155
|
+
protocol: 'udp',
|
|
156
|
+
country: '',
|
|
157
|
+
killSwitch: true,
|
|
158
|
+
login: 'none',
|
|
159
|
+
loginSavedAt: null,
|
|
160
|
+
running: null,
|
|
161
|
+
};
|
|
162
|
+
/** Whether a GitHub token is saved (never the token): the token row needs only its state. */
|
|
163
|
+
github = { shareToken: false, gitAccess: 'full', token: 'none', kind: null, savedAt: null };
|
|
114
164
|
constructor(app, files, draft, ctx) {
|
|
115
165
|
super(app);
|
|
116
166
|
this.files = files;
|
|
117
167
|
this.draft = draft;
|
|
118
168
|
this.ctx = ctx;
|
|
169
|
+
this.operations = new MenuOperations(app, ctx);
|
|
119
170
|
this.editor = new ValueEditor(app, {
|
|
120
171
|
suggestions: (key) => ['defaultHarness', 'harness'].includes(key.join('.'))
|
|
121
172
|
? Object.keys(this.files.user.userConfig().harnesses)
|
|
@@ -125,15 +176,24 @@ export class SettingsPage extends ListPage {
|
|
|
125
176
|
get file() {
|
|
126
177
|
return this.files[this.scope];
|
|
127
178
|
}
|
|
128
|
-
load() {
|
|
129
|
-
|
|
179
|
+
async load() {
|
|
180
|
+
this.vpn = await readQuery(vpnStatus, this.ctx, { tunnel: false });
|
|
181
|
+
this.github = await readQuery(githubStatus, this.ctx, {});
|
|
130
182
|
}
|
|
131
183
|
options() {
|
|
132
184
|
const row = dataFolderRow(this.ctx);
|
|
133
185
|
return settingsOptions(this.files, this.scope, this.draft, [
|
|
134
186
|
{ value: DATA_FOLDER, category: 'general', ...row },
|
|
135
|
-
{ value: VPN_LOGIN, category: 'network', ...
|
|
187
|
+
{ value: VPN_LOGIN, category: 'network', ...vpnLoginRowOf(this.vpn) },
|
|
188
|
+
{ value: GITHUB_TOKEN, category: 'security', ...githubTokenRowOf(this.github) },
|
|
136
189
|
...shareSettingsRows().map((r) => ({ ...r, category: 'general' })),
|
|
190
|
+
], [
|
|
191
|
+
...(this.vpn.login !== 'none'
|
|
192
|
+
? [{ key: 'x', label: 'delete VPN login', applies: (id) => id === VPN_LOGIN }]
|
|
193
|
+
: []),
|
|
194
|
+
...(this.github.token !== 'none'
|
|
195
|
+
? [{ key: 'x', label: 'delete GitHub token', applies: (id) => id === GITHUB_TOKEN }]
|
|
196
|
+
: []),
|
|
137
197
|
]);
|
|
138
198
|
}
|
|
139
199
|
/** Stages a value; your own file never keeps a line that only repeats the default. */
|
|
@@ -159,20 +219,32 @@ export class SettingsPage extends ListPage {
|
|
|
159
219
|
if (result.value === DATA_FOLDER) {
|
|
160
220
|
if (result.kind !== 'pick')
|
|
161
221
|
return {};
|
|
162
|
-
|
|
163
|
-
return exit ? { exit } : { reload: true };
|
|
222
|
+
return this.operations.perform(action(changeDataFolder, {}), [this.label, 'Data folder'], (text) => this.busy(text));
|
|
164
223
|
}
|
|
165
224
|
if (result.value === EXPORT_SETTINGS || result.value === IMPORT_SETTINGS) {
|
|
166
225
|
if (result.kind !== 'pick')
|
|
167
226
|
return {};
|
|
168
|
-
const
|
|
169
|
-
const
|
|
170
|
-
|
|
227
|
+
const exporting = result.value === EXPORT_SETTINGS;
|
|
228
|
+
const page = settingsPage(await readQuery(listSettings, this.ctx, { scope: 'user' }));
|
|
229
|
+
const wanted = exporting ? 'settings.export' : 'settings.import';
|
|
230
|
+
const act = page.actions?.find((a) => a.kind === 'operation' && a.op === wanted);
|
|
231
|
+
if (!act)
|
|
232
|
+
return {};
|
|
233
|
+
return this.operations.perform(act, ['Settings', exporting ? 'Export settings' : 'Import settings']);
|
|
171
234
|
}
|
|
172
235
|
if (result.value === VPN_LOGIN) {
|
|
236
|
+
if (result.kind === 'action' && result.key === 'x')
|
|
237
|
+
return this.operations.perform(action(vpnLogout, {}), VPN_PATH, (t) => this.busy(t));
|
|
238
|
+
if (result.kind !== 'pick')
|
|
239
|
+
return {};
|
|
240
|
+
return this.operations.perform(action(vpnLogin, {}), VPN_PATH, (t) => this.busy(t));
|
|
241
|
+
}
|
|
242
|
+
if (result.value === GITHUB_TOKEN) {
|
|
243
|
+
if (result.kind === 'action' && result.key === 'x')
|
|
244
|
+
return this.operations.perform(action(githubLogout, {}), GITHUB_PATH, (t) => this.busy(t));
|
|
173
245
|
if (result.kind !== 'pick')
|
|
174
246
|
return {};
|
|
175
|
-
return {
|
|
247
|
+
return this.operations.perform(action(githubLogin, {}), GITHUB_PATH, (t) => this.busy(t));
|
|
176
248
|
}
|
|
177
249
|
const setting = settingsOf(this.file).find((s) => s.key.join('.') === result.value);
|
|
178
250
|
if (!setting)
|
|
@@ -37,6 +37,7 @@ export function menuView(page, o = {}) {
|
|
|
37
37
|
if (e.action)
|
|
38
38
|
enter.set(prefix + EMPTY_ROW, e.action);
|
|
39
39
|
}
|
|
40
|
+
// Section.text (a log's lines) is not a row: the menu shows a log on the normal screen (menu.ts view), not here.
|
|
40
41
|
for (const section of page.sections) {
|
|
41
42
|
const heading = section.title ?? page.title;
|
|
42
43
|
for (const f of section.facts ?? [])
|
|
@@ -55,7 +56,7 @@ export function menuView(page, o = {}) {
|
|
|
55
56
|
value: id,
|
|
56
57
|
label: safeText(item.label),
|
|
57
58
|
hint: paint(item.hint, item.tone),
|
|
58
|
-
description: item.description,
|
|
59
|
+
description: [item.description, item.keys].filter(Boolean).join(' ') || undefined,
|
|
59
60
|
details: item.details?.map(safeText),
|
|
60
61
|
section: item.group ?? heading,
|
|
61
62
|
keywords: item.keywords,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// The menu's settings editing: staged changes (Ctrl+S saves them)
|
|
2
|
-
//
|
|
1
|
+
// The menu's settings editing: staged changes (Ctrl+S saves them) and the editors for each kind of value. What the
|
|
2
|
+
// settings are, their files, rows and sharing (export, import) live in the settings feature
|
|
3
|
+
// (src/app/features/settings).
|
|
3
4
|
export { Draft } from './draft.js';
|
|
4
|
-
export { diffText, exportSettings, planImport, skippedLine, } from './share.js';
|
package/dist/cli/menu/views.js
CHANGED
|
@@ -1,11 +1,39 @@
|
|
|
1
1
|
// The shared core's views the menu shows, and in which section (the parity self-test reads this list: an operation or
|
|
2
2
|
// query is reachable in the menu when a view here offers it). Settings is drawn by its own page over the same rows,
|
|
3
3
|
// because the menu stages changes until Ctrl+S.
|
|
4
|
+
import { agentsView } from '../../app/features/agents/index.js';
|
|
5
|
+
import { dataView } from '../../app/features/data/index.js';
|
|
6
|
+
import { accountsView } from '../../app/features/accounts/index.js';
|
|
7
|
+
import { appsView } from '../../app/features/apps/index.js';
|
|
8
|
+
import { healthView } from '../../app/features/health/index.js';
|
|
9
|
+
import { logsView } from '../../app/features/logs/index.js';
|
|
10
|
+
import { projectsView } from '../../app/features/projects/index.js';
|
|
4
11
|
import { sandboxView } from '../../app/features/sandbox/index.js';
|
|
5
12
|
import { sessionsView } from '../../app/features/sessions/index.js';
|
|
13
|
+
import { storageView } from '../../app/features/storage/index.js';
|
|
6
14
|
import { settingsView } from '../../app/features/settings/index.js';
|
|
15
|
+
import { engineView } from '../../app/features/engine/index.js';
|
|
16
|
+
import { updatesView } from '../../app/features/updates/index.js';
|
|
17
|
+
import { webView } from '../../app/features/web/index.js';
|
|
18
|
+
import { vpnView } from '../../app/features/vpn/index.js';
|
|
19
|
+
import { githubView } from '../../app/features/github/index.js';
|
|
7
20
|
export const MENU_VIEWS = [
|
|
21
|
+
{ view: agentsView, section: 'Agents' },
|
|
8
22
|
{ view: sessionsView, section: 'Sessions' },
|
|
9
23
|
{ view: sandboxView, section: 'Sandbox' },
|
|
10
24
|
{ view: settingsView, section: 'Settings' },
|
|
25
|
+
{ view: accountsView, section: 'Accounts' },
|
|
26
|
+
{ view: appsView, section: 'Apps' },
|
|
27
|
+
{ view: projectsView, section: 'Sandbox' },
|
|
28
|
+
{ view: healthView, section: 'Maintenance' },
|
|
29
|
+
{ view: dataView, section: 'Maintenance' },
|
|
30
|
+
{ view: storageView, section: 'Maintenance' },
|
|
31
|
+
{ view: logsView, section: 'Maintenance' },
|
|
32
|
+
{ view: updatesView, section: 'Maintenance' },
|
|
33
|
+
{ view: engineView, section: 'Maintenance' },
|
|
34
|
+
{ view: webView, section: 'Maintenance' },
|
|
35
|
+
// The Settings page draws the VPN row itself (its login is staged with the settings); the view lists its operations.
|
|
36
|
+
{ view: vpnView, section: 'Settings' },
|
|
37
|
+
// The same for the GitHub token row.
|
|
38
|
+
{ view: githubView, section: 'Settings' },
|
|
11
39
|
];
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import { VIEWS } from '../../app/features/defs.js';
|
|
5
5
|
import { runDefinition } from '../../app/registry.js';
|
|
6
6
|
import { Cancelled } from '../../app/kernel/index.js';
|
|
7
|
-
import { printJson, printPage } from '../output/index.js';
|
|
7
|
+
import { nextStep, printJson, printPage } from '../output/index.js';
|
|
8
8
|
import { cliInput, definitionFor } from './input.js';
|
|
9
9
|
import { cliIO } from './io-cli.js';
|
|
10
10
|
/** The view that shows only this query (its page is the command's text output). */
|
|
@@ -22,6 +22,9 @@ function printOutput(def, output, input) {
|
|
|
22
22
|
const text = def.text(output);
|
|
23
23
|
if (text)
|
|
24
24
|
console.log(text);
|
|
25
|
+
const next = def.next?.(output);
|
|
26
|
+
if (next)
|
|
27
|
+
nextStep(next);
|
|
25
28
|
return;
|
|
26
29
|
}
|
|
27
30
|
const shown = viewOf(def);
|
|
@@ -38,12 +41,13 @@ export function definitionHandler(def) {
|
|
|
38
41
|
try {
|
|
39
42
|
const output = await runDefinition(def.id, ctx, input, io);
|
|
40
43
|
close();
|
|
44
|
+
const code = def.cli?.exitCode?.(output) ?? 0;
|
|
41
45
|
if (def.cli?.json && ctx.options.json) {
|
|
42
46
|
printJson(ctx, def.cli.shapeJson ? def.cli.shapeJson(output) : output);
|
|
43
|
-
return
|
|
47
|
+
return code;
|
|
44
48
|
}
|
|
45
49
|
printOutput(def, output, def.input.parse(input));
|
|
46
|
-
return
|
|
50
|
+
return code;
|
|
47
51
|
}
|
|
48
52
|
catch (e) {
|
|
49
53
|
close();
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { AnyDefinition } from '../../app/kernel/index.js';
|
|
2
2
|
import type { CliOptions } from '../args.js';
|
|
3
|
-
/** The definition a command runs: its own command, or an action of a hand-written one (`config get`). */
|
|
3
|
+
/** The definition a command runs: its own command, or an action of a hand-written one (`config get`, `storage use`). */
|
|
4
4
|
export declare function definitionFor(command: string, positionals: readonly string[]): AnyDefinition | undefined;
|
|
5
5
|
/** The input a command line gives a definition (fields not on the line are left to the schema's defaults). */
|
|
6
6
|
export declare function cliInput(def: AnyDefinition, options: CliOptions): Record<string, unknown>;
|