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
|
@@ -3,72 +3,99 @@ import fs from 'node:fs';
|
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
import { Config, Mapping } from '../core/schema.js';
|
|
5
5
|
import { guestPathFor } from '../cli/commands/context.js';
|
|
6
|
-
import { buildWsb } from '../host/
|
|
6
|
+
import { buildWsb } from '../host/launch/wsb.js';
|
|
7
7
|
import { guestDrive, isValidGuestPath, planMirrorWorkspace, sandboxFolder, substDrives } from '../shared/guest-paths.js';
|
|
8
8
|
import { guestWorkspaceAliases, projectFolderName } from '../shared/paths.js';
|
|
9
9
|
import { syncHistoryIn, syncHistoryOut } from '../sync/history.js';
|
|
10
|
-
export const
|
|
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
|
-
|
|
73
|
-
|
|
10
|
+
export const mirrorSuite = {
|
|
11
|
+
name: 'mirror',
|
|
12
|
+
title: 'guest paths on other drive letters, guestWorkspace "mirror"',
|
|
13
|
+
run: async (t, f) => {
|
|
14
|
+
t.section('which guest paths are valid');
|
|
15
|
+
const valid = ['C:\\Assets', 'C:\\Workspace\\x', 'F:\\SteamLibrary\\steamapps\\common\\Game', 'f:\\x', 'Z:\\a b\\c (1)'];
|
|
16
|
+
t.equal(valid.filter((p) => !isValidGuestPath(p)), [], 'guest paths under C:\\ or on D: to Z: are accepted');
|
|
17
|
+
const invalid = ['C:\\', 'F:\\', 'F:', 'C:\\Windows\\x', 'C:\\Users\\me', 'c:\\program files\\x', 'C:\\AgentData\\x', 'C:\\Mirror', 'C:\\Mirror\\F\\x', 'A:\\x', 'B:\\x', 'C:\\a\\..\\Windows', 'F:\\a\\..\\b', 'F:\\a:b', 'F:\\a/b', 'F:\\a\\\\b', 'F:\\a.\\b', 'F:\\a|b', 'F:\\a\nb', '\\\\server\\share\\x', 'relative\\x', 'F:x'];
|
|
18
|
+
t.equal(invalid.filter(isValidGuestPath), [], 'drive roots, reserved folders, C:\\Mirror, A:/B:, .., streams, odd characters and UNC paths are refused');
|
|
19
|
+
const mappingAccepts = (guest) => Mapping.safeParse({ host: 'E:\\Games', guest, readOnly: true }).success;
|
|
20
|
+
t.check(mappingAccepts('F:\\SteamLibrary\\Game') && mappingAccepts('C:\\F'), 'schema: mappings[].guest may be on another drive letter');
|
|
21
|
+
t.check(!mappingAccepts('C:\\Mirror\\F\\x') && !mappingAccepts('F:\\'), 'schema: mappings[].guest may never be C:\\Mirror or a drive root');
|
|
22
|
+
const workspaceAccepts = (guestWorkspace) => Config.safeParse({ ...f.makeConfig(), guestWorkspace }).success;
|
|
23
|
+
t.check(workspaceAccepts('mirror') && workspaceAccepts('F:\\AgentProjects\\x'), 'schema: guestWorkspace accepts "mirror" and D:-Z: paths');
|
|
24
|
+
t.check(!workspaceAccepts('C:\\Users\\x'), 'schema: guestWorkspace refuses reserved paths');
|
|
25
|
+
t.equal([guestDrive('f:\\x'), guestDrive('\\\\s\\x')], ['F', null], 'drive letter of a guest path');
|
|
26
|
+
t.section('where a drive-letter path really lives');
|
|
27
|
+
t.equal([sandboxFolder('F:\\SteamLibrary\\Game'), sandboxFolder('f:\\x'), sandboxFolder('C:\\Assets')], ['C:\\Mirror\\F\\SteamLibrary\\Game', 'C:\\Mirror\\F\\x', 'C:\\Assets'], 'F:\\x really lives at C:\\Mirror\\F\\x; C: paths stay as they are');
|
|
28
|
+
t.equal(substDrives(['C:\\a', 'G:\\z', 'F:\\x', 'f:\\y']), [{ letter: 'F', target: 'C:\\Mirror\\F' }, { letter: 'G', target: 'C:\\Mirror\\G' }], 'one subst drive per used letter (never C:), sorted');
|
|
29
|
+
t.equal(guestWorkspaceAliases('F:\\AgentProjects\\mw2'), ['C:\\Mirror\\F\\AgentProjects\\mw2', 'F:\\AgentProjects\\mw2'], 'a mirrored workspace is also known by its real C:\\Mirror path');
|
|
30
|
+
t.equal(guestWorkspaceAliases('C:\\Workspace\\x').length, 1, 'a C: workspace has no alias');
|
|
31
|
+
const wsb = buildWsb(f.baseConfig, 4096, [
|
|
32
|
+
{ host: 'E:\\SteamLibrary\\steamapps\\common\\Game', guest: 'F:\\SteamLibrary\\steamapps\\common\\Game', readOnly: true },
|
|
33
|
+
{ host: 'D:\\Assets', guest: 'C:\\Assets', readOnly: false },
|
|
34
|
+
]);
|
|
35
|
+
t.includes(wsb, '<SandboxFolder>C:\\Mirror\\F\\SteamLibrary\\steamapps\\common\\Game</SandboxFolder>', 'the .wsb maps F:\\ guests under C:\\Mirror\\F');
|
|
36
|
+
t.includes(wsb, '<SandboxFolder>C:\\Assets</SandboxFolder>', 'the .wsb maps C:\\ guests as they are');
|
|
37
|
+
t.excludes(wsb, '<SandboxFolder>F:', 'the .wsb never maps a drive-letter folder directly');
|
|
38
|
+
t.section('guestWorkspace "mirror"');
|
|
39
|
+
const fallback = 'C:\\Workspace\\mw2-agent';
|
|
40
|
+
const onF = planMirrorWorkspace('F:\\AgentProjects\\mw2-agent', fallback);
|
|
41
|
+
t.equal(onF.guest, 'F:\\AgentProjects\\mw2-agent', 'a workspace on F: appears at its PC path (mirror + subst)');
|
|
42
|
+
t.includes(onF.note ?? '', 'C:\\Mirror\\F\\AgentProjects\\mw2-agent', 'a workspace on F: comes with a note saying where it really is');
|
|
43
|
+
t.equal(planMirrorWorkspace('f:\\AgentProjects\\x\\', fallback).guest, 'F:\\AgentProjects\\x', 'a trailing backslash and a lower-case letter are normalised');
|
|
44
|
+
const onC = planMirrorWorkspace('C:\\dev\\mw2-agent', fallback);
|
|
45
|
+
t.equal({ guest: onC.guest, note: onC.note }, { guest: 'C:\\dev\\mw2-agent', note: null }, 'a workspace on C: outside reserved folders keeps its path');
|
|
46
|
+
const reserved = planMirrorWorkspace('C:\\Users\\josh\\mw2-agent', fallback);
|
|
47
|
+
t.equal(reserved.guest, fallback, 'C:\\Users\\... falls back to C:\\Workspace\\<name>...');
|
|
48
|
+
t.includes(reserved.note ?? '', 'reserved', '... with a note');
|
|
49
|
+
t.equal(planMirrorWorkspace('\\\\server\\share\\mw2-agent', fallback).guest, fallback, 'UNC paths fall back');
|
|
50
|
+
t.equal(planMirrorWorkspace('A:\\mw2-agent', fallback).guest, fallback, 'A: and B: fall back');
|
|
51
|
+
const resolved = await f.run({}, { ...f.makeConfig(), guestWorkspace: 'mirror' });
|
|
52
|
+
const expected = planMirrorWorkspace(f.workA, 'C:\\Workspace\\work-a');
|
|
53
|
+
t.equal(resolved.config.guestWorkspace, expected.guest, 'resolveRun turns "mirror" into a concrete guest path');
|
|
54
|
+
t.check(expected.note === null || resolved.notes.includes(expected.note), 'resolveRun explains a fallback in run.notes', JSON.stringify(resolved.notes));
|
|
55
|
+
t.section('generating a sandbox with drive-letter folders');
|
|
56
|
+
const game = t.dir('steam', 'Game');
|
|
57
|
+
const base = await f.run();
|
|
58
|
+
const run = { ...base, config: { ...base.config, guestWorkspace: 'G:\\Projects\\work-a', mappings: [{ host: game, guest: 'F:\\SteamLibrary\\steamapps\\common\\Game', readOnly: true }] } };
|
|
59
|
+
const generated = f.generate(run);
|
|
60
|
+
const session = f.readJson(generated.sessionPath);
|
|
61
|
+
const text = fs.readFileSync(generated.wsbPath, 'utf8');
|
|
62
|
+
t.equal(session.workspace, 'G:\\Projects\\work-a', 'session.json: the workspace is at its drive-letter path');
|
|
63
|
+
t.equal(session.substDrives, [{ letter: 'F', target: 'C:\\Mirror\\F' }, { letter: 'G', target: 'C:\\Mirror\\G' }], 'session.json: subst drives are listed for bootstrap.ps1');
|
|
64
|
+
t.includes(text, '<SandboxFolder>C:\\Mirror\\G\\Projects\\work-a</SandboxFolder>', '.wsb: the workspace is under C:\\Mirror');
|
|
65
|
+
t.includes(text, '<SandboxFolder>C:\\Mirror\\F\\SteamLibrary\\steamapps\\common\\Game</SandboxFolder>', '.wsb: the mapping is under C:\\Mirror');
|
|
66
|
+
t.equal(f.readJson(f.generate(base).sessionPath).substDrives, [], 'no other drive letters: no subst drives');
|
|
67
|
+
const withMapping = (guest) => ({ ...run, config: { ...run.config, mappings: [{ host: game, guest, readOnly: true }] } });
|
|
68
|
+
await t.throws(() => f.generate(withMapping('C:\\Mirror\\F\\x')), 'not a usable sandbox folder', 'a mapping straight into C:\\Mirror is refused');
|
|
69
|
+
await t.throws(() => f.generate(withMapping('C:\\Windows\\x')), 'not a usable sandbox folder', 'a reserved guest folder is refused by the host too (not only the schema)');
|
|
70
|
+
await t.throws(() => f.generate(withMapping('g:\\projects\\work-a\\game')), 'overlapping', 'mappings overlapping on the same mirrored drive are refused');
|
|
71
|
+
t.section('exec, attach and history for a mirrored workspace');
|
|
72
|
+
const workspace = 'F:\\AgentProjects\\mw2-agent';
|
|
73
|
+
t.equal(guestPathFor(workspace + '\\crates\\engine', workspace, workspace), workspace + '\\crates\\engine', 'a host folder maps to the same guest folder');
|
|
74
|
+
const project = projectFolderName(workspace);
|
|
75
|
+
t.equal(project, 'F--AgentProjects-mw2-agent', 'the Claude project folder is the same on both sides');
|
|
76
|
+
const sides = f.historySides('mirror', workspace, workspace);
|
|
77
|
+
const hostProject = path.join(sides.hostClaudeDir, 'projects', project);
|
|
78
|
+
const guestProject = path.join(sides.guestClaudeDir, 'projects', project);
|
|
79
|
+
t.write(path.join(hostProject, 's1.jsonl'), '{"cwd":"F:\\\\AgentProjects\\\\mw2-agent","t":1}\n');
|
|
80
|
+
t.write(path.join(sides.hostClaudeDir, 'history.jsonl'), '{"display":"hi","timestamp":1,"project":"F:\\\\AgentProjects\\\\mw2-agent"}\n');
|
|
81
|
+
syncHistoryIn(sides);
|
|
82
|
+
t.includes(fs.readFileSync(path.join(guestProject, 's1.jsonl'), 'utf8'), 'F:\\\\AgentProjects\\\\mw2-agent', 'history in: paths are unchanged');
|
|
83
|
+
t.equal(fs.readdirSync(path.join(sides.guestClaudeDir, 'projects')).length, 1, 'history in: only the one project folder is created');
|
|
84
|
+
t.write(path.join(guestProject, 's2.jsonl'), '{"cwd":"F:\\\\AgentProjects\\\\mw2-agent","t":2}\n');
|
|
85
|
+
const realPathProject = path.join(sides.guestClaudeDir, 'projects', 'C--Mirror-F-AgentProjects-mw2-agent');
|
|
86
|
+
t.write(path.join(realPathProject, 's3.jsonl'), '{"cwd":"C:\\\\Mirror\\\\F\\\\AgentProjects\\\\mw2-agent","f":"C:/Mirror/F/AgentProjects/mw2-agent/src/main.rs"}\n');
|
|
87
|
+
fs.appendFileSync(path.join(sides.guestClaudeDir, 'history.jsonl'), '{"display":"real path","timestamp":2,"project":"C:\\\\Mirror\\\\F\\\\AgentProjects\\\\mw2-agent"}\n');
|
|
88
|
+
syncHistoryOut(sides);
|
|
89
|
+
const s3 = path.join(hostProject, 's3.jsonl');
|
|
90
|
+
t.check(fs.existsSync(path.join(hostProject, 's2.jsonl')), 'history out: transcripts under the PC path come back');
|
|
91
|
+
t.check(fs.existsSync(s3), 'history out: transcripts under the real C:\\Mirror path come back into the PC project folder');
|
|
92
|
+
t.check(!fs.existsSync(path.join(sides.hostClaudeDir, 'projects', 'C--Mirror-F-AgentProjects-mw2-agent')), 'history out: no C:\\Mirror project folder appears on the PC');
|
|
93
|
+
const s3Text = fs.existsSync(s3) ? fs.readFileSync(s3, 'utf8') : '';
|
|
94
|
+
t.includes(s3Text, '"cwd":"F:\\\\AgentProjects\\\\mw2-agent"', 'history out: C:\\Mirror\\F\\... paths are translated back to F:\\...');
|
|
95
|
+
t.includes(s3Text, 'F:/AgentProjects/mw2-agent/src/main.rs', 'history out: forward-slash paths are translated too');
|
|
96
|
+
t.excludes(s3Text, 'Mirror', 'history out: nothing mentions C:\\Mirror any more');
|
|
97
|
+
const promptHistory = fs.readFileSync(path.join(sides.hostClaudeDir, 'history.jsonl'), 'utf8');
|
|
98
|
+
t.includes(promptHistory, '"project":"F:\\\\AgentProjects\\\\mw2-agent"}', 'prompt history out: real paths are translated');
|
|
99
|
+
t.excludes(promptHistory, 'Mirror', 'prompt history out: nothing mentions C:\\Mirror');
|
|
100
|
+
},
|
|
74
101
|
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { isSandboxAddress } from '../host/attach.js';
|
|
2
|
+
import { buildFirewallCommands, cidrToRange, ipv4DnsServers, parseDefaultGateways, parseDnsServers, subtractIps } from '../shared/netrules.js';
|
|
3
|
+
import { expandAllowList, hostAllowed, withBlockedHosts } from '../shared/netpolicy.js';
|
|
4
|
+
export const networkSuite = {
|
|
5
|
+
name: 'network',
|
|
6
|
+
title: 'firewall maths, gateway/DNS parsing, attach address checks',
|
|
7
|
+
run: (t) => {
|
|
8
|
+
t.section('firewall');
|
|
9
|
+
const [start172, end172] = cidrToRange('172.16.0.0/12');
|
|
10
|
+
const gateway = 172 * 16777216 + 28 * 65536 + 1;
|
|
11
|
+
const remaining = subtractIps([[start172, end172]], ['172.28.0.1']);
|
|
12
|
+
t.check(remaining.every(([start, end]) => gateway < start || gateway > end), 'the private block minus the gateway no longer contains the gateway');
|
|
13
|
+
t.excludes(buildFirewallCommands(['8.8.8.8']).join(), '8.8.8.8', 'public addresses are not part of the private-range rules');
|
|
14
|
+
t.section('reading Windows output');
|
|
15
|
+
t.equal(parseDefaultGateways(' 0.0.0.0 0.0.0.0 172.28.80.1 172.28.85.200 5\n'), ['172.28.80.1'], 'the default gateway is read from the route table');
|
|
16
|
+
t.equal(parseDnsServers(' DNS Servers . . . : 172.28.80.1\n 8.8.8.8\n NetBIOS : x\n'), ['172.28.80.1', '8.8.8.8'], 'DNS servers are read from ipconfig output');
|
|
17
|
+
t.equal(ipv4DnsServers(['172.28.80.1', '8.8.8.8:1053', '[::1]:53', 'fe80::1']), ['172.28.80.1', '8.8.8.8'], 'DNS servers from the resolver (any Windows language): IPv4 only, ports dropped');
|
|
18
|
+
t.section('attach only reaches into the sandbox');
|
|
19
|
+
const interfaces = {
|
|
20
|
+
'vEthernet (Default Switch)': [{ address: '172.20.0.1', netmask: '255.255.240.0', family: 'IPv4', internal: false, mac: '', cidr: null }],
|
|
21
|
+
'vEthernet (WSL (Hyper-V firewall))': [{ address: '172.30.0.1', netmask: '255.255.240.0', family: 'IPv4', internal: false, mac: '', cidr: null }],
|
|
22
|
+
Ethernet: [{ address: '192.168.1.10', netmask: '255.255.255.0', family: 'IPv4', internal: false, mac: '', cidr: null }],
|
|
23
|
+
};
|
|
24
|
+
t.check(isSandboxAddress('172.20.5.9', interfaces), 'an address in the Hyper-V subnet is the sandbox');
|
|
25
|
+
t.check(!isSandboxAddress('192.168.1.20', interfaces), 'a LAN address is not');
|
|
26
|
+
t.check(!isSandboxAddress('172.30.4.4', interfaces), 'an address on the WSL Hyper-V network is not (keystrokes never go to a WSL VM)');
|
|
27
|
+
t.check(!isSandboxAddress('127.0.0.1', interfaces), 'loopback is not');
|
|
28
|
+
t.check(!isSandboxAddress('8.8.8.8', interfaces), 'an internet address is not');
|
|
29
|
+
t.check(!isSandboxAddress('172.20.0.1', interfaces), 'this PC\'s own address on that subnet is not');
|
|
30
|
+
t.section('network settings');
|
|
31
|
+
const allow = expandAllowList(['@developer', 'Example.COM', '*.corp.example', 'not a host!']);
|
|
32
|
+
t.check(allow.includes('registry.npmjs.org') && allow.includes('api.anthropic.com') && allow.includes('example.com') && !allow.includes('not a host!'), 'allowOnly: @developer expands to registries, GitHub and AI providers; bad entries are dropped');
|
|
33
|
+
t.equal(['a.corp.example', 'corp.example', 'example.com', 'www.example.com', 'evil-example.com'].map((h) => hostAllowed(h, allow)), [true, false, true, false, false], 'allowOnly: *.x covers subdomains only, a name covers only itself');
|
|
34
|
+
const hosts = '127.0.0.1 localhost\r\n# mine\r\n';
|
|
35
|
+
const once = withBlockedHosts(hosts, ['Telemetry.Example.com', '*.bad']);
|
|
36
|
+
t.check(once.includes('0.0.0.0 telemetry.example.com') && once.includes('# mine') && !once.includes('*.bad'), 'blockHosts: names go to 0.0.0.0, your own lines stay, wildcards are skipped (a hosts file cannot do them)');
|
|
37
|
+
t.equal(withBlockedHosts(once, ['telemetry.example.com']), once, 'blockHosts: applying again changes nothing');
|
|
38
|
+
t.check(!withBlockedHosts(once, []).includes('telemetry'), 'blockHosts: an empty list removes the section');
|
|
39
|
+
},
|
|
40
|
+
};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
// Things written for Windows itself on this PC: the registry personalisation (.reg file) and the Windows Terminal
|
|
2
|
+
// PowerShell 7 profile. The Windows Terminal part is only tried on temp copies.
|
|
3
|
+
import fs from 'node:fs';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { toRegFile } from '../host/personalize.js';
|
|
6
|
+
import { PWSH_PROFILE_GUID, syncPwshProfile, withPwshProfile } from '../host/terminal.js';
|
|
7
|
+
export const personalizationSuite = {
|
|
8
|
+
name: 'personalization',
|
|
9
|
+
title: 'registry personalisation (.reg) and the Windows Terminal PowerShell 7 profile',
|
|
10
|
+
run: (t) => {
|
|
11
|
+
t.section('registry values');
|
|
12
|
+
const reg = toRegFile([
|
|
13
|
+
{ key: 'Control Panel\\Desktop', name: 'WallpaperStyle', kind: 'String', value: '10' },
|
|
14
|
+
{ key: 'X', name: 'D', kind: 'DWord', value: 4294967295 },
|
|
15
|
+
{ key: 'X', name: 'B', kind: 'Binary', value: Buffer.from([1, 255]).toString('base64') },
|
|
16
|
+
]);
|
|
17
|
+
t.includes(reg, '[HKEY_CURRENT_USER\\Control Panel\\Desktop]', 'the .reg file only writes under HKCU');
|
|
18
|
+
t.includes(reg, '"WallpaperStyle"="10"', 'string values are written as strings');
|
|
19
|
+
t.includes(reg, '"D"=dword:ffffffff', 'DWORD values are written in hex');
|
|
20
|
+
t.includes(reg, '"B"=hex:01,ff', 'binary values are written as hex bytes');
|
|
21
|
+
t.section('Windows Terminal profile');
|
|
22
|
+
const shown = withPwshProfile({ theme: 'dark', profiles: { defaults: { font: {} } } }, true);
|
|
23
|
+
const shownProfiles = shown?.profiles;
|
|
24
|
+
t.equal(shownProfiles?.list.length, 1, 'a PowerShell 7 profile is added once pwsh is installed');
|
|
25
|
+
t.equal(shownProfiles?.list[0].guid, PWSH_PROFILE_GUID, 'the added profile has our GUID');
|
|
26
|
+
t.includes(String(shownProfiles?.list[0].commandline), 'pwsh.exe', 'the added profile starts pwsh.exe');
|
|
27
|
+
t.check(Boolean(shownProfiles?.defaults) && shown?.theme === 'dark', 'the rest of the settings are kept');
|
|
28
|
+
t.equal(withPwshProfile(shown, true), null, 'nothing is rewritten when the profile is already there');
|
|
29
|
+
t.equal(withPwshProfile({ profiles: { defaults: {} } }, false), null, 'nothing is rewritten when pwsh was never wanted');
|
|
30
|
+
const edited = { profiles: { list: [{ guid: 'other' }, { guid: PWSH_PROFILE_GUID.toUpperCase(), name: 'My pwsh', fontSize: 14 }] } };
|
|
31
|
+
const hidden = withPwshProfile(edited, false)?.profiles;
|
|
32
|
+
t.equal({ hidden: hidden?.list[1].hidden, name: hidden?.list[1].name, fontSize: hidden?.list[1].fontSize, count: hidden?.list.length }, { hidden: true, name: 'My pwsh', fontSize: 14, count: 2 }, 'turning pwsh off hides the profile and keeps the user\'s edits');
|
|
33
|
+
const oldForm = withPwshProfile({ profiles: [{ guid: 'a' }] }, true)?.profiles;
|
|
34
|
+
t.equal(oldForm.list.length, 2, 'the old array form of "profiles" works');
|
|
35
|
+
t.section('Windows Terminal settings.json on disk (JSONC, temp copy)');
|
|
36
|
+
const data = t.at('wt-data');
|
|
37
|
+
const settings = t.write(path.join(data, 'tools', 'terminal', 'settings', 'settings.json'), '// edited in the sandbox\n{ "theme": "light", "profiles": { "list": [{ "guid": "{x}", }] } }');
|
|
38
|
+
const read = () => JSON.parse(fs.readFileSync(settings, 'utf8'));
|
|
39
|
+
syncPwshProfile(data, true);
|
|
40
|
+
const untouched = fs.readFileSync(settings, 'utf8');
|
|
41
|
+
t.check(untouched.startsWith('// edited'), 'untouched until pwsh is installed (comments and trailing commas survive)');
|
|
42
|
+
t.write(path.join(data, 'tools', 'pwsh', 'pwsh.exe'), 'MZ');
|
|
43
|
+
syncPwshProfile(data, true);
|
|
44
|
+
const added = read();
|
|
45
|
+
t.equal(added.theme, 'light', 'once pwsh is installed the profile is added and the user\'s settings are kept');
|
|
46
|
+
t.equal(added.profiles.list.map((p) => p.guid), ['{x}', PWSH_PROFILE_GUID], 'the profile is added after the existing ones');
|
|
47
|
+
syncPwshProfile(data, false);
|
|
48
|
+
t.equal(read().profiles.list[1].hidden, true, 'the profile is hidden when pwsh is turned off');
|
|
49
|
+
t.write(settings, '{ not json');
|
|
50
|
+
syncPwshProfile(data, true);
|
|
51
|
+
t.equal(fs.readFileSync(settings, 'utf8'), '{ not json', 'an unreadable settings file is left alone');
|
|
52
|
+
},
|
|
53
|
+
};
|