statuslin.es

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

Updated 2026-06-29

2 copies

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

Dreambase Panel

150 copies

╭─ CONTEXT ────────────────────────────────────────────╮ ████▊░░░░░░░░░░░░░░░░░ 22% of 200K · GOOD ├─ STATS ──────────────────────────────────────────────┤ 44.0K 1.4K $0.41 ⏱ 10m 12s +128/-34 ├─ REPO ───────────────────────────────────────────────┤ Opus 4.8 · main · 16:21 ╰──────────────────────────────────────────────────────╯
app · main · Opus-4.8 · effort high · ctx 22% · 5h 26% ↻2h6m · 7d 7% ↻2d0h
Opus 4.8 [high] ~/app main 16:20:55 | ⛁ ██░░░░░░░░ 22% | 5h ●◔○○○ 26% ↻2h7m | 7d ◔○○○○○○ 7% ↻2d1h │ $0.41 ⏱ 10m
Opus 4.8 main app 44k/200k $0.41

Activity Feed

36 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
████▊░░░░░░░░░░░░░░░░░ 22% of 200K · GOOD 44.0K 1.4K $0.41 ⏱ 10m 12s +128/-34 Opus 4.8 · main · 16:22