Summary
The chat surface is the most-used view in CrowClaw and currently looks like a 2018 iMessage clone: 85%-max-width bubbles for both user and assistant, ALL-CAPS role tags above every message, no per-message actions, dumb auto-scroll that yanks users back to the bottom mid-read.
Modern agent dashboards (Claude Code preview, Cursor, Cline, LangSmith) render assistant content as full-width left-aligned blocks with subtle role indicators, and provide per-message actions on hover. This issue overhauls the chat surface to that standard.
Target milestone: v0.8.1 (Dashboard sweep).
Why this matters (no shortcut)
- Bubbles waste 15% of horizontal space on every assistant message — code blocks and tables get cramped.
- ALL-CAPS
role-tag at 9px is visual noise that adds zero information once a user knows the layout.
- The dumb auto-scroll is the single most-cited annoyance in dev-tool chat surfaces ("the page kept yanking me down while I was trying to read").
- The shortcut is "rewrite CSS only". Don't take it — per-message actions (copy/retry/edit/branch) require state management and event plumbing, not just visual changes. Half-doing this is worse than not doing it.
Source / reference points
- Cline's
webview-ui/src/components/chat/ChatRow.tsx — full-width assistant blocks, hover-revealed action row.
- Claude Code preview screenshots — left-margin avatar, no bubbles, message-level branch button.
- LangSmith run viewer — hover shows copy/share/expand.
Scope
Files to change
| File |
Change |
packages/web/ui/src/views/chat-view.ts |
Remove .bubble class and 85% max-width on assistant messages. Assistant content renders full-width with a 24px left margin reserved for a subtle role indicator (small dot + name in muted text on hover). User messages stay right-aligned with a light surface background, no border. Remove the 9px ALL-CAPS role-tag entirely. |
packages/web/ui/src/views/chat-view.ts |
Smart auto-scroll: replace unconditional _scrollToBottom() with an IntersectionObserver on a sentinel element near the bottom. Only auto-scroll if the sentinel is currently visible (user is reading the latest content). When user has scrolled up, show a floating "↓ N new" button that snaps to bottom on click. |
packages/web/ui/src/views/chat-view.ts |
Per-message hover actions: each assistant message gets a hover-revealed row at the bottom with Copy, Retry, Branch from here. Each user message gets Copy, Edit. Edit replaces the message content with a textarea + Save/Cancel; Save deletes all subsequent messages and re-runs from that point (POST /api/sessions/:id/edit-from). |
packages/web/ui/src/views/chat-view.ts |
Stream delta batching: accumulate onTextDelta chunks into a buffer flushed once per requestAnimationFrame. Today every chunk triggers a full Lit re-render. |
packages/runtime-node/src/index.ts |
New endpoint POST /api/sessions/:id/edit-from { messageIndex, newContent } truncates session history at messageIndex, replaces the user message at that index with newContent, and re-runs from there. Returns the same shape as /message. Required for the Edit action to be functional, not cosmetic. |
Visual changes (specifications)
- Assistant message: full width, no bubble, no border, 16px vertical spacing between turns.
- User message: right-aligned block with
--surface-2 background, --radius-md border-radius, max-width 70%, no border.
- Role indicator: 6px dot + name in
--text-muted, only visible on hover or when the message is focused.
- Per-message action row: 24px height, hidden by default, slides in on hover with 100ms opacity transition.
What must NOT change
Acceptance criteria
Performance target
- Stream delta batching: ≤ 60 Lit re-renders per second regardless of chunk arrival rate.
- Smart auto-scroll: zero observable scroll yanks when the user is > 100px above the latest message.
Out of scope
- Replacing the markdown engine (separate issue).
- Inspector rail / consolidating floating toggles (separate issue).
- Mobile chat layout (we will declare desktop-only).
- Voice / audio messages.
Labels: enhancement, priority/critical, ux, polish, source/audit
Summary
The chat surface is the most-used view in CrowClaw and currently looks like a 2018 iMessage clone: 85%-max-width bubbles for both user and assistant, ALL-CAPS role tags above every message, no per-message actions, dumb auto-scroll that yanks users back to the bottom mid-read.
Modern agent dashboards (Claude Code preview, Cursor, Cline, LangSmith) render assistant content as full-width left-aligned blocks with subtle role indicators, and provide per-message actions on hover. This issue overhauls the chat surface to that standard.
Target milestone: v0.8.1 (Dashboard sweep).
Why this matters (no shortcut)
role-tagat 9px is visual noise that adds zero information once a user knows the layout.Source / reference points
webview-ui/src/components/chat/ChatRow.tsx— full-width assistant blocks, hover-revealed action row.Scope
Files to change
packages/web/ui/src/views/chat-view.ts.bubbleclass and 85% max-width on assistant messages. Assistant content renders full-width with a 24px left margin reserved for a subtle role indicator (small dot + name in muted text on hover). User messages stay right-aligned with a light surface background, no border. Remove the 9px ALL-CAPSrole-tagentirely.packages/web/ui/src/views/chat-view.ts_scrollToBottom()with an IntersectionObserver on a sentinel element near the bottom. Only auto-scroll if the sentinel is currently visible (user is reading the latest content). When user has scrolled up, show a floating "↓ N new" button that snaps to bottom on click.packages/web/ui/src/views/chat-view.tsCopy,Retry,Branch from here. Each user message getsCopy,Edit. Edit replaces the message content with a textarea + Save/Cancel; Save deletes all subsequent messages and re-runs from that point (POST /api/sessions/:id/edit-from).packages/web/ui/src/views/chat-view.tsonTextDeltachunks into a buffer flushed once perrequestAnimationFrame. Today every chunk triggers a full Lit re-render.packages/runtime-node/src/index.tsPOST /api/sessions/:id/edit-from { messageIndex, newContent }truncates session history atmessageIndex, replaces the user message at that index withnewContent, and re-runs from there. Returns the same shape as/message. Required for the Edit action to be functional, not cosmetic.Visual changes (specifications)
--surface-2background,--radius-mdborder-radius, max-width 70%, no border.--text-muted, only visible on hover or when the message is focused.What must NOT change
<crowclaw-tool-call-trace>and<crowclaw-memory-stream>(shipped but never rendered) #224 follow-up, separate issue).Acceptance criteria
Performance target
Out of scope
Labels:
enhancement,priority/critical,ux,polish,source/audit