Release Note Generation
smith-chem-wisc/MetaMorpheus
Toolkit for generating PowerToys release notes from GitHub milestone PRs or commit ranges.
Update the project CHANGES.md with issues from a given GitHub milestone, with correct categorization and references.
$ npx skills add penpot/penpot --skill update-changelog -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install penpot/penpot update-changelog --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/penpot/penpot.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/update-changelog .claude/skills/update-changelog && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "update-changelog" agent skill from https://github.com/penpot/penpot/tree/develop/.agents/skills/update-changelog into .claude/skills/update-changelog/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "update-changelog", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/penpot/penpot/tree/develop/.agents/skills/update-changelogType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add penpot/penpot --skill update-changelog -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install penpot/penpot update-changelog --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/penpot/penpot.git skills-src && mkdir -p .agents/skills && cp -r skills-src/.agents/skills/update-changelog .agents/skills/update-changelog && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "update-changelog" agent skill from https://github.com/penpot/penpot/tree/develop/.agents/skills/update-changelog into .agents/skills/update-changelog/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "update-changelog", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add penpot/penpot --skill update-changelog -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install penpot/penpot update-changelog --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/penpot/penpot.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/.agents/skills/update-changelog .cursor/skills/update-changelog && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "update-changelog" agent skill from https://github.com/penpot/penpot/tree/develop/.agents/skills/update-changelog into .cursor/skills/update-changelog/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "update-changelog", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/penpot/penpot.git --path .agents/skills/update-changelog--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add penpot/penpot --skill update-changelog -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install penpot/penpot update-changelog --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/penpot/penpot.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/.agents/skills/update-changelog .gemini/skills/update-changelog && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "update-changelog" agent skill from https://github.com/penpot/penpot/tree/develop/.agents/skills/update-changelog into .gemini/skills/update-changelog/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "update-changelog", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install penpot/penpot update-changelogInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add penpot/penpot --skill update-changelog -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/penpot/penpot.git skills-src && mkdir -p .github/skills && cp -r skills-src/.agents/skills/update-changelog .github/skills/update-changelog && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "update-changelog" agent skill from https://github.com/penpot/penpot/tree/develop/.agents/skills/update-changelog into .github/skills/update-changelog/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "update-changelog", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add penpot/penpot --skill update-changelog -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install penpot/penpot update-changelog --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/penpot/penpot.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/.agents/skills/update-changelog .opencode/skills/update-changelog && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "update-changelog" agent skill from https://github.com/penpot/penpot/tree/develop/.agents/skills/update-changelog into .opencode/skills/update-changelog/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "update-changelog", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
update-changelogUpdate the project CHANGES.md with issues from a given GitHub milestone, with correct categorization and references.
Update Changelog is an agent skill from penpot/penpot. Update the project CHANGES.md with issues from a given GitHub milestone, with correct categorization and references.
Its SKILL.md is about 3.5k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.
It sits in Development, covering Project management and Changelog and release notes. It works with GitHub. The repository describes itself as: Penpot: The open-source design platform for Product teams that need scalable collaboration. The licence is MPL-2.0.
9 steps, taken from the step headings in SKILL.md.
Read from SKILL.md and the folder at commit 10955f1. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Shell commands in SKILL.md call:
python3ghFrom the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md. Its commands use gh, which can reach the network depending on how they are called.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Update Changelog loads about 3.5k tokens when it runs. Until then it costs about 33 tokens; SKILL.md has 1,658 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from penpot/penpot at commit 10955f1, republished under its MPL-2.0 licence (© penpot). 1,658 words, ~3,494 tokens.
.claude/skills/update-changelog/SKILL.md (or your agent's skills folder).Update CHANGES.md with entries for all issues and PRs in a given GitHub
milestone. Each entry references the user-facing issue (not the PR) as the
primary link, with the fix PR inline on the same line.
gh CLI authenticated (gh auth status)scripts/gh.py for GitHub queries, scripts/changelog.py for changelog
checks (run python3 scripts/changelog.py <command> --help for usage)The version is typically a semver string like 2.15.3. Confirm with the user
if not specified.
# All closed issues (default)
python3 scripts/gh.py issues "2.16.0"
# Include open issues too
python3 scripts/gh.py issues "2.16.0" --state all
# Exclude entries that should not go in the changelog
python3 scripts/gh.py issues "2.16.0" --exclude "release blocker,no changelog"Exclusion rules (issue-level):
no changelog label — chore/refactor work, no entry neededrelease blocker label — blocked issues not yet ready for changelogTask issue type — internal chores, not user-facing; excluded by gh.py
(use --include-tasks to override)gh.py (use --include-rejected to override).
This status is independent of the GitHub issue state.Exclusion rules (PR-level): PRs with these labels stay out regardless of
their linked issue's labels: release blocker, no issue required.
Each entry carries number, title, state, issue_type, labels,
closing_prs, and project_status.
python3 scripts/gh.py issues "2.16.0" --exclude "release blocker,no changelog" --compare CHANGES.mdReturns only milestone issues not yet referenced in the changelog. Note: it compares issues only. For unreferenced merged PRs, use the cross-reference in step 8.
# One or more PR numbers (also: --file prs.txt, or --stdin)
python3 scripts/gh.py prs 9179 9204 9311
# All merged PRs in a milestone (default); --state all/open/closed for others
python3 scripts/gh.py prs --milestone "2.16.0"Returns number, title, body, state, merged_at, author, labels,
and closing_issues. Milestone mode uses paginated GraphQL (100 per page).
Use the Issue Type field (issue_type in the gh.py output). No separate
query is needed.
⚠️ CRITICAL: Never use labels or title emoji prefixes for categorization. Labels like
bug/enhancementand prefixes like:bug:/:sparkles:are often wrong or missing.issue_typeis the single source of truth.
issue_type value | Changelog section |
|---|---|
Bug | ### :bug: Bugs fixed |
Feature or Enhancement | ### :sparkles: New features & Enhancements |
Task | Exclude — internal chores, not user-facing |
null (not set) | Fallback to labels: bug label → bugs, otherwise enhancements |
Breaking changes override everything: an issue with the breaking change
label goes under ### :boom: Breaking changes & Deprecations, no matter its
issue type. This and release highlight below are the only label-based
rules — explicit exceptions to the "never by labels" principle above. The
:boom: subsection goes first in the version, before :rocket: (matching
the existing precedent).
Highlights come from the release highlight label: an issue with that
label also gets an entry under ### :rocket: Epics and highlights, on top of
its regular entry (usually :sparkles:). In the section being refreshed,
:rocket: lists exactly the labelled issues: never pick highlights yourself
and never keep an unlabelled entry there. Product decides the highlights by
labelling issues on GitHub, so a regeneration cannot undo that choice. Older
version sections are left as they are.
Community attribution: if the issue or its fix PR has the
community contribution label, add (by @<github_username>) on the entry
line, before the issue/PR references. Use the PR author (the author
field from step 4), not the issue author:
- Fix description of the bug (by @username) [#<ISSUE>](...) (PR: [#<PR>](...))Only closed issues are included, even if open ones are tracked in the milestone.
Pairing rules:
| Pattern | Changelog format |
|---|---|
| Closed issue + one or more fix PRs | Primary link = issue, PRs inline comma-separated |
| PR with no linked issue | Link the issue if a matching closed one exists in the milestone; otherwise skip (the issue is the changelog unit) |
| Closed issue with no fix PR in milestone | Link the issue directly, no PR reference |
False-positive associations: a PR may wrongly claim to close an issue from another context (ancient PR, cross-project reference). If titles are clearly unrelated or the PR predates the issue by years, treat it as a data glitch and skip it.
A closed issue may list closing PRs that were closed without merging (e.g. a superseded community PR). Only merged PRs go in the changelog:
python3 scripts/changelog.py check-merged <ALL_PR_NUMBERS>
# also accepts: --file prs.txt, or numbers via --stdinIf a closing PR is closed-unmerged, find the merged PR that superseded it (other PRs in the issue's closing list, similar titles, or pointers in the closed PR's timeline) and reference that one instead.
Advisories fixed in a release go in the changelog even though they are neither milestone issues nor PRs. The GHSA ID and description come from the user or the release notes — never from the milestone fetch.
- Fix <user-facing description> (https://github.com/penpot/penpot/security/advisories/GHSA-XXXX-XXXX-XXXX)Rules: place under ### :bug: Bugs fixed with no issue or PR link; do
not fetch or verify the URL (it may be draft/unpublished and 404); write
the description in imperative mood from the advisory title. These entries are
invisible to the automation — add them by hand, and in step 9 apply only the
backport/duplicate check to them.
Newest version goes at the top, right after the # CHANGELOG header:
## <VERSION>
### :boom: Breaking changes & Deprecations
- <breaking change or deprecation> [#<ISSUE>](https://github.com/penpot/penpot/issues/<ISSUE>) (PR: [#<PR>](https://github.com/penpot/penpot/pull/<PR>))
### :bug: Bugs fixed
- Fix description of the bug [#<ISSUE>](https://github.com/penpot/penpot/issues/<ISSUE>) (PR: [#<PR>](https://github.com/penpot/penpot/pull/<PR>))
- Fix another bug (by @contributor) [#<ISSUE>](https://github.com/penpot/penpot/issues/<ISSUE>) (PR: [#<PR>](https://github.com/penpot/penpot/pull/<PR>))
### :sparkles: New features & Enhancements
- Add new feature description [#<ISSUE>](https://github.com/penpot/penpot/issues/<ISSUE>) (PR: [#<PR>](https://github.com/penpot/penpot/pull/<PR>))Format details: entries start with - plus a short imperative description;
PR refs stay inline ((PR: [#<N>](<url>)), comma-separated for several);
(by @<username>) goes before the issue link; only include non-empty
sections; blank line between a section's last entry and the next title; never
duplicate an entry from an earlier version section (the earlier version wins
for backports).
Pre-flight checks — fix violations directly in CHANGES.md before writing
the new section. Reconcile every existing entry (any version section) and
every milestone candidate against the current milestone state (re-fetch, do
not trust cached data):
no changelog, release blocker) →
remove the entry.Task → remove the entry.breaking change label but
sits in another section) → move the entry to :boom:.:rocket: entry without the release highlight label, or a labelled issue missing from :rocket:) → remove
the :rocket: entry or add it (step 7b). The regular entry stays.Derive it from the issue title, not the PR title. Strip leading emoji
prefixes (:bug:, :sparkles:, :tada:) and describe the user-facing
behavior:
| Issue title | Changelog description |
|---|---|
Plugin API token methods fail with schema validation error on PRO | Fix Plugin API token methods failing with schema validation error on PRO |
Comment content is not sanitized before rendering, enabling stored XSS | Sanitize comment content on rendering |
Custom uploaded font family names are not sanitized | Sanitize font family names on custom uploaded fonts |
Insert the new version section right after the # CHANGELOG header with the
edit tool and enough context for a unique match.
:rocket: Epics and highlights from the labelList the milestone issues that pass step 2 exclusions and carry the
release highlight label:
python3 scripts/gh.py issues "2.16.0" --exclude "release blocker,no changelog" \
| python3 -c "import sys,json; [print(i['number'], i['title']) for i in json.load(sys.stdin) if 'release highlight' in i['labels']]"Create the subsection if missing (place it before ### :sparkles:) with one
entry per labelled issue, same text and references as its regular entry.
Every :rocket: entry MUST carry issue AND PR references. If no issue is
labelled, leave :rocket: out and tell the user: the highlights are
product's call, not the agent's. To change them, add or remove the label on
GitHub and re-run; never edit :rocket: by hand.
python3 scripts/changelog.py cross-ref "<MILESTONE>" [--changes CHANGES.md]Lists merged milestone PRs missing from the changelog section (decide per PR: add it or confirm its exclusion labels) and warns about CLOSED (unmerged) PRs in the milestone. GHSA entries never appear here — that absence is expected.
python3 scripts/changelog.py report "<MILESTONE>" [--changes CHANGES.md --output CHANGES-ISSUES.md]Overwrites CHANGES-ISSUES.md with the current state. Every number renders as
a full [#N](https://github.com/penpot/penpot/issues/N) or
[#N](https://github.com/penpot/penpot/pull/N) link.
An anomaly is a milestone mismatch or a :boom: mislabel (the changelog
pairing is misleading and a human must judge intent):
:boom: entry whose issue lacks the breaking change label. These stay
listed in the report and in the changelog: either label the issue or
move the entry to its regular section.:rocket: out of sync with the release highlight label. Step 6
pre-flight should have fixed it: if it shows up, re-run the workflow.Highlight gaps are warnings, not anomalies: missing :rocket: on a
released X.Y.0 (patches never carry highlights); :rocket: entry without
issue AND PR references. Gaps never count toward the anomaly total.
Anything else is a rule violation, not a report item: fix it in step 6 pre-flight. If one shows up in the report, re-run the workflow.
# CHANGELOG header.breaking change
label → :boom: first, and release highlight label → also :rocket:.no changelog and Task stay out.:bug: with only the advisory URL (see 5b).scripts/gh.py over raw gh api.check-merged); PR-level exclusions apply.cross-ref); watch for
false-positive PR-to-issue links.© penpot, MPL-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
Just SKILL.md in .agents/skills/update-changelog of penpot/penpot.
Open the folder on GitHubat commit 10955f1
Update Changelog next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Update Changelog this skillpenpot/penpot | 61k | — | ~3.5k | Automated safety check: Pass | MPL-2.0 | |
| Release Note Generationsmith-chem-wisc/MetaMorpheus | 109 | — | ~1.4k | Automated safety check: Pass | MIT | |
| Skia Analystmono/SkiaSharp | 5.6k | — | ~1.6k | Automated safety check: Pass | MIT | |
| Release Create Tracker Issuepytorch/test-infra | 113 | — | ~2.7k | Automated safety check: Pass | Custom licence | |
| Cutting A ReleaseTriliumNext/Trilium | 38k | — | ~3.2k | Automated safety check: Pass | AGPL-3.0 | |
| Mole CLI Release Flowtw93/Mole | 70k | — | ~2.6k | Automated safety check: Pass | GPL-3.0 |
smith-chem-wisc/MetaMorpheus
Toolkit for generating PowerToys release notes from GitHub milestone PRs or commit ranges.
mono/SkiaSharp
Analyze Skia features for SkiaSharp - produces a unified analysis of what shipped (upstream engine benefits, PR links, migration guides) and what's missing (impact/priority/effort scoring, hidden…
pytorch/test-infra
Generate (and optionally open) a PyTorch release tracker / cherry-pick tracking issue from a release announcement, like https://github.com/pytorch/pytorch/issues/180506.
TriliumNext/Trilium
A skill your agent uses when cutting, preparing, or debugging a Trilium release — bumping the monorepo version, tagging, or diagnosing a failed "Release" workflow run.
tw93/Mole
Runbook for assessing and executing a Mole CLI release: distribution channels, pre-flight checks, capital-V tags, build artifacts and the handoff to curated release notes.
jamiepine/voicebox
Writes or refreshes the Unreleased section of CHANGELOG.md as a themed narrative built from the commits, PRs and diff since the last version tag.
penpot/penpot
Hardens code against vulnerabilities. An agent skill from penpot/penpot.
penpot/penpot
PR flow — open a new PR for the current task branch (validates base branch, commits, issue and push state) or update an existing PR's title or description to match Penpot conventions.
penpot/penpot
A cat clone with syntax highlighting, line numbers, and Git integration - a modern replacement for cat.
penpot/penpot
Run local CI-style checks with ./scripts/ci (lint, tests, format) per monorepo module.
penpot/penpot
Write or rewrite text in ASD-STE100 Simplified Technical English.
penpot/penpot
Code review criteria — the five review axes, core principles, severity format, and verdict for reviewing code changes.
Works with
Categories
Update the project CHANGES.md with issues from a given GitHub milestone, with correct categorization and references. Update Changelog is an agent skill from penpot/penpot.md with issues from a given GitHub milestone, with correct categorization and references.
Update Changelog fits situations like: tasks that involve Project management; tasks that involve Changelog and release notes.
Run `npx skills add penpot/penpot --skill update-changelog -a claude-code`. Or copy the skill folder (.agents/skills/update-changelog in penpot/penpot) into .claude/skills/update-changelog in your project. Claude Code loads it when a task matches its description.
Run `npx skills add penpot/penpot --skill update-changelog -a codex`. Or copy the skill folder (.agents/skills/update-changelog in penpot/penpot) into .agents/skills/update-changelog in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add penpot/penpot --skill update-changelog -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/update-changelog, .gemini/skills/update-changelog, .github/skills/update-changelog and .opencode/skills/update-changelog in your project.
Going by SKILL.md and its folder, Update Changelog needs the command-line tools its instructions call (python3 and gh). Our summary lists: Python 3.
SKILL.md contains no URLs. Its commands use gh, which can reach the network depending on how they are called. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Update Changelog is published under the MPL-2.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 3.5k tokens (SKILL.md is roughly 14k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Update Changelog: Release Note Generation (smith-chem-wisc/MetaMorpheus, 109 stars), Skia Analyst (mono/SkiaSharp, 5.6k stars), Release Create Tracker Issue (pytorch/test-infra, 113 stars) and Cutting A Release (TriliumNext/Trilium, 38k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
penpot (a GitHub organization) maintains it in penpot/penpot, which has 60,869 GitHub stars. The repository holds 24 skills in this directory. The repository was last updated on October 9, 2026.
Source: penpot/penpot on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.