aws-runtime-bridge 1.9.78 → 1.9.80
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/dist/adapter/AcodeSdkAdapter.d.ts +0 -1
- package/dist/adapter/AcodeSdkAdapter.js +11 -1986
- package/dist/adapter/AdapterRegistry.d.ts +0 -1
- package/dist/adapter/AdapterRegistry.js +2 -100
- package/dist/adapter/ClaudeSdkAdapter.d.ts +0 -1
- package/dist/adapter/ClaudeSdkAdapter.js +4 -1300
- package/dist/adapter/CodexSdkAdapter.d.ts +0 -1
- package/dist/adapter/CodexSdkAdapter.js +4 -836
- package/dist/adapter/OpencodeSdkAdapter.d.ts +0 -1
- package/dist/adapter/OpencodeSdkAdapter.js +4 -879
- package/dist/adapter/SdkProviderSpi.d.ts +0 -1
- package/dist/adapter/SdkProviderSpi.js +2 -55
- package/dist/adapter/acode-tool-names.d.ts +0 -1
- package/dist/adapter/acode-tool-names.js +2 -37
- package/dist/adapter/idle-poll-loop.d.ts +0 -1
- package/dist/adapter/idle-poll-loop.js +2 -59
- package/dist/adapter/index.d.ts +0 -1
- package/dist/adapter/index.js +2 -11
- package/dist/adapter/instance-ai-config-resolver.d.ts +0 -1
- package/dist/adapter/instance-ai-config-resolver.js +2 -46
- package/dist/adapter/types.d.ts +0 -1
- package/dist/adapter/types.js +2 -443
- package/dist/adapters/cc-switch/common.d.ts +0 -1
- package/dist/adapters/cc-switch/common.js +2 -61
- package/dist/adapters/cc-switch/index.d.ts +0 -1
- package/dist/adapters/cc-switch/index.js +2 -57
- package/dist/adapters/cc-switch/mcp-acode.d.ts +0 -1
- package/dist/adapters/cc-switch/mcp-acode.js +2 -71
- package/dist/adapters/cc-switch/mcp-claude.d.ts +0 -1
- package/dist/adapters/cc-switch/mcp-claude.js +2 -89
- package/dist/adapters/cc-switch/mcp-claudecode.d.ts +0 -1
- package/dist/adapters/cc-switch/mcp-claudecode.js +2 -77
- package/dist/adapters/cc-switch/mcp-codex.d.ts +0 -1
- package/dist/adapters/cc-switch/mcp-codex.js +11 -249
- package/dist/adapters/cc-switch/mcp-opencode.d.ts +0 -1
- package/dist/adapters/cc-switch/mcp-opencode.js +2 -97
- package/dist/adapters/cc-switch/mcp-placeholder.d.ts +0 -1
- package/dist/adapters/cc-switch/mcp-placeholder.js +2 -19
- package/dist/adapters/cc-switch/skill-acode.d.ts +0 -1
- package/dist/adapters/cc-switch/skill-acode.js +2 -12
- package/dist/adapters/cc-switch/skill-claude.d.ts +0 -1
- package/dist/adapters/cc-switch/skill-claude.js +2 -11
- package/dist/adapters/cc-switch/skill-claudecode.d.ts +0 -1
- package/dist/adapters/cc-switch/skill-claudecode.js +2 -11
- package/dist/adapters/cc-switch/skill-codex.d.ts +0 -1
- package/dist/adapters/cc-switch/skill-codex.js +2 -6
- package/dist/adapters/cc-switch/skill-directory.d.ts +0 -1
- package/dist/adapters/cc-switch/skill-directory.js +3 -137
- package/dist/adapters/cc-switch/skill-opencode.d.ts +0 -1
- package/dist/adapters/cc-switch/skill-opencode.js +2 -11
- package/dist/adapters/cc-switch/skill-placeholder.d.ts +0 -1
- package/dist/adapters/cc-switch/skill-placeholder.js +2 -19
- package/dist/config.d.ts +0 -1
- package/dist/config.js +2 -290
- package/dist/index.d.ts +0 -1
- package/dist/index.js +2 -573
- package/dist/middleware/auth.d.ts +0 -1
- package/dist/middleware/auth.js +2 -98
- package/dist/routes/acode-todos.d.ts +0 -1
- package/dist/routes/acode-todos.js +2 -75
- package/dist/routes/ai-sources.d.ts +0 -1
- package/dist/routes/ai-sources.js +2 -132
- package/dist/routes/dashboard.d.ts +0 -1
- package/dist/routes/dashboard.js +182 -649
- package/dist/routes/events.d.ts +0 -1
- package/dist/routes/events.js +2 -22
- package/dist/routes/file-browser.d.ts +0 -1
- package/dist/routes/file-browser.js +2 -781
- package/dist/routes/file-diff-rollback.d.ts +0 -1
- package/dist/routes/file-diff-rollback.js +2 -301
- package/dist/routes/file-snapshot.d.ts +0 -1
- package/dist/routes/file-snapshot.js +2 -156
- package/dist/routes/git.d.ts +0 -1
- package/dist/routes/git.js +28 -1900
- package/dist/routes/instance.d.ts +0 -1
- package/dist/routes/instance.js +3 -748
- package/dist/routes/mcp.d.ts +0 -1
- package/dist/routes/mcp.js +2 -196
- package/dist/routes/processes.d.ts +0 -1
- package/dist/routes/processes.js +2 -252
- package/dist/routes/properties.d.ts +0 -1
- package/dist/routes/properties.js +2 -72
- package/dist/routes/pty.d.ts +0 -1
- package/dist/routes/pty.js +6 -560
- package/dist/routes/runtime-binding.d.ts +0 -1
- package/dist/routes/runtime-binding.js +2 -263
- package/dist/routes/sessions.d.ts +0 -1
- package/dist/routes/sessions.js +2 -758
- package/dist/routes/skills.d.ts +0 -1
- package/dist/routes/skills.js +2 -187
- package/dist/routes/sub-agents.d.ts +0 -1
- package/dist/routes/sub-agents.js +20 -279
- package/dist/routes/system-metrics.d.ts +0 -1
- package/dist/routes/system-metrics.js +2 -20
- package/dist/routes/task-context.d.ts +0 -1
- package/dist/routes/task-context.js +2 -78
- package/dist/routes/terminal.d.ts +0 -1
- package/dist/routes/terminal.js +54 -2882
- package/dist/routes/yml.d.ts +0 -1
- package/dist/routes/yml.js +2 -223
- package/dist/services/acode-package.d.ts +0 -1
- package/dist/services/acode-package.js +2 -111
- package/dist/services/agent-event-store.d.ts +0 -1
- package/dist/services/agent-event-store.js +2 -81
- package/dist/services/agent-process-manager.d.ts +0 -1
- package/dist/services/agent-process-manager.js +2 -796
- package/dist/services/ai-source-apply.d.ts +0 -1
- package/dist/services/ai-source-apply.js +2 -83
- package/dist/services/auto-register.d.ts +0 -1
- package/dist/services/auto-register.js +2 -1053
- package/dist/services/aws-client-agent-mcp.d.ts +0 -1
- package/dist/services/aws-client-agent-mcp.js +3 -337
- package/dist/services/bridge-package-publish-hooks.d.ts +0 -1
- package/dist/services/bridge-package-publish-hooks.js +2 -115
- package/dist/services/cc-switch-sdk.d.ts +0 -1
- package/dist/services/cc-switch-sdk.js +2 -135
- package/dist/services/cli-commands.d.ts +6 -1
- package/dist/services/cli-commands.js +6 -645
- package/dist/services/event-delta-pusher.d.ts +0 -1
- package/dist/services/event-delta-pusher.js +2 -95
- package/dist/services/fileSnapshotStore.d.ts +0 -1
- package/dist/services/fileSnapshotStore.js +2 -500
- package/dist/services/instance-ai-config-service.d.ts +0 -1
- package/dist/services/instance-ai-config-service.js +2 -174
- package/dist/services/instance-init-service.d.ts +0 -1
- package/dist/services/instance-init-service.js +2 -193
- package/dist/services/instance-service.d.ts +0 -1
- package/dist/services/instance-service.js +2 -237
- package/dist/services/instance-state.d.ts +0 -1
- package/dist/services/instance-state.js +2 -94
- package/dist/services/legacy-path-migration.d.ts +0 -1
- package/dist/services/legacy-path-migration.js +2 -66
- package/dist/services/lifecycle-state.d.ts +0 -1
- package/dist/services/lifecycle-state.js +3 -110
- package/dist/services/mcp-launch-binding-queue.d.ts +0 -1
- package/dist/services/mcp-launch-binding-queue.js +2 -175
- package/dist/services/orphan-monitor.d.ts +0 -1
- package/dist/services/orphan-monitor.js +2 -382
- package/dist/services/panel-auth.d.ts +0 -1
- package/dist/services/panel-auth.js +2 -168
- package/dist/services/process-detector.d.ts +0 -1
- package/dist/services/process-detector.js +18 -1019
- package/dist/services/process-registry.d.ts +0 -1
- package/dist/services/process-registry.js +2 -375
- package/dist/services/ring-buffer.d.ts +0 -1
- package/dist/services/ring-buffer.js +2 -103
- package/dist/services/runtime-binding.d.ts +0 -1
- package/dist/services/runtime-binding.js +6 -363
- package/dist/services/runtime-lifecycle-policy.d.ts +0 -1
- package/dist/services/runtime-lifecycle-policy.js +2 -35
- package/dist/services/session-output.d.ts +0 -1
- package/dist/services/session-output.js +5 -539
- package/dist/services/startup-config-wizard.d.ts +0 -1
- package/dist/services/startup-config-wizard.js +14 -258
- package/dist/services/sub-agent-manager-instance.d.ts +0 -1
- package/dist/services/sub-agent-manager-instance.js +2 -12
- package/dist/services/system-metrics.d.ts +0 -1
- package/dist/services/system-metrics.js +2 -252
- package/dist/services/terminal-persistence.d.ts +0 -1
- package/dist/services/terminal-persistence.js +2 -176
- package/dist/services/tool-installer.d.ts +0 -1
- package/dist/services/tool-installer.js +5 -751
- package/dist/services/tunnel-client.d.ts +0 -1
- package/dist/services/tunnel-client.js +2 -402
- package/dist/services/windows-service-manager.d.ts +3 -2
- package/dist/services/windows-service-manager.js +2 -54
- package/dist/services/workspace-files.d.ts +0 -1
- package/dist/services/workspace-files.js +2 -1275
- package/dist/services/workspace-watch.d.ts +0 -1
- package/dist/services/workspace-watch.js +2 -123
- package/dist/services/workspaceTaskChangeWatcher.d.ts +0 -1
- package/dist/services/workspaceTaskChangeWatcher.js +2 -483
- package/dist/types.d.ts +0 -1
- package/dist/types.js +1 -1
- package/dist/utils/file-utils.d.ts +0 -1
- package/dist/utils/file-utils.js +3 -208
- package/dist/utils/instance-ai-config-debug-logger.d.ts +0 -1
- package/dist/utils/instance-ai-config-debug-logger.js +4 -63
- package/dist/utils/logger.d.ts +0 -1
- package/dist/utils/logger.js +2 -154
- package/dist/utils/mcp-utils.d.ts +0 -1
- package/dist/utils/mcp-utils.js +2 -187
- package/dist/utils/path-utils.d.ts +0 -1
- package/dist/utils/path-utils.js +2 -44
- package/dist/utils/sdk-package-loader.d.ts +0 -1
- package/dist/utils/sdk-package-loader.js +2 -78
- package/dist/utils/validation.d.ts +0 -1
- package/dist/utils/validation.js +2 -53
- package/dist/utils/yaml-utils.d.ts +0 -1
- package/dist/utils/yaml-utils.js +2 -312
- package/node_modules/@cc-switch/sdk/dist/constants.d.ts +0 -1
- package/node_modules/@cc-switch/sdk/dist/constants.js +2 -63
- package/node_modules/@cc-switch/sdk/dist/errors.d.ts +0 -1
- package/node_modules/@cc-switch/sdk/dist/errors.js +2 -8
- package/node_modules/@cc-switch/sdk/dist/index.d.ts +0 -1
- package/node_modules/@cc-switch/sdk/dist/index.js +2 -9
- package/node_modules/@cc-switch/sdk/dist/schemas.d.ts +0 -1
- package/node_modules/@cc-switch/sdk/dist/schemas.js +2 -38
- package/node_modules/@cc-switch/sdk/dist/sdk.d.ts +0 -1
- package/node_modules/@cc-switch/sdk/dist/sdk.js +2 -470
- package/node_modules/@cc-switch/sdk/dist/services/ai-config-service.d.ts +0 -1
- package/node_modules/@cc-switch/sdk/dist/services/ai-config-service.js +4 -307
- package/node_modules/@cc-switch/sdk/dist/services/mcp-model.d.ts +0 -1
- package/node_modules/@cc-switch/sdk/dist/services/mcp-model.js +2 -37
- package/node_modules/@cc-switch/sdk/dist/services/mcp-service.d.ts +0 -1
- package/node_modules/@cc-switch/sdk/dist/services/mcp-service.js +2 -9
- package/node_modules/@cc-switch/sdk/dist/services/skill-model.d.ts +0 -1
- package/node_modules/@cc-switch/sdk/dist/services/skill-model.js +2 -41
- package/node_modules/@cc-switch/sdk/dist/services/skill-service.d.ts +0 -1
- package/node_modules/@cc-switch/sdk/dist/services/skill-service.js +2 -9
- package/node_modules/@cc-switch/sdk/dist/state.d.ts +0 -1
- package/node_modules/@cc-switch/sdk/dist/state.js +2 -19
- package/node_modules/@cc-switch/sdk/dist/types.d.ts +0 -1
- package/node_modules/@cc-switch/sdk/dist/types.js +1 -1
- package/node_modules/@cc-switch/sdk/dist/utils/fs.d.ts +0 -1
- package/node_modules/@cc-switch/sdk/dist/utils/fs.js +3 -114
- package/node_modules/@cc-switch/sdk/dist/utils/id.d.ts +0 -1
- package/node_modules/@cc-switch/sdk/dist/utils/id.js +2 -12
- package/node_modules/@cc-switch/sdk/package.json +1 -1
- package/package/acode/dist/ask-user-question-tool.d.ts +0 -1
- package/package/acode/dist/ask-user-question-tool.js +4 -233
- package/package/acode/dist/built-in-file-tools.d.ts +0 -1
- package/package/acode/dist/built-in-file-tools.js +4 -966
- package/package/acode/dist/built-in-symbols-tool.d.ts +0 -1
- package/package/acode/dist/built-in-symbols-tool.js +2 -117
- package/package/acode/dist/builtins/commandArtifacts.d.ts +0 -1
- package/package/acode/dist/builtins/commandArtifacts.js +9 -97
- package/package/acode/dist/builtins/commandOutputEvents.d.ts +0 -1
- package/package/acode/dist/builtins/commandOutputEvents.js +2 -56
- package/package/acode/dist/builtins/shellCommandPreparation.d.ts +0 -1
- package/package/acode/dist/builtins/shellCommandPreparation.js +5 -44
- package/package/acode/dist/builtins/shellCommandResult.d.ts +0 -1
- package/package/acode/dist/builtins/shellCommandResult.js +2 -71
- package/package/acode/dist/builtins/shellCommandRunner.d.ts +0 -1
- package/package/acode/dist/builtins/shellCommandRunner.js +2 -115
- package/package/acode/dist/builtins/shellOutputDecoder.d.ts +0 -1
- package/package/acode/dist/builtins/shellOutputDecoder.js +2 -94
- package/package/acode/dist/cli.d.ts +0 -1
- package/package/acode/dist/cli.js +4 -38
- package/package/acode/dist/commands/commandLoader.d.ts +0 -1
- package/package/acode/dist/commands/commandLoader.js +2 -33
- package/package/acode/dist/commands/commandParser.d.ts +0 -1
- package/package/acode/dist/commands/commandParser.js +3 -77
- package/package/acode/dist/commands/commandRegistry.d.ts +0 -1
- package/package/acode/dist/commands/commandRegistry.js +2 -30
- package/package/acode/dist/compaction.d.ts +0 -1
- package/package/acode/dist/compaction.js +7 -919
- package/package/acode/dist/config.d.ts +0 -1
- package/package/acode/dist/config.js +5 -105
- package/package/acode/dist/fs-utils.d.ts +0 -1
- package/package/acode/dist/fs-utils.js +2 -79
- package/package/acode/dist/hooks/hookBus.d.ts +0 -1
- package/package/acode/dist/hooks/hookBus.js +2 -40
- package/package/acode/dist/index.d.ts +0 -1
- package/package/acode/dist/index.js +2 -19
- package/package/acode/dist/mcpToolNames.d.ts +0 -1
- package/package/acode/dist/mcpToolNames.js +2 -17
- package/package/acode/dist/parsers/ast-cache.d.ts +0 -1
- package/package/acode/dist/parsers/ast-cache.js +2 -76
- package/package/acode/dist/parsers/language-detector.d.ts +0 -1
- package/package/acode/dist/parsers/language-detector.js +2 -44
- package/package/acode/dist/parsers/language-queries.d.ts +0 -1
- package/package/acode/dist/parsers/language-queries.js +12 -602
- package/package/acode/dist/parsers/symbol-extractor.d.ts +0 -1
- package/package/acode/dist/parsers/symbol-extractor.js +3 -164
- package/package/acode/dist/parsers/tree-sitter-loader.d.ts +0 -1
- package/package/acode/dist/parsers/tree-sitter-loader.js +2 -64
- package/package/acode/dist/parsers/types.d.ts +0 -1
- package/package/acode/dist/parsers/types.js +1 -7
- package/package/acode/dist/runtime.d.ts +0 -1
- package/package/acode/dist/runtime.js +86 -3771
- package/package/acode/dist/skill-tool.d.ts +0 -1
- package/package/acode/dist/skill-tool.js +5 -174
- package/package/acode/dist/sub-agent-manager.d.ts +0 -1
- package/package/acode/dist/sub-agent-manager.js +2 -1159
- package/package/acode/dist/sub-agent-store.d.ts +0 -1
- package/package/acode/dist/sub-agent-store.js +4 -236
- package/package/acode/dist/sub-agent-tools.d.ts +0 -1
- package/package/acode/dist/sub-agent-tools.js +15 -369
- package/package/acode/dist/sub-agent-types.d.ts +0 -1
- package/package/acode/dist/sub-agent-types.js +1 -8
- package/package/acode/dist/todo-store.d.ts +0 -1
- package/package/acode/dist/todo-store.js +2 -73
- package/package/acode/dist/todo-tool.d.ts +0 -1
- package/package/acode/dist/todo-tool.js +5 -121
- package/package/acode/dist/types.d.ts +0 -1
- package/package/acode/dist/types.js +1 -1
- package/package/acode/package.json +2 -2
- package/package/aws-client-agent-mcp/dist/agent-client.d.ts +0 -1
- package/package/aws-client-agent-mcp/dist/agent-client.js +2 -890
- package/package/aws-client-agent-mcp/dist/agent-client.test.d.ts +0 -1
- package/package/aws-client-agent-mcp/dist/agent-client.test.js +0 -1
- package/package/aws-client-agent-mcp/dist/config.d.ts +0 -1
- package/package/aws-client-agent-mcp/dist/config.js +2 -243
- package/package/aws-client-agent-mcp/dist/config.test.d.ts +0 -1
- package/package/aws-client-agent-mcp/dist/config.test.js +0 -1
- package/package/aws-client-agent-mcp/dist/constants.d.ts +0 -1
- package/package/aws-client-agent-mcp/dist/constants.js +2 -24
- package/package/aws-client-agent-mcp/dist/context-manager.d.ts +0 -1
- package/package/aws-client-agent-mcp/dist/context-manager.js +2 -477
- package/package/aws-client-agent-mcp/dist/context-manager.test.d.ts +0 -1
- package/package/aws-client-agent-mcp/dist/context-manager.test.js +0 -1
- package/package/aws-client-agent-mcp/dist/http-client.d.ts +0 -1
- package/package/aws-client-agent-mcp/dist/http-client.js +2 -446
- package/package/aws-client-agent-mcp/dist/http-client.test.d.ts +0 -1
- package/package/aws-client-agent-mcp/dist/http-client.test.js +0 -1
- package/package/aws-client-agent-mcp/dist/index.d.ts +0 -1
- package/package/aws-client-agent-mcp/dist/index.js +2 -34
- package/package/aws-client-agent-mcp/dist/logger.d.ts +0 -1
- package/package/aws-client-agent-mcp/dist/logger.js +3 -178
- package/package/aws-client-agent-mcp/dist/logger.test.d.ts +0 -1
- package/package/aws-client-agent-mcp/dist/logger.test.js +0 -1
- package/package/aws-client-agent-mcp/dist/mcp-server.d.ts +0 -1
- package/package/aws-client-agent-mcp/dist/mcp-server.js +38 -2709
- package/package/aws-client-agent-mcp/dist/mcp-server.test.d.ts +0 -1
- package/package/aws-client-agent-mcp/dist/mcp-server.test.js +0 -1
- package/package/aws-client-agent-mcp/dist/mcp-tools.d.ts +0 -1
- package/package/aws-client-agent-mcp/dist/mcp-tools.js +22 -562
- package/package/aws-client-agent-mcp/dist/mcp-tools.test.d.ts +0 -1
- package/package/aws-client-agent-mcp/dist/mcp-tools.test.js +0 -1
- package/package/aws-client-agent-mcp/dist/memory-store.d.ts +0 -1
- package/package/aws-client-agent-mcp/dist/memory-store.js +4 -826
- package/package/aws-client-agent-mcp/dist/memory-store.test.d.ts +0 -1
- package/package/aws-client-agent-mcp/dist/memory-store.test.js +0 -1
- package/package/aws-client-agent-mcp/dist/memory-tools.d.ts +0 -1
- package/package/aws-client-agent-mcp/dist/memory-tools.js +31 -294
- package/package/aws-client-agent-mcp/dist/message-buffer.d.ts +0 -1
- package/package/aws-client-agent-mcp/dist/message-buffer.js +2 -288
- package/package/aws-client-agent-mcp/dist/message-buffer.test.d.ts +0 -1
- package/package/aws-client-agent-mcp/dist/message-buffer.test.js +0 -1
- package/package/aws-client-agent-mcp/dist/messageContent.d.ts +0 -1
- package/package/aws-client-agent-mcp/dist/messageContent.js +2 -125
- package/package/aws-client-agent-mcp/dist/runtime-launch-binding.d.ts +0 -1
- package/package/aws-client-agent-mcp/dist/runtime-launch-binding.js +2 -103
- package/package/aws-client-agent-mcp/dist/runtime-launch-binding.test.d.ts +0 -1
- package/package/aws-client-agent-mcp/dist/runtime-launch-binding.test.js +0 -1
- package/package/aws-client-agent-mcp/dist/server-memory-store.d.ts +0 -1
- package/package/aws-client-agent-mcp/dist/server-memory-store.js +2 -96
- package/package/aws-client-agent-mcp/dist/status-reporter.d.ts +0 -1
- package/package/aws-client-agent-mcp/dist/status-reporter.js +3 -327
- package/package/aws-client-agent-mcp/dist/status-reporter.test.d.ts +0 -1
- package/package/aws-client-agent-mcp/dist/status-reporter.test.js +0 -1
- package/package/aws-client-agent-mcp/dist/types.d.ts +0 -1
- package/package/aws-client-agent-mcp/dist/types.js +2 -9
- package/package/aws-client-agent-mcp/dist/websocket-client.d.ts +0 -1
- package/package/aws-client-agent-mcp/dist/websocket-client.js +2 -677
- package/package/aws-client-agent-mcp/dist/websocket-client.test.d.ts +0 -1
- package/package/aws-client-agent-mcp/dist/websocket-client.test.js +0 -1
- package/package/aws-client-agent-mcp/package.json +1 -1
- package/package/cc-switch-sdk/dist/constants.d.ts +0 -1
- package/package/cc-switch-sdk/dist/constants.js +2 -63
- package/package/cc-switch-sdk/dist/errors.d.ts +0 -1
- package/package/cc-switch-sdk/dist/errors.js +2 -8
- package/package/cc-switch-sdk/dist/index.d.ts +0 -1
- package/package/cc-switch-sdk/dist/index.js +2 -9
- package/package/cc-switch-sdk/dist/schemas.d.ts +0 -1
- package/package/cc-switch-sdk/dist/schemas.js +2 -38
- package/package/cc-switch-sdk/dist/sdk.d.ts +0 -1
- package/package/cc-switch-sdk/dist/sdk.js +2 -470
- package/package/cc-switch-sdk/dist/services/ai-config-service.d.ts +0 -1
- package/package/cc-switch-sdk/dist/services/ai-config-service.js +4 -307
- package/package/cc-switch-sdk/dist/services/mcp-model.d.ts +0 -1
- package/package/cc-switch-sdk/dist/services/mcp-model.js +2 -37
- package/package/cc-switch-sdk/dist/services/mcp-service.d.ts +0 -1
- package/package/cc-switch-sdk/dist/services/mcp-service.js +2 -9
- package/package/cc-switch-sdk/dist/services/skill-model.d.ts +0 -1
- package/package/cc-switch-sdk/dist/services/skill-model.js +2 -41
- package/package/cc-switch-sdk/dist/services/skill-service.d.ts +0 -1
- package/package/cc-switch-sdk/dist/services/skill-service.js +2 -9
- package/package/cc-switch-sdk/dist/state.d.ts +0 -1
- package/package/cc-switch-sdk/dist/state.js +2 -19
- package/package/cc-switch-sdk/dist/types.d.ts +0 -1
- package/package/cc-switch-sdk/dist/types.js +1 -1
- package/package/cc-switch-sdk/dist/utils/fs.d.ts +0 -1
- package/package/cc-switch-sdk/dist/utils/fs.js +3 -114
- package/package/cc-switch-sdk/dist/utils/id.d.ts +0 -1
- package/package/cc-switch-sdk/dist/utils/id.js +2 -12
- package/package/cc-switch-sdk/package.json +1 -1
- package/package.json +4 -2
- package/dist/adapter/AcodeSdkAdapter.d.ts.map +0 -1
- package/dist/adapter/AdapterRegistry.d.ts.map +0 -1
- package/dist/adapter/ClaudeSdkAdapter.d.ts.map +0 -1
- package/dist/adapter/CodexSdkAdapter.d.ts.map +0 -1
- package/dist/adapter/OpencodeSdkAdapter.d.ts.map +0 -1
- package/dist/adapter/SdkProviderSpi.d.ts.map +0 -1
- package/dist/adapter/acode-tool-names.d.ts.map +0 -1
- package/dist/adapter/idle-poll-loop.d.ts.map +0 -1
- package/dist/adapter/index.d.ts.map +0 -1
- package/dist/adapter/instance-ai-config-resolver.d.ts.map +0 -1
- package/dist/adapter/types.d.ts.map +0 -1
- package/dist/adapters/cc-switch/common.d.ts.map +0 -1
- package/dist/adapters/cc-switch/index.d.ts.map +0 -1
- package/dist/adapters/cc-switch/mcp-acode.d.ts.map +0 -1
- package/dist/adapters/cc-switch/mcp-claude.d.ts.map +0 -1
- package/dist/adapters/cc-switch/mcp-claudecode.d.ts.map +0 -1
- package/dist/adapters/cc-switch/mcp-codex.d.ts.map +0 -1
- package/dist/adapters/cc-switch/mcp-opencode.d.ts.map +0 -1
- package/dist/adapters/cc-switch/mcp-placeholder.d.ts.map +0 -1
- package/dist/adapters/cc-switch/skill-acode.d.ts.map +0 -1
- package/dist/adapters/cc-switch/skill-claude.d.ts.map +0 -1
- package/dist/adapters/cc-switch/skill-claudecode.d.ts.map +0 -1
- package/dist/adapters/cc-switch/skill-codex.d.ts.map +0 -1
- package/dist/adapters/cc-switch/skill-directory.d.ts.map +0 -1
- package/dist/adapters/cc-switch/skill-opencode.d.ts.map +0 -1
- package/dist/adapters/cc-switch/skill-placeholder.d.ts.map +0 -1
- package/dist/config.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/middleware/auth.d.ts.map +0 -1
- package/dist/routes/acode-todos.d.ts.map +0 -1
- package/dist/routes/ai-sources.d.ts.map +0 -1
- package/dist/routes/dashboard.d.ts.map +0 -1
- package/dist/routes/events.d.ts.map +0 -1
- package/dist/routes/file-browser.d.ts.map +0 -1
- package/dist/routes/file-diff-rollback.d.ts.map +0 -1
- package/dist/routes/file-snapshot.d.ts.map +0 -1
- package/dist/routes/git.d.ts.map +0 -1
- package/dist/routes/instance.d.ts.map +0 -1
- package/dist/routes/mcp.d.ts.map +0 -1
- package/dist/routes/processes.d.ts.map +0 -1
- package/dist/routes/properties.d.ts.map +0 -1
- package/dist/routes/pty.d.ts.map +0 -1
- package/dist/routes/runtime-binding.d.ts.map +0 -1
- package/dist/routes/sessions.d.ts.map +0 -1
- package/dist/routes/skills.d.ts.map +0 -1
- package/dist/routes/sub-agents.d.ts.map +0 -1
- package/dist/routes/system-metrics.d.ts.map +0 -1
- package/dist/routes/task-context.d.ts.map +0 -1
- package/dist/routes/terminal.d.ts.map +0 -1
- package/dist/routes/yml.d.ts.map +0 -1
- package/dist/services/acode-package.d.ts.map +0 -1
- package/dist/services/agent-event-store.d.ts.map +0 -1
- package/dist/services/agent-process-manager.d.ts.map +0 -1
- package/dist/services/ai-source-apply.d.ts.map +0 -1
- package/dist/services/auto-register.d.ts.map +0 -1
- package/dist/services/aws-client-agent-mcp.d.ts.map +0 -1
- package/dist/services/bridge-package-publish-hooks.d.ts.map +0 -1
- package/dist/services/cc-switch-sdk.d.ts.map +0 -1
- package/dist/services/cli-commands.d.ts.map +0 -1
- package/dist/services/event-delta-pusher.d.ts.map +0 -1
- package/dist/services/fileSnapshotStore.d.ts.map +0 -1
- package/dist/services/instance-ai-config-service.d.ts.map +0 -1
- package/dist/services/instance-init-service.d.ts.map +0 -1
- package/dist/services/instance-service.d.ts.map +0 -1
- package/dist/services/instance-state.d.ts.map +0 -1
- package/dist/services/legacy-path-migration.d.ts.map +0 -1
- package/dist/services/lifecycle-state.d.ts.map +0 -1
- package/dist/services/mcp-launch-binding-queue.d.ts.map +0 -1
- package/dist/services/orphan-monitor.d.ts.map +0 -1
- package/dist/services/panel-auth.d.ts.map +0 -1
- package/dist/services/process-detector.d.ts.map +0 -1
- package/dist/services/process-registry.d.ts.map +0 -1
- package/dist/services/ring-buffer.d.ts.map +0 -1
- package/dist/services/runtime-binding.d.ts.map +0 -1
- package/dist/services/runtime-lifecycle-policy.d.ts.map +0 -1
- package/dist/services/session-output.d.ts.map +0 -1
- package/dist/services/startup-config-wizard.d.ts.map +0 -1
- package/dist/services/sub-agent-manager-instance.d.ts.map +0 -1
- package/dist/services/system-metrics.d.ts.map +0 -1
- package/dist/services/terminal-persistence.d.ts.map +0 -1
- package/dist/services/tool-installer.d.ts.map +0 -1
- package/dist/services/tunnel-client.d.ts.map +0 -1
- package/dist/services/windows-service-manager.d.ts.map +0 -1
- package/dist/services/workspace-files.d.ts.map +0 -1
- package/dist/services/workspace-watch.d.ts.map +0 -1
- package/dist/services/workspaceTaskChangeWatcher.d.ts.map +0 -1
- package/dist/types.d.ts.map +0 -1
- package/dist/utils/file-utils.d.ts.map +0 -1
- package/dist/utils/instance-ai-config-debug-logger.d.ts.map +0 -1
- package/dist/utils/logger.d.ts.map +0 -1
- package/dist/utils/mcp-utils.d.ts.map +0 -1
- package/dist/utils/path-utils.d.ts.map +0 -1
- package/dist/utils/sdk-package-loader.d.ts.map +0 -1
- package/dist/utils/validation.d.ts.map +0 -1
- package/dist/utils/yaml-utils.d.ts.map +0 -1
- package/node_modules/@cc-switch/sdk/dist/constants.d.ts.map +0 -1
- package/node_modules/@cc-switch/sdk/dist/errors.d.ts.map +0 -1
- package/node_modules/@cc-switch/sdk/dist/index.d.ts.map +0 -1
- package/node_modules/@cc-switch/sdk/dist/schemas.d.ts.map +0 -1
- package/node_modules/@cc-switch/sdk/dist/sdk.d.ts.map +0 -1
- package/node_modules/@cc-switch/sdk/dist/services/ai-config-service.d.ts.map +0 -1
- package/node_modules/@cc-switch/sdk/dist/services/mcp-model.d.ts.map +0 -1
- package/node_modules/@cc-switch/sdk/dist/services/mcp-service.d.ts.map +0 -1
- package/node_modules/@cc-switch/sdk/dist/services/skill-model.d.ts.map +0 -1
- package/node_modules/@cc-switch/sdk/dist/services/skill-service.d.ts.map +0 -1
- package/node_modules/@cc-switch/sdk/dist/state.d.ts.map +0 -1
- package/node_modules/@cc-switch/sdk/dist/types.d.ts.map +0 -1
- package/node_modules/@cc-switch/sdk/dist/utils/fs.d.ts.map +0 -1
- package/node_modules/@cc-switch/sdk/dist/utils/id.d.ts.map +0 -1
- package/package/acode/dist/ask-user-question-tool.d.ts.map +0 -1
- package/package/acode/dist/built-in-file-tools.d.ts.map +0 -1
- package/package/acode/dist/built-in-symbols-tool.d.ts.map +0 -1
- package/package/acode/dist/builtins/commandArtifacts.d.ts.map +0 -1
- package/package/acode/dist/builtins/commandOutputEvents.d.ts.map +0 -1
- package/package/acode/dist/builtins/shellCommandPreparation.d.ts.map +0 -1
- package/package/acode/dist/builtins/shellCommandResult.d.ts.map +0 -1
- package/package/acode/dist/builtins/shellCommandRunner.d.ts.map +0 -1
- package/package/acode/dist/builtins/shellOutputDecoder.d.ts.map +0 -1
- package/package/acode/dist/cli.d.ts.map +0 -1
- package/package/acode/dist/commands/commandLoader.d.ts.map +0 -1
- package/package/acode/dist/commands/commandParser.d.ts.map +0 -1
- package/package/acode/dist/commands/commandRegistry.d.ts.map +0 -1
- package/package/acode/dist/compaction.d.ts.map +0 -1
- package/package/acode/dist/config.d.ts.map +0 -1
- package/package/acode/dist/fs-utils.d.ts.map +0 -1
- package/package/acode/dist/hooks/hookBus.d.ts.map +0 -1
- package/package/acode/dist/index.d.ts.map +0 -1
- package/package/acode/dist/mcpToolNames.d.ts.map +0 -1
- package/package/acode/dist/parsers/ast-cache.d.ts.map +0 -1
- package/package/acode/dist/parsers/language-detector.d.ts.map +0 -1
- package/package/acode/dist/parsers/language-queries.d.ts.map +0 -1
- package/package/acode/dist/parsers/symbol-extractor.d.ts.map +0 -1
- package/package/acode/dist/parsers/tree-sitter-loader.d.ts.map +0 -1
- package/package/acode/dist/parsers/types.d.ts.map +0 -1
- package/package/acode/dist/runtime.d.ts.map +0 -1
- package/package/acode/dist/skill-tool.d.ts.map +0 -1
- package/package/acode/dist/sub-agent-manager.d.ts.map +0 -1
- package/package/acode/dist/sub-agent-store.d.ts.map +0 -1
- package/package/acode/dist/sub-agent-tools.d.ts.map +0 -1
- package/package/acode/dist/sub-agent-types.d.ts.map +0 -1
- package/package/acode/dist/todo-store.d.ts.map +0 -1
- package/package/acode/dist/todo-tool.d.ts.map +0 -1
- package/package/acode/dist/types.d.ts.map +0 -1
- package/package/aws-client-agent-mcp/dist/agent-client.d.ts.map +0 -1
- package/package/aws-client-agent-mcp/dist/agent-client.js.map +0 -1
- package/package/aws-client-agent-mcp/dist/agent-client.test.d.ts.map +0 -1
- package/package/aws-client-agent-mcp/dist/agent-client.test.js.map +0 -1
- package/package/aws-client-agent-mcp/dist/config.d.ts.map +0 -1
- package/package/aws-client-agent-mcp/dist/config.js.map +0 -1
- package/package/aws-client-agent-mcp/dist/config.test.d.ts.map +0 -1
- package/package/aws-client-agent-mcp/dist/config.test.js.map +0 -1
- package/package/aws-client-agent-mcp/dist/constants.d.ts.map +0 -1
- package/package/aws-client-agent-mcp/dist/constants.js.map +0 -1
- package/package/aws-client-agent-mcp/dist/context-manager.d.ts.map +0 -1
- package/package/aws-client-agent-mcp/dist/context-manager.js.map +0 -1
- package/package/aws-client-agent-mcp/dist/context-manager.test.d.ts.map +0 -1
- package/package/aws-client-agent-mcp/dist/context-manager.test.js.map +0 -1
- package/package/aws-client-agent-mcp/dist/http-client.d.ts.map +0 -1
- package/package/aws-client-agent-mcp/dist/http-client.js.map +0 -1
- package/package/aws-client-agent-mcp/dist/http-client.test.d.ts.map +0 -1
- package/package/aws-client-agent-mcp/dist/http-client.test.js.map +0 -1
- package/package/aws-client-agent-mcp/dist/index.d.ts.map +0 -1
- package/package/aws-client-agent-mcp/dist/index.js.map +0 -1
- package/package/aws-client-agent-mcp/dist/logger.d.ts.map +0 -1
- package/package/aws-client-agent-mcp/dist/logger.js.map +0 -1
- package/package/aws-client-agent-mcp/dist/logger.test.d.ts.map +0 -1
- package/package/aws-client-agent-mcp/dist/logger.test.js.map +0 -1
- package/package/aws-client-agent-mcp/dist/mcp-server.d.ts.map +0 -1
- package/package/aws-client-agent-mcp/dist/mcp-server.js.map +0 -1
- package/package/aws-client-agent-mcp/dist/mcp-server.test.d.ts.map +0 -1
- package/package/aws-client-agent-mcp/dist/mcp-server.test.js.map +0 -1
- package/package/aws-client-agent-mcp/dist/mcp-tools.d.ts.map +0 -1
- package/package/aws-client-agent-mcp/dist/mcp-tools.js.map +0 -1
- package/package/aws-client-agent-mcp/dist/mcp-tools.test.d.ts.map +0 -1
- package/package/aws-client-agent-mcp/dist/mcp-tools.test.js.map +0 -1
- package/package/aws-client-agent-mcp/dist/memory-store.d.ts.map +0 -1
- package/package/aws-client-agent-mcp/dist/memory-store.js.map +0 -1
- package/package/aws-client-agent-mcp/dist/memory-store.test.d.ts.map +0 -1
- package/package/aws-client-agent-mcp/dist/memory-store.test.js.map +0 -1
- package/package/aws-client-agent-mcp/dist/memory-tools.d.ts.map +0 -1
- package/package/aws-client-agent-mcp/dist/memory-tools.js.map +0 -1
- package/package/aws-client-agent-mcp/dist/message-buffer.d.ts.map +0 -1
- package/package/aws-client-agent-mcp/dist/message-buffer.js.map +0 -1
- package/package/aws-client-agent-mcp/dist/message-buffer.test.d.ts.map +0 -1
- package/package/aws-client-agent-mcp/dist/message-buffer.test.js.map +0 -1
- package/package/aws-client-agent-mcp/dist/messageContent.d.ts.map +0 -1
- package/package/aws-client-agent-mcp/dist/messageContent.js.map +0 -1
- package/package/aws-client-agent-mcp/dist/runtime-launch-binding.d.ts.map +0 -1
- package/package/aws-client-agent-mcp/dist/runtime-launch-binding.js.map +0 -1
- package/package/aws-client-agent-mcp/dist/runtime-launch-binding.test.d.ts.map +0 -1
- package/package/aws-client-agent-mcp/dist/runtime-launch-binding.test.js.map +0 -1
- package/package/aws-client-agent-mcp/dist/server-memory-store.d.ts.map +0 -1
- package/package/aws-client-agent-mcp/dist/server-memory-store.js.map +0 -1
- package/package/aws-client-agent-mcp/dist/status-reporter.d.ts.map +0 -1
- package/package/aws-client-agent-mcp/dist/status-reporter.js.map +0 -1
- package/package/aws-client-agent-mcp/dist/status-reporter.test.d.ts.map +0 -1
- package/package/aws-client-agent-mcp/dist/status-reporter.test.js.map +0 -1
- package/package/aws-client-agent-mcp/dist/types.d.ts.map +0 -1
- package/package/aws-client-agent-mcp/dist/types.js.map +0 -1
- package/package/aws-client-agent-mcp/dist/websocket-client.d.ts.map +0 -1
- package/package/aws-client-agent-mcp/dist/websocket-client.js.map +0 -1
- package/package/aws-client-agent-mcp/dist/websocket-client.test.d.ts.map +0 -1
- package/package/aws-client-agent-mcp/dist/websocket-client.test.js.map +0 -1
- package/package/cc-switch-sdk/dist/constants.d.ts.map +0 -1
- package/package/cc-switch-sdk/dist/errors.d.ts.map +0 -1
- package/package/cc-switch-sdk/dist/index.d.ts.map +0 -1
- package/package/cc-switch-sdk/dist/schemas.d.ts.map +0 -1
- package/package/cc-switch-sdk/dist/sdk.d.ts.map +0 -1
- package/package/cc-switch-sdk/dist/services/ai-config-service.d.ts.map +0 -1
- package/package/cc-switch-sdk/dist/services/mcp-model.d.ts.map +0 -1
- package/package/cc-switch-sdk/dist/services/mcp-service.d.ts.map +0 -1
- package/package/cc-switch-sdk/dist/services/skill-model.d.ts.map +0 -1
- package/package/cc-switch-sdk/dist/services/skill-service.d.ts.map +0 -1
- package/package/cc-switch-sdk/dist/state.d.ts.map +0 -1
- package/package/cc-switch-sdk/dist/types.d.ts.map +0 -1
- package/package/cc-switch-sdk/dist/utils/fs.d.ts.map +0 -1
- package/package/cc-switch-sdk/dist/utils/id.d.ts.map +0 -1
package/dist/routes/pty.js
CHANGED
|
@@ -1,560 +1,6 @@
|
|
|
1
|
-
import crypto from "node:
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
import WebSocket, { WebSocketServer } from "ws";
|
|
8
|
-
import { isRuntimeTokenValid, validateToken } from "../middleware/auth.js";
|
|
9
|
-
import { createLogger } from "../utils/logger.js";
|
|
10
|
-
const log = createLogger("pty");
|
|
11
|
-
const DEFAULT_COLS = 80;
|
|
12
|
-
const DEFAULT_ROWS = 24;
|
|
13
|
-
const MAX_OUTPUT_BUFFER_CHARS = 200_000;
|
|
14
|
-
const DEFAULT_IDLE_TTL_MS = 30 * 60 * 1000;
|
|
15
|
-
const DEFAULT_EXITED_TTL_MS = 5 * 60 * 1000;
|
|
16
|
-
const DEFAULT_CONNECT_TOKEN_TTL_MS = 60 * 1000;
|
|
17
|
-
const DEFAULT_MAX_PTY_SESSIONS = 8;
|
|
18
|
-
const NON_INTERACTIVE_UNIX_SHELLS = new Set([
|
|
19
|
-
"false",
|
|
20
|
-
"halt",
|
|
21
|
-
"nologin",
|
|
22
|
-
"reboot",
|
|
23
|
-
"shutdown",
|
|
24
|
-
"sync",
|
|
25
|
-
"true",
|
|
26
|
-
]);
|
|
27
|
-
export const ptySessions = new Map();
|
|
28
|
-
const ptyConnectTokens = new Map();
|
|
29
|
-
/**
|
|
30
|
-
* 解析 PTY 空闲清理时间。
|
|
31
|
-
* 主流程:读取环境变量 -> 非法值回退默认值 -> 用于 WebSocket 全断开后的延迟清理。
|
|
32
|
-
*/
|
|
33
|
-
export function resolvePtyIdleTtlMs(env = process.env) {
|
|
34
|
-
const raw = String(env.AWS_PTY_IDLE_TTL_MS || "").trim();
|
|
35
|
-
if (!raw) {
|
|
36
|
-
return DEFAULT_IDLE_TTL_MS;
|
|
37
|
-
}
|
|
38
|
-
const parsed = Number(raw);
|
|
39
|
-
if (!Number.isFinite(parsed) || parsed < 1_000) {
|
|
40
|
-
return DEFAULT_IDLE_TTL_MS;
|
|
41
|
-
}
|
|
42
|
-
return parsed;
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* 选择默认 shell。
|
|
46
|
-
* 主流程:Windows 优先 pwsh/powershell/cmd;Unix 优先 SHELL/bash/sh,返回可执行文件名与参数。
|
|
47
|
-
*/
|
|
48
|
-
export function resolveDefaultShell(platform = process.platform, env = process.env, existsSync = fs.existsSync) {
|
|
49
|
-
if (platform === "win32") {
|
|
50
|
-
const comSpec = String(env.ComSpec || env.COMSPEC || "").trim();
|
|
51
|
-
return { shell: comSpec || "powershell.exe", args: [] };
|
|
52
|
-
}
|
|
53
|
-
const configuredShell = String(env.SHELL || "").trim();
|
|
54
|
-
const shell = [configuredShell, "/bin/bash", "/bin/sh"].find((candidate) => isUsableUnixShellCandidate(candidate, existsSync));
|
|
55
|
-
return { shell: shell || "/bin/sh", args: [] };
|
|
56
|
-
}
|
|
57
|
-
/**
|
|
58
|
-
* 判断 Unix shell 候选是否适合交互式 PTY。
|
|
59
|
-
* 具体逻辑:跳过 nologin/false 等会立即退出的系统 shell;绝对路径还必须真实存在。
|
|
60
|
-
*/
|
|
61
|
-
function isUsableUnixShellCandidate(candidate, existsSync) {
|
|
62
|
-
const shell = candidate.trim();
|
|
63
|
-
if (!shell) {
|
|
64
|
-
return false;
|
|
65
|
-
}
|
|
66
|
-
const basename = path.basename(shell).toLowerCase();
|
|
67
|
-
if (NON_INTERACTIVE_UNIX_SHELLS.has(basename)) {
|
|
68
|
-
return false;
|
|
69
|
-
}
|
|
70
|
-
return !path.isAbsolute(shell) || existsSync(shell);
|
|
71
|
-
}
|
|
72
|
-
/**
|
|
73
|
-
* 校验并解析 shell 选择。
|
|
74
|
-
* 主流程:auto 使用默认 shell;显式 shell 必须命中 allowlist,避免前端任意执行二进制。
|
|
75
|
-
*/
|
|
76
|
-
export function resolveRequestedShell(requestedShell, platform = process.platform, env = process.env) {
|
|
77
|
-
const normalized = String(requestedShell || "auto").trim();
|
|
78
|
-
if (!normalized || normalized === "auto") {
|
|
79
|
-
return resolveDefaultShell(platform, env);
|
|
80
|
-
}
|
|
81
|
-
const allowlist = new Set([
|
|
82
|
-
"bash",
|
|
83
|
-
"sh",
|
|
84
|
-
"zsh",
|
|
85
|
-
"fish",
|
|
86
|
-
"pwsh",
|
|
87
|
-
"pwsh.exe",
|
|
88
|
-
"powershell",
|
|
89
|
-
"powershell.exe",
|
|
90
|
-
"cmd",
|
|
91
|
-
"cmd.exe",
|
|
92
|
-
]);
|
|
93
|
-
const basename = path.basename(normalized).toLowerCase();
|
|
94
|
-
if (!allowlist.has(basename)) {
|
|
95
|
-
throw new Error(`shell is not allowed: ${normalized}`);
|
|
96
|
-
}
|
|
97
|
-
return { shell: normalized, args: [] };
|
|
98
|
-
}
|
|
99
|
-
/**
|
|
100
|
-
* 判断候选路径是否位于允许根目录中。
|
|
101
|
-
* 具体逻辑:使用 path.relative 处理 Windows/Unix 分隔符,拒绝向上穿越和跨盘路径。
|
|
102
|
-
*/
|
|
103
|
-
export function isPathInsideRoot(candidatePath, rootPath) {
|
|
104
|
-
const relative = path.relative(path.resolve(rootPath), path.resolve(candidatePath));
|
|
105
|
-
return relative === "" || (!relative.startsWith("..") && !path.isAbsolute(relative));
|
|
106
|
-
}
|
|
107
|
-
function resolveAllowedWorkspaceRoots(env = process.env) {
|
|
108
|
-
return String(env.AWS_PTY_ALLOWED_ROOTS || "")
|
|
109
|
-
.split(path.delimiter)
|
|
110
|
-
.map((item) => item.trim())
|
|
111
|
-
.filter(Boolean)
|
|
112
|
-
.map((item) => path.resolve(item));
|
|
113
|
-
}
|
|
114
|
-
/**
|
|
115
|
-
* 解析并校验 PTY 工作目录。
|
|
116
|
-
* 主流程:要求绝对目录存在;如果配置 AWS_PTY_ALLOWED_ROOTS,则必须位于允许根目录内。
|
|
117
|
-
*/
|
|
118
|
-
export function resolvePtyWorkspacePath(workspacePath, env = process.env) {
|
|
119
|
-
const raw = String(workspacePath || "").trim();
|
|
120
|
-
if (!raw) {
|
|
121
|
-
throw new Error("workspacePath is required");
|
|
122
|
-
}
|
|
123
|
-
if (!path.isAbsolute(raw)) {
|
|
124
|
-
throw new Error("workspacePath must be absolute");
|
|
125
|
-
}
|
|
126
|
-
const resolved = path.resolve(raw);
|
|
127
|
-
const stat = fs.statSync(resolved);
|
|
128
|
-
if (!stat.isDirectory()) {
|
|
129
|
-
throw new Error("workspacePath must be an existing directory");
|
|
130
|
-
}
|
|
131
|
-
const allowedRoots = resolveAllowedWorkspaceRoots(env);
|
|
132
|
-
if (allowedRoots.length > 0 && !allowedRoots.some((root) => isPathInsideRoot(resolved, root))) {
|
|
133
|
-
throw new Error("workspacePath is outside allowed roots");
|
|
134
|
-
}
|
|
135
|
-
return resolved;
|
|
136
|
-
}
|
|
137
|
-
function normalizeDimension(value, fallback) {
|
|
138
|
-
const parsed = Number(value);
|
|
139
|
-
if (!Number.isInteger(parsed) || parsed <= 0) {
|
|
140
|
-
return fallback;
|
|
141
|
-
}
|
|
142
|
-
return Math.min(parsed, 500);
|
|
143
|
-
}
|
|
144
|
-
function buildPtyEnv(baseEnv) {
|
|
145
|
-
return {
|
|
146
|
-
...baseEnv,
|
|
147
|
-
TERM: baseEnv.TERM || "xterm-256color",
|
|
148
|
-
COLORTERM: baseEnv.COLORTERM || "truecolor",
|
|
149
|
-
};
|
|
150
|
-
}
|
|
151
|
-
function appendOutputBuffer(session, data) {
|
|
152
|
-
session.outputBuffer = `${session.outputBuffer}${data}`;
|
|
153
|
-
if (session.outputBuffer.length > MAX_OUTPUT_BUFFER_CHARS) {
|
|
154
|
-
session.outputBuffer = session.outputBuffer.slice(-MAX_OUTPUT_BUFFER_CHARS);
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
function toSummary(session) {
|
|
158
|
-
return {
|
|
159
|
-
id: session.id,
|
|
160
|
-
title: session.title,
|
|
161
|
-
workspacePath: session.workspacePath,
|
|
162
|
-
shell: session.shell,
|
|
163
|
-
cols: session.cols,
|
|
164
|
-
rows: session.rows,
|
|
165
|
-
status: session.status,
|
|
166
|
-
createdAt: session.createdAt,
|
|
167
|
-
lastActiveAt: session.lastActiveAt,
|
|
168
|
-
exitCode: session.exitCode,
|
|
169
|
-
signal: session.signal,
|
|
170
|
-
attachedClients: session.sockets.size,
|
|
171
|
-
ownerUserId: session.ownerUserId,
|
|
172
|
-
tenantId: session.tenantId,
|
|
173
|
-
projectName: session.projectName,
|
|
174
|
-
};
|
|
175
|
-
}
|
|
176
|
-
function sendJson(socket, payload) {
|
|
177
|
-
if (socket.readyState === WebSocket.OPEN) {
|
|
178
|
-
socket.send(JSON.stringify(payload));
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
function broadcast(session, payload) {
|
|
182
|
-
for (const socket of session.sockets) {
|
|
183
|
-
sendJson(socket, payload);
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
function scheduleIdleCleanup(session) {
|
|
187
|
-
if (session.idleTimer) {
|
|
188
|
-
clearTimeout(session.idleTimer);
|
|
189
|
-
}
|
|
190
|
-
session.idleTimer = setTimeout(() => {
|
|
191
|
-
if (session.sockets.size === 0) {
|
|
192
|
-
closePtySession(session.id, "idle-timeout");
|
|
193
|
-
}
|
|
194
|
-
}, resolvePtyIdleTtlMs());
|
|
195
|
-
}
|
|
196
|
-
function cancelIdleCleanup(session) {
|
|
197
|
-
if (session.idleTimer) {
|
|
198
|
-
clearTimeout(session.idleTimer);
|
|
199
|
-
session.idleTimer = null;
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
/**
|
|
203
|
-
* 创建 PTY session。
|
|
204
|
-
* 主流程:校验 cwd/shell -> spawn 真实 PTY -> 注册 output/exit 事件 -> 返回元数据给控制面。
|
|
205
|
-
*/
|
|
206
|
-
export function createPtySession(input) {
|
|
207
|
-
if (ptySessions.size >= resolveMaxPtySessions()) {
|
|
208
|
-
throw new Error("maximum PTY sessions reached");
|
|
209
|
-
}
|
|
210
|
-
const workspacePath = resolvePtyWorkspacePath(input.workspacePath);
|
|
211
|
-
const shell = resolveRequestedShell(input.shell);
|
|
212
|
-
const cols = normalizeDimension(input.cols, DEFAULT_COLS);
|
|
213
|
-
const rows = normalizeDimension(input.rows, DEFAULT_ROWS);
|
|
214
|
-
const id = `pty_${uuidv4()}`;
|
|
215
|
-
const now = new Date().toISOString();
|
|
216
|
-
const title = String(input.title || "").trim() || `Terminal ${ptySessions.size + 1}`;
|
|
217
|
-
const ptyProcess = pty.spawn(shell.shell, shell.args, {
|
|
218
|
-
name: "xterm-256color",
|
|
219
|
-
cols,
|
|
220
|
-
rows,
|
|
221
|
-
cwd: workspacePath,
|
|
222
|
-
env: buildPtyEnv(process.env),
|
|
223
|
-
});
|
|
224
|
-
const session = {
|
|
225
|
-
id,
|
|
226
|
-
title,
|
|
227
|
-
workspacePath,
|
|
228
|
-
shell: shell.shell,
|
|
229
|
-
cols,
|
|
230
|
-
rows,
|
|
231
|
-
status: "running",
|
|
232
|
-
createdAt: now,
|
|
233
|
-
lastActiveAt: now,
|
|
234
|
-
attachedClients: 0,
|
|
235
|
-
ptyProcess,
|
|
236
|
-
sockets: new Set(),
|
|
237
|
-
outputBuffer: "",
|
|
238
|
-
idleTimer: null,
|
|
239
|
-
persistent: input.persistent === true,
|
|
240
|
-
ownerUserId: String(input.ownerUserId || "").trim() || undefined,
|
|
241
|
-
tenantId: String(input.tenantId || "").trim() || undefined,
|
|
242
|
-
projectName: String(input.projectName || "").trim() || undefined,
|
|
243
|
-
};
|
|
244
|
-
ptyProcess.onData((data) => {
|
|
245
|
-
session.lastActiveAt = new Date().toISOString();
|
|
246
|
-
appendOutputBuffer(session, data);
|
|
247
|
-
broadcast(session, { type: "output", data });
|
|
248
|
-
});
|
|
249
|
-
ptyProcess.onExit(({ exitCode, signal }) => {
|
|
250
|
-
session.status = "exited";
|
|
251
|
-
session.exitCode = exitCode;
|
|
252
|
-
session.signal = signal;
|
|
253
|
-
session.lastActiveAt = new Date().toISOString();
|
|
254
|
-
broadcast(session, { type: "exit", exitCode, signal });
|
|
255
|
-
if (session.sockets.size === 0 && !session.persistent) {
|
|
256
|
-
scheduleIdleCleanup(session);
|
|
257
|
-
}
|
|
258
|
-
else if (session.persistent) {
|
|
259
|
-
if (session.idleTimer) {
|
|
260
|
-
clearTimeout(session.idleTimer);
|
|
261
|
-
}
|
|
262
|
-
session.idleTimer = setTimeout(() => {
|
|
263
|
-
closePtySession(session.id, "exited-timeout");
|
|
264
|
-
}, resolvePtyExitedTtlMs());
|
|
265
|
-
}
|
|
266
|
-
});
|
|
267
|
-
ptySessions.set(id, session);
|
|
268
|
-
if (!session.persistent) {
|
|
269
|
-
scheduleIdleCleanup(session);
|
|
270
|
-
}
|
|
271
|
-
injectPtyPreCommand(session, input.preCommand);
|
|
272
|
-
log.info(`created pty session id=${id}, cwd=${workspacePath}, shell=${shell.shell}`);
|
|
273
|
-
return toSummary(session);
|
|
274
|
-
}
|
|
275
|
-
/**
|
|
276
|
-
* 注入 PTY 前置命令。
|
|
277
|
-
* 主流程:忽略空命令 -> 保持已有结尾换行 -> 否则追加一次回车,模拟用户输入执行。
|
|
278
|
-
*/
|
|
279
|
-
function injectPtyPreCommand(session, preCommand) {
|
|
280
|
-
const command = typeof preCommand === "string" ? preCommand : "";
|
|
281
|
-
if (!command.trim()) {
|
|
282
|
-
return;
|
|
283
|
-
}
|
|
284
|
-
const payload = `${command.replace(/\n/g, "\r").replace(/\r+$/g, "")}\r`;
|
|
285
|
-
try {
|
|
286
|
-
session.ptyProcess.write(payload);
|
|
287
|
-
}
|
|
288
|
-
catch (error) {
|
|
289
|
-
const err = error;
|
|
290
|
-
log.warn(`failed to inject pty pre-command sessionId=${session.id}: ${err.message}`);
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
function resolvePtyConnectTokenTtlMs(env = process.env) {
|
|
294
|
-
const raw = String(env.AWS_PTY_CONNECT_TOKEN_TTL_MS || "").trim();
|
|
295
|
-
if (!raw) {
|
|
296
|
-
return DEFAULT_CONNECT_TOKEN_TTL_MS;
|
|
297
|
-
}
|
|
298
|
-
const parsed = Number(raw);
|
|
299
|
-
if (!Number.isFinite(parsed) || parsed < 5_000 || parsed > 10 * 60 * 1000) {
|
|
300
|
-
return DEFAULT_CONNECT_TOKEN_TTL_MS;
|
|
301
|
-
}
|
|
302
|
-
return parsed;
|
|
303
|
-
}
|
|
304
|
-
export function resolvePtyExitedTtlMs(env = process.env) {
|
|
305
|
-
const raw = String(env.AWS_PTY_EXITED_TTL_MS || "").trim();
|
|
306
|
-
if (!raw) {
|
|
307
|
-
return DEFAULT_EXITED_TTL_MS;
|
|
308
|
-
}
|
|
309
|
-
const parsed = Number(raw);
|
|
310
|
-
if (!Number.isFinite(parsed) || parsed < 1_000) {
|
|
311
|
-
return DEFAULT_EXITED_TTL_MS;
|
|
312
|
-
}
|
|
313
|
-
return parsed;
|
|
314
|
-
}
|
|
315
|
-
export function resolveMaxPtySessions(env = process.env) {
|
|
316
|
-
const raw = String(env.AWS_PTY_MAX_SESSIONS || "").trim();
|
|
317
|
-
if (!raw) {
|
|
318
|
-
return DEFAULT_MAX_PTY_SESSIONS;
|
|
319
|
-
}
|
|
320
|
-
const parsed = Number(raw);
|
|
321
|
-
if (!Number.isInteger(parsed) || parsed < 1 || parsed > 100) {
|
|
322
|
-
return DEFAULT_MAX_PTY_SESSIONS;
|
|
323
|
-
}
|
|
324
|
-
return parsed;
|
|
325
|
-
}
|
|
326
|
-
function readCreatePtySessionInput(body) {
|
|
327
|
-
if (!body || typeof body !== "object") {
|
|
328
|
-
return { workspacePath: undefined };
|
|
329
|
-
}
|
|
330
|
-
const record = body;
|
|
331
|
-
return {
|
|
332
|
-
workspacePath: record.workspacePath,
|
|
333
|
-
title: record.title,
|
|
334
|
-
shell: record.shell,
|
|
335
|
-
cols: record.cols,
|
|
336
|
-
rows: record.rows,
|
|
337
|
-
persistent: record.persistent,
|
|
338
|
-
preCommand: record.preCommand,
|
|
339
|
-
ownerUserId: record.ownerUserId,
|
|
340
|
-
tenantId: record.tenantId,
|
|
341
|
-
projectName: record.projectName,
|
|
342
|
-
};
|
|
343
|
-
}
|
|
344
|
-
export function listPtySessions() {
|
|
345
|
-
return Array.from(ptySessions.values()).map(toSummary);
|
|
346
|
-
}
|
|
347
|
-
export function getPtySessionSummary(id) {
|
|
348
|
-
const session = ptySessions.get(id);
|
|
349
|
-
return session ? toSummary(session) : undefined;
|
|
350
|
-
}
|
|
351
|
-
/**
|
|
352
|
-
* 生成短期 PTY 连接令牌。
|
|
353
|
-
* 主流程:确认 session 存在 -> 生成随机 token -> 记录 session 绑定和过期时间。
|
|
354
|
-
*/
|
|
355
|
-
export function createPtyConnectToken(sessionId) {
|
|
356
|
-
if (!ptySessions.has(sessionId)) {
|
|
357
|
-
return undefined;
|
|
358
|
-
}
|
|
359
|
-
const token = `ptyws_${crypto.randomBytes(32).toString("base64url")}`;
|
|
360
|
-
const expiresAtMs = Date.now() + resolvePtyConnectTokenTtlMs();
|
|
361
|
-
ptyConnectTokens.set(token, { sessionId, expiresAt: expiresAtMs });
|
|
362
|
-
return { token, expiresAt: new Date(expiresAtMs).toISOString() };
|
|
363
|
-
}
|
|
364
|
-
function consumePtyConnectToken(sessionId, token) {
|
|
365
|
-
const entry = ptyConnectTokens.get(token);
|
|
366
|
-
if (!entry) {
|
|
367
|
-
log.warn(`[pty-ws] consumePtyConnectToken: token 不存在, sessionId=${sessionId}, ptyConnectTokens.size=${ptyConnectTokens.size}`);
|
|
368
|
-
return false;
|
|
369
|
-
}
|
|
370
|
-
if (entry.expiresAt < Date.now()) {
|
|
371
|
-
ptyConnectTokens.delete(token);
|
|
372
|
-
log.warn(`[pty-ws] consumePtyConnectToken: token 已过期, sessionId=${sessionId}, expiredAt=${new Date(entry.expiresAt).toISOString()}`);
|
|
373
|
-
return false;
|
|
374
|
-
}
|
|
375
|
-
if (entry.sessionId !== sessionId) {
|
|
376
|
-
log.warn(`[pty-ws] consumePtyConnectToken: sessionId 不匹配, expected=${entry.sessionId}, actual=${sessionId}`);
|
|
377
|
-
return false;
|
|
378
|
-
}
|
|
379
|
-
ptyConnectTokens.delete(token);
|
|
380
|
-
log.info(`[pty-ws] consumePtyConnectToken: 成功, sessionId=${sessionId}`);
|
|
381
|
-
return true;
|
|
382
|
-
}
|
|
383
|
-
function deletePtyConnectTokensForSession(sessionId) {
|
|
384
|
-
for (const [token, entry] of ptyConnectTokens.entries()) {
|
|
385
|
-
if (entry.sessionId === sessionId) {
|
|
386
|
-
ptyConnectTokens.delete(token);
|
|
387
|
-
}
|
|
388
|
-
}
|
|
389
|
-
}
|
|
390
|
-
/**
|
|
391
|
-
* 关闭 PTY session。
|
|
392
|
-
* 主流程:关闭连接 -> kill PTY -> 清理定时器和内存索引。
|
|
393
|
-
*/
|
|
394
|
-
export function closePtySession(id, reason = "closed") {
|
|
395
|
-
const session = ptySessions.get(id);
|
|
396
|
-
if (!session) {
|
|
397
|
-
return false;
|
|
398
|
-
}
|
|
399
|
-
cancelIdleCleanup(session);
|
|
400
|
-
deletePtyConnectTokensForSession(id);
|
|
401
|
-
broadcast(session, { type: "status", status: "closing", reason });
|
|
402
|
-
for (const socket of session.sockets) {
|
|
403
|
-
socket.close(1000, reason);
|
|
404
|
-
}
|
|
405
|
-
session.sockets.clear();
|
|
406
|
-
if (session.status === "running") {
|
|
407
|
-
session.ptyProcess.kill();
|
|
408
|
-
}
|
|
409
|
-
ptySessions.delete(id);
|
|
410
|
-
log.info(`closed pty session id=${id}, reason=${reason}`);
|
|
411
|
-
return true;
|
|
412
|
-
}
|
|
413
|
-
export function closeAllPtySessions(reason = "shutdown") {
|
|
414
|
-
for (const id of Array.from(ptySessions.keys())) {
|
|
415
|
-
closePtySession(id, reason);
|
|
416
|
-
}
|
|
417
|
-
}
|
|
418
|
-
export const ptyRouter = createRouter();
|
|
419
|
-
ptyRouter.get("/sessions", validateToken, (_req, res) => {
|
|
420
|
-
res.json({ ok: true, sessions: listPtySessions() });
|
|
421
|
-
});
|
|
422
|
-
ptyRouter.post("/sessions", validateToken, (req, res) => {
|
|
423
|
-
try {
|
|
424
|
-
const session = createPtySession(readCreatePtySessionInput(req.body));
|
|
425
|
-
res.status(201).json({ ok: true, session });
|
|
426
|
-
}
|
|
427
|
-
catch (error) {
|
|
428
|
-
const err = error;
|
|
429
|
-
res.status(400).json({ error: err.message });
|
|
430
|
-
}
|
|
431
|
-
});
|
|
432
|
-
ptyRouter.get("/sessions/:sessionId", validateToken, (req, res) => {
|
|
433
|
-
const session = getPtySessionSummary(req.params.sessionId);
|
|
434
|
-
if (!session) {
|
|
435
|
-
res.status(404).json({ error: "pty session not found" });
|
|
436
|
-
return;
|
|
437
|
-
}
|
|
438
|
-
res.json({ ok: true, session });
|
|
439
|
-
});
|
|
440
|
-
ptyRouter.delete("/sessions/:sessionId", validateToken, (req, res) => {
|
|
441
|
-
const closed = closePtySession(req.params.sessionId, "explicit-close");
|
|
442
|
-
if (!closed) {
|
|
443
|
-
res.status(404).json({ error: "pty session not found" });
|
|
444
|
-
return;
|
|
445
|
-
}
|
|
446
|
-
res.json({ ok: true });
|
|
447
|
-
});
|
|
448
|
-
ptyRouter.post("/sessions/:sessionId/connect-token", validateToken, (req, res) => {
|
|
449
|
-
const token = createPtyConnectToken(req.params.sessionId);
|
|
450
|
-
if (!token) {
|
|
451
|
-
res.status(404).json({ error: "pty session not found" });
|
|
452
|
-
return;
|
|
453
|
-
}
|
|
454
|
-
res.json({ ok: true, ...token });
|
|
455
|
-
});
|
|
456
|
-
function parseWebSocketMessage(raw) {
|
|
457
|
-
const text = raw.toString();
|
|
458
|
-
try {
|
|
459
|
-
return JSON.parse(text);
|
|
460
|
-
}
|
|
461
|
-
catch {
|
|
462
|
-
return { type: "input", data: text };
|
|
463
|
-
}
|
|
464
|
-
}
|
|
465
|
-
function handlePtySocket(session, socket) {
|
|
466
|
-
cancelIdleCleanup(session);
|
|
467
|
-
session.sockets.add(socket);
|
|
468
|
-
session.lastActiveAt = new Date().toISOString();
|
|
469
|
-
sendJson(socket, { type: "status", status: session.status, session: toSummary(session) });
|
|
470
|
-
if (session.outputBuffer) {
|
|
471
|
-
sendJson(socket, { type: "output", data: session.outputBuffer, replay: true });
|
|
472
|
-
}
|
|
473
|
-
socket.on("message", (raw) => {
|
|
474
|
-
const message = parseWebSocketMessage(raw);
|
|
475
|
-
if (!message || typeof message !== "object") {
|
|
476
|
-
return;
|
|
477
|
-
}
|
|
478
|
-
const typed = message;
|
|
479
|
-
const type = String(typed.type || "");
|
|
480
|
-
session.lastActiveAt = new Date().toISOString();
|
|
481
|
-
if (type === "input") {
|
|
482
|
-
session.ptyProcess.write(String(typed.data || ""));
|
|
483
|
-
return;
|
|
484
|
-
}
|
|
485
|
-
if (type === "resize") {
|
|
486
|
-
const cols = normalizeDimension(typed.cols, session.cols);
|
|
487
|
-
const rows = normalizeDimension(typed.rows, session.rows);
|
|
488
|
-
session.cols = cols;
|
|
489
|
-
session.rows = rows;
|
|
490
|
-
session.ptyProcess.resize(cols, rows);
|
|
491
|
-
return;
|
|
492
|
-
}
|
|
493
|
-
if (type === "close") {
|
|
494
|
-
closePtySession(session.id, "client-close");
|
|
495
|
-
return;
|
|
496
|
-
}
|
|
497
|
-
if (type === "ping") {
|
|
498
|
-
sendJson(socket, { type: "pong" });
|
|
499
|
-
}
|
|
500
|
-
});
|
|
501
|
-
socket.on("close", () => {
|
|
502
|
-
session.sockets.delete(socket);
|
|
503
|
-
session.lastActiveAt = new Date().toISOString();
|
|
504
|
-
if (session.sockets.size === 0 && session.status === "running" && !session.persistent) {
|
|
505
|
-
scheduleIdleCleanup(session);
|
|
506
|
-
}
|
|
507
|
-
});
|
|
508
|
-
}
|
|
509
|
-
function extractWsToken(request, requestUrl) {
|
|
510
|
-
const queryToken = requestUrl.searchParams.get("token") || "";
|
|
511
|
-
if (queryToken.trim()) {
|
|
512
|
-
return queryToken.trim();
|
|
513
|
-
}
|
|
514
|
-
const headerToken = request.headers["x-runtime-token"];
|
|
515
|
-
if (Array.isArray(headerToken)) {
|
|
516
|
-
return headerToken[0]?.trim() || "";
|
|
517
|
-
}
|
|
518
|
-
if (typeof headerToken === "string") {
|
|
519
|
-
return headerToken.trim();
|
|
520
|
-
}
|
|
521
|
-
const authorization = String(request.headers.authorization || "");
|
|
522
|
-
const bearerMatch = authorization.match(/^Bearer\s+(.+)$/i);
|
|
523
|
-
return bearerMatch?.[1]?.trim() || "";
|
|
524
|
-
}
|
|
525
|
-
/**
|
|
526
|
-
* 将 PTY WebSocket upgrade 挂到 HTTP server。
|
|
527
|
-
* 主流程:匹配 /pty/sessions/:id/stream -> token 校验 -> session 校验 -> 交给 noServer WSS。
|
|
528
|
-
*/
|
|
529
|
-
export function attachPtyWebSocketServer(server) {
|
|
530
|
-
const wss = new WebSocketServer({ noServer: true });
|
|
531
|
-
server.on("upgrade", (request, socket, head) => {
|
|
532
|
-
const host = request.headers.host || "localhost";
|
|
533
|
-
const requestUrl = new URL(request.url || "/", `http://${host}`);
|
|
534
|
-
const match = requestUrl.pathname.match(/^\/pty\/sessions\/([^/]+)\/stream$/);
|
|
535
|
-
if (!match) {
|
|
536
|
-
return;
|
|
537
|
-
}
|
|
538
|
-
const token = extractWsToken(request, requestUrl);
|
|
539
|
-
const sessionId = decodeURIComponent(match[1] || "");
|
|
540
|
-
const tokenPreview = token ? (token.length > 12 ? token.substring(0, 12) + "..." : token) : "empty";
|
|
541
|
-
log.info(`[pty-ws] upgrade 请求: sessionId=${sessionId}, token=${tokenPreview}, pathname=${requestUrl.pathname}`);
|
|
542
|
-
if (!isRuntimeTokenValid(token) && !consumePtyConnectToken(sessionId, token)) {
|
|
543
|
-
log.warn(`[pty-ws] token 校验失败: sessionId=${sessionId}, token=${tokenPreview}, runtimeTokenValid=${isRuntimeTokenValid(token)}, ptySessions.size=${ptySessions.size}`);
|
|
544
|
-
socket.write("HTTP/1.1 401 Unauthorized\r\n\r\n");
|
|
545
|
-
socket.destroy();
|
|
546
|
-
return;
|
|
547
|
-
}
|
|
548
|
-
const session = ptySessions.get(sessionId);
|
|
549
|
-
if (!session) {
|
|
550
|
-
log.warn(`[pty-ws] session 不存在: sessionId=${sessionId}, ptySessions.size=${ptySessions.size}, keys=${Array.from(ptySessions.keys()).join(",")}`);
|
|
551
|
-
socket.write("HTTP/1.1 404 Not Found\r\n\r\n");
|
|
552
|
-
socket.destroy();
|
|
553
|
-
return;
|
|
554
|
-
}
|
|
555
|
-
log.info(`[pty-ws] handleUpgrade: sessionId=${sessionId}, status=${session.status}, persistent=${session.persistent}, sockets=${session.sockets.size}`);
|
|
556
|
-
wss.handleUpgrade(request, socket, head, (ws) => {
|
|
557
|
-
handlePtySocket(session, ws);
|
|
558
|
-
});
|
|
559
|
-
});
|
|
560
|
-
}
|
|
1
|
+
import O from"node:crypto";import I from"node:fs";import l from"node:path";import{Router as L}from"express";import*as D from"node-pty";import{v4 as M}from"uuid";import U,{WebSocketServer as z}from"ws";import{isRuntimeTokenValid as _,validateToken as h}from"../middleware/auth.js";import{createLogger as R}from"../utils/logger.js";const p=R("pty"),j=80,W=24,x=2e5,$=30*60*1e3,v=5*60*1e3,E=60*1e3,b=8,B=new Set(["false","halt","nologin","reboot","shutdown","sync","true"]),a=new Map,w=new Map;function F(e=process.env){const t=String(e.AWS_PTY_IDLE_TTL_MS||"").trim();if(!t)return $;const r=Number(t);return!Number.isFinite(r)||r<1e3?$:r}function Y(e=process.platform,t=process.env,r=I.existsSync){return e==="win32"?{shell:String(t.ComSpec||t.COMSPEC||"").trim()||"powershell.exe",args:[]}:{shell:[String(t.SHELL||"").trim(),"/bin/bash","/bin/sh"].find(s=>X(s,r))||"/bin/sh",args:[]}}function X(e,t){const r=e.trim();if(!r)return!1;const n=l.basename(r).toLowerCase();return B.has(n)?!1:!l.isAbsolute(r)||t(r)}function H(e,t=process.platform,r=process.env){const n=String(e||"auto").trim();if(!n||n==="auto")return Y(t,r);const i=new Set(["bash","sh","zsh","fish","pwsh","pwsh.exe","powershell","powershell.exe","cmd","cmd.exe"]),s=l.basename(n).toLowerCase();if(!i.has(s))throw new Error(`shell is not allowed: ${n}`);return{shell:n,args:[]}}function J(e,t){const r=l.relative(l.resolve(t),l.resolve(e));return r===""||!r.startsWith("..")&&!l.isAbsolute(r)}function V(e=process.env){return String(e.AWS_PTY_ALLOWED_ROOTS||"").split(l.delimiter).map(t=>t.trim()).filter(Boolean).map(t=>l.resolve(t))}function K(e,t=process.env){const r=String(e||"").trim();if(!r)throw new Error("workspacePath is required");if(!l.isAbsolute(r))throw new Error("workspacePath must be absolute");const n=l.resolve(r);if(!I.statSync(n).isDirectory())throw new Error("workspacePath must be an existing directory");const s=V(t);if(s.length>0&&!s.some(c=>J(n,c)))throw new Error("workspacePath is outside allowed roots");return n}function T(e,t){const r=Number(e);return!Number.isInteger(r)||r<=0?t:Math.min(r,500)}function q(e){return{...e,TERM:e.TERM||"xterm-256color",COLORTERM:e.COLORTERM||"truecolor"}}function G(e,t){e.outputBuffer=`${e.outputBuffer}${t}`,e.outputBuffer.length>x&&(e.outputBuffer=e.outputBuffer.slice(-x))}function g(e){return{id:e.id,title:e.title,workspacePath:e.workspacePath,shell:e.shell,cols:e.cols,rows:e.rows,status:e.status,createdAt:e.createdAt,lastActiveAt:e.lastActiveAt,exitCode:e.exitCode,signal:e.signal,attachedClients:e.sockets.size,ownerUserId:e.ownerUserId,tenantId:e.tenantId,projectName:e.projectName}}function k(e,t){e.readyState===U.OPEN&&e.send(JSON.stringify(t))}function P(e,t){for(const r of e.sockets)k(r,t)}function A(e){e.idleTimer&&clearTimeout(e.idleTimer),e.idleTimer=setTimeout(()=>{e.sockets.size===0&&S(e.id,"idle-timeout")},F())}function C(e){e.idleTimer&&(clearTimeout(e.idleTimer),e.idleTimer=null)}function Q(e){if(a.size>=re())throw new Error("maximum PTY sessions reached");const t=K(e.workspacePath),r=H(e.shell),n=T(e.cols,j),i=T(e.rows,W),s=`pty_${M()}`,c=new Date().toISOString(),m=String(e.title||"").trim()||`Terminal ${a.size+1}`,u=D.spawn(r.shell,r.args,{name:"xterm-256color",cols:n,rows:i,cwd:t,env:q(process.env)}),o={id:s,title:m,workspacePath:t,shell:r.shell,cols:n,rows:i,status:"running",createdAt:c,lastActiveAt:c,attachedClients:0,ptyProcess:u,sockets:new Set,outputBuffer:"",idleTimer:null,persistent:e.persistent===!0,ownerUserId:String(e.ownerUserId||"").trim()||void 0,tenantId:String(e.tenantId||"").trim()||void 0,projectName:String(e.projectName||"").trim()||void 0};return u.onData(f=>{o.lastActiveAt=new Date().toISOString(),G(o,f),P(o,{type:"output",data:f})}),u.onExit(({exitCode:f,signal:d})=>{o.status="exited",o.exitCode=f,o.signal=d,o.lastActiveAt=new Date().toISOString(),P(o,{type:"exit",exitCode:f,signal:d}),o.sockets.size===0&&!o.persistent?A(o):o.persistent&&(o.idleTimer&&clearTimeout(o.idleTimer),o.idleTimer=setTimeout(()=>{S(o.id,"exited-timeout")},te()))}),a.set(s,o),o.persistent||A(o),Z(o,e.preCommand),p.info(`created pty session id=${s}, cwd=${t}, shell=${r.shell}`),g(o)}function Z(e,t){const r=typeof t=="string"?t:"";if(!r.trim())return;const n=`${r.replace(/\n/g,"\r").replace(/\r+$/g,"")}\r`;try{e.ptyProcess.write(n)}catch(i){const s=i;p.warn(`failed to inject pty pre-command sessionId=${e.id}: ${s.message}`)}}function ee(e=process.env){const t=String(e.AWS_PTY_CONNECT_TOKEN_TTL_MS||"").trim();if(!t)return E;const r=Number(t);return!Number.isFinite(r)||r<5e3||r>10*60*1e3?E:r}function te(e=process.env){const t=String(e.AWS_PTY_EXITED_TTL_MS||"").trim();if(!t)return v;const r=Number(t);return!Number.isFinite(r)||r<1e3?v:r}function re(e=process.env){const t=String(e.AWS_PTY_MAX_SESSIONS||"").trim();if(!t)return b;const r=Number(t);return!Number.isInteger(r)||r<1||r>100?b:r}function ne(e){if(!e||typeof e!="object")return{workspacePath:void 0};const t=e;return{workspacePath:t.workspacePath,title:t.title,shell:t.shell,cols:t.cols,rows:t.rows,persistent:t.persistent,preCommand:t.preCommand,ownerUserId:t.ownerUserId,tenantId:t.tenantId,projectName:t.projectName}}function oe(){return Array.from(a.values()).map(g)}function se(e){const t=a.get(e);return t?g(t):void 0}function ie(e){if(!a.has(e))return;const t=`ptyws_${O.randomBytes(32).toString("base64url")}`,r=Date.now()+ee();return w.set(t,{sessionId:e,expiresAt:r}),{token:t,expiresAt:new Date(r).toISOString()}}function ae(e,t){const r=w.get(t);return r?r.expiresAt<Date.now()?(w.delete(t),p.warn(`[pty-ws] consumePtyConnectToken: token \u5DF2\u8FC7\u671F, sessionId=${e}, expiredAt=${new Date(r.expiresAt).toISOString()}`),!1):r.sessionId!==e?(p.warn(`[pty-ws] consumePtyConnectToken: sessionId \u4E0D\u5339\u914D, expected=${r.sessionId}, actual=${e}`),!1):(w.delete(t),p.info(`[pty-ws] consumePtyConnectToken: \u6210\u529F, sessionId=${e}`),!0):(p.warn(`[pty-ws] consumePtyConnectToken: token \u4E0D\u5B58\u5728, sessionId=${e}, ptyConnectTokens.size=${w.size}`),!1)}function ce(e){for(const[t,r]of w.entries())r.sessionId===e&&w.delete(t)}function S(e,t="closed"){const r=a.get(e);if(!r)return!1;C(r),ce(e),P(r,{type:"status",status:"closing",reason:t});for(const n of r.sockets)n.close(1e3,t);return r.sockets.clear(),r.status==="running"&&r.ptyProcess.kill(),a.delete(e),p.info(`closed pty session id=${e}, reason=${t}`),!0}function ge(e="shutdown"){for(const t of Array.from(a.keys()))S(t,e)}const y=L();y.get("/sessions",h,(e,t)=>{t.json({ok:!0,sessions:oe()})}),y.post("/sessions",h,(e,t)=>{try{const r=Q(ne(e.body));t.status(201).json({ok:!0,session:r})}catch(r){const n=r;t.status(400).json({error:n.message})}}),y.get("/sessions/:sessionId",h,(e,t)=>{const r=se(e.params.sessionId);if(!r){t.status(404).json({error:"pty session not found"});return}t.json({ok:!0,session:r})}),y.delete("/sessions/:sessionId",h,(e,t)=>{if(!S(e.params.sessionId,"explicit-close")){t.status(404).json({error:"pty session not found"});return}t.json({ok:!0})}),y.post("/sessions/:sessionId/connect-token",h,(e,t)=>{const r=ie(e.params.sessionId);if(!r){t.status(404).json({error:"pty session not found"});return}t.json({ok:!0,...r})});function ue(e){const t=e.toString();try{return JSON.parse(t)}catch{return{type:"input",data:t}}}function le(e,t){C(e),e.sockets.add(t),e.lastActiveAt=new Date().toISOString(),k(t,{type:"status",status:e.status,session:g(e)}),e.outputBuffer&&k(t,{type:"output",data:e.outputBuffer,replay:!0}),t.on("message",r=>{const n=ue(r);if(!n||typeof n!="object")return;const i=n,s=String(i.type||"");if(e.lastActiveAt=new Date().toISOString(),s==="input"){e.ptyProcess.write(String(i.data||""));return}if(s==="resize"){const c=T(i.cols,e.cols),m=T(i.rows,e.rows);e.cols=c,e.rows=m,e.ptyProcess.resize(c,m);return}if(s==="close"){S(e.id,"client-close");return}s==="ping"&&k(t,{type:"pong"})}),t.on("close",()=>{e.sockets.delete(t),e.lastActiveAt=new Date().toISOString(),e.sockets.size===0&&e.status==="running"&&!e.persistent&&A(e)})}function pe(e,t){const r=t.searchParams.get("token")||"";if(r.trim())return r.trim();const n=e.headers["x-runtime-token"];return Array.isArray(n)?n[0]?.trim()||"":typeof n=="string"?n.trim():String(e.headers.authorization||"").match(/^Bearer\s+(.+)$/i)?.[1]?.trim()||""}function ke(e){const t=new z({noServer:!0});e.on("upgrade",(r,n,i)=>{const s=r.headers.host||"localhost",c=new URL(r.url||"/",`http://${s}`),m=c.pathname.match(/^\/pty\/sessions\/([^/]+)\/stream$/);if(!m)return;const u=pe(r,c),o=decodeURIComponent(m[1]||""),f=u?u.length>12?u.substring(0,12)+"...":u:"empty";if(p.info(`[pty-ws] upgrade \u8BF7\u6C42: sessionId=${o}, token=${f}, pathname=${c.pathname}`),!_(u)&&!ae(o,u)){p.warn(`[pty-ws] token \u6821\u9A8C\u5931\u8D25: sessionId=${o}, token=${f}, runtimeTokenValid=${_(u)}, ptySessions.size=${a.size}`),n.write(`HTTP/1.1 401 Unauthorized\r
|
|
2
|
+
\r
|
|
3
|
+
`),n.destroy();return}const d=a.get(o);if(!d){p.warn(`[pty-ws] session \u4E0D\u5B58\u5728: sessionId=${o}, ptySessions.size=${a.size}, keys=${Array.from(a.keys()).join(",")}`),n.write(`HTTP/1.1 404 Not Found\r
|
|
4
|
+
\r
|
|
5
|
+
`),n.destroy();return}p.info(`[pty-ws] handleUpgrade: sessionId=${o}, status=${d.status}, persistent=${d.persistent}, sockets=${d.sockets.size}`),t.handleUpgrade(r,n,i,N=>{le(d,N)})})}export{ke as attachPtyWebSocketServer,ge as closeAllPtySessions,S as closePtySession,ie as createPtyConnectToken,Q as createPtySession,se as getPtySessionSummary,J as isPathInsideRoot,oe as listPtySessions,y as ptyRouter,a as ptySessions,Y as resolveDefaultShell,re as resolveMaxPtySessions,te as resolvePtyExitedTtlMs,F as resolvePtyIdleTtlMs,K as resolvePtyWorkspacePath,H as resolveRequestedShell};
|
|
6
|
+
|
|
@@ -18,4 +18,3 @@ export interface RuntimeTokenRequestResult {
|
|
|
18
18
|
*/
|
|
19
19
|
export declare function resolveRuntimeTokenRequest(input: RuntimeTokenRequestInput): RuntimeTokenRequestResult;
|
|
20
20
|
export declare function logRuntimeBindingStartupState(): void;
|
|
21
|
-
//# sourceMappingURL=runtime-binding.d.ts.map
|