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,9 +1,13 @@
|
|
|
1
1
|
import { Text } from '../text.js';
|
|
2
2
|
import { Theme } from '../theme.js';
|
|
3
|
+
/** Lists longer than this say how to search. */
|
|
4
|
+
const LONG_LIST = 12;
|
|
3
5
|
export class ListScreen {
|
|
4
6
|
o;
|
|
5
7
|
category = 0;
|
|
6
8
|
focus = 'list';
|
|
9
|
+
/** The list has the keyboard (false while the menu's navigation has it): the highlight is drawn softer. */
|
|
10
|
+
active = true;
|
|
7
11
|
cursor = 0;
|
|
8
12
|
offset = 0;
|
|
9
13
|
query = '';
|
|
@@ -57,7 +61,7 @@ export class ListScreen {
|
|
|
57
61
|
render(size) {
|
|
58
62
|
const visible = this.visible();
|
|
59
63
|
this.cursor = Math.min(this.cursor, Math.max(0, visible.length - 1));
|
|
60
|
-
const sideWidth = this.o.categories
|
|
64
|
+
const sideWidth = this.o.categories && !this.external
|
|
61
65
|
? Math.min(32, Math.max(...this.o.categories.map((c) => Text.width(c.label))) + 7)
|
|
62
66
|
: 0;
|
|
63
67
|
const rest = size.width - 1 - (sideWidth ? sideWidth + 3 : 0);
|
|
@@ -65,14 +69,16 @@ export class ListScreen {
|
|
|
65
69
|
const detailsWidth = detailsRight ? Math.min(52, Math.floor(rest * 0.38)) : rest;
|
|
66
70
|
const listWidth = detailsRight ? rest - detailsWidth - 3 : rest;
|
|
67
71
|
const top = [];
|
|
68
|
-
if (this.o.tabs)
|
|
69
|
-
|
|
72
|
+
if (this.o.tabs) {
|
|
73
|
+
const row = ' ' +
|
|
70
74
|
this.o.tabs.items
|
|
71
75
|
.map((tab, i) => i === this.o.tabs.active
|
|
72
76
|
? tab.paint(' ' + tab.badge + ' ' + tab.label + ' ')
|
|
73
77
|
: Theme.muted(' ' + tab.label + ' '))
|
|
74
78
|
.join(' ') +
|
|
75
|
-
Theme.muted(' tab switches')
|
|
79
|
+
Theme.muted(' tab switches');
|
|
80
|
+
top.push(Text.truncate(row, size.width - 1), '');
|
|
81
|
+
}
|
|
76
82
|
const intro = typeof this.o.intro === 'string' ? [this.o.intro] : (this.o.intro ?? []);
|
|
77
83
|
for (const line of intro)
|
|
78
84
|
top.push(...Text.wrap(line, size.width - 3).map((l) => ' ' + Theme.muted(l)));
|
|
@@ -113,9 +119,10 @@ export class ListScreen {
|
|
|
113
119
|
listLines.push(Theme.muted(' ' +
|
|
114
120
|
(above > 0 ? '▲ ' + above + ' above' : '') +
|
|
115
121
|
(above > 0 && below > 0 ? ' ' : '') +
|
|
116
|
-
(below > 0 ? '▼ ' + below + ' more' : '')
|
|
122
|
+
(below > 0 ? '▼ ' + below + ' more' : '') +
|
|
123
|
+
(this.searching || this.query ? '' : ' / search')));
|
|
117
124
|
}
|
|
118
|
-
const sideLines = this.sideLines(sideWidth);
|
|
125
|
+
const sideLines = sideWidth ? this.sideLines(sideWidth) : [];
|
|
119
126
|
const body = [...top];
|
|
120
127
|
const height = Math.max(listLines.length, detailsRight ? details.length : 0, sideLines.length);
|
|
121
128
|
for (let i = 0; i < Math.min(height, size.height - top.length); i++) {
|
|
@@ -156,7 +163,9 @@ export class ListScreen {
|
|
|
156
163
|
' ';
|
|
157
164
|
if (!selected)
|
|
158
165
|
return ' ' + line;
|
|
159
|
-
return this.focus === 'list'
|
|
166
|
+
return this.focus === 'list' && this.active
|
|
167
|
+
? ' ' + Theme.selected(Text.strip(line))
|
|
168
|
+
: ' ' + Theme.accent(Text.strip(line));
|
|
160
169
|
}
|
|
161
170
|
sideLines(width) {
|
|
162
171
|
if (!this.o.categories)
|
|
@@ -199,12 +208,14 @@ export class ListScreen {
|
|
|
199
208
|
if (this.searching)
|
|
200
209
|
return [
|
|
201
210
|
['type', 'to search', 1],
|
|
202
|
-
['↵', this.o.multi ? 'done' : (this.
|
|
211
|
+
['↵', this.o.multi ? 'done' : this.enterLabel(this.valueAt(this.visible()[this.cursor])), 1],
|
|
203
212
|
['esc', 'clear search', 0],
|
|
204
213
|
['↑↓', 'move', 4],
|
|
205
214
|
];
|
|
206
215
|
const current = this.visible()[this.cursor];
|
|
216
|
+
const value = current === undefined ? undefined : this.o.items[current].value;
|
|
207
217
|
const flips = current !== undefined && this.o.items[current].flip;
|
|
218
|
+
const long = this.o.items.length > LONG_LIST;
|
|
208
219
|
return [
|
|
209
220
|
...(this.o.multi
|
|
210
221
|
? [
|
|
@@ -212,16 +223,19 @@ export class ListScreen {
|
|
|
212
223
|
...(this.o.enterTicks ? [] : [['↵', 'done', 1]]),
|
|
213
224
|
['a', 'tick all shown', 6],
|
|
214
225
|
]
|
|
215
|
-
: [
|
|
216
|
-
|
|
226
|
+
: [
|
|
227
|
+
...(this.enterLabel(value) ? [['↵', this.enterLabel(value), 1]] : []),
|
|
228
|
+
...(flips ? [['space', 'flip', 1]] : []),
|
|
229
|
+
]),
|
|
230
|
+
...this.actionsNow(value).map((a) => [
|
|
217
231
|
a.ctrl ? 'ctrl+' + a.key : a.key,
|
|
218
232
|
a.label,
|
|
219
233
|
a.ctrl ? 0 : (a.importance ?? 2),
|
|
220
234
|
]),
|
|
221
235
|
...(this.o.tabs ? [['tab', 'scope', 3]] : []),
|
|
222
|
-
...(this.o.categories ? [['←→', 'categories', 3]] : []),
|
|
236
|
+
...(this.o.categories && !this.external ? [['←→', 'categories', 3]] : []),
|
|
223
237
|
['↑↓', 'move', 5],
|
|
224
|
-
['/', 'search', 6],
|
|
238
|
+
['/', 'search', long ? 3 : 6],
|
|
225
239
|
['esc', this.o.escapeLabel ?? 'back', 0],
|
|
226
240
|
];
|
|
227
241
|
}
|
|
@@ -229,14 +243,45 @@ export class ListScreen {
|
|
|
229
243
|
setNotice(text) {
|
|
230
244
|
this.notice = text;
|
|
231
245
|
}
|
|
246
|
+
/** The categories are shown by the menu's navigation, which drives them (no sidebar of its own). */
|
|
247
|
+
get external() {
|
|
248
|
+
return this.o.categoryNav === 'external';
|
|
249
|
+
}
|
|
250
|
+
enterLabel(value) {
|
|
251
|
+
const label = this.o.enterLabel;
|
|
252
|
+
return (typeof label === 'function' ? label(this.currentCategory, value) : label) ?? 'open';
|
|
253
|
+
}
|
|
254
|
+
valueAt(index) {
|
|
255
|
+
return index === undefined ? undefined : this.o.items[index].value;
|
|
256
|
+
}
|
|
257
|
+
/** The categories of the list (empty without any). */
|
|
258
|
+
get categories() {
|
|
259
|
+
return this.o.categories ?? [];
|
|
260
|
+
}
|
|
261
|
+
/** Opens a category (the menu's navigation does this); a search in progress ends. */
|
|
262
|
+
setCategory(id) {
|
|
263
|
+
const index = this.categories.findIndex((c) => c.id === id);
|
|
264
|
+
if (index < 0 || index === this.category)
|
|
265
|
+
return;
|
|
266
|
+
this.category = index;
|
|
267
|
+
this.query = '';
|
|
268
|
+
this.searching = false;
|
|
269
|
+
this.cursor = 0;
|
|
270
|
+
this.offset = 0;
|
|
271
|
+
}
|
|
272
|
+
/** Whether the list has the keyboard (the highlight is drawn softer when it has not). */
|
|
273
|
+
setActive(on) {
|
|
274
|
+
this.active = on;
|
|
275
|
+
}
|
|
232
276
|
/** The id of the category open in the sidebar (undefined without a sidebar). */
|
|
233
277
|
get currentCategory() {
|
|
234
278
|
return this.o.categories?.[this.category]?.id;
|
|
235
279
|
}
|
|
236
|
-
/** The extra keys that work now (they may depend on the category). */
|
|
237
|
-
actionsNow() {
|
|
280
|
+
/** The extra keys that work now (they may depend on the category and on the highlighted entry). */
|
|
281
|
+
actionsNow(value) {
|
|
238
282
|
const actions = this.o.actions;
|
|
239
|
-
|
|
283
|
+
const all = typeof actions === 'function' ? actions(this.currentCategory) : (actions ?? []);
|
|
284
|
+
return all.filter((a) => !a.applies || (value !== undefined && a.applies(value)));
|
|
240
285
|
}
|
|
241
286
|
/** Keys are going into the search box (digits and letters are text, not shortcuts). */
|
|
242
287
|
get isSearching() {
|
|
@@ -250,15 +295,10 @@ export class ListScreen {
|
|
|
250
295
|
const visible = this.visible();
|
|
251
296
|
const current = visible[this.cursor];
|
|
252
297
|
this.notice = undefined;
|
|
253
|
-
const
|
|
298
|
+
const value = this.valueAt(current);
|
|
299
|
+
const ctrlAction = key.ctrl ? this.actionsNow(value).find((a) => a.ctrl && a.key === key.name) : undefined;
|
|
254
300
|
if (ctrlAction)
|
|
255
|
-
return {
|
|
256
|
-
done: {
|
|
257
|
-
kind: 'action',
|
|
258
|
-
key: 'ctrl+' + ctrlAction.key,
|
|
259
|
-
value: current === undefined ? undefined : this.o.items[current].value,
|
|
260
|
-
},
|
|
261
|
-
};
|
|
301
|
+
return { done: { kind: 'action', key: 'ctrl+' + ctrlAction.key, value } };
|
|
262
302
|
const move = (by) => {
|
|
263
303
|
this.cursor = Math.max(0, Math.min(visible.length - 1, this.cursor + by));
|
|
264
304
|
};
|
|
@@ -318,7 +358,9 @@ export class ListScreen {
|
|
|
318
358
|
const n = this.o.tabs.items.length;
|
|
319
359
|
return { done: { kind: 'tab', index: (this.o.tabs.active + (key.shift ? n - 1 : 1)) % n } };
|
|
320
360
|
}
|
|
321
|
-
if (this.
|
|
361
|
+
if (this.external && !this.query && !this.searching && key.name === 'left')
|
|
362
|
+
return { done: { kind: 'back' } };
|
|
363
|
+
if (this.o.categories && !this.external && !this.query) {
|
|
322
364
|
if (key.name === 'left' && this.focus === 'list') {
|
|
323
365
|
this.focus = 'side';
|
|
324
366
|
return;
|
|
@@ -370,15 +412,9 @@ export class ListScreen {
|
|
|
370
412
|
}
|
|
371
413
|
return { done: { kind: 'pick', value: it.value } };
|
|
372
414
|
}
|
|
373
|
-
const action = !this.searching && key.text ? this.actionsNow().find((a) => !a.ctrl && a.key === key.text) : undefined;
|
|
415
|
+
const action = !this.searching && key.text ? this.actionsNow(value).find((a) => !a.ctrl && a.key === key.text) : undefined;
|
|
374
416
|
if (action)
|
|
375
|
-
return {
|
|
376
|
-
done: {
|
|
377
|
-
kind: 'action',
|
|
378
|
-
key: action.key,
|
|
379
|
-
value: current === undefined ? undefined : this.o.items[current].value,
|
|
380
|
-
},
|
|
381
|
-
};
|
|
417
|
+
return { done: { kind: 'action', key: action.key, value } };
|
|
382
418
|
return;
|
|
383
419
|
}
|
|
384
420
|
toggle(index) {
|
|
@@ -26,9 +26,11 @@ export interface Category {
|
|
|
26
26
|
label: string;
|
|
27
27
|
description?: string;
|
|
28
28
|
}
|
|
29
|
-
export interface ListAction {
|
|
29
|
+
export interface ListAction<T = unknown> {
|
|
30
30
|
key: string;
|
|
31
31
|
label: string;
|
|
32
|
+
/** Only while an entry this accepts is highlighted: the key bar and the key itself ignore it otherwise. */
|
|
33
|
+
applies?: (value: T) => boolean;
|
|
32
34
|
/** Pressed with Ctrl (ctrl+s ...); works while searching too. */
|
|
33
35
|
ctrl?: boolean;
|
|
34
36
|
/** How long it survives in a narrow footer: 0 never goes, bigger goes earlier (default 2). */
|
|
@@ -70,7 +72,7 @@ export interface ListOptions<T> {
|
|
|
70
72
|
startAt?: T;
|
|
71
73
|
startCategory?: string;
|
|
72
74
|
/** Extra keys; a function picks them by the open category. */
|
|
73
|
-
actions?: ListAction[] | ((category: string | undefined) => ListAction[]);
|
|
75
|
+
actions?: ListAction<T>[] | ((category: string | undefined) => ListAction<T>[]);
|
|
74
76
|
notice?: string;
|
|
75
77
|
empty?: string;
|
|
76
78
|
tabs?: {
|
|
@@ -79,6 +81,8 @@ export interface ListOptions<T> {
|
|
|
79
81
|
};
|
|
80
82
|
/** What Esc does, for the footer ("back", "quit"). */
|
|
81
83
|
escapeLabel?: string;
|
|
82
|
-
/** What Enter does, for the footer ("open", "edit", "start"). */
|
|
83
|
-
enterLabel?: string;
|
|
84
|
+
/** What Enter does, for the footer ("open", "edit", "start"); a function picks it by entry ("": none). */
|
|
85
|
+
enterLabel?: string | ((category: string | undefined, value: T | undefined) => string);
|
|
86
|
+
/** Where the categories are listed: in a sidebar of the list itself (default) or in the menu's own navigation. */
|
|
87
|
+
categoryNav?: 'own' | 'external';
|
|
84
88
|
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export interface NavCategory {
|
|
2
|
+
readonly label: string;
|
|
3
|
+
/** The category open in the list. */
|
|
4
|
+
readonly current: boolean;
|
|
5
|
+
}
|
|
6
|
+
export interface NavSection {
|
|
7
|
+
readonly label: string;
|
|
8
|
+
/** Something is waiting in this section (unsaved changes). */
|
|
9
|
+
readonly marked?: boolean;
|
|
10
|
+
/** The categories of the open section (other sections are drawn without theirs). */
|
|
11
|
+
readonly categories: readonly NavCategory[];
|
|
12
|
+
}
|
|
13
|
+
export interface NavState {
|
|
14
|
+
readonly sections: readonly NavSection[];
|
|
15
|
+
/** Index of the open section. */
|
|
16
|
+
readonly active: number;
|
|
17
|
+
/** The navigation has the keyboard (else the list has it). */
|
|
18
|
+
readonly focused: boolean;
|
|
19
|
+
/** A dialog or sub-screen is shown over the menu: everything is drawn grey. */
|
|
20
|
+
readonly dimmed?: boolean;
|
|
21
|
+
}
|
|
22
|
+
export declare class SideNav {
|
|
23
|
+
/** Columns the navigation takes on a terminal `termWidth` columns wide (without the divider). */
|
|
24
|
+
static width(termWidth: number): number;
|
|
25
|
+
/** Exactly `height` lines, each `SideNav.width(termWidth)` columns wide. */
|
|
26
|
+
static render(nav: NavState, termWidth: number, height: number): string[];
|
|
27
|
+
private static section;
|
|
28
|
+
private static category;
|
|
29
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
// The navigation on the left of every menu screen: the sections as a tree (the open one shows its categories), with
|
|
2
|
+
// the way you are standing marked. Narrow terminals get a slim column of numbers instead of names. Pure (tested).
|
|
3
|
+
import { Text } from './text.js';
|
|
4
|
+
import { Theme } from './theme.js';
|
|
5
|
+
/** Terminals narrower than this get the slim column. */
|
|
6
|
+
const SLIM_BELOW = 80;
|
|
7
|
+
const SLIM_WIDTH = 5;
|
|
8
|
+
export class SideNav {
|
|
9
|
+
/** Columns the navigation takes on a terminal `termWidth` columns wide (without the divider). */
|
|
10
|
+
static width(termWidth) {
|
|
11
|
+
if (termWidth < SLIM_BELOW)
|
|
12
|
+
return SLIM_WIDTH;
|
|
13
|
+
return termWidth >= 130 ? 28 : 24;
|
|
14
|
+
}
|
|
15
|
+
/** Exactly `height` lines, each `SideNav.width(termWidth)` columns wide. */
|
|
16
|
+
static render(nav, termWidth, height) {
|
|
17
|
+
const width = SideNav.width(termWidth);
|
|
18
|
+
const slim = width === SLIM_WIDTH;
|
|
19
|
+
const lines = [];
|
|
20
|
+
nav.sections.forEach((section, i) => {
|
|
21
|
+
const open = i === nav.active;
|
|
22
|
+
const hasCategories = open && section.categories.length > 0;
|
|
23
|
+
const standing = open && !hasCategories;
|
|
24
|
+
lines.push({ text: SideNav.section(nav, section, i, width, slim, standing), stop: standing });
|
|
25
|
+
if (!hasCategories)
|
|
26
|
+
return;
|
|
27
|
+
section.categories.forEach((cat, c) => {
|
|
28
|
+
const last = c === section.categories.length - 1;
|
|
29
|
+
lines.push({ text: SideNav.category(nav, cat, last, width, slim), stop: cat.current });
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
const at = Math.max(0, lines.findIndex((l) => l.stop));
|
|
33
|
+
const start = lines.length > height ? Math.min(Math.max(0, at - Math.floor(height / 2)), lines.length - height) : 0;
|
|
34
|
+
const shown = lines.slice(start, start + height).map((l) => l.text);
|
|
35
|
+
while (shown.length < height)
|
|
36
|
+
shown.push(' '.repeat(width));
|
|
37
|
+
return shown;
|
|
38
|
+
}
|
|
39
|
+
static section(nav, section, index, width, slim, standing) {
|
|
40
|
+
const open = index === nav.active;
|
|
41
|
+
const live = !nav.dimmed;
|
|
42
|
+
// The open section has a marker, so it shows without colour.
|
|
43
|
+
const lead = open ? (section.categories.length ? '▾' : Theme.glyph.pointer) : ' ';
|
|
44
|
+
const mark = section.marked ? Theme.changed(Theme.glyph.changed) : ' ';
|
|
45
|
+
const inner = slim
|
|
46
|
+
? lead + (index + 1) + mark + ' '
|
|
47
|
+
: Text.fit(lead + (index + 1) + ' ' + (open && live ? Theme.bold(section.label) : section.label), width - 3) +
|
|
48
|
+
' ' +
|
|
49
|
+
mark +
|
|
50
|
+
' ';
|
|
51
|
+
if (standing && live && nav.focused)
|
|
52
|
+
return Theme.selected(Text.fit(inner, width));
|
|
53
|
+
if (!live || !open)
|
|
54
|
+
return Theme.muted(Text.fit(inner, width));
|
|
55
|
+
return nav.focused ? Text.fit(inner, width) : Theme.accent(Text.fit(inner, width));
|
|
56
|
+
}
|
|
57
|
+
static category(nav, cat, last, width, slim) {
|
|
58
|
+
const live = !nav.dimmed;
|
|
59
|
+
const plain = slim
|
|
60
|
+
? ' ' + (cat.current ? Theme.glyph.on : Theme.glyph.dot) + ' '
|
|
61
|
+
: ' ' + (cat.current ? Theme.glyph.pointer : last ? '└' : '├') + ' ' + cat.label;
|
|
62
|
+
const line = Text.fit(plain, width);
|
|
63
|
+
if (!cat.current || !live)
|
|
64
|
+
return Theme.muted(line);
|
|
65
|
+
return nav.focused ? Theme.selected(line) : Theme.accentBold(line);
|
|
66
|
+
}
|
|
67
|
+
}
|
package/dist/cli/validate.d.ts
CHANGED
|
@@ -12,6 +12,6 @@ export declare function validPythonSpec(spec: string): boolean;
|
|
|
12
12
|
export declare function checkHarness(name: string | undefined, harnesses: string[]): void;
|
|
13
13
|
export declare const PROJECT_ACTIONS: readonly ["list", "choose", "add", "remove", "include", "exclude", "all", "roots"];
|
|
14
14
|
/** `sandbox projects <action> [value] [folder]`: the action, then what it needs. Pure (no file checks). */
|
|
15
|
-
export declare function validateProjectsArgs(args: string[]): void;
|
|
15
|
+
export declare function validateProjectsArgs(args: string[], canAsk?: boolean): void;
|
|
16
16
|
/** Fails with what is wrong and what is valid, before anything is started. */
|
|
17
17
|
export declare function validateOptions(ctx: Context): void;
|
package/dist/cli/validate.js
CHANGED
|
@@ -44,11 +44,11 @@ export function checkHarness(name, harnesses) {
|
|
|
44
44
|
const LAUNCHING = new Set(['launch', 'generate', 'host-claude']);
|
|
45
45
|
export const PROJECT_ACTIONS = ['list', 'choose', 'add', 'remove', 'include', 'exclude', 'all', 'roots'];
|
|
46
46
|
/** `sandbox projects <action> [value] [folder]`: the action, then what it needs. Pure (no file checks). */
|
|
47
|
-
export function validateProjectsArgs(args) {
|
|
47
|
+
export function validateProjectsArgs(args, canAsk = false) {
|
|
48
48
|
const [action = 'list', value, folder] = args;
|
|
49
49
|
if (!PROJECT_ACTIONS.includes(action))
|
|
50
50
|
unknownValue('projects action', action, PROJECT_ACTIONS, 'sandbox projects with no action lists your projects.');
|
|
51
|
-
if (['add', 'remove', 'include', 'exclude'].includes(action) && !value)
|
|
51
|
+
if (['add', 'remove', 'include', 'exclude'].includes(action) && !value && !canAsk)
|
|
52
52
|
fail('Which folder?', 'Usage: sandbox projects ' + action + ' <folder> (. = this folder)');
|
|
53
53
|
if (action === 'all' && value !== undefined && !['on', 'off'].includes(value))
|
|
54
54
|
unknownValue('value for projects all', value, ['on', 'off'], 'sandbox projects all on|off');
|
|
@@ -64,7 +64,7 @@ export function validateOptions(ctx) {
|
|
|
64
64
|
if (['launch', 'generate', 'restart', 'doctor'].includes(o.command))
|
|
65
65
|
checkHarness(o.harness, harnesses);
|
|
66
66
|
if (o.command === 'projects')
|
|
67
|
-
validateProjectsArgs(o.positionals);
|
|
67
|
+
validateProjectsArgs(o.positionals, Boolean(process.stdin.isTTY));
|
|
68
68
|
if (!LAUNCHING.has(o.command))
|
|
69
69
|
return;
|
|
70
70
|
if (o.node !== undefined && !validNodeSpec(o.node))
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// `sandbox --version`: the version and where it runs from; `--version --short` is the plain number (the updater and the
|
|
2
|
+
// installer compare it to the version they just installed).
|
|
3
|
+
import { packageVersion } from '../core/package-info.js';
|
|
4
|
+
import { describeCopy } from '../host/install/index.js';
|
|
5
|
+
/** The text for a version-only command line (`--version`, `-v`, with or without `--short`), or null for any other. */
|
|
6
|
+
export function versionText(argv, packageRoot) {
|
|
7
|
+
const flags = argv.filter((a) => a !== '--short');
|
|
8
|
+
if (flags.length === 0 || flags.some((a) => a !== '--version' && a !== '-v'))
|
|
9
|
+
return null;
|
|
10
|
+
return argv.includes('--short') ? packageVersion() : packageVersion() + ' (' + describeCopy(packageRoot) + ')';
|
|
11
|
+
}
|
|
@@ -24,13 +24,14 @@ export const DEFAULTS = {
|
|
|
24
24
|
},
|
|
25
25
|
sharing: { otherUsers: false },
|
|
26
26
|
storage: {
|
|
27
|
-
root: '%
|
|
27
|
+
root: '%ProgramData%\\AgentSandbox\\users\\%USERNAME%',
|
|
28
28
|
persistAgentState: true,
|
|
29
29
|
dataName: 'default',
|
|
30
30
|
markSandboxFiles: true,
|
|
31
31
|
warnDataGb: 50,
|
|
32
32
|
},
|
|
33
33
|
network: { blockPrivateRanges: true, allowOnly: [], blockHosts: [], forwardPorts: [], dns: [], proxy: '' },
|
|
34
|
+
vpn: { enabled: false, provider: 'nordvpn', protocol: 'udp', country: '', configFile: '', killSwitch: true },
|
|
34
35
|
provisioning: {
|
|
35
36
|
copyFromHost: true,
|
|
36
37
|
fallbackToInstall: true,
|
|
@@ -88,6 +89,7 @@ export const DEFAULTS = {
|
|
|
88
89
|
sqlserver: { enabled: 'auto' },
|
|
89
90
|
},
|
|
90
91
|
attach: { enabled: true, reuseSession: true, auto: false, autoHide: false },
|
|
92
|
+
web: { enabled: false, port: 47800 },
|
|
91
93
|
agentCommands: { enabled: false, agents: 'auto' },
|
|
92
94
|
secrets: { strip: true, allow: [], patterns: [], warnFiles: true },
|
|
93
95
|
personalization: { enabled: true },
|
|
@@ -99,6 +101,7 @@ export const DEFAULTS = {
|
|
|
99
101
|
globalStateFile: 'auto',
|
|
100
102
|
copyCredentials: false,
|
|
101
103
|
overwrite: true,
|
|
104
|
+
sharePluginsAcrossAccounts: false,
|
|
102
105
|
syncHistory: true,
|
|
103
106
|
historyScope: 'project',
|
|
104
107
|
syncClaudeMem: true,
|
|
@@ -122,6 +125,7 @@ export const DEFAULTS = {
|
|
|
122
125
|
arguments: [],
|
|
123
126
|
environment: {},
|
|
124
127
|
home: { env: { CODEX_HOME: 'codex' }, loginFiles: ['auth.json'], hostDir: '~/.codex' },
|
|
128
|
+
localState: { CODEX_SQLITE_HOME: 'sqlite' },
|
|
125
129
|
resumeArguments: ['resume', '--last'],
|
|
126
130
|
},
|
|
127
131
|
gemini: {
|
|
@@ -23,8 +23,18 @@ export function machineConfigPath(env = process.env) {
|
|
|
23
23
|
* folders in it must be full paths (after %VARIABLES% expand), never relative to someone's folder.
|
|
24
24
|
*/
|
|
25
25
|
function readMachineConfig(file) {
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
// existsSync says false on "access denied": a user not yet in the group would silently get the defaults.
|
|
27
|
+
try {
|
|
28
|
+
fs.accessSync(file, fs.constants.R_OK);
|
|
29
|
+
}
|
|
30
|
+
catch (e) {
|
|
31
|
+
const code = e.code;
|
|
32
|
+
if (code === 'ENOENT' || code === 'ENOTDIR')
|
|
33
|
+
return null;
|
|
34
|
+
if (code === 'EACCES' || code === 'EPERM')
|
|
35
|
+
fail('Cannot read the settings for this PC in ' + file + '.', 'Sign out of Windows and in again after being added to the Agent Sandbox Users group.');
|
|
36
|
+
throw e;
|
|
37
|
+
}
|
|
28
38
|
const raw = readJsonc(file);
|
|
29
39
|
const config = validateConfig(mergeConfig(DEFAULTS, raw), file);
|
|
30
40
|
const folders = config.mappings.map((m, i) => ['mappings[' + i + '].host', m.host]);
|
package/dist/core/prompt.d.ts
CHANGED
|
@@ -1,4 +1,23 @@
|
|
|
1
|
+
/** One entry of a list question; `description` is shown under the highlighted entry. */
|
|
2
|
+
export interface PromptChoice<T> {
|
|
3
|
+
readonly name: string;
|
|
4
|
+
readonly value: T;
|
|
5
|
+
readonly description?: string;
|
|
6
|
+
}
|
|
1
7
|
/** A yes/no question (default no). */
|
|
2
8
|
export declare function askYesNo(question: string, defaultYes?: boolean): Promise<boolean>;
|
|
9
|
+
/** A yes/no question the command needs answered: no terminal fails (`--yes` answers yes on the command line). */
|
|
10
|
+
export declare function askRequired(question: string, fix?: string, defaultYes?: boolean): Promise<boolean>;
|
|
3
11
|
/** Asks the user to type `expected` (a stronger confirmation than yes/no). */
|
|
4
12
|
export declare function askTyped(question: string, expected: string): Promise<boolean>;
|
|
13
|
+
/** Pick one entry from a list (for an argument that was left out); `fix` says what to type instead. */
|
|
14
|
+
export declare function askChoice<T>(message: string, choices: readonly PromptChoice<T>[], fix: string): Promise<T>;
|
|
15
|
+
/** Tick any number of entries from a list; `fix` says what to type instead. */
|
|
16
|
+
export declare function askChoices<T>(message: string, choices: readonly PromptChoice<T>[], fix: string): Promise<T[]>;
|
|
17
|
+
/** Type a name or a path. `validate` returns true, or the problem to show. */
|
|
18
|
+
export declare function askName(message: string, fix: string, validate?: (value: string) => true | string): Promise<string>;
|
|
19
|
+
/**
|
|
20
|
+
* Type a secret (a password, an API key) with each character shown as *. Never echoed, never kept; `fix` says what to
|
|
21
|
+
* do without a terminal.
|
|
22
|
+
*/
|
|
23
|
+
export declare function askSecret(message: string, fix: string): Promise<string>;
|
package/dist/core/prompt.js
CHANGED
|
@@ -1,12 +1,24 @@
|
|
|
1
|
-
// Questions asked on the terminal, all through @inquirer/prompts.
|
|
2
|
-
// "no".
|
|
3
|
-
|
|
1
|
+
// Questions asked on the terminal, all through @inquirer/prompts. askYesNo is for optional offers: without an
|
|
2
|
+
// interactive terminal the answer is "no". askRequired, askChoice and askName are for questions a command cannot go on
|
|
3
|
+
// without: with no terminal they fail and say how to answer on the command line.
|
|
4
|
+
import { checkbox, confirm, input, password, select } from '@inquirer/prompts';
|
|
5
|
+
import { fail } from './util/errors.js';
|
|
6
|
+
/** The terminal check every required question starts with. */
|
|
7
|
+
function requireTerminal(fix) {
|
|
8
|
+
if (!process.stdin.isTTY)
|
|
9
|
+
fail('Cannot ask here (no terminal).', fix);
|
|
10
|
+
}
|
|
4
11
|
/** A yes/no question (default no). */
|
|
5
12
|
export async function askYesNo(question, defaultYes = false) {
|
|
6
13
|
if (!process.stdin.isTTY)
|
|
7
14
|
return false;
|
|
8
15
|
return confirm({ message: question, default: defaultYes });
|
|
9
16
|
}
|
|
17
|
+
/** A yes/no question the command needs answered: no terminal fails (`--yes` answers yes on the command line). */
|
|
18
|
+
export async function askRequired(question, fix = 'Add --yes to answer yes.', defaultYes = false) {
|
|
19
|
+
requireTerminal(fix);
|
|
20
|
+
return confirm({ message: question, default: defaultYes });
|
|
21
|
+
}
|
|
10
22
|
/** Asks the user to type `expected` (a stronger confirmation than yes/no). */
|
|
11
23
|
export async function askTyped(question, expected) {
|
|
12
24
|
if (!process.stdin.isTTY)
|
|
@@ -14,3 +26,31 @@ export async function askTyped(question, expected) {
|
|
|
14
26
|
const answer = await input({ message: question + ' Type "' + expected + '" to confirm:' });
|
|
15
27
|
return answer.trim().toLowerCase() === expected;
|
|
16
28
|
}
|
|
29
|
+
/** Pick one entry from a list (for an argument that was left out); `fix` says what to type instead. */
|
|
30
|
+
export async function askChoice(message, choices, fix) {
|
|
31
|
+
requireTerminal(fix);
|
|
32
|
+
return select({ message, choices: [...choices] });
|
|
33
|
+
}
|
|
34
|
+
/** Tick any number of entries from a list; `fix` says what to type instead. */
|
|
35
|
+
export async function askChoices(message, choices, fix) {
|
|
36
|
+
requireTerminal(fix);
|
|
37
|
+
return checkbox({ message, choices: [...choices] });
|
|
38
|
+
}
|
|
39
|
+
/** Type a name or a path. `validate` returns true, or the problem to show. */
|
|
40
|
+
export async function askName(message, fix, validate) {
|
|
41
|
+
requireTerminal(fix);
|
|
42
|
+
const answer = await input({ message, validate: validate ? (v) => validate(v.trim()) : undefined });
|
|
43
|
+
return answer.trim();
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Type a secret (a password, an API key) with each character shown as *. Never echoed, never kept; `fix` says what to
|
|
47
|
+
* do without a terminal.
|
|
48
|
+
*/
|
|
49
|
+
export async function askSecret(message, fix) {
|
|
50
|
+
requireTerminal(fix);
|
|
51
|
+
return password({
|
|
52
|
+
message,
|
|
53
|
+
mask: '*',
|
|
54
|
+
validate: (v) => (v.length > 0 ? true : 'Type it, or press Ctrl+C to cancel.'),
|
|
55
|
+
});
|
|
56
|
+
}
|
|
@@ -18,3 +18,9 @@ export declare const GitAccessSchema: z.ZodEnum<{
|
|
|
18
18
|
export declare const EnabledSchema: z.ZodUnion<readonly [z.ZodBoolean, z.ZodLiteral<"auto">]>;
|
|
19
19
|
export declare function enabled(what: string, markers: string): typeof EnabledSchema;
|
|
20
20
|
export declare function Packages(what: string, example: string): typeof StringsSchema;
|
|
21
|
+
/**
|
|
22
|
+
* Marks a setting whose value is a secret (an API key in an agent's environment): config show / get, the menu, doctor
|
|
23
|
+
* and every --json print *** for it (core/schema/redact.ts), and it is never written to session.json or the launch
|
|
24
|
+
* folder (it travels in a one-shot file, see shared/channel/secrets.ts).
|
|
25
|
+
*/
|
|
26
|
+
export declare function secret<T extends z.ZodType>(schema: T): T;
|
|
@@ -25,3 +25,11 @@ export function enabled(what, markers) {
|
|
|
25
25
|
export function Packages(what, example) {
|
|
26
26
|
return StringsSchema.describe(what + ', installed once and kept (e.g. ' + example + ').');
|
|
27
27
|
}
|
|
28
|
+
/**
|
|
29
|
+
* Marks a setting whose value is a secret (an API key in an agent's environment): config show / get, the menu, doctor
|
|
30
|
+
* and every --json print *** for it (core/schema/redact.ts), and it is never written to session.json or the launch
|
|
31
|
+
* folder (it travels in a one-shot file, see shared/channel/secrets.ts).
|
|
32
|
+
*/
|
|
33
|
+
export function secret(schema) {
|
|
34
|
+
return schema.meta({ secret: true });
|
|
35
|
+
}
|
|
@@ -60,6 +60,20 @@ export declare const ConfigSchema: z.ZodObject<{
|
|
|
60
60
|
dns: z.ZodArray<z.ZodString>;
|
|
61
61
|
proxy: z.ZodString;
|
|
62
62
|
}, z.core.$strict>;
|
|
63
|
+
vpn: z.ZodObject<{
|
|
64
|
+
enabled: z.ZodBoolean;
|
|
65
|
+
provider: z.ZodEnum<{
|
|
66
|
+
nordvpn: "nordvpn";
|
|
67
|
+
"openvpn-file": "openvpn-file";
|
|
68
|
+
}>;
|
|
69
|
+
protocol: z.ZodEnum<{
|
|
70
|
+
udp: "udp";
|
|
71
|
+
tcp: "tcp";
|
|
72
|
+
}>;
|
|
73
|
+
country: z.ZodString;
|
|
74
|
+
configFile: z.ZodString;
|
|
75
|
+
killSwitch: z.ZodBoolean;
|
|
76
|
+
}, z.core.$strict>;
|
|
63
77
|
provisioning: z.ZodObject<{
|
|
64
78
|
copyFromHost: z.ZodBoolean;
|
|
65
79
|
fallbackToInstall: z.ZodBoolean;
|
|
@@ -218,6 +232,10 @@ export declare const ConfigSchema: z.ZodObject<{
|
|
|
218
232
|
auto: z.ZodBoolean;
|
|
219
233
|
autoHide: z.ZodBoolean;
|
|
220
234
|
}, z.core.$strict>;
|
|
235
|
+
web: z.ZodObject<{
|
|
236
|
+
enabled: z.ZodBoolean;
|
|
237
|
+
port: z.ZodNumber;
|
|
238
|
+
}, z.core.$strict>;
|
|
221
239
|
agentCommands: z.ZodObject<{
|
|
222
240
|
enabled: z.ZodBoolean;
|
|
223
241
|
agents: z.ZodUnion<readonly [z.ZodLiteral<"auto">, z.ZodArray<z.ZodString>]>;
|
|
@@ -258,6 +276,7 @@ export declare const ConfigSchema: z.ZodObject<{
|
|
|
258
276
|
globalStateFile: z.ZodString;
|
|
259
277
|
copyCredentials: z.ZodBoolean;
|
|
260
278
|
overwrite: z.ZodBoolean;
|
|
279
|
+
sharePluginsAcrossAccounts: z.ZodBoolean;
|
|
261
280
|
syncHistory: z.ZodBoolean;
|
|
262
281
|
historyScope: z.ZodEnum<{
|
|
263
282
|
project: "project";
|
|
@@ -281,6 +300,7 @@ export declare const ConfigSchema: z.ZodObject<{
|
|
|
281
300
|
loginFiles: z.ZodArray<z.ZodString>;
|
|
282
301
|
hostDir: z.ZodOptional<z.ZodString>;
|
|
283
302
|
}, z.core.$strict>>;
|
|
303
|
+
localState: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
284
304
|
resumeArguments: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
285
305
|
resumeOneArguments: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
286
306
|
}, z.core.$strict>>;
|
|
@@ -345,6 +365,9 @@ export declare const LocalOverridesSchema: z.ZodObject<{
|
|
|
345
365
|
blockPrivateRanges: z.ZodOptional<z.ZodBoolean>;
|
|
346
366
|
blockHosts: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
347
367
|
}, z.core.$strict>>;
|
|
368
|
+
vpn: z.ZodOptional<z.ZodObject<{
|
|
369
|
+
killSwitch: z.ZodOptional<z.ZodBoolean>;
|
|
370
|
+
}, z.core.$strict>>;
|
|
348
371
|
provisioning: z.ZodOptional<z.ZodObject<{
|
|
349
372
|
copyFromHost: z.ZodOptional<z.ZodBoolean>;
|
|
350
373
|
fallbackToInstall: z.ZodOptional<z.ZodBoolean>;
|