agentleFS
robritacca-dotcomrobritacca-dotcom/rift-ds/.claude/skills/release/SKILL.md

release

Skill9 starsChanged 6 days agoMITView on GitHub

Cut a new npm release of rift-ds. Bump the version, dry-run, publish via the Release workflow, then tag the published commit. Use when asked to cut a release, publish a new version, or ship the package to npm.

  • Installs packages
  • Commits and pushes

196 other projects use a version of this.

Adopted by

Most recently taken up by

Used with

Projects with it also use create-agent-adapter, changelog-style and 10 more.

Other files people use alongside this one.

Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
  • MicrosoftSkill

    create-agent-adapter

    Technical guide for creating a new Paperclip agent adapter. Use when building a new adapter package, adding support for a new AI coding tool (e.g. a new CLI agent, API-based agent, or custom process), or when modifying the adapter system. Covers the required interfaces, module structure, registration points, and conventions derived from the existing claude-local and codex-local adapters.

    Also in 5 projects that use this

  • GrinvSkill

    changelog-style

    Turn a commit range into CHANGELOG.md entries following common-changelog style. Use when finishing a PR or cutting a release, to write/fix the [Unreleased] section's entries — moving [Unreleased] under a new dated version heading is a separate, automated step (see the release skill / scripts/sync-version.ts), not this skill's job.

    Also in 4 projects that use this

  • GrinvSkill

    docs-consistency-check

    Check README/manifest.json/server.json/CHANGELOG.md/AGENTS.md and docs/*.md for drift against the actual registered tools and source. Use after adding, renaming, or removing a tool, or as part of a live-audit pass.

    Also in 4 projects that use this

  • Microsoft AzureSkill

    component-release

    Prepares a verifiable Agent Landing Zone UI release. Use for release branches, VERSION, changelog entries, tags, release notes, and compatibility evidence; never publish without explicit human approval.

    Also in 4 projects that use this

  • Microsoft AzureSkill

    documentation-consistency

    Keeps AI Landing Zone contributor, user, and operator documentation aligned with shipped Bicep behavior. Use for parameters, defaults, outputs, topology, deployment flow, operations, or releases.

    Also in 8 projects that use this

  • rivet-devSkill

    launch-graphics

    Generate agentOS marketing/launch graphics (launch & social heroes, code-snippet cards) from the committed generators in docs-internal/graphics. Use when asked to make, update, or render an agentOS launch image, social image, "agentOS Apps" graphic, or technical code-snippet image.

    Also in 3 projects that use this

  • +3 more from Grinv

The file

We split this skill into the rules it gives an agent

5 rules. 0 are common, 3 are distinctive, and 2 are very specific to this project.

  • 0

    Common

    Most of the 186 edited versions we read keep these.

  • 3

    Distinctive

    This author's own choices. Worth a look.

  • 2

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Use this skill when asked to cut a release, publish a new version, or ship the package to npm — phrases like "cut a release", "publish the …

    line 15
  2. Distinctive:

    Check what shipped since the last tag to justify the choice, and confirm it with the owner before bumping:

    line 29
  3. Very specific:

    Run npm run verify if anything at all is uncommitted or you haven't verified since the last change.

    line 44
  4. Very specific:

    Write the notes for a consumer, not a maintainer: what's new, anything breaking with the migration step spelled out, and the install …

    line 114
  5. Distinctive:

    Never publish from a dirty tree, an unpushed commit, or a red CI

    line 129

“Common” is measured: kept by at least 6 in 10 of the 186 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

release

Cut a new npm release of rift-ds — bump, dry-run, publish, tag.

When invoked

Use this skill when asked to cut a release, publish a new version, or ship the package to npm — phrases like "cut a release", "publish the next version", "ship the package".

This is the one workflow in this repo where a mistake is permanent. npm never lets a version number be reused, even after unpublishing, so a botched publish burns that version forever. Read the guardrails before starting.

Instructions

1. Decide the version

Read PACKAGE_VERSION in scripts/package-manifest.mjs — that constant is the authoritative version; two other files mirror it (see step 3) and validate-package-exports.mjs fails the build when they disagree (the root package.json version is a hand-maintained mirror; dist/package.json is generated from the manifest). Then pick the next version from what actually changed since the last release:

  • patch — bug fixes, internal refactors, docs
  • minor — new components, new exports, new tokens (additive)
  • major — a renamed/removed prop, export, or token; anything a consumer must edit code for

Check what shipped since the last tag to justify the choice, and confirm it with the owner before bumping:

git log $(git describe --tags --abbrev=0)..HEAD --oneline

node scripts/validate-api-compat.mjs answers half of this mechanically (the published schema files and meta-schema properties under website/public/schema/ included): it compares the working tree's props, export names, subpaths, deep-import files and bin with the last tag, and fails on anything removed or narrowed. A clean run means nothing published has gone, which rules out a major for shape reasons (a moved default is behaviour, and still needs a reader). A deliberate break ships only as a major, with a SANCTIONED_BREAKS row in that script naming the version and the reason. The one other kind of row is a correction to the baseline's own record, where the published types never changed and only the generated API misreported them (its reason starts "not a break" and says so); that rides in a minor. Either way, after the tag in step 7 the row goes stale and the next run fails until it is deleted.

Be deliberate about breaking changes: components are exported both from the barrel and from ./components/* deep paths, so a renamed component folder breaks consumers even if the barrel still exports the old name. Every other subpath in SUBPATHS in scripts/package-manifest.mjs (the chat widget's, ./format, the published behaviours and the token modules) is a public path on the same terms, and the scaffold templates under src/cli/templates/ (one folder per init subcommand: chat, app and blocks) ride in the tarball, so a renamed export they import breaks files the bin has already written into consumer apps.

2. Pre-flight

  • Working tree must be clean and pushed. The workflow builds from the repo, not your disk — anything uncommitted will not be in the release. git status --short and git log origin/main..HEAD should both be empty.
  • CI on main must be green. A release from a red main ships known-broken code.
  • Confirm the Trusted Publishing registration on npmjs.com still covers THIS repo before a real publish. It is keyed to repo + workflow filename, and was registered for robritacca-dotcom/rift-ds + release.yml on 2026-09-26. Renaming either breaks publishing until the registration is updated, and the owner owns anything that changes on npmjs.com.
  • Run npm run verify if anything at all is uncommitted or you haven't verified since the last change.

3. Bump and commit

Three files carry the version — edit the first two, regenerate the third:

  1. PACKAGE_VERSION in scripts/package-manifest.mjs — the source of truth for what ships.
  2. "version" in the root package.json — must be kept in sync by hand. No generator writes it. The root package.json stays private: true forever; only the generated dist/package.json is published, but the parity check still gates every build.
  3. package-lock.json — npm records the version there too. Refresh it with npm install --package-lock-only and commit it with the bump; a stale lockfile dirties every later plain npm install (the 0.3.0 bump shipped without this and broke the worktree-based skills' cleanup).

scripts/validate-package-exports.mjs fails the build when any of the three disagree.

Per-version facts (the version, its date, what shipped) have one home: the release log (website/src/data/release-log.json, written in step 8). Never restate them in prose anywhere else, a doc or a workflow comment: nothing validates a hand copy, so it drifts the first release it is forgotten.

Then:

npm run validate-registry

This re-runs the three-way version parity check and regenerates the derived surfaces — and several generators stamp PACKAGE_VERSION into their output, so the bump rewrites every per-component markdown page under website/public/components/, every component schema and the index under website/public/schema/ (their version field) and every DTCG token file there (its $extensions block), the consumer agent skills' folders under website/public/skill/ (AGENT_SKILLS in scripts/brand.mjs owns the names), the agent starter (website/public/AGENTS.md and its module, website/src/data/agent-starter.generated.ts) and the site corpus that carries the starter's text. Whatever the regeneration touches is the list. The diff is large by design. Commit all of it together as the bump commit (chore(release): <version>) and push — a bump pushed without the restamped files fails CI's drift guard (that exact split produced the 0.15.0 cleanup commit), and the commit you push here is the commit that will be published and tagged.

4. Dry run — never skip this

gh workflow run release.yml -f dry_run=true

Watch it to completion — but confirm you are watching the run you just dispatched, not the previous one. Registration lags the dispatch by a few seconds, so --limit 1 immediately after gh workflow run can return the prior run (at step 5 that prior run is the green dry run, and watching it reads as a successful publish):

sleep 10
gh run list --workflow=release.yml --limit 3 --json databaseId,createdAt,displayTitle   # newest first — check createdAt is after your dispatch
gh run watch <the-new-databaseId> --exit-status

The dry run does everything except upload: builds dist/, packs the tarball, installs it into two scratch Vite + React apps — one that builds with none of the optional peers installed (the regression this catches: a peer leaking into the main barrel), and one that installs every peer, runs the packed bin's init chat, init app and init block for every block against an app-router layout, and type-checks and builds the scaffolds — then prints the publish preview. It needs no npm token, so it is free to run as often as you like. Read the preview's file count and package size and sanity-check them against the previous release; a sudden jump means something got swept into the tarball. Expect LICENSE, README.md, the init bin under bin/ (named by BIN_NAME in scripts/brand.mjs, origin-stamped and executable) and its scaffold templates (every folder of src/cli/templates/, one per init subcommand) under bin/templates/ alongside the build output; anything else new is not deliberate.

5. Publish

gh workflow run release.yml -f dry_run=false

Watch it the same way (the same watch-the-right-run caution applies, and matters more here). The publish step runs npm publish --access public --provenance --loglevel verbose from dist/ — the verbose flag is deliberate, because its log lines are the only visible evidence of the OIDC token exchange the auth guardrails below tell you to look for — and signs a provenance attestation tying the tarball to this repo, commit, and workflow run.

6. Verify — and do not panic at a 404

The registry lags a successful publish by several minutes. A 404 from npm view right after a green workflow is propagation, not failure. Confirm the workflow's publish step actually ran (gh run view <id> --json jobs) and look for + rift-ds@<version> in its log — if that line is there, it published. Never re-run the workflow on a 404; the version is already consumed and the rerun will fail with EPUBLISHCONFLICT.

Once it propagates, confirm the registry serves the new version:

npm view rift-ds version --prefer-online

The real consumer-shaped check already ran before publish: scripts/smoke-consumer.mjs packs the tarball into two scratch Vite apps and builds them: one with no optional peer installed, importing the barrel, and one with every optional peer that also runs the packed bin's init chat, init app and init block for every block, and builds the scaffolds (bare node can't import the barrel because components import their own CSS; that needs a bundler). To repeat it against the published artifact rather than the local tarball, scaffold a scratch Vite app, npm install rift-ds@<version>, import the barrel plus tokens/tokens.css, and run its build; for the chat, install every optional peer in a scratch Next.js app router project, run npx rift-ds@<version> init chat there, and build it; in the same project, run npx rift-ds@<version> init app, add the lines it prints to the root layout (importing tokens/base.css among them), and build again. The smoke consumer is a Vite app with next/link stubbed, so this is init app's only check against a real Next.js app.

7. Tag the published commit

Tag the commit that was published, not necessarily current HEAD — the provenance attestation names that commit, so the tag, attestation, and tarball should all agree:

git tag -a v<version> <published-sha> -m "v<version> — <one-line summary>"
git push origin v<version>
gh release create v<version> --verify-tag --title "v<version> — <short title>" --notes-file <notes>

Tagging moves the compatibility gate's baseline, so any SANCTIONED_BREAKS row this release carried now matches nothing. Delete it in the next commit.

Write the notes for a consumer, not a maintainer: what's new, anything breaking with the migration step spelled out, and the install snippet. The previous release is the format reference; the prose follows content-design.md.

8. Append the release-log entry

The /releases page is 1:1 with npm by rule: every publish gets exactly one entry in website/src/data/release-log.json, written now, as part of this ritual — never later, never speculatively. Add the new entry at the TOP of releases (newest first) with the published version, the publish date, a plain descriptive title, and body paragraphs written for a consumer (the same story as the GitHub release notes, condensed — content-design.md's release-log register row owns the voice). scripts/validate-release-log.mjs holds the structure. The site corpus carries the log, so run npm run validate-registry after adding the entry and commit the regenerated corpus with it; commit both with the version-bump follow-ups so the site and the registry never tell different stories.

9. Report

Version published, the npm URL, the tagged commit, the release URL, and anything a consumer must do to upgrade.

Guardrails

  • Never publish from a local machine (npm publish by hand) — releases go through the workflow so every release is provenance-signed and smoke-tested
  • Never re-run the publish workflow after a successful publish, even if the registry 404s
  • The version's three homes must agree — step 3 above is the procedure and CLAUDE.md's Release section owns the fact. Never bump package.json alone — the manifest is what ships
  • Never publish from a dirty tree, an unpushed commit, or a red CI
  • Auth is Trusted Publishing (OIDC) — there is no npm token to expire or rotate. The one exception is a package's first-ever publish: a trusted publisher can only be attached to a package that already exists, so a brand-new name must be created with the workflow's bootstrap_token input (off by default, NPM_TOKEN secret, revoked immediately after). npm's tell for that case is specific — 404 ... OIDC token exchange error - package not found from the exchange endpoint. Otherwise, if the publish step fails to authenticate, the cause is one of: actions/setup-node was given a registry-url: (see below); the id-token: write permission was dropped from release.yml; the workflow file was renamed or moved (the trusted-publisher registration on npmjs.com is keyed to the filename release.yml); the registration on npmjs.com names a different repository — it is keyed to repo + workflow filename, so check the pre-flight above for what is registered today; the npm CLI on the runner is older than 11.5.1; or the registration itself was removed. The owner owns anything that has to change on npmjs.com.
  • A 404 on PUT during publish is an AUTH failure, not a missing package. npm returns 404 instead of 403 so it doesn't leak whether a package exists — the message even says "or you do not have permission to access it". Do not go hunting for a missing package; check the auth path.
  • Never add registry-url: to actions/setup-node in this workflow. It writes an .npmrc with _authToken=${NODE_AUTH_TOKEN} and exports a placeholder NODE_AUTH_TOKEN, so npm thinks it is already authenticated, skips the OIDC exchange entirely, and gets rejected. The tell in the log: no mention of oidc/trusted anywhere, and NODE_AUTH_TOKEN: XXXXX-XXXXX-XXXXX-XXXXX in a step's env block. Provenance signing still succeeds in this state — that is GitHub→Sigstore and proves nothing about npm accepting the token.
  • A dry run never authenticates, so it cannot prove OIDC is working — it exercises the build and the tarball, nothing else. After any change to release.yml's auth, permissions, or filename, the only real proof is a genuine publish. Treat that as a reason to make the next release a small patch, not a reason to skip the dry run.
  • The npm README is the package README — if the release changes install or usage, fix README.md in the same release, since it ships inside the tarball. Fix src/stories/Configure.mdx too: it carries the same install snippet on the Storybook landing page, deploys separately, and is where people evaluating a component arrive. generate-readme-content.mjs enforces that both mention the package name, but it cannot tell whether the snippet is still correct. The README banner image (.github/readme-banner.jpg) has no generator: it is a screenshot of the site hero and states its headline and subtitle in pixels. If either moved since the last re-shoot, run node scripts/capture-readme-banner.mjs and commit the image in the same release

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.