@ashx-j/lunr-dev 0.2.16-dev.9.1 → 0.2.21-dev.12.1

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 (430) hide show
  1. package/CHANGELOG.md +67 -1
  2. package/README.md +7 -1
  3. package/dist/builtin-extensions/ashxj-thinking.d.ts +1 -0
  4. package/dist/builtin-extensions/ashxj-thinking.d.ts.map +1 -1
  5. package/dist/builtin-extensions/ashxj-thinking.js +44 -19
  6. package/dist/builtin-extensions/ashxj-thinking.js.map +1 -1
  7. package/dist/builtin-extensions/index.d.ts.map +1 -1
  8. package/dist/builtin-extensions/index.js +1 -2
  9. package/dist/builtin-extensions/index.js.map +1 -1
  10. package/dist/builtin-extensions/lunr-computer-use.d.ts +3 -0
  11. package/dist/builtin-extensions/lunr-computer-use.d.ts.map +1 -0
  12. package/dist/builtin-extensions/lunr-computer-use.js +158 -0
  13. package/dist/builtin-extensions/lunr-computer-use.js.map +1 -0
  14. package/dist/builtin-extensions/lunr-todos.d.ts +6 -5
  15. package/dist/builtin-extensions/lunr-todos.d.ts.map +1 -1
  16. package/dist/builtin-extensions/lunr-todos.js +9 -7
  17. package/dist/builtin-extensions/lunr-todos.js.map +1 -1
  18. package/dist/builtin-extensions/pi-intercom/broker/spawn.d.ts +6 -4
  19. package/dist/builtin-extensions/pi-intercom/broker/spawn.d.ts.map +1 -1
  20. package/dist/builtin-extensions/pi-intercom/broker/spawn.js +114 -61
  21. package/dist/builtin-extensions/pi-intercom/broker/spawn.js.map +1 -1
  22. package/dist/builtin-extensions/pi-intercom/index.d.ts.map +1 -1
  23. package/dist/builtin-extensions/pi-intercom/index.js +360 -351
  24. package/dist/builtin-extensions/pi-intercom/index.js.map +1 -1
  25. package/dist/builtin-extensions/pi-lsp-extension/src/index.d.ts.map +1 -1
  26. package/dist/builtin-extensions/pi-lsp-extension/src/index.js +10 -3
  27. package/dist/builtin-extensions/pi-lsp-extension/src/index.js.map +1 -1
  28. package/dist/builtin-extensions/pi-lsp-extension/src/runtime.d.ts +5 -1
  29. package/dist/builtin-extensions/pi-lsp-extension/src/runtime.d.ts.map +1 -1
  30. package/dist/builtin-extensions/pi-lsp-extension/src/runtime.js +26 -4
  31. package/dist/builtin-extensions/pi-lsp-extension/src/runtime.js.map +1 -1
  32. package/dist/builtin-extensions/pi-mcp-adapter/index.d.ts.map +1 -1
  33. package/dist/builtin-extensions/pi-mcp-adapter/index.js +37 -27
  34. package/dist/builtin-extensions/pi-mcp-adapter/index.js.map +1 -1
  35. package/dist/builtin-extensions/pi-mcp-adapter/server-manager.d.ts +6 -1
  36. package/dist/builtin-extensions/pi-mcp-adapter/server-manager.d.ts.map +1 -1
  37. package/dist/builtin-extensions/pi-mcp-adapter/server-manager.js +33 -8
  38. package/dist/builtin-extensions/pi-mcp-adapter/server-manager.js.map +1 -1
  39. package/dist/builtin-extensions/pi-subagents/src/extension/fanout-child.d.ts.map +1 -1
  40. package/dist/builtin-extensions/pi-subagents/src/extension/fanout-child.js +2 -2
  41. package/dist/builtin-extensions/pi-subagents/src/extension/fanout-child.js.map +1 -1
  42. package/dist/builtin-extensions/pi-subagents/src/extension/index.d.ts +8 -6
  43. package/dist/builtin-extensions/pi-subagents/src/extension/index.d.ts.map +1 -1
  44. package/dist/builtin-extensions/pi-subagents/src/extension/index.js +179 -79
  45. package/dist/builtin-extensions/pi-subagents/src/extension/index.js.map +1 -1
  46. package/dist/builtin-extensions/pi-subagents/src/extension/schemas.d.ts +18 -8
  47. package/dist/builtin-extensions/pi-subagents/src/extension/schemas.d.ts.map +1 -1
  48. package/dist/builtin-extensions/pi-subagents/src/extension/schemas.js +44 -15
  49. package/dist/builtin-extensions/pi-subagents/src/extension/schemas.js.map +1 -1
  50. package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.d.ts +4 -3
  51. package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.d.ts.map +1 -1
  52. package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.js +24 -14
  53. package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.js.map +1 -1
  54. package/dist/builtin-extensions/pi-subagents/src/intercom/native-supervisor-channel.d.ts +8 -1
  55. package/dist/builtin-extensions/pi-subagents/src/intercom/native-supervisor-channel.d.ts.map +1 -1
  56. package/dist/builtin-extensions/pi-subagents/src/intercom/native-supervisor-channel.js +247 -18
  57. package/dist/builtin-extensions/pi-subagents/src/intercom/native-supervisor-channel.js.map +1 -1
  58. package/dist/builtin-extensions/pi-subagents/src/intercom/result-intercom.d.ts +1 -0
  59. package/dist/builtin-extensions/pi-subagents/src/intercom/result-intercom.d.ts.map +1 -1
  60. package/dist/builtin-extensions/pi-subagents/src/intercom/result-intercom.js +1 -1
  61. package/dist/builtin-extensions/pi-subagents/src/intercom/result-intercom.js.map +1 -1
  62. package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-ask.d.ts +29 -0
  63. package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-ask.d.ts.map +1 -0
  64. package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-ask.js +179 -0
  65. package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-ask.js.map +1 -0
  66. package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-questions.d.ts +89 -0
  67. package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-questions.d.ts.map +1 -0
  68. package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-questions.js +541 -0
  69. package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-questions.js.map +1 -0
  70. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-execution.d.ts +11 -1
  71. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-execution.d.ts.map +1 -1
  72. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-execution.js +38 -12
  73. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-execution.js.map +1 -1
  74. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-job-tracker.d.ts.map +1 -1
  75. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-job-tracker.js +3 -2
  76. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-job-tracker.js.map +1 -1
  77. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-resume.d.ts +2 -1
  78. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-resume.d.ts.map +1 -1
  79. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-resume.js +35 -8
  80. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-resume.js.map +1 -1
  81. package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.d.ts +7 -3
  82. package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.d.ts.map +1 -1
  83. package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.js +26 -4
  84. package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.js.map +1 -1
  85. package/dist/builtin-extensions/pi-subagents/src/runs/background/result-watcher.d.ts +1 -0
  86. package/dist/builtin-extensions/pi-subagents/src/runs/background/result-watcher.d.ts.map +1 -1
  87. package/dist/builtin-extensions/pi-subagents/src/runs/background/result-watcher.js +55 -38
  88. package/dist/builtin-extensions/pi-subagents/src/runs/background/result-watcher.js.map +1 -1
  89. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.d.ts +100 -0
  90. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.d.ts.map +1 -1
  91. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.js +46 -31
  92. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.js.map +1 -1
  93. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-wait.d.ts +3 -6
  94. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-wait.d.ts.map +1 -1
  95. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-wait.js +64 -5
  96. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-wait.js.map +1 -1
  97. package/dist/builtin-extensions/pi-subagents/src/runs/background/top-level-async.d.ts +15 -2
  98. package/dist/builtin-extensions/pi-subagents/src/runs/background/top-level-async.d.ts.map +1 -1
  99. package/dist/builtin-extensions/pi-subagents/src/runs/background/top-level-async.js +14 -4
  100. package/dist/builtin-extensions/pi-subagents/src/runs/background/top-level-async.js.map +1 -1
  101. package/dist/builtin-extensions/pi-subagents/src/runs/background/wait-tool.d.ts +1 -1
  102. package/dist/builtin-extensions/pi-subagents/src/runs/background/wait-tool.d.ts.map +1 -1
  103. package/dist/builtin-extensions/pi-subagents/src/runs/background/wait-tool.js +7 -3
  104. package/dist/builtin-extensions/pi-subagents/src/runs/background/wait-tool.js.map +1 -1
  105. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.d.ts.map +1 -1
  106. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.js +21 -8
  107. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.js.map +1 -1
  108. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.d.ts.map +1 -1
  109. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.js +1 -1
  110. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.js.map +1 -1
  111. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/request-params.d.ts +10 -0
  112. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/request-params.d.ts.map +1 -0
  113. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/request-params.js +38 -0
  114. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/request-params.js.map +1 -0
  115. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.d.ts +0 -1
  116. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.d.ts.map +1 -1
  117. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.js +74 -41
  118. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.js.map +1 -1
  119. package/dist/builtin-extensions/pi-subagents/src/runs/shared/acceptance.d.ts +2 -0
  120. package/dist/builtin-extensions/pi-subagents/src/runs/shared/acceptance.d.ts.map +1 -1
  121. package/dist/builtin-extensions/pi-subagents/src/runs/shared/acceptance.js +75 -18
  122. package/dist/builtin-extensions/pi-subagents/src/runs/shared/acceptance.js.map +1 -1
  123. package/dist/builtin-extensions/pi-subagents/src/runs/shared/child-tools.d.ts +1 -1
  124. package/dist/builtin-extensions/pi-subagents/src/runs/shared/child-tools.d.ts.map +1 -1
  125. package/dist/builtin-extensions/pi-subagents/src/runs/shared/child-tools.js +2 -0
  126. package/dist/builtin-extensions/pi-subagents/src/runs/shared/child-tools.js.map +1 -1
  127. package/dist/builtin-extensions/pi-subagents/src/runs/shared/completion-guard.d.ts +1 -1
  128. package/dist/builtin-extensions/pi-subagents/src/runs/shared/completion-guard.d.ts.map +1 -1
  129. package/dist/builtin-extensions/pi-subagents/src/runs/shared/completion-guard.js +1 -1
  130. package/dist/builtin-extensions/pi-subagents/src/runs/shared/completion-guard.js.map +1 -1
  131. package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.d.ts +13 -1
  132. package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.d.ts.map +1 -1
  133. package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.js +67 -11
  134. package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.js.map +1 -1
  135. package/dist/builtin-extensions/pi-subagents/src/runs/shared/parallel-utils.d.ts +1 -0
  136. package/dist/builtin-extensions/pi-subagents/src/runs/shared/parallel-utils.d.ts.map +1 -1
  137. package/dist/builtin-extensions/pi-subagents/src/runs/shared/parallel-utils.js.map +1 -1
  138. package/dist/builtin-extensions/pi-subagents/src/runs/shared/pi-args.d.ts +3 -0
  139. package/dist/builtin-extensions/pi-subagents/src/runs/shared/pi-args.d.ts.map +1 -1
  140. package/dist/builtin-extensions/pi-subagents/src/runs/shared/pi-args.js +7 -2
  141. package/dist/builtin-extensions/pi-subagents/src/runs/shared/pi-args.js.map +1 -1
  142. package/dist/builtin-extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.d.ts.map +1 -1
  143. package/dist/builtin-extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.js +13 -3
  144. package/dist/builtin-extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.js.map +1 -1
  145. package/dist/builtin-extensions/pi-subagents/src/runs/shared/task-intent.d.ts +2 -2
  146. package/dist/builtin-extensions/pi-subagents/src/runs/shared/task-intent.d.ts.map +1 -1
  147. package/dist/builtin-extensions/pi-subagents/src/runs/shared/task-intent.js +5 -10
  148. package/dist/builtin-extensions/pi-subagents/src/runs/shared/task-intent.js.map +1 -1
  149. package/dist/builtin-extensions/pi-subagents/src/shared/async-guidance.d.ts +2 -0
  150. package/dist/builtin-extensions/pi-subagents/src/shared/async-guidance.d.ts.map +1 -0
  151. package/dist/builtin-extensions/pi-subagents/src/shared/async-guidance.js +3 -0
  152. package/dist/builtin-extensions/pi-subagents/src/shared/async-guidance.js.map +1 -0
  153. package/dist/builtin-extensions/pi-subagents/src/shared/child-spec.d.ts +3 -0
  154. package/dist/builtin-extensions/pi-subagents/src/shared/child-spec.d.ts.map +1 -1
  155. package/dist/builtin-extensions/pi-subagents/src/shared/child-spec.js +68 -11
  156. package/dist/builtin-extensions/pi-subagents/src/shared/child-spec.js.map +1 -1
  157. package/dist/builtin-extensions/pi-subagents/src/shared/formatters.d.ts +12 -1
  158. package/dist/builtin-extensions/pi-subagents/src/shared/formatters.d.ts.map +1 -1
  159. package/dist/builtin-extensions/pi-subagents/src/shared/formatters.js +21 -2
  160. package/dist/builtin-extensions/pi-subagents/src/shared/formatters.js.map +1 -1
  161. package/dist/builtin-extensions/pi-subagents/src/shared/types.d.ts +21 -4
  162. package/dist/builtin-extensions/pi-subagents/src/shared/types.d.ts.map +1 -1
  163. package/dist/builtin-extensions/pi-subagents/src/shared/types.js +1 -1
  164. package/dist/builtin-extensions/pi-subagents/src/shared/types.js.map +1 -1
  165. package/dist/builtin-extensions/pi-subagents/src/slash/delegation-adapters.d.ts.map +1 -1
  166. package/dist/builtin-extensions/pi-subagents/src/slash/delegation-adapters.js.map +1 -1
  167. package/dist/builtin-extensions/pi-subagents/src/slash/prompt-workflows.d.ts +7 -0
  168. package/dist/builtin-extensions/pi-subagents/src/slash/prompt-workflows.d.ts.map +1 -1
  169. package/dist/builtin-extensions/pi-subagents/src/slash/prompt-workflows.js +11 -7
  170. package/dist/builtin-extensions/pi-subagents/src/slash/prompt-workflows.js.map +1 -1
  171. package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.d.ts +6 -0
  172. package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.d.ts.map +1 -1
  173. package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.js +46 -29
  174. package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.js.map +1 -1
  175. package/dist/builtin-extensions/pi-subagents/src/tui/render.d.ts +47 -4
  176. package/dist/builtin-extensions/pi-subagents/src/tui/render.d.ts.map +1 -1
  177. package/dist/builtin-extensions/pi-subagents/src/tui/render.js +428 -431
  178. package/dist/builtin-extensions/pi-subagents/src/tui/render.js.map +1 -1
  179. package/dist/builtin-extensions/pi-subagents/src/watchdog/register-main.d.ts.map +1 -1
  180. package/dist/builtin-extensions/pi-subagents/src/watchdog/register-main.js +1 -1
  181. package/dist/builtin-extensions/pi-subagents/src/watchdog/register-main.js.map +1 -1
  182. package/dist/builtin-extensions/pi-subagents/src/watchdog/tool-actions.d.ts +2 -13
  183. package/dist/builtin-extensions/pi-subagents/src/watchdog/tool-actions.d.ts.map +1 -1
  184. package/dist/builtin-extensions/pi-subagents/src/watchdog/tool-actions.js +5 -91
  185. package/dist/builtin-extensions/pi-subagents/src/watchdog/tool-actions.js.map +1 -1
  186. package/dist/builtin-extensions/pi-web-access/index.d.ts.map +1 -1
  187. package/dist/builtin-extensions/pi-web-access/index.js +103 -102
  188. package/dist/builtin-extensions/pi-web-access/index.js.map +1 -1
  189. package/dist/core/agent-session-services.d.ts.map +1 -1
  190. package/dist/core/agent-session-services.js +1 -1
  191. package/dist/core/agent-session-services.js.map +1 -1
  192. package/dist/core/computer-use/adapter.d.ts +23 -0
  193. package/dist/core/computer-use/adapter.d.ts.map +1 -0
  194. package/dist/core/computer-use/adapter.js +116 -0
  195. package/dist/core/computer-use/adapter.js.map +1 -0
  196. package/dist/core/computer-use/image.d.ts +26 -0
  197. package/dist/core/computer-use/image.d.ts.map +1 -0
  198. package/dist/core/computer-use/image.js +64 -0
  199. package/dist/core/computer-use/image.js.map +1 -0
  200. package/dist/core/computer-use/lease.d.ts +18 -0
  201. package/dist/core/computer-use/lease.d.ts.map +1 -0
  202. package/dist/core/computer-use/lease.js +129 -0
  203. package/dist/core/computer-use/lease.js.map +1 -0
  204. package/dist/core/computer-use/macos-runtime.d.ts +14 -0
  205. package/dist/core/computer-use/macos-runtime.d.ts.map +1 -0
  206. package/dist/core/computer-use/macos-runtime.js +148 -0
  207. package/dist/core/computer-use/macos-runtime.js.map +1 -0
  208. package/dist/core/computer-use/policy.d.ts +19 -0
  209. package/dist/core/computer-use/policy.d.ts.map +1 -0
  210. package/dist/core/computer-use/policy.js +62 -0
  211. package/dist/core/computer-use/policy.js.map +1 -0
  212. package/dist/core/computer-use/release.generated.d.ts +31 -0
  213. package/dist/core/computer-use/release.generated.d.ts.map +1 -0
  214. package/dist/core/computer-use/release.generated.js +36 -0
  215. package/dist/core/computer-use/release.generated.js.map +1 -0
  216. package/dist/core/computer-use/runtime.d.ts +13 -0
  217. package/dist/core/computer-use/runtime.d.ts.map +1 -0
  218. package/dist/core/computer-use/runtime.js +158 -0
  219. package/dist/core/computer-use/runtime.js.map +1 -0
  220. package/dist/core/computer-use/schemas.d.ts +91 -0
  221. package/dist/core/computer-use/schemas.d.ts.map +1 -0
  222. package/dist/core/computer-use/schemas.js +71 -0
  223. package/dist/core/computer-use/schemas.js.map +1 -0
  224. package/dist/core/computer-use/windows-desktop.d.ts +3 -0
  225. package/dist/core/computer-use/windows-desktop.d.ts.map +1 -0
  226. package/dist/core/computer-use/windows-desktop.js +48 -0
  227. package/dist/core/computer-use/windows-desktop.js.map +1 -0
  228. package/dist/core/computer-use/workflow.d.ts +32 -0
  229. package/dist/core/computer-use/workflow.d.ts.map +1 -0
  230. package/dist/core/computer-use/workflow.js +341 -0
  231. package/dist/core/computer-use/workflow.js.map +1 -0
  232. package/dist/core/customize.d.ts +2 -0
  233. package/dist/core/customize.d.ts.map +1 -1
  234. package/dist/core/customize.js +3 -0
  235. package/dist/core/customize.js.map +1 -1
  236. package/dist/core/keybindings.d.ts +2 -2
  237. package/dist/core/keybindings.d.ts.map +1 -1
  238. package/dist/core/keybindings.js +2 -2
  239. package/dist/core/keybindings.js.map +1 -1
  240. package/dist/core/model-runtime.d.ts +0 -3
  241. package/dist/core/model-runtime.d.ts.map +1 -1
  242. package/dist/core/model-runtime.js +1 -10
  243. package/dist/core/model-runtime.js.map +1 -1
  244. package/dist/core/package-manager.d.ts.map +1 -1
  245. package/dist/core/package-manager.js +1 -1
  246. package/dist/core/package-manager.js.map +1 -1
  247. package/dist/core/permissions.d.ts +2 -1
  248. package/dist/core/permissions.d.ts.map +1 -1
  249. package/dist/core/permissions.js +31 -11
  250. package/dist/core/permissions.js.map +1 -1
  251. package/dist/core/plan-mode.d.ts.map +1 -1
  252. package/dist/core/plan-mode.js +9 -5
  253. package/dist/core/plan-mode.js.map +1 -1
  254. package/dist/core/rollback.d.ts.map +1 -1
  255. package/dist/core/rollback.js +13 -90
  256. package/dist/core/rollback.js.map +1 -1
  257. package/dist/core/runtime-bridges.d.ts.map +1 -1
  258. package/dist/core/runtime-bridges.js +0 -2
  259. package/dist/core/runtime-bridges.js.map +1 -1
  260. package/dist/core/session-manager.d.ts +0 -1
  261. package/dist/core/session-manager.d.ts.map +1 -1
  262. package/dist/core/session-manager.js +21 -79
  263. package/dist/core/session-manager.js.map +1 -1
  264. package/dist/core/settings-manager.d.ts +10 -0
  265. package/dist/core/settings-manager.d.ts.map +1 -1
  266. package/dist/core/settings-manager.js +30 -0
  267. package/dist/core/settings-manager.js.map +1 -1
  268. package/dist/core/subagent-cancellation.d.ts +21 -0
  269. package/dist/core/subagent-cancellation.d.ts.map +1 -0
  270. package/dist/core/subagent-cancellation.js +53 -0
  271. package/dist/core/subagent-cancellation.js.map +1 -0
  272. package/dist/core/subagent-spinner-setting.d.ts +6 -0
  273. package/dist/core/subagent-spinner-setting.d.ts.map +1 -0
  274. package/dist/core/subagent-spinner-setting.js +12 -0
  275. package/dist/core/subagent-spinner-setting.js.map +1 -0
  276. package/dist/core/subagent-spinner.d.ts +4 -0
  277. package/dist/core/subagent-spinner.d.ts.map +1 -0
  278. package/dist/core/subagent-spinner.js +6 -0
  279. package/dist/core/subagent-spinner.js.map +1 -0
  280. package/dist/dev-cli.js +0 -0
  281. package/dist/gateway/agent-bridge.d.ts +6 -1
  282. package/dist/gateway/agent-bridge.d.ts.map +1 -1
  283. package/dist/gateway/agent-bridge.js +23 -6
  284. package/dist/gateway/agent-bridge.js.map +1 -1
  285. package/dist/gateway/cron.d.ts +1 -1
  286. package/dist/gateway/cron.d.ts.map +1 -1
  287. package/dist/gateway/cron.js +23 -7
  288. package/dist/gateway/cron.js.map +1 -1
  289. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  290. package/dist/modes/interactive/components/assistant-message.js +12 -18
  291. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  292. package/dist/modes/interactive/components/footer.d.ts +4 -2
  293. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  294. package/dist/modes/interactive/components/footer.js +23 -32
  295. package/dist/modes/interactive/components/footer.js.map +1 -1
  296. package/dist/modes/interactive/components/processes-selector.d.ts +2 -3
  297. package/dist/modes/interactive/components/processes-selector.d.ts.map +1 -1
  298. package/dist/modes/interactive/components/processes-selector.js +5 -10
  299. package/dist/modes/interactive/components/processes-selector.js.map +1 -1
  300. package/dist/modes/interactive/components/settings-selector.d.ts +8 -0
  301. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  302. package/dist/modes/interactive/components/settings-selector.js +93 -1
  303. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  304. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  305. package/dist/modes/interactive/components/tool-execution.js +12 -0
  306. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  307. package/dist/modes/interactive/extension-widget-order.d.ts +8 -0
  308. package/dist/modes/interactive/extension-widget-order.d.ts.map +1 -0
  309. package/dist/modes/interactive/extension-widget-order.js +37 -0
  310. package/dist/modes/interactive/extension-widget-order.js.map +1 -0
  311. package/dist/modes/interactive/interactive-mode.d.ts +1 -0
  312. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  313. package/dist/modes/interactive/interactive-mode.js +58 -26
  314. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  315. package/dist/modes/interactive/thinking-level-slash.d.ts +4 -0
  316. package/dist/modes/interactive/thinking-level-slash.d.ts.map +1 -0
  317. package/dist/modes/interactive/thinking-level-slash.js +23 -0
  318. package/dist/modes/interactive/thinking-level-slash.js.map +1 -0
  319. package/dist/node-runtime/adapter-AZMY335J.js +279 -0
  320. package/dist/node-runtime/{agent-session-services-IFJMSX7Z.js → agent-session-services-QANFGM2V.js} +15 -11
  321. package/dist/node-runtime/{builtin-extensions-LYZ3BFWQ.js → builtin-extensions-SRCYQPZ6.js} +5 -3
  322. package/dist/node-runtime/chunk-2IDTZAG5.js +1415 -0
  323. package/dist/node-runtime/chunk-3ONQTOMR.js +68 -0
  324. package/dist/node-runtime/{chunk-TQNSPERU.js → chunk-5SQDLSZJ.js} +1 -1
  325. package/dist/node-runtime/chunk-5ZH3ZFIZ.js +308 -0
  326. package/dist/node-runtime/{chunk-PBC2Y6GS.js → chunk-6UB6NKA3.js} +29 -72
  327. package/dist/node-runtime/{chunk-A2KQXUJD.js → chunk-7AFOFSDY.js} +1 -1
  328. package/dist/node-runtime/chunk-A3KMVBZV.js +60 -0
  329. package/dist/node-runtime/{chunk-N77MY65L.js → chunk-BJ6H7DPI.js} +25 -25
  330. package/dist/node-runtime/{chunk-PGAJ5MO5.js → chunk-BYQ2MOFI.js} +6 -6
  331. package/dist/node-runtime/{chunk-QH42CDX3.js → chunk-CZUBYPFP.js} +234 -124
  332. package/dist/node-runtime/{chunk-LZAW4ZX3.js → chunk-D466UAID.js} +34 -13
  333. package/dist/node-runtime/{chunk-ZKMFUD3Q.js → chunk-GT5F3OKM.js} +3 -3
  334. package/dist/node-runtime/chunk-H2BI7G7T.js +73 -0
  335. package/dist/node-runtime/{chunk-5P7PZMRU.js → chunk-HRS4HMDX.js} +1 -1
  336. package/dist/node-runtime/{chunk-IPA627GP.js → chunk-HXJS2PJM.js} +4 -4
  337. package/dist/node-runtime/chunk-JZHEUQRL.js +180 -0
  338. package/dist/node-runtime/chunk-LISUTZS3.js +19 -0
  339. package/dist/node-runtime/chunk-LOYUC2ID.js +2185 -0
  340. package/dist/node-runtime/{chunk-2QKLKMKC.js → chunk-LTXUQJI4.js} +1 -1
  341. package/dist/node-runtime/{chunk-YF63P5ZT.js → chunk-LTYWTR3V.js} +1 -426
  342. package/dist/node-runtime/{chunk-MKKH27PH.js → chunk-LWJXTA6Z.js} +274 -2416
  343. package/dist/node-runtime/chunk-MW2XJZIK.js +108 -0
  344. package/dist/node-runtime/{chunk-CDFZEWPU.js → chunk-N3PNL74S.js} +537 -262
  345. package/dist/node-runtime/{chunk-4TLO4PO2.js → chunk-U6C7VTR5.js} +7 -1401
  346. package/dist/node-runtime/chunk-URD2SLIT.js +1019 -0
  347. package/dist/node-runtime/{chunk-HQCKFM2O.js → chunk-VGYZ3APQ.js} +3 -0
  348. package/dist/node-runtime/{chunk-AJX357CL.js → chunk-VQ4UBWSA.js} +30 -1013
  349. package/dist/node-runtime/{chunk-F4VQFJI2.js → chunk-VTGEKB7R.js} +2 -2
  350. package/dist/node-runtime/{chunk-AD6VXAO7.js → chunk-VTPM5V35.js} +5 -100
  351. package/dist/node-runtime/chunk-W3SILANP.js +24 -0
  352. package/dist/node-runtime/{chunk-WOVTOV5P.js → chunk-XAUQOKYK.js} +421 -63
  353. package/dist/node-runtime/{chunk-ECD5L7YI.js → chunk-XSRCAQK2.js} +390 -16
  354. package/dist/node-runtime/{chunk-PCGNAY2O.js → chunk-ZOIIMEN6.js} +54 -433
  355. package/dist/node-runtime/{chunk-EDBJNRSM.js → chunk-ZVSORYRM.js} +1 -1
  356. package/dist/node-runtime/cli-runtime.js +1 -1
  357. package/dist/node-runtime/{command-L3LAHDIH.js → command-ZURZJDXF.js} +1 -1
  358. package/dist/node-runtime/{commands-RL5YBW5I.js → commands-BZGSLIP7.js} +4 -2
  359. package/dist/node-runtime/{customize-XEXL2DGQ.js → customize-LF5VST47.js} +1 -1
  360. package/dist/node-runtime/{direct-tool-executor-JVDXTO7A.js → direct-tool-executor-BSZDHIYR.js} +7 -4
  361. package/dist/node-runtime/{export-html-KR26FOUZ.js → export-html-E4DT6ZJQ.js} +1 -1
  362. package/dist/node-runtime/{gateway-X2TI5X7F.js → gateway-FWHRIBK5.js} +24 -369
  363. package/dist/node-runtime/index.js +49 -42
  364. package/dist/node-runtime/{init-NJV2T55N.js → init-DVJUAOUO.js} +4 -2
  365. package/dist/node-runtime/{interactive-mode-KOM35YF2.js → interactive-mode-BBASNWHN.js} +23 -17
  366. package/dist/node-runtime/{interactive-view-U6OILKF3.js → interactive-view-N6F4KUIT.js} +3 -5
  367. package/dist/node-runtime/lunr-computer-use-TJNDAMWM.js +135 -0
  368. package/dist/node-runtime/{lunr-cron-YJ5UHYRD.js → lunr-cron-J64I72C6.js} +7 -1
  369. package/dist/node-runtime/main.js +25 -20
  370. package/dist/node-runtime/{mcp-auth-flow-QIXHW6QN.js → mcp-auth-flow-YL6RWPYG.js} +2 -1
  371. package/dist/node-runtime/{package-manager-cli-TZZHJCVI.js → package-manager-cli-VMYX4Y2S.js} +10 -7
  372. package/dist/node-runtime/{pi-intercom-EEMBGQID.js → pi-intercom-NV2LW6X7.js} +108 -87
  373. package/dist/node-runtime/{pi-mcp-adapter-QFB37AVN.js → pi-mcp-adapter-JLB5YL2F.js} +31 -25
  374. package/dist/node-runtime/{pi-subagents-7XJ4H53P.js → pi-subagents-WEHV3W7H.js} +1321 -631
  375. package/dist/node-runtime/{pi-web-access-DPGAVKOA.js → pi-web-access-FN5YC5T6.js} +67 -64
  376. package/dist/node-runtime/{proxy-modes-HEEFK4KC.js → proxy-modes-OR7ISBXK.js} +7 -4
  377. package/dist/node-runtime/rpc-entry.js +25 -20
  378. package/dist/node-runtime/runtime-3SB5ATHQ.js +21 -0
  379. package/dist/node-runtime/{runtime-bridges-PPHNBFWL.js → runtime-bridges-2VQTLPOZ.js} +3 -5
  380. package/dist/node-runtime/{session-manager-MQNBYACL.js → session-manager-QEMZBMTM.js} +3 -5
  381. package/dist/node-runtime/{session-selector-5AZLJS6U.js → session-selector-URVJLOTK.js} +2 -2
  382. package/dist/node-runtime/{settings-manager-5LF2VQWC.js → settings-manager-3CCU326G.js} +4 -1
  383. package/dist/node-runtime/{src-Y7JSCK64.js → src-BPQFJR76.js} +27 -7
  384. package/dist/node-runtime/{subagent-executor-5RNDEPIJ.js → subagent-executor-CXKXQDHH.js} +189 -284
  385. package/dist/node-runtime/{update-cli-A253SZ7P.js → update-cli-NM7B4CKL.js} +4 -1
  386. package/dist/node-runtime/workflow-C26QCUTW.js +468 -0
  387. package/dist/rpc.d.ts +3 -0
  388. package/dist/rpc.d.ts.map +1 -0
  389. package/dist/rpc.js +18 -0
  390. package/dist/rpc.js.map +1 -0
  391. package/dist/startup/interactive-view.d.ts.map +1 -1
  392. package/dist/startup/interactive-view.js +1 -2
  393. package/dist/startup/interactive-view.js.map +1 -1
  394. package/docs/computer-use.md +242 -0
  395. package/docs/development.md +0 -32
  396. package/docs/features.md +24 -6
  397. package/docs/interactive-startup.md +10 -3
  398. package/docs/keybindings.md +5 -3
  399. package/docs/settings.md +3 -2
  400. package/docs/terminal-setup.md +1 -1
  401. package/docs/usage.md +1 -1
  402. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  403. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  404. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  405. package/examples/extensions/gondolin/package-lock.json +2 -2
  406. package/examples/extensions/gondolin/package.json +1 -1
  407. package/examples/extensions/hidden-thinking-label.ts +1 -1
  408. package/examples/extensions/sandbox/package-lock.json +2 -2
  409. package/examples/extensions/sandbox/package.json +1 -1
  410. package/examples/extensions/with-deps/package-lock.json +2 -2
  411. package/examples/extensions/with-deps/package.json +1 -1
  412. package/install-lock/package-lock.json +3827 -0
  413. package/install-lock/package.json +18 -0
  414. package/native/computer-use/LICENSE.md +21 -0
  415. package/npm-shrinkwrap.json +3808 -0
  416. package/package.json +16 -10
  417. package/dist/builtin-extensions/lunr-settings-tools.d.ts +0 -4
  418. package/dist/builtin-extensions/lunr-settings-tools.d.ts.map +0 -1
  419. package/dist/builtin-extensions/lunr-settings-tools.js +0 -120
  420. package/dist/builtin-extensions/lunr-settings-tools.js.map +0 -1
  421. package/dist/core/settings-tools-bridge.d.ts +0 -35
  422. package/dist/core/settings-tools-bridge.d.ts.map +0 -1
  423. package/dist/core/settings-tools-bridge.js +0 -56
  424. package/dist/core/settings-tools-bridge.js.map +0 -1
  425. package/dist/node-runtime/chunk-AHSTJBIB.js +0 -64
  426. package/dist/startup/interactive-shell.d.ts +0 -55
  427. package/dist/startup/interactive-shell.d.ts.map +0 -1
  428. package/dist/startup/interactive-shell.js +0 -264
  429. package/dist/startup/interactive-shell.js.map +0 -1
  430. package/dist/node-runtime/{chunk-YSKSB3BJ.js → chunk-CH6OL6P2.js} +2 -2
@@ -2,11 +2,12 @@
2
2
  /**
3
3
  * Rendering functions for subagent results
4
4
  */
5
+ import { getSubagentSpinnerDefinition } from "../../../../core/subagent-spinner.js";
5
6
  import { getMarkdownTheme } from "../../../../modes/interactive/theme/theme.js";
6
7
  import { keyText } from "../../../../modes/interactive/components/keybinding-hints.js";
7
8
  import { Container, Markdown, Spacer, Text, visibleWidth } from "@ashx-j/lunr-tui";
8
- import { MAX_WIDGET_JOBS, WIDGET_KEY, } from "../shared/types.js";
9
- import { formatTokens, formatUsage, formatDuration, formatModelSelection, formatToolCall, shortenPath } from "../shared/formatters.js";
9
+ import { WIDGET_KEY, } from "../shared/types.js";
10
+ import { formatTokens, formatUsage, formatDuration, formatModelSelection, formatCompactModelBadge, formatToolCall, shortenPath } from "../shared/formatters.js";
10
11
  import { sanitizeChildDescription } from "../shared/child-spec.js";
11
12
  import { getDisplayItems, getSingleResultOutput } from "../shared/utils.js";
12
13
  import { flatToLogicalStepIndex } from "../runs/background/parallel-groups.js";
