@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
@@ -0,0 +1,82 @@
1
+ import type { ExtensionAPI } from "@bastani/atomic";
2
+ import type { McpExtensionState } from "./state.js";
3
+
4
+ interface CommandStateLease {
5
+ readonly state: McpExtensionState;
6
+ readonly assertActive: () => void;
7
+ }
8
+
9
+ export function registerMcpCommands(
10
+ pi: ExtensionAPI,
11
+ earlyConfigPath: string | undefined,
12
+ acquireState: () => Promise<CommandStateLease>,
13
+ ): void {
14
+ pi.registerCommand("mcp", {
15
+ description: "Show MCP server status",
16
+ handler: async (args, ctx) => {
17
+ let lease: CommandStateLease;
18
+ try {
19
+ lease = await acquireState();
20
+ } catch (error) {
21
+ const message = error instanceof Error ? error.message : String(error);
22
+ if (ctx.hasUI) ctx.ui.notify(`MCP initialization failed: ${message}`, "error");
23
+ return;
24
+ }
25
+ const { showStatus, showTools, reconnectServers, logoutServer, openMcpPanel, openMcpSetup } = await import("./commands.js");
26
+ try { lease.assertActive(); } catch { return; }
27
+ const parts = args?.trim()?.split(/\s+/) ?? [];
28
+ const subcommand = parts[0] ?? "";
29
+ const targetServer = parts[1];
30
+ const rest = parts.slice(1).join(" ");
31
+ switch (subcommand) {
32
+ case "reconnect": await reconnectServers(lease.state, ctx, targetServer); break;
33
+ case "tools": await showTools(lease.state, ctx); break;
34
+ case "setup": {
35
+ const result = await openMcpSetup(lease.state, pi, ctx, earlyConfigPath, "setup");
36
+ if (result?.configChanged) await ctx.reload();
37
+ break;
38
+ }
39
+ case "logout": {
40
+ if (!rest) {
41
+ if (ctx.hasUI) ctx.ui.notify("Usage: /mcp logout <server>", "error");
42
+ return;
43
+ }
44
+ await logoutServer(rest, lease.state, ctx);
45
+ break;
46
+ }
47
+ case "status":
48
+ case "":
49
+ default:
50
+ if (ctx.hasUI) {
51
+ const result = await openMcpPanel(lease.state, pi, ctx, earlyConfigPath);
52
+ if (result?.configChanged) await ctx.reload();
53
+ } else {
54
+ await showStatus(lease.state, ctx);
55
+ }
56
+ }
57
+ },
58
+ });
59
+
60
+ pi.registerCommand("mcp-auth", {
61
+ description: "Authenticate with an MCP server (OAuth)",
62
+ handler: async (args, ctx) => {
63
+ const serverName = args?.trim();
64
+ if (!serverName && !ctx.hasUI) return;
65
+ let lease: CommandStateLease;
66
+ try {
67
+ lease = await acquireState();
68
+ } catch (error) {
69
+ const message = error instanceof Error ? error.message : String(error);
70
+ if (ctx.hasUI) ctx.ui.notify(`MCP initialization failed: ${message}`, "error");
71
+ return;
72
+ }
73
+ const { authenticateServer, openMcpAuthPanel } = await import("./commands.js");
74
+ try { lease.assertActive(); } catch { return; }
75
+ if (!serverName) {
76
+ await openMcpAuthPanel(lease.state, pi, ctx, earlyConfigPath);
77
+ return;
78
+ }
79
+ await authenticateServer(serverName, lease.state.config, ctx);
80
+ },
81
+ });
82
+ }
@@ -0,0 +1,279 @@
1
+ import type { AgentToolResult, AgentToolUpdateCallback, ExtensionContext } from "@bastani/atomic";
2
+ import { CallToolResultSchema } from "@modelcontextprotocol/sdk/types.js";
3
+ import type { McpExtensionState } from "./state.js";
4
+ import type { DirectToolSpec, McpContent } from "./types.js";
5
+ import { getFailureAgeSeconds, lazyConnect } from "./init.js";
6
+ import { formatSchema } from "./tool-metadata.js";
7
+ import { transformMcpContent } from "./tool-registrar.js";
8
+ import { maybeStartUiSession, type UiSessionRuntime } from "./ui-session.js";
9
+ import { authenticate, supportsOAuth } from "./mcp-auth-flow.js";
10
+ import { formatAuthRequiredMessage, unflattenToolArguments } from "./utils.js";
11
+ import { waitForCaller, waitForCallerWithLateCleanup } from "./caller-wait.js";
12
+ import { notifyUiCancellation, rethrowHostAbortAfterUiCancellation } from "./apps-cancellation.js";
13
+ import { asCallToolResult } from "./call-tool-result.js";
14
+
15
+ interface DirectToolStateChangedDetails extends Record<string, unknown> {
16
+ error: "state_changed";
17
+ message: string;
18
+ }
19
+
20
+ type DirectToolExecute = (
21
+ toolCallId: string,
22
+ params: Record<string, unknown>,
23
+ signal: AbortSignal | undefined,
24
+ onUpdate: AgentToolUpdateCallback<Record<string, unknown>> | undefined,
25
+ ctx: ExtensionContext,
26
+ ) => Promise<AgentToolResult<Record<string, unknown>>>;
27
+
28
+ type IsActiveStateOwner = (candidate: McpExtensionState) => boolean;
29
+ type StartUiSession = typeof maybeStartUiSession;
30
+
31
+ export interface DirectToolExecutorOptions {
32
+ readonly startUiSession?: StartUiSession;
33
+ readonly startAutoAuth?: (state: McpExtensionState, serverName: string) => Promise<DirectAutoAuthResult>;
34
+ }
35
+
36
+ export type DirectAutoAuthResult =
37
+ | { status: "skipped" }
38
+ | { status: "success" }
39
+ | { status: "failed"; message: string };
40
+
41
+ function getDirectAuthRequiredMessage(
42
+ state: McpExtensionState,
43
+ serverName: string,
44
+ defaultMessage = `MCP server "${serverName}" requires OAuth authentication. Run /mcp-auth ${serverName} first.`,
45
+ ): string {
46
+ return formatAuthRequiredMessage(state.config, serverName, defaultMessage);
47
+ }
48
+
49
+ function getDirectAuthFailedMessage(state: McpExtensionState, serverName: string, message: string): string {
50
+ const customGuidance = state.config.settings?.authRequiredMessage;
51
+ if (customGuidance) {
52
+ return `OAuth authentication failed for "${serverName}": ${message}. ${getDirectAuthRequiredMessage(state, serverName)}`;
53
+ }
54
+ return `OAuth authentication failed for "${serverName}": ${message}. Run /mcp-auth ${serverName} first.`;
55
+ }
56
+
57
+ async function attemptDirectAutoAuth(
58
+ state: McpExtensionState,
59
+ serverName: string,
60
+ ): Promise<DirectAutoAuthResult> {
61
+ if (state.config.settings?.autoAuth !== true) return { status: "skipped" };
62
+
63
+ const definition = state.config.mcpServers[serverName];
64
+ if (!definition || !supportsOAuth(definition) || !definition.url) return { status: "skipped" };
65
+
66
+ const grantType = definition.oauth ? definition.oauth.grantType ?? "authorization_code" : "authorization_code";
67
+ if (!state.ui && grantType !== "client_credentials") {
68
+ return {
69
+ status: "failed",
70
+ message: getDirectAuthRequiredMessage(
71
+ state,
72
+ serverName,
73
+ `MCP server "${serverName}" requires OAuth authentication. Run /mcp-auth ${serverName} in an interactive session.`,
74
+ ),
75
+ };
76
+ }
77
+
78
+ try {
79
+ await authenticate(serverName, definition.url, definition);
80
+ return { status: "success" };
81
+ } catch (error) {
82
+ const message = error instanceof Error ? error.message : String(error);
83
+ return { status: "failed", message: getDirectAuthFailedMessage(state, serverName, message) };
84
+ }
85
+ }
86
+
87
+ function stateChangedResult(): AgentToolResult<DirectToolStateChangedDetails> {
88
+ const message = "MCP session changed before direct tool execution completed";
89
+ return {
90
+ content: [{ type: "text" as const, text: message }],
91
+ details: { error: "state_changed", message },
92
+ };
93
+ }
94
+
95
+ export function createDirectToolExecutor(
96
+ ensureInitialized: () => Promise<McpExtensionState>,
97
+ isActiveStateOwner: IsActiveStateOwner,
98
+ spec: DirectToolSpec,
99
+ options: DirectToolExecutorOptions = {},
100
+ ): DirectToolExecute {
101
+ const startUiSession = options.startUiSession ?? maybeStartUiSession;
102
+ const startAutoAuth = options.startAutoAuth ?? attemptDirectAutoAuth;
103
+ return async function execute(_toolCallId, params, signal) {
104
+ signal?.throwIfAborted();
105
+ let state: McpExtensionState;
106
+ try {
107
+ state = await waitForCaller(ensureInitialized, signal);
108
+ } catch (error) {
109
+ signal?.throwIfAborted();
110
+ const message = error instanceof Error ? error.message : String(error);
111
+ return {
112
+ content: [{ type: "text" as const, text: `MCP initialization failed: ${message}` }],
113
+ details: { error: "init_failed", message },
114
+ };
115
+ }
116
+ signal?.throwIfAborted();
117
+ if (!isActiveStateOwner(state)) return stateChangedResult();
118
+
119
+ let connected = await waitForCaller(() => lazyConnect(state, spec.serverName), signal);
120
+ signal?.throwIfAborted();
121
+ if (!isActiveStateOwner(state)) return stateChangedResult();
122
+ let autoAuthAttempted = false;
123
+
124
+ if (!connected && state.manager.getConnection(spec.serverName)?.status === "needs-auth") {
125
+ autoAuthAttempted = true;
126
+ const autoAuth = await waitForCaller(() => startAutoAuth(state, spec.serverName), signal);
127
+ signal?.throwIfAborted();
128
+ if (!isActiveStateOwner(state)) return stateChangedResult();
129
+ if (autoAuth.status === "failed") {
130
+ return {
131
+ content: [{ type: "text" as const, text: autoAuth.message }],
132
+ details: { error: "auth_required", server: spec.serverName, message: autoAuth.message },
133
+ };
134
+ }
135
+ if (autoAuth.status === "success") {
136
+ await waitForCaller(() => state.manager.close(spec.serverName), signal);
137
+ signal?.throwIfAborted();
138
+ if (!isActiveStateOwner(state)) return stateChangedResult();
139
+ state.failureTracker.delete(spec.serverName);
140
+ connected = await waitForCaller(() => lazyConnect(state, spec.serverName), signal);
141
+ signal?.throwIfAborted();
142
+ if (!isActiveStateOwner(state)) return stateChangedResult();
143
+ }
144
+ }
145
+
146
+ if (!connected) {
147
+ const authConnection = state.manager.getConnection(spec.serverName);
148
+ if (authConnection?.status === "needs-auth") {
149
+ const message = getDirectAuthRequiredMessage(state, spec.serverName);
150
+ return {
151
+ content: [{ type: "text" as const, text: message }],
152
+ details: { error: "auth_required", server: spec.serverName, message, autoAuthAttempted },
153
+ };
154
+ }
155
+ const failedAgo = getFailureAgeSeconds(state, spec.serverName);
156
+ return {
157
+ content: [{ type: "text" as const, text: `MCP server "${spec.serverName}" not available${failedAgo !== null ? ` (failed ${failedAgo}s ago)` : ""}` }],
158
+ details: { error: "server_unavailable", server: spec.serverName },
159
+ };
160
+ }
161
+
162
+ const connection = state.manager.getConnection(spec.serverName);
163
+ if (!connection || connection.status !== "connected") {
164
+ return {
165
+ content: [{ type: "text" as const, text: `MCP server "${spec.serverName}" not connected` }],
166
+ details: { error: "not_connected", server: spec.serverName },
167
+ };
168
+ }
169
+
170
+ let uiSession: UiSessionRuntime | null = null;
171
+ let closeUiForStaleState = false;
172
+ let inFlightStarted = false;
173
+ const staleStateResult = (): AgentToolResult<DirectToolStateChangedDetails> => {
174
+ if (uiSession && !uiSession.reused) closeUiForStaleState = true;
175
+ return stateChangedResult();
176
+ };
177
+ const cancelStaleUi = async (): Promise<AgentToolResult<DirectToolStateChangedDetails>> => {
178
+ await notifyUiCancellation(uiSession, "MCP session changed during direct tool execution");
179
+ signal?.throwIfAborted();
180
+ return staleStateResult();
181
+ };
182
+
183
+ try {
184
+ if (!isActiveStateOwner(state)) return staleStateResult();
185
+ state.manager.touch(spec.serverName);
186
+ state.manager.incrementInFlight(spec.serverName);
187
+ inFlightStarted = true;
188
+
189
+ if (spec.resourceUri) {
190
+ const result = await connection.client.readResource({ uri: spec.resourceUri }, { signal });
191
+ signal?.throwIfAborted();
192
+ if (!isActiveStateOwner(state)) return stateChangedResult();
193
+ const content = (result.contents ?? []).map((item) => ({
194
+ type: "text" as const,
195
+ text: "text" in item
196
+ ? item.text
197
+ : ("blob" in item ? `[Binary data: ${item.mimeType ?? "unknown"}]` : JSON.stringify(item)),
198
+ }));
199
+ return {
200
+ content: content.length > 0 ? content : [{ type: "text" as const, text: "(empty resource)" }],
201
+ details: { server: spec.serverName, resourceUri: spec.resourceUri },
202
+ };
203
+ }
204
+
205
+ const hasUi = !!spec.uiResourceUri;
206
+ uiSession = hasUi
207
+ ? await waitForCallerWithLateCleanup(
208
+ () => startUiSession(state, {
209
+ serverName: spec.serverName,
210
+ toolName: spec.originalName,
211
+ toolArgs: params,
212
+ uiResourceUri: spec.uiResourceUri!,
213
+ streamMode: spec.uiStreamMode,
214
+ }),
215
+ signal,
216
+ (lateSession) => {
217
+ if (lateSession && !lateSession.reused) lateSession.close("caller cancelled during UI startup");
218
+ },
219
+ )
220
+ : null;
221
+ signal?.throwIfAborted();
222
+ if (!isActiveStateOwner(state)) return cancelStaleUi();
223
+
224
+ const sdkResult = await connection.client.callTool({
225
+ name: spec.originalName,
226
+ arguments: unflattenToolArguments(params, spec.inputSchema),
227
+ _meta: uiSession?.requestMeta,
228
+ }, CallToolResultSchema, { signal });
229
+ signal?.throwIfAborted();
230
+ if (!isActiveStateOwner(state)) return cancelStaleUi();
231
+ const result = asCallToolResult(sdkResult);
232
+ uiSession?.sendToolResult(result);
233
+
234
+ const content = transformMcpContent((result.content ?? []) as McpContent[]);
235
+ if (result.isError) {
236
+ let errorText = content.filter((item) => item.type === "text").map((item) => item.text).join("\n") || "Tool execution failed";
237
+ if (spec.inputSchema) errorText += `\n\nExpected parameters:\n${formatSchema(spec.inputSchema)}`;
238
+ return {
239
+ content: [{ type: "text" as const, text: `Error: ${errorText}` }],
240
+ details: { error: "tool_error", server: spec.serverName },
241
+ };
242
+ }
243
+
244
+ const resultText = content.filter((item) => item.type === "text").map((item) => item.text).join("\n") || "(empty result)";
245
+ if (hasUi) {
246
+ const uiMessage = uiSession?.reused
247
+ ? "Updated the open UI."
248
+ : "📺 Interactive UI is now open in your browser. I'll respond to your prompts and intents as you interact with it.";
249
+ return {
250
+ content: [{ type: "text" as const, text: `${resultText}\n\n${uiMessage}` }],
251
+ details: { server: spec.serverName, tool: spec.originalName, uiOpen: true },
252
+ };
253
+ }
254
+
255
+ return {
256
+ content: content.length > 0 ? content : [{ type: "text" as const, text: "(empty result)" }],
257
+ details: { server: spec.serverName, tool: spec.originalName },
258
+ };
259
+ } catch (error) {
260
+ await rethrowHostAbortAfterUiCancellation(signal, uiSession);
261
+ const message = error instanceof Error ? error.message : String(error);
262
+ await notifyUiCancellation(uiSession, message);
263
+ signal?.throwIfAborted();
264
+ if (!isActiveStateOwner(state)) return staleStateResult();
265
+ let errorText = `Failed to call tool: ${message}`;
266
+ if (spec.inputSchema) errorText += `\n\nExpected parameters:\n${formatSchema(spec.inputSchema)}`;
267
+ return {
268
+ content: [{ type: "text" as const, text: errorText }],
269
+ details: { error: "call_failed", server: spec.serverName },
270
+ };
271
+ } finally {
272
+ if (uiSession && (uiSession.reused || closeUiForStaleState)) uiSession.close(closeUiForStaleState ? "stale MCP session" : undefined);
273
+ if (inFlightStarted) {
274
+ state.manager.decrementInFlight(spec.serverName);
275
+ if (isActiveStateOwner(state)) state.manager.touch(spec.serverName);
276
+ }
277
+ }
278
+ };
279
+ }
@@ -1,77 +1,11 @@
1
- import type { AgentToolResult, AgentToolUpdateCallback, ExtensionContext } from "@bastani/atomic";
2
- import type { McpExtensionState } from "./state.ts";
3
- import type { DirectToolSpec, McpConfig, McpContent } from "./types.ts";
4
- import type { MetadataCache } from "./metadata-cache.ts";
5
- import { lazyConnect, getFailureAgeSeconds } from "./init.ts";
6
- import { isServerCacheValid } from "./metadata-cache.ts";
7
- import { formatSchema } from "./tool-metadata.ts";
8
- import { transformMcpContent } from "./tool-registrar.ts";
9
- import { maybeStartUiSession, type UiSessionRuntime } from "./ui-session.ts";
10
- import { formatToolName, isToolExcluded } from "./types.ts";
11
- import { resourceNameToToolName } from "./resource-tools.ts";
12
- import { authenticate, supportsOAuth } from "./mcp-auth-flow.ts";
13
- import { formatAuthRequiredMessage, unflattenToolArguments } from "./utils.ts";
1
+ import type { DirectToolSpec, McpConfig } from "./types.js";
2
+ import type { MetadataCache } from "./metadata-cache.js";
3
+ import { isServerCacheValid } from "./metadata-cache.js";
4
+ import { formatToolName, isToolExcluded } from "./types.js";
5
+ import { resourceNameToToolName } from "./resource-tools.js";
14
6
 
