fix: keep long tokens in wrapping <pre> blocks on screen (#5820) - #5998
Merged
Conversation
The app shell clips horizontal overflow rather than scrolling it, and `whitespace-pre-wrap` only wraps at whitespace — so a log line, JSON dump, prompt, or wiki body containing one unbroken token (a path, a URL, a base64 blob, a stack frame) ran past the clip edge with no scrollbar to recover it. Adds a break class to the 35 remaining `<pre>` blocks that wrapped but could not break, following the split established in #5675: machine output (server logs, install logs, command output, JSON dumps, error traces, agent transcripts) gets `break-all`, while human-authored prose (prompt templates, treatments, bios, user stories, soul documents, wiki bodies) gets `break-words`, which only breaks a word that cannot fit on a line of its own. A new tree-wide guard, `client/src/preWrapClasses.test.js`, fails when any non-test `<pre>` carries `whitespace-pre-wrap` without a break class, so blocks added later are covered too. It reads each opening tag whole rather than line by line — one of the blocks fixed here splits its attributes across lines and a line-scoped grep passed straight over it.
The new guard asserts over the whole tracked tree, so CI's import-graph selection can never reach it from a changed file. Register it alongside the other class-string guards so it runs whenever any `client/src` source changes, instead of only on a full suite.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Layout's root shell isoverflow-x-hidden, so a child wider than the viewport is clipped, not scrollable — there is no scrollbar to recover the overflowing edge.whitespace-pre-wraponly wraps at whitespace, so a<pre>carrying it alone still runs off that edge as soon as its content holds one unbroken token: an absolute path, a URL, a base64 blob, a minified JSON line, a stack frame.#5675 fixed the two
<pre>openers that had no wrap class at all, plus the two inJobCard.jsx. This is the remaining sweep: 35 blocks across 27 files, each classified by what it renders, following the splitJobCard.jsxestablished.break-all(matchingcomponents/ui/ProcessLogLines.jsx, the canonical log renderer): llama.cpp / mtplx / slotstream server logs, the local-setup install log, runner and provider command output, browser logs, JSON dumps (TrustTab,VoiceTab,HistoryPagedetails), error traces, agent transcripts and raw model output in the capability tests, the resume-agent context blob, and the digital-twin export payload.break-words(breaks a word only when it cannot fit on a line of its own): prompt templates and previews (PromptEditor,PromptManager,Loops,NextActionBanner, the capability-test "what PortOS will send" panel), creative-director style specs / user stories / treatment prompts, the comic-script markdown source, digital-twin soul documents and bios, and wiki note bodies.Nothing else changes:
Layout'soverflow-x-hiddenis untouched (it is what stops one wide child from giving the whole app a horizontal scrollbar), and nooverflow-x-autowas added — a horizontal scroller inside a card is worse on touch than a block that keeps every character reachable at 360px.New tree-wide guard
client/src/preWrapClasses.test.jsfails when any git-tracked non-test<pre>opener carrieswhitespace-pre-wrapwithout a break class, so blocks added later are covered too. It reads each opening tag whole rather than line by line —LocalSetupPanel.jsxsplits its attributes across lines, and the line-scoped grep in the issue passed straight over it. It follows the existing convention-guard shape (popoverClampConventions.test.js) and reuses the sharedtest/trackedFiles.js+test/classNameScan.jshelpers.Closes #5820
Test plan
client/src/preWrapClasses.test.js— 3 cases: the tree is populated, a bypass probe asserting the detector flags the bug and clears every safe form (break class present, no wrap class at all, multi-line opener, interpolated class branches, a>inside the class expression,overflow-x-autoas a non-substitute, a<preview>tag, a doc comment quoting an example), and the tree-wide sweep.break-allfromRunnerPage.jsx:510and from the multi-lineLocalSetupPanel.jsx:269opener turned the suite red naming both — including the one a line-scoped grep cannot see. Restored, green again.cd client && npm test— Test Files 827 passed | 1 skipped (828), Tests 10110 passed | 2 skipped. (One earlier run had two unrelatedPostSessionLauncherdrill-selection flakes that pass in isolation and did not recur.)cd client && npm run lint— clean.client/src, which the server Vitest project does not glob.