fabro/lib
Bryan Helmkamp 6050b5fa4b
feat(web): Run Files tab empty/error/loading states, refresh, a11y
Completes Units 11 and 12 of the Run Files Changed plan:

- Empty-state taxonomy: distinct copy for total_changed==0 vs no
  recoverable diff
- LoadingSkeleton on initial loader navigation (shimmer respects
  prefers-reduced-motion via motion-safe:animate-pulse)
- ErrorBoundary export handling 401/403/503/429 and generic 5xx
- Refresh button + Toolbar with freshness indicator; relative
  timestamps tick every 10s
- SSE subscription to /runs/{id}/attach with a 500ms debounce that
  revalidates on checkpoint.completed, run.completed, run.failed
- After a revalidation completes, focus returns to the Refresh button
- j/k keyboard navigation over file rows, ignoring key presses while
  a text field is focused
- md (768 px) breakpoint collapses split to unified without writing
  any persisted preference
- #file=<encoded-path> deep link scrolls + focuses the matching row
  on mount; absent file surfaces a 5s toast; patch-only mode shows
  a toast explaining the limitation
- Touch targets on the Refresh button meet WCAG 2.5.5 AAA (44x44)

Refs plan docs/plans/2026-04-19-002-feat-run-files-changed-tab-plan.md

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-19 17:13:17 -04:00
..
crates feat(web): Run Files tab empty/error/loading states, refresh, a11y 2026-04-19 17:13:17 -04:00
packages/fabro-api-client feat(api): add GET /runs/{id}/files spec + RunFilesMeta schema 2026-04-19 15:33:24 -04:00