Skip to content
Development
Command

/gaia-release

Cut a new GAIA release, bump version, graduate CHANGELOG, regenerate manifest, open release PR, then tag on merge. Maintainer-only.

From plugin
gaia-react-gaia
2314 skills10 agents14 commands
Install
$ npx -y skills add gaia-react/gaia --agent claude-code

How it fires

How this command gets triggered: by you, by Claude, or both.

  • Fires itselfClaude auto-loads it when your prompt matches the work.
  • You can call itInvoke it directly when you want it.
  • Slash command/gaia-release

Context preview

What this command does when you run it.

Cut a new GAIA release, bump version, graduate CHANGELOG, regenerate manifest, open release PR, then tag on merge. Maintainer-only.

Command definition

gaia-release.md
name: gaia-release
description: Cut a new GAIA release, bump version, graduate CHANGELOG, regenerate manifest, open release PR, then tag on merge. Maintainer-only.
argument-hint: patch|minor|major

Cut a new GAIA release. Thin orchestrator over the `.gaia/cli/gaia-maintainer release` CLI namespace, which owns every deterministic step (preflight checks, semver bump, CHANGELOG graduation, wiki scrub, manifest regen, commit + tag dance). This command sequences the CLI subcommands and surfaces user-facing prompts where human judgment is required.

This command is **maintainer-only**, both this slash command and the `gaia-maintainer` binary are stripped from distributed tarballs by `.gaia/release-exclude` so adopters never see them. The adopter `gaia` binary has no `release` namespace at all; only `gaia-maintainer` does. Unlike `/gaia-init`, this command does not self-delete; it runs every release.

> [!important] `main` is protected > Direct pushes to `main` are blocked. The release commit lands on a `release/v<NEW_VERSION>` branch, goes through a PR, and the tag is created on the merge commit _after_ it lands on `main`. The release PR is subject to the same CI gate and the same Code Audit Team merge handshake as any other PR. Expect `Vitest and Playwright`, `Run Chromatic`, and `Vitest (.gaia/cli)`: a release PR bumps the version and rebundles both CLI binaries, so it always touches `.gaia/cli/**` and always runs that job's full typecheck, lint, vitest, and bundle-freshness path rather than its filter-miss fast pass. `gh pr merge --merge --auto` is the normal path: base-branch protection rejects a plain `--merge`, so `--auto` is required to queue the merge until checks pass. See `wiki/concepts/PR Merge Workflow.md`.

Required argument

Invocation: `/gaia-release patch|minor|major`. The argument is the **sole authority** for the version bump.

If the argument is missing, including when `/gaia-release` is reached as part of a larger batch of work ("ship this then release", a multi-step plan that ends in release, a chained workflow), **STOP and ask the maintainer via `AskUserQuestion`** before any preflight / branch / commit step. Do not infer the bump from commit prefixes, diff size, or the `gaia-maintainer release bump` proposal.

The conventional-commit scan over-proposes `minor` for CI/plumbing commits incorrectly tagged `feat:` that are patch-level in spirit; the maintainer is the only reliable source for semver intent. Never proceed without an explicit `patch|minor|major` from the maintainer.

Pre-flight: Worktree check

This command bumps `.gaia/VERSION`, commits and tags on `main`, and opens the release PR, all main-checkout operations that must never run from a per-SPEC worktree branch. If invoked from a linked worktree, reject hard: `gaia_refuse_if_worktree` (`.gaia/scripts/main-only-lib.sh`) asks the shared resolver which tree this is and refuses out loud, naming the main checkout, when the answer is a worktree.

Detection (run this first, before anything else):

. .gaia/scripts/main-only-lib.sh
gaia_refuse_if_worktree "/gaia-release" || exit 1

If the detection does not fire, fall through to `### 1. Preflight` below.

Workflow

The CLI surface is the source of truth. The classification rules for `.gaia/manifest.json` live in code (`.gaia/cli/src/release/manifest.ts`); the on-disk manifest is the single source of truth for `/update-gaia` consumers.

1. Preflight

.gaia/cli/gaia-maintainer release preflight

Verifies: on `main`, clean working tree, and `wiki/.state.json` is current. The wiki check reads `gaia wiki state --json`: a reachable state passes on `commits_ahead === 0`; an orphaned state (`reachable:false`, the normal post-squash-merge condition, where `commits_ahead` is hardcoded `0`) is re-evaluated over `suggested_base..HEAD` so an un-evaluated window isn't read as a silent zero. Either way, drift that is only wiki-sync squash artifacts passes; substantive drift exits non-zero with an explanation. STOP and report; the maintainer fixes (commit, push, run `/gaia-wiki sync`) and re-runs `/gaia-release`.

1b. Fold any local rate overlay upstream

bash .gaia/scripts/cost-unpriced-scan.sh

`overlay_active` names the models this machine is pricing from `.gaia/local/token-rates.local.json` rather than from the shipped `.gaia/scripts/token-rates.json`. Every name in it is a rate adopters do **not** get, so the release is the moment to decide whether it belongs in the shipped table.

For each name: if the rate is real and current, add it to `.gaia/scripts/token-rates.json` now, before the bump, so it ships. If it was a local experiment, leave it. Either way the overlay entry stays where it is; it is machine-local and harmless, and removing it would only re-open the gap on this machine until the release lands.

Not a gate. An empty `overlay_active`, or a non-zero exit because there is no ledger yet, is the ordinary case and blocks nothing. This step exists so an overlay entry does not calcify into permanent shadow config that silently diverges from what adopters receive.

`unpriced` in the same output names a model **nothing** can price, shipped table or overlay. That is worth a look at release time for the same reason, but it is not release-blocking either.

2. Apply the bump

Use the maintainer's argument from "Required argument" as `<BUMP>`. The CLI's `release bump` proposal is **informational only**, print it for awareness, then proceed with `<BUMP>` regardless:

.gaia/cli/gaia-maintainer release bump            # propose only, informational

If the proposal disagrees with `<BUMP>`, surface the disagreement once (e.g. "CLI proposed minor from `feat(ci):` commits; you specified patch, proceeding with patch") but do not re-prompt.

Apply by path:

  • **`<BUMP>` ≥ proposal, not major:** `.gaia/cli/gaia-maintainer release bump --auto`, writes `package.json` + `.gaia/VERSION`.
  • **`<BUMP>` < proposal** (e.g.
Read more
Ships withgaia-react-gaia

Claude is raw power. GAIA is order and focus. The foundation that keeps Claude-shipped code production-grade as your team scales. The React frontend is handled. You build the rest of your app on top. Every convention enforced in code.

Get the whole plugin

Other commands on gaia-react-gaia.