Forest is now distributed via Homebrew using the bwl/ettio tap.
brew tap bwl/ettio
brew install --cask forestThis installs:
- Forest Desktop.app →
~/Applications/Forest Desktop.app - forest CLI → symlinked to
/opt/homebrew/bin/forest
- Contains Forest source code
- GitHub Releases host DMG files
- Current release: v0.4.0
- Repository: https://github.com/bwl/homebrew-ettio
- Contains
Casks/forest.rbcask definition - Automatically tested via GitHub Actions
File: Casks/forest.rb
Key features:
- Downloads DMG from GitHub Releases
- Installs app to
~/Applications - Creates binary symlink automatically
- Removes quarantine attribute (postflight script for unsigned apps)
- Includes zap stanza for clean uninstall
cask "forest" do
version "0.4.0"
sha256 "38dbfe9cc6f21d63b33705e50b9607725c874865eb47b825ba21170e8f6d840c"
url "https://github.com/bwl/forest/releases/download/v#{version}/Forest.Desktop_0.1.0_aarch64.dmg"
app "Forest Desktop.app"
binary "#{appdir}/Forest Desktop.app/Contents/MacOS/forest"
postflight do
system_command "/usr/bin/xattr",
args: ["-rd", "com.apple.quarantine", "#{appdir}/Forest Desktop.app"],
sudo: false
end
end# Update the VERSION file (single source of truth)
echo "0.X.Y" > VERSION
git add VERSION
git commit -m "chore: Bump version to 0.X.Y"
git push origin thinNtauriThe VERSION file automatically syncs to both:
package.json(CLI version)forest-desktop/src-tauri/tauri.conf.json(desktop app version)
cd forest-desktop
bun run tauri buildThe build script (scripts/build-cli.sh) reads VERSION and updates both package.json and tauri.conf.json automatically.
Creates:
src-tauri/target/release/bundle/macos/Forest Desktop.appsrc-tauri/target/release/bundle/dmg/Forest Desktop_0.X.Y_aarch64.dmg
# Tag the version
git tag v0.X.Y
git push origin v0.X.Y
# Create release with DMG
gh release create v0.X.Y \
--title "Forest v0.X.Y" \
--notes "Release notes here" \
"forest-desktop/src-tauri/target/release/bundle/dmg/Forest Desktop_0.X.Y_aarch64.dmg#Forest.Desktop_0.X.Y_aarch64.dmg"# Calculate SHA256
shasum -a 256 forest-desktop/src-tauri/target/release/bundle/dmg/Forest\ Desktop_0.X.Y_aarch64.dmg
# Update Casks/forest.rb
cd /opt/homebrew/Library/Taps/bwl/homebrew-ettio
# Edit version and sha256 in Casks/forest.rb
git add Casks/forest.rb
git commit -m "Update forest to v0.X.Y"
git push origin mainbrew uninstall --cask forest
brew install --cask bwl/ettio/forest
open "/Users/bwl/Applications/Forest Desktop.app"
forest --versionThe bundled CLI is automatically symlinked by Homebrew:
/opt/homebrew/bin/forest → ~/Applications/Forest Desktop.app/Contents/MacOS/forest
Since /opt/homebrew/bin is in PATH, the forest command works immediately after installation.
Users can also use the GUI installer:
- Press
⌘Kto open command palette - Type
/cli-install - Choose shell and click "Auto Install"
This adds the app bundle's MacOS directory directly to PATH (alternative to Homebrew symlink).
Currently using postflight script to remove quarantine attribute for unsigned apps.
For production distribution with proper code signing:
- Get Apple Developer ID ($99/year)
- Update
tauri.conf.json:
{
"bundle": {
"macOS": {
"signingIdentity": "Developer ID Application: Your Name (TEAM_ID)"
}
}
}- Remove postflight script from cask
Fixed by postflight script. If you still see this:
sudo xattr -rd com.apple.quarantine "/Users/bwl/Applications/Forest Desktop.app"Ensure Homebrew's bin directory is in PATH:
echo 'export PATH="/opt/homebrew/bin:$PATH"' >> ~/.zshrc
source ~/.zshrcMake sure tap is added:
brew tap bwl/ettio# Install
brew tap bwl/ettio
brew install --cask forest
# Update
brew upgrade forest
# Uninstall (keeps preferences)
brew uninstall --cask forest
# Completely remove (including preferences)
brew uninstall --zap --cask forest
# Check info
brew info forest
# List installed casks
brew list --cask- Homebrew Tap: https://github.com/bwl/homebrew-ettio
- Forest Repo: https://github.com/bwl/forest
- Latest Release: https://github.com/bwl/forest/releases/latest
- Cask File: https://github.com/bwl/homebrew-ettio/blob/main/Casks/forest.rb