Documentation
Every number on the band, and where it comes from.
Install, use, how each figure is computed, the known limits, uninstalling, and the developer guide. The price table and the version are read from the plugin's own files when this page is built.
Start here
Install
/plugin marketplace add akshit-bansal11/plimsoll
/plugin install plimsoll@plimsollPick a scope when asked. User scope loads it in every session.
Requirements
- Node.js on your
PATH. The plugin starts it to read the transcripts and to run git. - git, for the git tab.
- GitHub CLI (gh), signed in. Optional, and only for pull request and CI status. Without it the git tab says so and still shows local git state.
Coming from usage-board
The plugin was called usage-board before 0.3.0. Remove the old plugin and its marketplace first, so only one copy runs:
/plugin uninstall usage-board@usage-board
/plugin marketplace remove usage-boardThe first scan after the update copies the old cache from <config dir>/usage-board/ to <config dir>/plimsoll/ when the new one does not exist yet, so no transcript is read again. Whether the HUD was hidden is stored under the plugin's name, so it resets once: run /hud hide again if it was.
Use
| Action | How |
|---|---|
| Hide or show the HUD | /hud (or /hud hide, /hud show) |
| Switch tab | /hud usage, /hud stats, /hud git |
| Collapse the band | ctrl+x ctrl+a (Claude Code's own shortcut for the band) |
| Switch tab by key | ctrl+x tab to focus the band, then 1, 2 or 3 |
/hud alone toggles between hidden and shown. A tab name shows the HUD if it was hidden. Anything else answers with the usage line, /hud [usage|stats|git|hide|show].
While hidden, a one-line summary stays in the status line: each rate-limit window's percentage, today's tokens and estimated cost, and a reminder of /hud. The hidden state is remembered across sessions.
How the numbers are computed
Context window
Claude Code reports the window's size, the tokens in it and the percentage used, when a session starts and each time it measures again. The CTX gauge draws the percentage, and the detail beside it reads used · left, where left is the window's size minus the tokens in it, never below zero. Before the first response there is nothing to measure, and the detail says awaiting first response.
Rate limits
Each window comes with the percentage used and, usually, when it resets. The gauge's label comes from the window's kind; a kind not in this table is shown by its own name, upper-cased and cut to five letters.
| Window kind | Label |
|---|---|
five_hour | 5H |
seven_day | WEEK |
spend_limit | SPEND |
The time to reset is the reset time minus now: days and hours from a day out, hours and minutes inside one, and now once it has passed. With no windows reported the band says No rate limits reported for this account. Rate-limit windows are only reported on a subscription.
Tokens and statistics
The scan reads every .jsonl transcript under <config dir>/projects, where the config dir is CLAUDE_CONFIG_DIR or ~/.claude. It runs when a session starts and after every turn, and nothing it reads leaves your machine.
What counts
- Only assistant responses with a usage block, from a real model (not
<synthetic>), with a readable timestamp. - A response is written once per content block under one message id, its usage final on the last, so the last row of each id is the one counted.
- A token total is all four kinds added together: input, output, cache writes and cache reads.
Periods
Every response is filed under its local hour. Today is the local date, the week starts on Monday, and the month on the 1st. The statistics run over every transcript on disk: tokens by hour of day and by weekday, the last 30 days and 12 months (zero-filled, the current one last), and the busiest single day, week (named by its Monday) and month.
The cache
Each transcript's per-hour sums are kept in <config dir>/plimsoll/scan-cache-2.json, keyed by path. A file whose modification time and size have not changed is not read again, so only the first scan reads everything. The cache is written to a temporary file and renamed into place, so a second session never reads half of one.
Estimated cost
Each response is priced by the first row below whose prefix its model id starts with, so a longer prefix is listed before a shorter one it begins with. A model with no row adds $0 rather than a guessed price.
cost = ( input × input price
+ output × output price
+ cache read × input price × cache-read multiplier
+ 5m write × input price × 1.25
+ 1h write × input price × 2 ) / 1,000,000Claude Code splits a cache write by lifetime when it records one; without the split every written token is priced as a 5-minute write. The three totals are rounded to the cent.
| Model id prefix | Input / MTok | Output / MTok | Cache read |
|---|---|---|---|
claude-fable-5-1 | $10 | $50 | × 0.025 |
claude-mythos-5-1 | $10 | $50 | × 0.025 |
claude-fable-5 | $10 | $50 | × 0.1 |
claude-mythos-5 | $10 | $50 | × 0.1 |
claude-opus-5-5 | $4 | $20 | × 0.05 |
claude-opus-5 | $5 | $25 | × 0.1 |
claude-opus-4-8 | $5 | $25 | × 0.1 |
claude-opus-4-7 | $5 | $25 | × 0.1 |
claude-opus-4-6 | $5 | $25 | × 0.1 |
claude-sonnet-5-5 | $2 | $10 | × 0.1 |
claude-sonnet-5 | $2 | $10 | × 0.1 |
claude-sonnet-4-6 | $3 | $15 | × 0.1 |
claude-haiku-5-5 | $0.1 | $0.5 | × 0.1 |
claude-haiku-4-5 | $1 | $5 | × 0.1 |
Prices as of 2026-10-06, read from scripts/prices.mjs when this site was built. Cache reads are a fraction of the input price; cache writes cost × 1.25 of it for 5 minutes and × 2 for 1 hour.
Git, pull requests and CI
It runs when a session starts, after each turn while the git tab is showing, and when you switch to the git tab. git gets 5 seconds a command, gh 8, and the whole read 45.
From git
git rev-parse --show-toplevelfinds the repository. Outside one the tab saysNot a git repository; without git,git is not installed.git status --porcelain=v2 --branchgives the branch, its upstream, ahead and behind, and the counts: staged from the index column, modified from the work-tree column, conflicts and untracked files. A detached HEAD shows its short hash in parentheses.git stash listis counted, andgit log -1gives the last commit's hash, subject and age.
From gh
Skipped on a detached HEAD or a repository with no remote. Otherwise gh pr view gives the branch's pull request: number, title, state, draft, review decision and its checks, sorted into three counts.
| Count | Check states |
|---|---|
| Passed | SUCCESS, NEUTRAL, SKIPPED |
| Failed | FAILURE, ERROR, TIMED_OUT, CANCELLED, ACTION_REQUIRED, STARTUP_FAILURE |
| Pending | anything else |
gh run list --branch <branch> --limit 1 gives the newest workflow run's name, status and conclusion. When gh cannot answer the tab says why: gh is not installed, gh is not signed in, gh timed out or remote is not on GitHub. Any other failure reads as no pull request for the branch.
Colours and the mascot
| Percentage | Gauge colour |
|---|---|
| below 50% | Green |
| 50% to 74% | Yellow |
| 75% to 89% | Orange |
| 90% and over | Red |
The kitten panics when the context gauge or any rate-limit gauge is red. Short of that it types while Claude is working, sleeps once five minutes have passed since a turn last started or ended, and otherwise idles. It moves a frame every 300 milliseconds while the HUD is shown, and not at all while it is hidden.
Reference
Known limits
- A transcript that was forked or copied is counted twice for the rows it shares.
- Dollars are an estimate at API list prices, not a bill. A model missing from the price table counts as $0 until the table is updated.
- Rate-limit windows are only reported on a subscription.
- A mod cannot draw over the transcript or register its own key chord, so the HUD takes rows of its own and uses Claude Code's band shortcuts.
- Below 48 columns the band is not drawn.
- The mod API is early access and may change between Claude Code releases.
- A clean filter that the inspected repository's config defines still runs when git status rereads a changed file, as it does for any git prompt; git has no switch for that.
Privacy and security
- Token totals and statistics are summed locally. The only file the plugin writes is its scan cache.
- The one network call is gh, to GitHub, with your own sign-in, for the repository you are in. No server, no account, no telemetry.
- git and gh are found on
PATHby absolute folder and run by full path, so agit.exeorgh.exeplanted in the repository is never run on Windows. - The repository's
core.fsmonitorandlog.showSignaturesettings are overridden, since each names a program for git to run, and optional index locks and terminal prompts are switched off. - Branch names, commit subjects, pull request titles and workflow names have control characters replaced before they are drawn, so an escape sequence cannot reach your terminal.
Report a hole privately through a security advisory, as SECURITY.md describes.
/plugin uninstall plimsoll@plimsoll
/plugin marketplace remove plimsollThen delete <config dir>/plimsoll/ (~/.claude/plimsoll/ by default) to remove the scan cache. A usage-board/ folder beside it is the cache of a version before 0.3.0 and can go too.
Developing
Develop
The hooks run inside Claude Code and import only claude-code; the scripts use only Node's standard library. Run the plugin from a clone with claude --plugin-dir /path/to/plimsoll.
Checks
node scripts/check.mjs # price table check
claude plugin validate --strict . # manifest + hooks check
claude plugin test . # UI and logic testsCI runs the same three on every push and pull request, with the Claude Code CLI pinned to one version.
The mod tests cannot import node: modules, so script logic that needs a test takes its file system functions as arguments; scripts/cache.mjs is the example.
The site
cd site
npm ci
npm run check:ci # Biome, ESLint, tsc; non-mutating
npm run build # static export to site/outThe site reads the plugin's version, price table and band mock-up from the repository at build time, so it must be built from inside it. It deploys to Vercel from the repository root.
Layout
hooks/register.tsx the band, the /hud command and the status line
hooks/mascot.ts the kitten's frames
scripts/scan.mjs sums the transcripts
scripts/cache.mjs names the scan cache, carries the old one over
scripts/prices.mjs the price table
scripts/git.mjs reads git and gh
tests/ the mod's tests
site/ this siteChanges follow CONTRIBUTING.md: Conventional Commits, a line under Unreleased in the changelog, and no lint suppressions.
Releases
A v* tag that matches plugin.json's version runs the checks, zips the plugin's runtime files under a plimsoll/ folder into Plimsoll-<version>.zip, writes SHA256SUMS.txt, attests where the zip was built, and publishes a GitHub Release with that version's changelog section as its notes.
The marketplace install does not need the zip; it is for a pinned or offline install with claude --plugin-dir. Check one with:
gh attestation verify Plimsoll-<version>.zip --repo akshit-bansal11/plimsollSee the changelog for what changed in each version.