#!/usr/bin/env bash
#
# Claude Code status line — model, version, cwd, git state, context budget.
#
#   Opus 5 (1M context) v2.1.4 in geisel-forge   main (eab45d6) ✓  󱇛 84k/1000k
#
# Renders, left to right:
#   • model display name          (cyan)
#   • Claude Code version         (grey)
#   • current directory basename  (blue)
#   • git branch + short hash     (magenta / yellow)  — only inside a repo
#   • git state indicator         ✗ dirty · ↑ ahead of upstream · ✓ clean
#   • context window used / total (colour shifts as you fill it up)
#
# Context colour thresholds:  <50% terracotta · 50–89% yellow · 90%+ red.
#
# INSTALL
#   1. Save this file somewhere stable, e.g. ~/.claude/statusline.sh
#   2. chmod +x ~/.claude/statusline.sh
#   3. Add to ~/.claude/settings.json:
#
#        "statusLine": {
#          "type": "command",
#          "command": "~/.claude/statusline.sh"
#        }
#
# REQUIRES
#   jq, git, and a Nerd Font for the  and 󱇛 glyphs.
#   No Nerd Font? Swap them for plain text — see the printf at the bottom.
#
# Claude Code pipes a JSON blob in on stdin; everything below reads from it.

input=$(cat)

dir=$(echo      "$input" | jq -r '.workspace.current_dir')
model=$(echo    "$input" | jq -r '.model.display_name')
version=$(echo  "$input" | jq -r '.version')
used_pct=$(echo "$input" | jq -r '.context_window.used_percentage // 0')
ctx_size=$(echo "$input" | jq -r '.context_window.context_window_size // 200000')

# Context window, in thousands of tokens.
size_k=$(( ctx_size / 1000 ))
used_k=$(( used_pct * size_k / 100 ))

# Warm terracotta while there's room, yellow past halfway, red when nearly full.
if   [ "$used_pct" -ge 90 ] 2>/dev/null; then ctx_color='\033[38;2;255;50;50m'
elif [ "$used_pct" -ge 50 ] 2>/dev/null; then ctx_color='\033[38;2;255;230;50m'
else                                          ctx_color='\033[38;2;212;113;78m'
fi

# Git segment — skipped entirely outside a repo.
if [ -d "$dir/.git" ] || git -C "$dir" rev-parse --git-dir >/dev/null 2>&1; then
  dirty=$(git -C "$dir" status --porcelain 2>/dev/null)
  ahead=$(git -C "$dir" rev-list @{u}..HEAD 2>/dev/null | wc -l)

  if   [ -n "$dirty" ];      then git_ind='\033[1;38;2;255;50;50m✗\033[0m'   # uncommitted changes
  elif [ "$ahead" -gt 0 ];   then git_ind='\033[1;38;2;255;230;50m↑\033[0m'  # committed, not pushed
  else                            git_ind='\033[1;38;2;50;255;50m✓\033[0m'   # clean and in sync
  fi

  branch=$(git -C "$dir" rev-parse --abbrev-ref HEAD 2>/dev/null)
  hash=$(git   -C "$dir" rev-parse --short HEAD 2>/dev/null)

  git_part=$(printf ' \033[0;35m %s\033[0m \033[0;33m(%s)\033[0m %b' \
    "$branch" "$hash" "$git_ind")
else
  git_part=''
fi

# One line, one printf.
# No Nerd Font? Replace  with "git:" and 󱇛 with "ctx".
printf '\033[1;36m%s\033[0m \033[0;90mv%s\033[0m \033[1;32min\033[0m \033[1;34m%s\033[0m%s  %b󱇛 %sk/%sk\033[0m' \
  "$model" \
  "$version" \
  "$(basename "$dir")" \
  "$git_part" \
  "$ctx_color" "$used_k" "$size_k"
