diff --git a/packages/coding-agent/src/modes/interactive-mode.ts b/packages/coding-agent/src/modes/interactive-mode.ts index 5a271f936..e69c1ca9a 100644 --- a/packages/coding-agent/src/modes/interactive-mode.ts +++ b/packages/coding-agent/src/modes/interactive-mode.ts @@ -644,7 +644,7 @@ export class InteractiveMode implements InteractiveModeContext { // unless the user opts in, and never emits raw escapes on other terminals. setTerminalTextSizing(settings.get("tui.textSizing") && TERMINAL.textSizing); this.chatContainer = new TranscriptContainer(); - this.pendingMessagesContainer = new Container(); + this.pendingMessagesContainer = new AnchoredLiveContainer(); this.statusContainer = new AnchoredLiveContainer(); this.todoContainer = new AnchoredLiveContainer(); this.subagentContainer = new AnchoredLiveContainer(); diff --git a/packages/coding-agent/test/interactive-mode-plan-review.test.ts b/packages/coding-agent/test/interactive-mode-plan-review.test.ts index 0b91c96e5..7efce822d 100644 --- a/packages/coding-agent/test/interactive-mode-plan-review.test.ts +++ b/packages/coding-agent/test/interactive-mode-plan-review.test.ts @@ -18,7 +18,7 @@ import { AuthStorage } from "@oh-my-pi/pi-coding-agent/session/auth-storage"; import { SILENT_ABORT_MARKER, USER_INTERRUPT_LABEL } from "@oh-my-pi/pi-coding-agent/session/messages"; import { SessionManager } from "@oh-my-pi/pi-coding-agent/session/session-manager"; import { AUTO_THINKING } from "@oh-my-pi/pi-coding-agent/thinking"; -import { setKeybindings } from "@oh-my-pi/pi-tui"; +import { setKeybindings, Text } from "@oh-my-pi/pi-tui"; import { formatNumber, TempDir } from "@oh-my-pi/pi-utils"; /** @@ -131,6 +131,16 @@ describe("InteractiveMode plan review rendering", () => { resetSettingsForTest(); }); + it("keeps queued-message rows in the live region instead of native scrollback", () => { + const liveRegion = mode.pendingMessagesContainer as { + getNativeScrollbackLiveRegionStart?: () => number | undefined; + }; + + expect(liveRegion.getNativeScrollbackLiveRegionStart?.()).toBeUndefined(); + mode.pendingMessagesContainer.addChild(new Text("Queued: follow-up")); + expect(liveRegion.getNativeScrollbackLiveRegionStart?.()).toBe(0); + }); + it("exits empty plan mode without confirmation", async () => { const planFilePath = "local://PLAN.md"; const resolvedPlanPath = resolveLocalUrlToPath(planFilePath, {