@chances-ai/engine 24.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agents/discover.d.ts +30 -0
- package/dist/agents/discover.d.ts.map +1 -0
- package/dist/agents/discover.js +183 -0
- package/dist/agents/discover.js.map +1 -0
- package/dist/agents/index.d.ts +20 -0
- package/dist/agents/index.d.ts.map +1 -0
- package/dist/agents/index.js +52 -0
- package/dist/agents/index.js.map +1 -0
- package/dist/agents/parse.d.ts +61 -0
- package/dist/agents/parse.d.ts.map +1 -0
- package/dist/agents/parse.js +527 -0
- package/dist/agents/parse.js.map +1 -0
- package/dist/agents/types.d.ts +52 -0
- package/dist/agents/types.d.ts.map +1 -0
- package/dist/agents/types.js +8 -0
- package/dist/agents/types.js.map +1 -0
- package/dist/ai/adapters/ai-sdk-stream.d.ts +19 -0
- package/dist/ai/adapters/ai-sdk-stream.d.ts.map +1 -0
- package/dist/ai/adapters/ai-sdk-stream.js +125 -0
- package/dist/ai/adapters/ai-sdk-stream.js.map +1 -0
- package/dist/ai/adapters/ai-sdk.d.ts +56 -0
- package/dist/ai/adapters/ai-sdk.d.ts.map +1 -0
- package/dist/ai/adapters/ai-sdk.js +112 -0
- package/dist/ai/adapters/ai-sdk.js.map +1 -0
- package/dist/ai/adapters/mock.d.ts +13 -0
- package/dist/ai/adapters/mock.d.ts.map +1 -0
- package/dist/ai/adapters/mock.js +54 -0
- package/dist/ai/adapters/mock.js.map +1 -0
- package/dist/ai/adapters/openai-compatible.d.ts +23 -0
- package/dist/ai/adapters/openai-compatible.d.ts.map +1 -0
- package/dist/ai/adapters/openai-compatible.js +45 -0
- package/dist/ai/adapters/openai-compatible.js.map +1 -0
- package/dist/ai/cost.d.ts +3 -0
- package/dist/ai/cost.d.ts.map +1 -0
- package/dist/ai/cost.js +5 -0
- package/dist/ai/cost.js.map +1 -0
- package/dist/ai/index.d.ts +12 -0
- package/dist/ai/index.d.ts.map +1 -0
- package/dist/ai/index.js +11 -0
- package/dist/ai/index.js.map +1 -0
- package/dist/ai/known-models.d.ts +20 -0
- package/dist/ai/known-models.d.ts.map +1 -0
- package/dist/ai/known-models.js +129 -0
- package/dist/ai/known-models.js.map +1 -0
- package/dist/ai/registry.d.ts +12 -0
- package/dist/ai/registry.d.ts.map +1 -0
- package/dist/ai/registry.js +24 -0
- package/dist/ai/registry.js.map +1 -0
- package/dist/ai/retry.d.ts +11 -0
- package/dist/ai/retry.d.ts.map +1 -0
- package/dist/ai/retry.js +14 -0
- package/dist/ai/retry.js.map +1 -0
- package/dist/ai/router.d.ts +25 -0
- package/dist/ai/router.d.ts.map +1 -0
- package/dist/ai/router.js +36 -0
- package/dist/ai/router.js.map +1 -0
- package/dist/ai/setup.d.ts +23 -0
- package/dist/ai/setup.d.ts.map +1 -0
- package/dist/ai/setup.js +47 -0
- package/dist/ai/setup.js.map +1 -0
- package/dist/ai/summarizer.d.ts +24 -0
- package/dist/ai/summarizer.d.ts.map +1 -0
- package/dist/ai/summarizer.js +56 -0
- package/dist/ai/summarizer.js.map +1 -0
- package/dist/ai/types.d.ts +83 -0
- package/dist/ai/types.d.ts.map +1 -0
- package/dist/ai/types.js +2 -0
- package/dist/ai/types.js.map +1 -0
- package/dist/core/compaction/circuit-breaker.d.ts +32 -0
- package/dist/core/compaction/circuit-breaker.d.ts.map +1 -0
- package/dist/core/compaction/circuit-breaker.js +42 -0
- package/dist/core/compaction/circuit-breaker.js.map +1 -0
- package/dist/core/compaction/compactor.d.ts +75 -0
- package/dist/core/compaction/compactor.d.ts.map +1 -0
- package/dist/core/compaction/compactor.js +261 -0
- package/dist/core/compaction/compactor.js.map +1 -0
- package/dist/core/compaction/estimate.d.ts +39 -0
- package/dist/core/compaction/estimate.d.ts.map +1 -0
- package/dist/core/compaction/estimate.js +74 -0
- package/dist/core/compaction/estimate.js.map +1 -0
- package/dist/core/compaction/index.d.ts +5 -0
- package/dist/core/compaction/index.d.ts.map +1 -0
- package/dist/core/compaction/index.js +5 -0
- package/dist/core/compaction/index.js.map +1 -0
- package/dist/core/compaction/prune.d.ts +43 -0
- package/dist/core/compaction/prune.d.ts.map +1 -0
- package/dist/core/compaction/prune.js +51 -0
- package/dist/core/compaction/prune.js.map +1 -0
- package/dist/core/engine.d.ts +268 -0
- package/dist/core/engine.d.ts.map +1 -0
- package/dist/core/engine.js +767 -0
- package/dist/core/engine.js.map +1 -0
- package/dist/core/index.d.ts +6 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +6 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/task-tool.d.ts +175 -0
- package/dist/core/task-tool.d.ts.map +1 -0
- package/dist/core/task-tool.js +901 -0
- package/dist/core/task-tool.js.map +1 -0
- package/dist/core/workspace-query.d.ts +83 -0
- package/dist/core/workspace-query.d.ts.map +1 -0
- package/dist/core/workspace-query.js +217 -0
- package/dist/core/workspace-query.js.map +1 -0
- package/dist/core/worktree/active-marker.d.ts +31 -0
- package/dist/core/worktree/active-marker.d.ts.map +1 -0
- package/dist/core/worktree/active-marker.js +109 -0
- package/dist/core/worktree/active-marker.js.map +1 -0
- package/dist/core/worktree/create.d.ts +40 -0
- package/dist/core/worktree/create.d.ts.map +1 -0
- package/dist/core/worktree/create.js +121 -0
- package/dist/core/worktree/create.js.map +1 -0
- package/dist/core/worktree/errors.d.ts +7 -0
- package/dist/core/worktree/errors.d.ts.map +1 -0
- package/dist/core/worktree/errors.js +11 -0
- package/dist/core/worktree/errors.js.map +1 -0
- package/dist/core/worktree/gc.d.ts +39 -0
- package/dist/core/worktree/gc.d.ts.map +1 -0
- package/dist/core/worktree/gc.js +146 -0
- package/dist/core/worktree/gc.js.map +1 -0
- package/dist/core/worktree/git.d.ts +53 -0
- package/dist/core/worktree/git.d.ts.map +1 -0
- package/dist/core/worktree/git.js +166 -0
- package/dist/core/worktree/git.js.map +1 -0
- package/dist/core/worktree/index.d.ts +8 -0
- package/dist/core/worktree/index.d.ts.map +1 -0
- package/dist/core/worktree/index.js +8 -0
- package/dist/core/worktree/index.js.map +1 -0
- package/dist/core/worktree/paths.d.ts +26 -0
- package/dist/core/worktree/paths.d.ts.map +1 -0
- package/dist/core/worktree/paths.js +57 -0
- package/dist/core/worktree/paths.js.map +1 -0
- package/dist/core/worktree/slug.d.ts +6 -0
- package/dist/core/worktree/slug.d.ts.map +1 -0
- package/dist/core/worktree/slug.js +21 -0
- package/dist/core/worktree/slug.js.map +1 -0
- package/dist/local-vault/file-store.d.ts +64 -0
- package/dist/local-vault/file-store.d.ts.map +1 -0
- package/dist/local-vault/file-store.js +225 -0
- package/dist/local-vault/file-store.js.map +1 -0
- package/dist/local-vault/index.d.ts +57 -0
- package/dist/local-vault/index.d.ts.map +1 -0
- package/dist/local-vault/index.js +68 -0
- package/dist/local-vault/index.js.map +1 -0
- package/dist/local-vault/keychain.d.ts +58 -0
- package/dist/local-vault/keychain.d.ts.map +1 -0
- package/dist/local-vault/keychain.js +200 -0
- package/dist/local-vault/keychain.js.map +1 -0
- package/dist/local-vault/mutex.d.ts +20 -0
- package/dist/local-vault/mutex.d.ts.map +1 -0
- package/dist/local-vault/mutex.js +44 -0
- package/dist/local-vault/mutex.js.map +1 -0
- package/dist/local-vault/passphrase.d.ts +30 -0
- package/dist/local-vault/passphrase.d.ts.map +1 -0
- package/dist/local-vault/passphrase.js +72 -0
- package/dist/local-vault/passphrase.js.map +1 -0
- package/dist/lsp/config.d.ts +34 -0
- package/dist/lsp/config.d.ts.map +1 -0
- package/dist/lsp/config.js +68 -0
- package/dist/lsp/config.js.map +1 -0
- package/dist/lsp/detect.d.ts +7 -0
- package/dist/lsp/detect.d.ts.map +1 -0
- package/dist/lsp/detect.js +78 -0
- package/dist/lsp/detect.js.map +1 -0
- package/dist/lsp/errors.d.ts +11 -0
- package/dist/lsp/errors.d.ts.map +1 -0
- package/dist/lsp/errors.js +11 -0
- package/dist/lsp/errors.js.map +1 -0
- package/dist/lsp/formatters.d.ts +147 -0
- package/dist/lsp/formatters.d.ts.map +1 -0
- package/dist/lsp/formatters.js +259 -0
- package/dist/lsp/formatters.js.map +1 -0
- package/dist/lsp/index.d.ts +31 -0
- package/dist/lsp/index.d.ts.map +1 -0
- package/dist/lsp/index.js +31 -0
- package/dist/lsp/index.js.map +1 -0
- package/dist/lsp/instance.d.ts +72 -0
- package/dist/lsp/instance.d.ts.map +1 -0
- package/dist/lsp/instance.js +489 -0
- package/dist/lsp/instance.js.map +1 -0
- package/dist/lsp/lazy-load.d.ts +27 -0
- package/dist/lsp/lazy-load.d.ts.map +1 -0
- package/dist/lsp/lazy-load.js +57 -0
- package/dist/lsp/lazy-load.js.map +1 -0
- package/dist/lsp/manager.d.ts +59 -0
- package/dist/lsp/manager.d.ts.map +1 -0
- package/dist/lsp/manager.js +242 -0
- package/dist/lsp/manager.js.map +1 -0
- package/dist/lsp/ops.d.ts +13 -0
- package/dist/lsp/ops.d.ts.map +1 -0
- package/dist/lsp/ops.js +225 -0
- package/dist/lsp/ops.js.map +1 -0
- package/dist/lsp/rpc.d.ts +47 -0
- package/dist/lsp/rpc.d.ts.map +1 -0
- package/dist/lsp/rpc.js +134 -0
- package/dist/lsp/rpc.js.map +1 -0
- package/dist/lsp/safe-uri.d.ts +18 -0
- package/dist/lsp/safe-uri.d.ts.map +1 -0
- package/dist/lsp/safe-uri.js +96 -0
- package/dist/lsp/safe-uri.js.map +1 -0
- package/dist/lsp/types.d.ts +70 -0
- package/dist/lsp/types.d.ts.map +1 -0
- package/dist/lsp/types.js +16 -0
- package/dist/lsp/types.js.map +1 -0
- package/dist/mcp/bridge.d.ts +57 -0
- package/dist/mcp/bridge.d.ts.map +1 -0
- package/dist/mcp/bridge.js +98 -0
- package/dist/mcp/bridge.js.map +1 -0
- package/dist/mcp/category.d.ts +22 -0
- package/dist/mcp/category.d.ts.map +1 -0
- package/dist/mcp/category.js +11 -0
- package/dist/mcp/category.js.map +1 -0
- package/dist/mcp/client.d.ts +228 -0
- package/dist/mcp/client.d.ts.map +1 -0
- package/dist/mcp/client.js +352 -0
- package/dist/mcp/client.js.map +1 -0
- package/dist/mcp/content.d.ts +86 -0
- package/dist/mcp/content.d.ts.map +1 -0
- package/dist/mcp/content.js +147 -0
- package/dist/mcp/content.js.map +1 -0
- package/dist/mcp/env.d.ts +19 -0
- package/dist/mcp/env.d.ts.map +1 -0
- package/dist/mcp/env.js +50 -0
- package/dist/mcp/env.js.map +1 -0
- package/dist/mcp/host.d.ts +199 -0
- package/dist/mcp/host.d.ts.map +1 -0
- package/dist/mcp/host.js +530 -0
- package/dist/mcp/host.js.map +1 -0
- package/dist/mcp/index.d.ts +18 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +17 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/load-mcp-host.d.ts +32 -0
- package/dist/mcp/load-mcp-host.d.ts.map +1 -0
- package/dist/mcp/load-mcp-host.js +49 -0
- package/dist/mcp/load-mcp-host.js.map +1 -0
- package/dist/mcp/oauth/callback-server.d.ts +73 -0
- package/dist/mcp/oauth/callback-server.d.ts.map +1 -0
- package/dist/mcp/oauth/callback-server.js +280 -0
- package/dist/mcp/oauth/callback-server.js.map +1 -0
- package/dist/mcp/oauth/config-hash.d.ts +24 -0
- package/dist/mcp/oauth/config-hash.d.ts.map +1 -0
- package/dist/mcp/oauth/config-hash.js +55 -0
- package/dist/mcp/oauth/config-hash.js.map +1 -0
- package/dist/mcp/oauth/error-normalize.d.ts +39 -0
- package/dist/mcp/oauth/error-normalize.d.ts.map +1 -0
- package/dist/mcp/oauth/error-normalize.js +91 -0
- package/dist/mcp/oauth/error-normalize.js.map +1 -0
- package/dist/mcp/oauth/provider.d.ts +190 -0
- package/dist/mcp/oauth/provider.d.ts.map +1 -0
- package/dist/mcp/oauth/provider.js +305 -0
- package/dist/mcp/oauth/provider.js.map +1 -0
- package/dist/mcp/oauth/refresh-coalescer.d.ts +46 -0
- package/dist/mcp/oauth/refresh-coalescer.d.ts.map +1 -0
- package/dist/mcp/oauth/refresh-coalescer.js +77 -0
- package/dist/mcp/oauth/refresh-coalescer.js.map +1 -0
- package/dist/mcp/oauth/sdk-shapes.d.ts +77 -0
- package/dist/mcp/oauth/sdk-shapes.d.ts.map +1 -0
- package/dist/mcp/oauth/sdk-shapes.js +21 -0
- package/dist/mcp/oauth/sdk-shapes.js.map +1 -0
- package/dist/mcp/parse.d.ts +28 -0
- package/dist/mcp/parse.d.ts.map +1 -0
- package/dist/mcp/parse.js +209 -0
- package/dist/mcp/parse.js.map +1 -0
- package/dist/mcp/prompts.d.ts +31 -0
- package/dist/mcp/prompts.d.ts.map +1 -0
- package/dist/mcp/prompts.js +71 -0
- package/dist/mcp/prompts.js.map +1 -0
- package/dist/mcp/redact.d.ts +62 -0
- package/dist/mcp/redact.d.ts.map +1 -0
- package/dist/mcp/redact.js +87 -0
- package/dist/mcp/redact.js.map +1 -0
- package/dist/mcp/resources.d.ts +70 -0
- package/dist/mcp/resources.d.ts.map +1 -0
- package/dist/mcp/resources.js +170 -0
- package/dist/mcp/resources.js.map +1 -0
- package/dist/mcp/types.d.ts +123 -0
- package/dist/mcp/types.d.ts.map +1 -0
- package/dist/mcp/types.js +2 -0
- package/dist/mcp/types.js.map +1 -0
- package/dist/memory/frontmatter.d.ts +18 -0
- package/dist/memory/frontmatter.d.ts.map +1 -0
- package/dist/memory/frontmatter.js +81 -0
- package/dist/memory/frontmatter.js.map +1 -0
- package/dist/memory/index.d.ts +5 -0
- package/dist/memory/index.d.ts.map +1 -0
- package/dist/memory/index.js +5 -0
- package/dist/memory/index.js.map +1 -0
- package/dist/memory/store.d.ts +44 -0
- package/dist/memory/store.d.ts.map +1 -0
- package/dist/memory/store.js +237 -0
- package/dist/memory/store.js.map +1 -0
- package/dist/memory/tools.d.ts +11 -0
- package/dist/memory/tools.d.ts.map +1 -0
- package/dist/memory/tools.js +159 -0
- package/dist/memory/tools.js.map +1 -0
- package/dist/memory/types.d.ts +32 -0
- package/dist/memory/types.d.ts.map +1 -0
- package/dist/memory/types.js +20 -0
- package/dist/memory/types.js.map +1 -0
- package/dist/plugin-api/index.d.ts +167 -0
- package/dist/plugin-api/index.d.ts.map +1 -0
- package/dist/plugin-api/index.js +151 -0
- package/dist/plugin-api/index.js.map +1 -0
- package/dist/plugin-logger/index.d.ts +21 -0
- package/dist/plugin-logger/index.d.ts.map +1 -0
- package/dist/plugin-logger/index.js +59 -0
- package/dist/plugin-logger/index.js.map +1 -0
- package/dist/session/index.d.ts +125 -0
- package/dist/session/index.d.ts.map +1 -0
- package/dist/session/index.js +202 -0
- package/dist/session/index.js.map +1 -0
- package/dist/tools/approval.d.ts +33 -0
- package/dist/tools/approval.d.ts.map +1 -0
- package/dist/tools/approval.js +53 -0
- package/dist/tools/approval.js.map +1 -0
- package/dist/tools/builtins/_shared.d.ts +94 -0
- package/dist/tools/builtins/_shared.d.ts.map +1 -0
- package/dist/tools/builtins/_shared.js +246 -0
- package/dist/tools/builtins/_shared.js.map +1 -0
- package/dist/tools/builtins/ask-user-question.d.ts +27 -0
- package/dist/tools/builtins/ask-user-question.d.ts.map +1 -0
- package/dist/tools/builtins/ask-user-question.js +191 -0
- package/dist/tools/builtins/ask-user-question.js.map +1 -0
- package/dist/tools/builtins/bash.d.ts +3 -0
- package/dist/tools/builtins/bash.d.ts.map +1 -0
- package/dist/tools/builtins/bash.js +158 -0
- package/dist/tools/builtins/bash.js.map +1 -0
- package/dist/tools/builtins/diff.d.ts +3 -0
- package/dist/tools/builtins/diff.d.ts.map +1 -0
- package/dist/tools/builtins/diff.js +83 -0
- package/dist/tools/builtins/diff.js.map +1 -0
- package/dist/tools/builtins/edit.d.ts +3 -0
- package/dist/tools/builtins/edit.d.ts.map +1 -0
- package/dist/tools/builtins/edit.js +40 -0
- package/dist/tools/builtins/edit.js.map +1 -0
- package/dist/tools/builtins/glob.d.ts +3 -0
- package/dist/tools/builtins/glob.d.ts.map +1 -0
- package/dist/tools/builtins/glob.js +37 -0
- package/dist/tools/builtins/glob.js.map +1 -0
- package/dist/tools/builtins/grep.d.ts +3 -0
- package/dist/tools/builtins/grep.d.ts.map +1 -0
- package/dist/tools/builtins/grep.js +81 -0
- package/dist/tools/builtins/grep.js.map +1 -0
- package/dist/tools/builtins/lsp.d.ts +3 -0
- package/dist/tools/builtins/lsp.d.ts.map +1 -0
- package/dist/tools/builtins/lsp.js +102 -0
- package/dist/tools/builtins/lsp.js.map +1 -0
- package/dist/tools/builtins/pty.d.ts +64 -0
- package/dist/tools/builtins/pty.d.ts.map +1 -0
- package/dist/tools/builtins/pty.js +536 -0
- package/dist/tools/builtins/pty.js.map +1 -0
- package/dist/tools/builtins/read.d.ts +3 -0
- package/dist/tools/builtins/read.d.ts.map +1 -0
- package/dist/tools/builtins/read.js +18 -0
- package/dist/tools/builtins/read.js.map +1 -0
- package/dist/tools/builtins/web-fetch.d.ts +4 -0
- package/dist/tools/builtins/web-fetch.d.ts.map +1 -0
- package/dist/tools/builtins/web-fetch.js +353 -0
- package/dist/tools/builtins/web-fetch.js.map +1 -0
- package/dist/tools/builtins/write.d.ts +3 -0
- package/dist/tools/builtins/write.d.ts.map +1 -0
- package/dist/tools/builtins/write.js +48 -0
- package/dist/tools/builtins/write.js.map +1 -0
- package/dist/tools/builtins.d.ts +9 -0
- package/dist/tools/builtins.d.ts.map +1 -0
- package/dist/tools/builtins.js +29 -0
- package/dist/tools/builtins.js.map +1 -0
- package/dist/tools/diff.d.ts +18 -0
- package/dist/tools/diff.d.ts.map +1 -0
- package/dist/tools/diff.js +57 -0
- package/dist/tools/diff.js.map +1 -0
- package/dist/tools/index.d.ts +10 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +9 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/permission.d.ts +120 -0
- package/dist/tools/permission.d.ts.map +1 -0
- package/dist/tools/permission.js +208 -0
- package/dist/tools/permission.js.map +1 -0
- package/dist/tools/registry.d.ts +12 -0
- package/dist/tools/registry.d.ts.map +1 -0
- package/dist/tools/registry.js +19 -0
- package/dist/tools/registry.js.map +1 -0
- package/dist/tools/types.d.ts +244 -0
- package/dist/tools/types.d.ts.map +1 -0
- package/dist/tools/types.js +15 -0
- package/dist/tools/types.js.map +1 -0
- package/package.json +109 -0
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type-only mirrors of `@modelcontextprotocol/sdk/shared/auth.js` shapes.
|
|
3
|
+
*
|
|
4
|
+
* Why mirror instead of `import type { ... }` from the SDK?
|
|
5
|
+
*
|
|
6
|
+
* The SDK is an OPTIONAL peer dependency. When MCP is disabled, the SDK
|
|
7
|
+
* is absent from `node_modules` entirely. A bare `import type` is erased
|
|
8
|
+
* at runtime, BUT `tsc` still resolves the module and errors when the
|
|
9
|
+
* SDK isn't installed in the build environment (e.g. consumer projects
|
|
10
|
+
* that depend on `@chances-ai/cli` without enabling MCP). The
|
|
11
|
+
* runtime-load story (computed-specifier dynamic import in `client.ts`
|
|
12
|
+
* and `provider.ts` wiring) keeps the binary compileable without the
|
|
13
|
+
* SDK; this file keeps the TYPE story consistent.
|
|
14
|
+
*
|
|
15
|
+
* These mirrors must stay aligned with SDK `1.29.0` `shared/auth.d.ts`.
|
|
16
|
+
* Drift is acceptable because the runtime path uses the SDK's own zod
|
|
17
|
+
* schemas — our types are advisory, not load-bearing. The integration
|
|
18
|
+
* test (`e2e-oauth.test.ts`) exercises the real SDK shapes end-to-end.
|
|
19
|
+
*/
|
|
20
|
+
/** RFC 6749 / OAuth 2.1 token response (snake_case). */
|
|
21
|
+
export interface OAuthTokens {
|
|
22
|
+
access_token: string;
|
|
23
|
+
token_type: string;
|
|
24
|
+
refresh_token?: string;
|
|
25
|
+
scope?: string;
|
|
26
|
+
id_token?: string;
|
|
27
|
+
/** Relative seconds — convert to absolute `expires_at` (epoch ms) on save. */
|
|
28
|
+
expires_in?: number;
|
|
29
|
+
}
|
|
30
|
+
/** RFC 7591 client information — fields we surface to the SDK. */
|
|
31
|
+
export interface OAuthClientInformation {
|
|
32
|
+
client_id: string;
|
|
33
|
+
client_secret?: string;
|
|
34
|
+
client_id_issued_at?: number;
|
|
35
|
+
client_secret_expires_at?: number;
|
|
36
|
+
}
|
|
37
|
+
/** RFC 7591 full DCR response — `OAuthClientInformation` + metadata. */
|
|
38
|
+
export interface OAuthClientInformationFull extends OAuthClientInformation {
|
|
39
|
+
redirect_uris: readonly string[];
|
|
40
|
+
token_endpoint_auth_method?: string;
|
|
41
|
+
grant_types?: readonly string[];
|
|
42
|
+
response_types?: readonly string[];
|
|
43
|
+
client_name?: string;
|
|
44
|
+
client_uri?: string;
|
|
45
|
+
logo_uri?: string;
|
|
46
|
+
scope?: string;
|
|
47
|
+
contacts?: readonly string[];
|
|
48
|
+
tos_uri?: string;
|
|
49
|
+
policy_uri?: string;
|
|
50
|
+
jwks_uri?: string;
|
|
51
|
+
jwks?: unknown;
|
|
52
|
+
software_id?: string;
|
|
53
|
+
software_version?: string;
|
|
54
|
+
software_statement?: string;
|
|
55
|
+
}
|
|
56
|
+
/** Union the SDK passes through `clientInformation()` / `saveClientInformation()`. */
|
|
57
|
+
export type OAuthClientInformationMixed = OAuthClientInformation | OAuthClientInformationFull;
|
|
58
|
+
/** RFC 7591 DCR registration request body. */
|
|
59
|
+
export interface OAuthClientMetadata {
|
|
60
|
+
redirect_uris: readonly string[];
|
|
61
|
+
token_endpoint_auth_method?: string;
|
|
62
|
+
grant_types?: readonly string[];
|
|
63
|
+
response_types?: readonly string[];
|
|
64
|
+
client_name?: string;
|
|
65
|
+
client_uri?: string;
|
|
66
|
+
logo_uri?: string;
|
|
67
|
+
scope?: string;
|
|
68
|
+
contacts?: readonly string[];
|
|
69
|
+
tos_uri?: string;
|
|
70
|
+
policy_uri?: string;
|
|
71
|
+
jwks_uri?: string;
|
|
72
|
+
jwks?: unknown;
|
|
73
|
+
software_id?: string;
|
|
74
|
+
software_version?: string;
|
|
75
|
+
software_statement?: string;
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=sdk-shapes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sdk-shapes.d.ts","sourceRoot":"","sources":["../../../src/mcp/oauth/sdk-shapes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,wDAAwD;AACxD,MAAM,WAAW,WAAW;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,8EAA8E;IAC9E,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,kEAAkE;AAClE,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,wBAAwB,CAAC,EAAE,MAAM,CAAC;CACnC;AAED,wEAAwE;AACxE,MAAM,WAAW,0BAA2B,SAAQ,sBAAsB;IACxE,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,0BAA0B,CAAC,EAAE,MAAM,CAAC;IACpC,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,sFAAsF;AACtF,MAAM,MAAM,2BAA2B,GAAG,sBAAsB,GAAG,0BAA0B,CAAC;AAE9F,8CAA8C;AAC9C,MAAM,WAAW,mBAAmB;IAClC,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,0BAA0B,CAAC,EAAE,MAAM,CAAC;IACpC,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type-only mirrors of `@modelcontextprotocol/sdk/shared/auth.js` shapes.
|
|
3
|
+
*
|
|
4
|
+
* Why mirror instead of `import type { ... }` from the SDK?
|
|
5
|
+
*
|
|
6
|
+
* The SDK is an OPTIONAL peer dependency. When MCP is disabled, the SDK
|
|
7
|
+
* is absent from `node_modules` entirely. A bare `import type` is erased
|
|
8
|
+
* at runtime, BUT `tsc` still resolves the module and errors when the
|
|
9
|
+
* SDK isn't installed in the build environment (e.g. consumer projects
|
|
10
|
+
* that depend on `@chances-ai/cli` without enabling MCP). The
|
|
11
|
+
* runtime-load story (computed-specifier dynamic import in `client.ts`
|
|
12
|
+
* and `provider.ts` wiring) keeps the binary compileable without the
|
|
13
|
+
* SDK; this file keeps the TYPE story consistent.
|
|
14
|
+
*
|
|
15
|
+
* These mirrors must stay aligned with SDK `1.29.0` `shared/auth.d.ts`.
|
|
16
|
+
* Drift is acceptable because the runtime path uses the SDK's own zod
|
|
17
|
+
* schemas — our types are advisory, not load-bearing. The integration
|
|
18
|
+
* test (`e2e-oauth.test.ts`) exercises the real SDK shapes end-to-end.
|
|
19
|
+
*/
|
|
20
|
+
export {};
|
|
21
|
+
//# sourceMappingURL=sdk-shapes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sdk-shapes.js","sourceRoot":"","sources":["../../../src/mcp/oauth/sdk-shapes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { McpServerConfig } from "./types.js";
|
|
2
|
+
export interface ParseFailure {
|
|
3
|
+
error: string;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Defensive narrowing from `unknown` JSON to the typed `McpServerConfig`
|
|
7
|
+
* union. The config layer keeps MCP entries as opaque records — this is
|
|
8
|
+
* where we enforce the discriminator + required-field shape so a malformed
|
|
9
|
+
* entry can't crash `McpHost.start`.
|
|
10
|
+
*
|
|
11
|
+
* Unknown fields are **dropped** (not preserved) — we explicitly enumerate
|
|
12
|
+
* every accepted field below. When the SDK adds a new transport-specific
|
|
13
|
+
* knob, this parser must learn it too. The trade-off favors auditability
|
|
14
|
+
* (one place to see what's accepted) over auto-passthrough (which would
|
|
15
|
+
* forward typos like `enableed: true` straight to the SDK and silently
|
|
16
|
+
* misbehave).
|
|
17
|
+
*/
|
|
18
|
+
export declare function parseServerConfig(raw: unknown): McpServerConfig | ParseFailure;
|
|
19
|
+
/**
|
|
20
|
+
* Parses the entire `mcp.servers` map. Per-server failures are reported via
|
|
21
|
+
* `failures` so the caller can surface them on the log without dropping the
|
|
22
|
+
* good entries.
|
|
23
|
+
*/
|
|
24
|
+
export declare function parseServerMap(raw: Record<string, unknown> | undefined): {
|
|
25
|
+
servers: Record<string, McpServerConfig>;
|
|
26
|
+
failures: Record<string, string>;
|
|
27
|
+
};
|
|
28
|
+
//# sourceMappingURL=parse.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../../src/mcp/parse.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAgB,MAAM,YAAY,CAAC;AAEhE,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,OAAO,GAAG,eAAe,GAAG,YAAY,CA2D9E;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GACvC;IAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,CAYhF"}
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Defensive narrowing from `unknown` JSON to the typed `McpServerConfig`
|
|
3
|
+
* union. The config layer keeps MCP entries as opaque records — this is
|
|
4
|
+
* where we enforce the discriminator + required-field shape so a malformed
|
|
5
|
+
* entry can't crash `McpHost.start`.
|
|
6
|
+
*
|
|
7
|
+
* Unknown fields are **dropped** (not preserved) — we explicitly enumerate
|
|
8
|
+
* every accepted field below. When the SDK adds a new transport-specific
|
|
9
|
+
* knob, this parser must learn it too. The trade-off favors auditability
|
|
10
|
+
* (one place to see what's accepted) over auto-passthrough (which would
|
|
11
|
+
* forward typos like `enableed: true` straight to the SDK and silently
|
|
12
|
+
* misbehave).
|
|
13
|
+
*/
|
|
14
|
+
export function parseServerConfig(raw) {
|
|
15
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
|
|
16
|
+
return { error: "mcp server config must be a JSON object" };
|
|
17
|
+
}
|
|
18
|
+
const obj = raw;
|
|
19
|
+
const type = obj["type"];
|
|
20
|
+
if (type === "stdio") {
|
|
21
|
+
if (typeof obj["command"] !== "string" || !obj["command"]) {
|
|
22
|
+
return { error: "stdio mcp server: 'command' (string) is required" };
|
|
23
|
+
}
|
|
24
|
+
const args = obj["args"];
|
|
25
|
+
if (args !== undefined && !isStringArray(args)) {
|
|
26
|
+
return { error: "stdio mcp server: 'args' must be an array of strings" };
|
|
27
|
+
}
|
|
28
|
+
const env = obj["env"];
|
|
29
|
+
if (env !== undefined && !isStringRecord(env)) {
|
|
30
|
+
return { error: "stdio mcp server: 'env' must be a string-keyed string map" };
|
|
31
|
+
}
|
|
32
|
+
if (obj["cwd"] !== undefined && typeof obj["cwd"] !== "string") {
|
|
33
|
+
return { error: "stdio mcp server: 'cwd' must be a string" };
|
|
34
|
+
}
|
|
35
|
+
return {
|
|
36
|
+
type: "stdio",
|
|
37
|
+
command: obj["command"],
|
|
38
|
+
args: args,
|
|
39
|
+
env: env,
|
|
40
|
+
cwd: obj["cwd"],
|
|
41
|
+
enabled: optBool(obj["enabled"]),
|
|
42
|
+
timeoutMs: optPositiveInt(obj["timeoutMs"]),
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
if (type === "http") {
|
|
46
|
+
if (typeof obj["url"] !== "string" || !obj["url"]) {
|
|
47
|
+
return { error: "http mcp server: 'url' (string) is required" };
|
|
48
|
+
}
|
|
49
|
+
const headers = obj["headers"];
|
|
50
|
+
if (headers !== undefined && !isStringRecord(headers)) {
|
|
51
|
+
return { error: "http mcp server: 'headers' must be a string-keyed string map" };
|
|
52
|
+
}
|
|
53
|
+
const authResult = parseOAuthAuth(obj["auth"]);
|
|
54
|
+
if ("error" in authResult)
|
|
55
|
+
return authResult;
|
|
56
|
+
// (codex Round-1 MUST-FIX #7) When OAuth is configured, the resource
|
|
57
|
+
// URL MUST be https:// (RFC 6750 §5.2 — bearer tokens travel in
|
|
58
|
+
// cleartext otherwise). Loopback exceptions allowed for local-dev MCP
|
|
59
|
+
// servers running on `127.0.0.1` / `[::1]` / `localhost`.
|
|
60
|
+
if (authResult.auth) {
|
|
61
|
+
const httpsErr = validateOAuthResourceUrl(obj["url"]);
|
|
62
|
+
if (httpsErr)
|
|
63
|
+
return { error: httpsErr };
|
|
64
|
+
}
|
|
65
|
+
return {
|
|
66
|
+
type: "http",
|
|
67
|
+
url: obj["url"],
|
|
68
|
+
headers: headers,
|
|
69
|
+
enabled: optBool(obj["enabled"]),
|
|
70
|
+
timeoutMs: optPositiveInt(obj["timeoutMs"]),
|
|
71
|
+
auth: authResult.auth,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
return { error: `mcp server: 'type' must be 'stdio' or 'http' (got ${JSON.stringify(type)})` };
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Parses the entire `mcp.servers` map. Per-server failures are reported via
|
|
78
|
+
* `failures` so the caller can surface them on the log without dropping the
|
|
79
|
+
* good entries.
|
|
80
|
+
*/
|
|
81
|
+
export function parseServerMap(raw) {
|
|
82
|
+
const servers = {};
|
|
83
|
+
const failures = {};
|
|
84
|
+
for (const [id, value] of Object.entries(raw ?? {})) {
|
|
85
|
+
const parsed = parseServerConfig(value);
|
|
86
|
+
if ("error" in parsed) {
|
|
87
|
+
failures[id] = parsed.error;
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
servers[id] = parsed;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return { servers, failures };
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* (3.7) Parses the optional `auth` block on an HTTP MCP server config.
|
|
97
|
+
* Returns `{auth: undefined}` when absent. Validation is intentionally
|
|
98
|
+
* defensive — config can come from `.chances/config.json` typed by a user.
|
|
99
|
+
*/
|
|
100
|
+
function parseOAuthAuth(raw) {
|
|
101
|
+
if (raw === undefined || raw === null)
|
|
102
|
+
return { auth: undefined };
|
|
103
|
+
if (typeof raw !== "object" || Array.isArray(raw)) {
|
|
104
|
+
return { error: "http mcp server: 'auth' must be an object" };
|
|
105
|
+
}
|
|
106
|
+
const o = raw;
|
|
107
|
+
if (o["kind"] !== "oauth") {
|
|
108
|
+
return { error: `http mcp server: 'auth.kind' must be 'oauth' (got ${JSON.stringify(o["kind"])})` };
|
|
109
|
+
}
|
|
110
|
+
if (o["authServerMetadataUrl"] !== undefined) {
|
|
111
|
+
// (codex Round-2 SHOULD-FIX #1) The field is parsed + validated but
|
|
112
|
+
// not yet threaded into SDK auth() — the SDK doesn't expose a clean
|
|
113
|
+
// override path for protected-resource-metadata short-circuiting in
|
|
114
|
+
// v1.29.0. We continue to validate so users get a clear error if
|
|
115
|
+
// they typo the URL, and we'll wire the override in 3.7.1 (or
|
|
116
|
+
// remove the field entirely if the SDK still doesn't surface a hook).
|
|
117
|
+
if (typeof o["authServerMetadataUrl"] !== "string") {
|
|
118
|
+
return { error: "http mcp server: 'auth.authServerMetadataUrl' must be a string" };
|
|
119
|
+
}
|
|
120
|
+
let u;
|
|
121
|
+
try {
|
|
122
|
+
u = new URL(o["authServerMetadataUrl"]);
|
|
123
|
+
}
|
|
124
|
+
catch {
|
|
125
|
+
return { error: "http mcp server: 'auth.authServerMetadataUrl' must be a valid URL" };
|
|
126
|
+
}
|
|
127
|
+
if (u.protocol !== "https:") {
|
|
128
|
+
return { error: "http mcp server: 'auth.authServerMetadataUrl' must use https:// (protects discovery from MITM)" };
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
if (o["clientId"] !== undefined && typeof o["clientId"] !== "string") {
|
|
132
|
+
return { error: "http mcp server: 'auth.clientId' must be a string" };
|
|
133
|
+
}
|
|
134
|
+
if (o["clientSecret"] !== undefined && typeof o["clientSecret"] !== "string") {
|
|
135
|
+
return { error: "http mcp server: 'auth.clientSecret' must be a string" };
|
|
136
|
+
}
|
|
137
|
+
if (o["scopes"] !== undefined) {
|
|
138
|
+
if (!Array.isArray(o["scopes"]) || !o["scopes"].every((s) => typeof s === "string")) {
|
|
139
|
+
return { error: "http mcp server: 'auth.scopes' must be an array of strings" };
|
|
140
|
+
}
|
|
141
|
+
if (o["scopes"].length > 32) {
|
|
142
|
+
return { error: "http mcp server: 'auth.scopes' is limited to 32 entries" };
|
|
143
|
+
}
|
|
144
|
+
if (o["scopes"].some((s) => s.length > 256)) {
|
|
145
|
+
return { error: "http mcp server: each entry in 'auth.scopes' must be ≤ 256 characters" };
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
if (o["callbackPort"] !== undefined) {
|
|
149
|
+
if (typeof o["callbackPort"] !== "number" ||
|
|
150
|
+
!Number.isInteger(o["callbackPort"]) ||
|
|
151
|
+
o["callbackPort"] < 1024 ||
|
|
152
|
+
o["callbackPort"] > 65535) {
|
|
153
|
+
return { error: "http mcp server: 'auth.callbackPort' must be an integer in [1024, 65535]" };
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
return {
|
|
157
|
+
auth: {
|
|
158
|
+
kind: "oauth",
|
|
159
|
+
authServerMetadataUrl: o["authServerMetadataUrl"],
|
|
160
|
+
clientId: o["clientId"],
|
|
161
|
+
clientSecret: o["clientSecret"],
|
|
162
|
+
scopes: o["scopes"],
|
|
163
|
+
callbackPort: o["callbackPort"],
|
|
164
|
+
},
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* (3.7 codex Round-1 MUST-FIX #7) RFC 6750 §5.2 requires that bearer
|
|
169
|
+
* tokens never travel in cleartext. When OAuth is configured, the MCP
|
|
170
|
+
* server URL must be `https://` UNLESS it points to a loopback address
|
|
171
|
+
* (local-dev exception per RFC 8252 §7.3 spirit). Returns an error
|
|
172
|
+
* message string when the URL fails the check; undefined when it's OK.
|
|
173
|
+
*/
|
|
174
|
+
function validateOAuthResourceUrl(urlStr) {
|
|
175
|
+
let url;
|
|
176
|
+
try {
|
|
177
|
+
url = new URL(urlStr);
|
|
178
|
+
}
|
|
179
|
+
catch {
|
|
180
|
+
return "http mcp server: 'url' must be a valid URL when OAuth is configured";
|
|
181
|
+
}
|
|
182
|
+
if (url.protocol === "https:")
|
|
183
|
+
return undefined;
|
|
184
|
+
if (url.protocol !== "http:") {
|
|
185
|
+
return `http mcp server: OAuth requires https:// (got ${url.protocol})`;
|
|
186
|
+
}
|
|
187
|
+
// http:// — only loopback is allowed.
|
|
188
|
+
const host = url.hostname.toLowerCase().replace(/\.+$/, "");
|
|
189
|
+
if (host === "127.0.0.1" || host === "localhost" || host === "[::1]" || host === "::1")
|
|
190
|
+
return undefined;
|
|
191
|
+
return ("http mcp server: OAuth requires https:// for the resource server URL " +
|
|
192
|
+
"(bearer tokens travel in cleartext otherwise; RFC 6750 §5.2). " +
|
|
193
|
+
"Add TLS, or use a loopback address (127.0.0.1 / [::1] / localhost) for local dev.");
|
|
194
|
+
}
|
|
195
|
+
function isStringArray(v) {
|
|
196
|
+
return Array.isArray(v) && v.every((x) => typeof x === "string");
|
|
197
|
+
}
|
|
198
|
+
function isStringRecord(v) {
|
|
199
|
+
if (!v || typeof v !== "object" || Array.isArray(v))
|
|
200
|
+
return false;
|
|
201
|
+
return Object.values(v).every((x) => typeof x === "string");
|
|
202
|
+
}
|
|
203
|
+
function optBool(v) {
|
|
204
|
+
return typeof v === "boolean" ? v : undefined;
|
|
205
|
+
}
|
|
206
|
+
function optPositiveInt(v) {
|
|
207
|
+
return typeof v === "number" && Number.isInteger(v) && v > 0 ? v : undefined;
|
|
208
|
+
}
|
|
209
|
+
//# sourceMappingURL=parse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse.js","sourceRoot":"","sources":["../../src/mcp/parse.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { McpPromptArgument, McpPromptMessage } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* (5.4 D2) Parse slash-command tokens into a `prompts/get` argument map.
|
|
4
|
+
*
|
|
5
|
+
* - **No declared args** → `{}` (surplus tokens ignored).
|
|
6
|
+
* - **Named mode** — iff EVERY token is `key=value` (key a valid identifier)
|
|
7
|
+
* AND every key is a declared arg name → `{key: value}`.
|
|
8
|
+
* - **Positional mode** (default) — zip tokens to declared names in order;
|
|
9
|
+
* surplus tokens space-rejoin into the LAST arg (so a free-text trailing
|
|
10
|
+
* arg works: `/srv:summarize the whole file`).
|
|
11
|
+
* - Missing **required** args → `{ ok: false, error }` with a usage hint; the
|
|
12
|
+
* caller surfaces it and does NOT fire a model turn.
|
|
13
|
+
*/
|
|
14
|
+
export declare function parsePromptArgs(declared: McpPromptArgument[] | undefined, tokens: string[]): {
|
|
15
|
+
ok: true;
|
|
16
|
+
args: Record<string, string>;
|
|
17
|
+
} | {
|
|
18
|
+
ok: false;
|
|
19
|
+
error: string;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* (5.4) Render `prompts/get` messages into a single user-turn string. Most MCP
|
|
23
|
+
* prompts return one user message; multi-message prompts are flattened (assistant
|
|
24
|
+
* messages prefixed `[assistant]`). Each message's `content` is a single MCP
|
|
25
|
+
* content part per spec, but we tolerate an array too. Text-first via
|
|
26
|
+
* `renderMcpContentParts` (strip + redact). Returns "" when nothing renders.
|
|
27
|
+
*/
|
|
28
|
+
export declare function renderPromptMessages(messages: McpPromptMessage[], opts?: {
|
|
29
|
+
redact?: (msg: string) => string;
|
|
30
|
+
}): string;
|
|
31
|
+
//# sourceMappingURL=prompts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../src/mcp/prompts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAGtE;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,iBAAiB,EAAE,GAAG,SAAS,EACzC,MAAM,EAAE,MAAM,EAAE,GACf;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAoC3E;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,gBAAgB,EAAE,EAC5B,IAAI,GAAE;IAAE,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAA;CAAO,GAC9C,MAAM,CAWR"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { renderMcpContentParts } from "./content.js";
|
|
2
|
+
/**
|
|
3
|
+
* (5.4 D2) Parse slash-command tokens into a `prompts/get` argument map.
|
|
4
|
+
*
|
|
5
|
+
* - **No declared args** → `{}` (surplus tokens ignored).
|
|
6
|
+
* - **Named mode** — iff EVERY token is `key=value` (key a valid identifier)
|
|
7
|
+
* AND every key is a declared arg name → `{key: value}`.
|
|
8
|
+
* - **Positional mode** (default) — zip tokens to declared names in order;
|
|
9
|
+
* surplus tokens space-rejoin into the LAST arg (so a free-text trailing
|
|
10
|
+
* arg works: `/srv:summarize the whole file`).
|
|
11
|
+
* - Missing **required** args → `{ ok: false, error }` with a usage hint; the
|
|
12
|
+
* caller surfaces it and does NOT fire a model turn.
|
|
13
|
+
*/
|
|
14
|
+
export function parsePromptArgs(declared, tokens) {
|
|
15
|
+
const decl = declared ?? [];
|
|
16
|
+
if (decl.length === 0)
|
|
17
|
+
return { ok: true, args: {} };
|
|
18
|
+
const names = decl.map((a) => a.name);
|
|
19
|
+
const nameSet = new Set(names);
|
|
20
|
+
const args = {};
|
|
21
|
+
const looksNamed = tokens.length > 0 && tokens.every((t) => /^[A-Za-z_][\w-]*=/.test(t));
|
|
22
|
+
const allKeysKnown = looksNamed && tokens.every((t) => nameSet.has(t.slice(0, t.indexOf("="))));
|
|
23
|
+
if (looksNamed && allKeysKnown) {
|
|
24
|
+
for (const t of tokens) {
|
|
25
|
+
const eq = t.indexOf("=");
|
|
26
|
+
args[t.slice(0, eq)] = t.slice(eq + 1);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
// Positional: zip; the surplus joins into the last declared arg.
|
|
31
|
+
for (let i = 0; i < names.length; i++) {
|
|
32
|
+
const name = names[i];
|
|
33
|
+
if (i < names.length - 1) {
|
|
34
|
+
if (tokens[i] !== undefined)
|
|
35
|
+
args[name] = tokens[i];
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
const rest = tokens.slice(i);
|
|
39
|
+
if (rest.length > 0)
|
|
40
|
+
args[name] = rest.join(" ");
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
const missing = decl.filter((a) => a.required && !args[a.name]).map((a) => a.name);
|
|
45
|
+
if (missing.length > 0) {
|
|
46
|
+
const usage = decl.map((a) => (a.required ? `<${a.name}>` : `[${a.name}]`)).join(" ");
|
|
47
|
+
return { ok: false, error: `missing required argument(s): ${missing.join(", ")} — usage: ${usage}` };
|
|
48
|
+
}
|
|
49
|
+
return { ok: true, args };
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* (5.4) Render `prompts/get` messages into a single user-turn string. Most MCP
|
|
53
|
+
* prompts return one user message; multi-message prompts are flattened (assistant
|
|
54
|
+
* messages prefixed `[assistant]`). Each message's `content` is a single MCP
|
|
55
|
+
* content part per spec, but we tolerate an array too. Text-first via
|
|
56
|
+
* `renderMcpContentParts` (strip + redact). Returns "" when nothing renders.
|
|
57
|
+
*/
|
|
58
|
+
export function renderPromptMessages(messages, opts = {}) {
|
|
59
|
+
const blocks = [];
|
|
60
|
+
for (const m of messages) {
|
|
61
|
+
const parts = Array.isArray(m.content)
|
|
62
|
+
? m.content
|
|
63
|
+
: [m.content];
|
|
64
|
+
const text = renderMcpContentParts(parts, opts);
|
|
65
|
+
if (!text)
|
|
66
|
+
continue;
|
|
67
|
+
blocks.push(m.role === "assistant" ? `[assistant]\n${text}` : text);
|
|
68
|
+
}
|
|
69
|
+
return blocks.join("\n\n");
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=prompts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../src/mcp/prompts.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scrubs sensitive substrings from a string. Used by the MCP client/host to
|
|
3
|
+
* sanitize errors before they hit the bus, the logger, transcript plugins,
|
|
4
|
+
* or `/mcp test` output. Mirrors the redactor pattern in
|
|
5
|
+
* `packages/ai/src/adapters/ai-sdk.ts` — when an HTTP transport throws with
|
|
6
|
+
* a bearer token or env-var value in the message (some servers echo
|
|
7
|
+
* `Authorization` headers in 4xx bodies), the original string must never
|
|
8
|
+
* reach the user-facing channels.
|
|
9
|
+
*
|
|
10
|
+
* Short secrets (< 8 chars) are not redacted — too many false positives on
|
|
11
|
+
* innocuous substrings, and a token of 8+ chars is the practical floor for
|
|
12
|
+
* anything worth protecting.
|
|
13
|
+
*
|
|
14
|
+
* (3.7) The returned callable carries a mutable `.add(secrets)` method so
|
|
15
|
+
* OAuth tokens / refresh tokens / PKCE verifiers discovered at runtime can
|
|
16
|
+
* join the scrub set on save WITHOUT having to rebuild the redactor (which
|
|
17
|
+
* would invalidate the reference held by every already-wired callsite).
|
|
18
|
+
* Strings shorter than 8 chars are silently ignored — same floor as the
|
|
19
|
+
* constructor.
|
|
20
|
+
*/
|
|
21
|
+
export interface RuntimeRedactor {
|
|
22
|
+
(msg: string): string;
|
|
23
|
+
/** Extend the scrub set in place. Re-sorts longest-first lazily so a new
|
|
24
|
+
* short secret doesn't clobber an existing long-prefix scrub on the
|
|
25
|
+
* next call. */
|
|
26
|
+
add(secrets: readonly string[]): void;
|
|
27
|
+
}
|
|
28
|
+
export declare function buildRedactor(secrets: ReadonlyArray<string | undefined>): RuntimeRedactor;
|
|
29
|
+
/**
|
|
30
|
+
* Collects every substring that should be considered a secret for one
|
|
31
|
+
* server's lifetime: header values, URL userinfo, URL query values, and
|
|
32
|
+
* env-var values from a stdio launch. Used by `McpHost` when wiring each
|
|
33
|
+
* `McpClient`.
|
|
34
|
+
*
|
|
35
|
+
* Defense-in-depth: the *raw URL* is always added too, even when it parses
|
|
36
|
+
* cleanly. A malformed-URL error (`new URL("https://x?token=secret bad")`
|
|
37
|
+
* throwing) would otherwise echo the full URL with embedded secrets into
|
|
38
|
+
* logs while the parsed query-value bag is empty. Adding the raw URL means
|
|
39
|
+
* any string-replace pass scrubs it wholesale; the cost is that the user's
|
|
40
|
+
* own URL shows up as `[REDACTED]` in errors, which is acceptable for a
|
|
41
|
+
* defense layer (the user can read their config to see the URL).
|
|
42
|
+
*/
|
|
43
|
+
export declare function collectSecrets(input: {
|
|
44
|
+
env?: Record<string, string>;
|
|
45
|
+
headers?: Record<string, string>;
|
|
46
|
+
url?: string;
|
|
47
|
+
}): string[];
|
|
48
|
+
/**
|
|
49
|
+
* Removes ANSI / OSC / other CSI control sequences from MCP-rendered text
|
|
50
|
+
* before it reaches the bus / TUI / transcript. A malicious server (or a
|
|
51
|
+
* carelessly-pasted shell output from a benign one) can otherwise emit
|
|
52
|
+
* cursor moves, clipboard hijacks (OSC 52), or terminal-title escapes that
|
|
53
|
+
* affect the host terminal.
|
|
54
|
+
*
|
|
55
|
+
* (5.7) Now the shared **conservative** variant from `@chances-ai/runtime`
|
|
56
|
+
* (`text-sanitize.ts`): only `ESC [ … letter` (CSI), `ESC ] … BEL|ST` (OSC),
|
|
57
|
+
* and `ESC @`..`ESC _` — deliberately NOT every non-printable byte, because
|
|
58
|
+
* MCP tools legitimately return tabs / newlines / form-feed in code snippets.
|
|
59
|
+
* Kept distinct from the model-output `stripAnsi` for exactly that reason.
|
|
60
|
+
*/
|
|
61
|
+
export { stripTerminalControls } from "@chances-ai/runtime";
|
|
62
|
+
//# sourceMappingURL=redact.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redact.d.ts","sourceRoot":"","sources":["../../src/mcp/redact.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,WAAW,eAAe;IAC9B,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB;;qBAEiB;IACjB,GAAG,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAAC;CACvC;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,aAAa,CAAC,MAAM,GAAG,SAAS,CAAC,GAAG,eAAe,CA4BzF;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE;IACpC,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,GAAG,MAAM,EAAE,CAkBX;AAED;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
export function buildRedactor(secrets) {
|
|
2
|
+
// Mutable set — the closure below sees changes from `.add()`.
|
|
3
|
+
const set = new Set();
|
|
4
|
+
for (const s of secrets) {
|
|
5
|
+
if (typeof s === "string" && s.length >= 8)
|
|
6
|
+
set.add(s);
|
|
7
|
+
}
|
|
8
|
+
// Lazy-sorted scrub list — invalidated whenever `set` mutates.
|
|
9
|
+
let sorted = undefined;
|
|
10
|
+
const fn = ((msg) => {
|
|
11
|
+
if (set.size === 0)
|
|
12
|
+
return msg;
|
|
13
|
+
if (!sorted)
|
|
14
|
+
sorted = [...set].sort((a, b) => b.length - a.length);
|
|
15
|
+
let out = msg;
|
|
16
|
+
for (const s of sorted) {
|
|
17
|
+
out = out.split(s).join("[REDACTED]");
|
|
18
|
+
}
|
|
19
|
+
return out;
|
|
20
|
+
});
|
|
21
|
+
fn.add = (more) => {
|
|
22
|
+
let mutated = false;
|
|
23
|
+
for (const s of more) {
|
|
24
|
+
if (typeof s === "string" && s.length >= 8 && !set.has(s)) {
|
|
25
|
+
set.add(s);
|
|
26
|
+
mutated = true;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
if (mutated)
|
|
30
|
+
sorted = undefined;
|
|
31
|
+
};
|
|
32
|
+
return fn;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Collects every substring that should be considered a secret for one
|
|
36
|
+
* server's lifetime: header values, URL userinfo, URL query values, and
|
|
37
|
+
* env-var values from a stdio launch. Used by `McpHost` when wiring each
|
|
38
|
+
* `McpClient`.
|
|
39
|
+
*
|
|
40
|
+
* Defense-in-depth: the *raw URL* is always added too, even when it parses
|
|
41
|
+
* cleanly. A malformed-URL error (`new URL("https://x?token=secret bad")`
|
|
42
|
+
* throwing) would otherwise echo the full URL with embedded secrets into
|
|
43
|
+
* logs while the parsed query-value bag is empty. Adding the raw URL means
|
|
44
|
+
* any string-replace pass scrubs it wholesale; the cost is that the user's
|
|
45
|
+
* own URL shows up as `[REDACTED]` in errors, which is acceptable for a
|
|
46
|
+
* defense layer (the user can read their config to see the URL).
|
|
47
|
+
*/
|
|
48
|
+
export function collectSecrets(input) {
|
|
49
|
+
const out = [];
|
|
50
|
+
for (const v of Object.values(input.env ?? {}))
|
|
51
|
+
out.push(v);
|
|
52
|
+
for (const v of Object.values(input.headers ?? {}))
|
|
53
|
+
out.push(v);
|
|
54
|
+
if (input.url) {
|
|
55
|
+
// Always include the raw URL so even an unparseable URL gets scrubbed
|
|
56
|
+
// out of error messages that quote it back.
|
|
57
|
+
out.push(input.url);
|
|
58
|
+
try {
|
|
59
|
+
const u = new URL(input.url);
|
|
60
|
+
if (u.username)
|
|
61
|
+
out.push(u.username);
|
|
62
|
+
if (u.password)
|
|
63
|
+
out.push(u.password);
|
|
64
|
+
for (const [, v] of u.searchParams)
|
|
65
|
+
out.push(v);
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
// The raw URL above is the fallback when parsing fails.
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return out;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Removes ANSI / OSC / other CSI control sequences from MCP-rendered text
|
|
75
|
+
* before it reaches the bus / TUI / transcript. A malicious server (or a
|
|
76
|
+
* carelessly-pasted shell output from a benign one) can otherwise emit
|
|
77
|
+
* cursor moves, clipboard hijacks (OSC 52), or terminal-title escapes that
|
|
78
|
+
* affect the host terminal.
|
|
79
|
+
*
|
|
80
|
+
* (5.7) Now the shared **conservative** variant from `@chances-ai/runtime`
|
|
81
|
+
* (`text-sanitize.ts`): only `ESC [ … letter` (CSI), `ESC ] … BEL|ST` (OSC),
|
|
82
|
+
* and `ESC @`..`ESC _` — deliberately NOT every non-printable byte, because
|
|
83
|
+
* MCP tools legitimately return tabs / newlines / form-feed in code snippets.
|
|
84
|
+
* Kept distinct from the model-output `stripAnsi` for exactly that reason.
|
|
85
|
+
*/
|
|
86
|
+
export { stripTerminalControls } from "@chances-ai/runtime";
|
|
87
|
+
//# sourceMappingURL=redact.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redact.js","sourceRoot":"","sources":["../../src/mcp/redact.ts"],"names":[],"mappings":"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"}
|