fix(desktop): keep WorkHub chat bubbles on --radius-chat - #4919
fix(desktop): keep WorkHub chat bubbles on --radius-chat#4919liuxiaocs7 wants to merge 3 commits into
Conversation
WorkHub's conversation surface passed `density="compact"` into Astryx's `ChatMessage` / `ChatMessageList`, and `ChatMessageBubble` maps that to `border-radius: var(--radius-container)` (12px). The WorkHub composer stayed on `--radius-chat` (28px), so a bubble and the dock on the same surface disagreed by more than 2x. The main transcript avoided this — apache#3452 dropped the compact density from its `ChatMessageList`; WorkHub reintroduced it in apache#3497. Drop `density="compact"` from WorkHub's chat primitives — both `ChatMessageList` calls and the user/assistant `ChatMessage` rows in `WorkHubMessageFrame` — so the bubble falls back to the primitive's `--radius-chat` and rounds together with the composer as one conversation surface, exactly as apache#3452 fixed the main transcript. `gap={4}` stays: it sets the row gap explicitly and never depended on density. The existing `SubmittedWorkKeepsTargetMetadataInside` story already renders the projected user bubble; its play now also pins the bubble's radius to a `--radius-chat` probe (measured, not read back — ink-ladder-contract forbids the latter), so an upstream token change moves both or fails here. Fixes apache#4914 Generated-by: Claude Code
FIDELITY.md keeps geometry contracts out of a Storybook `play`, and apache#3452 — the sibling chat-radius fix this PR mirrors — put its regression in the E2E harness. Drop the story-play probe added earlier and assert the pairing where it belongs: in workhub-reconstruction.spec.ts, comparing the projected user bubble's computed border radius against the real composer plate rather than a token literal, so an upstream `--radius-chat` change moves both or fails here. Generated-by: Claude Code
e2e-budget.json keeps layout geometry and pure CSS in a Storybook `play`, not the Electron tier, and apache#4877 already moved the sibling Side Chat / WorkHub geometry there while deleting the old E2E radius checks. Revert the E2E assertion added in the previous commit and put the contract in the existing SubmittedWorkKeepsTargetMetadataInside play, comparing the real user bubble's computed radius against the real composer plate — so the bubble and the dock on one surface must round together or this fails. Generated-by: Claude Code
Astro-Han
left a comment
There was a problem hiding this comment.
Reviewed current head 531249fd (OPEN, MERGEABLE, awaiting human review). Technical GO — no P0–P3. CI test fully green on this head (12m39s, including Electron e2e budget check, Test Storybook audit contracts, Build Storybook, and Storybook smoke).
What changed
Four WorkHub chat primitives (two ChatMessageLists, user/assistant ChatMessages) drop density="compact", so bubbles fall back from --radius-container (12px) to the primitive default --radius-chat (28px), matching the composer panel — the same fix previously applied to the main transcript. gap={4} is correctly kept (row gap never depended on density). No CSS override was added (chat-message.css:100 deliberately leaves radius to the primitive; an override would conflict).
Correctness points verified
- The density blast radius was checked at its widest point:
density=compactalso drives Markdown heading scale and list/quote rhythm, but WorkHub message rows render plain<p>text with no Markdown body — on this surface density only ever affected bubble radius, so removing it has no collateral density regression. - Before/after screenshots (light and dark) confirm the claim: 12px vs 28px mismatch before, identical bubbles after, with no other movement in metadata blocks, spacing, or text.
- The extended story asserts
border-top-left-radiusequality against the real composer plate element rather than a28pxliteral — both move together (or the test fails) if the upstream token changes, which is the right way to pin it. The e2e-budget annotation correctly attributes pure CSS geometry to the Storybook layer. - Six-layer pass: design (real issue, 12 vs 28 on one surface) → function (real WorkHub submission path) → complexity (removing a knob instead of adding an override, entropy down) → tests → naming/comments → style.
Verification boundary
- No real WorkHub submission was driven end to end; geometry is verified via screenshots plus the element-to-element regression, not a live session.
Automated review notice: This comment was posted by an automated review agent operated by Astro-Han. It is not an independent human review and does not replace one.
简体中文
评审结论来自自动化审查流程;发布者没有读这份 diff,核的是当前 head 有没有漂移、以及 exact-head 的门禁状态。当前 head 是 531249f,未关闭,检查全绿。技术上无阻断问题。合并由人类定。
Summary
WorkHub's conversation surface passed
density="compact"into Astryx'sChatMessage/ChatMessageList, andChatMessageBubblemaps that toborder-radius: var(--radius-container)(12px). The WorkHub composer stayed on--radius-chat(28px), so a bubble and the dock on the same surface disagreed by more than 2x. The main transcript already avoids this — #3452 dropped the compact density from itsChatMessageList; WorkHub reintroduced it in #3497.This drops
density="compact"from WorkHub's chat primitives — bothChatMessageListcalls and the user/assistantChatMessagerows inWorkHubMessageFrame— so the bubble falls back to the primitive's--radius-chatand rounds together with the composer as one conversation surface, exactly as #3452 fixed the main transcript.gap={4}stays: it sets the row gap explicitly and never depended on density. No product CSS override is added;chat-message.cssalready documents that the bubble radius is left to the primitive on purpose.Fixes #4914
Verification
Before / after on the real story render (
Product/WorkHub → SubmittedWorkKeepsTargetMetadataInside), light and dark:Computed
border-top-left-radius, measured in the running Storybook (Playwright):density="compact")Light and dark measured identical. After the fix the user bubble and the composer plate agree at 28px — matching the main transcript.
play): the existingSubmittedWorkKeepsTargetMetadataInsideplay now asserts the projected user bubble's computedborder-top-left-radiusequals the real composer plate's — compared element-to-element, so the bubble and dock on one surface must round together or it fails. This lives in the storyplaypere2e-budget.json(layout geometry / pure CSS is not an Electron-tier concern), the same tier test(desktop): finish moving non-Electron coverage out of the E2E tier #4877 moved the sibling Side Chat / WorkHub geometry into. Red without the fix (bubble 12px vs plate 28px); I ran the story both ways to confirm.biome checkon the changed files): pass, no fixes.tsc -p tsconfig.renderer.jsonandtsconfig.storybook.json): no errors inworkhub-surface.tsxorworkhub.stories.tsx. Remaining diagnostics in the run are pre-existing/unrelated, because this worktree had no installed deps — I ran against a lockfile-identical siblingnode_modules.workhub-surface.tsxare untouched, so norenderer-architecture.jsonregeneration is needed. No.tsx/.cssadded or renamed, so the surface-inventory gate is not triggered.AI use
Select exactly one:
Tool(s) and scope: Claude Code — diagnosed the issue, made the fix, added the story-
playregression assertion, and captured the before/after screenshots. Commits carry aGenerated-by: Claude Codetrailer.Checklist
Biome (lint/format) and typecheck of the changed files pass locally; the
SubmittedWorkKeepsTargetMetadataInsideplay was rendered both ways (fixed = green,density="compact"restored = red) via Playwright against the running Storybook.Does this PR entail a change in behavior?