Skip to content

emaspa/trmnl-claude

Repository files navigation

claude-trmnl

Advanced Claude Code usage dashboard for TRMNL e-ink displays.

Claude Code Dashboard on TRMNL

Reads local Claude Code session data and optionally scrapes live usage limits via PTY. Cross-platform (Windows, macOS, Linux). Only stdlib + optional pywinpty (Windows) or pexpect (Unix).

What it shows

Metric Description
Subscription Plan type (Pro/Max) and rate limit tier (5x/20x)
Usage limits Session %, weekly %, Sonnet % with progress bars and reset time
Active sessions Currently running Claude Code instances
Today's tokens Input, output, cache read, cache write breakdown
API-equivalent cost What today's usage would cost at API prices
Session & message counts How many sessions and messages today
Model breakdown Per-model usage with percentage bars (7-day)
Weekly totals Tokens, cost, sessions for the current week
7-day sparkline Visual activity trend
Usage streak Consecutive days of Claude Code usage
Top project Most active project by token usage
Trend indicator Up/down/flat vs yesterday

How it works

~/.claude/
  .credentials.json   -->  subscription type + tier
  sessions/*.json     -->  active session count
  projects/**/*.jsonl  -->  token usage per message

claude CLI (via PTY)  -->  session/weekly usage % + reset times
        |
   claude_trmnl.py
        |
   POST merge_variables
        |
   trmnl.com/api/custom_plugins/{UUID}
        |
   TRMNL renders Liquid template to PNG
        |
   e-ink display pulls image on next wake

Setup

1. Install dependencies (optional)

For live usage limit scraping:

# Windows
pip install pywinpty

# macOS/Linux
pip install pexpect

Without these, the dashboard still works -- it just won't show the session/weekly usage percentages. Use --no-scrape to skip.

2. Configure

Set your Plugin UUID. Pick one of these approaches:

Option A: Environment variable (recommended)

Set TRMNL_PLUGIN_UUID as a system environment variable:

  • Windows: Settings > System > About > Advanced system settings > Environment Variables > New
  • macOS/Linux: add export TRMNL_PLUGIN_UUID="your-uuid" to ~/.bashrc or ~/.zshrc

Option B: Wrapper script

Create a run.bat (Windows) or run.sh (macOS/Linux) in the project folder:

@rem run.bat (Windows)
set TRMNL_PLUGIN_UUID=your-uuid-here
py claude_trmnl.py --no-scrape
# run.sh (macOS/Linux)
export TRMNL_PLUGIN_UUID="your-uuid-here"
python claude_trmnl.py

3. Run

# Test locally (prints JSON, does not post)
python claude_trmnl.py --dry-run

# Post to TRMNL (with usage limit scraping, ~20 sec)
python claude_trmnl.py

# Post without scraping (faster, ~1 sec, skips usage %)
python claude_trmnl.py --no-scrape

# Preview with sample multi-model data
python claude_trmnl.py --test

4. Schedule

Run every 5-10 minutes to keep your display updated.

Windows (Task Scheduler):

If using a wrapper script:

$action = New-ScheduledTaskAction -Execute "C:\path\to\claude-trmnl\run.bat" `
  -WorkingDirectory "C:\path\to\claude-trmnl"
$trigger = New-ScheduledTaskTrigger -Once -At (Get-Date) `
  -RepetitionInterval (New-TimeSpan -Minutes 5)
$settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries
Register-ScheduledTask -TaskName "claude-trmnl" `
  -Action $action -Trigger $trigger -Settings $settings

If using a system environment variable:

$action = New-ScheduledTaskAction -Execute "python" `
  -Argument "claude_trmnl.py" `
  -WorkingDirectory "C:\path\to\claude-trmnl"
$trigger = New-ScheduledTaskTrigger -Once -At (Get-Date) `
  -RepetitionInterval (New-TimeSpan -Minutes 5)
$settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries
Register-ScheduledTask -TaskName "claude-trmnl" `
  -Action $action -Trigger $trigger -Settings $settings

Linux/macOS (cron):

# crontab -e
*/5 * * * * cd /path/to/claude-trmnl && ./run.sh

macOS (launchd):

<!-- ~/Library/LaunchAgents/com.claude-trmnl.plist -->
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>Label</key><string>com.claude-trmnl</string>
  <key>ProgramArguments</key>
  <array>
    <string>/bin/bash</string>
    <string>-c</string>
    <string>cd /path/to/claude-trmnl &amp;&amp; ./run.sh</string>
  </array>
  <key>StartInterval</key><integer>300</integer>
  <key>RunAtLoad</key><true/>
</dict>
</plist>

5. Live updates with Claude Code hooks (optional)

You can have Claude Code automatically push dashboard updates while you're actively using it. Add a Notification hook to ~/.claude/settings.json:

{
  "hooks": {
    "Notification": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "cmd /c start /min /b py C:\\path\\to\\claude-trmnl\\claude_trmnl.py --debounce 5"
          }
        ]
      }
    ]
  }
}

On macOS/Linux:

{
  "hooks": {
    "Notification": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "python /path/to/claude-trmnl/claude_trmnl.py --debounce 5 &"
          }
        ]
      }
    ]
  }
}

The --debounce 5 flag ensures it only pushes once every 5 minutes (respecting TRMNL's 12/hour rate limit). The command runs in the background so it doesn't slow down your responses.

Restart Claude Code after editing settings.json for the hook to take effect.

License

GPL-3.0 -- see LICENSE

About

Advanced Claude Code usage dashboard for TRMNL e-ink displays

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors