Skip to content

Instantly share code, notes, and snippets.

@roeniss
Last active June 14, 2026 15:24
Show Gist options
  • Select an option

  • Save roeniss/c04ce1db92eb8de7b6b6dc3a52d925ae to your computer and use it in GitHub Desktop.

Select an option

Save roeniss/c04ce1db92eb8de7b6b6dc3a52d925ae to your computer and use it in GitHub Desktop.
Claude Code Statusline Install script

Claude Code — full colored status line

A drop-in status line for Claude Code, installed with one command.

~/code/app  [roeniss/app:main]  [Claude Opus 4.8 high]  [ctx 32%]  [5h:14% 7d:3%]  [PR #42 approved]  [INSERT]  my-session

Install

curl -fsSL https://gist.githubusercontent.com/roeniss/c04ce1db92eb8de7b6b6dc3a52d925ae/raw/claude-code-statusline-install.sh | sh

Then restart Claude Code (or start a new session).

Requires jq:

brew install jq        # macOS
sudo apt install jq    # Debian/Ubuntu

What it shows

Segment Source
Directory current working dir (~ for home)
[repo:branch] git repo owner/name + branch (worktree name appended in worktrees)
[model effort] model display name + effort level
[ctx N%] context usage — blue < 50%, yellow 50–79%, red ≥ 80%
[5h:N% 7d:N%] Claude.ai 5-hour / 7-day rate limits (when available)
[PR #n state] open PR number + review state for the branch
[MODE] vim mode, color-coded (only when vim mode is on)
output style shown only when not default
session name set via /rename

Segments only appear when their data is present, so the line stays compact.

What the installer does

  • Writes ~/.claude/statusline-command.sh
  • Adds a statusLine entry to ~/.claude/settings.json, merging with your existing settings (other keys are untouched)
  • If a status line is already configured, it warns and saves a settings.json.bak.* backup before replacing — remove any other statusline tooling (e.g. ccstatusline) so you don't run two
  • Uses an absolute path resolved at install time, so it works on any machine/username
  • Safe to re-run (idempotent)

Uninstall

Remove the statusLine key from ~/.claude/settings.json and delete ~/.claude/statusline-command.sh.

#!/bin/sh
# ============================================================================
# Full colored status line for Claude Code — one-line installer
# ============================================================================
#
# curl -fsSL https://gist.githubusercontent.com/roeniss/c04ce1db92eb8de7b6b6dc3a52d925ae/raw/claude-code-statusline-install.sh | sh
#
# Shows: <dir> [repo:branch] [model effort] [ctx %] [5h/7d limits]
# [PR #n state] [vim mode] [output style] <session name>
#
# What it does:
# • installs ~/.claude/statusline-command.sh
# • adds "statusLine" to ~/.claude/settings.json (merges; never clobbers
# other keys; backs the file up first if a status line already exists)
#
# Requires: jq (macOS: brew install jq • Debian: sudo apt install jq)
# Safe to re-run. Restart Claude Code afterwards to see it.
# ============================================================================
set -e
CLAUDE_DIR="$HOME/.claude"
SCRIPT="$CLAUDE_DIR/statusline-command.sh"
SETTINGS="$CLAUDE_DIR/settings.json"
# --- dependency check -------------------------------------------------------
if ! command -v jq >/dev/null 2>&1; then
echo "error: 'jq' is required but not installed." >&2
echo " macOS: brew install jq" >&2
echo " Debian: sudo apt install jq" >&2
exit 1
fi
mkdir -p "$CLAUDE_DIR"
# --- write the status line script -------------------------------------------
# Quoted heredoc: nothing below is expanded, written verbatim.
cat > "$SCRIPT" <<'STATUSLINE_EOF'
#!/bin/sh
# Full colored statusline for Claude Code.
# Layout: <dir> [repo:branch] [model effort] [ctx N%] [5h:N% 7d:N%] [PR #n state] [vim MODE] [output_style] <session>
input=$(cat)
cwd=$(printf '%s' "$input" | jq -r '.cwd // .workspace.current_dir // ""')
model=$(printf '%s' "$input" | jq -r '.model.display_name // ""')
effort=$(printf '%s' "$input" | jq -r '.effort.level // empty')
used_pct=$(printf '%s' "$input" | jq -r '.context_window.used_percentage // empty')
repo=$(printf '%s' "$input" | jq -r '.workspace.repo | if . then .owner+"/"+.name else empty end')
branch=$(printf '%s' "$input" | jq -r '.worktree.branch // empty')
git_worktree=$(printf '%s' "$input" | jq -r '.workspace.git_worktree // empty')
pr_number=$(printf '%s' "$input" | jq -r '.pr.number // empty')
pr_state=$(printf '%s' "$input" | jq -r '.pr.review_state // empty')
session_name=$(printf '%s' "$input" | jq -r '.session_name // empty')
five_hour=$(printf '%s' "$input" | jq -r '.rate_limits.five_hour.used_percentage // empty')
seven_day=$(printf '%s' "$input" | jq -r '.rate_limits.seven_day.used_percentage // empty')
vim_mode=$(printf '%s' "$input" | jq -r '.vim.mode // empty')
output_style=$(printf '%s' "$input" | jq -r '.output_style.name // empty')
worktree_name=$(printf '%s' "$input" | jq -r '.worktree.name // empty')
short_cwd=$(printf '%s' "$cwd" | sed "s|^$HOME|~|")
ESC=$(printf '\033')
R="${ESC}[0m" # reset
DIM="38;2;120;120;120" # bracket/punctuation color
out=""
# append joined by two spaces
add() { if [ -n "$out" ]; then out="$out $1"; else out="$1"; fi; }
# colored "[text]" with dim brackets and given fg color for text
brk() { # $1=fg "r;g;b" $2=text
printf '%s' "${ESC}[${DIM}m[${ESC}[38;2;$1m$2${ESC}[${DIM}m]${R}"
}
# Directory (no brackets, leading element)
[ -n "$short_cwd" ] && add "${ESC}[38;2;90;150;210m${short_cwd}${R}"
# Git [repo:branch] or [repo:worktree]
gtxt="$repo"
if [ -n "$branch" ]; then
gtxt="${gtxt:+$gtxt:}$branch"
elif [ -n "$git_worktree" ]; then
gtxt="${gtxt:+$gtxt:}$git_worktree"
fi
[ -n "$worktree_name" ] && gtxt="${gtxt:+$gtxt }(wt:$worktree_name)"
[ -n "$gtxt" ] && add "$(brk "90;190;110" "$gtxt")"
# Model [model effort]
mtxt="$model"
[ -n "$effort" ] && mtxt="$mtxt $effort"
[ -n "$mtxt" ] && add "$(brk "175;150;230" "$mtxt")"
# Context [ctx N%] — color scales with pressure
if [ -n "$used_pct" ]; then
ci=$(printf '%.0f' "$used_pct")
if [ "$ci" -ge 80 ]; then cf="225;95;95"
elif [ "$ci" -ge 50 ]; then cf="225;185;70"
else cf="120;170;200"; fi
add "$(brk "$cf" "ctx ${ci}%")"
fi
# Rate limits [5h:N% 7d:N%]
rate_txt=""
if [ -n "$five_hour" ]; then
fh=$(printf '%.0f' "$five_hour")
rate_txt="5h:${fh}%"
fi
if [ -n "$seven_day" ]; then
sd=$(printf '%.0f' "$seven_day")
rate_txt="${rate_txt:+$rate_txt }7d:${sd}%"
fi
[ -n "$rate_txt" ] && add "$(brk "200;140;90" "$rate_txt")"
# Open PR [PR #n state]
if [ -n "$pr_number" ]; then
pr_txt="PR #$pr_number"
[ -n "$pr_state" ] && pr_txt="$pr_txt $pr_state"
add "$(brk "220;160;80" "$pr_txt")"
fi
# Vim mode [vim MODE]
if [ -n "$vim_mode" ]; then
case "$vim_mode" in
INSERT) vc="100;200;100" ;;
NORMAL) vc="100;160;220" ;;
VISUAL*) vc="220;160;220" ;;
*) vc="200;200;100" ;;
esac
add "$(brk "$vc" "$vim_mode")"
fi
# Output style — only show when not default
if [ -n "$output_style" ] && [ "$output_style" != "default" ]; then
add "$(brk "160;160;160" "$output_style")"
fi
# Session name (from /rename)
[ -n "$session_name" ] && add "${ESC}[38;2;150;150;150m${session_name}${R}"
printf '%s' "$out"
STATUSLINE_EOF
chmod +x "$SCRIPT"
echo "✓ wrote $SCRIPT"
# --- wire it into settings.json ---------------------------------------------
# Absolute path resolved at install time → works on any machine/username.
STATUSLINE_JSON=$(printf '{"type":"command","command":"sh %s/statusline-command.sh"}' "$CLAUDE_DIR")
if [ -f "$SETTINGS" ]; then
# Warn if a status line is already configured — it will be overwritten.
existing=$(jq -r '.statusLine.command // empty' "$SETTINGS" 2>/dev/null || true)
if [ -n "$existing" ]; then
echo "" >&2
echo "⚠ an existing status line is already configured:" >&2
echo " $existing" >&2
echo " It will be replaced. Remove any other statusline tooling (e.g. ccstatusline)" >&2
echo " if you don't want both active." >&2
backup="$SETTINGS.bak.$$"
cp "$SETTINGS" "$backup"
echo " A backup was saved to: $backup" >&2
echo "" >&2
fi
tmp=$(mktemp)
jq --argjson sl "$STATUSLINE_JSON" '.statusLine = $sl' "$SETTINGS" > "$tmp" && mv "$tmp" "$SETTINGS"
echo "✓ merged statusLine into existing $SETTINGS"
else
jq -n --argjson sl "$STATUSLINE_JSON" '{statusLine: $sl}' > "$SETTINGS"
echo "✓ created $SETTINGS"
fi
echo ""
echo "Done. Restart Claude Code (or start a new session) to see the status line."
@roeniss

roeniss commented Jun 14, 2026

Copy link
Copy Markdown
Author

Result:

Screenshot 2026-06-15 at 00 24 36

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