statuslin.es

Single-line usage

One-line status bar showing your directory, git branch (with a * when dirty), model, live effort level, context-window usage, and 5-hour/7-day rate-limit usage.

Updated 2026-06-22

87 copies

Preview

Clean repo
app · main · Opus-4.8 · effort high · ctx 22% · 5h 26% ↻2h6m · 7d 7% ↻2d0h
New session
app · main · Opus-4.8 · effort high · ctx 0%
Dirty branch
app · feat/auth* · Sonnet-4.6 · effort med · ctx 48% · 5h 40% ↻1h11m · 7d 18% ↻2d21h
Near-full
app · main · Opus-4.8 · effort max · ctx 91% · 5h 88% ↻17m · 7d 61% ↻19h59m · Explanatory
1M context
app · main · Fable-5 · effort xhigh · ctx 64% · 5h 33% ↻3h29m · 7d 80% ↻4d23h
Post-compact
app · main · Haiku-4.5 · ctx 0% · 5h 52% ↻4h1m
Worktree
feature · worktree-feature · Opus-4.8 · effort low · ctx 37% · 5h 44% ↻2h49m · 7d 20% ↻1d6h
Non-git
scratch · Opus-4.8 · effort high · ctx 22%

Source

#!/bin/bash

input=$(cat)

dir=$(echo "$input" | jq -r '.workspace.current_dir')
model=$(echo "$input" | jq -r '.model.display_name')
model_id=$(echo "$input" | jq -r '.model.id')
output_style=$(echo "$input" | jq -r '.output_style.name')

dim="\033[2m"
reset="\033[0m"
bold="\033[1m"
cyan="\033[36m"
yellow="\033[33m"
green="\033[32m"
red="\033[31m"
magenta="\033[35m"
blue="\033[34m"

# Color helper: green <50, yellow 50-79, red >=80
color_for_pct() {
    local p=$1
    if [ "$p" -ge 80 ]; then echo "$red"
    elif [ "$p" -ge 50 ]; then echo "$yellow"
    else echo "$green"; fi
}

# Format a duration in seconds → "2h13m" / "47m" / "3d4h"
fmt_duration() {
    local s=$1
    [ "$s" -lt 0 ] && s=0
    local d=$((s / 86400))
    local h=$(((s % 86400) / 3600))
    local m=$(((s % 3600) / 60))
    if [ "$d" -gt 0 ]; then
        printf "%dd%dh" "$d" "$h"
    elif [ "$h" -gt 0 ]; then
        printf "%dh%dm" "$h" "$m"
    else
        printf "%dm" "$m"
    fi
}

# --- Line 1: orientation ---

dir_name=$(basename "$dir")

git_info=""
if git -C "$dir" rev-parse --git-dir &>/dev/null; then
    branch=$(git -C "$dir" -c core.useBuiltinFSMonitor=false rev-parse --abbrev-ref HEAD 2>/dev/null || echo '')
    if [ -n "$branch" ]; then
        if git -C "$dir" -c core.useBuiltinFSMonitor=false diff-index --quiet HEAD -- 2>/dev/null; then
            git_info="$branch"
        else
            git_info="${branch}*"
        fi
    fi
fi

short_model=$(echo "$model" | sed 's/Claude //' | sed 's/ /-/g')
if [[ "$model_id" == *"opus"* ]]; then
    model_str="${bold}${yellow}${short_model}${reset}"
elif [[ "$model_id" == *"sonnet"* ]]; then
    model_str="${cyan}${short_model}${reset}"
elif [[ "$model_id" == *"haiku"* ]]; then
    model_str="${blue}${short_model}${reset}"
else
    model_str="${short_model}"
fi

ctx_pct=$(echo "$input" | jq -r '.context_window.used_percentage // 0' | cut -d. -f1)
ctx_color=$(color_for_pct "$ctx_pct")

now=$(date +%s)
fh_pct_raw=$(echo "$input" | jq -r '.rate_limits.five_hour.used_percentage // empty')
sd_pct_raw=$(echo "$input" | jq -r '.rate_limits.seven_day.used_percentage // empty')

effort=$(echo "$input" | jq -r '.effort.level // empty')
case "$effort" in
    max)    effort_str="${bold}${red}max${reset}" ;;
    xhigh)  effort_str="${bold}${red}xhigh${reset}" ;;
    high)   effort_str="${red}high${reset}" ;;
    medium) effort_str="${yellow}med${reset}" ;;
    low)    effort_str="${green}low${reset}" ;;
    "")     effort_str="" ;;
    *)      effort_str="${dim}${effort}${reset}" ;;
esac

sep="${dim} · ${reset}"
line="${bold}${dir_name}${reset}"
[ -n "$git_info" ] && line+="${sep}${magenta}${git_info}${reset}"
line+="${sep}${model_str}"
[ -n "$effort_str" ] && line+="${sep}${dim}effort${reset} ${effort_str}"
line+="${sep}${dim}ctx${reset} ${ctx_color}${ctx_pct}%${reset}"

