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
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
// The kill switch as netsh argument lists (pure, so it is tested without a firewall). Phase 1 runs BEFORE the tunnel
|
|
2
|
+
// starts: everything that goes out is blocked except loopback, the VPN servers themselves, DHCP and the host's attach
|
|
3
|
+
// channel. Phase 2 runs once the tunnel is up: traffic from the tunnel's own address is allowed, which is everything
|
|
4
|
+
// that goes through the tunnel (DNS included). Windows keeps the block rules for private ranges
|
|
5
|
+
// (network.blockPrivateRanges) on top of this: a block rule always beats an allow rule.
|
|
6
|
+
import { isIPv4 } from '../network/firewall-rules.js';
|
|
7
|
+
export const VPN_RULE_PREFIX = 'AgentSandbox-VPN-';
|
|
8
|
+
const rule = (name, extra) => [
|
|
9
|
+
'advfirewall',
|
|
10
|
+
'firewall',
|
|
11
|
+
'add',
|
|
12
|
+
'rule',
|
|
13
|
+
'name=' + VPN_RULE_PREFIX + name,
|
|
14
|
+
'dir=out',
|
|
15
|
+
'action=allow',
|
|
16
|
+
'enable=yes',
|
|
17
|
+
'profile=any',
|
|
18
|
+
...extra,
|
|
19
|
+
];
|
|
20
|
+
const drop = (name) => [
|
|
21
|
+
'advfirewall',
|
|
22
|
+
'firewall',
|
|
23
|
+
'delete',
|
|
24
|
+
'rule',
|
|
25
|
+
'name=' + VPN_RULE_PREFIX + name,
|
|
26
|
+
];
|
|
27
|
+
/** The rule names phase 1 and 2 may create (the servers get a number each). */
|
|
28
|
+
export function ruleNames(serverCount) {
|
|
29
|
+
return [
|
|
30
|
+
'Loopback',
|
|
31
|
+
'DHCP',
|
|
32
|
+
'Host',
|
|
33
|
+
'Tunnel',
|
|
34
|
+
...Array.from({ length: Math.max(serverCount, 0) }, (_v, i) => 'Server-' + (i + 1)),
|
|
35
|
+
];
|
|
36
|
+
}
|
|
37
|
+
/** Servers worth a rule: valid IPv4 addresses and ports, each endpoint once. */
|
|
38
|
+
export function cleanServers(servers) {
|
|
39
|
+
const seen = new Set();
|
|
40
|
+
return servers.filter((s) => {
|
|
41
|
+
const key = s.proto + ':' + s.ip + ':' + s.port;
|
|
42
|
+
if (!isIPv4(s.ip) || !Number.isInteger(s.port) || s.port < 1 || s.port > 65535 || seen.has(key))
|
|
43
|
+
return false;
|
|
44
|
+
seen.add(key);
|
|
45
|
+
return true;
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
/** Phase 1: block everything that goes out, then allow only what the tunnel and the attach channel need. */
|
|
49
|
+
export function killSwitchCommands(servers, ptyHostExe) {
|
|
50
|
+
const list = cleanServers(servers);
|
|
51
|
+
return [
|
|
52
|
+
...ruleNames(Math.max(list.length, 8)).map(drop),
|
|
53
|
+
['advfirewall', 'set', 'allprofiles', 'state', 'on'],
|
|
54
|
+
['advfirewall', 'set', 'allprofiles', 'firewallpolicy', 'blockinbound,blockoutbound'],
|
|
55
|
+
rule('Loopback', ['protocol=any', 'remoteip=127.0.0.0/8']),
|
|
56
|
+
rule('DHCP', ['protocol=udp', 'localport=68', 'remoteport=67']),
|
|
57
|
+
...(ptyHostExe ? [rule('Host', ['protocol=any', 'remoteip=LocalSubnet', 'program=' + ptyHostExe])] : []),
|
|
58
|
+
...list.map((s, i) => rule('Server-' + (i + 1), ['protocol=' + s.proto, 'remoteip=' + s.ip, 'remoteport=' + s.port])),
|
|
59
|
+
];
|
|
60
|
+
}
|
|
61
|
+
/** Phase 2: everything that leaves from the tunnel's own address goes (it is inside the tunnel). */
|
|
62
|
+
export function tunnelCommands(tunnelIp) {
|
|
63
|
+
if (!isIPv4(tunnelIp))
|
|
64
|
+
throw new Error('Not an IPv4 address: ' + tunnelIp);
|
|
65
|
+
return [drop('Tunnel'), rule('Tunnel', ['protocol=any', 'localip=' + tunnelIp])];
|
|
66
|
+
}
|
|
67
|
+
/** Takes the kill switch away again: its rules go and outbound traffic is allowed by default as before. */
|
|
68
|
+
export function removeKillSwitchCommands() {
|
|
69
|
+
return [
|
|
70
|
+
...ruleNames(64).map(drop),
|
|
71
|
+
['advfirewall', 'set', 'allprofiles', 'firewallpolicy', 'blockinbound,allowoutbound'],
|
|
72
|
+
];
|
|
73
|
+
}
|
|
74
|
+
/** The tunnel's own IPv4 address from OpenVPN's log (its "net_addr_v4_add" or "ifconfig" line), or null. */
|
|
75
|
+
export function tunnelAddressFromLog(log) {
|
|
76
|
+
const add = /net_addr_v4_add:\s*(\d{1,3}(?:\.\d{1,3}){3})\/\d+/.exec(log);
|
|
77
|
+
if (add && isIPv4(add[1]))
|
|
78
|
+
return add[1];
|
|
79
|
+
const ifconfig = /(?:ifconfig|ip addr add|Notified TAP-Windows driver to set a DHCP IP\/netmask of)\s+(\d{1,3}(?:\.\d{1,3}){3})/i.exec(log);
|
|
80
|
+
return ifconfig && isIPv4(ifconfig[1]) ? ifconfig[1] : null;
|
|
81
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/** Directives that run a program, load code or touch a file on this machine. Refused with a clear reason. */
|
|
2
|
+
export declare const PROGRAM_DIRECTIVES: readonly ["script-security", "up", "down", "up-restart", "down-pre", "route-up", "route-pre-down", "ipchange", "tls-verify", "plugin", "client-connect", "client-disconnect", "learn-address", "auth-user-pass-verify", "setenv-safe", "management", "management-client", "management-client-auth", "management-hold", "management-query-passwords", "config", "daemon", "service", "cd", "chroot", "setcon", "log", "log-append", "writepid", "status", "askpass", "engine", "bcast-dev", "dev-node", "cryptoapicert", "pkcs11-providers", "pkcs12", "http-proxy-user-pass", "tmp-dir"];
|
|
3
|
+
export declare const MAX_OVPN_BYTES: number;
|
|
4
|
+
/** Where the tunnel connects. `host` is an IPv4 address or a name. */
|
|
5
|
+
export interface OvpnRemote {
|
|
6
|
+
readonly host: string;
|
|
7
|
+
readonly port: number;
|
|
8
|
+
readonly proto: 'udp' | 'tcp';
|
|
9
|
+
}
|
|
10
|
+
export type OvpnReport = {
|
|
11
|
+
readonly ok: true;
|
|
12
|
+
readonly remotes: readonly OvpnRemote[];
|
|
13
|
+
} | {
|
|
14
|
+
readonly ok: false;
|
|
15
|
+
readonly problems: readonly string[];
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Checks a profile. `ok: false` lists the problems; `ok: true` gives the servers it connects to. A profile must name at
|
|
19
|
+
* least one remote, and every certificate must be inside it.
|
|
20
|
+
*/
|
|
21
|
+
export declare function inspectOvpn(text: string): OvpnReport;
|
|
22
|
+
/** The servers of a safe profile; throws, saying why, when it is not (`what` names the file or source). */
|
|
23
|
+
export declare function assertSafeOvpn(text: string, what: string): readonly OvpnRemote[];
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
// An OpenVPN profile (.ovpn) is untrusted data: it comes from the internet or from a file you were given, and OpenVPN
|
|
2
|
+
// can run programs from it (script-security, up, down, plugin ...) with administrator rights. Only directives on a
|
|
3
|
+
// short list of harmless ones are accepted; anything else is refused by name. Also answers where the tunnel connects
|
|
4
|
+
// (the `remote` lines), which the kill switch needs. Pure: no files, no network.
|
|
5
|
+
/** Directives that run a program, load code or touch a file on this machine. Refused with a clear reason. */
|
|
6
|
+
export const PROGRAM_DIRECTIVES = [
|
|
7
|
+
'script-security',
|
|
8
|
+
'up',
|
|
9
|
+
'down',
|
|
10
|
+
'up-restart',
|
|
11
|
+
'down-pre',
|
|
12
|
+
'route-up',
|
|
13
|
+
'route-pre-down',
|
|
14
|
+
'ipchange',
|
|
15
|
+
'tls-verify',
|
|
16
|
+
'plugin',
|
|
17
|
+
'client-connect',
|
|
18
|
+
'client-disconnect',
|
|
19
|
+
'learn-address',
|
|
20
|
+
'auth-user-pass-verify',
|
|
21
|
+
'setenv-safe',
|
|
22
|
+
'management',
|
|
23
|
+
'management-client',
|
|
24
|
+
'management-client-auth',
|
|
25
|
+
'management-hold',
|
|
26
|
+
'management-query-passwords',
|
|
27
|
+
'config',
|
|
28
|
+
'daemon',
|
|
29
|
+
'service',
|
|
30
|
+
'cd',
|
|
31
|
+
'chroot',
|
|
32
|
+
'setcon',
|
|
33
|
+
'log',
|
|
34
|
+
'log-append',
|
|
35
|
+
'writepid',
|
|
36
|
+
'status',
|
|
37
|
+
'askpass',
|
|
38
|
+
'engine',
|
|
39
|
+
'bcast-dev',
|
|
40
|
+
'dev-node',
|
|
41
|
+
'cryptoapicert',
|
|
42
|
+
'pkcs11-providers',
|
|
43
|
+
'pkcs12',
|
|
44
|
+
'http-proxy-user-pass',
|
|
45
|
+
'tmp-dir',
|
|
46
|
+
];
|
|
47
|
+
/** Directives that are only settings of the tunnel. Everything else is refused. */
|
|
48
|
+
const ALLOWED = new Set([
|
|
49
|
+
'client',
|
|
50
|
+
'tls-client',
|
|
51
|
+
'dev',
|
|
52
|
+
'dev-type',
|
|
53
|
+
'proto',
|
|
54
|
+
'remote',
|
|
55
|
+
'remote-random',
|
|
56
|
+
'remote-random-hostname',
|
|
57
|
+
'resolv-retry',
|
|
58
|
+
'nobind',
|
|
59
|
+
'persist-key',
|
|
60
|
+
'persist-tun',
|
|
61
|
+
'remote-cert-tls',
|
|
62
|
+
'remote-cert-eku',
|
|
63
|
+
'ns-cert-type',
|
|
64
|
+
'verify-x509-name',
|
|
65
|
+
'cipher',
|
|
66
|
+
'data-ciphers',
|
|
67
|
+
'data-ciphers-fallback',
|
|
68
|
+
'ncp-ciphers',
|
|
69
|
+
'auth',
|
|
70
|
+
'verb',
|
|
71
|
+
'mute',
|
|
72
|
+
'mute-replay-warnings',
|
|
73
|
+
'reneg-sec',
|
|
74
|
+
'reneg-bytes',
|
|
75
|
+
'reneg-pkts',
|
|
76
|
+
'tun-mtu',
|
|
77
|
+
'tun-mtu-extra',
|
|
78
|
+
'ping-timer-rem',
|
|
79
|
+
'fast-io',
|
|
80
|
+
'tls-timeout',
|
|
81
|
+
'push-peer-info',
|
|
82
|
+
'comp-noadapt',
|
|
83
|
+
'link-mtu',
|
|
84
|
+
'fragment',
|
|
85
|
+
'mssfix',
|
|
86
|
+
'sndbuf',
|
|
87
|
+
'rcvbuf',
|
|
88
|
+
'comp-lzo',
|
|
89
|
+
'compress',
|
|
90
|
+
'allow-compression',
|
|
91
|
+
'key-direction',
|
|
92
|
+
'auth-user-pass',
|
|
93
|
+
'auth-nocache',
|
|
94
|
+
'explicit-exit-notify',
|
|
95
|
+
'pull',
|
|
96
|
+
'pull-filter',
|
|
97
|
+
'route-nopull',
|
|
98
|
+
'route',
|
|
99
|
+
'route-ipv6',
|
|
100
|
+
'route-delay',
|
|
101
|
+
'route-metric',
|
|
102
|
+
'redirect-gateway',
|
|
103
|
+
'redirect-private',
|
|
104
|
+
'dhcp-option',
|
|
105
|
+
'block-outside-dns',
|
|
106
|
+
'register-dns',
|
|
107
|
+
'topology',
|
|
108
|
+
'tls-version-min',
|
|
109
|
+
'tls-version-max',
|
|
110
|
+
'tls-cipher',
|
|
111
|
+
'tls-ciphersuites',
|
|
112
|
+
'tls-groups',
|
|
113
|
+
'tls-exit',
|
|
114
|
+
'ping',
|
|
115
|
+
'ping-restart',
|
|
116
|
+
'ping-exit',
|
|
117
|
+
'keepalive',
|
|
118
|
+
'connect-retry',
|
|
119
|
+
'connect-retry-max',
|
|
120
|
+
'connect-timeout',
|
|
121
|
+
'server-poll-timeout',
|
|
122
|
+
'float',
|
|
123
|
+
'ifconfig-nowarn',
|
|
124
|
+
'tun-ipv6',
|
|
125
|
+
'disable-dco',
|
|
126
|
+
'windows-driver',
|
|
127
|
+
'ignore-unknown-option',
|
|
128
|
+
'opt-verify',
|
|
129
|
+
'setenv',
|
|
130
|
+
'key-method',
|
|
131
|
+
'replay-window',
|
|
132
|
+
'hand-window',
|
|
133
|
+
'tran-window',
|
|
134
|
+
'inactive',
|
|
135
|
+
'socket-flags',
|
|
136
|
+
'auth-retry',
|
|
137
|
+
'ca',
|
|
138
|
+
'cert',
|
|
139
|
+
'key',
|
|
140
|
+
'tls-auth',
|
|
141
|
+
'tls-crypt',
|
|
142
|
+
'tls-crypt-v2',
|
|
143
|
+
'extra-certs',
|
|
144
|
+
'dh',
|
|
145
|
+
]);
|
|
146
|
+
/** Directives that name a file: only allowed as inline sections (the certificates must be inside the profile). */
|
|
147
|
+
const FILE_DIRECTIVES = new Set(['ca', 'cert', 'key', 'tls-auth', 'tls-crypt', 'tls-crypt-v2', 'extra-certs', 'dh']);
|
|
148
|
+
/** The inline sections (<ca> ... </ca>); their text is data, never parsed as directives. */
|
|
149
|
+
const BLOCKS = new Set(['ca', 'cert', 'key', 'tls-auth', 'tls-crypt', 'tls-crypt-v2', 'extra-certs', 'dh']);
|
|
150
|
+
export const MAX_OVPN_BYTES = 256 * 1024;
|
|
151
|
+
const MAX_LINES = 4000;
|
|
152
|
+
const HOST = /^(?:\d{1,3}(?:\.\d{1,3}){3}|[A-Za-z0-9](?:[A-Za-z0-9.-]{0,251}[A-Za-z0-9])?)$/;
|
|
153
|
+
function directiveOf(line) {
|
|
154
|
+
const text = line.replace(/^\uFEFF/, '').trim();
|
|
155
|
+
if (text === '' || text.startsWith('#') || text.startsWith(';'))
|
|
156
|
+
return null;
|
|
157
|
+
// OpenVPN accepts "--client" too.
|
|
158
|
+
const parts = text.replace(/^-+/, '').split(/\s+/);
|
|
159
|
+
return { name: parts[0].toLowerCase(), args: parts.slice(1) };
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Checks a profile. `ok: false` lists the problems; `ok: true` gives the servers it connects to. A profile must name at
|
|
163
|
+
* least one remote, and every certificate must be inside it.
|
|
164
|
+
*/
|
|
165
|
+
export function inspectOvpn(text) {
|
|
166
|
+
const problems = [];
|
|
167
|
+
const found = [];
|
|
168
|
+
const refuse = (message) => {
|
|
169
|
+
if (problems.length < 20 && !problems.includes(message))
|
|
170
|
+
problems.push(message);
|
|
171
|
+
};
|
|
172
|
+
if (Buffer.byteLength(text, 'utf8') > MAX_OVPN_BYTES)
|
|
173
|
+
return { ok: false, problems: ['the file is too big'] };
|
|
174
|
+
if (text.includes('\0'))
|
|
175
|
+
return { ok: false, problems: ['the file is not text'] };
|
|
176
|
+
const lines = text.split(/\r?\n/);
|
|
177
|
+
if (lines.length > MAX_LINES)
|
|
178
|
+
return { ok: false, problems: ['the file has too many lines'] };
|
|
179
|
+
let block = null;
|
|
180
|
+
let defaultProto = 'udp';
|
|
181
|
+
lines.forEach((line, i) => {
|
|
182
|
+
const at = 'line ' + (i + 1) + ': ';
|
|
183
|
+
const trimmed = line.trim();
|
|
184
|
+
if (block) {
|
|
185
|
+
if (trimmed.toLowerCase() === '</' + block + '>')
|
|
186
|
+
block = null;
|
|
187
|
+
else if (/^<\/?[A-Za-z-]+>$/.test(trimmed))
|
|
188
|
+
refuse(at + 'a section inside a section');
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
const open = /^<([A-Za-z0-9-]+)>$/.exec(trimmed);
|
|
192
|
+
if (open) {
|
|
193
|
+
const tag = open[1].toLowerCase();
|
|
194
|
+
if (!BLOCKS.has(tag))
|
|
195
|
+
refuse(at + '<' + tag + '> is not allowed');
|
|
196
|
+
block = tag;
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
const d = directiveOf(line);
|
|
200
|
+
if (!d)
|
|
201
|
+
return;
|
|
202
|
+
if (!/^[a-z0-9-]{1,40}$/.test(d.name))
|
|
203
|
+
return refuse(at + 'a directive name with odd characters');
|
|
204
|
+
if (PROGRAM_DIRECTIVES.includes(d.name))
|
|
205
|
+
return refuse(at + d.name + ' runs a program or reads or writes a file on this machine');
|
|
206
|
+
if (!ALLOWED.has(d.name))
|
|
207
|
+
return refuse(at + d.name + ' is not on the list of settings that are safe to accept');
|
|
208
|
+
if (FILE_DIRECTIVES.has(d.name))
|
|
209
|
+
return refuse(at + d.name + ' names a file: certificates must be inside the profile');
|
|
210
|
+
if (d.name === 'auth-user-pass' && d.args.length > 0)
|
|
211
|
+
return refuse(at + 'auth-user-pass names a file: the login is given separately');
|
|
212
|
+
if (d.name === 'setenv' && !(d.args[0] === 'CLIENT_CERT' && d.args.length === 2))
|
|
213
|
+
return refuse(at + 'setenv may only be CLIENT_CERT');
|
|
214
|
+
if (d.name === 'proto')
|
|
215
|
+
defaultProto = d.args[0]?.startsWith('tcp') ? 'tcp' : 'udp';
|
|
216
|
+
if (d.name === 'remote') {
|
|
217
|
+
const [host, port = '1194', proto] = d.args;
|
|
218
|
+
if (!host || !HOST.test(host))
|
|
219
|
+
return refuse(at + 'remote needs a host name or an IPv4 address');
|
|
220
|
+
const n = Number(port);
|
|
221
|
+
if (!Number.isInteger(n) || n < 1 || n > 65535)
|
|
222
|
+
return refuse(at + 'remote has an invalid port');
|
|
223
|
+
found.push({ host, port: n, ...(proto ? { proto: proto.startsWith('tcp') ? 'tcp' : 'udp' } : {}) });
|
|
224
|
+
}
|
|
225
|
+
});
|
|
226
|
+
// A remote without its own protocol uses the profile's proto line, wherever that line is.
|
|
227
|
+
const remotes = found.map((r) => ({ host: r.host, port: r.port, proto: r.proto ?? defaultProto }));
|
|
228
|
+
if (block)
|
|
229
|
+
refuse('a <' + block + '> section is never closed');
|
|
230
|
+
if (remotes.length === 0)
|
|
231
|
+
refuse('it names no remote server');
|
|
232
|
+
if (remotes.length > 64)
|
|
233
|
+
refuse('it names too many servers');
|
|
234
|
+
return problems.length ? { ok: false, problems } : { ok: true, remotes };
|
|
235
|
+
}
|
|
236
|
+
/** The servers of a safe profile; throws, saying why, when it is not (`what` names the file or source). */
|
|
237
|
+
export function assertSafeOvpn(text, what) {
|
|
238
|
+
const report = inspectOvpn(text);
|
|
239
|
+
if (report.ok)
|
|
240
|
+
return report.remotes;
|
|
241
|
+
throw new Error(what +
|
|
242
|
+
' was refused because it could run programs or is not a plain profile:\n - ' +
|
|
243
|
+
report.problems.slice(0, 5).join('\n - '));
|
|
244
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './protocol.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './protocol.js';
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/** The header every state-changing call carries (a browser page of another site cannot add it without CORS). */
|
|
2
|
+
export declare const CSRF_HEADER = "x-sandbox-web";
|
|
3
|
+
export declare const CSRF_VALUE = "1";
|
|
4
|
+
export declare const COOKIE_NAME = "sbxweb";
|
|
5
|
+
export interface WebSession {
|
|
6
|
+
readonly id: string;
|
|
7
|
+
readonly harness: string;
|
|
8
|
+
readonly project: string;
|
|
9
|
+
readonly cwd: string;
|
|
10
|
+
readonly phase: 'starting' | 'running' | 'exited' | 'failed';
|
|
11
|
+
readonly message: string;
|
|
12
|
+
readonly startedAt: string;
|
|
13
|
+
/** Terminals attached right now (null: the session could not be asked). */
|
|
14
|
+
readonly viewers: number | null;
|
|
15
|
+
/** The session can be opened here (running, and reachable from this PC). */
|
|
16
|
+
readonly canOpen: boolean;
|
|
17
|
+
}
|
|
18
|
+
export interface WebProject {
|
|
19
|
+
readonly name: string;
|
|
20
|
+
readonly guest: string;
|
|
21
|
+
}
|
|
22
|
+
export interface WebInfo {
|
|
23
|
+
readonly sandbox: 'running' | 'stopped';
|
|
24
|
+
/** "Running, started by alice (shared with you)" and the like; null for your own sandbox. */
|
|
25
|
+
readonly owner: string | null;
|
|
26
|
+
/** This user may open sessions and start new ones in the running sandbox. */
|
|
27
|
+
readonly canUse: boolean;
|
|
28
|
+
readonly harnesses: readonly string[];
|
|
29
|
+
readonly defaultHarness: string;
|
|
30
|
+
readonly projects: readonly WebProject[];
|
|
31
|
+
}
|
|
32
|
+
export interface NewSessionRequest {
|
|
33
|
+
readonly harness: string;
|
|
34
|
+
readonly project: string;
|
|
35
|
+
}
|
|
36
|
+
/** Browser -> server on the terminal socket: binary messages are keystrokes; text messages are these (JSON). */
|
|
37
|
+
export type ClientMessage = {
|
|
38
|
+
readonly t: 'resize';
|
|
39
|
+
readonly cols: number;
|
|
40
|
+
readonly rows: number;
|
|
41
|
+
};
|
|
42
|
+
/** Server -> browser: binary messages are terminal output; text messages are these (JSON). */
|
|
43
|
+
export type ServerMessage = {
|
|
44
|
+
readonly t: 'ready';
|
|
45
|
+
} | {
|
|
46
|
+
readonly t: 'restarting';
|
|
47
|
+
} | {
|
|
48
|
+
readonly t: 'exit';
|
|
49
|
+
readonly code: number;
|
|
50
|
+
} | {
|
|
51
|
+
readonly t: 'error';
|
|
52
|
+
readonly message: string;
|
|
53
|
+
};
|
|
54
|
+
export declare const MIN_COLS = 10;
|
|
55
|
+
export declare const MAX_COLS = 500;
|
|
56
|
+
export declare const MIN_ROWS = 2;
|
|
57
|
+
export declare const MAX_ROWS = 300;
|
|
58
|
+
/** Biggest browser message the server accepts (a paste); more closes the socket. */
|
|
59
|
+
export declare const MAX_CLIENT_MESSAGE_BYTES: number;
|
|
60
|
+
/** A browser message that is JSON of a known shape and sane numbers, else null (the socket is then closed). */
|
|
61
|
+
export declare function parseClientMessage(text: string): ClientMessage | null;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// What the web UI's server and its browser app say to each other. Types and constants only (no Node, no DOM), so the
|
|
2
|
+
// server (src/host/web) and the app (web/) share one definition.
|
|
3
|
+
/** The header every state-changing call carries (a browser page of another site cannot add it without CORS). */
|
|
4
|
+
export const CSRF_HEADER = 'x-sandbox-web';
|
|
5
|
+
export const CSRF_VALUE = '1';
|
|
6
|
+
export const COOKIE_NAME = 'sbxweb';
|
|
7
|
+
export const MIN_COLS = 10;
|
|
8
|
+
export const MAX_COLS = 500;
|
|
9
|
+
export const MIN_ROWS = 2;
|
|
10
|
+
export const MAX_ROWS = 300;
|
|
11
|
+
/** Biggest browser message the server accepts (a paste); more closes the socket. */
|
|
12
|
+
export const MAX_CLIENT_MESSAGE_BYTES = 256 * 1024;
|
|
13
|
+
/** A browser message that is JSON of a known shape and sane numbers, else null (the socket is then closed). */
|
|
14
|
+
export function parseClientMessage(text) {
|
|
15
|
+
let value;
|
|
16
|
+
try {
|
|
17
|
+
value = JSON.parse(text);
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
if (typeof value !== 'object' || value === null)
|
|
23
|
+
return null;
|
|
24
|
+
const m = value;
|
|
25
|
+
if (m.t !== 'resize')
|
|
26
|
+
return null;
|
|
27
|
+
const { cols, rows } = m;
|
|
28
|
+
if (!Number.isInteger(cols) || !Number.isInteger(rows))
|
|
29
|
+
return null;
|
|
30
|
+
const c = cols;
|
|
31
|
+
const r = rows;
|
|
32
|
+
if (c < MIN_COLS || c > MAX_COLS || r < MIN_ROWS || r > MAX_ROWS)
|
|
33
|
+
return null;
|
|
34
|
+
return { t: 'resize', cols: c, rows: r };
|
|
35
|
+
}
|
package/dist/sync/sync-cycle.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
2
|
import { assertNoLinks } from '../core/util/index.js';
|
|
3
|
-
import { hostClaudeDir } from '../host/profile/index.js';
|
|
3
|
+
import { hostClaudeDir, PluginShare } from '../host/profile/index.js';
|
|
4
|
+
import { storageOf } from '../host/storage/index.js';
|
|
4
5
|
import { hostClaudeMemDir, syncClaudeMem } from './claude-mem.js';
|
|
5
6
|
import { readSyncState, writeSyncState } from './sync-state.js';
|
|
6
7
|
import { syncHistoryIn, syncHistoryOut } from './history.js';
|
|
@@ -58,6 +59,7 @@ export function syncBeforeLaunch(config, dataPath, hostWorkspace) {
|
|
|
58
59
|
historyScope: profile.historyScope,
|
|
59
60
|
syncClaudeMem: profile.syncClaudeMem,
|
|
60
61
|
syncClaudeMemBack: profile.syncClaudeMemBack,
|
|
62
|
+
sharePlugins: profile.sharePluginsAcrossAccounts,
|
|
61
63
|
projects: [],
|
|
62
64
|
};
|
|
63
65
|
if (profile.syncHistory)
|
|
@@ -78,6 +80,8 @@ export function syncBack(dataPath, final) {
|
|
|
78
80
|
return summary;
|
|
79
81
|
if (state.syncHistory)
|
|
80
82
|
summary.history = syncHistoryOut(toPaths(state, dataPath));
|
|
83
|
+
if (final && state.sharePlugins)
|
|
84
|
+
PluginShare.in(storageOf(dataPath)).saveQuietly(dataPath, guestClaude(dataPath));
|
|
81
85
|
if (final && state.syncClaudeMem && state.syncClaudeMemBack)
|
|
82
86
|
summary.claudeMem = memSync(dataPath, state, 'out');
|
|
83
87
|
writeSyncState(dataPath, state);
|
|
@@ -6,6 +6,7 @@ declare const SyncStateSchema: z.ZodObject<{
|
|
|
6
6
|
syncHistory: z.ZodOptional<z.ZodBoolean>;
|
|
7
7
|
syncClaudeMem: z.ZodOptional<z.ZodBoolean>;
|
|
8
8
|
syncClaudeMemBack: z.ZodOptional<z.ZodBoolean>;
|
|
9
|
+
sharePlugins: z.ZodOptional<z.ZodBoolean>;
|
|
9
10
|
historyScope: z.ZodOptional<z.ZodEnum<{
|
|
10
11
|
project: "project";
|
|
11
12
|
all: "all";
|
package/dist/sync/sync-state.js
CHANGED
|
@@ -14,6 +14,7 @@ const SyncStateSchema = z.object({
|
|
|
14
14
|
syncHistory: z.boolean().optional(),
|
|
15
15
|
syncClaudeMem: z.boolean().optional(),
|
|
16
16
|
syncClaudeMemBack: z.boolean().optional(),
|
|
17
|
+
sharePlugins: z.boolean().optional(),
|
|
17
18
|
historyScope: z.enum(['project', 'all']).optional(),
|
|
18
19
|
/** Newest claude-mem database time on each side right after the last sync (detects edits on both sides). */
|
|
19
20
|
memHostStamp: z.number().optional(),
|
package/dist/sync/watcher.js
CHANGED
|
@@ -17,6 +17,7 @@ import { autoRestartAllowed, causeSince, KeepAwake, LifeRecord, saveCrashReport,
|
|
|
17
17
|
import { SandboxChannel } from '../host/channel/index.js';
|
|
18
18
|
import { ProjectRegistry } from '../host/projects/registry.js';
|
|
19
19
|
import { storageOf } from '../host/storage/index.js';
|
|
20
|
+
import { clearSecrets } from '../host/secrets/index.js';
|
|
20
21
|
import { endSharing, sharingDeps } from '../host/sharing/index.js';
|
|
21
22
|
import { PACKAGE_ROOT } from '../core/package-info.js';
|
|
22
23
|
import { syncBack } from './sync-cycle.js';
|
|
@@ -261,6 +262,15 @@ export class Watcher {
|
|
|
261
262
|
catch {
|
|
262
263
|
/* best effort */
|
|
263
264
|
}
|
|
265
|
+
// One-shot secrets the sandbox never read (it stopped early) and any login copy left in a launch folder.
|
|
266
|
+
try {
|
|
267
|
+
// Not when a new sandbox already started: its own files are there.
|
|
268
|
+
if (!isSandboxRunning())
|
|
269
|
+
clearSecrets(this.storageRoot, this.dataPath);
|
|
270
|
+
}
|
|
271
|
+
catch (e) {
|
|
272
|
+
this.note('could not remove the one-shot secrets: ' + errMsg(e));
|
|
273
|
+
}
|
|
264
274
|
// An all-users install: the record of whose sandbox this was goes, and the group loses access to the folders.
|
|
265
275
|
const sharing = sharingDeps(PACKAGE_ROOT);
|
|
266
276
|
if (sharing)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en" data-bs-theme="dark">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
|
+
<title>Sandbox</title>
|
|
7
|
+
<link rel="stylesheet" href="/main-VLR7DVQ4.css" />
|
|
8
|
+
<script type="module" src="/main-CXESL347.js"></script>
|
|
9
|
+
</head>
|
|
10
|
+
<body>
|
|
11
|
+
<div id="root"></div>
|
|
12
|
+
</body>
|
|
13
|
+
</html>
|