npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

ccfleet

v0.2.0

Published

Aggregate ccusage across every machine where you run Claude Code — one merged view of tokens, cost, and billing blocks, over SSH.

Readme

ccfleet

Aggregate ccusage across every machine where you run Claude Code — one merged view of tokens, cost, and active billing blocks, over SSH.

┌────────────┬──────────────────────┬─────────┬─────────┬───────────┬─────────────┬─────────────┬─────────┬──────────────────────┐
│ Date       │ Models               │ Input   │ Output  │ Cache+    │ CacheR      │ Total       │ Cost    │ Devices              │
├────────────┼──────────────────────┼─────────┼─────────┼───────────┼─────────────┼─────────────┼─────────┼──────────────────────┤
│ 2026-04-10 │ haiku-4-5, opus-4-6  │ 11,825  │ 558,993 │ 2,791,514 │ 113,085,015 │ 116,447,347 │ $87.15  │ local, zju-pro6000   │
│ 2026-04-11 │ opus-4-6, sonnet-4-6 │ 2,074   │ 487,914 │ 2,324,279 │  55,606,452 │  58,420,719 │ $54.47  │ local, zju-pro6000   │
│ TOTAL      │ …                    │ 372,737 │ …       │ …         │ …           │ …           │ $308.61 │ local, zju-pro6000   │
└────────────┴──────────────────────┴─────────┴─────────┴───────────┴─────────────┴─────────────┴─────────┴──────────────────────┘

Think of it as "ccusage, but across all your dev boxes."

Why

If you run Claude Code on more than one machine — laptop, workstation, GPU boxes, remote dev hosts — ccusage only sees one at a time. You end up SSH-ing around, running ccusage daily on each, and adding the numbers in your head. ccfleet does that for you: one command, one merged table, no data ever leaves the hosts unencrypted.

Install

npm install -g ccfleet

Or run ad-hoc without installing:

npx ccfleet daily

30-second quickstart

No config file to write. ccfleet builds the config for you.

Step 1 — just your laptop

npm install -g ccfleet
ccfleet devices add local --local
ccfleet daily

Three commands. You'll see a merged table of every day you've used Claude Code on this machine.

Step 2 — add a remote machine

This step only applies if you already use ssh to connect to another computer (a server, a GPU box, a home desktop, etc). If you only run Claude Code on this one machine, Step 1 is all you need — skip to Step 3.

🍎 macOS users: install GNU rsync first.

brew install rsync

Apple ships openrsync 2.6.9, which crashes with renameat: No such file or directory whenever Claude Code is actively writing on the remote while ccfleet is mirroring it. GNU rsync 3.x (~10 seconds to install via Homebrew) fixes this and ccfleet picks it up automatically. Skip this only if you plan to use --cache-mode direct everywhere — but cache mode is much faster and usually what you want.

What's an "ssh alias"? When you type a command like ssh gpu-box and it connects somewhere, gpu-box is an alias defined in your ~/.ssh/config file. ccfleet reuses whatever aliases you already have — it does not ask for passwords and does not set up ssh for you.

Option A — you already ssh into it with a short name.

Suppose you normally connect with ssh gpu-box. Then:

# Use YOUR alias here, not "gpu-box" — that's just an example.
ccfleet devices add gpu --ssh-alias gpu-box --cache-mode cache
ccfleet devices test

gpu is the label ccfleet shows in tables; gpu-box is the actual ssh alias it connects with. You can use the same word for both if you want.

⚠️ If you see unknown host or Could not resolve hostname, the alias you passed does not exist in your ~/.ssh/config. Try ssh gpu-box yourself first — if that fails from your terminal, ccfleet can't connect either. Fix your ~/.ssh/config, or use Option B below.

Option B — you don't have an ssh alias, just a hostname + user.

ccfleet devices add gpu \
  --host 192.168.1.42 \
  --user your_username \
  --port 22 \
  --identity ~/.ssh/id_ed25519 \
  --cache-mode cache
ccfleet devices test

Replace 192.168.1.42, your_username, and the identity-file path with whatever you'd actually type into ssh. --port 22 and --identity … are optional — omit them if you don't need them.

Once devices test says ok:

ccfleet daily            # merged across laptop + gpu

Step 3 — explore

ccfleet daily --since 20260401             # just April
ccfleet blocks --active                    # current 5-hour billing block
ccfleet session --merge                    # grand total across everything
ccfleet daily --group-by device            # break down per machine
ccfleet daily --currency CNY               # show cost in ¥ instead of $
ccfleet devices list                       # what's configured

Fully automatic

ccfleet devices add writes ~/.config/ccfleet/config.toml for you with sensible defaults. You never need to edit TOML. If you want to, the schema is documented in Configuration reference and an annotated example lives in examples/config.toml.

Prerequisites

  • Node 20+ on the machine running ccfleet.
  • On each remote, one of:
    • Direct mode: ccusage reachable (default is npx -y ccusage@latest, override with ccusage_cmd).
    • Cache mode: rsync reachable, plus ccusage installed locally (once, on the ccfleet machine) — it runs against the mirrored JSONL.
  • macOS users, please install GNU rsync: brew install rsync. Apple's bundled openrsync 2.6.9 has known rename-race bugs when the remote ~/.claude/projects is being actively written by Claude Code, and you will hit them.

Commands

