windows-development-sandbox 1.10.0 → 1.11.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/README.md +64 -17
- package/config.example.json +5 -1
- package/dist/app/features/accounts/accounts.def.d.ts +122 -0
- package/dist/app/features/accounts/accounts.def.js +243 -0
- package/dist/app/features/accounts/accounts.run.d.ts +51 -0
- package/dist/app/features/accounts/accounts.run.js +125 -0
- package/dist/app/features/accounts/index.d.ts +2 -0
- package/dist/app/features/accounts/index.js +3 -0
- package/dist/app/features/agents/agent-entry.d.ts +17 -0
- package/dist/app/features/agents/agent-entry.js +50 -0
- package/dist/app/features/agents/agents.def.d.ts +65 -0
- package/dist/app/features/agents/agents.def.js +142 -0
- package/dist/app/features/agents/agents.run.d.ts +31 -0
- package/dist/app/features/agents/agents.run.js +189 -0
- package/dist/app/features/agents/index.d.ts +3 -0
- package/dist/app/features/agents/index.js +4 -0
- package/dist/app/features/apps/apps-rows.d.ts +31 -0
- package/dist/app/features/apps/apps-rows.js +73 -0
- package/dist/app/features/apps/apps.def.d.ts +181 -0
- package/dist/app/features/apps/apps.def.js +264 -0
- package/dist/app/features/apps/apps.run.d.ts +58 -0
- package/dist/app/features/apps/apps.run.js +76 -0
- package/dist/app/features/apps/index.d.ts +3 -0
- package/dist/app/features/apps/index.js +4 -0
- package/dist/app/features/data/data.def.d.ts +154 -0
- package/dist/app/features/data/data.def.js +201 -0
- package/dist/app/features/data/data.run.d.ts +46 -0
- package/dist/app/features/data/data.run.js +141 -0
- package/dist/app/features/data/index.d.ts +2 -0
- package/dist/app/features/data/index.js +3 -0
- package/dist/app/features/defs.d.ts +952 -4
- package/dist/app/features/defs.js +147 -10
- package/dist/app/features/engine/engine.def.d.ts +228 -0
- package/dist/app/features/engine/engine.def.js +194 -0
- package/dist/app/features/engine/engine.run.d.ts +72 -0
- package/dist/app/features/engine/engine.run.js +77 -0
- package/dist/app/features/engine/index.d.ts +2 -0
- package/dist/app/features/engine/index.js +4 -0
- package/dist/app/features/files/files.def.d.ts +51 -0
- package/dist/app/features/files/files.def.js +38 -0
- package/dist/app/features/files/files.run.d.ts +20 -0
- package/dist/app/features/files/files.run.js +59 -0
- package/dist/app/features/files/index.d.ts +2 -0
- package/dist/app/features/files/index.js +3 -0
- package/dist/app/features/github/github.def.d.ts +80 -0
- package/dist/app/features/github/github.def.js +142 -0
- package/dist/app/features/github/github.run.d.ts +36 -0
- package/dist/app/features/github/github.run.js +59 -0
- package/dist/app/features/github/index.d.ts +2 -0
- package/dist/app/features/github/index.js +3 -0
- package/dist/app/features/health/health.def.d.ts +275 -0
- package/dist/app/features/health/health.def.js +281 -0
- package/dist/app/features/health/health.run.d.ts +125 -0
- package/dist/app/features/health/health.run.js +204 -0
- package/dist/app/features/health/index.d.ts +2 -0
- package/dist/app/features/health/index.js +3 -0
- package/dist/app/features/logs/index.d.ts +2 -0
- package/dist/app/features/logs/index.js +3 -0
- package/dist/app/features/logs/logs.def.d.ts +78 -0
- package/dist/app/features/logs/logs.def.js +115 -0
- package/dist/app/features/logs/logs.run.d.ts +20 -0
- package/dist/app/features/logs/logs.run.js +42 -0
- package/dist/app/features/projects/index.d.ts +2 -0
- package/dist/app/features/projects/index.js +3 -0
- package/dist/app/features/projects/projects.def.d.ts +101 -0
- package/dist/app/features/projects/projects.def.js +208 -0
- package/dist/app/features/projects/projects.run.d.ts +56 -0
- package/dist/app/features/projects/projects.run.js +155 -0
- package/dist/app/features/sandbox/sandbox.def.js +11 -5
- package/dist/app/features/sessions/sessions.def.js +3 -0
- package/dist/app/features/settings/categories.def.js +3 -2
- package/dist/{cli/menu/settings/share.d.ts → app/features/settings/settings-share.d.ts} +1 -1
- package/dist/{cli/menu/settings/share.js → app/features/settings/settings-share.js} +3 -2
- package/dist/app/features/settings/settings.def.d.ts +22 -5
- package/dist/app/features/settings/settings.def.js +81 -6
- package/dist/app/features/settings/settings.run.d.ts +17 -0
- package/dist/app/features/settings/settings.run.js +89 -4
- package/dist/app/features/storage/index.d.ts +2 -0
- package/dist/app/features/storage/index.js +3 -0
- package/dist/app/features/storage/storage.def.d.ts +133 -0
- package/dist/app/features/storage/storage.def.js +225 -0
- package/dist/app/features/storage/storage.run.d.ts +62 -0
- package/dist/app/features/storage/storage.run.js +370 -0
- package/dist/app/features/updates/index.d.ts +3 -0
- package/dist/app/features/updates/index.js +4 -0
- package/dist/app/features/updates/update-lines.d.ts +13 -0
- package/dist/app/features/updates/update-lines.js +61 -0
- package/dist/app/features/updates/updates.def.d.ts +89 -0
- package/dist/app/features/updates/updates.def.js +225 -0
- package/dist/app/features/updates/updates.run.d.ts +48 -0
- package/dist/app/features/updates/updates.run.js +154 -0
- package/dist/app/features/vpn/index.d.ts +2 -0
- package/dist/app/features/vpn/index.js +3 -0
- package/dist/app/features/vpn/vpn.def.d.ts +112 -0
- package/dist/app/features/vpn/vpn.def.js +174 -0
- package/dist/app/features/vpn/vpn.run.d.ts +37 -0
- package/dist/app/features/vpn/vpn.run.js +54 -0
- package/dist/app/features/web/index.d.ts +2 -0
- package/dist/app/features/web/index.js +3 -0
- package/dist/app/features/web/web.def.d.ts +33 -0
- package/dist/app/features/web/web.def.js +90 -0
- package/dist/app/features/web/web.run.d.ts +24 -0
- package/dist/app/features/web/web.run.js +93 -0
- package/dist/app/kernel/define.d.ts +10 -1
- package/dist/app/kernel/io.d.ts +34 -0
- package/dist/app/kernel/io.js +9 -0
- package/dist/app/kernel/rpc.d.ts +17 -0
- package/dist/app/kernel/text.d.ts +2 -0
- package/dist/app/kernel/text.js +7 -0
- package/dist/app/kernel/view.d.ts +24 -1
- package/dist/app/kernel/view.js +1 -1
- package/dist/app/registry.js +74 -1
- package/dist/cli/args.js +1 -1
- package/dist/cli/commands/context.d.ts +7 -0
- package/dist/cli/commands/context.js +29 -2
- package/dist/cli/commands/engine.js +5 -58
- package/dist/cli/commands/github.d.ts +2 -0
- package/dist/cli/commands/github.js +11 -0
- package/dist/cli/commands/index.d.ts +3 -5
- package/dist/cli/commands/index.js +3 -5
- package/dist/cli/commands/launch/launch.js +21 -4
- package/dist/cli/commands/launch/running.js +4 -1
- package/dist/cli/commands/maintenance/config.js +1 -6
- package/dist/cli/commands/maintenance/index.d.ts +0 -1
- package/dist/cli/commands/maintenance/index.js +1 -2
- package/dist/cli/commands/maintenance/logs.js +27 -32
- package/dist/cli/commands/maintenance/migrate.d.ts +0 -8
- package/dist/cli/commands/maintenance/migrate.js +2 -44
- package/dist/cli/commands/maintenance/update.d.ts +0 -19
- package/dist/cli/commands/maintenance/update.js +1 -99
- package/dist/cli/commands/projects/index.d.ts +0 -1
- package/dist/cli/commands/projects/index.js +0 -1
- package/dist/cli/commands/registry.d.ts +1 -1
- package/dist/cli/commands/registry.js +29 -11
- package/dist/cli/commands/repair/checks/data.js +1 -1
- package/dist/cli/commands/repair/checks/hcs.js +28 -1
- package/dist/cli/commands/repair/checks/sandbox.js +1 -1
- package/dist/cli/commands/repair/health-run.d.ts +30 -0
- package/dist/cli/commands/repair/health-run.js +32 -0
- package/dist/cli/commands/repair/printer.d.ts +2 -2
- package/dist/cli/commands/repair/printer.js +2 -11
- package/dist/cli/commands/repair/run.d.ts +1 -21
- package/dist/cli/commands/repair/run.js +13 -70
- package/dist/cli/commands/storage/index.d.ts +0 -1
- package/dist/cli/commands/storage/index.js +0 -1
- package/dist/cli/commands/storage/offer.js +6 -2
- package/dist/cli/commands/vpn.d.ts +1 -3
- package/dist/cli/commands/vpn.js +8 -89
- package/dist/cli/commands/web.d.ts +2 -1
- package/dist/cli/commands/web.js +14 -78
- package/dist/cli/index.js +3 -2
- package/dist/cli/manifest.d.ts +16 -153
- package/dist/cli/manifest.js +20 -50
- package/dist/cli/menu/command-form.js +1 -2
- package/dist/cli/menu/io-menu.d.ts +2 -2
- package/dist/cli/menu/io-menu.js +6 -4
- package/dist/cli/menu/menu.js +1 -1
- package/dist/cli/menu/pages/accounts-page.d.ts +5 -17
- package/dist/cli/menu/pages/accounts-page.js +28 -170
- package/dist/cli/menu/pages/agents-page.d.ts +17 -18
- package/dist/cli/menu/pages/agents-page.js +67 -124
- package/dist/cli/menu/pages/apps-page.d.ts +15 -8
- package/dist/cli/menu/pages/apps-page.js +121 -29
- package/dist/cli/menu/pages/list-page.js +10 -1
- package/dist/cli/menu/pages/maintenance-page.d.ts +51 -52
- package/dist/cli/menu/pages/maintenance-page.js +246 -427
- package/dist/cli/menu/pages/sandbox-page.d.ts +3 -5
- package/dist/cli/menu/pages/sandbox-page.js +34 -112
- package/dist/cli/menu/pages/settings-page.d.ts +21 -3
- package/dist/cli/menu/pages/settings-page.js +89 -17
- package/dist/cli/menu/render-view.js +2 -1
- package/dist/cli/menu/settings/index.d.ts +0 -1
- package/dist/cli/menu/settings/index.js +3 -3
- package/dist/cli/menu/views.js +28 -0
- package/dist/cli/operations/handler.js +7 -3
- package/dist/cli/operations/input.d.ts +1 -1
- package/dist/cli/operations/input.js +29 -5
- package/dist/cli/operations/io-cli.js +9 -1
- package/dist/cli/operations/spec.js +8 -2
- package/dist/cli/output/render-view.js +2 -0
- package/dist/cli/{commands/data/collect.js → services/data-collect.js} +2 -2
- package/dist/cli/{commands/data/remove.js → services/data-remove.js} +2 -2
- package/dist/cli/services/data-service.d.ts +1 -1
- package/dist/cli/services/data-service.js +2 -2
- package/dist/cli/services/databases-service.d.ts +5 -0
- package/dist/cli/services/databases-service.js +15 -0
- package/dist/cli/services/health-service.d.ts +8 -4
- package/dist/cli/services/health-service.js +10 -8
- package/dist/cli/services/index.d.ts +4 -1
- package/dist/cli/services/index.js +4 -1
- package/dist/cli/services/logs-service.d.ts +7 -0
- package/dist/cli/services/logs-service.js +13 -0
- package/dist/cli/services/storage-service.d.ts +19 -0
- package/dist/cli/services/storage-service.js +71 -0
- package/dist/cli/services/vpn-service.d.ts +6 -4
- package/dist/cli/services/vpn-service.js +5 -11
- package/dist/cli/services/web-service.d.ts +4 -3
- package/dist/cli/services/web-service.js +12 -32
- package/dist/core/config/defaults.js +2 -1
- package/dist/core/schema/config.d.ts +5 -0
- package/dist/core/schema/config.js +2 -0
- package/dist/core/schema/github.d.ts +4 -0
- package/dist/core/schema/github.js +7 -0
- package/dist/core/schema/index.d.ts +1 -0
- package/dist/core/schema/index.js +1 -0
- package/dist/core/schema/profile.d.ts +1 -0
- package/dist/core/schema/profile.js +3 -0
- package/dist/core/schema/sandbox.js +3 -3
- package/dist/core/schema/toolchains.js +2 -2
- package/dist/core/types.d.ts +6 -3
- package/dist/guest/boot/boot.js +8 -0
- package/dist/guest/daemon/daemon.js +1 -1
- package/dist/guest/daemon/sessions.d.ts +3 -2
- package/dist/guest/daemon/sessions.js +38 -7
- package/dist/guest/governor/core.d.ts +44 -0
- package/dist/guest/governor/core.js +124 -0
- package/dist/guest/governor/decide.d.ts +46 -18
- package/dist/guest/governor/decide.js +136 -82
- package/dist/guest/governor/governor.d.ts +2 -38
- package/dist/guest/governor/governor.js +33 -113
- package/dist/guest/governor/index.d.ts +1 -0
- package/dist/guest/governor/index.js +1 -0
- package/dist/guest/network/firewall.d.ts +2 -0
- package/dist/guest/network/firewall.js +3 -3
- package/dist/guest/sessions/viewer.js +5 -1
- package/dist/guest/setup/github-token.d.ts +7 -0
- package/dist/guest/setup/github-token.js +65 -0
- package/dist/guest/toolchains/languages/node.js +11 -1
- package/dist/guest/toolchains/native/rust-extras.js +2 -2
- package/dist/guest/toolchains/tools/cli.d.ts +8 -0
- package/dist/guest/toolchains/tools/cli.js +16 -2
- package/dist/guest/vpn/openvpn.d.ts +5 -0
- package/dist/guest/vpn/openvpn.js +14 -1
- package/dist/guest/vpn/vpn.js +55 -16
- package/dist/guest/vpn/wireguard.js +2 -0
- package/dist/host/channel/attach.d.ts +1 -0
- package/dist/host/channel/attach.js +1 -0
- package/dist/host/channel/channel.d.ts +1 -1
- package/dist/host/channel/channel.js +2 -2
- package/dist/host/engines/hcs/check.d.ts +1 -0
- package/dist/host/engines/hcs/check.js +1 -1
- package/dist/host/engines/hcs/engine.d.ts +1 -1
- package/dist/host/engines/hcs/engine.js +6 -4
- package/dist/host/engines/hcs/helper.d.ts +11 -0
- package/dist/host/engines/hcs/helper.js +31 -2
- package/dist/host/engines/hcs/leftovers.d.ts +42 -0
- package/dist/host/engines/hcs/leftovers.js +101 -0
- package/dist/host/engines/index.d.ts +1 -0
- package/dist/host/engines/index.js +1 -0
- package/dist/host/github/deliver.d.ts +13 -0
- package/dist/host/github/deliver.js +51 -0
- package/dist/host/github/index.d.ts +2 -0
- package/dist/host/github/index.js +3 -0
- package/dist/host/github/token.d.ts +21 -0
- package/dist/host/github/token.js +74 -0
- package/dist/host/launch/generate.js +11 -5
- package/dist/host/launch/index.d.ts +1 -1
- package/dist/host/launch/index.js +1 -1
- package/dist/host/launch/session-file.js +1 -2
- package/dist/host/launch/wsb-file.d.ts +11 -7
- package/dist/host/launch/wsb-file.js +30 -12
- package/dist/host/life/watchdog.d.ts +9 -0
- package/dist/host/life/watchdog.js +17 -1
- package/dist/host/sandbox/tasklist.d.ts +6 -0
- package/dist/host/sandbox/tasklist.js +37 -0
- package/dist/host/secrets/launch-secrets.d.ts +2 -1
- package/dist/host/secrets/launch-secrets.js +4 -2
- package/dist/host/vpn/status.js +13 -3
- package/dist/host/web/backend.d.ts +1 -3
- package/dist/host/web/index.d.ts +2 -1
- package/dist/host/web/index.js +2 -1
- package/dist/host/web/live.d.ts +23 -0
- package/dist/host/web/live.js +107 -0
- package/dist/host/web/rpc.d.ts +6 -1
- package/dist/host/web/rpc.js +23 -31
- package/dist/host/web/runner.d.ts +4 -0
- package/dist/host/web/runner.js +12 -1
- package/dist/host/web/server.d.ts +30 -2
- package/dist/host/web/server.js +87 -29
- package/dist/host/web/state.d.ts +1 -0
- package/dist/host/web/state.js +2 -0
- package/dist/runtime/agent.js +30 -6
- package/dist/runtime/daemon.js +323 -176
- package/dist/runtime/db.js +30 -6
- package/dist/runtime/main.js +375 -76
- package/dist/runtime/netproxy.js +30 -6
- package/dist/runtime/view.js +495 -146
- package/dist/selftest/app.test.js +620 -12
- package/dist/selftest/channel.test.js +18 -1
- package/dist/selftest/cli.test.js +1 -1
- package/dist/selftest/config.test.js +1 -1
- package/dist/selftest/contained.test.js +1 -1
- package/dist/selftest/data.test.js +1 -2
- package/dist/selftest/engine.test.js +3 -1
- package/dist/selftest/github.test.d.ts +2 -0
- package/dist/selftest/github.test.js +243 -0
- package/dist/selftest/hcs.test.js +105 -8
- package/dist/selftest/health.test.js +71 -0
- package/dist/selftest/heavy-load.test.js +132 -72
- package/dist/selftest/index.js +4 -0
- package/dist/selftest/layout.test.js +8 -0
- package/dist/selftest/live-terminal.test.js +74 -0
- package/dist/selftest/menu-screens.js +171 -56
- package/dist/selftest/menu.test.js +54 -37
- package/dist/selftest/migrate.test.js +14 -12
- package/dist/selftest/powershell-variables.test.d.ts +2 -0
- package/dist/selftest/powershell-variables.test.js +61 -0
- package/dist/selftest/support/engine-golden.js +1 -0
- package/dist/selftest/support/fixtures.d.ts +4 -0
- package/dist/selftest/support/web-preview.d.ts +1 -0
- package/dist/selftest/support/web-preview.js +856 -0
- package/dist/selftest/update-service.test.js +15 -8
- package/dist/selftest/vpn.test.js +86 -2
- package/dist/selftest/web.test.js +58 -11
- package/dist/shared/channel/run-dir.d.ts +2 -0
- package/dist/shared/channel/run-dir.js +3 -0
- package/dist/shared/channel/schema.d.ts +7 -0
- package/dist/shared/channel/schema.js +9 -1
- package/dist/shared/channel/secrets.d.ts +1 -0
- package/dist/shared/channel/secrets.js +3 -0
- package/dist/shared/github/index.d.ts +1 -0
- package/dist/shared/github/index.js +2 -0
- package/dist/shared/github/token.d.ts +29 -0
- package/dist/shared/github/token.js +89 -0
- package/dist/shared/memory/policy.d.ts +33 -12
- package/dist/shared/memory/policy.js +50 -19
- package/dist/shared/pty/ctrl-c.d.ts +18 -0
- package/dist/shared/pty/ctrl-c.js +36 -0
- package/dist/shared/pty/index.d.ts +1 -0
- package/dist/shared/pty/index.js +1 -0
- package/dist/shared/pty/terminal.d.ts +2 -0
- package/dist/shared/pty/terminal.js +21 -2
- package/dist/shared/vpn/kill-switch.d.ts +13 -2
- package/dist/shared/vpn/kill-switch.js +88 -8
- package/dist/shared/web/protocol.d.ts +0 -4
- package/dist/sync/watcher.js +1 -1
- package/dist/web/index.html +2 -2
- package/dist/web/{main-T5DMCHYV.css → main-6JF3ASB5.css} +1 -1
- package/dist/web/main-Z645W45E.js +219 -0
- package/native/csharp/HcsHost/AssemblyInfo.cs +3 -3
- package/native/csharp/HostTools/AssemblyInfo.cs +3 -3
- package/package.json +10 -3
- package/sandbox/csharp/MemGov.cs +240 -38
- package/sandbox/csharp/PtyHost.cs +104 -15
- package/sandbox/csharp/SandboxTools/CpuCap.cs +50 -1
- package/sandbox/csharp/SandboxTools/Program.cs +1 -1
- package/sandbox/scripts/repair-wmi-services.ps1 +26 -0
- package/schemas/config.schema.json +19 -5
- package/schemas/sandbox-config.schema.json +7 -3
- package/dist/cli/commands/accounts.d.ts +0 -2
- package/dist/cli/commands/accounts.js +0 -96
- package/dist/cli/commands/data/clean.d.ts +0 -3
- package/dist/cli/commands/data/clean.js +0 -60
- package/dist/cli/commands/data/index.d.ts +0 -4
- package/dist/cli/commands/data/index.js +0 -62
- package/dist/cli/commands/maintenance/clean.d.ts +0 -2
- package/dist/cli/commands/maintenance/clean.js +0 -24
- package/dist/cli/commands/maintenance/config-share.d.ts +0 -12
- package/dist/cli/commands/maintenance/config-share.js +0 -80
- package/dist/cli/commands/projects/projects.d.ts +0 -2
- package/dist/cli/commands/projects/projects.js +0 -162
- package/dist/cli/commands/storage/contained.d.ts +0 -3
- package/dist/cli/commands/storage/contained.js +0 -179
- package/dist/cli/commands/storage/storage.d.ts +0 -8
- package/dist/cli/commands/storage/storage.js +0 -179
- package/dist/cli/menu/add-agent.d.ts +0 -47
- package/dist/cli/menu/add-agent.js +0 -168
- package/dist/cli/menu/apps.d.ts +0 -69
- package/dist/cli/menu/apps.js +0 -214
- package/dist/cli/menu/data-folder.d.ts +0 -18
- package/dist/cli/menu/data-folder.js +0 -99
- package/dist/cli/menu/share-settings.d.ts +0 -21
- package/dist/cli/menu/share-settings.js +0 -112
- package/dist/cli/menu/vpn-login.d.ts +0 -16
- package/dist/cli/menu/vpn-login.js +0 -74
- package/dist/web/main-NRRS5O6Z.js +0 -157
- /package/dist/cli/{commands/data/collect.d.ts → services/data-collect.d.ts} +0 -0
- /package/dist/cli/{commands/data/remove.d.ts → services/data-remove.d.ts} +0 -0
|
@@ -8,7 +8,7 @@ using System.Runtime.InteropServices;
|
|
|
8
8
|
[assembly: AssemblyCompany("windows-development-sandbox (open source)")]
|
|
9
9
|
[assembly: AssemblyProduct("Windows Development Sandbox")]
|
|
10
10
|
[assembly: AssemblyCopyright("MIT License, windows-development-sandbox contributors")]
|
|
11
|
-
[assembly: AssemblyVersion("1.
|
|
12
|
-
[assembly: AssemblyFileVersion("1.
|
|
13
|
-
[assembly: AssemblyInformationalVersion("1.
|
|
11
|
+
[assembly: AssemblyVersion("1.11.3.0")]
|
|
12
|
+
[assembly: AssemblyFileVersion("1.11.3.0")]
|
|
13
|
+
[assembly: AssemblyInformationalVersion("1.11.3")]
|
|
14
14
|
[assembly: ComVisible(false)]
|
|
@@ -8,7 +8,7 @@ using System.Runtime.InteropServices;
|
|
|
8
8
|
[assembly: AssemblyCompany("windows-development-sandbox (open source)")]
|
|
9
9
|
[assembly: AssemblyProduct("Windows Development Sandbox")]
|
|
10
10
|
[assembly: AssemblyCopyright("MIT License, windows-development-sandbox contributors")]
|
|
11
|
-
[assembly: AssemblyVersion("1.
|
|
12
|
-
[assembly: AssemblyFileVersion("1.
|
|
13
|
-
[assembly: AssemblyInformationalVersion("1.
|
|
11
|
+
[assembly: AssemblyVersion("1.11.3.0")]
|
|
12
|
+
[assembly: AssemblyFileVersion("1.11.3.0")]
|
|
13
|
+
[assembly: AssemblyInformationalVersion("1.11.3")]
|
|
14
14
|
[assembly: ComVisible(false)]
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "windows-development-sandbox",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.11.3",
|
|
4
4
|
"description": "A disposable Windows Sandbox for development, with or without an AI agent (Claude Code, Codex, Gemini, opencode, ...): the folder you run it from is the workspace, toolchains and databases for your project install themselves, and nothing else on your PC is reachable.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"LICENSE"
|
|
43
43
|
],
|
|
44
44
|
"scripts": {
|
|
45
|
-
"build": "tsc -p tsconfig.json && node scripts/bundle.mjs && node scripts/bundle-web.mjs && node scripts/schemas.mjs",
|
|
45
|
+
"build": "tsc -p tsconfig.json && tsc -p web/tsconfig.json --noEmit && node scripts/bundle.mjs && node scripts/bundle-web.mjs && node scripts/schemas.mjs",
|
|
46
46
|
"clean": "node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\"",
|
|
47
47
|
"rebuild": "npm run clean && npm run build",
|
|
48
48
|
"test": "npm run build && node dist/bin/agent-sandbox.js self-test",
|
|
@@ -55,7 +55,9 @@
|
|
|
55
55
|
"doctor": "node dist/bin/agent-sandbox.js doctor",
|
|
56
56
|
"lint": "eslint src scripts web",
|
|
57
57
|
"format": "prettier --write src scripts web",
|
|
58
|
-
"format:check": "prettier --check src scripts web"
|
|
58
|
+
"format:check": "prettier --check src scripts web",
|
|
59
|
+
"web:preview": "node dist/selftest/support/web-preview.js",
|
|
60
|
+
"web:shots": "node scripts/web-shots.mjs"
|
|
59
61
|
},
|
|
60
62
|
"publishConfig": {
|
|
61
63
|
"access": "public"
|
|
@@ -98,6 +100,7 @@
|
|
|
98
100
|
"@mantine/hooks": "^7.17.8",
|
|
99
101
|
"@mantine/modals": "^7.17.8",
|
|
100
102
|
"@mantine/notifications": "^7.17.8",
|
|
103
|
+
"@mantine/spotlight": "7.17.8",
|
|
101
104
|
"@tabler/icons-react": "^3.49.0",
|
|
102
105
|
"@tanstack/react-query": "^5.104.3",
|
|
103
106
|
"@types/lodash": "^4.17.26",
|
|
@@ -106,10 +109,14 @@
|
|
|
106
109
|
"@types/react-dom": "^18.3.7",
|
|
107
110
|
"@types/ws": "^8.18.2",
|
|
108
111
|
"@xterm/addon-fit": "^0.11.0",
|
|
112
|
+
"@xterm/addon-search": "0.16.0",
|
|
113
|
+
"@xterm/addon-unicode11": "0.9.0",
|
|
114
|
+
"@xterm/addon-web-links": "0.12.0",
|
|
109
115
|
"@xterm/xterm": "^6.0.0",
|
|
110
116
|
"esbuild": "^0.28.2",
|
|
111
117
|
"eslint": "^9.39.5",
|
|
112
118
|
"mantine-form-zod-resolver": "^1.3.0",
|
|
119
|
+
"playwright-core": "1.63.0",
|
|
113
120
|
"prettier": "^3.9.10",
|
|
114
121
|
"react": "^18.3.1",
|
|
115
122
|
"react-dom": "^18.3.1",
|
package/sandbox/csharp/MemGov.cs
CHANGED
|
@@ -35,6 +35,24 @@ static class MemGov
|
|
|
35
35
|
private const uint IdleClass = 0x00000040;
|
|
36
36
|
private const uint BelowNormalClass = 0x00004000;
|
|
37
37
|
private const uint NormalClass = 0x00000020;
|
|
38
|
+
// The throttle job: compilers join it from the governor's step 2; its CPU cap follows the dial.
|
|
39
|
+
private const string ThrottleJobName = "Local\\AgentSandboxBuildThrottle";
|
|
40
|
+
private const uint ProcessTerminate = 0x0001;
|
|
41
|
+
private const uint ProcessSetQuota = 0x0100;
|
|
42
|
+
private const int JobObjectCpuRateControlInformation = 15;
|
|
43
|
+
private const uint CpuRateEnable = 0x1;
|
|
44
|
+
private const uint CpuRateHardCap = 0x4;
|
|
45
|
+
private const int ProcessMemoryPriorityClass = 0;
|
|
46
|
+
private const uint MemoryPriorityLow = 2;
|
|
47
|
+
private const uint MemoryPriorityNormal = 5;
|
|
48
|
+
|
|
49
|
+
// JOBOBJECT_CPU_RATE_CONTROL_INFORMATION (CpuRate in hundredths of a percent).
|
|
50
|
+
[StructLayout(LayoutKind.Sequential)]
|
|
51
|
+
private struct CpuRateControl
|
|
52
|
+
{
|
|
53
|
+
public uint ControlFlags;
|
|
54
|
+
public uint CpuRate;
|
|
55
|
+
}
|
|
38
56
|
|
|
39
57
|
// MEMORYSTATUSEX.
|
|
40
58
|
[StructLayout(LayoutKind.Sequential)]
|
|
@@ -51,6 +69,23 @@ static class MemGov
|
|
|
51
69
|
public ulong AvailExtendedVirtual;
|
|
52
70
|
}
|
|
53
71
|
|
|
72
|
+
// PROCESS_MEMORY_COUNTERS_EX (PrivateUsage is the private memory Process.PrivateMemorySize64 reported).
|
|
73
|
+
[StructLayout(LayoutKind.Sequential)]
|
|
74
|
+
private struct MemoryCounters
|
|
75
|
+
{
|
|
76
|
+
public uint Size;
|
|
77
|
+
public uint PageFaultCount;
|
|
78
|
+
public UIntPtr PeakWorkingSetSize;
|
|
79
|
+
public UIntPtr WorkingSetSize;
|
|
80
|
+
public UIntPtr QuotaPeakPagedPoolUsage;
|
|
81
|
+
public UIntPtr QuotaPagedPoolUsage;
|
|
82
|
+
public UIntPtr QuotaPeakNonPagedPoolUsage;
|
|
83
|
+
public UIntPtr QuotaNonPagedPoolUsage;
|
|
84
|
+
public UIntPtr PagefileUsage;
|
|
85
|
+
public UIntPtr PeakPagefileUsage;
|
|
86
|
+
public UIntPtr PrivateUsage;
|
|
87
|
+
}
|
|
88
|
+
|
|
54
89
|
private static class NativeMethods
|
|
55
90
|
{
|
|
56
91
|
[DllImport("kernel32.dll", SetLastError = true)]
|
|
@@ -77,6 +112,27 @@ static class MemGov
|
|
|
77
112
|
[DllImport("kernel32.dll", SetLastError = true)]
|
|
78
113
|
public static extern bool CloseHandle(IntPtr handle);
|
|
79
114
|
|
|
115
|
+
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
|
|
116
|
+
public static extern IntPtr CreateJobObjectW(IntPtr attributes, string name);
|
|
117
|
+
|
|
118
|
+
[DllImport("kernel32.dll", SetLastError = true)]
|
|
119
|
+
public static extern bool AssignProcessToJobObject(IntPtr job, IntPtr process);
|
|
120
|
+
|
|
121
|
+
[DllImport("kernel32.dll", SetLastError = true)]
|
|
122
|
+
public static extern bool SetInformationJobObject(IntPtr job, int infoClass, ref CpuRateControl info, int length);
|
|
123
|
+
|
|
124
|
+
[DllImport("kernel32.dll", SetLastError = true)]
|
|
125
|
+
public static extern bool SetProcessInformation(IntPtr process, int infoClass, ref uint info, int length);
|
|
126
|
+
|
|
127
|
+
[DllImport("kernel32.dll", SetLastError = true)]
|
|
128
|
+
public static extern bool SetProcessWorkingSetSize(IntPtr process, IntPtr minimum, IntPtr maximum);
|
|
129
|
+
|
|
130
|
+
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
|
|
131
|
+
public static extern bool QueryFullProcessImageNameW(IntPtr process, uint flags, StringBuilder name, ref uint size);
|
|
132
|
+
|
|
133
|
+
[DllImport("kernel32.dll", EntryPoint = "K32GetProcessMemoryInfo", SetLastError = true)]
|
|
134
|
+
public static extern bool GetProcessMemoryInfo(IntPtr process, ref MemoryCounters counters, uint size);
|
|
135
|
+
|
|
80
136
|
[DllImport("ntdll.dll")]
|
|
81
137
|
public static extern int NtSuspendProcess(IntPtr process);
|
|
82
138
|
|
|
@@ -90,6 +146,7 @@ static class MemGov
|
|
|
90
146
|
/// <summary>The paused process ids on disk, so a memgov that is killed mid-pause is undone by the next one.</summary>
|
|
91
147
|
private static readonly string HeldFile = Path.Combine(Path.GetTempPath(), "agent-sandbox-memgov-held.txt");
|
|
92
148
|
private static IntPtr job = IntPtr.Zero;
|
|
149
|
+
private static IntPtr throttleJob = IntPtr.Zero;
|
|
93
150
|
private static volatile bool stop;
|
|
94
151
|
|
|
95
152
|
static int Main(string[] args)
|
|
@@ -113,6 +170,8 @@ static class MemGov
|
|
|
113
170
|
}
|
|
114
171
|
// A memgov that ended without resuming (killed, crashed) left its pauses in the file: undo them first.
|
|
115
172
|
RecoverHeld();
|
|
173
|
+
// A memgov that ended while compilers were capped left the cap: lift it before anything else.
|
|
174
|
+
SetCpuRate(100);
|
|
116
175
|
Thread commands = new Thread(ReadCommands);
|
|
117
176
|
commands.IsBackground = true;
|
|
118
177
|
commands.Start();
|
|
@@ -136,15 +195,28 @@ static class MemGov
|
|
|
136
195
|
}
|
|
137
196
|
}
|
|
138
197
|
ResumeAll();
|
|
198
|
+
SetCpuRate(100);
|
|
139
199
|
return 0;
|
|
140
200
|
}
|
|
141
201
|
|
|
202
|
+
/// <summary>The self-test's own job (MEMGOV_JOB_NAME, a name in the agents' job family), or null.</summary>
|
|
203
|
+
private static string TestJobName()
|
|
204
|
+
{
|
|
205
|
+
string name = Environment.GetEnvironmentVariable("MEMGOV_JOB_NAME");
|
|
206
|
+
return !string.IsNullOrEmpty(name) && name.StartsWith(AgentJobName + "Test", StringComparison.Ordinal) ? name : null;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
private static string JobName()
|
|
210
|
+
{
|
|
211
|
+
return TestJobName() ?? AgentJobName;
|
|
212
|
+
}
|
|
213
|
+
|
|
142
214
|
/// <summary>The job, opened once it exists (ptyhost makes it when the first agent starts).</summary>
|
|
143
215
|
private static IntPtr Job()
|
|
144
216
|
{
|
|
145
217
|
if (job == IntPtr.Zero)
|
|
146
218
|
{
|
|
147
|
-
job = NativeMethods.OpenJobObjectW(JobObjectQuery, false,
|
|
219
|
+
job = NativeMethods.OpenJobObjectW(JobObjectQuery, false, JobName());
|
|
148
220
|
}
|
|
149
221
|
return job;
|
|
150
222
|
}
|
|
@@ -164,36 +236,70 @@ static class MemGov
|
|
|
164
236
|
sb.Append(",\"commitAvailMb\":").Append(Mb(status.AvailPageFile));
|
|
165
237
|
sb.Append(",\"procs\":[");
|
|
166
238
|
bool first = true;
|
|
167
|
-
int self =
|
|
239
|
+
int self = SelfId;
|
|
168
240
|
foreach (int pid in JobProcessIds())
|
|
169
241
|
{
|
|
170
242
|
if (pid == self)
|
|
171
243
|
{
|
|
172
244
|
continue;
|
|
173
245
|
}
|
|
174
|
-
|
|
246
|
+
// Read everything first: a process that ends half way must not leave half an entry behind.
|
|
247
|
+
string entry = Entry(pid);
|
|
248
|
+
if (entry == null)
|
|
175
249
|
{
|
|
176
|
-
|
|
177
|
-
{
|
|
178
|
-
if (!first)
|
|
179
|
-
{
|
|
180
|
-
sb.Append(',');
|
|
181
|
-
}
|
|
182
|
-
first = false;
|
|
183
|
-
sb.Append("{\"pid\":").Append(pid.ToString(CultureInfo.InvariantCulture));
|
|
184
|
-
sb.Append(",\"name\":").Append(Json(p.ProcessName));
|
|
185
|
-
sb.Append(",\"mb\":").Append(Mb((ulong)p.PrivateMemorySize64));
|
|
186
|
-
sb.Append(",\"prio\":\"").Append(PriorityName(pid)).Append("\"}");
|
|
187
|
-
}
|
|
250
|
+
continue;
|
|
188
251
|
}
|
|
189
|
-
|
|
252
|
+
if (!first)
|
|
190
253
|
{
|
|
191
|
-
|
|
254
|
+
sb.Append(',');
|
|
192
255
|
}
|
|
256
|
+
first = false;
|
|
257
|
+
sb.Append(entry);
|
|
193
258
|
}
|
|
194
259
|
return sb.Append("]}").ToString();
|
|
195
260
|
}
|
|
196
261
|
|
|
262
|
+
private static readonly int SelfId = Process.GetCurrentProcess().Id;
|
|
263
|
+
|
|
264
|
+
/// <summary>
|
|
265
|
+
/// One process's line, read through one handle: its name, private memory and priority (null when it ended). Not
|
|
266
|
+
/// System.Diagnostics.Process, which reads the whole system's process list for every process it opens: with a
|
|
267
|
+
/// build's dozens of processes every two seconds that alone kept a CPU busy.
|
|
268
|
+
/// </summary>
|
|
269
|
+
private static string Entry(int pid)
|
|
270
|
+
{
|
|
271
|
+
IntPtr process = NativeMethods.OpenProcess(ProcessQueryLimited, false, pid);
|
|
272
|
+
if (process == IntPtr.Zero)
|
|
273
|
+
{
|
|
274
|
+
return null;
|
|
275
|
+
}
|
|
276
|
+
try
|
|
277
|
+
{
|
|
278
|
+
StringBuilder path = new StringBuilder(1024);
|
|
279
|
+
uint size = (uint)path.Capacity;
|
|
280
|
+
if (!NativeMethods.QueryFullProcessImageNameW(process, 0, path, ref size))
|
|
281
|
+
{
|
|
282
|
+
return null;
|
|
283
|
+
}
|
|
284
|
+
MemoryCounters counters = new MemoryCounters();
|
|
285
|
+
counters.Size = (uint)Marshal.SizeOf(typeof(MemoryCounters));
|
|
286
|
+
if (!NativeMethods.GetProcessMemoryInfo(process, ref counters, counters.Size))
|
|
287
|
+
{
|
|
288
|
+
return null;
|
|
289
|
+
}
|
|
290
|
+
uint c = NativeMethods.GetPriorityClass(process);
|
|
291
|
+
string priority = c == IdleClass ? "idle" : c == BelowNormalClass ? "below" : "normal";
|
|
292
|
+
return "{\"pid\":" + pid.ToString(CultureInfo.InvariantCulture)
|
|
293
|
+
+ ",\"name\":" + Json(Path.GetFileNameWithoutExtension(path.ToString(0, (int)size)))
|
|
294
|
+
+ ",\"mb\":" + Mb(counters.PrivateUsage.ToUInt64())
|
|
295
|
+
+ ",\"prio\":\"" + priority + "\"}";
|
|
296
|
+
}
|
|
297
|
+
finally
|
|
298
|
+
{
|
|
299
|
+
NativeMethods.CloseHandle(process);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
197
303
|
private static List<int> JobProcessIds()
|
|
198
304
|
{
|
|
199
305
|
List<int> ids = new List<int>();
|
|
@@ -224,28 +330,10 @@ static class MemGov
|
|
|
224
330
|
return ids;
|
|
225
331
|
}
|
|
226
332
|
|
|
227
|
-
private static string PriorityName(int pid)
|
|
228
|
-
{
|
|
229
|
-
IntPtr process = NativeMethods.OpenProcess(ProcessQueryLimited, false, pid);
|
|
230
|
-
if (process == IntPtr.Zero)
|
|
231
|
-
{
|
|
232
|
-
return "normal";
|
|
233
|
-
}
|
|
234
|
-
try
|
|
235
|
-
{
|
|
236
|
-
uint c = NativeMethods.GetPriorityClass(process);
|
|
237
|
-
return c == IdleClass ? "idle" : c == BelowNormalClass ? "below" : "normal";
|
|
238
|
-
}
|
|
239
|
-
finally
|
|
240
|
-
{
|
|
241
|
-
NativeMethods.CloseHandle(process);
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
|
|
245
333
|
/// <summary>Whether pid is a process of the agents' job and not this one: the only ones this program touches.</summary>
|
|
246
334
|
private static bool Allowed(int pid)
|
|
247
335
|
{
|
|
248
|
-
return pid !=
|
|
336
|
+
return pid != SelfId && JobProcessIds().Contains(pid);
|
|
249
337
|
}
|
|
250
338
|
|
|
251
339
|
private static void ReadCommands()
|
|
@@ -277,12 +365,39 @@ static class MemGov
|
|
|
277
365
|
stop = true;
|
|
278
366
|
return;
|
|
279
367
|
}
|
|
368
|
+
if (parts.Length == 2 && parts[0] == "cpurate")
|
|
369
|
+
{
|
|
370
|
+
int percent;
|
|
371
|
+
if (int.TryParse(parts[1], NumberStyles.Integer, CultureInfo.InvariantCulture, out percent))
|
|
372
|
+
{
|
|
373
|
+
SetCpuRate(percent);
|
|
374
|
+
}
|
|
375
|
+
return;
|
|
376
|
+
}
|
|
280
377
|
int pid;
|
|
281
|
-
if (parts.Length <
|
|
378
|
+
if (parts.Length < 2 || !int.TryParse(parts[1], NumberStyles.Integer, CultureInfo.InvariantCulture, out pid) || !Allowed(pid))
|
|
379
|
+
{
|
|
380
|
+
return;
|
|
381
|
+
}
|
|
382
|
+
if (parts[0] == "throttle")
|
|
383
|
+
{
|
|
384
|
+
Throttle(pid);
|
|
385
|
+
return;
|
|
386
|
+
}
|
|
387
|
+
if (parts[0] == "trim")
|
|
388
|
+
{
|
|
389
|
+
Trim(pid);
|
|
390
|
+
return;
|
|
391
|
+
}
|
|
392
|
+
if (parts.Length < 3)
|
|
282
393
|
{
|
|
283
394
|
return;
|
|
284
395
|
}
|
|
285
|
-
if (parts[0] == "
|
|
396
|
+
if (parts[0] == "memprio")
|
|
397
|
+
{
|
|
398
|
+
SetMemoryPriority(pid, parts[2] == "low" ? MemoryPriorityLow : MemoryPriorityNormal);
|
|
399
|
+
}
|
|
400
|
+
else if (parts[0] == "priority")
|
|
286
401
|
{
|
|
287
402
|
uint cls = parts[2] == "idle" ? IdleClass : parts[2] == "below" ? BelowNormalClass : NormalClass;
|
|
288
403
|
IntPtr process = NativeMethods.OpenProcess(ProcessSetInformation, false, pid);
|
|
@@ -303,6 +418,93 @@ static class MemGov
|
|
|
303
418
|
}
|
|
304
419
|
}
|
|
305
420
|
|
|
421
|
+
/// <summary>The throttle job, made once. A process already in the agents' job is nested in it (Windows 8+).</summary>
|
|
422
|
+
private static IntPtr ThrottleJob()
|
|
423
|
+
{
|
|
424
|
+
if (throttleJob == IntPtr.Zero)
|
|
425
|
+
{
|
|
426
|
+
string test = TestJobName();
|
|
427
|
+
throttleJob = NativeMethods.CreateJobObjectW(IntPtr.Zero, test != null ? test + "Throttle" : ThrottleJobName);
|
|
428
|
+
}
|
|
429
|
+
return throttleJob;
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
/// <summary>The CPU cap of the compilers in the throttle job, percent of the sandbox; 100 or more lifts it.</summary>
|
|
433
|
+
private static void SetCpuRate(int percent)
|
|
434
|
+
{
|
|
435
|
+
IntPtr throttle = ThrottleJob();
|
|
436
|
+
if (throttle == IntPtr.Zero)
|
|
437
|
+
{
|
|
438
|
+
return;
|
|
439
|
+
}
|
|
440
|
+
CpuRateControl info = new CpuRateControl();
|
|
441
|
+
if (percent < 100)
|
|
442
|
+
{
|
|
443
|
+
info.ControlFlags = CpuRateEnable | CpuRateHardCap;
|
|
444
|
+
info.CpuRate = (uint)(Math.Max(1, percent) * 100);
|
|
445
|
+
}
|
|
446
|
+
NativeMethods.SetInformationJobObject(throttle, JobObjectCpuRateControlInformation, ref info, Marshal.SizeOf(typeof(CpuRateControl)));
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
private static void Throttle(int pid)
|
|
450
|
+
{
|
|
451
|
+
IntPtr throttle = ThrottleJob();
|
|
452
|
+
if (throttle == IntPtr.Zero)
|
|
453
|
+
{
|
|
454
|
+
return;
|
|
455
|
+
}
|
|
456
|
+
IntPtr process = NativeMethods.OpenProcess(ProcessSetQuota | ProcessTerminate, false, pid);
|
|
457
|
+
if (process == IntPtr.Zero)
|
|
458
|
+
{
|
|
459
|
+
return;
|
|
460
|
+
}
|
|
461
|
+
try
|
|
462
|
+
{
|
|
463
|
+
NativeMethods.AssignProcessToJobObject(throttle, process);
|
|
464
|
+
}
|
|
465
|
+
finally
|
|
466
|
+
{
|
|
467
|
+
NativeMethods.CloseHandle(process);
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
/// <summary>Low memory priority: Windows trims this process's pages before others' (the agents keep theirs).</summary>
|
|
472
|
+
private static void SetMemoryPriority(int pid, uint priority)
|
|
473
|
+
{
|
|
474
|
+
IntPtr process = NativeMethods.OpenProcess(ProcessSetInformation, false, pid);
|
|
475
|
+
if (process == IntPtr.Zero)
|
|
476
|
+
{
|
|
477
|
+
return;
|
|
478
|
+
}
|
|
479
|
+
try
|
|
480
|
+
{
|
|
481
|
+
uint value = priority;
|
|
482
|
+
NativeMethods.SetProcessInformation(process, ProcessMemoryPriorityClass, ref value, sizeof(uint));
|
|
483
|
+
}
|
|
484
|
+
finally
|
|
485
|
+
{
|
|
486
|
+
NativeMethods.CloseHandle(process);
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
/// <summary>A waiting compiler's pages go to the paging file now, so the ones that run have the RAM.</summary>
|
|
491
|
+
private static void Trim(int pid)
|
|
492
|
+
{
|
|
493
|
+
IntPtr process = NativeMethods.OpenProcess(ProcessSetQuota, false, pid);
|
|
494
|
+
if (process == IntPtr.Zero)
|
|
495
|
+
{
|
|
496
|
+
return;
|
|
497
|
+
}
|
|
498
|
+
try
|
|
499
|
+
{
|
|
500
|
+
NativeMethods.SetProcessWorkingSetSize(process, new IntPtr(-1), new IntPtr(-1));
|
|
501
|
+
}
|
|
502
|
+
finally
|
|
503
|
+
{
|
|
504
|
+
NativeMethods.CloseHandle(process);
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
|
|
306
508
|
private static void Suspend(int pid, int ms)
|
|
307
509
|
{
|
|
308
510
|
lock (Gate)
|
|
@@ -432,7 +432,17 @@ sealed class ClientHub
|
|
|
432
432
|
clients.Add(client);
|
|
433
433
|
}
|
|
434
434
|
}
|
|
435
|
-
|
|
435
|
+
// Passed through, a size change makes the program redraw for everyone (a second copy of the screen in some),
|
|
436
|
+
// so a viewer that only looks leaves the size to the one in use; it takes over when it types or is resized.
|
|
437
|
+
bool owned;
|
|
438
|
+
lock (gate)
|
|
439
|
+
{
|
|
440
|
+
owned = sizeOwner != null;
|
|
441
|
+
}
|
|
442
|
+
if (!passthrough || !owned)
|
|
443
|
+
{
|
|
444
|
+
TakeOwnership(client);
|
|
445
|
+
}
|
|
436
446
|
return true;
|
|
437
447
|
}
|
|
438
448
|
|
|
@@ -781,9 +791,11 @@ sealed class ClientHub
|
|
|
781
791
|
return;
|
|
782
792
|
}
|
|
783
793
|
PseudoConsole current;
|
|
794
|
+
bool same;
|
|
784
795
|
lock (gate)
|
|
785
796
|
{
|
|
786
797
|
current = console;
|
|
798
|
+
same = cols == width && rows == height;
|
|
787
799
|
cols = width;
|
|
788
800
|
rows = height;
|
|
789
801
|
}
|
|
@@ -791,7 +803,18 @@ sealed class ClientHub
|
|
|
791
803
|
{
|
|
792
804
|
return;
|
|
793
805
|
}
|
|
794
|
-
|
|
806
|
+
if (Native.ConsoleKind.StartsWith("conpty"))
|
|
807
|
+
{
|
|
808
|
+
// Passed through: nothing repaints, the program redraws itself on every resize. Programs like Claude Code
|
|
809
|
+
// leave a second copy of their screen behind when they do, so resize only when the size really changes.
|
|
810
|
+
if (!same)
|
|
811
|
+
{
|
|
812
|
+
current.Resize(width, height);
|
|
813
|
+
}
|
|
814
|
+
return;
|
|
815
|
+
}
|
|
816
|
+
// Windows' own ConPTY repaints everything on a size change; resizing by one row first forces that even for the
|
|
817
|
+
// same size.
|
|
795
818
|
current.Resize(width, (short)(height - 1));
|
|
796
819
|
current.Resize(width, height);
|
|
797
820
|
}
|
|
@@ -1090,6 +1113,10 @@ static class Native
|
|
|
1090
1113
|
private const string AgentJobName = "Local\\AgentSandboxAgentsJob";
|
|
1091
1114
|
private const int JobObjectExtendedLimitInformation = 9;
|
|
1092
1115
|
private const uint JobObjectLimitJobMemory = 0x00000200;
|
|
1116
|
+
private const int ErrorAlreadyExists = 183;
|
|
1117
|
+
/// <summary>The backstop's headroom for "auto": this much of the commit limit, at least MinHeadroomMb.</summary>
|
|
1118
|
+
private const int HeadroomPercent = 3;
|
|
1119
|
+
private const long MinHeadroomMb = 1536;
|
|
1093
1120
|
private const long BytesPerMb = 1024L * 1024L;
|
|
1094
1121
|
private const int UseStdHandles = 0x00000100;
|
|
1095
1122
|
private static readonly IntPtr PseudoConsoleAttribute = (IntPtr)0x00020016;
|
|
@@ -1157,6 +1184,21 @@ static class Native
|
|
|
1157
1184
|
public ulong OtherTransferCount;
|
|
1158
1185
|
}
|
|
1159
1186
|
|
|
1187
|
+
// MEMORYSTATUSEX: ullTotalPageFile is the commit limit (RAM plus paging files).
|
|
1188
|
+
[StructLayout(LayoutKind.Sequential)]
|
|
1189
|
+
private struct MemoryStatus
|
|
1190
|
+
{
|
|
1191
|
+
public uint Length;
|
|
1192
|
+
public uint MemoryLoad;
|
|
1193
|
+
public ulong TotalPhys;
|
|
1194
|
+
public ulong AvailPhys;
|
|
1195
|
+
public ulong TotalPageFile;
|
|
1196
|
+
public ulong AvailPageFile;
|
|
1197
|
+
public ulong TotalVirtual;
|
|
1198
|
+
public ulong AvailVirtual;
|
|
1199
|
+
public ulong AvailExtendedVirtual;
|
|
1200
|
+
}
|
|
1201
|
+
|
|
1160
1202
|
[StructLayout(LayoutKind.Sequential)]
|
|
1161
1203
|
private struct JobExtendedLimit
|
|
1162
1204
|
{
|
|
@@ -1228,6 +1270,9 @@ static class Native
|
|
|
1228
1270
|
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
|
|
1229
1271
|
public static extern IntPtr CreateJobObjectW(IntPtr attributes, string name);
|
|
1230
1272
|
|
|
1273
|
+
[DllImport("kernel32.dll", SetLastError = true)]
|
|
1274
|
+
public static extern bool GlobalMemoryStatusEx(ref MemoryStatus status);
|
|
1275
|
+
|
|
1231
1276
|
[DllImport("kernel32.dll", SetLastError = true)]
|
|
1232
1277
|
public static extern bool SetInformationJobObject(IntPtr job, int infoClass, ref JobExtendedLimit info, int length);
|
|
1233
1278
|
|
|
@@ -1300,10 +1345,12 @@ static class Native
|
|
|
1300
1345
|
private static bool agentJobTried;
|
|
1301
1346
|
|
|
1302
1347
|
/// <summary>
|
|
1303
|
-
/// The shared job of everything the agents start
|
|
1304
|
-
///
|
|
1305
|
-
///
|
|
1306
|
-
///
|
|
1348
|
+
/// The shared job of everything the agents start (the governor reads it to slow builds down). Its only limit is a
|
|
1349
|
+
/// last-resort backstop: the sandbox's commit limit minus a small headroom (PTYHOST_BACKSTOP_MB: "auto", a number
|
|
1350
|
+
/// of MB, or "none"). The job's committed memory is part of the whole sandbox's, so it can reach the backstop only
|
|
1351
|
+
/// when Windows inside the sandbox is about to refuse memory to everyone; then a build is refused instead of
|
|
1352
|
+
/// Windows' own processes. Only the ptyhost that creates the job sets it: one that joins it never changes it.
|
|
1353
|
+
/// ptyhost itself is never in it; the handle stays open for ptyhost's whole life.
|
|
1307
1354
|
/// </summary>
|
|
1308
1355
|
private static IntPtr AgentJob(Log log)
|
|
1309
1356
|
{
|
|
@@ -1312,31 +1359,73 @@ static class Native
|
|
|
1312
1359
|
return agentJob;
|
|
1313
1360
|
}
|
|
1314
1361
|
agentJobTried = true;
|
|
1315
|
-
|
|
1316
|
-
if (
|
|
1362
|
+
string setting = Environment.GetEnvironmentVariable("PTYHOST_BACKSTOP_MB");
|
|
1363
|
+
if (string.IsNullOrEmpty(setting))
|
|
1317
1364
|
{
|
|
1318
1365
|
return IntPtr.Zero;
|
|
1319
1366
|
}
|
|
1320
|
-
|
|
1367
|
+
// The self-test uses a job of its own (a name in the same family), never the agents' real one.
|
|
1368
|
+
string name = Environment.GetEnvironmentVariable("PTYHOST_JOB_NAME");
|
|
1369
|
+
if (string.IsNullOrEmpty(name) || !name.StartsWith(AgentJobName + "Test", StringComparison.Ordinal))
|
|
1370
|
+
{
|
|
1371
|
+
name = AgentJobName;
|
|
1372
|
+
}
|
|
1373
|
+
IntPtr job = NativeMethods.CreateJobObjectW(IntPtr.Zero, name);
|
|
1374
|
+
int error = Marshal.GetLastWin32Error();
|
|
1321
1375
|
if (job == IntPtr.Zero)
|
|
1322
1376
|
{
|
|
1323
|
-
log.Write("agent job: CreateJobObject failed (" +
|
|
1377
|
+
log.Write("agent job: CreateJobObject failed (" + error + "); agents run outside it");
|
|
1324
1378
|
return IntPtr.Zero;
|
|
1325
1379
|
}
|
|
1380
|
+
agentJob = job;
|
|
1381
|
+
if (error == ErrorAlreadyExists)
|
|
1382
|
+
{
|
|
1383
|
+
log.Write("agent job: joined the existing one (its backstop stays as it was set)");
|
|
1384
|
+
return job;
|
|
1385
|
+
}
|
|
1386
|
+
if (setting == "none")
|
|
1387
|
+
{
|
|
1388
|
+
log.Write("agent job: no backstop (sandbox.agentMemoryHeadroomMb is none)");
|
|
1389
|
+
return job;
|
|
1390
|
+
}
|
|
1391
|
+
long commitMb;
|
|
1392
|
+
long limitMb = BackstopMb(setting, out commitMb);
|
|
1393
|
+
if (limitMb <= 0)
|
|
1394
|
+
{
|
|
1395
|
+
log.Write("agent job: the commit limit cannot be read; no backstop");
|
|
1396
|
+
return job;
|
|
1397
|
+
}
|
|
1326
1398
|
JobExtendedLimit info = new JobExtendedLimit();
|
|
1327
1399
|
info.BasicLimitInformation.LimitFlags = JobObjectLimitJobMemory;
|
|
1328
1400
|
info.JobMemoryLimit = new UIntPtr((ulong)(limitMb * BytesPerMb));
|
|
1329
1401
|
if (!NativeMethods.SetInformationJobObject(job, JobObjectExtendedLimitInformation, ref info, Marshal.SizeOf(typeof(JobExtendedLimit))))
|
|
1330
1402
|
{
|
|
1331
|
-
log.Write("agent job: setting the
|
|
1332
|
-
|
|
1333
|
-
return IntPtr.Zero;
|
|
1403
|
+
log.Write("agent job: setting the backstop failed (" + Marshal.GetLastWin32Error() + "); no backstop");
|
|
1404
|
+
return job;
|
|
1334
1405
|
}
|
|
1335
|
-
log.Write("agent job:
|
|
1336
|
-
agentJob = job;
|
|
1406
|
+
log.Write("agent job: last-resort backstop at " + limitMb + " MB committed (the sandbox's commit limit is " + commitMb + " MB)");
|
|
1337
1407
|
return job;
|
|
1338
1408
|
}
|
|
1339
1409
|
|
|
1410
|
+
/// <summary>The commit limit minus the headroom ("auto" or MB), at least half of it; 0 when it cannot be read.</summary>
|
|
1411
|
+
private static long BackstopMb(string setting, out long commitMb)
|
|
1412
|
+
{
|
|
1413
|
+
commitMb = 0;
|
|
1414
|
+
MemoryStatus status = new MemoryStatus();
|
|
1415
|
+
status.Length = (uint)Marshal.SizeOf(typeof(MemoryStatus));
|
|
1416
|
+
if (!NativeMethods.GlobalMemoryStatusEx(ref status))
|
|
1417
|
+
{
|
|
1418
|
+
return 0;
|
|
1419
|
+
}
|
|
1420
|
+
commitMb = (long)(status.TotalPageFile / (ulong)BytesPerMb);
|
|
1421
|
+
long headroom;
|
|
1422
|
+
if (setting == "auto" || !long.TryParse(setting, out headroom) || headroom < 0)
|
|
1423
|
+
{
|
|
1424
|
+
headroom = Math.Max(MinHeadroomMb, commitMb * HeadroomPercent / 100);
|
|
1425
|
+
}
|
|
1426
|
+
return Math.Max(commitMb / 2, commitMb - headroom);
|
|
1427
|
+
}
|
|
1428
|
+
|
|
1340
1429
|
/// <summary>Starts `commandLine` attached to the pseudo console. Null std handles: never leak our own stdio into the child.</summary>
|
|
1341
1430
|
public static IntPtr Spawn(string commandLine, IntPtr pseudoConsole, Log log)
|
|
1342
1431
|
{
|