- Add AppDiscovery provider for running app enumeration - Implement AppDropdownView with auto-launch functionality - Create SignalAction models for 40+ yabai commands - Build ActionBuilderView with nested parameter controls - Add LiveShellPreview for real-time shell command generation - Implement ActionValidator for conflict detection - Add migration parser for existing raw action strings - Include feature flag for safe rollout - Maintain full backward compatibility
7.5 KiB
YabaiPro
A lightweight macOS menu bar app for managing Yabai window manager settings. Provides an easy-to-use interface for toggling aesthetics, focus behavior, and applying presets.
Features
- Menu Bar Integration: Clean status bar icon with popover interface
- Aesthetic Controls:
- Fade inactive windows (SIP required)
- Disable window shadows (SIP required)
- Adjustable menu bar opacity (SIP required)
- Window gap/padding slider
- Focus & Behavior:
- Focus follows mouse toggle
- Presets: Quick "Default" and "Minimalist" configurations
- Live Application: Changes apply immediately to running Yabai instance
- Config Persistence: Updates
~/.yabaircwith your settings
Requirements
- macOS 12.0+
- Yabai installed and running
- Accessibility permissions granted to the app
Installation
From Source (Swift Package)
-
Clone this repository:
git clone https://github.com/yourusername/YabaiPro.git cd YabaiPro -
Build with Swift:
swift build -c release -
Copy the executable to Applications:
cp .build/release/YabaiPro /Applications/
From Xcode
- Open
Package.swiftin Xcode - Build and run the project
- The app will appear in your menu bar
Setup
1. Grant Accessibility Permissions
YabaiPro needs Accessibility permissions to control window management:
- When you first run YabaiPro, it will show an alert asking for permissions
- Click "Open System Settings" or go to:
- System Settings → Privacy & Security → Accessibility
- Add and enable YabaiPro in the list
2. Configure Yabai
Ensure Yabai is properly installed and configured. YabaiPro will create/update your ~/.yabairc file.
Usage
- Launch YabaiPro: The app runs in the menu bar (rectangle.split.3x3 icon)
- Click the icon: Opens the settings popover
- Adjust settings: Toggle options and use sliders as needed
- Apply changes: Click "Apply Changes" to update Yabai immediately
- Use presets: Click "Default" or "Minimalist" for quick configurations
SIP (System Integrity Protection) Features
Some features require SIP to be disabled:
- Fade inactive windows
- Disable window shadows
- Transparent menu bar
To disable SIP:
- Restart your Mac in Recovery Mode (hold Command + R during startup)
- Open Terminal from the menu bar
- Run:
csrutil disable - Restart your Mac
⚠️ Warning: Disabling SIP reduces system security. Re-enable with csrutil enable when done.
Troubleshooting
Changes not applying?
- Ensure Yabai is running:
brew services start yabai - Check permissions in System Settings
- Restart Yabai:
launchctl kickstart -k gui/$(id -u)/org.yabai.yabai
Config file issues?
- YabaiPro backs up your
~/.yabaircto~/.yabairc.backupbefore changes - Restore backup if needed:
cp ~/.yabairc.backup ~/.yabairc
Permission denied errors?
- Re-grant Accessibility permissions
- Check that YabaiPro has execute permissions:
chmod +x /Applications/YabaiPro
Development
Project Structure
YabaiPro/
├── Sources/
│ ├── YabaiProApp.swift # Main app entry
│ ├── StatusBarController.swift # Menu bar management
│ ├── SettingsView.swift # UI components
│ ├── SettingsViewModel.swift # Business logic
│ ├── ConfigManager.swift # ~/.yabairc management
│ ├── YabaiCommandRunner.swift # Command execution
│ └── PermissionsManager.swift # Accessibility permissions
├── Package.swift # Swift package definition
└── README.md # This file
Building
# Debug build
swift build
# Release build
swift build -c release
# Run tests (when added)
swift test
Contributing
- Fork the repository
- Create a feature branch
- Make your changes
- Test thoroughly with Yabai
- Submit a pull request
License
MIT License - see LICENSE file for details.
Acknowledgments
Remote Control (iPhone companion)
YabaiPro can expose a local HTTP/WebSocket server that allows a companion iOS app ("WindowPilot") to control Yabai remotely over the local network.
Quick start:
- Open YabaiPro and go to Settings → Remote Control.
- Click "Start Server & Pair" to start the local server and generate a 6-digit PIN.
- On the iPhone app (or a web client), discover the Mac via Bonjour (
_yabaipro._tcp) and enter the PIN to pair. - The iOS app will receive a token which it stores in the Keychain and uses for future commands (Authorization: Bearer <token>).
Security notes:
- The server binds to
127.0.0.1and advertises via Bonjour on the local network. Pairing uses an ephemeral PIN (default 2-minute lifetime). - Paired devices are persisted to
Application Supportasyabaipro_paired_devices.json. Tokens are kept short-lived on the client and can be revoked from the app.
API (MVP):
- POST
/pair/start-> { pin: "XXXXXX" } - POST
/pair/confirm{ pin: "XXXXXX", name?: "My iPhone" } -> { token: "..." } - GET
/state-> { windows: [...], spaces: [...] } - POST
/window/focus{ direction: "north" } - POST
/space/focus{ index: 2 }
This feature is experimental. See the Sources/RemoteServer.swift and Sources/RemoteAuthManager.swift files for implementation details.
Tailscale (recommended for remote pairing)
If you use Tailscale, pairing your iPhone to YabaiPro is simple and secure because Tailscale provides an encrypted mesh network between your devices.
Quick steps
- Install and sign into Tailscale on both your Mac and iPhone.
- In YabaiPro, open Settings → Remote Control and click "Start Server & Pair". The app will show a 6-digit PIN and list reachable addresses (LAN and Tailscale IPs) plus a QR code you can scan with your iPhone.
- On the iPhone, use the companion app or any HTTP client to visit the displayed URL (for example
http://100.x.y.z:PORT/pair/start) or scan the QR code. Confirm pairing in the app by entering the PIN when prompted. - After
POST /pair/confirmreturns a token, the iPhone client stores it and usesAuthorization: Bearer <token>for future commands.
Notes and tips
- The macOS server binds to all interfaces (0.0.0.0) so it is reachable from LAN addresses and Tailscale IPs. The Settings UI shows the list of reachable HTTP URLs and a QR code for easy pairing.
- If you use Tailscale MagicDNS, you can also use the MagicDNS hostname (e.g.,
my-mac.tailnet.example) instead of the raw IP. - For local-only testing (no phone), YabaiPro still supports loopback testing via
127.0.0.1when run locally from the build.
Security recommendations
- Keep pairing PINs short-lived (default 2 minutes) and require the Bearer token for all protected endpoints (already implemented).
- Prefer connecting over Tailscale (encrypted mesh). Do not open the server port to the public internet unless you enable additional TLS/ACL protections.
- Use Tailscale ACLs to restrict which devices on your tailnet can reach your Mac.
- If you need to allow access outside Tailscale, consider adding TLS and stronger authentication (mutual TLS or OAuth) before exposing the server.
Troubleshooting
- If the iPhone cannot reach the Mac over Tailscale, verify Tailscale is running on both devices and check the Mac's reachable addresses shown in Settings. Running
tailscale ip -4on the Mac prints your Tailscale IPv4 address.