windows-development-sandbox 1.5.0 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/config.example.json +27 -1
- package/dist/app/context.d.ts +8 -0
- package/dist/app/context.js +12 -0
- package/dist/app/features/defs.d.ts +322 -0
- package/dist/app/features/defs.js +28 -0
- package/dist/app/features/sandbox/index.d.ts +2 -0
- package/dist/app/features/sandbox/index.js +3 -0
- package/dist/app/features/sandbox/sandbox.def.d.ts +193 -0
- package/dist/app/features/sandbox/sandbox.def.js +245 -0
- package/dist/app/features/sandbox/sandbox.run.d.ts +72 -0
- package/dist/app/features/sandbox/sandbox.run.js +98 -0
- package/dist/app/features/sessions/index.d.ts +2 -0
- package/dist/app/features/sessions/index.js +3 -0
- package/dist/app/features/sessions/sessions.def.d.ts +141 -0
- package/dist/app/features/sessions/sessions.def.js +176 -0
- package/dist/app/features/sessions/sessions.run.d.ts +39 -0
- package/dist/app/features/sessions/sessions.run.js +58 -0
- package/dist/{cli/menu/settings/categories.d.ts → app/features/settings/categories.def.d.ts} +4 -0
- package/dist/{cli/menu/settings/categories.js → app/features/settings/categories.def.js} +40 -46
- package/dist/app/features/settings/index.d.ts +5 -0
- package/dist/app/features/settings/index.js +6 -0
- package/dist/{cli/menu/settings/config-file.d.ts → app/features/settings/settings-file.d.ts} +1 -1
- package/dist/{cli/menu/settings/config-file.js → app/features/settings/settings-file.js} +1 -1
- package/dist/app/features/settings/settings-rows.d.ts +35 -0
- package/dist/app/features/settings/settings-rows.js +94 -0
- package/dist/app/features/settings/settings.def.d.ts +157 -0
- package/dist/app/features/settings/settings.def.js +179 -0
- package/dist/app/features/settings/settings.run.d.ts +67 -0
- package/dist/app/features/settings/settings.run.js +84 -0
- package/dist/app/kernel/define.d.ts +143 -0
- package/dist/app/kernel/define.js +42 -0
- package/dist/app/kernel/errors.d.ts +34 -0
- package/dist/app/kernel/errors.js +45 -0
- package/dist/app/kernel/fields.d.ts +70 -0
- package/dist/app/kernel/fields.js +243 -0
- package/dist/app/kernel/index.d.ts +8 -0
- package/dist/app/kernel/index.js +10 -0
- package/dist/app/kernel/io.d.ts +193 -0
- package/dist/app/kernel/io.js +126 -0
- package/dist/app/kernel/rpc.d.ts +156 -0
- package/dist/app/kernel/rpc.js +47 -0
- package/dist/{cli/menu/settings → app/kernel}/schema-node.d.ts +9 -0
- package/dist/{cli/menu/settings → app/kernel}/schema-node.js +26 -0
- package/dist/app/kernel/text.d.ts +6 -0
- package/dist/app/kernel/text.js +57 -0
- package/dist/app/kernel/view.d.ts +146 -0
- package/dist/app/kernel/view.js +28 -0
- package/dist/app/registry.d.ts +10 -0
- package/dist/app/registry.js +50 -0
- package/dist/cli/args.d.ts +18 -2
- package/dist/cli/args.js +101 -24
- package/dist/cli/commands/accounts.js +45 -17
- package/dist/cli/commands/context.d.ts +2 -0
- package/dist/cli/commands/context.js +9 -2
- package/dist/cli/commands/data/clean.js +32 -9
- package/dist/cli/commands/engine.d.ts +2 -0
- package/dist/cli/commands/engine.js +60 -0
- package/dist/cli/commands/index.d.ts +2 -1
- package/dist/cli/commands/index.js +2 -1
- package/dist/cli/commands/launch/add-root.d.ts +3 -2
- package/dist/cli/commands/launch/add-root.js +11 -10
- package/dist/cli/commands/launch/launch.js +102 -9
- package/dist/cli/commands/launch/prepare.js +6 -4
- package/dist/cli/commands/launch/running.js +2 -1
- package/dist/cli/commands/launch/summary.d.ts +2 -0
- package/dist/cli/commands/maintenance/audit.js +1 -1
- package/dist/cli/commands/maintenance/clean.d.ts +1 -1
- package/dist/cli/commands/maintenance/clean.js +17 -3
- package/dist/cli/commands/maintenance/config-share.d.ts +12 -0
- package/dist/cli/commands/maintenance/config-share.js +80 -0
- package/dist/cli/commands/maintenance/config.d.ts +1 -1
- package/dist/cli/commands/maintenance/config.js +38 -10
- package/dist/cli/commands/maintenance/doctor.d.ts +1 -1
- package/dist/cli/commands/maintenance/doctor.js +2 -4
- package/dist/cli/commands/maintenance/logs.js +14 -0
- package/dist/cli/commands/maintenance/migrate.d.ts +2 -1
- package/dist/cli/commands/maintenance/migrate.js +19 -4
- package/dist/cli/commands/maintenance/sync.js +2 -0
- package/dist/cli/commands/maintenance/update.d.ts +2 -0
- package/dist/cli/commands/maintenance/update.js +27 -4
- package/dist/cli/commands/projects/here.js +12 -7
- package/dist/cli/commands/projects/projects.js +26 -17
- package/dist/cli/commands/registry.js +10 -7
- package/dist/cli/commands/repair/checks/agents.d.ts +2 -0
- package/dist/cli/commands/repair/checks/agents.js +70 -0
- package/dist/cli/commands/repair/checks/common.d.ts +8 -0
- package/dist/cli/commands/repair/checks/common.js +22 -0
- package/dist/cli/commands/repair/checks/contained.d.ts +2 -0
- package/dist/cli/commands/repair/checks/contained.js +139 -0
- package/dist/cli/commands/repair/checks/data.d.ts +2 -0
- package/dist/cli/commands/repair/checks/data.js +241 -0
- package/dist/cli/commands/repair/checks/hcs.d.ts +7 -0
- package/dist/cli/commands/repair/checks/hcs.js +28 -0
- package/dist/cli/commands/repair/checks/index.d.ts +2 -0
- package/dist/cli/commands/repair/checks/index.js +24 -0
- package/dist/cli/commands/repair/checks/install.d.ts +5 -0
- package/dist/cli/commands/repair/checks/install.js +318 -0
- package/dist/cli/commands/repair/checks/machine.d.ts +2 -0
- package/dist/cli/commands/repair/checks/machine.js +232 -0
- package/dist/cli/commands/repair/checks/network.d.ts +6 -0
- package/dist/cli/commands/repair/checks/network.js +60 -0
- package/dist/cli/commands/repair/checks/pc.d.ts +4 -0
- package/dist/cli/commands/repair/checks/pc.js +86 -0
- package/dist/cli/commands/repair/checks/sandbox.d.ts +2 -0
- package/dist/cli/commands/repair/checks/sandbox.js +282 -0
- package/dist/cli/commands/repair/checks/settings.d.ts +2 -0
- package/dist/cli/commands/repair/checks/settings.js +169 -0
- package/dist/cli/commands/repair/checks/vpn.d.ts +2 -0
- package/dist/cli/commands/repair/checks/vpn.js +78 -0
- package/dist/cli/commands/repair/engine.d.ts +32 -0
- package/dist/cli/commands/repair/engine.js +127 -0
- package/dist/cli/commands/repair/env.d.ts +7 -0
- package/dist/cli/commands/repair/env.js +50 -0
- package/dist/cli/commands/repair/index.d.ts +1 -9
- package/dist/cli/commands/repair/index.js +2 -54
- package/dist/cli/commands/repair/log.d.ts +17 -0
- package/dist/cli/commands/repair/log.js +82 -0
- package/dist/cli/commands/repair/printer.d.ts +32 -0
- package/dist/cli/commands/repair/printer.js +132 -0
- package/dist/cli/commands/repair/run.d.ts +33 -0
- package/dist/cli/commands/repair/run.js +133 -0
- package/dist/cli/commands/repair/types.d.ts +97 -9
- package/dist/cli/commands/repair/types.js +11 -7
- package/dist/cli/commands/resume.js +2 -2
- package/dist/cli/commands/sessions/index.d.ts +0 -4
- package/dist/cli/commands/sessions/index.js +3 -7
- package/dist/cli/commands/setup/index.d.ts +5 -0
- package/dist/cli/commands/setup/index.js +25 -1
- package/dist/cli/commands/shared-use.d.ts +5 -2
- package/dist/cli/commands/shared-use.js +11 -8
- package/dist/cli/commands/storage/contained.d.ts +3 -0
- package/dist/cli/commands/storage/contained.js +179 -0
- package/dist/cli/commands/storage/index.d.ts +2 -0
- package/dist/cli/commands/storage/index.js +2 -0
- package/dist/cli/commands/storage/offer.d.ts +3 -0
- package/dist/cli/commands/storage/offer.js +91 -0
- package/dist/cli/commands/storage/storage.d.ts +8 -0
- package/dist/cli/commands/storage/storage.js +179 -0
- package/dist/cli/commands/user-config.js +2 -2
- package/dist/cli/commands/vpn.d.ts +4 -0
- package/dist/cli/commands/vpn.js +91 -0
- package/dist/cli/commands/web.d.ts +4 -0
- package/dist/cli/commands/web.js +97 -0
- package/dist/cli/history.js +1 -1
- package/dist/cli/index.js +48 -4
- package/dist/cli/manifest.d.ts +339 -97
- package/dist/cli/manifest.js +222 -67
- package/dist/cli/menu/add-agent.d.ts +47 -0
- package/dist/cli/menu/add-agent.js +168 -0
- package/dist/cli/menu/apps.d.ts +38 -3
- package/dist/cli/menu/apps.js +80 -5
- package/dist/cli/menu/command-fields.d.ts +18 -0
- package/dist/cli/menu/command-fields.js +61 -0
- package/dist/cli/menu/command-form.d.ts +22 -0
- package/dist/cli/menu/command-form.js +169 -46
- package/dist/cli/menu/data-folder.d.ts +18 -0
- package/dist/cli/menu/data-folder.js +99 -0
- package/dist/cli/menu/io-menu.d.ts +29 -0
- package/dist/cli/menu/io-menu.js +126 -0
- package/dist/cli/menu/live.d.ts +27 -0
- package/dist/cli/menu/live.js +69 -0
- package/dist/cli/menu/memory.d.ts +19 -0
- package/dist/cli/menu/memory.js +53 -0
- package/dist/cli/menu/menu.d.ts +11 -2
- package/dist/cli/menu/menu.js +36 -15
- package/dist/cli/menu/pages/accounts-page.js +55 -24
- package/dist/cli/menu/pages/agents-page.d.ts +68 -0
- package/dist/cli/menu/pages/agents-page.js +345 -0
- package/dist/cli/menu/pages/apps-page.d.ts +3 -1
- package/dist/cli/menu/pages/apps-page.js +20 -4
- package/dist/cli/menu/pages/list-page.d.ts +43 -3
- package/dist/cli/menu/pages/list-page.js +146 -12
- package/dist/cli/menu/pages/maintenance-page.d.ts +9 -5
- package/dist/cli/menu/pages/maintenance-page.js +172 -85
- package/dist/cli/menu/pages/sandbox-page.d.ts +7 -6
- package/dist/cli/menu/pages/sandbox-page.js +117 -120
- package/dist/cli/menu/pages/scopes.d.ts +1 -1
- package/dist/cli/menu/pages/sessions-page.d.ts +6 -8
- package/dist/cli/menu/pages/sessions-page.js +22 -75
- package/dist/cli/menu/pages/settings-page.d.ts +10 -14
- package/dist/cli/menu/pages/settings-page.js +95 -102
- package/dist/cli/menu/render-view.d.ts +28 -0
- package/dist/cli/menu/render-view.js +112 -0
- package/dist/cli/menu/settings/ask-path.d.ts +14 -0
- package/dist/cli/menu/settings/ask-path.js +14 -0
- package/dist/cli/menu/settings/collections/collection-editor.d.ts +8 -2
- package/dist/cli/menu/settings/collections/collection-editor.js +12 -8
- package/dist/cli/menu/settings/collections/map-editor.js +5 -1
- package/dist/cli/menu/settings/collections/object-list-editor.js +2 -2
- package/dist/cli/menu/settings/collections/object-map-editor.js +2 -2
- package/dist/cli/menu/settings/collections/string-list-editor.d.ts +10 -1
- package/dist/cli/menu/settings/collections/string-list-editor.js +23 -0
- package/dist/cli/menu/settings/draft.d.ts +1 -1
- package/dist/cli/menu/settings/format.d.ts +1 -3
- package/dist/cli/menu/settings/format.js +6 -36
- package/dist/cli/menu/settings/index.d.ts +1 -3
- package/dist/cli/menu/settings/index.js +3 -3
- package/dist/cli/menu/settings/object-editor.d.ts +6 -2
- package/dist/cli/menu/settings/object-editor.js +15 -4
- package/dist/cli/menu/settings/share.d.ts +36 -0
- package/dist/cli/menu/settings/share.js +131 -0
- package/dist/cli/menu/settings/value-editor.d.ts +10 -1
- package/dist/cli/menu/settings/value-editor.js +99 -63
- package/dist/cli/menu/several.js +7 -5
- package/dist/cli/menu/share-settings.d.ts +21 -0
- package/dist/cli/menu/share-settings.js +112 -0
- package/dist/cli/menu/shell.d.ts +53 -10
- package/dist/cli/menu/shell.js +115 -10
- package/dist/cli/menu/views.d.ts +7 -0
- package/dist/cli/menu/views.js +11 -0
- package/dist/cli/menu/vpn-login.d.ts +16 -0
- package/dist/cli/menu/vpn-login.js +74 -0
- package/dist/cli/operations/handler.d.ts +6 -0
- package/dist/cli/operations/handler.js +61 -0
- package/dist/cli/operations/index.d.ts +4 -0
- package/dist/cli/operations/index.js +5 -0
- package/dist/cli/operations/input.d.ts +6 -0
- package/dist/cli/operations/input.js +37 -0
- package/dist/cli/operations/io-cli.d.ts +7 -0
- package/dist/cli/operations/io-cli.js +62 -0
- package/dist/cli/operations/spec.d.ts +18 -0
- package/dist/cli/operations/spec.js +108 -0
- package/dist/cli/output/colors.d.ts +2 -2
- package/dist/cli/output/colors.js +2 -11
- package/dist/cli/output/index.d.ts +1 -0
- package/dist/cli/output/index.js +1 -0
- package/dist/cli/output/print.d.ts +5 -1
- package/dist/cli/output/print.js +15 -4
- package/dist/cli/output/progress.d.ts +15 -0
- package/dist/cli/output/progress.js +44 -0
- package/dist/cli/output/render-view.d.ts +4 -0
- package/dist/cli/output/render-view.js +63 -0
- package/dist/cli/services/accounts-service.d.ts +2 -0
- package/dist/cli/services/accounts-service.js +2 -2
- package/dist/cli/services/agent-commands-service.d.ts +2 -0
- package/dist/cli/services/agent-commands-service.js +11 -2
- package/dist/cli/services/health-service.d.ts +0 -6
- package/dist/cli/services/health-service.js +5 -42
- package/dist/cli/services/index.d.ts +3 -1
- package/dist/cli/services/index.js +3 -1
- package/dist/cli/services/logs-service.js +4 -3
- package/dist/cli/services/migrate-service.js +1 -1
- package/dist/cli/services/update-service.d.ts +2 -0
- package/dist/cli/services/update-service.js +13 -6
- package/dist/cli/services/vpn-service.d.ts +28 -0
- package/dist/cli/services/vpn-service.js +46 -0
- package/dist/cli/services/web-service.d.ts +22 -0
- package/dist/cli/services/web-service.js +111 -0
- package/dist/cli/tui/app.d.ts +12 -4
- package/dist/cli/tui/app.js +38 -9
- package/dist/cli/tui/dialogs/path-listing.d.ts +43 -0
- package/dist/cli/tui/dialogs/path-listing.js +127 -0
- package/dist/cli/tui/dialogs/path-picker.d.ts +67 -0
- package/dist/cli/tui/dialogs/path-picker.js +423 -0
- package/dist/cli/tui/dialogs/text-screen.d.ts +6 -0
- package/dist/cli/tui/dialogs/text-screen.js +10 -3
- package/dist/cli/tui/frame.d.ts +7 -10
- package/dist/cli/tui/frame.js +19 -10
- package/dist/cli/tui/index.d.ts +4 -3
- package/dist/cli/tui/index.js +2 -1
- package/dist/cli/tui/list/list-screen.d.ts +28 -2
- package/dist/cli/tui/list/list-screen.js +130 -66
- package/dist/cli/tui/list/list-types.d.ts +10 -4
- package/dist/cli/tui/nav.d.ts +29 -0
- package/dist/cli/tui/nav.js +67 -0
- package/dist/cli/tui/terminal.d.ts +7 -0
- package/dist/cli/tui/terminal.js +30 -10
- package/dist/cli/validate.d.ts +1 -1
- package/dist/cli/validate.js +3 -3
- package/dist/cli/version.d.ts +2 -0
- package/dist/cli/version.js +11 -0
- package/dist/core/config/defaults.js +13 -1
- package/dist/core/config/loader.js +12 -2
- package/dist/core/local-config/overrides.js +1 -0
- package/dist/core/prompt.d.ts +19 -0
- package/dist/core/prompt.js +43 -3
- package/dist/core/schema/common.d.ts +6 -0
- package/dist/core/schema/common.js +8 -0
- package/dist/core/schema/config.d.ts +36 -0
- package/dist/core/schema/config.js +26 -2
- package/dist/core/schema/harness.d.ts +2 -0
- package/dist/core/schema/harness.js +13 -2
- package/dist/core/schema/index.d.ts +3 -1
- package/dist/core/schema/index.js +3 -1
- package/dist/core/schema/profile.d.ts +1 -0
- package/dist/core/schema/profile.js +3 -0
- package/dist/core/schema/redact.d.ts +13 -0
- package/dist/core/schema/redact.js +75 -0
- package/dist/core/schema/sandbox.d.ts +6 -0
- package/dist/core/schema/sandbox.js +21 -3
- package/dist/core/schema/vpn.d.ts +18 -0
- package/dist/core/schema/vpn.js +22 -0
- package/dist/core/schema/web.d.ts +6 -0
- package/dist/core/schema/web.js +14 -0
- package/dist/core/types.d.ts +44 -0
- package/dist/core/util/fs.d.ts +2 -0
- package/dist/core/util/fs.js +9 -0
- package/dist/core/util/index.d.ts +1 -1
- package/dist/core/util/index.js +1 -1
- package/dist/guest/agents/agent-files.d.ts +54 -0
- package/dist/guest/agents/agent-files.js +67 -0
- package/dist/guest/agents/agent-installer.js +2 -9
- package/dist/guest/agents/local-state.d.ts +14 -0
- package/dist/guest/agents/local-state.js +218 -0
- package/dist/guest/agents/sbx-agent.d.ts +2 -0
- package/dist/guest/agents/sbx-agent.js +35 -0
- package/dist/guest/boot/boot.d.ts +4 -0
- package/dist/guest/boot/boot.js +51 -11
- package/dist/guest/daemon/daemon.js +8 -1
- package/dist/guest/daemon/exec.js +2 -1
- package/dist/guest/daemon/idle-shutdown.js +2 -0
- package/dist/guest/daemon/sessions.d.ts +5 -0
- package/dist/guest/daemon/sessions.js +20 -3
- package/dist/guest/entries/agent.d.ts +1 -0
- package/dist/guest/entries/agent.js +10 -0
- package/dist/guest/entries/daemon.js +5 -0
- package/dist/guest/governor/decide.d.ts +61 -0
- package/dist/guest/governor/decide.js +182 -0
- package/dist/guest/governor/governor.d.ts +42 -0
- package/dist/guest/governor/governor.js +214 -0
- package/dist/guest/governor/index.d.ts +2 -0
- package/dist/guest/governor/index.js +2 -0
- package/dist/guest/runtime/csc.d.ts +2 -0
- package/dist/guest/runtime/csc.js +2 -0
- package/dist/guest/runtime/secrets.d.ts +12 -0
- package/dist/guest/runtime/secrets.js +63 -0
- package/dist/guest/sessions/viewer.js +3 -1
- package/dist/guest/setup/claude-profile.d.ts +2 -1
- package/dist/guest/setup/claude-profile.js +12 -1
- package/dist/guest/setup/environment.d.ts +6 -0
- package/dist/guest/setup/environment.js +56 -6
- package/dist/guest/setup/path-plan.d.ts +32 -0
- package/dist/guest/setup/path-plan.js +67 -0
- package/dist/guest/setup/shell-path.d.ts +1 -0
- package/dist/guest/setup/shell-path.js +22 -0
- package/dist/guest/toolchains/languages/python.js +1 -1
- package/dist/guest/toolchains/native/rust-extras.js +4 -2
- package/dist/guest/toolchains/runtimes.js +2 -2
- package/dist/guest/vpn/index.d.ts +1 -0
- package/dist/guest/vpn/index.js +1 -0
- package/dist/guest/vpn/openvpn.d.ts +9 -0
- package/dist/guest/vpn/openvpn.js +47 -0
- package/dist/guest/vpn/tunnel.d.ts +17 -0
- package/dist/guest/vpn/tunnel.js +78 -0
- package/dist/guest/vpn/vpn.d.ts +6 -0
- package/dist/guest/vpn/vpn.js +174 -0
- package/dist/guest/vpn/wireguard.d.ts +32 -0
- package/dist/guest/vpn/wireguard.js +132 -0
- package/dist/host/agent-commands/commands.d.ts +4 -0
- package/dist/host/agent-commands/commands.js +31 -7
- package/dist/host/audit/log.d.ts +1 -1
- package/dist/host/channel/attach.d.ts +6 -2
- package/dist/host/channel/attach.js +6 -3
- package/dist/host/channel/channel.d.ts +9 -0
- package/dist/host/channel/channel.js +30 -2
- package/dist/host/engines/engine.d.ts +12 -0
- package/dist/host/engines/engine.js +1 -0
- package/dist/host/engines/hcs/check.d.ts +25 -0
- package/dist/host/engines/hcs/check.js +95 -0
- package/dist/host/engines/hcs/documents.d.ts +44 -0
- package/dist/host/engines/hcs/documents.js +155 -0
- package/dist/host/engines/hcs/engine.d.ts +39 -0
- package/dist/host/engines/hcs/engine.js +171 -0
- package/dist/host/engines/hcs/helper.d.ts +43 -0
- package/dist/host/engines/hcs/helper.js +173 -0
- package/dist/host/engines/hcs/images.d.ts +37 -0
- package/dist/host/engines/hcs/images.js +152 -0
- package/dist/host/engines/index.d.ts +7 -0
- package/dist/host/engines/index.js +5 -0
- package/dist/host/engines/registry.d.ts +16 -0
- package/dist/host/engines/registry.js +30 -0
- package/dist/host/engines/types.d.ts +58 -0
- package/dist/host/engines/types.js +1 -0
- package/dist/host/engines/windows-sandbox/engine.d.ts +16 -0
- package/dist/host/engines/windows-sandbox/engine.js +63 -0
- package/dist/host/engines/windows-sandbox/wsb-text.d.ts +2 -0
- package/dist/host/engines/windows-sandbox/wsb-text.js +29 -0
- package/dist/host/health/acl-read.d.ts +17 -0
- package/dist/host/health/acl-read.js +45 -0
- package/dist/host/health/config-backup.d.ts +11 -0
- package/dist/host/health/config-backup.js +73 -0
- package/dist/host/health/index.d.ts +6 -0
- package/dist/host/health/index.js +7 -0
- package/dist/host/health/install-state.d.ts +33 -0
- package/dist/host/health/install-state.js +110 -0
- package/dist/host/health/path-copies.d.ts +32 -0
- package/dist/host/health/path-copies.js +82 -0
- package/dist/host/health/stale.d.ts +45 -0
- package/dist/host/health/stale.js +120 -0
- package/dist/host/health/system.d.ts +37 -0
- package/dist/host/health/system.js +87 -0
- package/dist/host/install/copies.d.ts +13 -0
- package/dist/host/install/copies.js +63 -0
- package/dist/host/install/index.d.ts +1 -0
- package/dist/host/install/index.js +1 -0
- package/dist/host/launch/generate.d.ts +5 -1
- package/dist/host/launch/generate.js +73 -7
- package/dist/host/launch/index.d.ts +3 -1
- package/dist/host/launch/index.js +3 -1
- package/dist/host/launch/launch-plan.d.ts +13 -0
- package/dist/host/launch/launch-plan.js +26 -0
- package/dist/host/launch/mappings.js +2 -1
- package/dist/host/launch/risk-notes.d.ts +10 -0
- package/dist/host/launch/risk-notes.js +18 -0
- package/dist/host/launch/session-file.d.ts +2 -0
- package/dist/host/launch/session-file.js +11 -2
- package/dist/host/launch/stage.js +1 -1
- package/dist/host/launch/wsb-file.d.ts +28 -4
- package/dist/host/launch/wsb-file.js +61 -42
- package/dist/host/life/crash-report.d.ts +27 -1
- package/dist/host/life/crash-report.js +173 -7
- package/dist/host/life/host-memory.d.ts +40 -0
- package/dist/host/life/host-memory.js +137 -0
- package/dist/host/life/index.d.ts +2 -0
- package/dist/host/life/index.js +2 -0
- package/dist/host/life/stop-events.d.ts +2 -0
- package/dist/host/life/stop-events.js +20 -3
- package/dist/host/life/stop-warning.js +1 -1
- package/dist/host/life/watchdog.d.ts +54 -0
- package/dist/host/life/watchdog.js +108 -0
- package/dist/host/migrate/backup.js +3 -0
- package/dist/host/migrate/migrations/config-file.d.ts +2 -0
- package/dist/host/migrate/migrations/config-file.js +7 -0
- package/dist/host/migrate/migrations/follow-machine-storage.js +9 -1
- package/dist/host/migrate/migrations/pin-storage-root.d.ts +4 -0
- package/dist/host/migrate/migrations/pin-storage-root.js +46 -0
- package/dist/host/migrate/migrations/unpin-config-defaults.js +4 -1
- package/dist/host/migrate/registry.js +2 -1
- package/dist/host/native.d.ts +3 -2
- package/dist/host/native.js +22 -3
- package/dist/host/profile/accounts.d.ts +25 -1
- package/dist/host/profile/accounts.js +96 -13
- package/dist/host/profile/agent-accounts.d.ts +5 -1
- package/dist/host/profile/agent-accounts.js +35 -5
- package/dist/host/profile/claude-login.js +3 -2
- package/dist/host/profile/index.d.ts +2 -1
- package/dist/host/profile/index.js +1 -0
- package/dist/host/profile/plugin-share.d.ts +26 -0
- package/dist/host/profile/plugin-share.js +146 -0
- package/dist/host/projects/join.d.ts +7 -1
- package/dist/host/projects/join.js +21 -4
- package/dist/host/projects/registry.d.ts +16 -10
- package/dist/host/projects/registry.js +74 -6
- package/dist/host/sandbox/contained-deps.d.ts +2 -0
- package/dist/host/sandbox/contained-deps.js +17 -0
- package/dist/host/sandbox/index.d.ts +2 -0
- package/dist/host/sandbox/index.js +2 -0
- package/dist/host/sandbox/platform.d.ts +4 -0
- package/dist/host/sandbox/platform.js +23 -4
- package/dist/host/sandbox/tasklist.d.ts +13 -0
- package/dist/host/sandbox/tasklist.js +47 -0
- package/dist/host/secrets/index.d.ts +2 -0
- package/dist/host/secrets/index.js +2 -0
- package/dist/host/secrets/launch-secrets.d.ts +17 -0
- package/dist/host/secrets/launch-secrets.js +94 -0
- package/dist/host/secrets/secret-store.d.ts +25 -0
- package/dist/host/secrets/secret-store.js +89 -0
- package/dist/host/sharing/acl.d.ts +16 -2
- package/dist/host/sharing/acl.js +35 -10
- package/dist/host/sharing/current.js +8 -3
- package/dist/host/sharing/doctor.d.ts +2 -0
- package/dist/host/sharing/doctor.js +44 -0
- package/dist/host/sharing/group-access.d.ts +6 -0
- package/dist/host/sharing/group-access.js +24 -0
- package/dist/host/sharing/index.d.ts +2 -1
- package/dist/host/sharing/index.js +2 -1
- package/dist/host/sharing/lifecycle.d.ts +8 -2
- package/dist/host/sharing/lifecycle.js +16 -7
- package/dist/host/storage/cleanup.d.ts +2 -0
- package/dist/host/storage/cleanup.js +2 -1
- package/dist/host/storage/contained/check.d.ts +9 -0
- package/dist/host/storage/contained/check.js +37 -0
- package/dist/host/storage/contained/contained-storage.d.ts +66 -0
- package/dist/host/storage/contained/contained-storage.js +168 -0
- package/dist/host/storage/contained/disk-port.d.ts +43 -0
- package/dist/host/storage/contained/disk-port.js +122 -0
- package/dist/host/storage/contained/index.d.ts +9 -0
- package/dist/host/storage/contained/index.js +8 -0
- package/dist/host/storage/contained/layout.d.ts +28 -0
- package/dist/host/storage/contained/layout.js +45 -0
- package/dist/host/storage/contained/resolve.d.ts +4 -0
- package/dist/host/storage/contained/resolve.js +30 -0
- package/dist/host/storage/contained/setting.d.ts +1 -0
- package/dist/host/storage/contained/setting.js +5 -0
- package/dist/host/storage/contained/state.d.ts +89 -0
- package/dist/host/storage/contained/state.js +166 -0
- package/dist/host/storage/contained/transfer.d.ts +24 -0
- package/dist/host/storage/contained/transfer.js +121 -0
- package/dist/host/storage/history.d.ts +21 -0
- package/dist/host/storage/history.js +49 -0
- package/dist/host/storage/index.d.ts +6 -0
- package/dist/host/storage/index.js +6 -0
- package/dist/host/storage/move.d.ts +95 -0
- package/dist/host/storage/move.js +384 -0
- package/dist/host/storage/offer.d.ts +11 -0
- package/dist/host/storage/offer.js +36 -0
- package/dist/host/storage/providers/contained.d.ts +15 -0
- package/dist/host/storage/providers/contained.js +39 -0
- package/dist/host/storage/providers/folder.d.ts +12 -0
- package/dist/host/storage/providers/folder.js +20 -0
- package/dist/host/storage/providers/index.d.ts +4 -0
- package/dist/host/storage/providers/index.js +3 -0
- package/dist/host/storage/providers/registry.d.ts +9 -0
- package/dist/host/storage/providers/registry.js +14 -0
- package/dist/host/storage/providers/types.d.ts +33 -0
- package/dist/host/storage/providers/types.js +1 -0
- package/dist/host/storage/root.d.ts +18 -0
- package/dist/host/storage/root.js +77 -0
- package/dist/host/tools/conpty.js +3 -2
- package/dist/host/tools/windows-terminal.d.ts +2 -0
- package/dist/host/tools/windows-terminal.js +31 -12
- package/dist/host/update/index.d.ts +1 -1
- package/dist/host/update/index.js +1 -1
- package/dist/host/update/notice.d.ts +2 -0
- package/dist/host/update/notice.js +13 -1
- package/dist/host/update/update-state.d.ts +6 -0
- package/dist/host/update/update-state.js +2 -0
- package/dist/host/update/updater.d.ts +19 -0
- package/dist/host/update/updater.js +88 -12
- package/dist/host/vpn/index.d.ts +4 -0
- package/dist/host/vpn/index.js +4 -0
- package/dist/host/vpn/login.d.ts +24 -0
- package/dist/host/vpn/login.js +79 -0
- package/dist/host/vpn/nordvpn.d.ts +21 -0
- package/dist/host/vpn/nordvpn.js +77 -0
- package/dist/host/vpn/prepare.d.ts +19 -0
- package/dist/host/vpn/prepare.js +138 -0
- package/dist/host/vpn/status.d.ts +12 -0
- package/dist/host/vpn/status.js +53 -0
- package/dist/host/web/auth.d.ts +38 -0
- package/dist/host/web/auth.js +96 -0
- package/dist/host/web/backend.d.ts +14 -0
- package/dist/host/web/backend.js +1 -0
- package/dist/host/web/bridge.d.ts +27 -0
- package/dist/host/web/bridge.js +144 -0
- package/dist/host/web/browser.d.ts +3 -0
- package/dist/host/web/browser.js +23 -0
- package/dist/host/web/control.d.ts +17 -0
- package/dist/host/web/control.js +67 -0
- package/dist/host/web/index.d.ts +10 -0
- package/dist/host/web/index.js +9 -0
- package/dist/host/web/rpc.d.ts +24 -0
- package/dist/host/web/rpc.js +149 -0
- package/dist/host/web/runner.d.ts +16 -0
- package/dist/host/web/runner.js +44 -0
- package/dist/host/web/server.d.ts +47 -0
- package/dist/host/web/server.js +238 -0
- package/dist/host/web/state.d.ts +20 -0
- package/dist/host/web/state.js +41 -0
- package/dist/host/web/static-files.d.ts +13 -0
- package/dist/host/web/static-files.js +57 -0
- package/dist/runtime/agent.js +27675 -0
- package/dist/runtime/daemon.js +1950 -1122
- package/dist/runtime/db.js +302 -111
- package/dist/runtime/main.js +1560 -275
- package/dist/runtime/netproxy.js +168 -8
- package/dist/runtime/view.js +186 -13
- package/dist/selftest/accounts.test.js +40 -0
- package/dist/selftest/agent-paths.test.d.ts +2 -0
- package/dist/selftest/agent-paths.test.js +125 -0
- package/dist/selftest/app.test.d.ts +2 -0
- package/dist/selftest/app.test.js +324 -0
- package/dist/selftest/channel.test.js +18 -0
- package/dist/selftest/cli.test.js +35 -4
- package/dist/selftest/config.test.js +59 -0
- package/dist/selftest/contained.test.d.ts +2 -0
- package/dist/selftest/contained.test.js +544 -0
- package/dist/selftest/credentials.test.d.ts +2 -0
- package/dist/selftest/credentials.test.js +198 -0
- package/dist/selftest/engine.test.d.ts +2 -0
- package/dist/selftest/engine.test.js +127 -0
- package/dist/selftest/generate.test.js +1 -1
- package/dist/selftest/hcs.test.d.ts +2 -0
- package/dist/selftest/hcs.test.js +482 -0
- package/dist/selftest/health.test.d.ts +2 -0
- package/dist/selftest/health.test.js +470 -0
- package/dist/selftest/heavy-load.test.d.ts +2 -0
- package/dist/selftest/heavy-load.test.js +329 -0
- package/dist/selftest/host-sim.test.js +2 -0
- package/dist/selftest/index.js +31 -0
- package/dist/selftest/layout.test.js +14 -0
- package/dist/selftest/menu-perf.test.d.ts +2 -0
- package/dist/selftest/menu-perf.test.js +248 -0
- package/dist/selftest/menu-screens.d.ts +7 -0
- package/dist/selftest/menu-screens.js +68 -17
- package/dist/selftest/menu.test.js +603 -22
- package/dist/selftest/migrate.test.js +1 -1
- package/dist/selftest/personalization.test.js +3 -1
- package/dist/selftest/projects.test.js +39 -1
- package/dist/selftest/shared-use.test.js +64 -2
- package/dist/selftest/sharing.test.js +50 -1
- package/dist/selftest/storage.test.d.ts +2 -0
- package/dist/selftest/storage.test.js +363 -0
- package/dist/selftest/support/engine-cases.d.ts +8 -0
- package/dist/selftest/support/engine-cases.js +65 -0
- package/dist/selftest/support/engine-golden.d.ts +3 -0
- package/dist/selftest/support/engine-golden.js +66 -0
- package/dist/selftest/support/fixtures.d.ts +20 -0
- package/dist/selftest/support/hcs-probes.d.ts +17 -0
- package/dist/selftest/support/hcs-probes.js +41 -0
- package/dist/selftest/support/releases.js +1 -1
- package/dist/selftest/toolchains.test.js +21 -0
- package/dist/selftest/update-service.test.js +87 -3
- package/dist/selftest/vpn.test.d.ts +2 -0
- package/dist/selftest/vpn.test.js +412 -0
- package/dist/selftest/web.test.d.ts +2 -0
- package/dist/selftest/web.test.js +402 -0
- package/dist/shared/apps/catalogue.js +31 -0
- package/dist/shared/channel/index.d.ts +1 -0
- package/dist/shared/channel/index.js +1 -0
- package/dist/shared/channel/run-dir.d.ts +9 -1
- package/dist/shared/channel/run-dir.js +18 -1
- package/dist/shared/channel/schema.d.ts +53 -0
- package/dist/shared/channel/schema.js +38 -0
- package/dist/shared/channel/secrets.d.ts +29 -0
- package/dist/shared/channel/secrets.js +50 -0
- package/dist/shared/memory/index.d.ts +1 -0
- package/dist/shared/memory/index.js +1 -0
- package/dist/shared/memory/policy.d.ts +33 -0
- package/dist/shared/memory/policy.js +55 -0
- package/dist/shared/pty/output-filter.d.ts +14 -1
- package/dist/shared/pty/output-filter.js +22 -4
- package/dist/shared/pty/terminal.d.ts +4 -1
- package/dist/shared/pty/terminal.js +4 -2
- package/dist/shared/system.d.ts +1 -0
- package/dist/shared/system.js +1 -0
- package/dist/shared/vpn/download.d.ts +29 -0
- package/dist/shared/vpn/download.js +30 -0
- package/dist/shared/vpn/kill-switch.d.ts +18 -0
- package/dist/shared/vpn/kill-switch.js +81 -0
- package/dist/shared/vpn/ovpn.d.ts +23 -0
- package/dist/shared/vpn/ovpn.js +244 -0
- package/dist/shared/vpn/wireguard.d.ts +51 -0
- package/dist/shared/vpn/wireguard.js +227 -0
- package/dist/shared/web/index.d.ts +1 -0
- package/dist/shared/web/index.js +1 -0
- package/dist/shared/web/protocol.d.ts +61 -0
- package/dist/shared/web/protocol.js +35 -0
- package/dist/sync/sync-cycle.js +9 -5
- package/dist/sync/sync-state.d.ts +1 -0
- package/dist/sync/sync-state.js +1 -0
- package/dist/sync/watcher.d.ts +13 -0
- package/dist/sync/watcher.js +102 -3
- package/dist/web/index.html +14 -0
- package/dist/web/main-NRRS5O6Z.js +157 -0
- package/dist/web/main-T5DMCHYV.css +1 -0
- package/native/csharp/FolderSecurity.cs +29 -0
- package/native/csharp/HcsHost/AssemblyInfo.cs +14 -0
- package/native/csharp/HcsHost/Guard.cs +100 -0
- package/native/csharp/HcsHost/Hcs.cs +256 -0
- package/native/csharp/HcsHost/Json.cs +78 -0
- package/native/csharp/HcsHost/Program.cs +185 -0
- package/native/csharp/HcsHost/VirtualDisk.cs +95 -0
- package/native/csharp/HostTools/AssemblyInfo.cs +14 -0
- package/native/csharp/HostTools/MemoryStatus.cs +107 -0
- package/native/csharp/HostTools/Program.cs +58 -17
- package/native/scripts/check-contained.ps1 +28 -0
- package/native/scripts/contained-common.ps1 +241 -0
- package/native/scripts/dismount-contained.ps1 +66 -0
- package/native/scripts/memory-status.ps1 +34 -0
- package/native/scripts/mount-contained.ps1 +139 -0
- package/native/scripts/protect-data.ps1 +29 -0
- package/native/scripts/read-folder-sddl.ps1 +10 -0
- package/native/scripts/run-elevated.ps1 +17 -4
- package/native/scripts/set-folder-access.ps1 +49 -7
- package/native/scripts/stop-events.ps1 +23 -8
- package/node_modules/ws/LICENSE +20 -0
- package/node_modules/ws/README.md +548 -0
- package/node_modules/ws/browser.js +8 -0
- package/node_modules/ws/index.js +22 -0
- package/node_modules/ws/lib/buffer-util.js +131 -0
- package/node_modules/ws/lib/constants.js +19 -0
- package/node_modules/ws/lib/event-target.js +292 -0
- package/node_modules/ws/lib/extension.js +203 -0
- package/node_modules/ws/lib/limiter.js +55 -0
- package/node_modules/ws/lib/permessage-deflate.js +530 -0
- package/node_modules/ws/lib/receiver.js +743 -0
- package/node_modules/ws/lib/sender.js +607 -0
- package/node_modules/ws/lib/stream.js +161 -0
- package/node_modules/ws/lib/subprotocol.js +62 -0
- package/node_modules/ws/lib/validation.js +152 -0
- package/node_modules/ws/lib/websocket-server.js +562 -0
- package/node_modules/ws/lib/websocket.js +1421 -0
- package/node_modules/ws/package.json +74 -0
- package/node_modules/ws/wrapper.mjs +21 -0
- package/package.json +22 -5
- package/sandbox/csharp/EnvBroadcast.cs +33 -0
- package/sandbox/csharp/MemGov.cs +398 -0
- package/sandbox/csharp/PathSync.cs +90 -0
- package/sandbox/csharp/PtyHost.cs +111 -5
- package/sandbox/scripts/install-shell-path.ps1 +73 -0
- package/sandbox/scripts/set-machine-environment.ps1 +37 -4
- package/schemas/config.schema.json +136 -7
- package/schemas/sandbox-config.schema.json +17 -4
- package/dist/cli/commands/repair/checks.d.ts +0 -2
- package/dist/cli/commands/repair/checks.js +0 -246
- package/dist/cli/commands/sessions/control.d.ts +0 -4
- package/dist/cli/commands/sessions/control.js +0 -66
- package/dist/cli/commands/sessions/list.d.ts +0 -2
- package/dist/cli/commands/sessions/list.js +0 -45
- package/dist/cli/commands/sessions/status.d.ts +0 -2
- package/dist/cli/commands/sessions/status.js +0 -93
- package/dist/cli/commands/sessions/window.d.ts +0 -3
- package/dist/cli/commands/sessions/window.js +0 -18
- package/dist/cli/menu/pages/start-page.d.ts +0 -43
- package/dist/cli/menu/pages/start-page.js +0 -192
- package/dist/cli/tui/tab-bar.d.ts +0 -9
- package/dist/cli/tui/tab-bar.js +0 -33
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { Config, ResolvedMapping } from '../../core/types.js';
|
|
2
|
+
import type { StorageAttachment } from '../storage/providers/index.js';
|
|
3
|
+
export type EngineId = Config['sandbox']['engine'];
|
|
4
|
+
export interface EngineCapabilities {
|
|
5
|
+
readonly desktop: boolean;
|
|
6
|
+
readonly gpu: boolean;
|
|
7
|
+
readonly clipboard: boolean;
|
|
8
|
+
readonly audio: boolean;
|
|
9
|
+
readonly video: boolean;
|
|
10
|
+
readonly printers: boolean;
|
|
11
|
+
/** Folders can be added to a running sandbox. */
|
|
12
|
+
readonly liveFolderAdd: boolean;
|
|
13
|
+
readonly attachedDisks: boolean;
|
|
14
|
+
readonly multipleInstances: boolean;
|
|
15
|
+
readonly hvsocket: boolean;
|
|
16
|
+
}
|
|
17
|
+
export interface EngineCheck {
|
|
18
|
+
readonly available: boolean;
|
|
19
|
+
readonly reasons: readonly string[];
|
|
20
|
+
readonly fixes: readonly string[];
|
|
21
|
+
}
|
|
22
|
+
export interface LaunchDevices {
|
|
23
|
+
readonly gpu: boolean;
|
|
24
|
+
readonly clipboard: boolean;
|
|
25
|
+
readonly audioInput: boolean;
|
|
26
|
+
readonly videoInput: boolean;
|
|
27
|
+
readonly printers: boolean;
|
|
28
|
+
readonly protectedClient: boolean;
|
|
29
|
+
}
|
|
30
|
+
/** One launch, whatever runs it. Pure data: nothing in it is engine-specific. */
|
|
31
|
+
export interface LaunchPlan {
|
|
32
|
+
/** The launch folder: where an engine writes its own files. */
|
|
33
|
+
readonly launchPath: string;
|
|
34
|
+
readonly memoryMb: number;
|
|
35
|
+
/** Percent of this PC's CPU, or 'none'. The guest applies it; an engine may use it as a hint. */
|
|
36
|
+
readonly cpuLimit: 'none' | number;
|
|
37
|
+
readonly networking: boolean;
|
|
38
|
+
readonly devices: LaunchDevices;
|
|
39
|
+
/** Every folder shared in, in order (the folder attachments of `storage` are among them). */
|
|
40
|
+
readonly mappings: readonly ResolvedMapping[];
|
|
41
|
+
/** The command the guest runs at logon. */
|
|
42
|
+
readonly logonCommand: string;
|
|
43
|
+
readonly storage: readonly StorageAttachment[];
|
|
44
|
+
}
|
|
45
|
+
/** What an engine made of a LaunchPlan: files to write and the one to start from. Callers do not look inside. */
|
|
46
|
+
export interface EnginePlan {
|
|
47
|
+
readonly engine: EngineId;
|
|
48
|
+
readonly files: readonly {
|
|
49
|
+
readonly path: string;
|
|
50
|
+
readonly text: string;
|
|
51
|
+
}[];
|
|
52
|
+
readonly entry: string;
|
|
53
|
+
}
|
|
54
|
+
export interface RunningSandbox {
|
|
55
|
+
readonly id: string;
|
|
56
|
+
readonly engine: EngineId;
|
|
57
|
+
readonly started: number;
|
|
58
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Config } from '../../../core/types.js';
|
|
2
|
+
import type { SandboxEngine } from '../engine.js';
|
|
3
|
+
import type { EngineCapabilities, EngineCheck, EnginePlan, LaunchPlan, RunningSandbox } from '../types.js';
|
|
4
|
+
export declare class WindowsSandboxEngine implements SandboxEngine {
|
|
5
|
+
private readonly sandbox;
|
|
6
|
+
private readonly hasWsbCli;
|
|
7
|
+
readonly id = "windows-sandbox";
|
|
8
|
+
/** `hasWsbCli`: whether wsb.exe is on this PC (adding folders to a running sandbox needs it). */
|
|
9
|
+
constructor(sandbox: Config['sandbox'], hasWsbCli?: () => boolean);
|
|
10
|
+
capabilities(): EngineCapabilities;
|
|
11
|
+
check(): Promise<EngineCheck>;
|
|
12
|
+
plan(launch: LaunchPlan): EnginePlan;
|
|
13
|
+
start(plan: EnginePlan): Promise<RunningSandbox>;
|
|
14
|
+
running(): Promise<boolean>;
|
|
15
|
+
stop(): Promise<void>;
|
|
16
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// Windows Sandbox behind the engine interface: the .wsb file, and the existing start / wait / running code.
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { fail, isWin } from '../../../core/util/index.js';
|
|
4
|
+
import { confirmSandboxStarted, findWsb, isSandboxRunning, sandboxFeatureInstalled, startSandbox, } from '../../sandbox/index.js';
|
|
5
|
+
import { wsbText } from './wsb-text.js';
|
|
6
|
+
const WSB_FILE = 'agent.wsb';
|
|
7
|
+
export class WindowsSandboxEngine {
|
|
8
|
+
sandbox;
|
|
9
|
+
hasWsbCli;
|
|
10
|
+
id = 'windows-sandbox';
|
|
11
|
+
/** `hasWsbCli`: whether wsb.exe is on this PC (adding folders to a running sandbox needs it). */
|
|
12
|
+
constructor(sandbox, hasWsbCli = () => findWsb() !== null) {
|
|
13
|
+
this.sandbox = sandbox;
|
|
14
|
+
this.hasWsbCli = hasWsbCli;
|
|
15
|
+
}
|
|
16
|
+
capabilities() {
|
|
17
|
+
return {
|
|
18
|
+
desktop: true,
|
|
19
|
+
gpu: this.sandbox.vGpu,
|
|
20
|
+
clipboard: this.sandbox.clipboard,
|
|
21
|
+
audio: this.sandbox.audioInput,
|
|
22
|
+
video: this.sandbox.videoInput,
|
|
23
|
+
printers: this.sandbox.printerRedirection,
|
|
24
|
+
liveFolderAdd: this.hasWsbCli(),
|
|
25
|
+
attachedDisks: false,
|
|
26
|
+
multipleInstances: false,
|
|
27
|
+
hvsocket: false,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
check() {
|
|
31
|
+
if (!isWin)
|
|
32
|
+
return Promise.resolve({
|
|
33
|
+
available: false,
|
|
34
|
+
reasons: ['Windows Sandbox only runs on Windows.'],
|
|
35
|
+
fixes: ['Use sandbox generate to only write the files.'],
|
|
36
|
+
});
|
|
37
|
+
if (!sandboxFeatureInstalled())
|
|
38
|
+
return Promise.resolve({
|
|
39
|
+
available: false,
|
|
40
|
+
reasons: ['Windows Sandbox is not enabled on this PC.'],
|
|
41
|
+
fixes: [
|
|
42
|
+
'Run in an admin PowerShell, then reboot: Enable-WindowsOptionalFeature -Online -FeatureName Containers-DisposableClientVM -All (needs Windows Pro, Enterprise or Education)',
|
|
43
|
+
],
|
|
44
|
+
});
|
|
45
|
+
return Promise.resolve({ available: true, reasons: [], fixes: [] });
|
|
46
|
+
}
|
|
47
|
+
plan(launch) {
|
|
48
|
+
const entry = path.join(launch.launchPath, WSB_FILE);
|
|
49
|
+
return { engine: this.id, files: [{ path: entry, text: wsbText(launch) }], entry };
|
|
50
|
+
}
|
|
51
|
+
async start(plan) {
|
|
52
|
+
startSandbox(plan.entry);
|
|
53
|
+
await confirmSandboxStarted(plan.entry);
|
|
54
|
+
return { id: path.basename(path.dirname(plan.entry)), engine: this.id, started: Date.now() };
|
|
55
|
+
}
|
|
56
|
+
running() {
|
|
57
|
+
return Promise.resolve(isSandboxRunning());
|
|
58
|
+
}
|
|
59
|
+
stop() {
|
|
60
|
+
// Windows Sandbox shuts itself down from inside, through the session channel; it is never killed from outside.
|
|
61
|
+
return Promise.resolve().then(() => fail('Windows Sandbox is not stopped from outside.', 'Use sandbox stop (it shuts down from inside).'));
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// The .wsb file Windows Sandbox starts from: memory, devices and the folders mapped in, written from a LaunchPlan.
|
|
2
|
+
import { xmlEscape } from '../../../core/util/index.js';
|
|
3
|
+
import { sandboxFolder } from '../../../shared/paths/index.js';
|
|
4
|
+
function element(name, value) {
|
|
5
|
+
return '<' + name + '>' + value + '</' + name + '>';
|
|
6
|
+
}
|
|
7
|
+
function toggle(value) {
|
|
8
|
+
return value ? 'Enable' : 'Disable';
|
|
9
|
+
}
|
|
10
|
+
export function wsbText(plan) {
|
|
11
|
+
const d = plan.devices;
|
|
12
|
+
// Guest paths on other drive letters (F:\x) really live under C:\Mirror\F; bootstrap.ps1 substs F: onto it at boot.
|
|
13
|
+
const folders = plan.mappings
|
|
14
|
+
.map((m) => element('MappedFolder', element('HostFolder', xmlEscape(m.host)) +
|
|
15
|
+
element('SandboxFolder', xmlEscape(sandboxFolder(m.guest))) +
|
|
16
|
+
element('ReadOnly', String(m.readOnly))))
|
|
17
|
+
.join('');
|
|
18
|
+
// The elements are in the order Windows Sandbox expects.
|
|
19
|
+
return element('Configuration', element('MemoryInMB', String(plan.memoryMb)) +
|
|
20
|
+
element('vGPU', toggle(d.gpu)) +
|
|
21
|
+
element('Networking', toggle(plan.networking)) +
|
|
22
|
+
element('ClipboardRedirection', toggle(d.clipboard)) +
|
|
23
|
+
element('AudioInput', toggle(d.audioInput)) +
|
|
24
|
+
element('VideoInput', toggle(d.videoInput)) +
|
|
25
|
+
element('PrinterRedirection', toggle(d.printers)) +
|
|
26
|
+
element('ProtectedClient', toggle(d.protectedClient)) +
|
|
27
|
+
element('MappedFolders', folders) +
|
|
28
|
+
element('LogonCommand', element('Command', xmlEscape(plan.logonCommand))));
|
|
29
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/** The Windows group of the users who may use a shared sandbox. */
|
|
2
|
+
export declare const SHARING_GROUP = "Agent Sandbox Users";
|
|
3
|
+
export interface AclEntry {
|
|
4
|
+
readonly principal: string;
|
|
5
|
+
/** The flags in order, e.g. "(OI)(CI)(F)". */
|
|
6
|
+
readonly flags: string;
|
|
7
|
+
readonly inherited: boolean;
|
|
8
|
+
readonly deny: boolean;
|
|
9
|
+
}
|
|
10
|
+
/** Entries of `icacls` output for `dir` (the first line starts with the folder's path). */
|
|
11
|
+
export declare function parseIcacls(text: string, dir: string): AclEntry[];
|
|
12
|
+
/** The entries that make a folder readable by more than you, SYSTEM and Administrators (empty: it is private). */
|
|
13
|
+
export declare function privacyProblems(entries: readonly AclEntry[], groupName: string): string[];
|
|
14
|
+
/** Entries of the sharing group (the folders it may enter only while a shared sandbox runs). */
|
|
15
|
+
export declare function groupEntries(entries: readonly AclEntry[], groupName: string): AclEntry[];
|
|
16
|
+
/** The folders a sharing plan touches for one user's data set: the storage folder, data folder, data set and run. */
|
|
17
|
+
export declare function sharedFolders(storageUserDir: string, dataPath: string): string[];
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// Reading a folder's permissions from `icacls <folder>` (read only): who has an entry, and is it inherited. Used to
|
|
2
|
+
// tell whether a user's data folder is private and whether the sharing group still has entries on folders it should
|
|
3
|
+
// not.
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
/** The Windows group of the users who may use a shared sandbox. */
|
|
6
|
+
export const SHARING_GROUP = 'Agent Sandbox Users';
|
|
7
|
+
/** Entries of `icacls` output for `dir` (the first line starts with the folder's path). */
|
|
8
|
+
export function parseIcacls(text, dir) {
|
|
9
|
+
const entries = [];
|
|
10
|
+
const lines = text.split(/\r?\n/);
|
|
11
|
+
for (let i = 0; i < lines.length; i++) {
|
|
12
|
+
let line = lines[i];
|
|
13
|
+
if (/^\s*(Successfully processed|Failed processing)/i.test(line))
|
|
14
|
+
break;
|
|
15
|
+
if (i === 0 && line.toLowerCase().startsWith(dir.toLowerCase()))
|
|
16
|
+
line = line.slice(dir.length);
|
|
17
|
+
const m = /^\s*(\S.*?):((?:\([A-Za-z0-9,]+\))+)\s*$/.exec(line);
|
|
18
|
+
if (!m)
|
|
19
|
+
continue;
|
|
20
|
+
entries.push({
|
|
21
|
+
principal: m[1].trim(),
|
|
22
|
+
flags: m[2],
|
|
23
|
+
inherited: m[2].includes('(I)'),
|
|
24
|
+
deny: m[2].includes('(DENY)'),
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
return entries;
|
|
28
|
+
}
|
|
29
|
+
const BROAD = /(^|\\)(Everyone|Users|Authenticated Users)$/i;
|
|
30
|
+
/** The entries that make a folder readable by more than you, SYSTEM and Administrators (empty: it is private). */
|
|
31
|
+
export function privacyProblems(entries, groupName) {
|
|
32
|
+
const group = new RegExp('(^|\\\\)' + groupName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + '$', 'i');
|
|
33
|
+
return entries
|
|
34
|
+
.filter((e) => !e.deny && (BROAD.test(e.principal) || group.test(e.principal) || e.inherited))
|
|
35
|
+
.map((e) => e.principal + (e.inherited ? ' (inherited)' : ''));
|
|
36
|
+
}
|
|
37
|
+
/** Entries of the sharing group (the folders it may enter only while a shared sandbox runs). */
|
|
38
|
+
export function groupEntries(entries, groupName) {
|
|
39
|
+
const group = new RegExp('(^|\\\\)' + groupName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + '$', 'i');
|
|
40
|
+
return entries.filter((e) => group.test(e.principal));
|
|
41
|
+
}
|
|
42
|
+
/** The folders a sharing plan touches for one user's data set: the storage folder, data folder, data set and run. */
|
|
43
|
+
export function sharedFolders(storageUserDir, dataPath) {
|
|
44
|
+
return [storageUserDir, path.dirname(dataPath), dataPath, path.join(dataPath, 'run')];
|
|
45
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface ConfigBackup {
|
|
2
|
+
readonly folder: string;
|
|
3
|
+
/** The saved copy of the settings file. */
|
|
4
|
+
readonly copy: string;
|
|
5
|
+
/** From the folder name: "1.4.0 to 1.5.0 at 2026-10-14 09:30:12". */
|
|
6
|
+
readonly label: string;
|
|
7
|
+
}
|
|
8
|
+
/** Saved copies of `configFile`, newest first. A backup with no readable manifest or no such copy is skipped. */
|
|
9
|
+
export declare function configBackups(storageRoot: string, configFile: string): ConfigBackup[];
|
|
10
|
+
/** A short line difference: "- line" only in `current`, "+ line" only in `backup`; at most `max` lines. */
|
|
11
|
+
export declare function lineDiff(current: string, backup: string, max?: number): string[];
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
// The copies of config.json that an update saved before it changed anything (<storage>\backups\migrate-*\), so a
|
|
2
|
+
// settings file that no longer loads can be put back. Read only; the caller shows the difference first and keeps the
|
|
3
|
+
// broken file.
|
|
4
|
+
import fs from 'node:fs';
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
import { z } from 'zod';
|
|
7
|
+
import { assertNoLinks, dirExists } from '../../core/util/index.js';
|
|
8
|
+
import { readValid } from '../../shared/io/index.js';
|
|
9
|
+
const ManifestSchema = z.object({
|
|
10
|
+
entries: z.array(z.object({ original: z.string(), copy: z.string(), existed: z.boolean() })),
|
|
11
|
+
});
|
|
12
|
+
const MAX_CONFIG_BYTES = 1024 * 1024;
|
|
13
|
+
/** The stamp in migrate-<from>-<to>-<yyyymmddhhmmss>[-n] folder names. */
|
|
14
|
+
function stampOf(name) {
|
|
15
|
+
return /-(\d{14})(?:-\d+)?$/.exec(name)?.[1] ?? '';
|
|
16
|
+
}
|
|
17
|
+
function labelOf(name) {
|
|
18
|
+
const m = /^migrate-(.+?)-(.+?)-(\d{4})(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)(?:-\d+)?$/.exec(name);
|
|
19
|
+
return m
|
|
20
|
+
? m[1] + ' to ' + m[2] + ' at ' + m[3] + '-' + m[4] + '-' + m[5] + ' ' + m[6] + ':' + m[7] + ':' + m[8]
|
|
21
|
+
: name;
|
|
22
|
+
}
|
|
23
|
+
/** Saved copies of `configFile`, newest first. A backup with no readable manifest or no such copy is skipped. */
|
|
24
|
+
export function configBackups(storageRoot, configFile) {
|
|
25
|
+
const dir = path.join(storageRoot, 'backups');
|
|
26
|
+
if (!dirExists(dir))
|
|
27
|
+
return [];
|
|
28
|
+
assertNoLinks(storageRoot, dir);
|
|
29
|
+
const found = [];
|
|
30
|
+
for (const name of fs.readdirSync(dir)) {
|
|
31
|
+
if (!name.startsWith('migrate-'))
|
|
32
|
+
continue;
|
|
33
|
+
const folder = path.join(dir, name);
|
|
34
|
+
const manifest = readValid(ManifestSchema, path.join(folder, 'manifest.json'));
|
|
35
|
+
const entry = manifest?.entries.find((e) => e.existed && path.resolve(e.original).toLowerCase() === path.resolve(configFile).toLowerCase());
|
|
36
|
+
if (!entry)
|
|
37
|
+
continue;
|
|
38
|
+
// The manifest is data on disk: the copy must be a file inside this backup folder, and small.
|
|
39
|
+
const copy = path.resolve(entry.copy);
|
|
40
|
+
if (!copy.toLowerCase().startsWith(path.resolve(folder).toLowerCase() + path.sep))
|
|
41
|
+
continue;
|
|
42
|
+
try {
|
|
43
|
+
assertNoLinks(storageRoot, copy);
|
|
44
|
+
const stat = fs.statSync(copy);
|
|
45
|
+
if (!stat.isFile() || stat.size > MAX_CONFIG_BYTES)
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
found.push({ folder, copy, label: labelOf(name) });
|
|
52
|
+
}
|
|
53
|
+
return found.sort((a, b) => stampOf(path.basename(b.folder)).localeCompare(stampOf(path.basename(a.folder))));
|
|
54
|
+
}
|
|
55
|
+
/** A short line difference: "- line" only in `current`, "+ line" only in `backup`; at most `max` lines. */
|
|
56
|
+
export function lineDiff(current, backup, max = 12) {
|
|
57
|
+
const split = (t) => t
|
|
58
|
+
.replace(/\r\n/g, '\n')
|
|
59
|
+
.split('\n')
|
|
60
|
+
.map((l) => l.trimEnd())
|
|
61
|
+
.filter((l) => l.trim() !== '');
|
|
62
|
+
const a = split(current);
|
|
63
|
+
const b = split(backup);
|
|
64
|
+
const inB = new Set(b);
|
|
65
|
+
const inA = new Set(a);
|
|
66
|
+
const lines = [
|
|
67
|
+
...a.filter((l) => !inB.has(l)).map((l) => '- ' + l.trim()),
|
|
68
|
+
...b.filter((l) => !inA.has(l)).map((l) => '+ ' + l.trim()),
|
|
69
|
+
];
|
|
70
|
+
return lines.length > max
|
|
71
|
+
? [...lines.slice(0, max), '... and ' + (lines.length - max) + ' more changed lines']
|
|
72
|
+
: lines;
|
|
73
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// Looking at the install, the data folders and what a closed sandbox leaves behind: the host side of doctor and repair.
|
|
2
|
+
export * from './system.js';
|
|
3
|
+
export * from './install-state.js';
|
|
4
|
+
export * from './acl-read.js';
|
|
5
|
+
export * from './stale.js';
|
|
6
|
+
export * from './config-backup.js';
|
|
7
|
+
export * from './path-copies.js';
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { type InstallLayout } from '../install/index.js';
|
|
2
|
+
export interface PointerState {
|
|
3
|
+
readonly activeVersion: string | null;
|
|
4
|
+
readonly activeNode: string | null;
|
|
5
|
+
/** Versions that have a package.json, oldest first. */
|
|
6
|
+
readonly versions: readonly string[];
|
|
7
|
+
/** Node folders that have node.exe, oldest first. */
|
|
8
|
+
readonly nodes: readonly string[];
|
|
9
|
+
readonly problems: readonly string[];
|
|
10
|
+
/** Where the pointers should point to be whole again, or null when nothing usable is installed. */
|
|
11
|
+
readonly want: {
|
|
12
|
+
readonly version: string;
|
|
13
|
+
readonly node: string;
|
|
14
|
+
} | null;
|
|
15
|
+
}
|
|
16
|
+
/** Node versions under <root>\node that really hold node.exe, oldest first. */
|
|
17
|
+
export declare function installedNodes(layout: InstallLayout): string[];
|
|
18
|
+
/** Versions that are really there (a package.json in their package folder), oldest first. */
|
|
19
|
+
export declare function completeVersions(layout: InstallLayout): string[];
|
|
20
|
+
/** Looks at active-version and active-node. */
|
|
21
|
+
export declare function inspectPointers(layout: InstallLayout): PointerState;
|
|
22
|
+
/** Moves the pointers to what is installed (the newest version and Node that are whole). Returns what changed. */
|
|
23
|
+
export declare function repairPointers(layout: InstallLayout, state?: PointerState): string;
|
|
24
|
+
/** The commands a package folder declares (name -> program path), or null when its package.json cannot be read. */
|
|
25
|
+
export declare function binsOfPackage(packageDir: string): Record<string, string> | null;
|
|
26
|
+
export interface ShimProblems {
|
|
27
|
+
readonly missing: readonly string[];
|
|
28
|
+
readonly different: readonly string[];
|
|
29
|
+
}
|
|
30
|
+
/** Shim files (both the .cmd and the shell one) that are missing or not what shimText() writes now. */
|
|
31
|
+
export declare function shimProblems(layout: InstallLayout, bins: Record<string, string>): ShimProblems;
|
|
32
|
+
/** Is `dir` one of the entries of a PATH value (variables expanded, case and a trailing slash ignored)? */
|
|
33
|
+
export declare function pathHas(value: string | null, dir: string): boolean;
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
// Is a managed install (versions side by side, a private Node, shims in bin) in one piece: do the two pointer files
|
|
2
|
+
// name installed folders, do the shims say what they should, is bin on PATH. These look; the fixes move a pointer or
|
|
3
|
+
// rewrite shims, and never delete a version.
|
|
4
|
+
import fs from 'node:fs';
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
import { expandVariables } from '../../core/util/index.js';
|
|
7
|
+
import { NODE_PATTERN, compareVersions, readBins, shimText } from '../install/index.js';
|
|
8
|
+
/** Node versions under <root>\node that really hold node.exe, oldest first. */
|
|
9
|
+
export function installedNodes(layout) {
|
|
10
|
+
const dir = path.join(layout.root, 'node');
|
|
11
|
+
try {
|
|
12
|
+
return fs
|
|
13
|
+
.readdirSync(dir, { withFileTypes: true })
|
|
14
|
+
.filter((d) => d.isDirectory() && NODE_PATTERN.test(d.name) && fs.existsSync(layout.nodeExe(d.name)))
|
|
15
|
+
.map((d) => d.name)
|
|
16
|
+
.sort((a, b) => compareVersions(a.slice(1), b.slice(1)));
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
return [];
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
/** Versions that are really there (a package.json in their package folder), oldest first. */
|
|
23
|
+
export function completeVersions(layout) {
|
|
24
|
+
return layout.installedVersions().filter((v) => fs.existsSync(path.join(layout.packageDir(v), 'package.json')));
|
|
25
|
+
}
|
|
26
|
+
function rawPointer(layout, name) {
|
|
27
|
+
try {
|
|
28
|
+
return fs.readFileSync(path.join(layout.root, name), 'utf8').trim();
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/** Looks at active-version and active-node. */
|
|
35
|
+
export function inspectPointers(layout) {
|
|
36
|
+
const versions = completeVersions(layout);
|
|
37
|
+
const nodes = installedNodes(layout);
|
|
38
|
+
const activeVersion = layout.activeVersion();
|
|
39
|
+
const activeNode = layout.activeNode();
|
|
40
|
+
const problems = [];
|
|
41
|
+
const raw = (name) => {
|
|
42
|
+
const text = rawPointer(layout, name);
|
|
43
|
+
return text === null ? 'is missing' : text === '' ? 'is empty' : 'says "' + text.slice(0, 40) + '"';
|
|
44
|
+
};
|
|
45
|
+
if (!activeVersion)
|
|
46
|
+
problems.push('active-version ' + raw('active-version') + ' (it must name a version like 1.5.0)');
|
|
47
|
+
else if (!versions.includes(activeVersion))
|
|
48
|
+
problems.push('active-version points at ' + activeVersion + ', which is not installed');
|
|
49
|
+
if (!activeNode)
|
|
50
|
+
problems.push('active-node ' + raw('active-node') + ' (it must name a Node like v22.11.0)');
|
|
51
|
+
else if (!nodes.includes(activeNode))
|
|
52
|
+
problems.push('active-node points at ' + activeNode + ', which is not installed');
|
|
53
|
+
const version = activeVersion && versions.includes(activeVersion) ? activeVersion : versions[versions.length - 1];
|
|
54
|
+
const node = activeNode && nodes.includes(activeNode) ? activeNode : nodes[nodes.length - 1];
|
|
55
|
+
return { activeVersion, activeNode, versions, nodes, problems, want: version && node ? { version, node } : null };
|
|
56
|
+
}
|
|
57
|
+
/** Moves the pointers to what is installed (the newest version and Node that are whole). Returns what changed. */
|
|
58
|
+
export function repairPointers(layout, state = inspectPointers(layout)) {
|
|
59
|
+
if (!state.want)
|
|
60
|
+
throw new Error('No complete version or Node is installed in ' + layout.root + '.');
|
|
61
|
+
layout.setActive(state.want.version, state.want.node);
|
|
62
|
+
return 'active-version ' + state.want.version + ', active-node ' + state.want.node;
|
|
63
|
+
}
|
|
64
|
+
/** The commands a package folder declares (name -> program path), or null when its package.json cannot be read. */
|
|
65
|
+
export function binsOfPackage(packageDir) {
|
|
66
|
+
try {
|
|
67
|
+
return readBins(JSON.parse(fs.readFileSync(path.join(packageDir, 'package.json'), 'utf8')));
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
const sameText = (a, b) => a.replace(/\r\n/g, '\n') === b.replace(/\r\n/g, '\n');
|
|
74
|
+
/** Shim files (both the .cmd and the shell one) that are missing or not what shimText() writes now. */
|
|
75
|
+
export function shimProblems(layout, bins) {
|
|
76
|
+
const missing = [];
|
|
77
|
+
const different = [];
|
|
78
|
+
for (const [name, target] of Object.entries(bins)) {
|
|
79
|
+
for (const [file, kind] of [
|
|
80
|
+
[name + '.cmd', 'cmd'],
|
|
81
|
+
[name, 'sh'],
|
|
82
|
+
]) {
|
|
83
|
+
let text;
|
|
84
|
+
try {
|
|
85
|
+
text = fs.readFileSync(path.join(layout.binDir, file), 'utf8');
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
missing.push(file);
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
if (!sameText(text, shimText(name, kind, target)))
|
|
92
|
+
different.push(file);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return { missing, different };
|
|
96
|
+
}
|
|
97
|
+
const normal = (p) => path
|
|
98
|
+
.normalize(expandVariables(p.trim().replace(/^"|"$/g, '')))
|
|
99
|
+
.replace(/[\\/]+$/, '')
|
|
100
|
+
.toLowerCase();
|
|
101
|
+
/** Is `dir` one of the entries of a PATH value (variables expanded, case and a trailing slash ignored)? */
|
|
102
|
+
export function pathHas(value, dir) {
|
|
103
|
+
if (!value)
|
|
104
|
+
return false;
|
|
105
|
+
const want = normal(dir);
|
|
106
|
+
return value
|
|
107
|
+
.split(';')
|
|
108
|
+
.filter((p) => p.trim() !== '')
|
|
109
|
+
.some((p) => normal(p) === want);
|
|
110
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export declare const COMMAND_NAMES: readonly ["sandbox", "agent-sandbox", "claude-sbx"];
|
|
2
|
+
export type CopyKind = 'managed-machine' | 'managed-user' | 'npm' | 'old-scripts' | 'other';
|
|
3
|
+
/** One folder on the PATH that holds the commands. */
|
|
4
|
+
export interface CommandCopy {
|
|
5
|
+
readonly dir: string;
|
|
6
|
+
/** The commands found in it, as the file Windows would run for each (sandbox.cmd, ...). */
|
|
7
|
+
readonly files: readonly string[];
|
|
8
|
+
readonly kind: CopyKind;
|
|
9
|
+
/** Position among the PATH folders that hold a copy (0 = the first one, the one that runs). */
|
|
10
|
+
readonly order: number;
|
|
11
|
+
}
|
|
12
|
+
export interface PathCopyEnv {
|
|
13
|
+
/** Machine PATH, then user PATH (raw registry values; null when unreadable). */
|
|
14
|
+
readonly machinePath: string | null;
|
|
15
|
+
readonly userPath: string | null;
|
|
16
|
+
/** PATHEXT, e.g. ".COM;.EXE;.BAT;.CMD". */
|
|
17
|
+
readonly pathext: string;
|
|
18
|
+
/** %ProgramFiles% and %LOCALAPPDATA% (where the managed installs live). */
|
|
19
|
+
readonly programFiles: string | null;
|
|
20
|
+
readonly localAppData: string | null;
|
|
21
|
+
readonly exists: (file: string) => boolean;
|
|
22
|
+
}
|
|
23
|
+
/** The PATH folders in the order Windows searches them (machine, then user), each once, variables expanded. */
|
|
24
|
+
export declare function pathFolders(machinePath: string | null, userPath: string | null): string[];
|
|
25
|
+
/** The folders that hold at least one of the commands, in search order. */
|
|
26
|
+
export declare function findCommandCopies(env: PathCopyEnv): CommandCopy[];
|
|
27
|
+
/** The folder a program runs from as a bin folder: the managed bin, or the npm global folder holding the package. */
|
|
28
|
+
export declare function ownBinDir(packageRoot: string, managedBin: string | null): string | null;
|
|
29
|
+
export declare const sameFolder: (a: string, b: string) => boolean;
|
|
30
|
+
/** PATHEXT from the process, or the Windows default. */
|
|
31
|
+
export declare function currentPathext(): string;
|
|
32
|
+
export declare const fileOnDisk: (file: string) => boolean;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
// Every copy of the sandbox commands on the PATH (sandbox, agent-sandbox, claude-sbx), in the order Windows finds them:
|
|
2
|
+
// the machine PATH, then yours, and in each folder PATHEXT order. Read only: nothing is run, and a file is only checked
|
|
3
|
+
// for existing. Used by doctor to say which copy runs and how to remove each of the others.
|
|
4
|
+
import fs from 'node:fs';
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
import { expandVariables } from '../../core/util/index.js';
|
|
7
|
+
export const COMMAND_NAMES = ['sandbox', 'agent-sandbox', 'claude-sbx'];
|
|
8
|
+
const normal = (p) => path
|
|
9
|
+
.normalize(expandVariables(p.trim().replace(/^"|"$/g, '')))
|
|
10
|
+
.replace(/[\\/]+$/, '')
|
|
11
|
+
.toLowerCase();
|
|
12
|
+
/** The PATH folders in the order Windows searches them (machine, then user), each once, variables expanded. */
|
|
13
|
+
export function pathFolders(machinePath, userPath) {
|
|
14
|
+
const seen = new Set();
|
|
15
|
+
const out = [];
|
|
16
|
+
for (const value of [machinePath, userPath])
|
|
17
|
+
for (const raw of (value ?? '').split(';')) {
|
|
18
|
+
if (raw.trim() === '')
|
|
19
|
+
continue;
|
|
20
|
+
const dir = path.normalize(expandVariables(raw.trim().replace(/^"|"$/g, '')));
|
|
21
|
+
const key = normal(raw);
|
|
22
|
+
if (seen.has(key))
|
|
23
|
+
continue;
|
|
24
|
+
seen.add(key);
|
|
25
|
+
out.push(dir);
|
|
26
|
+
}
|
|
27
|
+
return out;
|
|
28
|
+
}
|
|
29
|
+
function classify(dir, env) {
|
|
30
|
+
const here = normal(dir);
|
|
31
|
+
const managed = (base) => base ? normal(path.join(base, 'WindowsDevelopmentSandbox', 'bin')) : null;
|
|
32
|
+
if (here === managed(env.programFiles))
|
|
33
|
+
return 'managed-machine';
|
|
34
|
+
if (here === managed(env.localAppData))
|
|
35
|
+
return 'managed-user';
|
|
36
|
+
for (const pkg of ['windows-development-sandbox', 'agent-sandbox'])
|
|
37
|
+
if (env.exists(path.join(dir, 'node_modules', pkg, 'package.json')))
|
|
38
|
+
return 'npm';
|
|
39
|
+
if (/[\\/]scripts[\\/]agent-sandbox([\\/]bin)?$/i.test(here))
|
|
40
|
+
return 'old-scripts';
|
|
41
|
+
return 'other';
|
|
42
|
+
}
|
|
43
|
+
/** The folders that hold at least one of the commands, in search order. */
|
|
44
|
+
export function findCommandCopies(env) {
|
|
45
|
+
const exts = env.pathext
|
|
46
|
+
.split(';')
|
|
47
|
+
.map((e) => e.trim().toLowerCase())
|
|
48
|
+
.filter((e) => e.startsWith('.'));
|
|
49
|
+
const copies = [];
|
|
50
|
+
for (const dir of pathFolders(env.machinePath, env.userPath)) {
|
|
51
|
+
const files = [];
|
|
52
|
+
for (const name of COMMAND_NAMES) {
|
|
53
|
+
const hit = exts.map((ext) => name + ext).find((file) => env.exists(path.join(dir, file)));
|
|
54
|
+
if (hit)
|
|
55
|
+
files.push(hit);
|
|
56
|
+
}
|
|
57
|
+
if (files.length)
|
|
58
|
+
copies.push({ dir, files, kind: classify(dir, env), order: copies.length });
|
|
59
|
+
}
|
|
60
|
+
return copies;
|
|
61
|
+
}
|
|
62
|
+
/** The folder a program runs from as a bin folder: the managed bin, or the npm global folder holding the package. */
|
|
63
|
+
export function ownBinDir(packageRoot, managedBin) {
|
|
64
|
+
if (managedBin)
|
|
65
|
+
return managedBin;
|
|
66
|
+
const resolved = path.resolve(packageRoot);
|
|
67
|
+
const nodeModules = path.dirname(resolved);
|
|
68
|
+
return path.basename(nodeModules).toLowerCase() === 'node_modules' ? path.dirname(nodeModules) : null;
|
|
69
|
+
}
|
|
70
|
+
export const sameFolder = (a, b) => normal(a) === normal(b);
|
|
71
|
+
/** PATHEXT from the process, or the Windows default. */
|
|
72
|
+
export function currentPathext() {
|
|
73
|
+
return process.env.PATHEXT ?? '.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC';
|
|
74
|
+
}
|
|
75
|
+
export const fileOnDisk = (file) => {
|
|
76
|
+
try {
|
|
77
|
+
return fs.statSync(file).isFile();
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { ActiveSandbox, TaskRow } from '../sharing/index.js';
|
|
2
|
+
/** A watcher this old, with its log quiet and no sandbox, is left over (a finishing one is done within minutes). */
|
|
3
|
+
export declare const WATCHER_MIN_AGE_MS: number;
|
|
4
|
+
export declare const WATCHER_LOG_QUIET_MS: number;
|
|
5
|
+
/** Windows sessions that have a sandbox running (empty: none runs). */
|
|
6
|
+
export declare function sandboxSessions(rows: readonly TaskRow[]): number[];
|
|
7
|
+
/** Sharing records whose Windows session has no sandbox running (nothing else removes them after a crash). */
|
|
8
|
+
export declare function staleActiveRecords(records: readonly ActiveSandbox[], rows: readonly TaskRow[]): ActiveSandbox[];
|
|
9
|
+
export interface RunStateProblems {
|
|
10
|
+
/** Sessions still marked running or starting. */
|
|
11
|
+
readonly sessions: number;
|
|
12
|
+
/** Requests nobody answered (valid or not). */
|
|
13
|
+
readonly requests: number;
|
|
14
|
+
/** The sandbox status file says the boot never finished (booting, provisioning, failed). */
|
|
15
|
+
readonly unfinishedBoot: string | null;
|
|
16
|
+
readonly any: boolean;
|
|
17
|
+
}
|
|
18
|
+
/** What is left in <data>\run by a sandbox that is no longer running. */
|
|
19
|
+
export declare function runStateProblems(dataPath: string): RunStateProblems;
|
|
20
|
+
export interface OldLaunch {
|
|
21
|
+
readonly path: string;
|
|
22
|
+
readonly ageDays: number;
|
|
23
|
+
}
|
|
24
|
+
/** Launch folders under <storage>\launches that nothing has touched for `days` days (each is a finished start). */
|
|
25
|
+
export declare function staleLaunchFolders(storageRoot: string, days: number, now: number, keep?: readonly string[]): OldLaunch[];
|
|
26
|
+
export interface WatcherInfo {
|
|
27
|
+
readonly file: string;
|
|
28
|
+
readonly pid: number | null;
|
|
29
|
+
readonly ageMs: number;
|
|
30
|
+
/** How long ago the watcher's log was written; null when there is none. */
|
|
31
|
+
readonly logAgeMs: number | null;
|
|
32
|
+
}
|
|
33
|
+
/** The history-sync watcher records in <storage>\run (watcher-<data set>.pid) with the age of each and of its log. */
|
|
34
|
+
export declare function watcherRecords(storageRoot: string, now: number): WatcherInfo[];
|
|
35
|
+
/**
|
|
36
|
+
* Watchers that run with no sandbox to watch: the process is alive and is a Node program (a recycled pid is somebody
|
|
37
|
+
* else's), no sandbox runs, and neither its record nor its log has changed for a while (a finishing watcher is spared).
|
|
38
|
+
*/
|
|
39
|
+
export declare function orphanWatchers(infos: readonly WatcherInfo[], o: {
|
|
40
|
+
running: boolean;
|
|
41
|
+
alive: (pid: number) => boolean;
|
|
42
|
+
image: (pid: number) => string | null;
|
|
43
|
+
}): WatcherInfo[];
|
|
44
|
+
/** null when a small file can be created in the folder, else the reason (the file is removed again). */
|
|
45
|
+
export declare function writeProblem(dir: string): string | null;
|