@bastani/atomic 0.8.11 → 0.8.12-0

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 (514) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/dist/builtin/intercom/package.json +1 -1
  3. package/dist/builtin/mcp/package.json +1 -1
  4. package/dist/builtin/subagents/CHANGELOG.md +3 -0
  5. package/dist/builtin/subagents/package.json +1 -1
  6. package/dist/builtin/subagents/src/agents/agent-serializer.ts +3 -2
  7. package/dist/builtin/subagents/src/agents/agents.ts +1 -1
  8. package/dist/builtin/subagents/src/extension/index.ts +597 -471
  9. package/dist/builtin/subagents/src/runs/background/async-job-tracker.ts +16 -8
  10. package/dist/builtin/subagents/src/runs/background/subagent-runner.ts +9 -13
  11. package/dist/builtin/subagents/src/runs/foreground/execution.ts +7 -3
  12. package/dist/builtin/subagents/src/shared/formatters.ts +8 -3
  13. package/dist/builtin/subagents/src/slash/slash-commands.ts +625 -468
  14. package/dist/builtin/subagents/src/tui/render.ts +342 -158
  15. package/dist/builtin/web-access/package.json +1 -1
  16. package/dist/builtin/workflows/package.json +1 -1
  17. package/dist/builtin/workflows/src/runs/foreground/executor.ts +15 -4
  18. package/dist/builtin/workflows/src/runs/foreground/stage-control-registry.ts +75 -33
  19. package/dist/builtin/workflows/src/shared/store-types.ts +3 -4
  20. package/dist/builtin/workflows/src/shared/store.ts +2 -3
  21. package/dist/builtin/workflows/src/tui/graph-view.ts +12 -1
  22. package/dist/builtin/workflows/src/tui/stage-chat-view.ts +1 -2
  23. package/dist/builtin/workflows/src/tui/status-helpers.ts +1 -1
  24. package/dist/bun/cli.d.ts.map +1 -1
  25. package/dist/bun/cli.js.map +1 -1
  26. package/dist/cli/args.d.ts +1 -1
  27. package/dist/cli/args.d.ts.map +1 -1
  28. package/dist/cli/args.js.map +1 -1
  29. package/dist/cli/config-selector.d.ts +2 -2
  30. package/dist/cli/config-selector.d.ts.map +1 -1
  31. package/dist/cli/config-selector.js.map +1 -1
  32. package/dist/cli/file-processor.d.ts.map +1 -1
  33. package/dist/cli/file-processor.js.map +1 -1
  34. package/dist/cli/initial-message.d.ts +1 -1
  35. package/dist/cli/initial-message.d.ts.map +1 -1
  36. package/dist/cli/initial-message.js.map +1 -1
  37. package/dist/cli/list-models.d.ts +1 -1
  38. package/dist/cli/list-models.d.ts.map +1 -1
  39. package/dist/cli/list-models.js.map +1 -1
  40. package/dist/cli/session-picker.d.ts +1 -1
  41. package/dist/cli/session-picker.d.ts.map +1 -1
  42. package/dist/cli/session-picker.js.map +1 -1
  43. package/dist/cli.d.ts.map +1 -1
  44. package/dist/cli.js +2 -6
  45. package/dist/cli.js.map +1 -1
  46. package/dist/config.d.ts.map +1 -1
  47. package/dist/config.js +45 -22
  48. package/dist/config.js.map +1 -1
  49. package/dist/core/agent-session-runtime.d.ts +9 -9
  50. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  51. package/dist/core/agent-session-runtime.js +2 -3
  52. package/dist/core/agent-session-runtime.js.map +1 -1
  53. package/dist/core/agent-session-services.d.ts +7 -7
  54. package/dist/core/agent-session-services.d.ts.map +1 -1
  55. package/dist/core/agent-session-services.js.map +1 -1
  56. package/dist/core/agent-session.d.ts +10 -10
  57. package/dist/core/agent-session.d.ts.map +1 -1
  58. package/dist/core/agent-session.js.map +1 -1
  59. package/dist/core/atomic-guide-command.d.ts.map +1 -1
  60. package/dist/core/atomic-guide-command.js.map +1 -1
  61. package/dist/core/auth-guidance.d.ts.map +1 -1
  62. package/dist/core/auth-guidance.js.map +1 -1
  63. package/dist/core/auth-storage.d.ts +1 -1
  64. package/dist/core/auth-storage.d.ts.map +1 -1
  65. package/dist/core/auth-storage.js +1 -1
  66. package/dist/core/auth-storage.js.map +1 -1
  67. package/dist/core/bash-executor.d.ts +1 -1
  68. package/dist/core/bash-executor.d.ts.map +1 -1
  69. package/dist/core/bash-executor.js.map +1 -1
  70. package/dist/core/builtin-packages.d.ts.map +1 -1
  71. package/dist/core/builtin-packages.js.map +1 -1
  72. package/dist/core/compaction/branch-summarization.d.ts +3 -3
  73. package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
  74. package/dist/core/compaction/branch-summarization.js.map +1 -1
  75. package/dist/core/compaction/compaction.d.ts +2 -2
  76. package/dist/core/compaction/compaction.d.ts.map +1 -1
  77. package/dist/core/compaction/compaction.js.map +1 -1
  78. package/dist/core/compaction/index.d.ts +3 -3
  79. package/dist/core/compaction/index.d.ts.map +1 -1
  80. package/dist/core/compaction/index.js.map +1 -1
  81. package/dist/core/exec.d.ts.map +1 -1
  82. package/dist/core/exec.js.map +1 -1
  83. package/dist/core/export-html/index.d.ts +1 -1
  84. package/dist/core/export-html/index.d.ts.map +1 -1
  85. package/dist/core/export-html/index.js.map +1 -1
  86. package/dist/core/export-html/tool-renderer.d.ts +2 -2
  87. package/dist/core/export-html/tool-renderer.d.ts.map +1 -1
  88. package/dist/core/export-html/tool-renderer.js.map +1 -1
  89. package/dist/core/extensions/index.d.ts +8 -8
  90. package/dist/core/extensions/index.d.ts.map +1 -1
  91. package/dist/core/extensions/index.js.map +1 -1
  92. package/dist/core/extensions/loader.d.ts +3 -3
  93. package/dist/core/extensions/loader.d.ts.map +1 -1
  94. package/dist/core/extensions/loader.js.map +1 -1
  95. package/dist/core/extensions/runner.d.ts +6 -6
  96. package/dist/core/extensions/runner.d.ts.map +1 -1
  97. package/dist/core/extensions/runner.js.map +1 -1
  98. package/dist/core/extensions/types.d.ts +20 -20
  99. package/dist/core/extensions/types.d.ts.map +1 -1
  100. package/dist/core/extensions/types.js.map +1 -1
  101. package/dist/core/extensions/wrapper.d.ts +2 -2
  102. package/dist/core/extensions/wrapper.d.ts.map +1 -1
  103. package/dist/core/extensions/wrapper.js.map +1 -1
  104. package/dist/core/footer-data-provider.d.ts.map +1 -1
  105. package/dist/core/footer-data-provider.js.map +1 -1
  106. package/dist/core/http-dispatcher.d.ts +32 -0
  107. package/dist/core/http-dispatcher.d.ts.map +1 -0
  108. package/dist/core/http-dispatcher.js +43 -0
  109. package/dist/core/http-dispatcher.js.map +1 -0
  110. package/dist/core/index.d.ts +8 -8
  111. package/dist/core/index.d.ts.map +1 -1
  112. package/dist/core/index.js.map +1 -1
  113. package/dist/core/keybindings.d.ts.map +1 -1
  114. package/dist/core/keybindings.js.map +1 -1
  115. package/dist/core/model-registry.d.ts +4 -4
  116. package/dist/core/model-registry.d.ts.map +1 -1
  117. package/dist/core/model-registry.js +2 -2
  118. package/dist/core/model-registry.js.map +1 -1
  119. package/dist/core/model-resolver.d.ts +1 -1
  120. package/dist/core/model-resolver.d.ts.map +1 -1
  121. package/dist/core/model-resolver.js.map +1 -1
  122. package/dist/core/package-manager.d.ts +1 -1
  123. package/dist/core/package-manager.d.ts.map +1 -1
  124. package/dist/core/package-manager.js +10 -11
  125. package/dist/core/package-manager.js.map +1 -1
  126. package/dist/core/prompt-templates.d.ts +1 -1
  127. package/dist/core/prompt-templates.d.ts.map +1 -1
  128. package/dist/core/prompt-templates.js.map +1 -1
  129. package/dist/core/resolve-config-value.d.ts.map +1 -1
  130. package/dist/core/resolve-config-value.js.map +1 -1
  131. package/dist/core/resource-loader.d.ts +9 -9
  132. package/dist/core/resource-loader.d.ts.map +1 -1
  133. package/dist/core/resource-loader.js.map +1 -1
  134. package/dist/core/sdk.d.ts +13 -13
  135. package/dist/core/sdk.d.ts.map +1 -1
  136. package/dist/core/sdk.js.map +1 -1
  137. package/dist/core/session-manager.d.ts +1 -1
  138. package/dist/core/session-manager.d.ts.map +1 -1
  139. package/dist/core/session-manager.js.map +1 -1
  140. package/dist/core/settings-manager.d.ts +3 -0
  141. package/dist/core/settings-manager.d.ts.map +1 -1
  142. package/dist/core/settings-manager.js +21 -0
  143. package/dist/core/settings-manager.js.map +1 -1
  144. package/dist/core/skills.d.ts +2 -2
  145. package/dist/core/skills.d.ts.map +1 -1
  146. package/dist/core/skills.js.map +1 -1
  147. package/dist/core/slash-commands.d.ts +1 -1
  148. package/dist/core/slash-commands.d.ts.map +1 -1
  149. package/dist/core/slash-commands.js.map +1 -1
  150. package/dist/core/source-info.d.ts +1 -1
  151. package/dist/core/source-info.d.ts.map +1 -1
  152. package/dist/core/source-info.js.map +1 -1
  153. package/dist/core/system-prompt.d.ts +1 -1
  154. package/dist/core/system-prompt.d.ts.map +1 -1
  155. package/dist/core/system-prompt.js +7 -8
  156. package/dist/core/system-prompt.js.map +1 -1
  157. package/dist/core/telemetry.d.ts +1 -1
  158. package/dist/core/telemetry.d.ts.map +1 -1
  159. package/dist/core/telemetry.js.map +1 -1
  160. package/dist/core/timings.d.ts.map +1 -1
  161. package/dist/core/timings.js.map +1 -1
  162. package/dist/core/tools/ask-user-question/ask-user-question.d.ts +4 -4
  163. package/dist/core/tools/ask-user-question/ask-user-question.d.ts.map +1 -1
  164. package/dist/core/tools/ask-user-question/ask-user-question.js.map +1 -1
  165. package/dist/core/tools/ask-user-question/index.d.ts +1 -1
  166. package/dist/core/tools/ask-user-question/index.d.ts.map +1 -1
  167. package/dist/core/tools/ask-user-question/index.js.map +1 -1
  168. package/dist/core/tools/ask-user-question/state/build-questionnaire.d.ts +5 -5
  169. package/dist/core/tools/ask-user-question/state/build-questionnaire.d.ts.map +1 -1
  170. package/dist/core/tools/ask-user-question/state/build-questionnaire.js.map +1 -1
  171. package/dist/core/tools/ask-user-question/state/key-router.d.ts +2 -2
  172. package/dist/core/tools/ask-user-question/state/key-router.d.ts.map +1 -1
  173. package/dist/core/tools/ask-user-question/state/key-router.js.map +1 -1
  174. package/dist/core/tools/ask-user-question/state/questionnaire-session.d.ts +3 -3
  175. package/dist/core/tools/ask-user-question/state/questionnaire-session.d.ts.map +1 -1
  176. package/dist/core/tools/ask-user-question/state/questionnaire-session.js.map +1 -1
  177. package/dist/core/tools/ask-user-question/state/row-intent.d.ts +2 -2
  178. package/dist/core/tools/ask-user-question/state/row-intent.d.ts.map +1 -1
  179. package/dist/core/tools/ask-user-question/state/row-intent.js.map +1 -1
  180. package/dist/core/tools/ask-user-question/state/selectors/contract.d.ts +6 -6
  181. package/dist/core/tools/ask-user-question/state/selectors/contract.d.ts.map +1 -1
  182. package/dist/core/tools/ask-user-question/state/selectors/contract.js.map +1 -1
  183. package/dist/core/tools/ask-user-question/state/selectors/derivations.d.ts +2 -2
  184. package/dist/core/tools/ask-user-question/state/selectors/derivations.d.ts.map +1 -1
  185. package/dist/core/tools/ask-user-question/state/selectors/derivations.js.map +1 -1
  186. package/dist/core/tools/ask-user-question/state/selectors/focus.d.ts +1 -1
  187. package/dist/core/tools/ask-user-question/state/selectors/focus.d.ts.map +1 -1
  188. package/dist/core/tools/ask-user-question/state/selectors/focus.js.map +1 -1
  189. package/dist/core/tools/ask-user-question/state/selectors/projections.d.ts +8 -8
  190. package/dist/core/tools/ask-user-question/state/selectors/projections.d.ts.map +1 -1
  191. package/dist/core/tools/ask-user-question/state/selectors/projections.js.map +1 -1
  192. package/dist/core/tools/ask-user-question/state/state-reducer.d.ts +4 -4
  193. package/dist/core/tools/ask-user-question/state/state-reducer.d.ts.map +1 -1
  194. package/dist/core/tools/ask-user-question/state/state-reducer.js.map +1 -1
  195. package/dist/core/tools/ask-user-question/state/state.d.ts +2 -2
  196. package/dist/core/tools/ask-user-question/state/state.d.ts.map +1 -1
  197. package/dist/core/tools/ask-user-question/state/state.js.map +1 -1
  198. package/dist/core/tools/ask-user-question/tool/format-answer.d.ts +1 -1
  199. package/dist/core/tools/ask-user-question/tool/format-answer.d.ts.map +1 -1
  200. package/dist/core/tools/ask-user-question/tool/format-answer.js.map +1 -1
  201. package/dist/core/tools/ask-user-question/tool/response-envelope.d.ts +1 -1
  202. package/dist/core/tools/ask-user-question/tool/response-envelope.d.ts.map +1 -1
  203. package/dist/core/tools/ask-user-question/tool/response-envelope.js.map +1 -1
  204. package/dist/core/tools/ask-user-question/tool/types.d.ts.map +1 -1
  205. package/dist/core/tools/ask-user-question/tool/types.js.map +1 -1
  206. package/dist/core/tools/ask-user-question/tool/validate-questionnaire.d.ts +1 -1
  207. package/dist/core/tools/ask-user-question/tool/validate-questionnaire.d.ts.map +1 -1
  208. package/dist/core/tools/ask-user-question/tool/validate-questionnaire.js.map +1 -1
  209. package/dist/core/tools/ask-user-question/view/body-residual-spacer.d.ts.map +1 -1
  210. package/dist/core/tools/ask-user-question/view/body-residual-spacer.js.map +1 -1
  211. package/dist/core/tools/ask-user-question/view/component-binding.d.ts +4 -4
  212. package/dist/core/tools/ask-user-question/view/component-binding.d.ts.map +1 -1
  213. package/dist/core/tools/ask-user-question/view/component-binding.js.map +1 -1
  214. package/dist/core/tools/ask-user-question/view/components/chat-row-view.d.ts +2 -2
  215. package/dist/core/tools/ask-user-question/view/components/chat-row-view.d.ts.map +1 -1
  216. package/dist/core/tools/ask-user-question/view/components/chat-row-view.js.map +1 -1
  217. package/dist/core/tools/ask-user-question/view/components/multi-select-view.d.ts +4 -4
  218. package/dist/core/tools/ask-user-question/view/components/multi-select-view.d.ts.map +1 -1
  219. package/dist/core/tools/ask-user-question/view/components/multi-select-view.js.map +1 -1
  220. package/dist/core/tools/ask-user-question/view/components/option-list-view.d.ts +2 -2
  221. package/dist/core/tools/ask-user-question/view/components/option-list-view.d.ts.map +1 -1
  222. package/dist/core/tools/ask-user-question/view/components/option-list-view.js.map +1 -1
  223. package/dist/core/tools/ask-user-question/view/components/preview/markdown-content-cache.d.ts +2 -2
  224. package/dist/core/tools/ask-user-question/view/components/preview/markdown-content-cache.d.ts.map +1 -1
  225. package/dist/core/tools/ask-user-question/view/components/preview/markdown-content-cache.js.map +1 -1
  226. package/dist/core/tools/ask-user-question/view/components/preview/preview-block-renderer.d.ts +3 -3
  227. package/dist/core/tools/ask-user-question/view/components/preview/preview-block-renderer.d.ts.map +1 -1
  228. package/dist/core/tools/ask-user-question/view/components/preview/preview-block-renderer.js.map +1 -1
  229. package/dist/core/tools/ask-user-question/view/components/preview/preview-layout-decider.d.ts +2 -2
  230. package/dist/core/tools/ask-user-question/view/components/preview/preview-layout-decider.d.ts.map +1 -1
  231. package/dist/core/tools/ask-user-question/view/components/preview/preview-layout-decider.js.map +1 -1
  232. package/dist/core/tools/ask-user-question/view/components/preview/preview-pane.d.ts +8 -8
  233. package/dist/core/tools/ask-user-question/view/components/preview/preview-pane.d.ts.map +1 -1
  234. package/dist/core/tools/ask-user-question/view/components/preview/preview-pane.js.map +1 -1
  235. package/dist/core/tools/ask-user-question/view/components/submit-picker.d.ts +3 -3
  236. package/dist/core/tools/ask-user-question/view/components/submit-picker.d.ts.map +1 -1
  237. package/dist/core/tools/ask-user-question/view/components/submit-picker.js.map +1 -1
  238. package/dist/core/tools/ask-user-question/view/components/tab-bar.d.ts +3 -3
  239. package/dist/core/tools/ask-user-question/view/components/tab-bar.d.ts.map +1 -1
  240. package/dist/core/tools/ask-user-question/view/components/tab-bar.js.map +1 -1
  241. package/dist/core/tools/ask-user-question/view/dialog-builder.d.ts +8 -8
  242. package/dist/core/tools/ask-user-question/view/dialog-builder.d.ts.map +1 -1
  243. package/dist/core/tools/ask-user-question/view/dialog-builder.js.map +1 -1
  244. package/dist/core/tools/ask-user-question/view/props-adapter.d.ts +5 -5
  245. package/dist/core/tools/ask-user-question/view/props-adapter.d.ts.map +1 -1
  246. package/dist/core/tools/ask-user-question/view/props-adapter.js.map +1 -1
  247. package/dist/core/tools/ask-user-question/view/tab-components.d.ts +4 -4
  248. package/dist/core/tools/ask-user-question/view/tab-components.d.ts.map +1 -1
  249. package/dist/core/tools/ask-user-question/view/tab-components.js.map +1 -1
  250. package/dist/core/tools/ask-user-question/view/tab-content-strategy.d.ts +9 -9
  251. package/dist/core/tools/ask-user-question/view/tab-content-strategy.d.ts.map +1 -1
  252. package/dist/core/tools/ask-user-question/view/tab-content-strategy.js +2 -2
  253. package/dist/core/tools/ask-user-question/view/tab-content-strategy.js.map +1 -1
  254. package/dist/core/tools/bash.d.ts +2 -2
  255. package/dist/core/tools/bash.d.ts.map +1 -1
  256. package/dist/core/tools/bash.js +9 -1
  257. package/dist/core/tools/bash.js.map +1 -1
  258. package/dist/core/tools/edit-diff.d.ts.map +1 -1
  259. package/dist/core/tools/edit-diff.js.map +1 -1
  260. package/dist/core/tools/edit.d.ts +2 -2
  261. package/dist/core/tools/edit.d.ts.map +1 -1
  262. package/dist/core/tools/edit.js.map +1 -1
  263. package/dist/core/tools/find.d.ts +2 -2
  264. package/dist/core/tools/find.d.ts.map +1 -1
  265. package/dist/core/tools/find.js.map +1 -1
  266. package/dist/core/tools/grep.d.ts +2 -2
  267. package/dist/core/tools/grep.d.ts.map +1 -1
  268. package/dist/core/tools/grep.js.map +1 -1
  269. package/dist/core/tools/index.d.ts +19 -19
  270. package/dist/core/tools/index.d.ts.map +1 -1
  271. package/dist/core/tools/index.js.map +1 -1
  272. package/dist/core/tools/ls.d.ts +2 -2
  273. package/dist/core/tools/ls.d.ts.map +1 -1
  274. package/dist/core/tools/ls.js.map +1 -1
  275. package/dist/core/tools/output-accumulator.d.ts +1 -1
  276. package/dist/core/tools/output-accumulator.d.ts.map +1 -1
  277. package/dist/core/tools/output-accumulator.js.map +1 -1
  278. package/dist/core/tools/read.d.ts +2 -2
  279. package/dist/core/tools/read.d.ts.map +1 -1
  280. package/dist/core/tools/read.js.map +1 -1
  281. package/dist/core/tools/render-utils.d.ts +1 -1
  282. package/dist/core/tools/render-utils.d.ts.map +1 -1
  283. package/dist/core/tools/render-utils.js.map +1 -1
  284. package/dist/core/tools/todos.d.ts +1 -1
  285. package/dist/core/tools/todos.d.ts.map +1 -1
  286. package/dist/core/tools/todos.js.map +1 -1
  287. package/dist/core/tools/tool-definition-wrapper.d.ts +1 -1
  288. package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -1
  289. package/dist/core/tools/tool-definition-wrapper.js.map +1 -1
  290. package/dist/core/tools/write.d.ts +1 -1
  291. package/dist/core/tools/write.d.ts.map +1 -1
  292. package/dist/core/tools/write.js.map +1 -1
  293. package/dist/index.d.ts +30 -29
  294. package/dist/index.d.ts.map +1 -1
  295. package/dist/index.js +1 -0
  296. package/dist/index.js.map +1 -1
  297. package/dist/main.d.ts +1 -1
  298. package/dist/main.d.ts.map +1 -1
  299. package/dist/main.js +2 -0
  300. package/dist/main.js.map +1 -1
  301. package/dist/migrations.d.ts.map +1 -1
  302. package/dist/migrations.js.map +1 -1
  303. package/dist/modes/index.d.ts +5 -5
  304. package/dist/modes/index.d.ts.map +1 -1
  305. package/dist/modes/index.js.map +1 -1
  306. package/dist/modes/interactive/components/armin.d.ts.map +1 -1
  307. package/dist/modes/interactive/components/armin.js.map +1 -1
  308. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  309. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  310. package/dist/modes/interactive/components/atomic-banner.d.ts +1 -1
  311. package/dist/modes/interactive/components/atomic-banner.d.ts.map +1 -1
  312. package/dist/modes/interactive/components/atomic-banner.js.map +1 -1
  313. package/dist/modes/interactive/components/bash-execution.d.ts +1 -1
  314. package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
  315. package/dist/modes/interactive/components/bash-execution.js.map +1 -1
  316. package/dist/modes/interactive/components/bordered-loader.d.ts +1 -1
  317. package/dist/modes/interactive/components/bordered-loader.d.ts.map +1 -1
  318. package/dist/modes/interactive/components/bordered-loader.js.map +1 -1
  319. package/dist/modes/interactive/components/branch-summary-message.d.ts +1 -1
  320. package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -1
  321. package/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
  322. package/dist/modes/interactive/components/chat-message-renderer.d.ts +3 -3
  323. package/dist/modes/interactive/components/chat-message-renderer.d.ts.map +1 -1
  324. package/dist/modes/interactive/components/chat-message-renderer.js +1 -1
  325. package/dist/modes/interactive/components/chat-message-renderer.js.map +1 -1
  326. package/dist/modes/interactive/components/chat-transcript.d.ts.map +1 -1
  327. package/dist/modes/interactive/components/chat-transcript.js.map +1 -1
  328. package/dist/modes/interactive/components/compaction-summary-message.d.ts +1 -1
  329. package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
  330. package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
  331. package/dist/modes/interactive/components/config-selector.d.ts +2 -2
  332. package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
  333. package/dist/modes/interactive/components/config-selector.js.map +1 -1
  334. package/dist/modes/interactive/components/countdown-timer.d.ts +2 -2
  335. package/dist/modes/interactive/components/countdown-timer.d.ts.map +1 -1
  336. package/dist/modes/interactive/components/countdown-timer.js.map +1 -1
  337. package/dist/modes/interactive/components/custom-editor.d.ts +1 -1
  338. package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
  339. package/dist/modes/interactive/components/custom-editor.js.map +1 -1
  340. package/dist/modes/interactive/components/custom-message.d.ts +2 -2
  341. package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
  342. package/dist/modes/interactive/components/custom-message.js.map +1 -1
  343. package/dist/modes/interactive/components/daxnuts.d.ts.map +1 -1
  344. package/dist/modes/interactive/components/daxnuts.js.map +1 -1
  345. package/dist/modes/interactive/components/diff.d.ts.map +1 -1
  346. package/dist/modes/interactive/components/diff.js.map +1 -1
  347. package/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -1
  348. package/dist/modes/interactive/components/dynamic-border.js.map +1 -1
  349. package/dist/modes/interactive/components/earendil-announcement.d.ts.map +1 -1
  350. package/dist/modes/interactive/components/earendil-announcement.js.map +1 -1
  351. package/dist/modes/interactive/components/extension-editor.d.ts +1 -1
  352. package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
  353. package/dist/modes/interactive/components/extension-editor.js.map +1 -1
  354. package/dist/modes/interactive/components/extension-input.d.ts.map +1 -1
  355. package/dist/modes/interactive/components/extension-input.js.map +1 -1
  356. package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -1
  357. package/dist/modes/interactive/components/extension-selector.js.map +1 -1
  358. package/dist/modes/interactive/components/footer.d.ts +3 -3
  359. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  360. package/dist/modes/interactive/components/footer.js +1 -1
  361. package/dist/modes/interactive/components/footer.js.map +1 -1
  362. package/dist/modes/interactive/components/index.d.ts +34 -34
  363. package/dist/modes/interactive/components/index.d.ts.map +1 -1
  364. package/dist/modes/interactive/components/index.js.map +1 -1
  365. package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -1
  366. package/dist/modes/interactive/components/keybinding-hints.js.map +1 -1
  367. package/dist/modes/interactive/components/login-dialog.d.ts +1 -1
  368. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  369. package/dist/modes/interactive/components/login-dialog.js +1 -1
  370. package/dist/modes/interactive/components/login-dialog.js.map +1 -1
  371. package/dist/modes/interactive/components/model-selector.d.ts +2 -2
  372. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  373. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  374. package/dist/modes/interactive/components/oauth-selector.d.ts +1 -1
  375. package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
  376. package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
  377. package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
  378. package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
  379. package/dist/modes/interactive/components/session-selector-search.d.ts +1 -1
  380. package/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -1
  381. package/dist/modes/interactive/components/session-selector-search.js.map +1 -1
  382. package/dist/modes/interactive/components/session-selector.d.ts +3 -3
  383. package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
  384. package/dist/modes/interactive/components/session-selector.js.map +1 -1
  385. package/dist/modes/interactive/components/settings-selector.d.ts +3 -1
  386. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  387. package/dist/modes/interactive/components/settings-selector.js +13 -0
  388. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  389. package/dist/modes/interactive/components/show-images-selector.d.ts.map +1 -1
  390. package/dist/modes/interactive/components/show-images-selector.js.map +1 -1
  391. package/dist/modes/interactive/components/skill-invocation-message.d.ts +1 -1
  392. package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -1
  393. package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
  394. package/dist/modes/interactive/components/theme-selector.d.ts.map +1 -1
  395. package/dist/modes/interactive/components/theme-selector.js.map +1 -1
  396. package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
  397. package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
  398. package/dist/modes/interactive/components/tool-execution.d.ts +1 -1
  399. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  400. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  401. package/dist/modes/interactive/components/tree-selector.d.ts +1 -1
  402. package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
  403. package/dist/modes/interactive/components/tree-selector.js.map +1 -1
  404. package/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -1
  405. package/dist/modes/interactive/components/user-message-selector.js.map +1 -1
  406. package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  407. package/dist/modes/interactive/components/user-message.js.map +1 -1
  408. package/dist/modes/interactive/components/working-status.d.ts.map +1 -1
  409. package/dist/modes/interactive/components/working-status.js.map +1 -1
  410. package/dist/modes/interactive/interactive-mode.d.ts +2 -2
  411. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  412. package/dist/modes/interactive/interactive-mode.js +7 -1
  413. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  414. package/dist/modes/interactive/theme/theme.d.ts +1 -1
  415. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  416. package/dist/modes/interactive/theme/theme.js.map +1 -1
  417. package/dist/modes/print-mode.d.ts +1 -1
  418. package/dist/modes/print-mode.d.ts.map +1 -1
  419. package/dist/modes/print-mode.js.map +1 -1
  420. package/dist/modes/rpc/rpc-client.d.ts +5 -5
  421. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  422. package/dist/modes/rpc/rpc-client.js +1 -1
  423. package/dist/modes/rpc/rpc-client.js.map +1 -1
  424. package/dist/modes/rpc/rpc-mode.d.ts +2 -2
  425. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  426. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  427. package/dist/modes/rpc/rpc-types.d.ts +4 -4
  428. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  429. package/dist/modes/rpc/rpc-types.js.map +1 -1
  430. package/dist/package-manager-cli.d.ts.map +1 -1
  431. package/dist/package-manager-cli.js +22 -6
  432. package/dist/package-manager-cli.js.map +1 -1
  433. package/dist/utils/changelog.d.ts +1 -1
  434. package/dist/utils/changelog.d.ts.map +1 -1
  435. package/dist/utils/changelog.js.map +1 -1
  436. package/dist/utils/child-process.d.ts +5 -2
  437. package/dist/utils/child-process.d.ts.map +1 -1
  438. package/dist/utils/child-process.js +9 -7
  439. package/dist/utils/child-process.js.map +1 -1
  440. package/dist/utils/clipboard-image.d.ts.map +1 -1
  441. package/dist/utils/clipboard-image.js.map +1 -1
  442. package/dist/utils/clipboard.d.ts.map +1 -1
  443. package/dist/utils/clipboard.js.map +1 -1
  444. package/dist/utils/exif-orientation.d.ts +1 -1
  445. package/dist/utils/exif-orientation.d.ts.map +1 -1
  446. package/dist/utils/exif-orientation.js.map +1 -1
  447. package/dist/utils/image-convert.d.ts.map +1 -1
  448. package/dist/utils/image-convert.js.map +1 -1
  449. package/dist/utils/image-resize.d.ts.map +1 -1
  450. package/dist/utils/image-resize.js.map +1 -1
  451. package/dist/utils/shell.d.ts.map +1 -1
  452. package/dist/utils/shell.js.map +1 -1
  453. package/dist/utils/syntax-highlight.d.ts.map +1 -1
  454. package/dist/utils/syntax-highlight.js.map +1 -1
  455. package/dist/utils/tools-manager.d.ts.map +1 -1
  456. package/dist/utils/tools-manager.js.map +1 -1
  457. package/dist/utils/version-check.d.ts.map +1 -1
  458. package/dist/utils/version-check.js.map +1 -1
  459. package/dist/utils/windows-self-update.d.ts +3 -0
  460. package/dist/utils/windows-self-update.d.ts.map +1 -0
  461. package/dist/utils/windows-self-update.js +78 -0
  462. package/dist/utils/windows-self-update.js.map +1 -0
  463. package/docs/compaction.md +5 -5
  464. package/docs/custom-provider.md +2 -2
  465. package/docs/development.md +22 -16
  466. package/docs/docs.json +6 -2
  467. package/docs/extensions.md +25 -25
  468. package/docs/index.md +11 -14
  469. package/docs/keybindings.md +5 -5
  470. package/docs/models.md +6 -6
  471. package/docs/packages.md +55 -48
  472. package/docs/prompt-templates.md +5 -5
  473. package/docs/providers.md +10 -10
  474. package/docs/quickstart.md +32 -30
  475. package/docs/rpc.md +9 -9
  476. package/docs/sdk.md +1 -1
  477. package/docs/session-format.md +3 -3
  478. package/docs/sessions.md +11 -11
  479. package/docs/settings.md +18 -15
  480. package/docs/shell-aliases.md +2 -2
  481. package/docs/skills.md +11 -11
  482. package/docs/terminal-setup.md +8 -8
  483. package/docs/termux.md +6 -6
  484. package/docs/themes.md +10 -10
  485. package/docs/tui.md +5 -4
  486. package/docs/usage.md +50 -50
  487. package/docs/windows.md +2 -2
  488. package/docs/workflows.md +695 -0
  489. package/examples/extensions/custom-provider-gitlab-duo/test.ts +1 -1
  490. package/examples/extensions/doom-overlay/doom-component.ts +2 -2
  491. package/examples/extensions/doom-overlay/index.ts +3 -3
  492. package/examples/extensions/overlay-qa-tests.ts +116 -33
  493. package/examples/extensions/overlay-test.ts +9 -3
  494. package/examples/extensions/plan-mode/index.ts +1 -1
  495. package/examples/extensions/subagent/index.ts +1159 -903
  496. package/package.json +6 -4
  497. package/dist/builtin/workflows/skills/workflow/SKILL.md +0 -322
  498. package/dist/builtin/workflows/skills/workflow/references/context-engineering/advanced-evaluation.md +0 -404
  499. package/dist/builtin/workflows/skills/workflow/references/context-engineering/bdi-mental-states.md +0 -313
  500. package/dist/builtin/workflows/skills/workflow/references/context-engineering/context-compression.md +0 -274
  501. package/dist/builtin/workflows/skills/workflow/references/context-engineering/context-degradation.md +0 -208
  502. package/dist/builtin/workflows/skills/workflow/references/context-engineering/context-fundamentals.md +0 -203
  503. package/dist/builtin/workflows/skills/workflow/references/context-engineering/context-optimization.md +0 -197
  504. package/dist/builtin/workflows/skills/workflow/references/context-engineering/evaluation.md +0 -253
  505. package/dist/builtin/workflows/skills/workflow/references/context-engineering/filesystem-context.md +0 -289
  506. package/dist/builtin/workflows/skills/workflow/references/context-engineering/hosted-agents.md +0 -262
  507. package/dist/builtin/workflows/skills/workflow/references/context-engineering/memory-systems.md +0 -221
  508. package/dist/builtin/workflows/skills/workflow/references/context-engineering/multi-agent-patterns.md +0 -259
  509. package/dist/builtin/workflows/skills/workflow/references/context-engineering/project-development.md +0 -293
  510. package/dist/builtin/workflows/skills/workflow/references/context-engineering/tool-design.md +0 -273
  511. package/dist/builtin/workflows/skills/workflow/references/context-engineering.md +0 -23
  512. package/dist/builtin/workflows/skills/workflow/references/design-checklist.md +0 -83
  513. package/dist/builtin/workflows/skills/workflow/references/running-workflows.md +0 -159
  514. package/dist/builtin/workflows/skills/workflow/references/sdk-authoring.md +0 -260
@@ -17,44 +17,78 @@ import * as os from "node:os";
17
17
  import * as path from "node:path";
18
18
  import { getAgentConfigPaths, getEnvValue } from "@bastani/atomic";
19
19
  import type { AgentToolResult } from "@earendil-works/pi-agent-core";
20
- import { type ExtensionAPI, type ExtensionContext, type ToolDefinition } from "@bastani/atomic";
21
- import { Box, Container, Spacer, Text, truncateToWidth, visibleWidth, wrapTextWithAnsi, type Component } from "@earendil-works/pi-tui";
20
+ import {
21
+ type ExtensionAPI,
22
+ type ExtensionContext,
23
+ type ToolDefinition,
24
+ } from "@bastani/atomic";
25
+ import {
26
+ Box,
27
+ Container,
28
+ Spacer,
29
+ Text,
30
+ truncateToWidth,
31
+ visibleWidth,
32
+ wrapTextWithAnsi,
33
+ type Component,
34
+ } from "@earendil-works/pi-tui";
22
35
  import { discoverAgents } from "../agents/agents.ts";
23
- import { cleanupAllArtifactDirs, cleanupOldArtifacts, getArtifactsDir } from "../shared/artifacts.ts";
36
+ import {
37
+ cleanupAllArtifactDirs,
38
+ cleanupOldArtifacts,
39
+ getArtifactsDir,
40
+ } from "../shared/artifacts.ts";
24
41
  import { resolveCurrentSessionId } from "../shared/session-identity.ts";
