windows-development-sandbox 1.7.0 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/config.example.json +10 -0
- package/dist/app/context.d.ts +8 -0
- package/dist/app/context.js +12 -0
- package/dist/app/features/defs.d.ts +322 -0
- package/dist/app/features/defs.js +28 -0
- package/dist/app/features/sandbox/index.d.ts +2 -0
- package/dist/app/features/sandbox/index.js +3 -0
- package/dist/app/features/sandbox/sandbox.def.d.ts +193 -0
- package/dist/app/features/sandbox/sandbox.def.js +245 -0
- package/dist/app/features/sandbox/sandbox.run.d.ts +72 -0
- package/dist/app/features/sandbox/sandbox.run.js +98 -0
- package/dist/app/features/sessions/index.d.ts +2 -0
- package/dist/app/features/sessions/index.js +3 -0
- package/dist/app/features/sessions/sessions.def.d.ts +141 -0
- package/dist/app/features/sessions/sessions.def.js +176 -0
- package/dist/app/features/sessions/sessions.run.d.ts +39 -0
- package/dist/app/features/sessions/sessions.run.js +58 -0
- package/dist/{cli/menu/settings/categories.d.ts → app/features/settings/categories.def.d.ts} +2 -0
- package/dist/{cli/menu/settings/categories.js → app/features/settings/categories.def.js} +24 -5
- package/dist/app/features/settings/index.d.ts +5 -0
- package/dist/app/features/settings/index.js +6 -0
- package/dist/{cli/menu/settings/config-file.d.ts → app/features/settings/settings-file.d.ts} +1 -1
- package/dist/{cli/menu/settings/config-file.js → app/features/settings/settings-file.js} +1 -1
- package/dist/app/features/settings/settings-rows.d.ts +35 -0
- package/dist/app/features/settings/settings-rows.js +94 -0
- package/dist/app/features/settings/settings.def.d.ts +157 -0
- package/dist/app/features/settings/settings.def.js +179 -0
- package/dist/app/features/settings/settings.run.d.ts +67 -0
- package/dist/app/features/settings/settings.run.js +84 -0
- package/dist/app/kernel/define.d.ts +143 -0
- package/dist/app/kernel/define.js +42 -0
- package/dist/app/kernel/errors.d.ts +34 -0
- package/dist/app/kernel/errors.js +45 -0
- package/dist/app/kernel/fields.d.ts +70 -0
- package/dist/app/kernel/fields.js +243 -0
- package/dist/app/kernel/index.d.ts +8 -0
- package/dist/app/kernel/index.js +10 -0
- package/dist/app/kernel/io.d.ts +193 -0
- package/dist/app/kernel/io.js +126 -0
- package/dist/app/kernel/rpc.d.ts +156 -0
- package/dist/app/kernel/rpc.js +47 -0
- package/dist/app/kernel/text.d.ts +6 -0
- package/dist/app/kernel/text.js +57 -0
- package/dist/app/kernel/view.d.ts +146 -0
- package/dist/app/kernel/view.js +28 -0
- package/dist/app/registry.d.ts +10 -0
- package/dist/app/registry.js +50 -0
- package/dist/cli/args.d.ts +5 -0
- package/dist/cli/args.js +6 -0
- package/dist/cli/commands/engine.d.ts +2 -0
- package/dist/cli/commands/engine.js +60 -0
- package/dist/cli/commands/index.d.ts +1 -1
- package/dist/cli/commands/index.js +1 -1
- package/dist/cli/commands/launch/launch.js +47 -7
- package/dist/cli/commands/launch/prepare.js +3 -3
- package/dist/cli/commands/launch/running.js +2 -1
- package/dist/cli/commands/launch/summary.d.ts +2 -0
- package/dist/cli/commands/maintenance/config-share.d.ts +12 -0
- package/dist/cli/commands/maintenance/config-share.js +80 -0
- package/dist/cli/commands/maintenance/config.js +8 -82
- package/dist/cli/commands/maintenance/logs.js +14 -0
- package/dist/cli/commands/registry.js +3 -7
- package/dist/cli/commands/repair/checks/contained.d.ts +2 -0
- package/dist/cli/commands/repair/checks/contained.js +139 -0
- package/dist/cli/commands/repair/checks/hcs.d.ts +7 -0
- package/dist/cli/commands/repair/checks/hcs.js +28 -0
- package/dist/cli/commands/repair/checks/index.js +4 -0
- package/dist/cli/commands/repair/checks/pc.js +32 -1
- package/dist/cli/commands/repair/checks/sandbox.js +16 -1
- package/dist/cli/commands/repair/checks/vpn.js +34 -9
- package/dist/cli/commands/repair/env.js +2 -1
- package/dist/cli/commands/sessions/index.d.ts +0 -4
- package/dist/cli/commands/sessions/index.js +3 -7
- package/dist/cli/commands/shared-use.d.ts +5 -2
- package/dist/cli/commands/shared-use.js +11 -8
- package/dist/cli/commands/storage/contained.d.ts +3 -0
- package/dist/cli/commands/storage/contained.js +179 -0
- package/dist/cli/commands/storage/offer.js +7 -1
- package/dist/cli/commands/storage/storage.js +10 -2
- package/dist/cli/commands/user-config.js +1 -1
- package/dist/cli/commands/vpn.js +19 -3
- package/dist/cli/commands/web.js +2 -0
- package/dist/cli/index.js +2 -1
- package/dist/cli/manifest.d.ts +72 -104
- package/dist/cli/manifest.js +64 -39
- package/dist/cli/menu/add-agent.d.ts +1 -1
- package/dist/cli/menu/add-agent.js +1 -1
- package/dist/cli/menu/apps.d.ts +7 -1
- package/dist/cli/menu/apps.js +36 -0
- package/dist/cli/menu/command-fields.d.ts +1 -1
- package/dist/cli/menu/command-form.js +2 -2
- package/dist/cli/menu/io-menu.d.ts +29 -0
- package/dist/cli/menu/io-menu.js +126 -0
- package/dist/cli/menu/live.d.ts +27 -0
- package/dist/cli/menu/live.js +69 -0
- package/dist/cli/menu/memory.d.ts +19 -0
- package/dist/cli/menu/memory.js +53 -0
- package/dist/cli/menu/menu.d.ts +10 -1
- package/dist/cli/menu/menu.js +27 -9
- package/dist/cli/menu/pages/agents-page.d.ts +3 -1
- package/dist/cli/menu/pages/agents-page.js +12 -5
- package/dist/cli/menu/pages/apps-page.d.ts +3 -1
- package/dist/cli/menu/pages/apps-page.js +19 -2
- package/dist/cli/menu/pages/list-page.d.ts +27 -0
- package/dist/cli/menu/pages/list-page.js +109 -7
- package/dist/cli/menu/pages/maintenance-page.d.ts +0 -5
- package/dist/cli/menu/pages/maintenance-page.js +17 -19
- package/dist/cli/menu/pages/sandbox-page.d.ts +4 -6
- package/dist/cli/menu/pages/sandbox-page.js +26 -118
- package/dist/cli/menu/pages/scopes.d.ts +1 -1
- package/dist/cli/menu/pages/sessions-page.d.ts +5 -11
- package/dist/cli/menu/pages/sessions-page.js +19 -88
- package/dist/cli/menu/pages/settings-page.d.ts +2 -10
- package/dist/cli/menu/pages/settings-page.js +64 -94
- package/dist/cli/menu/render-view.d.ts +28 -0
- package/dist/cli/menu/render-view.js +112 -0
- package/dist/cli/menu/settings/{path-kind.d.ts → ask-path.d.ts} +1 -7
- package/dist/cli/menu/settings/ask-path.js +14 -0
- package/dist/cli/menu/settings/collections/collection-editor.d.ts +1 -1
- package/dist/cli/menu/settings/collections/string-list-editor.d.ts +1 -2
- package/dist/cli/menu/settings/collections/string-list-editor.js +1 -1
- package/dist/cli/menu/settings/draft.d.ts +1 -1
- package/dist/cli/menu/settings/format.d.ts +1 -3
- package/dist/cli/menu/settings/format.js +6 -36
- package/dist/cli/menu/settings/index.d.ts +1 -3
- package/dist/cli/menu/settings/index.js +3 -3
- package/dist/cli/menu/settings/object-editor.d.ts +1 -1
- package/dist/cli/menu/settings/share.d.ts +36 -0
- package/dist/cli/menu/settings/share.js +131 -0
- package/dist/cli/menu/settings/value-editor.d.ts +5 -1
- package/dist/cli/menu/settings/value-editor.js +57 -54
- package/dist/cli/menu/several.js +1 -1
- package/dist/cli/menu/share-settings.d.ts +21 -0
- package/dist/cli/menu/share-settings.js +112 -0
- package/dist/cli/menu/shell.d.ts +21 -5
- package/dist/cli/menu/shell.js +31 -6
- package/dist/cli/menu/views.d.ts +7 -0
- package/dist/cli/menu/views.js +11 -0
- package/dist/cli/menu/vpn-login.js +8 -0
- package/dist/cli/operations/handler.d.ts +6 -0
- package/dist/cli/operations/handler.js +61 -0
- package/dist/cli/operations/index.d.ts +4 -0
- package/dist/cli/operations/index.js +5 -0
- package/dist/cli/operations/input.d.ts +6 -0
- package/dist/cli/operations/input.js +37 -0
- package/dist/cli/operations/io-cli.d.ts +7 -0
- package/dist/cli/operations/io-cli.js +62 -0
- package/dist/cli/operations/spec.d.ts +18 -0
- package/dist/cli/operations/spec.js +108 -0
- package/dist/cli/output/colors.d.ts +2 -2
- package/dist/cli/output/colors.js +2 -11
- package/dist/cli/output/index.d.ts +1 -0
- package/dist/cli/output/index.js +1 -0
- package/dist/cli/output/print.d.ts +3 -1
- package/dist/cli/output/print.js +7 -3
- package/dist/cli/output/progress.d.ts +15 -0
- package/dist/cli/output/progress.js +44 -0
- package/dist/cli/output/render-view.d.ts +4 -0
- package/dist/cli/output/render-view.js +63 -0
- package/dist/cli/services/agent-commands-service.d.ts +2 -0
- package/dist/cli/services/agent-commands-service.js +11 -2
- package/dist/cli/services/logs-service.js +4 -3
- package/dist/cli/tui/app.d.ts +6 -1
- package/dist/cli/tui/app.js +26 -4
- package/dist/cli/tui/list/list-screen.d.ts +14 -0
- package/dist/cli/tui/list/list-screen.js +64 -36
- package/dist/cli/tui/list/list-types.d.ts +2 -0
- package/dist/cli/tui/terminal.d.ts +7 -0
- package/dist/cli/tui/terminal.js +30 -10
- package/dist/core/config/defaults.js +8 -0
- package/dist/core/schema/config.d.ts +13 -0
- package/dist/core/schema/config.js +16 -1
- package/dist/core/schema/harness.d.ts +1 -0
- package/dist/core/schema/harness.js +5 -0
- package/dist/core/schema/sandbox.d.ts +6 -0
- package/dist/core/schema/sandbox.js +20 -3
- package/dist/core/schema/vpn.d.ts +2 -1
- package/dist/core/schema/vpn.js +3 -3
- package/dist/core/types.d.ts +23 -5
- package/dist/core/util/fs.d.ts +2 -0
- package/dist/core/util/fs.js +9 -0
- package/dist/core/util/index.d.ts +1 -1
- package/dist/core/util/index.js +1 -1
- package/dist/guest/agents/agent-files.d.ts +5 -0
- package/dist/guest/agents/agent-files.js +4 -0
- package/dist/guest/agents/local-state.d.ts +2 -0
- package/dist/guest/agents/local-state.js +21 -1
- package/dist/guest/boot/boot.js +2 -1
- package/dist/guest/daemon/daemon.js +4 -0
- package/dist/guest/daemon/sessions.d.ts +5 -0
- package/dist/guest/daemon/sessions.js +17 -3
- package/dist/guest/entries/daemon.js +3 -0
- package/dist/guest/governor/decide.d.ts +61 -0
- package/dist/guest/governor/decide.js +182 -0
- package/dist/guest/governor/governor.d.ts +42 -0
- package/dist/guest/governor/governor.js +214 -0
- package/dist/guest/governor/index.d.ts +2 -0
- package/dist/guest/governor/index.js +2 -0
- package/dist/guest/runtime/csc.d.ts +1 -0
- package/dist/guest/runtime/csc.js +1 -0
- package/dist/guest/sessions/viewer.js +3 -1
- package/dist/guest/toolchains/native/rust-extras.js +4 -2
- package/dist/guest/vpn/vpn.js +69 -21
- package/dist/guest/vpn/wireguard.d.ts +32 -0
- package/dist/guest/vpn/wireguard.js +132 -0
- package/dist/host/agent-commands/commands.d.ts +4 -0
- package/dist/host/agent-commands/commands.js +31 -7
- package/dist/host/audit/log.d.ts +1 -1
- package/dist/host/channel/attach.d.ts +3 -1
- package/dist/host/channel/attach.js +5 -2
- package/dist/host/channel/channel.d.ts +2 -0
- package/dist/host/channel/channel.js +4 -0
- package/dist/host/engines/engine.d.ts +12 -0
- package/dist/host/engines/engine.js +1 -0
- package/dist/host/engines/hcs/check.d.ts +25 -0
- package/dist/host/engines/hcs/check.js +95 -0
- package/dist/host/engines/hcs/documents.d.ts +44 -0
- package/dist/host/engines/hcs/documents.js +155 -0
- package/dist/host/engines/hcs/engine.d.ts +39 -0
- package/dist/host/engines/hcs/engine.js +171 -0
- package/dist/host/engines/hcs/helper.d.ts +43 -0
- package/dist/host/engines/hcs/helper.js +173 -0
- package/dist/host/engines/hcs/images.d.ts +37 -0
- package/dist/host/engines/hcs/images.js +152 -0
- package/dist/host/engines/index.d.ts +7 -0
- package/dist/host/engines/index.js +5 -0
- package/dist/host/engines/registry.d.ts +16 -0
- package/dist/host/engines/registry.js +30 -0
- package/dist/host/engines/types.d.ts +58 -0
- package/dist/host/engines/types.js +1 -0
- package/dist/host/engines/windows-sandbox/engine.d.ts +16 -0
- package/dist/host/engines/windows-sandbox/engine.js +63 -0
- package/dist/host/engines/windows-sandbox/wsb-text.d.ts +2 -0
- package/dist/host/engines/windows-sandbox/wsb-text.js +29 -0
- package/dist/host/launch/generate.d.ts +5 -1
- package/dist/host/launch/generate.js +50 -8
- package/dist/host/launch/index.d.ts +3 -1
- package/dist/host/launch/index.js +3 -1
- package/dist/host/launch/launch-plan.d.ts +13 -0
- package/dist/host/launch/launch-plan.js +26 -0
- package/dist/host/launch/mappings.js +2 -1
- package/dist/host/launch/risk-notes.d.ts +10 -0
- package/dist/host/launch/risk-notes.js +18 -0
- package/dist/host/launch/session-file.d.ts +2 -0
- package/dist/host/launch/session-file.js +7 -1
- package/dist/host/launch/wsb-file.d.ts +28 -4
- package/dist/host/launch/wsb-file.js +61 -42
- package/dist/host/life/crash-report.d.ts +27 -1
- package/dist/host/life/crash-report.js +173 -7
- package/dist/host/life/host-memory.d.ts +40 -0
- package/dist/host/life/host-memory.js +137 -0
- package/dist/host/life/index.d.ts +2 -0
- package/dist/host/life/index.js +2 -0
- package/dist/host/life/stop-events.d.ts +2 -0
- package/dist/host/life/stop-events.js +20 -3
- package/dist/host/life/stop-warning.js +1 -1
- package/dist/host/life/watchdog.d.ts +54 -0
- package/dist/host/life/watchdog.js +108 -0
- package/dist/host/native.d.ts +3 -2
- package/dist/host/native.js +22 -3
- package/dist/host/profile/claude-login.js +3 -2
- package/dist/host/sandbox/contained-deps.d.ts +2 -0
- package/dist/host/sandbox/contained-deps.js +17 -0
- package/dist/host/sandbox/index.d.ts +2 -0
- package/dist/host/sandbox/index.js +2 -0
- package/dist/host/sandbox/platform.d.ts +2 -0
- package/dist/host/sandbox/platform.js +7 -7
- package/dist/host/sandbox/tasklist.d.ts +13 -0
- package/dist/host/sandbox/tasklist.js +47 -0
- package/dist/host/secrets/launch-secrets.js +2 -1
- package/dist/host/sharing/current.js +2 -6
- package/dist/host/storage/contained/check.d.ts +9 -0
- package/dist/host/storage/contained/check.js +37 -0
- package/dist/host/storage/contained/contained-storage.d.ts +66 -0
- package/dist/host/storage/contained/contained-storage.js +168 -0
- package/dist/host/storage/contained/disk-port.d.ts +43 -0
- package/dist/host/storage/contained/disk-port.js +122 -0
- package/dist/host/storage/contained/index.d.ts +9 -0
- package/dist/host/storage/contained/index.js +8 -0
- package/dist/host/storage/contained/layout.d.ts +28 -0
- package/dist/host/storage/contained/layout.js +45 -0
- package/dist/host/storage/contained/resolve.d.ts +4 -0
- package/dist/host/storage/contained/resolve.js +30 -0
- package/dist/host/storage/contained/setting.d.ts +1 -0
- package/dist/host/storage/contained/setting.js +5 -0
- package/dist/host/storage/contained/state.d.ts +89 -0
- package/dist/host/storage/contained/state.js +166 -0
- package/dist/host/storage/contained/transfer.d.ts +24 -0
- package/dist/host/storage/contained/transfer.js +121 -0
- package/dist/host/storage/index.d.ts +2 -0
- package/dist/host/storage/index.js +2 -0
- package/dist/host/storage/providers/contained.d.ts +15 -0
- package/dist/host/storage/providers/contained.js +39 -0
- package/dist/host/storage/providers/folder.d.ts +12 -0
- package/dist/host/storage/providers/folder.js +20 -0
- package/dist/host/storage/providers/index.d.ts +4 -0
- package/dist/host/storage/providers/index.js +3 -0
- package/dist/host/storage/providers/registry.d.ts +9 -0
- package/dist/host/storage/providers/registry.js +14 -0
- package/dist/host/storage/providers/types.d.ts +33 -0
- package/dist/host/storage/providers/types.js +1 -0
- package/dist/host/tools/conpty.js +3 -2
- package/dist/host/tools/windows-terminal.js +8 -7
- package/dist/host/vpn/index.d.ts +1 -1
- package/dist/host/vpn/index.js +1 -1
- package/dist/host/vpn/prepare.d.ts +2 -0
- package/dist/host/vpn/prepare.js +63 -2
- package/dist/host/web/browser.d.ts +2 -0
- package/dist/host/web/browser.js +14 -1
- package/dist/host/web/index.d.ts +3 -2
- package/dist/host/web/index.js +3 -2
- package/dist/host/web/rpc.d.ts +24 -0
- package/dist/host/web/rpc.js +149 -0
- package/dist/host/web/runner.d.ts +2 -0
- package/dist/host/web/runner.js +1 -2
- package/dist/host/web/server.d.ts +7 -0
- package/dist/host/web/server.js +23 -3
- package/dist/runtime/agent.js +69 -8
- package/dist/runtime/daemon.js +1058 -624
- package/dist/runtime/db.js +69 -8
- package/dist/runtime/main.js +624 -182
- package/dist/runtime/netproxy.js +69 -8
- package/dist/runtime/view.js +87 -13
- package/dist/selftest/agent-paths.test.js +11 -1
- package/dist/selftest/app.test.d.ts +2 -0
- package/dist/selftest/app.test.js +324 -0
- package/dist/selftest/channel.test.js +13 -0
- package/dist/selftest/cli.test.js +2 -1
- package/dist/selftest/config.test.js +59 -0
- package/dist/selftest/contained.test.d.ts +2 -0
- package/dist/selftest/contained.test.js +544 -0
- package/dist/selftest/credentials.test.js +1 -1
- package/dist/selftest/engine.test.d.ts +2 -0
- package/dist/selftest/engine.test.js +127 -0
- package/dist/selftest/hcs.test.d.ts +2 -0
- package/dist/selftest/hcs.test.js +482 -0
- package/dist/selftest/heavy-load.test.d.ts +2 -0
- package/dist/selftest/heavy-load.test.js +329 -0
- package/dist/selftest/index.js +12 -0
- package/dist/selftest/layout.test.js +12 -0
- package/dist/selftest/menu-perf.test.d.ts +2 -0
- package/dist/selftest/menu-perf.test.js +248 -0
- package/dist/selftest/menu-screens.js +4 -2
- package/dist/selftest/menu.test.js +36 -8
- package/dist/selftest/support/engine-cases.d.ts +8 -0
- package/dist/selftest/support/engine-cases.js +65 -0
- package/dist/selftest/support/engine-golden.d.ts +3 -0
- package/dist/selftest/support/engine-golden.js +66 -0
- package/dist/selftest/support/fixtures.d.ts +7 -1
- package/dist/selftest/support/hcs-probes.d.ts +17 -0
- package/dist/selftest/support/hcs-probes.js +41 -0
- package/dist/selftest/vpn.test.js +136 -3
- package/dist/selftest/web.test.js +101 -3
- package/dist/shared/channel/run-dir.d.ts +4 -1
- package/dist/shared/channel/run-dir.js +7 -1
- package/dist/shared/channel/schema.d.ts +35 -1
- package/dist/shared/channel/schema.js +27 -0
- package/dist/shared/channel/secrets.d.ts +1 -0
- package/dist/shared/channel/secrets.js +6 -0
- package/dist/shared/memory/index.d.ts +1 -0
- package/dist/shared/memory/index.js +1 -0
- package/dist/shared/memory/policy.d.ts +33 -0
- package/dist/shared/memory/policy.js +55 -0
- package/dist/shared/pty/output-filter.d.ts +14 -1
- package/dist/shared/pty/output-filter.js +22 -4
- package/dist/shared/pty/terminal.d.ts +4 -1
- package/dist/shared/pty/terminal.js +4 -2
- package/dist/shared/system.d.ts +1 -0
- package/dist/shared/system.js +1 -0
- package/dist/shared/vpn/download.d.ts +16 -0
- package/dist/shared/vpn/download.js +16 -0
- package/dist/shared/vpn/wireguard.d.ts +51 -0
- package/dist/shared/vpn/wireguard.js +227 -0
- package/dist/sync/sync-cycle.js +5 -5
- package/dist/sync/watcher.d.ts +13 -0
- package/dist/sync/watcher.js +92 -3
- package/dist/web/index.html +4 -3
- package/dist/web/main-NRRS5O6Z.js +157 -0
- package/dist/web/main-T5DMCHYV.css +1 -0
- package/native/csharp/HcsHost/AssemblyInfo.cs +14 -0
- package/native/csharp/HcsHost/Guard.cs +100 -0
- package/native/csharp/HcsHost/Hcs.cs +256 -0
- package/native/csharp/HcsHost/Json.cs +78 -0
- package/native/csharp/HcsHost/Program.cs +185 -0
- package/native/csharp/HcsHost/VirtualDisk.cs +95 -0
- package/native/csharp/HostTools/AssemblyInfo.cs +14 -0
- package/native/csharp/HostTools/MemoryStatus.cs +107 -0
- package/native/csharp/HostTools/Program.cs +58 -17
- package/native/scripts/check-contained.ps1 +28 -0
- package/native/scripts/contained-common.ps1 +241 -0
- package/native/scripts/dismount-contained.ps1 +66 -0
- package/native/scripts/memory-status.ps1 +34 -0
- package/native/scripts/mount-contained.ps1 +139 -0
- package/native/scripts/run-elevated.ps1 +17 -4
- package/native/scripts/stop-events.ps1 +23 -8
- package/package.json +9 -2
- package/sandbox/csharp/MemGov.cs +398 -0
- package/sandbox/csharp/PtyHost.cs +111 -5
- package/schemas/config.schema.json +60 -6
- package/schemas/sandbox-config.schema.json +3 -3
- package/dist/cli/commands/sessions/control.d.ts +0 -4
- package/dist/cli/commands/sessions/control.js +0 -66
- package/dist/cli/commands/sessions/list.d.ts +0 -2
- package/dist/cli/commands/sessions/list.js +0 -48
- package/dist/cli/commands/sessions/status.d.ts +0 -4
- package/dist/cli/commands/sessions/status.js +0 -114
- package/dist/cli/commands/sessions/window.d.ts +0 -3
- package/dist/cli/commands/sessions/window.js +0 -18
- package/dist/cli/menu/settings/path-kind.js +0 -44
- package/dist/web/main-CXESL347.js +0 -45
- package/dist/web/main-VLR7DVQ4.css +0 -1
- /package/dist/{cli/menu/settings → app/kernel}/schema-node.d.ts +0 -0
- /package/dist/{cli/menu/settings → app/kernel}/schema-node.js +0 -0
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
// The common shape of a tab that is a list: it loads its data, builds a list screen from it, and acts on what the list
|
|
2
|
-
// returns. After every action the list is built again from fresh data, on the same entry.
|
|
2
|
+
// returns. After every action the list is built again from fresh data, on the same entry. Opening a tab never makes
|
|
3
|
+
// the keys wait for a slow load: after a moment the tab shows "Loading…" (or the data it had), and the list is built
|
|
4
|
+
// when the data is there.
|
|
3
5
|
import { ListScreen, } from '../../tui/index.js';
|
|
6
|
+
import { errMsg } from '../../../core/util/index.js';
|
|
7
|
+
import { Theme } from '../../tui/index.js';
|
|
8
|
+
/** A tab whose data is not here after this long shows "Loading…" instead of holding up the keys. */
|
|
9
|
+
const QUICK_LOAD_MS = 120;
|
|
10
|
+
/** What a tab shows before its data has arrived. */
|
|
11
|
+
function loadingOptions() {
|
|
12
|
+
return { path: [], items: [], empty: 'Loading…' };
|
|
13
|
+
}
|
|
4
14
|
export class ListPage {
|
|
5
15
|
app;
|
|
6
16
|
stages = false;
|
|
@@ -10,6 +20,14 @@ export class ListPage {
|
|
|
10
20
|
focused = true;
|
|
11
21
|
/** The entry that was last acted on: the cursor returns to it when the section opens again. */
|
|
12
22
|
lastFocus;
|
|
23
|
+
/** A search to start the next list with (restored from the last run); used once. */
|
|
24
|
+
pendingQuery;
|
|
25
|
+
/** The data has arrived at least once (until then the list is "Loading…"). */
|
|
26
|
+
loaded = false;
|
|
27
|
+
/** Counts loads, so that a slow one that was overtaken does not replace newer data. */
|
|
28
|
+
generation = 0;
|
|
29
|
+
/** A category asked for before the data arrived: it opens when it does. */
|
|
30
|
+
wantedCategory;
|
|
13
31
|
constructor(app) {
|
|
14
32
|
this.app = app;
|
|
15
33
|
}
|
|
@@ -17,6 +35,10 @@ export class ListPage {
|
|
|
17
35
|
initialFocus() {
|
|
18
36
|
return undefined;
|
|
19
37
|
}
|
|
38
|
+
/** The data has not arrived yet (the tab shows "Loading…"). */
|
|
39
|
+
get loading() {
|
|
40
|
+
return !this.loaded;
|
|
41
|
+
}
|
|
20
42
|
get capturing() {
|
|
21
43
|
return this.list?.isSearching ?? false;
|
|
22
44
|
}
|
|
@@ -24,10 +46,24 @@ export class ListPage {
|
|
|
24
46
|
get category() {
|
|
25
47
|
return this.list?.currentCategory;
|
|
26
48
|
}
|
|
49
|
+
/** The search typed in the list ('' when none). */
|
|
50
|
+
get search() {
|
|
51
|
+
return this.list?.searchText ?? '';
|
|
52
|
+
}
|
|
53
|
+
/** Shows the list with this search typed (the menu opens on the search it was left on). */
|
|
54
|
+
restoreSearch(text) {
|
|
55
|
+
this.pendingQuery = text;
|
|
56
|
+
if (this.loaded)
|
|
57
|
+
this.rebuild(undefined);
|
|
58
|
+
}
|
|
27
59
|
categories() {
|
|
28
60
|
return this.screen().categories;
|
|
29
61
|
}
|
|
30
62
|
async selectCategory(id) {
|
|
63
|
+
if (!this.loaded) {
|
|
64
|
+
this.wantedCategory = id;
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
31
67
|
this.screen().setCategory(id);
|
|
32
68
|
await this.afterKey();
|
|
33
69
|
}
|
|
@@ -41,7 +77,15 @@ export class ListPage {
|
|
|
41
77
|
}
|
|
42
78
|
/** A list from the current data; its categories are shown by the menu's navigation. */
|
|
43
79
|
build(extra) {
|
|
44
|
-
const
|
|
80
|
+
const startQuery = this.pendingQuery;
|
|
81
|
+
this.pendingQuery = undefined;
|
|
82
|
+
const list = new ListScreen({
|
|
83
|
+
...(this.loaded ? this.options() : loadingOptions()),
|
|
84
|
+
startQuery,
|
|
85
|
+
...extra,
|
|
86
|
+
categoryNav: 'external',
|
|
87
|
+
escapeLabel: 'sections',
|
|
88
|
+
});
|
|
45
89
|
list.setActive(this.focused);
|
|
46
90
|
return list;
|
|
47
91
|
}
|
|
@@ -49,14 +93,68 @@ export class ListPage {
|
|
|
49
93
|
ticked() {
|
|
50
94
|
return this.list?.ticked() ?? [];
|
|
51
95
|
}
|
|
96
|
+
/** Loads the data again; a slow load does not hold up the keys (the tab keeps what it showed, then updates). */
|
|
52
97
|
async open() {
|
|
53
|
-
await this.
|
|
54
|
-
|
|
55
|
-
|
|
98
|
+
await this.reload(true);
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Loads the data and waits for it at most QUICK_LOAD_MS. In time, the list is built here (`build`) or by the caller;
|
|
102
|
+
* later, the list is built when the data arrives, on the entry and search the user has moved to meanwhile.
|
|
103
|
+
*/
|
|
104
|
+
async reload(build) {
|
|
105
|
+
const mine = ++this.generation;
|
|
106
|
+
let late = false;
|
|
107
|
+
let timer;
|
|
108
|
+
const quick = new Promise((resolve) => {
|
|
109
|
+
timer = setTimeout(() => {
|
|
110
|
+
late = true;
|
|
111
|
+
resolve();
|
|
112
|
+
}, QUICK_LOAD_MS);
|
|
113
|
+
});
|
|
114
|
+
const arrived = this.loadData().then(() => {
|
|
115
|
+
if (mine !== this.generation)
|
|
116
|
+
return;
|
|
117
|
+
this.loaded = true;
|
|
118
|
+
if (late)
|
|
119
|
+
this.rebuildLate();
|
|
120
|
+
else if (build)
|
|
121
|
+
this.rebuildOpened();
|
|
122
|
+
});
|
|
123
|
+
await Promise.race([arrived, quick]);
|
|
124
|
+
clearTimeout(timer);
|
|
125
|
+
}
|
|
126
|
+
async loadData() {
|
|
127
|
+
try {
|
|
128
|
+
await this.load();
|
|
129
|
+
}
|
|
130
|
+
catch (e) {
|
|
131
|
+
this.say(Theme.error(Theme.glyph.cross + ' ' + errMsg(e)));
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
/** Back on the entry used last, when it is still in the category that is open. */
|
|
135
|
+
rebuildOpened() {
|
|
136
|
+
this.rebuildOn(this.lastFocus ?? this.initialFocus());
|
|
137
|
+
this.openWantedCategory();
|
|
138
|
+
}
|
|
139
|
+
/** Data that came after the keys stopped waiting: the cursor and the search stay where the user moved them. */
|
|
140
|
+
rebuildLate() {
|
|
141
|
+
if (this.list)
|
|
142
|
+
this.pendingQuery ??= this.list.searchText || undefined;
|
|
143
|
+
this.rebuildOn(this.list?.current);
|
|
144
|
+
this.openWantedCategory();
|
|
145
|
+
this.app.requestRedraw();
|
|
146
|
+
}
|
|
147
|
+
rebuildOn(wanted) {
|
|
56
148
|
const open = this.list?.currentCategory;
|
|
57
149
|
const item = wanted === undefined ? undefined : this.options().items.find((i) => i.value === wanted);
|
|
58
150
|
this.rebuild(item && (!open || !item.category || item.category === open) ? wanted : undefined);
|
|
59
151
|
}
|
|
152
|
+
openWantedCategory() {
|
|
153
|
+
if (!this.wantedCategory)
|
|
154
|
+
return;
|
|
155
|
+
this.list?.setCategory(this.wantedCategory);
|
|
156
|
+
this.wantedCategory = undefined;
|
|
157
|
+
}
|
|
60
158
|
/** Builds the list again, on `focus` when it is still there. */
|
|
61
159
|
rebuild(focus, notice) {
|
|
62
160
|
const startCategory = this.list?.currentCategory;
|
|
@@ -83,8 +181,12 @@ export class ListPage {
|
|
|
83
181
|
const outcome = result.kind === 'back' ? { exit: { kind: 'quit' } } : await this.act(result);
|
|
84
182
|
if (outcome.exit)
|
|
85
183
|
return { done: outcome.exit };
|
|
86
|
-
|
|
87
|
-
|
|
184
|
+
// What the action changed (a stop, a restart) is known to the menu before the page loads again. An action that
|
|
185
|
+
// loads nothing again changed nothing the menu shows, so the keys do not wait for it.
|
|
186
|
+
if (outcome.reload) {
|
|
187
|
+
await this.app.afterAction();
|
|
188
|
+
await this.reload(false);
|
|
189
|
+
}
|
|
88
190
|
const here = result.kind === 'pick' || result.kind === 'action' ? result.value : undefined;
|
|
89
191
|
this.lastFocus = outcome.focus ?? here ?? this.lastFocus;
|
|
90
192
|
this.rebuild(outcome.focus ?? here, outcome.notice);
|
|
@@ -4,8 +4,6 @@ import { type DataEntry } from '../../commands/data/collect.js';
|
|
|
4
4
|
import type { RepairResult } from '../../commands/repair/types.js';
|
|
5
5
|
import { type LogFile, type SetupReport, type UpdateStatus } from '../../services/index.js';
|
|
6
6
|
import { type App, type ListOptions, type ListResult } from '../../tui/index.js';
|
|
7
|
-
import type { Step } from '../../tui/index.js';
|
|
8
|
-
import type { ShellExit } from '../shell.js';
|
|
9
7
|
import { ListPage, type Outcome } from './list-page.js';
|
|
10
8
|
export interface MaintenanceModel {
|
|
11
9
|
/** The data folder row (where the sandbox keeps its data). */
|
|
@@ -54,7 +52,6 @@ export declare class MaintenancePage extends ListPage<string> {
|
|
|
54
52
|
private doctorRows;
|
|
55
53
|
private repairRows;
|
|
56
54
|
private setupReport;
|
|
57
|
-
private seen;
|
|
58
55
|
private settings;
|
|
59
56
|
private readonly migrate;
|
|
60
57
|
private readonly health;
|
|
@@ -65,8 +62,6 @@ export declare class MaintenancePage extends ListPage<string> {
|
|
|
65
62
|
private model;
|
|
66
63
|
protected load(): Promise<void>;
|
|
67
64
|
protected options(): ListOptions<string>;
|
|
68
|
-
/** Opening a category loads what it shows (the cheap ones; data is measured on request). */
|
|
69
|
-
protected afterKey(): Promise<Step<ShellExit>>;
|
|
70
65
|
private readSettings;
|
|
71
66
|
private updateStatus;
|
|
72
67
|
/** The Updates category: look, install, go back, switch automatic updates. */
|
|
@@ -148,6 +148,18 @@ export function maintenanceOptions(m) {
|
|
|
148
148
|
hint: humanBytes(f.bytes) + ' ' + ago(f.modified),
|
|
149
149
|
description: 'Enter shows the end of this log in the terminal.',
|
|
150
150
|
}));
|
|
151
|
+
// The checks take seconds (programs are run), so they are not made while you move through the categories.
|
|
152
|
+
const check = m.doctor === null && m.setup === null
|
|
153
|
+
? [
|
|
154
|
+
{
|
|
155
|
+
value: 'health:check',
|
|
156
|
+
label: 'Check this PC',
|
|
157
|
+
category: 'health',
|
|
158
|
+
section: 'Doctor',
|
|
159
|
+
description: 'Looks at this PC: Windows features, the install, the folders and the sandbox. It takes a few seconds, so it only runs when you ask.',
|
|
160
|
+
},
|
|
161
|
+
]
|
|
162
|
+
: [];
|
|
151
163
|
const doctor = (m.doctor ?? []).map(([name, detail], i) => ({
|
|
152
164
|
value: 'doctor:' + i,
|
|
153
165
|
label: name,
|
|
@@ -225,7 +237,7 @@ export function maintenanceOptions(m) {
|
|
|
225
237
|
return {
|
|
226
238
|
path: [],
|
|
227
239
|
categories: CATEGORIES,
|
|
228
|
-
items: [...updates, ...settings, ...dataItems(m), ...doctor, ...repair, ...setup, ...logs, ...more],
|
|
240
|
+
items: [...updates, ...settings, ...dataItems(m), ...check, ...doctor, ...repair, ...setup, ...logs, ...more],
|
|
229
241
|
empty: 'Nothing here yet.',
|
|
230
242
|
actions: maintenanceActions(m),
|
|
231
243
|
enterLabel: (_category, id) => enterLabel(id ?? '', m),
|
|
@@ -241,6 +253,8 @@ function enterLabel(id, m) {
|
|
|
241
253
|
return 'choose what';
|
|
242
254
|
if (id === 'repair:run')
|
|
243
255
|
return 'check and fix';
|
|
256
|
+
if (id === 'health:check')
|
|
257
|
+
return 'check';
|
|
244
258
|
if (id === 'updates:latest')
|
|
245
259
|
return m.latest ? 'install' : 'look';
|
|
246
260
|
if (id === 'updates:auto')
|
|
@@ -271,7 +285,7 @@ function maintenanceActions(m) {
|
|
|
271
285
|
const canEnable = m.setup !== null && !('error' in m.setup) && m.setup.canEnable;
|
|
272
286
|
return [
|
|
273
287
|
{ key: 'f', label: 'check and fix' },
|
|
274
|
-
{ key: 'l', label: 'check again' },
|
|
288
|
+
{ key: 'l', label: m.doctor ? 'check again' : 'check' },
|
|
275
289
|
...(canEnable ? [{ key: 'e', label: 'turn on Windows Sandbox' }] : []),
|
|
276
290
|
];
|
|
277
291
|
}
|
|
@@ -313,7 +327,6 @@ export class MaintenancePage extends ListPage {
|
|
|
313
327
|
doctorRows = null;
|
|
314
328
|
repairRows = null;
|
|
315
329
|
setupReport = null;
|
|
316
|
-
seen;
|
|
317
330
|
settings = { pending: [] };
|
|
318
331
|
migrate;
|
|
319
332
|
health;
|
|
@@ -362,21 +375,6 @@ export class MaintenancePage extends ListPage {
|
|
|
362
375
|
options() {
|
|
363
376
|
return maintenanceOptions(this.model());
|
|
364
377
|
}
|
|
365
|
-
/** Opening a category loads what it shows (the cheap ones; data is measured on request). */
|
|
366
|
-
async afterKey() {
|
|
367
|
-
const category = this.category;
|
|
368
|
-
if (category === this.seen)
|
|
369
|
-
return;
|
|
370
|
-
this.seen = category;
|
|
371
|
-
if (category !== 'health' || (this.doctorRows && this.setupReport))
|
|
372
|
-
return;
|
|
373
|
-
if (!this.doctorRows)
|
|
374
|
-
await this.loadDoctor();
|
|
375
|
-
if (!this.setupReport)
|
|
376
|
-
await this.loadSetup();
|
|
377
|
-
this.rebuild(undefined);
|
|
378
|
-
return;
|
|
379
|
-
}
|
|
380
378
|
readSettings() {
|
|
381
379
|
try {
|
|
382
380
|
this.settings = { pending: this.migrate.plan() };
|
|
@@ -493,7 +491,7 @@ export class MaintenancePage extends ListPage {
|
|
|
493
491
|
if (this.category === 'health') {
|
|
494
492
|
if (key === 'f' || id === 'repair:run')
|
|
495
493
|
return this.repair();
|
|
496
|
-
if (key === 'l') {
|
|
494
|
+
if (key === 'l' || id === 'health:check') {
|
|
497
495
|
await this.loadDoctor();
|
|
498
496
|
await this.loadSetup();
|
|
499
497
|
return {};
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
import { type SandboxStatus } from '../../../app/features/sandbox/index.js';
|
|
1
2
|
import type { Context } from '../../commands/context.js';
|
|
2
|
-
import { type DatabaseRow, type ProjectsListing
|
|
3
|
+
import { type DatabaseRow, type ProjectsListing } from '../../services/index.js';
|
|
3
4
|
import { type App, type ListOptions, type ListResult } from '../../tui/index.js';
|
|
4
5
|
import { ListPage, type Outcome } from './list-page.js';
|
|
5
6
|
export interface SandboxModel {
|
|
6
|
-
readonly report:
|
|
7
|
+
readonly report: SandboxStatus;
|
|
7
8
|
readonly projects: ProjectsListing;
|
|
8
9
|
/** Null: the sandbox is not running or did not answer. */
|
|
9
10
|
readonly databases: DatabaseRow[] | null;
|
|
@@ -16,8 +17,8 @@ export declare class SandboxPage extends ListPage<string> {
|
|
|
16
17
|
private readonly ctx;
|
|
17
18
|
readonly label = "Sandbox";
|
|
18
19
|
private model;
|
|
19
|
-
private readonly sandbox;
|
|
20
20
|
private readonly projects;
|
|
21
|
+
private readonly operations;
|
|
21
22
|
constructor(app: App, ctx: Context);
|
|
22
23
|
protected load(): Promise<void>;
|
|
23
24
|
/** The folder `sbx-db` runs in: the sandbox's own workspace. */
|
|
@@ -26,9 +27,6 @@ export declare class SandboxPage extends ListPage<string> {
|
|
|
26
27
|
protected act(result: ListResult<string>): Promise<Outcome<string>>;
|
|
27
28
|
private defaultAgent;
|
|
28
29
|
private noSandbox;
|
|
29
|
-
private show;
|
|
30
|
-
private hide;
|
|
31
|
-
private stop;
|
|
32
30
|
private addRoot;
|
|
33
31
|
private forget;
|
|
34
32
|
private toggleDatabase;
|
|
@@ -1,12 +1,15 @@
|
|
|
1
|
-
// Section 3: the sandbox as a whole. Status (
|
|
2
|
-
// Databases (start and stop), each a category on the left.
|
|
1
|
+
// Section 3: the sandbox as a whole. Status (the sandbox view: its facts, the window, stopping it), Projects (roots and
|
|
2
|
+
// known projects) and Databases (start and stop), each a category on the left.
|
|
3
3
|
import fs from 'node:fs';
|
|
4
4
|
import path from 'node:path';
|
|
5
|
+
import { sandboxPage, sandboxStatus } from '../../../app/features/sandbox/index.js';
|
|
6
|
+
import { readQuery } from '../../../app/registry.js';
|
|
5
7
|
import { errMsg, safeText } from '../../../core/util/index.js';
|
|
6
8
|
import { RunDir } from '../../../shared/channel/index.js';
|
|
7
|
-
import {
|
|
8
|
-
import { DatabasesService, ProjectsService, SandboxService, } from '../../services/index.js';
|
|
9
|
+
import { DatabasesService, ProjectsService } from '../../services/index.js';
|
|
9
10
|
import { Text, Theme, } from '../../tui/index.js';
|
|
11
|
+
import { MenuOperations } from '../io-menu.js';
|
|
12
|
+
import { menuView } from '../render-view.js';
|
|
10
13
|
import { ListPage } from './list-page.js';
|
|
11
14
|
const CATEGORIES = [
|
|
12
15
|
{ id: 'status', label: 'Status', description: 'What the sandbox is doing, its window, and stopping it.' },
|
|
@@ -17,51 +20,15 @@ const CATEGORIES = [
|
|
|
17
20
|
},
|
|
18
21
|
{ id: 'databases', label: 'Databases', description: 'Databases the sandbox can run: start and stop them.' },
|
|
19
22
|
];
|
|
20
|
-
|
|
23
|
+
/** The status category: the sandbox view's rows (prefixed, so they never clash with the projects' rows). */
|
|
24
|
+
function statusView(m) {
|
|
25
|
+
return menuView(sandboxPage(m.report), { category: 'status', prefix: 'status:', refresh: false });
|
|
26
|
+
}
|
|
21
27
|
/** The list for the sandbox tab. Pure. */
|
|
22
28
|
export function sandboxOptions(m) {
|
|
23
|
-
const
|
|
24
|
-
const
|
|
25
|
-
const
|
|
26
|
-
value: id,
|
|
27
|
-
label,
|
|
28
|
-
hint,
|
|
29
|
-
category: 'status',
|
|
30
|
-
section: 'Sandbox',
|
|
31
|
-
...extra,
|
|
32
|
-
});
|
|
33
|
-
const sessions = m.report.projects.reduce((n, p) => n + p.sessions.length, 0) + m.report.otherSessions.length;
|
|
34
|
-
const status = [
|
|
35
|
-
...(running ? [] : startRows(m.defaultAgent, 'status')),
|
|
36
|
-
row('info:state', 'State', running ? Theme.ok(Theme.glyph.on + ' ' + sandbox.phase) : Theme.muted(Theme.glyph.off + ' stopped'), { description: sandbox.message ? safeText(sandbox.message) : undefined }),
|
|
37
|
-
row('info:uptime', 'Up for', sandbox.startedAt && running ? ago(sandbox.startedAt).replace(' ago', '') : '-'),
|
|
38
|
-
row('info:daemon', 'Sandbox agent', running ? safeText(sandbox.daemon) : '-'),
|
|
39
|
-
row('info:window', 'Window', running ? (sandbox.headless ? 'hidden' : 'shown') : '-'),
|
|
40
|
-
row('info:sessions', 'Sessions', running ? String(sessions) : '-'),
|
|
41
|
-
row('info:account', 'Claude account', sandbox.account ?? '-'),
|
|
42
|
-
row('info:sync', 'History sync running', yesNo(sandbox.syncWatcher)),
|
|
43
|
-
row('info:guard', 'Repo guard', repoGuard.guarded +
|
|
44
|
-
' folder(s) guarded' +
|
|
45
|
-
(repoGuard.findings.length ? ', ' + repoGuard.findings.length + ' change(s) neutralised' : ''), {
|
|
46
|
-
details: repoGuard.findings.slice(-8).map((f) => Theme.warn(safeText(f))),
|
|
47
|
-
}),
|
|
48
|
-
...(running
|
|
49
|
-
? [
|
|
50
|
-
row('act:show', 'Show the window', '', {
|
|
51
|
-
section: 'Actions',
|
|
52
|
-
description: 'Brings the sandbox window to the front.',
|
|
53
|
-
}),
|
|
54
|
-
row('act:hide', 'Hide the window', '', {
|
|
55
|
-
section: 'Actions',
|
|
56
|
-
description: 'Hides the window. Show the window brings it back.',
|
|
57
|
-
}),
|
|
58
|
-
row('act:stop', 'Stop the sandbox…', '', {
|
|
59
|
-
section: 'Actions',
|
|
60
|
-
description: 'Shuts the sandbox down; your history syncs back when it closes.',
|
|
61
|
-
}),
|
|
62
|
-
]
|
|
63
|
-
: []),
|
|
64
|
-
];
|
|
29
|
+
const running = m.report.sandbox.running;
|
|
30
|
+
const status = statusView(m);
|
|
31
|
+
const statusItems = [...(running ? [] : startRows(m.defaultAgent, 'status')), ...status.items];
|
|
65
32
|
const addRoot = {
|
|
66
33
|
value: ADD_ROOT,
|
|
67
34
|
label: '+ Add a project root…',
|
|
@@ -113,11 +80,11 @@ export function sandboxOptions(m) {
|
|
|
113
80
|
}));
|
|
114
81
|
return {
|
|
115
82
|
path: [],
|
|
116
|
-
items: [...
|
|
83
|
+
items: [...statusItems, addRoot, ...roots, ...projects, ...databases, ...noDatabases],
|
|
117
84
|
categories: CATEGORIES,
|
|
118
85
|
empty: 'Nothing here yet.',
|
|
119
|
-
actions: (category) => sandboxActions(category,
|
|
120
|
-
enterLabel: (
|
|
86
|
+
actions: (category) => category === 'projects' || category === 'databases' ? sandboxActions(category) : [...status.actions, REFRESH],
|
|
87
|
+
enterLabel: (category, id) => status.enterLabel(category, id) || enterLabel(id ?? '', m),
|
|
121
88
|
};
|
|
122
89
|
}
|
|
123
90
|
const ADD_ROOT = '@add-root';
|
|
@@ -142,14 +109,8 @@ function startRows(agent, category) {
|
|
|
142
109
|
},
|
|
143
110
|
];
|
|
144
111
|
}
|
|
145
|
-
/** What Enter does on a row ("" = the row only shows information). */
|
|
112
|
+
/** What Enter does on a row of Projects and Databases ("" = the row only shows information). */
|
|
146
113
|
function enterLabel(id, m) {
|
|
147
|
-
if (id === 'act:show')
|
|
148
|
-
return 'show';
|
|
149
|
-
if (id === 'act:hide')
|
|
150
|
-
return 'hide';
|
|
151
|
-
if (id === 'act:stop')
|
|
152
|
-
return 'stop';
|
|
153
114
|
if (id.startsWith('act:start'))
|
|
154
115
|
return 'start';
|
|
155
116
|
if (id === ADD_ROOT)
|
|
@@ -158,7 +119,7 @@ function enterLabel(id, m) {
|
|
|
158
119
|
return m.databases?.find((d) => 'db:' + d.name === id)?.running ? 'stop' : 'start';
|
|
159
120
|
return '';
|
|
160
121
|
}
|
|
161
|
-
function sandboxActions(category
|
|
122
|
+
function sandboxActions(category) {
|
|
162
123
|
if (category === 'projects')
|
|
163
124
|
return [
|
|
164
125
|
{ key: 'a', label: 'add root', importance: 1 },
|
|
@@ -166,31 +127,22 @@ function sandboxActions(category, running) {
|
|
|
166
127
|
{ key: 'f', label: 'forget project', importance: 1, applies: (id) => id.startsWith('project:') },
|
|
167
128
|
REFRESH,
|
|
168
129
|
];
|
|
169
|
-
|
|
170
|
-
return [REFRESH];
|
|
171
|
-
return running
|
|
172
|
-
? [
|
|
173
|
-
{ key: 'w', label: 'show window', importance: 3 },
|
|
174
|
-
{ key: 'h', label: 'hide window', importance: 3 },
|
|
175
|
-
{ key: 'x', label: 'stop', importance: 1 },
|
|
176
|
-
REFRESH,
|
|
177
|
-
]
|
|
178
|
-
: [REFRESH];
|
|
130
|
+
return [REFRESH];
|
|
179
131
|
}
|
|
180
132
|
export class SandboxPage extends ListPage {
|
|
181
133
|
ctx;
|
|
182
134
|
label = 'Sandbox';
|
|
183
135
|
model;
|
|
184
|
-
sandbox;
|
|
185
136
|
projects;
|
|
137
|
+
operations;
|
|
186
138
|
constructor(app, ctx) {
|
|
187
139
|
super(app);
|
|
188
140
|
this.ctx = ctx;
|
|
189
|
-
this.sandbox = new SandboxService(ctx);
|
|
190
141
|
this.projects = new ProjectsService(ctx);
|
|
142
|
+
this.operations = new MenuOperations(app, ctx);
|
|
191
143
|
}
|
|
192
144
|
async load() {
|
|
193
|
-
const report = await this.
|
|
145
|
+
const report = await readQuery(sandboxStatus, this.ctx);
|
|
194
146
|
const guest = report.sandbox.running && report.sandbox.phase === 'ready' ? this.guestWorkspace() : null;
|
|
195
147
|
let databases = null;
|
|
196
148
|
if (guest) {
|
|
@@ -218,18 +170,15 @@ export class SandboxPage extends ListPage {
|
|
|
218
170
|
try {
|
|
219
171
|
if (key === 'l')
|
|
220
172
|
return { reload: true };
|
|
173
|
+
const chosen = this.model ? statusView(this.model).resolve(result) : undefined;
|
|
174
|
+
if (chosen?.kind === 'action')
|
|
175
|
+
return await this.operations.perform(chosen.action, [this.label], (text) => this.busy(text, id));
|
|
221
176
|
if (id === 'act:start' && !key)
|
|
222
177
|
return { exit: { kind: 'run', argv: ['launch', '--harness', this.defaultAgent()] } };
|
|
223
178
|
if (id === 'act:start-bare' && !key)
|
|
224
179
|
return { exit: { kind: 'run', argv: ['start'] } };
|
|
225
180
|
if (id === ADD_ROOT && !key)
|
|
226
181
|
return await this.addRoot();
|
|
227
|
-
if (id === 'act:show' || key === 'w')
|
|
228
|
-
return this.show();
|
|
229
|
-
if (id === 'act:hide' || key === 'h')
|
|
230
|
-
return await this.hide();
|
|
231
|
-
if (id === 'act:stop' || key === 'x')
|
|
232
|
-
return await this.stop();
|
|
233
182
|
if (key === 'a')
|
|
234
183
|
return await this.addRoot();
|
|
235
184
|
if (key === 'f')
|
|
@@ -248,47 +197,6 @@ export class SandboxPage extends ListPage {
|
|
|
248
197
|
noSandbox() {
|
|
249
198
|
return this.model?.report.sandbox.running ? null : { notice: Theme.warn('No sandbox is running.') };
|
|
250
199
|
}
|
|
251
|
-
show() {
|
|
252
|
-
const none = this.noSandbox();
|
|
253
|
-
if (none)
|
|
254
|
-
return none;
|
|
255
|
-
this.sandbox.showWindow();
|
|
256
|
-
return { notice: Theme.ok(Theme.glyph.ok + ' Window shown.') };
|
|
257
|
-
}
|
|
258
|
-
async hide() {
|
|
259
|
-
const none = this.noSandbox();
|
|
260
|
-
if (none)
|
|
261
|
-
return none;
|
|
262
|
-
await this.sandbox.hideWindow();
|
|
263
|
-
return {
|
|
264
|
-
reload: true,
|
|
265
|
-
notice: Theme.ok(Theme.glyph.ok + ' Window hidden.'),
|
|
266
|
-
};
|
|
267
|
-
}
|
|
268
|
-
async stop() {
|
|
269
|
-
const none = this.noSandbox();
|
|
270
|
-
if (none)
|
|
271
|
-
return none;
|
|
272
|
-
const plan = this.sandbox.stopPlan();
|
|
273
|
-
const named = plan.running.map((s) => safeText(s.harness) + ' in ' + safeText(s.project ?? path.win32.basename(s.cwd)));
|
|
274
|
-
const lines = [
|
|
275
|
-
plan.running.length
|
|
276
|
-
? 'Stopping ends ' +
|
|
277
|
-
plan.running.length +
|
|
278
|
-
' session' +
|
|
279
|
-
(plan.running.length === 1 ? '' : 's') +
|
|
280
|
-
': ' +
|
|
281
|
-
named.join(', ') +
|
|
282
|
-
'.'
|
|
283
|
-
: 'No session is running.',
|
|
284
|
-
...(plan.others.length ? [plan.others.length + ' of them belong to other projects.'] : []),
|
|
285
|
-
'History and claude-mem sync back when it closes.',
|
|
286
|
-
];
|
|
287
|
-
if (!(await this.app.ask('Stop the sandbox?', lines, 'Stop', true)))
|
|
288
|
-
return {};
|
|
289
|
-
await this.sandbox.shutdown(plan.sandbox);
|
|
290
|
-
return { reload: true, notice: Theme.ok(Theme.glyph.ok + ' The sandbox is shutting down.') };
|
|
291
|
-
}
|
|
292
200
|
async addRoot() {
|
|
293
201
|
const picked = await this.app.pickPath({
|
|
294
202
|
path: ['Sandbox', 'Add a project root'],
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type Tab } from '../../tui/index.js';
|
|
2
|
-
import type { ConfigFile } from '
|
|
2
|
+
import type { ConfigFile } from '../../../app/features/settings/index.js';
|
|
3
3
|
export type Scope = 'user' | 'project';
|
|
4
4
|
export declare const SCOPES: {
|
|
5
5
|
scope: Scope;
|
|
@@ -1,23 +1,17 @@
|
|
|
1
|
+
import { type SessionsList } from '../../../app/features/sessions/index.js';
|
|
1
2
|
import type { Context } from '../../commands/context.js';
|
|
2
|
-
import {
|
|
3
|
-
import { type App, type ListOptions, type ListResult } from '../../tui/index.js';
|
|
3
|
+
import type { App, ListOptions, ListResult } from '../../tui/index.js';
|
|
4
4
|
import { ListPage, type Outcome } from './list-page.js';
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
/** Newest first, this folder's project first. */
|
|
8
|
-
readonly sessions: readonly ListedSession[];
|
|
9
|
-
/** The agent "Start" offers while there is no session. */
|
|
10
|
-
readonly defaultAgent: string;
|
|
11
|
-
}
|
|
5
|
+
/** What the page shows: the sessions query's result (the folder column is never shown here). */
|
|
6
|
+
export type SessionsModel = Omit<SessionsList, 'wide'>;
|
|
12
7
|
/** The list for the sessions tab. Pure. */
|
|
13
8
|
export declare function sessionsOptions(m: SessionsModel): ListOptions<string>;
|
|
14
9
|
export declare class SessionsPage extends ListPage<string> {
|
|
15
10
|
private readonly ctx;
|
|
16
11
|
readonly label = "Sessions";
|
|
17
12
|
private model;
|
|
18
|
-
private readonly
|
|
13
|
+
private readonly operations;
|
|
19
14
|
constructor(app: App, ctx: Context);
|
|
20
|
-
private defaultAgent;
|
|
21
15
|
protected load(): Promise<void>;
|
|
22
16
|
protected options(): ListOptions<string>;
|
|
23
17
|
protected act(result: ListResult<string>): Promise<Outcome<string>>;
|