Skip to content

Session view tails like tail -f; UI polish; session-replay design#6

Merged
lroolle merged 1 commit into
mainfrom
feat/session-live-tail
Jul 11, 2026
Merged

Session view tails like tail -f; UI polish; session-replay design#6
lroolle merged 1 commit into
mainfrom
feat/session-live-tail

Conversation

@lroolle

@lroolle lroolle commented Jul 11, 2026

Copy link
Copy Markdown
Member

1. Live-tail session view (the bug behind "refresh loses my place")

renderConvoPane ended with convoEl.scrollTop = 0 — a refresh of #/session/<key> landed at the top of a long conversation, and every live pair re-render yanked the scroll to top mid-read. Now, proper tail -f semantics:

  • Open/refresh in live mode → lands on the newest turn. Snapshots still open at the top (reviewing a finished session is reading, not tailing).
  • Re-renders stick to the bottom only while you're already there (60px slack).
  • Scrolled up reading history? Position is preserved exactly; new content shows a "↓ new activity" pill (click or scroll down to re-attach).
  • <details> folds you toggled survive re-renders (positional restore — turn mutations are tail-only), and the threads sidebar keeps its scroll.

2. Polish pass

Rules written down in docs/design/ui.md ("well-kept terminal": information first, one accent, keyboard first-class, motion budget ~zero). Applied here:

  • thin quiet scrollbars; accent ::selection + :focus-visible
  • status dot: green heartbeat = live, red = offline, blue = snapshot (labels now live/offline/snapshot)
  • / focuses the filter, Esc blurs it; keyboard hints in the empty state
  • prefers-reduced-motion disables the pulse and smooth scrolling

3. Session replay — designed, deliberately not built

docs/design/session-replay.md: jobs, what the wire already gives us (every trace is already a timeline — P1/P2 need zero capture changes; chunk timing is honestly absent until an opt-in P3), UX model (cursor over the session view, scrubber-as-minimap, idle compression, pair-id deep links), architecture (visibleAt(pairs, cursor) + existing buildSession), P1–P4 phasing, non-goals (no re-execution). Roadmap entries added to README + CHANGELOG.

Tests

147/147 (bun test), page-script parse + render smoke, compiled-binary smoke (served page carries the tail machinery). Not verified: real-browser scroll behavior — the logic is four branches over standard scroll metrics, but eyes on it after merge are welcome.

🤖 Generated with Claude Code

The conversation pane reset scrollTop to 0 on every render: a refresh of
a long live session landed at the top, and every live pair yanked the
scroll out from under the reader. Proper tail semantics now:

- open/refresh in live mode lands on the newest turn (snapshots still
  open at the top — reviewing a finished session is reading, not tailing)
- re-renders stick to the bottom only while you're already there
- reading history is never interrupted: scroll position is preserved and
  new activity surfaces as a "↓ new activity" pill instead
- folds you toggle survive re-renders (positional restore — turn
  mutations are tail-only), and the thread sidebar keeps its scroll

Polish pass, per the design language now written down in
docs/design/ui.md: quiet thin scrollbars, live/offline/snapshot status
dot with a heartbeat pulse, accent ::selection and :focus-visible, "/"
focuses the filter (Esc blurs), keyboard hints in the empty state,
prefers-reduced-motion respected.

Session replay is designed but deliberately not built:
docs/design/session-replay.md (jobs, wire-data reality, UX model,
architecture, P1–P4 phasing) + roadmap entries in README/CHANGELOG.
The core call: replay is viewer-side — every existing trace is already
a timeline, so P1/P2 need zero capture changes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@lroolle lroolle merged commit a01cbb8 into main Jul 11, 2026
1 check passed
@lroolle lroolle deleted the feat/session-live-tail branch July 11, 2026 06:06
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