- OpenClaw: JSONL parser with multi-path discovery, tool extraction
(toolCall + tool_use block types), model tracking via model_change
and custom model-snapshot events
- Roo Code + KiloCode: shared Cline-family parser extracts model from
<model> tags in api_conversation_history.json, strips provider
prefixes from model names
- Add cline-auto and openclaw-auto aliases and display names
- Add menubar provider filters and tab colors for all three
- Show cached data instantly instead of blocking on CLI refresh
Parse ~/.gemini/tmp/<project>/chats/session-*.json files from Gemini
CLI 0.38+. Uses real token counts (input, output, cached, thoughts)
embedded in each message instead of character estimation. Correctly
separates cached tokens from fresh input to avoid double-charging.
- Pricing for gemini-3.1-pro-preview, gemini-3-flash-preview,
gemini-2.5-pro, gemini-2.5-flash from official Google API rates
- Tool name normalization (ReadFile->Read, SearchText->Grep, etc.)
- Menubar tab with Google Blue color (#4485F4)
Closes#166
* Add Kiro provider and transparent auto-model naming
- Add Kiro IDE provider: parses .chat JSON files, estimates tokens,
normalizes dot-versioned model IDs for cost lookup
- Show "Cursor (auto)", "Copilot (auto)", "Kiro (auto)" in CLI
dashboard instead of pretending to know which model was used
- Route auto model names through BUILTIN_ALIASES for cost estimation
* Fix menubar tabs: add missing providers, show period-scoped costs
- Add Kiro, OMP to ProviderFilter enum so installed providers appear as tabs
- Merge Cursor + Cursor Agent into single Cursor tab
- Tab costs now reflect the selected period (7d/30d/month/all) instead
of always showing today
- Tab visibility still uses today's provider list so tabs don't
disappear when switching to periods with no data
* Add accent color picker to menubar with Apple system presets
- 9 presets using Apple's exact macOS dark-mode accent colors
(Ember, Blue, Purple, Pink, Red, Orange, Yellow, Green, Graphite)
- Color picker in header, persisted via UserDefaults
- "Burn" text stays fixed ember regardless of accent
- ThemeState is MainActor-isolated for thread safety
- Picker state lifted to AppStore so it survives .id() tree rebuild
- Accessibility labels on all color swatches
- Renamed brandAccentDark/brandEmberDeep/brandEmberGlow to match
their actual light/deep/glow semantics
* Fix review findings: case-sensitive cost lookup, Kiro timestamp guard, cache versioning
- Normalize provider dictionary keys to lowercase in tab cost lookup
so "Cursor Agent" (title-case from CLI) matches providerKeys
- Guard against missing/invalid/epoch startTime in Kiro parser to
prevent RangeError crash or 1970-01-01 ghost entries
- Bump DAILY_CACHE_VERSION to 4 so upgraded users get a clean
recompute with the new auto-model naming (cursor-auto vs default)
- Add version field to cursor-results.json cache to invalidate stale
entries that still use the old 'default' model name
The AgentTabStrip was using allProvidersToday for cost display, which
meant tabs always showed today's per-provider costs regardless of
which period was selected. This caused the hero to show e.g. $209 for
30 Days but the Claude tab to show $59 (today's Claude cost).
Fix: cost(for:) now reads from store.payload (selected period) instead
of allProvidersToday. Tab VISIBILITY still uses todayPayload so tabs
don't disappear when switching periods.
Bug existed since the original menubar app commit (495a254, Apr 17).
Fixes crash when switching timeframes or providers by handling
duplicate dates in history data gracefully.
Adds LaunchAgent that posts a distributed notification every 15
seconds to keep prices fresh even after long idle periods.
Loading overlay no longer flashes on every 15s poll. isLoading now only
toggles when the cache is cold, and all periods prefetch once on launch
so tab switching is instant.
Heatmap tooltip, trend bars, forecast, and all-time stats were computing
on UTC dates while the CLI reports on local dates, so the two disagreed
at day boundaries. Switched every date formatter and calendar in these
paths to .current so the menubar matches codeburn today output.
Remove the broken "Connect Claude" / "Reconnect Claude" buttons from
the Plan pane -- they opened a terminal session that did nothing useful
for already-logged-in users. Keep only the "Retry" button.
Add an auto-update checker that queries GitHub releases every 2 days in
the background. When a newer menubar build is available, an "Update"
pill appears in the header. Clicking it runs the existing installer
flow (download, replace, relaunch) with no manual steps.
Add package.json repository/bugs/homepage fields. Swap hardcoded
AgentSeal/codeburn URLs to getagentseal/codeburn across README,
mac README, macOS menubar star banner, and the menubar installer's
release-API endpoint. 301 redirects keep old URLs working, but
canonical links now point at the current org.
Co-authored-by: AgentSeal <hello@agentseal.org>
The trend chart tooltip always displayed `bar.tokens` in its header,
which is zero for provider-filtered history (the CLI only carries
per-provider cost+calls in the daily cache, not tokens). Result: when
you selected Claude/Codex/Cursor/Pi, hovering a bar showed $0.00 even
on days with real spend.
The trend chart's main metric already falls back to cost when tokens
are zero. Pass that same metric value through to the tooltip so both
stay consistent.
Also removed the misleading "No model breakdown available" fallback
line. For provider-filtered views the per-model breakdown legitimately
doesn't exist in the payload, so the tooltip now just shows date +
cost without the error-sounding message.
The Plan pane previously told users to "run claude login in your
terminal, then retry" with no way to start the flow from the app.
Added a primary Connect Claude button on both the no-credentials and
failed states that launches Terminal.app with `claude login`, so the
OAuth flow is one click away.
TerminalLauncher.openClaudeLogin() uses a hardcoded literal, so no
user input reaches AppleScript. Refactored the common path into
runInTerminal(command:preValidated:) which re-validates any non-
literal input against CodeburnCLI.isSafe as defense-in-depth.
On machines without Terminal.app (iTerm/Ghostty/Warp), the button
surfaces an inline instruction to run `claude login` manually instead
of failing silently.
Tabs were filtering on `value > 0` (today's spend), which hid the row
whenever only one provider had activity today. The CLI's providers map
already contains only providers detected on the system, so showing the
map as-is matches user intent: a tab for each installed tool,
regardless of today's spend. Tab strip only hides when nothing is
detected.
This also makes the Plan pill reachable again: it gates on
`selectedProvider == .claude`, which required clicking the Claude tab
to select.
The tab strip was visible for everyone regardless of which tools they
actually run, which produced a row of All + one provider for Claude-only
users and a row of All + zeros for users on exotic stacks. Hide the
whole row until a second provider has real spend, matching the behavior
the GNOME extension ships with.
Also expand ProviderFilter to include every provider the CLI supports
(OpenCode and Pi were missing) so their tabs appear when those tools
produce sessions. The CLI already emits pi and opencode in the payload's
providers map; the Mac app just wasn't offering a tab for them.
visibleFilters now filters on value > 0 instead of key presence, because
the CLI includes zero-cost entries for discovered-but-unused providers
and we don't want those rendering as blank tabs.