From ea78e346d03dc8a1852ecebdc9a0e7d9e2aceabf Mon Sep 17 00:00:00 2001 From: roboomp Date: Fri, 17 Jul 2026 13:11:52 +0000 Subject: [PATCH] fix(tui): dropped stale hidden-lines footer on expanded output MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Expanded `!` bash and `eval` execution output kept rendering the `… N more lines (ctrl+o to expand)` footer after Ctrl+O revealed every line, because `hiddenLineCount` was computed from the collapsed preview window regardless of the `#expanded` (or sixel-passthrough) state. Zero the hidden count whenever the full output is shown so `buildStatusFooter()` stops advertising hidden lines and ctrl+o. Fixes #5842 --- packages/coding-agent/CHANGELOG.md | 4 ++ .../src/modes/components/bash-execution.ts | 10 +++-- .../src/modes/components/eval-execution.ts | 4 +- .../test/bash-execution-sixel.test.ts | 44 +++++++++++++++++++ 4 files changed, 58 insertions(+), 4 deletions(-) diff --git a/packages/coding-agent/CHANGELOG.md b/packages/coding-agent/CHANGELOG.md index 493bd5332..ad08354ad 100644 --- a/packages/coding-agent/CHANGELOG.md +++ b/packages/coding-agent/CHANGELOG.md @@ -2,6 +2,10 @@ ## [Unreleased] +### Fixed + +- Fixed expanded `!` bash and `eval` output keeping a stale `… N more lines (ctrl+o to expand)` footer after Ctrl+O revealed every line ([#5842](https://github.com/can1357/oh-my-pi/issues/5842)). + ## [17.0.2] - 2026-07-17 ### Added diff --git a/packages/coding-agent/src/modes/components/bash-execution.ts b/packages/coding-agent/src/modes/components/bash-execution.ts index b17300cb2..05c7d437d 100644 --- a/packages/coding-agent/src/modes/components/bash-execution.ts +++ b/packages/coding-agent/src/modes/components/bash-execution.ts @@ -146,14 +146,18 @@ export class BashExecutionComponent extends Container { #updateDisplay(): void { const availableLines = this.#outputLines; - // Apply preview truncation based on expanded state + // Full output is shown when expanded or when sixel passthrough renders + // the raw payload; the collapsed preview shows only the tail window. const previewLogicalLines = availableLines.slice(-PREVIEW_LINES); - const hiddenLineCount = availableLines.length - previewLogicalLines.length; const sixelLineMask = TERMINAL.imageProtocol === ImageProtocol.Sixel && isSixelPassthroughEnabled() ? getSixelLineMask(availableLines) : undefined; const hasSixelOutput = sixelLineMask?.some(Boolean) ?? false; + const showingAllLines = this.#expanded || hasSixelOutput; + // Only the collapsed preview hides lines; when the full output is shown + // the footer must not keep advertising hidden lines / ctrl+o. + const hiddenLineCount = showingAllLines ? 0 : availableLines.length - previewLogicalLines.length; // Rebuild content container this.#contentContainer.clear(); @@ -163,7 +167,7 @@ export class BashExecutionComponent extends Container { // Output if (availableLines.length > 0) { - if (this.#expanded || hasSixelOutput) { + if (showingAllLines) { const displayText = availableLines .map((line, index) => (sixelLineMask?.[index] ? line : theme.fg("muted", line))) .join("\n"); diff --git a/packages/coding-agent/src/modes/components/eval-execution.ts b/packages/coding-agent/src/modes/components/eval-execution.ts index fd6084a9e..53050a81f 100644 --- a/packages/coding-agent/src/modes/components/eval-execution.ts +++ b/packages/coding-agent/src/modes/components/eval-execution.ts @@ -114,7 +114,9 @@ export class EvalExecutionComponent extends Container { #updateDisplay(): void { const availableLines = this.#outputLines; const previewLogicalLines = availableLines.slice(-PREVIEW_LINES); - const hiddenLineCount = availableLines.length - previewLogicalLines.length; + // Only the collapsed preview hides lines; when expanded the footer must + // not keep advertising hidden lines / ctrl+o. + const hiddenLineCount = this.#expanded ? 0 : availableLines.length - previewLogicalLines.length; this.#contentContainer.clear(); diff --git a/packages/coding-agent/test/bash-execution-sixel.test.ts b/packages/coding-agent/test/bash-execution-sixel.test.ts index 082fd07da..9a3a86fa7 100644 --- a/packages/coding-agent/test/bash-execution-sixel.test.ts +++ b/packages/coding-agent/test/bash-execution-sixel.test.ts @@ -141,3 +141,47 @@ describe("BashExecutionComponent streaming throttle", () => { expect(output).not.toContain("streaming_line"); }); }); + +describe("BashExecutionComponent expand footer", () => { + const ui = { requestRender: () => {}, requestComponentRender: () => {} } as unknown as TUI; + + beforeEach(async () => { + const theme = await getThemeByName("dark"); + expect(theme).toBeDefined(); + setThemeInstance(theme!); + }); + + // PREVIEW_LINES is 20: 27 lines leaves 7 hidden in the collapsed preview. + const makeComponent = () => { + const component = new BashExecutionComponent("ls", ui, false); + const lines = Array.from({ length: 27 }, (_, i) => `entry${i}`); + component.setComplete(0, false, { output: lines.join("\n") }); + return component; + }; + + it("advertises hidden lines while collapsed", () => { + const rendered = makeComponent().render(120).join("\n"); + expect(rendered).toContain("more lines"); + expect(rendered).toContain("ctrl+o to expand"); + }); + + it("drops the hidden-lines footer once expanded", () => { + const component = makeComponent(); + component.setExpanded(true); + const rendered = component.render(120).join("\n"); + expect(rendered).not.toContain("more lines"); + expect(rendered).not.toContain("ctrl+o to expand"); + // Every line is now present, including the previously hidden prefix. + expect(rendered).toContain("entry0"); + expect(rendered).toContain("entry26"); + }); + + it("restores the footer when collapsed again", () => { + const component = makeComponent(); + component.setExpanded(true); + component.setExpanded(false); + const rendered = component.render(120).join("\n"); + expect(rendered).toContain("more lines"); + expect(rendered).toContain("ctrl+o to expand"); + }); +});