claude-carbon 1.5.0 β 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +56 -99
- package/package.json +12 -4
package/README.md
CHANGED
|
@@ -6,10 +6,18 @@
|
|
|
6
6
|
[](https://www.npmjs.com/package/claude-carbon)
|
|
7
7
|
[](https://github.com/gwittebolle/claude-carbon/actions/workflows/ci.yml)
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
claude-carbon is an open source Claude Code plugin that tracks the carbon footprint of your sessions: a live CO2 estimate in the status line, computed locally from your token usage, next to the session cost.
|
|
10
10
|
|
|
11
11
|

|
|
12
12
|
|
|
13
|
+
## What claude-carbon does
|
|
14
|
+
|
|
15
|
+
- Adds a live CO2 estimate to the Claude Code status line, next to the session cost
|
|
16
|
+
- Persists each session to a local SQLite database, so history survives the 30-day transcript purge
|
|
17
|
+
- Backfills historical data from existing `~/.claude` transcripts
|
|
18
|
+
- Slash commands: `/carbon-report` (text), `/carbon-card` (PNG), `/carbon-pr` (footprint of a pull request)
|
|
19
|
+
- A README badge with your all-time total, and a public methodology with every factor sourced
|
|
20
|
+
|
|
13
21
|
**1. Install (or update):**
|
|
14
22
|
|
|
15
23
|
macOS, Linux, WSL:
|
|
@@ -32,10 +40,12 @@ npx claude-carbon
|
|
|
32
40
|
|
|
33
41
|
Same command to install and to update to the latest version (all three run the same installer).
|
|
34
42
|
|
|
43
|
+
> **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.
|
|
44
|
+
|
|
35
45
|
**2. Restart Claude Code.** Your CO2 appears in the status line:
|
|
36
46
|
|
|
37
47
|
```
|
|
38
|
-
claude-carbon β₯ main | π’ Opus
|
|
48
|
+
claude-carbon β₯ main | π’ Opus 5 ββββββββββ 35% | $0.50 Β· 65g COβ | Use 24% β»13:00
|
|
39
49
|
```
|
|
40
50
|
|
|
41
51
|
Segments, left to right: project + git branch, model + context window %, 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%).
|
|
@@ -55,13 +65,6 @@ Accurate on every plan, including Max 20x.
|
|
|
55
65
|
- `/carbon-card` - generate shareable PNG report cards (requires `playwright-core`, see [Dependencies](#dependencies))
|
|
56
66
|
- `/carbon-update` - update to the latest version and re-price history (see [Updating](#updating))
|
|
57
67
|
|
|
58
|
-
## What it does
|
|
59
|
-
|
|
60
|
-
- Adds a live CO2 estimate to the Claude Code status line, next to the session cost
|
|
61
|
-
- Persists each session to a local SQLite database
|
|
62
|
-
- Backfills historical data from existing `~/.claude` transcripts
|
|
63
|
-
- Two slash commands: `/carbon-report` (text) and `/carbon-card` (PNG)
|
|
64
|
-
|
|
65
68
|
## Example report
|
|
66
69
|
|
|
67
70
|
<p align="center">
|
|
@@ -74,6 +77,12 @@ OneDrive-redirected one is honoured) and the folder opens in your file manager,
|
|
|
74
77
|
card selected on macOS. `CLAUDE_CARBON_EXPORT_DIR` picks another folder;
|
|
75
78
|
`CLAUDE_CARBON_NO_OPEN=1` skips the opening.
|
|
76
79
|
|
|
80
|
+
From the 1st to the 10th of each month the status line ends with `π August wrapped Β· /carbon-card`:
|
|
81
|
+
the month just closed has its bar on the card, under the running total. Generating a card
|
|
82
|
+
clears it for the month; it goes quiet on its own after the 10th. `CLAUDE_CARBON_CARD_NUDGE_UNTIL_DAY`
|
|
83
|
+
moves the cut-off, `CLAUDE_CARBON_NO_CARD_NUDGE=1` removes the nudge. Nothing is posted anywhere:
|
|
84
|
+
sharing stays a human decision.
|
|
85
|
+
|
|
77
86
|
<details>
|
|
78
87
|
<summary>Advanced options (CLI)</summary>
|
|
79
88
|
|
|
@@ -149,6 +158,17 @@ The second script merges the block below into `~/.claude/settings.json` (additiv
|
|
|
149
158
|
]
|
|
150
159
|
}
|
|
151
160
|
],
|
|
161
|
+
"SessionEnd": [
|
|
162
|
+
{
|
|
163
|
+
"matcher": "",
|
|
164
|
+
"hooks": [
|
|
165
|
+
{
|
|
166
|
+
"type": "command",
|
|
167
|
+
"command": "~/code/claude-carbon/scripts/persist-on-exit.sh"
|
|
168
|
+
}
|
|
169
|
+
]
|
|
170
|
+
}
|
|
171
|
+
],
|
|
152
172
|
"SessionStart": [
|
|
153
173
|
{
|
|
154
174
|
"matcher": "",
|
|
@@ -164,7 +184,7 @@ The second script merges the block below into `~/.claude/settings.json` (additiv
|
|
|
164
184
|
}
|
|
165
185
|
```
|
|
166
186
|
|
|
167
|
-
The `Stop` hook records the session
|
|
187
|
+
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.
|
|
168
188
|
|
|
169
189
|
Restart Claude Code.
|
|
170
190
|
|
|
@@ -195,14 +215,14 @@ Turning it off is the default: nothing is posted unless you run it. `--dry-run`
|
|
|
195
215
|
|
|
196
216
|
## How it works
|
|
197
217
|
|
|
198
|
-

|
|
199
219
|
|
|
200
220
|
**Three data paths, two levels of accuracy:**
|
|
201
221
|
|
|
202
222
|
| Script | Trigger | Data source | Subagents | Cache reads | Accuracy |
|
|
203
223
|
| -------------------- | ----------------------- | --------------------- | ------------ | ------------------- | ------------- |
|
|
204
224
|
| `backfill.sh` | Manual / setup | JSONL files | Included | Counted (8% energy) | Best estimate |
|
|
205
|
-
| `persist-session.sh` | Stop
|
|
225
|
+
| `persist-session.sh` | Stop + SessionEnd hooks | JSONL files | Included | Counted (8% energy) | Best estimate |
|
|
206
226
|
| `statusline.sh` | Every turn (live) | `carbon.db` row | Included | Counted (8% energy) | One turn late |
|
|
207
227
|
|
|
208
228
|
**backfill** and **persist-session** parse the raw JSONL transcripts (main session + subagent files), 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.
|
|
@@ -213,12 +233,14 @@ Turning it off is the default: nothing is posted unless you run it. `--dry-run`
|
|
|
213
233
|
|
|
214
234
|
### Surviving the 30-day transcript purge
|
|
215
235
|
|
|
216
|
-
Claude Code deletes JSONL transcripts after about 30 days, so the SQLite database is the durable record. The `Stop`
|
|
236
|
+
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:
|
|
217
237
|
|
|
218
238
|
```bash
|
|
219
239
|
bash scripts/recompute.sh
|
|
220
240
|
```
|
|
221
241
|
|
|
242
|
+
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").
|
|
243
|
+
|
|
222
244
|
## Commands
|
|
223
245
|
|
|
224
246
|
| Command | What it does |
|
|
@@ -236,7 +258,8 @@ bash scripts/recompute.sh
|
|
|
236
258
|
| -------------------- | ----------------------------------------------------------------------------------------- |
|
|
237
259
|
| `setup.sh` | Init database, backfill historical sessions, show total |
|
|
238
260
|
| `statusline.sh` | Status line script (called automatically by Claude Code) |
|
|
239
|
-
| `persist-session.sh` | Stop hook (saves session data
|
|
261
|
+
| `persist-session.sh` | Stop hook (saves session data after each turn) |
|
|
262
|
+
| `persist-on-exit.sh` | SessionEnd hook (saves the session once more as it closes, in the background) |
|
|
240
263
|
| `safety-rescan.sh` | SessionStart hook (throttled background re-scan, catches missed sessions) |
|
|
241
264
|
| `backfill.sh` | Re-parse all historical JSONL transcripts (incl. subagents) |
|
|
242
265
|
| `recompute.sh` | Re-derive cost/CO2 from stored tokens after a price/factor change (no transcripts needed) |
|
|
@@ -250,17 +273,19 @@ Note: backfill now derives project names from the transcript's `cwd` (matching t
|
|
|
250
273
|
|
|
251
274
|
## Badge
|
|
252
275
|
|
|
253
|
-
`/carbon-badge` prints a ready-to-paste shields.io badge with your measured all-time footprint, clickable
|
|
276
|
+
`/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:
|
|
254
277
|
|
|
255
|
-
[](https://github.com/gwittebolle/claude-carbon/blob/main/METHODOLOGY.md)
|
|
256
279
|
|
|
257
|
-
<sub>That badge is live, not a mockup: the author's own total, 1,
|
|
280
|
+
<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>
|
|
258
281
|
|
|
259
282
|
```markdown
|
|
260
|
-
[](https://github.com/gwittebolle/claude-carbon/blob/main/METHODOLOGY.md)
|
|
261
284
|
```
|
|
262
285
|
|
|
263
|
-
The badge is a static image built from your local database, so the number is measured, not estimated on the fly.
|
|
286
|
+
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.
|
|
287
|
+
|
|
288
|
+
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.
|
|
264
289
|
|
|
265
290
|
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.
|
|
266
291
|
|
|
@@ -289,7 +314,8 @@ Factors from [Jegham et al. 2025](https://arxiv.org/abs/2505.09598), an arXiv pr
|
|
|
289
314
|
|
|
290
315
|
- Sonnet factors are a 3-point least-squares fit to the three Claude 3.7 Sonnet per-query energies estimated in Jegham et al. v6 (0.950 / 2.989 / 5.671 Wh), giving a ~21:1 output:input ratio. The value is consistent with [EcoLogits](https://ecologits.ai): its independent estimate for Sonnet brackets the same range (a wide band, so this is a consistency check, not proof). Fable, Opus and Haiku are extrapolated (no public data from Anthropic on per-model energy consumption); Opus = 2x Sonnet matches both the current EcoLogits Opus 4.5+ parameter ratio and the Anthropic price ratio (honest band 2x-5x).
|
|
291
316
|
- Sessions run on non-Anthropic models (e.g. local models behind `ANTHROPIC_BASE_URL`) are stored with their raw tokens but zero cost/CO2 and excluded from reports - a datacenter factor doesn't apply to them. Add patterns to `exclude_models` in `data/factors.json` to exclude more models by name.
|
|
292
|
-
- Cache read tokens are counted at a reduced factor (default 0.08 of an input token, set in `data/factors.json`). A cached token skips
|
|
317
|
+
- Cache read tokens are counted at a reduced factor (default 0.08 of an input token, set in `data/factors.json`). A cached token skips most of the prefill compute; the factor is the residual. This is an engineering estimate derived from the literature, not Anthropic's 0.1x billing ratio. The decode-phase re-read of the cache grows with context length x generated tokens and is not modelled yet; every session stores that product (`output_context_sum`) so a calibrated term can be applied to history later. See [METHODOLOGY.md](METHODOLOGY.md).
|
|
318
|
+
- Reviewed against the April-September 2026 literature (measurement papers, provider disclosures, the Watershed framework) with a sensitivity run on 30 days of real transcripts: no factor moved, the displayed figure is more likely low than high, next review March 2027. See [Where the estimate stands](METHODOLOGY.md#where-the-estimate-stands-september-2026).
|
|
293
319
|
- Carbon intensity uses the AWS region grid (location-based, 0.287 kgCO2e/kWh), not real-time grid data. This sits at the low end of the location-based range; the US national average is ~380 g/kWh.
|
|
294
320
|
- Anthropic does not publish Scope 1, 2, or 3 emissions. These estimates are independent and based on academic research, not provider data.
|
|
295
321
|
|
|
@@ -400,86 +426,17 @@ hook and the status line, hook manifests spawned the way Claude Code spawns them
|
|
|
400
426
|
|
|
401
427
|
## Reduce your footprint
|
|
402
428
|
|
|
403
|
-
Measuring is step one.
|
|
404
|
-
|
|
405
|
-
### Use the right model for the task
|
|
406
|
-
|
|
407
|
-
Output tokens cost ~21x more energy than input tokens (the marginal output:input ratio fit on Jegham v6). Opus is estimated at ~2x Sonnet per token (uncertainty band 2x-5x, see METHODOLOGY.md).
|
|
408
|
-
|
|
409
|
-
```json
|
|
410
|
-
{
|
|
411
|
-
"env": {
|
|
412
|
-
"CLAUDE_CODE_SUBAGENT_MODEL": "claude-haiku-4-5"
|
|
413
|
-
}
|
|
414
|
-
}
|
|
415
|
-
```
|
|
416
|
-
|
|
417
|
-
Use Opus for architecture and planning. Sonnet for daily work. Haiku for subagents (exploration, file reading, reviews). As an indicative estimate with this tool's factors, this alone can cut your emissions by up to ~60% vs all-Opus.
|
|
418
|
-
|
|
419
|
-
### Install RTK (Rust Token Killer)
|
|
420
|
-
|
|
421
|
-
[RTK](https://github.com/rtk-ai/rtk) is a CLI proxy that filters noise from shell outputs (progress bars, verbose logs, passing tests) before they hit the context window. 60-90% token reduction on CLI commands, zero quality loss.
|
|
422
|
-
|
|
423
|
-
```bash
|
|
424
|
-
brew install rtk-ai/tap/rtk
|
|
425
|
-
rtk init -g
|
|
426
|
-
```
|
|
427
|
-
|
|
428
|
-
### Reduce thinking tokens
|
|
429
|
-
|
|
430
|
-
Claude's extended thinking can use up to 32k hidden tokens per message. Capping it reduces consumption without degrading quality on routine tasks.
|
|
431
|
-
|
|
432
|
-
```json
|
|
433
|
-
{
|
|
434
|
-
"env": {
|
|
435
|
-
"MAX_THINKING_TOKENS": "10000"
|
|
436
|
-
}
|
|
437
|
-
}
|
|
438
|
-
```
|
|
439
|
-
|
|
440
|
-
### Compact earlier
|
|
441
|
-
|
|
442
|
-
By default, Claude Code compacts context at 95% usage. Compacting earlier keeps context cleaner and avoids bloated sessions.
|
|
443
|
-
|
|
444
|
-
```json
|
|
445
|
-
{
|
|
446
|
-
"env": {
|
|
447
|
-
"CLAUDE_AUTOCOMPACT_PCT_OVERRIDE": "50"
|
|
448
|
-
}
|
|
449
|
-
}
|
|
450
|
-
```
|
|
451
|
-
|
|
452
|
-
### Disconnect unused MCP servers
|
|
453
|
-
|
|
454
|
-
Every connected MCP server ships its full tool schemas into the context window with every request, whether the session uses them or not. Most of that overhead is served from prompt cache after the first turn, and cache reads carry a much lower energy factor (see METHODOLOGY.md), so the saving per turn is modest; the gain comes from repetition across every turn of every session.
|
|
455
|
-
|
|
456
|
-
```bash
|
|
457
|
-
claude mcp list
|
|
458
|
-
```
|
|
459
|
-
|
|
460
|
-
Keep the servers the project actually uses, remove the rest with `claude mcp remove <name>`.
|
|
461
|
-
|
|
462
|
-
### Write concise instructions
|
|
463
|
-
|
|
464
|
-
Add to your project's CLAUDE.md:
|
|
465
|
-
|
|
466
|
-
```
|
|
467
|
-
Be concise. No preamble, no summaries unless asked.
|
|
468
|
-
```
|
|
469
|
-
|
|
470
|
-
Output tokens are the most expensive in both cost and energy.
|
|
471
|
-
|
|
472
|
-
### Combined impact
|
|
429
|
+
Measuring is step one. The levers below are ordered by what the 2026 measurement literature and this tool's own sensitivity run on real transcripts say matters most. None of them comes with a percentage: the emission factors carry a wider uncertainty band than any gain figure would. `/carbon-report` before and after a change, over several sessions, is the measurement that applies to you. The mechanism, the direction and the sources of each lever are in [docs/reduce.md](docs/reduce.md).
|
|
473
430
|
|
|
474
|
-
|
|
431
|
+
- **Keep the context short when the model generates.** Almost every token of a session is a cache read, and the energy of a generated token grows with the context it is generated in. One session per task, `/clear` when the subject changes, `/btw` for side questions, subagents for exploration and verbose operations.
|
|
432
|
+
- **Compact on your terms.** `/compact <instructions>` at a natural break, `/rewind` when abandoning a path, `/autocompact 150k` to bound the window, `CLAUDE_CODE_DISABLE_1M_CONTEXT=1` on models that run at 1M by default.
|
|
433
|
+
- **Trim what every turn carries.** `/context` shows it. A short `CLAUDE.md` with the rest in skills, unused MCP servers off with `/mcp`, a CLI over an MCP server where both exist.
|
|
434
|
+
- **Do not break the cache mid-session.** Pick the model and the effort level at the start; `/usage` shows the hit ratio and the likely cause of the last miss.
|
|
435
|
+
- **Fewer turns, fewer failed loops.** A spec and a test the agent can run, a deterministic tool over a retry, `/clear` after two failed corrections, no `/loop` left running on an idle session.
|
|
436
|
+
- **Ask the agent only what needs an agent.** An agentic task runs on the order of a thousand times the tokens of a chat exchange. A `--help` costs nothing.
|
|
437
|
+
- **Match reasoning and model to the task.** `/effort low` on routine work, set at session start; Haiku for subagents via `CLAUDE_CODE_SUBAGENT_MODEL`.
|
|
475
438
|
|
|
476
|
-
|
|
477
|
-
| -------------------- | ---------------------------- |
|
|
478
|
-
| Right model per task | -60% vs all-Opus |
|
|
479
|
-
| RTK | -70% on CLI tokens |
|
|
480
|
-
| Thinking cap at 10k | -70% on thinking tokens |
|
|
481
|
-
| Haiku subagents | -75% vs Opus, -50% vs Sonnet |
|
|
482
|
-
| **All combined** | **-50 to 70% total** |
|
|
439
|
+
The same document covers what does not hold up (shell output filters, prompt compressors, adding up percentages), the harness as a lever, and what is out of your hands for now.
|
|
483
440
|
|
|
484
441
|
### Related projects
|
|
485
442
|
|
|
@@ -511,4 +468,4 @@ The shareable report cards already carry this attribution in their footer, so re
|
|
|
511
468
|
|
|
512
469
|
claude-carbon is free and open source under the [MIT license](LICENSE). Contributions welcome.
|
|
513
470
|
|
|
514
|
-
Built by [
|
|
471
|
+
Built by [GaΓ«tan Wittebolle](https://gaetanwittebolle.com), carbon consultant turned solo builder in Bordeaux, France. Team version: [TokenClimate](https://tokenclimate.com).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-carbon",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.8.0",
|
|
4
4
|
"description": "Track the carbon footprint of your Claude Code sessions",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"diagram": "node docs/render-diagram.mjs",
|
|
@@ -18,15 +18,23 @@
|
|
|
18
18
|
"url": "git+https://github.com/gwittebolle/claude-carbon.git"
|
|
19
19
|
},
|
|
20
20
|
"bugs": "https://github.com/gwittebolle/claude-carbon/issues",
|
|
21
|
-
"author": "
|
|
21
|
+
"author": "GaΓ«tan Wittebolle <gaetan.wittebolle@gmail.com> (https://gaetanwittebolle.com)",
|
|
22
22
|
"license": "MIT",
|
|
23
23
|
"keywords": [
|
|
24
|
+
"claude-carbon",
|
|
24
25
|
"carbon-footprint",
|
|
26
|
+
"carbon-emissions",
|
|
27
|
+
"co2",
|
|
28
|
+
"co2-tracker",
|
|
25
29
|
"sustainability",
|
|
30
|
+
"green-it",
|
|
31
|
+
"green-ai",
|
|
26
32
|
"claude-code",
|
|
33
|
+
"claude-code-plugin",
|
|
27
34
|
"claude",
|
|
28
|
-
"
|
|
29
|
-
"
|
|
35
|
+
"anthropic",
|
|
36
|
+
"statusline",
|
|
37
|
+
"llm"
|
|
30
38
|
],
|
|
31
39
|
"engines": {
|
|
32
40
|
"node": ">=18"
|