factory-release
Skill9 starsChanged 4 months agoMITView on GitHub
Cut a new release — bump package.json + VERSION in lockstep, commit, tag with a per-version breakdown since the last published baseline, push, publish a GitHub Release, and publish to npm. Five approval gates; the user edits release notes in their preferred editor.
- Commits and pushes
1 other project uses a version of this.
Adopted by
Most recently taken up by
- tikalk/adlc-team-skillstheir own version, first seen Nov 8, 2026
Other versions1 project uses a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 1
- tikalk/adlc-team-skills★ 145same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository42 other files it gives its agents.
- guidance/claude.mdCLAUDE.md
- factory-animationSkill
- factory-api-route-engineerSkill
- factory-apiSkill
- factory-authSkill
- factory-auth-wiring-specialistSkill
- factory-ciSkill
- factory-closeSkill
- factory-code-reviewerSkill
- factory-commitsSkill
- factory-data-layerSkill
- factory-data-pipeline-engineerSkill
- factory-data-pipelinesSkill
- factory-db-migration-engineerSkill
- factory-db-migrationSkill
- factory-db-schema-architectSkill
- factory-deploymentSkill
- factory-designSkill
- factory-entrySkill
- factory-feature-architectSkill
- factory-forms-builderSkill
- factory-formsSkill
- factory-frontend-engineerSkill
- factory-frontendSkill
- factory-kit-auditSkill
- factory-llm-workflow-engineerSkill
- factory-llm-workflowsSkill
- factory-observabilitySkill
- factory-pitfallsSkill
- factory-promptingSkill
- factory-promptSkill
- factory-security-engineerSkill
- factory-securitySkill
- factory-setup-linearSkill
- factory-stackSkill
- factory-standupSkill
- factory-state-modelingSkill
- factory-submitSkill
- factory-testingSkill
- factory-verification-engineerSkill
- factory-verificationSkill
- factory-voiceSkill
The file
We split this skill into the rules it gives an agent
10 rules. About 0 are common, 3 are distinctive, and 7 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈3
Distinctive · estimate
This author's own choices. Worth a look.
7
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 15
Pre-flight: Run in parallel:
- Very specific: line 23
If these disagree, surface all of them explicitly and treat the highest (by semver) as the current base.
- Very specific: line 34
If this is an npm package (package.json with a name, not private): npm view <name> version → the last version on npm.
- Very specific: line 83
Open it in the user's editor: Use the host's safe application-launch capability with $EDITOR when available.
- Very specific: line 88
Wait for the user's reply.
- Distinctive: line 104
Gate 4 — publish GitHub Release?: Only runs if Gate 3 was approved (no tag on origin means nothing to release against).
- Distinctive: line 121
Gate 5 — publish to npm?: Only runs if Gate 3 (push) was approved — publishing a version that isn't on origin recreates the drift this …
- Very specific: line 131
Run npm publish. The package's publishConfig.access governs scope visibility, and any prepublishOnly script builds artifacts first — don't …
- Very specific: line 132
If npm reports a one-time password is required (2FA), ask the user for their OTP code and re-run npm publish --otp=<code>.
- Very specific: line 137
Clean up and confirm: Delete /tmp/factory-kit-release-notes-v<new-version>.md.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
You're cutting a new release. The user owns the final word at every gate and edits the release notes directly in their preferred editor.
A release is one atomic fact — package.json version, the VERSION file, the git tag, the GitHub Release, and the npm publish all name the same thing. This command's job is to advance them together. Letting any one of them move without the others is the drift this command exists to prevent.
Invocation input: patch, minor, or major. If empty, ask through the host's user-interaction capability or directly in chat.
What to do
- Pre-flight. Run in parallel:
git status --porcelain— must be clean. If dirty, list the files and ask whether to abort or stash.git rev-parse --abbrev-ref HEAD— confirm we're on the default branch (typicallymain). If not, warn and ask before proceeding.Establish the current version from up to three sources, and detect drift between them:
package.jsonversion(if apackage.jsonexists) — the source npm publishes from.VERSIONfile at repo root (if present).- Latest git tag:
git describe --tags --abbrev=0(strip leadingv).
If these disagree, surface all of them explicitly and treat the highest (by semver) as the current base. Drift is exactly what this command exists to close — name it, don't silently pick one. If none exist, treat current as
0.0.0.
- Compute the new version from the reconciled base:
patch:X.Y.Z → X.Y.(Z+1)minor:X.Y.Z → X.(Y+1).0major:X.Y.Z → (X+1).0.0
- Check for tag collision.
git rev-parse v<new-version> 2>/dev/null— if it resolves, fail with a clear message and stop. Don't overwrite an existing tag. - Establish the baseline and enumerate the version spans. The breakdown starts from the last published point, not merely the last tag — so versions that were tagged but never shipped still get a changelog entry.
- Baseline:
- If this is an npm package (
package.jsonwith aname, notprivate):npm view <name> version→ the last version on npm. The baseline ref is its tagv<published>if that tag exists; if the tag is missing, fall back togit describe --tags --abbrev=0and note the mismatch. - Otherwise: baseline = previous tag
git describe --tags --abbrev=0. If no tags exist at all, baseline = the initial commit.
- If this is an npm package (
- Enumerate every version boundary from the baseline to HEAD. List tags with
git tag --list 'v*' --sort=v:refname, keep those strictly greater than the baseline, and append the new version (v<new-version>, spanning the last existing tag → HEAD). This yields an ordered list of spans:(baseline → v_a), (v_a → v_b), …, (v_last → HEAD as v<new-version>). In the normal no-drift case the baseline IS the last tag, so there's exactly one span and the per-version breakdown collapses to a single block automatically. - For each span, gather deterministically (straight from git, no interpretation):
- Commits:
git log <from>..<to> --pretty=format:"%h %s", grouped by Conventional Commits type (feat,fix,refactor,chore,docs,test; anything non-conforming →**other:**with a flag for the user to rewrite). - Diffstat:
git diff --shortstat <from>..<to>→ "N files changed, +X / −Y". - Surface map:
git diff --name-status <from>..<to>, group changed paths by top-level directory and mark added (+), modified (~), deleted (−), renamed (→). For this kit,skills/,agents/,commands/, andbin/ARE the public API surface (see the README's Versioning section), so this line is the at-a-glance "what moved in the surface."
- Commits:
- Identify the dominant theme across the whole span (largest user-facing group,
feat>fix>refactor>chore) for the top-level Outcome line. - Extract any Linear IDs (
<TEAM>-<NUM>) across all spans for the Refs line.
- Baseline:
Write the draft to a file the user can actually edit. Use the host's filesystem-write capability to create
/tmp/factory-kit-release-notes-v<new-version>.md. Auto-fill everything you can; leave clearREFINEmarkers where judgment is needed. Order version blocks newest-first — this release at the top, older catch-up versions beneath. Shape:**Outcome:** v<new-version> — <one-line summary of the dominant change across the span — REFINE> **Why:** <best guess from the dominant type — REFINE THIS> <!-- Catch-up line: include ONLY when unpublished versions exist between the baseline and the previous tag --> **Catch-up:** npm last shipped v<baseline>; this release also folds in v<a>…v<last> that were tagged but never published. Per-version breakdown below. ## Changes by version ### v<new-version> — this release _<N files changed, +X / −Y>_ **feat:** - <subjects> **fix:** - <subjects> <omit any empty group> **Surface:** Skills ~factory-api.md +factory-x.md · Commands ~release.md · Bin +factory-kit-check.js <!-- omit the Surface line for a span if nothing under skills/ agents/ commands/ bin/ changed --> ### v<last-existing-tag> _<diffstat>_ **feat:** - … **Surface:** … <!-- …one block per span, down to v<baseline+1>… --> **Refs:** <aggregated Linear IDs across all spans — omit line if none>- Open it in the user's editor. Use the host's safe application-launch capability with
$EDITORwhen available. If the host cannot launch applications, tell the user the path and ask them to open it manually. Gate 1 — wait for the user. Print:
Draft is ready at
/tmp/factory-kit-release-notes-v<new-version>.md. Edit anything you want —Why,Outcome, the bullets, all of it. Save the file and replydone(orcancelto abort).Wait for the user's reply. On
cancel, delete the temp file and stop.- Read back what they saved. Use the host's filesystem-read capability on the temp file. Print a brief diff summary (or just the final content if the diff would be longer than the file). Extract the Outcome line's summary fragment (the text after
—) to use as the commit subject. Ask one final confirmation:Final notes shown above. Confirm to write the version bump + commit + tag, or reply with another round of edits and I'll wait again.
- Gate 2 — write. On confirmation, bump every version source that exists, in lockstep:
- package.json (if it exists and
privateis nottrue):npm version <new-version> --no-git-tag-version --allow-same-version. This rewritespackage.json(andpackage-lock.jsonif present) without making its own commit or tag — this command owns the commit. If the repo has nopackage.json, skip this and note it. - VERSION file (only if it existed before): write the new version to it.
git addeverything that changed:package.json,package-lock.json,VERSION(whichever apply).git commit -m "release: v<new-version> — <outcome-summary>"— the summary comes from the Outcome line in the notes. Keep the full header ≤ 72 chars (truncate the summary if needed; full text is in the tag annotation).git tag -a v<new-version> -F /tmp/factory-kit-release-notes-v<new-version>.md— pass the file directly so multi-line formatting (the full per-version breakdown) is preserved in the annotation.
- package.json (if it exists and
- Gate 3 — push? Show local state (
git log -1 --oneline,git tag --list 'v*' | tail -3) and ask explicitly whether to push. Don't pre-authorize. On yes:git push origin HEADgit push origin v<new-version>
Gate 4 — publish GitHub Release? Only runs if Gate 3 was approved (no tag on origin means nothing to release against). Pre-checks:
git remote get-url origin | grep -q github.com— if origin isn't GitHub, skip this gate entirely (don't ask).command -v gh— ifghisn't on PATH, print the manual one-liner and the Releases URL, then skip. Don't fail the run.
Otherwise ask explicitly:
Publish a GitHub Release for v
<new-version>? Notes come from the tag annotation. (y/n)On yes, run:
gh release create v<new-version> \ --title "v<new-version> — <outcome-summary>" \ --notes-file <(git tag -l v<new-version> --format='%(contents)')<outcome-summary>is the same fragment used for the commit subject (step 8). The annotation carries the full per-version breakdown, so the Release page shows the catch-up changelog. Print the returned Release URL.Rationale: tag and GitHub Release should be 1:1. Tags are the source of truth for "what shipped"; the Release page is the discoverable changelog and the feed that Renovate/Dependabot watch. Skipping it for patches creates "did this ship?" gaps on the Releases page.
Gate 5 — publish to npm? Only runs if Gate 3 (push) was approved — publishing a version that isn't on origin recreates the drift this command exists to prevent. Pre-checks (skip the gate, don't fail the run, when one isn't satisfied):
package.jsonexists, has aname, andprivateis nottrue— if not, this isn't a publishable npm package; skip entirely (don't ask).npm whoami— if it errors (not logged in), print:Not logged in to npm. Runnpm login, thennpm publishfrom <repo-dir> to ship v<new-version>.and skip.npm view <name>@<new-version> version— if it returns the version, it's already on npm; print that and skip.- Show exactly what will ship: run
npm publish --dry-runand surface the tarball file list and the version line.
Otherwise ask explicitly:
Publish v
<new-version>to npm? Tarball shown above. (y/n)On yes:
- Run
npm publish. The package'spublishConfig.accessgoverns scope visibility, and anyprepublishOnlyscript builds artifacts first — don't add flags it doesn't need. - If npm reports a one-time password is required (2FA), ask the user for their OTP code and re-run
npm publish --otp=<code>. Never ask them to disable 2FA. - On success, print the published version and the URL:
https://www.npmjs.com/package/<name>/v/<new-version>.
Rationale: npm is the distribution surface. If the git tag advances but npm doesn't, the package your users
npxis older than the tag claims — the exact gap this command now closes.- Clean up and confirm. Delete
/tmp/factory-kit-release-notes-v<new-version>.md. Print:Released v
<new-version>. package.json + VERSION bumped, tag pushed (if approved), GitHub Release published (if approved), npm publish done (if approved/applicable). Rungit show v<new-version>to verify the annotation.
Style
Follow factory-voice.md. Five explicit gates — notes (edited by the user), write (version bump + commit + tag), push, GitHub Release, npm publish — none batched, none skipped silently. Gates 4 and 5 auto-skip when the environment can't satisfy them (origin isn't GitHub, gh/npm missing, not logged in, no package.json, already published); they never ask a question the environment can't answer, and they never fail the whole run for a missing optional step — they print the manual fallback and move on.
The version bump in Gate 2 always moves package.json and VERSION together; that lockstep is the anti-drift guarantee. The notes are a per-version breakdown from the last published baseline — every tagged-but-unpublished version gets its own block (commits, diffstat, surface map), so a catch-up publish documents each step instead of collapsing it into one jump; with no drift it's a single block. All of it is deterministic from git — the auto-grouped commit list and diffstat/surface map ARE the changelog; don't editorialize them. Architect judgment goes on the Outcome and Why lines, which the user will rewrite in their editor. If a commit was pushed with --no-verify and doesn't fit the conventional format, surface it under **other:** so the user can decide how to characterize it.
Related
factory-commits.md— the Conventional Commits format this command parsesfactory-voice.md— the shape used for release notes
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
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.

