homebrew-cask-authoring について
Homebrew Caskへの貢献を支援するスキルです。スタイル検査では判断できない適格性、Caskの構成、検証、クリーンアップ、プルリクエストの手順を扱います。
主な機能
- 01Caskの適格性とトークン命名
- 02インストールとクリーンアップ設定
- 03アーキテクチャとOS別Cask
- 04監査、インストール、zapの検証
- 05プルリクエストとAI開示の手順
活用シーン
- 01新しいCaskの対象になるかの評価
- 02macOSとLinux向け成果物のCask作成
- 03レビュー前のアンインストールとzapの確認
- 04Homebrew Caskのプルリクエスト準備
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ connorads/ dotfiles --skill homebrew-cask-authoringインストール後、Claude Code で/homebrew-cask-authoringを入力して読み込まれたか確認します。
同梱ファイルreferences/homebrew-cask-contribution-workflow.md
詳細
Homebrew Cask の作成
質問せずに、Homebrew Cask のメンテナーがこれをマージするでしょうか?
Homebrew の cops と監査機能は、レイアウト、順序、構文の大部分をチェックします。このスキルでは、それらでカバーできない適格性、命名、クリーンアップのパス、テスト、PR の進め方を扱います。ここに記載されたルールと brew style/brew audit の結果が食い違う場合は、ツールの判定に従ってください。ツールは Homebrew の最新リリースを反映していますが、このファイルは反映していません。
運用ルール
- PR を作成する前に homebrew-cask 自身のエージェントポリシーを取得し、それに従ってください:
gh api repos/Homebrew/homebrew-cask/contents/AGENTS.md -H 'Accept: application/vnd.github.raw'。 公式ドキュメント:Cask Cookbook、 Acceptable Casks。 - Cask は最小限にしてください。正しくインストール、アンインストール、クリーンアップするために必要なスタンザのみを記述してください。
url ..., verified:は決して記述しないでください。これは非推奨で、無視されます。編集する Cask に含まれている場合は削除してください。- 1 つの OS のみをサポートする Cask には、トップレベルに
depends_on :macos(またはバージョンを指定したdepends_on macos: :<sym>)かdepends_on :linuxが必要です。アーティファクトの種類だけでは OS は決まりません。 - クロスプラットフォームの Cask には、トップレベルの OS 依存関係を指定しないでください。OS 固有のアーティファクトは
on_macos(app、pkg、suiteなど)またはon_linux(app_image)の内部で条件を指定してください。binaryは移植可能です。depends_on macos:はon_macosの内部に記述してください。トップレベルに記述すると、Linux が対象から外れます。 rm、tap、システムへの変更を実行する前に、その内容を明示してください。ユーザーから上書き状態を維持するよう求められない限り、テスト後に Homebrew を標準状態に戻してください。
事前確認(新規 Cask)
- 注目度(ポリシー): GitHub プロジェクトのフォーク数/ウォッチャー数が 30 未満、またはスター数が 75 未満の場合、却下される可能性が高くなります。PR の作成者が上流リポジトリを所有している場合は、その 3 倍(90/90/225)が基準です。Linux 専用および AppImage の Cask に例外はありません。
- 経過期間:リポジトリとホームページのドメインの両方が 30 日以上経過していないと、Cask の品質に関係なく
brew audit --newが失敗します。 - Gatekeeper:macOS のアーティファクトには署名と公証が必要です(
spctl -a -vv <App>.app)。署名されていないアプリは対象外です。回避策として--no-quarantineの使用や Gatekeeper の無効化を決して提案しないでください。 - Rosetta:macOS 27 が最新の安定版 macOS になると、新規の
requires_rosetta/x86_64 専用 macOS Cask は対象外になります。作成に取りかかる前に確認してください。Linux 専用 Cask は対象外です。 - 適切なリポジトリ:コンパイル済みアプリを含まないオープンソースの CLI は homebrew/core に追加するものです。homebrew/core で却下されても、Cask の対象になるわけではありません。
- 過去の事例:トークンを使ってマージされなかったクローズ済み PRとオープン中の PRを検索してください。修正できない理由で却下されたものを再提出しないでください。
- Linux ビルド:上流プロジェクトが AppImage を配布しているか確認してください。新規 Cask ではレビュー担当者から求められるため、存在する場合は含めてください。
- プレリリース:上流プロジェクトが GitHub のすべてのリリースをプレリリースとしてマークしている場合、オンライン監査は
<tag> is a GitHub pre-releaseというエラーで失敗します。同じコミットでaudit_exceptions/github_prerelease_allowlist.jsonに"<token>": "all"を追加してください(前例:agent-tars、duplicati)。後からプレリリースではないリリースが出た場合も、"all"はエラーになります。並べ替えは厳密ではないため、近くの項目の隣に追加してください。ファイル全体を並べ替えると、無関係な差分が生じます。PR 本文で理由を説明してください。
ワークフロー
1) トークン
まず brew generate-cask-token "<App Name>.app" を実行し、その後、このコマンドでは適用されない判断ルールを適用します。
- アプリが移植版ではなく、「Mac」が名前の一部として不可分な場合(
playonmac)を除き、「Mac」を削除します。 - デフォルトでは「Desktop」を削除します。あるメンテナーはデスクトップアプリに
executorを採用し、その後 Homebrew/core の CLI がexecutor-cliを採用しました。先に Homebrew に登録されたコンポーネントが、修飾語のない名前を使用します。 - ブランド名である場合(
docker-desktop、`ltx-desktop)、または同じ名前の兄弟コンポーネントが Homebrew 内に すでに存在する場合に限り、「Desktop」を残します。上流(npm、crates.io)にしか存在しない CLI は理由になりません。 cask token mentions desktopの監査は厳格モード専用です(--newのときに実行されます)。どちらを選ぶ場合でも、PR の本文で選択理由を説明してください。- バリアント:
@beta、@nightly、@latest、@<major>。
ファイルを作成する前に、トークンをユーザーに確認してください。
2) 下書き
brew create --cask <url> --set-name <token> でひな形を作成し、次の内容まで削ります。
cask "token" do
version "1.2.3"
sha256 "..."
url "https://example.com/app-#{version}.dmg"
name "Official App Name"
desc "Short one-line description"
homepage "https://example.com/"
depends_on :macos
app "AppName.app"
end
desc:事実に基づき、宣伝文句を避け、プラットフォーム名(「for macOS」など)を含めず、80 文字未満にします。- アプリがより新しい最低対応バージョンを必要とする場合は、
depends_on :macosをdepends_on macos: :<sym>に置き換えます。brew audit --cask --online --fix <token>は、on_*ブロックのない Cask に限り、バンドルから必要なバージョンを判定します。シンボルの一覧はリファレンスを参照してください。
3) アーキテクチャ
ベンダーの宣伝ではなく、バイナリを確認します。
lipo -archs "/Volumes/<Vol>/<AppName>.app/Contents/MacOS/<AppName>"
arm64のみ:depends_on arch: :arm64を追加します。追加しないと、Intel ユーザーが実行できないアプリをインストールすることになります。- Universal:アーキテクチャの制限は不要です。
- CPU ごとのダウンロードでバージョンが同じ場合:
arch arm: ..., intel: ...とsha256 arm: ..., intel: ...を指定します。 - CPU ごとにバージョンが異なる場合:
on_arm/on_intelブロックを使用します。
4) アンインストールと削除
pkgとinstaller(pkgutil:、launchctl:など)にはuninstallが必要です。uninstall quit:はアンインストール、アップグレード、再インストール時に実行されます。Homebrew はアップグレード後にアプリを再び開きます。アップグレード時は、on_upgrade: :signalを指定しない限り、signal:はスキップされます。- モーダルウィンドウ(初回起動時のアクセス許可パネルなど)が実行ループをブロックすると、アプリが
quit:を無視する場合があります。CI の zap-check は新しい runner でアプリを起動するため、アクセス許可を与えたローカル環境では発生しない問題に遭遇し、CI は「Some launch jobs were not unloaded」で失敗します。macOS 26 ではsignal:も役に立ちません。Homebrew は launchd ラベルでプロセスを検索しますが、ラベルが UUID で終わるようになり(application.<id>.<n>.<n>.<UUID>)、Homebrew のパターンに一致しなくなったためです。quit:の隣にlaunchctl: "application.<bundle-id>.*"を指定してください(前例:shutter-encoder、cmux)。ジョブを削除するとプロセスも終了します。 launchctl:は各ジョブをsudoで再確認するため、ユーザーレベルのジョブであっても、ローカルでアンインストールするとパスワードの入力を求められます。sudo なしでの処理ですでにジョブは削除されているため、プロンプトをキャンセルしても問題ありません。CI の sudo はパスワードなしで実行できます。- ヘルパープロセス(
Contents/Helpers/、またはアプリの実行中にpgrep -lf <AppName>で確認できるもの)があるアプリでは、quit:にすべてのバンドル ID が必要です。ID がドットで区切られた部分を 3 つ以上含む場合は、ワイルドカードを使用できます("com.vendor.*")。 zapは監査では省略可能ですが、新しい cask ではレビュー担当者が指定を期待します。- アプリをインストールして起動し、実際に使用します(ログインして、実際の作業を行います)。一部のパス(
~/Library/HTTPStorages/<id>、セッションキャッシュなど)は、使用後に初めて作成されます。 brew generate-zap <token>を実行します(cask の作成前なら--name "<App Name>"を指定します)。Full Disk Access を求めるエラーが出た場合は、ターミナルにアクセスを許可して再実行します。出力を確認してください。不要な項目も含まれます。generate-zapが対象とするのは~/Libraryと~/.<app>のドットフォルダーで、XDG パスは対象外です。--zapの実行後に再インストールしても状態が残る場合は、上流ソースでos.homedir()、env-paths、xdgを検索してください。 また、アプリ名のみを照合するため、状態が CLI 名やトークン名(~/Library/Caches/<cli>など)で保存されている場合、「No zap stanza required」と報告します。~/Library内でトークンとバンドル ID も検索し、上流ソースでパス結合の処理を検索してください。一部のディレクトリは、機能を使用して初めて作成されます。- PR を作成した後、CI の zap-check ジョブの概要を読み、不足していると判断されたパスを確認します。
- アプリをインストールして起動し、実際に使用します(ログインして、実際の作業を行います)。一部のパス(
- Keystone/GoogleUpdater 型の共有コンポーネントは
zapのみに指定し、uninstallには指定しないでください。
5) ライブチェック
- デフォルトのチェックでバージョンを検出できる場合は、
livecheckを省略します。プレリリース、アセットのないリリース、誤った取得元など、明確な必要性がある場合にのみブロックを追加します。 - Sparkle アプリの場合は、
brew find-appcast <path>.appでフィードを確認します。 :github_latest/:github_releasesは明示的に指定する場合のみ使用します。Git タグや上流フィードが使えない場合に使用してください。これらはアセット名ではなくtag_nameに一致します。strategy :extract_plistとversion :latestは自動的に autobump の対象外となるため、no_autobump!は不要です。
6) クロスプラットフォーム(macOS + Linux AppImage)
- OS ごとの文字列は、トップレベルの
arch(intel: on_system_conditional(macos: "x64", linux: "x86_64"))、os、またはローカルのon_system_conditionalに指定します。いずれもversionより前に記述します。 - トップレベルの
sha256はarm:、intel:、arm64_linux:、x86_64_linux:をキーにします(存在するキーのみ)。sha256をon_macos/on_linuxの中にネストしないでください。 on_macos/on_linuxブロックはsha256の後、urlの前に記述します。app_image "<file>", target: "<App>.AppImage"の target にバージョンを含めないでください。
4 アーキテクチャ対応、Linux のみの単一アーキテクチャ対応、ユニバーサル macOS 対応の各テンプレート、depends_on macos: のシンボルテーブル、app_image の動作については、
references/homebrew-cask-contribution-workflow.md を参照してください。
7) 検証
ローカルの homebrew/cask チェックアウトから実行します(セットアップについては参考資料を参照してください)。
brew style --fix <token>
brew audit --cask --online --os=all --arch=all <token>
brew audit --cask --new <token> # new casks; implies --strict --online
brew lgtm --online # final gate; stage the cask first
HOMEBREW_NO_INSTALL_FROM_API=1 brew install --cask <token>
brew uninstall --cask <token>
- 成功時、
brew auditは何も出力しません。 brew lgtmはorigin/mainではなく、ローカルのmainブランチとの差分を確認します。古いチェックアウトでは、それ以降に upstream で変更されたすべての cask を監査します(アーティファクトをダウンロードします)。最初にgit fetch origin && git rebase origin/mainを実行してから、git branch -f main origin/mainを実行してください。git diff --name-only mainには、自分のファイルだけが表示されるはずです。--onlineのみを指定した場合、ホストの OS とアーキテクチャだけを監査します。Mac からon_linuxも確認するには、--os=all --arch=allを指定します。- インストールとアンインストールには、ファイルパスではなくトークンを使用してください。
- TTY(tmux、エージェントの PTY)では、依存関係がインストールされる際に
brew installが確認を求めます。-yを指定してください。
アプリを起動した状態で zap を検証します。
HOMEBREW_NO_INSTALL_FROM_API=1 brew install --cask <token>
open "/Applications/<AppName>.app" # log in, use it
brew uninstall --zap --cask <token>
pgrep -lf <AppName> # empty, or add bundle IDs to uninstall quit:
通常の uninstall の後に再インストールするとログイン状態が維持され、--zap の後は維持されないはずです。これにより、zap が実際のユーザー状態を対象としていることを確認できます。
uninstall --zap は、作業コピーではなく、インストール時に記録されたスタンザ(Caskroom/<token>/.metadata/)を使用します。zap を編集した後は、アンインストール、インストール、uninstall --zap の順に実行してください。
8) PR
- 既存の cask のバージョンを更新する場合:
brew bump --open-pr <token>(またはbrew bump-cask-pr <token> --version <new>)を使用します。手動の手順は、新しい cask とスタンザの変更に使用します。 - PR ごとに cask は 1 つとし、差分は最小限に抑え、ついでのフォーマット変更はしないでください。ベースブランチは
mainです。 - コミットの件名(50 文字以内):
token 1.2.3 (new cask)、token 1.2.3、またはtoken: description。 - PR の作成時は、cask ごとにコミットを 1 つにします。作成後は、レビューや CI の修正を新しいコミットとしてプッシュしてください(homebrew-cask
AGENTS.md)。メンテナーから求められた場合にのみスカッシュしてください。CONTRIBUTING.md とドキュメントにはスカッシュについての説明があるため、依頼される可能性があります。 - PR の本文ではテンプレートをそのまま使用してください。チェックリストの上に、URL だけでなく、「Adds a cask for App, a ...」のような説明文を 1 文追加します。実施した項目だけにチェックを入れてください。冗長なログや AI による分析は含めないでください。
9) AI の使用に関する開示
Responsible AI Usage とテンプレートに従ってください。
- 出力(
zapのパスを含む)を確認した後に限り、人間が AI のチェックボックスにチェックを入れます。 - その下に、使用したツール/モデル、使用方法、人間が手動で検証した内容(インストール、ログイン、使用、zap の導出、アプリ実行中のアンインストール)を簡潔に記載します。補助ツールに 2 つ目の
quit:ID が必要だったなど、テストで判明した一見わかりにくい事項も記載してください。 - コミットに
Co-Authored-By、Assisted-byなどの AI に関するトレーラーを付けないでください。 - メンテナーからの質問やレビューコメントには、人間が AI を使わずに回答します。エージェントは回答案を作成したり投稿したりしません。
- メンテナーではない人が同時にオープンできる AI 支援 PR は 1 件までです。