cceye
v1.2.0
Published
Monitor Claude Code JSONL usage logs, estimate token costs, and notify on threshold breaches.
Downloads
49
Maintainers
Readme
Key Features
Claude Usage Log Parsing
Read Claude Code JSONL session logs from your local data directories, recursively scanning all projects and extracting usage from message.usage.
Data roots are discovered in this order:
CLAUDE_CONFIG_DIR(comma-separated directories, highest priority)claude_data_dirfrom config- auto-discovered defaults (
~/.config/claude/projects,~/.claude/projects)
Note: When CLAUDE_CONFIG_DIR is set, it overrides all other roots and must resolve to at least one existing projects/ directory. If none of the configured directories contain projects/, cceye errors instead of falling back to claude_data_dir or auto-discovered defaults.
Cost Tracking Modes
Choose how costs are computed:
auto: usecostUSDfrom log when present, otherwise calculate from token pricingcalculate: always calculate from token countsdisplay: always usecostUSDfrom log (fallback to0)
Threshold Alerts
Evaluate spend against daily, weekly, and monthly thresholds with warning and critical levels.
Multi-Channel Notifications
Send alerts to:
- Console output
- macOS Notification Center
- Slack webhook
- SMTP email
Live Dashboard (TUI)
Track current costs, hourly trend, model/project breakdown, and notification history in a keyboard-driven terminal dashboard.
Usage Reports
Generate report snapshots with:
dailyweeklymonthlysession
Each report supports date filters and JSON output options.
Smart Pricing Cache
Pricing is fetched from LiteLLM and cached at ~/.config/cceye/pricing-cache.json (24h TTL), with fallback prices for known models.
macOS Background Service
Install/uninstall a LaunchAgent for background monitoring with log files under ~/Library/Logs/cceye/.
Installation
Prerequisites
- Node.js 20 or later
- Claude Code logs available locally (e.g.
~/.claude/projects)
Install from npm (recommended)
npm install -g cceyeRun without install
npx cceye statusBuild from source (development)
git clone https://github.com/ydah/cceye.git
cd cceye
npm install
npm run buildDevelopment checks
npm run typecheck
npm run lintUsage
Quick Start
If you installed globally, use cceye. If not, replace it with npx cceye.
- Generate config interactively:
cceye initEdit thresholds and notification settings in
~/.config/cceye/config.yaml.Run a one-shot status check:
cceye status- Start daemon mode (foreground, silent):
cceye- Start daemon mode with logs (debug):
cceye -d- Start dashboard mode:
cceye dashboardCommands
cceye [command] [--config /path/to/config.yaml]
Commands:
--version Print CLI version
-v Print CLI version
(none) Start daemon mode (silent)
debug Start daemon mode with logs
--debug Enable debug logs for daemon mode
-d Alias for --debug
dashboard Start TUI dashboard mode
status Run one poll cycle and print current totals (no notifications)
daily Print daily usage report
weekly Print weekly usage report
monthly Print monthly usage report
session Print session usage report
init Interactive config generator
install Install macOS LaunchAgent
uninstall Remove macOS LaunchAgentNotes
- Any command accepts
--config <path>. - Report commands support:
--since YYYYMMDD--until YYYYMMDD--json--breakdown--timezone <IANA TZ>--offline
- If not installed globally, run commands with
npx cceye <command>. - Starting with no arguments (
cceye) clears notification cooldown flags once before daemon startup.
Configuration
Config file location
Default path:
~/.config/cceye/config.yamlSee config.example.yaml for a complete template.
Key fields
| Field | Description |
|------|-------------|
| claude_data_dir | Fallback root directory containing Claude JSONL logs (~ expansion supported) |
| polling_interval_milliseconds | Polling interval in milliseconds (>= 1) |
| timezone | Timezone used for daily/weekly/monthly window boundaries |
| cost_mode | auto, calculate, or display |
| thresholds.* | Warning/Critical cost thresholds per window |
| notifications.console.enabled | Enable console alerts |
| notifications.macos.enabled | Enable macOS notifications |
| notifications.macos.sound | Play notification sound on macOS |
| notifications.slack.enabled | Enable Slack alerts |
| notifications.slack.webhook_url | Slack Incoming Webhook URL |
| notifications.slack.mention | Optional mention prefix (<!channel>, <@U...>) |
| notifications.email.enabled | Enable SMTP email alerts |
| notifications.email.* | SMTP sender/recipient/auth settings |
| notification_cooldown_minutes | Cooldown for repeated alerts of same window/level |
| log_level | debug, info, warn, error |
| dashboard.refresh_interval_seconds | Required setting (currently not used by runtime logic) |
Validation rules
warningmust be less thancriticalfor all windows.- If Slack is enabled,
webhook_urlis required. - If email is enabled, these are required:
smtp_host,smtp_port,smtp_user,smtp_pass,from,to
Environment variables
| Variable | Description |
|----------|-------------|
| CLAUDE_CONFIG_DIR | Comma-separated Claude config roots; each must contain projects/ |
| CCEYE_SLACK_WEBHOOK_URL | Fills Slack webhook when Slack is enabled and URL is missing in config |
| CCEYE_SMTP_PASS | Fills SMTP password when email is enabled and password is missing in config |
Keybindings
Dashboard Controls
| Key | Action |
|-----|--------|
| q / Ctrl-C | Quit dashboard |
| r | Trigger refresh immediately |
| d | Switch breakdown window to daily (current target) |
| w | Switch breakdown window to weekly (current target) |
| m | Switch breakdown window to monthly (current target) |
| p | Toggle breakdown target (model / project) |
| Tab | Move focus to next panel |
| ↑ / ↓ | Scroll notification log |
Data Files
| File | Purpose |
|------|---------|
| ~/.config/cceye/config.yaml | Runtime configuration |
| ~/.config/cceye/state.json | Notification state, cooldown markers, and internal state |
| ~/.config/cceye/data.json | Dashboard-facing current aggregates and history |
| ~/.config/cceye/pricing-cache.json | Cached model pricing data |
Run as a Background Daemon
Option 1: macOS LaunchAgent (recommended)
This is the most reliable way to keep the daemon running in the background on macOS, including after login.
Install
cceye install --config ~/.config/cceye/config.yamlUninstall
cceye uninstall --config ~/.config/cceye/config.yamlLogs
~/Library/Logs/cceye/stdout.log~/Library/Logs/cceye/stderr.log
Option 2: nohup (quick/manual)
Use this when you want a simple background process without installing LaunchAgent.
Start
mkdir -p ~/.local/state/cceye
nohup cceye --config ~/.config/cceye/config.yaml > ~/.local/state/cceye/daemon.log 2>&1 &
echo $! > ~/.local/state/cceye/daemon.pidStop
kill "$(cat ~/.local/state/cceye/daemon.pid)"
rm -f ~/.local/state/cceye/daemon.pidTroubleshooting
config file not found
Create ~/.config/cceye/config.yaml or pass --config explicitly.
no session logs found
Verify the following, depending on your environment:
- If
CLAUDE_CONFIG_DIRis set: ensure its paths exist and contain Claude session logs, or unset it. - Otherwise, ensure either:
claude_data_dirpoints to Claude session logs, or- one default path exists and contains logs:
~/.config/claude/projects~/.claude/projects
Slack or Email config errors
When a channel is enabled, all required fields for that channel must be present and valid.
Dashboard terminal capability errors
When running from source, rebuild before running to ensure dist/ is up to date:
npm run buildDevelopment
npm run dev
npm test
npm run test:coverage
npm run buildMigration Notes
- Existing config files remain valid.
- Path resolution is now more flexible:
- If
CLAUDE_CONFIG_DIRis set, those paths are used exclusively. - Otherwise,
claude_data_diris used, with auto-discovered defaults appended when available.
- If
- New report commands are available:
cceye dailycceye weeklycceye monthlycceye session
