|
# ~/.claude/scripts/statusline-command.sh |
|
#!/bin/sh |
|
# Claude Code status line: dir | git branch+status | model | context% (color-coded) |
|
|
|
input=$(cat) |
|
|
|
cwd=$(echo "$input" | jq -r '.workspace.current_dir // .cwd // ""') |
|
model=$(echo "$input" | jq -r '.model.display_name // ""') |
|
used_pct=$(echo "$input" | jq -r '.context_window.used_percentage // empty') |
|
|
|
# Shorten home directory to ~ |
|
short_cwd=$(echo "$cwd" | sed "s|^$HOME|~|") |
|
|
|
# Git branch and status |
|
git_info="" |
|
if git -C "$cwd" rev-parse --git-dir > /dev/null 2>&1; then |
|
branch=$(git -C "$cwd" symbolic-ref --short HEAD 2>/dev/null || git -C "$cwd" rev-parse --short HEAD 2>/dev/null) |
|
if [ -n "$branch" ]; then |
|
git_info=" [$branch" |
|
# Ahead/behind remote |
|
upstream=$(git -C "$cwd" rev-parse --abbrev-ref --symbolic-full-name @{u} 2>/dev/null) |
|
if [ -n "$upstream" ]; then |
|
ahead=$(git -C "$cwd" rev-list --count @{u}..HEAD 2>/dev/null) |
|
behind=$(git -C "$cwd" rev-list --count HEAD..@{u} 2>/dev/null) |
|
[ "$ahead" -gt 0 ] 2>/dev/null && git_info="${git_info} ⇡${ahead}" |
|
[ "$behind" -gt 0 ] 2>/dev/null && git_info="${git_info} ⇣${behind}" |
|
fi |
|
# Modified files |
|
modified=$(git -C "$cwd" diff --name-only 2>/dev/null | wc -l | tr -d ' ') |
|
staged=$(git -C "$cwd" diff --cached --name-only 2>/dev/null | wc -l | tr -d ' ') |
|
total_modified=$(( modified + staged )) |
|
[ "$total_modified" -gt 0 ] && git_info="${git_info} !${total_modified}" |
|
# Untracked files (count ?? entries like p10k — directories count as 1) |
|
untracked=$(git -C "$cwd" status --porcelain 2>/dev/null | grep -c '^??') |
|
[ "$untracked" -gt 0 ] && git_info="${git_info} ?${untracked}" |
|
git_info="${git_info}]" |
|
fi |
|
fi |
|
|
|
# Helper: color for a percentage value (value only, not label) |
|
pct_color() { |
|
if [ "$1" -le 50 ]; then printf '\033[32m' |
|
elif [ "$1" -le 80 ]; then printf '\033[33m' |
|
else printf '\033[31m' |
|
fi |
|
} |
|
reset=$(printf '\033[0m') |
|
|
|
# Context window usage (default 0% if not yet available) |
|
ctx_int=0 |
|
[ -n "$used_pct" ] && ctx_int=$(printf "%.0f" "$used_pct") |
|
ctx_info=" ctx:$(pct_color "$ctx_int")${ctx_int}%${reset}" |
|
|
|
# Helper: format a rate limit label — usage: rate_label <prefix> <pct> <resets_at> <date_fmt> |
|
rate_label() { |
|
prefix="$1" pct="$2" resets_at="$3" fmt="$4" |
|
if [ -z "$pct" ]; then |
|
printf "%s(-):-" "$prefix" |
|
return |
|
fi |
|
pct_int=$(printf "%.0f" "$pct") |
|
if [ -n "$resets_at" ]; then |
|
time_part="($(date -r "$resets_at" "$fmt" 2>/dev/null || date -d "@$resets_at" "$fmt" 2>/dev/null))" |
|
else |
|
time_part="(-)" |
|
fi |
|
printf "%s%s:%s%s%%%s" "$prefix" "$time_part" "$(pct_color "$pct_int")" "$pct_int" "$reset" |
|
} |
|
|
|
# Rate limits |
|
five_label=$(rate_label "5h" \ |
|
"$(echo "$input" | jq -r '.rate_limits.five_hour.used_percentage // empty')" \ |
|
"$(echo "$input" | jq -r '.rate_limits.five_hour.resets_at // empty')" \ |
|
'+%H:%M') |
|
seven_label=$(rate_label "7d" \ |
|
"$(echo "$input" | jq -r '.rate_limits.seven_day.used_percentage // empty')" \ |
|
"$(echo "$input" | jq -r '.rate_limits.seven_day.resets_at // empty')" \ |
|
'+%m/%d %H:%M') |
|
rate_info=" ${five_label} ${seven_label}" |
|
|
|
printf "%s%s | %s%s%s\n" "$short_cwd" "$git_info" "$model" "$ctx_info" "$rate_info" |