25
42
  import { cleanupOldChainDirs } from "../shared/settings.ts";
26
- import { renderWidget, renderSubagentResult, stopResultAnimations, stopWidgetAnimation, syncResultAnimation } from "../tui/render.ts";
43
+ import {
44
+ renderWidget,
45
+ renderSubagentResult,
46
+ stopResultAnimations,
47
+ stopWidgetAnimation,
48
+ syncResultAnimation,
49
+ } from "../tui/render.ts";
27
50
  import { SubagentParams } from "./schemas.ts";
28
- import { createSubagentExecutor, type SubagentParamsLike } from "../runs/foreground/subagent-executor.ts";
51
+ import {
52
+ createSubagentExecutor,
53
+ type SubagentParamsLike,
54
+ } from "../runs/foreground/subagent-executor.ts";
29
55
  import { createAsyncJobTracker } from "../runs/background/async-job-tracker.ts";
30
56
  import { createResultWatcher } from "../runs/background/result-watcher.ts";
31
57
  import { registerSlashCommands } from "../slash/slash-commands.ts";
32
58
  import { registerPromptTemplateDelegationBridge } from "../slash/prompt-template-bridge.ts";
33
59
  import { registerSlashSubagentBridge } from "../slash/slash-bridge.ts";
34
- import { clearSlashSnapshots, getSlashRenderableSnapshot, resolveSlashMessageDetails, restoreSlashFinalSnapshots, type SlashMessageDetails } from "../slash/slash-live-state.ts";
60
+ import {
61
+ clearSlashSnapshots,
62
+ getSlashRenderableSnapshot,
63
+ resolveSlashMessageDetails,
64
+ restoreSlashFinalSnapshots,
65
+ type SlashMessageDetails,
66
+ } from "../slash/slash-live-state.ts";
35
67
  import { inspectSubagentStatus } from "../runs/background/run-status.ts";
