@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.
Files changed (377) hide show
  1. package/CHANGELOG.md +106 -0
  2. package/README.md +2 -2
  3. package/dist/builtin/cursor/CHANGELOG.md +12 -0
  4. package/dist/builtin/cursor/package.json +3 -3
  5. package/dist/builtin/cursor/src/model-mapper.ts +6 -3
  6. package/dist/builtin/intercom/CHANGELOG.md +37 -0
  7. package/dist/builtin/intercom/README.md +4 -2
  8. package/dist/builtin/intercom/broker/broker.ts +6 -114
  9. package/dist/builtin/intercom/broker/client.ts +29 -54
  10. package/dist/builtin/intercom/broker/delivered-message-cache.ts +44 -0
  11. package/dist/builtin/intercom/broker/pending-send-registry.ts +142 -0
  12. package/dist/builtin/intercom/broker/send-handler.ts +106 -0
  13. package/dist/builtin/intercom/broker/send-signature.ts +37 -0
  14. package/dist/builtin/intercom/foreground-detach-handoff.ts +136 -0
  15. package/dist/builtin/intercom/index-heavy.ts +49 -53
  16. package/dist/builtin/intercom/index.ts +278 -262
  17. package/dist/builtin/intercom/lazy-heavy-proxy.ts +114 -0
  18. package/dist/builtin/intercom/lazy-subagent-ack.ts +20 -0
  19. package/dist/builtin/intercom/lazy-tool-execution.ts +39 -0
  20. package/dist/builtin/intercom/lifecycle-lease.ts +51 -0
  21. package/dist/builtin/intercom/lifecycle.ts +37 -20
  22. package/dist/builtin/intercom/package.json +3 -6
  23. package/dist/builtin/intercom/reply-routing.ts +17 -0
  24. package/dist/builtin/intercom/subagent-relay.ts +58 -12
  25. package/dist/builtin/intercom/types.ts +3 -3
  26. package/dist/builtin/mcp/CHANGELOG.md +27 -0
  27. package/dist/builtin/mcp/OAUTH.md +1 -0
  28. package/dist/builtin/mcp/README.md +4 -0
  29. package/dist/builtin/mcp/apps-cancellation.ts +32 -0
  30. package/dist/builtin/mcp/call-tool-result.ts +9 -0
  31. package/dist/builtin/mcp/caller-wait.ts +50 -0
  32. package/dist/builtin/mcp/command-registration.ts +82 -0
  33. package/dist/builtin/mcp/direct-tool-executor.ts +279 -0
  34. package/dist/builtin/mcp/direct-tools.ts +6 -239
  35. package/dist/builtin/mcp/host-html-template.ts +4 -2
  36. package/dist/builtin/mcp/index.ts +258 -250
  37. package/dist/builtin/mcp/init.ts +96 -87
  38. package/dist/builtin/mcp/mcp-auth-flow.ts +247 -237
  39. package/dist/builtin/mcp/mcp-callback-server.ts +89 -68
  40. package/dist/builtin/mcp/mcp-oauth-provider.ts +23 -1
  41. package/dist/builtin/mcp/metadata-hydration.ts +21 -6
  42. package/dist/builtin/mcp/package.json +3 -3
  43. package/dist/builtin/mcp/proxy-auth.ts +4 -4
  44. package/dist/builtin/mcp/proxy-call.ts +111 -40
  45. package/dist/builtin/mcp/proxy-connect.ts +35 -15
  46. package/dist/builtin/mcp/proxy-info-modes.ts +49 -19
  47. package/dist/builtin/mcp/proxy-modes.ts +3 -3
  48. package/dist/builtin/mcp/session-cleanup-barrier.ts +43 -0
  49. package/dist/builtin/mcp/state-lease.ts +12 -0
  50. package/dist/builtin/mcp/ui-server.ts +8 -8
  51. package/dist/builtin/mcp/ui-session.ts +9 -18
  52. package/dist/builtin/subagents/CHANGELOG.md +66 -0
  53. package/dist/builtin/subagents/README.md +30 -29
  54. package/dist/builtin/subagents/agents/code-simplifier.md +2 -2
  55. package/dist/builtin/subagents/agents/codebase-analyzer.md +2 -2
  56. package/dist/builtin/subagents/agents/codebase-locator.md +2 -2
  57. package/dist/builtin/subagents/agents/codebase-online-researcher.md +2 -2
  58. package/dist/builtin/subagents/agents/codebase-pattern-finder.md +2 -2
  59. package/dist/builtin/subagents/agents/codebase-research-analyzer.md +2 -2
  60. package/dist/builtin/subagents/agents/codebase-research-locator.md +2 -2
  61. package/dist/builtin/subagents/agents/debugger.md +2 -2
  62. package/dist/builtin/subagents/agents/worker.md +2 -2
  63. package/dist/builtin/subagents/package.json +5 -5
  64. package/dist/builtin/subagents/prompts/review-loop.md +1 -1
  65. package/dist/builtin/subagents/skills/subagent/SKILL.md +37 -36
  66. package/dist/builtin/subagents/src/extension/api-lifecycle.ts +64 -0
  67. package/dist/builtin/subagents/src/extension/fanout-child.ts +44 -51
  68. package/dist/builtin/subagents/src/extension/index.ts +287 -307
  69. package/dist/builtin/subagents/src/extension/prompt-guidance.ts +7 -10
  70. package/dist/builtin/subagents/src/extension/schemas.ts +22 -5
  71. package/dist/builtin/subagents/src/extension/tool-description.ts +29 -0
  72. package/dist/builtin/subagents/src/intercom/intercom-bridge.ts +13 -2
  73. package/dist/builtin/subagents/src/intercom/result-intercom.ts +4 -4
  74. package/dist/builtin/subagents/src/runs/background/async-event-journal.ts +106 -0
  75. package/dist/builtin/subagents/src/runs/background/async-execution-common.ts +3 -2
  76. package/dist/builtin/subagents/src/runs/background/async-execution-single.ts +13 -2
  77. package/dist/builtin/subagents/src/runs/background/async-execution-types.ts +3 -0
  78. package/dist/builtin/subagents/src/runs/background/async-job-tracker.ts +1 -1
  79. package/dist/builtin/subagents/src/runs/background/completion-claims.ts +189 -0
  80. package/dist/builtin/subagents/src/runs/background/completion-dedupe.ts +44 -7
  81. package/dist/builtin/subagents/src/runs/background/completion-notification.ts +34 -0
  82. package/dist/builtin/subagents/src/runs/background/notify.ts +72 -22
  83. package/dist/builtin/subagents/src/runs/background/result-delivery-processor.ts +232 -0
  84. package/dist/builtin/subagents/src/runs/background/result-file-claims.ts +151 -0
  85. package/dist/builtin/subagents/src/runs/background/result-quarantine.ts +72 -0
  86. package/dist/builtin/subagents/src/runs/background/result-retry-scheduler.ts +48 -0
  87. package/dist/builtin/subagents/src/runs/background/result-status.ts +81 -0
  88. package/dist/builtin/subagents/src/runs/background/result-watcher-data.ts +59 -0
  89. package/dist/builtin/subagents/src/runs/background/result-watcher.ts +172 -238
  90. package/dist/builtin/subagents/src/runs/background/run-id-resolver.ts +3 -2
  91. package/dist/builtin/subagents/src/runs/background/stale-run-reconciler.ts +73 -14
  92. package/dist/builtin/subagents/src/runs/background/subagent-runner-streaming.ts +17 -13
  93. package/dist/builtin/subagents/src/runs/background/top-level-async.ts +1 -2
  94. package/dist/builtin/subagents/src/runs/foreground/chain-execution-dynamic-step.ts +1 -0
  95. package/dist/builtin/subagents/src/runs/foreground/chain-execution-parallel-runner.ts +1 -0
  96. package/dist/builtin/subagents/src/runs/foreground/chain-execution-parallel-step.ts +1 -0
  97. package/dist/builtin/subagents/src/runs/foreground/chain-execution-sequential-step.ts +7 -9
  98. package/dist/builtin/subagents/src/runs/foreground/chain-execution-types.ts +3 -13
  99. package/dist/builtin/subagents/src/runs/foreground/chain-execution.ts +2 -15
  100. package/dist/builtin/subagents/src/runs/foreground/execution-attempt-finalize.ts +2 -2
  101. package/dist/builtin/subagents/src/runs/foreground/execution-attempt.ts +53 -44
  102. package/dist/builtin/subagents/src/runs/foreground/execution-detach-reservations.ts +48 -0
  103. package/dist/builtin/subagents/src/runs/foreground/execution-detach-route.ts +17 -0
  104. package/dist/builtin/subagents/src/runs/foreground/execution-run-sync.ts +39 -26
  105. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-async.ts +3 -1
  106. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-chain.ts +3 -51
  107. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-context.ts +6 -11
  108. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-input.ts +11 -2
  109. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-parallel-task.ts +2 -0
  110. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-parallel.ts +5 -112
  111. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-resume.ts +2 -0
  112. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-single.ts +68 -118
  113. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-status.ts +79 -7
  114. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-types.ts +2 -2
  115. package/dist/builtin/subagents/src/runs/foreground/subagent-executor.ts +3 -0
  116. package/dist/builtin/subagents/src/runs/shared/pi-args.ts +2 -2
  117. package/dist/builtin/subagents/src/runs/shared/pi-spawn.ts +27 -11
  118. package/dist/builtin/subagents/src/shared/artifacts.ts +22 -11
  119. package/dist/builtin/subagents/src/shared/event-jsonl-writer.ts +294 -0
  120. package/dist/builtin/subagents/src/shared/exclusive-file-publication.ts +44 -0
  121. package/dist/builtin/subagents/src/shared/jsonl-writer.ts +1 -0
  122. package/dist/builtin/subagents/src/shared/model-info.ts +2 -2
  123. package/dist/builtin/subagents/src/shared/settings.ts +20 -10
  124. package/dist/builtin/subagents/src/shared/types-async.ts +3 -1
  125. package/dist/builtin/subagents/src/shared/types-config.ts +2 -0
  126. package/dist/builtin/subagents/src/shared/types-runtime.ts +3 -2
  127. package/dist/builtin/subagents/src/slash/slash-commands.ts +9 -12
  128. package/dist/builtin/subagents/src/slash/slash-live-state.ts +63 -32
  129. package/dist/builtin/subagents/src/tui/render-result.ts +7 -0
  130. package/dist/builtin/subagents/src/tui/render-stable-output.ts +1 -0
  131. package/dist/builtin/subagents/src/tui/render-widget.ts +128 -89
  132. package/dist/builtin/web-access/CHANGELOG.md +28 -0
  133. package/dist/builtin/web-access/README.md +4 -0
  134. package/dist/builtin/web-access/content-tools.ts +8 -3
  135. package/dist/builtin/web-access/index-heavy.ts +1 -1
  136. package/dist/builtin/web-access/index.ts +190 -46
  137. package/dist/builtin/web-access/lifecycle-lease.ts +38 -0
  138. package/dist/builtin/web-access/package.json +2 -2
  139. package/dist/builtin/web-access/result-renderers.ts +1 -1
  140. package/dist/builtin/web-access/summary-review.ts +1 -1
  141. package/dist/builtin/web-access/web-search-activity.ts +1 -1
  142. package/dist/builtin/web-access/web-search-return.ts +7 -0
  143. package/dist/builtin/web-access/web-search-summary.ts +1 -1
  144. package/dist/builtin/web-access/web-search-tool.ts +4 -2
  145. package/dist/builtin/workflows/CHANGELOG.md +68 -0
  146. package/dist/builtin/workflows/README.md +4 -4
  147. package/dist/builtin/workflows/builtin/deep-research-codebase-utils.ts +27 -4
  148. package/dist/builtin/workflows/builtin/goal-runner.ts +47 -26
  149. package/dist/builtin/workflows/builtin/open-claude-design-runner.ts +10 -0
  150. package/dist/builtin/workflows/builtin/ralph-core.ts +9 -9
  151. package/dist/builtin/workflows/builtin/ralph-models.ts +71 -36
  152. package/dist/builtin/workflows/builtin/ralph-runner.ts +20 -31
  153. package/dist/builtin/workflows/package.json +2 -2
  154. package/dist/builtin/workflows/src/durable/stage-primitive.ts +2 -1
  155. package/dist/builtin/workflows/src/engine/primitives/task.ts +2 -1
  156. package/dist/builtin/workflows/src/extension/workflow-prompts.ts +17 -22
  157. package/dist/builtin/workflows/src/extension/workflow-schema.ts +15 -2
  158. package/dist/builtin/workflows/src/runs/foreground/executor-hil.ts +1 -2
  159. package/dist/builtin/workflows/src/runs/shared/model-fallback-candidates.ts +1 -1
  160. package/dist/builtin/workflows/src/shared/authoring-contract-stage.d.ts +2 -2
  161. package/dist/builtin/workflows/src/shared/authoring-contract-stage.ts +2 -2
  162. package/dist/builtin/workflows/src/shared/resume-continuation.ts +2 -0
  163. package/dist/builtin/workflows/src/tui/stage-chat-view-archive-history.ts +1 -23
  164. package/dist/builtin/workflows/src/tui/stage-chat-view-footer-status.ts +54 -9
  165. package/dist/builtin/workflows/src/tui/stage-chat-view.ts +5 -2
  166. package/dist/cli/args.d.ts.map +1 -1
  167. package/dist/cli/args.js +2 -2
  168. package/dist/cli/args.js.map +1 -1
  169. package/dist/core/agent-session-events.d.ts.map +1 -1
  170. package/dist/core/agent-session-events.js +2 -1
  171. package/dist/core/agent-session-events.js.map +1 -1
  172. package/dist/core/agent-session-message-queue.d.ts.map +1 -1
  173. package/dist/core/agent-session-message-queue.js +1 -1
  174. package/dist/core/agent-session-message-queue.js.map +1 -1
  175. package/dist/core/agent-session-prompt.d.ts.map +1 -1
  176. package/dist/core/agent-session-prompt.js +1 -1
  177. package/dist/core/agent-session-prompt.js.map +1 -1
  178. package/dist/core/agent-session-retry.d.ts.map +1 -1
  179. package/dist/core/agent-session-retry.js +1 -1
  180. package/dist/core/agent-session-retry.js.map +1 -1
  181. package/dist/core/agent-session-services.d.ts.map +1 -1
  182. package/dist/core/agent-session-services.js +3 -2
  183. package/dist/core/agent-session-services.js.map +1 -1
  184. package/dist/core/agent-session-types.d.ts.map +1 -1
  185. package/dist/core/agent-session-types.js +1 -1
  186. package/dist/core/agent-session-types.js.map +1 -1
  187. package/dist/core/anthropic-thinking-guard.d.ts +5 -5
  188. package/dist/core/anthropic-thinking-guard.d.ts.map +1 -1
  189. package/dist/core/anthropic-thinking-guard.js +42 -32
  190. package/dist/core/anthropic-thinking-guard.js.map +1 -1
  191. package/dist/core/atomic-guide-command.d.ts.map +1 -1
  192. package/dist/core/atomic-guide-command.js +15 -15
  193. package/dist/core/atomic-guide-command.js.map +1 -1
  194. package/dist/core/auth-storage.d.ts.map +1 -1
  195. package/dist/core/auth-storage.js +14 -9
  196. package/dist/core/auth-storage.js.map +1 -1
  197. package/dist/core/compaction/compaction.d.ts +2 -0
  198. package/dist/core/compaction/compaction.d.ts.map +1 -1
  199. package/dist/core/compaction/compaction.js +79 -46
  200. package/dist/core/compaction/compaction.js.map +1 -1
  201. package/dist/core/compaction/context-assistant-turns.d.ts +42 -0
  202. package/dist/core/compaction/context-assistant-turns.d.ts.map +1 -0
  203. package/dist/core/compaction/context-assistant-turns.js +87 -0
  204. package/dist/core/compaction/context-assistant-turns.js.map +1 -0
  205. package/dist/core/compaction/context-compaction-critical.d.ts +1 -1
  206. package/dist/core/compaction/context-compaction-critical.d.ts.map +1 -1
  207. package/dist/core/compaction/context-compaction-critical.js +2 -2
  208. package/dist/core/compaction/context-compaction-critical.js.map +1 -1
  209. package/dist/core/compaction/context-compaction-eviction-alternates.d.ts +18 -0
  210. package/dist/core/compaction/context-compaction-eviction-alternates.d.ts.map +1 -0
  211. package/dist/core/compaction/context-compaction-eviction-alternates.js +186 -0
  212. package/dist/core/compaction/context-compaction-eviction-alternates.js.map +1 -0
  213. package/dist/core/compaction/context-compaction-eviction.d.ts +10 -2
  214. package/dist/core/compaction/context-compaction-eviction.d.ts.map +1 -1
  215. package/dist/core/compaction/context-compaction-eviction.js +196 -146
  216. package/dist/core/compaction/context-compaction-eviction.js.map +1 -1
  217. package/dist/core/compaction/context-compaction-prompt.d.ts.map +1 -1
  218. package/dist/core/compaction/context-compaction-prompt.js +1 -1
  219. package/dist/core/compaction/context-compaction-prompt.js.map +1 -1
  220. package/dist/core/compaction/context-compaction-types.d.ts +2 -0
  221. package/dist/core/compaction/context-compaction-types.d.ts.map +1 -1
  222. package/dist/core/compaction/context-compaction-types.js.map +1 -1
  223. package/dist/core/compaction/context-deletion-application.d.ts +5 -4
  224. package/dist/core/compaction/context-deletion-application.d.ts.map +1 -1
  225. package/dist/core/compaction/context-deletion-application.js +17 -15
  226. package/dist/core/compaction/context-deletion-application.js.map +1 -1
  227. package/dist/core/compaction/context-deletion-store.d.ts.map +1 -1
  228. package/dist/core/compaction/context-deletion-store.js +1 -1
  229. package/dist/core/compaction/context-deletion-store.js.map +1 -1
  230. package/dist/core/compaction/context-deletion-targets.d.ts +2 -1
  231. package/dist/core/compaction/context-deletion-targets.d.ts.map +1 -1
  232. package/dist/core/compaction/context-deletion-targets.js +36 -31
  233. package/dist/core/compaction/context-deletion-targets.js.map +1 -1
  234. package/dist/core/compaction/context-deletion-tool-helpers.d.ts.map +1 -1
  235. package/dist/core/compaction/context-deletion-tool-helpers.js +116 -43
  236. package/dist/core/compaction/context-deletion-tool-helpers.js.map +1 -1
  237. package/dist/core/compaction/context-transcript-analysis.d.ts +1 -2
  238. package/dist/core/compaction/context-transcript-analysis.d.ts.map +1 -1
  239. package/dist/core/compaction/context-transcript-analysis.js +33 -37
  240. package/dist/core/compaction/context-transcript-analysis.js.map +1 -1
  241. package/dist/core/copilot-model-synthesis.d.ts.map +1 -1
  242. package/dist/core/copilot-model-synthesis.js +3 -1
  243. package/dist/core/copilot-model-synthesis.js.map +1 -1
  244. package/dist/core/extensions/provider-types.d.ts +2 -7
  245. package/dist/core/extensions/provider-types.d.ts.map +1 -1
  246. package/dist/core/extensions/provider-types.js.map +1 -1
  247. package/dist/core/messages.d.ts +9 -0
  248. package/dist/core/messages.d.ts.map +1 -1
  249. package/dist/core/messages.js +100 -18
  250. package/dist/core/messages.js.map +1 -1
  251. package/dist/core/model-registry-builtins.d.ts.map +1 -1
  252. package/dist/core/model-registry-builtins.js +5 -0
  253. package/dist/core/model-registry-builtins.js.map +1 -1
  254. package/dist/core/model-registry-custom-loader.d.ts.map +1 -1
  255. package/dist/core/model-registry-custom-loader.js +49 -8
  256. package/dist/core/model-registry-custom-loader.js.map +1 -1
  257. package/dist/core/model-registry-dynamic.d.ts.map +1 -1
  258. package/dist/core/model-registry-dynamic.js +11 -5
  259. package/dist/core/model-registry-dynamic.js.map +1 -1
  260. package/dist/core/model-registry-loader.d.ts.map +1 -1
  261. package/dist/core/model-registry-loader.js +8 -0
  262. package/dist/core/model-registry-loader.js.map +1 -1
  263. package/dist/core/model-registry-schemas.d.ts +93 -8
  264. package/dist/core/model-registry-schemas.d.ts.map +1 -1
  265. package/dist/core/model-registry-schemas.js +24 -12
  266. package/dist/core/model-registry-schemas.js.map +1 -1
  267. package/dist/core/model-registry-types.d.ts +7 -6
  268. package/dist/core/model-registry-types.d.ts.map +1 -1
  269. package/dist/core/model-registry-types.js.map +1 -1
  270. package/dist/core/model-registry.d.ts +5 -0
  271. package/dist/core/model-registry.d.ts.map +1 -1
  272. package/dist/core/model-registry.js +23 -0
  273. package/dist/core/model-registry.js.map +1 -1
  274. package/dist/core/model-resolver-cli.d.ts.map +1 -1
  275. package/dist/core/model-resolver-cli.js +33 -5
  276. package/dist/core/model-resolver-cli.js.map +1 -1
  277. package/dist/core/model-resolver-initial.d.ts +6 -1
  278. package/dist/core/model-resolver-initial.d.ts.map +1 -1
  279. package/dist/core/model-resolver-initial.js +12 -7
  280. package/dist/core/model-resolver-initial.js.map +1 -1
  281. package/dist/core/model-resolver.d.ts +1 -1
  282. package/dist/core/model-resolver.d.ts.map +1 -1
  283. package/dist/core/model-resolver.js +1 -1
  284. package/dist/core/model-resolver.js.map +1 -1
  285. package/dist/core/resource-loader-context-files.d.ts +1 -0
  286. package/dist/core/resource-loader-context-files.d.ts.map +1 -1
  287. package/dist/core/resource-loader-context-files.js +13 -10
  288. package/dist/core/resource-loader-context-files.js.map +1 -1
  289. package/dist/core/sdk.d.ts.map +1 -1
  290. package/dist/core/sdk.js +2 -2
  291. package/dist/core/sdk.js.map +1 -1
  292. package/dist/core/session-entry-normalization.d.ts +7 -0
  293. package/dist/core/session-entry-normalization.d.ts.map +1 -0
  294. package/dist/core/session-entry-normalization.js +14 -0
  295. package/dist/core/session-entry-normalization.js.map +1 -0
  296. package/dist/core/session-manager-core.d.ts.map +1 -1
  297. package/dist/core/session-manager-core.js +1 -0
  298. package/dist/core/session-manager-core.js.map +1 -1
  299. package/dist/core/session-manager-history.d.ts +2 -2
  300. package/dist/core/session-manager-history.d.ts.map +1 -1
  301. package/dist/core/session-manager-history.js +127 -108
  302. package/dist/core/session-manager-history.js.map +1 -1
  303. package/dist/core/settings-manager-basic-accessors.d.ts +2 -2
  304. package/dist/core/settings-manager-basic-accessors.d.ts.map +1 -1
  305. package/dist/core/settings-manager-basic-accessors.js.map +1 -1
  306. package/dist/core/settings-types.d.ts +1 -1
  307. package/dist/core/settings-types.d.ts.map +1 -1
  308. package/dist/core/settings-types.js.map +1 -1
  309. package/dist/core/tools/bash.d.ts.map +1 -1
  310. package/dist/core/tools/bash.js +11 -8
  311. package/dist/core/tools/bash.js.map +1 -1
  312. package/dist/main-session.d.ts.map +1 -1
  313. package/dist/main-session.js +1 -0
  314. package/dist/main-session.js.map +1 -1
  315. package/dist/modes/interactive/components/settings-selector-options.d.ts.map +1 -1
  316. package/dist/modes/interactive/components/settings-selector-options.js +3 -1
  317. package/dist/modes/interactive/components/settings-selector-options.js.map +1 -1
  318. package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
  319. package/dist/modes/interactive/components/thinking-selector.js +2 -1
  320. package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
  321. package/dist/modes/interactive/interactive-agent-events.d.ts.map +1 -1
  322. package/dist/modes/interactive/interactive-agent-events.js +2 -1
  323. package/dist/modes/interactive/interactive-agent-events.js.map +1 -1
  324. package/dist/modes/interactive/interactive-child-ordering.d.ts +7 -0
  325. package/dist/modes/interactive/interactive-child-ordering.d.ts.map +1 -0
  326. package/dist/modes/interactive/interactive-child-ordering.js +26 -0
  327. package/dist/modes/interactive/interactive-child-ordering.js.map +1 -0
  328. package/dist/modes/interactive/interactive-deferred-startup.d.ts.map +1 -1
  329. package/dist/modes/interactive/interactive-deferred-startup.js +2 -2
  330. package/dist/modes/interactive/interactive-deferred-startup.js.map +1 -1
  331. package/dist/modes/interactive/interactive-mode-deps.d.ts +1 -1
  332. package/dist/modes/interactive/interactive-mode-deps.d.ts.map +1 -1
  333. package/dist/modes/interactive/interactive-mode-deps.js +1 -1
  334. package/dist/modes/interactive/interactive-mode-deps.js.map +1 -1
  335. package/dist/modes/interactive/interactive-model-routing.d.ts.map +1 -1
  336. package/dist/modes/interactive/interactive-model-routing.js +8 -3
  337. package/dist/modes/interactive/interactive-model-routing.js.map +1 -1
  338. package/dist/modes/interactive/theme/theme-class.d.ts +1 -1
  339. package/dist/modes/interactive/theme/theme-class.d.ts.map +1 -1
  340. package/dist/modes/interactive/theme/theme-class.js +2 -0
  341. package/dist/modes/interactive/theme/theme-class.js.map +1 -1
  342. package/dist/utils/clipboard-image.d.ts.map +1 -1
  343. package/dist/utils/clipboard-image.js +3 -0
  344. package/dist/utils/clipboard-image.js.map +1 -1
  345. package/docs/changelog.mdx +19 -0
  346. package/docs/compaction.md +55 -48
  347. package/docs/custom-provider.md +18 -5
  348. package/docs/extensions.md +7 -3
  349. package/docs/models.md +69 -10
  350. package/docs/providers.md +1 -1
  351. package/docs/quickstart.md +11 -7
  352. package/docs/rpc.md +2 -2
  353. package/docs/sdk.md +1 -1
  354. package/docs/settings.md +3 -3
  355. package/docs/subagents.md +36 -5
  356. package/docs/tools.md +1 -1
  357. package/docs/usage.md +4 -2
  358. package/docs/workflows.md +26 -43
  359. package/examples/extensions/preset.ts +2 -2
  360. package/examples/extensions/subagent/README.md +2 -2
  361. package/examples/extensions/subagent/index.ts +1 -2
  362. package/examples/extensions/subagent/schemas.ts +4 -1
  363. package/examples/sdk/12-full-control.ts +1 -1
  364. package/npm-shrinkwrap.json +48 -51
  365. package/package.json +7 -7
  366. package/dist/builtin/subagents/src/runs/foreground/chain-clarify-behavior.ts +0 -75
  367. package/dist/builtin/subagents/src/runs/foreground/chain-clarify-component.ts +0 -202
  368. package/dist/builtin/subagents/src/runs/foreground/chain-clarify-edit.ts +0 -97
  369. package/dist/builtin/subagents/src/runs/foreground/chain-clarify-editor.ts +0 -160
  370. package/dist/builtin/subagents/src/runs/foreground/chain-clarify-frame.ts +0 -72
  371. package/dist/builtin/subagents/src/runs/foreground/chain-clarify-render-modes.ts +0 -161
  372. package/dist/builtin/subagents/src/runs/foreground/chain-clarify-render-selectors.ts +0 -203
  373. package/dist/builtin/subagents/src/runs/foreground/chain-clarify-selectors.ts +0 -234
  374. package/dist/builtin/subagents/src/runs/foreground/chain-clarify-state.ts +0 -103
  375. package/dist/builtin/subagents/src/runs/foreground/chain-clarify-types.ts +0 -29
  376. package/dist/builtin/subagents/src/runs/foreground/chain-clarify.ts +0 -9
  377. package/dist/builtin/subagents/src/runs/foreground/chain-execution-clarify.ts +0 -117
@@ -1,62 +1,76 @@
1
- /**
2
- * MCP Auth Flow
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.ts"
5
+ import { McpOAuthProvider, type McpOAuthConfig } from "./mcp-oauth-provider.js"
14
6
  import {
15
- ensureCallbackServer,
16
- waitForCallback,
7
+ cancelAllPendingCallbacks,
17
8
  cancelPendingCallback,
9
+ ensureCallbackServer,
18
10
  stopCallbackServer,
19
- } from "./mcp-callback-server.ts"
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.ts"
32
- import type { ServerEntry } from "./types.ts"
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
- // Track pending transports for auth completion
38
- const pendingTransports = new Map<string, StreamableHTTPClientTransport>()
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
- // Deduplicate concurrent authenticate() calls per server.
41
- const pendingAuthentications = new Map<string, Promise<AuthStatus>>()
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((b) => b.toString(16).padStart(2, "0"))
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
- // If oauth is explicitly false, return empty config
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
- * Start OAuth authentication flow for a server.
70
- * Returns the authorization URL when browser authorization is required.
71
- */
72
- export async function startAuth(
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
- ): Promise<{ authorizationUrl: string }> {
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
- await clearOAuthState(serverName)
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
- if (result !== "AUTHORIZED") {
94
- throw new UnauthorizedError("Failed to authorize")
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
- await updateOAuthState(serverName, oauthState, serverUrl)
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
- capturedUrl = url
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
- await clearOAuthState(serverName)
117
- return { authorizationUrl: "" }
154
+ clearOwnedOAuthState(serverName, oauthState)
155
+ return { authorizationUrl: "", oauthState }
118
156
  }
119
- if (!capturedUrl) {
120
- throw new UnauthorizedError("OAuth authorization URL was not provided")
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
- return { authorizationUrl: capturedUrl.toString() }
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
- await clearOAuthState(serverName)
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
- * Complete OAuth authentication with the authorization code.
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
- authorizationCode: string
139
- ): Promise<AuthStatus> {
140
- const transport = pendingTransports.get(serverName)
141
- if (!transport) {
142
- throw new Error(`No pending OAuth flow for server: ${serverName}`)
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
- // Complete the auth using the transport's finishAuth method
147
- await transport.finishAuth(authorizationCode)
189
+ await pending.transport.finishAuth(authorizationCode)
148
190
  return "authenticated"
149
191
  } finally {
150
- pendingTransports.delete(serverName)
151
- await transport.close().catch(() => {})
192
+ await retireTransport(serverName, pending)
152
193
  }
153
194
  }
154
195
 
155
- /**
156
- * Perform the complete OAuth authentication flow for a server.
157
- *
158
- * @param serverName - The name of the MCP server
159
- * @param serverUrl - The URL of the MCP server
160
- * @param definition - The server definition (optional)
161
- * @returns The final auth status
162
- */
163
- export async function authenticate(
164
- serverName: string,
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 inFlight = pendingAuthentications.get(serverName)
169
- if (inFlight) {
170
- return inFlight
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 operation = (async (): Promise<AuthStatus> => {
174
- // Start auth flow
175
- const { authorizationUrl } = await startAuth(serverName, serverUrl, definition)
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
- // Open browser
193
- console.log(`MCP Auth: Opening browser for ${serverName}`)
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
- cancelPendingCallback(oauthState)
219
- await clearOAuthState(serverName)
220
- const pendingTransport = pendingTransports.get(serverName)
221
- if (pendingTransport) {
222
- pendingTransports.delete(serverName)
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
- pendingAuthentications.set(serverName, operation)
230
-
231
- try {
232
- return await operation
233
- } finally {
234
- if (pendingAuthentications.get(serverName) === operation) {
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
- * Get a valid access token for a server, refreshing if necessary.
242
- *
243
- * @param serverName - The name of the MCP server
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
- // Check if we have valid tokens
252
- const entry = await getAuthForUrl(serverName, serverUrl)
253
- if (!entry?.tokens) {
254
- return null
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
- return null
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
- const hasTokens = await hasStoredTokens(serverName)
303
- if (!hasTokens) return "not_authenticated"
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 = await getOAuthState(serverName)
316
- if (oauthState) {
317
- cancelPendingCallback(oauthState)
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
- await clearOAuthState(serverName)
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
- // OAuth requires a URL
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
- * Shutdown the OAuth system.
358
- * Stops the callback server and cancels pending auths.
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
  }