howells/arc/release
Claude Code and agent skill by howells/arc
- community
Checking that the SKILL.md file is still in the repository.
Versioned releases of npm packages: semver bumps, changelogs, and multi-package releases for single-package repos and pnpm workspaces with changesets. Use when asked to "cut a release", "bump the version", "release the packages", "publish a new version", "run changesets", or "ship a versioned package".
Install
npx vskill@latest install howells/arc/releaseSKILL.md
<arc_runtime> Requires the full Arc bundle. Arc-owned paths (agents/, references/, disciplines/, templates/, scripts/, rules/, skills/) resolve from the plugin root — the directory containing agents/ and skills/. Everything else is the user's repository. </arc_runtime>
<platform_context> Adapt the workflow to the current harness instead of assuming Claude-specific tool names.
- Use platform-native structured questions when available; otherwise ask one concise plain-text question at a time.
- Use the repo's detected package manager (
pnpm,npm,yarn,bun) consistently for every command below. Commands are written with a<pm>placeholder — substitute the detected manager. - Detect
<pm>in this order: thepackageManagerfield inpackage.json, then a lockfile (pnpm-lock.yaml→ pnpm,package-lock.json→ npm,yarn.lock→ yarn,bun.lockb→ bun), then default tonpm. - The changesets workspace-root install flag
-wapplies only under pnpm; drop it for npm, yarn, and bun. - Publishing itself uses
npm publishregardless of the install-time package manager. Changeset-driven publishes run through the detected manager (<pm> changeset publish).
</platform_context>
Release Workflow
Cut a versioned release of one or more npm packages. /arc:commit publishes a package whose version is already committed and not yet on the registry. /arc:release owns bumping versions, changelogs, and coordinated multi-package releases.
The canonical order across both skills is commit → push → publish → tag. /arc:commit states the governing invariant — never publish before pushing the commit containing the package version — and this skill follows it.
Usage:
/arc:release- Detect, propose bumps, author, verify, commit and push, then gate publish./arc:release dry-run- Run everything up to and includingnpm packverification, but never commit, publish, tag, or push.
$ARGUMENTS will be empty or "dry-run". Treat "dry-run" as a hard stop before any publish.
Resolve the run mode first: the dry-run argument, or any unattended gate fallback, sets mode = dry-run for the remainder of the run. In dry-run mode Steps 3 and 5 are skipped entirely, and Step 6 reports instead of publishing. Once set, the mode never clears — carry it to the report.
Boundary
- Never bump a version, publish, tag, or push without an explicit user choice at a gate — the Step 2 gate authorizes the release commit and its push; publish and tag stay separately gated.
- If no user response is available (an unattended or non-interactive run), fall back to
dry-runmode: continue read-only, report what would be bumped and published, and mutate nothing. The gate stays absolute for attended runs. - Never publish a
privatepackage or a version already on the registry. - Never use
--force,--no-verify, or delete published versions. - Do not invent changelog entries. Base them on actual commits and diffs.
Step 1: Detect Release State
Establish what is being released before proposing anything.
Never write the tag lookup as a bare $(git describe ...)..HEAD range: when there is no tag the range collapses to ..HEAD, which exits 0 with no output, so a || fallback never fires and an unreleased repo reports zero commits. Branch on $LAST_TAG explicitly, as above.
Surface the remote result — Step 5 cannot push without one.
Determine the repo shape:
- Single package: one
package.jsonat root, no workspace config. - Workspace/monorepo:
pnpm-workspace.yaml, orworkspacesin rootpackage.json.
For workspace repos, check for changesets:
- If changesets are present, read pending intents and status:
``bash LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null) if [ -n "$LAST_TAG" ]; then <pm> changeset status --since="$LAST_TAG"; else <pm> changeset status; fi ``
- If changesets are absent in a workspace repo, offer to scaffold on first run (
<pm> add -Dw @changesets/cli && <pm> changeset init, dropping-woutside pnpm) via one question before continuing. Do not scaffold silently. If no user response is available, skip scaffolding, continue without changesets, and note the skipped offer in the report.
Identify which publishable packages changed since their last release. Prefer changeset status; fall back to diffing since the last tag filtered by each package's directory. With no tag there is no baseline to diff against — every tracked file is in scope:
Never substitute HEAD~20 for a missing tag: it is a fatal error in any repo with fewer than 21 commits, which is exactly the young untagged repo the fallback is meant to cover.
A package is a release candidate only if its package.json has a name, a version, is not "private": true, and declares at least one entry point (exports, main, or module) or a files array. A package with none of those is an application, not a library — stop and ask before treating it as publishable; if no user response is available, report it and stop. Ignore generated dirs (node_modules, dist, build, .next, .turbo, coverage).
Step 2: Propose Semver With Reasoning
For each changed package, inspect the diff and classify the change, then propose a bump with a one-line reason:
- major — removed or renamed an export, changed a signature, dropped a runtime, changed default behavior.
- minor — added a new export, prop, or option; backwards-compatible surface growth.
- patch — bug fix, internal change, docs, types-only fix with no surface change.
No tags and nothing on the registry → this is the first release. Propose publishing the current version as-is unless the change set argues for a bump, and note that pre-1.0 versions carry no compatibility promise under semver.
Confirm all packages in one structured question. List each package with its proposed bump; let the user override any of them.
A structured question returns only the chosen label, so "Override" carries no package or level. If the user selects Override, follow up with one question per package to collect its bump level before authoring anything.
If no user response is available, set mode = dry-run and continue: report the proposed bumps, skip Step 3 (no changesets, no version bumps, no CHANGELOG.md edits), and run Step 4's verification read-only against the current, pre-bump versions. Say so in the report.
Step 3: Author The Release
Skip this step entirely in dry-run mode — it writes to the tree.
Once bumps are confirmed:
- Changesets repo: write a changeset file per package under
.changeset/with the confirmed bump and a human summary, then run:
``bash <pm> changeset version ` This applies bumps and regenerates each CHANGELOG.md`.
- Single package: bump the
versionfield manually to the confirmed level and prepend a dated entry toCHANGELOG.md(create it if absent), grouping changes as Added / Changed / Fixed / Breaking.
If the repo ships a version-bump script (often paired with a manifest such as .version-bump.json; look in package.json scripts and a scripts/ directory), run that script rather than editing version fields directly — hand-editing one file desynchronizes the rest.
For any breaking change, write a short migration note — how to upgrade, before/after, and what to search-and-replace. Append it to MIGRATIONS.md at the package root (create if absent), keyed by the new version. Keep it to the minimum a consumer needs to update.
Step 4: Pre-Publish Verification
This step catches the failures a plain npm publish ships silently. Run it for every publishing package. Use the platform temp/scratch directory for the throwaway project.
For each package:
- Build: run the package's
buildscript if present. A real compile error stops the release. Acommand not foundor a missingnode_modulesis an environment prerequisite, not a build failure — report "install dependencies first" as the next step and do not read it as a broken package. - Pack: create the real tarball and inspect its contents. Use
npm packregardless of the detected<pm>— yarn appends its own timing line and renames the file, andbun packdoes not exist. Pack into a temp directory so no.tgzis left in the working tree for a later commit to sweep up, and pass the filename pack prints totarexactly — a*.tgzglob breaks once a second tarball exists.
``bash PACK_DIR=$(mktemp -d) TARBALL="$PACK_DIR/$(npm pack --pack-destination "$PACK_DIR" | tail -1)" tar -tf "$TARBALL" ``
- Install into a throwaway project: create a temp dir,
npm init -y(the project is disposable, so it does not need the repo's package manager — andpnpm initrejects-y), and install the tarball by path so you exercise the published shape, not the source. - Import-smoke each entry point: for every path in the
exportsmap (andmain/module/types), import it and confirm it resolves and loads without throwing. Zero entry points is not a vacuous pass — a package nothing can import is not publishable. Stop and report.
Then check the traps that only appear in the packed output:
- `"use client"` survives bundling: if any source file declares
"use client", grep the packeddistfor the directive. If the bundler stripped it, the package is broken for RSC consumers — stop and report. - Runtime/animation libs are peerDependencies: libraries the consumer's app also renders with (React, React DOM, framer-motion, and similar runtime/animation libs) belong in
peerDependencies, notdependencies, to avoid duplicate copies. Flag any that are misplaced. - Exports map resolves both conditions: confirm both the
importandrequireconditions resolve for each export entry, and thattypespoints at real.d.tsfiles in the tarball. - Files array does not drop dist: confirm the
filesarray /.npmignoreactually includes the builtdist(and types) — the packed tarball listing from step 2 is the source of truth. - Tarball hygiene: read the same listing for anything that should not be published —
.envfiles, credentials or keys, internaldocs/, notes, fixtures, or a tarball far larger than the built output justifies. Publishing is irreversible, so flag these before they ship.
Report every finding. Any hard failure (build fail, stripped directive, missing dist, unresolved export, secret in the tarball) blocks publish until fixed.
In dry-run mode, stop here and report the verification results. Do not proceed to commit or publish.
Step 5: Commit And Push The Release
Do not enter this step in dry-run mode.
If the repo has no remote, stop BEFORE committing and report — the publish-after-push invariant cannot be satisfied without one, so committing here would only leave the tree mutated and publishing permanently blocked.
This is the start of the file. Read the full SKILL.md on GitHub.
Security
- Security scanPassed, 95 of 100Pattern checks on the skill's files.
- Model reviewPassed
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingskills/release/SKILL.md
Popularity
- Repository stars
- 25
- Repository forks
- 2
- 7-day trend score
- 16
Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/howells/arc/release)