ccpulse

module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 22, 2026 License: MIT

README

ccpulse

A native Go TUI dashboard for Claude Code usage. Reads ~/.claude/projects/*/*.jsonl transcripts, computes token / cost / 5-hour-window breakdowns. Local-only — no network calls during normal operation.

ccpulse TUI demo

Features

  • 5h + 7d quota bars — rolling-window gauges in the header, fed by the Anthropic usage API where available with a JSONL fallback.
  • Token histogram — horizontally-scrollable bar chart of usage per time bucket, heat-coloured relative to the peak bucket. Zoom cycles between 15m / 1h / 24h granularity.
  • fsnotify live updates — file watcher (not polling) keeps the cache in sync as Claude writes new turns; the TUI redraws on each refresh.

Installation

Homebrew (macOS, Linuxbrew)
brew install martinciu/tap/ccpulse

Shell completions are installed automatically.

Debian / Ubuntu (.deb)
curl -LO https://github.com/martinciu/ccpulse/releases/latest/download/ccpulse_<version>_linux_amd64.deb
sudo dpkg -i ccpulse_*.deb

Replace amd64 with arm64 on ARM. Find the latest version on the releases page.

Fedora / RHEL / openSUSE (.rpm)
curl -LO https://github.com/martinciu/ccpulse/releases/latest/download/ccpulse_<version>_linux_amd64.rpm
sudo rpm -i ccpulse_*.rpm

Replace amd64 with arm64 on ARM.

Verifying the download (optional)

Each release ships a checksums.txt alongside the binaries. To verify integrity before installing:

curl -LO https://github.com/martinciu/ccpulse/releases/latest/download/checksums.txt
sha256sum --ignore-missing -c checksums.txt

Run this from the directory where you downloaded the .deb / .rpm / tarball. The Homebrew install path is already integrity-checked by brew against the formula's sha256.

go install
go install github.com/martinciu/ccpulse/cmd/ccpulse@latest

Requires Go 1.25+. Skips the build-channel ldflag, so the binary writes dev debug logs to ~/.cache/ccpulse/debug.log.

After install, launch the TUI:

ccpulse

On first launch the TUI cold-walks ~/.claude/projects/ and backfills the cache (progress shown in the header). After that, the fsnotify watcher keeps the cache up to date automatically.

Build from source

Requires mise and git.

git clone https://github.com/martinciu/ccpulse ~/code/ccpulse
cd ~/code/ccpulse
mise install        # fetches Go 1.25 into the project-scoped toolchain
make install        # builds → ~/.local/bin/ccpulse

The binary lives in ~/.local/bin/ccpulse.

Commands

ccpulse

Opens the interactive TUI: 5h + 7d quota bars and a horizontally-scrollable token-usage histogram. / scroll the chart, z cycles bucket zoom (15m / 1h / 24h), ? toggles full help, q quits.

ccpulse index

Drops the SQLite cache and rebuilds it from a full scan of projects_root.

ccpulse index --rebuild   # drop the cache, then do a full scan

The TUI backfills automatically on launch, so this is only needed if the cache gets out of sync or you want a clean slate. The bare ccpulse index (no --rebuild) is intentionally an error.

ccpulse status

Prints the current 5-hour rolling window without opening the TUI.

ccpulse status            # human-readable summary
ccpulse status --json     # JSON: 5h + 7d percent/reset, tokens_5h, cost_5h_usd,
                          #       ceiling, optional projection block

--json is useful for scripting or status bars that consume structured data.

Claude Code hook

ccpulse status --quiet is designed to be called from Claude Code's Stop hook, which fires after every assistant turn. The internal 3-minute cache TTL absorbs the burst rate, so the Anthropic usage API is hit at most once every few minutes even during heavy use — no daemon, no blind polling. Add this to ~/.claude/settings.json (or merge the "hooks" key if you already have one):

{
  "hooks": {
    "Stop": [
      {
        "matcher": "",
        "hooks": [
          { "type": "command", "command": "ccpulse status --quiet" }
        ]
      }
    ]
  }
}

ccpulse doctor reports whether this hook is configured.

ccpulse config
ccpulse config edit   # create config if missing, then open in $EDITOR
ccpulse config show   # print the live config (defaults + your overrides)
ccpulse config path   # print the path to config.toml

edit never overwrites an existing file — safe to run at any time to check where the file lives before editing it manually.

ccpulse doctor

Runs a health-check checklist and prints a pass/fail report:

  • Config file loads and projects_root is readable
  • SQLite cache opens and PRAGMA integrity_check passes
  • Pricing table version
  • git is on PATH

Run this first when something looks wrong.

ccpulse version

Prints the build version, commit hash, and build date.

Configuration

~/.config/ccpulse/config.toml (created on first config edit):

[history]
retention_days = 0           # 0 = keep usage history forever; positive int prunes older rows

[paths]
projects_root = "~/.claude/projects"
cache_dir = "~/.cache/ccpulse"
  • [history] retention_days — drop usage history rows older than N days on each insert. Default 0 keeps history forever. Usage history is recorded once per ~3 minutes whenever ccpulse is running and successfully reaches the Anthropic usage API.

The plan tier (used to compute the 5h / 7d quota ceilings) is read from your Claude Code OAuth credential — there is no config knob for it.

Troubleshooting

ccpulse doctor runs a checklist:

  • Config loads / projects_root readable
  • SQLite cache opens, integrity_check passes
  • Pricing version
  • git on PATH

If the TUI launches with empty tabs, run ccpulse index to do a cold scan of ~/.claude/projects/.

If the cache is corrupt (rare; usually after a kill-during-write), the TUI auto-rebuilds on launch. Manual: ccpulse index --rebuild.

Parse errors are logged to ~/.cache/ccpulse/parse-errors.log (rotated at 10 MB). Empty when everything is healthy.

License

MIT (see LICENSE).

Directories

Path Synopsis
cmd
ccpulse command
pkg
anthro
Package anthro talks to api.anthropic.com on behalf of ccpulse, using the Claude Code OAuth credential.
Package anthro talks to api.anthropic.com on behalf of ccpulse, using the Claude Code OAuth credential.
channel
Package channel exposes the build channel (dev or release) chosen at link time by cmd/ccpulse/main.go via an ldflag-injected variable.
Package channel exposes the build channel (dev or release) chosen at link time by cmd/ccpulse/main.go via an ldflag-injected variable.
devlog
Package devlog wires slog.Default() based on the build channel and the resolved log level.
Package devlog wires slog.Default() based on the build channel and the resolved log level.
ingest
Package ingest catches the ccpulse cache up to current EOF for one or many .jsonl transcripts.
Package ingest catches the ccpulse cache up to current EOF for one or many .jsonl transcripts.
parse
Package parse turns Claude Code JSONL transcripts into Message records.
Package parse turns Claude Code JSONL transcripts into Message records.
secfile
Package secfile provides file/dir helpers that enforce private modes (0700 for dirs, 0600 for files) and chmod existing entries to those modes on next access.
Package secfile provides file/dir helpers that enforce private modes (0700 for dirs, 0600 for files) and chmod existing entries to those modes on next access.
tui
watcher
Package watcher wraps fsnotify with a debounce so a flurry of writes to the same JSONL collapses into a single onChange callback.
Package watcher wraps fsnotify with a debounce so a flurry of writes to the same JSONL collapses into a single onChange callback.
scripts
seedyear command
scripts/seedyear — synthesise a year of Claude Code messages into the dev ccpulse cache for manual bar-chart perf probing (issue #71).
scripts/seedyear — synthesise a year of Claude Code messages into the dev ccpulse cache for manual bar-chart perf probing (issue #71).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL