Created
March 13, 2026 22:35
-
-
Save beveradb/7090a49ae0c1d958163cb671e1e08a0e to your computer and use it in GitHub Desktop.
Claude Code two-line status line: model, git, context bar, cost, duration, lines changed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| # Claude Code status line — feature-rich two-line display | |
| input=$(cat) | |
| # ── Extract JSON fields ────────────────────────────────────────── | |
| MODEL=$(echo "$input" | jq -r '.model.display_name // "?"') | |
| DIR=$(echo "$input" | jq -r '.workspace.current_dir // .cwd') | |
| COST=$(echo "$input" | jq -r '.cost.total_cost_usd // 0') | |
| DURATION_MS=$(echo "$input" | jq -r '.cost.total_duration_ms // 0') | |
| API_MS=$(echo "$input" | jq -r '.cost.total_api_duration_ms // 0') | |
| PCT=$(echo "$input" | jq -r '.context_window.used_percentage // 0' | cut -d. -f1) | |
| LINES_ADD=$(echo "$input" | jq -r '.cost.total_lines_added // 0') | |
| LINES_DEL=$(echo "$input" | jq -r '.cost.total_lines_removed // 0') | |
| VERSION=$(echo "$input" | jq -r '.version // ""') | |
| # ── Colors ──────────────────────────────────────────────────────── | |
| CYAN='\033[36m'; GREEN='\033[32m'; YELLOW='\033[33m'; RED='\033[31m' | |
| BOLD='\033[1m'; DIM='\033[2m'; RESET='\033[0m' | |
| BLUE='\033[34m'; MAGENTA='\033[35m' | |
| # ── Git info (cached for performance) ──────────────────────────── | |
| CACHE_FILE="/tmp/claude-statusline-git-cache" | |
| CACHE_MAX_AGE=5 | |
| cache_is_stale() { | |
| [ ! -f "$CACHE_FILE" ] || \ | |
| [ $(($(date +%s) - $(stat -f %m "$CACHE_FILE" 2>/dev/null || stat -c %Y "$CACHE_FILE" 2>/dev/null || echo 0))) -gt $CACHE_MAX_AGE ] | |
| } | |
| BRANCH=""; STAGED=0; MODIFIED=0; UNTRACKED=0; REMOTE_URL="" | |
| if cache_is_stale; then | |
| if git -C "$DIR" rev-parse --git-dir > /dev/null 2>&1; then | |
| BRANCH=$(git -C "$DIR" branch --show-current 2>/dev/null) | |
| STAGED=$(git -C "$DIR" diff --cached --numstat 2>/dev/null | wc -l | tr -d ' ') | |
| MODIFIED=$(git -C "$DIR" diff --numstat 2>/dev/null | wc -l | tr -d ' ') | |
| UNTRACKED=$(git -C "$DIR" ls-files --others --exclude-standard 2>/dev/null | wc -l | tr -d ' ') | |
| REMOTE_URL=$(git -C "$DIR" remote get-url origin 2>/dev/null | sed 's/git@github.com:/https:\/\/github.com\//' | sed 's/\.git$//') | |
| echo "$BRANCH|$STAGED|$MODIFIED|$UNTRACKED|$REMOTE_URL" > "$CACHE_FILE" | |
| else | |
| echo "||||" > "$CACHE_FILE" | |
| fi | |
| fi | |
| IFS='|' read -r BRANCH STAGED MODIFIED UNTRACKED REMOTE_URL < "$CACHE_FILE" | |
| # ── Format duration ────────────────────────────────────────────── | |
| format_duration() { | |
| local ms=$1 | |
| local secs=$((ms / 1000)) | |
| local mins=$((secs / 60)) | |
| local hrs=$((mins / 60)) | |
| mins=$((mins % 60)) | |
| secs=$((secs % 60)) | |
| if [ "$hrs" -gt 0 ]; then | |
| echo "${hrs}h ${mins}m" | |
| elif [ "$mins" -gt 0 ]; then | |
| echo "${mins}m ${secs}s" | |
| else | |
| echo "${secs}s" | |
| fi | |
| } | |
| DURATION=$(format_duration "$DURATION_MS") | |
| API_DURATION=$(format_duration "$API_MS") | |
| # ── Line 1: Model | Dir | Git branch + status | GitHub link ───── | |
| LINE1="" | |
| # Model | |
| LINE1="${BOLD}${CYAN}${MODEL}${RESET}" | |
| # Directory | |
| LINE1="${LINE1} ${DIM}│${RESET} ${BLUE}${DIR##*/}${RESET}" | |
| # Git branch + status indicators | |
| if [ -n "$BRANCH" ]; then | |
| LINE1="${LINE1} ${DIM}│${RESET} ${MAGENTA}${BRANCH}${RESET}" | |
| GIT_INDICATORS="" | |
| [ "$STAGED" -gt 0 ] && GIT_INDICATORS="${GIT_INDICATORS}${GREEN}+${STAGED}${RESET} " | |
| [ "$MODIFIED" -gt 0 ] && GIT_INDICATORS="${GIT_INDICATORS}${YELLOW}~${MODIFIED}${RESET} " | |
| [ "$UNTRACKED" -gt 0 ] && GIT_INDICATORS="${GIT_INDICATORS}${RED}?${UNTRACKED}${RESET} " | |
| [ -n "$GIT_INDICATORS" ] && LINE1="${LINE1} ${GIT_INDICATORS}" | |
| fi | |
| # Clickable GitHub link (OSC 8) | |
| if [ -n "$REMOTE_URL" ]; then | |
| REPO_NAME=$(basename "$REMOTE_URL") | |
| LINE1="${LINE1}${DIM}│${RESET} \033]8;;${REMOTE_URL}\a${DIM}${REPO_NAME}${RESET}\033]8;;\a" | |
| fi | |
| # Version (dim, at end) | |
| if [ -n "$VERSION" ]; then | |
| LINE1="${LINE1} ${DIM}v${VERSION}${RESET}" | |
| fi | |
| # ── Line 2: Context bar | Cost | Duration | Lines changed ─────── | |
| # Color-coded context progress bar | |
| if [ "$PCT" -ge 90 ]; then BAR_COLOR="$RED" | |
| elif [ "$PCT" -ge 70 ]; then BAR_COLOR="$YELLOW" | |
| else BAR_COLOR="$GREEN"; fi | |
| BAR_WIDTH=15 | |
| FILLED=$((PCT * BAR_WIDTH / 100)) | |
| EMPTY=$((BAR_WIDTH - FILLED)) | |
| BAR="" | |
| [ "$FILLED" -gt 0 ] && BAR=$(printf "%${FILLED}s" | tr ' ' '█') | |
| [ "$EMPTY" -gt 0 ] && BAR="${BAR}$(printf "%${EMPTY}s" | tr ' ' '░')" | |
| COST_FMT=$(printf '$%.2f' "$COST") | |
| LINE2="${BAR_COLOR}${BAR}${RESET} ${BOLD}${PCT}%${RESET}" | |
| LINE2="${LINE2} ${DIM}│${RESET} ${YELLOW}${COST_FMT}${RESET}" | |
| LINE2="${LINE2} ${DIM}│${RESET} ⏱ ${DURATION} ${DIM}(api ${API_DURATION})${RESET}" | |
| # Lines changed | |
| if [ "$LINES_ADD" -gt 0 ] || [ "$LINES_DEL" -gt 0 ]; then | |
| LINE2="${LINE2} ${DIM}│${RESET} ${GREEN}+${LINES_ADD}${RESET}${RED}-${LINES_DEL}${RESET}" | |
| fi | |
| # ── Output ──────────────────────────────────────────────────────── | |
| printf '%b\n' "$LINE1" | |
| printf '%b\n' "$LINE2" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment