@ashx-j/lunr 0.2.19 → 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 +36 -1
- package/README.md +2 -2
- package/dist/builtin-extensions/index.d.ts.map +1 -1
- package/dist/builtin-extensions/index.js +0 -2
- package/dist/builtin-extensions/index.js.map +1 -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 +6 -4
- package/dist/builtin-extensions/pi-intercom/broker/spawn.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-intercom/broker/spawn.js +114 -61
- 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 +360 -351
- 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 +8 -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 +128 -57
- package/dist/builtin-extensions/pi-subagents/src/extension/index.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/schemas.d.ts +18 -8
- package/dist/builtin-extensions/pi-subagents/src/extension/schemas.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/schemas.js +38 -13
- 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 +4 -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 +24 -14
- 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 +8 -1
- 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 +247 -18
- 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/intercom/supervisor-ask.d.ts +29 -0
- package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-ask.d.ts.map +1 -0
- package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-ask.js +179 -0
- package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-ask.js.map +1 -0
- package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-questions.d.ts +89 -0
- package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-questions.d.ts.map +1 -0
- package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-questions.js +541 -0
- package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-questions.js.map +1 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/background/async-execution.d.ts +11 -1
- 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 +38 -12
- 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 +3 -2
- 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/async-resume.d.ts +2 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/async-resume.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/async-resume.js +35 -8
- package/dist/builtin-extensions/pi-subagents/src/runs/background/async-resume.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.d.ts +7 -3
- 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 +26 -4
- 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 +1 -0
- 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 +55 -38
- 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/subagent-wait.d.ts +3 -6
- package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-wait.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-wait.js +64 -5
- package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-wait.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 +2 -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/chain-execution.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.js +21 -8
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.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 +71 -25
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/acceptance.d.ts +2 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/acceptance.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/acceptance.js +75 -18
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/acceptance.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/model-fallback.d.ts +13 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.js +67 -11
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.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 +7 -2
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/pi-args.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.js +13 -3
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.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/child-spec.d.ts +3 -0
- package/dist/builtin-extensions/pi-subagents/src/shared/child-spec.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/shared/child-spec.js +68 -11
- package/dist/builtin-extensions/pi-subagents/src/shared/child-spec.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/shared/formatters.d.ts +12 -1
- package/dist/builtin-extensions/pi-subagents/src/shared/formatters.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/shared/formatters.js +21 -2
- package/dist/builtin-extensions/pi-subagents/src/shared/formatters.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/shared/types.d.ts +21 -4
- package/dist/builtin-extensions/pi-subagents/src/shared/types.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/shared/types.js +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 +6 -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 +46 -29
- 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 +46 -4
- package/dist/builtin-extensions/pi-subagents/src/tui/render.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/tui/render.js +407 -450
- package/dist/builtin-extensions/pi-subagents/src/tui/render.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/watchdog/register-main.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/watchdog/register-main.js +1 -1
- package/dist/builtin-extensions/pi-subagents/src/watchdog/register-main.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/watchdog/tool-actions.d.ts +2 -13
- package/dist/builtin-extensions/pi-subagents/src/watchdog/tool-actions.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/watchdog/tool-actions.js +5 -91
- package/dist/builtin-extensions/pi-subagents/src/watchdog/tool-actions.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/permissions.d.ts +1 -0
- package/dist/core/permissions.d.ts.map +1 -1
- package/dist/core/permissions.js +8 -4
- package/dist/core/permissions.js.map +1 -1
- package/dist/core/plan-mode.d.ts.map +1 -1
- package/dist/core/plan-mode.js +0 -5
- package/dist/core/plan-mode.js.map +1 -1
- package/dist/core/runtime-bridges.d.ts.map +1 -1
- package/dist/core/runtime-bridges.js +0 -2
- package/dist/core/runtime-bridges.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-cancellation.d.ts +21 -0
- package/dist/core/subagent-cancellation.d.ts.map +1 -0
- package/dist/core/subagent-cancellation.js +53 -0
- package/dist/core/subagent-cancellation.js.map +1 -0
- 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/assistant-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/assistant-message.js +12 -18
- package/dist/modes/interactive/components/assistant-message.js.map +1 -1
- 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/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +12 -0
- package/dist/modes/interactive/components/tool-execution.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 +1 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +44 -22
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/node-runtime/{agent-session-services-35WNVGMR.js → agent-session-services-C743TYQE.js} +6 -5
- package/dist/node-runtime/{builtin-extensions-322XDDEM.js → builtin-extensions-JCOPAAB5.js} +3 -2
- package/dist/node-runtime/{chunk-XATUM2HK.js → chunk-25I2BHAA.js} +1 -1
- package/dist/node-runtime/{chunk-TXHKBRHZ.js → chunk-2BUAYZ7K.js} +136 -53
- package/dist/node-runtime/chunk-5ZH3ZFIZ.js +308 -0
- package/dist/node-runtime/{chunk-J26TSGDL.js → chunk-6N22HULO.js} +8 -5
- package/dist/node-runtime/chunk-A3KMVBZV.js +60 -0
- package/dist/node-runtime/{chunk-4FX25LWP.js → chunk-AWVD5IEY.js} +20 -421
- package/dist/node-runtime/{chunk-ZRCBN365.js → chunk-GB2MGFLI.js} +12 -12
- package/dist/node-runtime/chunk-LISUTZS3.js +19 -0
- package/dist/node-runtime/{chunk-PNJSG3IZ.js → chunk-LTYWTR3V.js} +1 -369
- package/dist/node-runtime/{chunk-TFBIJTM3.js → chunk-PDNXVXMD.js} +13 -13
- package/dist/node-runtime/{chunk-MCUNIRD5.js → chunk-SY2TFMLO.js} +532 -261
- 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-W3SILANP.js +24 -0
- package/dist/node-runtime/{chunk-CBGB57XT.js → chunk-WLLDXJRT.js} +10 -0
- package/dist/node-runtime/{chunk-ATGA2WLC.js → chunk-XI77KVKA.js} +399 -36
- 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-DWUM5X3U.js → command-P4NYCJ2M.js} +1 -1
- package/dist/node-runtime/{customize-XEXL2DGQ.js → customize-LF5VST47.js} +1 -1
- package/dist/node-runtime/{gateway-UZXMFGWY.js → gateway-BM6NLOH4.js} +2 -2
- package/dist/node-runtime/index.js +16 -13
- package/dist/node-runtime/{interactive-mode-QT5IKGQ5.js → interactive-mode-EVVBA64D.js} +11 -8
- package/dist/node-runtime/{lunr-cron-QPBTKBGI.js → lunr-cron-4VHP4E4B.js} +2 -2
- package/dist/node-runtime/main.js +14 -12
- package/dist/node-runtime/{package-manager-cli-7RKSZGEN.js → package-manager-cli-N37546V5.js} +5 -4
- package/dist/node-runtime/{pi-intercom-EEMBGQID.js → pi-intercom-NV2LW6X7.js} +108 -87
- package/dist/node-runtime/{pi-subagents-7YJ3I4VE.js → pi-subagents-6MUIFNDM.js} +1262 -599
- package/dist/node-runtime/rpc-entry.js +14 -12
- package/dist/node-runtime/{runtime-bridges-3RKBDLNA.js → runtime-bridges-2VQTLPOZ.js} +3 -5
- package/dist/node-runtime/{settings-manager-GHPTUN7R.js → settings-manager-CUGAZWAB.js} +2 -1
- package/dist/node-runtime/{subagent-executor-5Q5A4HJ2.js → subagent-executor-MH4A7CCF.js} +181 -294
- package/dist/node-runtime/{update-cli-L3JIBH2U.js → update-cli-XTZMZGOL.js} +2 -1
- package/docs/features.md +22 -4
- package/docs/keybindings.md +3 -1
- package/docs/settings.md +3 -2
- 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
- package/dist/builtin-extensions/lunr-settings-tools.d.ts +0 -4
- package/dist/builtin-extensions/lunr-settings-tools.d.ts.map +0 -1
- package/dist/builtin-extensions/lunr-settings-tools.js +0 -120
- package/dist/builtin-extensions/lunr-settings-tools.js.map +0 -1
- package/dist/core/settings-tools-bridge.d.ts +0 -35
- package/dist/core/settings-tools-bridge.d.ts.map +0 -1
- package/dist/core/settings-tools-bridge.js +0 -56
- package/dist/core/settings-tools-bridge.js.map +0 -1
- package/dist/node-runtime/chunk-3NMWLTPV.js +0 -64
|
@@ -2,11 +2,12 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* Rendering functions for subagent results
|
|
4
4
|
*/
|
|
5
|
+
import { getSubagentSpinnerDefinition } from "../../../../core/subagent-spinner.js";
|
|
5
6
|
import { getMarkdownTheme } from "../../../../modes/interactive/theme/theme.js";
|
|
6
7
|
import { keyText } from "../../../../modes/interactive/components/keybinding-hints.js";
|
|
7
8
|
import { Container, Markdown, Spacer, Text, visibleWidth } from "@ashx-j/lunr-tui";
|
|
8
|
-
import {
|
|
9
|
-
import { formatTokens, formatUsage, formatDuration, formatModelSelection, formatToolCall, shortenPath } from "../shared/formatters.js";
|
|
9
|
+
import { WIDGET_KEY, } from "../shared/types.js";
|
|
10
|
+
import { formatTokens, formatUsage, formatDuration, formatModelSelection, formatCompactModelBadge, formatToolCall, shortenPath } from "../shared/formatters.js";
|
|
10
11
|
import { sanitizeChildDescription } from "../shared/child-spec.js";
|
|
11
12
|
import { getDisplayItems, getSingleResultOutput } from "../shared/utils.js";
|
|
12
13
|
import { flatToLogicalStepIndex } from "../runs/background/parallel-groups.js";
|
|
@@ -98,8 +99,12 @@ function wrapPlainText(text, maxWidth) {
|
|
|
98
99
|
}
|
|
99
100
|
return lines;
|
|
100
101
|
}
|
|
101
|
-
const RUNNING_FRAMES = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
|
|
102
102
|
const STATIC_RUNNING_GLYPH = "●";
|
|
103
|
+
export const SUBAGENT_PAINT_INTERVAL_MS = 80;
|
|
104
|
+
function selectedSubagentSpinner() {
|
|
105
|
+
const bridge = globalThis[Symbol.for("@lunr/customize")];
|
|
106
|
+
return getSubagentSpinnerDefinition(bridge?.getSubagentSpinner?.() ?? "braille");
|
|
107
|
+
}
|
|
103
108
|
function runningSeed(...values) {
|
|
104
109
|
let seed;
|
|
105
110
|
for (const value of values) {
|
|
@@ -112,7 +117,12 @@ function runningSeed(...values) {
|
|
|
112
117
|
function runningGlyph(seed) {
|
|
113
118
|
if (seed === undefined)
|
|
114
119
|
return STATIC_RUNNING_GLYPH;
|
|
115
|
-
|
|
120
|
+
const frames = selectedSubagentSpinner().frames;
|
|
121
|
+
return frames[Math.abs(seed) % frames.length];
|
|
122
|
+
}
|
|
123
|
+
function foregroundSpinnerFrame(timerFrame) {
|
|
124
|
+
const { interval } = selectedSubagentSpinner();
|
|
125
|
+
return Math.floor((Math.max(0, timerFrame) * SUBAGENT_PAINT_INTERVAL_MS) / interval);
|
|
116
126
|
}
|
|
117
127
|
function progressRunningSeed(progress) {
|
|
118
128
|
if (!progress)
|
|
@@ -202,6 +212,20 @@ function statJoin(theme, parts) {
|
|
|
202
212
|
function formatTokenStat(tokens) {
|
|
203
213
|
return `${formatTokens(tokens)} token`;
|
|
204
214
|
}
|
|
215
|
+
function usageTokenTotal(usage) {
|
|
216
|
+
if (!usage)
|
|
217
|
+
return 0;
|
|
218
|
+
return (usage.input ?? 0) + (usage.output ?? 0) + (usage.cacheRead ?? 0) + (usage.cacheWrite ?? 0);
|
|
219
|
+
}
|
|
220
|
+
function compactResultTokens(result) {
|
|
221
|
+
const progress = result.progress || result.progressSummary;
|
|
222
|
+
if (progress && progress.tokens > 0)
|
|
223
|
+
return progress.tokens;
|
|
224
|
+
const fromUsage = usageTokenTotal(result.usage);
|
|
225
|
+
if (fromUsage > 0)
|
|
226
|
+
return fromUsage;
|
|
227
|
+
return progress?.tokens ?? 0;
|
|
228
|
+
}
|
|
205
229
|
function formatToolUseStat(count) {
|
|
206
230
|
return `${count} tool use${count === 1 ? "" : "s"}`;
|
|
207
231
|
}
|
|
@@ -220,9 +244,10 @@ function formatTotalCostStat(totalCost) {
|
|
|
220
244
|
function liveDurationMs(progress, running, now) {
|
|
221
245
|
if (!progress)
|
|
222
246
|
return 0;
|
|
247
|
+
const durationMs = progress.durationMs ?? 0;
|
|
223
248
|
if (!running || progress.lastActivityAt === undefined)
|
|
224
|
-
return
|
|
225
|
-
return
|
|
249
|
+
return durationMs;
|
|
250
|
+
return durationMs + Math.max(0, now - progress.lastActivityAt);
|
|
226
251
|
}
|
|
227
252
|
function formatProgressStats(theme, progress, includeDuration = true, options = {}) {
|
|
228
253
|
if (!progress)
|
|
@@ -299,17 +324,19 @@ function resultGlyph(result, output, theme, running = result.progress?.status ==
|
|
|
299
324
|
return theme.fg("warning", "✓");
|
|
300
325
|
return theme.fg("success", "✓");
|
|
301
326
|
}
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
327
|
+
function formatCompactRowStats(tokens, durationMs) {
|
|
328
|
+
return `${formatTokenStat(tokens)} · ${durationMs > 0 ? formatDuration(durationMs) : "0ms"}`;
|
|
329
|
+
}
|
|
330
|
+
/** Unified compact row: glyph description · tier|model · tokens · time. */
|
|
331
|
+
export function formatCompactSubagentRow(theme, width, parts) {
|
|
332
|
+
const stats = formatCompactRowStats(parts.tokens, parts.durationMs);
|
|
307
333
|
const body = [
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
334
|
+
`${parts.prefix ?? ""}${parts.glyph} ${themeBold(theme, parts.description)}`,
|
|
335
|
+
parts.modelBadge ? theme.fg("dim", parts.modelBadge) : "",
|
|
336
|
+
theme.fg("dim", stats),
|
|
337
|
+
parts.terminalStatus ? theme.fg("dim", parts.terminalStatus) : "",
|
|
338
|
+
].filter(Boolean).join(` ${theme.fg("dim", "·")} `);
|
|
339
|
+
return truncLine(body, width);
|
|
313
340
|
}
|
|
314
341
|
export function widgetRenderKey(job) {
|
|
315
342
|
return JSON.stringify({
|
|
@@ -401,14 +428,9 @@ function widgetStepsRunningSeed(steps) {
|
|
|
401
428
|
function widgetJobRunningSeed(job) {
|
|
402
429
|
return runningSeed(job.currentStep, job.runningSteps, widgetStepsRunningSeed(job.steps));
|
|
403
430
|
}
|
|
404
|
-
function widgetJobsRunningSeed(jobs) {
|
|
405
|
-
let seed;
|
|
406
|
-
for (const job of jobs)
|
|
407
|
-
seed = runningSeed(seed, widgetJobRunningSeed(job));
|
|
408
|
-
return seed;
|
|
409
|
-
}
|
|
410
431
|
function widgetAnimFrame(now = Date.now()) {
|
|
411
|
-
|
|
432
|
+
const definition = selectedSubagentSpinner();
|
|
433
|
+
return Math.floor(now / definition.interval) % definition.frames.length;
|
|
412
434
|
}
|
|
413
435
|
function widgetStatusGlyph(job, theme, now = Date.now()) {
|
|
414
436
|
if (job.status === "running")
|
|
@@ -589,7 +611,11 @@ function isDoneResult(result) {
|
|
|
589
611
|
return result.exitCode === 0;
|
|
590
612
|
}
|
|
591
613
|
function workflowGraphHasStatus(details, statuses) {
|
|
592
|
-
|
|
614
|
+
const matches = (nodes) => nodes.some((node) => statuses.includes(node.status) || matches(node.children ?? []));
|
|
615
|
+
return matches(details.workflowGraph?.nodes ?? []);
|
|
616
|
+
}
|
|
617
|
+
function resultAtFlatIndex(details, flatIndex) {
|
|
618
|
+
return details.results.find((result, arrayIndex) => (result.progress?.index ?? result.progressSummary?.index ?? arrayIndex) === flatIndex);
|
|
593
619
|
}
|
|
594
620
|
function buildChainRenderEntries(details, label) {
|
|
595
621
|
if (details.mode !== "chain" || !label.hasParallelInChain || label.showActiveGroupOnly)
|
|
@@ -608,11 +634,20 @@ function buildChainRenderEntries(details, label) {
|
|
|
608
634
|
continue;
|
|
609
635
|
}
|
|
610
636
|
for (let index = span.start; index < span.start + span.count; index++) {
|
|
637
|
+
const workflowStep = details.workflowGraph?.nodes.find((node) => node.stepIndex === span.stepIndex);
|
|
638
|
+
const workflowNode = workflowStep?.children?.find((node) => node.flatIndex === index)
|
|
639
|
+
?? (workflowStep?.flatIndex === index ? workflowStep : undefined);
|
|
640
|
+
const result = resultAtFlatIndex(details, index);
|
|
611
641
|
entries.push({
|
|
612
642
|
kind: "result",
|
|
613
643
|
resultIndex: index,
|
|
614
644
|
rowNumber: index + 1,
|
|
615
|
-
agentName:
|
|
645
|
+
agentName: result?.agent
|
|
646
|
+
?? workflowNode?.label
|
|
647
|
+
?? details.chainAgents?.[span.stepIndex]
|
|
648
|
+
?? `step-${span.stepIndex + 1}`,
|
|
649
|
+
status: workflowNode?.status ?? span.status,
|
|
650
|
+
error: workflowNode?.error ?? span.error,
|
|
616
651
|
});
|
|
617
652
|
}
|
|
618
653
|
}
|
|
@@ -953,20 +988,31 @@ function foregroundStyleWidgetDetails(job, theme, expanded, width) {
|
|
|
953
988
|
}
|
|
954
989
|
return lines;
|
|
955
990
|
}
|
|
991
|
+
function compactTerminalStatus(status) {
|
|
992
|
+
if (status === "failed")
|
|
993
|
+
return "failed";
|
|
994
|
+
if (status === "paused")
|
|
995
|
+
return "paused";
|
|
996
|
+
if (status === "stopped")
|
|
997
|
+
return "stopped";
|
|
998
|
+
if (status === "detached")
|
|
999
|
+
return "detached";
|
|
1000
|
+
return undefined;
|
|
1001
|
+
}
|
|
956
1002
|
function compactJobProgress(job, step, now = Date.now()) {
|
|
957
1003
|
const running = (step?.status ?? job.status) === "running";
|
|
1004
|
+
const tokens = step?.tokens?.total ?? job.totalTokens?.total ?? 0;
|
|
1005
|
+
if (step?.durationMs !== undefined) {
|
|
1006
|
+
return {
|
|
1007
|
+
tokens,
|
|
1008
|
+
durationMs: liveDurationMs({ durationMs: step.durationMs, lastActivityAt: step.lastActivityAt }, running, now),
|
|
1009
|
+
};
|
|
1010
|
+
}
|
|
958
1011
|
const startedAt = step?.startedAt ?? job.startedAt;
|
|
1012
|
+
if (startedAt === undefined)
|
|
1013
|
+
return { tokens, durationMs: 0 };
|
|
959
1014
|
const endedAt = running ? now : step?.endedAt ?? step?.lastActivityAt ?? job.updatedAt ?? now;
|
|
960
|
-
|
|
961
|
-
? step.durationMs
|
|
962
|
-
: startedAt !== undefined
|
|
963
|
-
? Math.max(0, endedAt - startedAt)
|
|
964
|
-
: 0;
|
|
965
|
-
return {
|
|
966
|
-
toolCount: step?.toolCount ?? job.toolCount ?? 0,
|
|
967
|
-
tokens: step?.tokens?.total ?? job.totalTokens?.total ?? 0,
|
|
968
|
-
durationMs,
|
|
969
|
-
};
|
|
1015
|
+
return { tokens, durationMs: Math.max(0, endedAt - startedAt) };
|
|
970
1016
|
}
|
|
971
1017
|
function compactJobLead(job, step) {
|
|
972
1018
|
return compactRowLead({
|
|
@@ -977,26 +1023,19 @@ function compactJobLead(job, step) {
|
|
|
977
1023
|
function compactJobLines(job, step, theme, width, now = Date.now()) {
|
|
978
1024
|
const running = (step?.status ?? job.status) === "running";
|
|
979
1025
|
const lead = compactJobLead(job, step);
|
|
980
|
-
const modelBadge =
|
|
981
|
-
const permissionBadge = step?.permissions ? theme.fg("dim", step.permissions) : "";
|
|
1026
|
+
const modelBadge = formatCompactModelBadge(step?.modelSelection, step?.model);
|
|
982
1027
|
const glyph = step
|
|
983
1028
|
? widgetStepGlyph(step.status, theme, running ? (widgetStepRunningSeed(step, step.index) ?? 0) + widgetAnimFrame(now) : widgetStepRunningSeed(step, step.index))
|
|
984
1029
|
: widgetStatusGlyph(job, theme, now);
|
|
985
|
-
const
|
|
986
|
-
return [
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
if (steps.length <= 1)
|
|
995
|
-
return compactJobLines(job, steps[0], theme, width, now);
|
|
996
|
-
return steps.flatMap((step) => compactJobLines(job, step, theme, width, now));
|
|
997
|
-
}
|
|
998
|
-
function compactSingleWidgetLines(job, theme, width) {
|
|
999
|
-
return buildSingleWidgetLines(job, theme, width, false);
|
|
1030
|
+
const progress = compactJobProgress(job, step, now);
|
|
1031
|
+
return [formatCompactSubagentRow(theme, width, {
|
|
1032
|
+
glyph,
|
|
1033
|
+
description: lead,
|
|
1034
|
+
modelBadge,
|
|
1035
|
+
tokens: progress.tokens,
|
|
1036
|
+
durationMs: progress.durationMs,
|
|
1037
|
+
terminalStatus: compactTerminalStatus(step?.status ?? job.status),
|
|
1038
|
+
})];
|
|
1000
1039
|
}
|
|
1001
1040
|
const RESERVED_NON_WIDGET_ROWS = 19;
|
|
1002
1041
|
let widgetLayoutSession;
|
|
@@ -1018,35 +1057,6 @@ function widgetSessionMatches(expanded) {
|
|
|
1018
1057
|
&& widgetLayoutSession.rows === currentTerminalRows()
|
|
1019
1058
|
&& widgetLayoutSession.columns === currentTerminalColumns();
|
|
1020
1059
|
}
|
|
1021
|
-
function widgetHeaderCounts(jobs) {
|
|
1022
|
-
return {
|
|
1023
|
-
running: jobs.filter((job) => job.status === "running"),
|
|
1024
|
-
queued: jobs.filter((job) => job.status === "queued"),
|
|
1025
|
-
complete: jobs.filter((job) => job.status === "complete"),
|
|
1026
|
-
failed: jobs.filter((job) => job.status === "failed"),
|
|
1027
|
-
paused: jobs.filter((job) => job.status === "paused"),
|
|
1028
|
-
stopped: jobs.filter((job) => job.status === "stopped"),
|
|
1029
|
-
};
|
|
1030
|
-
}
|
|
1031
|
-
function buildSingleLineWidgetLines(jobs, theme, width) {
|
|
1032
|
-
const counts = widgetHeaderCounts(jobs);
|
|
1033
|
-
const hasActive = counts.running.length > 0 || counts.queued.length > 0;
|
|
1034
|
-
const glyph = counts.running.length > 0 ? runningGlyph(widgetJobsRunningSeed(counts.running)) : hasActive ? "●" : "○";
|
|
1035
|
-
const parts = [];
|
|
1036
|
-
if (counts.running.length > 0)
|
|
1037
|
-
parts.push(`${counts.running.length}/${jobs.length} running`);
|
|
1038
|
-
if (counts.queued.length > 0)
|
|
1039
|
-
parts.push(`${counts.queued.length} queued`);
|
|
1040
|
-
if (counts.failed.length > 0)
|
|
1041
|
-
parts.push(`${counts.failed.length} failed`);
|
|
1042
|
-
if (counts.stopped.length > 0)
|
|
1043
|
-
parts.push(`${counts.stopped.length} stopped`);
|
|
1044
|
-
if (counts.paused.length > 0)
|
|
1045
|
-
parts.push(`${counts.paused.length} paused`);
|
|
1046
|
-
if (!hasActive && counts.complete.length > 0)
|
|
1047
|
-
parts.push(`${counts.complete.length}/${jobs.length} done`);
|
|
1048
|
-
return [truncLine(`${theme.fg(hasActive ? "accent" : "dim", glyph)} ${theme.fg(hasActive ? "accent" : "dim", "subagents")} (${parts.join(", ") || `${jobs.length} total`})`, width)];
|
|
1049
|
-
}
|
|
1050
1060
|
function orderedWidgetJobs(jobs) {
|
|
1051
1061
|
return [
|
|
1052
1062
|
...jobs.filter((job) => job.status === "running"),
|
|
@@ -1054,124 +1064,6 @@ function orderedWidgetJobs(jobs) {
|
|
|
1054
1064
|
...jobs.filter((job) => job.status !== "running" && job.status !== "queued"),
|
|
1055
1065
|
];
|
|
1056
1066
|
}
|
|
1057
|
-
function progressiveJobKey(job) {
|
|
1058
|
-
return job.asyncId;
|
|
1059
|
-
}
|
|
1060
|
-
function isProgressiveActiveJob(job) {
|
|
1061
|
-
return job?.status === "running" || job?.status === "queued";
|
|
1062
|
-
}
|
|
1063
|
-
function selectProgressiveJobKeys(jobs, previousKeys, bodyRows) {
|
|
1064
|
-
if (bodyRows <= 0)
|
|
1065
|
-
return [];
|
|
1066
|
-
const jobsByKey = new Map(jobs.map((job) => [progressiveJobKey(job), job]));
|
|
1067
|
-
const selected = [];
|
|
1068
|
-
const append = (key) => {
|
|
1069
|
-
if (selected.includes(key) || !jobsByKey.has(key))
|
|
1070
|
-
return;
|
|
1071
|
-
selected.push(key);
|
|
1072
|
-
};
|
|
1073
|
-
for (const key of previousKeys) {
|
|
1074
|
-
if (!isProgressiveActiveJob(jobsByKey.get(key)))
|
|
1075
|
-
continue;
|
|
1076
|
-
append(key);
|
|
1077
|
-
if (selected.length >= bodyRows)
|
|
1078
|
-
return selected;
|
|
1079
|
-
}
|
|
1080
|
-
for (const job of orderedWidgetJobs(jobs)) {
|
|
1081
|
-
if (!isProgressiveActiveJob(job))
|
|
1082
|
-
continue;
|
|
1083
|
-
const key = progressiveJobKey(job);
|
|
1084
|
-
append(key);
|
|
1085
|
-
if (selected.length >= bodyRows)
|
|
1086
|
-
break;
|
|
1087
|
-
}
|
|
1088
|
-
if (selected.length >= bodyRows)
|
|
1089
|
-
return selected;
|
|
1090
|
-
for (const key of previousKeys) {
|
|
1091
|
-
if (isProgressiveActiveJob(jobsByKey.get(key)))
|
|
1092
|
-
continue;
|
|
1093
|
-
append(key);
|
|
1094
|
-
if (selected.length >= bodyRows)
|
|
1095
|
-
return selected;
|
|
1096
|
-
}
|
|
1097
|
-
for (const job of orderedWidgetJobs(jobs)) {
|
|
1098
|
-
const key = progressiveJobKey(job);
|
|
1099
|
-
append(key);
|
|
1100
|
-
if (selected.length >= bodyRows)
|
|
1101
|
-
break;
|
|
1102
|
-
}
|
|
1103
|
-
return selected;
|
|
1104
|
-
}
|
|
1105
|
-
function progressiveHeaderLine(jobs, theme, width) {
|
|
1106
|
-
const counts = widgetHeaderCounts(jobs);
|
|
1107
|
-
const hasActive = counts.running.length > 0 || counts.queued.length > 0;
|
|
1108
|
-
const glyph = counts.running.length > 0 ? runningGlyph(widgetJobsRunningSeed(counts.running)) : hasActive ? "●" : "○";
|
|
1109
|
-
const parts = [];
|
|
1110
|
-
if (counts.running.length > 0)
|
|
1111
|
-
parts.push(formatAgentRunningLabel(counts.running.length));
|
|
1112
|
-
if (counts.queued.length > 0)
|
|
1113
|
-
parts.push(`${counts.queued.length} queued`);
|
|
1114
|
-
if (!hasActive) {
|
|
1115
|
-
if (counts.failed.length > 0)
|
|
1116
|
-
parts.push(`${counts.failed.length} failed`);
|
|
1117
|
-
if (counts.stopped.length > 0)
|
|
1118
|
-
parts.push(`${counts.stopped.length} stopped`);
|
|
1119
|
-
if (counts.paused.length > 0)
|
|
1120
|
-
parts.push(`${counts.paused.length} paused`);
|
|
1121
|
-
if (counts.complete.length > 0)
|
|
1122
|
-
parts.push(`${counts.complete.length}/${jobs.length} done`);
|
|
1123
|
-
}
|
|
1124
|
-
return truncLine(`${theme.fg(hasActive ? "accent" : "dim", glyph)} ${theme.fg(hasActive ? "accent" : "dim", "Async agents")} ${theme.fg("dim", "·")} ${theme.fg("dim", parts.join(", ") || `${jobs.length} total`)}`, width);
|
|
1125
|
-
}
|
|
1126
|
-
function progressiveJobLine(job, theme, width) {
|
|
1127
|
-
const stats = widgetStats(job, theme);
|
|
1128
|
-
const activity = widgetActivity(job);
|
|
1129
|
-
const status = job.status === "complete" ? "done" : job.status;
|
|
1130
|
-
const parts = [
|
|
1131
|
-
themeBold(theme, widgetJobName(job)),
|
|
1132
|
-
theme.fg("dim", status),
|
|
1133
|
-
stats,
|
|
1134
|
-
activity && activity.toLowerCase() !== status ? theme.fg("dim", activity) : "",
|
|
1135
|
-
].filter(Boolean);
|
|
1136
|
-
return truncLine(` ${widgetStatusGlyph(job, theme)} ${parts.join(` ${theme.fg("dim", "·")} `)}`, width);
|
|
1137
|
-
}
|
|
1138
|
-
function progressiveHiddenLine(hiddenJobs, theme, width) {
|
|
1139
|
-
const counts = widgetHeaderCounts(hiddenJobs);
|
|
1140
|
-
const parts = [];
|
|
1141
|
-
if (counts.running.length > 0)
|
|
1142
|
-
parts.push(`${counts.running.length} running`);
|
|
1143
|
-
if (counts.queued.length > 0)
|
|
1144
|
-
parts.push(`${counts.queued.length} queued`);
|
|
1145
|
-
const finished = counts.complete.length + counts.failed.length + counts.paused.length + counts.stopped.length;
|
|
1146
|
-
if (finished > 0)
|
|
1147
|
-
parts.push(`${finished} finished`);
|
|
1148
|
-
return truncLine(theme.fg("dim", ` +${hiddenJobs.length} more${parts.length ? ` (${parts.join(", ")})` : ""}`), width);
|
|
1149
|
-
}
|
|
1150
|
-
function buildProgressiveWidgetLines(jobs, theme, width, lockedRows, previousKeys) {
|
|
1151
|
-
const rowCount = Math.max(1, lockedRows);
|
|
1152
|
-
if (rowCount === 1)
|
|
1153
|
-
return { lines: buildSingleLineWidgetLines(jobs, theme, width), visibleJobKeys: [] };
|
|
1154
|
-
const bodyRows = rowCount - 1;
|
|
1155
|
-
let visibleJobKeys = selectProgressiveJobKeys(jobs, previousKeys, bodyRows);
|
|
1156
|
-
const jobsByKey = new Map(jobs.map((job) => [progressiveJobKey(job), job]));
|
|
1157
|
-
let visibleJobs = visibleJobKeys.map((key) => jobsByKey.get(key)).filter((job) => Boolean(job));
|
|
1158
|
-
let hiddenJobs = jobs.filter((job) => !visibleJobKeys.includes(progressiveJobKey(job)));
|
|
1159
|
-
const needsHiddenLine = hiddenJobs.length > 0;
|
|
1160
|
-
if (needsHiddenLine && visibleJobs.length >= bodyRows && bodyRows > 0) {
|
|
1161
|
-
visibleJobs = visibleJobs.slice(0, bodyRows - 1);
|
|
1162
|
-
visibleJobKeys = visibleJobs.map(progressiveJobKey);
|
|
1163
|
-
hiddenJobs = jobs.filter((job) => !visibleJobKeys.includes(progressiveJobKey(job)));
|
|
1164
|
-
}
|
|
1165
|
-
const lines = [
|
|
1166
|
-
progressiveHeaderLine(jobs, theme, width),
|
|
1167
|
-
...visibleJobs.map((job) => progressiveJobLine(job, theme, width)),
|
|
1168
|
-
];
|
|
1169
|
-
if (hiddenJobs.length > 0 && lines.length < rowCount)
|
|
1170
|
-
lines.push(progressiveHiddenLine(hiddenJobs, theme, width));
|
|
1171
|
-
while (lines.length < rowCount)
|
|
1172
|
-
lines.push(" ");
|
|
1173
|
-
return { lines: lines.slice(0, rowCount), visibleJobKeys };
|
|
1174
|
-
}
|
|
1175
1067
|
function collapsedWidgetLineBudget(rows) {
|
|
1176
1068
|
return Math.max(10, Math.min(14, Math.floor(rows * 0.35)));
|
|
1177
1069
|
}
|
|
@@ -1189,143 +1081,178 @@ function fitWidgetLineBudget(lines, theme, width, expanded) {
|
|
|
1189
1081
|
: `… ${hiddenCount} lines hidden · ${liveDetailKeyText()} expands`;
|
|
1190
1082
|
return [...lines.slice(0, visibleLines), truncLine(theme.fg("dim", hint), width)];
|
|
1191
1083
|
}
|
|
1192
|
-
function fitAdaptiveWidgetLines(
|
|
1084
|
+
function fitAdaptiveWidgetLines(_jobs, lines, theme, width, expanded) {
|
|
1193
1085
|
if (expanded) {
|
|
1194
1086
|
resetWidgetLayoutSession();
|
|
1195
1087
|
return fitWidgetLineBudget(lines, theme, width, true);
|
|
1196
1088
|
}
|
|
1197
|
-
const hasMatchingSession = widgetSessionMatches(expanded);
|
|
1198
1089
|
const rows = currentTerminalRows();
|
|
1199
1090
|
const columns = currentTerminalColumns();
|
|
1200
1091
|
const availableRows = estimateAvailableWidgetRows();
|
|
1201
|
-
if (hasMatchingSession && widgetLayoutSession?.tier === "single-line") {
|
|
1202
|
-
return buildSingleLineWidgetLines(jobs, theme, width);
|
|
1203
|
-
}
|
|
1204
|
-
if (hasMatchingSession && widgetLayoutSession?.tier === "progressive" && widgetLayoutSession.lockedRows !== undefined) {
|
|
1205
|
-
const rendered = buildProgressiveWidgetLines(jobs, theme, width, widgetLayoutSession.lockedRows, widgetLayoutSession.visibleJobKeys);
|
|
1206
|
-
widgetLayoutSession.visibleJobKeys = rendered.visibleJobKeys;
|
|
1207
|
-
return rendered.lines;
|
|
1208
|
-
}
|
|
1209
1092
|
if (lines.length <= availableRows) {
|
|
1210
|
-
widgetLayoutSession = { expanded, rows, columns, tier: "full"
|
|
1093
|
+
widgetLayoutSession = { expanded, rows, columns, tier: "full" };
|
|
1211
1094
|
return fitWidgetLineBudget(lines, theme, width, false);
|
|
1212
1095
|
}
|
|
1213
|
-
|
|
1214
|
-
widgetLayoutSession
|
|
1215
|
-
|
|
1096
|
+
const lockedRows = widgetSessionMatches(expanded) && widgetLayoutSession?.tier === "progressive"
|
|
1097
|
+
? widgetLayoutSession.lockedRows ?? 1
|
|
1098
|
+
: Math.max(1, Math.min(availableRows, collapsedWidgetLineBudget(rows)));
|
|
1099
|
+
widgetLayoutSession = { expanded, rows, columns, tier: "progressive", lockedRows };
|
|
1100
|
+
if (lockedRows === 1)
|
|
1101
|
+
return lines.slice(0, 1);
|
|
1102
|
+
const visibleCount = Math.max(1, lockedRows - 1);
|
|
1103
|
+
const visible = lines.slice(0, visibleCount);
|
|
1104
|
+
const hidden = lines.length - visible.length;
|
|
1105
|
+
if (hidden > 0)
|
|
1106
|
+
visible.push(truncLine(theme.fg("dim", `+${hidden} more`), width));
|
|
1107
|
+
while (visible.length < lockedRows)
|
|
1108
|
+
visible.push(" ");
|
|
1109
|
+
return visible.slice(0, lockedRows);
|
|
1110
|
+
}
|
|
1111
|
+
function widgetExpandedDiagnostics(job, step, index, theme, width, now) {
|
|
1112
|
+
const lines = [];
|
|
1113
|
+
const status = step?.status ?? job.status;
|
|
1114
|
+
const runLabel = step ? `${job.asyncId}:${step.index ?? index}` : job.asyncId;
|
|
1115
|
+
lines.push(truncLine(theme.fg("dim", ` ⎿ run ${runLabel} · ${status}`), width));
|
|
1116
|
+
const error = step?.error;
|
|
1117
|
+
if (error)
|
|
1118
|
+
lines.push(truncLine(theme.fg("error", ` ${error}`), width));
|
|
1119
|
+
const snapshotNow = status === "running" ? now : step?.endedAt ?? job.updatedAt;
|
|
1120
|
+
const activity = step
|
|
1121
|
+
? widgetStepActivityLine(step, Math.max(1, width - 4), true, snapshotNow)
|
|
1122
|
+
: widgetActivity(job, now);
|
|
1123
|
+
if (activity)
|
|
1124
|
+
lines.push(truncLine(theme.fg("dim", ` ${activity}`), width));
|
|
1125
|
+
for (const tool of step?.recentTools?.slice(-3) ?? []) {
|
|
1126
|
+
lines.push(truncLine(theme.fg("dim", ` ${tool.tool}${tool.args ? `: ${tool.args}` : ""}`), width));
|
|
1216
1127
|
}
|
|
1217
|
-
const
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
}
|
|
1222
|
-
|
|
1223
|
-
return
|
|
1224
|
-
const width = getTermWidth();
|
|
1225
|
-
const lines = expanded
|
|
1226
|
-
? buildWidgetLines(jobs, theme, width, true)
|
|
1227
|
-
: jobs.length === 1
|
|
1228
|
-
? compactSingleWidgetLines(jobs[0], theme, width)
|
|
1229
|
-
: buildWidgetLines(jobs, theme, width, false);
|
|
1230
|
-
const container = new Container();
|
|
1231
|
-
for (const line of fitAdaptiveWidgetLines(jobs, lines, theme, width, expanded))
|
|
1232
|
-
container.addChild(new Text(line, 1, 0));
|
|
1233
|
-
return container;
|
|
1234
|
-
};
|
|
1128
|
+
for (const output of step?.recentOutput?.slice(-5) ?? []) {
|
|
1129
|
+
lines.push(truncLine(theme.fg("dim", ` ${output}`), width));
|
|
1130
|
+
}
|
|
1131
|
+
for (const nestedLine of formatNestedWidgetLines(step?.children ?? job.nestedChildren, theme, width, true, snapshotNow)) {
|
|
1132
|
+
lines.push(truncLine(` ${nestedLine}`, width));
|
|
1133
|
+
}
|
|
1134
|
+
return lines;
|
|
1235
1135
|
}
|
|
1236
|
-
export function buildWidgetLines(jobs, theme, width = getTermWidth(), expanded = false) {
|
|
1237
|
-
if (jobs.length === 0)
|
|
1238
|
-
return [];
|
|
1239
|
-
if (jobs.length === 1)
|
|
1240
|
-
return buildSingleWidgetLines(jobs[0], theme, width, expanded);
|
|
1241
|
-
const running = jobs.filter((job) => job.status === "running");
|
|
1242
|
-
const queued = jobs.filter((job) => job.status === "queued");
|
|
1243
|
-
const finished = jobs.filter((job) => job.status !== "running" && job.status !== "queued");
|
|
1136
|
+
export function buildWidgetLines(jobs, theme, width = getTermWidth(), expanded = false, now = Date.now()) {
|
|
1244
1137
|
const lines = [];
|
|
1245
|
-
const
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
hiddenRunning++;
|
|
1256
|
-
continue;
|
|
1138
|
+
for (const job of orderedWidgetJobs(jobs)) {
|
|
1139
|
+
const steps = job.steps?.length
|
|
1140
|
+
? job.steps
|
|
1141
|
+
: job.agents?.length
|
|
1142
|
+
? job.agents.map((agent, index) => ({ agent, description: agent, status: job.status, index }))
|
|
1143
|
+
: [undefined];
|
|
1144
|
+
for (const [index, step] of steps.entries()) {
|
|
1145
|
+
lines.push(...compactJobLines(job, step, theme, width, now));
|
|
1146
|
+
if (expanded)
|
|
1147
|
+
lines.push(...widgetExpandedDiagnostics(job, step, index, theme, width, now));
|
|
1257
1148
|
}
|
|
1258
|
-
const stats = widgetStats(job, theme);
|
|
1259
|
-
items.push([
|
|
1260
|
-
`${widgetStatusGlyph(job, theme)} ${themeBold(theme, widgetJobName(job))}${stats ? ` ${theme.fg("dim", "·")} ${stats}` : ""}`,
|
|
1261
|
-
` ${theme.fg("dim", `⎿ ${widgetActivity(job)}`)}`,
|
|
1262
|
-
...widgetParallelAgentDetails(job, theme, expanded, width),
|
|
1263
|
-
]);
|
|
1264
|
-
slots--;
|
|
1265
1149
|
}
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1150
|
+
return lines;
|
|
1151
|
+
}
|
|
1152
|
+
let activeWidget;
|
|
1153
|
+
export class SubagentAsyncWidget {
|
|
1154
|
+
jobs;
|
|
1155
|
+
expanded;
|
|
1156
|
+
theme;
|
|
1157
|
+
requestRender;
|
|
1158
|
+
nowFn;
|
|
1159
|
+
timer;
|
|
1160
|
+
disposed = false;
|
|
1161
|
+
cachedWidth;
|
|
1162
|
+
cachedLines;
|
|
1163
|
+
constructor(jobs, theme, options) {
|
|
1164
|
+
this.jobs = jobs;
|
|
1165
|
+
this.theme = theme;
|
|
1166
|
+
this.expanded = options?.expanded ?? false;
|
|
1167
|
+
this.requestRender = options?.requestRender;
|
|
1168
|
+
this.nowFn = options?.now ?? Date.now;
|
|
1169
|
+
this.syncTimer();
|
|
1270
1170
|
}
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
continue;
|
|
1275
|
-
}
|
|
1276
|
-
const stats = widgetStats(job, theme);
|
|
1277
|
-
items.push([
|
|
1278
|
-
`${widgetStatusGlyph(job, theme)} ${themeBold(theme, widgetJobName(job))}${stats ? ` ${theme.fg("dim", "·")} ${stats}` : ""}`,
|
|
1279
|
-
` ${theme.fg("dim", `⎿ ${widgetActivity(job)}`)}`,
|
|
1280
|
-
...widgetParallelAgentDetails(job, theme, expanded, width),
|
|
1281
|
-
]);
|
|
1282
|
-
slots--;
|
|
1171
|
+
setTheme(theme) {
|
|
1172
|
+
this.theme = theme;
|
|
1173
|
+
this.invalidate();
|
|
1283
1174
|
}
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
if (hiddenRunning > 0)
|
|
1289
|
-
parts.push(`${hiddenRunning} running`);
|
|
1290
|
-
if (hiddenQueued > 0)
|
|
1291
|
-
parts.push(`${hiddenQueued} queued`);
|
|
1292
|
-
if (hiddenFinished > 0)
|
|
1293
|
-
parts.push(`${hiddenFinished} finished`);
|
|
1294
|
-
items.push([theme.fg("dim", `+${hiddenTotal} more (${parts.join(", ")})`)]);
|
|
1175
|
+
setJobs(jobs) {
|
|
1176
|
+
this.jobs = jobs;
|
|
1177
|
+
this.invalidate();
|
|
1178
|
+
this.syncTimer();
|
|
1295
1179
|
}
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
lines.push(truncLine(`${theme.fg("dim", branch)} ${item[0]}`, width));
|
|
1302
|
-
for (const detail of item.slice(1)) {
|
|
1303
|
-
lines.push(truncLine(`${theme.fg("dim", continuation)} ${detail}`, width));
|
|
1304
|
-
}
|
|
1180
|
+
setExpanded(expanded) {
|
|
1181
|
+
if (this.expanded === expanded)
|
|
1182
|
+
return;
|
|
1183
|
+
this.expanded = expanded;
|
|
1184
|
+
this.invalidate();
|
|
1305
1185
|
}
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
let widgetPaintTimer;
|
|
1309
|
-
let widgetPaintCtx;
|
|
1310
|
-
export function clearWidgetPaintTimer() {
|
|
1311
|
-
if (widgetPaintTimer) {
|
|
1312
|
-
clearInterval(widgetPaintTimer);
|
|
1313
|
-
widgetPaintTimer = undefined;
|
|
1186
|
+
setRequestRender(requestRender) {
|
|
1187
|
+
this.requestRender = requestRender;
|
|
1314
1188
|
}
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
function ensureWidgetPaintTimer(ctx, running) {
|
|
1318
|
-
widgetPaintCtx = ctx;
|
|
1319
|
-
if (!running || !ctx.hasUI) {
|
|
1320
|
-
clearWidgetPaintTimer();
|
|
1321
|
-
return;
|
|
1189
|
+
hasRunning() {
|
|
1190
|
+
return this.jobs.some((job) => job.status === "running");
|
|
1322
1191
|
}
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1192
|
+
syncTimer() {
|
|
1193
|
+
if (this.disposed)
|
|
1194
|
+
return;
|
|
1195
|
+
if (this.hasRunning())
|
|
1196
|
+
this.startTimer();
|
|
1197
|
+
else
|
|
1198
|
+
this.stopTimer();
|
|
1199
|
+
}
|
|
1200
|
+
startTimer() {
|
|
1201
|
+
if (this.timer)
|
|
1202
|
+
return;
|
|
1203
|
+
this.timer = setInterval(() => {
|
|
1204
|
+
if (this.disposed)
|
|
1205
|
+
return;
|
|
1206
|
+
this.invalidate();
|
|
1207
|
+
this.requestRender?.();
|
|
1208
|
+
}, SUBAGENT_PAINT_INTERVAL_MS);
|
|
1209
|
+
this.timer.unref?.();
|
|
1210
|
+
}
|
|
1211
|
+
stopTimer() {
|
|
1212
|
+
if (!this.timer)
|
|
1213
|
+
return;
|
|
1214
|
+
clearInterval(this.timer);
|
|
1215
|
+
this.timer = undefined;
|
|
1216
|
+
}
|
|
1217
|
+
invalidate() {
|
|
1218
|
+
this.cachedWidth = undefined;
|
|
1219
|
+
this.cachedLines = undefined;
|
|
1220
|
+
}
|
|
1221
|
+
dispose() {
|
|
1222
|
+
this.disposed = true;
|
|
1223
|
+
this.stopTimer();
|
|
1224
|
+
if (activeWidget === this)
|
|
1225
|
+
activeWidget = undefined;
|
|
1226
|
+
}
|
|
1227
|
+
render(width) {
|
|
1228
|
+
const theme = this.theme;
|
|
1229
|
+
if (!theme)
|
|
1230
|
+
return [];
|
|
1231
|
+
if (this.cachedLines && this.cachedWidth === width && !this.hasRunning())
|
|
1232
|
+
return this.cachedLines;
|
|
1233
|
+
const now = this.nowFn();
|
|
1234
|
+
const innerWidth = Math.max(1, width - 2);
|
|
1235
|
+
const lines = buildWidgetLines(this.jobs, theme, innerWidth, this.expanded, now);
|
|
1236
|
+
const fitted = fitAdaptiveWidgetLines(this.jobs, lines, theme, innerWidth, this.expanded);
|
|
1237
|
+
const padded = fitted.map((line) => {
|
|
1238
|
+
const withPad = ` ${line}`;
|
|
1239
|
+
const vis = visibleWidth(withPad);
|
|
1240
|
+
return withPad + " ".repeat(Math.max(0, width - vis));
|
|
1241
|
+
});
|
|
1242
|
+
this.cachedWidth = width;
|
|
1243
|
+
this.cachedLines = padded;
|
|
1244
|
+
return padded;
|
|
1245
|
+
}
|
|
1246
|
+
}
|
|
1247
|
+
export function createSubagentWidgetComponent(jobs, theme, options) {
|
|
1248
|
+
return new SubagentAsyncWidget(jobs, theme, options);
|
|
1249
|
+
}
|
|
1250
|
+
export function disposeSubagentWidget() {
|
|
1251
|
+
activeWidget?.dispose();
|
|
1252
|
+
activeWidget = undefined;
|
|
1253
|
+
}
|
|
1254
|
+
export function clearWidgetPaintTimer() {
|
|
1255
|
+
disposeSubagentWidget();
|
|
1329
1256
|
}
|
|
1330
1257
|
/**
|
|
1331
1258
|
* Render the async jobs widget
|
|
@@ -1333,144 +1260,136 @@ function ensureWidgetPaintTimer(ctx, running) {
|
|
|
1333
1260
|
export function renderWidget(ctx, jobs) {
|
|
1334
1261
|
if (jobs.length === 0) {
|
|
1335
1262
|
resetWidgetLayoutSession();
|
|
1336
|
-
|
|
1263
|
+
disposeSubagentWidget();
|
|
1337
1264
|
if (ctx.hasUI)
|
|
1338
1265
|
ctx.ui.setWidget(WIDGET_KEY, undefined);
|
|
1339
1266
|
return;
|
|
1340
1267
|
}
|
|
1341
1268
|
if (!ctx.hasUI)
|
|
1342
1269
|
return;
|
|
1343
|
-
|
|
1344
|
-
|
|
1270
|
+
const expanded = ctx.ui.getToolsExpanded?.() ?? false;
|
|
1271
|
+
const requestRender = () => ctx.ui.requestRender?.();
|
|
1272
|
+
if (activeWidget) {
|
|
1273
|
+
activeWidget.setJobs(jobs);
|
|
1274
|
+
activeWidget.setExpanded(expanded);
|
|
1275
|
+
activeWidget.setRequestRender(requestRender);
|
|
1276
|
+
ctx.ui.requestRender?.();
|
|
1277
|
+
return;
|
|
1278
|
+
}
|
|
1279
|
+
const widget = new SubagentAsyncWidget(jobs, undefined, { expanded, requestRender });
|
|
1280
|
+
activeWidget = widget;
|
|
1281
|
+
ctx.ui.setWidget(WIDGET_KEY, (_tui, theme) => {
|
|
1282
|
+
widget.setTheme(theme);
|
|
1283
|
+
return widget;
|
|
1284
|
+
});
|
|
1285
|
+
}
|
|
1286
|
+
function compactResultTerminalStatus(result) {
|
|
1287
|
+
if (result.stopped)
|
|
1288
|
+
return "stopped";
|
|
1289
|
+
if (result.detached)
|
|
1290
|
+
return "detached";
|
|
1291
|
+
if (result.interrupted)
|
|
1292
|
+
return "paused";
|
|
1293
|
+
if (result.exitCode !== 0)
|
|
1294
|
+
return "failed";
|
|
1295
|
+
return undefined;
|
|
1345
1296
|
}
|
|
1346
1297
|
function renderSingleCompact(d, r, theme, frame) {
|
|
1347
1298
|
const output = r.truncation?.text || getSingleResultOutput(r);
|
|
1348
1299
|
const progress = r.progress || r.progressSummary;
|
|
1349
1300
|
const isRunning = r.progress?.status === "running";
|
|
1350
|
-
const contextBadge = d.context === "fork" ? theme.fg("warning", " [fork]") : "";
|
|
1351
|
-
// lunr: simplified collapsed row — glyph · task summary · agent type · runtime/tools/tokens stats.
|
|
1352
|
-
const c = new Container();
|
|
1353
1301
|
const width = getTermWidth() - 4;
|
|
1354
|
-
// lunr: row line is a per-frame template so the running glyph animates in place (see subagentAnimSink).
|
|
1355
1302
|
const lead = compactRowLead({ description: r.description ?? r.agent, task: r.task });
|
|
1356
|
-
const modelBadge =
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1303
|
+
const modelBadge = formatCompactModelBadge(r.modelSelection ?? progress?.modelSelection, r.model ?? progress?.model);
|
|
1304
|
+
return animatedLine((animationTick, now) => formatCompactSubagentRow(theme, width, {
|
|
1305
|
+
glyph: resultGlyph(r, output, theme, isRunning, undefined, foregroundSpinnerFrame(animationTick)),
|
|
1306
|
+
description: lead,
|
|
1307
|
+
modelBadge,
|
|
1308
|
+
tokens: compactResultTokens(r),
|
|
1309
|
+
durationMs: liveDurationMs(progress, isRunning, now),
|
|
1310
|
+
terminalStatus: compactResultTerminalStatus(r),
|
|
1311
|
+
}), frame, isRunning);
|
|
1312
|
+
}
|
|
1313
|
+
function progressStatusGlyph(progress, theme, frame) {
|
|
1314
|
+
if (!progress || progress.status === "pending")
|
|
1315
|
+
return theme.fg("muted", "◦");
|
|
1316
|
+
if (progress.status === "running")
|
|
1317
|
+
return theme.fg("accent", runningGlyph((progressRunningSeed(progress) ?? 0) + (frame ?? 0)));
|
|
1318
|
+
if (progress.status === "completed")
|
|
1319
|
+
return theme.fg("success", "✓");
|
|
1320
|
+
if (progress.status === "failed")
|
|
1321
|
+
return theme.fg("error", "✗");
|
|
1322
|
+
return theme.fg("warning", "■");
|
|
1323
|
+
}
|
|
1324
|
+
function flattenCompactWorkflowNodes(nodes) {
|
|
1325
|
+
const rows = [];
|
|
1326
|
+
for (const node of nodes) {
|
|
1327
|
+
if (node.children?.length)
|
|
1328
|
+
rows.push(...flattenCompactWorkflowNodes(node.children));
|
|
1329
|
+
else
|
|
1330
|
+
rows.push(node);
|
|
1331
|
+
}
|
|
1332
|
+
return rows;
|
|
1333
|
+
}
|
|
1334
|
+
function compactForegroundEntries(d) {
|
|
1335
|
+
const workflowNodes = flattenCompactWorkflowNodes(d.workflowGraph?.nodes ?? []);
|
|
1336
|
+
if (workflowNodes.length === 0) {
|
|
1337
|
+
const progressCount = d.progress?.reduce((count, entry) => Math.max(count, entry.index + 1), 0) ?? 0;
|
|
1338
|
+
const chainCount = d.mode === "chain"
|
|
1339
|
+
? buildChainStepSpans(d).reduce((count, span) => Math.max(count, span.start + span.count), 0)
|
|
1340
|
+
: 0;
|
|
1341
|
+
const count = Math.max(d.results.length, progressCount, d.chainChildren?.length ?? 0, d.chainAgents?.length ?? 0, chainCount);
|
|
1342
|
+
return Array.from({ length: count }, (_, flatIndex) => ({ flatIndex }));
|
|
1365
1343
|
}
|
|
1366
|
-
|
|
1367
|
-
const
|
|
1368
|
-
|
|
1369
|
-
|
|
1344
|
+
const entries = workflowNodes.map((node) => ({ flatIndex: node.flatIndex, node }));
|
|
1345
|
+
const seen = new Set(entries.flatMap((entry) => entry.flatIndex === undefined ? [] : [entry.flatIndex]));
|
|
1346
|
+
const progressCount = d.progress?.reduce((count, entry) => Math.max(count, entry.index + 1), 0) ?? 0;
|
|
1347
|
+
const dataCount = Math.max(d.results.length, progressCount, d.chainChildren?.length ?? 0);
|
|
1348
|
+
for (let flatIndex = 0; flatIndex < dataCount; flatIndex++) {
|
|
1349
|
+
if (!seen.has(flatIndex))
|
|
1350
|
+
entries.push({ flatIndex });
|
|
1370
1351
|
}
|
|
1371
|
-
|
|
1372
|
-
c.addChild(new Text(truncLine(theme.fg("dim", ` session: ${shortenPath(r.sessionFile)}`), width), 0, 0));
|
|
1373
|
-
return c;
|
|
1352
|
+
return entries;
|
|
1374
1353
|
}
|
|
1375
1354
|
function renderMultiCompact(d, theme, frame) {
|
|
1376
|
-
const hasRunning = d.progress?.some((p) => p.status === "running")
|
|
1377
|
-
|| d.results.some((r) => r.progress?.status === "running")
|
|
1378
|
-
|| workflowGraphHasStatus(d, ["running"]);
|
|
1379
|
-
const stopped = d.results.some((r) => r.stopped && r.progress?.status !== "running")
|
|
1380
|
-
|| workflowGraphHasStatus(d, ["stopped"]);
|
|
1381
|
-
const failed = d.results.some((r) => !r.stopped && r.exitCode !== 0 && r.progress?.status !== "running")
|
|
1382
|
-
|| workflowGraphHasStatus(d, ["failed"]);
|
|
1383
|
-
const paused = d.results.some((r) => (r.interrupted || r.detached) && r.progress?.status !== "running")
|
|
1384
|
-
|| workflowGraphHasStatus(d, ["paused", "detached"]);
|
|
1385
|
-
let totalSummary = d.progressSummary;
|
|
1386
|
-
if (!totalSummary) {
|
|
1387
|
-
let sawProgress = false;
|
|
1388
|
-
const summary = { toolCount: 0, tokens: 0, durationMs: 0, lastActivityAt: undefined };
|
|
1389
|
-
for (const r of d.results) {
|
|
1390
|
-
const prog = r.progress || r.progressSummary;
|
|
1391
|
-
if (!prog)
|
|
1392
|
-
continue;
|
|
1393
|
-
sawProgress = true;
|
|
1394
|
-
summary.toolCount += prog.toolCount;
|
|
1395
|
-
summary.tokens += prog.tokens;
|
|
1396
|
-
summary.durationMs = d.mode === "chain" ? summary.durationMs + prog.durationMs : Math.max(summary.durationMs, prog.durationMs);
|
|
1397
|
-
if (prog.status === "running" && prog.lastActivityAt !== undefined) {
|
|
1398
|
-
summary.lastActivityAt = Math.max(summary.lastActivityAt ?? 0, prog.lastActivityAt);
|
|
1399
|
-
}
|
|
1400
|
-
}
|
|
1401
|
-
if (sawProgress)
|
|
1402
|
-
totalSummary = summary;
|
|
1403
|
-
}
|
|
1404
|
-
const multiLabel = buildMultiProgressLabel(d, hasRunning);
|
|
1405
|
-
const itemTitle = multiLabel.itemTitle;
|
|
1406
|
-
const glyph = (f) => hasRunning
|
|
1407
|
-
? theme.fg("accent", runningGlyph(f !== undefined ? (runningSeed(progressRunningSeed(totalSummary), d.currentStepIndex) ?? 0) + f : runningSeed(progressRunningSeed(totalSummary), d.currentStepIndex)))
|
|
1408
|
-
: stopped
|
|
1409
|
-
? theme.fg("warning", "■")
|
|
1410
|
-
: failed
|
|
1411
|
-
? theme.fg("error", "✗")
|
|
1412
|
-
: paused
|
|
1413
|
-
? theme.fg("warning", "■")
|
|
1414
|
-
: theme.fg("success", "✓");
|
|
1415
|
-
const contextBadge = d.context === "fork" ? theme.fg("warning", " [fork]") : "";
|
|
1416
1355
|
const c = new Container();
|
|
1417
1356
|
const width = getTermWidth() - 4;
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
const
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
const rProg = r.progress || progressFromArray || r.progressSummary;
|
|
1455
|
-
const rRunning = rProg && "status" in rProg && rProg.status === "running";
|
|
1456
|
-
const rPending = rProg && "status" in rProg && rProg.status === "pending";
|
|
1457
|
-
const pendingLabel = rPending ? ` ${theme.fg("dim", "· pending")}` : "";
|
|
1458
|
-
// lunr: simplified collapsed row — glyph · task summary · agent type · runtime/tools/tokens stats.
|
|
1459
|
-
// lunr: row line is a per-frame template so the running glyph animates in place (see subagentAnimSink).
|
|
1460
|
-
const lead = compactRowLead({ description: r.description ?? agentName, task: r.task });
|
|
1461
|
-
const permissionBadge = r.permissions ? theme.fg("dim", r.permissions) : "";
|
|
1462
|
-
const modelBadge = formatModelSelection(r.modelSelection ?? (rProg && "modelSelection" in rProg ? rProg.modelSelection : undefined), r.model ?? (rProg && "model" in rProg ? rProg.model : undefined), r.thinking ?? (rProg && "thinking" in rProg ? rProg.thinking : undefined));
|
|
1463
|
-
c.addChild(animatedLine((f, now) => {
|
|
1464
|
-
const glyph = rPending ? theme.fg("dim", "◦") : resultGlyph(r, output, theme, rRunning, progressRunningSeed(rProg), f);
|
|
1465
|
-
const stepStats = formatProgressStats(theme, rProg, true, { running: !!rRunning, terminal: !rRunning && !rPending, now });
|
|
1466
|
-
return truncLine(` ${glyph} ${themeBold(theme, lead)}${modelBadge ? ` ${theme.fg("dim", "·")} ${theme.fg("dim", modelBadge)}` : ""}${permissionBadge ? ` ${theme.fg("dim", "·")} ${permissionBadge}` : ""}${stepStats ? ` ${theme.fg("dim", "·")} ${stepStats}` : ""}${pendingLabel}`, width);
|
|
1467
|
-
}, frame, !!rRunning));
|
|
1468
|
-
if (rRunning && rProg && "status" in rProg) {
|
|
1469
|
-
c.addChild(animatedLine((_f, now) => formatCompactStatsHangLine(rProg, width, (s) => theme.fg("dim", s), " ⎿ ", now, true), frame, true));
|
|
1470
|
-
}
|
|
1471
|
-
else if (!rPending && (r.exitCode !== 0 || r.interrupted || r.detached || hasEmptyTextOutputWithoutOutputTarget(r.task, output))) {
|
|
1472
|
-
c.addChild(new Text(truncLine(theme.fg(r.exitCode !== 0 ? "error" : "dim", ` ⎿ ${resultStatusLine(r, output)}`), width), 0, 0));
|
|
1473
|
-
}
|
|
1357
|
+
const entries = compactForegroundEntries(d);
|
|
1358
|
+
for (const [rowIndex, entry] of entries.entries()) {
|
|
1359
|
+
const flatIndex = entry.flatIndex;
|
|
1360
|
+
const result = flatIndex === undefined ? undefined : resultAtFlatIndex(d, flatIndex);
|
|
1361
|
+
const progress = result?.progress
|
|
1362
|
+
?? (flatIndex === undefined ? undefined : d.progress?.find((candidate) => candidate.index === flatIndex))
|
|
1363
|
+
?? result?.progressSummary;
|
|
1364
|
+
const status = progress?.status ?? entry.node?.status ?? "pending";
|
|
1365
|
+
const description = compactRowLead({
|
|
1366
|
+
description: result?.description
|
|
1367
|
+
?? progress?.description
|
|
1368
|
+
?? entry.node?.label
|
|
1369
|
+
?? (flatIndex === undefined ? undefined : d.chainChildren?.[flatIndex]?.description)
|
|
1370
|
+
?? (flatIndex === undefined ? undefined : d.chainAgents?.[flatIndex])
|
|
1371
|
+
?? result?.agent
|
|
1372
|
+
?? progress?.agent,
|
|
1373
|
+
task: result?.task ?? progress?.task,
|
|
1374
|
+
}) || `child ${rowIndex + 1}`;
|
|
1375
|
+
const running = status === "running";
|
|
1376
|
+
const output = result ? getSingleResultOutput(result) : "";
|
|
1377
|
+
const modelBadge = formatCompactModelBadge(result?.modelSelection ?? progress?.modelSelection, result?.model ?? progress?.model);
|
|
1378
|
+
c.addChild(animatedLine((animationTick, now) => {
|
|
1379
|
+
const animationFrame = foregroundSpinnerFrame(animationTick);
|
|
1380
|
+
return formatCompactSubagentRow(theme, width, {
|
|
1381
|
+
glyph: result
|
|
1382
|
+
? resultGlyph(result, output, theme, running, progressRunningSeed(progress), animationFrame)
|
|
1383
|
+
: progressStatusGlyph({ ...progress, status, index: flatIndex }, theme, animationFrame),
|
|
1384
|
+
description,
|
|
1385
|
+
modelBadge,
|
|
1386
|
+
tokens: result ? compactResultTokens(result) : progress?.tokens ?? 0,
|
|
1387
|
+
durationMs: liveDurationMs(progress, running, now),
|
|
1388
|
+
terminalStatus: result
|
|
1389
|
+
? compactResultTerminalStatus(result)
|
|
1390
|
+
: compactTerminalStatus(status),
|
|
1391
|
+
});
|
|
1392
|
+
}, frame, running));
|
|
1474
1393
|
}
|
|
1475
1394
|
return c;
|
|
1476
1395
|
}
|
|
@@ -1479,7 +1398,9 @@ function renderMultiCompact(d, theme, frame) {
|
|
|
1479
1398
|
*/
|
|
1480
1399
|
export function renderSubagentResult(result, options, theme, frame) {
|
|
1481
1400
|
const d = result.details;
|
|
1482
|
-
|
|
1401
|
+
const hasWorkflowRows = d?.mode !== "management"
|
|
1402
|
+
&& Boolean(d?.workflowGraph?.nodes.length || d?.progress?.length || d?.chainChildren?.length);
|
|
1403
|
+
if (!d || (!d.results.length && !hasWorkflowRows)) {
|
|
1483
1404
|
const t = result.content[0];
|
|
1484
1405
|
const text = t?.type === "text" ? t.text : "(no output)";
|
|
1485
1406
|
const contextPrefix = d?.context === "fork" ? `${theme.fg("warning", "[fork]")} ` : "";
|
|
@@ -1524,6 +1445,9 @@ export function renderSubagentResult(result, options, theme, frame) {
|
|
|
1524
1445
|
? r.task
|
|
1525
1446
|
: `${r.task.slice(0, taskMaxLen)}...`;
|
|
1526
1447
|
c.addChild(new Text(fit(theme.fg("dim", `Task: ${taskPreview}`)), 0, 0));
|
|
1448
|
+
if (!isRunning && compactResultTerminalStatus(r)) {
|
|
1449
|
+
c.addChild(new Text(fit(theme.fg(r.exitCode !== 0 ? "error" : "warning", resultStatusLine(r, output))), 0, 0));
|
|
1450
|
+
}
|
|
1527
1451
|
c.addChild(new Spacer(1));
|
|
1528
1452
|
if (isRunning && r.progress) {
|
|
1529
1453
|
const progressSnapshotNow = snapshotNowForProgress(r.progress);
|
|
@@ -1596,6 +1520,7 @@ export function renderSubagentResult(result, options, theme, frame) {
|
|
|
1596
1520
|
const hasWorkflowFailure = workflowGraphHasStatus(d, ["failed"]);
|
|
1597
1521
|
const hasWorkflowStop = d.results.some((r) => r.stopped && r.progress?.status !== "running") || workflowGraphHasStatus(d, ["stopped"]);
|
|
1598
1522
|
const hasWorkflowPause = workflowGraphHasStatus(d, ["paused", "detached"]);
|
|
1523
|
+
const hasWorkflowPending = workflowGraphHasStatus(d, ["pending"]);
|
|
1599
1524
|
const icon = hasRunning
|
|
1600
1525
|
? theme.fg("warning", "running")
|
|
1601
1526
|
: hasEmptyWithoutTarget
|
|
@@ -1606,9 +1531,11 @@ export function renderSubagentResult(result, options, theme, frame) {
|
|
|
1606
1531
|
? theme.fg("warning", "stopped")
|
|
1607
1532
|
: hasWorkflowPause
|
|
1608
1533
|
? theme.fg("warning", "paused")
|
|
1609
|
-
:
|
|
1610
|
-
? theme.fg("
|
|
1611
|
-
:
|
|
1534
|
+
: hasWorkflowPending
|
|
1535
|
+
? theme.fg("dim", "pending")
|
|
1536
|
+
: ok === d.results.length
|
|
1537
|
+
? theme.fg("success", "ok")
|
|
1538
|
+
: theme.fg("error", "failed");
|
|
1612
1539
|
const totalSummary = d.progressSummary ||
|
|
1613
1540
|
d.results.reduce((acc, r) => {
|
|
1614
1541
|
const prog = r.progress || r.progressSummary;
|
|
@@ -1670,16 +1597,40 @@ export function renderSubagentResult(result, options, theme, frame) {
|
|
|
1670
1597
|
if (chainVis) {
|
|
1671
1598
|
c.addChild(new Text(fit(` ${chainVis}`), 0, 0));
|
|
1672
1599
|
}
|
|
1673
|
-
const useResultsDirectly = multiLabel.hasParallelInChain || !d.chainAgents?.length;
|
|
1674
|
-
const displayStart = multiLabel.showActiveGroupOnly ? multiLabel.groupStartIndex : 0;
|
|
1675
|
-
const displayEnd = multiLabel.showActiveGroupOnly ? multiLabel.groupEndIndex : (useResultsDirectly ? d.results.length : d.chainAgents.length);
|
|
1676
1600
|
const chainEntries = buildChainRenderEntries(d, multiLabel);
|
|
1677
|
-
const
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1601
|
+
const fallbackEntries = compactForegroundEntries(d)
|
|
1602
|
+
.filter((entry) => !multiLabel.showActiveGroupOnly
|
|
1603
|
+
|| entry.flatIndex === undefined
|
|
1604
|
+
|| (entry.flatIndex >= multiLabel.groupStartIndex && entry.flatIndex < multiLabel.groupEndIndex))
|
|
1605
|
+
.map((entry, rowIndex) => {
|
|
1606
|
+
if (entry.flatIndex === undefined) {
|
|
1607
|
+
return {
|
|
1608
|
+
kind: "placeholder",
|
|
1609
|
+
rowNumber: entry.node?.stepIndex !== undefined ? entry.node.stepIndex + 1 : rowIndex + 1,
|
|
1610
|
+
stepLabel: `Step ${entry.node?.stepIndex !== undefined ? entry.node.stepIndex + 1 : rowIndex + 1}`,
|
|
1611
|
+
agentName: entry.node?.label ?? `step-${rowIndex + 1}`,
|
|
1612
|
+
status: entry.node?.status ?? "pending",
|
|
1613
|
+
error: entry.node?.error,
|
|
1614
|
+
};
|
|
1615
|
+
}
|
|
1616
|
+
const result = resultAtFlatIndex(d, entry.flatIndex);
|
|
1617
|
+
const rowNumber = multiLabel.showActiveGroupOnly
|
|
1618
|
+
? entry.flatIndex - multiLabel.groupStartIndex + 1
|
|
1619
|
+
: entry.flatIndex + 1;
|
|
1620
|
+
return {
|
|
1621
|
+
kind: "result",
|
|
1622
|
+
resultIndex: entry.flatIndex,
|
|
1623
|
+
rowNumber,
|
|
1624
|
+
agentName: result?.agent
|
|
1625
|
+
?? entry.node?.label
|
|
1626
|
+
?? d.chainChildren?.[entry.flatIndex]?.description
|
|
1627
|
+
?? d.chainAgents?.[entry.flatIndex]
|
|
1628
|
+
?? `step-${rowNumber}`,
|
|
1629
|
+
status: entry.node?.status,
|
|
1630
|
+
error: entry.node?.error,
|
|
1631
|
+
};
|
|
1682
1632
|
});
|
|
1633
|
+
const renderEntries = chainEntries ?? fallbackEntries;
|
|
1683
1634
|
c.addChild(new Spacer(1));
|
|
1684
1635
|
for (const entry of renderEntries) {
|
|
1685
1636
|
if (entry.kind === "placeholder") {
|
|
@@ -1692,13 +1643,16 @@ export function renderSubagentResult(result, options, theme, frame) {
|
|
|
1692
1643
|
continue;
|
|
1693
1644
|
}
|
|
1694
1645
|
const i = entry.resultIndex;
|
|
1695
|
-
const r = d
|
|
1646
|
+
const r = resultAtFlatIndex(d, i);
|
|
1696
1647
|
const rowNumber = entry.rowNumber;
|
|
1697
1648
|
const agentName = entry.agentName;
|
|
1698
1649
|
if (!r) {
|
|
1699
|
-
const
|
|
1700
|
-
|
|
1701
|
-
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));
|
|
1702
1656
|
c.addChild(new Spacer(1));
|
|
1703
1657
|
continue;
|
|
1704
1658
|
}
|
|
@@ -1729,6 +1683,9 @@ export function renderSubagentResult(result, options, theme, frame) {
|
|
|
1729
1683
|
? r.task
|
|
1730
1684
|
: `${r.task.slice(0, taskMaxLen)}...`;
|
|
1731
1685
|
c.addChild(new Text(fit(theme.fg("dim", ` task: ${taskPreview}`)), 0, 0));
|
|
1686
|
+
if (!rRunning && compactResultTerminalStatus(r)) {
|
|
1687
|
+
c.addChild(new Text(fit(theme.fg(r.exitCode !== 0 ? "error" : "warning", ` ${resultStatusLine(r, resultOutput)}`)), 0, 0));
|
|
1688
|
+
}
|
|
1732
1689
|
if (r.skills?.length) {
|
|
1733
1690
|
c.addChild(new Text(fit(theme.fg("dim", ` skills: ${r.skills.join(", ")}`)), 0, 0));
|
|
1734
1691
|
}
|