windows-development-sandbox 1.5.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/README.md +1 -0
- package/config.example.json +27 -1
- 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} +4 -0
- package/dist/{cli/menu/settings/categories.js → app/features/settings/categories.def.js} +40 -46
- 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/{cli/menu/settings → app/kernel}/schema-node.d.ts +9 -0
- package/dist/{cli/menu/settings → app/kernel}/schema-node.js +26 -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 +18 -2
- package/dist/cli/args.js +101 -24
- package/dist/cli/commands/accounts.js +45 -17
- package/dist/cli/commands/context.d.ts +2 -0
- package/dist/cli/commands/context.js +9 -2
- package/dist/cli/commands/data/clean.js +32 -9
- package/dist/cli/commands/engine.d.ts +2 -0
- package/dist/cli/commands/engine.js +60 -0
- package/dist/cli/commands/index.d.ts +2 -1
- package/dist/cli/commands/index.js +2 -1
- package/dist/cli/commands/launch/add-root.d.ts +3 -2
- package/dist/cli/commands/launch/add-root.js +11 -10
- package/dist/cli/commands/launch/launch.js +102 -9
- package/dist/cli/commands/launch/prepare.js +6 -4
- package/dist/cli/commands/launch/running.js +2 -1
- package/dist/cli/commands/launch/summary.d.ts +2 -0
- package/dist/cli/commands/maintenance/audit.js +1 -1
- package/dist/cli/commands/maintenance/clean.d.ts +1 -1
- package/dist/cli/commands/maintenance/clean.js +17 -3
- 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.d.ts +1 -1
- package/dist/cli/commands/maintenance/config.js +38 -10
- package/dist/cli/commands/maintenance/doctor.d.ts +1 -1
- package/dist/cli/commands/maintenance/doctor.js +2 -4
- package/dist/cli/commands/maintenance/logs.js +14 -0
- package/dist/cli/commands/maintenance/migrate.d.ts +2 -1
- package/dist/cli/commands/maintenance/migrate.js +19 -4
- package/dist/cli/commands/maintenance/sync.js +2 -0
- package/dist/cli/commands/maintenance/update.d.ts +2 -0
- package/dist/cli/commands/maintenance/update.js +27 -4
- package/dist/cli/commands/projects/here.js +12 -7
- package/dist/cli/commands/projects/projects.js +26 -17
- package/dist/cli/commands/registry.js +10 -7
- package/dist/cli/commands/repair/checks/agents.d.ts +2 -0
- package/dist/cli/commands/repair/checks/agents.js +70 -0
- package/dist/cli/commands/repair/checks/common.d.ts +8 -0
- package/dist/cli/commands/repair/checks/common.js +22 -0
- 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/data.d.ts +2 -0
- package/dist/cli/commands/repair/checks/data.js +241 -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.d.ts +2 -0
- package/dist/cli/commands/repair/checks/index.js +24 -0
- package/dist/cli/commands/repair/checks/install.d.ts +5 -0
- package/dist/cli/commands/repair/checks/install.js +318 -0
- package/dist/cli/commands/repair/checks/machine.d.ts +2 -0
- package/dist/cli/commands/repair/checks/machine.js +232 -0
- package/dist/cli/commands/repair/checks/network.d.ts +6 -0
- package/dist/cli/commands/repair/checks/network.js +60 -0
- package/dist/cli/commands/repair/checks/pc.d.ts +4 -0
- package/dist/cli/commands/repair/checks/pc.js +86 -0
- package/dist/cli/commands/repair/checks/sandbox.d.ts +2 -0
- package/dist/cli/commands/repair/checks/sandbox.js +282 -0
- package/dist/cli/commands/repair/checks/settings.d.ts +2 -0
- package/dist/cli/commands/repair/checks/settings.js +169 -0
- package/dist/cli/commands/repair/checks/vpn.d.ts +2 -0
- package/dist/cli/commands/repair/checks/vpn.js +78 -0
- package/dist/cli/commands/repair/engine.d.ts +32 -0
- package/dist/cli/commands/repair/engine.js +127 -0
- package/dist/cli/commands/repair/env.d.ts +7 -0
- package/dist/cli/commands/repair/env.js +50 -0
- package/dist/cli/commands/repair/index.d.ts +1 -9
- package/dist/cli/commands/repair/index.js +2 -54
- package/dist/cli/commands/repair/log.d.ts +17 -0
- package/dist/cli/commands/repair/log.js +82 -0
- package/dist/cli/commands/repair/printer.d.ts +32 -0
- package/dist/cli/commands/repair/printer.js +132 -0
- package/dist/cli/commands/repair/run.d.ts +33 -0
- package/dist/cli/commands/repair/run.js +133 -0
- package/dist/cli/commands/repair/types.d.ts +97 -9
- package/dist/cli/commands/repair/types.js +11 -7
- package/dist/cli/commands/resume.js +2 -2
- package/dist/cli/commands/sessions/index.d.ts +0 -4
- package/dist/cli/commands/sessions/index.js +3 -7
- package/dist/cli/commands/setup/index.d.ts +5 -0
- package/dist/cli/commands/setup/index.js +25 -1
- 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/index.d.ts +2 -0
- package/dist/cli/commands/storage/index.js +2 -0
- package/dist/cli/commands/storage/offer.d.ts +3 -0
- package/dist/cli/commands/storage/offer.js +91 -0
- package/dist/cli/commands/storage/storage.d.ts +8 -0
- package/dist/cli/commands/storage/storage.js +179 -0
- package/dist/cli/commands/user-config.js +2 -2
- package/dist/cli/commands/vpn.d.ts +4 -0
- package/dist/cli/commands/vpn.js +91 -0
- package/dist/cli/commands/web.d.ts +4 -0
- package/dist/cli/commands/web.js +97 -0
- package/dist/cli/history.js +1 -1
- package/dist/cli/index.js +48 -4
- package/dist/cli/manifest.d.ts +339 -97
- package/dist/cli/manifest.js +222 -67
- package/dist/cli/menu/add-agent.d.ts +47 -0
- package/dist/cli/menu/add-agent.js +168 -0
- package/dist/cli/menu/apps.d.ts +38 -3
- package/dist/cli/menu/apps.js +80 -5
- package/dist/cli/menu/command-fields.d.ts +18 -0
- package/dist/cli/menu/command-fields.js +61 -0
- package/dist/cli/menu/command-form.d.ts +22 -0
- package/dist/cli/menu/command-form.js +169 -46
- package/dist/cli/menu/data-folder.d.ts +18 -0
- package/dist/cli/menu/data-folder.js +99 -0
- 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 +11 -2
- package/dist/cli/menu/menu.js +36 -15
- package/dist/cli/menu/pages/accounts-page.js +55 -24
- package/dist/cli/menu/pages/agents-page.d.ts +68 -0
- package/dist/cli/menu/pages/agents-page.js +345 -0
- package/dist/cli/menu/pages/apps-page.d.ts +3 -1
- package/dist/cli/menu/pages/apps-page.js +20 -4
- package/dist/cli/menu/pages/list-page.d.ts +43 -3
- package/dist/cli/menu/pages/list-page.js +146 -12
- package/dist/cli/menu/pages/maintenance-page.d.ts +9 -5
- package/dist/cli/menu/pages/maintenance-page.js +172 -85
- package/dist/cli/menu/pages/sandbox-page.d.ts +7 -6
- package/dist/cli/menu/pages/sandbox-page.js +117 -120
- package/dist/cli/menu/pages/scopes.d.ts +1 -1
- package/dist/cli/menu/pages/sessions-page.d.ts +6 -8
- package/dist/cli/menu/pages/sessions-page.js +22 -75
- package/dist/cli/menu/pages/settings-page.d.ts +10 -14
- package/dist/cli/menu/pages/settings-page.js +95 -102
- package/dist/cli/menu/render-view.d.ts +28 -0
- package/dist/cli/menu/render-view.js +112 -0
- package/dist/cli/menu/settings/ask-path.d.ts +14 -0
- package/dist/cli/menu/settings/ask-path.js +14 -0
- package/dist/cli/menu/settings/collections/collection-editor.d.ts +8 -2
- package/dist/cli/menu/settings/collections/collection-editor.js +12 -8
- package/dist/cli/menu/settings/collections/map-editor.js +5 -1
- package/dist/cli/menu/settings/collections/object-list-editor.js +2 -2
- package/dist/cli/menu/settings/collections/object-map-editor.js +2 -2
- package/dist/cli/menu/settings/collections/string-list-editor.d.ts +10 -1
- package/dist/cli/menu/settings/collections/string-list-editor.js +23 -0
- 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 +6 -2
- package/dist/cli/menu/settings/object-editor.js +15 -4
- 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 +10 -1
- package/dist/cli/menu/settings/value-editor.js +99 -63
- package/dist/cli/menu/several.js +7 -5
- 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 +53 -10
- package/dist/cli/menu/shell.js +115 -10
- package/dist/cli/menu/views.d.ts +7 -0
- package/dist/cli/menu/views.js +11 -0
- package/dist/cli/menu/vpn-login.d.ts +16 -0
- package/dist/cli/menu/vpn-login.js +74 -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 +5 -1
- package/dist/cli/output/print.js +15 -4
- 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/accounts-service.d.ts +2 -0
- package/dist/cli/services/accounts-service.js +2 -2
- 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/health-service.d.ts +0 -6
- package/dist/cli/services/health-service.js +5 -42
- package/dist/cli/services/index.d.ts +3 -1
- package/dist/cli/services/index.js +3 -1
- package/dist/cli/services/logs-service.js +4 -3
- package/dist/cli/services/migrate-service.js +1 -1
- package/dist/cli/services/update-service.d.ts +2 -0
- package/dist/cli/services/update-service.js +13 -6
- package/dist/cli/services/vpn-service.d.ts +28 -0
- package/dist/cli/services/vpn-service.js +46 -0
- package/dist/cli/services/web-service.d.ts +22 -0
- package/dist/cli/services/web-service.js +111 -0
- package/dist/cli/tui/app.d.ts +12 -4
- package/dist/cli/tui/app.js +38 -9
- package/dist/cli/tui/dialogs/path-listing.d.ts +43 -0
- package/dist/cli/tui/dialogs/path-listing.js +127 -0
- package/dist/cli/tui/dialogs/path-picker.d.ts +67 -0
- package/dist/cli/tui/dialogs/path-picker.js +423 -0
- package/dist/cli/tui/dialogs/text-screen.d.ts +6 -0
- package/dist/cli/tui/dialogs/text-screen.js +10 -3
- package/dist/cli/tui/frame.d.ts +7 -10
- package/dist/cli/tui/frame.js +19 -10
- package/dist/cli/tui/index.d.ts +4 -3
- package/dist/cli/tui/index.js +2 -1
- package/dist/cli/tui/list/list-screen.d.ts +28 -2
- package/dist/cli/tui/list/list-screen.js +130 -66
- package/dist/cli/tui/list/list-types.d.ts +10 -4
- package/dist/cli/tui/nav.d.ts +29 -0
- package/dist/cli/tui/nav.js +67 -0
- package/dist/cli/tui/terminal.d.ts +7 -0
- package/dist/cli/tui/terminal.js +30 -10
- package/dist/cli/validate.d.ts +1 -1
- package/dist/cli/validate.js +3 -3
- package/dist/cli/version.d.ts +2 -0
- package/dist/cli/version.js +11 -0
- package/dist/core/config/defaults.js +13 -1
- package/dist/core/config/loader.js +12 -2
- package/dist/core/local-config/overrides.js +1 -0
- package/dist/core/prompt.d.ts +19 -0
- package/dist/core/prompt.js +43 -3
- package/dist/core/schema/common.d.ts +6 -0
- package/dist/core/schema/common.js +8 -0
- package/dist/core/schema/config.d.ts +36 -0
- package/dist/core/schema/config.js +26 -2
- package/dist/core/schema/harness.d.ts +2 -0
- package/dist/core/schema/harness.js +13 -2
- package/dist/core/schema/index.d.ts +3 -1
- package/dist/core/schema/index.js +3 -1
- package/dist/core/schema/profile.d.ts +1 -0
- package/dist/core/schema/profile.js +3 -0
- package/dist/core/schema/redact.d.ts +13 -0
- package/dist/core/schema/redact.js +75 -0
- package/dist/core/schema/sandbox.d.ts +6 -0
- package/dist/core/schema/sandbox.js +21 -3
- package/dist/core/schema/vpn.d.ts +18 -0
- package/dist/core/schema/vpn.js +22 -0
- package/dist/core/schema/web.d.ts +6 -0
- package/dist/core/schema/web.js +14 -0
- package/dist/core/types.d.ts +44 -0
- 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 +54 -0
- package/dist/guest/agents/agent-files.js +67 -0
- package/dist/guest/agents/agent-installer.js +2 -9
- package/dist/guest/agents/local-state.d.ts +14 -0
- package/dist/guest/agents/local-state.js +218 -0
- package/dist/guest/agents/sbx-agent.d.ts +2 -0
- package/dist/guest/agents/sbx-agent.js +35 -0
- package/dist/guest/boot/boot.d.ts +4 -0
- package/dist/guest/boot/boot.js +51 -11
- package/dist/guest/daemon/daemon.js +8 -1
- package/dist/guest/daemon/exec.js +2 -1
- package/dist/guest/daemon/idle-shutdown.js +2 -0
- package/dist/guest/daemon/sessions.d.ts +5 -0
- package/dist/guest/daemon/sessions.js +20 -3
- package/dist/guest/entries/agent.d.ts +1 -0
- package/dist/guest/entries/agent.js +10 -0
- package/dist/guest/entries/daemon.js +5 -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 +2 -0
- package/dist/guest/runtime/csc.js +2 -0
- package/dist/guest/runtime/secrets.d.ts +12 -0
- package/dist/guest/runtime/secrets.js +63 -0
- package/dist/guest/sessions/viewer.js +3 -1
- package/dist/guest/setup/claude-profile.d.ts +2 -1
- package/dist/guest/setup/claude-profile.js +12 -1
- package/dist/guest/setup/environment.d.ts +6 -0
- package/dist/guest/setup/environment.js +56 -6
- package/dist/guest/setup/path-plan.d.ts +32 -0
- package/dist/guest/setup/path-plan.js +67 -0
- package/dist/guest/setup/shell-path.d.ts +1 -0
- package/dist/guest/setup/shell-path.js +22 -0
- package/dist/guest/toolchains/languages/python.js +1 -1
- package/dist/guest/toolchains/native/rust-extras.js +4 -2
- package/dist/guest/toolchains/runtimes.js +2 -2
- package/dist/guest/vpn/index.d.ts +1 -0
- package/dist/guest/vpn/index.js +1 -0
- package/dist/guest/vpn/openvpn.d.ts +9 -0
- package/dist/guest/vpn/openvpn.js +47 -0
- package/dist/guest/vpn/tunnel.d.ts +17 -0
- package/dist/guest/vpn/tunnel.js +78 -0
- package/dist/guest/vpn/vpn.d.ts +6 -0
- package/dist/guest/vpn/vpn.js +174 -0
- 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 +6 -2
- package/dist/host/channel/attach.js +6 -3
- package/dist/host/channel/channel.d.ts +9 -0
- package/dist/host/channel/channel.js +30 -2
- 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/health/acl-read.d.ts +17 -0
- package/dist/host/health/acl-read.js +45 -0
- package/dist/host/health/config-backup.d.ts +11 -0
- package/dist/host/health/config-backup.js +73 -0
- package/dist/host/health/index.d.ts +6 -0
- package/dist/host/health/index.js +7 -0
- package/dist/host/health/install-state.d.ts +33 -0
- package/dist/host/health/install-state.js +110 -0
- package/dist/host/health/path-copies.d.ts +32 -0
- package/dist/host/health/path-copies.js +82 -0
- package/dist/host/health/stale.d.ts +45 -0
- package/dist/host/health/stale.js +120 -0
- package/dist/host/health/system.d.ts +37 -0
- package/dist/host/health/system.js +87 -0
- package/dist/host/install/copies.d.ts +13 -0
- package/dist/host/install/copies.js +63 -0
- package/dist/host/install/index.d.ts +1 -0
- package/dist/host/install/index.js +1 -0
- package/dist/host/launch/generate.d.ts +5 -1
- package/dist/host/launch/generate.js +73 -7
- 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 +11 -2
- package/dist/host/launch/stage.js +1 -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/migrate/backup.js +3 -0
- package/dist/host/migrate/migrations/config-file.d.ts +2 -0
- package/dist/host/migrate/migrations/config-file.js +7 -0
- package/dist/host/migrate/migrations/follow-machine-storage.js +9 -1
- package/dist/host/migrate/migrations/pin-storage-root.d.ts +4 -0
- package/dist/host/migrate/migrations/pin-storage-root.js +46 -0
- package/dist/host/migrate/migrations/unpin-config-defaults.js +4 -1
- package/dist/host/migrate/registry.js +2 -1
- package/dist/host/native.d.ts +3 -2
- package/dist/host/native.js +22 -3
- package/dist/host/profile/accounts.d.ts +25 -1
- package/dist/host/profile/accounts.js +96 -13
- package/dist/host/profile/agent-accounts.d.ts +5 -1
- package/dist/host/profile/agent-accounts.js +35 -5
- package/dist/host/profile/claude-login.js +3 -2
- package/dist/host/profile/index.d.ts +2 -1
- package/dist/host/profile/index.js +1 -0
- package/dist/host/profile/plugin-share.d.ts +26 -0
- package/dist/host/profile/plugin-share.js +146 -0
- package/dist/host/projects/join.d.ts +7 -1
- package/dist/host/projects/join.js +21 -4
- package/dist/host/projects/registry.d.ts +16 -10
- package/dist/host/projects/registry.js +74 -6
- 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 +4 -0
- package/dist/host/sandbox/platform.js +23 -4
- package/dist/host/sandbox/tasklist.d.ts +13 -0
- package/dist/host/sandbox/tasklist.js +47 -0
- package/dist/host/secrets/index.d.ts +2 -0
- package/dist/host/secrets/index.js +2 -0
- package/dist/host/secrets/launch-secrets.d.ts +17 -0
- package/dist/host/secrets/launch-secrets.js +94 -0
- package/dist/host/secrets/secret-store.d.ts +25 -0
- package/dist/host/secrets/secret-store.js +89 -0
- package/dist/host/sharing/acl.d.ts +16 -2
- package/dist/host/sharing/acl.js +35 -10
- package/dist/host/sharing/current.js +8 -3
- package/dist/host/sharing/doctor.d.ts +2 -0
- package/dist/host/sharing/doctor.js +44 -0
- package/dist/host/sharing/group-access.d.ts +6 -0
- package/dist/host/sharing/group-access.js +24 -0
- package/dist/host/sharing/index.d.ts +2 -1
- package/dist/host/sharing/index.js +2 -1
- package/dist/host/sharing/lifecycle.d.ts +8 -2
- package/dist/host/sharing/lifecycle.js +16 -7
- package/dist/host/storage/cleanup.d.ts +2 -0
- package/dist/host/storage/cleanup.js +2 -1
- 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/history.d.ts +21 -0
- package/dist/host/storage/history.js +49 -0
- package/dist/host/storage/index.d.ts +6 -0
- package/dist/host/storage/index.js +6 -0
- package/dist/host/storage/move.d.ts +95 -0
- package/dist/host/storage/move.js +384 -0
- package/dist/host/storage/offer.d.ts +11 -0
- package/dist/host/storage/offer.js +36 -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/storage/root.d.ts +18 -0
- package/dist/host/storage/root.js +77 -0
- package/dist/host/tools/conpty.js +3 -2
- package/dist/host/tools/windows-terminal.d.ts +2 -0
- package/dist/host/tools/windows-terminal.js +31 -12
- package/dist/host/update/index.d.ts +1 -1
- package/dist/host/update/index.js +1 -1
- package/dist/host/update/notice.d.ts +2 -0
- package/dist/host/update/notice.js +13 -1
- package/dist/host/update/update-state.d.ts +6 -0
- package/dist/host/update/update-state.js +2 -0
- package/dist/host/update/updater.d.ts +19 -0
- package/dist/host/update/updater.js +88 -12
- package/dist/host/vpn/index.d.ts +4 -0
- package/dist/host/vpn/index.js +4 -0
- package/dist/host/vpn/login.d.ts +24 -0
- package/dist/host/vpn/login.js +79 -0
- package/dist/host/vpn/nordvpn.d.ts +21 -0
- package/dist/host/vpn/nordvpn.js +77 -0
- package/dist/host/vpn/prepare.d.ts +19 -0
- package/dist/host/vpn/prepare.js +138 -0
- package/dist/host/vpn/status.d.ts +12 -0
- package/dist/host/vpn/status.js +53 -0
- package/dist/host/web/auth.d.ts +38 -0
- package/dist/host/web/auth.js +96 -0
- package/dist/host/web/backend.d.ts +14 -0
- package/dist/host/web/backend.js +1 -0
- package/dist/host/web/bridge.d.ts +27 -0
- package/dist/host/web/bridge.js +144 -0
- package/dist/host/web/browser.d.ts +3 -0
- package/dist/host/web/browser.js +23 -0
- package/dist/host/web/control.d.ts +17 -0
- package/dist/host/web/control.js +67 -0
- package/dist/host/web/index.d.ts +10 -0
- package/dist/host/web/index.js +9 -0
- package/dist/host/web/rpc.d.ts +24 -0
- package/dist/host/web/rpc.js +149 -0
- package/dist/host/web/runner.d.ts +16 -0
- package/dist/host/web/runner.js +44 -0
- package/dist/host/web/server.d.ts +47 -0
- package/dist/host/web/server.js +238 -0
- package/dist/host/web/state.d.ts +20 -0
- package/dist/host/web/state.js +41 -0
- package/dist/host/web/static-files.d.ts +13 -0
- package/dist/host/web/static-files.js +57 -0
- package/dist/runtime/agent.js +27675 -0
- package/dist/runtime/daemon.js +1950 -1122
- package/dist/runtime/db.js +302 -111
- package/dist/runtime/main.js +1560 -275
- package/dist/runtime/netproxy.js +168 -8
- package/dist/runtime/view.js +186 -13
- package/dist/selftest/accounts.test.js +40 -0
- package/dist/selftest/agent-paths.test.d.ts +2 -0
- package/dist/selftest/agent-paths.test.js +125 -0
- package/dist/selftest/app.test.d.ts +2 -0
- package/dist/selftest/app.test.js +324 -0
- package/dist/selftest/channel.test.js +18 -0
- package/dist/selftest/cli.test.js +35 -4
- 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.d.ts +2 -0
- package/dist/selftest/credentials.test.js +198 -0
- package/dist/selftest/engine.test.d.ts +2 -0
- package/dist/selftest/engine.test.js +127 -0
- package/dist/selftest/generate.test.js +1 -1
- package/dist/selftest/hcs.test.d.ts +2 -0
- package/dist/selftest/hcs.test.js +482 -0
- package/dist/selftest/health.test.d.ts +2 -0
- package/dist/selftest/health.test.js +470 -0
- package/dist/selftest/heavy-load.test.d.ts +2 -0
- package/dist/selftest/heavy-load.test.js +329 -0
- package/dist/selftest/host-sim.test.js +2 -0
- package/dist/selftest/index.js +31 -0
- package/dist/selftest/layout.test.js +14 -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.d.ts +7 -0
- package/dist/selftest/menu-screens.js +68 -17
- package/dist/selftest/menu.test.js +603 -22
- package/dist/selftest/migrate.test.js +1 -1
- package/dist/selftest/personalization.test.js +3 -1
- package/dist/selftest/projects.test.js +39 -1
- package/dist/selftest/shared-use.test.js +64 -2
- package/dist/selftest/sharing.test.js +50 -1
- package/dist/selftest/storage.test.d.ts +2 -0
- package/dist/selftest/storage.test.js +363 -0
- 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 +20 -0
- package/dist/selftest/support/hcs-probes.d.ts +17 -0
- package/dist/selftest/support/hcs-probes.js +41 -0
- package/dist/selftest/support/releases.js +1 -1
- package/dist/selftest/toolchains.test.js +21 -0
- package/dist/selftest/update-service.test.js +87 -3
- package/dist/selftest/vpn.test.d.ts +2 -0
- package/dist/selftest/vpn.test.js +412 -0
- package/dist/selftest/web.test.d.ts +2 -0
- package/dist/selftest/web.test.js +402 -0
- package/dist/shared/apps/catalogue.js +31 -0
- package/dist/shared/channel/index.d.ts +1 -0
- package/dist/shared/channel/index.js +1 -0
- package/dist/shared/channel/run-dir.d.ts +9 -1
- package/dist/shared/channel/run-dir.js +18 -1
- package/dist/shared/channel/schema.d.ts +53 -0
- package/dist/shared/channel/schema.js +38 -0
- package/dist/shared/channel/secrets.d.ts +29 -0
- package/dist/shared/channel/secrets.js +50 -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 +29 -0
- package/dist/shared/vpn/download.js +30 -0
- package/dist/shared/vpn/kill-switch.d.ts +18 -0
- package/dist/shared/vpn/kill-switch.js +81 -0
- package/dist/shared/vpn/ovpn.d.ts +23 -0
- package/dist/shared/vpn/ovpn.js +244 -0
- package/dist/shared/vpn/wireguard.d.ts +51 -0
- package/dist/shared/vpn/wireguard.js +227 -0
- package/dist/shared/web/index.d.ts +1 -0
- package/dist/shared/web/index.js +1 -0
- package/dist/shared/web/protocol.d.ts +61 -0
- package/dist/shared/web/protocol.js +35 -0
- package/dist/sync/sync-cycle.js +9 -5
- package/dist/sync/sync-state.d.ts +1 -0
- package/dist/sync/sync-state.js +1 -0
- package/dist/sync/watcher.d.ts +13 -0
- package/dist/sync/watcher.js +102 -3
- package/dist/web/index.html +14 -0
- package/dist/web/main-NRRS5O6Z.js +157 -0
- package/dist/web/main-T5DMCHYV.css +1 -0
- package/native/csharp/FolderSecurity.cs +29 -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/protect-data.ps1 +29 -0
- package/native/scripts/read-folder-sddl.ps1 +10 -0
- package/native/scripts/run-elevated.ps1 +17 -4
- package/native/scripts/set-folder-access.ps1 +49 -7
- package/native/scripts/stop-events.ps1 +23 -8
- package/node_modules/ws/LICENSE +20 -0
- package/node_modules/ws/README.md +548 -0
- package/node_modules/ws/browser.js +8 -0
- package/node_modules/ws/index.js +22 -0
- package/node_modules/ws/lib/buffer-util.js +131 -0
- package/node_modules/ws/lib/constants.js +19 -0
- package/node_modules/ws/lib/event-target.js +292 -0
- package/node_modules/ws/lib/extension.js +203 -0
- package/node_modules/ws/lib/limiter.js +55 -0
- package/node_modules/ws/lib/permessage-deflate.js +530 -0
- package/node_modules/ws/lib/receiver.js +743 -0
- package/node_modules/ws/lib/sender.js +607 -0
- package/node_modules/ws/lib/stream.js +161 -0
- package/node_modules/ws/lib/subprotocol.js +62 -0
- package/node_modules/ws/lib/validation.js +152 -0
- package/node_modules/ws/lib/websocket-server.js +562 -0
- package/node_modules/ws/lib/websocket.js +1421 -0
- package/node_modules/ws/package.json +74 -0
- package/node_modules/ws/wrapper.mjs +21 -0
- package/package.json +22 -5
- package/sandbox/csharp/EnvBroadcast.cs +33 -0
- package/sandbox/csharp/MemGov.cs +398 -0
- package/sandbox/csharp/PathSync.cs +90 -0
- package/sandbox/csharp/PtyHost.cs +111 -5
- package/sandbox/scripts/install-shell-path.ps1 +73 -0
- package/sandbox/scripts/set-machine-environment.ps1 +37 -4
- package/schemas/config.schema.json +136 -7
- package/schemas/sandbox-config.schema.json +17 -4
- package/dist/cli/commands/repair/checks.d.ts +0 -2
- package/dist/cli/commands/repair/checks.js +0 -246
- 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 -45
- package/dist/cli/commands/sessions/status.d.ts +0 -2
- package/dist/cli/commands/sessions/status.js +0 -93
- package/dist/cli/commands/sessions/window.d.ts +0 -3
- package/dist/cli/commands/sessions/window.js +0 -18
- package/dist/cli/menu/pages/start-page.d.ts +0 -43
- package/dist/cli/menu/pages/start-page.js +0 -192
- package/dist/cli/tui/tab-bar.d.ts +0 -9
- package/dist/cli/tui/tab-bar.js +0 -33
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
// Section 1: the agents. "Start" lists the agents you can start here (Enter starts one) after "Repeat last", and ends
|
|
2
|
+
// with "Add an agent…" (the new one appears in the list); "Options" holds how a start goes (attach, window, folder) and
|
|
3
|
+
// the other ways to start; "On this PC" has the not-sandboxed entries while agent commands are on.
|
|
4
|
+
import fs from 'node:fs';
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
import { DEFAULTS } from '../../../core/config/index.js';
|
|
7
|
+
import { errMsg } from '../../../core/util/index.js';
|
|
8
|
+
import { commandLine, readHistory } from '../../history.js';
|
|
9
|
+
import { AgentCommandsService } from '../../services/index.js';
|
|
10
|
+
import { commandSpec } from '../../manifest.js';
|
|
11
|
+
import { Text, Theme, } from '../../tui/index.js';
|
|
12
|
+
import { AddAgent, makeDefaultAgent, removeAgent } from '../add-agent.js';
|
|
13
|
+
import { CommandForm } from '../command-form.js';
|
|
14
|
+
import { askPath } from '../settings/ask-path.js';
|
|
15
|
+
import { SeveralAgents } from '../several.js';
|
|
16
|
+
import { ListPage } from './list-page.js';
|
|
17
|
+
/** The agents of `harnesses` that are not built in. Pure. */
|
|
18
|
+
export function addedAgents(names) {
|
|
19
|
+
return names.filter((n) => !(n in DEFAULTS.harnesses));
|
|
20
|
+
}
|
|
21
|
+
const agentOf = (id) => (id.startsWith('agent:') ? id.slice(6) : undefined);
|
|
22
|
+
/** The keys of the Start category: make an agent the default, remove one you added. Pure. */
|
|
23
|
+
export function agentActions(m) {
|
|
24
|
+
const isOther = (id) => {
|
|
25
|
+
const name = agentOf(id);
|
|
26
|
+
return name !== undefined && name !== m.defaultAgent;
|
|
27
|
+
};
|
|
28
|
+
return [
|
|
29
|
+
{ key: 'd', label: 'make default', importance: 1, applies: isOther },
|
|
30
|
+
{
|
|
31
|
+
key: 'x',
|
|
32
|
+
label: 'remove',
|
|
33
|
+
importance: 1,
|
|
34
|
+
applies: (id) => isOther(id) && (m.removable ?? []).includes(agentOf(id) ?? ''),
|
|
35
|
+
},
|
|
36
|
+
];
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* The "not sandboxed" entries: only while agent commands are on (typing the agent then starts the sandbox, so a way to
|
|
40
|
+
* run the real one is needed), one per agent found installed on this PC.
|
|
41
|
+
*/
|
|
42
|
+
export function hostAgentsToShow(enabled, found) {
|
|
43
|
+
return enabled ? found.map((a) => a.harness) : [];
|
|
44
|
+
}
|
|
45
|
+
const WINDOW_TEXT = { config: 'as configured', hide: 'hidden', show: 'shown' };
|
|
46
|
+
/** The command line a start stands for. Pure. */
|
|
47
|
+
export function startArgv(m, agent, cwd) {
|
|
48
|
+
return [
|
|
49
|
+
'launch',
|
|
50
|
+
'--harness',
|
|
51
|
+
agent,
|
|
52
|
+
...(m.attach ? ['--terminal'] : []),
|
|
53
|
+
...(m.window === 'hide' ? ['--headless'] : m.window === 'show' ? ['--window'] : []),
|
|
54
|
+
...(path.resolve(m.folder).toLowerCase() === path.resolve(cwd).toLowerCase() ? [] : ['--workspace', m.folder]),
|
|
55
|
+
];
|
|
56
|
+
}
|
|
57
|
+
/** The categories of the agents section; "On this PC" only when there is something in it. Pure. */
|
|
58
|
+
export function agentCategories(m) {
|
|
59
|
+
return [
|
|
60
|
+
{
|
|
61
|
+
id: 'start',
|
|
62
|
+
label: 'Start',
|
|
63
|
+
description: 'Agents you can start in ' + m.folder + '. Add an agent at the end of the list.',
|
|
64
|
+
},
|
|
65
|
+
{ id: 'options', label: 'Options', description: 'How a start goes, and the other ways to start.' },
|
|
66
|
+
...(m.hostAgents.length
|
|
67
|
+
? [
|
|
68
|
+
{
|
|
69
|
+
id: 'host',
|
|
70
|
+
label: 'On this PC',
|
|
71
|
+
description: 'The real agents on this PC, with no sandbox around them.',
|
|
72
|
+
},
|
|
73
|
+
]
|
|
74
|
+
: []),
|
|
75
|
+
];
|
|
76
|
+
}
|
|
77
|
+
/** The list for the agents section. Pure. */
|
|
78
|
+
export function agentsOptions(m, cwd = process.cwd()) {
|
|
79
|
+
const section = 'Start in ' + path.basename(m.folder);
|
|
80
|
+
const agents = [...m.agents].sort((a, b) => Number(b.name === m.defaultAgent) - Number(a.name === m.defaultAgent));
|
|
81
|
+
return {
|
|
82
|
+
path: [],
|
|
83
|
+
categories: agentCategories(m),
|
|
84
|
+
items: [
|
|
85
|
+
...(m.last
|
|
86
|
+
? [
|
|
87
|
+
{
|
|
88
|
+
value: 'repeat',
|
|
89
|
+
label: 'Repeat last',
|
|
90
|
+
category: 'start',
|
|
91
|
+
section: 'Quick start',
|
|
92
|
+
hint: Theme.muted(Text.truncate(commandLine(m.last), 50)),
|
|
93
|
+
description: 'Runs the last command again.',
|
|
94
|
+
},
|
|
95
|
+
]
|
|
96
|
+
: []),
|
|
97
|
+
...agents.map((a) => ({
|
|
98
|
+
value: 'agent:' + a.name,
|
|
99
|
+
label: a.name,
|
|
100
|
+
category: 'start',
|
|
101
|
+
section,
|
|
102
|
+
hint: (a.name === m.defaultAgent ? Theme.accent('default ') : '') +
|
|
103
|
+
(a.ready ? Theme.ok('ready') : Theme.muted('installs on first start')),
|
|
104
|
+
description: 'Starts ' +
|
|
105
|
+
a.name +
|
|
106
|
+
' in ' +
|
|
107
|
+
path.basename(m.folder) +
|
|
108
|
+
'.' +
|
|
109
|
+
(a.name === m.defaultAgent ? ' It is the default agent.' : '') +
|
|
110
|
+
((m.removable ?? []).includes(a.name) && a.name !== m.defaultAgent
|
|
111
|
+
? ' You added it: x removes it.'
|
|
112
|
+
: (m.removable ?? []).includes(a.name)
|
|
113
|
+
? ' You added it. Make another agent the default to remove it.'
|
|
114
|
+
: ''),
|
|
115
|
+
details: [Theme.muted('Command ') + commandLine(startArgv(m, a.name, cwd))],
|
|
116
|
+
})),
|
|
117
|
+
{
|
|
118
|
+
value: 'add',
|
|
119
|
+
label: 'Add an agent…',
|
|
120
|
+
category: 'start',
|
|
121
|
+
section,
|
|
122
|
+
description: 'Add another agent by its npm or Python package, or a program on this PC. It is saved in your settings and appears in this list.',
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
value: 'opt:attach',
|
|
126
|
+
label: 'Attach this terminal',
|
|
127
|
+
category: 'options',
|
|
128
|
+
section: 'This start',
|
|
129
|
+
hint: m.attach ? Theme.ok('yes') : Theme.muted('no'),
|
|
130
|
+
flip: true,
|
|
131
|
+
description: 'Shows the agent in this terminal (Ctrl+] detaches). Without it the agent runs in the sandbox.',
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
value: 'opt:window',
|
|
135
|
+
label: 'Sandbox window',
|
|
136
|
+
category: 'options',
|
|
137
|
+
section: 'This start',
|
|
138
|
+
hint: WINDOW_TEXT[m.window],
|
|
139
|
+
description: 'Hide or show the Windows Sandbox window (sbx-show brings a hidden one back).',
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
value: 'opt:folder',
|
|
143
|
+
label: 'Folder',
|
|
144
|
+
category: 'options',
|
|
145
|
+
section: 'This start',
|
|
146
|
+
hint: Text.middle(m.folder, 40),
|
|
147
|
+
description: 'The project folder to work on.',
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
value: 'more',
|
|
151
|
+
label: 'More start options…',
|
|
152
|
+
category: 'options',
|
|
153
|
+
section: 'Start differently',
|
|
154
|
+
description: 'Node and Python versions, databases, scripts and the rest of the start form.',
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
value: 'several',
|
|
158
|
+
label: 'Start several agents…',
|
|
159
|
+
category: 'options',
|
|
160
|
+
section: 'Start differently',
|
|
161
|
+
description: 'One or more projects, one or more agents each, all in one sandbox.',
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
value: 'noagent',
|
|
165
|
+
label: 'Sandbox without an agent…',
|
|
166
|
+
category: 'options',
|
|
167
|
+
section: 'Start differently',
|
|
168
|
+
description: 'Tools and databases only.',
|
|
169
|
+
},
|
|
170
|
+
...m.hostAgents.map((agent) => ({
|
|
171
|
+
value: 'host:' + agent,
|
|
172
|
+
label: agent + ' (not sandboxed)',
|
|
173
|
+
category: 'host',
|
|
174
|
+
description: 'Runs the real ' + agent + ' on this PC, with no sandbox around it.',
|
|
175
|
+
})),
|
|
176
|
+
],
|
|
177
|
+
enterLabel: (_category, id) => ENTER[id ?? ''] ?? (id?.startsWith('agent:') ? 'start' : id?.startsWith('host:') ? 'run' : 'open'),
|
|
178
|
+
actions: (category) => (category === 'start' ? agentActions(m) : []),
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
/** What Enter does on the rows that are not an agent. */
|
|
182
|
+
const ENTER = {
|
|
183
|
+
repeat: 'run again',
|
|
184
|
+
add: 'add',
|
|
185
|
+
'opt:attach': 'switch',
|
|
186
|
+
'opt:window': 'change',
|
|
187
|
+
'opt:folder': 'choose',
|
|
188
|
+
};
|
|
189
|
+
export class AgentsPage extends ListPage {
|
|
190
|
+
ctx;
|
|
191
|
+
file;
|
|
192
|
+
draft;
|
|
193
|
+
label = 'Agents';
|
|
194
|
+
attach = false;
|
|
195
|
+
window = 'config';
|
|
196
|
+
folder = process.cwd();
|
|
197
|
+
model;
|
|
198
|
+
/** What load() looked up (programs on PATH, the history file): not asked again for every list that is built. */
|
|
199
|
+
facts;
|
|
200
|
+
constructor(app, ctx,
|
|
201
|
+
/** Your own config file and its unsaved changes: where "Add an agent" writes to. */
|
|
202
|
+
file, draft) {
|
|
203
|
+
super(app);
|
|
204
|
+
this.ctx = ctx;
|
|
205
|
+
this.file = file;
|
|
206
|
+
this.draft = draft;
|
|
207
|
+
}
|
|
208
|
+
/** Every agent: the configured ones, and any added in Settings that is not saved yet. */
|
|
209
|
+
harnesses() {
|
|
210
|
+
const config = this.file.userConfig();
|
|
211
|
+
const staged = this.draft.has(this.file, ['harnesses'])
|
|
212
|
+
? this.draft.value(this.file, ['harnesses'])
|
|
213
|
+
: undefined;
|
|
214
|
+
return { ...config.harnesses, ...staged };
|
|
215
|
+
}
|
|
216
|
+
/** Is this agent already in the sandbox's persistent storage (so starting it needs no install)? */
|
|
217
|
+
installed(name, harnesses) {
|
|
218
|
+
const h = harnesses[name];
|
|
219
|
+
const dir = path.join(this.ctx.dataPath, 'tools', 'agents', name);
|
|
220
|
+
return (Boolean(h) &&
|
|
221
|
+
[h.hostExecutable, h.npmBin && h.npmBin + '.cmd', h.uvBin && h.uvBin + '.exe'].some((f) => f && fs.existsSync(path.join(dir, f))));
|
|
222
|
+
}
|
|
223
|
+
current() {
|
|
224
|
+
const harnesses = this.harnesses();
|
|
225
|
+
if (!this.facts)
|
|
226
|
+
throw new Error('The agents tab was not loaded');
|
|
227
|
+
const { commands, last } = this.facts;
|
|
228
|
+
return {
|
|
229
|
+
folder: this.folder,
|
|
230
|
+
defaultAgent: this.file.userConfig().defaultHarness,
|
|
231
|
+
agents: Object.keys(harnesses).map((name) => ({ name, ready: this.installed(name, harnesses) })),
|
|
232
|
+
last,
|
|
233
|
+
attach: this.attach,
|
|
234
|
+
window: this.window,
|
|
235
|
+
hostAgents: hostAgentsToShow(commands.enabled, commands.found),
|
|
236
|
+
removable: addedAgents(Object.keys(harnesses)),
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
/** The cursor starts on the default agent. */
|
|
240
|
+
initialFocus() {
|
|
241
|
+
return 'agent:' + this.file.userConfig().defaultHarness;
|
|
242
|
+
}
|
|
243
|
+
async load() {
|
|
244
|
+
this.facts = {
|
|
245
|
+
commands: await new AgentCommandsService(this.ctx).statusAsync(),
|
|
246
|
+
last: readHistory()[0]?.argv,
|
|
247
|
+
};
|
|
248
|
+
this.model = this.current();
|
|
249
|
+
}
|
|
250
|
+
options() {
|
|
251
|
+
this.model = this.current();
|
|
252
|
+
return agentsOptions(this.model);
|
|
253
|
+
}
|
|
254
|
+
async act(result) {
|
|
255
|
+
if (result.kind === 'action')
|
|
256
|
+
return this.action(result.key, result.value);
|
|
257
|
+
if (result.kind !== 'pick')
|
|
258
|
+
return {};
|
|
259
|
+
const id = result.value;
|
|
260
|
+
const model = this.current();
|
|
261
|
+
if (id.startsWith('host:'))
|
|
262
|
+
return { exit: { kind: 'run', argv: ['host', id.slice(5)] } };
|
|
263
|
+
if (id.startsWith('agent:'))
|
|
264
|
+
return { exit: { kind: 'run', argv: startArgv(model, id.slice(6), process.cwd()) } };
|
|
265
|
+
switch (id) {
|
|
266
|
+
case 'repeat':
|
|
267
|
+
return model.last ? { exit: { kind: 'run', argv: model.last } } : {};
|
|
268
|
+
case 'add':
|
|
269
|
+
return this.add(model);
|
|
270
|
+
case 'opt:attach':
|
|
271
|
+
this.attach = !this.attach;
|
|
272
|
+
return {};
|
|
273
|
+
case 'opt:window':
|
|
274
|
+
this.window = this.window === 'config' ? 'hide' : this.window === 'hide' ? 'show' : 'config';
|
|
275
|
+
return {};
|
|
276
|
+
case 'opt:folder': {
|
|
277
|
+
const picked = await askPath(this.app, {
|
|
278
|
+
path: ['Agents', 'Folder'],
|
|
279
|
+
title: 'Choose the project folder',
|
|
280
|
+
kind: 'dir',
|
|
281
|
+
initial: this.folder,
|
|
282
|
+
validate: (v) => (fs.existsSync(path.resolve(v)) ? true : 'That folder does not exist.'),
|
|
283
|
+
});
|
|
284
|
+
if (picked)
|
|
285
|
+
this.folder = path.resolve(picked);
|
|
286
|
+
return {};
|
|
287
|
+
}
|
|
288
|
+
case 'more': {
|
|
289
|
+
const argv = await new CommandForm(this.app, this.ctx, commandSpec('launch'), startArgv(model, model.defaultAgent, process.cwd()).slice(1)).run();
|
|
290
|
+
return argv ? { exit: { kind: 'run', argv } } : {};
|
|
291
|
+
}
|
|
292
|
+
case 'several': {
|
|
293
|
+
const argv = await new SeveralAgents(this.app, this.ctx).run();
|
|
294
|
+
return argv ? { exit: { kind: 'run', argv } } : {};
|
|
295
|
+
}
|
|
296
|
+
case 'noagent': {
|
|
297
|
+
const argv = await new CommandForm(this.app, this.ctx, commandSpec('start')).run();
|
|
298
|
+
return argv ? { exit: { kind: 'run', argv } } : {};
|
|
299
|
+
}
|
|
300
|
+
default:
|
|
301
|
+
return {};
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
/** Make default (d) and Remove (x) on the highlighted agent. */
|
|
305
|
+
async action(key, id) {
|
|
306
|
+
const name = id?.startsWith('agent:') ? id.slice(6) : undefined;
|
|
307
|
+
if (!name)
|
|
308
|
+
return {};
|
|
309
|
+
try {
|
|
310
|
+
if (key === 'd') {
|
|
311
|
+
makeDefaultAgent(this.file, this.draft, name);
|
|
312
|
+
return { focus: id, notice: Theme.ok(Theme.glyph.ok + ' ' + name + ' is the default agent.') };
|
|
313
|
+
}
|
|
314
|
+
if (key !== 'x')
|
|
315
|
+
return {};
|
|
316
|
+
const ok = await this.app.ask('Remove ' + name + '?', ['It is taken out of your settings. Its files in the sandbox stay until you clean them up.'], 'Remove', true);
|
|
317
|
+
if (!ok)
|
|
318
|
+
return {};
|
|
319
|
+
removeAgent(this.file, this.draft, name);
|
|
320
|
+
return {
|
|
321
|
+
focus: 'agent:' + this.file.userConfig().defaultHarness,
|
|
322
|
+
notice: Theme.ok(Theme.glyph.ok + ' Removed ' + name + '.'),
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
catch (e) {
|
|
326
|
+
return { notice: Theme.error(Theme.glyph.cross + ' ' + errMsg(e)) };
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
/** "Add an agent…": the new agent shows in the list, with the cursor on it. */
|
|
330
|
+
async add(model) {
|
|
331
|
+
try {
|
|
332
|
+
const added = await new AddAgent(this.app, this.file, this.draft, model.agents.map((a) => a.name)).run();
|
|
333
|
+
if (!added)
|
|
334
|
+
return {};
|
|
335
|
+
return {
|
|
336
|
+
focus: 'agent:' + added.name,
|
|
337
|
+
notice: Theme.ok(Theme.glyph.ok + ' Added ' + added.name + '.') +
|
|
338
|
+
Theme.muted(added.saved ? ' Enter starts it.' : ' Ctrl+S saves it.'),
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
catch (e) {
|
|
342
|
+
return { notice: Theme.error(Theme.glyph.cross + ' ' + errMsg(e)) };
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type App, type ListOptions, type ListResult } from '../../tui/index.js';
|
|
2
2
|
import { AppsModel } from '../apps.js';
|
|
3
|
-
import type { ConfigFile } from '
|
|
3
|
+
import type { ConfigFile } from '../../../app/features/settings/index.js';
|
|
4
4
|
import type { Draft } from '../settings/draft.js';
|
|
5
5
|
import { type Scope } from './scopes.js';
|
|
6
6
|
import { ListPage, type Outcome } from './list-page.js';
|
|
@@ -22,5 +22,7 @@ export declare class AppsPage extends ListPage<string> {
|
|
|
22
22
|
protected options(): ListOptions<string>;
|
|
23
23
|
/** Every tick is staged as it happens, so leaving or saving always sees it. */
|
|
24
24
|
protected afterKey(): Step<ShellExit>;
|
|
25
|
+
/** Opens the GitHub request form in the browser and says where it is. */
|
|
26
|
+
private request;
|
|
25
27
|
protected act(result: ListResult<string>): Promise<Outcome<string>>;
|
|
26
28
|
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
//
|
|
1
|
+
// Section 4: the apps catalogue. Groups on the left, space ticks, and the ticks are staged until Ctrl+S saves them. Two
|
|
2
2
|
// scopes like Settings: apps for every project, or for this project only.
|
|
3
3
|
import { errMsg } from '../../../core/util/index.js';
|
|
4
4
|
import { Theme } from '../../tui/index.js';
|
|
5
|
-
import {
|
|
5
|
+
import { openIssuePage } from '../../../host/web/index.js';
|
|
6
|
+
import { AppsModel, requestAppUrl } from '../apps.js';
|
|
6
7
|
import { ValueEditor } from '../settings/value-editor.js';
|
|
7
8
|
import { SCOPES, scopeStatus } from './scopes.js';
|
|
8
9
|
import { ListPage } from './list-page.js';
|
|
@@ -17,8 +18,10 @@ export function appsOptions(model, file, draft, scope) {
|
|
|
17
18
|
enterTicks: true,
|
|
18
19
|
categories: model.categories(),
|
|
19
20
|
items: model.items(draft),
|
|
20
|
-
actions:
|
|
21
|
-
|
|
21
|
+
actions: [
|
|
22
|
+
...(file.isProject ? [] : [{ key: 'c', label: 'your own programs' }]),
|
|
23
|
+
{ key: 'r', label: 'request an app' },
|
|
24
|
+
],
|
|
22
25
|
};
|
|
23
26
|
}
|
|
24
27
|
export class AppsPage extends ListPage {
|
|
@@ -51,12 +54,25 @@ export class AppsPage extends ListPage {
|
|
|
51
54
|
this.model.stageTicks(this.draft, this.ticked());
|
|
52
55
|
return;
|
|
53
56
|
}
|
|
57
|
+
/** Opens the GitHub request form in the browser and says where it is. */
|
|
58
|
+
request() {
|
|
59
|
+
const url = requestAppUrl();
|
|
60
|
+
try {
|
|
61
|
+
openIssuePage(url);
|
|
62
|
+
return Theme.ok(Theme.glyph.ok + ' Opened the request form in your browser: ') + Theme.muted(url);
|
|
63
|
+
}
|
|
64
|
+
catch (e) {
|
|
65
|
+
return Theme.error(Theme.glyph.cross + ' ' + errMsg(e)) + Theme.muted(' Open it yourself: ' + url);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
54
68
|
async act(result) {
|
|
55
69
|
this.model.stageTicks(this.draft, this.ticked());
|
|
56
70
|
if (result.kind === 'tab') {
|
|
57
71
|
this.scope = SCOPES[result.index].scope;
|
|
58
72
|
return {};
|
|
59
73
|
}
|
|
74
|
+
if (result.kind === 'action' && result.key === 'r')
|
|
75
|
+
return { notice: this.request() };
|
|
60
76
|
if (result.kind !== 'action' || result.key !== 'c')
|
|
61
77
|
return {};
|
|
62
78
|
const node = this.file.schema.child('apps')?.child('custom');
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type App, type FrameParts, type Key, type ListOptions, type ListResult } from '../../tui/index.js';
|
|
1
|
+
import { type App, type Category, type FrameParts, type Key, type ListOptions, type ListResult } from '../../tui/index.js';
|
|
2
2
|
import type { Size, Step } from '../../tui/index.js';
|
|
3
3
|
import type { Page, ShellExit } from '../shell.js';
|
|
4
4
|
/** What an action did: leave the shell, and/or what the rebuilt list shows. */
|
|
@@ -16,19 +16,59 @@ export declare abstract class ListPage<T> implements Page {
|
|
|
16
16
|
readonly stages: boolean;
|
|
17
17
|
private list;
|
|
18
18
|
private notice;
|
|
19
|
+
/** The list has the keyboard (the menu's navigation does not). */
|
|
20
|
+
private focused;
|
|
21
|
+
/** The entry that was last acted on: the cursor returns to it when the section opens again. */
|
|
22
|
+
private lastFocus;
|
|
23
|
+
/** A search to start the next list with (restored from the last run); used once. */
|
|
24
|
+
private pendingQuery;
|
|
25
|
+
/** The data has arrived at least once (until then the list is "Loading…"). */
|
|
26
|
+
private loaded;
|
|
27
|
+
/** Counts loads, so that a slow one that was overtaken does not replace newer data. */
|
|
28
|
+
private generation;
|
|
29
|
+
/** A category asked for before the data arrived: it opens when it does. */
|
|
30
|
+
private wantedCategory;
|
|
19
31
|
constructor(app: App);
|
|
20
32
|
/** Loads the data the list shows (called when the tab opens and after actions that change it). */
|
|
21
33
|
protected abstract load(): Promise<void>;
|
|
22
34
|
/** The list for the data loaded (pure: no I/O). */
|
|
23
35
|
protected abstract options(): ListOptions<T>;
|
|
36
|
+
/** The entry the cursor starts on the first time the section opens (default: the first). */
|
|
37
|
+
protected initialFocus(): T | undefined;
|
|
24
38
|
/** Does what the list returned. */
|
|
25
39
|
protected abstract act(result: ListResult<T>): Promise<Outcome<T>>;
|
|
40
|
+
/** The data has not arrived yet (the tab shows "Loading…"). */
|
|
41
|
+
get loading(): boolean;
|
|
26
42
|
get capturing(): boolean;
|
|
27
|
-
/** The id of the open
|
|
28
|
-
|
|
43
|
+
/** The id of the open category, if the list has any. */
|
|
44
|
+
get category(): string | undefined;
|
|
45
|
+
/** The search typed in the list ('' when none). */
|
|
46
|
+
get search(): string;
|
|
47
|
+
/** Shows the list with this search typed (the menu opens on the search it was left on). */
|
|
48
|
+
restoreSearch(text: string): void;
|
|
49
|
+
categories(): readonly Category[];
|
|
50
|
+
selectCategory(id: string): Promise<void>;
|
|
51
|
+
setFocus(list: boolean): void;
|
|
52
|
+
/** The list on screen, built when there is none yet. */
|
|
53
|
+
private screen;
|
|
54
|
+
/** A list from the current data; its categories are shown by the menu's navigation. */
|
|
55
|
+
private build;
|
|
29
56
|
/** The entries ticked in a multi-select list. */
|
|
30
57
|
protected ticked(): T[];
|
|
58
|
+
/** Loads the data again; a slow load does not hold up the keys (the tab keeps what it showed, then updates). */
|
|
31
59
|
open(): Promise<void>;
|
|
60
|
+
/**
|
|
61
|
+
* Loads the data and waits for it at most QUICK_LOAD_MS. In time, the list is built here (`build`) or by the caller;
|
|
62
|
+
* later, the list is built when the data arrives, on the entry and search the user has moved to meanwhile.
|
|
63
|
+
*/
|
|
64
|
+
private reload;
|
|
65
|
+
private loadData;
|
|
66
|
+
/** Back on the entry used last, when it is still in the category that is open. */
|
|
67
|
+
private rebuildOpened;
|
|
68
|
+
/** Data that came after the keys stopped waiting: the cursor and the search stay where the user moved them. */
|
|
69
|
+
private rebuildLate;
|
|
70
|
+
private rebuildOn;
|
|
71
|
+
private openWantedCategory;
|
|
32
72
|
/** Builds the list again, on `focus` when it is still there. */
|
|
33
73
|
protected rebuild(focus: T | undefined, notice?: string): void;
|
|
34
74
|
/** Shows `text` now, before slow work starts. */
|
|
@@ -1,33 +1,164 @@
|
|
|
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.
|
|
3
|
-
|
|
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.
|
|
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;
|
|
7
17
|
list;
|
|
8
18
|
notice;
|
|
19
|
+
/** The list has the keyboard (the menu's navigation does not). */
|
|
20
|
+
focused = true;
|
|
21
|
+
/** The entry that was last acted on: the cursor returns to it when the section opens again. */
|
|
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;
|
|
9
31
|
constructor(app) {
|
|
10
32
|
this.app = app;
|
|
11
33
|
}
|
|
34
|
+
/** The entry the cursor starts on the first time the section opens (default: the first). */
|
|
35
|
+
initialFocus() {
|
|
36
|
+
return undefined;
|
|
37
|
+
}
|
|
38
|
+
/** The data has not arrived yet (the tab shows "Loading…"). */
|
|
39
|
+
get loading() {
|
|
40
|
+
return !this.loaded;
|
|
41
|
+
}
|
|
12
42
|
get capturing() {
|
|
13
43
|
return this.list?.isSearching ?? false;
|
|
14
44
|
}
|
|
15
|
-
/** The id of the open
|
|
45
|
+
/** The id of the open category, if the list has any. */
|
|
16
46
|
get category() {
|
|
17
47
|
return this.list?.currentCategory;
|
|
18
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
|
+
}
|
|
59
|
+
categories() {
|
|
60
|
+
return this.screen().categories;
|
|
61
|
+
}
|
|
62
|
+
async selectCategory(id) {
|
|
63
|
+
if (!this.loaded) {
|
|
64
|
+
this.wantedCategory = id;
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
this.screen().setCategory(id);
|
|
68
|
+
await this.afterKey();
|
|
69
|
+
}
|
|
70
|
+
setFocus(list) {
|
|
71
|
+
this.focused = list;
|
|
72
|
+
this.list?.setActive(list);
|
|
73
|
+
}
|
|
74
|
+
/** The list on screen, built when there is none yet. */
|
|
75
|
+
screen() {
|
|
76
|
+
return (this.list ??= this.build({}));
|
|
77
|
+
}
|
|
78
|
+
/** A list from the current data; its categories are shown by the menu's navigation. */
|
|
79
|
+
build(extra) {
|
|
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
|
+
});
|
|
89
|
+
list.setActive(this.focused);
|
|
90
|
+
return list;
|
|
91
|
+
}
|
|
19
92
|
/** The entries ticked in a multi-select list. */
|
|
20
93
|
ticked() {
|
|
21
94
|
return this.list?.ticked() ?? [];
|
|
22
95
|
}
|
|
96
|
+
/** Loads the data again; a slow load does not hold up the keys (the tab keeps what it showed, then updates). */
|
|
23
97
|
async open() {
|
|
24
|
-
await this.
|
|
25
|
-
|
|
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) {
|
|
148
|
+
const open = this.list?.currentCategory;
|
|
149
|
+
const item = wanted === undefined ? undefined : this.options().items.find((i) => i.value === wanted);
|
|
150
|
+
this.rebuild(item && (!open || !item.category || item.category === open) ? wanted : undefined);
|
|
151
|
+
}
|
|
152
|
+
openWantedCategory() {
|
|
153
|
+
if (!this.wantedCategory)
|
|
154
|
+
return;
|
|
155
|
+
this.list?.setCategory(this.wantedCategory);
|
|
156
|
+
this.wantedCategory = undefined;
|
|
26
157
|
}
|
|
27
158
|
/** Builds the list again, on `focus` when it is still there. */
|
|
28
159
|
rebuild(focus, notice) {
|
|
29
160
|
const startCategory = this.list?.currentCategory;
|
|
30
|
-
this.list =
|
|
161
|
+
this.list = this.build({ startAt: focus, startCategory, notice: notice ?? this.notice });
|
|
31
162
|
this.notice = undefined;
|
|
32
163
|
}
|
|
33
164
|
/** Shows `text` now, before slow work starts. */
|
|
@@ -40,21 +171,24 @@ export class ListPage {
|
|
|
40
171
|
this.notice = text;
|
|
41
172
|
}
|
|
42
173
|
render(size) {
|
|
43
|
-
this.
|
|
44
|
-
return this.list.render(size);
|
|
174
|
+
return this.screen().render(size);
|
|
45
175
|
}
|
|
46
176
|
async handle(key) {
|
|
47
|
-
|
|
48
|
-
const step = this.list.handle(key);
|
|
177
|
+
const step = this.screen().handle(key);
|
|
49
178
|
if (!step)
|
|
50
179
|
return this.afterKey();
|
|
51
180
|
const result = step.done;
|
|
52
181
|
const outcome = result.kind === 'back' ? { exit: { kind: 'quit' } } : await this.act(result);
|
|
53
182
|
if (outcome.exit)
|
|
54
183
|
return { done: outcome.exit };
|
|
55
|
-
|
|
56
|
-
|
|
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
|
+
}
|
|
57
190
|
const here = result.kind === 'pick' || result.kind === 'action' ? result.value : undefined;
|
|
191
|
+
this.lastFocus = outcome.focus ?? here ?? this.lastFocus;
|
|
58
192
|
this.rebuild(outcome.focus ?? here, outcome.notice);
|
|
59
193
|
return;
|
|
60
194
|
}
|