Local TypeScript dashboard that reads Codex and Claude Code usage artifacts from your machine and helps you understand coding-agent activity with token, water, energy, and carbon estimates.
Requires Node 18+.
npx agentic-insights@0.2.0That command starts a local server, opens the dashboard in your browser, and reads local coding-agent usage from your own machine.
If you want a reusable command instead:
npm install -g agentic-insights
agentic-insightsSupported launcher flags:
agentic-insights --port 3001 --host 127.0.0.1
agentic-insights --codex-home /path/to/.codex
agentic-insights --no-opennpm install
npm run dev- Frontend:
http://localhost:5173 - API:
http://localhost:3001
By default the backend reads:
~/.codex/sessions~/.codex/archived_sessions~/.codex/log/codex-tui.log~/.claude/projects~/.claude/usage-data/session-meta
You can override the Codex home directory with CODEX_HOME=/path/to/.codex or agentic-insights --codex-home /path/to/.codex. Claude Code usage is read from the default ~/.claude home for the current user.
- Total token usage
- Total estimated water usage with low, central, and high bounds
- Total estimated energy usage
- Total estimated operational carbon usage
- Water, energy, or carbon usage aggregated by day, week, or month
- Coverage information for supported, excluded, and unestimated usage
For each session file the backend reads only the fields needed for this dashboard:
session_metaturn_contextevent_msgwherepayload.type === "token_count"
The parser treats total_token_usage.total_tokens as a cumulative session total and converts it into per-event deltas.
If last_token_usage is present, those split token counts are used directly.
If last_token_usage is missing but total_token_usage.{input,output,cached_input} is present, the backend derives split counts from differences between consecutive cumulative totals.
If a session has no usable total_token_usage rows at all, the backend can still recover token totals from codex-tui.log, but those events are marked token_only because split token counts are unavailable.
For Claude Code usage, the backend reads assistant message usage rows from ~/.claude/projects/*.jsonl and converts those into per-message token events. If a Claude session has no usable per-message rows, the backend can fall back to ~/.claude/usage-data/session-meta/*.json for a session-level summary event.
The UI does not show USD, but the app uses a bundled pricing snapshot generated from Portkey's MIT-licensed models catalog as a stable weighting proxy for relative inference intensity [3-8].
The runtime stays offline-safe for npx users. Pricing data is refreshed by maintainers with:
npm run sync:pricingFor each supported event:
eventCostUsd =
inputTokens / 1,000,000 * inputPrice
+ cachedInputTokens / 1,000,000 * cachedInputPrice
+ outputTokens / 1,000,000 * outputPrice
The app bundles the generated Portkey snapshot rather than maintaining a small handwritten table in the repo. The live UI exposes the current priced model catalog, and maintainers can refresh it with npm run sync:pricing.
Absolute litres per token are not observable from local coding-agent logs.
So the app creates a local reference event cost on first run:
referenceEventCostUsd = median(eventCostUsd)
This median is computed across all supported positive-usage events found in your local history and persisted to:
- Linux:
~/.cache/agentic-insights/calibration.json - macOS:
~/Library/Caches/agentic-insights/calibration.json - Windows:
%LOCALAPPDATA%\agentic-insights\calibration.json
You can override the cache location with AGENTIC_INSIGHTS_CACHE_DIR=/path/to/cache.
This makes the dashboard stable across refreshes while still being anchored to the token mix in your own logs.
The app uses three benchmark coefficients taken from Li, Yang, Islam, and Ren's "Making AI Less 'Thirsty'" benchmark discussion [1,2].
These values come from the paper's "total water for each request" benchmarks for a GPT-3 medium-sized request with 10 input tokens and 50 output tokens:
- Low:
0.010585 Lfrom Georgia - Central:
0.016904 Lfrom the U.S. average - High:
0.029926 Lfrom Arizona
For each supported event:
lowLitres = eventCostUsd / referenceEventCostUsd * 0.010585
centralLitres = eventCostUsd / referenceEventCostUsd * 0.016904
highLitres = eventCostUsd / referenceEventCostUsd * 0.029926
In this app, those literature values act as low, central, and high benchmark anchors after pricing-weighted usage has been normalized by your local median event.
They are not a physical measurement from your machine.
Energy uses the same normalized eventCostUsd / referenceEventCostUsd multiplier as water, but applies a single benchmark request energy of 0.004 kWh [1,2,9].
For each supported event:
energyKwh = eventCostUsd / referenceEventCostUsd * 0.004
This keeps the energy estimate consistent with the water estimate while avoiding a made-up uncertainty band. The number is still directional rather than a direct watt-hour reading from your device or the remote data center [10].
Carbon starts with the same benchmarked energy estimate and applies a single global electricity emissions factor of 0.445 kg CO2/kWh from the IEA's 2024 global average electricity intensity [11,12].
For each supported event:
carbonKgCo2 = energyKwh * 0.445
Equivalently:
carbonKgCo2 = eventCostUsd / referenceEventCostUsd * 0.00178
where 0.00178 kg CO2 is the carbon footprint of the benchmark 0.004 kWh request after applying the same global factor.
This is an operational electricity-related CO2 estimate for supported inference activity. It is not a direct meter reading, and it is not a full lifecycle footprint for chip fabrication, data-center construction, or end-user device manufacturing [11,12].
The app intentionally does not guess when it lacks enough information.
Excluded from water, energy, and carbon totals:
- Unsupported providers and models, such as local
ollamasessions token_onlyfallback events recovered from TUI totals without split token counts
These still appear in token totals and coverage summaries so the dashboard stays honest about what is and is not estimated.
The dashboard is exact about tokens, but estimated about water, energy, and carbon.
The main uncertainty comes from three places:
- OpenAI price ratios are being used as a compute-intensity proxy, not as billed spend shown to the user
- The local median calibration step is a normalization choice, not a physical measurement
- The water low/central/high coefficients, the
0.004 kWhenergy anchor, and the0.445 kg CO2/kWhcarbon factor are literature and standards-based anchors reused as normalized defaults for coding-agent events [1,2,9,10,11,12]
GET /api/overviewGET /api/timeseries?bucket=day|week|month&tz=Europe/LondonGET /api/methodology
tz should be an IANA timezone such as Europe/London or America/Los_Angeles. The frontend sends the browser timezone so day/week/month aggregation follows the user's local calendar boundaries.
npm run sync:pricing
npm run lint
npm run test
npm run build
npm run test:packReleases are cut from GitHub Actions on tags like v0.2.0.
The release workflow:
- Runs
npm run lint,npm run test,npm run build, andnpm run test:pack - Publishes
agentic-insightsto npm withNPM_TOKENif provided, otherwise with trusted publishing and provenance - Generates a scoped mirror package and publishes
@max-stoddard/agentic-insightsto GitHub Packages - Creates a GitHub Release from
.github/release-notes/vX.Y.Z.md
Before cutting a release:
- For the first npm publish of
agentic-insights, add theNPM_TOKENGitHub Actions secret for the npm account that will own the package - Add a matching release notes file at
.github/release-notes/vX.Y.Z.md - Run the release workflow for the existing tag from GitHub Actions using the
tag_nameinput, or push a fresh release tag - After the first successful npm publish, configure npm trusted publishing for
max-stoddard/agentic-insightsand.github/workflows/release.yml, then removeNPM_TOKEN - Verify
@max-stoddard/agentic-insightsis available on GitHub Packages
[1] Li P, Yang J, Islam MA, Ren S. Making AI Less "Thirsty". Commun ACM. 2025;68(7):54-61. doi:10.1145/3724499
[2] Li P, Yang J, Islam MA, Ren S. Making AI Less "Thirsty": Uncovering and Addressing the Secret Water Footprint of AI Models [Internet]. arXiv:2304.03271; 2023 [cited 2026 Mar 9]. Available from: https://arxiv.org/abs/2304.03271
[3] OpenAI. Pricing [Internet]. 2026 [cited 2026 Mar 9]. Available from: https://openai.com/api/pricing/
[4] OpenAI. GPT-5.1-Codex Mini model [Internet]. 2026 [cited 2026 Mar 9]. Available from: https://developers.openai.com/api/docs/models/gpt-5.1-codex-mini
[5] OpenAI. GPT-5.1-Codex Max model [Internet]. 2026 [cited 2026 Mar 9]. Available from: https://developers.openai.com/api/docs/models/gpt-5.1-codex-max
[6] OpenAI. GPT-5.2-Codex model [Internet]. 2026 [cited 2026 Mar 9]. Available from: https://developers.openai.com/api/docs/models/gpt-5.2-codex
[7] OpenAI. GPT-5.3-Codex model [Internet]. 2026 [cited 2026 Mar 9]. Available from: https://developers.openai.com/api/docs/models/gpt-5.3-codex
[8] OpenAI. GPT-5.4 model [Internet]. 2026 [cited 2026 Mar 9]. Available from: https://developers.openai.com/api/docs/models/gpt-5.4
[9] Brown T, Mann B, Ryder N, et al. Language Models are Few-Shot Learners. Adv Neural Inf Process Syst. 2020;33:1877-1901. Available from: https://papers.nips.cc/paper/2020/file/1457c0d6bfcb4967418bfb8ac142f64a-Paper.pdf
[10] Luccioni AS, Luccioni A, Dumas M, et al. Estimating the Carbon Footprint of BLOOM, a 176B Parameter Language Model. J Mach Learn Res. 2023;24(253):1-15. Available from: https://jmlr.org/papers/v24/23-0069.html
[11] International Energy Agency. Electricity 2025: Emissions [Internet]. 2025 [cited 2026 Mar 15]. Available from: https://www.iea.org/reports/electricity-2025/emissions
[12] GHG Protocol. Scope 2 Guidance [Internet]. [cited 2026 Mar 15]. Available from: https://ghgprotocol.org/scope_2_guidance