Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
f5b0ac5
Replace osascript/JXA with native Mach-O agent and SMAppService to fi…
May 11, 2026
1149ab6
Fix menubar wake recovery and release asset selection
iamtoruk May 11, 2026
2301577
Merge pull request #310 from getagentseal/fix/menubar-wake-recovery
AgentSeal May 11, 2026
ce0e1eb
Make menubar refresh now reset stale state
iamtoruk May 11, 2026
33649e0
Refresh live quota progress from menubar
iamtoruk May 11, 2026
469d956
Preserve menubar bundle seal during install
iamtoruk May 11, 2026
cd8c646
Merge pull request #311 from getagentseal/fix/menubar-manual-refresh-…
AgentSeal May 11, 2026
4737bfb
Contribution rules: require real-data testing for new providers, one …
iamtoruk May 12, 2026
03e22ec
Add IBM Bob provider with workspace extraction (#316)
AgentSeal May 12, 2026
c85beea
Fix Claude 1-hour cache write pricing (#317)
AgentSeal May 12, 2026
a1b5e4b
Fix OpenCode MCP usage reporting (#318)
AgentSeal May 12, 2026
38e41e9
Add Node version guard for unsupported runtimes (#319)
iamtoruk May 12, 2026
3b71650
Fix mangled project paths in dashboard (#320)
iamtoruk May 12, 2026
fe2e622
Skip Cursor bubble rows that lack a createdAt timestamp (#321)
iamtoruk May 12, 2026
f9a5d2c
Add changelog entries for project path fix and Cursor undated bubbles
iamtoruk May 12, 2026
151d24f
Drop Z suffix from day-aggregator test timestamps for timezone stabil…
iamtoruk May 12, 2026
ab87b61
Fix menubar showing empty data after reboot when CLI is installed via…
rashidrazak May 13, 2026
f663ec0
Replace osascript/JXA with native Mach-O agent and SMAppService to fi…
May 11, 2026
4376571
Fix menubar showing empty data after reboot when CLI is installed via…
rashidrazak May 13, 2026
b1622b3
Merge branch 'fix/menubar-edr-detection-fix' of github.com:rashidraza…
rashidrazak May 13, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
## Summary

<!-- What does this PR do? 1-3 bullet points. -->

## Testing

- [ ] I have tested this locally against real data (not just unit tests)
- [ ] `npm test` passes
- [ ] `npm run build` succeeds

### For new providers only:

- [ ] I installed the tool and generated real sessions by using it
- [ ] `npm run dev -- today` shows correct costs and session counts for this provider
- [ ] `npm run dev -- models --provider <name>` shows correct model names and pricing
- [ ] Screenshot or terminal output attached below proving it works with real data

<!-- Paste screenshot / terminal output here -->
8 changes: 5 additions & 3 deletions .github/workflows/release-menubar.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@ jobs:
uses: actions/upload-artifact@v4
with:
name: CodeBurnMenubar-${{ steps.version.outputs.value }}
path: mac/.build/dist/CodeBurnMenubar-*.zip
path: |
mac/.build/dist/CodeBurnMenubar-${{ steps.version.outputs.value }}.zip
mac/.build/dist/CodeBurnMenubar-${{ steps.version.outputs.value }}.zip.sha256
if-no-files-found: error

- name: Create / update GitHub Release
Expand All @@ -66,6 +68,6 @@ jobs:
and macOS shows "cannot verify developer", right-click the app in Finder and
pick Open to whitelist it once.
files: |
mac/.build/dist/CodeBurnMenubar-*.zip
mac/.build/dist/CodeBurnMenubar-*.zip.sha256
mac/.build/dist/CodeBurnMenubar-${{ steps.version.outputs.value }}.zip
mac/.build/dist/CodeBurnMenubar-${{ steps.version.outputs.value }}.zip.sha256
fail_on_unmatched_files: true
23 changes: 23 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,28 @@
# Changelog

## Unreleased

### Added (CLI)
- **IBM Bob provider.** Discovers IBM Bob IDE task history, reuses the
Cline-family parser for token/cost records, extracts model tags and
workspace-based project names from session data. Closes #248.

### Fixed (CLI)
- **Claude 1-hour cache write pricing.** 1-hour cache writes are now priced
at 2x base input (previously used the 5-minute 1.25x rate for all writes).
Daily cache bumped to v6 so stale totals are recomputed. Closes #276.
- **OpenCode MCP usage now counted.** OpenCode stores MCP tool calls as
`<server>_<tool>` names, which the shared MCP pipeline did not recognize.
The provider now normalizes these to the canonical `mcp__<server>__<tool>`
form so MCP breakdowns and `optimize` work correctly. Closes #308.
- **Mangled project names in dashboard.** The By Project and Top Sessions
panels decoded slugs by splitting on `-`, which broke directory names
containing dashes or dots (e.g. `my-project` rendered as `my/project`).
Now uses the real project path instead. Closes #196.
- **Cursor undated bubble rows misattributed to Today.** Bubble rows without
a `createdAt` timestamp were defaulting to the current date, inflating
Today's spend. Now skipped at both the SQL and application level.

## 0.9.8 - 2026-05-10

### Added (CLI)
Expand Down
17 changes: 17 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,23 @@ The `.github/workflows/block-claude-coauthor.yml` workflow rejects any PR whose

If a flagged PR rejects on this check, the workflow prints the exact rebase command to fix it.

## Before You Start

**Comment on the issue first.** Before writing code for a feature or new provider, leave a comment on the relevant issue saying what you plan to do. Wait for a maintainer to confirm the approach. Unsolicited PRs that duplicate work already in progress or take an incompatible approach will be closed.

**One PR at a time.** We will not review a second PR from you until the first is merged or closed. This keeps the review queue manageable and ensures each contribution gets proper attention.

## Adding a New Provider

New providers have the highest bar because broken parsing silently produces wrong data for users. Before opening a PR:

1. **Install the tool and use it.** Generate real sessions by actually coding with the provider. We do this ourselves for every provider we ship.
2. **Test against real data.** Run `npm run dev -- today` and `npm run dev -- models` with your real sessions and confirm the output looks correct — costs are non-zero, model names resolve, session counts match what you see in the tool.
3. **Include proof in the PR.** Attach a screenshot or terminal output showing codeburn correctly parsing your real sessions. PRs for new providers without evidence of local testing will not be reviewed.
4. **Do not rely on AI-generated guesses about storage paths or schemas.** Tools change their data formats between versions. The only way to know the current schema is to install the tool and inspect the actual files on disk.

PRs that add a provider based solely on online documentation or AI-generated code, without evidence of testing against real data, will be closed.

## Pull Requests

1. Fork or branch from `main`.
Expand Down
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<a href="https://github.com/sponsors/iamtoruk"><img src="https://img.shields.io/badge/sponsor-♥-ea4aaa?logo=github" alt="Sponsor" /></a>
</p>

CodeBurn tracks token usage, cost, and performance across **18 AI coding tools**. It breaks down spending by task type, model, tool, project, and provider so you can see exactly where your budget goes.
CodeBurn tracks token usage, cost, and performance across **19 AI coding tools**. It breaks down spending by task type, model, tool, project, and provider so you can see exactly where your budget goes.

Everything runs locally. No wrapper, no proxy, no API keys. CodeBurn reads session data directly from disk and prices every call using [LiteLLM](https://github.com/BerriAI/litellm).

Expand Down Expand Up @@ -104,6 +104,7 @@ Arrow keys switch between Today, 7 Days, 30 Days, Month, and 6 Months (use `--fr
| <img src="assets/providers/cursor-agent.jpg" width="28" /> | cursor-agent | Yes | [cursor-agent.md](docs/providers/cursor-agent.md) |
| <img src="assets/providers/gemini.png" width="28" /> | Gemini CLI | Yes | [gemini.md](docs/providers/gemini.md) |
| <img src="assets/providers/copilot.jpg" width="28" /> | GitHub Copilot | Yes | [copilot.md](docs/providers/copilot.md) |
| <img src="assets/providers/ibm-bob.svg" width="28" /> | IBM Bob | Yes | [ibm-bob.md](docs/providers/ibm-bob.md) |
| <img src="assets/providers/kiro.png" width="28" /> | Kiro | Yes | [kiro.md](docs/providers/kiro.md) |
| <img src="assets/providers/opencode.png" width="28" /> | OpenCode | Yes | [opencode.md](docs/providers/opencode.md) |
| <img src="assets/providers/openclaw.jpg" width="28" /> | OpenClaw | Yes | [openclaw.md](docs/providers/openclaw.md) |
Expand All @@ -119,7 +120,7 @@ Arrow keys switch between Today, 7 Days, 30 Days, Month, and 6 Months (use `--fr

Each provider doc lists the exact data location, storage format, and known quirks. Linux and Windows paths are detected automatically. If a path has changed or is wrong, please [open an issue](https://github.com/getagentseal/codeburn/issues).

Provider logos are trademarks of their respective owners. The icon set was sourced from [tokscale](https://github.com/junhoyeo/tokscale) (MIT) plus official vendor assets, used under nominative fair use for the purpose of identifying supported tools.
Provider logos are trademarks of their respective owners. The icon set was sourced from [tokscale](https://github.com/junhoyeo/tokscale) (MIT), official vendor assets, and simple provider identifiers, used under nominative fair use for the purpose of identifying supported tools.

CodeBurn auto-detects which AI coding tools you use. If multiple providers have session data on disk, press `p` in the dashboard to toggle between them.

Expand Down Expand Up @@ -378,6 +379,8 @@ These are starting points, not verdicts. A 60% cache hit on a single experimenta

**OpenClaw** stores agent sessions as JSONL at `~/.openclaw/agents/*.jsonl`. Also checks legacy paths `.clawdbot`, `.moltbot`, `.moldbot`. Token usage comes from assistant message `usage` blocks; model from `modelId` or `message.model` fields.

**IBM Bob** stores IDE task history in `User/globalStorage/ibm.bob-code/tasks/<task-id>/` under the IBM Bob application data directory. CodeBurn reads `ui_messages.json` for API request token/cost records and `api_conversation_history.json` for the selected model, with support for both GA (`IBM Bob`) and preview (`Bob-IDE`) app data folders.

**Roo Code / KiloCode** are Cline-family VS Code extensions. CodeBurn reads `ui_messages.json` from each task directory in VS Code's `globalStorage`, filtering `type: "say"` entries with `say: "api_req_started"` to extract token counts.

CodeBurn deduplicates messages (by API message ID for Claude, by cumulative token cross-check for Codex, by conversation/timestamp for Cursor, by session ID for Gemini, by session+message ID for OpenCode, by responseId for Pi/OMP), filters by date range per entry, and classifies each turn.
Expand Down
6 changes: 6 additions & 0 deletions assets/providers/ibm-bob.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 3 additions & 3 deletions docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,14 +128,14 @@ type Provider = {
}
```

`src/providers/index.ts` registers eighteen providers across two tiers:
`src/providers/index.ts` registers nineteen providers across two tiers:

- **Eager**: `claude`, `codex`, `copilot`, `droid`, `gemini`, `kilo-code`, `kiro`, `openclaw`, `pi`, `omp`, `qwen`, `roo-code`. Imported at module load.
- **Eager**: `claude`, `codex`, `copilot`, `droid`, `gemini`, `ibm-bob`, `kilo-code`, `kiro`, `openclaw`, `pi`, `omp`, `qwen`, `roo-code`. Imported at module load.
- **Lazy**: `antigravity`, `goose`, `cursor`, `opencode`, `cursor-agent`, `crush`. Imported via dynamic `import()` so the heavy dependencies (SQLite, protobuf) do not touch users who do not have those tools installed.

Both lists hit the same `getAllProviders()` aggregator. A failed lazy import is silent and excludes that provider from the run.

`src/providers/vscode-cline-parser.ts` is a shared helper consumed by `kilo-code` and `roo-code`. It is not registered as a provider on its own.
`src/providers/vscode-cline-parser.ts` is a shared helper consumed by `ibm-bob`, `kilo-code`, and `roo-code`. It is not registered as a provider on its own.

For the per-provider data location, storage format, parser quirks, and test coverage, see `docs/providers/`.

Expand Down
3 changes: 2 additions & 1 deletion docs/providers/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ For the architectural picture, see `../architecture.md`.
| [Copilot](copilot.md) | JSONL | `src/providers/copilot.ts` | `tests/providers/copilot.test.ts` |
| [Droid](droid.md) | JSONL | `src/providers/droid.ts` | `tests/providers/droid.test.ts` |
| [Gemini](gemini.md) | JSON / JSONL | `src/providers/gemini.ts` | none |
| [IBM Bob](ibm-bob.md) | JSON | `src/providers/ibm-bob.ts` | `tests/providers/ibm-bob.test.ts` |
| [KiloCode](kilo-code.md) | JSON | `src/providers/kilo-code.ts` | `tests/providers/kilo-code.test.ts` |
| [Kiro](kiro.md) | JSON | `src/providers/kiro.ts` | `tests/providers/kiro.test.ts` |
| [OpenClaw](openclaw.md) | JSONL | `src/providers/openclaw.ts` | `tests/providers/openclaw.test.ts` |
Expand All @@ -38,7 +39,7 @@ For the architectural picture, see `../architecture.md`.

| Helper | Used by | Source |
|---|---|---|
| [vscode-cline-parser](vscode-cline-parser.md) | `kilo-code`, `roo-code` | `src/providers/vscode-cline-parser.ts` |
| [vscode-cline-parser](vscode-cline-parser.md) | `ibm-bob`, `kilo-code`, `roo-code` | `src/providers/vscode-cline-parser.ts` |

## File Format

Expand Down
11 changes: 11 additions & 0 deletions docs/providers/claude.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,17 @@ JSONL, one event per line, per session file. Sessions live under `<project>/<ses

`createSessionParser` returns an empty async generator (`claude.ts:101-105`). Claude is a special case: `src/parser.ts` reads Claude JSONL files directly with full turn grouping, dedup of streaming message IDs, and MCP tool inventory extraction. The provider object exists only so `discoverSessions` can return Claude session sources alongside the others.

## Pricing

Claude Code reports total cache-write tokens in `usage.cache_creation_input_tokens`.
When available, it also splits those writes by duration in
`usage.cache_creation.ephemeral_5m_input_tokens` and
`usage.cache_creation.ephemeral_1h_input_tokens`. CodeBurn keeps the existing
aggregate cache-write token total for reports, but prices the 1-hour portion at
2x base input cost (1.6x the 5-minute cache-write rate exposed by LiteLLM).
If the split fields are missing, the parser falls back to the legacy behavior
and prices every cache write at the 5-minute rate.

## Caching

None at the provider level. The daily aggregation cache (`src/daily-cache.ts`) reuses prior computed days.
Expand Down
55 changes: 55 additions & 0 deletions docs/providers/ibm-bob.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# IBM Bob

IBM Bob IDE task history.

- **Source:** `src/providers/ibm-bob.ts`
- **Loading:** eager (`src/providers/index.ts`)
- **Test:** `tests/providers/ibm-bob.test.ts`

## Where It Reads From

IBM Bob stores IDE task history below `User/globalStorage/ibm.bob-code/tasks/` in the application data directory.

Default paths checked:

| Platform | Paths |
|---|---|
| macOS | `~/Library/Application Support/IBM Bob/User/globalStorage/ibm.bob-code/`, `~/Library/Application Support/Bob-IDE/User/globalStorage/ibm.bob-code/` |
| Windows | `%APPDATA%/IBM Bob/User/globalStorage/ibm.bob-code/`, `%APPDATA%/Bob-IDE/User/globalStorage/ibm.bob-code/` |
| Linux | `$XDG_CONFIG_HOME/IBM Bob/User/globalStorage/ibm.bob-code/`, `$XDG_CONFIG_HOME/Bob-IDE/User/globalStorage/ibm.bob-code/` with `~/.config` fallback |

The `Bob-IDE` paths cover the preview-era app name that some installs used before the GA `IBM Bob` directory.

## Storage Format

Each task is a directory under `tasks/<task-id>/` and must contain `ui_messages.json`.

CodeBurn parses the same Cline-family UI event format used by Roo Code and KiloCode:

- `ui_messages.json` entries with `type: "say"` and `say: "api_req_started"` contain serialized token/cost metrics.
- `ui_messages.json` user text entries seed the turn's first user message.
- `api_conversation_history.json` is optional and is used to extract the selected model from `<model>...</model>` environment details when present.
- `task_metadata.json` may exist upstream, but CodeBurn does not need it for usage math today.

If no model tag is present, the parser uses `ibm-bob-auto`, which is priced through the same conservative Sonnet fallback used for Cline-family auto modes.

## Caching

None at the provider level.

## Deduplication

Per `<providerName>:<taskId>:<apiRequestIndex>` via `vscode-cline-parser.ts`.

## Quirks

- IBM Bob has shipped under both `IBM Bob` and `Bob-IDE` application data folder names.
- This provider intentionally covers the IDE task-history format. Bob Shell's `~/.bob` checkpoint data is a separate storage surface and is not parsed until we have a stable usage schema fixture.
- The shared Cline parser does not currently extract individual tool names from UI messages, so tool breakdowns are empty for IBM Bob just like Roo Code and KiloCode.

## When Fixing A Bug Here

1. Check whether the install uses `IBM Bob` or `Bob-IDE` as the application data directory.
2. Confirm the task folder still contains `ui_messages.json` and `api_conversation_history.json`.
3. If the UI message schema changed, add a focused fixture to `tests/providers/ibm-bob.test.ts`.
4. If the change also affects Roo Code or KiloCode, update `src/providers/vscode-cline-parser.ts` and run all three provider test files.
14 changes: 9 additions & 5 deletions docs/providers/opencode.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ OpenCode (sst/opencode).

- **Source:** `src/providers/opencode.ts`
- **Loading:** lazy (`src/providers/index.ts:59-75`)
- **Test:** `tests/providers/opencode.test.ts` (558 lines, the largest provider test)
- **Test:** `tests/providers/opencode.test.ts` (676 lines, the largest provider test)

## Where it reads from

Expand All @@ -20,14 +20,18 @@ None.

## Deduplication

Per `<sessionId>:<messageId>` (`opencode.ts:242`).
Per `<sessionId>:<messageId>`.

## Quirks

- **Schema validation is loud.** When a required table is missing, the parser logs an actionable warning telling the user which table is gone and what version of OpenCode it expects (`opencode.ts:104-131`). This is the right behavior; do not silently swallow these.
- Source paths are encoded as `<dbPath>:<sessionId>` (`opencode.ts:147-150`).
- Each message's `parts` are indexed (`opencode.ts:177-191`); preserving the order matters for reasoning-token correctness.
- **Schema validation is loud.** When a required table is missing, the parser logs an actionable warning telling the user which table is gone and what version of OpenCode it expects. This is the right behavior; do not silently swallow these.
- Source paths are encoded as `<dbPath>:<sessionId>`.
- Each message's `parts` are indexed; preserving the order matters for reasoning-token correctness.
- Tokens are reported across `input`, `output`, `reasoning`, `cache.read`, and `cache.write`. Anthropic semantics.
- External MCP tools are stored as `<server>_<tool>` names (for example
`clickup_clickup_get_task`). The provider normalizes those to CodeBurn's
canonical `mcp__<server>__<tool>` names before aggregation so shared MCP
panels and `optimize` findings count OpenCode usage.

## When fixing a bug here

Expand Down
Loading