with one click
release
// Worktrunk release workflow. Use when user asks to "do a release", "release a new version", "cut a release", or wants to publish a new version to crates.io and GitHub.
// Worktrunk release workflow. Use when user asks to "do a release", "release a new version", "cut a release", or wants to publish a new version to crates.io and GitHub.
Worktrunk-specific guidance for tend CI workflows. Adds codecov polling, Rust test commands, labels, and review criteria on top of the generic tend-* skills. Use when operating in CI.
CLI output formatting standards for worktrunk. Load before editing any code that calls warning_message, hint_message, error_message, info_message, eprintln, or println, or that produces strings the user will see (CLI help, progress UI, snapshot text). Documents ANSI color nesting rules, message patterns, and output system architecture.
Guidance for Worktrunk (the `wt` CLI) — git worktree management, hooks, and config. Load when editing .config/wt.toml or ~/.config/worktrunk/config.toml; adding, modifying, or debugging hooks (post-merge, post-start, pre-commit, pre-merge, post-switch, etc.); configuring commit message generation or command aliases; or troubleshooting wt behavior. Also answers general worktrunk/wt questions.
Create a new worktrunk worktree (optionally in another repo) and switch this session's working directory into it. Use when launching a session that should work in its own worktree (e.g. `/wt-switch-create my-branch -- <task>`, or `/wt-switch-create my-branch ~/workspace/other-repo -- <task>`), or mid-session to move work into a fresh branch.
| name | release |
| description | Worktrunk release workflow. Use when user asks to "do a release", "release a new version", "cut a release", or wants to publish a new version to crates.io and GitHub. |
| metadata | {"internal":true} |
cargo run -- hook pre-merge --yesversion in Cargo.tomlcargo semver-checks check-release -p worktrunk (install with cargo install cargo-semver-checks --locked if missing). If it reports breaking changes, the bump must be minor (pre-1.0) or major (post-1.0). See "Library API Compatibility" below.cargo release X.Y.Z -p worktrunk -x --no-publish --no-push --no-tag --no-verify --no-confirm && cargo check
This bumps Cargo.toml and Cargo.lock, then auto-commits. We'll reset this commit in step 9 to fold in the CHANGELOG.## X.Y.Z section at top with changes (see MANDATORY verification below)git reset --soft HEAD~1 && git add -A && git commit -m "Release vX.Y.Z"
/gpk — opens a PR, waits for CI, merges via PR (preserves worktree)/gpk squash-merges, the local branch HEAD is not the commit on main. Tag the PR's merge commit explicitly so the tag is reachable from main:
MERGE_SHA=$(gh pr view --json mergeCommit --jq '.mergeCommit.oid')
git tag vX.Y.Z "$MERGE_SHA" && git push origin vX.Y.Z
release.yaml. Launch a ci-reporter agent to monitor the run through to completion (avoid gh run watch — it can hang); the run ID comes from:
gh run list --workflow=release.yaml --event=push --branch=vX.Y.Z --limit 1 --json databaseId --jq '.[0].databaseId'
release.yaml builds binaries and publishes to crates.io, Homebrew, and winget automatically.
Worktrunk's worst failure is silently destroying a user's work. The per-PR review (running-tend, "Data-Loss Surface") is the first gate; the release is the second, where the whole diff since the last release is visible at once.
This review optimizes for recall: find every change that could touch the deletion surface, accept false positives, then adjudicate each candidate. Missing one real loss path costs far more than reviewing a false alarm.
A keyword grep alone is insufficient. It finds only what someone thought to pattern-match, and an agent handed the grep anchors on it and inherits its blind spots. So fan out independent finders, most of them without the grep, and analyze every candidate they surface.
Launch 3-5 finder subagents in parallel over the cumulative diff (git log v<last-version>..HEAD -p) and the code it touches, including anything that calls into or is called by the changed code. Each works independently: do not let them share findings during this phase, and do not collapse them onto one method. Each returns candidate locations with a one-line reason, erring toward over-reporting.
Give each a distinct charter. At least two receive no grep and no keyword list, so they reason from the code instead of pattern-matching:
plugins/*/hooks/hooks.json, hooks/hooks.json, hooks/wt.sh, and skill or alias examples users copy. Flag any new or altered invocation that removes or force-overwrites anything.src/commands/process.rs, sits outside src/git/).
git log v<last-version>..HEAD -p \
| grep -nE -- '--force-delete|--force| -D| -f |branch -[dD]|worktree remove|reset --hard|checkout -f|clean -[fdx]|remove_dir_all|remove_file|rm -rf'
Pool the candidates, dedupe, and analyze each against the data-safety invariants in CLAUDE.md and the FAQ "What can Worktrunk delete?" inventory: does it preserve data on failure, require explicit consent for destructive ops, and avoid silent side-effect deletion? Mark each real risk / acceptable / needs change, with the reasoning.
Surface the full adjudicated list and get explicit sign-off before tagging. Do not tag a release with an unresolved deletion-surface candidate, even if it looks acceptable.
Check commits since last release for missing entries:
git log v<last-version>..HEAD --oneline
IMPORTANT: Don't trust commit messages. Commit messages often undersell or misdescribe changes. For any commit that might be user-facing:
git show <commit> --stat to see what files changedCommon patterns where commit messages mislead:
Notable changes to document:
Section order: Improved, Fixed, Documentation, Internal. Documentation is for help text, web docs, and terminology improvements. Internal is for selected notable internal changes (not everything).
Within each section, order by impact:
Breaking changes: Note inline with the entry, not as a separate section:
- **Feature name**: Description. (Breaking: old behavior no longer supported)
Skip: internal refactors, test additions (unless user-facing like shell completion tests).
Combine related bullets. Several PRs that share a theme — e.g. three perf changes that together account for one user-visible speedup — belong in one bullet, not three. The reader cares about the net change, not the PR boundaries. Cite all the PRs in the trailing ([#a](...), [#b](...), [#c](...)) list.
Be brief. Each bullet should communicate the user-visible change in 1–3 sentences. Internal-section bullets in particular should be terse — usually one sentence. Drop the "why we did it this way" details unless they materially affect how the user thinks about the change. Code examples and exhaustive Cmd::stream / OnceCell / DashMap-style internals usually don't belong; they live in the PR description.
No editorial framing. Describe what changed, not what was wrong with the previous decision in subjective terms. Avoid words like "sledgehammer", "ugly", "noisy", "wrong" applied to past code. State the prior behavior neutrally and the new behavior plainly.
Good: "Removed .pi/ from the default excludes list; users who need it can add it via [step.copy-ignored]."
Bad: "Removed .pi/ — a sledgehammer fix from an unrelated debugging session that has no place as a project-agnostic default."
For any changelog entry where an external contributor (not the repo owner) authored the commit, add credit with their GitHub username:
- **Feature name**: Description. ([#123](https://github.com/user/repo/pull/123), thanks @contributor)
Find external contributors:
git log v<last-version>..HEAD --format="%an <%ae>" | sort -u
Then for each external contributor's commit, find their GitHub username from the commit (usually in the email or PR).
When a fix or feature addresses a user-reported issue in this repo, thank the reporter — not just the PR author. Users who take time to report bugs, request features, or provide reproduction steps deserve recognition. (Don't credit reporters from upstream/external repos — only issues filed here.)
- **Feature name**: Description. ([#456](https://github.com/user/repo/pull/456), thanks @reporter for reporting)
For fixes that reference issues:
- **Bug fix**: Description. Fixes [#123](https://github.com/user/repo/issues/123). (thanks @reporter)
Finding reporters — do ALL three steps:
Issues may have been filed months before the fix. Bug reports also appear as PR comments, not just issues. These steps are complementary; each catches things the others miss.
Extract every issue/PR reference from every commit (PRIMARY):
git log v<last-version>..HEAD --format="%B" | grep -oE '#[0-9]+' | sort -un
For each referenced number: run gh issue view N --json title,author,state. This catches issues filed months ago — the most commonly missed credits.
Check PR comments for bug reports (catches reports that never became issues): For feature PRs referenced in commits, check comment threads for users reporting problems:
gh pr view NNN --json comments --jq '.comments[] | "\(.author.login): \(.body[:150])"'
Survey every issue opened or closed since last release (catches unreferenced matches):
git log -1 --format=%cs v<last-version>
gh issue list --state all --search "created:>=<date>" --json number,title,author --limit 100
gh issue list --state closed --search "closed:>=<date>" --json number,title,author --limit 100
Cross-reference every title against changes in this release.
When to credit:
Skip credit for: issues opened by the repo owner, trivial reports, or issues that were substantially different from what was implemented.
For major features with dedicated documentation, include a docs link. Use full URLs so links work from GitHub releases:
- **Hook system**: Shell commands that run at key points in worktree lifecycle. [Docs](https://worktrunk.dev/hook/) ([#234](https://github.com/user/repo/pull/234), thanks @contributor for the suggestion)
Link when there's substantial documentation the user would benefit from reading — new commands, feature pages, or Tips & Patterns sections. Skip for minor improvements.
After drafting changelog entries, you MUST spawn a subagent to verify each bullet point is accurate. This is non-negotiable — changelog mistakes are a recurring problem.
The subagent should:
Subagent prompt template:
Verify these changelog entries for version X.Y.Z are accurate.
Previous version: [e.g., v0.1.9]
Commits to check: git log v<previous>..HEAD
Entries to verify:
[paste drafted entries]
For EACH entry:
1. Find the relevant commit(s) using git log and git show
2. Read the actual diff, not just the commit message
3. Confirm the entry accurately describes the user-facing change
4. Flag if the entry overstates, understates, or misdescribes the change
Also check:
- Are there user-facing changes NOT covered by these entries?
- Verify each "thanks @..." attribution (right person, right role — author vs reporter)
Report format:
- Entry: [entry text]
Status: ✅ Accurate / ⚠️ Needs revision / ❌ Incorrect
Evidence: [what you found in the diff]
Suggested fix: [if needed]
Do not finalize the changelog until the subagent confirms all entries are accurate.
If verification finds problems: Escalate to the user. Show them the subagent's findings and ask how to proceed. Don't attempt to resolve ambiguous changelog entries autonomously — the user knows the intent behind their changes better than you do.
Pick the bump from the changes. Skip the question when only one level is plausible; ask only when the choice is genuinely ambiguous.
Proceed without asking when the answer is obvious:
cargo semver-checks reports breaking changes → minor (pre-1.0; patch is disallowed, major has no basis pre-1.0 in a maturing project). Inform the user and continue: "Bumping minor — semver-checks reported N breaking changes; patch is disallowed pre-1.0."Ask only when genuinely ambiguous — e.g., new features landed with no semver breakage (patch vs. minor is a judgment call), or a borderline case where the user's read of the changes may differ. Use AskUserQuestion with the actual choice (patch vs. minor); don't add novelty options like skipping a version number.
When asking, present:
0.2.0)Example:
Current version: 0.2.0
Changes since v0.2.0:
- Added `state clear` command (new feature)
- Added `previous-branch` state key (new feature)
- No breaking changes
Recommendation: Minor release (0.3.0) — new features, no breaking changes
Current project status: early release, breaking changes acceptable, optimize for best solution over compatibility.
Worktrunk is primarily a CLI, but it also publishes a library crate ([lib] in Cargo.toml) that downstream crates depend on. cargo-semver-checks compares the current public API against the last version published to crates.io and flags semver violations.
cargo semver-checks check-release -p worktrunk
Interpreting results:
cargo semver-checks check-release -p worktrunk --baseline-version <last-published>.This check validates the chosen bump — it doesn't distinguish patch vs. minor when no breakage exists. Continue using the commit review to decide between patch (fixes only) and minor (new features).