From daaabbeac5bb822ba48e9d164307081f6fcc6cbb Mon Sep 17 00:00:00 2001 From: Mario Zechner Date: Thu, 5 Mar 2026 22:35:03 +0100 Subject: [PATCH] fix(coding-agent): normalize CRLF in write preview rendering (fixes #1854) --- .../interactive/components/tool-execution.ts | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/packages/coding-agent/src/modes/interactive/components/tool-execution.ts b/packages/coding-agent/src/modes/interactive/components/tool-execution.ts index 8633b81c..bf282ad2 100644 --- a/packages/coding-agent/src/modes/interactive/components/tool-execution.ts +++ b/packages/coding-agent/src/modes/interactive/components/tool-execution.ts @@ -48,6 +48,14 @@ function replaceTabs(text: string): string { return text.replace(/\t/g, " "); } +/** + * Normalize control characters for terminal preview rendering. + * Keep tool arguments unchanged, sanitize only display text. + */ +function normalizeDisplayText(text: string): string { + return text.replace(/\r/g, ""); +} + /** Safely coerce value to string for display. Returns null if invalid type. */ function str(value: unknown): string | null { if (typeof value === "string") return value; @@ -174,7 +182,8 @@ export class ToolExecutionComponent extends Container { return; } - const normalized = replaceTabs(fileContent); + const displayContent = normalizeDisplayText(fileContent); + const normalized = replaceTabs(displayContent); this.writeHighlightCache = { rawPath, lang, @@ -219,7 +228,8 @@ export class ToolExecutionComponent extends Container { } const deltaRaw = fileContent.slice(cache.rawContent.length); - const deltaNormalized = replaceTabs(deltaRaw); + const deltaDisplay = normalizeDisplayText(deltaRaw); + const deltaNormalized = replaceTabs(deltaDisplay); cache.rawContent = fileContent; if (cache.normalizedLines.length === 0) { @@ -686,7 +696,8 @@ export class ToolExecutionComponent extends Container { if (cache && cache.lang === lang && cache.rawPath === rawPath && cache.rawContent === fileContent) { lines = cache.highlightedLines; } else { - const normalized = replaceTabs(fileContent); + const displayContent = normalizeDisplayText(fileContent); + const normalized = replaceTabs(displayContent); lines = highlightCode(normalized, lang); this.writeHighlightCache = { rawPath, @@ -697,7 +708,7 @@ export class ToolExecutionComponent extends Container { }; } } else { - lines = fileContent.split("\n"); + lines = normalizeDisplayText(fileContent).split("\n"); this.writeHighlightCache = undefined; }