In progress Aug 2026

Granola Prizegiving

A macOS menu bar app that reads your meeting transcripts and hands out tongue-in-cheek talk-time awards. Also my first go at anything native.


Two things happened in the same week. I found out Granola has a public API that’ll give you your notes and, more interestingly, diarised transcripts. And I caught myself monologuing extremely hard in a meeting at work.

So: a little menu bar app that reads the transcript after a meeting and hands out awards.

Prizegiving awards handed out for a meeting

The awards

Deliberately petty. Chatterbox for total talk time, Longest Monologue, Fastest Talker in words per minute, Quietest, and Most Interruptions, which is really just counting how often someone started talking before the last person had finished. That one’s flagged “approx.” in the UI because it’s a timestamp overlap and not a judgement of character. It is, obviously, a judgement of character.

If it’s a one-on-one you don’t get a leaderboard, you get you vs. the other person, which is somehow worse.

The native bit

I’ve wanted to build a macOS menu bar item for ages and never had a reason. It’s Tauri, so the UI is Vue and TypeScript and the shell is Rust, which meant I got to do the native parts without writing a whole app in Swift.

  • The tray icon has to be a template image. macOS ignores your colours and tints the alpha mask so it works on light and dark menu bars. Took me a while to work out why my nice icon was showing up as a black blob.
  • Setting the activation policy to Accessory is what keeps it out of the Dock and the app switcher. One line, and suddenly it feels like a menu bar app rather than a window that happens to be small.
  • The popover uses the native menu material with a blur, and hides itself the moment it loses focus. That single behaviour is about 80% of “feels right”.
  • Granola’s API 404s the CORS preflight, so fetching from the webview is a non-starter. Every request goes through a small Rust command instead, locked to the Granola host. Annoying problem, tidier outcome.
  • Your API key lives in a settings file in the OS config dir rather than a .env, so the tray popover and the settings window are reading the same thing.

It polls in the background, diffs the note IDs against a set it’s already seen, and fires a notification when a new meeting shows up. First run just seeds the baseline rather than notifying you about every meeting you’ve ever had, which I learned the hard way.

Where it’s at

Fully working, as of yesterday. I’ll be testing it myself this week, and bracing for it to identify me as Chatterbox more often than I’d like.

Next job is signing and packaging it properly so there’s a .dmg you can grab straight off this site. That’ll go up here soon. For now the source is on GitHub if you want to build it yourself.