Releases: jettoai/cleat
Release list
Cleat 0.3.3
The daemon now comes back on its own
Cleat died twice this month and stayed dead for two days each time: it had been started with open -g from a supervised shell, inherited that shell's session mark, and was ended by the supervisor's cleanup at the next account handoff. A login item only starts at login, so nothing brought it back.
- The bundle ships a LaunchAgent and
launchAtLoginregisters it (SMAppService.agent) instead of a login item.KeepAlive{SuccessfulExit:false}: a killed or crashed daemon is back within seconds, a clean quit stays down. launchd starts the binary with a clean environment. cleat restartregisters the agent if needed and has launchd replace the running process.cleat statusgains asupervision:line.- A daemon that LaunchServices started hands over to the launchd one instead of running beside it.
- The 0.3.2 login item is unregistered on first run.
- Cask:
uninstall launchctl:, and a postflight that kickstarts the agent sobrew upgradeleaves a running daemon.
After upgrading, cleat status should show supervision: launchd agent (registered); if it does not, run cleat restart once.
Cleat 0.3.2
Hotfix: 0.3.0 wedged on its first reconcile when reclaim was set
+[IOBluetoothDevice pairedDevices] never returns in a process that holds no Bluetooth privacy decision, which is every launch of Cleat as an app; the engine queue stopped draining on the first beat and every rule went quiet. The paired-headset list now comes from system_profiler, read with a five second limit, only while the Mac is playing, and cached for thirty seconds.
CLEAT_CONFIGoverrides the config path, so a Debug build can run against its own config.
Cleat 0.3.0
The Mac asks its headphones back from an idle iPhone
AirPods that wandered to the phone used to stay there: macOS only re-routes a headset when its own Smart Routing decides to, and a third-party app had no documented way to ask. Rule 7 uses the same routing request the system itself sends.
reclaim— a list of Bluetooth headsets Cleat is allowed to pull back. When one of them is connected to this Mac but missing from CoreAudio's device list, and the Mac's default output is playing, Cleat sends a routing request at the system's "the computer is playing" priority. An idle phone hands the headset over; a phone that is actually playing keeps it, and Cleat backs off for 60 seconds before asking again. Phone first, Mac only when the phone is quiet.cleat reclaim "AirPods Max"— the same request on demand, printing the routing daemon's answer.cleat statusgains areclaimline; the log recordsreclaim: <device> <- remote deviceon success andheld by remote devicewhen the phone wins.
Also in this release:
- Output pinning no longer stops evicting a blocked output when every entry in
outputis a Bluetooth device andheadphonesTakeOveris on. - Input volume locks now hold every device that shares a name, not just the first one.
cleat statusand the README no longer overstate what a blocked list does without a priority list, or claim an unedited example config changes nothing (balanceandlaunchAtLoginapply immediately).
v0.2.0
Bluetooth headphones take over the output when they connect
macOS switches the output to wired headphones the moment you plug them in, and iOS does the same for AirPods. A Bluetooth headset reconnecting to a Mac after a spell on the phone gets neither: the sound stays on whatever was playing before. Rule 6 closes that gap.
headphonesTakeOver: true— a Bluetooth output device that appears becomes the default output. It is edge triggered: picking another device by hand while the headphones stay connected is respected until they leave and come back. Headphones already connected when Cleat starts do not count as arriving.blockedOutput— devices that must never be the default output. A USB microphone's speaker end is what macOS falls back to when the headphones go; listing it here sends the output to the top of youroutputlist instead.outputnow only decides what plays when no headphones are around, so the headset does not have to be listed.config.example.jsonand the README example mirror the shipped setup.
cleat status gains a headphones line and shows the blocked outputs next to outputPin.
Upgrade: brew upgrade --cask cleat. Existing configs keep working; both new keys default to off.
Cleat 0.1.1
What's new
inputVolumeaccepts"*"as a default gain for every input device present; a named entry (name or UID) overrides it for that device. Without a wildcard, unlisted devices are left alone as before.- Volume listeners are registered on every device the rule holds, so a wildcard-covered device that a conferencing app turns down is pulled back on the change itself.
cleat statuslists the default first, then each held device; a device that is present but whose gain could not be read shows(unreadable)instead of(absent).
Universal binary, Developer ID signed, notarized.
brew tap jettoai/tap && brew trust jettoai/tap && brew install --cask cleat
Cleat 0.1.0
First release. macOS audio device keeper: input priority and blocklist, wireless-mic liveness detection, balance lock, output priority, input volume lock, hot-reloaded config, cleat status / cleat log. Signed and notarized universal build.
Install: brew tap jettoai/tap && brew install --cask cleat