diff --git a/.agents/skills/mcpp-release/SKILL.md b/.agents/skills/mcpp-release/SKILL.md
index 60d44656..9be37e0f 100644
--- a/.agents/skills/mcpp-release/SKILL.md
+++ b/.agents/skills/mcpp-release/SKILL.md
@@ -231,6 +231,24 @@ git commit -am "ci: workspace mcpp bootstrap pin -> $NEW_VERSION (released, mirr
资产 CDN 上可能还要几分钟才更新。紧接着跑的 CI 可能仍拿到旧索引并报
`package 'mcpp@X.Y.Z' not found` —— 这不是 release 坏了,等指针稳定后重跑即可。
+### 下游分发渠道(都是自动的,只需核验)
+
+两条渠道都挂在 `release` workflow 的 `workflow_run: completed` 上,不需要人工推:
+
+| 渠道 | workflow | 核验 |
+|------|----------|------|
+| AUR (`mcpp-bin` / `mcpp-m`) | `.github/workflows/aur-publish.yml` | `gh run list --workflow aur-publish.yml --limit 1` |
+| Homebrew tap (`mcpp-m`) | `.github/workflows/homebrew-publish.yml` → ping [`mcpp-community/homebrew-mcpp`](https://github.com/mcpp-community/homebrew-mcpp) | `gh api repos/mcpp-community/homebrew-mcpp/contents/Formula/mcpp-m.rb --jq .content \| base64 -d \| grep '^ version'` |
+
+Homebrew 那条**不写公式**,只发一个 `repository_dispatch`;公式重写由 tap 仓库自己的
+`bump-formula.yml` 完成(它读 release 的 `.sha256` 边车)。这条 ping 依赖仓库 secret
+`HOMEBREW_TAP_TOKEN`;**没配也不会让发布失败** —— tap 有每日 schedule 兜底,24h 内自己跟上。
+想立刻跟上就手动触发一次:
+
+```bash
+gh workflow run bump-formula.yml -R mcpp-community/homebrew-mcpp
+```
+
### 常见失败原因
| 症状 | 原因 | 修复 |
diff --git a/.github/workflows/homebrew-publish.yml b/.github/workflows/homebrew-publish.yml
new file mode 100644
index 00000000..858e6e49
--- /dev/null
+++ b/.github/workflows/homebrew-publish.yml
@@ -0,0 +1,83 @@
+name: homebrew-publish
+
+# Tell the Homebrew tap (mcpp-community/homebrew-mcpp) that a release is out.
+#
+# The tap owns the formula rewrite — it reads the .sha256 sidecars from the
+# release and commits the new url/version itself. All this workflow does is
+# fire the starting gun, so nothing here needs to know what a formula is.
+#
+# Triggers on COMPLETION of the `release` workflow rather than on
+# `release: published`, for the same reason aur-publish.yml does: release.yml
+# creates the GitHub Release in its first job but uploads the macOS / aarch64
+# assets in later jobs, and the tap needs every sidecar to exist.
+#
+# Requires one repository secret:
+# HOMEBREW_TAP_TOKEN — fine-grained PAT scoped to mcpp-community/homebrew-mcpp
+# with "Contents: read and write" (repository_dispatch
+# is a write-level API).
+#
+# The secret is OPTIONAL. Without it this workflow logs a notice and exits 0;
+# the tap runs the same bump on a daily schedule, so a missing token costs
+# freshness (up to 24h), not correctness. That keeps a release from failing
+# over a credential the release itself doesn't need.
+
+on:
+ workflow_run:
+ workflows: [release]
+ types: [completed]
+ workflow_dispatch:
+ inputs:
+ version:
+ description: "Version to publish (default: [package].version in mcpp.toml)"
+ required: false
+
+concurrency:
+ group: homebrew-publish
+ cancel-in-progress: false
+
+jobs:
+ notify-tap:
+ runs-on: ubuntu-latest
+ # On the workflow_run trigger, only proceed if the release actually
+ # succeeded (skip failed/cancelled release runs).
+ if: >-
+ github.event_name == 'workflow_dispatch' ||
+ github.event.workflow_run.conclusion == 'success'
+ steps:
+ - name: Checkout released commit
+ uses: actions/checkout@v4
+ with:
+ # workflow_run: the exact commit the release was built from.
+ # workflow_dispatch: default ref (HEAD of the branch).
+ ref: ${{ github.event.workflow_run.head_sha || github.ref }}
+
+ - name: Resolve version
+ id: resolve
+ run: |
+ VER="${{ github.event.inputs.version }}"
+ if [ -z "$VER" ]; then
+ # mcpp.toml at the released commit carries the right version.
+ VER=$(grep -m1 -E '^\s*version\s*=' mcpp.toml | sed -E 's/.*"([^"]+)".*/\1/')
+ fi
+ [ -n "$VER" ] || { echo "cannot resolve version"; exit 1; }
+ echo "version=$VER" >> "$GITHUB_OUTPUT"
+ echo ":: version $VER"
+
+ - name: Ping the tap
+ env:
+ TAP_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }}
+ VER: ${{ steps.resolve.outputs.version }}
+ run: |
+ set -eu
+ if [ -z "${TAP_TOKEN}" ]; then
+ echo "::notice::HOMEBREW_TAP_TOKEN is not configured; skipping the ping. mcpp-community/homebrew-mcpp bumps itself on a daily schedule, so ${VER} reaches the tap within 24h."
+ exit 0
+ fi
+ curl -fsS -X POST \
+ -H "Authorization: Bearer ${TAP_TOKEN}" \
+ -H "Accept: application/vnd.github+json" \
+ -H "X-GitHub-Api-Version: 2022-11-28" \
+ https://api.github.com/repos/mcpp-community/homebrew-mcpp/dispatches \
+ -d "{\"event_type\":\"mcpp-release\",\"client_payload\":{\"version\":\"${VER}\"}}"
+ echo ":: dispatched mcpp-release ${VER} to mcpp-community/homebrew-mcpp"
+ echo "Pinged the Homebrew tap for **${VER}**." >> "$GITHUB_STEP_SUMMARY"
diff --git a/README.md b/README.md
index 316c17a0..b3351cf3 100644
--- a/README.md
+++ b/README.md
@@ -81,7 +81,23 @@ Installs into `~/.mcpp/` and adds it to your shell PATH. Deleting `~/.mcpp` unin
-Option 2 — Arch Linux (AUR)
+Option 2 — Homebrew (macOS / Linux)
+
+```bash
+brew install mcpp-community/mcpp/mcpp-m
+```
+
+One command — it taps [`mcpp-community/homebrew-mcpp`](https://github.com/mcpp-community/homebrew-mcpp)
+and installs the same prebuilt release binary. macOS needs Apple silicon +
+macOS 14; per-user data lives in `~/.mcpp/`.
+
+Homebrew's `mcpp` is an unrelated C preprocessor, hence the `mcpp-m` formula
+name — the command it installs is still `mcpp`.
+
+
+
+
+Option 3 — Arch Linux (AUR)
```bash
yay -S mcpp-bin # prebuilt release binary
@@ -95,7 +111,7 @@ On Arch the name `mcpp` is an unrelated C preprocessor, so the packages are
-Option 3 — let an AI assistant install it for you
+Option 4 — let an AI assistant install it for you
Copy the following prompt to your AI coding assistant (Claude Code / Cursor / Copilot, etc.):
diff --git a/README.zh-CN.md b/README.zh-CN.md
index 8271378f..db1601b4 100644
--- a/README.zh-CN.md
+++ b/README.zh-CN.md
@@ -81,7 +81,23 @@ curl -fsSL https://github.com/mcpp-community/mcpp/releases/latest/download/insta
-方式 2 — Arch Linux(AUR)
+方式 2 — Homebrew(macOS / Linux)
+
+```bash
+brew install mcpp-community/mcpp/mcpp-m
+```
+
+一条命令即可,会自动 tap [`mcpp-community/homebrew-mcpp`](https://github.com/mcpp-community/homebrew-mcpp)
+并安装同一份预编译 release 二进制。macOS 需要 Apple 芯片 + macOS 14;
+每个用户的数据仍在各自的 `~/.mcpp/`。
+
+Homebrew 上 `mcpp` 属于一个无关的 C 预处理器,所以公式名是 `mcpp-m`,
+装出来的命令仍然是 `mcpp`。
+
+
+
+
+方式 3 — Arch Linux(AUR)
```bash
yay -S mcpp-bin # 预编译 release 二进制
@@ -95,7 +111,7 @@ Arch 上 `mcpp` 这个名字属于一个无关的 C 预处理器,所以包名
-方式 3 — 让 AI 助手帮你安装
+方式 4 — 让 AI 助手帮你安装
将以下提示词复制给你的 AI 编码助手(Claude Code / Cursor / Copilot 等):