.claude/skills/release/SKILL.md
Release a new version of OMI Desktop. Analyzes changes since last release, generates changelog, and runs the full release pipeline.
npx skillsauth add m13v/fazm releaseInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Release a new version of the OMI Desktop app with auto-generated changelog.
NEVER run release.sh more than once. Each run generates a unique EdDSA signature for the Sparkle ZIP. If you run it twice, the second run creates a new ZIP with a different signature but GitHub keeps the old ZIP — causing "improperly signed" errors for all users.
NEVER run release steps manually. Always use ./release.sh for the entire pipeline.
If release.sh fails mid-way:
release.sh during a release to fix the issuerelease.sh for the user to approve./release.sh [version] from the beginning after fixesWhy? Manual steps lead to errors (wrong entitlements, wrong endpoints, missing signatures). The script is designed to run as a complete unit.
Exception: If the failure is in the project code itself (not release.sh), fix the project code, then re-run release.sh.
release.sh logs all output to /private/tmp/omi-release.log. Use this to check progress:
# Check current step
tail -20 /private/tmp/omi-release.log
# Watch live progress
tail -f /private/tmp/omi-release.log
# Check if release.sh is still running
ps aux | grep 'release.sh' | grep -v grep
# Check if release was published to GitHub
gh release list --repo BasedHardware/omi --limit 3
# Check if appcast is serving the new version
curl -s https://desktop-backend-hhibjajaja-uc.a.run.app/appcast.xml | grep shortVersionString
If the Bash tool sends release.sh to background (long-running command), do NOT re-run it. Instead:
/private/tmp/omi-release.log to see progressps aux | grep release.sh to confirm it's still runningLAST_TAG=$(git tag -l 'v*' | sort -V | tail -1)
echo "Last release: $LAST_TAG"
git log ${LAST_TAG}..HEAD --oneline --no-merges
Review the commits and create a concise changelog. Group changes by category:
Keep it user-friendly - focus on what users will notice, not internal changes.
Changelog entries are auto-accumulated by agents in the unreleased array of CHANGELOG.json. Before releasing, verify entries exist and add any missing ones:
# Check current unreleased entries
python3 -c "import json; data=json.load(open('CHANGELOG.json')); print('\n'.join(data.get('unreleased', [])) or '(empty — add entries before releasing)')"
If unreleased is empty, review the commits from Step 1 and add entries:
python3 -c "
import json
with open('CHANGELOG.json', 'r') as f:
data = json.load(f)
data.setdefault('unreleased', []).extend([
'Your changelog item 1',
'Your changelog item 2'
])
with open('CHANGELOG.json', 'w') as f:
json.dump(data, f, indent=2)
f.write('\n')
"
The GitHub Actions workflow (desktop_auto_release.yml) consolidates these into a versioned release entry when the tag is created. The release script reads releases[0] for both GitHub release notes and Sparkle appcast.
Before running release.sh, verify prerequisites are ready:
# Docker must be running (needed for Cloud Run backend deploy)
if ! docker info &>/dev/null; then
open -a Docker
echo "Waiting for Docker to start..."
for i in {1..30}; do docker info &>/dev/null && break; sleep 2; done
fi
./release.sh [version]
If no version specified, it auto-increments the patch version.
MANDATORY — Run verification immediately after release completes:
./verify-release.sh [version]
This script automatically:
If verification fails, immediately roll back using the rollback skill (.claude/skills/rollback/SKILL.md).
After the build completes and is registered on staging, run /test-release on the remote MacStadium machine only (staging channel). See .claude/skills/test-release/SKILL.md.
Do NOT promote to beta. Report staging test results and wait for the user to say "promote to beta".
After the user explicitly approves, run ./scripts/promote_release.sh <tag> to promote staging → beta. Then run /test-release on the local machine (beta channel).
Do NOT promote to stable. Report beta test results and wait for the user to say "promote to stable".
Each promotion (staging → beta → stable) is a separate decision that requires explicit user approval.
This is common - Apple's CDN can be slow. DO NOT manually retry staple.
./release.sh [same-version] from the beginninggh auth login or gcloud auth loginopen -a Dockerdocker infoThe release requires these in .env:
NOTARIZE_PASSWORD - Apple app-specific passwordSPARKLE_PRIVATE_KEY - EdDSA key for signing updatesRELEASE_SECRET - Backend API secretAPPLE_PRIVATE_KEY - For Apple Sign-In configIf verification fails or a broken release is discovered post-release, use the rollback skill (.claude/skills/rollback/SKILL.md). The key steps are:
is_live=False in Firestore desktop_releases collection (stops appcast from serving broken version)./release.sh [same-version]Why speed matters: Users who auto-updated to a broken build are stuck — the app can't launch, so Sparkle can't check for fixes. They must manually re-download the DMG.
/Users/matthewdi/omi-desktop/release.sh/Users/matthewdi/omi-desktop/verify-release.sh - Post-release download + launch test/Users/matthewdi/omi-desktop/.claude/skills/rollback/SKILL.md/Users/matthewdi/omi-desktop/CHANGELOG.json - Version history with all release notes/Users/matthewdi/omi-desktop/Desktop/Omi-Release.entitlements - Must NOT have provisioning-profile-dependent keysdevelopment
# test-release: Smoke Test a Fazm Release Smoke test a Fazm release. Use when the user says "test the release", "smoke test", or "verify the build works". **This skill does NOT build anything.** It tests the shipped product via Sparkle auto-update. ## Channel → Machine Mapping Both the local production app (`/Applications/Fazm.app`) and the MacStadium remote are on the `staging` channel. Staging releases get tested on **both** machines; the primary test is the **local** machine (more reliabl
development
# FAZM Inbox Agent Read ~/fazm/inbox/skill/AGENT-VOICE.md first — it has your persona, tone rules, examples, and investigation workflow. **Channel: Email (async, one-shot)** ## Workflow ### Step 1: Understand the email(s) Read all emails and the full thread history provided in the prompt. You may receive multiple unprocessed emails from the same user (e.g., they sent a bug report, then a follow-up, then a correction). Treat them as one batch: read all of them, then categorize the combined i
devops
Local text-to-speech via sherpa-onnx (offline, no cloud)
devops
Feishu cloud storage file management. Activate when user mentions cloud space, folders, drive.