36
- import registerSubagentNotify, { type SubagentNotifyDetails } from "../runs/background/notify.ts";
68
+ import registerSubagentNotify, {
69
+ type SubagentNotifyDetails,
70
+ } from "../runs/background/notify.ts";
37
71
  import { SUBAGENT_CHILD_ENV } from "../runs/shared/pi-args.ts";
38
72
  import { formatDuration, shortenPath } from "../shared/formatters.ts";
39
73
  import {
40
- type Details,
41
- type ExtensionConfig,
42
- type SubagentState,
43
- ASYNC_DIR,
44
- DEFAULT_ARTIFACT_CONFIG,
45
- RESULTS_DIR,
46
- SLASH_RESULT_TYPE,
47
- SUBAGENT_ASYNC_COMPLETE_EVENT,
48
- SUBAGENT_ASYNC_STARTED_EVENT,
49
- SUBAGENT_CONTROL_EVENT,
50
- WIDGET_KEY,
74
+ type Details,
75
+ type ExtensionConfig,
76
+ type SubagentState,
77
+ ASYNC_DIR,
78
+ DEFAULT_ARTIFACT_CONFIG,
79
+ RESULTS_DIR,
80
+ SLASH_RESULT_TYPE,
81
+ SUBAGENT_ASYNC_COMPLETE_EVENT,
82
+ SUBAGENT_ASYNC_STARTED_EVENT,
83
+ SUBAGENT_CONTROL_EVENT,
84
+ WIDGET_KEY,
51
85
  } from "../shared/types.ts";
52
86
  import {
53
- clearPendingForegroundControlNotices,
54
- formatSubagentControlNotice,
55
- handleSubagentControlNotice,
56
- SUBAGENT_CONTROL_MESSAGE_TYPE,
57
- type SubagentControlMessageDetails,
87
+ clearPendingForegroundControlNotices,
88
+ formatSubagentControlNotice,
89
+ handleSubagentControlNotice,
90
+ SUBAGENT_CONTROL_MESSAGE_TYPE,
91
+ type SubagentControlMessageDetails,
58
92
  } from "./control-notices.ts";
59
93
 
60
94
  /**
@@ -65,29 +99,38 @@ import {
65
99
  * Falls back to a unique temp directory if no parent session.
66
100
  */
67
101
  function getSubagentSessionRoot(parentSessionFile: string | null): string {
68
- if (parentSessionFile) {
69
- const baseName = path.basename(parentSessionFile, ".jsonl");
70
- const sessionsDir = path.dirname(parentSessionFile);
71
- return path.join(sessionsDir, baseName);
72
- }
73
- return fs.mkdtempSync(path.join(os.tmpdir(), "pi-subagent-session-"));
102
+ if (parentSessionFile) {
103
+ const baseName = path.basename(parentSessionFile, ".jsonl");
104
+ const sessionsDir = path.dirname(parentSessionFile);
105
+ return path.join(sessionsDir, baseName);
106
+ }
107
+ return fs.mkdtempSync(path.join(os.tmpdir(), "pi-subagent-session-"));
74
108
  }
75
109
 
76
110
  function loadConfig(): ExtensionConfig {
77
- for (const configPath of getAgentConfigPaths("extensions", "subagent", "config.json")) {
78
- try {
79
- if (fs.existsSync(configPath)) {
80
- return JSON.parse(fs.readFileSync(configPath, "utf-8")) as ExtensionConfig;
81
- }
82
- } catch (error) {
83
- console.error(`Failed to load subagent config from '${configPath}':`, error);
84
- }
85
- }
86
- return {};
111
+ for (const configPath of getAgentConfigPaths(
112
+ "extensions",
113
+ "subagent",
114
+ "config.json",
115
+ )) {
116
+ try {
117
+ if (fs.existsSync(configPath)) {
118
+ return JSON.parse(
119
+ fs.readFileSync(configPath, "utf-8"),
120
+ ) as ExtensionConfig;
121
+ }
122
+ } catch (error) {
123
+ console.error(
124
+ `Failed to load subagent config from '${configPath}':`,
125
+ error,
126
+ );
127
+ }
128
+ }
129
+ return {};
87
130
  }
88
131
 
89
132
  function expandTilde(p: string): string {
90
- return p.startsWith("~/") ? path.join(os.homedir(), p.slice(2)) : p;
133
+ return p.startsWith("~/") ? path.join(os.homedir(), p.slice(2)) : p;
91
134
  }
92
135
 
93
136
  /**
@@ -98,309 +141,380 @@ function expandTilde(p: string): string {
98
141
  * the directory completely inaccessible to the creating user.
99
142
  */
100
143
  function ensureAccessibleDir(dirPath: string): void {
101
- fs.mkdirSync(dirPath, { recursive: true });
102
- try {
103
- fs.accessSync(dirPath, fs.constants.R_OK | fs.constants.W_OK);
104
- } catch {
105
- try {
106
- fs.rmSync(dirPath, { recursive: true, force: true });
107
- } catch {
108
- // Best effort: retry mkdir/access even if cleanup fails.
109
- }
110
- fs.mkdirSync(dirPath, { recursive: true });
111
- fs.accessSync(dirPath, fs.constants.R_OK | fs.constants.W_OK);
112
- }
144
+ fs.mkdirSync(dirPath, { recursive: true });
145
+ try {
146
+ fs.accessSync(dirPath, fs.constants.R_OK | fs.constants.W_OK);
147
+ } catch {
148
+ try {
149
+ fs.rmSync(dirPath, { recursive: true, force: true });
150
+ } catch {
151
+ // Best effort: retry mkdir/access even if cleanup fails.
152
+ }
153
+ fs.mkdirSync(dirPath, { recursive: true });
154
+ fs.accessSync(dirPath, fs.constants.R_OK | fs.constants.W_OK);
155
+ }
113
156
  }
114
157
 
115
158
  function isSlashResultRunning(result: { details?: Details }): boolean {
116
- return result.details?.progress?.some((entry) => entry.status === "running")
117
- || result.details?.results.some((entry) => entry.progress?.status === "running")
118
- || false;
159
+ return (
160
+ result.details?.progress?.some((entry) => entry.status === "running") ||
161
+ result.details?.results.some(
162
+ (entry) => entry.progress?.status === "running",
163
+ ) ||
164
+ false
165
+ );
119
166
  }
120
167
 
121
168
  function isSlashResultError(result: { details?: Details }): boolean {
122
- return result.details?.results.some((entry) => entry.exitCode !== 0 && entry.progress?.status !== "running") || false;
169
+ return (
170
+ result.details?.results.some(
171
+ (entry) => entry.exitCode !== 0 && entry.progress?.status !== "running",
172
+ ) || false
173
+ );
123
174
  }
124
175
 
125
176
  function isStaleExtensionContextError(error: unknown): boolean {
126
- return error instanceof Error && error.message.includes("Extension context no longer active");
177
+ return (
178
+ error instanceof Error &&
179
+ error.message.includes("Extension context no longer active")
180
+ );
127
181
  }
128
182
 
129
183
  function rebuildSlashResultContainer(
130
- container: Container,
131
- result: AgentToolResult<Details>,
132
- options: { expanded: boolean },
133
- theme: ExtensionContext["ui"]["theme"],
184
+ container: Container,
185
+ result: AgentToolResult<Details>,
186
+ options: { expanded: boolean },
187
+ theme: ExtensionContext["ui"]["theme"],
134
188
  ): void {
135
- container.clear();
136
- container.addChild(new Spacer(1));
137
- const boxTheme = isSlashResultRunning(result) ? "toolPendingBg" : isSlashResultError(result) ? "toolErrorBg" : "toolSuccessBg";
138
- const box = new Box(1, 1, (text: string) => theme.bg(boxTheme, text));
139
- box.addChild(renderSubagentResult(result, options, theme));
140
- container.addChild(box);
189
+ container.clear();
190
+ container.addChild(new Spacer(1));
191
+ const boxTheme = isSlashResultRunning(result)
192
+ ? "toolPendingBg"
193
+ : isSlashResultError(result)
194
+ ? "toolErrorBg"
195
+ : "toolSuccessBg";
196
+ const box = new Box(1, 1, (text: string) => theme.bg(boxTheme, text));
197
+ box.addChild(renderSubagentResult(result, options, theme));
198
+ container.addChild(box);
141
199
  }
142
200
 
143
201
  function createSlashResultComponent(
144
- details: SlashMessageDetails,
145
- options: { expanded: boolean },
146
- theme: ExtensionContext["ui"]["theme"],
147
- requestRender: () => void,
202
+ details: SlashMessageDetails,
203
+ options: { expanded: boolean },
204
+ theme: ExtensionContext["ui"]["theme"],
205
+ requestRender: () => void,
148
206
  ): Container {
149
- const container = new Container();
150
- const animationState: { subagentResultAnimationTimer?: ReturnType<typeof setInterval> } = {};
151
- let lastVersion = -1;
152
- container.render = (width: number): string[] => {
153
- const snapshot = getSlashRenderableSnapshot(details);
154
- syncResultAnimation(snapshot.result, { state: animationState, invalidate: requestRender });
155
- if (snapshot.version !== lastVersion || isSlashResultRunning(snapshot.result)) {
156
- lastVersion = snapshot.version;
157
- rebuildSlashResultContainer(container, snapshot.result, options, theme);
158
- }
159
- return Container.prototype.render.call(container, width);
160
- };
161
- return container;
207
+ const container = new Container();
208
+ const animationState: { subagentResultAnimationTimer?: ReturnType<typeof setInterval> } = {};
209
+ let lastVersion = -1;
210
+ container.render = (width: number): string[] => {
211
+ const snapshot = getSlashRenderableSnapshot(details);
212
+ syncResultAnimation(snapshot.result, { state: animationState, invalidate: requestRender });
213
+ if (
214
+ snapshot.version !== lastVersion ||
215
+ isSlashResultRunning(snapshot.result)
216
+ ) {
217
+ lastVersion = snapshot.version;
218
+ rebuildSlashResultContainer(container, snapshot.result, options, theme);
219
+ }
220
+ return Container.prototype.render.call(container, width);
221
+ };
222
+ return container;
162
223
  }
163
224
 
164
- function parseSubagentNotifyContent(content: string): SubagentNotifyDetails | undefined {
165
- const lines = content.split("\n");
166
- const header = lines[0] ?? "";
167
- const match = header.match(/^Background task (completed|failed|paused): \*\*(.+?)\*\*(?:\s+(\([^)]*\)))?$/);
168
- if (!match) return undefined;
169
- const body = lines.slice(2);
170
- let sessionIndex = -1;
171
- for (let i = body.length - 1; i >= 1; i--) {
172
- if (body[i - 1]?.trim() === "" && /^(Session|Session file|Session share error):\s+/.test(body[i]!)) {
173
- sessionIndex = i;
174
- break;
175
- }
176
- }
177
- const sessionLine = sessionIndex >= 0 ? body[sessionIndex] : undefined;
178
- const resultLines = sessionIndex >= 0 ? body.slice(0, sessionIndex) : body;
179
- const resultPreview = resultLines.join("\n").trim() || "(no output)";
180
- let sessionLabel: string | undefined;
181
- let sessionValue: string | undefined;
182
- if (sessionLine) {
183
- const separator = sessionLine.indexOf(":");
184
- sessionLabel = sessionLine.slice(0, separator).toLowerCase();
185
- sessionValue = sessionLine.slice(separator + 1).trim();
186
- }
187
- return {
188
- agent: match[2]!,
189
- status: match[1] as SubagentNotifyDetails["status"],
190
- ...(match[3] ? { taskInfo: match[3] } : {}),
191
- resultPreview,
192
- ...(sessionLabel && sessionValue ? { sessionLabel, sessionValue } : {}),
193
- };
225
+ function parseSubagentNotifyContent(
226
+ content: string,
227
+ ): SubagentNotifyDetails | undefined {
228
+ const lines = content.split("\n");
229
+ const header = lines[0] ?? "";
230
+ const match = header.match(
231
+ /^Background task (completed|failed|paused): \*\*(.+?)\*\*(?:\s+(\([^)]*\)))?$/,
232
+ );
233
+ if (!match) return undefined;
234
+ const body = lines.slice(2);
235
+ let sessionIndex = -1;
236
+ for (let i = body.length - 1; i >= 1; i--) {
237
+ if (
238
+ body[i - 1]?.trim() === "" &&
239
+ /^(Session|Session file|Session share error):\s+/.test(body[i]!)
240
+ ) {
241
+ sessionIndex = i;
242
+ break;
243
+ }
244
+ }
245
+ const sessionLine = sessionIndex >= 0 ? body[sessionIndex] : undefined;
246
+ const resultLines = sessionIndex >= 0 ? body.slice(0, sessionIndex) : body;
247
+ const resultPreview = resultLines.join("\n").trim() || "(no output)";
248
+ let sessionLabel: string | undefined;
249
+ let sessionValue: string | undefined;
250
+ if (sessionLine) {
251
+ const separator = sessionLine.indexOf(":");
252
+ sessionLabel = sessionLine.slice(0, separator).toLowerCase();
253
+ sessionValue = sessionLine.slice(separator + 1).trim();
254
+ }
255
+ return {
256
+ agent: match[2]!,
257
+ status: match[1] as SubagentNotifyDetails["status"],
258
+ ...(match[3] ? { taskInfo: match[3] } : {}),
259
+ resultPreview,
260
+ ...(sessionLabel && sessionValue ? { sessionLabel, sessionValue } : {}),
261
+ };
194
262
  }
195
263
 
