windows-development-sandbox 1.0.5 → 1.4.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/LICENSE +21 -0
- package/README.md +25 -8
- package/config.example.json +55 -5
- package/dist/api.js +2 -1
- package/dist/cli/args.d.ts +23 -0
- package/dist/cli/args.js +38 -4
- package/dist/cli/colors.d.ts +24 -0
- package/dist/cli/colors.js +42 -0
- package/dist/cli/commands/accounts.js +2 -2
- package/dist/cli/commands/agent-commands.d.ts +6 -0
- package/dist/cli/commands/agent-commands.js +61 -0
- package/dist/cli/commands/context.d.ts +2 -0
- package/dist/cli/commands/context.js +5 -1
- package/dist/cli/commands/data/clean.d.ts +15 -0
- package/dist/cli/commands/data/clean.js +106 -0
- package/dist/cli/commands/data/collect.d.ts +11 -0
- package/dist/cli/commands/data/collect.js +54 -0
- package/dist/cli/commands/data/index.d.ts +4 -0
- package/dist/cli/commands/data/index.js +45 -0
- package/dist/cli/commands/data/remove.d.ts +2 -0
- package/dist/cli/commands/data/remove.js +30 -0
- package/dist/cli/commands/index.d.ts +6 -4
- package/dist/cli/commands/index.js +6 -4
- package/dist/cli/commands/launch.d.ts +26 -2
- package/dist/cli/commands/launch.js +256 -42
- package/dist/cli/commands/maintenance.d.ts +2 -0
- package/dist/cli/commands/maintenance.js +67 -5
- package/dist/cli/commands/project.d.ts +29 -0
- package/dist/cli/commands/project.js +63 -0
- package/dist/cli/commands/projects.d.ts +14 -0
- package/dist/cli/commands/projects.js +146 -0
- package/dist/cli/commands/repair/checks.d.ts +2 -0
- package/dist/cli/commands/{repair.js → repair/checks.js} +19 -181
- package/dist/cli/commands/{repair.d.ts → repair/finders.d.ts} +0 -29
- package/dist/cli/commands/repair/finders.js +108 -0
- package/dist/cli/commands/repair/index.d.ts +12 -0
- package/dist/cli/commands/repair/index.js +61 -0
- package/dist/cli/commands/repair/types.d.ts +26 -0
- package/dist/cli/commands/repair/types.js +3 -0
- package/dist/cli/commands/restart.d.ts +6 -0
- package/dist/cli/commands/restart.js +85 -0
- package/dist/cli/commands/sessions.d.ts +2 -1
- package/dist/cli/commands/sessions.js +189 -45
- package/dist/cli/commands/setup/checks.d.ts +13 -0
- package/dist/cli/commands/setup/checks.js +71 -0
- package/dist/cli/commands/{setup.d.ts → setup/facts.d.ts} +1 -15
- package/dist/cli/commands/setup/facts.js +60 -0
- package/dist/cli/commands/setup/index.d.ts +2 -0
- package/dist/cli/commands/setup/index.js +43 -0
- package/dist/cli/commands/user-config.d.ts +8 -0
- package/dist/cli/commands/user-config.js +41 -0
- package/dist/cli/history.d.ts +11 -0
- package/dist/cli/history.js +21 -0
- package/dist/cli/index.d.ts +7 -1
- package/dist/cli/index.js +42 -15
- package/dist/cli/manifest.d.ts +8 -0
- package/dist/cli/manifest.js +40 -15
- package/dist/cli/menu/apps.d.ts +21 -0
- package/dist/cli/menu/apps.js +122 -0
- package/dist/cli/menu/command-form.d.ts +28 -0
- package/dist/cli/menu/command-form.js +219 -0
- package/dist/cli/menu/index.d.ts +26 -0
- package/dist/cli/menu/index.js +180 -0
- package/dist/cli/menu/settings/categories.d.ts +9 -0
- package/dist/cli/menu/settings/categories.js +28 -0
- package/dist/cli/menu/settings/config-file.d.ts +40 -0
- package/dist/cli/menu/settings/config-file.js +71 -0
- package/dist/cli/menu/settings/editors.d.ts +30 -0
- package/dist/cli/menu/settings/editors.js +305 -0
- package/dist/cli/menu/settings/index.d.ts +32 -0
- package/dist/cli/menu/settings/index.js +136 -0
- package/dist/cli/menu/settings/schema-node.d.ts +62 -0
- package/dist/cli/menu/settings/schema-node.js +104 -0
- package/dist/cli/menu/several.d.ts +20 -0
- package/dist/cli/menu/several.js +102 -0
- package/dist/cli/progress.d.ts +9 -0
- package/dist/cli/progress.js +49 -0
- package/dist/cli/tui/app.d.ts +39 -0
- package/dist/cli/tui/app.js +52 -0
- package/dist/cli/tui/dialogs.d.ts +57 -0
- package/dist/cli/tui/dialogs.js +162 -0
- package/dist/cli/tui/frame.d.ts +18 -0
- package/dist/cli/tui/frame.js +27 -0
- package/dist/cli/tui/index.d.ts +7 -0
- package/dist/cli/tui/index.js +8 -0
- package/dist/cli/tui/list-screen.d.ts +101 -0
- package/dist/cli/tui/list-screen.js +299 -0
- package/dist/cli/tui/terminal.d.ts +37 -0
- package/dist/cli/tui/terminal.js +89 -0
- package/dist/cli/tui/text.d.ts +20 -0
- package/dist/cli/tui/text.js +105 -0
- package/dist/cli/tui/theme.d.ts +45 -0
- package/dist/cli/tui/theme.js +30 -0
- package/dist/cli/validate.d.ts +17 -0
- package/dist/cli/validate.js +89 -0
- package/dist/core/config.js +12 -6
- package/dist/core/disk.d.ts +16 -0
- package/dist/core/disk.js +55 -0
- package/dist/core/local-config.d.ts +23 -0
- package/dist/core/local-config.js +79 -7
- package/dist/core/project-policy.d.ts +15 -0
- package/dist/core/project-policy.js +35 -0
- package/dist/core/prompt.d.ts +4 -0
- package/dist/core/prompt.js +15 -0
- package/dist/core/safe-paths.d.ts +4 -0
- package/dist/core/safe-paths.js +37 -0
- package/dist/core/schema/apps.d.ts +40 -0
- package/dist/core/schema/apps.js +27 -0
- package/dist/core/schema/common.d.ts +17 -0
- package/dist/core/schema/common.js +15 -0
- package/dist/core/schema/config.d.ts +659 -0
- package/dist/core/schema/config.js +75 -0
- package/dist/core/schema/databases.d.ts +33 -0
- package/dist/core/schema/databases.js +35 -0
- package/dist/core/schema/harness.d.ts +12 -0
- package/dist/core/schema/harness.js +17 -0
- package/dist/core/schema/json-schema.d.ts +5 -0
- package/dist/core/schema/json-schema.js +25 -0
- package/dist/core/schema/profile.d.ts +32 -0
- package/dist/core/schema/profile.js +31 -0
- package/dist/core/schema/projects.d.ts +9 -0
- package/dist/core/schema/projects.js +11 -0
- package/dist/core/schema/sandbox.d.ts +78 -0
- package/dist/core/schema/sandbox.js +64 -0
- package/dist/core/schema/toolchains.d.ts +96 -0
- package/dist/core/schema/toolchains.js +88 -0
- package/dist/core/schema.d.ts +6 -604
- package/dist/core/schema.js +8 -264
- package/dist/core/types.d.ts +35 -1
- package/dist/core/util.d.ts +9 -0
- package/dist/core/util.js +14 -3
- package/dist/core/workspace.d.ts +0 -5
- package/dist/core/workspace.js +33 -50
- package/dist/guest/apps/index.d.ts +10 -0
- package/dist/guest/apps/index.js +206 -0
- package/dist/guest/apps/resolvers.d.ts +8 -0
- package/dist/guest/apps/resolvers.js +90 -0
- package/dist/guest/audit-parse.d.ts +7 -0
- package/dist/guest/audit-parse.js +24 -0
- package/dist/guest/audit.d.ts +4 -0
- package/dist/guest/audit.js +47 -0
- package/dist/guest/boot-env.d.ts +4 -0
- package/dist/guest/boot-env.js +25 -0
- package/dist/guest/cmdline.d.ts +12 -0
- package/dist/guest/cmdline.js +23 -0
- package/dist/guest/daemon/exec.d.ts +5 -0
- package/dist/guest/daemon/exec.js +32 -0
- package/dist/guest/daemon/project.d.ts +14 -0
- package/dist/guest/daemon/project.js +132 -0
- package/dist/guest/daemon/relays.d.ts +1 -0
- package/dist/guest/daemon/relays.js +18 -0
- package/dist/guest/daemon/session.d.ts +13 -0
- package/dist/guest/daemon/session.js +139 -0
- package/dist/guest/daemon/shutdown.d.ts +1 -0
- package/dist/guest/daemon/shutdown.js +21 -0
- package/dist/guest/daemon/state.d.ts +17 -0
- package/dist/guest/daemon/state.js +31 -0
- package/dist/guest/daemon.js +12 -141
- package/dist/guest/db.js +18 -3
- package/dist/guest/env.d.ts +3 -0
- package/dist/guest/env.js +7 -3
- package/dist/guest/guide.d.ts +6 -2
- package/dist/guest/guide.js +5 -4
- package/dist/guest/helpers.d.ts +3 -0
- package/dist/guest/helpers.js +26 -0
- package/dist/guest/main.js +31 -8
- package/dist/guest/netproxy.d.ts +1 -0
- package/dist/guest/netproxy.js +100 -0
- package/dist/guest/ports.d.ts +6 -0
- package/dist/guest/ports.js +22 -0
- package/dist/guest/project-context.d.ts +7 -0
- package/dist/guest/project-context.js +10 -0
- package/dist/guest/project-env.d.ts +20 -0
- package/dist/guest/project-env.js +20 -0
- package/dist/guest/project-status.d.ts +5 -0
- package/dist/guest/project-status.js +17 -0
- package/dist/guest/ptyhost.d.ts +0 -18
- package/dist/guest/ptyhost.js +17 -65
- package/dist/guest/setup/agents.d.ts +5 -2
- package/dist/guest/setup/agents.js +22 -8
- package/dist/guest/setup/claude.d.ts +0 -4
- package/dist/guest/setup/claude.js +59 -5
- package/dist/guest/setup/environment.d.ts +13 -3
- package/dist/guest/setup/environment.js +14 -10
- package/dist/guest/setup/hooks.d.ts +9 -1
- package/dist/guest/setup/hooks.js +28 -14
- package/dist/guest/setup/network.d.ts +9 -0
- package/dist/guest/setup/network.js +97 -4
- package/dist/guest/setup/user.js +4 -0
- package/dist/guest/toolchains/catalogue.d.ts +4 -0
- package/dist/guest/toolchains/catalogue.js +2 -2
- package/dist/guest/toolchains/cli.js +25 -17
- package/dist/guest/toolchains/common.d.ts +18 -1
- package/dist/guest/toolchains/common.js +34 -11
- package/dist/guest/toolchains/databases/dynamodb.d.ts +8 -0
- package/dist/guest/toolchains/databases/dynamodb.js +52 -0
- package/dist/guest/toolchains/{databases.d.ts → databases/index.d.ts} +2 -3
- package/dist/guest/toolchains/databases/index.js +62 -0
- package/dist/guest/toolchains/databases/mongodb.d.ts +3 -0
- package/dist/guest/toolchains/databases/mongodb.js +31 -0
- package/dist/guest/toolchains/databases/mysql.d.ts +3 -0
- package/dist/guest/toolchains/databases/mysql.js +38 -0
- package/dist/guest/toolchains/databases/postgres.d.ts +5 -0
- package/dist/guest/toolchains/databases/postgres.js +38 -0
- package/dist/guest/toolchains/databases/redis.d.ts +3 -0
- package/dist/guest/toolchains/databases/redis.js +16 -0
- package/dist/guest/toolchains/databases/server.d.ts +14 -0
- package/dist/guest/toolchains/databases/server.js +52 -0
- package/dist/guest/toolchains/git.js +25 -16
- package/dist/guest/toolchains/go.js +1 -1
- package/dist/guest/toolchains/index.d.ts +13 -9
- package/dist/guest/toolchains/index.js +40 -82
- package/dist/guest/toolchains/java.js +5 -5
- package/dist/guest/toolchains/leftovers.d.ts +2 -0
- package/dist/guest/toolchains/leftovers.js +26 -0
- package/dist/guest/toolchains/managers.js +12 -10
- package/dist/guest/toolchains/{binstall.js → native/binstall.js} +6 -9
- package/dist/guest/toolchains/native/cpp.d.ts +4 -0
- package/dist/guest/toolchains/native/cpp.js +38 -0
- package/dist/guest/toolchains/native/dotnet.d.ts +4 -0
- package/dist/guest/toolchains/native/dotnet.js +103 -0
- package/dist/guest/toolchains/native/mesa.d.ts +7 -0
- package/dist/guest/toolchains/native/mesa.js +56 -0
- package/dist/guest/toolchains/native/msvc/environment.d.ts +16 -0
- package/dist/guest/toolchains/native/msvc/environment.js +57 -0
- package/dist/guest/toolchains/native/msvc/index.d.ts +6 -0
- package/dist/guest/toolchains/native/msvc/index.js +48 -0
- package/dist/guest/toolchains/native/msvc/packages.d.ts +6 -0
- package/dist/guest/toolchains/native/msvc/packages.js +156 -0
- package/dist/guest/toolchains/native/msvc/tree.d.ts +15 -0
- package/dist/guest/toolchains/native/msvc/tree.js +21 -0
- package/dist/guest/toolchains/native/rust.d.ts +3 -0
- package/dist/guest/toolchains/native/rust.js +45 -0
- package/dist/guest/toolchains/node.js +26 -6
- package/dist/guest/toolchains/plan.d.ts +24 -0
- package/dist/guest/toolchains/plan.js +140 -0
- package/dist/guest/toolchains/pwsh.js +1 -1
- package/dist/guest/toolchains/python.js +43 -12
- package/dist/guest/toolchains/runtimes.d.ts +2 -0
- package/dist/guest/toolchains/runtimes.js +6 -8
- package/dist/guest/toolchains/scripting/php.d.ts +3 -0
- package/dist/guest/toolchains/scripting/php.js +71 -0
- package/dist/guest/toolchains/scripting/ruby.d.ts +3 -0
- package/dist/guest/toolchains/scripting/ruby.js +47 -0
- package/dist/guest/toolchains/scripting/vcruntime.d.ts +7 -0
- package/dist/guest/toolchains/scripting/vcruntime.js +45 -0
- package/dist/guest/toolchains/vscode-profile.d.ts +30 -0
- package/dist/guest/toolchains/vscode-profile.js +69 -0
- package/dist/guest/toolchains/vscode.d.ts +17 -0
- package/dist/guest/toolchains/vscode.js +87 -1
- package/dist/guest/view.js +21 -1
- package/dist/host/accounts.js +14 -5
- package/dist/host/agent-commands.d.ts +25 -0
- package/dist/host/agent-commands.js +145 -0
- package/dist/host/attach.d.ts +17 -0
- package/dist/host/attach.js +70 -0
- package/dist/host/audit/collect.d.ts +34 -0
- package/dist/host/audit/collect.js +126 -0
- package/dist/host/audit/log.d.ts +46 -0
- package/dist/host/audit/log.js +143 -0
- package/dist/host/channel.d.ts +23 -22
- package/dist/host/channel.js +66 -84
- package/dist/host/claude-profile.js +7 -3
- package/dist/host/cleanup.js +2 -11
- package/dist/host/database-plan.d.ts +12 -0
- package/dist/host/database-plan.js +52 -0
- package/dist/host/generate.d.ts +10 -12
- package/dist/host/generate.js +58 -135
- package/dist/host/join.d.ts +28 -0
- package/dist/host/join.js +76 -0
- package/dist/host/launch/mappings.d.ts +3 -0
- package/dist/host/launch/mappings.js +54 -0
- package/dist/host/launch/projects.d.ts +15 -0
- package/dist/host/launch/projects.js +56 -0
- package/dist/host/launch/stage.d.ts +11 -0
- package/dist/host/launch/stage.js +66 -0
- package/dist/host/launch/wsb.d.ts +10 -0
- package/dist/host/launch/wsb.js +34 -0
- package/dist/host/motw.d.ts +17 -0
- package/dist/host/motw.js +74 -0
- package/dist/host/pc-scan.d.ts +6 -0
- package/dist/host/pc-scan.js +37 -0
- package/dist/host/platform.d.ts +2 -0
- package/dist/host/platform.js +16 -1
- package/dist/host/port-forward.d.ts +8 -0
- package/dist/host/port-forward.js +37 -0
- package/dist/host/project-scan.d.ts +1 -17
- package/dist/host/project-scan.js +2 -86
- package/dist/host/projects.d.ts +100 -0
- package/dist/host/projects.js +147 -0
- package/dist/host/repo-guard.d.ts +25 -5
- package/dist/host/repo-guard.js +242 -23
- package/dist/host/stops.d.ts +67 -0
- package/dist/host/stops.js +126 -0
- package/dist/host/terminal.d.ts +8 -0
- package/dist/host/terminal.js +48 -1
- package/dist/host/test-guard.d.ts +6 -0
- package/dist/host/test-guard.js +15 -0
- package/dist/host/window.js +7 -3
- package/dist/host/workspace-view/index.d.ts +20 -0
- package/dist/host/workspace-view/index.js +53 -0
- package/dist/host/workspace-view/rules.d.ts +26 -0
- package/dist/host/workspace-view/rules.js +93 -0
- package/dist/host/workspace-view/view.d.ts +50 -0
- package/dist/host/workspace-view/view.js +281 -0
- package/dist/host/wsb.d.ts +37 -0
- package/dist/host/wsb.js +101 -0
- package/dist/runtime/daemon.js +11791 -2821
- package/dist/runtime/db.js +6585 -466
- package/dist/runtime/main.js +10238 -1724
- package/dist/runtime/netproxy.js +25936 -0
- package/dist/runtime/view.js +6183 -59
- package/dist/selftest/accounts.test.d.ts +2 -0
- package/dist/selftest/accounts.test.js +44 -0
- package/dist/selftest/agent-commands.test.d.ts +2 -0
- package/dist/selftest/agent-commands.test.js +47 -0
- package/dist/selftest/audit.test.d.ts +2 -0
- package/dist/selftest/audit.test.js +57 -0
- package/dist/selftest/channel.test.d.ts +2 -0
- package/dist/selftest/channel.test.js +44 -0
- package/dist/selftest/cli.test.d.ts +2 -2
- package/dist/selftest/cli.test.js +145 -27
- package/dist/selftest/cmdline.test.d.ts +2 -0
- package/dist/selftest/cmdline.test.js +45 -0
- package/dist/selftest/config.test.d.ts +2 -3
- package/dist/selftest/config.test.js +36 -72
- package/dist/selftest/data.test.d.ts +2 -2
- package/dist/selftest/data.test.js +77 -70
- package/dist/selftest/detect.test.d.ts +2 -2
- package/dist/selftest/detect.test.js +54 -38
- package/dist/selftest/fixtures.d.ts +89 -4
- package/dist/selftest/fixtures.js +43 -24
- package/dist/selftest/generate.test.d.ts +2 -0
- package/dist/selftest/generate.test.js +68 -0
- package/dist/selftest/git-access.test.d.ts +2 -0
- package/dist/selftest/git-access.test.js +26 -0
- package/dist/selftest/guest-boot.test.d.ts +2 -0
- package/dist/selftest/guest-boot.test.js +76 -0
- package/dist/selftest/harness.d.ts +44 -7
- package/dist/selftest/harness.js +62 -21
- package/dist/selftest/host-sim.test.d.ts +2 -0
- package/dist/selftest/host-sim.test.js +93 -0
- package/dist/selftest/hostile-input.test.d.ts +2 -0
- package/dist/selftest/hostile-input.test.js +54 -0
- package/dist/selftest/index.d.ts +8 -1
- package/dist/selftest/index.js +137 -35
- package/dist/selftest/links.test.d.ts +2 -0
- package/dist/selftest/links.test.js +50 -0
- package/dist/selftest/live-daemon.test.d.ts +2 -0
- package/dist/selftest/live-daemon.test.js +91 -0
- package/dist/selftest/live-git.test.d.ts +2 -0
- package/dist/selftest/live-git.test.js +60 -0
- package/dist/selftest/live-network.test.d.ts +2 -0
- package/dist/selftest/live-network.test.js +63 -0
- package/dist/selftest/live-projects.test.d.ts +2 -0
- package/dist/selftest/live-projects.test.js +127 -0
- package/dist/selftest/live.d.ts +65 -0
- package/dist/selftest/live.js +109 -0
- package/dist/selftest/local-config.test.d.ts +2 -0
- package/dist/selftest/local-config.test.js +120 -0
- package/dist/selftest/mirror.test.d.ts +2 -3
- package/dist/selftest/mirror.test.js +92 -65
- package/dist/selftest/network.test.d.ts +2 -0
- package/dist/selftest/network.test.js +40 -0
- package/dist/selftest/personalization.test.d.ts +2 -0
- package/dist/selftest/personalization.test.js +53 -0
- package/dist/selftest/projects.test.d.ts +2 -0
- package/dist/selftest/projects.test.js +254 -0
- package/dist/selftest/repair.test.d.ts +2 -0
- package/dist/selftest/repair.test.js +42 -0
- package/dist/selftest/repo-guard.test.d.ts +2 -0
- package/dist/selftest/repo-guard.test.js +121 -0
- package/dist/selftest/secrets.test.d.ts +2 -0
- package/dist/selftest/secrets.test.js +71 -0
- package/dist/selftest/setup.test.d.ts +2 -2
- package/dist/selftest/setup.test.js +45 -22
- package/dist/selftest/suite.d.ts +13 -0
- package/dist/selftest/suite.js +1 -0
- package/dist/selftest/sync.test.d.ts +2 -3
- package/dist/selftest/sync.test.js +130 -78
- package/dist/selftest/test-guard.test.d.ts +2 -0
- package/dist/selftest/test-guard.test.js +49 -0
- package/dist/selftest/toolchains.test.d.ts +2 -0
- package/dist/selftest/toolchains.test.js +133 -0
- package/dist/selftest/workspace-view.test.d.ts +2 -0
- package/dist/selftest/workspace-view.test.js +89 -0
- package/dist/selftest/workspace.test.d.ts +2 -0
- package/dist/selftest/workspace.test.js +53 -0
- package/dist/shared/apps.d.ts +49 -0
- package/dist/shared/apps.js +114 -0
- package/dist/shared/download.d.ts +3 -1
- package/dist/shared/download.js +19 -4
- package/dist/shared/netpolicy.d.ts +27 -0
- package/dist/shared/netpolicy.js +51 -0
- package/dist/shared/paths.d.ts +5 -0
- package/dist/shared/paths.js +6 -0
- package/dist/shared/projects.d.ts +53 -0
- package/dist/shared/projects.js +67 -0
- package/dist/shared/pty-client.d.ts +9 -4
- package/dist/shared/pty-client.js +139 -17
- package/dist/shared/rundir.d.ts +12 -1
- package/dist/shared/rundir.js +14 -4
- package/dist/shared/safe-remove.js +11 -0
- package/dist/shared/schema.d.ts +453 -0
- package/dist/shared/schema.js +43 -2
- package/dist/shared/system.d.ts +1 -0
- package/dist/shared/system.js +1 -0
- package/dist/shared/test-guard.d.ts +4 -0
- package/dist/shared/test-guard.js +37 -0
- package/dist/sync/claude-mem.js +6 -3
- package/dist/sync/history.d.ts +29 -12
- package/dist/sync/history.js +72 -25
- package/dist/sync/watcher.d.ts +8 -0
- package/dist/sync/watcher.js +99 -8
- package/package.json +7 -6
- package/sandbox/bootstrap.ps1 +258 -258
- package/sandbox/cargoshim.cs +56 -0
- package/sandbox/cpucap.cs +33 -0
- package/sandbox/cpucap.ps1 +20 -0
- package/sandbox/logon.cmd +24 -16
- package/sandbox/memlog.ps1 +34 -0
- package/sandbox/openssl.cs +42 -0
- package/sandbox/pagefile.cs +31 -0
- package/sandbox/pagefile.ps1 +21 -0
- package/sandbox/ptyhost.cs +120 -11
- package/sandbox/trust.cmd +35 -35
- package/schemas/config.schema.json +403 -3
- package/schemas/sandbox-config.schema.json +143 -13
- package/dist/cli/commands/data.d.ts +0 -46
- package/dist/cli/commands/data.js +0 -249
- package/dist/cli/commands/setup.js +0 -152
- package/dist/cli/menu.d.ts +0 -22
- package/dist/cli/menu.js +0 -187
- package/dist/cli/settings.d.ts +0 -11
- package/dist/cli/settings.js +0 -156
- package/dist/guest/toolchains/databases.js +0 -226
- package/dist/guest/toolchains/msvc.d.ts +0 -10
- package/dist/guest/toolchains/msvc.js +0 -216
- package/dist/guest/toolchains/native.d.ts +0 -12
- package/dist/guest/toolchains/native.js +0 -220
- package/dist/guest/toolchains/scripting.d.ts +0 -10
- package/dist/guest/toolchains/scripting.js +0 -137
- package/dist/selftest/guest.test.d.ts +0 -3
- package/dist/selftest/guest.test.js +0 -61
- package/dist/selftest/helpers.test.d.ts +0 -2
- package/dist/selftest/helpers.test.js +0 -125
- package/dist/selftest/host.test.d.ts +0 -2
- package/dist/selftest/host.test.js +0 -71
- package/dist/selftest/live.test.d.ts +0 -7
- package/dist/selftest/live.test.js +0 -127
- package/dist/selftest/security.test.d.ts +0 -3
- package/dist/selftest/security.test.js +0 -143
- /package/dist/guest/toolchains/{binstall.d.ts → native/binstall.d.ts} +0 -0
|
@@ -1,74 +1,38 @@
|
|
|
1
|
-
//
|
|
2
|
-
import fs from 'node:fs';
|
|
1
|
+
// Loading the settings: built-in defaults, a user config file, and the example config that ships with the tool.
|
|
3
2
|
import path from 'node:path';
|
|
4
|
-
import
|
|
5
|
-
import { loadConfig } from '../core/config.js';
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
t
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
fs.rmSync(path.join(f.workA, '.python-version'));
|
|
40
|
-
write(path.join(f.workA, '.node-version'), 'v20.11.1');
|
|
41
|
-
check((await f.run()).versions.node.spec === 'v20.11.1', '.node-version is respected');
|
|
42
|
-
fs.rmSync(path.join(f.workA, '.node-version'));
|
|
43
|
-
check(await rejects(() => f.run({ cwd: f.install }), 'install folder') && await rejects(() => f.run({ cwd: temp }), 'must not be able to change') && await rejects(() => f.run({ cwd: path.join(temp, 'storage') }), 'storage folder'), 'refuses the install folder, its parents and the storage folder');
|
|
44
|
-
const originalWindir = process.env.WINDIR;
|
|
45
|
-
ensureDir(path.join(temp, 'winroot', 'sys'));
|
|
46
|
-
process.env.WINDIR = path.join(temp, 'winroot');
|
|
47
|
-
const sysRefused = await rejects(() => f.run({ cwd: path.join(temp, 'winroot', 'sys') }), 'system folder');
|
|
48
|
-
process.env.WINDIR = originalWindir;
|
|
49
|
-
check(sysRefused && await rejects(() => f.run({ cwd: path.parse(temp).root }), 'whole drive'), 'refuses system folders and drive roots');
|
|
50
|
-
t.section('.sandbox-config.json');
|
|
51
|
-
const localB = { harness: 'codex', sandbox: { memoryMb: 4096, networking: false, headless: true }, toolchains: { node: { version: '18' }, rust: { enabled: false } }, mappings: [{ host: './assets', guest: 'C:\\Assets', readOnly: true }, { host: '../shared', guest: 'C:\\Shared', readOnly: false }], scripts: ['./setup.mjs'] };
|
|
52
|
-
f.writeLocal(f.workB, localB);
|
|
53
|
-
check(await rejects(() => f.run({ cwd: f.workB }), '--trust-config') && await rejects(() => f.run({ cwd: f.workB }), 'READ/WRITE'), 'an untrusted .sandbox-config.json is refused and its effects are listed');
|
|
54
|
-
check(await rejects(() => f.run({ cwd: f.workB, ask: async () => false }), 'has not been approved'), 'answering "no" refuses it');
|
|
55
|
-
const rB = await f.run({ cwd: f.workB, ask: async () => true });
|
|
56
|
-
check(rB.harnessName === 'codex' && rB.config.sandbox.memoryMb === 4096 && rB.config.sandbox.headless && !rB.config.toolchains.rust.enabled && rB.config.toolchains.python.enabled && rB.versions.node.source === '.sandbox-config.json', 'approved local settings apply over the defaults (incl. toolchains, headless)');
|
|
57
|
-
check(rB.config.mappings.some((m) => m.host === f.shared && !m.readOnly) && rB.scripts.includes(path.join(f.workB, 'setup.mjs')), 'relative paths resolve against the folder of .sandbox-config.json');
|
|
58
|
-
check((await f.run({ cwd: f.workB })).harnessName === 'codex' && (await f.run({ cwd: f.workB, noLocalConfig: true })).harnessName === 'claude' && (await f.run({ cwd: f.workB, harness: 'gemini' })).harnessName === 'gemini', 'approval is remembered; --no-local-config and --harness win');
|
|
59
|
-
check((await f.run({ cwd: f.workB, headless: false })).config.sandbox.headless === false, '--window beats a local headless setting');
|
|
60
|
-
f.writeLocal(f.workB, { ...localB, sandbox: { memoryMb: 6144 } });
|
|
61
|
-
check(await rejects(() => f.run({ cwd: f.workB }), 'has not been approved'), 'changing the file requires approval again');
|
|
62
|
-
const dirC = path.join(temp, 'work-c');
|
|
63
|
-
ensureDir(dirC);
|
|
64
|
-
const bad = async (content, needle) => { f.writeLocal(dirC, content); return rejects(() => f.run({ cwd: dirC, trustConfig: true }), needle); };
|
|
65
|
-
check(await bad({ storage: { root: 'C:\\x' } }, 'storage is not allowed') && await bad({ harnesses: {} }, 'harnesses is not allowed'), 'local file cannot change storage or agent executables');
|
|
66
|
-
check(await bad({ claudeProfile: { hostDir: 'C:\\x' } }, 'claudeProfile.hostDir is not allowed') && await bad({ toolchains: { node: { hostDir: 'x' } } }, 'toolchains.node.hostDir is not allowed'), 'local file cannot point at host folders');
|
|
67
|
-
check(await bad({ sandbox: { memoryMb: 12 } }, 'sandbox.memoryMb:') && await bad({ mappings: [{ host: 'x', guest: 'C:\\Windows\\x', readOnly: true }] }, 'reserved or invalid guest path') && await bad({ provisioning: { git: { access: 'admin' } } }, 'provisioning.git.access:'), 'values are type-checked; reserved guest paths and unknown git modes are rejected');
|
|
68
|
-
check(await bad('{\n // a comment\n "readOnly": tru\n}', 'line 3') && await bad({ _comment: 'old style' }, '_comment is not allowed'), 'broken JSON is reported with line and column; unknown keys are rejected');
|
|
69
|
-
f.writeLocal(dirC, '// comments and trailing commas are fine\n{\n "readOnly": true, /* inline */\n}\n');
|
|
70
|
-
check((await f.run({ cwd: dirC, trustConfig: true })).config.readOnly === true, '.sandbox-config.json may contain comments and trailing commas');
|
|
71
|
-
f.writeLocal(dirC, { claudeProfile: { copyCredentials: true }, network: { blockPrivateRanges: false }, provisioning: { git: { access: 'full' } } });
|
|
72
|
-
check(await rejects(() => f.run({ cwd: dirC }), 'copies your Claude LOGIN') && await rejects(() => f.run({ cwd: dirC }), 'turns OFF the LAN block') && await rejects(() => f.run({ cwd: dirC }), 'commit and push'), 'risky settings are called out before approval');
|
|
73
|
-
fs.rmSync(path.join(dirC, '.sandbox-config.json'));
|
|
3
|
+
import _ from 'lodash';
|
|
4
|
+
import { DEFAULTS, loadConfig } from '../core/config.js';
|
|
5
|
+
import { readJsonc } from '../core/util.js';
|
|
6
|
+
export const configSuite = {
|
|
7
|
+
name: 'config',
|
|
8
|
+
title: 'built-in defaults, user config file, config.example.json',
|
|
9
|
+
run: async (t, f) => {
|
|
10
|
+
t.section('built-in defaults');
|
|
11
|
+
const builtIn = loadConfig();
|
|
12
|
+
t.equal({
|
|
13
|
+
configPath: builtIn.configPath,
|
|
14
|
+
guestWorkspace: builtIn.config.guestWorkspace,
|
|
15
|
+
headless: builtIn.config.sandbox.headless,
|
|
16
|
+
vGpu: builtIn.config.sandbox.vGpu,
|
|
17
|
+
gitAccess: builtIn.config.provisioning.git.access,
|
|
18
|
+
}, { configPath: null, guestWorkspace: 'auto', headless: false, vGpu: false, gitAccess: 'full' }, 'with no user config the built-in defaults apply (auto guest folder, headless off, vGPU off, git full)');
|
|
19
|
+
t.section('a user config file');
|
|
20
|
+
const customFile = t.writeJson(t.at('cfg.json'), {
|
|
21
|
+
sandbox: { headless: true },
|
|
22
|
+
toolchains: { rust: { enabled: false } },
|
|
23
|
+
mappings: [{ host: 'rel-folder', guest: 'C:\\Rel', readOnly: true }],
|
|
24
|
+
});
|
|
25
|
+
const custom = loadConfig(customFile);
|
|
26
|
+
t.equal({ headless: custom.config.sandbox.headless, rust: custom.config.toolchains.rust.enabled, python: custom.config.toolchains.python.enabled }, { headless: true, rust: false, python: 'auto' }, 'a config file only needs the keys it changes (deep merge over the defaults)');
|
|
27
|
+
await t.throws(() => loadConfig(t.at('missing.json')), 'Config file not found', 'an explicit --config that does not exist is an error');
|
|
28
|
+
t.dir('rel-folder');
|
|
29
|
+
const relativeRun = await f.run({}, { ...custom.config, storage: f.baseConfig.storage });
|
|
30
|
+
const mappedHosts = relativeRun.config.mappings.map((m) => m.host);
|
|
31
|
+
t.check(mappedHosts.includes(t.at('rel-folder')), 'relative mappings in the user config resolve against the config file\'s folder', 'mapped hosts: ' + JSON.stringify(mappedHosts));
|
|
32
|
+
t.section('config.example.json');
|
|
33
|
+
const examplePath = path.join(t.packageRoot, 'config.example.json');
|
|
34
|
+
t.equal(loadConfig(examplePath).config.defaultHarness, 'claude', 'config.example.json is valid');
|
|
35
|
+
const example = _.omit(readJsonc(examplePath), '$schema');
|
|
36
|
+
t.check(_.isEqual(example, DEFAULTS), 'config.example.json lists exactly the built-in defaults', 'the differences are in: ' + Object.keys(DEFAULTS).filter((key) => !_.isEqual(example[key], DEFAULTS[key])).join(', '));
|
|
37
|
+
},
|
|
74
38
|
};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
export declare const
|
|
1
|
+
import type { Suite } from './suite.js';
|
|
2
|
+
export declare const dataSuite: Suite;
|
|
@@ -1,73 +1,80 @@
|
|
|
1
|
-
// `sandbox data`
|
|
1
|
+
// `sandbox data` and `sandbox clean`: what a clean target may name, how sizes and removal treat links, and which old
|
|
2
|
+
// launch folders, logs and downloads are pruned.
|
|
2
3
|
import fs from 'node:fs';
|
|
3
4
|
import path from 'node:path';
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
5
|
+
import { resolveCleanTargets } from '../cli/commands/data/clean.js';
|
|
6
|
+
import { removeTree } from '../cli/commands/data/remove.js';
|
|
7
|
+
import { findLinks } from '../cli/commands/repair/finders.js';
|
|
8
|
+
import { humanBytes, sizeOf } from '../core/disk.js';
|
|
9
|
+
import { pruneStorage } from '../host/cleanup.js';
|
|
10
|
+
export const dataSuite = {
|
|
11
|
+
name: 'data',
|
|
12
|
+
title: 'data clean targets, sizes and removal with links, storage cleanup',
|
|
13
|
+
run: async (t) => {
|
|
14
|
+
t.section('clean targets');
|
|
15
|
+
const storage = t.at('data-store');
|
|
16
|
+
const dataPath = path.join(storage, 'data', 'default');
|
|
17
|
+
const resolve = (...inputs) => resolveCleanTargets(inputs, dataPath, storage).map((r) => path.relative(storage, r.path));
|
|
18
|
+
const inData = (...parts) => path.join('data', 'default', ...parts);
|
|
19
|
+
t.equal(resolve('tools/go'), [inData('tools', 'go')], 'tools/<name> resolves inside the data folder');
|
|
20
|
+
t.equal(resolve('tools\\go'), [inData('tools', 'go')], 'either slash works');
|
|
21
|
+
t.equal(resolve('Tools/agents/claude'), [inData('tools', 'agents', 'claude')], 'tools/agents/<name> resolves, whatever the case');
|
|
22
|
+
t.equal(resolve('databases/postgres-18'), [inData('databases', 'postgres-18')], 'databases/<name> resolves');
|
|
23
|
+
t.equal(resolve('logs'), [inData('logs')], 'logs resolves');
|
|
24
|
+
t.equal(resolve('launches'), ['launches'], 'launches resolves to the storage folder\'s launches');
|
|
25
|
+
t.equal(resolve('state/claude'), [inData('state', 'claude')], 'state/<agent> resolves');
|
|
26
|
+
t.equal(resolve('tools', 'tools/go', 'tools/go'), [inData('tools')], 'nested and repeated targets collapse');
|
|
27
|
+
t.equal(resolve('all', 'logs'), [inData(), 'launches'], '`all` is the data folder plus launches');
|
|
28
|
+
t.check(Boolean(resolveCleanTargets(['state/claude'], dataPath, storage)[0].warning?.includes('login')), 'cleaning state warns about the login');
|
|
29
|
+
t.check(Boolean(resolveCleanTargets(['all'], dataPath, storage)[0].warning), 'cleaning everything carries a warning');
|
|
30
|
+
const badTargets = ['', '..', 'tools/..', 'tools/../../x', '../data', 'C:\\Windows', 'C:tools', '/etc', '\\\\server\\share', 'tools/*', 'tools/go:stream', 'tools/a/b', 'tools/agents/a/b', 'logs/guest.log', 'accounts', 'sync', 'windows', 'tools/.', 'tools/go.'];
|
|
31
|
+
const accepted = badTargets.filter((target) => {
|
|
32
|
+
try {
|
|
33
|
+
resolveCleanTargets([target], dataPath, storage);
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
t.equal(accepted, [], 'rejected: .., absolute paths, drive letters, UNC, wildcards, streams, too deep, unknown areas');
|
|
41
|
+
await t.throws(() => resolveCleanTargets([], dataPath, storage), '', 'rejected: no target at all (that is not "everything")');
|
|
42
|
+
t.section('sizes and removal never follow links');
|
|
43
|
+
const sized = t.at('sized');
|
|
44
|
+
t.write(path.join(sized, 'a.bin'), 'x'.repeat(1000));
|
|
45
|
+
t.write(path.join(sized, 'sub', 'b.bin'), 'y'.repeat(24));
|
|
46
|
+
const outside = t.at('outside');
|
|
47
|
+
t.write(path.join(outside, 'keep.txt'), 'z'.repeat(5000));
|
|
48
|
+
let linked = false;
|
|
49
|
+
try {
|
|
50
|
+
fs.symlinkSync(outside, path.join(sized, 'sub', 'escape'), 'junction');
|
|
51
|
+
linked = true;
|
|
52
|
+
}
|
|
53
|
+
catch { /* no junctions here */ }
|
|
54
|
+
t.equal(sizeOf(sized), 1024, 'sizes count real files only' + (linked ? ' (a junction counts 0)' : ''));
|
|
55
|
+
t.equal([humanBytes(1536), humanBytes(0), humanBytes(3 * 1024 ** 3)], ['1.5 KB', '0 B', '3.0 GB'], 'sizes are shown in readable units');
|
|
56
|
+
if (linked)
|
|
57
|
+
t.equal(findLinks(sized).length, 1, 'repair finds a junction planted in the data folder');
|
|
58
|
+
removeTree(sized, t.temp);
|
|
59
|
+
t.check(!fs.existsSync(sized), 'a folder is removed');
|
|
60
|
+
t.check(fs.existsSync(path.join(outside, 'keep.txt')), 'removing a folder never deletes what a link inside points to');
|
|
61
|
+
t.section('storage cleanup');
|
|
62
|
+
const store = t.at('prune');
|
|
63
|
+
const aged = (p, days) => { const d = new Date(Date.now() - days * 86400000); fs.utimesSync(p, d, d); };
|
|
64
|
+
for (const [name, days] of [['old', 9], ['kept', 30], ['new', 1]]) {
|
|
65
|
+
aged(t.write(path.join(store, 'launches', name, 'agent.wsb'), 'x'), days);
|
|
66
|
+
aged(path.join(store, 'launches', name), days);
|
|
67
|
+
}
|
|
68
|
+
aged(t.write(path.join(store, 'data', 'd', 'logs', 'guest-old.log'), 'x'), 20);
|
|
69
|
+
t.write(path.join(store, 'data', 'd', 'logs', 'guest-new.log'), 'x');
|
|
70
|
+
const staging = t.dir('prune', 'data', 'd', 'tools', 'git.staging-ab12');
|
|
71
|
+
aged(staging, 2);
|
|
72
|
+
t.dir('prune', 'data', 'd', 'tools', 'node');
|
|
73
|
+
const pruned = pruneStorage(store, { keep: ['kept'] });
|
|
74
|
+
const left = (p) => fs.existsSync(path.join(store, p));
|
|
75
|
+
t.equal(pruned.launches, 1, 'cleanup removes one launch folder');
|
|
76
|
+
t.equal({ old: left('launches/old'), kept: left('launches/kept'), new: left('launches/new') }, { old: false, kept: true, new: true }, 'cleanup: launch folders older than 7 days go; the running launch and recent ones stay');
|
|
77
|
+
t.equal({ oldLog: left('data/d/logs/guest-old.log'), newLog: left('data/d/logs/guest-new.log') }, { oldLog: false, newLog: true }, 'cleanup: logs older than 14 days go');
|
|
78
|
+
t.equal({ interrupted: left('data/d/tools/git.staging-ab12'), realTool: left('data/d/tools/node') }, { interrupted: false, realTool: true }, 'cleanup: interrupted downloads go; real tools stay');
|
|
79
|
+
},
|
|
73
80
|
};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
export declare const
|
|
1
|
+
import type { Suite } from './suite.js';
|
|
2
|
+
export declare const detectSuite: Suite;
|
|
@@ -1,42 +1,58 @@
|
|
|
1
|
-
// "
|
|
1
|
+
// "What does this project need?": databases and toolchains detected from project files, and the plans built from them.
|
|
2
2
|
import { databasesFromServices, detectDatabases } from '../core/detect-databases.js';
|
|
3
3
|
import { DEFAULTS } from '../core/config.js';
|
|
4
|
-
import { databaseCatalog, planDatabases } from '../host/
|
|
5
|
-
import { voltaNode } from '../core/workspace.js';
|
|
4
|
+
import { databaseCatalog, planDatabases } from '../host/database-plan.js';
|
|
6
5
|
import { decideToolchains, resolveToolchains } from '../core/detect-toolchains.js';
|
|
7
|
-
|
|
8
|
-
const
|
|
9
|
-
export const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
6
|
+
const found = (files, host = []) => detectDatabases(files, host).map((d) => d.database);
|
|
7
|
+
const file = (path, text) => ({ path, text });
|
|
8
|
+
export const detectSuite = {
|
|
9
|
+
name: 'detect',
|
|
10
|
+
title: 'database and toolchain detection from project files',
|
|
11
|
+
run: (t) => {
|
|
12
|
+
t.section('databases from project files');
|
|
13
|
+
const compose = file('docker-compose.yml', 'services:\n db:\n image: postgres:16-alpine\n cache:\n image: "redis:7"\n dynamo:\n image: amazon/dynamodb-local:latest\n');
|
|
14
|
+
t.equal(found([compose]), ['postgres', 'redis', 'dynamodb'], 'compose services: postgres, redis and DynamoDB Local images');
|
|
15
|
+
t.equal(found([file('package.json', '{"dependencies":{"pg":"^8.11.0","ioredis":"5","@aws-sdk/client-dynamodb":"3"}}')]), ['postgres', 'redis', 'dynamodb'], 'package.json: pg, ioredis, @aws-sdk/client-dynamodb');
|
|
16
|
+
t.equal(found([file('package.json', '{"dependencies":{"pgadmin-ui":"1","mysql-logger":"2","express":"4"}}')]), [], 'package.json: names that only contain a driver name do not count');
|
|
17
|
+
t.equal(found([file('prisma/schema.prisma', 'datasource db {\n provider = "mysql"\n url = env("DATABASE_URL")\n}')]), ['mysql'], 'Prisma: the datasource provider decides');
|
|
18
|
+
t.equal(found([file('requirements.txt', 'django==5.0\npsycopg2-binary==2.9\npymongo>=4\n')]), ['postgres', 'mongodb'], 'Python requirements: psycopg2 and pymongo');
|
|
19
|
+
t.equal(found([file('Api/Api.csproj', '<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.0" />')]), ['sqlserver'], '.NET: EF Core SQL Server provider');
|
|
20
|
+
t.equal(found([file('.env.example', 'DATABASE_URL=postgresql://user:pass@localhost:5432/app\nMONGO_URL=mongodb+srv://cluster/x\n')]), ['postgres', 'mongodb'], '.env templates: connection-string schemes');
|
|
21
|
+
t.equal(found([file('template.yaml', 'Resources:\n Table:\n Type: AWS::DynamoDB::Table\n')]), ['dynamodb'], 'SAM/CloudFormation: a DynamoDB table resource');
|
|
22
|
+
t.equal(found([file('go.mod', 'require (\n\tgithub.com/jackc/pgx/v5 v5.5.0\n\tgithub.com/aws/aws-sdk-go-v2/service/dynamodb v1.0.0\n)')]), ['postgres', 'dynamodb'], 'go.mod: pgx and the DynamoDB SDK');
|
|
23
|
+
const knex = [file('package.json', '{"dependencies":{"knex":"3"}}')];
|
|
24
|
+
t.equal(found(knex), [], 'an ORM that names no database uses nothing when this PC has none');
|
|
25
|
+
t.equal(found(knex, ['mysql']), ['mysql'], 'an ORM that names no database uses the one installed on this PC');
|
|
26
|
+
t.equal(databasesFromServices(['postgresql-x64-16', 'MySQL80', 'MSSQL$SQLEXPRESS', 'Spooler', 'Redis']), ['postgres', 'mysql', 'sqlserver', 'redis'], 'database services on this PC are recognised by name');
|
|
27
|
+
// Hostile workspace files (a cloned repository is untrusted): detection must stay linear.
|
|
28
|
+
const hostile = [
|
|
29
|
+
file('.env', 'Server=a;Database=a;'.repeat(12000)),
|
|
30
|
+
file('compose.yaml', 'services:\n x:\n image: ' + 'postgres'.repeat(20000) + '!\n'),
|
|
31
|
+
file('appsettings.json', 'Host=a;'.repeat(30000)),
|
|
32
|
+
];
|
|
33
|
+
const started = Date.now();
|
|
34
|
+
detectDatabases(hostile);
|
|
35
|
+
const took = Date.now() - started;
|
|
36
|
+
t.check(took < 2000, 'database detection stays fast on hostile workspace files (no catastrophic backtracking)', 'took ' + took + ' ms');
|
|
37
|
+
t.section('the database plan');
|
|
38
|
+
const plan = planDatabases({ ...DEFAULTS.databases, mongodb: { ...DEFAULTS.databases.mongodb, enabled: true }, redis: { ...DEFAULTS.databases.redis, enabled: false } }, 'unused', { files: [compose], host: [] });
|
|
39
|
+
t.equal(plan.map((p) => p.database + '@' + p.version + ':' + p.port), ['postgres@16:5432', 'mongodb@latest:27017', 'dynamodb@latest:8000'], 'plan: "auto" from the project (compose pins Postgres 16), true always, false never');
|
|
40
|
+
t.equal(plan.find((p) => p.database === 'dynamodb')?.adminPort, 8001, 'plan: DynamoDB gets its admin UI port');
|
|
41
|
+
const catalog = databaseCatalog({ ...DEFAULTS.databases, postgres: { ...DEFAULTS.databases.postgres, enabled: false, port: 6543 } });
|
|
42
|
+
t.equal(catalog.map((p) => p.database), ['postgres', 'mysql', 'mongodb', 'redis', 'dynamodb'], 'sbx-db catalog: every database that can run (not SQL Server), even ones off at boot');
|
|
43
|
+
t.equal(catalog[0].port, 6543, 'sbx-db catalog: configured ports are used');
|
|
44
|
+
t.section('toolchains from project files');
|
|
45
|
+
const tc = DEFAULTS.toolchains;
|
|
46
|
+
const goProject = decideToolchains(tc, ['README.md', 'go.mod', 'api/main.go'], ['python', 'rust']);
|
|
47
|
+
t.equal({ go: goProject.go.on, reason: goProject.go.reason }, { go: true, reason: 'go.mod' }, 'toolchains: a Go project gets Go (and says why)');
|
|
48
|
+
t.equal({ python: goProject.python.on, rust: goProject.rust.on, dotnet: goProject.dotnet.on, java: goProject.java.on }, { python: false, rust: false, dotnet: false, java: false }, 'toolchains: a Go project gets nothing it does not use, whatever this PC has');
|
|
49
|
+
const fresh = decideToolchains(tc, ['notes.txt'], ['python', 'dotnet']);
|
|
50
|
+
t.equal({ python: fresh.python.on, dotnet: fresh.dotnet.on, go: fresh.go.on }, { python: true, dotnet: true, go: false }, 'toolchains: a folder that is no project yet gets the languages this PC has');
|
|
51
|
+
t.includes(fresh.python.reason, 'this PC', 'toolchains: the reason names this PC');
|
|
52
|
+
const rusty = decideToolchains({ ...tc, python: { ...tc.python, enabled: true } }, ['Cargo.toml'], []);
|
|
53
|
+
t.equal({ rust: rusty.rust.on, cpp: rusty.cpp.on }, { rust: true, cpp: true }, 'toolchains: Rust brings its C/C++ linker');
|
|
54
|
+
t.equal({ python: rusty.python.on, reason: rusty.python.reason }, { python: true, reason: 'enabled in config' }, 'toolchains: true in config always wins');
|
|
55
|
+
const resolved = resolveToolchains(tc, goProject);
|
|
56
|
+
t.equal({ go: resolved.go.enabled, python: resolved.python.enabled }, { go: true, python: false }, 'the sandbox gets plain decisions instead of "auto"');
|
|
57
|
+
},
|
|
42
58
|
};
|