@ashx-j/lunr 0.2.20 → 0.2.21
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.
- package/CHANGELOG.md +13 -1
- package/dist/builtin-extensions/lunr-todos.d.ts +6 -5
- package/dist/builtin-extensions/lunr-todos.d.ts.map +1 -1
- package/dist/builtin-extensions/lunr-todos.js +9 -7
- package/dist/builtin-extensions/lunr-todos.js.map +1 -1
- package/dist/builtin-extensions/pi-intercom/broker/spawn.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-intercom/broker/spawn.js +30 -21
- package/dist/builtin-extensions/pi-intercom/broker/spawn.js.map +1 -1
- package/dist/builtin-extensions/pi-intercom/index.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-intercom/index.js +12 -3
- package/dist/builtin-extensions/pi-intercom/index.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/fanout-child.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/fanout-child.js +2 -2
- package/dist/builtin-extensions/pi-subagents/src/extension/fanout-child.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/index.d.ts +7 -6
- package/dist/builtin-extensions/pi-subagents/src/extension/index.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/index.js +63 -29
- package/dist/builtin-extensions/pi-subagents/src/extension/index.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/schemas.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/schemas.js +2 -2
- package/dist/builtin-extensions/pi-subagents/src/extension/schemas.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.d.ts +3 -3
- package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.js +3 -2
- package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/intercom/native-supervisor-channel.d.ts +1 -0
- package/dist/builtin-extensions/pi-subagents/src/intercom/native-supervisor-channel.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/intercom/native-supervisor-channel.js +26 -7
- package/dist/builtin-extensions/pi-subagents/src/intercom/native-supervisor-channel.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/intercom/result-intercom.d.ts +1 -0
- package/dist/builtin-extensions/pi-subagents/src/intercom/result-intercom.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/intercom/result-intercom.js +1 -1
- package/dist/builtin-extensions/pi-subagents/src/intercom/result-intercom.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/async-execution.d.ts +2 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/background/async-execution.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/async-execution.js +4 -3
- package/dist/builtin-extensions/pi-subagents/src/runs/background/async-execution.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/async-job-tracker.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/async-job-tracker.js +2 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/background/async-job-tracker.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.d.ts +6 -2
- package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.js +23 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/result-watcher.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/result-watcher.js +1 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/background/result-watcher.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.d.ts +100 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.js +46 -31
- package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/top-level-async.d.ts +15 -2
- package/dist/builtin-extensions/pi-subagents/src/runs/background/top-level-async.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/top-level-async.js +14 -4
- package/dist/builtin-extensions/pi-subagents/src/runs/background/top-level-async.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/wait-tool.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/wait-tool.js +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/wait-tool.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.js +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.d.ts +0 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.js +9 -9
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/completion-guard.d.ts +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/completion-guard.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/completion-guard.js +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/completion-guard.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/parallel-utils.d.ts +1 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/parallel-utils.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/parallel-utils.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/pi-args.d.ts +3 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/pi-args.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/pi-args.js +2 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/pi-args.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/task-intent.d.ts +2 -2
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/task-intent.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/task-intent.js +5 -10
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/task-intent.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/shared/async-guidance.d.ts +2 -0
- package/dist/builtin-extensions/pi-subagents/src/shared/async-guidance.d.ts.map +1 -0
- package/dist/builtin-extensions/pi-subagents/src/shared/async-guidance.js +3 -0
- package/dist/builtin-extensions/pi-subagents/src/shared/async-guidance.js.map +1 -0
- package/dist/builtin-extensions/pi-subagents/src/shared/types.d.ts +5 -0
- package/dist/builtin-extensions/pi-subagents/src/shared/types.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/shared/types.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/slash/delegation-adapters.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/slash/delegation-adapters.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/slash/prompt-workflows.d.ts +7 -0
- package/dist/builtin-extensions/pi-subagents/src/slash/prompt-workflows.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/slash/prompt-workflows.js +11 -7
- package/dist/builtin-extensions/pi-subagents/src/slash/prompt-workflows.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.d.ts +4 -0
- package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.js +22 -23
- package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/tui/render.d.ts +2 -0
- package/dist/builtin-extensions/pi-subagents/src/tui/render.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/tui/render.js +237 -374
- package/dist/builtin-extensions/pi-subagents/src/tui/render.js.map +1 -1
- package/dist/core/customize.d.ts +2 -0
- package/dist/core/customize.d.ts.map +1 -1
- package/dist/core/customize.js +3 -0
- package/dist/core/customize.js.map +1 -1
- package/dist/core/settings-manager.d.ts +4 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +11 -0
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/subagent-spinner-setting.d.ts +6 -0
- package/dist/core/subagent-spinner-setting.d.ts.map +1 -0
- package/dist/core/subagent-spinner-setting.js +12 -0
- package/dist/core/subagent-spinner-setting.js.map +1 -0
- package/dist/core/subagent-spinner.d.ts +4 -0
- package/dist/core/subagent-spinner.d.ts.map +1 -0
- package/dist/core/subagent-spinner.js +6 -0
- package/dist/core/subagent-spinner.js.map +1 -0
- package/dist/modes/interactive/components/settings-selector.d.ts +4 -0
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +73 -1
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/extension-widget-order.d.ts +8 -0
- package/dist/modes/interactive/extension-widget-order.d.ts.map +1 -0
- package/dist/modes/interactive/extension-widget-order.js +37 -0
- package/dist/modes/interactive/extension-widget-order.js.map +1 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +15 -22
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/node-runtime/{agent-session-services-75JKASCW.js → agent-session-services-C743TYQE.js} +4 -3
- package/dist/node-runtime/{builtin-extensions-X4JMM4ZS.js → builtin-extensions-JCOPAAB5.js} +2 -1
- package/dist/node-runtime/{chunk-QKFMBRAL.js → chunk-2BUAYZ7K.js} +94 -25
- package/dist/node-runtime/chunk-5ZH3ZFIZ.js +308 -0
- package/dist/node-runtime/{chunk-BBUVIEZB.js → chunk-A3KMVBZV.js} +10 -1
- package/dist/node-runtime/{chunk-K3646JTM.js → chunk-AWVD5IEY.js} +7 -307
- package/dist/node-runtime/{chunk-ELWEXVO5.js → chunk-GB2MGFLI.js} +11 -11
- package/dist/node-runtime/chunk-LISUTZS3.js +19 -0
- package/dist/node-runtime/{chunk-AL2FMKKM.js → chunk-PDNXVXMD.js} +12 -12
- package/dist/node-runtime/{chunk-46ECNOLF.js → chunk-SY2TFMLO.js} +57 -17
- package/dist/node-runtime/{chunk-HQCKFM2O.js → chunk-VGYZ3APQ.js} +3 -0
- package/dist/node-runtime/{chunk-4DJ6HEGH.js → chunk-VZR3NCM7.js} +3 -3
- package/dist/node-runtime/{chunk-AOFXZQKA.js → chunk-W3SILANP.js} +1 -1
- package/dist/node-runtime/{chunk-CBGB57XT.js → chunk-WLLDXJRT.js} +10 -0
- package/dist/node-runtime/{chunk-JYNNB7DU.js → chunk-XI77KVKA.js} +2 -2
- package/dist/node-runtime/{chunk-4CSFRBCN.js → chunk-Y5KOEMBH.js} +1 -1
- package/dist/node-runtime/{chunk-AROOY4BB.js → chunk-YMEAYRBE.js} +1 -1
- package/dist/node-runtime/{command-RBTRL55A.js → command-P4NYCJ2M.js} +1 -1
- package/dist/node-runtime/{customize-XEXL2DGQ.js → customize-LF5VST47.js} +1 -1
- package/dist/node-runtime/{gateway-L4ANRTVE.js → gateway-BM6NLOH4.js} +1 -1
- package/dist/node-runtime/index.js +13 -11
- package/dist/node-runtime/{interactive-mode-HPUNH7SV.js → interactive-mode-EVVBA64D.js} +9 -7
- package/dist/node-runtime/{lunr-cron-NNYTWTGF.js → lunr-cron-4VHP4E4B.js} +1 -1
- package/dist/node-runtime/main.js +11 -9
- package/dist/node-runtime/{package-manager-cli-7RKSZGEN.js → package-manager-cli-N37546V5.js} +5 -4
- package/dist/node-runtime/{pi-intercom-DDQMRNPJ.js → pi-intercom-NV2LW6X7.js} +34 -33
- package/dist/node-runtime/{pi-subagents-T5WMMLBB.js → pi-subagents-6MUIFNDM.js} +286 -345
- package/dist/node-runtime/rpc-entry.js +11 -9
- package/dist/node-runtime/{runtime-bridges-NJQERQ72.js → runtime-bridges-2VQTLPOZ.js} +2 -2
- package/dist/node-runtime/{settings-manager-GHPTUN7R.js → settings-manager-CUGAZWAB.js} +2 -1
- package/dist/node-runtime/{subagent-executor-SRFC26SJ.js → subagent-executor-MH4A7CCF.js} +14 -46
- package/dist/node-runtime/{update-cli-L3JIBH2U.js → update-cli-XTZMZGOL.js} +2 -1
- package/docs/features.md +6 -2
- package/docs/settings.md +2 -1
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/gondolin/package-lock.json +2 -2
- package/examples/extensions/gondolin/package.json +1 -1
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/package.json +4 -4
|
@@ -2,10 +2,11 @@
|
|
|
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 {
|
|
9
|
+
import { WIDGET_KEY, } from "../shared/types.js";
|
|
9
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";
|
|
@@ -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
|
-
|
|
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)
|
|
@@ -324,6 +334,7 @@ export function formatCompactSubagentRow(theme, width, parts) {
|
|
|
324
334
|
`${parts.prefix ?? ""}${parts.glyph} ${themeBold(theme, parts.description)}`,
|
|
325
335
|
parts.modelBadge ? theme.fg("dim", parts.modelBadge) : "",
|
|
326
336
|
theme.fg("dim", stats),
|
|
337
|
+
parts.terminalStatus ? theme.fg("dim", parts.terminalStatus) : "",
|
|
327
338
|
].filter(Boolean).join(` ${theme.fg("dim", "·")} `);
|
|
328
339
|
return truncLine(body, width);
|
|
329
340
|
}
|
|
@@ -417,14 +428,9 @@ function widgetStepsRunningSeed(steps) {
|
|
|
417
428
|
function widgetJobRunningSeed(job) {
|
|
418
429
|
return runningSeed(job.currentStep, job.runningSteps, widgetStepsRunningSeed(job.steps));
|
|
419
430
|
}
|
|
420
|
-
function widgetJobsRunningSeed(jobs) {
|
|
421
|
-
let seed;
|
|
422
|
-
for (const job of jobs)
|
|
423
|
-
seed = runningSeed(seed, widgetJobRunningSeed(job));
|
|
424
|
-
return seed;
|
|
425
|
-
}
|
|
426
431
|
function widgetAnimFrame(now = Date.now()) {
|
|
427
|
-
|
|
432
|
+
const definition = selectedSubagentSpinner();
|
|
433
|
+
return Math.floor(now / definition.interval) % definition.frames.length;
|
|
428
434
|
}
|
|
429
435
|
function widgetStatusGlyph(job, theme, now = Date.now()) {
|
|
430
436
|
if (job.status === "running")
|
|
@@ -605,7 +611,11 @@ function isDoneResult(result) {
|
|
|
605
611
|
return result.exitCode === 0;
|
|
606
612
|
}
|
|
607
613
|
function workflowGraphHasStatus(details, statuses) {
|
|
608
|
-
|
|
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);
|
|
609
619
|
}
|
|
610
620
|
function buildChainRenderEntries(details, label) {
|
|
611
621
|
if (details.mode !== "chain" || !label.hasParallelInChain || label.showActiveGroupOnly)
|
|
@@ -624,11 +634,20 @@ function buildChainRenderEntries(details, label) {
|
|
|
624
634
|
continue;
|
|
625
635
|
}
|
|
626
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);
|
|
627
641
|
entries.push({
|
|
628
642
|
kind: "result",
|
|
629
643
|
resultIndex: index,
|
|
630
644
|
rowNumber: index + 1,
|
|
631
|
-
agentName:
|
|
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,
|
|
632
651
|
});
|
|
633
652
|
}
|
|
634
653
|
}
|
|
@@ -969,6 +988,17 @@ function foregroundStyleWidgetDetails(job, theme, expanded, width) {
|
|
|
969
988
|
}
|
|
970
989
|
return lines;
|
|
971
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
|
+
}
|
|
972
1002
|
function compactJobProgress(job, step, now = Date.now()) {
|
|
973
1003
|
const running = (step?.status ?? job.status) === "running";
|
|
974
1004
|
const tokens = step?.tokens?.total ?? job.totalTokens?.total ?? 0;
|
|
@@ -990,18 +1020,6 @@ function compactJobLead(job, step) {
|
|
|
990
1020
|
task: step?.description ?? step?.agent,
|
|
991
1021
|
}) || widgetJobName(job);
|
|
992
1022
|
}
|
|
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
|
-
}
|
|
1005
1023
|
function compactJobLines(job, step, theme, width, now = Date.now()) {
|
|
1006
1024
|
const running = (step?.status ?? job.status) === "running";
|
|
1007
1025
|
const lead = compactJobLead(job, step);
|
|
@@ -1016,17 +1034,9 @@ function compactJobLines(job, step, theme, width, now = Date.now()) {
|
|
|
1016
1034
|
modelBadge,
|
|
1017
1035
|
tokens: progress.tokens,
|
|
1018
1036
|
durationMs: progress.durationMs,
|
|
1037
|
+
terminalStatus: compactTerminalStatus(step?.status ?? job.status),
|
|
1019
1038
|
})];
|
|
1020
1039
|
}
|
|
1021
|
-
function buildSingleWidgetLines(job, theme, width, _expanded, now = Date.now()) {
|
|
1022
|
-
const steps = job.steps ?? [];
|
|
1023
|
-
if (steps.length <= 1)
|
|
1024
|
-
return compactJobLines(job, steps[0], theme, width, now);
|
|
1025
|
-
return steps.flatMap((step) => compactJobLines(job, step, theme, width, now));
|
|
1026
|
-
}
|
|
1027
|
-
function compactSingleWidgetLines(job, theme, width, now = Date.now()) {
|
|
1028
|
-
return buildSingleWidgetLines(job, theme, width, false, now);
|
|
1029
|
-
}
|
|
1030
1040
|
const RESERVED_NON_WIDGET_ROWS = 19;
|
|
1031
1041
|
let widgetLayoutSession;
|
|
1032
1042
|
function resetWidgetLayoutSession() {
|
|
@@ -1047,37 +1057,6 @@ function widgetSessionMatches(expanded) {
|
|
|
1047
1057
|
&& widgetLayoutSession.rows === currentTerminalRows()
|
|
1048
1058
|
&& widgetLayoutSession.columns === currentTerminalColumns();
|
|
1049
1059
|
}
|
|
1050
|
-
function widgetHeaderCounts(jobs) {
|
|
1051
|
-
return {
|
|
1052
|
-
running: jobs.filter((job) => job.status === "running"),
|
|
1053
|
-
queued: jobs.filter((job) => job.status === "queued"),
|
|
1054
|
-
complete: jobs.filter((job) => job.status === "complete"),
|
|
1055
|
-
failed: jobs.filter((job) => job.status === "failed"),
|
|
1056
|
-
paused: jobs.filter((job) => job.status === "paused"),
|
|
1057
|
-
stopped: jobs.filter((job) => job.status === "stopped"),
|
|
1058
|
-
};
|
|
1059
|
-
}
|
|
1060
|
-
function buildSingleLineWidgetLines(jobs, theme, width) {
|
|
1061
|
-
const counts = widgetHeaderCounts(jobs);
|
|
1062
|
-
const hasActive = counts.running.length > 0 || counts.queued.length > 0;
|
|
1063
|
-
const glyph = counts.running.length > 0
|
|
1064
|
-
? runningGlyph((widgetJobsRunningSeed(counts.running) ?? 0) + widgetAnimFrame())
|
|
1065
|
-
: hasActive ? "●" : "○";
|
|
1066
|
-
const parts = [];
|
|
1067
|
-
if (counts.running.length > 0)
|
|
1068
|
-
parts.push(`${counts.running.length}/${jobs.length} running`);
|
|
1069
|
-
if (counts.queued.length > 0)
|
|
1070
|
-
parts.push(`${counts.queued.length} queued`);
|
|
1071
|
-
if (counts.failed.length > 0)
|
|
1072
|
-
parts.push(`${counts.failed.length} failed`);
|
|
1073
|
-
if (counts.stopped.length > 0)
|
|
1074
|
-
parts.push(`${counts.stopped.length} stopped`);
|
|
1075
|
-
if (counts.paused.length > 0)
|
|
1076
|
-
parts.push(`${counts.paused.length} paused`);
|
|
1077
|
-
if (!hasActive && counts.complete.length > 0)
|
|
1078
|
-
parts.push(`${counts.complete.length}/${jobs.length} done`);
|
|
1079
|
-
return [truncLine(`${theme.fg(hasActive ? "accent" : "dim", glyph)} ${theme.fg(hasActive ? "accent" : "dim", "subagents")} (${parts.join(", ") || `${jobs.length} total`})`, width)];
|
|
1080
|
-
}
|
|
1081
1060
|
function orderedWidgetJobs(jobs) {
|
|
1082
1061
|
return [
|
|
1083
1062
|
...jobs.filter((job) => job.status === "running"),
|
|
@@ -1085,118 +1064,6 @@ function orderedWidgetJobs(jobs) {
|
|
|
1085
1064
|
...jobs.filter((job) => job.status !== "running" && job.status !== "queued"),
|
|
1086
1065
|
];
|
|
1087
1066
|
}
|
|
1088
|
-
function progressiveJobKey(job) {
|
|
1089
|
-
return job.asyncId;
|
|
1090
|
-
}
|
|
1091
|
-
function isProgressiveActiveJob(job) {
|
|
1092
|
-
return job?.status === "running" || job?.status === "queued";
|
|
1093
|
-
}
|
|
1094
|
-
function selectProgressiveJobKeys(jobs, previousKeys, bodyRows) {
|
|
1095
|
-
if (bodyRows <= 0)
|
|
1096
|
-
return [];
|
|
1097
|
-
const jobsByKey = new Map(jobs.map((job) => [progressiveJobKey(job), job]));
|
|
1098
|
-
const selected = [];
|
|
1099
|
-
const append = (key) => {
|
|
1100
|
-
if (selected.includes(key) || !jobsByKey.has(key))
|
|
1101
|
-
return;
|
|
1102
|
-
selected.push(key);
|
|
1103
|
-
};
|
|
1104
|
-
for (const key of previousKeys) {
|
|
1105
|
-
if (!isProgressiveActiveJob(jobsByKey.get(key)))
|
|
1106
|
-
continue;
|
|
1107
|
-
append(key);
|
|
1108
|
-
if (selected.length >= bodyRows)
|
|
1109
|
-
return selected;
|
|
1110
|
-
}
|
|
1111
|
-
for (const job of orderedWidgetJobs(jobs)) {
|
|
1112
|
-
if (!isProgressiveActiveJob(job))
|
|
1113
|
-
continue;
|
|
1114
|
-
const key = progressiveJobKey(job);
|
|
1115
|
-
append(key);
|
|
1116
|
-
if (selected.length >= bodyRows)
|
|
1117
|
-
break;
|
|
1118
|
-
}
|
|
1119
|
-
if (selected.length >= bodyRows)
|
|
1120
|
-
return selected;
|
|
1121
|
-
for (const key of previousKeys) {
|
|
1122
|
-
if (isProgressiveActiveJob(jobsByKey.get(key)))
|
|
1123
|
-
continue;
|
|
1124
|
-
append(key);
|
|
1125
|
-
if (selected.length >= bodyRows)
|
|
1126
|
-
return selected;
|
|
1127
|
-
}
|
|
1128
|
-
for (const job of orderedWidgetJobs(jobs)) {
|
|
1129
|
-
const key = progressiveJobKey(job);
|
|
1130
|
-
append(key);
|
|
1131
|
-
if (selected.length >= bodyRows)
|
|
1132
|
-
break;
|
|
1133
|
-
}
|
|
1134
|
-
return selected;
|
|
1135
|
-
}
|
|
1136
|
-
function progressiveHeaderLine(jobs, theme, width) {
|
|
1137
|
-
const counts = widgetHeaderCounts(jobs);
|
|
1138
|
-
const hasActive = counts.running.length > 0 || counts.queued.length > 0;
|
|
1139
|
-
const glyph = counts.running.length > 0
|
|
1140
|
-
? runningGlyph((widgetJobsRunningSeed(counts.running) ?? 0) + widgetAnimFrame())
|
|
1141
|
-
: hasActive ? "●" : "○";
|
|
1142
|
-
const parts = [];
|
|
1143
|
-
if (counts.running.length > 0)
|
|
1144
|
-
parts.push(formatAgentRunningLabel(counts.running.length));
|
|
1145
|
-
if (counts.queued.length > 0)
|
|
1146
|
-
parts.push(`${counts.queued.length} queued`);
|
|
1147
|
-
if (!hasActive) {
|
|
1148
|
-
if (counts.failed.length > 0)
|
|
1149
|
-
parts.push(`${counts.failed.length} failed`);
|
|
1150
|
-
if (counts.stopped.length > 0)
|
|
1151
|
-
parts.push(`${counts.stopped.length} stopped`);
|
|
1152
|
-
if (counts.paused.length > 0)
|
|
1153
|
-
parts.push(`${counts.paused.length} paused`);
|
|
1154
|
-
if (counts.complete.length > 0)
|
|
1155
|
-
parts.push(`${counts.complete.length}/${jobs.length} done`);
|
|
1156
|
-
}
|
|
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);
|
|
1158
|
-
}
|
|
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}` : "";
|
|
1162
|
-
}
|
|
1163
|
-
function progressiveHiddenLine(hiddenJobs, theme, width) {
|
|
1164
|
-
const counts = widgetHeaderCounts(hiddenJobs);
|
|
1165
|
-
const parts = [];
|
|
1166
|
-
if (counts.running.length > 0)
|
|
1167
|
-
parts.push(`${counts.running.length} running`);
|
|
1168
|
-
if (counts.queued.length > 0)
|
|
1169
|
-
parts.push(`${counts.queued.length} queued`);
|
|
1170
|
-
const finished = counts.complete.length + counts.failed.length + counts.paused.length + counts.stopped.length;
|
|
1171
|
-
if (finished > 0)
|
|
1172
|
-
parts.push(`${finished} finished`);
|
|
1173
|
-
return truncLine(theme.fg("dim", ` +${hiddenJobs.length} more${parts.length ? ` (${parts.join(", ")})` : ""}`), width);
|
|
1174
|
-
}
|
|
1175
|
-
function buildProgressiveWidgetLines(jobs, theme, width, lockedRows, previousKeys) {
|
|
1176
|
-
const rowCount = Math.max(1, lockedRows);
|
|
1177
|
-
if (rowCount === 1)
|
|
1178
|
-
return { lines: buildSingleLineWidgetLines(jobs, theme, width), visibleJobKeys: [] };
|
|
1179
|
-
const bodyRows = rowCount - 1;
|
|
1180
|
-
let visibleJobKeys = selectProgressiveJobKeys(jobs, previousKeys, bodyRows);
|
|
1181
|
-
const jobsByKey = new Map(jobs.map((job) => [progressiveJobKey(job), job]));
|
|
1182
|
-
let visibleJobs = visibleJobKeys.map((key) => jobsByKey.get(key)).filter((job) => Boolean(job));
|
|
1183
|
-
let hiddenJobs = jobs.filter((job) => !visibleJobKeys.includes(progressiveJobKey(job)));
|
|
1184
|
-
const needsHiddenLine = hiddenJobs.length > 0;
|
|
1185
|
-
if (needsHiddenLine && visibleJobs.length >= bodyRows && bodyRows > 0) {
|
|
1186
|
-
visibleJobs = visibleJobs.slice(0, bodyRows - 1);
|
|
1187
|
-
visibleJobKeys = visibleJobs.map(progressiveJobKey);
|
|
1188
|
-
hiddenJobs = jobs.filter((job) => !visibleJobKeys.includes(progressiveJobKey(job)));
|
|
1189
|
-
}
|
|
1190
|
-
const lines = [
|
|
1191
|
-
progressiveHeaderLine(jobs, theme, width),
|
|
1192
|
-
...visibleJobs.map((job) => progressiveJobLine(job, theme, width)),
|
|
1193
|
-
];
|
|
1194
|
-
if (hiddenJobs.length > 0 && lines.length < rowCount)
|
|
1195
|
-
lines.push(progressiveHiddenLine(hiddenJobs, theme, width));
|
|
1196
|
-
while (lines.length < rowCount)
|
|
1197
|
-
lines.push(" ");
|
|
1198
|
-
return { lines: lines.slice(0, rowCount), visibleJobKeys };
|
|
1199
|
-
}
|
|
1200
1067
|
function collapsedWidgetLineBudget(rows) {
|
|
1201
1068
|
return Math.max(10, Math.min(14, Math.floor(rows * 0.35)));
|
|
1202
1069
|
}
|
|
@@ -1214,98 +1081,70 @@ function fitWidgetLineBudget(lines, theme, width, expanded) {
|
|
|
1214
1081
|
: `… ${hiddenCount} lines hidden · ${liveDetailKeyText()} expands`;
|
|
1215
1082
|
return [...lines.slice(0, visibleLines), truncLine(theme.fg("dim", hint), width)];
|
|
1216
1083
|
}
|
|
1217
|
-
function fitAdaptiveWidgetLines(
|
|
1084
|
+
function fitAdaptiveWidgetLines(_jobs, lines, theme, width, expanded) {
|
|
1218
1085
|
if (expanded) {
|
|
1219
1086
|
resetWidgetLayoutSession();
|
|
1220
1087
|
return fitWidgetLineBudget(lines, theme, width, true);
|
|
1221
1088
|
}
|
|
1222
|
-
const hasMatchingSession = widgetSessionMatches(expanded);
|
|
1223
1089
|
const rows = currentTerminalRows();
|
|
1224
1090
|
const columns = currentTerminalColumns();
|
|
1225
1091
|
const availableRows = estimateAvailableWidgetRows();
|
|
1226
|
-
if (hasMatchingSession && widgetLayoutSession?.tier === "single-line") {
|
|
1227
|
-
return buildSingleLineWidgetLines(jobs, theme, width);
|
|
1228
|
-
}
|
|
1229
|
-
if (hasMatchingSession && widgetLayoutSession?.tier === "progressive" && widgetLayoutSession.lockedRows !== undefined) {
|
|
1230
|
-
const rendered = buildProgressiveWidgetLines(jobs, theme, width, widgetLayoutSession.lockedRows, widgetLayoutSession.visibleJobKeys);
|
|
1231
|
-
widgetLayoutSession.visibleJobKeys = rendered.visibleJobKeys;
|
|
1232
|
-
return rendered.lines;
|
|
1233
|
-
}
|
|
1234
1092
|
if (lines.length <= availableRows) {
|
|
1235
|
-
widgetLayoutSession = { expanded, rows, columns, tier: "full"
|
|
1093
|
+
widgetLayoutSession = { expanded, rows, columns, tier: "full" };
|
|
1236
1094
|
return fitWidgetLineBudget(lines, theme, width, false);
|
|
1237
1095
|
}
|
|
1238
|
-
|
|
1239
|
-
widgetLayoutSession
|
|
1240
|
-
|
|
1241
|
-
}
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
const finished = jobs.filter((job) => job.status !== "running" && job.status !== "queued");
|
|
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) {
|
|
1255
1112
|
const lines = [];
|
|
1256
|
-
const
|
|
1257
|
-
const
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
}
|
|
1271
|
-
const row = compactJobChildRows(job, theme, Math.max(1, width - 3), now);
|
|
1272
|
-
items.push(expanded ? [...row, ...widgetParallelAgentDetails(job, theme, true, width)] : row);
|
|
1273
|
-
slots--;
|
|
1274
|
-
}
|
|
1275
|
-
if (queued.length > 0 && slots > 0) {
|
|
1276
|
-
items.push([`${theme.fg("muted", "◦")} ${theme.fg("dim", `${queued.length} queued`)}`]);
|
|
1277
|
-
queuedSummaryShown = true;
|
|
1278
|
-
slots--;
|
|
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));
|
|
1279
1127
|
}
|
|
1280
|
-
for (const
|
|
1281
|
-
|
|
1282
|
-
hiddenFinished++;
|
|
1283
|
-
continue;
|
|
1284
|
-
}
|
|
1285
|
-
const row = compactJobChildRows(job, theme, Math.max(1, width - 3), now);
|
|
1286
|
-
items.push(expanded ? [...row, ...widgetParallelAgentDetails(job, theme, true, width)] : row);
|
|
1287
|
-
slots--;
|
|
1128
|
+
for (const output of step?.recentOutput?.slice(-5) ?? []) {
|
|
1129
|
+
lines.push(truncLine(theme.fg("dim", ` ${output}`), width));
|
|
1288
1130
|
}
|
|
1289
|
-
const
|
|
1290
|
-
|
|
1291
|
-
if (hiddenTotal > 0) {
|
|
1292
|
-
const parts = [];
|
|
1293
|
-
if (hiddenRunning > 0)
|
|
1294
|
-
parts.push(`${hiddenRunning} running`);
|
|
1295
|
-
if (hiddenQueued > 0)
|
|
1296
|
-
parts.push(`${hiddenQueued} queued`);
|
|
1297
|
-
if (hiddenFinished > 0)
|
|
1298
|
-
parts.push(`${hiddenFinished} finished`);
|
|
1299
|
-
items.push([theme.fg("dim", `+${hiddenTotal} more (${parts.join(", ")})`)]);
|
|
1131
|
+
for (const nestedLine of formatNestedWidgetLines(step?.children ?? job.nestedChildren, theme, width, true, snapshotNow)) {
|
|
1132
|
+
lines.push(truncLine(` ${nestedLine}`, width));
|
|
1300
1133
|
}
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1134
|
+
return lines;
|
|
1135
|
+
}
|
|
1136
|
+
export function buildWidgetLines(jobs, theme, width = getTermWidth(), expanded = false, now = Date.now()) {
|
|
1137
|
+
const lines = [];
|
|
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));
|
|
1309
1148
|
}
|
|
1310
1149
|
}
|
|
1311
1150
|
return lines;
|
|
@@ -1366,7 +1205,7 @@ export class SubagentAsyncWidget {
|
|
|
1366
1205
|
return;
|
|
1367
1206
|
this.invalidate();
|
|
1368
1207
|
this.requestRender?.();
|
|
1369
|
-
},
|
|
1208
|
+
}, SUBAGENT_PAINT_INTERVAL_MS);
|
|
1370
1209
|
this.timer.unref?.();
|
|
1371
1210
|
}
|
|
1372
1211
|
stopTimer() {
|
|
@@ -1393,11 +1232,7 @@ export class SubagentAsyncWidget {
|
|
|
1393
1232
|
return this.cachedLines;
|
|
1394
1233
|
const now = this.nowFn();
|
|
1395
1234
|
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);
|
|
1235
|
+
const lines = buildWidgetLines(this.jobs, theme, innerWidth, this.expanded, now);
|
|
1401
1236
|
const fitted = fitAdaptiveWidgetLines(this.jobs, lines, theme, innerWidth, this.expanded);
|
|
1402
1237
|
const padded = fitted.map((line) => {
|
|
1403
1238
|
const withPad = ` ${line}`;
|
|
@@ -1448,123 +1283,113 @@ export function renderWidget(ctx, jobs) {
|
|
|
1448
1283
|
return widget;
|
|
1449
1284
|
});
|
|
1450
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;
|
|
1296
|
+
}
|
|
1451
1297
|
function renderSingleCompact(d, r, theme, frame) {
|
|
1452
1298
|
const output = r.truncation?.text || getSingleResultOutput(r);
|
|
1453
1299
|
const progress = r.progress || r.progressSummary;
|
|
1454
1300
|
const isRunning = r.progress?.status === "running";
|
|
1455
|
-
const c = new Container();
|
|
1456
1301
|
const width = getTermWidth() - 4;
|
|
1457
1302
|
const lead = compactRowLead({ description: r.description ?? r.agent, task: r.task });
|
|
1458
1303
|
const modelBadge = formatCompactModelBadge(r.modelSelection ?? progress?.modelSelection, r.model ?? progress?.model);
|
|
1459
|
-
|
|
1460
|
-
glyph: resultGlyph(r, output, theme, isRunning, undefined,
|
|
1304
|
+
return animatedLine((animationTick, now) => formatCompactSubagentRow(theme, width, {
|
|
1305
|
+
glyph: resultGlyph(r, output, theme, isRunning, undefined, foregroundSpinnerFrame(animationTick)),
|
|
1461
1306
|
description: lead,
|
|
1462
1307
|
modelBadge,
|
|
1463
1308
|
tokens: compactResultTokens(r),
|
|
1464
1309
|
durationMs: liveDurationMs(progress, isRunning, now),
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
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 }));
|
|
1343
|
+
}
|
|
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 });
|
|
1468
1351
|
}
|
|
1469
|
-
return
|
|
1352
|
+
return entries;
|
|
1470
1353
|
}
|
|
1471
1354
|
function renderMultiCompact(d, theme, frame) {
|
|
1472
|
-
const hasRunning = d.progress?.some((p) => p.status === "running")
|
|
1473
|
-
|| d.results.some((r) => r.progress?.status === "running")
|
|
1474
|
-
|| workflowGraphHasStatus(d, ["running"]);
|
|
1475
|
-
const stopped = d.results.some((r) => r.stopped && r.progress?.status !== "running")
|
|
1476
|
-
|| workflowGraphHasStatus(d, ["stopped"]);
|
|
1477
|
-
const failed = d.results.some((r) => !r.stopped && r.exitCode !== 0 && r.progress?.status !== "running")
|
|
1478
|
-
|| workflowGraphHasStatus(d, ["failed"]);
|
|
1479
|
-
const paused = d.results.some((r) => (r.interrupted || r.detached) && r.progress?.status !== "running")
|
|
1480
|
-
|| workflowGraphHasStatus(d, ["paused", "detached"]);
|
|
1481
|
-
let totalSummary = d.progressSummary;
|
|
1482
|
-
if (!totalSummary) {
|
|
1483
|
-
let sawProgress = false;
|
|
1484
|
-
const summary = { toolCount: 0, tokens: 0, durationMs: 0, lastActivityAt: undefined };
|
|
1485
|
-
for (const r of d.results) {
|
|
1486
|
-
const prog = r.progress || r.progressSummary;
|
|
1487
|
-
if (!prog)
|
|
1488
|
-
continue;
|
|
1489
|
-
sawProgress = true;
|
|
1490
|
-
summary.toolCount += prog.toolCount;
|
|
1491
|
-
summary.tokens += prog.tokens;
|
|
1492
|
-
summary.durationMs = d.mode === "chain" ? summary.durationMs + prog.durationMs : Math.max(summary.durationMs, prog.durationMs);
|
|
1493
|
-
if (prog.status === "running" && prog.lastActivityAt !== undefined) {
|
|
1494
|
-
summary.lastActivityAt = Math.max(summary.lastActivityAt ?? 0, prog.lastActivityAt);
|
|
1495
|
-
}
|
|
1496
|
-
}
|
|
1497
|
-
if (sawProgress)
|
|
1498
|
-
totalSummary = summary;
|
|
1499
|
-
}
|
|
1500
|
-
const multiLabel = buildMultiProgressLabel(d, hasRunning);
|
|
1501
|
-
const itemTitle = multiLabel.itemTitle;
|
|
1502
|
-
const glyph = (f) => hasRunning
|
|
1503
|
-
? theme.fg("accent", runningGlyph(f !== undefined ? (runningSeed(progressRunningSeed(totalSummary), d.currentStepIndex) ?? 0) + f : runningSeed(progressRunningSeed(totalSummary), d.currentStepIndex)))
|
|
1504
|
-
: stopped
|
|
1505
|
-
? theme.fg("warning", "■")
|
|
1506
|
-
: failed
|
|
1507
|
-
? theme.fg("error", "✗")
|
|
1508
|
-
: paused
|
|
1509
|
-
? theme.fg("warning", "■")
|
|
1510
|
-
: theme.fg("success", "✓");
|
|
1511
|
-
const contextBadge = d.context === "fork" ? theme.fg("warning", " [fork]") : "";
|
|
1512
1355
|
const c = new Container();
|
|
1513
1356
|
const width = getTermWidth() - 4;
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
}
|
|
1538
|
-
const i = entry.resultIndex;
|
|
1539
|
-
const r = d.results[i];
|
|
1540
|
-
const rowNumber = entry.rowNumber;
|
|
1541
|
-
const agentName = entry.agentName;
|
|
1542
|
-
if (!r) {
|
|
1543
|
-
const pendingLabel = chainEntries ? resultRowLabel(d, multiLabel, i, rowNumber) : `${itemTitle} ${rowNumber}`;
|
|
1544
|
-
c.addChild(new Text(truncLine(theme.fg("dim", ` ◦ ${pendingLabel}: ${agentName} · pending`), width), 0, 0));
|
|
1545
|
-
continue;
|
|
1546
|
-
}
|
|
1547
|
-
const output = getSingleResultOutput(r);
|
|
1548
|
-
const progressFromArray = d.progress?.find((p) => p.index === i) || d.progress?.find((p) => p.agent === r.agent && p.status === "running");
|
|
1549
|
-
const rProg = r.progress || progressFromArray || r.progressSummary;
|
|
1550
|
-
const rRunning = rProg && "status" in rProg && rProg.status === "running";
|
|
1551
|
-
const rPending = rProg && "status" in rProg && rProg.status === "pending";
|
|
1552
|
-
const lead = compactRowLead({ description: r.description ?? agentName, task: r.task });
|
|
1553
|
-
const modelBadge = formatCompactModelBadge(r.modelSelection ?? (rProg && "modelSelection" in rProg ? rProg.modelSelection : undefined), r.model ?? (rProg && "model" in rProg ? rProg.model : undefined));
|
|
1554
|
-
c.addChild(animatedLine((f, now) => {
|
|
1555
|
-
const rowGlyph = rPending ? theme.fg("dim", "◦") : resultGlyph(r, output, theme, rRunning, progressRunningSeed(rProg), f);
|
|
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);
|
|
1556
1380
|
return formatCompactSubagentRow(theme, width, {
|
|
1557
|
-
glyph:
|
|
1558
|
-
|
|
1381
|
+
glyph: result
|
|
1382
|
+
? resultGlyph(result, output, theme, running, progressRunningSeed(progress), animationFrame)
|
|
1383
|
+
: progressStatusGlyph({ ...progress, status, index: flatIndex }, theme, animationFrame),
|
|
1384
|
+
description,
|
|
1559
1385
|
modelBadge,
|
|
1560
|
-
tokens: compactResultTokens(
|
|
1561
|
-
durationMs: liveDurationMs(
|
|
1562
|
-
|
|
1386
|
+
tokens: result ? compactResultTokens(result) : progress?.tokens ?? 0,
|
|
1387
|
+
durationMs: liveDurationMs(progress, running, now),
|
|
1388
|
+
terminalStatus: result
|
|
1389
|
+
? compactResultTerminalStatus(result)
|
|
1390
|
+
: compactTerminalStatus(status),
|
|
1563
1391
|
});
|
|
1564
|
-
}, frame,
|
|
1565
|
-
if (!rPending && !rRunning && (r.exitCode !== 0 || r.interrupted || r.detached || r.stopped)) {
|
|
1566
|
-
c.addChild(new Text(truncLine(theme.fg(r.exitCode !== 0 ? "error" : "dim", ` ⎿ ${resultStatusLine(r, output)}`), width), 0, 0));
|
|
1567
|
-
}
|
|
1392
|
+
}, frame, running));
|
|
1568
1393
|
}
|
|
1569
1394
|
return c;
|
|
1570
1395
|
}
|
|
@@ -1573,7 +1398,9 @@ function renderMultiCompact(d, theme, frame) {
|
|
|
1573
1398
|
*/
|
|
1574
1399
|
export function renderSubagentResult(result, options, theme, frame) {
|
|
1575
1400
|
const d = result.details;
|
|
1576
|
-
|
|
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)) {
|
|
1577
1404
|
const t = result.content[0];
|
|
1578
1405
|
const text = t?.type === "text" ? t.text : "(no output)";
|
|
1579
1406
|
const contextPrefix = d?.context === "fork" ? `${theme.fg("warning", "[fork]")} ` : "";
|
|
@@ -1618,6 +1445,9 @@ export function renderSubagentResult(result, options, theme, frame) {
|
|
|
1618
1445
|
? r.task
|
|
1619
1446
|
: `${r.task.slice(0, taskMaxLen)}...`;
|
|
1620
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
|
+
}
|
|
1621
1451
|
c.addChild(new Spacer(1));
|
|
1622
1452
|
if (isRunning && r.progress) {
|
|
1623
1453
|
const progressSnapshotNow = snapshotNowForProgress(r.progress);
|
|
@@ -1690,6 +1520,7 @@ export function renderSubagentResult(result, options, theme, frame) {
|
|
|
1690
1520
|
const hasWorkflowFailure = workflowGraphHasStatus(d, ["failed"]);
|
|
1691
1521
|
const hasWorkflowStop = d.results.some((r) => r.stopped && r.progress?.status !== "running") || workflowGraphHasStatus(d, ["stopped"]);
|
|
1692
1522
|
const hasWorkflowPause = workflowGraphHasStatus(d, ["paused", "detached"]);
|
|
1523
|
+
const hasWorkflowPending = workflowGraphHasStatus(d, ["pending"]);
|
|
1693
1524
|
const icon = hasRunning
|
|
1694
1525
|
? theme.fg("warning", "running")
|
|
1695
1526
|
: hasEmptyWithoutTarget
|
|
@@ -1700,9 +1531,11 @@ export function renderSubagentResult(result, options, theme, frame) {
|
|
|
1700
1531
|
? theme.fg("warning", "stopped")
|
|
1701
1532
|
: hasWorkflowPause
|
|
1702
1533
|
? theme.fg("warning", "paused")
|
|
1703
|
-
:
|
|
1704
|
-
? theme.fg("
|
|
1705
|
-
:
|
|
1534
|
+
: hasWorkflowPending
|
|
1535
|
+
? theme.fg("dim", "pending")
|
|
1536
|
+
: ok === d.results.length
|
|
1537
|
+
? theme.fg("success", "ok")
|
|
1538
|
+
: theme.fg("error", "failed");
|
|
1706
1539
|
const totalSummary = d.progressSummary ||
|
|
1707
1540
|
d.results.reduce((acc, r) => {
|
|
1708
1541
|
const prog = r.progress || r.progressSummary;
|
|
@@ -1764,16 +1597,40 @@ export function renderSubagentResult(result, options, theme, frame) {
|
|
|
1764
1597
|
if (chainVis) {
|
|
1765
1598
|
c.addChild(new Text(fit(` ${chainVis}`), 0, 0));
|
|
1766
1599
|
}
|
|
1767
|
-
const useResultsDirectly = multiLabel.hasParallelInChain || !d.chainAgents?.length;
|
|
1768
|
-
const displayStart = multiLabel.showActiveGroupOnly ? multiLabel.groupStartIndex : 0;
|
|
1769
|
-
const displayEnd = multiLabel.showActiveGroupOnly ? multiLabel.groupEndIndex : (useResultsDirectly ? d.results.length : d.chainAgents.length);
|
|
1770
1600
|
const chainEntries = buildChainRenderEntries(d, multiLabel);
|
|
1771
|
-
const
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
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
|
+
};
|
|
1776
1632
|
});
|
|
1633
|
+
const renderEntries = chainEntries ?? fallbackEntries;
|
|
1777
1634
|
c.addChild(new Spacer(1));
|
|
1778
1635
|
for (const entry of renderEntries) {
|
|
1779
1636
|
if (entry.kind === "placeholder") {
|
|
@@ -1786,13 +1643,16 @@ export function renderSubagentResult(result, options, theme, frame) {
|
|
|
1786
1643
|
continue;
|
|
1787
1644
|
}
|
|
1788
1645
|
const i = entry.resultIndex;
|
|
1789
|
-
const r = d
|
|
1646
|
+
const r = resultAtFlatIndex(d, i);
|
|
1790
1647
|
const rowNumber = entry.rowNumber;
|
|
1791
1648
|
const agentName = entry.agentName;
|
|
1792
1649
|
if (!r) {
|
|
1793
|
-
const
|
|
1794
|
-
|
|
1795
|
-
c.addChild(new Text(theme.fg("dim", `
|
|
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));
|
|
1796
1656
|
c.addChild(new Spacer(1));
|
|
1797
1657
|
continue;
|
|
1798
1658
|
}
|
|
@@ -1823,6 +1683,9 @@ export function renderSubagentResult(result, options, theme, frame) {
|
|
|
1823
1683
|
? r.task
|
|
1824
1684
|
: `${r.task.slice(0, taskMaxLen)}...`;
|
|
1825
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
|
+
}
|
|
1826
1689
|
if (r.skills?.length) {
|
|
1827
1690
|
c.addChild(new Text(fit(theme.fg("dim", ` skills: ${r.skills.join(", ")}`)), 0, 0));
|
|
1828
1691
|
}
|