Commit graph

407 commits

Author SHA1 Message Date
iamtoruk
39fc05595c Harden menubar: fix refresh loop, concurrency, data sync, and edge cases
- Fix refresh loop: proper while loop with 30s sleep and force:true
  instead of single-fire Task that never repeated
- Fix loading overlay: counter-based isLoading so concurrent fetches
  don't flicker the overlay on/off
- Fix rapid tab switching: cancel previous switchTask, check
  Task.isCancelled after CLI returns to discard stale results
- Fix tab strip vs hero desync: fetch provider-specific and all-provider
  data in parallel so costs arrive from same data snapshot
- Fix stale menubar icon after wake: forceRefresh now fetches today/all
  in parallel alongside the current selection
- Fix accent color: ThemeState is now @Observable so color changes
  propagate via observation, removing .id() view hierarchy teardown
- Fix currency flash: defer store.currency and symbol update until a
  rate is available so symbol and rate apply atomically
- Fix export: terminationHandler instead of waitUntilExit (no UI freeze),
  HHmmss in filename to prevent overwrite on double-export
- Fix CurrencyState: @MainActor isolation with proper Sendable
  conformance, nonisolated on pure static functions
- Fix streak count: iterate calendar days instead of sparse history
  entries so gaps are counted as streak-breakers
- Fix TrendBar identity: stable date-based id instead of UUID
- Add GPT-5.3 and DeepSeek model display names
2026-05-01 08:01:25 -07:00
Resham Joshi
78ad04c77f
Merge pull request #186 from getagentseal/fix/menubar-timezone-184
Fix timezone handling for non-UTC users
2026-04-30 17:33:27 -07:00
iamtoruk
68c6f2c710 Fix timezone handling: menubar UTC bugs, --timezone flag, DST-safe dates
Three fixes for issue #184:

1. Menubar Swift code used UTC instead of local timezone in two places:
   computeHistoryStats hardcoded TimeZone("UTC") and
   effectiveTokensInLast7Days used ISO8601DateFormatter (UTC default).
   Both now use .current to match CLI-produced local date keys.

2. Add --timezone flag and CODEBURN_TZ env var to override the system
   timezone for all date grouping. Sets process.env.TZ before any Date
   operations so all existing local-timezone code works unchanged.

3. Replace MS_PER_DAY arithmetic with Date constructor day-of-month
   math for yesterday/backfill computations. Subtracting 86400000ms
   from midnight skips a day on DST spring-forward (23-hour day).

Fixes #184
2026-04-30 17:33:02 -07:00
Resham Joshi
7ceef6b464
Merge pull request #185 from getagentseal/feat/codex-result-cache
Some checks are pending
CI / semgrep (push) Waiting to run
Add per-file result cache for Codex provider
2026-04-30 16:44:26 -07:00
iamtoruk
8ab9ea916b Add per-file result cache for Codex provider
Fixes #183. Users with large Codex session directories (45 GB, 10K+
files) experienced CPU pegging because every 30-second refresh re-parsed
all session files from scratch.

Three optimizations:

1. readFirstLine now reads 16 KB via fs.open() instead of loading the
   entire file through readSessionFile. Cuts discovery I/O from ~45 GB
   to ~160 MB for 10K files.

2. Per-file result cache (codex-results.json) with mtime+size
   fingerprinting. Parsed results are cached on first run; subsequent
   runs return cached data instantly for unchanged files.

3. Cache-accelerated discovery skips header validation for cached files,
   pulling the project name directly from the cache manifest.

