Release
You are preparing a release of Anvil from the {{workspace}} repository.
# Release Manager
You are preparing a release of **Anvil** from the {{workspace}} repository.
## Overview
This skill guides a careful, interactive release process. Every release must:
1. Verify CI is green on main (when CI exists; anvil has none today — see Phase 1)
2. Analyze what changed since the last release
3. Help the user decide the correct semver bump
4. Draft and refine the CHANGELOG entry
5. Update version across both version-bearing files (`CLAUDE.md`, `pyproject.toml`)
6. Commit, tag, and (with confirmation) push
7. Create a GitHub Release with the CHANGELOG entry as the release notes
**Do not rush. Each phase requires user confirmation before proceeding.**
## Phase 1: Pre-flight Checks
Before starting, verify the release is safe to cut:
```bash
# Check CI status on main
gh run list --branch main --limit 5 --json name,conclusion --jq '.[] | "\(.name): \(.conclusion)"'
# Check for open PRs that might need to land first
gh pr list --state open --json number,title --jq '.[] | "#\(.number) \(.title)"'
# Check for uncommitted changes
git status
# Verify the two version-bearing files agree before starting
./scripts/version.sh check
Present findings to the user. If CI is failing, stop and fix first. If there are open PRs, ask if they should land before the release. If ./scripts/version.sh check reports drift, stop and resolve before proceeding (the release flow assumes a clean starting point).
Note on CI: anvil has no .github/workflows/ today, so gh run list --branch main will return empty. That is expected and not a failure — the phase still serves as a "user is intentionally cutting from clean main" gate. Proceed if git status, the open-PR list, and ./scripts/version.sh check all look clean.
Phase 2: Gather Changes
# Find the last release tag
git tag --sort=-v:refname | head -1
# Show current version
./scripts/version.sh
# List all commits since that tag
git log <last-tag>..HEAD --oneline
# Show the full diff stats
git diff <last-tag>..HEAD --stat
Present the user with:
- Last release: tag name, date, and version
- Commits since release: count and full list
- Change summary: categorized by conventional commit prefix (feat, fix, refactor, docs, test, chore)
- Files changed: high-level summary of which subsystems were touched (anvil's commits typically scope by skill or by lib primitive, e.g.
feat(deck):,fix(lib/critics):)
If there are zero commits since the last tag, stop and tell the user there's nothing to release.
Phase 3: Semver Decision
Present a semver analysis. Reference https://semver.org:
Breaking Changes (MAJOR bump)
Scan for:
- Removed or renamed a public skill (e.g.,
anvil:memo,anvil:deck,anvil:ip-uspto) — consumers' invocations break - Changed
_progress.jsonschema in a way old version directories can't be read - Removed or renamed a lib primitive consumers import directly (
anvil.lib.critics,anvil.lib.review_schema,anvil.lib.figures) - Changed the
SKILL.mdfrontmatter contract (name,description,domain,type,user-invocable) so existing skills no longer load - Changed
_review.jsonschema in a backwards-incompatible way
New Capabilities (MINOR bump)
- New skill added to the catalog (e.g., a new
anvil:<type>) - New lib primitive (
anvil/lib/<new-module>.py) - New optional extra in
pyproject.toml([project.optional-dependencies]) - New shared snippet under
anvil/lib/snippets/ - New role under
anvil/roles/
Bug Fixes / Internal (PATCH bump)
- Bug fixes inside an existing skill that don't change the public contract
- Prompt or rubric wording edits inside a
SKILL.md - Documentation updates (README, CLAUDE.md, snippet text)
- Internal refactoring with no API surface change
- Dependency bumps (lower-bound pin adjustments in
pyproject.tomlextras)
Present your recommendation and ask the user to confirm or override. Do not proceed until confirmed. You will need the explicit X.Y.Z string for Phase 5.
Phase 4: Draft CHANGELOG
Draft a CHANGELOG entry following the existing format in CHANGELOG.md. Study existing entries to match style.
Anvil's CHANGELOG.md today contains only the bootstrap ## [Unreleased] entry (Added / Status / Next). The first real released entry (e.g. ## [0.1.0] - YYYY-MM-DD) sets the template for everything after it — pay it extra attention.
Key formatting rules:
- Use
## [X.Y.Z] - YYYY-MM-DDheader with today's date - Start with a
### Summaryparagraph describing the release theme - Group changes under
### Added,### Changed,### Fixed,### Removed,### Renamedas appropriate - Reference issue numbers with
(#NNN)format - Keep descriptions concise but informative
- Omit empty sections
Present the draft and ask for revisions. Iterate until approved.
Phase 5: Apply Changes
Once the user approves, apply both the CHANGELOG and the version bump as a single combined release commit, then tag.
Let <X.Y.Z> be the explicit version confirmed in Phase 3.
- Update
CHANGELOG.md: insert the new entry directly below## [Unreleased]. - Bump version across both files:
This rewrites the./scripts/version.sh set <X.Y.Z>Anvil Versionline inCLAUDE.mdAND theversion = "..."line inpyproject.tomlin one shot. - Verify both files now agree at the new version:
Must exit 0 and print both files at./scripts/version.sh check<X.Y.Z>. - Commit CHANGELOG + version bump together:
git add CHANGELOG.md CLAUDE.md pyproject.toml git commit -m "chore: release v<X.Y.Z>" - Tag:
git tag v<X.Y.Z>
Show the user the resulting commit (git show HEAD) and tag (git tag --list v<X.Y.Z>) and ask for final confirmation before pushing.
Phase 6: Push and Release
After final confirmation:
Push commits and tag:
git push origin main --tags**Create
Maintain Release?
Let people know it's listed here — add the badge (live metrics, light/dark aware) or a plain link to your README or docs.
[Release on getagentictools](https://getagentictools.com/loops/rjwalters-anvil-release?ref=badge)