| Command | What it does | |---|---| | ccfleet daily | Per-day token/cost table merged across devices. | | ccfleet monthly | Per-month rollup. | | ccfleet session | Per-session rollup. | | ccfleet blocks | ccusage's 5-hour billing-block view. --active shows the current block. | | ccfleet sync | Force an rsync for all cache-mode devices. --status shows last-sync-at + bytes. | | ccfleet devices list\|test\|add\|remove | Device management. | | ccfleet run <device> -- <args…> | Escape hatch — run ccusage <args…> on a specific device, raw stdout. |

All query commands support:

| Flag | | |---|---| | --since 20260401 --until 20260411 | Date range (forwarded to ccusage). | | --timezone America/Los_Angeles | Time-zone for the day boundary. | | --group-by device / --group-by project | Slice the merged table. | | --merge | Single grand-total row. | | --device <name> (repeatable) | Limit to specific hosts. | | --breakdown | Per-model rows. | | --json | Machine-readable output. | | --refresh | Force an rsync before reading. | | --direct | Bypass the cache for this query. | | --currency USD\|CNY\|SGD\|EUR\|… | Show cost in any ISO 4217 currency. Live ECB rates, refreshed once per day and cached locally. --json output always stays in USD. |

How it works

Every device is queried in one of two modes:

  • Direct modessh <host> -- npx -y ccusage@latest daily --json, parse the response. Zero local state. Needs ccusage reachable on the remote.
  • Cache modersync the remote ~/.claude/projects to ~/.cache/ccfleet/<device>/projects, then run ccusage locally against the mirror with CLAUDE_CONFIG_DIR pointed at the cache dir. Warm queries are effectively free because ccusage is reading local JSONL, and the same mirror answers daily, monthly, session, and blocks without re-syncing.

Cache mode auto-refreshes when the mirror is older than cache_ttl_minutes (default 15). Use --refresh to force a sync mid-session, --direct to skip the cache entirely. local devices always run ccusage locally, uncached.

All device queries run in parallel, bounded by defaults.parallel. A failure on one device never blocks the others — it surfaces as a per-device error row with an actionable hint ("unknown host", "host key verification failed", "remote missing ccusage", etc).

Configuration reference

[defaults]
parallel          = 4              # max concurrent device queries
timeout_seconds   = 30             # per-device timeout
cache_mode        = "direct"       # "direct" (default) | "cache"
cache_ttl_minutes = 15             # auto-refresh threshold for cache mode
claude_dir        = "~/.claude"    # remote Claude data dir (override per-device)
ssh_multiplex     = true           # ControlMaster/ControlPersist for speed
currency          = "USD"          # 3-letter ISO (USD|CNY|SGD|EUR|GBP|JPY|…); `--currency` overrides

[[devices]]
name        = "work"               # required, unique
# Pick one of three ways to address the host:
ssh_alias   = "work"               # (a) use ~/.ssh/config — recommended
# host      = "work.example.com"   # (b) raw hostname + optional:
# user      = "alice"
# port      = 22
# identity  = "~/.ssh/id_ed25519"
# local     = true                 # (c) mark as local, no ssh, no cache
cache_mode  = "cache"              # override defaults per-device
claude_dir  = "/home/alice/.claude"
ccusage_cmd = "/home/alice/.bun/bin/ccusage"  # replace the default npx invocation

Or manage devices from the CLI:

ccfleet devices add work --ssh-alias work --cache-mode cache
ccfleet devices add gpu  --host gpu.example.com --user alice --identity ~/.ssh/id_ed25519
ccfleet devices test
ccfleet devices remove gpu

Troubleshooting

unknown host (check ~/.ssh/config) / Could not resolve hostname … — the --ssh-alias you passed isn't defined in your ~/.ssh/config, or it points at a hostname DNS can't resolve. Quick check: run ssh <that-alias> yourself in a new terminal. If that fails, ccfleet can't connect either — it's a plain ssh problem, not a ccfleet problem. Fix your ssh config, or re-add the device with --host <ip-or-hostname> / --user … flags instead of --ssh-alias.

command not found: ccusage — the remote doesn't have ccusage. Install it (npm i -g ccusage), or set ccusage_cmd to a pinned path. Direct mode defaults to npx -y ccusage@latest, which requires node + npm on the remote.

rsync failed (exit 10/23/24): renameat: No such file or directory — you're on macOS's openrsync 2.6.9. brew install rsync to get GNU rsync 3.x, which is first on PATH after install.

permission denied (publickey) — run ssh <alias> manually once to confirm your key is loaded and the remote accepts it. ccfleet uses BatchMode=yes, so it can't prompt for passwords interactively.

host key verification failedssh <alias> once to accept the host key, then retry.

Numbers don't match what ccusage shows locallyccfleet run <device> -- daily --since YYYYMMDD runs ccusage on that device raw, so you can diff against the merged view and find the drift.

Want to see what ccfleet is actually running?DEBUG=1 ccfleet daily prints stack traces on errors. For the literal argv, ccfleet run <device> -- --help is the passthrough.

Development

git clone https://github.com/tangshunpu/ccfleet
cd ccfleet
npm install
npm run build        # produces dist/cli.js
npm link             # puts `ccfleet` on your PATH, pointing at dist/cli.js

Architecture notes and future work live in PLAN.md.

License

MIT