@@ -98,8 +99,12 @@ function wrapPlainText(text, maxWidth) {
98
99
  }
99
100
  return lines;
100
101
  }
101
- const RUNNING_FRAMES = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
102
102
  const STATIC_RUNNING_GLYPH = "●";
103
+ export const SUBAGENT_PAINT_INTERVAL_MS = 80;
104
+ function selectedSubagentSpinner() {
105
+ const bridge = globalThis[Symbol.for("@lunr/customize")];
106
+ return getSubagentSpinnerDefinition(bridge?.getSubagentSpinner?.() ?? "braille");
107
+ }
103
108
  function runningSeed(...values) {
104
109
  let seed;
105
110
  for (const value of values) {
@@ -112,7 +117,12 @@ function runningSeed(...values) {
112
117
  function runningGlyph(seed) {
113
118
  if (seed === undefined)
114
119
  return STATIC_RUNNING_GLYPH;
115
- return RUNNING_FRAMES[Math.abs(seed) % RUNNING_FRAMES.length];
120
+ const frames = selectedSubagentSpinner().frames;
121
+ return frames[Math.abs(seed) % frames.length];
122
+ }
123
+ function foregroundSpinnerFrame(timerFrame) {
124
+ const { interval } = selectedSubagentSpinner();
125
+ return Math.floor((Math.max(0, timerFrame) * SUBAGENT_PAINT_INTERVAL_MS) / interval);
116
126
  }
117
127
  function progressRunningSeed(progress) {
118
128
  if (!progress)
@@ -202,6 +212,20 @@ function statJoin(theme, parts) {
202
212
  function formatTokenStat(tokens) {
203
213
  return `${formatTokens(tokens)} token`;
204
214
  }
215
+ function usageTokenTotal(usage) {
216
+ if (!usage)
217
+ return 0;
218
+ return (usage.input ?? 0) + (usage.output ?? 0) + (usage.cacheRead ?? 0) + (usage.cacheWrite ?? 0);
219
+ }
220
+ function compactResultTokens(result) {
221
+ const progress = result.progress || result.progressSummary;
222
+ if (progress && progress.tokens > 0)
223
+ return progress.tokens;
224
+ const fromUsage = usageTokenTotal(result.usage);
225
+ if (fromUsage > 0)
226
+ return fromUsage;
227
+ return progress?.tokens ?? 0;
228
+ }
205
229
  function formatToolUseStat(count) {
206
230
  return `${count} tool use${count === 1 ? "" : "s"}`;
207
231
  }
@@ -220,9 +244,10 @@ function formatTotalCostStat(totalCost) {
220
244
  function liveDurationMs(progress, running, now) {
221
245
  if (!progress)
222
246
  return 0;
247
+ const durationMs = progress.durationMs ?? 0;
223
248
  if (!running || progress.lastActivityAt === undefined)
224
- return progress.durationMs;
225
- return progress.durationMs + Math.max(0, now - progress.lastActivityAt);
249
+ return durationMs;
250
+ return durationMs + Math.max(0, now - progress.lastActivityAt);
226
251
  }
227
252
  function formatProgressStats(theme, progress, includeDuration = true, options = {}) {
228
253
  if (!progress)
@@ -299,17 +324,19 @@ function resultGlyph(result, output, theme, running = result.progress?.status ==
299
324
  return theme.fg("warning", "✓");
300
325
  return theme.fg("success", "✓");
301
326
  }
302
- /** Compact hang row: tool count, tokens, elapsed time. */
303
- export function formatCompactStatsHangLine(progress, width, paint = (s) => s, prefix = " ⎿ ", now = Date.now(), running = false) {
304
- const toolCount = progress?.toolCount ?? 0;
305
- const tokens = progress?.tokens ?? 0;
306
- const durationMs = liveDurationMs(progress, running, now);
327
+ function formatCompactRowStats(tokens, durationMs) {
328
+ return `${formatTokenStat(tokens)} · ${durationMs > 0 ? formatDuration(durationMs) : "0ms"}`;
329
+ }
330
+ /** Unified compact row: glyph description · tier|model · tokens · time. */
331
+ export function formatCompactSubagentRow(theme, width, parts) {
332
+ const stats = formatCompactRowStats(parts.tokens, parts.durationMs);
307
333
  const body = [
308
- formatToolUseStat(toolCount),
309
- formatTokenStat(tokens),
310
- durationMs > 0 ? formatDuration(durationMs) : "0ms",
311
- ].join(" · ");
312
- return truncLine(paint(`${prefix}${body}`), width);
334
+ `${parts.prefix ?? ""}${parts.glyph} ${themeBold(theme, parts.description)}`,
335
+ parts.modelBadge ? theme.fg("dim", parts.modelBadge) : "",
336
+ theme.fg("dim", stats),
337
+ parts.terminalStatus ? theme.fg("dim", parts.terminalStatus) : "",
338
+ ].filter(Boolean).join(` ${theme.fg("dim", "·")} `);
339
+ return truncLine(body, width);
313
340
  }
314
341
  export function widgetRenderKey(job) {
315
342
  return JSON.stringify({
@@ -401,15 +428,13 @@ function widgetStepsRunningSeed(steps) {
401
428
  function widgetJobRunningSeed(job) {
402
429
  return runningSeed(job.currentStep, job.runningSteps, widgetStepsRunningSeed(job.steps));
403
430
  }
404
- function widgetJobsRunningSeed(jobs) {
405
- let seed;
406
- for (const job of jobs)
407
- seed = runningSeed(seed, widgetJobRunningSeed(job));
408
- return seed;
431
+ function widgetAnimFrame(now = Date.now()) {
432
+ const definition = selectedSubagentSpinner();
433
+ return Math.floor(now / definition.interval) % definition.frames.length;
409
434
  }
410
- function widgetStatusGlyph(job, theme) {
435
+ function widgetStatusGlyph(job, theme, now = Date.now()) {
411
436
  if (job.status === "running")
412
- return theme.fg("accent", runningGlyph(widgetJobRunningSeed(job)));
437
+ return theme.fg("accent", runningGlyph((widgetJobRunningSeed(job) ?? 0) + widgetAnimFrame(now)));
413
438
  if (job.status === "queued")
414
439
  return theme.fg("muted", "◦");
415
440
  if (job.status === "complete")
@@ -586,7 +611,11 @@ function isDoneResult(result) {
586
611
  return result.exitCode === 0;
587
612
  }
588
613
  function workflowGraphHasStatus(details, statuses) {
589
- return details.workflowGraph?.nodes.some((node) => statuses.includes(node.status)) ?? false;
614
+ const matches = (nodes) => nodes.some((node) => statuses.includes(node.status) || matches(node.children ?? []));
615
+ return matches(details.workflowGraph?.nodes ?? []);
616
+ }
617
+ function resultAtFlatIndex(details, flatIndex) {
618
+ return details.results.find((result, arrayIndex) => (result.progress?.index ?? result.progressSummary?.index ?? arrayIndex) === flatIndex);
590
619
  }
591
620
  function buildChainRenderEntries(details, label) {
592
621
  if (details.mode !== "chain" || !label.hasParallelInChain || label.showActiveGroupOnly)
@@ -605,11 +634,20 @@ function buildChainRenderEntries(details, label) {
605
634
  continue;
606
635
  }
607
636
  for (let index = span.start; index < span.start + span.count; index++) {
637
+ const workflowStep = details.workflowGraph?.nodes.find((node) => node.stepIndex === span.stepIndex);
638
+ const workflowNode = workflowStep?.children?.find((node) => node.flatIndex === index)
639
+ ?? (workflowStep?.flatIndex === index ? workflowStep : undefined);
640
+ const result = resultAtFlatIndex(details, index);
608
641
  entries.push({
609
642
  kind: "result",
610
643
  resultIndex: index,
611
644
  rowNumber: index + 1,
612
- agentName: details.results[index]?.agent ?? details.chainAgents?.[span.stepIndex] ?? `step-${span.stepIndex + 1}`,
645
+ agentName: result?.agent
646
+ ?? workflowNode?.label
647
+ ?? details.chainAgents?.[span.stepIndex]
648
+ ?? `step-${span.stepIndex + 1}`,
649
+ status: workflowNode?.status ?? span.status,
650
+ error: workflowNode?.error ?? span.error,
613
651
  });
614
652
  }
615
653
  }
@@ -950,37 +988,54 @@ function foregroundStyleWidgetDetails(job, theme, expanded, width) {
950
988
  }
951
989
  return lines;
952
990
  }
953
- function buildSingleWidgetLines(job, theme, width, expanded) {
954
- const stats = widgetStats(job, theme);
955
- const count = job.mode === "chain" ? job.chainStepCount : job.stepsTotal ?? job.agents?.length ?? job.steps?.length;
956
- const mode = widgetJobName(job);
957
- const title = `async subagent ${mode}${count && count > 1 ? ` (${count})` : ""}`;
958
- return [
959
- `${theme.fg("toolTitle", themeBold(theme, title))} ${theme.fg("dim", "· background")}`,
960
- `${widgetStatusGlyph(job, theme)} ${themeBold(theme, mode)}${stats ? ` ${theme.fg("dim", "·")} ${stats}` : ""}`,
961
- ...foregroundStyleWidgetDetails(job, theme, expanded, width),
962
- ].map((line) => truncLine(line, width));
963
- }
964
- function compactSingleWidgetLines(job, theme, width) {
965
- const fullLines = buildSingleWidgetLines(job, theme, width, false);
966
- if (fullLines.length <= 10 || !job.steps?.length || (job.mode !== "parallel" && !job.activeParallelGroup))
967
- return fullLines;
968
- const total = job.stepsTotal ?? job.steps.length;
969
- const itemTitle = job.mode === "parallel" || job.activeParallelGroup ? "Agent" : "Step";
970
- const lines = fullLines.slice(0, 2);
971
- for (const [index, step] of job.steps.entries()) {
972
- const status = widgetStepStatus(step.status, theme);
973
- const activity = widgetStepActivityLine(step, width, false, job.updatedAt);
974
- const stepStats = widgetStepStats(theme, step);
975
- const activitySuffix = activity ? ` ${theme.fg("dim", "·")} ${theme.fg("dim", activity)}` : "";
976
- const modelDisplay = modelThinkingBadge(theme, step.model, step.thinking, step.modelSelection);
977
- lines.push(` ${widgetStepGlyph(step.status, theme, widgetStepRunningSeed(step, index))} ${itemTitle} ${index + 1}/${total}: ${themeBold(theme, step.agent)} ${theme.fg("dim", "·")} ${status}${modelDisplay}${activitySuffix}${stepStats ? ` ${theme.fg("dim", "·")} ${stepStats}` : ""}`);
978
- for (const nestedLine of formatNestedWidgetLines(step.children, theme, width, false, job.updatedAt))
979
- lines.push(` ${nestedLine}`);
991
+ function compactTerminalStatus(status) {
992
+ if (status === "failed")
993
+ return "failed";
994
+ if (status === "paused")
995
+ return "paused";
996
+ if (status === "stopped")
997
+ return "stopped";
998
+ if (status === "detached")
999
+ return "detached";
1000
+ return undefined;
1001
+ }
1002
+ function compactJobProgress(job, step, now = Date.now()) {
1003
+ const running = (step?.status ?? job.status) === "running";
1004
+ const tokens = step?.tokens?.total ?? job.totalTokens?.total ?? 0;
1005
+ if (step?.durationMs !== undefined) {
1006
+ return {
1007
+ tokens,
1008
+ durationMs: liveDurationMs({ durationMs: step.durationMs, lastActivityAt: step.lastActivityAt }, running, now),
1009
+ };
980
1010
  }
981
- if (job.steps.some((step) => step.status === "running"))
982
- lines.push(theme.fg("accent", ` ${liveDetailHintText()}`));
983
- return lines.map((line) => truncLine(line, width));
1011
+ const startedAt = step?.startedAt ?? job.startedAt;
1012
+ if (startedAt === undefined)
1013
+ return { tokens, durationMs: 0 };
1014
+ const endedAt = running ? now : step?.endedAt ?? step?.lastActivityAt ?? job.updatedAt ?? now;
1015
+ return { tokens, durationMs: Math.max(0, endedAt - startedAt) };
1016
+ }
1017
+ function compactJobLead(job, step) {
1018
+ return compactRowLead({
1019
+ description: step?.description ?? step?.agent ?? job.agents?.[0],
1020
+ task: step?.description ?? step?.agent,
1021
+ }) || widgetJobName(job);
1022
+ }
1023
+ function compactJobLines(job, step, theme, width, now = Date.now()) {
1024
+ const running = (step?.status ?? job.status) === "running";
1025
+ const lead = compactJobLead(job, step);
1026
+ const modelBadge = formatCompactModelBadge(step?.modelSelection, step?.model);
1027
+ const glyph = step
1028
+ ? widgetStepGlyph(step.status, theme, running ? (widgetStepRunningSeed(step, step.index) ?? 0) + widgetAnimFrame(now) : widgetStepRunningSeed(step, step.index))
1029
+ : widgetStatusGlyph(job, theme, now);
1030
+ const progress = compactJobProgress(job, step, now);
1031
+ return [formatCompactSubagentRow(theme, width, {
1032
+ glyph,
1033
+ description: lead,
1034
+ modelBadge,
1035
+ tokens: progress.tokens,
1036
+ durationMs: progress.durationMs,
1037
+ terminalStatus: compactTerminalStatus(step?.status ?? job.status),
1038
+ })];
984
1039
  }
985
1040
  const RESERVED_NON_WIDGET_ROWS = 19;
986
1041
  let widgetLayoutSession;
@@ -1002,35 +1057,6 @@ function widgetSessionMatches(expanded) {
1002
1057
  && widgetLayoutSession.rows === currentTerminalRows()
1003
1058
  && widgetLayoutSession.columns === currentTerminalColumns();
1004
1059
  }
1005
- function widgetHeaderCounts(jobs) {
1006
- return {
1007
- running: jobs.filter((job) => job.status === "running"),
1008
- queued: jobs.filter((job) => job.status === "queued"),
1009
- complete: jobs.filter((job) => job.status === "complete"),
1010
- failed: jobs.filter((job) => job.status === "failed"),
1011
- paused: jobs.filter((job) => job.status === "paused"),
1012
- stopped: jobs.filter((job) => job.status === "stopped"),
1013
- };
1014
- }
1015
- function buildSingleLineWidgetLines(jobs, theme, width) {
1016
- const counts = widgetHeaderCounts(jobs);
1017
- const hasActive = counts.running.length > 0 || counts.queued.length > 0;
1018
- const glyph = counts.running.length > 0 ? runningGlyph(widgetJobsRunningSeed(counts.running)) : hasActive ? "●" : "○";
1019
- const parts = [];
1020
- if (counts.running.length > 0)
1021
- parts.push(`${counts.running.length}/${jobs.length} running`);
1022
- if (counts.queued.length > 0)
1023
- parts.push(`${counts.queued.length} queued`);
1024
- if (counts.failed.length > 0)
1025
- parts.push(`${counts.failed.length} failed`);
1026
- if (counts.stopped.length > 0)
1027
- parts.push(`${counts.stopped.length} stopped`);
1028
- if (counts.paused.length > 0)
1029
- parts.push(`${counts.paused.length} paused`);
1030
- if (!hasActive && counts.complete.length > 0)
1031
- parts.push(`${counts.complete.length}/${jobs.length} done`);
1032
- return [truncLine(`${theme.fg(hasActive ? "accent" : "dim", glyph)} ${theme.fg(hasActive ? "accent" : "dim", "subagents")} (${parts.join(", ") || `${jobs.length} total`})`, width)];
1033
- }
1034
1060
  function orderedWidgetJobs(jobs) {
1035
1061
  return [
1036
1062
  ...jobs.filter((job) => job.status === "running"),
@@ -1038,124 +1064,6 @@ function orderedWidgetJobs(jobs) {
1038
1064
  ...jobs.filter((job) => job.status !== "running" && job.status !== "queued"),
1039
1065
  ];
1040
1066
  }
1041
- function progressiveJobKey(job) {
1042
- return job.asyncId;
1043
- }
1044
- function isProgressiveActiveJob(job) {
1045
- return job?.status === "running" || job?.status === "queued";
1046
- }
1047
- function selectProgressiveJobKeys(jobs, previousKeys, bodyRows) {
1048
- if (bodyRows <= 0)
1049
- return [];
1050
- const jobsByKey = new Map(jobs.map((job) => [progressiveJobKey(job), job]));
1051
- const selected = [];
1052
- const append = (key) => {
1053
- if (selected.includes(key) || !jobsByKey.has(key))
1054
- return;
1055
- selected.push(key);
1056
- };
1057
- for (const key of previousKeys) {
1058
- if (!isProgressiveActiveJob(jobsByKey.get(key)))
1059
- continue;
1060
- append(key);
1061
- if (selected.length >= bodyRows)
1062
- return selected;
1063
- }
1064
- for (const job of orderedWidgetJobs(jobs)) {
1065
- if (!isProgressiveActiveJob(job))
1066
- continue;
1067
- const key = progressiveJobKey(job);
1068
- append(key);
1069
- if (selected.length >= bodyRows)
1070
- break;
1071
- }
1072
- if (selected.length >= bodyRows)
1073
- return selected;
1074
- for (const key of previousKeys) {
1075
- if (isProgressiveActiveJob(jobsByKey.get(key)))
1076
- continue;
1077
- append(key);
1078
- if (selected.length >= bodyRows)
1079
- return selected;
1080
- }
1081
- for (const job of orderedWidgetJobs(jobs)) {
1082
- const key = progressiveJobKey(job);
1083
- append(key);
1084
- if (selected.length >= bodyRows)
1085
- break;
1086
- }
1087
- return selected;
1088
- }
1089
- function progressiveHeaderLine(jobs, theme, width) {
1090
- const counts = widgetHeaderCounts(jobs);
1091
- const hasActive = counts.running.length > 0 || counts.queued.length > 0;
1092
- const glyph = counts.running.length > 0 ? runningGlyph(widgetJobsRunningSeed(counts.running)) : hasActive ? "●" : "○";
1093
- const parts = [];
1094
- if (counts.running.length > 0)
1095
- parts.push(formatAgentRunningLabel(counts.running.length));
1096
- if (counts.queued.length > 0)
1097
- parts.push(`${counts.queued.length} queued`);
1098
- if (!hasActive) {
1099
- if (counts.failed.length > 0)
1100
- parts.push(`${counts.failed.length} failed`);
1101
- if (counts.stopped.length > 0)
1102
- parts.push(`${counts.stopped.length} stopped`);
1103
- if (counts.paused.length > 0)
1104
- parts.push(`${counts.paused.length} paused`);
1105
- if (counts.complete.length > 0)
1106
- parts.push(`${counts.complete.length}/${jobs.length} done`);
1107
- }
1108
- return truncLine(`${theme.fg(hasActive ? "accent" : "dim", glyph)} ${theme.fg(hasActive ? "accent" : "dim", "Async agents")} ${theme.fg("dim", "·")} ${theme.fg("dim", parts.join(", ") || `${jobs.length} total`)}`, width);
1109
- }
1110
- function progressiveJobLine(job, theme, width) {
1111
- const stats = widgetStats(job, theme);
1112
- const activity = widgetActivity(job);
1113
- const status = job.status === "complete" ? "done" : job.status;
1114
- const parts = [
1115
- themeBold(theme, widgetJobName(job)),
1116
- theme.fg("dim", status),
1117
- stats,
1118
- activity && activity.toLowerCase() !== status ? theme.fg("dim", activity) : "",
1119
- ].filter(Boolean);
1120
- return truncLine(` ${widgetStatusGlyph(job, theme)} ${parts.join(` ${theme.fg("dim", "·")} `)}`, width);
1121
- }
1122
- function progressiveHiddenLine(hiddenJobs, theme, width) {
1123
- const counts = widgetHeaderCounts(hiddenJobs);
1124
- const parts = [];
1125
- if (counts.running.length > 0)
1126
- parts.push(`${counts.running.length} running`);
1127
- if (counts.queued.length > 0)
1128
- parts.push(`${counts.queued.length} queued`);
1129
- const finished = counts.complete.length + counts.failed.length + counts.paused.length + counts.stopped.length;
1130
- if (finished > 0)
1131
- parts.push(`${finished} finished`);
1132
- return truncLine(theme.fg("dim", ` +${hiddenJobs.length} more${parts.length ? ` (${parts.join(", ")})` : ""}`), width);
1133
- }
1134
- function buildProgressiveWidgetLines(jobs, theme, width, lockedRows, previousKeys) {
1135
- const rowCount = Math.max(1, lockedRows);
1136
- if (rowCount === 1)
1137
- return { lines: buildSingleLineWidgetLines(jobs, theme, width), visibleJobKeys: [] };
1138
- const bodyRows = rowCount - 1;
1139
- let visibleJobKeys = selectProgressiveJobKeys(jobs, previousKeys, bodyRows);
1140
- const jobsByKey = new Map(jobs.map((job) => [progressiveJobKey(job), job]));
1141
- let visibleJobs = visibleJobKeys.map((key) => jobsByKey.get(key)).filter((job) => Boolean(job));
1142
- let hiddenJobs = jobs.filter((job) => !visibleJobKeys.includes(progressiveJobKey(job)));
1143
- const needsHiddenLine = hiddenJobs.length > 0;
1144
- if (needsHiddenLine && visibleJobs.length >= bodyRows && bodyRows > 0) {
1145
- visibleJobs = visibleJobs.slice(0, bodyRows - 1);
1146
- visibleJobKeys = visibleJobs.map(progressiveJobKey);
1147
- hiddenJobs = jobs.filter((job) => !visibleJobKeys.includes(progressiveJobKey(job)));
1148
- }
1149
- const lines = [
1150
- progressiveHeaderLine(jobs, theme, width),
1151
- ...visibleJobs.map((job) => progressiveJobLine(job, theme, width)),
1152
- ];
1153
- if (hiddenJobs.length > 0 && lines.length < rowCount)
1154
- lines.push(progressiveHiddenLine(hiddenJobs, theme, width));
1155
- while (lines.length < rowCount)
1156
- lines.push(" ");
1157
- return { lines: lines.slice(0, rowCount), visibleJobKeys };
1158
- }
1159
1067
  function collapsedWidgetLineBudget(rows) {
1160
1068
  return Math.max(10, Math.min(14, Math.floor(rows * 0.35)));
1161
1069
  }
@@ -1173,121 +1081,178 @@ function fitWidgetLineBudget(lines, theme, width, expanded) {
1173
1081
  : `… ${hiddenCount} lines hidden · ${liveDetailKeyText()} expands`;
1174
1082
  return [...lines.slice(0, visibleLines), truncLine(theme.fg("dim", hint), width)];
1175
1083
  }
1176
- function fitAdaptiveWidgetLines(jobs, lines, theme, width, expanded) {
1084
+ function fitAdaptiveWidgetLines(_jobs, lines, theme, width, expanded) {
1177
1085
  if (expanded) {
1178
1086
  resetWidgetLayoutSession();
1179
1087
  return fitWidgetLineBudget(lines, theme, width, true);
1180
1088
  }
1181
- const hasMatchingSession = widgetSessionMatches(expanded);
1182
1089
  const rows = currentTerminalRows();
1183
1090
  const columns = currentTerminalColumns();
1184
1091
  const availableRows = estimateAvailableWidgetRows();
1185
- if (hasMatchingSession && widgetLayoutSession?.tier === "single-line") {
1186
- return buildSingleLineWidgetLines(jobs, theme, width);
1187
- }
1188
- if (hasMatchingSession && widgetLayoutSession?.tier === "progressive" && widgetLayoutSession.lockedRows !== undefined) {
1189
- const rendered = buildProgressiveWidgetLines(jobs, theme, width, widgetLayoutSession.lockedRows, widgetLayoutSession.visibleJobKeys);
1190
- widgetLayoutSession.visibleJobKeys = rendered.visibleJobKeys;
1191
- return rendered.lines;
1192
- }
1193
1092
  if (lines.length <= availableRows) {
1194
- widgetLayoutSession = { expanded, rows, columns, tier: "full", visibleJobKeys: [] };
1093
+ widgetLayoutSession = { expanded, rows, columns, tier: "full" };
1195
1094
  return fitWidgetLineBudget(lines, theme, width, false);
1196
1095
  }
1197
- if (availableRows <= 2) {
1198
- widgetLayoutSession = { expanded, rows, columns, tier: "single-line", visibleJobKeys: [] };
1199
- return buildSingleLineWidgetLines(jobs, theme, width);
1096
+ const lockedRows = widgetSessionMatches(expanded) && widgetLayoutSession?.tier === "progressive"
1097
+ ? widgetLayoutSession.lockedRows ?? 1
1098
+ : Math.max(1, Math.min(availableRows, collapsedWidgetLineBudget(rows)));
1099
+ widgetLayoutSession = { expanded, rows, columns, tier: "progressive", lockedRows };
1100
+ if (lockedRows === 1)
1101
+ return lines.slice(0, 1);
1102
+ const visibleCount = Math.max(1, lockedRows - 1);
1103
+ const visible = lines.slice(0, visibleCount);
1104
+ const hidden = lines.length - visible.length;
1105
+ if (hidden > 0)
1106
+ visible.push(truncLine(theme.fg("dim", `+${hidden} more`), width));
1107
+ while (visible.length < lockedRows)
1108
+ visible.push(" ");
1109
+ return visible.slice(0, lockedRows);
1110
+ }
1111
+ function widgetExpandedDiagnostics(job, step, index, theme, width, now) {
1112
+ const lines = [];
1113
+ const status = step?.status ?? job.status;
1114
+ const runLabel = step ? `${job.asyncId}:${step.index ?? index}` : job.asyncId;
1115
+ lines.push(truncLine(theme.fg("dim", ` ⎿ run ${runLabel} · ${status}`), width));
1116
+ const error = step?.error;
1117
+ if (error)
1118
+ lines.push(truncLine(theme.fg("error", ` ${error}`), width));
1119
+ const snapshotNow = status === "running" ? now : step?.endedAt ?? job.updatedAt;
1120
+ const activity = step
1121
+ ? widgetStepActivityLine(step, Math.max(1, width - 4), true, snapshotNow)
1122
+ : widgetActivity(job, now);
1123
+ if (activity)
1124
+ lines.push(truncLine(theme.fg("dim", ` ${activity}`), width));
1125
+ for (const tool of step?.recentTools?.slice(-3) ?? []) {
1126
+ lines.push(truncLine(theme.fg("dim", ` ${tool.tool}${tool.args ? `: ${tool.args}` : ""}`), width));
1200
1127
  }
1201
- const lockedRows = Math.min(availableRows, collapsedWidgetLineBudget(rows));
1202
- const rendered = buildProgressiveWidgetLines(jobs, theme, width, lockedRows, []);
1203
- widgetLayoutSession = { expanded, rows, columns, tier: "progressive", lockedRows, visibleJobKeys: rendered.visibleJobKeys };
1204
- return rendered.lines;
1205
- }
1206
- function buildWidgetComponent(jobs, expanded) {
1207
- return (_tui, theme) => {
1208
- const width = getTermWidth();
1209
- const lines = expanded
1210
- ? buildWidgetLines(jobs, theme, width, true)
1211
- : jobs.length === 1
1212
- ? compactSingleWidgetLines(jobs[0], theme, width)
1213
- : buildWidgetLines(jobs, theme, width, false);
1214
- const container = new Container();
1215
- for (const line of fitAdaptiveWidgetLines(jobs, lines, theme, width, expanded))
1216
- container.addChild(new Text(line, 1, 0));
1217
- return container;
1218
- };
1128
+ for (const output of step?.recentOutput?.slice(-5) ?? []) {
1129
+ lines.push(truncLine(theme.fg("dim", ` ${output}`), width));
1130
+ }
1131
+ for (const nestedLine of formatNestedWidgetLines(step?.children ?? job.nestedChildren, theme, width, true, snapshotNow)) {
1132
+ lines.push(truncLine(` ${nestedLine}`, width));
1133
+ }
1134
+ return lines;
1219
1135
  }
1220
- export function buildWidgetLines(jobs, theme, width = getTermWidth(), expanded = false) {
1221
- if (jobs.length === 0)
1222
- return [];
1223
- if (jobs.length === 1)
1224
- return buildSingleWidgetLines(jobs[0], theme, width, expanded);
1225
- const running = jobs.filter((job) => job.status === "running");
1226
- const queued = jobs.filter((job) => job.status === "queued");
1227
- const finished = jobs.filter((job) => job.status !== "running" && job.status !== "queued");
1136
+ export function buildWidgetLines(jobs, theme, width = getTermWidth(), expanded = false, now = Date.now()) {
1228
1137
  const lines = [];
1229
- const hasActive = running.length > 0 || queued.length > 0;
1230
- const headerGlyph = running.length > 0 ? runningGlyph(widgetJobsRunningSeed(running)) : hasActive ? "●" : "○";
1231
- lines.push(truncLine(`${theme.fg(hasActive ? "accent" : "dim", headerGlyph)} ${theme.fg(hasActive ? "accent" : "dim", "Async agents")} ${theme.fg("dim", "· background")}`, width));
1232
- const items = [];
1233
- let hiddenRunning = 0;
1234
- let hiddenFinished = 0;
1235
- let queuedSummaryShown = false;
1236
- let slots = MAX_WIDGET_JOBS;
1237
- for (const job of running) {
1238
- if (slots <= 0) {
1239
- hiddenRunning++;
1240
- continue;
1138
+ for (const job of orderedWidgetJobs(jobs)) {
1139
+ const steps = job.steps?.length
1140
+ ? job.steps
1141
+ : job.agents?.length
1142
+ ? job.agents.map((agent, index) => ({ agent, description: agent, status: job.status, index }))
1143
+ : [undefined];
1144
+ for (const [index, step] of steps.entries()) {
1145
+ lines.push(...compactJobLines(job, step, theme, width, now));
1146
+ if (expanded)
1147
+ lines.push(...widgetExpandedDiagnostics(job, step, index, theme, width, now));
1241
1148
  }
1242
- const stats = widgetStats(job, theme);
1243
- items.push([
1244
- `${widgetStatusGlyph(job, theme)} ${themeBold(theme, widgetJobName(job))}${stats ? ` ${theme.fg("dim", "·")} ${stats}` : ""}`,
1245
- ` ${theme.fg("dim", `⎿ ${widgetActivity(job)}`)}`,
1246
- ...widgetParallelAgentDetails(job, theme, expanded, width),
1247
- ]);
1248
- slots--;
1249
1149
  }
1250
- if (queued.length > 0 && slots > 0) {
1251
- items.push([`${theme.fg("muted", "◦")} ${theme.fg("dim", `${queued.length} queued`)}`]);
1252
- queuedSummaryShown = true;
1253
- slots--;
1150
+ return lines;
1151
+ }
1152
+ let activeWidget;
1153
+ export class SubagentAsyncWidget {
1154
+ jobs;
1155
+ expanded;
1156
+ theme;
1157
+ requestRender;
1158
+ nowFn;
1159
+ timer;
1160
+ disposed = false;
1161
+ cachedWidth;
1162
+ cachedLines;
1163
+ constructor(jobs, theme, options) {
1164
+ this.jobs = jobs;
1165
+ this.theme = theme;
1166
+ this.expanded = options?.expanded ?? false;
1167
+ this.requestRender = options?.requestRender;
1168
+ this.nowFn = options?.now ?? Date.now;
1169
+ this.syncTimer();
1254
1170
  }
1255
- for (const job of finished) {
1256
- if (slots <= 0) {
1257
- hiddenFinished++;
1258
- continue;
1259
- }
1260
- const stats = widgetStats(job, theme);
1261
- items.push([
1262
- `${widgetStatusGlyph(job, theme)} ${themeBold(theme, widgetJobName(job))}${stats ? ` ${theme.fg("dim", "·")} ${stats}` : ""}`,
1263
- ` ${theme.fg("dim", `⎿ ${widgetActivity(job)}`)}`,
1264
- ...widgetParallelAgentDetails(job, theme, expanded, width),
1265
- ]);
1266
- slots--;
1171
+ setTheme(theme) {
1172
+ this.theme = theme;
1173
+ this.invalidate();
1267
1174
  }
1268
- const hiddenQueued = queued.length > 0 && !queuedSummaryShown ? queued.length : 0;
1269
- const hiddenTotal = hiddenRunning + hiddenFinished + hiddenQueued;
1270
- if (hiddenTotal > 0) {
1271
- const parts = [];
1272
- if (hiddenRunning > 0)
1273
- parts.push(`${hiddenRunning} running`);
1274
- if (hiddenQueued > 0)
1275
- parts.push(`${hiddenQueued} queued`);
1276
- if (hiddenFinished > 0)
1277
- parts.push(`${hiddenFinished} finished`);
1278
- items.push([theme.fg("dim", `+${hiddenTotal} more (${parts.join(", ")})`)]);
1175
+ setJobs(jobs) {
1176
+ this.jobs = jobs;
1177
+ this.invalidate();
1178
+ this.syncTimer();
1279
1179
  }
1280
- for (let i = 0; i < items.length; i++) {
1281
- const item = items[i];
1282
- const last = i === items.length - 1;
1283
- const branch = last ? "└─" : "├─";
1284
- const continuation = last ? " " : "│ ";
1285
- lines.push(truncLine(`${theme.fg("dim", branch)} ${item[0]}`, width));
1286
- for (const detail of item.slice(1)) {
1287
- lines.push(truncLine(`${theme.fg("dim", continuation)} ${detail}`, width));
1288
- }
1180
+ setExpanded(expanded) {
1181
+ if (this.expanded === expanded)
1182
+ return;
1183
+ this.expanded = expanded;
1184
+ this.invalidate();
1289
1185
  }
1290
- return lines;
1186
+ setRequestRender(requestRender) {
1187
+ this.requestRender = requestRender;
1188
+ }
1189
+ hasRunning() {
1190
+ return this.jobs.some((job) => job.status === "running");
1191
+ }
1192
+ syncTimer() {
1193
+ if (this.disposed)
1194
+ return;
1195
+ if (this.hasRunning())
1196
+ this.startTimer();
1197
+ else
1198
+ this.stopTimer();
1199
+ }
1200
+ startTimer() {
1201
+ if (this.timer)
1202
+ return;
1203
+ this.timer = setInterval(() => {
1204
+ if (this.disposed)
1205
+ return;
1206
+ this.invalidate();
1207
+ this.requestRender?.();
1208
+ }, SUBAGENT_PAINT_INTERVAL_MS);
1209
+ this.timer.unref?.();
1210
+ }
1211
+ stopTimer() {
1212
+ if (!this.timer)
1213
+ return;
1214
+ clearInterval(this.timer);
1215
+ this.timer = undefined;
1216
+ }
1217
+ invalidate() {
1218
+ this.cachedWidth = undefined;
1219
+ this.cachedLines = undefined;
1220
+ }
1221
+ dispose() {
1222
+ this.disposed = true;
1223
+ this.stopTimer();
1224
+ if (activeWidget === this)
1225
+ activeWidget = undefined;
1226
+ }
1227
+ render(width) {
1228
+ const theme = this.theme;
1229
+ if (!theme)
1230
+ return [];
1231
+ if (this.cachedLines && this.cachedWidth === width && !this.hasRunning())
1232
+ return this.cachedLines;
1233
+ const now = this.nowFn();
1234
+ const innerWidth = Math.max(1, width - 2);
1235
+ const lines = buildWidgetLines(this.jobs, theme, innerWidth, this.expanded, now);
1236
+ const fitted = fitAdaptiveWidgetLines(this.jobs, lines, theme, innerWidth, this.expanded);
1237
+ const padded = fitted.map((line) => {
1238
+ const withPad = ` ${line}`;
1239
+ const vis = visibleWidth(withPad);
1240
+ return withPad + " ".repeat(Math.max(0, width - vis));
1241
+ });
1242
+ this.cachedWidth = width;
1243
+ this.cachedLines = padded;
1244
+ return padded;
1245
+ }
1246
+ }
1247
+ export function createSubagentWidgetComponent(jobs, theme, options) {
1248
+ return new SubagentAsyncWidget(jobs, theme, options);
1249
+ }
1250
+ export function disposeSubagentWidget() {
1251
+ activeWidget?.dispose();
1252
+ activeWidget = undefined;
1253
+ }
1254
+ export function clearWidgetPaintTimer() {
1255
+ disposeSubagentWidget();
1291
1256
  }
1292
1257
  /**
1293
1258
  * Render the async jobs widget
@@ -1295,142 +1260,136 @@ export function buildWidgetLines(jobs, theme, width = getTermWidth(), expanded =
1295
1260
  export function renderWidget(ctx, jobs) {
1296
1261
  if (jobs.length === 0) {
1297
1262
  resetWidgetLayoutSession();
1263
+ disposeSubagentWidget();
1298
1264
  if (ctx.hasUI)
1299
1265
  ctx.ui.setWidget(WIDGET_KEY, undefined);
1300
1266
  return;
1301
1267
  }
1302
1268
  if (!ctx.hasUI)
1303
1269
  return;
1304
- ctx.ui.setWidget(WIDGET_KEY, buildWidgetComponent(jobs, ctx.ui.getToolsExpanded?.() ?? false));
1270
+ const expanded = ctx.ui.getToolsExpanded?.() ?? false;
1271
+ const requestRender = () => ctx.ui.requestRender?.();
1272
+ if (activeWidget) {
1273
+ activeWidget.setJobs(jobs);
1274
+ activeWidget.setExpanded(expanded);
1275
+ activeWidget.setRequestRender(requestRender);
1276
+ ctx.ui.requestRender?.();
1277
+ return;
1278
+ }
1279
+ const widget = new SubagentAsyncWidget(jobs, undefined, { expanded, requestRender });
1280
+ activeWidget = widget;
1281
+ ctx.ui.setWidget(WIDGET_KEY, (_tui, theme) => {
1282
+ widget.setTheme(theme);
1283
+ return widget;
1284
+ });
1285
+ }
1286
+ function compactResultTerminalStatus(result) {
1287
+ if (result.stopped)
1288
+ return "stopped";
1289
+ if (result.detached)
1290
+ return "detached";
1291
+ if (result.interrupted)
1292
+ return "paused";
1293
+ if (result.exitCode !== 0)
1294
+ return "failed";
1295
+ return undefined;
1305
1296
  }
1306
1297
  function renderSingleCompact(d, r, theme, frame) {
1307
1298
  const output = r.truncation?.text || getSingleResultOutput(r);
1308
1299
  const progress = r.progress || r.progressSummary;
1309
1300
  const isRunning = r.progress?.status === "running";
1310
- const contextBadge = d.context === "fork" ? theme.fg("warning", " [fork]") : "";
1311
- // lunr: simplified collapsed row — glyph · task summary · agent type · runtime/tools/tokens stats.
1312
- const c = new Container();
1313
1301
  const width = getTermWidth() - 4;
1314
- // lunr: row line is a per-frame template so the running glyph animates in place (see subagentAnimSink).
1315
1302
  const lead = compactRowLead({ description: r.description ?? r.agent, task: r.task });
1316
- const modelBadge = formatModelSelection(r.modelSelection ?? progress?.modelSelection, r.model ?? progress?.model, r.thinking ?? progress?.thinking);
1317
- const permissionBadge = r.permissions ? theme.fg("dim", r.permissions) : "";
1318
- c.addChild(animatedLine((f, now) => {
1319
- const stats = formatProgressStats(theme, progress, true, { running: isRunning, terminal: !isRunning, now });
1320
- return truncLine(`${resultGlyph(r, output, theme, isRunning, undefined, f)} ${themeBold(theme, lead)}${modelBadge ? ` ${theme.fg("dim", "·")} ${theme.fg("dim", modelBadge)}` : ""}${permissionBadge ? ` ${theme.fg("dim", "·")} ${permissionBadge}` : ""}${contextBadge}${stats ? ` ${theme.fg("dim", "·")} ${stats}` : ""}`, width);
1321
- }, frame, isRunning));
1322
- if (isRunning && r.progress) {
1323
- c.addChild(animatedLine((_f, now) => formatCompactStatsHangLine(r.progress, width, (s) => theme.fg("dim", s), " ⎿ ", now, true), frame, true));
1324
- return c;
1303
+ const modelBadge = formatCompactModelBadge(r.modelSelection ?? progress?.modelSelection, r.model ?? progress?.model);
1304
+ return animatedLine((animationTick, now) => formatCompactSubagentRow(theme, width, {
1305
+ glyph: resultGlyph(r, output, theme, isRunning, undefined, foregroundSpinnerFrame(animationTick)),
1306
+ description: lead,
1307
+ modelBadge,
1308
+ tokens: compactResultTokens(r),
1309
+ durationMs: liveDurationMs(progress, isRunning, now),
1310
+ terminalStatus: compactResultTerminalStatus(r),
1311
+ }), frame, isRunning);
1312
+ }
1313
+ function progressStatusGlyph(progress, theme, frame) {
1314
+ if (!progress || progress.status === "pending")
1315
+ return theme.fg("muted", "◦");
1316
+ if (progress.status === "running")
1317
+ return theme.fg("accent", runningGlyph((progressRunningSeed(progress) ?? 0) + (frame ?? 0)));
1318
+ if (progress.status === "completed")
1319
+ return theme.fg("success", "✓");
1320
+ if (progress.status === "failed")
1321
+ return theme.fg("error", "✗");
1322
+ return theme.fg("warning", "■");
1323
+ }
1324
+ function flattenCompactWorkflowNodes(nodes) {
1325
+ const rows = [];
1326
+ for (const node of nodes) {
1327
+ if (node.children?.length)
1328
+ rows.push(...flattenCompactWorkflowNodes(node.children));
1329
+ else
1330
+ rows.push(node);
1325
1331
  }
1326
- c.addChild(new Text(truncLine(theme.fg("dim", ` ⎿ ${resultStatusLine(r, output)}`), width), 0, 0));
1327
- const preview = firstOutputLine(output);
1328
- if (preview && r.exitCode === 0 && !hasEmptyTextOutputWithoutOutputTarget(r.task, output)) {
1329
- c.addChild(new Text(truncLine(theme.fg("dim", ` ${preview}`), width), 0, 0));
1332
+ return rows;
1333
+ }
1334
+ function compactForegroundEntries(d) {
1335
+ const workflowNodes = flattenCompactWorkflowNodes(d.workflowGraph?.nodes ?? []);
1336
+ if (workflowNodes.length === 0) {
1337
+ const progressCount = d.progress?.reduce((count, entry) => Math.max(count, entry.index + 1), 0) ?? 0;
1338
+ const chainCount = d.mode === "chain"
1339
+ ? buildChainStepSpans(d).reduce((count, span) => Math.max(count, span.start + span.count), 0)
1340
+ : 0;
1341
+ const count = Math.max(d.results.length, progressCount, d.chainChildren?.length ?? 0, d.chainAgents?.length ?? 0, chainCount);
1342
+ return Array.from({ length: count }, (_, flatIndex) => ({ flatIndex }));
1330
1343
  }
1331
- if (r.sessionFile)
1332
- c.addChild(new Text(truncLine(theme.fg("dim", ` session: ${shortenPath(r.sessionFile)}`), width), 0, 0));
1333
- return c;
1344
+ const entries = workflowNodes.map((node) => ({ flatIndex: node.flatIndex, node }));
1345
+ const seen = new Set(entries.flatMap((entry) => entry.flatIndex === undefined ? [] : [entry.flatIndex]));
1346
+ const progressCount = d.progress?.reduce((count, entry) => Math.max(count, entry.index + 1), 0) ?? 0;
1347
+ const dataCount = Math.max(d.results.length, progressCount, d.chainChildren?.length ?? 0);
1348
+ for (let flatIndex = 0; flatIndex < dataCount; flatIndex++) {
1349
+ if (!seen.has(flatIndex))
1350
+ entries.push({ flatIndex });
1351
+ }
1352
+ return entries;
1334
1353
  }
1335
1354
  function renderMultiCompact(d, theme, frame) {
1336
- const hasRunning = d.progress?.some((p) => p.status === "running")
1337
- || d.results.some((r) => r.progress?.status === "running")
1338
- || workflowGraphHasStatus(d, ["running"]);
1339
- const stopped = d.results.some((r) => r.stopped && r.progress?.status !== "running")
1340
- || workflowGraphHasStatus(d, ["stopped"]);
1341
- const failed = d.results.some((r) => !r.stopped && r.exitCode !== 0 && r.progress?.status !== "running")
1342
- || workflowGraphHasStatus(d, ["failed"]);
1343
- const paused = d.results.some((r) => (r.interrupted || r.detached) && r.progress?.status !== "running")
1344
- || workflowGraphHasStatus(d, ["paused", "detached"]);
1345
- let totalSummary = d.progressSummary;
1346
- if (!totalSummary) {
1347
- let sawProgress = false;
1348
- const summary = { toolCount: 0, tokens: 0, durationMs: 0, lastActivityAt: undefined };
1349
- for (const r of d.results) {
1350
- const prog = r.progress || r.progressSummary;
1351
- if (!prog)
1352
- continue;
1353
- sawProgress = true;
1354
- summary.toolCount += prog.toolCount;
1355
- summary.tokens += prog.tokens;
1356
- summary.durationMs = d.mode === "chain" ? summary.durationMs + prog.durationMs : Math.max(summary.durationMs, prog.durationMs);
1357
- if (prog.status === "running" && prog.lastActivityAt !== undefined) {
1358
- summary.lastActivityAt = Math.max(summary.lastActivityAt ?? 0, prog.lastActivityAt);
1359
- }
1360
- }
1361
- if (sawProgress)
1362
- totalSummary = summary;
1363
- }
1364
- const multiLabel = buildMultiProgressLabel(d, hasRunning);
1365
- const itemTitle = multiLabel.itemTitle;
1366
- const glyph = (f) => hasRunning
1367
- ? theme.fg("accent", runningGlyph(f !== undefined ? (runningSeed(progressRunningSeed(totalSummary), d.currentStepIndex) ?? 0) + f : runningSeed(progressRunningSeed(totalSummary), d.currentStepIndex)))
1368
- : stopped
1369
- ? theme.fg("warning", "■")
1370
- : failed
1371
- ? theme.fg("error", "✗")
1372
- : paused
1373
- ? theme.fg("warning", "■")
1374
- : theme.fg("success", "✓");
1375
- const contextBadge = d.context === "fork" ? theme.fg("warning", " [fork]") : "";
1376
1355
  const c = new Container();
1377
1356
  const width = getTermWidth() - 4;
1378
- // lunr: header line is a per-frame template so the running glyph animates in place (see subagentAnimSink).
1379
- c.addChild(animatedLine((f, now) => {
1380
- const stats = statJoin(theme, [multiLabel.headerLabel, formatProgressStats(theme, totalSummary, true, { running: hasRunning, terminal: !hasRunning, now }), formatTotalCostStat(d.totalCost)]);
1381
- return truncLine(`${glyph(f)} ${theme.fg("toolTitle", theme.bold(d.mode))}${contextBadge}${stats ? ` ${theme.fg("dim", "·")} ${stats}` : ""}`, width);
1382
- }, frame, hasRunning));
1383
- const useResultsDirectly = multiLabel.hasParallelInChain || !d.chainAgents?.length;
1384
- const displayStart = multiLabel.showActiveGroupOnly ? multiLabel.groupStartIndex : 0;
1385
- const displayEnd = multiLabel.showActiveGroupOnly ? multiLabel.groupEndIndex : (useResultsDirectly ? d.results.length : d.chainAgents.length);
1386
- const chainEntries = buildChainRenderEntries(d, multiLabel);
1387
- const renderEntries = chainEntries ?? Array.from({ length: displayEnd - displayStart }, (_, offset) => {
1388
- const i = displayStart + offset;
1389
- const r = d.results[i];
1390
- const fallbackLabel = itemTitle.toLowerCase();
1391
- const rowNumber = multiLabel.showActiveGroupOnly ? (i - multiLabel.groupStartIndex + 1) : (i + 1);
1392
- return { kind: "result", resultIndex: i, rowNumber, agentName: useResultsDirectly ? (r?.agent || `${fallbackLabel}-${rowNumber}`) : (d.chainAgents[i] || r?.agent || `${fallbackLabel}-${rowNumber}`) };
1393
- });
1394
- for (const entry of renderEntries) {
1395
- if (entry.kind === "placeholder") {
1396
- const glyph = widgetStepGlyph(entry.status, theme);
1397
- const statusLabel = widgetStepStatus(entry.status, theme);
1398
- c.addChild(new Text(truncLine(` ${glyph} ${entry.stepLabel}: ${themeBold(theme, entry.agentName)} ${theme.fg("dim", "·")} ${statusLabel}`, width), 0, 0));
1399
- if (entry.error)
1400
- c.addChild(new Text(truncLine(theme.fg("error", ` ⎿ Error: ${entry.error}`), width), 0, 0));
1401
- continue;
1402
- }
1403
- const i = entry.resultIndex;
1404
- const r = d.results[i];
1405
- const rowNumber = entry.rowNumber;
1406
- const agentName = entry.agentName;
1407
- if (!r) {
1408
- const pendingLabel = chainEntries ? resultRowLabel(d, multiLabel, i, rowNumber) : `${itemTitle} ${rowNumber}`;
1409
- c.addChild(new Text(truncLine(theme.fg("dim", ` ◦ ${pendingLabel}: ${agentName} · pending`), width), 0, 0));
1410
- continue;
1411
- }
1412
- const output = getSingleResultOutput(r);
1413
- const progressFromArray = d.progress?.find((p) => p.index === i) || d.progress?.find((p) => p.agent === r.agent && p.status === "running");
1414
- const rProg = r.progress || progressFromArray || r.progressSummary;
1415
- const rRunning = rProg && "status" in rProg && rProg.status === "running";
1416
- const rPending = rProg && "status" in rProg && rProg.status === "pending";
1417
- const pendingLabel = rPending ? ` ${theme.fg("dim", "· pending")}` : "";
1418
- // lunr: simplified collapsed row — glyph · task summary · agent type · runtime/tools/tokens stats.
1419
- // lunr: row line is a per-frame template so the running glyph animates in place (see subagentAnimSink).
1420
- const lead = compactRowLead({ description: r.description ?? agentName, task: r.task });
1421
- const permissionBadge = r.permissions ? theme.fg("dim", r.permissions) : "";
1422
- const modelBadge = formatModelSelection(r.modelSelection ?? (rProg && "modelSelection" in rProg ? rProg.modelSelection : undefined), r.model ?? (rProg && "model" in rProg ? rProg.model : undefined), r.thinking ?? (rProg && "thinking" in rProg ? rProg.thinking : undefined));
1423
- c.addChild(animatedLine((f, now) => {
1424
- const glyph = rPending ? theme.fg("dim", "◦") : resultGlyph(r, output, theme, rRunning, progressRunningSeed(rProg), f);
1425
- const stepStats = formatProgressStats(theme, rProg, true, { running: !!rRunning, terminal: !rRunning && !rPending, now });
1426
- return truncLine(` ${glyph} ${themeBold(theme, lead)}${modelBadge ? ` ${theme.fg("dim", "·")} ${theme.fg("dim", modelBadge)}` : ""}${permissionBadge ? ` ${theme.fg("dim", "·")} ${permissionBadge}` : ""}${stepStats ? ` ${theme.fg("dim", "·")} ${stepStats}` : ""}${pendingLabel}`, width);
1427
- }, frame, !!rRunning));
1428
- if (rRunning && rProg && "status" in rProg) {
1429
- c.addChild(animatedLine((_f, now) => formatCompactStatsHangLine(rProg, width, (s) => theme.fg("dim", s), " ⎿ ", now, true), frame, true));
1430
- }
1431
- else if (!rPending && (r.exitCode !== 0 || r.interrupted || r.detached || hasEmptyTextOutputWithoutOutputTarget(r.task, output))) {
1432
- c.addChild(new Text(truncLine(theme.fg(r.exitCode !== 0 ? "error" : "dim", ` ⎿ ${resultStatusLine(r, output)}`), width), 0, 0));
1433
- }
1357
+ const entries = compactForegroundEntries(d);
1358
+ for (const [rowIndex, entry] of entries.entries()) {
1359
+ const flatIndex = entry.flatIndex;
1360
+ const result = flatIndex === undefined ? undefined : resultAtFlatIndex(d, flatIndex);
1361
+ const progress = result?.progress
1362
+ ?? (flatIndex === undefined ? undefined : d.progress?.find((candidate) => candidate.index === flatIndex))
1363
+ ?? result?.progressSummary;
1364
+ const status = progress?.status ?? entry.node?.status ?? "pending";
1365
+ const description = compactRowLead({
1366
+ description: result?.description
1367
+ ?? progress?.description
1368
+ ?? entry.node?.label
1369
+ ?? (flatIndex === undefined ? undefined : d.chainChildren?.[flatIndex]?.description)
1370
+ ?? (flatIndex === undefined ? undefined : d.chainAgents?.[flatIndex])
1371
+ ?? result?.agent
1372
+ ?? progress?.agent,
1373
+ task: result?.task ?? progress?.task,
1374
+ }) || `child ${rowIndex + 1}`;
1375
+ const running = status === "running";
1376
+ const output = result ? getSingleResultOutput(result) : "";
1377
+ const modelBadge = formatCompactModelBadge(result?.modelSelection ?? progress?.modelSelection, result?.model ?? progress?.model);
1378
+ c.addChild(animatedLine((animationTick, now) => {
1379
+ const animationFrame = foregroundSpinnerFrame(animationTick);
1380
+ return formatCompactSubagentRow(theme, width, {
1381
+ glyph: result
1382
+ ? resultGlyph(result, output, theme, running, progressRunningSeed(progress), animationFrame)
1383
+ : progressStatusGlyph({ ...progress, status, index: flatIndex }, theme, animationFrame),
1384
+ description,
1385
+ modelBadge,
1386
+ tokens: result ? compactResultTokens(result) : progress?.tokens ?? 0,
1387
+ durationMs: liveDurationMs(progress, running, now),
1388
+ terminalStatus: result
1389
+ ? compactResultTerminalStatus(result)
1390
+ : compactTerminalStatus(status),
1391
+ });
1392
+ }, frame, running));
1434
1393
  }
1435
1394
  return c;
1436
1395
  }
@@ -1439,7 +1398,9 @@ function renderMultiCompact(d, theme, frame) {
1439
1398
  */
1440
1399
  export function renderSubagentResult(result, options, theme, frame) {
1441
1400
  const d = result.details;
1442
- if (!d || !d.results.length) {
1401
+ const hasWorkflowRows = d?.mode !== "management"
1402
+ && Boolean(d?.workflowGraph?.nodes.length || d?.progress?.length || d?.chainChildren?.length);
1403
+ if (!d || (!d.results.length && !hasWorkflowRows)) {
1443
1404
  const t = result.content[0];
1444
1405
  const text = t?.type === "text" ? t.text : "(no output)";
1445
1406
  const contextPrefix = d?.context === "fork" ? `${theme.fg("warning", "[fork]")} ` : "";
@@ -1484,6 +1445,9 @@ export function renderSubagentResult(result, options, theme, frame) {
1484
1445
  ? r.task
1485
1446
  : `${r.task.slice(0, taskMaxLen)}...`;
1486
1447
  c.addChild(new Text(fit(theme.fg("dim", `Task: ${taskPreview}`)), 0, 0));
1448
+ if (!isRunning && compactResultTerminalStatus(r)) {
1449
+ c.addChild(new Text(fit(theme.fg(r.exitCode !== 0 ? "error" : "warning", resultStatusLine(r, output))), 0, 0));
1450
+ }
1487
1451
  c.addChild(new Spacer(1));
1488
1452
  if (isRunning && r.progress) {
1489
1453
  const progressSnapshotNow = snapshotNowForProgress(r.progress);
@@ -1556,6 +1520,7 @@ export function renderSubagentResult(result, options, theme, frame) {
1556
1520
  const hasWorkflowFailure = workflowGraphHasStatus(d, ["failed"]);
1557
1521
  const hasWorkflowStop = d.results.some((r) => r.stopped && r.progress?.status !== "running") || workflowGraphHasStatus(d, ["stopped"]);
1558
1522
  const hasWorkflowPause = workflowGraphHasStatus(d, ["paused", "detached"]);
1523
+ const hasWorkflowPending = workflowGraphHasStatus(d, ["pending"]);
1559
1524
  const icon = hasRunning
1560
1525
  ? theme.fg("warning", "running")
1561
1526
  : hasEmptyWithoutTarget
@@ -1566,9 +1531,11 @@ export function renderSubagentResult(result, options, theme, frame) {
1566
1531
  ? theme.fg("warning", "stopped")
1567
1532
  : hasWorkflowPause
1568
1533
  ? theme.fg("warning", "paused")
1569
- : ok === d.results.length
1570
- ? theme.fg("success", "ok")
1571
- : theme.fg("error", "failed");
1534
+ : hasWorkflowPending
1535
+ ? theme.fg("dim", "pending")
1536
+ : ok === d.results.length
1537
+ ? theme.fg("success", "ok")
1538
+ : theme.fg("error", "failed");
1572
1539
  const totalSummary = d.progressSummary ||
1573
1540
  d.results.reduce((acc, r) => {
1574
1541
  const prog = r.progress || r.progressSummary;
@@ -1630,16 +1597,40 @@ export function renderSubagentResult(result, options, theme, frame) {
1630
1597
  if (chainVis) {
1631
1598
  c.addChild(new Text(fit(` ${chainVis}`), 0, 0));
1632
1599
  }
1633
- const useResultsDirectly = multiLabel.hasParallelInChain || !d.chainAgents?.length;
1634
- const displayStart = multiLabel.showActiveGroupOnly ? multiLabel.groupStartIndex : 0;
1635
- const displayEnd = multiLabel.showActiveGroupOnly ? multiLabel.groupEndIndex : (useResultsDirectly ? d.results.length : d.chainAgents.length);
1636
1600
  const chainEntries = buildChainRenderEntries(d, multiLabel);
1637
- const renderEntries = chainEntries ?? Array.from({ length: displayEnd - displayStart }, (_, offset) => {
1638
- const i = displayStart + offset;
1639
- const r = d.results[i];
1640
- const rowNumber = multiLabel.showActiveGroupOnly ? (i - multiLabel.groupStartIndex + 1) : (i + 1);
1641
- return { kind: "result", resultIndex: i, rowNumber, agentName: useResultsDirectly ? (r?.agent || `step-${rowNumber}`) : (d.chainAgents[i] || r?.agent || `step-${rowNumber}`) };
1601
+ const fallbackEntries = compactForegroundEntries(d)
1602
+ .filter((entry) => !multiLabel.showActiveGroupOnly
1603
+ || entry.flatIndex === undefined
1604
+ || (entry.flatIndex >= multiLabel.groupStartIndex && entry.flatIndex < multiLabel.groupEndIndex))
1605
+ .map((entry, rowIndex) => {
1606
+ if (entry.flatIndex === undefined) {
1607
+ return {
1608
+ kind: "placeholder",
1609
+ rowNumber: entry.node?.stepIndex !== undefined ? entry.node.stepIndex + 1 : rowIndex + 1,
1610
+ stepLabel: `Step ${entry.node?.stepIndex !== undefined ? entry.node.stepIndex + 1 : rowIndex + 1}`,
1611
+ agentName: entry.node?.label ?? `step-${rowIndex + 1}`,
1612
+ status: entry.node?.status ?? "pending",
1613
+ error: entry.node?.error,
1614
+ };
1615
+ }
1616
+ const result = resultAtFlatIndex(d, entry.flatIndex);
1617
+ const rowNumber = multiLabel.showActiveGroupOnly
1618
+ ? entry.flatIndex - multiLabel.groupStartIndex + 1
1619
+ : entry.flatIndex + 1;
1620
+ return {
1621
+ kind: "result",
1622
+ resultIndex: entry.flatIndex,
1623
+ rowNumber,
1624
+ agentName: result?.agent
1625
+ ?? entry.node?.label
1626
+ ?? d.chainChildren?.[entry.flatIndex]?.description
1627
+ ?? d.chainAgents?.[entry.flatIndex]
1628
+ ?? `step-${rowNumber}`,
1629
+ status: entry.node?.status,
1630
+ error: entry.node?.error,
1631
+ };
1642
1632
  });
1633
+ const renderEntries = chainEntries ?? fallbackEntries;
1643
1634
  c.addChild(new Spacer(1));
1644
1635
  for (const entry of renderEntries) {
1645
1636
  if (entry.kind === "placeholder") {
@@ -1652,13 +1643,16 @@ export function renderSubagentResult(result, options, theme, frame) {
1652
1643
  continue;
1653
1644
  }
1654
1645
  const i = entry.resultIndex;
1655
- const r = d.results[i];
1646
+ const r = resultAtFlatIndex(d, i);
1656
1647
  const rowNumber = entry.rowNumber;
1657
1648
  const agentName = entry.agentName;
1658
1649
  if (!r) {
1659
- const pendingLabel = chainEntries ? resultRowLabel(d, multiLabel, i, rowNumber) : `${itemTitle} ${rowNumber}`;
1660
- c.addChild(new Text(fit(theme.fg("dim", ` ${pendingLabel}: ${agentName}`)), 0, 0));
1661
- c.addChild(new Text(theme.fg("dim", ` status: pending`), 0, 0));
1650
+ const rowLabel = chainEntries ? resultRowLabel(d, multiLabel, i, rowNumber) : `${itemTitle} ${rowNumber}`;
1651
+ const status = entry.status ?? "pending";
1652
+ c.addChild(new Text(fit(theme.fg(status === "failed" ? "error" : "dim", ` ${rowLabel}: ${agentName}`)), 0, 0));
1653
+ c.addChild(new Text(theme.fg(status === "failed" ? "error" : "dim", ` status: ${status}`), 0, 0));
1654
+ if (entry.error)
1655
+ c.addChild(new Text(theme.fg("error", ` error: ${entry.error}`), 0, 0));
1662
1656
  c.addChild(new Spacer(1));
1663
1657
  continue;
1664
1658
  }
@@ -1689,6 +1683,9 @@ export function renderSubagentResult(result, options, theme, frame) {
1689
1683
  ? r.task
1690
1684
  : `${r.task.slice(0, taskMaxLen)}...`;
1691
1685
  c.addChild(new Text(fit(theme.fg("dim", ` task: ${taskPreview}`)), 0, 0));
1686
+ if (!rRunning && compactResultTerminalStatus(r)) {
1687
+ c.addChild(new Text(fit(theme.fg(r.exitCode !== 0 ? "error" : "warning", ` ${resultStatusLine(r, resultOutput)}`)), 0, 0));
1688
+ }
1692
1689
  if (r.skills?.length) {
1693
1690
  c.addChild(new Text(fit(theme.fg("dim", ` skills: ${r.skills.join(", ")}`)), 0, 0));
1694
1691
  }