@ashx-j/lunr-dev 0.2.19-dev.10.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 (307) hide show
  1. package/CHANGELOG.md +36 -1
  2. package/README.md +2 -2
  3. package/dist/builtin-extensions/index.d.ts.map +1 -1
  4. package/dist/builtin-extensions/index.js +0 -2
  5. package/dist/builtin-extensions/index.js.map +1 -1
  6. package/dist/builtin-extensions/lunr-computer-use.d.ts.map +1 -1
  7. package/dist/builtin-extensions/lunr-computer-use.js +15 -14
  8. package/dist/builtin-extensions/lunr-computer-use.js.map +1 -1
  9. package/dist/builtin-extensions/lunr-todos.d.ts +6 -5
  10. package/dist/builtin-extensions/lunr-todos.d.ts.map +1 -1
  11. package/dist/builtin-extensions/lunr-todos.js +9 -7
  12. package/dist/builtin-extensions/lunr-todos.js.map +1 -1
  13. package/dist/builtin-extensions/pi-intercom/broker/spawn.d.ts +6 -4
  14. package/dist/builtin-extensions/pi-intercom/broker/spawn.d.ts.map +1 -1
  15. package/dist/builtin-extensions/pi-intercom/broker/spawn.js +114 -61
  16. package/dist/builtin-extensions/pi-intercom/broker/spawn.js.map +1 -1
  17. package/dist/builtin-extensions/pi-intercom/index.d.ts.map +1 -1
  18. package/dist/builtin-extensions/pi-intercom/index.js +360 -351
  19. package/dist/builtin-extensions/pi-intercom/index.js.map +1 -1
  20. package/dist/builtin-extensions/pi-subagents/src/extension/fanout-child.d.ts.map +1 -1
  21. package/dist/builtin-extensions/pi-subagents/src/extension/fanout-child.js +2 -2
  22. package/dist/builtin-extensions/pi-subagents/src/extension/fanout-child.js.map +1 -1
  23. package/dist/builtin-extensions/pi-subagents/src/extension/index.d.ts +8 -6
  24. package/dist/builtin-extensions/pi-subagents/src/extension/index.d.ts.map +1 -1
  25. package/dist/builtin-extensions/pi-subagents/src/extension/index.js +128 -57
  26. package/dist/builtin-extensions/pi-subagents/src/extension/index.js.map +1 -1
  27. package/dist/builtin-extensions/pi-subagents/src/extension/schemas.d.ts +18 -8
  28. package/dist/builtin-extensions/pi-subagents/src/extension/schemas.d.ts.map +1 -1
  29. package/dist/builtin-extensions/pi-subagents/src/extension/schemas.js +38 -13
  30. package/dist/builtin-extensions/pi-subagents/src/extension/schemas.js.map +1 -1
  31. package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.d.ts +4 -3
  32. package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.d.ts.map +1 -1
  33. package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.js +24 -14
  34. package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.js.map +1 -1
  35. package/dist/builtin-extensions/pi-subagents/src/intercom/native-supervisor-channel.d.ts +8 -1
  36. package/dist/builtin-extensions/pi-subagents/src/intercom/native-supervisor-channel.d.ts.map +1 -1
  37. package/dist/builtin-extensions/pi-subagents/src/intercom/native-supervisor-channel.js +247 -18
  38. package/dist/builtin-extensions/pi-subagents/src/intercom/native-supervisor-channel.js.map +1 -1
  39. package/dist/builtin-extensions/pi-subagents/src/intercom/result-intercom.d.ts +1 -0
  40. package/dist/builtin-extensions/pi-subagents/src/intercom/result-intercom.d.ts.map +1 -1
  41. package/dist/builtin-extensions/pi-subagents/src/intercom/result-intercom.js +1 -1
  42. package/dist/builtin-extensions/pi-subagents/src/intercom/result-intercom.js.map +1 -1
  43. package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-ask.d.ts +29 -0
  44. package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-ask.d.ts.map +1 -0
  45. package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-ask.js +179 -0
  46. package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-ask.js.map +1 -0
  47. package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-questions.d.ts +89 -0
  48. package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-questions.d.ts.map +1 -0
  49. package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-questions.js +541 -0
  50. package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-questions.js.map +1 -0
  51. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-execution.d.ts +11 -1
  52. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-execution.d.ts.map +1 -1
  53. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-execution.js +38 -12
  54. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-execution.js.map +1 -1
  55. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-job-tracker.d.ts.map +1 -1
  56. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-job-tracker.js +3 -2
  57. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-job-tracker.js.map +1 -1
  58. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-resume.d.ts +2 -1
  59. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-resume.d.ts.map +1 -1
  60. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-resume.js +35 -8
  61. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-resume.js.map +1 -1
  62. package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.d.ts +7 -3
  63. package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.d.ts.map +1 -1
  64. package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.js +26 -4
  65. package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.js.map +1 -1
  66. package/dist/builtin-extensions/pi-subagents/src/runs/background/result-watcher.d.ts +1 -0
  67. package/dist/builtin-extensions/pi-subagents/src/runs/background/result-watcher.d.ts.map +1 -1
  68. package/dist/builtin-extensions/pi-subagents/src/runs/background/result-watcher.js +55 -38
  69. package/dist/builtin-extensions/pi-subagents/src/runs/background/result-watcher.js.map +1 -1
  70. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.d.ts +100 -0
  71. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.d.ts.map +1 -1
  72. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.js +46 -31
  73. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.js.map +1 -1
  74. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-wait.d.ts +3 -6
  75. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-wait.d.ts.map +1 -1
  76. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-wait.js +64 -5
  77. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-wait.js.map +1 -1
  78. package/dist/builtin-extensions/pi-subagents/src/runs/background/top-level-async.d.ts +15 -2
  79. package/dist/builtin-extensions/pi-subagents/src/runs/background/top-level-async.d.ts.map +1 -1
  80. package/dist/builtin-extensions/pi-subagents/src/runs/background/top-level-async.js +14 -4
  81. package/dist/builtin-extensions/pi-subagents/src/runs/background/top-level-async.js.map +1 -1
  82. package/dist/builtin-extensions/pi-subagents/src/runs/background/wait-tool.d.ts.map +1 -1
  83. package/dist/builtin-extensions/pi-subagents/src/runs/background/wait-tool.js +2 -1
  84. package/dist/builtin-extensions/pi-subagents/src/runs/background/wait-tool.js.map +1 -1
  85. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.d.ts.map +1 -1
  86. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.js +21 -8
  87. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.js.map +1 -1
  88. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.d.ts.map +1 -1
  89. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.js +1 -1
  90. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.js.map +1 -1
  91. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.d.ts +0 -1
  92. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.d.ts.map +1 -1
  93. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.js +71 -25
  94. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.js.map +1 -1
  95. package/dist/builtin-extensions/pi-subagents/src/runs/shared/acceptance.d.ts +2 -0
  96. package/dist/builtin-extensions/pi-subagents/src/runs/shared/acceptance.d.ts.map +1 -1
  97. package/dist/builtin-extensions/pi-subagents/src/runs/shared/acceptance.js +75 -18
  98. package/dist/builtin-extensions/pi-subagents/src/runs/shared/acceptance.js.map +1 -1
  99. package/dist/builtin-extensions/pi-subagents/src/runs/shared/completion-guard.d.ts +1 -1
  100. package/dist/builtin-extensions/pi-subagents/src/runs/shared/completion-guard.d.ts.map +1 -1
  101. package/dist/builtin-extensions/pi-subagents/src/runs/shared/completion-guard.js +1 -1
  102. package/dist/builtin-extensions/pi-subagents/src/runs/shared/completion-guard.js.map +1 -1
  103. package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.d.ts +13 -1
  104. package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.d.ts.map +1 -1
  105. package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.js +67 -11
  106. package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.js.map +1 -1
  107. package/dist/builtin-extensions/pi-subagents/src/runs/shared/parallel-utils.d.ts +1 -0
  108. package/dist/builtin-extensions/pi-subagents/src/runs/shared/parallel-utils.d.ts.map +1 -1
  109. package/dist/builtin-extensions/pi-subagents/src/runs/shared/parallel-utils.js.map +1 -1
  110. package/dist/builtin-extensions/pi-subagents/src/runs/shared/pi-args.d.ts +3 -0
  111. package/dist/builtin-extensions/pi-subagents/src/runs/shared/pi-args.d.ts.map +1 -1
  112. package/dist/builtin-extensions/pi-subagents/src/runs/shared/pi-args.js +7 -2
  113. package/dist/builtin-extensions/pi-subagents/src/runs/shared/pi-args.js.map +1 -1
  114. package/dist/builtin-extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.d.ts.map +1 -1
  115. package/dist/builtin-extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.js +13 -3
  116. package/dist/builtin-extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.js.map +1 -1
  117. package/dist/builtin-extensions/pi-subagents/src/runs/shared/task-intent.d.ts +2 -2
  118. package/dist/builtin-extensions/pi-subagents/src/runs/shared/task-intent.d.ts.map +1 -1
  119. package/dist/builtin-extensions/pi-subagents/src/runs/shared/task-intent.js +5 -10
  120. package/dist/builtin-extensions/pi-subagents/src/runs/shared/task-intent.js.map +1 -1
  121. package/dist/builtin-extensions/pi-subagents/src/shared/async-guidance.d.ts +2 -0
  122. package/dist/builtin-extensions/pi-subagents/src/shared/async-guidance.d.ts.map +1 -0
  123. package/dist/builtin-extensions/pi-subagents/src/shared/async-guidance.js +3 -0
  124. package/dist/builtin-extensions/pi-subagents/src/shared/async-guidance.js.map +1 -0
  125. package/dist/builtin-extensions/pi-subagents/src/shared/child-spec.d.ts +3 -0
  126. package/dist/builtin-extensions/pi-subagents/src/shared/child-spec.d.ts.map +1 -1
  127. package/dist/builtin-extensions/pi-subagents/src/shared/child-spec.js +68 -11
  128. package/dist/builtin-extensions/pi-subagents/src/shared/child-spec.js.map +1 -1
  129. package/dist/builtin-extensions/pi-subagents/src/shared/formatters.d.ts +12 -1
  130. package/dist/builtin-extensions/pi-subagents/src/shared/formatters.d.ts.map +1 -1
  131. package/dist/builtin-extensions/pi-subagents/src/shared/formatters.js +21 -2
  132. package/dist/builtin-extensions/pi-subagents/src/shared/formatters.js.map +1 -1
  133. package/dist/builtin-extensions/pi-subagents/src/shared/types.d.ts +21 -4
  134. package/dist/builtin-extensions/pi-subagents/src/shared/types.d.ts.map +1 -1
  135. package/dist/builtin-extensions/pi-subagents/src/shared/types.js +1 -1
  136. package/dist/builtin-extensions/pi-subagents/src/shared/types.js.map +1 -1
  137. package/dist/builtin-extensions/pi-subagents/src/slash/delegation-adapters.d.ts.map +1 -1
  138. package/dist/builtin-extensions/pi-subagents/src/slash/delegation-adapters.js.map +1 -1
  139. package/dist/builtin-extensions/pi-subagents/src/slash/prompt-workflows.d.ts +7 -0
  140. package/dist/builtin-extensions/pi-subagents/src/slash/prompt-workflows.d.ts.map +1 -1
  141. package/dist/builtin-extensions/pi-subagents/src/slash/prompt-workflows.js +11 -7
  142. package/dist/builtin-extensions/pi-subagents/src/slash/prompt-workflows.js.map +1 -1
  143. package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.d.ts +6 -0
  144. package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.d.ts.map +1 -1
  145. package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.js +46 -29
  146. package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.js.map +1 -1
  147. package/dist/builtin-extensions/pi-subagents/src/tui/render.d.ts +46 -4
  148. package/dist/builtin-extensions/pi-subagents/src/tui/render.d.ts.map +1 -1
  149. package/dist/builtin-extensions/pi-subagents/src/tui/render.js +407 -450
  150. package/dist/builtin-extensions/pi-subagents/src/tui/render.js.map +1 -1
  151. package/dist/builtin-extensions/pi-subagents/src/watchdog/register-main.d.ts.map +1 -1
  152. package/dist/builtin-extensions/pi-subagents/src/watchdog/register-main.js +1 -1
  153. package/dist/builtin-extensions/pi-subagents/src/watchdog/register-main.js.map +1 -1
  154. package/dist/builtin-extensions/pi-subagents/src/watchdog/tool-actions.d.ts +2 -13
  155. package/dist/builtin-extensions/pi-subagents/src/watchdog/tool-actions.d.ts.map +1 -1
  156. package/dist/builtin-extensions/pi-subagents/src/watchdog/tool-actions.js +5 -91
  157. package/dist/builtin-extensions/pi-subagents/src/watchdog/tool-actions.js.map +1 -1
  158. package/dist/core/computer-use/image.d.ts +26 -0
  159. package/dist/core/computer-use/image.d.ts.map +1 -0
  160. package/dist/core/computer-use/image.js +64 -0
  161. package/dist/core/computer-use/image.js.map +1 -0
  162. package/dist/core/computer-use/policy.d.ts.map +1 -1
  163. package/dist/core/computer-use/policy.js +2 -6
  164. package/dist/core/computer-use/policy.js.map +1 -1
  165. package/dist/core/computer-use/schemas.d.ts +13 -10
  166. package/dist/core/computer-use/schemas.d.ts.map +1 -1
  167. package/dist/core/computer-use/schemas.js +26 -35
  168. package/dist/core/computer-use/schemas.js.map +1 -1
  169. package/dist/core/computer-use/workflow.d.ts +16 -8
  170. package/dist/core/computer-use/workflow.d.ts.map +1 -1
  171. package/dist/core/computer-use/workflow.js +271 -260
  172. package/dist/core/computer-use/workflow.js.map +1 -1
  173. package/dist/core/customize.d.ts +2 -0
  174. package/dist/core/customize.d.ts.map +1 -1
  175. package/dist/core/customize.js +3 -0
  176. package/dist/core/customize.js.map +1 -1
  177. package/dist/core/permissions.d.ts +1 -0
  178. package/dist/core/permissions.d.ts.map +1 -1
  179. package/dist/core/permissions.js +8 -4
  180. package/dist/core/permissions.js.map +1 -1
  181. package/dist/core/plan-mode.d.ts.map +1 -1
  182. package/dist/core/plan-mode.js +0 -5
  183. package/dist/core/plan-mode.js.map +1 -1
  184. package/dist/core/runtime-bridges.d.ts.map +1 -1
  185. package/dist/core/runtime-bridges.js +0 -2
  186. package/dist/core/runtime-bridges.js.map +1 -1
  187. package/dist/core/settings-manager.d.ts +4 -0
  188. package/dist/core/settings-manager.d.ts.map +1 -1
  189. package/dist/core/settings-manager.js +11 -0
  190. package/dist/core/settings-manager.js.map +1 -1
  191. package/dist/core/subagent-cancellation.d.ts +21 -0
  192. package/dist/core/subagent-cancellation.d.ts.map +1 -0
  193. package/dist/core/subagent-cancellation.js +53 -0
  194. package/dist/core/subagent-cancellation.js.map +1 -0
  195. package/dist/core/subagent-spinner-setting.d.ts +6 -0
  196. package/dist/core/subagent-spinner-setting.d.ts.map +1 -0
  197. package/dist/core/subagent-spinner-setting.js +12 -0
  198. package/dist/core/subagent-spinner-setting.js.map +1 -0
  199. package/dist/core/subagent-spinner.d.ts +4 -0
  200. package/dist/core/subagent-spinner.d.ts.map +1 -0
  201. package/dist/core/subagent-spinner.js +6 -0
  202. package/dist/core/subagent-spinner.js.map +1 -0
  203. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  204. package/dist/modes/interactive/components/assistant-message.js +12 -18
  205. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  206. package/dist/modes/interactive/components/settings-selector.d.ts +4 -0
  207. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  208. package/dist/modes/interactive/components/settings-selector.js +73 -1
  209. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  210. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  211. package/dist/modes/interactive/components/tool-execution.js +12 -0
  212. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  213. package/dist/modes/interactive/extension-widget-order.d.ts +8 -0
  214. package/dist/modes/interactive/extension-widget-order.d.ts.map +1 -0
  215. package/dist/modes/interactive/extension-widget-order.js +37 -0
  216. package/dist/modes/interactive/extension-widget-order.js.map +1 -0
  217. package/dist/modes/interactive/interactive-mode.d.ts +1 -0
  218. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  219. package/dist/modes/interactive/interactive-mode.js +44 -22
  220. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  221. package/dist/node-runtime/{agent-session-services-RSGP5GDN.js → agent-session-services-QANFGM2V.js} +14 -13
  222. package/dist/node-runtime/{builtin-extensions-7STLFW3A.js → builtin-extensions-SRCYQPZ6.js} +4 -3
  223. package/dist/node-runtime/{chunk-5OLJGVCB.js → chunk-3ONQTOMR.js} +2 -2
  224. package/dist/node-runtime/chunk-5ZH3ZFIZ.js +308 -0
  225. package/dist/node-runtime/{chunk-4SJWFTUP.js → chunk-7NBZ5P7I.js} +1 -1
  226. package/dist/node-runtime/chunk-A3KMVBZV.js +60 -0
  227. package/dist/node-runtime/{chunk-FLYMHKCS.js → chunk-BJ6H7DPI.js} +25 -25
  228. package/dist/node-runtime/{chunk-T5GM5BFH.js → chunk-BYQ2MOFI.js} +6 -6
  229. package/dist/node-runtime/{chunk-W7S2REEG.js → chunk-CZUBYPFP.js} +157 -74
  230. package/dist/node-runtime/{chunk-ZRDIMBEQ.js → chunk-D466UAID.js} +9 -6
  231. package/dist/node-runtime/{chunk-K72NVGUB.js → chunk-GT5F3OKM.js} +1 -1
  232. package/dist/node-runtime/chunk-H2BI7G7T.js +73 -0
  233. package/dist/node-runtime/{chunk-ISQDQIZN.js → chunk-HXJS2PJM.js} +2 -2
  234. package/dist/node-runtime/chunk-LISUTZS3.js +19 -0
  235. package/dist/node-runtime/{chunk-BKAZ6BKX.js → chunk-LOYUC2ID.js} +7 -7
  236. package/dist/node-runtime/{chunk-OTT6JMPU.js → chunk-LTYWTR3V.js} +1 -369
  237. package/dist/node-runtime/{chunk-5Q45AVQG.js → chunk-MW2XJZIK.js} +1 -1
  238. package/dist/node-runtime/{chunk-MUMMMTW4.js → chunk-N3PNL74S.js} +536 -265
  239. package/dist/node-runtime/{chunk-HQCKFM2O.js → chunk-VGYZ3APQ.js} +3 -0
  240. package/dist/node-runtime/{chunk-5NWQCSKR.js → chunk-VQ4UBWSA.js} +11 -1
  241. package/dist/node-runtime/{chunk-6SPPH4FY.js → chunk-VTGEKB7R.js} +4 -4
  242. package/dist/node-runtime/chunk-W3SILANP.js +24 -0
  243. package/dist/node-runtime/{chunk-J7QGQD45.js → chunk-WJVFOIB5.js} +1 -1
  244. package/dist/node-runtime/{chunk-JT6YCS5B.js → chunk-XAUQOKYK.js} +408 -45
  245. package/dist/node-runtime/{chunk-LCACDWHJ.js → chunk-XSRCAQK2.js} +13 -13
  246. package/dist/node-runtime/{chunk-TAP7QTUT.js → chunk-ZOIIMEN6.js} +24 -425
  247. package/dist/node-runtime/{chunk-MGSB2C3M.js → chunk-ZVSORYRM.js} +1 -1
  248. package/dist/node-runtime/{command-6UXQ6XZN.js → command-ZURZJDXF.js} +1 -1
  249. package/dist/node-runtime/{commands-LGR5VT5X.js → commands-BZGSLIP7.js} +3 -3
  250. package/dist/node-runtime/{customize-XEXL2DGQ.js → customize-LF5VST47.js} +1 -1
  251. package/dist/node-runtime/{direct-tool-executor-TDJS7TBD.js → direct-tool-executor-BSZDHIYR.js} +4 -4
  252. package/dist/node-runtime/{extract-IUCVZCWC.js → extract-XLQSJN4V.js} +2 -2
  253. package/dist/node-runtime/{gateway-3OLC4GQN.js → gateway-FWHRIBK5.js} +9 -9
  254. package/dist/node-runtime/{gemini-search-NCIDF7NE.js → gemini-search-U7SUMPQA.js} +1 -1
  255. package/dist/node-runtime/{gemini-url-context-OKIN7AIP.js → gemini-url-context-PXWCBQHK.js} +2 -2
  256. package/dist/node-runtime/index.js +34 -31
  257. package/dist/node-runtime/{init-EKE277AG.js → init-DVJUAOUO.js} +3 -3
  258. package/dist/node-runtime/{interactive-mode-S5M26CQ7.js → interactive-mode-BBASNWHN.js} +18 -15
  259. package/dist/node-runtime/lunr-computer-use-TJNDAMWM.js +135 -0
  260. package/dist/node-runtime/{lunr-cron-KKBOGAEF.js → lunr-cron-J64I72C6.js} +5 -5
  261. package/dist/node-runtime/main.js +22 -20
  262. package/dist/node-runtime/{package-manager-cli-C4EJOO5Q.js → package-manager-cli-VMYX4Y2S.js} +8 -7
  263. package/dist/node-runtime/{pi-intercom-EEMBGQID.js → pi-intercom-NV2LW6X7.js} +108 -87
  264. package/dist/node-runtime/{pi-mcp-adapter-DPTJGAAL.js → pi-mcp-adapter-JLB5YL2F.js} +6 -6
  265. package/dist/node-runtime/{pi-subagents-VKCLYIBY.js → pi-subagents-WEHV3W7H.js} +1267 -604
  266. package/dist/node-runtime/{pi-web-access-BV6DSZOP.js → pi-web-access-FN5YC5T6.js} +5 -5
  267. package/dist/node-runtime/{proxy-modes-R64LU6WZ.js → proxy-modes-OR7ISBXK.js} +7 -7
  268. package/dist/node-runtime/rpc-entry.js +22 -20
  269. package/dist/node-runtime/{runtime-bridges-UJ5WJJLN.js → runtime-bridges-2VQTLPOZ.js} +3 -5
  270. package/dist/node-runtime/{settings-manager-K6IPIQTI.js → settings-manager-3CCU326G.js} +3 -2
  271. package/dist/node-runtime/{subagent-executor-EFLTO32A.js → subagent-executor-CXKXQDHH.js} +186 -299
  272. package/dist/node-runtime/{update-cli-I6OVDRPL.js → update-cli-NM7B4CKL.js} +3 -2
  273. package/dist/node-runtime/{video-extract-ETA5RA7U.js → video-extract-OYT5WKS5.js} +2 -2
  274. package/dist/node-runtime/workflow-C26QCUTW.js +468 -0
  275. package/dist/node-runtime/{youtube-extract-SRVGNN26.js → youtube-extract-TQYKGFGS.js} +2 -2
  276. package/docs/computer-use.md +233 -268
  277. package/docs/features.md +22 -4
  278. package/docs/keybindings.md +3 -1
  279. package/docs/settings.md +3 -2
  280. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  281. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  282. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  283. package/examples/extensions/gondolin/package-lock.json +2 -2
  284. package/examples/extensions/gondolin/package.json +1 -1
  285. package/examples/extensions/sandbox/package-lock.json +2 -2
  286. package/examples/extensions/sandbox/package.json +1 -1
  287. package/examples/extensions/with-deps/package-lock.json +2 -2
  288. package/examples/extensions/with-deps/package.json +1 -1
  289. package/install-lock/package-lock.json +24 -24
  290. package/install-lock/package.json +2 -2
  291. package/npm-shrinkwrap.json +21 -21
  292. package/package.json +7 -7
  293. package/dist/builtin-extensions/lunr-settings-tools.d.ts +0 -4
  294. package/dist/builtin-extensions/lunr-settings-tools.d.ts.map +0 -1
  295. package/dist/builtin-extensions/lunr-settings-tools.js +0 -120
  296. package/dist/builtin-extensions/lunr-settings-tools.js.map +0 -1
  297. package/dist/core/settings-tools-bridge.d.ts +0 -35
  298. package/dist/core/settings-tools-bridge.d.ts.map +0 -1
  299. package/dist/core/settings-tools-bridge.js +0 -56
  300. package/dist/core/settings-tools-bridge.js.map +0 -1
  301. package/dist/node-runtime/chunk-EH2LJQPM.js +0 -64
  302. package/dist/node-runtime/image-resize-6ZPBFMWW.js +0 -11
  303. package/dist/node-runtime/lunr-computer-use-4X3KUNF4.js +0 -206
  304. package/dist/node-runtime/workflow-SA34S4VX.js +0 -325
  305. package/dist/node-runtime/{chunk-EHMBW7FA.js → chunk-VSELYKWU.js} +3 -3
  306. package/dist/node-runtime/{chunk-ZSEZY3II.js → chunk-VTPM5V35.js} +0 -0
  307. package/dist/node-runtime/{src-GPFAU3N6.js → src-BPQFJR76.js} +3 -3
@@ -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,14 +428,9 @@ 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;
409
- }
410
431
  function widgetAnimFrame(now = Date.now()) {
411
- return Math.floor(now / 80) % RUNNING_FRAMES.length;
432
+ const definition = selectedSubagentSpinner();
433
+ return Math.floor(now / definition.interval) % definition.frames.length;
412
434
  }
413
435
  function widgetStatusGlyph(job, theme, now = Date.now()) {
414
436
  if (job.status === "running")
@@ -589,7 +611,11 @@ function isDoneResult(result) {
589
611
  return result.exitCode === 0;
590
612
  }
591
613
  function workflowGraphHasStatus(details, statuses) {
592
- 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);
593
619
  }
594
620
  function buildChainRenderEntries(details, label) {
595
621
  if (details.mode !== "chain" || !label.hasParallelInChain || label.showActiveGroupOnly)
@@ -608,11 +634,20 @@ function buildChainRenderEntries(details, label) {
608
634
  continue;
609
635
  }
610
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);
611
641
  entries.push({
612
642
  kind: "result",
613
643
  resultIndex: index,
614
644
  rowNumber: index + 1,
615
- 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,
616
651
  });
617
652
  }
618
653
  }
@@ -953,20 +988,31 @@ function foregroundStyleWidgetDetails(job, theme, expanded, width) {
953
988
  }
954
989
  return lines;
955
990
  }
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
+ }
956
1002
  function compactJobProgress(job, step, now = Date.now()) {
957
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
+ };
1010
+ }
958
1011
  const startedAt = step?.startedAt ?? job.startedAt;
1012
+ if (startedAt === undefined)
1013
+ return { tokens, durationMs: 0 };
959
1014
  const endedAt = running ? now : step?.endedAt ?? step?.lastActivityAt ?? job.updatedAt ?? now;
960
- const durationMs = step?.durationMs !== undefined
961
- ? step.durationMs
962
- : startedAt !== undefined
963
- ? Math.max(0, endedAt - startedAt)
964
- : 0;
965
- return {
966
- toolCount: step?.toolCount ?? job.toolCount ?? 0,
967
- tokens: step?.tokens?.total ?? job.totalTokens?.total ?? 0,
968
- durationMs,
969
- };
1015
+ return { tokens, durationMs: Math.max(0, endedAt - startedAt) };
970
1016
  }
971
1017
  function compactJobLead(job, step) {
972
1018
  return compactRowLead({
@@ -977,26 +1023,19 @@ function compactJobLead(job, step) {
977
1023
  function compactJobLines(job, step, theme, width, now = Date.now()) {
978
1024
  const running = (step?.status ?? job.status) === "running";
979
1025
  const lead = compactJobLead(job, step);
980
- const modelBadge = formatModelSelection(step?.modelSelection, step?.model, step?.thinking);
981
- const permissionBadge = step?.permissions ? theme.fg("dim", step.permissions) : "";
1026
+ const modelBadge = formatCompactModelBadge(step?.modelSelection, step?.model);
982
1027
  const glyph = step
983
1028
  ? widgetStepGlyph(step.status, theme, running ? (widgetStepRunningSeed(step, step.index) ?? 0) + widgetAnimFrame(now) : widgetStepRunningSeed(step, step.index))
984
1029
  : widgetStatusGlyph(job, theme, now);
985
- const hang = formatCompactStatsHangLine(compactJobProgress(job, step, now), width, (s) => theme.fg("dim", s), " ⎿ ", now, running);
986
- return [
987
- truncLine(`${glyph} ${themeBold(theme, lead)}${modelBadge ? ` ${theme.fg("dim", "·")} ${theme.fg("dim", modelBadge)}` : ""}${permissionBadge ? ` ${theme.fg("dim", "·")} ${permissionBadge}` : ""}`, width),
988
- hang,
989
- ];
990
- }
991
- function buildSingleWidgetLines(job, theme, width, _expanded) {
992
- const now = Date.now();
993
- const steps = job.steps ?? [];
994
- if (steps.length <= 1)
995
- return compactJobLines(job, steps[0], theme, width, now);
996
- return steps.flatMap((step) => compactJobLines(job, step, theme, width, now));
997
- }
998
- function compactSingleWidgetLines(job, theme, width) {
999
- return buildSingleWidgetLines(job, theme, width, false);
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
+ })];
1000
1039
  }
1001
1040
  const RESERVED_NON_WIDGET_ROWS = 19;
1002
1041
  let widgetLayoutSession;
@@ -1018,35 +1057,6 @@ function widgetSessionMatches(expanded) {
1018
1057
  && widgetLayoutSession.rows === currentTerminalRows()
1019
1058
  && widgetLayoutSession.columns === currentTerminalColumns();
1020
1059
  }
1021
- function widgetHeaderCounts(jobs) {
1022
- return {
1023
- running: jobs.filter((job) => job.status === "running"),
1024
- queued: jobs.filter((job) => job.status === "queued"),
1025
- complete: jobs.filter((job) => job.status === "complete"),
1026
- failed: jobs.filter((job) => job.status === "failed"),
1027
- paused: jobs.filter((job) => job.status === "paused"),
1028
- stopped: jobs.filter((job) => job.status === "stopped"),
1029
- };
1030
- }
1031
- function buildSingleLineWidgetLines(jobs, theme, width) {
1032
- const counts = widgetHeaderCounts(jobs);
1033
- const hasActive = counts.running.length > 0 || counts.queued.length > 0;
1034
- const glyph = counts.running.length > 0 ? runningGlyph(widgetJobsRunningSeed(counts.running)) : hasActive ? "●" : "○";
1035
- const parts = [];
1036
- if (counts.running.length > 0)
1037
- parts.push(`${counts.running.length}/${jobs.length} running`);
1038
- if (counts.queued.length > 0)
1039
- parts.push(`${counts.queued.length} queued`);
1040
- if (counts.failed.length > 0)
1041
- parts.push(`${counts.failed.length} failed`);
1042
- if (counts.stopped.length > 0)
1043
- parts.push(`${counts.stopped.length} stopped`);
1044
- if (counts.paused.length > 0)
1045
- parts.push(`${counts.paused.length} paused`);
1046
- if (!hasActive && counts.complete.length > 0)
1047
- parts.push(`${counts.complete.length}/${jobs.length} done`);
1048
- return [truncLine(`${theme.fg(hasActive ? "accent" : "dim", glyph)} ${theme.fg(hasActive ? "accent" : "dim", "subagents")} (${parts.join(", ") || `${jobs.length} total`})`, width)];
1049
- }
1050
1060
  function orderedWidgetJobs(jobs) {
1051
1061
  return [
1052
1062
  ...jobs.filter((job) => job.status === "running"),
@@ -1054,124 +1064,6 @@ function orderedWidgetJobs(jobs) {
1054
1064
  ...jobs.filter((job) => job.status !== "running" && job.status !== "queued"),
1055
1065
  ];
1056
1066
  }
1057
- function progressiveJobKey(job) {
1058
- return job.asyncId;
1059
- }
1060
- function isProgressiveActiveJob(job) {
1061
- return job?.status === "running" || job?.status === "queued";
1062
- }
1063
- function selectProgressiveJobKeys(jobs, previousKeys, bodyRows) {
1064
- if (bodyRows <= 0)
1065
- return [];
1066
- const jobsByKey = new Map(jobs.map((job) => [progressiveJobKey(job), job]));
1067
- const selected = [];
1068
- const append = (key) => {
1069
- if (selected.includes(key) || !jobsByKey.has(key))
1070
- return;
1071
- selected.push(key);
1072
- };
1073
- for (const key of previousKeys) {
1074
- if (!isProgressiveActiveJob(jobsByKey.get(key)))
1075
- continue;
1076
- append(key);
1077
- if (selected.length >= bodyRows)
1078
- return selected;
1079
- }
1080
- for (const job of orderedWidgetJobs(jobs)) {
1081
- if (!isProgressiveActiveJob(job))
1082
- continue;
1083
- const key = progressiveJobKey(job);
1084
- append(key);
1085
- if (selected.length >= bodyRows)
1086
- break;
1087
- }
1088
- if (selected.length >= bodyRows)
1089
- return selected;
1090
- for (const key of previousKeys) {
1091
- if (isProgressiveActiveJob(jobsByKey.get(key)))
1092
- continue;
1093
- append(key);
1094
- if (selected.length >= bodyRows)
1095
- return selected;
1096
- }
1097
- for (const job of orderedWidgetJobs(jobs)) {
1098
- const key = progressiveJobKey(job);
1099
- append(key);
1100
- if (selected.length >= bodyRows)
1101
- break;
1102
- }
1103
- return selected;
1104
- }
1105
- function progressiveHeaderLine(jobs, theme, width) {
1106
- const counts = widgetHeaderCounts(jobs);
1107
- const hasActive = counts.running.length > 0 || counts.queued.length > 0;
1108
- const glyph = counts.running.length > 0 ? runningGlyph(widgetJobsRunningSeed(counts.running)) : hasActive ? "●" : "○";
1109
- const parts = [];
1110
- if (counts.running.length > 0)
1111
- parts.push(formatAgentRunningLabel(counts.running.length));
1112
- if (counts.queued.length > 0)
1113
- parts.push(`${counts.queued.length} queued`);
1114
- if (!hasActive) {
1115
- if (counts.failed.length > 0)
1116
- parts.push(`${counts.failed.length} failed`);
1117
- if (counts.stopped.length > 0)
1118
- parts.push(`${counts.stopped.length} stopped`);
1119
- if (counts.paused.length > 0)
1120
- parts.push(`${counts.paused.length} paused`);
1121
- if (counts.complete.length > 0)
1122
- parts.push(`${counts.complete.length}/${jobs.length} done`);
1123
- }
1124
- 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);
1125
- }
1126
- function progressiveJobLine(job, theme, width) {
1127
- const stats = widgetStats(job, theme);
1128
- const activity = widgetActivity(job);
1129
- const status = job.status === "complete" ? "done" : job.status;
1130
- const parts = [
1131
- themeBold(theme, widgetJobName(job)),
1132
- theme.fg("dim", status),
1133
- stats,
1134
- activity && activity.toLowerCase() !== status ? theme.fg("dim", activity) : "",
1135
- ].filter(Boolean);
1136
- return truncLine(` ${widgetStatusGlyph(job, theme)} ${parts.join(` ${theme.fg("dim", "·")} `)}`, width);
1137
- }
1138
- function progressiveHiddenLine(hiddenJobs, theme, width) {
1139
- const counts = widgetHeaderCounts(hiddenJobs);
1140
- const parts = [];
1141
- if (counts.running.length > 0)
1142
- parts.push(`${counts.running.length} running`);
1143
- if (counts.queued.length > 0)
1144
- parts.push(`${counts.queued.length} queued`);
1145
- const finished = counts.complete.length + counts.failed.length + counts.paused.length + counts.stopped.length;
1146
- if (finished > 0)
1147
- parts.push(`${finished} finished`);
1148
- return truncLine(theme.fg("dim", ` +${hiddenJobs.length} more${parts.length ? ` (${parts.join(", ")})` : ""}`), width);
1149
- }
1150
- function buildProgressiveWidgetLines(jobs, theme, width, lockedRows, previousKeys) {
1151
- const rowCount = Math.max(1, lockedRows);
1152
- if (rowCount === 1)
1153
- return { lines: buildSingleLineWidgetLines(jobs, theme, width), visibleJobKeys: [] };
1154
- const bodyRows = rowCount - 1;
1155
- let visibleJobKeys = selectProgressiveJobKeys(jobs, previousKeys, bodyRows);
1156
- const jobsByKey = new Map(jobs.map((job) => [progressiveJobKey(job), job]));
1157
- let visibleJobs = visibleJobKeys.map((key) => jobsByKey.get(key)).filter((job) => Boolean(job));
1158
- let hiddenJobs = jobs.filter((job) => !visibleJobKeys.includes(progressiveJobKey(job)));
1159
- const needsHiddenLine = hiddenJobs.length > 0;
1160
- if (needsHiddenLine && visibleJobs.length >= bodyRows && bodyRows > 0) {
1161
- visibleJobs = visibleJobs.slice(0, bodyRows - 1);
1162
- visibleJobKeys = visibleJobs.map(progressiveJobKey);
1163
- hiddenJobs = jobs.filter((job) => !visibleJobKeys.includes(progressiveJobKey(job)));
1164
- }
1165
- const lines = [
1166
- progressiveHeaderLine(jobs, theme, width),
1167
- ...visibleJobs.map((job) => progressiveJobLine(job, theme, width)),
1168
- ];
1169
- if (hiddenJobs.length > 0 && lines.length < rowCount)
1170
- lines.push(progressiveHiddenLine(hiddenJobs, theme, width));
1171
- while (lines.length < rowCount)
1172
- lines.push(" ");
1173
- return { lines: lines.slice(0, rowCount), visibleJobKeys };
1174
- }
1175
1067
  function collapsedWidgetLineBudget(rows) {
1176
1068
  return Math.max(10, Math.min(14, Math.floor(rows * 0.35)));
1177
1069
  }
@@ -1189,143 +1081,178 @@ function fitWidgetLineBudget(lines, theme, width, expanded) {
1189
1081
  : `… ${hiddenCount} lines hidden · ${liveDetailKeyText()} expands`;
1190
1082
  return [...lines.slice(0, visibleLines), truncLine(theme.fg("dim", hint), width)];
1191
1083
  }
1192
- function fitAdaptiveWidgetLines(jobs, lines, theme, width, expanded) {
1084
+ function fitAdaptiveWidgetLines(_jobs, lines, theme, width, expanded) {
1193
1085
  if (expanded) {
1194
1086
  resetWidgetLayoutSession();
1195
1087
  return fitWidgetLineBudget(lines, theme, width, true);
1196
1088
  }
1197
- const hasMatchingSession = widgetSessionMatches(expanded);
1198
1089
  const rows = currentTerminalRows();
1199
1090
  const columns = currentTerminalColumns();
1200
1091
  const availableRows = estimateAvailableWidgetRows();
1201
- if (hasMatchingSession && widgetLayoutSession?.tier === "single-line") {
1202
- return buildSingleLineWidgetLines(jobs, theme, width);
1203
- }
1204
- if (hasMatchingSession && widgetLayoutSession?.tier === "progressive" && widgetLayoutSession.lockedRows !== undefined) {
1205
- const rendered = buildProgressiveWidgetLines(jobs, theme, width, widgetLayoutSession.lockedRows, widgetLayoutSession.visibleJobKeys);
1206
- widgetLayoutSession.visibleJobKeys = rendered.visibleJobKeys;
1207
- return rendered.lines;
1208
- }
1209
1092
  if (lines.length <= availableRows) {
1210
- widgetLayoutSession = { expanded, rows, columns, tier: "full", visibleJobKeys: [] };
1093
+ widgetLayoutSession = { expanded, rows, columns, tier: "full" };
1211
1094
  return fitWidgetLineBudget(lines, theme, width, false);
1212
1095
  }
1213
- if (availableRows <= 2) {
1214
- widgetLayoutSession = { expanded, rows, columns, tier: "single-line", visibleJobKeys: [] };
1215
- 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));
1216
1127
  }
1217
- const lockedRows = Math.min(availableRows, collapsedWidgetLineBudget(rows));
1218
- const rendered = buildProgressiveWidgetLines(jobs, theme, width, lockedRows, []);
1219
- widgetLayoutSession = { expanded, rows, columns, tier: "progressive", lockedRows, visibleJobKeys: rendered.visibleJobKeys };
1220
- return rendered.lines;
1221
- }
1222
- function buildWidgetComponent(jobs, expanded) {
1223
- return (_tui, theme) => {
1224
- const width = getTermWidth();
1225
- const lines = expanded
1226
- ? buildWidgetLines(jobs, theme, width, true)
1227
- : jobs.length === 1
1228
- ? compactSingleWidgetLines(jobs[0], theme, width)
1229
- : buildWidgetLines(jobs, theme, width, false);
1230
- const container = new Container();
1231
- for (const line of fitAdaptiveWidgetLines(jobs, lines, theme, width, expanded))
1232
- container.addChild(new Text(line, 1, 0));
1233
- return container;
1234
- };
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;
1235
1135
  }
