English · 简体中文
Ledger is an open-source, local-first usage analytics dashboard for Codex. It turns the usage telemetry already persisted on your machine into a clear view of tokens, projects, models, sessions, per-turn context growth, cache efficiency, trends, and observed quota windows.
No Ledger account. No cloud backend. No telemetry.
Recommended: install Ledger for Codex as a Plugin and ask Codex to open or analyze your local usage. Prefer a plain script? Clone the repo and run one Python command.
| Question | Ledger shows you |
|---|---|
| How much have I used? | Total observable tokens + period comparison |
| Am I consuming too fast? | Burn rate + observed quota-window pacing |
| Where did it go? | Project, model, and model × project breakdowns |
| Why was a session so large? | Tokens / turn, context growth, peak turn, cache reuse, and transparent drivers |
| What changed? | Previous-period deltas + rule-based usage insights |
| Is the data leaving my machine? | No. Parsing and reports are local by default |
The screenshot uses synthetic demo data. Ledger does not ship anyone's real usage history.
Codex can do a lot of work, but the raw usage trail is hard to reason about at a glance.
| Without Ledger | With Ledger |
|---|---|
| “Where did my usage go?” | Project and model attribution |
| “Why was this session so large?” | Session health, context growth, peak turn, and transparent drivers |
| “Is today unusual?” | Burn rate, outliers, and previous-period comparison |
| “Did cache help?” | Cache hit and cached / uncached input breakdown |
| “How much quota is left?” | Observed 5-hour / weekly snapshots when Codex persisted them |
Ledger does not invent an account quota from token totals. If Codex did not persist a rate-limit snapshot, the quota cards say it is unavailable.
|
|
|
|
Ledger is packaged as a portable Agent Plugin with a bundled ledger-analysis Skill. No MCP server or external account is required in v0.2.
codex plugin marketplace add ctdaniel/codex-ledgerOpen the Plugin directory in ChatGPT desktop or Codex CLI, choose the Ledger for Codex marketplace, and install Ledger for Codex. In Codex CLI, use /plugins to open the plugin browser.
Start a new session after installation if the new Skill does not appear immediately. The Codex IDE extension does not currently provide the plugin browser, so use ChatGPT desktop or Codex CLI for installation.
Open my Codex usage dashboard.
Analyze my Codex usage for the last 7 days.
Show me my 5 most expensive Codex tasks.
The bundled Skill runs the local parser, starts the private local dashboard, and can analyze the sanitized normalized payload without dumping raw rollout logs into the conversation.
Plugin installation behavior can vary by supported client. The marketplace command and package format follow the current OpenAI Plugin documentation. The direct local method below remains available even when a client does not expose Plugins.
The codex terminal command comes from Codex CLI. Installing Ledger from ChatGPT desktop does not automatically install the CLI on your shell.
Check whether Codex CLI is available:
command -v codex
codex --versionIf your terminal says codex: command not found, install the current Codex CLI on macOS / Linux with OpenAI's installer:
curl -fsSL https://chatgpt.com/codex/install.sh | shThen open a new terminal and verify:
codex --versionRefresh the Ledger marketplace snapshot:
codex plugin marketplace upgrade codex-ledgerYou can inspect configured marketplaces first if needed:
codex plugin marketplace listAfter upgrading, start Codex, open /plugins, confirm Ledger for Codex is installed, then start a new session so the updated Skill is loaded.
If Ledger was installed through a workspace-synced GitHub marketplace, an admin can instead use Workspace settings → Plugins → Marketplaces → Sync now. If an individually imported plugin shows a Refresh action, that action refreshes the plugin source.
cd codex-ledger
git pull
python3 scripts/ledger.py --openLedger has no npm dependencies and no build step. Python 3 parses your local Codex session telemetry and serves the dashboard on 127.0.0.1. With --open, the Refresh data button rescans ~/.codex immediately — no model call and no Codex quota is used for the refresh itself.
git clone https://github.com/ctdaniel/codex-ledger.git
cd codex-ledger
python3 scripts/ledger.py --openWith --open, Ledger:
- reads
$CODEX_HOMEor~/.codex, - scans the most recent 90 days of persisted sessions,
- keeps only normalized usage metadata,
- writes the report to
~/.codex/ledger/latest/, - starts a local-only HTTP server on
127.0.0.1, - opens the dashboard in your browser,
- rescans local Codex telemetry whenever you click Refresh data.
Keep the terminal process running while you use live refresh. Press Ctrl+C to stop it. If you open the generated index.html directly with file://, it is a static snapshot and cannot rescan local files from the browser sandbox.
Useful options:
# Parse all discoverable persisted sessions
python3 scripts/ledger.py --days 0 --open
# Write to a different local directory
python3 scripts/ledger.py --output ./ledger-report --open
# Serve without opening a browser
python3 scripts/ledger.py --serve
# Print the sanitized normalized payload instead of generating a report
python3 scripts/ledger.py --jsonWant to inspect the interface without reading Codex data? Open the repository's index.html; it uses deterministic synthetic demo fixtures.
Use Today / Last 7 days / Last 30 days / Custom and filter by project, task, or model. All derived cards, charts, insights, rankings, and task details recalculate from the same filtered dataset.
Ledger distinguishes three kinds of information:
- Observed — directly present in locally persisted Codex telemetry.
- Calculated — derived locally from observed records.
- Estimated — a forecast or rate-weighted heuristic; never presented as official billing or quota data.
With the Plugin installed, try:
Why was my most expensive Codex session so large?
Which sessions have the fastest context growth?
Did my tokens per turn increase versus the previous period?
Which long sessions also have unusually low cache reuse?
Do I have an observed quota snapshot right now?
The parser currently reads Codex's persisted local rollout JSONL on a best-effort basis. It uses per-request last_token_usage events; it deliberately does not sum cumulative total_token_usage snapshots, which would overcount the same usage repeatedly.
For project attribution, Ledger keeps only the final directory name from cwd. The local report may also include the persisted session/thread title so you can identify tasks.
Ledger is local-first by design.
- ✅ no Ledger account
- ✅ no cloud backend required
- ✅ no telemetry
- ✅ no prompt-body upload
- ✅ no assistant/tool-output upload
- ✅ no code or repository-content upload
- ✅ no API key or auth-file collection
- ✅ full local paths are stripped from the generated report
The generated local dashboard can contain session titles and project-folder basenames because those are needed for useful attribution. They remain on your machine unless you explicitly share the generated report or a screenshot.
The repository's demo data is synthetic. Files matching local report / snapshot patterns are ignored by Git.
Ledger v0.2 intentionally avoids pretending that local telemetry is a formal billing or context-window API.
- Codex's persisted local session format can evolve; the parser is best-effort and covered by fixtures/tests.
- Sessions without persisted
last_token_usageevents cannot contribute token records. - Context Growth uses observed per-turn input tokens as a local proxy; it is not official context-window occupancy.
- Session Health is relative to your own local usage distribution, not an external benchmark or a quality score.
- Quota cards are shown only when a persisted
rate_limitssnapshot is observed. - Refresh data rescans quota snapshots already persisted by Codex; it cannot force Codex to query the account quota service. When an observed reset boundary passes, Ledger hides the old percentage instead of showing a stale value. Use Codex once, then click Refresh data to load the next persisted snapshot.
- Ledger never converts token totals into an invented 5-hour or weekly quota percentage.
- Generation speed appears only when usable duration telemetry is present.
- Model rate-weighted intensity appears only for models with a known built-in mapping; otherwise it is left unavailable.
If Codex changes its local telemetry format, please open an issue with a sanitized schema sample, never a raw session containing private content.
Ledger's repository root is also its portable Agent Plugin package:
codex-ledger/
├── plugin.json # Agent Plugins 1.0 portable manifest
├── .codex-plugin/plugin.json # Codex compatibility fallback
├── skills/
│ └── ledger-analysis/
│ ├── SKILL.md
│ └── references/
├── scripts/
│ └── ledger.py # local, dependency-free parser
├── .agents/plugins/marketplace.json # GitHub marketplace catalog
├── index.html
├── app.css
├── app.js
└── assets/
The Plugin is intentionally Skill-first in v0.2. A local MCP server is not required just to read files already available on your machine and render the dashboard.
Run the checks:
python3 -m unittest discover -s tests -v
node --check app.js
python3 -m json.tool plugin.json >/dev/null
python3 -m json.tool .agents/plugins/marketplace.json >/dev/nullSee CONTRIBUTING.md for contribution guidelines and docs/DESIGN.md for the current interface notes.
- local Codex token parser + live refresh
- project / model / session attribution
- burn rate, cache and period comparison
- tokens / session + tokens / turn
- session context-growth analysis (first vs last turns)
- peak-turn detection + session health using your own baseline
- Session Detail with context-growth chart and transparent drivers
- session-oriented insights
- observed quota snapshots when persisted locally
- bilingual dashboard
- Codex Plugin + Ledger Analysis Skill
- GitHub marketplace packaging
- tool / file / MCP-call observability where local telemetry supports it
- richer parser coverage diagnostics
- exportable privacy-safe reports
- optional local MCP interface if it materially improves the workflow
- additional AI coding-agent adapters
- stronger anomaly detection
No dates promised — contributions are welcome.
Usage visibility should not be a paid feature.
Ledger is free and open so anyone can inspect exactly what is parsed, how metrics are calculated, and what stays local. If the underlying Codex format changes, the community can fix the adapter without waiting for a black box service.
MIT © 2026 Daniel Chen and contributors.
If Ledger makes your Codex usage easier to understand, a ⭐ helps more people find it.
