- Extract millis_u64 and save_json/load_json to shared crate root, replacing
identical copies in engine, parallel, human, conclusion, manifest,
checkpoint, and retro modules
- Remove exists() pre-checks before Manifest::load and Conclusion::load
in CLI runs scanner (TOCTOU anti-pattern)
- Merge duplicate cancel_run match arms for Queued/Starting/Running
- Change Conclusion.status from String to StageStatus enum
- Extract RunFilterArgs shared struct from RunsListArgs/RunsPruneArgs
- Replace hand-rolled formatDuration with formatDurationMs wrapper over
existing formatDurationSecs
- Extract duplicated ToolRow/ToolBlock components to shared tool-use.tsx
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Shared layout for setup, login, and callback pages with consistent
styling. Add GitHub mark icon to action buttons. Document dev server
commands in CLAUDE.md.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Introduce semantic CSS custom properties (page, panel, fg, line, overlay,
etc.) that swap values via .light/.dark class on <html>. An inline script
reads localStorage / prefers-color-scheme before first paint to prevent
flash-of-wrong-theme.
- ThemeProvider + useTheme hook in app/lib/theme.tsx
- Sun/Moon toggle in desktop nav and mobile menu
- .light overrides for all semantic tokens, accent colors (WCAG AA on
white), atmosphere gradient, @pierre/diffs surfaces, and chart variables
- Migrated ~30 files from hardcoded color classes to semantic tokens
- GraphViz diagrams use getGraphTheme() for light/dark hex maps
- Chart gridlines and axis labels use CSS custom properties
- Workflow card colors reference CSS vars for automatic theme switching
- Pierre diffs switch between pierre-dark and pierre-light themes
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sidebar "Run Configuration" and "Workflow Graph" links now navigate to
/runs/:id/configuration and /runs/:id/graph instead of away to the
workflow detail page. Extracts CollapsibleFile into a shared component.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>