Skip to content

fix: keep long tokens in wrapping <pre> blocks on screen (#5820) - #5998

Merged
atomantic merged 2 commits into
mainfrom
claim/issue-5820
Sep 3, 2026
Merged

fix: keep long tokens in wrapping <pre> blocks on screen (#5820)#5998
atomantic merged 2 commits into
mainfrom
claim/issue-5820

Conversation

@atomantic

Copy link
Copy Markdown
Owner

Summary

Layout's root shell is overflow-x-hidden, so a child wider than the viewport is clipped, not scrollable — there is no scrollbar to recover the overflowing edge. whitespace-pre-wrap only 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 in JobCard.jsx. This is the remaining sweep: 35 blocks across 27 files, each classified by what it renders, following the split JobCard.jsx established.

  • Machine output → break-all (matching components/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, HistoryPage details), error traces, agent transcripts and raw model output in the capability tests, the resume-agent context blob, and the digital-twin export payload.
  • Human-authored prose → 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's overflow-x-hidden is untouched (it is what stops one wide child from giving the whole app a horizontal scrollbar), and no overflow-x-auto was 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.js fails when any git-tracked non-test <pre> opener 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 — LocalSetupPanel.jsx splits 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 shared test/trackedFiles.js + test/classNameScan.js helpers.

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-auto as a non-substitute, a <preview> tag, a doc comment quoting an example), and the tree-wide sweep.
  • Guard verified to fail pre-fix: stripping break-all from RunnerPage.jsx:510 and from the multi-line LocalSetupPanel.jsx:269 opener turned the suite red naming both — including the one a line-scoped grep cannot see. Restored, green again.
  • The issue's enumeration grep now returns no results.
  • cd client && npm testTest Files 827 passed | 1 skipped (828), Tests 10110 passed | 2 skipped. (One earlier run had two unrelated PostSessionLauncher drill-selection flakes that pass in isolation and did not recur.)
  • cd client && npm run lint — clean.
  • Server suite not run: the change touches only client/src, which the server Vitest project does not glob.

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.
@atomantic
atomantic merged commit f877fc7 into main Sep 3, 2026
13 of 24 checks passed
@atomantic
atomantic deleted the claim/issue-5820 branch September 3, 2026 05:17
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.

Sweep the remaining pre blocks that wrap at whitespace but not on unbroken tokens

1 participant