Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions cli/src/commands/environmental.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*/
import { Command } from 'commander';
import chalk from 'chalk';
import { discoverSessionFiles, calculateDetailedStats, fmt, formatTokens, ENVIRONMENTAL } from '../helpers';
import { discoverSessionFiles, calculateDetailedStats, formatTokens, ENVIRONMENTAL } from '../helpers';
import type { PeriodStats } from '../../../vscode-extension/src/types';

export const environmentalCommand = new Command('environmental')
Expand Down Expand Up @@ -38,7 +38,7 @@ export const environmentalCommand = new Command('environmental')
console.log(chalk.dim('Methodology: Estimates based on industry averages for AI inference'));
console.log(chalk.dim(` CO₂: ${ENVIRONMENTAL.CO2_PER_1K_TOKENS} gCO₂e per 1K tokens`));
console.log(chalk.dim(` Water: ${ENVIRONMENTAL.WATER_USAGE_PER_1K_TOKENS} L per 1K tokens`));
console.log(chalk.dim(` Tree absorption: ${fmt(ENVIRONMENTAL.CO2_ABSORPTION_PER_TREE_PER_YEAR)} g CO₂/year\n`));
console.log(chalk.dim(` Tree absorption: ${formatCo2(ENVIRONMENTAL.CO2_ABSORPTION_PER_TREE_PER_YEAR)} CO₂/year\n`));

for (const period of periods) {
printEnvironmentalStats(period.label, period.emoji, period.stats);
Expand Down Expand Up @@ -75,6 +75,14 @@ export const environmentalCommand = new Command('environmental')
console.log(chalk.dim(`Last updated: ${stats.lastUpdated.toLocaleString()}\n`));
});

/** Format CO₂ in grams, switching to kg notation when ≥ 1 000 g */
function formatCo2(grams: number): string {
if (grams >= 1000) {
return `${(grams / 1000).toFixed(2)} kgCO₂e`;
}
return `${grams.toFixed(3)} gCO₂e`;
}

function printEnvironmentalStats(label: string, emoji: string, stats: PeriodStats): void {
console.log(chalk.bold(`${emoji} ${label}`));
console.log(chalk.dim('─'.repeat(55)));
Expand All @@ -86,7 +94,7 @@ function printEnvironmentalStats(label: string, emoji: string, stats: PeriodStat
}

console.log(` Tokens used: ${chalk.bold.yellow(formatTokens(stats.tokens))}`);
console.log(` CO₂ emissions: ${chalk.bold(stats.co2.toFixed(3))} gCO₂e`);
console.log(` CO₂ emissions: ${chalk.bold(formatCo2(stats.co2))}`);
console.log(` Water usage: ${chalk.bold(stats.waterUsage.toFixed(3))} liters`);

if (stats.treesEquivalent > 0) {
Expand Down
16 changes: 12 additions & 4 deletions vscode-extension/src/webview/environmental/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,14 @@ function smartFixed(value: number): string {
return formatFixed(Math.round(value), 0);
}

/** Format CO₂ in grams, switching to kg notation when ≥ 1 000 g */
function formatCo2Grams(grams: number): string {
if (grams >= 1000) {
return `${smartFixed(grams / 1000)} kg`;
}
return `${smartFixed(grams)} g`;
}

type AnalogyItem = { icon: string; text: string };

const co2AnalogyItems = (grams: number): AnalogyItem[] => [
Expand Down Expand Up @@ -188,10 +196,10 @@ function buildImpactCards(
],
// CO₂ card
[
['📅 Today', `${smartFixed(stats.today.co2)} g`, co2AnalogyItems(stats.today.co2)],
['📈 Last 30 Days', `${smartFixed(stats.last30Days.co2)} g`, co2AnalogyItems(stats.last30Days.co2)],
['📆 Previous Month', `${smartFixed(stats.lastMonth.co2)} g`, co2AnalogyItems(stats.lastMonth.co2)],
['🌍 Projected Year', `${smartFixed(projectedCo2)} g`, co2AnalogyItems(projectedCo2)],
['📅 Today', formatCo2Grams(stats.today.co2), co2AnalogyItems(stats.today.co2)],
['📈 Last 30 Days', formatCo2Grams(stats.last30Days.co2), co2AnalogyItems(stats.last30Days.co2)],
['📆 Previous Month', formatCo2Grams(stats.lastMonth.co2), co2AnalogyItems(stats.lastMonth.co2)],
['🌍 Projected Year', formatCo2Grams(projectedCo2), co2AnalogyItems(projectedCo2)],
],
// Water card
[
Expand Down
Loading