Add a '30 Days' section to the menubar format output, positioned between
'7 Days' and 'Month' to match the tab order in the interactive report.
The rolling 30-day date range logic already existed (used by report and
export commands) - this wires it into the status menubar renderer.
Both 30 Days (rolling window) and Month (calendar month) are shown,
giving useful context early in the month when the calendar month total
is nearly empty.
Codex Desktop on Windows uses "Codex Desktop" as the originator
string instead of "codex_cli" or "codex_vscode". The startsWith
check was case-sensitive, rejecting these sessions silently.
Fixes#1 (comment by @JiglioNero).
Reads session data from OpenCode's SQLite databases at
~/.local/share/opencode/. Reuses the existing better-sqlite3
adapter (same as Cursor), lazy-loaded so users without OpenCode
see no difference. Adds bashCommands to the provider interface
so shell command breakdowns work across all providers.
31 tests, schema validation, diagnostic stderr on failures.
Also fixes a pre-existing tsc error in currency.ts.
Major release adding Cursor as the third supported provider.
Lazy-loaded SQLite, file-based result cache, provider-specific
dashboard layouts, debounced period switching, broader classifier.
- Cursor listed as supported provider with data location and caveats
- Auto mode pricing estimation explained
- Languages panel and cache behavior documented
- Project structure updated with new files
- Repo description and topics updated on GitHub
120 days was for testing. Max dashboard period is 30 days, so
Cursor SQL lookback is now 35 days (30 + margin for This Month).
Smaller scan window = faster cold starts, smaller cache file.
First run parses the 21GB DB (slow, ~40-80s). Writes parsed
results to ~/.cache/codeburn/cursor-results.json. Subsequent
runs check DB mtime+size -- if unchanged, load from cache
(instant). Cache auto-invalidates when Cursor modifies the DB.
- Fetch actual user messages (type 1 bubbles) for keyword classification
instead of using assistant response text
- Synthetic Edit tool when codeBlocks present so classifier detects coding
- Languages use lang: prefix to separate from tool classification
- Dashboard filters lang: entries for Languages panel, hides from Core Tools
- Extract user text from bubbles for activity classifier
- Extract codeBlocks languageId for programming language breakdown
- Show Languages panel instead of Core Tools/Shell/MCP for Cursor
- Adaptive dashboard layout based on active provider
- 120-day daily activity range for longer periods
The incremental cache saved a timestamp watermark but not the parsed
data, so subsequent runs found no new entries and returned empty.
Removed the cache layer entirely -- the 120-day SQL time filter
already limits the scan sufficiently.
Cursor stores createdAt as ISO strings ('2026-02-23T06:00:51.123Z'),
not numeric timestamps. Was comparing string against number, so all
rows were filtered out. Now uses ISO string comparison throughout.
Arrow keys now wait 600ms before loading data, so quickly
scrolling through periods (7d -> 30d -> 90d) skips intermediate
loads. Number keys (1-5) still load immediately.
Cursor module (sqlite.ts, better-sqlite3) now only loads when
cursor provider is actually requested. Claude/Codex startup
is unaffected -- cursor import never happens unless needed.
The dashboard was pre-loading data for ALL detected providers
on startup, causing unnecessary SQLite scans when Cursor was
detected. Now only loads data for the active provider.
Instead of scanning all 300K+ rows on every load, only query
entries from the last 90 days. Eliminates the full table scan
that caused slow provider switching on large databases.
Reads token usage from Cursor's local state.vscdb database.
Supports per-request input/output tokens, model tracking,
and incremental caching for large databases.
- better-sqlite3 as optionalDependency (lazy-loaded, no impact on Claude/Codex)
- Parameterized SQL queries, read-only mode, per-row error handling
- Schema detection with clear error on format changes
- Cache layer with timestamp watermark for incremental reads
- Provider colors and [p] key cycling in dashboard
- 39 tests passing, zero regressions
The two menubar action items were built as `bash -c "cd ~/codeburn &&
npx tsx src/cli.ts ..."`, which:
1. assumes a `~/codeburn` source checkout that npm-installed users
don't have, and
2. interacts badly with how SwiftBar serialises `param2=` on long
quoted strings — only the `cd` half ends up reaching `bash -c`,
so the `npx tsx` fallback runs from `$HOME` and fails with
`ERR_MODULE_NOT_FOUND: /Users/<u>/src/cli.ts`.
Replace with the resolved `${bin}` plus separate `paramN=` args,
which SwiftBar/xbar deliver as discrete argv entries — no shell
quoting, no checkout assumption.
While here, fix the currency submenu the same way: the items were
emitting `${bin} config currency XXX`, but the real CLI subcommand
defined in `src/cli.ts` is `codeburn currency [code]` (with
`--reset` for USD). The previous form silently failed on click.
That's #27.
Closes#32Closes#27
Verified by running `npm run build` (clean) + `npm test -- --run`
(28/28 pass), and inspecting the rendered output of `codeburn status
--format menubar` to confirm the action lines now look like:
Open Full Report | terminal=true shell=<bin> param1=report
Export CSV to Desktop | terminal=false shell=<bin> param1=export param2=-o param3=<HOME>/Desktop/codeburn-report.csv
--US Dollar (USD) * | terminal=false refresh=true shell=<bin> param1=currency param2=--reset
--British Pound (GBP) | terminal=false refresh=true shell=<bin> param1=currency param2=GBP
- Remove agent-*.jsonl exclusion filter that was dropping ~46% of API calls
- Scan subagents/ directories for subagent session files
- Normalize Codex token semantics: OpenAI includes cached tokens inside
input_tokens, subtract them to match Anthropic's separate reporting
- Fixes cost double-counting and 100% cache hit display for Codex users