@bastani/atomic 0.9.5-alpha.8 → 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 +122 -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 +38 -0
- package/dist/builtin/mcp/OAUTH.md +1 -0
- package/dist/builtin/mcp/README.md +10 -6
- 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 +40 -255
- package/dist/builtin/mcp/host-html-template.ts +4 -2
- package/dist/builtin/mcp/index.ts +274 -239
- package/dist/builtin/mcp/init.ts +96 -126
- 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 +52 -0
- 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 +106 -23
- package/dist/builtin/mcp/proxy-modes.ts +3 -3
- package/dist/builtin/mcp/session-cleanup-barrier.ts +43 -0
- package/dist/builtin/mcp/startup-warmup.ts +98 -0
- package/dist/builtin/mcp/state-lease.ts +12 -0
- package/dist/builtin/mcp/tool-result-renderer.ts +3 -3
- package/dist/builtin/mcp/ui-server.ts +8 -8
- package/dist/builtin/mcp/ui-session.ts +9 -18
- package/dist/builtin/subagents/CHANGELOG.md +78 -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 +289 -320
- 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/startup-maintenance.ts +89 -0
- 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 +26 -20
- 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 +177 -233
- 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 +29 -15
- 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 +63 -46
- 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 +55 -12
- 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 +157 -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 +86 -0
- package/dist/builtin/workflows/README.md +5 -5
- package/dist/builtin/workflows/builtin/deep-research-codebase-utils.ts +27 -4
- package/dist/builtin/workflows/builtin/goal-runner.ts +86 -27
- 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/skills/impeccable/SKILL.md +16 -13
- package/dist/builtin/workflows/skills/impeccable/reference/adapt.md +1 -0
- package/dist/builtin/workflows/skills/impeccable/reference/adapt.native.md +58 -0
- package/dist/builtin/workflows/skills/impeccable/reference/android.md +40 -0
- package/dist/builtin/workflows/skills/impeccable/reference/animate.md +2 -0
- package/dist/builtin/workflows/skills/impeccable/reference/audit.md +2 -0
- package/dist/builtin/workflows/skills/impeccable/reference/audit.native.md +139 -0
- package/dist/builtin/workflows/skills/impeccable/reference/bolder.md +69 -62
- package/dist/builtin/workflows/skills/impeccable/reference/critique.md +21 -7
- package/dist/builtin/workflows/skills/impeccable/reference/document.md +1 -1
- package/dist/builtin/workflows/skills/impeccable/reference/hooks.md +92 -0
- package/dist/builtin/workflows/skills/impeccable/reference/init.md +29 -7
- package/dist/builtin/workflows/skills/impeccable/reference/ios.md +45 -0
- package/dist/builtin/workflows/skills/impeccable/reference/layout.md +25 -1
- package/dist/builtin/workflows/skills/impeccable/reference/typeset.md +23 -1
- package/dist/builtin/workflows/skills/impeccable/scripts/context-signals.mjs +2 -1
- package/dist/builtin/workflows/skills/impeccable/scripts/context.mjs +75 -14
- package/dist/builtin/workflows/skills/impeccable/scripts/detector/browser/injected/index.mjs +1 -1
- package/dist/builtin/workflows/skills/impeccable/scripts/detector/cli/main.mjs +31 -0
- package/dist/builtin/workflows/skills/impeccable/scripts/detector/design-system.mjs +64 -0
- package/dist/builtin/workflows/skills/impeccable/scripts/detector/detect-antipatterns-browser.js +118 -11
- package/dist/builtin/workflows/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs +16 -11
- package/dist/builtin/workflows/skills/impeccable/scripts/detector/registry/antipatterns.mjs +66 -0
- package/dist/builtin/workflows/skills/impeccable/scripts/detector/rules/checks.mjs +42 -10
- package/dist/builtin/workflows/skills/impeccable/scripts/detector/shared/fonts.mjs +30 -0
- package/dist/builtin/workflows/skills/impeccable/scripts/detector/shared/page.mjs +4 -6
- package/dist/builtin/workflows/skills/impeccable/scripts/hook-admin.mjs +660 -0
- package/dist/builtin/workflows/skills/impeccable/scripts/hook-before-edit.mjs +516 -0
- package/dist/builtin/workflows/skills/impeccable/scripts/hook-lib.mjs +1764 -0
- package/dist/builtin/workflows/skills/impeccable/scripts/hook.mjs +61 -0
- package/dist/builtin/workflows/skills/impeccable/scripts/lib/impeccable-config.mjs +4 -2
- package/dist/builtin/workflows/skills/impeccable/scripts/lib/is-generated.mjs +2 -2
- package/dist/builtin/workflows/skills/impeccable/scripts/live/svelte-component.mjs +13 -16
- package/dist/builtin/workflows/skills/impeccable/scripts/live-accept.mjs +17 -11
- package/dist/builtin/workflows/skills/impeccable/scripts/live-browser.js +104 -37
- package/dist/builtin/workflows/skills/impeccable/scripts/live-wrap.mjs +9 -0
- package/dist/builtin/workflows/src/durable/backend.ts +12 -0
- package/dist/builtin/workflows/src/durable/dbos-backend.ts +17 -1
- package/dist/builtin/workflows/src/durable/resume-catalog.ts +12 -0
- package/dist/builtin/workflows/src/durable/resume-runtime.ts +5 -2
- package/dist/builtin/workflows/src/durable/stage-primitive.ts +2 -1
- package/dist/builtin/workflows/src/durable/types.ts +16 -0
- package/dist/builtin/workflows/src/engine/primitives/task.ts +3 -1
- package/dist/builtin/workflows/src/engine/run-durable-finalize.ts +1 -2
- package/dist/builtin/workflows/src/engine/run-returned-status.ts +50 -16
- package/dist/builtin/workflows/src/engine/run.ts +20 -19
- package/dist/builtin/workflows/src/engine/runtime.ts +5 -0
- package/dist/builtin/workflows/src/extension/extension-factory.ts +3 -0
- package/dist/builtin/workflows/src/extension/extension-lifecycle.ts +9 -2
- package/dist/builtin/workflows/src/extension/extension-runtime-state.ts +137 -27
- package/dist/builtin/workflows/src/extension/lifecycle-notifications.ts +22 -6
- package/dist/builtin/workflows/src/extension/public-types.ts +1 -1
- package/dist/builtin/workflows/src/extension/workflow-command-completions.ts +13 -1
- package/dist/builtin/workflows/src/extension/workflow-command-registration.ts +19 -4
- package/dist/builtin/workflows/src/extension/workflow-command-surfaces.ts +9 -0
- package/dist/builtin/workflows/src/extension/workflow-prompts.ts +17 -22
- package/dist/builtin/workflows/src/extension/workflow-run-control-command.ts +48 -23
- package/dist/builtin/workflows/src/extension/workflow-schema.ts +15 -2
- package/dist/builtin/workflows/src/extension/workflow-tool-control.ts +20 -8
- package/dist/builtin/workflows/src/extension/workflow-tool.ts +24 -8
- package/dist/builtin/workflows/src/runs/background/status.ts +4 -3
- package/dist/builtin/workflows/src/runs/foreground/executor-direct-helpers.ts +29 -8
- package/dist/builtin/workflows/src/runs/foreground/executor-hil.ts +1 -1
- package/dist/builtin/workflows/src/runs/foreground/executor-stage-factory.ts +3 -2
- package/dist/builtin/workflows/src/runs/shared/model-fallback-candidates.ts +1 -1
- package/dist/builtin/workflows/src/runs/shared/worktree-git.ts +155 -20
- package/dist/builtin/workflows/src/runs/shared/worktree-types.ts +6 -0
- package/dist/builtin/workflows/src/runs/shared/worktree.ts +2 -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/shared/returned-run-status.ts +116 -0
- package/dist/builtin/workflows/src/shared/workflow-failures-decisions.ts +2 -0
- package/dist/builtin/workflows/src/tui/graph-view-render-helpers.ts +21 -3
- package/dist/builtin/workflows/src/tui/graph-view-state.ts +3 -0
- package/dist/builtin/workflows/src/tui/graph-view-types.ts +3 -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/builtin/workflows/src/tui/status-list.ts +22 -15
- package/dist/builtin/workflows/src/tui/workflow-attach-pane.ts +4 -4
- 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-auto-compaction.d.ts +23 -3
- package/dist/core/agent-session-auto-compaction.d.ts.map +1 -1
- package/dist/core/agent-session-auto-compaction.js +129 -17
- package/dist/core/agent-session-auto-compaction.js.map +1 -1
- package/dist/core/agent-session-events.d.ts.map +1 -1
- package/dist/core/agent-session-events.js +9 -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-methods.d.ts +6 -3
- package/dist/core/agent-session-methods.d.ts.map +1 -1
- package/dist/core/agent-session-methods.js.map +1 -1
- package/dist/core/agent-session-prompt.d.ts.map +1 -1
- package/dist/core/agent-session-prompt.js +2 -2
- 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/agent-session.d.ts +4 -2
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +4 -2
- package/dist/core/agent-session.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/loader-virtual-modules.d.ts +8 -1
- package/dist/core/extensions/loader-virtual-modules.d.ts.map +1 -1
- package/dist/core/extensions/loader-virtual-modules.js +2 -1
- package/dist/core/extensions/loader-virtual-modules.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/footer-data-provider.d.ts +6 -0
- package/dist/core/footer-data-provider.d.ts.map +1 -1
- package/dist/core/footer-data-provider.js +72 -29
- package/dist/core/footer-data-provider.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/openai-responses-payload-sanitizer.d.ts +1 -0
- package/dist/core/openai-responses-payload-sanitizer.d.ts.map +1 -1
- package/dist/core/openai-responses-payload-sanitizer.js +24 -9
- package/dist/core/openai-responses-payload-sanitizer.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/slash-commands.d.ts +2 -0
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +141 -0
- package/dist/core/slash-commands.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/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/main-deferred-startup.d.ts.map +1 -1
- package/dist/main-deferred-startup.js +2 -2
- package/dist/main-deferred-startup.js.map +1 -1
- package/dist/main-early-input.d.ts.map +1 -1
- package/dist/main-early-input.js +7 -0
- package/dist/main-early-input.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/main.d.ts.map +1 -1
- package/dist/main.js +1 -1
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/chat-session-host-actions.d.ts.map +1 -1
- package/dist/modes/interactive/components/chat-session-host-actions.js +0 -1
- package/dist/modes/interactive/components/chat-session-host-actions.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 +3 -1
- package/dist/modes/interactive/interactive-agent-events.js.map +1 -1
- package/dist/modes/interactive/interactive-autocomplete.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-autocomplete.js +21 -9
- package/dist/modes/interactive/interactive-autocomplete.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 +43 -30
- package/dist/modes/interactive/interactive-deferred-startup.js.map +1 -1
- package/dist/modes/interactive/interactive-hotkeys-debug.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-hotkeys-debug.js +1 -0
- package/dist/modes/interactive/interactive-hotkeys-debug.js.map +1 -1
- package/dist/modes/interactive/interactive-input-handling.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-input-handling.js +41 -6
- package/dist/modes/interactive/interactive-input-handling.js.map +1 -1
- package/dist/modes/interactive/interactive-mode-base.d.ts +3 -0
- package/dist/modes/interactive/interactive-mode-base.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode-base.js +3 -0
- package/dist/modes/interactive/interactive-mode-base.js.map +1 -1
- package/dist/modes/interactive/interactive-mode-deps.d.ts +2 -2
- package/dist/modes/interactive/interactive-mode-deps.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode-deps.js +2 -2
- package/dist/modes/interactive/interactive-mode-deps.js.map +1 -1
- package/dist/modes/interactive/interactive-mode-surface.d.ts +2 -2
- package/dist/modes/interactive/interactive-mode-surface.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode-surface.js.map +1 -1
- package/dist/modes/interactive/interactive-model-routing.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-model-routing.js +11 -4
- package/dist/modes/interactive/interactive-model-routing.js.map +1 -1
- package/dist/modes/interactive/interactive-process-lifecycle.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-process-lifecycle.js +0 -3
- package/dist/modes/interactive/interactive-process-lifecycle.js.map +1 -1
- package/dist/modes/interactive/interactive-render-chat.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-render-chat.js +15 -1
- package/dist/modes/interactive/interactive-render-chat.js.map +1 -1
- package/dist/modes/interactive/interactive-session-routing.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-session-routing.js +5 -1
- package/dist/modes/interactive/interactive-session-routing.js.map +1 -1
- package/dist/modes/interactive/interactive-startup.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-startup.js +20 -21
- package/dist/modes/interactive/interactive-startup.js.map +1 -1
- package/dist/modes/interactive/theme/global-theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/global-theme.js +26 -2
- package/dist/modes/interactive/theme/global-theme.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/dist/utils/fs-watch.d.ts +24 -1
- package/dist/utils/fs-watch.d.ts.map +1 -1
- package/dist/utils/fs-watch.js +60 -5
- package/dist/utils/fs-watch.js.map +1 -1
- package/docs/changelog.mdx +19 -0
- package/docs/compaction.md +60 -49
- package/docs/custom-provider.md +18 -5
- package/docs/development.md +4 -0
- package/docs/extensions.md +11 -2
- package/docs/json.md +1 -1
- package/docs/models.md +69 -10
- package/docs/providers.md +1 -1
- package/docs/quickstart.md +12 -8
- package/docs/rpc.md +2 -2
- package/docs/sdk.md +1 -1
- package/docs/settings.md +4 -4
- package/docs/subagents.md +40 -5
- package/docs/tools.md +1 -1
- package/docs/usage.md +4 -2
- package/docs/windows.md +4 -0
- package/docs/workflows.md +33 -48
- 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,62 +1,76 @@
|
|
|
1
|
-
/**
|
|
2
|
-
|
|
3
|
-
*
|
|
4
|
-
* High-level OAuth flow management using the MCP SDK's built-in auth functions.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import {
|
|
8
|
-
auth as runSdkAuth,
|
|
9
|
-
UnauthorizedError,
|
|
10
|
-
} from "@modelcontextprotocol/sdk/client/auth.js"
|
|
1
|
+
/** High-level MCP OAuth flow management using the SDK auth helpers. */
|
|
2
|
+
import { auth as runSdkAuth, UnauthorizedError } from "@modelcontextprotocol/sdk/client/auth.js"
|
|
11
3
|
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js"
|
|
12
4
|
import open from "open"
|
|
13
|
-
import { McpOAuthProvider, type McpOAuthConfig } from "./mcp-oauth-provider.
|
|
5
|
+
import { McpOAuthProvider, type McpOAuthConfig } from "./mcp-oauth-provider.js"
|
|
14
6
|
import {
|
|
15
|
-
|
|
16
|
-
waitForCallback,
|
|
7
|
+
cancelAllPendingCallbacks,
|
|
17
8
|
cancelPendingCallback,
|
|
9
|
+
ensureCallbackServer,
|
|
18
10
|
stopCallbackServer,
|
|
19
|
-
|
|
11
|
+
waitForCallback,
|
|
12
|
+
} from "./mcp-callback-server.js"
|
|
20
13
|
import {
|
|
21
|
-
getAuthForUrl,
|
|
22
|
-
isTokenExpired,
|
|
23
|
-
hasStoredTokens,
|
|
24
14
|
clearAllCredentials,
|
|
25
15
|
clearClientInfo,
|
|
26
16
|
clearCodeVerifier,
|
|
27
|
-
updateOAuthState,
|
|
28
|
-
getOAuthState,
|
|
29
17
|
clearOAuthState,
|
|
18
|
+
getAuthForUrl,
|
|
19
|
+
getOAuthState,
|
|
20
|
+
hasStoredTokens,
|
|
21
|
+
isTokenExpired,
|
|
22
|
+
updateOAuthState,
|
|
30
23
|
type StoredTokens,
|
|
31
|
-
} from "./mcp-auth.
|
|
32
|
-
import
|
|
24
|
+
} from "./mcp-auth.js"
|
|
25
|
+
import { McpSessionCleanupBarrier } from "./session-cleanup-barrier.js"
|
|
26
|
+
import type { ServerEntry } from "./types.js"
|
|
33
27
|
|
|
34
|
-
/** Auth status for a server */
|
|
35
28
|
export type AuthStatus = "authenticated" | "expired" | "not_authenticated"
|
|
36
29
|
|
|
37
|
-
|
|
38
|
-
|
|
30
|
+
interface PendingTransport {
|
|
31
|
+
readonly serverName: string
|
|
32
|
+
readonly transport: StreamableHTTPClientTransport
|
|
33
|
+
readonly oauthState?: string
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
interface PendingAuthentication {
|
|
37
|
+
readonly serverName: string
|
|
38
|
+
readonly controller: AbortController
|
|
39
|
+
readonly result: Promise<AuthStatus>
|
|
40
|
+
readonly producer: Promise<AuthStatus>
|
|
41
|
+
readonly resolve: (status: AuthStatus) => void
|
|
42
|
+
readonly reject: (error: Error) => void
|
|
43
|
+
oauthState?: string
|
|
44
|
+
transport?: PendingTransport
|
|
45
|
+
}
|
|
39
46
|
|
|
40
|
-
|
|
41
|
-
const pendingAuthentications = new Map<string,
|
|
47
|
+
const pendingTransports = new Map<string, PendingTransport>()
|
|
48
|
+
const pendingAuthentications = new Map<string, PendingAuthentication>()
|
|
49
|
+
const closingTransports = new WeakMap<StreamableHTTPClientTransport, Promise<void>>()
|
|
50
|
+
const oauthCleanupBarrier = new McpSessionCleanupBarrier()
|
|
51
|
+
|
|
52
|
+
/** Actionable cancellation surfaced to callers whose session no longer owns OAuth. */
|
|
53
|
+
export class OAuthSessionResetError extends Error {
|
|
54
|
+
readonly code = "MCP_OAUTH_SESSION_RESET"
|
|
55
|
+
|
|
56
|
+
constructor(serverName: string | undefined, reason: string) {
|
|
57
|
+
const target = serverName ? ` for "${serverName}"` : ""
|
|
58
|
+
const readableReason = reason.replaceAll("_", " ")
|
|
59
|
+
super(
|
|
60
|
+
`MCP OAuth authentication${target} was cancelled because the MCP session was reset (${readableReason}). Retry authentication in the active session.`,
|
|
61
|
+
)
|
|
62
|
+
this.name = "OAuthSessionResetError"
|
|
63
|
+
}
|
|
64
|
+
}
|
|
42
65
|
|
|
43
|
-
/**
|
|
44
|
-
* Generate a cryptographically secure random state parameter.
|
|
45
|
-
*/
|
|
46
66
|
function generateState(): string {
|
|
47
67
|
return Array.from(crypto.getRandomValues(new Uint8Array(32)))
|
|
48
|
-
.map((
|
|
68
|
+
.map((byte) => byte.toString(16).padStart(2, "0"))
|
|
49
69
|
.join("")
|
|
50
70
|
}
|
|
51
71
|
|
|
52
|
-
/**
|
|
53
|
-
* Extract OAuth configuration from a ServerEntry.
|
|
54
|
-
*/
|
|
55
72
|
function extractOAuthConfig(definition: ServerEntry): McpOAuthConfig {
|
|
56
|
-
|
|
57
|
-
if (definition.oauth === false) {
|
|
58
|
-
return {}
|
|
59
|
-
}
|
|
73
|
+
if (definition.oauth === false) return {}
|
|
60
74
|
return {
|
|
61
75
|
grantType: definition.oauth?.grantType,
|
|
62
76
|
clientId: definition.oauth?.clientId,
|
|
@@ -65,298 +79,294 @@ function extractOAuthConfig(definition: ServerEntry): McpOAuthConfig {
|
|
|
65
79
|
}
|
|
66
80
|
}
|
|
67
81
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
82
|
+
function assertActive(owner?: PendingAuthentication): void {
|
|
83
|
+
owner?.controller.signal.throwIfAborted()
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function clearOwnedOAuthState(serverName: string, oauthState?: string): void {
|
|
87
|
+
if (oauthState && getOAuthState(serverName) === oauthState) clearOAuthState(serverName)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function closeTransport(transport: StreamableHTTPClientTransport): Promise<void> {
|
|
91
|
+
const existing = closingTransports.get(transport)
|
|
92
|
+
if (existing) return existing
|
|
93
|
+
const closing = transport.close().catch(() => undefined)
|
|
94
|
+
closingTransports.set(transport, closing)
|
|
95
|
+
return closing
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
async function retireTransport(serverName: string, pending: PendingTransport): Promise<void> {
|
|
99
|
+
if (pendingTransports.get(serverName) === pending) pendingTransports.delete(serverName)
|
|
100
|
+
await closeTransport(pending.transport)
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
interface StartedAuth {
|
|
104
|
+
readonly authorizationUrl: string
|
|
105
|
+
readonly oauthState?: string
|
|
106
|
+
readonly pendingTransport?: PendingTransport
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
async function startAuthAttempt(
|
|
73
110
|
serverName: string,
|
|
74
111
|
serverUrl: string,
|
|
75
|
-
definition?: ServerEntry
|
|
76
|
-
|
|
112
|
+
definition?: ServerEntry,
|
|
113
|
+
owner?: PendingAuthentication,
|
|
114
|
+
): Promise<StartedAuth> {
|
|
115
|
+
assertActive(owner)
|
|
77
116
|
const config = definition ? extractOAuthConfig(definition) : {}
|
|
78
|
-
|
|
79
|
-
const storedAuth = await getAuthForUrl(serverName, serverUrl)
|
|
117
|
+
const storedAuth = getAuthForUrl(serverName, serverUrl)
|
|
80
118
|
if (storedAuth?.clientInfo && !storedAuth.tokens && !config.clientId) {
|
|
81
119
|
clearClientInfo(serverName)
|
|
82
120
|
clearCodeVerifier(serverName)
|
|
83
|
-
|
|
121
|
+
clearOAuthState(serverName)
|
|
84
122
|
}
|
|
85
123
|
|
|
124
|
+
const providerCallbacks = {
|
|
125
|
+
onRedirect: async (_url: URL): Promise<void> => {
|
|
126
|
+
throw new Error("Browser redirect is not used for client_credentials flow")
|
|
127
|
+
},
|
|
128
|
+
assertActive: (): void => assertActive(owner),
|
|
129
|
+
}
|
|
86
130
|
if (config.grantType === "client_credentials") {
|
|
87
|
-
const authProvider = new McpOAuthProvider(serverName, serverUrl, config,
|
|
88
|
-
onRedirect: async () => {
|
|
89
|
-
throw new Error("Browser redirect is not used for client_credentials flow")
|
|
90
|
-
},
|
|
91
|
-
})
|
|
131
|
+
const authProvider = new McpOAuthProvider(serverName, serverUrl, config, providerCallbacks)
|
|
92
132
|
const result = await runSdkAuth(authProvider, { serverUrl })
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
}
|
|
133
|
+
assertActive(owner)
|
|
134
|
+
if (result !== "AUTHORIZED") throw new UnauthorizedError("Failed to authorize")
|
|
96
135
|
return { authorizationUrl: "" }
|
|
97
136
|
}
|
|
98
137
|
|
|
99
|
-
// Start the callback server.
|
|
100
|
-
// Pre-registered OAuth clients require an exact redirect URI, so enforce strict port binding.
|
|
101
138
|
await ensureCallbackServer({ strictPort: Boolean(config.clientId) })
|
|
102
|
-
|
|
139
|
+
assertActive(owner)
|
|
103
140
|
const oauthState = generateState()
|
|
104
|
-
|
|
141
|
+
if (owner) owner.oauthState = oauthState
|
|
142
|
+
updateOAuthState(serverName, oauthState, serverUrl)
|
|
105
143
|
|
|
106
144
|
let capturedUrl: URL | undefined
|
|
107
145
|
const authProvider = new McpOAuthProvider(serverName, serverUrl, config, {
|
|
108
|
-
onRedirect: async (url) => {
|
|
109
|
-
|
|
110
|
-
},
|
|
146
|
+
onRedirect: async (url) => { capturedUrl = url },
|
|
147
|
+
assertActive: (): void => assertActive(owner),
|
|
111
148
|
})
|
|
112
149
|
|
|
113
150
|
try {
|
|
114
151
|
const result = await runSdkAuth(authProvider, { serverUrl })
|
|
152
|
+
assertActive(owner)
|
|
115
153
|
if (result === "AUTHORIZED") {
|
|
116
|
-
|
|
117
|
-
return { authorizationUrl: "" }
|
|
154
|
+
clearOwnedOAuthState(serverName, oauthState)
|
|
155
|
+
return { authorizationUrl: "", oauthState }
|
|
118
156
|
}
|
|
119
|
-
if (!capturedUrl)
|
|
120
|
-
|
|
121
|
-
}
|
|
122
|
-
pendingTransports.set(
|
|
157
|
+
if (!capturedUrl) throw new UnauthorizedError("OAuth authorization URL was not provided")
|
|
158
|
+
const pendingTransport = {
|
|
123
159
|
serverName,
|
|
124
|
-
new StreamableHTTPClientTransport(new URL(serverUrl), { authProvider }),
|
|
125
|
-
|
|
126
|
-
|
|
160
|
+
transport: new StreamableHTTPClientTransport(new URL(serverUrl), { authProvider }),
|
|
161
|
+
oauthState,
|
|
162
|
+
}
|
|
163
|
+
pendingTransports.set(serverName, pendingTransport)
|
|
164
|
+
if (owner) owner.transport = pendingTransport
|
|
165
|
+
return { authorizationUrl: capturedUrl.toString(), oauthState, pendingTransport }
|
|
127
166
|
} catch (error) {
|
|
128
|
-
|
|
167
|
+
clearOwnedOAuthState(serverName, oauthState)
|
|
168
|
+
if (owner?.transport) await retireTransport(serverName, owner.transport)
|
|
129
169
|
throw error
|
|
130
170
|
}
|
|
131
171
|
}
|
|
132
172
|
|
|
133
|
-
/**
|
|
134
|
-
|
|
135
|
-
*/
|
|
136
|
-
export async function completeAuth(
|
|
173
|
+
/** Start OAuth and return the browser authorization URL when interaction is needed. */
|
|
174
|
+
export async function startAuth(
|
|
137
175
|
serverName: string,
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
176
|
+
serverUrl: string,
|
|
177
|
+
definition?: ServerEntry,
|
|
178
|
+
): Promise<{ authorizationUrl: string }> {
|
|
179
|
+
const { authorizationUrl } = await startAuthAttempt(serverName, serverUrl, definition)
|
|
180
|
+
return { authorizationUrl }
|
|
181
|
+
}
|
|
144
182
|
|
|
183
|
+
async function completePendingTransport(
|
|
184
|
+
serverName: string,
|
|
185
|
+
authorizationCode: string,
|
|
186
|
+
pending: PendingTransport,
|
|
187
|
+
): Promise<AuthStatus> {
|
|
145
188
|
try {
|
|
146
|
-
|
|
147
|
-
await transport.finishAuth(authorizationCode)
|
|
189
|
+
await pending.transport.finishAuth(authorizationCode)
|
|
148
190
|
return "authenticated"
|
|
149
191
|
} finally {
|
|
150
|
-
|
|
151
|
-
await transport.close().catch(() => {})
|
|
192
|
+
await retireTransport(serverName, pending)
|
|
152
193
|
}
|
|
153
194
|
}
|
|
154
195
|
|
|
155
|
-
/**
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
196
|
+
/** Complete a separately started OAuth flow with its authorization code. */
|
|
197
|
+
export async function completeAuth(serverName: string, authorizationCode: string): Promise<AuthStatus> {
|
|
198
|
+
const pending = pendingTransports.get(serverName)
|
|
199
|
+
if (!pending) throw new Error(`No pending OAuth flow for server: ${serverName}`)
|
|
200
|
+
return completePendingTransport(serverName, authorizationCode, pending)
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
function asError(error: unknown): Error {
|
|
204
|
+
return error instanceof Error ? error : new Error(String(error))
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
async function performAuthentication(
|
|
208
|
+
owner: PendingAuthentication,
|
|
165
209
|
serverUrl: string,
|
|
166
210
|
definition?: ServerEntry,
|
|
167
211
|
): Promise<AuthStatus> {
|
|
168
|
-
const
|
|
169
|
-
|
|
170
|
-
|
|
212
|
+
const serverName = owner.serverName
|
|
213
|
+
const started = await startAuthAttempt(serverName, serverUrl, definition, owner)
|
|
214
|
+
assertActive(owner)
|
|
215
|
+
if (!started.authorizationUrl) return "authenticated"
|
|
216
|
+
if (!started.oauthState || !started.pendingTransport) {
|
|
217
|
+
throw new Error("OAuth state or transport not found - this should not happen")
|
|
171
218
|
}
|
|
172
219
|
|
|
173
|
-
const
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
// If no auth URL needed, already authenticated
|
|
178
|
-
if (!authorizationUrl) {
|
|
179
|
-
return "authenticated"
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
// Get the state that was already generated and stored in startAuth()
|
|
183
|
-
const oauthState = await getOAuthState(serverName)
|
|
184
|
-
if (!oauthState) {
|
|
185
|
-
throw new Error("OAuth state not found - this should not happen")
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
// Register the callback BEFORE opening the browser
|
|
189
|
-
const callbackPromise = waitForCallback(oauthState)
|
|
190
|
-
|
|
220
|
+
const callbackPromise = waitForCallback(started.oauthState)
|
|
221
|
+
try {
|
|
222
|
+
console.log(`MCP Auth: Opening browser for ${serverName}`)
|
|
191
223
|
try {
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
try {
|
|
195
|
-
await open(authorizationUrl)
|
|
196
|
-
} catch (error) {
|
|
197
|
-
console.warn(`MCP Auth: Failed to open browser for ${serverName}`, { error })
|
|
198
|
-
throw new Error(
|
|
199
|
-
`Could not open browser. Please open this URL manually: ${authorizationUrl}`,
|
|
200
|
-
{ cause: error },
|
|
201
|
-
)
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
// Wait for callback
|
|
205
|
-
const code = await callbackPromise
|
|
206
|
-
|
|
207
|
-
// Validate state
|
|
208
|
-
const storedState = await getOAuthState(serverName)
|
|
209
|
-
if (storedState !== oauthState) {
|
|
210
|
-
await clearOAuthState(serverName)
|
|
211
|
-
throw new Error("OAuth state mismatch - potential CSRF attack")
|
|
212
|
-
}
|
|
213
|
-
await clearOAuthState(serverName)
|
|
214
|
-
|
|
215
|
-
// Complete the auth
|
|
216
|
-
return await completeAuth(serverName, code)
|
|
224
|
+
await open(started.authorizationUrl)
|
|
225
|
+
assertActive(owner)
|
|
217
226
|
} catch (error) {
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
await pendingTransport.close().catch(() => {})
|
|
224
|
-
}
|
|
225
|
-
throw error
|
|
227
|
+
assertActive(owner)
|
|
228
|
+
throw new Error(
|
|
229
|
+
`Could not open browser. Please open this URL manually: ${started.authorizationUrl}`,
|
|
230
|
+
{ cause: error },
|
|
231
|
+
)
|
|
226
232
|
}
|
|
227
|
-
})()
|
|
228
233
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
pendingAuthentications.delete(serverName)
|
|
234
|
+
const code = await callbackPromise
|
|
235
|
+
assertActive(owner)
|
|
236
|
+
const storedState = getOAuthState(serverName)
|
|
237
|
+
if (storedState !== started.oauthState) {
|
|
238
|
+
clearOwnedOAuthState(serverName, started.oauthState)
|
|
239
|
+
throw new Error("OAuth state mismatch - potential CSRF attack")
|
|
236
240
|
}
|
|
241
|
+
clearOwnedOAuthState(serverName, started.oauthState)
|
|
242
|
+
assertActive(owner)
|
|
243
|
+
return await completePendingTransport(serverName, code, started.pendingTransport)
|
|
244
|
+
} catch (error) {
|
|
245
|
+
const failure = owner.controller.signal.aborted
|
|
246
|
+
? asError(owner.controller.signal.reason)
|
|
247
|
+
: asError(error)
|
|
248
|
+
cancelPendingCallback(started.oauthState, failure)
|
|
249
|
+
clearOwnedOAuthState(serverName, started.oauthState)
|
|
250
|
+
await retireTransport(serverName, started.pendingTransport)
|
|
251
|
+
throw failure
|
|
237
252
|
}
|
|
238
253
|
}
|
|
239
254
|
|
|
255
|
+
/** Authenticate once per server while allowing every caller to await the same producer. */
|
|
256
|
+
export function authenticate(
|
|
257
|
+
serverName: string,
|
|
258
|
+
serverUrl: string,
|
|
259
|
+
definition?: ServerEntry,
|
|
260
|
+
): Promise<AuthStatus> {
|
|
261
|
+
const inFlight = pendingAuthentications.get(serverName)
|
|
262
|
+
if (inFlight) return inFlight.result
|
|
263
|
+
|
|
264
|
+
let resolve!: (status: AuthStatus) => void
|
|
265
|
+
let reject!: (error: Error) => void
|
|
266
|
+
const result = new Promise<AuthStatus>((resolveResult, rejectResult) => {
|
|
267
|
+
resolve = resolveResult
|
|
268
|
+
reject = rejectResult
|
|
269
|
+
})
|
|
270
|
+
const controller = new AbortController()
|
|
271
|
+
const inheritedCleanup = oauthCleanupBarrier.wait()
|
|
272
|
+
let owner!: PendingAuthentication
|
|
273
|
+
const producer = inheritedCleanup.then(() => performAuthentication(owner, serverUrl, definition))
|
|
274
|
+
owner = { serverName, controller, result, producer, resolve, reject }
|
|
275
|
+
pendingAuthentications.set(serverName, owner)
|
|
276
|
+
const removeOwner = (): void => {
|
|
277
|
+
if (pendingAuthentications.get(serverName) === owner) pendingAuthentications.delete(serverName)
|
|
278
|
+
}
|
|
279
|
+
void result.then(removeOwner, removeOwner)
|
|
280
|
+
void producer.then(resolve, (error: unknown) => reject(asError(error)))
|
|
281
|
+
return result
|
|
282
|
+
}
|
|
283
|
+
|
|
240
284
|
/**
|
|
241
|
-
*
|
|
242
|
-
*
|
|
243
|
-
*
|
|
244
|
-
* @param serverUrl - The URL of the MCP server
|
|
245
|
-
* @returns The valid tokens or null if not authenticated
|
|
285
|
+
* Retire every OAuth single-flight owner before a replacement session can start.
|
|
286
|
+
* Caller-visible promises reject immediately; non-abortable SDK work remains observed
|
|
287
|
+
* and is fenced from later credential/transport ownership by its aborted provider.
|
|
246
288
|
*/
|
|
289
|
+
export function resetOAuthLifecycle(reason = "session_reset"): Promise<void> {
|
|
290
|
+
const owners = Array.from(pendingAuthentications.values())
|
|
291
|
+
pendingAuthentications.clear()
|
|
292
|
+
const lifecycleError = new OAuthSessionResetError(undefined, reason)
|
|
293
|
+
for (const owner of owners) {
|
|
294
|
+
const ownerError = new OAuthSessionResetError(owner.serverName, reason)
|
|
295
|
+
owner.controller.abort(ownerError)
|
|
296
|
+
owner.reject(ownerError)
|
|
297
|
+
clearOwnedOAuthState(owner.serverName, owner.oauthState)
|
|
298
|
+
}
|
|
299
|
+
cancelAllPendingCallbacks(lifecycleError)
|
|
300
|
+
|
|
301
|
+
const transports = Array.from(new Set(pendingTransports.values()))
|
|
302
|
+
pendingTransports.clear()
|
|
303
|
+
for (const pending of transports) clearOwnedOAuthState(pending.serverName, pending.oauthState)
|
|
304
|
+
|
|
305
|
+
const callbackCleanup = stopCallbackServer(lifecycleError)
|
|
306
|
+
return oauthCleanupBarrier.retain([
|
|
307
|
+
callbackCleanup,
|
|
308
|
+
...owners.map((owner) => owner.producer),
|
|
309
|
+
...transports.map((pending) => closeTransport(pending.transport)),
|
|
310
|
+
])
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
/** Get a valid access token, refreshing it when the stored token is expired. */
|
|
247
314
|
export async function getValidToken(
|
|
248
315
|
serverName: string,
|
|
249
316
|
serverUrl: string,
|
|
250
317
|
): Promise<StoredTokens | null> {
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
// Check expiration
|
|
258
|
-
const expired = await isTokenExpired(serverName)
|
|
259
|
-
if (expired === false) {
|
|
260
|
-
return entry.tokens
|
|
261
|
-
}
|
|
318
|
+
const entry = getAuthForUrl(serverName, serverUrl)
|
|
319
|
+
if (!entry?.tokens) return null
|
|
320
|
+
const expired = isTokenExpired(serverName)
|
|
321
|
+
if (expired === false) return entry.tokens
|
|
262
322
|
|
|
263
323
|
if (expired === true && entry.tokens.refreshToken) {
|
|
264
|
-
// Token is expired, try to refresh
|
|
265
324
|
console.log(`MCP Auth: Token expired for ${serverName}, attempting refresh`)
|
|
266
|
-
|
|
267
325
|
try {
|
|
268
|
-
// Create auth provider for token refresh
|
|
269
326
|
const authProvider = new McpOAuthProvider(serverName, serverUrl, {}, {
|
|
270
327
|
onRedirect: async () => {},
|
|
271
328
|
})
|
|
272
|
-
|
|
273
329
|
const clientInfo = await authProvider.clientInformation()
|
|
274
330
|
if (!clientInfo) {
|
|
275
331
|
console.log(`MCP Auth: No client info for refresh for ${serverName}`)
|
|
276
332
|
return null
|
|
277
333
|
}
|
|
278
|
-
|
|
279
334
|
const result = await runSdkAuth(authProvider, { serverUrl })
|
|
280
|
-
if (result !== "AUTHORIZED")
|
|
281
|
-
|
|
282
|
-
}
|
|
283
|
-
const refreshed = await getAuthForUrl(serverName, serverUrl)
|
|
284
|
-
return refreshed?.tokens ?? null
|
|
335
|
+
if (result !== "AUTHORIZED") return null
|
|
336
|
+
return getAuthForUrl(serverName, serverUrl)?.tokens ?? null
|
|
285
337
|
} catch (error) {
|
|
286
338
|
console.error(`MCP Auth: Token refresh failed for ${serverName}`, { error })
|
|
287
339
|
return null
|
|
288
340
|
}
|
|
289
341
|
}
|
|
290
|
-
|
|
291
|
-
// No expiration info or no refresh token, assume valid
|
|
292
342
|
return entry.tokens
|
|
293
343
|
}
|
|
294
344
|
|
|
295
|
-
/**
|
|
296
|
-
* Check the authentication status for a server.
|
|
297
|
-
*
|
|
298
|
-
* @param serverName - The name of the MCP server
|
|
299
|
-
* @returns The current auth status
|
|
300
|
-
*/
|
|
301
345
|
export async function getAuthStatus(serverName: string): Promise<AuthStatus> {
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
const expired = await isTokenExpired(serverName)
|
|
306
|
-
return expired ? "expired" : "authenticated"
|
|
346
|
+
if (!hasStoredTokens(serverName)) return "not_authenticated"
|
|
347
|
+
return isTokenExpired(serverName) ? "expired" : "authenticated"
|
|
307
348
|
}
|
|
308
349
|
|
|
309
|
-
/**
|
|
310
|
-
* Remove all OAuth credentials for a server.
|
|
311
|
-
*
|
|
312
|
-
* @param serverName - The name of the MCP server
|
|
313
|
-
*/
|
|
314
350
|
export async function removeAuth(serverName: string): Promise<void> {
|
|
315
|
-
const oauthState =
|
|
316
|
-
if (oauthState)
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
const pendingTransport = pendingTransports.get(serverName)
|
|
320
|
-
if (pendingTransport) {
|
|
321
|
-
pendingTransports.delete(serverName)
|
|
322
|
-
await pendingTransport.close().catch(() => {})
|
|
323
|
-
}
|
|
351
|
+
const oauthState = getOAuthState(serverName)
|
|
352
|
+
if (oauthState) cancelPendingCallback(oauthState)
|
|
353
|
+
const pending = pendingTransports.get(serverName)
|
|
354
|
+
if (pending) await retireTransport(serverName, pending)
|
|
324
355
|
clearAllCredentials(serverName)
|
|
325
|
-
|
|
356
|
+
clearOAuthState(serverName)
|
|
326
357
|
console.log(`MCP Auth: Removed credentials for ${serverName}`)
|
|
327
358
|
}
|
|
328
359
|
|
|
329
|
-
/**
|
|
330
|
-
* Check if OAuth is supported for a server configuration.
|
|
331
|
-
* OAuth is supported for HTTP servers unless explicitly disabled.
|
|
332
|
-
*
|
|
333
|
-
* @param definition - The server definition
|
|
334
|
-
* @returns True if OAuth is supported
|
|
335
|
-
*/
|
|
336
360
|
export function supportsOAuth(definition: ServerEntry): boolean {
|
|
337
|
-
|
|
338
|
-
if (!definition.url) return false
|
|
339
|
-
|
|
340
|
-
// Explicitly disabled via auth: false or oauth: false
|
|
341
|
-
if (definition.auth === false) return false
|
|
342
|
-
if (definition.oauth === false) return false
|
|
343
|
-
|
|
344
|
-
// OAuth is enabled if auth is 'oauth' or not specified (auto-detect)
|
|
361
|
+
if (!definition.url || definition.auth === false || definition.oauth === false) return false
|
|
345
362
|
return definition.auth === "oauth" || definition.auth === undefined
|
|
346
363
|
}
|
|
347
364
|
|
|
348
|
-
/**
|
|
349
|
-
* Initialize the OAuth system on startup.
|
|
350
|
-
* Starts the callback server if there are any OAuth servers configured.
|
|
351
|
-
*/
|
|
352
365
|
export async function initializeOAuth(): Promise<void> {
|
|
353
366
|
await ensureCallbackServer()
|
|
354
367
|
}
|
|
355
368
|
|
|
356
|
-
/**
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
*/
|
|
360
|
-
export async function shutdownOAuth(): Promise<void> {
|
|
361
|
-
await stopCallbackServer()
|
|
369
|
+
/** Reset all OAuth ownership and stop callback acceptance for session teardown. */
|
|
370
|
+
export function shutdownOAuth(reason = "session_shutdown"): Promise<void> {
|
|
371
|
+
return resetOAuthLifecycle(reason)
|
|
362
372
|
}
|