Files
boocode/openspec/changes/streaming-codeblocks-messages-components-v2/tasks.md
indifferentketchup 6fde7002aa docs: boocode-lift-analysis, openspec change docs, codesight cache, deps
- Add boocode-lift-analysis.md: comprehensive 30-repo lift matrix across 25 domains
- Add openspec/ change docs: domain2-code-intelligence, domain3-multi-agent, impeccable-wave, streaming-codeblocks
- Update .gitignore: .impeccable/, .omo/, bun.lock, DESIGN.md, PRODUCT.md
- Update dependencies in package.json + pnpm-lock.yaml
- Update .codesight/ analysis cache
2026-06-08 03:49:26 +00:00

4.1 KiB

1. Contracts: Channel delta frame schema

  • 1.1 Add channel-delta frame types to packages/contracts/src/ws-frames.ts: seq field, channel discriminator (text | tool_call | tool_result | status | error), and per-channel payload types
  • 1.2 Update WsFrameSchema Zod schema with the new channel frame variants
  • 1.3 Regenerate downstream types and verify ws-frames.test.ts passes

2. Streaming layer: Channel-based reducer

  • 2.1 Implement ChannelBuffer — per-channel out-of-order frame buffer with contiguous-seq flush logic
  • 2.2 Rewrite applyFrame in useSessionStream.ts as a channel-dispatch reducer that fans out to channel buffers then merges into StreamState
  • 2.3 Add mid-stream reconnection protocol: client sends last seq per-channel on reconnect; server sends replay deltas or fallback snapshot
  • 2.4 Handle edge cases: empty delta, duplicate seq, channel stall timeout (5s force-snapshot fallback)
  • 2.5 Test: manual WS frame injection with out-of-order deltas, reconnect mid-stream, verify state consistency — 29 tests, all pass

3. CodeBlock Pro

  • 3.1 Add line-number gutter rendering (1-indexed, right-aligned, muted color, hidden for ≥1000 lines)
  • 3.2 Add diff-gutter mode: detect diff- language prefix, parse +/- markers, render green/red gutter classes
  • 3.3 Add theme toggle button (github-dark / github-light) with session-persisted choice
  • 3.4 Add word-wrap toggle button (default no-wrap, toggle to wrap with CSS white-space: pre-wrap)
  • 3.5 Add collapsible mode: auto-collapse ≥30 lines, show first 15 + "Show N more" button with gradient fade
  • 3.6 Add inline copy with progress states (check/red-X revert after 1200ms)
  • 3.7 Add LRU cache (Map<code+theme+lang, html>, max 50 entries) to avoid redundant Shiki calls
  • 3.8 Test: each feature toggles independently, Shiki fallback to plain <pre> on error

4. MessageList v2

  • 4.1 Replace flat div with react-virtuoso Virtuoso component, configure followOutput="auto" and overscan=5
  • 4.2 Preserve isNearBottomRef scroll-tracking logic for followOutput gating
  • 4.3 Add stagger entrance animation (40ms stagger between new items, max 500ms, 0-duration with prefers-reduced-motion)
  • 4.4 Refactor tool-call grouping: per-group independent expand/collapse state (not all-or-nothing)
  • 4.5 Implement message pin/bookmark: URL hash #pin=<messageId>, pin indicator bar at top with "Jump to pinned"
  • 4.6 Add react-virtuoso to package.json dependencies
  • 4.7 Test: 500-message transcript renders with ~20 DOM nodes, scroll-to-bottom on new stream, pin/unpin works

5. Component hardening

  • 5.1 Create <MessageBoundary> component that catches render errors and shows "Rendering failed" + Retry button
  • 5.2 Wrap MarkdownRenderer in <MessageBoundary>
  • 5.3 Wrap CodeBlock in <MessageBoundary> with plain <pre> fallback on Shiki failure
  • 5.4 Add streaming skeleton placeholder: status === 'streaming' with empty content renders pulse bar
  • 5.5 Add keyboard navigation to ToolCallLine: Tab focus, Enter/Space toggle, Escape collapse, visible focus ring — tabIndex={0}, onKeyDown, focus-visible:ring-2
  • 5.6 Add keyboard navigation to ToolCallGroup: focusable header, same keybindings
  • 5.7 Audit ActionRow buttons: every interactive element has matching aria-label and title
  • 5.8 Create <MessageListErrorBoundary> top-level wrapper for catastrophic failures

6. Build and verify

  • 6.1 Run pnpm build and fix any type/compile errors — PASSES (tsc -b + vite build)
  • 6.2 Run npx tsc -p apps/web/tsconfig.app.json --noEmit and fix any type errors — PASSES (no errors)
  • 6.3 Smoke-test streaming with a real LLM turn (send message, verify streaming renders, tool calls, complete) — requires running LLM environment
  • 6.4 Smoke-test code blocks (diff highlight, line numbers, collapse, copy, theme toggle) — requires running environment
  • 6.5 Smoke-test message list (scrolling, pin, error boundary injection) — requires running environment