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,198 @@
|
|
|
1
|
+
// Credentials: what is encrypted at rest, what never lands in session.json or the launch folder, what the one-shot
|
|
2
|
+
// secrets file carries, and that printed settings show *** for secrets.
|
|
3
|
+
import fs from 'node:fs';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { DEFAULTS } from '../core/config/index.js';
|
|
6
|
+
import { ConfigSchema, HarnessSchema, redactSecrets, scrubSecrets, secretPaths } from '../core/schema/index.js';
|
|
7
|
+
import { SchemaNode } from '../app/kernel/index.js';
|
|
8
|
+
import { SandboxChannel } from '../host/channel/index.js';
|
|
9
|
+
import { AccountStore, AgentAccountStore } from '../host/profile/index.js';
|
|
10
|
+
import { clearSecrets, SecretStore, withoutSecrets } from '../host/secrets/index.js';
|
|
11
|
+
import { sharingAclPlan } from '../host/sharing/index.js';
|
|
12
|
+
import { RunDir } from '../shared/channel/index.js';
|
|
13
|
+
import { mergeRequestSecrets } from '../shared/channel/secrets.js';
|
|
14
|
+
const API_KEY = 'sk-planted-ENV-7f3a9c1d';
|
|
15
|
+
const LOGIN = 'login-planted-4b2e';
|
|
16
|
+
/** Every file under `dir` that contains `needle` (text or not), so a planted secret cannot hide in a corner. */
|
|
17
|
+
function filesContaining(dir, needle) {
|
|
18
|
+
const found = [];
|
|
19
|
+
const walk = (d) => {
|
|
20
|
+
for (const entry of fs.readdirSync(d, { withFileTypes: true })) {
|
|
21
|
+
const file = path.join(d, entry.name);
|
|
22
|
+
if (entry.isDirectory())
|
|
23
|
+
walk(file);
|
|
24
|
+
else if (entry.isFile() && fs.statSync(file).size < 20 * 1024 * 1024 && fs.readFileSync(file).includes(needle))
|
|
25
|
+
found.push(path.relative(dir, file));
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
walk(dir);
|
|
29
|
+
return found;
|
|
30
|
+
}
|
|
31
|
+
export const credentialsSuite = {
|
|
32
|
+
name: 'credentials',
|
|
33
|
+
title: 'secrets: encrypted at rest, kept out of session.json and the launch folder, hidden when printed',
|
|
34
|
+
timeoutMs: 240000,
|
|
35
|
+
run: async (t, f) => {
|
|
36
|
+
t.section('the secret store');
|
|
37
|
+
const memory = SecretStore.memory();
|
|
38
|
+
const sealed = memory.sealJson({ a: 1, key: API_KEY });
|
|
39
|
+
t.check(SecretStore.isSealed(sealed) && !sealed.includes(API_KEY) && !sealed.includes('"a"'), 'a sealed value is one short opaque string');
|
|
40
|
+
t.equal(memory.openJson(sealed), { a: 1, key: API_KEY }, 'it opens again');
|
|
41
|
+
await t.throws(() => SecretStore.dpapi().open(sealed), 'another system', 'a value sealed by another kind of store is refused, never guessed at');
|
|
42
|
+
if (process.platform === 'win32') {
|
|
43
|
+
const dpapi = SecretStore.dpapi();
|
|
44
|
+
const real = dpapi.seal(API_KEY);
|
|
45
|
+
t.check(real.startsWith('dpapi1:') && !real.includes(API_KEY) && dpapi.open(real) === API_KEY, 'Windows DPAPI (through powershell.exe, nothing on a command line) seals and opens a value');
|
|
46
|
+
await t.throws(() => dpapi.open('dpapi1:AAAA'), 'could not decrypt', 'a value Windows cannot open fails with a message that says what to do');
|
|
47
|
+
}
|
|
48
|
+
else
|
|
49
|
+
t.skip('DPAPI needs Windows');
|
|
50
|
+
t.section('saved Claude logins are encrypted at rest');
|
|
51
|
+
const storage = t.at('cred-storage');
|
|
52
|
+
const dataA = path.join(storage, 'data', 'x');
|
|
53
|
+
const claudeDir = path.join(dataA, 'state', 'claude');
|
|
54
|
+
t.write(path.join(claudeDir, '.credentials.json'), '{"claudeAiOauth":{"refreshToken":"' + LOGIN + '-1"}}');
|
|
55
|
+
t.write(path.join(claudeDir, '.claude.json'), '{"oauthAccount":{"emailAddress":"me@example.com"}}');
|
|
56
|
+
const accounts = new AccountStore(storage);
|
|
57
|
+
accounts.save(dataA, 'personal', null);
|
|
58
|
+
const saved = fs.readFileSync(path.join(storage, 'accounts', 'personal.json'), 'utf8');
|
|
59
|
+
t.check(!saved.includes(LOGIN) && saved.includes('me@example.com') && saved.includes('"sealed"'), 'the file shows the name, date and e-mail only; the tokens are sealed');
|
|
60
|
+
t.check(accounts.list(dataA)[0]?.email === 'me@example.com' && accounts.meta('personal')?.name === 'personal', 'listing needs no decryption');
|
|
61
|
+
t.includes(JSON.stringify(accounts.read('personal')?.credentials), LOGIN + '-1', 'reading an account opens it (when switching)');
|
|
62
|
+
t.write(path.join(storage, 'accounts', 'old.json'), JSON.stringify({
|
|
63
|
+
name: 'old',
|
|
64
|
+
savedAt: '2026-01-01T00:00:00.000Z',
|
|
65
|
+
email: null,
|
|
66
|
+
credentials: { claudeAiOauth: { refreshToken: LOGIN + '-legacy' } },
|
|
67
|
+
oauthAccount: {},
|
|
68
|
+
}));
|
|
69
|
+
const migrated = new AccountStore(storage).list(dataA);
|
|
70
|
+
t.check(migrated.some((a) => a.name === 'old') &&
|
|
71
|
+
!fs.readFileSync(path.join(storage, 'accounts', 'old.json'), 'utf8').includes(LOGIN), 'an account saved plain by an older version is encrypted the first time accounts are listed, and the plain text is gone');
|
|
72
|
+
t.includes(JSON.stringify(new AccountStore(storage).read('old')?.credentials), LOGIN + '-legacy', 'and it still opens');
|
|
73
|
+
new AccountStore(storage).activate(dataA, 'old');
|
|
74
|
+
t.includes(fs.readFileSync(path.join(claudeDir, '.credentials.json'), 'utf8'), LOGIN + '-legacy', 'switching decrypts it into the sandbox state');
|
|
75
|
+
t.section('other agents: login files are encrypted at rest');
|
|
76
|
+
const codexHome = t.at('cred-codex-home');
|
|
77
|
+
t.write(path.join(codexHome, 'auth.json'), '{"token":"' + LOGIN + '-codex"}');
|
|
78
|
+
const agent = new AgentAccountStore(storage, 'codex', ['auth.json']);
|
|
79
|
+
agent.save(dataA, 'main', codexHome, true);
|
|
80
|
+
const folder = path.join(storage, 'accounts', 'codex', 'main');
|
|
81
|
+
t.check(fs.existsSync(path.join(folder, 'auth.json.sealed')) &&
|
|
82
|
+
!fs.existsSync(path.join(folder, 'auth.json')) &&
|
|
83
|
+
filesContaining(folder, LOGIN).length === 0, 'the login file is stored sealed, never as it was');
|
|
84
|
+
const restored = t.at('cred-codex-to');
|
|
85
|
+
agent.activate(dataA, 'main', restored);
|
|
86
|
+
t.equal(fs.readFileSync(path.join(restored, 'auth.json'), 'utf8'), '{"token":"' + LOGIN + '-codex"}', 'switching puts the original file back');
|
|
87
|
+
t.write(path.join(storage, 'accounts', 'codex', 'older', 'auth.json'), '{"token":"' + LOGIN + '-older"}');
|
|
88
|
+
t.write(path.join(storage, 'accounts', 'codex', 'older', 'meta.json'), JSON.stringify({ name: 'older', savedAt: '2026-01-01T00:00:00.000Z' }));
|
|
89
|
+
agent.list(dataA);
|
|
90
|
+
t.check(filesContaining(path.join(storage, 'accounts', 'codex', 'older'), LOGIN).length === 0 &&
|
|
91
|
+
fs.existsSync(path.join(storage, 'accounts', 'codex', 'older', 'auth.json.sealed')), 'a copy saved plain by an older version is encrypted when the accounts are listed');
|
|
92
|
+
t.section('the agent environment and the Claude login stay out of the launch folder');
|
|
93
|
+
t.write(path.join(f.hostProfile, '.credentials.json'), '{"token":"' + LOGIN + '-host"}');
|
|
94
|
+
const config = f.makeConfig();
|
|
95
|
+
config.harnesses.claude.environment = { ANTHROPIC_API_KEY: API_KEY, DISABLE_AUTOUPDATER: '1' };
|
|
96
|
+
config.claudeProfile.copyCredentials = true;
|
|
97
|
+
const run = await f.run({}, config);
|
|
98
|
+
const gen = f.generate(run);
|
|
99
|
+
const session = fs.readFileSync(gen.sessionPath, 'utf8');
|
|
100
|
+
t.check(!session.includes(API_KEY) && !session.includes(LOGIN), 'session.json holds neither the API key nor the Claude login');
|
|
101
|
+
t.equal(filesContaining(gen.launchPath, API_KEY).concat(filesContaining(gen.launchPath, LOGIN + '-host')), [], 'nothing in the launch folder holds them either (it is mapped into the sandbox and kept for days)');
|
|
102
|
+
t.equal(f.readJson(gen.sessionPath).harness.environment, {}, "the booted agent's environment in session.json is empty");
|
|
103
|
+
const dir = new RunDir(run.dataPath);
|
|
104
|
+
const handed = f.readJson(dir.secretFile(gen.launchId));
|
|
105
|
+
t.check(handed.harnessEnvironment?.ANTHROPIC_API_KEY === API_KEY &&
|
|
106
|
+
handed.claudeCredentials?.includes(LOGIN + '-host') === true, 'both are in the one-shot file in <data>\\secrets for the sandbox to read and delete', JSON.stringify(handed));
|
|
107
|
+
t.check(path.relative(dir.root, dir.secretsDir).startsWith('..'), 'the one-shot folder is next to run, not in it: other users of a shared sandbox may change run');
|
|
108
|
+
const plan = sharingAclPlan({
|
|
109
|
+
storageUserDir: storage,
|
|
110
|
+
dataPath: path.join(storage, 'data', 'testdata'),
|
|
111
|
+
groupSid: 'S-1-5-32-545',
|
|
112
|
+
on: true,
|
|
113
|
+
});
|
|
114
|
+
t.check(plan.filter((c) => c.rights === 'Modify').every((c) => path.basename(c.path) === 'run') &&
|
|
115
|
+
!plan.some((c) => c.path.includes('secrets')), 'sharing opens only run for writing, never the secrets folder');
|
|
116
|
+
t.write(path.join(storage, 'launches', 'older', 'claude-profile', '.credentials.json'), '{"x":1}');
|
|
117
|
+
t.check(clearSecrets(storage, run.dataPath) >= 2 &&
|
|
118
|
+
!fs.existsSync(dir.secretFile(gen.launchId)) &&
|
|
119
|
+
!fs.existsSync(path.join(storage, 'launches', 'older', 'claude-profile', '.credentials.json')), 'what the sandbox never read, and a login left in an old launch folder, is removed (at launch and when the sandbox stops)');
|
|
120
|
+
t.write(path.join(f.hostProfile, '.credentials.json'), '{ "token": "secret" }');
|
|
121
|
+
t.section('requests carry no environment values');
|
|
122
|
+
const request = {
|
|
123
|
+
kind: 'session',
|
|
124
|
+
id: 'req1',
|
|
125
|
+
harness: 'codex',
|
|
126
|
+
args: [],
|
|
127
|
+
cwd: 'C:\\Workspace\\x',
|
|
128
|
+
harnessSpec: { ...config.harnesses.claude, environment: { OPENAI_API_KEY: API_KEY } },
|
|
129
|
+
project: {
|
|
130
|
+
name: 'other',
|
|
131
|
+
workspace: 'C:\\Workspace\\other',
|
|
132
|
+
workspaceHost: 'C:\\other',
|
|
133
|
+
toolchains: DEFAULTS.toolchains,
|
|
134
|
+
versions: run.versions,
|
|
135
|
+
databases: [],
|
|
136
|
+
harnesses: { codex: { ...config.harnesses.claude, environment: { OTHER_KEY: API_KEY + '-2' } } },
|
|
137
|
+
hooks: false,
|
|
138
|
+
},
|
|
139
|
+
createdAt: new Date().toISOString(),
|
|
140
|
+
};
|
|
141
|
+
const stripped = withoutSecrets(request);
|
|
142
|
+
t.check(!JSON.stringify(stripped.request).includes(API_KEY) &&
|
|
143
|
+
stripped.secrets?.harnessSpecEnvironment?.OPENAI_API_KEY === API_KEY &&
|
|
144
|
+
stripped.secrets?.projectHarnessEnvironment?.codex?.OTHER_KEY === API_KEY + '-2', 'withoutSecrets takes the values out of the agent and the project agents');
|
|
145
|
+
t.equal(mergeRequestSecrets(stripped.request, stripped.secrets ?? {}), request, 'the sandbox puts them back, exactly, in memory');
|
|
146
|
+
t.equal(withoutSecrets({ kind: 'ping', id: 'p', createdAt: 'now' }).secrets, null, 'other requests are untouched');
|
|
147
|
+
const sent = new SandboxChannel(run.dataPath, () => true);
|
|
148
|
+
sent.requestSession('codex', [], 'C:\\Workspace\\x', { harnessSpec: request.harnessSpec });
|
|
149
|
+
const requestFiles = fs.readdirSync(dir.requestsDir);
|
|
150
|
+
t.check(requestFiles.length === 1 &&
|
|
151
|
+
filesContaining(dir.root, API_KEY).length === 0 &&
|
|
152
|
+
filesContaining(dir.secretsDir, API_KEY).length === 1, 'the host channel writes the request without the value (nothing in run holds it) and the value into its own one-shot file');
|
|
153
|
+
clearSecrets(storage, run.dataPath);
|
|
154
|
+
t.section('network.proxy takes no login');
|
|
155
|
+
const withProxy = (proxy) => ConfigSchema.safeParse({ ...DEFAULTS, network: { ...DEFAULTS.network, proxy } });
|
|
156
|
+
t.check(withProxy('http://proxy.corp:8080').success && withProxy('').success, 'a proxy address without a login is accepted');
|
|
157
|
+
const refused = withProxy('http://user:pass@proxy.corp:8080');
|
|
158
|
+
t.check(!refused.success && JSON.stringify(refused.error?.issues).includes('no user name or password'), 'a user name and password in the address is refused, with a plain reason');
|
|
159
|
+
t.check(!withProxy('https://token@proxy.corp').success, 'a lone token in front of @ is refused too');
|
|
160
|
+
t.section('secrets print as ***');
|
|
161
|
+
t.check(secretPaths().some((p) => p.join('.') === 'harnesses.*.environment.*'), 'agent environment values are marked secret in the schema');
|
|
162
|
+
t.check(new SchemaNode(HarnessSchema).child('environment')?.element?.secret === true, 'the settings screen knows them as secret too (hidden input, *** in lists)');
|
|
163
|
+
const planted = structuredClone(config);
|
|
164
|
+
const shown = redactSecrets(planted);
|
|
165
|
+
t.check(shown.harnesses.claude.environment.ANTHROPIC_API_KEY === '***' &&
|
|
166
|
+
shown.harnesses.claude.environment.DISABLE_AUTOUPDATER === '***' &&
|
|
167
|
+
planted.harnesses.claude.environment.ANTHROPIC_API_KEY === API_KEY &&
|
|
168
|
+
shown.harnesses.codex.arguments.length === planted.harnesses.codex.arguments.length, 'redactSecrets hides every environment value and leaves the rest and the original alone');
|
|
169
|
+
t.excludes(scrubSecrets(JSON.stringify({ anything: 'x ' + API_KEY + ' y' }), planted), API_KEY, 'scrubSecrets removes a secret from any text built from a config');
|
|
170
|
+
const home = t.dir('cred-cli', 'home');
|
|
171
|
+
const cliConfig = t.writeJson(t.at('cred-cli', 'config.json'), {
|
|
172
|
+
storage: { root: t.dir('cred-cli', 'storage') },
|
|
173
|
+
personalization: { enabled: false },
|
|
174
|
+
provisioning: { terminal: { enabled: false } },
|
|
175
|
+
harnesses: {
|
|
176
|
+
planted: { npmPackage: 'planted', npmBin: 'planted', arguments: [], environment: { PLANTED_KEY: API_KEY } },
|
|
177
|
+
},
|
|
178
|
+
});
|
|
179
|
+
const baseEnv = Object.fromEntries(Object.entries(process.env).filter(([k]) => !['AGENT_SANDBOX_CONFIG', 'AGENT_WORKSPACE'].includes(k)));
|
|
180
|
+
const env = {
|
|
181
|
+
...baseEnv,
|
|
182
|
+
AGENT_SANDBOX_HOME: home,
|
|
183
|
+
AGENT_LAUNCH_DIR: t.at('cred-cli', 'no-launch'),
|
|
184
|
+
AGENT_DATA_DIR: t.at('cred-cli', 'no-data'),
|
|
185
|
+
NO_COLOR: '1',
|
|
186
|
+
AGENT_SANDBOX_HOST_ONLY: '1',
|
|
187
|
+
};
|
|
188
|
+
for (const args of [
|
|
189
|
+
['config', 'show'],
|
|
190
|
+
['doctor', '--json'],
|
|
191
|
+
['vpn', 'status', '--json'],
|
|
192
|
+
['status', '--json'],
|
|
193
|
+
]) {
|
|
194
|
+
const out = await f.runBin('agent-sandbox', [...args, '--config', cliConfig], { cwd: f.workA, env });
|
|
195
|
+
t.check(!out.out.includes(API_KEY) && (args[0] !== 'config' || out.out.includes('***')), 'sandbox ' + args.join(' ') + ' never prints the planted key' + (args[0] === 'config' ? ' (it shows ***)' : ''), out.out.slice(0, 400));
|
|
196
|
+
}
|
|
197
|
+
},
|
|
198
|
+
};
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
// The engine layer and storage providers (phase 1): the Windows Sandbox engine writes exactly the .wsb and launch
|
|
2
|
+
// folder the code before the layer did, the settings for later engines are refused clearly, and a project cannot set
|
|
3
|
+
// them.
|
|
4
|
+
import fs from 'node:fs';
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
import { DEFAULTS } from '../core/config/index.js';
|
|
7
|
+
import { LocalOverridesSchema } from '../core/schema/index.js';
|
|
8
|
+
import { xmlEscape } from '../core/util/index.js';
|
|
9
|
+
import { engineFor, engineReports, WindowsSandboxEngine, } from '../host/engines/index.js';
|
|
10
|
+
import { buildLaunchPlan, buildWsb } from '../host/launch/index.js';
|
|
11
|
+
import { folderAttachment, FolderStorageProvider, providerFor } from '../host/storage/index.js';
|
|
12
|
+
import { sandboxFolder } from '../shared/paths/index.js';
|
|
13
|
+
import { NO_HCS_PC } from './support/hcs-probes.js';
|
|
14
|
+
import { ENGINE_CASES } from './support/engine-cases.js';
|
|
15
|
+
import { ENGINE_GOLDEN, LAUNCH_FILES_GOLDEN } from './support/engine-golden.js';
|
|
16
|
+
/** The .wsb writer as it was before the engine layer (frozen copy), to compare real launches with. */
|
|
17
|
+
function legacyWsb(config, memoryMb, mappings) {
|
|
18
|
+
const s = config.sandbox;
|
|
19
|
+
const element = (name, value) => '<' + name + '>' + value + '</' + name + '>';
|
|
20
|
+
const toggle = (value) => (value ? 'Enable' : 'Disable');
|
|
21
|
+
const devices = [
|
|
22
|
+
['vGPU', s.vGpu],
|
|
23
|
+
['Networking', s.networking],
|
|
24
|
+
['ClipboardRedirection', s.clipboard],
|
|
25
|
+
['AudioInput', s.audioInput],
|
|
26
|
+
['VideoInput', s.videoInput],
|
|
27
|
+
['PrinterRedirection', s.printerRedirection],
|
|
28
|
+
['ProtectedClient', s.protectedClient],
|
|
29
|
+
];
|
|
30
|
+
const folders = mappings
|
|
31
|
+
.map((m) => element('MappedFolder', element('HostFolder', xmlEscape(m.host)) +
|
|
32
|
+
element('SandboxFolder', xmlEscape(sandboxFolder(m.guest))) +
|
|
33
|
+
element('ReadOnly', String(m.readOnly))))
|
|
34
|
+
.join('');
|
|
35
|
+
return element('Configuration', element('MemoryInMB', String(memoryMb)) +
|
|
36
|
+
devices.map(([name, value]) => element(name, toggle(value))).join('') +
|
|
37
|
+
element('MappedFolders', folders) +
|
|
38
|
+
element('LogonCommand', element('Command', xmlEscape('C:\\AgentLaunch\\sandbox\\boot\\logon.cmd'))));
|
|
39
|
+
}
|
|
40
|
+
function filesUnder(dir, rel = '') {
|
|
41
|
+
return fs
|
|
42
|
+
.readdirSync(path.join(dir, rel), { withFileTypes: true })
|
|
43
|
+
.flatMap((e) => e.isDirectory() ? filesUnder(dir, rel ? rel + '/' + e.name : e.name) : [rel ? rel + '/' + e.name : e.name])
|
|
44
|
+
.sort();
|
|
45
|
+
}
|
|
46
|
+
export const engineSuite = {
|
|
47
|
+
name: 'engine',
|
|
48
|
+
title: 'engine layer, Windows Sandbox engine, storage providers, new settings',
|
|
49
|
+
run: async (t, f) => {
|
|
50
|
+
t.section('the .wsb through the engine is what it always was');
|
|
51
|
+
for (const c of ENGINE_CASES) {
|
|
52
|
+
const plan = buildLaunchPlan({
|
|
53
|
+
config: c.config,
|
|
54
|
+
memoryMb: c.memoryMb,
|
|
55
|
+
mappings: c.mappings,
|
|
56
|
+
launchPath: 'C:\\L\\launches\\1',
|
|
57
|
+
storage: [],
|
|
58
|
+
});
|
|
59
|
+
const viaEngine = new WindowsSandboxEngine(c.config.sandbox, () => false).plan(plan).files[0].text;
|
|
60
|
+
t.check(viaEngine === ENGINE_GOLDEN[c.name] &&
|
|
61
|
+
buildWsb(c.config, c.memoryMb, [...c.mappings]) === ENGINE_GOLDEN[c.name], 'byte-identical .wsb: ' + c.name, 'expected: ' + ENGINE_GOLDEN[c.name] + '\nactual: ' + viaEngine);
|
|
62
|
+
t.equal(viaEngine, legacyWsb(c.config, c.memoryMb, c.mappings), 'same as the frozen old writer: ' + c.name);
|
|
63
|
+
}
|
|
64
|
+
t.section('a real launch');
|
|
65
|
+
const gen = await f.launch({}, { args: ['--version'], probe: { ...f.probe, gitDir: f.shared, nvmDir: f.workB } });
|
|
66
|
+
t.equal(fs.readFileSync(gen.wsbPath, 'utf8'), legacyWsb(f.baseConfig, gen.memoryMb, gen.mappings), 'the launch writes the .wsb the old writer would have (same settings, memory and mappings)');
|
|
67
|
+
t.equal(path.basename(gen.wsbPath), 'agent.wsb', 'the engine file is still agent.wsb in the launch folder');
|
|
68
|
+
t.equal(gen.enginePlan.entry, gen.wsbPath, 'the engine plan starts from that file');
|
|
69
|
+
t.equal(filesUnder(gen.launchPath), [...LAUNCH_FILES_GOLDEN], 'the launch folder has exactly the files it had before');
|
|
70
|
+
t.equal(gen.mappings.find((m) => m.guest === 'C:\\AgentData')?.host, f.baseConfig.storage.root + '\\data\\testdata', 'the data folder is still mapped at C:\\AgentData (through the folder provider)');
|
|
71
|
+
t.section('capabilities');
|
|
72
|
+
const caps = (over, cli) => new WindowsSandboxEngine({ ...DEFAULTS.sandbox, ...over }, () => cli).capabilities();
|
|
73
|
+
t.equal(caps({}, false), {
|
|
74
|
+
desktop: true,
|
|
75
|
+
gpu: false,
|
|
76
|
+
clipboard: true,
|
|
77
|
+
audio: false,
|
|
78
|
+
video: false,
|
|
79
|
+
printers: false,
|
|
80
|
+
liveFolderAdd: false,
|
|
81
|
+
attachedDisks: false,
|
|
82
|
+
multipleInstances: false,
|
|
83
|
+
hvsocket: false,
|
|
84
|
+
}, 'Windows Sandbox: desktop and clipboard by default, no live folders without the wsb CLI, no disks, one at a time');
|
|
85
|
+
t.equal([caps({ vGpu: true, audioInput: true, videoInput: true, printerRedirection: true, clipboard: false }, true)].map((c) => [c.gpu, c.audio, c.video, c.printers, c.clipboard, c.liveFolderAdd]), [[true, true, true, true, false, true]], 'capabilities follow the device settings and the wsb CLI');
|
|
86
|
+
const reports = await engineReports(f.baseConfig, NO_HCS_PC);
|
|
87
|
+
t.check(reports.length === 2 &&
|
|
88
|
+
reports[0].inUse &&
|
|
89
|
+
!reports[1].inUse &&
|
|
90
|
+
!reports[1].check.available &&
|
|
91
|
+
reports[1].check.reasons[0].includes('computecore.dll'), 'sandbox engine lists both engines; the HCS check says what this PC lacks');
|
|
92
|
+
t.section('settings that cannot work yet are refused');
|
|
93
|
+
const hcs = { ...structuredClone(f.baseConfig), sandbox: { ...f.baseConfig.sandbox, engine: 'hcs' } };
|
|
94
|
+
const vhdx = {
|
|
95
|
+
...structuredClone(f.baseConfig),
|
|
96
|
+
storage: { ...f.baseConfig.storage, contained: 'vhdx' },
|
|
97
|
+
};
|
|
98
|
+
t.equal([DEFAULTS.sandbox.engine, DEFAULTS.storage.contained, DEFAULTS.storage.containedMaxGb], ['windows-sandbox', 'off', 64], 'defaults: Windows Sandbox, loose folders, 64 GB');
|
|
99
|
+
await t.throws(() => engineFor(hcs), 'The HCS engine has to be opened first', 'engine hcs is not handed out without its check');
|
|
100
|
+
await t.throws(() => providerFor(vhdx, {
|
|
101
|
+
availability: () => ({ available: false, reasons: ['No disks here.'], fixes: ['Use a PC.'] }),
|
|
102
|
+
}), 'Contained storage cannot be used: No disks here.', 'contained vhdx is refused where this PC cannot use it');
|
|
103
|
+
const launches = path.join(f.baseConfig.storage.root, 'launches');
|
|
104
|
+
const before = fs.readdirSync(launches).length;
|
|
105
|
+
await t.throws(() => f.launch({}, { config: hcs }), 'HCS engine has to be opened first', 'a launch with hcs stops');
|
|
106
|
+
await t.throws(() => f.launch({}, { config: vhdx }), 'Contained storage was not prepared for this launch', 'a launch with vhdx that was not mounted first stops');
|
|
107
|
+
t.equal(fs.readdirSync(launches).length, before, 'a refused launch writes no launch folder');
|
|
108
|
+
t.section('storage provider: folder');
|
|
109
|
+
const set = { dataPath: 'C:\\S\\data\\x', guest: 'C:\\AgentData' };
|
|
110
|
+
const prepared = await new FolderStorageProvider().prepare(set);
|
|
111
|
+
t.equal([prepared.attachments, prepared.mappings, (await new FolderStorageProvider().check()).available], [[folderAttachment(set)], [{ host: set.dataPath, guest: set.guest, readOnly: false }], true], 'the folder provider shares the data folder read/write, as before');
|
|
112
|
+
t.section('a project cannot choose the engine or the storage kind');
|
|
113
|
+
t.check(!LocalOverridesSchema.safeParse({ sandbox: { engine: 'hcs' } }).success &&
|
|
114
|
+
!LocalOverridesSchema.safeParse({ storage: { contained: 'vhdx' } }).success &&
|
|
115
|
+
!LocalOverridesSchema.safeParse({ storage: { containedMaxGb: 8 } }).success, "a project's .sandbox-config.json cannot set sandbox.engine, storage.contained or storage.containedMaxGb");
|
|
116
|
+
t.check(LocalOverridesSchema.safeParse({ sandbox: { vGpu: false } }).success, 'other sandbox settings are still allowed in a project file');
|
|
117
|
+
t.section('sandbox engine');
|
|
118
|
+
const run = await f.runBin('agent-sandbox', ['engine', '--json', '--config', t.writeJson(t.at('engine-config.json'), {})], {
|
|
119
|
+
cwd: f.workA,
|
|
120
|
+
env: { ...process.env, NO_COLOR: '1', AGENT_SANDBOX_HOME: t.dir('engine-home'), AGENT_SANDBOX_HOST_ONLY: '1' },
|
|
121
|
+
});
|
|
122
|
+
const parsed = JSON.parse(run.out.slice(run.out.indexOf('{')));
|
|
123
|
+
t.check(run.status === 0 &&
|
|
124
|
+
parsed.engine === 'windows-sandbox' &&
|
|
125
|
+
parsed.engines.map((e) => e.id).join() === 'windows-sandbox,hcs', 'sandbox engine --json names the engine in use and both engines', run.out);
|
|
126
|
+
},
|
|
127
|
+
};
|
|
@@ -38,7 +38,7 @@ export const generateSuite = {
|
|
|
38
38
|
'sandbox/csharp/LinkGate.cs',
|
|
39
39
|
];
|
|
40
40
|
const missing = expectedFiles.filter((file) => !fs.existsSync(path.join(gen.launchPath, file)));
|
|
41
|
-
t.check(missing.length === 0 && fs.readdirSync(path.join(gen.launchPath, 'runtime')).length ===
|
|
41
|
+
t.check(missing.length === 0 && fs.readdirSync(path.join(gen.launchPath, 'runtime')).length === 7, 'the launch folder has the runtime (7 self-contained files), the C# sources and the boot scripts', missing.join(', '));
|
|
42
42
|
const logon = fs.readFileSync(path.join(gen.launchPath, 'sandbox', 'boot', 'logon.cmd'), 'utf8');
|
|
43
43
|
t.check(logon.indexOf('trust.cmd') < logon.indexOf('wt.exe') &&
|
|
44
44
|
logon.includes('tools\\terminal\\wt.exe') &&
|