From arc
Automates versioned npm releases with reasoned semver bumps, changelogs, migration notes, and tarball verification before publishing.
How this skill is triggered — by the user, by Claude, or both
Slash command
/arc:release [dry-run][dry-run]The summary Claude sees in its skill listing — used to decide when to auto-load this skill
<arc_runtime>
<arc_runtime> This workflow requires the full Arc bundle, not a prompts-only install.
Paths in this skill use these conventions:
agents/..., references/..., disciplines/..., templates/..., scripts/..., rules/..., skills/<name>/... are Arc-owned files at the plugin root. Resolve the plugin root from this skill's filesystem location — it's the directory containing agents/ and skills/../... is local to this skill's directory..ruler/..., docs/..., src/..., or any project-relative path refers to the user's project repository.
</arc_runtime><required_reading> Read this reference NOW:
references/platform-tools.md
</required_reading><platform_context> Adapt the workflow to the current harness instead of assuming Claude-specific tool names.
pnpm, npm, yarn, bun) consistently for every command below.
</platform_context>Cut a versioned release of one or more npm packages. Owns semver bumps, changelogs, and multi-package releases. Commits, pushes, and simple unversioned publishing belong to /arc:commit.
Usage:
/arc:release - Detect, propose bumps, author, verify, then gate publish./arc:release dry-run - Run everything up to and including pnpm pack verification, but never publish.$ARGUMENTS will be empty or "dry-run". Treat "dry-run" as a hard stop before any publish.
private package or a version already on the registry.--force, --no-verify, or delete published versions.Establish what is being released before proposing anything.
git describe --tags --abbrev=0 2>/dev/null || echo "(no tags)"
git log $(git describe --tags --abbrev=0 2>/dev/null)..HEAD --oneline 2>/dev/null || git log --oneline -20
Determine the repo shape:
package.json at root, no workspace config.pnpm-workspace.yaml, or workspaces in root package.json.For workspace repos, check for changesets:
test -f .changeset/config.json && echo "changesets present" || echo "no changesets"
pnpm changeset status --since=$(git describe --tags --abbrev=0 2>/dev/null || echo HEAD~20)
pnpm add -Dw @changesets/cli && pnpm changeset init) via one question before continuing. Do not scaffold silently.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:
git diff --name-only $(git describe --tags --abbrev=0 2>/dev/null || echo HEAD~20)..HEAD
A package is a release candidate only if its package.json has a name, a version, and is not "private": true. Ignore generated dirs (node_modules, dist, build, .next, .turbo, coverage).
For each changed package, inspect the diff and classify the change, then propose a bump with a one-line reason:
Confirm all packages in one structured question. List each package with its proposed bump; let the user override any of them.
AskUserQuestion:
question: "Proposed version bumps. Adjust any before I author the release."
header: "Bumps"
options:
- label: "Accept all"
description: "e.g. @scope/ui minor (new prop), @scope/core patch (internal fix)"
- label: "Override"
description: "Tell me which package should be major / minor / patch instead"
- label: "Stop"
description: "Cancel the release"
Once bumps are confirmed:
.changeset/ with the confirmed bump and a human summary, then run:
pnpm changeset version
This applies bumps and regenerates each CHANGELOG.md.version field manually to the confirmed level and prepend a dated entry to CHANGELOG.md (create it if absent), grouping changes as Added / Changed / Fixed / Breaking.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.
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 script if present. A failed build stops the release.pnpm pack
tar -tf *.tgz
npm init -y, and install the tarball by path so you exercise the published shape, not the source.exports map (and main/module/types), import it and confirm it resolves and loads without throwing.Then check the traps that only appear in the packed output:
"use client" survives bundling: if any source file declares "use client", grep the packed dist for the directive. If the bundler stripped it, the package is broken for RSC consumers — stop and report.peerDependencies, not dependencies, to avoid duplicate copies. Flag any that are misplaced.import and require conditions resolve for each export entry, and that types points at real .d.ts files in the tarball.files array / .npmignore actually includes the built dist (and types) — the packed tarball listing from step 2 is the source of truth.Report every finding. Any hard failure (build fail, stripped directive, missing dist, unresolved export) blocks publish until fixed.
If $ARGUMENTS is "dry-run", stop here and report the verification results. Do not proceed to publish.
Gate publishing behind one explicit question:
AskUserQuestion:
question: "Verification passed for <packages>. How do you want to proceed?"
header: "Publish"
options:
- label: "Publish now"
description: "Publish each verified package to the registry"
- label: "Dry-run only"
description: "Run publish with --dry-run and report, but do not publish"
- label: "Stop"
description: "Leave the release authored but unpublished"
On Publish now, publish each verified package from its directory using the detected package manager. For changesets repos prefer pnpm changeset publish (it publishes only bumped packages and skips already-published versions). For single packages use npm publish, adding --access public for scoped public packages.
After a successful publish, offer to tag and push — never do it silently:
# offered, not automatic:
git tag <name>@<version> # or vX.Y.Z for single-package repos
git push --follow-tags
Tell the user:
npx claudepluginhub howells/howells-plugins --plugin arcGuides npm publishing for @mcp-b monorepo packages using changesets: validate build/test/typecheck, create/apply changesets for version bumps and CHangelogs, NPM_TOKEN auth, pnpm publish -r in topological order.
Bumps versions, writes changelogs, commits, and tags for single-package repos or workspace monorepos. Supports beta releases and dry runs.
Generates changelog from git commits, determines semver bump from commit messages or user input, updates package.json, commits/tags/pushes, creates GitHub release, publishes to npm.