A macOS menu-bar app that turns a Ulanzi LED matrix clock running AWTRIX 3 into an ambient notifier — for your Mac Calendar meetings, for Claude Desktop when it's waiting on you, and as a pixel canvas you can paint and push to the display.
It runs quietly in the menu bar, talks to the clock over its local HTTP API, and sends nothing anywhere else.
- Meeting warnings — 10 minutes before a timed Mac Calendar event, its name scrolls across the clock for 15 seconds. All-day and declined events are skipped, and you can choose which calendars are watched.
- Claude Desktop "awaiting input" — when Claude Desktop is blocked on a
permission prompt or an
AskUserQuestion, a little waving figure appears with a short message and a corner LED lights until you answer. The message reflects what's waiting (a shell command, a question, a plan to review, computer use…). A "done" ping fires when a long (>30s) task finishes. - Pixel paint — a 32×8 paint window (pixel, fill, text, colour, clear tools) that pushes an image to the clock live as you draw, or on a schedule, for a set number of minutes or until you clear it.
- Menu surface — per-feature toggles, a live status panel (clock reachable, calendar access, next meeting, Claude log health, pending count), a calendar picker, a manual "Clear notification", and a Settings window (see below).
Claude Desktop does not expose an API for "is it waiting on me", so the app
tails its local log file at ~/Library/Logs/Claude/main.log and watches for
the lines it writes when a permission request is emitted and resolved. That file
is read locally and never transmitted — the app's only network traffic is
HTTP to your clock on your LAN.
This log format is undocumented Claude Desktop internals and can change with any update. When it does, the menu shows the Claude feature as degraded rather than silently going dead, so you'll know.
- macOS 14 (Sonoma) or later
- Swift 6 toolchain (Xcode 16+ or the standalone toolchain) to build
- A Ulanzi / AWTRIX 3 clock reachable on your local network
- Claude Desktop (only for the Claude-notification feature)
git clone https://github.com/elpabl0/claude_clock.git
cd claude_clock
# Point it at YOUR clock's IP (see "Configuration" below), then:
./scripts/install.shinstall.sh builds a release, assembles a .app bundle, ad-hoc-signs it,
installs it to /Applications, and launches it. On first run macOS will ask for
Calendar access — grant it for meeting warnings to work. The app registers
itself as a login item so it starts with you.
To build and run the tests without installing:
swift build
swift test # ~240 unit tests, no device or calendar neededMost settings live in the Settings window — open it from the menu-bar icon (Settings…, or ⌘,). It has:
- Clock — your clock's host/IP, with a Test button that checks
reachability. This is the one thing you must set for your own device (it
defaults to
10.6.20.196). Changes take effect immediately, no restart. - Startup — a launch-at-login toggle.
- Timing — meeting lead time (default 10 min), notification duration (15 s), and the "done" ping threshold (30 s).
- Messages — edit the per-category wave messages (generic / shell / question / plan / computer / done) in place.
Advanced:
- The messages also live at
~/Library/Application Support/AECSClock/messages.jsonif you'd rather edit the file directly. The device host is stored undercom.aecs.clockinUserDefaults(defaults write com.aecs.clock deviceHost "…") — the Settings window is the friendly way to set it. - The wave icon.
Sources/IconGen/regenerates the little character (swift run IconGen); upload the result to the clock's/ICONSfolder. The two source frames live inResources/icon/.
Swift Package Manager, no third-party dependencies. The code is split into small, single-purpose targets with one-way dependencies:
| Target | Responsibility |
|---|---|
AwtrixClient |
HTTP to the clock (notify, indicators, image push, reachability) |
ClaudeWatch |
Tails the Claude log; parses it; tracks pending prompts and turns |
CalendarWatch |
EventKit adapter + pure meeting-scheduling logic |
ClockCore |
All alerting policy, settings, the pixel-canvas/font/scheduler |
AECSClock |
The menu-bar app and the paint window (AppKit) |
docs/ holds the design specs and implementation plans if you want the full
rationale behind each iteration.
Useful scripts: scripts/testfire.sh {meeting|claude|clear} fires test
notifications; scripts/bundle.sh builds the signed .app.
- The Claude log format is unofficial and may break on Claude Desktop updates (surfaced as "degraded" in the menu).
- The app is ad-hoc signed — you build and run it yourself; it is not notarized or distributed as a binary.
MIT.
Built on the excellent AWTRIX 3 firmware by Blueforcer and its open HTTP API.