Created
April 20, 2026 13:15
-
-
Save shaal/82995b61c1cd49013d7001698ba9d05f to your computer and use it in GitHub Desktop.
Claude Code statusline script
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| # Read JSON input from stdin | |
| INPUT=$(cat) | |
| MODEL=$(echo "$INPUT" | jq -r '.model.display_name // "Claude"') | |
| CWD=$(echo "$INPUT" | jq -r '.workspace.current_dir // .cwd') | |
| DIR=$(basename "$CWD") | |
| # Replace claude-code-flow with branded name | |
| if [ "$DIR" = "claude-code-flow" ]; then | |
| DIR="Claude Flow" | |
| fi | |
| # Get git branch | |
| BRANCH=$(cd "$CWD" 2>/dev/null && git -c gc.auto=0 branch --show-current 2>/dev/null) | |
| # PS1-style prefix: bold green user@host, bold blue cwd | |
| printf "\033[01;32m$(whoami)@$(hostname -s)\033[00m:\033[01;34m$CWD\033[00m" | |
| # Model and git branch | |
| printf " | \033[1m$MODEL\033[0m" | |
| [ -n "$BRANCH" ] && printf " on \033[33m$BRANCH\033[0m" | |
| # Claude-Flow integration | |
| FLOW_DIR="$CWD/.claude-flow" | |
| if [ -d "$FLOW_DIR" ]; then | |
| printf " │" | |
| # 1. Swarm Configuration & Topology | |
| if [ -f "$FLOW_DIR/swarm-config.json" ]; then | |
| STRATEGY=$(jq -r '.defaultStrategy // empty' "$FLOW_DIR/swarm-config.json" 2>/dev/null) | |
| if [ -n "$STRATEGY" ]; then | |
| # Map strategy to topology icon | |
| case "$STRATEGY" in | |
| "balanced") TOPO_ICON="⚡mesh" ;; | |
| "conservative") TOPO_ICON="⚡hier" ;; | |
| "aggressive") TOPO_ICON="⚡ring" ;; | |
| *) TOPO_ICON="⚡$STRATEGY" ;; | |
| esac | |
| printf " \033[35m$TOPO_ICON\033[0m" | |
| # Count agent profiles as "configured agents" | |
| AGENT_COUNT=$(jq -r '.agentProfiles | length' "$FLOW_DIR/swarm-config.json" 2>/dev/null) | |
| if [ -n "$AGENT_COUNT" ] && [ "$AGENT_COUNT" != "null" ] && [ "$AGENT_COUNT" -gt 0 ]; then | |
| printf " \033[35m🤖 $AGENT_COUNT\033[0m" | |
| fi | |
| fi | |
| fi | |
| # 2. Real-time System Metrics | |
| if [ -f "$FLOW_DIR/metrics/system-metrics.json" ]; then | |
| # Get latest metrics (last entry in array) | |
| LATEST=$(jq -r '.[-1]' "$FLOW_DIR/metrics/system-metrics.json" 2>/dev/null) | |
| if [ -n "$LATEST" ] && [ "$LATEST" != "null" ]; then | |
| # Memory usage | |
| MEM_PERCENT=$(echo "$LATEST" | jq -r '.memoryUsagePercent // 0' | awk '{printf "%.0f", $1}') | |
| if [ -n "$MEM_PERCENT" ] && [ "$MEM_PERCENT" != "null" ]; then | |
| # Color-coded memory (green <60%, yellow 60-80%, red >80%) | |
| if [ "$MEM_PERCENT" -lt 60 ]; then | |
| MEM_COLOR="\033[32m" # Green | |
| elif [ "$MEM_PERCENT" -lt 80 ]; then | |
| MEM_COLOR="\033[33m" # Yellow | |
| else | |
| MEM_COLOR="\033[31m" # Red | |
| fi | |
| printf " ${MEM_COLOR}💾 ${MEM_PERCENT}%\033[0m" | |
| fi | |
| # CPU load | |
| CPU_LOAD=$(echo "$LATEST" | jq -r '.cpuLoad // 0' | awk '{printf "%.0f", $1 * 100}') | |
| if [ -n "$CPU_LOAD" ] && [ "$CPU_LOAD" != "null" ]; then | |
| # Color-coded CPU (green <50%, yellow 50-75%, red >75%) | |
| if [ "$CPU_LOAD" -lt 50 ]; then | |
| CPU_COLOR="\033[32m" # Green | |
| elif [ "$CPU_LOAD" -lt 75 ]; then | |
| CPU_COLOR="\033[33m" # Yellow | |
| else | |
| CPU_COLOR="\033[31m" # Red | |
| fi | |
| printf " ${CPU_COLOR}⚙ ${CPU_LOAD}%\033[0m" | |
| fi | |
| fi | |
| fi | |
| # 3. Session State | |
| if [ -f "$FLOW_DIR/session-state.json" ]; then | |
| SESSION_ID=$(jq -r '.sessionId // empty' "$FLOW_DIR/session-state.json" 2>/dev/null) | |
| ACTIVE=$(jq -r '.active // false' "$FLOW_DIR/session-state.json" 2>/dev/null) | |
| if [ "$ACTIVE" = "true" ] && [ -n "$SESSION_ID" ]; then | |
| # Show abbreviated session ID | |
| SHORT_ID=$(echo "$SESSION_ID" | cut -d'-' -f1) | |
| printf " \033[34m🔄 $SHORT_ID\033[0m" | |
| fi | |
| fi | |
| # 4. Performance Metrics from task-metrics.json | |
| if [ -f "$FLOW_DIR/metrics/task-metrics.json" ]; then | |
| # Parse task metrics for success rate, avg time, and streak | |
| METRICS=$(jq -r ' | |
| # Calculate metrics | |
| (map(select(.success == true)) | length) as $successful | | |
| (length) as $total | | |
| (if $total > 0 then ($successful / $total * 100) else 0 end) as $success_rate | | |
| (map(.duration // 0) | add / length) as $avg_duration | | |
| # Calculate streak (consecutive successes from end) | |
| (reverse | | |
| reduce .[] as $task (0; | |
| if $task.success == true then . + 1 else 0 end | |
| ) | |
| ) as $streak | | |
| { | |
| success_rate: $success_rate, | |
| avg_duration: $avg_duration, | |
| streak: $streak, | |
| total: $total | |
| } | @json | |
| ' "$FLOW_DIR/metrics/task-metrics.json" 2>/dev/null) | |
| if [ -n "$METRICS" ] && [ "$METRICS" != "null" ]; then | |
| # Success Rate | |
| SUCCESS_RATE=$(echo "$METRICS" | jq -r '.success_rate // 0' | awk '{printf "%.0f", $1}') | |
| TOTAL_TASKS=$(echo "$METRICS" | jq -r '.total // 0') | |
| if [ -n "$SUCCESS_RATE" ] && [ "$TOTAL_TASKS" -gt 0 ]; then | |
| # Color-code: Green (>80%), Yellow (60-80%), Red (<60%) | |
| if [ "$SUCCESS_RATE" -gt 80 ]; then | |
| SUCCESS_COLOR="\033[32m" # Green | |
| elif [ "$SUCCESS_RATE" -ge 60 ]; then | |
| SUCCESS_COLOR="\033[33m" # Yellow | |
| else | |
| SUCCESS_COLOR="\033[31m" # Red | |
| fi | |
| printf " ${SUCCESS_COLOR}🎯 ${SUCCESS_RATE}%\033[0m" | |
| fi | |
| # Average Time | |
| AVG_TIME=$(echo "$METRICS" | jq -r '.avg_duration // 0') | |
| if [ -n "$AVG_TIME" ] && [ "$TOTAL_TASKS" -gt 0 ]; then | |
| # Format smartly: seconds, minutes, or hours | |
| if [ $(echo "$AVG_TIME < 60" | bc -l 2>/dev/null || echo 0) -eq 1 ]; then | |
| TIME_STR=$(echo "$AVG_TIME" | awk '{printf "%.1fs", $1}') | |
| elif [ $(echo "$AVG_TIME < 3600" | bc -l 2>/dev/null || echo 0) -eq 1 ]; then | |
| TIME_STR=$(echo "$AVG_TIME" | awk '{printf "%.1fm", $1/60}') | |
| else | |
| TIME_STR=$(echo "$AVG_TIME" | awk '{printf "%.1fh", $1/3600}') | |
| fi | |
| printf " \033[36m⏱️ $TIME_STR\033[0m" | |
| fi | |
| # Streak (only show if > 0) | |
| STREAK=$(echo "$METRICS" | jq -r '.streak // 0') | |
| if [ -n "$STREAK" ] && [ "$STREAK" -gt 0 ]; then | |
| printf " \033[91m🔥 $STREAK\033[0m" | |
| fi | |
| fi | |
| fi | |
| # 5. Active Tasks (check for task files) | |
| if [ -d "$FLOW_DIR/tasks" ]; then | |
| TASK_COUNT=$(find "$FLOW_DIR/tasks" -name "*.json" -type f 2>/dev/null | wc -l) | |
| if [ "$TASK_COUNT" -gt 0 ]; then | |
| printf " \033[36m📋 $TASK_COUNT\033[0m" | |
| fi | |
| fi | |
| # 6. Check for hooks activity | |
| if [ -f "$FLOW_DIR/hooks-state.json" ]; then | |
| HOOKS_ACTIVE=$(jq -r '.enabled // false' "$FLOW_DIR/hooks-state.json" 2>/dev/null) | |
| if [ "$HOOKS_ACTIVE" = "true" ]; then | |
| printf " \033[35m🔗\033[0m" | |
| fi | |
| fi | |
| fi | |
| # Context window progress | |
| USED_PCT=$(echo "$INPUT" | jq -r '.context_window.used_percentage // empty') | |
| if [ -n "$USED_PCT" ]; then | |
| # Round to integer | |
| PCT=$(printf "%.0f" "$USED_PCT") | |
| # Choose color based on fill level | |
| if [ "$PCT" -lt 50 ]; then | |
| BAR_COLOR="\033[32m" # Green | |
| elif [ "$PCT" -lt 75 ]; then | |
| BAR_COLOR="\033[33m" # Yellow | |
| elif [ "$PCT" -lt 90 ]; then | |
| BAR_COLOR="\033[31m" # Red | |
| else | |
| BAR_COLOR="\033[1;31m" # Bold red | |
| fi | |
| # Build a 20-char bar | |
| FILLED=$(( PCT * 20 / 100 )) | |
| EMPTY=$(( 20 - FILLED )) | |
| BAR="" | |
| for i in $(seq 1 $FILLED); do BAR="${BAR}█"; done | |
| for i in $(seq 1 $EMPTY); do BAR="${BAR}░"; done | |
| printf " | ctx ${BAR_COLOR}${BAR} ${PCT}%%\033[0m" | |
| fi | |
| # Claude subscription rate limits | |
| FIVE_HR=$(echo "$INPUT" | jq -r '.rate_limits.five_hour.used_percentage // empty') | |
| FIVE_RESETS=$(echo "$INPUT" | jq -r '.rate_limits.five_hour.resets_at // empty') | |
| SEVEN_DAY=$(echo "$INPUT" | jq -r '.rate_limits.seven_day.used_percentage // empty') | |
| WEEK_RESETS=$(echo "$INPUT" | jq -r '.rate_limits.seven_day.resets_at // empty') | |
| NOW=$(date +%s) | |
| if [ -n "$FIVE_HR" ] || [ -n "$SEVEN_DAY" ]; then | |
| printf " |" | |
| if [ -n "$FIVE_HR" ]; then | |
| FIVE_PCT=$(printf "%.0f" "$FIVE_HR") | |
| if [ "$FIVE_PCT" -lt 50 ]; then | |
| FIVE_COLOR="\033[32m" | |
| elif [ "$FIVE_PCT" -lt 80 ]; then | |
| FIVE_COLOR="\033[33m" | |
| else | |
| FIVE_COLOR="\033[31m" | |
| fi | |
| # Compute elapsed time % within the 5-hour window (18000s) | |
| if [ -n "$FIVE_RESETS" ]; then | |
| FIVE_ELAPSED=$(awk -v now="$NOW" -v resets="$FIVE_RESETS" 'BEGIN { | |
| elapsed = now - (resets - 18000) | |
| if (elapsed < 0) elapsed = 0 | |
| if (elapsed > 18000) elapsed = 18000 | |
| printf "%.0f", elapsed / 18000 * 100 | |
| }') | |
| printf " ${FIVE_COLOR}5h:${FIVE_PCT}%%/${FIVE_ELAPSED}%%\033[0m" | |
| else | |
| printf " ${FIVE_COLOR}5h:${FIVE_PCT}%%\033[0m" | |
| fi | |
| fi | |
| if [ -n "$SEVEN_DAY" ]; then | |
| WEEK_PCT=$(printf "%.0f" "$SEVEN_DAY") | |
| if [ "$WEEK_PCT" -lt 50 ]; then | |
| WEEK_COLOR="\033[32m" | |
| elif [ "$WEEK_PCT" -lt 80 ]; then | |
| WEEK_COLOR="\033[33m" | |
| else | |
| WEEK_COLOR="\033[31m" | |
| fi | |
| # Compute elapsed time % within the 7-day window (604800s) | |
| if [ -n "$WEEK_RESETS" ]; then | |
| WEEK_ELAPSED=$(awk -v now="$NOW" -v resets="$WEEK_RESETS" 'BEGIN { | |
| elapsed = now - (resets - 604800) | |
| if (elapsed < 0) elapsed = 0 | |
| if (elapsed > 604800) elapsed = 604800 | |
| printf "%.0f", elapsed / 604800 * 100 | |
| }') | |
| printf " ${WEEK_COLOR}7d:${WEEK_PCT}%%/${WEEK_ELAPSED}%%\033[0m" | |
| else | |
| printf " ${WEEK_COLOR}7d:${WEEK_PCT}%%\033[0m" | |
| fi | |
| fi | |
| fi | |
| echo |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment