Feat/UI redesign 2.0
Your work logs itself. Meridian watches what you build - no prompts, no timers - classifies every session into the right task, and auto-updates Jira, Linear, and GitHub Issues. All data stays on your machine.
Brought to you by:
prateekbhoge320
Originally posted by: adityaharishch
Response to review
Thanks for the thorough pass. Addressing everything below.
Blocking issues — fixed
#1 File size (TodayView.tsx 512 lines)
Extracted
buildStory→ui/lib/story.tsand the today-specific timeline component →ui/components/views/TodayTimeline.tsx(a separate name from the existingui/components/DayTimeline.tsxused by the sessions page). TodayView.tsx is now 349 lines.#2 Shadow-copy tests
Created
ui/lib/fmt.tsas a pure, no-React module containingfmtDur,fmtDurDecimal,fmtClock,hexA, andCATS.atoms.tsxnow imports and re-exports from there;theme-context.tsximportshexAfrom there.redesign.test.tsnow imports from the canonical sources instead of re-implementing inline. Addedui/__tests__/story.test.tswith 10 tests coveringbuildStory.Should-fixes — all addressed
#3 Timezone bug in
week/route.ts— Agreed, fixed. Replaced the naivelocalDayRangewithlocalDayBoundsfrom@/lib/date-utils, same as every other route.#4
catsin hours vs seconds — Agreed, fixed. Route now accumulates seconds;WeekView'sDayBartooltip andCategoryBarsdivide by 3600 for display.#5 QueueView dismiss no persistence — Agreed the current behavior is misleading. Wiring a full
PATCH /api/queue-reviewendpoint is out of scope for this PR (needs a new DB column + tagger changes). Added a "resets on refresh" note in the header so users know. Will track the persistence work separately.#6 Dead buttons in TodayView + TasksView — Fixed. Added
disabled+opacity-50 cursor-not-allowedto Skip/Log/Edit draft/Assign buttons.#7 Dead
export { AppGlyph }in TasksView — Removed.#8
Record<string, unknown>DB row types — Partially addressed.week/route.tsnow has typed query results. On the other three routes (today,tasks,queue-review): they already cast all fields explicitly at the mapping stage and produce fully-typed output interfaces (TodaySession,TaskSummary,QueueItem). TheRecord<string, unknown>is only the intermediate DB row — not a typed output boundary. Adding aDbRowinterface here would just alias the sameRecord<string, unknown>with named fields. Happy to add it if you feel strongly, but I don't think it buys safety beyond what the explicit casts already provide.#9
eslint-disablein TasksView — Fixed. Split into two effects: one for fetch (no deps), one for setting the default selection (deps[data, selected]).#10 Sidebar
ActiveInfotype mismatch — Respectfully pushing back on "doesn't match":ActiveInfo's four fields (app_name,started_at,elapsed_s,category) are all present and correctly typed in the actualActiveSessionRowresponse. TypeScript's structural typing means this wasn't a runtime bug. That said, the hand-rolled interface is still a drift risk, so I've narrowed it toPick<ActiveSessionRow, 'app_name' | 'elapsed_s'>(only the two fields actually rendered inActiveSessionPill).#11 Hardcoded DAY_START/DAY_END — Fixed. The extracted
TodayTimelinecomponent derives the window from actual min/max timestamps in the day's data (±1 hour padding), falling back to 7–19 when there's no data.Nits
// ── Foo ──) removed from TodayView, redesign.test.ts — per CLAUDE.md convention.const story = buildStory(data)hoisted abovereturn.pushToBucketmoved to module level (no longer recreated on every render).next/font/googleself-hosts at build time and is the right long-term fix, but swapping fonts requires verifying the rendered weight/style matches. I'll open a follow-up issue rather than risk a visual regression here.CommandBararrow-key navigation: noted, will track.Cardcatch-all props: noted, will track.All 89 UI tests pass.
bun testoutput:89 pass, 0 fail.Ticket changed by: Akarsh-Hegde
Originally posted by: adityaharishch
🎉 This PR is included in version 1.0.0 🎉
The release is available on:
v1.0.0Your semantic-release bot 📦🚀