software:vyvoj:claude-code:statusline

Status line pro Claude Code

Claude Code umí vykreslovat vlastní status line spuštěný jako externí příkaz. Tohle je moje varianta, která drží stabilní pořadí polí a na jeden pohled ukazuje pracovní adresář, model, session ID, využití kontextu, 5h a 7d limity i informaci, jestli session nepřelezla hranici 200k tokenů.

  • Aktuální pracovní adresář zkrácený relativně k $HOME, takže místo celé cesty vidím jen ~ nebo ~/….
  • Použitý model a session ID přímo ve status line.
  • Využití context window v procentech.
  • 5hodinový a 7denní limit, včetně času resetu, pokud je Claude Code pošle v JSONu.
  • Rychlý signál, jestli session už překročila hranici 200k tokenů.
  • Barevné zvýraznění podle vytížení: zelená pod 70 %, žlutá od 70 %, červená od 90 %.

V ~/.claude/settings.json mám status line zapojený takto:

"statusLine": {
  "type": "command",
  "command": "bash /home/ubuntu/.claude/statusline-command.sh"
}

Skript čte JSON ze standardního vstupu, parsuje ho přes jq a složí z něj jednu barevnou řádku.

Když Claude Code neposílá data o rate_limits, výstup vypadá zhruba takto:

~/scratch │ Sonnet 4.6 | sid:<id> │ ctx:23% │ <200k

Když jsou limity v JSONu k dispozici, řádka se rozšíří o 5h a 7d přehled:

~/project-dokuwiki │ Sonnet 4.6 | sid:<id> │ ctx:23% │ 5h:41% ↺ 01:15 │ 7d:68% ↺ Ne 10:00 │ <200k

Barvy jsou rozdělené takto:

  • cwd → cyan + bold
  • model → magenta
  • sid → dim
  • ctx, 5h a 7d → zelená pod 70 %, žlutá od 70 %, červená od 90 %
  • >200k → červeně a tučně
  • <200k → dim
#!/usr/bin/env bash
# Claude Code status line
# Order: cwd | model | context used | 5h limit | 7d limit
 
input=$(cat)
 
# ── helpers ────────────────────────────────────────────────────────────────────
RESET='\033[0m'
BOLD='\033[1m'
DIM='\033[2m'
RED='\033[31m'
YELLOW='\033[33m'
GREEN='\033[32m'
CYAN='\033[36m'
MAGENTA='\033[35m'
WHITE='\033[37m'
 
# ── 1) cwd ─────────────────────────────────────────────────────────────────────
cwd=$(echo "$input" | jq -r '.workspace.current_dir // .cwd // ""')
# Show path relative to home dir
home_dir="$HOME"
if [[ "$cwd" == "$home_dir" ]]; then
  short_cwd="~"
elif [[ "$cwd" == "$home_dir/"* ]]; then
  short_cwd="~/${cwd#$home_dir/}"
else
  short_cwd="$cwd"
fi
[ "$short_cwd" = "/" ] && short_cwd="/"
 
# ── 2) model ───────────────────────────────────────────────────────────────────
model_name=$(echo "$input" | jq -r '.model.display_name // .model.id // ""')
session_id=$(echo "$input" | jq -r '.session_id // .conversation_id // empty')
 
# ── rate limit helpers ─────────────────────────────────────────────────────────
five_pct=$(echo "$input" | jq -r '.rate_limits.five_hour.used_percentage  // empty')
five_rst=$(echo "$input" | jq -r '.rate_limits.five_hour.resets_at        // empty')
week_pct=$(echo "$input" | jq -r '.rate_limits.seven_day.used_percentage  // empty')
week_rst=$(echo "$input" | jq -r '.rate_limits.seven_day.resets_at        // empty')
 
fmt_reset_short() {
  local v="$1"
  [ -z "$v" ] && return
  # Try as epoch first, then as ISO-8601 string
  if [[ "$v" =~ ^[0-9]+$ ]]; then
    date -d "@$v" +%H:%M 2>/dev/null || date -r "$v" +%H:%M 2>/dev/null || echo "?"
  else
    date -d "$v" +%H:%M 2>/dev/null || echo "?"
  fi
}
 