196
264
  class SubagentControlNoticeComponent implements Component {
197
- constructor(
198
- private readonly details: SubagentControlMessageDetails,
199
- private readonly theme: ExtensionContext["ui"]["theme"],
200
- ) {}
201
-
202
- invalidate(): void {}
203
-
204
- render(width: number): string[] {
205
- const eventLabel = this.details.event.type.replaceAll("_", " ");
206
- if (width < 3) return [truncateToWidth(`Subagent ${eventLabel}`, width)];
207
- const bodyWidth = Math.max(1, width - 2);
208
- const borderChar = "─";
209
- const header = ` ⚠ Subagent ${eventLabel}: ${this.details.event.agent} `;
210
- const headerText = truncateToWidth(header, bodyWidth, "");
211
- const headerPadding = Math.max(0, bodyWidth - visibleWidth(headerText));
212
- const lines = [this.theme.fg("accent", `╭${headerText}${borderChar.repeat(headerPadding)}╮`)];
213
-
214
- for (const line of wrapTextWithAnsi(formatSubagentControlNotice(this.details), bodyWidth)) {
215
- const text = truncateToWidth(line, bodyWidth, "");
216
- const padding = Math.max(0, bodyWidth - visibleWidth(text));
217
- lines.push(this.theme.fg("accent", `│${text}${" ".repeat(padding)}│`));
218
- }
219
- lines.push(this.theme.fg("accent", `╰${borderChar.repeat(bodyWidth)}╯`));
220
- return lines;
221
- }
265
+ constructor(
266
+ private readonly details: SubagentControlMessageDetails,
267
+ private readonly theme: ExtensionContext["ui"]["theme"],
268
+ ) {}
269
+
270
+ invalidate(): void {}
271
+
272
+ render(width: number): string[] {
273
+ const eventLabel = this.details.event.type.replaceAll("_", " ");
274
+ if (width < 3) return [truncateToWidth(`Subagent ${eventLabel}`, width)];
275
+ const bodyWidth = Math.max(1, width - 2);
276
+ const borderChar = "─";
277
+ const header = ` ⚠ Subagent ${eventLabel}: ${this.details.event.agent} `;
278
+ const headerText = truncateToWidth(header, bodyWidth, "");
279
+ const headerPadding = Math.max(0, bodyWidth - visibleWidth(headerText));
280
+ const lines = [
281
+ this.theme.fg(
282
+ "accent",
283
+ `╭${headerText}${borderChar.repeat(headerPadding)}╮`,
284
+ ),
285
+ ];
286
+
287
+ for (const line of wrapTextWithAnsi(
288
+ formatSubagentControlNotice(this.details),
289
+ bodyWidth,
290
+ )) {
291
+ const text = truncateToWidth(line, bodyWidth, "");
292
+ const padding = Math.max(0, bodyWidth - visibleWidth(text));
293
+ lines.push(this.theme.fg("accent", `│${text}${" ".repeat(padding)}│`));
294
+ }
295
+ lines.push(this.theme.fg("accent", `╰${borderChar.repeat(bodyWidth)}╯`));
296
+ return lines;
297
+ }
222
298
  }
223
299
 
