@bastani/atomic 0.9.5-alpha.9 → 0.9.5
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 +106 -0
- package/README.md +2 -2
- package/dist/builtin/cursor/CHANGELOG.md +12 -0
- package/dist/builtin/cursor/package.json +3 -3
- package/dist/builtin/cursor/src/model-mapper.ts +6 -3
- package/dist/builtin/intercom/CHANGELOG.md +37 -0
- package/dist/builtin/intercom/README.md +4 -2
- package/dist/builtin/intercom/broker/broker.ts +6 -114
- package/dist/builtin/intercom/broker/client.ts +29 -54
- package/dist/builtin/intercom/broker/delivered-message-cache.ts +44 -0
- package/dist/builtin/intercom/broker/pending-send-registry.ts +142 -0
- package/dist/builtin/intercom/broker/send-handler.ts +106 -0
- package/dist/builtin/intercom/broker/send-signature.ts +37 -0
- package/dist/builtin/intercom/foreground-detach-handoff.ts +136 -0
- package/dist/builtin/intercom/index-heavy.ts +49 -53
- package/dist/builtin/intercom/index.ts +278 -262
- package/dist/builtin/intercom/lazy-heavy-proxy.ts +114 -0
- package/dist/builtin/intercom/lazy-subagent-ack.ts +20 -0
- package/dist/builtin/intercom/lazy-tool-execution.ts +39 -0
- package/dist/builtin/intercom/lifecycle-lease.ts +51 -0
- package/dist/builtin/intercom/lifecycle.ts +37 -20
- package/dist/builtin/intercom/package.json +3 -6
- package/dist/builtin/intercom/reply-routing.ts +17 -0
- package/dist/builtin/intercom/subagent-relay.ts +58 -12
- package/dist/builtin/intercom/types.ts +3 -3
- package/dist/builtin/mcp/CHANGELOG.md +27 -0
- package/dist/builtin/mcp/OAUTH.md +1 -0
- package/dist/builtin/mcp/README.md +4 -0
- package/dist/builtin/mcp/apps-cancellation.ts +32 -0
- package/dist/builtin/mcp/call-tool-result.ts +9 -0
- package/dist/builtin/mcp/caller-wait.ts +50 -0
- package/dist/builtin/mcp/command-registration.ts +82 -0
- package/dist/builtin/mcp/direct-tool-executor.ts +279 -0
- package/dist/builtin/mcp/direct-tools.ts +6 -239
- package/dist/builtin/mcp/host-html-template.ts +4 -2
- package/dist/builtin/mcp/index.ts +258 -250
- package/dist/builtin/mcp/init.ts +96 -87
- package/dist/builtin/mcp/mcp-auth-flow.ts +247 -237
- package/dist/builtin/mcp/mcp-callback-server.ts +89 -68
- package/dist/builtin/mcp/mcp-oauth-provider.ts +23 -1
- package/dist/builtin/mcp/metadata-hydration.ts +21 -6
- package/dist/builtin/mcp/package.json +3 -3
- package/dist/builtin/mcp/proxy-auth.ts +4 -4
- package/dist/builtin/mcp/proxy-call.ts +111 -40
- package/dist/builtin/mcp/proxy-connect.ts +35 -15
- package/dist/builtin/mcp/proxy-info-modes.ts +49 -19
- package/dist/builtin/mcp/proxy-modes.ts +3 -3
- package/dist/builtin/mcp/session-cleanup-barrier.ts +43 -0
- package/dist/builtin/mcp/state-lease.ts +12 -0
- package/dist/builtin/mcp/ui-server.ts +8 -8
- package/dist/builtin/mcp/ui-session.ts +9 -18
- package/dist/builtin/subagents/CHANGELOG.md +66 -0
- package/dist/builtin/subagents/README.md +30 -29
- package/dist/builtin/subagents/agents/code-simplifier.md +2 -2
- package/dist/builtin/subagents/agents/codebase-analyzer.md +2 -2
- package/dist/builtin/subagents/agents/codebase-locator.md +2 -2
- package/dist/builtin/subagents/agents/codebase-online-researcher.md +2 -2
- package/dist/builtin/subagents/agents/codebase-pattern-finder.md +2 -2
- package/dist/builtin/subagents/agents/codebase-research-analyzer.md +2 -2
- package/dist/builtin/subagents/agents/codebase-research-locator.md +2 -2
- package/dist/builtin/subagents/agents/debugger.md +2 -2
- package/dist/builtin/subagents/agents/worker.md +2 -2
- package/dist/builtin/subagents/package.json +5 -5
- package/dist/builtin/subagents/prompts/review-loop.md +1 -1
- package/dist/builtin/subagents/skills/subagent/SKILL.md +37 -36
- package/dist/builtin/subagents/src/extension/api-lifecycle.ts +64 -0
- package/dist/builtin/subagents/src/extension/fanout-child.ts +44 -51
- package/dist/builtin/subagents/src/extension/index.ts +287 -307
- package/dist/builtin/subagents/src/extension/prompt-guidance.ts +7 -10
- package/dist/builtin/subagents/src/extension/schemas.ts +22 -5
- package/dist/builtin/subagents/src/extension/tool-description.ts +29 -0
- package/dist/builtin/subagents/src/intercom/intercom-bridge.ts +13 -2
- package/dist/builtin/subagents/src/intercom/result-intercom.ts +4 -4
- package/dist/builtin/subagents/src/runs/background/async-event-journal.ts +106 -0
- package/dist/builtin/subagents/src/runs/background/async-execution-common.ts +3 -2
- package/dist/builtin/subagents/src/runs/background/async-execution-single.ts +13 -2
- package/dist/builtin/subagents/src/runs/background/async-execution-types.ts +3 -0
- package/dist/builtin/subagents/src/runs/background/async-job-tracker.ts +1 -1
- package/dist/builtin/subagents/src/runs/background/completion-claims.ts +189 -0
- package/dist/builtin/subagents/src/runs/background/completion-dedupe.ts +44 -7
- package/dist/builtin/subagents/src/runs/background/completion-notification.ts +34 -0
- package/dist/builtin/subagents/src/runs/background/notify.ts +72 -22
- package/dist/builtin/subagents/src/runs/background/result-delivery-processor.ts +232 -0
- package/dist/builtin/subagents/src/runs/background/result-file-claims.ts +151 -0
- package/dist/builtin/subagents/src/runs/background/result-quarantine.ts +72 -0
- package/dist/builtin/subagents/src/runs/background/result-retry-scheduler.ts +48 -0
- package/dist/builtin/subagents/src/runs/background/result-status.ts +81 -0
- package/dist/builtin/subagents/src/runs/background/result-watcher-data.ts +59 -0
- package/dist/builtin/subagents/src/runs/background/result-watcher.ts +172 -238
- package/dist/builtin/subagents/src/runs/background/run-id-resolver.ts +3 -2
- package/dist/builtin/subagents/src/runs/background/stale-run-reconciler.ts +73 -14
- package/dist/builtin/subagents/src/runs/background/subagent-runner-streaming.ts +17 -13
- package/dist/builtin/subagents/src/runs/background/top-level-async.ts +1 -2
- package/dist/builtin/subagents/src/runs/foreground/chain-execution-dynamic-step.ts +1 -0
- package/dist/builtin/subagents/src/runs/foreground/chain-execution-parallel-runner.ts +1 -0
- package/dist/builtin/subagents/src/runs/foreground/chain-execution-parallel-step.ts +1 -0
- package/dist/builtin/subagents/src/runs/foreground/chain-execution-sequential-step.ts +7 -9
- package/dist/builtin/subagents/src/runs/foreground/chain-execution-types.ts +3 -13
- package/dist/builtin/subagents/src/runs/foreground/chain-execution.ts +2 -15
- package/dist/builtin/subagents/src/runs/foreground/execution-attempt-finalize.ts +2 -2
- package/dist/builtin/subagents/src/runs/foreground/execution-attempt.ts +53 -44
- package/dist/builtin/subagents/src/runs/foreground/execution-detach-reservations.ts +48 -0
- package/dist/builtin/subagents/src/runs/foreground/execution-detach-route.ts +17 -0
- package/dist/builtin/subagents/src/runs/foreground/execution-run-sync.ts +39 -26
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-async.ts +3 -1
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-chain.ts +3 -51
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-context.ts +6 -11
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-input.ts +11 -2
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-parallel-task.ts +2 -0
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-parallel.ts +5 -112
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-resume.ts +2 -0
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-single.ts +68 -118
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-status.ts +79 -7
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-types.ts +2 -2
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor.ts +3 -0
- package/dist/builtin/subagents/src/runs/shared/pi-args.ts +2 -2
- package/dist/builtin/subagents/src/runs/shared/pi-spawn.ts +27 -11
- package/dist/builtin/subagents/src/shared/artifacts.ts +22 -11
- package/dist/builtin/subagents/src/shared/event-jsonl-writer.ts +294 -0
- package/dist/builtin/subagents/src/shared/exclusive-file-publication.ts +44 -0
- package/dist/builtin/subagents/src/shared/jsonl-writer.ts +1 -0
- package/dist/builtin/subagents/src/shared/model-info.ts +2 -2
- package/dist/builtin/subagents/src/shared/settings.ts +20 -10
- package/dist/builtin/subagents/src/shared/types-async.ts +3 -1
- package/dist/builtin/subagents/src/shared/types-config.ts +2 -0
- package/dist/builtin/subagents/src/shared/types-runtime.ts +3 -2
- package/dist/builtin/subagents/src/slash/slash-commands.ts +9 -12
- package/dist/builtin/subagents/src/slash/slash-live-state.ts +63 -32
- package/dist/builtin/subagents/src/tui/render-result.ts +7 -0
- package/dist/builtin/subagents/src/tui/render-stable-output.ts +1 -0
- package/dist/builtin/subagents/src/tui/render-widget.ts +128 -89
- package/dist/builtin/web-access/CHANGELOG.md +28 -0
- package/dist/builtin/web-access/README.md +4 -0
- package/dist/builtin/web-access/content-tools.ts +8 -3
- package/dist/builtin/web-access/index-heavy.ts +1 -1
- package/dist/builtin/web-access/index.ts +190 -46
- package/dist/builtin/web-access/lifecycle-lease.ts +38 -0
- package/dist/builtin/web-access/package.json +2 -2
- package/dist/builtin/web-access/result-renderers.ts +1 -1
- package/dist/builtin/web-access/summary-review.ts +1 -1
- package/dist/builtin/web-access/web-search-activity.ts +1 -1
- package/dist/builtin/web-access/web-search-return.ts +7 -0
- package/dist/builtin/web-access/web-search-summary.ts +1 -1
- package/dist/builtin/web-access/web-search-tool.ts +4 -2
- package/dist/builtin/workflows/CHANGELOG.md +68 -0
- package/dist/builtin/workflows/README.md +4 -4
- package/dist/builtin/workflows/builtin/deep-research-codebase-utils.ts +27 -4
- package/dist/builtin/workflows/builtin/goal-runner.ts +47 -26
- package/dist/builtin/workflows/builtin/open-claude-design-runner.ts +10 -0
- package/dist/builtin/workflows/builtin/ralph-core.ts +9 -9
- package/dist/builtin/workflows/builtin/ralph-models.ts +71 -36
- package/dist/builtin/workflows/builtin/ralph-runner.ts +20 -31
- package/dist/builtin/workflows/package.json +2 -2
- package/dist/builtin/workflows/src/durable/stage-primitive.ts +2 -1
- package/dist/builtin/workflows/src/engine/primitives/task.ts +2 -1
- package/dist/builtin/workflows/src/extension/workflow-prompts.ts +17 -22
- package/dist/builtin/workflows/src/extension/workflow-schema.ts +15 -2
- package/dist/builtin/workflows/src/runs/foreground/executor-hil.ts +1 -2
- package/dist/builtin/workflows/src/runs/shared/model-fallback-candidates.ts +1 -1
- package/dist/builtin/workflows/src/shared/authoring-contract-stage.d.ts +2 -2
- package/dist/builtin/workflows/src/shared/authoring-contract-stage.ts +2 -2
- package/dist/builtin/workflows/src/shared/resume-continuation.ts +2 -0
- package/dist/builtin/workflows/src/tui/stage-chat-view-archive-history.ts +1 -23
- package/dist/builtin/workflows/src/tui/stage-chat-view-footer-status.ts +54 -9
- package/dist/builtin/workflows/src/tui/stage-chat-view.ts +5 -2
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +2 -2
- package/dist/cli/args.js.map +1 -1
- package/dist/core/agent-session-events.d.ts.map +1 -1
- package/dist/core/agent-session-events.js +2 -1
- package/dist/core/agent-session-events.js.map +1 -1
- package/dist/core/agent-session-message-queue.d.ts.map +1 -1
- package/dist/core/agent-session-message-queue.js +1 -1
- package/dist/core/agent-session-message-queue.js.map +1 -1
- package/dist/core/agent-session-prompt.d.ts.map +1 -1
- package/dist/core/agent-session-prompt.js +1 -1
- package/dist/core/agent-session-prompt.js.map +1 -1
- package/dist/core/agent-session-retry.d.ts.map +1 -1
- package/dist/core/agent-session-retry.js +1 -1
- package/dist/core/agent-session-retry.js.map +1 -1
- package/dist/core/agent-session-services.d.ts.map +1 -1
- package/dist/core/agent-session-services.js +3 -2
- package/dist/core/agent-session-services.js.map +1 -1
- package/dist/core/agent-session-types.d.ts.map +1 -1
- package/dist/core/agent-session-types.js +1 -1
- package/dist/core/agent-session-types.js.map +1 -1
- package/dist/core/anthropic-thinking-guard.d.ts +5 -5
- package/dist/core/anthropic-thinking-guard.d.ts.map +1 -1
- package/dist/core/anthropic-thinking-guard.js +42 -32
- package/dist/core/anthropic-thinking-guard.js.map +1 -1
- package/dist/core/atomic-guide-command.d.ts.map +1 -1
- package/dist/core/atomic-guide-command.js +15 -15
- package/dist/core/atomic-guide-command.js.map +1 -1
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +14 -9
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts +2 -0
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +79 -46
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/compaction/context-assistant-turns.d.ts +42 -0
- package/dist/core/compaction/context-assistant-turns.d.ts.map +1 -0
- package/dist/core/compaction/context-assistant-turns.js +87 -0
- package/dist/core/compaction/context-assistant-turns.js.map +1 -0
- package/dist/core/compaction/context-compaction-critical.d.ts +1 -1
- package/dist/core/compaction/context-compaction-critical.d.ts.map +1 -1
- package/dist/core/compaction/context-compaction-critical.js +2 -2
- package/dist/core/compaction/context-compaction-critical.js.map +1 -1
- package/dist/core/compaction/context-compaction-eviction-alternates.d.ts +18 -0
- package/dist/core/compaction/context-compaction-eviction-alternates.d.ts.map +1 -0
- package/dist/core/compaction/context-compaction-eviction-alternates.js +186 -0
- package/dist/core/compaction/context-compaction-eviction-alternates.js.map +1 -0
- package/dist/core/compaction/context-compaction-eviction.d.ts +10 -2
- package/dist/core/compaction/context-compaction-eviction.d.ts.map +1 -1
- package/dist/core/compaction/context-compaction-eviction.js +196 -146
- package/dist/core/compaction/context-compaction-eviction.js.map +1 -1
- package/dist/core/compaction/context-compaction-prompt.d.ts.map +1 -1
- package/dist/core/compaction/context-compaction-prompt.js +1 -1
- package/dist/core/compaction/context-compaction-prompt.js.map +1 -1
- package/dist/core/compaction/context-compaction-types.d.ts +2 -0
- package/dist/core/compaction/context-compaction-types.d.ts.map +1 -1
- package/dist/core/compaction/context-compaction-types.js.map +1 -1
- package/dist/core/compaction/context-deletion-application.d.ts +5 -4
- package/dist/core/compaction/context-deletion-application.d.ts.map +1 -1
- package/dist/core/compaction/context-deletion-application.js +17 -15
- package/dist/core/compaction/context-deletion-application.js.map +1 -1
- package/dist/core/compaction/context-deletion-store.d.ts.map +1 -1
- package/dist/core/compaction/context-deletion-store.js +1 -1
- package/dist/core/compaction/context-deletion-store.js.map +1 -1
- package/dist/core/compaction/context-deletion-targets.d.ts +2 -1
- package/dist/core/compaction/context-deletion-targets.d.ts.map +1 -1
- package/dist/core/compaction/context-deletion-targets.js +36 -31
- package/dist/core/compaction/context-deletion-targets.js.map +1 -1
- package/dist/core/compaction/context-deletion-tool-helpers.d.ts.map +1 -1
- package/dist/core/compaction/context-deletion-tool-helpers.js +116 -43
- package/dist/core/compaction/context-deletion-tool-helpers.js.map +1 -1
- package/dist/core/compaction/context-transcript-analysis.d.ts +1 -2
- package/dist/core/compaction/context-transcript-analysis.d.ts.map +1 -1
- package/dist/core/compaction/context-transcript-analysis.js +33 -37
- package/dist/core/compaction/context-transcript-analysis.js.map +1 -1
- package/dist/core/copilot-model-synthesis.d.ts.map +1 -1
- package/dist/core/copilot-model-synthesis.js +3 -1
- package/dist/core/copilot-model-synthesis.js.map +1 -1
- package/dist/core/extensions/provider-types.d.ts +2 -7
- package/dist/core/extensions/provider-types.d.ts.map +1 -1
- package/dist/core/extensions/provider-types.js.map +1 -1
- package/dist/core/messages.d.ts +9 -0
- package/dist/core/messages.d.ts.map +1 -1
- package/dist/core/messages.js +100 -18
- package/dist/core/messages.js.map +1 -1
- package/dist/core/model-registry-builtins.d.ts.map +1 -1
- package/dist/core/model-registry-builtins.js +5 -0
- package/dist/core/model-registry-builtins.js.map +1 -1
- package/dist/core/model-registry-custom-loader.d.ts.map +1 -1
- package/dist/core/model-registry-custom-loader.js +49 -8
- package/dist/core/model-registry-custom-loader.js.map +1 -1
- package/dist/core/model-registry-dynamic.d.ts.map +1 -1
- package/dist/core/model-registry-dynamic.js +11 -5
- package/dist/core/model-registry-dynamic.js.map +1 -1
- package/dist/core/model-registry-loader.d.ts.map +1 -1
- package/dist/core/model-registry-loader.js +8 -0
- package/dist/core/model-registry-loader.js.map +1 -1
- package/dist/core/model-registry-schemas.d.ts +93 -8
- package/dist/core/model-registry-schemas.d.ts.map +1 -1
- package/dist/core/model-registry-schemas.js +24 -12
- package/dist/core/model-registry-schemas.js.map +1 -1
- package/dist/core/model-registry-types.d.ts +7 -6
- package/dist/core/model-registry-types.d.ts.map +1 -1
- package/dist/core/model-registry-types.js.map +1 -1
- package/dist/core/model-registry.d.ts +5 -0
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +23 -0
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/model-resolver-cli.d.ts.map +1 -1
- package/dist/core/model-resolver-cli.js +33 -5
- package/dist/core/model-resolver-cli.js.map +1 -1
- package/dist/core/model-resolver-initial.d.ts +6 -1
- package/dist/core/model-resolver-initial.d.ts.map +1 -1
- package/dist/core/model-resolver-initial.js +12 -7
- package/dist/core/model-resolver-initial.js.map +1 -1
- package/dist/core/model-resolver.d.ts +1 -1
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +1 -1
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/resource-loader-context-files.d.ts +1 -0
- package/dist/core/resource-loader-context-files.d.ts.map +1 -1
- package/dist/core/resource-loader-context-files.js +13 -10
- package/dist/core/resource-loader-context-files.js.map +1 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +2 -2
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-entry-normalization.d.ts +7 -0
- package/dist/core/session-entry-normalization.d.ts.map +1 -0
- package/dist/core/session-entry-normalization.js +14 -0
- package/dist/core/session-entry-normalization.js.map +1 -0
- package/dist/core/session-manager-core.d.ts.map +1 -1
- package/dist/core/session-manager-core.js +1 -0
- package/dist/core/session-manager-core.js.map +1 -1
- package/dist/core/session-manager-history.d.ts +2 -2
- package/dist/core/session-manager-history.d.ts.map +1 -1
- package/dist/core/session-manager-history.js +127 -108
- package/dist/core/session-manager-history.js.map +1 -1
- package/dist/core/settings-manager-basic-accessors.d.ts +2 -2
- package/dist/core/settings-manager-basic-accessors.d.ts.map +1 -1
- package/dist/core/settings-manager-basic-accessors.js.map +1 -1
- package/dist/core/settings-types.d.ts +1 -1
- package/dist/core/settings-types.d.ts.map +1 -1
- package/dist/core/settings-types.js.map +1 -1
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +11 -8
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/main-session.d.ts.map +1 -1
- package/dist/main-session.js +1 -0
- package/dist/main-session.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector-options.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector-options.js +3 -1
- package/dist/modes/interactive/components/settings-selector-options.js.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.js +2 -1
- package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
- package/dist/modes/interactive/interactive-agent-events.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-agent-events.js +2 -1
- package/dist/modes/interactive/interactive-agent-events.js.map +1 -1
- package/dist/modes/interactive/interactive-child-ordering.d.ts +7 -0
- package/dist/modes/interactive/interactive-child-ordering.d.ts.map +1 -0
- package/dist/modes/interactive/interactive-child-ordering.js +26 -0
- package/dist/modes/interactive/interactive-child-ordering.js.map +1 -0
- package/dist/modes/interactive/interactive-deferred-startup.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-deferred-startup.js +2 -2
- package/dist/modes/interactive/interactive-deferred-startup.js.map +1 -1
- package/dist/modes/interactive/interactive-mode-deps.d.ts +1 -1
- package/dist/modes/interactive/interactive-mode-deps.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode-deps.js +1 -1
- package/dist/modes/interactive/interactive-mode-deps.js.map +1 -1
- package/dist/modes/interactive/interactive-model-routing.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-model-routing.js +8 -3
- package/dist/modes/interactive/interactive-model-routing.js.map +1 -1
- package/dist/modes/interactive/theme/theme-class.d.ts +1 -1
- package/dist/modes/interactive/theme/theme-class.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme-class.js +2 -0
- package/dist/modes/interactive/theme/theme-class.js.map +1 -1
- package/dist/utils/clipboard-image.d.ts.map +1 -1
- package/dist/utils/clipboard-image.js +3 -0
- package/dist/utils/clipboard-image.js.map +1 -1
- package/docs/changelog.mdx +19 -0
- package/docs/compaction.md +55 -48
- package/docs/custom-provider.md +18 -5
- package/docs/extensions.md +7 -3
- package/docs/models.md +69 -10
- package/docs/providers.md +1 -1
- package/docs/quickstart.md +11 -7
- package/docs/rpc.md +2 -2
- package/docs/sdk.md +1 -1
- package/docs/settings.md +3 -3
- package/docs/subagents.md +36 -5
- package/docs/tools.md +1 -1
- package/docs/usage.md +4 -2
- package/docs/workflows.md +26 -43
- package/examples/extensions/preset.ts +2 -2
- package/examples/extensions/subagent/README.md +2 -2
- package/examples/extensions/subagent/index.ts +1 -2
- package/examples/extensions/subagent/schemas.ts +4 -1
- package/examples/sdk/12-full-control.ts +1 -1
- package/npm-shrinkwrap.json +48 -51
- package/package.json +7 -7
- package/dist/builtin/subagents/src/runs/foreground/chain-clarify-behavior.ts +0 -75
- package/dist/builtin/subagents/src/runs/foreground/chain-clarify-component.ts +0 -202
- package/dist/builtin/subagents/src/runs/foreground/chain-clarify-edit.ts +0 -97
- package/dist/builtin/subagents/src/runs/foreground/chain-clarify-editor.ts +0 -160
- package/dist/builtin/subagents/src/runs/foreground/chain-clarify-frame.ts +0 -72
- package/dist/builtin/subagents/src/runs/foreground/chain-clarify-render-modes.ts +0 -161
- package/dist/builtin/subagents/src/runs/foreground/chain-clarify-render-selectors.ts +0 -203
- package/dist/builtin/subagents/src/runs/foreground/chain-clarify-selectors.ts +0 -234
- package/dist/builtin/subagents/src/runs/foreground/chain-clarify-state.ts +0 -103
- package/dist/builtin/subagents/src/runs/foreground/chain-clarify-types.ts +0 -29
- package/dist/builtin/subagents/src/runs/foreground/chain-clarify.ts +0 -9
- package/dist/builtin/subagents/src/runs/foreground/chain-execution-clarify.ts +0 -117
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import type { ExtensionAPI } from "@bastani/atomic";
|
|
2
|
+
import type { McpExtensionState } from "./state.js";
|
|
3
|
+
|
|
4
|
+
interface CommandStateLease {
|
|
5
|
+
readonly state: McpExtensionState;
|
|
6
|
+
readonly assertActive: () => void;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function registerMcpCommands(
|
|
10
|
+
pi: ExtensionAPI,
|
|
11
|
+
earlyConfigPath: string | undefined,
|
|
12
|
+
acquireState: () => Promise<CommandStateLease>,
|
|
13
|
+
): void {
|
|
14
|
+
pi.registerCommand("mcp", {
|
|
15
|
+
description: "Show MCP server status",
|
|
16
|
+
handler: async (args, ctx) => {
|
|
17
|
+
let lease: CommandStateLease;
|
|
18
|
+
try {
|
|
19
|
+
lease = await acquireState();
|
|
20
|
+
} catch (error) {
|
|
21
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
22
|
+
if (ctx.hasUI) ctx.ui.notify(`MCP initialization failed: ${message}`, "error");
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
const { showStatus, showTools, reconnectServers, logoutServer, openMcpPanel, openMcpSetup } = await import("./commands.js");
|
|
26
|
+
try { lease.assertActive(); } catch { return; }
|
|
27
|
+
const parts = args?.trim()?.split(/\s+/) ?? [];
|
|
28
|
+
const subcommand = parts[0] ?? "";
|
|
29
|
+
const targetServer = parts[1];
|
|
30
|
+
const rest = parts.slice(1).join(" ");
|
|
31
|
+
switch (subcommand) {
|
|
32
|
+
case "reconnect": await reconnectServers(lease.state, ctx, targetServer); break;
|
|
33
|
+
case "tools": await showTools(lease.state, ctx); break;
|
|
34
|
+
case "setup": {
|
|
35
|
+
const result = await openMcpSetup(lease.state, pi, ctx, earlyConfigPath, "setup");
|
|
36
|
+
if (result?.configChanged) await ctx.reload();
|
|
37
|
+
break;
|
|
38
|
+
}
|
|
39
|
+
case "logout": {
|
|
40
|
+
if (!rest) {
|
|
41
|
+
if (ctx.hasUI) ctx.ui.notify("Usage: /mcp logout <server>", "error");
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
await logoutServer(rest, lease.state, ctx);
|
|
45
|
+
break;
|
|
46
|
+
}
|
|
47
|
+
case "status":
|
|
48
|
+
case "":
|
|
49
|
+
default:
|
|
50
|
+
if (ctx.hasUI) {
|
|
51
|
+
const result = await openMcpPanel(lease.state, pi, ctx, earlyConfigPath);
|
|
52
|
+
if (result?.configChanged) await ctx.reload();
|
|
53
|
+
} else {
|
|
54
|
+
await showStatus(lease.state, ctx);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
pi.registerCommand("mcp-auth", {
|
|
61
|
+
description: "Authenticate with an MCP server (OAuth)",
|
|
62
|
+
handler: async (args, ctx) => {
|
|
63
|
+
const serverName = args?.trim();
|
|
64
|
+
if (!serverName && !ctx.hasUI) return;
|
|
65
|
+
let lease: CommandStateLease;
|
|
66
|
+
try {
|
|
67
|
+
lease = await acquireState();
|
|
68
|
+
} catch (error) {
|
|
69
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
70
|
+
if (ctx.hasUI) ctx.ui.notify(`MCP initialization failed: ${message}`, "error");
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
const { authenticateServer, openMcpAuthPanel } = await import("./commands.js");
|
|
74
|
+
try { lease.assertActive(); } catch { return; }
|
|
75
|
+
if (!serverName) {
|
|
76
|
+
await openMcpAuthPanel(lease.state, pi, ctx, earlyConfigPath);
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
await authenticateServer(serverName, lease.state.config, ctx);
|
|
80
|
+
},
|
|
81
|
+
});
|
|
82
|
+
}
|
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
import type { AgentToolResult, AgentToolUpdateCallback, ExtensionContext } from "@bastani/atomic";
|
|
2
|
+
import { CallToolResultSchema } from "@modelcontextprotocol/sdk/types.js";
|
|
3
|
+
import type { McpExtensionState } from "./state.js";
|
|
4
|
+
import type { DirectToolSpec, McpContent } from "./types.js";
|
|
5
|
+
import { getFailureAgeSeconds, lazyConnect } from "./init.js";
|
|
6
|
+
import { formatSchema } from "./tool-metadata.js";
|
|
7
|
+
import { transformMcpContent } from "./tool-registrar.js";
|
|
8
|
+
import { maybeStartUiSession, type UiSessionRuntime } from "./ui-session.js";
|
|
9
|
+
import { authenticate, supportsOAuth } from "./mcp-auth-flow.js";
|
|
10
|
+
import { formatAuthRequiredMessage, unflattenToolArguments } from "./utils.js";
|
|
11
|
+
import { waitForCaller, waitForCallerWithLateCleanup } from "./caller-wait.js";
|
|
12
|
+
import { notifyUiCancellation, rethrowHostAbortAfterUiCancellation } from "./apps-cancellation.js";
|
|
13
|
+
import { asCallToolResult } from "./call-tool-result.js";
|
|
14
|
+
|
|
15
|
+
interface DirectToolStateChangedDetails extends Record<string, unknown> {
|
|
16
|
+
error: "state_changed";
|
|
17
|
+
message: string;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
type DirectToolExecute = (
|
|
21
|
+
toolCallId: string,
|
|
22
|
+
params: Record<string, unknown>,
|
|
23
|
+
signal: AbortSignal | undefined,
|
|
24
|
+
onUpdate: AgentToolUpdateCallback<Record<string, unknown>> | undefined,
|
|
25
|
+
ctx: ExtensionContext,
|
|
26
|
+
) => Promise<AgentToolResult<Record<string, unknown>>>;
|
|
27
|
+
|
|
28
|
+
type IsActiveStateOwner = (candidate: McpExtensionState) => boolean;
|
|
29
|
+
type StartUiSession = typeof maybeStartUiSession;
|
|
30
|
+
|
|
31
|
+
export interface DirectToolExecutorOptions {
|
|
32
|
+
readonly startUiSession?: StartUiSession;
|
|
33
|
+
readonly startAutoAuth?: (state: McpExtensionState, serverName: string) => Promise<DirectAutoAuthResult>;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export type DirectAutoAuthResult =
|
|
37
|
+
| { status: "skipped" }
|
|
38
|
+
| { status: "success" }
|
|
39
|
+
| { status: "failed"; message: string };
|
|
40
|
+
|
|
41
|
+
function getDirectAuthRequiredMessage(
|
|
42
|
+
state: McpExtensionState,
|
|
43
|
+
serverName: string,
|
|
44
|
+
defaultMessage = `MCP server "${serverName}" requires OAuth authentication. Run /mcp-auth ${serverName} first.`,
|
|
45
|
+
): string {
|
|
46
|
+
return formatAuthRequiredMessage(state.config, serverName, defaultMessage);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function getDirectAuthFailedMessage(state: McpExtensionState, serverName: string, message: string): string {
|
|
50
|
+
const customGuidance = state.config.settings?.authRequiredMessage;
|
|
51
|
+
if (customGuidance) {
|
|
52
|
+
return `OAuth authentication failed for "${serverName}": ${message}. ${getDirectAuthRequiredMessage(state, serverName)}`;
|
|
53
|
+
}
|
|
54
|
+
return `OAuth authentication failed for "${serverName}": ${message}. Run /mcp-auth ${serverName} first.`;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
async function attemptDirectAutoAuth(
|
|
58
|
+
state: McpExtensionState,
|
|
59
|
+
serverName: string,
|
|
60
|
+
): Promise<DirectAutoAuthResult> {
|
|
61
|
+
if (state.config.settings?.autoAuth !== true) return { status: "skipped" };
|
|
62
|
+
|
|
63
|
+
const definition = state.config.mcpServers[serverName];
|
|
64
|
+
if (!definition || !supportsOAuth(definition) || !definition.url) return { status: "skipped" };
|
|
65
|
+
|
|
66
|
+
const grantType = definition.oauth ? definition.oauth.grantType ?? "authorization_code" : "authorization_code";
|
|
67
|
+
if (!state.ui && grantType !== "client_credentials") {
|
|
68
|
+
return {
|
|
69
|
+
status: "failed",
|
|
70
|
+
message: getDirectAuthRequiredMessage(
|
|
71
|
+
state,
|
|
72
|
+
serverName,
|
|
73
|
+
`MCP server "${serverName}" requires OAuth authentication. Run /mcp-auth ${serverName} in an interactive session.`,
|
|
74
|
+
),
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
try {
|
|
79
|
+
await authenticate(serverName, definition.url, definition);
|
|
80
|
+
return { status: "success" };
|
|
81
|
+
} catch (error) {
|
|
82
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
83
|
+
return { status: "failed", message: getDirectAuthFailedMessage(state, serverName, message) };
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function stateChangedResult(): AgentToolResult<DirectToolStateChangedDetails> {
|
|
88
|
+
const message = "MCP session changed before direct tool execution completed";
|
|
89
|
+
return {
|
|
90
|
+
content: [{ type: "text" as const, text: message }],
|
|
91
|
+
details: { error: "state_changed", message },
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export function createDirectToolExecutor(
|
|
96
|
+
ensureInitialized: () => Promise<McpExtensionState>,
|
|
97
|
+
isActiveStateOwner: IsActiveStateOwner,
|
|
98
|
+
spec: DirectToolSpec,
|
|
99
|
+
options: DirectToolExecutorOptions = {},
|
|
100
|
+
): DirectToolExecute {
|
|
101
|
+
const startUiSession = options.startUiSession ?? maybeStartUiSession;
|
|
102
|
+
const startAutoAuth = options.startAutoAuth ?? attemptDirectAutoAuth;
|
|
103
|
+
return async function execute(_toolCallId, params, signal) {
|
|
104
|
+
signal?.throwIfAborted();
|
|
105
|
+
let state: McpExtensionState;
|
|
106
|
+
try {
|
|
107
|
+
state = await waitForCaller(ensureInitialized, signal);
|
|
108
|
+
} catch (error) {
|
|
109
|
+
signal?.throwIfAborted();
|
|
110
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
111
|
+
return {
|
|
112
|
+
content: [{ type: "text" as const, text: `MCP initialization failed: ${message}` }],
|
|
113
|
+
details: { error: "init_failed", message },
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
signal?.throwIfAborted();
|
|
117
|
+
if (!isActiveStateOwner(state)) return stateChangedResult();
|
|
118
|
+
|
|
119
|
+
let connected = await waitForCaller(() => lazyConnect(state, spec.serverName), signal);
|
|
120
|
+
signal?.throwIfAborted();
|
|
121
|
+
if (!isActiveStateOwner(state)) return stateChangedResult();
|
|
122
|
+
let autoAuthAttempted = false;
|
|
123
|
+
|
|
124
|
+
if (!connected && state.manager.getConnection(spec.serverName)?.status === "needs-auth") {
|
|
125
|
+
autoAuthAttempted = true;
|
|
126
|
+
const autoAuth = await waitForCaller(() => startAutoAuth(state, spec.serverName), signal);
|
|
127
|
+
signal?.throwIfAborted();
|
|
128
|
+
if (!isActiveStateOwner(state)) return stateChangedResult();
|
|
129
|
+
if (autoAuth.status === "failed") {
|
|
130
|
+
return {
|
|
131
|
+
content: [{ type: "text" as const, text: autoAuth.message }],
|
|
132
|
+
details: { error: "auth_required", server: spec.serverName, message: autoAuth.message },
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
if (autoAuth.status === "success") {
|
|
136
|
+
await waitForCaller(() => state.manager.close(spec.serverName), signal);
|
|
137
|
+
signal?.throwIfAborted();
|
|
138
|
+
if (!isActiveStateOwner(state)) return stateChangedResult();
|
|
139
|
+
state.failureTracker.delete(spec.serverName);
|
|
140
|
+
connected = await waitForCaller(() => lazyConnect(state, spec.serverName), signal);
|
|
141
|
+
signal?.throwIfAborted();
|
|
142
|
+
if (!isActiveStateOwner(state)) return stateChangedResult();
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
if (!connected) {
|
|
147
|
+
const authConnection = state.manager.getConnection(spec.serverName);
|
|
148
|
+
if (authConnection?.status === "needs-auth") {
|
|
149
|
+
const message = getDirectAuthRequiredMessage(state, spec.serverName);
|
|
150
|
+
return {
|
|
151
|
+
content: [{ type: "text" as const, text: message }],
|
|
152
|
+
details: { error: "auth_required", server: spec.serverName, message, autoAuthAttempted },
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
const failedAgo = getFailureAgeSeconds(state, spec.serverName);
|
|
156
|
+
return {
|
|
157
|
+
content: [{ type: "text" as const, text: `MCP server "${spec.serverName}" not available${failedAgo !== null ? ` (failed ${failedAgo}s ago)` : ""}` }],
|
|
158
|
+
details: { error: "server_unavailable", server: spec.serverName },
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const connection = state.manager.getConnection(spec.serverName);
|
|
163
|
+
if (!connection || connection.status !== "connected") {
|
|
164
|
+
return {
|
|
165
|
+
content: [{ type: "text" as const, text: `MCP server "${spec.serverName}" not connected` }],
|
|
166
|
+
details: { error: "not_connected", server: spec.serverName },
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
let uiSession: UiSessionRuntime | null = null;
|
|
171
|
+
let closeUiForStaleState = false;
|
|
172
|
+
let inFlightStarted = false;
|
|
173
|
+
const staleStateResult = (): AgentToolResult<DirectToolStateChangedDetails> => {
|
|
174
|
+
if (uiSession && !uiSession.reused) closeUiForStaleState = true;
|
|
175
|
+
return stateChangedResult();
|
|
176
|
+
};
|
|
177
|
+
const cancelStaleUi = async (): Promise<AgentToolResult<DirectToolStateChangedDetails>> => {
|
|
178
|
+
await notifyUiCancellation(uiSession, "MCP session changed during direct tool execution");
|
|
179
|
+
signal?.throwIfAborted();
|
|
180
|
+
return staleStateResult();
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
try {
|
|
184
|
+
if (!isActiveStateOwner(state)) return staleStateResult();
|
|
185
|
+
state.manager.touch(spec.serverName);
|
|
186
|
+
state.manager.incrementInFlight(spec.serverName);
|
|
187
|
+
inFlightStarted = true;
|
|
188
|
+
|
|
189
|
+
if (spec.resourceUri) {
|
|
190
|
+
const result = await connection.client.readResource({ uri: spec.resourceUri }, { signal });
|
|
191
|
+
signal?.throwIfAborted();
|
|
192
|
+
if (!isActiveStateOwner(state)) return stateChangedResult();
|
|
193
|
+
const content = (result.contents ?? []).map((item) => ({
|
|
194
|
+
type: "text" as const,
|
|
195
|
+
text: "text" in item
|
|
196
|
+
? item.text
|
|
197
|
+
: ("blob" in item ? `[Binary data: ${item.mimeType ?? "unknown"}]` : JSON.stringify(item)),
|
|
198
|
+
}));
|
|
199
|
+
return {
|
|
200
|
+
content: content.length > 0 ? content : [{ type: "text" as const, text: "(empty resource)" }],
|
|
201
|
+
details: { server: spec.serverName, resourceUri: spec.resourceUri },
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
const hasUi = !!spec.uiResourceUri;
|
|
206
|
+
uiSession = hasUi
|
|
207
|
+
? await waitForCallerWithLateCleanup(
|
|
208
|
+
() => startUiSession(state, {
|
|
209
|
+
serverName: spec.serverName,
|
|
210
|
+
toolName: spec.originalName,
|
|
211
|
+
toolArgs: params,
|
|
212
|
+
uiResourceUri: spec.uiResourceUri!,
|
|
213
|
+
streamMode: spec.uiStreamMode,
|
|
214
|
+
}),
|
|
215
|
+
signal,
|
|
216
|
+
(lateSession) => {
|
|
217
|
+
if (lateSession && !lateSession.reused) lateSession.close("caller cancelled during UI startup");
|
|
218
|
+
},
|
|
219
|
+
)
|
|
220
|
+
: null;
|
|
221
|
+
signal?.throwIfAborted();
|
|
222
|
+
if (!isActiveStateOwner(state)) return cancelStaleUi();
|
|
223
|
+
|
|
224
|
+
const sdkResult = await connection.client.callTool({
|
|
225
|
+
name: spec.originalName,
|
|
226
|
+
arguments: unflattenToolArguments(params, spec.inputSchema),
|
|
227
|
+
_meta: uiSession?.requestMeta,
|
|
228
|
+
}, CallToolResultSchema, { signal });
|
|
229
|
+
signal?.throwIfAborted();
|
|
230
|
+
if (!isActiveStateOwner(state)) return cancelStaleUi();
|
|
231
|
+
const result = asCallToolResult(sdkResult);
|
|
232
|
+
uiSession?.sendToolResult(result);
|
|
233
|
+
|
|
234
|
+
const content = transformMcpContent((result.content ?? []) as McpContent[]);
|
|
235
|
+
if (result.isError) {
|
|
236
|
+
let errorText = content.filter((item) => item.type === "text").map((item) => item.text).join("\n") || "Tool execution failed";
|
|
237
|
+
if (spec.inputSchema) errorText += `\n\nExpected parameters:\n${formatSchema(spec.inputSchema)}`;
|
|
238
|
+
return {
|
|
239
|
+
content: [{ type: "text" as const, text: `Error: ${errorText}` }],
|
|
240
|
+
details: { error: "tool_error", server: spec.serverName },
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
const resultText = content.filter((item) => item.type === "text").map((item) => item.text).join("\n") || "(empty result)";
|
|
245
|
+
if (hasUi) {
|
|
246
|
+
const uiMessage = uiSession?.reused
|
|
247
|
+
? "Updated the open UI."
|
|
248
|
+
: "📺 Interactive UI is now open in your browser. I'll respond to your prompts and intents as you interact with it.";
|
|
249
|
+
return {
|
|
250
|
+
content: [{ type: "text" as const, text: `${resultText}\n\n${uiMessage}` }],
|
|
251
|
+
details: { server: spec.serverName, tool: spec.originalName, uiOpen: true },
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
return {
|
|
256
|
+
content: content.length > 0 ? content : [{ type: "text" as const, text: "(empty result)" }],
|
|
257
|
+
details: { server: spec.serverName, tool: spec.originalName },
|
|
258
|
+
};
|
|
259
|
+
} catch (error) {
|
|
260
|
+
await rethrowHostAbortAfterUiCancellation(signal, uiSession);
|
|
261
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
262
|
+
await notifyUiCancellation(uiSession, message);
|
|
263
|
+
signal?.throwIfAborted();
|
|
264
|
+
if (!isActiveStateOwner(state)) return staleStateResult();
|
|
265
|
+
let errorText = `Failed to call tool: ${message}`;
|
|
266
|
+
if (spec.inputSchema) errorText += `\n\nExpected parameters:\n${formatSchema(spec.inputSchema)}`;
|
|
267
|
+
return {
|
|
268
|
+
content: [{ type: "text" as const, text: errorText }],
|
|
269
|
+
details: { error: "call_failed", server: spec.serverName },
|
|
270
|
+
};
|
|
271
|
+
} finally {
|
|
272
|
+
if (uiSession && (uiSession.reused || closeUiForStaleState)) uiSession.close(closeUiForStaleState ? "stale MCP session" : undefined);
|
|
273
|
+
if (inFlightStarted) {
|
|
274
|
+
state.manager.decrementInFlight(spec.serverName);
|
|
275
|
+
if (isActiveStateOwner(state)) state.manager.touch(spec.serverName);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
};
|
|
279
|
+
}
|
|
@@ -1,77 +1,11 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
6
|
-
import { isServerCacheValid } from "./metadata-cache.ts";
|
|
7
|
-
import { formatSchema } from "./tool-metadata.ts";
|
|
8
|
-
import { transformMcpContent } from "./tool-registrar.ts";
|
|
9
|
-
import { maybeStartUiSession, type UiSessionRuntime } from "./ui-session.ts";
|
|
10
|
-
import { formatToolName, isToolExcluded } from "./types.ts";
|
|
11
|
-
import { resourceNameToToolName } from "./resource-tools.ts";
|
|
12
|
-
import { authenticate, supportsOAuth } from "./mcp-auth-flow.ts";
|
|
13
|
-
import { formatAuthRequiredMessage, unflattenToolArguments } from "./utils.ts";
|
|
1
|
+
import type { DirectToolSpec, McpConfig } from "./types.js";
|
|
2
|
+
import type { MetadataCache } from "./metadata-cache.js";
|
|
3
|
+
import { isServerCacheValid } from "./metadata-cache.js";
|
|
4
|
+
import { formatToolName, isToolExcluded } from "./types.js";
|
|
5
|
+
import { resourceNameToToolName } from "./resource-tools.js";
|
|
14
6
|
|
|
15
7
|
const BUILTIN_NAMES = new Set(["read", "bash", "edit", "write", "grep", "find", "search", "ls", "mcp"]);
|
|
16
8
|
|
|
17
|
-
type DirectAutoAuthResult =
|
|
18
|
-
| { status: "skipped" }
|
|
19
|
-
| { status: "success" }
|
|
20
|
-
| { status: "failed"; message: string };
|
|
21
|
-
|
|
22
|
-
function getDirectAuthRequiredMessage(
|
|
23
|
-
state: McpExtensionState,
|
|
24
|
-
serverName: string,
|
|
25
|
-
defaultMessage = `MCP server "${serverName}" requires OAuth authentication. Run /mcp-auth ${serverName} first.`,
|
|
26
|
-
): string {
|
|
27
|
-
return formatAuthRequiredMessage(state.config, serverName, defaultMessage);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
function getDirectAuthFailedMessage(state: McpExtensionState, serverName: string, message: string): string {
|
|
31
|
-
const customGuidance = state.config.settings?.authRequiredMessage;
|
|
32
|
-
if (customGuidance) {
|
|
33
|
-
return `OAuth authentication failed for "${serverName}": ${message}. ${getDirectAuthRequiredMessage(state, serverName)}`;
|
|
34
|
-
}
|
|
35
|
-
return `OAuth authentication failed for "${serverName}": ${message}. Run /mcp-auth ${serverName} first.`;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
async function attemptDirectAutoAuth(
|
|
39
|
-
state: McpExtensionState,
|
|
40
|
-
serverName: string,
|
|
41
|
-
): Promise<DirectAutoAuthResult> {
|
|
42
|
-
if (state.config.settings?.autoAuth !== true) {
|
|
43
|
-
return { status: "skipped" };
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
const definition = state.config.mcpServers[serverName];
|
|
47
|
-
if (!definition || !supportsOAuth(definition) || !definition.url) {
|
|
48
|
-
return { status: "skipped" };
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
const grantType = definition.oauth ? definition.oauth.grantType ?? "authorization_code" : "authorization_code";
|
|
52
|
-
if (!state.ui && grantType !== "client_credentials") {
|
|
53
|
-
return {
|
|
54
|
-
status: "failed",
|
|
55
|
-
message: getDirectAuthRequiredMessage(
|
|
56
|
-
state,
|
|
57
|
-
serverName,
|
|
58
|
-
`MCP server "${serverName}" requires OAuth authentication. Run /mcp-auth ${serverName} in an interactive session.`,
|
|
59
|
-
),
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
try {
|
|
64
|
-
await authenticate(serverName, definition.url, definition);
|
|
65
|
-
return { status: "success" };
|
|
66
|
-
} catch (error) {
|
|
67
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
68
|
-
return {
|
|
69
|
-
status: "failed",
|
|
70
|
-
message: getDirectAuthFailedMessage(state, serverName, message),
|
|
71
|
-
};
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
9
|
interface DirectToolSelection {
|
|
76
10
|
readonly servers: ReadonlySet<string>;
|
|
77
11
|
readonly toolsByServer: ReadonlyMap<string, ReadonlySet<string>>;
|
|
@@ -278,172 +212,5 @@ export function buildProxyDescription(
|
|
|
278
212
|
return desc;
|
|
279
213
|
}
|
|
280
214
|
|
|
281
|
-
type DirectToolExecute = (
|
|
282
|
-
toolCallId: string,
|
|
283
|
-
params: Record<string, unknown>,
|
|
284
|
-
signal: AbortSignal | undefined,
|
|
285
|
-
onUpdate: AgentToolUpdateCallback<Record<string, unknown>> | undefined,
|
|
286
|
-
ctx: ExtensionContext,
|
|
287
|
-
) => Promise<AgentToolResult<Record<string, unknown>>>;
|
|
288
|
-
|
|
289
|
-
export function createDirectToolExecutor(
|
|
290
|
-
getState: () => McpExtensionState | null,
|
|
291
|
-
getInitPromise: () => Promise<McpExtensionState> | null,
|
|
292
|
-
spec: DirectToolSpec
|
|
293
|
-
): DirectToolExecute {
|
|
294
|
-
return async function execute(_toolCallId, params) {
|
|
295
|
-
let state = getState();
|
|
296
|
-
const initPromise = getInitPromise();
|
|
297
|
-
|
|
298
|
-
if (!state && initPromise) {
|
|
299
|
-
try {
|
|
300
|
-
state = await initPromise;
|
|
301
|
-
} catch (error) {
|
|
302
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
303
|
-
return {
|
|
304
|
-
content: [{ type: "text" as const, text: `MCP initialization failed: ${message}` }],
|
|
305
|
-
details: { error: "init_failed", message },
|
|
306
|
-
};
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
if (!state) {
|
|
310
|
-
return {
|
|
311
|
-
content: [{ type: "text" as const, text: "MCP not initialized" }],
|
|
312
|
-
details: { error: "not_initialized" },
|
|
313
|
-
};
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
let connected = await lazyConnect(state, spec.serverName);
|
|
317
|
-
let autoAuthAttempted = false;
|
|
318
|
-
|
|
319
|
-
if (!connected && state.manager.getConnection(spec.serverName)?.status === "needs-auth") {
|
|
320
|
-
autoAuthAttempted = true;
|
|
321
|
-
const autoAuth = await attemptDirectAutoAuth(state, spec.serverName);
|
|
322
|
-
if (autoAuth.status === "failed") {
|
|
323
|
-
return {
|
|
324
|
-
content: [{ type: "text" as const, text: autoAuth.message }],
|
|
325
|
-
details: { error: "auth_required", server: spec.serverName, message: autoAuth.message },
|
|
326
|
-
};
|
|
327
|
-
}
|
|
328
|
-
if (autoAuth.status === "success") {
|
|
329
|
-
await state.manager.close(spec.serverName);
|
|
330
|
-
state.failureTracker.delete(spec.serverName);
|
|
331
|
-
connected = await lazyConnect(state, spec.serverName);
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
if (!connected) {
|
|
336
|
-
const authConnection = state.manager.getConnection(spec.serverName);
|
|
337
|
-
if (authConnection?.status === "needs-auth") {
|
|
338
|
-
const message = getDirectAuthRequiredMessage(state, spec.serverName);
|
|
339
|
-
return {
|
|
340
|
-
content: [{ type: "text" as const, text: message }],
|
|
341
|
-
details: { error: "auth_required", server: spec.serverName, message, autoAuthAttempted },
|
|
342
|
-
};
|
|
343
|
-
}
|
|
344
|
-
const failedAgo = getFailureAgeSeconds(state, spec.serverName);
|
|
345
|
-
return {
|
|
346
|
-
content: [{ type: "text" as const, text: `MCP server "${spec.serverName}" not available${failedAgo !== null ? ` (failed ${failedAgo}s ago)` : ""}` }],
|
|
347
|
-
details: { error: "server_unavailable", server: spec.serverName },
|
|
348
|
-
};
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
const connection = state.manager.getConnection(spec.serverName);
|
|
352
|
-
if (!connection || connection.status !== "connected") {
|
|
353
|
-
return {
|
|
354
|
-
content: [{ type: "text" as const, text: `MCP server "${spec.serverName}" not connected` }],
|
|
355
|
-
details: { error: "not_connected", server: spec.serverName },
|
|
356
|
-
};
|
|
357
|
-
}
|
|
358
215
|
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
try {
|
|
362
|
-
state.manager.touch(spec.serverName);
|
|
363
|
-
state.manager.incrementInFlight(spec.serverName);
|
|
364
|
-
|
|
365
|
-
if (spec.resourceUri) {
|
|
366
|
-
const result = await connection.client.readResource({ uri: spec.resourceUri });
|
|
367
|
-
const content = (result.contents ?? []).map(c => ({
|
|
368
|
-
type: "text" as const,
|
|
369
|
-
text: "text" in c ? c.text : ("blob" in c ? `[Binary data: ${(c as { mimeType?: string }).mimeType ?? "unknown"}]` : JSON.stringify(c)),
|
|
370
|
-
}));
|
|
371
|
-
return {
|
|
372
|
-
content: content.length > 0 ? content : [{ type: "text" as const, text: "(empty resource)" }],
|
|
373
|
-
details: { server: spec.serverName, resourceUri: spec.resourceUri },
|
|
374
|
-
};
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
const hasUi = !!spec.uiResourceUri;
|
|
378
|
-
uiSession = hasUi
|
|
379
|
-
? await maybeStartUiSession(state, {
|
|
380
|
-
serverName: spec.serverName,
|
|
381
|
-
toolName: spec.originalName,
|
|
382
|
-
toolArgs: params ?? {},
|
|
383
|
-
uiResourceUri: spec.uiResourceUri!,
|
|
384
|
-
streamMode: spec.uiStreamMode,
|
|
385
|
-
})
|
|
386
|
-
: null;
|
|
387
|
-
|
|
388
|
-
const resultPromise = connection.client.callTool({
|
|
389
|
-
name: spec.originalName,
|
|
390
|
-
// Normalize provider-flattened argument keys (e.g. Gemini's `keywords[0]`)
|
|
391
|
-
// back into arrays/objects before the MCP server validates them.
|
|
392
|
-
// Schema-aware: literal dotted property names (e.g. `filter.name`) are
|
|
393
|
-
// preserved unless the schema proves the head is a container.
|
|
394
|
-
arguments: unflattenToolArguments(params, spec.inputSchema),
|
|
395
|
-
_meta: uiSession?.requestMeta,
|
|
396
|
-
});
|
|
397
|
-
|
|
398
|
-
const result = await resultPromise;
|
|
399
|
-
uiSession?.sendToolResult(result as unknown as import("@modelcontextprotocol/sdk/types.js").CallToolResult);
|
|
400
|
-
|
|
401
|
-
const mcpContent = (result.content ?? []) as McpContent[];
|
|
402
|
-
const content = transformMcpContent(mcpContent);
|
|
403
|
-
|
|
404
|
-
if (result.isError) {
|
|
405
|
-
let errorText = content.filter(c => c.type === "text").map(c => (c as { text: string }).text).join("\n") || "Tool execution failed";
|
|
406
|
-
if (spec.inputSchema) {
|
|
407
|
-
errorText += `\n\nExpected parameters:\n${formatSchema(spec.inputSchema)}`;
|
|
408
|
-
}
|
|
409
|
-
return {
|
|
410
|
-
content: [{ type: "text" as const, text: `Error: ${errorText}` }],
|
|
411
|
-
details: { error: "tool_error", server: spec.serverName },
|
|
412
|
-
};
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
const resultText = content.filter(c => c.type === "text").map(c => (c as { text: string }).text).join("\n") || "(empty result)";
|
|
416
|
-
if (hasUi) {
|
|
417
|
-
const uiMessage = uiSession?.reused
|
|
418
|
-
? "Updated the open UI."
|
|
419
|
-
: "📺 Interactive UI is now open in your browser. I'll respond to your prompts and intents as you interact with it.";
|
|
420
|
-
return {
|
|
421
|
-
content: [{ type: "text" as const, text: `${resultText}\n\n${uiMessage}` }],
|
|
422
|
-
details: { server: spec.serverName, tool: spec.originalName, uiOpen: true },
|
|
423
|
-
};
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
return {
|
|
427
|
-
content: content.length > 0 ? content : [{ type: "text" as const, text: "(empty result)" }],
|
|
428
|
-
details: { server: spec.serverName, tool: spec.originalName },
|
|
429
|
-
};
|
|
430
|
-
} catch (error) {
|
|
431
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
432
|
-
uiSession?.sendToolCancelled(message);
|
|
433
|
-
let errorText = `Failed to call tool: ${message}`;
|
|
434
|
-
if (spec.inputSchema) {
|
|
435
|
-
errorText += `\n\nExpected parameters:\n${formatSchema(spec.inputSchema)}`;
|
|
436
|
-
}
|
|
437
|
-
return {
|
|
438
|
-
content: [{ type: "text" as const, text: errorText }],
|
|
439
|
-
details: { error: "call_failed", server: spec.serverName },
|
|
440
|
-
};
|
|
441
|
-
} finally {
|
|
442
|
-
if (uiSession?.reused) {
|
|
443
|
-
uiSession.close();
|
|
444
|
-
}
|
|
445
|
-
state.manager.decrementInFlight(spec.serverName);
|
|
446
|
-
state.manager.touch(spec.serverName);
|
|
447
|
-
}
|
|
448
|
-
};
|
|
449
|
-
}
|
|
216
|
+
export { createDirectToolExecutor } from "./direct-tool-executor.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { UiHostContext, UiResourceContent, UiResourceCsp } from "./types.
|
|
1
|
+
import type { UiHostContext, UiResourceContent, UiResourceCsp } from "./types.js";
|
|
2
2
|
|
|
3
3
|
// Use locally bundled AppBridge to avoid CDN Zod bundling issues
|
|
4
4
|
const DEFAULT_APP_BRIDGE_MODULE_URL = "/app-bridge.bundle.js";
|
|
@@ -292,7 +292,9 @@ export function buildHostHtmlTemplate(input: HostHtmlTemplateInput): string {
|
|
|
292
292
|
});
|
|
293
293
|
eventSource.addEventListener("tool-cancelled", (event) => {
|
|
294
294
|
try {
|
|
295
|
-
bridge.sendToolCancelled(JSON.parse(event.data))
|
|
295
|
+
void bridge.sendToolCancelled(JSON.parse(event.data)).catch((error) => {
|
|
296
|
+
showError("Failed to forward cancellation: " + String(error));
|
|
297
|
+
});
|
|
296
298
|
} catch (error) {
|
|
297
299
|
showError("Failed to forward cancellation: " + String(error));
|
|
298
300
|
}
|