Skip to content

fix(coding/tui): keep the cached tool preview read-only while rendering - #35

Merged
rsbin1178 merged 1 commit into
mainfrom
fix/tui-tool-preview-row-mutation
Oct 8, 2026
Merged

rsbin1178 merged 1 commit into
mainfrom
fix/tui-tool-preview-row-mutation

Conversation

@rsbin1178

Copy link
Copy Markdown
Owner

A compact tool block renders its rows by prefixing and styling each line, and the
rows it was handed were the activity's own preview slice. Writing them back meant
every re-render added another branch prefix and left the previous render's colour
escapes inside the text, so switching the theme during a session grew a run of └
markers in front of the same diff line. The tone lookup made it worse: it reads the
leading characters of the row to tell an added line from a removed one, and a row
that starts with an escape fell through to the muted tone, which is why the - and +
colours stopped following the theme after the first re-render.

toolActivityRows now documents that the caller owns its result and clones a preview
before returning it, so the cached activity stays input. The regression test renders
one patch under the dark theme and then the light one: it asserts the activity is
unchanged, that exactly one branch prefix is applied per render, and that each render
carries its own theme's error and added tones with none of the other theme's escapes.

Evidence

Before the fix, two renders of one patch under two themes left the activity holding �[38;2;139;148;158m └ - (13, 13), (31, 61),�[m and then �[38;2;87;96;106m └ �[38;2;139;148;158m └ - ... — one branch prefix per render, with the first theme's escapes inside the second theme's output.

After: the activity is byte-identical across renders, one prefix per render, and the dark and light renders each carry their own error and idle tones.

TERM=xterm-256color go test ./... (89 packages), go test -race ./internal/coding/tui/, the three golden digests and golangci-lint run --new-from-rev=HEAD~ ./... (0 issues) are all clean.

A compact tool block renders its rows by prefixing and styling each line, and the
rows it was handed were the activity's own preview slice. Writing them back meant
every re-render added another branch prefix and left the previous render's colour
escapes inside the text, so switching the theme during a session grew a run of └
markers in front of the same diff line. The tone lookup made it worse: it reads the
leading characters of the row to tell an added line from a removed one, and a row
that starts with an escape fell through to the muted tone, which is why the - and +
colours stopped following the theme after the first re-render.

toolActivityRows now documents that the caller owns its result and clones a preview
before returning it, so the cached activity stays input. The regression test renders
one patch under the dark theme and then the light one: it asserts the activity is
unchanged, that exactly one branch prefix is applied per render, and that each render
carries its own theme's error and added tones with none of the other theme's escapes.
@rsbin1178
rsbin1178 merged commit a1db48a into main Oct 8, 2026
4 checks passed
@rsbin1178
rsbin1178 deleted the fix/tui-tool-preview-row-mutation branch October 8, 2026 14:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant