>- Author the committed release-notes file for a stable Prisma Next release by enumerating the merged PRs since the previous stable `v*` tag, resolving triaging public-worthiness, and writing categorized notes — breaking changes first — into `docs/releases/v<version>.md` plus a mirrored `CHANGELOG.md` entry. Use when cutting a release, when the `publish-npm-version` skill reaches its "draft the release notes" step, when asked to "draft the release notes", "write the changelog for this release", "author docs/releases/v<x>.md", or "summarize what shipped since the last stable tag".
npx skills add https://github.com/prisma/prisma --skill draft-release-notes
This skill fires inside a stable-release cut. The release-cutting agent runs it from the release/<version> worktree that publish-npm-version created, with the target version already known, and produces the committed notes file that is the GitHub Release body (the publish workflow ships it verbatim via gh release create --notes-file docs/releases/v<version>.md). There is no --generate-notes fallback — the file you author here is what every consumer reads.
The skill is prose-driven: there is no codemod or script to run. You — the agent — do the enumeration, the Linear-context lookup, the triage, and the writing directly, the same way record-upgrade-instructions walks you through authoring an upgrade entry rather than running one for you.
Run this skill when all of the following hold:
latest) release is being cut — the target version $NEXT is known (computed by publish-npm-version step 1, e.g. 0.12.0).release/<version> worktree checked out at the bump commit (HEAD carries the bumped root version).docs/releases/v$NEXT.md does not exist yet (the PR-mode release-notes gate, pnpm check:release-notes --mode pr, fails the release PR until it does).Do not run it for -dev.N or -beta.N builds: those create no GitHub Release and are not gated. Do not run it to backfill notes for an already-shipped release — the convention starts from the first release cut after it landed.
These are project requirements, not style preferences. A draft that violates either is wrong even if everything else is perfect.
Linear is a summarization-context input only. You read a ticket to understand the user-facing outcome of an opaque PR title, then you write a fresh, public, user-facing sentence describing that outcome. You never paste ticket prose into the notes. Specifically, the following must never appear in docs/releases/*.md or CHANGELOG.md:
TML-NNNN: issue prefix or issue title — link the PR (#NNN) instead.If you cannot describe a change for a public audience without leaning on internal context, that is a signal the entry needs rethinking (or is internal-only and should be excluded — see the triage rubric), not a licence to paraphrase the ticket closely. When in doubt, describe only the externally-observable behaviour change.
Every entry links its PR (#NNN) so the human reviewer can check your one-line summary against the actual diff during the release-PR review. The human review is the backstop for triage and summarization judgment calls — write for that reviewer.
The range is "everything since the last latest release", so the lower bound is the most recent stable v* tag, excluding -dev.* / -beta.* pre-release tags:
PREV_TAG=$(git describe --abbrev=0 --tags --match 'v[0-9]*' --exclude '*-dev.*' --exclude '*-beta.*')
echo "$PREV_TAG" # e.g. v0.11.0
Equivalently, list and filter explicitly (useful when describe can't find an ancestor tag):
git tag --list 'v*' --sort=-v:refname | grep -Ev -- '-(dev|beta)\.' | head
The dev/beta exclusion matters: a -dev.N tag is cut on most merges, so an unfiltered "previous tag" would scope the range to a single PR. Filtering to stable gives the full set of changes since consumers last saw a latest release.
Take the commit set from git log and resolve each commit to its PR via gh:
git log --first-parent --oneline "$PREV_TAG"..HEAD
For each merged PR in the range, resolve the metadata you need with gh / gh api — PR number, title, author (login), labels, and whether the author is a first-time contributor:
# PRs merged in the range (adjust the search window to the range you enumerated)
gh pr list --state merged --base main --limit 200 \
--json number,title,author,labels,mergeCommit,mergedAt
# Or resolve a single PR by its merge commit:
gh api "repos/prisma/prisma-next/commits/<sha>/pulls" \
--jq '.[] | {number, title, author: .user.login, labels: [.labels[].name]}'
Use --first-parent so squash-merged PRs each show up as one commit; cross-check against gh pr list so you do not miss a PR or double-count.
When a PR title is an internal shorthand (TML-NNNN: <terse handle>), read the referenced Linear issue (via the Linear MCP) to understand what changed for the user. This is enrichment only — re-read Rule 1 before writing anything. Summarize the outcome in your own public words; cite the PR, never the ticket.
Decide, per PR, whether it earns a line in the public notes. The rubric biases toward a clean, user-facing changelog over exhaustiveness — the human PR review is the backstop for judgment calls.
Always include:
@prisma-next/* public API), CLI commands/flags, prisma-next.config.ts fields, the contract format (contract.json / contract.d.ts shape), on-disk migration shape, or error codes.Default-exclude unless user-relevant:
Excluded PRs are dropped silently — no "internal changes" catch-all section. If a default-exclude PR has a genuine user-facing consequence, include it and describe that consequence.
Write the entries under the fixed section order from docs/releases/README.md, omitting any section with no entries:
Breaking changes lead because they are what a reader scanning the notes most needs to see. Every line links its PR as an absolute markdown link — #NNN, never bare #NNN. Bare references only autolink inside the GitHub Release body; they render as plain text when the committed docs/releases/v<version>.md is read as a repo file or in PR review, so the explicit link form is what makes every reference work in every context.
A breaking change shipping in this release has a matching upgrade-instructions directory keyed to the minor transition, following the convention enforced by scripts/check-upgrade-coverage.mjs and authored via record-upgrade-instructions. The transition label is <prev.major>.<prev.minor>-to-<head.major>.<head.minor> — computed from the previous stable tag's minor and $NEXT's minor (e.g. v0.11.0 → 0.12.0 gives 0.11-to-0.12). Point the breaking note at the recipe directory rather than restating the migration.
Recipe links must be absolute, tag-pinned URLs — https://github.com/prisma/prisma-next/blob/v$NEXT/.... The notes file becomes the GitHub Release body via --notes-file, and the Release page does not reliably resolve repo-relative links, so a relative recipe path would publish as a dead migration link. Pinning to the release tag (/blob/v$NEXT/) means the link always resolves and never rots as the recipe tree evolves on main:
https://github.com/prisma/prisma-next/blob/v$NEXT/skills/upgrade/prisma-next-upgrade/upgrades/<prev.minor>-to-<head.minor>/https://github.com/prisma/prisma-next/blob/v$NEXT/skills/extension-author/prisma-next-extension-upgrade/upgrades/<prev.minor>-to-<head.minor>/A breaking change can affect one or both audiences — link whichever recipe directories exist.
If the recipe directory is absent, do not fail authoring: still list the breaking change and describe the required action inline. The missing recipe is check:upgrade-coverage's concern to enforce, not this skill's.
For a skipped-publish range (more than one minor in this release — see graceful degradation below), the recipe is a *chain* of consecutive transition directories (e.g. 0.11-to-0.12 + 0.12-to-0.13 for a v0.11.0 → 0.13.0 publish), mirroring how check-upgrade-coverage aggregates the chain. Anchor each breaking entry to the step that introduced it.
Prose tells a reader *that* something changed; a short before/after snippet shows them *what it looks like*, which is what they actually need to act. For the most code-visible breaking changes — contract-shape changes, authoring-surface changes, runtime-option or builder-API changes — nest a compact before / after example under the prose bullet.
<prev.minor>-to-<head.minor> upgrade recipe (authored via record-upgrade-instructions) already contains authoritative before/after migration code — lift the snippet from there so it stays accurate. If the change is only visible in the emitted contract.json / contract.d.ts, a minimal shape diff from the recipe or the PR diff is fine. prisma , never psl ), per the repo's authoring-surface convention. Use TS or JSON only when the change is genuinely a TS-surface change (a builder/runtime option, a consumer reading the emitted .d.ts) or an emitted-shape change with no PSL form.The format is the prose bullet, then the nested example:
- **<title>** — <what changed and what the reader must do; recipe link>. ([#<pr>](https://github.com/prisma/prisma-next/pull/<pr>))
Before:
…
After:
…
Preserve the "New contributors" credit that --generate-notes gave for free. Each first-time contributor gets a line naming the PR that welcomed them, with both the handle and the PR as absolute links:
- [@<handle>](https://github.com/<handle>) made their first contribution in [#<pr>](https://github.com/prisma/prisma-next/pull/<pr>)
Resolve first-time status from PR author metadata (e.g. gh api author_association of FIRST_TIME_CONTRIBUTOR / FIRST_TIMER, or by checking whether the author appears in the range before this PR).
Fill the docs/releases/README.md template into docs/releases/v$NEXT.md:
# v<version>
<optional one- or two-sentence summary of the release's theme>
## Breaking changes
- **<short title>** — <what changed and what the reader must do; link the upgrade recipe>. ([#<pr>](https://github.com/prisma/prisma-next/pull/<pr>))
Before:
<old shape>
After:
<new shape>
## Features
- <new capability>. ([#<pr>](https://github.com/prisma/prisma-next/pull/<pr>))
## Fixes
- <bug fix>. ([#<pr>](https://github.com/prisma/prisma-next/pull/<pr>))
## New contributors
- [@<handle>](https://github.com/<handle>) made their first contribution in [#<pr>](https://github.com/prisma/prisma-next/pull/<pr>)
Then prepend a ## v$NEXT entry to CHANGELOG.md, mirroring the notes-file body (newest-first). The CHANGELOG is a plain newest-first mirror — no second authoring format, no "Keep a Changelog" headers; copy the section bodies under the ## v$NEXT header at the top of the entry list (below the file's intro and the <!-- New release entries go here … --> marker).
Commit the notes file + CHANGELOG as their own commit on the release/<version> branch (keeping publish-npm-version's chore(release): bump commit clean), so the notes ride in the bump PR diff and satisfy the check:release-notes PR-mode gate. Use explicit staging and sign off:
git add docs/releases/v$NEXT.md CHANGELOG.md
git commit -s -m "docs(release): add release notes for v$NEXT"
Control then returns to publish-npm-version for the push + PR-open steps.
git describe finds no stable v* tag, fall back to the earliest tag or the repo root and note in the summary that this is the first curated release; enumerate the whole range.$NEXT (a minor was bumped in-tree but never shipped), enumerate across the *whole* range and treat breaking-change anchoring as a chain of consecutive transition directories, mirroring check-upgrade-coverage's skipped-publish handling.publish-npm-version runs pnpm install --frozen-lockfile --ignore-scripts, so the .claude/ / .agents/ skill mirrors may not be materialized there. This skill is invoked by reading its canonical path, skills-contrib/draft-release-notes/SKILL.md, which exists in the checkout regardless.--notes-file wiring (scripts/check-release-notes.mjs, .github/workflows/). This skill *produces* the file; the gate and workflow *consume* it.publish-npm-version and updating docs/oss/versioning.md — handled separately; this file is the authoring logic only..github/release.yml label config or any third-party release-notes tool. Categorization is done here, by reasoning over the diff + Linear context — not from PR labels or an external generator.Cutting v0.12.0 from origin/main (previous stable tag v0.11.0).
PREV_TAG=$(git describe --abbrev=0 --tags --match 'v[0-9]*' --exclude '*-dev.*' --exclude '*-beta.*') → v0.11.0.git log --first-parent --oneline v0.11.0..HEAD lists 14 merged PRs. gh pr list --state merged --base main --json number,title,author,labels,mergedAt resolves their metadata.TML-2536: contract deserializer seam. Read TML-2536 in Linear → the user-facing outcome is "contract deserialization now goes through an explicit adapter seam". Write that outcome in public words; cite #1240, not TML-2536.includeMany capability (#1234) → feature. A null-handling bug fix (#1242) → fix. First-time contributor @somebody on #1238.0.11-to-0.12. The recipe dir skills/upgrade/prisma-next-upgrade/upgrades/0.11-to-0.12/ exists in the checkout → the breaking note links it as a tag-pinned URL, https://github.com/prisma/prisma-next/blob/v0.12.0/skills/upgrade/prisma-next-upgrade/upgrades/0.11-to-0.12/. (If it were absent, the note would describe the required adapter migration inline instead.)0.11-to-0.12 recipe (a TS runtime change, so a ts fence). @somebody's contributor line, with absolute links: - @somebody made their first contribution in #1238.docs/releases/v0.12.0.md (every PR ref + handle an absolute link; the breaking entry carries a before/after):# v0.12.0
Contract deserialization gains an explicit adapter seam, and queries can now eager-load related records.
## Breaking changes
- **Contract deserialization requires an adapter seam** — deserialization now goes through an explicit seam adapter; existing code must register one. See the [0.11-to-0.12 upgrade recipe](https://github.com/prisma/prisma-next/blob/v0.12.0/skills/upgrade/prisma-next-upgrade/upgrades/0.11-to-0.12/). ([#1240](https://github.com/prisma/prisma-next/pull/1240))
Before:
const contract = deserializeContract(json);
After:
const contract = deserializeContract(json, { adapter: postgresAdapter });
## Features
- `includeMany` eager-loads related records in a single query. ([#1234](https://github.com/prisma/prisma-next/pull/1234))
## Fixes
- Null values in `returning()` projections no longer throw. ([#1242](https://github.com/prisma/prisma-next/pull/1242))
## New contributors
- [@somebody](https://github.com/somebody) made their first contribution in [#1238](https://github.com/prisma/prisma-next/pull/1238)
Then prepend the same body under ## v0.12.0 to CHANGELOG.md.
git add docs/releases/v0.12.0.md CHANGELOG.md && git commit -s -m "docs(release): add release notes for v0.12.0".docs/releases/README.md — the committed-notes-file convention, the no-fallback design, the section order, and the template this skill fills.CHANGELOG.md — the rolling newest-first mirror this skill prepends.publish-npm-version — the release-cut skill that invokes this one from the release/<version> worktree.record-upgrade-instructions — the breaking-change upgrade-recipe authoring flow whose upgrades/<prev.minor>-to-<head.minor>/ directories the breaking-change section anchors to.scripts/check-upgrade-coverage.mjs — the transition-label convention (<major>.<minor>-to-<major>.<minor>) and skipped-publish chain handling.docs/oss/versioning.md — the version contract and release procedure these notes are part of.Guide users through a structured workflow for co-authoring documentation. Use when user wants to write documentation, proposals, technical specs, decision docs, or similar structured content. This workflow helps users efficiently transfer context, refine content through iteration, and verify the doc works for readers. Trigger when user mentions writing docs, creating proposals, drafting specs, or similar documentation tasks.
Automatically creates user-facing changelogs from git commits by analyzing commit history, categorizing changes, and transforming technical commits into clear, customer-friendly release notes. Turns hours of manual changelog writing into minutes of automated generation.
Use when implementing any feature or bugfix, before writing implementation code
Use when you have a spec or requirements for a multi-step task, before touching code
Use when creating new skills, editing existing skills, or verifying skills work before deployment
Use when writing or improving README files. Not all READMEs are the same — provides templates and guidance matched to your audience and project type.
| Remove signs of AI-generated writing from text. Use when editing or reviewing text to make it sound more natural and human-written. Based on Wikipedia's inflated symbolism, promotional language, superficial -ing analyses, vague attributions, em dash overuse, rule of three, AI vocabulary words, negative parallelisms, and excessive conjunctive phrases.
Official Opentrons Protocol API for OT-2 and Flex robots. Use when writing protocols specifically for Opentrons hardware with full access to Protocol API v2 features. Best for production Opentrons protocols, official API compatibility. For multi-vendor automation or broader equipment control use pylabrobot.
Take prisma/draft-release-notes from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.
The instructions reference npm.
Without those the skill loads but fails at the first command.