--- name: version-bump-advisor description: "Decide the semver bump (major, minor or patch) for a design system release from a diff or change list, with reasoning and a CHANGELOG entry. Triggers: what version bump, is this breaking, major or minor. Release notes and announcements: change-communication. Migration scripts: codemod-generator." allowed-tools: Read, Write, Grep, Glob, Bash(cat:*), Bash(ls:*), Bash(git diff:*), Bash(git tag:*), Bash(git log:*), Bash(npm pack:*), Bash(npm view:*) references: - ../../knowledge-notes/component-governance.md - ../../knowledge-notes/design-to-code-contract.md - ../../knowledge-notes/output-discipline.md --- # Version Bump Advisor ## Before you begin: verify references Confirm that every path in this skill's frontmatter `references:` exists relative to this SKILL.md. If any is missing, stop: the install is incomplete, usually because a flattening installer (for example `npx skills install`) dropped the repo-root `knowledge-notes/` directory. Tell the user to reinstall by a method in `1-INSTALL.md` and run `verify-install.sh` from the install root. Proceed without the references only if the user explicitly says to, and then say in the output that it was produced without the pack's reference material. ## Context Design system versioning is a persistent source of team friction. Breaking changes are called minor because they "just affect two components." Minor improvements trigger unnecessary major bumps because someone worries about change. And the reasoning is never written down, so every release prompts the same debate. This skill removes the subjectivity by applying a consistent classification framework to every change, then generating a changelog entry and reasoning that the team can trust. When the next release ships, there's a record of why it was a major and what consumers need to change. This is the pack's single source for semver calls. Other skills (`change-communication`, `contribution-workflow`, `deprecation-process`, `decision-record`) point here rather than classifying changes themselves. ## Steps ### 0. Establish the baseline If you have repository access, read the current `version` from the package's `package.json` (each published package, in a monorepo) so the recommendation names the actual next version. Then diff the exported surface between the last release tag and the change: exported component names, prop types and defaults from the published type definitions (`.d.ts` or the `types` entry), token names, CSS custom properties, and the `exports` map in `package.json`. A change list from the user is a starting point; the diff is what catches the removal nobody mentioned. If you can't read either, say so and classify from the change list alone. **Use the team's release tooling, not a parallel format.** If `.changeset/` exists, the recommendation is a changeset file (`.changeset/.md` with the package name, the bump and a one-line summary) and the changelog entry is what Changesets will generate from it. If `commitlint` or conventional commits are in use, phrase each entry as the commit type it maps to (`feat`, `fix`, `feat!`). If `release-please` or `semantic-release` is configured, say so: they decide the version from the commits, and this skill's job becomes checking that the commits are classified honestly. ### 1. Accept and Classify Input Accept input in any form: git diff output, PR description, a list of changes in natural language, or direct conversation about planned changes. For each change, classify it into exactly one category: - **Breaking (→ major):** removed prop, component, token, CSS custom property, variant, variant option or `exports` subpath; renamed API surface; a new *required* prop; a narrowed set of accepted values or types; a changed callback signature (different arguments, or a widened argument type consumers narrow on); changed default behaviour; a removed CSS class or a changed selector specificity; a DOM or ARIA change consumers' tests or styles query (a changed role, a removed `data-testid`, a changed element type); dropped browser or peer-dependency support - **Minor (→ minor):** new optional prop, new component, new token, new variant, new optional parameter, new CSS custom property, a widened set of accepted input values, added optional CSS class without removing existing classes - **Patch (→ patch):** bug fix (fix for unintended behaviour), documentation update, internal refactor with no API change, dependency update, performance improvement with no API change Be strict about classifications. Misclassifying a breaking change as a patch or minor is worse than over-bumping. If you are unsure, err toward breaking, and say which item is uncertain and what would settle it. ### 2. Determine the Semver Bump The highest-severity change wins. If there is one breaking change and five patches, the bump is major. If there are five minors and zero breaking changes, the bump is minor. Lead with the bump, then the composition by type so the team sees what drove it. Example: "Bump: major (2.4.1 → 3.0.0). 1 breaking change, 3 new features, 2 bug fixes." ### 3. Flag Edge Cases Design systems have scenarios that don't fit standard semver cleanly. Identify and resolve them: - **Breaking changes disguised as fixes:** A change labeled "bug fix" but that actually changes component behaviour (e.g., "fixed Button to now require an onClick handler"). This is breaking, not a patch. Reclassify. - **Pre-1.0 versions:** The semver spec says a 0.y.z version may change at any time and promises nothing. The convention most teams and npm's caret ranges follow is that a breaking change bumps the minor (0.4.0 → 0.5.0) and a feature or fix bumps the patch. Apply that convention, say it's a convention, and don't jump to 1.0 unless the team has planned it. - **Deprecation-only releases:** A release that deprecates a prop but does not remove it is minor (deprecation is additive). The removal is breaking and happens in a later major bump. Example: "@deprecated Use newProp instead" on oldProp in v2.4.0 is minor; removing oldProp in v3.0.0 is major. - **Peer dependency changes:** Changes to peer dependencies (e.g., "now requires React 18+", "drops support for Node 14") are often breaking and frequently miscategorised as patches. Reclassify if necessary. - **CSS specificity changes:** A change that keeps class names but increases specificity (e.g., `.button` becomes `.button-group .button`) can be breaking even if the API surface didn't change. It breaks overrides. Treat as breaking if consumers rely on specificity. - **Token value changes:** A changed token value (e.g., color-primary from #0047AB to #0052CC) defaults to minor for a deliberate visual change, or patch for a correction, because consumers referencing the token pick it up as intended. Treat it as breaking only if the team's stated versioning policy says so, or there's evidence consumers snapshot values (hardcoded copies, visual regression baselines they own, values baked into another platform's build). State which assumption the call rests on. Document which edge cases apply to this release, even if the answer is "none apply." ### 4. Generate Changelog Entry Produce a changelog entry in markdown format, organised by category, ready for CHANGELOG.md once its open placeholders are filled. The entries and figures below are illustrative: ``` ## [X.Y.Z] - YYYY-MM-DD ### Removed - **ComponentName:** prop `oldProp`. Use `newProp` instead. [migration: change `oldProp={value}` to `newProp={value}`] ### Changed - **ComponentName:** default `size` is now `sm` (was `md`). [migration: pass `size="md"` to keep the old look] ### Added - **ComponentName:** variant `outline` (`variant="outline"`). - **Tokens:** `color-secondary-light` for lighter secondary backgrounds. ### Deprecated - **ComponentName:** prop `oldSize`. Use `size` instead. Removal planned for the next major. ### Fixed - **ComponentName:** icon spacing now applies in all variants. - **Tokens:** `color-disabled` opacity corrected to meet the contrast baseline. ``` The headings are Keep a Changelog's (Added, Changed, Deprecated, Removed, Fixed, Security), which is what CHANGELOG readers and tooling expect; anything under Removed or Changed that breaks consumers gets a `[migration: ...]` note. Internal refactors and dev-dependency updates don't go in a consumer changelog. Keep descriptions to one line per item. ### 5. List the Migration Inputs for Breaking Changes The migration guide is written once, by `change-communication`. For every breaking change, give it one row: the before and after in a line each, and the rationale. | Change | Before | After | Rationale | |---|---|---|---| | Button prop rename | `