Cache safety: fingerprint captured before read (no TOCTOU), atomic
write via temp+fsync+rename, 0o600 permissions, Object.hasOwn for
prototype pollution defense, eviction of deleted files on flush,
try/finally ensures flush even on parse errors.
2026-04-30 16:43:41 -07:00
iamtoruk
f35400f199 Fix menubar refresh stuck after first load (#179)
forceRefresh() was missing force:true, so the cache TTL guard
silently skipped every LaunchAgent and wake-triggered refresh.
Also adds right-click context menu and version label in footer.
2026-04-30 09:22:38 -07:00
Resham Joshi
78aa6fc534
Merge pull request #181 from davidg-h/fix/copilot-vscode-insiders-integration
Some checks are pending
CI / semgrep (push) Waiting to run
fix(copilot): discover VS Code Insiders transcripts
2026-04-30 07:53:57 -07:00
David
116388427e fix(copilot): discover VS Code Insiders transcripts 2026-04-30 16:27:22 +02:00
Resham Joshi
2e354834e6
Update README.md
Some checks are pending
CI / semgrep (push) Waiting to run
2026-04-29 16:43:06 +02:00
iamtoruk
1db63c6216 Add AgentSeal and CodeBurn GitHub star badges to README
Some checks are pending
CI / semgrep (push) Waiting to run
2026-04-28 16:37:08 -07:00
AgentSeal
46924322d9 Bump version to 0.9.4
Some checks are pending
CI / semgrep (push) Waiting to run
OpenClaw, Roo Code, KiloCode, Qwen, Droid providers. Durable daily cache
with migration. Gemini JSONL fix. README restructure with honeycomb hero.
16 providers supported.
2026-04-29 01:11:27 +02:00
AgentSeal
01f215f634 Switch hero image to raw.githubusercontent.com to avoid CDN cache delay 2026-04-29 01:05:44 +02:00
AgentSeal
d0cfa40c05 Update providers hero image with tighter honeycomb layout 2026-04-29 01:03:24 +02:00
AgentSeal
c3816b0161 Restructure README with new hero image, compare screenshot, and full reference
Replace providers hero image with honeycomb design. Add compare screenshot
to 2x2 grid. Consolidate all documentation into single README with provider
table showing data locations, full feature reference, reading the dashboard
guide, and credits section. Add bunx as alternative install option.
2026-04-29 00:44:56 +02:00
AgentSeal
465294ca1e Merge feat/cache-durability: durable daily cache with migration 2026-04-28 23:18:35 +02:00
AgentSeal
7b8f4df856 Fix review findings: error handling, constant dedup, migration persist
- Wrap hydrateCache() in try/catch so disk errors don't crash commands
  that previously never touched the cache
- Export MS_PER_DAY, BACKFILL_DAYS, toDateString from daily-cache.ts
  and remove duplicates from cli.ts
- Remove double hydrateCache() call in report JSON path
- Persist migrated cache to disk so old-version files aren't
  re-migrated on every run
- Export emptyCache() for use as fallback on hydration failure
2026-04-28 22:56:47 +02:00
AgentSeal
888f592bd2 Make daily cache durable: hydrate from all commands, migrate instead of nuke
- Extract ensureCacheHydrated() from menubar-json path into daily-cache.ts
- Call it from every command that parses sessions (report, status, today,
  month, export, optimize, compare, yield) so CLI-only users also persist
  historical data that survives source file deletion
- Replace strict version equality check with fill-defaults migration for
  cache versions 2-4, preserving history across schema changes
- Back up old cache to .bak before discarding on unmigrateable versions
- Fix Copilot auto bucket display names in menubar (Copilot (Anthropic),
  Copilot (OpenAI))
- Fix Roo Code / KiloCode provider key matching in menubar tab strip
2026-04-28 22:41:01 +02:00
Resham Joshi
fbb2c4e69c
Merge pull request #171 from ksp2000/feature/copilot-auto-model-buckets
refactor(copilot): use auto model buckets for transcript inference
2026-04-28 12:17:50 -07:00
Resham Joshi
77d04172b5
Merge pull request #173 from Aeversil/add-droid-provider
Add Droid CLI provider
2026-04-28 12:09:29 -07:00
Dunccan de Weerdt
26ebe75aa1 Add Droid CLI provider
Discovers and parses sessions from ~/.factory/sessions/, reading JSONL
message logs and companion settings.json files for token usage tracking.

- Discovers sessions by scanning per-cwd subdirectories
- Skips internal .factory housekeeping sessions
- Extracts tools, bash commands, and user messages from JSONL
- Distributes session-level cumulative token counts across calls
- Normalizes Droid model wrappers before existing pricing lookup
- Derives clean project names from cwd paths
- Adds menubar provider filtering for Droid
2026-04-28 20:16:45 +02:00
AgentSeal
607cb463c9 Merge branch 'fix/menubar-perf' 2026-04-28 19:50:13 +02:00
AgentSeal
d043795855 Add Qwen provider and replace hardcoded pricing with LiteLLM snapshot
- Add Qwen CLI provider (discovers sessions from ~/.qwen/projects/)
- Replace FALLBACK_PRICING (40 hand-maintained entries) with auto-generated
  LiteLLM snapshot (3595 models including Azure, OpenRouter pricing)
- Build script fetches and bundles LiteLLM data before tsup
- Provider-prefixed lookups (azure/, openrouter/) resolve to correct pricing
- Add display names for all GPT-5.x model variants
- Add Qwen to menubar provider filter and tab strip
2026-04-28 19:49:14 +02:00
Resham Joshi
ec2de6a642
Add OpenClaw, Roo Code, and KiloCode providers (#175)
- 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
2026-04-28 09:24:14 -07:00
AgentSeal
daa292a998 Show cached data instantly instead of blocking on CLI refresh
Only show the loading overlay when no cached data exists for the
current period/provider. When stale data is available, display it
immediately while the background fetch runs. Also skip CLI calls
entirely when the cache is still fresh (within TTL), reducing
redundant subprocess invocations from the 30s LaunchAgent timer.
2026-04-28 18:09:13 +02:00
saipraneeth.konda
74c1c4b4c1 refactor(copilot): use auto model buckets for transcript inference 2026-04-28 19:32:03 +05:30
AgentSeal
ce78ac52c1 Add builtin aliases for Cursor model names
Some checks are pending
CI / semgrep (push) Waiting to run
Cursor emits dot-version tier-last names like claude-4.6-sonnet
that don't match our pricing keys. Map them so individual models
show costs instead of $0.
2026-04-28 15:09:54 +02:00
AgentSeal
64259c929c Fix Gemini provider for JSONL format (CLI 0.39+)
Gemini CLI 0.39 switched from single JSON to JSONL with one object
per line and $set metadata lines. Parser now handles both formats.
Also updated --provider help text to list all providers.
2026-04-28 15:03:39 +02:00
AgentSeal
220d3193db Fix menubar not dimming on inactive screens
Drop explicit foregroundColor from the status item attributed string
so NSStatusBarButton can apply native inactive-screen dimming.

Fixes #170
2026-04-28 14:54:15 +02:00
AgentSeal
dbde5cb52a Release 0.9.3: Gemini CLI, Kiro, Copilot VS Code, Cursor lookback fix
Some checks are pending
CI / semgrep (push) Waiting to run
2026-04-28 05:14:56 +02:00
Resham Joshi
383df90c93
Fix Cursor provider dropping data older than 35 days (#169)
Increase lookback from 35 to 180 days so longer period views
(30-day, month, all) show accurate totals.

Fixes #159, fixes #163
2026-04-27 20:02:06 -07:00
Resham Joshi
6d15ea43a5
Add Gemini CLI provider for session tracking (#168)
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
2026-04-27 19:48:25 -07:00
Resham Joshi
f7f64a01ab
Add new providers, fix menubar tabs, accent color picker (#167)
* 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
2026-04-27 19:46:30 -07:00
Resham Joshi
5d1b335c0a
Fix Copilot provider to read VS Code workspace transcripts (#165)
The Copilot provider only looked in ~/.copilot/session-state/ which is
from an older CLI tool. VS Code Copilot agent stores transcripts in
~/Library/Application Support/Code/User/workspaceStorage/*/GitHub.copilot-chat/transcripts/.

The new transcript format has no outputTokens or model_change events,
so tokens are estimated from content length and the model is inferred
from tool call ID prefixes. Both legacy and VS Code paths are now
scanned in parallel.

Fixes #161
2026-04-27 19:44:35 -07:00
AgentSeal
314ef7a505 Release 0.9.2: fix Cursor cost tracking for v3 format and NULL timestamps
Some checks are pending
CI / semgrep (push) Waiting to run
2026-04-28 00:38:29 +02:00
Resham Joshi
30fd165b0c
Merge pull request #164 from getagentseal/fix/cursor-cost-tracking
Fix Cursor provider reporting $0 for v3 bubbles and NULL createdAt rows
2026-04-27 15:37:28 -07:00
AgentSeal
410fad9495 Fix Cursor provider reporting $0 for v3 bubble format and NULL createdAt rows
Cursor v3 stores zero token counts in bubbles, causing parseBubbles to
return empty results. The query also dropped rows with NULL createdAt
via the SQL comparison, hiding data from older Cursor versions too.

Changes:
- Remove inputTokens > 0 SQL filter, estimate tokens from text length
  when token counts are zero (same 4 chars/token ratio as agentKv)
- Include NULL createdAt rows with OR IS NULL, fall back to current
  timestamp when createdAt is missing
- Parse agentKv entries with plain string content instead of skipping
  them (not all content is a JSON array)
- Always parse both bubbles and agentKv instead of agentKv-only fallback
- Discover subagent transcripts in subagents/ subdirectories
- Fix timezone-dependent test in day-aggregator

Fixes #159, #163
2026-04-28 00:35:51 +02:00
AgentSeal
37a54081b2 Release 0.9.1: yield command
Some checks failed
CI / semgrep (push) Has been cancelled
Adds `codeburn yield` to track which AI sessions shipped to main vs were reverted or abandoned.
2026-04-25 17:11:37 +02:00
AgentSeal
54c035f5aa docs: add yield command to README
Some checks are pending
CI / semgrep (push) Waiting to run
2026-04-25 14:17:50 +02:00
AgentSeal
6eb9ba0a3b chore: clean up yield.ts - remove redundant comments and dead code 2026-04-25 14:04:16 +02:00
iamtoruk
1c5ca45bd8 Add experimental yield command to track productive vs wasted spend
New command: codeburn yield --period <period>

Correlates AI sessions with git commits to categorize spend:
- Productive: sessions with nearby commits that made it to main
- Reverted: sessions with commits that were reverted
- Abandoned: sessions with no commits or not in main

Uses timestamp proximity heuristic (session time + 1 hour window).
Works across branches, squash merges, and rebases by checking
if commits are in main branch ancestry.

Closes #152
2026-04-25 13:47:07 +02:00
iamtoruk
155b4a0708 Fix README: correct defaults domain and clarify menubar shows today 2026-04-25 13:09:23 +02:00
iamtoruk
e2254e9237 Revert AgentTabStrip to original todayPayload behavior
Some checks are pending
CI / semgrep (push) Waiting to run
2026-04-25 01:59:51 +02:00
AgentSeal
d7c92225e5 Revert "Fix trend chart to show days matching selected period"
This reverts commit c10484fe2b.
2026-04-25 01:56:51 +02:00
iamtoruk
c10484fe2b Fix trend chart to show days matching selected period 2026-04-25 01:47:30 +02:00
iamtoruk
8ffbffcd7f Fix double-counting in menubar-json period data
PR #136 (2e5e449) changed parseAllSessions to use periodInfo.range
(full period) instead of just today's range. When combined with
cached historical data, this caused days to be counted twice:
- Once from getDaysInRange(cache, ...)
- Again from parseAllSessions(periodInfo.range, ...)

Result: 7-day cost showed ~$402 instead of correct ~$209.

Fix: Parse only today's sessions when using cache path. Historical
data comes exclusively from cache, today's data from fresh parse.
2026-04-25 01:44:02 +02:00
iamtoruk
bfcae0f84e Fix provider tabs showing wrong costs when period changes
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).
2026-04-25 01:34:10 +02:00
Resham Joshi
d54e88fdbb
Merge pull request #150 from getagentseal/release/0.9.0
Some checks are pending
CI / semgrep (push) Waiting to run
Release 0.9.0
2026-04-24 11:25:25 -07:00
AgentSeal
ed7d76567b Release 0.9.0: Cursor Composer 2 support and provider fixes
- Fix cursor-agent provider to detect Composer 2 JSONL sessions (#142)
- Bump version to 0.9.0
- Update changelog with all 0.9.0 changes
2026-04-24 20:24:49 +02:00
Resham Joshi
0bebe6e5d0
Merge pull request #149 from getagentseal/fix/compare-bar-colors
Fix compare chart bar colors to always match legend
2026-04-24 11:18:57 -07:00
AgentSeal
752aaf04c1 Fix compare chart bar colors to always match legend
Bars now always show their assigned colors (blue for model A, green
for model B) instead of graying out the non-winner. Only the winner's
percentage value is highlighted in green.
2026-04-24 20:18:33 +02:00