@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
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
import type { ToolInfo } from "@bastani/atomic";
|
|
2
|
-
import type { McpExtensionState } from "./state.
|
|
3
|
-
import type { McpContent, ToolMetadata } from "./types.
|
|
4
|
-
import { getServerPrefix } from "./types.
|
|
5
|
-
import { lazyConnect, updateServerMetadata, updateMetadataCache, getFailureAgeSeconds, updateStatusBar } from "./init.
|
|
6
|
-
import { getToolNames, findToolByName, formatSchema } from "./tool-metadata.
|
|
7
|
-
import { transformMcpContent } from "./tool-registrar.
|
|
8
|
-
import { maybeStartUiSession, type UiSessionRuntime } from "./ui-session.
|
|
9
|
-
import { unflattenToolArguments } from "./utils.
|
|
10
|
-
import { attemptAutoAuth, getAuthRequiredMessage } from "./proxy-auth.
|
|
11
|
-
import type { ProxyToolResult } from "./proxy-types.
|
|
2
|
+
import type { McpExtensionState } from "./state.js";
|
|
3
|
+
import type { McpContent, ToolMetadata } from "./types.js";
|
|
4
|
+
import { getServerPrefix } from "./types.js";
|
|
5
|
+
import { lazyConnect, updateServerMetadata, updateMetadataCache, getFailureAgeSeconds, updateStatusBar } from "./init.js";
|
|
6
|
+
import { getToolNames, findToolByName, formatSchema } from "./tool-metadata.js";
|
|
7
|
+
import { transformMcpContent } from "./tool-registrar.js";
|
|
8
|
+
import { maybeStartUiSession, type UiSessionRuntime } from "./ui-session.js";
|
|
9
|
+
import { unflattenToolArguments } from "./utils.js";
|
|
10
|
+
import { attemptAutoAuth, getAuthRequiredMessage, type AutoAuthResult } from "./proxy-auth.js";
|
|
11
|
+
import type { ProxyToolResult } from "./proxy-types.js";
|
|
12
|
+
import { CallToolResultSchema } from "@modelcontextprotocol/sdk/types.js";
|
|
13
|
+
import { waitForCaller, waitForCallerWithLateCleanup } from "./caller-wait.js";
|
|
14
|
+
import { notifyUiCancellation, rethrowHostAbortAfterUiCancellation } from "./apps-cancellation.js";
|
|
15
|
+
import { asCallToolResult } from "./call-tool-result.js";
|
|
16
|
+
import { assertMcpStateLease, McpStateChangedError, type AssertMcpStateLease } from "./state-lease.js";
|
|
12
17
|
|
|
13
18
|
export async function executeCall(
|
|
14
19
|
state: McpExtensionState,
|
|
@@ -16,7 +21,12 @@ export async function executeCall(
|
|
|
16
21
|
args?: Record<string, unknown>,
|
|
17
22
|
serverOverride?: string,
|
|
18
23
|
getPiTools?: () => ToolInfo[],
|
|
24
|
+
signal?: AbortSignal,
|
|
25
|
+
startAutoAuth: (state: McpExtensionState, serverName: string) => Promise<AutoAuthResult> = attemptAutoAuth,
|
|
26
|
+
assertActive?: AssertMcpStateLease,
|
|
19
27
|
): Promise<ProxyToolResult> {
|
|
28
|
+
signal?.throwIfAborted();
|
|
29
|
+
assertMcpStateLease(assertActive);
|
|
20
30
|
let serverName: string | undefined = serverOverride;
|
|
21
31
|
let toolMeta: ToolMetadata | undefined;
|
|
22
32
|
let autoAuthAttempted = false;
|
|
@@ -43,14 +53,18 @@ export async function executeCall(
|
|
|
43
53
|
}
|
|
44
54
|
|
|
45
55
|
if (serverName && !toolMeta) {
|
|
46
|
-
const connected = await lazyConnect(state, serverName);
|
|
56
|
+
const connected = await waitForCaller(() => lazyConnect(state, serverName!), signal);
|
|
57
|
+
signal?.throwIfAborted();
|
|
58
|
+
assertMcpStateLease(assertActive);
|
|
47
59
|
if (connected) {
|
|
48
60
|
toolMeta = findToolByName(state.toolMetadata.get(serverName), toolName);
|
|
49
61
|
} else {
|
|
50
62
|
const needsAuthConnection = state.manager.getConnection(serverName);
|
|
51
63
|
if (needsAuthConnection?.status === "needs-auth") {
|
|
52
64
|
autoAuthAttempted = true;
|
|
53
|
-
const autoAuth = await
|
|
65
|
+
const autoAuth = await waitForCaller(() => startAutoAuth(state, serverName!), signal);
|
|
66
|
+
signal?.throwIfAborted();
|
|
67
|
+
assertMcpStateLease(assertActive);
|
|
54
68
|
if (autoAuth.status === "failed") {
|
|
55
69
|
return {
|
|
56
70
|
content: [{ type: "text" as const, text: autoAuth.message }],
|
|
@@ -58,9 +72,13 @@ export async function executeCall(
|
|
|
58
72
|
};
|
|
59
73
|
}
|
|
60
74
|
if (autoAuth.status === "success") {
|
|
61
|
-
await state.manager.close(serverName);
|
|
75
|
+
await waitForCaller(() => state.manager.close(serverName!), signal);
|
|
76
|
+
signal?.throwIfAborted();
|
|
77
|
+
assertMcpStateLease(assertActive);
|
|
62
78
|
state.failureTracker.delete(serverName);
|
|
63
|
-
const connectedAfterAuth = await lazyConnect(state, serverName);
|
|
79
|
+
const connectedAfterAuth = await waitForCaller(() => lazyConnect(state, serverName!), signal);
|
|
80
|
+
signal?.throwIfAborted();
|
|
81
|
+
assertMcpStateLease(assertActive);
|
|
64
82
|
if (connectedAfterAuth) {
|
|
65
83
|
toolMeta = findToolByName(state.toolMetadata.get(serverName), toolName);
|
|
66
84
|
if (!toolMeta) {
|
|
@@ -106,10 +124,14 @@ export async function executeCall(
|
|
|
106
124
|
const failedAgo = getFailureAgeSeconds(state, configuredServer);
|
|
107
125
|
if (failedAgo !== null && existingConnection?.status !== "needs-auth") continue;
|
|
108
126
|
|
|
109
|
-
let connected = await lazyConnect(state, configuredServer);
|
|
127
|
+
let connected = await waitForCaller(() => lazyConnect(state, configuredServer), signal);
|
|
128
|
+
signal?.throwIfAborted();
|
|
129
|
+
assertMcpStateLease(assertActive);
|
|
110
130
|
if (!connected && state.manager.getConnection(configuredServer)?.status === "needs-auth" && !autoAuthAttempted) {
|
|
111
131
|
autoAuthAttempted = true;
|
|
112
|
-
const autoAuth = await
|
|
132
|
+
const autoAuth = await waitForCaller(() => startAutoAuth(state, configuredServer), signal);
|
|
133
|
+
signal?.throwIfAborted();
|
|
134
|
+
assertMcpStateLease(assertActive);
|
|
113
135
|
if (autoAuth.status === "failed") {
|
|
114
136
|
return {
|
|
115
137
|
content: [{ type: "text" as const, text: autoAuth.message }],
|
|
@@ -117,9 +139,13 @@ export async function executeCall(
|
|
|
117
139
|
};
|
|
118
140
|
}
|
|
119
141
|
if (autoAuth.status === "success") {
|
|
120
|
-
await state.manager.close(configuredServer);
|
|
142
|
+
await waitForCaller(() => state.manager.close(configuredServer), signal);
|
|
143
|
+
signal?.throwIfAborted();
|
|
144
|
+
assertMcpStateLease(assertActive);
|
|
121
145
|
state.failureTracker.delete(configuredServer);
|
|
122
|
-
connected = await lazyConnect(state, configuredServer);
|
|
146
|
+
connected = await waitForCaller(() => lazyConnect(state, configuredServer), signal);
|
|
147
|
+
signal?.throwIfAborted();
|
|
148
|
+
assertMcpStateLease(assertActive);
|
|
123
149
|
}
|
|
124
150
|
}
|
|
125
151
|
|
|
@@ -162,7 +188,9 @@ export async function executeCall(
|
|
|
162
188
|
if (connection?.status === "needs-auth") {
|
|
163
189
|
if (!autoAuthAttempted) {
|
|
164
190
|
autoAuthAttempted = true;
|
|
165
|
-
const autoAuth = await
|
|
191
|
+
const autoAuth = await waitForCaller(() => startAutoAuth(state, serverName!), signal);
|
|
192
|
+
signal?.throwIfAborted();
|
|
193
|
+
assertMcpStateLease(assertActive);
|
|
166
194
|
if (autoAuth.status === "failed") {
|
|
167
195
|
return {
|
|
168
196
|
content: [{ type: "text" as const, text: autoAuth.message }],
|
|
@@ -170,7 +198,9 @@ export async function executeCall(
|
|
|
170
198
|
};
|
|
171
199
|
}
|
|
172
200
|
if (autoAuth.status === "success") {
|
|
173
|
-
await state.manager.close(serverName);
|
|
201
|
+
await waitForCaller(() => state.manager.close(serverName!), signal);
|
|
202
|
+
signal?.throwIfAborted();
|
|
203
|
+
assertMcpStateLease(assertActive);
|
|
174
204
|
state.failureTracker.delete(serverName);
|
|
175
205
|
connection = state.manager.getConnection(serverName);
|
|
176
206
|
}
|
|
@@ -202,14 +232,19 @@ export async function executeCall(
|
|
|
202
232
|
}
|
|
203
233
|
|
|
204
234
|
try {
|
|
235
|
+
assertMcpStateLease(assertActive);
|
|
205
236
|
if (state.ui) {
|
|
206
237
|
state.ui.setStatus("mcp", `MCP: connecting to ${serverName}...`);
|
|
207
238
|
}
|
|
208
|
-
connection = await state.manager.connect(serverName, definition);
|
|
239
|
+
connection = await waitForCaller(() => state.manager.connect(serverName, definition), signal);
|
|
240
|
+
signal?.throwIfAborted();
|
|
241
|
+
assertMcpStateLease(assertActive);
|
|
209
242
|
if (connection.status === "needs-auth") {
|
|
210
243
|
if (!autoAuthAttempted) {
|
|
211
244
|
autoAuthAttempted = true;
|
|
212
|
-
const autoAuth = await
|
|
245
|
+
const autoAuth = await waitForCaller(() => startAutoAuth(state, serverName!), signal);
|
|
246
|
+
signal?.throwIfAborted();
|
|
247
|
+
assertMcpStateLease(assertActive);
|
|
213
248
|
if (autoAuth.status === "failed") {
|
|
214
249
|
return {
|
|
215
250
|
content: [{ type: "text" as const, text: autoAuth.message }],
|
|
@@ -217,8 +252,12 @@ export async function executeCall(
|
|
|
217
252
|
};
|
|
218
253
|
}
|
|
219
254
|
if (autoAuth.status === "success") {
|
|
220
|
-
await state.manager.close(serverName);
|
|
221
|
-
|
|
255
|
+
await waitForCaller(() => state.manager.close(serverName!), signal);
|
|
256
|
+
signal?.throwIfAborted();
|
|
257
|
+
assertMcpStateLease(assertActive);
|
|
258
|
+
connection = await waitForCaller(() => state.manager.connect(serverName, definition), signal);
|
|
259
|
+
signal?.throwIfAborted();
|
|
260
|
+
assertMcpStateLease(assertActive);
|
|
222
261
|
}
|
|
223
262
|
}
|
|
224
263
|
|
|
@@ -230,6 +269,7 @@ export async function executeCall(
|
|
|
230
269
|
};
|
|
231
270
|
}
|
|
232
271
|
}
|
|
272
|
+
assertMcpStateLease(assertActive);
|
|
233
273
|
state.failureTracker.delete(serverName);
|
|
234
274
|
updateServerMetadata(state, serverName);
|
|
235
275
|
updateMetadataCache(state, serverName);
|
|
@@ -246,6 +286,8 @@ export async function executeCall(
|
|
|
246
286
|
};
|
|
247
287
|
}
|
|
248
288
|
} catch (error) {
|
|
289
|
+
signal?.throwIfAborted();
|
|
290
|
+
assertMcpStateLease(assertActive);
|
|
249
291
|
state.failureTracker.set(serverName, Date.now());
|
|
250
292
|
updateStatusBar(state);
|
|
251
293
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -259,11 +301,15 @@ export async function executeCall(
|
|
|
259
301
|
let uiSession: UiSessionRuntime | null = null;
|
|
260
302
|
|
|
261
303
|
try {
|
|
304
|
+
assertMcpStateLease(assertActive);
|
|
262
305
|
state.manager.touch(serverName);
|
|
263
306
|
state.manager.incrementInFlight(serverName);
|
|
264
307
|
|
|
265
308
|
if (toolMeta.resourceUri) {
|
|
266
|
-
|
|
309
|
+
assertMcpStateLease(assertActive);
|
|
310
|
+
const result = await connection.client.readResource({ uri: toolMeta.resourceUri }, { signal });
|
|
311
|
+
signal?.throwIfAborted();
|
|
312
|
+
assertMcpStateLease(assertActive);
|
|
267
313
|
const content = (result.contents ?? []).map(c => ({
|
|
268
314
|
type: "text" as const,
|
|
269
315
|
text: "text" in c ? c.text : ("blob" in c ? `[Binary data: ${(c as { mimeType?: string }).mimeType ?? "unknown"}]` : JSON.stringify(c)),
|
|
@@ -275,15 +321,24 @@ export async function executeCall(
|
|
|
275
321
|
}
|
|
276
322
|
|
|
277
323
|
uiSession = toolMeta.uiResourceUri
|
|
278
|
-
? await
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
324
|
+
? await waitForCallerWithLateCleanup(
|
|
325
|
+
() => maybeStartUiSession(state, {
|
|
326
|
+
serverName,
|
|
327
|
+
toolName: toolMeta.originalName,
|
|
328
|
+
toolArgs: args ?? {},
|
|
329
|
+
uiResourceUri: toolMeta.uiResourceUri!,
|
|
330
|
+
streamMode: toolMeta.uiStreamMode,
|
|
331
|
+
}),
|
|
332
|
+
signal,
|
|
333
|
+
(lateSession) => {
|
|
334
|
+
if (lateSession && !lateSession.reused) lateSession.close("caller cancelled during UI startup");
|
|
335
|
+
},
|
|
336
|
+
)
|
|
285
337
|
: null;
|
|
338
|
+
signal?.throwIfAborted();
|
|
339
|
+
assertMcpStateLease(assertActive);
|
|
286
340
|
|
|
341
|
+
assertMcpStateLease(assertActive);
|
|
287
342
|
const resultPromise = connection.client.callTool({
|
|
288
343
|
name: toolMeta.originalName,
|
|
289
344
|
// Normalize provider-flattened argument keys (e.g. Gemini's `keywords[0]`)
|
|
@@ -292,11 +347,14 @@ export async function executeCall(
|
|
|
292
347
|
// preserved unless the schema proves the head is a container.
|
|
293
348
|
arguments: unflattenToolArguments(args, toolMeta.inputSchema),
|
|
294
349
|
_meta: uiSession?.requestMeta,
|
|
295
|
-
});
|
|
350
|
+
}, CallToolResultSchema, { signal });
|
|
296
351
|
|
|
297
352
|
if (toolMeta.uiResourceUri) {
|
|
298
|
-
const
|
|
299
|
-
|
|
353
|
+
const sdkResult = await resultPromise;
|
|
354
|
+
signal?.throwIfAborted();
|
|
355
|
+
assertMcpStateLease(assertActive);
|
|
356
|
+
const result = asCallToolResult(sdkResult);
|
|
357
|
+
uiSession?.sendToolResult(result);
|
|
300
358
|
const mcpContent = (result.content ?? []) as McpContent[];
|
|
301
359
|
const content = transformMcpContent(mcpContent);
|
|
302
360
|
|
|
@@ -326,7 +384,10 @@ export async function executeCall(
|
|
|
326
384
|
};
|
|
327
385
|
}
|
|
328
386
|
|
|
329
|
-
const
|
|
387
|
+
const sdkResult = await resultPromise;
|
|
388
|
+
signal?.throwIfAborted();
|
|
389
|
+
assertMcpStateLease(assertActive);
|
|
390
|
+
const result = asCallToolResult(sdkResult);
|
|
330
391
|
|
|
331
392
|
const mcpContent = (result.content ?? []) as McpContent[];
|
|
332
393
|
const content = transformMcpContent(mcpContent);
|
|
@@ -353,8 +414,11 @@ export async function executeCall(
|
|
|
353
414
|
details: { mode: "call", mcpResult: result, server: serverName, tool: toolMeta.originalName },
|
|
354
415
|
};
|
|
355
416
|
} catch (error) {
|
|
417
|
+
await rethrowHostAbortAfterUiCancellation(signal, uiSession);
|
|
356
418
|
const message = error instanceof Error ? error.message : String(error);
|
|
357
|
-
uiSession
|
|
419
|
+
await notifyUiCancellation(uiSession, message);
|
|
420
|
+
signal?.throwIfAborted();
|
|
421
|
+
assertMcpStateLease(assertActive);
|
|
358
422
|
|
|
359
423
|
let errorWithSchema = `Failed to call tool: ${message}`;
|
|
360
424
|
if (toolMeta.inputSchema) {
|
|
@@ -366,10 +430,17 @@ export async function executeCall(
|
|
|
366
430
|
details: { mode: "call", error: "call_failed", message },
|
|
367
431
|
};
|
|
368
432
|
} finally {
|
|
369
|
-
|
|
370
|
-
|
|
433
|
+
let staleState = false;
|
|
434
|
+
try {
|
|
435
|
+
assertMcpStateLease(assertActive);
|
|
436
|
+
} catch (error) {
|
|
437
|
+
if (error instanceof McpStateChangedError) staleState = true;
|
|
438
|
+
else throw error;
|
|
439
|
+
}
|
|
440
|
+
if (uiSession && (uiSession.reused || staleState)) {
|
|
441
|
+
uiSession.close(staleState ? "stale MCP session" : undefined);
|
|
371
442
|
}
|
|
372
443
|
state.manager.decrementInFlight(serverName);
|
|
373
|
-
state.manager.touch(serverName);
|
|
444
|
+
if (!staleState) state.manager.touch(serverName);
|
|
374
445
|
}
|
|
375
446
|
}
|
|
@@ -1,11 +1,21 @@
|
|
|
1
|
-
import type { McpExtensionState } from "./state.
|
|
2
|
-
import { updateMetadataCache, updateStatusBar } from "./init.
|
|
3
|
-
import { buildToolMetadata } from "./tool-metadata.
|
|
4
|
-
import { attemptAutoAuth, getAuthRequiredMessage } from "./proxy-auth.
|
|
5
|
-
import { executeList } from "./proxy-info-modes.
|
|
6
|
-
import type { ProxyToolResult } from "./proxy-types.
|
|
1
|
+
import type { McpExtensionState } from "./state.js";
|
|
2
|
+
import { updateMetadataCache, updateStatusBar } from "./init.js";
|
|
3
|
+
import { buildToolMetadata } from "./tool-metadata.js";
|
|
4
|
+
import { attemptAutoAuth, getAuthRequiredMessage, type AutoAuthResult } from "./proxy-auth.js";
|
|
5
|
+
import { executeList } from "./proxy-info-modes.js";
|
|
6
|
+
import type { ProxyToolResult } from "./proxy-types.js";
|
|
7
|
+
import { waitForCaller } from "./caller-wait.js";
|
|
8
|
+
import { assertMcpStateLease, type AssertMcpStateLease } from "./state-lease.js";
|
|
7
9
|
|
|
8
|
-
export async function executeConnect(
|
|
10
|
+
export async function executeConnect(
|
|
11
|
+
state: McpExtensionState,
|
|
12
|
+
serverName: string,
|
|
13
|
+
signal?: AbortSignal,
|
|
14
|
+
startAutoAuth: (state: McpExtensionState, serverName: string) => Promise<AutoAuthResult> = attemptAutoAuth,
|
|
15
|
+
assertActive?: AssertMcpStateLease,
|
|
16
|
+
): Promise<ProxyToolResult> {
|
|
17
|
+
signal?.throwIfAborted();
|
|
18
|
+
assertMcpStateLease(assertActive);
|
|
9
19
|
const definition = state.config.mcpServers[serverName];
|
|
10
20
|
if (!definition) {
|
|
11
21
|
return {
|
|
@@ -15,12 +25,15 @@ export async function executeConnect(state: McpExtensionState, serverName: strin
|
|
|
15
25
|
}
|
|
16
26
|
|
|
17
27
|
try {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
28
|
+
assertMcpStateLease(assertActive);
|
|
29
|
+
if (state.ui) state.ui.setStatus("mcp", `MCP: connecting to ${serverName}...`);
|
|
30
|
+
let connection = await waitForCaller(() => state.manager.connect(serverName, definition), signal);
|
|
31
|
+
signal?.throwIfAborted();
|
|
32
|
+
assertMcpStateLease(assertActive);
|
|
22
33
|
if (connection.status === "needs-auth") {
|
|
23
|
-
const autoAuth = await
|
|
34
|
+
const autoAuth = await waitForCaller(() => startAutoAuth(state, serverName), signal);
|
|
35
|
+
signal?.throwIfAborted();
|
|
36
|
+
assertMcpStateLease(assertActive);
|
|
24
37
|
if (autoAuth.status === "failed") {
|
|
25
38
|
return {
|
|
26
39
|
content: [{ type: "text" as const, text: autoAuth.message }],
|
|
@@ -28,8 +41,12 @@ export async function executeConnect(state: McpExtensionState, serverName: strin
|
|
|
28
41
|
};
|
|
29
42
|
}
|
|
30
43
|
if (autoAuth.status === "success") {
|
|
31
|
-
await state.manager.close(serverName);
|
|
32
|
-
|
|
44
|
+
await waitForCaller(() => state.manager.close(serverName), signal);
|
|
45
|
+
signal?.throwIfAborted();
|
|
46
|
+
assertMcpStateLease(assertActive);
|
|
47
|
+
connection = await waitForCaller(() => state.manager.connect(serverName, definition), signal);
|
|
48
|
+
signal?.throwIfAborted();
|
|
49
|
+
assertMcpStateLease(assertActive);
|
|
33
50
|
}
|
|
34
51
|
if (connection.status === "needs-auth") {
|
|
35
52
|
const message = getAuthRequiredMessage(state, serverName);
|
|
@@ -39,14 +56,17 @@ export async function executeConnect(state: McpExtensionState, serverName: strin
|
|
|
39
56
|
};
|
|
40
57
|
}
|
|
41
58
|
}
|
|
59
|
+
assertMcpStateLease(assertActive);
|
|
42
60
|
const prefix = state.config.settings?.toolPrefix ?? "server";
|
|
43
61
|
const { metadata } = buildToolMetadata(connection.tools, connection.resources, definition, serverName, prefix);
|
|
44
62
|
state.toolMetadata.set(serverName, metadata);
|
|
45
63
|
updateMetadataCache(state, serverName);
|
|
46
64
|
state.failureTracker.delete(serverName);
|
|
47
65
|
updateStatusBar(state);
|
|
48
|
-
return executeList(state, serverName);
|
|
66
|
+
return executeList(state, serverName, signal, assertActive);
|
|
49
67
|
} catch (error) {
|
|
68
|
+
signal?.throwIfAborted();
|
|
69
|
+
assertMcpStateLease(assertActive);
|
|
50
70
|
state.failureTracker.set(serverName, Date.now());
|
|
51
71
|
updateStatusBar(state);
|
|
52
72
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-
import type { McpExtensionState } from "./state.
|
|
2
|
-
import type { ToolMetadata } from "./types.
|
|
3
|
-
import { getServerPrefix, parseUiPromptHandoff } from "./types.
|
|
4
|
-
import { getFailureAgeSeconds } from "./init.
|
|
5
|
-
import { findToolByName, formatSchema } from "./tool-metadata.
|
|
6
|
-
import { truncateAtWord } from "./utils.
|
|
7
|
-
import { hydrateMissingMetadata } from "./metadata-hydration.
|
|
8
|
-
import type { ProxyToolResult } from "./proxy-types.
|
|
9
|
-
|
|
10
|
-
|
|
1
|
+
import type { McpExtensionState } from "./state.js";
|
|
2
|
+
import type { ToolMetadata } from "./types.js";
|
|
3
|
+
import { getServerPrefix, parseUiPromptHandoff } from "./types.js";
|
|
4
|
+
import { getFailureAgeSeconds } from "./init.js";
|
|
5
|
+
import { findToolByName, formatSchema } from "./tool-metadata.js";
|
|
6
|
+
import { truncateAtWord } from "./utils.js";
|
|
7
|
+
import { hydrateMissingMetadata } from "./metadata-hydration.js";
|
|
8
|
+
import type { ProxyToolResult } from "./proxy-types.js";
|
|
9
|
+
import { assertMcpStateLease, type AssertMcpStateLease } from "./state-lease.js";
|
|
10
|
+
|
|
11
|
+
export function executeUiMessages(state: McpExtensionState, assertActive?: AssertMcpStateLease): ProxyToolResult {
|
|
12
|
+
assertMcpStateLease(assertActive);
|
|
11
13
|
const sessions = state.completedUiSessions;
|
|
12
14
|
|
|
13
15
|
if (sessions.length === 0) {
|
|
@@ -71,6 +73,7 @@ export function executeUiMessages(state: McpExtensionState): ProxyToolResult {
|
|
|
71
73
|
}
|
|
72
74
|
|
|
73
75
|
const count = sessions.length;
|
|
76
|
+
assertMcpStateLease(assertActive);
|
|
74
77
|
state.completedUiSessions = [];
|
|
75
78
|
|
|
76
79
|
return {
|
|
@@ -85,7 +88,8 @@ export function executeUiMessages(state: McpExtensionState): ProxyToolResult {
|
|
|
85
88
|
};
|
|
86
89
|
}
|
|
87
90
|
|
|
88
|
-
export function executeStatus(state: McpExtensionState): ProxyToolResult {
|
|
91
|
+
export function executeStatus(state: McpExtensionState, assertActive?: AssertMcpStateLease): ProxyToolResult {
|
|
92
|
+
assertMcpStateLease(assertActive);
|
|
89
93
|
const servers: Array<{ name: string; status: string; toolCount: number; failedAgo: number | null }> = [];
|
|
90
94
|
|
|
91
95
|
for (const name of Object.keys(state.config.mcpServers)) {
|
|
@@ -169,33 +173,46 @@ function prefixHydrationCandidates(state: McpExtensionState, toolName: string):
|
|
|
169
173
|
.map(({ serverName }) => serverName);
|
|
170
174
|
}
|
|
171
175
|
|
|
172
|
-
async function hydrateDescribeMetadata(
|
|
176
|
+
async function hydrateDescribeMetadata(
|
|
177
|
+
state: McpExtensionState,
|
|
178
|
+
toolName: string,
|
|
179
|
+
server?: string,
|
|
180
|
+
signal?: AbortSignal,
|
|
181
|
+
assertActive?: AssertMcpStateLease,
|
|
182
|
+
): Promise<void> {
|
|
183
|
+
signal?.throwIfAborted();
|
|
184
|
+
assertMcpStateLease(assertActive);
|
|
173
185
|
if (server) {
|
|
174
|
-
await hydrateMissingMetadata(state, { server });
|
|
186
|
+
await hydrateMissingMetadata(state, { server }, signal, assertActive);
|
|
175
187
|
return;
|
|
176
188
|
}
|
|
177
189
|
|
|
178
190
|
const candidates = prefixHydrationCandidates(state, toolName);
|
|
179
191
|
if (candidates.length > 0) {
|
|
180
192
|
for (const candidate of candidates) {
|
|
181
|
-
await hydrateMissingMetadata(state, { server: candidate });
|
|
193
|
+
await hydrateMissingMetadata(state, { server: candidate }, signal, assertActive);
|
|
182
194
|
if (findToolMetadata(state, toolName, candidate)) return;
|
|
183
195
|
}
|
|
184
196
|
return;
|
|
185
197
|
}
|
|
186
198
|
|
|
187
199
|
if (findToolMetadata(state, toolName)) return;
|
|
188
|
-
await hydrateMissingMetadata(state);
|
|
200
|
+
await hydrateMissingMetadata(state, undefined, signal, assertActive);
|
|
189
201
|
}
|
|
190
202
|
|
|
191
203
|
export async function executeDescribe(
|
|
192
204
|
state: McpExtensionState,
|
|
193
205
|
toolName: string,
|
|
194
206
|
server?: string,
|
|
207
|
+
signal?: AbortSignal,
|
|
208
|
+
assertActive?: AssertMcpStateLease,
|
|
195
209
|
): Promise<ProxyToolResult> {
|
|
210
|
+
signal?.throwIfAborted();
|
|
211
|
+
assertMcpStateLease(assertActive);
|
|
196
212
|
let found = findToolMetadata(state, toolName, server);
|
|
197
213
|
if (!found) {
|
|
198
|
-
await hydrateDescribeMetadata(state, toolName, server);
|
|
214
|
+
await hydrateDescribeMetadata(state, toolName, server, signal, assertActive);
|
|
215
|
+
assertMcpStateLease(assertActive);
|
|
199
216
|
found = findToolMetadata(state, toolName, server);
|
|
200
217
|
}
|
|
201
218
|
|
|
@@ -235,7 +252,11 @@ export async function executeSearch(
|
|
|
235
252
|
regex?: boolean,
|
|
236
253
|
server?: string,
|
|
237
254
|
includeSchemas?: boolean,
|
|
255
|
+
signal?: AbortSignal,
|
|
256
|
+
assertActive?: AssertMcpStateLease,
|
|
238
257
|
): Promise<ProxyToolResult> {
|
|
258
|
+
signal?.throwIfAborted();
|
|
259
|
+
assertMcpStateLease(assertActive);
|
|
239
260
|
const showSchemas = includeSchemas !== false;
|
|
240
261
|
|
|
241
262
|
const matches: Array<{ server: string; tool: ToolMetadata }> = [];
|
|
@@ -261,7 +282,8 @@ export async function executeSearch(
|
|
|
261
282
|
details: { mode: "search", error: "invalid_pattern", query },
|
|
262
283
|
};
|
|
263
284
|
}
|
|
264
|
-
await hydrateMissingMetadata(state, { server });
|
|
285
|
+
await hydrateMissingMetadata(state, { server }, signal, assertActive);
|
|
286
|
+
assertMcpStateLease(assertActive);
|
|
265
287
|
|
|
266
288
|
for (const [serverName, metadata] of state.toolMetadata.entries()) {
|
|
267
289
|
if (server && serverName !== server) continue;
|
|
@@ -319,7 +341,14 @@ export async function executeSearch(
|
|
|
319
341
|
};
|
|
320
342
|
}
|
|
321
343
|
|
|
322
|
-
export async function executeList(
|
|
344
|
+
export async function executeList(
|
|
345
|
+
state: McpExtensionState,
|
|
346
|
+
server: string,
|
|
347
|
+
signal?: AbortSignal,
|
|
348
|
+
assertActive?: AssertMcpStateLease,
|
|
349
|
+
): Promise<ProxyToolResult> {
|
|
350
|
+
signal?.throwIfAborted();
|
|
351
|
+
assertMcpStateLease(assertActive);
|
|
323
352
|
if (!state.config.mcpServers[server]) {
|
|
324
353
|
return {
|
|
325
354
|
content: [{ type: "text" as const, text: `Server "${server}" not found. Use mcp({}) to see available servers.` }],
|
|
@@ -328,7 +357,8 @@ export async function executeList(state: McpExtensionState, server: string): Pro
|
|
|
328
357
|
}
|
|
329
358
|
|
|
330
359
|
if (!state.toolMetadata.has(server)) {
|
|
331
|
-
await hydrateMissingMetadata(state, { server });
|
|
360
|
+
await hydrateMissingMetadata(state, { server }, signal, assertActive);
|
|
361
|
+
assertMcpStateLease(assertActive);
|
|
332
362
|
}
|
|
333
363
|
|
|
334
364
|
const metadata = state.toolMetadata.get(server);
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { executeUiMessages, executeStatus, executeDescribe, executeSearch, executeList } from "./proxy-info-modes.
|
|
2
|
-
export { executeConnect } from "./proxy-connect.
|
|
3
|
-
export { executeCall } from "./proxy-call.
|
|
1
|
+
export { executeUiMessages, executeStatus, executeDescribe, executeSearch, executeList } from "./proxy-info-modes.js";
|
|
2
|
+
export { executeConnect } from "./proxy-connect.js";
|
|
3
|
+
export { executeCall } from "./proxy-call.js";
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Retain teardown work across MCP lifecycle generations without allowing a
|
|
3
|
+
* non-abortable producer to block every later generation forever.
|
|
4
|
+
*/
|
|
5
|
+
type CleanupTask = PromiseLike<object | string | void>;
|
|
6
|
+
|
|
7
|
+
const DEFAULT_CLEANUP_DEADLINE_MS = 2_000;
|
|
8
|
+
|
|
9
|
+
function observeWithin(task: CleanupTask, deadlineMs: number, onTimeout: () => void): Promise<void> {
|
|
10
|
+
const observed = Promise.resolve(task).then(() => undefined, () => undefined);
|
|
11
|
+
let timer: ReturnType<typeof setTimeout> | undefined;
|
|
12
|
+
const deadline = new Promise<void>((resolve) => {
|
|
13
|
+
timer = setTimeout(() => {
|
|
14
|
+
onTimeout();
|
|
15
|
+
resolve();
|
|
16
|
+
}, deadlineMs);
|
|
17
|
+
timer.unref?.();
|
|
18
|
+
});
|
|
19
|
+
return Promise.race([observed, deadline]).finally(() => {
|
|
20
|
+
if (timer) clearTimeout(timer);
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export class McpSessionCleanupBarrier {
|
|
25
|
+
private settled: Promise<void> = Promise.resolve();
|
|
26
|
+
|
|
27
|
+
constructor(private readonly deadlineMs = DEFAULT_CLEANUP_DEADLINE_MS) {}
|
|
28
|
+
|
|
29
|
+
wait(): Promise<void> {
|
|
30
|
+
return this.settled;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
retain(tasks: readonly (CleanupTask | null | undefined)[]): Promise<void> {
|
|
34
|
+
const observed = tasks.filter((task): task is CleanupTask => task !== null && task !== undefined);
|
|
35
|
+
const prior = this.settled;
|
|
36
|
+
const next = Promise.all([
|
|
37
|
+
observeWithin(prior, this.deadlineMs, () => console.error("MCP: prior cleanup exceeded its deadline; continuing with fenced state")),
|
|
38
|
+
...observed.map((task) => observeWithin(task, this.deadlineMs, () => console.error("MCP: cleanup task exceeded its deadline; continuing with fenced state"))),
|
|
39
|
+
]).then(() => undefined);
|
|
40
|
+
this.settled = next;
|
|
41
|
+
return next;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export type AssertMcpStateLease = () => void;
|
|
2
|
+
|
|
3
|
+
export class McpStateChangedError extends Error {
|
|
4
|
+
constructor() {
|
|
5
|
+
super("MCP session changed during execution");
|
|
6
|
+
this.name = "McpStateChangedError";
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function assertMcpStateLease(assertActive?: AssertMcpStateLease): void {
|
|
11
|
+
assertActive?.();
|
|
12
|
+
}
|
|
@@ -7,12 +7,12 @@ import type {
|
|
|
7
7
|
CallToolRequest,
|
|
8
8
|
CallToolResult,
|
|
9
9
|
} from "@modelcontextprotocol/sdk/types.js";
|
|
10
|
-
import type { ConsentManager } from "./consent-manager.
|
|
11
|
-
import { ServerError, wrapError } from "./errors.
|
|
12
|
-
import { buildHostHtmlTemplate, buildCspMetaContent, applyCspMeta } from "./host-html-template.
|
|
13
|
-
import { logger } from "./logger.
|
|
14
|
-
import { parseBody, sendJson, validateTokenBody, validateTokenQuery } from "./ui-server-http.
|
|
15
|
-
import type { McpServerManager } from "./server-manager.
|
|
10
|
+
import type { ConsentManager } from "./consent-manager.js";
|
|
11
|
+
import { ServerError, wrapError } from "./errors.js";
|
|
12
|
+
import { buildHostHtmlTemplate, buildCspMetaContent, applyCspMeta } from "./host-html-template.js";
|
|
13
|
+
import { logger } from "./logger.js";
|
|
14
|
+
import { parseBody, sendJson, validateTokenBody, validateTokenQuery } from "./ui-server-http.js";
|
|
15
|
+
import type { McpServerManager } from "./server-manager.js";
|
|
16
16
|
import {
|
|
17
17
|
extractUiPromptText,
|
|
18
18
|
getVisualizationStreamEnvelope,
|
|
@@ -26,7 +26,7 @@ import {
|
|
|
26
26
|
type UiResourceContent,
|
|
27
27
|
type UiSessionMessages,
|
|
28
28
|
type UiStreamSummary,
|
|
29
|
-
} from "./types.
|
|
29
|
+
} from "./types.js";
|
|
30
30
|
|
|
31
31
|
const ABANDONED_GRACE_MS = 60_000;
|
|
32
32
|
const WATCHDOG_INTERVAL_MS = 5_000;
|
|
@@ -58,7 +58,7 @@ export interface UiServerHandle {
|
|
|
58
58
|
sendToolInput: (args: Record<string, unknown>) => void;
|
|
59
59
|
sendToolResult: (result: CallToolResult) => void;
|
|
60
60
|
sendResultPatch: (result: CallToolResult) => void;
|
|
61
|
-
sendToolCancelled: (reason: string) => void
|
|
61
|
+
sendToolCancelled: (reason: string) => void | Promise<void>;
|
|
62
62
|
sendHostContext: (context: UiHostContext) => void;
|
|
63
63
|
/** Get accumulated messages from this session */
|
|
64
64
|
getSessionMessages: () => UiSessionMessages;
|