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
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
// Host side of the sandbox channel: follow the boot and send requests (sessions, exec, restart, ping). Attaching a
|
|
2
|
+
// terminal to a session is in attach.ts. Everything read from the run folder is guest-written and treated as untrusted.
|
|
3
|
+
import crypto from 'node:crypto';
|
|
4
|
+
import fs from 'node:fs';
|
|
5
|
+
import { assertNoLinks, fail, isLink, removeLink, safeText, sleep } from '../../core/util/index.js';
|
|
6
|
+
import { isWithin } from '../../shared/paths/index.js';
|
|
7
|
+
import { now, RunDir } from '../../shared/channel/index.js';
|
|
8
|
+
import { safeRemove, writeJsonAtomic } from '../../shared/io/index.js';
|
|
9
|
+
import { isSandboxRunning } from '../sandbox/index.js';
|
|
10
|
+
import { assertTestWritable, refuseInSelfTest } from '../test-guard.js';
|
|
11
|
+
const BOOT_TIMEOUT_MS = 30 * 60 * 1000;
|
|
12
|
+
/** Most sessions the host will ever contact for one listing: a sandbox can write as many session files as it likes. */
|
|
13
|
+
export const MAX_QUERIED_SESSIONS = 32;
|
|
14
|
+
const printLine = (line) => console.log(line);
|
|
15
|
+
const newId = () => Date.now().toString(36) + crypto.randomBytes(3).toString('hex');
|
|
16
|
+
/** Sessions in this guest folder or below (one project's) first, each group newest first. */
|
|
17
|
+
export function sessionsFirstIn(sessions, guestDir) {
|
|
18
|
+
const newest = [...sessions].reverse();
|
|
19
|
+
if (!guestDir)
|
|
20
|
+
return newest;
|
|
21
|
+
return [...newest.filter((s) => isWithin(guestDir, s.cwd)), ...newest.filter((s) => !isWithin(guestDir, s.cwd))];
|
|
22
|
+
}
|
|
23
|
+
/** The channel to the sandbox of one data folder: requests go into its run folder, answers are polled from it. */
|
|
24
|
+
export class SandboxChannel {
|
|
25
|
+
dataPath;
|
|
26
|
+
isAlive;
|
|
27
|
+
run;
|
|
28
|
+
constructor(dataPath, isAlive = isSandboxRunning) {
|
|
29
|
+
this.dataPath = dataPath;
|
|
30
|
+
this.isAlive = isAlive;
|
|
31
|
+
this.run = new RunDir(dataPath);
|
|
32
|
+
}
|
|
33
|
+
async until(timeoutMs, poll, timeoutMessage) {
|
|
34
|
+
const deadline = Date.now() + timeoutMs;
|
|
35
|
+
for (let round = 0; Date.now() < deadline; round++) {
|
|
36
|
+
const value = poll();
|
|
37
|
+
if (value !== null && value !== undefined)
|
|
38
|
+
return value;
|
|
39
|
+
if (round % 10 === 0 && !this.isAlive())
|
|
40
|
+
fail('Windows Sandbox closed (or is not running).', 'Start it again with sandbox claude; sandbox logs shows what happened.');
|
|
41
|
+
await sleep(500);
|
|
42
|
+
}
|
|
43
|
+
fail(timeoutMessage, 'Check what the sandbox is doing with sandbox logs -f (or sbx-show to see its window).');
|
|
44
|
+
}
|
|
45
|
+
/** Deletes an answer once read; a planted link means the answer is read and nothing is deleted. */
|
|
46
|
+
dropResponse(requestId) {
|
|
47
|
+
try {
|
|
48
|
+
assertNoLinks(this.dataPath, this.run.responsesDir);
|
|
49
|
+
fs.rmSync(this.run.responseFile(requestId), { force: true });
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
/* a planted link: the answer is read, nothing is deleted */
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/** Waits until the sandbox finished provisioning, reporting each boot step (onStatus: every status read, validated). */
|
|
56
|
+
waitForReady(launchId, progress = (m) => printLine(' [sandbox] ' + m), onStatus) {
|
|
57
|
+
let last = '';
|
|
58
|
+
return this.until(BOOT_TIMEOUT_MS, () => {
|
|
59
|
+
const status = this.run.readSandboxStatus();
|
|
60
|
+
if (!status || (launchId !== null && status.launchId !== launchId))
|
|
61
|
+
return null;
|
|
62
|
+
onStatus?.(status);
|
|
63
|
+
if (status.message !== last) {
|
|
64
|
+
progress(safeText(status.message).slice(0, 300));
|
|
65
|
+
last = status.message;
|
|
66
|
+
}
|
|
67
|
+
if (status.phase === 'failed')
|
|
68
|
+
fail('The sandbox failed to start: ' + status.message, 'See sandbox logs for details; the sandbox window shows the error too (sbx-show if headless).');
|
|
69
|
+
return status.phase === 'ready' ? status : null;
|
|
70
|
+
}, 'Timed out waiting for the sandbox to finish provisioning.');
|
|
71
|
+
}
|
|
72
|
+
send(request) {
|
|
73
|
+
assertTestWritable(this.dataPath);
|
|
74
|
+
// Asking the sandbox to power off is the one request with an effect outside it, so the self-test never sends it.
|
|
75
|
+
if (request.kind === 'exec' && /shutdown/i.test(request.command[0] ?? ''))
|
|
76
|
+
refuseInSelfTest('shut down Windows Sandbox');
|
|
77
|
+
assertNoLinks(this.dataPath, this.run.requestsDir);
|
|
78
|
+
writeJsonAtomic(this.run.requestFile(request.id), request);
|
|
79
|
+
}
|
|
80
|
+
waitForResponse(requestId, timeoutMs) {
|
|
81
|
+
return this.until(timeoutMs, () => {
|
|
82
|
+
const response = this.run.readResponse(requestId);
|
|
83
|
+
if (response)
|
|
84
|
+
this.dropResponse(requestId);
|
|
85
|
+
return response;
|
|
86
|
+
}, 'The sandbox did not answer (its session daemon may have stopped).');
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* project: a project registered after boot (provisioned first). harnessSpec: the agent's definition, for an agent the
|
|
90
|
+
* sandbox did not boot with.
|
|
91
|
+
*/
|
|
92
|
+
requestSession(harness, args, cwd, extra = {}) {
|
|
93
|
+
const requestId = newId();
|
|
94
|
+
this.send({
|
|
95
|
+
kind: 'session',
|
|
96
|
+
id: requestId,
|
|
97
|
+
harness,
|
|
98
|
+
args,
|
|
99
|
+
cwd,
|
|
100
|
+
...(extra.project ? { project: extra.project } : {}),
|
|
101
|
+
...(extra.harnessSpec ? { harnessSpec: extra.harnessSpec } : {}),
|
|
102
|
+
createdAt: now(),
|
|
103
|
+
});
|
|
104
|
+
return requestId;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Provisions a registered project without starting an agent and waits for it, printing its progress (the guest's
|
|
108
|
+
* run\projects\<name>.json) as it goes. Throws when it failed.
|
|
109
|
+
*/
|
|
110
|
+
async prepareProject(project, progress = (m) => printLine(' [' + project.name + '] ' + m)) {
|
|
111
|
+
const requestId = newId();
|
|
112
|
+
this.send({ kind: 'project', id: requestId, project, createdAt: now() });
|
|
113
|
+
let last = '';
|
|
114
|
+
const response = await this.until(60 * 60 * 1000, () => {
|
|
115
|
+
const status = this.run.readProjectStatus(project.name);
|
|
116
|
+
if (status && status.message !== last) {
|
|
117
|
+
progress(safeText(status.message).slice(0, 300));
|
|
118
|
+
last = status.message;
|
|
119
|
+
}
|
|
120
|
+
return this.run.readResponse(requestId);
|
|
121
|
+
}, 'Timed out waiting for the project to be set up.');
|
|
122
|
+
this.dropResponse(requestId);
|
|
123
|
+
if (!response.ok)
|
|
124
|
+
fail(safeText(response.message), 'See sandbox logs for details.');
|
|
125
|
+
return response;
|
|
126
|
+
}
|
|
127
|
+
waitForSession(sessionId, timeoutMs = 15 * 60 * 1000, progress = (m) => printLine(' [session] ' + m)) {
|
|
128
|
+
let last = '';
|
|
129
|
+
return this.until(timeoutMs, () => {
|
|
130
|
+
const session = this.run.readSession(sessionId);
|
|
131
|
+
if (!session)
|
|
132
|
+
return null;
|
|
133
|
+
if (session.message !== last) {
|
|
134
|
+
progress(safeText(session.message).slice(0, 300));
|
|
135
|
+
last = session.message;
|
|
136
|
+
}
|
|
137
|
+
if (session.phase === 'failed')
|
|
138
|
+
fail('The agent session failed to start: ' + session.message, 'See sandbox logs for details.');
|
|
139
|
+
if (session.phase === 'exited')
|
|
140
|
+
fail('The agent exited right away (code ' + session.exitCode + ').', 'Check sandbox logs; a wrong agent argument is the usual cause.');
|
|
141
|
+
return session.phase === 'running' ? session : null;
|
|
142
|
+
}, 'Timed out waiting for the session to start.');
|
|
143
|
+
}
|
|
144
|
+
/** Runs a command inside the sandbox (in the workspace or a folder below it) and returns its output. */
|
|
145
|
+
async exec(command, cwd, timeoutSeconds) {
|
|
146
|
+
const requestId = newId();
|
|
147
|
+
this.send({ kind: 'exec', id: requestId, command, cwd, timeoutSeconds, createdAt: now() });
|
|
148
|
+
return this.waitForResponse(requestId, (timeoutSeconds + 30) * 1000);
|
|
149
|
+
}
|
|
150
|
+
/** Restarts running sessions in place (they resume via the harness's resumeArguments, e.g. claude --continue). */
|
|
151
|
+
async restart(harness, cwd) {
|
|
152
|
+
const requestId = newId();
|
|
153
|
+
this.send({ kind: 'restart', id: requestId, harness, ...(cwd ? { cwd } : {}), createdAt: now() });
|
|
154
|
+
return this.waitForResponse(requestId, 30000);
|
|
155
|
+
}
|
|
156
|
+
async ping() {
|
|
157
|
+
const requestId = newId();
|
|
158
|
+
this.send({ kind: 'ping', id: requestId, createdAt: now() });
|
|
159
|
+
return this.waitForResponse(requestId, 15000);
|
|
160
|
+
}
|
|
161
|
+
runningSessions() {
|
|
162
|
+
return this.run.listSessions().filter((s) => s.phase === 'running');
|
|
163
|
+
}
|
|
164
|
+
/** Running sessions of the sandbox that is running now (its launch id), newest last, capped. */
|
|
165
|
+
currentSessions() {
|
|
166
|
+
const launchId = this.run.readSandboxStatus()?.launchId;
|
|
167
|
+
return this.runningSessions()
|
|
168
|
+
.filter((s) => s.launchId === launchId)
|
|
169
|
+
.slice(-MAX_QUERIED_SESSIONS);
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* The session with this id (or id prefix), else the most recently started running one: in `guestDir` (the project
|
|
173
|
+
* you are in) when it has one, else any.
|
|
174
|
+
*/
|
|
175
|
+
pickSession(sessionId, guestDir = null) {
|
|
176
|
+
const running = this.runningSessions();
|
|
177
|
+
if (running.length === 0)
|
|
178
|
+
fail('No agent session is running in the sandbox.', 'Start one with sandbox claude (it opens a new session in the running sandbox).');
|
|
179
|
+
if (!sessionId)
|
|
180
|
+
return sessionsFirstIn(running, guestDir)[0];
|
|
181
|
+
return (running.find((s) => s.id === sessionId || s.id.startsWith(sessionId)) ??
|
|
182
|
+
fail('No running session "' + sessionId + '".', 'Running sessions: ' + running.map((s) => s.id).join(', ') + ' (sandbox sessions lists them).'));
|
|
183
|
+
}
|
|
184
|
+
/** Forgets status from a previous sandbox run so nothing stale is picked up. */
|
|
185
|
+
reset() {
|
|
186
|
+
const p = this.run;
|
|
187
|
+
// A link (planted by a sandbox) is removed itself and never followed, including `run` itself.
|
|
188
|
+
if (isLink(p.root)) {
|
|
189
|
+
removeLink(p.root);
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
for (const target of [p.sandboxFile, p.requestsDir, p.responsesDir, p.sessionsDir, p.projectsDir]) {
|
|
193
|
+
safeRemove(target, this.dataPath);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { GuardRule, RepoFinding, RepoSnapshot } from './types.js';
|
|
2
|
+
export declare function agentSnapshot(workspace: string): Record<string, string>;
|
|
3
|
+
/** Hooks, helper commands and MCP servers in .claude/ and .mcp.json, VS Code folder-open tasks and programs, .envrc. */
|
|
4
|
+
export declare class AgentFilesRule implements GuardRule {
|
|
5
|
+
readonly kind = "agent-files";
|
|
6
|
+
check(workspace: string, before: RepoSnapshot): RepoFinding[];
|
|
7
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
// Agent and editor files that tools on this PC run things from: only their runnable part is fingerprinted and guarded.
|
|
2
|
+
import crypto from 'node:crypto';
|
|
3
|
+
import fs from 'node:fs';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import _ from 'lodash';
|
|
6
|
+
import { parse as parseJsonc } from 'jsonc-parser';
|
|
7
|
+
import { fileExists, isLink } from '../../core/util/index.js';
|
|
8
|
+
import { hash } from './file-hash.js';
|
|
9
|
+
const CLAUDE_RISKY_KEYS = [
|
|
10
|
+
'hooks',
|
|
11
|
+
'apiKeyHelper',
|
|
12
|
+
'awsAuthRefresh',
|
|
13
|
+
'awsCredentialExport',
|
|
14
|
+
'otelHeadersHelper',
|
|
15
|
+
'statusLine',
|
|
16
|
+
'env',
|
|
17
|
+
'enableAllProjectMcpServers',
|
|
18
|
+
'enabledMcpjsonServers',
|
|
19
|
+
'disableAllHooks',
|
|
20
|
+
];
|
|
21
|
+
const VSCODE_RISKY_KEY = /path|executable|command|interpreter|shell|profile|args|env|exec|program|server|launch|runtime|binary/i;
|
|
22
|
+
const MAX_AGENT_FILE_BYTES = 1024 * 1024;
|
|
23
|
+
function claudeRisk(d) {
|
|
24
|
+
const s = (_.isPlainObject(d) ? d : {});
|
|
25
|
+
const permissions = (_.isPlainObject(s.permissions) ? s.permissions : {});
|
|
26
|
+
return {
|
|
27
|
+
..._.pick(s, CLAUDE_RISKY_KEYS),
|
|
28
|
+
permissions: _.pick(permissions, ['defaultMode', 'additionalDirectories']),
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Project files that tools on this PC act on by themselves: Claude Code runs a project's hooks, helpers and MCP
|
|
33
|
+
* servers, VS Code runs folder-open tasks and the programs workspace settings point at, direnv runs .envrc. For each,
|
|
34
|
+
* only the part that can run something is compared (`risky`), so the agent may still edit the rest.
|
|
35
|
+
*/
|
|
36
|
+
const AGENT_FILES = {
|
|
37
|
+
'.claude/settings.json': (d) => claudeRisk(d),
|
|
38
|
+
'.claude/settings.local.json': (d) => claudeRisk(d),
|
|
39
|
+
'.mcp.json': (_d, text) => text,
|
|
40
|
+
'.vscode/tasks.json': (d) => (JSON.stringify(d).match(/"runOn"\s*:\s*"folderOpen"/) ? d : null),
|
|
41
|
+
'.vscode/settings.json': (d) => _.pickBy(_.isPlainObject(d) ? d : {}, (_v, k) => VSCODE_RISKY_KEY.test(k)),
|
|
42
|
+
'.envrc': (_d, text) => text,
|
|
43
|
+
};
|
|
44
|
+
const AGENT_FILE_NAMES = Object.keys(AGENT_FILES);
|
|
45
|
+
/** What can run in one agent file, as a short fingerprint (null = the file is not there). */
|
|
46
|
+
function agentRisk(workspace, rel) {
|
|
47
|
+
const file = path.join(workspace, ...rel.split('/'));
|
|
48
|
+
if (!fs.existsSync(file))
|
|
49
|
+
return null;
|
|
50
|
+
if (isLink(file) || isLink(path.dirname(file)) || !fileExists(file))
|
|
51
|
+
return 'link-or-not-a-file';
|
|
52
|
+
if (fs.statSync(file).size > MAX_AGENT_FILE_BYTES)
|
|
53
|
+
return 'too-large-' + hash(file);
|
|
54
|
+
const text = fs.readFileSync(file, 'utf8');
|
|
55
|
+
const errors = [];
|
|
56
|
+
const data = parseJsonc(text, errors, { allowTrailingComma: true });
|
|
57
|
+
const risk = AGENT_FILES[rel](rel === '.envrc' ? null : data, text);
|
|
58
|
+
return crypto
|
|
59
|
+
.createHash('sha256')
|
|
60
|
+
.update(JSON.stringify(risk ?? null) + (errors.length && rel !== '.envrc' && rel !== '.mcp.json' ? hash(file) : ''))
|
|
61
|
+
.digest('hex');
|
|
62
|
+
}
|
|
63
|
+
export function agentSnapshot(workspace) {
|
|
64
|
+
return Object.fromEntries(AGENT_FILE_NAMES.flatMap((rel) => {
|
|
65
|
+
const r = agentRisk(workspace, rel);
|
|
66
|
+
return r ? [[rel, r]] : [];
|
|
67
|
+
}));
|
|
68
|
+
}
|
|
69
|
+
/** Agent files whose runnable part changed are moved to the quarantine folder (with the rest of your edits). */
|
|
70
|
+
function guardAgentFiles(workspace, before) {
|
|
71
|
+
const changed = AGENT_FILE_NAMES.filter((rel) => {
|
|
72
|
+
const now = agentRisk(workspace, rel);
|
|
73
|
+
return now !== null && now !== before[rel];
|
|
74
|
+
});
|
|
75
|
+
if (!changed.length)
|
|
76
|
+
return [];
|
|
77
|
+
const target = path.join(workspace, 'agent-sandbox-quarantine', String(Date.now()));
|
|
78
|
+
fs.mkdirSync(target, { recursive: true });
|
|
79
|
+
return changed.map((rel) => {
|
|
80
|
+
const what = rel + ' (the sandbox added something it would run on this PC: hooks, MCP servers, helper commands or tasks';
|
|
81
|
+
try {
|
|
82
|
+
fs.renameSync(path.join(workspace, ...rel.split('/')), path.join(target, rel.replace(/\//g, '_')));
|
|
83
|
+
}
|
|
84
|
+
catch (e) {
|
|
85
|
+
return {
|
|
86
|
+
kind: 'agent',
|
|
87
|
+
detail: what +
|
|
88
|
+
'; could not be moved: ' +
|
|
89
|
+
e.code +
|
|
90
|
+
'. Check it before you open this folder in Claude Code or VS Code)',
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
return { kind: 'agent', detail: what + '; moved to ' + target + ')' };
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
/** Hooks, helper commands and MCP servers in .claude/ and .mcp.json, VS Code folder-open tasks and programs, .envrc. */
|
|
97
|
+
export class AgentFilesRule {
|
|
98
|
+
kind = 'agent-files';
|
|
99
|
+
check(workspace, before) {
|
|
100
|
+
// Snapshots from before these checks existed have no baseline: checking against nothing would move your own files.
|
|
101
|
+
return before.agent ? guardAgentFiles(workspace, before.agent) : [];
|
|
102
|
+
}
|
|
103
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { GuardRule, RepoFinding, RepoSnapshot } from './types.js';
|
|
2
|
+
/** Names you are likely to run in a project folder; with any of these extensions Windows would pick the local copy. */
|
|
3
|
+
export declare const COMMANDS: RegExp;
|
|
4
|
+
/** Fingerprints of the files in the project root named like one of COMMANDS. */
|
|
5
|
+
export declare function plantedCommands(workspace: string): Record<string, string>;
|
|
6
|
+
/** Executables dropped in the project root under the name of something you type there (Windows runs those first). */
|
|
7
|
+
export declare class PlantedCommandsRule implements GuardRule {
|
|
8
|
+
readonly kind = "commands";
|
|
9
|
+
check(workspace: string, before: RepoSnapshot): RepoFinding[];
|
|
10
|
+
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { filesIn } from './file-hash.js';
|
|
2
|
+
import { quarantine } from './quarantine.js';
|
|
3
|
+
/** Names you are likely to run in a project folder; with any of these extensions Windows would pick the local copy. */
|
|
4
|
+
export const COMMANDS = new RegExp('^(' +
|
|
5
|
+
[
|
|
6
|
+
// this tool's own commands (package.json "bin")
|
|
7
|
+
'sandbox',
|
|
8
|
+
'windows-development-sandbox',
|
|
9
|
+
'agent-sandbox',
|
|
10
|
+
'claude-sbx',
|
|
11
|
+
'claude-sandbox',
|
|
12
|
+
'codex-sbx',
|
|
13
|
+
'codex-sandbox',
|
|
14
|
+
'gemini-sbx',
|
|
15
|
+
'gemini-sandbox',
|
|
16
|
+
'claude-host',
|
|
17
|
+
'sbx-show',
|
|
18
|
+
'sbx-hide',
|
|
19
|
+
// agents
|
|
20
|
+
'claude',
|
|
21
|
+
'codex',
|
|
22
|
+
'gemini',
|
|
23
|
+
'opencode',
|
|
24
|
+
'qwen',
|
|
25
|
+
'crush',
|
|
26
|
+
'copilot',
|
|
27
|
+
'kilo',
|
|
28
|
+
'kilocode',
|
|
29
|
+
'amp',
|
|
30
|
+
'cline',
|
|
31
|
+
'cn',
|
|
32
|
+
'kimi',
|
|
33
|
+
'reasonix',
|
|
34
|
+
'codewhale',
|
|
35
|
+
'aider',
|
|
36
|
+
'cursor-agent',
|
|
37
|
+
'agent',
|
|
38
|
+
'goose',
|
|
39
|
+
// toolchains and everyday tools
|
|
40
|
+
'node',
|
|
41
|
+
'npm',
|
|
42
|
+
'npx',
|
|
43
|
+
'pnpm',
|
|
44
|
+
'pnpx',
|
|
45
|
+
'yarn',
|
|
46
|
+
'corepack',
|
|
47
|
+
'volta',
|
|
48
|
+
'nvm',
|
|
49
|
+
'deno',
|
|
50
|
+
'bun',
|
|
51
|
+
'bunx',
|
|
52
|
+
'tsc',
|
|
53
|
+
'git',
|
|
54
|
+
'gh',
|
|
55
|
+
'code',
|
|
56
|
+
'python',
|
|
57
|
+
'python3',
|
|
58
|
+
'py',
|
|
59
|
+
'pip',
|
|
60
|
+
'pip3',
|
|
61
|
+
'uv',
|
|
62
|
+
'uvx',
|
|
63
|
+
'pyenv',
|
|
64
|
+
'poetry',
|
|
65
|
+
'cargo',
|
|
66
|
+
'rustc',
|
|
67
|
+
'rustup',
|
|
68
|
+
'dotnet',
|
|
69
|
+
'nuget',
|
|
70
|
+
'msbuild',
|
|
71
|
+
'go',
|
|
72
|
+
'java',
|
|
73
|
+
'javac',
|
|
74
|
+
'mvn',
|
|
75
|
+
'mvnw',
|
|
76
|
+
'gradle',
|
|
77
|
+
'gradlew',
|
|
78
|
+
'ruby',
|
|
79
|
+
'gem',
|
|
80
|
+
'bundle',
|
|
81
|
+
'rake',
|
|
82
|
+
'rails',
|
|
83
|
+
'php',
|
|
84
|
+
'composer',
|
|
85
|
+
'make',
|
|
86
|
+
'cmake',
|
|
87
|
+
'ninja',
|
|
88
|
+
'gcc',
|
|
89
|
+
'g\\+\\+',
|
|
90
|
+
'clang',
|
|
91
|
+
'psql',
|
|
92
|
+
'mysql',
|
|
93
|
+
'mariadb',
|
|
94
|
+
'mongosh',
|
|
95
|
+
'redis-cli',
|
|
96
|
+
'docker',
|
|
97
|
+
'kubectl',
|
|
98
|
+
'terraform',
|
|
99
|
+
'az',
|
|
100
|
+
'aws',
|
|
101
|
+
'powershell',
|
|
102
|
+
'pwsh',
|
|
103
|
+
'cmd',
|
|
104
|
+
'where',
|
|
105
|
+
'tasklist',
|
|
106
|
+
'tar',
|
|
107
|
+
'curl',
|
|
108
|
+
'ssh',
|
|
109
|
+
'scp',
|
|
110
|
+
].join('|') +
|
|
111
|
+
')\\.(exe|com|bat|cmd|vbs|vbe|js|jse|wsf|wsh|msc|ps1)$', 'i');
|
|
112
|
+
/** Fingerprints of the files in the project root named like one of COMMANDS. */
|
|
113
|
+
export function plantedCommands(workspace) {
|
|
114
|
+
return filesIn(workspace, (n) => COMMANDS.test(n));
|
|
115
|
+
}
|
|
116
|
+
/** Executables dropped in the project root under the name of something you type there (Windows runs those first). */
|
|
117
|
+
export class PlantedCommandsRule {
|
|
118
|
+
kind = 'commands';
|
|
119
|
+
check(workspace, before) {
|
|
120
|
+
const now = plantedCommands(workspace);
|
|
121
|
+
return quarantine(workspace, Object.keys(now).filter((n) => before.commands[n] !== now[n]), workspace, 'command');
|
|
122
|
+
}
|
|
123
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** SHA-256 in small chunks: a sandbox can plant a multi-gigabyte "node.exe" to exhaust this PC's memory. */
|
|
2
|
+
export declare function hash(file: string): string;
|
|
3
|
+
/** The accepted files (and links) directly in a folder, by name, with their fingerprints. Links are not followed. */
|
|
4
|
+
export declare function filesIn(dir: string, accept: (name: string) => boolean): Record<string, string>;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// Fingerprints of the files the guard compares (planted commands, git hooks).
|
|
2
|
+
import crypto from 'node:crypto';
|
|
3
|
+
import fs from 'node:fs';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { dirExists, isLink } from '../../core/util/index.js';
|
|
6
|
+
/** SHA-256 in small chunks: a sandbox can plant a multi-gigabyte "node.exe" to exhaust this PC's memory. */
|
|
7
|
+
export function hash(file) {
|
|
8
|
+
if (isLink(file))
|
|
9
|
+
return 'link';
|
|
10
|
+
const sum = crypto.createHash('sha256');
|
|
11
|
+
const buffer = Buffer.alloc(1 << 20);
|
|
12
|
+
let fd;
|
|
13
|
+
// A file that cannot be read (locked by a program in the sandbox) never matches the snapshot, so it is dealt with.
|
|
14
|
+
try {
|
|
15
|
+
fd = fs.openSync(file, 'r');
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
return 'unreadable-' + crypto.randomBytes(4).toString('hex');
|
|
19
|
+
}
|
|
20
|
+
try {
|
|
21
|
+
for (let n = fs.readSync(fd, buffer, 0, buffer.length, null); n > 0; n = fs.readSync(fd, buffer, 0, buffer.length, null))
|
|
22
|
+
sum.update(buffer.subarray(0, n));
|
|
23
|
+
}
|
|
24
|
+
finally {
|
|
25
|
+
fs.closeSync(fd);
|
|
26
|
+
}
|
|
27
|
+
return sum.digest('hex');
|
|
28
|
+
}
|
|
29
|
+
/** The accepted files (and links) directly in a folder, by name, with their fingerprints. Links are not followed. */
|
|
30
|
+
export function filesIn(dir, accept) {
|
|
31
|
+
return dirExists(dir) && !isLink(dir)
|
|
32
|
+
? Object.fromEntries(fs
|
|
33
|
+
.readdirSync(dir, { withFileTypes: true })
|
|
34
|
+
.filter((e) => (e.isFile() || e.isSymbolicLink()) && accept(e.name))
|
|
35
|
+
.map((e) => [e.name, hash(path.join(dir, e.name))]))
|
|
36
|
+
: {};
|
|
37
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { RepoFinding } from './types.js';
|
|
2
|
+
/** The lines of <dir>\config (none for a link or a file over 4 MB). */
|
|
3
|
+
export declare function configLines(dir: string): string[];
|
|
4
|
+
/** Comments out newly added config lines that make git run programs. Existing lines are never touched. */
|
|
5
|
+
export declare function disableConfig(dir: string, before: readonly string[]): RepoFinding[];
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
// Git config lines that make git run a program on this PC: found by comparing with the snapshot, then commented out.
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import _ from 'lodash';
|
|
5
|
+
import { writeFileAtomic } from '../../shared/io/index.js';
|
|
6
|
+
import { fileExists, isLink } from '../../core/util/index.js';
|
|
7
|
+
/** Config keys that make git run a program, or load more config. */
|
|
8
|
+
const DANGEROUS_KEY = /^(fsmonitor|hookspath|sshcommand|pager|editor|askpass|program|gpgprogram|textconv|command|cmd|clean|smudge|process|driver|helper|uploadpack|receivepack|path|attributesfile|excludesfile|worktree|worktreeconfig|gitproxy|proxycommand|sendemailvalidate|tool|external|difffilter|defaultkeycommand|alternaterefscommand)\s*=/i;
|
|
9
|
+
const SECTION = /^\s*\[([^\]]*)\]\s*/;
|
|
10
|
+
const MARK = '# [agent-sandbox] disabled, added inside the sandbox: ';
|
|
11
|
+
const MAX_CONFIG_BYTES = 4 * 1024 * 1024;
|
|
12
|
+
/** Sections where any key runs a program ([pager] log = x), or where a "!" value does ([alias] st = !x). */
|
|
13
|
+
function dangerousInSection(section, keyPart) {
|
|
14
|
+
return (section === 'pager' && keyPart.includes('=')) || (section === 'alias' && /^[^=]+=\s*"?\s*!/.test(keyPart));
|
|
15
|
+
}
|
|
16
|
+
/** The lines of <dir>\config (none for a link or a file over 4 MB). */
|
|
17
|
+
export function configLines(dir) {
|
|
18
|
+
const file = path.join(dir, 'config');
|
|
19
|
+
return fileExists(file) && !isLink(file) && fs.statSync(file).size <= MAX_CONFIG_BYTES
|
|
20
|
+
? fs.readFileSync(file, 'utf8').split(/\r?\n/)
|
|
21
|
+
: [];
|
|
22
|
+
}
|
|
23
|
+
/** Comments out newly added config lines that make git run programs. Existing lines are never touched. */
|
|
24
|
+
export function disableConfig(dir, before) {
|
|
25
|
+
const lines = configLines(dir);
|
|
26
|
+
const known = _.countBy(before);
|
|
27
|
+
const seen = {};
|
|
28
|
+
const findings = [];
|
|
29
|
+
let inInclude = false;
|
|
30
|
+
let section = '';
|
|
31
|
+
const fixed = lines.map((line) => {
|
|
32
|
+
const header = SECTION.exec(line);
|
|
33
|
+
if (header) {
|
|
34
|
+
section = header[1].trim().toLowerCase().split(/\s/)[0];
|
|
35
|
+
inInclude = /^include(if\s+"[^"]*")?$/i.test(header[1].trim());
|
|
36
|
+
}
|
|
37
|
+
seen[line] = (seen[line] ?? 0) + 1;
|
|
38
|
+
if (line.startsWith(MARK) || seen[line] <= (known[line] ?? 0))
|
|
39
|
+
return line;
|
|
40
|
+
// git also accepts "[core] fsmonitor = x" on one line, so look past a leading section header.
|
|
41
|
+
const keyPart = line.replace(SECTION, '').trim();
|
|
42
|
+
if (!(DANGEROUS_KEY.test(keyPart) || (inInclude && keyPart.includes('=')) || dangerousInSection(section, keyPart)))
|
|
43
|
+
return line;
|
|
44
|
+
findings.push({ kind: 'config', detail: line.trim() });
|
|
45
|
+
return MARK + line.trim();
|
|
46
|
+
});
|
|
47
|
+
if (findings.length)
|
|
48
|
+
writeFileAtomic(path.join(dir, 'config'), fixed.join('\n'));
|
|
49
|
+
const file = path.join(dir, 'config');
|
|
50
|
+
// A link or a huge file is not read at all, so say so instead of letting it pass as "nothing found".
|
|
51
|
+
const unchecked = isLink(file)
|
|
52
|
+
? '.git/config is a link'
|
|
53
|
+
: lines.length === 0 && fileExists(file) && fs.statSync(file).size > MAX_CONFIG_BYTES
|
|
54
|
+
? '.git/config is over 4 MB'
|
|
55
|
+
: null;
|
|
56
|
+
if (unchecked)
|
|
57
|
+
findings.push({
|
|
58
|
+
kind: 'git',
|
|
59
|
+
detail: unchecked + ', so it cannot be checked. Do not run git in this folder until you have looked at it.',
|
|
60
|
+
});
|
|
61
|
+
return findings;
|
|
62
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { GitState, GuardRule, RepoFinding, RepoSnapshot } from './types.js';
|
|
2
|
+
export declare const EMPTY_GIT: GitState;
|
|
3
|
+
/** <workspace>\.git when it is a real folder (not a link or a "gitdir:" file). */
|
|
4
|
+
export declare function plainGitDir(workspace: string): string | null;
|
|
5
|
+
export declare function gitState(dir: string | null): GitState;
|
|
6
|
+
/** New or changed hooks and new redirect files are quarantined; new config that runs programs is commented out. */
|
|
7
|
+
export declare function guardGitDir(dir: string, before: GitState): RepoFinding[];
|
|
8
|
+
/** The project's own .git; a .git replaced by a link or a "gitdir:" file is reported, never followed. */
|
|
9
|
+
export declare class GitDirRule implements GuardRule {
|
|
10
|
+
readonly kind = "git-dir";
|
|
11
|
+
check(workspace: string, before: RepoSnapshot): RepoFinding[];
|
|
12
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
// A git folder's hooks, config and redirect files, and the rule that guards the project's own .git.
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { dirExists, isLink } from '../../core/util/index.js';
|
|
5
|
+
import { filesIn } from './file-hash.js';
|
|
6
|
+
import { configLines, disableConfig } from './git-config.js';
|
|
7
|
+
import { quarantine } from './quarantine.js';
|
|
8
|
+
/** Files in .git that make git read config/hooks from somewhere else. */
|
|
9
|
+
const REDIRECTS = ['commondir', 'config.worktree'];
|
|
10
|
+
const isHook = (name) => !name.endsWith('.sample');
|
|
11
|
+
export const EMPTY_GIT = { config: [], hooks: {}, redirects: [] };
|
|
12
|
+
/** <workspace>\.git when it is a real folder (not a link or a "gitdir:" file). */
|
|
13
|
+
export function plainGitDir(workspace) {
|
|
14
|
+
const dir = path.join(workspace, '.git');
|
|
15
|
+
return dirExists(dir) && !isLink(dir) ? dir : null;
|
|
16
|
+
}
|
|
17
|
+
export function gitState(dir) {
|
|
18
|
+
return {
|
|
19
|
+
config: dir ? configLines(dir) : [],
|
|
20
|
+
hooks: dir ? filesIn(path.join(dir, 'hooks'), isHook) : {},
|
|
21
|
+
redirects: dir ? REDIRECTS.filter((n) => fs.existsSync(path.join(dir, n))) : [],
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
/** New or changed hooks and new redirect files are quarantined; new config that runs programs is commented out. */
|
|
25
|
+
export function guardGitDir(dir, before) {
|
|
26
|
+
const hooksDir = path.join(dir, 'hooks');
|
|
27
|
+
const hooksNow = filesIn(hooksDir, isHook);
|
|
28
|
+
return [
|
|
29
|
+
...quarantine(hooksDir, Object.keys(hooksNow).filter((n) => before.hooks[n] !== hooksNow[n]), dir, 'hook'),
|
|
30
|
+
...quarantine(dir, REDIRECTS.filter((n) => fs.existsSync(path.join(dir, n)) && !before.redirects.includes(n)), dir, 'git'),
|
|
31
|
+
...disableConfig(dir, before.config),
|
|
32
|
+
];
|
|
33
|
+
}
|
|
34
|
+
/** The project's own .git; a .git replaced by a link or a "gitdir:" file is reported, never followed. */
|
|
35
|
+
export class GitDirRule {
|
|
36
|
+
kind = 'git-dir';
|
|
37
|
+
check(workspace, before) {
|
|
38
|
+
const dir = plainGitDir(workspace);
|
|
39
|
+
if (dir)
|
|
40
|
+
return guardGitDir(dir, before);
|
|
41
|
+
const replaced = before.gitDir && fs.existsSync(path.join(workspace, '.git'));
|
|
42
|
+
if (!replaced)
|
|
43
|
+
return [];
|
|
44
|
+
return [
|
|
45
|
+
{
|
|
46
|
+
kind: 'git',
|
|
47
|
+
detail: '.git was replaced by a link or a "gitdir:" file inside the sandbox. Do not run git in ' +
|
|
48
|
+
workspace +
|
|
49
|
+
' until you have checked it.',
|
|
50
|
+
},
|
|
51
|
+
];
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export type { GitState, RepoFinding, RepoSnapshot } from './types.js';
|
|
2
|
+
export { RepoGuard } from './repo-guard.js';
|
|
3
|
+
export { RepoGuardStore, type RecordedFinding } from './store.js';
|
|
4
|
+
export { RISKY, isMarked, markFromSandbox, watchAndMark } from './mark-of-the-web.js';
|
|
5
|
+
export { readDataSize, readMarkedProjects, saveDataSize, saveMarkedProjects } from './watch-state.js';
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { RepoGuard } from './repo-guard.js';
|
|
2
|
+
export { RepoGuardStore } from './store.js';
|
|
3
|
+
export { RISKY, isMarked, markFromSandbox, watchAndMark } from './mark-of-the-web.js';
|
|
4
|
+
export { readDataSize, readMarkedProjects, saveDataSize, saveMarkedProjects } from './watch-state.js';
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** What Windows runs when you open it (not source files such as .js or .py: those need a program you choose). */
|
|
2
|
+
export declare const RISKY: RegExp;
|
|
3
|
+
/** Marks one file if it is a program or script (and a plain file, not a link). Returns true when it marked it. */
|
|
4
|
+
export declare function markFromSandbox(file: string): boolean;
|
|
5
|
+
/** Has this file the mark? */
|
|
6
|
+
export declare function isMarked(file: string): boolean;
|
|
7
|
+
/** Watches the projects while the sandbox runs and marks what appears or changes; returns a function that stops it. */
|
|
8
|
+
export declare function watchAndMark(projects: readonly string[], note?: (message: string) => void): () => void;
|