Your AI limits in the tray: how Bumeter's menu bar icon works

#tray#tauri#ux#rust

Most of the time you do not want another window. You want to glance up and know whether you can keep going. That is what Bumeter's tray icon is for: one small face in the menu bar, one click for the numbers, and the full app only when you ask for it.

What you see without clicking

Bumeter sits in the system tray: the menu bar on macOS, the notification area on Windows, the top bar on Linux. Two things are always visible:

AsleepNo recent data: the numbers are old and you have not worked for 30 minutes
On fire5-hour limit past your danger threshold (90%), or a very expensive turn in the last 10 minutes
WorriedPast your warning threshold (70%), or on pace to run out before the reset
HappyYou have used less today than on an average working day this month
CalmEverything else: a normal day

The rules are checked in that order, so the most urgent face wins. "On pace to run out" counts every tool, so Kiro credits running low worry Bum too, not only Claude's windows. Both thresholds come from Settings, the same numbers that trigger notifications.

What the menu shows

Click the icon and the menu opens with one block per tool you have installed. Tools Bumeter supports but that are not on your machine are left out.

macOS · Windows
90%
Claude Code
5 hours · 49% · reset 13:10
7 days · 90% · reset Oct 16
Kiro
Month · 27% · 271/1000 credits · reset Nov 1
Today: Claude Code 1.2M tokens · Kiro 12 credits
Open Bumeter
Pause notifications for 1 hour
Check for updates
Quit
Linux (GNOME)
90%
Claude Code
▰▰▰▰▰▱▱▱▱▱ 🟢 5 hours · 49% · reset 13:10
▰▰▰▰▰▰▰▰▰▱ 🔴 7 days · 90% · reset Oct 16
Kiro
▰▰▰▱▱▱▱▱▱▱ 🟢 Month · 27% · 271/1000 credits · reset Nov 1
Today: Claude Code 1.2M tokens · Kiro 12 credits
Open Bumeter
Pause notifications for 1 hour
Check for updates
Quit

On macOS and Windows each row has a small ring: orange as it fills, red from your warning threshold or when you are on pace to run out, grey when the data is old. Linux menus cannot show those icons, so the same information is drawn in text: a ten-cell bar and a coloured dot.

How to use it

  1. Install and start Bumeter. It goes straight to the tray and starts reading your logs; there is nothing to configure for tokens.
  2. Turn on limit tracking for the Claude Code percentages: Settings → Limit tracking. Bumeter reads them from Claude Code's status line (the previous post explains how). For Kiro, Bumeter asks kiro-cli for your real credit usage by itself, at startup and every 15 minutes; if that is not available, set your monthly credit limit in Settings.
  3. Click a tool's row to open the app already filtered to that tool.
  4. Pause notifications for 1 hour when you are in a meeting or presenting. The tray keeps updating; only the pop-ups stop.
  5. Close the window when you are done. Bumeter keeps running in the tray. Use Quit to stop it.

The menu speaks your language (English or Vietnamese, from Settings) and follows Settings immediately: change a threshold and the next refresh uses it.

How it is built

The tray is part of the Bumeter desktop app, built with Tauri. The interesting parts are less about the tray API and more about keeping a small icon honest, cheap and identical on three operating systems.

One source of truth for the text

The text of every row is not written in the app. It comes from meter::render_tray in bum-core, the same library that serves the CLI. That is why bum status in a terminal prints the same tool lines as the tray menu: they are the same function. The app only places the rows into the menu.

The menu is built once, when the app starts, with a fixed number of rows per tool (the tool registry decides how many). After that, each refresh only changes the text (and, where it changed, the icon) of the items that are already there; the menu itself is never rebuilt.

When it refreshes

The tray updates when there is something new, and otherwise stays quiet:

Each refresh reads the settings file again, so a change in Settings shows up without a restart.

Ring icons drawn in Rust

Each ring is a 32×32 image drawn in plain Rust, anti-aliased by sampling every pixel 4×4 times, with a translucent grey track so it looks right on light and dark menus. There is no image library and no SVG renderer. Percentages are rounded to whole numbers, so there are at most 101 rings per colour, and each one is drawn once and cached. A row's icon is only replaced when its rounded value or colour actually changes.

Linux is different, so it gets text

On Linux the tray goes through AppIndicator and D-Bus menus. Two limits there shaped the design: menu item icons are not shown in the GNOME top bar, and an item that has an icon cannot change its label afterwards. So on Linux every row is a plain text item, and the ring becomes text:

▰▰▰▰▰▱▱▱▱▱ 🟢  5 hours · 49% · reset 13:10

The bar comes first on purpose: menu fonts are proportional, and starting each line with the fixed-width bar keeps them lined up. A used limit shows at least one cell, and the bar is only full at 100%, so 99.6% never looks like "blocked". Menu text cannot be coloured, but emoji can, so the dot carries the colour.

The mascot is a pure function

The face is chosen by a small function, face_for, from a handful of facts: how old the quota data is, minutes since your last turn, the 5-hour percentage and your two thresholds, minutes since the last unusually expensive turn, today's tokens against your 30-day average, and whether any tool is on pace to run out. It has no side effects, so every rule has a unit test, and the Bum on the app's screens follows the same rules.

Light when idle

The window exists only while it is open. Closing it destroys the web view instead of hiding it, so the app sitting in your tray all day costs little memory. Clicking Open Bumeter builds a fresh window, and clicking a tool row opens it straight on that tool.

Bumeter is free and open source (GPL-3.0), and everything stays on your machine. The source is at github.com/chieund/bumeter. The tray code lives mostly in app/src-tauri/src/tray.rs, crates/bum-core/src/meter.rs, ring.rs and face.rs.

Download Bumeter