windows-development-sandbox 1.5.0 → 1.9.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 -0
- package/config.example.json +27 -1
- package/dist/app/context.d.ts +8 -0
- package/dist/app/context.js +12 -0
- package/dist/app/features/defs.d.ts +322 -0
- package/dist/app/features/defs.js +28 -0
- package/dist/app/features/sandbox/index.d.ts +2 -0
- package/dist/app/features/sandbox/index.js +3 -0
- package/dist/app/features/sandbox/sandbox.def.d.ts +193 -0
- package/dist/app/features/sandbox/sandbox.def.js +245 -0
- package/dist/app/features/sandbox/sandbox.run.d.ts +72 -0
- package/dist/app/features/sandbox/sandbox.run.js +98 -0
- package/dist/app/features/sessions/index.d.ts +2 -0
- package/dist/app/features/sessions/index.js +3 -0
- package/dist/app/features/sessions/sessions.def.d.ts +141 -0
- package/dist/app/features/sessions/sessions.def.js +176 -0
- package/dist/app/features/sessions/sessions.run.d.ts +39 -0
- package/dist/app/features/sessions/sessions.run.js +58 -0
- package/dist/{cli/menu/settings/categories.d.ts → app/features/settings/categories.def.d.ts} +4 -0
- package/dist/{cli/menu/settings/categories.js → app/features/settings/categories.def.js} +40 -46
- package/dist/app/features/settings/index.d.ts +5 -0
- package/dist/app/features/settings/index.js +6 -0
- package/dist/{cli/menu/settings/config-file.d.ts → app/features/settings/settings-file.d.ts} +1 -1
- package/dist/{cli/menu/settings/config-file.js → app/features/settings/settings-file.js} +1 -1
- package/dist/app/features/settings/settings-rows.d.ts +35 -0
- package/dist/app/features/settings/settings-rows.js +94 -0
- package/dist/app/features/settings/settings.def.d.ts +157 -0
- package/dist/app/features/settings/settings.def.js +179 -0
- package/dist/app/features/settings/settings.run.d.ts +67 -0
- package/dist/app/features/settings/settings.run.js +84 -0
- package/dist/app/kernel/define.d.ts +143 -0
- package/dist/app/kernel/define.js +42 -0
- package/dist/app/kernel/errors.d.ts +34 -0
- package/dist/app/kernel/errors.js +45 -0
- package/dist/app/kernel/fields.d.ts +70 -0
- package/dist/app/kernel/fields.js +243 -0
- package/dist/app/kernel/index.d.ts +8 -0
- package/dist/app/kernel/index.js +10 -0
- package/dist/app/kernel/io.d.ts +193 -0
- package/dist/app/kernel/io.js +126 -0
- package/dist/app/kernel/rpc.d.ts +156 -0
- package/dist/app/kernel/rpc.js +47 -0
- package/dist/{cli/menu/settings → app/kernel}/schema-node.d.ts +9 -0
- package/dist/{cli/menu/settings → app/kernel}/schema-node.js +26 -0
- package/dist/app/kernel/text.d.ts +6 -0
- package/dist/app/kernel/text.js +57 -0
- package/dist/app/kernel/view.d.ts +146 -0
- package/dist/app/kernel/view.js +28 -0
- package/dist/app/registry.d.ts +10 -0
- package/dist/app/registry.js +50 -0
- package/dist/cli/args.d.ts +18 -2
- package/dist/cli/args.js +101 -24
- package/dist/cli/commands/accounts.js +45 -17
- package/dist/cli/commands/context.d.ts +2 -0
- package/dist/cli/commands/context.js +9 -2
- package/dist/cli/commands/data/clean.js +32 -9
- package/dist/cli/commands/engine.d.ts +2 -0
- package/dist/cli/commands/engine.js +60 -0
- package/dist/cli/commands/index.d.ts +2 -1
- package/dist/cli/commands/index.js +2 -1
- package/dist/cli/commands/launch/add-root.d.ts +3 -2
- package/dist/cli/commands/launch/add-root.js +11 -10
- package/dist/cli/commands/launch/launch.js +102 -9
- package/dist/cli/commands/launch/prepare.js +6 -4
- package/dist/cli/commands/launch/running.js +2 -1
- package/dist/cli/commands/launch/summary.d.ts +2 -0
- package/dist/cli/commands/maintenance/audit.js +1 -1
- package/dist/cli/commands/maintenance/clean.d.ts +1 -1
- package/dist/cli/commands/maintenance/clean.js +17 -3
- package/dist/cli/commands/maintenance/config-share.d.ts +12 -0
- package/dist/cli/commands/maintenance/config-share.js +80 -0
- package/dist/cli/commands/maintenance/config.d.ts +1 -1
- package/dist/cli/commands/maintenance/config.js +38 -10
- package/dist/cli/commands/maintenance/doctor.d.ts +1 -1
- package/dist/cli/commands/maintenance/doctor.js +2 -4
- package/dist/cli/commands/maintenance/logs.js +14 -0
- package/dist/cli/commands/maintenance/migrate.d.ts +2 -1
- package/dist/cli/commands/maintenance/migrate.js +19 -4
- package/dist/cli/commands/maintenance/sync.js +2 -0
- package/dist/cli/commands/maintenance/update.d.ts +2 -0
- package/dist/cli/commands/maintenance/update.js +27 -4
- package/dist/cli/commands/projects/here.js +12 -7
- package/dist/cli/commands/projects/projects.js +26 -17
- package/dist/cli/commands/registry.js +10 -7
- package/dist/cli/commands/repair/checks/agents.d.ts +2 -0
- package/dist/cli/commands/repair/checks/agents.js +70 -0
- package/dist/cli/commands/repair/checks/common.d.ts +8 -0
- package/dist/cli/commands/repair/checks/common.js +22 -0
- package/dist/cli/commands/repair/checks/contained.d.ts +2 -0
- package/dist/cli/commands/repair/checks/contained.js +139 -0
- package/dist/cli/commands/repair/checks/data.d.ts +2 -0
- package/dist/cli/commands/repair/checks/data.js +241 -0
- package/dist/cli/commands/repair/checks/hcs.d.ts +7 -0
- package/dist/cli/commands/repair/checks/hcs.js +28 -0
- package/dist/cli/commands/repair/checks/index.d.ts +2 -0
- package/dist/cli/commands/repair/checks/index.js +24 -0
- package/dist/cli/commands/repair/checks/install.d.ts +5 -0
- package/dist/cli/commands/repair/checks/install.js +318 -0
- package/dist/cli/commands/repair/checks/machine.d.ts +2 -0
- package/dist/cli/commands/repair/checks/machine.js +232 -0
- package/dist/cli/commands/repair/checks/network.d.ts +6 -0
- package/dist/cli/commands/repair/checks/network.js +60 -0
- package/dist/cli/commands/repair/checks/pc.d.ts +4 -0
- package/dist/cli/commands/repair/checks/pc.js +86 -0
- package/dist/cli/commands/repair/checks/sandbox.d.ts +2 -0
- package/dist/cli/commands/repair/checks/sandbox.js +282 -0
- package/dist/cli/commands/repair/checks/settings.d.ts +2 -0
- package/dist/cli/commands/repair/checks/settings.js +169 -0
- package/dist/cli/commands/repair/checks/vpn.d.ts +2 -0
- package/dist/cli/commands/repair/checks/vpn.js +78 -0
- package/dist/cli/commands/repair/engine.d.ts +32 -0
- package/dist/cli/commands/repair/engine.js +127 -0
- package/dist/cli/commands/repair/env.d.ts +7 -0
- package/dist/cli/commands/repair/env.js +50 -0
- package/dist/cli/commands/repair/index.d.ts +1 -9
- package/dist/cli/commands/repair/index.js +2 -54
- package/dist/cli/commands/repair/log.d.ts +17 -0
- package/dist/cli/commands/repair/log.js +82 -0
- package/dist/cli/commands/repair/printer.d.ts +32 -0
- package/dist/cli/commands/repair/printer.js +132 -0
- package/dist/cli/commands/repair/run.d.ts +33 -0
- package/dist/cli/commands/repair/run.js +133 -0
- package/dist/cli/commands/repair/types.d.ts +97 -9
- package/dist/cli/commands/repair/types.js +11 -7
- package/dist/cli/commands/resume.js +2 -2
- package/dist/cli/commands/sessions/index.d.ts +0 -4
- package/dist/cli/commands/sessions/index.js +3 -7
- package/dist/cli/commands/setup/index.d.ts +5 -0
- package/dist/cli/commands/setup/index.js +25 -1
- package/dist/cli/commands/shared-use.d.ts +5 -2
- package/dist/cli/commands/shared-use.js +11 -8
- package/dist/cli/commands/storage/contained.d.ts +3 -0
- package/dist/cli/commands/storage/contained.js +179 -0
- package/dist/cli/commands/storage/index.d.ts +2 -0
- package/dist/cli/commands/storage/index.js +2 -0
- package/dist/cli/commands/storage/offer.d.ts +3 -0
- package/dist/cli/commands/storage/offer.js +91 -0
- package/dist/cli/commands/storage/storage.d.ts +8 -0
- package/dist/cli/commands/storage/storage.js +179 -0
- package/dist/cli/commands/user-config.js +2 -2
- package/dist/cli/commands/vpn.d.ts +4 -0
- package/dist/cli/commands/vpn.js +91 -0
- package/dist/cli/commands/web.d.ts +4 -0
- package/dist/cli/commands/web.js +97 -0
- package/dist/cli/history.js +1 -1
- package/dist/cli/index.js +48 -4
- package/dist/cli/manifest.d.ts +339 -97
- package/dist/cli/manifest.js +222 -67
- package/dist/cli/menu/add-agent.d.ts +47 -0
- package/dist/cli/menu/add-agent.js +168 -0
- package/dist/cli/menu/apps.d.ts +38 -3
- package/dist/cli/menu/apps.js +80 -5
- package/dist/cli/menu/command-fields.d.ts +18 -0
- package/dist/cli/menu/command-fields.js +61 -0
- package/dist/cli/menu/command-form.d.ts +22 -0
- package/dist/cli/menu/command-form.js +169 -46
- package/dist/cli/menu/data-folder.d.ts +18 -0
- package/dist/cli/menu/data-folder.js +99 -0
- package/dist/cli/menu/io-menu.d.ts +29 -0
- package/dist/cli/menu/io-menu.js +126 -0
- package/dist/cli/menu/live.d.ts +27 -0
- package/dist/cli/menu/live.js +69 -0
- package/dist/cli/menu/memory.d.ts +19 -0
- package/dist/cli/menu/memory.js +53 -0
- package/dist/cli/menu/menu.d.ts +11 -2
- package/dist/cli/menu/menu.js +36 -15
- package/dist/cli/menu/pages/accounts-page.js +55 -24
- package/dist/cli/menu/pages/agents-page.d.ts +68 -0
- package/dist/cli/menu/pages/agents-page.js +345 -0
- package/dist/cli/menu/pages/apps-page.d.ts +3 -1
- package/dist/cli/menu/pages/apps-page.js +20 -4
- package/dist/cli/menu/pages/list-page.d.ts +43 -3
- package/dist/cli/menu/pages/list-page.js +146 -12
- package/dist/cli/menu/pages/maintenance-page.d.ts +9 -5
- package/dist/cli/menu/pages/maintenance-page.js +172 -85
- package/dist/cli/menu/pages/sandbox-page.d.ts +7 -6
- package/dist/cli/menu/pages/sandbox-page.js +117 -120
- package/dist/cli/menu/pages/scopes.d.ts +1 -1
- package/dist/cli/menu/pages/sessions-page.d.ts +6 -8
- package/dist/cli/menu/pages/sessions-page.js +22 -75
- package/dist/cli/menu/pages/settings-page.d.ts +10 -14
- package/dist/cli/menu/pages/settings-page.js +95 -102
- package/dist/cli/menu/render-view.d.ts +28 -0
- package/dist/cli/menu/render-view.js +112 -0
- package/dist/cli/menu/settings/ask-path.d.ts +14 -0
- package/dist/cli/menu/settings/ask-path.js +14 -0
- package/dist/cli/menu/settings/collections/collection-editor.d.ts +8 -2
- package/dist/cli/menu/settings/collections/collection-editor.js +12 -8
- package/dist/cli/menu/settings/collections/map-editor.js +5 -1
- package/dist/cli/menu/settings/collections/object-list-editor.js +2 -2
- package/dist/cli/menu/settings/collections/object-map-editor.js +2 -2
- package/dist/cli/menu/settings/collections/string-list-editor.d.ts +10 -1
- package/dist/cli/menu/settings/collections/string-list-editor.js +23 -0
- package/dist/cli/menu/settings/draft.d.ts +1 -1
- package/dist/cli/menu/settings/format.d.ts +1 -3
- package/dist/cli/menu/settings/format.js +6 -36
- package/dist/cli/menu/settings/index.d.ts +1 -3
- package/dist/cli/menu/settings/index.js +3 -3
- package/dist/cli/menu/settings/object-editor.d.ts +6 -2
- package/dist/cli/menu/settings/object-editor.js +15 -4
- package/dist/cli/menu/settings/share.d.ts +36 -0
- package/dist/cli/menu/settings/share.js +131 -0
- package/dist/cli/menu/settings/value-editor.d.ts +10 -1
- package/dist/cli/menu/settings/value-editor.js +99 -63
- package/dist/cli/menu/several.js +7 -5
- package/dist/cli/menu/share-settings.d.ts +21 -0
- package/dist/cli/menu/share-settings.js +112 -0
- package/dist/cli/menu/shell.d.ts +53 -10
- package/dist/cli/menu/shell.js +115 -10
- package/dist/cli/menu/views.d.ts +7 -0
- package/dist/cli/menu/views.js +11 -0
- package/dist/cli/menu/vpn-login.d.ts +16 -0
- package/dist/cli/menu/vpn-login.js +74 -0
- package/dist/cli/operations/handler.d.ts +6 -0
- package/dist/cli/operations/handler.js +61 -0
- package/dist/cli/operations/index.d.ts +4 -0
- package/dist/cli/operations/index.js +5 -0
- package/dist/cli/operations/input.d.ts +6 -0
- package/dist/cli/operations/input.js +37 -0
- package/dist/cli/operations/io-cli.d.ts +7 -0
- package/dist/cli/operations/io-cli.js +62 -0
- package/dist/cli/operations/spec.d.ts +18 -0
- package/dist/cli/operations/spec.js +108 -0
- package/dist/cli/output/colors.d.ts +2 -2
- package/dist/cli/output/colors.js +2 -11
- package/dist/cli/output/index.d.ts +1 -0
- package/dist/cli/output/index.js +1 -0
- package/dist/cli/output/print.d.ts +5 -1
- package/dist/cli/output/print.js +15 -4
- package/dist/cli/output/progress.d.ts +15 -0
- package/dist/cli/output/progress.js +44 -0
- package/dist/cli/output/render-view.d.ts +4 -0
- package/dist/cli/output/render-view.js +63 -0
- package/dist/cli/services/accounts-service.d.ts +2 -0
- package/dist/cli/services/accounts-service.js +2 -2
- package/dist/cli/services/agent-commands-service.d.ts +2 -0
- package/dist/cli/services/agent-commands-service.js +11 -2
- package/dist/cli/services/health-service.d.ts +0 -6
- package/dist/cli/services/health-service.js +5 -42
- package/dist/cli/services/index.d.ts +3 -1
- package/dist/cli/services/index.js +3 -1
- package/dist/cli/services/logs-service.js +4 -3
- package/dist/cli/services/migrate-service.js +1 -1
- package/dist/cli/services/update-service.d.ts +2 -0
- package/dist/cli/services/update-service.js +13 -6
- package/dist/cli/services/vpn-service.d.ts +28 -0
- package/dist/cli/services/vpn-service.js +46 -0
- package/dist/cli/services/web-service.d.ts +22 -0
- package/dist/cli/services/web-service.js +111 -0
- package/dist/cli/tui/app.d.ts +12 -4
- package/dist/cli/tui/app.js +38 -9
- package/dist/cli/tui/dialogs/path-listing.d.ts +43 -0
- package/dist/cli/tui/dialogs/path-listing.js +127 -0
- package/dist/cli/tui/dialogs/path-picker.d.ts +67 -0
- package/dist/cli/tui/dialogs/path-picker.js +423 -0
- package/dist/cli/tui/dialogs/text-screen.d.ts +6 -0
- package/dist/cli/tui/dialogs/text-screen.js +10 -3
- package/dist/cli/tui/frame.d.ts +7 -10
- package/dist/cli/tui/frame.js +19 -10
- package/dist/cli/tui/index.d.ts +4 -3
- package/dist/cli/tui/index.js +2 -1
- package/dist/cli/tui/list/list-screen.d.ts +28 -2
- package/dist/cli/tui/list/list-screen.js +130 -66
- package/dist/cli/tui/list/list-types.d.ts +10 -4
- package/dist/cli/tui/nav.d.ts +29 -0
- package/dist/cli/tui/nav.js +67 -0
- package/dist/cli/tui/terminal.d.ts +7 -0
- package/dist/cli/tui/terminal.js +30 -10
- package/dist/cli/validate.d.ts +1 -1
- package/dist/cli/validate.js +3 -3
- package/dist/cli/version.d.ts +2 -0
- package/dist/cli/version.js +11 -0
- package/dist/core/config/defaults.js +13 -1
- package/dist/core/config/loader.js +12 -2
- package/dist/core/local-config/overrides.js +1 -0
- package/dist/core/prompt.d.ts +19 -0
- package/dist/core/prompt.js +43 -3
- package/dist/core/schema/common.d.ts +6 -0
- package/dist/core/schema/common.js +8 -0
- package/dist/core/schema/config.d.ts +36 -0
- package/dist/core/schema/config.js +26 -2
- package/dist/core/schema/harness.d.ts +2 -0
- package/dist/core/schema/harness.js +13 -2
- package/dist/core/schema/index.d.ts +3 -1
- package/dist/core/schema/index.js +3 -1
- package/dist/core/schema/profile.d.ts +1 -0
- package/dist/core/schema/profile.js +3 -0
- package/dist/core/schema/redact.d.ts +13 -0
- package/dist/core/schema/redact.js +75 -0
- package/dist/core/schema/sandbox.d.ts +6 -0
- package/dist/core/schema/sandbox.js +21 -3
- package/dist/core/schema/vpn.d.ts +18 -0
- package/dist/core/schema/vpn.js +22 -0
- package/dist/core/schema/web.d.ts +6 -0
- package/dist/core/schema/web.js +14 -0
- package/dist/core/types.d.ts +44 -0
- package/dist/core/util/fs.d.ts +2 -0
- package/dist/core/util/fs.js +9 -0
- package/dist/core/util/index.d.ts +1 -1
- package/dist/core/util/index.js +1 -1
- package/dist/guest/agents/agent-files.d.ts +54 -0
- package/dist/guest/agents/agent-files.js +67 -0
- package/dist/guest/agents/agent-installer.js +2 -9
- package/dist/guest/agents/local-state.d.ts +14 -0
- package/dist/guest/agents/local-state.js +218 -0
- package/dist/guest/agents/sbx-agent.d.ts +2 -0
- package/dist/guest/agents/sbx-agent.js +35 -0
- package/dist/guest/boot/boot.d.ts +4 -0
- package/dist/guest/boot/boot.js +51 -11
- package/dist/guest/daemon/daemon.js +8 -1
- package/dist/guest/daemon/exec.js +2 -1
- package/dist/guest/daemon/idle-shutdown.js +2 -0
- package/dist/guest/daemon/sessions.d.ts +5 -0
- package/dist/guest/daemon/sessions.js +20 -3
- package/dist/guest/entries/agent.d.ts +1 -0
- package/dist/guest/entries/agent.js +10 -0
- package/dist/guest/entries/daemon.js +5 -0
- package/dist/guest/governor/decide.d.ts +61 -0
- package/dist/guest/governor/decide.js +182 -0
- package/dist/guest/governor/governor.d.ts +42 -0
- package/dist/guest/governor/governor.js +214 -0
- package/dist/guest/governor/index.d.ts +2 -0
- package/dist/guest/governor/index.js +2 -0
- package/dist/guest/runtime/csc.d.ts +2 -0
- package/dist/guest/runtime/csc.js +2 -0
- package/dist/guest/runtime/secrets.d.ts +12 -0
- package/dist/guest/runtime/secrets.js +63 -0
- package/dist/guest/sessions/viewer.js +3 -1
- package/dist/guest/setup/claude-profile.d.ts +2 -1
- package/dist/guest/setup/claude-profile.js +12 -1
- package/dist/guest/setup/environment.d.ts +6 -0
- package/dist/guest/setup/environment.js +56 -6
- package/dist/guest/setup/path-plan.d.ts +32 -0
- package/dist/guest/setup/path-plan.js +67 -0
- package/dist/guest/setup/shell-path.d.ts +1 -0
- package/dist/guest/setup/shell-path.js +22 -0
- package/dist/guest/toolchains/languages/python.js +1 -1
- package/dist/guest/toolchains/native/rust-extras.js +4 -2
- package/dist/guest/toolchains/runtimes.js +2 -2
- package/dist/guest/vpn/index.d.ts +1 -0
- package/dist/guest/vpn/index.js +1 -0
- package/dist/guest/vpn/openvpn.d.ts +9 -0
- package/dist/guest/vpn/openvpn.js +47 -0
- package/dist/guest/vpn/tunnel.d.ts +17 -0
- package/dist/guest/vpn/tunnel.js +78 -0
- package/dist/guest/vpn/vpn.d.ts +6 -0
- package/dist/guest/vpn/vpn.js +174 -0
- package/dist/guest/vpn/wireguard.d.ts +32 -0
- package/dist/guest/vpn/wireguard.js +132 -0
- package/dist/host/agent-commands/commands.d.ts +4 -0
- package/dist/host/agent-commands/commands.js +31 -7
- package/dist/host/audit/log.d.ts +1 -1
- package/dist/host/channel/attach.d.ts +6 -2
- package/dist/host/channel/attach.js +6 -3
- package/dist/host/channel/channel.d.ts +9 -0
- package/dist/host/channel/channel.js +30 -2
- package/dist/host/engines/engine.d.ts +12 -0
- package/dist/host/engines/engine.js +1 -0
- package/dist/host/engines/hcs/check.d.ts +25 -0
- package/dist/host/engines/hcs/check.js +95 -0
- package/dist/host/engines/hcs/documents.d.ts +44 -0
- package/dist/host/engines/hcs/documents.js +155 -0
- package/dist/host/engines/hcs/engine.d.ts +39 -0
- package/dist/host/engines/hcs/engine.js +171 -0
- package/dist/host/engines/hcs/helper.d.ts +43 -0
- package/dist/host/engines/hcs/helper.js +173 -0
- package/dist/host/engines/hcs/images.d.ts +37 -0
- package/dist/host/engines/hcs/images.js +152 -0
- package/dist/host/engines/index.d.ts +7 -0
- package/dist/host/engines/index.js +5 -0
- package/dist/host/engines/registry.d.ts +16 -0
- package/dist/host/engines/registry.js +30 -0
- package/dist/host/engines/types.d.ts +58 -0
- package/dist/host/engines/types.js +1 -0
- package/dist/host/engines/windows-sandbox/engine.d.ts +16 -0
- package/dist/host/engines/windows-sandbox/engine.js +63 -0
- package/dist/host/engines/windows-sandbox/wsb-text.d.ts +2 -0
- package/dist/host/engines/windows-sandbox/wsb-text.js +29 -0
- package/dist/host/health/acl-read.d.ts +17 -0
- package/dist/host/health/acl-read.js +45 -0
- package/dist/host/health/config-backup.d.ts +11 -0
- package/dist/host/health/config-backup.js +73 -0
- package/dist/host/health/index.d.ts +6 -0
- package/dist/host/health/index.js +7 -0
- package/dist/host/health/install-state.d.ts +33 -0
- package/dist/host/health/install-state.js +110 -0
- package/dist/host/health/path-copies.d.ts +32 -0
- package/dist/host/health/path-copies.js +82 -0
- package/dist/host/health/stale.d.ts +45 -0
- package/dist/host/health/stale.js +120 -0
- package/dist/host/health/system.d.ts +37 -0
- package/dist/host/health/system.js +87 -0
- package/dist/host/install/copies.d.ts +13 -0
- package/dist/host/install/copies.js +63 -0
- package/dist/host/install/index.d.ts +1 -0
- package/dist/host/install/index.js +1 -0
- package/dist/host/launch/generate.d.ts +5 -1
- package/dist/host/launch/generate.js +73 -7
- package/dist/host/launch/index.d.ts +3 -1
- package/dist/host/launch/index.js +3 -1
- package/dist/host/launch/launch-plan.d.ts +13 -0
- package/dist/host/launch/launch-plan.js +26 -0
- package/dist/host/launch/mappings.js +2 -1
- package/dist/host/launch/risk-notes.d.ts +10 -0
- package/dist/host/launch/risk-notes.js +18 -0
- package/dist/host/launch/session-file.d.ts +2 -0
- package/dist/host/launch/session-file.js +11 -2
- package/dist/host/launch/stage.js +1 -1
- package/dist/host/launch/wsb-file.d.ts +28 -4
- package/dist/host/launch/wsb-file.js +61 -42
- package/dist/host/life/crash-report.d.ts +27 -1
- package/dist/host/life/crash-report.js +173 -7
- package/dist/host/life/host-memory.d.ts +40 -0
- package/dist/host/life/host-memory.js +137 -0
- package/dist/host/life/index.d.ts +2 -0
- package/dist/host/life/index.js +2 -0
- package/dist/host/life/stop-events.d.ts +2 -0
- package/dist/host/life/stop-events.js +20 -3
- package/dist/host/life/stop-warning.js +1 -1
- package/dist/host/life/watchdog.d.ts +54 -0
- package/dist/host/life/watchdog.js +108 -0
- package/dist/host/migrate/backup.js +3 -0
- package/dist/host/migrate/migrations/config-file.d.ts +2 -0
- package/dist/host/migrate/migrations/config-file.js +7 -0
- package/dist/host/migrate/migrations/follow-machine-storage.js +9 -1
- package/dist/host/migrate/migrations/pin-storage-root.d.ts +4 -0
- package/dist/host/migrate/migrations/pin-storage-root.js +46 -0
- package/dist/host/migrate/migrations/unpin-config-defaults.js +4 -1
- package/dist/host/migrate/registry.js +2 -1
- package/dist/host/native.d.ts +3 -2
- package/dist/host/native.js +22 -3
- package/dist/host/profile/accounts.d.ts +25 -1
- package/dist/host/profile/accounts.js +96 -13
- package/dist/host/profile/agent-accounts.d.ts +5 -1
- package/dist/host/profile/agent-accounts.js +35 -5
- package/dist/host/profile/claude-login.js +3 -2
- package/dist/host/profile/index.d.ts +2 -1
- package/dist/host/profile/index.js +1 -0
- package/dist/host/profile/plugin-share.d.ts +26 -0
- package/dist/host/profile/plugin-share.js +146 -0
- package/dist/host/projects/join.d.ts +7 -1
- package/dist/host/projects/join.js +21 -4
- package/dist/host/projects/registry.d.ts +16 -10
- package/dist/host/projects/registry.js +74 -6
- package/dist/host/sandbox/contained-deps.d.ts +2 -0
- package/dist/host/sandbox/contained-deps.js +17 -0
- package/dist/host/sandbox/index.d.ts +2 -0
- package/dist/host/sandbox/index.js +2 -0
- package/dist/host/sandbox/platform.d.ts +4 -0
- package/dist/host/sandbox/platform.js +23 -4
- package/dist/host/sandbox/tasklist.d.ts +13 -0
- package/dist/host/sandbox/tasklist.js +47 -0
- package/dist/host/secrets/index.d.ts +2 -0
- package/dist/host/secrets/index.js +2 -0
- package/dist/host/secrets/launch-secrets.d.ts +17 -0
- package/dist/host/secrets/launch-secrets.js +94 -0
- package/dist/host/secrets/secret-store.d.ts +25 -0
- package/dist/host/secrets/secret-store.js +89 -0
- package/dist/host/sharing/acl.d.ts +16 -2
- package/dist/host/sharing/acl.js +35 -10
- package/dist/host/sharing/current.js +8 -3
- package/dist/host/sharing/doctor.d.ts +2 -0
- package/dist/host/sharing/doctor.js +44 -0
- package/dist/host/sharing/group-access.d.ts +6 -0
- package/dist/host/sharing/group-access.js +24 -0
- package/dist/host/sharing/index.d.ts +2 -1
- package/dist/host/sharing/index.js +2 -1
- package/dist/host/sharing/lifecycle.d.ts +8 -2
- package/dist/host/sharing/lifecycle.js +16 -7
- package/dist/host/storage/cleanup.d.ts +2 -0
- package/dist/host/storage/cleanup.js +2 -1
- package/dist/host/storage/contained/check.d.ts +9 -0
- package/dist/host/storage/contained/check.js +37 -0
- package/dist/host/storage/contained/contained-storage.d.ts +66 -0
- package/dist/host/storage/contained/contained-storage.js +168 -0
- package/dist/host/storage/contained/disk-port.d.ts +43 -0
- package/dist/host/storage/contained/disk-port.js +122 -0
- package/dist/host/storage/contained/index.d.ts +9 -0
- package/dist/host/storage/contained/index.js +8 -0
- package/dist/host/storage/contained/layout.d.ts +28 -0
- package/dist/host/storage/contained/layout.js +45 -0
- package/dist/host/storage/contained/resolve.d.ts +4 -0
- package/dist/host/storage/contained/resolve.js +30 -0
- package/dist/host/storage/contained/setting.d.ts +1 -0
- package/dist/host/storage/contained/setting.js +5 -0
- package/dist/host/storage/contained/state.d.ts +89 -0
- package/dist/host/storage/contained/state.js +166 -0
- package/dist/host/storage/contained/transfer.d.ts +24 -0
- package/dist/host/storage/contained/transfer.js +121 -0
- package/dist/host/storage/history.d.ts +21 -0
- package/dist/host/storage/history.js +49 -0
- package/dist/host/storage/index.d.ts +6 -0
- package/dist/host/storage/index.js +6 -0
- package/dist/host/storage/move.d.ts +95 -0
- package/dist/host/storage/move.js +384 -0
- package/dist/host/storage/offer.d.ts +11 -0
- package/dist/host/storage/offer.js +36 -0
- package/dist/host/storage/providers/contained.d.ts +15 -0
- package/dist/host/storage/providers/contained.js +39 -0
- package/dist/host/storage/providers/folder.d.ts +12 -0
- package/dist/host/storage/providers/folder.js +20 -0
- package/dist/host/storage/providers/index.d.ts +4 -0
- package/dist/host/storage/providers/index.js +3 -0
- package/dist/host/storage/providers/registry.d.ts +9 -0
- package/dist/host/storage/providers/registry.js +14 -0
- package/dist/host/storage/providers/types.d.ts +33 -0
- package/dist/host/storage/providers/types.js +1 -0
- package/dist/host/storage/root.d.ts +18 -0
- package/dist/host/storage/root.js +77 -0
- package/dist/host/tools/conpty.js +3 -2
- package/dist/host/tools/windows-terminal.d.ts +2 -0
- package/dist/host/tools/windows-terminal.js +31 -12
- package/dist/host/update/index.d.ts +1 -1
- package/dist/host/update/index.js +1 -1
- package/dist/host/update/notice.d.ts +2 -0
- package/dist/host/update/notice.js +13 -1
- package/dist/host/update/update-state.d.ts +6 -0
- package/dist/host/update/update-state.js +2 -0
- package/dist/host/update/updater.d.ts +19 -0
- package/dist/host/update/updater.js +88 -12
- package/dist/host/vpn/index.d.ts +4 -0
- package/dist/host/vpn/index.js +4 -0
- package/dist/host/vpn/login.d.ts +24 -0
- package/dist/host/vpn/login.js +79 -0
- package/dist/host/vpn/nordvpn.d.ts +21 -0
- package/dist/host/vpn/nordvpn.js +77 -0
- package/dist/host/vpn/prepare.d.ts +19 -0
- package/dist/host/vpn/prepare.js +138 -0
- package/dist/host/vpn/status.d.ts +12 -0
- package/dist/host/vpn/status.js +53 -0
- package/dist/host/web/auth.d.ts +38 -0
- package/dist/host/web/auth.js +96 -0
- package/dist/host/web/backend.d.ts +14 -0
- package/dist/host/web/backend.js +1 -0
- package/dist/host/web/bridge.d.ts +27 -0
- package/dist/host/web/bridge.js +144 -0
- package/dist/host/web/browser.d.ts +3 -0
- package/dist/host/web/browser.js +23 -0
- package/dist/host/web/control.d.ts +17 -0
- package/dist/host/web/control.js +67 -0
- package/dist/host/web/index.d.ts +10 -0
- package/dist/host/web/index.js +9 -0
- package/dist/host/web/rpc.d.ts +24 -0
- package/dist/host/web/rpc.js +149 -0
- package/dist/host/web/runner.d.ts +16 -0
- package/dist/host/web/runner.js +44 -0
- package/dist/host/web/server.d.ts +47 -0
- package/dist/host/web/server.js +238 -0
- package/dist/host/web/state.d.ts +20 -0
- package/dist/host/web/state.js +41 -0
- package/dist/host/web/static-files.d.ts +13 -0
- package/dist/host/web/static-files.js +57 -0
- package/dist/runtime/agent.js +27675 -0
- package/dist/runtime/daemon.js +1950 -1122
- package/dist/runtime/db.js +302 -111
- package/dist/runtime/main.js +1560 -275
- package/dist/runtime/netproxy.js +168 -8
- package/dist/runtime/view.js +186 -13
- package/dist/selftest/accounts.test.js +40 -0
- package/dist/selftest/agent-paths.test.d.ts +2 -0
- package/dist/selftest/agent-paths.test.js +125 -0
- package/dist/selftest/app.test.d.ts +2 -0
- package/dist/selftest/app.test.js +324 -0
- package/dist/selftest/channel.test.js +18 -0
- package/dist/selftest/cli.test.js +35 -4
- package/dist/selftest/config.test.js +59 -0
- package/dist/selftest/contained.test.d.ts +2 -0
- package/dist/selftest/contained.test.js +544 -0
- package/dist/selftest/credentials.test.d.ts +2 -0
- package/dist/selftest/credentials.test.js +198 -0
- package/dist/selftest/engine.test.d.ts +2 -0
- package/dist/selftest/engine.test.js +127 -0
- package/dist/selftest/generate.test.js +1 -1
- package/dist/selftest/hcs.test.d.ts +2 -0
- package/dist/selftest/hcs.test.js +482 -0
- package/dist/selftest/health.test.d.ts +2 -0
- package/dist/selftest/health.test.js +470 -0
- package/dist/selftest/heavy-load.test.d.ts +2 -0
- package/dist/selftest/heavy-load.test.js +329 -0
- package/dist/selftest/host-sim.test.js +2 -0
- package/dist/selftest/index.js +31 -0
- package/dist/selftest/layout.test.js +14 -0
- package/dist/selftest/menu-perf.test.d.ts +2 -0
- package/dist/selftest/menu-perf.test.js +248 -0
- package/dist/selftest/menu-screens.d.ts +7 -0
- package/dist/selftest/menu-screens.js +68 -17
- package/dist/selftest/menu.test.js +603 -22
- package/dist/selftest/migrate.test.js +1 -1
- package/dist/selftest/personalization.test.js +3 -1
- package/dist/selftest/projects.test.js +39 -1
- package/dist/selftest/shared-use.test.js +64 -2
- package/dist/selftest/sharing.test.js +50 -1
- package/dist/selftest/storage.test.d.ts +2 -0
- package/dist/selftest/storage.test.js +363 -0
- package/dist/selftest/support/engine-cases.d.ts +8 -0
- package/dist/selftest/support/engine-cases.js +65 -0
- package/dist/selftest/support/engine-golden.d.ts +3 -0
- package/dist/selftest/support/engine-golden.js +66 -0
- package/dist/selftest/support/fixtures.d.ts +20 -0
- package/dist/selftest/support/hcs-probes.d.ts +17 -0
- package/dist/selftest/support/hcs-probes.js +41 -0
- package/dist/selftest/support/releases.js +1 -1
- package/dist/selftest/toolchains.test.js +21 -0
- package/dist/selftest/update-service.test.js +87 -3
- package/dist/selftest/vpn.test.d.ts +2 -0
- package/dist/selftest/vpn.test.js +412 -0
- package/dist/selftest/web.test.d.ts +2 -0
- package/dist/selftest/web.test.js +402 -0
- package/dist/shared/apps/catalogue.js +31 -0
- package/dist/shared/channel/index.d.ts +1 -0
- package/dist/shared/channel/index.js +1 -0
- package/dist/shared/channel/run-dir.d.ts +9 -1
- package/dist/shared/channel/run-dir.js +18 -1
- package/dist/shared/channel/schema.d.ts +53 -0
- package/dist/shared/channel/schema.js +38 -0
- package/dist/shared/channel/secrets.d.ts +29 -0
- package/dist/shared/channel/secrets.js +50 -0
- package/dist/shared/memory/index.d.ts +1 -0
- package/dist/shared/memory/index.js +1 -0
- package/dist/shared/memory/policy.d.ts +33 -0
- package/dist/shared/memory/policy.js +55 -0
- package/dist/shared/pty/output-filter.d.ts +14 -1
- package/dist/shared/pty/output-filter.js +22 -4
- package/dist/shared/pty/terminal.d.ts +4 -1
- package/dist/shared/pty/terminal.js +4 -2
- package/dist/shared/system.d.ts +1 -0
- package/dist/shared/system.js +1 -0
- package/dist/shared/vpn/download.d.ts +29 -0
- package/dist/shared/vpn/download.js +30 -0
- package/dist/shared/vpn/kill-switch.d.ts +18 -0
- package/dist/shared/vpn/kill-switch.js +81 -0
- package/dist/shared/vpn/ovpn.d.ts +23 -0
- package/dist/shared/vpn/ovpn.js +244 -0
- package/dist/shared/vpn/wireguard.d.ts +51 -0
- package/dist/shared/vpn/wireguard.js +227 -0
- package/dist/shared/web/index.d.ts +1 -0
- package/dist/shared/web/index.js +1 -0
- package/dist/shared/web/protocol.d.ts +61 -0
- package/dist/shared/web/protocol.js +35 -0
- package/dist/sync/sync-cycle.js +9 -5
- package/dist/sync/sync-state.d.ts +1 -0
- package/dist/sync/sync-state.js +1 -0
- package/dist/sync/watcher.d.ts +13 -0
- package/dist/sync/watcher.js +102 -3
- package/dist/web/index.html +14 -0
- package/dist/web/main-NRRS5O6Z.js +157 -0
- package/dist/web/main-T5DMCHYV.css +1 -0
- package/native/csharp/FolderSecurity.cs +29 -0
- package/native/csharp/HcsHost/AssemblyInfo.cs +14 -0
- package/native/csharp/HcsHost/Guard.cs +100 -0
- package/native/csharp/HcsHost/Hcs.cs +256 -0
- package/native/csharp/HcsHost/Json.cs +78 -0
- package/native/csharp/HcsHost/Program.cs +185 -0
- package/native/csharp/HcsHost/VirtualDisk.cs +95 -0
- package/native/csharp/HostTools/AssemblyInfo.cs +14 -0
- package/native/csharp/HostTools/MemoryStatus.cs +107 -0
- package/native/csharp/HostTools/Program.cs +58 -17
- package/native/scripts/check-contained.ps1 +28 -0
- package/native/scripts/contained-common.ps1 +241 -0
- package/native/scripts/dismount-contained.ps1 +66 -0
- package/native/scripts/memory-status.ps1 +34 -0
- package/native/scripts/mount-contained.ps1 +139 -0
- package/native/scripts/protect-data.ps1 +29 -0
- package/native/scripts/read-folder-sddl.ps1 +10 -0
- package/native/scripts/run-elevated.ps1 +17 -4
- package/native/scripts/set-folder-access.ps1 +49 -7
- package/native/scripts/stop-events.ps1 +23 -8
- package/node_modules/ws/LICENSE +20 -0
- package/node_modules/ws/README.md +548 -0
- package/node_modules/ws/browser.js +8 -0
- package/node_modules/ws/index.js +22 -0
- package/node_modules/ws/lib/buffer-util.js +131 -0
- package/node_modules/ws/lib/constants.js +19 -0
- package/node_modules/ws/lib/event-target.js +292 -0
- package/node_modules/ws/lib/extension.js +203 -0
- package/node_modules/ws/lib/limiter.js +55 -0
- package/node_modules/ws/lib/permessage-deflate.js +530 -0
- package/node_modules/ws/lib/receiver.js +743 -0
- package/node_modules/ws/lib/sender.js +607 -0
- package/node_modules/ws/lib/stream.js +161 -0
- package/node_modules/ws/lib/subprotocol.js +62 -0
- package/node_modules/ws/lib/validation.js +152 -0
- package/node_modules/ws/lib/websocket-server.js +562 -0
- package/node_modules/ws/lib/websocket.js +1421 -0
- package/node_modules/ws/package.json +74 -0
- package/node_modules/ws/wrapper.mjs +21 -0
- package/package.json +22 -5
- package/sandbox/csharp/EnvBroadcast.cs +33 -0
- package/sandbox/csharp/MemGov.cs +398 -0
- package/sandbox/csharp/PathSync.cs +90 -0
- package/sandbox/csharp/PtyHost.cs +111 -5
- package/sandbox/scripts/install-shell-path.ps1 +73 -0
- package/sandbox/scripts/set-machine-environment.ps1 +37 -4
- package/schemas/config.schema.json +136 -7
- package/schemas/sandbox-config.schema.json +17 -4
- package/dist/cli/commands/repair/checks.d.ts +0 -2
- package/dist/cli/commands/repair/checks.js +0 -246
- package/dist/cli/commands/sessions/control.d.ts +0 -4
- package/dist/cli/commands/sessions/control.js +0 -66
- package/dist/cli/commands/sessions/list.d.ts +0 -2
- package/dist/cli/commands/sessions/list.js +0 -45
- package/dist/cli/commands/sessions/status.d.ts +0 -2
- package/dist/cli/commands/sessions/status.js +0 -93
- package/dist/cli/commands/sessions/window.d.ts +0 -3
- package/dist/cli/commands/sessions/window.js +0 -18
- package/dist/cli/menu/pages/start-page.d.ts +0 -43
- package/dist/cli/menu/pages/start-page.js +0 -192
- package/dist/cli/tui/tab-bar.d.ts +0 -9
- package/dist/cli/tui/tab-bar.js +0 -33
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { safeText } from '../../core/util/index.js';
|
|
2
|
+
import { connect, encodeFrame, FrameReader, FrameType, helloFrame, OutputFilter, PING_INTERVAL_MS, resizeFrame, } from '../../shared/pty/index.js';
|
|
3
|
+
import { parseClientMessage } from '../../shared/web/index.js';
|
|
4
|
+
/** The browser is slower than the sandbox: past this much waiting to be sent, output is held back in the socket. */
|
|
5
|
+
const MAX_BUFFERED_BYTES = 4 * 1024 * 1024;
|
|
6
|
+
const DRAIN_CHECK_MS = 50;
|
|
7
|
+
/** A browser that cannot keep up for this long is closed. */
|
|
8
|
+
const MAX_STALLED_MS = 60 * 1000;
|
|
9
|
+
export class TerminalBridge {
|
|
10
|
+
ws;
|
|
11
|
+
endpoint;
|
|
12
|
+
cols;
|
|
13
|
+
rows;
|
|
14
|
+
dial;
|
|
15
|
+
socket = null;
|
|
16
|
+
pinger = null;
|
|
17
|
+
drain = null;
|
|
18
|
+
stalledSince = 0;
|
|
19
|
+
done = false;
|
|
20
|
+
filter = new OutputFilter();
|
|
21
|
+
reader = new FrameReader();
|
|
22
|
+
constructor(ws, endpoint, cols, rows, dial = connect) {
|
|
23
|
+
this.ws = ws;
|
|
24
|
+
this.endpoint = endpoint;
|
|
25
|
+
this.cols = cols;
|
|
26
|
+
this.rows = rows;
|
|
27
|
+
this.dial = dial;
|
|
28
|
+
}
|
|
29
|
+
/** Connects to the session and starts passing data both ways. */
|
|
30
|
+
async start() {
|
|
31
|
+
this.ws.on('message', (data, isBinary) => this.fromBrowser(data, isBinary));
|
|
32
|
+
this.ws.on('close', () => this.finish());
|
|
33
|
+
this.ws.on('error', () => this.finish());
|
|
34
|
+
let socket;
|
|
35
|
+
try {
|
|
36
|
+
socket = await this.dial(this.endpoint);
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
this.tell({ t: 'error', message: 'Could not reach the session in the sandbox.' });
|
|
40
|
+
this.finish(1011, 'unreachable');
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
if (this.done) {
|
|
44
|
+
socket.destroy();
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
this.socket = socket;
|
|
48
|
+
socket.on('data', (chunk) => this.fromSession(chunk));
|
|
49
|
+
socket.on('error', () => this.finish(1011, 'session connection failed'));
|
|
50
|
+
socket.on('close', () => this.finish(1011, 'session connection closed'));
|
|
51
|
+
socket.write(helloFrame(this.endpoint.token, this.cols, this.rows));
|
|
52
|
+
// The session drops a viewer it has not heard from in 15 s.
|
|
53
|
+
this.pinger = setInterval(() => this.socket?.write(encodeFrame(FrameType.Ping)), PING_INTERVAL_MS);
|
|
54
|
+
this.tell({ t: 'ready' });
|
|
55
|
+
}
|
|
56
|
+
fromBrowser(data, isBinary) {
|
|
57
|
+
if (!this.socket || this.done)
|
|
58
|
+
return;
|
|
59
|
+
const bytes = Array.isArray(data) ? Buffer.concat(data) : Buffer.from(data);
|
|
60
|
+
if (isBinary) {
|
|
61
|
+
if (bytes.length)
|
|
62
|
+
this.socket.write(encodeFrame(FrameType.Input, bytes));
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
const message = parseClientMessage(bytes.toString('utf8'));
|
|
66
|
+
if (!message) {
|
|
67
|
+
this.finish(1008, 'bad message');
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
this.socket.write(resizeFrame(message.cols, message.rows));
|
|
71
|
+
}
|
|
72
|
+
fromSession(chunk) {
|
|
73
|
+
let frames;
|
|
74
|
+
try {
|
|
75
|
+
frames = this.reader.push(chunk);
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
this.tell({ t: 'error', message: 'The session sent data that could not be read.' });
|
|
79
|
+
this.finish(1011, 'bad frame');
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
for (const frame of frames) {
|
|
83
|
+
if (this.done)
|
|
84
|
+
return;
|
|
85
|
+
switch (frame.type) {
|
|
86
|
+
case FrameType.Output: {
|
|
87
|
+
const clean = this.filter.push(frame.payload);
|
|
88
|
+
if (clean.length)
|
|
89
|
+
this.ws.send(clean, { binary: true });
|
|
90
|
+
break;
|
|
91
|
+
}
|
|
92
|
+
case FrameType.Restarting:
|
|
93
|
+
this.tell({ t: 'restarting' });
|
|
94
|
+
break;
|
|
95
|
+
case FrameType.Exit:
|
|
96
|
+
this.tell({ t: 'exit', code: frame.payload.length >= 4 ? frame.payload.readInt32LE(0) : 1 });
|
|
97
|
+
this.finish(1000, 'exit');
|
|
98
|
+
return;
|
|
99
|
+
case FrameType.Error:
|
|
100
|
+
this.tell({ t: 'error', message: safeText(frame.payload.toString('utf8').slice(0, 500)) });
|
|
101
|
+
this.finish(1000, 'error');
|
|
102
|
+
return;
|
|
103
|
+
default:
|
|
104
|
+
break; // status and console frames are for terminals that draw the screen themselves
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
if (this.ws.bufferedAmount > MAX_BUFFERED_BYTES)
|
|
108
|
+
this.hold();
|
|
109
|
+
}
|
|
110
|
+
/** Stops reading from the session until the browser has taken what it was sent. */
|
|
111
|
+
hold() {
|
|
112
|
+
if (this.drain || !this.socket)
|
|
113
|
+
return;
|
|
114
|
+
this.socket.pause();
|
|
115
|
+
this.stalledSince = Date.now();
|
|
116
|
+
this.drain = setInterval(() => {
|
|
117
|
+
if (this.ws.bufferedAmount <= MAX_BUFFERED_BYTES / 4) {
|
|
118
|
+
if (this.drain)
|
|
119
|
+
clearInterval(this.drain);
|
|
120
|
+
this.drain = null;
|
|
121
|
+
this.socket?.resume();
|
|
122
|
+
}
|
|
123
|
+
else if (Date.now() - this.stalledSince > MAX_STALLED_MS)
|
|
124
|
+
this.finish(1013, 'too slow');
|
|
125
|
+
}, DRAIN_CHECK_MS);
|
|
126
|
+
}
|
|
127
|
+
tell(message) {
|
|
128
|
+
if (this.ws.readyState === this.ws.OPEN)
|
|
129
|
+
this.ws.send(JSON.stringify(message));
|
|
130
|
+
}
|
|
131
|
+
/** Closes both sides (once). */
|
|
132
|
+
finish(code = 1000, reason = '') {
|
|
133
|
+
if (this.done)
|
|
134
|
+
return;
|
|
135
|
+
this.done = true;
|
|
136
|
+
if (this.pinger)
|
|
137
|
+
clearInterval(this.pinger);
|
|
138
|
+
if (this.drain)
|
|
139
|
+
clearInterval(this.drain);
|
|
140
|
+
this.socket?.destroy();
|
|
141
|
+
if (this.ws.readyState === this.ws.OPEN || this.ws.readyState === this.ws.CONNECTING)
|
|
142
|
+
this.ws.close(code, reason);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// Opens an address in the default browser (through cmd's start; the address is one we built, hex and digits only).
|
|
2
|
+
import { spawn } from 'node:child_process';
|
|
3
|
+
import { SYSTEM, system32 } from '../../shared/system.js';
|
|
4
|
+
import { refuseInSelfTest } from '../test-guard.js';
|
|
5
|
+
export function openBrowser(url) {
|
|
6
|
+
refuseInSelfTest('open a browser');
|
|
7
|
+
if (!/^http:\/\/127\.0\.0\.1:\d{1,5}\/(#k=[0-9a-f]{64})?$/.test(url))
|
|
8
|
+
throw new Error('Not a web UI address.');
|
|
9
|
+
spawn(SYSTEM.cmd(), ['/c', 'start', '', url], { detached: true, stdio: 'ignore', windowsHide: true }).unref();
|
|
10
|
+
}
|
|
11
|
+
/** The one other page we open: a GitHub new-issue form (letters, digits and URL escapes only). */
|
|
12
|
+
const ISSUE_URL = /^https:\/\/github\.com\/[\w.-]+\/[\w.-]+\/issues\/new\?[\w%.~&=+-]*$/;
|
|
13
|
+
/** Opens a GitHub new-issue address in the default browser (rundll32, so no shell reads the & in it). */
|
|
14
|
+
export function openIssuePage(url) {
|
|
15
|
+
refuseInSelfTest('open a browser');
|
|
16
|
+
if (!ISSUE_URL.test(url) || url.length > 2000)
|
|
17
|
+
throw new Error('Not a GitHub new-issue address.');
|
|
18
|
+
spawn(system32('rundll32.exe'), ['url.dll,FileProtocolHandler', url], {
|
|
19
|
+
detached: true,
|
|
20
|
+
stdio: 'ignore',
|
|
21
|
+
windowsHide: true,
|
|
22
|
+
}).unref();
|
|
23
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { WebStore, WebState } from './state.js';
|
|
2
|
+
export interface WebStatus {
|
|
3
|
+
readonly running: boolean;
|
|
4
|
+
readonly state: WebState | null;
|
|
5
|
+
}
|
|
6
|
+
export declare class WebControl {
|
|
7
|
+
private readonly store;
|
|
8
|
+
constructor(store: WebStore);
|
|
9
|
+
/** Running means the state file exists and its port answers as our server. */
|
|
10
|
+
status(): Promise<WebStatus>;
|
|
11
|
+
/** http://127.0.0.1:<port>/#k=<token>: the fragment never goes to the server. */
|
|
12
|
+
url(state: WebState): string;
|
|
13
|
+
/** Signs in with the token and asks the server to stop. False when it does not answer. */
|
|
14
|
+
stop(state: WebState): Promise<boolean>;
|
|
15
|
+
/** The state file of a server that is gone. */
|
|
16
|
+
clear(): void;
|
|
17
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
// Talking to a running web server from the CLI: is it up, its address (with the token fragment), and stopping it. The
|
|
2
|
+
// state file says where it is and holds the token, so only you (and SYSTEM / Administrators) can do any of this.
|
|
3
|
+
import http from 'node:http';
|
|
4
|
+
import { CSRF_HEADER, CSRF_VALUE } from '../../shared/web/index.js';
|
|
5
|
+
function request(state, method, path, body, cookie) {
|
|
6
|
+
return new Promise((resolve, reject) => {
|
|
7
|
+
const payload = body === undefined ? undefined : JSON.stringify(body);
|
|
8
|
+
const req = http.request({
|
|
9
|
+
host: '127.0.0.1',
|
|
10
|
+
port: state.port,
|
|
11
|
+
method,
|
|
12
|
+
path,
|
|
13
|
+
timeout: 3000,
|
|
14
|
+
headers: {
|
|
15
|
+
Origin: 'http://127.0.0.1:' + state.port,
|
|
16
|
+
[CSRF_HEADER]: CSRF_VALUE,
|
|
17
|
+
...(payload ? { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(payload) } : {}),
|
|
18
|
+
...(cookie ? { Cookie: cookie } : {}),
|
|
19
|
+
},
|
|
20
|
+
}, (res) => {
|
|
21
|
+
res.resume();
|
|
22
|
+
resolve(res);
|
|
23
|
+
});
|
|
24
|
+
req.on('timeout', () => req.destroy(new Error('timed out')));
|
|
25
|
+
req.on('error', reject);
|
|
26
|
+
req.end(payload);
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
export class WebControl {
|
|
30
|
+
store;
|
|
31
|
+
constructor(store) {
|
|
32
|
+
this.store = store;
|
|
33
|
+
}
|
|
34
|
+
/** Running means the state file exists and its port answers as our server. */
|
|
35
|
+
async status() {
|
|
36
|
+
const state = this.store.read();
|
|
37
|
+
if (!state)
|
|
38
|
+
return { running: false, state: null };
|
|
39
|
+
try {
|
|
40
|
+
return { running: (await request(state, 'GET', '/api/health')).statusCode === 200, state };
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
return { running: false, state };
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/** http://127.0.0.1:<port>/#k=<token>: the fragment never goes to the server. */
|
|
47
|
+
url(state) {
|
|
48
|
+
return 'http://127.0.0.1:' + state.port + '/#k=' + state.token;
|
|
49
|
+
}
|
|
50
|
+
/** Signs in with the token and asks the server to stop. False when it does not answer. */
|
|
51
|
+
async stop(state) {
|
|
52
|
+
try {
|
|
53
|
+
const login = await request(state, 'POST', '/api/login', { token: state.token });
|
|
54
|
+
const cookie = (login.headers['set-cookie'] ?? [])[0]?.split(';')[0];
|
|
55
|
+
if (login.statusCode !== 200 || !cookie)
|
|
56
|
+
return false;
|
|
57
|
+
return (await request(state, 'POST', '/api/stop', {}, cookie)).statusCode === 200;
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/** The state file of a server that is gone. */
|
|
64
|
+
clear() {
|
|
65
|
+
this.store.clear();
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export { WebAuth, newToken, sameSecret, hostAllowed, originAllowed, csrfOk, cookieValue, cookieHeader, } from './auth.js';
|
|
2
|
+
export type { WebBackend } from './backend.js';
|
|
3
|
+
export { openBrowser, openIssuePage } from './browser.js';
|
|
4
|
+
export { TerminalBridge } from './bridge.js';
|
|
5
|
+
export { WebControl, type WebStatus } from './control.js';
|
|
6
|
+
export { WebRunner } from './runner.js';
|
|
7
|
+
export { RpcSession } from './rpc.js';
|
|
8
|
+
export { WebServer, CONTENT_SECURITY_POLICY, RPC_PATH, type WebServerOptions } from './server.js';
|
|
9
|
+
export { StaticFiles } from './static-files.js';
|
|
10
|
+
export { WebStore, WebStateSchema, type WebState } from './state.js';
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { WebAuth, newToken, sameSecret, hostAllowed, originAllowed, csrfOk, cookieValue, cookieHeader, } from './auth.js';
|
|
2
|
+
export { openBrowser, openIssuePage } from './browser.js';
|
|
3
|
+
export { TerminalBridge } from './bridge.js';
|
|
4
|
+
export { WebControl } from './control.js';
|
|
5
|
+
export { WebRunner } from './runner.js';
|
|
6
|
+
export { RpcSession } from './rpc.js';
|
|
7
|
+
export { WebServer, CONTENT_SECURITY_POLICY, RPC_PATH } from './server.js';
|
|
8
|
+
export { StaticFiles } from './static-files.js';
|
|
9
|
+
export { WebStore, WebStateSchema } from './state.js';
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { WebSocket } from 'ws';
|
|
2
|
+
import { type RpcHost } from '../../app/kernel/index.js';
|
|
3
|
+
export declare class RpcSession {
|
|
4
|
+
private readonly ws;
|
|
5
|
+
private readonly host;
|
|
6
|
+
private readonly calls;
|
|
7
|
+
private readonly subscriptions;
|
|
8
|
+
private closed;
|
|
9
|
+
constructor(ws: WebSocket, host: RpcHost);
|
|
10
|
+
start(): void;
|
|
11
|
+
private send;
|
|
12
|
+
/** A browser that sends something that is not one of our messages is closed. */
|
|
13
|
+
private refuse;
|
|
14
|
+
private receive;
|
|
15
|
+
private handle;
|
|
16
|
+
/** The id is free and the socket has room for one more call or subscription. */
|
|
17
|
+
private admit;
|
|
18
|
+
private call;
|
|
19
|
+
private answer;
|
|
20
|
+
private subscribe;
|
|
21
|
+
private unsubscribe;
|
|
22
|
+
/** The browser went away: subscriptions stop, and questions still open are answered no. */
|
|
23
|
+
private close;
|
|
24
|
+
}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { ANSWER_SCHEMAS, ClientMessageSchema, MAX_OPEN_PER_SOCKET, NO_QUESTIONS, ioFromAsker, toWireError, } from '../../app/kernel/index.js';
|
|
2
|
+
/** What a question gets when the browser goes away before answering: no. */
|
|
3
|
+
function declined(q) {
|
|
4
|
+
return q.kind === 'confirm' ? false : undefined;
|
|
5
|
+
}
|
|
6
|
+
export class RpcSession {
|
|
7
|
+
ws;
|
|
8
|
+
host;
|
|
9
|
+
calls = new Map();
|
|
10
|
+
subscriptions = new Map();
|
|
11
|
+
closed = false;
|
|
12
|
+
constructor(ws, host) {
|
|
13
|
+
this.ws = ws;
|
|
14
|
+
this.host = host;
|
|
15
|
+
}
|
|
16
|
+
start() {
|
|
17
|
+
this.ws.on('message', (data, binary) => this.receive(data, binary));
|
|
18
|
+
this.ws.on('close', () => this.close());
|
|
19
|
+
this.ws.on('error', () => this.close());
|
|
20
|
+
}
|
|
21
|
+
send(message) {
|
|
22
|
+
if (!this.closed && this.ws.readyState === this.ws.OPEN)
|
|
23
|
+
this.ws.send(JSON.stringify(message));
|
|
24
|
+
}
|
|
25
|
+
/** A browser that sends something that is not one of our messages is closed. */
|
|
26
|
+
refuse() {
|
|
27
|
+
this.ws.close(1008, 'bad message');
|
|
28
|
+
this.close();
|
|
29
|
+
}
|
|
30
|
+
receive(data, binary) {
|
|
31
|
+
if (binary)
|
|
32
|
+
return this.refuse();
|
|
33
|
+
let value;
|
|
34
|
+
try {
|
|
35
|
+
value = JSON.parse(data.toString());
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
return this.refuse();
|
|
39
|
+
}
|
|
40
|
+
const parsed = ClientMessageSchema.safeParse(value);
|
|
41
|
+
if (!parsed.success)
|
|
42
|
+
return this.refuse();
|
|
43
|
+
this.handle(parsed.data);
|
|
44
|
+
}
|
|
45
|
+
handle(m) {
|
|
46
|
+
switch (m.t) {
|
|
47
|
+
case 'call':
|
|
48
|
+
return this.call(m.id, m.op, m.input);
|
|
49
|
+
case 'answer':
|
|
50
|
+
return this.answer(m.id, m.value);
|
|
51
|
+
case 'subscribe':
|
|
52
|
+
return this.subscribe(m.id, m.query, m.input);
|
|
53
|
+
case 'unsubscribe':
|
|
54
|
+
return this.unsubscribe(m.id);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/** The id is free and the socket has room for one more call or subscription. */
|
|
58
|
+
admit(id) {
|
|
59
|
+
if (this.calls.has(id) || this.subscriptions.has(id)) {
|
|
60
|
+
this.send({ t: 'error', id, error: { kind: 'invalid', message: 'That id is in use.' } });
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
if (this.calls.size + this.subscriptions.size >= MAX_OPEN_PER_SOCKET) {
|
|
64
|
+
this.send({ t: 'error', id, error: { kind: 'invalid', message: 'Too many at once.' } });
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
call(id, op, input) {
|
|
70
|
+
if (!this.admit(id))
|
|
71
|
+
return;
|
|
72
|
+
if (!this.host.kind(op)) {
|
|
73
|
+
this.send({ t: 'error', id, error: { kind: 'invalid', message: 'There is no ' + op + ' here.' } });
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
this.calls.set(id, null);
|
|
77
|
+
const io = ioFromAsker((question) => new Promise((resolve) => {
|
|
78
|
+
if (this.closed)
|
|
79
|
+
return resolve(declined(question));
|
|
80
|
+
this.calls.set(id, { question, resolve: resolve });
|
|
81
|
+
this.send({ t: 'ask', id, question });
|
|
82
|
+
}), {
|
|
83
|
+
progress: (text) => this.send({ t: 'progress', id, text }),
|
|
84
|
+
log: (text, tone) => this.send({ t: 'log', id, text, ...(tone ? { tone } : {}) }),
|
|
85
|
+
});
|
|
86
|
+
this.host
|
|
87
|
+
.run(op, input, io)
|
|
88
|
+
.then((output) => this.send({ t: 'result', id, output }), (e) => this.send({ t: 'error', id, error: toWireError(e) }))
|
|
89
|
+
.finally(() => this.calls.delete(id));
|
|
90
|
+
}
|
|
91
|
+
answer(id, value) {
|
|
92
|
+
const waiting = this.calls.get(id);
|
|
93
|
+
if (!waiting)
|
|
94
|
+
return;
|
|
95
|
+
const parsed = ANSWER_SCHEMAS[waiting.question.kind].safeParse(value);
|
|
96
|
+
this.calls.set(id, null);
|
|
97
|
+
waiting.resolve(parsed.success ? parsed.data : declined(waiting.question));
|
|
98
|
+
}
|
|
99
|
+
subscribe(id, query, input) {
|
|
100
|
+
if (!this.admit(id))
|
|
101
|
+
return;
|
|
102
|
+
if (this.host.kind(query) !== 'query') {
|
|
103
|
+
this.send({ t: 'error', id, error: { kind: 'invalid', message: 'There is no ' + query + ' here.' } });
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
const sub = { timer: undefined, last: undefined, busy: false };
|
|
107
|
+
this.subscriptions.set(id, sub);
|
|
108
|
+
const read = async () => {
|
|
109
|
+
if (sub.busy)
|
|
110
|
+
return;
|
|
111
|
+
sub.busy = true;
|
|
112
|
+
try {
|
|
113
|
+
const output = await this.host.run(query, input, NO_QUESTIONS);
|
|
114
|
+
const text = JSON.stringify(output);
|
|
115
|
+
if (text !== sub.last && this.subscriptions.get(id) === sub) {
|
|
116
|
+
sub.last = text;
|
|
117
|
+
this.send({ t: 'data', id, output });
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
catch (e) {
|
|
121
|
+
sub.last = undefined;
|
|
122
|
+
this.send({ t: 'error', id, error: toWireError(e) });
|
|
123
|
+
}
|
|
124
|
+
finally {
|
|
125
|
+
sub.busy = false;
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
void read();
|
|
129
|
+
const every = this.host.liveMs(query);
|
|
130
|
+
if (every)
|
|
131
|
+
sub.timer = setInterval(() => void read(), every);
|
|
132
|
+
}
|
|
133
|
+
unsubscribe(id) {
|
|
134
|
+
const sub = this.subscriptions.get(id);
|
|
135
|
+
if (sub?.timer)
|
|
136
|
+
clearInterval(sub.timer);
|
|
137
|
+
this.subscriptions.delete(id);
|
|
138
|
+
}
|
|
139
|
+
/** The browser went away: subscriptions stop, and questions still open are answered no. */
|
|
140
|
+
close() {
|
|
141
|
+
if (this.closed)
|
|
142
|
+
return;
|
|
143
|
+
this.closed = true;
|
|
144
|
+
for (const id of [...this.subscriptions.keys()])
|
|
145
|
+
this.unsubscribe(id);
|
|
146
|
+
for (const waiting of this.calls.values())
|
|
147
|
+
waiting?.resolve(declined(waiting.question));
|
|
148
|
+
}
|
|
149
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { RpcHost } from '../../app/kernel/index.js';
|
|
2
|
+
import type { WebBackend } from './backend.js';
|
|
3
|
+
export interface WebRunOptions {
|
|
4
|
+
readonly storageRoot: string;
|
|
5
|
+
readonly port: number;
|
|
6
|
+
readonly backend: WebBackend;
|
|
7
|
+
readonly rpc?: RpcHost;
|
|
8
|
+
readonly staticRoot: string;
|
|
9
|
+
}
|
|
10
|
+
export declare class WebRunner {
|
|
11
|
+
private readonly options;
|
|
12
|
+
private readonly store;
|
|
13
|
+
constructor(options: WebRunOptions);
|
|
14
|
+
/** Runs until stopped (from the browser, the CLI, or a signal). */
|
|
15
|
+
run(): Promise<void>;
|
|
16
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { fail } from '../../core/util/index.js';
|
|
2
|
+
import { newToken } from './auth.js';
|
|
3
|
+
import { WebServer } from './server.js';
|
|
4
|
+
import { WebStore } from './state.js';
|
|
5
|
+
export class WebRunner {
|
|
6
|
+
options;
|
|
7
|
+
store;
|
|
8
|
+
constructor(options) {
|
|
9
|
+
this.options = options;
|
|
10
|
+
this.store = new WebStore(options.storageRoot);
|
|
11
|
+
}
|
|
12
|
+
/** Runs until stopped (from the browser, the CLI, or a signal). */
|
|
13
|
+
async run() {
|
|
14
|
+
const token = newToken();
|
|
15
|
+
let stop = () => undefined;
|
|
16
|
+
const stopped = new Promise((resolve) => (stop = resolve));
|
|
17
|
+
const server = new WebServer({
|
|
18
|
+
port: this.options.port,
|
|
19
|
+
token,
|
|
20
|
+
backend: this.options.backend,
|
|
21
|
+
rpc: this.options.rpc,
|
|
22
|
+
staticRoot: this.options.staticRoot,
|
|
23
|
+
onStop: stop,
|
|
24
|
+
});
|
|
25
|
+
try {
|
|
26
|
+
await server.start();
|
|
27
|
+
}
|
|
28
|
+
catch (e) {
|
|
29
|
+
if (e.code === 'EADDRINUSE')
|
|
30
|
+
fail('Port ' + this.options.port + ' is taken by another program.', 'Pick another with the web.port setting, then run sandbox web start again.');
|
|
31
|
+
throw e;
|
|
32
|
+
}
|
|
33
|
+
this.store.write({ pid: process.pid, port: server.port, token, startedAt: new Date().toISOString() });
|
|
34
|
+
process.once('SIGINT', stop);
|
|
35
|
+
process.once('SIGTERM', stop);
|
|
36
|
+
try {
|
|
37
|
+
await stopped;
|
|
38
|
+
}
|
|
39
|
+
finally {
|
|
40
|
+
this.store.clear();
|
|
41
|
+
await server.stop();
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type net from 'node:net';
|
|
2
|
+
import type { RpcHost } from '../../app/kernel/index.js';
|
|
3
|
+
import type { Endpoint } from '../../shared/pty/index.js';
|
|
4
|
+
import type { WebBackend } from './backend.js';
|
|
5
|
+
/** No inline script: the page and its script are files from this server. Inline styles are what xterm.js needs. */
|
|
6
|
+
export declare const CONTENT_SECURITY_POLICY: string;
|
|
7
|
+
export declare const RPC_PATH = "/api/rpc";
|
|
8
|
+
export interface WebServerOptions {
|
|
9
|
+
/** 0 picks a free port (tests). */
|
|
10
|
+
readonly port: number;
|
|
11
|
+
readonly token: string;
|
|
12
|
+
readonly backend: WebBackend;
|
|
13
|
+
/** The folder of the built app (dist/web). */
|
|
14
|
+
readonly staticRoot: string;
|
|
15
|
+
/** Called when a signed-in browser (or the CLI) asks the server to stop. */
|
|
16
|
+
readonly onStop?: () => void;
|
|
17
|
+
/** How terminals reach a session (tests use a fake on loopback). */
|
|
18
|
+
readonly dial?: (endpoint: Endpoint) => Promise<net.Socket>;
|
|
19
|
+
/** The shared core's operations and queries the browser may run (none: /api/rpc is not served). */
|
|
20
|
+
readonly rpc?: RpcHost;
|
|
21
|
+
}
|
|
22
|
+
export declare class WebServer {
|
|
23
|
+
private readonly options;
|
|
24
|
+
private readonly server;
|
|
25
|
+
private readonly sockets;
|
|
26
|
+
private readonly auth;
|
|
27
|
+
private readonly files;
|
|
28
|
+
private terminals;
|
|
29
|
+
private rpcSockets;
|
|
30
|
+
private actualPort;
|
|
31
|
+
constructor(options: WebServerOptions);
|
|
32
|
+
get port(): number;
|
|
33
|
+
start(): Promise<void>;
|
|
34
|
+
stop(): Promise<void>;
|
|
35
|
+
private headers;
|
|
36
|
+
private json;
|
|
37
|
+
private handle;
|
|
38
|
+
private serveFile;
|
|
39
|
+
/** A call that changes something: the custom header, and an Origin that is this page. */
|
|
40
|
+
private requireSameSite;
|
|
41
|
+
private api;
|
|
42
|
+
/** A small JSON body (application/json only). */
|
|
43
|
+
private body;
|
|
44
|
+
private upgrade;
|
|
45
|
+
/** The RPC socket (after the same Origin and cookie checks as a terminal). */
|
|
46
|
+
private upgradeRpc;
|
|
47
|
+
}
|