Statusline Implementation
Complete reference for building Claude Code status line scripts with themes, modules, and helpers.
Themes
Five built-in themes with consistent indicator mappings:
Theme: default
Standard emoji theme - works in all modern terminals.
# Status indicators (3-level: good/warn/critical)
STATUS_OK="🟢"
STATUS_WARN="🟡"
STATUS_CRIT="🔴"
# Status indicators (4-level: good/fair/warn/critical)
STATUS_4_OK="🟢"
STATUS_4_FAIR="🔵"
STATUS_4_WARN="🟡"
STATUS_4_CRIT="🔴"
# Module icons
ICON_DIR="📁"
ICON_MODEL="🤖"
ICON_CONTEXT="📊"
ICON_GIT="🌿"
ICON_COST="💰"
ICON_RATE="⚡"
ICON_PROJECT="📦"
ICON_LINES="📝"
ICON_BATTERY="🔋"
ICON_CPU="💻"
ICON_MEM="🧠"
ICON_DOCKER="🐳"
ICON_TIME="🕐"
ICON_CCA="☁️"
# Separators
SEP=" | "
Theme: minimal
Geometric shapes - clean and compact.
STATUS_OK="◦"
STATUS_WARN="○"
STATUS_CRIT="●"
STATUS_4_OK="◦"
STATUS_4_FAIR="◦"
STATUS_4_WARN="○"
STATUS_4_CRIT="●"
ICON_DIR="→"
ICON_MODEL=""
ICON_CONTEXT=""
ICON_GIT="⎇"
ICON_COST="$"
ICON_RATE="~"
ICON_PROJECT=""
ICON_LINES="±"
ICON_BATTERY="◐"
ICON_CPU=""
ICON_MEM=""
ICON_DOCKER="◫"
ICON_TIME=""
ICON_CCA="☁"
SEP=" "
Theme: vibrant
Bold, colorful emoji - high visibility.
STATUS_OK="💚"
STATUS_WARN="💛"
STATUS_CRIT="🧡"
STATUS_4_OK="💚"
STATUS_4_FAIR="💙"
STATUS_4_WARN="💛"
STATUS_4_CRIT="❤️"
ICON_DIR="📂"
ICON_MODEL="🤖"
ICON_CONTEXT="🎯"
ICON_GIT="🔀"
ICON_COST="💵"
ICON_RATE="⚡"
ICON_PROJECT="🚀"
ICON_LINES="✏️"
ICON_BATTERY="🔌"
ICON_CPU="🖥️"
ICON_MEM="💾"
ICON_DOCKER="🐋"
ICON_TIME="⏰"
ICON_CCA="🌐"
SEP=" │ "
Theme: monochrome
ASCII only - maximum compatibility.
STATUS_OK="[OK]"
STATUS_WARN="[~~]"
STATUS_CRIT="[!!]"
STATUS_4_OK="[OK]"
STATUS_4_FAIR="[--]"
STATUS_4_WARN="[~~]"
STATUS_4_CRIT="[!!]"
ICON_DIR="DIR:"
ICON_MODEL=""
ICON_CONTEXT="CTX:"
ICON_GIT="GIT:"
ICON_COST="$"
ICON_RATE="RATE:"
ICON_PROJECT="PRJ:"
ICON_LINES="+/-"
ICON_BATTERY="BAT:"
ICON_CPU="CPU:"
ICON_MEM="MEM:"
ICON_DOCKER="DOCK:"
ICON_TIME=""
ICON_CCA="CCA:"
SEP=" | "
Theme: nerd
Nerd Font glyphs - requires Nerd Fonts.
STATUS_OK=""
STATUS_WARN=""
STATUS_CRIT=""
STATUS_4_OK=""
STATUS_4_FAIR=""
STATUS_4_WARN=""
STATUS_4_CRIT=""
ICON_DIR=""
ICON_MODEL=""
ICON_CONTEXT=""
ICON_GIT=""
ICON_COST=""
ICON_RATE=""
ICON_PROJECT=""
ICON_LINES=""
ICON_BATTERY=""
ICON_CPU=""
ICON_MEM=""
ICON_DOCKER=""
ICON_TIME=""
ICON_CCA=""
SEP=" "
Helper Functions
get_status (3-level)
Returns status indicator based on percentage threshold.
get_status() {
local pct=$1
local warn_threshold=${2:-50}
local crit_threshold=${3:-75}
if (( pct >= crit_threshold )); then
echo "$STATUS_CRIT"
elif (( pct >= warn_threshold )); then
echo "$STATUS_WARN"
else
echo "$STATUS_OK"
fi
}
get_status_4level (4-level)
Returns status indicator with fair level (for rate limits).
get_status_4level() {
local pct=$1
local fair_threshold=${2:-25}
local warn_threshold=${3:-50}
local crit_threshold=${4:-75}
if (( pct >= crit_threshold )); then
echo "$STATUS_4_CRIT"
elif (( pct >= warn_threshold )); then
echo "$STATUS_4_WARN"
elif (( pct >= fair_threshold )); then
echo "$STATUS_4_FAIR"
else
echo "$STATUS_4_OK"
fi
}
progress_bar
Creates visual progress bar.
progress_bar() {
local pct=$1
local width=${2:-10}
local filled=$(( pct * width / 100 ))
local empty=$(( width - filled ))
printf "["
printf "%${filled}s" | tr ' ' '='
printf "%${empty}s" | tr ' ' '-'
printf "]"
}
safe_int
Safely converts value to integer.
safe_int() {
local val="$1"
local default="${2:-0}"
# Remove decimal portion and non-numeric chars
val="${val%%.*}"
val="${val//[^0-9-]/}"
if [[ "$val" =~ ^-?[0-9]+$ ]]; then
echo "$val"
else
echo "$default"
fi
}
json_get
Safe JSON extraction (handles missing jq gracefully).
json_get() {
local json="$1"
local path="$2"
local default="${3:-}"
if command -v jq &>/dev/null; then
local result
result=$(echo "$json" | jq -r "$path // empty" 2>/dev/null)
echo "${result:-$default}"
else
echo "$default"
fi
}
Modules
Module: directory
Current directory name (basename only).
# --- directory ---
get_directory() {
local dir
dir=$(json_get "$INPUT" '.workspace.current_dir')
if [ -n "$dir" ]; then
echo "${ICON_DIR}$(basename "$dir")"
fi
}
DIRECTORY=$(get_directory)
Module: model
Claude model display name.
# --- model ---
get_model() {
local model
model=$(json_get "$INPUT" '.model.display_name' 'Claude')
# Shorten common names
case "$model" in
"Claude Opus 4.5") echo "${ICON_MODEL}Opus4.5" ;;
"Claude Sonnet 4") echo "${ICON_MODEL}Sonnet4" ;;
"Claude Haiku 3.5") echo "${ICON_MODEL}Haiku3.5" ;;
*) echo "${ICON_MODEL}${model}" ;;
esac
}
MODEL=$(get_model)
Module: context
Context window usage with optional progress bar.
# --- context ---
get_context() {
local pct
pct=$(json_get "$INPUT" '.context_window.used_percentage' '0')
pct=$(safe_int "$pct")
local status
status=$(get_status "$pct" 50 75)
if [ "$DISPLAY_MODE" = "verbose" ]; then
local bar
bar=$(progress_bar "$pct" 10)
echo "${ICON_CONTEXT}${bar} ${pct}%${status}"
else
echo "${ICON_CONTEXT}${pct}%${status}"
fi
}
CONTEXT=$(get_context)
Module: git
Branch name and status indicators.
# --- git ---
get_git() {
local dir
dir=$(json_get "$INPUT" '.workspace.current_dir')
[ -z "$dir" ] && return
local branch
branch=$(cd "$dir" 2>/dev/null && git branch --show-current 2>/dev/null) || return
[ -z "$branch" ] && return
local status_indicator=""
if [ "$DISPLAY_MODE" != "compact" ]; then
# Check for uncommitted changes
if cd "$dir" && ! git diff --quiet 2>/dev/null; then
status_indicator="*"
fi
# Check for staged changes
if cd "$dir" && ! git diff --cached --quiet 2>/dev/null; then
status_indicator="${status_indicator}+"
fi
fi
echo "${ICON_GIT}${branch}${status_indicator}"
}
GIT=$(get_git)
Module: cost
Session cost in USD.
# --- cost ---
get_cost() {
local cost
cost=$(json_get "$INPUT" '.total_cost_usd' '0')
# Skip if zero or empty
[ "$cost" = "0" ] || [ -z "$cost" ] && return
# Format based on magnitude
if (( $(echo "$cost >= 1" | bc -l 2>/dev/null || echo 0) )); then
printf "${ICON_COST}\$%.2f" "$cost"
else
printf "${ICON_COST}\$%.3f" "$cost"
fi
}
COST=$(get_cost)
Module: rate-limits
API usage via OAuth token (5h/7d limits).
# --- rate-limits ---
get_rate_limits() {
# Get OAuth token from Claude config
local token_file="$HOME/.claude/.credentials"
[ ! -f "$token_file" ] && return
local access_token
access_token=$(jq -r '.oauth.accessToken // empty' "$token_file" 2>/dev/null)
[ -z "$access_token" ] && return
# Fetch usage (with timeout)
local usage
usage=$(curl -s --max-time 2 \
-H "Authorization: Bearer $access_token" \
"https://api.claude.ai/api/usage" 2>/dev/null)
[ -z "$usage" ] && return
# Parse usage (example fields - adjust based on actual API)
local hour_pct day_pct
hour_pct=$(echo "$usage" | jq -r '.fiveHourUsagePercent // 0' 2>/dev/null)
day_pct=$(echo "$usage" | jq -r '.sevenDayUsagePercent // 0' 2>/dev/null)
hour_pct=$(safe_int "$hour_pct")
day_pct=$(safe_int "$day_pct")
local hour_status day_status
hour_status=$(get_status_4level "$hour_pct" 25 50 75)
day_status=$(get_status_4level "$day_pct" 25 50 75)
echo "${ICON_RATE}5h:${hour_pct}%${hour_status} 7d:${day_pct}%${day_status}"
}
RATE_LIMITS=$(get_rate_limits)
Module: project
Detect project type by manifest files.
# --- project ---
get_project() {
local dir
dir=$(json_get "$INPUT" '.workspace.current_dir')
[ -z "$dir" ] && return
# Priority order - check most specific first
if [ -f "$dir/Cargo.toml" ]; then
echo "${ICON_PROJECT}Rust"
elif [ -f "$dir/go.mod" ]; then
echo "${ICON_PROJECT}Go"
elif [ -f "$dir/pyproject.toml" ] || [ -f "$dir/setup.py" ]; then
echo "${ICON_PROJECT}Python"
elif [ -f "$dir/package.json" ]; then
# Check for specific frameworks
if [ -f "$dir/next.config.js" ] || [ -f "$dir/next.config.mjs" ]; then
echo "${ICON_PROJECT}Next.js"
elif [ -f "$dir/nuxt.config.ts" ] || [ -f "$dir/nuxt.config.js" ]; then
echo "${ICON_PROJECT}Nuxt"
elif [ -f "$dir/vite.config.ts" ] || [ -f "$dir/vite.config.js" ]; then
echo "${ICON_PROJECT}Vite"
elif [ -f "$dir/tsconfig.json" ]; then
echo "${ICON_PROJECT}TypeScript"
else
echo "${ICON_PROJECT}Node"
fi
elif [ -f "$dir/Gemfile" ]; then
echo "${ICON_PROJECT}Ruby"
elif [ -f "$dir/pom.xml" ] || [ -f "$dir/build.gradle" ]; then
echo "${ICON_PROJECT}Java"
elif [ -f "$dir/composer.json" ]; then
echo "${ICON_PROJECT}PHP"
elif [ -f "$dir/mix.exs" ]; then
echo "${ICON_PROJECT}Elixir"
elif [ -f "$dir/pubspec.yaml" ]; then
echo "${ICON_PROJECT}Dart"
fi
}
PROJECT=$(get_project)
Module: lines-changed
Lines added/removed in current session (approximation via git).
# --- lines-changed ---
get_lines_changed() {
local dir
dir=$(json_get "$INPUT" '.workspace.current_dir')
[ -z "$dir" ] && return
cd "$dir" 2>/dev/null || return
# Get diff stats (staged + unstaged)
local stats
stats=$(git diff --stat HEAD 2>/dev/null | tail -1)
[ -z "$stats" ] && return
# Parse "X files changed, Y insertions(+), Z deletions(-)"
local insertions deletions
insertions=$(echo "$stats" | grep -oE '[0-9]+ insertion' | grep -oE '[0-9]+' || echo 0)
deletions=$(echo "$stats" | grep -oE '[0-9]+ deletion' | grep -oE '[0-9]+' || echo 0)
[ "$insertions" = "0" ] && [ "$deletions" = "0" ] && return
echo "${ICON_LINES}+${insertions}/-${deletions}"
}
LINES_CHANGED=$(get_lines_changed)
Module: battery (macOS)
Battery percentage with charging indicator.
# --- battery ---
get_battery() {
# macOS only
[ "$(uname)" != "Darwin" ] && return
local battery_info
battery_info=$(pmset -g batt 2>/dev/null)
[ -z "$battery_info" ] && return
local pct charging
pct=$(echo "$battery_info" | grep -oE '[0-9]+%' | head -1 | tr -d '%')
[ -z "$pct" ] && return
charging=""
echo "$battery_info" | grep -q "charging" && charging="+"
echo "$battery_info" | grep -q "AC Power" && charging="⚡"
local status
# Battery: low is critical (inverted thresholds)
if (( pct <= 10 )); then
status="$STATUS_CRIT"
elif (( pct <= 25 )); then
status="$STATUS_WARN"
else
status="$STATUS_OK"
fi
echo "${ICON_BATTERY}${pct}%${charging}${status}"
}
BATTERY=$(get_battery)
Module: cpu
CPU usage percentage.
# --- cpu ---
get_cpu() {
local cpu_pct
if [ "$(uname)" = "Darwin" ]; then
# macOS
cpu_pct=$(top -l 1 -n 0 2>/dev/null | grep "CPU usage" | awk '{print int($3)}')
else
# Linux
cpu_pct=$(top -bn1 2>/dev/null | grep "Cpu(s)" | awk '{print int($2)}')
fi
[ -z "$cpu_pct" ] && return
local status
status=$(get_status "$cpu_pct" 50 80)
echo "${ICON_CPU}${cpu_pct}%${status}"
}
CPU=$(get_cpu)
Module: memory
RAM usage percentage.
# --- memory ---
get_memory() {
local mem_pct
if [ "$(uname)" = "Darwin" ]; then
# macOS - approximate from vm_stat
local page_size pages_free pages_active pages_speculative pages_wired
page_size=$(pagesize 2>/dev/null || echo 4096)
local vm_stats
vm_stats=$(vm_stat 2>/dev/null)
pages_free=$(echo "$vm_stats" | awk '/Pages free/ {gsub(/\./,""); print $3}')
pages_active=$(echo "$vm_stats" | awk '/Pages active/ {gsub(/\./,""); print $3}')
pages_speculative=$(echo "$vm_stats" | awk '/Pages speculative/ {gsub(/\./,""); print $3}')
pages_wired=$(echo "$vm_stats" | awk '/Pages wired/ {gsub(/\./,""); print $4}')
local total_mem used_mem
total_mem=$(sysctl -n hw.memsize 2>/dev/null)
used_mem=$(( (pages_active + pages_wired) * page_size ))
[ -z "$total_mem" ] || [ "$total_mem" = "0" ] && return
mem_pct=$(( used_mem * 100 / total_mem ))
else
# Linux
mem_pct=$(free 2>/dev/null | awk '/Mem:/ {printf "%.0f", $3/$2 * 100}')
fi
[ -z "$mem_pct" ] && return
local status
status=$(get_status "$mem_pct" 60 85)
echo "${ICON_MEM}${mem_pct}%${status}"
}
MEMORY=$(get_memory)
Module: docker
Running container count.
# --- docker ---
get_docker() {
command -v docker &>/dev/null || return
local count
count=$(docker ps -q 2>/dev/null | wc -l | tr -d ' ')
[ "$count" = "0" ] && return
echo "${ICON_DOCKER}${count}"
}
DOCKER=$(get_docker)
Module: time
Current time display.
# --- time ---
get_time() {
if [ "$DISPLAY_MODE" = "verbose" ]; then
echo "${ICON_TIME}$(date '+%Y-%m-%d %H:%M')"
else
echo "${ICON_TIME}$(date '+%H:%M')"
fi
}
TIME=$(get_time)
Module: cca-status
Claude Code Anywhere status.
# --- claude-code-anywhere status ---
get_cca_status() {
local port_file="$HOME/.config/claude-code-anywhere/port"
[ ! -f "$port_file" ] && return
local port
port=$(cat "$port_file" 2>/dev/null)
[ -z "$port" ] && return
# Check if service is responding
local status
if curl -s --max-time 1 "http://127.0.0.1:${port}/health" &>/dev/null; then
status="${STATUS_OK}"
else
status="${STATUS_WARN}"
fi
echo "${ICON_CCA}CCA${status}"
}
CCA_STATUS=$(get_cca_status)
Complete Template
Full statusline.sh script template. When generating, include only enabled modules.
#!/bin/bash
# Claude Code Status Line Script
# Generated by /bluera-base:statusline
# Theme: {{THEME}}
# Modules: {{MODULES}}
# Display Mode: {{DISPLAY_MODE}}
set -e
# Read JSON input
read -r INPUT
# === THEME: {{THEME}} ===
{{THEME_VARS}}
# === DISPLAY MODE ===
DISPLAY_MODE="{{DISPLAY_MODE}}"
# === HELPER FUNCTIONS ===
get_status() {
local pct=$1
local warn_threshold=${2:-50}
local crit_threshold=${3:-75}
if (( pct >= crit_threshold )); then
echo "$STATUS_CRIT"
elif (( pct >= warn_threshold )); then
echo "$STATUS_WARN"
else
echo "$STATUS_OK"
fi
}
get_status_4level() {
local pct=$1
local fair_threshold=${2:-25}
local warn_threshold=${3:-50}
local crit_threshold=${4:-75}
if (( pct >= crit_threshold )); then
echo "$STATUS_4_CRIT"
elif (( pct >= warn_threshold )); then
echo "$STATUS_4_WARN"
elif (( pct >= fair_threshold )); then
echo "$STATUS_4_FAIR"
else
echo "$STATUS_4_OK"
fi
}
progress_bar() {
local pct=$1
local width=${2:-10}
local filled=$(( pct * width / 100 ))
local empty=$(( width - filled ))
printf "["
printf "%${filled}s" | tr ' ' '='
printf "%${empty}s" | tr ' ' '-'
printf "]"
}
safe_int() {
local val="$1"
local default="${2:-0}"
val="${val%%.*}"
val="${val//[^0-9-]/}"
if [[ "$val" =~ ^-?[0-9]+$ ]]; then
echo "$val"
else
echo "$default"
fi
}
json_get() {
local json="$1"
local path="$2"
local default="${3:-}"
if command -v jq &>/dev/null; then
local result
result=$(echo "$json" | jq -r "$path // empty" 2>/dev/null)
echo "${result:-$default}"
else
echo "$default"
fi
}
# === MODULES ===
{{MODULE_CODE}}
# === OUTPUT ===
OUTPUT=""
{{OUTPUT_ASSEMBLY}}
echo "$OUTPUT"
File Operations (REQUIRED)
After generating the statusline script, you MUST complete these steps:
Determine config directory:
CLAUDE_CONFIG="${CLAUDE_CONFIG_DIR:-$HOME/.claude}"Backup existing statusline (if present):
if [ -f "$CLAUDE_CONFIG/statusline.sh" ]; then BACKUP_TS=$(date +%Y%m%d-%H%M%S) cp "$CLAUDE_CONFIG/statusline.sh" "$CLAUDE_CONFIG/statusline.sh.bluera-base-backup-$BACKUP_TS" fiWrite the script to the config directory:
cat > "$CLAUDE_CONFIG/statusline.sh" << 'STATUSLINE_EOF' <generated script content here> STATUSLINE_EOFMake executable:
chmod +x "$CLAUDE_CONFIG/statusline.sh"Verify the file exists and is executable:
ls -la "$CLAUDE_CONFIG/statusline.sh"
The statusline will not work until these steps are completed.
Preserving User Customizations
When modifying an existing $CLAUDE_CONFIG/statusline.sh, preserve user-added content:
Detection Patterns
Look for these indicators of custom code:
Boundary comments:
# --- custom ---/# --- end custom ---# --- user ---/# --- end user ---# --- <name> status ---/# --- end <name> status ---
Custom function definitions:
- Functions not matching standard module names
- Example:
get_cca_status(),get_k8s_status()
External service integration:
curlto localhost/127.0.0.1 addresses- Reads from non-standard config files
- Environment-specific ports or paths
Custom variables in output:
- Variables referenced in final
echo/printfthat aren't from standard modules
- Variables referenced in final
Preservation Algorithm
1. Read existing script
2. Extract sections between boundary comments
3. Identify custom variables used in output format
4. Generate new script with standard modules
5. Append preserved custom sections before output
6. Update output format to include custom variables
Example: CCA Integration (Preserve)
# --- claude-code-anywhere status ---
CCA_STATUS=""
_CCA_PORT=$(cat ~/.config/claude-code-anywhere/port 2>/dev/null)
if [ -n "$_CCA_PORT" ]; then
_CCA_RESP=$(curl -s --max-time 1 "http://127.0.0.1:${_CCA_PORT}/health" 2>/dev/null)
if [ -n "$_CCA_RESP" ]; then
CCA_STATUS="${SEP}${ICON_CCA}CCA${STATUS_OK}"
fi
fi
# --- end claude-code-anywhere status ---
This should be preserved because:
- Has clear boundary comments
- Fetches from local service (127.0.0.1)
- Defines
CCA_STATUSvariable used in output
Configuration Examples
Minimal Developer
THEME="minimal"
MODULES="directory,context,git"
DISPLAY_MODE="compact"
Output: →myproject 45% ⎇main*
Full System Monitor
THEME="default"
MODULES="directory,model,context,git,cost,rate-limits,cpu,memory,docker"
DISPLAY_MODE="normal"
Output: 📁myproject | 🤖Opus4.5 | 📊45%🟢 | 🌿main* | 💰$1.23 | ⚡5h:12%🟢 7d:8%🟢 | 💻15%🟢 | 🧠62%🟡 | 🐳3
Server/Remote
THEME="monochrome"
MODULES="directory,context,git,cpu,memory"
DISPLAY_MODE="compact"
Output: DIR:myproject | CTX:45%[OK] | GIT:main | CPU:15%[OK] | MEM:62%[~~]
Preview All Presets
When statusline preset is run without a name argument, display this preview table:
| Preset | Example Output |
|---|---|
| minimal | Opus 4.5 45% |
| informative | 🤖 Opus 4.5 │ 📊 45%🟢 │ 💰 $1.23 |
| developer | 📁project │ 🤖Opus4.5 │ 📊45%🟢 │ 🌿main* │ 📦Node │ 💰$1.23 |
| system | 📁project │ 🤖Opus4.5 │ 📊45%🟢 │ 🌿main │ 💻15%🟢 │ 🧠62%🟡 │ 🐳3 |
| bluera | Opus4.5 project 🐍 main* │ $1.23 │ ██████░░░░ 60% │ +42/-8 │ 5h:12% 7d:8% |
Then use AskUserQuestion to let the user select which preset to apply.
Preset Definitions
Preset: minimal
THEME="minimal"
MODULES="model,context"
DISPLAY_MODE="compact"
Static string alternative: %model% | %context%
Preset: informative
THEME="default"
MODULES="model,context,cost"
DISPLAY_MODE="normal"
Static string alternative: 🤖 %model% | 📊 %context% | 💰 %cost%
Preset: developer
THEME="default"
MODULES="directory,model,context,git,project,cost"
DISPLAY_MODE="normal"
Preset: system
THEME="default"
MODULES="directory,model,context,git,cpu,memory,docker"
DISPLAY_MODE="normal"
Preset: bluera
Advanced statusline with rate limits, context bar, and ANSI colors.
Features:
- ANSI terminal colors (not emojis for status)
- 10-character context progress bar (█░)
- Rate limits (5h/7d) from Anthropic API with caching
- Lines changed (+/-) in session
- Project type detection (🦀🐹🐍💧💎📦🦕▲⚡🍞)
Output format:
Model dir project branch │ $cost │ [ctx bar] pct% │ +added/-removed │ 5h:X% 7d:Y%
Example:
Opus 4.5 myproject 🐍 main* │ $1.23 │ ██████░░░░ 60% │ +42/-8 │ 5h:12% 7d:8%
Ready-to-Use Preset Scripts
IMPORTANT: When applying a preset, copy the entire script below to ~/.claude/statusline.sh and make it executable with chmod +x ~/.claude/statusline.sh.
Script: minimal
#!/bin/bash
input=$(cat)
MODEL=$(echo "$input" | jq -r '.model.display_name // "?"')
CTX=$(echo "$input" | jq -r '.context_window.used_percentage // 0' | cut -d. -f1)
echo "$MODEL $CTX%"
Script: informative
#!/bin/bash
input=$(cat)
MODEL=$(echo "$input" | jq -r '.model.display_name // "?"')
CTX=$(echo "$input" | jq -r '.context_window.used_percentage // 0' | cut -d. -f1)
COST=$(echo "$input" | jq -r '.cost.total_cost_usd // 0')
# Status indicator
if [ "$CTX" -lt 50 ]; then STATUS="🟢"
elif [ "$CTX" -lt 80 ]; then STATUS="🟡"
else STATUS="🔴"; fi
# Format cost
if (( $(echo "$COST < 1" | bc -l 2>/dev/null || echo 1) )); then
COST_FMT=$(printf "%.0f¢" "$(echo "$COST * 100" | bc -l 2>/dev/null || echo 0)")
else
COST_FMT=$(printf "$%.2f" "$COST")
fi
echo "🤖 $MODEL │ 📊 ${CTX}%${STATUS} │ 💰 $COST_FMT"
Script: developer
#!/bin/bash
input=$(cat)
# Extract values
MODEL=$(echo "$input" | jq -r '.model.display_name // "?"')
CURRENT_DIR=$(echo "$input" | jq -r '.workspace.current_dir // "."')
DIR_NAME=$(basename "$CURRENT_DIR")
CTX=$(echo "$input" | jq -r '.context_window.used_percentage // 0' | cut -d. -f1)
COST=$(echo "$input" | jq -r '.cost.total_cost_usd // 0')
# Status indicator
if [ "$CTX" -lt 50 ]; then STATUS="🟢"
elif [ "$CTX" -lt 80 ]; then STATUS="🟡"
else STATUS="🔴"; fi
# Format cost
if (( $(echo "$COST < 1" | bc -l 2>/dev/null || echo 1) )); then
COST_FMT=$(printf "%.0f¢" "$(echo "$COST * 100" | bc -l 2>/dev/null || echo 0)")
else
COST_FMT=$(printf "$%.2f" "$COST")
fi
# Git branch
GIT_INFO=""
if git -C "$CURRENT_DIR" rev-parse --git-dir > /dev/null 2>&1; then
BRANCH=$(git -C "$CURRENT_DIR" --no-optional-locks branch --show-current 2>/dev/null)
if [ -n "$(git -C "$CURRENT_DIR" --no-optional-locks status --porcelain 2>/dev/null)" ]; then
GIT_INFO="🌿${BRANCH}*"
else
GIT_INFO="🌿${BRANCH}"
fi
fi
# Project type
PROJECT=""
if [ -f "$CURRENT_DIR/Cargo.toml" ]; then PROJECT="🦀Rust"
elif [ -f "$CURRENT_DIR/go.mod" ]; then PROJECT="🐹Go"
elif [ -f "$CURRENT_DIR/pyproject.toml" ] || [ -f "$CURRENT_DIR/requirements.txt" ]; then PROJECT="🐍Python"
elif [ -f "$CURRENT_DIR/package.json" ]; then
if [ -f "$CURRENT_DIR/next.config.js" ] || [ -f "$CURRENT_DIR/next.config.ts" ]; then PROJECT="▲Next.js"
elif [ -f "$CURRENT_DIR/bun.lockb" ]; then PROJECT="🍞Bun"
else PROJECT="📦Node"
fi
fi
# Build output
OUTPUT="📁$DIR_NAME │ 🤖$MODEL │ 📊${CTX}%${STATUS}"
[ -n "$GIT_INFO" ] && OUTPUT="$OUTPUT │ $GIT_INFO"
[ -n "$PROJECT" ] && OUTPUT="$OUTPUT │ $PROJECT"
OUTPUT="$OUTPUT │ 💰$COST_FMT"
echo "$OUTPUT"
Script: system
#!/bin/bash
input=$(cat)
# Extract values
MODEL=$(echo "$input" | jq -r '.model.display_name // "?"')
CURRENT_DIR=$(echo "$input" | jq -r '.workspace.current_dir // "."')
DIR_NAME=$(basename "$CURRENT_DIR")
CTX=$(echo "$input" | jq -r '.context_window.used_percentage // 0' | cut -d. -f1)
# Status indicator
if [ "$CTX" -lt 50 ]; then CTX_STATUS="🟢"
elif [ "$CTX" -lt 80 ]; then CTX_STATUS="🟡"
else CTX_STATUS="🔴"; fi
# Git branch
GIT_INFO=""
if git -C "$CURRENT_DIR" rev-parse --git-dir > /dev/null 2>&1; then
BRANCH=$(git -C "$CURRENT_DIR" --no-optional-locks branch --show-current 2>/dev/null)
GIT_INFO="🌿$BRANCH"
fi
# CPU usage (cross-platform)
CPU_PCT=0
if [[ "$OSTYPE" == "darwin"* ]]; then
CPU_PCT=$(top -l 1 -n 0 2>/dev/null | grep "CPU usage" | awk '{print int($3)}')
else
CPU_PCT=$(top -bn1 2>/dev/null | grep "Cpu(s)" | awk '{print int($2)}')
fi
if [ "$CPU_PCT" -lt 50 ]; then CPU_STATUS="🟢"
elif [ "$CPU_PCT" -lt 80 ]; then CPU_STATUS="🟡"
else CPU_STATUS="🔴"; fi
# Memory usage (cross-platform)
MEM_PCT=0
if [[ "$OSTYPE" == "darwin"* ]]; then
MEM_PCT=$(vm_stat 2>/dev/null | awk '/Pages active/ {active=$3} /Pages inactive/ {inactive=$3} /Pages speculative/ {spec=$3} /Pages wired/ {wired=$4} /Pages free/ {free=$3} END {used=active+inactive+spec+wired; total=used+free; if(total>0) printf "%d", (used/total)*100}')
else
MEM_PCT=$(free 2>/dev/null | awk '/Mem:/ {printf "%d", $3/$2*100}')
fi
if [ "$MEM_PCT" -lt 50 ]; then MEM_STATUS="🟢"
elif [ "$MEM_PCT" -lt 80 ]; then MEM_STATUS="🟡"
else MEM_STATUS="🔴"; fi
# Docker containers
DOCKER_COUNT=$(docker ps -q 2>/dev/null | wc -l | tr -d ' ')
# Build output
OUTPUT="📁$DIR_NAME │ 🤖$MODEL │ 📊${CTX}%${CTX_STATUS}"
[ -n "$GIT_INFO" ] && OUTPUT="$OUTPUT │ $GIT_INFO"
OUTPUT="$OUTPUT │ 💻${CPU_PCT}%${CPU_STATUS} │ 🧠${MEM_PCT}%${MEM_STATUS}"
[ "$DOCKER_COUNT" -gt 0 ] && OUTPUT="$OUTPUT │ 🐳$DOCKER_COUNT"
echo "$OUTPUT"
Script: bluera
#!/bin/bash
# Bluera preset - advanced statusline with rate limits, context bar, and ANSI colors
input=$(cat)
# --- Project Type Detection ---
get_project_type() {
local dir="$1"
if [ -f "$dir/Cargo.toml" ]; then echo "🦀"
elif [ -f "$dir/go.mod" ]; then echo "🐹"
elif [ -f "$dir/pyproject.toml" ] || [ -f "$dir/requirements.txt" ]; then echo "🐍"
elif [ -f "$dir/mix.exs" ]; then echo "💧"
elif [ -f "$dir/Gemfile" ]; then echo "💎"
elif [ -f "$dir/package.json" ]; then
if [ -f "$dir/next.config.js" ] || [ -f "$dir/next.config.ts" ] || [ -f "$dir/next.config.mjs" ]; then echo "▲"
elif [ -f "$dir/nuxt.config.ts" ] || [ -f "$dir/nuxt.config.js" ]; then echo "⚡"
elif [ -f "$dir/vite.config.ts" ] || [ -f "$dir/vite.config.js" ]; then echo "⚡"
elif [ -f "$dir/bun.lockb" ]; then echo "🍞"
else echo "📦"
fi
elif [ -f "$dir/deno.json" ]; then echo "🦕"
else echo ""
fi
}
# --- Rate Limits (fetches from Anthropic API via keychain - macOS only) ---
get_rate_limits() {
local cache_file="/tmp/.claude_usage_cache"
local cache_max_age=60
local usage_data=""
# Check cache
if [ -f "$cache_file" ]; then
local cache_age=$(($(date +%s) - $(stat -f %m "$cache_file" 2>/dev/null || stat -c %Y "$cache_file" 2>/dev/null || echo 0)))
if [ "$cache_age" -lt "$cache_max_age" ]; then
usage_data=$(cat "$cache_file")
fi
fi
# Fetch if no cache (macOS keychain)
if [ -z "$usage_data" ]; then
local token
token=$(security find-generic-password -s 'Claude Code-credentials' -w 2>/dev/null | jq -r '.claudeAiOauth.accessToken // empty' 2>/dev/null)
if [ -n "$token" ]; then
usage_data=$(curl -s --max-time 2 "https://api.anthropic.com/api/oauth/usage" \
-H "Authorization: Bearer $token" \
-H "anthropic-beta: oauth-2025-04-20" \
-H "Accept: application/json" 2>/dev/null)
[ -n "$usage_data" ] && echo "$usage_data" > "$cache_file" 2>/dev/null
fi
fi
if [ -z "$usage_data" ]; then echo ""; return; fi
local five_hour=$(echo "$usage_data" | jq -r '(.five_hour // .five_hour_opus // .five_hour_sonnet // {}).utilization // 0' 2>/dev/null)
local seven_day=$(echo "$usage_data" | jq -r '(.seven_day // .seven_day_opus // .seven_day_sonnet // {}).utilization // 0' 2>/dev/null)
local five_int=$(printf "%.0f" "$five_hour" 2>/dev/null || echo "0")
local seven_int=$(printf "%.0f" "$seven_day" 2>/dev/null || echo "0")
# Color based on usage
local five_color="\033[32m"; [ "$five_int" -ge 50 ] && five_color="\033[33m"; [ "$five_int" -ge 75 ] && five_color="\033[38;5;208m"; [ "$five_int" -ge 95 ] && five_color="\033[31m"
local seven_color="\033[32m"; [ "$seven_int" -ge 50 ] && seven_color="\033[33m"; [ "$seven_int" -ge 75 ] && seven_color="\033[38;5;208m"; [ "$seven_int" -ge 95 ] && seven_color="\033[31m"
printf "${five_color}5h:%d%%\033[0m ${seven_color}7d:%d%%\033[0m" "$five_int" "$seven_int"
}
# Extract values
MODEL=$(echo "$input" | jq -r '.model.display_name // "?"')
CURRENT_DIR=$(echo "$input" | jq -r '.workspace.current_dir')
DIR_NAME=$(basename "$CURRENT_DIR")
COST=$(echo "$input" | jq -r '.cost.total_cost_usd // 0')
LINES_ADDED=$(echo "$input" | jq -r '.cost.total_lines_added // 0')
LINES_REMOVED=$(echo "$input" | jq -r '.cost.total_lines_removed // 0')
CONTEXT_SIZE=$(echo "$input" | jq -r '.context_window.context_window_size // 200000')
USAGE=$(echo "$input" | jq '.context_window.current_usage')
# Calculate context percentage
if [ "$USAGE" != "null" ]; then
INPUT_TOKENS=$(echo "$USAGE" | jq '.input_tokens // 0')
CACHE_CREATE=$(echo "$USAGE" | jq '.cache_creation_input_tokens // 0')
CACHE_READ=$(echo "$USAGE" | jq '.cache_read_input_tokens // 0')
CURRENT_TOKENS=$((INPUT_TOKENS + CACHE_CREATE + CACHE_READ))
CONTEXT_PCT=$((CURRENT_TOKENS * 100 / CONTEXT_SIZE))
else
CONTEXT_PCT=0
fi
# Git info with colors
GIT_INFO=""
if git -C "$CURRENT_DIR" rev-parse --git-dir > /dev/null 2>&1; then
BRANCH=$(git -C "$CURRENT_DIR" --no-optional-locks branch --show-current 2>/dev/null)
if [ -n "$(git -C "$CURRENT_DIR" --no-optional-locks status --porcelain 2>/dev/null)" ]; then
GIT_INFO=$(printf " \033[33m%s\033[0m\033[31m*\033[0m" "$BRANCH")
else
GIT_INFO=$(printf " \033[36m%s\033[0m" "$BRANCH")
fi
fi
# Format cost
if (( $(echo "$COST < 1" | bc -l) )); then
COST_FMT=$(printf "%.0f¢" "$(echo "$COST * 100" | bc -l)")
else
COST_FMT=$(printf "$%.2f" "$COST")
fi
# Format lines changed
if [ "$LINES_ADDED" -gt 0 ] || [ "$LINES_REMOVED" -gt 0 ]; then
LINES_FMT=$(printf "\033[32m+%d\033[0m/\033[31m-%d\033[0m" "$LINES_ADDED" "$LINES_REMOVED")
else
LINES_FMT="-"
fi
# Build context bar (10 chars wide)
BAR_WIDTH=10
FILLED=$((CONTEXT_PCT * BAR_WIDTH / 100))
[ "$FILLED" -gt "$BAR_WIDTH" ] && FILLED=$BAR_WIDTH
EMPTY=$((BAR_WIDTH - FILLED))
BAR=""; for ((i=0; i<FILLED; i++)); do BAR+="█"; done; for ((i=0; i<EMPTY; i++)); do BAR+="░"; done
# Project type and rate limits
PROJECT_TYPE=$(get_project_type "$CURRENT_DIR")
[ -n "$PROJECT_TYPE" ] && PROJECT_TYPE=" $PROJECT_TYPE"
RATE_LIMITS=$(get_rate_limits)
[ -n "$RATE_LIMITS" ] && RATE_LIMITS=" │ $RATE_LIMITS"
# Output with colored context bar
if [ "$CONTEXT_PCT" -lt 50 ]; then
printf "\033[35m%s\033[0m \033[1m%s\033[0m%s%s │ \033[33m%s\033[0m │ \033[32m%s\033[0m %d%% │ %s%s" \
"$MODEL" "$DIR_NAME" "$PROJECT_TYPE" "$GIT_INFO" "$COST_FMT" "$BAR" "$CONTEXT_PCT" "$LINES_FMT" "$RATE_LIMITS"
elif [ "$CONTEXT_PCT" -lt 80 ]; then
printf "\033[35m%s\033[0m \033[1m%s\033[0m%s%s │ \033[33m%s\033[0m │ \033[33m%s\033[0m %d%% │ %s%s" \
"$MODEL" "$DIR_NAME" "$PROJECT_TYPE" "$GIT_INFO" "$COST_FMT" "$BAR" "$CONTEXT_PCT" "$LINES_FMT" "$RATE_LIMITS"
else
printf "\033[35m%s\033[0m \033[1m%s\033[0m%s%s │ \033[33m%s\033[0m │ \033[31m%s\033[0m %d%% │ %s%s" \
"$MODEL" "$DIR_NAME" "$PROJECT_TYPE" "$GIT_INFO" "$COST_FMT" "$BAR" "$CONTEXT_PCT" "$LINES_FMT" "$RATE_LIMITS"
fi