|
| 1 | +--- |
| 2 | +name: changelog |
| 3 | +description: Maintain FreeCut's weekly changelog with a rolling current entry. Use when (1) backfilling historical weeks into CHANGELOG.md and src/data/changelog.json (backfill mode), (2) adding new bullets to the rolling current entry as commits land (append mode), or (3) closing the week and promoting current into a tagged weekly release (rollup mode). Handles commit curation, deduplication, version assignment, tag creation, and keeping both markdown and JSON artifacts in sync. |
| 4 | +--- |
| 5 | + |
| 6 | +# Changelog skill |
| 7 | + |
| 8 | +FreeCut's changelog lives in two synchronized files: |
| 9 | + |
| 10 | +- **`CHANGELOG.md`** — human-facing, Keep-a-Changelog style, read on GitHub |
| 11 | +- **`src/data/changelog.json`** — typed, imported by the "What's New" dialog UI |
| 12 | + |
| 13 | +Both are generated from the same data. Always update both or neither. |
| 14 | + |
| 15 | +## Structure: weekly releases + one rolling current entry |
| 16 | + |
| 17 | +The changelog has two tiers: |
| 18 | + |
| 19 | +1. **`current`** — a single rolling entry for the in-progress week. It accumulates bullets as commits land, dedupes when the same feature is touched multiple times, and is shown in the UI as a "This Week" card. **Not tagged, not versioned with a final version number.** |
| 20 | +2. **`releases`** — one entry per completed week, newest first. Each has a version, a date, and a git tag. |
| 21 | + |
| 22 | +### Versioning: CalVer, Monday-start weeks |
| 23 | + |
| 24 | +- Format: `YYYY.MM.DD` where the date is the **Monday** that opens the week (Mon–Sun). |
| 25 | +- Tag: `v2026.04.13` (leading `v`, always). |
| 26 | +- A week "closes" on Monday morning of the following week. Rollup is **manually triggered**. |
| 27 | +- If a mid-week hotfix needs its own release, add `.N` suffix (`2026.04.13.2`). Rare. |
| 28 | +- `package.json` `version` field mirrors the most recent released version. |
| 29 | + |
| 30 | +Separate packages (future CLI/API) get their own semver and their own changelog under their package directory. This file is for the web app only. |
| 31 | + |
| 32 | +## Modes |
| 33 | + |
| 34 | +### Backfill mode |
| 35 | + |
| 36 | +Given a git range, produce historical weekly entries. |
| 37 | + |
| 38 | +**Process**: |
| 39 | +1. Walk PR merges in chronological order: `git log --merges --first-parent main --pretty=format:"%H|%ad|%s" --date=short <range>`. |
| 40 | +2. Group commits by week (Monday-start). For each week, union all non-merge commits across all PRs that landed that week. |
| 41 | +3. Apply curation rules (below), dedup features revisited within the week. |
| 42 | +4. Emit one weekly entry per week that has at least one user-visible change. Skip empty weeks. |
| 43 | + |
| 44 | +Pre-PR era (if any): collapse the entire foundation into a single initial release entry, dated the Monday of the week before first-PR week. |
| 45 | + |
| 46 | +### Append mode |
| 47 | + |
| 48 | +Triggered ad-hoc to update `current` as new commits land. |
| 49 | + |
| 50 | +**Input**: commits since last read of `current` (or `git log v<lastTag>..HEAD` if current is empty). |
| 51 | + |
| 52 | +**Process**: |
| 53 | +1. Walk new commits, applying curation rules. |
| 54 | +2. Merge with existing `current.groups` — **dedupe by title**. If a new commit refines or walks back a bullet already in current, edit the existing bullet rather than adding a duplicate. |
| 55 | +3. Update `current.date` to today. |
| 56 | +4. Do not create tags. Do not update `package.json`. |
| 57 | + |
| 58 | +### Rollup mode |
| 59 | + |
| 60 | +Triggered manually on Monday to close the previous week. |
| 61 | + |
| 62 | +**Input**: none (reads `current` and today's date). |
| 63 | + |
| 64 | +**Process**: |
| 65 | +1. Determine last week's Monday date → new version `vYYYY.MM.DD`. |
| 66 | +2. Move `current` into `releases` with that version and the Monday date. |
| 67 | +3. Empty `current` (or seed with any commits landed since Monday). |
| 68 | +4. Bump `package.json` `version` to the new release. |
| 69 | +5. Create annotated tag locally: `git tag -a v<version> <mergeCommitSha> -m "<version> — <highlights>"`. The tag should point at the last PR merge commit of the closed week, not today's HEAD (since dev continues on develop). |
| 70 | +6. **Do not `git push --tags`** — print the plan and wait for user confirmation. |
| 71 | + |
| 72 | +## Curation rules |
| 73 | + |
| 74 | +### Drop |
| 75 | + |
| 76 | +- Merge commits (`Merge pull request`, `Merge branch`) |
| 77 | +- `chore(...)` — including `chore(release)` |
| 78 | +- `ci(...)` |
| 79 | +- `test(...)` unless it documents notable test infra changes |
| 80 | +- `refactor(...)` when the scope is internal (stores, types, utils, deps adapters, chunk splits) |
| 81 | +- `deps` / `deps-dev` bumps unless major-version bumps with user-visible impact |
| 82 | +- **Follow-up fixes** — commits whose message matches `/address.*(review|PR|findings|feedback)|code review|follow-?up|fix.*(lint|typecheck|build|pre-existing)/i` AND land in the same week as a parent feature. Roll them into the parent bullet silently. |
| 83 | +- Reverts paired with a subsequent re-fix in the same week — skip both the revert and the offending commit; keep only the final correct implementation. |
| 84 | +- "Update src/..." auto-subject merges (GitHub web-edit artifacts) |
| 85 | +- Revisits: if the same feature is improved multiple times in one week, dedupe to one bullet describing the final state. Never list the same feature twice in one week. |
| 86 | + |
| 87 | +### Keep and rewrite |
| 88 | + |
| 89 | +- `feat(...)` — always, one bullet per distinct user-visible feature |
| 90 | +- `fix(...)` — if the bug was user-observable (rendering, playback, data loss, crash). Skip fixes for code that never shipped or was shipped and reverted in the same week. |
| 91 | +- `perf(...)` — if the impact is noticeable (measurable time saved, dropped frames recovered) |
| 92 | + |
| 93 | +### Rewrite style |
| 94 | + |
| 95 | +Commit messages are dev-speak. The changelog is user-facing. Rewrite: |
| 96 | + |
| 97 | +| Commit subject | Changelog bullet | |
| 98 | +|---|---| |
| 99 | +| `feat(timeline): add Alt+C as alternate split-at-playhead shortcut` | Split clips at playhead with Alt+C | |
| 100 | +| `perf(filmstrip): fill zoom gaps with cover frame background and full-set fallback` | Smoother filmstrip rendering when zooming the timeline | |
| 101 | +| `fix(preview): retry video with fresh blob URL on stale-blob load errors` | Preview no longer fails when media blobs expire | |
| 102 | +| `feat(storage): migrate to workspace folder via File System Access API` | Projects now live on disk in a folder you choose, not hidden browser storage | |
| 103 | + |
| 104 | +Rules of thumb: |
| 105 | +- Lead with the verb of the user experience, not the code change. |
| 106 | +- Drop internal names (stores, modules, workers) unless the user knows them. |
| 107 | +- If a bullet is only meaningful to developers, drop it. |
| 108 | +- Aim for ≤12 words per bullet. |
| 109 | +- For weekly entries, prefer thematic phrasing over commit-level phrasing ("Trim tools with smart zone detection" rather than listing each tool variant). |
| 110 | + |
| 111 | +### Grouping |
| 112 | + |
| 113 | +Within each weekly entry, group into: |
| 114 | +- **Added** — new features |
| 115 | +- **Fixed** — user-visible bug fixes |
| 116 | +- **Improved** — performance, polish, noticeable refactors |
| 117 | + |
| 118 | +Skip any group with zero entries. |
| 119 | + |
| 120 | +### Highlights |
| 121 | + |
| 122 | +Each weekly entry picks 1–3 highlights — the bullets a user would brag about. These appear at the top of the UI card. Skip highlights for weeks that are purely fixes. |
| 123 | + |
| 124 | +## File formats |
| 125 | + |
| 126 | +### `src/data/changelog.json` |
| 127 | + |
| 128 | +Matches types in `src/data/changelog-types.ts`: |
| 129 | + |
| 130 | +```ts |
| 131 | +export type ChangelogGroup = 'added' | 'fixed' | 'improved'; |
| 132 | + |
| 133 | +export type ChangelogItem = { |
| 134 | + title: string; // ≤12 words, user-facing |
| 135 | + scope?: string; // optional, e.g. "timeline" |
| 136 | +}; |
| 137 | + |
| 138 | +export type ChangelogEntry = { |
| 139 | + version: string; // "2026.04.13" for releases, "current" for rolling |
| 140 | + date: string; // ISO date — Monday for releases, today for current |
| 141 | + highlights?: string[]; // 1-3 bullets |
| 142 | + groups: Partial<Record<ChangelogGroup, ChangelogItem[]>>; |
| 143 | +}; |
| 144 | + |
| 145 | +export type ChangelogFile = { |
| 146 | + current: ChangelogEntry | null; // in-progress week |
| 147 | + releases: ChangelogEntry[]; // completed weeks, newest first |
| 148 | +}; |
| 149 | +``` |
| 150 | + |
| 151 | +### `CHANGELOG.md` |
| 152 | + |
| 153 | +```markdown |
| 154 | +# Changelog |
| 155 | + |
| 156 | +All notable changes to FreeCut. Versioning follows weekly CalVer: `YYYY.MM.DD` = the Monday of the release week. |
| 157 | + |
| 158 | +## [Current] — week of 2026-04-13 |
| 159 | +... |
| 160 | +## [2026.04.06] — week of 2026-04-06 to 2026-04-12 |
| 161 | +... |
| 162 | +``` |
| 163 | + |
| 164 | +Do **not** include PR links in weekly entries. Weekly entries aggregate many PRs; PR links add noise. Optionally link the GitHub compare view at the bottom of each entry: |
| 165 | + |
| 166 | +```markdown |
| 167 | +[Compare](https://github.com/walterlow/freecut/compare/v2026.03.30...v2026.04.06) |
| 168 | +``` |
| 169 | + |
| 170 | +## Git tag discipline |
| 171 | + |
| 172 | +- Always annotated (`git tag -a`), never lightweight. |
| 173 | +- Tag message = version + 1-line summary of highlights. |
| 174 | +- Tag points at the **last PR merge commit of that week** on `main`, not develop HEAD. |
| 175 | +- Print the plan (tag → sha → date) before creating tags; never push without the user asking. |
| 176 | + |
| 177 | +## When in doubt |
| 178 | + |
| 179 | +- Fewer bullets > more bullets. A wall of text is worse than missing a tiny fix. |
| 180 | +- If a week is 100 commits but they all revisit the same 3 features, produce 3 bullets. |
| 181 | +- If a commit scope is new and you don't know if it's user-visible, check what files it touches. UI components and public APIs = user-visible; stores/utils/tests = usually not. |
| 182 | +- A "current" entry that has grown past ~15 bullets is a sign you need a rollup. |
0 commit comments