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
package/dist/runtime/main.js
CHANGED
|
@@ -1363,11 +1363,11 @@ var require_lodash = __commonJS({
|
|
|
1363
1363
|
return isFunction(object2[key]);
|
|
1364
1364
|
});
|
|
1365
1365
|
}
|
|
1366
|
-
function baseGet(object2,
|
|
1367
|
-
|
|
1368
|
-
var index = 0, length =
|
|
1366
|
+
function baseGet(object2, path75) {
|
|
1367
|
+
path75 = castPath(path75, object2);
|
|
1368
|
+
var index = 0, length = path75.length;
|
|
1369
1369
|
while (object2 != null && index < length) {
|
|
1370
|
-
object2 = object2[toKey(
|
|
1370
|
+
object2 = object2[toKey(path75[index++])];
|
|
1371
1371
|
}
|
|
1372
1372
|
return index && index == length ? object2 : undefined2;
|
|
1373
1373
|
}
|
|
@@ -1431,10 +1431,10 @@ var require_lodash = __commonJS({
|
|
|
1431
1431
|
});
|
|
1432
1432
|
return accumulator;
|
|
1433
1433
|
}
|
|
1434
|
-
function baseInvoke(object2,
|
|
1435
|
-
|
|
1436
|
-
object2 = parent(object2,
|
|
1437
|
-
var func = object2 == null ? object2 : object2[toKey(last(
|
|
1434
|
+
function baseInvoke(object2, path75, args) {
|
|
1435
|
+
path75 = castPath(path75, object2);
|
|
1436
|
+
object2 = parent(object2, path75);
|
|
1437
|
+
var func = object2 == null ? object2 : object2[toKey(last(path75))];
|
|
1438
1438
|
return func == null ? undefined2 : apply(func, object2, args);
|
|
1439
1439
|
}
|
|
1440
1440
|
function baseIsArguments(value) {
|
|
@@ -1590,13 +1590,13 @@ var require_lodash = __commonJS({
|
|
|
1590
1590
|
return object2 === source || baseIsMatch(object2, source, matchData);
|
|
1591
1591
|
};
|
|
1592
1592
|
}
|
|
1593
|
-
function baseMatchesProperty(
|
|
1594
|
-
if (isKey(
|
|
1595
|
-
return matchesStrictComparable(toKey(
|
|
1593
|
+
function baseMatchesProperty(path75, srcValue) {
|
|
1594
|
+
if (isKey(path75) && isStrictComparable(srcValue)) {
|
|
1595
|
+
return matchesStrictComparable(toKey(path75), srcValue);
|
|
1596
1596
|
}
|
|
1597
1597
|
return function(object2) {
|
|
1598
|
-
var objValue = get(object2,
|
|
1599
|
-
return objValue === undefined2 && objValue === srcValue ? hasIn(object2,
|
|
1598
|
+
var objValue = get(object2, path75);
|
|
1599
|
+
return objValue === undefined2 && objValue === srcValue ? hasIn(object2, path75) : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG);
|
|
1600
1600
|
};
|
|
1601
1601
|
}
|
|
1602
1602
|
function baseMerge(object2, source, srcIndex, customizer, stack) {
|
|
@@ -1693,23 +1693,23 @@ var require_lodash = __commonJS({
|
|
|
1693
1693
|
});
|
|
1694
1694
|
}
|
|
1695
1695
|
function basePick(object2, paths) {
|
|
1696
|
-
return basePickBy(object2, paths, function(value,
|
|
1697
|
-
return hasIn(object2,
|
|
1696
|
+
return basePickBy(object2, paths, function(value, path75) {
|
|
1697
|
+
return hasIn(object2, path75);
|
|
1698
1698
|
});
|
|
1699
1699
|
}
|
|
1700
1700
|
function basePickBy(object2, paths, predicate) {
|
|
1701
1701
|
var index = -1, length = paths.length, result2 = {};
|
|
1702
1702
|
while (++index < length) {
|
|
1703
|
-
var
|
|
1704
|
-
if (predicate(value,
|
|
1705
|
-
baseSet(result2, castPath(
|
|
1703
|
+
var path75 = paths[index], value = baseGet(object2, path75);
|
|
1704
|
+
if (predicate(value, path75)) {
|
|
1705
|
+
baseSet(result2, castPath(path75, object2), value);
|
|
1706
1706
|
}
|
|
1707
1707
|
}
|
|
1708
1708
|
return result2;
|
|
1709
1709
|
}
|
|
1710
|
-
function basePropertyDeep(
|
|
1710
|
+
function basePropertyDeep(path75) {
|
|
1711
1711
|
return function(object2) {
|
|
1712
|
-
return baseGet(object2,
|
|
1712
|
+
return baseGet(object2, path75);
|
|
1713
1713
|
};
|
|
1714
1714
|
}
|
|
1715
1715
|
function basePullAll(array2, values2, iteratee2, comparator) {
|
|
@@ -1783,14 +1783,14 @@ var require_lodash = __commonJS({
|
|
|
1783
1783
|
var array2 = values(collection);
|
|
1784
1784
|
return shuffleSelf(array2, baseClamp(n, 0, array2.length));
|
|
1785
1785
|
}
|
|
1786
|
-
function baseSet(object2,
|
|
1786
|
+
function baseSet(object2, path75, value, customizer) {
|
|
1787
1787
|
if (!isObject2(object2)) {
|
|
1788
1788
|
return object2;
|
|
1789
1789
|
}
|
|
1790
|
-
|
|
1791
|
-
var index = -1, length =
|
|
1790
|
+
path75 = castPath(path75, object2);
|
|
1791
|
+
var index = -1, length = path75.length, lastIndex = length - 1, nested = object2;
|
|
1792
1792
|
while (nested != null && ++index < length) {
|
|
1793
|
-
var key = toKey(
|
|
1793
|
+
var key = toKey(path75[index]), newValue = value;
|
|
1794
1794
|
if (key === "__proto__" || key === "constructor" || key === "prototype") {
|
|
1795
1795
|
return object2;
|
|
1796
1796
|
}
|
|
@@ -1798,7 +1798,7 @@ var require_lodash = __commonJS({
|
|
|
1798
1798
|
var objValue = nested[key];
|
|
1799
1799
|
newValue = customizer ? customizer(objValue, key, nested) : undefined2;
|
|
1800
1800
|
if (newValue === undefined2) {
|
|
1801
|
-
newValue = isObject2(objValue) ? objValue : isIndex(
|
|
1801
|
+
newValue = isObject2(objValue) ? objValue : isIndex(path75[index + 1]) ? [] : {};
|
|
1802
1802
|
}
|
|
1803
1803
|
}
|
|
1804
1804
|
assignValue(nested, key, newValue);
|
|
@@ -1964,14 +1964,14 @@ var require_lodash = __commonJS({
|
|
|
1964
1964
|
}
|
|
1965
1965
|
return result2;
|
|
1966
1966
|
}
|
|
1967
|
-
function baseUnset(object2,
|
|
1968
|
-
|
|
1969
|
-
var index = -1, length =
|
|
1967
|
+
function baseUnset(object2, path75) {
|
|
1968
|
+
path75 = castPath(path75, object2);
|
|
1969
|
+
var index = -1, length = path75.length;
|
|
1970
1970
|
if (!length) {
|
|
1971
1971
|
return true;
|
|
1972
1972
|
}
|
|
1973
1973
|
while (++index < length) {
|
|
1974
|
-
var key = toKey(
|
|
1974
|
+
var key = toKey(path75[index]);
|
|
1975
1975
|
if (key === "__proto__" && !hasOwnProperty.call(object2, "__proto__")) {
|
|
1976
1976
|
return false;
|
|
1977
1977
|
}
|
|
@@ -1979,11 +1979,11 @@ var require_lodash = __commonJS({
|
|
|
1979
1979
|
return false;
|
|
1980
1980
|
}
|
|
1981
1981
|
}
|
|
1982
|
-
var obj = parent(object2,
|
|
1983
|
-
return obj == null || delete obj[toKey(last(
|
|
1982
|
+
var obj = parent(object2, path75);
|
|
1983
|
+
return obj == null || delete obj[toKey(last(path75))];
|
|
1984
1984
|
}
|
|
1985
|
-
function baseUpdate(object2,
|
|
1986
|
-
return baseSet(object2,
|
|
1985
|
+
function baseUpdate(object2, path75, updater, customizer) {
|
|
1986
|
+
return baseSet(object2, path75, updater(baseGet(object2, path75)), customizer);
|
|
1987
1987
|
}
|
|
1988
1988
|
function baseWhile(array2, predicate, isDrop, fromRight) {
|
|
1989
1989
|
var length = array2.length, index = fromRight ? length : -1;
|
|
@@ -2866,11 +2866,11 @@ var require_lodash = __commonJS({
|
|
|
2866
2866
|
var match = source.match(reWrapDetails);
|
|
2867
2867
|
return match ? match[1].split(reSplitDetails) : [];
|
|
2868
2868
|
}
|
|
2869
|
-
function hasPath(object2,
|
|
2870
|
-
|
|
2871
|
-
var index = -1, length =
|
|
2869
|
+
function hasPath(object2, path75, hasFunc) {
|
|
2870
|
+
path75 = castPath(path75, object2);
|
|
2871
|
+
var index = -1, length = path75.length, result2 = false;
|
|
2872
2872
|
while (++index < length) {
|
|
2873
|
-
var key = toKey(
|
|
2873
|
+
var key = toKey(path75[index]);
|
|
2874
2874
|
if (!(result2 = object2 != null && hasFunc(object2, key))) {
|
|
2875
2875
|
break;
|
|
2876
2876
|
}
|
|
@@ -3072,8 +3072,8 @@ var require_lodash = __commonJS({
|
|
|
3072
3072
|
return apply(func, this, otherArgs);
|
|
3073
3073
|
};
|
|
3074
3074
|
}
|
|
3075
|
-
function parent(object2,
|
|
3076
|
-
return
|
|
3075
|
+
function parent(object2, path75) {
|
|
3076
|
+
return path75.length < 2 ? object2 : baseGet(object2, baseSlice(path75, 0, -1));
|
|
3077
3077
|
}
|
|
3078
3078
|
function reorder(array2, indexes) {
|
|
3079
3079
|
var arrLength = array2.length, length = nativeMin(indexes.length, arrLength), oldArray = copyArray(array2);
|
|
@@ -3230,7 +3230,7 @@ var require_lodash = __commonJS({
|
|
|
3230
3230
|
}
|
|
3231
3231
|
return isArrayLikeObject(array2) ? baseDifference(array2, baseFlatten(values2, 1, isArrayLikeObject, true), undefined2, comparator) : [];
|
|
3232
3232
|
});
|
|
3233
|
-
function
|
|
3233
|
+
function drop2(array2, n, guard) {
|
|
3234
3234
|
var length = array2 == null ? 0 : array2.length;
|
|
3235
3235
|
if (!length) {
|
|
3236
3236
|
return [];
|
|
@@ -3461,7 +3461,7 @@ var require_lodash = __commonJS({
|
|
|
3461
3461
|
function sortedUniqBy(array2, iteratee2) {
|
|
3462
3462
|
return array2 && array2.length ? baseSortedUniq(array2, getIteratee(iteratee2, 2)) : [];
|
|
3463
3463
|
}
|
|
3464
|
-
function
|
|
3464
|
+
function tail2(array2) {
|
|
3465
3465
|
var length = array2 == null ? 0 : array2.length;
|
|
3466
3466
|
return length ? baseSlice(array2, 1, length) : [];
|
|
3467
3467
|
}
|
|
@@ -3708,10 +3708,10 @@ var require_lodash = __commonJS({
|
|
|
3708
3708
|
}
|
|
3709
3709
|
return isString(collection) ? fromIndex <= length && collection.indexOf(value, fromIndex) > -1 : !!length && baseIndexOf(collection, value, fromIndex) > -1;
|
|
3710
3710
|
}
|
|
3711
|
-
var invokeMap = baseRest(function(collection,
|
|
3712
|
-
var index = -1, isFunc = typeof
|
|
3711
|
+
var invokeMap = baseRest(function(collection, path75, args) {
|
|
3712
|
+
var index = -1, isFunc = typeof path75 == "function", result2 = isArrayLike(collection) ? Array2(collection.length) : [];
|
|
3713
3713
|
baseEach(collection, function(value) {
|
|
3714
|
-
result2[++index] = isFunc ? apply(
|
|
3714
|
+
result2[++index] = isFunc ? apply(path75, value, args) : baseInvoke(value, path75, args);
|
|
3715
3715
|
});
|
|
3716
3716
|
return result2;
|
|
3717
3717
|
});
|
|
@@ -4363,15 +4363,15 @@ var require_lodash = __commonJS({
|
|
|
4363
4363
|
function functionsIn(object2) {
|
|
4364
4364
|
return object2 == null ? [] : baseFunctions(object2, keysIn(object2));
|
|
4365
4365
|
}
|
|
4366
|
-
function get(object2,
|
|
4367
|
-
var result2 = object2 == null ? undefined2 : baseGet(object2,
|
|
4366
|
+
function get(object2, path75, defaultValue) {
|
|
4367
|
+
var result2 = object2 == null ? undefined2 : baseGet(object2, path75);
|
|
4368
4368
|
return result2 === undefined2 ? defaultValue : result2;
|
|
4369
4369
|
}
|
|
4370
|
-
function has(object2,
|
|
4371
|
-
return object2 != null && hasPath(object2,
|
|
4370
|
+
function has(object2, path75) {
|
|
4371
|
+
return object2 != null && hasPath(object2, path75, baseHas);
|
|
4372
4372
|
}
|
|
4373
|
-
function hasIn(object2,
|
|
4374
|
-
return object2 != null && hasPath(object2,
|
|
4373
|
+
function hasIn(object2, path75) {
|
|
4374
|
+
return object2 != null && hasPath(object2, path75, baseHasIn);
|
|
4375
4375
|
}
|
|
4376
4376
|
var invert = createInverter(function(result2, value, key) {
|
|
4377
4377
|
if (value != null && typeof value.toString != "function") {
|
|
@@ -4424,10 +4424,10 @@ var require_lodash = __commonJS({
|
|
|
4424
4424
|
return result2;
|
|
4425
4425
|
}
|
|
4426
4426
|
var isDeep = false;
|
|
4427
|
-
paths = arrayMap(paths, function(
|
|
4428
|
-
|
|
4429
|
-
isDeep || (isDeep =
|
|
4430
|
-
return
|
|
4427
|
+
paths = arrayMap(paths, function(path75) {
|
|
4428
|
+
path75 = castPath(path75, object2);
|
|
4429
|
+
isDeep || (isDeep = path75.length > 1);
|
|
4430
|
+
return path75;
|
|
4431
4431
|
});
|
|
4432
4432
|
copyObject(object2, getAllKeysIn(object2), result2);
|
|
4433
4433
|
if (isDeep) {
|
|
@@ -4453,19 +4453,19 @@ var require_lodash = __commonJS({
|
|
|
4453
4453
|
return [prop];
|
|
4454
4454
|
});
|
|
4455
4455
|
predicate = getIteratee(predicate);
|
|
4456
|
-
return basePickBy(object2, props, function(value,
|
|
4457
|
-
return predicate(value,
|
|
4456
|
+
return basePickBy(object2, props, function(value, path75) {
|
|
4457
|
+
return predicate(value, path75[0]);
|
|
4458
4458
|
});
|
|
4459
4459
|
}
|
|
4460
|
-
function result(object2,
|
|
4461
|
-
|
|
4462
|
-
var index = -1, length =
|
|
4460
|
+
function result(object2, path75, defaultValue) {
|
|
4461
|
+
path75 = castPath(path75, object2);
|
|
4462
|
+
var index = -1, length = path75.length;
|
|
4463
4463
|
if (!length) {
|
|
4464
4464
|
length = 1;
|
|
4465
4465
|
object2 = undefined2;
|
|
4466
4466
|
}
|
|
4467
4467
|
while (++index < length) {
|
|
4468
|
-
var value = object2 == null ? undefined2 : object2[toKey(
|
|
4468
|
+
var value = object2 == null ? undefined2 : object2[toKey(path75[index])];
|
|
4469
4469
|
if (value === undefined2) {
|
|
4470
4470
|
index = length;
|
|
4471
4471
|
value = defaultValue;
|
|
@@ -4474,12 +4474,12 @@ var require_lodash = __commonJS({
|
|
|
4474
4474
|
}
|
|
4475
4475
|
return object2;
|
|
4476
4476
|
}
|
|
4477
|
-
function set2(object2,
|
|
4478
|
-
return object2 == null ? object2 : baseSet(object2,
|
|
4477
|
+
function set2(object2, path75, value) {
|
|
4478
|
+
return object2 == null ? object2 : baseSet(object2, path75, value);
|
|
4479
4479
|
}
|
|
4480
|
-
function setWith(object2,
|
|
4480
|
+
function setWith(object2, path75, value, customizer) {
|
|
4481
4481
|
customizer = typeof customizer == "function" ? customizer : undefined2;
|
|
4482
|
-
return object2 == null ? object2 : baseSet(object2,
|
|
4482
|
+
return object2 == null ? object2 : baseSet(object2, path75, value, customizer);
|
|
4483
4483
|
}
|
|
4484
4484
|
var toPairs = createToPairs(keys);
|
|
4485
4485
|
var toPairsIn = createToPairs(keysIn);
|
|
@@ -4501,15 +4501,15 @@ var require_lodash = __commonJS({
|
|
|
4501
4501
|
});
|
|
4502
4502
|
return accumulator;
|
|
4503
4503
|
}
|
|
4504
|
-
function unset(object2,
|
|
4505
|
-
return object2 == null ? true : baseUnset(object2,
|
|
4504
|
+
function unset(object2, path75) {
|
|
4505
|
+
return object2 == null ? true : baseUnset(object2, path75);
|
|
4506
4506
|
}
|
|
4507
|
-
function update(object2,
|
|
4508
|
-
return object2 == null ? object2 : baseUpdate(object2,
|
|
4507
|
+
function update(object2, path75, updater) {
|
|
4508
|
+
return object2 == null ? object2 : baseUpdate(object2, path75, castFunction(updater));
|
|
4509
4509
|
}
|
|
4510
|
-
function updateWith(object2,
|
|
4510
|
+
function updateWith(object2, path75, updater, customizer) {
|
|
4511
4511
|
customizer = typeof customizer == "function" ? customizer : undefined2;
|
|
4512
|
-
return object2 == null ? object2 : baseUpdate(object2,
|
|
4512
|
+
return object2 == null ? object2 : baseUpdate(object2, path75, castFunction(updater), customizer);
|
|
4513
4513
|
}
|
|
4514
4514
|
function values(object2) {
|
|
4515
4515
|
return object2 == null ? [] : baseValues(object2, keys(object2));
|
|
@@ -4532,7 +4532,7 @@ var require_lodash = __commonJS({
|
|
|
4532
4532
|
}
|
|
4533
4533
|
return baseClamp(toNumber(number4), lower, upper);
|
|
4534
4534
|
}
|
|
4535
|
-
function
|
|
4535
|
+
function inRange2(number4, start, end) {
|
|
4536
4536
|
start = toFinite(start);
|
|
4537
4537
|
if (end === undefined2) {
|
|
4538
4538
|
end = start;
|
|
@@ -4895,17 +4895,17 @@ var require_lodash = __commonJS({
|
|
|
4895
4895
|
function matches(source) {
|
|
4896
4896
|
return baseMatches(baseClone(source, CLONE_DEEP_FLAG));
|
|
4897
4897
|
}
|
|
4898
|
-
function matchesProperty(
|
|
4899
|
-
return baseMatchesProperty(
|
|
4898
|
+
function matchesProperty(path75, srcValue) {
|
|
4899
|
+
return baseMatchesProperty(path75, baseClone(srcValue, CLONE_DEEP_FLAG));
|
|
4900
4900
|
}
|
|
4901
|
-
var method = baseRest(function(
|
|
4901
|
+
var method = baseRest(function(path75, args) {
|
|
4902
4902
|
return function(object2) {
|
|
4903
|
-
return baseInvoke(object2,
|
|
4903
|
+
return baseInvoke(object2, path75, args);
|
|
4904
4904
|
};
|
|
4905
4905
|
});
|
|
4906
4906
|
var methodOf = baseRest(function(object2, args) {
|
|
4907
|
-
return function(
|
|
4908
|
-
return baseInvoke(object2,
|
|
4907
|
+
return function(path75) {
|
|
4908
|
+
return baseInvoke(object2, path75, args);
|
|
4909
4909
|
};
|
|
4910
4910
|
});
|
|
4911
4911
|
function mixin(object2, source, options) {
|
|
@@ -4952,12 +4952,12 @@ var require_lodash = __commonJS({
|
|
|
4952
4952
|
var over = createOver(arrayMap);
|
|
4953
4953
|
var overEvery = createOver(arrayEvery);
|
|
4954
4954
|
var overSome = createOver(arraySome);
|
|
4955
|
-
function property(
|
|
4956
|
-
return isKey(
|
|
4955
|
+
function property(path75) {
|
|
4956
|
+
return isKey(path75) ? baseProperty(toKey(path75)) : basePropertyDeep(path75);
|
|
4957
4957
|
}
|
|
4958
4958
|
function propertyOf(object2) {
|
|
4959
|
-
return function(
|
|
4960
|
-
return object2 == null ? undefined2 : baseGet(object2,
|
|
4959
|
+
return function(path75) {
|
|
4960
|
+
return object2 == null ? undefined2 : baseGet(object2, path75);
|
|
4961
4961
|
};
|
|
4962
4962
|
}
|
|
4963
4963
|
var range = createRange();
|
|
@@ -5071,7 +5071,7 @@ var require_lodash = __commonJS({
|
|
|
5071
5071
|
lodash.difference = difference;
|
|
5072
5072
|
lodash.differenceBy = differenceBy;
|
|
5073
5073
|
lodash.differenceWith = differenceWith;
|
|
5074
|
-
lodash.drop =
|
|
5074
|
+
lodash.drop = drop2;
|
|
5075
5075
|
lodash.dropRight = dropRight;
|
|
5076
5076
|
lodash.dropRightWhile = dropRightWhile;
|
|
5077
5077
|
lodash.dropWhile = dropWhile;
|
|
@@ -5151,7 +5151,7 @@ var require_lodash = __commonJS({
|
|
|
5151
5151
|
lodash.sortedUniqBy = sortedUniqBy;
|
|
5152
5152
|
lodash.split = split;
|
|
5153
5153
|
lodash.spread = spread;
|
|
5154
|
-
lodash.tail =
|
|
5154
|
+
lodash.tail = tail2;
|
|
5155
5155
|
lodash.take = take;
|
|
5156
5156
|
lodash.takeRight = takeRight;
|
|
5157
5157
|
lodash.takeRightWhile = takeRightWhile;
|
|
@@ -5235,7 +5235,7 @@ var require_lodash = __commonJS({
|
|
|
5235
5235
|
lodash.identity = identity;
|
|
5236
5236
|
lodash.includes = includes;
|
|
5237
5237
|
lodash.indexOf = indexOf;
|
|
5238
|
-
lodash.inRange =
|
|
5238
|
+
lodash.inRange = inRange2;
|
|
5239
5239
|
lodash.invoke = invoke;
|
|
5240
5240
|
lodash.isArguments = isArguments;
|
|
5241
5241
|
lodash.isArray = isArray;
|
|
@@ -5410,12 +5410,12 @@ var require_lodash = __commonJS({
|
|
|
5410
5410
|
LazyWrapper.prototype.findLast = function(predicate) {
|
|
5411
5411
|
return this.reverse().find(predicate);
|
|
5412
5412
|
};
|
|
5413
|
-
LazyWrapper.prototype.invokeMap = baseRest(function(
|
|
5414
|
-
if (typeof
|
|
5413
|
+
LazyWrapper.prototype.invokeMap = baseRest(function(path75, args) {
|
|
5414
|
+
if (typeof path75 == "function") {
|
|
5415
5415
|
return new LazyWrapper(this);
|
|
5416
5416
|
}
|
|
5417
5417
|
return this.map(function(value) {
|
|
5418
|
-
return baseInvoke(value,
|
|
5418
|
+
return baseInvoke(value, path75, args);
|
|
5419
5419
|
});
|
|
5420
5420
|
});
|
|
5421
5421
|
LazyWrapper.prototype.reject = function(predicate) {
|
|
@@ -5532,8 +5532,8 @@ var require_lodash = __commonJS({
|
|
|
5532
5532
|
});
|
|
5533
5533
|
|
|
5534
5534
|
// src/guest/entries/main.ts
|
|
5535
|
-
import
|
|
5536
|
-
import
|
|
5535
|
+
import fs60 from "node:fs";
|
|
5536
|
+
import path74 from "node:path";
|
|
5537
5537
|
|
|
5538
5538
|
// src/guest/runtime/paths.ts
|
|
5539
5539
|
import path7 from "node:path";
|
|
@@ -6358,10 +6358,10 @@ function mergeDefs(...defs) {
|
|
|
6358
6358
|
function cloneDef(schema) {
|
|
6359
6359
|
return mergeDefs(schema._zod.def);
|
|
6360
6360
|
}
|
|
6361
|
-
function getElementAtPath(obj,
|
|
6362
|
-
if (!
|
|
6361
|
+
function getElementAtPath(obj, path75) {
|
|
6362
|
+
if (!path75)
|
|
6363
6363
|
return obj;
|
|
6364
|
-
return
|
|
6364
|
+
return path75.reduce((acc, key) => acc?.[key], obj);
|
|
6365
6365
|
}
|
|
6366
6366
|
function promiseAllObject(promisesObj) {
|
|
6367
6367
|
const keys = Object.keys(promisesObj);
|
|
@@ -6701,11 +6701,11 @@ function explicitlyAborted(x, startIndex = 0) {
|
|
|
6701
6701
|
}
|
|
6702
6702
|
return false;
|
|
6703
6703
|
}
|
|
6704
|
-
function prefixIssues(
|
|
6704
|
+
function prefixIssues(path75, issues) {
|
|
6705
6705
|
return issues.map((iss) => {
|
|
6706
6706
|
var _a3;
|
|
6707
6707
|
(_a3 = iss).path ?? (_a3.path = []);
|
|
6708
|
-
iss.path.unshift(
|
|
6708
|
+
iss.path.unshift(path75);
|
|
6709
6709
|
return iss;
|
|
6710
6710
|
});
|
|
6711
6711
|
}
|
|
@@ -7155,16 +7155,16 @@ function flattenError(error62, mapper = (issue2) => issue2.message) {
|
|
|
7155
7155
|
}
|
|
7156
7156
|
function formatError(error62, mapper = (issue2) => issue2.message) {
|
|
7157
7157
|
const fieldErrors = { _errors: [] };
|
|
7158
|
-
const processError = (error63,
|
|
7158
|
+
const processError = (error63, path75 = []) => {
|
|
7159
7159
|
for (const issue2 of error63.issues) {
|
|
7160
7160
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
7161
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
7161
|
+
issue2.errors.map((issues) => processError({ issues }, [...path75, ...issue2.path]));
|
|
7162
7162
|
} else if (issue2.code === "invalid_key") {
|
|
7163
|
-
processError({ issues: issue2.issues }, [...
|
|
7163
|
+
processError({ issues: issue2.issues }, [...path75, ...issue2.path]);
|
|
7164
7164
|
} else if (issue2.code === "invalid_element") {
|
|
7165
|
-
processError({ issues: issue2.issues }, [...
|
|
7165
|
+
processError({ issues: issue2.issues }, [...path75, ...issue2.path]);
|
|
7166
7166
|
} else {
|
|
7167
|
-
const fullpath = [...
|
|
7167
|
+
const fullpath = [...path75, ...issue2.path];
|
|
7168
7168
|
if (fullpath.length === 0) {
|
|
7169
7169
|
fieldErrors._errors.push(mapper(issue2));
|
|
7170
7170
|
} else {
|
|
@@ -7203,17 +7203,17 @@ function formatError(error62, mapper = (issue2) => issue2.message) {
|
|
|
7203
7203
|
}
|
|
7204
7204
|
function treeifyError(error62, mapper = (issue2) => issue2.message) {
|
|
7205
7205
|
const result = { errors: [] };
|
|
7206
|
-
const processError = (error63,
|
|
7206
|
+
const processError = (error63, path75 = []) => {
|
|
7207
7207
|
var _a3;
|
|
7208
7208
|
for (const issue2 of error63.issues) {
|
|
7209
7209
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
7210
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
7210
|
+
issue2.errors.map((issues) => processError({ issues }, [...path75, ...issue2.path]));
|
|
7211
7211
|
} else if (issue2.code === "invalid_key") {
|
|
7212
|
-
processError({ issues: issue2.issues }, [...
|
|
7212
|
+
processError({ issues: issue2.issues }, [...path75, ...issue2.path]);
|
|
7213
7213
|
} else if (issue2.code === "invalid_element") {
|
|
7214
|
-
processError({ issues: issue2.issues }, [...
|
|
7214
|
+
processError({ issues: issue2.issues }, [...path75, ...issue2.path]);
|
|
7215
7215
|
} else {
|
|
7216
|
-
const fullpath = [...
|
|
7216
|
+
const fullpath = [...path75, ...issue2.path];
|
|
7217
7217
|
if (fullpath.length === 0) {
|
|
7218
7218
|
result.errors.push(mapper(issue2));
|
|
7219
7219
|
continue;
|
|
@@ -7252,8 +7252,8 @@ function treeifyError(error62, mapper = (issue2) => issue2.message) {
|
|
|
7252
7252
|
}
|
|
7253
7253
|
function toDotPath(_path) {
|
|
7254
7254
|
const segs = [];
|
|
7255
|
-
const
|
|
7256
|
-
for (const seg of
|
|
7255
|
+
const path75 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
7256
|
+
for (const seg of path75) {
|
|
7257
7257
|
if (typeof seg === "number")
|
|
7258
7258
|
segs.push(`[${seg}]`);
|
|
7259
7259
|
else if (typeof seg === "symbol")
|
|
@@ -10030,9 +10030,9 @@ var $ZodTransform = /* @__PURE__ */ $constructor("$ZodTransform", (inst, def) =>
|
|
|
10030
10030
|
}
|
|
10031
10031
|
const _out = def.transform(payload.value, payload);
|
|
10032
10032
|
if (ctx.async) {
|
|
10033
|
-
const
|
|
10034
|
-
return
|
|
10035
|
-
payload.value =
|
|
10033
|
+
const output3 = _out instanceof Promise ? _out : Promise.resolve(_out);
|
|
10034
|
+
return output3.then((output4) => {
|
|
10035
|
+
payload.value = output4;
|
|
10036
10036
|
return payload;
|
|
10037
10037
|
});
|
|
10038
10038
|
}
|
|
@@ -10482,12 +10482,12 @@ var $ZodFunction = /* @__PURE__ */ $constructor("$ZodFunction", (inst, def) => {
|
|
|
10482
10482
|
output: inst._def.output
|
|
10483
10483
|
});
|
|
10484
10484
|
};
|
|
10485
|
-
inst.output = (
|
|
10485
|
+
inst.output = (output3) => {
|
|
10486
10486
|
const F = inst.constructor;
|
|
10487
10487
|
return new F({
|
|
10488
10488
|
type: "function",
|
|
10489
10489
|
input: inst._def.input,
|
|
10490
|
-
output:
|
|
10490
|
+
output: output3
|
|
10491
10491
|
});
|
|
10492
10492
|
};
|
|
10493
10493
|
return inst;
|
|
@@ -23896,14 +23896,14 @@ var ZodTransform = /* @__PURE__ */ $constructor("ZodTransform", (inst, def) => {
|
|
|
23896
23896
|
payload.issues.push(util_exports.issue(_issue));
|
|
23897
23897
|
}
|
|
23898
23898
|
};
|
|
23899
|
-
const
|
|
23900
|
-
if (
|
|
23901
|
-
return
|
|
23902
|
-
payload.value =
|
|
23899
|
+
const output3 = def.transform(payload.value, payload);
|
|
23900
|
+
if (output3 instanceof Promise) {
|
|
23901
|
+
return output3.then((output4) => {
|
|
23902
|
+
payload.value = output4;
|
|
23903
23903
|
return payload;
|
|
23904
23904
|
});
|
|
23905
23905
|
}
|
|
23906
|
-
payload.value =
|
|
23906
|
+
payload.value = output3;
|
|
23907
23907
|
return payload;
|
|
23908
23908
|
};
|
|
23909
23909
|
});
|
|
@@ -24355,13 +24355,13 @@ function resolveRef(ref, ctx) {
|
|
|
24355
24355
|
if (!ref.startsWith("#")) {
|
|
24356
24356
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
24357
24357
|
}
|
|
24358
|
-
const
|
|
24359
|
-
if (
|
|
24358
|
+
const path75 = ref.slice(1).split("/").filter(Boolean);
|
|
24359
|
+
if (path75.length === 0) {
|
|
24360
24360
|
return ctx.rootSchema;
|
|
24361
24361
|
}
|
|
24362
24362
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
24363
|
-
if (
|
|
24364
|
-
const key =
|
|
24363
|
+
if (path75[0] === defsKey) {
|
|
24364
|
+
const key = path75[1] === void 0 ? void 0 : decodeJSONPointerSegment(path75[1]);
|
|
24365
24365
|
if (!key || !ctx.defs[key]) {
|
|
24366
24366
|
throw new Error(`Reference not found: ${ref}`);
|
|
24367
24367
|
}
|
|
@@ -25292,6 +25292,9 @@ function enabled(what, markers) {
|
|
|
25292
25292
|
function Packages(what, example) {
|
|
25293
25293
|
return StringsSchema.describe(what + ", installed once and kept (e.g. " + example + ").");
|
|
25294
25294
|
}
|
|
25295
|
+
function secret(schema) {
|
|
25296
|
+
return schema.meta({ secret: true });
|
|
25297
|
+
}
|
|
25295
25298
|
|
|
25296
25299
|
// src/core/schema/config.ts
|
|
25297
25300
|
var import_lodash = __toESM(require_lodash(), 1);
|
|
@@ -25360,10 +25363,18 @@ var HarnessSchema = external_exports.strictObject({
|
|
|
25360
25363
|
uvPackage: external_exports.string().optional().describe("Python package installed with `uv tool install` inside the sandbox (e.g. aider-chat)."),
|
|
25361
25364
|
uvBin: external_exports.string().optional().describe("Command the uv package provides."),
|
|
25362
25365
|
arguments: StringsSchema.describe("Arguments always passed to the agent."),
|
|
25363
|
-
environment: external_exports.record(external_exports.string(), external_exports.string()).describe(
|
|
25366
|
+
environment: external_exports.record(external_exports.string(), secret(external_exports.string())).describe(
|
|
25367
|
+
"Environment variables for the agent (API keys go here). Their values are shown as *** and are handed to the sandbox in a one-shot file, never kept in the launch folder. The agent can read its own environment."
|
|
25368
|
+
),
|
|
25364
25369
|
home: HarnessHomeSchema.optional().describe(
|
|
25365
25370
|
"Where its login lives inside the sandbox; leave out when the agent cannot be pointed at a folder (then its login is not kept between sandboxes)."
|
|
25366
25371
|
),
|
|
25372
|
+
localState: external_exports.record(external_exports.string().regex(/^[A-Za-z_][A-Za-z0-9_]*$/), SubfolderSchema).optional().describe(
|
|
25373
|
+
"Environment variable -> folder below the agent's own state folder (state\\<agent>) for SQLite databases. SQLite cannot run in a mapped folder, so the agent runs from a copy on the sandbox's disk (the variable points to it) that is copied from and back to that folder."
|
|
25374
|
+
),
|
|
25375
|
+
bootReset: external_exports.array(SubfolderSchema).max(32).optional().describe(
|
|
25376
|
+
"Files and folders below the agent's own state folder (state\\<agent>) that only work on the machine that wrote them (keys sealed with Windows DPAPI, local accounts it created). Every sandbox is a new machine, so they are deleted at each boot and the agent sets them up again."
|
|
25377
|
+
),
|
|
25367
25378
|
resumeArguments: StringsSchema.optional().describe(
|
|
25368
25379
|
"Arguments used when the agent is restarted in place (e.g. after an account switch) so it resumes the conversation."
|
|
25369
25380
|
),
|
|
@@ -25415,6 +25426,9 @@ var ClaudeProfileSchema = external_exports.strictObject({
|
|
|
25415
25426
|
globalStateFile: external_exports.string().describe('Your .claude.json, or "auto". Empty string = do not copy.'),
|
|
25416
25427
|
copyCredentials: external_exports.boolean().describe("Copy your Claude LOGIN into the sandbox. Prefer sandbox account instead."),
|
|
25417
25428
|
overwrite: external_exports.boolean().describe("Refresh these settings from this PC on every launch."),
|
|
25429
|
+
sharePluginsAcrossAccounts: external_exports.boolean().describe(
|
|
25430
|
+
"When you switch Claude accounts, copy your Claude plugins (and which ones are enabled) into a data set that has none yet. Off by default: plugins are code that runs in your sessions."
|
|
25431
|
+
),
|
|
25418
25432
|
syncHistory: external_exports.boolean().describe("Bring conversation history in, and sync new history back (path-translated)."),
|
|
25419
25433
|
historyScope: external_exports.enum(["project", "all"]).describe(
|
|
25420
25434
|
`Which history comes in: "project" = only the projects in this sandbox (other projects' conversations, file backups and prompts stay on this PC), "all" = everything. Only this sandbox's projects ever sync back.`
|
|
@@ -25438,6 +25452,9 @@ var MappingSchema = external_exports.strictObject({
|
|
|
25438
25452
|
optional: external_exports.boolean().optional().describe("true = skip it quietly when the host folder does not exist.")
|
|
25439
25453
|
});
|
|
25440
25454
|
var SandboxSchema = external_exports.strictObject({
|
|
25455
|
+
engine: external_exports.enum(["windows-sandbox", "hcs"]).describe(
|
|
25456
|
+
'(alpha) What runs the sandbox. "windows-sandbox" = Windows Sandbox (the default: desktop, Windows Terminal, GPU, clipboard, audio, printers). "hcs" = a headless Hyper-V isolated Server Core container for agents (no desktop, GPU or clipboard); it needs Windows features and an image on this PC (sandbox engine check hcs lists what is missing), and starting it is not enabled yet in this alpha. sandbox engine shows what each engine can do. Yours only: a project file (.sandbox-config.json) cannot set it.'
|
|
25457
|
+
),
|
|
25441
25458
|
memoryMb: external_exports.union([external_exports.literal("auto"), external_exports.number().int().min(2048)]).describe('Sandbox RAM in MB (>= 2048), or "auto": free RAM minus reserveHostMb, capped at maxMemoryMb.'),
|
|
25442
25459
|
maxMemoryMb: external_exports.number().int().positive().describe('Upper limit for memoryMb "auto".'),
|
|
25443
25460
|
maxMemoryPercent: external_exports.number().int().min(10).max(100).describe(`memoryMb "auto" never takes more than this share of this PC's total RAM (percent).`),
|
|
@@ -25447,10 +25464,22 @@ var SandboxSchema = external_exports.strictObject({
|
|
|
25447
25464
|
pageFileMb: external_exports.number().int().min(0).max(262144).describe(
|
|
25448
25465
|
`Size of the sandbox's paging file in MB, created at full size when it starts so it never grows while builds run (8 GB of its disk always stays free). Windows Sandbox starts with about 1 GB: parallel builds then fail with "The paging file is too small", and Windows grows the file under load. 0 = leave Windows' own.`
|
|
25449
25466
|
),
|
|
25450
|
-
reserveHostMb: external_exports.number().int().nonnegative().describe(
|
|
25451
|
-
|
|
25467
|
+
reserveHostMb: external_exports.number().int().nonnegative().describe(
|
|
25468
|
+
'Memory always left for this PC when memoryMb is "auto": the sandbox gets at most (free RAM, and RAM plus paging file still unused) minus this.'
|
|
25469
|
+
),
|
|
25470
|
+
agentMemoryHeadroomMb: external_exports.union([external_exports.literal("auto"), external_exports.literal("none"), external_exports.number().int().min(0)]).describe(
|
|
25471
|
+
'Memory kept out of the agents reach inside the sandbox, in MB: everything the agents start (their builds, tests, tools) together may use at most the sandbox memory minus this; a runaway parallel build then gets out-of-memory errors in its own session instead of freezing or crashing the whole sandbox. "auto" = the larger of 2048 MB and 10 % of the sandbox memory; "none" = no limit. Yours only: a project file cannot change it.'
|
|
25472
|
+
),
|
|
25473
|
+
pressureResponse: external_exports.boolean().describe(
|
|
25474
|
+
"When the sandbox (or this PC) runs low on memory, slow the heaviest build programs down (lower priority) and, if that is not enough, pause the biggest compiler for a few seconds at a time, so heavy parallel builds slow down instead of closing the sandbox. Never touches the agents themselves. Yours only: a project file cannot change it."
|
|
25475
|
+
),
|
|
25476
|
+
vGpu: external_exports.boolean().describe(
|
|
25477
|
+
"Virtual GPU. Off by default: Microsoft notes it widens the sandbox attack surface. The sandbox then uses this PC's graphics card, and with some graphics drivers heavy use can freeze the whole PC: turn it on only when a program in the sandbox needs the GPU (the mesa toolchain gives software OpenGL without it)."
|
|
25478
|
+
),
|
|
25452
25479
|
networking: external_exports.boolean().describe("Internet access. false is the only hard network isolation Windows Sandbox offers."),
|
|
25453
|
-
clipboard: external_exports.boolean().describe(
|
|
25480
|
+
clipboard: external_exports.boolean().describe(
|
|
25481
|
+
"Shared clipboard between this PC and the sandbox. Also lets an agent's copy (in sandbox attach) reach this PC's clipboard."
|
|
25482
|
+
),
|
|
25454
25483
|
audioInput: external_exports.boolean().describe("Microphone access."),
|
|
25455
25484
|
videoInput: external_exports.boolean().describe("Camera access."),
|
|
25456
25485
|
printerRedirection: external_exports.boolean().describe("Printers from this PC."),
|
|
@@ -25491,7 +25520,10 @@ var NetworkSchema = external_exports.strictObject({
|
|
|
25491
25520
|
"Reach servers in the sandbox from this PC: http://localhost:<pc> here goes to <sandbox> inside, while it runs. Nothing else on your network can use them."
|
|
25492
25521
|
),
|
|
25493
25522
|
dns: external_exports.array(external_exports.string().regex(/^\d{1,3}(\.\d{1,3}){3}$/, "an IPv4 address like 1.1.1.1")).describe("DNS servers for the sandbox instead of your network's, e.g. 1.1.1.1 and 9.9.9.9."),
|
|
25494
|
-
proxy: external_exports.string().regex(/^(https?:\/\/[^\s]+)?$/, "http://host:port").
|
|
25523
|
+
proxy: external_exports.string().regex(/^(https?:\/\/[^\s]+)?$/, "http://host:port").refine(
|
|
25524
|
+
(v) => !/^https?:\/\/[^/?#]*@/i.test(v),
|
|
25525
|
+
"no user name or password in the address (it would be stored in plain text and visible to the agent): use a proxy that needs no login"
|
|
25526
|
+
).describe(
|
|
25495
25527
|
"An HTTP proxy the sandbox uses to reach the internet (HTTP_PROXY / HTTPS_PROXY for everything in it), e.g. http://proxy.corp:8080. Empty = none."
|
|
25496
25528
|
)
|
|
25497
25529
|
});
|
|
@@ -25893,6 +25925,17 @@ var APPS = [
|
|
|
25893
25925
|
exe: "lazygit.exe",
|
|
25894
25926
|
cli: true
|
|
25895
25927
|
},
|
|
25928
|
+
{
|
|
25929
|
+
id: "jj",
|
|
25930
|
+
name: "Jujutsu (jj)",
|
|
25931
|
+
category: "git",
|
|
25932
|
+
about: "Git-compatible version control; conflicts do not block a rebase. Pilot, untested with worktrees.",
|
|
25933
|
+
size: "10 MB",
|
|
25934
|
+
source: gh("jj-vcs/jj", "^jj-v[\\d.]+-x86_64-pc-windows-msvc\\.zip$"),
|
|
25935
|
+
exe: "jj.exe",
|
|
25936
|
+
cli: true,
|
|
25937
|
+
fullGitOnly: true
|
|
25938
|
+
},
|
|
25896
25939
|
// ---- utilities
|
|
25897
25940
|
{
|
|
25898
25941
|
id: "7zip",
|
|
@@ -26421,6 +26464,26 @@ var APPS = [
|
|
|
26421
26464
|
source: gh("gitleaks/gitleaks", "^gitleaks_[\\d.]+_windows_x64\\.zip$"),
|
|
26422
26465
|
exe: "gitleaks.exe",
|
|
26423
26466
|
cli: true
|
|
26467
|
+
},
|
|
26468
|
+
{
|
|
26469
|
+
id: "ast-grep",
|
|
26470
|
+
name: "ast-grep",
|
|
26471
|
+
category: "cli",
|
|
26472
|
+
about: "Search and rewrite code by its syntax tree (ast-grep, sg); prints only the matches.",
|
|
26473
|
+
size: "15 MB",
|
|
26474
|
+
source: gh("ast-grep/ast-grep", "^app-x86_64-pc-windows-msvc\\.zip$"),
|
|
26475
|
+
exe: "ast-grep.exe",
|
|
26476
|
+
cli: true
|
|
26477
|
+
},
|
|
26478
|
+
{
|
|
26479
|
+
id: "rust-analyzer",
|
|
26480
|
+
name: "rust-analyzer",
|
|
26481
|
+
category: "cli",
|
|
26482
|
+
about: "Rust language server: type errors and go-to-definition without cargo (for editors and the Claude LSP plugin).",
|
|
26483
|
+
size: "18 MB",
|
|
26484
|
+
source: gh("rust-lang/rust-analyzer", "^rust-analyzer-x86_64-pc-windows-msvc\\.zip$"),
|
|
26485
|
+
exe: "rust-analyzer.exe",
|
|
26486
|
+
cli: true
|
|
26424
26487
|
}
|
|
26425
26488
|
];
|
|
26426
26489
|
function appById(id) {
|
|
@@ -26529,6 +26592,33 @@ var ResumeSchema = external_exports.strictObject({
|
|
|
26529
26592
|
)
|
|
26530
26593
|
});
|
|
26531
26594
|
|
|
26595
|
+
// src/core/schema/web.ts
|
|
26596
|
+
var WebSchema = external_exports.strictObject({
|
|
26597
|
+
enabled: external_exports.boolean().describe(
|
|
26598
|
+
"(Beta) Allow the web UI: your sandbox sessions in a browser on this PC. Off by default, and nothing starts it by itself yet: sandbox web start works either way and runs it until sandbox web stop (or a restart of the PC)."
|
|
26599
|
+
),
|
|
26600
|
+
port: external_exports.number().int().min(1024).max(65535).describe("Port of the web UI on 127.0.0.1 (this PC only). Pick another when it is taken.")
|
|
26601
|
+
});
|
|
26602
|
+
|
|
26603
|
+
// src/core/schema/vpn.ts
|
|
26604
|
+
var VPN_PROVIDERS = ["nordvpn", "openvpn-file", "wireguard-file"];
|
|
26605
|
+
var VpnSchema = external_exports.strictObject({
|
|
26606
|
+
enabled: external_exports.boolean().describe(
|
|
26607
|
+
"Send the sandbox's traffic through a VPN. Only the sandbox: your PC's own connection is untouched. Needs a saved login first (sandbox vpn login). The agent in the sandbox can read that login and can turn the tunnel off (it is the administrator there)."
|
|
26608
|
+
),
|
|
26609
|
+
provider: external_exports.enum(VPN_PROVIDERS).describe(
|
|
26610
|
+
"nordvpn: a recommended NordVPN server is picked at every launch. openvpn-file: your own .ovpn file (configFile). wireguard-file: your own WireGuard .conf (configFile), e.g. from your company."
|
|
26611
|
+
),
|
|
26612
|
+
protocol: external_exports.enum(["udp", "tcp"]).describe("udp is faster; tcp gets through networks that block udp."),
|
|
26613
|
+
country: external_exports.string().regex(/^([A-Za-z][A-Za-z .'-]{0,39})?$/, "a country name or code like uk or Germany").describe("nordvpn: the country of the server, e.g. uk, us or Germany. Empty = the best server anywhere."),
|
|
26614
|
+
configFile: external_exports.string().describe(
|
|
26615
|
+
"openvpn-file / wireguard-file: the .ovpn or .conf file on this PC (an .ovpn has its certificates inside it). Files that run programs (script-security, up, down, plugin, PostUp ...) are refused. A WireGuard file holds your private key: it is read when a sandbox starts and handed over in a one-shot file. A project's file can never set this."
|
|
26616
|
+
),
|
|
26617
|
+
killSwitch: external_exports.boolean().describe(
|
|
26618
|
+
"Block all traffic that does not go through the tunnel: when the tunnel cannot start, the sandbox stays offline instead of using your normal connection. A project can only turn this on, never off."
|
|
26619
|
+
)
|
|
26620
|
+
});
|
|
26621
|
+
|
|
26532
26622
|
// src/core/schema/config.ts
|
|
26533
26623
|
var ConfigSchema = external_exports.strictObject({
|
|
26534
26624
|
$schema: SchemaRefSchema.optional(),
|
|
@@ -26541,17 +26631,24 @@ var ConfigSchema = external_exports.strictObject({
|
|
|
26541
26631
|
sandbox: SandboxSchema,
|
|
26542
26632
|
sharing: SharingSchema,
|
|
26543
26633
|
storage: external_exports.strictObject({
|
|
26544
|
-
root: external_exports.string().min(1).describe(
|
|
26634
|
+
root: external_exports.string().min(1).describe(
|
|
26635
|
+
"Where everything is kept on this PC (tools, databases, logins, launches). The default is a private folder for you under %ProgramData%\\AgentSandbox\\users, which works for installs for one user and for everyone. sandbox storage move <folder> moves it."
|
|
26636
|
+
),
|
|
26545
26637
|
persistAgentState: external_exports.boolean().describe("Keep agent logins and history between sandboxes."),
|
|
26546
26638
|
dataName: NameSchema.describe("Name of the persistent data set (C:\\AgentData) shared by all workspaces."),
|
|
26547
26639
|
markSandboxFiles: external_exports.boolean().describe(
|
|
26548
26640
|
`Programs and scripts (.exe, .ps1, .bat, .cmd, .msi, .lnk ...) that appear or change in your project while a sandbox runs get Windows' "downloaded from the internet" mark, so SmartScreen and PowerShell ask before they run on this PC.`
|
|
26549
26641
|
),
|
|
26642
|
+
contained: external_exports.enum(["off", "vhdx"]).describe(
|
|
26643
|
+
'(beta) Keep the sandbox tools, state and logs inside one disk image file (vhdx) instead of loose folders, so scanning programs on this PC see one file. Not yet tried on a real PC. Turn it on with sandbox storage contained on (it moves your files and asks first); Windows asks for permission to mount the image when a sandbox starts. "off" = loose folders, as always. Yours only: a project file (.sandbox-config.json) cannot set it.'
|
|
26644
|
+
),
|
|
26645
|
+
containedMaxGb: external_exports.number().int().min(8).max(4096).describe("(beta) Largest size, in GB, the disk image of storage.contained may grow to."),
|
|
26550
26646
|
warnDataGb: external_exports.number().min(0).describe(
|
|
26551
26647
|
"Say at launch when the persisted data (tools, databases, logins) is bigger than this many GB; 0 = never. sandbox data shows what takes the space."
|
|
26552
26648
|
)
|
|
26553
26649
|
}),
|
|
26554
26650
|
network: NetworkSchema,
|
|
26651
|
+
vpn: VpnSchema,
|
|
26555
26652
|
provisioning: ProvisioningSchema,
|
|
26556
26653
|
downloads: DownloadsSchema,
|
|
26557
26654
|
toolchains: ToolchainsSchema,
|
|
@@ -26559,6 +26656,7 @@ var ConfigSchema = external_exports.strictObject({
|
|
|
26559
26656
|
"Databases running inside the sandbox. Data persists in C:\\AgentData\\databases; each one starts at boot."
|
|
26560
26657
|
),
|
|
26561
26658
|
attach: AttachSchema,
|
|
26659
|
+
web: WebSchema,
|
|
26562
26660
|
agentCommands: AgentCommandsSchema,
|
|
26563
26661
|
secrets: SecretsSchema,
|
|
26564
26662
|
personalization: toggle("Copy your desktop look (theme, accent, taskbar, wallpaper, ...) into the sandbox."),
|
|
@@ -26588,9 +26686,17 @@ var LocalOverridesSchema = external_exports.strictObject({
|
|
|
26588
26686
|
"Scripts (.ps1 / .mjs / .cmd, relative to this file) run inside the sandbox before the agent."
|
|
26589
26687
|
),
|
|
26590
26688
|
// This PC's resources are yours to share: CPU and paging file (this PC's disk) are not a project's to set.
|
|
26591
|
-
sandbox: SandboxSchema.omit({
|
|
26689
|
+
sandbox: SandboxSchema.omit({
|
|
26690
|
+
cpuLimit: true,
|
|
26691
|
+
pageFileMb: true,
|
|
26692
|
+
engine: true,
|
|
26693
|
+
agentMemoryHeadroomMb: true,
|
|
26694
|
+
pressureResponse: true
|
|
26695
|
+
}).partial(),
|
|
26592
26696
|
// A project may block more (the LAN, hosts); it never opens hosts, ports, DNS or a proxy.
|
|
26593
26697
|
network: NetworkSchema.pick({ blockPrivateRanges: true, blockHosts: true }).partial(),
|
|
26698
|
+
// A project may turn the kill switch on, never off, and never choose a VPN, a server, a file or a login.
|
|
26699
|
+
vpn: VpnSchema.pick({ killSwitch: true }).partial(),
|
|
26594
26700
|
provisioning: ProvisioningSchema.pick({ copyFromHost: true, fallbackToInstall: true, refresh: true }).extend({ git: GitSchema.partial(), terminal: toggle("Windows Terminal as the sandbox window.").partial() }).partial(),
|
|
26595
26701
|
downloads: DownloadsSchema.partial(),
|
|
26596
26702
|
// Every toolchain setting, each one optional (a project usually only switches languages on or pins a version).
|
|
@@ -26695,8 +26801,34 @@ var GuestRequestSchema = external_exports.discriminatedUnion("kind", [
|
|
|
26695
26801
|
cwd: Text().optional(),
|
|
26696
26802
|
createdAt: TimeSchema
|
|
26697
26803
|
}),
|
|
26698
|
-
external_exports.strictObject({ kind: external_exports.literal("ping"), id: IdSchema, createdAt: TimeSchema })
|
|
26804
|
+
external_exports.strictObject({ kind: external_exports.literal("ping"), id: IdSchema, createdAt: TimeSchema }),
|
|
26805
|
+
/**
|
|
26806
|
+
* The PC's own memory or CPU is running low (the host watchdog): the sandbox slows its heaviest builds down for
|
|
26807
|
+
* `seconds` (it never stops them) so Windows does not have to close it. Repeated while the PC stays low.
|
|
26808
|
+
*/
|
|
26809
|
+
external_exports.strictObject({
|
|
26810
|
+
kind: external_exports.literal("pressure"),
|
|
26811
|
+
id: IdSchema,
|
|
26812
|
+
reason: Text(300),
|
|
26813
|
+
seconds: external_exports.number().int().min(10).max(300),
|
|
26814
|
+
createdAt: TimeSchema
|
|
26815
|
+
})
|
|
26699
26816
|
]);
|
|
26817
|
+
var PressureStatusSchema = external_exports.object({
|
|
26818
|
+
level: external_exports.enum(["ok", "throttled", "suspending"]),
|
|
26819
|
+
profile: external_exports.enum(["normal", "gentle"]),
|
|
26820
|
+
/** Share of the sandbox's RAM still free and of its commit limit in use (percent). */
|
|
26821
|
+
ramFreePercent: external_exports.number().int().min(0).max(100),
|
|
26822
|
+
commitPercent: external_exports.number().int().min(0).max(100),
|
|
26823
|
+
/** Programs running at lower priority because of it. */
|
|
26824
|
+
lowered: external_exports.number().int().min(0).max(1024),
|
|
26825
|
+
/** Programs paused right now (name, process id, seconds left). */
|
|
26826
|
+
paused: external_exports.array(external_exports.object({ name: Text(64), pid: external_exports.number().int(), seconds: external_exports.number().int().min(0).max(60) })).max(8),
|
|
26827
|
+
/** The PC itself asked for slowing down (its memory or CPU is low). */
|
|
26828
|
+
pcLow: external_exports.boolean(),
|
|
26829
|
+
lastAction: Text(300),
|
|
26830
|
+
updatedAt: TimeSchema
|
|
26831
|
+
});
|
|
26700
26832
|
var GuestResponseSchema = external_exports.object({
|
|
26701
26833
|
id: IdSchema,
|
|
26702
26834
|
ok: external_exports.boolean(),
|
|
@@ -26731,6 +26863,16 @@ var ProjectStatusSchema = external_exports.object({
|
|
|
26731
26863
|
databases: external_exports.array(external_exports.object({ database: Text(32), port: external_exports.number().int() })).max(16),
|
|
26732
26864
|
summary: external_exports.array(Text(512)).max(64)
|
|
26733
26865
|
});
|
|
26866
|
+
var VpnStatusSchema = external_exports.object({
|
|
26867
|
+
state: external_exports.enum(["off", "starting", "up", "failed"]),
|
|
26868
|
+
message: Text(2e3),
|
|
26869
|
+
killSwitch: external_exports.boolean(),
|
|
26870
|
+
/** The server's name, e.g. uk2201.nordvpn.com. */
|
|
26871
|
+
server: Text(128).optional(),
|
|
26872
|
+
/** What the sandbox's traffic looks like from outside, once the tunnel is up. */
|
|
26873
|
+
publicIp: Text(64).optional(),
|
|
26874
|
+
updatedAt: TimeSchema
|
|
26875
|
+
});
|
|
26734
26876
|
|
|
26735
26877
|
// src/shared/io/json.ts
|
|
26736
26878
|
import fs2 from "node:fs";
|
|
@@ -26894,20 +27036,28 @@ var scan = (schema, dir) => {
|
|
|
26894
27036
|
var RunDir = class {
|
|
26895
27037
|
root;
|
|
26896
27038
|
sandboxFile;
|
|
27039
|
+
vpnFile;
|
|
27040
|
+
/** What the memory governor in the sandbox is doing (pressure.json). */
|
|
27041
|
+
pressureFile;
|
|
26897
27042
|
requestsDir;
|
|
26898
27043
|
responsesDir;
|
|
26899
27044
|
sessionsDir;
|
|
26900
27045
|
projectsDir;
|
|
26901
27046
|
/** audit.processes: programs the sandbox started, in small .jsonl files the host takes in and deletes. */
|
|
26902
27047
|
auditDir;
|
|
27048
|
+
/** One-shot secrets the host hands over (see secrets.ts). Next to run, not in it: shared-use users can change run. */
|
|
27049
|
+
secretsDir;
|
|
26903
27050
|
constructor(dataDir2) {
|
|
26904
27051
|
this.root = path6.join(dataDir2, "run");
|
|
26905
27052
|
this.sandboxFile = path6.join(this.root, "sandbox.json");
|
|
27053
|
+
this.vpnFile = path6.join(this.root, "vpn.json");
|
|
27054
|
+
this.pressureFile = path6.join(this.root, "pressure.json");
|
|
26906
27055
|
this.requestsDir = path6.join(this.root, "requests");
|
|
26907
27056
|
this.responsesDir = path6.join(this.root, "responses");
|
|
26908
27057
|
this.sessionsDir = path6.join(this.root, "sessions");
|
|
26909
27058
|
this.projectsDir = path6.join(this.root, "projects");
|
|
26910
27059
|
this.auditDir = path6.join(this.root, "audit");
|
|
27060
|
+
this.secretsDir = path6.join(dataDir2, "secrets");
|
|
26911
27061
|
}
|
|
26912
27062
|
requestFile(id) {
|
|
26913
27063
|
return path6.join(this.requestsDir, safeId(id) + ".json");
|
|
@@ -26921,9 +27071,18 @@ var RunDir = class {
|
|
|
26921
27071
|
projectFile(name) {
|
|
26922
27072
|
return path6.join(this.projectsDir, safeId(name) + ".json");
|
|
26923
27073
|
}
|
|
27074
|
+
secretFile(id) {
|
|
27075
|
+
return path6.join(this.secretsDir, safeId(id) + ".json");
|
|
27076
|
+
}
|
|
26924
27077
|
readSandboxStatus() {
|
|
26925
27078
|
return readValid(SandboxStatusSchema, this.sandboxFile);
|
|
26926
27079
|
}
|
|
27080
|
+
readVpnStatus() {
|
|
27081
|
+
return readValid(VpnStatusSchema, this.vpnFile);
|
|
27082
|
+
}
|
|
27083
|
+
readPressure() {
|
|
27084
|
+
return readValid(PressureStatusSchema, this.pressureFile);
|
|
27085
|
+
}
|
|
26927
27086
|
readSession(id) {
|
|
26928
27087
|
return readValid(SessionStatusSchema, this.sessionFile(id));
|
|
26929
27088
|
}
|
|
@@ -27047,6 +27206,7 @@ var SYSTEM = {
|
|
|
27047
27206
|
shutdown: () => system32("shutdown.exe"),
|
|
27048
27207
|
dism: () => system32("Dism.exe"),
|
|
27049
27208
|
msiexec: () => system32("msiexec.exe"),
|
|
27209
|
+
sc: () => system32("sc.exe"),
|
|
27050
27210
|
/** The .NET Framework C# compiler that ships with Windows (C# 5). */
|
|
27051
27211
|
csc: () => path9.join(systemRoot(), "Microsoft.NET", "Framework64", "v4.0.30319", "csc.exe")
|
|
27052
27212
|
};
|
|
@@ -27331,9 +27491,9 @@ function writeStatus(phase, message) {
|
|
|
27331
27491
|
}
|
|
27332
27492
|
|
|
27333
27493
|
// src/guest/boot/boot.ts
|
|
27334
|
-
import
|
|
27335
|
-
import
|
|
27336
|
-
import { spawn as
|
|
27494
|
+
import fs59 from "node:fs";
|
|
27495
|
+
import path73 from "node:path";
|
|
27496
|
+
import { spawn as spawn9 } from "node:child_process";
|
|
27337
27497
|
|
|
27338
27498
|
// src/guest/boot/guide.ts
|
|
27339
27499
|
import fs10 from "node:fs";
|
|
@@ -28664,7 +28824,9 @@ var SOURCES = {
|
|
|
28664
28824
|
vswhere: "VsWhere.cs",
|
|
28665
28825
|
openssl: "OpenSsl.cs",
|
|
28666
28826
|
cargoshim: "CargoShim.cs",
|
|
28667
|
-
linkgate: "LinkGate.cs"
|
|
28827
|
+
linkgate: "LinkGate.cs",
|
|
28828
|
+
pathsync: "PathSync.cs",
|
|
28829
|
+
memgov: "MemGov.cs"
|
|
28668
28830
|
};
|
|
28669
28831
|
function sourceOf(name) {
|
|
28670
28832
|
return path30.join(launchDir, "sandbox", "csharp", SOURCES[name]);
|
|
@@ -29014,7 +29176,7 @@ async function setupUv(env) {
|
|
|
29014
29176
|
{ size: "20 MB" }
|
|
29015
29177
|
);
|
|
29016
29178
|
Object.assign(env.vars, uvVars());
|
|
29017
|
-
env.prepend.push(tool("uv-bin"));
|
|
29179
|
+
env.prepend.push(mkdirp(tool("uv-bin")));
|
|
29018
29180
|
}
|
|
29019
29181
|
|
|
29020
29182
|
// src/guest/toolchains/tools/cli.ts
|
|
@@ -30015,7 +30177,7 @@ async function setupPython(env, config2, versions) {
|
|
|
30015
30177
|
const py3 = await installPython("python", versions.python.spec);
|
|
30016
30178
|
const shims = shimDir(py3);
|
|
30017
30179
|
shimPair(shims, "3", py3);
|
|
30018
|
-
env.prepend.push(py3, path46.join(py3, "Scripts"), shims);
|
|
30180
|
+
env.prepend.push(py3, mkdirp(path46.join(py3, "Scripts")), shims);
|
|
30019
30181
|
env.vars.PYTHONIOENCODING = "utf-8";
|
|
30020
30182
|
env.summary.push(
|
|
30021
30183
|
"python: " + path46.basename(py3).replace("python-", "") + " (from " + versions.python.source + "; py works too)"
|
|
@@ -31008,12 +31170,12 @@ function parseTree(text, errors = [], options = ParseOptions.DEFAULT) {
|
|
|
31008
31170
|
}
|
|
31009
31171
|
return result;
|
|
31010
31172
|
}
|
|
31011
|
-
function findNodeAtLocation(root,
|
|
31173
|
+
function findNodeAtLocation(root, path75) {
|
|
31012
31174
|
if (!root) {
|
|
31013
31175
|
return void 0;
|
|
31014
31176
|
}
|
|
31015
31177
|
let node2 = root;
|
|
31016
|
-
for (let segment of
|
|
31178
|
+
for (let segment of path75) {
|
|
31017
31179
|
if (typeof segment === "string") {
|
|
31018
31180
|
if (node2.type !== "object" || !Array.isArray(node2.children)) {
|
|
31019
31181
|
return void 0;
|
|
@@ -31367,14 +31529,14 @@ function getNodeType(value) {
|
|
|
31367
31529
|
|
|
31368
31530
|
// node_modules/jsonc-parser/lib/esm/impl/edit.js
|
|
31369
31531
|
function setProperty(text, originalPath, value, options) {
|
|
31370
|
-
const
|
|
31532
|
+
const path75 = originalPath.slice();
|
|
31371
31533
|
const errors = [];
|
|
31372
31534
|
const root = parseTree(text, errors);
|
|
31373
31535
|
let parent = void 0;
|
|
31374
31536
|
let lastSegment = void 0;
|
|
31375
|
-
while (
|
|
31376
|
-
lastSegment =
|
|
31377
|
-
parent = findNodeAtLocation(root,
|
|
31537
|
+
while (path75.length > 0) {
|
|
31538
|
+
lastSegment = path75.pop();
|
|
31539
|
+
parent = findNodeAtLocation(root, path75);
|
|
31378
31540
|
if (parent === void 0 && value !== void 0) {
|
|
31379
31541
|
if (typeof lastSegment === "string") {
|
|
31380
31542
|
value = { [lastSegment]: value };
|
|
@@ -31560,8 +31722,8 @@ var ParseErrorCode;
|
|
|
31560
31722
|
ParseErrorCode2[ParseErrorCode2["InvalidEscapeCharacter"] = 15] = "InvalidEscapeCharacter";
|
|
31561
31723
|
ParseErrorCode2[ParseErrorCode2["InvalidCharacter"] = 16] = "InvalidCharacter";
|
|
31562
31724
|
})(ParseErrorCode || (ParseErrorCode = {}));
|
|
31563
|
-
function modify(text,
|
|
31564
|
-
return setProperty(text,
|
|
31725
|
+
function modify(text, path75, value, options) {
|
|
31726
|
+
return setProperty(text, path75, value, options);
|
|
31565
31727
|
}
|
|
31566
31728
|
function applyEdits(text, edits) {
|
|
31567
31729
|
let sortedEdits = edits.slice(0).sort((a, b) => {
|
|
@@ -31802,6 +31964,16 @@ async function setupVscode(env, refresh) {
|
|
|
31802
31964
|
import fs41 from "node:fs";
|
|
31803
31965
|
import os8 from "node:os";
|
|
31804
31966
|
import path51 from "node:path";
|
|
31967
|
+
|
|
31968
|
+
// src/shared/memory/policy.ts
|
|
31969
|
+
function cargoJobs(cpus, memoryGb, sessions) {
|
|
31970
|
+
const byCpu = Math.max(2, Math.min(4, Math.floor(cpus / 4)));
|
|
31971
|
+
const byMemory = Math.max(1, Math.floor(memoryGb / 4));
|
|
31972
|
+
const jobs = Math.min(byCpu, byMemory);
|
|
31973
|
+
return Math.max(1, Math.min(jobs, Math.floor(8 / Math.max(1, sessions))));
|
|
31974
|
+
}
|
|
31975
|
+
|
|
31976
|
+
// src/guest/toolchains/native/rust-extras.ts
|
|
31805
31977
|
var cargoTarget = (targetDir) => {
|
|
31806
31978
|
if (targetDir === "shared" || targetDir === "separate") return null;
|
|
31807
31979
|
if (targetDir === "local") return path51.join(localDir, "cargo-target");
|
|
@@ -31836,7 +32008,7 @@ function linkGate(env, rust, host) {
|
|
|
31836
32008
|
function cargoDefaults(host) {
|
|
31837
32009
|
const file3 = tool("rust", "cargo", "config.toml");
|
|
31838
32010
|
if (exists(file3) || !exists(path51.dirname(file3))) return;
|
|
31839
|
-
const jobs =
|
|
32011
|
+
const jobs = cargoJobs(os8.cpus().length, os8.totalmem() / 1024 ** 3, 1);
|
|
31840
32012
|
const gnu = host.endsWith("-gnu");
|
|
31841
32013
|
fs41.writeFileSync(
|
|
31842
32014
|
file3,
|
|
@@ -32110,14 +32282,179 @@ async function setupToolchains(config2, versions, options, run3 = {}) {
|
|
|
32110
32282
|
}
|
|
32111
32283
|
|
|
32112
32284
|
// src/guest/agents/agent-installer.ts
|
|
32285
|
+
import fs43 from "node:fs";
|
|
32286
|
+
import path56 from "node:path";
|
|
32287
|
+
|
|
32288
|
+
// src/guest/setup/environment.ts
|
|
32289
|
+
import path55 from "node:path";
|
|
32290
|
+
|
|
32291
|
+
// src/guest/agents/local-state.ts
|
|
32113
32292
|
import fs42 from "node:fs";
|
|
32114
32293
|
import path53 from "node:path";
|
|
32115
32294
|
|
|
32116
|
-
// src/guest/
|
|
32295
|
+
// src/guest/agents/agent-files.ts
|
|
32117
32296
|
import path52 from "node:path";
|
|
32297
|
+
function agentPaths(toolsDir2, name, harness) {
|
|
32298
|
+
const dir = path52.join(toolsDir2, "agents", name);
|
|
32299
|
+
const exe = harness.hostExecutable ?? (harness.uvBin ? harness.uvBin + ".exe" : null);
|
|
32300
|
+
return {
|
|
32301
|
+
dir,
|
|
32302
|
+
exe: exe ? path52.join(dir, exe) : null,
|
|
32303
|
+
cmd: harness.npmBin ? path52.join(dir, harness.npmBin + ".cmd") : null
|
|
32304
|
+
};
|
|
32305
|
+
}
|
|
32306
|
+
function agentCommand(name, harness) {
|
|
32307
|
+
return harness.npmBin ?? harness.uvBin ?? (harness.hostExecutable ?? name).replace(/\.exe$/i, "");
|
|
32308
|
+
}
|
|
32309
|
+
function agentShims(toolsDir2, agents2) {
|
|
32310
|
+
return Object.entries(agents2).flatMap(([name, harness]) => {
|
|
32311
|
+
const p = agentPaths(toolsDir2, name, harness);
|
|
32312
|
+
const target = p.exe ?? p.cmd;
|
|
32313
|
+
const command = agentCommand(name, harness);
|
|
32314
|
+
return target && /^[A-Za-z0-9_-]+$/.test(command) && /^[A-Za-z0-9_-]+$/.test(name) ? [{ name, command, target }] : [];
|
|
32315
|
+
});
|
|
32316
|
+
}
|
|
32317
|
+
function shimText(shim3, install) {
|
|
32318
|
+
return [
|
|
32319
|
+
"@echo off",
|
|
32320
|
+
"setlocal",
|
|
32321
|
+
'set "SBX_REAL=' + shim3.target + '"',
|
|
32322
|
+
'if exist "%SBX_REAL%" goto run',
|
|
32323
|
+
"echo " + shim3.command + " is not installed in this sandbox yet. Installing it now (one time)...",
|
|
32324
|
+
'"' + install.node + '" "' + install.script + '" install ' + shim3.name,
|
|
32325
|
+
"if errorlevel 1 exit /b 1",
|
|
32326
|
+
":run",
|
|
32327
|
+
'endlocal & "%SBX_REAL%" %*',
|
|
32328
|
+
""
|
|
32329
|
+
].join("\r\n");
|
|
32330
|
+
}
|
|
32331
|
+
function sbxAgentText(install) {
|
|
32332
|
+
return '@"' + install.node + '" "' + install.script + '" %*\r\n';
|
|
32333
|
+
}
|
|
32334
|
+
function localStateEntries(agents2, stateDir2, localRoot2) {
|
|
32335
|
+
return Object.entries(agents2).flatMap(
|
|
32336
|
+
([agent, harness]) => Object.entries(harness.localState ?? {}).map(([env, folder]) => ({
|
|
32337
|
+
agent,
|
|
32338
|
+
env,
|
|
32339
|
+
store: path52.join(stateDir2, agent, folder),
|
|
32340
|
+
local: path52.join(localRoot2, agent, folder),
|
|
32341
|
+
processes: [agentCommand(agent, harness) + ".exe"],
|
|
32342
|
+
legacy: path52.join(stateDir2, agent)
|
|
32343
|
+
}))
|
|
32344
|
+
);
|
|
32345
|
+
}
|
|
32346
|
+
function bootResetPaths(agents2, stateDir2) {
|
|
32347
|
+
return Object.entries(agents2).flatMap(
|
|
32348
|
+
([agent, harness]) => (harness.bootReset ?? []).map((rel) => ({ agent, path: path52.join(stateDir2, agent, rel) }))
|
|
32349
|
+
);
|
|
32350
|
+
}
|
|
32351
|
+
var isDatabaseFile = (name) => /\.(sqlite3?|db)(-wal|-shm)?$/i.test(name);
|
|
32352
|
+
var isCopyableDatabaseFile = (name) => isDatabaseFile(name) && !/-shm$/i.test(name);
|
|
32353
|
+
|
|
32354
|
+
// src/guest/agents/local-state.ts
|
|
32355
|
+
var localRoot = () => path53.join(localDir, "agent-state");
|
|
32356
|
+
function agentLocalStates() {
|
|
32357
|
+
return localStateEntries(session.agents ?? {}, stateDir, localRoot());
|
|
32358
|
+
}
|
|
32359
|
+
function localStateVars() {
|
|
32360
|
+
return Object.fromEntries(agentLocalStates().map((s) => [s.env, s.local]));
|
|
32361
|
+
}
|
|
32362
|
+
var databaseFiles = (dir, keep) => exists(dir) ? fs42.readdirSync(dir, { withFileTypes: true }).flatMap((e) => e.isFile() && keep(e.name) ? [e.name] : []) : [];
|
|
32363
|
+
var copyFiles = (from, to, names) => {
|
|
32364
|
+
fs42.rmSync(to, { recursive: true, force: true });
|
|
32365
|
+
mkdirp(to);
|
|
32366
|
+
for (const name of names) fs42.copyFileSync(path53.join(from, name), path53.join(to, name));
|
|
32367
|
+
};
|
|
32368
|
+
var swapIn = (incoming, store2) => {
|
|
32369
|
+
const previous = store2 + ".previous";
|
|
32370
|
+
fs42.rmSync(previous, { recursive: true, force: true });
|
|
32371
|
+
if (exists(store2)) fs42.renameSync(store2, previous);
|
|
32372
|
+
try {
|
|
32373
|
+
fs42.renameSync(incoming, store2);
|
|
32374
|
+
} catch (e) {
|
|
32375
|
+
if (exists(previous)) fs42.renameSync(previous, store2);
|
|
32376
|
+
throw e;
|
|
32377
|
+
}
|
|
32378
|
+
fs42.rmSync(previous, { recursive: true, force: true });
|
|
32379
|
+
};
|
|
32380
|
+
function adoptLegacy(s) {
|
|
32381
|
+
if (exists(s.store)) return;
|
|
32382
|
+
const names = databaseFiles(s.legacy, isDatabaseFile);
|
|
32383
|
+
if (!names.length) return;
|
|
32384
|
+
const copyable = names.filter(isCopyableDatabaseFile);
|
|
32385
|
+
const incoming = s.store + ".incoming";
|
|
32386
|
+
copyFiles(s.legacy, incoming, copyable);
|
|
32387
|
+
swapIn(incoming, s.store);
|
|
32388
|
+
const same = copyable.every(
|
|
32389
|
+
(n) => fs42.statSync(path53.join(s.store, n)).size === fs42.statSync(path53.join(s.legacy, n)).size
|
|
32390
|
+
);
|
|
32391
|
+
if (!same) {
|
|
32392
|
+
warn(s.agent + ": the copied databases differ in size from the originals; the originals were kept.");
|
|
32393
|
+
return;
|
|
32394
|
+
}
|
|
32395
|
+
for (const n of names) fs42.rmSync(path53.join(s.legacy, n), { force: true });
|
|
32396
|
+
log(s.agent + ": moved " + copyable.length + " database file(s) to " + s.store + ".");
|
|
32397
|
+
}
|
|
32398
|
+
function resetMachineBound() {
|
|
32399
|
+
if (dryRun) return;
|
|
32400
|
+
for (const { agent, path: target } of bootResetPaths(session.agents ?? {}, stateDir)) {
|
|
32401
|
+
try {
|
|
32402
|
+
const stat = fs42.lstatSync(target, { throwIfNoEntry: false });
|
|
32403
|
+
if (!stat || stat.isSymbolicLink()) continue;
|
|
32404
|
+
fs42.rmSync(target, { recursive: true, force: true });
|
|
32405
|
+
log(
|
|
32406
|
+
agent + ": removed " + path53.relative(path53.join(stateDir, agent), target) + " (it only worked in the last sandbox)."
|
|
32407
|
+
);
|
|
32408
|
+
} catch (e) {
|
|
32409
|
+
warn(agent + ": could not remove " + target + " (" + errMsg(e) + ").");
|
|
32410
|
+
}
|
|
32411
|
+
}
|
|
32412
|
+
}
|
|
32413
|
+
function restoreLocalState() {
|
|
32414
|
+
if (dryRun) return;
|
|
32415
|
+
for (const s of agentLocalStates()) {
|
|
32416
|
+
try {
|
|
32417
|
+
adoptLegacy(s);
|
|
32418
|
+
mkdirp(s.local);
|
|
32419
|
+
const names = databaseFiles(s.store, isCopyableDatabaseFile);
|
|
32420
|
+
for (const n of names) fs42.copyFileSync(path53.join(s.store, n), path53.join(s.local, n));
|
|
32421
|
+
if (names.length) log(s.agent + ": databases restored to " + s.local + ".");
|
|
32422
|
+
} catch (e) {
|
|
32423
|
+
warn(s.agent + ": could not restore its databases (" + errMsg(e) + "); it starts with empty ones.");
|
|
32424
|
+
}
|
|
32425
|
+
}
|
|
32426
|
+
}
|
|
32427
|
+
|
|
32428
|
+
// src/guest/setup/path-plan.ts
|
|
32429
|
+
import path54 from "node:path";
|
|
32430
|
+
function pathKey(folder) {
|
|
32431
|
+
const slashes = folder.trim().replace(/^"|"$/g, "").replace(/\//g, "\\");
|
|
32432
|
+
return (slashes.length > 3 ? slashes.replace(/\\+$/, "") : slashes).toLowerCase();
|
|
32433
|
+
}
|
|
32434
|
+
function splitPath(value) {
|
|
32435
|
+
return value.split(";").map((part) => part.trim().replace(/^"|"$/g, "")).filter(Boolean);
|
|
32436
|
+
}
|
|
32437
|
+
function planPath(input2) {
|
|
32438
|
+
const seen = /* @__PURE__ */ new Set();
|
|
32439
|
+
const result = [];
|
|
32440
|
+
for (const entry of input2.entries.flatMap(splitPath)) {
|
|
32441
|
+
const key = pathKey(entry);
|
|
32442
|
+
if (seen.has(key) || input2.drop?.(entry) || !input2.exists(entry)) continue;
|
|
32443
|
+
seen.add(key);
|
|
32444
|
+
result.push(entry);
|
|
32445
|
+
}
|
|
32446
|
+
return result;
|
|
32447
|
+
}
|
|
32448
|
+
function isPinnedNodeDir(folder, nvmHome2) {
|
|
32449
|
+
const key = pathKey(folder);
|
|
32450
|
+
const home = pathKey(nvmHome2);
|
|
32451
|
+
return key.startsWith(home + "\\") && /^v\d/.test(path54.win32.basename(key));
|
|
32452
|
+
}
|
|
32453
|
+
|
|
32454
|
+
// src/guest/setup/environment.ts
|
|
32118
32455
|
var LEGACY_HOMES = { CODEX_HOME: "codex", GEMINI_CLI_HOME: "gemini" };
|
|
32119
32456
|
var agentHomes = () => Object.fromEntries(
|
|
32120
|
-
Object.entries(session.agentHomes ?? LEGACY_HOMES).filter(([name]) => name !== "CLAUDE_CONFIG_DIR").map(([name, sub]) => [name,
|
|
32457
|
+
Object.entries(session.agentHomes ?? LEGACY_HOMES).filter(([name]) => name !== "CLAUDE_CONFIG_DIR").map(([name, sub]) => [name, path55.join(stateDir, sub)])
|
|
32121
32458
|
);
|
|
32122
32459
|
var AGENT_VARS = [
|
|
32123
32460
|
"CLAUDE_CONFIG_DIR",
|
|
@@ -32137,7 +32474,8 @@ function agentEnv(tools, target = { workspace, project: session.project, base: p
|
|
|
32137
32474
|
...tools.vars,
|
|
32138
32475
|
CLAUDE_CONFIG_DIR: claudeDir,
|
|
32139
32476
|
...homes,
|
|
32140
|
-
|
|
32477
|
+
...localStateVars(),
|
|
32478
|
+
npm_config_cache: path55.join(toolsDir, "npm-cache"),
|
|
32141
32479
|
npm_config_update_notifier: "false",
|
|
32142
32480
|
AGENT_WORKSPACE: target.workspace,
|
|
32143
32481
|
AGENT_DATA: dataDir,
|
|
@@ -32147,22 +32485,32 @@ function agentEnv(tools, target = { workspace, project: session.project, base: p
|
|
|
32147
32485
|
AGENT_SANDBOX: "1",
|
|
32148
32486
|
AGENT_SANDBOX_WORKSPACE: target.workspace
|
|
32149
32487
|
};
|
|
32150
|
-
|
|
32488
|
+
const local = Object.keys(localStateVars());
|
|
32489
|
+
for (const dir of [
|
|
32490
|
+
env.CLAUDE_CONFIG_DIR,
|
|
32491
|
+
...Object.keys(homes).map((n) => env[n]),
|
|
32492
|
+
env.npm_config_cache,
|
|
32493
|
+
...local.map((n) => env[n])
|
|
32494
|
+
])
|
|
32151
32495
|
mkdirp(dir);
|
|
32152
|
-
const runners = [
|
|
32153
|
-
const base = (target.base.PATH ?? "").split(
|
|
32154
|
-
env.PATH = [.../* @__PURE__ */ new Set([...tools.prepend, ...base, ...tools.append])].join(
|
|
32496
|
+
const runners = [path55.join(toolsDir, "node"), path55.dirname(process.execPath)].map((d) => d.toLowerCase());
|
|
32497
|
+
const base = (target.base.PATH ?? "").split(path55.delimiter).filter((d) => d && !runners.includes(d.toLowerCase()));
|
|
32498
|
+
env.PATH = [.../* @__PURE__ */ new Set([...tools.prepend, ...base, ...tools.append])].join(path55.delimiter);
|
|
32155
32499
|
return env;
|
|
32156
32500
|
}
|
|
32157
32501
|
function persistEnvironment(env, toolVars2) {
|
|
32158
32502
|
if (!isWin || dryRun || testMode) return;
|
|
32159
32503
|
const vars = Object.fromEntries(
|
|
32160
|
-
[...toolVars2, ...AGENT_VARS, ...Object.keys(agentHomes())].filter((n) => env[n] !== void 0).map((n) => [n, env[n]])
|
|
32504
|
+
[...toolVars2, ...AGENT_VARS, ...Object.keys(agentHomes()), ...Object.keys(localStateVars())].filter((n) => env[n] !== void 0).map((n) => [n, env[n]])
|
|
32161
32505
|
);
|
|
32162
32506
|
try {
|
|
32163
32507
|
runScriptWithJson("set-machine-environment.ps1", "SettingsFile", {
|
|
32164
32508
|
vars,
|
|
32165
|
-
path:
|
|
32509
|
+
path: planPath({
|
|
32510
|
+
entries: [env.PATH ?? "", ...installedAgentDirs()],
|
|
32511
|
+
exists,
|
|
32512
|
+
drop: (dir) => isPinnedNodeDir(dir, nvmHome())
|
|
32513
|
+
}).join(path55.delimiter),
|
|
32166
32514
|
add: [],
|
|
32167
32515
|
additive: false
|
|
32168
32516
|
});
|
|
@@ -32172,12 +32520,20 @@ function persistEnvironment(env, toolVars2) {
|
|
|
32172
32520
|
}
|
|
32173
32521
|
function addMachineEnvironment(vars, dirs, additive = false) {
|
|
32174
32522
|
if (!isWin || dryRun || testMode) return;
|
|
32523
|
+
const planned = planPath({ entries: dirs, exists, drop: (dir) => isPinnedNodeDir(dir, nvmHome()) });
|
|
32175
32524
|
try {
|
|
32176
|
-
runScriptWithJson("set-machine-environment.ps1", "SettingsFile", { vars, path: null, add:
|
|
32525
|
+
runScriptWithJson("set-machine-environment.ps1", "SettingsFile", { vars, path: null, add: planned, additive });
|
|
32177
32526
|
} catch (e) {
|
|
32178
32527
|
warn("Could not add to the environment: " + errMsg(e));
|
|
32179
32528
|
}
|
|
32180
32529
|
}
|
|
32530
|
+
var nvmHome = () => path55.join(toolsDir, "nvm");
|
|
32531
|
+
function installedAgentDirs() {
|
|
32532
|
+
return Object.entries(session.agents ?? {}).flatMap(([name, harness]) => {
|
|
32533
|
+
const p = agentPaths(toolsDir, name, harness);
|
|
32534
|
+
return p.exe && exists(p.exe) || p.cmd && exists(p.cmd) ? [p.dir] : [];
|
|
32535
|
+
});
|
|
32536
|
+
}
|
|
32181
32537
|
|
|
32182
32538
|
// src/guest/agents/profile-links.ts
|
|
32183
32539
|
var profileRoot = () => process.env.USERPROFILE ?? "";
|
|
@@ -32199,19 +32555,11 @@ function linkHarnessProfile(name, harness) {
|
|
|
32199
32555
|
}
|
|
32200
32556
|
|
|
32201
32557
|
// src/guest/agents/agent-installer.ts
|
|
32202
|
-
|
|
32203
|
-
const dir = path53.join(toolsDir, "agents", name);
|
|
32204
|
-
const exe = harness.hostExecutable ?? (harness.uvBin ? harness.uvBin + ".exe" : null);
|
|
32205
|
-
return {
|
|
32206
|
-
dir,
|
|
32207
|
-
exe: exe ? path53.join(dir, exe) : null,
|
|
32208
|
-
cmd: harness.npmBin ? path53.join(dir, harness.npmBin + ".cmd") : null
|
|
32209
|
-
};
|
|
32210
|
-
}
|
|
32558
|
+
var agentPaths2 = (name, harness) => agentPaths(toolsDir, name, harness);
|
|
32211
32559
|
async function installViaNpm(name, harness, dir, env) {
|
|
32212
32560
|
if (!harness.npmPackage)
|
|
32213
32561
|
throw new Error("No npmPackage configured for " + name + " and no host executable was available.");
|
|
32214
|
-
const npmCli =
|
|
32562
|
+
const npmCli = path56.join(path56.dirname(process.execPath), "node_modules", "npm", "bin", "npm-cli.js");
|
|
32215
32563
|
const args = [npmCli, "install", "--global", "--prefix", dir, harness.npmPackage, "--no-fund", "--no-audit"];
|
|
32216
32564
|
log("Installing " + harness.npmPackage + " (this can take a minute)...");
|
|
32217
32565
|
if (dryRun) {
|
|
@@ -32222,7 +32570,7 @@ async function installViaNpm(name, harness, dir, env) {
|
|
|
32222
32570
|
await execAsync(process.execPath, args, { env });
|
|
32223
32571
|
}
|
|
32224
32572
|
async function installViaUv(name, harness, dir, env) {
|
|
32225
|
-
const uv =
|
|
32573
|
+
const uv = path56.join(toolsDir, "uv", "uv.exe");
|
|
32226
32574
|
log("Installing " + harness.uvPackage + " with uv (this can take a minute)...");
|
|
32227
32575
|
if (dryRun) {
|
|
32228
32576
|
log("(dry run) uv tool install " + harness.uvPackage);
|
|
@@ -32237,8 +32585,8 @@ async function installViaUv(name, harness, dir, env) {
|
|
|
32237
32585
|
});
|
|
32238
32586
|
}
|
|
32239
32587
|
function putOnPath(dir, env) {
|
|
32240
|
-
const parts2 = (env.PATH ?? "").split(
|
|
32241
|
-
if (!parts2.some((p) => p.toLowerCase() === dir.toLowerCase())) env.PATH = [...parts2, dir].join(
|
|
32588
|
+
const parts2 = (env.PATH ?? "").split(path56.delimiter);
|
|
32589
|
+
if (!parts2.some((p) => p.toLowerCase() === dir.toLowerCase())) env.PATH = [...parts2, dir].join(path56.delimiter);
|
|
32242
32590
|
addMachineEnvironment({}, [dir], true);
|
|
32243
32591
|
}
|
|
32244
32592
|
var AgentInstaller = class {
|
|
@@ -32252,13 +32600,13 @@ var AgentInstaller = class {
|
|
|
32252
32600
|
const current = this.installing.get(name);
|
|
32253
32601
|
if (current) return current;
|
|
32254
32602
|
linkHarnessProfile(name, harness);
|
|
32255
|
-
const work = this.install(name, harness, env, refresh).then(() => putOnPath(
|
|
32603
|
+
const work = this.install(name, harness, env, refresh).then(() => putOnPath(agentPaths2(name, harness).dir, env)).finally(() => this.installing.delete(name));
|
|
32256
32604
|
this.installing.set(name, work);
|
|
32257
32605
|
return work;
|
|
32258
32606
|
}
|
|
32259
32607
|
/** Program + arguments that start the agent (an npm .cmd shim has to go through cmd.exe). */
|
|
32260
32608
|
resolveLaunch(name, harness) {
|
|
32261
|
-
const p =
|
|
32609
|
+
const p = agentPaths2(name, harness);
|
|
32262
32610
|
if (p.exe && exists(p.exe)) return { file: p.exe, args: [] };
|
|
32263
32611
|
if (p.cmd && exists(p.cmd))
|
|
32264
32612
|
return isWin ? { file: SYSTEM.cmd(), args: ["/d", "/c", p.cmd] } : { file: p.cmd, args: [] };
|
|
@@ -32271,7 +32619,7 @@ var AgentInstaller = class {
|
|
|
32271
32619
|
return harness.uvPackage && !harness.npmPackage ? "uv" : "npm";
|
|
32272
32620
|
}
|
|
32273
32621
|
async install(name, harness, env, refresh) {
|
|
32274
|
-
const p =
|
|
32622
|
+
const p = agentPaths2(name, harness);
|
|
32275
32623
|
const cached2 = p.exe !== null && exists(p.exe) || p.cmd !== null && exists(p.cmd);
|
|
32276
32624
|
if (cached2 && !refresh) {
|
|
32277
32625
|
log(name + " already cached in persistent storage.");
|
|
@@ -32279,9 +32627,9 @@ var AgentInstaller = class {
|
|
|
32279
32627
|
}
|
|
32280
32628
|
mkdirp(p.dir);
|
|
32281
32629
|
if (this.sourceOf(name, harness) === "host") {
|
|
32282
|
-
const source =
|
|
32630
|
+
const source = path56.join(hostToolsDir, "agents", name, harness.hostExecutable);
|
|
32283
32631
|
if (exists(source) && p.exe) {
|
|
32284
|
-
|
|
32632
|
+
fs43.copyFileSync(source, p.exe);
|
|
32285
32633
|
log("Copied " + name + " from this PC: " + source);
|
|
32286
32634
|
return;
|
|
32287
32635
|
}
|
|
@@ -32295,28 +32643,45 @@ var AgentInstaller = class {
|
|
|
32295
32643
|
};
|
|
32296
32644
|
var agents = new AgentInstaller();
|
|
32297
32645
|
|
|
32646
|
+
// src/guest/setup/shell-path.ts
|
|
32647
|
+
import fs44 from "node:fs";
|
|
32648
|
+
import path57 from "node:path";
|
|
32649
|
+
function installShellPath() {
|
|
32650
|
+
if (!isWin || dryRun || testMode) return;
|
|
32651
|
+
const helper = path57.join(mkdirp(path57.join(localDir, "bin")), "pathsync.exe");
|
|
32652
|
+
fs44.copyFileSync(ensureCompiled("pathsync"), helper);
|
|
32653
|
+
runScript("install-shell-path.ps1", [
|
|
32654
|
+
"-Helper",
|
|
32655
|
+
helper,
|
|
32656
|
+
"-PwshDir",
|
|
32657
|
+
path57.join(toolsDir, "pwsh"),
|
|
32658
|
+
"-GitRoot",
|
|
32659
|
+
path57.join(toolsDir, "git")
|
|
32660
|
+
]);
|
|
32661
|
+
}
|
|
32662
|
+
|
|
32298
32663
|
// src/guest/setup/claude-mem.ts
|
|
32299
|
-
import
|
|
32664
|
+
import fs45 from "node:fs";
|
|
32300
32665
|
import os9 from "node:os";
|
|
32301
|
-
import
|
|
32666
|
+
import path58 from "node:path";
|
|
32302
32667
|
var claudeMemPaths = {
|
|
32303
|
-
store:
|
|
32304
|
-
local:
|
|
32668
|
+
store: path58.join(stateDir, "claude-mem"),
|
|
32669
|
+
local: path58.join(os9.homedir(), ".claude-mem")
|
|
32305
32670
|
};
|
|
32306
32671
|
var claudeMemEnabled = () => session.claudeProfile.syncClaudeMem && !dryRun;
|
|
32307
32672
|
function restoreClaudeMem() {
|
|
32308
32673
|
if (!claudeMemEnabled()) return;
|
|
32309
32674
|
const previous = claudeMemPaths.store + ".previous";
|
|
32310
|
-
if (!exists(claudeMemPaths.store) && exists(previous))
|
|
32675
|
+
if (!exists(claudeMemPaths.store) && exists(previous)) fs45.renameSync(previous, claudeMemPaths.store);
|
|
32311
32676
|
const backups = claudeMemPaths.store + ".backups";
|
|
32312
|
-
if (!looksLikeSqlite(
|
|
32313
|
-
const good = (exists(backups) ?
|
|
32314
|
-
(b) => exists(
|
|
32677
|
+
if (!looksLikeSqlite(path58.join(claudeMemPaths.store, "claude-mem.db")) || !exists(claudeMemPaths.store)) {
|
|
32678
|
+
const good = (exists(backups) ? fs45.readdirSync(backups).sort().reverse() : []).find(
|
|
32679
|
+
(b) => exists(path58.join(backups, b, "claude-mem.db")) && looksLikeSqlite(path58.join(backups, b, "claude-mem.db"))
|
|
32315
32680
|
);
|
|
32316
32681
|
if (good) {
|
|
32317
32682
|
if (exists(claudeMemPaths.store))
|
|
32318
|
-
|
|
32319
|
-
|
|
32683
|
+
fs45.renameSync(claudeMemPaths.store, claudeMemPaths.store + ".damaged-" + Date.now());
|
|
32684
|
+
fs45.cpSync(path58.join(backups, good), claudeMemPaths.store, { recursive: true });
|
|
32320
32685
|
warn(
|
|
32321
32686
|
"claude-mem: the stored database was missing or damaged; restored the backup from " + new Date(Number(good)).toISOString() + "."
|
|
32322
32687
|
);
|
|
@@ -32329,33 +32694,33 @@ function restoreClaudeMem() {
|
|
|
32329
32694
|
var SQLITE_HEADER = "SQLite format 3\0";
|
|
32330
32695
|
var looksLikeSqlite = (file3) => {
|
|
32331
32696
|
if (!exists(file3)) return true;
|
|
32332
|
-
const fd =
|
|
32697
|
+
const fd = fs45.openSync(file3, "r");
|
|
32333
32698
|
try {
|
|
32334
32699
|
const head = Buffer.alloc(16);
|
|
32335
|
-
return
|
|
32700
|
+
return fs45.readSync(fd, head, 0, 16, 0) === 16 && head.toString("latin1") === SQLITE_HEADER;
|
|
32336
32701
|
} finally {
|
|
32337
|
-
|
|
32702
|
+
fs45.closeSync(fd);
|
|
32338
32703
|
}
|
|
32339
32704
|
};
|
|
32340
32705
|
var BACKUP_EVERY_MS = 6 * 3600 * 1e3;
|
|
32341
32706
|
|
|
32342
32707
|
// src/guest/setup/claude-profile.ts
|
|
32343
|
-
import
|
|
32344
|
-
import
|
|
32708
|
+
import fs46 from "node:fs";
|
|
32709
|
+
import path59 from "node:path";
|
|
32345
32710
|
var KEEP_SANDBOX_COPY = [".claude.json", ".credentials.json"];
|
|
32346
32711
|
var fixPluginPaths = (hostConfigDir) => {
|
|
32347
|
-
const plugins =
|
|
32712
|
+
const plugins = path59.join(claudeDir, "plugins");
|
|
32348
32713
|
if (!hostConfigDir || !exists(plugins)) return;
|
|
32349
|
-
for (const name of
|
|
32350
|
-
const file3 =
|
|
32351
|
-
const text =
|
|
32714
|
+
for (const name of fs46.readdirSync(plugins).filter((f) => f.endsWith(".json"))) {
|
|
32715
|
+
const file3 = path59.join(plugins, name);
|
|
32716
|
+
const text = fs46.readFileSync(file3, "utf8");
|
|
32352
32717
|
const fixed = translatePaths(text, hostConfigDir, claudeDir);
|
|
32353
|
-
if (fixed !== text)
|
|
32718
|
+
if (fixed !== text) fs46.writeFileSync(file3, fixed, "utf8");
|
|
32354
32719
|
}
|
|
32355
32720
|
};
|
|
32356
32721
|
var readState2 = (file3) => {
|
|
32357
32722
|
try {
|
|
32358
|
-
return JSON.parse(
|
|
32723
|
+
return JSON.parse(fs46.readFileSync(file3, "utf8").replace(/^\uFEFF/, ""));
|
|
32359
32724
|
} catch {
|
|
32360
32725
|
return null;
|
|
32361
32726
|
}
|
|
@@ -32380,30 +32745,37 @@ function mergeMcpServers(hostFile, guestFile, hostWorkspace, guestWorkspace) {
|
|
|
32380
32745
|
writeJsonAtomic(guestFile, merged);
|
|
32381
32746
|
return Object.keys(host.mcpServers ?? {}).length + Object.keys(hostProject).length;
|
|
32382
32747
|
}
|
|
32383
|
-
function syncClaudeProfile() {
|
|
32748
|
+
function syncClaudeProfile(credentials) {
|
|
32384
32749
|
const profile = session.claudeProfile;
|
|
32385
32750
|
if (profile.items.length === 0) {
|
|
32386
32751
|
log("No Claude settings were staged from this PC.");
|
|
32387
32752
|
return;
|
|
32388
32753
|
}
|
|
32389
|
-
const source =
|
|
32754
|
+
const source = path59.join(launchDir, "claude-profile");
|
|
32390
32755
|
mkdirp(claudeDir);
|
|
32391
32756
|
for (const name of profile.items) {
|
|
32392
|
-
const from =
|
|
32393
|
-
const to =
|
|
32757
|
+
const from = path59.join(source, name);
|
|
32758
|
+
const to = path59.join(claudeDir, name);
|
|
32759
|
+
if (name === ".credentials.json") {
|
|
32760
|
+
if (credentials && !exists(to)) {
|
|
32761
|
+
fs46.writeFileSync(to, credentials, "utf8");
|
|
32762
|
+
log("Claude settings: copied " + name + " from this PC");
|
|
32763
|
+
} else log("Claude settings: kept the sandbox's " + name);
|
|
32764
|
+
continue;
|
|
32765
|
+
}
|
|
32394
32766
|
if (!exists(from)) continue;
|
|
32395
32767
|
if ((KEEP_SANDBOX_COPY.includes(name) || !profile.overwrite) && exists(to)) {
|
|
32396
32768
|
log("Claude settings: kept the sandbox's " + name);
|
|
32397
32769
|
continue;
|
|
32398
32770
|
}
|
|
32399
|
-
if (
|
|
32400
|
-
|
|
32771
|
+
if (fs46.statSync(from).isDirectory()) safeRemove(to, claudeDir);
|
|
32772
|
+
fs46.cpSync(from, to, { recursive: true, force: true });
|
|
32401
32773
|
log("Claude settings: copied " + name + " from this PC");
|
|
32402
32774
|
}
|
|
32403
32775
|
fixPluginPaths(profile.hostConfigDir);
|
|
32404
32776
|
const mcp = mergeMcpServers(
|
|
32405
|
-
|
|
32406
|
-
|
|
32777
|
+
path59.join(source, ".claude.json"),
|
|
32778
|
+
path59.join(claudeDir, ".claude.json"),
|
|
32407
32779
|
session.workspaceHost,
|
|
32408
32780
|
workspace
|
|
32409
32781
|
);
|
|
@@ -32412,11 +32784,11 @@ function syncClaudeProfile() {
|
|
|
32412
32784
|
}
|
|
32413
32785
|
|
|
32414
32786
|
// src/guest/setup/hooks.ts
|
|
32415
|
-
import
|
|
32416
|
-
import
|
|
32787
|
+
import fs47 from "node:fs";
|
|
32788
|
+
import path60 from "node:path";
|
|
32417
32789
|
import { spawnSync as spawnSync4 } from "node:child_process";
|
|
32418
32790
|
var commandFor = (file3) => {
|
|
32419
|
-
const ext =
|
|
32791
|
+
const ext = path60.extname(file3).toLowerCase();
|
|
32420
32792
|
if (ext === ".mjs" || ext === ".js") return [process.execPath, [file3]];
|
|
32421
32793
|
if (!isWin) return null;
|
|
32422
32794
|
if (ext === ".ps1")
|
|
@@ -32424,12 +32796,12 @@ var commandFor = (file3) => {
|
|
|
32424
32796
|
if (ext === ".cmd" || ext === ".bat") return [SYSTEM.cmd(), ["/d", "/c", file3]];
|
|
32425
32797
|
return null;
|
|
32426
32798
|
};
|
|
32427
|
-
var BOOT = { root:
|
|
32799
|
+
var BOOT = { root: path60.join(launchDir, "hooks"), cwd: workspace };
|
|
32428
32800
|
var hooksOf = (stage, target) => {
|
|
32429
|
-
const dir =
|
|
32801
|
+
const dir = path60.join(target.root, stage);
|
|
32430
32802
|
if (!exists(dir)) return [];
|
|
32431
|
-
return
|
|
32432
|
-
const command = commandFor(
|
|
32803
|
+
return fs47.readdirSync(dir).sort().flatMap((name) => {
|
|
32804
|
+
const command = commandFor(path60.join(dir, name));
|
|
32433
32805
|
return command ? [{ name, command }] : [];
|
|
32434
32806
|
});
|
|
32435
32807
|
};
|
|
@@ -32447,8 +32819,8 @@ function runHooks(stage, env, target = BOOT) {
|
|
|
32447
32819
|
}
|
|
32448
32820
|
|
|
32449
32821
|
// src/guest/network/allow-only.ts
|
|
32450
|
-
import
|
|
32451
|
-
import
|
|
32822
|
+
import fs49 from "node:fs";
|
|
32823
|
+
import path62 from "node:path";
|
|
32452
32824
|
import { spawn as spawn6, spawnSync as spawnSync6 } from "node:child_process";
|
|
32453
32825
|
|
|
32454
32826
|
// src/shared/network/policy.ts
|
|
@@ -32543,8 +32915,8 @@ var PROXY_PORT = 38080;
|
|
|
32543
32915
|
|
|
32544
32916
|
// src/guest/network/firewall.ts
|
|
32545
32917
|
import dns from "node:dns";
|
|
32546
|
-
import
|
|
32547
|
-
import
|
|
32918
|
+
import fs48 from "node:fs";
|
|
32919
|
+
import path61 from "node:path";
|
|
32548
32920
|
import { spawnSync as spawnSync5 } from "node:child_process";
|
|
32549
32921
|
|
|
32550
32922
|
// src/shared/network/firewall-rules.ts
|
|
@@ -32783,12 +33155,12 @@ async function applyNetworkPolicy(ptyHostExe) {
|
|
|
32783
33155
|
return "blocked";
|
|
32784
33156
|
}
|
|
32785
33157
|
var FORWARD_RULE = "AgentSandbox-Forward";
|
|
32786
|
-
var HOSTS_FILE =
|
|
33158
|
+
var HOSTS_FILE = path61.join(process.env.WINDIR ?? "C:\\Windows", "System32", "drivers", "etc", "hosts");
|
|
32787
33159
|
var applyBlockedHosts = () => {
|
|
32788
33160
|
const hosts = session.network.blockHosts ?? [];
|
|
32789
33161
|
if (!hosts.length) return;
|
|
32790
|
-
const text =
|
|
32791
|
-
|
|
33162
|
+
const text = fs48.existsSync(HOSTS_FILE) ? fs48.readFileSync(HOSTS_FILE, "utf8") : "";
|
|
33163
|
+
fs48.writeFileSync(HOSTS_FILE, withBlockedHosts(text, hosts));
|
|
32792
33164
|
log("Blocked hosts (network.blockHosts): " + hosts.join(", "));
|
|
32793
33165
|
};
|
|
32794
33166
|
var applyDns = () => {
|
|
@@ -32843,11 +33215,11 @@ async function applyAllowOnly() {
|
|
|
32843
33215
|
log("(dry run) would allow only: " + hosts.join(", "));
|
|
32844
33216
|
return false;
|
|
32845
33217
|
}
|
|
32846
|
-
const exe =
|
|
32847
|
-
|
|
32848
|
-
if (!
|
|
32849
|
-
|
|
32850
|
-
spawn6(exe, [
|
|
33218
|
+
const exe = path62.join(toolsDir, "netproxy", "sbx-netproxy.exe");
|
|
33219
|
+
fs49.mkdirSync(path62.dirname(exe), { recursive: true });
|
|
33220
|
+
if (!fs49.existsSync(exe) || fs49.statSync(exe).size !== fs49.statSync(process.execPath).size)
|
|
33221
|
+
fs49.copyFileSync(process.execPath, exe);
|
|
33222
|
+
spawn6(exe, [path62.join(launchDir, "runtime", "netproxy.js")], {
|
|
32851
33223
|
detached: true,
|
|
32852
33224
|
stdio: "ignore",
|
|
32853
33225
|
windowsHide: true
|
|
@@ -32891,8 +33263,8 @@ async function applyAllowOnly() {
|
|
|
32891
33263
|
}
|
|
32892
33264
|
|
|
32893
33265
|
// src/guest/setup/managed-policy.ts
|
|
32894
|
-
import
|
|
32895
|
-
import
|
|
33266
|
+
import fs50 from "node:fs";
|
|
33267
|
+
import path63 from "node:path";
|
|
32896
33268
|
|
|
32897
33269
|
// src/guest/setup/git-rules.ts
|
|
32898
33270
|
var SHELLS = ["Bash", "PowerShell"];
|
|
@@ -32949,44 +33321,44 @@ function gitDenyRules(access) {
|
|
|
32949
33321
|
|
|
32950
33322
|
// src/guest/setup/managed-policy.ts
|
|
32951
33323
|
function managedSettingsFile() {
|
|
32952
|
-
return
|
|
33324
|
+
return path63.join(path63.dirname(managedClaudeMd()), "managed-settings.json");
|
|
32953
33325
|
}
|
|
32954
33326
|
function writeManagedSettings2(access) {
|
|
32955
33327
|
const file3 = managedSettingsFile();
|
|
32956
33328
|
const deny = gitDenyRules(access);
|
|
32957
33329
|
if (deny.length === 0) {
|
|
32958
|
-
|
|
33330
|
+
fs50.rmSync(file3, { force: true });
|
|
32959
33331
|
return;
|
|
32960
33332
|
}
|
|
32961
|
-
|
|
32962
|
-
|
|
33333
|
+
fs50.mkdirSync(path63.dirname(file3), { recursive: true });
|
|
33334
|
+
fs50.writeFileSync(file3, JSON.stringify({ permissions: { deny } }, null, 2) + "\n", "utf8");
|
|
32963
33335
|
}
|
|
32964
33336
|
|
|
32965
33337
|
// src/guest/setup/desktop.ts
|
|
32966
|
-
import
|
|
33338
|
+
import fs51 from "node:fs";
|
|
32967
33339
|
import os10 from "node:os";
|
|
32968
|
-
import
|
|
33340
|
+
import path64 from "node:path";
|
|
32969
33341
|
function applyPersonalization() {
|
|
32970
|
-
const dir =
|
|
33342
|
+
const dir = path64.join(launchDir, "personalize");
|
|
32971
33343
|
if (!session.personalization || !exists(dir) || dryRun || !isWin) return;
|
|
32972
|
-
exec(SYSTEM.reg(), ["import",
|
|
32973
|
-
const wallpaper =
|
|
32974
|
-
const local = wallpaper ?
|
|
32975
|
-
if (wallpaper && local)
|
|
33344
|
+
exec(SYSTEM.reg(), ["import", path64.join(dir, "personalize.reg")], { stdio: "ignore" });
|
|
33345
|
+
const wallpaper = fs51.readdirSync(dir).find((f) => f.startsWith("wallpaper"));
|
|
33346
|
+
const local = wallpaper ? path64.join(mkdirp(path64.join(os10.homedir(), "Pictures")), wallpaper) : null;
|
|
33347
|
+
if (wallpaper && local) fs51.copyFileSync(path64.join(dir, wallpaper), local);
|
|
32976
33348
|
runScript("set-desktop.ps1", local ? ["-Wallpaper", local] : []);
|
|
32977
33349
|
log("Desktop personalisation applied from this PC.");
|
|
32978
33350
|
}
|
|
32979
33351
|
|
|
32980
33352
|
// src/guest/setup/git-identity.ts
|
|
32981
|
-
import
|
|
33353
|
+
import fs52 from "node:fs";
|
|
32982
33354
|
import os11 from "node:os";
|
|
32983
|
-
import
|
|
33355
|
+
import path65 from "node:path";
|
|
32984
33356
|
import { spawnSync as spawnSync7 } from "node:child_process";
|
|
32985
33357
|
function setupGitConfig(env) {
|
|
32986
33358
|
if (dryRun) return;
|
|
32987
|
-
const source =
|
|
32988
|
-
if (exists(source))
|
|
32989
|
-
const git =
|
|
33359
|
+
const source = path65.join(launchDir, "home", ".gitconfig");
|
|
33360
|
+
if (exists(source)) fs52.copyFileSync(source, path65.join(os11.homedir(), ".gitconfig"));
|
|
33361
|
+
const git = path65.join(toolsDir, "git", "cmd", "git.exe");
|
|
32990
33362
|
if (!exists(git)) return;
|
|
32991
33363
|
const { GIT_DIR: _gitDir, ...rest } = env;
|
|
32992
33364
|
spawnSync7(git, ["config", "--global", "--add", "safe.directory", "*"], {
|
|
@@ -33004,35 +33376,35 @@ function ensurePtyHost() {
|
|
|
33004
33376
|
}
|
|
33005
33377
|
|
|
33006
33378
|
// src/guest/toolchains/leftovers.ts
|
|
33007
|
-
import
|
|
33008
|
-
import
|
|
33379
|
+
import fs53 from "node:fs";
|
|
33380
|
+
import path66 from "node:path";
|
|
33009
33381
|
var STAGING = /\.staging-[0-9a-f]+$/i;
|
|
33010
33382
|
var entries2 = (dir) => {
|
|
33011
33383
|
try {
|
|
33012
|
-
return
|
|
33384
|
+
return fs53.readdirSync(dir, { withFileTypes: true });
|
|
33013
33385
|
} catch {
|
|
33014
33386
|
return [];
|
|
33015
33387
|
}
|
|
33016
33388
|
};
|
|
33017
33389
|
function pruneToolLeftovers() {
|
|
33018
|
-
for (const legacy of ["ptyhost", "gitshim"]) safeRemove(
|
|
33390
|
+
for (const legacy of ["ptyhost", "gitshim"]) safeRemove(path66.join(toolsDir, legacy), toolsDir);
|
|
33019
33391
|
for (const top of entries2(toolsDir)) {
|
|
33020
|
-
const dir =
|
|
33392
|
+
const dir = path66.join(toolsDir, top.name);
|
|
33021
33393
|
if (STAGING.test(top.name)) safeRemove(dir, toolsDir);
|
|
33022
33394
|
else if (top.isDirectory())
|
|
33023
|
-
for (const sub of entries2(dir).filter((e) => STAGING.test(e.name))) safeRemove(
|
|
33395
|
+
for (const sub of entries2(dir).filter((e) => STAGING.test(e.name))) safeRemove(path66.join(dir, sub.name), dir);
|
|
33024
33396
|
}
|
|
33025
33397
|
}
|
|
33026
33398
|
|
|
33027
33399
|
// src/guest/audit/process-audit.ts
|
|
33028
|
-
import
|
|
33400
|
+
import path67 from "node:path";
|
|
33029
33401
|
import { spawnSync as spawnSync8 } from "node:child_process";
|
|
33030
33402
|
var PROCESS_CREATION = "{0CCE922B-69AE-11D9-BED3-505054503030}";
|
|
33031
33403
|
var auditOn = () => Boolean(session.auditProcesses) && isWin && !dryRun;
|
|
33032
33404
|
function enableProcessAudit() {
|
|
33033
33405
|
if (!auditOn()) return;
|
|
33034
33406
|
spawnSync8(
|
|
33035
|
-
|
|
33407
|
+
path67.join(process.env.WINDIR ?? "C:\\Windows", "System32", "auditpol.exe"),
|
|
33036
33408
|
["/set", "/subcategory:" + PROCESS_CREATION, "/success:enable"],
|
|
33037
33409
|
{ windowsHide: true, stdio: "ignore" }
|
|
33038
33410
|
);
|
|
@@ -33054,6 +33426,831 @@ function enableProcessAudit() {
|
|
|
33054
33426
|
log("Audit: programs started in the sandbox are recorded (audit.processes).");
|
|
33055
33427
|
}
|
|
33056
33428
|
|
|
33429
|
+
// src/guest/vpn/vpn.ts
|
|
33430
|
+
import dns2 from "node:dns";
|
|
33431
|
+
import fs57 from "node:fs";
|
|
33432
|
+
import os14 from "node:os";
|
|
33433
|
+
import path71 from "node:path";
|
|
33434
|
+
|
|
33435
|
+
// src/shared/vpn/ovpn.ts
|
|
33436
|
+
var PROGRAM_DIRECTIVES = [
|
|
33437
|
+
"script-security",
|
|
33438
|
+
"up",
|
|
33439
|
+
"down",
|
|
33440
|
+
"up-restart",
|
|
33441
|
+
"down-pre",
|
|
33442
|
+
"route-up",
|
|
33443
|
+
"route-pre-down",
|
|
33444
|
+
"ipchange",
|
|
33445
|
+
"tls-verify",
|
|
33446
|
+
"plugin",
|
|
33447
|
+
"client-connect",
|
|
33448
|
+
"client-disconnect",
|
|
33449
|
+
"learn-address",
|
|
33450
|
+
"auth-user-pass-verify",
|
|
33451
|
+
"setenv-safe",
|
|
33452
|
+
"management",
|
|
33453
|
+
"management-client",
|
|
33454
|
+
"management-client-auth",
|
|
33455
|
+
"management-hold",
|
|
33456
|
+
"management-query-passwords",
|
|
33457
|
+
"config",
|
|
33458
|
+
"daemon",
|
|
33459
|
+
"service",
|
|
33460
|
+
"cd",
|
|
33461
|
+
"chroot",
|
|
33462
|
+
"setcon",
|
|
33463
|
+
"log",
|
|
33464
|
+
"log-append",
|
|
33465
|
+
"writepid",
|
|
33466
|
+
"status",
|
|
33467
|
+
"askpass",
|
|
33468
|
+
"engine",
|
|
33469
|
+
"bcast-dev",
|
|
33470
|
+
"dev-node",
|
|
33471
|
+
"cryptoapicert",
|
|
33472
|
+
"pkcs11-providers",
|
|
33473
|
+
"pkcs12",
|
|
33474
|
+
"http-proxy-user-pass",
|
|
33475
|
+
"tmp-dir"
|
|
33476
|
+
];
|
|
33477
|
+
var ALLOWED = /* @__PURE__ */ new Set([
|
|
33478
|
+
"client",
|
|
33479
|
+
"tls-client",
|
|
33480
|
+
"dev",
|
|
33481
|
+
"dev-type",
|
|
33482
|
+
"proto",
|
|
33483
|
+
"remote",
|
|
33484
|
+
"remote-random",
|
|
33485
|
+
"remote-random-hostname",
|
|
33486
|
+
"resolv-retry",
|
|
33487
|
+
"nobind",
|
|
33488
|
+
"persist-key",
|
|
33489
|
+
"persist-tun",
|
|
33490
|
+
"remote-cert-tls",
|
|
33491
|
+
"remote-cert-eku",
|
|
33492
|
+
"ns-cert-type",
|
|
33493
|
+
"verify-x509-name",
|
|
33494
|
+
"cipher",
|
|
33495
|
+
"data-ciphers",
|
|
33496
|
+
"data-ciphers-fallback",
|
|
33497
|
+
"ncp-ciphers",
|
|
33498
|
+
"auth",
|
|
33499
|
+
"verb",
|
|
33500
|
+
"mute",
|
|
33501
|
+
"mute-replay-warnings",
|
|
33502
|
+
"reneg-sec",
|
|
33503
|
+
"reneg-bytes",
|
|
33504
|
+
"reneg-pkts",
|
|
33505
|
+
"tun-mtu",
|
|
33506
|
+
"tun-mtu-extra",
|
|
33507
|
+
"ping-timer-rem",
|
|
33508
|
+
"fast-io",
|
|
33509
|
+
"tls-timeout",
|
|
33510
|
+
"push-peer-info",
|
|
33511
|
+
"comp-noadapt",
|
|
33512
|
+
"link-mtu",
|
|
33513
|
+
"fragment",
|
|
33514
|
+
"mssfix",
|
|
33515
|
+
"sndbuf",
|
|
33516
|
+
"rcvbuf",
|
|
33517
|
+
"comp-lzo",
|
|
33518
|
+
"compress",
|
|
33519
|
+
"allow-compression",
|
|
33520
|
+
"key-direction",
|
|
33521
|
+
"auth-user-pass",
|
|
33522
|
+
"auth-nocache",
|
|
33523
|
+
"explicit-exit-notify",
|
|
33524
|
+
"pull",
|
|
33525
|
+
"pull-filter",
|
|
33526
|
+
"route-nopull",
|
|
33527
|
+
"route",
|
|
33528
|
+
"route-ipv6",
|
|
33529
|
+
"route-delay",
|
|
33530
|
+
"route-metric",
|
|
33531
|
+
"redirect-gateway",
|
|
33532
|
+
"redirect-private",
|
|
33533
|
+
"dhcp-option",
|
|
33534
|
+
"block-outside-dns",
|
|
33535
|
+
"register-dns",
|
|
33536
|
+
"topology",
|
|
33537
|
+
"tls-version-min",
|
|
33538
|
+
"tls-version-max",
|
|
33539
|
+
"tls-cipher",
|
|
33540
|
+
"tls-ciphersuites",
|
|
33541
|
+
"tls-groups",
|
|
33542
|
+
"tls-exit",
|
|
33543
|
+
"ping",
|
|
33544
|
+
"ping-restart",
|
|
33545
|
+
"ping-exit",
|
|
33546
|
+
"keepalive",
|
|
33547
|
+
"connect-retry",
|
|
33548
|
+
"connect-retry-max",
|
|
33549
|
+
"connect-timeout",
|
|
33550
|
+
"server-poll-timeout",
|
|
33551
|
+
"float",
|
|
33552
|
+
"ifconfig-nowarn",
|
|
33553
|
+
"tun-ipv6",
|
|
33554
|
+
"disable-dco",
|
|
33555
|
+
"windows-driver",
|
|
33556
|
+
"ignore-unknown-option",
|
|
33557
|
+
"opt-verify",
|
|
33558
|
+
"setenv",
|
|
33559
|
+
"key-method",
|
|
33560
|
+
"replay-window",
|
|
33561
|
+
"hand-window",
|
|
33562
|
+
"tran-window",
|
|
33563
|
+
"inactive",
|
|
33564
|
+
"socket-flags",
|
|
33565
|
+
"auth-retry",
|
|
33566
|
+
"ca",
|
|
33567
|
+
"cert",
|
|
33568
|
+
"key",
|
|
33569
|
+
"tls-auth",
|
|
33570
|
+
"tls-crypt",
|
|
33571
|
+
"tls-crypt-v2",
|
|
33572
|
+
"extra-certs",
|
|
33573
|
+
"dh"
|
|
33574
|
+
]);
|
|
33575
|
+
var FILE_DIRECTIVES = /* @__PURE__ */ new Set(["ca", "cert", "key", "tls-auth", "tls-crypt", "tls-crypt-v2", "extra-certs", "dh"]);
|
|
33576
|
+
var BLOCKS = /* @__PURE__ */ new Set(["ca", "cert", "key", "tls-auth", "tls-crypt", "tls-crypt-v2", "extra-certs", "dh"]);
|
|
33577
|
+
var MAX_OVPN_BYTES = 256 * 1024;
|
|
33578
|
+
var MAX_LINES = 4e3;
|
|
33579
|
+
var HOST = /^(?:\d{1,3}(?:\.\d{1,3}){3}|[A-Za-z0-9](?:[A-Za-z0-9.-]{0,251}[A-Za-z0-9])?)$/;
|
|
33580
|
+
function directiveOf(line) {
|
|
33581
|
+
const text = line.replace(/^\uFEFF/, "").trim();
|
|
33582
|
+
if (text === "" || text.startsWith("#") || text.startsWith(";")) return null;
|
|
33583
|
+
const parts2 = text.replace(/^-+/, "").split(/\s+/);
|
|
33584
|
+
return { name: parts2[0].toLowerCase(), args: parts2.slice(1) };
|
|
33585
|
+
}
|
|
33586
|
+
function inspectOvpn(text) {
|
|
33587
|
+
const problems = [];
|
|
33588
|
+
const found = [];
|
|
33589
|
+
const refuse = (message) => {
|
|
33590
|
+
if (problems.length < 20 && !problems.includes(message)) problems.push(message);
|
|
33591
|
+
};
|
|
33592
|
+
if (Buffer.byteLength(text, "utf8") > MAX_OVPN_BYTES) return { ok: false, problems: ["the file is too big"] };
|
|
33593
|
+
if (text.includes("\0")) return { ok: false, problems: ["the file is not text"] };
|
|
33594
|
+
const lines = text.split(/\r?\n/);
|
|
33595
|
+
if (lines.length > MAX_LINES) return { ok: false, problems: ["the file has too many lines"] };
|
|
33596
|
+
let block = null;
|
|
33597
|
+
let defaultProto = "udp";
|
|
33598
|
+
lines.forEach((line, i) => {
|
|
33599
|
+
const at = "line " + (i + 1) + ": ";
|
|
33600
|
+
const trimmed = line.trim();
|
|
33601
|
+
if (block) {
|
|
33602
|
+
if (trimmed.toLowerCase() === "</" + block + ">") block = null;
|
|
33603
|
+
else if (/^<\/?[A-Za-z-]+>$/.test(trimmed)) refuse(at + "a section inside a section");
|
|
33604
|
+
return;
|
|
33605
|
+
}
|
|
33606
|
+
const open2 = /^<([A-Za-z0-9-]+)>$/.exec(trimmed);
|
|
33607
|
+
if (open2) {
|
|
33608
|
+
const tag = open2[1].toLowerCase();
|
|
33609
|
+
if (!BLOCKS.has(tag)) refuse(at + "<" + tag + "> is not allowed");
|
|
33610
|
+
block = tag;
|
|
33611
|
+
return;
|
|
33612
|
+
}
|
|
33613
|
+
const d = directiveOf(line);
|
|
33614
|
+
if (!d) return;
|
|
33615
|
+
if (!/^[a-z0-9-]{1,40}$/.test(d.name)) return refuse(at + "a directive name with odd characters");
|
|
33616
|
+
if (PROGRAM_DIRECTIVES.includes(d.name))
|
|
33617
|
+
return refuse(at + d.name + " runs a program or reads or writes a file on this machine");
|
|
33618
|
+
if (!ALLOWED.has(d.name)) return refuse(at + d.name + " is not on the list of settings that are safe to accept");
|
|
33619
|
+
if (FILE_DIRECTIVES.has(d.name))
|
|
33620
|
+
return refuse(at + d.name + " names a file: certificates must be inside the profile");
|
|
33621
|
+
if (d.name === "auth-user-pass" && d.args.length > 0)
|
|
33622
|
+
return refuse(at + "auth-user-pass names a file: the login is given separately");
|
|
33623
|
+
if (d.name === "setenv" && !(d.args[0] === "CLIENT_CERT" && d.args.length === 2))
|
|
33624
|
+
return refuse(at + "setenv may only be CLIENT_CERT");
|
|
33625
|
+
if (d.name === "proto") defaultProto = d.args[0]?.startsWith("tcp") ? "tcp" : "udp";
|
|
33626
|
+
if (d.name === "remote") {
|
|
33627
|
+
const [host, port = "1194", proto] = d.args;
|
|
33628
|
+
if (!host || !HOST.test(host)) return refuse(at + "remote needs a host name or an IPv4 address");
|
|
33629
|
+
const n = Number(port);
|
|
33630
|
+
if (!Number.isInteger(n) || n < 1 || n > 65535) return refuse(at + "remote has an invalid port");
|
|
33631
|
+
found.push({ host, port: n, ...proto ? { proto: proto.startsWith("tcp") ? "tcp" : "udp" } : {} });
|
|
33632
|
+
}
|
|
33633
|
+
});
|
|
33634
|
+
const remotes = found.map((r) => ({ host: r.host, port: r.port, proto: r.proto ?? defaultProto }));
|
|
33635
|
+
if (block) refuse("a <" + block + "> section is never closed");
|
|
33636
|
+
if (remotes.length === 0) refuse("it names no remote server");
|
|
33637
|
+
if (remotes.length > 64) refuse("it names too many servers");
|
|
33638
|
+
return problems.length ? { ok: false, problems } : { ok: true, remotes };
|
|
33639
|
+
}
|
|
33640
|
+
function assertSafeOvpn(text, what) {
|
|
33641
|
+
const report = inspectOvpn(text);
|
|
33642
|
+
if (report.ok) return report.remotes;
|
|
33643
|
+
throw new Error(
|
|
33644
|
+
what + " was refused because it could run programs or is not a plain profile:\n - " + report.problems.slice(0, 5).join("\n - ")
|
|
33645
|
+
);
|
|
33646
|
+
}
|
|
33647
|
+
|
|
33648
|
+
// src/shared/vpn/wireguard.ts
|
|
33649
|
+
import net2 from "node:net";
|
|
33650
|
+
var MAX_WIREGUARD_BYTES = 16 * 1024;
|
|
33651
|
+
var MAX_LINES2 = 300;
|
|
33652
|
+
var MAX_PEERS = 16;
|
|
33653
|
+
var WIREGUARD_PROGRAM_KEYS = ["preup", "postup", "predown", "postdown", "table", "saveconfig"];
|
|
33654
|
+
var INTERFACE_KEYS = /* @__PURE__ */ new Set(["privatekey", "address", "dns", "mtu", "listenport"]);
|
|
33655
|
+
var PEER_KEYS = /* @__PURE__ */ new Set(["publickey", "presharedkey", "allowedips", "endpoint", "persistentkeepalive"]);
|
|
33656
|
+
var LIST_KEYS = /* @__PURE__ */ new Set(["address", "dns", "allowedips"]);
|
|
33657
|
+
var KEY = /^[A-Za-z0-9+/]{43}=$/;
|
|
33658
|
+
var HOST2 = /^(?:\d{1,3}(?:\.\d{1,3}){3}|[A-Za-z0-9](?:[A-Za-z0-9.-]{0,251}[A-Za-z0-9])?)$/;
|
|
33659
|
+
function validCidr(text) {
|
|
33660
|
+
const [addr, prefix, ...rest] = text.split("/");
|
|
33661
|
+
if (rest.length > 0 || !addr) return false;
|
|
33662
|
+
const version2 = net2.isIP(addr);
|
|
33663
|
+
if (version2 === 0) return false;
|
|
33664
|
+
if (prefix === void 0) return true;
|
|
33665
|
+
if (!/^\d{1,3}$/.test(prefix)) return false;
|
|
33666
|
+
return Number(prefix) <= (version2 === 4 ? 32 : 128);
|
|
33667
|
+
}
|
|
33668
|
+
var inRange = (text, low, high) => {
|
|
33669
|
+
if (!/^\d{1,5}$/.test(text)) return null;
|
|
33670
|
+
const n = Number(text);
|
|
33671
|
+
return n >= low && n <= high ? n : null;
|
|
33672
|
+
};
|
|
33673
|
+
var splitList = (text) => text.split(",").map((s) => s.trim()).filter(Boolean);
|
|
33674
|
+
function inspectWireguard(text) {
|
|
33675
|
+
const problems = [];
|
|
33676
|
+
const refuse = (message) => {
|
|
33677
|
+
if (problems.length < 20 && !problems.includes(message)) problems.push(message);
|
|
33678
|
+
};
|
|
33679
|
+
if (Buffer.byteLength(text, "utf8") > MAX_WIREGUARD_BYTES) return { ok: false, problems: ["the file is too big"] };
|
|
33680
|
+
if (text.includes("\0")) return { ok: false, problems: ["the file is not text"] };
|
|
33681
|
+
const lines = (text.charCodeAt(0) === 65279 ? text.slice(1) : text).split(/\r?\n/);
|
|
33682
|
+
if (lines.length > MAX_LINES2) return { ok: false, problems: ["the file has too many lines"] };
|
|
33683
|
+
const sections = [];
|
|
33684
|
+
let current = null;
|
|
33685
|
+
lines.forEach((raw, i) => {
|
|
33686
|
+
const at = "line " + (i + 1) + ": ";
|
|
33687
|
+
const line = raw.replace(/#.*$/, "").trim();
|
|
33688
|
+
if (!line) return;
|
|
33689
|
+
const header = /^\[([A-Za-z]{1,20})\]$/.exec(line);
|
|
33690
|
+
if (header) {
|
|
33691
|
+
const name = header[1].toLowerCase();
|
|
33692
|
+
if (name !== "interface" && name !== "peer") {
|
|
33693
|
+
current = null;
|
|
33694
|
+
return refuse(at + "[" + name + "] is not allowed");
|
|
33695
|
+
}
|
|
33696
|
+
current = { kind: name, values: /* @__PURE__ */ new Map() };
|
|
33697
|
+
sections.push(current);
|
|
33698
|
+
return;
|
|
33699
|
+
}
|
|
33700
|
+
const pair = /^([A-Za-z]{1,40})\s*=\s*(.*)$/.exec(line);
|
|
33701
|
+
if (!pair) return refuse(at + 'not a "Key = value" line');
|
|
33702
|
+
const key = pair[1].toLowerCase();
|
|
33703
|
+
if (WIREGUARD_PROGRAM_KEYS.includes(key))
|
|
33704
|
+
return refuse(at + pair[1] + " runs a program or changes how the tunnel is routed or saved");
|
|
33705
|
+
if (!current) return refuse(at + pair[1] + " is outside a section");
|
|
33706
|
+
if (!(current.kind === "interface" ? INTERFACE_KEYS : PEER_KEYS).has(key))
|
|
33707
|
+
return refuse(at + pair[1] + " is not on the list of settings that are safe to accept");
|
|
33708
|
+
const seen = current.values.get(key);
|
|
33709
|
+
if (seen && !LIST_KEYS.has(key)) return refuse(at + pair[1] + " is given twice");
|
|
33710
|
+
current.values.set(key, [...seen ?? [], pair[2].trim()]);
|
|
33711
|
+
});
|
|
33712
|
+
const one = (s, key) => s.values.get(key)?.[0];
|
|
33713
|
+
const joined = (s, key) => (s.values.get(key) ?? []).flatMap(splitList);
|
|
33714
|
+
const interfaces = sections.filter((s) => s.kind === "interface");
|
|
33715
|
+
const peers = sections.filter((s) => s.kind === "peer");
|
|
33716
|
+
if (interfaces.length !== 1) refuse("it needs exactly one [Interface] section");
|
|
33717
|
+
if (peers.length === 0) refuse("it has no [Peer] section");
|
|
33718
|
+
if (peers.length > MAX_PEERS) refuse("it has too many [Peer] sections");
|
|
33719
|
+
if (problems.length) return { ok: false, problems };
|
|
33720
|
+
const face = interfaces[0];
|
|
33721
|
+
const privateKey = one(face, "privatekey");
|
|
33722
|
+
if (!privateKey) refuse("[Interface] has no PrivateKey");
|
|
33723
|
+
else if (!KEY.test(privateKey)) refuse("PrivateKey is not a WireGuard key (44 characters of base64)");
|
|
33724
|
+
const addresses = joined(face, "address");
|
|
33725
|
+
if (addresses.length === 0 || !addresses.every(validCidr)) refuse("[Interface] needs valid Address values");
|
|
33726
|
+
else if (!addresses.some((a) => net2.isIPv4(a.split("/")[0])))
|
|
33727
|
+
refuse("Address needs an IPv4 address (the kill switch works on IPv4)");
|
|
33728
|
+
const dns3 = joined(face, "dns");
|
|
33729
|
+
if (!dns3.every((d) => net2.isIP(d) !== 0)) refuse("DNS may only list IP addresses");
|
|
33730
|
+
const mtuText = one(face, "mtu");
|
|
33731
|
+
const mtu = mtuText === void 0 ? void 0 : inRange(mtuText, 576, 1500);
|
|
33732
|
+
if (mtuText !== void 0 && mtu === null) refuse("MTU must be a number from 576 to 1500");
|
|
33733
|
+
const portText = one(face, "listenport");
|
|
33734
|
+
const listenPort = portText === void 0 ? void 0 : inRange(portText, 1, 65535);
|
|
33735
|
+
if (portText !== void 0 && listenPort === null) refuse("ListenPort must be a number from 1 to 65535");
|
|
33736
|
+
const checked = [];
|
|
33737
|
+
peers.forEach((p, n) => {
|
|
33738
|
+
const who = "[Peer] " + (n + 1) + ": ";
|
|
33739
|
+
const publicKey = one(p, "publickey");
|
|
33740
|
+
if (!publicKey || !KEY.test(publicKey)) return refuse(who + "PublicKey is missing or not a WireGuard key");
|
|
33741
|
+
const preshared = one(p, "presharedkey");
|
|
33742
|
+
if (preshared !== void 0 && !KEY.test(preshared)) return refuse(who + "PresharedKey is not a WireGuard key");
|
|
33743
|
+
const allowed = joined(p, "allowedips");
|
|
33744
|
+
if (allowed.length === 0 || !allowed.every(validCidr)) return refuse(who + "AllowedIPs is missing or invalid");
|
|
33745
|
+
const endpoint = one(p, "endpoint");
|
|
33746
|
+
const m = endpoint ? /^([^:[\]]+):(\d{1,5})$/.exec(endpoint) : null;
|
|
33747
|
+
if (!m || !HOST2.test(m[1]) || inRange(m[2], 1, 65535) === null)
|
|
33748
|
+
return refuse(who + "Endpoint must be host:port with a name or an IPv4 address");
|
|
33749
|
+
if (/^\d+\.\d+\.\d+\.\d+$/.test(m[1]) && !net2.isIPv4(m[1])) return refuse(who + "Endpoint is not a valid address");
|
|
33750
|
+
const keepText = one(p, "persistentkeepalive");
|
|
33751
|
+
let keepalive;
|
|
33752
|
+
if (keepText !== void 0 && keepText.toLowerCase() !== "off") {
|
|
33753
|
+
const k = inRange(keepText, 0, 65535);
|
|
33754
|
+
if (k === null) return refuse(who + "PersistentKeepalive must be a number or off");
|
|
33755
|
+
keepalive = k;
|
|
33756
|
+
}
|
|
33757
|
+
checked.push({
|
|
33758
|
+
publicKey,
|
|
33759
|
+
...preshared ? { presharedKey: preshared } : {},
|
|
33760
|
+
allowedIps: allowed,
|
|
33761
|
+
endpointHost: m[1],
|
|
33762
|
+
endpointPort: Number(m[2]),
|
|
33763
|
+
...keepalive !== void 0 ? { keepalive } : {}
|
|
33764
|
+
});
|
|
33765
|
+
});
|
|
33766
|
+
if (problems.length || !privateKey) return { ok: false, problems };
|
|
33767
|
+
return {
|
|
33768
|
+
ok: true,
|
|
33769
|
+
config: {
|
|
33770
|
+
privateKey,
|
|
33771
|
+
addresses,
|
|
33772
|
+
dns: dns3,
|
|
33773
|
+
...typeof mtu === "number" ? { mtu } : {},
|
|
33774
|
+
...typeof listenPort === "number" ? { listenPort } : {},
|
|
33775
|
+
peers: checked
|
|
33776
|
+
}
|
|
33777
|
+
};
|
|
33778
|
+
}
|
|
33779
|
+
function assertSafeWireguard(text, what) {
|
|
33780
|
+
const report = inspectWireguard(text);
|
|
33781
|
+
if (report.ok) return report.config;
|
|
33782
|
+
throw new Error(
|
|
33783
|
+
what + " was refused because it could run programs or is not a plain WireGuard config:\n - " + report.problems.slice(0, 5).join("\n - ")
|
|
33784
|
+
);
|
|
33785
|
+
}
|
|
33786
|
+
function renderWireguard(config2, endpointIps = {}) {
|
|
33787
|
+
const out = ["[Interface]", "PrivateKey = " + config2.privateKey, "Address = " + config2.addresses.join(", ")];
|
|
33788
|
+
if (config2.dns.length) out.push("DNS = " + config2.dns.join(", "));
|
|
33789
|
+
if (config2.mtu !== void 0) out.push("MTU = " + config2.mtu);
|
|
33790
|
+
if (config2.listenPort !== void 0) out.push("ListenPort = " + config2.listenPort);
|
|
33791
|
+
config2.peers.forEach((p, i) => {
|
|
33792
|
+
out.push("", "[Peer]", "PublicKey = " + p.publicKey);
|
|
33793
|
+
if (p.presharedKey) out.push("PresharedKey = " + p.presharedKey);
|
|
33794
|
+
out.push(
|
|
33795
|
+
"AllowedIPs = " + p.allowedIps.join(", "),
|
|
33796
|
+
"Endpoint = " + (endpointIps[i] ?? p.endpointHost) + ":" + p.endpointPort
|
|
33797
|
+
);
|
|
33798
|
+
if (p.keepalive !== void 0) out.push("PersistentKeepalive = " + p.keepalive);
|
|
33799
|
+
});
|
|
33800
|
+
return out.join("\r\n") + "\r\n";
|
|
33801
|
+
}
|
|
33802
|
+
function wireguardEndpoints(config2) {
|
|
33803
|
+
return config2.peers.map((p) => ({ host: p.endpointHost, port: p.endpointPort }));
|
|
33804
|
+
}
|
|
33805
|
+
function wireguardTunnelAddress(config2) {
|
|
33806
|
+
const found = config2.addresses.map((a) => a.split("/")[0]).find((a) => net2.isIPv4(a));
|
|
33807
|
+
if (!found) throw new Error("the config has no IPv4 address");
|
|
33808
|
+
return found;
|
|
33809
|
+
}
|
|
33810
|
+
function routesEverything(config2) {
|
|
33811
|
+
return config2.peers.some((p) => p.allowedIps.some((a) => a === "0.0.0.0/0"));
|
|
33812
|
+
}
|
|
33813
|
+
function serviceRunning(scOutput) {
|
|
33814
|
+
return /STATE\s*:\s*\d+\s+RUNNING/i.test(scOutput);
|
|
33815
|
+
}
|
|
33816
|
+
function handshakeDone(wgOutput) {
|
|
33817
|
+
return wgOutput.split(/\r?\n/).some((line) => {
|
|
33818
|
+
const t = /\s(\d+)\s*$/.exec(line);
|
|
33819
|
+
return t !== null && Number(t[1]) > 0;
|
|
33820
|
+
});
|
|
33821
|
+
}
|
|
33822
|
+
|
|
33823
|
+
// src/shared/vpn/kill-switch.ts
|
|
33824
|
+
var VPN_RULE_PREFIX = "AgentSandbox-VPN-";
|
|
33825
|
+
var rule = (name, extra) => [
|
|
33826
|
+
"advfirewall",
|
|
33827
|
+
"firewall",
|
|
33828
|
+
"add",
|
|
33829
|
+
"rule",
|
|
33830
|
+
"name=" + VPN_RULE_PREFIX + name,
|
|
33831
|
+
"dir=out",
|
|
33832
|
+
"action=allow",
|
|
33833
|
+
"enable=yes",
|
|
33834
|
+
"profile=any",
|
|
33835
|
+
...extra
|
|
33836
|
+
];
|
|
33837
|
+
var drop = (name) => [
|
|
33838
|
+
"advfirewall",
|
|
33839
|
+
"firewall",
|
|
33840
|
+
"delete",
|
|
33841
|
+
"rule",
|
|
33842
|
+
"name=" + VPN_RULE_PREFIX + name
|
|
33843
|
+
];
|
|
33844
|
+
function ruleNames(serverCount) {
|
|
33845
|
+
return [
|
|
33846
|
+
"Loopback",
|
|
33847
|
+
"DHCP",
|
|
33848
|
+
"Host",
|
|
33849
|
+
"Tunnel",
|
|
33850
|
+
...Array.from({ length: Math.max(serverCount, 0) }, (_v, i) => "Server-" + (i + 1))
|
|
33851
|
+
];
|
|
33852
|
+
}
|
|
33853
|
+
function cleanServers(servers) {
|
|
33854
|
+
const seen = /* @__PURE__ */ new Set();
|
|
33855
|
+
return servers.filter((s) => {
|
|
33856
|
+
const key = s.proto + ":" + s.ip + ":" + s.port;
|
|
33857
|
+
if (!isIPv4(s.ip) || !Number.isInteger(s.port) || s.port < 1 || s.port > 65535 || seen.has(key)) return false;
|
|
33858
|
+
seen.add(key);
|
|
33859
|
+
return true;
|
|
33860
|
+
});
|
|
33861
|
+
}
|
|
33862
|
+
function killSwitchCommands(servers, ptyHostExe) {
|
|
33863
|
+
const list = cleanServers(servers);
|
|
33864
|
+
return [
|
|
33865
|
+
...ruleNames(Math.max(list.length, 8)).map(drop),
|
|
33866
|
+
["advfirewall", "set", "allprofiles", "state", "on"],
|
|
33867
|
+
["advfirewall", "set", "allprofiles", "firewallpolicy", "blockinbound,blockoutbound"],
|
|
33868
|
+
rule("Loopback", ["protocol=any", "remoteip=127.0.0.0/8"]),
|
|
33869
|
+
rule("DHCP", ["protocol=udp", "localport=68", "remoteport=67"]),
|
|
33870
|
+
...ptyHostExe ? [rule("Host", ["protocol=any", "remoteip=LocalSubnet", "program=" + ptyHostExe])] : [],
|
|
33871
|
+
...list.map(
|
|
33872
|
+
(s, i) => rule("Server-" + (i + 1), ["protocol=" + s.proto, "remoteip=" + s.ip, "remoteport=" + s.port])
|
|
33873
|
+
)
|
|
33874
|
+
];
|
|
33875
|
+
}
|
|
33876
|
+
function tunnelCommands(tunnelIp) {
|
|
33877
|
+
if (!isIPv4(tunnelIp)) throw new Error("Not an IPv4 address: " + tunnelIp);
|
|
33878
|
+
return [drop("Tunnel"), rule("Tunnel", ["protocol=any", "localip=" + tunnelIp])];
|
|
33879
|
+
}
|
|
33880
|
+
function tunnelAddressFromLog(log2) {
|
|
33881
|
+
const add = /net_addr_v4_add:\s*(\d{1,3}(?:\.\d{1,3}){3})\/\d+/.exec(log2);
|
|
33882
|
+
if (add && isIPv4(add[1])) return add[1];
|
|
33883
|
+
const ifconfig = /(?:ifconfig|ip addr add|Notified TAP-Windows driver to set a DHCP IP\/netmask of)\s+(\d{1,3}(?:\.\d{1,3}){3})/i.exec(
|
|
33884
|
+
log2
|
|
33885
|
+
);
|
|
33886
|
+
return ifconfig && isIPv4(ifconfig[1]) ? ifconfig[1] : null;
|
|
33887
|
+
}
|
|
33888
|
+
|
|
33889
|
+
// src/guest/vpn/openvpn.ts
|
|
33890
|
+
import crypto4 from "node:crypto";
|
|
33891
|
+
import fs54 from "node:fs";
|
|
33892
|
+
import path68 from "node:path";
|
|
33893
|
+
|
|
33894
|
+
// src/shared/vpn/download.ts
|
|
33895
|
+
var OPENVPN_MSI = {
|
|
33896
|
+
version: "2.7.8",
|
|
33897
|
+
x64: {
|
|
33898
|
+
file: "OpenVPN-2.7.8-I001-amd64.msi",
|
|
33899
|
+
sha256: "1ea61a3056905b90607d4b0f084c04e5cf3043e07cf192d9cd44b0474f29cc49"
|
|
33900
|
+
},
|
|
33901
|
+
arm64: {
|
|
33902
|
+
file: "OpenVPN-2.7.8-I001-arm64.msi",
|
|
33903
|
+
sha256: "6fc0e8899cc5275ee297fb837bc84aa2bc49f8ef96d7ad93ee3fee1e7163a25c"
|
|
33904
|
+
},
|
|
33905
|
+
base: "https://swupdate.openvpn.org/community/releases/"
|
|
33906
|
+
};
|
|
33907
|
+
var WIREGUARD_MSI = {
|
|
33908
|
+
version: "1.1.1",
|
|
33909
|
+
x64: {
|
|
33910
|
+
file: "wireguard-amd64-1.1.1.msi",
|
|
33911
|
+
sha256: "7bfed60ad61b785c914b38b61555a975488e1d3ec472dbfb2fcdf498fca75242"
|
|
33912
|
+
},
|
|
33913
|
+
arm64: {
|
|
33914
|
+
file: "wireguard-arm64-1.1.1.msi",
|
|
33915
|
+
sha256: "8336335c738d4aff040fa9d11b752da65a80b6f41d3262d6ba5e82f97ebd1bd4"
|
|
33916
|
+
},
|
|
33917
|
+
base: "https://download.wireguard.com/windows-client/"
|
|
33918
|
+
};
|
|
33919
|
+
|
|
33920
|
+
// src/guest/vpn/openvpn.ts
|
|
33921
|
+
function openvpnExe(env = process.env) {
|
|
33922
|
+
return path68.join(env.ProgramFiles ?? "C:\\Program Files", "OpenVPN", "bin", "openvpn.exe");
|
|
33923
|
+
}
|
|
33924
|
+
function openvpnDownload(arch2 = process.arch) {
|
|
33925
|
+
const entry = arch2 === "arm64" ? OPENVPN_MSI.arm64 : OPENVPN_MSI.x64;
|
|
33926
|
+
return { ...entry, url: OPENVPN_MSI.base + entry.file };
|
|
33927
|
+
}
|
|
33928
|
+
var hasHash = (file3, sha256) => crypto4.createHash("sha256").update(fs54.readFileSync(file3)).digest("hex") === sha256;
|
|
33929
|
+
async function ensureOpenVpn() {
|
|
33930
|
+
const exe = openvpnExe();
|
|
33931
|
+
if (!isWin || dryRun) return exe;
|
|
33932
|
+
if (exists(exe)) return exe;
|
|
33933
|
+
const dl = openvpnDownload();
|
|
33934
|
+
const msi = path68.join(mkdirp(path68.join(toolsDir, "downloads")), dl.file);
|
|
33935
|
+
if (!exists(msi) || !hasHash(msi, dl.sha256)) {
|
|
33936
|
+
log("VPN: downloading OpenVPN " + OPENVPN_MSI.version + " (about 6 MB)");
|
|
33937
|
+
await downloader.file(dl.url, msi, dl.sha256);
|
|
33938
|
+
}
|
|
33939
|
+
log("VPN: installing OpenVPN");
|
|
33940
|
+
const logFile2 = path68.join(toolsDir, "downloads", "openvpn-install.log");
|
|
33941
|
+
const code = await spawnAsync(SYSTEM.msiexec(), ["/i", msi, "/qn", "/norestart", "/l*v", logFile2], {
|
|
33942
|
+
stdio: "ignore"
|
|
33943
|
+
});
|
|
33944
|
+
if (code !== 0 && code !== 3010)
|
|
33945
|
+
throw new Error("The OpenVPN installer failed (exit " + code + "). Its log: " + logFile2);
|
|
33946
|
+
if (!exists(exe)) throw new Error("OpenVPN was installed but " + exe + " is missing. The installer log: " + logFile2);
|
|
33947
|
+
return exe;
|
|
33948
|
+
}
|
|
33949
|
+
|
|
33950
|
+
// src/guest/vpn/tunnel.ts
|
|
33951
|
+
import { spawn as spawn7 } from "node:child_process";
|
|
33952
|
+
import fs55 from "node:fs";
|
|
33953
|
+
import os12 from "node:os";
|
|
33954
|
+
import path69 from "node:path";
|
|
33955
|
+
var DONE = "Initialization Sequence Completed";
|
|
33956
|
+
function failureReason(text) {
|
|
33957
|
+
if (/AUTH_FAILED/i.test(text))
|
|
33958
|
+
return "the VPN refused the login (for NordVPN use the service credentials, not your account password)";
|
|
33959
|
+
if (/TLS Error: TLS key negotiation failed|TLS handshake failed/i.test(text))
|
|
33960
|
+
return "it could not reach the VPN server (the network blocks it, or the server is down)";
|
|
33961
|
+
if (/All wintun adapters on this system are in use|Cannot open TUN\/TAP|Could not create Wintun|ovpn-dco.*(error|failed)/i.test(
|
|
33962
|
+
text
|
|
33963
|
+
))
|
|
33964
|
+
return "the network driver for the tunnel could not be used";
|
|
33965
|
+
if (/Exiting due to fatal error/i.test(text)) return "OpenVPN stopped with an error";
|
|
33966
|
+
return null;
|
|
33967
|
+
}
|
|
33968
|
+
var tail = (text, lines = 12) => text.trim().split(/\r?\n/).slice(-lines).join("\n");
|
|
33969
|
+
async function startTunnel(o) {
|
|
33970
|
+
const dir = fs55.mkdtempSync(path69.join(os12.tmpdir(), "sbx-vpn-"));
|
|
33971
|
+
const auth = path69.join(dir, "login.txt");
|
|
33972
|
+
const logFile2 = path69.join(dir, "openvpn.log");
|
|
33973
|
+
const keepLog = () => {
|
|
33974
|
+
try {
|
|
33975
|
+
fs55.mkdirSync(logsDir, { recursive: true });
|
|
33976
|
+
fs55.copyFileSync(logFile2, path69.join(logsDir, "openvpn.log"));
|
|
33977
|
+
} catch {
|
|
33978
|
+
}
|
|
33979
|
+
};
|
|
33980
|
+
fs55.writeFileSync(auth, o.username + "\r\n" + o.password + "\r\n", "utf8");
|
|
33981
|
+
try {
|
|
33982
|
+
const child = spawn7(
|
|
33983
|
+
o.exe,
|
|
33984
|
+
["--config", o.profile, "--auth-user-pass", auth, "--auth-nocache", "--verb", "3", "--log", logFile2],
|
|
33985
|
+
{ detached: true, stdio: "ignore", windowsHide: true }
|
|
33986
|
+
);
|
|
33987
|
+
let exited = null;
|
|
33988
|
+
child.once("exit", (code) => {
|
|
33989
|
+
exited = code ?? -1;
|
|
33990
|
+
});
|
|
33991
|
+
child.once("error", (e) => {
|
|
33992
|
+
exited = -1;
|
|
33993
|
+
log("VPN: could not start OpenVPN: " + e.message);
|
|
33994
|
+
});
|
|
33995
|
+
child.unref();
|
|
33996
|
+
const deadline = Date.now() + (o.timeoutMs ?? 9e4);
|
|
33997
|
+
for (; ; ) {
|
|
33998
|
+
const text = fs55.existsSync(logFile2) ? fs55.readFileSync(logFile2, "utf8") : "";
|
|
33999
|
+
if (text.includes(DONE)) {
|
|
34000
|
+
keepLog();
|
|
34001
|
+
const tunnelIp = tunnelAddressFromLog(text) ?? void 0;
|
|
34002
|
+
return { ok: true, message: "the tunnel is up", ...tunnelIp ? { tunnelIp } : {} };
|
|
34003
|
+
}
|
|
34004
|
+
const reason = failureReason(text);
|
|
34005
|
+
if (exited !== null || reason) {
|
|
34006
|
+
if (exited === null) child.kill();
|
|
34007
|
+
keepLog();
|
|
34008
|
+
return { ok: false, message: (reason ?? "OpenVPN stopped") + ". " + tail(text, 4) };
|
|
34009
|
+
}
|
|
34010
|
+
if (Date.now() > deadline) {
|
|
34011
|
+
child.kill();
|
|
34012
|
+
keepLog();
|
|
34013
|
+
return { ok: false, message: "the tunnel did not come up in time. " + tail(text, 4) };
|
|
34014
|
+
}
|
|
34015
|
+
await new Promise((r) => setTimeout(r, 500));
|
|
34016
|
+
}
|
|
34017
|
+
} finally {
|
|
34018
|
+
fs55.rmSync(auth, { force: true });
|
|
34019
|
+
}
|
|
34020
|
+
}
|
|
34021
|
+
|
|
34022
|
+
// src/guest/vpn/wireguard.ts
|
|
34023
|
+
import { execFile } from "node:child_process";
|
|
34024
|
+
import crypto5 from "node:crypto";
|
|
34025
|
+
import fs56 from "node:fs";
|
|
34026
|
+
import os13 from "node:os";
|
|
34027
|
+
import path70 from "node:path";
|
|
34028
|
+
var WIREGUARD_TUNNEL = "sandbox";
|
|
34029
|
+
function wireguardDir(env = process.env) {
|
|
34030
|
+
return path70.join(env.ProgramFiles ?? "C:\\Program Files", "WireGuard");
|
|
34031
|
+
}
|
|
34032
|
+
function wireguardExe(env = process.env) {
|
|
34033
|
+
return path70.join(wireguardDir(env), "wireguard.exe");
|
|
34034
|
+
}
|
|
34035
|
+
function wireguardDownload(arch2 = process.arch) {
|
|
34036
|
+
const entry = arch2 === "arm64" ? WIREGUARD_MSI.arm64 : WIREGUARD_MSI.x64;
|
|
34037
|
+
return { ...entry, url: WIREGUARD_MSI.base + entry.file };
|
|
34038
|
+
}
|
|
34039
|
+
var hasHash2 = (file3, sha256) => crypto5.createHash("sha256").update(fs56.readFileSync(file3)).digest("hex") === sha256;
|
|
34040
|
+
async function ensureWireguard() {
|
|
34041
|
+
const exe = wireguardExe();
|
|
34042
|
+
if (!isWin || dryRun) return exe;
|
|
34043
|
+
if (exists(exe)) return exe;
|
|
34044
|
+
const dl = wireguardDownload();
|
|
34045
|
+
const msi = path70.join(mkdirp(path70.join(toolsDir, "downloads")), dl.file);
|
|
34046
|
+
if (!exists(msi) || !hasHash2(msi, dl.sha256)) {
|
|
34047
|
+
log("VPN: downloading WireGuard " + WIREGUARD_MSI.version + " (about 3 MB)");
|
|
34048
|
+
await downloader.file(dl.url, msi, dl.sha256);
|
|
34049
|
+
}
|
|
34050
|
+
log("VPN: installing WireGuard");
|
|
34051
|
+
const logFile2 = path70.join(toolsDir, "downloads", "wireguard-install.log");
|
|
34052
|
+
const code = await spawnAsync(
|
|
34053
|
+
SYSTEM.msiexec(),
|
|
34054
|
+
["/i", msi, "/qn", "/norestart", "DO_NOT_LAUNCH=1", "/l*v", logFile2],
|
|
34055
|
+
{
|
|
34056
|
+
stdio: "ignore"
|
|
34057
|
+
}
|
|
34058
|
+
);
|
|
34059
|
+
if (code !== 0 && code !== 3010)
|
|
34060
|
+
throw new Error("The WireGuard installer failed (exit " + code + "). Its log: " + logFile2);
|
|
34061
|
+
if (!exists(exe))
|
|
34062
|
+
throw new Error("WireGuard was installed but " + exe + " is missing. The installer log: " + logFile2);
|
|
34063
|
+
return exe;
|
|
34064
|
+
}
|
|
34065
|
+
var sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
34066
|
+
function output2(file3, args) {
|
|
34067
|
+
return new Promise((resolve2) => {
|
|
34068
|
+
execFile(file3, args, { windowsHide: true, timeout: 15e3, maxBuffer: 1024 * 1024 }, (error62, stdout, stderr) => {
|
|
34069
|
+
const code = error62 ? typeof error62.code === "number" ? error62.code : -1 : 0;
|
|
34070
|
+
resolve2({ code, text: String(stdout) + String(stderr) });
|
|
34071
|
+
});
|
|
34072
|
+
});
|
|
34073
|
+
}
|
|
34074
|
+
var serviceName = () => "WireGuardTunnel$" + WIREGUARD_TUNNEL;
|
|
34075
|
+
var hasAdapter = (ip) => Object.values(os13.networkInterfaces()).some((list) => (list ?? []).some((i) => i.address === ip));
|
|
34076
|
+
async function removeWireguardTunnel(exe) {
|
|
34077
|
+
try {
|
|
34078
|
+
await output2(exe, ["/uninstalltunnelservice", WIREGUARD_TUNNEL]);
|
|
34079
|
+
} catch {
|
|
34080
|
+
}
|
|
34081
|
+
}
|
|
34082
|
+
async function startWireguardTunnel(o) {
|
|
34083
|
+
const root = path70.join(process.env.SystemRoot ?? "C:\\Windows", "Temp");
|
|
34084
|
+
const dir = fs56.mkdtempSync(path70.join(fs56.existsSync(root) ? root : os13.tmpdir(), "sbx-wg-"));
|
|
34085
|
+
const file3 = path70.join(dir, WIREGUARD_TUNNEL + ".conf");
|
|
34086
|
+
fs56.writeFileSync(file3, o.config, "utf8");
|
|
34087
|
+
const fail = async (message) => {
|
|
34088
|
+
await removeWireguardTunnel(o.exe);
|
|
34089
|
+
return { ok: false, message };
|
|
34090
|
+
};
|
|
34091
|
+
try {
|
|
34092
|
+
const install = await output2(o.exe, ["/installtunnelservice", file3]);
|
|
34093
|
+
if (install.code !== 0) return await fail("WireGuard could not install the tunnel (exit " + install.code + ")");
|
|
34094
|
+
const deadline = Date.now() + (o.timeoutMs ?? 6e4);
|
|
34095
|
+
for (; ; ) {
|
|
34096
|
+
const state = await output2(SYSTEM.sc(), ["query", serviceName()]);
|
|
34097
|
+
if (serviceRunning(state.text) && hasAdapter(o.tunnelIp)) {
|
|
34098
|
+
return { ok: true, message: "the tunnel service is running", tunnelIp: o.tunnelIp };
|
|
34099
|
+
}
|
|
34100
|
+
if (/STOPPED/i.test(state.text) || /1060/.test(state.text))
|
|
34101
|
+
return await fail("the WireGuard tunnel service stopped (check the config: keys, address, endpoint)");
|
|
34102
|
+
if (Date.now() > deadline)
|
|
34103
|
+
return await fail("the WireGuard tunnel did not start in time (the network driver may not work here)");
|
|
34104
|
+
await sleep(500);
|
|
34105
|
+
}
|
|
34106
|
+
} finally {
|
|
34107
|
+
fs56.rmSync(dir, { recursive: true, force: true });
|
|
34108
|
+
}
|
|
34109
|
+
}
|
|
34110
|
+
async function waitForHandshake(exe, poke, timeoutMs = 3e4) {
|
|
34111
|
+
const wg = path70.join(path70.dirname(exe), "wg.exe");
|
|
34112
|
+
if (!exists(wg)) return { ok: true, message: "the tunnel service is running (no wg.exe to check the handshake)" };
|
|
34113
|
+
const deadline = Date.now() + timeoutMs;
|
|
34114
|
+
for (; ; ) {
|
|
34115
|
+
await poke().catch(() => void 0);
|
|
34116
|
+
const shown = await output2(wg, ["show", WIREGUARD_TUNNEL, "latest-handshakes"]);
|
|
34117
|
+
if (shown.code === 0 && handshakeDone(shown.text)) return { ok: true, message: "the server answered" };
|
|
34118
|
+
if (Date.now() > deadline)
|
|
34119
|
+
return {
|
|
34120
|
+
ok: false,
|
|
34121
|
+
message: "the VPN server did not answer (check the endpoint, the keys and that its UDP port is reachable)"
|
|
34122
|
+
};
|
|
34123
|
+
await sleep(1e3);
|
|
34124
|
+
}
|
|
34125
|
+
}
|
|
34126
|
+
|
|
34127
|
+
// src/guest/vpn/vpn.ts
|
|
34128
|
+
function setVpnStatus(state, message, extra = {}) {
|
|
34129
|
+
try {
|
|
34130
|
+
writeJsonAtomic(run.vpnFile, {
|
|
34131
|
+
state,
|
|
34132
|
+
message: message.slice(0, 1900),
|
|
34133
|
+
killSwitch: session.vpn?.killSwitch ?? false,
|
|
34134
|
+
updatedAt: now(),
|
|
34135
|
+
...session.vpn ? { server: session.vpn.server.slice(0, 120) } : {},
|
|
34136
|
+
...extra
|
|
34137
|
+
});
|
|
34138
|
+
} catch (e) {
|
|
34139
|
+
warn("Could not write the VPN status: " + errMsg(e));
|
|
34140
|
+
}
|
|
34141
|
+
}
|
|
34142
|
+
async function serverAddresses(remotes) {
|
|
34143
|
+
const out = [];
|
|
34144
|
+
for (const r of remotes) {
|
|
34145
|
+
const ips = isIPv4(r.host) ? [r.host] : await dns2.promises.lookup(r.host, { all: true, family: 4 }).then(
|
|
34146
|
+
(all) => all.map((a) => a.address),
|
|
34147
|
+
() => []
|
|
34148
|
+
);
|
|
34149
|
+
for (const ip of ips) out.push({ ip, port: r.port, proto: r.proto });
|
|
34150
|
+
}
|
|
34151
|
+
return out;
|
|
34152
|
+
}
|
|
34153
|
+
async function wireguardServers(config2) {
|
|
34154
|
+
const endpointIps = {};
|
|
34155
|
+
const servers = [];
|
|
34156
|
+
const found = wireguardEndpoints(config2);
|
|
34157
|
+
for (let i = 0; i < found.length; i++) {
|
|
34158
|
+
const [ip] = await serverAddresses([{ host: found[i].host, port: found[i].port, proto: "udp" }]).then(
|
|
34159
|
+
(all) => all.map((s) => s.ip)
|
|
34160
|
+
);
|
|
34161
|
+
if (!ip) throw new Error("the VPN server address could not be found");
|
|
34162
|
+
endpointIps[i] = ip;
|
|
34163
|
+
servers.push({ ip, port: found[i].port, proto: "udp" });
|
|
34164
|
+
}
|
|
34165
|
+
return { servers, text: renderWireguard(config2, endpointIps) };
|
|
34166
|
+
}
|
|
34167
|
+
async function publicAddress() {
|
|
34168
|
+
try {
|
|
34169
|
+
const text = (await (await fetch("https://api.ipify.org", { signal: AbortSignal.timeout(1e4) })).text()).trim();
|
|
34170
|
+
return /^[0-9a-fA-F.:]{3,45}$/.test(text) ? text : null;
|
|
34171
|
+
} catch {
|
|
34172
|
+
return null;
|
|
34173
|
+
}
|
|
34174
|
+
}
|
|
34175
|
+
var hasAdapter2 = (ip) => Object.values(os14.networkInterfaces()).some((list) => (list ?? []).some((i) => i.address === ip));
|
|
34176
|
+
async function setupVpn(secrets, ptyHostExe) {
|
|
34177
|
+
const vpn = session.vpn;
|
|
34178
|
+
if (!vpn) return true;
|
|
34179
|
+
const killSwitch = vpn.killSwitch;
|
|
34180
|
+
let blocked = false;
|
|
34181
|
+
const block = (servers) => {
|
|
34182
|
+
if (isWin && !dryRun) run2(killSwitchCommands(servers, ptyHostExe));
|
|
34183
|
+
blocked = true;
|
|
34184
|
+
log("VPN: kill switch on: nothing leaves the sandbox except through the tunnel.");
|
|
34185
|
+
};
|
|
34186
|
+
setVpnStatus("starting", "Starting the VPN");
|
|
34187
|
+
try {
|
|
34188
|
+
if (!session.networking) throw new Error("networking is off for this sandbox");
|
|
34189
|
+
let result;
|
|
34190
|
+
let wireguardExe2 = null;
|
|
34191
|
+
if (vpn.provider === "wireguard-file") {
|
|
34192
|
+
if (!secrets.wireguardConfig) throw new Error("the WireGuard config did not arrive (start the sandbox again)");
|
|
34193
|
+
const config2 = assertSafeWireguard(secrets.wireguardConfig, vpn.server);
|
|
34194
|
+
const exe = await ensureWireguard();
|
|
34195
|
+
const { servers, text } = await wireguardServers(config2);
|
|
34196
|
+
if (killSwitch && !routesEverything(config2))
|
|
34197
|
+
warn(
|
|
34198
|
+
"VPN: AllowedIPs does not include 0.0.0.0/0: with the kill switch on, only the tunnel traffic can leave the sandbox."
|
|
34199
|
+
);
|
|
34200
|
+
if (killSwitch) block(servers);
|
|
34201
|
+
if (dryRun || !isWin) {
|
|
34202
|
+
log("(dry run) would start the WireGuard tunnel " + vpn.server);
|
|
34203
|
+
setVpnStatus("off", "dry run");
|
|
34204
|
+
return true;
|
|
34205
|
+
}
|
|
34206
|
+
log("VPN: connecting with " + vpn.server);
|
|
34207
|
+
wireguardExe2 = exe;
|
|
34208
|
+
result = await startWireguardTunnel({ exe, config: text, tunnelIp: wireguardTunnelAddress(config2) });
|
|
34209
|
+
if (result.ok && result.tunnelIp && killSwitch) run2(tunnelCommands(result.tunnelIp));
|
|
34210
|
+
if (result.ok) result = await waitForHandshake(exe, publicAddress);
|
|
34211
|
+
} else {
|
|
34212
|
+
const credentials = secrets.vpn;
|
|
34213
|
+
if (!credentials) throw new Error("the VPN login did not arrive (start the sandbox again)");
|
|
34214
|
+
const profile = path71.join(launchDir, "vpn", "server.ovpn");
|
|
34215
|
+
const remotes = assertSafeOvpn(fs57.readFileSync(profile, "utf8"), vpn.server);
|
|
34216
|
+
const exe = await ensureOpenVpn();
|
|
34217
|
+
const servers = await serverAddresses(remotes);
|
|
34218
|
+
if (servers.length === 0) throw new Error("the VPN server addresses could not be found");
|
|
34219
|
+
if (killSwitch) block(servers);
|
|
34220
|
+
if (dryRun || !isWin) {
|
|
34221
|
+
log("(dry run) would start the VPN tunnel to " + vpn.server);
|
|
34222
|
+
setVpnStatus("off", "dry run");
|
|
34223
|
+
return true;
|
|
34224
|
+
}
|
|
34225
|
+
log("VPN: connecting to " + vpn.server);
|
|
34226
|
+
result = await startTunnel({ exe, profile, username: credentials.username, password: credentials.password });
|
|
34227
|
+
if (result.ok && result.tunnelIp && hasAdapter2(result.tunnelIp) && killSwitch)
|
|
34228
|
+
run2(tunnelCommands(result.tunnelIp));
|
|
34229
|
+
}
|
|
34230
|
+
if (!result.ok) {
|
|
34231
|
+
if (wireguardExe2) await removeWireguardTunnel(wireguardExe2);
|
|
34232
|
+
throw new Error(result.message);
|
|
34233
|
+
}
|
|
34234
|
+
if (!result.tunnelIp || !hasAdapter2(result.tunnelIp))
|
|
34235
|
+
throw new Error("the tunnel reported it was up, but no network adapter with its address appeared");
|
|
34236
|
+
const publicIp = await publicAddress();
|
|
34237
|
+
log("VPN: up" + (publicIp ? " (the sandbox appears as " + publicIp + ")" : "") + ".");
|
|
34238
|
+
setVpnStatus("up", "The tunnel is up", publicIp ? { publicIp } : {});
|
|
34239
|
+
return true;
|
|
34240
|
+
} catch (e) {
|
|
34241
|
+
const reason = errMsg(e);
|
|
34242
|
+
try {
|
|
34243
|
+
if (killSwitch && !blocked) block([]);
|
|
34244
|
+
} catch (blockError) {
|
|
34245
|
+
warn("VPN: could not close the network after the failure: " + errMsg(blockError));
|
|
34246
|
+
}
|
|
34247
|
+
const text = "VPN failed: " + reason + (killSwitch ? " The kill switch is on, so this sandbox has NO internet access." : " The kill switch is off, so this sandbox is using your normal connection.");
|
|
34248
|
+
warn(text);
|
|
34249
|
+
setVpnStatus("failed", reason);
|
|
34250
|
+
return false;
|
|
34251
|
+
}
|
|
34252
|
+
}
|
|
34253
|
+
|
|
33057
34254
|
// src/shared/pty/protocol.ts
|
|
33058
34255
|
var FrameType = {
|
|
33059
34256
|
Hello: 1,
|
|
@@ -33106,10 +34303,10 @@ var FrameReader = class {
|
|
|
33106
34303
|
};
|
|
33107
34304
|
|
|
33108
34305
|
// src/shared/pty/client.ts
|
|
33109
|
-
import
|
|
34306
|
+
import net3 from "node:net";
|
|
33110
34307
|
var connectOnce = (host, port, timeoutMs) => {
|
|
33111
34308
|
return new Promise((resolve2, reject) => {
|
|
33112
|
-
const socket =
|
|
34309
|
+
const socket = net3.connect({ host, port });
|
|
33113
34310
|
const timer = setTimeout(() => {
|
|
33114
34311
|
socket.destroy();
|
|
33115
34312
|
reject(new Error("timed out connecting to " + host + ":" + port));
|
|
@@ -33145,7 +34342,14 @@ var KEPT_OSC = (body) => {
|
|
|
33145
34342
|
return n <= 2 || n === 8 || n === 133 || n === 9 && body.startsWith(number4[1] + ";4;");
|
|
33146
34343
|
};
|
|
33147
34344
|
var MAX_KEPT_STRING = 4096;
|
|
34345
|
+
var MAX_CLIPBOARD_STRING = 1024 * 1024;
|
|
34346
|
+
var CLIPBOARD_WRITE = /^0{0,2}52;[cpqs0-7]{0,8};[A-Za-z0-9+/=]*$/;
|
|
33148
34347
|
var OutputFilter = class {
|
|
34348
|
+
constructor(options = {}) {
|
|
34349
|
+
this.options = options;
|
|
34350
|
+
this.maxString = options.clipboardWrites ? MAX_CLIPBOARD_STRING : MAX_KEPT_STRING;
|
|
34351
|
+
}
|
|
34352
|
+
options;
|
|
33149
34353
|
/**
|
|
33150
34354
|
* text: normal output; esc: after ESC; c2: after a 0xC2 lead byte; string: inside an OSC/DCS/...; stringEsc /
|
|
33151
34355
|
* stringC2: a possible terminator inside one.
|
|
@@ -33153,8 +34357,14 @@ var OutputFilter = class {
|
|
|
33153
34357
|
state = "text";
|
|
33154
34358
|
/** The string being read: an OSC worth keeping is collected until its terminator; null = being dropped. */
|
|
33155
34359
|
body = null;
|
|
34360
|
+
maxString;
|
|
34361
|
+
/** An OSC that may pass: a short title, link, progress or mark, or (when allowed) a clipboard write. */
|
|
34362
|
+
kept(body) {
|
|
34363
|
+
if (this.options.clipboardWrites && CLIPBOARD_WRITE.test(body)) return true;
|
|
34364
|
+
return body.length <= MAX_KEPT_STRING && KEPT_OSC(body);
|
|
34365
|
+
}
|
|
33156
34366
|
push(chunk) {
|
|
33157
|
-
const out = Buffer.allocUnsafe(chunk.length +
|
|
34367
|
+
const out = Buffer.allocUnsafe(chunk.length + (this.body?.length ?? 0) + 8);
|
|
33158
34368
|
let n = 0;
|
|
33159
34369
|
const put = (...bytes) => {
|
|
33160
34370
|
for (const b of bytes) out[n++] = b;
|
|
@@ -33174,7 +34384,7 @@ var OutputFilter = class {
|
|
|
33174
34384
|
};
|
|
33175
34385
|
const endString = (terminator) => {
|
|
33176
34386
|
const body = this.body && Buffer.from(this.body).toString("latin1");
|
|
33177
|
-
if (body !== null &&
|
|
34387
|
+
if (body !== null && this.kept(body)) {
|
|
33178
34388
|
put(27, 93);
|
|
33179
34389
|
out.write(body, n, "latin1");
|
|
33180
34390
|
n += body.length;
|
|
@@ -33184,7 +34394,7 @@ var OutputFilter = class {
|
|
|
33184
34394
|
this.state = "text";
|
|
33185
34395
|
};
|
|
33186
34396
|
const collect = (b) => {
|
|
33187
|
-
if (this.body && this.body.push(b) >
|
|
34397
|
+
if (this.body && this.body.push(b) > this.maxString) this.body = null;
|
|
33188
34398
|
};
|
|
33189
34399
|
for (const b of chunk) {
|
|
33190
34400
|
switch (this.state) {
|
|
@@ -33250,7 +34460,7 @@ var OutputFilter = class {
|
|
|
33250
34460
|
};
|
|
33251
34461
|
|
|
33252
34462
|
// src/shared/pty/console-input.ts
|
|
33253
|
-
import { spawn as
|
|
34463
|
+
import { spawn as spawn8 } from "node:child_process";
|
|
33254
34464
|
function enableVtInput() {
|
|
33255
34465
|
if (process.platform !== "win32" || !process.stdin.isTTY)
|
|
33256
34466
|
return { ready: Promise.resolve(false), stop: () => Promise.resolve() };
|
|
@@ -33258,7 +34468,7 @@ function enableVtInput() {
|
|
|
33258
34468
|
let exited = Promise.resolve();
|
|
33259
34469
|
const ready = new Promise((resolve2) => {
|
|
33260
34470
|
try {
|
|
33261
|
-
child =
|
|
34471
|
+
child = spawn8(SYSTEM.powershell(), scriptArgs("enable-vt-input.ps1", ["-ProcessId", String(process.pid)]), {
|
|
33262
34472
|
stdio: "ignore",
|
|
33263
34473
|
windowsHide: true
|
|
33264
34474
|
});
|
|
@@ -33334,7 +34544,7 @@ function runTerminalClient(socket, token, options = {}) {
|
|
|
33334
34544
|
return new Promise((resolve2) => {
|
|
33335
34545
|
let done = false;
|
|
33336
34546
|
const reader = new FrameReader();
|
|
33337
|
-
const filter = new OutputFilter();
|
|
34547
|
+
const filter = new OutputFilter({ clipboardWrites: options.clipboardWrites });
|
|
33338
34548
|
let sent = size();
|
|
33339
34549
|
let resizeTimer;
|
|
33340
34550
|
let vtInput;
|
|
@@ -33451,14 +34661,14 @@ async function viewSession(id) {
|
|
|
33451
34661
|
return 1;
|
|
33452
34662
|
}
|
|
33453
34663
|
const socket = await connect({ ...session2.attach, addresses: ["127.0.0.1"] });
|
|
33454
|
-
const result = await runTerminalClient(socket, session2.attach.token);
|
|
34664
|
+
const result = await runTerminalClient(socket, session2.attach.token, { clipboardWrites: true });
|
|
33455
34665
|
if (result.reason === "exit") console.log(session2.harness + " exited with code " + result.exitCode + ".");
|
|
33456
34666
|
else if (result.reason === "error") console.log("Session error: " + result.message);
|
|
33457
34667
|
return result.reason === "exit" ? result.exitCode : 1;
|
|
33458
34668
|
}
|
|
33459
34669
|
|
|
33460
34670
|
// src/guest/boot/boot-env.ts
|
|
33461
|
-
import
|
|
34671
|
+
import path72 from "node:path";
|
|
33462
34672
|
|
|
33463
34673
|
// src/guest/boot/project-env.ts
|
|
33464
34674
|
var EnvSchema = external_exports.object({
|
|
@@ -33477,7 +34687,7 @@ var BootEnvSchema = external_exports.object({
|
|
|
33477
34687
|
});
|
|
33478
34688
|
|
|
33479
34689
|
// src/guest/boot/boot-env.ts
|
|
33480
|
-
var file2 = () =>
|
|
34690
|
+
var file2 = () => path72.join(localDir, "boot-env.json");
|
|
33481
34691
|
function saveBootEnv(value) {
|
|
33482
34692
|
try {
|
|
33483
34693
|
writeJsonAtomic(file2(), value);
|
|
@@ -33505,8 +34715,54 @@ function saveProjectStatus(name, workspace2, phase, message, databases, summary)
|
|
|
33505
34715
|
}
|
|
33506
34716
|
}
|
|
33507
34717
|
|
|
34718
|
+
// src/guest/runtime/secrets.ts
|
|
34719
|
+
import fs58 from "node:fs";
|
|
34720
|
+
|
|
34721
|
+
// src/shared/channel/secrets.ts
|
|
34722
|
+
var Environment = external_exports.record(external_exports.string().max(256), external_exports.string().max(65536));
|
|
34723
|
+
var SecretsFileSchema = external_exports.strictObject({
|
|
34724
|
+
/** The agent the sandbox booted with: its harness environment. */
|
|
34725
|
+
harnessEnvironment: Environment.optional(),
|
|
34726
|
+
/** harnessSpec of a session request (an agent the sandbox did not boot with). */
|
|
34727
|
+
harnessSpecEnvironment: Environment.optional(),
|
|
34728
|
+
/** project.harnesses of a request, by agent name. */
|
|
34729
|
+
projectHarnessEnvironment: external_exports.record(external_exports.string().max(64), Environment).optional(),
|
|
34730
|
+
/** The login of this PC's Claude (claudeProfile.copyCredentials): the text of .credentials.json. */
|
|
34731
|
+
claudeCredentials: external_exports.string().max(1024 * 1024).optional(),
|
|
34732
|
+
/** VPN service credentials (vpn.provider's login), only for the launch's own sandbox. */
|
|
34733
|
+
vpn: external_exports.strictObject({ username: external_exports.string().min(1).max(256), password: external_exports.string().min(1).max(1024) }).optional(),
|
|
34734
|
+
/** The checked WireGuard config of vpn.provider wireguard-file (holds the private key). */
|
|
34735
|
+
wireguardConfig: external_exports.string().min(1).max(32 * 1024).optional()
|
|
34736
|
+
});
|
|
34737
|
+
|
|
34738
|
+
// src/guest/runtime/secrets.ts
|
|
34739
|
+
var BOOT_SECRETS_VARIABLE = "SBX_BOOT_SECRETS";
|
|
34740
|
+
var MAX_BYTES = 4 * 1024 * 1024;
|
|
34741
|
+
function takeSecrets(id) {
|
|
34742
|
+
const file3 = run.secretFile(id);
|
|
34743
|
+
let text;
|
|
34744
|
+
try {
|
|
34745
|
+
if (fs58.statSync(file3).size > MAX_BYTES) throw new Error("too big");
|
|
34746
|
+
text = fs58.readFileSync(file3, "utf8").replace(/^\uFEFF/, "");
|
|
34747
|
+
} catch {
|
|
34748
|
+
return {};
|
|
34749
|
+
} finally {
|
|
34750
|
+
fs58.rmSync(file3, { force: true });
|
|
34751
|
+
}
|
|
34752
|
+
try {
|
|
34753
|
+
const parsed = SecretsFileSchema.safeParse(JSON.parse(text));
|
|
34754
|
+
if (parsed.success) return parsed.data;
|
|
34755
|
+
} catch {
|
|
34756
|
+
}
|
|
34757
|
+
warn("The secrets file for " + id + " was not valid and was ignored.");
|
|
34758
|
+
return {};
|
|
34759
|
+
}
|
|
34760
|
+
function applyBootEnvironment(environment) {
|
|
34761
|
+
if (session.harness && environment) session.harness.environment = { ...environment };
|
|
34762
|
+
}
|
|
34763
|
+
|
|
33508
34764
|
// src/guest/boot/boot.ts
|
|
33509
|
-
var STEPS =
|
|
34765
|
+
var STEPS = 9;
|
|
33510
34766
|
var PRIMARY_POLLS = 600;
|
|
33511
34767
|
var POLL_MS = 500;
|
|
33512
34768
|
var VSCODE_LANGUAGES = ["python", "java", "go", "rust", "cpp", "msvc", "dotnet", "ruby", "php", "deno", "pwsh"];
|
|
@@ -33528,23 +34784,35 @@ async function soft(what, work) {
|
|
|
33528
34784
|
warn(what + " failed (continuing): " + errMsg(e));
|
|
33529
34785
|
}
|
|
33530
34786
|
}
|
|
33531
|
-
function startDaemon(env) {
|
|
33532
|
-
|
|
34787
|
+
function startDaemon(env, secrets) {
|
|
34788
|
+
spawn9(process.execPath, [path73.join(path73.dirname(process.argv[1]), "daemon.js")], {
|
|
33533
34789
|
detached: true,
|
|
33534
34790
|
stdio: "ignore",
|
|
33535
34791
|
windowsHide: true,
|
|
33536
|
-
env: {
|
|
34792
|
+
env: {
|
|
34793
|
+
...env,
|
|
34794
|
+
AGENT_LOG_PREFIX: "daemon",
|
|
34795
|
+
// The agent's environment (it may hold API keys): the daemon moves it into memory and removes this at once.
|
|
34796
|
+
...secrets.harnessEnvironment ? { [BOOT_SECRETS_VARIABLE]: JSON.stringify({ harnessEnvironment: secrets.harnessEnvironment }) } : {}
|
|
34797
|
+
}
|
|
33537
34798
|
}).unref();
|
|
33538
34799
|
}
|
|
33539
34800
|
function writeDbCommand() {
|
|
33540
|
-
const dir = mkdirp(
|
|
33541
|
-
const db =
|
|
33542
|
-
|
|
33543
|
-
|
|
34801
|
+
const dir = mkdirp(path73.join(localDir, "bin"));
|
|
34802
|
+
const db = path73.join(path73.dirname(process.argv[1]), "db.js");
|
|
34803
|
+
fs59.writeFileSync(
|
|
34804
|
+
path73.join(dir, "sbx-db.cmd"),
|
|
33544
34805
|
'@setlocal\r\n@set AGENT_LOG_PREFIX=db\r\n@"' + process.execPath + '" "' + db + '" %*\r\n'
|
|
33545
34806
|
);
|
|
34807
|
+
writeAgentCommands(dir);
|
|
33546
34808
|
return dir;
|
|
33547
34809
|
}
|
|
34810
|
+
function writeAgentCommands(dir) {
|
|
34811
|
+
const install = { node: process.execPath, script: path73.join(path73.dirname(process.argv[1]), "agent.js") };
|
|
34812
|
+
for (const shim3 of agentShims(toolsDir, session.agents ?? {}))
|
|
34813
|
+
fs59.writeFileSync(path73.join(dir, shim3.command + ".cmd"), shimText(shim3, install));
|
|
34814
|
+
fs59.writeFileSync(path73.join(dir, "sbx-agent.cmd"), sbxAgentText(install));
|
|
34815
|
+
}
|
|
33548
34816
|
async function waitForPrimary() {
|
|
33549
34817
|
for (let i = 0; i < PRIMARY_POLLS; i++) {
|
|
33550
34818
|
const s = run.readSession(session.launchId);
|
|
@@ -33565,17 +34833,22 @@ var Boot = class {
|
|
|
33565
34833
|
ptyHost = null;
|
|
33566
34834
|
lan = session.networking ? "open" : "offline";
|
|
33567
34835
|
gitAccess = session.provisioning.git.access ?? "full";
|
|
34836
|
+
/** What the host handed over in its one-shot file (read and deleted at the start of run()). */
|
|
34837
|
+
secrets = {};
|
|
33568
34838
|
async run() {
|
|
33569
34839
|
log(
|
|
33570
34840
|
"Agent sandbox: " + session.project + " | workspace " + workspace + " | agent " + session.harnessName + " | log " + logPath
|
|
33571
34841
|
);
|
|
33572
|
-
if (!
|
|
34842
|
+
if (!fs59.statSync(workspace, { throwIfNoEntry: false })?.isDirectory())
|
|
33573
34843
|
throw new Error("Workspace folder is missing in the sandbox: " + workspace);
|
|
33574
34844
|
mkdirp(toolsDir);
|
|
33575
34845
|
mkdirp(run.root);
|
|
34846
|
+
this.secrets = takeSecrets(session.launchId);
|
|
34847
|
+
applyBootEnvironment(this.secrets.harnessEnvironment);
|
|
33576
34848
|
await this.networkAndSessionHost();
|
|
33577
34849
|
await this.hooksAndDesktop();
|
|
33578
34850
|
const { tools, env } = await this.developerTools();
|
|
34851
|
+
await this.vpn();
|
|
33579
34852
|
await this.gitIdentity(env);
|
|
33580
34853
|
await this.claude(tools);
|
|
33581
34854
|
await this.agent(env);
|
|
@@ -33629,6 +34902,7 @@ var Boot = class {
|
|
|
33629
34902
|
);
|
|
33630
34903
|
const env = agentEnv(tools);
|
|
33631
34904
|
persistEnvironment(env, Object.keys(tools.vars));
|
|
34905
|
+
await soft("Shell start-up PATH", installShellPath);
|
|
33632
34906
|
saveBootEnv({
|
|
33633
34907
|
basePath,
|
|
33634
34908
|
toolVars: Object.keys(tools.vars),
|
|
@@ -33641,32 +34915,43 @@ var Boot = class {
|
|
|
33641
34915
|
await soft("Cleaning old tool builds", () => pruneToolLeftovers());
|
|
33642
34916
|
return { tools, env };
|
|
33643
34917
|
}
|
|
34918
|
+
/** vpn.enabled: the tunnel and its kill switch, before anything else uses the network (git, the agent). */
|
|
34919
|
+
async vpn() {
|
|
34920
|
+
step(4, session.vpn ? "VPN (" + session.vpn.server + ")" : "VPN (off)");
|
|
34921
|
+
if (!session.vpn) return;
|
|
34922
|
+
await soft("VPN", async () => {
|
|
34923
|
+
await setupVpn(this.secrets, this.ptyHost);
|
|
34924
|
+
});
|
|
34925
|
+
}
|
|
33644
34926
|
async gitIdentity(env) {
|
|
33645
|
-
step(
|
|
34927
|
+
step(5, "Git identity");
|
|
33646
34928
|
await soft("Git config", () => setupGitConfig(env));
|
|
33647
34929
|
}
|
|
33648
34930
|
async claude(tools) {
|
|
33649
|
-
step(
|
|
33650
|
-
if (session.harnessName === "claude")
|
|
34931
|
+
step(6, "Claude settings, history and claude-mem");
|
|
34932
|
+
if (session.harnessName === "claude")
|
|
34933
|
+
await soft("Claude settings", () => syncClaudeProfile(this.secrets.claudeCredentials));
|
|
33651
34934
|
await soft("claude-mem restore", restoreClaudeMem);
|
|
34935
|
+
await soft("Agent files of the last sandbox", resetMachineBound);
|
|
34936
|
+
await soft("Agent databases restore", restoreLocalState);
|
|
33652
34937
|
await soft("Sandbox guide for the agent", () => writeGuides(tools.summary, this.lan));
|
|
33653
34938
|
await soft("Claude managed settings", () => writeManagedSettings2(this.gitAccess));
|
|
33654
34939
|
}
|
|
33655
34940
|
async agent(env) {
|
|
33656
|
-
step(
|
|
34941
|
+
step(7, "Agent: " + session.harnessName);
|
|
33657
34942
|
linkProfileDirs(session.agentProfileDirs ?? {});
|
|
33658
34943
|
if (session.harness) await agents.provision(session.harnessName, session.harness, env);
|
|
33659
34944
|
}
|
|
33660
34945
|
preAgentHooks(env) {
|
|
33661
|
-
step(
|
|
34946
|
+
step(8, "Pre-agent hooks");
|
|
33662
34947
|
runHooks("pre-agent", env);
|
|
33663
34948
|
}
|
|
33664
34949
|
/** Ready: starts the session daemon and, with an agent, its first session, shown in this window. */
|
|
33665
34950
|
async start(env) {
|
|
33666
|
-
step(
|
|
34951
|
+
step(9, "Starting " + session.harnessName);
|
|
33667
34952
|
setSandboxStatus("ready", "Ready");
|
|
33668
34953
|
if (!session.harness || session.autoSession === false) {
|
|
33669
|
-
if (!dryRun) startDaemon(env);
|
|
34954
|
+
if (!dryRun) startDaemon(env, this.secrets);
|
|
33670
34955
|
log("Ready" + (session.harness ? "" : " (no agent requested)") + ". Workspace: " + workspace);
|
|
33671
34956
|
return;
|
|
33672
34957
|
}
|
|
@@ -33678,7 +34963,7 @@ var Boot = class {
|
|
|
33678
34963
|
runHooks("post-agent", env);
|
|
33679
34964
|
return;
|
|
33680
34965
|
}
|
|
33681
|
-
startDaemon(env);
|
|
34966
|
+
startDaemon(env, this.secrets);
|
|
33682
34967
|
writeJsonAtomic(run.requestFile(session.launchId), {
|
|
33683
34968
|
kind: "session",
|
|
33684
34969
|
id: session.launchId,
|
|
@@ -33702,11 +34987,11 @@ runBoot().catch((e) => {
|
|
|
33702
34987
|
const message = errMsg(e) + (e instanceof Error && e.stack ? "\n" + e.stack : "");
|
|
33703
34988
|
try {
|
|
33704
34989
|
setSandboxStatus("failed", errMsg(e));
|
|
33705
|
-
|
|
34990
|
+
fs60.writeFileSync(path74.join(logsDir, "guest-error.txt"), message);
|
|
33706
34991
|
} catch {
|
|
33707
34992
|
}
|
|
33708
34993
|
console.error(
|
|
33709
|
-
"\n\x1B[31mThe sandbox could not start: " + errMsg(e) + "\x1B[0m\nDetails: " +
|
|
34994
|
+
"\n\x1B[31mThe sandbox could not start: " + errMsg(e) + "\x1B[0m\nDetails: " + path74.join(logsDir, "guest-error.txt")
|
|
33710
34995
|
);
|
|
33711
34996
|
process.exitCode = 1;
|
|
33712
34997
|
});
|