Agent skill
new-cask
This skill should be used when the user asks to "add a cask to homebrew", "create a homebrew cask", "add an app to homebrew", "new cask for", "homebrew cask for", "package an app for homebrew", "submit to homebrew-cask", "make a cask", "contribute a cask", or wants to package a macOS application for Homebrew.
Install this agent skill to your Project
npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/data/new-cask
SKILL.md
Creating a New Homebrew Cask
Reference Documentation
Official docs (read as needed):
$(brew --repository)/docs/Adding-Software-to-Homebrew.md- Contribution overview$(brew --repository)/docs/Cask-Cookbook.md- Stanza reference$(brew --repository)/docs/Brew-Livecheck.md- Livecheck strategies$(brew --repository)/docs/Acceptable-Casks.md- Acceptance criteria
Workflow Overview
- Pre-flight checks - Duplicate detection, rejection history, acceptability
- Information gathering - URLs, versions, checksums, auto-updates, zap paths
- Cask creation - Write the .rb file with proper stanzas
- Testing - Audit, style, livecheck, install/uninstall
- PR submission - Branch, commit, push, create PR with AI disclosure
Pre-flight Checks
Before investing time:
-
Check for duplicates: Search existing casks and open PRs
bashbrew search <name> gh pr list -R Homebrew/homebrew-cask --search "<name>" -
Check rejection history: Some apps are explicitly rejected
bashgh issue list -R Homebrew/homebrew-cask --search "<name> is:closed" -
Verify acceptability: Review
$(brew --repository)/docs/Acceptable-Casks.md- No trial-only software
- No malware or potentially unwanted programs
- Must have stable releases
Token Collisions
When an app name conflicts with an existing cask:
- Check what the existing cask is:
brew info --cask <name> - If different products (e.g., CLI tool vs GUI app from same vendor), suffix appropriately:
- GUI app when CLI exists:
<name>-app - Different vendor's product:
<vendor>-<name>
- GUI app when CLI exists:
- Example:
codex(CLI) vscodex-app(GUI desktop app)
URL Types
The skill accepts various URL types:
- Direct download URL (preferred):
https://example.com/App.dmg - Product/download page: Will scrape for download links
- GitHub repo: Will check releases for download assets
- No URL: Will ask for app name and search for download source
If the URL isn't a direct download, first identify the actual installer URL before proceeding with checksum calculation.
Information Gathering
1. Find Download URLs
Look for direct download links on the vendor's website. Check for architecture-specific URLs:
- Apple Silicon (arm64): URLs often contain
arm64,aarch64,apple, oruniversal - Intel (x64/x86_64): URLs often contain
x64,x86_64,intel
Common URL patterns:
/latestredirects (usestrategy :header_matchfor livecheck)- RELEASES.json feeds (use
strategy :jsonfor livecheck) - GitHub releases (use
strategy :github_latestfor livecheck)
2. Discover Version Numbers
Try these approaches:
- Check URL structure - version often in filename
- Follow
/latestURLs and inspect redirect:bashcurl -sIL "<url>/latest" | grep -i location - Look for RELEASES.json, releases.json, or similar feeds
- Check app's "About" or website changelog
Important: When versions differ by architecture, use on_arm/on_intel blocks.
3. Calculate Checksums
Download and checksum each architecture:
# ARM64
curl -Lo /tmp/app-arm.dmg "<arm64-url>"
shasum -a 256 /tmp/app-arm.dmg
# Intel
curl -Lo /tmp/app-intel.dmg "<intel-url>"
shasum -a 256 /tmp/app-intel.dmg
Unversioned URLs: When the download URL doesn't contain version info (always points to latest), use sha256 :no_check instead of a checksum.
4. Detect Auto-updates
Check if the app self-updates (affects auto_updates stanza):
- Look for "Check for Updates" in app menus
- Check for Sparkle framework:
ls "/Applications/<App>.app/Contents/Frameworks" | grep -i sparkle - Look for ShipIt (Electron apps): bundle ID contains
.ShipIt - Check Info.plist for
SUFeedURL(Sparkle appcast)
If auto-updates exist, add auto_updates true to the cask.
5. Discover Zap Paths
Use the brew createzap helper (requires tapping first):
brew tap nrlquaker/createzap
brew createzap "<app-name>"
brew createzap "com.example.bundle-id" # Try bundle ID if app name fails
Important: Ask the user to launch the app and use it briefly before running createzap a second time. This ensures runtime files (caches, preferences, logs) are created and captured.
Manual discovery (if createzap fails):
# Search common paths
sudo find ~/Library -iname "*<app-name>*" 2>/dev/null
sudo find ~/Library -iname "*<bundle-id>*" 2>/dev/null
Common locations:
~/Library/Application Support/<app-or-vendor>/~/Library/Caches/<bundle-id>/~/Library/Preferences/<bundle-id>.plist~/Library/Saved Application State/<bundle-id>.savedState/~/Library/Logs/<app-name>/~/Library/HTTPStorages/<bundle-id>/
Shared Configuration Directories
Some apps share config directories with related tools (e.g., GUI app + CLI tool). Check if paths like ~/.appname are used by other casks:
grep -r "~/\.<appname>" "$(brew --repository homebrew/cask)/Casks/"
If shared, add a comment and exclude from zap:
zap trash: [
# "~/.appname", # Shared with appname CLI cask
"~/Library/Application Support/AppName",
...
]
Cask Structure
Basic Template
cask "<token>" do
version "<version>"
sha256 "<checksum>"
url "<download-url>"
name "<Full App Name>"
desc "<One-line description>"
homepage "<homepage-url>"
livecheck do
url "<livecheck-url>"
strategy :<strategy>
end
auto_updates true # if applicable
depends_on macos: ">= :<minimum-version>" # if applicable
app "<App Name>.app"
zap trash: [
# paths here
]
end
Unversioned Download URLs
When the download URL doesn't contain version info (always points to latest):
version "1.2.3"
sha256 :no_check # URL doesn't include version
url "https://example.com/download/App.dmg",
verified: "example.com/download/"
For Sparkle livecheck with unversioned URLs, use &:short_version to return only the display version (not build number):
livecheck do
url "https://example.com/appcast.xml"
strategy :sparkle, &:short_version
end
Architecture-Specific Versions
When ARM and Intel have different versions:
cask "<token>" do
arch arm: "arm64", intel: "x64"
on_arm do
version "<arm-version>"
sha256 "<arm-checksum>"
end
on_intel do
version "<intel-version>"
sha256 "<intel-checksum>"
end
url "https://example.com/app/#{arch}/App-v#{version}.dmg"
# ... rest of cask
end
URL Verification
When download domain differs from homepage, add verified::
url "https://cdn.example.com/downloads/app.dmg",
verified: "cdn.example.com/downloads/"
Livecheck Configuration
Choose the appropriate strategy based on how versions are published. See references/livecheck-strategies.md in this skill's directory for detailed patterns.
Quick reference:
| Source Type | Strategy |
|---|---|
/latest redirect URL |
:header_match |
| JSON feed (RELEASES.json) | :json |
| GitHub releases | :github_latest |
| Sparkle appcast | :sparkle |
| HTML page with links | :page_match |
Testing Checklist
1. Manual Testing (install/uninstall)
export HOMEBREW_NO_AUTO_UPDATE=1 HOMEBREW_NO_INSTALL_FROM_API=1
# Test installation - verify app works
brew install --cask <cask-name>
# Test uninstallation
brew uninstall --cask <cask-name>
unset HOMEBREW_NO_AUTO_UPDATE HOMEBREW_NO_INSTALL_FROM_API
2. Automated Checks (audit, style, livecheck)
Use the scripts/test-cask helper in this skill's directory, or run manually:
export HOMEBREW_NO_AUTO_UPDATE=1 HOMEBREW_NO_INSTALL_FROM_API=1
brew audit --cask --new <cask-name>
brew style --fix <cask-name>
brew livecheck --cask <cask-name>
unset HOMEBREW_NO_AUTO_UPDATE HOMEBREW_NO_INSTALL_FROM_API
PR Submission
Git Setup
Before pushing, verify remotes to ensure pushing to your fork (not the main Homebrew repo):
cd "$(brew --repository homebrew/cask)"
git remote -v
The main Homebrew repo is typically origin. Identify your fork's remote name (e.g., your GitHub username).
Prepare the Branch
cd "$(brew --repository homebrew/cask)"
git checkout main
git pull origin main
git checkout -b <cask-name>
git add Casks/<first-letter>/<cask-name>.rb
git commit -m "<cask-name> <version> (new cask)"
Push and Create PR
Push to your fork (not origin):
git push -u <your-fork-remote> <cask-name>
Before creating the PR, read the template at $(brew --repository homebrew/cask)/.github/PULL_REQUEST_TEMPLATE.md. Use the template verbatim as the PR body, checking boxes for completed items.
PR Checklist Verification
Before checking boxes in the PR template, ensure these were actually run:
brew audit --cask --online <cask-name>- Required for all cask changesbrew audit --cask --new <cask-name>- Required for new casksbrew style --fix <cask-name>- Must report no offensesHOMEBREW_NO_INSTALL_FROM_API=1 brew install --cask <cask-name>- Must succeedbrew uninstall --cask <cask-name>- Must succeed
AI Disclosure
The PR template requires AI disclosure. Use this format:
## AI Disclosure
I have a skill that automates my standard cask creation workflow: gathering app info
(version, bundle ID, min macOS), checking for auto-update frameworks, finding zap paths,
writing the cask file, and running all the standard tests (audit, style, livecheck,
install/uninstall). I supervised the process throughout.
Common Issues and Solutions
Different versions per architecture
Use on_arm/on_intel blocks with arch-specific version and sha256.
Livecheck not finding versions
- Debug with
brew livecheck --debug --cask <cask-name> - Try different strategies or URLs
- For
/latestURLs, use:header_match - For JSON feeds, use
:jsonwith appropriate block - For unversioned URLs with Sparkle, use
&:short_version
Audit failures
- Read error messages carefully - they're usually specific
verified:needed when URL domain != homepage domain- Use glob
*instead of specific versions in zap paths (e.g.,sfl*notsfl2) - "Download does not require additional version components" → use
&:short_versionin Sparkle livecheck
PR review feedback
Common reviewer requests:
- More specific livecheck strategy
- Additional zap paths
- Better description wording
- Architecture handling improvements
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
agent-ops-spec
Manage specification documents in .agent/specs/. Use when user provides requirements, acceptance criteria, or feature descriptions that need to be tracked and validated against implementation.
agent-ops-state
Maintain .agent state files. Use at session start, after meaningful steps, and before concluding: read/update constitution/memory/focus/issues/baseline consistently.
agent-ops-spec
Manage specification documents in .agent/specs/. Use when user provides requirements, acceptance criteria, or feature descriptions that need to be tracked and validated against implementation.
agent-ops-testing
Test strategy, execution, and coverage analysis. Use when designing tests, running test suites, or analyzing test results beyond baseline checks.
agent-ops-testing
Test strategy, execution, and coverage analysis. Use when designing tests, running test suites, or analyzing test results beyond baseline checks.
agent-ops-state
Maintain .agent state files. Use at session start, after meaningful steps, and before concluding: read/update constitution/memory/focus/issues/baseline consistently.
Didn't find tool you were looking for?