Skip to content

Instantly share code, notes, and snippets.

@vivekhaldar
Created February 5, 2026 20:32
Show Gist options
  • Select an option

  • Save vivekhaldar/ce65d62398e90905bdd3ae31a3260bcf to your computer and use it in GitHub Desktop.

Select an option

Save vivekhaldar/ce65d62398e90905bdd3ae31a3260bcf to your computer and use it in GitHub Desktop.
Dynamic statusline script for Claude Code CLI — shows git status, context usage, model info, and estimated cost
#!/usr/bin/env bash
# Read JSON input from stdin
input=$(cat)
# Extract data from JSON
current_dir=$(echo "$input" | jq -r '.workspace.current_dir')
model_name=$(echo "$input" | jq -r '.model.display_name // "Claude"')
output_style=$(echo "$input" | jq -r '.output_style.name // ""')
# Change to the current directory
cd "$current_dir" 2>/dev/null || exit 1
# Build status line components (matching Starship config)
status_parts=()
# Username (only show if not default user)
current_user=$(whoami)
if [[ "$current_user" != "your_username" ]]; then
status_parts+=("$(printf '\033[1;33m%s\033[0m' "$current_user")")
fi
# Hostname (trimmed at .local, matching Starship)
hostname_short=$(hostname -s | sed 's/\.local$//')
if [[ -n "$hostname_short" ]]; then
status_parts+=("$(printf 'at \033[1;32m%s\033[0m' "$hostname_short")")
fi
# Directory (use basename if in repo, matching truncate_to_repo)
if git rev-parse --git-dir >/dev/null 2>&1; then
git_root=$(git rev-parse --show-toplevel 2>/dev/null)
if [[ "$current_dir" == "$git_root" ]]; then
dir_display=$(basename "$current_dir")
else
rel_path=${current_dir#$git_root/}
dir_display="$(basename "$git_root")/$rel_path"
fi
else
# Show last 3 components
dir_display=$(echo "$current_dir" | awk -F/ '{if (NF<=3) print $0; else print $(NF-2)"/"$(NF-1)"/"$NF}')
fi
status_parts+=("$(printf 'in \033[1;36m%s\033[0m' "$dir_display")")
# Git branch (if in a repo)
if git rev-parse --git-dir >/dev/null 2>&1; then
git_branch=$(git symbolic-ref --short HEAD 2>/dev/null)
if [[ -n "$git_branch" ]]; then
status_parts+=("$(printf 'on \033[1;35m%s\033[0m' "$git_branch")")
# Git status (matching Starship symbols)
git_status=$(git status --porcelain 2>/dev/null)
if [[ -n "$git_status" ]]; then
status_symbols=""
[[ "$git_status" =~ ^\?\? ]] && status_symbols+="?"
[[ "$git_status" =~ ^[MADRC] ]] && status_symbols+="+"
[[ "$git_status" =~ ^.[MD] ]] && status_symbols+="!"
if [[ -n "$status_symbols" ]]; then
status_parts+=("$(printf '\033[1;31m%s\033[0m' "$status_symbols")")
fi
fi
# Git ahead/behind (skip optional locks for performance)
upstream=$(git rev-parse --abbrev-ref @{upstream} 2>/dev/null)
if [[ -n "$upstream" ]]; then
ahead=$(git rev-list --count --no-optional-locks "$upstream"..HEAD 2>/dev/null || echo "0")
behind=$(git rev-list --count --no-optional-locks HEAD.."$upstream" 2>/dev/null || echo "0")
if [[ "$ahead" -gt 0 ]]; then
status_parts+=("$(printf '\033[1;31mahead %s\033[0m' "$ahead")")
fi
if [[ "$behind" -gt 0 ]]; then
status_parts+=("$(printf '\033[1;31mbehind %s\033[0m' "$behind")")
fi
fi
fi
fi
# Python version (if pyproject.toml or .py files exist)
if [[ -f "pyproject.toml" ]] || ls *.py >/dev/null 2>&1; then
python_version=$(python3 --version 2>/dev/null | awk '{print $2}')
if [[ -n "$python_version" ]]; then
status_parts+=("$(printf 'via \033[1;33mpy:%s\033[0m' "$python_version")")
fi
fi
# Context window usage
total_input=$(echo "$input" | jq -r '.context_window.total_input_tokens // 0')
total_output=$(echo "$input" | jq -r '.context_window.total_output_tokens // 0')
context_size=$(echo "$input" | jq -r '.context_window.context_window_size // 200000')
total_tokens=$((total_input + total_output))
if [[ $context_size -gt 0 ]]; then
usage_pct=$((total_tokens * 100 / context_size))
else
usage_pct=0
fi
# Format tokens with K suffix for readability
if [[ $total_tokens -ge 1000 ]]; then
tokens_display="$((total_tokens / 1000))K"
else
tokens_display="$total_tokens"
fi
# Pricing (approximate, based on Claude 3.5 Sonnet pricing)
# Input: $3 per 1M tokens, Output: $15 per 1M tokens
cost_input=$(echo "scale=4; $total_input * 3 / 1000000" | bc 2>/dev/null || echo "0")
cost_output=$(echo "scale=4; $total_output * 15 / 1000000" | bc 2>/dev/null || echo "0")
total_cost=$(echo "scale=2; $cost_input + $cost_output" | bc 2>/dev/null || echo "0")
# Model and output style info (Claude-specific additions)
if [[ -n "$output_style" ]]; then
status_parts+=("$(printf '[\033[1;34m%s\033[0m|\033[1;36m%s\033[0m]' "$model_name" "$output_style")")
else
status_parts+=("$(printf '[\033[1;34m%s\033[0m]' "$model_name")")
fi
# Add context usage and cost
status_parts+=("$(printf '\033[1;33m%s tok\033[0m \033[1;32m%d%%\033[0m \033[1;36m$%s\033[0m' "$tokens_display" "$usage_pct" "$total_cost")")
# Join all parts with spaces
printf '%s' "${status_parts[*]}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment