aws-runtime-bridge 1.0.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 +56 -0
- package/dist/adapter/AdapterRegistry.d.ts +53 -0
- package/dist/adapter/AdapterRegistry.d.ts.map +1 -0
- package/dist/adapter/AdapterRegistry.js +100 -0
- package/dist/adapter/AdapterRegistry.test.d.ts +5 -0
- package/dist/adapter/AdapterRegistry.test.d.ts.map +1 -0
- package/dist/adapter/AdapterRegistry.test.js +109 -0
- package/dist/adapter/ClaudeSdkAdapter.d.ts +120 -0
- package/dist/adapter/ClaudeSdkAdapter.d.ts.map +1 -0
- package/dist/adapter/ClaudeSdkAdapter.js +1140 -0
- package/dist/adapter/ClaudeSdkAdapter.test.d.ts +2 -0
- package/dist/adapter/ClaudeSdkAdapter.test.d.ts.map +1 -0
- package/dist/adapter/ClaudeSdkAdapter.test.js +95 -0
- package/dist/adapter/CodexSdkAdapter.d.ts +48 -0
- package/dist/adapter/CodexSdkAdapter.d.ts.map +1 -0
- package/dist/adapter/CodexSdkAdapter.js +750 -0
- package/dist/adapter/CodexSdkAdapter.test.d.ts +2 -0
- package/dist/adapter/CodexSdkAdapter.test.d.ts.map +1 -0
- package/dist/adapter/CodexSdkAdapter.test.js +245 -0
- package/dist/adapter/OpencodeSdkAdapter.d.ts +45 -0
- package/dist/adapter/OpencodeSdkAdapter.d.ts.map +1 -0
- package/dist/adapter/OpencodeSdkAdapter.js +622 -0
- package/dist/adapter/OpencodeSdkAdapter.test.d.ts +2 -0
- package/dist/adapter/OpencodeSdkAdapter.test.d.ts.map +1 -0
- package/dist/adapter/OpencodeSdkAdapter.test.js +14 -0
- package/dist/adapter/SdkProviderSpi.d.ts +15 -0
- package/dist/adapter/SdkProviderSpi.d.ts.map +1 -0
- package/dist/adapter/SdkProviderSpi.js +46 -0
- package/dist/adapter/adapter.test.d.ts +5 -0
- package/dist/adapter/adapter.test.d.ts.map +1 -0
- package/dist/adapter/adapter.test.js +180 -0
- package/dist/adapter/index.d.ts +11 -0
- package/dist/adapter/index.d.ts.map +1 -0
- package/dist/adapter/index.js +10 -0
- package/dist/adapter/types.d.ts +278 -0
- package/dist/adapter/types.d.ts.map +1 -0
- package/dist/adapter/types.js +278 -0
- package/dist/adapter/types.test.d.ts +2 -0
- package/dist/adapter/types.test.d.ts.map +1 -0
- package/dist/adapter/types.test.js +59 -0
- package/dist/adapters/cc-switch/common.d.ts +52 -0
- package/dist/adapters/cc-switch/common.d.ts.map +1 -0
- package/dist/adapters/cc-switch/common.js +61 -0
- package/dist/adapters/cc-switch/index.d.ts +25 -0
- package/dist/adapters/cc-switch/index.d.ts.map +1 -0
- package/dist/adapters/cc-switch/index.js +51 -0
- package/dist/adapters/cc-switch/mcp-claude.d.ts +15 -0
- package/dist/adapters/cc-switch/mcp-claude.d.ts.map +1 -0
- package/dist/adapters/cc-switch/mcp-claude.js +88 -0
- package/dist/adapters/cc-switch/mcp-claudecode.d.ts +15 -0
- package/dist/adapters/cc-switch/mcp-claudecode.d.ts.map +1 -0
- package/dist/adapters/cc-switch/mcp-claudecode.js +77 -0
- package/dist/adapters/cc-switch/mcp-codex.d.ts +17 -0
- package/dist/adapters/cc-switch/mcp-codex.d.ts.map +1 -0
- package/dist/adapters/cc-switch/mcp-codex.js +248 -0
- package/dist/adapters/cc-switch/mcp-codex.test.d.ts +2 -0
- package/dist/adapters/cc-switch/mcp-codex.test.d.ts.map +1 -0
- package/dist/adapters/cc-switch/mcp-codex.test.js +125 -0
- package/dist/adapters/cc-switch/mcp-opencode.d.ts +23 -0
- package/dist/adapters/cc-switch/mcp-opencode.d.ts.map +1 -0
- package/dist/adapters/cc-switch/mcp-opencode.js +100 -0
- package/dist/adapters/cc-switch/mcp-placeholder.d.ts +14 -0
- package/dist/adapters/cc-switch/mcp-placeholder.d.ts.map +1 -0
- package/dist/adapters/cc-switch/mcp-placeholder.js +19 -0
- package/dist/adapters/cc-switch/skill-claude.d.ts +15 -0
- package/dist/adapters/cc-switch/skill-claude.d.ts.map +1 -0
- package/dist/adapters/cc-switch/skill-claude.js +91 -0
- package/dist/adapters/cc-switch/skill-claudecode.d.ts +15 -0
- package/dist/adapters/cc-switch/skill-claudecode.d.ts.map +1 -0
- package/dist/adapters/cc-switch/skill-claudecode.js +91 -0
- package/dist/adapters/cc-switch/skill-opencode.d.ts +15 -0
- package/dist/adapters/cc-switch/skill-opencode.d.ts.map +1 -0
- package/dist/adapters/cc-switch/skill-opencode.js +95 -0
- package/dist/adapters/cc-switch/skill-placeholder.d.ts +14 -0
- package/dist/adapters/cc-switch/skill-placeholder.d.ts.map +1 -0
- package/dist/adapters/cc-switch/skill-placeholder.js +19 -0
- package/dist/config.d.ts +76 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +109 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +503 -0
- package/dist/middleware/auth.d.ts +12 -0
- package/dist/middleware/auth.d.ts.map +1 -0
- package/dist/middleware/auth.js +18 -0
- package/dist/routes/ai-sources.d.ts +2 -0
- package/dist/routes/ai-sources.d.ts.map +1 -0
- package/dist/routes/ai-sources.js +136 -0
- package/dist/routes/ai-sources.test.d.ts +2 -0
- package/dist/routes/ai-sources.test.d.ts.map +1 -0
- package/dist/routes/ai-sources.test.js +148 -0
- package/dist/routes/aws-mcp.d.ts +10 -0
- package/dist/routes/aws-mcp.d.ts.map +1 -0
- package/dist/routes/aws-mcp.js +74 -0
- package/dist/routes/aws-mcp.test.d.ts +2 -0
- package/dist/routes/aws-mcp.test.d.ts.map +1 -0
- package/dist/routes/aws-mcp.test.js +42 -0
- package/dist/routes/file-browser.d.ts +7 -0
- package/dist/routes/file-browser.d.ts.map +1 -0
- package/dist/routes/file-browser.js +227 -0
- package/dist/routes/file-browser.test.d.ts +5 -0
- package/dist/routes/file-browser.test.d.ts.map +1 -0
- package/dist/routes/file-browser.test.js +88 -0
- package/dist/routes/git.d.ts +7 -0
- package/dist/routes/git.d.ts.map +1 -0
- package/dist/routes/git.js +470 -0
- package/dist/routes/git.test.d.ts +5 -0
- package/dist/routes/git.test.d.ts.map +1 -0
- package/dist/routes/git.test.js +87 -0
- package/dist/routes/instance.d.ts +3 -0
- package/dist/routes/instance.d.ts.map +1 -0
- package/dist/routes/instance.js +170 -0
- package/dist/routes/instance.test.d.ts +5 -0
- package/dist/routes/instance.test.d.ts.map +1 -0
- package/dist/routes/instance.test.js +64 -0
- package/dist/routes/mcp.d.ts +2 -0
- package/dist/routes/mcp.d.ts.map +1 -0
- package/dist/routes/mcp.js +171 -0
- package/dist/routes/mcp.test.d.ts +5 -0
- package/dist/routes/mcp.test.d.ts.map +1 -0
- package/dist/routes/mcp.test.js +84 -0
- package/dist/routes/memory.d.ts +13 -0
- package/dist/routes/memory.d.ts.map +1 -0
- package/dist/routes/memory.js +429 -0
- package/dist/routes/processes.d.ts +7 -0
- package/dist/routes/processes.d.ts.map +1 -0
- package/dist/routes/processes.js +245 -0
- package/dist/routes/properties.d.ts +7 -0
- package/dist/routes/properties.d.ts.map +1 -0
- package/dist/routes/properties.js +72 -0
- package/dist/routes/properties.test.d.ts +5 -0
- package/dist/routes/properties.test.d.ts.map +1 -0
- package/dist/routes/properties.test.js +72 -0
- package/dist/routes/sessions.d.ts +7 -0
- package/dist/routes/sessions.d.ts.map +1 -0
- package/dist/routes/sessions.js +808 -0
- package/dist/routes/sessions.test.d.ts +5 -0
- package/dist/routes/sessions.test.d.ts.map +1 -0
- package/dist/routes/sessions.test.js +70 -0
- package/dist/routes/skills.d.ts +2 -0
- package/dist/routes/skills.d.ts.map +1 -0
- package/dist/routes/skills.js +162 -0
- package/dist/routes/skills.test.d.ts +5 -0
- package/dist/routes/skills.test.d.ts.map +1 -0
- package/dist/routes/skills.test.js +42 -0
- package/dist/routes/terminal.d.ts +18 -0
- package/dist/routes/terminal.d.ts.map +1 -0
- package/dist/routes/terminal.js +663 -0
- package/dist/routes/terminal.test.d.ts +2 -0
- package/dist/routes/terminal.test.d.ts.map +1 -0
- package/dist/routes/terminal.test.js +91 -0
- package/dist/routes/yml.d.ts +7 -0
- package/dist/routes/yml.d.ts.map +1 -0
- package/dist/routes/yml.js +223 -0
- package/dist/routes/yml.test.d.ts +5 -0
- package/dist/routes/yml.test.d.ts.map +1 -0
- package/dist/routes/yml.test.js +58 -0
- package/dist/services/agent-process-manager.d.ts +241 -0
- package/dist/services/agent-process-manager.d.ts.map +1 -0
- package/dist/services/agent-process-manager.js +762 -0
- package/dist/services/auto-register.d.ts +94 -0
- package/dist/services/auto-register.d.ts.map +1 -0
- package/dist/services/auto-register.js +510 -0
- package/dist/services/aws-client-agent-mcp.d.ts +26 -0
- package/dist/services/aws-client-agent-mcp.d.ts.map +1 -0
- package/dist/services/aws-client-agent-mcp.js +142 -0
- package/dist/services/aws-client-agent-mcp.test.d.ts +2 -0
- package/dist/services/aws-client-agent-mcp.test.d.ts.map +1 -0
- package/dist/services/aws-client-agent-mcp.test.js +89 -0
- package/dist/services/aws-mcp-http.d.ts +11 -0
- package/dist/services/aws-mcp-http.d.ts.map +1 -0
- package/dist/services/aws-mcp-http.js +225 -0
- package/dist/services/aws-mcp-http.test.d.ts +2 -0
- package/dist/services/aws-mcp-http.test.d.ts.map +1 -0
- package/dist/services/aws-mcp-http.test.js +27 -0
- package/dist/services/cc-switch-sdk.d.ts +18 -0
- package/dist/services/cc-switch-sdk.d.ts.map +1 -0
- package/dist/services/cc-switch-sdk.js +117 -0
- package/dist/services/easytier-manager.d.ts +106 -0
- package/dist/services/easytier-manager.d.ts.map +1 -0
- package/dist/services/easytier-manager.js +331 -0
- package/dist/services/easytier-manager.test.d.ts +5 -0
- package/dist/services/easytier-manager.test.d.ts.map +1 -0
- package/dist/services/easytier-manager.test.js +98 -0
- package/dist/services/instance-init-service.d.ts +35 -0
- package/dist/services/instance-init-service.d.ts.map +1 -0
- package/dist/services/instance-init-service.js +190 -0
- package/dist/services/instance-service.d.ts +88 -0
- package/dist/services/instance-service.d.ts.map +1 -0
- package/dist/services/instance-service.js +236 -0
- package/dist/services/instance-state.d.ts +36 -0
- package/dist/services/instance-state.d.ts.map +1 -0
- package/dist/services/instance-state.js +79 -0
- package/dist/services/instance-state.test.d.ts +2 -0
- package/dist/services/instance-state.test.d.ts.map +1 -0
- package/dist/services/instance-state.test.js +213 -0
- package/dist/services/memory-service.d.ts +195 -0
- package/dist/services/memory-service.d.ts.map +1 -0
- package/dist/services/memory-service.js +650 -0
- package/dist/services/orphan-monitor.d.ts +94 -0
- package/dist/services/orphan-monitor.d.ts.map +1 -0
- package/dist/services/orphan-monitor.js +321 -0
- package/dist/services/process-detector.d.ts +175 -0
- package/dist/services/process-detector.d.ts.map +1 -0
- package/dist/services/process-detector.js +992 -0
- package/dist/services/process-registry.d.ts +208 -0
- package/dist/services/process-registry.d.ts.map +1 -0
- package/dist/services/process-registry.js +354 -0
- package/dist/services/session-lookup.d.ts +20 -0
- package/dist/services/session-lookup.d.ts.map +1 -0
- package/dist/services/session-lookup.js +43 -0
- package/dist/services/session-output.d.ts +56 -0
- package/dist/services/session-output.d.ts.map +1 -0
- package/dist/services/session-output.js +122 -0
- package/dist/services/session-output.test.d.ts +5 -0
- package/dist/services/session-output.test.d.ts.map +1 -0
- package/dist/services/session-output.test.js +68 -0
- package/dist/services/terminal-persistence.d.ts +51 -0
- package/dist/services/terminal-persistence.d.ts.map +1 -0
- package/dist/services/terminal-persistence.js +125 -0
- package/dist/services/terminal-persistence.test.d.ts +5 -0
- package/dist/services/terminal-persistence.test.d.ts.map +1 -0
- package/dist/services/terminal-persistence.test.js +88 -0
- package/dist/services/tool-installer.d.ts +15 -0
- package/dist/services/tool-installer.d.ts.map +1 -0
- package/dist/services/tool-installer.js +297 -0
- package/dist/services/tool-installer.test.d.ts +2 -0
- package/dist/services/tool-installer.test.d.ts.map +1 -0
- package/dist/services/tool-installer.test.js +102 -0
- package/dist/services/user-api-key-service.d.ts +28 -0
- package/dist/services/user-api-key-service.d.ts.map +1 -0
- package/dist/services/user-api-key-service.js +75 -0
- package/dist/services/workspace-files.d.ts +85 -0
- package/dist/services/workspace-files.d.ts.map +1 -0
- package/dist/services/workspace-files.js +224 -0
- package/dist/services/workspace-files.test.d.ts +2 -0
- package/dist/services/workspace-files.test.d.ts.map +1 -0
- package/dist/services/workspace-files.test.js +117 -0
- package/dist/types.d.ts +233 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +1 -0
- package/dist/utils/file-utils.d.ts +13 -0
- package/dist/utils/file-utils.d.ts.map +1 -0
- package/dist/utils/file-utils.js +140 -0
- package/dist/utils/file-utils.test.d.ts +2 -0
- package/dist/utils/file-utils.test.d.ts.map +1 -0
- package/dist/utils/file-utils.test.js +201 -0
- package/dist/utils/logger.d.ts +39 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +110 -0
- package/dist/utils/logger.test.d.ts +2 -0
- package/dist/utils/logger.test.d.ts.map +1 -0
- package/dist/utils/logger.test.js +93 -0
- package/dist/utils/mcp-utils.d.ts +73 -0
- package/dist/utils/mcp-utils.d.ts.map +1 -0
- package/dist/utils/mcp-utils.js +165 -0
- package/dist/utils/path-utils.d.ts +24 -0
- package/dist/utils/path-utils.d.ts.map +1 -0
- package/dist/utils/path-utils.js +44 -0
- package/dist/utils/validation.d.ts +23 -0
- package/dist/utils/validation.d.ts.map +1 -0
- package/dist/utils/validation.js +53 -0
- package/dist/utils/validation.test.d.ts +2 -0
- package/dist/utils/validation.test.d.ts.map +1 -0
- package/dist/utils/validation.test.js +88 -0
- package/dist/utils/yaml-utils.d.ts +73 -0
- package/dist/utils/yaml-utils.d.ts.map +1 -0
- package/dist/utils/yaml-utils.js +309 -0
- package/dist/utils/yaml-utils.test.d.ts +2 -0
- package/dist/utils/yaml-utils.test.d.ts.map +1 -0
- package/dist/utils/yaml-utils.test.js +363 -0
- package/package/aws-client-agent-mcp/README.md +288 -0
- package/package/aws-client-agent-mcp/dist/activity-reporter.d.ts +150 -0
- package/package/aws-client-agent-mcp/dist/activity-reporter.d.ts.map +1 -0
- package/package/aws-client-agent-mcp/dist/activity-reporter.js +353 -0
- package/package/aws-client-agent-mcp/dist/activity-reporter.js.map +1 -0
- package/package/aws-client-agent-mcp/dist/activity-reporter.test.d.ts +2 -0
- package/package/aws-client-agent-mcp/dist/activity-reporter.test.d.ts.map +1 -0
- package/package/aws-client-agent-mcp/dist/activity-reporter.test.js +75 -0
- package/package/aws-client-agent-mcp/dist/activity-reporter.test.js.map +1 -0
- package/package/aws-client-agent-mcp/dist/activity-types.d.ts +96 -0
- package/package/aws-client-agent-mcp/dist/activity-types.d.ts.map +1 -0
- package/package/aws-client-agent-mcp/dist/activity-types.js +141 -0
- package/package/aws-client-agent-mcp/dist/activity-types.js.map +1 -0
- package/package/aws-client-agent-mcp/dist/agent-client.d.ts +165 -0
- package/package/aws-client-agent-mcp/dist/agent-client.d.ts.map +1 -0
- package/package/aws-client-agent-mcp/dist/agent-client.js +588 -0
- package/package/aws-client-agent-mcp/dist/agent-client.js.map +1 -0
- package/package/aws-client-agent-mcp/dist/agent-client.test.d.ts +2 -0
- package/package/aws-client-agent-mcp/dist/agent-client.test.d.ts.map +1 -0
- package/package/aws-client-agent-mcp/dist/agent-client.test.js +534 -0
- package/package/aws-client-agent-mcp/dist/agent-client.test.js.map +1 -0
- package/package/aws-client-agent-mcp/dist/config.d.ts +21 -0
- package/package/aws-client-agent-mcp/dist/config.d.ts.map +1 -0
- package/package/aws-client-agent-mcp/dist/config.js +67 -0
- package/package/aws-client-agent-mcp/dist/config.js.map +1 -0
- package/package/aws-client-agent-mcp/dist/config.test.d.ts +2 -0
- package/package/aws-client-agent-mcp/dist/config.test.d.ts.map +1 -0
- package/package/aws-client-agent-mcp/dist/config.test.js +139 -0
- package/package/aws-client-agent-mcp/dist/config.test.js.map +1 -0
- package/package/aws-client-agent-mcp/dist/constants.d.ts +15 -0
- package/package/aws-client-agent-mcp/dist/constants.d.ts.map +1 -0
- package/package/aws-client-agent-mcp/dist/constants.js +19 -0
- package/package/aws-client-agent-mcp/dist/constants.js.map +1 -0
- package/package/aws-client-agent-mcp/dist/http-client.d.ts +27 -0
- package/package/aws-client-agent-mcp/dist/http-client.d.ts.map +1 -0
- package/package/aws-client-agent-mcp/dist/http-client.js +65 -0
- package/package/aws-client-agent-mcp/dist/http-client.js.map +1 -0
- package/package/aws-client-agent-mcp/dist/http-client.test.d.ts +2 -0
- package/package/aws-client-agent-mcp/dist/http-client.test.d.ts.map +1 -0
- package/package/aws-client-agent-mcp/dist/http-client.test.js +228 -0
- package/package/aws-client-agent-mcp/dist/http-client.test.js.map +1 -0
- package/package/aws-client-agent-mcp/dist/index.d.ts +14 -0
- package/package/aws-client-agent-mcp/dist/index.d.ts.map +1 -0
- package/package/aws-client-agent-mcp/dist/index.js +30 -0
- package/package/aws-client-agent-mcp/dist/index.js.map +1 -0
- package/package/aws-client-agent-mcp/dist/logger.d.ts +7 -0
- package/package/aws-client-agent-mcp/dist/logger.d.ts.map +1 -0
- package/package/aws-client-agent-mcp/dist/logger.js +19 -0
- package/package/aws-client-agent-mcp/dist/logger.js.map +1 -0
- package/package/aws-client-agent-mcp/dist/mcp-server.d.ts +77 -0
- package/package/aws-client-agent-mcp/dist/mcp-server.d.ts.map +1 -0
- package/package/aws-client-agent-mcp/dist/mcp-server.js +427 -0
- package/package/aws-client-agent-mcp/dist/mcp-server.js.map +1 -0
- package/package/aws-client-agent-mcp/dist/mcp-server.test.d.ts +2 -0
- package/package/aws-client-agent-mcp/dist/mcp-server.test.d.ts.map +1 -0
- package/package/aws-client-agent-mcp/dist/mcp-server.test.js +624 -0
- package/package/aws-client-agent-mcp/dist/mcp-server.test.js.map +1 -0
- package/package/aws-client-agent-mcp/dist/mcp-tools.d.ts +78 -0
- package/package/aws-client-agent-mcp/dist/mcp-tools.d.ts.map +1 -0
- package/package/aws-client-agent-mcp/dist/mcp-tools.js +420 -0
- package/package/aws-client-agent-mcp/dist/mcp-tools.js.map +1 -0
- package/package/aws-client-agent-mcp/dist/memory-store.d.ts +61 -0
- package/package/aws-client-agent-mcp/dist/memory-store.d.ts.map +1 -0
- package/package/aws-client-agent-mcp/dist/memory-store.js +268 -0
- package/package/aws-client-agent-mcp/dist/memory-store.js.map +1 -0
- package/package/aws-client-agent-mcp/dist/memory-store.test.d.ts +2 -0
- package/package/aws-client-agent-mcp/dist/memory-store.test.d.ts.map +1 -0
- package/package/aws-client-agent-mcp/dist/memory-store.test.js +164 -0
- package/package/aws-client-agent-mcp/dist/memory-store.test.js.map +1 -0
- package/package/aws-client-agent-mcp/dist/message-buffer.d.ts +74 -0
- package/package/aws-client-agent-mcp/dist/message-buffer.d.ts.map +1 -0
- package/package/aws-client-agent-mcp/dist/message-buffer.js +159 -0
- package/package/aws-client-agent-mcp/dist/message-buffer.js.map +1 -0
- package/package/aws-client-agent-mcp/dist/message-buffer.test.d.ts +2 -0
- package/package/aws-client-agent-mcp/dist/message-buffer.test.d.ts.map +1 -0
- package/package/aws-client-agent-mcp/dist/message-buffer.test.js +44 -0
- package/package/aws-client-agent-mcp/dist/message-buffer.test.js.map +1 -0
- package/package/aws-client-agent-mcp/dist/messageContent.d.ts +53 -0
- package/package/aws-client-agent-mcp/dist/messageContent.d.ts.map +1 -0
- package/package/aws-client-agent-mcp/dist/messageContent.js +125 -0
- package/package/aws-client-agent-mcp/dist/messageContent.js.map +1 -0
- package/package/aws-client-agent-mcp/dist/orchestration-tools.d.ts +19 -0
- package/package/aws-client-agent-mcp/dist/orchestration-tools.d.ts.map +1 -0
- package/package/aws-client-agent-mcp/dist/orchestration-tools.js +317 -0
- package/package/aws-client-agent-mcp/dist/orchestration-tools.js.map +1 -0
- package/package/aws-client-agent-mcp/dist/status-reporter.d.ts +66 -0
- package/package/aws-client-agent-mcp/dist/status-reporter.d.ts.map +1 -0
- package/package/aws-client-agent-mcp/dist/status-reporter.js +220 -0
- package/package/aws-client-agent-mcp/dist/status-reporter.js.map +1 -0
- package/package/aws-client-agent-mcp/dist/status-reporter.test.d.ts +2 -0
- package/package/aws-client-agent-mcp/dist/status-reporter.test.d.ts.map +1 -0
- package/package/aws-client-agent-mcp/dist/status-reporter.test.js +45 -0
- package/package/aws-client-agent-mcp/dist/status-reporter.test.js.map +1 -0
- package/package/aws-client-agent-mcp/dist/types.d.ts +286 -0
- package/package/aws-client-agent-mcp/dist/types.d.ts.map +1 -0
- package/package/aws-client-agent-mcp/dist/types.js +9 -0
- package/package/aws-client-agent-mcp/dist/types.js.map +1 -0
- package/package/aws-client-agent-mcp/dist/user-config-reader.d.ts +63 -0
- package/package/aws-client-agent-mcp/dist/user-config-reader.d.ts.map +1 -0
- package/package/aws-client-agent-mcp/dist/user-config-reader.js +161 -0
- package/package/aws-client-agent-mcp/dist/user-config-reader.js.map +1 -0
- package/package/aws-client-agent-mcp/dist/websocket-client.d.ts +94 -0
- package/package/aws-client-agent-mcp/dist/websocket-client.d.ts.map +1 -0
- package/package/aws-client-agent-mcp/dist/websocket-client.js +316 -0
- package/package/aws-client-agent-mcp/dist/websocket-client.js.map +1 -0
- package/package/aws-client-agent-mcp/dist/websocket-client.test.d.ts +2 -0
- package/package/aws-client-agent-mcp/dist/websocket-client.test.d.ts.map +1 -0
- package/package/aws-client-agent-mcp/dist/websocket-client.test.js +191 -0
- package/package/aws-client-agent-mcp/dist/websocket-client.test.js.map +1 -0
- package/package/aws-client-agent-mcp/package.json +51 -0
- package/package/cc-switch-sdk/README.md +541 -0
- package/package/cc-switch-sdk/dist/adapters/common.d.ts +38 -0
- package/package/cc-switch-sdk/dist/adapters/common.d.ts.map +1 -0
- package/package/cc-switch-sdk/dist/adapters/common.js +47 -0
- package/package/cc-switch-sdk/dist/adapters/index.d.ts +5 -0
- package/package/cc-switch-sdk/dist/adapters/index.d.ts.map +1 -0
- package/package/cc-switch-sdk/dist/adapters/index.js +28 -0
- package/package/cc-switch-sdk/dist/adapters/mcp-claude.d.ts +10 -0
- package/package/cc-switch-sdk/dist/adapters/mcp-claude.d.ts.map +1 -0
- package/package/cc-switch-sdk/dist/adapters/mcp-claude.js +39 -0
- package/package/cc-switch-sdk/dist/adapters/mcp-claudecode.d.ts +10 -0
- package/package/cc-switch-sdk/dist/adapters/mcp-claudecode.d.ts.map +1 -0
- package/package/cc-switch-sdk/dist/adapters/mcp-claudecode.js +40 -0
- package/package/cc-switch-sdk/dist/adapters/mcp-opencode.d.ts +18 -0
- package/package/cc-switch-sdk/dist/adapters/mcp-opencode.d.ts.map +1 -0
- package/package/cc-switch-sdk/dist/adapters/mcp-opencode.js +63 -0
- package/package/cc-switch-sdk/dist/adapters/mcp-opencode.test.d.ts +2 -0
- package/package/cc-switch-sdk/dist/adapters/mcp-opencode.test.d.ts.map +1 -0
- package/package/cc-switch-sdk/dist/adapters/mcp-opencode.test.js +86 -0
- package/package/cc-switch-sdk/dist/adapters/mcp-placeholder.d.ts +9 -0
- package/package/cc-switch-sdk/dist/adapters/mcp-placeholder.d.ts.map +1 -0
- package/package/cc-switch-sdk/dist/adapters/mcp-placeholder.js +14 -0
- package/package/cc-switch-sdk/dist/adapters/skill-claude.d.ts +10 -0
- package/package/cc-switch-sdk/dist/adapters/skill-claude.d.ts.map +1 -0
- package/package/cc-switch-sdk/dist/adapters/skill-claude.js +51 -0
- package/package/cc-switch-sdk/dist/adapters/skill-claudecode.d.ts +10 -0
- package/package/cc-switch-sdk/dist/adapters/skill-claudecode.d.ts.map +1 -0
- package/package/cc-switch-sdk/dist/adapters/skill-claudecode.js +51 -0
- package/package/cc-switch-sdk/dist/adapters/skill-opencode.d.ts +10 -0
- package/package/cc-switch-sdk/dist/adapters/skill-opencode.d.ts.map +1 -0
- package/package/cc-switch-sdk/dist/adapters/skill-opencode.js +51 -0
- package/package/cc-switch-sdk/dist/adapters/skill-placeholder.d.ts +9 -0
- package/package/cc-switch-sdk/dist/adapters/skill-placeholder.d.ts.map +1 -0
- package/package/cc-switch-sdk/dist/adapters/skill-placeholder.js +14 -0
- package/package/cc-switch-sdk/dist/constants.d.ts +9 -0
- package/package/cc-switch-sdk/dist/constants.d.ts.map +1 -0
- package/package/cc-switch-sdk/dist/constants.js +54 -0
- package/package/cc-switch-sdk/dist/errors.d.ts +6 -0
- package/package/cc-switch-sdk/dist/errors.d.ts.map +1 -0
- package/package/cc-switch-sdk/dist/errors.js +8 -0
- package/package/cc-switch-sdk/dist/index.d.ts +11 -0
- package/package/cc-switch-sdk/dist/index.d.ts.map +1 -0
- package/package/cc-switch-sdk/dist/index.js +9 -0
- package/package/cc-switch-sdk/dist/schemas.d.ts +8 -0
- package/package/cc-switch-sdk/dist/schemas.d.ts.map +1 -0
- package/package/cc-switch-sdk/dist/schemas.js +37 -0
- package/package/cc-switch-sdk/dist/sdk.d.ts +91 -0
- package/package/cc-switch-sdk/dist/sdk.d.ts.map +1 -0
- package/package/cc-switch-sdk/dist/sdk.js +427 -0
- package/package/cc-switch-sdk/dist/services/ai-config-service.d.ts +75 -0
- package/package/cc-switch-sdk/dist/services/ai-config-service.d.ts.map +1 -0
- package/package/cc-switch-sdk/dist/services/ai-config-service.js +280 -0
- package/package/cc-switch-sdk/dist/services/instance-service.d.ts +78 -0
- package/package/cc-switch-sdk/dist/services/instance-service.d.ts.map +1 -0
- package/package/cc-switch-sdk/dist/services/instance-service.js +180 -0
- package/package/cc-switch-sdk/dist/services/mcp-model.d.ts +17 -0
- package/package/cc-switch-sdk/dist/services/mcp-model.d.ts.map +1 -0
- package/package/cc-switch-sdk/dist/services/mcp-model.js +34 -0
- package/package/cc-switch-sdk/dist/services/mcp-service.d.ts +18 -0
- package/package/cc-switch-sdk/dist/services/mcp-service.d.ts.map +1 -0
- package/package/cc-switch-sdk/dist/services/mcp-service.js +9 -0
- package/package/cc-switch-sdk/dist/services/skill-model.d.ts +17 -0
- package/package/cc-switch-sdk/dist/services/skill-model.d.ts.map +1 -0
- package/package/cc-switch-sdk/dist/services/skill-model.js +38 -0
- package/package/cc-switch-sdk/dist/services/skill-service.d.ts +17 -0
- package/package/cc-switch-sdk/dist/services/skill-service.d.ts.map +1 -0
- package/package/cc-switch-sdk/dist/services/skill-service.js +9 -0
- package/package/cc-switch-sdk/dist/state.d.ts +4 -0
- package/package/cc-switch-sdk/dist/state.d.ts.map +1 -0
- package/package/cc-switch-sdk/dist/state.js +19 -0
- package/package/cc-switch-sdk/dist/types.d.ts +75 -0
- package/package/cc-switch-sdk/dist/types.d.ts.map +1 -0
- package/package/cc-switch-sdk/dist/types.js +1 -0
- package/package/cc-switch-sdk/dist/utils/fs.d.ts +10 -0
- package/package/cc-switch-sdk/dist/utils/fs.d.ts.map +1 -0
- package/package/cc-switch-sdk/dist/utils/fs.js +91 -0
- package/package/cc-switch-sdk/dist/utils/id.d.ts +4 -0
- package/package/cc-switch-sdk/dist/utils/id.d.ts.map +1 -0
- package/package/cc-switch-sdk/dist/utils/id.js +12 -0
- package/package/cc-switch-sdk/package.json +31 -0
- package/package.json +73 -0
|
@@ -0,0 +1,762 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent Process Manager
|
|
3
|
+
*
|
|
4
|
+
* Core lifecycle manager for agent processes on the bridge machine.
|
|
5
|
+
* Provides comprehensive process management including creation, discovery,
|
|
6
|
+
* monitoring, termination, and orphan reclamation capabilities.
|
|
7
|
+
*/
|
|
8
|
+
import { execSync } from 'node:child_process';
|
|
9
|
+
import os from 'node:os';
|
|
10
|
+
import { createLogger } from '../utils/logger.js';
|
|
11
|
+
import { getProcessRegistry } from './process-registry.js';
|
|
12
|
+
import { isProcessRunning, findClaudeCodeProcesses, findOrphanProcessByAgentId, terminateProcessTree, waitForProcessExit, checkProcessHealth, } from './process-detector.js';
|
|
13
|
+
import { loadPersistedSessions } from './terminal-persistence.js';
|
|
14
|
+
const log = createLogger('agent-process-manager');
|
|
15
|
+
/**
|
|
16
|
+
* Agent Process Manager
|
|
17
|
+
*
|
|
18
|
+
* Manages the complete lifecycle of agent processes including:
|
|
19
|
+
* - Creation: Register and verify new processes
|
|
20
|
+
* - Discovery: Scan for managed, orphan, and unknown processes
|
|
21
|
+
* - Monitoring: Health checks and heartbeat tracking
|
|
22
|
+
* - Termination: Graceful stop with escalation strategy
|
|
23
|
+
* - Orphan Reclamation: Adopt or terminate orphan processes
|
|
24
|
+
*/
|
|
25
|
+
export class AgentProcessManager {
|
|
26
|
+
/**
|
|
27
|
+
* Private constructor - use getAgentProcessManager() for singleton access
|
|
28
|
+
*/
|
|
29
|
+
constructor() {
|
|
30
|
+
this.registry = getProcessRegistry();
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Get the singleton instance
|
|
34
|
+
*/
|
|
35
|
+
static getInstance() {
|
|
36
|
+
if (AgentProcessManager.instance === null) {
|
|
37
|
+
AgentProcessManager.instance = new AgentProcessManager();
|
|
38
|
+
}
|
|
39
|
+
return AgentProcessManager.instance;
|
|
40
|
+
}
|
|
41
|
+
// =============================================================================
|
|
42
|
+
// CREATION PHASE
|
|
43
|
+
// =============================================================================
|
|
44
|
+
/**
|
|
45
|
+
* Start a new process and register it in the process registry
|
|
46
|
+
*
|
|
47
|
+
* Flow:
|
|
48
|
+
* 1. Register process with state='creating'
|
|
49
|
+
* 2. Verify it's running
|
|
50
|
+
* 3. Update state to 'running'
|
|
51
|
+
*
|
|
52
|
+
* @param config - Process configuration
|
|
53
|
+
* @throws Error if process registration fails or process is not running
|
|
54
|
+
*/
|
|
55
|
+
async startProcess(config) {
|
|
56
|
+
const { agentId, sessionId, pid, mode, workspacePath, command } = config;
|
|
57
|
+
log.info(`[startProcess] Starting process: agentId=${agentId}, pid=${pid}, mode=${mode}`);
|
|
58
|
+
// Step 1: Register with 'creating' state
|
|
59
|
+
await this.registry.register({
|
|
60
|
+
agentId,
|
|
61
|
+
sessionId,
|
|
62
|
+
pid,
|
|
63
|
+
mode,
|
|
64
|
+
state: 'creating',
|
|
65
|
+
workspacePath,
|
|
66
|
+
command,
|
|
67
|
+
});
|
|
68
|
+
// Step 2: Verify process is running
|
|
69
|
+
log.debug(`[startProcess] Verifying process is running: pid=${pid}`);
|
|
70
|
+
const isRunning = isProcessRunning(pid);
|
|
71
|
+
if (!isRunning) {
|
|
72
|
+
log.error(`[startProcess] Process not running after registration: agentId=${agentId}, pid=${pid}`);
|
|
73
|
+
// Mark as terminated since it's not actually running
|
|
74
|
+
await this.registry.markTerminated(agentId);
|
|
75
|
+
throw new Error(`Process ${pid} is not running`);
|
|
76
|
+
}
|
|
77
|
+
// Step 3: Update state to 'running'
|
|
78
|
+
await this.registry.update(agentId, { state: 'running' });
|
|
79
|
+
await this.registry.updateHeartbeat(agentId);
|
|
80
|
+
log.info(`[startProcess] Process started successfully: agentId=${agentId}, pid=${pid}`);
|
|
81
|
+
}
|
|
82
|
+
// =============================================================================
|
|
83
|
+
// DISCOVERY PHASE
|
|
84
|
+
// =============================================================================
|
|
85
|
+
/**
|
|
86
|
+
* Discover all agent processes on the system
|
|
87
|
+
*
|
|
88
|
+
* Scans OS for all agent processes, compares with registry, and returns
|
|
89
|
+
* a list of discovered processes with their management status.
|
|
90
|
+
*
|
|
91
|
+
* @returns Array of discovered processes with management status
|
|
92
|
+
*/
|
|
93
|
+
async discoverAllProcesses() {
|
|
94
|
+
log.debug('[discoverAllProcesses] Scanning for all agent processes');
|
|
95
|
+
// Get all processes from OS
|
|
96
|
+
const osProcesses = findClaudeCodeProcesses();
|
|
97
|
+
const managedProcesses = this.registry.getAll();
|
|
98
|
+
const discovered = [];
|
|
99
|
+
// Create a set of managed PIDs for quick lookup
|
|
100
|
+
const managedPids = new Set(managedProcesses.map(p => p.pid));
|
|
101
|
+
const managedAgentIds = new Set(managedProcesses.map(p => p.agentId));
|
|
102
|
+
// Check each OS process
|
|
103
|
+
for (const proc of osProcesses) {
|
|
104
|
+
const isManagedByPid = managedPids.has(proc.pid);
|
|
105
|
+
const isManagedByAgentId = proc.agentId && managedAgentIds.has(proc.agentId);
|
|
106
|
+
if (isManagedByPid || isManagedByAgentId) {
|
|
107
|
+
// Process is managed - find its record
|
|
108
|
+
const record = managedProcesses.find(p => p.pid === proc.pid || p.agentId === proc.agentId);
|
|
109
|
+
discovered.push({
|
|
110
|
+
...proc,
|
|
111
|
+
managementStatus: 'managed',
|
|
112
|
+
sessionId: record?.sessionId,
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
else if (proc.agentId) {
|
|
116
|
+
// Process has agentId but not in registry - it's an orphan
|
|
117
|
+
discovered.push({
|
|
118
|
+
...proc,
|
|
119
|
+
managementStatus: 'orphan',
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
// Unknown agent process
|
|
124
|
+
discovered.push({
|
|
125
|
+
...proc,
|
|
126
|
+
managementStatus: 'unknown',
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
// Also check registry processes that might not be in OS scan
|
|
131
|
+
for (const record of managedProcesses) {
|
|
132
|
+
const found = discovered.find(p => p.pid === record.pid);
|
|
133
|
+
if (!found) {
|
|
134
|
+
// Process is in registry but not found in OS scan
|
|
135
|
+
const isAlive = isProcessRunning(record.pid);
|
|
136
|
+
discovered.push({
|
|
137
|
+
pid: record.pid,
|
|
138
|
+
command: record.command,
|
|
139
|
+
agentId: record.agentId,
|
|
140
|
+
managementStatus: isAlive ? 'managed' : 'orphan',
|
|
141
|
+
sessionId: record.sessionId,
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
log.debug(`[discoverAllProcesses] Discovered ${discovered.length} processes: ` +
|
|
146
|
+
`${discovered.filter(p => p.managementStatus === 'managed').length} managed, ` +
|
|
147
|
+
`${discovered.filter(p => p.managementStatus === 'orphan').length} orphans, ` +
|
|
148
|
+
`${discovered.filter(p => p.managementStatus === 'unknown').length} unknown`);
|
|
149
|
+
return discovered;
|
|
150
|
+
}
|
|
151
|
+
// =============================================================================
|
|
152
|
+
// MONITORING PHASE
|
|
153
|
+
// =============================================================================
|
|
154
|
+
/**
|
|
155
|
+
* Check health of all registered processes
|
|
156
|
+
*
|
|
157
|
+
* Updates heartbeat and health status in registry for each managed process.
|
|
158
|
+
*
|
|
159
|
+
* @returns Map of agentId to health status
|
|
160
|
+
*/
|
|
161
|
+
async healthCheckAll() {
|
|
162
|
+
log.debug('[healthCheckAll] Starting health check for all processes');
|
|
163
|
+
const results = new Map();
|
|
164
|
+
const managedProcesses = this.registry.getAll();
|
|
165
|
+
const promises = managedProcesses.map(async (record) => {
|
|
166
|
+
const health = await this.healthCheck(record.agentId);
|
|
167
|
+
results.set(record.agentId, health);
|
|
168
|
+
return health;
|
|
169
|
+
});
|
|
170
|
+
await Promise.all(promises);
|
|
171
|
+
log.debug(`[healthCheckAll] Completed health check for ${managedProcesses.length} processes`);
|
|
172
|
+
return results;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Check health of a single process
|
|
176
|
+
*
|
|
177
|
+
* @param agentId - Agent ID to check
|
|
178
|
+
* @returns Health status of the process
|
|
179
|
+
*/
|
|
180
|
+
async healthCheck(agentId) {
|
|
181
|
+
const record = this.registry.get(agentId);
|
|
182
|
+
if (!record) {
|
|
183
|
+
log.warn(`[healthCheck] Process not found in registry: agentId=${agentId}`);
|
|
184
|
+
return {
|
|
185
|
+
pid: -1,
|
|
186
|
+
agentId,
|
|
187
|
+
alive: false,
|
|
188
|
+
cpu: 0,
|
|
189
|
+
memoryMB: 0,
|
|
190
|
+
status: 'dead',
|
|
191
|
+
lastUpdate: new Date(),
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
// Check process health
|
|
195
|
+
const health = await checkProcessHealth(record.pid, agentId);
|
|
196
|
+
// Update registry with health info
|
|
197
|
+
const healthStatus = {
|
|
198
|
+
cpu: health.cpu,
|
|
199
|
+
memoryMB: health.memoryMB,
|
|
200
|
+
status: health.status,
|
|
201
|
+
};
|
|
202
|
+
await this.registry.updateHealth(agentId, healthStatus);
|
|
203
|
+
if (health.alive) {
|
|
204
|
+
await this.registry.updateHeartbeat(agentId);
|
|
205
|
+
}
|
|
206
|
+
else if (record.state !== 'terminated' && record.state !== 'orphaned') {
|
|
207
|
+
// Process died unexpectedly - mark as orphaned
|
|
208
|
+
log.warn(`[healthCheck] Process died unexpectedly: agentId=${agentId}, pid=${record.pid}`);
|
|
209
|
+
await this.registry.markOrphaned(agentId);
|
|
210
|
+
}
|
|
211
|
+
return health;
|
|
212
|
+
}
|
|
213
|
+
// =============================================================================
|
|
214
|
+
// TERMINATION PHASE (with escalation strategy)
|
|
215
|
+
// =============================================================================
|
|
216
|
+
/**
|
|
217
|
+
* Stop a process with graceful escalation strategy
|
|
218
|
+
*
|
|
219
|
+
* Escalation levels:
|
|
220
|
+
* Level 1: SIGTERM → wait 3s
|
|
221
|
+
* Level 2: taskkill /T /F (Win) or kill -9 (Unix) → wait 3s
|
|
222
|
+
* Level 3: terminateProcessTree → wait 5s
|
|
223
|
+
* Level 4: mark as "unstoppable", return failure
|
|
224
|
+
*
|
|
225
|
+
* @param agentId - Agent ID to stop
|
|
226
|
+
* @returns Termination result with details
|
|
227
|
+
*/
|
|
228
|
+
async stopProcess(agentId) {
|
|
229
|
+
const record = this.registry.get(agentId);
|
|
230
|
+
if (!record) {
|
|
231
|
+
return {
|
|
232
|
+
success: false,
|
|
233
|
+
agentId,
|
|
234
|
+
pid: -1,
|
|
235
|
+
level: 0,
|
|
236
|
+
terminated: 0,
|
|
237
|
+
failed: 0,
|
|
238
|
+
message: `Process not found in registry: ${agentId}`,
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
const { pid } = record;
|
|
242
|
+
log.info(`[stopProcess] Stopping process: agentId=${agentId}, pid=${pid}`);
|
|
243
|
+
// Check if already stopped
|
|
244
|
+
if (!isProcessRunning(pid)) {
|
|
245
|
+
log.info(`[stopProcess] Process already stopped: agentId=${agentId}, pid=${pid}`);
|
|
246
|
+
await this.registry.markTerminated(agentId);
|
|
247
|
+
return {
|
|
248
|
+
success: true,
|
|
249
|
+
agentId,
|
|
250
|
+
pid,
|
|
251
|
+
level: 0,
|
|
252
|
+
terminated: 1,
|
|
253
|
+
failed: 0,
|
|
254
|
+
message: 'Process was already stopped',
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
// Update state to 'stopping'
|
|
258
|
+
await this.registry.update(agentId, { state: 'stopping' });
|
|
259
|
+
// Level 1: SIGTERM
|
|
260
|
+
log.debug(`[stopProcess] Level 1: Sending SIGTERM to pid=${pid}`);
|
|
261
|
+
const sigtermResult = this.sendSigterm(pid);
|
|
262
|
+
if (sigtermResult) {
|
|
263
|
+
const exited = waitForProcessExit(pid, 3000);
|
|
264
|
+
if (exited) {
|
|
265
|
+
await this.registry.markTerminated(agentId);
|
|
266
|
+
log.info(`[stopProcess] Process stopped at Level 1: agentId=${agentId}, pid=${pid}`);
|
|
267
|
+
return {
|
|
268
|
+
success: true,
|
|
269
|
+
agentId,
|
|
270
|
+
pid,
|
|
271
|
+
level: 1,
|
|
272
|
+
terminated: 1,
|
|
273
|
+
failed: 0,
|
|
274
|
+
message: 'Process terminated with SIGTERM',
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
// Level 2: Force kill (taskkill /F or kill -9)
|
|
279
|
+
log.debug(`[stopProcess] Level 2: Force killing pid=${pid}`);
|
|
280
|
+
const forceKillResult = this.sendForceKill(pid);
|
|
281
|
+
if (forceKillResult) {
|
|
282
|
+
const exited = waitForProcessExit(pid, 3000);
|
|
283
|
+
if (exited) {
|
|
284
|
+
await this.registry.markTerminated(agentId);
|
|
285
|
+
log.info(`[stopProcess] Process stopped at Level 2: agentId=${agentId}, pid=${pid}`);
|
|
286
|
+
return {
|
|
287
|
+
success: true,
|
|
288
|
+
agentId,
|
|
289
|
+
pid,
|
|
290
|
+
level: 2,
|
|
291
|
+
terminated: 1,
|
|
292
|
+
failed: 0,
|
|
293
|
+
message: 'Process terminated with force kill',
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
// Level 3: Terminate process tree
|
|
298
|
+
log.debug(`[stopProcess] Level 3: Terminating process tree for pid=${pid}`);
|
|
299
|
+
const treeResult = terminateProcessTree(pid);
|
|
300
|
+
// Wait for process tree to terminate
|
|
301
|
+
const treeExited = waitForProcessExit(pid, 5000);
|
|
302
|
+
if (treeExited) {
|
|
303
|
+
await this.registry.markTerminated(agentId);
|
|
304
|
+
log.info(`[stopProcess] Process stopped at Level 3: agentId=${agentId}, pid=${pid}, terminated=${treeResult.terminated}, failed=${treeResult.failed}`);
|
|
305
|
+
return {
|
|
306
|
+
success: true,
|
|
307
|
+
agentId,
|
|
308
|
+
pid,
|
|
309
|
+
level: 3,
|
|
310
|
+
terminated: treeResult.terminated,
|
|
311
|
+
failed: treeResult.failed,
|
|
312
|
+
message: `Process tree terminated (${treeResult.terminated} processes)`,
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
// Level 4: Process is unstoppable
|
|
316
|
+
log.error(`[stopProcess] Level 4: Process is unstoppable: agentId=${agentId}, pid=${pid}`);
|
|
317
|
+
// Check final state
|
|
318
|
+
const finalStatus = isProcessRunning(pid) ? 'still running' : 'terminated';
|
|
319
|
+
if (finalStatus === 'terminated') {
|
|
320
|
+
await this.registry.markTerminated(agentId);
|
|
321
|
+
return {
|
|
322
|
+
success: true,
|
|
323
|
+
agentId,
|
|
324
|
+
pid,
|
|
325
|
+
level: 4,
|
|
326
|
+
terminated: 1,
|
|
327
|
+
failed: 0,
|
|
328
|
+
message: 'Process eventually terminated after all escalation levels',
|
|
329
|
+
};
|
|
330
|
+
}
|
|
331
|
+
return {
|
|
332
|
+
success: false,
|
|
333
|
+
agentId,
|
|
334
|
+
pid,
|
|
335
|
+
level: 4,
|
|
336
|
+
terminated: treeResult.terminated,
|
|
337
|
+
failed: treeResult.failed + 1,
|
|
338
|
+
message: 'Process could not be terminated - marked as unstoppable',
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* Send SIGTERM to a process
|
|
343
|
+
*/
|
|
344
|
+
sendSigterm(pid) {
|
|
345
|
+
try {
|
|
346
|
+
process.kill(pid, 'SIGTERM');
|
|
347
|
+
return true;
|
|
348
|
+
}
|
|
349
|
+
catch (error) {
|
|
350
|
+
log.debug(`[sendSigterm] Failed to send SIGTERM to ${pid}:`, error);
|
|
351
|
+
return false;
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* Send force kill (SIGKILL on Unix, taskkill /F on Windows)
|
|
356
|
+
*/
|
|
357
|
+
sendForceKill(pid) {
|
|
358
|
+
try {
|
|
359
|
+
if (os.platform() === 'win32') {
|
|
360
|
+
execSync(`taskkill /PID ${pid} /F`, { encoding: 'utf8', timeout: 5000, windowsHide: true });
|
|
361
|
+
}
|
|
362
|
+
else {
|
|
363
|
+
process.kill(pid, 'SIGKILL');
|
|
364
|
+
}
|
|
365
|
+
return true;
|
|
366
|
+
}
|
|
367
|
+
catch (error) {
|
|
368
|
+
log.debug(`[sendForceKill] Failed to force kill ${pid}:`, error);
|
|
369
|
+
return false;
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
/**
|
|
373
|
+
* Force kill a process immediately using terminateProcessTree
|
|
374
|
+
*
|
|
375
|
+
* This bypasses the graceful escalation and uses the most aggressive
|
|
376
|
+
* termination method immediately.
|
|
377
|
+
*
|
|
378
|
+
* @param agentId - Agent ID to force kill
|
|
379
|
+
* @returns Termination result
|
|
380
|
+
*/
|
|
381
|
+
async forceKill(agentId) {
|
|
382
|
+
const record = this.registry.get(agentId);
|
|
383
|
+
if (!record) {
|
|
384
|
+
return {
|
|
385
|
+
success: false,
|
|
386
|
+
agentId,
|
|
387
|
+
pid: -1,
|
|
388
|
+
level: 0,
|
|
389
|
+
terminated: 0,
|
|
390
|
+
failed: 0,
|
|
391
|
+
message: `Process not found in registry: ${agentId}`,
|
|
392
|
+
};
|
|
393
|
+
}
|
|
394
|
+
const { pid } = record;
|
|
395
|
+
log.info(`[forceKill] Force killing process: agentId=${agentId}, pid=${pid}`);
|
|
396
|
+
// Update state
|
|
397
|
+
await this.registry.update(agentId, { state: 'stopping' });
|
|
398
|
+
// Direct process tree termination
|
|
399
|
+
const result = terminateProcessTree(pid);
|
|
400
|
+
// Wait briefly for termination
|
|
401
|
+
const exited = waitForProcessExit(pid, 2000);
|
|
402
|
+
if (exited) {
|
|
403
|
+
await this.registry.markTerminated(agentId);
|
|
404
|
+
log.info(`[forceKill] Process terminated: agentId=${agentId}, pid=${pid}`);
|
|
405
|
+
return {
|
|
406
|
+
success: true,
|
|
407
|
+
agentId,
|
|
408
|
+
pid,
|
|
409
|
+
level: 3, // Same level as tree termination
|
|
410
|
+
terminated: result.terminated,
|
|
411
|
+
failed: result.failed,
|
|
412
|
+
message: `Process force killed (${result.terminated} processes terminated)`,
|
|
413
|
+
};
|
|
414
|
+
}
|
|
415
|
+
log.error(`[forceKill] Process could not be force killed: agentId=${agentId}, pid=${pid}`);
|
|
416
|
+
return {
|
|
417
|
+
success: false,
|
|
418
|
+
agentId,
|
|
419
|
+
pid,
|
|
420
|
+
level: 3,
|
|
421
|
+
terminated: result.terminated,
|
|
422
|
+
failed: result.failed + 1,
|
|
423
|
+
message: 'Force kill failed - process may require manual intervention',
|
|
424
|
+
};
|
|
425
|
+
}
|
|
426
|
+
// =============================================================================
|
|
427
|
+
// ORPHAN RECLAMATION
|
|
428
|
+
// =============================================================================
|
|
429
|
+
/**
|
|
430
|
+
* Reclaim an orphan process by agentId
|
|
431
|
+
*
|
|
432
|
+
* Finds an orphan process by agentId, and either:
|
|
433
|
+
* - Adopts it into the registry (if found and not managed)
|
|
434
|
+
* - Terminates it (if adoption fails or process is problematic)
|
|
435
|
+
*
|
|
436
|
+
* @param agentId - Agent ID to find and reclaim
|
|
437
|
+
* @returns Reclamation result
|
|
438
|
+
*/
|
|
439
|
+
async reclaimOrphan(agentId) {
|
|
440
|
+
log.info(`[reclaimOrphan] Attempting to reclaim orphan: agentId=${agentId}`);
|
|
441
|
+
// Check if already managed
|
|
442
|
+
if (this.registry.isManaged(agentId)) {
|
|
443
|
+
const record = this.registry.get(agentId);
|
|
444
|
+
if (!record) {
|
|
445
|
+
return { success: false, pid: -1, action: 'failed' };
|
|
446
|
+
}
|
|
447
|
+
log.info(`[reclaimOrphan] Process already managed: agentId=${agentId}, pid=${record.pid}`);
|
|
448
|
+
return {
|
|
449
|
+
success: true,
|
|
450
|
+
pid: record.pid,
|
|
451
|
+
action: 'adopted',
|
|
452
|
+
};
|
|
453
|
+
}
|
|
454
|
+
// Find orphan process
|
|
455
|
+
const orphan = findOrphanProcessByAgentId(agentId);
|
|
456
|
+
if (!orphan) {
|
|
457
|
+
log.warn(`[reclaimOrphan] No orphan process found: agentId=${agentId}`);
|
|
458
|
+
return {
|
|
459
|
+
success: false,
|
|
460
|
+
pid: -1,
|
|
461
|
+
action: 'failed',
|
|
462
|
+
};
|
|
463
|
+
}
|
|
464
|
+
// Verify the process is still running
|
|
465
|
+
if (!isProcessRunning(orphan.pid)) {
|
|
466
|
+
log.warn(`[reclaimOrphan] Orphan process not running: agentId=${agentId}, pid=${orphan.pid}`);
|
|
467
|
+
return {
|
|
468
|
+
success: false,
|
|
469
|
+
pid: orphan.pid,
|
|
470
|
+
action: 'failed',
|
|
471
|
+
};
|
|
472
|
+
}
|
|
473
|
+
// Check if this PID is already managed by a different agent
|
|
474
|
+
if (this.registry.isManagedByPid(orphan.pid)) {
|
|
475
|
+
const existingRecord = this.registry.getByPid(orphan.pid);
|
|
476
|
+
if (!existingRecord) {
|
|
477
|
+
// Race condition - PID was just removed, proceed with adoption inline
|
|
478
|
+
try {
|
|
479
|
+
const sessions = await loadPersistedSessions();
|
|
480
|
+
const session = sessions.find(s => s.agentId === agentId);
|
|
481
|
+
await this.registry.register({
|
|
482
|
+
agentId,
|
|
483
|
+
sessionId: session?.sessionId || `reclaimed-${Date.now()}`,
|
|
484
|
+
pid: orphan.pid,
|
|
485
|
+
mode: session?.mode || 'sdk',
|
|
486
|
+
state: 'running',
|
|
487
|
+
workspacePath: session?.workspacePath || orphan.cwd || '',
|
|
488
|
+
command: orphan.command || session?.command || '',
|
|
489
|
+
metadata: { reclaimedAt: new Date().toISOString(), wasOrphan: true },
|
|
490
|
+
});
|
|
491
|
+
return { success: true, pid: orphan.pid, action: 'adopted' };
|
|
492
|
+
}
|
|
493
|
+
catch {
|
|
494
|
+
terminateProcessTree(orphan.pid);
|
|
495
|
+
return { success: false, pid: orphan.pid, action: 'terminated' };
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
log.warn(`[reclaimOrphan] PID already managed by different agent: pid=${orphan.pid}, existingAgentId=${existingRecord.agentId}`);
|
|
499
|
+
// If it's the same agentId, just update - this shouldn't happen but handle it
|
|
500
|
+
if (existingRecord.agentId === agentId) {
|
|
501
|
+
return {
|
|
502
|
+
success: true,
|
|
503
|
+
pid: orphan.pid,
|
|
504
|
+
action: 'adopted',
|
|
505
|
+
};
|
|
506
|
+
}
|
|
507
|
+
// Different agent - this is a conflict, terminate the orphan
|
|
508
|
+
log.warn(`[reclaimOrphan] Terminating conflicting orphan: agentId=${agentId}, pid=${orphan.pid}`);
|
|
509
|
+
terminateProcessTree(orphan.pid);
|
|
510
|
+
return {
|
|
511
|
+
success: true,
|
|
512
|
+
pid: orphan.pid,
|
|
513
|
+
action: 'terminated',
|
|
514
|
+
};
|
|
515
|
+
}
|
|
516
|
+
// Try to adopt the orphan - load persisted sessions for metadata
|
|
517
|
+
const sessions = await loadPersistedSessions();
|
|
518
|
+
const session = sessions.find(s => s.agentId === agentId);
|
|
519
|
+
try {
|
|
520
|
+
await this.registry.register({
|
|
521
|
+
agentId,
|
|
522
|
+
sessionId: session?.sessionId || `reclaimed-${Date.now()}`,
|
|
523
|
+
pid: orphan.pid,
|
|
524
|
+
mode: session?.mode || 'sdk',
|
|
525
|
+
state: 'running',
|
|
526
|
+
workspacePath: session?.workspacePath || orphan.cwd || '',
|
|
527
|
+
command: orphan.command || session?.command || '',
|
|
528
|
+
metadata: {
|
|
529
|
+
reclaimedAt: new Date().toISOString(),
|
|
530
|
+
wasOrphan: true,
|
|
531
|
+
},
|
|
532
|
+
});
|
|
533
|
+
log.info(`[reclaimOrphan] Successfully adopted orphan: agentId=${agentId}, pid=${orphan.pid}`);
|
|
534
|
+
return {
|
|
535
|
+
success: true,
|
|
536
|
+
pid: orphan.pid,
|
|
537
|
+
action: 'adopted',
|
|
538
|
+
};
|
|
539
|
+
}
|
|
540
|
+
catch (error) {
|
|
541
|
+
log.error(`[reclaimOrphan] Failed to adopt orphan: agentId=${agentId}, pid=${orphan.pid}`, error);
|
|
542
|
+
// If adoption fails, terminate the process
|
|
543
|
+
terminateProcessTree(orphan.pid);
|
|
544
|
+
return {
|
|
545
|
+
success: false,
|
|
546
|
+
pid: orphan.pid,
|
|
547
|
+
action: 'terminated',
|
|
548
|
+
};
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
/**
|
|
552
|
+
* Scan all orphans and attempt to reclaim each
|
|
553
|
+
*
|
|
554
|
+
* @returns Array of reclamation results
|
|
555
|
+
*/
|
|
556
|
+
async scanAndReclaimAll() {
|
|
557
|
+
log.info('[scanAndReclaimAll] Scanning for all orphan processes');
|
|
558
|
+
const results = [];
|
|
559
|
+
// Load persisted sessions to find potential orphans
|
|
560
|
+
const sessions = await loadPersistedSessions();
|
|
561
|
+
// Find all agent processes
|
|
562
|
+
const allProcesses = findClaudeCodeProcesses();
|
|
563
|
+
const managedPids = new Set(this.registry.getAll().map(p => p.pid));
|
|
564
|
+
// Identify orphan processes
|
|
565
|
+
const orphans = allProcesses.filter(proc => {
|
|
566
|
+
// Not managed by PID
|
|
567
|
+
if (managedPids.has(proc.pid))
|
|
568
|
+
return false;
|
|
569
|
+
// Has agentId but not managed - this is an orphan
|
|
570
|
+
if (proc.agentId && !this.registry.isManaged(proc.agentId)) {
|
|
571
|
+
return true;
|
|
572
|
+
}
|
|
573
|
+
return false;
|
|
574
|
+
});
|
|
575
|
+
log.info(`[scanAndReclaimAll] Found ${orphans.length} orphan processes`);
|
|
576
|
+
// Try to reclaim each orphan
|
|
577
|
+
for (const orphan of orphans) {
|
|
578
|
+
if (!orphan.agentId) {
|
|
579
|
+
// No agentId - can't reclaim, just terminate
|
|
580
|
+
log.warn(`[scanAndReclaimAll] Orphan without agentId, terminating: pid=${orphan.pid}`);
|
|
581
|
+
terminateProcessTree(orphan.pid);
|
|
582
|
+
results.push({
|
|
583
|
+
agentId: 'unknown',
|
|
584
|
+
pid: orphan.pid,
|
|
585
|
+
action: 'terminated',
|
|
586
|
+
});
|
|
587
|
+
continue;
|
|
588
|
+
}
|
|
589
|
+
const result = await this.reclaimOrphan(orphan.agentId);
|
|
590
|
+
results.push({
|
|
591
|
+
agentId: orphan.agentId,
|
|
592
|
+
pid: result.pid,
|
|
593
|
+
action: result.action,
|
|
594
|
+
});
|
|
595
|
+
}
|
|
596
|
+
// Also check persisted sessions for orphans that might not be in the process list
|
|
597
|
+
for (const session of sessions) {
|
|
598
|
+
if (session.agentId && !this.registry.isManaged(session.agentId)) {
|
|
599
|
+
const orphanByAgentId = findOrphanProcessByAgentId(session.agentId);
|
|
600
|
+
if (orphanByAgentId) {
|
|
601
|
+
const result = await this.reclaimOrphan(session.agentId);
|
|
602
|
+
// Avoid duplicates
|
|
603
|
+
const existing = results.find(r => r.agentId === session.agentId);
|
|
604
|
+
if (!existing) {
|
|
605
|
+
results.push({
|
|
606
|
+
agentId: session.agentId,
|
|
607
|
+
pid: result.pid,
|
|
608
|
+
action: result.action,
|
|
609
|
+
});
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
log.info(`[scanAndReclaimAll] Reclamation complete: ${results.length} processes processed`);
|
|
615
|
+
return results;
|
|
616
|
+
}
|
|
617
|
+
// =============================================================================
|
|
618
|
+
// REGISTRY INTEGRATION
|
|
619
|
+
// =============================================================================
|
|
620
|
+
/**
|
|
621
|
+
* Mark a process as orphaned in the registry
|
|
622
|
+
*
|
|
623
|
+
* @param agentId - Agent ID to mark
|
|
624
|
+
* @returns Whether the operation succeeded
|
|
625
|
+
*/
|
|
626
|
+
async markOrphaned(agentId) {
|
|
627
|
+
log.info(`[markOrphaned] Marking process as orphaned: agentId=${agentId}`);
|
|
628
|
+
return await this.registry.markOrphaned(agentId);
|
|
629
|
+
}
|
|
630
|
+
/**
|
|
631
|
+
* Check if a process is managed
|
|
632
|
+
*
|
|
633
|
+
* @param agentId - Agent ID to check
|
|
634
|
+
* @returns Whether the process is managed
|
|
635
|
+
*/
|
|
636
|
+
isManaged(agentId) {
|
|
637
|
+
return this.registry.isManaged(agentId);
|
|
638
|
+
}
|
|
639
|
+
/**
|
|
640
|
+
* Get all managed processes
|
|
641
|
+
*
|
|
642
|
+
* @returns Array of all managed process records
|
|
643
|
+
*/
|
|
644
|
+
getAllManagedProcesses() {
|
|
645
|
+
return this.registry.getAll();
|
|
646
|
+
}
|
|
647
|
+
/**
|
|
648
|
+
* Get managed processes by state
|
|
649
|
+
*
|
|
650
|
+
* @param state - Process state to filter by
|
|
651
|
+
* @returns Array of process records matching the state
|
|
652
|
+
*/
|
|
653
|
+
getManagedProcessesByState(state) {
|
|
654
|
+
return this.registry.getByState(state);
|
|
655
|
+
}
|
|
656
|
+
/**
|
|
657
|
+
* Find processes running on the machine that are NOT in registry
|
|
658
|
+
*
|
|
659
|
+
* @returns Array of unmanaged process info
|
|
660
|
+
*/
|
|
661
|
+
async getUnmanagedProcesses() {
|
|
662
|
+
const allProcesses = findClaudeCodeProcesses();
|
|
663
|
+
const managedPids = new Set(this.registry.getAll().map(p => p.pid));
|
|
664
|
+
const managedAgentIds = new Set(this.registry.getAll().map(p => p.agentId));
|
|
665
|
+
return allProcesses.filter(proc => {
|
|
666
|
+
// Not managed by PID
|
|
667
|
+
if (managedPids.has(proc.pid))
|
|
668
|
+
return false;
|
|
669
|
+
// Not managed by agentId
|
|
670
|
+
if (proc.agentId && managedAgentIds.has(proc.agentId))
|
|
671
|
+
return false;
|
|
672
|
+
return true;
|
|
673
|
+
});
|
|
674
|
+
}
|
|
675
|
+
/**
|
|
676
|
+
* Rebuild the process registry from persisted sessions (e.g. on startup)
|
|
677
|
+
*
|
|
678
|
+
* Scans all persisted sessions, checks which processes are still running,
|
|
679
|
+
* and registers them with appropriate state.
|
|
680
|
+
*
|
|
681
|
+
* @param sessions - Array of persisted session data
|
|
682
|
+
*/
|
|
683
|
+
async rebuildRegistry(sessions) {
|
|
684
|
+
log.info(`[rebuildRegistry] Rebuilding registry from ${sessions.length} persisted sessions`);
|
|
685
|
+
// Clear existing registry
|
|
686
|
+
await this.registry.clear();
|
|
687
|
+
for (const session of sessions) {
|
|
688
|
+
if (!session.pid) {
|
|
689
|
+
log.debug(`[rebuildRegistry] Skipping session without PID: agentId=${session.agentId}`);
|
|
690
|
+
continue;
|
|
691
|
+
}
|
|
692
|
+
const isRunning = isProcessRunning(session.pid);
|
|
693
|
+
const state = isRunning ? 'running' : 'unknown';
|
|
694
|
+
try {
|
|
695
|
+
await this.registry.register({
|
|
696
|
+
agentId: session.agentId,
|
|
697
|
+
sessionId: session.sessionId,
|
|
698
|
+
pid: session.pid,
|
|
699
|
+
mode: session.mode || 'pty',
|
|
700
|
+
state,
|
|
701
|
+
workspacePath: session.workspacePath || '',
|
|
702
|
+
command: session.command || '',
|
|
703
|
+
metadata: {
|
|
704
|
+
rebuiltAt: new Date().toISOString(),
|
|
705
|
+
wasRunningOnStartup: isRunning,
|
|
706
|
+
},
|
|
707
|
+
});
|
|
708
|
+
log.debug(`[rebuildRegistry] Registered: agentId=${session.agentId}, pid=${session.pid}, state=${state}`);
|
|
709
|
+
}
|
|
710
|
+
catch (error) {
|
|
711
|
+
log.warn(`[rebuildRegistry] Failed to register: agentId=${session.agentId}`, error);
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
const stats = this.registry.getStats();
|
|
715
|
+
log.info(`[rebuildRegistry] Registry rebuilt: total=${stats.total}, running=${stats.running}, unknown=${stats.unknown}`);
|
|
716
|
+
}
|
|
717
|
+
/**
|
|
718
|
+
* Get process statistics
|
|
719
|
+
*
|
|
720
|
+
* @returns Statistics for all managed processes
|
|
721
|
+
*/
|
|
722
|
+
getStats() {
|
|
723
|
+
return this.registry.getStats();
|
|
724
|
+
}
|
|
725
|
+
/**
|
|
726
|
+
* Remove a process from registry
|
|
727
|
+
*
|
|
728
|
+
* @param agentId - Agent ID to remove
|
|
729
|
+
* @returns Whether the operation succeeded
|
|
730
|
+
*/
|
|
731
|
+
async removeProcess(agentId) {
|
|
732
|
+
log.info(`[removeProcess] Removing process from registry: agentId=${agentId}`);
|
|
733
|
+
return await this.registry.remove(agentId);
|
|
734
|
+
}
|
|
735
|
+
/**
|
|
736
|
+
* Get a single process record
|
|
737
|
+
*
|
|
738
|
+
* @param agentId - Agent ID to get
|
|
739
|
+
* @returns Process record or undefined
|
|
740
|
+
*/
|
|
741
|
+
getProcess(agentId) {
|
|
742
|
+
return this.registry.get(agentId);
|
|
743
|
+
}
|
|
744
|
+
/**
|
|
745
|
+
* Get a process record by PID
|
|
746
|
+
*
|
|
747
|
+
* @param pid - Process ID to get
|
|
748
|
+
* @returns Process record or undefined
|
|
749
|
+
*/
|
|
750
|
+
getProcessByPid(pid) {
|
|
751
|
+
return this.registry.getByPid(pid);
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
AgentProcessManager.instance = null;
|
|
755
|
+
/**
|
|
756
|
+
* Get the AgentProcessManager singleton instance
|
|
757
|
+
*
|
|
758
|
+
* @returns AgentProcessManager instance
|
|
759
|
+
*/
|
|
760
|
+
export function getAgentProcessManager() {
|
|
761
|
+
return AgentProcessManager.getInstance();
|
|
762
|
+
}
|