Skip to content

fix(console): Agents list wraps long names on wide screens; phone sheets stay above the keyboard - #2893

Merged
freeqaz merged 25 commits into
mainfrom
ux-fixes-123-list
Oct 19, 2026
Merged

freeqaz merged 25 commits into
mainfrom
ux-fixes-123-list

Conversation

@freeqaz

@freeqaz freeqaz commented Oct 19, 2026 •

Copy link
Copy Markdown
Collaborator

Problem

Two layout bugs from bughunt-123:

  • Finding 1955: the Agents table has no wrap for the Agent name above 760 px. A name can be 200 characters, and one with no break opportunity (200 x "W", a long Arabic run, a URL-like name) widens the table to about 3600 px at 761, 800, 1024 and 1440 px. Every other column then sits off-screen, in LTR and RTL. At 760 px and below the stacked phone rows already wrap.
  • Finding 1956: the phone-list test only uses 60-character names with spaces, so it passes with the phone layout's overflow-wrap: anywhere removed.
  • Finding 1957: at 760 px and below every dialog is a bottom sheet pinned to the bottom of the layout viewport. A phone's on-screen keyboard shrinks only the visual viewport (Chrome Android 108+ by default, iOS Safari always). So while the Create Secret dialog's Name or Value field has focus, Cancel and Create Secret sit under the keyboard; the user has to dismiss the keyboard to confirm. The Slack drawer's Save and the Plugins sheet's search have the same exposure.

Change

  • Agents list (1955). Only a name that cannot wrap changes.
    • list.mjs marks a name link agent-name-unbroken when the name has a run of 21 or more characters with no place a line can break. That is longer than any ordinary word ("Internationalization" is 20).
    • A run ends only at a character Chromium breaks a line at (measured): a breaking space (U+0020, U+1680, U+2000-U+2006, U+2008-U+200A, U+205F, U+3000), the zero-width space, the soft hyphen, or a hyphen or dash (-, U+2010, U+2012-U+2014). No-break spaces (U+00A0, U+2007, U+202F, U+FEFF) and the non-breaking hyphen do not end it. The previous head used \s, which counts no-break spaces, so a 200-character name of "WWWW" joined by no-break spaces was never marked and the table measured 3072 px (internal review). A name holds no control or line-separator characters, so tabs and newlines need no entry.
    • The marked link is an inline-block capped at 310 px, the ID's cap, with overflow-wrap: anywhere, so it no longer sets the table's width.
    • Every other name keeps main's layout exactly. I tried a column-wide rule (anywhere plus a 10 or 12rem column minimum) and dropped it. It widened ordinary tables where they are narrowest (the Populated story from 645 to 670 px, the test's ordinary rows from 709 to 736 px at 761-1024), and 10rem split "Documentation" mid-word.
    • Under 760 px the marked link goes back to inline and inherits its cell's wrap, so the phone layout is unchanged.
  • Phone sheets (1957). trackVisualViewport() in dom.mjs is called once at console startup. It listens to visualViewport resize and scroll and mirrors how far the visible area is inset from the layout viewport's top and bottom into --visual-viewport-top (offsetTop) and --visual-viewport-bottom (innerHeight - offsetTop - height) on <html>. It writes once per animation frame, and only values that changed.
    • In the phone query the sheet sets top and bottom to those insets, margin: auto 0 0 and max-height: calc(100% - top inset - bottom inset - var(--space-8)), and the wide sheet takes its height the same way. These resolve against the layout viewport the fixed dialog sits in, so a hidden URL bar does not change the gap. Without the properties the values are today's.
    • Both insets are 0 while no keyboard or zoom is up, so a value one frame stale after a window resize still places the sheet right. The previous head mirrored the absolute visible height instead; right after a window resize that value was a frame stale, sized the sheet for the old window, and pushed the Create Agent plugins catalog's pagination out of the dialog's scroll area (console-agent-presets "discovers hosted plugins" failed in CI).
    • tests/conformance/console-design-tokens.test.mjs allowlists the two runtime-set properties, as it already does --log-time-width.
    • A sheet taller than the visible area keeps its whole box in view and scrolls inside, as it does today on a short screen.
    • index.html is unchanged. interactive-widget=resizes-content would cover Chrome and Firefox on Android only: Safari ignores it, and it resizes the whole page's layout for every text field. No viewport-fit=cover or env(safe-area-inset-bottom) either: without viewport-fit=cover, env() is 0.
  • Storybook. I added Pages / Agents / Long unbroken name and Long unbroken name (phone) (a 200-character name with no space) and a step 7 in dialog-pattern-workflow.md. Step 7 opens the Create Secret fixture in its own phone tab, because an iframe's visual viewport does not follow the page's keyboard.

Verification

Tested revision: 6b81881d8 (merged with origin/main 5bf45e1b2), headless Chromium (Playwright), in-memory console fixture.

Tests

  • tests/browser/console-agents-list-return.test.mjs, phone-list test (1955, 1956):
    • Two of its 12 Agents have the longest allowed name with no break in it: 200 x "W", and 200 characters of "WWWW" joined by no-break spaces. The other 10 names contain "documentation", a 13-character word. The test runs at 390, 360, 600, 760, 761, 1024 and 1440 px.
    • At every width it asserts that each name stays inside its cell, and that the table is no wider than it is with the unbroken names' rows hidden.
    • Ordinary names must keep main's wrap (inline, overflow-wrap: normal on desktop) and break only between words. Above 760 px each unbroken name must be at most 310 px wide; at 600 and 760 px a stacked row gives it its full width.
    • It asserts that the table fits its card except at 761 and 1024, where these rows' five columns still scroll (finding 1907).
    • On main it fails: 761: the unbroken name widens the table from 709 to 3600 px. The earlier break-word head failed with from 709 to 910 px, and the previous head's \s regex fails with from 709 to 3132 px (the no-break-space name).
  • tests/browser/console-dialogs.test.mjs, new test "On a phone the Secret sheet keeps its actions in the visible area above the keyboard" (1957):
    • It opens Create Secret at 390x844 and keeps the Name textbox focused (checked by role and name). It then shrinks the visual viewport two ways:
      1. Chromium's own pinch zoom (Emulation.setPageScaleFactor 1.5, 0 to 563 px visible). Only the vertical axis is checked, because zoom also narrows the view.
      2. A keyboard-shaped visual viewport: the page's height/offsetTop getters are replaced and the event is dispatched by hand. Cases: (0, 508) with resize, (120, 508) with scroll, (0, 400) and (200, 300).
    • Each time it asserts that the sheet's bottom equals the visible bottom and the sheet's top is in view. For the 508 px cases it also asserts that Cancel and Create Secret are inside the visible area; in the shorter cases the sheet scrolls, so only its box is checked.
    • On main it fails: zoomed: the sheet's bottom edge (Create Secret at 789-828 px with 0-563 visible).
    • Not verified: a real on-screen keyboard. Headless Chromium has none, and CDP cannot shrink only the visual viewport's height (Emulation.setVisibleSize and setDeviceMetricsOverride with a viewport left it at 844 px). The test proves the visualViewport contract, not a device. The hidden-URL-bar case is covered by construction (nothing reads clientHeight any more), not by a test.

Mutants (each applied by hand to the changed source, then the touched test run):

Mutant Result
Every name marked killed (761: row 0 name wrap)
No name marked killed (761: ... from 709 to 3600 px)
Run regex back to /[^\s-]{21,}/u (no-break spaces end a run) killed (761: ... from 709 to 3132 px)
Marked link without overflow-wrap: anywhere killed (... from 709 to 3016 px)
Marked link without max-width: 310px killed (1440: the unbroken name is 483 px)
Marked link without display: inline-block killed (1440: the unbroken name is 480 px)
Phone reset of the marked link removed killed (600: the unbroken name is 310 px)
Phone .agent-table td without overflow-wrap: anywhere killed (390: the table scrolls sideways)
Phone .agent-table td without min-width: 0 survives: equivalent
trackVisualViewport() not called killed (zoomed: the sheet's bottom edge)
Top inset always 0px killed (300 px visible, 200 px down: the sheet's top is hidden)
Bottom inset ignores offsetTop killed (508 px visible, 120 px down: the sheet's bottom edge)
No scroll listener killed (508 px visible, 120 px down)
No resize listener killed (zoomed: the sheet's bottom edge)
Frame id never reset killed (zoom undone: the sheet's bottom edge)
Sheet bottom: 0px instead of the inset killed (zoomed: the sheet's bottom edge)
Sheet max-height without the insets killed (400 px visible, 0 px down: the sheet's top is hidden)
Sheet top: 0px instead of the inset survives: equivalent, since max-height keeps the sheet's top inside the visible area
Wide sheet height without the insets survives: equivalent, the shared max-height clamps it
No write at startup survives: both insets are 0 when the page loads without a keyboard or zoom
root.clientHeight instead of innerHeight survives in headless Chromium, where the two are equal (no scrollbars)
No clamp of sub-pixel insets to 0 survives: changes sub-pixel values only

The phone .agent-table td min-width: 0 mutant survives on main too. I reran bughunt-123's list probe (six names: Arabic, Hebrew, emoji ZWJ sequences, URL-like and others) without it at 360-760 px, LTR and RTL, and nothing scrolls sideways. With anywhere the cell's min-content is one character. The phone td:first-child reset matters only where a cell is under 168 px wide, which never happens at 360 px and up.

Pins. 20/20 for each touched browser file, sequential, on 2 CPUs, at 6b81881d8 (the final code): console-agents-list-return.test.mjs 20/20 and console-dialogs.test.mjs 20/20. tests/conformance/console-design-tokens.test.mjs passes (2/2; misspelling one allowlisted name makes it fail again), and so does console-json-errors.test.mjs, which imports dom.mjs. Every browser file that opens a dialog passed once at 33cd3ca1f (23 files, among them console-agent-presets 32/32, console-agent-detail 36/36, console-agent-detail-2 62/62, console-focus-ring 5/5, console-agent-channels 15/15, console-agents 31/31, console-dialogs 2/2), and after merging #2898 console-button-hierarchy 6/6 and console-agent-presets 32/32 again. ESLint and Prettier pass on the touched files.

Ordinary tables, main vs this head (scroll width / card width, px):

Width Populated story, main Populated story, head Test's 11 ordinary rows, main Same rows, head Same rows plus the 200 x "W" row, head
761 645/422 645/422 709/422 709/422 709/422
800 645/461 645/461 709/461 709/461 709/461
900 645/561 645/561 709/561 709/561 709/561
1024 685/685 685/685 709/685 709/685 709/685
1100 761/761 761/761 761/761 761/761 761/761
1440 1101/1101 1101/1101 1101/1101 1101/1101 1101/1101

The test's ordinary rows already scroll at 761-1024 on main (finding 1907); this PR leaves them unchanged. With the 200 x "W" row, main measures 3600 px at every width.

Media (simulated data): list media commit 0460dcb49 and keyboard media commit 463e1119a (each removed by the next commit). The list shots come from the Storybook fixture frames, served from this branch's and main's console sources, using the story's 200-character mixed-case name. That name makes the main table 2159 px wide; 200 x "W" in the test makes it about 3600 px. The keyboard shots come from the console test fixture: a drawn 336 px panel stands in for the keyboard, the visual viewport is faked to 508 px, and Name has focus.

Before (main) After
Agents list, 1440 px Before: the table is 2159 px wide and only the Agent column is visible After: the name wraps within 310 px and all five columns fit
Agents list, 1024 px Before: the table is 2159 px wide After: only the unbroken name breaks; Documentation assistant wraps as on main; the table is 690 px in a 685 px card (finding 1907)
Agents list, 390 px (unchanged) After: the phone list wraps the name inside its stacked row
Create Secret sheet, 390 px, keyboard Before: Cancel and Create Secret under the keyboard After: the sheet sits above the keyboard

Video (simulated data, commit 70aed9fc5, removed by the next commit; now attached natively in Verification; the relevant list, viewport, CSS, and owning browser-test blobs are identical to this reviewed head):

  • Agents list, 1440 px: two ordinary names, the 200 x "W" name, the no-break-space name and the mixed-case story name; all five columns fit.
  • Agents list, 390 px: the same names wrap inside their stacked rows.
  • Create Secret sheet, 390 px: Name focused; a drawn 336 px panel stands in for the keyboard while the visual viewport is faked to 508 px, the sheet moves above it with Cancel and Create Secret visible, typing continues, and the sheet returns when the panel goes. This is the same simulated visual viewport as the test, not a physical on-screen keyboard (see Not verified above).

Storybook: Pages / Agents / Long unbroken name and Long unbroken name (phone). I could not run a full Storybook build here, because its dependencies are not installed in this checkout; the screenshots are the story frames themselves.

Conflicts. I ran git merge-tree --write-tree for each open PR head that touches these files, against origin/main (5bf45e1b2) and against this head. The table lists conflict hunks.

PR Head Conflicts with origin/main Conflicts with this branch
#2899 d8619ea 0 files / 0 hunks 0 files / 0 hunks
#2860 766479a 0 files / 0 hunks 0 files / 0 hunks
#2833 d4847cd 0 files / 0 hunks 0 files / 0 hunks
#2599 bc3ba21 19 files / 33 hunks 19 files / 33 hunks
#2596 2aa1d5b 0 files / 0 hunks 0 files / 0 hunks
#2524 a8fb50b 3 files / 4 hunks 3 files / 4 hunks
#2518 6be6b0a 6 files / 11 hunks 6 files / 11 hunks
#2505 883cdd6 1 files / 2 hunks 1 files / 2 hunks
#2502 d4440b3 3 files / 6 hunks 3 files / 6 hunks
#2445 c0824a1 4 files / 4 hunks 4 files / 4 hunks
#2258 dfc28d8 1 files / 3 hunks 1 files / 3 hunks
#2255 0ced398 3 files / 5 hunks 3 files / 5 hunks
#2253 82c7e1f 2 files / 3 hunks 2 files / 3 hunks
#1619 b4ff6e5 8 files / 17 hunks 8 files / 17 hunks
#906 22c5ee8 2 files / 5 hunks 2 files / 5 hunks
#878 78d0e26 2 files / 2 hunks 2 files / 2 hunks

No PR gains a conflict hunk. The CSS rule and stories were placed clear of #2524's insertion points.

Review response (freeqaz-openai, 6ff74d2)

  • Conformance (Checks and Conformance 1). tests/conformance/console-design-tokens.test.mjs keeps the check and its explicit inventory, and adds the runtime properties right after the log ones with the requested comment, // Set on the document element by trackVisualViewport (dom.mjs). (1e5510341, wording 33cd3ca1f). The names are --visual-viewport-top and --visual-viewport-bottom, because the height property is gone (next item).
  • Plugins catalog pagination (Console Browser 2). Thanks for the race diagnosis: right after setViewportSize the sheet still used the old --visual-viewport-height. I fixed it in the console rather than with a wait in the test (1e5510341): the sheet now reads the visible area's top and bottom insets, which are 0 whenever no keyboard or zoom is up, so a value one frame stale after a window resize no longer sizes the sheet for the old window. A real user resizing or rotating would have hit the same stale frame. console-agent-presets.test.mjs is unchanged, its hit-test assertion included, and passes 32/32.
  • No-break spaces (internal review). The unbroken-run rule no longer counts no-break spaces as breaks (b59468fad); the list test gained a no-break-space name that fails against the old rule.
  • Video. Added under Verification (70aed9fc5, removed by f3a0a7875), ready to attach natively. The physical-keyboard limit stays explicit there and under Not verified.

Risks

  • Threshold. A name with a 21-or-more-character run with no break opportunity (for example a long snake_case name) breaks anywhere within 310 px. A name whose longest run is 20 characters or fewer is untouched and still sets the column's width, as on main.
  • A name whose longest unbroken run is 20 characters or fewer (e.g. two 20-"W" runs) can still widen the table (855 px at 761/1024), as on main.
  • Pinch zoom. The sheet follows pinch zoom as well as the keyboard: while a phone user zooms or pans with a dialog open, the sheet stays on the bottom of the visible area, possibly a frame behind during a pan.
  • Tall sheets. A sheet taller than the area above the keyboard (for example the Slack drawer on a small phone) keeps its whole box visible but scrolls. Its actions are reachable by scrolling the sheet without closing the keyboard, but they are not pinned.
  • iOS Safari, unverified. The bottom inset uses window.innerHeight as the fixed dialog's box. That is right for Chromium (URL bar shown or hidden, keyboard, pinch zoom). If WebKit's innerHeight follows the visible area under zoom or the keyboard, the inset clamps to 0 and the sheet behaves as on main: no regression, but no fix there.
  • Always-set properties. <html> now always carries the two inset properties (0 px without a keyboard or zoom). At desktop widths nothing reads them.

…reens

One unbroken name (200 characters is allowed) widened the desktop Agents
table to about 3600 px, so every other column sat off-screen (finding 1955).
The name link now wraps within the 310 px its ID takes and breaks only a word
longer than that; the phone layout keeps the inline link and its cell's wrap.

The phone-list test gains one unbroken maximum-length name and runs at 760 and
761 too, so it fails on main at 761 and 1440 and kills the phone wrap mutant
(finding 1956).
A phone keyboard shrinks the visual viewport, not the layout viewport a modal
dialog sits in, so the bottom sheet's Cancel and Create Secret sat under the
keyboard while a field had focus (finding 1957). The console now mirrors the
visual viewport into two custom properties, set only while it differs from
the layout viewport, and the sheet takes its bottom margin and maximum height
from them. This covers Safari, which ignores interactive-widget, and needs no
change to the viewport meta tag.

The new dialog test shrinks the visual viewport with a pinch zoom (Chromium's
own visual viewport) and with a keyboard-shaped one, including a scrolled and
a short visible area; it fails on main.
…eet check

Adds Pages/Agents Long unbroken name and its phone variant (a 200-character
name with no space), and a dialog-pattern workflow step for the sheet rising
with the on-screen keyboard (findings 1955, 1957).
…2524

Moves the name-wrap rule above .agent-table a and the long-name scenarios
beside the deployment ones, so the branch adds no conflict hunk with the open
Agents-list row actions PR. Order only; no rule or scenario changes.
@freeqaz
freeqaz requested a review from a team as a code owner October 19, 2026 00:41
@clawsweeper

clawsweeper Bot commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

🦞👀
ClawSweeper picked this up.

Pull request received. I will update this pull request when review starts.

ClawSweeper review complete

ClawSweeper finished reviewing this revision. The review result is being finalized.

View the workflow run.

@freeqaz
freeqaz temporarily deployed to integration-qa-pr October 19, 2026 00:42 — with GitHub Actions Inactive
@freeqaz
freeqaz temporarily deployed to integration-qa-pr October 19, 2026 00:42 — with GitHub Actions Inactive
@clawsweeper clawsweeper Bot added P2 Normal priority bug or improvement with limited blast radius. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. labels Oct 19, 2026
@clawsweeper

clawsweeper Bot commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge.

What this changes

This PR bounds long Agent names on desktop and positions phone dialog sheets within the visual viewport.

Example: View an Agent named with 200 consecutive W characters at 1440 px.

  • Before: The name expands the table to about 3600 px and pushes other columns off-screen.
  • After: The name wraps within 310 px while the other columns remain visible.

Review scores

Measure Result What it means
Overall readiness 🐚 platinum hermit (4/6) Useful, focused repair with resolved prior findings, visual comparisons, meaningful browser regressions, and passing required CI.
Proof confidence 🐚 platinum hermit (4/6) ✨ media proof bonus Sufficient (screenshot): Inspected native before/after screenshots show the production console rendering bounded names and moving Secret actions above a simulated keyboard in Chromium fixtures. Physical keyboards and Safari remain explicitly unverified; independent video playback was unavailable here, while the current-head approval records inspection of all three attached walkthroughs.
Patch quality 🐚 platinum hermit (4/6) No actionable review findings were identified.

Product

Kind: Bug fix · Worth it: Yes · Fix scope: Complete
User problem: Long names hide neighboring Agent columns, and phone keyboards cover dialog actions.
Reason: The maintainer-authored repair addresses demonstrated failures while preserving ordinary-name layout and existing dialog interactions.

Merge readiness

✅ Ready for maintainer review

This PR remains useful and has no remaining actionable findings; both previously reported defects are resolved in the corrected head.

Priority: P2
Reviewed head: 6b81881d8ff955f40886c548079a6a9db38e6cb2

Before merge

None.

Findings

None.

Agent review details

How this fits together

The controller serves the browser console; its list renderer consumes Agent metadata, while viewport events update CSS insets used by shared phone dialogs.

flowchart TB
  A[Agent API responses] --> B[Agent list renderer]
  B --> C[Bounded name links]
  D[Visual viewport events] --> E[Shared DOM utility]
  E --> F[Phone dialog CSS]
Loading

Technical review

Best possible solution:

Land the focused renderer and shared-dialog repair with its existing browser coverage and attached visual evidence.

Do we have a high-confidence way to reproduce the issue?

Current-main source, before/after screenshots, and documented base-failing browser cases establish both layout failures; no target code was executed during this review.

Is this the best way to solve the issue?

The repair uses the existing renderer, DOM utility module, and shared dialog styles; inset-based geometry removes the stale-height resize failure without weakening the pagination assertion.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning medium; reviewed against 3139f1309e3c.

Provenance checked

Testing

Proof path: shipped entry point.

Security

None.

Evidence

What I checked:

Labels

Label changes:

  • add proof: sufficient: Contributor real behavior proof is sufficient.
  • add proof: 📸 screenshot: Contributor real behavior proof includes screenshot evidence.
  • add rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🐚 platinum hermit and patch quality is 🐚 platinum hermit.
  • add status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR.
  • remove rating: 🦪 silver shellfish: Current PR rating is rating: 🐚 platinum hermit, so this older rating label is no longer current.
  • remove status: ⏳ waiting on author: Current PR status label is status: 👀 ready for maintainer look.

Label justifications:

  • P2: The changes repair bounded console layout problems with horizontal scrolling or keyboard dismissal available as existing workarounds.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🐚 platinum hermit and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR.
  • proof: sufficient: Contributor real behavior proof is sufficient.
  • proof: 📸 screenshot: Contributor real behavior proof includes screenshot evidence.

Rating scale

6/6 🦀 challenger crab · 5/6 🦞 diamond lobster · 4/6 🐚 platinum hermit · 3/6 🦐 gold shrimp · 2/6 🦪 silver shellfish · 1/6 🧂 unranked krab. Overall follows the weaker of proof and patch quality; ✨ marks media proof (a screenshot, video, or linked artifact) that directly shows the changed behavior.

Workflow

ClawSweeper edits this one comment on every review. Comment @clawsweeper re-review for a fresh review only. Repair and merge execution lanes are retired.

History

Review history (1 earlier review cycle)
  • reviewed 2026-10-19T00:56:09.222Z sha ffc45da :: needs changes before merge. :: [P2] Register the viewport properties in the existing conformance check | [P3] Remove committed verification images from the merge diff

Reviewed October 18, 2026, 11:39 PM ET / October 19, 2026, 03:39 UTC (Revision 2).

… and height

Internal review: the bottom gap came from documentElement.clientHeight, the
initial containing block's height with the URL bar shown, while the dialog is
fixed in the layout viewport, so with the URL bar hidden the gap was about
56 px short. trackVisualViewport now mirrors only offsetTop and height into
--visual-viewport-top and --visual-viewport-height, and the sheet's top and
bottom resolve against its own fixed box. It writes once per frame and only
changed values.

The test checks Name's focus by role and name, adds a short visible area
scrolled 200 px down, and drops the removed-properties check.
…e column

Internal review: break-word kept the name's min-content at 310 px, so one
unbroken name still widened the table from 690 to 910 px at 761 to 1024 px.
The name link now breaks anywhere, like the ID, and the Agent column keeps
10rem so ordinary names still break between words; the phone layout resets
that minimum.

The list test also runs at 1024, checks that the unbroken name leaves the
table as wide as its other rows make it, and that ordinary names break only
between words.
An iframe's visual viewport does not follow the top-level page's keyboard, so
the check opens /storybook-fixtures/frame.html directly.
At 10rem (140 px) the narrowest table split "Documentation assistant" in the
Populated story mid-word. 12rem keeps a word of about 16 characters whole and
costs 27 px of table width where it already scrolls (finding 1907). The list
test's ordinary names now carry "documentation", so 10rem fails it.
…s height

The sheet read --visual-viewport-height, an absolute height written a
frame after each visual viewport resize. Right after a window resize the
stale value sized the sheet for the old window, so the Create Agent
plugins catalog's pagination fell below the dialog's scroll area
(console-agent-presets "discovers hosted plugins" in CI).

The sheet now reads how far the visible area is inset from the layout
viewport's top and bottom (innerHeight). Both are 0 while no keyboard or
zoom is up, so a value one frame stale after a resize still places the
sheet right. The design-tokens conformance test allowlists the two
runtime-set properties the way it already does --log-time-width.
UNBROKEN_RUN used \s, which also matches no-break spaces (U+00A0,
U+2007, U+202F, U+FEFF). A 200-character name of "WWWW" joined by
no-break spaces was never marked, and the desktop table measured over
3000 px (finding 1955). The run now ends only at characters Chromium
breaks a line at: breaking spaces, the zero-width space, the soft
hyphen, and hyphens and dashes.

The phone/desktop list test adds such a name; against the old regex it
fails with "761: the unbroken name widens the table from 709 to 3132 px".

@freeqaz-openai freeqaz-openai left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Free's clanker here. I checked the synchronized head 2fe85752: its hosted test tree is identical to the PR tree. There are two specific failures; please fix these rather than rerun unchanged.

  1. Console Browser 2: 360 passed, one failed, “Catalog pagination must be reachable without scrolling the whole dialog.” I reproduced a race in the actual Configure plugins test in sandboxed Chromium. Immediately after resizing to 390 × 640, the visual viewport was already 640 high but the app's CSS still said 844px. The Next page button was centered at y=805, so the hit test correctly returned null. About 15 ms later the app published 640px, the button was at y=599, and the same hit test succeeded without scrolling. This explains how the hosted result can happen; its log doesn't tell us the exact frame it observed.

    In tests/browser/console-agent-presets.test.mjs, wait for the new prerequisite immediately after setViewportSize, then keep the current hit-test assertion unchanged:

    await page.waitForFunction(
      (height) =>
        document.documentElement.style.getPropertyValue("--visual-viewport-height") ===
        `${height}px`,
      height,
    );

    The affected test passed with that change. As a negative control I held the actual layout at 844px while letting the variable update: the wait completed and the original reachability assertion failed as intended. No arbitrary delay, automatic scroll, assertion relaxation, or physical-keyboard claim.

  2. Checks and Conformance 1: 2,595 passed, one failed. The result still names --visual-viewport-top and --visual-viewport-height. The two-property declared-runtime-token correction still applies; the conformance file is unchanged.

I verified both result digests and the tested merge's parents and tree. Once these small test changes are up, please attach the existing native UI evidence, keep the simulated-keyboard qualification, and let current-head CI and ClawSweeper review the result. No production change requested by this review.

@freeqaz-openai freeqaz-openai left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Free's clanker here. Both failures I requested changes for are fixed at 6b81881d. Using insets instead of an asynchronously updated absolute height is better than my proposed test wait. The original pagination assertion is still intact.

  • I reran the real hosted-plugin fixture at 390 px, including the 844 → 640 px resize. The immediate hit test, without a wait for layout synchronization, reached Next page at y=601 with top and bottom insets both zero. At the earlier head it missed at y=805 because CSS still said 844 px high. The owning Agents list and Secret sheet cases also passed in sandboxed Chromium; the latter simulates the viewport, not a physical keyboard.
  • The exact CSS-token conformance file passes both cases, now listing top and bottom as set by the real viewport owner. Hosted CI exercised the actual two failing cases: 2,599/2,599 baseline checks and 367/367 browser cases passed, no skips. I verified both artifact digests and the tested merge 99ff91b3 (base 4aa82964, PR 6b81881d); this is stronger evidence than saying a rerun went green.
  • Seven native comparison images and three walkthroughs are in Verification. I opened the media, verified the videos' relevant source blobs match the reviewed head, downloaded all ten attachments byte-for-byte, and corrected the HTML image links without uploading duplicates.

This clears my change request. Please keep the physical-keyboard limitation explicit and use the fresh Claw verdict and normal protection for landing.

@freeqaz-openai

Copy link
Copy Markdown
Collaborator

@clawsweeper re-review

Please review corrected head 6b81881d. The runtime token inventory now matches top/bottom viewport insets. I reproduced the earlier stale-height pagination failure, verified the original test succeeds immediately with the inset fix, and checked both formerly failing cases in the exact-head hosted merge results. Verification includes native before/after screenshots and three walkthroughs; the phone keyboard is explicitly simulated. Review only, not a CI rerun.

@clawsweeper

clawsweeper Bot commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

🦞👀
Exact review queued.

Re-review progress:

@clawsweeper clawsweeper Bot added proof: sufficient Contributor real behavior proof is sufficient. proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. and removed rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. labels Oct 19, 2026
@freeqaz
freeqaz merged commit d717962 into main Oct 19, 2026
57 of 61 checks passed
@freeqaz
freeqaz deleted the ux-fixes-123-list branch October 19, 2026 03:43

This branch was previously deployed

1 inactive deployment
integration-qa-pr — 6b81881d Deployed Oct 19, 2026 by freeqaz via QA advisory (kubernetes) #2452
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

P2 Normal priority bug or improvement with limited blast radius. proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. proof: sufficient Contributor real behavior proof is sufficient. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants