Skip to content
Development
Skill

/han-release

Cut a Han release: update CHANGELOG.md with the changes since the last release, bump and tag every plugin that changed as {plugin-name}--v{version} so a version-constrained dependency can resolve, and publish a GitHub release crediting every merged pull request and closed issue

From plugin
han
35047 skills31 agents

Claude Code

$ npx -y skills add testdouble/han --skill han-release --agent claude-code

SKILL.md

han-release.SKILL.md
name: han-release
description: >
  Cut a Han release: update CHANGELOG.md with the changes since the last release, bump and tag every plugin that changed
  as {plugin-name}--v{version} so a version-constrained dependency can resolve, and publish a GitHub release crediting
  every merged pull request and closed issue to the people behind it. Use when releasing, cutting a release, shipping a
  new Han version, publishing release notes, or tagging a version. Always stops for approval before creating any tag,
  because a pushed tag is never moved. Requires the gh CLI, jq, the claude CLI, and a clean git checkout. This is a
  repository-maintenance skill for the Han repo itself, not a general review or PR skill — use code-review for local
  review, post-code-review-to-pr to post a PR review, and update-pr-description for PR bodies.
argument-hint: "[pause before publishing] [draft] [optional release context]"
allowed-tools:
  Read, Edit, Write, Glob, Grep, Agent, Bash(git *), Bash(gh *), Bash(jq *), Bash(which *), Bash(grep *), Bash(sed *),
  Bash(head *), Bash(command claude *)

<!-- `AskUserQuestion` is deliberately absent from `allowed-tools`, and must stay absent. Listing it makes Claude Code's permission evaluator auto-approve the tool through its always-allow path and return empty answers without ever rendering the prompt, so every gate in this skill would silently pass. See han-plugin-builder/skills/guidance/references/skill-building-guidance/allowed-tools-AskUserQuestion.md. The tool still works unlisted; it prompts once for permission. -->

Pre-requisites

  • gh CLI: !`which gh 2>/dev/null || echo "not installed"`
  • jq: !`which jq 2>/dev/null || echo "not installed"`
  • claude CLI: !`which claude 2>/dev/null || echo "not installed"`
  • git repo: !`git rev-parse --is-inside-work-tree 2>/dev/null || echo NO`

**If `gh`, `jq`, or `claude` reads `not installed`, or this is not a git repo:** tell the operator which prerequisite is missing and that it must be installed/configured before `/han-release` can run, then **immediately stop**. The skill cannot proceed without all four.

The `claude` CLI is what creates the per-plugin tags in Step 10. Every invocation of it in this skill goes through the shell's `command` builtin (`command claude ...`), never a bare `claude`, because an operator's shell commonly wraps `claude` in a function or alias that blocks waiting for terminal input. The `which` probe above resolves the same way a bare call would, so it reports the wrapper's presence rather than the executable's; treat a non-empty result as "the tool is reachable" and let Step 10's first invocation be what proves it runs.

Project Context

  • repo: !`gh repo view --json nameWithOwner -q .nameWithOwner 2>/dev/null || git config --get remote.origin.url`
  • current branch: !`git branch --show-current 2>/dev/null || echo unknown`
  • default branch: !`git symbolic-ref --short refs/remotes/origin/HEAD 2>/dev/null | sed 's#^origin/##' || echo unknown`
  • working tree: !`git status --porcelain 2>/dev/null || echo NO`
  • parent plugin name: !`jq -r .name .claude-plugin/marketplace.json 2>/dev/null`
  • plugins (name source version):

!`jq -r '.plugins[] | "\(.name)\t\(.source)\t\(.version)"' .claude-plugin/marketplace.json 2>/dev/null`

  • latest parent tag: !`git fetch --tags --quiet >/dev/null 2>&1; git tag -l 'han--v*' --sort=-v:refname | head -n1`
  • latest suite tag: !`git tag -l 'v*.*.*' --sort=-v:refname | head -n1`
  • changelog head: !`grep -m1 '^## v' CHANGELOG.md 2>/dev/null`

The two tag probes are separate on purpose. A single pattern covering both namings returns the **wrong** tag: version sorting compares the whole refname, so `v4.6.0` sorts ahead of `han--v5.0.0` and the old suite tag wins on every release after the transition. The fetch runs on the first probe only; both read the same refreshed tag list.

`latest parent tag` carries the literal `han--v*` pattern, because a context-injection command is a fixed string and cannot interpolate `parent plugin name`. If `parent plugin name` is not `han`, redo the lookup in Step 2 with the actual name before using either value. Skipping that turns a renamed parent into an empty probe, which Step 2 would read as a first release and silently expand the changelog to the whole repository history.

Vocabulary used throughout this skill

  • **parent** — the meta-plugin whose name equals the marketplace `name` (`parent plugin name` above, normally `han`). It

has no skills or agents of its own; it exists to install the children via `dependencies`. The parent's own per-plugin tag is the one the GitHub release attaches to, so the release tag is `{parent plugin name}--v{parent target}`.

  • **children** — every other entry in `marketplace.json.plugins[]` (`han-core`, `han-github`, `han-reporting`, and any

future `han-*` plugin). Each child has its own version line, bumped independently of the others.

  • **baseline** of a plugin — its version at `prev` (the latest release tag). For the parent this is `prev#`. For a child

it is the version recorded in that child's `plugin.json` at `prev`; if the child did not exist at `prev`, it is a **new plugin** (see Step 3).

  • **current** of a plugin — the version in its working-tree `plugin.json`.
  • **target** of a plugin — the version being released for it. The release tag is

`{parent plugin name}--v{parent target}`.

  • **tag name** of a plugin — `{name}--v{target}`, for example `han--v5.0.0` and `han-core--v3.0.0`. Every plugin gets

one, and the parent's is what the GitHub release attaches to.

  • `prev` is the previous release's tag, resolved in Step 2 from the two tag probes. On the first release it is empty.
  • `prev#` is **the part of `prev` after its last `v`**. That rule is correct under both namings, which matters because

`prev` can be either shape:

  v4.6.0        -> prev# is 4.6.0
  han--v5.0.0   -> prev# is 5.0.0

Do not read `prev#` as "the number without the leading `v`". That

Read more
@testdouble
Ships withhan

Han is a suite of AI skills and agents for solo (or small-team) product engineers.

35047 skills31 agents
Get the whole plugin

Stars on GitHub

Momentum

stars in total
350
Star history of testdouble/han on GitHub, a chart by star-history.com

Other skills on han.

han-update-documentation

han-update-documentati…

Update Han plugin documentation so every skill, agent, guidance doc, index, and cross-reference is current and accurate. On a…

@testdouble@testdoubleInstall Skill
code-overview-to-confluence

code-overview-to-confl…

Produces a progressive-disclosure overview of unfamiliar code or a pull request's changes with code-overview and publishes the…

@testdouble@testdoubleInstall Skill
investigate-to-confluence

investigate-to-conflue…

Runs an evidence-based investigation of a bug, failure, or unexpected behavior with investigate and publishes the resulting…

@testdouble@testdoubleInstall Skill
markdown-to-confluence

markdown-to-confluence

Publishes a local Markdown file to a user-specified Confluence location, creating a new page or updating an existing one through…

@testdouble@testdoubleInstall Skill
plan-a-feature-to-confluence

plan-a-feature-to-conf…

Builds a feature specification from scratch with plan-a-feature and publishes it to a user-specified Confluence location, posting…

@testdouble@testdoubleInstall Skill

More skills from other plugins.

brainstorming
Auto-invoked

brainstorming

You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…

@obra@obraInstall Skill
ask-matt

ask-matt

Ask which skill or flow fits your situation. A router over the skills in this repo.

skills2w309k
@mattpocock@mattpocockInstall Skill
accessibility
Auto-invoked

accessibility

Design, implement, and audit accessible UI to WCAG 2.2 Level AA across Web, iOS, and Android — semantic ARIA roles and labels,…

ecc2w293k
@affaan-m@affaan-mInstall Skill
compiler-commit

compiler-commit

Use when you want to verify compiler changes and commit with the correct convention. Runs tests, lint, and format, then commits…

react5d252k
@facebook@facebookInstall Skill

Questions about han-release.

Which coding agents can use han-release?
han-release installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.