Three-line status: directory, git branch and model up top; a context-fill bar with session cost and an hourly burn rate ($/h); then 5-hour and weekly rate-limit bars with context-warning icons.

MIT licensed · original source

4 copies

Using the Claude desktop app? Add your status line with statusline-anywhere.

Preview

Clean repo
📁 app 🌿 main 🧠 Opus 🧊 22% [==--------] 💰 $0.41 ($2.41/h) ⏳ 5h: 26% [==--------] 7d: 7% [----------]
New session
📁 app 🌿 main 🧠 Opus 🧊 0% [----------] 💰 $0.00 ($0.00/h)
Dirty branch
📁 app 🌿 feat/auth* 🧠 Sonnet 🧊 48% [====------] 💰 $0.41 ($2.41/h) ⏳ 5h: 40% [====------] 7d: 18% [=---------]
Near-full
📁 app 🌿 main 🧠 Opus ❗ 91% [=========-] 💰 $4.12 ($24.24/h) ⏳ 5h: 88% [========--] 7d: 61% [======----]
1M context
📁 app 🌿 main 🧠 Fable 🧊 64% [======----] 💰 $0.41 ($2.41/h) ⏳ 5h: 33% [===-------] 7d: 80% [========--]
Post-compact
📁 app 🌿 main 🧠 Haiku 🧊 0% [----------] 💰 $0.41 ($2.41/h) ⏳ 5h: 52% [=====-----]
Worktree
📁 feature 🌿 worktree-feature 🧠 Opus 🧊 37% [===-------] 💰 $0.41 ($2.41/h) ⏳ 5h: 44% [====------] 7d: 20% [==--------]
Non-git
📁 scratch 🌿 🧠 Opus 🧊 22% [==--------] 💰 $0.41 ($2.41/h)

Source

#!/bin/bash
input=$(cat)

# jq 또는 python3으로 JSON 파싱
parse() {
  local field="$1"
  local default="$2"
  if command -v jq &>/dev/null; then
    echo "$input" | jq -r "$field // \"$default\""
  else
    local py=$(command -v python3 || command -v python || command -v py)
    [ -z "$py" ] && { echo "$default"; return; }
    echo "$input" | $py -c "
import sys, json
data = json.load(sys.stdin)
keys = '$field'.strip('.').split('.')
val = data
for k in keys:
    val = val.get(k, '$default') if isinstance(val, dict) else '$default'
print(val)
" 2>/dev/null || echo "$default"
  fi
}

MODEL_RAW=$(parse '.model.display_name' 'unknown')
# shorten model name: "Opus 4.6 (1M context)" → "Opus"
MODEL=$(echo "$MODEL_RAW" | sed 's/ [0-9].*//')
DIR=$(parse '.workspace.current_dir' '.')
COST=$(parse '.cost.total_cost_usd' '0')
DURATION_MS=$(parse '.cost.total_duration_ms' '0')
REM=$(parse '.context_window.remaining_percentage' '100')
REM=${REM%%.*}
PCT=$((100 - REM))
VERSION=$(parse '.version' '')

# rate limits
RL5_PCT=$(parse '.rate_limits.five_hour.used_percentage' '')
RL7_PCT=$(parse '.rate_limits.seven_day.used_percentage' '')

# git branch + dirty check
BRANCH=$(cd "$DIR" 2>/dev/null && git branch --show-current 2>/dev/null || echo "")
if [ -n "$BRANCH" ] && cd "$DIR" 2>/dev/null && ! git diff --quiet HEAD 2>/dev/null; then
  BRANCH="${BRANCH}*"
fi

# context bar (usage-based: fills up as you use more)
FILLED=$((PCT / 10))
EMPTY=$((10 - FILLED))
BAR=$(printf "%${FILLED}s" | tr ' ' '=')$(printf "%${EMPTY}s" | tr ' ' '-')

# cost / hourly rate
COST_FMT=$(printf '$%.2f' "$COST")
DURATION_S=${DURATION_MS%.*}
SECS=$((DURATION_S / 1000))
if [ "$SECS" -gt 0 ]; then
  PY=$(command -v python3 || command -v python || command -v py)
  HOURLY=$($PY -c "print(f'{$COST / $SECS * 3600:.2f}')" 2>/dev/null || echo "0.00")
  HOURLY_FMT="\$${HOURLY}/h"
else
  HOURLY_FMT='$0.00/h'
fi

# context warning icon
if [ "$PCT" -ge 80 ]; then
  CTX_ICON="❗"
elif [ "$PCT" -ge 70 ]; then
  CTX_ICON="⚠️"
else
  CTX_ICON="🧊"
fi

# rate limit bars (remaining = 100 - used)
make_bar() {
  local pct=${1%%.*}
  local filled=$((pct / 10))
  local empty=$((10 - filled))
  printf "%${filled}s" | tr ' ' '='
  printf "%${empty}s" | tr ' ' '-'
}

