Skip to content

Instantly share code, notes, and snippets.

@grgsim
Last active March 10, 2026 08:13
Show Gist options
  • Select an option

  • Save grgsim/26b1140761073d547339d28af99a58c5 to your computer and use it in GitHub Desktop.

Select an option

Save grgsim/26b1140761073d547339d28af99a58c5 to your computer and use it in GitHub Desktop.
Custom Claude Code statusline — single line, monochrome, with git status
#!/usr/bin/env bash
# Custom Claude Code statusline — single line, monochrome
input=$(cat)
[ -z "$input" ] && { printf "Claude"; exit 0; }
# ── Style ────────────────────────────────────────────────
dim='\033[2m'
reset='\033[0m'
sep=" ${dim}│${reset} "
now=$(date +%s)
# ── Extract data (single jq call) ────────────────────────
eval "$(echo "$input" | jq -r '
"model=" + (.model.display_name // "Claude" | @sh) +
" ctx_pct=" + (.context_window.used_percentage // 0 | floor | tostring | @sh) +
" cwd=" + (.cwd // "" | @sh) +
" cost=" + (.cost.total_cost_usd // 0 | . * 100 | floor | . / 100 | tostring | @sh)
')"
[ -z "$cwd" ] && cwd="$PWD"
# ── Git info (cached 5s, per-repo) ───────────────────────
git_info=""
repo_root=$(git -C "$cwd" rev-parse --show-toplevel 2>/dev/null)
if [ -n "$repo_root" ]; then
git_cache="/tmp/claude-statusline-git-${repo_root//\//_}"
git_stale=true
if [ -f "$git_cache" ]; then
git_age=$(( now - $(stat -f %m "$git_cache" 2>/dev/null || stat -c %Y "$git_cache" 2>/dev/null || echo 0) ))
[ "$git_age" -lt 5 ] && git_stale=false
fi
if [ "$git_stale" = true ]; then
branch=$(git -C "$cwd" rev-parse --abbrev-ref HEAD 2>/dev/null)
dots=""
while IFS= read -r l; do
case "$l" in
[MADRC]*) dots+='\033[38;2;120;180;120m●\033[0m' ;;
esac
case "${l:1:1}" in
[MD]) dots+='\033[38;2;200;180;100m●\033[0m' ;;
esac
case "$l" in
"??"*) dots+='\033[38;2;200;120;110m●\033[0m' ;;
esac
done < <(git -C "$cwd" status --porcelain 2>/dev/null)
# Deduplicate: keep at most one dot per category
staged="" unstaged="" untracked=""
[[ "$dots" == *'120;180;120'* ]] && staged='\033[38;2;120;180;120m●\033[0m'
[[ "$dots" == *'200;180;100'* ]] && unstaged='\033[38;2;200;180;100m●\033[0m'
[[ "$dots" == *'200;120;110'* ]] && untracked='\033[38;2;200;120;110m●\033[0m'
dots="${staged}${unstaged}${untracked}"
git_info="󰊢 ${branch} ${dots}"
tmp="${git_cache}.$$"
echo "$git_info" > "$tmp" && mv "$tmp" "$git_cache"
else
git_info=$(cat "$git_cache" 2>/dev/null)
fi
fi
# ── Build single line ────────────────────────────────────
dir="${cwd/#$HOME/~}"
line="${model}${sep}${dir}"
[ -n "$git_info" ] && line+="${sep}${git_info}"
line+="${sep}󰦨 ${ctx_pct}%"
line+="${sep}\$ ${cost}"
printf '%b' "$line${reset}"
@grgsim
Copy link
Author

grgsim commented Mar 8, 2026

Claude Code Custom Statusline

Single-line, monochrome statusline with live session info. Cross-compatible macOS and Linux.

Features

  • Model name — currently active model
  • Working directory — home-relative path (~/...)
  • Git branch & status — branch name with colored dots: 🟢 staged, 🟡 unstaged, 🔴 untracked (cached 5s per repo)
  • Context usage — context window percentage
  • Session cost — running USD cost for the session

Requires jq and git.

Install

mkdir -p ~/.claude
curl -o ~/.claude/statusline.sh 'https://gist.githubusercontent.com/grgsim/26b1140761073d547339d28af99a58c5/raw/statusline.sh'

Add to ~/.claude/settings.json:

{
  "statusLine": {
    "type": "command",
    "command": "bash ~/.claude/statusline.sh"
  }
}

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