claude-carbon 1.3.0 โ†’ 1.7.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 CHANGED
@@ -6,33 +6,49 @@
6
6
  [![npm](https://img.shields.io/npm/v/claude-carbon)](https://www.npmjs.com/package/claude-carbon)
7
7
  [![CI](https://github.com/gwittebolle/claude-carbon/actions/workflows/ci.yml/badge.svg)](https://github.com/gwittebolle/claude-carbon/actions/workflows/ci.yml)
8
8
 
9
- Track the carbon footprint of your Claude Code sessions.
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
  ![Live CO2 in the Claude Code status line](docs/demo.gif)
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
 
23
+ macOS, Linux, WSL:
24
+
15
25
  ```bash
16
26
  curl -fsSL https://raw.githubusercontent.com/gwittebolle/claude-carbon/main/install.sh | bash
17
27
  ```
18
28
 
19
- Or, if you have Node.js:
29
+ Windows (PowerShell), which needs [Git for Windows](https://git-scm.com/downloads/win) and two packages first - see [Windows](#windows):
30
+
31
+ ```powershell
32
+ irm https://raw.githubusercontent.com/gwittebolle/claude-carbon/main/install.ps1 | iex
33
+ ```
34
+
35
+ Or, on any platform with Node.js:
20
36
 
21
37
  ```bash
22
38
  npx claude-carbon
23
39
  ```
24
40
 
25
- Same command to install and to update to the latest version (both run the same installer).
41
+ Same command to install and to update to the latest version (all three run the same installer).
26
42
 
27
43
  **2. Restart Claude Code.** Your CO2 appears in the status line:
28
44
 
29
45
  ```
30
- claude-carbon โŒฅ main | ๐ŸŸข Opus 4.7 โ–“โ–“โ–“โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘ 35% | $0.50 ยท 65g COโ‚‚ | Use 24% โ†ป13:00
46
+ claude-carbon โŒฅ main | ๐ŸŸข Opus 5 โ–“โ–“โ–“โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘ 35% | $0.50 ยท 65g COโ‚‚ | Use 24% โ†ป13:00
31
47
  ```
32
48
 
33
49
  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%).
34
50
 
35
- > **Terminal and IDE only.** claude-carbon runs through the Claude Code status line and shell hooks, which execute in the terminal CLI and IDE extensions. They do not run in the web app (claude.ai/code) or the desktop app, so no CO2 is displayed or recorded there.
51
+ > **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) and the desktop app run neither the status line nor the hooks, so nothing is displayed or recorded there.
36
52
 
37
53
  **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:
38
54
 
@@ -47,20 +63,23 @@ Accurate on every plan, including Max 20x.
47
63
  - `/carbon-card` - generate shareable PNG report cards (requires `playwright-core`, see [Dependencies](#dependencies))
48
64
  - `/carbon-update` - update to the latest version and re-price history (see [Updating](#updating))
49
65
 
50
- ## What it does
51
-
52
- - Adds a live CO2 estimate to the Claude Code status line, next to the session cost
53
- - Persists each session to a local SQLite database
54
- - Backfills historical data from existing `~/.claude` transcripts
55
- - Two slash commands: `/carbon-report` (text) and `/carbon-card` (PNG)
56
-
57
66
  ## Example report
58
67
 
59
68
  <p align="center">
60
69
  <img src="docs/example-report-v2.png" alt="Claude Carbon Report" width="540">
61
70
  </p>
62
71
 
63
- Generate yours with `/carbon-card` in Claude Code. Exports summary and detailed PNGs to `exports/`.
72
+ Generate yours with `/carbon-card` in Claude Code. The summary and detailed PNGs land in
73
+ `~/Downloads/claude-carbon/` (the Windows Downloads folder follows the system setting, so a
74
+ OneDrive-redirected one is honoured) and the folder opens in your file manager, with the
75
+ card selected on macOS. `CLAUDE_CARBON_EXPORT_DIR` picks another folder;
76
+ `CLAUDE_CARBON_NO_OPEN=1` skips the opening.
77
+
78
+ From the 1st to the 10th of each month the status line ends with `๐Ÿ“Š August wrapped ยท /carbon-card`:
79
+ the month just closed has its bar on the card, under the running total. Generating a card
80
+ clears it for the month; it goes quiet on its own after the 10th. `CLAUDE_CARBON_CARD_NUDGE_UNTIL_DAY`
81
+ moves the cut-off, `CLAUDE_CARBON_NO_CARD_NUDGE=1` removes the nudge. Nothing is posted anywhere:
82
+ sharing stays a human decision.
64
83
 
65
84
  <details>
66
85
  <summary>Advanced options (CLI)</summary>
@@ -168,9 +187,22 @@ claude-carbon measures one developer's sessions, locally. If the question comes
168
187
 
169
188
  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.
170
189
 
190
+ ### PR dev footprint (/carbon-pr)
191
+
192
+ 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.
193
+
194
+ ```
195
+ **Claude Code carbon report** ยท developing this PR
196
+ 124 g CO2e ยท $3.00 ยท 180k tokens ยท 1.5M cache reads ยท 2 sessions
197
+ ```
198
+
199
+ 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). Sessions started from a subdirectory of the repo are stored under the subdirectory's name and stay out of the sum. A session that ends on another branch than it started is attributed to where it finished.
200
+
201
+ Turning it off is the default: nothing is posted unless you run it. `--dry-run` previews the comment, `--pr <number>` targets a specific PR, and deleting the comment on GitHub is the full cleanup.
202
+
171
203
  ## How it works
172
204
 
173
- ![Data flow](docs/data-flow.png)
205
+ ![claude-carbon data flow: Claude Code transcripts and status line JSON to a local SQLite database and a CO2 estimate](docs/data-flow.svg)
174
206
 
175
207
  **Three data paths, two levels of accuracy:**
176
208
 
@@ -178,13 +210,13 @@ The only places the OSS points there are a one-line footer in `/carbon-report` a
178
210
  | -------------------- | ----------------------- | --------------------- | ------------ | ------------------- | ------------- |
179
211
  | `backfill.sh` | Manual / setup | JSONL files | Included | Counted (8% energy) | Best estimate |
180
212
  | `persist-session.sh` | Stop hook (session end) | JSONL files | Included | Counted (8% energy) | Best estimate |
181
- | `statusline.sh` | Every turn (live) | `context_window` JSON | Not included | Included (approx) | Approximate |
213
+ | `statusline.sh` | Every turn (live) | `carbon.db` row | Included | Counted (8% energy) | One turn late |
182
214
 
183
215
  **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.
184
216
 
185
- **Cost** is the theoretical API list value (pay-as-you-go), not your subscription price: input, output, cache write (1.25x input), and cache read (0.1x input) at current Anthropic rates, set in `data/prices.json`. On deduplicated data it matches `ccusage`.
217
+ **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`.
186
218
 
187
- **statusline** reads `context_window.total_input_tokens` from Claude Code at each turn. This value represents the current context size (not a cumulative total), includes cache reads, and does not account for subagent tokens. It's an indicative live display, not a data source for reports.
219
+ **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.
188
220
 
189
221
  ### Surviving the 30-day transcript purge
190
222
 
@@ -200,6 +232,8 @@ bash scripts/recompute.sh
200
232
  | ---------------- | --------------------------------------------------- |
201
233
  | `/carbon-report` | Text report with totals, equivalences, top sessions |
202
234
  | `/carbon-card` | Generate shareable PNG report cards |
235
+ | `/carbon-badge` | Shields.io badge of your total footprint for your READMEs |
236
+ | `/carbon-pr` | Post the dev footprint of the current branch on its PR |
203
237
  | `/carbon-update` | Update to the latest version and re-price history |
204
238
 
205
239
  <details>
@@ -214,11 +248,29 @@ bash scripts/recompute.sh
214
248
  | `backfill.sh` | Re-parse all historical JSONL transcripts (incl. subagents) |
215
249
  | `recompute.sh` | Re-derive cost/CO2 from stored tokens after a price/factor change (no transcripts needed) |
216
250
  | `generate-report.sh` | Export PNG report cards (CLI, with `--since` / `--until` / `--all`) |
251
+ | `generate-badge.sh` | Print the shields.io badge markdown + URL (CLI) |
252
+ | `generate-pr-report.sh` | Post the branch's dev footprint on its PR (CLI, `--dry-run` / `--pr`) |
217
253
 
218
254
  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.
219
255
 
220
256
  </details>
221
257
 
258
+ ## Badge
259
+
260
+ `/carbon-badge` prints a ready-to-paste shields.io badge with your measured all-time footprint, clickable back to this repo:
261
+
262
+ [![Claude Code carbon footprint](https://img.shields.io/badge/claude--carbon-972.0%20kg%20CO2e-2f6f4f)](https://github.com/gwittebolle/claude-carbon)
263
+
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>
265
+
266
+ ```markdown
267
+ [![Claude Code carbon footprint](https://img.shields.io/badge/claude--carbon-972.0%20kg%20CO2e-2f6f4f)](https://github.com/gwittebolle/claude-carbon)
268
+ ```
269
+
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.
271
+
272
+ 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
+
222
274
  ## Using with ccstatusline
223
275
 
224
276
  Claude Code accepts a single `statusLine` command, so claude-carbon's full status line and [ccstatusline](https://github.com/sirmalloc/ccstatusline) cannot run side by side. If ccstatusline drives your status line, embed the CO2 segment instead: in the ccstatusline TUI, add a `Custom Command` widget pointing to
@@ -244,7 +296,8 @@ Factors from [Jegham et al. 2025](https://arxiv.org/abs/2505.09598), an arXiv pr
244
296
 
245
297
  - 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).
246
298
  - 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.
247
- - 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 prefill compute but still incurs decode-phase memory reads, so it is cheap but not free. This is an engineering estimate derived from the literature, not Anthropic's 0.1x billing ratio. See [METHODOLOGY.md](METHODOLOGY.md).
299
+ - 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).
300
+ - 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).
248
301
  - 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.
249
302
  - Anthropic does not publish Scope 1, 2, or 3 emissions. These estimates are independent and based on academic research, not provider data.
250
303
 
@@ -276,9 +329,9 @@ curl -fsSL https://raw.githubusercontent.com/gwittebolle/claude-carbon/main/inst
276
329
  - `sqlite3` - local database
277
330
  - `git` - branch detection in status line (optional)
278
331
  - `curl` - 5h quota usage via Anthropic's `/api/oauth/usage` endpoint (optional, 60s cache)
279
- - `playwright-core` + Chromium - PNG export for `/carbon-card` (optional)
332
+ - `node` + `playwright-core` + Chromium - PNG export for `/carbon-card` (optional)
280
333
 
281
- `jq` and `sqlite3` are pre-installed on macOS. On Linux: `apt install jq sqlite3`.
334
+ `jq` and `sqlite3` are pre-installed on macOS. On Linux: `apt install jq sqlite3`. On Windows, see below.
282
335
 
283
336
  To use `/carbon-card`, install Playwright and its Chromium browser:
284
337
 
@@ -287,6 +340,72 @@ npm install -g playwright-core
287
340
  npx playwright install chromium
288
341
  ```
289
342
 
343
+ ## Windows
344
+
345
+ claude-carbon is bash, and stays bash on Windows. That is deliberate rather than a
346
+ shortcut: on native Windows, Claude Code runs status line and hook commands through
347
+ the bash that ships with [Git for Windows](https://git-scm.com/downloads/win), falling
348
+ back to PowerShell only when Git Bash is absent
349
+ ([status line docs](https://code.claude.com/docs/en/statusline#windows-configuration),
350
+ [hooks docs](https://code.claude.com/docs/en/hooks)). The plugin speaks the shell its
351
+ host already spawns.
352
+
353
+ **Native Windows.** Install Git for Windows, plus the two commands it does not ship:
354
+
355
+ ```powershell
356
+ winget install Git.Git --source winget
357
+ winget install jqlang.jq --source winget
358
+ winget install SQLite.SQLite --source winget
359
+ ```
360
+
361
+ Then, in the same terminal:
362
+
363
+ ```powershell
364
+ irm https://raw.githubusercontent.com/gwittebolle/claude-carbon/main/install.ps1 | iex
365
+ ```
366
+
367
+ Everything else the plugin needs - `bash`, `awk`, `sed`, `grep`, `date`, `curl`,
368
+ `git`, `cygpath` - comes with Git for Windows.
369
+
370
+ **WSL 2.** Nothing special: run the `curl | bash` installer inside your distribution.
371
+ Claude Code, its transcripts and claude-carbon all live on the Linux side. This is
372
+ the path to pick if your projects are already in WSL. VS Code reaches it through the
373
+ Remote - WSL extension.
374
+
375
+ **Marketplace install.** `/plugin install claude-carbon@claude-carbon` behaves the
376
+ same as on macOS, once Git for Windows, `jq` and `sqlite3` are present.
377
+
378
+ ### Windows specifics
379
+
380
+ - **Git Bash is required.** Without it Claude Code routes commands to PowerShell,
381
+ which cannot run a `.sh` file. `claude doctor` tells you which shell it picked. If
382
+ Git is installed somewhere unusual, point Claude Code at it in `settings.json`:
383
+ `{"env": {"CLAUDE_CODE_GIT_BASH_PATH": "C:\\Program Files\\Git\\bin\\bash.exe"}}`.
384
+ - **Paths in `settings.json` use forward slashes** (`C:/Users/you/code/claude-carbon/...`).
385
+ Git Bash eats unquoted backslashes, and the command then fails with no visible error.
386
+ The installer writes them correctly; only hand-edits need the care.
387
+ - **Slash commands are copied, not symlinked.** Git Bash cannot create a real symlink
388
+ without Developer Mode, so `/carbon-report` and friends are copied into
389
+ `~/.claude/commands/` and refreshed on every update.
390
+ - **Sandboxing is not available** on native Windows (a Claude Code limitation, not
391
+ this plugin's). Use WSL 2 if you need it.
392
+ - **`/carbon-card` additionally needs Node.js**: `winget install OpenJS.NodeJS --source winget`.
393
+ - **Behind a TLS-inspecting proxy or antivirus**, the clone fails with
394
+ `SSL certificate problem: unable to get local issuer certificate`. Git for Windows
395
+ checks certificates against its own bundled CA list, which does not know the root
396
+ such tools re-sign traffic with; the Windows certificate store does. Switch git to
397
+ it (verification stays on) and rerun the installer:
398
+ `git config --global http.sslBackend schannel`. The installer prints this hint
399
+ when it detects the case. The same interception is why `winget` needs
400
+ `--source winget` on those machines: the Microsoft Store source fails its
401
+ certificate check and, without an explicit source, winget aborts instead of
402
+ falling back.
403
+
404
+ CI runs the full test suite on `windows-latest` under Git Bash, alongside Ubuntu,
405
+ plus two Windows-only suites: `tests/run-windows-e2e.sh` (native paths through the Stop
406
+ hook and the status line, hook manifests spawned the way Claude Code spawns them) and
407
+ `tests/run-install-ps1-tests.ps1`.
408
+
290
409
  ## Reduce your footprint
291
410
 
292
411
  Measuring is step one. Here are concrete levers to reduce your AI carbon footprint, ranked by impact.
@@ -6,11 +6,45 @@
6
6
  "use strict";
7
7
 
8
8
  const { spawnSync } = require("node:child_process");
9
- const { mkdtempSync, writeFileSync } = require("node:fs");
9
+ const { existsSync, mkdtempSync, writeFileSync } = require("node:fs");
10
10
  const { tmpdir } = require("node:os");
11
11
  const { join } = require("node:path");
12
12
  const pkg = require("../package.json");
13
13
 
14
+ // The installer, the hooks and the status line are all bash. On macOS and Linux
15
+ // that is simply "bash"; on Windows it is the bash.exe that ships with Git for
16
+ // Windows, which is also the shell Claude Code itself spawns for hooks and the
17
+ // status line. Returns null when nothing usable is found.
18
+ function findBash() {
19
+ if (process.platform !== "win32") return "bash";
20
+
21
+ const candidates = [
22
+ // Same variable Claude Code reads, so a user who already pointed Claude Code
23
+ // at a non-default Git install does not have to say it twice.
24
+ process.env.CLAUDE_CODE_GIT_BASH_PATH,
25
+ join(process.env.ProgramFiles || "C:\\Program Files", "Git", "bin", "bash.exe"),
26
+ join(process.env["ProgramFiles(x86)"] || "C:\\Program Files (x86)", "Git", "bin", "bash.exe"),
27
+ join(process.env.LOCALAPPDATA || "", "Programs", "Git", "bin", "bash.exe"),
28
+ ].filter(Boolean);
29
+
30
+ for (const candidate of candidates) {
31
+ if (existsSync(candidate)) return candidate;
32
+ }
33
+
34
+ // Last resort: ask PATH. C:\Windows\System32\bash.exe is excluded on purpose โ€”
35
+ // that one is the WSL launcher, and running the installer through it would set
36
+ // claude-carbon up inside the Linux distribution instead of on Windows.
37
+ const where = spawnSync("where.exe", ["bash"], { encoding: "utf8" });
38
+ if (where.status === 0 && where.stdout) {
39
+ for (const line of where.stdout.split(/\r?\n/)) {
40
+ const path = line.trim();
41
+ if (path && !/\\System32\\/i.test(path) && existsSync(path)) return path;
42
+ }
43
+ }
44
+
45
+ return null;
46
+ }
47
+
14
48
  const INSTALL_URL =
15
49
  process.env.CLAUDE_CARBON_INSTALL_URL ||
16
50
  "https://raw.githubusercontent.com/gwittebolle/claude-carbon/main/install.sh";
@@ -46,9 +80,14 @@ if (arg !== undefined && arg !== "--dry-run") {
46
80
  }
47
81
 
48
82
  async function main() {
49
- if (process.platform === "win32") {
83
+ const bash = findBash();
84
+ if (!bash) {
50
85
  console.error(
51
- "claude-carbon needs bash (macOS or Linux); Windows is not supported yet.",
86
+ "claude-carbon runs on bash. On Windows that means Git for Windows, which\n" +
87
+ "Claude Code also uses for its own Bash tool.\n\n" +
88
+ " Install it: winget install Git.Git\n" +
89
+ " Or, if it is already installed somewhere unusual, point at it:\n" +
90
+ ' set CLAUDE_CODE_GIT_BASH_PATH="C:\\Program Files\\Git\\bin\\bash.exe"',
52
91
  );
53
92
  process.exit(1);
54
93
  }
@@ -73,9 +112,9 @@ async function main() {
73
112
  process.exit(0);
74
113
  }
75
114
 
76
- const { status, error } = spawnSync("bash", [file], { stdio: "inherit" });
115
+ const { status, error } = spawnSync(bash, [file], { stdio: "inherit" });
77
116
  if (error) {
78
- console.error(`Could not run bash: ${error.message}`);
117
+ console.error(`Could not run ${bash}: ${error.message}`);
79
118
  process.exit(1);
80
119
  }
81
120
  process.exit(status ?? 1);
package/package.json CHANGED
@@ -1,7 +1,11 @@
1
1
  {
2
2
  "name": "claude-carbon",
3
- "version": "1.3.0",
3
+ "version": "1.7.0",
4
4
  "description": "Track the carbon footprint of your Claude Code sessions",
5
+ "scripts": {
6
+ "diagram": "node docs/render-diagram.mjs",
7
+ "diagram:png": "node docs/render-diagram.mjs --png"
8
+ },
5
9
  "bin": {
6
10
  "claude-carbon": "bin/claude-carbon.js"
7
11
  },
@@ -17,12 +21,20 @@
17
21
  "author": "Gaetan Wittebolle (https://github.com/gwittebolle)",
18
22
  "license": "MIT",
19
23
  "keywords": [
24
+ "claude-carbon",
20
25
  "carbon-footprint",
26
+ "carbon-emissions",
27
+ "co2",
28
+ "co2-tracker",
21
29
  "sustainability",
30
+ "green-it",
31
+ "green-ai",
22
32
  "claude-code",
33
+ "claude-code-plugin",
23
34
  "claude",
24
- "green-it",
25
- "co2"
35
+ "anthropic",
36
+ "statusline",
37
+ "llm"
26
38
  ],
27
39
  "engines": {
28
40
  "node": ">=18"