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,168 +0,0 @@
|
|
|
1
|
-
// "Add an agent": a few questions (how it installs, its name, its package or program) that end in a new entry of
|
|
2
|
-
// `harnesses` in your own config file. It is written at once, unless harnesses has unsaved changes in Settings (then
|
|
3
|
-
// it joins them). Everything else about the agent (arguments, login folders ...) is edited in Settings > Agents &
|
|
4
|
-
// sessions.
|
|
5
|
-
import { DEFAULTS } from '../../core/config/index.js';
|
|
6
|
-
import { HarnessSchema, NameSchema, describeIssues } from '../../core/schema/index.js';
|
|
7
|
-
import { fail } from '../../core/util/index.js';
|
|
8
|
-
import { askPath } from './settings/ask-path.js';
|
|
9
|
-
/** Nothing wrong with the name (true), or what is wrong. Pure. */
|
|
10
|
-
export function agentNameProblem(name, taken) {
|
|
11
|
-
const typed = name.trim();
|
|
12
|
-
if (!typed)
|
|
13
|
-
return 'Type a name.';
|
|
14
|
-
const parsed = NameSchema.safeParse(typed);
|
|
15
|
-
if (!parsed.success)
|
|
16
|
-
return 'Use letters, numbers, - and _ only.';
|
|
17
|
-
if (taken.some((t) => t.toLowerCase() === typed.toLowerCase()))
|
|
18
|
-
return typed + ' is an agent already.';
|
|
19
|
-
return true;
|
|
20
|
-
}
|
|
21
|
-
/** The command a package usually provides: "@scope/my-agent@latest" gives "my-agent". Pure. */
|
|
22
|
-
export function commandFromPackage(pkg) {
|
|
23
|
-
const version = pkg.lastIndexOf('@');
|
|
24
|
-
const bare = version > 0 ? pkg.slice(0, version) : pkg;
|
|
25
|
-
return (bare.split(/[\\/]/).pop() ?? '').replace(/[^A-Za-z0-9._-]/g, '');
|
|
26
|
-
}
|
|
27
|
-
/** The config entry for a new agent. Pure. */
|
|
28
|
-
export function newAgent(source, what, command, hostDir = 'auto') {
|
|
29
|
-
const common = { arguments: [], environment: {} };
|
|
30
|
-
if (source === 'npm')
|
|
31
|
-
return { ...common, npmPackage: what, npmBin: command };
|
|
32
|
-
if (source === 'uv')
|
|
33
|
-
return { ...common, uvPackage: what, uvBin: command };
|
|
34
|
-
return { ...common, hostExecutable: what, hostDir };
|
|
35
|
-
}
|
|
36
|
-
/** What `harnesses` should say with `name` taken out. Pure. */
|
|
37
|
-
export function withoutAgent(current, name) {
|
|
38
|
-
const rest = { ...(current && typeof current === 'object' ? current : {}) };
|
|
39
|
-
delete rest[name];
|
|
40
|
-
return rest;
|
|
41
|
-
}
|
|
42
|
-
/** Writes a setting to your config file now, or adds it to the unsaved changes when it has some already. */
|
|
43
|
-
export function writeOrStage(file, draft, key, value) {
|
|
44
|
-
if (draft.has(file, key)) {
|
|
45
|
-
draft.stage(file, key, value);
|
|
46
|
-
return { saved: false };
|
|
47
|
-
}
|
|
48
|
-
const result = file.set(key, value);
|
|
49
|
-
if (typeof result === 'object')
|
|
50
|
-
fail('It could not be saved: ' + result.problems.join('; '));
|
|
51
|
-
return { saved: true };
|
|
52
|
-
}
|
|
53
|
-
/** What `harnesses` should say with `name` added to what is staged or in the file now. Pure. */
|
|
54
|
-
export function withAgent(current, name, harness) {
|
|
55
|
-
return { ...(current && typeof current === 'object' ? current : {}), [name]: harness };
|
|
56
|
-
}
|
|
57
|
-
/** The staged value of a setting, else what your own file says (what `harnesses` or `defaultHarness` will be). */
|
|
58
|
-
function current(file, draft, key) {
|
|
59
|
-
return draft.has(file, key) ? draft.value(file, key) : file.valueInFile(key);
|
|
60
|
-
}
|
|
61
|
-
/** Makes `name` the agent that starts by default (written now, or joined to unsaved changes to that setting). */
|
|
62
|
-
export function makeDefaultAgent(file, draft, name) {
|
|
63
|
-
return writeOrStage(file, draft, ['defaultHarness'], name);
|
|
64
|
-
}
|
|
65
|
-
/** Takes an agent you added out of your settings (the built-in ones are not removable). */
|
|
66
|
-
export function removeAgent(file, draft, name) {
|
|
67
|
-
if (name in DEFAULTS.harnesses)
|
|
68
|
-
fail(name + ' is built in, so it cannot be removed.');
|
|
69
|
-
const key = ['harnesses'];
|
|
70
|
-
const standing = current(file, draft, ['defaultHarness']) ?? file.userConfig().defaultHarness;
|
|
71
|
-
if (standing === name)
|
|
72
|
-
fail(name + ' is the default agent.', 'Make another agent the default first.');
|
|
73
|
-
const rest = withoutAgent(current(file, draft, key), name);
|
|
74
|
-
// Nothing of your own left: the setting goes (the built-in agents need no line).
|
|
75
|
-
return writeOrStage(file, draft, key, Object.keys(rest).length ? rest : undefined);
|
|
76
|
-
}
|
|
77
|
-
export class AddAgent {
|
|
78
|
-
app;
|
|
79
|
-
file;
|
|
80
|
-
draft;
|
|
81
|
-
taken;
|
|
82
|
-
constructor(app, file, draft,
|
|
83
|
-
/** Every agent that exists now (the new name must be different). */
|
|
84
|
-
taken) {
|
|
85
|
-
this.app = app;
|
|
86
|
-
this.file = file;
|
|
87
|
-
this.draft = draft;
|
|
88
|
-
this.taken = taken;
|
|
89
|
-
}
|
|
90
|
-
/** Asks, then adds the agent. Undefined when you backed out. */
|
|
91
|
-
async run() {
|
|
92
|
-
const path = ['Agents', 'Add an agent'];
|
|
93
|
-
const source = await this.app.choose(path, 'How does the agent get into the sandbox?', [
|
|
94
|
-
{
|
|
95
|
-
value: 'npm',
|
|
96
|
-
label: 'An npm package',
|
|
97
|
-
description: 'Installed inside the sandbox with npm once and kept (e.g. @openai/codex).',
|
|
98
|
-
},
|
|
99
|
-
{
|
|
100
|
-
value: 'uv',
|
|
101
|
-
label: 'A Python package',
|
|
102
|
-
description: 'Installed inside the sandbox with uv once and kept (e.g. aider-chat).',
|
|
103
|
-
},
|
|
104
|
-
{
|
|
105
|
-
value: 'host',
|
|
106
|
-
label: 'A program on this PC',
|
|
107
|
-
description: 'An .exe copied from this PC into the sandbox (looked up on PATH and in ~/.local/bin).',
|
|
108
|
-
},
|
|
109
|
-
]);
|
|
110
|
-
if (!source)
|
|
111
|
-
return undefined;
|
|
112
|
-
const name = await this.app.text({
|
|
113
|
-
path,
|
|
114
|
-
label: 'Name of the agent',
|
|
115
|
-
about: ['What you type after "sandbox", e.g. sandbox <name>. Letters, numbers, - and _.'],
|
|
116
|
-
validate: (v) => agentNameProblem(v, this.taken),
|
|
117
|
-
});
|
|
118
|
-
if (!name)
|
|
119
|
-
return undefined;
|
|
120
|
-
if (source === 'host') {
|
|
121
|
-
const exe = await askPath(this.app, {
|
|
122
|
-
path,
|
|
123
|
-
title: 'Choose the program (.exe)',
|
|
124
|
-
about: ['The agent program on this PC. It is copied into the sandbox. A bare file name is looked up on PATH.'],
|
|
125
|
-
kind: 'file',
|
|
126
|
-
validate: (v) => (v.trim() ? true : 'Choose a file.'),
|
|
127
|
-
});
|
|
128
|
-
if (!exe)
|
|
129
|
-
return undefined;
|
|
130
|
-
const slash = Math.max(exe.lastIndexOf('\\'), exe.lastIndexOf('/'));
|
|
131
|
-
const dir = slash > 0 ? exe.slice(0, slash) : 'auto';
|
|
132
|
-
return this.add(name.trim(), newAgent('host', exe.slice(slash + 1), '', dir));
|
|
133
|
-
}
|
|
134
|
-
const what = await this.app.text({
|
|
135
|
-
path,
|
|
136
|
-
label: source === 'npm' ? 'npm package' : 'Python package',
|
|
137
|
-
about: [
|
|
138
|
-
source === 'npm'
|
|
139
|
-
? 'The package to install, optionally with a version: @scope/name or name@latest.'
|
|
140
|
-
: 'The package for `uv tool install`.',
|
|
141
|
-
],
|
|
142
|
-
validate: (v) => (v.trim() ? true : 'Type it.'),
|
|
143
|
-
});
|
|
144
|
-
if (!what)
|
|
145
|
-
return undefined;
|
|
146
|
-
const command = await this.app.text({
|
|
147
|
-
path,
|
|
148
|
-
label: 'Command',
|
|
149
|
-
about: ['The command the package provides; it is what runs inside the sandbox.'],
|
|
150
|
-
initial: commandFromPackage(what.trim()),
|
|
151
|
-
validate: (v) => (/^[A-Za-z0-9._-]+$/.test(v.trim()) ? true : 'Letters, numbers, . - and _ only.'),
|
|
152
|
-
});
|
|
153
|
-
if (!command)
|
|
154
|
-
return undefined;
|
|
155
|
-
return this.add(name.trim(), newAgent(source, what.trim(), command.trim()));
|
|
156
|
-
}
|
|
157
|
-
/** Validates and writes (or stages) the entry. */
|
|
158
|
-
add(name, harness) {
|
|
159
|
-
const checked = HarnessSchema.safeParse(harness);
|
|
160
|
-
if (!checked.success)
|
|
161
|
-
fail('That agent is not valid: ' + describeIssues(checked.error).join('; '));
|
|
162
|
-
const key = ['harnesses'];
|
|
163
|
-
return {
|
|
164
|
-
name,
|
|
165
|
-
...writeOrStage(this.file, this.draft, key, withAgent(current(this.file, this.draft, key), name, harness)),
|
|
166
|
-
};
|
|
167
|
-
}
|
|
168
|
-
}
|
package/dist/cli/menu/apps.d.ts
DELETED
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
import { type AppCategory, type AppEntry } from '../../shared/apps/index.js';
|
|
2
|
-
import { type Category, type ListItem } from '../tui/index.js';
|
|
3
|
-
import type { ConfigFile } from '../../app/features/settings/index.js';
|
|
4
|
-
import type { Draft } from './settings/draft.js';
|
|
5
|
-
export declare const CUSTOM = "@custom:";
|
|
6
|
-
/** The catalogue has many small categories; the menu shows these few groups so the navigation stays short. */
|
|
7
|
-
export declare const APP_GROUPS: readonly [{
|
|
8
|
-
readonly id: "editors";
|
|
9
|
-
readonly label: "Editors & docs";
|
|
10
|
-
readonly description: "Code and text editors (VS Code is on by default), plus diagrams and document conversion.";
|
|
11
|
-
readonly members: readonly ["editors", "diagrams"];
|
|
12
|
-
}, {
|
|
13
|
-
readonly id: "clients";
|
|
14
|
-
readonly label: "DB & API clients";
|
|
15
|
-
readonly description: "GUIs for the sandbox databases, tools to send HTTP, REST and GraphQL requests, and to inspect traffic.";
|
|
16
|
-
readonly members: readonly ["databases", "api", "network"];
|
|
17
|
-
}, {
|
|
18
|
-
readonly id: "tools";
|
|
19
|
-
readonly label: "Git & utilities";
|
|
20
|
-
readonly description: "Git GUIs and terminal UIs, archives, file search and comparing, process tools, and decompilers.";
|
|
21
|
-
readonly members: readonly ["git", "utilities", "reversing"];
|
|
22
|
-
}, {
|
|
23
|
-
readonly id: "cli";
|
|
24
|
-
readonly label: "Command-line & cloud";
|
|
25
|
-
readonly description: "Small developer tools (JSON, search, builds, media ...) and tools for clouds and Kubernetes.";
|
|
26
|
-
readonly members: readonly ["cli", "cloud"];
|
|
27
|
-
}, {
|
|
28
|
-
readonly id: "play";
|
|
29
|
-
readonly label: "Browsers & games";
|
|
30
|
-
readonly description: "Browsers for testing web apps, and game engines and editors (they draw with OpenGL on the CPU).";
|
|
31
|
-
readonly members: readonly ["browsers", "gamedev"];
|
|
32
|
-
}];
|
|
33
|
-
/** The group an app category is shown under. */
|
|
34
|
-
export declare function groupOf(category: AppCategory): string;
|
|
35
|
-
/** The row in Apps that opens the "request an app" issue form (its id is not an app). */
|
|
36
|
-
export declare const REQUEST_APP = "@request-app";
|
|
37
|
-
/** This project's new-issue page on GitHub. */
|
|
38
|
-
export declare const ISSUES_URL = "https://github.com/JoshDiDuca/windows-development-sandbox/issues/new";
|
|
39
|
-
/** The new-issue address with a title and a body to fill in (the page needs no login to show it). */
|
|
40
|
-
export declare function requestAppUrl(): string;
|
|
41
|
-
export declare class AppsModel {
|
|
42
|
-
private readonly file;
|
|
43
|
-
private readonly dataPath;
|
|
44
|
-
constructor(file: ConfigFile, dataPath: string);
|
|
45
|
-
/** The catalogue entries this file can change (a project cannot change an app that has a setting of its own). */
|
|
46
|
-
entries(): AppEntry[];
|
|
47
|
-
categories(): Category[];
|
|
48
|
-
/** Downloaded already (into this data folder), so the next sandbox starts it without a download. */
|
|
49
|
-
private installed;
|
|
50
|
-
private savedInstall;
|
|
51
|
-
/** Is the entry on in the saved file? */
|
|
52
|
-
private savedOn;
|
|
53
|
-
/** Is the entry on once the staged changes are saved? */
|
|
54
|
-
isOn(entry: AppEntry, draft: Draft): boolean;
|
|
55
|
-
/** Your own programs (apps.custom), staged or saved. */
|
|
56
|
-
custom(draft: Draft): Record<string, {
|
|
57
|
-
name: string;
|
|
58
|
-
github?: string;
|
|
59
|
-
url?: string;
|
|
60
|
-
cli?: boolean;
|
|
61
|
-
}>;
|
|
62
|
-
private item;
|
|
63
|
-
items(draft: Draft): ListItem<string>[];
|
|
64
|
-
/** Stages the ticks of the list: only what differs from the saved file is kept in the draft. */
|
|
65
|
-
stageTicks(draft: Draft, ticked: readonly string[]): void;
|
|
66
|
-
}
|
|
67
|
-
/** For notices: "12 apps chosen". */
|
|
68
|
-
export declare function appsSummary(file: ConfigFile): string;
|
|
69
|
-
export declare function appLabel(id: string): string;
|
package/dist/cli/menu/apps.js
DELETED
|
@@ -1,214 +0,0 @@
|
|
|
1
|
-
// The apps catalogue as data for the Apps tab: every app by category, ticked = installed in every sandbox. VS Code and
|
|
2
|
-
// Windows Terminal are listed too (they have settings of their own, which ticking changes). Ticks are staged in the
|
|
3
|
-
// Draft and written with Ctrl+S, to your config file or (catalogue apps only) the project's .sandbox-config.json.
|
|
4
|
-
import fs from 'node:fs';
|
|
5
|
-
import path from 'node:path';
|
|
6
|
-
import _ from 'lodash';
|
|
7
|
-
import { APPS } from '../../shared/apps/index.js';
|
|
8
|
-
import { Text, Theme } from '../tui/index.js';
|
|
9
|
-
export const CUSTOM = '@custom:';
|
|
10
|
-
/** The catalogue has many small categories; the menu shows these few groups so the navigation stays short. */
|
|
11
|
-
export const APP_GROUPS = [
|
|
12
|
-
{
|
|
13
|
-
id: 'editors',
|
|
14
|
-
label: 'Editors & docs',
|
|
15
|
-
description: 'Code and text editors (VS Code is on by default), plus diagrams and document conversion.',
|
|
16
|
-
members: ['editors', 'diagrams'],
|
|
17
|
-
},
|
|
18
|
-
{
|
|
19
|
-
id: 'clients',
|
|
20
|
-
label: 'DB & API clients',
|
|
21
|
-
description: 'GUIs for the sandbox databases, tools to send HTTP, REST and GraphQL requests, and to inspect traffic.',
|
|
22
|
-
members: ['databases', 'api', 'network'],
|
|
23
|
-
},
|
|
24
|
-
{
|
|
25
|
-
id: 'tools',
|
|
26
|
-
label: 'Git & utilities',
|
|
27
|
-
description: 'Git GUIs and terminal UIs, archives, file search and comparing, process tools, and decompilers.',
|
|
28
|
-
members: ['git', 'utilities', 'reversing'],
|
|
29
|
-
},
|
|
30
|
-
{
|
|
31
|
-
id: 'cli',
|
|
32
|
-
label: 'Command-line & cloud',
|
|
33
|
-
description: 'Small developer tools (JSON, search, builds, media ...) and tools for clouds and Kubernetes.',
|
|
34
|
-
members: ['cli', 'cloud'],
|
|
35
|
-
},
|
|
36
|
-
{
|
|
37
|
-
id: 'play',
|
|
38
|
-
label: 'Browsers & games',
|
|
39
|
-
description: 'Browsers for testing web apps, and game engines and editors (they draw with OpenGL on the CPU).',
|
|
40
|
-
members: ['browsers', 'gamedev'],
|
|
41
|
-
},
|
|
42
|
-
];
|
|
43
|
-
/** The group an app category is shown under. */
|
|
44
|
-
export function groupOf(category) {
|
|
45
|
-
return APP_GROUPS.find((g) => g.members.includes(category))?.id ?? 'tools';
|
|
46
|
-
}
|
|
47
|
-
const INSTALL = ['apps', 'install'];
|
|
48
|
-
/** The row in Apps that opens the "request an app" issue form (its id is not an app). */
|
|
49
|
-
export const REQUEST_APP = '@request-app';
|
|
50
|
-
/** This project's new-issue page on GitHub. */
|
|
51
|
-
export const ISSUES_URL = 'https://github.com/JoshDiDuca/windows-development-sandbox/issues/new';
|
|
52
|
-
/** The new-issue address with a title and a body to fill in (the page needs no login to show it). */
|
|
53
|
-
export function requestAppUrl() {
|
|
54
|
-
const body = [
|
|
55
|
-
'**App name:**',
|
|
56
|
-
'',
|
|
57
|
-
'**Where to get it** (GitHub releases page or a direct download link):',
|
|
58
|
-
'',
|
|
59
|
-
'**What it is for:**',
|
|
60
|
-
'',
|
|
61
|
-
'**Command-line tool or desktop app?**',
|
|
62
|
-
'',
|
|
63
|
-
'**Does it need a GPU, a license or an account?**',
|
|
64
|
-
].join('\n');
|
|
65
|
-
const query = [
|
|
66
|
-
['title', 'App request: '],
|
|
67
|
-
['body', body],
|
|
68
|
-
['labels', 'app-request'],
|
|
69
|
-
];
|
|
70
|
-
return ISSUES_URL + '?' + query.map(([k, v]) => k + '=' + encodeURIComponent(v)).join('&');
|
|
71
|
-
}
|
|
72
|
-
export class AppsModel {
|
|
73
|
-
file;
|
|
74
|
-
dataPath;
|
|
75
|
-
constructor(file, dataPath) {
|
|
76
|
-
this.file = file;
|
|
77
|
-
this.dataPath = dataPath;
|
|
78
|
-
}
|
|
79
|
-
/** The catalogue entries this file can change (a project cannot change an app that has a setting of its own). */
|
|
80
|
-
entries() {
|
|
81
|
-
return APPS.filter((a) => !(this.file.isProject && a.setting));
|
|
82
|
-
}
|
|
83
|
-
categories() {
|
|
84
|
-
return [
|
|
85
|
-
...APP_GROUPS.map(({ id, label, description }) => ({ id, label, description })),
|
|
86
|
-
...(this.file.isProject
|
|
87
|
-
? []
|
|
88
|
-
: [
|
|
89
|
-
{
|
|
90
|
-
id: 'custom',
|
|
91
|
-
label: 'Your own programs',
|
|
92
|
-
description: 'Programs you added yourself (c to add or change them).',
|
|
93
|
-
},
|
|
94
|
-
]),
|
|
95
|
-
];
|
|
96
|
-
}
|
|
97
|
-
/** Downloaded already (into this data folder), so the next sandbox starts it without a download. */
|
|
98
|
-
installed(entry) {
|
|
99
|
-
if (entry.id === 'vscode')
|
|
100
|
-
return fs.existsSync(path.join(this.dataPath, 'tools', 'vscode', 'Code.exe'));
|
|
101
|
-
if (entry.id === 'windows-terminal')
|
|
102
|
-
return fs.existsSync(path.join(this.dataPath, 'tools', 'terminal', 'WindowsTerminal.exe'));
|
|
103
|
-
return fs.existsSync(path.join(this.dataPath, 'tools', 'apps', entry.id, '.agent-sandbox-app'));
|
|
104
|
-
}
|
|
105
|
-
savedInstall() {
|
|
106
|
-
return ((this.file.isProject ? this.file.valueInFile(INSTALL) : this.file.userConfig().apps.install) ?? []);
|
|
107
|
-
}
|
|
108
|
-
/** Is the entry on in the saved file? */
|
|
109
|
-
savedOn(entry) {
|
|
110
|
-
return entry.setting
|
|
111
|
-
? _.get(this.file.userConfig(), entry.setting) === true
|
|
112
|
-
: this.savedInstall().includes(entry.id);
|
|
113
|
-
}
|
|
114
|
-
/** Is the entry on once the staged changes are saved? */
|
|
115
|
-
isOn(entry, draft) {
|
|
116
|
-
if (entry.setting) {
|
|
117
|
-
const key = entry.setting.split('.');
|
|
118
|
-
return draft.has(this.file, key) ? draft.value(this.file, key) === true : this.savedOn(entry);
|
|
119
|
-
}
|
|
120
|
-
const staged = draft.has(this.file, INSTALL)
|
|
121
|
-
? draft.value(this.file, INSTALL)
|
|
122
|
-
: undefined;
|
|
123
|
-
return draft.has(this.file, INSTALL) ? (staged ?? []).includes(entry.id) : this.savedOn(entry);
|
|
124
|
-
}
|
|
125
|
-
/** Your own programs (apps.custom), staged or saved. */
|
|
126
|
-
custom(draft) {
|
|
127
|
-
if (this.file.isProject)
|
|
128
|
-
return {};
|
|
129
|
-
const key = ['apps', 'custom'];
|
|
130
|
-
return (draft.has(this.file, key) ? draft.value(this.file, key) : this.file.userConfig().apps.custom);
|
|
131
|
-
}
|
|
132
|
-
item(entry, draft) {
|
|
133
|
-
const notes = [
|
|
134
|
-
Theme.muted('Download ') +
|
|
135
|
-
'~' +
|
|
136
|
-
entry.size +
|
|
137
|
-
' once, kept in C:\\AgentData\\tools\\' +
|
|
138
|
-
(entry.setting ? '' : 'apps\\') +
|
|
139
|
-
entry.id,
|
|
140
|
-
Theme.muted('Starts ') +
|
|
141
|
-
(entry.cli ? 'from a terminal (on PATH)' : 'from the desktop or Start > Sandbox apps'),
|
|
142
|
-
...(entry.needs?.includes('mesa')
|
|
143
|
-
? [Theme.muted('Graphics ') + 'OpenGL on the CPU (Mesa) is added for it']
|
|
144
|
-
: []),
|
|
145
|
-
...(entry.fullGitOnly
|
|
146
|
-
? [Theme.warn('Needs full git access (Settings > Projects & setup > Git): it pushes with its own git.')]
|
|
147
|
-
: []),
|
|
148
|
-
...(entry.setting ? [Theme.muted('Setting ') + entry.setting] : []),
|
|
149
|
-
];
|
|
150
|
-
return {
|
|
151
|
-
value: entry.id,
|
|
152
|
-
label: entry.name,
|
|
153
|
-
category: groupOf(entry.category),
|
|
154
|
-
description: entry.about,
|
|
155
|
-
details: notes,
|
|
156
|
-
keywords: entry.id,
|
|
157
|
-
hint: (this.installed(entry) ? Theme.ok('installed ') : '') + Theme.muted(entry.size),
|
|
158
|
-
checked: this.isOn(entry, draft),
|
|
159
|
-
};
|
|
160
|
-
}
|
|
161
|
-
items(draft) {
|
|
162
|
-
return [
|
|
163
|
-
...this.entries().map((a) => this.item(a, draft)),
|
|
164
|
-
...(this.file.isProject
|
|
165
|
-
? []
|
|
166
|
-
: [
|
|
167
|
-
{
|
|
168
|
-
value: REQUEST_APP,
|
|
169
|
-
label: 'Request an app…',
|
|
170
|
-
category: 'custom',
|
|
171
|
-
description: 'Not in the list? Press r: your browser opens a prefilled request on GitHub (' + ISSUES_URL + ').',
|
|
172
|
-
hint: Theme.muted('press r'),
|
|
173
|
-
disabled: 'Press r to open the request form on GitHub.',
|
|
174
|
-
},
|
|
175
|
-
]),
|
|
176
|
-
...Object.entries(this.custom(draft)).map(([id, a]) => ({
|
|
177
|
-
value: CUSTOM + id,
|
|
178
|
-
label: a.name,
|
|
179
|
-
category: 'custom',
|
|
180
|
-
description: a.github ? 'From the latest ' + a.github + ' release.' : 'From ' + a.url,
|
|
181
|
-
hint: Theme.muted(a.cli ? 'command line' : 'desktop'),
|
|
182
|
-
checked: true,
|
|
183
|
-
disabled: 'Your own programs are always installed; c to change or remove them.',
|
|
184
|
-
})),
|
|
185
|
-
];
|
|
186
|
-
}
|
|
187
|
-
/** Stages the ticks of the list: only what differs from the saved file is kept in the draft. */
|
|
188
|
-
stageTicks(draft, ticked) {
|
|
189
|
-
for (const entry of this.entries().filter((a) => a.setting)) {
|
|
190
|
-
const key = entry.setting.split('.');
|
|
191
|
-
const on = ticked.includes(entry.id);
|
|
192
|
-
if (on === this.savedOn(entry))
|
|
193
|
-
draft.unstage(this.file, key);
|
|
194
|
-
else
|
|
195
|
-
draft.stage(this.file, key, on);
|
|
196
|
-
}
|
|
197
|
-
const wanted = this.entries()
|
|
198
|
-
.filter((a) => !a.setting && ticked.includes(a.id))
|
|
199
|
-
.map((a) => a.id);
|
|
200
|
-
if (_.isEqual([...wanted].sort(), [...this.savedInstall()].sort()))
|
|
201
|
-
draft.unstage(this.file, INSTALL);
|
|
202
|
-
else
|
|
203
|
-
draft.stage(this.file, INSTALL, wanted.length || this.file.isProject ? wanted : undefined);
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
/** For notices: "12 apps chosen". */
|
|
207
|
-
export function appsSummary(file) {
|
|
208
|
-
const config = file.userConfig();
|
|
209
|
-
const n = config.apps.install.length + Object.keys(config.apps.custom).length;
|
|
210
|
-
return n ? n + ' chosen' : 'none chosen';
|
|
211
|
-
}
|
|
212
|
-
export function appLabel(id) {
|
|
213
|
-
return APPS.find((a) => a.id === id)?.name ?? Text.humanize(id);
|
|
214
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import type { Context } from '../commands/context.js';
|
|
2
|
-
import type { App } from '../tui/index.js';
|
|
3
|
-
import type { ShellExit } from './shell.js';
|
|
4
|
-
/** The row in Settings and Maintenance. */
|
|
5
|
-
export declare function dataFolderRow(ctx: Context): {
|
|
6
|
-
label: string;
|
|
7
|
-
hint: string;
|
|
8
|
-
description: string;
|
|
9
|
-
};
|
|
10
|
-
export declare class DataFolderFlow {
|
|
11
|
-
private readonly app;
|
|
12
|
-
private readonly ctx;
|
|
13
|
-
constructor(app: App, ctx: Context);
|
|
14
|
-
/** The command to run (move or use), or undefined when nothing was chosen. */
|
|
15
|
-
run(): Promise<ShellExit | undefined>;
|
|
16
|
-
private measure;
|
|
17
|
-
private decide;
|
|
18
|
-
}
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
// The "Data folder" row and its flow: shows where the saved data is, lets you pick another folder in the path picker,
|
|
2
|
-
// asks whether to move the data or only switch, and hands the command to run on the normal screen (the move prints its
|
|
3
|
-
// progress there).
|
|
4
|
-
import fs from 'node:fs';
|
|
5
|
-
import { humanBytes } from '../../core/disk.js';
|
|
6
|
-
import { describeDuration, describeSize, estimate, holdsData, measureFolder, moveProblem, moveWarning, } from '../../host/storage/index.js';
|
|
7
|
-
/** Measuring for the dialog stops after this long (the size then reads "at least"). */
|
|
8
|
-
const MEASURE_MS = 8000;
|
|
9
|
-
/** The row in Settings and Maintenance. */
|
|
10
|
-
export function dataFolderRow(ctx) {
|
|
11
|
-
return {
|
|
12
|
-
label: 'Data folder',
|
|
13
|
-
hint: ctx.storageRoot,
|
|
14
|
-
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.',
|
|
15
|
-
};
|
|
16
|
-
}
|
|
17
|
-
export class DataFolderFlow {
|
|
18
|
-
app;
|
|
19
|
-
ctx;
|
|
20
|
-
constructor(app, ctx) {
|
|
21
|
-
this.app = app;
|
|
22
|
-
this.ctx = ctx;
|
|
23
|
-
}
|
|
24
|
-
/** The command to run (move or use), or undefined when nothing was chosen. */
|
|
25
|
-
async run() {
|
|
26
|
-
const from = this.ctx.storageRoot;
|
|
27
|
-
const exists = fs.existsSync(from);
|
|
28
|
-
const measured = exists ? this.measure(from) : { bytes: 0, files: 0, partial: false };
|
|
29
|
-
const size = exists && holdsData(from) ? describeSize(measured) : 'nothing in it yet';
|
|
30
|
-
const to = await this.app.pickPath({
|
|
31
|
-
path: ['Data folder'],
|
|
32
|
-
title: 'Choose the folder for your saved data',
|
|
33
|
-
about: [
|
|
34
|
-
'Now: ' + from + ' (' + size + ').',
|
|
35
|
-
'Pick a new or empty folder to move your data there, or a folder that already holds data to use it.',
|
|
36
|
-
],
|
|
37
|
-
initial: from.replace(/[\\/][^\\/]*$/, '\\'),
|
|
38
|
-
use: 'use this folder',
|
|
39
|
-
validate: (picked) => {
|
|
40
|
-
const problem = moveProblem(from, picked, true);
|
|
41
|
-
return problem ? problem.message : true;
|
|
42
|
-
},
|
|
43
|
-
});
|
|
44
|
-
if (!to)
|
|
45
|
-
return undefined;
|
|
46
|
-
return this.decide(from, to, measured, exists);
|
|
47
|
-
}
|
|
48
|
-
measure(from) {
|
|
49
|
-
const before = this.app.status;
|
|
50
|
-
this.app.status = () => 'Measuring your saved data…';
|
|
51
|
-
this.app.redraw();
|
|
52
|
-
try {
|
|
53
|
-
return measureFolder(from, MEASURE_MS);
|
|
54
|
-
}
|
|
55
|
-
finally {
|
|
56
|
-
this.app.status = before;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
async decide(from, to, measured, exists) {
|
|
60
|
-
if (to.toLowerCase() === from.toLowerCase())
|
|
61
|
-
return undefined;
|
|
62
|
-
const target = holdsData(to);
|
|
63
|
-
const lines = [];
|
|
64
|
-
let canMove = exists && holdsData(from) && !target;
|
|
65
|
-
if (canMove) {
|
|
66
|
-
const est = estimate(from, to, measured);
|
|
67
|
-
lines.push('From: ' + from, 'To: ' + to, 'Size: ' + describeSize(measured));
|
|
68
|
-
lines.push(est.sameVolume
|
|
69
|
-
? 'Time: a few seconds (same drive, nothing is copied)'
|
|
70
|
-
: 'Time: ' + describeDuration(est.seconds) + ' (copied to another drive)');
|
|
71
|
-
if (est.freeBytes !== null)
|
|
72
|
-
lines.push('Free space on the target drive: ' + humanBytes(est.freeBytes));
|
|
73
|
-
const warning = moveWarning(measured, est);
|
|
74
|
-
if (warning)
|
|
75
|
-
lines.push('', warning);
|
|
76
|
-
if (!est.fits)
|
|
77
|
-
canMove = false;
|
|
78
|
-
}
|
|
79
|
-
else {
|
|
80
|
-
lines.push(target ? to + ' already holds data, so it is used as it is.' : 'There is nothing in ' + from + ' to move.', 'Your data stays where it is.');
|
|
81
|
-
}
|
|
82
|
-
const choice = await this.app.dialog({
|
|
83
|
-
title: canMove ? 'Move your data to ' + to + '?' : 'Use ' + to + '?',
|
|
84
|
-
lines: [...lines, '', 'Use without moving: the new folder is used from now on and your old data is left behind.'],
|
|
85
|
-
choices: [
|
|
86
|
-
...(canMove ? [{ value: 'move', label: 'Move data', key: 'm' }] : []),
|
|
87
|
-
{ value: 'use', label: 'Switch without moving', key: 's' },
|
|
88
|
-
{ value: 'cancel', label: 'Cancel', key: 'c' },
|
|
89
|
-
],
|
|
90
|
-
initial: 0,
|
|
91
|
-
escape: 'cancel',
|
|
92
|
-
});
|
|
93
|
-
if (choice === 'move')
|
|
94
|
-
return { kind: 'run', argv: ['storage', 'move', to, '--yes'] };
|
|
95
|
-
if (choice === 'use')
|
|
96
|
-
return { kind: 'run', argv: ['storage', 'use', to, '--yes'] };
|
|
97
|
-
return undefined;
|
|
98
|
-
}
|
|
99
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import type { Context } from '../commands/context.js';
|
|
2
|
-
import { type App } from '../tui/index.js';
|
|
3
|
-
/** The rows' ids in the settings list. */
|
|
4
|
-
export declare const EXPORT_SETTINGS = "@export-settings";
|
|
5
|
-
export declare const IMPORT_SETTINGS = "@import-settings";
|
|
6
|
-
export declare function shareSettingsRows(): {
|
|
7
|
-
value: string;
|
|
8
|
-
label: string;
|
|
9
|
-
hint: string;
|
|
10
|
-
description: string;
|
|
11
|
-
}[];
|
|
12
|
-
export declare class ShareSettingsFlow {
|
|
13
|
-
private readonly app;
|
|
14
|
-
private readonly ctx;
|
|
15
|
-
constructor(app: App, ctx: Context);
|
|
16
|
-
/** Your settings as they are on disk now (the menu may have saved changes since it started). */
|
|
17
|
-
private fresh;
|
|
18
|
-
/** Returns the notice to show (undefined when cancelled). */
|
|
19
|
-
export(): Promise<string | undefined>;
|
|
20
|
-
import(): Promise<string | undefined>;
|
|
21
|
-
}
|