Release logo

Release

CommunityPopular
tractorjuice
release

Cut a new ArcKit release — bump versions in lockstep, regenerate non-Claude formats, validate plugin/marketplace agreement, tag, and push to standalone repos. Use when the user says 'cut a release', 'release ArcKit', 'ship vX.Y.Z', 'bump the version and release', 'do the release flow', 'tag and publish', or 'push the extensions'. This is a manual, high-consequence workflow: it never runs automatically.

Overview

Publishertractorjuice
Repositoryarc-kit
Skill namerelease
Stars
2.3K
Forks
282
Bundled files
Instructions only
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • Self-contained

    Everything the model needs lives in the instructions — no extra files to sync.

  • Open source

    Published by tractorjuice on GitHub. Read the source before you install it.

Installation

Install the Release AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
    https://github.com/tractorjuice/arc-kit/tree/main/.claude/skills/release
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/tractorjuice/arc-kit.git /tmp/arc-kit
mkdir -p .claude/skills
cp -r /tmp/arc-kit/.claude/skills/release .claude/skills/release
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Release in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Release on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Release is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

Release ArcKit

Drive the ArcKit release flow end to end. This skill is the executable companion to docs/RELEASING.md — that doc is the source of truth; if the two disagree, trust RELEASING.md and update this skill.

The target version is $ARGUMENTS (e.g. /release 5.10.0). If no version was given, ask for it before doing anything — never guess a version.

Preconditions

Confirm all of these before touching version files:

  1. The feature PR is merged to main — releases are cut from main, never from a branch.
  2. Working tree is on main and clean: git checkout main && git pull && git status.
  3. The version $ARGUMENTS is valid semver (X.Y.Z) and greater than the current plugin version (cat plugins/arckit-claude/VERSION) and CLI version (cat VERSION).
  4. GH_TOKEN is set in the environment (needed by push-extensions.sh).

If any precondition fails, stop and surface it. Do not work around it.

Release flow

Run these in order. Each script is idempotent or safe to re-run except the git tag/git push steps. Pause after step 6 (the commit) and after step 8 before tagging to let the user confirm.

bash
# 1. Edit CHANGELOGs by hand — both of them:
#    CHANGELOG.md (CLI) and plugins/arckit-claude/CHANGELOG.md (plugin).
#    Preview what shipped since the last tag to seed the entries:
./scripts/generate-release-notes.sh

# 2. Bump every version file in lockstep (15 locations: VERSION files,
#    manifests, README badges, docs, plugin.json):
./scripts/bump-version.sh X.Y.Z

# 3. Regenerate Codex/OpenCode/Gemini/Copilot/Paperclip formats from the
#    plugin source — MUST run after the bump so the extensions carry the
#    new version:
python scripts/converter.py

# 4. Validate generated extension outputs before committing:
pytest tests/codex/test_codex_extension.py \
  tests/gemini tests/opencode tests/copilot \
  tests/vibe/test_vibe_extension.py \
  tests/paperclip/test_commands_json.py \
  tests/plugin/test_release_process.py

# 5. Sanity-check the tree (no stray edits, counts/versions consistent):
git status && git diff --stat

# 6. Commit the bump — a clean tree is required for `claude plugin tag`:
git add -A && git commit -m "chore: bump version to X.Y.Z"

# 7. Validate EVERY plugin manifest against the marketplace entry.
#    Discover plugins dynamically — do NOT hardcode the list (it grows).
#    Search from `plugins`, not `.`: from the repo root the manifests sit at
#    depth 4, so `find . -maxdepth 3` matches nothing and the loop below
#    "passes" having validated not one plugin.
mapfile -t manifests < <(find plugins -maxdepth 3 -path '*/.claude-plugin/plugin.json' | sort)

(( ${#manifests[@]} > 0 )) || { echo "No plugin manifests found — check the find path"; exit 1; }
echo "Validating ${#manifests[@]} plugin manifests..."

for manifest in "${manifests[@]}"; do
  dir=${manifest%/.claude-plugin/plugin.json}   # PATH — `claude plugin tag` rejects the name
  claude plugin tag "$dir" --dry-run || { echo "VERSION DRIFT: $dir"; exit 1; }
done

# 8. (optional) Prune orphaned plugin deps:
claude plugin prune --dry-run

# 9. Tag the umbrella release and push — this triggers
#    .github/workflows/release.yml, which creates the GitHub Release.
#    Push the tag BY NAME: `git push --tags` pushes every local tag, and
#    published a stray `pre-rebase-*` backup tag during v6.8.0.
git tag -a vX.Y.Z -m "vX.Y.Z"
git push && git push origin vX.Y.Z

# 10. Create native per-plugin tags (arckit--vX.Y.Z, arckit-uae--vX.Y.Z, …).
#    Auto-discovers plugins; idempotent (skips existing tags):
./scripts/tag-plugins.sh X.Y.Z

# 11. Push each distribution to its standalone GitHub repo
#     (tractorjuice/arckit-claude, arckit-gemini, arckit-codex, …).
#     The claude target publishes the full Claude marketplace repo: core at
#     plugins/arckit, overlays under plugins/... paths, only the marketplace,
#     README and LICENSE at the root. This also creates or preserves each
#     repo's vX.Y.Z tag and GitHub Release:
./scripts/push-extensions.sh

After step 11, confirm the GitHub Release was created (the release.yml workflow runs on the vX.Y.Z tag push). Also confirm every standalone repo has a vX.Y.Z tag and GitHub Release, then report the release URLs and which standalone repos were pushed.

Then write the release article for the major features — docs/articles/YYYY-MM-DD-<slug>.md plus a hero generator script, force-added past the drafts-folder gitignore. No Markdown tables — LinkedIn and Medium do not render them; write comparisons as prose. See "Release article" in RELEASING.md for the full conventions (voice, hero style, community block, contributor credits).

Common Gotchas

The highest-signal failures — collected from real releases. Read these before running anything.

  • Releasing from a feature branch. Releases are cut from main after the PR is merged. Tagging a branch ships an unmerged tree. Always git checkout main && git pull first.
  • Forgetting the converter (step 3). bump-version.sh updates the plugin source, but the Codex/OpenCode/Gemini/Copilot/Paperclip copies are generated. Skip converter.py and the extensions ship the old version. The converter must run after the bump and before the commit, so the regenerated files are included.
  • Skipping extension tests. Run the step 4 extension suite after converter.py. It validates Codex, Gemini, OpenCode, Copilot, Vibe, Paperclip, release inventory, version alignment, and platform-specific command rewrites before anything is tagged.
  • Releasing from a Mac. bump-version.sh runs on stock macOS (BSD sed, bash 3.2) and asserts every substitution lands — a does not contain "…" after edit error is pattern drift, not a sed-flavour problem. tag-plugins.sh and push-extensions.sh still need bash ≥ 4: brew install bash, then /opt/homebrew/bin/bash scripts/…. Full macOS notes (uv commands for the converter and tests, the http.postBuffer fix for protocol error: bad line length pushes, GH_TOKEN via gh auth token) live in RELEASING.md's "Releasing from macOS" section.
  • Hardcoding the plugin list. The Claude marketplace now ships 16 plugins (core plus regional, sector, method, agent-architecture, tooling, and supplier overlays) and keeps growing. Older examples listed only 7, silently skipping newer plugins. Discover plugins dynamically (step 7) -- this is the exact bug that shipped arckit-uk-nhs untagged mid-v5.4.0, which is why tag-plugins.sh now auto-discovers. Never copy a static plugin array.
  • A for loop over an empty glob exits 0. Step 7's discovery searched from . while the manifests sit at depth 4, so -maxdepth 3 matched nothing and the validation reported a clean pass having checked not one plugin -- through every release from v6.0.0 to v6.7.4. Dynamic discovery only helps if you assert it found something, hence the count check and the Validating N plugin manifests... line. Treat any loop whose body might never run as unvalidated until it prints what it covered.
  • claude plugin tag takes a PATH, not a plugin name. Passing the name from plugin.json (arckit) resolves relative to the repo root and fails ✘ Path not found: /…/arckit. Use the plugin directory: plugins/arckit-claude. This compounded the bug above -- had the glob ever matched, every iteration would have failed anyway.
  • Validate before tag-plugins.sh, never after. Once the native name--vX.Y.Z tags exist, the dry-run fails with Tag "…" already exists locally -- correct behaviour, not version drift, but it will send you hunting for a problem that isn't there.
  • claude plugin tag needs a clean tree. Run it after the commit (step 6), not before, or it errors on the dirty working tree.
  • claude plugin tag is --dry-run only here. It creates name--vX.Y.Z style tags that do not match release.yml's v[0-9]+.[0-9]+.[0-9]+ trigger. We use it solely for its validation side effect (cross-checking plugin.json vs marketplace.json). The real release tag is the git tag -a vX.Y.Z in step 8.
  • Two CHANGELOGs, not one. CHANGELOG.md is the CLI changelog; plugins/arckit-claude/CHANGELOG.md is the plugin changelog. Both need an entry. They are human-authored — generate-release-notes.sh only previews what changed, it does not write them.
  • CLI and plugin versions are independent but bumped together. bump-version.sh moves both to the same number by design; don't try to skew them.
  • push-extensions.sh needs GH_TOKEN and skips repos that don't yet exist on GitHub — a "skipped" line is not an error for a brand-new extension, but double-check it's not skipping a repo that should exist. The claude target writes the full arckit-claude marketplace repo, including the public-but-proprietary plugins/uk/gcloud/ overlay and its license exception. It now creates/preserves standalone repo vX.Y.Z tags and GitHub Releases; use ARCKIT_SKIP_EXTENSION_RELEASES=1 only when intentionally doing a commit-only sync.
  • Tables in release articles. LinkedIn and Medium do not render Markdown tables — a comparison pasted there lands as a wall of pipes. Write it as prose. Articles live in the gitignored docs/articles/ drafts folder; force-add the keepers (git add -f).
  • Articles are for users, not maintainers. Lead each section with what changed for the reader and why it matters; no file names, hook names, schema or regex talk in the body — say what a mechanism does, not what it is called. Hero labels follow the same rule. The first draft of the commerce-skills article (#845) had to be rewritten for this; the maintainer detail lives in the CHANGELOG and the PR body, which the article can link to.
  • The core plugin publishes to plugins/arckit, not the repo root. Until 6.16.2 it sat at the root, so its plugin folder was the whole repo: the Claude plugin directory's validator timed out on it and every install carried a copy of all the overlays. Anything in the core that needs an overlay's files must look beside the core (${CLAUDE_PLUGIN_ROOT}/../../arckit-*/*/ in the install cache, ${CLAUDE_PLUGIN_ROOT}/../ in a repo checkout), never inside it.
  • Do not put release numbers in extension READMEs. Extension release identity lives in VERSION files, manifests, Git tags, and GitHub Releases. README-pinned versions drift and are blocked by tests/plugin/test_release_process.py.
  • Order is load-bearing. bump → convert → extension tests → commit → validate → tag → tag-plugins → push-extensions. Re-running an earlier step after a later one (e.g. editing files after the commit) means the tag no longer points at the released tree. If you edit after committing, redo from the commit.

Reference

  • docs/RELEASING.md — full release documentation and rationale
  • scripts/bump-version.sh — version bump across all files
  • scripts/generate-release-notes.sh — changelog preview from git log
  • scripts/tag-plugins.sh — native per-plugin tags (auto-discovers)
  • scripts/push-extensions.sh — pushes distribution dirs to standalone repos
  • .github/workflows/release.yml — creates the GitHub Release on v* tag push

Frequently asked questions

What does the Release AI skill do?

Cut a new ArcKit release — bump versions in lockstep, regenerate non-Claude formats, validate plugin/marketplace agreement, tag, and push to standalone repos. Use when the user says 'cut a release', 'release ArcKit', 'ship vX.Y.Z', 'bump the version and release', 'do the release flow', 'tag and publish', or 'push the extensions'. This is a manual, high-consequence workflow: it never runs automatically.

Why use Release on TypingMind?

Because you install it once and use it with any model. Release is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Release in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/tractorjuice/arc-kit/tree/main/.claude/skills/release. TypingMind reads its SKILL.md and installs it as a skill you can enable per chat.

Which AI models can use Release?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Release?

As many as you like. As long as a model supports skills, you can use Release with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Release AI skill free?

It is published on GitHub by tractorjuice. Check the repository for licensing terms. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