howells/arc/release

Claude Code and agent skill by howells/arc

Trust tier 3
  • community
Source check pending

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/release

SKILL.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: the packageManager field in package.json, then a lockfile (pnpm-lock.yaml → pnpm, package-lock.json → npm, yarn.lock → yarn, bun.lockb → bun), then default to npm.
  • The changesets workspace-root install flag -w applies only under pnpm; drop it for npm, yarn, and bun.
  • Publishing itself uses npm publish regardless 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 including npm pack verification, 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-run mode: continue read-only, report what would be bumped and published, and mutate nothing. The gate stays absolute for attended runs.
  • Never publish a private package 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.

bash
git remote || echo "(no remote)"
LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null)
if [ -n "$LAST_TAG" ]; then
echo "last tag: $LAST_TAG"
git log "$LAST_TAG"..HEAD --oneline
else
echo "(no tags)"
git log --oneline
fi

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.json at root, no workspace config.
  • Workspace/monorepo: pnpm-workspace.yaml, or workspaces in root package.json.

For workspace repos, check for changesets:

bash
test -f .changeset/config.json && echo "changesets present" || echo "no 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 -w outside 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:

bash
LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null)
if [ -n "$LAST_TAG" ]; then git diff --name-only "$LAST_TAG"..HEAD; else git ls-files; fi

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.

AskUserQuestion:
question: "Proposed version bumps. Confirming authorizes me to author, commit, and push the release — publishing and tagging are asked separately."
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"

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 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.

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:

  1. Build: run the package's build script if present. A real compile error stops the release. A command not found or a missing node_modules is an environment prerequisite, not a build failure — report "install dependencies first" as the next step and do not read it as a broken package.
  2. Pack: create the real tarball and inspect its contents. Use npm pack regardless of the detected <pm> — yarn appends its own timing line and renames the file, and bun pack does not exist. Pack into a temp directory so no .tgz is left in the working tree for a later commit to sweep up, and pass the filename pack prints to tar exactly — a *.tgz glob 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" ``

  1. 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 — and pnpm init rejects -y), and install the tarball by path so you exercise the published shape, not the source.
  2. Import-smoke each entry point: for every path in the exports map (and main/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 packed dist for 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, not dependencies, to avoid duplicate copies. Flag any that are misplaced.
  • Exports map resolves both conditions: confirm both the import and require conditions resolve for each export entry, and that types points at real .d.ts files in the tarball.
  • Files array does not drop dist: confirm the files array / .npmignore actually includes the built dist (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 — .env files, credentials or keys, internal docs/, 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

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
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/howells/arc/release/badge)](https://verified-skill.com/skills/howells/arc/release)

Something wrong with this skill or its page? Tell us.