Every released version of coffee-bar, newest first.
The format follows Keep a Changelog. The project follows Semantic Versioning.
Current release
A fix release for three things v0.3.0 got wrong on the surface a new user meets first. Nothing here changes what coffee-bar decides. All three are the app either refusing an action it had just offered, or failing to explain something it had just done.
pmset displaysleepnow, which is required rather than incidental: a machine held awake with its lid shut must not keep the panel lit. Nothing said so, and the most visible consequence of the click read as a crash. The armed line now says the display was put to sleep and that the lid can be closed. (#143)The published 0.3.0 entry claimed four things that were not true of the build it described, and they are corrected in place rather than left standing. The repository's front page still announced v0.1.1 three releases on, and now states what v0.3.0 shipped, including the single outbound request the app makes. SECURITY.md records that helper removal and the unsigned-build fallback were both exercised on 2026-08-19, with the limits of that measurement stated beside it.
Two guards were added for defects that had shipped through a green suite: one refuses any page under site/, and the README, that claims the app makes no network request, and one holds the update verdict against the stamp it was reached with.
| Fact | Value |
|---|---|
| File | coffee-bar-0.3.1.dmg |
| Size | 1059046 bytes |
| SHA-256 | ca72a571f5595da27d377bbb69ed0fe3b20869bcc9823caeb490fbc2afc2badd |
| Architecture | Apple silicon (arm64) only |
| Minimum macOS | 14.0 |
| Signature | Developer ID Application, team 85FN4Z37V8 |
| Notarisation | spctl accepts it, source Notarized Developer ID |
| Staple | xcrun stapler validate passes on the app and on the image |
Verify the download before you open it:
shasum -a 256 coffee-bar-0.3.1.dmg spctl -a -t open --context context:primary-signature -vv coffee-bar-0.3.1.dmg
Lid-closed mode is a button. Keeping a Mac awake with the lid shut used to mean finding a command in the docs, copying it into a terminal and running it under sudo; the app could not do it, and said so. Preferences does it now. The first run takes two clicks with a trip to System Settings in between, because macOS installs the helper switched off and leaves the switch for you to find; after that it is one click, and reverting is one click in the same window.
The rest of the release is about the first ten minutes and the days after them: coffee-bar now asks what it needs to know the first time it runs, can open at login, says when a newer version is published, keeps the machine reachable rather than merely powered, and answers an agent that asks what it is doing.
SMAppService helper and macOS is what runs it as root: the app process never becomes root itself, takes no credentials and runs no interpreter. The channel between the two is XPC, and its peer is pinned by Team ID and by bundle identifier, evaluated by Security.framework, so no other process can drive the helper over that channel. The pin binds the XPC endpoint rather than the machine: sudo coffee-bar-probe arm arms the same hold from a terminal, and on a Homebrew install it is the only route. This is opt-in and it is the only part of coffee-bar that involves root at all. (#71)SleepDisabled back to confirm it returned to 0, and only then unregisters. That order is the feature: unregistering first, or letting the read-back fail quietly, would leave the system flag set with the one thing that could clear it already gone. This is opt-in, and the app cannot reach root by any other route. (#71)GET /status on the ingest socket returns JSON: the version the panel shows, the control position you chose, whether a hold is in force, how many sessions are working, how many are waiting on you, one word for hook health, and whether this process is answering. It is read-only, it publishes counts and never sessions, and the hook channel that agents already post to still answers with an empty body, so nothing coffee-bar knows reaches an agent that did not go and read it. (#9)SleepDisabled is twenty-four hours, three times the eight hours earlier versions enforced, so an eight-hour cap named in an older entry below belongs to that release and not to 0.3.0. On battery the hold still ends at the daemon's own floor before any of that, which is the protection that matters when you arm it and walk away. (#74, #121)Allow header naming the verb that resource serves: POST for the hook channel, GET for /status. Neither reads a body it was never going to accept. (#102)Token accounting is v0.4 and does not exist here. Nothing in this release measures battery saved: that number needs a harness a user can reproduce, and that harness is not built.
| Fact | Value |
|---|---|
| File | coffee-bar-0.3.0.dmg |
| Size | 1054199 bytes |
| SHA-256 | 61009669234d891418bfd367289a95cb7fed85ab407711ba1038bbdde3fc441d |
| Architecture | Apple silicon (arm64) only |
| Minimum macOS | 14.0 |
| Signature | Developer ID Application, team 85FN4Z37V8 |
| Notarisation | spctl accepts it, source Notarized Developer ID |
| Staple | xcrun stapler validate passes on the app and on the image |
This is not a universal binary. lipo -archs on the shipped binary reports arm64 alone, so an Intel Mac cannot run it.
Verify the download before you open it:
shasum -a 256 coffee-bar-0.3.0.dmg spctl -a -t open --context context:primary-signature -vv coffee-bar-0.3.0.dmg
Previous release
A release about trusting the suite that certifies this app. Nothing here changes what coffee-bar does for you. Seven tests could fail on a loaded machine while the code they cover was correct, and a suite that cries wolf is one you stop reading — which is how a real defect ships behind 900 green checks.
Five root causes, each traced to a specific line and each fix mutation-checked: delete the fix, the guard must go red.
fopen(path, "w"), which truncates the file to zero bytes before writing, on a 50 ms cycle — so a reader could observe an empty file. Measured at 71 empty reads in 219,902 samples. Worse for the crash test, which reads after a SIGKILL: a kill landing inside that window left the file empty permanently. The helper now writes to a sibling path and rename(2)s over the target, so a reader sees the old report or the new one and never neither. (#84)hdiutil create fails with Resource busy. Measured from a CI log: all three started within 0.93 s of each other and ran concurrently for about 45 s. The create/attach/detach cycle is now serialised — pairwise overlap went from 96.10 s to zero.52 (empty reply) and 55 (failed sending data) both describe the socket accepting a post and then dropping it; which arrives depends on where the drop lands relative to the write. The test now accepts exactly those two, and still fails on delivery or refusal.COFFEE_BAR_SHIM_TIMEOUT_SECONDS sets the hook shim's total run budget. It is the only production change in this release and exists so tests can raise the budget above what a loaded machine costs. Absent, unparseable, zero, negative, non-finite or above the five-second ceiling all fall back to the shipped default of one second, so behaviour is unchanged unless you set it deliberately.site/, the app's UI and every user-facing behaviour are untouched. The only shipped binary difference is the shim's budget resolver above.
| Fact | Value |
|---|---|
| File | coffee-bar-0.2.2.dmg |
| Size | 860341 bytes |
| SHA-256 | 21839e1612b67a845943102b4737d4cd2f3984d5facee4e428a992774e08331b |
| Architecture | Apple silicon (arm64) only |
| Minimum macOS | 14.0 |
| Signature | Developer ID Application, team 85FN4Z37V8 |
| Notarisation | spctl accepts it, source Notarized Developer ID |
| Staple | xcrun stapler validate passes on the app and on the image |
This is not a universal binary. lipo -archs on the shipped binary reports arm64 alone, so an Intel Mac cannot run it.
Verify the download before you open it:
shasum -a 256 coffee-bar-0.2.2.dmg spctl -a -t open --context context:primary-signature -vv coffee-bar-0.2.2.dmg
Previous release
A release about trust in what the app tells you. Four things it reported, or failed to report, were not true. Each is now correct, and each correction is held in place by a check that fails if it regresses.
null, or not a string counted as healthy, so the app would tell you your setup was fine while it could never run. A tool event now requires a matcher the tool can actually use, and a lifecycle event must carry none at all. (#55)SMAppService were written when this project had no signed bundle. One has shipped since 0.2.0. Both decisions now read as unimplemented rather than impossible, and the open question is tracked in #71. (#86)| Fact | Value |
|---|---|
| File | coffee-bar-0.2.1.dmg |
| Size | 858099 bytes |
| SHA-256 | 0c1cd40bbd2c8a1bd2e1cd54122ab49d7f5f40b5a716772d0713917178f11288 |
| Architecture | Apple silicon (arm64) only |
| Minimum macOS | 14.0 |
| Signature | Developer ID Application, team 85FN4Z37V8 |
| Notarisation | spctl accepts it, source Notarized Developer ID |
| Staple | xcrun stapler validate passes on the app and on the image |
This is not a universal binary. lipo -archs on the shipped binary reports arm64 alone, so an Intel Mac cannot run it.
Verify the download before you open it:
shasum -a 256 coffee-bar-0.2.1.dmg spctl -a -t open --context context:primary-signature -vv coffee-bar-0.2.1.dmg
Nothing to do beyond installing it. This release changes no on-disk format and ends no hold that is already running.
If you armed lid-closed mode with an earlier build, install this one and then follow the advisory the panel now shows: the root helper is replaced by the command it gives you, not by the installer.
Homebrew installs 0.2.1 as well: the tap pins this tag. It builds on your machine, so that copy is signed only ad hoc and is not notarised. The disk image is the signed, notarised and stapled artifact.
Previous release
Lid-closed mode, a Preferences window, and a hardened privileged path. The disk image now carries coffee-bar-probe, so the feature it unlocks is reachable without building from source.
sudo coffee-bar-probe arm holds the Mac awake with the lid shut, governed by a launchd watchdog with a revert ladder and a hard eight-hour cap.10% and 50% in steps of 5.coffeebar-hook shim, so each agent tool's hook file is read in its own shape.coffee-bar-probe inside the bundle, and so inside the disk image. 0.1.1 shipped coffee-bar alone, which left lid-closed mode reachable only by building from source.scripts/release-dmg.sh, which builds this disk image. 0.1.1's image left no trace in the repository of how it was made.| Fact | Value |
|---|---|
| File | coffee-bar-0.2.0.dmg |
| Size | 844641 bytes |
| SHA-256 | 5c16bfd3636adfc568e14dbf26e8a3c62ecd9e2fb2606136a08e6342c965cd15 |
| Architecture | Apple silicon (arm64) only |
| Minimum macOS | 14.0 |
| Signature | Developer ID Application, team 85FN4Z37V8 |
| Notarisation | spctl accepts it, source Notarized Developer ID |
| Staple | xcrun stapler validate passes on the image; the app inside it was NOT stapled |
The Staple row above read passes until 0.2.1, which is what a run that stapled only the image prints. Measured on the shipped 0.2.0 image: stapler validate exits 65 on CoffeeBar.app with "does not have a ticket stapled to it". 0.2.1 staples the app as well, and the row now names both so the two states can be told apart. That is #82.
Verify the download before you open it:
shasum -a 256 coffee-bar-0.2.0.dmg spctl -a -t open --context context:primary-signature -vv coffee-bar-0.2.0.dmg
uninstall booted the service out before removing its plist, leaving a root LaunchDaemon that came back at every boot.mach_continuous_time(), which keeps counting across sleep.schemaVersion moved from 1 to 2.Installing this version ends an arm that is already running. A hold armed by an older build wrote a version 1 journal. The first watchdog rung reads it, answers .unknownSchema, and reverts. That is the fail-safe working as designed, but it is invisible unless you know the schema moved. Re-arm after installing.
Homebrew installs 0.2.0 as well: the tap now pins this tag. It builds on your machine, so that copy is signed only ad hoc and is not notarised. The disk image is the signed, notarised and stapled artifact.
Previous release
The first signed and notarised download. This release ships no code change.
coffee-bar-0.1.1.dmg, on the GitHub release page. It is the first artifact signed with a Developer ID, notarised by Apple, and stapled.| Fact | Value |
|---|---|
| File | coffee-bar-0.1.1.dmg |
| Size | 299302 bytes |
| SHA-256 | afc1b15f9bde31aad09de80f23ae97b05f6053322b68b89bab36bcfbc641d2e6 |
| Architecture | Apple silicon (arm64) only |
| Minimum macOS | 14.0 |
| Signature | Developer ID Application, team 85FN4Z37V8 |
| Notarisation | spctl accepts it, source Notarized Developer ID |
| Staple | xcrun stapler validate passes on the app and on the image |
Measured on the shipped 0.1.1 image, not inferred: stapler validate exits 0 on the image and on CoffeeBar.app inside it. 0.2.0 lost the second of those and 0.2.1 restored it, so this row now says which staples were checked rather than the bare passes it shared with 0.2.0 — wording that read the same either way.
Verify the download before you open it:
shasum -a 256 coffee-bar-0.1.1.dmg spctl -a -t open --context context:primary-signature -vv coffee-bar-0.1.1.dmg
site/. It now carries the product's own identity and the assertion timeline.SECURITY.md. Four stale claims now match the code..gitignore. It now excludes the signing and notarisation secrets.None of these change the application.
The application is the same code as 0.1.0. The measured difference between the two tags over the shipped source is empty:
git diff --stat v0.1.0..v0.1.1 -- Sources/ Package.swift Tests/
That command prints nothing. Take this release for the signed artifact, not for new behaviour.
When 0.1.1 shipped, Homebrew still installed 0.1.0: the tap pinned the older tag and built from source, so the version in the panel differed from the version in the disk image. The tap has since moved on.
Previous release
The first release. coffee-bar is a macOS menu-bar app that keeps the Mac awake while a coding agent works, and lets it sleep when every agent waits on you.
Auto, coffee-bar holds a PreventUserIdleSystemSleep assertion while an agent session is starting or working. It releases the assertion when every session waits on a human. Under Auto, a session that waits on you holds nothing.Off never holds, and it outranks an active session. Auto is the default, and the sessions decide. On holds whatever the sessions do. The battery floor below still applies to Auto and to On.Sleeps is the default, so the screen goes dark while the machine stays awake. Stays on adds a PreventUserIdleDisplaySleep assertion. That assertion rides the system hold and never outlives it.SessionStart, PreToolUse, PostToolUse, PermissionDenied and Stop. The app learns what your sessions do from these hooks and from nothing else.awaitingPermission and awaitingInput.coffee-bar asks macOS for the same power assertions caffeinate uses. v0.1.0 needs no root, no password, and no kernel extension.
v0.3.0 on GitHub · v0.2.2 on GitHub · v0.2.1 on GitHub · v0.2.0 on GitHub · v0.1.1 on GitHub · v0.1.0 on GitHub