1236
- export function buildWidgetLines(jobs, theme, width = getTermWidth(), expanded = false) {
1237
- if (jobs.length === 0)
1238
- return [];
1239
- if (jobs.length === 1)
1240
- return buildSingleWidgetLines(jobs[0], theme, width, expanded);
1241
- const running = jobs.filter((job) => job.status === "running");
1242
- const queued = jobs.filter((job) => job.status === "queued");
1243
- const finished = jobs.filter((job) => job.status !== "running" && job.status !== "queued");
1136
+ export function buildWidgetLines(jobs, theme, width = getTermWidth(), expanded = false, now = Date.now()) {
1244
1137
  const lines = [];
1245
- const hasActive = running.length > 0 || queued.length > 0;
1246
- const headerGlyph = running.length > 0 ? runningGlyph(widgetJobsRunningSeed(running)) : hasActive ? "●" : "○";
1247
- lines.push(truncLine(`${theme.fg(hasActive ? "accent" : "dim", headerGlyph)} ${theme.fg(hasActive ? "accent" : "dim", "Async agents")} ${theme.fg("dim", "· background")}`, width));
1248
- const items = [];
1249
- let hiddenRunning = 0;
1250
- let hiddenFinished = 0;
1251
- let queuedSummaryShown = false;
1252
- let slots = MAX_WIDGET_JOBS;
1253
- for (const job of running) {
1254
- if (slots <= 0) {
1255
- hiddenRunning++;
1256
- 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));
1257
1148
  }
1258
- const stats = widgetStats(job, theme);
1259
- items.push([
1260
- `${widgetStatusGlyph(job, theme)} ${themeBold(theme, widgetJobName(job))}${stats ? ` ${theme.fg("dim", "·")} ${stats}` : ""}`,
1261
- ` ${theme.fg("dim", `⎿ ${widgetActivity(job)}`)}`,
1262
- ...widgetParallelAgentDetails(job, theme, expanded, width),
1263
- ]);
1264
- slots--;
1265
1149
  }
1266
- if (queued.length > 0 && slots > 0) {
1267
- items.push([`${theme.fg("muted", "◦")} ${theme.fg("dim", `${queued.length} queued`)}`]);
1268
- queuedSummaryShown = true;
1269
- 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();
1270
1170
  }
1271
- for (const job of finished) {
1272
- if (slots <= 0) {
1273
- hiddenFinished++;
1274
- continue;
1275
- }
1276
- const stats = widgetStats(job, theme);
1277
- items.push([
1278
- `${widgetStatusGlyph(job, theme)} ${themeBold(theme, widgetJobName(job))}${stats ? ` ${theme.fg("dim", "·")} ${stats}` : ""}`,
1279
- ` ${theme.fg("dim", `⎿ ${widgetActivity(job)}`)}`,
1280
- ...widgetParallelAgentDetails(job, theme, expanded, width),
1281
- ]);
1282
- slots--;
1171
+ setTheme(theme) {
1172
+ this.theme = theme;
1173
+ this.invalidate();
1283
1174
  }
1284
- const hiddenQueued = queued.length > 0 && !queuedSummaryShown ? queued.length : 0;
1285
- const hiddenTotal = hiddenRunning + hiddenFinished + hiddenQueued;
1286
- if (hiddenTotal > 0) {
1287
- const parts = [];
1288
- if (hiddenRunning > 0)
1289
- parts.push(`${hiddenRunning} running`);
1290
- if (hiddenQueued > 0)
1291
- parts.push(`${hiddenQueued} queued`);
1292
- if (hiddenFinished > 0)
1293
- parts.push(`${hiddenFinished} finished`);
1294
- items.push([theme.fg("dim", `+${hiddenTotal} more (${parts.join(", ")})`)]);
1175
+ setJobs(jobs) {
1176
+ this.jobs = jobs;
1177
+ this.invalidate();
1178
+ this.syncTimer();
1295
1179
  }
1296
- for (let i = 0; i < items.length; i++) {
1297
- const item = items[i];
1298
- const last = i === items.length - 1;
1299
- const branch = last ? "└─" : "├─";
1300
- const continuation = last ? " " : "│ ";
1301
- lines.push(truncLine(`${theme.fg("dim", branch)} ${item[0]}`, width));
1302
- for (const detail of item.slice(1)) {
1303
- lines.push(truncLine(`${theme.fg("dim", continuation)} ${detail}`, width));
1304
- }
1180
+ setExpanded(expanded) {
1181
+ if (this.expanded === expanded)
1182
+ return;
1183
+ this.expanded = expanded;
1184
+ this.invalidate();
1305
1185
  }
1306
- return lines;
1307
- }
1308
- let widgetPaintTimer;
1309
- let widgetPaintCtx;
1310
- export function clearWidgetPaintTimer() {
1311
- if (widgetPaintTimer) {
1312
- clearInterval(widgetPaintTimer);
1313
- widgetPaintTimer = undefined;
1186
+ setRequestRender(requestRender) {
1187
+ this.requestRender = requestRender;
1314
1188
  }
1315
- widgetPaintCtx = undefined;
1316
- }
1317
- function ensureWidgetPaintTimer(ctx, running) {
1318
- widgetPaintCtx = ctx;
1319
- if (!running || !ctx.hasUI) {
1320
- clearWidgetPaintTimer();
1321
- return;
1189
+ hasRunning() {
1190
+ return this.jobs.some((job) => job.status === "running");
1322
1191
  }
1323
- if (widgetPaintTimer)
1324
- return;
1325
- widgetPaintTimer = setInterval(() => {
1326
- widgetPaintCtx?.ui.requestRender?.();
1327
- }, 80);
1328
- widgetPaintTimer.unref?.();
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();
1329
1256
  }
1330
1257
  /**
1331
1258
  * Render the async jobs widget
@@ -1333,144 +1260,136 @@ function ensureWidgetPaintTimer(ctx, running) {
1333
1260
  export function renderWidget(ctx, jobs) {
1334
1261
  if (jobs.length === 0) {
1335
1262
  resetWidgetLayoutSession();
1336
- clearWidgetPaintTimer();
1263
+ disposeSubagentWidget();
1337
1264
  if (ctx.hasUI)
1338
1265
  ctx.ui.setWidget(WIDGET_KEY, undefined);
1339
1266
  return;
1340
1267
  }
1341
1268
  if (!ctx.hasUI)
1342
1269
  return;
1343
- ensureWidgetPaintTimer(ctx, jobs.some((job) => job.status === "running"));
1344
- 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;
1345
1296
  }
1346
1297
  function renderSingleCompact(d, r, theme, frame) {
1347
1298
  const output = r.truncation?.text || getSingleResultOutput(r);
1348
1299
  const progress = r.progress || r.progressSummary;
1349
1300
  const isRunning = r.progress?.status === "running";
1350
- const contextBadge = d.context === "fork" ? theme.fg("warning", " [fork]") : "";
1351
- // lunr: simplified collapsed row — glyph · task summary · agent type · runtime/tools/tokens stats.
1352
- const c = new Container();
1353
1301
  const width = getTermWidth() - 4;
1354
- // lunr: row line is a per-frame template so the running glyph animates in place (see subagentAnimSink).
1355
1302
  const lead = compactRowLead({ description: r.description ?? r.agent, task: r.task });
1356
- const modelBadge = formatModelSelection(r.modelSelection ?? progress?.modelSelection, r.model ?? progress?.model, r.thinking ?? progress?.thinking);
1357
- const permissionBadge = r.permissions ? theme.fg("dim", r.permissions) : "";
1358
- c.addChild(animatedLine((f, now) => {
1359
- const stats = formatProgressStats(theme, progress, true, { running: isRunning, terminal: !isRunning, now });
1360
- 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);
1361
- }, frame, isRunning));
1362
- if (isRunning && r.progress) {
1363
- c.addChild(animatedLine((_f, now) => formatCompactStatsHangLine(r.progress, width, (s) => theme.fg("dim", s), " ⎿ ", now, true), frame, true));
1364
- 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);
1331
+ }
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 }));
1365
1343
  }
1366
- c.addChild(new Text(truncLine(theme.fg("dim", ` ⎿ ${resultStatusLine(r, output)}`), width), 0, 0));
1367
- const preview = firstOutputLine(output);
1368
- if (preview && r.exitCode === 0 && !hasEmptyTextOutputWithoutOutputTarget(r.task, output)) {
1369
- c.addChild(new Text(truncLine(theme.fg("dim", ` ${preview}`), width), 0, 0));
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 });
1370
1351
  }
1371
- if (r.sessionFile)
1372
- c.addChild(new Text(truncLine(theme.fg("dim", ` session: ${shortenPath(r.sessionFile)}`), width), 0, 0));
1373
- return c;
1352
+ return entries;
1374
1353
  }
1375
1354
  function renderMultiCompact(d, theme, frame) {
1376
- const hasRunning = d.progress?.some((p) => p.status === "running")
1377
- || d.results.some((r) => r.progress?.status === "running")
1378
- || workflowGraphHasStatus(d, ["running"]);
1379
- const stopped = d.results.some((r) => r.stopped && r.progress?.status !== "running")
1380
- || workflowGraphHasStatus(d, ["stopped"]);
1381
- const failed = d.results.some((r) => !r.stopped && r.exitCode !== 0 && r.progress?.status !== "running")
1382
- || workflowGraphHasStatus(d, ["failed"]);
1383
- const paused = d.results.some((r) => (r.interrupted || r.detached) && r.progress?.status !== "running")
1384
- || workflowGraphHasStatus(d, ["paused", "detached"]);
1385
- let totalSummary = d.progressSummary;
1386
- if (!totalSummary) {
1387
- let sawProgress = false;
1388
- const summary = { toolCount: 0, tokens: 0, durationMs: 0, lastActivityAt: undefined };
1389
- for (const r of d.results) {
1390
- const prog = r.progress || r.progressSummary;
1391
- if (!prog)
1392
- continue;
1393
- sawProgress = true;
1394
- summary.toolCount += prog.toolCount;
1395
- summary.tokens += prog.tokens;
1396
- summary.durationMs = d.mode === "chain" ? summary.durationMs + prog.durationMs : Math.max(summary.durationMs, prog.durationMs);
1397
- if (prog.status === "running" && prog.lastActivityAt !== undefined) {
1398
- summary.lastActivityAt = Math.max(summary.lastActivityAt ?? 0, prog.lastActivityAt);
1399
- }
1400
- }
1401
- if (sawProgress)
1402
- totalSummary = summary;
1403
- }
1404
- const multiLabel = buildMultiProgressLabel(d, hasRunning);
1405
- const itemTitle = multiLabel.itemTitle;
1406
- const glyph = (f) => hasRunning
1407
- ? theme.fg("accent", runningGlyph(f !== undefined ? (runningSeed(progressRunningSeed(totalSummary), d.currentStepIndex) ?? 0) + f : runningSeed(progressRunningSeed(totalSummary), d.currentStepIndex)))
1408
- : stopped
1409
- ? theme.fg("warning", "■")
1410
- : failed
1411
- ? theme.fg("error", "✗")
1412
- : paused
1413
- ? theme.fg("warning", "■")
1414
- : theme.fg("success", "✓");
1415
- const contextBadge = d.context === "fork" ? theme.fg("warning", " [fork]") : "";
1416
1355
  const c = new Container();
1417
1356
  const width = getTermWidth() - 4;
1418
- // lunr: header line is a per-frame template so the running glyph animates in place (see subagentAnimSink).
1419
- c.addChild(animatedLine((f, now) => {
1420
- const stats = statJoin(theme, [multiLabel.headerLabel, formatProgressStats(theme, totalSummary, true, { running: hasRunning, terminal: !hasRunning, now }), formatTotalCostStat(d.totalCost)]);
1421
- return truncLine(`${glyph(f)} ${theme.fg("toolTitle", theme.bold(d.mode))}${contextBadge}${stats ? ` ${theme.fg("dim", "·")} ${stats}` : ""}`, width);
1422
- }, frame, hasRunning));
1423
- const useResultsDirectly = multiLabel.hasParallelInChain || !d.chainAgents?.length;
1424
- const displayStart = multiLabel.showActiveGroupOnly ? multiLabel.groupStartIndex : 0;
1425
- const displayEnd = multiLabel.showActiveGroupOnly ? multiLabel.groupEndIndex : (useResultsDirectly ? d.results.length : d.chainAgents.length);
1426
- const chainEntries = buildChainRenderEntries(d, multiLabel);
1427
- const renderEntries = chainEntries ?? Array.from({ length: displayEnd - displayStart }, (_, offset) => {
1428
- const i = displayStart + offset;
1429
- const r = d.results[i];
1430
- const fallbackLabel = itemTitle.toLowerCase();
1431
- const rowNumber = multiLabel.showActiveGroupOnly ? (i - multiLabel.groupStartIndex + 1) : (i + 1);
1432
- return { kind: "result", resultIndex: i, rowNumber, agentName: useResultsDirectly ? (r?.agent || `${fallbackLabel}-${rowNumber}`) : (d.chainAgents[i] || r?.agent || `${fallbackLabel}-${rowNumber}`) };
1433
- });
1434
- for (const entry of renderEntries) {
1435
- if (entry.kind === "placeholder") {
1436
- const glyph = widgetStepGlyph(entry.status, theme);
1437
- const statusLabel = widgetStepStatus(entry.status, theme);
1438
- c.addChild(new Text(truncLine(` ${glyph} ${entry.stepLabel}: ${themeBold(theme, entry.agentName)} ${theme.fg("dim", "·")} ${statusLabel}`, width), 0, 0));
1439
- if (entry.error)
1440
- c.addChild(new Text(truncLine(theme.fg("error", ` ⎿ Error: ${entry.error}`), width), 0, 0));
1441
- continue;
1442
- }
1443
- const i = entry.resultIndex;
1444
- const r = d.results[i];
1445
- const rowNumber = entry.rowNumber;
1446
- const agentName = entry.agentName;
1447
- if (!r) {
1448
- const pendingLabel = chainEntries ? resultRowLabel(d, multiLabel, i, rowNumber) : `${itemTitle} ${rowNumber}`;
1449
- c.addChild(new Text(truncLine(theme.fg("dim", ` ◦ ${pendingLabel}: ${agentName} · pending`), width), 0, 0));
1450
- continue;
1451
- }
1452
- const output = getSingleResultOutput(r);
1453
- const progressFromArray = d.progress?.find((p) => p.index === i) || d.progress?.find((p) => p.agent === r.agent && p.status === "running");
1454
- const rProg = r.progress || progressFromArray || r.progressSummary;
1455
- const rRunning = rProg && "status" in rProg && rProg.status === "running";
1456
- const rPending = rProg && "status" in rProg && rProg.status === "pending";
1457
- const pendingLabel = rPending ? ` ${theme.fg("dim", "· pending")}` : "";
1458
- // lunr: simplified collapsed row — glyph · task summary · agent type · runtime/tools/tokens stats.
1459
- // lunr: row line is a per-frame template so the running glyph animates in place (see subagentAnimSink).
1460
- const lead = compactRowLead({ description: r.description ?? agentName, task: r.task });
1461
- const permissionBadge = r.permissions ? theme.fg("dim", r.permissions) : "";
1462
- 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));
1463
- c.addChild(animatedLine((f, now) => {
1464
- const glyph = rPending ? theme.fg("dim", "◦") : resultGlyph(r, output, theme, rRunning, progressRunningSeed(rProg), f);
1465
- const stepStats = formatProgressStats(theme, rProg, true, { running: !!rRunning, terminal: !rRunning && !rPending, now });
1466
- 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);
1467
- }, frame, !!rRunning));
1468
- if (rRunning && rProg && "status" in rProg) {
1469
- c.addChild(animatedLine((_f, now) => formatCompactStatsHangLine(rProg, width, (s) => theme.fg("dim", s), " ⎿ ", now, true), frame, true));
1470
- }
1471
- else if (!rPending && (r.exitCode !== 0 || r.interrupted || r.detached || hasEmptyTextOutputWithoutOutputTarget(r.task, output))) {
1472
- c.addChild(new Text(truncLine(theme.fg(r.exitCode !== 0 ? "error" : "dim", ` ⎿ ${resultStatusLine(r, output)}`), width), 0, 0));
1473
- }
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));
1474
1393
  }
1475
1394
  return c;
1476
1395
  }
@@ -1479,7 +1398,9 @@ function renderMultiCompact(d, theme, frame) {
1479
1398
  */
1480
1399
  export function renderSubagentResult(result, options, theme, frame) {
1481
1400
  const d = result.details;
1482
- 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)) {
1483
1404
  const t = result.content[0];
1484
1405
  const text = t?.type === "text" ? t.text : "(no output)";
1485
1406
  const contextPrefix = d?.context === "fork" ? `${theme.fg("warning", "[fork]")} ` : "";
@@ -1524,6 +1445,9 @@ export function renderSubagentResult(result, options, theme, frame) {
1524
1445
  ? r.task
1525
1446
  : `${r.task.slice(0, taskMaxLen)}...`;
1526
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
+ }
1527
1451
  c.addChild(new Spacer(1));
1528
1452
  if (isRunning && r.progress) {
1529
1453
  const progressSnapshotNow = snapshotNowForProgress(r.progress);
@@ -1596,6 +1520,7 @@ export function renderSubagentResult(result, options, theme, frame) {
1596
1520
  const hasWorkflowFailure = workflowGraphHasStatus(d, ["failed"]);
1597
1521
  const hasWorkflowStop = d.results.some((r) => r.stopped && r.progress?.status !== "running") || workflowGraphHasStatus(d, ["stopped"]);
1598
1522
  const hasWorkflowPause = workflowGraphHasStatus(d, ["paused", "detached"]);
1523
+ const hasWorkflowPending = workflowGraphHasStatus(d, ["pending"]);
1599
1524
  const icon = hasRunning
1600
1525
  ? theme.fg("warning", "running")
1601
1526
  : hasEmptyWithoutTarget
@@ -1606,9 +1531,11 @@ export function renderSubagentResult(result, options, theme, frame) {
1606
1531
  ? theme.fg("warning", "stopped")
1607
1532
  : hasWorkflowPause
1608
1533
  ? theme.fg("warning", "paused")
1609
- : ok === d.results.length
1610
- ? theme.fg("success", "ok")
1611
- : 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");
1612
1539
  const totalSummary = d.progressSummary ||
1613
1540
  d.results.reduce((acc, r) => {
1614
1541
  const prog = r.progress || r.progressSummary;
@@ -1670,16 +1597,40 @@ export function renderSubagentResult(result, options, theme, frame) {
1670
1597
  if (chainVis) {
1671
1598
  c.addChild(new Text(fit(` ${chainVis}`), 0, 0));
1672
1599
  }
1673
- const useResultsDirectly = multiLabel.hasParallelInChain || !d.chainAgents?.length;
1674
- const displayStart = multiLabel.showActiveGroupOnly ? multiLabel.groupStartIndex : 0;
1675
- const displayEnd = multiLabel.showActiveGroupOnly ? multiLabel.groupEndIndex : (useResultsDirectly ? d.results.length : d.chainAgents.length);
1676
1600
  const chainEntries = buildChainRenderEntries(d, multiLabel);
1677
- const renderEntries = chainEntries ?? Array.from({ length: displayEnd - displayStart }, (_, offset) => {
1678
- const i = displayStart + offset;
1679
- const r = d.results[i];
1680
- const rowNumber = multiLabel.showActiveGroupOnly ? (i - multiLabel.groupStartIndex + 1) : (i + 1);
1681
- 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
+ };
1682
1632
  });
1633
+ const renderEntries = chainEntries ?? fallbackEntries;
1683
1634
  c.addChild(new Spacer(1));
1684
1635
  for (const entry of renderEntries) {
1685
1636
  if (entry.kind === "placeholder") {
@@ -1692,13 +1643,16 @@ export function renderSubagentResult(result, options, theme, frame) {
1692
1643
  continue;
1693
1644
  }
1694
1645
  const i = entry.resultIndex;
1695
- const r = d.results[i];
1646
+ const r = resultAtFlatIndex(d, i);
1696
1647
  const rowNumber = entry.rowNumber;
1697
1648
  const agentName = entry.agentName;
1698
1649
  if (!r) {
1699
- const pendingLabel = chainEntries ? resultRowLabel(d, multiLabel, i, rowNumber) : `${itemTitle} ${rowNumber}`;
1700
- c.addChild(new Text(fit(theme.fg("dim", ` ${pendingLabel}: ${agentName}`)), 0, 0));
1701
- 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));
1702
1656
  c.addChild(new Spacer(1));
1703
1657
  continue;
1704
1658
  }
@@ -1729,6 +1683,9 @@ export function renderSubagentResult(result, options, theme, frame) {
1729
1683
  ? r.task
1730
1684
  : `${r.task.slice(0, taskMaxLen)}...`;
1731
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
+ }
1732
1689
  if (r.skills?.length) {
1733
1690
  c.addChild(new Text(fit(theme.fg("dim", ` skills: ${r.skills.join(", ")}`)), 0, 0));
1734
1691
  }