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
Preview
🤖 Opus 4.8 ⚡high 💡 │ 🎨 default │ 📂 ~/app 🌿(main)✅
🧠 Context ██░░░░░░░░ 22% │ 5H ███░░░░░░░ 26% (2h6m) │ 7D █░░░░░░░░░ 7% (Tue)
🤖 Opus 4.8 ⚡high │ 🎨 default │ 📂 ~/app 🌿(main)✅
🧠 Context ░░░░░░░░░░ 0% │ 5H ░░░░░░░░░░ 0% │ 7D ░░░░░░░░░░ 0% (loading..)
🤖 Sonnet 4.6 ⚡medium 💡 │ 🎨 default │ 📂 ~/app 🌿(feat/auth)📝!?
🧠 Context █████░░░░░ 48% │ 5H ████░░░░░░ 40% (1h11m) │ 7D ██░░░░░░░░ 18% (Wed)
🤖 Opus 4.8 ⚡max 💡 │ 🎨 Explanatory │ 📂 ~/app 🌿(main)✅
🧠 Context █████████░ 91% │ 5H █████████░ 88% (0h17m) │ 7D ██████░░░░ 61% (Mon)
🤖 Fable 5 ⚡xhigh 💡 │ 🎨 default │ 📂 ~/app 🌿(main)✅
🧠 Context ██████░░░░ 64% │ 5H ███░░░░░░░ 33% (3h29m) │ 7D ████████░░ 80% (Fri)
🤖 Haiku 4.5 │ 🎨 default │ 📂 ~/app 🌿(main)✅
🧠 Context ░░░░░░░░░░ 0% │ 5H █████░░░░░ 52% (4h1m) │ 7D ░░░░░░░░░░ 0% ()
🤖 Opus 4.8 ⚡low │ 🎨 default │ 📂 ~/.wt/feature 🌿(worktree-feature)✅
🧠 Context ████░░░░░░ 37% │ 5H ████░░░░░░ 44% (2h49m) │ 7D ██░░░░░░░░ 20% (Mon)
🤖 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
- Reads model, effort, thinking, output style, folder, tokens and rate_limits from stdin.
- Shows the git branch with ✅ when clean, or 📝 plus + staged, ! edited, ? new.
- Context % is input plus cache tokens over the window size. Past that size it assumes 1M.
- 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
One Dark Triptych
15 copies
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
Dracula Two-Liner
0 copies
Opus 4.8 │ app │ main high
██░░░░░░░░░░ 22% │ $0.41 │ 10m 12s │ 5h:26%
Catppuccin Wide Bars
0 copies
🤖 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)
Pace Dot Meters
94 copies
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
Usage Dot Bars
20 copies
Opus 4.8 │ ✍️ 22% │ app (main) │ ● high
current ●●○○○○○○○○ 26% ⟳ 6:59pm
weekly ○○○○○○○○○○ 7% ⟳ aug 1, 5:52pmRelated 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

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

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

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

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