Skip to content

Instantly share code, notes, and snippets.

@4rmx
Created August 9, 2026 09:10
Show Gist options
  • Select an option

  • Save 4rmx/6e28479f0d6d7374c7a19476c84a085f to your computer and use it in GitHub Desktop.

Select an option

Save 4rmx/6e28479f0d6d7374c7a19476c84a085f to your computer and use it in GitHub Desktop.

Claude Code Status Line

A sh script for Claude Code's statusLine hook that shows, in order:

██░░░░░░░░  22% session limit  |  ████░░░░░░  42% weekly limit  |  Opus 5 (High)  |  94.2k tokens
  • Session limit — 5-hour rolling usage bar (rate_limits.five_hour.used_percentage)
  • Weekly limit — 7-day rolling usage bar (rate_limits.seven_day.used_percentage)
  • Model + effort — e.g. Opus 5 (High)
  • Tokens used — current conversation's token usage, colorized once it gets large:
    • default color: ≤ 200k tokens
    • yellow: > 200k tokens
    • orange: > 300k tokens

Both usage bars only appear once Claude Code's backend starts reporting them (after your first API response in a session, and only for Claude.ai subscription plans) — the script degrades gracefully and just omits a segment if the field isn't present.

Requirements

  • jq (install via brew install jq on macOS)
  • A terminal font with full block-character coverage ( U+2588, U+2591) — most modern monospace / Nerd Fonts work. If the bars render as broken boxes, your terminal font is missing these glyphs; switch fonts or swap the characters in make_bar() for plain ASCII (# / -).

Installation

  1. Save the script below as ~/.claude/statusline-command.sh and make it executable:

    chmod +x ~/.claude/statusline-command.sh
  2. Point Claude Code at it in ~/.claude/settings.json:

    {
      "statusLine": {
        "type": "command",
        "command": "~/.claude/statusline-command.sh"
      }
    }
  3. Restart Claude Code (or start a new session) — the status line updates automatically as the conversation progresses.

The script

#!/bin/sh
# Claude Code statusLine
# Shows: session-limit bar | weekly-limit bar | model (effort) | used tokens

input=$(cat)

model=$(echo "$input" | jq -r '.model.display_name // ""')

# Reasoning effort level (low/medium/high). Only emitted for models that
# support effort levels, so treat it as optional.
effort=$(echo "$input" | jq -r '.effort.level // empty')
if [ -n "$effort" ]; then
  effort_display=$(printf '%s' "$effort" | awk '{print toupper(substr($0,1,1)) substr($0,2)}')
  model="${model} (${effort_display})"
fi

# Compute used tokens directly from current_usage fields so the count matches
# what /context reports (e.g. 19.8k) rather than back-calculating from the
# already-rounded used_percentage (which would give 20.0k for 10%).
# current_usage is null before the first API call, fall back to empty in that case.
used_tok=$(echo "$input" | jq -r '
  .context_window.current_usage
  | if . == null then empty
    else (.input_tokens // 0)
       + (.cache_creation_input_tokens // 0)
       + (.cache_read_input_tokens // 0)
    end
')

# Format a raw number with k suffix when >= 1000, always one decimal place
fmt_k1() {
  printf '%s' "$1" | awk '{
    n = int($1)
    if (n >= 1000) {
      printf "%.1fk", n / 1000
    } else {
      printf "%d", n
    }
  }'
}

# Build a 10-block progress bar from a percentage value (0-100).
# Filled blocks: █  Empty blocks: ░
make_bar() {
  pct="$1"
  filled=$(printf '%s' "$pct" | awk '{print int($1 / 10 + 0.5)}')
  empty=$((10 - filled))
  bar=""
  i=0
  while [ "$i" -lt "$filled" ]; do
    bar="${bar}"
    i=$((i + 1))
  done
  i=0
  while [ "$i" -lt "$empty" ]; do
    bar="${bar}"
    i=$((i + 1))
  done
  printf '%s' "$bar"
}

# Colorize the token count once it gets large: yellow above 200k, orange
# above 300k, default color below that.
colorize_tokens() {
  text="$1"
  tok="$2"
  if [ "$tok" -gt 300000 ] 2>/dev/null; then
    printf '\033[38;5;208m%s\033[0m' "$text"   # orange
  elif [ "$tok" -gt 200000 ] 2>/dev/null; then
    printf '\033[38;5;220m%s\033[0m' "$text"   # yellow
  else
    printf '%s' "$text"
  fi
}

# Plan usage: rate_limits.five_hour.used_percentage / rate_limits.seven_day.used_percentage
# Only present for Claude.ai subscribers after the first API response.
five_hr_pct=$(echo "$input" | jq -r '.rate_limits.five_hour.used_percentage // empty')
seven_day_pct=$(echo "$input" | jq -r '.rate_limits.seven_day.used_percentage // empty')

# Assemble
if [ -n "$used_tok" ]; then
  used_display=$(colorize_tokens "$(fmt_k1 "$used_tok") tokens" "$used_tok")
  out=$(printf '%s  |  %s' "$model" "$used_display")
else
  out=$(printf '%s' "$model")
fi

# Prepend weekly-limit bar when available
if [ -n "$seven_day_pct" ]; then
  weekly_pct_display=$(printf "%.0f" "$seven_day_pct")
  weekly_bar=$(make_bar "$seven_day_pct")
  out="${weekly_bar}  ${weekly_pct_display}% weekly limit  |  ${out}"
fi

# Prepend session-limit bar when available
if [ -n "$five_hr_pct" ]; then
  limit_pct_display=$(printf "%.0f" "$five_hr_pct")
  limit_bar=$(make_bar "$five_hr_pct")
  out="${limit_bar}  ${limit_pct_display}% session limit  |  ${out}"
fi

printf '%s' "$out"

Customizing

  • Change token color thresholds: edit the 300000 / 200000 values in colorize_tokens().
  • Change bar width: edit the 10 in make_bar()'s pct / 10 calculation (and note the fixed-width loop assumes 10 segments).
  • Drop the weekly bar: delete the "Prepend weekly-limit bar" block.
  • Font issues (bars render as broken boxes): swap / for ASCII equivalents like # / - in make_bar().
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment