claude-carbon 1.7.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.
Files changed (2) hide show
  1. package/README.md +37 -88
  2. package/package.json +2 -2
package/README.md CHANGED
@@ -40,6 +40,8 @@ npx claude-carbon
40
40
 
41
41
  Same command to install and to update to the latest version (all three run the same installer).
42
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
+
43
45
  **2. Restart Claude Code.** Your CO2 appears in the status line:
44
46
 
45
47
  ```
@@ -156,6 +158,17 @@ The second script merges the block below into `~/.claude/settings.json` (additiv
156
158
  ]
157
159
  }
158
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
+ ],
159
172
  "SessionStart": [
160
173
  {
161
174
  "matcher": "",
@@ -171,7 +184,7 @@ The second script merges the block below into `~/.claude/settings.json` (additiv
171
184
  }
172
185
  ```
173
186
 
174
- The `Stop` hook records the session that just ended. The `SessionStart` one re-scans for sessions that hook missed (crash, kill) and drives the daily update check the status line reads; without it you are never told a new version exists.
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.
175
188
 
176
189
  Restart Claude Code.
177
190
 
@@ -209,7 +222,7 @@ Turning it off is the default: nothing is posted unless you run it. `--dry-run`
209
222
  | Script | Trigger | Data source | Subagents | Cache reads | Accuracy |
210
223
  | -------------------- | ----------------------- | --------------------- | ------------ | ------------------- | ------------- |
211
224
  | `backfill.sh` | Manual / setup | JSONL files | Included | Counted (8% energy) | Best estimate |
212
- | `persist-session.sh` | Stop hook (session end) | JSONL files | Included | Counted (8% energy) | Best estimate |
225
+ | `persist-session.sh` | Stop + SessionEnd hooks | JSONL files | Included | Counted (8% energy) | Best estimate |
213
226
  | `statusline.sh` | Every turn (live) | `carbon.db` row | Included | Counted (8% energy) | One turn late |
214
227
 
215
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.
@@ -220,12 +233,14 @@ Turning it off is the default: nothing is posted unless you run it. `--dry-run`
220
233
 
221
234
  ### Surviving the 30-day transcript purge
222
235
 
223
- Claude Code deletes JSONL transcripts after about 30 days, so the SQLite database is the durable record. The `Stop` hook captures each session before its transcript ages out, and a once-a-day background re-scan (`SessionStart` hook, `safety-rescan.sh`) catches any session the `Stop` hook missed while its transcript still exists. 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:
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:
224
237
 
225
238
  ```bash
226
239
  bash scripts/recompute.sh
227
240
  ```
228
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
+
229
244
  ## Commands
230
245
 
231
246
  | Command | What it does |
@@ -243,7 +258,8 @@ bash scripts/recompute.sh
243
258
  | -------------------- | ----------------------------------------------------------------------------------------- |
244
259
  | `setup.sh` | Init database, backfill historical sessions, show total |
245
260
  | `statusline.sh` | Status line script (called automatically by Claude Code) |
246
- | `persist-session.sh` | Stop hook (saves session data on exit) |
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) |
247
263
  | `safety-rescan.sh` | SessionStart hook (throttled background re-scan, catches missed sessions) |
248
264
  | `backfill.sh` | Re-parse all historical JSONL transcripts (incl. subagents) |
249
265
  | `recompute.sh` | Re-derive cost/CO2 from stored tokens after a price/factor change (no transcripts needed) |
@@ -257,17 +273,19 @@ Note: backfill now derives project names from the transcript's `cwd` (matching t
257
273
 
258
274
  ## Badge
259
275
 
260
- `/carbon-badge` prints a ready-to-paste shields.io badge with your measured all-time footprint, clickable back to this repo:
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:
261
277
 
262
- [![Claude Code carbon footprint](https://img.shields.io/badge/claude--carbon-972.0%20kg%20CO2e-2f6f4f)](https://github.com/gwittebolle/claude-carbon)
278
+ [![Claude Code carbon footprint](https://img.shields.io/badge/claude--carbon-1139.2%20kg%20CO2e%2C%202026--09-2f6f4f)](https://github.com/gwittebolle/claude-carbon/blob/main/METHODOLOGY.md)
263
279
 
264
- <sub>That badge is live, not a mockup: the author's own total, 1,025 sessions measured between 15 January 2026 and 20 August 2026. It is one developer's footprint, not the project's.</sub>
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>
265
281
 
266
282
  ```markdown
267
- [![Claude Code carbon footprint](https://img.shields.io/badge/claude--carbon-972.0%20kg%20CO2e-2f6f4f)](https://github.com/gwittebolle/claude-carbon)
283
+ [![Claude Code carbon footprint](https://img.shields.io/badge/claude--carbon-1139.2%20kg%20CO2e%2C%202026--09-2f6f4f)](https://github.com/gwittebolle/claude-carbon/blob/main/METHODOLOGY.md)
268
284
  ```
269
285
 
270
- The badge is a static image built from your local database, so the number is measured, not estimated on the fly. Re-run `/carbon-badge` whenever you want to refresh it.
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.
271
289
 
272
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.
273
291
 
@@ -408,86 +426,17 @@ hook and the status line, hook manifests spawned the way Claude Code spawns them
408
426
 
409
427
  ## Reduce your footprint
410
428
 
411
- Measuring is step one. Here are concrete levers to reduce your AI carbon footprint, ranked by impact.
412
-
413
- ### Use the right model for the task
414
-
415
- 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).
416
-
417
- ```json
418
- {
419
- "env": {
420
- "CLAUDE_CODE_SUBAGENT_MODEL": "claude-haiku-4-5"
421
- }
422
- }
423
- ```
424
-
425
- 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.
426
-
427
- ### Install RTK (Rust Token Killer)
428
-
429
- [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.
430
-
431
- ```bash
432
- brew install rtk-ai/tap/rtk
433
- rtk init -g
434
- ```
435
-
436
- ### Reduce thinking tokens
437
-
438
- Claude's extended thinking can use up to 32k hidden tokens per message. Capping it reduces consumption without degrading quality on routine tasks.
439
-
440
- ```json
441
- {
442
- "env": {
443
- "MAX_THINKING_TOKENS": "10000"
444
- }
445
- }
446
- ```
447
-
448
- ### Compact earlier
449
-
450
- By default, Claude Code compacts context at 95% usage. Compacting earlier keeps context cleaner and avoids bloated sessions.
451
-
452
- ```json
453
- {
454
- "env": {
455
- "CLAUDE_AUTOCOMPACT_PCT_OVERRIDE": "50"
456
- }
457
- }
458
- ```
459
-
460
- ### Disconnect unused MCP servers
461
-
462
- 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.
463
-
464
- ```bash
465
- claude mcp list
466
- ```
467
-
468
- Keep the servers the project actually uses, remove the rest with `claude mcp remove <name>`.
469
-
470
- ### Write concise instructions
471
-
472
- Add to your project's CLAUDE.md:
473
-
474
- ```
475
- Be concise. No preamble, no summaries unless asked.
476
- ```
477
-
478
- Output tokens are the most expensive in both cost and energy.
479
-
480
- ### 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).
481
430
 
482
- These reductions are indicative estimates, not measurements on a benchmark workload. The RTK figure comes from RTK's own documentation. The Haiku rows follow from this tool's own factors (Haiku = 0.5x Sonnet = 0.25x Opus per token): -50% when your subagents would otherwise run Sonnet, -75% when they would run Opus. They inherit the 0.5x extrapolation, the widest uncertainty band in the tool (see METHODOLOGY.md); if most of your usage is already Haiku, your absolute total rides on that band, so read it as an order of magnitude.
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`.
483
438
 
484
- | Lever | Estimated reduction |
485
- | -------------------- | ---------------------------- |
486
- | Right model per task | -60% vs all-Opus |
487
- | RTK | -70% on CLI tokens |
488
- | Thinking cap at 10k | -70% on thinking tokens |
489
- | Haiku subagents | -75% vs Opus, -50% vs Sonnet |
490
- | **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.
491
440
 
492
441
  ### Related projects
493
442
 
@@ -519,4 +468,4 @@ The shareable report cards already carry this attribution in their footer, so re
519
468
 
520
469
  claude-carbon is free and open source under the [MIT license](LICENSE). Contributions welcome.
521
470
 
522
- Built by [Gaetan Wittebolle](https://github.com/gwittebolle).
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.7.0",
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,7 +18,7 @@
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": "Gaetan Wittebolle (https://github.com/gwittebolle)",
21
+ "author": "Gaëtan Wittebolle <gaetan.wittebolle@gmail.com> (https://gaetanwittebolle.com)",
22
22
  "license": "MIT",
23
23
  "keywords": [
24
24
  "claude-carbon",