Skip to content

Render the real Chat composer on the Conversation audit plate - #629

Merged
MaggieAppleton merged 2 commits into
mainfrom
audit-chat-composer
Oct 15, 2026
Merged

MaggieAppleton merged 2 commits into
mainfrom
audit-chat-composer

Conversation

@MaggieAppleton

@MaggieAppleton MaggieAppleton commented Oct 15, 2026 •

Copy link
Copy Markdown
Collaborator

What was fake

  • Conversation plate hand-built a .chat-composer with a bare <textarea>, invented hint text ("Use # to reference a document") and a TerminalAlert beneath it ("Message could not be sent. Try again."). None of that exists in the app. Its .design-audit-chat CSS imitated the Chat pane.
  • Rebased onto main after conversational initiative landed: the composer follows main (no mode switch, no Chopin chip, no data-mode, "Message…" placeholder). The plate also shows the real Participation toggle above the transcript ("Chopin participates") and its paused state, with an offline wire stub so pressing it does nothing.
  • Errors plate showed an invented "Research stopped before it finished." row with a secondary Retry on a destructive wash.

What it renders now

  • New presentational ChatComposer (apps/web/src/chat/composer.tsx, imports composer.css). Chat keeps all logic (wire, draft, pickers, key routing) and renders ChatComposer with props: notice {tone,text,action}, unavailable, references, run (stop/resume), connectionLabel/onReconnect, sending, sendDisabled, pickers and attachment slots, and input (draft value, handlers including main's typing reporter onChange/onBlur, combobox aria). composer.css is now imported once, from composer.tsx. Markup, classes and aria are unchanged; Stop and Resume stay two separate elements. DraftInput's props type is now exported as DraftInputProps.
  • Conversation plate renders the transcript plus the real composer inside the real .workspace-root / .workspace-chat-panel / .workspace-chat-body wrappers, then the composer in each live state: empty, mentioning Chopin, sending, send failed (composer-notice + Retry, copy from boundedChatError), reconnecting, offline + Reconnect, Chopin working (Stop), read-only, archived.
  • Rebased onto main after conversational initiative landed: the composer follows main (no mode switch, no Chopin chip, no data-mode, "Message…" placeholder). The plate also shows the real Participation toggle above the transcript ("Chopin participates") and its paused state, with an offline wire stub so pressing it does nothing.
  • Errors plate replaces the invented row with the real send-failed composer notice. Its [role="alert"] rule is now scoped to direct children so it doesn't restyle the notice.

CSS removed

.design-audit-chat, .design-audit-chat .chat-composer textarea, .design-audit-composer-actions, .design-audit-chat-error, .design-audit-recoverable-error. What's left is plate framing only (stage height and border, states grid).

Before / after

Conversation before: Conversation before
Conversation after: Conversation after
Errors before: Errors before
Errors after: Errors after

I didn't capture a live-app screenshot: the live Chat needs a signed-in server session. The plate now mounts the same component, so the two can't drift apart.

Risks

  • chat.tsx is the highest-risk file in the audit. The diff moves the composer JSX into ChatComposer without changing it; cueId, connectionId and instructionsId are now generated inside ChatComposer (opaque useId values, same aria-describedby order). Chat e2e suites (e2e/chat*.e2e.ts) weren't run locally because the ports are shared, so CI is the check.
  • e2e/design/specimens.e2e.ts baselines for the Conversation and Errors plates will change; that's expected.

Checks

bun run types ok; bun test apps/web/src/design-audit apps/web/src/chat 219 pass, including the new chat/composer.test.tsx (5 tests); check-design-contract ok (no spreads into style sinks); check-tokens ok; oxlint 0 warnings and 0 errors on changed files; dprint clean.

🤖 Generated with Claude Code

Base automatically changed from audit-split-plates to main October 15, 2026 10:34
MaggieAppleton and others added 2 commits October 15, 2026 11:48
Chat keeps the wire, draft, pickers and key routing and renders a new
presentational ChatComposer (chat/composer.tsx) with the same markup,
classes and aria. The Conversation plate now renders that composer inside
the real workspace wrappers in each live state, and the Errors plate shows
the real send-failed composer notice instead of an invented retry row.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The field and Stop/Resume markers moved with the composer markup.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@MaggieAppleton
MaggieAppleton merged commit 36616f5 into main Oct 15, 2026
24 checks passed
@MaggieAppleton
MaggieAppleton deleted the audit-chat-composer branch October 15, 2026 11:03
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.

1 participant