windows-development-sandbox 1.5.0 → 1.7.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 +17 -1
- package/dist/cli/args.d.ts +13 -2
- package/dist/cli/args.js +95 -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/index.d.ts +1 -0
- package/dist/cli/commands/index.js +1 -0
- 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 +57 -4
- package/dist/cli/commands/launch/prepare.js +3 -1
- 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.d.ts +1 -1
- package/dist/cli/commands/maintenance/config.js +112 -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/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 +7 -0
- 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/data.d.ts +2 -0
- package/dist/cli/commands/repair/checks/data.js +241 -0
- package/dist/cli/commands/repair/checks/index.d.ts +2 -0
- package/dist/cli/commands/repair/checks/index.js +20 -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 +55 -0
- package/dist/cli/commands/repair/checks/sandbox.d.ts +2 -0
- package/dist/cli/commands/repair/checks/sandbox.js +267 -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 +53 -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 +49 -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/list.js +5 -2
- package/dist/cli/commands/sessions/status.d.ts +2 -0
- package/dist/cli/commands/sessions/status.js +27 -6
- package/dist/cli/commands/setup/index.d.ts +5 -0
- package/dist/cli/commands/setup/index.js +25 -1
- 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 +85 -0
- package/dist/cli/commands/storage/storage.d.ts +8 -0
- package/dist/cli/commands/storage/storage.js +171 -0
- package/dist/cli/commands/user-config.js +1 -1
- package/dist/cli/commands/vpn.d.ts +4 -0
- package/dist/cli/commands/vpn.js +75 -0
- package/dist/cli/commands/web.d.ts +4 -0
- package/dist/cli/commands/web.js +95 -0
- package/dist/cli/history.js +1 -1
- package/dist/cli/index.js +46 -3
- package/dist/cli/manifest.d.ts +303 -29
- package/dist/cli/manifest.js +173 -43
- 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 +31 -2
- package/dist/cli/menu/apps.js +44 -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/menu.d.ts +1 -1
- package/dist/cli/menu/menu.js +11 -8
- package/dist/cli/menu/pages/accounts-page.js +55 -24
- package/dist/cli/menu/pages/agents-page.d.ts +66 -0
- package/dist/cli/menu/pages/agents-page.js +338 -0
- package/dist/cli/menu/pages/apps-page.js +1 -2
- package/dist/cli/menu/pages/list-page.d.ts +16 -3
- package/dist/cli/menu/pages/list-page.js +40 -8
- package/dist/cli/menu/pages/maintenance-page.d.ts +9 -0
- package/dist/cli/menu/pages/maintenance-page.js +161 -72
- package/dist/cli/menu/pages/sandbox-page.d.ts +3 -0
- package/dist/cli/menu/pages/sandbox-page.js +132 -43
- package/dist/cli/menu/pages/sessions-page.d.ts +4 -0
- package/dist/cli/menu/pages/sessions-page.js +41 -25
- package/dist/cli/menu/pages/settings-page.d.ts +8 -4
- package/dist/cli/menu/pages/settings-page.js +36 -13
- package/dist/cli/menu/settings/categories.d.ts +2 -0
- package/dist/cli/menu/settings/categories.js +19 -44
- package/dist/cli/menu/settings/collections/collection-editor.d.ts +7 -1
- 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 +11 -1
- package/dist/cli/menu/settings/collections/string-list-editor.js +23 -0
- package/dist/cli/menu/settings/index.d.ts +1 -1
- package/dist/cli/menu/settings/index.js +1 -1
- package/dist/cli/menu/settings/object-editor.d.ts +5 -1
- package/dist/cli/menu/settings/object-editor.js +15 -4
- package/dist/cli/menu/settings/path-kind.d.ts +20 -0
- package/dist/cli/menu/settings/path-kind.js +44 -0
- package/dist/cli/menu/settings/schema-node.d.ts +9 -0
- package/dist/cli/menu/settings/schema-node.js +26 -0
- package/dist/cli/menu/settings/value-editor.d.ts +5 -0
- package/dist/cli/menu/settings/value-editor.js +51 -18
- package/dist/cli/menu/several.js +7 -5
- package/dist/cli/menu/shell.d.ts +37 -10
- package/dist/cli/menu/shell.js +90 -10
- package/dist/cli/menu/vpn-login.d.ts +16 -0
- package/dist/cli/menu/vpn-login.js +66 -0
- package/dist/cli/output/print.d.ts +2 -0
- package/dist/cli/output/print.js +8 -1
- package/dist/cli/services/accounts-service.d.ts +2 -0
- package/dist/cli/services/accounts-service.js +2 -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/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 +6 -3
- package/dist/cli/tui/app.js +12 -5
- 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 +14 -2
- package/dist/cli/tui/list/list-screen.js +68 -32
- package/dist/cli/tui/list/list-types.d.ts +8 -4
- package/dist/cli/tui/nav.d.ts +29 -0
- package/dist/cli/tui/nav.js +67 -0
- 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 +5 -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 +23 -0
- package/dist/core/schema/config.js +10 -1
- package/dist/core/schema/harness.d.ts +1 -0
- package/dist/core/schema/harness.js +8 -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.js +1 -0
- package/dist/core/schema/vpn.d.ts +17 -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 +26 -0
- package/dist/guest/agents/agent-files.d.ts +49 -0
- package/dist/guest/agents/agent-files.js +63 -0
- package/dist/guest/agents/agent-installer.js +2 -9
- package/dist/guest/agents/local-state.d.ts +12 -0
- package/dist/guest/agents/local-state.js +198 -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 +50 -11
- package/dist/guest/daemon/daemon.js +4 -1
- package/dist/guest/daemon/exec.js +2 -1
- package/dist/guest/daemon/idle-shutdown.js +2 -0
- package/dist/guest/daemon/sessions.js +4 -1
- package/dist/guest/entries/agent.d.ts +1 -0
- package/dist/guest/entries/agent.js +10 -0
- package/dist/guest/entries/daemon.js +2 -0
- package/dist/guest/runtime/csc.d.ts +1 -0
- package/dist/guest/runtime/csc.js +1 -0
- package/dist/guest/runtime/secrets.d.ts +12 -0
- package/dist/guest/runtime/secrets.js +63 -0
- 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/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 +126 -0
- package/dist/host/channel/attach.d.ts +3 -1
- package/dist/host/channel/attach.js +1 -1
- package/dist/host/channel/channel.d.ts +7 -0
- package/dist/host/channel/channel.js +26 -2
- 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.js +25 -1
- package/dist/host/launch/session-file.js +4 -1
- package/dist/host/launch/stage.js +1 -1
- 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/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/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/platform.d.ts +2 -0
- package/dist/host/sandbox/platform.js +21 -2
- 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 +93 -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 +11 -2
- 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/history.d.ts +21 -0
- package/dist/host/storage/history.js +49 -0
- package/dist/host/storage/index.d.ts +4 -0
- package/dist/host/storage/index.js +4 -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/root.d.ts +18 -0
- package/dist/host/storage/root.js +77 -0
- package/dist/host/tools/windows-terminal.d.ts +2 -0
- package/dist/host/tools/windows-terminal.js +23 -5
- 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 +17 -0
- package/dist/host/vpn/prepare.js +77 -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 +1 -0
- package/dist/host/web/browser.js +10 -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 +9 -0
- package/dist/host/web/index.js +8 -0
- package/dist/host/web/runner.d.ts +14 -0
- package/dist/host/web/runner.js +45 -0
- package/dist/host/web/server.d.ts +40 -0
- package/dist/host/web/server.js +218 -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 +27614 -0
- package/dist/runtime/daemon.js +1012 -618
- package/dist/runtime/db.js +236 -106
- package/dist/runtime/main.js +1093 -250
- package/dist/runtime/netproxy.js +102 -3
- package/dist/runtime/view.js +102 -3
- 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 +115 -0
- package/dist/selftest/channel.test.js +5 -0
- package/dist/selftest/cli.test.js +34 -4
- package/dist/selftest/credentials.test.d.ts +2 -0
- package/dist/selftest/credentials.test.js +198 -0
- package/dist/selftest/generate.test.js +1 -1
- package/dist/selftest/health.test.d.ts +2 -0
- package/dist/selftest/health.test.js +470 -0
- package/dist/selftest/host-sim.test.js +2 -0
- package/dist/selftest/index.js +19 -0
- package/dist/selftest/layout.test.js +2 -0
- package/dist/selftest/menu-screens.d.ts +7 -0
- package/dist/selftest/menu-screens.js +65 -16
- package/dist/selftest/menu.test.js +574 -21
- 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/fixtures.d.ts +14 -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 +279 -0
- package/dist/selftest/web.test.d.ts +2 -0
- package/dist/selftest/web.test.js +304 -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 +6 -1
- package/dist/shared/channel/run-dir.js +12 -1
- package/dist/shared/channel/schema.d.ts +19 -0
- package/dist/shared/channel/schema.js +11 -0
- package/dist/shared/channel/secrets.d.ts +28 -0
- package/dist/shared/channel/secrets.js +44 -0
- package/dist/shared/vpn/download.d.ts +13 -0
- package/dist/shared/vpn/download.js +14 -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/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 +5 -1
- package/dist/sync/sync-state.d.ts +1 -0
- package/dist/sync/sync-state.js +1 -0
- package/dist/sync/watcher.js +10 -0
- package/dist/web/index.html +13 -0
- package/dist/web/main-CXESL347.js +45 -0
- package/dist/web/main-VLR7DVQ4.css +1 -0
- package/native/csharp/FolderSecurity.cs +29 -0
- package/native/scripts/protect-data.ps1 +29 -0
- package/native/scripts/read-folder-sddl.ps1 +10 -0
- package/native/scripts/set-folder-access.ps1 +49 -7
- 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 +15 -5
- package/sandbox/csharp/EnvBroadcast.cs +33 -0
- package/sandbox/csharp/PathSync.cs +90 -0
- package/sandbox/scripts/install-shell-path.ps1 +73 -0
- package/sandbox/scripts/set-machine-environment.ps1 +37 -4
- package/schemas/config.schema.json +79 -4
- package/schemas/sandbox-config.schema.json +14 -1
- package/dist/cli/commands/repair/checks.d.ts +0 -2
- package/dist/cli/commands/repair/checks.js +0 -246
- 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
|
@@ -1,10 +1,14 @@
|
|
|
1
|
-
//
|
|
1
|
+
// Section 6: saved logins for every agent. Agents on the left (each with its logins), actions on the right: save the
|
|
2
2
|
// sandbox's login or this PC's, use one, make one the default, rename, remove.
|
|
3
3
|
import { errMsg, safeText } from '../../../core/util/index.js';
|
|
4
4
|
import { AccountsService } from '../../services/index.js';
|
|
5
5
|
import { Theme } from '../../tui/index.js';
|
|
6
6
|
import { ListPage } from './list-page.js';
|
|
7
7
|
const NAME = /^[A-Za-z0-9_-]{1,40}$/;
|
|
8
|
+
const SAVE_SANDBOX = '@save-sandbox';
|
|
9
|
+
const SAVE_PC = '@save-pc';
|
|
10
|
+
/** A saved login (not a "save a login" row or a note). */
|
|
11
|
+
const isLogin = (id) => !id.startsWith('@') && !id.startsWith('info:');
|
|
8
12
|
/** The list for the accounts tab. Pure. */
|
|
9
13
|
export function accountsOptions(m) {
|
|
10
14
|
return {
|
|
@@ -19,6 +23,26 @@ export function accountsOptions(m) {
|
|
|
19
23
|
})),
|
|
20
24
|
items: m.agents.flatMap((a) => {
|
|
21
25
|
const rows = m.rows[a.name] ?? [];
|
|
26
|
+
const save = [
|
|
27
|
+
{
|
|
28
|
+
value: SAVE_SANDBOX,
|
|
29
|
+
label: "+ Save the sandbox's login…",
|
|
30
|
+
category: a.name,
|
|
31
|
+
section: 'Save a login',
|
|
32
|
+
description: 'Saves the ' + a.name + ' login you signed in with inside the sandbox, under a name you choose.',
|
|
33
|
+
},
|
|
34
|
+
...(a.canSavePc
|
|
35
|
+
? [
|
|
36
|
+
{
|
|
37
|
+
value: SAVE_PC,
|
|
38
|
+
label: "+ Save this PC's login…",
|
|
39
|
+
category: a.name,
|
|
40
|
+
section: 'Save a login',
|
|
41
|
+
description: 'Saves the ' + a.name + ' login of this PC, under a name you choose.',
|
|
42
|
+
},
|
|
43
|
+
]
|
|
44
|
+
: []),
|
|
45
|
+
];
|
|
22
46
|
if (!a.kept)
|
|
23
47
|
return [
|
|
24
48
|
{
|
|
@@ -28,25 +52,28 @@ export function accountsOptions(m) {
|
|
|
28
52
|
description: 'Sign in again in each new sandbox, or use an API key in the agent’s environment.',
|
|
29
53
|
},
|
|
30
54
|
];
|
|
31
|
-
return
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
55
|
+
return [
|
|
56
|
+
...save,
|
|
57
|
+
...rows.map((r) => ({
|
|
58
|
+
value: a.name + ':' + r.name,
|
|
59
|
+
label: r.name,
|
|
60
|
+
category: a.name,
|
|
61
|
+
section: 'Saved logins',
|
|
62
|
+
hint: (r.isActive ? Theme.ok('in the sandbox') : '') +
|
|
63
|
+
(r.isActive && r.isDefault ? Theme.muted(' · ') : '') +
|
|
64
|
+
(r.isDefault ? Theme.accent('default') : ''),
|
|
65
|
+
description: 'Enter makes the sandbox use this login.',
|
|
66
|
+
details: [
|
|
67
|
+
Theme.muted('Agent ') + a.name,
|
|
68
|
+
Theme.muted('Email ') + safeText(r.email ?? '-'),
|
|
69
|
+
Theme.muted('Saved ') + r.savedAt.slice(0, 16).replace('T', ' '),
|
|
70
|
+
],
|
|
71
|
+
})),
|
|
72
|
+
];
|
|
45
73
|
}),
|
|
46
|
-
empty:
|
|
74
|
+
empty: 'No agents.',
|
|
47
75
|
actions: accountActions(m.agents),
|
|
48
|
-
enterLabel: 'use',
|
|
49
|
-
escapeLabel: 'quit',
|
|
76
|
+
enterLabel: (_category, id) => (id === SAVE_SANDBOX || id === SAVE_PC ? 'save' : id && isLogin(id) ? 'use' : ''),
|
|
50
77
|
};
|
|
51
78
|
}
|
|
52
79
|
function accountActions(agents) {
|
|
@@ -55,11 +82,11 @@ function accountActions(agents) {
|
|
|
55
82
|
if (!agent?.kept)
|
|
56
83
|
return [];
|
|
57
84
|
return [
|
|
58
|
-
{ key: 's', label: 'save sandbox', importance:
|
|
59
|
-
...(agent.canSavePc ? [{ key: 'p', label: 'save PC', importance:
|
|
60
|
-
{ key: 'd', label: 'default', importance: 1 },
|
|
61
|
-
{ key: 'r', label: 'rename', importance: 2 },
|
|
62
|
-
{ key: 'x', label: 'remove', importance: 1 },
|
|
85
|
+
{ key: 's', label: 'save sandbox login', importance: 3 },
|
|
86
|
+
...(agent.canSavePc ? [{ key: 'p', label: 'save PC login', importance: 3 }] : []),
|
|
87
|
+
{ key: 'd', label: 'make default', importance: 1, applies: isLogin },
|
|
88
|
+
{ key: 'r', label: 'rename', importance: 2, applies: isLogin },
|
|
89
|
+
{ key: 'x', label: 'remove', importance: 1, applies: isLogin },
|
|
63
90
|
];
|
|
64
91
|
};
|
|
65
92
|
}
|
|
@@ -94,7 +121,7 @@ export class AccountsPage extends ListPage {
|
|
|
94
121
|
}
|
|
95
122
|
static nameOf(value) {
|
|
96
123
|
const i = value?.indexOf(':') ?? -1;
|
|
97
|
-
return value && i >= 0 &&
|
|
124
|
+
return value && i >= 0 && isLogin(value) ? value.slice(i + 1) : undefined;
|
|
98
125
|
}
|
|
99
126
|
async act(result) {
|
|
100
127
|
const agent = this.agentNow();
|
|
@@ -102,6 +129,8 @@ export class AccountsPage extends ListPage {
|
|
|
102
129
|
try {
|
|
103
130
|
if (result.kind === 'action' && (result.key === 's' || result.key === 'p'))
|
|
104
131
|
return await this.save(agent, result.key === 'p');
|
|
132
|
+
if (result.kind === 'pick' && (result.value === SAVE_SANDBOX || result.value === SAVE_PC))
|
|
133
|
+
return await this.save(agent, result.value === SAVE_PC);
|
|
105
134
|
if (result.kind === 'pick' && name)
|
|
106
135
|
return await this.use(agent, name);
|
|
107
136
|
if (result.kind === 'action' && name) {
|
|
@@ -154,6 +183,8 @@ export class AccountsPage extends ListPage {
|
|
|
154
183
|
async use(agent, name) {
|
|
155
184
|
const account = this.service.activate(name, agent);
|
|
156
185
|
let note = Theme.ok(Theme.glyph.ok + ' The sandbox now uses "' + account.name + '" for ' + agent + '.');
|
|
186
|
+
if (account.note)
|
|
187
|
+
note += ' ' + safeText(account.note);
|
|
157
188
|
if (this.service.hasRunningSessions(agent) &&
|
|
158
189
|
(await this.app.ask('Restart the running ' + agent + ' sessions?', ['They restart and continue their conversation where the agent can, now under the new login.'], 'Restart')))
|
|
159
190
|
note += ' ' + safeText(await this.service.restart(agent));
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type { Context } from '../../commands/context.js';
|
|
2
|
+
import { type App, type Category, type ListAction, type ListOptions, type ListResult } from '../../tui/index.js';
|
|
3
|
+
import type { ConfigFile } from '../settings/config-file.js';
|
|
4
|
+
import type { Draft } from '../settings/draft.js';
|
|
5
|
+
import { ListPage, type Outcome } from './list-page.js';
|
|
6
|
+
export type WindowChoice = 'config' | 'hide' | 'show';
|
|
7
|
+
export interface AgentsModel {
|
|
8
|
+
readonly folder: string;
|
|
9
|
+
readonly defaultAgent: string;
|
|
10
|
+
readonly agents: readonly {
|
|
11
|
+
readonly name: string;
|
|
12
|
+
readonly ready: boolean;
|
|
13
|
+
}[];
|
|
14
|
+
readonly last: string[] | undefined;
|
|
15
|
+
readonly attach: boolean;
|
|
16
|
+
readonly window: WindowChoice;
|
|
17
|
+
/** Agents that can be run on this PC without the sandbox (see hostAgentsToShow). */
|
|
18
|
+
readonly hostAgents: readonly string[];
|
|
19
|
+
/** The agents you added yourself: only these can be removed (the built-in ones stay). */
|
|
20
|
+
readonly removable?: readonly string[];
|
|
21
|
+
}
|
|
22
|
+
/** The agents of `harnesses` that are not built in. Pure. */
|
|
23
|
+
export declare function addedAgents(names: readonly string[]): string[];
|
|
24
|
+
/** The keys of the Start category: make an agent the default, remove one you added. Pure. */
|
|
25
|
+
export declare function agentActions(m: Pick<AgentsModel, 'defaultAgent' | 'removable'>): ListAction<string>[];
|
|
26
|
+
/**
|
|
27
|
+
* The "not sandboxed" entries: only while agent commands are on (typing the agent then starts the sandbox, so a way to
|
|
28
|
+
* run the real one is needed), one per agent found installed on this PC.
|
|
29
|
+
*/
|
|
30
|
+
export declare function hostAgentsToShow(enabled: boolean, found: readonly {
|
|
31
|
+
harness: string;
|
|
32
|
+
}[]): string[];
|
|
33
|
+
/** The command line a start stands for. Pure. */
|
|
34
|
+
export declare function startArgv(m: AgentsModel, agent: string, cwd: string): string[];
|
|
35
|
+
/** The categories of the agents section; "On this PC" only when there is something in it. Pure. */
|
|
36
|
+
export declare function agentCategories(m: Pick<AgentsModel, 'folder' | 'hostAgents'>): Category[];
|
|
37
|
+
/** The list for the agents section. Pure. */
|
|
38
|
+
export declare function agentsOptions(m: AgentsModel, cwd?: string): ListOptions<string>;
|
|
39
|
+
export declare class AgentsPage extends ListPage<string> {
|
|
40
|
+
private readonly ctx;
|
|
41
|
+
/** Your own config file and its unsaved changes: where "Add an agent" writes to. */
|
|
42
|
+
private readonly file;
|
|
43
|
+
private readonly draft;
|
|
44
|
+
readonly label = "Agents";
|
|
45
|
+
private attach;
|
|
46
|
+
private window;
|
|
47
|
+
private folder;
|
|
48
|
+
private model;
|
|
49
|
+
constructor(app: App, ctx: Context,
|
|
50
|
+
/** Your own config file and its unsaved changes: where "Add an agent" writes to. */
|
|
51
|
+
file: ConfigFile, draft: Draft);
|
|
52
|
+
/** Every agent: the configured ones, and any added in Settings that is not saved yet. */
|
|
53
|
+
private harnesses;
|
|
54
|
+
/** Is this agent already in the sandbox's persistent storage (so starting it needs no install)? */
|
|
55
|
+
private installed;
|
|
56
|
+
private current;
|
|
57
|
+
/** The cursor starts on the default agent. */
|
|
58
|
+
protected initialFocus(): string;
|
|
59
|
+
protected load(): Promise<void>;
|
|
60
|
+
protected options(): ListOptions<string>;
|
|
61
|
+
protected act(result: ListResult<string>): Promise<Outcome<string>>;
|
|
62
|
+
/** Make default (d) and Remove (x) on the highlighted agent. */
|
|
63
|
+
private action;
|
|
64
|
+
/** "Add an agent…": the new agent shows in the list, with the cursor on it. */
|
|
65
|
+
private add;
|
|
66
|
+
}
|
|
@@ -0,0 +1,338 @@
|
|
|
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/path-kind.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
|
+
constructor(app, ctx,
|
|
199
|
+
/** Your own config file and its unsaved changes: where "Add an agent" writes to. */
|
|
200
|
+
file, draft) {
|
|
201
|
+
super(app);
|
|
202
|
+
this.ctx = ctx;
|
|
203
|
+
this.file = file;
|
|
204
|
+
this.draft = draft;
|
|
205
|
+
}
|
|
206
|
+
/** Every agent: the configured ones, and any added in Settings that is not saved yet. */
|
|
207
|
+
harnesses() {
|
|
208
|
+
const config = this.file.userConfig();
|
|
209
|
+
const staged = this.draft.has(this.file, ['harnesses'])
|
|
210
|
+
? this.draft.value(this.file, ['harnesses'])
|
|
211
|
+
: undefined;
|
|
212
|
+
return { ...config.harnesses, ...staged };
|
|
213
|
+
}
|
|
214
|
+
/** Is this agent already in the sandbox's persistent storage (so starting it needs no install)? */
|
|
215
|
+
installed(name, harnesses) {
|
|
216
|
+
const h = harnesses[name];
|
|
217
|
+
const dir = path.join(this.ctx.dataPath, 'tools', 'agents', name);
|
|
218
|
+
return (Boolean(h) &&
|
|
219
|
+
[h.hostExecutable, h.npmBin && h.npmBin + '.cmd', h.uvBin && h.uvBin + '.exe'].some((f) => f && fs.existsSync(path.join(dir, f))));
|
|
220
|
+
}
|
|
221
|
+
current() {
|
|
222
|
+
const harnesses = this.harnesses();
|
|
223
|
+
const commands = new AgentCommandsService(this.ctx).status();
|
|
224
|
+
return {
|
|
225
|
+
folder: this.folder,
|
|
226
|
+
defaultAgent: this.file.userConfig().defaultHarness,
|
|
227
|
+
agents: Object.keys(harnesses).map((name) => ({ name, ready: this.installed(name, harnesses) })),
|
|
228
|
+
last: readHistory()[0]?.argv,
|
|
229
|
+
attach: this.attach,
|
|
230
|
+
window: this.window,
|
|
231
|
+
hostAgents: hostAgentsToShow(commands.enabled, commands.found),
|
|
232
|
+
removable: addedAgents(Object.keys(harnesses)),
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
/** The cursor starts on the default agent. */
|
|
236
|
+
initialFocus() {
|
|
237
|
+
return 'agent:' + this.file.userConfig().defaultHarness;
|
|
238
|
+
}
|
|
239
|
+
load() {
|
|
240
|
+
this.model = this.current();
|
|
241
|
+
return Promise.resolve();
|
|
242
|
+
}
|
|
243
|
+
options() {
|
|
244
|
+
this.model = this.current();
|
|
245
|
+
return agentsOptions(this.model);
|
|
246
|
+
}
|
|
247
|
+
async act(result) {
|
|
248
|
+
if (result.kind === 'action')
|
|
249
|
+
return this.action(result.key, result.value);
|
|
250
|
+
if (result.kind !== 'pick')
|
|
251
|
+
return {};
|
|
252
|
+
const id = result.value;
|
|
253
|
+
const model = this.current();
|
|
254
|
+
if (id.startsWith('host:'))
|
|
255
|
+
return { exit: { kind: 'run', argv: ['host', id.slice(5)] } };
|
|
256
|
+
if (id.startsWith('agent:'))
|
|
257
|
+
return { exit: { kind: 'run', argv: startArgv(model, id.slice(6), process.cwd()) } };
|
|
258
|
+
switch (id) {
|
|
259
|
+
case 'repeat':
|
|
260
|
+
return model.last ? { exit: { kind: 'run', argv: model.last } } : {};
|
|
261
|
+
case 'add':
|
|
262
|
+
return this.add(model);
|
|
263
|
+
case 'opt:attach':
|
|
264
|
+
this.attach = !this.attach;
|
|
265
|
+
return {};
|
|
266
|
+
case 'opt:window':
|
|
267
|
+
this.window = this.window === 'config' ? 'hide' : this.window === 'hide' ? 'show' : 'config';
|
|
268
|
+
return {};
|
|
269
|
+
case 'opt:folder': {
|
|
270
|
+
const picked = await askPath(this.app, {
|
|
271
|
+
path: ['Agents', 'Folder'],
|
|
272
|
+
title: 'Choose the project folder',
|
|
273
|
+
kind: 'dir',
|
|
274
|
+
initial: this.folder,
|
|
275
|
+
validate: (v) => (fs.existsSync(path.resolve(v)) ? true : 'That folder does not exist.'),
|
|
276
|
+
});
|
|
277
|
+
if (picked)
|
|
278
|
+
this.folder = path.resolve(picked);
|
|
279
|
+
return {};
|
|
280
|
+
}
|
|
281
|
+
case 'more': {
|
|
282
|
+
const argv = await new CommandForm(this.app, this.ctx, commandSpec('launch'), startArgv(model, model.defaultAgent, process.cwd()).slice(1)).run();
|
|
283
|
+
return argv ? { exit: { kind: 'run', argv } } : {};
|
|
284
|
+
}
|
|
285
|
+
case 'several': {
|
|
286
|
+
const argv = await new SeveralAgents(this.app, this.ctx).run();
|
|
287
|
+
return argv ? { exit: { kind: 'run', argv } } : {};
|
|
288
|
+
}
|
|
289
|
+
case 'noagent': {
|
|
290
|
+
const argv = await new CommandForm(this.app, this.ctx, commandSpec('start')).run();
|
|
291
|
+
return argv ? { exit: { kind: 'run', argv } } : {};
|
|
292
|
+
}
|
|
293
|
+
default:
|
|
294
|
+
return {};
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
/** Make default (d) and Remove (x) on the highlighted agent. */
|
|
298
|
+
async action(key, id) {
|
|
299
|
+
const name = id?.startsWith('agent:') ? id.slice(6) : undefined;
|
|
300
|
+
if (!name)
|
|
301
|
+
return {};
|
|
302
|
+
try {
|
|
303
|
+
if (key === 'd') {
|
|
304
|
+
makeDefaultAgent(this.file, this.draft, name);
|
|
305
|
+
return { focus: id, notice: Theme.ok(Theme.glyph.ok + ' ' + name + ' is the default agent.') };
|
|
306
|
+
}
|
|
307
|
+
if (key !== 'x')
|
|
308
|
+
return {};
|
|
309
|
+
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);
|
|
310
|
+
if (!ok)
|
|
311
|
+
return {};
|
|
312
|
+
removeAgent(this.file, this.draft, name);
|
|
313
|
+
return {
|
|
314
|
+
focus: 'agent:' + this.file.userConfig().defaultHarness,
|
|
315
|
+
notice: Theme.ok(Theme.glyph.ok + ' Removed ' + name + '.'),
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
catch (e) {
|
|
319
|
+
return { notice: Theme.error(Theme.glyph.cross + ' ' + errMsg(e)) };
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
/** "Add an agent…": the new agent shows in the list, with the cursor on it. */
|
|
323
|
+
async add(model) {
|
|
324
|
+
try {
|
|
325
|
+
const added = await new AddAgent(this.app, this.file, this.draft, model.agents.map((a) => a.name)).run();
|
|
326
|
+
if (!added)
|
|
327
|
+
return {};
|
|
328
|
+
return {
|
|
329
|
+
focus: 'agent:' + added.name,
|
|
330
|
+
notice: Theme.ok(Theme.glyph.ok + ' Added ' + added.name + '.') +
|
|
331
|
+
Theme.muted(added.saved ? ' Enter starts it.' : ' Ctrl+S saves it.'),
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
catch (e) {
|
|
335
|
+
return { notice: Theme.error(Theme.glyph.cross + ' ' + errMsg(e)) };
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
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';
|
|
@@ -18,7 +18,6 @@ export function appsOptions(model, file, draft, scope) {
|
|
|
18
18
|
categories: model.categories(),
|
|
19
19
|
items: model.items(draft),
|
|
20
20
|
actions: file.isProject ? [] : [{ key: 'c', label: 'your own programs' }],
|
|
21
|
-
escapeLabel: 'quit',
|
|
22
21
|
};
|
|
23
22
|
}
|
|
24
23
|
export class AppsPage extends ListPage {
|
|
@@ -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,16 +16,29 @@ 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;
|
|
19
23
|
constructor(app: App);
|
|
20
24
|
/** Loads the data the list shows (called when the tab opens and after actions that change it). */
|
|
21
25
|
protected abstract load(): Promise<void>;
|
|
22
26
|
/** The list for the data loaded (pure: no I/O). */
|
|
23
27
|
protected abstract options(): ListOptions<T>;
|
|
28
|
+
/** The entry the cursor starts on the first time the section opens (default: the first). */
|
|
29
|
+
protected initialFocus(): T | undefined;
|
|
24
30
|
/** Does what the list returned. */
|
|
25
31
|
protected abstract act(result: ListResult<T>): Promise<Outcome<T>>;
|
|
26
32
|
get capturing(): boolean;
|
|
27
|
-
/** The id of the open
|
|
28
|
-
|
|
33
|
+
/** The id of the open category, if the list has any. */
|
|
34
|
+
get category(): string | undefined;
|
|
35
|
+
categories(): readonly Category[];
|
|
36
|
+
selectCategory(id: string): Promise<void>;
|
|
37
|
+
setFocus(list: boolean): void;
|
|
38
|
+
/** The list on screen, built when there is none yet. */
|
|
39
|
+
private screen;
|
|
40
|
+
/** A list from the current data; its categories are shown by the menu's navigation. */
|
|
41
|
+
private build;
|
|
29
42
|
/** The entries ticked in a multi-select list. */
|
|
30
43
|
protected ticked(): T[];
|
|
31
44
|
open(): Promise<void>;
|