Skip to content

Instantly share code, notes, and snippets.

@markomitranic
Created January 29, 2026 09:13
Show Gist options
  • Select an option

  • Save markomitranic/2584561209afb74899c5f1644d55024e to your computer and use it in GitHub Desktop.

Select an option

Save markomitranic/2584561209afb74899c5f1644d55024e to your computer and use it in GitHub Desktop.
Minimal Claude Code statusline with context window warning
#!/usr/bin/env bash
# Status line script for Claude Code
# Displays: Branch, Model, Cost, Duration, Lines changed
# Location: ~/.claude/scripts/statusline.sh
#
# Installation: ~/.claude/settings.json
# "statusLine": {
# "type": "command",
# "command": "~/.claude/scripts/statusline.sh"
# }
#
# Flags:
# --preview Use hardcoded JSON for quick testing
# Parse flags
PREVIEW=0
for arg in "$@"; do
case "$arg" in
--preview)
PREVIEW=1
;;
esac
done
# Check if jq is installed
if ! command -v jq >/dev/null 2>&1; then
echo "Error: jq is required but not installed. Please install jq first." >&2
exit 1
fi
# Read JSON input
if [ "$PREVIEW" -eq 1 ]; then
input=$(cat <<EOF
{
"hook_event_name": "Status",
"session_id": "abc123...",
"transcript_path": "/path/to/transcript.json",
"cwd": "/current/working/directory",
"model": {
"id": "claude-opus-4-1",
"display_name": "Opus"
},
"workspace": {
"current_dir": "/current/working/directory",
"project_dir": "/original/project/directory"
},
"version": "1.0.80",
"output_style": {
"name": "default"
},
"cost": {
"total_cost_usd": 0.01234,
"total_duration_ms": 45000,
"total_api_duration_ms": 2300,
"total_lines_added": 156,
"total_lines_removed": 23
},
"context_window": {
"total_input_tokens": 15234,
"total_output_tokens": 4521,
"context_window_size": 200000,
"used_percentage": 42.5,
"remaining_percentage": 57.5,
"current_usage": {
"input_tokens": 8500,
"output_tokens": 1200,
"cache_creation_input_tokens": 5000,
"cache_read_input_tokens": 2000
}
}
}
EOF
)
else
input=$(cat)
fi
# Validate JSON input
if [ -z "$input" ]; then
echo "Error: No JSON input received from Claude Code." >&2
exit 1
fi
# Dump JSON to file for debugging
echo "$input" > /tmp/claude-statusline-input.json
# Extract data from JSON
cost=$(echo "$input" | jq -r '.cost.total_cost_usd // 0' 2>/dev/null)
total_input=$(echo "$input" | jq -r '.context_window.total_input_tokens // 0' 2>/dev/null)
total_output=$(echo "$input" | jq -r '.context_window.total_output_tokens // 0' 2>/dev/null)
context_percentage=$(echo "$input" | jq -r '.context_window.used_percentage // 0' 2>/dev/null)
model_name=$(echo "$input" | jq -r '.model.display_name // ""' 2>/dev/null)
model_id=$(echo "$input" | jq -r '.model.id // ""' 2>/dev/null)
workspace_dir=$(echo "$input" | jq -r '.workspace.current_dir // .workspace.project_dir // ""' 2>/dev/null)
# Validate critical values were parsed successfully
if [ -z "$cost" ] || [ "$cost" = "null" ]; then
echo "Error: Failed to parse session data. Invalid or malformed JSON input." >&2
exit 1
fi
# Get current git branch (use workspace directory if available)
if [ -n "$workspace_dir" ] && [ -d "$workspace_dir" ]; then
branch=$(git -C "$workspace_dir" rev-parse --abbrev-ref HEAD 2>/dev/null || echo "no-branch")
else
branch=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "no-branch")
fi
# Format tokens with k/M suffix
format_tokens_short() {
local num="$1"
num=${num//[^0-9]/}
if [ -z "$num" ]; then
echo "0"
return
fi
if [ "$num" -ge 1000000 ]; then
awk "BEGIN {printf \"%.0fM\", $num / 1000000}"
elif [ "$num" -ge 1000 ]; then
awk "BEGIN {printf \"%.0fk\", $num / 1000}"
else
echo "$num"
fi
}
# Calculate context tokens from percentage (actual context window usage)
context_window_size=$(echo "$input" | jq -r '.context_window.context_window_size // 200000' 2>/dev/null)
context_tokens=$(awk "BEGIN {printf \"%.0f\", $context_percentage * $context_window_size / 100}")
context_display=$(format_tokens_short "$context_tokens")
# Calculate session total (all input/output tokens consumed)
session_total=$((total_input + total_output))
session_display=$(format_tokens_short "$session_total")
# Prepare model display string (show name if available, fallback to ID)
if [ -z "$model_name" ] || [ "$model_name" = "null" ]; then
model_display="$model_id"
else
model_display="$model_name"
fi
# Convert percentage to integer
context_percent_int=$(awk "BEGIN {printf \"%.0f\", $context_percentage}")
# Choose context emoji based on token count
if [ "$context_tokens" -lt 30000 ]; then
context_emoji="😊"
elif [ "$context_tokens" -lt 70000 ]; then
context_emoji="πŸ€“"
elif [ "$context_tokens" -lt 100000 ]; then
context_emoji="😟"
else
context_emoji="😠"
fi
# Build and print status line
LC_ALL=C printf "🌿 \033[1;92m%s\033[0m | πŸ€– \033[1;96m%b\033[0m | %s Context: \033[1;97m%s\033[0m (\033[1;94m%d%%\033[0m) | πŸ’° Session: \033[1;97m%s\033[0m (\033[1;93m\$%.4f\033[0m)" \
"$branch" \
"$model_display" \
"$context_emoji" \
"$context_display" \
"$context_percent_int" \
"$session_display" \
"$cost"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment