Repository navigation
v0.6.2 — the meter in the menu bar
The menu bar carries the meter, not a flame emoji
The status item now shows the same meter-and-flame as the app icon and the org
avatar, as a template image — so macOS tints it for the bar it lands in and inverts
it while the item is held down.
Getting it to sit level took four attempts and a reader's screenshots, because the
reference was wrong: the glyph was being aligned to its own adjacent text rather
than to the bar. Apple's SF Symbols settle it — gauge.medium, speedometer and
flame.fill all centre their ink at 0.498–0.500 and fill ~0.90 of their box. The
image is now built from the shape: the drawing is rasterised, its ink measured,
and the image sized and placed so that ink fills it and is centred, which is what
every other item in the bar does. The title then gets a one-point baseline offset,
because digits and a percent sign have no descender and otherwise ride high.
--check-layout measures Apple's symbols as well as ours, so the target fails
loudly if their convention moves rather than quietly going stale.
Two pricing bugs, one of them live
A refresh that returned nothing was saved. A refreshed snapshot shadows the
packaged one completely, so a file written with zero models left a real machine
unable to price anything — the model carrying 97% of that user's spend rendered as
an em dash, with no error and no symptom but a cost that had stopped existing.
Upstream was healthy when checked, so the bad response was transient and we
persisted it. refresh_snapshot now refuses a result below a plausibility floor
and leaves the existing file alone, and a refreshed snapshot has to earn its
precedence on every read — because refusing to write only helps machines that do
not already have a bad file.
reprice relabelled locally-served events. It made the pricing decision itself
instead of calling the function the scan path calls, so it never learned about
not_metered: one burn-o-meter reprice turned "there is no rate, it ran on your
own hardware" into "we do not know the rate". Invisible, because both render as an
em dash. The decision now lives in one function both callers use.
Supply chain
22 Semgrep findings to none. Every action is pinned to a commit SHA — a tag can be
repointed by its owner, which is how the trivy-action and kics-github-action
compromises reached their users. Dependabot keeps the pins current, now with a
seven-day cooldown. Workflow inputs reach shell scripts through env rather than
${{ }} interpolation, which is substituted before the shell sees the text at all.
The pricing refresh pins both scheme and host: SECURITY.md has always said there is
exactly one egress, and that is now a property of the code, enforced by tests.
Also
- Rate-limit rows show a reading's age whenever the source samples periodically,
not only once it has aged — which is what makes a figure differing from the
Claude app's explicable rather than suspicious. The Claude app asks Anthropic
directly; we read what it writes to disk, about every 15 minutes. - A test asserts the macOS app knows every cost basis the engine can write. It
decodes unknown values asunpriced, which would be a specific and wrong claim. - The
·between percentage and spend is gone; it read as a stray full stop.
Full notes in CHANGELOG.md.
Upgrading
brew update && brew upgrade devopsinside/burn-o-meter/burn-o-meterThe menu bar app is a separate bundle — the glyph and alignment work is in it,
not the CLI:
git pull && macos/make-app.sh --install && open /Applications/burn-o-meter.app--install matters: macOS will not register a login item for an app outside
/Applications, so one built in place never returns after a reboot. The bundle is
ad-hoc signed and still needs Developer ID notarisation for distribution, which
this project does not yet have.