windows-development-sandbox 1.4.0 → 1.4.3
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/.sandbox-config.example.json +2 -1
- package/config.example.json +4 -1
- package/dist/api.js +27 -16
- package/dist/cli/args.d.ts +4 -6
- package/dist/cli/args.js +67 -34
- package/dist/cli/argv.d.ts +9 -0
- package/dist/cli/argv.js +22 -0
- package/dist/cli/commands/accounts.d.ts +1 -1
- package/dist/cli/commands/accounts.js +42 -27
- package/dist/cli/commands/agent-commands.d.ts +3 -3
- package/dist/cli/commands/agent-commands.js +27 -18
- package/dist/cli/commands/context.d.ts +9 -11
- package/dist/cli/commands/context.js +35 -32
- package/dist/cli/commands/data/clean.d.ts +2 -2
- package/dist/cli/commands/data/clean.js +27 -11
- package/dist/cli/commands/data/collect.d.ts +6 -3
- package/dist/cli/commands/data/collect.js +46 -15
- package/dist/cli/commands/data/index.d.ts +2 -2
- package/dist/cli/commands/data/index.js +30 -12
- package/dist/cli/commands/data/remove.d.ts +1 -1
- package/dist/cli/commands/data/remove.js +4 -4
- package/dist/cli/commands/index.d.ts +5 -4
- package/dist/cli/commands/index.js +5 -4
- package/dist/cli/commands/launch/add-root.d.ts +7 -0
- package/dist/cli/commands/launch/add-root.js +64 -0
- package/dist/cli/commands/launch/boot-progress.d.ts +7 -0
- package/dist/cli/commands/launch/boot-progress.js +48 -0
- package/dist/cli/commands/launch/boot-wants.d.ts +11 -0
- package/dist/cli/commands/launch/boot-wants.js +48 -0
- package/dist/cli/commands/launch/first-start.d.ts +10 -0
- package/dist/cli/commands/launch/first-start.js +53 -0
- package/dist/cli/commands/launch/index.d.ts +6 -0
- package/dist/cli/commands/launch/index.js +6 -0
- package/dist/cli/commands/launch/launch.d.ts +8 -0
- package/dist/cli/commands/launch/launch.js +211 -0
- package/dist/cli/commands/launch/prepare.d.ts +23 -0
- package/dist/cli/commands/launch/prepare.js +109 -0
- package/dist/cli/commands/launch/running.d.ts +45 -0
- package/dist/cli/commands/launch/running.js +218 -0
- package/dist/cli/commands/launch/summary.d.ts +8 -0
- package/dist/cli/commands/launch/summary.js +98 -0
- package/dist/cli/commands/maintenance/audit.d.ts +3 -0
- package/dist/cli/commands/maintenance/audit.js +58 -0
- package/dist/cli/commands/maintenance/clean.d.ts +2 -0
- package/dist/cli/commands/maintenance/clean.js +10 -0
- package/dist/cli/commands/maintenance/config.d.ts +2 -0
- package/dist/cli/commands/maintenance/config.js +145 -0
- package/dist/cli/commands/maintenance/doctor.d.ts +2 -0
- package/dist/cli/commands/maintenance/doctor.js +52 -0
- package/dist/cli/commands/maintenance/host-claude.d.ts +2 -0
- package/dist/cli/commands/maintenance/host-claude.js +4 -0
- package/dist/cli/commands/maintenance/index.d.ts +8 -0
- package/dist/cli/commands/maintenance/index.js +9 -0
- package/dist/cli/commands/maintenance/logs.d.ts +2 -0
- package/dist/cli/commands/maintenance/logs.js +44 -0
- package/dist/cli/commands/maintenance/sync.d.ts +2 -0
- package/dist/cli/commands/maintenance/sync.js +12 -0
- package/dist/cli/commands/maintenance/watch.d.ts +3 -0
- package/dist/cli/commands/maintenance/watch.js +6 -0
- package/dist/cli/commands/projects/describe-sessions.d.ts +3 -0
- package/dist/cli/commands/projects/describe-sessions.js +15 -0
- package/dist/cli/commands/projects/here.d.ts +38 -0
- package/dist/cli/commands/projects/here.js +145 -0
- package/dist/cli/commands/projects/index.d.ts +4 -0
- package/dist/cli/commands/projects/index.js +4 -0
- package/dist/cli/commands/projects/projects.d.ts +14 -0
- package/dist/cli/commands/projects/projects.js +213 -0
- package/dist/cli/commands/projects/restart.d.ts +15 -0
- package/dist/cli/commands/projects/restart.js +149 -0
- package/dist/cli/commands/registry.d.ts +3 -0
- package/dist/cli/commands/registry.js +34 -0
- package/dist/cli/commands/repair/checks.js +105 -29
- package/dist/cli/commands/repair/finders.d.ts +13 -10
- package/dist/cli/commands/repair/finders.js +63 -43
- package/dist/cli/commands/repair/index.d.ts +4 -4
- package/dist/cli/commands/repair/index.js +47 -21
- package/dist/cli/commands/repair/types.d.ts +2 -2
- package/dist/cli/commands/repair/types.js +7 -2
- package/dist/cli/commands/sessions/attach.d.ts +2 -0
- package/dist/cli/commands/sessions/attach.js +45 -0
- package/dist/cli/commands/sessions/control.d.ts +4 -0
- package/dist/cli/commands/sessions/control.js +62 -0
- package/dist/cli/commands/sessions/exec.d.ts +6 -0
- package/dist/cli/commands/sessions/exec.js +72 -0
- package/dist/cli/commands/sessions/index.d.ts +6 -0
- package/dist/cli/commands/sessions/index.js +9 -0
- package/dist/cli/commands/sessions/list.d.ts +15 -0
- package/dist/cli/commands/sessions/list.js +65 -0
- package/dist/cli/commands/sessions/status.d.ts +2 -0
- package/dist/cli/commands/sessions/status.js +153 -0
- package/dist/cli/commands/sessions/window.d.ts +3 -0
- package/dist/cli/commands/sessions/window.js +18 -0
- package/dist/cli/commands/setup/checks.d.ts +4 -4
- package/dist/cli/commands/setup/checks.js +36 -19
- package/dist/cli/commands/setup/facts.d.ts +6 -6
- package/dist/cli/commands/setup/facts.js +23 -11
- package/dist/cli/commands/setup/index.d.ts +1 -1
- package/dist/cli/commands/setup/index.js +25 -12
- package/dist/cli/commands/user-config.d.ts +5 -5
- package/dist/cli/commands/user-config.js +14 -12
- package/dist/cli/history.d.ts +5 -4
- package/dist/cli/history.js +23 -11
- package/dist/cli/index.d.ts +4 -14
- package/dist/cli/index.js +27 -77
- package/dist/cli/manifest.d.ts +464 -10
- package/dist/cli/manifest.js +328 -54
- package/dist/cli/menu/apps.d.ts +7 -5
- package/dist/cli/menu/apps.js +64 -16
- package/dist/cli/menu/command-fields.d.ts +15 -0
- package/dist/cli/menu/command-fields.js +23 -0
- package/dist/cli/menu/command-form.d.ts +3 -5
- package/dist/cli/menu/command-form.js +116 -48
- package/dist/cli/menu/home.d.ts +22 -0
- package/dist/cli/menu/home.js +72 -0
- package/dist/cli/menu/index.d.ts +2 -24
- package/dist/cli/menu/index.js +4 -178
- package/dist/cli/menu/menu.d.ts +23 -0
- package/dist/cli/menu/menu.js +185 -0
- package/dist/cli/menu/settings/categories.d.ts +2 -2
- package/dist/cli/menu/settings/categories.js +123 -20
- package/dist/cli/menu/settings/collections/collection-editor.d.ts +23 -0
- package/dist/cli/menu/settings/collections/collection-editor.js +89 -0
- package/dist/cli/menu/settings/collections/map-editor.d.ts +10 -0
- package/dist/cli/menu/settings/collections/map-editor.js +34 -0
- package/dist/cli/menu/settings/collections/object-list-editor.d.ts +10 -0
- package/dist/cli/menu/settings/collections/object-list-editor.js +23 -0
- package/dist/cli/menu/settings/collections/object-map-editor.d.ts +10 -0
- package/dist/cli/menu/settings/collections/object-map-editor.js +35 -0
- package/dist/cli/menu/settings/collections/string-list-editor.d.ts +12 -0
- package/dist/cli/menu/settings/collections/string-list-editor.js +39 -0
- package/dist/cli/menu/settings/config-file.d.ts +2 -2
- package/dist/cli/menu/settings/config-file.js +42 -19
- package/dist/cli/menu/settings/editor-actions.d.ts +2 -0
- package/dist/cli/menu/settings/editor-actions.js +2 -0
- package/dist/cli/menu/settings/format.d.ts +5 -0
- package/dist/cli/menu/settings/format.js +39 -0
- package/dist/cli/menu/settings/index.d.ts +1 -29
- package/dist/cli/menu/settings/index.js +1 -133
- package/dist/cli/menu/settings/object-editor.d.ts +12 -0
- package/dist/cli/menu/settings/object-editor.js +86 -0
- package/dist/cli/menu/settings/schema-node.d.ts +3 -1
- package/dist/cli/menu/settings/schema-node.js +71 -24
- package/dist/cli/menu/settings/settings-editor.d.ts +30 -0
- package/dist/cli/menu/settings/settings-editor.js +176 -0
- package/dist/cli/menu/settings/{editors.d.ts → value-editor.d.ts} +2 -13
- package/dist/cli/menu/settings/value-editor.js +137 -0
- package/dist/cli/menu/several.d.ts +4 -4
- package/dist/cli/menu/several.js +61 -20
- package/dist/cli/{colors.d.ts → output/colors.d.ts} +8 -8
- package/dist/cli/{colors.js → output/colors.js} +32 -14
- package/dist/cli/output/index.d.ts +3 -0
- package/dist/cli/output/index.js +3 -0
- package/dist/cli/output/print.d.ts +5 -0
- package/dist/cli/output/print.js +14 -0
- package/dist/cli/output/progress.d.ts +24 -0
- package/dist/cli/output/progress.js +124 -0
- package/dist/cli/report.d.ts +2 -0
- package/dist/cli/report.js +20 -0
- package/dist/cli/tui/app.d.ts +6 -16
- package/dist/cli/tui/app.js +28 -8
- package/dist/cli/tui/dialogs/confirm-screen.d.ts +20 -0
- package/dist/cli/tui/dialogs/confirm-screen.js +50 -0
- package/dist/cli/tui/dialogs/message-screen.d.ts +17 -0
- package/dist/cli/tui/dialogs/message-screen.js +55 -0
- package/dist/cli/tui/dialogs/paragraphs.d.ts +2 -0
- package/dist/cli/tui/dialogs/paragraphs.js +5 -0
- package/dist/cli/tui/dialogs/text-screen.d.ts +26 -0
- package/dist/cli/tui/dialogs/text-screen.js +107 -0
- package/dist/cli/tui/frame.js +3 -1
- package/dist/cli/tui/index.d.ts +7 -3
- package/dist/cli/tui/index.js +4 -2
- package/dist/cli/tui/list/list-screen.d.ts +29 -0
- package/dist/cli/tui/{list-screen.js → list/list-screen.js} +86 -23
- package/dist/cli/tui/{list-screen.d.ts → list/list-types.d.ts} +0 -28
- package/dist/cli/tui/screen.d.ts +14 -0
- package/dist/cli/tui/terminal.js +34 -10
- package/dist/cli/tui/text.d.ts +2 -1
- package/dist/cli/tui/text.js +37 -7
- package/dist/cli/tui/theme.js +27 -9
- package/dist/cli/validate.d.ts +8 -8
- package/dist/cli/validate.js +32 -21
- package/dist/core/config/defaults.d.ts +2 -0
- package/dist/core/config/defaults.js +203 -0
- package/dist/core/config/index.d.ts +2 -0
- package/dist/core/config/index.js +3 -0
- package/dist/core/{config.d.ts → config/loader.d.ts} +1 -2
- package/dist/core/config/loader.js +47 -0
- package/dist/core/{detect-databases.js → detect/databases.js} +111 -23
- package/dist/core/detect/index.d.ts +4 -0
- package/dist/core/detect/index.js +4 -0
- package/dist/core/{detect-pwsh.d.ts → detect/pwsh.d.ts} +1 -1
- package/dist/core/{detect-pwsh.js → detect/pwsh.js} +25 -11
- package/dist/core/{detect-toolchains.d.ts → detect/toolchains.d.ts} +1 -1
- package/dist/core/{detect-toolchains.js → detect/toolchains.js} +42 -5
- package/dist/{guest/toolchains → core/detect}/versions.js +28 -12
- package/dist/core/disk.d.ts +2 -0
- package/dist/core/disk.js +46 -3
- package/dist/core/local-config/boot-wants.d.ts +45 -0
- package/dist/core/local-config/boot-wants.js +120 -0
- package/dist/core/local-config/file.d.ts +3 -0
- package/dist/core/local-config/file.js +16 -0
- package/dist/core/local-config/index.d.ts +5 -0
- package/dist/core/local-config/index.js +7 -0
- package/dist/core/{local-config.d.ts → local-config/overrides.d.ts} +11 -11
- package/dist/core/{local-config.js → local-config/overrides.js} +53 -54
- package/dist/core/{project-policy.d.ts → local-config/policy.d.ts} +7 -3
- package/dist/core/{project-policy.js → local-config/policy.js} +16 -6
- package/dist/core/local-config/trust.d.ts +13 -0
- package/dist/core/local-config/trust.js +43 -0
- package/dist/core/package-info.d.ts +4 -0
- package/dist/core/package-info.js +13 -0
- package/dist/core/run/guest-workspace.d.ts +23 -0
- package/dist/core/run/guest-workspace.js +47 -0
- package/dist/core/run/index.d.ts +3 -0
- package/dist/core/run/index.js +3 -0
- package/dist/core/run/resolve-run.d.ts +3 -0
- package/dist/core/run/resolve-run.js +202 -0
- package/dist/core/run/versions.d.ts +13 -0
- package/dist/core/run/versions.js +65 -0
- package/dist/core/safe-paths.js +17 -5
- package/dist/core/schema/apps.d.ts +4 -4
- package/dist/core/schema/apps.js +55 -21
- package/dist/core/schema/common.d.ts +13 -10
- package/dist/core/schema/common.js +16 -10
- package/dist/core/schema/config.d.ts +18 -12
- package/dist/core/schema/config.js +78 -53
- package/dist/core/schema/databases.d.ts +4 -3
- package/dist/core/schema/databases.js +16 -12
- package/dist/core/schema/harness.d.ts +1 -1
- package/dist/core/schema/harness.js +17 -7
- package/dist/core/schema/index.d.ts +6 -0
- package/dist/core/schema/index.js +8 -0
- package/dist/core/schema/json-schema.js +10 -5
- package/dist/core/schema/profile.d.ts +4 -4
- package/dist/core/schema/profile.js +37 -17
- package/dist/core/schema/projects.d.ts +2 -1
- package/dist/core/schema/projects.js +16 -5
- package/dist/core/schema/sandbox.d.ts +12 -12
- package/dist/core/schema/sandbox.js +101 -37
- package/dist/core/schema/toolchains.d.ts +6 -1
- package/dist/core/schema/toolchains.js +84 -34
- package/dist/core/types.d.ts +36 -9
- package/dist/core/util/errors.d.ts +8 -0
- package/dist/core/util/errors.js +14 -0
- package/dist/core/util/fs.d.ts +8 -0
- package/dist/core/util/fs.js +40 -0
- package/dist/core/util/index.d.ts +7 -0
- package/dist/core/util/index.js +7 -0
- package/dist/core/util/jsonc.d.ts +6 -0
- package/dist/core/util/jsonc.js +25 -0
- package/dist/core/util/links.d.ts +10 -0
- package/dist/core/util/links.js +39 -0
- package/dist/core/util/paths.d.ts +7 -0
- package/dist/core/util/paths.js +33 -0
- package/dist/core/util/process.d.ts +15 -0
- package/dist/core/util/process.js +54 -0
- package/dist/core/util/text.d.ts +8 -0
- package/dist/core/util/text.js +8 -0
- package/dist/guest/{setup/agents.js → agents/agent-installer.js} +24 -4
- package/dist/guest/apps/after-install.d.ts +3 -0
- package/dist/guest/apps/after-install.js +47 -0
- package/dist/guest/apps/app-installer.d.ts +22 -0
- package/dist/guest/apps/app-installer.js +116 -0
- package/dist/guest/apps/find-exe.d.ts +5 -0
- package/dist/guest/apps/find-exe.js +41 -0
- package/dist/guest/apps/index.d.ts +3 -10
- package/dist/guest/apps/index.js +6 -206
- package/dist/guest/apps/resolvers.js +37 -9
- package/dist/guest/apps/shortcuts.d.ts +6 -0
- package/dist/guest/apps/shortcuts.js +28 -0
- package/dist/guest/apps/sources.d.ts +4 -0
- package/dist/guest/apps/sources.js +17 -0
- package/dist/guest/apps/unpack.d.ts +3 -0
- package/dist/guest/apps/unpack.js +47 -0
- package/dist/guest/{audit-parse.js → audit/parse.js} +39 -3
- package/dist/guest/{audit.d.ts → audit/process-audit.d.ts} +3 -1
- package/dist/guest/{audit.js → audit/process-audit.js} +33 -8
- package/dist/guest/boot/boot-env.d.ts +4 -0
- package/dist/guest/{boot-env.js → boot/boot-env.js} +7 -5
- package/dist/guest/boot/boot.d.ts +1 -0
- package/dist/guest/{main.js → boot/boot.js} +100 -50
- package/dist/guest/{guide.js → boot/guide.js} +32 -7
- package/dist/guest/{project-env.d.ts → boot/project-env.d.ts} +3 -3
- package/dist/guest/{project-env.js → boot/project-env.js} +12 -4
- package/dist/guest/boot/project-status.d.ts +5 -0
- package/dist/guest/boot/project-status.js +28 -0
- package/dist/guest/daemon/daemon.d.ts +1 -0
- package/dist/guest/daemon/daemon.js +51 -0
- package/dist/guest/daemon/exec.js +18 -6
- package/dist/guest/daemon/{shutdown.js → idle-shutdown.js} +5 -4
- package/dist/guest/daemon/{project.d.ts → project-provisioner.d.ts} +3 -3
- package/dist/guest/daemon/{project.js → project-provisioner.js} +60 -22
- package/dist/guest/daemon/relays.js +5 -3
- package/dist/guest/daemon/{session.js → sessions.js} +84 -24
- package/dist/guest/daemon/state.d.ts +4 -1
- package/dist/guest/daemon/state.js +34 -20
- package/dist/guest/databases/database-server.d.ts +13 -0
- package/dist/guest/databases/database-server.js +35 -0
- package/dist/guest/databases/dynamodb.d.ts +12 -0
- package/dist/guest/databases/dynamodb.js +81 -0
- package/dist/guest/databases/index.d.ts +2 -0
- package/dist/guest/databases/index.js +2 -0
- package/dist/guest/databases/mongodb.d.ts +7 -0
- package/dist/guest/databases/mongodb.js +46 -0
- package/dist/guest/databases/mysql.d.ts +7 -0
- package/dist/guest/databases/mysql.js +59 -0
- package/dist/guest/databases/names.d.ts +5 -0
- package/dist/guest/databases/names.js +8 -0
- package/dist/guest/databases/postgres.d.ts +9 -0
- package/dist/guest/databases/postgres.js +85 -0
- package/dist/guest/databases/redis.d.ts +7 -0
- package/dist/guest/databases/redis.js +25 -0
- package/dist/guest/databases/registry.d.ts +5 -0
- package/dist/guest/databases/registry.js +51 -0
- package/dist/guest/databases/sbx-db.d.ts +1 -0
- package/dist/guest/{db.js → databases/sbx-db.js} +13 -13
- package/dist/guest/{toolchains/databases → databases}/server.d.ts +5 -5
- package/dist/guest/{toolchains/databases → databases}/server.js +18 -13
- package/dist/guest/entries/daemon.js +16 -0
- package/dist/guest/entries/db.js +10 -0
- package/dist/guest/entries/gitguard.js +20 -0
- package/dist/guest/entries/main.d.ts +1 -0
- package/dist/guest/entries/main.js +24 -0
- package/dist/guest/entries/netproxy.d.ts +1 -0
- package/dist/guest/entries/netproxy.js +7 -0
- package/dist/guest/entries/view.d.ts +1 -0
- package/dist/guest/entries/view.js +11 -0
- package/dist/guest/{gitguard.js → git/decision.js} +49 -26
- package/dist/guest/network/addresses.d.ts +2 -0
- package/dist/guest/network/addresses.js +6 -0
- package/dist/guest/{setup/network.d.ts → network/allow-only.d.ts} +0 -10
- package/dist/guest/network/allow-only.js +84 -0
- package/dist/guest/network/firewall.d.ts +9 -0
- package/dist/guest/{setup/network.js → network/firewall.js} +58 -63
- package/dist/guest/network/proxy-server.d.ts +2 -0
- package/dist/guest/{netproxy.js → network/proxy-server.js} +37 -18
- package/dist/guest/{helpers.d.ts → runtime/csc.d.ts} +1 -1
- package/dist/guest/{helpers.js → runtime/csc.js} +7 -2
- package/dist/guest/runtime/fs.d.ts +2 -0
- package/dist/guest/runtime/fs.js +6 -0
- package/dist/guest/runtime/log.d.ts +3 -0
- package/dist/guest/runtime/log.js +22 -0
- package/dist/guest/runtime/paths.d.ts +13 -0
- package/dist/guest/runtime/paths.js +14 -0
- package/dist/guest/{ports.js → runtime/ports.js} +8 -2
- package/dist/guest/runtime/process.d.ts +15 -0
- package/dist/guest/runtime/process.js +59 -0
- package/dist/guest/{project-context.js → runtime/project-context.js} +1 -1
- package/dist/guest/runtime/session.d.ts +5 -0
- package/dist/guest/runtime/session.js +10 -0
- package/dist/guest/runtime/status.d.ts +7 -0
- package/dist/guest/runtime/status.js +57 -0
- package/dist/guest/{cmdline.js → sessions/cmdline.js} +10 -4
- package/dist/guest/{ptyhost.js → sessions/pty-host.js} +12 -5
- package/dist/guest/{view.js → sessions/viewer.js} +8 -11
- package/dist/guest/setup/claude-mem.d.ts +10 -0
- package/dist/guest/setup/{claude.js → claude-mem.js} +18 -78
- package/dist/guest/setup/{claude.d.ts → claude-profile.d.ts} +0 -10
- package/dist/guest/setup/claude-profile.js +89 -0
- package/dist/guest/setup/desktop.d.ts +2 -0
- package/dist/guest/setup/desktop.js +32 -0
- package/dist/guest/setup/environment.js +28 -5
- package/dist/guest/setup/{user.d.ts → git-identity.d.ts} +0 -2
- package/dist/guest/setup/git-identity.js +34 -0
- package/dist/guest/{gitrules.d.ts → setup/git-rules.d.ts} +1 -1
- package/dist/guest/setup/git-rules.js +50 -0
- package/dist/guest/setup/hooks.js +22 -5
- package/dist/guest/setup/{policy.js → managed-policy.js} +2 -2
- package/dist/guest/toolchains/catalogue.d.ts +4 -4
- package/dist/guest/toolchains/catalogue.js +30 -7
- package/dist/guest/toolchains/detect.d.ts +12 -0
- package/dist/guest/toolchains/detect.js +54 -0
- package/dist/guest/toolchains/index.d.ts +3 -17
- package/dist/guest/toolchains/index.js +1 -80
- package/dist/guest/toolchains/install.d.ts +20 -0
- package/dist/guest/toolchains/install.js +29 -0
- package/dist/guest/toolchains/languages/go.d.ts +3 -0
- package/dist/guest/toolchains/{go.js → languages/go.js} +27 -9
- package/dist/guest/toolchains/languages/java.d.ts +8 -0
- package/dist/guest/toolchains/{java.js → languages/java.js} +57 -18
- package/dist/guest/toolchains/languages/node.d.ts +3 -0
- package/dist/guest/toolchains/{node.js → languages/node.js} +51 -18
- package/dist/guest/toolchains/languages/php.d.ts +3 -0
- package/dist/guest/toolchains/{scripting → languages}/php.js +36 -11
- package/dist/guest/toolchains/languages/python-tools.d.ts +3 -0
- package/dist/guest/toolchains/languages/python-tools.js +12 -0
- package/dist/guest/toolchains/languages/python.d.ts +3 -0
- package/dist/guest/toolchains/{python.js → languages/python.js} +29 -16
- package/dist/guest/toolchains/languages/ruby.d.ts +3 -0
- package/dist/guest/toolchains/{scripting → languages}/ruby.js +28 -10
- package/dist/guest/toolchains/leftovers.d.ts +1 -1
- package/dist/guest/toolchains/leftovers.js +13 -11
- package/dist/guest/toolchains/managers.d.ts +6 -6
- package/dist/guest/toolchains/managers.js +38 -17
- package/dist/guest/toolchains/native/binstall.d.ts +3 -2
- package/dist/guest/toolchains/native/binstall.js +20 -8
- package/dist/guest/toolchains/native/cpp.d.ts +2 -2
- package/dist/guest/toolchains/native/cpp.js +23 -8
- package/dist/guest/toolchains/native/dotnet.d.ts +5 -3
- package/dist/guest/toolchains/native/dotnet.js +72 -24
- package/dist/guest/toolchains/native/mesa.d.ts +2 -2
- package/dist/guest/toolchains/native/mesa.js +27 -10
- package/dist/guest/toolchains/native/msvc/environment.d.ts +4 -4
- package/dist/guest/toolchains/native/msvc/environment.js +30 -16
- package/dist/guest/toolchains/native/msvc/index.d.ts +3 -3
- package/dist/guest/toolchains/native/msvc/index.js +10 -8
- package/dist/guest/toolchains/native/msvc/packages.d.ts +1 -1
- package/dist/guest/toolchains/native/msvc/packages.js +69 -23
- package/dist/guest/toolchains/native/msvc/tree.d.ts +6 -6
- package/dist/guest/toolchains/native/msvc/tree.js +15 -9
- package/dist/guest/toolchains/native/rust-extras.d.ts +23 -0
- package/dist/guest/toolchains/native/rust-extras.js +100 -0
- package/dist/guest/toolchains/native/rust.d.ts +2 -2
- package/dist/guest/toolchains/native/rust.js +41 -10
- package/dist/guest/toolchains/{scripting → native}/vcruntime.d.ts +2 -2
- package/dist/guest/toolchains/{scripting → native}/vcruntime.js +17 -7
- package/dist/guest/toolchains/package-ledger.d.ts +17 -0
- package/dist/guest/toolchains/package-ledger.js +54 -0
- package/dist/guest/toolchains/plan.d.ts +3 -24
- package/dist/guest/toolchains/plan.js +99 -111
- package/dist/guest/toolchains/runtimes.d.ts +6 -6
- package/dist/guest/toolchains/runtimes.js +31 -13
- package/dist/guest/toolchains/scheduler.d.ts +22 -0
- package/dist/guest/toolchains/scheduler.js +123 -0
- package/dist/guest/toolchains/setup.d.ts +10 -0
- package/dist/guest/toolchains/setup.js +22 -0
- package/dist/guest/toolchains/state-file.d.ts +3 -0
- package/dist/guest/toolchains/state-file.js +10 -0
- package/dist/guest/toolchains/step.d.ts +24 -0
- package/dist/guest/toolchains/step.js +1 -0
- package/dist/guest/toolchains/tool-env.d.ts +12 -0
- package/dist/guest/toolchains/tool-env.js +16 -0
- package/dist/guest/toolchains/tools/cli.d.ts +10 -0
- package/dist/guest/toolchains/{cli.js → tools/cli.js} +35 -15
- package/dist/guest/toolchains/tools/git.d.ts +3 -0
- package/dist/guest/toolchains/{git.js → tools/git.js} +38 -15
- package/dist/guest/toolchains/tools/pwsh.d.ts +4 -0
- package/dist/guest/toolchains/{pwsh.js → tools/pwsh.js} +14 -7
- package/dist/guest/toolchains/{vscode-profile.d.ts → tools/vscode-profile.d.ts} +6 -6
- package/dist/guest/toolchains/{vscode-profile.js → tools/vscode-profile.js} +28 -12
- package/dist/guest/toolchains/{vscode.d.ts → tools/vscode.d.ts} +6 -6
- package/dist/guest/toolchains/{vscode.js → tools/vscode.js} +67 -21
- package/dist/guest/toolchains/version-cache.d.ts +16 -0
- package/dist/guest/toolchains/version-cache.js +67 -0
- package/dist/host/agent-commands/commands.d.ts +13 -0
- package/dist/host/agent-commands/commands.js +33 -0
- package/dist/host/agent-commands/forwarders.d.ts +7 -0
- package/dist/host/agent-commands/forwarders.js +31 -0
- package/dist/host/agent-commands/index.d.ts +4 -0
- package/dist/host/agent-commands/index.js +4 -0
- package/dist/host/agent-commands/reconcile.d.ts +12 -0
- package/dist/host/agent-commands/reconcile.js +69 -0
- package/dist/host/agent-commands/user-path.d.ts +2 -0
- package/dist/host/agent-commands/user-path.js +33 -0
- package/dist/host/audit/collect.d.ts +2 -2
- package/dist/host/audit/collect.js +59 -22
- package/dist/host/audit/log.d.ts +2 -2
- package/dist/host/audit/log.js +24 -8
- package/dist/host/{attach.d.ts → channel/attach.d.ts} +2 -2
- package/dist/host/{attach.js → channel/attach.js} +33 -15
- package/dist/host/channel/channel.d.ts +51 -0
- package/dist/host/channel/channel.js +196 -0
- package/dist/host/channel/index.d.ts +2 -0
- package/dist/host/channel/index.js +2 -0
- package/dist/host/guard/agent-files.d.ts +7 -0
- package/dist/host/guard/agent-files.js +103 -0
- package/dist/host/guard/commands.d.ts +10 -0
- package/dist/host/guard/commands.js +123 -0
- package/dist/host/guard/file-hash.d.ts +4 -0
- package/dist/host/guard/file-hash.js +37 -0
- package/dist/host/guard/git-config.d.ts +5 -0
- package/dist/host/guard/git-config.js +62 -0
- package/dist/host/guard/git-dirs.d.ts +12 -0
- package/dist/host/guard/git-dirs.js +53 -0
- package/dist/host/guard/index.d.ts +5 -0
- package/dist/host/guard/index.js +4 -0
- package/dist/host/guard/mark-of-the-web.d.ts +8 -0
- package/dist/host/guard/mark-of-the-web.js +74 -0
- package/dist/host/guard/nested-repos.d.ts +14 -0
- package/dist/host/guard/nested-repos.js +88 -0
- package/dist/host/guard/quarantine.d.ts +3 -0
- package/dist/host/guard/quarantine.js +24 -0
- package/dist/host/guard/repo-guard.d.ts +10 -0
- package/dist/host/guard/repo-guard.js +36 -0
- package/dist/host/guard/store.d.ts +40 -0
- package/dist/host/guard/store.js +145 -0
- package/dist/host/guard/types.d.ts +27 -0
- package/dist/host/guard/types.js +3 -0
- package/dist/host/guard/watch-state.d.ts +9 -0
- package/dist/host/guard/watch-state.js +26 -0
- package/dist/host/launch/boot-projects.d.ts +17 -0
- package/dist/host/launch/{projects.js → boot-projects.js} +27 -12
- package/dist/host/{database-plan.d.ts → launch/database-plan.d.ts} +5 -5
- package/dist/host/{database-plan.js → launch/database-plan.js} +24 -13
- package/dist/host/launch/generate.d.ts +4 -0
- package/dist/host/launch/generate.js +77 -0
- package/dist/host/launch/index.d.ts +10 -0
- package/dist/host/launch/index.js +10 -0
- package/dist/host/launch/mappings.d.ts +7 -2
- package/dist/host/launch/mappings.js +83 -24
- package/dist/host/launch/pc-scan.d.ts +5 -0
- package/dist/host/{pc-scan.js → launch/pc-scan.js} +20 -13
- package/dist/host/launch/project-scan.d.ts +7 -0
- package/dist/host/{project-scan.js → launch/project-scan.js} +29 -21
- package/dist/host/launch/session-file.d.ts +23 -0
- package/dist/host/launch/session-file.js +73 -0
- package/dist/host/launch/stage.d.ts +5 -5
- package/dist/host/launch/stage.js +14 -13
- package/dist/host/launch/toolchains.d.ts +4 -0
- package/dist/host/launch/toolchains.js +11 -0
- package/dist/host/launch/{wsb.d.ts → wsb-file.d.ts} +4 -2
- package/dist/host/launch/wsb-file.js +56 -0
- package/dist/host/life/crash-report.d.ts +8 -0
- package/dist/host/life/crash-report.js +87 -0
- package/dist/host/life/index.d.ts +6 -0
- package/dist/host/life/index.js +6 -0
- package/dist/host/life/keep-awake.d.ts +10 -0
- package/dist/host/life/keep-awake.js +29 -0
- package/dist/host/life/life-record.d.ts +48 -0
- package/dist/host/life/life-record.js +76 -0
- package/dist/host/life/stop-events.d.ts +27 -0
- package/dist/host/life/stop-events.js +96 -0
- package/dist/host/life/stop-warning.d.ts +4 -0
- package/dist/host/life/stop-warning.js +25 -0
- package/dist/host/life/windows-update.d.ts +3 -0
- package/dist/host/life/windows-update.js +11 -0
- package/dist/host/native.d.ts +4 -0
- package/dist/host/native.js +11 -0
- package/dist/host/network/index.d.ts +1 -0
- package/dist/host/network/index.js +1 -0
- package/dist/host/{port-forward.d.ts → network/port-forward.d.ts} +1 -1
- package/dist/host/{port-forward.js → network/port-forward.js} +16 -10
- package/dist/host/profile/accounts.d.ts +37 -0
- package/dist/host/profile/accounts.js +146 -0
- package/dist/host/profile/claude-login.d.ts +22 -0
- package/dist/host/profile/claude-login.js +57 -0
- package/dist/host/{claude-profile.d.ts → profile/claude-profile.d.ts} +9 -9
- package/dist/host/{claude-profile.js → profile/claude-profile.js} +32 -22
- package/dist/host/profile/index.d.ts +7 -0
- package/dist/host/profile/index.js +7 -0
- package/dist/host/profile/personalize.d.ts +2 -0
- package/dist/host/profile/personalize.js +127 -0
- package/dist/host/profile/reg-file.d.ts +8 -0
- package/dist/host/profile/reg-file.js +45 -0
- package/dist/host/profile/secret-files.d.ts +2 -0
- package/dist/host/profile/secret-files.js +25 -0
- package/dist/host/profile/secret-patterns.d.ts +6 -0
- package/dist/host/profile/secret-patterns.js +128 -0
- package/dist/host/profile/secrets.d.ts +12 -0
- package/dist/host/profile/secrets.js +100 -0
- package/dist/host/projects/index.d.ts +4 -0
- package/dist/host/projects/index.js +4 -0
- package/dist/host/projects/join.d.ts +38 -0
- package/dist/host/projects/join.js +119 -0
- package/dist/host/projects/known.d.ts +28 -0
- package/dist/host/projects/known.js +55 -0
- package/dist/host/projects/mapper.d.ts +29 -0
- package/dist/host/projects/mapper.js +88 -0
- package/dist/host/projects/registry.d.ts +83 -0
- package/dist/host/projects/registry.js +136 -0
- package/dist/host/sandbox/doctor.d.ts +2 -0
- package/dist/host/sandbox/doctor.js +42 -0
- package/dist/host/sandbox/host-claude.d.ts +1 -0
- package/dist/host/sandbox/host-claude.js +26 -0
- package/dist/host/sandbox/index.d.ts +6 -0
- package/dist/host/sandbox/index.js +6 -0
- package/dist/host/{platform.d.ts → sandbox/platform.d.ts} +0 -5
- package/dist/host/sandbox/platform.js +60 -0
- package/dist/host/sandbox/probe.d.ts +3 -0
- package/dist/host/sandbox/probe.js +47 -0
- package/dist/host/{window.js → sandbox/window.js} +7 -5
- package/dist/host/{wsb.js → sandbox/wsb-cli.js} +31 -8
- package/dist/host/{cleanup.js → storage/cleanup.js} +27 -12
- package/dist/host/storage/index.d.ts +2 -0
- package/dist/host/storage/index.js +2 -0
- package/dist/host/storage/state-files.d.ts +4 -0
- package/dist/host/storage/state-files.js +10 -0
- package/dist/host/test-guard.js +1 -1
- package/dist/host/tools/conpty.d.ts +8 -0
- package/dist/host/tools/conpty.js +58 -0
- package/dist/host/tools/index.d.ts +2 -0
- package/dist/host/tools/index.js +2 -0
- package/dist/host/{terminal.d.ts → tools/windows-terminal.d.ts} +2 -10
- package/dist/host/{terminal.js → tools/windows-terminal.js} +33 -57
- package/dist/host/workspace-view/active-views.d.ts +3 -0
- package/dist/host/workspace-view/active-views.js +22 -0
- package/dist/host/workspace-view/index.d.ts +2 -18
- package/dist/host/workspace-view/index.js +2 -49
- package/dist/host/workspace-view/plan.d.ts +16 -0
- package/dist/host/workspace-view/plan.js +50 -0
- package/dist/host/workspace-view/rules.js +10 -3
- package/dist/host/workspace-view/view-state.d.ts +10 -0
- package/dist/host/workspace-view/view-state.js +31 -0
- package/dist/host/workspace-view/view.d.ts +1 -0
- package/dist/host/workspace-view/view.js +51 -55
- package/dist/runtime/daemon.js +4232 -1918
- package/dist/runtime/db.js +2145 -830
- package/dist/runtime/gitguard.js +29 -11
- package/dist/runtime/main.js +4760 -2155
- package/dist/runtime/netproxy.js +1654 -418
- package/dist/runtime/view.js +1515 -453
- package/dist/selftest/accounts.test.d.ts +1 -1
- package/dist/selftest/accounts.test.js +20 -17
- package/dist/selftest/agent-commands.test.d.ts +1 -1
- package/dist/selftest/agent-commands.test.js +9 -5
- package/dist/selftest/audit.test.d.ts +1 -1
- package/dist/selftest/audit.test.js +46 -13
- package/dist/selftest/channel.test.d.ts +1 -1
- package/dist/selftest/channel.test.js +91 -8
- package/dist/selftest/cli.test.d.ts +1 -1
- package/dist/selftest/cli.test.js +68 -16
- package/dist/selftest/cmdline.test.d.ts +1 -1
- package/dist/selftest/cmdline.test.js +36 -7
- package/dist/selftest/config.test.d.ts +1 -1
- package/dist/selftest/config.test.js +12 -5
- package/dist/selftest/data.test.d.ts +1 -1
- package/dist/selftest/data.test.js +35 -6
- package/dist/selftest/detect.test.d.ts +1 -1
- package/dist/selftest/detect.test.js +22 -9
- package/dist/selftest/generate.test.d.ts +1 -1
- package/dist/selftest/generate.test.js +33 -9
- package/dist/selftest/git-access.test.d.ts +1 -1
- package/dist/selftest/git-access.test.js +42 -4
- package/dist/selftest/guest-boot.test.d.ts +1 -1
- package/dist/selftest/guest-boot.test.js +25 -7
- package/dist/selftest/host-sim.test.d.ts +1 -1
- package/dist/selftest/host-sim.test.js +27 -3
- package/dist/selftest/hostile-input.test.d.ts +1 -1
- package/dist/selftest/hostile-input.test.js +5 -5
- package/dist/selftest/index.d.ts +1 -1
- package/dist/selftest/index.js +73 -16
- package/dist/selftest/layout.test.d.ts +2 -0
- package/dist/selftest/layout.test.js +131 -0
- package/dist/selftest/links.test.d.ts +1 -1
- package/dist/selftest/links.test.js +16 -11
- package/dist/selftest/live-daemon.test.d.ts +1 -1
- package/dist/selftest/live-daemon.test.js +20 -8
- package/dist/selftest/live-git.test.d.ts +1 -1
- package/dist/selftest/live-git.test.js +13 -4
- package/dist/selftest/live-network.test.d.ts +1 -1
- package/dist/selftest/live-network.test.js +24 -9
- package/dist/selftest/live-projects.test.d.ts +1 -1
- package/dist/selftest/live-projects.test.js +47 -20
- package/dist/selftest/live-terminal.test.d.ts +2 -0
- package/dist/selftest/live-terminal.test.js +195 -0
- package/dist/selftest/local-config.test.d.ts +1 -1
- package/dist/selftest/local-config.test.js +88 -15
- package/dist/selftest/mirror.test.d.ts +1 -1
- package/dist/selftest/mirror.test.js +118 -19
- package/dist/selftest/network.test.d.ts +1 -1
- package/dist/selftest/network.test.js +17 -8
- package/dist/selftest/personalization.test.d.ts +1 -1
- package/dist/selftest/personalization.test.js +12 -5
- package/dist/selftest/projects.test.d.ts +1 -1
- package/dist/selftest/projects.test.js +336 -72
- package/dist/selftest/repair.test.d.ts +1 -1
- package/dist/selftest/repair.test.js +17 -5
- package/dist/selftest/repo-guard.test.d.ts +1 -1
- package/dist/selftest/repo-guard.test.js +21 -20
- package/dist/selftest/secrets.test.d.ts +1 -1
- package/dist/selftest/secrets.test.js +57 -13
- package/dist/selftest/setup.test.d.ts +1 -1
- package/dist/selftest/setup.test.js +25 -5
- package/dist/selftest/{fixtures.d.ts → support/fixtures.d.ts} +7 -4
- package/dist/selftest/{fixtures.js → support/fixtures.js} +95 -17
- package/dist/selftest/{harness.js → support/harness.js} +24 -7
- package/dist/selftest/{live.d.ts → support/live.d.ts} +2 -2
- package/dist/selftest/{live.js → support/live.js} +34 -10
- package/dist/selftest/support/suite.js +1 -0
- package/dist/selftest/sync.test.d.ts +1 -1
- package/dist/selftest/sync.test.js +64 -26
- package/dist/selftest/test-guard.test.d.ts +1 -1
- package/dist/selftest/test-guard.test.js +43 -15
- package/dist/selftest/toolchains.test.d.ts +1 -1
- package/dist/selftest/toolchains.test.js +135 -36
- package/dist/selftest/workspace-view.test.d.ts +1 -1
- package/dist/selftest/workspace-view.test.js +48 -11
- package/dist/selftest/workspace.test.d.ts +1 -1
- package/dist/selftest/workspace.test.js +13 -4
- package/dist/shared/{apps.d.ts → apps/catalogue.d.ts} +1 -11
- package/dist/shared/apps/catalogue.js +768 -0
- package/dist/shared/apps/index.d.ts +2 -0
- package/dist/shared/apps/index.js +2 -0
- package/dist/shared/apps/selection.d.ts +11 -0
- package/dist/shared/apps/selection.js +40 -0
- package/dist/shared/channel/index.d.ts +2 -0
- package/dist/shared/channel/index.js +2 -0
- package/dist/shared/channel/run-dir.d.ts +30 -0
- package/dist/shared/channel/run-dir.js +84 -0
- package/dist/shared/{schema.d.ts → channel/schema.d.ts} +60 -19
- package/dist/shared/channel/schema.js +131 -0
- package/dist/shared/download/archive.d.ts +13 -0
- package/dist/shared/download/archive.js +57 -0
- package/dist/shared/download/downloader.d.ts +35 -0
- package/dist/shared/download/downloader.js +110 -0
- package/dist/shared/download/github.d.ts +16 -0
- package/dist/shared/download/github.js +74 -0
- package/dist/shared/download/http.d.ts +5 -0
- package/dist/shared/download/http.js +30 -0
- package/dist/shared/download/index.d.ts +5 -0
- package/dist/shared/download/index.js +5 -0
- package/dist/shared/download/spawn.d.ts +2 -0
- package/dist/shared/download/spawn.js +7 -0
- package/dist/shared/io/index.d.ts +3 -0
- package/dist/shared/io/index.js +3 -0
- package/dist/shared/io/json-file.d.ts +10 -0
- package/dist/shared/io/json-file.js +21 -0
- package/dist/shared/io/json.d.ts +13 -0
- package/dist/shared/io/json.js +49 -0
- package/dist/shared/{safe-remove.js → io/safe-remove.js} +32 -7
- package/dist/shared/{netrules.js → network/firewall-rules.js} +36 -5
- package/dist/shared/network/index.d.ts +2 -0
- package/dist/shared/network/index.js +2 -0
- package/dist/shared/{netpolicy.js → network/policy.js} +66 -11
- package/dist/shared/{paths.js → paths/claude-paths.js} +12 -2
- package/dist/shared/{guest-paths.d.ts → paths/guest-paths.d.ts} +21 -0
- package/dist/shared/paths/guest-paths.js +146 -0
- package/dist/shared/paths/index.d.ts +3 -0
- package/dist/shared/paths/index.js +3 -0
- package/dist/shared/{projects.d.ts → paths/projects.d.ts} +27 -4
- package/dist/shared/paths/projects.js +136 -0
- package/dist/shared/pty/client.d.ts +21 -0
- package/dist/shared/pty/client.js +79 -0
- package/dist/shared/pty/console-input.d.ts +11 -0
- package/dist/shared/pty/console-input.js +81 -0
- package/dist/shared/pty/index.d.ts +6 -0
- package/dist/shared/pty/index.js +6 -0
- package/dist/shared/pty/input-joiner.d.ts +15 -0
- package/dist/shared/pty/input-joiner.js +44 -0
- package/dist/shared/pty/output-filter.d.ts +13 -0
- package/dist/shared/pty/output-filter.js +140 -0
- package/dist/shared/pty/protocol.d.ts +36 -0
- package/dist/shared/pty/protocol.js +60 -0
- package/dist/shared/pty/terminal.d.ts +24 -0
- package/dist/shared/pty/terminal.js +147 -0
- package/dist/shared/test-guard.js +3 -1
- package/dist/sync/claude-mem.d.ts +1 -1
- package/dist/sync/claude-mem.js +9 -4
- package/dist/sync/history.d.ts +1 -29
- package/dist/sync/history.js +57 -45
- package/dist/sync/index.d.ts +5 -0
- package/dist/sync/index.js +5 -0
- package/dist/sync/sync-cycle.d.ts +18 -0
- package/dist/sync/sync-cycle.js +85 -0
- package/dist/sync/sync-state.d.ts +32 -0
- package/dist/sync/sync-state.js +37 -0
- package/dist/sync/watcher.d.ts +0 -18
- package/dist/sync/watcher.js +66 -100
- package/native/keep-awake.ps1 +8 -0
- package/native/power.cs +23 -0
- package/native/stop-events.ps1 +38 -0
- package/package.json +11 -3
- package/sandbox/linkgate.cs +98 -0
- package/sandbox/memlog.ps1 +15 -6
- package/sandbox/ptyhost.cs +60 -3
- package/schemas/config.schema.json +48 -1
- package/schemas/sandbox-config.schema.json +37 -3
- package/dist/cli/commands/launch.d.ts +0 -29
- package/dist/cli/commands/launch.js +0 -366
- package/dist/cli/commands/maintenance.d.ts +0 -10
- package/dist/cli/commands/maintenance.js +0 -187
- package/dist/cli/commands/project.d.ts +0 -29
- package/dist/cli/commands/project.js +0 -63
- package/dist/cli/commands/projects.d.ts +0 -14
- package/dist/cli/commands/projects.js +0 -146
- package/dist/cli/commands/restart.d.ts +0 -6
- package/dist/cli/commands/restart.js +0 -85
- package/dist/cli/commands/sessions.d.ts +0 -12
- package/dist/cli/commands/sessions.js +0 -257
- package/dist/cli/menu/settings/editors.js +0 -305
- package/dist/cli/progress.d.ts +0 -9
- package/dist/cli/progress.js +0 -49
- package/dist/cli/tui/dialogs.d.ts +0 -57
- package/dist/cli/tui/dialogs.js +0 -162
- package/dist/core/config.js +0 -109
- package/dist/core/schema.d.ts +0 -6
- package/dist/core/schema.js +0 -8
- package/dist/core/util.d.ts +0 -62
- package/dist/core/util.js +0 -156
- package/dist/core/workspace.d.ts +0 -18
- package/dist/core/workspace.js +0 -145
- package/dist/guest/boot-env.d.ts +0 -4
- package/dist/guest/daemon.js +0 -57
- package/dist/guest/env.d.ts +0 -52
- package/dist/guest/env.js +0 -103
- package/dist/guest/gitrules.js +0 -11
- package/dist/guest/project-status.d.ts +0 -5
- package/dist/guest/project-status.js +0 -17
- package/dist/guest/setup/user.js +0 -51
- package/dist/guest/toolchains/cli.d.ts +0 -10
- package/dist/guest/toolchains/common.d.ts +0 -54
- package/dist/guest/toolchains/common.js +0 -147
- package/dist/guest/toolchains/databases/dynamodb.d.ts +0 -8
- package/dist/guest/toolchains/databases/dynamodb.js +0 -52
- package/dist/guest/toolchains/databases/index.d.ts +0 -6
- package/dist/guest/toolchains/databases/index.js +0 -62
- package/dist/guest/toolchains/databases/mongodb.d.ts +0 -3
- package/dist/guest/toolchains/databases/mongodb.js +0 -31
- package/dist/guest/toolchains/databases/mysql.d.ts +0 -3
- package/dist/guest/toolchains/databases/mysql.js +0 -38
- package/dist/guest/toolchains/databases/postgres.d.ts +0 -5
- package/dist/guest/toolchains/databases/postgres.js +0 -38
- package/dist/guest/toolchains/databases/redis.d.ts +0 -3
- package/dist/guest/toolchains/databases/redis.js +0 -16
- package/dist/guest/toolchains/git.d.ts +0 -3
- package/dist/guest/toolchains/go.d.ts +0 -3
- package/dist/guest/toolchains/java.d.ts +0 -8
- package/dist/guest/toolchains/node.d.ts +0 -3
- package/dist/guest/toolchains/pwsh.d.ts +0 -4
- package/dist/guest/toolchains/python.d.ts +0 -3
- package/dist/guest/toolchains/scripting/php.d.ts +0 -3
- package/dist/guest/toolchains/scripting/ruby.d.ts +0 -3
- package/dist/host/accounts.d.ts +0 -32
- package/dist/host/accounts.js +0 -128
- package/dist/host/agent-commands.d.ts +0 -25
- package/dist/host/agent-commands.js +0 -145
- package/dist/host/channel.d.ts +0 -38
- package/dist/host/channel.js +0 -162
- package/dist/host/generate.d.ts +0 -13
- package/dist/host/generate.js +0 -108
- package/dist/host/join.d.ts +0 -28
- package/dist/host/join.js +0 -76
- package/dist/host/launch/projects.d.ts +0 -15
- package/dist/host/launch/wsb.js +0 -34
- package/dist/host/motw.d.ts +0 -17
- package/dist/host/motw.js +0 -74
- package/dist/host/pc-scan.d.ts +0 -6
- package/dist/host/personalize.d.ts +0 -10
- package/dist/host/personalize.js +0 -97
- package/dist/host/platform.js +0 -129
- package/dist/host/project-scan.d.ts +0 -7
- package/dist/host/projects.d.ts +0 -100
- package/dist/host/projects.js +0 -147
- package/dist/host/repo-guard.d.ts +0 -43
- package/dist/host/repo-guard.js +0 -347
- package/dist/host/secrets.d.ts +0 -14
- package/dist/host/secrets.js +0 -133
- package/dist/host/stops.d.ts +0 -67
- package/dist/host/stops.js +0 -126
- package/dist/shared/apps.js +0 -114
- package/dist/shared/download.d.ts +0 -60
- package/dist/shared/download.js +0 -215
- package/dist/shared/guest-paths.js +0 -61
- package/dist/shared/projects.js +0 -67
- package/dist/shared/pty-client.d.ts +0 -91
- package/dist/shared/pty-client.js +0 -349
- package/dist/shared/rundir.d.ts +0 -41
- package/dist/shared/rundir.js +0 -96
- package/dist/shared/schema.js +0 -92
- /package/dist/{guest/daemon.d.ts → cli/tui/list/list-types.js} +0 -0
- /package/dist/{guest/db.d.ts → cli/tui/screen.js} +0 -0
- /package/dist/core/{detect-databases.d.ts → detect/databases.d.ts} +0 -0
- /package/dist/{guest/toolchains → core/detect}/versions.d.ts +0 -0
- /package/dist/guest/{setup/agents.d.ts → agents/agent-installer.d.ts} +0 -0
- /package/dist/guest/{audit-parse.d.ts → audit/parse.d.ts} +0 -0
- /package/dist/guest/{guide.d.ts → boot/guide.d.ts} +0 -0
- /package/dist/guest/daemon/{shutdown.d.ts → idle-shutdown.d.ts} +0 -0
- /package/dist/guest/daemon/{session.d.ts → sessions.d.ts} +0 -0
- /package/dist/guest/{main.d.ts → entries/daemon.d.ts} +0 -0
- /package/dist/guest/{netproxy.d.ts → entries/db.d.ts} +0 -0
- /package/dist/{selftest/suite.js → guest/entries/gitguard.d.ts} +0 -0
- /package/dist/guest/{gitguard.d.ts → git/decision.d.ts} +0 -0
- /package/dist/guest/{ports.d.ts → runtime/ports.d.ts} +0 -0
- /package/dist/guest/{project-context.d.ts → runtime/project-context.d.ts} +0 -0
- /package/dist/guest/{cmdline.d.ts → sessions/cmdline.d.ts} +0 -0
- /package/dist/guest/{ptyhost.d.ts → sessions/pty-host.d.ts} +0 -0
- /package/dist/guest/{view.d.ts → sessions/viewer.d.ts} +0 -0
- /package/dist/guest/setup/{policy.d.ts → managed-policy.d.ts} +0 -0
- /package/dist/host/{window.d.ts → sandbox/window.d.ts} +0 -0
- /package/dist/host/{wsb.d.ts → sandbox/wsb-cli.d.ts} +0 -0
- /package/dist/host/{cleanup.d.ts → storage/cleanup.d.ts} +0 -0
- /package/dist/selftest/{harness.d.ts → support/harness.d.ts} +0 -0
- /package/dist/selftest/{suite.d.ts → support/suite.d.ts} +0 -0
- /package/dist/shared/{safe-remove.d.ts → io/safe-remove.d.ts} +0 -0
- /package/dist/shared/{netrules.d.ts → network/firewall-rules.d.ts} +0 -0
- /package/dist/shared/{netpolicy.d.ts → network/policy.d.ts} +0 -0
- /package/dist/shared/{paths.d.ts → paths/claude-paths.d.ts} +0 -0
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type { Suite } from './suite.js';
|
|
1
|
+
import type { Suite } from './support/suite.js';
|
|
2
2
|
export declare const accountsSuite: Suite;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Claude accounts: saving logins from the sandbox or this PC, switching, and the names that are refused.
|
|
2
2
|
import fs from 'node:fs';
|
|
3
3
|
import path from 'node:path';
|
|
4
|
-
import {
|
|
4
|
+
import { AccountStore } from '../host/profile/index.js';
|
|
5
5
|
export const accountsSuite = {
|
|
6
6
|
name: 'accounts',
|
|
7
7
|
title: 'Claude accounts (save, switch, remove, safe names)',
|
|
@@ -12,33 +12,36 @@ export const accountsSuite = {
|
|
|
12
12
|
const sandboxClaude = path.join(dataA, 'state', 'claude');
|
|
13
13
|
t.write(path.join(sandboxClaude, '.credentials.json'), '{"claudeAiOauth":{"refreshToken":"personal-1"}}');
|
|
14
14
|
t.write(path.join(sandboxClaude, '.claude.json'), '{"oauthAccount":{"emailAddress":"me@personal"},"other":1}');
|
|
15
|
-
|
|
15
|
+
new AccountStore(storage).save(dataA, 'personal', null);
|
|
16
16
|
t.write(t.at('host-login', '.credentials.json'), '{"claudeAiOauth":{"refreshToken":"work-1"}}');
|
|
17
17
|
t.write(t.at('host-login.json'), '{"oauthAccount":{"emailAddress":"me@work"}}');
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
18
|
+
new AccountStore(storage).save(dataA, 'work', {
|
|
19
|
+
claudeDir: t.at('host-login'),
|
|
20
|
+
globalStateFile: t.at('host-login.json'),
|
|
21
|
+
});
|
|
22
|
+
t.equal(new AccountStore(storage).list(dataA).length, 2, 'accounts can be saved from the sandbox and from this PC');
|
|
23
|
+
t.equal(new AccountStore(storage).defaultName(), 'personal', 'the first account saved becomes the default');
|
|
24
|
+
t.equal(new AccountStore(storage).activeFor(dataA), 'personal', 'the first account saved is the active one');
|
|
22
25
|
t.check(!fs.existsSync(path.join(sandboxClaude, '.agent-sandbox-account')), 'which account is active is not recorded inside the sandbox...');
|
|
23
26
|
t.check(fs.existsSync(path.join(storage, 'accounts', 'index.json')), '... it is recorded host-side');
|
|
24
27
|
t.write(path.join(sandboxClaude, '.credentials.json'), '{"claudeAiOauth":{"refreshToken":"personal-2"}}');
|
|
25
|
-
|
|
28
|
+
new AccountStore(storage).activate(dataA, 'work');
|
|
26
29
|
const stateAfter = f.readJson(path.join(sandboxClaude, '.claude.json'));
|
|
27
|
-
t.includes(fs.readFileSync(path.join(sandboxClaude, '.credentials.json'), 'utf8'), 'work-1',
|
|
30
|
+
t.includes(fs.readFileSync(path.join(sandboxClaude, '.credentials.json'), 'utf8'), 'work-1', "switching swaps in the other account's credentials");
|
|
28
31
|
t.equal(stateAfter.oauthAccount.emailAddress, 'me@work', 'switching swaps the signed-in account');
|
|
29
32
|
t.equal(stateAfter.other, 1, 'switching keeps the rest of the sandbox state');
|
|
30
|
-
t.equal(
|
|
31
|
-
t.includes(JSON.stringify(
|
|
33
|
+
t.equal(new AccountStore(storage).activeFor(dataA), 'work', 'the new account is active');
|
|
34
|
+
t.includes(JSON.stringify(new AccountStore(storage).read('personal')?.credentials), 'personal-2', "the outgoing account's refreshed tokens are saved back before switching");
|
|
32
35
|
t.section('removing and refusing');
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
t.equal(
|
|
36
|
-
await t.throws(() =>
|
|
37
|
-
await t.throws(() =>
|
|
36
|
+
new AccountStore(storage).setDefault('work');
|
|
37
|
+
new AccountStore(storage).remove('work');
|
|
38
|
+
t.equal(new AccountStore(storage).defaultName(), null, 'removing the default account clears the default');
|
|
39
|
+
await t.throws(() => new AccountStore(storage).activate(dataA, 'nope'), 'Unknown account', 'an unknown account cannot be activated');
|
|
40
|
+
await t.throws(() => new AccountStore(storage).save(dataA, '../x', null), 'Invalid account name', 'a path-like account name is rejected');
|
|
38
41
|
const victim = t.dir('victim');
|
|
39
42
|
const otherData = t.at('acct-storage', 'data', 'd');
|
|
40
43
|
const fromHost = { claudeDir: victim, globalStateFile: victim };
|
|
41
|
-
await t.throws(() =>
|
|
42
|
-
await t.throws(() =>
|
|
44
|
+
await t.throws(() => new AccountStore(t.at('acct-storage')).save(otherData, 'index', fromHost), 'Invalid account name', 'an account cannot be called "index" (it would overwrite the index)');
|
|
45
|
+
await t.throws(() => new AccountStore(t.at('acct-storage')).save(otherData, 'con', fromHost), 'Invalid account name', 'an account cannot be named after a device (it would open a device)');
|
|
43
46
|
},
|
|
44
47
|
};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type { Suite } from './suite.js';
|
|
1
|
+
import type { Suite } from './support/suite.js';
|
|
2
2
|
export declare const agentCommandsSuite: Suite;
|
|
@@ -2,8 +2,10 @@
|
|
|
2
2
|
// Everything happens in the test's temp folder with a made-up PATH; your real PATH is never read or written.
|
|
3
3
|
import fs from 'node:fs';
|
|
4
4
|
import path from 'node:path';
|
|
5
|
-
import { DEFAULTS } from '../core/config.js';
|
|
6
|
-
import { agentCommands, commandsDir,
|
|
5
|
+
import { DEFAULTS } from '../core/config/index.js';
|
|
6
|
+
import { agentCommands, commandsDir, realAgent } from '../host/agent-commands/index.js';
|
|
7
|
+
import { forwardingCmd, forwardingSh } from '../host/agent-commands/index.js';
|
|
8
|
+
import { reconcileAgentCommands } from '../host/agent-commands/index.js';
|
|
7
9
|
export const agentCommandsSuite = {
|
|
8
10
|
name: 'agent-commands',
|
|
9
11
|
title: 'agent commands (Beta): claude, codex ... forwarded into a hidden sandbox',
|
|
@@ -19,9 +21,11 @@ export const agentCommandsSuite = {
|
|
|
19
21
|
const PATH = [commandsDir(storage), npmDir, localBin].join(path.delimiter);
|
|
20
22
|
const on = { ...DEFAULTS, agentCommands: { enabled: true, agents: 'auto' } };
|
|
21
23
|
t.section('finding agents');
|
|
22
|
-
t.equal(realAgent('claude', commandsDir(storage), PATH), path.join(localBin, 'claude.exe'),
|
|
24
|
+
t.equal(realAgent('claude', commandsDir(storage), PATH), path.join(localBin, 'claude.exe'), "the real agent is found on PATH, skipping this tool's own forwarding files");
|
|
23
25
|
t.equal(realAgent('nope', commandsDir(storage), PATH), null, 'an agent that is not installed is not found');
|
|
24
|
-
const commandsOf = (config, searchPath) => agentCommands(config, storage, searchPath)
|
|
26
|
+
const commandsOf = (config, searchPath) => agentCommands(config, storage, searchPath)
|
|
27
|
+
.map((a) => a.command)
|
|
28
|
+
.sort();
|
|
25
29
|
t.equal(commandsOf(on, PATH), ['claude', 'codex', 'gemini'], '"auto": every agent installed on this PC gets a command, agents not installed none');
|
|
26
30
|
t.equal(commandsOf({ ...on, agentCommands: { enabled: true, agents: ['codex'] } }, PATH), ['codex'], 'a list limits it to the named agents');
|
|
27
31
|
const unsafeDir = t.at('agent%cmd^dir');
|
|
@@ -33,7 +37,7 @@ export const agentCommandsSuite = {
|
|
|
33
37
|
t.includes(cmd, '"C:\\node\\node.exe" "C:\\tool\\dist\\bin\\sandbox.js" launch --harness claude --headless --terminal -- %*', 'the .cmd starts the agent in a hidden sandbox attached to this terminal...');
|
|
34
38
|
t.includes(cmd, 'if "%SANDBOX_AGENT_DIRECT%"=="1" goto direct', '... unless SANDBOX_AGENT_DIRECT=1...');
|
|
35
39
|
t.includes(cmd, 'call "' + claude.real + '" %*', '... which runs the real agent');
|
|
36
|
-
const sh = forwardingSh({ ...claude, real:
|
|
40
|
+
const sh = forwardingSh({ ...claude, real: "C:\\Users\\me\\it's\\claude.exe" }, 'C:\\node\\node.exe', 'C:\\tool\\sandbox.js');
|
|
37
41
|
t.check(sh.startsWith('#!/bin/sh'), 'Git Bash gets a shell script');
|
|
38
42
|
t.includes(sh, "exec '/c/node/node.exe' '/c/tool/sandbox.js' launch --harness claude --headless --terminal -- \"$@\"", 'the shell script starts the same sandbox, with POSIX paths');
|
|
39
43
|
t.includes(sh, "'/c/Users/me/it'\\''s/claude.exe'", 'the shell script quotes awkward paths safely');
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type { Suite } from './suite.js';
|
|
1
|
+
import type { Suite } from './support/suite.js';
|
|
2
2
|
export declare const auditSuite: Suite;
|
|
@@ -6,21 +6,40 @@ import path from 'node:path';
|
|
|
6
6
|
import zlib from 'node:zlib';
|
|
7
7
|
import { AuditCollector } from '../host/audit/collect.js';
|
|
8
8
|
import { AuditLog, fold } from '../host/audit/log.js';
|
|
9
|
-
import { parseProcessEvents } from '../guest/audit
|
|
10
|
-
import {
|
|
11
|
-
const ev = (t, extra = {}) => ({
|
|
9
|
+
import { parseProcessEvents } from '../guest/audit/parse.js';
|
|
10
|
+
import { RunDir } from '../shared/channel/index.js';
|
|
11
|
+
const ev = (t, extra = {}) => ({
|
|
12
|
+
t,
|
|
13
|
+
k: 'proc',
|
|
14
|
+
p: 'C:\\x\\cargo.exe',
|
|
15
|
+
c: 'cargo build',
|
|
16
|
+
...extra,
|
|
17
|
+
});
|
|
12
18
|
export const auditSuite = {
|
|
13
19
|
name: 'audit',
|
|
14
20
|
title: 'audit log (folding, compression, limits, untrusted reports)',
|
|
15
21
|
run: (t) => {
|
|
16
22
|
t.section('small');
|
|
17
|
-
const folded = fold([
|
|
18
|
-
|
|
23
|
+
const folded = fold([
|
|
24
|
+
ev('2026-01-01T10:00:01Z'),
|
|
25
|
+
ev('2026-01-01T10:00:02Z'),
|
|
26
|
+
ev('2026-01-01T10:00:03Z', { c: 'cargo test' }),
|
|
27
|
+
ev('2026-01-01T10:01:00Z'),
|
|
28
|
+
]);
|
|
29
|
+
t.equal(folded.map((e) => [e.c, e.n ?? 1]), [
|
|
30
|
+
['cargo build', 2],
|
|
31
|
+
['cargo test', 1],
|
|
32
|
+
['cargo build', 1],
|
|
33
|
+
], 'repeats within a minute become one line with a count');
|
|
19
34
|
const flood = fold(Array.from({ length: 50 }, (_, i) => ev('2026-01-01T10:00:00Z', { c: 'step ' + i })), 10);
|
|
20
35
|
t.check(flood.length === 11 && flood[10].k === 'note' && flood[10].p.startsWith('40 more'), 'past the per-minute cap the rest is one note');
|
|
21
36
|
const dir = t.at('audit-log');
|
|
22
37
|
const log = new AuditLog(dir, { days: 3, maxMb: 5 });
|
|
23
|
-
log.append([
|
|
38
|
+
log.append([
|
|
39
|
+
ev('2026-01-01T10:00:00Z'),
|
|
40
|
+
ev('2026-01-02T10:00:00Z'),
|
|
41
|
+
ev('2026-01-04T10:00:00Z', { k: 'file', p: 'src/a.ts', a: 'change', w: 'C:\\app' }),
|
|
42
|
+
]);
|
|
24
43
|
log.maintain('2026-01-04');
|
|
25
44
|
t.equal(fs.readdirSync(dir).sort(), ['2026-01-02.jsonl.gz', '2026-01-04.jsonl'], 'finished days are compressed and days past audit.days are deleted');
|
|
26
45
|
t.includes(zlib.gunzipSync(fs.readFileSync(path.join(dir, '2026-01-02.jsonl.gz'))).toString(), 'cargo build', 'a compressed day still holds its events');
|
|
@@ -35,23 +54,37 @@ export const auditSuite = {
|
|
|
35
54
|
t.equal(log.read({ days: 10000, kinds: ['file'] }).map((e) => e.p), ['src/a.ts'], 'events can be filtered by kind');
|
|
36
55
|
t.equal(log.read({ days: 10000, grep: 'SRC/A.TS' }).length, 1, '... and by text (any case)');
|
|
37
56
|
t.section('what the sandbox reports');
|
|
38
|
-
const xml = "<Event><System><TimeCreated SystemTime='2026-01-05T09:00:00.000Z'/><EventRecordID>41</EventRecordID></System><EventData><Data Name='NewProcessName'>C:\\AgentData\\tools\\git\\cmd\\git.exe</Data><Data Name='CommandLine'>git push --force "origin"</Data><Data Name='ParentProcessName'>C:\\nvm\\nodejs\\node.exe</Data></EventData></Event>"
|
|
39
|
-
|
|
57
|
+
const xml = "<Event><System><TimeCreated SystemTime='2026-01-05T09:00:00.000Z'/><EventRecordID>41</EventRecordID></System><EventData><Data Name='NewProcessName'>C:\\AgentData\\tools\\git\\cmd\\git.exe</Data><Data Name='CommandLine'>git push --force "origin"</Data><Data Name='ParentProcessName'>C:\\nvm\\nodejs\\node.exe</Data></EventData></Event>" +
|
|
58
|
+
"<Event><System><EventRecordID>42</EventRecordID></System><EventData><Data Name='NewProcessName'>C:\\Windows\\System32\\conhost.exe</Data></EventData></Event>";
|
|
40
59
|
const parsed = parseProcessEvents(xml);
|
|
41
|
-
t.equal({ last: parsed.last, lines: parsed.lines.map((l) => JSON.parse(l)).map((e) => [e.p, e.c, e.pp]) }, {
|
|
60
|
+
t.equal({ last: parsed.last, lines: parsed.lines.map((l) => JSON.parse(l)).map((e) => [e.p, e.c, e.pp]) }, {
|
|
61
|
+
last: 42,
|
|
62
|
+
lines: [['C:\\AgentData\\tools\\git\\cmd\\git.exe', 'git push --force "origin"', 'C:\\nvm\\nodejs\\node.exe']],
|
|
63
|
+
}, "Windows process events become audit lines; Windows' own background programs are left out");
|
|
42
64
|
const data = t.at('audit-data', 'data', 'd');
|
|
43
65
|
const storage = t.at('audit-data');
|
|
44
|
-
const reports =
|
|
66
|
+
const reports = new RunDir(data).auditDir;
|
|
45
67
|
t.write(path.join(reports, '1-1.jsonl'), [
|
|
46
68
|
JSON.stringify({ t: '2026-01-05T09:00:00Z', k: 'guard', p: 'fake: all clear' }),
|
|
47
69
|
JSON.stringify({ t: '2026-01-05T09:00:01Z', k: 'proc', p: 'C:\\x.exe', c: 'x --y', w: 'C:\\Users\\me' }),
|
|
48
|
-
'not json',
|
|
70
|
+
'not json',
|
|
71
|
+
JSON.stringify({ t: '2026-01-05T09:00:02Z', k: 'proc', p: 'x'.repeat(5000) }),
|
|
49
72
|
].join('\n'));
|
|
50
73
|
t.write(path.join(reports, 'not-a-report.txt'), 'ignored');
|
|
51
|
-
const collector = new AuditCollector(data, storage, {
|
|
74
|
+
const collector = new AuditCollector(data, storage, {
|
|
75
|
+
enabled: true,
|
|
76
|
+
days: 14,
|
|
77
|
+
maxMb: 50,
|
|
78
|
+
processes: true,
|
|
79
|
+
files: false,
|
|
80
|
+
projects: [],
|
|
81
|
+
});
|
|
52
82
|
collector.flush();
|
|
53
83
|
const got = new AuditLog(AuditLog.dirFor(storage, data), { days: 14, maxMb: 50 }).read({ days: 100000 });
|
|
54
|
-
t.equal(got.map((e) => [e.k, e.p, e.w]), [
|
|
84
|
+
t.equal(got.map((e) => [e.k, e.p, e.w]), [
|
|
85
|
+
['proc', 'fake: all clear', undefined],
|
|
86
|
+
['proc', 'C:\\x.exe', undefined],
|
|
87
|
+
], 'sandbox reports can only be programs: other kinds are recorded as such, fields it may not set are dropped, oversized lines are refused');
|
|
55
88
|
t.check(!fs.existsSync(path.join(reports, '1-1.jsonl')), 'reports are deleted once taken in');
|
|
56
89
|
},
|
|
57
90
|
};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type { Suite } from './suite.js';
|
|
1
|
+
import type { Suite } from './support/suite.js';
|
|
2
2
|
export declare const channelSuite: Suite;
|
|
@@ -1,24 +1,84 @@
|
|
|
1
1
|
// The host <-> sandbox channel and the terminal protocol: everything arriving from the sandbox is validated, sized and
|
|
2
2
|
// filtered before this PC acts on it.
|
|
3
|
-
import { safeId } from '../shared/
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
3
|
+
import { safeId } from '../shared/channel/index.js';
|
|
4
|
+
import { GuestRequestSchema, SandboxStatusSchema, SessionStatusSchema } from '../shared/channel/index.js';
|
|
5
|
+
import { bootLine, firstStartNotice, pendingDownloads, readyIn, stillWorking } from '../cli/commands/launch/index.js';
|
|
6
|
+
import { encodeFrame, FrameReader, FrameType, fixWindowsKeys, helloFrame, InputJoiner, MAX_FRAME_BYTES, MOUSE_OFF, OutputFilter, } from '../shared/pty/index.js';
|
|
6
7
|
export const channelSuite = {
|
|
7
8
|
name: 'channel',
|
|
8
9
|
title: 'request/status validation and the terminal protocol (frames, OSC 52, keys)',
|
|
9
10
|
run: async (t) => {
|
|
10
11
|
t.section('requests and session status');
|
|
11
|
-
const validRequest = (r) =>
|
|
12
|
-
const validSession = (s) =>
|
|
12
|
+
const validRequest = (r) => GuestRequestSchema.safeParse(r).success;
|
|
13
|
+
const validSession = (s) => SessionStatusSchema.safeParse(s).success;
|
|
13
14
|
await t.throws(() => safeId('../evil'), 'invalid id', 'a path-like id is rejected');
|
|
14
15
|
t.check(!validRequest({ kind: 'shell', id: 'a' }), 'unknown request kinds are rejected');
|
|
15
16
|
t.check(!validRequest({ kind: 'exec', id: 'a/b', command: ['x'], cwd: 'C:\\', timeoutSeconds: 1 }), 'request ids must be safe file names');
|
|
16
17
|
t.check(validRequest({ kind: 'ping', id: 'abc', createdAt: 'x' }), 'a known request kind with a safe id is accepted');
|
|
17
18
|
t.check(!validRequest({ kind: 'ping', id: 'abc', createdAt: 'x', extra: 1 }), 'requests with unknown keys are rejected');
|
|
18
|
-
const goodSession = {
|
|
19
|
+
const goodSession = {
|
|
20
|
+
id: 's1',
|
|
21
|
+
launchId: 'l',
|
|
22
|
+
harness: 'claude',
|
|
23
|
+
cwd: 'C:\\Workspace',
|
|
24
|
+
message: 'ok',
|
|
25
|
+
phase: 'running',
|
|
26
|
+
updatedAt: 'x',
|
|
27
|
+
startedAt: 'x',
|
|
28
|
+
attach: { addresses: ['172.20.1.5'], port: 5000, token: 't' },
|
|
29
|
+
};
|
|
19
30
|
t.check(validSession(goodSession), 'a well-formed session status is accepted');
|
|
20
31
|
t.check(!validSession({ ...goodSession, attach: { ...goodSession.attach, port: 70000 } }), 'a session status with an impossible port is rejected');
|
|
21
32
|
t.check(!validSession({ ...goodSession, phase: 'pwned' }), 'a session status with an unknown phase is rejected');
|
|
33
|
+
t.section('boot progress');
|
|
34
|
+
const goodStatus = {
|
|
35
|
+
launchId: 'l1',
|
|
36
|
+
phase: 'provisioning',
|
|
37
|
+
message: '[3/8] Developer tools',
|
|
38
|
+
updatedAt: 'x',
|
|
39
|
+
workspaceHost: 'C:\\p',
|
|
40
|
+
guestWorkspace: 'C:\\Workspace',
|
|
41
|
+
headless: false,
|
|
42
|
+
};
|
|
43
|
+
const progress = {
|
|
44
|
+
step: 3,
|
|
45
|
+
steps: 8,
|
|
46
|
+
title: 'Developer tools',
|
|
47
|
+
active: [{ name: 'Rust', percent: 40 }, { name: 'Go' }],
|
|
48
|
+
done: 2,
|
|
49
|
+
total: 6,
|
|
50
|
+
};
|
|
51
|
+
const parsed = (s) => SandboxStatusSchema.safeParse(s);
|
|
52
|
+
t.equal(parsed({ ...goodStatus, progress }).data?.progress, progress, 'a well-formed boot progress is accepted');
|
|
53
|
+
t.check(parsed(goodStatus).success && parsed(goodStatus).data?.progress === undefined, 'a status without progress (an older sandbox) is accepted');
|
|
54
|
+
const hostile = [
|
|
55
|
+
{ ...progress, title: 'x'.repeat(5000) },
|
|
56
|
+
{ ...progress, active: Array.from({ length: 100 }, () => ({ name: 'a' })) },
|
|
57
|
+
{ ...progress, active: [{ name: 'a', percent: 500 }] },
|
|
58
|
+
{ ...progress, step: -1 },
|
|
59
|
+
{ ...progress, done: 1e9 },
|
|
60
|
+
{ ...progress, extra: 1 },
|
|
61
|
+
'pwned',
|
|
62
|
+
];
|
|
63
|
+
t.equal(hostile.map((p) => {
|
|
64
|
+
const r = parsed({ ...goodStatus, progress: p });
|
|
65
|
+
return r.success && r.data.progress === undefined;
|
|
66
|
+
}), hostile.map(() => true), 'an oversized or malformed progress is dropped, the status itself still counts');
|
|
67
|
+
t.check(!parsed({ ...goodStatus, phase: 'pwned', progress }).success, 'a status with an unknown phase is still rejected');
|
|
68
|
+
const line = (p) => bootLine(parsed({ ...goodStatus, progress: p }).data ?? null).line;
|
|
69
|
+
t.equal(line(progress), '[3/8] Developer tools: downloading Rust 40%; setting up Go (2 of 6 done)', 'the line shows the step, the download and what is set up');
|
|
70
|
+
t.equal(line({ ...progress, title: 'Agent: claude', step: 6, active: [], done: 0, total: 0 }), '[6/8] Agent: claude', 'a step without tools is just its title');
|
|
71
|
+
t.equal(line({ ...progress, active: [{ name: '\x1b]52;c;ZXZpbA==\x07Ru\x1b[2Jst\r\n', percent: 99 }] }), '[3/8] Developer tools: downloading Rust 99% (2 of 6 done)', 'escape sequences and control characters from the sandbox never reach the terminal');
|
|
72
|
+
t.equal(bootLine(null).line, 'Starting Windows Sandbox', 'before the sandbox writes anything');
|
|
73
|
+
t.equal(bootLine(parsed({ ...goodStatus, message: 'Installing Go (1 of 3 done)' }).data).line, 'Installing Go (1 of 3 done)', 'an older sandbox: its message');
|
|
74
|
+
t.equal(bootLine(parsed({ ...goodStatus, progress: { ...progress, active: [{ name: 'Rust', percent: 50 }] } }).data).key, bootLine(parsed({ ...goodStatus, progress: { ...progress, active: [{ name: 'Rust', percent: 60 }] } }).data).key, 'a download moving on is no new plain line (only a new step or tool is)');
|
|
75
|
+
t.equal(stillWorking('Rust', 3 * 60 * 1000), 'Still working on Rust (3 min). Full log: sandbox logs -f', 'the notice after a long quiet spell');
|
|
76
|
+
t.equal(readyIn(432_000), 'Ready in 7 min 12 s.', 'the time a first start took');
|
|
77
|
+
const pending = pendingDownloads(['node', 'rust', 'cpp', 'postgres', 'node', 'constructor'], (dir) => dir === 'nvm');
|
|
78
|
+
t.equal(pending, { names: ['rust', 'C/C++', 'PostgreSQL'], mb: 900 }, 'only what is not downloaded yet counts, once each');
|
|
79
|
+
t.equal(firstStartNotice(false, { names: [], mb: 0 }), null, 'a later start with everything downloaded says nothing');
|
|
80
|
+
t.check(/^First start: .*\(about 900 MB: rust, C\/C\+\+, PostgreSQL\)\. This can take 5-20 minutes/.test(firstStartNotice(true, pending) ?? ''), 'the first start says what it downloads, roughly how much, and how long it can take');
|
|
81
|
+
t.check(/^New tools for this project: .*about 1\.8 GB: MSVC, rust/.test(firstStartNotice(false, pendingDownloads(['msvc', 'rust'], () => false)) ?? ''), 'a new toolchain later on gets its own heads-up');
|
|
22
82
|
t.section('terminal frames');
|
|
23
83
|
const filter = new OutputFilter();
|
|
24
84
|
const filtered = Buffer.concat([
|
|
@@ -27,7 +87,10 @@ export const channelSuite = {
|
|
|
27
87
|
filter.push(Buffer.from('2;c;cGF5\x1b\\d')),
|
|
28
88
|
]).toString('latin1');
|
|
29
89
|
t.equal(filtered, 'a' + 'b\x1b]0;title\x07' + 'c' + 'd', 'clipboard writes (OSC 52) from the sandbox are stripped, even split across chunks; titles pass');
|
|
30
|
-
const through = (...chunks) => {
|
|
90
|
+
const through = (...chunks) => {
|
|
91
|
+
const f = new OutputFilter();
|
|
92
|
+
return Buffer.concat(chunks.map((s) => f.push(Buffer.from(s, 'latin1')))).toString('latin1');
|
|
93
|
+
};
|
|
31
94
|
t.equal(through('x\x1b]52;c;QUFB\x1b', '\\y'), 'xy', 'an OSC 52 whose terminator is split between chunks is still stripped');
|
|
32
95
|
t.equal(through('x\x1b]052;c;QUFB\x07y'), 'xy', 'OSC 052 (leading zero) is stripped too');
|
|
33
96
|
t.equal(through('x\x1b]52;c;' + 'A'.repeat(70000), 'B'.repeat(100), '\x07y'), 'xy', 'a huge OSC 52 stays stripped across chunks');
|
|
@@ -38,7 +101,27 @@ export const channelSuite = {
|
|
|
38
101
|
await t.throws(() => new FrameReader().push(oversizedHeader), 'frame too large', 'a frame announcing too much data is rejected instead of buffered');
|
|
39
102
|
t.equal(new FrameReader().push(encodeFrame(16, Buffer.alloc(MAX_FRAME_BYTES))).length, 1, 'a frame of exactly the maximum size is accepted');
|
|
40
103
|
const hello = new FrameReader().push(helloFrame('tok', 100, 30, 2))[0];
|
|
41
|
-
t.equal({
|
|
104
|
+
t.equal({
|
|
105
|
+
type: hello.type,
|
|
106
|
+
cols: hello.payload.readInt16LE(0),
|
|
107
|
+
rows: hello.payload.readInt16LE(2),
|
|
108
|
+
flags: hello.payload[4],
|
|
109
|
+
token: hello.payload.subarray(5).toString(),
|
|
110
|
+
}, { type: FrameType.Hello, cols: 100, rows: 30, flags: 2, token: 'tok' }, 'a hello frame carries size, flags and token');
|
|
42
111
|
t.equal(fixWindowsKeys(Buffer.from([0x61, 0x08, 0x7f, 0x1b])), Buffer.from([0x61, 0x7f, 0x08, 0x1b]), 'Windows console Backspace (^H) reaches the agent as DEL, so it deletes one character, not a word');
|
|
112
|
+
t.section('typed input keeps escape sequences whole');
|
|
113
|
+
const joined = (...chunks) => {
|
|
114
|
+
const j = new InputJoiner();
|
|
115
|
+
const out = chunks.map((c) => j.push(Buffer.from(c, 'latin1')).toString('latin1'));
|
|
116
|
+
out.push(j.flush().toString('latin1'));
|
|
117
|
+
return out.filter(Boolean);
|
|
118
|
+
};
|
|
119
|
+
t.equal(joined('ab\x1b[', 'C'), ['ab', '\x1b[C'], 'a Right arrow split after ESC[ is sent whole (ConPTY would read Alt+[ and a typed "C")');
|
|
120
|
+
t.equal(joined('\x1b', '[<0;10;', '5M', 'x'), ['\x1b[<0;10;5M', 'x'], 'a mouse report split three ways is sent as one');
|
|
121
|
+
t.equal(joined('\x1bO', 'A'), ['\x1bOA'], 'an SS3 key split after ESC O is sent whole');
|
|
122
|
+
t.equal(joined('a\x1b'), ['a', '\x1b'], 'a lone Esc key is held, then sent by the flush');
|
|
123
|
+
t.equal(joined('\x1b[A\x1bx\x7f'), ['\x1b[A\x1bx\x7f'], 'complete keys (arrows, Alt+x, Backspace) pass at once');
|
|
124
|
+
t.equal(joined('\x1b[' + '1;'.repeat(40)), ['\x1b[' + '1;'.repeat(40)], 'an endless "sequence" is not held back');
|
|
125
|
+
t.check(MOUSE_OFF.includes('\x1b[?1000l') && MOUSE_OFF.includes('\x1b[?1003l') && MOUSE_OFF.includes('\x1b[?1006l'), 'leaving a session turns every mouse tracking mode off in your terminal');
|
|
43
126
|
},
|
|
44
127
|
};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type { Suite } from './suite.js';
|
|
1
|
+
import type { Suite } from './support/suite.js';
|
|
2
2
|
export declare const cliSuite: Suite;
|
|
@@ -8,12 +8,12 @@ import { commandLine, readHistory, recordHistory } from '../cli/history.js';
|
|
|
8
8
|
import { splitArgs } from '../cli/args.js';
|
|
9
9
|
import { optionProblem } from '../cli/menu/index.js';
|
|
10
10
|
import { cleanTargetOf } from '../cli/commands/data/collect.js';
|
|
11
|
-
import { ago, colorEnabled, shorten, shortenMiddle } from '../cli/
|
|
12
|
-
import { hoistConfig, withoutConfig } from '../cli/
|
|
11
|
+
import { ago, colorEnabled, shorten, shortenMiddle } from '../cli/output/index.js';
|
|
12
|
+
import { hoistConfig, withoutConfig } from '../cli/argv.js';
|
|
13
13
|
import { closest, validNodeSpec, validPythonSpec } from '../cli/validate.js';
|
|
14
14
|
import { CATEGORIES, editConfigText, nameOf, SchemaNode } from '../cli/menu/settings/index.js';
|
|
15
15
|
import { Frame, ListScreen, Text, TextScreen } from '../cli/tui/index.js';
|
|
16
|
-
import {
|
|
16
|
+
import { ConfigSchema, LocalOverridesSchema } from '../core/schema/index.js';
|
|
17
17
|
export const cliSuite = {
|
|
18
18
|
name: 'cli',
|
|
19
19
|
title: 'command manifest, argument parser, menu helpers, settings screen',
|
|
@@ -36,13 +36,19 @@ export const cliSuite = {
|
|
|
36
36
|
t.equal(parseCli(['launch', '--harness', 'opencode', '--', '--continue']).passthrough, ['--continue'], 'agent arguments after -- reach the agent');
|
|
37
37
|
t.section('parser: agent wrappers (claude-sbx ...) and agent-sandbox');
|
|
38
38
|
const wrapped = parseCli(['--terminal', '--continue', '--headless', '--node', '20', '--', '--terminal'], true);
|
|
39
|
-
t.equal({
|
|
39
|
+
t.equal({
|
|
40
|
+
command: wrapped.command,
|
|
41
|
+
terminal: wrapped.terminal,
|
|
42
|
+
headless: wrapped.headless,
|
|
43
|
+
node: wrapped.node,
|
|
44
|
+
passthrough: wrapped.passthrough,
|
|
45
|
+
}, { command: 'launch', terminal: true, headless: true, node: '20', passthrough: ['--continue', '--terminal'] }, 'claude-sbx: sandbox flags are consumed, everything else goes to the agent');
|
|
40
46
|
await t.throws(() => parseCli(['status', '--bogus']), 'unknown option', 'agent-sandbox: unknown options are errors');
|
|
41
47
|
t.equal(parseCli(['account', 'use', 'work', '--no-restart']).positionals, ['use', 'work'], 'agent-sandbox: positionals are collected');
|
|
42
48
|
t.equal(parseCli(['clean', '--days=3']).days, 3, 'agent-sandbox: --opt=value works');
|
|
43
49
|
const agentFlags = parseCli(['--model', 'opus', '-p', 'fix it', '--json', '-f', 'x', '--timeout', '5', '--resume', 'abc'], true);
|
|
44
50
|
t.equal(agentFlags.passthrough, ['--model', 'opus', '-p', 'fix it', '--json', '-f', 'x', '--timeout', '5', '--resume', 'abc'], 'claude-sbx: any flag that is not a launch option goes to the agent, in order (even ones agent-sandbox uses elsewhere)');
|
|
45
|
-
t.equal({ json: agentFlags.json, follow: agentFlags.follow, timeout: agentFlags.timeout }, { json: false, follow: false, timeout: 600 },
|
|
51
|
+
t.equal({ json: agentFlags.json, follow: agentFlags.follow, timeout: agentFlags.timeout }, { json: false, follow: false, timeout: 600 }, "claude-sbx: the agent's flags do not set agent-sandbox options");
|
|
46
52
|
const reserved = parseCli(['--sbx-terminal', '--terminal', '--sbx-node=18'], true);
|
|
47
53
|
t.equal({ terminal: reserved.terminal, node: reserved.node, passthrough: reserved.passthrough }, { terminal: true, node: '18', passthrough: [] }, '--sbx-<option> always means agent-sandbox');
|
|
48
54
|
t.equal(parseCli(['launch', '--continue', '--sbx-headless']).passthrough, ['--continue'], 'agent-sandbox launch passes agent flags too');
|
|
@@ -57,7 +63,12 @@ export const cliSuite = {
|
|
|
57
63
|
t.check(optionProblem(optionOf('--workspace'), t.packageRoot) === undefined, 'menu: an existing folder is accepted');
|
|
58
64
|
t.check(optionProblem(optionOf('--days'), '0') !== undefined, 'menu: a number below the minimum is rejected');
|
|
59
65
|
const rowOf = (area, name) => ({ area, name, path: 'x', bytes: 1 });
|
|
60
|
-
t.equal([
|
|
66
|
+
t.equal([
|
|
67
|
+
cleanTargetOf(rowOf('tools', 'go')),
|
|
68
|
+
cleanTargetOf(rowOf('tools', 'agents/claude')),
|
|
69
|
+
cleanTargetOf(rowOf('databases', 'databases/pg')),
|
|
70
|
+
cleanTargetOf(rowOf('host', 'launches')),
|
|
71
|
+
], ['tools/go', 'tools/agents/claude', 'databases/pg', 'launches'], 'data menu: removable rows become checkbox targets');
|
|
61
72
|
t.equal([cleanTargetOf(rowOf('host', 'accounts')), cleanTargetOf(rowOf('tools', '(files in tools)'))], [null, null], 'data menu: accounts and loose files are never offered');
|
|
62
73
|
t.equal(COMMANDS.find((cmd) => cmd.name === 'data').options.find((o) => o.flag === '--yes')?.noMenu, true, 'data menu: --yes is never offered');
|
|
63
74
|
t.section('--config placement, history, validation, text helpers');
|
|
@@ -88,7 +99,7 @@ export const cliSuite = {
|
|
|
88
99
|
const reset = 'text' in nested ? editConfigText(nested.text, ['sandbox', 'headless'], undefined) : nested;
|
|
89
100
|
t.check('text' in reset, 'editing a config file gives new text');
|
|
90
101
|
const resetText = 'text' in reset ? reset.text : '';
|
|
91
|
-
t.includes(resetText, '// my notes stay',
|
|
102
|
+
t.includes(resetText, '// my notes stay', "settings screen: changes keep the file's comments");
|
|
92
103
|
t.includes(resetText, '"auto": true', 'settings screen: a new setting is added');
|
|
93
104
|
t.includes(resetText, '"port": 6543', 'settings screen: nested keys are created');
|
|
94
105
|
t.excludes(resetText, 'headless', 'settings screen: reset removes a key');
|
|
@@ -101,17 +112,35 @@ export const cliSuite = {
|
|
|
101
112
|
t.check('text' in projectEdit && projectEdit.text.includes('requireChecksum'), 'settings screen: a project file accepts project settings');
|
|
102
113
|
t.check('problems' in projectBad, 'settings screen: a project file is validated against the project schema (storage cannot be set there)');
|
|
103
114
|
// Every setting must be reachable in the settings screen, in a category, with an editor that fits it.
|
|
104
|
-
const userSchema = new SchemaNode(
|
|
105
|
-
const projectSchema = new SchemaNode(
|
|
115
|
+
const userSchema = new SchemaNode(ConfigSchema);
|
|
116
|
+
const projectSchema = new SchemaNode(LocalOverridesSchema);
|
|
106
117
|
const userLeaves = userSchema.leaves();
|
|
107
118
|
const projectLeaves = projectSchema.leaves();
|
|
108
|
-
t.check(userLeaves.length > 100 && projectLeaves.length > 50, 'settings screen: every setting is a leaf (' +
|
|
109
|
-
|
|
119
|
+
t.check(userLeaves.length > 100 && projectLeaves.length > 50, 'settings screen: every setting is a leaf (' +
|
|
120
|
+
userLeaves.length +
|
|
121
|
+
' settings, ' +
|
|
122
|
+
projectLeaves.length +
|
|
123
|
+
' in a project file)');
|
|
124
|
+
const uncategorised = [...userSchema.children(), ...projectSchema.children()]
|
|
125
|
+
.map(([name]) => name)
|
|
126
|
+
.filter((name) => !CATEGORIES.some((c) => c.keys.includes(name)));
|
|
110
127
|
t.equal(uncategorised, [], 'settings screen: every top-level setting belongs to a category');
|
|
111
128
|
const kinds = new Set(userLeaves.map((l) => l.node.editor));
|
|
112
|
-
t.equal([
|
|
129
|
+
t.equal([
|
|
130
|
+
'boolean',
|
|
131
|
+
'choice',
|
|
132
|
+
'union',
|
|
133
|
+
'number',
|
|
134
|
+
'string',
|
|
135
|
+
'string-list',
|
|
136
|
+
'choice-list',
|
|
137
|
+
'object-list',
|
|
138
|
+
'string-map',
|
|
139
|
+
'object-map',
|
|
140
|
+
].filter((k) => !kinds.has(k)), [], 'settings screen: every kind of editor is used');
|
|
113
141
|
t.equal(userLeaves.filter((l) => l.node.editor === 'json').map((l) => l.key.join('.')), [], 'settings screen: no setting falls back to typing JSON');
|
|
114
|
-
t.check(userLeaves.some((l) => l.key.join('.') === 'downloads.requireChecksum') &&
|
|
142
|
+
t.check(userLeaves.some((l) => l.key.join('.') === 'downloads.requireChecksum') &&
|
|
143
|
+
projectLeaves.some((l) => l.key.join('.') === 'downloads.requireChecksum'), 'settings screen: downloads.requireChecksum is reachable in both files');
|
|
115
144
|
const harness = userSchema.child('harnesses').element;
|
|
116
145
|
t.includes(String(harness.check(harness.initial())), 'npmPackage', 'settings screen: a new agent says what it still needs (a package to install)');
|
|
117
146
|
t.equal(harness.check({ ...harness.initial(), npmPackage: 'my-cli', npmBin: 'my-cli' }), true, '... and is valid once it has one');
|
|
@@ -122,19 +151,42 @@ export const cliSuite = {
|
|
|
122
151
|
const fit = Text.fit('\x1b[31mred text\x1b[0m', 5);
|
|
123
152
|
t.equal([Text.width(fit), Text.strip(fit)], [5, 'red …'], 'a coloured label is cut to the width without breaking its colour');
|
|
124
153
|
t.equal(Text.width('日本'), 4, 'wide characters take two columns');
|
|
125
|
-
const screen = new ListScreen({
|
|
154
|
+
const screen = new ListScreen({
|
|
155
|
+
path: ['T'],
|
|
156
|
+
items: [
|
|
157
|
+
{ value: 'a', label: 'Alpha', category: 'x' },
|
|
158
|
+
{ value: 'b', label: 'Beta', category: 'y', description: 'second' },
|
|
159
|
+
],
|
|
160
|
+
categories: [
|
|
161
|
+
{ id: 'x', label: 'X' },
|
|
162
|
+
{ id: 'y', label: 'Y' },
|
|
163
|
+
],
|
|
164
|
+
});
|
|
126
165
|
const key = (name, text = '') => ({ name, text, ctrl: false, meta: false, shift: false });
|
|
127
166
|
screen.handle(key('left'));
|
|
128
167
|
screen.handle(key('down'));
|
|
129
168
|
screen.handle(key('right'));
|
|
130
169
|
t.equal(screen.handle(key('return')), { done: { kind: 'pick', value: 'b' } }, 'list screen: arrows switch category, Enter picks');
|
|
131
|
-
const search = new ListScreen({
|
|
170
|
+
const search = new ListScreen({
|
|
171
|
+
path: ['T'],
|
|
172
|
+
items: [
|
|
173
|
+
{ value: 'a', label: 'Alpha' },
|
|
174
|
+
{ value: 'b', label: 'Beta' },
|
|
175
|
+
],
|
|
176
|
+
});
|
|
132
177
|
for (const k of [key('', '/'), key('b', 'b'), key('e', 'e')])
|
|
133
178
|
search.handle(k);
|
|
134
179
|
t.equal(search.handle(key('return')), { done: { kind: 'pick', value: 'b' } }, 'list screen: / searches');
|
|
135
180
|
const lines = Frame.render(screen.render({ width: 60, height: Frame.bodyHeight(20) }), 60, 20);
|
|
136
181
|
t.equal(lines.length, 20, 'a frame fills the terminal height exactly');
|
|
137
|
-
const multi = new ListScreen({
|
|
182
|
+
const multi = new ListScreen({
|
|
183
|
+
path: ['T'],
|
|
184
|
+
multi: true,
|
|
185
|
+
items: [
|
|
186
|
+
{ value: 'a', label: 'A' },
|
|
187
|
+
{ value: 'b', label: 'B', checked: true },
|
|
188
|
+
],
|
|
189
|
+
});
|
|
138
190
|
multi.handle(key('space'));
|
|
139
191
|
t.equal(multi.handle(key('return')), { done: { kind: 'multi', values: ['a', 'b'] } }, 'list screen: space ticks several');
|
|
140
192
|
const typed = new TextScreen({ path: ['T'], label: 'Port', validate: (v) => (Number(v) > 0 ? true : 'a number') });
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type { Suite } from './suite.js';
|
|
1
|
+
import type { Suite } from './support/suite.js';
|
|
2
2
|
export declare const cmdlineSuite: Suite;
|
|
@@ -3,10 +3,23 @@
|
|
|
3
3
|
import { spawnSync } from 'node:child_process';
|
|
4
4
|
import path from 'node:path';
|
|
5
5
|
import { pathToFileURL } from 'node:url';
|
|
6
|
-
import { isWin } from '../core/util.js';
|
|
7
|
-
import { runNode } from './fixtures.js';
|
|
6
|
+
import { isWin } from '../core/util/index.js';
|
|
7
|
+
import { runNode } from './support/fixtures.js';
|
|
8
8
|
// Odd quote counts flip cmd's quote state for every later argument: those come after them on purpose.
|
|
9
|
-
const TRICKY_ARGUMENTS = [
|
|
9
|
+
const TRICKY_ARGUMENTS = [
|
|
10
|
+
'https://x?a=1&b=2',
|
|
11
|
+
'50% off',
|
|
12
|
+
'a|b<c>d',
|
|
13
|
+
'x^y',
|
|
14
|
+
'say "hi" & go',
|
|
15
|
+
'plain',
|
|
16
|
+
'%PATH%',
|
|
17
|
+
'a"b&c',
|
|
18
|
+
'q"x|y^z"w',
|
|
19
|
+
'e"5%',
|
|
20
|
+
'k&v',
|
|
21
|
+
'100%',
|
|
22
|
+
];
|
|
10
23
|
export const cmdlineSuite = {
|
|
11
24
|
name: 'cmdline',
|
|
12
25
|
title: 'cmd.exe quoting for npm-installed agents',
|
|
@@ -21,14 +34,26 @@ export const cmdlineSuite = {
|
|
|
21
34
|
'console.log(JSON.stringify({ normal: m.commandLine("C:\\\\W\\\\cmd.exe", ["/d", "/c", "C:\\\\a\\\\agent.cmd", "--model", "big one", "plain", ""]), direct: m.commandLine("C:\\\\a\\\\agent.exe", ["a&b", "50%"]),',
|
|
22
35
|
' url: m.cmdArgs(["https://x?a=1&b=2"]), pct: m.cmdArgs(["50%"]), live: m.commandLine("cmd.exe", ["/d", "/c", cmd, ...tricky]).slice(8) }));',
|
|
23
36
|
].join('\n');
|
|
24
|
-
const probe = await runNode([
|
|
25
|
-
|
|
37
|
+
const probe = await runNode([
|
|
38
|
+
'--input-type=module',
|
|
39
|
+
'-e',
|
|
40
|
+
script,
|
|
41
|
+
pathToFileURL(path.join(t.packageRoot, 'dist', 'guest', 'sessions', 'cmdline.js')).href,
|
|
42
|
+
JSON.stringify([agentCmd, TRICKY_ARGUMENTS]),
|
|
43
|
+
], {
|
|
44
|
+
env: {
|
|
45
|
+
...process.env,
|
|
46
|
+
AGENT_LAUNCH_DIR: path.join(quoteDir, 'launch'),
|
|
47
|
+
AGENT_DATA_DIR: path.join(quoteDir, 'data'),
|
|
48
|
+
},
|
|
26
49
|
});
|
|
27
50
|
let quoting = {};
|
|
28
51
|
try {
|
|
29
52
|
quoting = JSON.parse(probe.out);
|
|
30
53
|
}
|
|
31
|
-
catch {
|
|
54
|
+
catch {
|
|
55
|
+
/* reported below */
|
|
56
|
+
}
|
|
32
57
|
const whyEmpty = quoting.normal ? '' : 'the helper printed: ' + probe.out.trim().slice(0, 300);
|
|
33
58
|
t.check(quoting.normal === 'C:\\W\\cmd.exe /d /c C:\\a\\agent.cmd --model "big one" plain ""', 'ordinary arguments are quoted as before', whyEmpty + '\nactual: ' + quoting.normal);
|
|
34
59
|
t.check(quoting.direct === 'C:\\a\\agent.exe a&b 50%', 'a program started directly gets & and % unchanged', 'actual: ' + quoting.direct);
|
|
@@ -36,7 +61,11 @@ export const cmdlineSuite = {
|
|
|
36
61
|
t.equal(quoting.pct, '"50"%""', 'cmd /c arguments: % is split out so no %name% expands');
|
|
37
62
|
// (A temp folder with spaces would also need cmd's own quote rules, so this end-to-end run skips those.)
|
|
38
63
|
if (isWin && quoting.live && !/\s/.test(agentCmd)) {
|
|
39
|
-
const echoed = spawnSync(process.env.ComSpec ?? 'cmd.exe', [quoting.live], {
|
|
64
|
+
const echoed = spawnSync(process.env.ComSpec ?? 'cmd.exe', [quoting.live], {
|
|
65
|
+
encoding: 'utf8',
|
|
66
|
+
windowsVerbatimArguments: true,
|
|
67
|
+
windowsHide: true,
|
|
68
|
+
});
|
|
40
69
|
t.equal(echoed.stdout.trim(), JSON.stringify(TRICKY_ARGUMENTS), 'cmd /d /c <agent>.cmd passes &, |, <, >, ^, % and quotes through to the agent unchanged');
|
|
41
70
|
}
|
|
42
71
|
else
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type { Suite } from './suite.js';
|
|
1
|
+
import type { Suite } from './support/suite.js';
|
|
2
2
|
export declare const configSuite: Suite;
|