Vytvořeno: | Aktualizováno: 08.05.2026 21:45
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 absolutní spotřebu tokenů context window se zvýrazněním nad hranicí 200k.
$HOME, takže místo celé cesty vidím jen ~ nebo ~/…. Adresář se v průběhu session nemění, i když shell přejde do podadresáře.used_percentage.XYZk/TOTALk. Hodnota celkového okna se čte dynamicky, takže funguje i pro 1M context window. Červeně se rozsvítí při překročení 200k tokenů.
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% │ 92k/400k
Když jsou limity v JSONu k dispozici, řádka se rozšíří o 5h a 7d přehled:
~/project-procesniaudit-website │ Sonnet 4.6 │ ctx:55% │ 5h:4% ↺ 00:50 │ 7d:45% ↺ Po 08:00 │ 220k/400k
Barvy jsou rozdělené takto:
ctx, 5h a 7d → zelená pod 70 %, žlutá od 70 %, červená od 90 %XYZk/TOTALk → červeně a tučně při překročení 200k, jinak 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.project_dir // .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 } # ── 3) context used ──────────────────────────────────────────────────────────── ctx_used_tokens=$(echo "$input" | jq -r '.context_window.total_input_tokens // empty') ctx_window_size=$(echo "$input" | jq -r '.context_window.context_window_size // empty') ctx_pct=$(echo "$input" | jq -r '.context_window.used_percentage // empty') ctx_str="" if [ -n "$ctx_pct" ]; then ctx_int=$(printf "%.0f" "$ctx_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) token counter — červeně od 200k if [ -n "$ctx_used_tokens" ] && [ -n "$ctx_window_size" ] && [ "$ctx_window_size" -gt 0 ]; then ctx_used_k=$(python3 -c "print(round($ctx_used_tokens / 1000))") ctx_total_k=$(python3 -c "print(round($ctx_window_size / 1000))") if [ "$ctx_used_tokens" -gt 200000 ]; then parts+=("$(printf "${RED}${BOLD}%sk/%sk${RESET}" "$ctx_used_k" "$ctx_total_k")") else parts+=("$(printf "${DIM}%sk/%sk${RESET}" "$ctx_used_k" "$ctx_total_k")") fi 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"
5h a 7d se zobrazí jen když Claude Code skutečně pošle rate_limits.fmt_reset_short() a fmt_reset_long() zvládnou jak unix epoch, tak ISO-8601 string..workspace.project_dir — pole, které Claude Code nastavuje na root projektu (kde byl spuštěn) a nemění se v průběhu session, i když shell přejde do podadresáře. Pole .workspace.current_dir a .cwd jsou jen fallback.context_window.used_percentage — předpočítané pole, které Claude Code posílá od verze 2.1.132. Pokrývá vstupní tokeny včetně cache: used_percentage = (input_tokens + cache_creation_input_tokens + cache_read_input_tokens) / context_window_size. Výstupní tokeny do procenta nezahrnuje, ale ani do XYZk v token counteru (tam se čte total_input_tokens, které je součtem stejných tří složek).total_input_tokens zahrnuje všechny vstupní tokeny včetně cache a od v2.1.132 reprezentuje aktuální stav context window, nikoli kumulativní součet přes celou session.exceeds_200k_tokens — ten vychází z tokenů aktuálního API volání (input + output + cache) a má pevnou hranici 200k bez ohledu na skutečnou velikost okna. Místo toho skript ukazuje aktuální stav v segmentu XYZk/TOTALk.cwd → model + sid → ctx → 5h → 7d → XYZk/TOTALk.