Two lines in Catppuccin colors: model with effort, output style, path, branch and a git clean or dirty mark, then gradient bars for context and the five-hour and seven-day limits with reset times.

0 copies

In Claude Desktop? Add this status line with statusline-anywhere.

Preview

Clean repo
🤖 Opus 4.8 ⚡high 💡 │ 🎨 default │ 📂 ~/app 🌿(main)✅ 🧠 Context ██░░░░░░░░ 22% │ 5H ███░░░░░░░ 26% (2h6m) │ 7D █░░░░░░░░░ 7% (Tue)
New session
🤖 Opus 4.8 ⚡high │ 🎨 default │ 📂 ~/app 🌿(main)✅ 🧠 Context ░░░░░░░░░░ 0% │ 5H ░░░░░░░░░░ 0% │ 7D ░░░░░░░░░░ 0% (loading..)
Dirty branch
🤖 Sonnet 4.6 ⚡medium 💡 │ 🎨 default │ 📂 ~/app 🌿(feat/auth)📝!? 🧠 Context █████░░░░░ 48% │ 5H ████░░░░░░ 40% (1h11m) │ 7D ██░░░░░░░░ 18% (Wed)
Near-full
🤖 Opus 4.8 ⚡max 💡 │ 🎨 Explanatory │ 📂 ~/app 🌿(main)✅ 🧠 Context █████████░ 91% │ 5H █████████░ 88% (0h17m) │ 7D ██████░░░░ 61% (Mon)
1M context
🤖 Fable 5 ⚡xhigh 💡 │ 🎨 default │ 📂 ~/app 🌿(main)✅ 🧠 Context ██████░░░░ 64% │ 5H ███░░░░░░░ 33% (3h29m) │ 7D ████████░░ 80% (Fri)
Post-compact
🤖 Haiku 4.5 │ 🎨 default │ 📂 ~/app 🌿(main)✅ 🧠 Context ░░░░░░░░░░ 0% │ 5H █████░░░░░ 52% (4h1m) │ 7D ░░░░░░░░░░ 0% ()
Worktree
🤖 Opus 4.8 ⚡low │ 🎨 default │ 📂 ~/.wt/feature 🌿(worktree-feature)✅ 🧠 Context ████░░░░░░ 37% │ 5H ████░░░░░░ 44% (2h49m) │ 7D ██░░░░░░░░ 20% (Mon)
Non-git
🤖 Opus 4.8 ⚡high │ 🎨 default │ 📂 ~/scratch 🧠 Context ██░░░░░░░░ 22% │ 5H ░░░░░░░░░░ 0% │ 7D ░░░░░░░░░░ 0% (loading..)

What it does

Two lines in Catppuccin colors: model, effort, output style, path and branch with a git clean or dirty mark, then gradient bars for context and the 5-hour and 7-day limits.

Written in
Bash
Network access
None
Works in
Terminal

How it works

  1. Reads model, effort, thinking, output style, folder, tokens and rate_limits from stdin.
  2. Shows the git branch with ✅ when clean, or 📝 plus + staged, ! edited, ? new.
  3. Context % is input plus cache tokens over the window size. Past that size it assumes 1M.
  4. Limit bars show time left, like (2h6m), and the 7-day reset weekday, like (Tue).

Good to know

  • Needs jq and git, plus a terminal with 24-bit color for the gradients.
  • Until rate_limits arrive (Pro and Max plans send them), both limit bars read 0% with (loading..).
  • Puts its own folder first on PATH, so a jq copied beside the script is found.

Source

#!/bin/bash
# ============================================================================
# Awesome Statusline - DEFAULT Mode
# ============================================================================
# Line 1: 🤖 Model | 🎨 Style | 📂 path 🌿(branch)✅
# Line 2: 🧠 Context bar % | 5H bar % (time) | 7D bar % (day)
# % numbers use gradient end color + Bold
# ============================================================================
# v2.1.1 - Updated from v2.1.0
# ============================================================================

# Ensure a bundled jq (copied next to this script by the installer) is found,
# even when Claude Code launches the statusline with a minimal PATH — common on
# Windows / GUI launches where a winget-installed jq is not on PATH yet.
export PATH="$(dirname "$0"):$PATH"

input=$(cat)

# Parse JSON input
MODEL=$(echo "$input" | jq -r '.model.display_name // "Unknown"')
CURRENT_DIR=$(echo "$input" | jq -r '.workspace.current_dir // "."')
CONTEXT_SIZE=$(echo "$input" | jq -r '.context_window.context_window_size // 200000')
CURRENT_USAGE=$(echo "$input" | jq -r '.context_window.current_usage // null')
OUTPUT_STYLE=$(echo "$input" | jq -r '.output_style.name // ""')

