Skip to content

danmunoz/trmnl-token-meter-cli

TRMNL Token Meter CLI

TRMNL Token Meter display preview

TRMNL Token Meter is a local collector for showing Codex token usage on a TRMNL display.

The CLI runs on your computer, reads local Codex usage records, calculates aggregate token and estimated cost totals, and syncs those totals to your TRMNL Token Meter plugin. It is meant for people who want a private, glanceable meter for how much Codex usage is happening today, this week, and this month.

Privacy is the core design constraint: raw Codex usage content stays on your machine. The CLI does not upload prompts, responses, commands, diffs, file contents, repository names, or file paths. It sends only aggregate totals and status fields needed to render the TRMNL display.

Compatibility

  • Supported OS: macOS and Linux
  • Supported Node: >=22.13.0

The package manifest enforces the OS restriction at install time.

How It Works

  1. The CLI scans local Codex usage files on your machine.
  2. It converts those records into daily, rolling-window, and per-model aggregates.
  3. It uploads only the sanitized aggregate snapshot needed by the TRMNL Token Meter backend.

The collector is designed to be useful without becoming another remote analytics pipe. Raw Codex session content stays local.

Quick Start

  1. Install the TRMNL Token Meter plugin in TRMNL.
  2. Open the plugin management page and generate a pairing code.
  3. Run the CLI on the computer you want to track:
npx trmnl-token-meter
  1. Enter the pairing code, choose a machine name, and use this backend URL when prompted:
https://trmnl-token-meter-backend.trmnltkn.workers.dev

Setup pairs this machine, uploads the first sanitized aggregate snapshot, and installs background sync. After setup, uploads continue automatically on the configured interval.

Install Options

Run directly from npm without a global install:

npx trmnl-token-meter

If you want a persistent local command instead, install from npm:

npm install -g trmnl-token-meter
trmnl-token-meter --version

What Gets Sent

Each upload sends a sanitized aggregate snapshot. The CLI computes this locally before upload. Individual usage records are not sent; only aggregate data, totals, and generic status fields are sent.

Compact representative example:

{
  "schema_version": "2026-05-15.v2-codexbar-cost",
  "machine_id": "mach_abc123",
  "machine_label": "My MacBook",
  "generated_at": "2026-05-18T12:42:57.320Z",
  "periods": {
    "today": {
      "start": "2026-05-18",
      "end": "2026-05-19",
      "input_tokens": 120000,
      "cached_input_tokens": 30000,
      "output_tokens": 42000,
      "total_tokens": 162000,
      "estimated_cost_usd": 1.2345,
      "cost_status": "known",
      "pricing_catalog_version": "2026-05-15.codexbar-parity",
      "warning_codes": []
    },
    "last_7_days": {
      "start": "2026-05-12",
      "end": "2026-05-19",
      "input_tokens": 500000,
      "cached_input_tokens": 130000,
      "output_tokens": 180000,
      "total_tokens": 680000,
      "estimated_cost_usd": 5.4321,
      "cost_status": "known",
      "pricing_catalog_version": "2026-05-15.codexbar-parity",
      "warning_codes": []
    },
    "last_30_days": {
      "start": "2026-04-19",
      "end": "2026-05-19",
      "input_tokens": 1500000,
      "cached_input_tokens": 410000,
      "output_tokens": 620000,
      "total_tokens": 2120000,
      "estimated_cost_usd": 16.789,
      "cost_status": "known",
      "pricing_catalog_version": "2026-05-15.codexbar-parity",
      "warning_codes": []
    }
  },
  "daily": [
    {
      "date": "2026-05-18",
      "start": "2026-05-18",
      "end": "2026-05-19",
      "input_tokens": 120000,
      "cached_input_tokens": 30000,
      "output_tokens": 42000,
      "total_tokens": 162000,
      "estimated_cost_usd": 1.2345,
      "cost_status": "known",
      "pricing_catalog_version": "2026-05-15.codexbar-parity",
      "warning_codes": [],
      "has_usage": true,
      "is_missing": false
    }
  ],
  "models": [
    {
      "name": "gpt-5",
      "input_tokens": 100000,
      "cached_input_tokens": 25000,
      "output_tokens": 36000,
      "total_tokens": 136000,
      "estimated_cost_usd": 1.01,
      "cost_status": "known",
      "pricing_catalog_version": "2026-05-15.codexbar-parity",
      "warning_codes": []
    }
  ],
  "collector": {
    "version": "0.1.0",
    "source": "codexbar-local-cost",
    "codex_home": "default",
    "cost_engine_version": "2026-05-15.codexbar-parity",
    "sources": [
      {
        "kind": "codex_sessions",
        "enabled": true,
        "status": "read",
        "record_count": 42
      }
    ],
    "warnings": []
  }
}

The real upload can include up to 31 daily rows and up to 25 normalized model rows. It does not include raw session records or anything needed to reconstruct your Codex conversations.

What Never Gets Sent

The CLI does not upload:

  • Prompts or responses
  • Tool output
  • Shell commands
  • File contents
  • Diffs
  • Absolute paths
  • Repository names
  • Raw Codex JSONL lines
  • Priority database rows
  • Pi session contents
  • Auth files, browser cookies, API keys, TRMNL secrets, pairing codes, or collector tokens in aggregate uploads

