{"slug": "powerline-status-line-for-claude-cli", "title": "Powerline Status Line for Claude CLI", "summary": "A developer created a Powerlevel10k-style status line for Claude CLI, displaying session name, current directory, git branch status, Vim mode, model name, context window usage, and rate limit information in a single line. The bash script parses JSON input from Claude Code to populate color-coded segments with pill-shaped badges and separators. The status line includes visual indicators for dirty git repositories, remaining context capacity, and API rate limit consumption.", "body_md": "| #!/bin/bash | |\n| # Claude Code statusLine — sexy Powerlevel10k-style | |\n| # Segments: session • cwd • git • vim • model • context bar • rate limits • caveman | |\n| input=$(cat) | |\n| # ── Palette ──────────────────────────────────────────────────────────────── | |\n| RESET=$'\\033[0m' | |\n| BOLD=$'\\033[1m' | |\n| DIM=$'\\033[2m' | |\n| # Foreground | |\n| FG_WHITE=$'\\033[97m' | |\n| FG_BLACK=$'\\033[30m' | |\n| FG_BLUE=$'\\033[34m' | |\n| FG_CYAN=$'\\033[36m' | |\n| FG_GREEN=$'\\033[32m' | |\n| FG_YELLOW=$'\\033[33m' | |\n| FG_RED=$'\\033[31m' | |\n| FG_MAGENTA=$'\\033[35m' | |\n| FG_ORANGE=$'\\033[38;5;214m' | |\n| FG_GRAY=$'\\033[90m' | |\n| # Background accents (used for mini-badge style) | |\n| BG_BLUE=$'\\033[44m' | |\n| BG_CYAN=$'\\033[46m' | |\n| BG_GREEN=$'\\033[42m' | |\n| BG_YELLOW=$'\\033[43m' | |\n| BG_RED=$'\\033[41m' | |\n| BG_MAGENTA=$'\\033[45m' | |\n| BG_DARK=$'\\033[48;5;236m' | |\n| BG_ORANGE=$'\\033[48;5;130m' | |\n| # ── Helpers ──────────────────────────────────────────────────────────────── | |\n| SEP=\"${FG_GRAY}│${RESET}\" | |\n| # Print a colored pill: bg fg text | |\n| pill() { | |\n| local bg=\"$1\" fg=\"$2\" text=\"$3\" | |\n| printf \"${bg}${fg}${BOLD} %s ${RESET}\" \"$text\" | |\n| } | |\n| # Print a dim label + colored value | |\n| kv() { | |\n| local label=\"$1\" color=\"$2\" value=\"$3\" | |\n| printf \"${FG_GRAY}%s${RESET}${color}%s${RESET}\" \"$label\" \"$value\" | |\n| } | |\n| # ── Parse JSON once ──────────────────────────────────────────────────────── | |\n| cwd=$(echo \"$input\" | jq -r '.workspace.current_dir // .cwd // empty') | |\n| model=$(echo \"$input\" | jq -r '.model.display_name // empty') | |\n| session=$(echo \"$input\" | jq -r '.session_name // empty') | |\n| remaining=$(echo \"$input\" | jq -r '.context_window.remaining_percentage // empty') | |\n| vim_mode=$(echo \"$input\" | jq -r '.vim.mode // empty') | |\n| five_pct=$(echo \"$input\" | jq -r '.rate_limits.five_hour.used_percentage // empty') | |\n| week_pct=$(echo \"$input\" | jq -r '.rate_limits.seven_day.used_percentage // empty') | |\n| # ── Segment: Session name ────────────────────────────────────────────────── | |\n| if [ -n \"$session\" ]; then | |\n| pill \"$BG_DARK\" \"$FG_CYAN\" \"✦ $session\" | |\n| printf ' ' | |\n| fi | |\n| # ── Segment: Directory ──────────────────────────────────────────────────── | |\n| if [ -n \"$cwd\" ]; then | |\n| # Show last 2 path components for context | |\n| dir_display=$(echo \"$cwd\" | awk -F'/' '{ | |\n| n=NF | |\n| if (n>=2) printf \"%s/%s\", $(n-1), $n | |\n| else print $n | |\n| }') | |\n| # Replace $HOME with ~ | |\n| dir_display=$(echo \"$dir_display\" | sed \"s|^$HOME|~|\") | |\n| pill $'\\033[48;5;24m' \"$FG_WHITE\" \" $dir_display\" | |\n| fi | |\n| # ── Segment: Git ────────────────────────────────────────────────────────── | |\n| if [ -n \"$cwd\" ]; then | |\n| git_root=$(GIT_OPTIONAL_LOCKS=0 git -C \"$cwd\" rev-parse --show-toplevel 2>/dev/null) | |\n| if [ -n \"$git_root\" ]; then | |\n| branch=$(GIT_OPTIONAL_LOCKS=0 git -C \"$cwd\" symbolic-ref --short HEAD 2>/dev/null \\ | |\n| || GIT_OPTIONAL_LOCKS=0 git -C \"$cwd\" rev-parse --short HEAD 2>/dev/null) | |\n| if [ -n \"$branch\" ]; then | |\n| # Check for dirty state (fast, no locks) | |\n| if GIT_OPTIONAL_LOCKS=0 git -C \"$cwd\" diff --quiet 2>/dev/null \\ | |\n| && GIT_OPTIONAL_LOCKS=0 git -C \"$cwd\" diff --cached --quiet 2>/dev/null; then | |\n| pill $'\\033[48;5;28m' \"$FG_WHITE\" \" $branch\" | |\n| else | |\n| pill $'\\033[48;5;136m' \"$FG_BLACK\" \" $branch *\" | |\n| fi | |\n| fi | |\n| fi | |\n| fi | |\n| # ── Segment: Vim mode ───────────────────────────────────────────────────── | |\n| if [ -n \"$vim_mode\" ]; then | |\n| printf ' ' | |\n| case \"$vim_mode\" in | |\n| NORMAL) pill \"$BG_MAGENTA\" \"$FG_WHITE\" \"N\" ;; | |\n| INSERT) pill \"$BG_CYAN\" \"$FG_BLACK\" \"I\" ;; | |\n| *) pill \"$BG_DARK\" \"$FG_GRAY\" \"$vim_mode\" ;; | |\n| esac | |\n| fi | |\n| # ── Separator ───────────────────────────────────────────────────────────── | |\n| printf ' %s ' \"$SEP\" | |\n| # ── Segment: Model ──────────────────────────────────────────────────────── | |\n| if [ -n \"$model\" ]; then | |\n| # Shorten: \"Claude 3.5 Sonnet\" → \"3.5 Sonnet\" | |\n| short_model=$(echo \"$model\" | sed 's/^Claude //') | |\n| printf \"${FG_MAGENTA}${BOLD}⬡ %s${RESET}\" \"$short_model\" | |\n| fi | |\n| # ── Segment: Context bar ────────────────────────────────────────────────── | |\n| if [ -n \"$remaining\" ]; then | |\n| remaining_int=$(printf '%.0f' \"$remaining\") | |\n| used_int=$((100 - remaining_int)) | |\n| # Color based on remaining | |\n| if [ \"$remaining_int\" -le 10 ]; then ctx_color=\"$FG_RED\"; ctx_bg=\"$BG_RED\" | |\n| elif [ \"$remaining_int\" -le 25 ]; then ctx_color=\"$FG_ORANGE\"; ctx_bg=\"$BG_ORANGE\" | |\n| elif [ \"$remaining_int\" -le 50 ]; then ctx_color=\"$FG_YELLOW\"; ctx_bg=\"$BG_YELLOW\" | |\n| else ctx_color=\"$FG_GREEN\"; ctx_bg=\"$BG_GREEN\" | |\n| fi | |\n| # 5-char mini progress bar ▓▓▓░░ | |\n| filled=$(( used_int * 5 / 100 )) | |\n| empty=$((5 - filled)) | |\n| bar=\"\" | |\n| for i in $(seq 1 $filled); do bar=\"${bar}▓\"; done | |\n| for i in $(seq 1 $empty); do bar=\"${bar}░\"; done | |\n| printf ' %s ' \"$SEP\" | |\n| printf \"${FG_GRAY}ctx ${RESET}${ctx_color}${bar} %d%%${RESET}\" \"$remaining_int\" | |\n| fi | |\n| # ── Segment: Rate limits ────────────────────────────────────────────────── | |\n| if [ -n \"$five_pct\" ] || [ -n \"$week_pct\" ]; then | |\n| printf ' %s ' \"$SEP\" | |\n| first=1 | |\n| if [ -n \"$five_pct\" ]; then | |\n| pct_int=$(printf '%.0f' \"$five_pct\") | |\n| if [ \"$pct_int\" -ge 90 ]; then rl_color=\"$FG_RED\" | |\n| elif [ \"$pct_int\" -ge 70 ]; then rl_color=\"$FG_YELLOW\" | |\n| else rl_color=\"$FG_GREEN\" | |\n| fi | |\n| printf \"${FG_GRAY}5h${RESET} ${rl_color}%d%%${RESET}\" \"$pct_int\" | |\n| first=0 | |\n| fi | |\n| if [ -n \"$week_pct\" ]; then | |\n| [ \"$first\" -eq 0 ] && printf \"${FG_GRAY} · ${RESET}\" | |\n| pct_int=$(printf '%.0f' \"$week_pct\") | |\n| if [ \"$pct_int\" -ge 90 ]; then rl_color=\"$FG_RED\" | |\n| elif [ \"$pct_int\" -ge 70 ]; then rl_color=\"$FG_YELLOW\" | |\n| else rl_color=\"$FG_GREEN\" | |\n| fi | |\n| printf \"${FG_GRAY}7d${RESET} ${rl_color}%d%%${RESET}\" \"$pct_int\" | |\n| fi | |\n| fi | |\n| # ── Segment: Caveman badge ──────────────────────────────────────────────── | |\n| FLAG=\"${CLAUDE_CONFIG_DIR:-$HOME/.claude}/.caveman-active\" | |\n| if [ -f \"$FLAG\" ] && [ ! -L \"$FLAG\" ]; then | |\n| MODE=$(head -c 64 \"$FLAG\" 2>/dev/null | tr -d '\\n\\r' | tr '[:upper:]' '[:lower:]') | |\n| MODE=$(printf '%s' \"$MODE\" | tr -cd 'a-z0-9-') | |\n| case \"$MODE\" in | |\n| off|lite|full|ultra|wenyan-lite|wenyan|wenyan-full|wenyan-ultra|commit|review|compress) | |\n| printf ' %s ' \"$SEP\" | |\n| if [ -z \"$MODE\" ] || [ \"$MODE\" = \"full\" ]; then | |\n| pill \"$BG_ORANGE\" \"$FG_WHITE\" \"🪨 CAVEMAN\" | |\n| else | |\n| SUFFIX=$(printf '%s' \"$MODE\" | tr '[:lower:]' '[:upper:]') | |\n| pill \"$BG_ORANGE\" \"$FG_WHITE\" \"🪨 $SUFFIX\" | |\n| fi | |\n| SAVINGS_FILE=\"${CLAUDE_CONFIG_DIR:-$HOME/.claude}/.caveman-statusline-suffix\" | |\n| if [ \"${CAVEMAN_STATUSLINE_SAVINGS:-1}\" != \"0\" ] && [ -f \"$SAVINGS_FILE\" ] && [ ! -L \"$SAVINGS_FILE\" ]; then | |\n| SAVINGS=$(head -c 64 \"$SAVINGS_FILE\" 2>/dev/null | tr -d '\\000-\\037') | |\n| [ -n \"$SAVINGS\" ] && printf \" ${FG_ORANGE}${SAVINGS}${RESET}\" | |\n| fi | |\n| ;; | |\n| esac | |\n| fi |", "url": "https://wpnews.pro/news/powerline-status-line-for-claude-cli", "canonical_source": "https://gist.github.com/navidnabavi/edc399b1e36521a6e84e8f9d4f3c4c19", "published_at": "2026-05-30 22:26:20+00:00", "updated_at": "2026-05-30 22:42:44.123453+00:00", "lang": "en", "topics": ["ai-tools"], "entities": ["Claude CLI", "Powerline", "Powerlevel10k"], "alternates": {"html": "https://wpnews.pro/news/powerline-status-line-for-claude-cli", "markdown": "https://wpnews.pro/news/powerline-status-line-for-claude-cli.md", "text": "https://wpnews.pro/news/powerline-status-line-for-claude-cli.txt", "jsonld": "https://wpnews.pro/news/powerline-status-line-for-claude-cli.jsonld"}}