@bastani/atomic 0.9.5-alpha.7 → 0.9.5-alpha.9

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 (317) hide show
  1. package/CHANGELOG.md +33 -2
  2. package/dist/builtin/cursor/package.json +2 -2
  3. package/dist/builtin/intercom/CHANGELOG.md +17 -0
  4. package/dist/builtin/intercom/README.md +27 -21
  5. package/dist/builtin/intercom/broker/broker.ts +3 -6
  6. package/dist/builtin/intercom/broker/paths.ts +42 -5
  7. package/dist/builtin/intercom/broker/spawn.ts +78 -10
  8. package/dist/builtin/intercom/config.ts +6 -3
  9. package/dist/builtin/intercom/contact-supervisor-tool.ts +6 -4
  10. package/dist/builtin/intercom/index-heavy.ts +1 -1
  11. package/dist/builtin/intercom/index.ts +162 -130
  12. package/dist/builtin/intercom/intercom-tool.ts +9 -3
  13. package/dist/builtin/intercom/package.json +10 -1
  14. package/dist/builtin/intercom/result-renderers.ts +1 -1
  15. package/dist/builtin/intercom/ui/compose.ts +2 -2
  16. package/dist/builtin/intercom/ui/inline-message.ts +2 -2
  17. package/dist/builtin/intercom/ui/session-list.ts +2 -2
  18. package/dist/builtin/mcp/CHANGELOG.md +11 -0
  19. package/dist/builtin/mcp/README.md +6 -6
  20. package/dist/builtin/mcp/direct-tools.ts +41 -23
  21. package/dist/builtin/mcp/index.ts +31 -4
  22. package/dist/builtin/mcp/init.ts +4 -43
  23. package/dist/builtin/mcp/metadata-hydration.ts +37 -0
  24. package/dist/builtin/mcp/package.json +1 -1
  25. package/dist/builtin/mcp/proxy-info-modes.ts +67 -14
  26. package/dist/builtin/mcp/startup-warmup.ts +98 -0
  27. package/dist/builtin/mcp/tool-result-renderer.ts +3 -3
  28. package/dist/builtin/subagents/CHANGELOG.md +18 -0
  29. package/dist/builtin/subagents/package.json +1 -1
  30. package/dist/builtin/subagents/src/extension/index.ts +14 -25
  31. package/dist/builtin/subagents/src/extension/startup-maintenance.ts +89 -0
  32. package/dist/builtin/subagents/src/runs/background/async-execution-common.ts +23 -18
  33. package/dist/builtin/subagents/src/runs/background/result-watcher.ts +20 -10
  34. package/dist/builtin/subagents/src/runs/background/subagent-runner-streaming.ts +13 -3
  35. package/dist/builtin/subagents/src/runs/foreground/execution-attempt.ts +10 -2
  36. package/dist/builtin/subagents/src/runs/shared/pi-spawn.ts +28 -1
  37. package/dist/builtin/subagents/src/tui/render-event-formatting.ts +15 -48
  38. package/dist/builtin/subagents/src/tui/render-layout.ts +9 -0
  39. package/dist/builtin/subagents/src/tui/render-widget-graph.ts +27 -25
  40. package/dist/builtin/subagents/src/tui/render-widget.ts +72 -66
  41. package/dist/builtin/subagents/src/tui/render.ts +1 -1
  42. package/dist/builtin/web-access/package.json +1 -1
  43. package/dist/builtin/workflows/CHANGELOG.md +29 -0
  44. package/dist/builtin/workflows/README.md +4 -2
  45. package/dist/builtin/workflows/builtin/goal-artifacts.ts +3 -1
  46. package/dist/builtin/workflows/builtin/goal-prompts.ts +23 -2
  47. package/dist/builtin/workflows/builtin/goal-reducer.ts +21 -0
  48. package/dist/builtin/workflows/builtin/goal-review.ts +60 -6
  49. package/dist/builtin/workflows/builtin/goal-runner.ts +71 -22
  50. package/dist/builtin/workflows/builtin/goal-types.ts +7 -1
  51. package/dist/builtin/workflows/builtin/ralph-core.ts +52 -4
  52. package/dist/builtin/workflows/builtin/ralph-review-gate.ts +10 -3
  53. package/dist/builtin/workflows/builtin/ralph-reviewer-prompt.ts +23 -2
  54. package/dist/builtin/workflows/builtin/ralph-runner.ts +38 -16
  55. package/dist/builtin/workflows/builtin/review-convergence.ts +111 -0
  56. package/dist/builtin/workflows/package.json +1 -1
  57. package/dist/builtin/workflows/skills/create-spec/SKILL.md +2 -0
  58. package/dist/builtin/workflows/skills/impeccable/SKILL.md +16 -13
  59. package/dist/builtin/workflows/skills/impeccable/reference/adapt.md +1 -0
  60. package/dist/builtin/workflows/skills/impeccable/reference/adapt.native.md +58 -0
  61. package/dist/builtin/workflows/skills/impeccable/reference/android.md +40 -0
  62. package/dist/builtin/workflows/skills/impeccable/reference/animate.md +2 -0
  63. package/dist/builtin/workflows/skills/impeccable/reference/audit.md +2 -0
  64. package/dist/builtin/workflows/skills/impeccable/reference/audit.native.md +139 -0
  65. package/dist/builtin/workflows/skills/impeccable/reference/bolder.md +69 -62
  66. package/dist/builtin/workflows/skills/impeccable/reference/critique.md +21 -7
  67. package/dist/builtin/workflows/skills/impeccable/reference/document.md +1 -1
  68. package/dist/builtin/workflows/skills/impeccable/reference/hooks.md +92 -0
  69. package/dist/builtin/workflows/skills/impeccable/reference/init.md +29 -7
  70. package/dist/builtin/workflows/skills/impeccable/reference/ios.md +45 -0
  71. package/dist/builtin/workflows/skills/impeccable/reference/layout.md +25 -1
  72. package/dist/builtin/workflows/skills/impeccable/reference/typeset.md +23 -1
  73. package/dist/builtin/workflows/skills/impeccable/scripts/context-signals.mjs +2 -1
  74. package/dist/builtin/workflows/skills/impeccable/scripts/context.mjs +75 -14
  75. package/dist/builtin/workflows/skills/impeccable/scripts/detector/browser/injected/index.mjs +1 -1
  76. package/dist/builtin/workflows/skills/impeccable/scripts/detector/cli/main.mjs +31 -0
  77. package/dist/builtin/workflows/skills/impeccable/scripts/detector/design-system.mjs +64 -0
  78. package/dist/builtin/workflows/skills/impeccable/scripts/detector/detect-antipatterns-browser.js +118 -11
  79. package/dist/builtin/workflows/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs +16 -11
  80. package/dist/builtin/workflows/skills/impeccable/scripts/detector/registry/antipatterns.mjs +66 -0
  81. package/dist/builtin/workflows/skills/impeccable/scripts/detector/rules/checks.mjs +42 -10
  82. package/dist/builtin/workflows/skills/impeccable/scripts/detector/shared/fonts.mjs +30 -0
  83. package/dist/builtin/workflows/skills/impeccable/scripts/detector/shared/page.mjs +4 -6
  84. package/dist/builtin/workflows/skills/impeccable/scripts/hook-admin.mjs +660 -0
  85. package/dist/builtin/workflows/skills/impeccable/scripts/hook-before-edit.mjs +516 -0
  86. package/dist/builtin/workflows/skills/impeccable/scripts/hook-lib.mjs +1764 -0
  87. package/dist/builtin/workflows/skills/impeccable/scripts/hook.mjs +61 -0
  88. package/dist/builtin/workflows/skills/impeccable/scripts/lib/impeccable-config.mjs +4 -2
  89. package/dist/builtin/workflows/skills/impeccable/scripts/lib/is-generated.mjs +2 -2
  90. package/dist/builtin/workflows/skills/impeccable/scripts/live/svelte-component.mjs +13 -16
  91. package/dist/builtin/workflows/skills/impeccable/scripts/live-accept.mjs +17 -11
  92. package/dist/builtin/workflows/skills/impeccable/scripts/live-browser.js +104 -37
  93. package/dist/builtin/workflows/skills/impeccable/scripts/live-wrap.mjs +9 -0
  94. package/dist/builtin/workflows/src/durable/backend.ts +12 -0
  95. package/dist/builtin/workflows/src/durable/child-primitive.ts +12 -8
  96. package/dist/builtin/workflows/src/durable/dbos-backend.ts +63 -2
  97. package/dist/builtin/workflows/src/durable/dbos-envelope.ts +28 -0
  98. package/dist/builtin/workflows/src/durable/resume-catalog.ts +12 -0
  99. package/dist/builtin/workflows/src/durable/resume-runtime.ts +5 -2
  100. package/dist/builtin/workflows/src/durable/stage-primitive.ts +165 -27
  101. package/dist/builtin/workflows/src/durable/types.ts +30 -1
  102. package/dist/builtin/workflows/src/engine/primitives/task.ts +1 -0
  103. package/dist/builtin/workflows/src/engine/run-durable-finalize.ts +1 -2
  104. package/dist/builtin/workflows/src/engine/run-returned-status.ts +50 -16
  105. package/dist/builtin/workflows/src/engine/run.ts +32 -32
  106. package/dist/builtin/workflows/src/engine/runtime.ts +5 -0
  107. package/dist/builtin/workflows/src/extension/extension-factory.ts +3 -0
  108. package/dist/builtin/workflows/src/extension/extension-lifecycle.ts +9 -2
  109. package/dist/builtin/workflows/src/extension/extension-runtime-state.ts +137 -27
  110. package/dist/builtin/workflows/src/extension/lifecycle-notifications.ts +22 -6
  111. package/dist/builtin/workflows/src/extension/public-types.ts +1 -1
  112. package/dist/builtin/workflows/src/extension/workflow-command-completions.ts +13 -1
  113. package/dist/builtin/workflows/src/extension/workflow-command-registration.ts +19 -4
  114. package/dist/builtin/workflows/src/extension/workflow-command-surfaces.ts +9 -0
  115. package/dist/builtin/workflows/src/extension/workflow-prompts.ts +2 -0
  116. package/dist/builtin/workflows/src/extension/workflow-run-control-command.ts +48 -23
  117. package/dist/builtin/workflows/src/extension/workflow-tool-control.ts +20 -8
  118. package/dist/builtin/workflows/src/extension/workflow-tool.ts +24 -8
  119. package/dist/builtin/workflows/src/runs/background/status.ts +4 -3
  120. package/dist/builtin/workflows/src/runs/foreground/executor-continuation.ts +13 -3
  121. package/dist/builtin/workflows/src/runs/foreground/executor-direct-helpers.ts +29 -8
  122. package/dist/builtin/workflows/src/runs/foreground/executor-hil.ts +2 -1
  123. package/dist/builtin/workflows/src/runs/foreground/executor-stage-factory.ts +4 -3
  124. package/dist/builtin/workflows/src/runs/foreground/stage-runner-controller.ts +18 -19
  125. package/dist/builtin/workflows/src/runs/foreground/stage-runner-unresolved-overflow.ts +38 -0
  126. package/dist/builtin/workflows/src/runs/shared/worktree-git.ts +155 -20
  127. package/dist/builtin/workflows/src/runs/shared/worktree-types.ts +6 -0
  128. package/dist/builtin/workflows/src/runs/shared/worktree.ts +2 -1
  129. package/dist/builtin/workflows/src/shared/persistence-restore-helpers.ts +18 -1
  130. package/dist/builtin/workflows/src/shared/persistence-restore.ts +23 -5
  131. package/dist/builtin/workflows/src/shared/persistence-session-entries.ts +4 -0
  132. package/dist/builtin/workflows/src/shared/returned-run-status.ts +116 -0
  133. package/dist/builtin/workflows/src/shared/workflow-failures-decisions.ts +2 -0
  134. package/dist/builtin/workflows/src/tui/graph-view-render-helpers.ts +21 -3
  135. package/dist/builtin/workflows/src/tui/graph-view-state.ts +3 -0
  136. package/dist/builtin/workflows/src/tui/graph-view-types.ts +3 -0
  137. package/dist/builtin/workflows/src/tui/status-list.ts +22 -15
  138. package/dist/builtin/workflows/src/tui/workflow-attach-pane.ts +4 -4
  139. package/dist/bun/internal-intercom-broker.d.ts +6 -0
  140. package/dist/bun/internal-intercom-broker.d.ts.map +1 -0
  141. package/dist/bun/internal-intercom-broker.js +39 -0
  142. package/dist/bun/internal-intercom-broker.js.map +1 -0
  143. package/dist/bun/split-loader.d.ts.map +1 -1
  144. package/dist/bun/split-loader.js +21 -8
  145. package/dist/bun/split-loader.js.map +1 -1
  146. package/dist/core/agent-session-auto-compaction.d.ts +21 -2
  147. package/dist/core/agent-session-auto-compaction.d.ts.map +1 -1
  148. package/dist/core/agent-session-auto-compaction.js +163 -11
  149. package/dist/core/agent-session-auto-compaction.js.map +1 -1
  150. package/dist/core/agent-session-events.d.ts.map +1 -1
  151. package/dist/core/agent-session-events.js +10 -1
  152. package/dist/core/agent-session-events.js.map +1 -1
  153. package/dist/core/agent-session-methods.d.ts +12 -3
  154. package/dist/core/agent-session-methods.d.ts.map +1 -1
  155. package/dist/core/agent-session-methods.js.map +1 -1
  156. package/dist/core/agent-session-models.d.ts +2 -2
  157. package/dist/core/agent-session-models.d.ts.map +1 -1
  158. package/dist/core/agent-session-models.js.map +1 -1
  159. package/dist/core/agent-session-prompt.d.ts.map +1 -1
  160. package/dist/core/agent-session-prompt.js +1 -0
  161. package/dist/core/agent-session-prompt.js.map +1 -1
  162. package/dist/core/agent-session-retry.d.ts +2 -0
  163. package/dist/core/agent-session-retry.d.ts.map +1 -1
  164. package/dist/core/agent-session-retry.js +152 -4
  165. package/dist/core/agent-session-retry.js.map +1 -1
  166. package/dist/core/agent-session-services.d.ts +1 -0
  167. package/dist/core/agent-session-services.d.ts.map +1 -1
  168. package/dist/core/agent-session-services.js +1 -0
  169. package/dist/core/agent-session-services.js.map +1 -1
  170. package/dist/core/agent-session-types.d.ts +15 -1
  171. package/dist/core/agent-session-types.d.ts.map +1 -1
  172. package/dist/core/agent-session-types.js.map +1 -1
  173. package/dist/core/agent-session.d.ts +6 -0
  174. package/dist/core/agent-session.d.ts.map +1 -1
  175. package/dist/core/agent-session.js +6 -0
  176. package/dist/core/agent-session.js.map +1 -1
  177. package/dist/core/compaction/context-compaction-runner.d.ts.map +1 -1
  178. package/dist/core/compaction/context-compaction-runner.js +36 -20
  179. package/dist/core/compaction/context-compaction-runner.js.map +1 -1
  180. package/dist/core/copilot-anthropic-sse-repair.d.ts +23 -0
  181. package/dist/core/copilot-anthropic-sse-repair.d.ts.map +1 -0
  182. package/dist/core/copilot-anthropic-sse-repair.js +340 -0
  183. package/dist/core/copilot-anthropic-sse-repair.js.map +1 -0
  184. package/dist/core/copilot-gemini-reasoning.d.ts +16 -8
  185. package/dist/core/copilot-gemini-reasoning.d.ts.map +1 -1
  186. package/dist/core/copilot-gemini-reasoning.js +27 -22
  187. package/dist/core/copilot-gemini-reasoning.js.map +1 -1
  188. package/dist/core/copilot-hosts.d.ts +12 -0
  189. package/dist/core/copilot-hosts.d.ts.map +1 -0
  190. package/dist/core/copilot-hosts.js +33 -0
  191. package/dist/core/copilot-hosts.js.map +1 -0
  192. package/dist/core/extensions/agent-events.d.ts +1 -1
  193. package/dist/core/extensions/agent-events.d.ts.map +1 -1
  194. package/dist/core/extensions/agent-events.js.map +1 -1
  195. package/dist/core/extensions/loader-virtual-modules.d.ts +8 -1
  196. package/dist/core/extensions/loader-virtual-modules.d.ts.map +1 -1
  197. package/dist/core/extensions/loader-virtual-modules.js +2 -1
  198. package/dist/core/extensions/loader-virtual-modules.js.map +1 -1
  199. package/dist/core/footer-data-provider.d.ts +6 -0
  200. package/dist/core/footer-data-provider.d.ts.map +1 -1
  201. package/dist/core/footer-data-provider.js +72 -29
  202. package/dist/core/footer-data-provider.js.map +1 -1
  203. package/dist/core/http-dispatcher.d.ts.map +1 -1
  204. package/dist/core/http-dispatcher.js +5 -5
  205. package/dist/core/http-dispatcher.js.map +1 -1
  206. package/dist/core/openai-responses-payload-sanitizer.d.ts +1 -0
  207. package/dist/core/openai-responses-payload-sanitizer.d.ts.map +1 -1
  208. package/dist/core/openai-responses-payload-sanitizer.js +24 -9
  209. package/dist/core/openai-responses-payload-sanitizer.js.map +1 -1
  210. package/dist/core/sdk-types.d.ts +2 -0
  211. package/dist/core/sdk-types.d.ts.map +1 -1
  212. package/dist/core/sdk-types.js.map +1 -1
  213. package/dist/core/sdk.d.ts.map +1 -1
  214. package/dist/core/sdk.js +1 -0
  215. package/dist/core/sdk.js.map +1 -1
  216. package/dist/core/settings-manager-basic-accessors.d.ts +1 -0
  217. package/dist/core/settings-manager-basic-accessors.d.ts.map +1 -1
  218. package/dist/core/settings-manager-basic-accessors.js +6 -0
  219. package/dist/core/settings-manager-basic-accessors.js.map +1 -1
  220. package/dist/core/settings-types.d.ts +1 -0
  221. package/dist/core/settings-types.d.ts.map +1 -1
  222. package/dist/core/settings-types.js.map +1 -1
  223. package/dist/core/slash-commands.d.ts +2 -0
  224. package/dist/core/slash-commands.d.ts.map +1 -1
  225. package/dist/core/slash-commands.js +141 -0
  226. package/dist/core/slash-commands.js.map +1 -1
  227. package/dist/index-extensions.d.ts +1 -1
  228. package/dist/index-extensions.d.ts.map +1 -1
  229. package/dist/index-extensions.js.map +1 -1
  230. package/dist/index.d.ts +1 -0
  231. package/dist/index.d.ts.map +1 -1
  232. package/dist/index.js +1 -0
  233. package/dist/index.js.map +1 -1
  234. package/dist/main-deferred-startup.d.ts +12 -0
  235. package/dist/main-deferred-startup.d.ts.map +1 -1
  236. package/dist/main-deferred-startup.js +23 -2
  237. package/dist/main-deferred-startup.js.map +1 -1
  238. package/dist/main-early-input.d.ts +41 -0
  239. package/dist/main-early-input.d.ts.map +1 -0
  240. package/dist/main-early-input.js +154 -0
  241. package/dist/main-early-input.js.map +1 -0
  242. package/dist/main.d.ts +0 -6
  243. package/dist/main.d.ts.map +1 -1
  244. package/dist/main.js +20 -14
  245. package/dist/main.js.map +1 -1
  246. package/dist/modes/interactive/components/chat-session-host-actions.d.ts.map +1 -1
  247. package/dist/modes/interactive/components/chat-session-host-actions.js +0 -1
  248. package/dist/modes/interactive/components/chat-session-host-actions.js.map +1 -1
  249. package/dist/modes/interactive/components/chat-session-host-events.d.ts.map +1 -1
  250. package/dist/modes/interactive/components/chat-session-host-events.js +15 -0
  251. package/dist/modes/interactive/components/chat-session-host-events.js.map +1 -1
  252. package/dist/modes/interactive/interactive-agent-events.d.ts.map +1 -1
  253. package/dist/modes/interactive/interactive-agent-events.js +25 -0
  254. package/dist/modes/interactive/interactive-agent-events.js.map +1 -1
  255. package/dist/modes/interactive/interactive-autocomplete.d.ts.map +1 -1
  256. package/dist/modes/interactive/interactive-autocomplete.js +21 -9
  257. package/dist/modes/interactive/interactive-autocomplete.js.map +1 -1
  258. package/dist/modes/interactive/interactive-deferred-startup.d.ts.map +1 -1
  259. package/dist/modes/interactive/interactive-deferred-startup.js +41 -28
  260. package/dist/modes/interactive/interactive-deferred-startup.js.map +1 -1
  261. package/dist/modes/interactive/interactive-hotkeys-debug.d.ts.map +1 -1
  262. package/dist/modes/interactive/interactive-hotkeys-debug.js +1 -0
  263. package/dist/modes/interactive/interactive-hotkeys-debug.js.map +1 -1
  264. package/dist/modes/interactive/interactive-input-handling.d.ts.map +1 -1
  265. package/dist/modes/interactive/interactive-input-handling.js +318 -185
  266. package/dist/modes/interactive/interactive-input-handling.js.map +1 -1
  267. package/dist/modes/interactive/interactive-mode-base.d.ts +12 -0
  268. package/dist/modes/interactive/interactive-mode-base.d.ts.map +1 -1
  269. package/dist/modes/interactive/interactive-mode-base.js +39 -0
  270. package/dist/modes/interactive/interactive-mode-base.js.map +1 -1
  271. package/dist/modes/interactive/interactive-mode-deps.d.ts +1 -1
  272. package/dist/modes/interactive/interactive-mode-deps.d.ts.map +1 -1
  273. package/dist/modes/interactive/interactive-mode-deps.js +1 -1
  274. package/dist/modes/interactive/interactive-mode-deps.js.map +1 -1
  275. package/dist/modes/interactive/interactive-mode-surface.d.ts +6 -2
  276. package/dist/modes/interactive/interactive-mode-surface.d.ts.map +1 -1
  277. package/dist/modes/interactive/interactive-mode-surface.js.map +1 -1
  278. package/dist/modes/interactive/interactive-mode-types.d.ts +3 -0
  279. package/dist/modes/interactive/interactive-mode-types.d.ts.map +1 -1
  280. package/dist/modes/interactive/interactive-mode-types.js.map +1 -1
  281. package/dist/modes/interactive/interactive-model-routing.d.ts.map +1 -1
  282. package/dist/modes/interactive/interactive-model-routing.js +3 -1
  283. package/dist/modes/interactive/interactive-model-routing.js.map +1 -1
  284. package/dist/modes/interactive/interactive-process-lifecycle.d.ts.map +1 -1
  285. package/dist/modes/interactive/interactive-process-lifecycle.js +0 -3
  286. package/dist/modes/interactive/interactive-process-lifecycle.js.map +1 -1
  287. package/dist/modes/interactive/interactive-render-chat.d.ts.map +1 -1
  288. package/dist/modes/interactive/interactive-render-chat.js +36 -10
  289. package/dist/modes/interactive/interactive-render-chat.js.map +1 -1
  290. package/dist/modes/interactive/interactive-session-routing.d.ts.map +1 -1
  291. package/dist/modes/interactive/interactive-session-routing.js +5 -1
  292. package/dist/modes/interactive/interactive-session-routing.js.map +1 -1
  293. package/dist/modes/interactive/interactive-startup.d.ts.map +1 -1
  294. package/dist/modes/interactive/interactive-startup.js +26 -22
  295. package/dist/modes/interactive/interactive-startup.js.map +1 -1
  296. package/dist/modes/interactive/theme/global-theme.d.ts.map +1 -1
  297. package/dist/modes/interactive/theme/global-theme.js +26 -2
  298. package/dist/modes/interactive/theme/global-theme.js.map +1 -1
  299. package/dist/utils/fs-watch.d.ts +24 -1
  300. package/dist/utils/fs-watch.d.ts.map +1 -1
  301. package/dist/utils/fs-watch.js +60 -5
  302. package/dist/utils/fs-watch.js.map +1 -1
  303. package/docs/compaction.md +8 -0
  304. package/docs/development.md +4 -0
  305. package/docs/extensions.md +5 -0
  306. package/docs/json.md +3 -1
  307. package/docs/providers.md +1 -0
  308. package/docs/quickstart.md +1 -1
  309. package/docs/rpc.md +3 -1
  310. package/docs/settings.md +27 -1
  311. package/docs/subagents.md +4 -0
  312. package/docs/terminal-setup.md +4 -0
  313. package/docs/usage.md +2 -2
  314. package/docs/windows.md +4 -0
  315. package/docs/workflows.md +21 -9
  316. package/npm-shrinkwrap.json +513 -23
  317. package/package.json +3 -2
@@ -72,6 +72,37 @@ async function attemptDirectAutoAuth(
72
72
  }
73
73
  }
74
74
 
75
+ interface DirectToolSelection {
76
+ readonly servers: ReadonlySet<string>;
77
+ readonly toolsByServer: ReadonlyMap<string, ReadonlySet<string>>;
78
+ }
79
+
80
+ function parseDirectToolSelection(items: readonly string[] | undefined): DirectToolSelection {
81
+ const servers = new Set<string>();
82
+ const toolsByServer = new Map<string, Set<string>>();
83
+ for (const rawItem of items ?? []) {
84
+ const item = rawItem.replace(/\/+$/, "");
85
+ if (!item) continue;
86
+ if (!item.includes("/")) {
87
+ servers.add(item);
88
+ continue;
89
+ }
90
+ const [server, tool] = item.split("/", 2);
91
+ if (!server) continue;
92
+ if (!tool) {
93
+ servers.add(server);
94
+ continue;
95
+ }
96
+ if (!toolsByServer.has(server)) toolsByServer.set(server, new Set());
97
+ toolsByServer.get(server)!.add(tool);
98
+ }
99
+ return { servers, toolsByServer };
100
+ }
101
+
102
+ function directToolSelectionIncludes(selection: DirectToolSelection, serverName: string): boolean {
103
+ return selection.servers.has(serverName) || selection.toolsByServer.has(serverName);
104
+ }
105
+
75
106
  export function resolveDirectTools(
76
107
  config: McpConfig,
77
108
  cache: MetadataCache | null,
@@ -83,24 +114,7 @@ export function resolveDirectTools(
83
114
 
84
115
  const seenNames = new Set<string>();
85
116
 
86
- const envServers = new Set<string>();
87
- const envTools = new Map<string, Set<string>>();
88
- if (envOverride) {
89
- for (let item of envOverride) {
90
- item = item.replace(/\/+$/, "");
91
- if (item.includes("/")) {
92
- const [server, tool] = item.split("/", 2);
93
- if (server && tool) {
94
- if (!envTools.has(server)) envTools.set(server, new Set());
95
- envTools.get(server)!.add(tool);
96
- } else if (server) {
97
- envServers.add(server);
98
- }
99
- } else if (item) {
100
- envServers.add(item);
101
- }
102
- }
103
- }
117
+ const envSelection = parseDirectToolSelection(envOverride);
104
118
 
105
119
  const globalDirect = config.settings?.directTools;
106
120
 
@@ -111,10 +125,10 @@ export function resolveDirectTools(
111
125
  let toolFilter: true | string[] | false = false;
112
126
 
113
127
  if (envOverride) {
114
- if (envServers.has(serverName)) {
128
+ if (envSelection.servers.has(serverName)) {
115
129
  toolFilter = true;
116
- } else if (envTools.has(serverName)) {
117
- toolFilter = [...envTools.get(serverName)!];
130
+ } else if (envSelection.toolsByServer.has(serverName)) {
131
+ toolFilter = [...envSelection.toolsByServer.get(serverName)!];
118
132
  }
119
133
  } else {
120
134
  if (definition.directTools !== undefined) {
@@ -182,14 +196,18 @@ export function resolveDirectTools(
182
196
  export function getMissingConfiguredDirectToolServers(
183
197
  config: McpConfig,
184
198
  cache: MetadataCache | null,
199
+ envOverride?: readonly string[],
185
200
  ): string[] {
186
201
  const missing: string[] = [];
187
202
  const globalDirect = config.settings?.directTools;
188
-
203
+ const envSelection = parseDirectToolSelection(envOverride);
189
204
  for (const [serverName, definition] of Object.entries(config.mcpServers)) {
190
- const hasDirectTools = definition.directTools !== undefined
205
+ const hasConfiguredDirectTools = definition.directTools !== undefined
191
206
  ? !!definition.directTools
192
207
  : !!globalDirect;
208
+ const hasDirectTools = envOverride
209
+ ? directToolSelectionIncludes(envSelection, serverName)
210
+ : hasConfiguredDirectTools;
193
211
 
194
212
  if (!hasDirectTools) continue;
195
213
 
@@ -39,6 +39,7 @@ export default function mcpAdapter(pi: ExtensionAPI) {
39
39
  let lifecycleGeneration = 0;
40
40
  let registeredDirectToolNames = new Set<string>();
41
41
  let registeredProxyTool = false;
42
+ let startupWarmupCancel: (() => void) | null = null;
42
43
 
43
44
  async function registerDirectToolsFromConfig(
44
45
  config: McpConfig,
@@ -50,13 +51,14 @@ export default function mcpAdapter(pi: ExtensionAPI) {
50
51
  ]);
51
52
  const prefix = config.settings?.toolPrefix ?? "server";
52
53
  const envRaw = process.env.MCP_DIRECT_TOOLS;
54
+ const envDirectTools = envRaw?.split(",").map(s => s.trim()).filter(Boolean);
53
55
  const directSpecs = envRaw === "__none__"
54
56
  ? []
55
57
  : resolveDirectTools(
56
58
  config,
57
59
  cache,
58
60
  prefix,
59
- envRaw?.split(",").map(s => s.trim()).filter(Boolean),
61
+ envDirectTools,
60
62
  );
61
63
  for (const spec of directSpecs) {
62
64
  if (registeredDirectToolNames.has(spec.prefixedName)) continue;
@@ -75,7 +77,7 @@ export default function mcpAdapter(pi: ExtensionAPI) {
75
77
  refreshTools?.();
76
78
  return {
77
79
  directToolCount: directSpecs.length,
78
- missingConfiguredDirectToolServers: getMissingConfiguredDirectToolServers(config, cache),
80
+ missingConfiguredDirectToolServers: getMissingConfiguredDirectToolServers(config, cache, envDirectTools),
79
81
  };
80
82
  }
81
83
 
@@ -129,12 +131,18 @@ export default function mcpAdapter(pi: ExtensionAPI) {
129
131
  type: "string",
130
132
  });
131
133
 
134
+ function cancelStartupWarmup(): void {
135
+ startupWarmupCancel?.();
136
+ startupWarmupCancel = null;
137
+ }
138
+
132
139
  pi.on("session_start", async (_event, ctx) => {
133
140
  const generation = ++lifecycleGeneration;
134
141
  const previousState = state;
135
142
  state = null;
136
143
  initPromise = null;
137
144
  registeredDirectToolNames = new Set<string>();
145
+ cancelStartupWarmup();
138
146
 
139
147
  try {
140
148
  const config = loadMcpConfig(earlyConfigPath, ctx.cwd);
@@ -168,7 +176,10 @@ export default function mcpAdapter(pi: ExtensionAPI) {
168
176
  throw new Error("Stale MCP session initialization cancelled before startup");
169
177
  }
170
178
 
171
- const { initializeMcp, updateStatusBar } = await import("./init.ts");
179
+ const [{ initializeMcp, updateStatusBar }, { scheduleMcpStartupWarmup }] = await Promise.all([
180
+ import("./init.ts"),
181
+ import("./startup-warmup.ts"),
182
+ ]);
172
183
  if (generation !== lifecycleGeneration || !isContextActive(ctx)) {
173
184
  throw new Error("Stale MCP session initialization cancelled before startup");
174
185
  }
@@ -193,6 +204,21 @@ export default function mcpAdapter(pi: ExtensionAPI) {
193
204
  ) {
194
205
  registerProxyTool();
195
206
  }
207
+ let cancelWarmup: (() => void) | null = null;
208
+ const warmup = scheduleMcpStartupWarmup(nextState, {
209
+ shouldContinue: () => generation === lifecycleGeneration && state === nextState,
210
+ onDirectToolsChanged: async () => {
211
+ if (generation !== lifecycleGeneration || state !== nextState) return;
212
+ await registerDirectTools(nextState);
213
+ },
214
+ onSettled: () => {
215
+ if (generation === lifecycleGeneration && state === nextState && startupWarmupCancel === cancelWarmup) {
216
+ startupWarmupCancel = null;
217
+ }
218
+ },
219
+ });
220
+ cancelWarmup = () => warmup.cancel();
221
+ startupWarmupCancel = cancelWarmup;
196
222
  if (initPromise === promiseRef.current) {
197
223
  initPromise = null;
198
224
  }
@@ -226,6 +252,7 @@ export default function mcpAdapter(pi: ExtensionAPI) {
226
252
  state = null;
227
253
  initPromise = null;
228
254
  registeredDirectToolNames = new Set<string>();
255
+ cancelStartupWarmup();
229
256
 
230
257
  try {
231
258
  await Promise.all([
@@ -409,7 +436,7 @@ export default function mcpAdapter(pi: ExtensionAPI) {
409
436
  return executeConnect(state, params.connect);
410
437
  }
411
438
  if (params.describe) {
412
- return executeDescribe(state, params.describe);
439
+ return executeDescribe(state, params.describe, params.server);
413
440
  }
414
441
  if (params.search) {
415
442
  return executeSearch(state, params.search, params.regex, params.server, params.includeSchemas);
@@ -21,7 +21,6 @@ import { buildToolMetadata, totalToolCount } from "./tool-metadata.ts";
21
21
  import { UiResourceHandler } from "./ui-resource-handler.ts";
22
22
  import { openUrl, parallelLimit } from "./utils.ts";
23
23
  import { logger } from "./logger.ts";
24
- import { getMissingConfiguredDirectToolServers } from "./direct-tools.ts";
25
24
 
26
25
  const FAILURE_BACKOFF_MS = 60 * 1000;
27
26
 
@@ -75,10 +74,7 @@ export async function initializeMcp(
75
74
  const cachePath = getMetadataCachePath();
76
75
  const cacheFileExists = existsSync(cachePath);
77
76
  let cache = loadMetadataCache();
78
- let bootstrapAll = false;
79
-
80
77
  if (!cacheFileExists) {
81
- bootstrapAll = true;
82
78
  saveMetadataCache({ version: 1, servers: {} });
83
79
  } else if (!cache) {
84
80
  cache = { version: 1, servers: {} };
@@ -105,12 +101,10 @@ export async function initializeMcp(
105
101
  }
106
102
  }
107
103
 
108
- const startupServers = bootstrapAll
109
- ? serverEntries
110
- : serverEntries.filter(([, definition]) => {
111
- const mode = definition.lifecycle ?? "lazy";
112
- return mode === "keep-alive" || mode === "eager";
113
- });
104
+ const startupServers = serverEntries.filter(([, definition]) => {
105
+ const mode = definition.lifecycle ?? "lazy";
106
+ return mode === "keep-alive" || mode === "eager";
107
+ });
114
108
 
115
109
  if (ctx.hasUI && startupServers.length > 0) {
116
110
  ctx.ui.setStatus("mcp", `MCP: connecting to ${startupServers.length} servers...`);
@@ -160,39 +154,6 @@ export async function initializeMcp(
160
154
  ctx.ui.notify(msg, "info");
161
155
  }
162
156
 
163
- const envDirect = process.env.MCP_DIRECT_TOOLS;
164
- if (envDirect !== "__none__") {
165
- const currentCache = loadMetadataCache();
166
- const missingCacheServers = getMissingConfiguredDirectToolServers(config, currentCache);
167
-
168
- if (missingCacheServers.length > 0) {
169
- const bootstrapResults = await parallelLimit(
170
- missingCacheServers.filter(name => !results.some(r => r.name === name && r.connection)),
171
- 10,
172
- async (name) => {
173
- const definition = config.mcpServers[name];
174
- try {
175
- const connection = await manager.connect(name, definition);
176
- if (connection.status === "needs-auth") {
177
- return { name, ok: false };
178
- }
179
- const { metadata } = buildToolMetadata(connection.tools, connection.resources, definition, name, prefix);
180
- toolMetadata.set(name, metadata);
181
- updateMetadataCache(state, name);
182
- return { name, ok: true };
183
- } catch (error) {
184
- const message = error instanceof Error ? error.message : String(error);
185
- logger.debug(`MCP: direct-tools bootstrap failed for ${name}: ${message}`);
186
- return { name, ok: false };
187
- }
188
- },
189
- );
190
- const bootstrapped = bootstrapResults.filter(r => r.ok).map(r => r.name);
191
- if (bootstrapped.length > 0 && ctx.hasUI) {
192
- ctx.ui.notify(`MCP: direct tools for ${bootstrapped.join(", ")} will be available after restart`, "info");
193
- }
194
- }
195
- }
196
157
 
197
158
  lifecycle.setReconnectCallback((serverName) => {
198
159
  updateServerMetadata(state, serverName);
@@ -0,0 +1,37 @@
1
+ import type { McpExtensionState } from "./state.ts";
2
+ import { lazyConnect, updateMetadataCache, updateServerMetadata } from "./init.ts";
3
+ import { parallelLimit } from "./utils.ts";
4
+
5
+ export async function hydrateServerMetadata(
6
+ state: McpExtensionState,
7
+ serverName: string,
8
+ ): Promise<boolean> {
9
+ if (state.toolMetadata.has(serverName)) return true;
10
+ if (!state.config.mcpServers[serverName]) return false;
11
+
12
+ const connection = state.manager.getConnection(serverName);
13
+ if (connection?.status === "connected") {
14
+ updateServerMetadata(state, serverName);
15
+ updateMetadataCache(state, serverName);
16
+ return state.toolMetadata.has(serverName);
17
+ }
18
+
19
+ return lazyConnect(state, serverName);
20
+ }
21
+
22
+ export async function hydrateMissingMetadata(
23
+ state: McpExtensionState,
24
+ options?: { server?: string },
25
+ ): Promise<void> {
26
+ if (options?.server) {
27
+ await hydrateServerMetadata(state, options.server);
28
+ return;
29
+ }
30
+
31
+ const missingServers = Object.keys(state.config.mcpServers).filter(
32
+ (serverName) => !state.toolMetadata.has(serverName),
33
+ );
34
+ await parallelLimit(missingServers, 10, async (serverName) => {
35
+ await hydrateServerMetadata(state, serverName);
36
+ });
37
+ }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bastani/mcp",
3
- "version": "0.9.5-alpha.7",
3
+ "version": "0.9.5-alpha.9",
4
4
  "private": true,
5
5
  "description": "Atomic extension that adapts MCP (Model Context Protocol) servers into the coding agent. Fork of: https://github.com/nicobailon/pi-mcp-adapter",
6
6
  "contributors": [
@@ -1,9 +1,10 @@
1
1
  import type { McpExtensionState } from "./state.ts";
2
2
  import type { ToolMetadata } from "./types.ts";
3
- import { parseUiPromptHandoff } from "./types.ts";
3
+ import { getServerPrefix, parseUiPromptHandoff } from "./types.ts";
4
4
  import { getFailureAgeSeconds } from "./init.ts";
5
5
  import { findToolByName, formatSchema } from "./tool-metadata.ts";
6
6
  import { truncateAtWord } from "./utils.ts";
7
+ import { hydrateMissingMetadata } from "./metadata-hydration.ts";
7
8
  import type { ProxyToolResult } from "./proxy-types.ts";
8
9
 
9
10
  export function executeUiMessages(state: McpExtensionState): ProxyToolResult {
@@ -140,26 +141,73 @@ export function executeStatus(state: McpExtensionState): ProxyToolResult {
140
141
  };
141
142
  }
142
143
 
143
- export function executeDescribe(state: McpExtensionState, toolName: string): ProxyToolResult {
144
- let serverName: string | undefined;
145
- let toolMeta: ToolMetadata | undefined;
144
+ function findToolMetadata(
145
+ state: McpExtensionState,
146
+ toolName: string,
147
+ server?: string,
148
+ ): { serverName: string; toolMeta: ToolMetadata } | null {
149
+ for (const [serverName, metadata] of state.toolMetadata.entries()) {
150
+ if (server && serverName !== server) continue;
151
+ const toolMeta = findToolByName(metadata, toolName);
152
+ if (toolMeta) return { serverName, toolMeta };
153
+ }
154
+ return null;
155
+ }
146
156
 
147
- for (const [server, metadata] of state.toolMetadata.entries()) {
148
- const found = findToolByName(metadata, toolName);
149
- if (found) {
150
- serverName = server;
151
- toolMeta = found;
152
- break;
157
+ function normalizeToolAlias(value: string): string {
158
+ return value.replace(/-/g, "_");
159
+ }
160
+
161
+ function prefixHydrationCandidates(state: McpExtensionState, toolName: string): string[] {
162
+ const prefixMode = state.config.settings?.toolPrefix ?? "server";
163
+ if (prefixMode === "none") return [];
164
+ const normalizedToolName = normalizeToolAlias(toolName);
165
+ return Object.keys(state.config.mcpServers)
166
+ .map((serverName) => ({ serverName, prefix: normalizeToolAlias(getServerPrefix(serverName, prefixMode)) }))
167
+ .filter(({ prefix }) => prefix.length > 0 && normalizedToolName.startsWith(`${prefix}_`))
168
+ .sort((a, b) => b.prefix.length - a.prefix.length)
169
+ .map(({ serverName }) => serverName);
170
+ }
171
+
172
+ async function hydrateDescribeMetadata(state: McpExtensionState, toolName: string, server?: string): Promise<void> {
173
+ if (server) {
174
+ await hydrateMissingMetadata(state, { server });
175
+ return;
176
+ }
177
+
178
+ const candidates = prefixHydrationCandidates(state, toolName);
179
+ if (candidates.length > 0) {
180
+ for (const candidate of candidates) {
181
+ await hydrateMissingMetadata(state, { server: candidate });
182
+ if (findToolMetadata(state, toolName, candidate)) return;
153
183
  }
184
+ return;
185
+ }
186
+
187
+ if (findToolMetadata(state, toolName)) return;
188
+ await hydrateMissingMetadata(state);
189
+ }
190
+
191
+ export async function executeDescribe(
192
+ state: McpExtensionState,
193
+ toolName: string,
194
+ server?: string,
195
+ ): Promise<ProxyToolResult> {
196
+ let found = findToolMetadata(state, toolName, server);
197
+ if (!found) {
198
+ await hydrateDescribeMetadata(state, toolName, server);
199
+ found = findToolMetadata(state, toolName, server);
154
200
  }
155
201
 
156
- if (!serverName || !toolMeta) {
202
+ if (!found) {
157
203
  return {
158
204
  content: [{ type: "text" as const, text: `Tool "${toolName}" not found. Use mcp({ search: "..." }) to search.` }],
159
205
  details: { mode: "describe", error: "tool_not_found", requestedTool: toolName },
160
206
  };
161
207
  }
162
208
 
209
+ const { serverName, toolMeta } = found;
210
+
163
211
  let text = `${toolMeta.name}\n`;
164
212
  text += `Server: ${serverName}\n`;
165
213
  if (toolMeta.resourceUri) {
@@ -181,13 +229,13 @@ export function executeDescribe(state: McpExtensionState, toolName: string): Pro
181
229
  };
182
230
  }
183
231
 
184
- export function executeSearch(
232
+ export async function executeSearch(
185
233
  state: McpExtensionState,
186
234
  query: string,
187
235
  regex?: boolean,
188
236
  server?: string,
189
237
  includeSchemas?: boolean,
190
- ): ProxyToolResult {
238
+ ): Promise<ProxyToolResult> {
191
239
  const showSchemas = includeSchemas !== false;
192
240
 
193
241
  const matches: Array<{ server: string; tool: ToolMetadata }> = [];
@@ -213,6 +261,7 @@ export function executeSearch(
213
261
  details: { mode: "search", error: "invalid_pattern", query },
214
262
  };
215
263
  }
264
+ await hydrateMissingMetadata(state, { server });
216
265
 
217
266
  for (const [serverName, metadata] of state.toolMetadata.entries()) {
218
267
  if (server && serverName !== server) continue;
@@ -270,7 +319,7 @@ export function executeSearch(
270
319
  };
271
320
  }
272
321
 
273
- export function executeList(state: McpExtensionState, server: string): ProxyToolResult {
322
+ export async function executeList(state: McpExtensionState, server: string): Promise<ProxyToolResult> {
274
323
  if (!state.config.mcpServers[server]) {
275
324
  return {
276
325
  content: [{ type: "text" as const, text: `Server "${server}" not found. Use mcp({}) to see available servers.` }],
@@ -278,6 +327,10 @@ export function executeList(state: McpExtensionState, server: string): ProxyTool
278
327
  };
279
328
  }
280
329
 
330
+ if (!state.toolMetadata.has(server)) {
331
+ await hydrateMissingMetadata(state, { server });
332
+ }
333
+
281
334
  const metadata = state.toolMetadata.get(server);
282
335
  const toolNames = metadata?.map(m => m.name) ?? [];
283
336
  const connection = state.manager.getConnection(server);
@@ -0,0 +1,98 @@
1
+ import type { McpExtensionState } from "./state.ts";
2
+ import { getMissingConfiguredDirectToolServers } from "./direct-tools.ts";
3
+ import { loadMetadataCache } from "./metadata-cache.ts";
4
+ import { buildToolMetadata } from "./tool-metadata.ts";
5
+ import { parallelLimit } from "./utils.ts";
6
+ import { logger } from "./logger.ts";
7
+ import { updateMetadataCache, updateStatusBar } from "./init.ts";
8
+
9
+ export interface McpStartupWarmupOptions {
10
+ shouldContinue?: () => boolean;
11
+ onDirectToolsChanged?: () => void | Promise<void>;
12
+ onSettled?: () => void;
13
+ }
14
+
15
+ export interface McpStartupWarmupHandle {
16
+ readonly promise: Promise<void>;
17
+ cancel(): void;
18
+ }
19
+
20
+ function deferToMacrotask(): Promise<void> {
21
+ return new Promise((resolve) => setImmediate(resolve));
22
+ }
23
+
24
+ export function scheduleMcpStartupWarmup(
25
+ state: McpExtensionState,
26
+ options: McpStartupWarmupOptions = {},
27
+ ): McpStartupWarmupHandle {
28
+ let cancelled = false;
29
+ const shouldContinue = (): boolean => !cancelled && (options.shouldContinue?.() ?? true);
30
+
31
+ const promise = (async () => {
32
+ await deferToMacrotask();
33
+ if (!shouldContinue()) return;
34
+
35
+ const envDirect = process.env.MCP_DIRECT_TOOLS;
36
+ if (envDirect === "__none__") return;
37
+
38
+ const envDirectTools = envDirect?.split(",").map((item) => item.trim()).filter(Boolean);
39
+ const missingCacheServers = getMissingConfiguredDirectToolServers(state.config, loadMetadataCache(), envDirectTools)
40
+ .filter((name) => state.manager.getConnection(name)?.status !== "connected");
41
+ if (missingCacheServers.length === 0) return;
42
+
43
+ const prefix = state.config.settings?.toolPrefix ?? "server";
44
+ const results = await parallelLimit(missingCacheServers, 10, async (name) => {
45
+ if (!shouldContinue()) return { name, ok: false };
46
+ const definition = state.config.mcpServers[name];
47
+ if (!definition) return { name, ok: false };
48
+ try {
49
+ const connection = await state.manager.connect(name, definition);
50
+ if (!shouldContinue()) {
51
+ if (state.manager.getConnection(name) === connection) {
52
+ await state.manager.close(name);
53
+ }
54
+ return { name, ok: false };
55
+ }
56
+ if (connection.status === "needs-auth") return { name, ok: false };
57
+ const { metadata } = buildToolMetadata(connection.tools, connection.resources, definition, name, prefix);
58
+ state.toolMetadata.set(name, metadata);
59
+ updateMetadataCache(state, name);
60
+ return { name, ok: true };
61
+ } catch (error) {
62
+ const message = error instanceof Error ? error.message : String(error);
63
+ logger.debug(`MCP: background direct-tools warmup failed for ${name}: ${message}`);
64
+ return { name, ok: false };
65
+ }
66
+ });
67
+
68
+ if (!shouldContinue()) return;
69
+ const warmed = results.filter((result) => result.ok).map((result) => result.name);
70
+ if (warmed.length === 0) return;
71
+ updateStatusBar(state);
72
+ if (!shouldContinue()) return;
73
+ await options.onDirectToolsChanged?.();
74
+ if (!shouldContinue()) return;
75
+ if (state.ui) {
76
+ state.ui.notify(`MCP: direct tools for ${warmed.join(", ")} are now available`, "info");
77
+ }
78
+ })()
79
+ .catch((error) => {
80
+ const message = error instanceof Error ? error.message : String(error);
81
+ logger.debug(`MCP: background startup warmup failed: ${message}`);
82
+ })
83
+ .finally(() => {
84
+ try {
85
+ options.onSettled?.();
86
+ } catch (error) {
87
+ const message = error instanceof Error ? error.message : String(error);
88
+ logger.debug(`MCP: background startup warmup settled callback failed: ${message}`);
89
+ }
90
+ });
91
+
92
+ return {
93
+ promise,
94
+ cancel() {
95
+ cancelled = true;
96
+ },
97
+ };
98
+ }
@@ -1,7 +1,7 @@
1
- import type { AgentToolResult, ToolRenderResultOptions } from "@bastani/atomic";
1
+ import { keyText, type AgentToolResult, type ToolRenderResultOptions } from "@bastani/atomic";
2
2
  import { Text } from "@earendil-works/pi-tui";
3
3
 
4
- type McpToolResultDetails = Record<string, unknown> & { error?: unknown };
4
+ export type McpToolResultDetails = Record<string, unknown> & { error?: unknown };
5
5
  type McpToolContentBlock = AgentToolResult<McpToolResultDetails>["content"][number];
6
6
 
7
7
  interface RenderTheme {
@@ -58,7 +58,7 @@ export function renderMcpToolResult(
58
58
  .map((line) => line === "…" ? theme.fg("muted", line) : theme.fg("toolOutput", line))
59
59
  .join("\n");
60
60
  const hint = display.truncated && !options.expanded
61
- ? `\n${theme.fg("muted", "(CTRL+O Expand)")}`
61
+ ? `\n${theme.fg("muted", `(${keyText("app.tools.expand")} Expand)`)}`
62
62
  : "";
63
63
 
64
64
  return new Text(`${output}${hint}`, 0, 0);
@@ -2,6 +2,24 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [0.9.5-alpha.9] - 2026-07-09
6
+
7
+ ### Changed
8
+
9
+ - Improved subagent extension startup by deferring old-run cleanup scans, result watcher startup, and existing-result priming to macrotasks while preserving immediate `subagent` tool and slash-command registration.
10
+
11
+ ### Fixed
12
+
13
+ - Fixed background async result watching on Windows to use Atomic's safe watcher path strategy and fall back to polling when native `fs.watch` would receive an unsafe or non-canonical watcher path.
14
+ - Fixed async/background subagent status visibility while the fullscreen workflow graph is active by publishing the live async summary through the shared status surface in addition to the below-editor widget.
15
+ - Fixed foreground and background subagent startup diagnostics so missing or invalid child `cwd` values are reported as working-directory problems before spawn, while runtime spawn failures include the attempted command and cwd instead of ambiguous `ENOENT` output.
16
+
17
+ ## [0.9.5-alpha.8] - 2026-07-08
18
+
19
+ ### Fixed
20
+
21
+ - Updated async/background subagent status widgets so running job, parallel child-agent, chain-step, and nested child rows reuse the same foreground pulsing-dot glyph treatment instead of braille spinner glyphs, while preserving counts, metadata, live-detail hints, and output paths.
22
+
5
23
  ## [0.9.5-alpha.5] - 2026-07-06
6
24
 
7
25
  ### Changed
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bastani/subagents",
3
- "version": "0.9.5-alpha.7",
3
+ "version": "0.9.5-alpha.9",
4
4
  "private": true,
5
5
  "description": "Atomic extension for delegating tasks to subagents with chains, parallel execution, and TUI clarification. Fork of: https://github.com/nicobailon/pi-subagents",
6
6
  "contributors": [