@ashx-j/lunr 0.2.18 → 0.2.20

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 (190) hide show
  1. package/CHANGELOG.md +31 -1
  2. package/README.md +2 -2
  3. package/dist/builtin-extensions/ashxj-tui.d.ts +2 -2
  4. package/dist/builtin-extensions/ashxj-tui.d.ts.map +1 -1
  5. package/dist/builtin-extensions/ashxj-tui.js +11 -8
  6. package/dist/builtin-extensions/ashxj-tui.js.map +1 -1
  7. package/dist/builtin-extensions/index.d.ts.map +1 -1
  8. package/dist/builtin-extensions/index.js +0 -2
  9. package/dist/builtin-extensions/index.js.map +1 -1
  10. package/dist/builtin-extensions/pi-intercom/broker/spawn.d.ts +6 -4
  11. package/dist/builtin-extensions/pi-intercom/broker/spawn.d.ts.map +1 -1
  12. package/dist/builtin-extensions/pi-intercom/broker/spawn.js +93 -49
  13. package/dist/builtin-extensions/pi-intercom/broker/spawn.js.map +1 -1
  14. package/dist/builtin-extensions/pi-intercom/index.d.ts.map +1 -1
  15. package/dist/builtin-extensions/pi-intercom/index.js +351 -351
  16. package/dist/builtin-extensions/pi-intercom/index.js.map +1 -1
  17. package/dist/builtin-extensions/pi-subagents/src/extension/index.d.ts +2 -1
  18. package/dist/builtin-extensions/pi-subagents/src/extension/index.d.ts.map +1 -1
  19. package/dist/builtin-extensions/pi-subagents/src/extension/index.js +80 -43
  20. package/dist/builtin-extensions/pi-subagents/src/extension/index.js.map +1 -1
  21. package/dist/builtin-extensions/pi-subagents/src/extension/schemas.d.ts +18 -8
  22. package/dist/builtin-extensions/pi-subagents/src/extension/schemas.d.ts.map +1 -1
  23. package/dist/builtin-extensions/pi-subagents/src/extension/schemas.js +36 -11
  24. package/dist/builtin-extensions/pi-subagents/src/extension/schemas.js.map +1 -1
  25. package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.d.ts +4 -3
  26. package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.d.ts.map +1 -1
  27. package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.js +21 -12
  28. package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.js.map +1 -1
  29. package/dist/builtin-extensions/pi-subagents/src/intercom/native-supervisor-channel.d.ts +7 -1
  30. package/dist/builtin-extensions/pi-subagents/src/intercom/native-supervisor-channel.d.ts.map +1 -1
  31. package/dist/builtin-extensions/pi-subagents/src/intercom/native-supervisor-channel.js +225 -15
  32. package/dist/builtin-extensions/pi-subagents/src/intercom/native-supervisor-channel.js.map +1 -1
  33. package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-ask.d.ts +29 -0
  34. package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-ask.d.ts.map +1 -0
  35. package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-ask.js +179 -0
  36. package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-ask.js.map +1 -0
  37. package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-questions.d.ts +89 -0
  38. package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-questions.d.ts.map +1 -0
  39. package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-questions.js +541 -0
  40. package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-questions.js.map +1 -0
  41. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-execution.d.ts +9 -1
  42. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-execution.d.ts.map +1 -1
  43. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-execution.js +34 -9
  44. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-execution.js.map +1 -1
  45. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-job-tracker.d.ts.map +1 -1
  46. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-job-tracker.js +1 -2
  47. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-job-tracker.js.map +1 -1
  48. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-resume.d.ts +2 -1
  49. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-resume.d.ts.map +1 -1
  50. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-resume.js +35 -8
  51. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-resume.js.map +1 -1
  52. package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.d.ts +1 -1
  53. package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.d.ts.map +1 -1
  54. package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.js +3 -3
  55. package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.js.map +1 -1
  56. package/dist/builtin-extensions/pi-subagents/src/runs/background/result-watcher.d.ts +1 -0
  57. package/dist/builtin-extensions/pi-subagents/src/runs/background/result-watcher.d.ts.map +1 -1
  58. package/dist/builtin-extensions/pi-subagents/src/runs/background/result-watcher.js +54 -38
  59. package/dist/builtin-extensions/pi-subagents/src/runs/background/result-watcher.js.map +1 -1
  60. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-wait.d.ts +3 -6
  61. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-wait.d.ts.map +1 -1
  62. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-wait.js +64 -5
  63. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-wait.js.map +1 -1
  64. package/dist/builtin-extensions/pi-subagents/src/runs/background/wait-tool.d.ts.map +1 -1
  65. package/dist/builtin-extensions/pi-subagents/src/runs/background/wait-tool.js +1 -0
  66. package/dist/builtin-extensions/pi-subagents/src/runs/background/wait-tool.js.map +1 -1
  67. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.d.ts.map +1 -1
  68. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.js +21 -8
  69. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.js.map +1 -1
  70. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.d.ts.map +1 -1
  71. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.js +62 -16
  72. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.js.map +1 -1
  73. package/dist/builtin-extensions/pi-subagents/src/runs/shared/acceptance.d.ts +2 -0
  74. package/dist/builtin-extensions/pi-subagents/src/runs/shared/acceptance.d.ts.map +1 -1
  75. package/dist/builtin-extensions/pi-subagents/src/runs/shared/acceptance.js +75 -18
  76. package/dist/builtin-extensions/pi-subagents/src/runs/shared/acceptance.js.map +1 -1
  77. package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.d.ts +13 -1
  78. package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.d.ts.map +1 -1
  79. package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.js +67 -11
  80. package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.js.map +1 -1
  81. package/dist/builtin-extensions/pi-subagents/src/runs/shared/pi-args.d.ts.map +1 -1
  82. package/dist/builtin-extensions/pi-subagents/src/runs/shared/pi-args.js +5 -2
  83. package/dist/builtin-extensions/pi-subagents/src/runs/shared/pi-args.js.map +1 -1
  84. package/dist/builtin-extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.d.ts.map +1 -1
  85. package/dist/builtin-extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.js +13 -3
  86. package/dist/builtin-extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.js.map +1 -1
  87. package/dist/builtin-extensions/pi-subagents/src/shared/child-spec.d.ts +3 -0
  88. package/dist/builtin-extensions/pi-subagents/src/shared/child-spec.d.ts.map +1 -1
  89. package/dist/builtin-extensions/pi-subagents/src/shared/child-spec.js +68 -11
  90. package/dist/builtin-extensions/pi-subagents/src/shared/child-spec.js.map +1 -1
  91. package/dist/builtin-extensions/pi-subagents/src/shared/formatters.d.ts +12 -1
  92. package/dist/builtin-extensions/pi-subagents/src/shared/formatters.d.ts.map +1 -1
  93. package/dist/builtin-extensions/pi-subagents/src/shared/formatters.js +21 -2
  94. package/dist/builtin-extensions/pi-subagents/src/shared/formatters.js.map +1 -1
  95. package/dist/builtin-extensions/pi-subagents/src/shared/types.d.ts +16 -4
  96. package/dist/builtin-extensions/pi-subagents/src/shared/types.d.ts.map +1 -1
  97. package/dist/builtin-extensions/pi-subagents/src/shared/types.js +1 -1
  98. package/dist/builtin-extensions/pi-subagents/src/shared/types.js.map +1 -1
  99. package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.d.ts +2 -0
  100. package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.d.ts.map +1 -1
  101. package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.js +24 -6
  102. package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.js.map +1 -1
  103. package/dist/builtin-extensions/pi-subagents/src/tui/render.d.ts +44 -4
  104. package/dist/builtin-extensions/pi-subagents/src/tui/render.d.ts.map +1 -1
  105. package/dist/builtin-extensions/pi-subagents/src/tui/render.js +227 -133
  106. package/dist/builtin-extensions/pi-subagents/src/tui/render.js.map +1 -1
  107. package/dist/builtin-extensions/pi-subagents/src/watchdog/register-main.d.ts.map +1 -1
  108. package/dist/builtin-extensions/pi-subagents/src/watchdog/register-main.js +1 -1
  109. package/dist/builtin-extensions/pi-subagents/src/watchdog/register-main.js.map +1 -1
  110. package/dist/builtin-extensions/pi-subagents/src/watchdog/tool-actions.d.ts +2 -13
  111. package/dist/builtin-extensions/pi-subagents/src/watchdog/tool-actions.d.ts.map +1 -1
  112. package/dist/builtin-extensions/pi-subagents/src/watchdog/tool-actions.js +5 -91
  113. package/dist/builtin-extensions/pi-subagents/src/watchdog/tool-actions.js.map +1 -1
  114. package/dist/core/permissions.d.ts +1 -0
  115. package/dist/core/permissions.d.ts.map +1 -1
  116. package/dist/core/permissions.js +8 -4
  117. package/dist/core/permissions.js.map +1 -1
  118. package/dist/core/plan-mode.d.ts.map +1 -1
  119. package/dist/core/plan-mode.js +0 -5
  120. package/dist/core/plan-mode.js.map +1 -1
  121. package/dist/core/runtime-bridges.d.ts.map +1 -1
  122. package/dist/core/runtime-bridges.js +0 -2
  123. package/dist/core/runtime-bridges.js.map +1 -1
  124. package/dist/core/subagent-cancellation.d.ts +21 -0
  125. package/dist/core/subagent-cancellation.d.ts.map +1 -0
  126. package/dist/core/subagent-cancellation.js +53 -0
  127. package/dist/core/subagent-cancellation.js.map +1 -0
  128. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  129. package/dist/modes/interactive/components/assistant-message.js +12 -18
  130. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  131. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  132. package/dist/modes/interactive/components/tool-execution.js +12 -0
  133. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  134. package/dist/modes/interactive/interactive-mode.d.ts +1 -2
  135. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  136. package/dist/modes/interactive/interactive-mode.js +29 -22
  137. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  138. package/dist/node-runtime/{agent-session-services-35WNVGMR.js → agent-session-services-75JKASCW.js} +3 -3
  139. package/dist/node-runtime/{builtin-extensions-QATGXENO.js → builtin-extensions-X4JMM4ZS.js} +3 -3
  140. package/dist/node-runtime/{chunk-XATUM2HK.js → chunk-25I2BHAA.js} +1 -1
  141. package/dist/node-runtime/{chunk-MCUNIRD5.js → chunk-46ECNOLF.js} +477 -246
  142. package/dist/node-runtime/{chunk-J26TSGDL.js → chunk-6N22HULO.js} +8 -5
  143. package/dist/node-runtime/{chunk-NI6OTSBH.js → chunk-AL2FMKKM.js} +7 -7
  144. package/dist/node-runtime/chunk-AOFXZQKA.js +24 -0
  145. package/dist/node-runtime/chunk-BBUVIEZB.js +51 -0
  146. package/dist/node-runtime/{chunk-EBF6COVM.js → chunk-ELWEXVO5.js} +7 -7
  147. package/dist/node-runtime/{chunk-R5EDISSV.js → chunk-JHYKXIMM.js} +5 -2
  148. package/dist/node-runtime/{chunk-ATGA2WLC.js → chunk-JYNNB7DU.js} +397 -34
  149. package/dist/node-runtime/{chunk-ZBV7FAHG.js → chunk-K3646JTM.js} +17 -118
  150. package/dist/node-runtime/{chunk-PNJSG3IZ.js → chunk-LTYWTR3V.js} +1 -369
  151. package/dist/node-runtime/{chunk-G4P75AIS.js → chunk-QKFMBRAL.js} +47 -54
  152. package/dist/node-runtime/cli-runtime.js +1 -1
  153. package/dist/node-runtime/{command-AAV3YRR5.js → command-RBTRL55A.js} +1 -1
  154. package/dist/node-runtime/{gateway-OAC4OBBL.js → gateway-L4ANRTVE.js} +2 -2
  155. package/dist/node-runtime/index.js +10 -9
  156. package/dist/node-runtime/{interactive-mode-2SZUO53H.js → interactive-mode-HPUNH7SV.js} +5 -4
  157. package/dist/node-runtime/{interactive-view-S6J3QHEF.js → interactive-view-ILS6TAN5.js} +1 -1
  158. package/dist/node-runtime/{lunr-cron-AUUYP4N4.js → lunr-cron-NNYTWTGF.js} +2 -2
  159. package/dist/node-runtime/main.js +8 -8
  160. package/dist/node-runtime/{pi-intercom-EEMBGQID.js → pi-intercom-DDQMRNPJ.js} +96 -76
  161. package/dist/node-runtime/{pi-subagents-7YJ3I4VE.js → pi-subagents-T5WMMLBB.js} +1040 -318
  162. package/dist/node-runtime/rpc-entry.js +8 -8
  163. package/dist/node-runtime/{runtime-bridges-3RKBDLNA.js → runtime-bridges-NJQERQ72.js} +2 -4
  164. package/dist/node-runtime/{subagent-executor-5Q5A4HJ2.js → subagent-executor-SRFC26SJ.js} +168 -249
  165. package/docs/features.md +17 -3
  166. package/docs/keybindings.md +3 -1
  167. package/docs/settings.md +1 -1
  168. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  169. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  170. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  171. package/examples/extensions/gondolin/package-lock.json +2 -2
  172. package/examples/extensions/gondolin/package.json +1 -1
  173. package/examples/extensions/sandbox/package-lock.json +2 -2
  174. package/examples/extensions/sandbox/package.json +1 -1
  175. package/examples/extensions/with-deps/package-lock.json +2 -2
  176. package/examples/extensions/with-deps/package.json +1 -1
  177. package/package.json +4 -4
  178. package/dist/builtin-extensions/lunr-settings-tools.d.ts +0 -4
  179. package/dist/builtin-extensions/lunr-settings-tools.d.ts.map +0 -1
  180. package/dist/builtin-extensions/lunr-settings-tools.js +0 -120
  181. package/dist/builtin-extensions/lunr-settings-tools.js.map +0 -1
  182. package/dist/core/settings-tools-bridge.d.ts +0 -35
  183. package/dist/core/settings-tools-bridge.d.ts.map +0 -1
  184. package/dist/core/settings-tools-bridge.js +0 -56
  185. package/dist/core/settings-tools-bridge.js.map +0 -1
  186. package/dist/modes/interactive/injected-context.d.ts +0 -2
  187. package/dist/modes/interactive/injected-context.d.ts.map +0 -1
  188. package/dist/modes/interactive/injected-context.js +0 -7
  189. package/dist/modes/interactive/injected-context.js.map +0 -1
  190. package/dist/node-runtime/chunk-3NMWLTPV.js +0 -64
@@ -6,7 +6,7 @@ import { getMarkdownTheme } from "../../../../modes/interactive/theme/theme.js";
6
6
  import { keyText } from "../../../../modes/interactive/components/keybinding-hints.js";
7
7
  import { Container, Markdown, Spacer, Text, visibleWidth } from "@ashx-j/lunr-tui";
8
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 { formatTokens, formatUsage, formatDuration, formatModelSelection, formatCompactModelBadge, formatToolCall, shortenPath } from "../shared/formatters.js";
10
10
  import { sanitizeChildDescription } from "../shared/child-spec.js";
11
11
  import { getDisplayItems, getSingleResultOutput } from "../shared/utils.js";
12
12
  import { flatToLogicalStepIndex } from "../runs/background/parallel-groups.js";
@@ -202,6 +202,20 @@ function statJoin(theme, parts) {
202
202
  function formatTokenStat(tokens) {
203
203
  return `${formatTokens(tokens)} token`;
204
204
  }
205
+ function usageTokenTotal(usage) {
206
+ if (!usage)
207
+ return 0;
208
+ return (usage.input ?? 0) + (usage.output ?? 0) + (usage.cacheRead ?? 0) + (usage.cacheWrite ?? 0);
209
+ }
210
+ function compactResultTokens(result) {
211
+ const progress = result.progress || result.progressSummary;
212
+ if (progress && progress.tokens > 0)
213
+ return progress.tokens;
214
+ const fromUsage = usageTokenTotal(result.usage);
215
+ if (fromUsage > 0)
216
+ return fromUsage;
217
+ return progress?.tokens ?? 0;
218
+ }
205
219
  function formatToolUseStat(count) {
206
220
  return `${count} tool use${count === 1 ? "" : "s"}`;
207
221
  }
@@ -220,9 +234,10 @@ function formatTotalCostStat(totalCost) {
220
234
  function liveDurationMs(progress, running, now) {
221
235
  if (!progress)
222
236
  return 0;
237
+ const durationMs = progress.durationMs ?? 0;
223
238
  if (!running || progress.lastActivityAt === undefined)
224
- return progress.durationMs;
225
- return progress.durationMs + Math.max(0, now - progress.lastActivityAt);
239
+ return durationMs;
240
+ return durationMs + Math.max(0, now - progress.lastActivityAt);
226
241
  }
227
242
  function formatProgressStats(theme, progress, includeDuration = true, options = {}) {
228
243
  if (!progress)
@@ -299,17 +314,18 @@ function resultGlyph(result, output, theme, running = result.progress?.status ==
299
314
  return theme.fg("warning", "✓");
300
315
  return theme.fg("success", "✓");
301
316
  }
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);
317
+ function formatCompactRowStats(tokens, durationMs) {
318
+ return `${formatTokenStat(tokens)} · ${durationMs > 0 ? formatDuration(durationMs) : "0ms"}`;
319
+ }
320
+ /** Unified compact row: glyph description · tier|model · tokens · time. */
321
+ export function formatCompactSubagentRow(theme, width, parts) {
322
+ const stats = formatCompactRowStats(parts.tokens, parts.durationMs);
307
323
  const body = [
308
- formatToolUseStat(toolCount),
309
- formatTokenStat(tokens),
310
- durationMs > 0 ? formatDuration(durationMs) : "0ms",
311
- ].join(" · ");
312
- return truncLine(paint(`${prefix}${body}`), width);
324
+ `${parts.prefix ?? ""}${parts.glyph} ${themeBold(theme, parts.description)}`,
325
+ parts.modelBadge ? theme.fg("dim", parts.modelBadge) : "",
326
+ theme.fg("dim", stats),
327
+ ].filter(Boolean).join(` ${theme.fg("dim", "·")} `);
328
+ return truncLine(body, width);
313
329
  }
314
330
  export function widgetRenderKey(job) {
315
331
  return JSON.stringify({
@@ -955,18 +971,18 @@ function foregroundStyleWidgetDetails(job, theme, expanded, width) {
955
971
  }
956
972
  function compactJobProgress(job, step, now = Date.now()) {
957
973
  const running = (step?.status ?? job.status) === "running";
974
+ const tokens = step?.tokens?.total ?? job.totalTokens?.total ?? 0;
975
+ if (step?.durationMs !== undefined) {
976
+ return {
977
+ tokens,
978
+ durationMs: liveDurationMs({ durationMs: step.durationMs, lastActivityAt: step.lastActivityAt }, running, now),
979
+ };
980
+ }
958
981
  const startedAt = step?.startedAt ?? job.startedAt;
982
+ if (startedAt === undefined)
983
+ return { tokens, durationMs: 0 };
959
984
  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
- };
985
+ return { tokens, durationMs: Math.max(0, endedAt - startedAt) };
970
986
  }
971
987
  function compactJobLead(job, step) {
972
988
  return compactRowLead({
@@ -974,29 +990,42 @@ function compactJobLead(job, step) {
974
990
  task: step?.description ?? step?.agent,
975
991
  }) || widgetJobName(job);
976
992
  }
993
+ function activeJobStep(job) {
994
+ const steps = job.steps ?? [];
995
+ return steps.find((step) => step.status === "running")
996
+ ?? steps.find((step) => step.status === "pending" || step.status === "queued")
997
+ ?? steps[steps.length - 1];
998
+ }
999
+ function compactJobChildRows(job, theme, width, now = Date.now()) {
1000
+ const steps = job.steps ?? [];
1001
+ if (steps.length <= 1)
1002
+ return compactJobLines(job, steps[0], theme, width, now);
1003
+ return steps.flatMap((step) => compactJobLines(job, step, theme, width, now));
1004
+ }
977
1005
  function compactJobLines(job, step, theme, width, now = Date.now()) {
978
1006
  const running = (step?.status ?? job.status) === "running";
979
1007
  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) : "";
1008
+ const modelBadge = formatCompactModelBadge(step?.modelSelection, step?.model);
982
1009
  const glyph = step
983
1010
  ? widgetStepGlyph(step.status, theme, running ? (widgetStepRunningSeed(step, step.index) ?? 0) + widgetAnimFrame(now) : widgetStepRunningSeed(step, step.index))
984
1011
  : 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();
1012
+ const progress = compactJobProgress(job, step, now);
1013
+ return [formatCompactSubagentRow(theme, width, {
1014
+ glyph,
1015
+ description: lead,
1016
+ modelBadge,
1017
+ tokens: progress.tokens,
1018
+ durationMs: progress.durationMs,
1019
+ })];
1020
+ }
1021
+ function buildSingleWidgetLines(job, theme, width, _expanded, now = Date.now()) {
993
1022
  const steps = job.steps ?? [];
994
1023
  if (steps.length <= 1)
995
1024
  return compactJobLines(job, steps[0], theme, width, now);
996
1025
  return steps.flatMap((step) => compactJobLines(job, step, theme, width, now));
997
1026
  }
998
- function compactSingleWidgetLines(job, theme, width) {
999
- return buildSingleWidgetLines(job, theme, width, false);
1027
+ function compactSingleWidgetLines(job, theme, width, now = Date.now()) {
1028
+ return buildSingleWidgetLines(job, theme, width, false, now);
1000
1029
  }
1001
1030
  const RESERVED_NON_WIDGET_ROWS = 19;
1002
1031
  let widgetLayoutSession;
@@ -1031,7 +1060,9 @@ function widgetHeaderCounts(jobs) {
1031
1060
  function buildSingleLineWidgetLines(jobs, theme, width) {
1032
1061
  const counts = widgetHeaderCounts(jobs);
1033
1062
  const hasActive = counts.running.length > 0 || counts.queued.length > 0;
1034
- const glyph = counts.running.length > 0 ? runningGlyph(widgetJobsRunningSeed(counts.running)) : hasActive ? "●" : "○";
1063
+ const glyph = counts.running.length > 0
1064
+ ? runningGlyph((widgetJobsRunningSeed(counts.running) ?? 0) + widgetAnimFrame())
1065
+ : hasActive ? "●" : "○";
1035
1066
  const parts = [];
1036
1067
  if (counts.running.length > 0)
1037
1068
  parts.push(`${counts.running.length}/${jobs.length} running`);
@@ -1105,7 +1136,9 @@ function selectProgressiveJobKeys(jobs, previousKeys, bodyRows) {
1105
1136
  function progressiveHeaderLine(jobs, theme, width) {
1106
1137
  const counts = widgetHeaderCounts(jobs);
1107
1138
  const hasActive = counts.running.length > 0 || counts.queued.length > 0;
1108
- const glyph = counts.running.length > 0 ? runningGlyph(widgetJobsRunningSeed(counts.running)) : hasActive ? "●" : "○";
1139
+ const glyph = counts.running.length > 0
1140
+ ? runningGlyph((widgetJobsRunningSeed(counts.running) ?? 0) + widgetAnimFrame())
1141
+ : hasActive ? "●" : "○";
1109
1142
  const parts = [];
1110
1143
  if (counts.running.length > 0)
1111
1144
  parts.push(formatAgentRunningLabel(counts.running.length));
@@ -1123,17 +1156,9 @@ function progressiveHeaderLine(jobs, theme, width) {
1123
1156
  }
1124
1157
  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
1158
  }
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);
1159
+ function progressiveJobLine(job, theme, width, now = Date.now()) {
1160
+ const row = compactJobLines(job, activeJobStep(job), theme, Math.max(1, width - 2), now)[0] ?? "";
1161
+ return row ? ` ${row}` : "";
1137
1162
  }
1138
1163
  function progressiveHiddenLine(hiddenJobs, theme, width) {
1139
1164
  const counts = widgetHeaderCounts(hiddenJobs);
@@ -1219,31 +1244,19 @@ function fitAdaptiveWidgetLines(jobs, lines, theme, width, expanded) {
1219
1244
  widgetLayoutSession = { expanded, rows, columns, tier: "progressive", lockedRows, visibleJobKeys: rendered.visibleJobKeys };
1220
1245
  return rendered.lines;
1221
1246
  }
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
- };
1235
- }
1236
- export function buildWidgetLines(jobs, theme, width = getTermWidth(), expanded = false) {
1247
+ export function buildWidgetLines(jobs, theme, width = getTermWidth(), expanded = false, now = Date.now()) {
1237
1248
  if (jobs.length === 0)
1238
1249
  return [];
1239
1250
  if (jobs.length === 1)
1240
- return buildSingleWidgetLines(jobs[0], theme, width, expanded);
1251
+ return buildSingleWidgetLines(jobs[0], theme, width, expanded, now);
1241
1252
  const running = jobs.filter((job) => job.status === "running");
1242
1253
  const queued = jobs.filter((job) => job.status === "queued");
1243
1254
  const finished = jobs.filter((job) => job.status !== "running" && job.status !== "queued");
1244
1255
  const lines = [];
1245
1256
  const hasActive = running.length > 0 || queued.length > 0;
1246
- const headerGlyph = running.length > 0 ? runningGlyph(widgetJobsRunningSeed(running)) : hasActive ? "●" : "○";
1257
+ const headerGlyph = running.length > 0
1258
+ ? runningGlyph((widgetJobsRunningSeed(running) ?? 0) + widgetAnimFrame(now))
1259
+ : hasActive ? "●" : "○";
1247
1260
  lines.push(truncLine(`${theme.fg(hasActive ? "accent" : "dim", headerGlyph)} ${theme.fg(hasActive ? "accent" : "dim", "Async agents")} ${theme.fg("dim", "· background")}`, width));
1248
1261
  const items = [];
1249
1262
  let hiddenRunning = 0;
@@ -1255,12 +1268,8 @@ export function buildWidgetLines(jobs, theme, width = getTermWidth(), expanded =
1255
1268
  hiddenRunning++;
1256
1269
  continue;
1257
1270
  }
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
- ]);
1271
+ const row = compactJobChildRows(job, theme, Math.max(1, width - 3), now);
1272
+ items.push(expanded ? [...row, ...widgetParallelAgentDetails(job, theme, true, width)] : row);
1264
1273
  slots--;
1265
1274
  }
1266
1275
  if (queued.length > 0 && slots > 0) {
@@ -1273,12 +1282,8 @@ export function buildWidgetLines(jobs, theme, width = getTermWidth(), expanded =
1273
1282
  hiddenFinished++;
1274
1283
  continue;
1275
1284
  }
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
- ]);
1285
+ const row = compactJobChildRows(job, theme, Math.max(1, width - 3), now);
1286
+ items.push(expanded ? [...row, ...widgetParallelAgentDetails(job, theme, true, width)] : row);
1282
1287
  slots--;
1283
1288
  }
1284
1289
  const hiddenQueued = queued.length > 0 && !queuedSummaryShown ? queued.length : 0;
@@ -1305,27 +1310,114 @@ export function buildWidgetLines(jobs, theme, width = getTermWidth(), expanded =
1305
1310
  }
1306
1311
  return lines;
1307
1312
  }
1308
- let widgetPaintTimer;
1309
- let widgetPaintCtx;
1310
- export function clearWidgetPaintTimer() {
1311
- if (widgetPaintTimer) {
1312
- clearInterval(widgetPaintTimer);
1313
- widgetPaintTimer = undefined;
1313
+ let activeWidget;
1314
+ export class SubagentAsyncWidget {
1315
+ jobs;
1316
+ expanded;
1317
+ theme;
1318
+ requestRender;
1319
+ nowFn;
1320
+ timer;
1321
+ disposed = false;
1322
+ cachedWidth;
1323
+ cachedLines;
1324
+ constructor(jobs, theme, options) {
1325
+ this.jobs = jobs;
1326
+ this.theme = theme;
1327
+ this.expanded = options?.expanded ?? false;
1328
+ this.requestRender = options?.requestRender;
1329
+ this.nowFn = options?.now ?? Date.now;
1330
+ this.syncTimer();
1314
1331
  }
1315
- widgetPaintCtx = undefined;
1316
- }
1317
- function ensureWidgetPaintTimer(ctx, running) {
1318
- widgetPaintCtx = ctx;
1319
- if (!running || !ctx.hasUI) {
1320
- clearWidgetPaintTimer();
1321
- return;
1332
+ setTheme(theme) {
1333
+ this.theme = theme;
1334
+ this.invalidate();
1322
1335
  }
1323
- if (widgetPaintTimer)
1324
- return;
1325
- widgetPaintTimer = setInterval(() => {
1326
- widgetPaintCtx?.ui.requestRender?.();
1327
- }, 80);
1328
- widgetPaintTimer.unref?.();
1336
+ setJobs(jobs) {
1337
+ this.jobs = jobs;
1338
+ this.invalidate();
1339
+ this.syncTimer();
1340
+ }
1341
+ setExpanded(expanded) {
1342
+ if (this.expanded === expanded)
1343
+ return;
1344
+ this.expanded = expanded;
1345
+ this.invalidate();
1346
+ }
1347
+ setRequestRender(requestRender) {
1348
+ this.requestRender = requestRender;
1349
+ }
1350
+ hasRunning() {
1351
+ return this.jobs.some((job) => job.status === "running");
1352
+ }
1353
+ syncTimer() {
1354
+ if (this.disposed)
1355
+ return;
1356
+ if (this.hasRunning())
1357
+ this.startTimer();
1358
+ else
1359
+ this.stopTimer();
1360
+ }
1361
+ startTimer() {
1362
+ if (this.timer)
1363
+ return;
1364
+ this.timer = setInterval(() => {
1365
+ if (this.disposed)
1366
+ return;
1367
+ this.invalidate();
1368
+ this.requestRender?.();
1369
+ }, 80);
1370
+ this.timer.unref?.();
1371
+ }
1372
+ stopTimer() {
1373
+ if (!this.timer)
1374
+ return;
1375
+ clearInterval(this.timer);
1376
+ this.timer = undefined;
1377
+ }
1378
+ invalidate() {
1379
+ this.cachedWidth = undefined;
1380
+ this.cachedLines = undefined;
1381
+ }
1382
+ dispose() {
1383
+ this.disposed = true;
1384
+ this.stopTimer();
1385
+ if (activeWidget === this)
1386
+ activeWidget = undefined;
1387
+ }
1388
+ render(width) {
1389
+ const theme = this.theme;
1390
+ if (!theme)
1391
+ return [];
1392
+ if (this.cachedLines && this.cachedWidth === width && !this.hasRunning())
1393
+ return this.cachedLines;
1394
+ const now = this.nowFn();
1395
+ const innerWidth = Math.max(1, width - 2);
1396
+ const lines = this.expanded
1397
+ ? buildWidgetLines(this.jobs, theme, innerWidth, true, now)
1398
+ : this.jobs.length === 1
1399
+ ? compactSingleWidgetLines(this.jobs[0], theme, innerWidth, now)
1400
+ : buildWidgetLines(this.jobs, theme, innerWidth, false, now);
1401
+ const fitted = fitAdaptiveWidgetLines(this.jobs, lines, theme, innerWidth, this.expanded);
1402
+ const padded = fitted.map((line) => {
1403
+ const withPad = ` ${line}`;
1404
+ const vis = visibleWidth(withPad);
1405
+ return withPad + " ".repeat(Math.max(0, width - vis));
1406
+ });
1407
+ this.cachedWidth = width;
1408
+ this.cachedLines = padded;
1409
+ return padded;
1410
+ }
1411
+ }
1412
+ export function createSubagentWidgetComponent(jobs, theme, options) {
1413
+ return new SubagentAsyncWidget(jobs, theme, options);
1414
+ }
1415
+ export function disposeSubagentWidget() {
1416
+ activeWidget?.dispose();
1417
+ activeWidget = undefined;
1418
+ }
1419
+ export function clearWidgetPaintTimer() {
1420
+ disposeSubagentWidget();
1329
1421
  }
1330
1422
  /**
1331
1423
  * Render the async jobs widget
@@ -1333,43 +1425,47 @@ function ensureWidgetPaintTimer(ctx, running) {
1333
1425
  export function renderWidget(ctx, jobs) {
1334
1426
  if (jobs.length === 0) {
1335
1427
  resetWidgetLayoutSession();
1336
- clearWidgetPaintTimer();
1428
+ disposeSubagentWidget();
1337
1429
  if (ctx.hasUI)
1338
1430
  ctx.ui.setWidget(WIDGET_KEY, undefined);
1339
1431
  return;
1340
1432
  }
1341
1433
  if (!ctx.hasUI)
1342
1434
  return;
1343
- ensureWidgetPaintTimer(ctx, jobs.some((job) => job.status === "running"));
1344
- ctx.ui.setWidget(WIDGET_KEY, buildWidgetComponent(jobs, ctx.ui.getToolsExpanded?.() ?? false));
1435
+ const expanded = ctx.ui.getToolsExpanded?.() ?? false;
1436
+ const requestRender = () => ctx.ui.requestRender?.();
1437
+ if (activeWidget) {
1438
+ activeWidget.setJobs(jobs);
1439
+ activeWidget.setExpanded(expanded);
1440
+ activeWidget.setRequestRender(requestRender);
1441
+ ctx.ui.requestRender?.();
1442
+ return;
1443
+ }
1444
+ const widget = new SubagentAsyncWidget(jobs, undefined, { expanded, requestRender });
1445
+ activeWidget = widget;
1446
+ ctx.ui.setWidget(WIDGET_KEY, (_tui, theme) => {
1447
+ widget.setTheme(theme);
1448
+ return widget;
1449
+ });
1345
1450
  }
1346
1451
  function renderSingleCompact(d, r, theme, frame) {
1347
1452
  const output = r.truncation?.text || getSingleResultOutput(r);
1348
1453
  const progress = r.progress || r.progressSummary;
1349
1454
  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
1455
  const c = new Container();
1353
1456
  const width = getTermWidth() - 4;
1354
- // lunr: row line is a per-frame template so the running glyph animates in place (see subagentAnimSink).
1355
1457
  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;
1458
+ const modelBadge = formatCompactModelBadge(r.modelSelection ?? progress?.modelSelection, r.model ?? progress?.model);
1459
+ c.addChild(animatedLine((f, now) => formatCompactSubagentRow(theme, width, {
1460
+ glyph: resultGlyph(r, output, theme, isRunning, undefined, f),
1461
+ description: lead,
1462
+ modelBadge,
1463
+ tokens: compactResultTokens(r),
1464
+ durationMs: liveDurationMs(progress, isRunning, now),
1465
+ }), frame, isRunning));
1466
+ if (!isRunning && (r.exitCode !== 0 || r.interrupted || r.detached || r.stopped)) {
1467
+ c.addChild(new Text(truncLine(theme.fg(r.exitCode !== 0 ? "error" : "dim", ` ⎿ ${resultStatusLine(r, output)}`), width), 0, 0));
1365
1468
  }
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));
1370
- }
1371
- if (r.sessionFile)
1372
- c.addChild(new Text(truncLine(theme.fg("dim", ` session: ${shortenPath(r.sessionFile)}`), width), 0, 0));
1373
1469
  return c;
1374
1470
  }
1375
1471
  function renderMultiCompact(d, theme, frame) {
@@ -1415,9 +1511,8 @@ function renderMultiCompact(d, theme, frame) {
1415
1511
  const contextBadge = d.context === "fork" ? theme.fg("warning", " [fork]") : "";
1416
1512
  const c = new Container();
1417
1513
  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)]);
1514
+ c.addChild(animatedLine((f) => {
1515
+ const stats = statJoin(theme, [multiLabel.headerLabel, formatTotalCostStat(d.totalCost)]);
1421
1516
  return truncLine(`${glyph(f)} ${theme.fg("toolTitle", theme.bold(d.mode))}${contextBadge}${stats ? ` ${theme.fg("dim", "·")} ${stats}` : ""}`, width);
1422
1517
  }, frame, hasRunning));
1423
1518
  const useResultsDirectly = multiLabel.hasParallelInChain || !d.chainAgents?.length;
@@ -1454,21 +1549,20 @@ function renderMultiCompact(d, theme, frame) {
1454
1549
  const rProg = r.progress || progressFromArray || r.progressSummary;
1455
1550
  const rRunning = rProg && "status" in rProg && rProg.status === "running";
1456
1551
  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
1552
  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));
1553
+ const modelBadge = formatCompactModelBadge(r.modelSelection ?? (rProg && "modelSelection" in rProg ? rProg.modelSelection : undefined), r.model ?? (rProg && "model" in rProg ? rProg.model : undefined));
1463
1554
  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);
1555
+ const rowGlyph = rPending ? theme.fg("dim", "◦") : resultGlyph(r, output, theme, rRunning, progressRunningSeed(rProg), f);
1556
+ return formatCompactSubagentRow(theme, width, {
1557
+ glyph: rowGlyph,
1558
+ description: lead,
1559
+ modelBadge,
1560
+ tokens: compactResultTokens(r),
1561
+ durationMs: liveDurationMs(rProg, !!rRunning, now),
1562
+ prefix: " ",
1563
+ });
1467
1564
  }, 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))) {
1565
+ if (!rPending && !rRunning && (r.exitCode !== 0 || r.interrupted || r.detached || r.stopped)) {
1472
1566
  c.addChild(new Text(truncLine(theme.fg(r.exitCode !== 0 ? "error" : "dim", ` ⎿ ${resultStatusLine(r, output)}`), width), 0, 0));
1473
1567
  }
1474
1568
  }