windows-development-sandbox 1.18.4 → 1.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/config.example.json +17 -1
- package/dist/app/features/access/access.def.js +5 -2
- package/dist/app/features/access/access.run.js +7 -3
- package/dist/app/features/accounts/accounts.def.d.ts +33 -1
- package/dist/app/features/accounts/accounts.def.js +10 -4
- package/dist/app/features/accounts/accounts.run.d.ts +2 -0
- package/dist/app/features/accounts/accounts.run.js +7 -2
- package/dist/app/features/accounts/services.def.d.ts +7 -1
- package/dist/app/features/accounts/services.def.js +19 -16
- package/dist/app/features/accounts/services.run.d.ts +2 -0
- package/dist/app/features/accounts/services.run.js +44 -16
- package/dist/app/features/agent-commands/agent-commands.def.d.ts +37 -0
- package/dist/app/features/agent-commands/agent-commands.def.js +91 -0
- package/dist/app/features/agent-commands/agent-commands.run.d.ts +28 -0
- package/dist/app/features/agent-commands/agent-commands.run.js +35 -0
- package/dist/app/features/agent-commands/index.d.ts +2 -0
- package/dist/app/features/agent-commands/index.js +3 -0
- package/dist/app/features/agents/agents.def.d.ts +14 -1
- package/dist/app/features/agents/agents.def.js +61 -6
- package/dist/app/features/agents/agents.run.d.ts +1 -0
- package/dist/app/features/agents/agents.run.js +8 -1
- package/dist/app/features/agents/claude-env.def.d.ts +36 -0
- package/dist/app/features/agents/claude-env.def.js +305 -0
- package/dist/app/features/agents/env.def.d.ts +163 -0
- package/dist/app/features/agents/env.def.js +184 -0
- package/dist/app/features/agents/env.run.d.ts +43 -0
- package/dist/app/features/agents/env.run.js +86 -0
- package/dist/app/features/agents/index.d.ts +2 -0
- package/dist/app/features/agents/index.js +2 -0
- package/dist/app/features/defs.d.ts +171 -3
- package/dist/app/features/defs.js +9 -0
- package/dist/app/features/engine/engine.run.js +1 -1
- package/dist/app/features/github/github.def.d.ts +44 -3
- package/dist/app/features/github/github.def.js +145 -63
- package/dist/app/features/github/github.run.d.ts +9 -2
- package/dist/app/features/github/github.run.js +43 -5
- package/dist/app/features/health/health.def.js +8 -2
- package/dist/app/features/logs/logs.def.js +0 -8
- package/dist/app/features/projects/projects.def.js +2 -2
- package/dist/app/features/projects/projects.run.js +5 -5
- package/dist/app/features/sandbox/sandbox.def.js +7 -3
- package/dist/app/features/sessions/sessions.def.d.ts +4 -4
- package/dist/app/features/sessions/sessions.def.js +0 -5
- package/dist/app/features/sessions/sessions.run.d.ts +1 -1
- package/dist/app/features/sessions/sessions.run.js +2 -2
- package/dist/app/features/settings/categories.def.js +7 -2
- package/dist/app/features/settings/settings-rows.js +6 -2
- package/dist/app/features/settings/settings.def.js +1 -1
- package/dist/app/features/settings/settings.run.d.ts +8 -0
- package/dist/app/features/settings/settings.run.js +12 -3
- package/dist/app/features/storage/storage.run.js +18 -9
- package/dist/app/features/updates/update-lines.js +2 -2
- package/dist/app/features/updates/updates.def.js +1 -1
- package/dist/app/features/updates/updates.run.js +13 -3
- package/dist/app/features/vpn/vpn.def.d.ts +33 -0
- package/dist/app/features/vpn/vpn.def.js +30 -6
- package/dist/app/features/vpn/vpn.run.d.ts +11 -0
- package/dist/app/features/vpn/vpn.run.js +4 -1
- package/dist/app/features/web/web.def.js +2 -2
- package/dist/app/features/web/web.run.js +12 -4
- package/dist/app/kernel/errors.d.ts +7 -0
- package/dist/app/kernel/errors.js +18 -3
- package/dist/app/kernel/rpc.d.ts +6 -1
- package/dist/app/kernel/view.d.ts +11 -1
- package/dist/app/registry.js +7 -1
- package/dist/bin/agent-sandbox.js +2 -2
- package/dist/bin/{chunk-N4GXYTLV.js → chunk-JETGP2C3.js} +239 -72
- package/dist/bin/{chunk-MY7NLQQY.js → chunk-XZKOPGNH.js} +1 -1
- package/dist/bin/{chunk-FRPLQLSY.js → chunk-ZTTOF5V3.js} +6566 -4964
- package/dist/bin/claude-host.js +2 -2
- package/dist/bin/claude-sbx.js +2 -2
- package/dist/bin/codex-sbx.js +2 -2
- package/dist/bin/gemini-sbx.js +2 -2
- package/dist/bin/sandbox.js +2 -2
- package/dist/bin/sbx-hide.js +2 -2
- package/dist/bin/sbx-show.js +2 -2
- package/dist/cli/commands/agent-commands.d.ts +0 -1
- package/dist/cli/commands/agent-commands.js +2 -32
- package/dist/cli/commands/index.d.ts +1 -1
- package/dist/cli/commands/index.js +1 -1
- package/dist/cli/commands/launch/launch.js +2 -2
- package/dist/cli/commands/registry.js +3 -2
- package/dist/cli/manifest.d.ts +3 -3
- package/dist/cli/manifest.js +3 -2
- package/dist/cli/menu/coverage-exempt.d.ts +17 -0
- package/dist/cli/menu/coverage-exempt.js +61 -0
- package/dist/cli/menu/io-menu.d.ts +2 -0
- package/dist/cli/menu/io-menu.js +50 -5
- package/dist/cli/menu/menu.d.ts +1 -1
- package/dist/cli/menu/menu.js +3 -3
- package/dist/cli/menu/pages/accounts-page.js +1 -1
- package/dist/cli/menu/pages/agents-page.d.ts +7 -2
- package/dist/cli/menu/pages/agents-page.js +75 -13
- package/dist/cli/menu/pages/maintenance-page.d.ts +6 -0
- package/dist/cli/menu/pages/maintenance-page.js +10 -4
- package/dist/cli/menu/pages/sessions-page.d.ts +2 -0
- package/dist/cli/menu/pages/sessions-page.js +12 -4
- package/dist/cli/menu/pages/settings-page.js +13 -1
- package/dist/cli/menu/remote-menu.js +1 -1
- package/dist/cli/menu/shell.d.ts +5 -0
- package/dist/cli/menu/shell.js +13 -0
- package/dist/cli/menu/views.js +2 -1
- package/dist/cli/report.js +2 -0
- package/dist/cli/services/agent-commands-service.d.ts +2 -0
- package/dist/cli/services/agent-commands-service.js +13 -7
- package/dist/cli/services/vpn-service.d.ts +5 -1
- package/dist/cli/services/vpn-service.js +6 -1
- package/dist/cli/tui/app.d.ts +5 -0
- package/dist/cli/tui/app.js +2 -0
- package/dist/cli/tui/dialogs/text-screen.js +2 -1
- package/dist/cli/tui/terminal.js +3 -1
- package/dist/core/config/defaults.js +12 -1
- package/dist/core/detect/toolchains.js +9 -0
- package/dist/core/disk.d.ts +1 -5
- package/dist/core/disk.js +1 -16
- package/dist/core/schema/accounts.d.ts +6 -0
- package/dist/core/schema/accounts.js +13 -11
- package/dist/core/schema/codex.d.ts +29 -0
- package/dist/core/schema/codex.js +24 -0
- package/dist/core/schema/config.d.ts +58 -14
- package/dist/core/schema/config.js +6 -4
- package/dist/core/schema/github.js +1 -1
- package/dist/core/schema/index.d.ts +1 -0
- package/dist/core/schema/index.js +1 -0
- package/dist/core/schema/profile.js +8 -4
- package/dist/core/schema/resume.js +1 -1
- package/dist/core/schema/sandbox.js +3 -3
- package/dist/core/schema/toolchains.d.ts +4 -0
- package/dist/core/schema/toolchains.js +3 -0
- package/dist/core/schema/vpn.js +1 -1
- package/dist/core/schema/web.js +3 -3
- package/dist/core/types.d.ts +8 -0
- package/dist/core/util/errors.d.ts +11 -1
- package/dist/core/util/errors.js +7 -1
- package/dist/core/util/index.d.ts +1 -1
- package/dist/core/util/index.js +1 -1
- package/dist/guest/accounts/adapter.d.ts +2 -0
- package/dist/guest/accounts/adapters.js +4 -0
- package/dist/guest/accounts/apply.d.ts +10 -6
- package/dist/guest/accounts/kinds/cfx.d.ts +7 -0
- package/dist/guest/accounts/kinds/cfx.js +33 -3
- package/dist/guest/accounts/kinds/comet.d.ts +7 -0
- package/dist/guest/accounts/kinds/comet.js +50 -0
- package/dist/guest/accounts/kinds/perplexity.d.ts +2 -0
- package/dist/guest/accounts/kinds/perplexity.js +12 -0
- package/dist/guest/accounts/watch.d.ts +2 -0
- package/dist/guest/accounts/watch.js +12 -2
- package/dist/guest/agents/agent-files.d.ts +26 -6
- package/dist/guest/agents/agent-files.js +84 -14
- package/dist/guest/agents/agent-installer.js +1 -1
- package/dist/guest/agents/local-state.d.ts +5 -2
- package/dist/guest/agents/local-state.js +24 -10
- package/dist/guest/agents/profile-links.d.ts +2 -0
- package/dist/guest/agents/profile-links.js +18 -4
- package/dist/guest/apps/after-install.js +19 -0
- package/dist/guest/apps/app-installer.d.ts +11 -0
- package/dist/guest/apps/app-installer.js +69 -6
- package/dist/guest/apps/comet-unpack.d.ts +20 -0
- package/dist/guest/apps/comet-unpack.js +127 -0
- package/dist/guest/apps/index.d.ts +1 -1
- package/dist/guest/apps/index.js +1 -1
- package/dist/guest/apps/resolvers-agents-web.d.ts +2 -0
- package/dist/guest/apps/resolvers-agents-web.js +7 -0
- package/dist/guest/apps/resolvers.js +2 -0
- package/dist/guest/apps/shortcuts.d.ts +2 -0
- package/dist/guest/apps/shortcuts.js +1 -0
- package/dist/guest/apps/unpack.js +14 -4
- package/dist/guest/boot/boot.d.ts +45 -16
- package/dist/guest/boot/boot.js +325 -149
- package/dist/guest/boot/graph.d.ts +252 -0
- package/dist/guest/boot/graph.js +257 -0
- package/dist/guest/boot/guide-lines.d.ts +25 -0
- package/dist/guest/boot/guide-lines.js +41 -0
- package/dist/guest/boot/guide.d.ts +1 -4
- package/dist/guest/boot/guide.js +6 -8
- package/dist/guest/boot/runner.d.ts +77 -0
- package/dist/guest/boot/runner.js +215 -0
- package/dist/guest/browser/cdp.d.ts +71 -0
- package/dist/guest/browser/cdp.js +306 -0
- package/dist/guest/browser/comet.d.ts +28 -0
- package/dist/guest/browser/comet.js +155 -0
- package/dist/guest/daemon/project-provisioner.js +6 -1
- package/dist/guest/daemon/sessions.js +2 -1
- package/dist/guest/devtools/fivem.d.ts +1 -1
- package/dist/guest/devtools/fivem.js +243 -3
- package/dist/guest/entries/daemon.js +2 -0
- package/dist/guest/runtime/log.d.ts +12 -0
- package/dist/guest/runtime/log.js +29 -5
- package/dist/guest/runtime/pools.d.ts +24 -0
- package/dist/guest/runtime/pools.js +60 -0
- package/dist/guest/runtime/process.d.ts +4 -0
- package/dist/guest/runtime/process.js +38 -1
- package/dist/guest/runtime/status.d.ts +5 -1
- package/dist/guest/runtime/status.js +19 -0
- package/dist/guest/setup/addon-mcp.d.ts +1 -1
- package/dist/guest/setup/addon-mcp.js +52 -12
- package/dist/guest/setup/agent-addons.d.ts +3 -2
- package/dist/guest/setup/agent-addons.js +12 -3
- package/dist/guest/setup/environment.d.ts +1 -1
- package/dist/guest/setup/environment.js +25 -12
- package/dist/guest/setup/headroom.d.ts +8 -3
- package/dist/guest/setup/headroom.js +44 -15
- package/dist/guest/setup/path-plan.d.ts +28 -0
- package/dist/guest/setup/path-plan.js +69 -2
- package/dist/guest/setup/shell-path.d.ts +1 -1
- package/dist/guest/setup/shell-path.js +3 -3
- package/dist/guest/toolchains/fivem/artifacts.d.ts +48 -1
- package/dist/guest/toolchains/fivem/artifacts.js +97 -4
- package/dist/guest/toolchains/fivem/fivem.d.ts +32 -1
- package/dist/guest/toolchains/fivem/fivem.js +168 -3
- package/dist/guest/toolchains/fivem/scaffold.d.ts +35 -0
- package/dist/guest/toolchains/fivem/scaffold.js +105 -0
- package/dist/guest/toolchains/fivem/serve-plan.d.ts +34 -0
- package/dist/guest/toolchains/fivem/serve-plan.js +61 -0
- package/dist/guest/toolchains/installers.d.ts +6 -10
- package/dist/guest/toolchains/installers.js +4 -12
- package/dist/guest/toolchains/languages/go.js +1 -1
- package/dist/guest/toolchains/languages/node.js +2 -1
- package/dist/guest/toolchains/languages/php.d.ts +2 -0
- package/dist/guest/toolchains/languages/php.js +13 -1
- package/dist/guest/toolchains/languages/python-tools.js +1 -1
- package/dist/guest/toolchains/languages/ruby.js +1 -1
- package/dist/guest/toolchains/native/autosdk.d.ts +3 -0
- package/dist/guest/toolchains/native/autosdk.js +50 -0
- package/dist/guest/toolchains/native/binstall.js +1 -1
- package/dist/guest/toolchains/native/msvc/packages.js +10 -4
- package/dist/guest/toolchains/native/rust.d.ts +2 -0
- package/dist/guest/toolchains/native/rust.js +11 -4
- package/dist/guest/toolchains/native/unreal.d.ts +2 -0
- package/dist/guest/toolchains/native/unreal.js +19 -6
- package/dist/guest/toolchains/native/vcruntime.d.ts +2 -3
- package/dist/guest/toolchains/native/vcruntime.js +12 -7
- package/dist/guest/toolchains/native/visual-studio.d.ts +5 -2
- package/dist/guest/toolchains/native/visual-studio.js +127 -25
- package/dist/guest/toolchains/native/vs-request.d.ts +23 -0
- package/dist/guest/toolchains/native/vs-request.js +62 -1
- package/dist/guest/toolchains/not-yet.d.ts +1 -1
- package/dist/guest/toolchains/not-yet.js +3 -3
- package/dist/guest/toolchains/persisted.js +2 -7
- package/dist/guest/toolchains/plan.js +27 -11
- package/dist/guest/toolchains/scheduler.d.ts +2 -21
- package/dist/guest/toolchains/scheduler.js +7 -121
- package/dist/guest/toolchains/setup.d.ts +15 -2
- package/dist/guest/toolchains/setup.js +39 -20
- package/dist/guest/toolchains/signature.d.ts +5 -0
- package/dist/guest/toolchains/signature.js +22 -0
- package/dist/guest/toolchains/split.d.ts +28 -0
- package/dist/guest/toolchains/split.js +60 -0
- package/dist/guest/toolchains/steam/client.js +2 -1
- package/dist/guest/toolchains/step-scheduler.d.ts +51 -0
- package/dist/guest/toolchains/step-scheduler.js +147 -0
- package/dist/guest/toolchains/step.d.ts +13 -0
- package/dist/guest/toolchains/tools/git.js +18 -0
- package/dist/guest/vpn/openvpn.js +3 -4
- package/dist/guest/vpn/tunnel.d.ts +3 -0
- package/dist/guest/vpn/tunnel.js +10 -12
- package/dist/guest/vpn/vpn.js +6 -1
- package/dist/guest/vpn/wireguard.js +11 -4
- package/dist/host/accounts/deliver.js +7 -0
- package/dist/host/accounts/handoff.js +2 -6
- package/dist/host/accounts/index.d.ts +1 -1
- package/dist/host/accounts/index.js +1 -1
- package/dist/host/accounts/kinds/cfx.d.ts +1 -1
- package/dist/host/accounts/kinds/cfx.js +47 -4
- package/dist/host/accounts/kinds/comet.d.ts +2 -0
- package/dist/host/accounts/kinds/comet.js +6 -0
- package/dist/host/accounts/kinds/perplexity.d.ts +2 -0
- package/dist/host/accounts/kinds/perplexity.js +30 -0
- package/dist/host/accounts/leases.d.ts +9 -3
- package/dist/host/accounts/leases.js +13 -2
- package/dist/host/accounts/source.d.ts +7 -1
- package/dist/host/accounts/source.js +28 -1
- package/dist/host/accounts/sources.js +4 -0
- package/dist/host/agent-commands/commands.js +1 -1
- package/dist/host/agent-commands/forwarders.d.ts +14 -2
- package/dist/host/agent-commands/forwarders.js +31 -13
- package/dist/host/agent-commands/reconcile.d.ts +2 -1
- package/dist/host/agent-commands/reconcile.js +7 -8
- package/dist/host/agent-commands/user-path.d.ts +5 -0
- package/dist/host/agent-commands/user-path.js +13 -0
- package/dist/host/github/deliver.d.ts +1 -1
- package/dist/host/github/deliver.js +20 -1
- package/dist/host/github/index.d.ts +2 -1
- package/dist/host/github/index.js +1 -0
- package/dist/host/github/token.d.ts +13 -1
- package/dist/host/github/token.js +19 -2
- package/dist/host/github/verify.d.ts +27 -0
- package/dist/host/github/verify.js +61 -0
- package/dist/host/launch/hints/fivem.d.ts +3 -1
- package/dist/host/launch/hints/fivem.js +68 -2
- package/dist/host/launch/session-file.js +5 -0
- package/dist/host/launch/toolchains.d.ts +2 -1
- package/dist/host/launch/toolchains.js +5 -3
- package/dist/host/profile/accounts.js +2 -4
- package/dist/host/profile/claude-login.d.ts +3 -2
- package/dist/host/profile/claude-login.js +3 -13
- package/dist/host/vpn/index.d.ts +2 -1
- package/dist/host/vpn/index.js +2 -1
- package/dist/host/vpn/last.d.ts +28 -0
- package/dist/host/vpn/last.js +43 -0
- package/dist/host/vpn/login.d.ts +3 -1
- package/dist/host/vpn/login.js +17 -3
- package/dist/host/vpn/nordvpn.d.ts +2 -4
- package/dist/host/vpn/nordvpn.js +2 -24
- package/dist/runtime/agent.js +433 -90
- package/dist/runtime/daemon.js +3378 -1546
- package/dist/runtime/db.js +363 -90
- package/dist/runtime/main.js +5134 -2096
- package/dist/runtime/netproxy.js +308 -69
- package/dist/runtime/tool.js +2867 -1765
- package/dist/runtime/view.js +308 -69
- package/dist/selftest/agent-commands.test.js +45 -7
- package/dist/selftest/agent-paths.test.js +40 -13
- package/dist/selftest/agent-settings.test.d.ts +2 -0
- package/dist/selftest/agent-settings.test.js +94 -0
- package/dist/selftest/agents-web.test.d.ts +2 -0
- package/dist/selftest/agents-web.test.js +647 -0
- package/dist/selftest/app.test.js +7 -3
- package/dist/selftest/boot-runner.test.d.ts +2 -0
- package/dist/selftest/boot-runner.test.js +456 -0
- package/dist/selftest/channel.test.js +15 -0
- package/dist/selftest/cli.test.js +4 -0
- package/dist/selftest/fivem.test.js +249 -3
- package/dist/selftest/github.test.js +94 -9
- package/dist/selftest/guest-boot.test.js +3 -0
- package/dist/selftest/health.test.js +1 -1
- package/dist/selftest/index.js +10 -0
- package/dist/selftest/layout.test.js +5 -0
- package/dist/selftest/menu-coverage.test.d.ts +2 -0
- package/dist/selftest/menu-coverage.test.js +46 -0
- package/dist/selftest/menu-screens.js +37 -1
- package/dist/selftest/menu.test.js +5 -3
- package/dist/selftest/pc-installs.test.js +5 -0
- package/dist/selftest/persisted-installs.test.js +72 -0
- package/dist/selftest/service-accounts.test.js +3 -2
- package/dist/selftest/support/engine-golden.js +28 -1
- package/dist/selftest/support/fixtures.d.ts +15 -0
- package/dist/selftest/support/web-preview.d.ts +34 -1
- package/dist/selftest/support/web-preview.js +21 -18
- package/dist/selftest/toolchains.test.js +23 -1
- package/dist/selftest/ui-text.test.d.ts +7 -0
- package/dist/selftest/ui-text.test.js +300 -0
- package/dist/selftest/vpn.test.js +51 -3
- package/dist/shared/accounts/anthropic.d.ts +5 -0
- package/dist/shared/accounts/anthropic.js +15 -0
- package/dist/shared/accounts/index.d.ts +3 -0
- package/dist/shared/accounts/index.js +3 -0
- package/dist/shared/accounts/kinds/comet.d.ts +12 -0
- package/dist/shared/accounts/kinds/comet.js +64 -0
- package/dist/shared/accounts/kinds/perplexity.d.ts +8 -0
- package/dist/shared/accounts/kinds/perplexity.js +37 -0
- package/dist/shared/accounts/kinds.d.ts +24 -5
- package/dist/shared/accounts/kinds.js +86 -4
- package/dist/shared/accounts/payloads.d.ts +81 -0
- package/dist/shared/accounts/payloads.js +39 -1
- package/dist/shared/apps/agent-addons.d.ts +33 -5
- package/dist/shared/apps/agent-addons.js +95 -3
- package/dist/shared/apps/catalogue-agents-web.d.ts +14 -0
- package/dist/shared/apps/catalogue-agents-web.js +112 -0
- package/dist/shared/apps/catalogue-modding.js +32 -1
- package/dist/shared/apps/catalogue.d.ts +27 -3
- package/dist/shared/apps/catalogue.js +2 -1
- package/dist/shared/apps/index.d.ts +3 -1
- package/dist/shared/apps/index.js +3 -1
- package/dist/shared/channel/schema.d.ts +40 -3
- package/dist/shared/channel/schema.js +9 -0
- package/dist/shared/channel/secrets.d.ts +19 -0
- package/dist/shared/concurrency/index.d.ts +3 -0
- package/dist/shared/concurrency/index.js +3 -0
- package/dist/shared/concurrency/installer-retry.d.ts +6 -0
- package/dist/shared/concurrency/installer-retry.js +10 -0
- package/dist/shared/concurrency/limiter.d.ts +19 -0
- package/dist/shared/concurrency/limiter.js +67 -0
- package/dist/shared/concurrency/pools.d.ts +7 -0
- package/dist/shared/concurrency/pools.js +9 -0
- package/dist/shared/download/archive.d.ts +2 -0
- package/dist/shared/download/archive.js +11 -1
- package/dist/shared/download/bounded-fetch.d.ts +13 -0
- package/dist/shared/download/bounded-fetch.js +40 -0
- package/dist/shared/download/downloader.d.ts +5 -0
- package/dist/shared/download/downloader.js +50 -38
- package/dist/shared/download/index.d.ts +2 -1
- package/dist/shared/download/index.js +2 -1
- package/dist/shared/io/disk.d.ts +9 -0
- package/dist/shared/io/disk.js +19 -0
- package/dist/shared/io/index.d.ts +1 -0
- package/dist/shared/io/index.js +1 -0
- package/dist/shared/readiness.d.ts +9 -0
- package/dist/shared/readiness.js +11 -0
- package/dist/shared/signer.d.ts +24 -0
- package/dist/shared/signer.js +15 -0
- package/dist/shared/vpn/failure.d.ts +10 -0
- package/dist/shared/vpn/failure.js +28 -0
- package/dist/sync/watcher.js +2 -0
- package/dist/web/index.html +1 -1
- package/dist/web/{main-GVZWWP4I.js → main-CCILLX2M.js} +75 -74
- package/native/csharp/HcsHost/AssemblyInfo.cs +3 -3
- package/native/csharp/HostTools/AssemblyInfo.cs +3 -3
- package/native/csharp/HostTools/Program.cs +14 -1
- package/native/csharp/HostTools/UserPath.cs +17 -0
- package/native/csharp/StorageHelper/AssemblyInfo.cs +3 -3
- package/native/scripts/edit-user-path.ps1 +6 -2
- package/package.json +1 -1
- package/sandbox/addons/browser-use-mcp/requirements.in +1 -0
- package/sandbox/addons/browser-use-mcp/requirements.txt +2350 -0
- package/sandbox/addons/chrome-devtools-mcp/package-lock.json +38 -0
- package/sandbox/addons/chrome-devtools-mcp/package.json +7 -0
- package/sandbox/addons/comet-mcp/package-lock.json +1277 -0
- package/sandbox/addons/comet-mcp/package.json +7 -0
- package/sandbox/addons/perplexity-mcp/package-lock.json +1655 -0
- package/sandbox/addons/perplexity-mcp/package.json +7 -0
- package/sandbox/scripts/add-firewall-port.ps1 +18 -4
- package/sandbox/scripts/get-signature.ps1 +13 -0
- package/sandbox/scripts/set-machine-environment.ps1 +30 -15
- package/sandbox/templates/fivem/README.txt +6 -2
- package/sandbox/templates/fivem/cs/Client/Client.csproj +15 -0
- package/sandbox/templates/fivem/cs/Client/ClientMain.cs +20 -0
- package/sandbox/templates/fivem/cs/Server/Server.csproj +14 -0
- package/sandbox/templates/fivem/cs/Server/ServerMain.cs +20 -0
- package/sandbox/templates/fivem/cs/fxmanifest.lua +11 -0
- package/sandbox/templates/fivem/js/client.js +12 -0
- package/sandbox/templates/fivem/js/fxmanifest.lua +9 -0
- package/sandbox/templates/fivem/js/server.js +6 -0
- package/sandbox/templates/fivem/lua/client.lua +8 -0
- package/sandbox/templates/fivem/lua/fxmanifest.lua +10 -0
- package/sandbox/templates/fivem/lua/server.lua +6 -0
- package/sandbox/templates/fivem/server.cfg +37 -0
- package/sandbox/templates/fivem/ts/build.js +17 -0
- package/sandbox/templates/fivem/ts/fxmanifest.lua +9 -0
- package/sandbox/templates/fivem/ts/package.json +16 -0
- package/sandbox/templates/fivem/ts/src/client/client.ts +12 -0
- package/sandbox/templates/fivem/ts/src/client/tsconfig.json +13 -0
- package/sandbox/templates/fivem/ts/src/server/server.ts +6 -0
- package/sandbox/templates/fivem/ts/src/server/tsconfig.json +13 -0
- package/schemas/config.schema.json +120 -27
- package/schemas/sandbox-config.schema.json +45 -14
- package/sandbox/scripts/get-signer.ps1 +0 -8
|
@@ -1,5 +1,30 @@
|
|
|
1
|
+
// How a sign-in reaches the store on this PC: taken from this PC's own program (fromPc), read from a file you name
|
|
2
|
+
// (fromFile, `sandbox account import <kind> --from <file>`), or typed (fromAnswers, `sandbox account login <kind>`).
|
|
3
|
+
// One module per kind under kinds/; sources.ts lists them.
|
|
4
|
+
import { spawnSync } from 'node:child_process';
|
|
1
5
|
import { fail } from '../../core/util/index.js';
|
|
6
|
+
import { SYSTEM } from '../../shared/system.js';
|
|
7
|
+
import { refuseInSelfTest } from '../test-guard.js';
|
|
2
8
|
import { SERVICE_SPECS } from '../../shared/accounts/index.js';
|
|
9
|
+
/** The value of `name` in `reg query <key> /v <name>` output, or null. */
|
|
10
|
+
export function parseRegValue(text, name) {
|
|
11
|
+
const escaped = name.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
12
|
+
const m = new RegExp('^\\s+' + escaped + '\\s+REG_(?:EXPAND_)?SZ\\s+(.*)$', 'im').exec(text);
|
|
13
|
+
return m ? m[1].trim() : null;
|
|
14
|
+
}
|
|
15
|
+
/** A variable of this Windows user's saved environment, read with reg.exe (by its full path); null when unset. */
|
|
16
|
+
function savedUserVariable(name) {
|
|
17
|
+
if (!/^[A-Za-z_][A-Za-z0-9_]{0,100}$/.test(name))
|
|
18
|
+
return null;
|
|
19
|
+
refuseInSelfTest("read this PC's saved environment");
|
|
20
|
+
const r = spawnSync(SYSTEM.reg(), ['query', 'HKCU\\Environment', '/v', name], {
|
|
21
|
+
encoding: 'utf8',
|
|
22
|
+
windowsHide: true,
|
|
23
|
+
timeout: 15000,
|
|
24
|
+
maxBuffer: 64 * 1024,
|
|
25
|
+
});
|
|
26
|
+
return r.status === 0 ? parseRegValue(String(r.stdout ?? ''), name) : null;
|
|
27
|
+
}
|
|
3
28
|
/** This PC's folders from the environment (never HOME or USERPROFILE). */
|
|
4
29
|
export function pcEnv() {
|
|
5
30
|
const env = process.env;
|
|
@@ -7,9 +32,11 @@ export function pcEnv() {
|
|
|
7
32
|
localAppData: env.LOCALAPPDATA ?? '',
|
|
8
33
|
appData: env.APPDATA ?? '',
|
|
9
34
|
programData: env.ProgramData ?? env.PROGRAMDATA ?? 'C:\\ProgramData',
|
|
35
|
+
env,
|
|
36
|
+
userVariable: savedUserVariable,
|
|
10
37
|
};
|
|
11
38
|
}
|
|
12
39
|
/** What a kind whose host side is not written yet says. */
|
|
13
40
|
export function notAvailableYet(kind) {
|
|
14
|
-
return fail('Saving a ' + SERVICE_SPECS[kind].label + ' sign-in
|
|
41
|
+
return fail('Saving a ' + SERVICE_SPECS[kind].label + ' sign-in comes in a later version of the sandbox.', 'Nothing was changed.');
|
|
15
42
|
}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { appstoreSource } from './kinds/appstore.js';
|
|
2
2
|
import { cfxSource } from './kinds/cfx.js';
|
|
3
|
+
import { cometSource } from './kinds/comet.js';
|
|
3
4
|
import { epicSource } from './kinds/epic.js';
|
|
4
5
|
import { expoSource } from './kinds/expo.js';
|
|
5
6
|
import { keystoreSource } from './kinds/keystore.js';
|
|
7
|
+
import { perplexitySource } from './kinds/perplexity.js';
|
|
6
8
|
import { playSource } from './kinds/play.js';
|
|
7
9
|
import { steamSource } from './kinds/steam.js';
|
|
8
10
|
import { unitySource } from './kinds/unity.js';
|
|
@@ -15,4 +17,6 @@ export const HOST_SOURCES = {
|
|
|
15
17
|
play: playSource,
|
|
16
18
|
expo: expoSource,
|
|
17
19
|
appstore: appstoreSource,
|
|
20
|
+
perplexity: perplexitySource,
|
|
21
|
+
comet: cometSource,
|
|
18
22
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
//
|
|
1
|
+
// Agent commands: with agentCommands.enabled, typing an agent's own command on this PC (claude, codex, ...)
|
|
2
2
|
// starts it in a hidden sandbox for the folder you are in and attaches that terminal. Small forwarding files in
|
|
3
3
|
// <storage>\agent-commands go first on YOUR PATH (so they win over npm's and the installers' copies); turning it off
|
|
4
4
|
// removes the files and that one PATH entry. SANDBOX_AGENT_DIRECT=1 runs the real agent on this PC instead.
|
|
@@ -1,7 +1,19 @@
|
|
|
1
1
|
import type { AgentCommand } from './commands.js';
|
|
2
2
|
/** Marks files this tool wrote, so only those are ever replaced or removed. */
|
|
3
3
|
export declare const MARKER = "windows-development-sandbox agent command";
|
|
4
|
+
/** What a forwarding file runs: the managed install's launcher when there is one, else node + the entry file. */
|
|
5
|
+
export interface ForwardTarget {
|
|
6
|
+
readonly node: string;
|
|
7
|
+
readonly entry: string;
|
|
8
|
+
/** The managed install's `bin\sandbox.cmd`: it survives updates, which remove the version folder `entry` is in. */
|
|
9
|
+
readonly launcher?: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Where the forwarding files send the typed command. Under a managed install (installRoot, the folder with `bin`,
|
|
13
|
+
* `versions` and `node`) that is its launcher; otherwise the entry file of this copy.
|
|
14
|
+
*/
|
|
15
|
+
export declare function forwardTarget(packageRoot: string, installRoot: string | null, node: string): ForwardTarget;
|
|
4
16
|
/** The .cmd file for one agent (cmd, PowerShell and Windows Terminal all run it). */
|
|
5
|
-
export declare function forwardingCmd(a: AgentCommand,
|
|
17
|
+
export declare function forwardingCmd(a: AgentCommand, target: ForwardTarget): string;
|
|
6
18
|
/** The same for Git Bash, which looks for a file without an extension. */
|
|
7
|
-
export declare function forwardingSh(a: AgentCommand,
|
|
19
|
+
export declare function forwardingSh(a: AgentCommand, target: ForwardTarget): string;
|
|
@@ -1,12 +1,30 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
1
2
|
/** Marks files this tool wrote, so only those are ever replaced or removed. */
|
|
2
3
|
export const MARKER = 'windows-development-sandbox agent command';
|
|
4
|
+
/**
|
|
5
|
+
* Where the forwarding files send the typed command. Under a managed install (installRoot, the folder with `bin`,
|
|
6
|
+
* `versions` and `node`) that is its launcher; otherwise the entry file of this copy.
|
|
7
|
+
*/
|
|
8
|
+
export function forwardTarget(packageRoot, installRoot, node) {
|
|
9
|
+
const entry = path.join(packageRoot, 'dist', 'bin', 'sandbox.js');
|
|
10
|
+
return installRoot ? { node, entry, launcher: path.join(installRoot, 'bin', 'sandbox.cmd') } : { node, entry };
|
|
11
|
+
}
|
|
12
|
+
const posix = (p) => p.replace(/^([A-Za-z]):/, (_m, d) => '/' + d.toLowerCase()).replace(/\\/g, '/');
|
|
3
13
|
/** The .cmd file for one agent (cmd, PowerShell and Windows Terminal all run it). */
|
|
4
|
-
export function forwardingCmd(a,
|
|
14
|
+
export function forwardingCmd(a, target) {
|
|
15
|
+
const launch = ' launch --harness ' + a.harness + ' --headless --terminal -- %*';
|
|
5
16
|
return [
|
|
6
17
|
'@echo off',
|
|
7
|
-
'rem ' + MARKER + '
|
|
18
|
+
'rem ' + MARKER + '. Turn off: sandbox agent-commands off. Run the real one: set SANDBOX_AGENT_DIRECT=1',
|
|
8
19
|
'if "%SANDBOX_AGENT_DIRECT%"=="1" goto direct',
|
|
9
|
-
|
|
20
|
+
// A missing program (the tool was uninstalled or moved) runs the real agent instead of failing.
|
|
21
|
+
...(target.launcher
|
|
22
|
+
? ['if not exist "' + target.launcher + '" goto direct', 'call "' + target.launcher + '"' + launch]
|
|
23
|
+
: [
|
|
24
|
+
'if not exist "' + target.node + '" goto direct',
|
|
25
|
+
'if not exist "' + target.entry + '" goto direct',
|
|
26
|
+
'"' + target.node + '" "' + target.entry + '"' + launch,
|
|
27
|
+
]),
|
|
10
28
|
'exit /b %errorlevel%',
|
|
11
29
|
':direct',
|
|
12
30
|
'call "' + a.real + '" %*',
|
|
@@ -14,20 +32,20 @@ export function forwardingCmd(a, node, entry) {
|
|
|
14
32
|
].join('\r\n');
|
|
15
33
|
}
|
|
16
34
|
/** The same for Git Bash, which looks for a file without an extension. */
|
|
17
|
-
export function forwardingSh(a,
|
|
18
|
-
const posix = (p) => p.replace(/^([A-Za-z]):/, (_m, d) => '/' + d.toLowerCase()).replace(/\\/g, '/');
|
|
35
|
+
export function forwardingSh(a, target) {
|
|
19
36
|
const q = (s) => "'" + s.replace(/'/g, "'\\''") + "'";
|
|
37
|
+
const launch = ' launch --harness ' + a.harness + ' --headless --terminal -- "$@"';
|
|
38
|
+
const shLauncher = target.launcher ? posix(target.launcher).replace(/\.cmd$/i, '') : null;
|
|
20
39
|
return [
|
|
21
40
|
'#!/bin/sh',
|
|
22
|
-
'# ' + MARKER + '
|
|
41
|
+
'# ' + MARKER + '. Turn off: sandbox agent-commands off. Run the real one: SANDBOX_AGENT_DIRECT=1',
|
|
23
42
|
'if [ "$SANDBOX_AGENT_DIRECT" = "1" ]; then exec ' + q(posix(a.real)) + ' "$@"; fi',
|
|
24
|
-
|
|
25
|
-
q(posix(
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
' --headless --terminal -- "$@"',
|
|
43
|
+
...(shLauncher
|
|
44
|
+
? ['[ -f ' + q(shLauncher) + ' ] || exec ' + q(posix(a.real)) + ' "$@"', 'exec ' + q(shLauncher) + launch]
|
|
45
|
+
: [
|
|
46
|
+
'[ -f ' + q(posix(target.entry)) + ' ] || exec ' + q(posix(a.real)) + ' "$@"',
|
|
47
|
+
'exec ' + q(posix(target.node)) + ' ' + q(posix(target.entry)) + launch,
|
|
48
|
+
]),
|
|
31
49
|
'',
|
|
32
50
|
].join('\n');
|
|
33
51
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Config } from '../../core/types.js';
|
|
2
|
+
import { type ForwardTarget } from './forwarders.js';
|
|
2
3
|
import { type AgentCommand } from './commands.js';
|
|
3
4
|
export interface Reconciled {
|
|
4
5
|
on: boolean;
|
|
@@ -9,4 +10,4 @@ export interface Reconciled {
|
|
|
9
10
|
* Makes this PC match agentCommands: on = a forwarding file per installed agent and the folder first on your PATH;
|
|
10
11
|
* off = no files, no PATH entry. Only touches files it wrote and its own PATH entry; does nothing when already right.
|
|
11
12
|
*/
|
|
12
|
-
export declare function reconcileAgentCommands(config: Config, storageRoot: string,
|
|
13
|
+
export declare function reconcileAgentCommands(config: Config, storageRoot: string, target: ForwardTarget): Reconciled;
|
|
@@ -5,7 +5,7 @@ import { writeFileAtomic } from '../../shared/io/index.js';
|
|
|
5
5
|
import { safeRemove } from '../../shared/io/index.js';
|
|
6
6
|
import { MARKER, forwardingCmd, forwardingSh } from './forwarders.js';
|
|
7
7
|
import { commandsDir, cmdSafe, agentCommands } from './commands.js';
|
|
8
|
-
import { editUserPath } from './user-path.js';
|
|
8
|
+
import { editUserPath, userPathHas } from './user-path.js';
|
|
9
9
|
const ownFiles = (dir) => fs.existsSync(dir)
|
|
10
10
|
? fs
|
|
11
11
|
.readdirSync(dir)
|
|
@@ -23,7 +23,7 @@ const ownFiles = (dir) => fs.existsSync(dir)
|
|
|
23
23
|
* Makes this PC match agentCommands: on = a forwarding file per installed agent and the folder first on your PATH;
|
|
24
24
|
* off = no files, no PATH entry. Only touches files it wrote and its own PATH entry; does nothing when already right.
|
|
25
25
|
*/
|
|
26
|
-
export function reconcileAgentCommands(config, storageRoot,
|
|
26
|
+
export function reconcileAgentCommands(config, storageRoot, target) {
|
|
27
27
|
const dir = commandsDir(storageRoot);
|
|
28
28
|
if (!config.agentCommands.enabled) {
|
|
29
29
|
if (!fs.existsSync(dir))
|
|
@@ -35,14 +35,14 @@ export function reconcileAgentCommands(config, storageRoot, node, entry) {
|
|
|
35
35
|
safeRemove(dir, storageRoot);
|
|
36
36
|
return { on: false, commands: [], changed: true };
|
|
37
37
|
}
|
|
38
|
-
if (!
|
|
38
|
+
if (![target.node, target.entry, target.launcher ?? ''].every(cmdSafe))
|
|
39
39
|
throw new Error('This tool is installed in a folder whose path has % " or ^, which cannot go into a command file safely.');
|
|
40
40
|
const commands = agentCommands(config, storageRoot);
|
|
41
41
|
ensureDir(dir);
|
|
42
42
|
const wanted = new Map();
|
|
43
43
|
for (const a of commands) {
|
|
44
|
-
wanted.set(path.join(dir, a.command + '.cmd'), forwardingCmd(a,
|
|
45
|
-
wanted.set(path.join(dir, a.command), forwardingSh(a,
|
|
44
|
+
wanted.set(path.join(dir, a.command + '.cmd'), forwardingCmd(a, target));
|
|
45
|
+
wanted.set(path.join(dir, a.command), forwardingSh(a, target));
|
|
46
46
|
}
|
|
47
47
|
let changed = false;
|
|
48
48
|
for (const f of ownFiles(dir))
|
|
@@ -60,9 +60,8 @@ export function reconcileAgentCommands(config, storageRoot, node, entry) {
|
|
|
60
60
|
changed = true;
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
.some((d) => path.resolve(d).toLowerCase() === path.resolve(dir).toLowerCase());
|
|
63
|
+
// Your PATH as stored (not this process's copy of it, which an older terminal keeps): the registry says if it is on.
|
|
64
|
+
const onPath = !changed && userPathHas(dir, storageRoot);
|
|
66
65
|
if (changed || !onPath)
|
|
67
66
|
editUserPath(dir, true, storageRoot);
|
|
68
67
|
return { on: true, commands, changed: changed || !onPath };
|
|
@@ -3,3 +3,8 @@
|
|
|
3
3
|
* <storageRoot>\bin), else native\scripts\edit-user-path.ps1.
|
|
4
4
|
*/
|
|
5
5
|
export declare function editUserPath(dir: string, add: boolean, storageRoot: string): void;
|
|
6
|
+
/**
|
|
7
|
+
* Whether dir is on YOUR PATH as stored in the registry (not this process's copy, which an older terminal keeps stale).
|
|
8
|
+
* False when it cannot be told: the caller then edits the PATH again, which is harmless.
|
|
9
|
+
*/
|
|
10
|
+
export declare function userPathHas(dir: string, storageRoot: string): boolean;
|
|
@@ -23,3 +23,16 @@ export function editUserPath(dir, add, storageRoot) {
|
|
|
23
23
|
' your PATH: ' +
|
|
24
24
|
(result.stderr || result.error?.message || 'exit ' + result.status).trim());
|
|
25
25
|
}
|
|
26
|
+
/**
|
|
27
|
+
* Whether dir is on YOUR PATH as stored in the registry (not this process's copy, which an older terminal keeps stale).
|
|
28
|
+
* False when it cannot be told: the caller then edits the PATH again, which is harmless.
|
|
29
|
+
*/
|
|
30
|
+
export function userPathHas(dir, storageRoot) {
|
|
31
|
+
refuseInSelfTest('read your PATH');
|
|
32
|
+
const tools = hostToolsExe(storageRoot);
|
|
33
|
+
const options = { encoding: 'utf8', windowsHide: true };
|
|
34
|
+
const result = tools
|
|
35
|
+
? spawnSync(tools, ['user-path', '--has', dir], options)
|
|
36
|
+
: spawnSync(SYSTEM.powershell(), nativeScript('edit-user-path.ps1', ['-Dir', dir, '-Query']), options);
|
|
37
|
+
return result.status === 0;
|
|
38
|
+
}
|
|
@@ -10,4 +10,4 @@ export interface GithubDelivery {
|
|
|
10
10
|
readonly notes: readonly string[];
|
|
11
11
|
}
|
|
12
12
|
/** What this launch hands over. Never throws: a token that cannot be read is a note, and the launch goes on. */
|
|
13
|
-
export declare function prepareGithubToken(config: Config, storageRoot: string, store?: GithubToken, others?: readonly BootWant[]): GithubDelivery;
|
|
13
|
+
export declare function prepareGithubToken(config: Config, storageRoot: string, store?: GithubToken, others?: readonly BootWant[], now?: number): GithubDelivery;
|
|
@@ -10,8 +10,26 @@ function stricterProject(config, others) {
|
|
|
10
10
|
export function githubTokenAllowed(config, others = []) {
|
|
11
11
|
return config.github.shareToken && stricterProject(config, others) === null;
|
|
12
12
|
}
|
|
13
|
+
/** A token that ends within this many days is mentioned at launch. */
|
|
14
|
+
const EXPIRY_NOTE_DAYS = 7;
|
|
15
|
+
/** "Your GitHub token expires in 3 days" (or has expired), from what GitHub said when it was saved. */
|
|
16
|
+
function expiryNotes(tokens, now = Date.now()) {
|
|
17
|
+
const at = Date.parse(tokens.check()?.expiresAt ?? '');
|
|
18
|
+
if (Number.isNaN(at))
|
|
19
|
+
return [];
|
|
20
|
+
const days = Math.ceil((at - now) / 86_400_000);
|
|
21
|
+
if (at <= now)
|
|
22
|
+
return ['Your GitHub token has expired, so GitHub will refuse it. Make a new one in Accounts.'];
|
|
23
|
+
if (days > EXPIRY_NOTE_DAYS)
|
|
24
|
+
return [];
|
|
25
|
+
return [
|
|
26
|
+
'Your GitHub token expires ' +
|
|
27
|
+
(days <= 1 ? 'within a day' : 'in ' + days + ' days') +
|
|
28
|
+
'. Make a new one in Accounts.',
|
|
29
|
+
];
|
|
30
|
+
}
|
|
13
31
|
/** What this launch hands over. Never throws: a token that cannot be read is a note, and the launch goes on. */
|
|
14
|
-
export function prepareGithubToken(config, storageRoot, store, others = []) {
|
|
32
|
+
export function prepareGithubToken(config, storageRoot, store, others = [], now = Date.now()) {
|
|
15
33
|
if (!config.github.shareToken)
|
|
16
34
|
return { notes: [] };
|
|
17
35
|
const stricter = stricterProject(config, others);
|
|
@@ -46,6 +64,7 @@ export function prepareGithubToken(config, storageRoot, store, others = []) {
|
|
|
46
64
|
token,
|
|
47
65
|
notes: [
|
|
48
66
|
'Your GitHub token is handed to this sandbox (github.shareToken): the agent can read it and use it for whatever it allows.',
|
|
67
|
+
...expiryNotes(tokens, now),
|
|
49
68
|
],
|
|
50
69
|
};
|
|
51
70
|
}
|
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
export { GithubToken, checkGithubToken, type TokenState } from './token.js';
|
|
1
|
+
export { GithubToken, checkGithubToken, type SavedCheck, type TokenState } from './token.js';
|
|
2
2
|
export { githubTokenAllowed, prepareGithubToken, type GithubDelivery } from './deliver.js';
|
|
3
|
+
export { expiryFromHeader, verifyGithubToken, type GithubCheck, type GithubVerdict } from './verify.js';
|
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
// The GitHub token for sandboxes: its encrypted store and whether a launch hands it over.
|
|
2
2
|
export { GithubToken, checkGithubToken } from './token.js';
|
|
3
3
|
export { githubTokenAllowed, prepareGithubToken } from './deliver.js';
|
|
4
|
+
export { expiryFromHeader, verifyGithubToken } from './verify.js';
|
|
@@ -1,5 +1,14 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
1
2
|
import { type GithubTokenKind } from '../../shared/github/index.js';
|
|
2
3
|
import { SecretStore } from '../secrets/index.js';
|
|
4
|
+
/** What GitHub said about the token when it was saved (never the token): shown in the status. */
|
|
5
|
+
declare const SavedCheckSchema: z.ZodObject<{
|
|
6
|
+
login: z.ZodString;
|
|
7
|
+
expiresAt: z.ZodNullable<z.ZodString>;
|
|
8
|
+
repoCount: z.ZodNumber;
|
|
9
|
+
checkedAt: z.ZodString;
|
|
10
|
+
}, z.core.$strip>;
|
|
11
|
+
export type SavedCheck = z.output<typeof SavedCheckSchema>;
|
|
3
12
|
/** What the status may say about the token: never its value. */
|
|
4
13
|
export type TokenState = 'none' | 'saved' | 'unreadable';
|
|
5
14
|
/** The token's kind, or a refusal that says what to do (the message never holds what was typed). */
|
|
@@ -10,7 +19,9 @@ export declare class GithubToken {
|
|
|
10
19
|
constructor(storageRoot: string, secrets?: SecretStore);
|
|
11
20
|
private file;
|
|
12
21
|
/** Checks, encrypts and saves the token (replacing an earlier one). Returns its kind. */
|
|
13
|
-
save(token: string): GithubTokenKind;
|
|
22
|
+
save(token: string, check?: SavedCheck): GithubTokenKind;
|
|
23
|
+
/** What GitHub said when the token was saved: who it is, when it expires, how many repositories (or null). */
|
|
24
|
+
check(): SavedCheck | null;
|
|
14
25
|
/** The token, decrypted. Only the launch calls this; throws when this Windows user cannot open it. */
|
|
15
26
|
read(): string | null;
|
|
16
27
|
/** Whether a token is saved and can be decrypted by this Windows user (the value is never returned). */
|
|
@@ -19,3 +30,4 @@ export declare class GithubToken {
|
|
|
19
30
|
kind(): GithubTokenKind | null;
|
|
20
31
|
remove(): boolean;
|
|
21
32
|
}
|
|
33
|
+
export {};
|
|
@@ -8,8 +8,16 @@ import { JsonFile } from '../../shared/io/index.js';
|
|
|
8
8
|
import { GITHUB_TOKEN_KINDS, GithubTokenSchema, githubTokenKind, githubTokenProblem, } from '../../shared/github/index.js';
|
|
9
9
|
import { fail } from '../../core/util/index.js';
|
|
10
10
|
import { SecretStore } from '../secrets/index.js';
|
|
11
|
+
/** What GitHub said about the token when it was saved (never the token): shown in the status. */
|
|
12
|
+
const SavedCheckSchema = z.object({
|
|
13
|
+
login: z.string().max(100),
|
|
14
|
+
expiresAt: z.string().max(64).nullable(),
|
|
15
|
+
repoCount: z.number().int().min(0).max(100000),
|
|
16
|
+
checkedAt: z.string().max(64),
|
|
17
|
+
});
|
|
11
18
|
const SavedSchema = z.object({
|
|
12
19
|
savedAt: z.string().max(64),
|
|
20
|
+
check: SavedCheckSchema.optional(),
|
|
13
21
|
kind: z.enum(GITHUB_TOKEN_KINDS),
|
|
14
22
|
sealed: z.string().max(10000),
|
|
15
23
|
});
|
|
@@ -31,11 +39,20 @@ export class GithubToken {
|
|
|
31
39
|
return new JsonFile(SavedSchema, path.join(this.storageRoot, 'github', 'token.json'));
|
|
32
40
|
}
|
|
33
41
|
/** Checks, encrypts and saves the token (replacing an earlier one). Returns its kind. */
|
|
34
|
-
save(token) {
|
|
42
|
+
save(token, check) {
|
|
35
43
|
const kind = checkGithubToken(token);
|
|
36
|
-
this.file().write({
|
|
44
|
+
this.file().write({
|
|
45
|
+
savedAt: new Date().toISOString(),
|
|
46
|
+
kind,
|
|
47
|
+
sealed: this.secrets.sealJson({ token }),
|
|
48
|
+
...(check ? { check } : {}),
|
|
49
|
+
});
|
|
37
50
|
return kind;
|
|
38
51
|
}
|
|
52
|
+
/** What GitHub said when the token was saved: who it is, when it expires, how many repositories (or null). */
|
|
53
|
+
check() {
|
|
54
|
+
return this.file().read()?.check ?? null;
|
|
55
|
+
}
|
|
39
56
|
/** The token, decrypted. Only the launch calls this; throws when this Windows user cannot open it. */
|
|
40
57
|
read() {
|
|
41
58
|
const saved = this.file().read();
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { type RequestFetcher } from '../../shared/download/index.js';
|
|
2
|
+
/** What GitHub told about a token (never the token). */
|
|
3
|
+
export interface GithubCheck {
|
|
4
|
+
readonly login: string;
|
|
5
|
+
/** ISO time, or null: it never expires (or GitHub did not say). */
|
|
6
|
+
readonly expiresAt: string | null;
|
|
7
|
+
readonly repos: {
|
|
8
|
+
readonly count: number;
|
|
9
|
+
readonly sample: readonly string[];
|
|
10
|
+
};
|
|
11
|
+
/** A classic token's scopes, as GitHub lists them. */
|
|
12
|
+
readonly scopes?: string;
|
|
13
|
+
}
|
|
14
|
+
/** The answer: a check, GitHub refusing the token, or GitHub not reachable (the token may still be fine). */
|
|
15
|
+
export type GithubVerdict = {
|
|
16
|
+
readonly kind: 'ok';
|
|
17
|
+
readonly check: GithubCheck;
|
|
18
|
+
} | {
|
|
19
|
+
readonly kind: 'refused';
|
|
20
|
+
readonly status: number;
|
|
21
|
+
} | {
|
|
22
|
+
readonly kind: 'unreachable';
|
|
23
|
+
readonly reason: string;
|
|
24
|
+
};
|
|
25
|
+
/** "2027-02-03 10:00:00 UTC" as an ISO time, or null. */
|
|
26
|
+
export declare function expiryFromHeader(value: string | null): string | null;
|
|
27
|
+
export declare function verifyGithubToken(token: string, fetcher?: RequestFetcher): Promise<GithubVerdict>;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
// Asks GitHub who a token belongs to, when it expires and how many repositories it reaches, right after it was typed,
|
|
2
|
+
// so a wrong or expired token is caught at once. The token goes only in the Authorization header of two requests to
|
|
3
|
+
// api.github.com; the answers are size-limited and read through strict shapes. Nothing here prints the token.
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
import { fetchBoundedResponse } from '../../shared/download/index.js';
|
|
6
|
+
const API = 'https://api.github.com';
|
|
7
|
+
const MAX_BYTES = 1024 * 1024;
|
|
8
|
+
/** GitHub's header on a token's answers: "2027-02-03 10:00:00 UTC". */
|
|
9
|
+
const EXPIRY_HEADER = 'github-authentication-token-expiration';
|
|
10
|
+
const UserSchema = z.object({ login: z.string().min(1).max(100) });
|
|
11
|
+
const ReposSchema = z.array(z.object({ full_name: z.string().min(1).max(200) })).max(100);
|
|
12
|
+
/** "2027-02-03 10:00:00 UTC" as an ISO time, or null. */
|
|
13
|
+
export function expiryFromHeader(value) {
|
|
14
|
+
const match = /^(\d{4}-\d{2}-\d{2}) (\d{2}:\d{2}:\d{2}) UTC$/.exec(value?.trim() ?? '');
|
|
15
|
+
if (!match)
|
|
16
|
+
return null;
|
|
17
|
+
const time = Date.parse(match[1] + 'T' + match[2] + 'Z');
|
|
18
|
+
return Number.isNaN(time) ? null : new Date(time).toISOString();
|
|
19
|
+
}
|
|
20
|
+
export async function verifyGithubToken(token, fetcher = fetchBoundedResponse) {
|
|
21
|
+
const init = {
|
|
22
|
+
headers: {
|
|
23
|
+
Authorization: 'Bearer ' + token,
|
|
24
|
+
Accept: 'application/vnd.github+json',
|
|
25
|
+
'X-GitHub-Api-Version': '2022-11-28',
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
try {
|
|
29
|
+
const user = await fetcher(API + '/user', MAX_BYTES, init);
|
|
30
|
+
if (user.status === 401 || user.status === 403)
|
|
31
|
+
return { kind: 'refused', status: user.status };
|
|
32
|
+
if (user.status !== 200)
|
|
33
|
+
return { kind: 'unreachable', reason: 'GitHub answered ' + user.status + '.' };
|
|
34
|
+
const who = UserSchema.safeParse(JSON.parse(user.text));
|
|
35
|
+
if (!who.success)
|
|
36
|
+
return { kind: 'unreachable', reason: 'GitHub gave an answer this program does not know.' };
|
|
37
|
+
const expiresAt = expiryFromHeader(user.header(EXPIRY_HEADER));
|
|
38
|
+
const scopes = user.header('x-oauth-scopes')?.trim();
|
|
39
|
+
const repos = await fetcher(API + '/user/repos?per_page=100&affiliation=owner,collaborator,organization_member', MAX_BYTES, init);
|
|
40
|
+
const list = repos.status === 200 ? ReposSchema.safeParse(JSON.parse(repos.text)) : undefined;
|
|
41
|
+
const names = list?.success ? list.data.map((r) => r.full_name) : [];
|
|
42
|
+
return {
|
|
43
|
+
kind: 'ok',
|
|
44
|
+
check: {
|
|
45
|
+
login: who.data.login,
|
|
46
|
+
expiresAt,
|
|
47
|
+
repos: { count: names.length, sample: names.slice(0, 5) },
|
|
48
|
+
...(scopes ? { scopes } : {}),
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
catch (e) {
|
|
53
|
+
// A timeout, no network, a body that is too big or not JSON: the token itself is not at fault.
|
|
54
|
+
const reason = e instanceof Error && e.name === 'TimeoutError'
|
|
55
|
+
? 'GitHub did not answer in time.'
|
|
56
|
+
: e instanceof Error && e.message.includes('too big')
|
|
57
|
+
? e.message
|
|
58
|
+
: 'GitHub could not be reached.';
|
|
59
|
+
return { kind: 'unreachable', reason };
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
import type { Toolchains } from '../../../core/types.js';
|
|
2
2
|
import type { ToolchainHints } from './hint.js';
|
|
3
|
-
|
|
3
|
+
/** The resource manifests in the project (relative paths), at most 3 folders down. */
|
|
4
|
+
export declare function findManifests(root: string): string[];
|
|
5
|
+
export declare function fivemHints(root: string, settings: Toolchains): ToolchainHints;
|
|
@@ -1,3 +1,69 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
// FiveM / RedM: toolchain hints from file contents: fxmanifest.lua or __resource.lua up to 3 folders down turns fivem
|
|
2
|
+
// on (resources\[local]\my-resource\fxmanifest.lua), a C# resource dotnet (a manifest that loads *.net.dll, or a
|
|
3
|
+
// .csproj in the resource's folder or one below). Files are found by name and size-checked before they are read, links
|
|
4
|
+
// are never followed and the walk is bounded (the project may be hostile).
|
|
5
|
+
import fs from 'node:fs';
|
|
6
|
+
import path from 'node:path';
|
|
7
|
+
const SKIP = /^(node_modules|\.git|\.hg|\.svn|vendor|target|bin|obj|dist|build|out|cache|\.vs|\.idea|packages)$/i;
|
|
8
|
+
const MANIFEST = /^(fxmanifest|__resource)\.lua$/i;
|
|
9
|
+
const MAX_DEPTH = 3;
|
|
10
|
+
const MAX_FOLDERS = 2000;
|
|
11
|
+
const MAX_MANIFESTS = 200;
|
|
12
|
+
const MAX_BYTES = 64 * 1024;
|
|
13
|
+
const list = (dir) => {
|
|
14
|
+
try {
|
|
15
|
+
return fs.readdirSync(dir, { withFileTypes: true }).slice(0, 2000);
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
return [];
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
/** The resource manifests in the project (relative paths), at most 3 folders down. */
|
|
22
|
+
export function findManifests(root) {
|
|
23
|
+
const found = [];
|
|
24
|
+
let folders = 0;
|
|
25
|
+
const walk = (dir, level) => {
|
|
26
|
+
if (++folders > MAX_FOLDERS || found.length >= MAX_MANIFESTS)
|
|
27
|
+
return;
|
|
28
|
+
for (const e of list(dir)) {
|
|
29
|
+
if (e.isFile() && MANIFEST.test(e.name))
|
|
30
|
+
found.push(path.relative(root, path.join(dir, e.name)));
|
|
31
|
+
else if (e.isDirectory() && level < MAX_DEPTH && !SKIP.test(e.name))
|
|
32
|
+
walk(path.join(dir, e.name), level + 1);
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
walk(root, 0);
|
|
36
|
+
return found;
|
|
37
|
+
}
|
|
38
|
+
const readSmall = (file) => {
|
|
39
|
+
try {
|
|
40
|
+
const st = fs.lstatSync(file);
|
|
41
|
+
return st.isFile() && st.size <= MAX_BYTES ? fs.readFileSync(file, 'utf8') : '';
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
return '';
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
const hasCsproj = (dir) => list(dir).some((e) => (e.isFile() && /\.csproj$/i.test(e.name)) ||
|
|
48
|
+
(e.isDirectory() &&
|
|
49
|
+
!SKIP.test(e.name) &&
|
|
50
|
+
list(path.join(dir, e.name)).some((f) => f.isFile() && /\.csproj$/i.test(f.name))));
|
|
51
|
+
/** Whether the resource whose manifest this is is written in C# (FiveM loads C# from *.net.dll). */
|
|
52
|
+
function isCsharpResource(root, manifest) {
|
|
53
|
+
if (/\.net\.dll/i.test(readSmall(path.join(root, manifest))))
|
|
54
|
+
return true;
|
|
55
|
+
return hasCsproj(path.dirname(path.join(root, manifest)));
|
|
56
|
+
}
|
|
57
|
+
export function fivemHints(root, settings) {
|
|
58
|
+
if (settings.fivem.enabled === false)
|
|
59
|
+
return {};
|
|
60
|
+
const manifests = findManifests(root);
|
|
61
|
+
if (!manifests.length)
|
|
62
|
+
return {};
|
|
63
|
+
const shown = (rel) => rel.split(path.sep).join('/');
|
|
64
|
+
const hints = { fivem: shown(manifests[0]) + ' (a FiveM / RedM resource)' };
|
|
65
|
+
const csharp = manifests.slice(0, 50).find((m) => isCsharpResource(root, m));
|
|
66
|
+
if (csharp)
|
|
67
|
+
hints.dotnet = 'a C# FiveM resource (' + shown(csharp) + ')';
|
|
68
|
+
return hints;
|
|
3
69
|
}
|
|
@@ -32,6 +32,10 @@ export function guestSession(o, parts) {
|
|
|
32
32
|
projectsDir: PROJECTS_GUEST,
|
|
33
33
|
// Every folder mapped for other projects (roots and projects mapped at boot): the guest accepts projects in them.
|
|
34
34
|
roots: [...parts.boot.roots, ...parts.boot.projects].map((r) => r.guest),
|
|
35
|
+
mappedProjects: [
|
|
36
|
+
...parts.boot.roots.map((r) => ({ host: r.host, guest: r.guest, root: true })),
|
|
37
|
+
...parts.boot.projects.map((r) => ({ host: r.host, guest: r.guest })),
|
|
38
|
+
],
|
|
35
39
|
...(o.autoSession === false ? { autoSession: false } : {}),
|
|
36
40
|
harnessName,
|
|
37
41
|
// The environment (it may hold API keys) travels in a one-shot file in <data>\secrets, never in this file.
|
|
@@ -65,6 +69,7 @@ export function guestSession(o, parts) {
|
|
|
65
69
|
loadProfile: loadProfileOf(config),
|
|
66
70
|
pageFileMb: config.sandbox.pageFileMb,
|
|
67
71
|
agentBackstop: config.sandbox.agentMemoryHeadroomMb,
|
|
72
|
+
codex: config.codex,
|
|
68
73
|
pressureResponse: config.sandbox.pressureResponse,
|
|
69
74
|
apps: config.apps,
|
|
70
75
|
auditProcesses: config.audit.enabled && config.audit.processes,
|
|
@@ -6,6 +6,7 @@ import { decideToolchains } from '../../core/detect/index.js';
|
|
|
6
6
|
export declare function decideProjectToolchains(o: Pick<GenerateOptions, 'run' | 'pcLanguages'>): ReturnType<typeof decideToolchains>;
|
|
7
7
|
/**
|
|
8
8
|
* The toolchains a service sign-in may serve that are on for this boot: the launch's own project (its files decide
|
|
9
|
-
* "auto") and the other boot projects that turn one on in their settings.
|
|
9
|
+
* "auto") and the other boot projects that turn one on in their settings. Plus the apps that use one (Perplexity's
|
|
10
|
+
* MCP server, Comet), from your apps.install: apps are installed for the launch's settings only.
|
|
10
11
|
*/
|
|
11
12
|
export declare function toolchainsOnForBoot(o: Pick<GenerateOptions, 'run' | 'pcLanguages'>, others?: readonly BootWant[]): Set<UsedBy>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { USED_BY } from '../../shared/accounts/index.js';
|
|
1
|
+
import { appUsersOn, USED_BY } from '../../shared/accounts/index.js';
|
|
2
2
|
import { decideToolchains, readPwshScripts, usesPwsh } from '../../core/detect/index.js';
|
|
3
3
|
import { pcLanguages } from './pc-scan.js';
|
|
4
4
|
import { msvcHint, projectEntries, uvHint } from './project-scan.js';
|
|
@@ -24,9 +24,11 @@ export function decideProjectToolchains(o) {
|
|
|
24
24
|
}
|
|
25
25
|
/**
|
|
26
26
|
* The toolchains a service sign-in may serve that are on for this boot: the launch's own project (its files decide
|
|
27
|
-
* "auto") and the other boot projects that turn one on in their settings.
|
|
27
|
+
* "auto") and the other boot projects that turn one on in their settings. Plus the apps that use one (Perplexity's
|
|
28
|
+
* MCP server, Comet), from your apps.install: apps are installed for the launch's settings only.
|
|
28
29
|
*/
|
|
29
30
|
export function toolchainsOnForBoot(o, others = []) {
|
|
30
31
|
const decisions = decideProjectToolchains(o);
|
|
31
|
-
|
|
32
|
+
const toolchains = USED_BY.filter((u) => decisions[u].on || others.some((p) => p.config.toolchains[u].enabled === true));
|
|
33
|
+
return new Set([...toolchains, ...appUsersOn(o.run.config.apps.install)]);
|
|
32
34
|
}
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
import fs from 'node:fs';
|
|
10
10
|
import path from 'node:path';
|
|
11
11
|
import { z } from 'zod';
|
|
12
|
+
import { ANTHROPIC_KEY_HINT } from '../../shared/accounts/index.js';
|
|
12
13
|
import { isSafeFileName } from '../../shared/paths/index.js';
|
|
13
14
|
import { JsonFile } from '../../shared/io/index.js';
|
|
14
15
|
import { storageOf } from '../storage/index.js';
|
|
@@ -36,10 +37,7 @@ const SealedSchema = z.object({
|
|
|
36
37
|
email: z.string().max(200).nullable(),
|
|
37
38
|
/** Missing in accounts saved before keys could be: a subscription. */
|
|
38
39
|
kind: z.enum(LOGIN_KINDS).optional(),
|
|
39
|
-
keyHint: z
|
|
40
|
-
.string()
|
|
41
|
-
.regex(/^sk-ant-\.\.\.[A-Za-z0-9_-]{4}$/)
|
|
42
|
-
.optional(),
|
|
40
|
+
keyHint: z.string().regex(ANTHROPIC_KEY_HINT).optional(),
|
|
43
41
|
sealed: z.string().max(200000),
|
|
44
42
|
});
|
|
45
43
|
const StoredSchema = z.union([SealedSchema, AccountSchema]);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { anthropicKeyProblem } from '../../shared/accounts/index.js';
|
|
1
2
|
/** subscription: claude.ai OAuth; console: the key a Console login made; api-key: a key you gave. */
|
|
2
3
|
export type LoginKind = 'subscription' | 'console' | 'api-key';
|
|
3
4
|
export declare const LOGIN_KINDS: readonly ["subscription", "console", "api-key"];
|
|
@@ -16,8 +17,8 @@ export interface CaptureOptions {
|
|
|
16
17
|
/** ANTHROPIC_API_KEY of this PC: the last place looked at (--from-host only). */
|
|
17
18
|
readonly envKey?: string | null;
|
|
18
19
|
}
|
|
19
|
-
/** What is wrong with a typed or found API key, or null
|
|
20
|
-
export declare
|
|
20
|
+
/** What is wrong with a typed or found API key (sk-ant-api or sk-ant-usr), or null. Never quotes the key. */
|
|
21
|
+
export declare const apiKeyProblem: typeof anthropicKeyProblem;
|
|
21
22
|
/** The most of a key that is ever shown: sk-ant-...abcd. */
|
|
22
23
|
export declare function maskApiKey(key: string): string;
|
|
23
24
|
export interface LoginFiles {
|