224
300
  export default function registerSubagentExtension(pi: ExtensionAPI): void {
225
- if (getEnvValue(SUBAGENT_CHILD_ENV) === "1") return;
226
- const globalStore = globalThis as Record<string, unknown>;
227
- const runtimeCleanupStoreKey = "__piSubagentRuntimeCleanup";
228
- const previousRuntimeCleanup = globalStore[runtimeCleanupStoreKey];
229
- if (typeof previousRuntimeCleanup === "function") {
230
- try {
231
- previousRuntimeCleanup();
232
- } catch {
233
- // Best effort cleanup for stale timers from an older reload.
234
- }
235
- }
236
-
237
- ensureAccessibleDir(RESULTS_DIR);
238
- ensureAccessibleDir(ASYNC_DIR);
239
- cleanupOldChainDirs();
240
-
241
- const config = loadConfig();
242
- const asyncByDefault = config.asyncByDefault === true;
243
- const tempArtifactsDir = getArtifactsDir(null);
244
- cleanupAllArtifactDirs(DEFAULT_ARTIFACT_CONFIG.cleanupDays);
245
-
246
- const state: SubagentState = {
247
- baseCwd: "",
248
- currentSessionId: null,
249
- asyncJobs: new Map(),
250
- foregroundRuns: new Map(),
251
- foregroundControls: new Map(),
252
- lastForegroundControlId: null,
253
- pendingForegroundControlNotices: new Map(),
254
- cleanupTimers: new Map(),
255
- lastUiContext: null,
256
- poller: null,
257
- completionSeen: new Map(),
258
- watcher: null,
259
- watcherRestartTimer: null,
260
- resultFileCoalescer: {
261
- schedule: () => false,
262
- clear: () => {},
263
- },
264
- };
265
-
266
- const { startResultWatcher, primeExistingResults, stopResultWatcher } = createResultWatcher(
267
- pi,
268
- state,
269
- RESULTS_DIR,
270
- 10 * 60 * 1000,
271
- );
272
- startResultWatcher();
273
- primeExistingResults();
274
-
275
- const runtimeCleanup = () => {
276
- stopWidgetAnimation();
277
- stopResultAnimations();
278
- stopResultWatcher();
279
- clearPendingForegroundControlNotices(state);
280
- if (state.poller) {
281
- clearInterval(state.poller);
282
- state.poller = null;
283
- }
284
- };
285
- globalStore[runtimeCleanupStoreKey] = runtimeCleanup;
286
-
287
- const { ensurePoller, handleStarted, handleComplete, resetJobs } = createAsyncJobTracker(pi, state, ASYNC_DIR);
288
- const executor = createSubagentExecutor({
289
- pi,
290
- state,
291
- config,
292
- asyncByDefault,
293
- tempArtifactsDir,
294
- getSubagentSessionRoot,
295
- expandTilde,
296
- discoverAgents,
297
- });
298
-
299
- pi.registerMessageRenderer<SlashMessageDetails>(SLASH_RESULT_TYPE, (message, options, theme) => {
300
- const details = resolveSlashMessageDetails(message.details);
301
- if (!details) return undefined;
302
- return createSlashResultComponent(details, options, theme, () => state.lastUiContext?.ui.requestRender?.());
303
- });
304
-
305
- pi.registerMessageRenderer<SubagentNotifyDetails>("subagent-notify", (message, options, theme) => {
306
- const content = typeof message.content === "string" ? message.content : "";
307
- const details = (message.details as SubagentNotifyDetails | undefined) ?? parseSubagentNotifyContent(content);
308
- if (!details) return new Text(content, 0, 0);
309
- const icon = details.status === "completed"
310
- ? theme.fg("success", "✓")
311
- : details.status === "paused"
312
- ? theme.fg("warning", "■")
313
- : theme.fg("error", "✗");
314
- const parts: string[] = [];
315
- if (details.taskInfo) parts.push(details.taskInfo);
316
- if (details.durationMs !== undefined) parts.push(formatDuration(details.durationMs));
317
- let text = `${icon} ${theme.bold(details.agent)} ${theme.fg("dim", details.status)}`;
318
- if (parts.length > 0) text += ` ${theme.fg("dim", "·")} ${parts.map((part) => theme.fg("dim", part)).join(` ${theme.fg("dim", "·")} `)}`;
319
- const trimmedPreview = details.resultPreview.trim();
320
- const previewLines = options.expanded
321
- ? trimmedPreview.split("\n").filter((line) => line.trim())
322
- : [trimmedPreview.split("\n", 1)[0] ?? ""].filter((line) => line.trim());
323
- for (const line of previewLines.length > 0 ? previewLines : ["(no output)"]) {
324
- text += `\n ${theme.fg("dim", `⎿ ${line}`)}`;
325
- }
326
- if (!options.expanded && trimmedPreview.includes("\n")) {
327
- text += `\n ${theme.fg("dim", "Ctrl+O full notification")}`;
328
- }
329
- if (details.sessionLabel && details.sessionValue) {
330
- text += `\n ${theme.fg("muted", `${details.sessionLabel}: ${shortenPath(details.sessionValue)}`)}`;
331
- }
332
- return new Text(text, 0, 0);
333
- });
334
-
335
- pi.registerMessageRenderer<SubagentControlMessageDetails>(SUBAGENT_CONTROL_MESSAGE_TYPE, (message, _options, theme) => {
336
- const details = message.details as SubagentControlMessageDetails | undefined;
337
- if (!details?.event) return undefined;
338
- const content = typeof message.content === "string" ? message.content : undefined;
339
- return new SubagentControlNoticeComponent({ ...details, noticeText: formatSubagentControlNotice(details, content) }, theme);
340
- });
341
-
342
- const executeSubagentCollapsed = (id: string, params: SubagentParamsLike, signal: AbortSignal, onUpdate: ((result: AgentToolResult<Details>) => void) | undefined, ctx: ExtensionContext) => {
343
- if (ctx.hasUI) ctx.ui.setToolsExpanded(false);
344
- return executor.execute(id, params, signal, onUpdate, ctx);
345
- };
346
-
347
- const slashBridge = registerSlashSubagentBridge({
348
- events: pi.events,
349
- getContext: () => state.lastUiContext,
350
- execute: (id, params, signal, onUpdate, ctx) =>
351
- executeSubagentCollapsed(id, params, signal, onUpdate, ctx),
352
- });
353
-
354
- const promptTemplateBridge = registerPromptTemplateDelegationBridge({
355
- events: pi.events,
356
- getContext: () => state.lastUiContext,
357
- execute: async (requestId, request, signal, ctx, onUpdate) => {
358
- if (request.tasks && request.tasks.length > 0) {
359
- return executeSubagentCollapsed(
360
- requestId,
361
- {
362
- tasks: request.tasks,
363
- context: request.context,
364
- cwd: request.cwd,
365
- worktree: request.worktree,
366
- async: false,
367
- clarify: false,
368
- },
369
- signal,
370
- onUpdate,
371
- ctx,
372
- );
373
- }
374
- return executeSubagentCollapsed(
375
- requestId,
376
- {
377
- agent: request.agent,
378
- task: request.task,
379
- context: request.context,
380
- cwd: request.cwd,
381
- model: request.model,
382
- async: false,
383
- clarify: false,
384
- },
385
- signal,
386
- onUpdate,
387
- ctx,
388
- );
389
- },
390
- });
391
-
392
- function effectiveParallelTaskCount(tasks: Array<{ count?: unknown }> | undefined): number {
393
- if (!tasks || tasks.length === 0) return 0;
394
- return tasks.reduce((total, task) => {
395
- const count = typeof task.count === "number" && Number.isInteger(task.count) && task.count >= 1 ? task.count : 1;
396
- return total + count;
397
- }, 0);
398
- }
399
-
400
- const tool: ToolDefinition<typeof SubagentParams, Details> = {
401
- name: "subagent",
402
- label: "Subagent",
403
- description: `Delegate to subagents or manage agent definitions.
301
+ if (getEnvValue(SUBAGENT_CHILD_ENV) === "1") return;
302
+ const globalStore = globalThis as Record<string, unknown>;
303
+ const runtimeCleanupStoreKey = "__piSubagentRuntimeCleanup";
304
+ const previousRuntimeCleanup = globalStore[runtimeCleanupStoreKey];
305
+ if (typeof previousRuntimeCleanup === "function") {
306
+ try {
307
+ previousRuntimeCleanup();
308
+ } catch {
309
+ // Best effort cleanup for stale timers from an older reload.
310
+ }
311
+ }
312
+
313
+ ensureAccessibleDir(RESULTS_DIR);
314
+ ensureAccessibleDir(ASYNC_DIR);
315
+ cleanupOldChainDirs();
316
+
317
+ const config = loadConfig();
318
+ const asyncByDefault = config.asyncByDefault === true;
319
+ const tempArtifactsDir = getArtifactsDir(null);
320
+ cleanupAllArtifactDirs(DEFAULT_ARTIFACT_CONFIG.cleanupDays);
321
+
322
+ const state: SubagentState = {
323
+ baseCwd: "",
324
+ currentSessionId: null,
325
+ asyncJobs: new Map(),
326
+ foregroundRuns: new Map(),
327
+ foregroundControls: new Map(),
328
+ lastForegroundControlId: null,
329
+ pendingForegroundControlNotices: new Map(),
330
+ cleanupTimers: new Map(),
331
+ lastUiContext: null,
332
+ poller: null,
333
+ completionSeen: new Map(),
334
+ watcher: null,
335
+ watcherRestartTimer: null,
336
+ resultFileCoalescer: {
337
+ schedule: () => false,
338
+ clear: () => {},
339
+ },
340
+ };
341
+
342
+ const { startResultWatcher, primeExistingResults, stopResultWatcher } =
343
+ createResultWatcher(pi, state, RESULTS_DIR, 10 * 60 * 1000);
344
+ startResultWatcher();
345
+ primeExistingResults();
346
+
347
+ const runtimeCleanup = () => {
348
+ stopWidgetAnimation();
349
+ stopResultAnimations();
350
+ stopResultWatcher();
351
+ clearPendingForegroundControlNotices(state);
352
+ if (state.poller) {
353
+ clearInterval(state.poller);
354
+ state.poller = null;
355
+ }
356
+ };
357
+ globalStore[runtimeCleanupStoreKey] = runtimeCleanup;
358
+
359
+ const { ensurePoller, handleStarted, handleComplete, resetJobs } =
360
+ createAsyncJobTracker(pi, state, ASYNC_DIR);
361
+ const executor = createSubagentExecutor({
362
+ pi,
363
+ state,
364
+ config,
365
+ asyncByDefault,
366
+ tempArtifactsDir,
367
+ getSubagentSessionRoot,
368
+ expandTilde,
369
+ discoverAgents,
370
+ });
371
+
372
+ pi.registerMessageRenderer<SlashMessageDetails>(
373
+ SLASH_RESULT_TYPE,
374
+ (message, options, theme) => {
375
+ const details = resolveSlashMessageDetails(message.details);
376
+ if (!details) return undefined;
377
+ return createSlashResultComponent(details, options, theme, () => state.lastUiContext?.ui.requestRender?.());
378
+ },
379
+ );
380
+
381
+ pi.registerMessageRenderer<SubagentNotifyDetails>(
382
+ "subagent-notify",
383
+ (message, options, theme) => {
384
+ const content =
385
+ typeof message.content === "string" ? message.content : "";
386
+ const details =
387
+ (message.details as SubagentNotifyDetails | undefined) ??
388
+ parseSubagentNotifyContent(content);
389
+ if (!details) return new Text(content, 0, 0);
390
+ const icon =
391
+ details.status === "completed"
392
+ ? theme.fg("success", "✓")
393
+ : details.status === "paused"
394
+ ? theme.fg("warning", "")
395
+ : theme.fg("error", "✗");
396
+ const parts: string[] = [];
397
+ if (details.taskInfo) parts.push(details.taskInfo);
398
+ if (details.durationMs !== undefined)
399
+ parts.push(formatDuration(details.durationMs));
400
+ let text = `${icon} ${theme.bold(details.agent)} ${theme.fg("dim", details.status)}`;
401
+ if (parts.length > 0)
402
+ text += ` ${theme.fg("dim", "·")} ${parts.map((part) => theme.fg("dim", part)).join(` ${theme.fg("dim", "·")} `)}`;
403
+ const trimmedPreview = details.resultPreview.trim();
404
+ const previewLines = options.expanded
405
+ ? trimmedPreview.split("\n").filter((line) => line.trim())
406
+ : [trimmedPreview.split("\n", 1)[0] ?? ""].filter((line) =>
407
+ line.trim(),
408
+ );
409
+ for (const line of previewLines.length > 0
410
+ ? previewLines
411
+ : ["(no output)"]) {
412
+ text += `\n ${theme.fg("dim", `⎿ ${line}`)}`;
413
+ }
414
+ if (!options.expanded && trimmedPreview.includes("\n")) {
415
+ text += `\n ${theme.fg("dim", "ctrl+o full notification")}`;
416
+ }
417
+ if (details.sessionLabel && details.sessionValue) {
418
+ text += `\n ${theme.fg("muted", `${details.sessionLabel}: ${shortenPath(details.sessionValue)}`)}`;
419
+ }
420
+ return new Text(text, 0, 0);
421
+ },
422
+ );
423
+
424
+ pi.registerMessageRenderer<SubagentControlMessageDetails>(
425
+ SUBAGENT_CONTROL_MESSAGE_TYPE,
426
+ (message, _options, theme) => {
427
+ const details = message.details as
428
+ | SubagentControlMessageDetails
429
+ | undefined;
430
+ if (!details?.event) return undefined;
431
+ const content =
432
+ typeof message.content === "string" ? message.content : undefined;
433
+ return new SubagentControlNoticeComponent(
434
+ {
435
+ ...details,
436
+ noticeText: formatSubagentControlNotice(details, content),
437
+ },
438
+ theme,
439
+ );
440
+ },
441
+ );
442
+
443
+ const executeSubagentCollapsed = (
444
+ id: string,
445
+ params: SubagentParamsLike,
446
+ signal: AbortSignal,
447
+ onUpdate: ((result: AgentToolResult<Details>) => void) | undefined,
448
+ ctx: ExtensionContext,
449
+ ) => {
450
+ if (ctx.hasUI) ctx.ui.setToolsExpanded(false);
451
+ return executor.execute(id, params, signal, onUpdate, ctx);
452
+ };
453
+
454
+ const slashBridge = registerSlashSubagentBridge({
455
+ events: pi.events,
456
+ getContext: () => state.lastUiContext,
457
+ execute: (id, params, signal, onUpdate, ctx) =>
458
+ executeSubagentCollapsed(id, params, signal, onUpdate, ctx),
459
+ });
460
+
461
+ const promptTemplateBridge = registerPromptTemplateDelegationBridge({
462
+ events: pi.events,
463
+ getContext: () => state.lastUiContext,
464
+ execute: async (requestId, request, signal, ctx, onUpdate) => {
465
+ if (request.tasks && request.tasks.length > 0) {
466
+ return executeSubagentCollapsed(
467
+ requestId,
468
+ {
469
+ tasks: request.tasks,
470
+ context: request.context,
471
+ cwd: request.cwd,
472
+ worktree: request.worktree,
473
+ async: false,
474
+ clarify: false,
475
+ },
476
+ signal,
477
+ onUpdate,
478
+ ctx,
479
+ );
480
+ }
481
+ return executeSubagentCollapsed(
482
+ requestId,
483
+ {
484
+ agent: request.agent,
485
+ task: request.task,
486
+ context: request.context,
487
+ cwd: request.cwd,
488
+ model: request.model,
489
+ async: false,
490
+ clarify: false,
491
+ },
492
+ signal,
493
+ onUpdate,
494
+ ctx,
495
+ );
496
+ },
497
+ });
498
+
499
+ function effectiveParallelTaskCount(
500
+ tasks: Array<{ count?: unknown }> | undefined,
501
+ ): number {
502
+ if (!tasks || tasks.length === 0) return 0;
503
+ return tasks.reduce((total, task) => {
504
+ const count =
505
+ typeof task.count === "number" &&
506
+ Number.isInteger(task.count) &&
507
+ task.count >= 1
508
+ ? task.count
509
+ : 1;
510
+ return total + count;
511
+ }, 0);
512
+ }
513
+
514
+ const tool: ToolDefinition<typeof SubagentParams, Details> = {
515
+ name: "subagent",
516
+ label: "Subagent",
517
+ description: `Delegate to subagents or manage agent definitions.
404
518
 
405
519
  EXECUTION (use exactly ONE mode):
406
520
  • Before executing, use { action: "list" } to inspect configured agents/chains. Only execute agents listed as executable/non-disabled.
@@ -431,157 +545,169 @@ CONTROL:
431
545
 
432
546
  DIAGNOSTICS:
433
547
  • { action: "doctor" } - read-only report for runtime paths, discovery, sessions, and intercom`,
434
- parameters: SubagentParams,
435
-
436
- execute(id, params, signal, onUpdate, ctx) {
437
- return executeSubagentCollapsed(id, params, signal, onUpdate, ctx);
438
- },
439
-
440
- renderCall(args, theme) {
441
- if (args.action) {
442
- const target = args.agent || args.chainName || "";
443
- return new Text(
444
- `${theme.fg("toolTitle", theme.bold("subagent "))}${args.action}${target ? ` ${theme.fg("accent", target)}` : ""}`,
445
- 0, 0,
446
- );
447
- }
448
- const isParallel = (args.tasks?.length ?? 0) > 0;
449
- const parallelCount = effectiveParallelTaskCount(args.tasks as Array<{ count?: unknown }> | undefined);
450
- const asyncLabel = args.async === true && args.clarify !== true && !isParallel ? theme.fg("warning", " [async]") : "";
451
- if (args.chain?.length)
452
- return new Text(
453
- `${theme.fg("toolTitle", theme.bold("subagent "))}chain (${args.chain.length})${asyncLabel}`,
454
- 0,
455
- 0,
456
- );
457
- if (isParallel)
458
- return new Text(
459
- `${theme.fg("toolTitle", theme.bold("subagent "))}parallel (${parallelCount})`,
460
- 0,
461
- 0,
462
- );
463
- return new Text(
464
- `${theme.fg("toolTitle", theme.bold("subagent "))}${theme.fg("accent", args.agent || "?")}${asyncLabel}`,
465
- 0,
466
- 0,
467
- );
468
- },
469
-
470
- renderResult(result, options, theme, context) {
471
- syncResultAnimation(result, context);
472
- return renderSubagentResult(result, options, theme);
473
- },
474
-
475
- };
476
-
477
- pi.registerTool(tool);
478
- registerSlashCommands(pi, state);
479
-
480
- const eventUnsubscribeStoreKey = "__piSubagentEventUnsubscribes";
481
- const controlNoticeSeenStoreKey = "__piSubagentVisibleControlNotices";
482
- const previousEventUnsubscribes = globalStore[eventUnsubscribeStoreKey];
483
- if (Array.isArray(previousEventUnsubscribes)) {
484
- for (const unsubscribe of previousEventUnsubscribes) {
485
- if (typeof unsubscribe !== "function") continue;
486
- try {
487
- unsubscribe();
488
- } catch {
489
- // Best effort cleanup for stale handlers from an older reload.
490
- }
491
- }
492
- }
493
- registerSubagentNotify(pi);
494
-
495
- const existingVisibleControlNotices = globalStore[controlNoticeSeenStoreKey];
496
- const visibleControlNotices = existingVisibleControlNotices instanceof Set ? existingVisibleControlNotices as Set<string> : new Set<string>();
497
- globalStore[controlNoticeSeenStoreKey] = visibleControlNotices;
498
- const controlEventHandler = (payload: unknown) => {
499
- handleSubagentControlNotice({
500
- pi,
501
- state,
502
- visibleControlNotices,
503
- details: payload as SubagentControlMessageDetails,
504
- });
505
- };
506
- const eventUnsubscribes = [
507
- pi.events.on(SUBAGENT_ASYNC_STARTED_EVENT, handleStarted),
508
- pi.events.on(SUBAGENT_ASYNC_COMPLETE_EVENT, handleComplete),
509
- pi.events.on(SUBAGENT_CONTROL_EVENT, controlEventHandler),
510
- ];
511
- globalStore[eventUnsubscribeStoreKey] = eventUnsubscribes;
512
-
513
- pi.on("tool_result", (event, ctx) => {
514
- if (event.toolName !== "subagent") return;
515
- if (!ctx.hasUI) return;
516
- state.lastUiContext = ctx;
517
- if (state.asyncJobs.size > 0) {
518
- renderWidget(ctx, Array.from(state.asyncJobs.values()));
519
- ensurePoller();
520
- }
521
- });
522
-
523
- const cleanupSessionArtifacts = (ctx: ExtensionContext) => {
524
- try {
525
- const sessionFile = ctx.sessionManager.getSessionFile();
526
- if (sessionFile) {
527
- cleanupOldArtifacts(getArtifactsDir(sessionFile), DEFAULT_ARTIFACT_CONFIG.cleanupDays);
528
- }
529
- } catch {
530
- // Cleanup failures should not block session lifecycle events.
531
- }
532
- };
533
-
534
- const resetSessionState = (ctx: ExtensionContext) => {
535
- state.baseCwd = ctx.cwd;
536
- state.currentSessionId = resolveCurrentSessionId(ctx.sessionManager);
537
- state.lastUiContext = ctx;
538
- cleanupSessionArtifacts(ctx);
539
- clearPendingForegroundControlNotices(state);
540
- resetJobs(ctx);
541
- restoreSlashFinalSnapshots(ctx.sessionManager.getEntries());
542
- primeExistingResults();
543
- };
544
-
545
- pi.on("session_start", (_event, ctx) => {
546
- resetSessionState(ctx);
547
- });
548
-
549
- pi.on("session_shutdown", () => {
550
- for (const unsubscribe of eventUnsubscribes) {
551
- try {
552
- unsubscribe();
553
- } catch {
554
- // Best effort cleanup during shutdown.
555
- }
556
- }
557
- if (globalStore[eventUnsubscribeStoreKey] === eventUnsubscribes) {
558
- delete globalStore[eventUnsubscribeStoreKey];
559
- }
560
- stopResultWatcher();
561
- if (state.poller) clearInterval(state.poller);
562
- state.poller = null;
563
- clearPendingForegroundControlNotices(state);
564
- for (const timer of state.cleanupTimers.values()) {
565
- clearTimeout(timer);
566
- }
567
- state.cleanupTimers.clear();
568
- state.asyncJobs.clear();
569
- clearSlashSnapshots();
570
- slashBridge.cancelAll();
571
- slashBridge.dispose();
572
- promptTemplateBridge.cancelAll();
573
- promptTemplateBridge.dispose();
574
- stopWidgetAnimation();
575
- stopResultAnimations();
576
- if (globalStore[runtimeCleanupStoreKey] === runtimeCleanup) {
577
- delete globalStore[runtimeCleanupStoreKey];
578
- }
579
- try {
580
- if (state.lastUiContext?.hasUI) {
581
- state.lastUiContext.ui.setWidget(WIDGET_KEY, undefined);
582
- }
583
- } catch (error) {
584
- if (!isStaleExtensionContextError(error)) throw error;
585
- }
586
- });
548
+ parameters: SubagentParams,
549
+
550
+ execute(id, params, signal, onUpdate, ctx) {
551
+ return executeSubagentCollapsed(id, params, signal, onUpdate, ctx);
552
+ },
553
+
554
+ renderCall(args, theme) {
555
+ if (args.action) {
556
+ const target = args.agent || args.chainName || "";
557
+ return new Text(
558
+ `${theme.fg("toolTitle", theme.bold("subagent "))}${args.action}${target ? ` ${theme.fg("accent", target)}` : ""}`,
559
+ 0,
560
+ 0,
561
+ );
562
+ }
563
+ const isParallel = (args.tasks?.length ?? 0) > 0;
564
+ const parallelCount = effectiveParallelTaskCount(
565
+ args.tasks as Array<{ count?: unknown }> | undefined,
566
+ );
567
+ const asyncLabel =
568
+ args.async === true && args.clarify !== true && !isParallel
569
+ ? theme.fg("warning", " [async]")
570
+ : "";
571
+ if (args.chain?.length)
572
+ return new Text(
573
+ `${theme.fg("toolTitle", theme.bold("subagent "))}chain (${args.chain.length})${asyncLabel}`,
574
+ 0,
575
+ 0,
576
+ );
577
+ if (isParallel)
578
+ return new Text(
579
+ `${theme.fg("toolTitle", theme.bold("subagent "))}parallel (${parallelCount})`,
580
+ 0,
581
+ 0,
582
+ );
583
+ return new Text(
584
+ `${theme.fg("toolTitle", theme.bold("subagent "))}${theme.fg("accent", args.agent || "?")}${asyncLabel}`,
585
+ 0,
586
+ 0,
587
+ );
588
+ },
589
+
590
+ renderResult(result, options, theme, context) {
591
+ syncResultAnimation(result, context);
592
+ return renderSubagentResult(result, options, theme);
593
+ },
594
+ };
595
+
596
+ pi.registerTool(tool);
597
+ registerSlashCommands(pi, state);
598
+
599
+ const eventUnsubscribeStoreKey = "__piSubagentEventUnsubscribes";
600
+ const controlNoticeSeenStoreKey = "__piSubagentVisibleControlNotices";
601
+ const previousEventUnsubscribes = globalStore[eventUnsubscribeStoreKey];
602
+ if (Array.isArray(previousEventUnsubscribes)) {
603
+ for (const unsubscribe of previousEventUnsubscribes) {
604
+ if (typeof unsubscribe !== "function") continue;
605
+ try {
606
+ unsubscribe();
607
+ } catch {
608
+ // Best effort cleanup for stale handlers from an older reload.
609
+ }
610
+ }
611
+ }
612
+ registerSubagentNotify(pi);
613
+
614
+ const existingVisibleControlNotices = globalStore[controlNoticeSeenStoreKey];
615
+ const visibleControlNotices =
616
+ existingVisibleControlNotices instanceof Set
617
+ ? (existingVisibleControlNotices as Set<string>)
618
+ : new Set<string>();
619
+ globalStore[controlNoticeSeenStoreKey] = visibleControlNotices;
620
+ const controlEventHandler = (payload: unknown) => {
621
+ handleSubagentControlNotice({
622
+ pi,
623
+ state,
624
+ visibleControlNotices,
625
+ details: payload as SubagentControlMessageDetails,
626
+ });
627
+ };
628
+ const eventUnsubscribes = [
629
+ pi.events.on(SUBAGENT_ASYNC_STARTED_EVENT, handleStarted),
630
+ pi.events.on(SUBAGENT_ASYNC_COMPLETE_EVENT, handleComplete),
631
+ pi.events.on(SUBAGENT_CONTROL_EVENT, controlEventHandler),
632
+ ];
633
+ globalStore[eventUnsubscribeStoreKey] = eventUnsubscribes;
634
+
635
+ pi.on("tool_result", (event, ctx) => {
636
+ if (event.toolName !== "subagent") return;
637
+ if (!ctx.hasUI) return;
638
+ state.lastUiContext = ctx;
639
+ if (state.asyncJobs.size > 0) {
640
+ renderWidget(ctx, Array.from(state.asyncJobs.values()));
641
+ ctx.ui.requestRender?.();
642
+ ensurePoller();
643
+ }
644
+ });
645
+
646
+ const cleanupSessionArtifacts = (ctx: ExtensionContext) => {
647
+ try {
648
+ const sessionFile = ctx.sessionManager.getSessionFile();
649
+ if (sessionFile) {
650
+ cleanupOldArtifacts(
651
+ getArtifactsDir(sessionFile),
652
+ DEFAULT_ARTIFACT_CONFIG.cleanupDays,
653
+ );
654
+ }
655
+ } catch {
656
+ // Cleanup failures should not block session lifecycle events.
657
+ }
658
+ };
659
+
660
+ const resetSessionState = (ctx: ExtensionContext) => {
661
+ state.baseCwd = ctx.cwd;
662
+ state.currentSessionId = resolveCurrentSessionId(ctx.sessionManager);
663
+ state.lastUiContext = ctx;
664
+ cleanupSessionArtifacts(ctx);
665
+ clearPendingForegroundControlNotices(state);
666
+ resetJobs(ctx);
667
+ restoreSlashFinalSnapshots(ctx.sessionManager.getEntries());
668
+ primeExistingResults();
669
+ };
670
+
671
+ pi.on("session_start", (_event, ctx) => {
672
+ resetSessionState(ctx);
673
+ });
674
+
675
+ pi.on("session_shutdown", () => {
676
+ for (const unsubscribe of eventUnsubscribes) {
677
+ try {
678
+ unsubscribe();
679
+ } catch {
680
+ // Best effort cleanup during shutdown.
681
+ }
682
+ }
683
+ if (globalStore[eventUnsubscribeStoreKey] === eventUnsubscribes) {
684
+ delete globalStore[eventUnsubscribeStoreKey];
685
+ }
686
+ stopResultWatcher();
687
+ if (state.poller) clearInterval(state.poller);
688
+ state.poller = null;
689
+ clearPendingForegroundControlNotices(state);
690
+ for (const timer of state.cleanupTimers.values()) {
691
+ clearTimeout(timer);
692
+ }
693
+ state.cleanupTimers.clear();
694
+ state.asyncJobs.clear();
695
+ clearSlashSnapshots();
696
+ slashBridge.cancelAll();
697
+ slashBridge.dispose();
698
+ promptTemplateBridge.cancelAll();
699
+ promptTemplateBridge.dispose();
700
+ stopWidgetAnimation();
701
+ stopResultAnimations();
702
+ if (globalStore[runtimeCleanupStoreKey] === runtimeCleanup) {
703
+ delete globalStore[runtimeCleanupStoreKey];
704
+ }
705
+ try {
706
+ if (state.lastUiContext?.hasUI) {
707
+ state.lastUiContext.ui.setWidget(WIDGET_KEY, undefined);
708
+ }
709
+ } catch (error) {
710
+ if (!isStaleExtensionContextError(error)) throw error;
711
+ }
712
+ });
587
713
  }