carbon-report
Display CO2 emissions report for Claude Code sessions
Install this skill
Security score
The carbon-report skill was audited on Sep 16, 2026 and we found 21 security issues across 1 threat category. Review the findings below before installing.
Categories Tested
Security Issues
Command substitution pattern
| 21 | esac |
| 22 | } |
| 23 | CFG="$(ccp "${CLAUDE_CONFIG_DIR:-$HOME/.claude}")" |
| 24 | REPO_DIR="" |
| 25 | if command -v jq >/dev/null 2>&1 && [ -f "$CFG/settings.json" ]; then |
Command substitution pattern
| 24 | REPO_DIR="" |
| 25 | if command -v jq >/dev/null 2>&1 && [ -f "$CFG/settings.json" ]; then |
| 26 | SL_CMD="$(jq -r '.statusLine.command // empty' "$CFG/settings.json" 2>/dev/null)" |
| 27 | # statusLine.command stores a shell-escaped path: expand ~ and unescape spaces |
| 28 | SL_CMD="${SL_CMD//\\ / }"; SL_CMD="${SL_CMD/#\~/$HOME}"; SL_CMD="$(ccp "$SL_CMD")" |
Command substitution pattern
| 26 | SL_CMD="$(jq -r '.statusLine.command // empty' "$CFG/settings.json" 2>/dev/null)" |
| 27 | # statusLine.command stores a shell-escaped path: expand ~ and unescape spaces |
| 28 | SL_CMD="${SL_CMD//\\ / }"; SL_CMD="${SL_CMD/#\~/$HOME}"; SL_CMD="$(ccp "$SL_CMD")" |
| 29 | [ -n "$SL_CMD" ] && [ -f "$SL_CMD" ] && REPO_DIR="$(cd "$(dirname "$SL_CMD")/.." 2>/dev/null && pwd)" |
| 30 | fi |
Command substitution pattern
| 27 | # statusLine.command stores a shell-escaped path: expand ~ and unescape spaces |
| 28 | SL_CMD="${SL_CMD//\\ / }"; SL_CMD="${SL_CMD/#\~/$HOME}"; SL_CMD="$(ccp "$SL_CMD")" |
| 29 | [ -n "$SL_CMD" ] && [ -f "$SL_CMD" ] && REPO_DIR="$(cd "$(dirname "$SL_CMD")/.." 2>/dev/null && pwd)" |
| 30 | fi |
| 31 | [ -z "$REPO_DIR" ] && [ -n "${CLAUDE_PLUGIN_ROOT:-}" ] && REPO_DIR="$(ccp "$CLAUDE_PLUGIN_ROOT")" |
Command substitution pattern
| 29 | [ -n "$SL_CMD" ] && [ -f "$SL_CMD" ] && REPO_DIR="$(cd "$(dirname "$SL_CMD")/.." 2>/dev/null && pwd)" |
| 30 | fi |
| 31 | [ -z "$REPO_DIR" ] && [ -n "${CLAUDE_PLUGIN_ROOT:-}" ] && REPO_DIR="$(ccp "$CLAUDE_PLUGIN_ROOT")" |
| 32 | [ -z "$REPO_DIR" ] && [ -n "${CLAUDE_CARBON_DIR:-}" ] && REPO_DIR="$(ccp "$CLAUDE_CARBON_DIR")" |
| 33 | if [ -z "$REPO_DIR" ]; then |
Command substitution pattern
| 30 | fi |
| 31 | [ -z "$REPO_DIR" ] && [ -n "${CLAUDE_PLUGIN_ROOT:-}" ] && REPO_DIR="$(ccp "$CLAUDE_PLUGIN_ROOT")" |
| 32 | [ -z "$REPO_DIR" ] && [ -n "${CLAUDE_CARBON_DIR:-}" ] && REPO_DIR="$(ccp "$CLAUDE_CARBON_DIR")" |
| 33 | if [ -z "$REPO_DIR" ]; then |
| 34 | # Pure marketplace installs reach here: settings.json carries no statusLine.command |
Command substitution pattern
| 39 | for D in "$CFG/plugins/cache"/*/claude-carbon/*/; do |
| 40 | [ -f "${D}scripts/equiv-lib.sh" ] || continue |
| 41 | if [ -z "$CACHE_LATEST" ] || [ "$(printf '%s\n%s\n' "$CACHE_LATEST" "$D" | sort -V | tail -1)" = "$D" ]; then |
| 42 | CACHE_LATEST="$D" |
| 43 | fi |
Command substitution pattern
| 56 | # the factors are country-specific (a French car and a US car differ by ~1.7x). |
| 57 | . "$REPO_DIR/scripts/equiv-lib.sh" |
| 58 | EQUIV_SET="$(detect_equiv_set)" |
| 59 | |
| 60 | # Force C locale: comma-decimal locales (de_DE, fr_FR) make awk mis-parse |
Command substitution pattern
| 62 | export LC_ALL=C |
| 63 | |
| 64 | DB_PATH="$(ccp "${CLAUDE_CARBON_DB:-${CLAUDE_CONFIG_DIR:-$HOME/.claude}/claude-carbon/carbon.db}")" |
| 65 | |
| 66 | if [ ! -f "$DB_PATH" ]; then |
Command substitution pattern
| 71 | |
| 72 | CURRENT_YEAR="$(date +%Y)" |
| 73 | TODAY="$(date +%Y-%m-%d)" |
| 74 | |
| 75 | # Ensure the excluded column exists on pre-existing DBs (idempotent). |
Command substitution pattern
| 79 | |
| 80 | # --- Aggregates --- |
| 81 | TODAY_CO2="$(sqlite3 "$DB_PATH" "SELECT COALESCE(SUM(co2_grams), 0) FROM sessions WHERE ${NOT_EXCLUDED} AND started_at LIKE '${TODAY}%';" | awk '{printf "%.1f", $1}')" |
| 82 | TODAY_SESSIONS="$(sqlite3 "$DB_PATH" "SELECT COUNT(*) FROM sessions WHERE ${NOT_EXCLUDED} AND started_at LIKE '${TODAY}%';")" |
| 83 |
Command substitution pattern
| 80 | # --- Aggregates --- |
| 81 | TODAY_CO2="$(sqlite3 "$DB_PATH" "SELECT COALESCE(SUM(co2_grams), 0) FROM sessions WHERE ${NOT_EXCLUDED} AND started_at LIKE '${TODAY}%';" | awk '{printf "%.1f", $1}')" |
| 82 | TODAY_SESSIONS="$(sqlite3 "$DB_PATH" "SELECT COUNT(*) FROM sessions WHERE ${NOT_EXCLUDED} AND started_at LIKE '${TODAY}%';")" |
| 83 | |
| 84 | YEAR_CO2="$(sqlite3 "$DB_PATH" "SELECT COALESCE(SUM(co2_grams), 0) FROM sessions WHERE ${NOT_EXCLUDED} AND started_at LIKE '${CURRENT_YEAR}%';" | awk '{printf "%.1f", $1}')" |
Command substitution pattern
| 82 | TODAY_SESSIONS="$(sqlite3 "$DB_PATH" "SELECT COUNT(*) FROM sessions WHERE ${NOT_EXCLUDED} AND started_at LIKE '${TODAY}%';")" |
| 83 | |
| 84 | YEAR_CO2="$(sqlite3 "$DB_PATH" "SELECT COALESCE(SUM(co2_grams), 0) FROM sessions WHERE ${NOT_EXCLUDED} AND started_at LIKE '${CURRENT_YEAR}%';" | awk '{printf "%.1f", $1}')" |
| 85 | YEAR_SESSIONS="$(sqlite3 "$DB_PATH" "SELECT COUNT(*) FROM sessions WHERE ${NOT_EXCLUDED} AND started_at LIKE '${CURRENT_YEAR}%';")" |
| 86 |
Command substitution pattern
| 83 | |
| 84 | YEAR_CO2="$(sqlite3 "$DB_PATH" "SELECT COALESCE(SUM(co2_grams), 0) FROM sessions WHERE ${NOT_EXCLUDED} AND started_at LIKE '${CURRENT_YEAR}%';" | awk '{printf "%.1f", $1}')" |
| 85 | YEAR_SESSIONS="$(sqlite3 "$DB_PATH" "SELECT COUNT(*) FROM sessions WHERE ${NOT_EXCLUDED} AND started_at LIKE '${CURRENT_YEAR}%';")" |
| 86 | |
| 87 | ALL_CO2="$(sqlite3 "$DB_PATH" "SELECT COALESCE(SUM(co2_grams), 0) FROM sessions WHERE ${NOT_EXCLUDED};" | awk '{printf "%.1f", $1}')" |
Command substitution pattern
| 85 | YEAR_SESSIONS="$(sqlite3 "$DB_PATH" "SELECT COUNT(*) FROM sessions WHERE ${NOT_EXCLUDED} AND started_at LIKE '${CURRENT_YEAR}%';")" |
| 86 | |
| 87 | ALL_CO2="$(sqlite3 "$DB_PATH" "SELECT COALESCE(SUM(co2_grams), 0) FROM sessions WHERE ${NOT_EXCLUDED};" | awk '{printf "%.1f", $1}')" |
| 88 | ALL_SESSIONS="$(sqlite3 "$DB_PATH" "SELECT COUNT(*) FROM sessions WHERE ${NOT_EXCLUDED};")" |
| 89 | ALL_COST="$(sqlite3 "$DB_PATH" "SELECT COALESCE(SUM(cost_usd), 0) FROM sessions WHERE ${NOT_EXCLUDED};" | awk '{printf "%.2f", $1}')" |
Command substitution pattern
| 86 | |
| 87 | ALL_CO2="$(sqlite3 "$DB_PATH" "SELECT COALESCE(SUM(co2_grams), 0) FROM sessions WHERE ${NOT_EXCLUDED};" | awk '{printf "%.1f", $1}')" |
| 88 | ALL_SESSIONS="$(sqlite3 "$DB_PATH" "SELECT COUNT(*) FROM sessions WHERE ${NOT_EXCLUDED};")" |
| 89 | ALL_COST="$(sqlite3 "$DB_PATH" "SELECT COALESCE(SUM(cost_usd), 0) FROM sessions WHERE ${NOT_EXCLUDED};" | awk '{printf "%.2f", $1}')" |
| 90 |
Command substitution pattern
| 87 | ALL_CO2="$(sqlite3 "$DB_PATH" "SELECT COALESCE(SUM(co2_grams), 0) FROM sessions WHERE ${NOT_EXCLUDED};" | awk '{printf "%.1f", $1}')" |
| 88 | ALL_SESSIONS="$(sqlite3 "$DB_PATH" "SELECT COUNT(*) FROM sessions WHERE ${NOT_EXCLUDED};")" |
| 89 | ALL_COST="$(sqlite3 "$DB_PATH" "SELECT COALESCE(SUM(cost_usd), 0) FROM sessions WHERE ${NOT_EXCLUDED};" | awk '{printf "%.2f", $1}')" |
| 90 | |
| 91 | # --- Equivalences (all-time total) --- |
Command substitution pattern
| 95 | # the world average: a car, a kWh and a kilo of beef each differ by 2x+ between |
| 96 | # countries, so a single set would be wrong for most readers. |
| 97 | EQUIV_ROWS="$(jq -r --arg set "$EQUIV_SET" \ |
| 98 | '.equivalences[$set][] | "\(.divisor)|\(.decimals)|\(.label)|\(.source)"' "$FACTORS_FILE" \ |
| 99 | | while IFS='|' read -r divisor decimals label source; do |
Command substitution pattern
| 98 | '.equivalences[$set][] | "\(.divisor)|\(.decimals)|\(.label)|\(.source)"' "$FACTORS_FILE" \ |
| 99 | | while IFS='|' read -r divisor decimals label source; do |
| 100 | count="$(echo "$ALL_CO2" | awk -v d="$divisor" -v p="$decimals" '{ fmt = "%." p "f"; printf fmt, $1 / d }')" |
| 101 | printf '%s|%s|%s\n' "$count" "$label" "$source" |
| 102 | done)" |
Command substitution pattern
| 108 | |
| 109 | # --- Top 5 sessions by CO2 --- |
| 110 | TOP5="$(sqlite3 -separator '|' "$DB_PATH" \ |
| 111 | "SELECT DATE(started_at), project, ROUND(co2_grams, 2), model, ROUND(cost_usd, 4) |
| 112 | FROM sessions |
Command substitution pattern
| 116 | |
| 117 | # --- By project --- |
| 118 | BY_PROJECT="$(sqlite3 -separator '|' "$DB_PATH" \ |
| 119 | "SELECT project, ROUND(SUM(co2_grams), 2), COUNT(*), ROUND(SUM(cost_usd), 4) |
| 120 | FROM sessions |