Skip to content

Instantly share code, notes, and snippets.

@dpaluy
Created December 24, 2025 18:37
Show Gist options
  • Select an option

  • Save dpaluy/3e83c6b1749c03e169c74d58237806f8 to your computer and use it in GitHub Desktop.

Select an option

Save dpaluy/3e83c6b1749c03e169c74d58237806f8 to your computer and use it in GitHub Desktop.
Claude Code Statusline
#!/bin/bash
# Read JSON input
input=$(cat)
# Extract session data
model=$(echo "$input" | jq -r '.model.display_name')
limit=$(echo "$input" | jq -r '.context_window.context_window_size // 200000')
current_dir=$(echo "$input" | jq -r '.workspace.current_dir // "."')
current_usage=$(echo "$input" | jq '.context_window.current_usage')
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
CYAN='\033[0;36m'
GRAY='\033[0;90m'
ORANGE='\033[38;5;214m'
NC='\033[0m'
# Calculate context from JSON input (preferred) or fallback to transcript
if [ "$current_usage" != "null" ] && [ -n "$current_usage" ]; then
context_tokens=$(echo "$current_usage" | jq '(.input_tokens // 0) + (.cache_creation_input_tokens // 0) + (.cache_read_input_tokens // 0)')
else
# Fallback: parse transcript file
transcript_path=$(echo "$input" | jq -r '.transcript_path')
if [ -f "$transcript_path" ]; then
context_tokens=$(tac "$transcript_path" | grep -m1 '"assistant"' | jq -r '
(.message.usage.input_tokens // 0) +
(.message.usage.cache_creation_input_tokens // 0) +
(.message.usage.cache_read_input_tokens // 0)
' 2>/dev/null || echo "0")
else
context_tokens=0
fi
fi
# Ensure context_tokens is a valid number
context_tokens=${context_tokens:-0}
[ "$context_tokens" = "null" ] && context_tokens=0
# Calculate context percentage (guard against division by zero)
if [ "$limit" -gt 0 ] 2>/dev/null; then
context_pct=$((context_tokens * 100 / limit))
else
context_pct=0
fi
# Build progress bar (10 chars wide)
bar_width=10
filled=$((context_pct * bar_width / 100))
[ $filled -gt $bar_width ] && filled=$bar_width
empty=$((bar_width - filled))
bar=""
for ((i=0; i<filled; i++)); do bar+="█"; done
for ((i=0; i<empty; i++)); do bar+="░"; done
# Calculate tokens until auto-compact (45k buffer)
compact_buffer=45000
compact_threshold=$((limit - compact_buffer))
until_compact=$((compact_threshold - context_tokens))
if [ $until_compact -lt 0 ]; then
compact_display="0k"
else
compact_display="$((until_compact / 1000))k"
fi
# Get current task from project-scoped file
task_display=""
task_file="${current_dir}/.claude/current_task.txt"
if [ -f "$task_file" ]; then
current_task=$(tr -d '\n' < "$task_file")
if [ -n "$current_task" ]; then
[ ${#current_task} -gt 30 ] && current_task="${current_task:0:27}..."
task_display=" ${GRAY}|${NC} ${CYAN}${current_task}${NC}"
fi
fi
# Get git info (branch + changes)
git_display=""
cd "$current_dir" 2>/dev/null || cd /
if git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
branch=$(git branch --show-current 2>/dev/null || echo "detached")
status_output=$(git status --porcelain 2>/dev/null)
if [ -n "$status_output" ]; then
total_files=$(echo "$status_output" | wc -l | xargs)
# Get line changes
staged_stats=$(git diff --numstat --cached 2>/dev/null | awk '{a+=$1; r+=$2} END {print a+0, r+0}')
unstaged_stats=$(git diff --numstat 2>/dev/null | awk '{a+=$1; r+=$2} END {print a+0, r+0}')
staged_added=$(echo $staged_stats | cut -d' ' -f1)
staged_removed=$(echo $staged_stats | cut -d' ' -f2)
unstaged_added=$(echo $unstaged_stats | cut -d' ' -f1)
unstaged_removed=$(echo $unstaged_stats | cut -d' ' -f2)
added=$((staged_added + unstaged_added))
removed=$((staged_removed + unstaged_removed))
git_display=" ${GRAY}|${NC} ${ORANGE}${branch}${NC} ${GRAY}${total_files}f${NC}"
[ "$added" -gt 0 ] && git_display="${git_display} ${GREEN}+${added}${NC}"
[ "$removed" -gt 0 ] && git_display="${git_display} ${RED}-${removed}${NC}"
else
git_display=" ${GRAY}|${NC} ${ORANGE}${branch}${NC}"
fi
fi
# Build output
echo -e "${model}${task_display}${git_display} ${GRAY}|${NC} ${GRAY}${bar}${NC} ${compact_display}"
#!/bin/bash
# Read JSON input
input=$(cat)
# Extract session data
model=$(echo "$input" | jq -r '.model.display_name')
limit=$(echo "$input" | jq -r '.context_window.context_window_size')
transcript_path=$(echo "$input" | jq -r '.transcript_path')
# Calculate current context usage from transcript (like ccusage does)
# Read last assistant message and sum input tokens (excluding output tokens)
if [ -f "$transcript_path" ]; then
context_tokens=$(tac "$transcript_path" | grep -m1 '"assistant"' | jq -r '
(.message.usage.input_tokens // 0) +
(.message.usage.cache_creation_input_tokens // 0) +
(.message.usage.cache_read_input_tokens // 0)
' 2>/dev/null || echo "0")
else
context_tokens=0
fi
# Calculate context percentage (progress bar)
context_pct=$((context_tokens * 100 / limit))
# Calculate tokens until auto-compact (45k buffer)
compact_buffer=45000
compact_threshold=$((limit - compact_buffer))
until_compact=$((compact_threshold - context_tokens))
# Format for display (in thousands)
if [ $until_compact -lt 0 ]; then
compact_display="0k"
else
compact_k=$((until_compact / 1000))
compact_display="${compact_k}k"
fi
# Get current task from project-scoped file
task_display=""
task_file=".claude/current_task.txt"
if [ -f "$task_file" ]; then
current_task=$(cat "$task_file" | tr -d '\n')
if [ -n "$current_task" ]; then
# Truncate if too long (max 40 chars)
if [ ${#current_task} -gt 40 ]; then
current_task="${current_task:0:37}..."
fi
task_display=" | Task: $current_task"
fi
fi
# Get current git branch
branch_display=""
if git rev-parse --git-dir > /dev/null 2>&1; then
branch=$(git branch --show-current 2>/dev/null)
if [ -n "$branch" ]; then
# Orange color (Claude color): RGB(255, 138, 0) ≈ 214 in 256-color
orange=$'\033[38;5;214m'
reset=$'\033[0m'
branch_display=" | Branch: ${orange}${branch}${reset}"
fi
fi
# Build output (no progress bar - can't accurately calculate from transcript)
printf "%s" "$model"
printf "%s" "$task_display"
printf "%b" "$branch_display"
printf " | Context: %s" "$compact_display"
@dpaluy
Copy link
Author

dpaluy commented Dec 24, 2025

@dpaluy
Copy link
Author

dpaluy commented Dec 24, 2025

CleanShot 2025-12-24 at 12 39 37

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment