====== Status line pro Claude Code ====== [[software:vyvoj:claude-code:start|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ů. ===== Co z toho získám ===== * 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 %. ===== Zapojení do konfigurace ===== 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. ===== Jak vypadá výstup ===== Když Claude Code neposílá data o ''rate_limits'', výstup vypadá zhruba takto: ~/scratch │ Sonnet 4.6 | sid: │ 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: │ 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 ===== Celý skript ===== #!/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" ===== Poznámky k chování ===== * 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é: ''cwd'' → ''model + sid'' → ''ctx'' → ''5h'' → ''7d'' → ''>200k/<200k''.