| name | claude-status-alignment |
| description | Calibrate the Claude Code statusline against the real /usage numbers. Use when the user shares a screenshot of the in-app `/usage` panel (or the claude.ai Settings → Usage page) and wants the statusline's "time left", session %, and weekly % to match what Claude actually reports. Fixes ccusage block-drift, where the local 5-hour clock starts from the first transcript message instead of the real server-side reset. |
Claude Status Alignment
The statusline at ~/.claude/tools/ccusage-statusline.py estimates session/weekly
usage from local ccusage data. Two things drift from Anthropic's real numbers:
- Session reset time — ccusage starts the 5-hour clock at the first message
in the transcript. The real window is server-side and starts later, so
"⏱ Xh Ym left" can be tens of minutes off.
- Token-limit calibration — the
% used depends on SESSION_LIMIT_TOKENS /
WEEKLY_LIMIT_TOKENS, which are guesses. The real % comes from /usage.
This skill reads those real numbers from a screenshot and writes them to a
sidecar config the statusline already knows how to read:
~/.claude/statusline-alignment.json. No Python editing required — the
script picks up the sidecar automatically on its next refresh.
What the statusline reads from the sidecar
{
"captured_at": "<ISO8601, when the screenshot was taken>",
"session_reset_at": "<ISO8601 absolute time the current session resets>",
"session_limit_tokens": <int, recalibrated 5h-window token budget>,
"weekly_reset_at": "<ISO8601, informational>",
"weekly_limit_tokens": <int, recalibrated weekly token budget>,
"notes": "<free text, optional>"
}
Behavior in the script (already implemented):
session_reset_at overrides "⏱ X left" only while it is still in the
future. Once it passes, the script falls back to ccusage's block end — so a
stale sidecar never shows a wrong negative/expired time.
session_limit_tokens / weekly_limit_tokens override the % denominators.
- Missing or corrupt sidecar → script silently uses its built-in defaults.
Procedure
Follow every step in order.
1. Read the screenshot
The user provides a screenshot of /usage (Claude Code) or claude.ai
Settings → Usage. Extract:
- Current session:
X% used and the reset label — this appears in two
possible formats:
- Absolute time:
Resets H:MMam (Timezone) — e.g. Resets 1:40am (America/Los_Angeles)
- Relative time:
Resets in Y min or Resets in Yh Zm
- Weekly · All models:
X% used and the reset label (e.g. Resets Jun 2 at 8am (America/Los_Angeles)).
- Weekly · Sonnet only (if shown):
X% used.
If any value is unreadable, ask the user rather than guessing.
2. Get the system clock and timezone
date "+%Y-%m-%dT%H:%M:%S%z"
Always run this — you need the current time regardless of which reset format the
screenshot uses. If the screenshot is old, ask the user when it was taken and
use that timestamp as "now" for the computation instead.
ISO8601 offset format: When writing any timestamp to the sidecar, always use
the colon form for the UTC offset: -07:00 not -0700. Python's
datetime.fromisoformat (3.6–3.10) rejects the no-colon form and the script
will silently fall back to ccusage's block end time instead of the sidecar value.
3. Get current token counts from ccusage
ccusage blocks --active --json
ccusage blocks --since YYYYMMDD --json
Use the active block's totalTokens for the session, and the summed
non-gap totalTokens since the last Tuesday reset for weekly. These are the
denominators you'll recalibrate against the screenshot's percentages.
4. Compute the sidecar values
- session_reset_at — depends on the format shown in the screenshot:
- Absolute time (
Resets 1:40am (America/Los_Angeles)): parse directly to
ISO8601 using the screenshot's timezone. Example: 2026-05-31T01:40:00-0700.
Do not add anything to "now" — the time is already absolute.
- Relative time (
Resets in Y min / Resets in Yh Zm): add the duration
to step-2 now. Example: now=21:06 + 34min → 2026-05-30T21:40:00-0700.
- session_limit_tokens =
round(session_block_tokens / (session_pct / 100)).
- If
session_pct is 0 (rounds to 0% on the page), skip recalibration — keep
the existing limit. Don't divide by zero.
- weekly_limit_tokens =
round(weekly_tokens / (all_models_pct / 100)).
- Same zero-guard. Use the All models percentage (the binding weekly cap),
not Sonnet-only.
- weekly_reset_at = next occurrence of the weekly reset label (informational;
the script still computes its own weekly countdown).
Show the user a small before/after table (old limit → new limit, old "time
left" → new "time left") and the percentages you read, so they can sanity-check
your screenshot reading before you write.
5. Write the sidecar
Write ~/.claude/statusline-alignment.json with the schema above. Preserve any
keys you aren't changing by reading the existing file first (if present) and
merging.
6. Verify
Run the statusline with a dummy hook payload and confirm the numbers now match
the screenshot:
echo '{"transcript_path":"/nonexistent","model":{"id":"claude-sonnet-4-6"}}' \
| python3 ~/.claude/tools/ccusage-statusline.py
Confirm ⏱ X left matches the session reset time from the screenshot (±1 min rounding) and the 🔋/📅
percentages match the screenshot. Report the verified output line to the user.
Do not claim success without running this step.
Notes & limits
- The sidecar is a point-in-time snapshot. The session override expires when
session_reset_at passes; re-run the skill with a fresh screenshot to realign.
- The weekly countdown shown in the statusline is still computed from the
Tuesday-8AM-Pacific anchor in the script (subject to a known PST/PDT offset
caveat in winter). Only the weekly percentage is recalibrated here.
- This skill never touches credentials or network APIs — it works purely from
the screenshot the user supplies plus local ccusage data.