No individual usage data is sent. No raw usage content is analyzed remotely. The private parts of your Codex activity stay local.

Commands

Open setup or the local control menu:

npx trmnl-token-meter

Show current pairing, background sync, and server status:

npx trmnl-token-meter status

Upload one snapshot immediately:

npx trmnl-token-meter sync --once

Add or replace the paired TRMNL meter:

npx trmnl-token-meter add

Revoke this machine and stop background sync:

npx trmnl-token-meter revoke

Remove background sync:

npx trmnl-token-meter uninstall

By default, uninstall keeps local pairing credentials. Use uninstall --revoke if you also want to revoke this machine from the TRMNL meter.

Background Sync

After pairing, the CLI installs a local background job so the display keeps updating without leaving a terminal open.

  • macOS: launchd
  • Linux: systemd when available, otherwise cron

Use npx trmnl-token-meter status to inspect whether background sync is installed and when the last local/server sync completed.

Non-Interactive Setup

For scripts or troubleshooting, pair manually:

npx trmnl-token-meter pair \
  --code ABCD-1234 \
  --machine-label "My MacBook" \
  --api-base-url https://trmnl-token-meter-backend.trmnltkn.workers.dev

Then install background sync:

npx trmnl-token-meter service install

Upload once:

npx trmnl-token-meter upload

Test Locally

To test the CLI from this repository with a persistent local command, install it globally from the repo root:

pnpm install
pnpm build
npm install -g .

Then you can run the CLI directly from later terminal sessions:

trmnl-token-meter --version
trmnl-token-meter setup --api-base-url https://trmnl-token-meter-backend.trmnltkn.workers.dev
trmnl-token-meter status

This is useful for local development and manual testing. The public setup flow still uses npx trmnl-token-meter.

Inspect Before Uploading

Use collect to print the exact sanitized payload locally without uploading:

npx trmnl-token-meter collect

This is the best way to verify what would be sent. The output is the aggregate snapshot, not raw Codex content.

Local Configuration

The collector stores credentials, service metadata, and sync state locally on your machine.

  • CODEX_HOME controls where Codex usage files are read from. Default: ~/.codex
  • TRMNL_TOKEN_METER_API_BASE_URL overrides the backend URL
  • TRMNL_TOKEN_METER_CONFIG_DIR overrides the config directory
  • TRMNL_TOKEN_METER_CACHE_DIR overrides the cache directory
  • TRMNL_TOKEN_METER_INCLUDE_PI_SESSIONS=1 includes compatible Pi session aggregates when present
  • PI_HOME overrides the Pi home directory. Default: ~/.pi

Default local paths:

  • macOS config: ~/Library/Application Support/trmnl-token-meter
  • macOS cache/logs: ~/Library/Caches/trmnl-token-meter
  • Linux config: ${XDG_CONFIG_HOME:-~/.config}/trmnl-token-meter
  • Linux cache/logs: ${XDG_CACHE_HOME:-~/.cache}/trmnl-token-meter

Background service logs are written to the cache directory as service.log and service.err.log.

Project Policies

Contributing

Contributions are welcome, especially around privacy hardening, cross-platform service behavior, documentation, and test coverage.

Before opening a pull request:

  1. Install dependencies with pnpm install.
  2. Run pnpm typecheck, pnpm lint, pnpm test, pnpm test:privacy, and pnpm test:pack.
  3. Update docs and tests in the same change when behavior or payload shape changes.

See CONTRIBUTING.md for the full contributor workflow and CODE_OF_CONDUCT.md for collaboration expectations.

License

This project is released under the MIT License.

Local Sources

By default, the CLI reads Codex usage from CODEX_HOME when set, otherwise ~/.codex.

Expected local inputs:

  • $CODEX_HOME/sessions/**/*.jsonl
  • $CODEX_HOME/archived_sessions/**/*.jsonl
  • $CODEX_HOME/logs_2.sqlite for priority-tier cost evidence
  • ~/.pi/agent/sessions/**/*.jsonl only when Pi session merging is explicitly enabled

To read another Codex directory:

CODEX_HOME=/path/to/codex-home npx trmnl-token-meter collect

Pi session merging is off by default. Enable it for one command with:

npx trmnl-token-meter collect --include-pi-sessions

Background Sync

Interactive setup installs background sync automatically.

On macOS, the CLI installs a user launchd agent. On Linux, it prefers a user systemd timer and falls back to cron when systemd user services are unavailable.

Foreground continuous mode is available for debugging:

npx trmnl-token-meter run

Closing the terminal stops foreground mode. Normal setup uses the background scheduler instead.

Update Checks

Human-facing commands check npm for a newer trmnl-token-meter version at most once per day. Disable that check with either:

TRMNL_TOKEN_METER_DISABLE_UPDATE_CHECK=1 npx trmnl-token-meter status
npx trmnl-token-meter status --no-update-check

Local Files

The CLI stores its local credential and sync metadata in the platform config directory with restrictive permissions.

  • macOS: ~/Library/Application Support/trmnl-token-meter
  • Linux: ${XDG_CONFIG_HOME:-~/.config}/trmnl-token-meter

The collector credential is used only to authenticate this machine with your TRMNL Token Meter plugin. Revoking the machine invalidates that credential.

About

Private local Codex usage collector that syncs sanitized token and cost aggregates to a TRMNL display.

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors