feat(chat): quick-return mobile header, in-stream needs-input note, jump-to-latest pill, merged composer #43
No reviewers
Labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Cloonar/coding-lab!43
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "afk/35"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Redesigns the embedded chat view (
web/src/routes/RunChat.tsx, route/runs/:id) so long assistant messages read comfortably on a phone and the composer reads as one polished control. Phone-first, single 640px breakpoint, no new dependencies — plain global CSS + SolidJS signals, with a single.chat-streamscroll listener driving both the header (§2) and the pill (§4).Closes #35
What changed (per the issue's five sections)
•••dropdown (📱 <640px): the wrapping header collapses to a single non-wrapping row[← back · title · ● state dot · •••]. The convo chip shrinks to a colored dot; Show/Hide thinking · Open/Attach · Stop run… (two-step confirm, contextual) move into an anchored dropdown reusingTopBar's menu + scrim + Escape pattern.•••is always present. ≥640px the inline header is unchanged (desktop controls kept viadisplay:contents).translateYwith no reflow (the stream reserves the band viapadding-top). Only user-initiated scroll toggles it — a programmatic-scroll guard keeps streaming autoscroll / follow-to-bottom / tap-to-latest from moving it. Logic lives in a pure, unit-testedquickReturnReduce()..chat-lifecycle, not a bubble), reactive onneeds_inputand only visible at the bottom. The composer collapses to just its input row.needs_input, taps smooth-scroll to the latest (which brings the header back). Pure, unit-testedpillState().DialogPanelis untouched.Design & review
Built via a design pass (scroll-controller / test-impact / DOM+CSS lenses, reconciled) and an adversarial multi-dimension review whose 8 confirmed findings were all fixed: the mobile header title/spacer flex split, the hidden overlay header vs. the error banner (z-index), scrim dimming the header (portaled), three menu a11y nits, and two test-coverage gaps. One finding (350ms smooth-scroll guard) was verified as a non-issue.
The
ErrorBannernow sits above a new.chat-bodypositioning wrapper (so the mobile overlay header can't cover it); on desktop it renders just above the header row rather than just below — a small, benign, documented placement change.Testing
npm run lint·npm run format:check·npm test·npm run build— all green.quickReturnReduce,pillState) and +12 component tests covering the•••dropdown (open/close/Escape, contextual Stop, thinking toggle), the state dot, the in-stream needs-input line (present / last-child / reactive / rewording), and the pill DOM contract (mounted / hidden-inert / reveal / emphasis /onJump).No API / SSE / schema / backend change. This evolves the chat UI within ADR-0016/0019/0022's design language with no ADR conflict (it preserves the ADR-0022 Send↔Interrupt morph and the ADR-0019 two-step Stop); a codifying ADR could be a maintainer follow-up if desired.
🤖 Generated with Claude Code