Skip to content
Development
Skill

/release-notes

Maintainer-only. Translate a version's GAIA CHANGELOG entries into plain-language public release notes for the marketing site (gaiareact.com). Writes a release-data `.ts` file under `../website/src/pages/changelog/releases/` plus an editorial-decisions report for human review.

From plugin
gaia-react-gaia
2320 skills10 agents14 commands
Install
$ npx -y skills add gaia-react/gaia --skill release-notes --agent claude-code

How it fires

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

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/release-notes

Context preview

The summary Claude sees to decide when to auto-load this skill.

Maintainer-only. Translate a version's GAIA CHANGELOG entries into plain-language public release notes for the marketing site (gaiareact.com). Writes a release-data `.ts` file under `../website/src/pages/changelog/releases/` plus an editorial-decisions report for human review.

SKILL.md

release-notes.SKILL.md
name: release-notes
description: Maintainer-only. Translate a version's GAIA CHANGELOG entries into plain-language public release notes for the marketing site (gaiareact.com). Writes a release-data `.ts` file under `../website/src/pages/changelog/releases/` plus an editorial-decisions report for human review. Use whenever the maintainer wants the adopter-facing notes for a version, e.g. "write release notes", "generate the changelog page entry", "translate the CHANGELOG for the website", "what's new on the site for v1.5.0", "public notes for 1.4.0", or right after cutting a release, and for one-time backfill of historical `## [x.y.z]` blocks. This is the website-notes step only. It does NOT edit `CHANGELOG.md`, it is not how you cut a release (version bump, manifest, and tag are `/gaia-release`), and it is not for an adopter's own app's release notes.

release-notes

Translate one version's CHANGELOG entries into adopter-facing release notes. The CHANGELOG is written for GAIA's own contributors: terse, imperative, full of internal mechanics and issue numbers. Adopters read the website. They don't care that an ADR was reframed or a memory was promoted; they care what GAIA now does for _their_ project. This skill is the translation layer between the two audiences.

**Maintainer-only.** Adopters never release GAIA, so this skill ships nowhere, it's excluded from the distribution tarball by `.gaia/release-exclude` (category 1), the same as `/gaia-release`. It pairs with `/gaia-release` but runs independently: you can point it at the `[Unreleased]` block while cutting a release, or at any historical `## [x.y.z]` block to backfill the website.

**It never edits `CHANGELOG.md`.** The changelog stays technical and precise, that's its job. This skill only _reads_ it.

Pre-flight: Worktree check

This skill writes into the sibling website checkout, resolved relative to the main checkout. 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 "/release-notes" || exit 1

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

Inputs

Invocation carries a target version, e.g. `release-notes 1.4.0` (no leading `v`). Resolve which CHANGELOG block to translate, and where the date comes from, by that version:

  • **Graduated / historical**: `CHANGELOG.md` contains `## [<version>], <YYYY-MM-DD>`. Translate that block. Take `version` and `date` **verbatim from the header**. The release already happened on that date; the shell clock is irrelevant.
  • **Live cut**: the version isn't graduated yet; its entries live under `## [Unreleased]`. Translate that block. `version` is the argument (the maintainer is cutting it now). `date` is **today from the shell clock** (`date +%F`).

If no version was supplied and an `[Unreleased]` block exists, ask the maintainer which version is being cut, the version label has to come from a human, not a guess.

The date is never yours to invent

Whether historical or live, the date comes from the CHANGELOG header or the shell, **never** from your own notion of "today." Models routinely misdate by months; a wrong `date` silently ships a wrong timeline to every visitor. For a live cut, run `date +%F` and use exactly that. This is the same discipline GAIA enforces for wiki playbook dates.

Output (a): the release data file

Write to `../website/src/pages/changelog/releases/<version>.ts` (version with no leading `v`; `mkdir -p` the directory if it's missing). The changelog page auto-discovers every file via `import.meta.glob('../releases/*.ts')` and sorts by version, so **dropping the file in is all that's needed**, there's no index or import list to update.

**The schema lives in `../website/src/pages/changelog/types.ts` (the `Release` type), read it as the source of truth before writing.** As of this writing it is:

export type Release = {
  added?: string[]; // "New"
  date: string; // ISO yyyy-mm-dd
  fixed?: string[]; // "Fixed"
  headline?: string;
  improved?: string[]; // "Improved"
  summary?: string; // freeform fallback for legacy/coarse entries
  version: string; // semver, no leading 'v'
};

**Match the file form of the existing release files, don't trust this skill's literal shape.** The website's convention drifts (export style and key order have both changed). Before writing, open the newest `releases/*.ts` and mirror it exactly: `types.ts` gives you the _fields_, a live sibling file gives you the _serialization_. Today that form is a bare default export with keys in **alphabetical order** (the formatter sorts them). Omit any optional key with no content:

export default {
  added: ['...'],
  date: '2026-06-02',
  fixed: ['...'],
  headline: 'A short title or one plain sentence.',
  improved: ['...'],
  version: '1.4.0',
};
  • `added` → "New" (capabilities that didn't exist before). `improved` → "Improved" (changed/enhanced behavior). `fixed` → "Fixed".
  • `headline`, **required for any bucketed release** (one or more `added`/`improved`/`fixed` items). A short title or one plain sentence, leading with the release's reason to exist. The buckets render with no title of their own, so a bucketed card with no `headline` ships titleless (this is exactly how `1.1.0` lost its title). A grab-bag with no single story still gets a `headline`: use a descriptive umbrella line naming the two or three biggest items ("Built-in a11y testing, dead-code detection, and Serena code intelligence"), never nothing. The only way to omit `headline` is to let a `summary` carry the lead instead (see below). For a newly-shipped capability, carry the rule 1 `now` into the headline too, "GAIA apps now ship with a CSP", not "ship with". The website build
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 skills on gaia-react-gaia.