Agent skill

Release

by matthiasn in matthiasn/lotti

Cut a Lotti release — assemble the changelog.d/ fragments into CHANGELOG.md and the Flathub metainfo, bump the version, open the release PR, then tag.

GPL-3.0Auto-check passedDevelopment

Install Release

skills CLI
$ npx skills add matthiasn/lotti --skill release -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install matthiasn/lotti release --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/matthiasn/lotti.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/release .claude/skills/release && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
release
GitHub stars
1.2k
Token cost
~2.6k tokens
SKILL.md length
1,307 words
Files
1
Skills in repo
10
Repo updated
First seen
Licence
GPL-3.0

At a glance

Cut a Lotti release — assemble the changelog.d/ fragments into CHANGELOG.md and the Flathub metainfo, bump the version, open the release PR, then tag.

  • Works in 10 steps: Read every fragment → Choose the version → Assemble the CHANGELOG section → …
  • Prepare a release
  • SKILL.md covers Before you start, 1. Read every fragment, 2. Choose the version and 3. Assemble the CHANGELOG…, plus 8 more sections
  • Calls git, make and brew

What it does

Release is an agent skill from matthiasn/lotti. Cut a Lotti release — assemble the changelog.d/ fragments into CHANGELOG.md and the Flathub metainfo, bump the version, open the release PR, then tag. Use when asked to cut or prepare a release, assemble the changelog, publish a new version, or work out what is unreleased.

Its SKILL.md is about 2.6k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

It sits in Development, covering Changelog and release notes. The repository describes itself as: A private logbook with a staff of personal AI assistants. Agents read what you record and propose what to do next — you approve the changes. End-to-end encrypted sync between… The licence is GPL-3.0.

When your agent uses it

  • Prepare a release
  • Assemble the changelog
  • Publish a new version
  • Work out what is unreleased

Example prompts

  • “/release”

Workflow steps

10 steps, taken from the step headings in SKILL.md.

  1. Read every fragment
  2. Choose the version
  3. Assemble the CHANGELOG section
  4. Write the Flathub release block
  5. Bump the version
  6. Delete the fragments you consumed
  7. Verify
  8. Open the release pull request
  9. Tag, after it merges
  10. Downstream, and out of scope here

What it can do on your machine

Read from SKILL.md and the folder at commit 2a438d2. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • git
    • make
    • brew

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md. Its commands use git, which can reach the network depending on how they are called.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Release loads about 2.6k tokens when it runs. Until then it costs about 70 tokens; SKILL.md has 1,307 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~70
When it runs · the whole SKILL.md, loaded when a task matches
~2.6k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from matthiasn/lotti at commit 2a438d2, republished under its GPL-3.0 licence (© matthiasn). 1,307 words, ~2,641 tokens.

Download SKILL.mdSave it as .claude/skills/release/SKILL.md (or your agent's skills folder).
name
release
description
Cut a Lotti release — assemble the changelog.d/ fragments into CHANGELOG.md and the Flathub metainfo, bump the version, open the release PR, then tag. Use when asked to cut or prepare a release, assemble the changelog, publish a new version, or work out what is unreleased.

Cut a release

Release notes are written per change as fragments in changelog.d/, one new file per pull request, and assembled once per release. A release is therefore a small, boring, self-contained pull request: it turns the fragments into prose in two files, moves the version, and deletes what it consumed.

This is the only change allowed to touch CHANGELOG.md, flatpak/com.matthiasn.lotti.metainfo.xml, or the version: line in pubspec.yaml. That rule is the whole point — those three files are written at the top by everything, so as long as exactly one pull request per release writes them, nothing can conflict. If you are here for any other reason, you are in the wrong skill; write a fragment instead (changelog.d/README.md).

Before you start

bash
git checkout main && git pull
ls changelog.d/[0-9]*.md       # the work queue; README.md is not a fragment
fvm dart run tool/changelog/validate.dart --strict

--strict rather than make changelog_check: the house-style warnings the author-facing check only prints — an entry with no bold headline, a paragraph pasted as one long line — are about to become published prose, so here they block.

  • Work from an up-to-date main. A release assembled on a stale branch drops whatever merged in the meantime.
  • If changelog.d/ holds nothing but its README, there is nothing to release. Say so and stop.
  • Fix any malformed fragment here, in the release branch. It is cheaper than sending the author back.
  • A fragment describing something that was reverted before it shipped gets deleted, not published.

Ask before committing, pushing or tagging. Every step below writes files; the git operations are the user's call, always.

1. Read every fragment

Read them all before writing anything. You are producing one coherent set of release notes, not a concatenation: two fragments may describe two halves of the same user-visible change and should be merged into one entry, and a later fragment may supersede an earlier one.

2. Choose the version

bash
grep -m1 '^version:' pubspec.yaml     # e.g. version: 1.0.13+4352
  • Bug fixes alone: keep the semantic version unchanged and increment only the build number (1.0.21+4362 → 1.0.21+4363). A fix-only release appends its notes to the current top changelog section and metainfo release block; it must not create a duplicate ## [1.0.21] heading or <release version="1.0.21"> block.
  • User-facing additions or changes: increment the patch version and the build number (1.0.21+4362 → 1.0.22+4363). Any publishable Added, Changed, Deprecated, or Removed entry makes this a user-facing release.
  • Explicit minor release: increment the minor version and reset the patch component to zero only when the user explicitly requests a minor release (1.0.21+4362 → 1.1.0+4363). The build number still increments normally.
  • Build number: always previous + 1. It only has to be unique and increasing per tag — every release lane triggers on tag push, not on merges to main — so it moves once per release, not once per pull request.

If the user named a version, use it. Otherwise propose one from what the fragments contain and confirm it.

3. Assemble the CHANGELOG section

For a user-facing release, insert one new section at the top of CHANGELOG.md, directly under the Keep a Changelog preamble and above the previous version:

markdown
## [1.0.22]
### Added
- **...**

### Changed
- **...**

### Fixed
- **...**
  • One section per type, in this order: Added, Changed, Deprecated, Removed, Fixed, Security. Skip the ones with no entries. Never repeat a heading inside a version — older sections do, because entries used to be appended one PR at a time; assembling from fragments is what fixes that.
  • The version heading carries no date. That is the file's existing shape.
  • Keep each entry's wording as the fragment wrote it, minus edits for duplication, house voice, or an entry that reads oddly next to its neighbours.
  • Wrap at about 78 columns, continuation lines indented two spaces.

For a fix-only build release, add the new bullets to the current top semantic version instead. Reuse its existing ### Fixed heading, or create that heading in the normal section order if it does not have one. Never create a second version section or a second ### Fixed heading.

4. Write the Flathub release block

For a user-facing release, add one <release> to flatpak/com.matthiasn.lotti.metainfo.xml, as the first child of <releases> — newest first:

xml
<release version="1.0.22" date="2026-08-25">
  <description>
    <p>Fixed: ...</p>
  </description>
</release>

This is the same prose, mechanically transformed. AppStream renders <p> as plain text: markdown does not survive it, and an unescaped & breaks the build.

For a fix-only build release, append the new Fixed: paragraphs to the description of the existing first <release> block and update that block's date to the day the build is cut. Do not create a duplicate release block for the unchanged semantic version.

In CHANGELOG.mdIn the metainfo
one - bulletone <p>, same order as the section
the ### Fixed heading above itthe prefix Fixed: on every paragraph in that section
- **Bold headline.** Detail…Fixed: bold headline. Detail… — bold markers dropped, first letter lowercased unless it is a proper noun (Settings, Flathub)
hard-wrapped over several linesone long line
— or –-
`code` or a glyph like •••plain words a user recognises — "...", the "Location with the name CEST doesn't exist" error
&, <, >&amp;, &lt;, &gt;

Worked example, from 1.0.13:

markdown
- **Daily habit reminders arrived hours late on iPhone, iPad and Android.** The
  app could not work out which timezone the device was in, quietly settled for
  UTC, and then built the reminder's time of day in UTC — so an 08:00 habit
  reminder rang at 10:00 in Central European Summer Time.
xml
<p>Fixed: daily habit reminders arrived hours late on iPhone, iPad and Android. The app could not work out which timezone the device was in, quietly settled for UTC, and then built the reminder's time of day in UTC - so an 08:00 habit reminder rang at 10:00 in Central European Summer Time.</p>

The date is the day the release is cut, YYYY-MM-DD.

Show full SKILL.md (501 more words)Show less

5. Bump the version

One line in pubspec.yaml:

yaml
version: 1.0.22+4363

6. Delete the fragments you consumed

bash
git rm changelog.d/[0-9]*.md       # fragments start with their date; README.md does not

Everything you just published goes. changelog.d/ holding only its README is what "nothing unreleased" looks like; git history keeps the originals.

7. Verify

bash
make changelog_check                                     # versions now agree
xmllint --noout flatpak/com.matthiasn.lotti.metainfo.xml # if available
git status --short

git status must show exactly four kinds of change and nothing else: CHANGELOG.md, the metainfo, pubspec.yaml, and deleted fragments. A release PR that also carries code is a release PR that can conflict.

Re-read the assembled section once as a user would. It is the text that reaches Flathub, the GitHub release and the app's What's New — it is read far more often than it is written.

8. Open the release pull request

Use the semantic version in the title for a user-facing release:

chore(release): 1.0.22

Use the full version and build for a fix-only release so it is distinguishable from the release that first introduced that semantic version:

chore(release): 1.0.21+4363

Body: the entries assembled for this release, grouped under their release headings, so review reads the new notes rather than the diff. For a fix-only release, label the body with the full version and build even though the changelog heading remains the unchanged semantic version. No screenshots — nothing visual changed.

9. Tag, after it merges

bash
git checkout main && git pull
make tag_push        # tags 1.0.22+4363 from pubspec.yaml and pushes it

make tag_push reads the version with yq; install it (brew install yq) or tag by hand with the exact version+build string if the target reports it missing.

The tag is what ships. Pushing it triggers, in parallel: macOS and iOS TestFlight, the Android release, the Linux GitHub release, the macOS signed .dmg, and the Flathub submission PR against flathub/com.matthiasn.lotti — which is why the metainfo has to be right before the tag, not after.

On Google Play the release tag stops at internal testing. Moving that build on is a separate tag from the same commit, once the internal upload has finished: make android_closed_testing for closed testing, make android_release for production. Both promote the build Play already has rather than rebuilding it; the mechanism is the Google Play tracks section of knowledge/architecture/platform-and-release.md.

Confirm with the user before tagging. Watch the lanes; docs/macos-release.md and docs/flatpak-flathub-recovery.md cover the two that fail in interesting ways.

10. Downstream, and out of scope here

The app's What's New modal reads from the separate matthiasn/lotti-docs repository (whats-new/), not from this one. Publishing there is an editorial step in that repo — mention it once the release is tagged; do not attempt it from here.

Gotchas

  • The metainfo lagging a version behind is invisible until Flathub ships it. make changelog_check fails on exactly that, which is why it runs in CI on every push rather than only at release time.
  • Tags carry the build number (1.0.14+4353), and every release lane keys on tag push. Re-tagging the same build number to fix a mistake will not give you a fresh TestFlight build; bump the build number and cut again.
  • Do not fold anything else into the release PR — not a "quick fix", not a dependency bump. The moment it carries code it can conflict, and the reason this flow exists is gone.

© matthiasn, GPL-3.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in .agents/skills/release of matthiasn/lotti.

Open the folder on GitHubat commit 2a438d2

Compare with similar skills

Release next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Release compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Release this skillmatthiasn/lotti1.2k—~2.6kAutomated safety check: PassGPL-3.0
Simple Englishmoeru-ai/airi50k2 repos~4.6kAutomated safety check: PassMIT
StarRocks Release NotesStarRocks/starrocks12k—~1.9kAutomated safety check: NotesApache-2.0
Cutting A ReleaseTriliumNext/Trilium38k—~3.2kAutomated safety check: PassAGPL-3.0
React Router Release Notes Prepremix-run/react-router57k—~1.1kAutomated safety check: PassMIT
Mole CLI Release Flowtw93/Mole70k—~2.6kAutomated safety check: PassGPL-3.0

Similar skills

  • Simple English

    moeru-ai/airi

    Write or rewrite technical text with the rules of ASD-STE100 Simplified Technical English so it is clear, unambiguous, and free of AI slop.

    50k GitHub starsUsed in 2 repos~4.6k tokens
    DevelopmentAuto-check passed
  • StarRocks Release Notes

    StarRocks/starrocks

    Drafts English release notes for a StarRocks patch release from the PRs merged into its release branch, then opens a documentation PR and hands translation to /translate.

    12k GitHub stars~1.9k tokensUpdated today
    DevelopmentAuto-check: notes
  • Cutting A Release

    TriliumNext/Trilium

    A skill your agent uses when cutting, preparing, or debugging a Trilium release — bumping the monorepo version, tagging, or diagnosing a failed "Release" workflow run.

    38k GitHub stars~3.2k tokensUpdated today
    DevelopmentAuto-check passed
  • React Router Release Notes Prep

    remix-run/react-router

    Polishes pending React Router change files before the versioning scripts run, and decides whether a long-form What's Changed section is warranted.

    57k GitHub stars~1.1k tokensUpdated yesterday
    DevelopmentAuto-check passed
  • Runbook for assessing and executing a Mole CLI release: distribution channels, pre-flight checks, capital-V tags, build artifacts and the handoff to curated release notes.

    70k GitHub stars~2.6k tokensUpdated yesterday
    DevelopmentAuto-check passed
  • Release

    PrefectHQ/fastmcp

    Cut a FastMCP release end to end. An agent skill from PrefectHQ/fastmcp.

    28k GitHub stars~2.9k tokensUpdated today
    DevelopmentAuto-check passed

More from matthiasn/lotti

All 10 skills in this repo
  • Add, complete, or audit a locale across a Flutter application's ARB catalogs and a localized Docusaurus manual, including generated localization code, locale selectors, native platform declarations…

    1.2k GitHub stars~1.2k tokensUpdated today
    Auto-check passed
  • Maintain a Docusaurus product manual whose prose, navigation, localized page trees, screenshots, coverage metadata, and release build must stay aligned with the application.

    1.2k GitHub stars~930 tokensUpdated today
    Auto-check passed
  • App Screenshots

    matthiasn/lotti

    Capture in-app screenshots of a widget or flow at mobile + desktop sizes — offline, deterministic, real fonts and icons — using the reusable screenshot harness.

    1.2k GitHub stars~1.9k tokensUpdated today
    Auto-check passed
  • Beads

    matthiasn/lotti

    A skill your agent uses for authorized Lotti maintainer work that needs private durable task tracking, issue dependencies, blocker management, multi-session handoff, or shared agent memory.

    1.2k GitHub stars~589 tokensUpdated today
    Auto-check passed
  • Design Review Panel

    matthiasn/lotti

    Run a multi-agent design review on a UI surface — capture reproducible baseline screenshots, then rate them with a panel of design experts (one agent per craft dimension) and, optionally, a panel of…

    1.2k GitHub stars~1.6k tokensUpdated today
    Auto-check passed
  • Tutorial Videos

    matthiasn/lotti

    Build, debug, extend, localize, or publish the automated tutorial videos — the workbench that drives the real Linux app under Xvfb (virtual mic, live Voxtral transcription, task-agent proposals)…

    1.2k GitHub stars~2.2k tokensUpdated today
    Auto-check: notes

Categories

Questions about Release

What does Release do?

Cut a Lotti release — assemble the changelog.d/ fragments into CHANGELOG.md and the Flathub metainfo, bump the version, open the release PR, then tag. Release is an agent skill from matthiasn/lotti.md and the Flathub metainfo, bump the version, open the release PR, then tag.

When should I use Release?

Release fits situations like: prepare a release; assemble the changelog; publish a new version; work out what is unreleased.

How do I install Release in Claude Code?

Run `npx skills add matthiasn/lotti --skill release -a claude-code`. Or copy the skill folder (.agents/skills/release in matthiasn/lotti) into .claude/skills/release in your project. Claude Code loads it when a task matches its description.

How do I install Release in Codex?

Run `npx skills add matthiasn/lotti --skill release -a codex`. Or copy the skill folder (.agents/skills/release in matthiasn/lotti) into .agents/skills/release in your project. Codex loads it when a task matches its description.

Can I use Release in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add matthiasn/lotti --skill release -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/release, .gemini/skills/release, .github/skills/release and .opencode/skills/release in your project.

What does Release need to run?

Going by SKILL.md and its folder, Release needs the command-line tools its instructions call (git, make and brew).

Does Release access the network?

SKILL.md contains no URLs. Its commands use git, which can reach the network depending on how they are called. This is read from the text; nothing was executed.

Is Release safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Release use?

Release is published under the GPL-3.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Release use?

About 2.6k tokens (SKILL.md is roughly 11k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Release?

Skills that share tags, products or a category with Release: Simple English (moeru-ai/airi, 50k stars), StarRocks Release Notes (StarRocks/starrocks, 12k stars), Cutting A Release (TriliumNext/Trilium, 38k stars) and React Router Release Notes Prep (remix-run/react-router, 57k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Release?

matthiasn (a GitHub user) maintains it in matthiasn/lotti, which has 1,199 GitHub stars. The repository holds 10 skills in this directory. The repository was last updated on October 9, 2026.

Source: matthiasn/lotti on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.