co2-tracker — плагин для Claude Code: учёт CO2 сессий
Считает углеродный след ваших сессий Claude Code локально по расходу токенов и показывает оценку CO2 прямо в статусной строке.
/plugin marketplace add anthropics/claude-plugins-community
/plugin install co2-tracker@claude-communityЧто делает co2-tracker
Плагин добавляет живую оценку выбросов CO2 в статусную строку Claude Code и подсказку под промптом в приложении Claude для десктопа, рядом с API-эквивалентом стоимости сессии. Расчёт идёт локально из вашего расхода токенов, коэффициенты взяты из рецензируемой работы Jegham et al. 2025.
Каждая сессия сохраняется в локальную базу SQLite, поэтому история переживает 30-дневную очистку транскриптов. Есть команды /carbon-report (текстовый отчёт), /carbon-card (PNG-карточка) и /carbon-pr (след пул-реквеста), а в десктопном приложении /carbon-panel открывает панель с молекулой, статистикой за выбранный период и полосами потепления.
Установщик проверяет зависимости: на macOS ему нужен git, а также jq и sqlite3 — без них установка остановится с сообщением о нехватке пакета. На Windows требуется Git for Windows, иначе Claude Code не запустит сессию. Вкладки Chat и Cowork не покрываются: их сессии идут на серверах Anthropic, и на вашу машину ничего не попадает.
Какие задачи решает
- увидеть расход CO2 текущей сессии прямо в терминале
- сохранить историю сессий дольше 30 дней
- собрать PNG-карточку с итогами за период
- оценить след отдельного пул-реквеста
- подтянуть статистику из старых транскриптов
~/.claude
Примеры запросов агенту
- Покажи отчёт по выбросам за последние 30 дней через
/carbon-report - Сделай PNG-карточку с моим углеродным следом:
/carbon-card - Открой панель с молекулой CO2 этой сессии:
/carbon-panel
Как установить co2-tracker
Через маркетплейс плагинов
/plugin marketplace add anthropics/claude-plugins-community/plugin install co2-tracker@claude-communityПо шагам, с командами для каждой платформы: Плагины Claude Code: маркетплейсы, установка и как собрать свой
Вопросы о co2-tracker
Как установить co2-tracker в Claude Code?
Через маркетплейс плагинов: сначала выполните /plugin marketplace add anthropics/claude-plugins-community, затем /plugin install co2-tracker@claude-community.
Что делает co2-tracker?
Считает локально оценку CO2 по расходу токенов и выводит её в статусной строке Claude Code. Сессии пишутся в локальную SQLite, есть команды для текстового отчёта, PNG-карточки и следа пул-реквеста.
Что нужно для работы co2-tracker?
На macOS и Linux установщику нужны git, jq и sqlite3. На Windows требуется Git for Windows и два пакета, которые ставит сам установщик.
Исходный текст
SKILL.md · MIT
<p><img src="docs/banner.png" width="100%" alt="claude-carbon, free and open source: the CO2 of your Claude Code sessions, in the terminal and in the Claude app. Eight pixel molecules from dark blue to dark red, a terminal whose status line reads 8.2gCO2, and the /carbon-panel pane: this session's molecule and CO2, the last 30 days as tiles and warming stripes, a button for the yearly card"></p>
[](https://github.com/gwittebolle/claude-carbon/stargazers)
[](LICENSE)
[](https://github.com/gwittebolle/claude-carbon/releases)
[](https://www.npmjs.com/package/claude-carbon)
[](https://github.com/gwittebolle/claude-carbon/actions/workflows/ci.yml)
claude-carbon is an open source Claude Code plugin that tracks the carbon footprint of your sessions: a live CO2 estimate computed locally from your token usage, in the terminal status line and in the Code tab of the Claude desktop app, next to the session's API-equivalent cost. In the desktop app, `/carbon-panel` opens a pane with a pixel molecule coloured by this session's CO2 against the median of your past sessions, your usage over the period you pick, its warming stripes, and a button for your yearly card.
<p align="center"><img src="https://github.com/user-attachments/assets/f52b2653-28b9-4efc-82a6-02dfe256e193" width="480" alt="claude-carbon in 16 seconds: Claude Code never shows its CO2; claude-carbon puts it in the terminal status line, then in the Claude desktop app, where /carbon-panel opens a pane with a pixel molecule coloured by this session's CO2 against the median of your past sessions"></p>
## What claude-carbon does
- `/carbon-panel`: a pane in the Claude desktop app with your CO2 molecule, your usage and the warming stripes of your sessions (in a terminal, the session in the band above the prompt). See [the mod](#the-mod-carbon-panel-and-the-co2-of-each-answer)
- Adds a live CO2 estimate to the Claude Code status line, and the session's CO2 under the prompt in the Claude desktop app, each next to the session's API-equivalent cost
- Persists each session to a local SQLite database, so history survives the 30-day transcript purge
- Backfills historical data from existing `~/.claude` transcripts
- Slash commands: `/carbon-report` (text), `/carbon-card` (PNG), `/carbon-pr` (footprint of a pull request)
- A README badge with your all-time total, and a public methodology with every factor sourced
> **About the `$` figure.** It is an API equivalent: what your session would cost at Anthropic's pay-as-you-go API list prices. On a Pro or Max subscription you do not pay it; it shows the value of what you used, next to its CO2. See [How it works](#how-it-works).
## Install
Two ways, same result. Pick the one that fits you:
- **Not a developer, or you use the Claude desktop app:** [let Claude install it for you](#option-1-from-the-claude-desktop-app-no-terminal). No terminal, one message to paste.
- **Developer, at ease in a terminal:** [one command](#option-2-from-a-terminal-developers).
Already installed? See [Updating](#updating).
### Option 1: from the Claude desktop app (no terminal)

1. Open the **Code** tab of the Claude desktop app and start a session, in any folder. In the mode selector under the prompt box, pick **Manual** if it shows **Auto**: auto mode blocks any command that downloads a script and runs it, and Claude would hand you the command instead of running it. Switch back once the install is done.
2. Paste the message for your system. It works in any language. Claude runs the installer for you and asks before running the command: accept.
macOS or Linux:
```text
Install claude-carbon for me by running this command:
curl -fsSL https://raw.githubusercontent.com/gwittebolle/claude-carbon/main/install.sh | bash
```
Windows:
```text
Install claude-carbon for me by running this command in PowerShell:
irm https://raw.githubusercontent.com/gwittebolle/claude-carbon/main/install.ps1 | iex
```
3. Quit the desktop app completely, open it again, and start a new session in the Code tab. Under the prompt you now see `This session: 3.6 gCO₂ · $0.12` (`Cette session : 3,6 gCO₂ · 0,12 $` in French). `/carbon-report` and `/carbon-card` work from there too.
The `$` is an API-equivalent cost, not what your subscription bills.
**If the install stops**
- **macOS opens a window about "command line developer tools".** That is `git`, which the installer needs and a Mac without developer tools does not have yet. Click **Install**, wait until it finishes (a few minutes), then tell Claude: "Run the claude-carbon install again."
- **"jq is not installed" or "sqlite3 is not installed".** Tell Claude: "Install what is missing, then run the claude-carbon install again." Every Mac has `sqlite3`, and macOS 15 and later also have `jq`; on an older Mac the installer fetches the official `jq` itself, checked against its published checksum. On Windows the installer installs both with `winget` itself, and prints the `winget` commands only when that fails.
- **Windows says Git Bash is missing.** Install [Git for Windows](https://git-scm.com/downloads/win) (Claude Code needs it on Windows anyway), quit the app completely and reopen it, then ask Claude again in a new session. Claude Code looks for Git Bash when a session starts, so a session open during the Git install still runs without it.
The chat and Cowork tabs are not covered: their sessions run on Anthropic's servers, so nothing reaches your machine to count.
### Option 2: from a terminal (developers)

**1. Install (or update):**
macOS, Linux, WSL:
```bash
curl -fsSL https://raw.githubusercontent.com/gwittebolle/claude-carbon/main/install.sh | bash
```
Windows (PowerShell), which needs [Git for Windows](https://git-scm.com/downloads/win) and two packages first - see [Windows](#windows):
```powershell
irm https://raw.githubusercontent.com/gwittebolle/claude-carbon/main/install.ps1 | iex
```
Or, on any platform with Node.js:
```bash
npx claude-carbon
```
Same command to install and to update to the latest version (all three run the same installer).
> **Installed from Anthropic's community marketplace and the plugin fails to load?** The `co2-tracker@claude-community` entry is pinned to a release from August 2026 that current Claude Code rejects ("Duplicate hooks file detected"). Run `/plugin uninstall co2-tracker@claude-community`, then install with one of the commands above.
**2. Restart Claude Code.** Your CO2 appears in the status line:
```
claude-carbon ⌥ main | 🟢 Opus 5 ▓▓▓░░░░░░░ 35% | $0.50 · 65gCO₂ | Use 24% ↻13:00
```
Segments, left to right: project + git branch, model + context window %, API-equivalent session cost + CO2, 5h block usage % + reset time. A 🔥 prefix appears when the sustained burn rate would overshoot 100% of the limit by the end of the 5h block (after a 15 min grace window, only once usage reaches 15%).
> **Where the CO2 shows up.** The status line is a feature of the Claude Code terminal UI. It is displayed only when you run `claude` in a terminal, including the integrated terminal of VS Code or JetBrains. The IDE extensions' chat panel has no status line at all, so nothing is displayed there even though the hooks still run and your sessions are recorded: `/carbon-report` covers them. If you use the VS Code panel and want the live CO2, open a terminal in VS Code (`` Ctrl+` ``) and run `claude` from there. The web app (claude.ai/code) runs neither the status line nor the hooks, so nothing is displayed or recorded there. The desktop app does not display the status line either; the plugin's [mod](#the-mod-carbon-panel-and-the-co2-of-each-answer) draws the CO2 in its Code tab.
**5h quota source.** The percentage comes directly from Anthropic's `/api/oauth/usage` endpoint (the same data Claude Code displays in `/usage`). No heuristic, no token-limit file to seed. Two sources in order:
1. **stdin** (preferred): if Claude Code injects `rate_limits.five_hour.used_percentage` in the statusline JSON, that value is used straight away.
2. **OAuth API fallback**: `GET https://api.anthropic.com/api/oauth/usage` with the bearer token from macOS Keychain, `CLAUDE_CODE_OAUTH_TOKEN`, or `~/.claude/.credentials.json`. Cached 60s in `~/.claude/claude-carbon/oauth-usage.json`.
Accurate on every plan, including Max 20x.
**3. Use the slash commands:**
- `/carbon-report` - text report with totals, a car equivalent, this year's share of a 2 t per-person budget, top sessions
- `/carbon-card` - generate shareable PNG report cards (drawn with the Chrome or Edge already on your machine, see [Dependencies](#dependencies); without one the card opens in your browser)
- `/carbon-update` - update to the latest version, whichever way you installed (see [Updating](#updating))
## Example report
<p align="center">
<img src="docs/example-card.png" alt="claude-carbon summary card: 1190.3 kg of estimated CO2 from January to September 2026, a bar per month, then 25.3B tokens processed, 94% of them cache reads, a car equivalent, the API-price cost and a yearly projection" width="540">
</p>
Generate yours with `/carbon-card` in Claude Code. The summary and detailed PNGs land in
`~/Downloads/claude-carbon/` (the Windows Downloads folder follows the system setting, so a
OneDrive-redirected one is honoured) and the folder opens in your file manager, with the
card selected on macOS. `CLAUDE_CARBON_EXPORT_DIR` picks another folder;
`CLAUDE_CARBON_NO_OPEN=1` skips the opening.
Without Playwright or Chromium there is no PNG and the command still finishes: the summary
card is saved as an HTML page in the same folder and opens in your browser, scaled to fit the
window, and a screenshot of it does the job.
The token count on the card is every token Claude processed, cache reads included, as `ccusage` counts them; the grey line under it gives the share of cache reads. The card's footer says where to find the tool, `claude-carbon sur GitHub` / `claude-carbon on GitHub`, with the address below it.
From the 1st to the 10th of each month the status line ends with `📊 September: 84.2kgCO₂ · /carbon-card`:
the total of the month just closed, the bar the card draws for it, in the same format as the
session figure. It is read from carbon.db once a day while the nudge shows, and kept in
`~/.claude/claude-carbon/last-month-total`. A month with fewer than 7 days of sessions gets no
nudge, so a fresh install is not pushed to share a near-empty card. Generating a card
clears it for the month; it goes quiet on its own after the 10th. `CLAUDE_CARBON_CARD_NUDGE_UNTIL_DAY`
moves the cut-off, `CLAUDE_CARBON_NO_CARD_NUDGE=1` removes the nudge. Nothing is posted anywhere:
sharing stays a human decision.
<details>
<summary>Advanced options (CLI)</summary>
```bash
# Since a specific date
bash ~/code/claude-carbon/scripts/generate-report.sh --since 2026-03-01
# All time
bash ~/code/claude-carbon/scripts/generate-report.sh --all
# A closed period (--until is an exclusive upper bound: this one stops at June 30th)
bash ~/code/claude-carbon/scripts/generate-report.sh --since 2026-01-01 --until 2026-07-01
```
</details>
<details>
<summary>Custom install directory</summary>
```bash
curl -fsSL https://raw.githubusercontent.com/gwittebolle/claude-carbon/main/install.sh | CLAUDE_CARBON_DIR=~/my-path/claude-carbon bash
```
The env var has to sit on the `bash` side of the pipe, not the `curl` side, or the installer never sees it.
</details>
<details>
<summary>Second Claude environment (CLAUDE_CONFIG_DIR)</summary>
If you run a second Claude Code environment out of its own config directory, e.g.
```bash
alias claude-work="CLAUDE_CONFIG_DIR=~/.claude-work claude"
```
install claude-carbon into that same directory by passing `CLAUDE_CONFIG_DIR` to the installer:
```bash
curl -fsSL https://raw.githubusercontent.com/gwittebolle/claude-carbon/main/install.sh | CLAUDE_CONFIG_DIR=~/.claude-work bash
```
The status line, the hooks, the database and the `/carbon-*` commands all live under that config dir, so each environment tracks its own sessions independently. When `CLAUDE_CONFIG_DIR` is unset everything falls back to `~/.claude` as before.
</details>
<details>
<summary>Manual install</summary>
```bash
git clone https://github.com/gwittebolle/claude-carbon.git ~/code/claude-carbon
bash ~/code/claude-carbon/scripts/setup.sh
bash ~/code/claude-carbon/scripts/configure-settings.sh
```
The second script merges the block below into `~/.claude/settings.json` (additively: an existing status line or third-party hooks are left alone) and symlinks the `/carbon-*` commands. To wire it by hand instead, skip it and add:
```json
{
"statusLine": {
"type": "command",
"command": "~/code/claude-carbon/scripts/statusline.sh"
},
"hooks": {
"Stop": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "~/code/claude-carbon/scripts/persist-session.sh"
}
]
}
],
"SessionEnd": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "~/code/claude-carbon/scripts/persist-on-exit.sh"
}
]
}
],
"SessionStart": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "~/code/claude-carbon/scripts/safety-rescan.sh"
}
]
}
],
"SubagentStop": [
{
"matcher": ".+",
"hooks": [
{
"type": "command",
"command": "~/code/claude-carbon/scripts/agent-stop.sh"
}
]
}
]
}
}
```
The `Stop` hook records the session after each turn, and `SessionEnd` records it once more as it closes, so a last turn interrupted before `Stop` fired is still counted. The `SessionStart` one re-scans for sessions both missed (crash, kill) and drives the daily update check the status line reads; without it you are never told a new version exists. `SubagentStop` records the branch an agent worked on, for `/carbon-pr`.
Restart Claude Code.
</details>
## For teams
claude-carbon measures one developer's sessions, locally. If the question comes from your CTO, a client RFP or a CSR committee, the same methodology exists as a hosted layer:
- [Free calculator](https://tokenclimate.com/en/calculator?ref=github) and [per-model factor sheets](https://tokenclimate.com/en/models?ref=github) - the exact versioned factors of this repo, browsable.
- [AI usage report](https://tokenclimate.com/bilan/en?ref=github) - a self-serve, shareable report of your organisation's real Claude usage (cost, CO2e, water, energy), generated in minutes from an Anthropic admin key. The key is never stored; the methodology annex is citation-ready.
- [TokenClimate](https://tokenclimate.com/en?ref=github) - hosted team dashboards. Both sides share this repo's golden vectors, verified weekly in CI.
The only places the OSS points there are a one-line footer in `/carbon-report` and a small credit on the `/carbon-card` PNGs. No status-line promo, no email capture: nothing leaves your machine.
### PR dev footprint (/carbon-pr)
The number reviewers rarely see is what the PR cost to develop: your local Claude Code sessions while building the branch. `/carbon-pr` (or `scripts/generate-pr-report.sh`) sums the recorded sessions of the current branch and posts one sticky comment on its open PR, through your own `gh` auth. Run it after your push; running it again updates the same comment in place.
```
**Claude Code carbon report** · developing this PR
124 g CO2e · $3.00 · 180k tokens · 1.5M cache reads · 2 sessions
```
How the sessions are attributed: the Stop hook stores each session's git branch (read from the transcript), and the report selects `project + branch`. Sessions recorded before this column existed carry no branch; `scripts/backfill.sh` repairs them while their transcripts are still on disk (about 30 days). A session whose last folder is a subdirectory of the repo is stored under the subdirectory's name and stays out of the sum. A session that ends on another branch than it started is attributed to where it finished.
How its agents are attributed: an agent counts with its session, unless it worked on a branch of its own. A session on `main` that sends agents to build a PR in a worktree puts their share on the PR's branch, and the comment then says how many sessions recorded elsewhere it includes. A `SubagentStop` hook (`agent-stop.sh`) reads the branch as each agent ends, while its worktree still exists:
- an agent that ran in a worktree of its own (Claude Code's isolated and workflow agents) counts on the branch that worktree has then, unless Claude Code named it (`worktree-agent-*`, `worktree-wf_*`) or it is detached;
- an agent that ran in the session's folder counts on the worktree its tool calls name in at least half of those that give a place (a command, a file path), and no other as often: absolute paths, `~/`, `../` from the repository's folder when the worktree sits beside it, `./` when it sits inside. Never the repository's main folder, nor the session's own. This one is a deduction from the agent's commands.
The hook stores that agent's tokens, CO2 and cost, per model, in an `agent_usage` table, with the repository and the worktree's folder; the session's own row does not change. The report takes those agents out of their session's branch and adds them to theirs, as long as the session's row holds all its agents (`agents_collected = 2`: the Stop hook or the rescan read every agent transcript), was written after the agent ended (in a later second) and was recorded with the current method (not a v1 row). An agent that worked in another repository than its session's is not recorded, and one recorded before its repository was moved stays with its session. Forks are left out (they replay their parent's messages), and so is the work a session does itself in a worktree. Only agents that end with this version installed are attributed: nothing is rebuilt for past sessions.
The hook needs Claude Code 2.1.69 or later, the first to give `SubagentStop` the agent's type (its id and transcript came in 2.0.42); with an older one it records nothing. Claude Code's own agents (prompt suggestions, `/btw`) are left out. In a session run without `--agent` their type is empty: the hook's matcher skips them from 2.1.275, the script itself before that. With `--agent` they carry that agent's name and pass the matcher; the script skips them because their transcript is not one the session's row reads.
The hook runs synchronously, before the agent's result reaches the session: on a Mac, about 0.1 to 0.3 s for most agents, up to about 1 to 2 s for one whose transcript passes 100 MB, since it reads that transcript whole. Claude Code writes transcripts asynchronously: when the agent's final message is not in it yet, the hook reads it again every 0.2 s, for 1 s at most, then counts what is there. A database kept busy for more than about 10 s (a long read elsewhere) loses the record, and the agent counts with its session.
Turning it off is the default: nothing is posted unless you run it. `--dry-run` previews the comment, `--pr <number>` targets a specific PR of the repository (one opened from a fork is refused: run the command from the fork's clone instead), and deleting the comment on GitHub is the full cleanup. Once agents of the repository are on record, the report counts, from whichever folder it runs, the sessions of the repository's main folder, of the worktree the branch is checked out in and of the worktrees its agents worked in, even removed since. A branch checked out nowhere whose name sessions of other folders also carry is refused: nothing is posted rather than a figure that may lack them.
## How it works

**Three data paths, two levels of accuracy:**
| Script | Trigger | Data source | Subagents | Cache reads | Accuracy |
| -------------------- | ----------------------- | --------------------- | ------------ | ------------------- | ------------- |
| `backfill.sh` | Manual / setup | JSONL files | Included | Counted (8% energy) | Best estimate |
| `persist-session.sh` | Stop + SessionEnd hooks | JSONL files | Included | Counted (8% energy) | Best estimate |
| `statusline.sh` | Every turn (live) | `carbon.db` row | Included | Counted (8% energy) | One turn late |
**backfill** and **persist-session** parse the raw JSONL transcripts (main session, subagent files and the transcripts of the agents a workflow starts), applying per-model emission factors. They deduplicate assistant messages by `(message.id, requestId)`, so resumed and compacted sessions are not double-counted (this matches `ccusage`; without it the token sum inflates roughly 3x). Each session stores its raw token breakdown (input, cache write, cache read, output), which feeds the SQLite database used by reports.
An agent's transcript stops changing once the agent is done, so its totals are kept in `~/.claude/claude-carbon/usage-cache/` (one small file per session, removed by the daily re-scan 45 days after it was last written) and read again only when the file's size, modification or change time, or inode changes (the file a symlink points to). An agent with a line that does not parse yet, cut by a write in progress, is never kept. The main transcript is always read in full. `CLAUDE_CARBON_NO_USAGE_CACHE=1` reads everything every time and writes no cache.
**Cost** is the theoretical API list value (pay-as-you-go), not your subscription price: input, output, cache write, and cache read (0.1x input) at current Anthropic rates, set in `data/prices.json`. Cache writes are billed per TTL tier, 1.25x input for the 5-minute tier and 2x for the 1-hour one; each session's split is read from its transcript rather than assumed (Claude Code writes at the 1-hour tier). On deduplicated data it matches `ccusage`.
**statusline** reads this session's row from `carbon.db` at each turn, so the CO2 it shows is the session total on the same basis as the reports, one turn behind at most. Before that row exists (first turn, or no database yet) it falls back to an estimate from `context_window.total_input_tokens`, which is the size of the current context rather than a running total: subagents are invisible to it and every compaction sends it back down. Either way the status line displays, it never feeds the reports.
### Surviving the 30-day transcript purge
Claude Code deletes JSONL transcripts after about 30 days, so the SQLite database is the durable record. The `Stop` and `SessionEnd` hooks capture each session before its transcript ages out, and a once-a-day background re-scan (`SessionStart` hook, `safety-rescan.sh`) catches any session they missed while its transcript still exists, including one whose transcript kept growing after its row was written. Because each row stores raw token counts, `recompute.sh` regenerates cost and CO2 from `data/factors.json` + `data/prices.json` at any time, with no transcript needed. When Anthropic changes a price or a factor is revised, edit the config and run:
```bash
bash scripts/recompute.sh
```
Sessions recorded since September 2026 are re-derived model by model, exactly. Older sessions without a per-model split keep their stored values; `--include-unsplit` re-derives them at their dominant model, an approximation (see METHODOLOGY.md, "Surviving the 30-day transcript purge").
## Commands
| Command | What it does |
| ---------------- | --------------------------------------------------- |
| `/carbon-report` | Text report with totals, car equivalent, share of a 2 t budget, top sessions |
| `/carbon-card` | Generate shareable PNG report cards |
| `/carbon-badge` | Shields.io badge of your total footprint for your READMEs |
| `/carbon-pr` | Post the dev footprint of the current branch on its PR |
| `/carbon-update` | Update to the latest version, whichever way you installed |
<details>
<summary>Scripts (run automatically, rarely needed manually)</summary>
| Script | What it does |
| -------------------- | ----------------------------------------------------------------------------------------- |
| `setup.sh` | Init database, backfill historical sessions, show total |
| `statusline.sh` | Status line script (called automatically by Claude Code) |
| `persist-session.sh` | Stop hook (saves session data after each turn) |
| `persist-on-exit.sh` | SessionEnd hook (saves the session once more as it closes, in the background) |
| `safety-rescan.sh` | SessionStart hook (throttled background re-scan, catches missed sessions) |
| `agent-stop.sh` | SubagentStop hook (the branch an agent worked on, for `/carbon-pr`) |
| `backfill.sh` | Re-parse all historical JSONL transcripts (incl. subagents) |
| `recompute.sh` | Re-derive cost/CO2 from stored tokens after a price/factor change (no transcripts needed) |
| `generate-report.sh` | Export PNG report cards (CLI, with `--since` / `--until` / `--all`) |
| `generate-badge.sh` | Print the shields.io badge markdown + URL (CLI) |
| `generate-pr-report.sh` | Post the branch's dev footprint on its PR (CLI, `--dry-run` / `--pr`) |
Note: backfill now derives project names from the transcript's `cwd` (matching the live hook). Sessions backfilled before this change keep their old, possibly truncated names; delete those rows and re-run `backfill.sh` to normalize them.
</details>
## Badge
`/carbon-badge` prints a ready-to-paste shields.io badge with your measured all-time footprint and the month it was taken, clickable to the methodology:
[](https://github.com/gwittebolle/claude-carbon/blob/main/METHODOLOGY.md)
<sub>That badge is live, not a mockup: the author's own total, 1,208 sessions measured between 15 January 2026 and 16 September 2026. It is one developer's footprint, not the project's.</sub>
```markdown
[](https://github.com/gwittebolle/claude-carbon/blob/main/METHODOLOGY.md)
```
The badge is a static image built from your local database, so the number is measured, not estimated on the fly, and nothing is sent anywhere. The month in the message says how old the figure is; re-run `/carbon-badge` whenever you want to refresh both.
It is one developer's total, so it belongs in your profile README or a personal project. In a team or organisation repository, reviewers will ask what produced the number and why it links out of the organisation, and they will be right to.
Numbers follow the locale the report uses (`fr` prints `12,4 kg`, `us` and the world default print `12.4 kg`); `CLAUDE_CARBON_LOCALE` forces a set.
## The mod: /carbon-panel and the CO2 of each answer
The claude-carbon plugin also holds a [Claude Code mod](https://code.claude.com/docs/en/plugins/mods/overview) that shows the CO2 of each answer when it ends, computed locally with the same formula and factors as the status line, and the session's total with its API-price cost.
- **Terminal**, including the integrated terminal of an editor and the JetBrains plugin: at the right end of the line that closes each answer, `✻ Worked for 38s · done 10:32 PM 16 gCO₂`. A line keeps its own answer's figure when it is drawn again (a resize, a scroll, ctrl+o); a line drawn for the first time later, such as one only ctrl+o shows, gets no figure.
- **Desktop app, Code tab**: a line under the answer, only for an unusual answer.
- **An unusual answer** shows the ratio, and the subagents' share when they weighed on it: `230 gCO₂ · 14× your median`. An answer is unusual when it is above the 97th percentile of your last 200 answers, over 3× their median and at least 10 g, which is about one answer in 27; none is flagged before 50 answers are recorded.
- **The session total** is pinned under the prompt, CO2 and API-price cost: `This session: 142 gCO₂ · $3.41`, in French `Cette session : 142 gCO₂ · 3,41 $`. It shows unless the claude-carbon status line already gives it or the `showSessionTotal` option is off (both in a terminal only, see [ccstatusline](#using-with-ccstatusline)). The cost is the pay-as-you-go API list price of the same requests as the CO2, from `data/prices.json` with the formula of `/carbon-report`, cache writes at the 1-hour tier Claude Code uses; under a cent it reads `< $0.01`, and it is...
© gwittebolle · MIT · gwittebolle/claude-carbon