@phuetz/code-buddy 2.0.0 → 2.2.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.fr.md +56 -0
- package/README.md +74 -16
- package/codebuddy-runtime.json +5 -5
- package/dist/agent/codebuddy-agent.d.ts +18 -0
- package/dist/agent/codebuddy-agent.js +45 -8
- package/dist/agent/execution/agent-executor.d.ts +0 -9
- package/dist/agent/execution/agent-executor.js +176 -12
- package/dist/agent/execution/context-pipeline.d.ts +9 -0
- package/dist/agent/execution/context-pipeline.js +64 -2
- package/dist/agent/execution/tool-loop-guard.d.ts +76 -0
- package/dist/agent/execution/tool-loop-guard.js +165 -0
- package/dist/agent/execution/tool-selection-strategy.d.ts +7 -0
- package/dist/agent/execution/tool-selection-strategy.js +32 -2
- package/dist/agent/facades/session-facade.d.ts +0 -6
- package/dist/agent/facades/session-facade.js +0 -45
- package/dist/agent/hermes-claw-migrate.d.ts +0 -21
- package/dist/agent/hermes-claw-migrate.js +9 -4
- package/dist/agent/hermes-protocol-gateways.js +8 -1
- package/dist/agent/repo-profiler.js +17 -4
- package/dist/agent/self-improvement/authored-tool-runtime.js +10 -2
- package/dist/agent/self-improvement/evolution/ast-novelty.d.ts +5 -0
- package/dist/agent/self-improvement/evolution/ast-novelty.js +58 -23
- package/dist/agent/self-improvement/evolution/code-variant-store.d.ts +3 -0
- package/dist/agent/self-improvement/evolution/evolution-engine.js +2 -0
- package/dist/agent/self-improvement/evolution/protected-paths.js +6 -0
- package/dist/agent/self-improvement/evolution/variant-fitness.d.ts +13 -2
- package/dist/agent/self-improvement/evolution/variant-fitness.js +184 -58
- package/dist/agent/self-improvement/evolution/worktree-scorer.d.ts +2 -0
- package/dist/agent/self-improvement/evolution/worktree-scorer.js +15 -0
- package/dist/agent/self-improvement/evolutionary-archive.d.ts +2 -1
- package/dist/agent/self-improvement/evolutionary-archive.js +34 -5
- package/dist/agent/self-improvement/proposal-store.d.ts +1 -0
- package/dist/agent/self-improvement/proposal-store.js +79 -17
- package/dist/agent/self-improvement/skill-apply-journal.d.ts +44 -0
- package/dist/agent/self-improvement/skill-apply-journal.js +178 -0
- package/dist/agent/self-improvement/skill-behavior-benchmark.d.ts +3 -0
- package/dist/agent/self-improvement/skill-behavior-benchmark.js +19 -0
- package/dist/agent/self-improvement/skill-behavior-gate.d.ts +34 -0
- package/dist/agent/self-improvement/skill-behavior-gate.js +96 -0
- package/dist/agent/self-improvement/skill-engine.d.ts +22 -0
- package/dist/agent/self-improvement/skill-engine.js +385 -13
- package/dist/agent/self-improvement/skill-gate.d.ts +2 -0
- package/dist/agent/self-improvement/skill-gate.js +17 -2
- package/dist/agent/self-improvement/skill-mutator.d.ts +6 -1
- package/dist/agent/self-improvement/skill-mutator.js +51 -15
- package/dist/agent/self-improvement/skill-types.d.ts +2 -1
- package/dist/agent/self-improvement/types.d.ts +11 -0
- package/dist/agent/tool-handler.d.ts +1 -1
- package/dist/agent/tool-handler.js +28 -9
- package/dist/auth/profile-manager.js +1 -1
- package/dist/channels/companion-channel-turn.d.ts +53 -4
- package/dist/channels/companion-channel-turn.js +218 -16
- package/dist/channels/slash-parity.d.ts +4 -6
- package/dist/channels/slash-parity.js +9 -44
- package/dist/cli/session-commands.d.ts +9 -0
- package/dist/cli/session-commands.js +45 -5
- package/dist/cli/session-picker.d.ts +43 -0
- package/dist/cli/session-picker.js +128 -0
- package/dist/codebuddy/a2a-call-tool-defs.d.ts +26 -0
- package/dist/codebuddy/a2a-call-tool-defs.js +12 -0
- package/dist/codebuddy/fleet-tool-defs.d.ts +2 -0
- package/dist/codebuddy/fleet-tool-defs.js +55 -0
- package/dist/codebuddy/providers/chatgpt-headers.d.ts +18 -0
- package/dist/codebuddy/providers/chatgpt-headers.js +37 -0
- package/dist/codebuddy/providers/provider-chatgpt-responses.d.ts +2 -1
- package/dist/codebuddy/providers/provider-chatgpt-responses.js +10 -23
- package/dist/codebuddy/providers/provider-openai-compat.d.ts +7 -0
- package/dist/codebuddy/providers/provider-openai-compat.js +29 -1
- package/dist/codebuddy/ragchat-tool-defs.d.ts +31 -0
- package/dist/codebuddy/ragchat-tool-defs.js +19 -0
- package/dist/codebuddy/resource-catalog-tool-defs.d.ts +28 -0
- package/dist/codebuddy/resource-catalog-tool-defs.js +18 -0
- package/dist/codebuddy/tool-definitions/agent-tools.js +2 -2
- package/dist/codebuddy/tool-definitions/code-exec-tools.js +5 -1
- package/dist/codebuddy/tool-definitions/cron-tools.js +6 -0
- package/dist/codebuddy/tool-definitions/self-describe-tools.js +6 -1
- package/dist/codebuddy/tools.d.ts +0 -6
- package/dist/codebuddy/tools.js +25 -3
- package/dist/commands/cli/daemon-commands.js +3 -1
- package/dist/commands/cli/evolve-command.js +21 -5
- package/dist/commands/cli/fleet-collaboration-commands.d.ts +2 -0
- package/dist/commands/cli/fleet-collaboration-commands.js +57 -0
- package/dist/commands/cli/fleet-commands.js +29 -0
- package/dist/commands/cli/fleet-mission-commands.d.ts +3 -0
- package/dist/commands/cli/fleet-mission-commands.js +72 -0
- package/dist/commands/cli/fleet-rooms-commands.d.ts +10 -0
- package/dist/commands/cli/fleet-rooms-commands.js +289 -0
- package/dist/commands/cli/tools-commands.js +2 -1
- package/dist/commands/cli/triage-command.d.ts +8 -0
- package/dist/commands/cli/triage-command.js +72 -0
- package/dist/commands/cli/utility-commands.js +25 -1
- package/dist/commands/client-dispatcher.d.ts +7 -0
- package/dist/commands/client-dispatcher.js +73 -21
- package/dist/commands/cron-cli/index.d.ts +3 -1
- package/dist/commands/cron-cli/index.js +25 -0
- package/dist/commands/device-auth.d.ts +10 -0
- package/dist/commands/device-auth.js +91 -0
- package/dist/commands/enhanced-command-handler.d.ts +9 -0
- package/dist/commands/enhanced-command-handler.js +28 -6
- package/dist/commands/handlers/agent-handlers.d.ts +1 -1
- package/dist/commands/handlers/agent-handlers.js +4 -4
- package/dist/commands/handlers/channel-handlers.js +53 -2
- package/dist/commands/handlers/export-handlers.d.ts +3 -2
- package/dist/commands/handlers/export-handlers.js +55 -28
- package/dist/commands/handlers/extra-handlers.js +5 -1
- package/dist/commands/handlers/grill-me-handler.js +26 -18
- package/dist/commands/handlers/memory-handlers.d.ts +6 -2
- package/dist/commands/handlers/memory-handlers.js +35 -15
- package/dist/commands/handlers/missing-handlers.d.ts +2 -2
- package/dist/commands/handlers/missing-handlers.js +12 -4
- package/dist/commands/handlers/resources-handler.d.ts +12 -0
- package/dist/commands/handlers/resources-handler.js +52 -0
- package/dist/commands/handlers/starter-handlers.d.ts +1 -1
- package/dist/commands/handlers/starter-handlers.js +32 -2
- package/dist/commands/handlers/switch-handler.d.ts +1 -1
- package/dist/commands/handlers/switch-handler.js +15 -0
- package/dist/commands/handlers/test-handlers.js +4 -86
- package/dist/commands/handlers/ui-handlers.js +11 -5
- package/dist/commands/login-chatgpt.d.ts +8 -0
- package/dist/commands/login-chatgpt.js +17 -0
- package/dist/commands/mcp-import.d.ts +11 -0
- package/dist/commands/mcp-import.js +67 -0
- package/dist/commands/mcp-invoke.d.ts +2 -0
- package/dist/commands/mcp-invoke.js +68 -0
- package/dist/commands/mcp.d.ts +13 -0
- package/dist/commands/mcp.js +66 -21
- package/dist/commands/pipeline.d.ts +7 -1
- package/dist/commands/pipeline.js +104 -7
- package/dist/commands/resources.d.ts +2 -0
- package/dist/commands/resources.js +64 -0
- package/dist/commands/skills-cli/index.js +35 -12
- package/dist/commands/slash/builtin-commands.js +16 -3
- package/dist/commands/slash/index.d.ts +3 -1
- package/dist/commands/slash/index.js +2 -0
- package/dist/commands/slash/surfaces.d.ts +53 -0
- package/dist/commands/slash/surfaces.js +177 -0
- package/dist/commands/slash/types.d.ts +17 -0
- package/dist/commands/try.d.ts +1 -1
- package/dist/commands/try.js +1 -1
- package/dist/companion/companion-identity.d.ts +43 -0
- package/dist/companion/companion-identity.js +136 -0
- package/dist/companion/companion-toolset.d.ts +66 -0
- package/dist/companion/companion-toolset.js +368 -0
- package/dist/companion/companion-turn.d.ts +10 -2
- package/dist/companion/companion-turn.js +38 -1
- package/dist/config/code-exec-policy.d.ts +25 -0
- package/dist/config/code-exec-policy.js +39 -0
- package/dist/config/model-tools.d.ts +9 -0
- package/dist/config/model-tools.js +103 -0
- package/dist/context/context-manager-v2.js +2 -2
- package/dist/context/lm-resizer-compressor.js +3 -2
- package/dist/context/lm-resizer-diagnostics.d.ts +9 -0
- package/dist/context/lm-resizer-diagnostics.js +30 -0
- package/dist/context/tool-output-masking.js +3 -4
- package/dist/curator/curator.d.ts +6 -0
- package/dist/curator/curator.js +53 -3
- package/dist/daemon/cron-agent-bridge.d.ts +6 -0
- package/dist/daemon/cron-agent-bridge.js +31 -4
- package/dist/doctor/index.d.ts +11 -2
- package/dist/doctor/index.js +84 -21
- package/dist/doctor/integrations.d.ts +197 -0
- package/dist/doctor/integrations.js +241 -0
- package/dist/doctor/triage.d.ts +108 -0
- package/dist/doctor/triage.js +304 -0
- package/dist/errors/crash-handler.js +2 -0
- package/dist/fleet/collaboration.d.ts +44 -0
- package/dist/fleet/collaboration.js +170 -0
- package/dist/fleet/fleet-listener.d.ts +1 -0
- package/dist/fleet/fleet-listener.js +87 -46
- package/dist/fleet/fleet-registry.d.ts +2 -0
- package/dist/fleet/resource-catalog.d.ts +245 -0
- package/dist/fleet/resource-catalog.js +211 -0
- package/dist/fleet/rooms/room-access.d.ts +138 -0
- package/dist/fleet/rooms/room-access.js +196 -0
- package/dist/fleet/rooms/room-client.d.ts +158 -0
- package/dist/fleet/rooms/room-client.js +685 -0
- package/dist/fleet/rooms/room-event.d.ts +139 -0
- package/dist/fleet/rooms/room-event.js +330 -0
- package/dist/fleet/rooms/room-filter.d.ts +48 -0
- package/dist/fleet/rooms/room-filter.js +152 -0
- package/dist/fleet/rooms/room-hub.d.ts +154 -0
- package/dist/fleet/rooms/room-hub.js +363 -0
- package/dist/fleet/rooms/room-identity.d.ts +26 -0
- package/dist/fleet/rooms/room-identity.js +82 -0
- package/dist/fleet/rooms/room-lock.d.ts +34 -0
- package/dist/fleet/rooms/room-lock.js +180 -0
- package/dist/fleet/rooms/room-observations.d.ts +7 -0
- package/dist/fleet/rooms/room-observations.js +61 -0
- package/dist/fleet/rooms/room-server.d.ts +28 -0
- package/dist/fleet/rooms/room-server.js +75 -0
- package/dist/fleet/rooms/room-store.d.ts +119 -0
- package/dist/fleet/rooms/room-store.js +448 -0
- package/dist/fleet/rooms/room-ws-bridge.d.ts +27 -0
- package/dist/fleet/rooms/room-ws-bridge.js +137 -0
- package/dist/fleet/sensory-mission-bridge.d.ts +42 -0
- package/dist/fleet/sensory-mission-bridge.js +136 -0
- package/dist/git/worktree-sessions.js +1 -0
- package/dist/harness/contract.d.ts +4 -4
- package/dist/harness/fleet-supervisor.d.ts +16 -0
- package/dist/harness/fleet-supervisor.js +64 -0
- package/dist/harness/index.d.ts +4 -0
- package/dist/harness/index.js +4 -0
- package/dist/harness/mission-runner.d.ts +3 -0
- package/dist/harness/mission-runner.js +53 -0
- package/dist/harness/mission-store.d.ts +93 -0
- package/dist/harness/mission-store.js +297 -0
- package/dist/harness/tool-harness.d.ts +56 -0
- package/dist/harness/tool-harness.js +153 -0
- package/dist/hooks/use-enhanced-input.js +48 -4
- package/dist/hooks/use-input-handler.d.ts +1 -0
- package/dist/hooks/use-input-handler.js +82 -22
- package/dist/hooks/use-input-history.js +1 -0
- package/dist/identity/lisa-introspection.js +5 -2
- package/dist/identity/operational-self-model.d.ts +2 -0
- package/dist/identity/operational-self-model.js +4 -0
- package/dist/index.js +52 -6
- package/dist/mcp/client.d.ts +11 -0
- package/dist/mcp/client.js +68 -3
- package/dist/mcp/config.d.ts +20 -0
- package/dist/mcp/config.js +121 -8
- package/dist/mcp/import-normalize.d.ts +12 -0
- package/dist/mcp/import-normalize.js +114 -0
- package/dist/mcp/mcp-oauth-constants.d.ts +8 -0
- package/dist/mcp/mcp-oauth-constants.js +9 -0
- package/dist/mcp/mcp-oauth-provider.d.ts +80 -0
- package/dist/mcp/mcp-oauth-provider.js +241 -0
- package/dist/mcp/mcp-oauth.d.ts +60 -1
- package/dist/mcp/mcp-oauth.js +241 -65
- package/dist/mcp/transports.d.ts +14 -5
- package/dist/mcp/transports.js +112 -101
- package/dist/mcp/types.d.ts +5 -0
- package/dist/media/comfyui-recipe-contract.d.ts +7 -7
- package/dist/memory/facts-memory.d.ts +11 -1
- package/dist/memory/facts-memory.js +47 -8
- package/dist/memory/memory-candidate-queue.d.ts +2 -2
- package/dist/memory/memory-candidate-queue.js +6 -6
- package/dist/memory/persistent-memory.d.ts +13 -8
- package/dist/memory/persistent-memory.js +77 -30
- package/dist/nodes/device-node.js +5 -9
- package/dist/observability/mobile-supervision-gateway-contract.js +20 -7
- package/dist/observability/run-event-writer.d.ts +21 -0
- package/dist/observability/run-event-writer.js +81 -0
- package/dist/observability/run-store.d.ts +5 -0
- package/dist/observability/run-store.js +18 -13
- package/dist/observability/run-trajectory.js +1 -1
- package/dist/optimization/prompt-cache.d.ts +19 -2
- package/dist/optimization/prompt-cache.js +41 -6
- package/dist/orchestration/orchestrator.d.ts +21 -0
- package/dist/orchestration/orchestrator.js +122 -15
- package/dist/persistence/session-content.d.ts +8 -0
- package/dist/persistence/session-content.js +76 -0
- package/dist/persistence/session-handoff.d.ts +64 -0
- package/dist/persistence/session-handoff.js +80 -0
- package/dist/persistence/session-history.d.ts +4 -0
- package/dist/persistence/session-history.js +38 -0
- package/dist/persistence/session-store.d.ts +9 -0
- package/dist/persistence/session-store.js +48 -20
- package/dist/personas/persona-manager.js +17 -1
- package/dist/plugins/code-explorer/CodeExplorerManager.d.ts +10 -4
- package/dist/plugins/code-explorer/CodeExplorerManager.js +69 -16
- package/dist/plugins/plugin-manager.js +10 -1
- package/dist/prompts/prompt-manager.js +11 -4
- package/dist/prompts/system-base.js +6 -2
- package/dist/protocols/a2a/codebuddy-executor.d.ts +11 -2
- package/dist/protocols/a2a/codebuddy-executor.js +9 -8
- package/dist/protocols/a2a/index.d.ts +1 -1
- package/dist/protocols/a2a/jsonrpc-v1.d.ts +41 -0
- package/dist/protocols/a2a/jsonrpc-v1.js +145 -0
- package/dist/protocols/a2a/peer-config.d.ts +20 -0
- package/dist/protocols/a2a/peer-config.js +55 -0
- package/dist/providers/codex-oauth.js +30 -6
- package/dist/providers/model-provider-compat.js +2 -1
- package/dist/sandbox/os-sandbox.d.ts +1 -1
- package/dist/scheduler/cron-scheduler.d.ts +15 -2
- package/dist/scheduler/cron-scheduler.js +35 -4
- package/dist/scheduler/job-notepad.d.ts +69 -0
- package/dist/scheduler/job-notepad.js +339 -0
- package/dist/security/audit-logger.d.ts +1 -1
- package/dist/security/compute-confinement.d.ts +4 -0
- package/dist/security/compute-confinement.js +89 -0
- package/dist/security/session-encryption.d.ts +4 -0
- package/dist/security/session-encryption.js +31 -0
- package/dist/sensory/voice-loop.d.ts +17 -0
- package/dist/sensory/voice-loop.js +72 -15
- package/dist/server/auth/device-session-context.d.ts +9 -0
- package/dist/server/auth/device-session-context.js +13 -0
- package/dist/server/auth/device-store.d.ts +89 -0
- package/dist/server/auth/device-store.js +261 -0
- package/dist/server/auth/device-token.d.ts +3 -0
- package/dist/server/auth/device-token.js +6 -0
- package/dist/server/auth/jwt.js +4 -0
- package/dist/server/index.d.ts +0 -10
- package/dist/server/index.js +28 -0
- package/dist/server/middleware/auth.js +3 -2
- package/dist/server/routes/a2a-jsonrpc.d.ts +9 -0
- package/dist/server/routes/a2a-jsonrpc.js +66 -0
- package/dist/server/routes/a2a-protocol.d.ts +12 -0
- package/dist/server/routes/a2a-protocol.js +1 -1
- package/dist/server/routes/device-auth.d.ts +4 -0
- package/dist/server/routes/device-auth.js +40 -0
- package/dist/server/types.d.ts +4 -0
- package/dist/server/websocket/handler.d.ts +13 -0
- package/dist/server/websocket/handler.js +102 -17
- package/dist/services/prompt-builder.d.ts +2 -0
- package/dist/services/prompt-builder.js +16 -6
- package/dist/services/runtime-settings-context.d.ts +81 -0
- package/dist/services/runtime-settings-context.js +79 -0
- package/dist/skills/executor.js +2 -0
- package/dist/skills/hub.js +16 -14
- package/dist/skills/local-inventory.d.ts +21 -0
- package/dist/skills/local-inventory.js +72 -0
- package/dist/skills/skill-loader.js +2 -2
- package/dist/skills/skill-usage-store.d.ts +49 -0
- package/dist/skills/skill-usage-store.js +121 -0
- package/dist/testing/ai-integration-tests.js +8 -5
- package/dist/themes/theme-manager.d.ts +12 -0
- package/dist/themes/theme-manager.js +29 -0
- package/dist/themes/theme-schema.d.ts +24 -24
- package/dist/tools/a2a-call-tool.d.ts +34 -0
- package/dist/tools/a2a-call-tool.js +75 -0
- package/dist/tools/bash/streaming-executor.d.ts +1 -0
- package/dist/tools/bash/streaming-executor.js +78 -90
- package/dist/tools/code-exec-preflight-runner.d.ts +41 -0
- package/dist/tools/code-exec-preflight-runner.js +254 -0
- package/dist/tools/code-exec-preflight.d.ts +44 -0
- package/dist/tools/code-exec-preflight.js +501 -0
- package/dist/tools/code-exec-tool.d.ts +48 -1
- package/dist/tools/code-exec-tool.js +191 -47
- package/dist/tools/comment-watcher.js +29 -12
- package/dist/tools/core-code-inspection.d.ts +56 -0
- package/dist/tools/core-code-inspection.js +86 -0
- package/dist/tools/create-skill-tool.d.ts +2 -3
- package/dist/tools/create-skill-tool.js +16 -75
- package/dist/tools/cronjob-tool.d.ts +1 -0
- package/dist/tools/cronjob-tool.js +1 -0
- package/dist/tools/env-doctor-tool.d.ts +2 -0
- package/dist/tools/env-doctor-tool.js +4 -3
- package/dist/tools/execute-code-rpc-invoker.d.ts +1 -1
- package/dist/tools/execute-code-rpc-invoker.js +35 -19
- package/dist/tools/execute-code-runner.d.ts +2 -0
- package/dist/tools/execute-code-runner.js +52 -17
- package/dist/tools/fleet-room-tool.d.ts +104 -0
- package/dist/tools/fleet-room-tool.js +124 -0
- package/dist/tools/integration-tool-hints.d.ts +4 -0
- package/dist/tools/integration-tool-hints.js +19 -0
- package/dist/tools/list-peers-tool.d.ts +3 -0
- package/dist/tools/list-peers-tool.js +11 -4
- package/dist/tools/media-generation-tool.d.ts +16 -1
- package/dist/tools/media-generation-tool.js +341 -9
- package/dist/tools/merge-conflict-tool.js +53 -25
- package/dist/tools/metadata.d.ts +1 -5
- package/dist/tools/metadata.js +30 -28
- package/dist/tools/peer-tool-invoke-tool.d.ts +61 -0
- package/dist/tools/peer-tool-invoke-tool.js +396 -0
- package/dist/tools/ragchat-tool.d.ts +39 -0
- package/dist/tools/ragchat-tool.js +105 -0
- package/dist/tools/registry/fleet-tools.d.ts +21 -3
- package/dist/tools/registry/fleet-tools.js +137 -4
- package/dist/tools/registry/index.d.ts +1 -1
- package/dist/tools/registry/index.js +2 -2
- package/dist/tools/registry/knowledge-tools.d.ts +2 -2
- package/dist/tools/registry/knowledge-tools.js +2 -2
- package/dist/tools/registry/lessons-tools.d.ts +7 -0
- package/dist/tools/registry/lessons-tools.js +43 -3
- package/dist/tools/registry/memory-tools.d.ts +1 -1
- package/dist/tools/registry/memory-tools.js +8 -8
- package/dist/tools/registry/research-tools.d.ts +1 -0
- package/dist/tools/registry/research-tools.js +4 -13
- package/dist/tools/registry/self-describe-tools.d.ts +1 -1
- package/dist/tools/registry/self-describe-tools.js +43 -30
- package/dist/tools/resource-catalog-tool.d.ts +38 -0
- package/dist/tools/resource-catalog-tool.js +46 -0
- package/dist/tools/skills-inspection-tool.js +30 -1
- package/dist/tools/stream-tool-output.d.ts +3 -0
- package/dist/tools/stream-tool-output.js +33 -0
- package/dist/tools/tool-call-scheduler.d.ts +10 -0
- package/dist/tools/tool-call-scheduler.js +58 -0
- package/dist/tools/tool-effect.d.ts +5 -0
- package/dist/tools/tool-effect.js +26 -0
- package/dist/tools/tool-search.d.ts +12 -11
- package/dist/tools/tool-search.js +67 -26
- package/dist/tools/types.d.ts +6 -0
- package/dist/ui/components/ChatHistory.d.ts +1 -1
- package/dist/ui/components/ChatHistory.js +2 -2
- package/dist/ui/components/ChatInput.d.ts +2 -1
- package/dist/ui/components/ChatInput.js +42 -88
- package/dist/ui/components/ChatInterface.d.ts +4 -2
- package/dist/ui/components/ChatInterface.js +27 -63
- package/dist/ui/components/CommandSuggestions.d.ts +0 -1
- package/dist/ui/components/CommandSuggestions.js +4 -6
- package/dist/ui/components/FileAutocomplete.js +1 -1
- package/dist/ui/components/KeyboardHelp.js +8 -6
- package/dist/ui/components/ModelSelection.js +6 -5
- package/dist/ui/components/StatusBar.d.ts +2 -1
- package/dist/ui/components/StatusBar.js +8 -7
- package/dist/ui/context/theme-context.js +3 -2
- package/dist/ui/index.d.ts +1 -1
- package/dist/ui/index.js +1 -1
- package/dist/ui/utils/markdown-renderer.js +4 -13
- package/dist/utils/atomic-write.d.ts +22 -0
- package/dist/utils/atomic-write.js +29 -0
- package/dist/utils/bounded-output.d.ts +16 -0
- package/dist/utils/bounded-output.js +63 -0
- package/dist/utils/config-validation/schema.d.ts +2 -2
- package/dist/utils/device-store-file.d.ts +4 -0
- package/dist/utils/device-store-file.js +40 -0
- package/dist/utils/export-manager.d.ts +9 -0
- package/dist/utils/export-manager.js +19 -0
- package/dist/utils/first-use-hints.d.ts +25 -0
- package/dist/utils/first-use-hints.js +58 -0
- package/dist/utils/graceful-shutdown.d.ts +8 -0
- package/dist/utils/graceful-shutdown.js +23 -7
- package/dist/utils/history-manager.js +1 -1
- package/dist/utils/update-notifier.js +16 -18
- package/dist/wizard/environment-detection.d.ts +5 -1
- package/dist/wizard/environment-detection.js +49 -7
- package/dist/wizard/onboarding.d.ts +5 -1
- package/dist/wizard/onboarding.js +90 -30
- package/dist/wizard/provider-onboarding.d.ts +2 -0
- package/dist/wizard/provider-onboarding.js +55 -17
- package/package.json +7 -3
package/dist/mcp/mcp-oauth.d.ts
CHANGED
|
@@ -18,6 +18,19 @@ export interface MCPOAuthToken {
|
|
|
18
18
|
expiresAt: number;
|
|
19
19
|
scopes: string[];
|
|
20
20
|
}
|
|
21
|
+
/** Client id + optional DCR metadata persisted next to the token (encrypted store). */
|
|
22
|
+
export interface StoredClientInformation {
|
|
23
|
+
client_id: string;
|
|
24
|
+
client_secret?: string;
|
|
25
|
+
client_id_issued_at?: number;
|
|
26
|
+
client_secret_expires_at?: number;
|
|
27
|
+
redirect_uris?: string[];
|
|
28
|
+
token_endpoint_auth_method?: string;
|
|
29
|
+
grant_types?: string[];
|
|
30
|
+
response_types?: string[];
|
|
31
|
+
client_name?: string;
|
|
32
|
+
scope?: string;
|
|
33
|
+
}
|
|
21
34
|
/**
|
|
22
35
|
* Generate a cryptographically random code verifier (43-128 chars, URL-safe)
|
|
23
36
|
*/
|
|
@@ -26,6 +39,35 @@ export declare function generateCodeVerifier(): string;
|
|
|
26
39
|
* Generate code challenge from verifier using S256 method
|
|
27
40
|
*/
|
|
28
41
|
export declare function generateCodeChallenge(verifier: string): string;
|
|
42
|
+
interface AuthorizationResult {
|
|
43
|
+
code: string;
|
|
44
|
+
state: string;
|
|
45
|
+
}
|
|
46
|
+
export declare class OAuthCallbackCancelledError extends Error {
|
|
47
|
+
constructor(message?: string);
|
|
48
|
+
}
|
|
49
|
+
export interface CallbackSession {
|
|
50
|
+
/** Resolves only after listen() succeeded. Rejects on bind failure or abort-before-listen. */
|
|
51
|
+
listening: Promise<void>;
|
|
52
|
+
/** Resolves with the authorization code after a valid callback. */
|
|
53
|
+
result: Promise<AuthorizationResult>;
|
|
54
|
+
abort: (reason?: Error) => void;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Bind the loopback callback server. Callers must await `listening` before
|
|
58
|
+
* opening a browser: a bind failure must not leave an unhandled rejection
|
|
59
|
+
* nor launch a flow that can never complete.
|
|
60
|
+
*/
|
|
61
|
+
export declare function startCallbackSession(redirectUri: string, expectedState: string, timeoutMs?: number, signal?: AbortSignal): CallbackSession;
|
|
62
|
+
/**
|
|
63
|
+
* Start a temporary local HTTP server to receive the OAuth callback.
|
|
64
|
+
* Awaits a successful listen before waiting for the code.
|
|
65
|
+
*/
|
|
66
|
+
export declare function startCallbackServer(redirectUri: string, expectedState: string, timeoutMs?: number, signal?: AbortSignal): Promise<AuthorizationResult>;
|
|
67
|
+
/**
|
|
68
|
+
* Open a URL in the default browser (cross-platform)
|
|
69
|
+
*/
|
|
70
|
+
export declare function openBrowser(url: string): Promise<void>;
|
|
29
71
|
export declare class MCPOAuthManager {
|
|
30
72
|
private tokenCache;
|
|
31
73
|
/**
|
|
@@ -48,17 +90,34 @@ export declare class MCPOAuthManager {
|
|
|
48
90
|
*/
|
|
49
91
|
getValidToken(serverId: string): Promise<string | null>;
|
|
50
92
|
/**
|
|
51
|
-
* Store a token encrypted on disk and in memory cache
|
|
93
|
+
* Store a token encrypted on disk and in memory cache.
|
|
94
|
+
* Preserves any previously persisted client metadata for the same server.
|
|
52
95
|
*/
|
|
53
96
|
storeToken(serverId: string, token: MCPOAuthToken, config: MCPOAuthConfig): void;
|
|
97
|
+
/**
|
|
98
|
+
* Persist client registration (client_id and optional DCR metadata) in the
|
|
99
|
+
* encrypted store, even before a token exists. Never writes plaintext.
|
|
100
|
+
*/
|
|
101
|
+
storeClientInformation(serverId: string, info: StoredClientInformation): void;
|
|
54
102
|
/**
|
|
55
103
|
* Remove a stored token
|
|
56
104
|
*/
|
|
57
105
|
removeToken(serverId: string): void;
|
|
106
|
+
/** Drop access/refresh tokens only; keep client_id and DCR metadata. */
|
|
107
|
+
clearTokens(serverId: string): void;
|
|
58
108
|
/**
|
|
59
109
|
* Check if a token exists for a server (may be expired)
|
|
60
110
|
*/
|
|
111
|
+
/** Stored token and client id for a server, without refresh side effects. */
|
|
112
|
+
getStoredToken(serverId: string): {
|
|
113
|
+
token: MCPOAuthToken;
|
|
114
|
+
clientId: string;
|
|
115
|
+
client?: StoredClientInformation;
|
|
116
|
+
} | null;
|
|
117
|
+
/** Persisted client id / DCR metadata, independent of whether a token exists. */
|
|
118
|
+
getStoredClientInformation(serverId: string): StoredClientInformation | null;
|
|
61
119
|
hasToken(serverId: string): boolean;
|
|
62
120
|
}
|
|
63
121
|
export declare function getMCPOAuthManager(): MCPOAuthManager;
|
|
64
122
|
export declare function resetMCPOAuthManager(): void;
|
|
123
|
+
export {};
|
package/dist/mcp/mcp-oauth.js
CHANGED
|
@@ -11,6 +11,29 @@ import * as path from 'path';
|
|
|
11
11
|
import { URL } from 'url';
|
|
12
12
|
import { logger } from '../utils/logger.js';
|
|
13
13
|
import { readTextAtomicSync, writeFileAtomicSync } from '../utils/atomic-write.js';
|
|
14
|
+
import { SDK_MANAGED_TOKEN_URL } from './mcp-oauth-constants.js';
|
|
15
|
+
function storedClientFrom(info) {
|
|
16
|
+
const client = { client_id: info.client_id };
|
|
17
|
+
if (info.client_secret)
|
|
18
|
+
client.client_secret = info.client_secret;
|
|
19
|
+
if (info.client_id_issued_at !== undefined)
|
|
20
|
+
client.client_id_issued_at = info.client_id_issued_at;
|
|
21
|
+
if (info.client_secret_expires_at !== undefined)
|
|
22
|
+
client.client_secret_expires_at = info.client_secret_expires_at;
|
|
23
|
+
if (info.redirect_uris?.length)
|
|
24
|
+
client.redirect_uris = [...info.redirect_uris];
|
|
25
|
+
if (info.token_endpoint_auth_method)
|
|
26
|
+
client.token_endpoint_auth_method = info.token_endpoint_auth_method;
|
|
27
|
+
if (info.grant_types?.length)
|
|
28
|
+
client.grant_types = [...info.grant_types];
|
|
29
|
+
if (info.response_types?.length)
|
|
30
|
+
client.response_types = [...info.response_types];
|
|
31
|
+
if (info.client_name)
|
|
32
|
+
client.client_name = info.client_name;
|
|
33
|
+
if (info.scope)
|
|
34
|
+
client.scope = info.scope;
|
|
35
|
+
return client;
|
|
36
|
+
}
|
|
14
37
|
// ============================================================================
|
|
15
38
|
// PKCE (RFC 7636)
|
|
16
39
|
// ============================================================================
|
|
@@ -35,7 +58,9 @@ export function generateCodeChallenge(verifier) {
|
|
|
35
58
|
const ALGORITHM = 'aes-256-gcm';
|
|
36
59
|
const SALT_LENGTH = 32;
|
|
37
60
|
function getEncryptionKey() {
|
|
38
|
-
//
|
|
61
|
+
// Prefer CODEBUDDY_VAULT_KEY or CODEBUDDY_MCP_KEY. The USER+platform fallback
|
|
62
|
+
// is derivable by anyone on the same account: AES-GCM still runs, but that is
|
|
63
|
+
// not a strong vault. Set an explicit key for real confidentiality.
|
|
39
64
|
return process.env.CODEBUDDY_VAULT_KEY
|
|
40
65
|
|| process.env.CODEBUDDY_MCP_KEY
|
|
41
66
|
|| `mcp-oauth-${process.env.USER || process.env.USERNAME || 'default'}-${process.platform}`;
|
|
@@ -101,63 +126,153 @@ function saveTokenStore(store) {
|
|
|
101
126
|
const encrypted = encryptData(JSON.stringify(store));
|
|
102
127
|
writeFileAtomicSync(filePath, encrypted, { mode: 0o600 });
|
|
103
128
|
}
|
|
129
|
+
export class OAuthCallbackCancelledError extends Error {
|
|
130
|
+
constructor(message = 'OAuth authorization cancelled') {
|
|
131
|
+
super(message);
|
|
132
|
+
this.name = 'OAuthCallbackCancelledError';
|
|
133
|
+
}
|
|
134
|
+
}
|
|
104
135
|
/**
|
|
105
|
-
*
|
|
106
|
-
*
|
|
136
|
+
* Bind the loopback callback server. Callers must await `listening` before
|
|
137
|
+
* opening a browser: a bind failure must not leave an unhandled rejection
|
|
138
|
+
* nor launch a flow that can never complete.
|
|
107
139
|
*/
|
|
108
|
-
function
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
140
|
+
export function startCallbackSession(redirectUri, expectedState, timeoutMs = 120_000, signal) {
|
|
141
|
+
const url = new URL(redirectUri);
|
|
142
|
+
const port = parseInt(url.port || '19836', 10);
|
|
143
|
+
const pathname = url.pathname || '/callback';
|
|
144
|
+
let listenResolve;
|
|
145
|
+
let listenReject;
|
|
146
|
+
let resultResolve;
|
|
147
|
+
let resultReject;
|
|
148
|
+
let listeningSettled = false;
|
|
149
|
+
let resultSettled = false;
|
|
150
|
+
let timer;
|
|
151
|
+
let server;
|
|
152
|
+
const listening = new Promise((resolve, reject) => {
|
|
153
|
+
listenResolve = resolve;
|
|
154
|
+
listenReject = reject;
|
|
155
|
+
});
|
|
156
|
+
const result = new Promise((resolve, reject) => {
|
|
157
|
+
resultResolve = resolve;
|
|
158
|
+
resultReject = reject;
|
|
159
|
+
});
|
|
160
|
+
// Attach observers at construction so a pre-aborted signal cannot leave an
|
|
161
|
+
// unhandledRejection on the public startCallbackServer wrapper (the early
|
|
162
|
+
// return used to skip the .catch() that lived after listen()).
|
|
163
|
+
listening.catch(() => undefined);
|
|
164
|
+
result.catch(() => undefined);
|
|
165
|
+
const settleListen = (err) => {
|
|
166
|
+
if (listeningSettled)
|
|
167
|
+
return;
|
|
168
|
+
listeningSettled = true;
|
|
169
|
+
if (err)
|
|
170
|
+
listenReject(err);
|
|
171
|
+
else
|
|
172
|
+
listenResolve();
|
|
173
|
+
};
|
|
174
|
+
const settleResult = (value, err) => {
|
|
175
|
+
if (resultSettled)
|
|
176
|
+
return;
|
|
177
|
+
resultSettled = true;
|
|
178
|
+
if (timer)
|
|
179
|
+
clearTimeout(timer);
|
|
180
|
+
if (err)
|
|
181
|
+
resultReject(err);
|
|
182
|
+
else
|
|
183
|
+
resultResolve(value);
|
|
184
|
+
};
|
|
185
|
+
let abort;
|
|
186
|
+
const onAbort = () => abort(new OAuthCallbackCancelledError());
|
|
187
|
+
const detachAbort = () => signal?.removeEventListener('abort', onAbort);
|
|
188
|
+
abort = (reason) => {
|
|
189
|
+
detachAbort();
|
|
190
|
+
const fail = reason ?? new OAuthCallbackCancelledError();
|
|
191
|
+
if (!listeningSettled)
|
|
192
|
+
settleListen(fail);
|
|
193
|
+
if (!resultSettled)
|
|
194
|
+
settleResult(undefined, fail);
|
|
195
|
+
if (timer) {
|
|
196
|
+
clearTimeout(timer);
|
|
197
|
+
timer = undefined;
|
|
198
|
+
}
|
|
199
|
+
if (server) {
|
|
200
|
+
server.removeAllListeners('error');
|
|
201
|
+
const closing = server;
|
|
202
|
+
server = undefined;
|
|
203
|
+
closing.close();
|
|
204
|
+
}
|
|
205
|
+
};
|
|
206
|
+
if (signal?.aborted) {
|
|
207
|
+
abort(new OAuthCallbackCancelledError());
|
|
208
|
+
return { listening, result, abort };
|
|
209
|
+
}
|
|
210
|
+
signal?.addEventListener('abort', onAbort, { once: true });
|
|
211
|
+
timer = setTimeout(() => {
|
|
212
|
+
abort(new Error('OAuth callback timed out (120s)'));
|
|
213
|
+
detachAbort();
|
|
214
|
+
}, timeoutMs);
|
|
215
|
+
server = http.createServer((req, res) => {
|
|
216
|
+
const reqUrl = new URL(req.url || '/', `http://127.0.0.1:${port}`);
|
|
217
|
+
if (reqUrl.pathname !== pathname) {
|
|
218
|
+
res.writeHead(404);
|
|
219
|
+
res.end('Not found');
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
const code = reqUrl.searchParams.get('code');
|
|
223
|
+
const state = reqUrl.searchParams.get('state');
|
|
224
|
+
const error = reqUrl.searchParams.get('error');
|
|
225
|
+
if (error) {
|
|
142
226
|
res.writeHead(200, { 'Content-Type': 'text/html' });
|
|
143
|
-
res.end('<html><body><h1>Authorization
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
227
|
+
res.end('<html><body><h1>Authorization Failed</h1><p>You can close this window.</p></body></html>');
|
|
228
|
+
detachAbort();
|
|
229
|
+
abort(new Error(`OAuth authorization error: ${error}`));
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
if (!code) {
|
|
233
|
+
res.writeHead(400, { 'Content-Type': 'text/html' });
|
|
234
|
+
res.end('<html><body><h1>Missing authorization code</h1></body></html>');
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
if (state !== expectedState) {
|
|
238
|
+
res.writeHead(400, { 'Content-Type': 'text/html' });
|
|
239
|
+
res.end('<html><body><h1>State mismatch — possible CSRF attack</h1></body></html>');
|
|
240
|
+
detachAbort();
|
|
241
|
+
abort(new Error('OAuth state mismatch'));
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
res.writeHead(200, { 'Content-Type': 'text/html' });
|
|
245
|
+
res.end('<html><body><h1>Authorization Successful</h1><p>You can close this window and return to the terminal.</p></body></html>');
|
|
246
|
+
detachAbort();
|
|
247
|
+
if (timer) {
|
|
154
248
|
clearTimeout(timer);
|
|
155
|
-
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
249
|
+
timer = undefined;
|
|
250
|
+
}
|
|
251
|
+
const closing = server;
|
|
252
|
+
server = undefined;
|
|
253
|
+
closing?.removeAllListeners('error');
|
|
254
|
+
closing?.close();
|
|
255
|
+
settleListen();
|
|
256
|
+
settleResult({ code, state });
|
|
257
|
+
});
|
|
258
|
+
server.on('error', (err) => {
|
|
259
|
+
detachAbort();
|
|
260
|
+
abort(new Error(`Failed to start callback server: ${err.message}`));
|
|
160
261
|
});
|
|
262
|
+
server.listen(port, '127.0.0.1', () => {
|
|
263
|
+
logger.debug(`OAuth callback server listening on port ${port}`);
|
|
264
|
+
settleListen();
|
|
265
|
+
});
|
|
266
|
+
return { listening, result, abort };
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Start a temporary local HTTP server to receive the OAuth callback.
|
|
270
|
+
* Awaits a successful listen before waiting for the code.
|
|
271
|
+
*/
|
|
272
|
+
export async function startCallbackServer(redirectUri, expectedState, timeoutMs = 120_000, signal) {
|
|
273
|
+
const session = startCallbackSession(redirectUri, expectedState, timeoutMs, signal);
|
|
274
|
+
await session.listening;
|
|
275
|
+
return session.result;
|
|
161
276
|
}
|
|
162
277
|
// ============================================================================
|
|
163
278
|
// Browser Opener
|
|
@@ -165,7 +280,7 @@ function startCallbackServer(redirectUri, expectedState, timeoutMs = 120_000) {
|
|
|
165
280
|
/**
|
|
166
281
|
* Open a URL in the default browser (cross-platform)
|
|
167
282
|
*/
|
|
168
|
-
async function openBrowser(url) {
|
|
283
|
+
export async function openBrowser(url) {
|
|
169
284
|
const { exec } = await import('child_process');
|
|
170
285
|
const command = process.platform === 'win32'
|
|
171
286
|
? `start "" "${url}"`
|
|
@@ -244,9 +359,11 @@ export class MCPOAuthManager {
|
|
|
244
359
|
authUrl.searchParams.set('state', state);
|
|
245
360
|
authUrl.searchParams.set('code_challenge', codeChallenge);
|
|
246
361
|
authUrl.searchParams.set('code_challenge_method', 'S256');
|
|
247
|
-
//
|
|
248
|
-
|
|
249
|
-
//
|
|
362
|
+
// Bind the loopback callback before opening the browser: a listen failure
|
|
363
|
+
// must not launch a flow that can never complete (same contract as the SDK
|
|
364
|
+
// provider path). Keep the manual URL if the opener fails.
|
|
365
|
+
const session = startCallbackSession(redirectUri, state);
|
|
366
|
+
await session.listening;
|
|
250
367
|
logger.info('Opening browser for OAuth authorization...');
|
|
251
368
|
try {
|
|
252
369
|
await openBrowser(authUrl.toString());
|
|
@@ -254,8 +371,7 @@ export class MCPOAuthManager {
|
|
|
254
371
|
catch {
|
|
255
372
|
logger.info(`Please open this URL in your browser:\n${authUrl.toString()}`);
|
|
256
373
|
}
|
|
257
|
-
|
|
258
|
-
const { code } = await callbackPromise;
|
|
374
|
+
const { code } = await session.result;
|
|
259
375
|
// Exchange code for token
|
|
260
376
|
const token = await exchangeCodeForToken(config, code, codeVerifier, redirectUri);
|
|
261
377
|
// Store token
|
|
@@ -306,14 +422,20 @@ export class MCPOAuthManager {
|
|
|
306
422
|
// Load from disk
|
|
307
423
|
const store = loadTokenStore();
|
|
308
424
|
const entry = store[serverId];
|
|
309
|
-
|
|
425
|
+
const token = entry?.token;
|
|
426
|
+
if (!token?.accessToken || !entry)
|
|
310
427
|
return null;
|
|
311
|
-
const {
|
|
428
|
+
const { config } = entry;
|
|
312
429
|
// If token is still valid (with 60s buffer), return it
|
|
313
430
|
if (token.expiresAt > Date.now() + 60_000) {
|
|
314
431
|
this.tokenCache.set(serverId, token);
|
|
315
432
|
return token.accessToken;
|
|
316
433
|
}
|
|
434
|
+
// Entries written by the SDK-backed provider are refreshed by the SDK itself.
|
|
435
|
+
if (config.tokenUrl === SDK_MANAGED_TOKEN_URL) {
|
|
436
|
+
logger.debug(`MCP OAuth token for ${serverId} is SDK-managed; refresh happens on the next transport connection`);
|
|
437
|
+
return null;
|
|
438
|
+
}
|
|
317
439
|
// Try to refresh
|
|
318
440
|
if (token.refreshToken) {
|
|
319
441
|
try {
|
|
@@ -340,17 +462,42 @@ export class MCPOAuthManager {
|
|
|
340
462
|
return null;
|
|
341
463
|
}
|
|
342
464
|
/**
|
|
343
|
-
* Store a token encrypted on disk and in memory cache
|
|
465
|
+
* Store a token encrypted on disk and in memory cache.
|
|
466
|
+
* Preserves any previously persisted client metadata for the same server.
|
|
344
467
|
*/
|
|
345
468
|
storeToken(serverId, token, config) {
|
|
346
469
|
this.tokenCache.set(serverId, token);
|
|
347
470
|
const store = loadTokenStore();
|
|
471
|
+
const prev = store[serverId];
|
|
472
|
+
const clientId = config.clientId || prev?.config.clientId || prev?.client?.client_id || '';
|
|
473
|
+
const client = prev?.client
|
|
474
|
+
? storedClientFrom({ ...prev.client, ...(clientId ? { client_id: clientId } : {}) })
|
|
475
|
+
: (clientId ? storedClientFrom({ client_id: clientId }) : undefined);
|
|
348
476
|
store[serverId] = {
|
|
349
477
|
token,
|
|
350
478
|
config: {
|
|
351
|
-
clientId
|
|
352
|
-
tokenUrl: config.tokenUrl,
|
|
479
|
+
clientId,
|
|
480
|
+
tokenUrl: config.tokenUrl || prev?.config.tokenUrl || SDK_MANAGED_TOKEN_URL,
|
|
481
|
+
},
|
|
482
|
+
...(client ? { client } : {}),
|
|
483
|
+
};
|
|
484
|
+
saveTokenStore(store);
|
|
485
|
+
}
|
|
486
|
+
/**
|
|
487
|
+
* Persist client registration (client_id and optional DCR metadata) in the
|
|
488
|
+
* encrypted store, even before a token exists. Never writes plaintext.
|
|
489
|
+
*/
|
|
490
|
+
storeClientInformation(serverId, info) {
|
|
491
|
+
const client = storedClientFrom(info);
|
|
492
|
+
const store = loadTokenStore();
|
|
493
|
+
const prev = store[serverId];
|
|
494
|
+
store[serverId] = {
|
|
495
|
+
...(prev?.token ? { token: prev.token } : {}),
|
|
496
|
+
config: {
|
|
497
|
+
clientId: client.client_id,
|
|
498
|
+
tokenUrl: prev?.config.tokenUrl ?? SDK_MANAGED_TOKEN_URL,
|
|
353
499
|
},
|
|
500
|
+
client,
|
|
354
501
|
};
|
|
355
502
|
saveTokenStore(store);
|
|
356
503
|
}
|
|
@@ -363,12 +510,41 @@ export class MCPOAuthManager {
|
|
|
363
510
|
delete store[serverId];
|
|
364
511
|
saveTokenStore(store);
|
|
365
512
|
}
|
|
513
|
+
/** Drop access/refresh tokens only; keep client_id and DCR metadata. */
|
|
514
|
+
clearTokens(serverId) {
|
|
515
|
+
this.tokenCache.delete(serverId);
|
|
516
|
+
const store = loadTokenStore();
|
|
517
|
+
const prev = store[serverId];
|
|
518
|
+
if (!prev)
|
|
519
|
+
return;
|
|
520
|
+
const { token: _dropped, ...rest } = prev;
|
|
521
|
+
store[serverId] = rest;
|
|
522
|
+
if (!rest.client && !rest.config?.clientId)
|
|
523
|
+
delete store[serverId];
|
|
524
|
+
saveTokenStore(store);
|
|
525
|
+
}
|
|
366
526
|
/**
|
|
367
527
|
* Check if a token exists for a server (may be expired)
|
|
368
528
|
*/
|
|
529
|
+
/** Stored token and client id for a server, without refresh side effects. */
|
|
530
|
+
getStoredToken(serverId) {
|
|
531
|
+
const entry = loadTokenStore()[serverId];
|
|
532
|
+
if (!entry?.token?.accessToken)
|
|
533
|
+
return null;
|
|
534
|
+
return { token: entry.token, clientId: entry.config.clientId, ...(entry.client ? { client: entry.client } : {}) };
|
|
535
|
+
}
|
|
536
|
+
/** Persisted client id / DCR metadata, independent of whether a token exists. */
|
|
537
|
+
getStoredClientInformation(serverId) {
|
|
538
|
+
const entry = loadTokenStore()[serverId];
|
|
539
|
+
if (entry?.client?.client_id)
|
|
540
|
+
return entry.client;
|
|
541
|
+
if (entry?.config.clientId)
|
|
542
|
+
return { client_id: entry.config.clientId };
|
|
543
|
+
return null;
|
|
544
|
+
}
|
|
369
545
|
hasToken(serverId) {
|
|
370
546
|
const store = loadTokenStore();
|
|
371
|
-
return serverId
|
|
547
|
+
return Boolean(store[serverId]?.token?.accessToken);
|
|
372
548
|
}
|
|
373
549
|
}
|
|
374
550
|
// ============================================================================
|
package/dist/mcp/transports.d.ts
CHANGED
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
import { Transport } from "@modelcontextprotocol/sdk/shared/transport.js";
|
|
2
|
+
import { type MCPTransportOAuthConfig } from "./mcp-oauth-provider.js";
|
|
2
3
|
import { EventEmitter } from "events";
|
|
3
|
-
export type TransportType = 'stdio' | 'http' | 'sse' | 'streamable_http';
|
|
4
|
+
export type TransportType = 'stdio' | 'http' | 'sse' | 'sse_sdk' | 'legacy_rpc' | 'streamable_http';
|
|
4
5
|
export interface TransportConfig {
|
|
5
6
|
type: TransportType;
|
|
6
7
|
command?: string;
|
|
8
|
+
cwd?: string;
|
|
9
|
+
/** Imported stdio servers receive SDK baseline env plus explicit declarations only. */
|
|
10
|
+
inheritEnv?: boolean;
|
|
7
11
|
args?: string[];
|
|
8
12
|
env?: Record<string, string>;
|
|
9
13
|
url?: string;
|
|
10
14
|
headers?: Record<string, string>;
|
|
15
|
+
/** OAuth bearer for HTTP transports (SDK discovery + PKCE, tokens in .codebuddy/mcp-tokens.json). */
|
|
16
|
+
auth?: MCPTransportOAuthConfig;
|
|
11
17
|
}
|
|
12
18
|
export interface MCPTransport {
|
|
13
19
|
connect(): Promise<Transport>;
|
|
@@ -31,9 +37,9 @@ export declare class HttpTransport extends EventEmitter implements MCPTransport
|
|
|
31
37
|
disconnect(): Promise<void>;
|
|
32
38
|
getType(): TransportType;
|
|
33
39
|
}
|
|
34
|
-
export declare class SSETransport
|
|
40
|
+
export declare class SSETransport implements MCPTransport {
|
|
35
41
|
private config;
|
|
36
|
-
private
|
|
42
|
+
private transport?;
|
|
37
43
|
constructor(config: TransportConfig);
|
|
38
44
|
connect(): Promise<Transport>;
|
|
39
45
|
disconnect(): Promise<void>;
|
|
@@ -41,10 +47,13 @@ export declare class SSETransport extends EventEmitter implements MCPTransport {
|
|
|
41
47
|
}
|
|
42
48
|
export declare class StreamableHttpTransport extends EventEmitter implements MCPTransport {
|
|
43
49
|
private config;
|
|
44
|
-
private
|
|
50
|
+
private transport?;
|
|
51
|
+
private oauthProvider?;
|
|
45
52
|
constructor(config: TransportConfig);
|
|
46
53
|
connect(): Promise<Transport>;
|
|
47
54
|
disconnect(): Promise<void>;
|
|
48
55
|
getType(): TransportType;
|
|
49
56
|
}
|
|
50
|
-
|
|
57
|
+
/** Resolve references only at connection time; missing credentials fail closed. */
|
|
58
|
+
export declare function resolveMCPTransport(config: TransportConfig): TransportConfig;
|
|
59
|
+
export declare function createTransport(input: TransportConfig): MCPTransport;
|