#17297: fix(tui): copy-paste inserts spaces into long tokens at wrap points (#17282 #17278)
stale
size: S
trusted-contributor
Cluster:
Model Reasoning Fixes
## Summary
Copying long paths or URLs from TUI output inserted extra spaces at every 32 characters, breaking pasted commands and file paths.
Closes #17282
#17278
lobster-biscuit
## Root Cause
`normalizeLongTokenForDisplay` in `tui-formatters.ts` chunks any non-whitespace token longer than 32 chars. For non-"copy-sensitive" tokens it joins the pieces with a literal space (`.join(" ")`), which mutates the actual text buffer so copy-paste grabs the corrupted version.
The existing `isCopySensitiveToken` heuristic tried to detect paths/URLs and skip chunking for those, but it can miss edge cases (base64 strings, encoded tokens, unusual path formats, etc.).
## Fix
Changed `normalizeLongTokenForDisplay` to always `.join("")` (empty string). This makes the chunking a no-op for the text buffer: long tokens pass through `chunkToken` but are reassembled unchanged. The text buffer stays byte-identical for copy operations.
This also removes the now-unnecessary `isCopySensitiveToken` heuristic and its associated regex constants (`URL_PREFIX_RE`, `WINDOWS_DRIVE_RE`, `FILE_LIKE_RE`), since all long tokens are now preserved verbatim.
Modern terminals handle long lines gracefully — they wrap at the terminal edge naturally, so explicit break hints are unnecessary.
- Before: `/Users/pia/.openclaw/workspace/s kills/briefing/Briefing-Agenda.m d`
- After: `/Users/pia/.openclaw/workspace/skills/briefing/Briefing-Agenda.md`
URLs and file paths now copy correctly and work when pasted into browsers and terminals.
## Tests
- `tui-formatters.test.ts` — 24 tests total (12 in `sanitizeRenderableText` block):
- Long tokens pass through unchanged (the issue repro)
- Moderately long tokens preserved
- Long filesystem paths preserved verbatim
- Long URLs preserved verbatim
- Long file-like underscore tokens preserved
- Idempotent: calling twice produces the same result
- Short tokens pass through untouched
- Mixed content: spaces between normal words preserved alongside long tokens
- ANSI stripping, control char stripping, binary redaction, empty string
- All tests pass
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
This PR fixes a copy-paste bug where long tokens (paths, URLs) had spaces inserted every 32 characters, breaking pasted commands. The fix changes `normalizeLongTokenForDisplay` to join chunks with empty string instead of space, making long tokens pass through unchanged and preserving copy-paste integrity.
The implementation is correct and solves the reported issue. Tests are comprehensive, covering the bug reproduction case, idempotency, and various edge cases (paths, URLs, mixed content, ANSI stripping, binary redaction).
Minor simplification opportunity: since `chunkToken(token, MAX_TOKEN_CHARS).join("")` is now a no-op that returns the input unchanged, the function could be simplified to `return token;` and potentially the `chunkToken` helper could be removed entirely as it's no longer used meaningfully.
<h3>Confidence Score: 5/5</h3>
- Safe to merge — fixes a real bug without introducing regressions
- The fix correctly solves the copy-paste corruption issue by preserving long tokens unchanged. Comprehensive test coverage validates the fix and guards against regressions. The implementation is simple and doesn't introduce new edge cases.
- No files require special attention
<sub>Last reviewed commit: ed2b9f4</sub>
<!-- greptile_other_comments_section -->
<!-- /greptile_comment -->
Most Similar PRs
#20516: fix(tui): preserve streamed text on finalize for pure text responses
by MisterGuy420 · 2026-02-19
75.6%
#17777: fix(tui): prevent URL breaking during line wrap
by proto-genesys-x · 2026-02-16
75.3%
#17814: fix(tui): add OSC 8 hyperlinks for wrapped URLs
by Phineas1500 · 2026-02-16
73.7%
#16733: fix(ui): avoid injected newlines when tool output is hidden
by jp117 · 2026-02-15
73.7%
#17686: fix(memory): support non-ASCII characters in FTS query tokenization
by Phineas1500 · 2026-02-16
73.3%
#6260: fix(tui): prevent width overflow crashes from nested ANSI escape codes
by 0xktn · 2026-02-01
73.3%
#10093: fix: import gateway token from URL param into localStorage
by devjiro76 · 2026-02-06
73.1%
#21110: fix(tts): deliver audio via structured mediaUrl instead of MEDIA: t...
by hydro13 · 2026-02-19
72.9%
#19885: test(gateway,browser): isolate tests from ambient OPENCLAW_GATEWAY_...
by NewdlDewdl · 2026-02-18
72.4%
#18273: fix: extract token from URL query string for Control UI websocket auth
by MisterGuy420 · 2026-02-16
72.2%