Skip to content
Back to skills

New Cask

ASecurity

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.

  • 462 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added February 7, 2026
developmentrubybashtestinggitapidocumentation

Works with

  • cli
  • api

Security analysis

A100/100

Pro scans all 3 files and shows the line behind each finding

Scanned February 12, 2026

npx -y skills add malob/nix-config --skill new-cask --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of New Cask?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for New Cask
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/malob-new-cask/badge)](https://www.skillsdirectory.com/skills/malob-new-cask)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: new-cask
argument-hint: "<download-url>"
context: fork
description: >-
  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.
---

# 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

1. **Pre-flight checks** - Duplicate detection, rejection history, acceptability
2. **Information gathering** - URLs, versions, checksums, auto-updates, zap paths
3. **Cask creation** - Write the .rb file with proper stanzas
4. **Testing** - Audit, style, livecheck, install/uninstall
5. **PR submission** - Branch, commit, push, create PR with AI disclosure

## Pre-flight Checks

Before investing time:

1. **Check for duplicates**: Search existing casks and open PRs

   ```bash
   brew search <name>
   gh pr list -R Homebrew/homebrew-cask --search "<name>"
   ```

2. **Check rejection history**: Some apps are explicitly rejected

   ```bash
   gh issue list -R Homebrew/homebrew-cask --search "<name> is:closed"
   ```

3. **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:

1. Check what the existing cask is: `brew info --cask <name>`
2. 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>`
3. Example: `codex` (CLI) vs `codex-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`, or `universal`
- Intel (x64/x86_64): URLs often contain `x64`, `x86_64`, `intel`

**Common URL patterns:**

- `/latest` redirects (use `strategy :header_match` for livecheck)
- RELEASES.json feeds (use `strategy :json` for livecheck)
- GitHub releases (use `strategy :github_latest` for livecheck)

### 2. Discover Version Numbers

Try these approaches:

1. Check URL structure - version often in filename
2. Follow `/latest` URLs and inspect redirect:
   ```bash
   curl -sIL "<url>/latest" | grep -i location
   ```
3. Look for RELEASES.json, releases.json, or similar feeds
4. 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:

```bash
# 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):

```bash
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):

```bash
# 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:

```bash
grep -r "~/\.<appname>" "$(brew --repository homebrew/cask)/Casks/"
```

If shared, add a comment and exclude from zap:

```ruby
zap trash: [
  # "~/.appname", # Shared with appname CLI cask
  "~/Library/Application Support/AppName",
  ...
]
```

## Cask Structure

### Basic Template

```ruby
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):

```ruby
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):

```ruby
livecheck do
  url "https://example.com/appcast.xml"
  strategy :sparkle, &:short_version
end
```

### Architecture-Specific Versions

When ARM and Intel have different versions:

```ruby
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:`:

```ruby
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)

```bash
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:

```bash
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):

```bash
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

```bash
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):

```bash
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 changes
- `brew audit --cask --new <cask-name>` - Required for new casks
- `brew style --fix <cask-name>` - Must report no offenses
- `HOMEBREW_NO_INSTALL_FROM_API=1 brew install --cask <cask-name>` - Must succeed
- `brew uninstall --cask <cask-name>` - Must succeed

### AI Disclosure

The PR template requires AI disclosure. Use this format:

```markdown
## 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 `/latest` URLs, use `:header_match`
- For JSON feeds, use `:json` with 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*` not `sfl2`)
- "Download does not require additional version components" → use `&:short_version` in Sparkle livecheck

### PR review feedback

Common reviewer requests:

- More specific livecheck strategy
- Additional zap paths
- Better description wording
- Architecture handling improvements

Files in this skill

  • SKILL.md10.8 KB
  • references/livecheck-strategies.md7.7 KB
  • scripts/test-cask551 B

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.