fmt_reset_long() {
  local v="$1"
  [ -z "$v" ] && return
  if [[ "$v" =~ ^[0-9]+$ ]]; then
    date -d "@$v" +"%a %H:%M" 2>/dev/null || date -r "$v" +"%a %H:%M" 2>/dev/null || echo "?"
  else
    date -d "$v" +"%a %H:%M" 2>/dev/null || echo "?"
  fi
}
 
# Choose colour based on used %
pct_color_used() {
  local used="$1"
  [ -z "$used" ] && echo "$WHITE" && return
  local u
  u=$(printf "%.0f" "$used")
  if   [ "$u" -ge 90 ]; then echo "$RED"
  elif [ "$u" -ge 70 ]; then echo "$YELLOW"
  else echo "$GREEN"
  fi
}
 
# ── exceeds_200k ───────────────────────────────────────────────────────────────
exceeds=$(echo "$input" | jq -r '.exceeds_200k_tokens // false')
 
# ── 3) context used ────────────────────────────────────────────────────────────
ctx_used_pct=$(echo "$input" | jq -r '.context_window.used_percentage // empty')
ctx_str=""
if [ -n "$ctx_used_pct" ]; then
  ctx_int=$(printf "%.0f" "$ctx_used_pct")
  if   [ "$ctx_int" -ge 90 ]; then
    ctx_str="$(printf "${RED}${BOLD}ctx:%s%%!${RESET}" "$ctx_int")"
  elif [ "$ctx_int" -ge 70 ]; then
    ctx_str="$(printf "${YELLOW}ctx:%s%%${RESET}" "$ctx_int")"
  else
    ctx_str="$(printf "${GREEN}ctx:%s%%${RESET}" "$ctx_int")"
  fi
fi
 
# ── assemble line ──────────────────────────────────────────────────────────────
parts=()
 
# 1) cwd
parts+=("$(printf "${CYAN}${BOLD}%s${RESET}" "$short_cwd")")
 
# 2) model + session id
if [ -n "$model_name" ] || [ -n "$session_id" ]; then
  parts+=("$(printf "${MAGENTA}%s${RESET}" "$model_name")${session_id:+ $(printf "${DIM}| sid:%s${RESET}" "$session_id")}")
fi
 
# 3) context used (always shown when data available)
[ -n "$ctx_str" ] && parts+=("$ctx_str")
 
# 4) 5h rate limit (only when data is available)
if [ -n "$five_pct" ]; then
  five_int=$(printf "%.0f" "$five_pct")
  col=$(pct_color_used "$five_pct")
  rst=$(fmt_reset_short "$five_rst")
  parts+=("$(printf "${col}5h:%s%%%s${RESET}" "$five_int" "${rst:+ ↺ $rst}")")
fi
 
# 5) 7d rate limit (only when data is available)
if [ -n "$week_pct" ]; then
  week_int=$(printf "%.0f" "$week_pct")
  col=$(pct_color_used "$week_pct")
  rst=$(fmt_reset_long "$week_rst")
  parts+=("$(printf "${col}7d:%s%%%s${RESET}" "$week_int" "${rst:+ ↺ $rst}")")
fi
 
# 6) exceeds_200k signal
if [ "$exceeds" = "true" ]; then
  parts+=("$(printf "${RED}${BOLD}>200k${RESET}")")
else
  parts+=("$(printf "${DIM}<200k${RESET}")")
fi
 
# ── print ──────────────────────────────────────────────────────────────────────
# Join with separator ""
sep="$(printf "${DIM}${RESET}")"
out=""
for p in "${parts[@]}"; do
  [ -z "$out" ] && out="$p" || out="${out}${sep}${p}"
done
 
printf "%b\n" "$out"
  • Pole 5h a 7d se zobrazí jen když Claude Code skutečně pošle rate_limits.
  • Funkce fmt_reset_short() a fmt_reset_long() zvládnou jak unix epoch, tak ISO-8601 string.
  • Když některé pole v JSONu chybí, skript se nerozbije a prostě ho přeskočí.
  • Pořadí polí je pevné: cwdmodel + sidctx5h7d>200k/<200k.
  • software/vyvoj/claude-code/statusline.txt
  • Poslední úprava: 2026/04/09 19:52
  • autor: Petr Nosek