RL_INFO=""
if [ -n "$RL5_PCT" ] && [ "$RL5_PCT" != "null" ]; then
  RL5_INT=${RL5_PCT%%.*}
  RL5_BAR=$(make_bar "$RL5_INT")
  RL_INFO="5h: ${RL5_INT}% [${RL5_BAR}]"
fi
if [ -n "$RL7_PCT" ] && [ "$RL7_PCT" != "null" ]; then
  RL7_INT=${RL7_PCT%%.*}
  RL7_BAR=$(make_bar "$RL7_INT")
  RL_INFO="${RL_INFO} 7d: ${RL7_INT}% [${RL7_BAR}]"
fi

# output
echo "📁 ${DIR##*/} 🌿 $BRANCH 🧠 $MODEL"
echo "${CTX_ICON} ${PCT}% [${BAR}] 💰 ${COST_FMT} (${HOURLY_FMT})"
[ -n "$RL_INFO" ] && echo "⏳ ${RL_INFO}"

What it shows

  • Current directory name (last path segment)
  • Current git branch, with a * suffix when the working tree has uncommitted changes
  • Model name shortened to its family word (e.g. Opus 4.6 becomes Opus)
  • Context window usage as a percentage with a 10-segment fill bar
  • A context icon that escalates with usage: snowflake below 70%, warning sign at 70% or more, exclamation at 80% or more
  • Total session cost in USD
  • Hourly burn rate in dollars per hour, computed from session cost and elapsed time
  • 5-hour rate limit usage as a percentage with a 10-segment bar
  • 7-day rate limit usage as a percentage with a 10-segment bar

Requirements

  • Bash
  • jq, or failing that python3/python/py, for JSON parsing; with none of them every field falls back to its default
  • python3, python, or py to compute the hourly burn rate; without it the rate shows $0.00/h
  • git for the branch name and dirty check; the branch slot is blank outside a git repository
  • Standard Unix utilities: sed, tr, printf
  • A terminal font that renders emoji
  • No network access

Behavior notes

  • The third line with rate limit bars only appears when Claude Code sends rate_limits data; brand-new sessions and the scratch-dir scenario omit it entirely
  • When only the 5-hour rate limit is present (Haiku scenario), the third line shows just the 5h bar and drops the 7d part
  • When remaining_percentage is null (new session, just after /compact), context usage displays as 0% with an empty bar
  • The context icon switched from the snowflake to the exclamation mark at 91% usage; the script also has a warning-sign tier for 70-79%
  • The branch gains a * on the dirty feature branch scenario; the branch comes from running git in the current directory, not from the JSON
  • In a non-git directory the branch slot after the leaf emoji is empty
  • The hourly rate scales with cost over the same duration: $0.41 shows $2.41/h, $4.12 shows $24.24/h
  • The script exits with code 1 when no rate limit line is printed, because the final conditional echo is the last command
  • The percentage bar is relative regardless of window size: a 1M-context session at 64% fills six segments just like a 200k session would
  • Vim mode, effort level, PR info, output style, session name, and agent fields never appear in the output even when present in the JSON

More status lines

Opus 4.8 [high] ~/app main 16:20:55 | ⛁ ██░░░░░░░░ 22% | 5h ●◔○○○ 26% ↻2h7m | 7d ◔○○○○○○ 7% ↻2d1h │ $0.41 ⏱ 10m

Activity Feed

51 copies

Opus 4.8 high ✦ │ ctx 22% │ app (main) │ PR #1287 ● │ $0.41 · 10m +128 -34 Session ● ● ● ● ● ● ● ● ○ ○ ○ 74% left Resets in 2h 6m Weekly ● ● ● ● ● ● ● ● ● ● ○ 93% left Resets in 2d 0h Fable ● ● ● ● ● ● ● ● ● ○ ○ 85% left Resets in 2d 0h ◐ Read:index.ts ✓ Read×1 ✓ Bash×1 ✓ Edit×1 ✓ Grep×1 ◐ code-reviewer Review the change for regressions

Pace Arrows

5 copies

Opus 4.8 (200K) high | app (main) ██░░░░░░░░ 22% 200K | 5h 26% ⇣32% 2h 7d 7% ⇣63% 2d
Model: Opus 4.8 | Thinking: high | Context: [▰▰▱▱▱▱▱▱▱▱] 45k/200k (22%) | cwd: ~/app | ⎇ main | (+0,-0) Cost: $0.41 | Block: 2hr 6m | Weekly: 7.0% | Session: 10m | In: 916.7 t/s | Out: 29.2 t/s | Cached: 2k | Session: [▰▱▱▱▱] 26.0% Mem: 0.8G/1.0G | (*゚∀゚*) | Session ID: b8e1c0d2-4a6f-4e2a-9c1b-3f5d7a9e2c10

Kanji Rain

6 copies

庫 app · 枝 main · 脳 OPUS-4.8 文 ▓▓░░░░░░ 22% · 時 ▓▓░░┃░░░ 26% · 週 ▓░░░░┃░░ 7%
app · main · Opus 4.8 · high ctx 22% 44k · 5h 26% ↻2h6m · 7d 7% ↻2d0h · cost $0.41 · msg $0.757