Docs
Homebrew Release
Aetower's Homebrew distribution is a cask that installs the same signed and notarized app bundle used by Sparkle. Homebrew is not a separate binary build. It points at the immutable release ZIP already published for the direct-download channel.
Generate the cask
Run the public-preview release pipeline:
sh scripts/release-public-preview.sh
This writes:
dist/homebrew/Casks/aetower.rb
The cask is generated from dist/Aetower.app/Contents/Info.plist and from the immutable Sparkle archive in dist/appcast/. Its sha256 is calculated from that archive, so regenerate the cask after every release build.
The public-preview pipeline also verifies the cask against the Sparkle appcast and the packaged app. Run the check directly with:
sh scripts/verify-sparkle-distribution-matrix.sh
Publish through a tap
Homebrew expects public casks to live in a tap repository. Aetower publishes to the dedicated tap repository:
https://github.com/Aeptus/homebrew-aetower
Users install it as:
brew tap aeptus/aetower
brew install --cask aetower
The release pipeline updates the tap with:
sh scripts/release-public-preview.sh --prepare-only --publish-homebrew-tap
For a full public release that makes both Sparkle/website artifacts and the tap visible, use:
sh scripts/release-public-preview.sh --prepare-only --publish-cloudflare --publish-homebrew-tap
scripts/publish-homebrew-tap.sh clones or reuses the configured tap checkout, copies the generated cask to Casks/aetower.rb, writes the tap README, runs Ruby syntax validation before commit, commits changed tap content, pushes it, then taps the published repository locally and runs Homebrew style/audit checks when brew is available.
Before the release ZIP is public, brew audit --online can fail because the URL is not reachable yet. That is expected during local preparation; it must pass before the tap is pushed for a public release.
Install smoke
After the ZIP and appcast are hosted:
brew install --cask ./Casks/aetower.rb
For the published tap:
brew tap aeptus/aetower
brew install --cask aetower
Confirm the installed app launches, Gatekeeper accepts it, and Sparkle can still detect updates from the app's configured feed.
The generated cask also links the bundled operator CLI:
binary "#{appdir}/Aetower.app/Contents/Helpers/aetower",
target: "aetower"
After brew install --cask aetower, confirm the shell path and the three operator entry points:
command -v aetower
aetower top
aetower storage
aetower repos
The read verbs require Aetower.app to be running because the CLI talks to the app-owned local MCP socket.
Relationship to Sparkle, DMG, and PKG
Sparkle remains the app's in-app update path. The cask installs the app from the same ZIP artifact that Sparkle references in appcast.xml.
The .dmg artifact is the human-facing download on aetower.dev. The .pkg artifact is for installer-style distribution and MDM/admin workflows. DMG and PKG installs can still receive future Sparkle app updates because Sparkle updates the installed .app; however, this repository's Sparkle generate_appcast tooling is ZIP-based and does not create DMG- or package-based Sparkle update items.
CLI install behavior by channel:
- PKG: postinstall best-effort links
/usr/local/bin/aetower. - Homebrew cask: the
binarystanza linksaetowerinto$(brew --prefix)/bin. - DMG / ZIP: launch Aetower, open Settings → AI Clients, and use Install Command Line Tool, or run
/Applications/Aetower.app/Contents/Helpers/aetower install.
Aetower is a free early-alpha download for macOS 14+ (Apple silicon).
Download for macOS