Originally created by: Akarsh-Hegde
Summary
- Adds a "What's New" modal to the dashboard: release history (highlights + fixes) and a roadmap, sourced from a small hand-curated
tray/src-tauri/resources/whats-new.json — deliberately separate from the auto-generated CHANGELOG.md, which is commit-level and too internal to show end users.
- Auto-opens once per app version after an update lands, via the same poll-tick pattern as the existing "Plan your day" auto-open. Defers itself whenever the dashboard window is already open, so it never collides with the sibling Plan auto-open on the same tick and never yanks the user off whatever they're doing.
- Always reachable via a new "What's New" item in the toolbar nav pill.
- Adds a "What's New per release" recipe to
CLAUDE.md's Common Tasks so the content doesn't drift out of sync with real releases.
Note for reviewers
The seeded roadmap content ("Idle & sleep detection", "Lighter local AI footprint") is a starting placeholder pulled from documented known-limitations — please confirm or replace it before this reaches users, since it reads as a product-facing promise.
Test plan
- [x]
cargo fmt --check / cargo clippy -- -D warnings / cargo test (tray crate) — all green, including new whats_new unit tests (JSON-shape guard + seen/unseen marker logic)
- [x]
npm run build (ui) — TypeScript + static export clean
- [x] Pre-push hooks (fmt, clippy, ui build/tests, cargo test, security audit) — all passed
- [x]
npm run tauri dev manual pass — auto-open firing, modal render, tab switching, nav-pill open, close-marks-seen (not exercised by CI or this session — WKWebView isn't automatable in this environment)
🤖 Generated with Claude Code
https://claude.ai/code/session_01MrJAJ3nnr5C1iyaKGV3BiY
Originally posted by: coderabbitai[bot]
✨ Finishing Touches
🧪 Generate unit tests (beta)
- [ ] Create PR with unit tests - [ ] Commit unit tests in branch `feat/whats-new-changelog`Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.
❤️ Share
- [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai) - [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai) - [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai) - [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code)Comment
@coderabbitai helpto get the list of available commands.Originally posted by: adityaharishch
Review: correctness-focused pass
Overall implementation is solid — no crashes or races found in the primary paths.
"Seen" tracking (
whats_new.rs:71-90,whats_new_auto_open.rs:71) — correct. Persisted to~/.meridian/last_seen_version(survives restart), exact-string-compared againstapp.package_info().version. Since app versions are always exact per release, this can't loop on a downgrade/rebuild, and an absent/mismatched file both correctly read as "unseen."Auto-open deferral vs. sibling "Plan your day" (
poll/mod.rs:141,146) — correct, not racy. Both run sequentially (.await) on the same tick;whats_new_auto_openruns strictly afterplan_auto_openand checksget_webview_window("dashboard").is_some(), so if Plan opens the dashboard first, What's New correctly sees it and defers.JSON parsing (
whats_new.rs:57-61) — build-time malformation is caught by thewhats_new_json_parsesunit test, but at runtimeparse_whats_new()uses.expect(...). If a malformedwhats-new.jsonever shipped (hooks bypassed, hand-edit, etc.), the firstget_whats_new()call (on modal open) would panic instead of degrading. Worth aserde_json::from_str(..).unwrap_or_else(|_| WhatsNewData { releases: vec![], roadmap: vec![] })fallback for defense-in-depth even though the test gate makes this low-risk in practice.Command/window wiring — fine,
get_whats_new/mark_whats_new_seen_cmdregistered inlib.rs'sinvoke_handler!, reuses the existing"dashboard"window capability — no gap.Seen-marking timing — minor inconsistency, not a bug: the auto-open path (
whats_new_auto_open.rs:71) marks the version seen before the window renders (documented as an intentional crash-safety tradeoff), which is subtly at odds with the doc comment atwhats_new.rs:92-94claiming seen "always reflects the version actually viewed." A crash between the marker write and the window rendering means that version's notes are silently never shown again (toolbar pill is the only remaining path to them) — worth tightening the comment to acknowledge this, even if the tradeoff itself is fine.Types — Rust/TS types match, except
RoadmapItem.statusis an unvalidatedStringin Rust vs. a TS literal union. A typo'd status inwhats-new.json(e.g."Planned"vs"planned") parses fine on the Rust side but silently rendersundefinedlabel/color via theROADMAP_STATUS_LABEL/_COLORlookups (WhatsNewModal.tsx:139,147) instead of erroring loudly.No blocking issues — nice work on the deferral logic against the sibling auto-open.
Originally posted by: Akarsh-Hegde
Addressed the review findings from @adityaharishch's correctness pass:
parse_whats_new()no longer.expect()s on a malformed embedded JSON. It now logstracing::error!and serves an empty{releases: [], roadmap: []}payload, so a bypassed hook or hand-edit degrades the modal gracefully instead of panicking on first open.RoadmapItem.statusis now a#[serde(rename_all = "kebab-case")]enum (InProgress | Planned | Considering) instead of a bareString. A typo'd value inwhats-new.jsonnow fails the JSON parse loudly (and falls into the same empty-payload fallback above) instead of silently renderingundefinedlabel/color on the frontend lookups. No frontend change needed — the wire format is unchanged.mark_whats_new_seen_cmd's doc comment to acknowledge that the auto-open path already writes the "seen" marker before the window renders, rather than implying this call is always what marks a version seen.Items [#1], [#2], and [#4] were reviewed and confirmed correct as-is, no change needed.
Also pushed the visual polish pass on
WhatsNewModal.tsx(accent bars, a "Latest" badge, colored bullet dots, staggered pop-in) that was finished but not yet committed from earlier manual testing — data/logic unchanged.Verified:
cargo fmt --check,cargo clippy -- -D warnings,cargo test(69/69 passing, including the new/existingwhats_newtests), andnpm run buildinui/all clean. Full pre-push suite (fmt, clippy, ui build + tests, cargo test, security audit) passed on push.Related
Tickets:
#1Tickets:
#2Tickets:
#4Ticket changed by: Akarsh-Hegde