@ai-agent-forge/agent-forge 0.88.4 → 0.88.6
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 +30 -0
- package/bundled-plugins/agent-loop-policy/agent-forge.json +1 -1
- package/bundled-plugins/agent-loop-policy/plugin.json +1 -1
- package/bundled-plugins/alignment/agent-forge.json +19 -0
- package/bundled-plugins/alignment/dist/baseline.d.ts +12 -0
- package/bundled-plugins/alignment/dist/baseline.d.ts.map +1 -0
- package/bundled-plugins/alignment/dist/baseline.js +68 -0
- package/bundled-plugins/alignment/dist/baseline.js.map +1 -0
- package/bundled-plugins/alignment/dist/engine.d.ts +102 -0
- package/bundled-plugins/alignment/dist/engine.d.ts.map +1 -0
- package/bundled-plugins/alignment/dist/engine.js +654 -0
- package/bundled-plugins/alignment/dist/engine.js.map +1 -0
- package/bundled-plugins/alignment/dist/entry.d.ts +14 -0
- package/bundled-plugins/alignment/dist/entry.d.ts.map +1 -0
- package/bundled-plugins/alignment/dist/entry.js +23 -0
- package/bundled-plugins/alignment/dist/entry.js.map +1 -0
- package/bundled-plugins/alignment/dist/export.d.ts +15 -0
- package/bundled-plugins/alignment/dist/export.d.ts.map +1 -0
- package/bundled-plugins/alignment/dist/export.js +122 -0
- package/bundled-plugins/alignment/dist/export.js.map +1 -0
- package/bundled-plugins/alignment/dist/http-server.d.ts +33 -0
- package/bundled-plugins/alignment/dist/http-server.d.ts.map +1 -0
- package/bundled-plugins/alignment/dist/http-server.js +119 -0
- package/bundled-plugins/alignment/dist/http-server.js.map +1 -0
- package/bundled-plugins/alignment/dist/index.d.ts +24 -0
- package/bundled-plugins/alignment/dist/index.d.ts.map +1 -0
- package/bundled-plugins/alignment/dist/index.js +719 -0
- package/bundled-plugins/alignment/dist/index.js.map +1 -0
- package/bundled-plugins/alignment/dist/page.d.ts +15 -0
- package/bundled-plugins/alignment/dist/page.d.ts.map +1 -0
- package/bundled-plugins/alignment/dist/page.js +832 -0
- package/bundled-plugins/alignment/dist/page.js.map +1 -0
- package/bundled-plugins/alignment/dist/render.d.ts +40 -0
- package/bundled-plugins/alignment/dist/render.d.ts.map +1 -0
- package/bundled-plugins/alignment/dist/render.js +194 -0
- package/bundled-plugins/alignment/dist/render.js.map +1 -0
- package/bundled-plugins/alignment/dist/types.d.ts +217 -0
- package/bundled-plugins/alignment/dist/types.d.ts.map +1 -0
- package/bundled-plugins/alignment/dist/types.js +30 -0
- package/bundled-plugins/alignment/dist/types.js.map +1 -0
- package/bundled-plugins/alignment/plugin.json +12 -0
- package/bundled-plugins/browser-playwright/MANUAL.md +60 -0
- package/bundled-plugins/browser-playwright/agent-forge.json +25 -0
- package/bundled-plugins/browser-playwright/dist/capability.d.ts +25 -0
- package/bundled-plugins/browser-playwright/dist/capability.d.ts.map +1 -0
- package/bundled-plugins/browser-playwright/dist/capability.js +612 -0
- package/bundled-plugins/browser-playwright/dist/capability.js.map +1 -0
- package/bundled-plugins/browser-playwright/dist/entry.d.ts +13 -0
- package/bundled-plugins/browser-playwright/dist/entry.d.ts.map +1 -0
- package/bundled-plugins/browser-playwright/dist/entry.js +14 -0
- package/bundled-plugins/browser-playwright/dist/entry.js.map +1 -0
- package/bundled-plugins/browser-playwright/dist/index.d.ts +7 -0
- package/bundled-plugins/browser-playwright/dist/index.d.ts.map +1 -0
- package/bundled-plugins/browser-playwright/dist/index.js +5 -0
- package/bundled-plugins/browser-playwright/dist/index.js.map +1 -0
- package/bundled-plugins/browser-playwright/dist/operations.d.ts +69 -0
- package/bundled-plugins/browser-playwright/dist/operations.d.ts.map +1 -0
- package/bundled-plugins/browser-playwright/dist/operations.js +149 -0
- package/bundled-plugins/browser-playwright/dist/operations.js.map +1 -0
- package/bundled-plugins/browser-playwright/dist/playwright-driver.d.ts +275 -0
- package/bundled-plugins/browser-playwright/dist/playwright-driver.d.ts.map +1 -0
- package/bundled-plugins/browser-playwright/dist/playwright-driver.js +953 -0
- package/bundled-plugins/browser-playwright/dist/playwright-driver.js.map +1 -0
- package/bundled-plugins/browser-playwright/dist/setup.d.ts +88 -0
- package/bundled-plugins/browser-playwright/dist/setup.d.ts.map +1 -0
- package/bundled-plugins/browser-playwright/dist/setup.js +252 -0
- package/bundled-plugins/browser-playwright/dist/setup.js.map +1 -0
- package/bundled-plugins/browser-playwright/dist/types.d.ts +270 -0
- package/bundled-plugins/browser-playwright/dist/types.d.ts.map +1 -0
- package/bundled-plugins/browser-playwright/dist/types.js +2 -0
- package/bundled-plugins/browser-playwright/dist/types.js.map +1 -0
- package/bundled-plugins/browser-playwright/plugin.json +20 -0
- package/bundled-plugins/coding-tools/agent-forge.json +1 -1
- package/bundled-plugins/coding-tools/dist/bash.d.ts +2 -7
- package/bundled-plugins/coding-tools/dist/bash.d.ts.map +1 -1
- package/bundled-plugins/coding-tools/dist/bash.js +2 -34
- package/bundled-plugins/coding-tools/dist/bash.js.map +1 -1
- package/bundled-plugins/coding-tools/plugin.json +1 -1
- package/bundled-plugins/compaction-policy/agent-forge.json +1 -1
- package/bundled-plugins/compaction-policy/plugin.json +1 -1
- package/bundled-plugins/mcp-http/dist/mcp-http.d.ts.map +1 -1
- package/bundled-plugins/mcp-http/dist/mcp-http.js +84 -31
- package/bundled-plugins/mcp-http/dist/mcp-http.js.map +1 -1
- package/bundled-plugins/overflow-policy/agent-forge.json +1 -1
- package/bundled-plugins/overflow-policy/plugin.json +1 -1
- package/bundled-plugins/provider-failover/agent-forge.json +1 -1
- package/bundled-plugins/provider-failover/plugin.json +1 -1
- package/bundled-plugins/retry-policy/agent-forge.json +1 -1
- package/bundled-plugins/retry-policy/plugin.json +1 -1
- package/dist/bundle/.build-manifest.json +60 -58
- package/dist/bundle/chunks/{anthropic-messages-3FJHRAJL.js → anthropic-messages-NL4Y6WPB.js} +1 -1
- package/dist/bundle/chunks/{azure-openai-responses-GCL47IDS.js → azure-openai-responses-CPXC42HO.js} +1 -1
- package/dist/bundle/chunks/bedrock-converse-stream.js +1 -1
- package/dist/bundle/chunks/chunk-5LRQFZFE.js +2 -0
- package/dist/bundle/chunks/{chunk-HTEVUY7F.js → chunk-7HSJPQKN.js} +1 -1
- package/dist/bundle/chunks/{chunk-AC2FIS4G.js → chunk-EDO7Q6XR.js} +1 -1
- package/dist/bundle/chunks/{chunk-755VNWIF.js → chunk-ISLHFRER.js} +6 -6
- package/dist/bundle/chunks/{chunk-HV64ASMT.js → chunk-K3S6GTL7.js} +1 -1
- package/dist/bundle/chunks/{chunk-HEL6TAWE.js → chunk-POLDAUYA.js} +37 -36
- package/dist/bundle/chunks/{chunk-V3ACW7VD.js → chunk-WJSKB3FC.js} +1 -1
- package/dist/bundle/chunks/{chunk-32YDZI4J.js → chunk-ZS5JEI76.js} +1 -1
- package/dist/bundle/chunks/{google-generative-ai-6BMXWA44.js → google-generative-ai-UMZ53EFA.js} +1 -1
- package/dist/bundle/chunks/{google-vertex-6H7NLRTK.js → google-vertex-ZNR5NS6H.js} +1 -1
- package/dist/bundle/chunks/image-resize-worker.js +1 -1
- package/dist/bundle/chunks/{mistral-conversations-IXUHSFSJ.js → mistral-conversations-IT66WUNN.js} +1 -1
- package/dist/bundle/chunks/{openai-codex-responses-YHUAEVCM.js → openai-codex-responses-FOVCVG6I.js} +1 -1
- package/dist/bundle/chunks/{openai-completions-ULQCFC72.js → openai-completions-FLQ7CBOL.js} +1 -1
- package/dist/bundle/chunks/{openai-responses-NLLAJDPS.js → openai-responses-ABGYHS2T.js} +1 -1
- package/dist/bundle/chunks/{pi-messages-EJTI2EJ3.js → pi-messages-6K5W6LUN.js} +1 -1
- package/dist/bundle/chunks/{virtual-modules-TQWEGNNZ.js → virtual-modules-2QGILFV7.js} +1 -1
- package/dist/bundle/cli.js +1 -1
- package/dist/bundle/client.js +1 -1
- package/dist/bundle/index.js +1 -1
- package/dist/bundle/rpc-entry.js +1 -1
- package/dist/client/remote-session.d.ts.map +1 -1
- package/dist/client/remote-session.js +65 -6
- package/dist/client/remote-session.js.map +1 -1
- package/dist/core/agent-session-store.d.ts.map +1 -1
- package/dist/core/agent-session-store.js +20 -3
- package/dist/core/agent-session-store.js.map +1 -1
- package/dist/core/extensions/agent-composition.d.ts.map +1 -1
- package/dist/core/extensions/agent-composition.js +20 -1
- package/dist/core/extensions/agent-composition.js.map +1 -1
- package/dist/core/i18n/locales/zh-cn/core-errors.d.ts.map +1 -1
- package/dist/core/i18n/locales/zh-cn/core-errors.js +1 -0
- package/dist/core/i18n/locales/zh-cn/core-errors.js.map +1 -1
- package/dist/core/i18n/locales/zh-cn/interactive-mode.d.ts.map +1 -1
- package/dist/core/i18n/locales/zh-cn/interactive-mode.js +10 -3
- package/dist/core/i18n/locales/zh-cn/interactive-mode.js.map +1 -1
- package/dist/core/keybindings.d.ts +35 -0
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +34 -0
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +62 -15
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +11 -3
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +2 -2
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/tools/capability-mount.d.ts.map +1 -1
- package/dist/core/tools/capability-mount.js +4 -21
- package/dist/core/tools/capability-mount.js.map +1 -1
- package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/assistant-message.js +2 -2
- package/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/dist/modes/interactive/components/bash-execution.d.ts +2 -0
- package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/bash-execution.js +25 -0
- package/dist/modes/interactive/components/bash-execution.js.map +1 -1
- package/dist/modes/interactive/components/changelog-pager.d.ts +53 -0
- package/dist/modes/interactive/components/changelog-pager.d.ts.map +1 -0
- package/dist/modes/interactive/components/changelog-pager.js +239 -0
- package/dist/modes/interactive/components/changelog-pager.js.map +1 -0
- package/dist/modes/interactive/components/tool-execution.d.ts +6 -0
- 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/components/tool-run-group.d.ts +41 -11
- package/dist/modes/interactive/components/tool-run-group.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-run-group.js +126 -14
- package/dist/modes/interactive/components/tool-run-group.js.map +1 -1
- package/dist/modes/interactive/interactive-commands.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-commands.js +23 -13
- package/dist/modes/interactive/interactive-commands.js.map +1 -1
- package/dist/modes/interactive/interactive-events.d.ts +14 -4
- package/dist/modes/interactive/interactive-events.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-events.js +94 -12
- package/dist/modes/interactive/interactive-events.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +6 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +21 -5
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/plugins/ecosystem/node-local-package-source.d.ts +2 -1
- package/dist/plugins/ecosystem/node-local-package-source.d.ts.map +1 -1
- package/dist/plugins/ecosystem/node-local-package-source.js +110 -4
- package/dist/plugins/ecosystem/node-local-package-source.js.map +1 -1
- package/dist/plugins/ecosystem/node-package-install-host.d.ts.map +1 -1
- package/dist/plugins/ecosystem/node-package-install-host.js +106 -39
- package/dist/plugins/ecosystem/node-package-install-host.js.map +1 -1
- package/dist/plugins/ecosystem/node-plugin-bootstrap.d.ts.map +1 -1
- package/dist/plugins/ecosystem/node-plugin-bootstrap.js +59 -2
- package/dist/plugins/ecosystem/node-plugin-bootstrap.js.map +1 -1
- package/dist/suites/builtin-suites.d.ts.map +1 -1
- package/dist/suites/builtin-suites.js +2 -2
- package/dist/suites/builtin-suites.js.map +1 -1
- package/dist/utils/changelog.d.ts +27 -0
- package/dist/utils/changelog.d.ts.map +1 -1
- package/dist/utils/changelog.js +110 -0
- package/dist/utils/changelog.js.map +1 -1
- package/docs/keybindings.md +14 -0
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/examples/extensions/with-deps/plugin.json +1 -1
- package/package.json +1 -1
- package/dist/bundle/chunks/chunk-A3JYRWB6.js +0 -2
|
@@ -306,6 +306,18 @@ export class ToolExecutionComponent extends Container {
|
|
|
306
306
|
}
|
|
307
307
|
return lines;
|
|
308
308
|
}
|
|
309
|
+
/**
|
|
310
|
+
* Quiet-transcript live tail (collapsed running group, D-083 运行态): the
|
|
311
|
+
* component's own render (pending background included) cut to the last
|
|
312
|
+
* `maxLines` visual lines. Hidden components render to [] and stay hidden.
|
|
313
|
+
*/
|
|
314
|
+
renderQuietLiveOutput(width, maxLines) {
|
|
315
|
+
const lines = this.render(width);
|
|
316
|
+
if (lines.length <= maxLines) {
|
|
317
|
+
return lines;
|
|
318
|
+
}
|
|
319
|
+
return lines.slice(lines.length - maxLines);
|
|
320
|
+
}
|
|
309
321
|
updateArgs(args) {
|
|
310
322
|
this.args = args;
|
|
311
323
|
this.updateDisplay();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool-execution.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/tool-execution.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ImageContent, TextContent } from \"@agent-forge/ai\";\nimport {\n\tBox,\n\ttype Component,\n\tContainer,\n\tgetCapabilities,\n\tImage,\n\tSpacer,\n\tText,\n\ttype TUI,\n\ttruncateToWidth,\n} from \"@agent-forge/tui\";\nimport { t } from \"../../../core/i18n/index.ts\";\nimport { formatToolCallWithArgs, getTextOutput as getRenderedTextOutput } from \"../../../core/tools/render-utils.ts\";\nimport type { ToolDefinition, ToolRenderContext } from \"../../../core/tools/tool-definition.ts\";\nimport { theme } from \"../../../theme/theme.ts\";\nimport { convertToPng } from \"../../../utils/image-convert.ts\";\nimport { keyText } from \"./keybinding-hints.ts\";\n\n/** Visual (wrapped) result lines shown before fallback output is expanded. */\nconst FALLBACK_PREVIEW_LINES = 10;\n\n/**\n * 单条工具结果展示预算 (M2, 终端输出模式设计 §3.2「展开仍复用统一的输出截断」):\n * 任何渲染器 (含第三方插件) 的结果输出在视觉行上超过预算时, 保留 head+tail、\n * 中间以一行截断说明替代 (截断原因 + 总量 + 完整输出引用, 引用存在时)。这是\n * compact 预览之上的兜底——折叠态有自己的小预览, detail 态 (ctrl+o) 的全文\n * 渲染由此封顶。错误结果豁免 (错误可见性优先, 与 collapsedPreviewText 同惯例)。\n */\nconst TOOL_OUTPUT_MAX_LINES = 400;\n\n/** 预算超出时保留完整输出的末尾视觉行数 (错误摘要与结论常聚在输出末尾)。 */\nconst TOOL_OUTPUT_TAIL_LINES = 100;\n\n/**\n * Pretty-printed JSON up to this length is collapsed to its compact single-line\n * form; longer compact forms are cut here so a short tool-result ticket shows\n * as one preview line instead of sprawling across the chat. Expansion always\n * shows the original text.\n */\nconst COLLAPSED_JSON_PREVIEW_CHARS = 220;\n\n/**\n * Collapsed preview text for fallback results: pretty-printed JSON (the default\n * serialization for capability-tool results) becomes one compact line, and any\n * other text previews verbatim. Unparseable JSON-like text stays verbatim too.\n * Error results never compact — error visibility beats compactness, so they\n * keep the (threshold-limited) full form with the error background.\n */\nfunction collapsedPreviewText(output: string, isError: boolean): string {\n\tif (isError) {\n\t\treturn output;\n\t}\n\tconst trimmed = output.trimStart();\n\tif (!trimmed.startsWith(\"{\") && !trimmed.startsWith(\"[\")) {\n\t\treturn output;\n\t}\n\ttry {\n\t\tconst compact = JSON.stringify(JSON.parse(output));\n\t\treturn compact.length > COLLAPSED_JSON_PREVIEW_CHARS\n\t\t\t? `${compact.slice(0, COLLAPSED_JSON_PREVIEW_CHARS - 1)}…`\n\t\t\t: compact;\n\t} catch {\n\t\treturn output;\n\t}\n}\n\n/**\n * Collapsed fallback output limited to a number of visual (wrapped) lines. Limiting logical\n * lines instead lets a single long line (such as minified JSON) wrap across the whole screen.\n * Caches its lines per width, since it renders on every frame for every result in the transcript.\n */\nclass VisualLinePreview implements Component {\n\tprivate text: string;\n\tprivate maxVisualLines: number;\n\tprivate formatHint: (hidden: number) => string;\n\tprivate cachedWidth: number | undefined;\n\tprivate cachedLines: string[] | undefined;\n\n\tconstructor(text: string, maxVisualLines: number, formatHint: (hidden: number) => string) {\n\t\tthis.text = text;\n\t\tthis.maxVisualLines = maxVisualLines;\n\t\tthis.formatHint = formatHint;\n\t}\n\n\trender(width: number): string[] {\n\t\tif (this.cachedLines === undefined || this.cachedWidth !== width) {\n\t\t\tconst allVisualLines = new Text(this.text, 0, 0).render(width);\n\t\t\tconst lines =\n\t\t\t\tallVisualLines.length > this.maxVisualLines\n\t\t\t\t\t? [\n\t\t\t\t\t\t\t...allVisualLines.slice(0, this.maxVisualLines),\n\t\t\t\t\t\t\ttruncateToWidth(this.formatHint(allVisualLines.length - this.maxVisualLines), width, \"...\"),\n\t\t\t\t\t\t]\n\t\t\t\t\t: allVisualLines;\n\t\t\tthis.cachedLines = lines;\n\t\t\tthis.cachedWidth = width;\n\t\t\treturn lines;\n\t\t}\n\t\treturn this.cachedLines;\n\t}\n\n\tinvalidate(): void {\n\t\tthis.cachedWidth = undefined;\n\t\tthis.cachedLines = undefined;\n\t}\n}\n\n/**\n * bash 系工具在 details 携带的全量输出文件引用 (截断说明行的\"完整输出\"引用;\n * 终端输出模式设计 §3.2 的引用要求在通用层的最大努力形态)。\n */\nfunction resultFullOutputRef(details: unknown): string | undefined {\n\tif (details === null || typeof details !== \"object\" || Array.isArray(details)) return undefined;\n\tconst ref = (details as { fullOutputPath?: unknown }).fullOutputPath;\n\treturn typeof ref === \"string\" && ref.trim() !== \"\" ? ref : undefined;\n}\n\n/**\n * 结果渲染器输出的展示预算兜底 (M2): 包装 renderResult/fallback 产出的子组件,\n * render(width) 时对视觉行超预算的输出做 head+截断说明+tail。渲染器契约不变\n * (renderResult 仍收 expanded 原值, lastComponent 仍传裸子组件); 缓存按宽度,\n * invalidate 透传子组件 (流式增量渲染依赖它)。\n */\nclass BoundedResultView implements Component {\n\tprivate child: Component;\n\tprivate maxLines: number;\n\tprivate tailLines: number;\n\tprivate isError: boolean;\n\tprivate fullOutputRef: string | undefined;\n\tprivate cachedWidth: number | undefined;\n\tprivate cachedLines: string[] | undefined;\n\n\tconstructor(\n\t\tchild: Component,\n\t\tmaxLines: number,\n\t\ttailLines: number,\n\t\tisError: boolean,\n\t\tfullOutputRef: string | undefined,\n\t) {\n\t\tthis.child = child;\n\t\tthis.maxLines = maxLines;\n\t\tthis.tailLines = tailLines;\n\t\tthis.isError = isError;\n\t\tthis.fullOutputRef = fullOutputRef;\n\t}\n\n\trender(width: number): string[] {\n\t\tif (this.cachedLines === undefined || this.cachedWidth !== width) {\n\t\t\tconst lines = this.child.render(width);\n\t\t\tif (this.isError || lines.length <= this.maxLines) {\n\t\t\t\tthis.cachedLines = lines;\n\t\t\t} else {\n\t\t\t\tconst headLines = this.maxLines - this.tailLines - 1;\n\t\t\t\tconst hidden = lines.length - headLines - this.tailLines;\n\t\t\t\tconst hint =\n\t\t\t\t\tthis.fullOutputRef === undefined\n\t\t\t\t\t\t? t(\"... ({count} lines truncated)\", { count: hidden })\n\t\t\t\t\t\t: t(\"... ({count} lines truncated; full output: {path})\", {\n\t\t\t\t\t\t\t\tcount: hidden,\n\t\t\t\t\t\t\t\tpath: this.fullOutputRef,\n\t\t\t\t\t\t\t});\n\t\t\t\tthis.cachedLines = [\n\t\t\t\t\t...lines.slice(0, headLines),\n\t\t\t\t\ttruncateToWidth(theme.fg(\"muted\", hint), width, \"...\"),\n\t\t\t\t\t...lines.slice(lines.length - this.tailLines),\n\t\t\t\t];\n\t\t\t}\n\t\t\tthis.cachedWidth = width;\n\t\t\treturn this.cachedLines;\n\t\t}\n\t\treturn this.cachedLines;\n\t}\n\n\tinvalidate(): void {\n\t\tthis.child.invalidate();\n\t\tthis.cachedWidth = undefined;\n\t\tthis.cachedLines = undefined;\n\t}\n}\n\nexport interface ToolExecutionOptions {\n\tshowImages?: boolean;\n\timageWidthCells?: number;\n}\n\nexport class ToolExecutionComponent extends Container {\n\tprivate contentBox: Box;\n\tprivate contentText: Text;\n\tprivate selfRenderContainer: Container;\n\tprivate callRendererComponent?: Component;\n\tprivate resultRendererComponent?: Component;\n\tprivate rendererState: Record<string, unknown> = {};\n\tprivate imageComponents: Image[] = [];\n\tprivate imageSpacers: Spacer[] = [];\n\tprivate toolName: string;\n\tprivate toolCallId: string;\n\tprivate args: unknown;\n\tprivate expanded = false;\n\tprivate showImages: boolean;\n\tprivate imageWidthCells: number;\n\tprivate isPartial = true;\n\tprivate toolDefinition?: ToolDefinition;\n\tprivate ui: TUI;\n\tprivate cwd: string;\n\tprivate executionStarted = false;\n\tprivate argsComplete = false;\n\tprivate result?: {\n\t\tcontent: (TextContent | ImageContent)[];\n\t\tisError: boolean;\n\t\tdetails?: unknown;\n\t};\n\tprivate convertedImages: Map<\n\t\tnumber,\n\t\t{ sourceData: string; sourceMimeType: string; data: string; mimeType: string }\n\t> = new Map();\n\tprivate hideComponent = false;\n\n\tconstructor(\n\t\ttoolName: string,\n\t\ttoolCallId: string,\n\t\targs: unknown,\n\t\toptions: ToolExecutionOptions = {},\n\t\ttoolDefinition: ToolDefinition | undefined,\n\t\tui: TUI,\n\t\tcwd: string,\n\t) {\n\t\tsuper();\n\t\tthis.toolName = toolName;\n\t\tthis.toolCallId = toolCallId;\n\t\tthis.args = args;\n\t\t// The caller passes the session registry's definition\n\t\t// (interactive-mode getRegisteredToolDefinition → facade.getToolDefinition).\n\t\t// Since D-082 批 1 the default coding tool definitions live in the\n\t\t// coding-tools plugin, so the registry is the only definition source;\n\t\t// names missing from the registry render through the generic fallback.\n\t\tthis.toolDefinition = toolDefinition;\n\t\tthis.showImages = options.showImages ?? true;\n\t\tthis.imageWidthCells = options.imageWidthCells ?? 60;\n\t\tthis.ui = ui;\n\t\tthis.cwd = cwd;\n\n\t\tthis.addChild(new Spacer(1));\n\n\t\t// Always create all shell variants. contentBox is used for default renderer-based composition.\n\t\t// selfRenderContainer is used when the tool renders its own framing.\n\t\t// contentText is reserved for generic fallback rendering when no tool definition exists.\n\t\tthis.contentBox = new Box(1, 1, (text: string) => theme.bg(\"toolPendingBg\", text));\n\t\tthis.contentText = new Text(\"\", 1, 1, (text: string) => theme.bg(\"toolPendingBg\", text));\n\t\tthis.selfRenderContainer = new Container();\n\n\t\tif (this.hasRendererDefinition()) {\n\t\t\tthis.addChild(this.getRenderShell() === \"self\" ? this.selfRenderContainer : this.contentBox);\n\t\t} else {\n\t\t\tthis.addChild(this.contentText);\n\t\t}\n\n\t\tthis.updateDisplay();\n\t}\n\n\tprivate getCallRenderer(): ToolDefinition[\"renderCall\"] | undefined {\n\t\treturn this.toolDefinition?.renderCall;\n\t}\n\n\tprivate getResultRenderer(): ToolDefinition[\"renderResult\"] | undefined {\n\t\treturn this.toolDefinition?.renderResult;\n\t}\n\n\tprivate hasRendererDefinition(): boolean {\n\t\treturn this.toolDefinition !== undefined;\n\t}\n\n\tprivate getRenderShell(): \"default\" | \"self\" {\n\t\treturn this.toolDefinition?.renderShell ?? \"default\";\n\t}\n\n\tprivate getRenderContext(lastComponent: Component | undefined): ToolRenderContext {\n\t\treturn {\n\t\t\targs: this.args,\n\t\t\ttoolCallId: this.toolCallId,\n\t\t\tinvalidate: () => {\n\t\t\t\tthis.invalidate();\n\t\t\t\tthis.ui.requestRender();\n\t\t\t},\n\t\t\tlastComponent,\n\t\t\tstate: this.rendererState,\n\t\t\tcwd: this.cwd,\n\t\t\texecutionStarted: this.executionStarted,\n\t\t\targsComplete: this.argsComplete,\n\t\t\tisPartial: this.isPartial,\n\t\t\texpanded: this.expanded,\n\t\t\tshowImages: this.showImages,\n\t\t\tisError: this.result?.isError ?? false,\n\t\t};\n\t}\n\n\tprivate createCallFallback(): Component {\n\t\treturn new Text(formatToolCallWithArgs(this.toolName, this.args, theme, this.expanded), 0, 0);\n\t}\n\n\tprivate createResultFallback(): Component | undefined {\n\t\tconst output = this.getTextOutput();\n\t\tif (!output) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tif (this.expanded) {\n\t\t\treturn new Text(\n\t\t\t\toutput\n\t\t\t\t\t.split(\"\\n\")\n\t\t\t\t\t.map((line) => theme.fg(\"toolOutput\", line))\n\t\t\t\t\t.join(\"\\n\"),\n\t\t\t\t0,\n\t\t\t\t0,\n\t\t\t);\n\t\t}\n\t\tconst previewText = collapsedPreviewText(output, this.result?.isError ?? false);\n\t\t// A compacted JSON preview is one line by construction, so it never\n\t\t// reaches the preview-line threshold — append the expand hint directly.\n\t\tif (previewText !== output) {\n\t\t\t// i18n: 原三段样式拼接合并为整句单 key,键位片段的 dim 样式损失按批次④特殊裁决 1 接受\n\t\t\tconst hint = theme.fg(\"muted\", t(\"({key} to expand)\", { key: keyText(\"app.tools.expand\") }));\n\t\t\treturn new Text(`${theme.fg(\"toolOutput\", previewText)} ${hint}`, 0, 0);\n\t\t}\n\t\tconst styled = previewText\n\t\t\t.split(\"\\n\")\n\t\t\t.map((line) => theme.fg(\"toolOutput\", line))\n\t\t\t.join(\"\\n\");\n\t\treturn new VisualLinePreview(styled, FALLBACK_PREVIEW_LINES, (hidden) =>\n\t\t\ttheme.fg(\n\t\t\t\t\"muted\",\n\t\t\t\tt(\"... ({count} more lines, {key} to expand)\", {\n\t\t\t\t\tcount: hidden,\n\t\t\t\t\tkey: keyText(\"app.tools.expand\"),\n\t\t\t\t}),\n\t\t\t),\n\t\t);\n\t}\n\n\t/** Failure fact for the enclosing ToolRunGroupComponent (D-083 quiet marker). */\n\tget isError(): boolean {\n\t\treturn this.result?.isError ?? false;\n\t}\n\n\t/** Tool name for the group marker's sole-tool form (restore path has no setActiveTool). */\n\tget name(): string {\n\t\treturn this.toolName;\n\t}\n\n\t/**\n\t * First non-empty line of a failed result's text output — the quiet group\n\t * marker's failure summary (D-083 增补:失败首行摘要). Successes and\n\t * result-less calls return undefined.\n\t */\n\tget errorSummary(): string | undefined {\n\t\tif (!this.result?.isError) return undefined;\n\t\treturn this.getTextOutput()\n\t\t\t.split(\"\\n\")\n\t\t\t.map((line) => line.trim())\n\t\t\t.find((line) => line !== \"\");\n\t}\n\n\t/**\n\t * Quiet-transcript image lines (D-083 增补:图片是用户可见的结论): the\n\t * collapsed group marker hides the text card but still renders result\n\t * images (desktop/browser screenshots). Empty when the result has no\n\t * renderable images.\n\t */\n\trenderQuietImages(width: number): string[] {\n\t\tconst lines: string[] = [];\n\t\tfor (let i = 0; i < this.imageComponents.length; i++) {\n\t\t\tconst spacer = this.imageSpacers[i];\n\t\t\t// v8 ignore next -- spacers and image components are always pushed in pairs\n\t\t\tif (spacer) {\n\t\t\t\tlines.push(...spacer.render(width));\n\t\t\t}\n\t\t\tconst imageComponent = this.imageComponents[i];\n\t\t\t// v8 ignore next -- spacers and image components are always pushed in pairs\n\t\t\tif (imageComponent) {\n\t\t\t\tlines.push(...imageComponent.render(width));\n\t\t\t}\n\t\t}\n\t\treturn lines;\n\t}\n\n\tupdateArgs(args: unknown): void {\n\t\tthis.args = args;\n\t\tthis.updateDisplay();\n\t}\n\n\tmarkExecutionStarted(): void {\n\t\tthis.executionStarted = true;\n\t\tthis.updateDisplay();\n\t\tthis.ui.requestRender();\n\t}\n\n\tsetArgsComplete(): void {\n\t\tthis.argsComplete = true;\n\t\tthis.updateDisplay();\n\t\tthis.ui.requestRender();\n\t}\n\n\tupdateResult(\n\t\tresult: {\n\t\t\tcontent: (TextContent | ImageContent)[];\n\t\t\tdetails?: unknown;\n\t\t\tisError: boolean;\n\t\t},\n\t\tisPartial = false,\n\t): void {\n\t\tthis.result = result;\n\t\tthis.isPartial = isPartial;\n\t\tthis.updateDisplay();\n\t\tthis.maybeConvertImagesForKitty();\n\t}\n\n\tprivate maybeConvertImagesForKitty(): void {\n\t\tconst caps = getCapabilities();\n\t\tif (caps.images !== \"kitty\") return;\n\t\t// v8 ignore next -- sole caller updateResult always assigns this.result first\n\t\tif (!this.result) return;\n\n\t\tconst imageBlocks = this.result.content.filter((c) => c.type === \"image\");\n\t\tfor (let i = 0; i < imageBlocks.length; i++) {\n\t\t\tconst img = imageBlocks[i];\n\t\t\tif (!img.data || !img.mimeType) continue;\n\t\t\tconst sourceData = img.data;\n\t\t\tconst sourceMimeType = img.mimeType;\n\t\t\tif (sourceMimeType === \"image/png\") continue;\n\t\t\tconst cached = this.convertedImages.get(i);\n\t\t\tif (cached?.sourceData === sourceData && cached.sourceMimeType === sourceMimeType) continue;\n\n\t\t\tconst index = i;\n\t\t\tconvertToPng(sourceData, sourceMimeType).then((converted) => {\n\t\t\t\tconst currentImage = this.result?.content.filter((content) => content.type === \"image\")[index];\n\t\t\t\tif (!converted || currentImage?.data !== sourceData || currentImage.mimeType !== sourceMimeType) return;\n\t\t\t\tthis.convertedImages.set(index, {\n\t\t\t\t\tsourceData,\n\t\t\t\t\tsourceMimeType,\n\t\t\t\t\t...converted,\n\t\t\t\t});\n\t\t\t\tthis.updateDisplay();\n\t\t\t\tthis.ui.requestRender();\n\t\t\t});\n\t\t}\n\t}\n\n\tsetExpanded(expanded: boolean): void {\n\t\tthis.expanded = expanded;\n\t\tthis.updateDisplay();\n\t}\n\n\tsetShowImages(show: boolean): void {\n\t\tthis.showImages = show;\n\t\tthis.updateDisplay();\n\t}\n\n\tsetImageWidthCells(width: number): void {\n\t\tthis.imageWidthCells = Math.max(1, Math.floor(width));\n\t\tthis.updateDisplay();\n\t}\n\n\toverride invalidate(): void {\n\t\tsuper.invalidate();\n\t\tthis.updateDisplay();\n\t}\n\n\toverride render(width: number): string[] {\n\t\tif (this.hideComponent) {\n\t\t\treturn [];\n\t\t}\n\n\t\tif (this.hasRendererDefinition() && this.getRenderShell() === \"self\") {\n\t\t\tconst contentLines = this.selfRenderContainer.render(width);\n\t\t\tif (contentLines.length === 0 && this.imageComponents.length === 0) {\n\t\t\t\treturn [];\n\t\t\t}\n\n\t\t\tconst lines: string[] = [];\n\t\t\tif (contentLines.length > 0) {\n\t\t\t\tlines.push(\"\");\n\t\t\t\tlines.push(...contentLines);\n\t\t\t}\n\t\t\tfor (let i = 0; i < this.imageComponents.length; i++) {\n\t\t\t\tconst spacer = this.imageSpacers[i];\n\t\t\t\t// v8 ignore next -- spacers and image components are always pushed in pairs\n\t\t\t\tif (spacer) {\n\t\t\t\t\tlines.push(...spacer.render(width));\n\t\t\t\t}\n\t\t\t\tconst imageComponent = this.imageComponents[i];\n\t\t\t\t// v8 ignore next -- spacers and image components are always pushed in pairs\n\t\t\t\tif (imageComponent) {\n\t\t\t\t\tlines.push(...imageComponent.render(width));\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn lines;\n\t\t}\n\n\t\treturn super.render(width);\n\t}\n\n\t/** M2 展示预算: 结果子组件统一过有界视图 (错误豁免), 见 BoundedResultView。 */\n\tprivate boundedResult(component: Component): Component {\n\t\treturn new BoundedResultView(\n\t\t\tcomponent,\n\t\t\tTOOL_OUTPUT_MAX_LINES,\n\t\t\tTOOL_OUTPUT_TAIL_LINES,\n\t\t\tthis.result?.isError ?? false,\n\t\t\tresultFullOutputRef(this.result?.details),\n\t\t);\n\t}\n\n\tprivate updateDisplay(): void {\n\t\tconst bgFn = this.isPartial\n\t\t\t? (text: string) => theme.bg(\"toolPendingBg\", text)\n\t\t\t: this.result?.isError\n\t\t\t\t? (text: string) => theme.bg(\"toolErrorBg\", text)\n\t\t\t\t: (text: string) => theme.bg(\"toolSuccessBg\", text);\n\n\t\tlet hasContent = false;\n\t\tthis.hideComponent = false;\n\t\tif (this.hasRendererDefinition()) {\n\t\t\tconst renderContainer = this.getRenderShell() === \"self\" ? this.selfRenderContainer : this.contentBox;\n\t\t\tif (renderContainer instanceof Box) {\n\t\t\t\trenderContainer.setBgFn(bgFn);\n\t\t\t}\n\t\t\trenderContainer.clear();\n\n\t\t\tconst callRenderer = this.getCallRenderer();\n\t\t\tif (!callRenderer) {\n\t\t\t\trenderContainer.addChild(this.createCallFallback());\n\t\t\t\thasContent = true;\n\t\t\t} else {\n\t\t\t\ttry {\n\t\t\t\t\tconst component = callRenderer(this.args, theme, this.getRenderContext(this.callRendererComponent));\n\t\t\t\t\t// 渲染器可能返回 undefined(选择不渲染);此时交给无内容隐藏\n\t\t\t\t\t// 逻辑,不能把 undefined 塞进 Box.children(invalidate 会崩溃)。\n\t\t\t\t\tif (component) {\n\t\t\t\t\t\tthis.callRendererComponent = component;\n\t\t\t\t\t\trenderContainer.addChild(component);\n\t\t\t\t\t\thasContent = true;\n\t\t\t\t\t}\n\t\t\t\t} catch {\n\t\t\t\t\tthis.callRendererComponent = undefined;\n\t\t\t\t\trenderContainer.addChild(this.createCallFallback());\n\t\t\t\t\thasContent = true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (this.result) {\n\t\t\t\tconst resultRenderer = this.getResultRenderer();\n\t\t\t\tif (!resultRenderer) {\n\t\t\t\t\tconst component = this.createResultFallback();\n\t\t\t\t\tif (component) {\n\t\t\t\t\t\trenderContainer.addChild(this.boundedResult(component));\n\t\t\t\t\t\thasContent = true;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst component = resultRenderer(\n\t\t\t\t\t\t\t{ content: this.result.content, details: this.result.details },\n\t\t\t\t\t\t\t{ expanded: this.expanded, isPartial: this.isPartial },\n\t\t\t\t\t\t\ttheme,\n\t\t\t\t\t\t\tthis.getRenderContext(this.resultRendererComponent),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tif (component) {\n\t\t\t\t\t\t\tthis.resultRendererComponent = component;\n\t\t\t\t\t\t\trenderContainer.addChild(this.boundedResult(component));\n\t\t\t\t\t\t\thasContent = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t} catch {\n\t\t\t\t\t\tthis.resultRendererComponent = undefined;\n\t\t\t\t\t\tconst component = this.createResultFallback();\n\t\t\t\t\t\tif (component) {\n\t\t\t\t\t\t\trenderContainer.addChild(component);\n\t\t\t\t\t\t\thasContent = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tthis.contentText.setCustomBgFn(bgFn);\n\t\t\tthis.contentText.setText(this.formatToolExecution());\n\t\t\thasContent = true;\n\t\t}\n\n\t\tfor (const img of this.imageComponents) {\n\t\t\tthis.removeChild(img);\n\t\t}\n\t\tthis.imageComponents = [];\n\t\tfor (const spacer of this.imageSpacers) {\n\t\t\tthis.removeChild(spacer);\n\t\t}\n\t\tthis.imageSpacers = [];\n\n\t\tif (this.result) {\n\t\t\tconst imageBlocks = this.result.content.filter((c) => c.type === \"image\");\n\t\t\tconst caps = getCapabilities();\n\t\t\tfor (let i = 0; i < imageBlocks.length; i++) {\n\t\t\t\tconst img = imageBlocks[i];\n\t\t\t\tif (caps.images && this.showImages && img.data && img.mimeType) {\n\t\t\t\t\tconst cached = this.convertedImages.get(i);\n\t\t\t\t\tconst converted =\n\t\t\t\t\t\tcached?.sourceData === img.data && cached.sourceMimeType === img.mimeType ? cached : undefined;\n\t\t\t\t\tconst imageData = converted?.data ?? img.data;\n\t\t\t\t\tconst imageMimeType = converted?.mimeType ?? img.mimeType;\n\t\t\t\t\tif (caps.images === \"kitty\" && imageMimeType !== \"image/png\") continue;\n\n\t\t\t\t\tconst spacer = new Spacer(1);\n\t\t\t\t\tthis.addChild(spacer);\n\t\t\t\t\tthis.imageSpacers.push(spacer);\n\t\t\t\t\tconst imageComponent = new Image(\n\t\t\t\t\t\timageData,\n\t\t\t\t\t\timageMimeType,\n\t\t\t\t\t\t{ fallbackColor: (s: string) => theme.fg(\"toolOutput\", s) },\n\t\t\t\t\t\t{ maxWidthCells: this.imageWidthCells },\n\t\t\t\t\t);\n\t\t\t\t\tthis.imageComponents.push(imageComponent);\n\t\t\t\t\tthis.addChild(imageComponent);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (this.hasRendererDefinition() && !hasContent && this.imageComponents.length === 0) {\n\t\t\tthis.hideComponent = true;\n\t\t}\n\t}\n\n\tprivate getTextOutput(): string {\n\t\treturn getRenderedTextOutput(this.result, this.showImages);\n\t}\n\n\tprivate formatToolExecution(): string {\n\t\tlet text = theme.fg(\"toolTitle\", theme.bold(this.toolName));\n\t\tconst content = JSON.stringify(this.args, null, 2);\n\t\tif (content) {\n\t\t\ttext += `\\n\\n${content}`;\n\t\t}\n\t\tconst output = this.getTextOutput();\n\t\tif (output) {\n\t\t\t// 无定义工具的通用回退同样封顶 (M2, 逻辑行粒度): 超预算 head+说明+tail。\n\t\t\tconst lines = output.split(\"\\n\");\n\t\t\tif (lines.length <= TOOL_OUTPUT_MAX_LINES) {\n\t\t\t\ttext += `\\n${output}`;\n\t\t\t} else {\n\t\t\t\tconst headLines = TOOL_OUTPUT_MAX_LINES - TOOL_OUTPUT_TAIL_LINES - 1;\n\t\t\t\tconst hint = t(\"... ({count} lines truncated)\", {\n\t\t\t\t\tcount: lines.length - headLines - TOOL_OUTPUT_TAIL_LINES,\n\t\t\t\t});\n\t\t\t\ttext += `\\n${[\n\t\t\t\t\t...lines.slice(0, headLines),\n\t\t\t\t\thint,\n\t\t\t\t\t...lines.slice(lines.length - TOOL_OUTPUT_TAIL_LINES),\n\t\t\t\t].join(\"\\n\")}`;\n\t\t\t}\n\t\t}\n\t\treturn text;\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"tool-execution.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/tool-execution.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ImageContent, TextContent } from \"@agent-forge/ai\";\nimport {\n\tBox,\n\ttype Component,\n\tContainer,\n\tgetCapabilities,\n\tImage,\n\tSpacer,\n\tText,\n\ttype TUI,\n\ttruncateToWidth,\n} from \"@agent-forge/tui\";\nimport { t } from \"../../../core/i18n/index.ts\";\nimport { formatToolCallWithArgs, getTextOutput as getRenderedTextOutput } from \"../../../core/tools/render-utils.ts\";\nimport type { ToolDefinition, ToolRenderContext } from \"../../../core/tools/tool-definition.ts\";\nimport { theme } from \"../../../theme/theme.ts\";\nimport { convertToPng } from \"../../../utils/image-convert.ts\";\nimport { keyText } from \"./keybinding-hints.ts\";\n\n/** Visual (wrapped) result lines shown before fallback output is expanded. */\nconst FALLBACK_PREVIEW_LINES = 10;\n\n/**\n * 单条工具结果展示预算 (M2, 终端输出模式设计 §3.2「展开仍复用统一的输出截断」):\n * 任何渲染器 (含第三方插件) 的结果输出在视觉行上超过预算时, 保留 head+tail、\n * 中间以一行截断说明替代 (截断原因 + 总量 + 完整输出引用, 引用存在时)。这是\n * compact 预览之上的兜底——折叠态有自己的小预览, detail 态 (ctrl+o) 的全文\n * 渲染由此封顶。错误结果豁免 (错误可见性优先, 与 collapsedPreviewText 同惯例)。\n */\nconst TOOL_OUTPUT_MAX_LINES = 400;\n\n/** 预算超出时保留完整输出的末尾视觉行数 (错误摘要与结论常聚在输出末尾)。 */\nconst TOOL_OUTPUT_TAIL_LINES = 100;\n\n/**\n * Pretty-printed JSON up to this length is collapsed to its compact single-line\n * form; longer compact forms are cut here so a short tool-result ticket shows\n * as one preview line instead of sprawling across the chat. Expansion always\n * shows the original text.\n */\nconst COLLAPSED_JSON_PREVIEW_CHARS = 220;\n\n/**\n * Collapsed preview text for fallback results: pretty-printed JSON (the default\n * serialization for capability-tool results) becomes one compact line, and any\n * other text previews verbatim. Unparseable JSON-like text stays verbatim too.\n * Error results never compact — error visibility beats compactness, so they\n * keep the (threshold-limited) full form with the error background.\n */\nfunction collapsedPreviewText(output: string, isError: boolean): string {\n\tif (isError) {\n\t\treturn output;\n\t}\n\tconst trimmed = output.trimStart();\n\tif (!trimmed.startsWith(\"{\") && !trimmed.startsWith(\"[\")) {\n\t\treturn output;\n\t}\n\ttry {\n\t\tconst compact = JSON.stringify(JSON.parse(output));\n\t\treturn compact.length > COLLAPSED_JSON_PREVIEW_CHARS\n\t\t\t? `${compact.slice(0, COLLAPSED_JSON_PREVIEW_CHARS - 1)}…`\n\t\t\t: compact;\n\t} catch {\n\t\treturn output;\n\t}\n}\n\n/**\n * Collapsed fallback output limited to a number of visual (wrapped) lines. Limiting logical\n * lines instead lets a single long line (such as minified JSON) wrap across the whole screen.\n * Caches its lines per width, since it renders on every frame for every result in the transcript.\n */\nclass VisualLinePreview implements Component {\n\tprivate text: string;\n\tprivate maxVisualLines: number;\n\tprivate formatHint: (hidden: number) => string;\n\tprivate cachedWidth: number | undefined;\n\tprivate cachedLines: string[] | undefined;\n\n\tconstructor(text: string, maxVisualLines: number, formatHint: (hidden: number) => string) {\n\t\tthis.text = text;\n\t\tthis.maxVisualLines = maxVisualLines;\n\t\tthis.formatHint = formatHint;\n\t}\n\n\trender(width: number): string[] {\n\t\tif (this.cachedLines === undefined || this.cachedWidth !== width) {\n\t\t\tconst allVisualLines = new Text(this.text, 0, 0).render(width);\n\t\t\tconst lines =\n\t\t\t\tallVisualLines.length > this.maxVisualLines\n\t\t\t\t\t? [\n\t\t\t\t\t\t\t...allVisualLines.slice(0, this.maxVisualLines),\n\t\t\t\t\t\t\ttruncateToWidth(this.formatHint(allVisualLines.length - this.maxVisualLines), width, \"...\"),\n\t\t\t\t\t\t]\n\t\t\t\t\t: allVisualLines;\n\t\t\tthis.cachedLines = lines;\n\t\t\tthis.cachedWidth = width;\n\t\t\treturn lines;\n\t\t}\n\t\treturn this.cachedLines;\n\t}\n\n\tinvalidate(): void {\n\t\tthis.cachedWidth = undefined;\n\t\tthis.cachedLines = undefined;\n\t}\n}\n\n/**\n * bash 系工具在 details 携带的全量输出文件引用 (截断说明行的\"完整输出\"引用;\n * 终端输出模式设计 §3.2 的引用要求在通用层的最大努力形态)。\n */\nfunction resultFullOutputRef(details: unknown): string | undefined {\n\tif (details === null || typeof details !== \"object\" || Array.isArray(details)) return undefined;\n\tconst ref = (details as { fullOutputPath?: unknown }).fullOutputPath;\n\treturn typeof ref === \"string\" && ref.trim() !== \"\" ? ref : undefined;\n}\n\n/**\n * 结果渲染器输出的展示预算兜底 (M2): 包装 renderResult/fallback 产出的子组件,\n * render(width) 时对视觉行超预算的输出做 head+截断说明+tail。渲染器契约不变\n * (renderResult 仍收 expanded 原值, lastComponent 仍传裸子组件); 缓存按宽度,\n * invalidate 透传子组件 (流式增量渲染依赖它)。\n */\nclass BoundedResultView implements Component {\n\tprivate child: Component;\n\tprivate maxLines: number;\n\tprivate tailLines: number;\n\tprivate isError: boolean;\n\tprivate fullOutputRef: string | undefined;\n\tprivate cachedWidth: number | undefined;\n\tprivate cachedLines: string[] | undefined;\n\n\tconstructor(\n\t\tchild: Component,\n\t\tmaxLines: number,\n\t\ttailLines: number,\n\t\tisError: boolean,\n\t\tfullOutputRef: string | undefined,\n\t) {\n\t\tthis.child = child;\n\t\tthis.maxLines = maxLines;\n\t\tthis.tailLines = tailLines;\n\t\tthis.isError = isError;\n\t\tthis.fullOutputRef = fullOutputRef;\n\t}\n\n\trender(width: number): string[] {\n\t\tif (this.cachedLines === undefined || this.cachedWidth !== width) {\n\t\t\tconst lines = this.child.render(width);\n\t\t\tif (this.isError || lines.length <= this.maxLines) {\n\t\t\t\tthis.cachedLines = lines;\n\t\t\t} else {\n\t\t\t\tconst headLines = this.maxLines - this.tailLines - 1;\n\t\t\t\tconst hidden = lines.length - headLines - this.tailLines;\n\t\t\t\tconst hint =\n\t\t\t\t\tthis.fullOutputRef === undefined\n\t\t\t\t\t\t? t(\"... ({count} lines truncated)\", { count: hidden })\n\t\t\t\t\t\t: t(\"... ({count} lines truncated; full output: {path})\", {\n\t\t\t\t\t\t\t\tcount: hidden,\n\t\t\t\t\t\t\t\tpath: this.fullOutputRef,\n\t\t\t\t\t\t\t});\n\t\t\t\tthis.cachedLines = [\n\t\t\t\t\t...lines.slice(0, headLines),\n\t\t\t\t\ttruncateToWidth(theme.fg(\"muted\", hint), width, \"...\"),\n\t\t\t\t\t...lines.slice(lines.length - this.tailLines),\n\t\t\t\t];\n\t\t\t}\n\t\t\tthis.cachedWidth = width;\n\t\t\treturn this.cachedLines;\n\t\t}\n\t\treturn this.cachedLines;\n\t}\n\n\tinvalidate(): void {\n\t\tthis.child.invalidate();\n\t\tthis.cachedWidth = undefined;\n\t\tthis.cachedLines = undefined;\n\t}\n}\n\nexport interface ToolExecutionOptions {\n\tshowImages?: boolean;\n\timageWidthCells?: number;\n}\n\nexport class ToolExecutionComponent extends Container {\n\tprivate contentBox: Box;\n\tprivate contentText: Text;\n\tprivate selfRenderContainer: Container;\n\tprivate callRendererComponent?: Component;\n\tprivate resultRendererComponent?: Component;\n\tprivate rendererState: Record<string, unknown> = {};\n\tprivate imageComponents: Image[] = [];\n\tprivate imageSpacers: Spacer[] = [];\n\tprivate toolName: string;\n\tprivate toolCallId: string;\n\tprivate args: unknown;\n\tprivate expanded = false;\n\tprivate showImages: boolean;\n\tprivate imageWidthCells: number;\n\tprivate isPartial = true;\n\tprivate toolDefinition?: ToolDefinition;\n\tprivate ui: TUI;\n\tprivate cwd: string;\n\tprivate executionStarted = false;\n\tprivate argsComplete = false;\n\tprivate result?: {\n\t\tcontent: (TextContent | ImageContent)[];\n\t\tisError: boolean;\n\t\tdetails?: unknown;\n\t};\n\tprivate convertedImages: Map<\n\t\tnumber,\n\t\t{ sourceData: string; sourceMimeType: string; data: string; mimeType: string }\n\t> = new Map();\n\tprivate hideComponent = false;\n\n\tconstructor(\n\t\ttoolName: string,\n\t\ttoolCallId: string,\n\t\targs: unknown,\n\t\toptions: ToolExecutionOptions = {},\n\t\ttoolDefinition: ToolDefinition | undefined,\n\t\tui: TUI,\n\t\tcwd: string,\n\t) {\n\t\tsuper();\n\t\tthis.toolName = toolName;\n\t\tthis.toolCallId = toolCallId;\n\t\tthis.args = args;\n\t\t// The caller passes the session registry's definition\n\t\t// (interactive-mode getRegisteredToolDefinition → facade.getToolDefinition).\n\t\t// Since D-082 批 1 the default coding tool definitions live in the\n\t\t// coding-tools plugin, so the registry is the only definition source;\n\t\t// names missing from the registry render through the generic fallback.\n\t\tthis.toolDefinition = toolDefinition;\n\t\tthis.showImages = options.showImages ?? true;\n\t\tthis.imageWidthCells = options.imageWidthCells ?? 60;\n\t\tthis.ui = ui;\n\t\tthis.cwd = cwd;\n\n\t\tthis.addChild(new Spacer(1));\n\n\t\t// Always create all shell variants. contentBox is used for default renderer-based composition.\n\t\t// selfRenderContainer is used when the tool renders its own framing.\n\t\t// contentText is reserved for generic fallback rendering when no tool definition exists.\n\t\tthis.contentBox = new Box(1, 1, (text: string) => theme.bg(\"toolPendingBg\", text));\n\t\tthis.contentText = new Text(\"\", 1, 1, (text: string) => theme.bg(\"toolPendingBg\", text));\n\t\tthis.selfRenderContainer = new Container();\n\n\t\tif (this.hasRendererDefinition()) {\n\t\t\tthis.addChild(this.getRenderShell() === \"self\" ? this.selfRenderContainer : this.contentBox);\n\t\t} else {\n\t\t\tthis.addChild(this.contentText);\n\t\t}\n\n\t\tthis.updateDisplay();\n\t}\n\n\tprivate getCallRenderer(): ToolDefinition[\"renderCall\"] | undefined {\n\t\treturn this.toolDefinition?.renderCall;\n\t}\n\n\tprivate getResultRenderer(): ToolDefinition[\"renderResult\"] | undefined {\n\t\treturn this.toolDefinition?.renderResult;\n\t}\n\n\tprivate hasRendererDefinition(): boolean {\n\t\treturn this.toolDefinition !== undefined;\n\t}\n\n\tprivate getRenderShell(): \"default\" | \"self\" {\n\t\treturn this.toolDefinition?.renderShell ?? \"default\";\n\t}\n\n\tprivate getRenderContext(lastComponent: Component | undefined): ToolRenderContext {\n\t\treturn {\n\t\t\targs: this.args,\n\t\t\ttoolCallId: this.toolCallId,\n\t\t\tinvalidate: () => {\n\t\t\t\tthis.invalidate();\n\t\t\t\tthis.ui.requestRender();\n\t\t\t},\n\t\t\tlastComponent,\n\t\t\tstate: this.rendererState,\n\t\t\tcwd: this.cwd,\n\t\t\texecutionStarted: this.executionStarted,\n\t\t\targsComplete: this.argsComplete,\n\t\t\tisPartial: this.isPartial,\n\t\t\texpanded: this.expanded,\n\t\t\tshowImages: this.showImages,\n\t\t\tisError: this.result?.isError ?? false,\n\t\t};\n\t}\n\n\tprivate createCallFallback(): Component {\n\t\treturn new Text(formatToolCallWithArgs(this.toolName, this.args, theme, this.expanded), 0, 0);\n\t}\n\n\tprivate createResultFallback(): Component | undefined {\n\t\tconst output = this.getTextOutput();\n\t\tif (!output) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tif (this.expanded) {\n\t\t\treturn new Text(\n\t\t\t\toutput\n\t\t\t\t\t.split(\"\\n\")\n\t\t\t\t\t.map((line) => theme.fg(\"toolOutput\", line))\n\t\t\t\t\t.join(\"\\n\"),\n\t\t\t\t0,\n\t\t\t\t0,\n\t\t\t);\n\t\t}\n\t\tconst previewText = collapsedPreviewText(output, this.result?.isError ?? false);\n\t\t// A compacted JSON preview is one line by construction, so it never\n\t\t// reaches the preview-line threshold — append the expand hint directly.\n\t\tif (previewText !== output) {\n\t\t\t// i18n: 原三段样式拼接合并为整句单 key,键位片段的 dim 样式损失按批次④特殊裁决 1 接受\n\t\t\tconst hint = theme.fg(\"muted\", t(\"({key} to expand)\", { key: keyText(\"app.tools.expand\") }));\n\t\t\treturn new Text(`${theme.fg(\"toolOutput\", previewText)} ${hint}`, 0, 0);\n\t\t}\n\t\tconst styled = previewText\n\t\t\t.split(\"\\n\")\n\t\t\t.map((line) => theme.fg(\"toolOutput\", line))\n\t\t\t.join(\"\\n\");\n\t\treturn new VisualLinePreview(styled, FALLBACK_PREVIEW_LINES, (hidden) =>\n\t\t\ttheme.fg(\n\t\t\t\t\"muted\",\n\t\t\t\tt(\"... ({count} more lines, {key} to expand)\", {\n\t\t\t\t\tcount: hidden,\n\t\t\t\t\tkey: keyText(\"app.tools.expand\"),\n\t\t\t\t}),\n\t\t\t),\n\t\t);\n\t}\n\n\t/** Failure fact for the enclosing ToolRunGroupComponent (D-083 quiet marker). */\n\tget isError(): boolean {\n\t\treturn this.result?.isError ?? false;\n\t}\n\n\t/** Tool name for the group marker's sole-tool form (restore path has no setActiveTool). */\n\tget name(): string {\n\t\treturn this.toolName;\n\t}\n\n\t/**\n\t * First non-empty line of a failed result's text output — the quiet group\n\t * marker's failure summary (D-083 增补:失败首行摘要). Successes and\n\t * result-less calls return undefined.\n\t */\n\tget errorSummary(): string | undefined {\n\t\tif (!this.result?.isError) return undefined;\n\t\treturn this.getTextOutput()\n\t\t\t.split(\"\\n\")\n\t\t\t.map((line) => line.trim())\n\t\t\t.find((line) => line !== \"\");\n\t}\n\n\t/**\n\t * Quiet-transcript image lines (D-083 增补:图片是用户可见的结论): the\n\t * collapsed group marker hides the text card but still renders result\n\t * images (desktop/browser screenshots). Empty when the result has no\n\t * renderable images.\n\t */\n\trenderQuietImages(width: number): string[] {\n\t\tconst lines: string[] = [];\n\t\tfor (let i = 0; i < this.imageComponents.length; i++) {\n\t\t\tconst spacer = this.imageSpacers[i];\n\t\t\t// v8 ignore next -- spacers and image components are always pushed in pairs\n\t\t\tif (spacer) {\n\t\t\t\tlines.push(...spacer.render(width));\n\t\t\t}\n\t\t\tconst imageComponent = this.imageComponents[i];\n\t\t\t// v8 ignore next -- spacers and image components are always pushed in pairs\n\t\t\tif (imageComponent) {\n\t\t\t\tlines.push(...imageComponent.render(width));\n\t\t\t}\n\t\t}\n\t\treturn lines;\n\t}\n\n\t/**\n\t * Quiet-transcript live tail (collapsed running group, D-083 运行态): the\n\t * component's own render (pending background included) cut to the last\n\t * `maxLines` visual lines. Hidden components render to [] and stay hidden.\n\t */\n\trenderQuietLiveOutput(width: number, maxLines: number): string[] {\n\t\tconst lines = this.render(width);\n\t\tif (lines.length <= maxLines) {\n\t\t\treturn lines;\n\t\t}\n\t\treturn lines.slice(lines.length - maxLines);\n\t}\n\n\tupdateArgs(args: unknown): void {\n\t\tthis.args = args;\n\t\tthis.updateDisplay();\n\t}\n\n\tmarkExecutionStarted(): void {\n\t\tthis.executionStarted = true;\n\t\tthis.updateDisplay();\n\t\tthis.ui.requestRender();\n\t}\n\n\tsetArgsComplete(): void {\n\t\tthis.argsComplete = true;\n\t\tthis.updateDisplay();\n\t\tthis.ui.requestRender();\n\t}\n\n\tupdateResult(\n\t\tresult: {\n\t\t\tcontent: (TextContent | ImageContent)[];\n\t\t\tdetails?: unknown;\n\t\t\tisError: boolean;\n\t\t},\n\t\tisPartial = false,\n\t): void {\n\t\tthis.result = result;\n\t\tthis.isPartial = isPartial;\n\t\tthis.updateDisplay();\n\t\tthis.maybeConvertImagesForKitty();\n\t}\n\n\tprivate maybeConvertImagesForKitty(): void {\n\t\tconst caps = getCapabilities();\n\t\tif (caps.images !== \"kitty\") return;\n\t\t// v8 ignore next -- sole caller updateResult always assigns this.result first\n\t\tif (!this.result) return;\n\n\t\tconst imageBlocks = this.result.content.filter((c) => c.type === \"image\");\n\t\tfor (let i = 0; i < imageBlocks.length; i++) {\n\t\t\tconst img = imageBlocks[i];\n\t\t\tif (!img.data || !img.mimeType) continue;\n\t\t\tconst sourceData = img.data;\n\t\t\tconst sourceMimeType = img.mimeType;\n\t\t\tif (sourceMimeType === \"image/png\") continue;\n\t\t\tconst cached = this.convertedImages.get(i);\n\t\t\tif (cached?.sourceData === sourceData && cached.sourceMimeType === sourceMimeType) continue;\n\n\t\t\tconst index = i;\n\t\t\tconvertToPng(sourceData, sourceMimeType).then((converted) => {\n\t\t\t\tconst currentImage = this.result?.content.filter((content) => content.type === \"image\")[index];\n\t\t\t\tif (!converted || currentImage?.data !== sourceData || currentImage.mimeType !== sourceMimeType) return;\n\t\t\t\tthis.convertedImages.set(index, {\n\t\t\t\t\tsourceData,\n\t\t\t\t\tsourceMimeType,\n\t\t\t\t\t...converted,\n\t\t\t\t});\n\t\t\t\tthis.updateDisplay();\n\t\t\t\tthis.ui.requestRender();\n\t\t\t});\n\t\t}\n\t}\n\n\tsetExpanded(expanded: boolean): void {\n\t\tthis.expanded = expanded;\n\t\tthis.updateDisplay();\n\t}\n\n\tsetShowImages(show: boolean): void {\n\t\tthis.showImages = show;\n\t\tthis.updateDisplay();\n\t}\n\n\tsetImageWidthCells(width: number): void {\n\t\tthis.imageWidthCells = Math.max(1, Math.floor(width));\n\t\tthis.updateDisplay();\n\t}\n\n\toverride invalidate(): void {\n\t\tsuper.invalidate();\n\t\tthis.updateDisplay();\n\t}\n\n\toverride render(width: number): string[] {\n\t\tif (this.hideComponent) {\n\t\t\treturn [];\n\t\t}\n\n\t\tif (this.hasRendererDefinition() && this.getRenderShell() === \"self\") {\n\t\t\tconst contentLines = this.selfRenderContainer.render(width);\n\t\t\tif (contentLines.length === 0 && this.imageComponents.length === 0) {\n\t\t\t\treturn [];\n\t\t\t}\n\n\t\t\tconst lines: string[] = [];\n\t\t\tif (contentLines.length > 0) {\n\t\t\t\tlines.push(\"\");\n\t\t\t\tlines.push(...contentLines);\n\t\t\t}\n\t\t\tfor (let i = 0; i < this.imageComponents.length; i++) {\n\t\t\t\tconst spacer = this.imageSpacers[i];\n\t\t\t\t// v8 ignore next -- spacers and image components are always pushed in pairs\n\t\t\t\tif (spacer) {\n\t\t\t\t\tlines.push(...spacer.render(width));\n\t\t\t\t}\n\t\t\t\tconst imageComponent = this.imageComponents[i];\n\t\t\t\t// v8 ignore next -- spacers and image components are always pushed in pairs\n\t\t\t\tif (imageComponent) {\n\t\t\t\t\tlines.push(...imageComponent.render(width));\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn lines;\n\t\t}\n\n\t\treturn super.render(width);\n\t}\n\n\t/** M2 展示预算: 结果子组件统一过有界视图 (错误豁免), 见 BoundedResultView。 */\n\tprivate boundedResult(component: Component): Component {\n\t\treturn new BoundedResultView(\n\t\t\tcomponent,\n\t\t\tTOOL_OUTPUT_MAX_LINES,\n\t\t\tTOOL_OUTPUT_TAIL_LINES,\n\t\t\tthis.result?.isError ?? false,\n\t\t\tresultFullOutputRef(this.result?.details),\n\t\t);\n\t}\n\n\tprivate updateDisplay(): void {\n\t\tconst bgFn = this.isPartial\n\t\t\t? (text: string) => theme.bg(\"toolPendingBg\", text)\n\t\t\t: this.result?.isError\n\t\t\t\t? (text: string) => theme.bg(\"toolErrorBg\", text)\n\t\t\t\t: (text: string) => theme.bg(\"toolSuccessBg\", text);\n\n\t\tlet hasContent = false;\n\t\tthis.hideComponent = false;\n\t\tif (this.hasRendererDefinition()) {\n\t\t\tconst renderContainer = this.getRenderShell() === \"self\" ? this.selfRenderContainer : this.contentBox;\n\t\t\tif (renderContainer instanceof Box) {\n\t\t\t\trenderContainer.setBgFn(bgFn);\n\t\t\t}\n\t\t\trenderContainer.clear();\n\n\t\t\tconst callRenderer = this.getCallRenderer();\n\t\t\tif (!callRenderer) {\n\t\t\t\trenderContainer.addChild(this.createCallFallback());\n\t\t\t\thasContent = true;\n\t\t\t} else {\n\t\t\t\ttry {\n\t\t\t\t\tconst component = callRenderer(this.args, theme, this.getRenderContext(this.callRendererComponent));\n\t\t\t\t\t// 渲染器可能返回 undefined(选择不渲染);此时交给无内容隐藏\n\t\t\t\t\t// 逻辑,不能把 undefined 塞进 Box.children(invalidate 会崩溃)。\n\t\t\t\t\tif (component) {\n\t\t\t\t\t\tthis.callRendererComponent = component;\n\t\t\t\t\t\trenderContainer.addChild(component);\n\t\t\t\t\t\thasContent = true;\n\t\t\t\t\t}\n\t\t\t\t} catch {\n\t\t\t\t\tthis.callRendererComponent = undefined;\n\t\t\t\t\trenderContainer.addChild(this.createCallFallback());\n\t\t\t\t\thasContent = true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (this.result) {\n\t\t\t\tconst resultRenderer = this.getResultRenderer();\n\t\t\t\tif (!resultRenderer) {\n\t\t\t\t\tconst component = this.createResultFallback();\n\t\t\t\t\tif (component) {\n\t\t\t\t\t\trenderContainer.addChild(this.boundedResult(component));\n\t\t\t\t\t\thasContent = true;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst component = resultRenderer(\n\t\t\t\t\t\t\t{ content: this.result.content, details: this.result.details },\n\t\t\t\t\t\t\t{ expanded: this.expanded, isPartial: this.isPartial },\n\t\t\t\t\t\t\ttheme,\n\t\t\t\t\t\t\tthis.getRenderContext(this.resultRendererComponent),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tif (component) {\n\t\t\t\t\t\t\tthis.resultRendererComponent = component;\n\t\t\t\t\t\t\trenderContainer.addChild(this.boundedResult(component));\n\t\t\t\t\t\t\thasContent = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t} catch {\n\t\t\t\t\t\tthis.resultRendererComponent = undefined;\n\t\t\t\t\t\tconst component = this.createResultFallback();\n\t\t\t\t\t\tif (component) {\n\t\t\t\t\t\t\trenderContainer.addChild(component);\n\t\t\t\t\t\t\thasContent = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tthis.contentText.setCustomBgFn(bgFn);\n\t\t\tthis.contentText.setText(this.formatToolExecution());\n\t\t\thasContent = true;\n\t\t}\n\n\t\tfor (const img of this.imageComponents) {\n\t\t\tthis.removeChild(img);\n\t\t}\n\t\tthis.imageComponents = [];\n\t\tfor (const spacer of this.imageSpacers) {\n\t\t\tthis.removeChild(spacer);\n\t\t}\n\t\tthis.imageSpacers = [];\n\n\t\tif (this.result) {\n\t\t\tconst imageBlocks = this.result.content.filter((c) => c.type === \"image\");\n\t\t\tconst caps = getCapabilities();\n\t\t\tfor (let i = 0; i < imageBlocks.length; i++) {\n\t\t\t\tconst img = imageBlocks[i];\n\t\t\t\tif (caps.images && this.showImages && img.data && img.mimeType) {\n\t\t\t\t\tconst cached = this.convertedImages.get(i);\n\t\t\t\t\tconst converted =\n\t\t\t\t\t\tcached?.sourceData === img.data && cached.sourceMimeType === img.mimeType ? cached : undefined;\n\t\t\t\t\tconst imageData = converted?.data ?? img.data;\n\t\t\t\t\tconst imageMimeType = converted?.mimeType ?? img.mimeType;\n\t\t\t\t\tif (caps.images === \"kitty\" && imageMimeType !== \"image/png\") continue;\n\n\t\t\t\t\tconst spacer = new Spacer(1);\n\t\t\t\t\tthis.addChild(spacer);\n\t\t\t\t\tthis.imageSpacers.push(spacer);\n\t\t\t\t\tconst imageComponent = new Image(\n\t\t\t\t\t\timageData,\n\t\t\t\t\t\timageMimeType,\n\t\t\t\t\t\t{ fallbackColor: (s: string) => theme.fg(\"toolOutput\", s) },\n\t\t\t\t\t\t{ maxWidthCells: this.imageWidthCells },\n\t\t\t\t\t);\n\t\t\t\t\tthis.imageComponents.push(imageComponent);\n\t\t\t\t\tthis.addChild(imageComponent);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (this.hasRendererDefinition() && !hasContent && this.imageComponents.length === 0) {\n\t\t\tthis.hideComponent = true;\n\t\t}\n\t}\n\n\tprivate getTextOutput(): string {\n\t\treturn getRenderedTextOutput(this.result, this.showImages);\n\t}\n\n\tprivate formatToolExecution(): string {\n\t\tlet text = theme.fg(\"toolTitle\", theme.bold(this.toolName));\n\t\tconst content = JSON.stringify(this.args, null, 2);\n\t\tif (content) {\n\t\t\ttext += `\\n\\n${content}`;\n\t\t}\n\t\tconst output = this.getTextOutput();\n\t\tif (output) {\n\t\t\t// 无定义工具的通用回退同样封顶 (M2, 逻辑行粒度): 超预算 head+说明+tail。\n\t\t\tconst lines = output.split(\"\\n\");\n\t\t\tif (lines.length <= TOOL_OUTPUT_MAX_LINES) {\n\t\t\t\ttext += `\\n${output}`;\n\t\t\t} else {\n\t\t\t\tconst headLines = TOOL_OUTPUT_MAX_LINES - TOOL_OUTPUT_TAIL_LINES - 1;\n\t\t\t\tconst hint = t(\"... ({count} lines truncated)\", {\n\t\t\t\t\tcount: lines.length - headLines - TOOL_OUTPUT_TAIL_LINES,\n\t\t\t\t});\n\t\t\t\ttext += `\\n${[\n\t\t\t\t\t...lines.slice(0, headLines),\n\t\t\t\t\thint,\n\t\t\t\t\t...lines.slice(lines.length - TOOL_OUTPUT_TAIL_LINES),\n\t\t\t\t].join(\"\\n\")}`;\n\t\t\t}\n\t\t}\n\t\treturn text;\n\t}\n}\n"]}
|
|
@@ -1,15 +1,22 @@
|
|
|
1
|
-
import { Container } from "@agent-forge/tui";
|
|
1
|
+
import { Container, type TUI } from "@agent-forge/tui";
|
|
2
2
|
import type { ToolExecutionComponent } from "./tool-execution.ts";
|
|
3
3
|
/**
|
|
4
4
|
* Quiet-transcript group for one assistant turn's tool calls (D-083,
|
|
5
5
|
* docs/design/终端输出模式设计.md §3). Collapsed (quiet, the default) it
|
|
6
|
-
* renders a single dim marker line —
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
6
|
+
* renders a single dim marker line — a braille spinner with the running tool
|
|
7
|
+
* name and live elapsed seconds while executing, the quiet ● dot with the tool
|
|
8
|
+
* count (or the sole tool's name) plus the group wall-clock duration once
|
|
9
|
+
* complete, plus an error-colored failure count that never goes silent —
|
|
10
|
+
* followed by the tail of the active tool's live output while running, the
|
|
11
|
+
* first failing result's first output line and every result image (D-083 增补:
|
|
12
|
+
* the error text and screenshots are user-visible conclusions, not process
|
|
13
|
+
* noise). Expanded (detail, ctrl+o) it renders every child tool component in
|
|
14
|
+
* its expanded form.
|
|
15
|
+
*
|
|
16
|
+
* The wall clock is live-path only (startClock on tool_execution_start):
|
|
17
|
+
* groups restored from a session carry no timing data and stay timeless.
|
|
18
|
+
* Completed groups reopen (adjacent assistant messages with no visible
|
|
19
|
+
* content in between) and keep accumulating the same clock.
|
|
13
20
|
*
|
|
14
21
|
* Collapsed render never renders the child text cards, so no per-tool card,
|
|
15
22
|
* kv arg line, or result preview leaks into the quiet transcript.
|
|
@@ -19,26 +26,49 @@ export declare class ToolRunGroupComponent extends Container {
|
|
|
19
26
|
private spacer;
|
|
20
27
|
private expanded;
|
|
21
28
|
private activeToolName;
|
|
29
|
+
private activeToolComponent;
|
|
22
30
|
private lastToolName;
|
|
23
31
|
private failedCount;
|
|
24
32
|
private runComplete;
|
|
25
|
-
|
|
33
|
+
private startedAt;
|
|
34
|
+
private endedAt;
|
|
35
|
+
private frameIndex;
|
|
36
|
+
private intervalId;
|
|
37
|
+
private ui;
|
|
38
|
+
constructor(ui: TUI);
|
|
26
39
|
addTool(component: ToolExecutionComponent): void;
|
|
27
|
-
/** Current executing tool
|
|
28
|
-
setActiveTool(name: string | undefined): void;
|
|
40
|
+
/** Current executing tool (tool_execution_start); clears on completion. */
|
|
41
|
+
setActiveTool(name: string | undefined, component?: ToolExecutionComponent): void;
|
|
29
42
|
/** Count a finished tool result; errors keep the failure count visible. */
|
|
30
43
|
noteResult(isError: boolean): void;
|
|
44
|
+
/**
|
|
45
|
+
* Live wall clock (tool_execution_start): stamp the start once and spin the
|
|
46
|
+
* running marker. Idempotent — later tools of the same run keep the
|
|
47
|
+
* original start.
|
|
48
|
+
*/
|
|
49
|
+
startClock(): void;
|
|
31
50
|
/** The turn's tool run finished; the marker switches to its final form. */
|
|
32
51
|
markRunComplete(): void;
|
|
52
|
+
/**
|
|
53
|
+
* Reopen a completed group so a merged run continues in it (D-083 跨回合
|
|
54
|
+
* 合并): back to the running form, wall clock kept accumulating.
|
|
55
|
+
*/
|
|
56
|
+
reopen(): void;
|
|
33
57
|
setExpanded(expanded: boolean): void;
|
|
34
58
|
invalidate(): void;
|
|
35
59
|
render(width: number): string[];
|
|
60
|
+
private startAnimation;
|
|
61
|
+
private stopAnimation;
|
|
36
62
|
/**
|
|
37
63
|
* First failing tool's first output line, indented under the marker and
|
|
38
64
|
* cut to width (D-083 增补:失败内容可见,不用全局展开找一条错误).
|
|
39
65
|
*/
|
|
40
66
|
private firstErrorSummary;
|
|
41
67
|
private markerLine;
|
|
68
|
+
/** Spinner frame while a tool executes, the quiet dot otherwise. */
|
|
69
|
+
private markerPrefix;
|
|
70
|
+
/** Live elapsed while running; frozen group wall-clock duration once complete. */
|
|
71
|
+
private markerTiming;
|
|
42
72
|
private markerLabel;
|
|
43
73
|
}
|
|
44
74
|
//# sourceMappingURL=tool-run-group.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool-run-group.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/tool-run-group.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAA2B,MAAM,kBAAkB,CAAC;AAGtE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAElE;;;;;;;;;;;;;GAaG;AACH,qBAAa,qBAAsB,SAAQ,SAAS;IACnD,OAAO,CAAC,KAAK,CAAgC;IAC7C,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,cAAc,CAAqB;IAC3C,OAAO,CAAC,YAAY,CAAqB;IACzC,OAAO,CAAC,WAAW,CAAK;IACxB,OAAO,CAAC,WAAW,CAAS;IAE5B,cAMC;IAED,OAAO,CAAC,SAAS,EAAE,sBAAsB,GAAG,IAAI,CAM/C;IAED,gFAAgF;IAChF,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAK5C;IAED,2EAA2E;IAC3E,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAIjC;IAED,2EAA2E;IAC3E,eAAe,IAAI,IAAI,CAGtB;IAID,WAAW,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,CAWnC;IAEQ,UAAU,IAAI,IAAI,CAE1B;IAEQ,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAavC;IAED;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAUzB,OAAO,CAAC,UAAU;IASlB,OAAO,CAAC,WAAW;CAUnB","sourcesContent":["import { Container, Spacer, truncateToWidth } from \"@agent-forge/tui\";\nimport { t } from \"../../../core/i18n/index.ts\";\nimport { theme } from \"../../../theme/theme.ts\";\nimport type { ToolExecutionComponent } from \"./tool-execution.ts\";\n\n/**\n * Quiet-transcript group for one assistant turn's tool calls (D-083,\n * docs/design/终端输出模式设计.md §3). Collapsed (quiet, the default) it\n * renders a single dim marker line — running tool name while executing, the\n * tool count (or the sole tool's name) once complete, plus an error-colored\n * failure count that never goes silent — followed by the first failing\n * result's first output line and every result image (D-083 增补: the error\n * text and screenshots are user-visible conclusions, not process noise).\n * Expanded (detail, ctrl+o) it renders every child tool component in its\n * expanded form.\n *\n * Collapsed render never renders the child text cards, so no per-tool card,\n * kv arg line, or result preview leaks into the quiet transcript.\n */\nexport class ToolRunGroupComponent extends Container {\n\tprivate tools: ToolExecutionComponent[] = [];\n\tprivate spacer = new Spacer(1);\n\tprivate expanded = false;\n\tprivate activeToolName: string | undefined;\n\tprivate lastToolName: string | undefined;\n\tprivate failedCount = 0;\n\tprivate runComplete = false;\n\n\tconstructor() {\n\t\tsuper();\n\t\t// Same transcript rhythm as a directly-mounted ToolExecutionComponent\n\t\t// (which leads with its own Spacer(1)): one blank line before the\n\t\t// marker line in quiet mode, before the child cards in detail mode.\n\t\tthis.addChild(this.spacer);\n\t}\n\n\taddTool(component: ToolExecutionComponent): void {\n\t\tthis.tools.push(component);\n\t\t// Seed the name so the sole-tool marker form survives the restore path,\n\t\t// which never sees a tool_execution_start (no setActiveTool call).\n\t\tthis.lastToolName = component.name;\n\t\tthis.addChild(component);\n\t}\n\n\t/** Current executing tool name (tool_execution_start); clears on completion. */\n\tsetActiveTool(name: string | undefined): void {\n\t\tthis.activeToolName = name;\n\t\tif (name !== undefined) {\n\t\t\tthis.lastToolName = name;\n\t\t}\n\t}\n\n\t/** Count a finished tool result; errors keep the failure count visible. */\n\tnoteResult(isError: boolean): void {\n\t\tif (isError) {\n\t\t\tthis.failedCount += 1;\n\t\t}\n\t}\n\n\t/** The turn's tool run finished; the marker switches to its final form. */\n\tmarkRunComplete(): void {\n\t\tthis.runComplete = true;\n\t\tthis.activeToolName = undefined;\n\t}\n\n\t// Not an override: Container declares no setExpanded; the Expandable\n\t// interface (interactive-dialog-ui.ts) matches structurally.\n\tsetExpanded(expanded: boolean): void {\n\t\tif (expanded === this.expanded) {\n\t\t\treturn;\n\t\t}\n\t\tthis.expanded = expanded;\n\t\t// Detail mode renders the children as full cards: propagate to every\n\t\t// child so an entire group flips with one ctrl+o press (the\n\t\t// setToolsExpanded loop only reaches this group component).\n\t\tfor (const tool of this.tools) {\n\t\t\ttool.setExpanded(expanded);\n\t\t}\n\t}\n\n\toverride invalidate(): void {\n\t\tsuper.invalidate();\n\t}\n\n\toverride render(width: number): string[] {\n\t\tif (this.expanded) {\n\t\t\treturn super.render(width);\n\t\t}\n\t\tconst lines = [...this.spacer.render(width), this.markerLine()];\n\t\tconst failure = this.firstErrorSummary(width);\n\t\tif (failure) {\n\t\t\tlines.push(failure);\n\t\t}\n\t\tfor (const tool of this.tools) {\n\t\t\tlines.push(...tool.renderQuietImages(width));\n\t\t}\n\t\treturn lines;\n\t}\n\n\t/**\n\t * First failing tool's first output line, indented under the marker and\n\t * cut to width (D-083 增补:失败内容可见,不用全局展开找一条错误).\n\t */\n\tprivate firstErrorSummary(width: number): string | undefined {\n\t\tfor (const tool of this.tools) {\n\t\t\tconst summary = tool.errorSummary;\n\t\t\tif (summary !== undefined) {\n\t\t\t\treturn ` ${theme.fg(\"error\", truncateToWidth(summary, Math.max(width - 1, 1), \"...\"))}`;\n\t\t\t}\n\t\t}\n\t\treturn undefined;\n\t}\n\n\tprivate markerLine(): string {\n\t\tconst label = this.markerLabel();\n\t\tlet line = theme.fg(\"muted\", `⏺ ${label}`);\n\t\tif (this.failedCount > 0) {\n\t\t\tline += ` ${theme.fg(\"error\", `· ${t(\"{count} failed\", { count: this.failedCount })}`)}`;\n\t\t}\n\t\treturn line;\n\t}\n\n\tprivate markerLabel(): string {\n\t\tif (!this.runComplete && this.activeToolName !== undefined) {\n\t\t\treturn this.activeToolName;\n\t\t}\n\t\tif (this.runComplete && this.tools.length === 1 && this.lastToolName !== undefined) {\n\t\t\treturn this.lastToolName;\n\t\t}\n\t\tconst count = this.tools.length;\n\t\treturn t(count === 1 ? \"{count} tool\" : \"{count} tools\", { count });\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"tool-run-group.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/tool-run-group.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAU,KAAK,GAAG,EAAmB,MAAM,kBAAkB,CAAC;AAGhF,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAuBlE;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBAAa,qBAAsB,SAAQ,SAAS;IACnD,OAAO,CAAC,KAAK,CAAgC;IAC7C,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,cAAc,CAAqB;IAC3C,OAAO,CAAC,mBAAmB,CAAqC;IAChE,OAAO,CAAC,YAAY,CAAqB;IACzC,OAAO,CAAC,WAAW,CAAK;IACxB,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,SAAS,CAAqB;IACtC,OAAO,CAAC,OAAO,CAAqB;IACpC,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,UAAU,CAA6B;IAC/C,OAAO,CAAC,EAAE,CAAM;IAEhB,YAAY,EAAE,EAAE,GAAG,EAOlB;IAED,OAAO,CAAC,SAAS,EAAE,sBAAsB,GAAG,IAAI,CAM/C;IAED,2EAA2E;IAC3E,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,SAAS,CAAC,EAAE,sBAAsB,GAAG,IAAI,CAMhF;IAED,2EAA2E;IAC3E,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAIjC;IAED;;;;OAIG;IACH,UAAU,IAAI,IAAI,CAKjB;IAED,2EAA2E;IAC3E,eAAe,IAAI,IAAI,CAMtB;IAED;;;OAGG;IACH,MAAM,IAAI,IAAI,CAMb;IAID,WAAW,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,CAkBnC;IAEQ,UAAU,IAAI,IAAI,CAE1B;IAEQ,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAmBvC;IAED,OAAO,CAAC,cAAc;IAStB,OAAO,CAAC,aAAa;IAOrB;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAUzB,OAAO,CAAC,UAAU;IAgBlB,oEAAoE;IACpE,OAAO,CAAC,YAAY;IAOpB,kFAAkF;IAClF,OAAO,CAAC,YAAY;IAUpB,OAAO,CAAC,WAAW;CAUnB","sourcesContent":["import { Container, Spacer, type TUI, truncateToWidth } from \"@agent-forge/tui\";\nimport { t } from \"../../../core/i18n/index.ts\";\nimport { theme } from \"../../../theme/theme.ts\";\nimport type { ToolExecutionComponent } from \"./tool-execution.ts\";\n\n/** Braille spinner frames for the running marker (same set as the TUI loader). */\nconst SPINNER_FRAMES = [\"⠋\", \"⠙\", \"⠹\", \"⠸\", \"⠼\", \"⠴\", \"⠦\", \"⠧\", \"⠇\", \"⠏\"];\nconst SPINNER_INTERVAL_MS = 120;\n\n/** Collapsed running-state preview: tail lines of the active tool's live output. */\nconst LIVE_PREVIEW_LINES = 8;\n\n/**\n * bash-style group wall-clock rendering: 5.2s under a minute, 2m 3s under an\n * hour, 1h 2m 3s beyond.\n */\nfunction formatDuration(ms: number): string {\n\tconst totalSeconds = Math.floor(ms / 1000);\n\tconst hours = Math.floor(totalSeconds / 3600);\n\tconst minutes = Math.floor((totalSeconds % 3600) / 60);\n\tconst seconds = totalSeconds % 60;\n\tif (hours > 0) return `${hours}h ${minutes}m ${seconds}s`;\n\tif (minutes > 0) return `${minutes}m ${seconds}s`;\n\treturn `${(ms / 1000).toFixed(1)}s`;\n}\n\n/**\n * Quiet-transcript group for one assistant turn's tool calls (D-083,\n * docs/design/终端输出模式设计.md §3). Collapsed (quiet, the default) it\n * renders a single dim marker line — a braille spinner with the running tool\n * name and live elapsed seconds while executing, the quiet ● dot with the tool\n * count (or the sole tool's name) plus the group wall-clock duration once\n * complete, plus an error-colored failure count that never goes silent —\n * followed by the tail of the active tool's live output while running, the\n * first failing result's first output line and every result image (D-083 增补:\n * the error text and screenshots are user-visible conclusions, not process\n * noise). Expanded (detail, ctrl+o) it renders every child tool component in\n * its expanded form.\n *\n * The wall clock is live-path only (startClock on tool_execution_start):\n * groups restored from a session carry no timing data and stay timeless.\n * Completed groups reopen (adjacent assistant messages with no visible\n * content in between) and keep accumulating the same clock.\n *\n * Collapsed render never renders the child text cards, so no per-tool card,\n * kv arg line, or result preview leaks into the quiet transcript.\n */\nexport class ToolRunGroupComponent extends Container {\n\tprivate tools: ToolExecutionComponent[] = [];\n\tprivate spacer = new Spacer(1);\n\tprivate expanded = false;\n\tprivate activeToolName: string | undefined;\n\tprivate activeToolComponent: ToolExecutionComponent | undefined;\n\tprivate lastToolName: string | undefined;\n\tprivate failedCount = 0;\n\tprivate runComplete = false;\n\tprivate startedAt: number | undefined;\n\tprivate endedAt: number | undefined;\n\tprivate frameIndex = 0;\n\tprivate intervalId: NodeJS.Timeout | undefined;\n\tprivate ui: TUI;\n\n\tconstructor(ui: TUI) {\n\t\tsuper();\n\t\tthis.ui = ui;\n\t\t// Same transcript rhythm as a directly-mounted ToolExecutionComponent\n\t\t// (which leads with its own Spacer(1)): one blank line before the\n\t\t// marker line in quiet mode, before the child cards in detail mode.\n\t\tthis.addChild(this.spacer);\n\t}\n\n\taddTool(component: ToolExecutionComponent): void {\n\t\tthis.tools.push(component);\n\t\t// Seed the name so the sole-tool marker form survives the restore path,\n\t\t// which never sees a tool_execution_start (no setActiveTool call).\n\t\tthis.lastToolName = component.name;\n\t\tthis.addChild(component);\n\t}\n\n\t/** Current executing tool (tool_execution_start); clears on completion. */\n\tsetActiveTool(name: string | undefined, component?: ToolExecutionComponent): void {\n\t\tthis.activeToolName = name;\n\t\tthis.activeToolComponent = name === undefined ? undefined : component;\n\t\tif (name !== undefined) {\n\t\t\tthis.lastToolName = name;\n\t\t}\n\t}\n\n\t/** Count a finished tool result; errors keep the failure count visible. */\n\tnoteResult(isError: boolean): void {\n\t\tif (isError) {\n\t\t\tthis.failedCount += 1;\n\t\t}\n\t}\n\n\t/**\n\t * Live wall clock (tool_execution_start): stamp the start once and spin the\n\t * running marker. Idempotent — later tools of the same run keep the\n\t * original start.\n\t */\n\tstartClock(): void {\n\t\tthis.startedAt ??= Date.now();\n\t\tif (!this.expanded) {\n\t\t\tthis.startAnimation();\n\t\t}\n\t}\n\n\t/** The turn's tool run finished; the marker switches to its final form. */\n\tmarkRunComplete(): void {\n\t\tthis.runComplete = true;\n\t\tthis.activeToolName = undefined;\n\t\tthis.activeToolComponent = undefined;\n\t\tthis.endedAt = Date.now();\n\t\tthis.stopAnimation();\n\t}\n\n\t/**\n\t * Reopen a completed group so a merged run continues in it (D-083 跨回合\n\t * 合并): back to the running form, wall clock kept accumulating.\n\t */\n\treopen(): void {\n\t\tthis.runComplete = false;\n\t\tthis.endedAt = undefined;\n\t\tif (!this.expanded) {\n\t\t\tthis.startAnimation();\n\t\t}\n\t}\n\n\t// Not an override: Container declares no setExpanded; the Expandable\n\t// interface (interactive-dialog-ui.ts) matches structurally.\n\tsetExpanded(expanded: boolean): void {\n\t\tif (expanded === this.expanded) {\n\t\t\treturn;\n\t\t}\n\t\tthis.expanded = expanded;\n\t\t// Detail mode renders the children as full cards: propagate to every\n\t\t// child so an entire group flips with one ctrl+o press (the\n\t\t// setToolsExpanded loop only reaches this group component).\n\t\tfor (const tool of this.tools) {\n\t\t\ttool.setExpanded(expanded);\n\t\t}\n\t\t// Detail mode keeps the marker (and its spinner) off screen: the\n\t\t// animation stops and restarts when the group collapses unfinished.\n\t\tif (expanded) {\n\t\t\tthis.stopAnimation();\n\t\t} else if (!this.runComplete && this.startedAt !== undefined) {\n\t\t\tthis.startAnimation();\n\t\t}\n\t}\n\n\toverride invalidate(): void {\n\t\tsuper.invalidate();\n\t}\n\n\toverride render(width: number): string[] {\n\t\tif (this.expanded) {\n\t\t\treturn super.render(width);\n\t\t}\n\t\tconst lines = [...this.spacer.render(width), this.markerLine(width)];\n\t\t// Live output (D-083 运行态): while the run executes, the active\n\t\t// tool's output tail rides under the marker; it disappears again the\n\t\t// moment the run seals.\n\t\tif (!this.runComplete && this.activeToolComponent) {\n\t\t\tlines.push(...this.activeToolComponent.renderQuietLiveOutput(width, LIVE_PREVIEW_LINES));\n\t\t}\n\t\tconst failure = this.firstErrorSummary(width);\n\t\tif (failure) {\n\t\t\tlines.push(failure);\n\t\t}\n\t\tfor (const tool of this.tools) {\n\t\t\tlines.push(...tool.renderQuietImages(width));\n\t\t}\n\t\treturn lines;\n\t}\n\n\tprivate startAnimation(): void {\n\t\tthis.stopAnimation();\n\t\tthis.intervalId = setInterval(() => {\n\t\t\tthis.frameIndex = (this.frameIndex + 1) % SPINNER_FRAMES.length;\n\t\t\tthis.invalidate();\n\t\t\tthis.ui.requestRender();\n\t\t}, SPINNER_INTERVAL_MS);\n\t}\n\n\tprivate stopAnimation(): void {\n\t\tif (this.intervalId !== undefined) {\n\t\t\tclearInterval(this.intervalId);\n\t\t\tthis.intervalId = undefined;\n\t\t}\n\t}\n\n\t/**\n\t * First failing tool's first output line, indented under the marker and\n\t * cut to width (D-083 增补:失败内容可见,不用全局展开找一条错误).\n\t */\n\tprivate firstErrorSummary(width: number): string | undefined {\n\t\tfor (const tool of this.tools) {\n\t\t\tconst summary = tool.errorSummary;\n\t\t\tif (summary !== undefined) {\n\t\t\t\treturn ` ${theme.fg(\"error\", truncateToWidth(summary, Math.max(width - 1, 1), \"...\"))}`;\n\t\t\t}\n\t\t}\n\t\treturn undefined;\n\t}\n\n\tprivate markerLine(width: number): string {\n\t\tconst label = this.markerLabel();\n\t\tlet line = theme.fg(\"muted\", `${this.markerPrefix()} ${label}`);\n\t\tconst timing = this.markerTiming();\n\t\tif (timing !== undefined) {\n\t\t\tline += ` ${theme.fg(\"muted\", timing)}`;\n\t\t}\n\t\tif (this.failedCount > 0) {\n\t\t\tline += ` ${theme.fg(\"error\", `· ${t(\"{count} failed\", { count: this.failedCount })}`)}`;\n\t\t}\n\t\t// The marker packs label + duration + failure count: long tool names\n\t\t// (mcp__server__tool) overflow narrow terminals, and the main screen\n\t\t// throws on overwide lines. Same ANSI-aware cut as firstErrorSummary.\n\t\treturn truncateToWidth(line, Math.max(width, 1), \"...\");\n\t}\n\n\t/** Spinner frame while a tool executes, the quiet dot otherwise. */\n\tprivate markerPrefix(): string {\n\t\tif (!this.runComplete && this.activeToolName !== undefined) {\n\t\t\treturn SPINNER_FRAMES[this.frameIndex];\n\t\t}\n\t\treturn \"●\";\n\t}\n\n\t/** Live elapsed while running; frozen group wall-clock duration once complete. */\n\tprivate markerTiming(): string | undefined {\n\t\tif (this.startedAt === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\t\tif (!this.runComplete) {\n\t\t\treturn formatDuration(Date.now() - this.startedAt);\n\t\t}\n\t\treturn this.endedAt !== undefined ? formatDuration(this.endedAt - this.startedAt) : undefined;\n\t}\n\n\tprivate markerLabel(): string {\n\t\tif (!this.runComplete && this.activeToolName !== undefined) {\n\t\t\treturn this.activeToolName;\n\t\t}\n\t\tif (this.runComplete && this.tools.length === 1 && this.lastToolName !== undefined) {\n\t\t\treturn this.lastToolName;\n\t\t}\n\t\tconst count = this.tools.length;\n\t\treturn t(count === 1 ? \"{count} tool\" : \"{count} tools\", { count });\n\t}\n}\n"]}
|
|
@@ -1,16 +1,43 @@
|
|
|
1
1
|
import { Container, Spacer, truncateToWidth } from "@agent-forge/tui";
|
|
2
2
|
import { t } from "../../../core/i18n/index.js";
|
|
3
3
|
import { theme } from "../../../theme/theme.js";
|
|
4
|
+
/** Braille spinner frames for the running marker (same set as the TUI loader). */
|
|
5
|
+
const SPINNER_FRAMES = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
|
|
6
|
+
const SPINNER_INTERVAL_MS = 120;
|
|
7
|
+
/** Collapsed running-state preview: tail lines of the active tool's live output. */
|
|
8
|
+
const LIVE_PREVIEW_LINES = 8;
|
|
9
|
+
/**
|
|
10
|
+
* bash-style group wall-clock rendering: 5.2s under a minute, 2m 3s under an
|
|
11
|
+
* hour, 1h 2m 3s beyond.
|
|
12
|
+
*/
|
|
13
|
+
function formatDuration(ms) {
|
|
14
|
+
const totalSeconds = Math.floor(ms / 1000);
|
|
15
|
+
const hours = Math.floor(totalSeconds / 3600);
|
|
16
|
+
const minutes = Math.floor((totalSeconds % 3600) / 60);
|
|
17
|
+
const seconds = totalSeconds % 60;
|
|
18
|
+
if (hours > 0)
|
|
19
|
+
return `${hours}h ${minutes}m ${seconds}s`;
|
|
20
|
+
if (minutes > 0)
|
|
21
|
+
return `${minutes}m ${seconds}s`;
|
|
22
|
+
return `${(ms / 1000).toFixed(1)}s`;
|
|
23
|
+
}
|
|
4
24
|
/**
|
|
5
25
|
* Quiet-transcript group for one assistant turn's tool calls (D-083,
|
|
6
26
|
* docs/design/终端输出模式设计.md §3). Collapsed (quiet, the default) it
|
|
7
|
-
* renders a single dim marker line —
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
27
|
+
* renders a single dim marker line — a braille spinner with the running tool
|
|
28
|
+
* name and live elapsed seconds while executing, the quiet ● dot with the tool
|
|
29
|
+
* count (or the sole tool's name) plus the group wall-clock duration once
|
|
30
|
+
* complete, plus an error-colored failure count that never goes silent —
|
|
31
|
+
* followed by the tail of the active tool's live output while running, the
|
|
32
|
+
* first failing result's first output line and every result image (D-083 增补:
|
|
33
|
+
* the error text and screenshots are user-visible conclusions, not process
|
|
34
|
+
* noise). Expanded (detail, ctrl+o) it renders every child tool component in
|
|
35
|
+
* its expanded form.
|
|
36
|
+
*
|
|
37
|
+
* The wall clock is live-path only (startClock on tool_execution_start):
|
|
38
|
+
* groups restored from a session carry no timing data and stay timeless.
|
|
39
|
+
* Completed groups reopen (adjacent assistant messages with no visible
|
|
40
|
+
* content in between) and keep accumulating the same clock.
|
|
14
41
|
*
|
|
15
42
|
* Collapsed render never renders the child text cards, so no per-tool card,
|
|
16
43
|
* kv arg line, or result preview leaks into the quiet transcript.
|
|
@@ -20,11 +47,18 @@ export class ToolRunGroupComponent extends Container {
|
|
|
20
47
|
spacer = new Spacer(1);
|
|
21
48
|
expanded = false;
|
|
22
49
|
activeToolName;
|
|
50
|
+
activeToolComponent;
|
|
23
51
|
lastToolName;
|
|
24
52
|
failedCount = 0;
|
|
25
53
|
runComplete = false;
|
|
26
|
-
|
|
54
|
+
startedAt;
|
|
55
|
+
endedAt;
|
|
56
|
+
frameIndex = 0;
|
|
57
|
+
intervalId;
|
|
58
|
+
ui;
|
|
59
|
+
constructor(ui) {
|
|
27
60
|
super();
|
|
61
|
+
this.ui = ui;
|
|
28
62
|
// Same transcript rhythm as a directly-mounted ToolExecutionComponent
|
|
29
63
|
// (which leads with its own Spacer(1)): one blank line before the
|
|
30
64
|
// marker line in quiet mode, before the child cards in detail mode.
|
|
@@ -37,9 +71,10 @@ export class ToolRunGroupComponent extends Container {
|
|
|
37
71
|
this.lastToolName = component.name;
|
|
38
72
|
this.addChild(component);
|
|
39
73
|
}
|
|
40
|
-
/** Current executing tool
|
|
41
|
-
setActiveTool(name) {
|
|
74
|
+
/** Current executing tool (tool_execution_start); clears on completion. */
|
|
75
|
+
setActiveTool(name, component) {
|
|
42
76
|
this.activeToolName = name;
|
|
77
|
+
this.activeToolComponent = name === undefined ? undefined : component;
|
|
43
78
|
if (name !== undefined) {
|
|
44
79
|
this.lastToolName = name;
|
|
45
80
|
}
|
|
@@ -50,10 +85,35 @@ export class ToolRunGroupComponent extends Container {
|
|
|
50
85
|
this.failedCount += 1;
|
|
51
86
|
}
|
|
52
87
|
}
|
|
88
|
+
/**
|
|
89
|
+
* Live wall clock (tool_execution_start): stamp the start once and spin the
|
|
90
|
+
* running marker. Idempotent — later tools of the same run keep the
|
|
91
|
+
* original start.
|
|
92
|
+
*/
|
|
93
|
+
startClock() {
|
|
94
|
+
this.startedAt ??= Date.now();
|
|
95
|
+
if (!this.expanded) {
|
|
96
|
+
this.startAnimation();
|
|
97
|
+
}
|
|
98
|
+
}
|
|
53
99
|
/** The turn's tool run finished; the marker switches to its final form. */
|
|
54
100
|
markRunComplete() {
|
|
55
101
|
this.runComplete = true;
|
|
56
102
|
this.activeToolName = undefined;
|
|
103
|
+
this.activeToolComponent = undefined;
|
|
104
|
+
this.endedAt = Date.now();
|
|
105
|
+
this.stopAnimation();
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Reopen a completed group so a merged run continues in it (D-083 跨回合
|
|
109
|
+
* 合并): back to the running form, wall clock kept accumulating.
|
|
110
|
+
*/
|
|
111
|
+
reopen() {
|
|
112
|
+
this.runComplete = false;
|
|
113
|
+
this.endedAt = undefined;
|
|
114
|
+
if (!this.expanded) {
|
|
115
|
+
this.startAnimation();
|
|
116
|
+
}
|
|
57
117
|
}
|
|
58
118
|
// Not an override: Container declares no setExpanded; the Expandable
|
|
59
119
|
// interface (interactive-dialog-ui.ts) matches structurally.
|
|
@@ -68,6 +128,14 @@ export class ToolRunGroupComponent extends Container {
|
|
|
68
128
|
for (const tool of this.tools) {
|
|
69
129
|
tool.setExpanded(expanded);
|
|
70
130
|
}
|
|
131
|
+
// Detail mode keeps the marker (and its spinner) off screen: the
|
|
132
|
+
// animation stops and restarts when the group collapses unfinished.
|
|
133
|
+
if (expanded) {
|
|
134
|
+
this.stopAnimation();
|
|
135
|
+
}
|
|
136
|
+
else if (!this.runComplete && this.startedAt !== undefined) {
|
|
137
|
+
this.startAnimation();
|
|
138
|
+
}
|
|
71
139
|
}
|
|
72
140
|
invalidate() {
|
|
73
141
|
super.invalidate();
|
|
@@ -76,7 +144,13 @@ export class ToolRunGroupComponent extends Container {
|
|
|
76
144
|
if (this.expanded) {
|
|
77
145
|
return super.render(width);
|
|
78
146
|
}
|
|
79
|
-
const lines = [...this.spacer.render(width), this.markerLine()];
|
|
147
|
+
const lines = [...this.spacer.render(width), this.markerLine(width)];
|
|
148
|
+
// Live output (D-083 运行态): while the run executes, the active
|
|
149
|
+
// tool's output tail rides under the marker; it disappears again the
|
|
150
|
+
// moment the run seals.
|
|
151
|
+
if (!this.runComplete && this.activeToolComponent) {
|
|
152
|
+
lines.push(...this.activeToolComponent.renderQuietLiveOutput(width, LIVE_PREVIEW_LINES));
|
|
153
|
+
}
|
|
80
154
|
const failure = this.firstErrorSummary(width);
|
|
81
155
|
if (failure) {
|
|
82
156
|
lines.push(failure);
|
|
@@ -86,6 +160,20 @@ export class ToolRunGroupComponent extends Container {
|
|
|
86
160
|
}
|
|
87
161
|
return lines;
|
|
88
162
|
}
|
|
163
|
+
startAnimation() {
|
|
164
|
+
this.stopAnimation();
|
|
165
|
+
this.intervalId = setInterval(() => {
|
|
166
|
+
this.frameIndex = (this.frameIndex + 1) % SPINNER_FRAMES.length;
|
|
167
|
+
this.invalidate();
|
|
168
|
+
this.ui.requestRender();
|
|
169
|
+
}, SPINNER_INTERVAL_MS);
|
|
170
|
+
}
|
|
171
|
+
stopAnimation() {
|
|
172
|
+
if (this.intervalId !== undefined) {
|
|
173
|
+
clearInterval(this.intervalId);
|
|
174
|
+
this.intervalId = undefined;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
89
177
|
/**
|
|
90
178
|
* First failing tool's first output line, indented under the marker and
|
|
91
179
|
* cut to width (D-083 增补:失败内容可见,不用全局展开找一条错误).
|
|
@@ -99,13 +187,37 @@ export class ToolRunGroupComponent extends Container {
|
|
|
99
187
|
}
|
|
100
188
|
return undefined;
|
|
101
189
|
}
|
|
102
|
-
markerLine() {
|
|
190
|
+
markerLine(width) {
|
|
103
191
|
const label = this.markerLabel();
|
|
104
|
-
let line = theme.fg("muted",
|
|
192
|
+
let line = theme.fg("muted", `${this.markerPrefix()} ${label}`);
|
|
193
|
+
const timing = this.markerTiming();
|
|
194
|
+
if (timing !== undefined) {
|
|
195
|
+
line += ` ${theme.fg("muted", timing)}`;
|
|
196
|
+
}
|
|
105
197
|
if (this.failedCount > 0) {
|
|
106
198
|
line += ` ${theme.fg("error", `· ${t("{count} failed", { count: this.failedCount })}`)}`;
|
|
107
199
|
}
|
|
108
|
-
|
|
200
|
+
// The marker packs label + duration + failure count: long tool names
|
|
201
|
+
// (mcp__server__tool) overflow narrow terminals, and the main screen
|
|
202
|
+
// throws on overwide lines. Same ANSI-aware cut as firstErrorSummary.
|
|
203
|
+
return truncateToWidth(line, Math.max(width, 1), "...");
|
|
204
|
+
}
|
|
205
|
+
/** Spinner frame while a tool executes, the quiet dot otherwise. */
|
|
206
|
+
markerPrefix() {
|
|
207
|
+
if (!this.runComplete && this.activeToolName !== undefined) {
|
|
208
|
+
return SPINNER_FRAMES[this.frameIndex];
|
|
209
|
+
}
|
|
210
|
+
return "●";
|
|
211
|
+
}
|
|
212
|
+
/** Live elapsed while running; frozen group wall-clock duration once complete. */
|
|
213
|
+
markerTiming() {
|
|
214
|
+
if (this.startedAt === undefined) {
|
|
215
|
+
return undefined;
|
|
216
|
+
}
|
|
217
|
+
if (!this.runComplete) {
|
|
218
|
+
return formatDuration(Date.now() - this.startedAt);
|
|
219
|
+
}
|
|
220
|
+
return this.endedAt !== undefined ? formatDuration(this.endedAt - this.startedAt) : undefined;
|
|
109
221
|
}
|
|
110
222
|
markerLabel() {
|
|
111
223
|
if (!this.runComplete && this.activeToolName !== undefined) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool-run-group.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/tool-run-group.ts"],"names":[],"mappings":"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","sourcesContent":["import { Container, Spacer, truncateToWidth } from \"@agent-forge/tui\";\nimport { t } from \"../../../core/i18n/index.ts\";\nimport { theme } from \"../../../theme/theme.ts\";\nimport type { ToolExecutionComponent } from \"./tool-execution.ts\";\n\n/**\n * Quiet-transcript group for one assistant turn's tool calls (D-083,\n * docs/design/终端输出模式设计.md §3). Collapsed (quiet, the default) it\n * renders a single dim marker line — running tool name while executing, the\n * tool count (or the sole tool's name) once complete, plus an error-colored\n * failure count that never goes silent — followed by the first failing\n * result's first output line and every result image (D-083 增补: the error\n * text and screenshots are user-visible conclusions, not process noise).\n * Expanded (detail, ctrl+o) it renders every child tool component in its\n * expanded form.\n *\n * Collapsed render never renders the child text cards, so no per-tool card,\n * kv arg line, or result preview leaks into the quiet transcript.\n */\nexport class ToolRunGroupComponent extends Container {\n\tprivate tools: ToolExecutionComponent[] = [];\n\tprivate spacer = new Spacer(1);\n\tprivate expanded = false;\n\tprivate activeToolName: string | undefined;\n\tprivate lastToolName: string | undefined;\n\tprivate failedCount = 0;\n\tprivate runComplete = false;\n\n\tconstructor() {\n\t\tsuper();\n\t\t// Same transcript rhythm as a directly-mounted ToolExecutionComponent\n\t\t// (which leads with its own Spacer(1)): one blank line before the\n\t\t// marker line in quiet mode, before the child cards in detail mode.\n\t\tthis.addChild(this.spacer);\n\t}\n\n\taddTool(component: ToolExecutionComponent): void {\n\t\tthis.tools.push(component);\n\t\t// Seed the name so the sole-tool marker form survives the restore path,\n\t\t// which never sees a tool_execution_start (no setActiveTool call).\n\t\tthis.lastToolName = component.name;\n\t\tthis.addChild(component);\n\t}\n\n\t/** Current executing tool name (tool_execution_start); clears on completion. */\n\tsetActiveTool(name: string | undefined): void {\n\t\tthis.activeToolName = name;\n\t\tif (name !== undefined) {\n\t\t\tthis.lastToolName = name;\n\t\t}\n\t}\n\n\t/** Count a finished tool result; errors keep the failure count visible. */\n\tnoteResult(isError: boolean): void {\n\t\tif (isError) {\n\t\t\tthis.failedCount += 1;\n\t\t}\n\t}\n\n\t/** The turn's tool run finished; the marker switches to its final form. */\n\tmarkRunComplete(): void {\n\t\tthis.runComplete = true;\n\t\tthis.activeToolName = undefined;\n\t}\n\n\t// Not an override: Container declares no setExpanded; the Expandable\n\t// interface (interactive-dialog-ui.ts) matches structurally.\n\tsetExpanded(expanded: boolean): void {\n\t\tif (expanded === this.expanded) {\n\t\t\treturn;\n\t\t}\n\t\tthis.expanded = expanded;\n\t\t// Detail mode renders the children as full cards: propagate to every\n\t\t// child so an entire group flips with one ctrl+o press (the\n\t\t// setToolsExpanded loop only reaches this group component).\n\t\tfor (const tool of this.tools) {\n\t\t\ttool.setExpanded(expanded);\n\t\t}\n\t}\n\n\toverride invalidate(): void {\n\t\tsuper.invalidate();\n\t}\n\n\toverride render(width: number): string[] {\n\t\tif (this.expanded) {\n\t\t\treturn super.render(width);\n\t\t}\n\t\tconst lines = [...this.spacer.render(width), this.markerLine()];\n\t\tconst failure = this.firstErrorSummary(width);\n\t\tif (failure) {\n\t\t\tlines.push(failure);\n\t\t}\n\t\tfor (const tool of this.tools) {\n\t\t\tlines.push(...tool.renderQuietImages(width));\n\t\t}\n\t\treturn lines;\n\t}\n\n\t/**\n\t * First failing tool's first output line, indented under the marker and\n\t * cut to width (D-083 增补:失败内容可见,不用全局展开找一条错误).\n\t */\n\tprivate firstErrorSummary(width: number): string | undefined {\n\t\tfor (const tool of this.tools) {\n\t\t\tconst summary = tool.errorSummary;\n\t\t\tif (summary !== undefined) {\n\t\t\t\treturn ` ${theme.fg(\"error\", truncateToWidth(summary, Math.max(width - 1, 1), \"...\"))}`;\n\t\t\t}\n\t\t}\n\t\treturn undefined;\n\t}\n\n\tprivate markerLine(): string {\n\t\tconst label = this.markerLabel();\n\t\tlet line = theme.fg(\"muted\", `⏺ ${label}`);\n\t\tif (this.failedCount > 0) {\n\t\t\tline += ` ${theme.fg(\"error\", `· ${t(\"{count} failed\", { count: this.failedCount })}`)}`;\n\t\t}\n\t\treturn line;\n\t}\n\n\tprivate markerLabel(): string {\n\t\tif (!this.runComplete && this.activeToolName !== undefined) {\n\t\t\treturn this.activeToolName;\n\t\t}\n\t\tif (this.runComplete && this.tools.length === 1 && this.lastToolName !== undefined) {\n\t\t\treturn this.lastToolName;\n\t\t}\n\t\tconst count = this.tools.length;\n\t\treturn t(count === 1 ? \"{count} tool\" : \"{count} tools\", { count });\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"tool-run-group.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/tool-run-group.ts"],"names":[],"mappings":"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","sourcesContent":["import { Container, Spacer, type TUI, truncateToWidth } from \"@agent-forge/tui\";\nimport { t } from \"../../../core/i18n/index.ts\";\nimport { theme } from \"../../../theme/theme.ts\";\nimport type { ToolExecutionComponent } from \"./tool-execution.ts\";\n\n/** Braille spinner frames for the running marker (same set as the TUI loader). */\nconst SPINNER_FRAMES = [\"⠋\", \"⠙\", \"⠹\", \"⠸\", \"⠼\", \"⠴\", \"⠦\", \"⠧\", \"⠇\", \"⠏\"];\nconst SPINNER_INTERVAL_MS = 120;\n\n/** Collapsed running-state preview: tail lines of the active tool's live output. */\nconst LIVE_PREVIEW_LINES = 8;\n\n/**\n * bash-style group wall-clock rendering: 5.2s under a minute, 2m 3s under an\n * hour, 1h 2m 3s beyond.\n */\nfunction formatDuration(ms: number): string {\n\tconst totalSeconds = Math.floor(ms / 1000);\n\tconst hours = Math.floor(totalSeconds / 3600);\n\tconst minutes = Math.floor((totalSeconds % 3600) / 60);\n\tconst seconds = totalSeconds % 60;\n\tif (hours > 0) return `${hours}h ${minutes}m ${seconds}s`;\n\tif (minutes > 0) return `${minutes}m ${seconds}s`;\n\treturn `${(ms / 1000).toFixed(1)}s`;\n}\n\n/**\n * Quiet-transcript group for one assistant turn's tool calls (D-083,\n * docs/design/终端输出模式设计.md §3). Collapsed (quiet, the default) it\n * renders a single dim marker line — a braille spinner with the running tool\n * name and live elapsed seconds while executing, the quiet ● dot with the tool\n * count (or the sole tool's name) plus the group wall-clock duration once\n * complete, plus an error-colored failure count that never goes silent —\n * followed by the tail of the active tool's live output while running, the\n * first failing result's first output line and every result image (D-083 增补:\n * the error text and screenshots are user-visible conclusions, not process\n * noise). Expanded (detail, ctrl+o) it renders every child tool component in\n * its expanded form.\n *\n * The wall clock is live-path only (startClock on tool_execution_start):\n * groups restored from a session carry no timing data and stay timeless.\n * Completed groups reopen (adjacent assistant messages with no visible\n * content in between) and keep accumulating the same clock.\n *\n * Collapsed render never renders the child text cards, so no per-tool card,\n * kv arg line, or result preview leaks into the quiet transcript.\n */\nexport class ToolRunGroupComponent extends Container {\n\tprivate tools: ToolExecutionComponent[] = [];\n\tprivate spacer = new Spacer(1);\n\tprivate expanded = false;\n\tprivate activeToolName: string | undefined;\n\tprivate activeToolComponent: ToolExecutionComponent | undefined;\n\tprivate lastToolName: string | undefined;\n\tprivate failedCount = 0;\n\tprivate runComplete = false;\n\tprivate startedAt: number | undefined;\n\tprivate endedAt: number | undefined;\n\tprivate frameIndex = 0;\n\tprivate intervalId: NodeJS.Timeout | undefined;\n\tprivate ui: TUI;\n\n\tconstructor(ui: TUI) {\n\t\tsuper();\n\t\tthis.ui = ui;\n\t\t// Same transcript rhythm as a directly-mounted ToolExecutionComponent\n\t\t// (which leads with its own Spacer(1)): one blank line before the\n\t\t// marker line in quiet mode, before the child cards in detail mode.\n\t\tthis.addChild(this.spacer);\n\t}\n\n\taddTool(component: ToolExecutionComponent): void {\n\t\tthis.tools.push(component);\n\t\t// Seed the name so the sole-tool marker form survives the restore path,\n\t\t// which never sees a tool_execution_start (no setActiveTool call).\n\t\tthis.lastToolName = component.name;\n\t\tthis.addChild(component);\n\t}\n\n\t/** Current executing tool (tool_execution_start); clears on completion. */\n\tsetActiveTool(name: string | undefined, component?: ToolExecutionComponent): void {\n\t\tthis.activeToolName = name;\n\t\tthis.activeToolComponent = name === undefined ? undefined : component;\n\t\tif (name !== undefined) {\n\t\t\tthis.lastToolName = name;\n\t\t}\n\t}\n\n\t/** Count a finished tool result; errors keep the failure count visible. */\n\tnoteResult(isError: boolean): void {\n\t\tif (isError) {\n\t\t\tthis.failedCount += 1;\n\t\t}\n\t}\n\n\t/**\n\t * Live wall clock (tool_execution_start): stamp the start once and spin the\n\t * running marker. Idempotent — later tools of the same run keep the\n\t * original start.\n\t */\n\tstartClock(): void {\n\t\tthis.startedAt ??= Date.now();\n\t\tif (!this.expanded) {\n\t\t\tthis.startAnimation();\n\t\t}\n\t}\n\n\t/** The turn's tool run finished; the marker switches to its final form. */\n\tmarkRunComplete(): void {\n\t\tthis.runComplete = true;\n\t\tthis.activeToolName = undefined;\n\t\tthis.activeToolComponent = undefined;\n\t\tthis.endedAt = Date.now();\n\t\tthis.stopAnimation();\n\t}\n\n\t/**\n\t * Reopen a completed group so a merged run continues in it (D-083 跨回合\n\t * 合并): back to the running form, wall clock kept accumulating.\n\t */\n\treopen(): void {\n\t\tthis.runComplete = false;\n\t\tthis.endedAt = undefined;\n\t\tif (!this.expanded) {\n\t\t\tthis.startAnimation();\n\t\t}\n\t}\n\n\t// Not an override: Container declares no setExpanded; the Expandable\n\t// interface (interactive-dialog-ui.ts) matches structurally.\n\tsetExpanded(expanded: boolean): void {\n\t\tif (expanded === this.expanded) {\n\t\t\treturn;\n\t\t}\n\t\tthis.expanded = expanded;\n\t\t// Detail mode renders the children as full cards: propagate to every\n\t\t// child so an entire group flips with one ctrl+o press (the\n\t\t// setToolsExpanded loop only reaches this group component).\n\t\tfor (const tool of this.tools) {\n\t\t\ttool.setExpanded(expanded);\n\t\t}\n\t\t// Detail mode keeps the marker (and its spinner) off screen: the\n\t\t// animation stops and restarts when the group collapses unfinished.\n\t\tif (expanded) {\n\t\t\tthis.stopAnimation();\n\t\t} else if (!this.runComplete && this.startedAt !== undefined) {\n\t\t\tthis.startAnimation();\n\t\t}\n\t}\n\n\toverride invalidate(): void {\n\t\tsuper.invalidate();\n\t}\n\n\toverride render(width: number): string[] {\n\t\tif (this.expanded) {\n\t\t\treturn super.render(width);\n\t\t}\n\t\tconst lines = [...this.spacer.render(width), this.markerLine(width)];\n\t\t// Live output (D-083 运行态): while the run executes, the active\n\t\t// tool's output tail rides under the marker; it disappears again the\n\t\t// moment the run seals.\n\t\tif (!this.runComplete && this.activeToolComponent) {\n\t\t\tlines.push(...this.activeToolComponent.renderQuietLiveOutput(width, LIVE_PREVIEW_LINES));\n\t\t}\n\t\tconst failure = this.firstErrorSummary(width);\n\t\tif (failure) {\n\t\t\tlines.push(failure);\n\t\t}\n\t\tfor (const tool of this.tools) {\n\t\t\tlines.push(...tool.renderQuietImages(width));\n\t\t}\n\t\treturn lines;\n\t}\n\n\tprivate startAnimation(): void {\n\t\tthis.stopAnimation();\n\t\tthis.intervalId = setInterval(() => {\n\t\t\tthis.frameIndex = (this.frameIndex + 1) % SPINNER_FRAMES.length;\n\t\t\tthis.invalidate();\n\t\t\tthis.ui.requestRender();\n\t\t}, SPINNER_INTERVAL_MS);\n\t}\n\n\tprivate stopAnimation(): void {\n\t\tif (this.intervalId !== undefined) {\n\t\t\tclearInterval(this.intervalId);\n\t\t\tthis.intervalId = undefined;\n\t\t}\n\t}\n\n\t/**\n\t * First failing tool's first output line, indented under the marker and\n\t * cut to width (D-083 增补:失败内容可见,不用全局展开找一条错误).\n\t */\n\tprivate firstErrorSummary(width: number): string | undefined {\n\t\tfor (const tool of this.tools) {\n\t\t\tconst summary = tool.errorSummary;\n\t\t\tif (summary !== undefined) {\n\t\t\t\treturn ` ${theme.fg(\"error\", truncateToWidth(summary, Math.max(width - 1, 1), \"...\"))}`;\n\t\t\t}\n\t\t}\n\t\treturn undefined;\n\t}\n\n\tprivate markerLine(width: number): string {\n\t\tconst label = this.markerLabel();\n\t\tlet line = theme.fg(\"muted\", `${this.markerPrefix()} ${label}`);\n\t\tconst timing = this.markerTiming();\n\t\tif (timing !== undefined) {\n\t\t\tline += ` ${theme.fg(\"muted\", timing)}`;\n\t\t}\n\t\tif (this.failedCount > 0) {\n\t\t\tline += ` ${theme.fg(\"error\", `· ${t(\"{count} failed\", { count: this.failedCount })}`)}`;\n\t\t}\n\t\t// The marker packs label + duration + failure count: long tool names\n\t\t// (mcp__server__tool) overflow narrow terminals, and the main screen\n\t\t// throws on overwide lines. Same ANSI-aware cut as firstErrorSummary.\n\t\treturn truncateToWidth(line, Math.max(width, 1), \"...\");\n\t}\n\n\t/** Spinner frame while a tool executes, the quiet dot otherwise. */\n\tprivate markerPrefix(): string {\n\t\tif (!this.runComplete && this.activeToolName !== undefined) {\n\t\t\treturn SPINNER_FRAMES[this.frameIndex];\n\t\t}\n\t\treturn \"●\";\n\t}\n\n\t/** Live elapsed while running; frozen group wall-clock duration once complete. */\n\tprivate markerTiming(): string | undefined {\n\t\tif (this.startedAt === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\t\tif (!this.runComplete) {\n\t\t\treturn formatDuration(Date.now() - this.startedAt);\n\t\t}\n\t\treturn this.endedAt !== undefined ? formatDuration(this.endedAt - this.startedAt) : undefined;\n\t}\n\n\tprivate markerLabel(): string {\n\t\tif (!this.runComplete && this.activeToolName !== undefined) {\n\t\t\treturn this.activeToolName;\n\t\t}\n\t\tif (this.runComplete && this.tools.length === 1 && this.lastToolName !== undefined) {\n\t\t\treturn this.lastToolName;\n\t\t}\n\t\tconst count = this.tools.length;\n\t\treturn t(count === 1 ? \"{count} tool\" : \"{count} tools\", { count });\n\t}\n}\n"]}
|