@ashx-j/lunr 0.2.14 → 0.2.16

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 (215) hide show
  1. package/CHANGELOG.md +24 -1
  2. package/README.md +4 -4
  3. package/dist/builtin-extensions/ashxj-tui.d.ts.map +1 -1
  4. package/dist/builtin-extensions/ashxj-tui.js +4 -4
  5. package/dist/builtin-extensions/ashxj-tui.js.map +1 -1
  6. package/dist/builtin-extensions/index.d.ts.map +1 -1
  7. package/dist/builtin-extensions/index.js +2 -0
  8. package/dist/builtin-extensions/index.js.map +1 -1
  9. package/dist/builtin-extensions/lunr-settings-tools.d.ts +4 -0
  10. package/dist/builtin-extensions/lunr-settings-tools.d.ts.map +1 -0
  11. package/dist/builtin-extensions/lunr-settings-tools.js +120 -0
  12. package/dist/builtin-extensions/lunr-settings-tools.js.map +1 -0
  13. package/dist/builtin-extensions/narumiruna-pi-goal/src/goal.d.ts.map +1 -1
  14. package/dist/builtin-extensions/narumiruna-pi-goal/src/goal.js +6 -2
  15. package/dist/builtin-extensions/narumiruna-pi-goal/src/goal.js.map +1 -1
  16. package/dist/builtin-extensions/pi-prompt-template-model/subagent-runtime.d.ts +2 -2
  17. package/dist/builtin-extensions/pi-prompt-template-model/subagent-runtime.d.ts.map +1 -1
  18. package/dist/builtin-extensions/pi-prompt-template-model/subagent-runtime.js.map +1 -1
  19. package/dist/builtin-extensions/pi-prompt-template-model/subagent-step.d.ts.map +1 -1
  20. package/dist/builtin-extensions/pi-prompt-template-model/subagent-step.js +3 -3
  21. package/dist/builtin-extensions/pi-prompt-template-model/subagent-step.js.map +1 -1
  22. package/dist/builtin-extensions/pi-subagents/src/api/delegation.d.ts +2 -2
  23. package/dist/builtin-extensions/pi-subagents/src/api/delegation.d.ts.map +1 -1
  24. package/dist/builtin-extensions/pi-subagents/src/api/delegation.js +1 -1
  25. package/dist/builtin-extensions/pi-subagents/src/api/delegation.js.map +1 -1
  26. package/dist/builtin-extensions/pi-subagents/src/extension/index.d.ts.map +1 -1
  27. package/dist/builtin-extensions/pi-subagents/src/extension/index.js +2 -1
  28. package/dist/builtin-extensions/pi-subagents/src/extension/index.js.map +1 -1
  29. package/dist/builtin-extensions/pi-subagents/src/extension/schemas.d.ts +5 -11
  30. package/dist/builtin-extensions/pi-subagents/src/extension/schemas.d.ts.map +1 -1
  31. package/dist/builtin-extensions/pi-subagents/src/extension/schemas.js +12 -15
  32. package/dist/builtin-extensions/pi-subagents/src/extension/schemas.js.map +1 -1
  33. package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.d.ts +3 -3
  34. package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.d.ts.map +1 -1
  35. package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.js +14 -27
  36. package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.js.map +1 -1
  37. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-execution.d.ts.map +1 -1
  38. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-execution.js +6 -4
  39. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-execution.js.map +1 -1
  40. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-job-tracker.d.ts.map +1 -1
  41. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-job-tracker.js +2 -1
  42. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-job-tracker.js.map +1 -1
  43. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-resume.d.ts.map +1 -1
  44. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-resume.js +6 -4
  45. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-resume.js.map +1 -1
  46. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-status.d.ts.map +1 -1
  47. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-status.js +4 -2
  48. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-status.js.map +1 -1
  49. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-clarify.d.ts.map +1 -1
  50. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-clarify.js +3 -35
  51. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-clarify.js.map +1 -1
  52. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.d.ts.map +1 -1
  53. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.js +5 -12
  54. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.js.map +1 -1
  55. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.d.ts.map +1 -1
  56. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.js +14 -31
  57. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.js.map +1 -1
  58. package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.d.ts +2 -0
  59. package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.d.ts.map +1 -1
  60. package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.js +28 -22
  61. package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.js.map +1 -1
  62. package/dist/builtin-extensions/pi-subagents/src/runs/shared/parallel-utils.d.ts +1 -0
  63. package/dist/builtin-extensions/pi-subagents/src/runs/shared/parallel-utils.d.ts.map +1 -1
  64. package/dist/builtin-extensions/pi-subagents/src/runs/shared/parallel-utils.js.map +1 -1
  65. package/dist/builtin-extensions/pi-subagents/src/shared/child-spec.d.ts.map +1 -1
  66. package/dist/builtin-extensions/pi-subagents/src/shared/child-spec.js +9 -4
  67. package/dist/builtin-extensions/pi-subagents/src/shared/child-spec.js.map +1 -1
  68. package/dist/builtin-extensions/pi-subagents/src/shared/formatters.d.ts +1 -1
  69. package/dist/builtin-extensions/pi-subagents/src/shared/formatters.d.ts.map +1 -1
  70. package/dist/builtin-extensions/pi-subagents/src/shared/formatters.js +2 -2
  71. package/dist/builtin-extensions/pi-subagents/src/shared/formatters.js.map +1 -1
  72. package/dist/builtin-extensions/pi-subagents/src/shared/types.d.ts +4 -7
  73. package/dist/builtin-extensions/pi-subagents/src/shared/types.d.ts.map +1 -1
  74. package/dist/builtin-extensions/pi-subagents/src/shared/types.js +1 -1
  75. package/dist/builtin-extensions/pi-subagents/src/shared/types.js.map +1 -1
  76. package/dist/builtin-extensions/pi-subagents/src/slash/delegation-adapters.d.ts +3 -3
  77. package/dist/builtin-extensions/pi-subagents/src/slash/delegation-adapters.d.ts.map +1 -1
  78. package/dist/builtin-extensions/pi-subagents/src/slash/delegation-adapters.js +7 -6
  79. package/dist/builtin-extensions/pi-subagents/src/slash/delegation-adapters.js.map +1 -1
  80. package/dist/builtin-extensions/pi-subagents/src/slash/delegation-request.d.ts.map +1 -1
  81. package/dist/builtin-extensions/pi-subagents/src/slash/delegation-request.js +3 -3
  82. package/dist/builtin-extensions/pi-subagents/src/slash/delegation-request.js.map +1 -1
  83. package/dist/builtin-extensions/pi-subagents/src/slash/prompt-workflows.d.ts +1 -1
  84. package/dist/builtin-extensions/pi-subagents/src/slash/prompt-workflows.d.ts.map +1 -1
  85. package/dist/builtin-extensions/pi-subagents/src/slash/prompt-workflows.js +6 -4
  86. package/dist/builtin-extensions/pi-subagents/src/slash/prompt-workflows.js.map +1 -1
  87. package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.d.ts +1 -1
  88. package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.d.ts.map +1 -1
  89. package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.js +15 -10
  90. package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.js.map +1 -1
  91. package/dist/builtin-extensions/pi-subagents/src/tui/fleet.d.ts.map +1 -1
  92. package/dist/builtin-extensions/pi-subagents/src/tui/fleet.js +3 -2
  93. package/dist/builtin-extensions/pi-subagents/src/tui/fleet.js.map +1 -1
  94. package/dist/builtin-extensions/pi-subagents/src/tui/render.d.ts +2 -2
  95. package/dist/builtin-extensions/pi-subagents/src/tui/render.d.ts.map +1 -1
  96. package/dist/builtin-extensions/pi-subagents/src/tui/render.js +75 -43
  97. package/dist/builtin-extensions/pi-subagents/src/tui/render.js.map +1 -1
  98. package/dist/core/agent-session-runtime.d.ts +5 -1
  99. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  100. package/dist/core/agent-session-runtime.js +7 -2
  101. package/dist/core/agent-session-runtime.js.map +1 -1
  102. package/dist/core/agent-session.d.ts +5 -0
  103. package/dist/core/agent-session.d.ts.map +1 -1
  104. package/dist/core/agent-session.js +68 -10
  105. package/dist/core/agent-session.js.map +1 -1
  106. package/dist/core/compaction/compaction.d.ts.map +1 -1
  107. package/dist/core/compaction/compaction.js +10 -5
  108. package/dist/core/compaction/compaction.js.map +1 -1
  109. package/dist/core/context-breakdown.d.ts +2 -0
  110. package/dist/core/context-breakdown.d.ts.map +1 -1
  111. package/dist/core/context-breakdown.js +6 -2
  112. package/dist/core/context-breakdown.js.map +1 -1
  113. package/dist/core/extensions/types.d.ts +2 -2
  114. package/dist/core/extensions/types.d.ts.map +1 -1
  115. package/dist/core/extensions/types.js.map +1 -1
  116. package/dist/core/injected-prompt.d.ts +3 -3
  117. package/dist/core/injected-prompt.d.ts.map +1 -1
  118. package/dist/core/injected-prompt.js +2 -7
  119. package/dist/core/injected-prompt.js.map +1 -1
  120. package/dist/core/large-subagent-launch.d.ts +13 -0
  121. package/dist/core/large-subagent-launch.d.ts.map +1 -0
  122. package/dist/core/large-subagent-launch.js +54 -0
  123. package/dist/core/large-subagent-launch.js.map +1 -0
  124. package/dist/core/model-instructions.d.ts +24 -0
  125. package/dist/core/model-instructions.d.ts.map +1 -0
  126. package/dist/core/model-instructions.js +123 -0
  127. package/dist/core/model-instructions.js.map +1 -0
  128. package/dist/core/permissions.d.ts +10 -11
  129. package/dist/core/permissions.d.ts.map +1 -1
  130. package/dist/core/permissions.js +107 -40
  131. package/dist/core/permissions.js.map +1 -1
  132. package/dist/core/plan-mode.d.ts.map +1 -1
  133. package/dist/core/plan-mode.js +10 -1
  134. package/dist/core/plan-mode.js.map +1 -1
  135. package/dist/core/resource-loader.d.ts +3 -0
  136. package/dist/core/resource-loader.d.ts.map +1 -1
  137. package/dist/core/resource-loader.js +13 -4
  138. package/dist/core/resource-loader.js.map +1 -1
  139. package/dist/core/runtime-bridges.d.ts +4 -0
  140. package/dist/core/runtime-bridges.d.ts.map +1 -0
  141. package/dist/core/runtime-bridges.js +16 -0
  142. package/dist/core/runtime-bridges.js.map +1 -0
  143. package/dist/core/sdk.d.ts.map +1 -1
  144. package/dist/core/sdk.js +1 -0
  145. package/dist/core/sdk.js.map +1 -1
  146. package/dist/core/settings-manager.d.ts +13 -0
  147. package/dist/core/settings-manager.d.ts.map +1 -1
  148. package/dist/core/settings-manager.js +32 -0
  149. package/dist/core/settings-manager.js.map +1 -1
  150. package/dist/core/settings-tools-bridge.d.ts +35 -0
  151. package/dist/core/settings-tools-bridge.d.ts.map +1 -0
  152. package/dist/core/settings-tools-bridge.js +56 -0
  153. package/dist/core/settings-tools-bridge.js.map +1 -0
  154. package/dist/core/slash-commands.d.ts.map +1 -1
  155. package/dist/core/slash-commands.js +0 -1
  156. package/dist/core/slash-commands.js.map +1 -1
  157. package/dist/core/system-prompt.d.ts.map +1 -1
  158. package/dist/core/system-prompt.js +1 -1
  159. package/dist/core/system-prompt.js.map +1 -1
  160. package/dist/gateway/agent-bridge.d.ts.map +1 -1
  161. package/dist/gateway/agent-bridge.js +3 -2
  162. package/dist/gateway/agent-bridge.js.map +1 -1
  163. package/dist/gateway/approval.d.ts.map +1 -1
  164. package/dist/gateway/approval.js +4 -3
  165. package/dist/gateway/approval.js.map +1 -1
  166. package/dist/gateway/commands.d.ts +1 -1
  167. package/dist/gateway/commands.d.ts.map +1 -1
  168. package/dist/gateway/commands.js +1 -18
  169. package/dist/gateway/commands.js.map +1 -1
  170. package/dist/gateway/cron.d.ts.map +1 -1
  171. package/dist/gateway/cron.js +3 -2
  172. package/dist/gateway/cron.js.map +1 -1
  173. package/dist/gateway/router.d.ts +1 -1
  174. package/dist/gateway/router.d.ts.map +1 -1
  175. package/dist/gateway/router.js +1 -1
  176. package/dist/gateway/router.js.map +1 -1
  177. package/dist/main.d.ts.map +1 -1
  178. package/dist/main.js +3 -9
  179. package/dist/main.js.map +1 -1
  180. package/dist/migrations.d.ts.map +1 -1
  181. package/dist/migrations.js +4 -0
  182. package/dist/migrations.js.map +1 -1
  183. package/dist/modes/interactive/components/injected-prompt-message.d.ts +1 -1
  184. package/dist/modes/interactive/components/injected-prompt-message.d.ts.map +1 -1
  185. package/dist/modes/interactive/components/injected-prompt-message.js +1 -1
  186. package/dist/modes/interactive/components/injected-prompt-message.js.map +1 -1
  187. package/dist/modes/interactive/components/settings-selector.d.ts +8 -1
  188. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  189. package/dist/modes/interactive/components/settings-selector.js +61 -1
  190. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  191. package/dist/modes/interactive/interactive-mode.d.ts +3 -3
  192. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  193. package/dist/modes/interactive/interactive-mode.js +45 -54
  194. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  195. package/docs/compaction.md +5 -3
  196. package/docs/features.md +7 -7
  197. package/docs/quickstart.md +2 -1
  198. package/docs/settings.md +3 -1
  199. package/docs/termux.md +1 -1
  200. package/docs/usage.md +2 -2
  201. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  202. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  203. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  204. package/examples/extensions/gondolin/package-lock.json +2 -2
  205. package/examples/extensions/gondolin/package.json +1 -1
  206. package/examples/extensions/sandbox/package-lock.json +2 -2
  207. package/examples/extensions/sandbox/package.json +1 -1
  208. package/examples/extensions/subagent/README.md +1 -1
  209. package/examples/extensions/with-deps/package-lock.json +2 -2
  210. package/examples/extensions/with-deps/package.json +1 -1
  211. package/package.json +4 -4
  212. package/dist/core/swarm.d.ts +0 -54
  213. package/dist/core/swarm.d.ts.map +0 -1
  214. package/dist/core/swarm.js +0 -119
  215. package/dist/core/swarm.js.map +0 -1
@@ -129,7 +129,7 @@ export function clearLegacyResultAnimationTimer(context) {
129
129
  }
130
130
  export const subagentAnimSink = { current: null };
131
131
  function animatedLine(line, frame, animate) {
132
- const text = new Text(line(frame ?? 0), 0, 0);
132
+ const text = new Text(line(frame ?? 0, Date.now()), 0, 0);
133
133
  if (animate && frame !== undefined && subagentAnimSink.current) {
134
134
  subagentAnimSink.current.push({ text, line });
135
135
  }
@@ -216,7 +216,14 @@ function formatTotalCostStat(totalCost) {
216
216
  parts.push(`$${totalCost.costUsd.toFixed(4)}`);
217
217
  return parts.join(" ");
218
218
  }
219
- function formatProgressStats(theme, progress, includeDuration = true) {
219
+ function liveDurationMs(progress, running, now) {
220
+ if (!progress)
221
+ return 0;
222
+ if (!running || progress.lastActivityAt === undefined)
223
+ return progress.durationMs;
224
+ return progress.durationMs + Math.max(0, now - progress.lastActivityAt);
225
+ }
226
+ function formatProgressStats(theme, progress, includeDuration = true, options = {}) {
220
227
  if (!progress)
221
228
  return "";
222
229
  const parts = [];
@@ -224,8 +231,9 @@ function formatProgressStats(theme, progress, includeDuration = true) {
224
231
  parts.push(formatToolUseStat(progress.toolCount));
225
232
  if (progress.tokens > 0)
226
233
  parts.push(formatTokenStat(progress.tokens));
227
- if (includeDuration && progress.durationMs > 0)
228
- parts.push(formatDuration(progress.durationMs));
234
+ const durationMs = liveDurationMs(progress, options.running === true, options.now ?? Date.now());
235
+ if (includeDuration && durationMs > 0)
236
+ parts.push(`${options.terminal ? "ran for " : ""}${formatDuration(durationMs)}`);
229
237
  return statJoin(theme, parts);
230
238
  }
231
239
  function firstOutputLine(text) {
@@ -291,10 +299,10 @@ function resultGlyph(result, output, theme, running = result.progress?.status ==
291
299
  return theme.fg("success", "✓");
292
300
  }
293
301
  /** Compact hang row: tool count, tokens, elapsed time. */
294
- export function formatCompactStatsHangLine(progress, width, paint = (s) => s, prefix = " ⎿ ") {
302
+ export function formatCompactStatsHangLine(progress, width, paint = (s) => s, prefix = " ⎿ ", now = Date.now(), running = false) {
295
303
  const toolCount = progress?.toolCount ?? 0;
296
304
  const tokens = progress?.tokens ?? 0;
297
- const durationMs = progress?.durationMs ?? 0;
305
+ const durationMs = liveDurationMs(progress, running, now);
298
306
  const body = [
299
307
  formatToolUseStat(toolCount),
300
308
  formatTokenStat(tokens),
@@ -348,10 +356,11 @@ function widgetJobName(job) {
348
356
  return formatWidgetAgents(job.agents);
349
357
  return job.mode ?? "subagent";
350
358
  }
351
- function widgetActivity(job) {
359
+ function widgetActivity(job, now = Date.now()) {
352
360
  const facts = [];
353
- if (job.currentTool && job.currentToolStartedAt !== undefined && job.updatedAt !== undefined)
354
- facts.push(`${job.currentTool} ${formatDuration(Math.max(0, job.updatedAt - job.currentToolStartedAt))}`);
361
+ const snapshotNow = job.status === "running" ? now : job.updatedAt;
362
+ if (job.currentTool && job.currentToolStartedAt !== undefined && snapshotNow !== undefined)
363
+ facts.push(`${job.currentTool} ${formatDuration(Math.max(0, snapshotNow - job.currentToolStartedAt))}`);
355
364
  else if (job.currentTool)
356
365
  facts.push(job.currentTool);
357
366
  if (job.currentPath)
@@ -360,7 +369,7 @@ function widgetActivity(job) {
360
369
  facts.push(`${job.turnCount} turns`);
361
370
  if (job.toolCount !== undefined)
362
371
  facts.push(`${job.toolCount} tools`);
363
- const activity = buildLiveStatusLine(job, job.updatedAt);
372
+ const activity = buildLiveStatusLine(job, snapshotNow);
364
373
  if (activity && facts.length)
365
374
  return `${activity} · ${facts.join(" · ")}`;
366
375
  if (activity)
@@ -712,7 +721,7 @@ function resultRowLabel(details, label, resultIndex, stepNumber) {
712
721
  }
713
722
  return `Step ${stepNumber}`;
714
723
  }
715
- function widgetStats(job, theme) {
724
+ function widgetStats(job, theme, now = Date.now()) {
716
725
  const parts = [];
717
726
  const stepsTotal = job.stepsTotal ?? (job.agents?.length ?? 1);
718
727
  if (job.activeParallelGroup) {
@@ -752,16 +761,25 @@ function widgetStats(job, theme) {
752
761
  parts.push(formatToolUseStat(job.toolCount));
753
762
  if (job.totalTokens?.total)
754
763
  parts.push(formatTokenStat(job.totalTokens.total));
755
- if (job.startedAt !== undefined && job.updatedAt !== undefined)
756
- parts.push(formatDuration(Math.max(0, job.updatedAt - job.startedAt)));
764
+ if (job.startedAt !== undefined) {
765
+ const end = job.status === "running" ? now : job.updatedAt;
766
+ if (end !== undefined)
767
+ parts.push(`${job.status === "running" ? "" : "ran for "}${formatDuration(Math.max(0, end - job.startedAt))}`);
768
+ }
757
769
  return statJoin(theme, parts);
758
770
  }
759
- function widgetStepStats(theme, step) {
771
+ function widgetStepStats(theme, step, now = Date.now()) {
772
+ const running = step.status === "running";
773
+ const durationMs = step.durationMs !== undefined
774
+ ? step.durationMs + (running && step.lastActivityAt !== undefined ? Math.max(0, now - step.lastActivityAt) : 0)
775
+ : step.startedAt !== undefined
776
+ ? Math.max(0, (running ? now : step.endedAt ?? step.lastActivityAt ?? now) - step.startedAt)
777
+ : undefined;
760
778
  return statJoin(theme, [
761
779
  step.turnCount !== undefined ? `${step.turnCount} turns` : "",
762
780
  step.toolCount !== undefined ? formatToolUseStat(step.toolCount) : "",
763
781
  step.tokens?.total ? formatTokenStat(step.tokens.total) : "",
764
- step.durationMs !== undefined ? formatDuration(step.durationMs) : "",
782
+ durationMs !== undefined ? `${running ? "" : "ran for "}${formatDuration(durationMs)}` : "",
765
783
  ]);
766
784
  }
767
785
  function modelThinkingBadge(theme, model, thinking, selection) {
@@ -1290,16 +1308,18 @@ function renderSingleCompact(d, r, theme, frame) {
1290
1308
  const isRunning = r.progress?.status === "running";
1291
1309
  const contextBadge = d.context === "fork" ? theme.fg("warning", " [fork]") : "";
1292
1310
  // lunr: simplified collapsed row — glyph · task summary · agent type · runtime/tools/tokens stats.
1293
- const stats = formatProgressStats(theme, progress);
1294
1311
  const c = new Container();
1295
1312
  const width = getTermWidth() - 4;
1296
1313
  // lunr: row line is a per-frame template so the running glyph animates in place (see subagentAnimSink).
1297
1314
  const lead = compactRowLead({ description: r.description ?? r.agent, task: r.task });
1298
1315
  const modelBadge = formatModelSelection(r.modelSelection ?? progress?.modelSelection, r.model ?? progress?.model, r.thinking ?? progress?.thinking);
1299
1316
  const permissionBadge = r.permissions ? theme.fg("dim", r.permissions) : "";
1300
- c.addChild(animatedLine((f) => 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), frame, isRunning));
1317
+ c.addChild(animatedLine((f, now) => {
1318
+ const stats = formatProgressStats(theme, progress, true, { running: isRunning, terminal: !isRunning, now });
1319
+ 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);
1320
+ }, frame, isRunning));
1301
1321
  if (isRunning && r.progress) {
1302
- c.addChild(new Text(formatCompactStatsHangLine(r.progress, width, (s) => theme.fg("dim", s)), 0, 0));
1322
+ c.addChild(animatedLine((_f, now) => formatCompactStatsHangLine(r.progress, width, (s) => theme.fg("dim", s), " ⎿ ", now, true), frame, true));
1303
1323
  return c;
1304
1324
  }
1305
1325
  c.addChild(new Text(truncLine(theme.fg("dim", ` ⎿ ${resultStatusLine(r, output)}`), width), 0, 0));
@@ -1324,7 +1344,7 @@ function renderMultiCompact(d, theme, frame) {
1324
1344
  let totalSummary = d.progressSummary;
1325
1345
  if (!totalSummary) {
1326
1346
  let sawProgress = false;
1327
- const summary = { toolCount: 0, tokens: 0, durationMs: 0 };
1347
+ const summary = { toolCount: 0, tokens: 0, durationMs: 0, lastActivityAt: undefined };
1328
1348
  for (const r of d.results) {
1329
1349
  const prog = r.progress || r.progressSummary;
1330
1350
  if (!prog)
@@ -1333,13 +1353,15 @@ function renderMultiCompact(d, theme, frame) {
1333
1353
  summary.toolCount += prog.toolCount;
1334
1354
  summary.tokens += prog.tokens;
1335
1355
  summary.durationMs = d.mode === "chain" ? summary.durationMs + prog.durationMs : Math.max(summary.durationMs, prog.durationMs);
1356
+ if (prog.status === "running" && prog.lastActivityAt !== undefined) {
1357
+ summary.lastActivityAt = Math.max(summary.lastActivityAt ?? 0, prog.lastActivityAt);
1358
+ }
1336
1359
  }
1337
1360
  if (sawProgress)
1338
1361
  totalSummary = summary;
1339
1362
  }
1340
1363
  const multiLabel = buildMultiProgressLabel(d, hasRunning);
1341
1364
  const itemTitle = multiLabel.itemTitle;
1342
- const stats = statJoin(theme, [multiLabel.headerLabel, formatProgressStats(theme, totalSummary), formatTotalCostStat(d.totalCost)]);
1343
1365
  const glyph = (f) => hasRunning
1344
1366
  ? theme.fg("accent", runningGlyph(f !== undefined ? (runningSeed(progressRunningSeed(totalSummary), d.currentStepIndex) ?? 0) + f : runningSeed(progressRunningSeed(totalSummary), d.currentStepIndex)))
1345
1367
  : stopped
@@ -1353,7 +1375,10 @@ function renderMultiCompact(d, theme, frame) {
1353
1375
  const c = new Container();
1354
1376
  const width = getTermWidth() - 4;
1355
1377
  // lunr: header line is a per-frame template so the running glyph animates in place (see subagentAnimSink).
1356
- c.addChild(animatedLine((f) => truncLine(`${glyph(f)} ${theme.fg("toolTitle", theme.bold(d.mode))}${contextBadge}${stats ? ` ${theme.fg("dim", "·")} ${stats}` : ""}`, width), frame, hasRunning));
1378
+ c.addChild(animatedLine((f, now) => {
1379
+ const stats = statJoin(theme, [multiLabel.headerLabel, formatProgressStats(theme, totalSummary, true, { running: hasRunning, terminal: !hasRunning, now }), formatTotalCostStat(d.totalCost)]);
1380
+ return truncLine(`${glyph(f)} ${theme.fg("toolTitle", theme.bold(d.mode))}${contextBadge}${stats ? ` ${theme.fg("dim", "·")} ${stats}` : ""}`, width);
1381
+ }, frame, hasRunning));
1357
1382
  const useResultsDirectly = multiLabel.hasParallelInChain || !d.chainAgents?.length;
1358
1383
  const displayStart = multiLabel.showActiveGroupOnly ? multiLabel.groupStartIndex : 0;
1359
1384
  const displayEnd = multiLabel.showActiveGroupOnly ? multiLabel.groupEndIndex : (useResultsDirectly ? d.results.length : d.chainAgents.length);
@@ -1388,19 +1413,19 @@ function renderMultiCompact(d, theme, frame) {
1388
1413
  const rProg = r.progress || progressFromArray || r.progressSummary;
1389
1414
  const rRunning = rProg && "status" in rProg && rProg.status === "running";
1390
1415
  const rPending = rProg && "status" in rProg && rProg.status === "pending";
1391
- const stepStats = formatProgressStats(theme, rProg);
1392
1416
  const pendingLabel = rPending ? ` ${theme.fg("dim", "· pending")}` : "";
1393
1417
  // lunr: simplified collapsed row — glyph · task summary · agent type · runtime/tools/tokens stats.
1394
1418
  // lunr: row line is a per-frame template so the running glyph animates in place (see subagentAnimSink).
1395
1419
  const lead = compactRowLead({ description: r.description ?? agentName, task: r.task });
1396
1420
  const permissionBadge = r.permissions ? theme.fg("dim", r.permissions) : "";
1397
1421
  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));
1398
- c.addChild(animatedLine((f) => {
1422
+ c.addChild(animatedLine((f, now) => {
1399
1423
  const glyph = rPending ? theme.fg("dim", "◦") : resultGlyph(r, output, theme, rRunning, progressRunningSeed(rProg), f);
1424
+ const stepStats = formatProgressStats(theme, rProg, true, { running: !!rRunning, terminal: !rRunning && !rPending, now });
1400
1425
  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);
1401
1426
  }, frame, !!rRunning));
1402
1427
  if (rRunning && rProg && "status" in rProg) {
1403
- c.addChild(new Text(formatCompactStatsHangLine(rProg, width, (s) => theme.fg("dim", s), " ⎿ "), 0, 0));
1428
+ c.addChild(animatedLine((_f, now) => formatCompactStatsHangLine(rProg, width, (s) => theme.fg("dim", s), " ⎿ ", now, true), frame, true));
1404
1429
  }
1405
1430
  else if (!rPending && (r.exitCode !== 0 || r.interrupted || r.detached || hasEmptyTextOutputWithoutOutputTarget(r.task, output))) {
1406
1431
  c.addChild(new Text(truncLine(theme.fg(r.exitCode !== 0 ? "error" : "dim", ` ⎿ ${resultStatusLine(r, output)}`), width), 0, 0));
@@ -1442,17 +1467,16 @@ export function renderSubagentResult(result, options, theme, frame) {
1442
1467
  : theme.fg("error", "failed");
1443
1468
  const contextBadge = d.context === "fork" ? theme.fg("warning", " [fork]") : "";
1444
1469
  const output = r.truncation?.text || getSingleResultOutput(r);
1445
- const progressInfo = isRunning && r.progress
1446
- ? ` | ${r.progress.toolCount} tools, ${formatTokens(r.progress.tokens)} tok, ${formatDuration(r.progress.durationMs)}`
1447
- : r.progressSummary
1448
- ? ` | ${r.progressSummary.toolCount} tools, ${formatTokens(r.progressSummary.tokens)} tok, ${formatDuration(r.progressSummary.durationMs)}`
1449
- : "";
1450
1470
  const w = getTermWidth() - 4;
1451
1471
  const fit = (text) => expanded ? text : truncLine(text, w);
1452
1472
  const toolCallLines = getToolCallLines(r, expanded);
1453
1473
  const c = new Container();
1454
1474
  const modelDisplay = modelThinkingBadge(theme, r.model, r.thinking ?? r.progress?.thinking, r.modelSelection ?? r.progress?.modelSelection);
1455
- c.addChild(new Text(fit(`${icon} ${theme.fg("toolTitle", theme.bold(r.agent))}${modelDisplay}${contextBadge}${progressInfo}`), 0, 0));
1475
+ const progress = r.progress ?? r.progressSummary;
1476
+ c.addChild(animatedLine((_f, now) => {
1477
+ const stats = formatProgressStats(theme, progress, true, { running: isRunning, terminal: !isRunning, now });
1478
+ return fit(`${icon} ${theme.fg("toolTitle", theme.bold(r.agent))}${modelDisplay}${contextBadge}${stats ? ` | ${stats}` : ""}`);
1479
+ }, frame, isRunning));
1456
1480
  c.addChild(new Spacer(1));
1457
1481
  const taskMaxLen = Math.max(20, w - 8);
1458
1482
  const taskPreview = expanded || r.task.length <= taskMaxLen
@@ -1557,13 +1581,6 @@ export function renderSubagentResult(result, options, theme, frame) {
1557
1581
  }
1558
1582
  return acc;
1559
1583
  }, { toolCount: 0, tokens: 0, durationMs: 0 });
1560
- const summaryParts = [
1561
- totalSummary.toolCount || totalSummary.tokens
1562
- ? `${totalSummary.toolCount} tools, ${formatTokens(totalSummary.tokens)} tok, ${formatDuration(totalSummary.durationMs)}`
1563
- : "",
1564
- formatTotalCostStat(d.totalCost),
1565
- ].filter(Boolean);
1566
- const summaryStr = summaryParts.length ? ` | ${summaryParts.join(", ")}` : "";
1567
1584
  const modeLabel = d.mode;
1568
1585
  const contextBadge = d.context === "fork" ? theme.fg("warning", " [fork]") : "";
1569
1586
  const multiLabel = buildMultiProgressLabel(d, hasRunning);
@@ -1594,7 +1611,21 @@ export function renderSubagentResult(result, options, theme, frame) {
1594
1611
  const w = getTermWidth() - 4;
1595
1612
  const fit = (text) => expanded ? text : truncLine(text, w);
1596
1613
  const c = new Container();
1597
- c.addChild(new Text(fit(`${icon} ${theme.fg("toolTitle", theme.bold(modeLabel))}${contextBadge} · ${multiLabel.headerLabel}${summaryStr}`), 0, 0));
1614
+ c.addChild(animatedLine((_f, now) => {
1615
+ const durations = d.results
1616
+ .map((result) => result.progress ?? result.progressSummary)
1617
+ .filter(Boolean)
1618
+ .map((progress) => liveDurationMs(progress, progress.status === "running", now));
1619
+ const durationMs = d.mode === "chain" ? durations.reduce((sum, value) => sum + value, 0) : Math.max(0, ...durations);
1620
+ const summaryParts = [
1621
+ totalSummary.toolCount || totalSummary.tokens || durationMs
1622
+ ? `${totalSummary.toolCount} tools, ${formatTokens(totalSummary.tokens)} tok, ${hasRunning ? "" : "ran for "}${formatDuration(durationMs)}`
1623
+ : "",
1624
+ formatTotalCostStat(d.totalCost),
1625
+ ].filter(Boolean);
1626
+ const summaryStr = summaryParts.length ? ` | ${summaryParts.join(", ")}` : "";
1627
+ return fit(`${icon} ${theme.fg("toolTitle", theme.bold(modeLabel))}${contextBadge} · ${multiLabel.headerLabel}${summaryStr}`);
1628
+ }, frame, hasRunning));
1598
1629
  if (chainVis) {
1599
1630
  c.addChild(new Text(fit(` ${chainVis}`), 0, 0));
1600
1631
  }
@@ -1643,14 +1674,15 @@ export function renderSubagentResult(result, options, theme, frame) {
1643
1674
  : hasEmptyTextOutputWithoutOutputTarget(r.task, resultOutput)
1644
1675
  ? theme.fg("warning", "warning")
1645
1676
  : theme.fg("success", "done");
1646
- const stats = rProg ? ` | ${rProg.toolCount} tools, ${formatDuration(rProg.durationMs)}` : "";
1647
1677
  const modelDisplay = modelThinkingBadge(theme, r.model, r.thinking ?? (rProg && "thinking" in rProg ? rProg.thinking : undefined), r.modelSelection ?? (rProg && "modelSelection" in rProg ? rProg.modelSelection : undefined));
1648
1678
  const stepLabel = resultRowLabel(d, multiLabel, i, stepNumber);
1649
- const stepHeader = rRunning
1650
- ? `${statusIcon} ${stepLabel}: ${theme.bold(theme.fg("warning", r.agent))}${modelDisplay}${stats}`
1651
- : `${statusIcon} ${stepLabel}: ${theme.bold(r.agent)}${modelDisplay}${stats}`;
1652
1679
  const toolCallLines = getToolCallLines(r, expanded);
1653
- c.addChild(new Text(fit(stepHeader), 0, 0));
1680
+ c.addChild(animatedLine((_f, now) => {
1681
+ const stats = formatProgressStats(theme, rProg, true, { running: rRunning, terminal: !rRunning, now });
1682
+ return fit(rRunning
1683
+ ? `${statusIcon} ${stepLabel}: ${theme.bold(theme.fg("warning", r.agent))}${modelDisplay}${stats ? ` | ${stats}` : ""}`
1684
+ : `${statusIcon} ${stepLabel}: ${theme.bold(r.agent)}${modelDisplay}${stats ? ` | ${stats}` : ""}`);
1685
+ }, frame, rRunning));
1654
1686
  const taskMaxLen = Math.max(20, w - 12);
1655
1687
  const taskPreview = expanded || r.task.length <= taskMaxLen
1656
1688
  ? r.task