@earendil-works/pi-coding-agent 0.87.1 → 0.99.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/CHANGELOG.md +79 -0
- package/dist/bun/cli.d.ts.map +1 -1
- package/dist/bun/restore-sandbox-env.d.ts.map +1 -1
- package/dist/bun/restore-sandbox-env.js.map +1 -1
- package/dist/bun/runtime-setup.d.ts.map +1 -1
- package/dist/bun/runtime-setup.js +4 -1
- package/dist/bun/runtime-setup.js.map +1 -1
- package/dist/bun/sandbox-env-setup.d.ts.map +1 -1
- package/dist/bundle/chunks/anthropic-messages-A6EXUBG6.js +6 -0
- package/dist/bundle/chunks/anthropic.js +2 -2
- package/dist/bundle/chunks/azure-openai-responses-EN5WOBET.js +2 -0
- package/dist/bundle/chunks/bedrock-converse-stream.js +2 -2
- package/dist/bundle/chunks/chunk-4CSSZFEW.js +1435 -0
- package/dist/bundle/chunks/chunk-7JGR3GZN.js +11 -0
- package/dist/bundle/chunks/chunk-AXPY26X7.js +146 -0
- package/dist/bundle/chunks/chunk-EPDRUIU6.js +2 -0
- package/dist/bundle/chunks/chunk-GOPCREV2.js +4 -0
- package/dist/bundle/chunks/chunk-H3QXYIF7.js +31 -0
- package/dist/bundle/chunks/{chunk-S7SZN6Z3.js → chunk-HSPCVFST.js} +1 -1
- package/dist/bundle/chunks/chunk-IMTXZUO7.js +82 -0
- package/dist/bundle/chunks/chunk-J4CWPC4N.js +2 -0
- package/dist/bundle/chunks/chunk-LLMKQWZS.js +21 -0
- package/dist/bundle/chunks/{chunk-WIUZI2CJ.js → chunk-LRS5S6EK.js} +3 -3
- package/dist/bundle/chunks/chunk-PEHWOV5U.js +187 -0
- package/dist/bundle/chunks/{chunk-XDUWOHPL.js → chunk-S3GGRYIO.js} +2 -2
- package/dist/bundle/chunks/chunk-UTB4DTYQ.js +2 -0
- package/dist/bundle/chunks/{chunk-FUXEF6JQ.js → chunk-W2DOMZSC.js} +1 -1
- package/dist/bundle/chunks/cli-AZXNGIZH.js +49 -0
- package/dist/bundle/chunks/cloudflare-workers-ai-system-one-XJQQYGGU.js +2 -0
- package/dist/bundle/chunks/codemode-worker.js +295 -0
- package/dist/bundle/chunks/execute-7XXPZAWW.js +308 -0
- package/dist/bundle/chunks/github-copilot.js +1 -1
- package/dist/bundle/chunks/google-generative-ai-CQAKKJTA.js +2 -0
- package/dist/bundle/chunks/google-vertex-AE36YXJU.js +2 -0
- package/dist/bundle/chunks/{lib-HGQMNYVT.js → lib-TEDK3E5I.js} +2 -2
- package/dist/bundle/chunks/llama-cpp-classify-PJJYKPLD.js +22 -0
- package/dist/bundle/chunks/mistral-conversations-KEYTXJM7.js +5 -0
- package/dist/bundle/chunks/{openai-codex-responses-QDSOTBBO.js → openai-codex-responses-JQTCOVEG.js} +2 -2
- package/dist/bundle/chunks/openai-codex.js +2 -2
- package/dist/bundle/chunks/{openai-completions-OBX42CLD.js → openai-completions-XW2Q5HVC.js} +2 -2
- package/dist/bundle/chunks/openai-responses-6AXWFL75.js +3 -0
- package/dist/bundle/chunks/{openrouter-images-N4XVVFSD.js → openrouter-images-TPQ4V6OR.js} +1 -1
- package/dist/bundle/chunks/openrouter.js +2 -2
- package/dist/bundle/chunks/{pi-messages-GFKBWJHZ.js → pi-messages-TM5SOOIW.js} +2 -2
- package/dist/bundle/chunks/radius.js +2 -2
- package/dist/bundle/chunks/runtime-G5WJPRBM.js +2 -0
- package/dist/bundle/chunks/typesafe-system-one-E7A4HNJI.js +2 -0
- package/dist/bundle/chunks/virtual-modules-AQ3FLU6H.js +2 -0
- package/dist/bundle/cli-runtime.js +1 -1
- package/dist/bundle/index.js +1 -1
- package/dist/bundle/rpc-entry.js +1 -1
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +4 -3
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/auth-check.d.ts.map +1 -1
- package/dist/cli/auth-check.js.map +1 -1
- package/dist/cli/auth-command.d.ts.map +1 -1
- package/dist/cli/auth-command.js.map +1 -1
- package/dist/cli/config-selector.d.ts.map +1 -1
- package/dist/cli/config-selector.js.map +1 -1
- package/dist/cli/credential-print.d.ts.map +1 -1
- package/dist/cli/credential-print.js.map +1 -1
- package/dist/cli/file-processor.d.ts.map +1 -1
- package/dist/cli/file-processor.js.map +1 -1
- package/dist/cli/initial-message.d.ts +1 -1
- package/dist/cli/initial-message.d.ts.map +1 -1
- package/dist/cli/initial-message.js.map +1 -1
- package/dist/cli/list-models.d.ts.map +1 -1
- package/dist/cli/list-models.js.map +1 -1
- package/dist/cli/project-trust.d.ts.map +1 -1
- package/dist/cli/project-trust.js.map +1 -1
- package/dist/cli/session-picker.d.ts.map +1 -1
- package/dist/cli/session-picker.js.map +1 -1
- package/dist/cli/setup.d.ts.map +1 -1
- package/dist/cli/setup.js.map +1 -1
- package/dist/cli/startup-ui.d.ts.map +1 -1
- package/dist/cli/startup-ui.js +38 -30
- package/dist/cli/startup-ui.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/config.d.ts +18 -4
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +30 -4
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session-runtime.d.ts.map +1 -1
- package/dist/core/agent-session-runtime.js +1 -1
- package/dist/core/agent-session-runtime.js.map +1 -1
- package/dist/core/agent-session-services.d.ts.map +1 -1
- package/dist/core/agent-session-services.js +13 -0
- package/dist/core/agent-session-services.js.map +1 -1
- package/dist/core/agent-session.d.ts +135 -11
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +509 -253
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/auth-guidance.d.ts.map +1 -1
- package/dist/core/auth-guidance.js.map +1 -1
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/bash-executor.d.ts.map +1 -1
- package/dist/core/bash-executor.js.map +1 -1
- package/dist/core/bug-report-upload.d.ts.map +1 -1
- package/dist/core/bug-report-upload.js.map +1 -1
- package/dist/core/bug-report.d.ts +1 -1
- package/dist/core/bug-report.d.ts.map +1 -1
- package/dist/core/bug-report.js +1 -1
- package/dist/core/bug-report.js.map +1 -1
- package/dist/core/cache-stats.d.ts.map +1 -1
- package/dist/core/cache-stats.js.map +1 -1
- package/dist/core/cache-warmer.d.ts.map +1 -1
- package/dist/core/cache-warmer.js.map +1 -1
- package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
- package/dist/core/compaction/branch-summarization.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +1 -22
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/compaction/index.d.ts.map +1 -1
- package/dist/core/compaction/utils.d.ts +2 -1
- package/dist/core/compaction/utils.d.ts.map +1 -1
- package/dist/core/compaction/utils.js +25 -18
- package/dist/core/compaction/utils.js.map +1 -1
- package/dist/core/crash-log.d.ts.map +1 -1
- package/dist/core/crash-log.js +2 -1
- package/dist/core/crash-log.js.map +1 -1
- package/dist/core/defaults.d.ts.map +1 -1
- package/dist/core/diagnostics.d.ts.map +1 -1
- package/dist/core/event-bus.d.ts.map +1 -1
- package/dist/core/event-bus.js.map +1 -1
- package/dist/core/exec.d.ts.map +1 -1
- package/dist/core/exec.js.map +1 -1
- package/dist/core/experimental.d.ts.map +1 -1
- package/dist/core/experimental.js.map +1 -1
- package/dist/core/export-html/ansi-to-html.d.ts.map +1 -1
- package/dist/core/export-html/ansi-to-html.js.map +1 -1
- package/dist/core/export-html/index.d.ts.map +1 -1
- package/dist/core/export-html/index.js.map +1 -1
- package/dist/core/export-html/template.css +10 -0
- package/dist/core/export-html/template.js +66 -17
- package/dist/core/export-html/tool-renderer.d.ts.map +1 -1
- package/dist/core/export-html/tool-renderer.js.map +1 -1
- package/dist/core/extensions/index.d.ts +1 -1
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/jiti-loader.d.ts.map +1 -1
- package/dist/core/extensions/jiti-static-loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +55 -5
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +18 -1
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +99 -0
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +296 -22
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/extensions/virtual-modules.d.ts.map +1 -1
- package/dist/core/extensions/wrapper.d.ts +2 -2
- package/dist/core/extensions/wrapper.d.ts.map +1 -1
- package/dist/core/extensions/wrapper.js +3 -3
- package/dist/core/extensions/wrapper.js.map +1 -1
- package/dist/core/footer-data-provider.d.ts.map +1 -1
- package/dist/core/footer-data-provider.js.map +1 -1
- package/dist/core/http-dispatcher.d.ts.map +1 -1
- package/dist/core/http-dispatcher.js.map +1 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/keybindings.d.ts +1 -1
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +1 -1
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/mcp-servers.d.ts +98 -0
- package/dist/core/mcp-servers.d.ts.map +1 -0
- package/dist/core/mcp-servers.js +157 -0
- package/dist/core/mcp-servers.js.map +1 -0
- package/dist/core/messages.d.ts.map +1 -1
- package/dist/core/messages.js.map +1 -1
- package/dist/core/model-config.d.ts.map +1 -1
- package/dist/core/model-config.js.map +1 -1
- package/dist/core/model-registry.d.ts +13 -1
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +25 -0
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/model-resolver.d.ts +2 -2
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +4 -4
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/model-runtime.d.ts +41 -3
- package/dist/core/model-runtime.d.ts.map +1 -1
- package/dist/core/model-runtime.js +167 -17
- package/dist/core/model-runtime.js.map +1 -1
- package/dist/core/models-store.d.ts.map +1 -1
- package/dist/core/models-store.js.map +1 -1
- package/dist/core/nested-tool-calls.d.ts +102 -0
- package/dist/core/nested-tool-calls.d.ts.map +1 -0
- package/dist/core/nested-tool-calls.js +178 -0
- package/dist/core/nested-tool-calls.js.map +1 -0
- package/dist/core/output-guard.d.ts.map +1 -1
- package/dist/core/output-guard.js.map +1 -1
- package/dist/core/package-manager.d.ts +4 -0
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +59 -12
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/pi-manifest.d.ts.map +1 -1
- package/dist/core/pi-manifest.js.map +1 -1
- package/dist/core/project-trust.d.ts.map +1 -1
- package/dist/core/project-trust.js.map +1 -1
- package/dist/core/prompt-templates.d.ts.map +1 -1
- package/dist/core/prompt-templates.js.map +1 -1
- package/dist/core/provider-attribution.d.ts.map +1 -1
- package/dist/core/provider-attribution.js.map +1 -1
- package/dist/core/provider-composer.d.ts +40 -21
- package/dist/core/provider-composer.d.ts.map +1 -1
- package/dist/core/provider-composer.js +92 -40
- package/dist/core/provider-composer.js.map +1 -1
- package/dist/core/radius.d.ts.map +1 -1
- package/dist/core/radius.js.map +1 -1
- package/dist/core/remote-catalog-provider.d.ts +8 -1
- package/dist/core/remote-catalog-provider.d.ts.map +1 -1
- package/dist/core/remote-catalog-provider.js +18 -3
- package/dist/core/remote-catalog-provider.js.map +1 -1
- package/dist/core/resolve-config-value.d.ts.map +1 -1
- package/dist/core/resolve-config-value.js.map +1 -1
- package/dist/core/resource-loader.d.ts +7 -1
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +161 -35
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/runtime-credentials.d.ts.map +1 -1
- package/dist/core/runtime-credentials.js.map +1 -1
- package/dist/core/sdk.d.ts +1 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +24 -6
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-cwd.d.ts.map +1 -1
- package/dist/core/session-cwd.js.map +1 -1
- package/dist/core/session-export.d.ts.map +1 -1
- package/dist/core/session-export.js.map +1 -1
- package/dist/core/session-manager.d.ts +9 -0
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +22 -22
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-diagnostics.d.ts.map +1 -1
- package/dist/core/settings-diagnostics.js.map +1 -1
- package/dist/core/settings-manager.d.ts +31 -1
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +72 -2
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/skills.d.ts.map +1 -1
- package/dist/core/skills.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/source-info.d.ts +8 -0
- package/dist/core/source-info.d.ts.map +1 -1
- package/dist/core/source-info.js +16 -0
- package/dist/core/source-info.js.map +1 -1
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +1 -1
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/telemetry.d.ts.map +1 -1
- package/dist/core/telemetry.js.map +1 -1
- package/dist/core/timings.d.ts.map +1 -1
- package/dist/core/timings.js.map +1 -1
- package/dist/core/tools/bash.d.ts +12 -0
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +35 -2
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/edit-diff.d.ts.map +1 -1
- package/dist/core/tools/edit-diff.js.map +1 -1
- package/dist/core/tools/edit.d.ts.map +1 -1
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/file-mutation-queue.d.ts.map +1 -1
- package/dist/core/tools/file-mutation-queue.js.map +1 -1
- package/dist/core/tools/find.d.ts.map +1 -1
- package/dist/core/tools/find.js.map +1 -1
- package/dist/core/tools/grep.d.ts.map +1 -1
- package/dist/core/tools/grep.js.map +1 -1
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js.map +1 -1
- package/dist/core/tools/ls.d.ts.map +1 -1
- package/dist/core/tools/ls.js.map +1 -1
- package/dist/core/tools/output-accumulator.d.ts +11 -0
- package/dist/core/tools/output-accumulator.d.ts.map +1 -1
- package/dist/core/tools/output-accumulator.js +36 -0
- package/dist/core/tools/output-accumulator.js.map +1 -1
- package/dist/core/tools/path-utils.d.ts.map +1 -1
- package/dist/core/tools/path-utils.js.map +1 -1
- package/dist/core/tools/powershell.d.ts.map +1 -1
- package/dist/core/tools/powershell.js.map +1 -1
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js.map +1 -1
- package/dist/core/tools/render-utils.d.ts +6 -0
- package/dist/core/tools/render-utils.d.ts.map +1 -1
- package/dist/core/tools/render-utils.js +26 -0
- package/dist/core/tools/render-utils.js.map +1 -1
- package/dist/core/tools/renderers/bash.d.ts.map +1 -1
- package/dist/core/tools/renderers/bash.js +9 -10
- package/dist/core/tools/renderers/bash.js.map +1 -1
- package/dist/core/tools/renderers/edit.d.ts.map +1 -1
- package/dist/core/tools/renderers/edit.js.map +1 -1
- package/dist/core/tools/renderers/find.d.ts.map +1 -1
- package/dist/core/tools/renderers/find.js.map +1 -1
- package/dist/core/tools/renderers/grep.d.ts.map +1 -1
- package/dist/core/tools/renderers/grep.js.map +1 -1
- package/dist/core/tools/renderers/index.d.ts.map +1 -1
- package/dist/core/tools/renderers/index.js.map +1 -1
- package/dist/core/tools/renderers/ls.d.ts.map +1 -1
- package/dist/core/tools/renderers/ls.js.map +1 -1
- package/dist/core/tools/renderers/read.d.ts.map +1 -1
- package/dist/core/tools/renderers/read.js +3 -2
- package/dist/core/tools/renderers/read.js.map +1 -1
- package/dist/core/tools/renderers/write.d.ts.map +1 -1
- package/dist/core/tools/renderers/write.js.map +1 -1
- package/dist/core/tools/tool-definition-wrapper.d.ts +5 -3
- package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -1
- package/dist/core/tools/tool-definition-wrapper.js +3 -1
- package/dist/core/tools/tool-definition-wrapper.js.map +1 -1
- package/dist/core/tools/truncate.d.ts +14 -0
- package/dist/core/tools/truncate.d.ts.map +1 -1
- package/dist/core/tools/truncate.js +29 -0
- package/dist/core/tools/truncate.js.map +1 -1
- package/dist/core/tools/write.d.ts.map +1 -1
- package/dist/core/tools/write.js.map +1 -1
- package/dist/core/trust-manager.d.ts.map +1 -1
- package/dist/core/trust-manager.js +1 -0
- package/dist/core/trust-manager.js.map +1 -1
- package/dist/core/usage-totals.d.ts +2 -0
- package/dist/core/usage-totals.d.ts.map +1 -1
- package/dist/core/usage-totals.js +23 -0
- package/dist/core/usage-totals.js.map +1 -1
- package/dist/core/virtual-models.d.ts +115 -0
- package/dist/core/virtual-models.d.ts.map +1 -0
- package/dist/core/virtual-models.js +117 -0
- package/dist/core/virtual-models.js.map +1 -0
- package/dist/extensions/codemode/execute.d.ts +16 -0
- package/dist/extensions/codemode/execute.d.ts.map +1 -0
- package/dist/extensions/codemode/execute.js +390 -0
- package/dist/extensions/codemode/execute.js.map +1 -0
- package/dist/extensions/codemode/execute.lazy.d.ts +3 -0
- package/dist/extensions/codemode/execute.lazy.d.ts.map +1 -0
- package/dist/extensions/codemode/execute.lazy.js +3 -0
- package/dist/extensions/codemode/execute.lazy.js.map +1 -0
- package/dist/extensions/codemode/index.d.ts +21 -0
- package/dist/extensions/codemode/index.d.ts.map +1 -0
- package/dist/extensions/codemode/index.js +31 -0
- package/dist/extensions/codemode/index.js.map +1 -0
- package/dist/extensions/codemode/renderer.d.ts +12 -0
- package/dist/extensions/codemode/renderer.d.ts.map +1 -0
- package/dist/extensions/codemode/renderer.js +119 -0
- package/dist/extensions/codemode/renderer.js.map +1 -0
- package/dist/extensions/codemode/tool.d.ts +122 -0
- package/dist/extensions/codemode/tool.d.ts.map +1 -0
- package/dist/extensions/codemode/tool.js +324 -0
- package/dist/extensions/codemode/tool.js.map +1 -0
- package/dist/extensions/codemode/worker.d.ts +7 -0
- package/dist/extensions/codemode/worker.d.ts.map +1 -0
- package/dist/extensions/codemode/worker.js +7 -0
- package/dist/extensions/codemode/worker.js.map +1 -0
- package/dist/extensions/index.d.ts.map +1 -1
- package/dist/extensions/index.js +11 -1
- package/dist/extensions/index.js.map +1 -1
- package/dist/extensions/llama/client.d.ts.map +1 -1
- package/dist/extensions/llama/client.js.map +1 -1
- package/dist/extensions/llama/huggingface.d.ts.map +1 -1
- package/dist/extensions/llama/huggingface.js.map +1 -1
- package/dist/extensions/llama/index.d.ts.map +1 -1
- package/dist/extensions/llama/index.js.map +1 -1
- package/dist/extensions/llama/provider.d.ts +1 -1
- package/dist/extensions/llama/provider.d.ts.map +1 -1
- package/dist/extensions/llama/provider.js +65 -13
- package/dist/extensions/llama/provider.js.map +1 -1
- package/dist/extensions/llama/ui.d.ts.map +1 -1
- package/dist/extensions/llama/ui.js.map +1 -1
- package/dist/extensions/mcp/cli.d.ts +21 -0
- package/dist/extensions/mcp/cli.d.ts.map +1 -0
- package/dist/extensions/mcp/cli.js +485 -0
- package/dist/extensions/mcp/cli.js.map +1 -0
- package/dist/extensions/mcp/cli.lazy.d.ts +3 -0
- package/dist/extensions/mcp/cli.lazy.d.ts.map +1 -0
- package/dist/extensions/mcp/cli.lazy.js +3 -0
- package/dist/extensions/mcp/cli.lazy.js.map +1 -0
- package/dist/extensions/mcp/config.d.ts +70 -0
- package/dist/extensions/mcp/config.d.ts.map +1 -0
- package/dist/extensions/mcp/config.js +146 -0
- package/dist/extensions/mcp/config.js.map +1 -0
- package/dist/extensions/mcp/index.d.ts +52 -0
- package/dist/extensions/mcp/index.d.ts.map +1 -0
- package/dist/extensions/mcp/index.js +902 -0
- package/dist/extensions/mcp/index.js.map +1 -0
- package/dist/extensions/mcp/log.d.ts +16 -0
- package/dist/extensions/mcp/log.d.ts.map +1 -0
- package/dist/extensions/mcp/log.js +66 -0
- package/dist/extensions/mcp/log.js.map +1 -0
- package/dist/extensions/mcp/oauth.d.ts +94 -0
- package/dist/extensions/mcp/oauth.d.ts.map +1 -0
- package/dist/extensions/mcp/oauth.js +333 -0
- package/dist/extensions/mcp/oauth.js.map +1 -0
- package/dist/extensions/mcp/resources.d.ts +43 -0
- package/dist/extensions/mcp/resources.d.ts.map +1 -0
- package/dist/extensions/mcp/resources.js +262 -0
- package/dist/extensions/mcp/resources.js.map +1 -0
- package/dist/extensions/mcp/runtime.d.ts +96 -0
- package/dist/extensions/mcp/runtime.d.ts.map +1 -0
- package/dist/extensions/mcp/runtime.js +388 -0
- package/dist/extensions/mcp/runtime.js.map +1 -0
- package/dist/extensions/mcp/runtime.lazy.d.ts +3 -0
- package/dist/extensions/mcp/runtime.lazy.d.ts.map +1 -0
- package/dist/extensions/mcp/runtime.lazy.js +3 -0
- package/dist/extensions/mcp/runtime.lazy.js.map +1 -0
- package/dist/extensions/mcp/tools.d.ts +83 -0
- package/dist/extensions/mcp/tools.d.ts.map +1 -0
- package/dist/extensions/mcp/tools.js +233 -0
- package/dist/extensions/mcp/tools.js.map +1 -0
- package/dist/extensions/mcp/ui.d.ts +60 -0
- package/dist/extensions/mcp/ui.d.ts.map +1 -0
- package/dist/extensions/mcp/ui.js +172 -0
- package/dist/extensions/mcp/ui.js.map +1 -0
- package/dist/extensions/tool-search/index.d.ts +12 -0
- package/dist/extensions/tool-search/index.d.ts.map +1 -0
- package/dist/extensions/tool-search/index.js +15 -0
- package/dist/extensions/tool-search/index.js.map +1 -0
- package/dist/extensions/tool-search/tool.d.ts +72 -0
- package/dist/extensions/tool-search/tool.d.ts.map +1 -0
- package/dist/extensions/tool-search/tool.js +210 -0
- package/dist/extensions/tool-search/tool.js.map +1 -0
- package/dist/index.d.ts +9 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +10 -0
- package/dist/main.js.map +1 -1
- package/dist/migrations.d.ts.map +1 -1
- package/dist/migrations.js.map +1 -1
- package/dist/modes/index.d.ts.map +1 -1
- package/dist/modes/interactive/bug-report.d.ts.map +1 -1
- package/dist/modes/interactive/bug-report.js.map +1 -1
- package/dist/modes/interactive/chat-viewport.d.ts.map +1 -1
- package/dist/modes/interactive/chat-viewport.js.map +1 -1
- package/dist/modes/interactive/components/armin.d.ts.map +1 -1
- package/dist/modes/interactive/components/armin.js.map +1 -1
- package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/bash-execution.js.map +1 -1
- package/dist/modes/interactive/components/bordered-loader.d.ts.map +1 -1
- package/dist/modes/interactive/components/bordered-loader.js.map +1 -1
- package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
- package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/config-selector.js +13 -3
- package/dist/modes/interactive/components/config-selector.js.map +1 -1
- package/dist/modes/interactive/components/countdown-timer.d.ts.map +1 -1
- package/dist/modes/interactive/components/countdown-timer.js.map +1 -1
- package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-editor.js.map +1 -1
- package/dist/modes/interactive/components/custom-entry.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-entry.js.map +1 -1
- package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-message.js.map +1 -1
- package/dist/modes/interactive/components/daxnuts.d.ts.map +1 -1
- package/dist/modes/interactive/components/daxnuts.js.map +1 -1
- package/dist/modes/interactive/components/diff.d.ts.map +1 -1
- package/dist/modes/interactive/components/diff.js.map +1 -1
- package/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -1
- package/dist/modes/interactive/components/dynamic-border.js.map +1 -1
- package/dist/modes/interactive/components/earendil-announcement.d.ts.map +1 -1
- package/dist/modes/interactive/components/earendil-announcement.js.map +1 -1
- package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-editor.js.map +1 -1
- package/dist/modes/interactive/components/extension-input.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-input.js.map +1 -1
- package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-selector.js.map +1 -1
- package/dist/modes/interactive/components/first-time-setup.d.ts +4 -4
- package/dist/modes/interactive/components/first-time-setup.d.ts.map +1 -1
- package/dist/modes/interactive/components/first-time-setup.js +8 -2
- package/dist/modes/interactive/components/first-time-setup.js.map +1 -1
- package/dist/modes/interactive/components/footer.d.ts +7 -0
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +43 -3
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/components/index.d.ts.map +1 -1
- package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -1
- package/dist/modes/interactive/components/keybinding-hints.js.map +1 -1
- package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
- package/dist/modes/interactive/components/login-dialog.js.map +1 -1
- package/dist/modes/interactive/components/markdown-transform.d.ts.map +1 -1
- package/dist/modes/interactive/components/markdown-transform.js.map +1 -1
- package/dist/modes/interactive/components/mermaid.d.ts.map +1 -1
- package/dist/modes/interactive/components/mermaid.js.map +1 -1
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
- package/dist/modes/interactive/components/pi-logo.d.ts +12 -0
- package/dist/modes/interactive/components/pi-logo.d.ts.map +1 -0
- package/dist/modes/interactive/components/pi-logo.js +25 -0
- package/dist/modes/interactive/components/pi-logo.js.map +1 -0
- package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
- package/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -1
- package/dist/modes/interactive/components/session-selector-search.js.map +1 -1
- package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/session-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts +3 -1
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +28 -6
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-submenu.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-submenu.js.map +1 -1
- package/dist/modes/interactive/components/show-images-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/show-images-selector.js.map +1 -1
- package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
- package/dist/modes/interactive/components/status-indicator.d.ts.map +1 -1
- package/dist/modes/interactive/components/status-indicator.js.map +1 -1
- package/dist/modes/interactive/components/theme-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/theme-selector.js.map +1 -1
- package/dist/modes/interactive/components/themed-text.d.ts +17 -0
- package/dist/modes/interactive/components/themed-text.d.ts.map +1 -0
- package/dist/modes/interactive/components/themed-text.js +29 -0
- package/dist/modes/interactive/components/themed-text.js.map +1 -0
- package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +2 -2
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/tree-selector.js.map +1 -1
- package/dist/modes/interactive/components/trust-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/trust-selector.js.map +1 -1
- package/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/user-message-selector.js.map +1 -1
- package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/user-message.js.map +1 -1
- package/dist/modes/interactive/components/visual-truncate.d.ts.map +1 -1
- package/dist/modes/interactive/components/visual-truncate.js.map +1 -1
- package/dist/modes/interactive/external-editor.d.ts.map +1 -1
- package/dist/modes/interactive/external-editor.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +11 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +199 -161
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/model-catalog-refresh.d.ts.map +1 -1
- package/dist/modes/interactive/model-catalog-refresh.js.map +1 -1
- package/dist/modes/interactive/model-search.d.ts.map +1 -1
- package/dist/modes/interactive/model-search.js.map +1 -1
- package/dist/modes/interactive/session-share.d.ts.map +1 -1
- package/dist/modes/interactive/session-share.js.map +1 -1
- package/dist/modes/interactive/theme/dark.json +59 -72
- package/dist/modes/interactive/theme/light.json +57 -69
- package/dist/modes/interactive/theme/system-theme.d.ts +54 -0
- package/dist/modes/interactive/theme/system-theme.d.ts.map +1 -0
- package/dist/modes/interactive/theme/system-theme.js +535 -0
- package/dist/modes/interactive/theme/system-theme.js.map +1 -0
- package/dist/modes/interactive/theme/theme-controller.d.ts +46 -6
- package/dist/modes/interactive/theme/theme-controller.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme-controller.js +127 -47
- package/dist/modes/interactive/theme/theme-controller.js.map +1 -1
- package/dist/modes/interactive/theme/theme-json.d.ts +1 -0
- package/dist/modes/interactive/theme/theme-json.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme-json.js +3 -1
- package/dist/modes/interactive/theme/theme-json.js.map +1 -1
- package/dist/modes/interactive/theme/theme-schema.json +7 -2
- package/dist/modes/interactive/theme/theme.d.ts +66 -39
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +238 -317
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/dist/modes/interactive/tui-renderer.d.ts +2 -1
- package/dist/modes/interactive/tui-renderer.d.ts.map +1 -1
- package/dist/modes/interactive/tui-renderer.js +1 -0
- package/dist/modes/interactive/tui-renderer.js.map +1 -1
- package/dist/modes/json-event.d.ts.map +1 -1
- package/dist/modes/json-event.js.map +1 -1
- package/dist/modes/print-mode.d.ts.map +1 -1
- package/dist/modes/print-mode.js.map +1 -1
- package/dist/modes/rpc/jsonl.d.ts.map +1 -1
- package/dist/modes/rpc/jsonl.js.map +1 -1
- package/dist/modes/rpc/rpc-client.d.ts +6 -6
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js +12 -8
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +7 -9
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +10 -1
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/dist/package-manager-cli.d.ts.map +1 -1
- package/dist/package-manager-cli.js +6 -2
- package/dist/package-manager-cli.js.map +1 -1
- package/dist/rpc-entry.d.ts.map +1 -1
- package/dist/rpc-entry.js.map +1 -1
- package/dist/utils/abort.d.ts.map +1 -1
- package/dist/utils/abort.js.map +1 -1
- package/dist/utils/ansi.d.ts.map +1 -1
- package/dist/utils/ansi.js.map +1 -1
- package/dist/utils/changelog.d.ts.map +1 -1
- package/dist/utils/changelog.js.map +1 -1
- package/dist/utils/child-process.d.ts.map +1 -1
- package/dist/utils/child-process.js.map +1 -1
- package/dist/utils/clipboard-command.d.ts.map +1 -1
- package/dist/utils/clipboard-command.js.map +1 -1
- package/dist/utils/clipboard-image.d.ts.map +1 -1
- package/dist/utils/clipboard-image.js +14 -17
- package/dist/utils/clipboard-image.js.map +1 -1
- package/dist/utils/clipboard.d.ts +2 -0
- package/dist/utils/clipboard.d.ts.map +1 -1
- package/dist/utils/clipboard.js +5 -0
- package/dist/utils/clipboard.js.map +1 -1
- package/dist/utils/deprecation.d.ts.map +1 -1
- package/dist/utils/deprecation.js.map +1 -1
- package/dist/utils/exif-orientation.d.ts.map +1 -1
- package/dist/utils/exif-orientation.js.map +1 -1
- package/dist/utils/frontmatter.d.ts.map +1 -1
- package/dist/utils/frontmatter.js.map +1 -1
- package/dist/utils/fs-watch.d.ts.map +1 -1
- package/dist/utils/fs-watch.js.map +1 -1
- package/dist/utils/git.d.ts.map +1 -1
- package/dist/utils/git.js.map +1 -1
- package/dist/utils/html.d.ts.map +1 -1
- package/dist/utils/html.js.map +1 -1
- package/dist/utils/image-convert.d.ts.map +1 -1
- package/dist/utils/image-convert.js.map +1 -1
- package/dist/utils/image-process.d.ts.map +1 -1
- package/dist/utils/image-process.js.map +1 -1
- package/dist/utils/image-resize-core.d.ts.map +1 -1
- package/dist/utils/image-resize-core.js.map +1 -1
- package/dist/utils/image-resize-worker.d.ts.map +1 -1
- package/dist/utils/image-resize-worker.js.map +1 -1
- package/dist/utils/image-resize.d.ts.map +1 -1
- package/dist/utils/image-resize.js.map +1 -1
- package/dist/utils/json.d.ts.map +1 -1
- package/dist/utils/json.js.map +1 -1
- package/dist/utils/management-http.d.ts.map +1 -1
- package/dist/utils/management-http.js.map +1 -1
- package/dist/utils/mime.d.ts.map +1 -1
- package/dist/utils/mime.js.map +1 -1
- package/dist/utils/open-browser.d.ts.map +1 -1
- package/dist/utils/open-browser.js.map +1 -1
- package/dist/utils/paths.d.ts +3 -3
- package/dist/utils/paths.d.ts.map +1 -1
- package/dist/utils/paths.js +5 -4
- package/dist/utils/paths.js.map +1 -1
- package/dist/utils/photon.d.ts.map +1 -1
- package/dist/utils/photon.js.map +1 -1
- package/dist/utils/pi-user-agent.d.ts.map +1 -1
- package/dist/utils/pi-user-agent.js.map +1 -1
- package/dist/utils/shell.d.ts +1 -3
- package/dist/utils/shell.d.ts.map +1 -1
- package/dist/utils/shell.js +3 -30
- package/dist/utils/shell.js.map +1 -1
- package/dist/utils/sleep.d.ts.map +1 -1
- package/dist/utils/sleep.js.map +1 -1
- package/dist/utils/syntax-highlight.d.ts.map +1 -1
- package/dist/utils/syntax-highlight.js +2 -0
- package/dist/utils/syntax-highlight.js.map +1 -1
- package/dist/utils/text.d.ts.map +1 -1
- package/dist/utils/text.js.map +1 -1
- package/dist/utils/tool-result-images.d.ts.map +1 -1
- package/dist/utils/tool-result-images.js.map +1 -1
- package/dist/utils/tools-manager.d.ts.map +1 -1
- package/dist/utils/tools-manager.js.map +1 -1
- package/dist/utils/version-check.d.ts.map +1 -1
- package/dist/utils/version-check.js.map +1 -1
- package/dist/utils/windows-self-update.d.ts.map +1 -1
- package/dist/utils/windows-self-update.js.map +1 -1
- package/dist/utils/wsl.d.ts.map +1 -1
- package/dist/utils/wsl.js.map +1 -1
- package/dist/utils/zip.d.ts.map +1 -1
- package/dist/utils/zip.js.map +1 -1
- package/docs/cli.md +64 -3
- package/docs/configuration.md +2 -0
- package/docs/custom-provider.md +43 -4
- package/docs/docs.json +8 -0
- package/docs/extensions.md +55 -0
- package/docs/keybindings.md +1 -1
- package/docs/llama-cpp.md +13 -0
- package/docs/mcp.md +188 -0
- package/docs/models.md +35 -0
- package/docs/packages.md +4 -2
- package/docs/providers.md +1 -0
- package/docs/rpc-commands.md +9 -3
- package/docs/rpc.md +3 -1
- package/docs/sdk.md +7 -2
- package/docs/security.md +2 -0
- package/docs/session-format.md +5 -1
- package/docs/settings.md +20 -3
- package/docs/themes.md +33 -7
- package/docs/tui.md +18 -0
- package/docs/virtual-models.md +114 -0
- package/docs/windows.md +2 -0
- package/examples/README.md +1 -1
- package/examples/extensions/README.md +2 -0
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/test.ts +5 -5
- package/examples/extensions/debug-provider.ts +90 -0
- package/examples/extensions/gondolin/package-lock.json +2 -2
- package/examples/extensions/gondolin/package.json +1 -1
- package/examples/extensions/jev-router.ts +113 -0
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/examples/rpc-client.ts +1 -1
- package/examples/rpc-extension-ui.ts +1 -1
- package/examples/sdk/14-codemode-mcp.ts +61 -0
- package/examples/sdk/README.md +2 -1
- package/npm-shrinkwrap.json +89 -39
- package/package.json +14 -12
- package/dist/bundle/chunks/anthropic-messages-J5WXPPPC.js +0 -6
- package/dist/bundle/chunks/azure-openai-responses-HUSQ3GP2.js +0 -2
- package/dist/bundle/chunks/chunk-65HAU2C5.js +0 -2
- package/dist/bundle/chunks/chunk-6R7UI4IY.js +0 -2
- package/dist/bundle/chunks/chunk-NUHFSC37.js +0 -25
- package/dist/bundle/chunks/chunk-OJP47DM6.js +0 -1568
- package/dist/bundle/chunks/chunk-RCZIEVGO.js +0 -11
- package/dist/bundle/chunks/google-generative-ai-IMS5EK2Y.js +0 -2
- package/dist/bundle/chunks/google-vertex-O4YJEQUW.js +0 -2
- package/dist/bundle/chunks/mistral-conversations-NOSQHBEY.js +0 -5
- package/dist/bundle/chunks/openai-responses-HWEUZ6WZ.js +0 -2
- package/dist/bundle/chunks/virtual-modules-VHMJYYWQ.js +0 -2
|
@@ -0,0 +1,902 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Built-in MCP integration.
|
|
3
|
+
*
|
|
4
|
+
* Connects the servers from `mcp.json` and the servers extensions register with
|
|
5
|
+
* `pi.registerMcpServer()` when a session starts, and servers registered later right away. A server
|
|
6
|
+
* in `mcp.json` takes precedence over a registered server of the same name. Tools are registered as
|
|
7
|
+
* `mcp__<server>__<tool>`. By default (`"exposure": "codemode"`) the tools are only callable from
|
|
8
|
+
* codemode scripts, which keeps large MCP tool lists out of the model's tool declarations; the
|
|
9
|
+
* codemode tool is activated for that unless `autoEnableCodemode` is false. `"codemode-deferred"`
|
|
10
|
+
* leaves them out of the codemode description as well. `"deferred"` declares them to the model once
|
|
11
|
+
* the `tool_search` tool loads them, and activates `tool_search` instead of codemode.
|
|
12
|
+
* `"exposure": "direct"` declares them to the model right away, and `"hidden"` makes them
|
|
13
|
+
* unreachable. `toolExposure` overrides the exposure of single tools. Servers with resources are
|
|
14
|
+
* reached through Codex's `list_mcp_resources`, `list_mcp_resource_templates`, and
|
|
15
|
+
* `read_mcp_resource` tools (resources.ts).
|
|
16
|
+
*
|
|
17
|
+
* Every call runs through pi's tool pipeline, so `tool_call`/`tool_result` hooks and permission
|
|
18
|
+
* extensions apply to MCP tools the same way they do to built-in tools.
|
|
19
|
+
*
|
|
20
|
+
* Problems found at startup (config errors, failed connections, servers that need a sign-in) are
|
|
21
|
+
* reported once. `/mcp` opens a manager to sign in, reconnect, enable or disable servers, and change
|
|
22
|
+
* their exposure; the last two are saved to the `mcp.json` that defines the server, or apply to the
|
|
23
|
+
* current session for registered servers.
|
|
24
|
+
*/
|
|
25
|
+
import { join, resolve } from "node:path";
|
|
26
|
+
import { getAgentDir } from "../../config.js";
|
|
27
|
+
import { openBrowser } from "../../utils/open-browser.js";
|
|
28
|
+
import { CODEMODE_TOOL_NAME, isCodemodeTool } from "../codemode/tool.js";
|
|
29
|
+
import { isToolSearchTool, TOOL_SEARCH_TOOL_NAME } from "../tool-search/tool.js";
|
|
30
|
+
import { getMcpToolExposure, loadMcpConfig, updateMcpServerConfig, } from "./config.js";
|
|
31
|
+
import { createMcpResourceToolDefinitions } from "./resources.js";
|
|
32
|
+
import { loadMcpRuntime } from "./runtime.lazy.js";
|
|
33
|
+
import { createMcpToolDefinition, createMcpToolName } from "./tools.js";
|
|
34
|
+
import { showMcpManager } from "./ui.js";
|
|
35
|
+
const DEFAULT_STARTUP_WAIT_MS = 10_000;
|
|
36
|
+
const EXPOSURE_DESCRIPTIONS = {
|
|
37
|
+
codemode: "called from codemode scripts, listed in the codemode description",
|
|
38
|
+
"codemode-deferred": "called from codemode scripts, not listed; scripts find them with searchTools()",
|
|
39
|
+
deferred: "not declared until tool_search loads them, then called directly; no codemode needed",
|
|
40
|
+
direct: "declared to the model like built-in tools",
|
|
41
|
+
};
|
|
42
|
+
function errorMessage(error) {
|
|
43
|
+
return error instanceof Error ? error.message : String(error);
|
|
44
|
+
}
|
|
45
|
+
function firstLine(text) {
|
|
46
|
+
return text.split("\n", 1)[0] ?? "";
|
|
47
|
+
}
|
|
48
|
+
function isEnabled(server) {
|
|
49
|
+
return server.entry.config.enabled !== false;
|
|
50
|
+
}
|
|
51
|
+
function exposureOf(entry) {
|
|
52
|
+
return entry.config.exposure ?? "codemode";
|
|
53
|
+
}
|
|
54
|
+
/** Short state for lists and the startup report. `withError` appends the first line of a failure. */
|
|
55
|
+
function describeState(server, withError = true) {
|
|
56
|
+
if (!isEnabled(server))
|
|
57
|
+
return "disabled";
|
|
58
|
+
const connection = server.connection;
|
|
59
|
+
if (!connection)
|
|
60
|
+
return "starting";
|
|
61
|
+
switch (connection.state) {
|
|
62
|
+
case "needs-auth":
|
|
63
|
+
return "needs sign-in";
|
|
64
|
+
case "failed":
|
|
65
|
+
return withError ? `failed: ${firstLine(connection.error ?? "unknown error")}` : "failed";
|
|
66
|
+
case "connected": {
|
|
67
|
+
const { tools, resources } = connection;
|
|
68
|
+
const count = resources.length;
|
|
69
|
+
const resourceCount = count > 0 ? ` · ${count} resource${count === 1 ? "" : "s"}` : "";
|
|
70
|
+
return `connected · ${tools.length} tool${tools.length === 1 ? "" : "s"}${resourceCount}`;
|
|
71
|
+
}
|
|
72
|
+
case "connecting":
|
|
73
|
+
return "connecting…";
|
|
74
|
+
default:
|
|
75
|
+
return connection.state;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/** Servers that need the user first. */
|
|
79
|
+
function attentionRank(server) {
|
|
80
|
+
if (!isEnabled(server))
|
|
81
|
+
return 5;
|
|
82
|
+
switch (server.connection?.state) {
|
|
83
|
+
case "needs-auth":
|
|
84
|
+
return 0;
|
|
85
|
+
case "failed":
|
|
86
|
+
return 1;
|
|
87
|
+
case "disconnected":
|
|
88
|
+
return 2;
|
|
89
|
+
case "connected":
|
|
90
|
+
return 4;
|
|
91
|
+
default:
|
|
92
|
+
return 3;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
function describeTransport(entry) {
|
|
96
|
+
const { config } = entry;
|
|
97
|
+
if ("url" in config)
|
|
98
|
+
return config.url;
|
|
99
|
+
return [config.command, ...(config.args ?? [])].join(" ");
|
|
100
|
+
}
|
|
101
|
+
const MCP_USAGE = "Usage: /mcp, /mcp login [server], /mcp logout [server], /mcp reconnect [server]";
|
|
102
|
+
export function createMcpExtension(options = {}) {
|
|
103
|
+
return (pi) => {
|
|
104
|
+
let servers = [];
|
|
105
|
+
/** Servers from `mcp.json`, which take precedence over registered servers of the same name. */
|
|
106
|
+
let configuredEntries = [];
|
|
107
|
+
let configErrors = [];
|
|
108
|
+
/** Registered servers that `mcp.json` overrides, shown in `/mcp`. */
|
|
109
|
+
let overridden = [];
|
|
110
|
+
/** Between session_start and session_shutdown. Registrations before that are read on session_start. */
|
|
111
|
+
let sessionActive = false;
|
|
112
|
+
let autoEnableCodemode = true;
|
|
113
|
+
/** Whether the "codemode tools unreachable" warning was shown since the session started. */
|
|
114
|
+
let warnedUnreachable = false;
|
|
115
|
+
let pending;
|
|
116
|
+
/** Whether a prompt already waited for the startup connections since the session started. */
|
|
117
|
+
let waitedForStartup = false;
|
|
118
|
+
const startupWaitMs = options.startupWaitMs ?? DEFAULT_STARTUP_WAIT_MS;
|
|
119
|
+
/** Bumped on every session start and shutdown so a runtime load that resolves late is dropped. */
|
|
120
|
+
let generation = 0;
|
|
121
|
+
/** Working directory of the session, for stdio servers. */
|
|
122
|
+
let sessionCwd = process.cwd();
|
|
123
|
+
let credentials = options.credentials;
|
|
124
|
+
let serverLog;
|
|
125
|
+
const openUrl = options.openUrl ?? openBrowser;
|
|
126
|
+
const updateConfig = options.updateConfig ?? ((entry, patch) => updateMcpServerConfig(entry.source, entry.name, patch));
|
|
127
|
+
const listeners = new Set();
|
|
128
|
+
const emitChange = () => {
|
|
129
|
+
for (const listener of listeners)
|
|
130
|
+
listener();
|
|
131
|
+
};
|
|
132
|
+
const subscribe = (listener) => {
|
|
133
|
+
listeners.add(listener);
|
|
134
|
+
return () => {
|
|
135
|
+
listeners.delete(listener);
|
|
136
|
+
};
|
|
137
|
+
};
|
|
138
|
+
const connections = () => servers.flatMap((server) => (server.connection ? [server.connection] : []));
|
|
139
|
+
const findServer = (name) => servers.find((server) => server.entry.name === name);
|
|
140
|
+
/** Servers extensions registered, except names `mcp.json` defines, which take precedence. */
|
|
141
|
+
const registeredServers = () => {
|
|
142
|
+
const registered = [];
|
|
143
|
+
const overriddenNames = [];
|
|
144
|
+
for (const { name, config, extensionPath } of pi.getMcpServers()) {
|
|
145
|
+
const configured = configuredEntries.find((entry) => entry.name === name);
|
|
146
|
+
if (configured) {
|
|
147
|
+
overriddenNames.push(`"${name}" registered by ${extensionPath} is overridden by ${configured.source}`);
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
150
|
+
registered.push({
|
|
151
|
+
entry: { name, config, source: extensionPath, scope: "extension" },
|
|
152
|
+
registeredConfig: JSON.stringify(config),
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
return { servers: registered, overridden: overriddenNames };
|
|
156
|
+
};
|
|
157
|
+
const getCredentials = (runtime) => {
|
|
158
|
+
credentials ??= new runtime.McpOAuthCredentialStore();
|
|
159
|
+
return credentials;
|
|
160
|
+
};
|
|
161
|
+
const getServerLog = (runtime) => {
|
|
162
|
+
serverLog ??= new runtime.McpServerLog(options.logPath ?? join(getAgentDir(), "mcp.log"));
|
|
163
|
+
return serverLog;
|
|
164
|
+
};
|
|
165
|
+
/** pi tool name to the `<server>\0<tool>` it was assigned to, so names stay unique and stable. */
|
|
166
|
+
const toolOwners = new Map();
|
|
167
|
+
/** Tool names currently offered by each server. */
|
|
168
|
+
const serverTools = new Map();
|
|
169
|
+
/** Last definition registered under each tool name, to re-register withdrawn tools as hidden. */
|
|
170
|
+
const definitions = new Map();
|
|
171
|
+
const registerTools = (connection) => {
|
|
172
|
+
const server = connection.entry.name;
|
|
173
|
+
const entry = findServer(server)?.entry ?? connection.entry;
|
|
174
|
+
const namespaceName = `mcp__${server}`;
|
|
175
|
+
const namespace = {
|
|
176
|
+
name: namespaceName,
|
|
177
|
+
description: connection.instructions ?? `Tools in the ${namespaceName} namespace.`,
|
|
178
|
+
};
|
|
179
|
+
const previous = serverTools.get(server) ?? new Set();
|
|
180
|
+
const current = new Set();
|
|
181
|
+
const assignName = (tool, owner) => {
|
|
182
|
+
const name = createMcpToolName(server, tool, (candidate) => {
|
|
183
|
+
const existing = toolOwners.get(candidate);
|
|
184
|
+
return (existing !== undefined && existing !== owner) || current.has(candidate);
|
|
185
|
+
});
|
|
186
|
+
toolOwners.set(name, owner);
|
|
187
|
+
current.add(name);
|
|
188
|
+
return name;
|
|
189
|
+
};
|
|
190
|
+
for (const tool of connection.tools) {
|
|
191
|
+
const definition = createMcpToolDefinition({
|
|
192
|
+
server,
|
|
193
|
+
tool,
|
|
194
|
+
name: assignName(tool.name, `${server}\0${tool.name}`),
|
|
195
|
+
exposure: getMcpToolExposure(entry.config, tool.name),
|
|
196
|
+
namespace,
|
|
197
|
+
timeoutMs: connection.timeoutMs,
|
|
198
|
+
getClient: async () => connection,
|
|
199
|
+
readableResources: () => resourceServers().includes(connection),
|
|
200
|
+
});
|
|
201
|
+
definitions.set(definition.name, definition);
|
|
202
|
+
pi.registerTool(definition);
|
|
203
|
+
}
|
|
204
|
+
serverTools.set(server, current);
|
|
205
|
+
// Tools cannot be unregistered, so tools the server dropped are re-registered as hidden. When
|
|
206
|
+
// the server offers them again they are registered with their configured exposure above.
|
|
207
|
+
for (const name of previous) {
|
|
208
|
+
const definition = definitions.get(name);
|
|
209
|
+
if (!current.has(name) && definition)
|
|
210
|
+
pi.registerTool({ ...definition, exposure: "hidden" });
|
|
211
|
+
}
|
|
212
|
+
syncResourceTools();
|
|
213
|
+
};
|
|
214
|
+
/** Make a disabled server's tools unreachable. */
|
|
215
|
+
const hideTools = (server) => {
|
|
216
|
+
for (const name of serverTools.get(server) ?? []) {
|
|
217
|
+
const definition = definitions.get(name);
|
|
218
|
+
if (definition)
|
|
219
|
+
pi.registerTool({ ...definition, exposure: "hidden" });
|
|
220
|
+
}
|
|
221
|
+
serverTools.set(server, new Set());
|
|
222
|
+
syncResourceTools();
|
|
223
|
+
};
|
|
224
|
+
/** Enabled servers with resources whose exposure is not `hidden`, which the resource tools reach. */
|
|
225
|
+
const serversWithResources = () => servers.filter((server) => server.connection?.hasResources && isEnabled(server) && exposureOf(server.entry) !== "hidden");
|
|
226
|
+
const resourceServers = () => serversWithResources().flatMap((server) => (server.connection ? [server.connection] : []));
|
|
227
|
+
/** Exposure the resource tools were last registered with; undefined until a server has resources. */
|
|
228
|
+
let resourceToolsExposure;
|
|
229
|
+
/**
|
|
230
|
+
* Register the resource tools with the widest exposure of the servers they reach: `direct` when
|
|
231
|
+
* one of them is direct, and so on. They are hidden when no server has resources.
|
|
232
|
+
*/
|
|
233
|
+
const syncResourceTools = () => {
|
|
234
|
+
const exposures = new Set(serversWithResources().map((server) => exposureOf(server.entry)));
|
|
235
|
+
const exposure = ["direct", "codemode", "codemode-deferred", "deferred"].find((candidate) => exposures.has(candidate));
|
|
236
|
+
const next = exposure ?? "hidden";
|
|
237
|
+
if (next === resourceToolsExposure || (resourceToolsExposure === undefined && next === "hidden"))
|
|
238
|
+
return;
|
|
239
|
+
const wasDirect = resourceToolsExposure === "direct";
|
|
240
|
+
resourceToolsExposure = next;
|
|
241
|
+
const resourceDefinitions = createMcpResourceToolDefinitions({ exposure: next, servers: resourceServers });
|
|
242
|
+
for (const definition of resourceDefinitions)
|
|
243
|
+
pi.registerTool(definition);
|
|
244
|
+
if (wasDirect) {
|
|
245
|
+
const names = new Set(resourceDefinitions.map((definition) => definition.name));
|
|
246
|
+
pi.setActiveTools(pi.getActiveTools().filter((name) => !names.has(name)));
|
|
247
|
+
}
|
|
248
|
+
};
|
|
249
|
+
/**
|
|
250
|
+
* Tools that are not declared to the model are reached through the codemode tool (scripts call
|
|
251
|
+
* them) or the tool_search tool (it declares them). Either reaches every such tool. Activate the
|
|
252
|
+
* one the tools' exposure asks for: codemode for `codemode` and `codemode-deferred` unless
|
|
253
|
+
* `autoEnableCodemode` is false, tool_search for `deferred`.
|
|
254
|
+
*/
|
|
255
|
+
const ensureDiscoveryActive = (ctx) => {
|
|
256
|
+
const exposures = new Set();
|
|
257
|
+
for (const { connection, entry } of servers) {
|
|
258
|
+
if (connection?.state !== "connected")
|
|
259
|
+
continue;
|
|
260
|
+
// Resource tools share the server's exposure.
|
|
261
|
+
if (connection.hasResources)
|
|
262
|
+
exposures.add(exposureOf(entry));
|
|
263
|
+
for (const tool of connection.tools)
|
|
264
|
+
exposures.add(getMcpToolExposure(entry.config, tool.name));
|
|
265
|
+
}
|
|
266
|
+
const needsCodemode = exposures.has("codemode") || exposures.has("codemode-deferred");
|
|
267
|
+
const needsToolSearch = exposures.has("deferred");
|
|
268
|
+
if (!needsCodemode && !needsToolSearch)
|
|
269
|
+
return;
|
|
270
|
+
// Other extensions' tools of the same names cannot reach MCP tools, so never activate them.
|
|
271
|
+
const tools = pi.getAllTools();
|
|
272
|
+
const hasCodemode = tools.some(isCodemodeTool);
|
|
273
|
+
const hasToolSearch = tools.some(isToolSearchTool);
|
|
274
|
+
const active = pi.getActiveTools();
|
|
275
|
+
const activate = [];
|
|
276
|
+
if (needsCodemode && hasCodemode && autoEnableCodemode && !active.includes(CODEMODE_TOOL_NAME)) {
|
|
277
|
+
activate.push(CODEMODE_TOOL_NAME);
|
|
278
|
+
}
|
|
279
|
+
if (needsToolSearch && hasToolSearch && !active.includes(TOOL_SEARCH_TOOL_NAME)) {
|
|
280
|
+
activate.push(TOOL_SEARCH_TOOL_NAME);
|
|
281
|
+
}
|
|
282
|
+
if (activate.length > 0)
|
|
283
|
+
pi.setActiveTools([...active, ...activate]);
|
|
284
|
+
const reachable = [...active, ...activate];
|
|
285
|
+
if (hasCodemode && reachable.includes(CODEMODE_TOOL_NAME))
|
|
286
|
+
return;
|
|
287
|
+
if (hasToolSearch && reachable.includes(TOOL_SEARCH_TOOL_NAME))
|
|
288
|
+
return;
|
|
289
|
+
if (warnedUnreachable)
|
|
290
|
+
return;
|
|
291
|
+
warnedUnreachable = true;
|
|
292
|
+
const reason = needsCodemode && hasCodemode && !autoEnableCodemode ? " (autoEnableCodemode is false)" : "";
|
|
293
|
+
ctx.ui.notify(`MCP tools are only reachable from the codemode or tool_search tool, but neither is active${reason}; they cannot be called.`, "warning");
|
|
294
|
+
};
|
|
295
|
+
/**
|
|
296
|
+
* Stored tokens of servers waiting for a sign-in, as they were when the sign-in was needed.
|
|
297
|
+
* `pi mcp login` in another process (for example run by the agent) changes them.
|
|
298
|
+
*/
|
|
299
|
+
const tokensAtSignIn = new Map();
|
|
300
|
+
const storedTokens = (connection) => {
|
|
301
|
+
const url = connection.oauthUrl;
|
|
302
|
+
return url && credentials ? JSON.stringify(credentials.tokens(url) ?? null) : "null";
|
|
303
|
+
};
|
|
304
|
+
const onConnectionChange = (connection) => {
|
|
305
|
+
if (connection.state !== "needs-auth")
|
|
306
|
+
tokensAtSignIn.delete(connection);
|
|
307
|
+
else if (!tokensAtSignIn.has(connection))
|
|
308
|
+
tokensAtSignIn.set(connection, storedTokens(connection));
|
|
309
|
+
emitChange();
|
|
310
|
+
};
|
|
311
|
+
/** Reconnect servers that need a sign-in when their credentials were stored since. */
|
|
312
|
+
const reconnectSignedIn = async (ctx) => {
|
|
313
|
+
const signedIn = [...tokensAtSignIn].filter(([connection, tokens]) => storedTokens(connection) !== tokens);
|
|
314
|
+
if (signedIn.length === 0)
|
|
315
|
+
return;
|
|
316
|
+
for (const [connection] of signedIn)
|
|
317
|
+
tokensAtSignIn.delete(connection);
|
|
318
|
+
await Promise.allSettled(signedIn.map(([connection]) => connection.reconnect()));
|
|
319
|
+
ensureDiscoveryActive(ctx);
|
|
320
|
+
};
|
|
321
|
+
/** Create the server's connection, loading the MCP runtime on first use. */
|
|
322
|
+
const createConnection = async (server) => {
|
|
323
|
+
const runtime = await loadMcpRuntime();
|
|
324
|
+
const connection = new runtime.McpServerConnection({
|
|
325
|
+
entry: server.entry,
|
|
326
|
+
cwd: sessionCwd,
|
|
327
|
+
createTransport: options.createTransport ?? runtime.createDefaultTransport,
|
|
328
|
+
credentials: getCredentials(runtime),
|
|
329
|
+
log: getServerLog(runtime),
|
|
330
|
+
onTools: registerTools,
|
|
331
|
+
onChange: onConnectionChange,
|
|
332
|
+
});
|
|
333
|
+
server.connection = connection;
|
|
334
|
+
emitChange();
|
|
335
|
+
return connection;
|
|
336
|
+
};
|
|
337
|
+
/**
|
|
338
|
+
* One message for everything that needs the user after startup, or only for `only`, servers
|
|
339
|
+
* that connected later.
|
|
340
|
+
*/
|
|
341
|
+
const reportProblems = (ctx, only) => {
|
|
342
|
+
const lines = only ? [] : configErrors.map((error) => `config: ${error}`);
|
|
343
|
+
for (const server of only ?? servers) {
|
|
344
|
+
const state = server.connection?.state;
|
|
345
|
+
if (state === "needs-auth" || state === "failed")
|
|
346
|
+
lines.push(`${server.entry.name}: ${describeState(server)}`);
|
|
347
|
+
}
|
|
348
|
+
if (lines.length === 0)
|
|
349
|
+
return;
|
|
350
|
+
ctx.ui.notify(`MCP servers need attention:\n${lines.map((line) => ` ${line}`).join("\n")}\nRun /mcp to fix.`, "warning");
|
|
351
|
+
};
|
|
352
|
+
/**
|
|
353
|
+
* Save a config change; returns an error message when the file could not be updated. Changes to
|
|
354
|
+
* registered servers only apply to the current session.
|
|
355
|
+
*/
|
|
356
|
+
const saveConfig = (server, patch) => {
|
|
357
|
+
if (server.entry.scope !== "extension") {
|
|
358
|
+
try {
|
|
359
|
+
updateConfig(server.entry, patch);
|
|
360
|
+
}
|
|
361
|
+
catch (error) {
|
|
362
|
+
return `Could not update ${server.entry.source}: ${errorMessage(error)}`;
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
server.entry = { ...server.entry, config: { ...server.entry.config, ...patch } };
|
|
366
|
+
return undefined;
|
|
367
|
+
};
|
|
368
|
+
const signIn = async (server, prompt) => {
|
|
369
|
+
const connection = server.connection;
|
|
370
|
+
const url = connection?.oauthUrl;
|
|
371
|
+
if (!connection || !url)
|
|
372
|
+
return `MCP server "${server.entry.name}" does not use OAuth.`;
|
|
373
|
+
const runtime = await loadMcpRuntime();
|
|
374
|
+
try {
|
|
375
|
+
await runtime.signInMcpServer({
|
|
376
|
+
serverUrl: url,
|
|
377
|
+
store: getCredentials(runtime).forServer(url),
|
|
378
|
+
settings: connection.oauthSettings(),
|
|
379
|
+
challenge: connection.challenge,
|
|
380
|
+
prompt,
|
|
381
|
+
});
|
|
382
|
+
}
|
|
383
|
+
catch (error) {
|
|
384
|
+
if (error instanceof runtime.McpSignInCancelledError)
|
|
385
|
+
return "Sign-in cancelled.";
|
|
386
|
+
return `Sign-in failed: ${errorMessage(error)}`;
|
|
387
|
+
}
|
|
388
|
+
// The challenge that asked for this sign-in (for example for more scope) is answered.
|
|
389
|
+
connection.challenge = undefined;
|
|
390
|
+
try {
|
|
391
|
+
await connection.reconnect();
|
|
392
|
+
}
|
|
393
|
+
catch (error) {
|
|
394
|
+
return `Signed in, but ${errorMessage(error)}`;
|
|
395
|
+
}
|
|
396
|
+
return undefined;
|
|
397
|
+
};
|
|
398
|
+
const signOut = async (server) => {
|
|
399
|
+
const connection = server.connection;
|
|
400
|
+
const url = connection?.oauthUrl;
|
|
401
|
+
if (!connection || !url)
|
|
402
|
+
return false;
|
|
403
|
+
const removed = getCredentials(await loadMcpRuntime()).remove(url);
|
|
404
|
+
await connection.signOut();
|
|
405
|
+
return removed;
|
|
406
|
+
};
|
|
407
|
+
const reconnect = async (server) => {
|
|
408
|
+
const connection = server.connection;
|
|
409
|
+
if (!connection)
|
|
410
|
+
return `MCP server "${server.entry.name}" is disabled.`;
|
|
411
|
+
try {
|
|
412
|
+
await connection.reconnect();
|
|
413
|
+
return undefined;
|
|
414
|
+
}
|
|
415
|
+
catch (error) {
|
|
416
|
+
return errorMessage(error);
|
|
417
|
+
}
|
|
418
|
+
};
|
|
419
|
+
/** Returns an error message when the config could not be saved; connection errors show in the state. */
|
|
420
|
+
const setEnabled = async (server, enabled) => {
|
|
421
|
+
const failed = saveConfig(server, { enabled });
|
|
422
|
+
if (failed)
|
|
423
|
+
return failed;
|
|
424
|
+
if (!enabled) {
|
|
425
|
+
const connection = server.connection;
|
|
426
|
+
server.connection = undefined;
|
|
427
|
+
hideTools(server.entry.name);
|
|
428
|
+
emitChange();
|
|
429
|
+
await connection?.close();
|
|
430
|
+
return undefined;
|
|
431
|
+
}
|
|
432
|
+
const connection = await createConnection(server);
|
|
433
|
+
await connection.getClient().catch(() => undefined);
|
|
434
|
+
return undefined;
|
|
435
|
+
};
|
|
436
|
+
const setExposure = (server, exposure) => {
|
|
437
|
+
const failed = saveConfig(server, { exposure });
|
|
438
|
+
if (failed)
|
|
439
|
+
return failed;
|
|
440
|
+
if (server.connection?.state === "connected")
|
|
441
|
+
registerTools(server.connection);
|
|
442
|
+
syncResourceTools();
|
|
443
|
+
// Tools no longer exposed directly leave the declared set; direct tools are activated on registration.
|
|
444
|
+
const indirect = new Set(pi
|
|
445
|
+
.getAllTools()
|
|
446
|
+
.filter((tool) => tool.exposure !== "direct")
|
|
447
|
+
.map((tool) => tool.name));
|
|
448
|
+
const tools = serverTools.get(server.entry.name) ?? new Set();
|
|
449
|
+
pi.setActiveTools(pi.getActiveTools().filter((name) => !tools.has(name) || !indirect.has(name)));
|
|
450
|
+
emitChange();
|
|
451
|
+
return undefined;
|
|
452
|
+
};
|
|
453
|
+
// ---------------------------------------------------------------------------------------
|
|
454
|
+
// Manager (`/mcp` in the TUI)
|
|
455
|
+
// ---------------------------------------------------------------------------------------
|
|
456
|
+
const notices = () => [
|
|
457
|
+
...configErrors.map((error) => `config: ${error}`),
|
|
458
|
+
...overridden.map((line) => `overridden: ${line}`),
|
|
459
|
+
];
|
|
460
|
+
const serversMenu = () => ({
|
|
461
|
+
title: "MCP servers",
|
|
462
|
+
error: notices().join("\n") || undefined,
|
|
463
|
+
items: [...servers]
|
|
464
|
+
.sort((a, b) => attentionRank(a) - attentionRank(b) || a.entry.name.localeCompare(b.entry.name))
|
|
465
|
+
.map((server) => ({
|
|
466
|
+
value: server.entry.name,
|
|
467
|
+
label: server.entry.name,
|
|
468
|
+
description: `${describeState(server)} · ${exposureOf(server.entry)} · ${server.entry.scope ?? server.entry.source}`,
|
|
469
|
+
})),
|
|
470
|
+
empty: `No MCP servers configured. Add them to ${resolve(getAgentDir(), "mcp.json")} or .pi/mcp.json.`,
|
|
471
|
+
confirmLabel: "manage",
|
|
472
|
+
cancelLabel: "close",
|
|
473
|
+
});
|
|
474
|
+
const serverMenu = (name) => {
|
|
475
|
+
const server = findServer(name);
|
|
476
|
+
if (!server) {
|
|
477
|
+
return {
|
|
478
|
+
title: name,
|
|
479
|
+
items: [],
|
|
480
|
+
empty: "This server is no longer configured.",
|
|
481
|
+
confirmLabel: "",
|
|
482
|
+
cancelLabel: "back",
|
|
483
|
+
};
|
|
484
|
+
}
|
|
485
|
+
const { entry, connection } = server;
|
|
486
|
+
const saved = entry.scope === "extension"
|
|
487
|
+
? "for this session"
|
|
488
|
+
: entry.scope
|
|
489
|
+
? `saved to the ${entry.scope} mcp.json`
|
|
490
|
+
: "saved to mcp.json";
|
|
491
|
+
const items = [];
|
|
492
|
+
if (!isEnabled(server)) {
|
|
493
|
+
items.push({ value: "enable", label: "Enable", description: saved });
|
|
494
|
+
}
|
|
495
|
+
else {
|
|
496
|
+
const state = connection?.state;
|
|
497
|
+
if (state === "needs-auth")
|
|
498
|
+
items.push({ value: "signin", label: "Sign in", description: "opens the browser" });
|
|
499
|
+
if (state === "connected" && connection) {
|
|
500
|
+
items.push({ value: "tools", label: "Tools", description: `${connection.tools.length} offered` });
|
|
501
|
+
}
|
|
502
|
+
if (state === "failed" || state === "disconnected" || state === "connected" || state === "needs-auth") {
|
|
503
|
+
items.push({ value: "reconnect", label: "Reconnect" });
|
|
504
|
+
}
|
|
505
|
+
if (state === "connected" && connection?.oauthUrl) {
|
|
506
|
+
items.push({ value: "signout", label: "Sign out", description: "deletes the stored credentials" });
|
|
507
|
+
}
|
|
508
|
+
items.push({ value: "exposure", label: "Exposure", description: exposureOf(entry) });
|
|
509
|
+
items.push({ value: "disable", label: "Disable", description: saved });
|
|
510
|
+
}
|
|
511
|
+
const details = [
|
|
512
|
+
describeTransport(entry),
|
|
513
|
+
`${entry.scope ?? "config"}: ${entry.source}`,
|
|
514
|
+
`State: ${describeState(server, false)}`,
|
|
515
|
+
];
|
|
516
|
+
const error = [server.message, connection?.state === "connected" ? undefined : connection?.error]
|
|
517
|
+
.filter((line) => line !== undefined)
|
|
518
|
+
.join("\n");
|
|
519
|
+
return {
|
|
520
|
+
title: `MCP server ${name}`,
|
|
521
|
+
details: details.join("\n"),
|
|
522
|
+
error: error || undefined,
|
|
523
|
+
items,
|
|
524
|
+
selected: items[0]?.value,
|
|
525
|
+
confirmLabel: "select",
|
|
526
|
+
cancelLabel: "back",
|
|
527
|
+
};
|
|
528
|
+
};
|
|
529
|
+
const showTools = async (ui, server) => {
|
|
530
|
+
const exposure = exposureOf(server.entry);
|
|
531
|
+
const overridden = Object.keys(server.entry.config.toolExposure ?? {}).length > 0;
|
|
532
|
+
await ui.menu(() => ({
|
|
533
|
+
title: `Tools of ${server.entry.name}`,
|
|
534
|
+
details: `Exposure ${exposure}: ${exposure === "hidden" ? "unreachable" : EXPOSURE_DESCRIPTIONS[exposure]}${overridden ? "\nSome tools override it with toolExposure." : ""}`,
|
|
535
|
+
items: (server.connection?.tools ?? []).map((tool) => {
|
|
536
|
+
const toolExposure = getMcpToolExposure(server.entry.config, tool.name);
|
|
537
|
+
const description = firstLine(tool.description ?? "");
|
|
538
|
+
return {
|
|
539
|
+
value: tool.name,
|
|
540
|
+
label: tool.name,
|
|
541
|
+
description: toolExposure === exposure ? description : `[${toolExposure}] ${description}`,
|
|
542
|
+
};
|
|
543
|
+
}),
|
|
544
|
+
empty: "The server offers no tools.",
|
|
545
|
+
confirmLabel: "back",
|
|
546
|
+
cancelLabel: "back",
|
|
547
|
+
}));
|
|
548
|
+
};
|
|
549
|
+
const chooseExposure = async (ui, server) => {
|
|
550
|
+
const current = exposureOf(server.entry);
|
|
551
|
+
const choice = await ui.menu(() => ({
|
|
552
|
+
title: `Exposure of ${server.entry.name}`,
|
|
553
|
+
details: server.entry.scope === "extension"
|
|
554
|
+
? `Applies to this session; the server is registered by ${server.entry.source}.`
|
|
555
|
+
: `Saved to ${server.entry.source}.`,
|
|
556
|
+
items: Object.keys(EXPOSURE_DESCRIPTIONS).map((exposure) => ({
|
|
557
|
+
value: exposure,
|
|
558
|
+
label: `${exposure === current ? "✓ " : " "}${exposure}`,
|
|
559
|
+
description: EXPOSURE_DESCRIPTIONS[exposure],
|
|
560
|
+
})),
|
|
561
|
+
selected: current,
|
|
562
|
+
confirmLabel: "save",
|
|
563
|
+
cancelLabel: "back",
|
|
564
|
+
}));
|
|
565
|
+
if (!choice || choice === current)
|
|
566
|
+
return undefined;
|
|
567
|
+
return setExposure(server, choice);
|
|
568
|
+
};
|
|
569
|
+
const runAction = async (ui, ctx, server, action) => {
|
|
570
|
+
const { name } = server.entry;
|
|
571
|
+
let message;
|
|
572
|
+
switch (action) {
|
|
573
|
+
case "signin": {
|
|
574
|
+
const title = `Sign in to ${name}`;
|
|
575
|
+
let authorizationUrl = "";
|
|
576
|
+
ui.status(title, "Contacting the authorization server…");
|
|
577
|
+
message = await signIn(server, {
|
|
578
|
+
showAuthorizationUrl: (url) => {
|
|
579
|
+
authorizationUrl = url.href;
|
|
580
|
+
openUrl(url.href);
|
|
581
|
+
},
|
|
582
|
+
promptForRedirectUrl: async (signal) => {
|
|
583
|
+
const value = await ui.redirectUrl(title, authorizationUrl, signal);
|
|
584
|
+
ui.status(title, "Connecting…");
|
|
585
|
+
return value;
|
|
586
|
+
},
|
|
587
|
+
});
|
|
588
|
+
break;
|
|
589
|
+
}
|
|
590
|
+
case "reconnect":
|
|
591
|
+
// A failure shows as the connection's state and error.
|
|
592
|
+
ui.status(`MCP server ${name}`, "Reconnecting…");
|
|
593
|
+
await reconnect(server);
|
|
594
|
+
break;
|
|
595
|
+
case "signout":
|
|
596
|
+
await signOut(server);
|
|
597
|
+
break;
|
|
598
|
+
case "tools":
|
|
599
|
+
await showTools(ui, server);
|
|
600
|
+
break;
|
|
601
|
+
case "exposure":
|
|
602
|
+
message = await chooseExposure(ui, server);
|
|
603
|
+
break;
|
|
604
|
+
case "enable":
|
|
605
|
+
case "disable":
|
|
606
|
+
ui.status(`MCP server ${name}`, action === "enable" ? "Connecting…" : "Disconnecting…");
|
|
607
|
+
message = await setEnabled(server, action === "enable");
|
|
608
|
+
break;
|
|
609
|
+
}
|
|
610
|
+
server.message = message;
|
|
611
|
+
ensureDiscoveryActive(ctx);
|
|
612
|
+
emitChange();
|
|
613
|
+
};
|
|
614
|
+
const manage = async (ui, ctx) => {
|
|
615
|
+
for (;;) {
|
|
616
|
+
const name = await ui.menu(serversMenu, subscribe);
|
|
617
|
+
if (!name)
|
|
618
|
+
return;
|
|
619
|
+
for (;;) {
|
|
620
|
+
const action = await ui.menu(() => serverMenu(name), subscribe);
|
|
621
|
+
const server = findServer(name);
|
|
622
|
+
if (!action || !server)
|
|
623
|
+
break;
|
|
624
|
+
await runAction(ui, ctx, server, action);
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
};
|
|
628
|
+
// ---------------------------------------------------------------------------------------
|
|
629
|
+
// Subcommands and plain status (no TUI)
|
|
630
|
+
// ---------------------------------------------------------------------------------------
|
|
631
|
+
const formatStatus = () => {
|
|
632
|
+
if (servers.length === 0 && configErrors.length === 0 && overridden.length === 0) {
|
|
633
|
+
return `No MCP servers configured. Add them to ${resolve(getAgentDir(), "mcp.json")} or .pi/mcp.json.`;
|
|
634
|
+
}
|
|
635
|
+
const lines = servers.map((server) => {
|
|
636
|
+
const { name } = server.entry;
|
|
637
|
+
const exposure = exposureOf(server.entry);
|
|
638
|
+
const connection = server.connection;
|
|
639
|
+
if (connection?.state === "needs-auth")
|
|
640
|
+
return `${name}: needs sign-in, run /mcp login ${name} (${exposure})`;
|
|
641
|
+
const tools = connection?.state === "connected" ? `, ${connection.tools.length} tools` : "";
|
|
642
|
+
const state = !isEnabled(server)
|
|
643
|
+
? "disabled"
|
|
644
|
+
: connection?.state === "disconnected"
|
|
645
|
+
? "disconnected, reconnects on next call"
|
|
646
|
+
: (connection?.state ?? "starting");
|
|
647
|
+
const error = connection?.error && connection.state !== "connected"
|
|
648
|
+
? `\n ${connection.error.split("\n").join("\n ")}`
|
|
649
|
+
: "";
|
|
650
|
+
return `${name}: ${state}${tools} (${exposure})${error}`;
|
|
651
|
+
});
|
|
652
|
+
for (const error of configErrors)
|
|
653
|
+
lines.push(`config error: ${error}`);
|
|
654
|
+
for (const line of overridden)
|
|
655
|
+
lines.push(`overridden: ${line}`);
|
|
656
|
+
return lines.join("\n");
|
|
657
|
+
};
|
|
658
|
+
/** Resolve the server for a subcommand, asking when the name is omitted and ambiguous. */
|
|
659
|
+
const pickServer = async (name, ctx, options) => {
|
|
660
|
+
if (name) {
|
|
661
|
+
const server = findServer(name);
|
|
662
|
+
if (!server)
|
|
663
|
+
ctx.ui.notify(`No MCP server named "${name}".`, "error");
|
|
664
|
+
else if (!options.eligible(server))
|
|
665
|
+
ctx.ui.notify(options.none, "error");
|
|
666
|
+
return server && options.eligible(server) ? server : undefined;
|
|
667
|
+
}
|
|
668
|
+
const candidates = servers.filter(options.eligible);
|
|
669
|
+
if (candidates.length === 0) {
|
|
670
|
+
ctx.ui.notify(options.none, "info");
|
|
671
|
+
return undefined;
|
|
672
|
+
}
|
|
673
|
+
const preferred = candidates.filter(options.preferred);
|
|
674
|
+
if (candidates.length === 1)
|
|
675
|
+
return candidates[0];
|
|
676
|
+
if (preferred.length === 1)
|
|
677
|
+
return preferred[0];
|
|
678
|
+
const choice = await ctx.ui.select("MCP server", candidates.map((server) => server.entry.name));
|
|
679
|
+
return candidates.find((server) => server.entry.name === choice);
|
|
680
|
+
};
|
|
681
|
+
const usesOAuth = (server) => server.connection?.oauthUrl !== undefined;
|
|
682
|
+
const oauthPick = {
|
|
683
|
+
eligible: usesOAuth,
|
|
684
|
+
preferred: (server) => server.connection?.state === "needs-auth",
|
|
685
|
+
none: "No enabled MCP server uses OAuth. Only HTTP servers without an Authorization header do.",
|
|
686
|
+
};
|
|
687
|
+
const loginCommand = async (server, ctx) => {
|
|
688
|
+
const { name } = server.entry;
|
|
689
|
+
if (!ctx.hasUI) {
|
|
690
|
+
ctx.ui.notify(`Signing in to MCP server "${name}" requires interactive mode.`, "error");
|
|
691
|
+
return;
|
|
692
|
+
}
|
|
693
|
+
const failure = await signIn(server, {
|
|
694
|
+
showAuthorizationUrl: (url) => {
|
|
695
|
+
ctx.ui.notify(`Sign in to MCP server "${name}" in your browser:\n${url.href}`, "info");
|
|
696
|
+
openUrl(url.href);
|
|
697
|
+
},
|
|
698
|
+
promptForRedirectUrl: (signal) => ctx.ui.input(`Waiting for sign-in to "${name}". If the browser cannot reach this machine, paste the URL it was redirected to.`, "http://127.0.0.1:.../callback?code=...", { signal }),
|
|
699
|
+
});
|
|
700
|
+
if (failure) {
|
|
701
|
+
ctx.ui.notify(failure, failure === "Sign-in cancelled." ? "info" : "error");
|
|
702
|
+
return;
|
|
703
|
+
}
|
|
704
|
+
ensureDiscoveryActive(ctx);
|
|
705
|
+
ctx.ui.notify(`Signed in to MCP server "${name}" (${server.connection?.tools.length ?? 0} tools).`, "info");
|
|
706
|
+
};
|
|
707
|
+
pi.on("session_start", (_event, ctx) => {
|
|
708
|
+
const loaded = (options.loadConfig ?? defaultLoadConfig)(ctx);
|
|
709
|
+
configErrors = loaded.errors;
|
|
710
|
+
autoEnableCodemode = loaded.autoEnableCodemode ?? true;
|
|
711
|
+
warnedUnreachable = false;
|
|
712
|
+
waitedForStartup = false;
|
|
713
|
+
sessionCwd = ctx.cwd;
|
|
714
|
+
const current = ++generation;
|
|
715
|
+
sessionActive = true;
|
|
716
|
+
configuredEntries = loaded.servers;
|
|
717
|
+
const registered = registeredServers();
|
|
718
|
+
overridden = registered.overridden;
|
|
719
|
+
servers = [...loaded.servers.map((entry) => ({ entry })), ...registered.servers];
|
|
720
|
+
emitChange();
|
|
721
|
+
const enabled = servers.filter(isEnabled);
|
|
722
|
+
if (enabled.length === 0) {
|
|
723
|
+
reportProblems(ctx);
|
|
724
|
+
return;
|
|
725
|
+
}
|
|
726
|
+
// The MCP client loads only now, so sessions without servers never pay for it. Waiting one
|
|
727
|
+
// event loop turn lets the first render happen before loading and connecting.
|
|
728
|
+
pending = new Promise((resolve) => setImmediate(resolve))
|
|
729
|
+
.then(() => loadMcpRuntime())
|
|
730
|
+
.then(async () => {
|
|
731
|
+
if (current !== generation)
|
|
732
|
+
return;
|
|
733
|
+
const started = await Promise.all(enabled.map((server) => createConnection(server)));
|
|
734
|
+
if (current !== generation)
|
|
735
|
+
return;
|
|
736
|
+
await Promise.allSettled(started.map((connection) => connection.getClient()));
|
|
737
|
+
if (current !== generation)
|
|
738
|
+
return;
|
|
739
|
+
ensureDiscoveryActive(ctx);
|
|
740
|
+
reportProblems(ctx);
|
|
741
|
+
})
|
|
742
|
+
.catch((error) => {
|
|
743
|
+
// The session may have been disposed meanwhile, which makes ctx stale.
|
|
744
|
+
try {
|
|
745
|
+
ctx.ui.notify(`MCP failed to load: ${errorMessage(error)}`, "error");
|
|
746
|
+
}
|
|
747
|
+
catch { }
|
|
748
|
+
});
|
|
749
|
+
});
|
|
750
|
+
// The first prompt waits for startup connections so their tools are available to it, but not
|
|
751
|
+
// indefinitely: a slow or hanging server must not hold up the prompt.
|
|
752
|
+
pi.on("before_agent_start", async (_event, ctx) => {
|
|
753
|
+
const startup = pending;
|
|
754
|
+
if (!startup || waitedForStartup)
|
|
755
|
+
return;
|
|
756
|
+
waitedForStartup = true;
|
|
757
|
+
let timer;
|
|
758
|
+
const finished = await Promise.race([
|
|
759
|
+
startup.then(() => true),
|
|
760
|
+
new Promise((resolve) => {
|
|
761
|
+
timer = setTimeout(() => resolve(false), startupWaitMs);
|
|
762
|
+
}),
|
|
763
|
+
]);
|
|
764
|
+
clearTimeout(timer);
|
|
765
|
+
if (!finished) {
|
|
766
|
+
ctx.ui.notify("MCP servers are still connecting; their tools become available once connected.", "info");
|
|
767
|
+
}
|
|
768
|
+
});
|
|
769
|
+
// Pick up sign-ins done outside the session, such as `pi mcp login` run by the agent.
|
|
770
|
+
pi.on("turn_start", async (_event, ctx) => {
|
|
771
|
+
if (tokensAtSignIn.size > 0)
|
|
772
|
+
await reconnectSignedIn(ctx);
|
|
773
|
+
});
|
|
774
|
+
// Servers registered or unregistered during the session connect or disconnect right away.
|
|
775
|
+
pi.on("mcp_servers_change", async (_event, ctx) => {
|
|
776
|
+
if (!sessionActive)
|
|
777
|
+
return;
|
|
778
|
+
const current = generation;
|
|
779
|
+
const registered = registeredServers();
|
|
780
|
+
overridden = registered.overridden;
|
|
781
|
+
const next = new Map(registered.servers.map((server) => [server.entry.name, server]));
|
|
782
|
+
// Unregistered servers and re-registered ones with a new config are dropped; the latter come back below.
|
|
783
|
+
const removed = servers.filter((server) => server.entry.scope === "extension" &&
|
|
784
|
+
next.get(server.entry.name)?.registeredConfig !== server.registeredConfig);
|
|
785
|
+
servers = servers.filter((server) => !removed.includes(server));
|
|
786
|
+
for (const server of removed)
|
|
787
|
+
hideTools(server.entry.name);
|
|
788
|
+
const added = registered.servers.filter((server) => !findServer(server.entry.name));
|
|
789
|
+
servers.push(...added);
|
|
790
|
+
emitChange();
|
|
791
|
+
await Promise.all(removed.map((server) => server.connection?.close()));
|
|
792
|
+
const connecting = added.filter(isEnabled);
|
|
793
|
+
if (current !== generation || connecting.length === 0)
|
|
794
|
+
return;
|
|
795
|
+
try {
|
|
796
|
+
const started = await Promise.all(connecting.map((server) => createConnection(server)));
|
|
797
|
+
if (current !== generation) {
|
|
798
|
+
await Promise.all(started.map((connection) => connection.close()));
|
|
799
|
+
return;
|
|
800
|
+
}
|
|
801
|
+
await Promise.allSettled(started.map((connection) => connection.getClient()));
|
|
802
|
+
}
|
|
803
|
+
catch (error) {
|
|
804
|
+
ctx.ui.notify(`MCP failed to load: ${errorMessage(error)}`, "error");
|
|
805
|
+
return;
|
|
806
|
+
}
|
|
807
|
+
if (current !== generation)
|
|
808
|
+
return;
|
|
809
|
+
ensureDiscoveryActive(ctx);
|
|
810
|
+
reportProblems(ctx, connecting);
|
|
811
|
+
});
|
|
812
|
+
pi.on("session_shutdown", async () => {
|
|
813
|
+
sessionActive = false;
|
|
814
|
+
generation++;
|
|
815
|
+
const closing = connections();
|
|
816
|
+
servers = [];
|
|
817
|
+
emitChange();
|
|
818
|
+
await Promise.all(closing.map((connection) => connection.close()));
|
|
819
|
+
});
|
|
820
|
+
pi.registerCommand("mcp", {
|
|
821
|
+
description: "Manage MCP servers: sign in, reconnect, enable or disable, and change exposure",
|
|
822
|
+
getArgumentCompletions: (prefix) => {
|
|
823
|
+
const [action, server, ...rest] = prefix.trimStart().split(/\s+/);
|
|
824
|
+
if (rest.length > 0)
|
|
825
|
+
return null;
|
|
826
|
+
if (server === undefined) {
|
|
827
|
+
return ["login", "logout", "reconnect"]
|
|
828
|
+
.filter((item) => item.startsWith(action ?? ""))
|
|
829
|
+
.map((item) => ({ value: `${item} `, label: item }));
|
|
830
|
+
}
|
|
831
|
+
if (action !== "login" && action !== "logout" && action !== "reconnect")
|
|
832
|
+
return null;
|
|
833
|
+
const items = servers
|
|
834
|
+
.filter((candidate) => action === "reconnect" ? candidate.connection !== undefined : usesOAuth(candidate))
|
|
835
|
+
.filter((candidate) => candidate.entry.name.startsWith(server))
|
|
836
|
+
.map((candidate) => ({
|
|
837
|
+
value: `${action} ${candidate.entry.name}`,
|
|
838
|
+
label: candidate.entry.name,
|
|
839
|
+
description: describeState(candidate),
|
|
840
|
+
}));
|
|
841
|
+
return items.length > 0 ? items : null;
|
|
842
|
+
},
|
|
843
|
+
handler: async (args, ctx) => {
|
|
844
|
+
await pending;
|
|
845
|
+
const [action, name, ...extra] = args.trim().split(/\s+/).filter(Boolean);
|
|
846
|
+
if (action === undefined) {
|
|
847
|
+
if (ctx.mode === "tui")
|
|
848
|
+
await showMcpManager(ctx, (ui) => manage(ui, ctx));
|
|
849
|
+
else
|
|
850
|
+
ctx.ui.notify(formatStatus(), "info");
|
|
851
|
+
return;
|
|
852
|
+
}
|
|
853
|
+
if (extra.length > 0) {
|
|
854
|
+
ctx.ui.notify(MCP_USAGE, "warning");
|
|
855
|
+
return;
|
|
856
|
+
}
|
|
857
|
+
switch (action) {
|
|
858
|
+
case "login": {
|
|
859
|
+
const server = await pickServer(name, ctx, oauthPick);
|
|
860
|
+
if (server)
|
|
861
|
+
await loginCommand(server, ctx);
|
|
862
|
+
return;
|
|
863
|
+
}
|
|
864
|
+
case "logout": {
|
|
865
|
+
const server = await pickServer(name, ctx, oauthPick);
|
|
866
|
+
if (!server)
|
|
867
|
+
return;
|
|
868
|
+
const removed = await signOut(server);
|
|
869
|
+
ctx.ui.notify(removed
|
|
870
|
+
? `Signed out of MCP server "${server.entry.name}".`
|
|
871
|
+
: `No stored credentials for MCP server "${server.entry.name}".`, "info");
|
|
872
|
+
return;
|
|
873
|
+
}
|
|
874
|
+
case "reconnect": {
|
|
875
|
+
const server = await pickServer(name, ctx, {
|
|
876
|
+
eligible: (candidate) => candidate.connection !== undefined,
|
|
877
|
+
preferred: (candidate) => candidate.connection?.state === "failed" || candidate.connection?.state === "disconnected",
|
|
878
|
+
none: "No enabled MCP server to reconnect.",
|
|
879
|
+
});
|
|
880
|
+
if (!server)
|
|
881
|
+
return;
|
|
882
|
+
const failure = await reconnect(server);
|
|
883
|
+
if (failure)
|
|
884
|
+
ctx.ui.notify(failure, "error");
|
|
885
|
+
else {
|
|
886
|
+
ensureDiscoveryActive(ctx);
|
|
887
|
+
ctx.ui.notify(`Reconnected to MCP server "${server.entry.name}" (${describeState(server)}).`, "info");
|
|
888
|
+
}
|
|
889
|
+
return;
|
|
890
|
+
}
|
|
891
|
+
default:
|
|
892
|
+
ctx.ui.notify(MCP_USAGE, "warning");
|
|
893
|
+
}
|
|
894
|
+
},
|
|
895
|
+
});
|
|
896
|
+
};
|
|
897
|
+
}
|
|
898
|
+
function defaultLoadConfig(ctx) {
|
|
899
|
+
return loadMcpConfig({ agentDir: getAgentDir(), cwd: ctx.cwd, projectTrusted: ctx.isProjectTrusted() });
|
|
900
|
+
}
|
|
901
|
+
export default createMcpExtension();
|
|
902
|
+
//# sourceMappingURL=index.js.map
|