diff --git a/apps/desktop/src/styles/messages.css b/apps/desktop/src/styles/messages.css index 68f78ca38d..237664b2a4 100644 --- a/apps/desktop/src/styles/messages.css +++ b/apps/desktop/src/styles/messages.css @@ -1646,7 +1646,8 @@ (D319) and the nested `.subagent-run`. */ .message-error { - width: min(100%, 680px); + /* The message column owns the dynamic chat width; do not add a second cap. */ + width: 100%; border-radius: var(--radius-md); background: color-mix(in oklab, var(--ds-error) 7%, transparent); padding: 10px 12px; diff --git a/apps/desktop/test/transcript-style.test.mjs b/apps/desktop/test/transcript-style.test.mjs index effedd231e..e8c8f43736 100644 --- a/apps/desktop/test/transcript-style.test.mjs +++ b/apps/desktop/test/transcript-style.test.mjs @@ -194,6 +194,31 @@ test("assistant turns stay transparent full-width prose", () => { /\.tool-activity-group\.has-subagents\s*\{[^}]*background:\s*var\(--ds-tile\)/, ); }); +test("assistant error cards follow the responsive transcript column", () => { + const errorCard = stylesSource.match(/\n\.message-error \{([^}]*)\}/)?.[1]; + assert.ok(errorCard); + assert.match(errorCard, /width:\s*100%;/); + assert.doesNotMatch(errorCard, /max-width\s*:/); + assert.match( + stylesSource, + /\.message-row\.assistant \.message-col,\s*\.message-row\.system \.message-col,\s*\.message-row\.tool \.message-col \{\s*width:\s*min\(100%,\s*var\(--chat-prose-max-width,\s*720px\)\);/, + ); +}); + +test("decision and outcome cards follow the responsive transcript band", () => { + const cardRules = [ + stylesSource.match(/\n\.permission-card \{([^}]*)\}/)?.[1], + stylesSource.match(/\n\.asktool-card \{([^}]*)\}/)?.[1], + stylesSource.match(/\n\.turn-outcome-card \{([^}]*)\}/)?.[1], + ]; + for (const rule of cardRules) { + assert.ok(rule); + assert.match( + rule, + /width:\s*min\(100%,\s*var\(--chat-prose-max-width,\s*720px\)\);/, + ); + } +}); test("transcript density and hover actions are quiet", () => { assert.match(stylesSource, /\.message-row \{[\s\S]*?padding:\s*12px 0;/); diff --git a/docs/spec/04-ux/08-component-spec.md b/docs/spec/04-ux/08-component-spec.md index f915ee19e6..9c54367975 100644 --- a/docs/spec/04-ux/08-component-spec.md +++ b/docs/spec/04-ux/08-component-spec.md @@ -1627,8 +1627,9 @@ Single message render — either user (plaintext) or assistant (markdown streami ### 8.3 Layout - Max content band: 760px default, user-resizable via dual edge handles - (D439 / ADR 0277). Assistant, tool, and decision rows follow the band. - User plates stay `min(82%, 600px)`. + (D439 / ADR 0277). Assistant, tool, decision, and structured assistant-error + rows follow the band; error cards fill their message column without a second + fixed width cap. User plates stay `min(82%, 600px)`. - The live band is `min(available pane, preferred)`. Collapsing the sidebar no longer tightens a 640px ceiling; the outer pane stays fluid and the width transition follows the sidebar dock. diff --git a/docs/spec/06-delivery/04-e2e-test-plan.md b/docs/spec/06-delivery/04-e2e-test-plan.md index a04ae25419..44249df78f 100644 --- a/docs/spec/06-delivery/04-e2e-test-plan.md +++ b/docs/spec/06-delivery/04-e2e-test-plan.md @@ -9089,7 +9089,7 @@ This test plan spec is accepted when: ### US-UI-60c Compact assistant error card - Trigger a retriable provider/model failure in the transcript in light and dark themes. - Expect the assistant error to use a restrained inline surface with a thin error rail. The localized summary, stable code, and details disclosure share one compact header; the card does not render a second bottom action row. -- Confirm the details remain expanded on first render, keep the redacted provider response and provider/model IDs, and expose an icon-only copy control with an accessible label/tooltip. On a narrow window, the header actions wrap without horizontal overflow. +- Confirm the details remain expanded on first render, keep the redacted provider response and provider/model IDs, and expose an icon-only copy control with an accessible label/tooltip. On a narrow window, header actions wrap without horizontal overflow. At default and widened chat content widths, the card fills the assistant column; resizing the content band makes the card follow it, and a constrained pane does not overflow. - Expect the compact assistant error card itself to expose one localized **Continue** action beside the details disclosure. Click it and expect the app to append the localized continuation prompt (`Continue the current task` / `继续当前任务`) to the same session and start the next turn without truncating the failed turn. - For a terminal `PROVIDER_RATE_LIMITED` (including HTTP 429), expect the structured assistant error card to remain the only failure surface: it