1---2name: release-notes3description: Write release notes for Meru. Use when drafting or updating GitHub Release notes, changelogs, or "what changed" summaries for a release.4---56# Release notes78## Gather the changes910- The release being written is the one the version commit at `HEAD` bumps to — a commit whose subject is the bare version number, matching `version` in `package.json`, such as `3.58.0` or `3.60.0-beta.1`, tagged `v3.58.0` or `v3.60.0-beta.1`.11- The source is the `[Unreleased]` section of `CHANGELOG.md` as it stood before the version commit, which emptied it: `git show HEAD~1:CHANGELOG.md`. Every change that landed since the last release added its line there in the same commit, so the section is the draft: read it in full before anything else.12- Cross-check it against the commit log, because a line can be missed. The range runs from the previous release's tag to the version commit, and which tag counts as previous depends on the channel:13 - **Stable** — the last stable tag, from `gh release list --exclude-pre-releases -L 1`. Never `gh release list -L 2`, which picks up an interleaved `-beta.N` tag and truncates the notes to the tail of the cycle.14 - **Beta** — the last release of any kind, from `gh release list -L 1`, so each prerelease covers only what's new since the previous one.15 - Triage the log on subjects alone and drop comment and docs edits, refactors, tests, CI, and dependency bumps other than Electron. For a surviving commit with no changelog line, `gh pr view <number>` says what changed for the user; fall back to `git show`. Add the missing bullet to the notes and mention it in the review, since the commit that should have carried it didn't.16- A stable that promotes a cycle of beta releases must be complete for the users who never saw a prerelease. `[Unreleased]` is emptied at every release, prereleases included, so for a stable that follows betas also read the notes of those beta releases (`gh release view v<version> --json body -q .body`) and fold their bullets in. That repetition is intended.17- Don't trust a commit message's scope — verify the actual fix from the diff. Messages often name a single platform or quote a GitHub issue title, such as "fix window position resetting after Windows reboot", when the underlying bug affects every platform. Only scope a note to a platform with `**macOS:**` or `**Windows:**` when the code confirms the fix is platform-specific.18- Describe the end state at the tag, not the journey. A feature that landed and was then renamed, redesigned, or extended over several commits in the same release gets one bullet describing how it works now, however many changelog lines it accumulated.19- Drop fixes to code newly introduced in the same release — a bug that only existed between merge and tag is invisible to users upgrading from the previous public release.20- Skip changes that aren't user-observable given the constraints already in place. Don't mention gating a feature behind Pro, for example, if free-tier limits already put it out of reach.2122## Structure2324- Sections are `## Added`, `## Changed`, `## Fixed`, `## Internal Changes`, in that order, omitting unused ones. Lead with `## Changed` when a change is needed to understand `## Added` — v3.58.0 opened with the Google Apps → Workspace Apps rename because every new tab bullet below it says "Workspace Apps".25- Classify each change correctly:26 - `Added` — new feature or capability27 - `Changed` — intentional change to existing behavior, rename, or default28 - `Fixed` — resolves a bug or unintended behavior, such as windows stacking awkwardly29- `## Internal Changes` is for Electron upgrades and little else — bumping Electron pulls in a new Chromium, which carries performance and security improvements users benefit from. Other dependency, CI, or tooling upgrades aren't user-observable, so omit them: TypeScript, dnd-kit, electron-builder, build config, and `CLAUDE.md` all fall here. If Electron wasn't upgraded, there's no `## Internal Changes` section at all.30- Group related bullets next to each other, keeping all the Workspace Apps changes together, for example.31- Use sub-bullets for details: options list, defaults, keyboard shortcuts, and behavior nuances. Always state the default for new options.3233## Write the notes3435- Write user-facing, not commit-facing. Describe what changed for the user, not the commit history or implementation. Merge multiple commits for one feature into a single bullet.36- Lead with outcome, not mechanism. "New windows no longer stack on top of each other" beats "Added cascading window positioning". Avoid internal jargon like "patch-burst" or "debounce".37- Never reference PR numbers, issue numbers, commit hashes, or contributor handles. Commit subjects carry a trailing `(#792)` — drop it.38- Say what carries over whenever a rename, move, or behavior change could read as lost settings or data: "Your existing settings carry over automatically", "Your existing Gmail zoom level is preserved".39- When reverting or removing a previously released feature, include the reason inline so users who relied on it understand the change.40- Prefix Pro-only features with `**Meru Pro:**`.41- Reference settings paths in backticks, with an ellipsis character rather than three dots: `` `Settings… → Section → Option` ``.42- Wrap keyboard shortcuts in `<kbd>` tags and write them per platform: `<kbd>Cmd</kbd>+<kbd>F</kbd> on macOS, <kbd>Ctrl</kbd>+<kbd>F</kbd> on Windows and Linux`.4344## Review4546- Print the drafted notes in chat and ask the user whether anything should be added, removed, or reworded before they go onto the release. Ask every time, including when folding changes into notes that already exist.47- Apply the feedback, print the revised notes, and ask again. Only write once the user is happy with them.4849## Output5051- Release notes live only on GitHub Releases. `CHANGELOG.md` holds nothing but the `[Unreleased]` draft — it never gets a versioned section, and the finished notes aren't written anywhere inside the repo. Match the style of recent published releases at https://github.com/zoidsh/meru/releases.52- Write the finished notes onto the release for the version commit's tag: `gh release edit v<version> --notes-file <path>`, with the notes in a temporary file outside the repo. Pass a file rather than `--notes` so the markdown, backticks, and `<kbd>` tags survive the shell.53- Read the current body first with `gh release view v<version> --json body -q .body`. When the release already has notes, fold the changes into them — editing replaces the body wholesale, so always pass the complete set of notes, never just the new bullets.54- If no release exists for the tag yet, stop and ask — creating one triggers the build-and-publish workflow, which isn't this skill's job.55- Share the release URL after writing.