From eb225ba99118556324881f9c84a7c6d7e486fd17 Mon Sep 17 00:00:00 2001 From: Kit Langton Date: Fri, 7 Aug 2026 12:02:12 -0400 Subject: [PATCH 1/2] fix(tui): align running shell output (#41101) --- packages/tui/src/routes/session/index.tsx | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/packages/tui/src/routes/session/index.tsx b/packages/tui/src/routes/session/index.tsx index c9eb7ed5fa13..0e450ab5fcd4 100644 --- a/packages/tui/src/routes/session/index.tsx +++ b/packages/tui/src/routes/session/index.tsx @@ -2830,6 +2830,8 @@ function Shell(props: ToolProps) { if (expanded() || !collapsed().overflow) return content() return collapsed().output }) + const limitedInput = createMemo(() => limited().slice(0, input().length)) + const limitedOutput = createMemo(() => limited().slice(Math.min(limited().length, input().length + 2))) const expandable = createMemo(() => Boolean(shellID()) || collapsed().overflow) const toggle = () => { const next = !expanded() @@ -2854,15 +2856,15 @@ function Shell(props: ToolProps) { when={isRunning()} fallback={ - {limited().slice(0, input().length)} + {limitedInput()} {limited().slice(input().length)} } > - - {limited().slice(0, input().length)} - {limited().slice(input().length)} - + {limitedInput()} + + {limitedOutput()} + From 380c17d77fbdb2167ed51bc72a11d082eb807a73 Mon Sep 17 00:00:00 2001 From: Kit Langton Date: Tue, 11 Aug 2026 20:27:46 -0400 Subject: [PATCH 2/2] fix(tui): keep wrapped shell command aligned --- packages/tui/src/routes/session/index.tsx | 25 ++++++++++++++--------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/packages/tui/src/routes/session/index.tsx b/packages/tui/src/routes/session/index.tsx index 0e450ab5fcd4..67f727a9c87c 100644 --- a/packages/tui/src/routes/session/index.tsx +++ b/packages/tui/src/routes/session/index.tsx @@ -2819,10 +2819,15 @@ function Shell(props: ToolProps) { }) const maxLines = 10 const maxChars = createMemo(() => maxLines * Math.max(20, ctx.width - 6)) + const prompt = createMemo(() => (workdir() && workdir() !== "." ? `${workdir()}$` : "$")) const input = createMemo(() => { - if (!command()) return "" - const prompt = workdir() && workdir() !== "." ? `${workdir()}$ ` : isRunning() ? "" : "$ " - return `${prompt}${command()}` + const cmd = command() + if (!cmd) return "" + // While running, the workdir prompt shares the spinner's text column; when + // settled, the prompt renders as its own column so wrapped command lines + // keep a stable hanging indent instead of jumping to the card inset. + if (isRunning() && prompt() !== "$") return `${prompt()} ${cmd}` + return cmd }) const content = createMemo(() => [input(), output()].filter(Boolean).join("\n\n")) const collapsed = createMemo(() => collapseToolOutput(content(), maxLines, maxChars())) @@ -2855,16 +2860,16 @@ function Shell(props: ToolProps) { - {limitedInput()} - {limited().slice(input().length)} - + + {prompt()} + {limitedInput()} + } > {limitedInput()} - - {limitedOutput()} - + + + {limitedOutput()}