# Rate limits (official API - available for Pro/Max subscribers)
FIVE_HOUR_PCT=$(echo "$input" | jq -r '.rate_limits.five_hour.used_percentage // empty')
FIVE_HOUR_RESET=$(echo "$input" | jq -r '.rate_limits.five_hour.resets_at // empty')
SEVEN_DAY_PCT=$(echo "$input" | jq -r '.rate_limits.seven_day.used_percentage // empty')
SEVEN_DAY_RESET=$(echo "$input" | jq -r '.rate_limits.seven_day.resets_at // empty')

# ============================================================================
# Colors (variables instead of functions to avoid newline issues)
# ============================================================================
RESET="\033[0m"
BOLD="\033[1m"
CLR="\033[K"  # Clear to end of line

C_TEAL="\033[38;2;148;226;213m"
C_PINK="\033[38;2;245;194;231m"
C_PEACH="\033[38;2;250;179;135m"
C_GREEN="\033[38;2;166;227;161m"
C_SUBTEXT="\033[38;2;166;173;200m"
C_LAVENDER="\033[38;2;180;190;254m"
C_YELLOW="\033[38;2;249;226;175m"
C_OVERLAY="\033[38;2;108;112;134m"
C_LATTE_GREEN="\033[38;2;64;160;43m"
C_LATTE_RED="\033[38;2;210;15;57m"
C_LATTE_YELLOW="\033[38;2;223;142;29m"

# ============================================================================
# Gradient Functions
# ============================================================================
get_context_gradient_color() {
    local pct=$1
    local r g b
    if [[ $pct -lt 30 ]]; then
        local t=$((pct * 100 / 30))
        r=$((245 + (230 - 245) * t / 100))
        g=$((194 + (69 - 194) * t / 100))
        b=$((231 + (83 - 231) * t / 100))
    elif [[ $pct -lt 70 ]]; then
        local t=$(((pct - 30) * 100 / 40))
        r=$((230 + (210 - 230) * t / 100))
        g=$((69 + (15 - 69) * t / 100))
        b=$((83 + (57 - 83) * t / 100))
    else
        r=210; g=15; b=57
    fi
    echo "$r;$g;$b"
}

# 5H: Mocha Lavender → Latte Blue → Latte Red
get_usage_gradient_color() {
    local pct=$1
    local r g b
    if [[ $pct -lt 50 ]]; then
        local t=$((pct * 2))
        r=$((180 + (30 - 180) * t / 100))
        g=$((190 + (102 - 190) * t / 100))
        b=$((254 + (245 - 254) * t / 100))
    else
        local t=$(((pct - 50) * 2))
        r=$((30 + (210 - 30) * t / 100))
        g=$((102 + (15 - 102) * t / 100))
        b=$((245 + (57 - 245) * t / 100))
    fi
    echo "$r;$g;$b"
}

# 7D: Mocha Yellow → Latte Peach → Latte Red
get_usage_7d_gradient_color() {
    local pct=$1
    local r g b
    if [[ $pct -lt 50 ]]; then
        local t=$((pct * 2))
        r=$((249 + (254 - 249) * t / 100))
        g=$((226 + (100 - 226) * t / 100))
        b=$((175 + (11 - 175) * t / 100))
    else
        local t=$(((pct - 50) * 2))
        r=$((254 + (210 - 254) * t / 100))
        g=$((100 + (15 - 100) * t / 100))
        b=$((11 + (57 - 11) * t / 100))
    fi
    echo "$r;$g;$b"
}

generate_bar() {
    local pct=$1
    local width=$2
    local type=$3
    local bar=""
    local filled=$(( (pct * width + 50) / 100 ))
    [[ $filled -gt $width ]] && filled=$width

    local end_color
    case "$type" in
        context) end_color=$(get_context_gradient_color "$pct") ;;
        7d) end_color=$(get_usage_7d_gradient_color "$pct") ;;
        *) end_color=$(get_usage_gradient_color "$pct") ;;
    esac

    for ((i=0; i<filled; i++)); do
        local block_pct=$((i * 100 / width))
        local color
        case "$type" in
            context) color=$(get_context_gradient_color "$block_pct") ;;
            7d) color=$(get_usage_7d_gradient_color "$block_pct") ;;
            *) color=$(get_usage_gradient_color "$block_pct") ;;
        esac
        bar+="\033[38;2;${color}m█"
    done

    for ((i=0; i<width-filled; i++)); do
        bar+="\033[38;2;${end_color}m░"
    done

    printf "%b%b" "$bar" "$RESET"
}

# ============================================================================
# Line 1: Model | Style | Directory + Git
# ============================================================================

# Model (bold)
MODEL_DISPLAY="🤖 ${BOLD}${C_TEAL}${MODEL}${RESET}"

# Reasoning effort + extended thinking (effort.level: low|medium|high|xhigh|max; absent if model lacks effort param)
EFFORT=$(echo "$input" | jq -r '.effort.level // empty')
THINKING=$(echo "$input" | jq -r '.thinking.enabled // empty')
[ -n "$EFFORT" ] && MODEL_DISPLAY="${MODEL_DISPLAY} \033[38;2;250;179;135m⚡${EFFORT}${RESET}"
[ "$THINKING" = "true" ] && MODEL_DISPLAY="${MODEL_DISPLAY} \033[38;2;249;226;175m💡${RESET}"

# Output style
STYLE_DISPLAY=""
[[ -n "$OUTPUT_STYLE" ]] && STYLE_DISPLAY=" │ 🎨 ${C_PEACH}${OUTPUT_STYLE}${RESET}"

# Directory (shorten $HOME to ~). Built with a case match rather than
# ${CURRENT_DIR/$HOME/~}: bash 5.2+ tilde-expands the replacement, turning ~
# back into $HOME and silently disabling the shortening.
case "$CURRENT_DIR" in
    "$HOME")    DIR_PATH="~" ;;
    "$HOME"/*)  DIR_PATH="~${CURRENT_DIR#$HOME}" ;;
    *)          DIR_PATH="$CURRENT_DIR" ;;
esac
DIR_DISPLAY="📂 ${C_SUBTEXT}${DIR_PATH}${RESET}"

# Git
GIT_DISPLAY=""
cd "$CURRENT_DIR" 2>/dev/null
if git rev-parse --git-dir > /dev/null 2>&1; then
    BRANCH=$(git branch --show-current 2>/dev/null)
    [[ -n "$BRANCH" ]] && GIT_DISPLAY="${C_LATTE_GREEN}🌿(${BRANCH})${RESET}"

    STAGED=$(git diff --cached --name-only 2>/dev/null | wc -l | tr -d ' ')
    UNSTAGED=$(git diff --name-only 2>/dev/null | wc -l | tr -d ' ')
    UNTRACKED=$(git ls-files --others --exclude-standard 2>/dev/null | wc -l | tr -d ' ')

    if [[ "$STAGED" -eq 0 && "$UNSTAGED" -eq 0 && "$UNTRACKED" -eq 0 ]]; then
        GIT_DISPLAY="${GIT_DISPLAY}${C_GREEN}✅${RESET}"
    else
        STATUS=""
        [[ "$STAGED" -gt 0 ]] && STATUS="${STATUS}+"
        [[ "$UNSTAGED" -gt 0 ]] && STATUS="${STATUS}!"
        [[ "$UNTRACKED" -gt 0 ]] && STATUS="${STATUS}?"
        GIT_DISPLAY="${GIT_DISPLAY}${C_LATTE_YELLOW}📝${STATUS}${RESET}"
    fi
fi

LINE1="${MODEL_DISPLAY}${STYLE_DISPLAY} │ ${DIR_DISPLAY} ${GIT_DISPLAY}"

# ============================================================================
# Line 2: Context + 5H + 7D
# ============================================================================

# Context
CONTEXT_PERCENT=0
if [[ "$CURRENT_USAGE" != "null" && -n "$CURRENT_USAGE" ]]; then
    INPUT_TOKENS=$(echo "$CURRENT_USAGE" | jq -r '.input_tokens // 0')
    CACHE_CREATE=$(echo "$CURRENT_USAGE" | jq -r '.cache_creation_input_tokens // 0')
    CACHE_READ=$(echo "$CURRENT_USAGE" | jq -r '.cache_read_input_tokens // 0')
    CURRENT_TOKENS=$((INPUT_TOKENS + CACHE_CREATE + CACHE_READ))

    # harness sometimes reports a stale 200k window even when the model is
    # actually running the 1m context beta (seen on opus and fable alike) --
    # usage exceeding the declared window is proof the declared size is wrong
    [[ "$CURRENT_TOKENS" -gt "$CONTEXT_SIZE" ]] && CONTEXT_SIZE=1000000

    [[ "$CONTEXT_SIZE" -gt 0 ]] && CONTEXT_PERCENT=$((CURRENT_TOKENS * 100 / CONTEXT_SIZE))
fi

CTX_BAR=$(generate_bar "$CONTEXT_PERCENT" 10 "context")
CTX_END_COLOR=$(get_context_gradient_color "$CONTEXT_PERCENT")
CTX_DISPLAY="🧠 ${C_PINK}Context${RESET} ${CTX_BAR} ${BOLD}\033[38;2;${CTX_END_COLOR}m${CONTEXT_PERCENT}%${RESET}"

# Format 5H reset as "1h2m"
format_time_remaining() {
    local reset_epoch="$1"
    [[ -z "$reset_epoch" || "$reset_epoch" == "null" ]] && return
    local now_epoch=$(date +%s)
    local remaining=$((reset_epoch - now_epoch))
    [[ $remaining -lt 0 ]] && remaining=0
    local hours=$((remaining / 3600))
    local minutes=$(((remaining % 3600) / 60))
    echo "${hours}h${minutes}m"
}

# Cross-platform date formatting (BSD/macOS vs GNU/Linux)
_date_fmt() {
    local epoch="$1" fmt="$2"
    local out=""
    out=$(date -j -f "%s" "$epoch" "+$fmt" 2>/dev/null) && [[ -n "$out" ]] && { echo "$out"; return; }
    out=$(date -r "$epoch" "+$fmt" 2>/dev/null) && [[ -n "$out" ]] && { echo "$out"; return; }
    date -d "@$epoch" "+$fmt" 2>/dev/null
}

# Format 7D reset as "Mon"
format_reset_day() {
    local reset_epoch="$1"
    [[ -z "$reset_epoch" || "$reset_epoch" == "null" ]] && return
    _date_fmt "$reset_epoch" "%a"
}

# Usage from rate_limits
if [[ -n "$FIVE_HOUR_PCT" ]]; then
    FIVE_HOUR=$(printf "%.0f" "$FIVE_HOUR_PCT")
    SEVEN_DAY=$(printf "%.0f" "${SEVEN_DAY_PCT:-0}")

    FIVE_RESET_FMT=$(format_time_remaining "$FIVE_HOUR_RESET")
    SEVEN_RESET_FMT=$(format_reset_day "$SEVEN_DAY_RESET")

    FIVE_BAR=$(generate_bar "$FIVE_HOUR" 10 "5h")
    SEVEN_BAR=$(generate_bar "$SEVEN_DAY" 10 "7d")

    FIVE_END_COLOR=$(get_usage_gradient_color "$FIVE_HOUR")
    SEVEN_END_COLOR=$(get_usage_7d_gradient_color "$SEVEN_DAY")

    FIVE_DISPLAY="${C_LAVENDER}5H${RESET} ${FIVE_BAR} ${BOLD}\033[38;2;${FIVE_END_COLOR}m${FIVE_HOUR}%${RESET} (${FIVE_RESET_FMT})"
    SEVEN_DISPLAY="${C_YELLOW}7D${RESET} ${SEVEN_BAR} ${BOLD}\033[38;2;${SEVEN_END_COLOR}m${SEVEN_DAY}%${RESET} (${SEVEN_RESET_FMT})"

    LINE2="${CTX_DISPLAY} │ ${FIVE_DISPLAY} │ ${SEVEN_DISPLAY}"
else
    FIVE_BAR=$(generate_bar 0 10 "5h")
    SEVEN_BAR=$(generate_bar 0 10 "7d")
    FIVE_END_COLOR=$(get_usage_gradient_color 0)
    SEVEN_END_COLOR=$(get_usage_7d_gradient_color 0)
    FIVE_DISPLAY="${C_LAVENDER}5H${RESET} ${FIVE_BAR} ${BOLD}\033[38;2;${FIVE_END_COLOR}m0%${RESET}"
    SEVEN_DISPLAY="${C_YELLOW}7D${RESET} ${SEVEN_BAR} ${BOLD}\033[38;2;${SEVEN_END_COLOR}m0%${RESET}"
    LINE2="${CTX_DISPLAY} │ ${FIVE_DISPLAY} │ ${SEVEN_DISPLAY} ${C_OVERLAY}(loading..)${RESET}"
fi

# ============================================================================
# Output (using printf with line clear)
# ============================================================================
printf "%b%b\n" "$LINE1" "$CLR"
printf "%b%b\n" "$LINE2" "$CLR"

More status lines

Model: Opus 4.8 | Thinking: high | Context: [▰▰▱▱▱▱▱▱▱▱] 45k/200k (22%) | cwd: ~/app | ⎇ main | (+0,-0) Cost: $0.41 | Block: 2hr 6m | Weekly: 7.0% | Session: 10m | In: 916.7 t/s | Out: 29.2 t/s | Cached: 2k | Session: [▰▱▱▱▱] 26.0% Mem: 0.8G/1.0G | (*゚∀゚*) | Session ID: b8e1c0d2-4a6f-4e2a-9c1b-3f5d7a9e2c10
 Opus 4.8 │  app │  main high  ██░░░░░░░░░░ 22% │  $0.41 │  10m 12s │  5h:26%
🤖 Opus 4.8 ⚡high 💡 │ 🎨 default │ ✅ git clean │ no env 📂 /home/user/app 🌿(main) │ 💰 0.41$ │ ⏰ 10m 🧠 Context █████████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 22% used (44k/200k) 🚀 5H Limit ██████████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 26% (Resets in 2h6m) 🌟 7D Limit ███░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 7% (Resets Oct 20 at 3pm)
Opus 4.8 [high] ~/app main 16:20:55 | ⛁ ██░░░░░░░░ 22% | 5h ●◔○○○ 26% ↻2h7m | 7d ◔○○○○○○ 7% ↻2d1h │ $0.41 ⏱ 10m

Activity Feed

51 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
Opus 4.8 │ ✍️ 22% │ app (main) │ ● high current ●●○○○○○○○○ 26% ⟳ 6:59pm weekly ○○○○○○○○○○ 7% ⟳ aug 1, 5:52pm

Related mods

Terminal

❯ /deck demo ⎿ deck: Sample plan running above the prompt, with sample routing until real ones arrive. [-] 0: deck ▾ · 5 rows 22:11:41 ⇄ Model route opus = opus jev: haiku · not applied effort ▁▃·· medi = kept ✕ ✓ Orders module Done · 12/12 · 2/2 agents 100% ✕ ● Context 44k / 200k 22% ✕ ◔ Session · 5h 5h · 26% used ↻ 2:04:24 ✕ ◔ Weekly · 7d 7d · 7% used ↻ 2d 0h 57m ✕ ❯  ⏵⏵ auto mode on (shift+tab to cycle) · ← for agents [ Deck 1 ]

Claude Desktop

Deck in Claude Desktop

A cockpit for Claude Code: plan bars and subagent strips, context, usage limits with reset countdowns and burn rates, spend, the model route and a pet. Six bar styles, three collapsed looks. CLI and Desktop.

Terminal

[-] zZ ▀▄ ▄▀ ▄▄▀▀▀▀▀▀▀▀▀▀ ▀▀▀▄▄▄ ▀▀▀▀▀▀▀▀▀▀▀▀ ▀▀▀▀▀▀▀▀ ctx 22% [ Pet ♥ ] [ ⚙ ] [ ↻ Adventurer ] [ Hide ] ❯ 

Claude Desktop

Pixel Cat in Claude Desktop

A little pixel cat that wanders above the Claude Code prompt, watches your usage limits and announces when work finishes; or switch packs for an adventurer who mines, chops trees and fights zombies

Terminal

╭─────────────────────────────────────────────────────────────────────────────────────────────╮ [-] │ ◆ context 44k of 200k · compacts at 167k 22% │ │ ████████████████████────────────────────────────────────────────────────────░░░░░░░░░░░░░░░ │ │ ■ system prompt 1.9k 1% ■ system tools 28k 14% ■ skills 2k 1% ■ messages 12k 6% │ │ ─ free space 123k ░ autocompact buffer 33k │ ╰─────────────────────────────────────────────────────────────────────────────────────────────╯ ❯ 

Claude Desktop

Context Bar in Claude Desktop

Your context window as a stacked bar above the prompt, a color per category, with token counts and the compaction point. /context-bar shows or hides it.

Terminal

BURN ▁ ▂ *▂▆ ▃ $0.41 = 0.04 burritos [-] 5h 26% in 2h 5m ▅▄█▅▅▆█▆███▅█ opus 4.8 44k in 1k out wk 7% in 2d 0h █████████████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ lifetime $0.41 hide ❯ 

Claude Desktop

Burn Meter in Claude Desktop

Live session cost odometer above the prompt: a burning fuse, real-world comparisons, threshold alerts