15
7
  const BUILTIN_NAMES = new Set(["read", "bash", "edit", "write", "grep", "find", "search", "ls", "mcp"]);
16
8
 
17
- type DirectAutoAuthResult =
18
- | { status: "skipped" }
19
- | { status: "success" }
20
- | { status: "failed"; message: string };
21
-
22
- function getDirectAuthRequiredMessage(
23
- state: McpExtensionState,
24
- serverName: string,
25
- defaultMessage = `MCP server "${serverName}" requires OAuth authentication. Run /mcp-auth ${serverName} first.`,
26
- ): string {
27
- return formatAuthRequiredMessage(state.config, serverName, defaultMessage);
28
- }
29
-
30
- function getDirectAuthFailedMessage(state: McpExtensionState, serverName: string, message: string): string {
31
- const customGuidance = state.config.settings?.authRequiredMessage;
32
- if (customGuidance) {
33
- return `OAuth authentication failed for "${serverName}": ${message}. ${getDirectAuthRequiredMessage(state, serverName)}`;
34
- }
35
- return `OAuth authentication failed for "${serverName}": ${message}. Run /mcp-auth ${serverName} first.`;
36
- }
37
-
38
- async function attemptDirectAutoAuth(
39
- state: McpExtensionState,
40
- serverName: string,
41
- ): Promise<DirectAutoAuthResult> {
42
- if (state.config.settings?.autoAuth !== true) {
43
- return { status: "skipped" };
44
- }
45
-
46
- const definition = state.config.mcpServers[serverName];
47
- if (!definition || !supportsOAuth(definition) || !definition.url) {
48
- return { status: "skipped" };
49
- }
50
-
51
- const grantType = definition.oauth ? definition.oauth.grantType ?? "authorization_code" : "authorization_code";
52
- if (!state.ui && grantType !== "client_credentials") {
53
- return {
54
- status: "failed",
55
- message: getDirectAuthRequiredMessage(
56
- state,
57
- serverName,
58
- `MCP server "${serverName}" requires OAuth authentication. Run /mcp-auth ${serverName} in an interactive session.`,
59
- ),
60
- };
61
- }
62
-
63
- try {
64
- await authenticate(serverName, definition.url, definition);
65
- return { status: "success" };
66
- } catch (error) {
67
- const message = error instanceof Error ? error.message : String(error);
68
- return {
69
- status: "failed",
70
- message: getDirectAuthFailedMessage(state, serverName, message),
71
- };
72
- }
73
- }
74
-
75
9
  interface DirectToolSelection {
76
10
  readonly servers: ReadonlySet<string>;
77
11
  readonly toolsByServer: ReadonlyMap<string, ReadonlySet<string>>;
@@ -278,172 +212,5 @@ export function buildProxyDescription(
278
212
  return desc;
279
213
  }
280
214
 
281
- type DirectToolExecute = (
282
- toolCallId: string,
283
- params: Record<string, unknown>,
284
- signal: AbortSignal | undefined,
285
- onUpdate: AgentToolUpdateCallback<Record<string, unknown>> | undefined,
286
- ctx: ExtensionContext,
287
- ) => Promise<AgentToolResult<Record<string, unknown>>>;
288
-
289
- export function createDirectToolExecutor(
290
- getState: () => McpExtensionState | null,
291
- getInitPromise: () => Promise<McpExtensionState> | null,
292
- spec: DirectToolSpec
293
- ): DirectToolExecute {
294
- return async function execute(_toolCallId, params) {
295
- let state = getState();
296
- const initPromise = getInitPromise();
297
-
298
- if (!state && initPromise) {
299
- try {
300
- state = await initPromise;
301
- } catch (error) {
302
- const message = error instanceof Error ? error.message : String(error);
303
- return {
304
- content: [{ type: "text" as const, text: `MCP initialization failed: ${message}` }],
305
- details: { error: "init_failed", message },
306
- };
307
- }
308
- }
309
- if (!state) {
310
- return {
311
- content: [{ type: "text" as const, text: "MCP not initialized" }],
312
- details: { error: "not_initialized" },
313
- };
314
- }
315
-
316
- let connected = await lazyConnect(state, spec.serverName);
317
- let autoAuthAttempted = false;
318
-
319
- if (!connected && state.manager.getConnection(spec.serverName)?.status === "needs-auth") {
320
- autoAuthAttempted = true;
321
- const autoAuth = await attemptDirectAutoAuth(state, spec.serverName);
322
- if (autoAuth.status === "failed") {
323
- return {
324
- content: [{ type: "text" as const, text: autoAuth.message }],
325
- details: { error: "auth_required", server: spec.serverName, message: autoAuth.message },
326
- };
327
- }
328
- if (autoAuth.status === "success") {
329
- await state.manager.close(spec.serverName);
330
- state.failureTracker.delete(spec.serverName);
331
- connected = await lazyConnect(state, spec.serverName);
332
- }
333
- }
334
-
335
- if (!connected) {
336
- const authConnection = state.manager.getConnection(spec.serverName);
337
- if (authConnection?.status === "needs-auth") {
338
- const message = getDirectAuthRequiredMessage(state, spec.serverName);
339
- return {
340
- content: [{ type: "text" as const, text: message }],
341
- details: { error: "auth_required", server: spec.serverName, message, autoAuthAttempted },
342
- };
343
- }
344
- const failedAgo = getFailureAgeSeconds(state, spec.serverName);
345
- return {
346
- content: [{ type: "text" as const, text: `MCP server "${spec.serverName}" not available${failedAgo !== null ? ` (failed ${failedAgo}s ago)` : ""}` }],
347
- details: { error: "server_unavailable", server: spec.serverName },
348
- };
349
- }
350
-
351
- const connection = state.manager.getConnection(spec.serverName);
352
- if (!connection || connection.status !== "connected") {
353
- return {
354
- content: [{ type: "text" as const, text: `MCP server "${spec.serverName}" not connected` }],
355
- details: { error: "not_connected", server: spec.serverName },
356
- };
357
- }
358
215
 
359
- let uiSession: UiSessionRuntime | null = null;
360
-
361
- try {
362
- state.manager.touch(spec.serverName);
363
- state.manager.incrementInFlight(spec.serverName);
364
-
365
- if (spec.resourceUri) {
366
- const result = await connection.client.readResource({ uri: spec.resourceUri });
367
- const content = (result.contents ?? []).map(c => ({
368
- type: "text" as const,
369
- text: "text" in c ? c.text : ("blob" in c ? `[Binary data: ${(c as { mimeType?: string }).mimeType ?? "unknown"}]` : JSON.stringify(c)),
370
- }));
371
- return {
372
- content: content.length > 0 ? content : [{ type: "text" as const, text: "(empty resource)" }],
373
- details: { server: spec.serverName, resourceUri: spec.resourceUri },
374
- };
375
- }
376
-
377
- const hasUi = !!spec.uiResourceUri;
378
- uiSession = hasUi
379
- ? await maybeStartUiSession(state, {
380
- serverName: spec.serverName,
381
- toolName: spec.originalName,
382
- toolArgs: params ?? {},
383
- uiResourceUri: spec.uiResourceUri!,
384
- streamMode: spec.uiStreamMode,
385
- })
386
- : null;
387
-
388
- const resultPromise = connection.client.callTool({
389
- name: spec.originalName,
390
- // Normalize provider-flattened argument keys (e.g. Gemini's `keywords[0]`)
391
- // back into arrays/objects before the MCP server validates them.
392
- // Schema-aware: literal dotted property names (e.g. `filter.name`) are
393
- // preserved unless the schema proves the head is a container.
394
- arguments: unflattenToolArguments(params, spec.inputSchema),
395
- _meta: uiSession?.requestMeta,
396
- });
397
-
398
- const result = await resultPromise;
399
- uiSession?.sendToolResult(result as unknown as import("@modelcontextprotocol/sdk/types.js").CallToolResult);
400
-
401
- const mcpContent = (result.content ?? []) as McpContent[];
402
- const content = transformMcpContent(mcpContent);
403
-
404
- if (result.isError) {
405
- let errorText = content.filter(c => c.type === "text").map(c => (c as { text: string }).text).join("\n") || "Tool execution failed";
406
- if (spec.inputSchema) {
407
- errorText += `\n\nExpected parameters:\n${formatSchema(spec.inputSchema)}`;
408
- }
409
- return {
410
- content: [{ type: "text" as const, text: `Error: ${errorText}` }],
411
- details: { error: "tool_error", server: spec.serverName },
412
- };
413
- }
414
-
415
- const resultText = content.filter(c => c.type === "text").map(c => (c as { text: string }).text).join("\n") || "(empty result)";
416
- if (hasUi) {
417
- const uiMessage = uiSession?.reused
418
- ? "Updated the open UI."
419
- : "📺 Interactive UI is now open in your browser. I'll respond to your prompts and intents as you interact with it.";
420
- return {
421
- content: [{ type: "text" as const, text: `${resultText}\n\n${uiMessage}` }],
422
- details: { server: spec.serverName, tool: spec.originalName, uiOpen: true },
423
- };
424
- }
425
-
426
- return {
427
- content: content.length > 0 ? content : [{ type: "text" as const, text: "(empty result)" }],
428
- details: { server: spec.serverName, tool: spec.originalName },
429
- };
430
- } catch (error) {
431
- const message = error instanceof Error ? error.message : String(error);
432
- uiSession?.sendToolCancelled(message);
433
- let errorText = `Failed to call tool: ${message}`;
434
- if (spec.inputSchema) {
435
- errorText += `\n\nExpected parameters:\n${formatSchema(spec.inputSchema)}`;
436
- }
437
- return {
438
- content: [{ type: "text" as const, text: errorText }],
439
- details: { error: "call_failed", server: spec.serverName },
440
- };
441
- } finally {
442
- if (uiSession?.reused) {
443
- uiSession.close();
444
- }
445
- state.manager.decrementInFlight(spec.serverName);
446
- state.manager.touch(spec.serverName);
447
- }
448
- };
449
- }
216
+ export { createDirectToolExecutor } from "./direct-tool-executor.js";
@@ -1,4 +1,4 @@
1
- import type { UiHostContext, UiResourceContent, UiResourceCsp } from "./types.ts";
1
+ import type { UiHostContext, UiResourceContent, UiResourceCsp } from "./types.js";
2
2
 
3
3
  // Use locally bundled AppBridge to avoid CDN Zod bundling issues
4
4
  const DEFAULT_APP_BRIDGE_MODULE_URL = "/app-bridge.bundle.js";
@@ -292,7 +292,9 @@ export function buildHostHtmlTemplate(input: HostHtmlTemplateInput): string {
292
292
  });
293
293
  eventSource.addEventListener("tool-cancelled", (event) => {
294
294
  try {
295
- bridge.sendToolCancelled(JSON.parse(event.data));
295
+ void bridge.sendToolCancelled(JSON.parse(event.data)).catch((error) => {
296
+ showError("Failed to forward cancellation: " + String(error));
297
+ });
296
298
  } catch (error) {
297
299
  showError("Failed to forward cancellation: " + String(error));
298
300
  }