if [ -n "$fh_pct_raw" ]; then
    fh_pct=$(printf "%.0f" "$fh_pct_raw")
    fh_color=$(color_for_pct "$fh_pct")
    fh_reset=$(echo "$input" | jq -r '.rate_limits.five_hour.resets_at // empty')
    fh_suffix=""
    [ -n "$fh_reset" ] && fh_suffix=" ${dim}↻$(fmt_duration $((fh_reset - now)))${reset}"
    line+="${sep}${dim}5h${reset} ${fh_color}${fh_pct}%${reset}${fh_suffix}"
fi

if [ -n "$sd_pct_raw" ]; then
    sd_pct=$(printf "%.0f" "$sd_pct_raw")
    sd_color=$(color_for_pct "$sd_pct")
    sd_reset=$(echo "$input" | jq -r '.rate_limits.seven_day.resets_at // empty')
    sd_suffix=""
    [ -n "$sd_reset" ] && sd_suffix=" ${dim}↻$(fmt_duration $((sd_reset - now)))${reset}"
    line+="${sep}${dim}7d${reset} ${sd_color}${sd_pct}%${reset}${sd_suffix}"
fi

if [ "$output_style" != "null" ] && [ "$output_style" != "default" ]; then
    line+="${sep}${dim}${output_style}${reset}"
fi

printf "%b" "$line"

What it shows

  • Current directory name (basename of the working directory)
  • Current git branch, with a trailing * when there are uncommitted changes
  • Model name, shortened (the Claude prefix stripped and spaces replaced with hyphens, e.g. Opus-4.8)
  • Effort level, when the session reports one (medium is abbreviated to med)
  • Context window usage as a percentage
  • 5-hour rate-limit usage as a percentage, with time until reset
  • 7-day rate-limit usage as a percentage, with time until reset
  • Output style name, when it is not the default

Requirements

  • bash
  • jq for parsing the JSON that Claude Code sends on stdin
  • git, used only to detect the branch and dirty state (the script still works outside a git repository)
  • Standard Unix utilities: date, sed, cut, basename, printf
  • A terminal that renders ANSI colors, bold, and dim text
  • No Nerd Font needed; the only special characters are plain Unicode symbols: the middle dot · used as the segment separator, and the reset symbol ↻
  • No network access needed

Behavior notes

  • Everything renders on a single line, with segments separated by dim middle dots
  • The git branch segment disappears entirely when the directory is not a git repository, as in the scratch-directory scenario
  • A dirty working tree adds a * after the branch name (feat/auth*); a clean tree shows the bare branch name
  • The 5h and 7d segments only appear when the matching rate-limit data is present: the new-session scenario shows neither, and the post-compact scenario shows only 5h
  • The reset countdown after each rate-limit percentage only appears when a reset time is provided
  • The effort segment disappears when the session reports no effort level, as in the Haiku scenario
  • Effort levels are color-coded: max and xhigh in bold red, high in red, medium in yellow, low in green
  • Context and rate-limit percentages change color by value: green below 50, yellow from 50 to 79, red at 80 and above
  • The model name is colored by family: Opus in bold yellow, Sonnet in cyan, Haiku in blue; other models like Fable 5 render uncolored
  • Context usage falls back to 0% when the session has no usage data yet, as in the new-session and post-compact scenarios
  • The output style name appears at the end only when it is not default, as with Explanatory in the near-full-context scenario

More status lines

Dreambase Panel

150 copies

╭─ CONTEXT ────────────────────────────────────────────╮ ████▊░░░░░░░░░░░░░░░░░ 22% of 200K · GOOD ├─ STATS ──────────────────────────────────────────────┤ 44.0K 1.4K $0.41 ⏱ 10m 12s +128/-34 ├─ REPO ───────────────────────────────────────────────┤ Opus 4.8 · main · 16:21 ╰──────────────────────────────────────────────────────╯
Opus 4.8 [high] ~/app main 16:20:55 | ⛁ ██░░░░░░░░ 22% | 5h ●◔○○○ 26% ↻2h7m | 7d ◔○○○○○○ 7% ↻2d1h │ $0.41 ⏱ 10m
Opus 4.8 main app 44k/200k $0.41

Activity Feed

36 copies

Opus 4.8 high ctx 22% app (main) PR #1287 $0.41 · 10m +128 -34 Session 74% left Resets in 2h 6m Weekly 93% left Resets in 2d 0h Fable 85% left Resets in 2d 0h ◐ Read:index.ts ✓ Read×1 ✓ Bash×1 ✓ Edit×1 ✓ Grep×1 ◐ code-reviewer Review the change for regressions
████▊░░░░░░░░░░░░░░░░░ 22% of 200K · GOOD 44.0K 1.4K $0.41 ⏱ 10m 12s +128/-34 Opus 4.8 · main · 16:22
◆ Opus 4.8 │ ▪ app │ ⎇ main │ ◷ 16:20 │ 26% (44K/167K) │ 26% ↻2h6m7% ⟳2d0h