windows-development-sandbox 1.9.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 +7 -2
- 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 +23 -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 -88
- package/dist/cli/commands/web.d.ts +7 -1
- package/dist/cli/commands/web.js +45 -71
- 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 +3 -2
- package/dist/core/schema/config.d.ts +6 -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/schema/vpn.js +1 -1
- package/dist/core/schema/web.d.ts +1 -0
- package/dist/core/schema/web.js +4 -1
- package/dist/core/types.d.ts +6 -3
- package/dist/guest/boot/boot.js +11 -1
- 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 +53 -15
- package/dist/guest/governor/decide.js +155 -72
- package/dist/guest/governor/governor.d.ts +2 -35
- package/dist/guest/governor/governor.js +35 -99
- package/dist/guest/governor/index.d.ts +1 -0
- package/dist/guest/governor/index.js +1 -0
- package/dist/guest/network/firewall.d.ts +3 -0
- package/dist/guest/network/firewall.js +65 -23
- package/dist/guest/runtime/process.js +53 -5
- package/dist/guest/sessions/viewer.js +5 -1
- package/dist/guest/setup/claude-mem.js +12 -4
- 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 +40 -4
- 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/host-memory.d.ts +1 -0
- package/dist/host/life/host-memory.js +4 -1
- package/dist/host/life/watchdog.d.ts +11 -0
- package/dist/host/life/watchdog.js +36 -4
- 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 +44 -16
- package/dist/runtime/daemon.js +1154 -857
- package/dist/runtime/db.js +44 -16
- package/dist/runtime/main.js +532 -115
- package/dist/runtime/netproxy.js +34 -9
- package/dist/runtime/view.js +499 -149
- 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/guest-boot.test.js +47 -1
- package/dist/selftest/hcs.test.js +105 -8
- package/dist/selftest/health.test.js +71 -0
- package/dist/selftest/heavy-load.test.js +152 -66
- 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/network.test.js +20 -1
- 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 +5 -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/io/copy-tree.d.ts +7 -0
- package/dist/shared/io/copy-tree.js +45 -0
- package/dist/shared/io/index.d.ts +2 -0
- package/dist/shared/io/index.js +2 -0
- package/dist/shared/io/robocopy-result.d.ts +6 -0
- package/dist/shared/io/robocopy-result.js +23 -0
- package/dist/shared/memory/policy.d.ts +38 -12
- package/dist/shared/memory/policy.js +58 -19
- package/dist/shared/network/firewall-rules.d.ts +8 -0
- package/dist/shared/network/firewall-rules.js +28 -0
- 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/native/csharp/HostTools/MemoryStatus.cs +128 -107
- package/native/scripts/memory-status.ps1 +10 -2
- package/package.json +10 -3
- package/sandbox/csharp/MemGov.cs +668 -398
- 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/new-shortcuts.ps1 +3 -1
- package/sandbox/scripts/repair-wmi-services.ps1 +26 -0
- package/schemas/config.schema.json +25 -7
- 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
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
// The projects a sandbox can open without a restart: the list, roots, include/exclude, the all-projects setting, and
|
|
2
|
+
// choosing the ticked ones. Pure: schemas, labels and the view; projects.run.ts does the work.
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
import { action, defineOperation, defineQuery, defineView, fieldsOf, } from '../../kernel/index.js';
|
|
5
|
+
export const ProjectRowSchema = z.object({
|
|
6
|
+
folder: z.string().describe('The project folder on this PC'),
|
|
7
|
+
here: z.boolean().describe('The folder you are in is inside it'),
|
|
8
|
+
known: z.boolean().describe('Started with this tool before'),
|
|
9
|
+
root: z.string().nullable().describe('The project root it is in, if any'),
|
|
10
|
+
excluded: z.boolean().describe('Excluded from the projects mapped at every start'),
|
|
11
|
+
mappedAtStart: z.boolean().describe('Mapped at every start'),
|
|
12
|
+
running: z.string().nullable().describe('Its name and how it got into the running sandbox, if it is there'),
|
|
13
|
+
});
|
|
14
|
+
export const ProjectsListSchema = z.object({
|
|
15
|
+
all: z.boolean().describe('Every project is mapped at every start (except excluded ones)'),
|
|
16
|
+
roots: z.array(z.string()).describe('Folders of projects, each opened without a restart'),
|
|
17
|
+
exclude: z.array(z.string()).describe('Folders left out of the projects mapped at every start'),
|
|
18
|
+
projects: z.array(ProjectRowSchema).describe('Every project worth listing'),
|
|
19
|
+
});
|
|
20
|
+
const Message = z.object({ message: z.string().describe('What happened') });
|
|
21
|
+
const FolderText = (what) => z
|
|
22
|
+
.string()
|
|
23
|
+
.optional()
|
|
24
|
+
.describe(what + ' (. = this folder; asked when left out)');
|
|
25
|
+
export const listProjects = defineQuery({
|
|
26
|
+
id: 'projects.list',
|
|
27
|
+
title: 'Projects',
|
|
28
|
+
summary: 'list your projects, roots and the all-projects setting',
|
|
29
|
+
input: z.object({}),
|
|
30
|
+
output: ProjectsListSchema,
|
|
31
|
+
cli: { name: 'projects', action: 'list', json: true },
|
|
32
|
+
});
|
|
33
|
+
export const chooseProjects = defineOperation({
|
|
34
|
+
id: 'projects.choose',
|
|
35
|
+
title: 'Choose the projects mapped at every start…',
|
|
36
|
+
summary: 'tick the projects mapped at every start; the rest are excluded',
|
|
37
|
+
input: z.object({}),
|
|
38
|
+
output: Message,
|
|
39
|
+
text: (o) => o.message,
|
|
40
|
+
cli: { name: 'projects', action: 'choose' },
|
|
41
|
+
});
|
|
42
|
+
export const addProject = defineOperation({
|
|
43
|
+
id: 'projects.add',
|
|
44
|
+
title: 'Add a project…',
|
|
45
|
+
summary: 'remember a project folder',
|
|
46
|
+
input: z.object({ projectFolder: FolderText('The project folder') }),
|
|
47
|
+
output: z.object({
|
|
48
|
+
message: z.string().describe('What happened'),
|
|
49
|
+
next: z.string().optional().describe('What to do next, when mapping all projects is off'),
|
|
50
|
+
}),
|
|
51
|
+
text: (o) => (o.next ? o.message + '\n' + o.next : o.message),
|
|
52
|
+
cli: { name: 'projects', action: 'add', positional: ['projectFolder'] },
|
|
53
|
+
});
|
|
54
|
+
export const removeProject = defineOperation({
|
|
55
|
+
id: 'projects.remove',
|
|
56
|
+
title: 'Forget project',
|
|
57
|
+
summary: 'forget a project (nothing in the folder is touched)',
|
|
58
|
+
input: z.object({ projectFolder: FolderText('The project folder') }),
|
|
59
|
+
output: Message,
|
|
60
|
+
danger: true,
|
|
61
|
+
text: (o) => o.message,
|
|
62
|
+
cli: { name: 'projects', action: 'remove', positional: ['projectFolder'] },
|
|
63
|
+
});
|
|
64
|
+
export const includeProject = defineOperation({
|
|
65
|
+
id: 'projects.include',
|
|
66
|
+
title: 'Include',
|
|
67
|
+
summary: 'map a project at every start again',
|
|
68
|
+
input: z.object({ projectFolder: FolderText('The project folder') }),
|
|
69
|
+
output: Message,
|
|
70
|
+
text: (o) => o.message,
|
|
71
|
+
cli: { name: 'projects', action: 'include', positional: ['projectFolder'] },
|
|
72
|
+
});
|
|
73
|
+
export const excludeProject = defineOperation({
|
|
74
|
+
id: 'projects.exclude',
|
|
75
|
+
title: 'Exclude',
|
|
76
|
+
summary: 'leave a project out of the projects mapped at every start',
|
|
77
|
+
input: z.object({ projectFolder: FolderText('The project folder') }),
|
|
78
|
+
output: Message,
|
|
79
|
+
text: (o) => o.message,
|
|
80
|
+
cli: { name: 'projects', action: 'exclude', positional: ['projectFolder'] },
|
|
81
|
+
});
|
|
82
|
+
export const allProjects = defineOperation({
|
|
83
|
+
id: 'projects.all',
|
|
84
|
+
title: 'Map all projects at every start',
|
|
85
|
+
summary: 'map every project at every start, or not',
|
|
86
|
+
input: z.object({ state: z.enum(['on', 'off']).optional().describe('on or off (left out: say which it is)') }),
|
|
87
|
+
output: Message,
|
|
88
|
+
text: (o) => o.message,
|
|
89
|
+
cli: { name: 'projects', action: 'all', positional: ['state'] },
|
|
90
|
+
});
|
|
91
|
+
export const projectRoots = defineOperation({
|
|
92
|
+
id: 'projects.roots',
|
|
93
|
+
title: 'Project roots',
|
|
94
|
+
summary: 'list, add or remove project roots',
|
|
95
|
+
input: z.object({
|
|
96
|
+
change: z.enum(['list', 'add', 'remove']).default('list').describe('list, add or remove'),
|
|
97
|
+
rootFolder: z.string().optional().describe('(add, remove) the folder that holds your projects'),
|
|
98
|
+
}),
|
|
99
|
+
output: Message,
|
|
100
|
+
text: (o) => o.message,
|
|
101
|
+
cli: { name: 'projects', action: 'roots', positional: ['change', 'rootFolder'] },
|
|
102
|
+
});
|
|
103
|
+
/** The folder fields: their names end in Folder, so the menu and the web give them the folder picker. */
|
|
104
|
+
const rootField = fieldsOf(projectRoots.input).find((f) => f.name === 'rootFolder');
|
|
105
|
+
const projectField = fieldsOf(addProject.input).find((f) => f.name === 'projectFolder');
|
|
106
|
+
const ROOT_DESCRIPTION = 'Every project in this folder (also new ones) opens without a restart.';
|
|
107
|
+
function atStart(p) {
|
|
108
|
+
return p.root ? 'root' : p.excluded ? 'excluded' : p.mappedAtStart ? 'mapped' : '-';
|
|
109
|
+
}
|
|
110
|
+
function projectItem(p) {
|
|
111
|
+
return {
|
|
112
|
+
id: 'project:' + p.folder,
|
|
113
|
+
label: p.folder,
|
|
114
|
+
marked: p.here,
|
|
115
|
+
icon: 'project',
|
|
116
|
+
hint: p.running ?? (p.root ? 'in a root' : p.excluded ? 'excluded' : p.mappedAtStart ? 'mapped' : '-'),
|
|
117
|
+
description: p.here ? 'This is the folder you started the menu in.' : undefined,
|
|
118
|
+
details: ['At start ' + atStart(p), 'In sandbox ' + (p.running ?? '-')],
|
|
119
|
+
cells: { here: p.here ? '*' : '', folder: p.folder, atStart: atStart(p), running: p.running ?? '-' },
|
|
120
|
+
actions: [
|
|
121
|
+
action(removeProject, { projectFolder: p.folder }, { key: 'f', verb: 'forget project', importance: 1 }),
|
|
122
|
+
p.excluded
|
|
123
|
+
? action(includeProject, { projectFolder: p.folder })
|
|
124
|
+
: action(excludeProject, { projectFolder: p.folder }),
|
|
125
|
+
],
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
function rootItem(r) {
|
|
129
|
+
return {
|
|
130
|
+
id: 'root:' + r,
|
|
131
|
+
label: r,
|
|
132
|
+
hint: 'root',
|
|
133
|
+
icon: 'folder',
|
|
134
|
+
description: ROOT_DESCRIPTION,
|
|
135
|
+
keys: 'f removes the root.',
|
|
136
|
+
actions: [
|
|
137
|
+
action(projectRoots, { change: 'remove', rootFolder: r }, { label: 'Remove the root', key: 'f', verb: 'remove root', importance: 1 }),
|
|
138
|
+
],
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
/** The projects page: the settings, the project roots, and the projects (the same rows as the menu's Projects). */
|
|
142
|
+
export function projectsPage(o) {
|
|
143
|
+
const settings = {
|
|
144
|
+
id: 'settings',
|
|
145
|
+
facts: [
|
|
146
|
+
{
|
|
147
|
+
id: 'all',
|
|
148
|
+
label: 'All projects',
|
|
149
|
+
value: o.all ? 'on (every project below is mapped at every start, except excluded ones)' : 'off',
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
id: 'roots',
|
|
153
|
+
label: 'Roots',
|
|
154
|
+
value: o.roots.length ? o.roots.join(', ') : 'none (sandbox projects roots add <folder>)',
|
|
155
|
+
},
|
|
156
|
+
],
|
|
157
|
+
actions: [
|
|
158
|
+
action(allProjects, { state: o.all ? 'off' : 'on' }, { label: o.all ? 'Stop mapping all projects' : 'Map all projects at every start' }),
|
|
159
|
+
],
|
|
160
|
+
notes: [{ text: 'sandbox projects all on|off', tone: 'muted', only: 'cli' }],
|
|
161
|
+
};
|
|
162
|
+
const roots = {
|
|
163
|
+
id: 'roots',
|
|
164
|
+
title: 'Project roots',
|
|
165
|
+
items: [
|
|
166
|
+
{
|
|
167
|
+
id: '@add-root',
|
|
168
|
+
label: '+ Add a project root…',
|
|
169
|
+
description: 'Pick a folder that holds your projects: every project in it (also new ones) opens without a restart.',
|
|
170
|
+
primary: action(projectRoots, { change: 'add' }, { label: 'Choose the folder…', verb: 'choose folder', fields: [rootField] }),
|
|
171
|
+
},
|
|
172
|
+
...o.roots.map(rootItem),
|
|
173
|
+
],
|
|
174
|
+
};
|
|
175
|
+
const projects = {
|
|
176
|
+
id: 'projects',
|
|
177
|
+
title: 'Projects',
|
|
178
|
+
columns: [
|
|
179
|
+
{ key: 'here', label: '' },
|
|
180
|
+
{ key: 'folder', label: 'FOLDER' },
|
|
181
|
+
{ key: 'atStart', label: 'AT START' },
|
|
182
|
+
{ key: 'running', label: 'RUNNING SANDBOX' },
|
|
183
|
+
],
|
|
184
|
+
// The web lists the rows in full (its table cannot carry the row actions: forget, include, exclude).
|
|
185
|
+
columnsOn: 'cli',
|
|
186
|
+
items: o.projects.map(projectItem),
|
|
187
|
+
notes: o.projects.length === 0
|
|
188
|
+
? [{ text: 'No projects yet: start one with sandbox claude in its folder.', tone: 'muted' }]
|
|
189
|
+
: [{ text: '* = this folder. Choose with: sandbox projects choose', tone: 'muted', only: 'cli' }],
|
|
190
|
+
};
|
|
191
|
+
return {
|
|
192
|
+
title: 'Projects',
|
|
193
|
+
sections: [settings, roots, projects],
|
|
194
|
+
actions: [
|
|
195
|
+
action(chooseProjects, {}, { label: 'Choose…' }),
|
|
196
|
+
action(addProject, {}, { fields: [projectField] }),
|
|
197
|
+
action(projectRoots, { change: 'add' }, { label: 'Add a project root…', key: 'a', verb: 'add root', importance: 1, fields: [rootField] }),
|
|
198
|
+
],
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
export const projectsView = defineView({
|
|
202
|
+
id: 'projects',
|
|
203
|
+
title: 'Projects',
|
|
204
|
+
summary: 'The projects a sandbox opens without a restart: roots, your projects, all or chosen.',
|
|
205
|
+
queries: { projects: listProjects },
|
|
206
|
+
operations: [chooseProjects, addProject, removeProject, includeProject, excludeProject, allProjects, projectRoots],
|
|
207
|
+
build: ({ projects }) => projectsPage(projects),
|
|
208
|
+
});
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
export declare const listProjectsRun: import("../../kernel/define.js").Implementation<import("../../kernel/define.js").QueryDef<import("zod").ZodObject<{}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
|
|
2
|
+
all: import("zod").ZodBoolean;
|
|
3
|
+
roots: import("zod").ZodArray<import("zod").ZodString>;
|
|
4
|
+
exclude: import("zod").ZodArray<import("zod").ZodString>;
|
|
5
|
+
projects: import("zod").ZodArray<import("zod").ZodObject<{
|
|
6
|
+
folder: import("zod").ZodString;
|
|
7
|
+
here: import("zod").ZodBoolean;
|
|
8
|
+
known: import("zod").ZodBoolean;
|
|
9
|
+
root: import("zod").ZodNullable<import("zod").ZodString>;
|
|
10
|
+
excluded: import("zod").ZodBoolean;
|
|
11
|
+
mappedAtStart: import("zod").ZodBoolean;
|
|
12
|
+
running: import("zod").ZodNullable<import("zod").ZodString>;
|
|
13
|
+
}, import("zod/v4/core").$strip>>;
|
|
14
|
+
}, import("zod/v4/core").$strip>, "projects.list">, import("../../../cli/commands/context.js").Context>;
|
|
15
|
+
export declare const chooseProjectsRun: import("../../kernel/define.js").Implementation<import("../../kernel/define.js").OperationDef<import("zod").ZodObject<{}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
|
|
16
|
+
message: import("zod").ZodString;
|
|
17
|
+
}, import("zod/v4/core").$strip>, "projects.choose">, import("../../../cli/commands/context.js").Context>;
|
|
18
|
+
export declare const addProjectRun: import("../../kernel/define.js").Implementation<import("../../kernel/define.js").OperationDef<import("zod").ZodObject<{
|
|
19
|
+
projectFolder: import("zod").ZodOptional<import("zod").ZodString>;
|
|
20
|
+
}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
|
|
21
|
+
message: import("zod").ZodString;
|
|
22
|
+
next: import("zod").ZodOptional<import("zod").ZodString>;
|
|
23
|
+
}, import("zod/v4/core").$strip>, "projects.add">, import("../../../cli/commands/context.js").Context>;
|
|
24
|
+
export declare const removeProjectRun: import("../../kernel/define.js").Implementation<import("../../kernel/define.js").OperationDef<import("zod").ZodObject<{
|
|
25
|
+
projectFolder: import("zod").ZodOptional<import("zod").ZodString>;
|
|
26
|
+
}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
|
|
27
|
+
message: import("zod").ZodString;
|
|
28
|
+
}, import("zod/v4/core").$strip>, "projects.remove">, import("../../../cli/commands/context.js").Context>;
|
|
29
|
+
export declare const includeProjectRun: import("../../kernel/define.js").Implementation<import("../../kernel/define.js").OperationDef<import("zod").ZodObject<{
|
|
30
|
+
projectFolder: import("zod").ZodOptional<import("zod").ZodString>;
|
|
31
|
+
}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
|
|
32
|
+
message: import("zod").ZodString;
|
|
33
|
+
}, import("zod/v4/core").$strip>, "projects.include">, import("../../../cli/commands/context.js").Context>;
|
|
34
|
+
export declare const excludeProjectRun: import("../../kernel/define.js").Implementation<import("../../kernel/define.js").OperationDef<import("zod").ZodObject<{
|
|
35
|
+
projectFolder: import("zod").ZodOptional<import("zod").ZodString>;
|
|
36
|
+
}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
|
|
37
|
+
message: import("zod").ZodString;
|
|
38
|
+
}, import("zod/v4/core").$strip>, "projects.exclude">, import("../../../cli/commands/context.js").Context>;
|
|
39
|
+
export declare const allProjectsRun: import("../../kernel/define.js").Implementation<import("../../kernel/define.js").OperationDef<import("zod").ZodObject<{
|
|
40
|
+
state: import("zod").ZodOptional<import("zod").ZodEnum<{
|
|
41
|
+
off: "off";
|
|
42
|
+
on: "on";
|
|
43
|
+
}>>;
|
|
44
|
+
}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
|
|
45
|
+
message: import("zod").ZodString;
|
|
46
|
+
}, import("zod/v4/core").$strip>, "projects.all">, import("../../../cli/commands/context.js").Context>;
|
|
47
|
+
export declare const projectRootsRun: import("../../kernel/define.js").Implementation<import("../../kernel/define.js").OperationDef<import("zod").ZodObject<{
|
|
48
|
+
change: import("zod").ZodDefault<import("zod").ZodEnum<{
|
|
49
|
+
list: "list";
|
|
50
|
+
add: "add";
|
|
51
|
+
remove: "remove";
|
|
52
|
+
}>>;
|
|
53
|
+
rootFolder: import("zod").ZodOptional<import("zod").ZodString>;
|
|
54
|
+
}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
|
|
55
|
+
message: import("zod").ZodString;
|
|
56
|
+
}, import("zod/v4/core").$strip>, "projects.roots">, import("../../../cli/commands/context.js").Context>;
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
// The projects feature's work: your project list, roots and the all-projects setting, through ProjectsService. Talks
|
|
2
|
+
// only through io. Changes what is mapped from the next start; a running sandbox keeps what it has.
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { isSandboxRunning } from '../../../host/sandbox/index.js';
|
|
5
|
+
import { fail } from '../../../core/util/index.js';
|
|
6
|
+
import { hereDir } from '../../../cli/commands/projects/here.js';
|
|
7
|
+
import { ProjectsService } from '../../../cli/services/index.js';
|
|
8
|
+
import { implement } from '../../context.js';
|
|
9
|
+
import { cancelled } from '../../kernel/index.js';
|
|
10
|
+
import { addProject, allProjects, chooseProjects, excludeProject, includeProject, listProjects, projectRoots, removeProject, } from './projects.def.js';
|
|
11
|
+
const NEXT_START = 'This changes what is mapped from the next start.';
|
|
12
|
+
function runningNote() {
|
|
13
|
+
return isSandboxRunning()
|
|
14
|
+
? ' The running sandbox keeps what it has; start a project in it (sandbox claude there) and it joins without a restart when it can, or you are offered one.'
|
|
15
|
+
: '';
|
|
16
|
+
}
|
|
17
|
+
/** The folder given, or one picked from the known projects (or this folder) when it was left out. */
|
|
18
|
+
async function pickFolder(ctx, io, given) {
|
|
19
|
+
if (given)
|
|
20
|
+
return path.resolve(given);
|
|
21
|
+
const here = hereDir(ctx);
|
|
22
|
+
const chosen = await io.choose({
|
|
23
|
+
title: 'Which folder?',
|
|
24
|
+
choices: [
|
|
25
|
+
{ value: here, label: 'This folder (' + here + ')' },
|
|
26
|
+
...new ProjectsService(ctx)
|
|
27
|
+
.rows()
|
|
28
|
+
.filter((r) => !r.here)
|
|
29
|
+
.map((r) => ({ value: r.folder, label: r.folder })),
|
|
30
|
+
],
|
|
31
|
+
});
|
|
32
|
+
if (chosen === undefined)
|
|
33
|
+
cancelled();
|
|
34
|
+
return chosen;
|
|
35
|
+
}
|
|
36
|
+
export const listProjectsRun = implement(listProjects, async (ctx) => new ProjectsService(ctx).list());
|
|
37
|
+
export const chooseProjectsRun = implement(chooseProjects, async (ctx, _input, io) => {
|
|
38
|
+
const service = new ProjectsService(ctx);
|
|
39
|
+
const rows = service.rows().filter((r) => !r.root);
|
|
40
|
+
if (!rows.length)
|
|
41
|
+
return {
|
|
42
|
+
message: 'No projects to choose from yet (projects in a root are always mapped with it). Start one with sandbox claude in its folder.',
|
|
43
|
+
};
|
|
44
|
+
const all = service.settings().all;
|
|
45
|
+
const picked = await io.checklist({
|
|
46
|
+
title: 'Projects mapped at every start, so they open without a restart (every agent in the sandbox can see them):',
|
|
47
|
+
choices: rows.map((r) => ({ value: r.folder, label: r.folder + (r.here ? ' (this folder)' : '') })),
|
|
48
|
+
checked: rows.filter((r) => all && !r.excluded).map((r) => r.folder),
|
|
49
|
+
});
|
|
50
|
+
if (picked === undefined)
|
|
51
|
+
cancelled();
|
|
52
|
+
const { mapped, excluded } = service.choose(rows, picked);
|
|
53
|
+
return {
|
|
54
|
+
message: mapped + ' project(s) mapped at every start, ' + excluded + ' excluded. ' + NEXT_START + runningNote(),
|
|
55
|
+
};
|
|
56
|
+
});
|
|
57
|
+
export const addProjectRun = implement(addProject, async (ctx, input, io) => {
|
|
58
|
+
const folder = await pickFolder(ctx, io, input.projectFolder);
|
|
59
|
+
const service = new ProjectsService(ctx);
|
|
60
|
+
const dir = service.add(folder);
|
|
61
|
+
const all = service.settings().all;
|
|
62
|
+
return {
|
|
63
|
+
message: 'Added ' + dir + ' to your projects.' + (all ? ' ' + NEXT_START : ''),
|
|
64
|
+
...(all ? {} : { next: 'Next: sandbox projects all on (map every project at every start)' }),
|
|
65
|
+
};
|
|
66
|
+
});
|
|
67
|
+
export const removeProjectRun = implement(removeProject, async (ctx, input, io) => {
|
|
68
|
+
const dir = await pickFolder(ctx, io, input.projectFolder);
|
|
69
|
+
const yes = await io.confirm({
|
|
70
|
+
title: 'Forget ' + path.basename(dir) + '?',
|
|
71
|
+
lines: ['The project is dropped from your list of projects.', 'Nothing in ' + dir + ' is touched.'],
|
|
72
|
+
yes: 'Forget',
|
|
73
|
+
danger: true,
|
|
74
|
+
implied: true,
|
|
75
|
+
});
|
|
76
|
+
if (!yes)
|
|
77
|
+
cancelled();
|
|
78
|
+
const { dir: forgotten, removed } = new ProjectsService(ctx).forget(dir);
|
|
79
|
+
return {
|
|
80
|
+
message: removed
|
|
81
|
+
? 'Removed ' + forgotten + ' from your projects (nothing in the folder was touched).'
|
|
82
|
+
: forgotten + ' was not in your projects.',
|
|
83
|
+
};
|
|
84
|
+
});
|
|
85
|
+
export const includeProjectRun = implement(includeProject, async (ctx, input, io) => {
|
|
86
|
+
const dir = await pickFolder(ctx, io, input.projectFolder);
|
|
87
|
+
const service = new ProjectsService(ctx);
|
|
88
|
+
const changed = service.include(dir);
|
|
89
|
+
return { message: includeOrExcludeText(service, 'include', dir, changed) };
|
|
90
|
+
});
|
|
91
|
+
export const excludeProjectRun = implement(excludeProject, async (ctx, input, io) => {
|
|
92
|
+
const dir = await pickFolder(ctx, io, input.projectFolder);
|
|
93
|
+
const service = new ProjectsService(ctx);
|
|
94
|
+
const changed = service.exclude(dir);
|
|
95
|
+
return { message: includeOrExcludeText(service, 'exclude', dir, changed) };
|
|
96
|
+
});
|
|
97
|
+
/** The sentence include and exclude print. */
|
|
98
|
+
function includeOrExcludeText(service, action, dir, changed) {
|
|
99
|
+
return ((changed
|
|
100
|
+
? (action === 'exclude' ? 'Excluded ' : 'Included ') + path.resolve(dir) + '. ' + NEXT_START
|
|
101
|
+
: 'Nothing changed.') +
|
|
102
|
+
(action === 'include' && !service.settings().all
|
|
103
|
+
? ' Mapping all projects is off: sandbox projects all on maps your projects at every start.'
|
|
104
|
+
: '') +
|
|
105
|
+
(changed ? runningNote() : ''));
|
|
106
|
+
}
|
|
107
|
+
export const allProjectsRun = implement(allProjects, async (ctx, input) => {
|
|
108
|
+
const service = new ProjectsService(ctx);
|
|
109
|
+
if (input.state === undefined)
|
|
110
|
+
return { message: 'Mapping all projects at every start is ' + (service.settings().all ? 'on' : 'off') + '.' };
|
|
111
|
+
service.setAll(input.state === 'on');
|
|
112
|
+
return {
|
|
113
|
+
message: 'Mapping all projects at every start is ' +
|
|
114
|
+
input.state +
|
|
115
|
+
'. ' +
|
|
116
|
+
NEXT_START +
|
|
117
|
+
(input.state === 'on' ? ' Every agent in the sandbox can then see all of those projects.' : '') +
|
|
118
|
+
runningNote(),
|
|
119
|
+
};
|
|
120
|
+
});
|
|
121
|
+
export const projectRootsRun = implement(projectRoots, async (ctx, input, io) => {
|
|
122
|
+
const service = new ProjectsService(ctx);
|
|
123
|
+
if (input.change === 'list') {
|
|
124
|
+
const list = service.settings().roots;
|
|
125
|
+
return {
|
|
126
|
+
message: list.length ? list.join('\n') : 'No project roots. Add one: sandbox projects roots add <folder>',
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
if (!input.rootFolder)
|
|
130
|
+
fail('Which folder?', 'Usage: sandbox projects roots ' + input.change + ' <folder>');
|
|
131
|
+
if (input.change === 'add') {
|
|
132
|
+
const { dir, added } = service.addRoot(input.rootFolder);
|
|
133
|
+
return {
|
|
134
|
+
message: added
|
|
135
|
+
? 'Added the project root ' +
|
|
136
|
+
dir +
|
|
137
|
+
': every project in it (also new ones) opens without a restart. Every agent in the sandbox can see all of them. ' +
|
|
138
|
+
NEXT_START +
|
|
139
|
+
runningNote()
|
|
140
|
+
: dir + ' is a root already.',
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
const dir = path.resolve(input.rootFolder);
|
|
144
|
+
const yes = await io.confirm({
|
|
145
|
+
title: 'Remove the root ' + path.basename(dir) + '?',
|
|
146
|
+
lines: ['Its projects are no longer opened without a restart.', 'Nothing in ' + dir + ' is touched.'],
|
|
147
|
+
yes: 'Remove',
|
|
148
|
+
danger: true,
|
|
149
|
+
implied: true,
|
|
150
|
+
});
|
|
151
|
+
if (!yes)
|
|
152
|
+
cancelled();
|
|
153
|
+
const { removed } = service.removeRoot(dir);
|
|
154
|
+
return { message: removed ? 'Removed the project root ' + dir + '. ' + NEXT_START : dir + ' was not a root.' };
|
|
155
|
+
});
|
|
@@ -126,6 +126,7 @@ function projectItem(p) {
|
|
|
126
126
|
return {
|
|
127
127
|
id: 'project:' + p.name,
|
|
128
128
|
label: p.name,
|
|
129
|
+
icon: 'project',
|
|
129
130
|
hint: p.host + ' -> ' + p.guest + ' (' + (MECHANISM_TEXT[p.mechanism] ?? 'wsb share') + ')',
|
|
130
131
|
marked: p.here,
|
|
131
132
|
details: [
|
|
@@ -149,11 +150,12 @@ function facts(o) {
|
|
|
149
150
|
});
|
|
150
151
|
return [
|
|
151
152
|
...(o.shared?.startedBy ? [fact('owner', 'Started by', o.shared.startedBy)] : []),
|
|
152
|
-
|
|
153
|
+
// One line for what it is doing: "Ready", "Installing Rust ...", or "not running".
|
|
154
|
+
fact('state', 'State', s.running ? s.message || s.phase : 'not running', {
|
|
155
|
+
tone: !s.running ? 'muted' : s.phase === 'ready' ? 'ok' : 'warn',
|
|
156
|
+
}),
|
|
153
157
|
...(s.running
|
|
154
158
|
? [
|
|
155
|
-
fact('phase', 'Phase', s.phase, { tone: s.phase === 'ready' ? 'ok' : 'warn' }),
|
|
156
|
-
fact('message', 'Message', s.message || '-'),
|
|
157
159
|
fact('window', 'Window', s.headless ? 'hidden (sandbox show opens it)' : 'shown'),
|
|
158
160
|
fact('uptime', 'Uptime', uptime(s) ?? '-'),
|
|
159
161
|
fact('helper', 'Helper', s.daemon === '-' ? '-' : helperText(s.daemon)),
|
|
@@ -168,6 +170,7 @@ function projectsSection(o) {
|
|
|
168
170
|
const roots = o.roots.map((r) => ({
|
|
169
171
|
id: 'root:' + r.host,
|
|
170
172
|
label: 'root',
|
|
173
|
+
icon: 'folder',
|
|
171
174
|
hint: r.host + ' -> ' + r.guest + ' (every project in it opens without a restart)',
|
|
172
175
|
}));
|
|
173
176
|
const here = o.projects.some((p) => p.here);
|
|
@@ -206,11 +209,14 @@ export function sandboxPage(o) {
|
|
|
206
209
|
const running = o.sandbox.running;
|
|
207
210
|
const status = {
|
|
208
211
|
id: 'status',
|
|
212
|
+
title: 'Status',
|
|
209
213
|
facts: facts(o),
|
|
214
|
+
// Only the window action that changes something: show a hidden window, hide a shown one.
|
|
210
215
|
actions: running
|
|
211
216
|
? [
|
|
212
|
-
|
|
213
|
-
|
|
217
|
+
o.sandbox.headless
|
|
218
|
+
? action(showWindow, {}, { key: 'w', verb: 'show', importance: 3 })
|
|
219
|
+
: action(hideWindow, {}, { key: 'h', verb: 'hide', importance: 3 }),
|
|
214
220
|
action(stopSandbox, {}, { key: 'x', verb: 'stop', importance: 1 }),
|
|
215
221
|
]
|
|
216
222
|
: [],
|
|
@@ -92,6 +92,7 @@ function sessionItem(s, wide) {
|
|
|
92
92
|
badges: [{ text: s.phase, tone: running ? 'ok' : s.phase === 'failed' ? 'danger' : 'muted' }],
|
|
93
93
|
group: s.here ? "This folder's project" : 'Other sessions',
|
|
94
94
|
marked: s.here,
|
|
95
|
+
icon: s.harness,
|
|
95
96
|
description: running
|
|
96
97
|
? "Opens this session's terminal (in a terminal, Ctrl+] detaches; the session keeps running)."
|
|
97
98
|
: undefined,
|
|
@@ -126,6 +127,7 @@ export function sessionsPage(o) {
|
|
|
126
127
|
sections: [
|
|
127
128
|
{
|
|
128
129
|
id: 'sessions',
|
|
130
|
+
cards: true,
|
|
129
131
|
columns: [
|
|
130
132
|
{ key: 'here', label: '' },
|
|
131
133
|
{ key: 'id', label: 'ID' },
|
|
@@ -147,6 +149,7 @@ export function sessionsPage(o) {
|
|
|
147
149
|
...startSection,
|
|
148
150
|
],
|
|
149
151
|
actions: [
|
|
152
|
+
...(o.sandboxRunning ? [{ ...start, label: 'New session', key: 'n', verb: 'new session', importance: 1 }] : []),
|
|
150
153
|
...(sessions.length
|
|
151
154
|
? [action(restartSessions, { all: false }, { key: 'r', verb: 'restart agents', importance: 1 })]
|
|
152
155
|
: []),
|
|
@@ -42,8 +42,8 @@ export const CATEGORIES = [
|
|
|
42
42
|
{
|
|
43
43
|
id: 'security',
|
|
44
44
|
label: 'Security & privacy',
|
|
45
|
-
description: 'Git-ignored files kept out, secrets kept out of the sandbox, download checks, what is kept on this PC, and sharing your sandbox with other Windows users.',
|
|
46
|
-
keys: ['workspaceFilter', 'audit', 'secrets', 'downloads', 'storage', 'sharing'],
|
|
45
|
+
description: 'Git-ignored files kept out, secrets kept out of the sandbox, a GitHub token for sandboxes (with its login set here), download checks, what is kept on this PC, and sharing your sandbox with other Windows users.',
|
|
46
|
+
keys: ['workspaceFilter', 'audit', 'secrets', 'github', 'downloads', 'storage', 'sharing'],
|
|
47
47
|
},
|
|
48
48
|
{
|
|
49
49
|
id: 'projects',
|
|
@@ -67,6 +67,7 @@ const NAMES = {
|
|
|
67
67
|
storage: 'Storage on this PC',
|
|
68
68
|
network: 'Network',
|
|
69
69
|
vpn: 'VPN',
|
|
70
|
+
github: 'GitHub',
|
|
70
71
|
hooks: 'Hooks',
|
|
71
72
|
personalization: 'Desktop look',
|
|
72
73
|
projects: 'Projects',
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Config } from '../../../core/types.js';
|
|
2
|
-
import type { SettingChange } from '
|
|
2
|
+
import type { SettingChange } from './settings-file.js';
|
|
3
3
|
/** Why something was left out. */
|
|
4
4
|
export interface Skipped {
|
|
5
5
|
readonly key: string;
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
// Sharing your settings: the part of them that differs from the defaults, as a .json a team can pass around, and the
|
|
2
2
|
// reverse (read a file, show what it would change, apply the rest). Secrets (anything the schema marks), the data
|
|
3
|
-
// folder and folders or files of this PC never go into a file and are never taken from one.
|
|
3
|
+
// folder and folders or files of this PC never go into a file and are never taken from one. Node side (lodash,
|
|
4
|
+
// core/schema): the settings run functions use these; the menu and the web only see the operations.
|
|
4
5
|
import { parse } from 'jsonc-parser';
|
|
5
6
|
import _ from 'lodash';
|
|
6
7
|
import { DEFAULTS, mergeConfig } from '../../../core/config/index.js';
|
|
7
8
|
import { ConfigSchema, describeIssues, secretPaths } from '../../../core/schema/index.js';
|
|
8
|
-
import { pathKindOf } from '
|
|
9
|
+
import { pathKindOf } from '../../kernel/index.js';
|
|
9
10
|
/** Settings that are about this PC and never travel (the data folder). */
|
|
10
11
|
const MACHINE_ONLY = ['storage.root'];
|
|
11
12
|
/** A folder or file of this PC: a drive path, a network path, a rooted path or a %VARIABLE% path. */
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { type Page } from '../../kernel/index.js';
|
|
2
|
+
import { type Field, type Page } from '../../kernel/index.js';
|
|
3
3
|
export declare const ScopeSchema: z.ZodEnum<{
|
|
4
4
|
project: "project";
|
|
5
5
|
user: "user";
|
|
@@ -12,7 +12,7 @@ export declare const SettingRowSchema: z.ZodObject<{
|
|
|
12
12
|
label: z.ZodString;
|
|
13
13
|
category: z.ZodString;
|
|
14
14
|
section: z.ZodOptional<z.ZodString>;
|
|
15
|
-
field: z.ZodType<
|
|
15
|
+
field: z.ZodType<Field, unknown, z.core.$ZodTypeInternals<Field, unknown>>;
|
|
16
16
|
value: z.ZodUnknown;
|
|
17
17
|
set: z.ZodBoolean;
|
|
18
18
|
yours: z.ZodUnknown;
|
|
@@ -30,6 +30,7 @@ export declare const SettingsListSchema: z.ZodObject<{
|
|
|
30
30
|
file: z.ZodString;
|
|
31
31
|
exists: z.ZodBoolean;
|
|
32
32
|
dataFolder: z.ZodOptional<z.ZodString>;
|
|
33
|
+
exportFile: z.ZodOptional<z.ZodString>;
|
|
33
34
|
categories: z.ZodArray<z.ZodObject<{
|
|
34
35
|
id: z.ZodString;
|
|
35
36
|
label: z.ZodString;
|
|
@@ -41,7 +42,7 @@ export declare const SettingsListSchema: z.ZodObject<{
|
|
|
41
42
|
label: z.ZodString;
|
|
42
43
|
category: z.ZodString;
|
|
43
44
|
section: z.ZodOptional<z.ZodString>;
|
|
44
|
-
field: z.ZodType<
|
|
45
|
+
field: z.ZodType<Field, unknown, z.core.$ZodTypeInternals<Field, unknown>>;
|
|
45
46
|
value: z.ZodUnknown;
|
|
46
47
|
set: z.ZodBoolean;
|
|
47
48
|
yours: z.ZodUnknown;
|
|
@@ -65,6 +66,7 @@ export declare const listSettings: import("../../kernel/define.js").QueryDef<z.Z
|
|
|
65
66
|
file: z.ZodString;
|
|
66
67
|
exists: z.ZodBoolean;
|
|
67
68
|
dataFolder: z.ZodOptional<z.ZodString>;
|
|
69
|
+
exportFile: z.ZodOptional<z.ZodString>;
|
|
68
70
|
categories: z.ZodArray<z.ZodObject<{
|
|
69
71
|
id: z.ZodString;
|
|
70
72
|
label: z.ZodString;
|
|
@@ -76,7 +78,7 @@ export declare const listSettings: import("../../kernel/define.js").QueryDef<z.Z
|
|
|
76
78
|
label: z.ZodString;
|
|
77
79
|
category: z.ZodString;
|
|
78
80
|
section: z.ZodOptional<z.ZodString>;
|
|
79
|
-
field: z.ZodType<
|
|
81
|
+
field: z.ZodType<Field, unknown, z.core.$ZodTypeInternals<Field, unknown>>;
|
|
80
82
|
value: z.ZodUnknown;
|
|
81
83
|
set: z.ZodBoolean;
|
|
82
84
|
yours: z.ZodUnknown;
|
|
@@ -115,6 +117,20 @@ export declare const resetSetting: import("../../kernel/define.js").OperationDef
|
|
|
115
117
|
changed: z.ZodBoolean;
|
|
116
118
|
message: z.ZodString;
|
|
117
119
|
}, z.core.$strip>, "settings.reset">;
|
|
120
|
+
export declare const exportConfig: import("../../kernel/define.js").OperationDef<z.ZodObject<{
|
|
121
|
+
settingsFile: z.ZodOptional<z.ZodString>;
|
|
122
|
+
withPaths: z.ZodDefault<z.ZodBoolean>;
|
|
123
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
124
|
+
file: z.ZodString;
|
|
125
|
+
leftOut: z.ZodArray<z.ZodString>;
|
|
126
|
+
pathsLeftOut: z.ZodBoolean;
|
|
127
|
+
}, z.core.$strip>, "settings.export">;
|
|
128
|
+
export declare const importConfig: import("../../kernel/define.js").OperationDef<z.ZodObject<{
|
|
129
|
+
settingsFile: z.ZodOptional<z.ZodString>;
|
|
130
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
131
|
+
changed: z.ZodNumber;
|
|
132
|
+
message: z.ZodString;
|
|
133
|
+
}, z.core.$strip>, "settings.import">;
|
|
118
134
|
/** The settings page of one scope: a section per category, each setting with its value and an edit action. */
|
|
119
135
|
export declare function settingsPage(o: SettingsList): Page;
|
|
120
136
|
export declare const settingsView: import("../../kernel/define.js").ViewDef<{
|
|
@@ -131,6 +147,7 @@ export declare const settingsView: import("../../kernel/define.js").ViewDef<{
|
|
|
131
147
|
file: z.ZodString;
|
|
132
148
|
exists: z.ZodBoolean;
|
|
133
149
|
dataFolder: z.ZodOptional<z.ZodString>;
|
|
150
|
+
exportFile: z.ZodOptional<z.ZodString>;
|
|
134
151
|
categories: z.ZodArray<z.ZodObject<{
|
|
135
152
|
id: z.ZodString;
|
|
136
153
|
label: z.ZodString;
|
|
@@ -142,7 +159,7 @@ export declare const settingsView: import("../../kernel/define.js").ViewDef<{
|
|
|
142
159
|
label: z.ZodString;
|
|
143
160
|
category: z.ZodString;
|
|
144
161
|
section: z.ZodOptional<z.ZodString>;
|
|
145
|
-
field: z.ZodType<
|
|
162
|
+
field: z.ZodType<Field, unknown, z.core.$ZodTypeInternals<Field, unknown>>;
|
|
146
163
|
value: z.ZodUnknown;
|
|
147
164
|
set: z.ZodBoolean;
|
|
148
165
|
yours: z.ZodUnknown;
|