summaryrefslogtreecommitdiff
path: root/ar/.config/claude/statusline.sh
diff options
context:
space:
mode:
authorTheSiahxyz <164138827+TheSiahxyz@users.noreply.github.com>2026-01-17 12:12:19 +0900
committerTheSiahxyz <164138827+TheSiahxyz@users.noreply.github.com>2026-01-17 12:12:19 +0900
commit501af21980ce428a17fd9b382246e344a47a6334 (patch)
tree60979bbc460f70da6f6d3385983c6ea347439e91 /ar/.config/claude/statusline.sh
parent59f2f8eec787ba62971968f7ffab20cb39af7346 (diff)
modified claude/settings.json, deleted claude/statusline.sh, created statuslines/
Diffstat (limited to 'ar/.config/claude/statusline.sh')
-rwxr-xr-xar/.config/claude/statusline.sh611
1 files changed, 0 insertions, 611 deletions
diff --git a/ar/.config/claude/statusline.sh b/ar/.config/claude/statusline.sh
deleted file mode 100755
index 0d524d2..0000000
--- a/ar/.config/claude/statusline.sh
+++ /dev/null
@@ -1,611 +0,0 @@
-#!/usr/bin/env bash
-set -euo pipefail 2>/dev/null || set -eu
-
-# ============================================================
-# STATUSLINE v2.0.0 - Claude Code Status Line
-# ============================================================
-
-readonly STATUSLINE_VERSION="2.0.0"
-
-# ============================================================
-# CONFIGURATION
-# ============================================================
-readonly BAR_WIDTH=12
-readonly BAR_FILLED="โ–ˆ"
-readonly BAR_EMPTY="โ–‘"
-
-# Colors (256-color palette)
-readonly RED='\033[38;5;203m'
-readonly GREEN='\033[38;5;150m'
-readonly BLUE='\033[38;5;117m'
-readonly MAGENTA='\033[38;5;147m'
-readonly CYAN='\033[38;5;81m'
-readonly ORANGE='\033[38;5;215m'
-readonly YELLOW='\033[38;5;222m'
-readonly GRAY='\033[38;5;245m'
-readonly LIGHT_GRAY='\033[38;5;249m'
-readonly NC='\033[0m'
-
-# Derived constants
-readonly SEPARATOR="${GRAY}โ”‚${NC}"
-readonly NULL_VALUE="null"
-
-# Icons
-readonly MODEL_ICON="๐Ÿค–"
-readonly CONTEXT_ICON="๐Ÿง "
-readonly DIR_ICON="๐Ÿ“"
-readonly GIT_ICON="๐ŸŒฟ"
-readonly COST_ICON="๐Ÿ’ฐ"
-readonly TOKEN_ICON="๐Ÿ“Š"
-readonly TIME_ICON="โฑ๏ธ"
-readonly VERSION_ICON="๐Ÿ“Ÿ"
-
-# Git state constants
-readonly STATE_NOT_REPO="not_repo"
-readonly STATE_CLEAN="clean"
-readonly STATE_DIRTY="dirty"
-
-# Context usage messages (tiered by usage percentage)
-readonly CONTEXT_MSG_VERY_LOW=(
- "just getting started"
- "barely touched it"
- "fresh as a daisy"
- "room for an elephant"
- "zero stress mode"
- "could do this all day"
- "warming up the engines"
- "practically empty"
- "smooth sailing ahead"
- "all systems nominal"
-)
-
-readonly CONTEXT_MSG_LOW=(
- "light snacking"
- "taking it easy"
- "smooth operator"
- "just vibing"
- "cruising altitude"
- "nice and steady"
- "zen mode activated"
- "coasting along"
- "comfortable cruise"
- "looking good"
-)
-
-readonly CONTEXT_MSG_MEDIUM=(
- "halfway there"
- "finding the groove"
- "building momentum"
- "picking up speed"
- "getting interesting"
- "entering the zone"
- "getting warmer"
- "balanced perfectly"
- "sweet spot territory"
- "gears are meshing"
-)
-
-readonly CONTEXT_MSG_HIGH=(
- "getting spicy"
- "filling up fast"
- "things heating up"
- "turning up the heat"
- "entering danger zone"
- "feeling the pressure"
- "approaching red zone"
- "intensity rising"
- "full throttle mode"
- "hold on tight"
-)
-
-readonly CONTEXT_MSG_CRITICAL=(
- "living dangerously"
- "pushing the limits"
- "houston we have a problem"
- "danger zone activated"
- "running on fumes"
- "this is fine ๐Ÿ”ฅ"
- "critical mass approaching"
- "maximum overdrive"
- "context go brrrr"
- "about to explode"
-)
-
-# ============================================================
-# LOGGING
-# ============================================================
-SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
-readonly LOG_FILE="${SCRIPT_DIR}/statusline.log"
-
-log_debug() {
- local timestamp
- timestamp=$(date '+%Y-%m-%d %H:%M:%S')
- echo "[$timestamp] $*" >> "$LOG_FILE" 2>/dev/null || true
-}
-
-# ============================================================
-# UTILITY FUNCTIONS
-# ============================================================
-
-# Check jq availability
-check_jq() {
- command -v jq >/dev/null 2>&1
-}
-
-# String utilities
-get_dirname() { echo "${1##*/}"; }
-sep() { echo -n " ${SEPARATOR} "; }
-
-# Format numbers with K/M suffixes
-format_number() {
- local num="${1:-0}"
- [[ ! "$num" =~ ^[0-9]+$ ]] && { echo "$num"; return; }
-
- if [[ "$num" -lt 1000 ]]; then
- echo "$num"
- elif [[ "$num" -lt 1000000 ]]; then
- local k=$((num / 1000))
- local remainder=$((num % 1000))
- if [[ "$k" -lt 10 ]]; then
- local decimal=$((remainder / 100))
- echo "${k}.${decimal}K"
- else
- echo "${k}K"
- fi
- else
- local m=$((num / 1000000))
- local remainder=$((num % 1000000))
- if [[ "$m" -lt 10 ]]; then
- local decimal=$((remainder / 100000))
- echo "${m}.${decimal}M"
- else
- echo "${m}M"
- fi
- fi
-}
-
-# Format duration (ms to human readable)
-format_duration() {
- local ms="${1:-0}"
- [[ ! "$ms" =~ ^[0-9]+$ ]] && { echo ""; return; }
-
- local seconds=$((ms / 1000))
- local minutes=$((seconds / 60))
- local hours=$((minutes / 60))
-
- if [[ "$hours" -gt 0 ]]; then
- local remaining_mins=$((minutes % 60))
- echo "${hours}h${remaining_mins}m"
- elif [[ "$minutes" -gt 0 ]]; then
- local remaining_secs=$((seconds % 60))
- echo "${minutes}m${remaining_secs}s"
- else
- echo "${seconds}s"
- fi
-}
-
-# Format cost
-format_cost() {
- local cost="${1:-0}"
- if [[ "$cost" =~ ^[0-9.]+$ ]]; then
- printf "%.2f" "$cost"
- else
- echo "0.00"
- fi
-}
-
-# Get random context message based on usage percentage
-get_context_message() {
- local percent="${1:-0}"
- local messages=()
-
- if [[ "$percent" -le 20 ]]; then
- messages=("${CONTEXT_MSG_VERY_LOW[@]}")
- elif [[ "$percent" -le 40 ]]; then
- messages=("${CONTEXT_MSG_LOW[@]}")
- elif [[ "$percent" -le 60 ]]; then
- messages=("${CONTEXT_MSG_MEDIUM[@]}")
- elif [[ "$percent" -le 80 ]]; then
- messages=("${CONTEXT_MSG_HIGH[@]}")
- else
- messages=("${CONTEXT_MSG_CRITICAL[@]}")
- fi
-
- local count=${#messages[@]}
- local index=$((RANDOM % count))
- echo "${messages[$index]}"
-}
-
-# ============================================================
-# JSON PARSING
-# ============================================================
-
-parse_with_jq() {
- local input="$1"
-
- echo "$input" | jq -r '
- .model.display_name // "Claude",
- .workspace.current_dir // .cwd // "unknown",
- (.context_window.context_window_size // 200000),
- (
- (.context_window.current_usage.input_tokens // 0) +
- (.context_window.current_usage.cache_creation_input_tokens // 0) +
- (.context_window.current_usage.cache_read_input_tokens // 0)
- ),
- (.context_window.total_input_tokens // 0),
- (.context_window.total_output_tokens // 0),
- (.cost.total_cost_usd // 0),
- (.cost.total_duration_ms // 0),
- .version // "",
- .session_id // ""
- ' 2>/dev/null
-}
-
-# Bash fallback for JSON parsing
-extract_json_string() {
- local json="$1"
- local key="$2"
- local default="${3:-}"
-
- local value
- value=$(echo "$json" | grep -o "\"${key}\"[[:space:]]*:[[:space:]]*\"[^\"]*\"" | head -1 | sed 's/.*:[[:space:]]*"\([^"]*\)".*/\1/')
-
- if [[ -z "$value" || "$value" == "null" ]]; then
- value=$(echo "$json" | grep -o "\"${key}\"[[:space:]]*:[[:space:]]*[0-9.]\+" | head -1 | sed 's/.*:[[:space:]]*\([0-9.]\+\).*/\1/')
- fi
-
- if [[ -n "$value" && "$value" != "null" ]]; then
- echo "$value"
- else
- echo "$default"
- fi
-}
-
-parse_without_jq() {
- local input="$1"
-
- local model_name current_dir context_size current_usage
- local total_input total_output cost_usd duration_ms version session_id
-
- model_name=$(extract_json_string "$input" "display_name" "Claude")
- current_dir=$(extract_json_string "$input" "current_dir" "")
- [[ -z "$current_dir" ]] && current_dir=$(extract_json_string "$input" "cwd" "unknown")
-
- context_size=$(extract_json_string "$input" "context_window_size" "200000")
- current_usage=$(extract_json_string "$input" "input_tokens" "0")
- total_input=$(extract_json_string "$input" "total_input_tokens" "0")
- total_output=$(extract_json_string "$input" "total_output_tokens" "0")
- cost_usd=$(extract_json_string "$input" "total_cost_usd" "0")
- duration_ms=$(extract_json_string "$input" "total_duration_ms" "0")
- version=$(extract_json_string "$input" "version" "")
- session_id=$(extract_json_string "$input" "session_id" "")
-
- printf '%s\n' "$model_name" "$current_dir" "$context_size" "$current_usage" \
- "$total_input" "$total_output" "$cost_usd" "$duration_ms" "$version" "$session_id"
-}
-
-# ============================================================
-# GIT OPERATIONS (Optimized with porcelain v2)
-# ============================================================
-
-get_git_info() {
- local current_dir="$1"
- local git_opts=()
-
- [[ -n "$current_dir" && "$current_dir" != "$NULL_VALUE" && "$current_dir" != "unknown" ]] && git_opts=(-C "$current_dir")
-
- # Check if git repo
- git "${git_opts[@]}" rev-parse --is-inside-work-tree >/dev/null 2>&1 || {
- echo "$STATE_NOT_REPO"
- return 0
- }
-
- # Single git status call with all info (porcelain v2)
- local status_output
- status_output=$(git "${git_opts[@]}" status --porcelain=v2 --branch --untracked-files=all 2>/dev/null) || {
- # Fallback for older git versions
- local branch
- branch=$(git "${git_opts[@]}" branch --show-current 2>/dev/null || git "${git_opts[@]}" rev-parse --short HEAD 2>/dev/null || echo "unknown")
- echo "$STATE_CLEAN|$branch|0|0"
- return 0
- }
-
- # Parse porcelain v2 output
- local branch="" ahead="0" behind="0"
- while IFS= read -r line; do
- case "$line" in
- "# branch.head "*)
- branch="${line#\# branch.head }"
- ;;
- "# branch.ab "*)
- local ab="${line#\# branch.ab }"
- ahead="${ab%% *}"
- ahead="${ahead#+}"
- behind="${ab##* }"
- behind="${behind#-}"
- ;;
- esac
- done <<< "$status_output"
-
- branch="${branch:-(detached)}"
- ahead="${ahead:-0}"
- behind="${behind:-0}"
-
- # Count modified files (lines not starting with #)
- local file_count=0
- while IFS= read -r line; do
- [[ "$line" != \#* && -n "$line" ]] && ((file_count++))
- done <<< "$status_output"
-
- if [[ "$file_count" -eq 0 ]]; then
- echo "$STATE_CLEAN|$branch|$ahead|$behind"
- return 0
- fi
-
- # Get line changes
- local added=0 removed=0
- local diff_output
- diff_output=$(git "${git_opts[@]}" diff HEAD --numstat 2>/dev/null || true)
- if [[ -n "$diff_output" ]]; then
- while IFS=$'\t' read -r a r _; do
- [[ "$a" =~ ^[0-9]+$ ]] && added=$((added + a))
- [[ "$r" =~ ^[0-9]+$ ]] && removed=$((removed + r))
- done <<< "$diff_output"
- fi
-
- echo "$STATE_DIRTY|$branch|$file_count|$added|$removed|$ahead|$behind"
-}
-
-# ============================================================
-# COMPONENT BUILDERS
-# ============================================================
-
-build_model_component() {
- local model_name="$1"
- echo -n "${MODEL_ICON} ${CYAN}${model_name}${NC}"
-}
-
-build_context_component() {
- local context_size="$1"
- local current_usage="$2"
-
- local context_percent=0
- if [[ "$current_usage" != "0" && "$context_size" -gt 0 ]] 2>/dev/null; then
- context_percent=$((current_usage * 100 / context_size))
- fi
-
- # Determine color based on usage (inverted - higher usage = more warning)
- local bar_color
- if [[ "$context_percent" -le 20 ]]; then
- bar_color="$GREEN"
- elif [[ "$context_percent" -le 40 ]]; then
- bar_color="$CYAN"
- elif [[ "$context_percent" -le 60 ]]; then
- bar_color="$YELLOW"
- elif [[ "$context_percent" -le 80 ]]; then
- bar_color="$ORANGE"
- else
- bar_color="$RED"
- fi
-
- # Build progress bar
- local filled=$((context_percent * BAR_WIDTH / 100))
- local empty=$((BAR_WIDTH - filled))
- local bar="${bar_color}"
- bar+=$(printf "%${filled}s" | tr ' ' "$BAR_FILLED")
- bar+="${GRAY}"
- bar+=$(printf "%${empty}s" | tr ' ' "$BAR_EMPTY")
- bar+="${NC}"
-
- # Format numbers
- local usage_fmt size_fmt
- usage_fmt=$(format_number "$current_usage")
- size_fmt=$(format_number "$context_size")
-
- # Get random message
- local message
- message=$(get_context_message "$context_percent")
-
- echo -n "${CONTEXT_ICON} ${GRAY}[${NC}${bar}${GRAY}]${NC} ${context_percent}% ${usage_fmt}/${size_fmt} ${GRAY}ยท ${message}${NC}"
-}
-
-build_directory_component() {
- local current_dir="$1"
-
- local dir_name
- if [[ -n "$current_dir" && "$current_dir" != "$NULL_VALUE" && "$current_dir" != "unknown" ]]; then
- # Replace home with ~
- current_dir="${current_dir/#$HOME/\~}"
- dir_name=$(get_dirname "$current_dir")
- else
- dir_name=$(get_dirname "$PWD")
- fi
-
- echo -n "${DIR_ICON} ${BLUE}${dir_name}${NC}"
-}
-
-build_git_component() {
- local git_data="$1"
-
- local state
- IFS='|' read -r state _ <<< "$git_data"
-
- case "$state" in
- "$STATE_NOT_REPO")
- return 0
- ;;
- "$STATE_CLEAN")
- local branch ahead behind
- IFS='|' read -r _ branch ahead behind <<< "$git_data"
- echo -n "${GIT_ICON} ${MAGENTA}${branch}${NC}"
- [[ "$ahead" -gt 0 ]] 2>/dev/null && echo -n " ${GREEN}โ†‘${ahead}${NC}"
- [[ "$behind" -gt 0 ]] 2>/dev/null && echo -n " ${RED}โ†“${behind}${NC}"
- ;;
- "$STATE_DIRTY")
- local branch files added removed ahead behind
- IFS='|' read -r _ branch files added removed ahead behind <<< "$git_data"
- echo -n "${GIT_ICON} ${MAGENTA}${branch}${NC}"
- [[ "$ahead" -gt 0 ]] 2>/dev/null && echo -n " ${GREEN}โ†‘${ahead}${NC}"
- [[ "$behind" -gt 0 ]] 2>/dev/null && echo -n " ${RED}โ†“${behind}${NC}"
- echo -n " ${GRAY}ยท${NC} ${ORANGE}${files} files${NC}"
- if [[ "$added" -gt 0 || "$removed" -gt 0 ]] 2>/dev/null; then
- echo -n " ${GREEN}+${added}${NC}/${RED}-${removed}${NC}"
- fi
- ;;
- esac
-}
-
-build_cost_component() {
- local cost_usd="$1"
- local duration_ms="$2"
-
- [[ -z "$cost_usd" || "$cost_usd" == "0" || "$cost_usd" == "$NULL_VALUE" ]] && return 0
-
- local cost_fmt
- cost_fmt=$(format_cost "$cost_usd")
- echo -n "${COST_ICON} ${YELLOW}\$${cost_fmt}${NC}"
-
- # Calculate burn rate ($/hour)
- if [[ -n "$duration_ms" && "$duration_ms" -gt 0 ]] 2>/dev/null; then
- local burn_rate
- burn_rate=$(echo "$cost_usd $duration_ms" | awk '{printf "%.2f", $1 * 3600000 / $2}')
- echo -n " ${GRAY}(\$${burn_rate}/h)${NC}"
- fi
-}
-
-build_token_component() {
- local total_input="$1"
- local total_output="$2"
- local duration_ms="$3"
-
- local total_tokens=$((total_input + total_output))
- [[ "$total_tokens" -eq 0 ]] && return 0
-
- local tokens_fmt
- tokens_fmt=$(format_number "$total_tokens")
- echo -n "${TOKEN_ICON} ${LIGHT_GRAY}${tokens_fmt} tok${NC}"
-
- # Calculate TPM
- if [[ -n "$duration_ms" && "$duration_ms" -gt 0 ]] 2>/dev/null; then
- local tpm
- tpm=$(echo "$total_tokens $duration_ms" | awk '{if ($2 > 0) printf "%.0f", $1 * 60000 / $2; else print "0"}')
- echo -n " ${GRAY}(${tpm} tpm)${NC}"
- fi
-}
-
-build_time_component() {
- local duration_ms="$1"
-
- [[ -z "$duration_ms" || "$duration_ms" == "0" || "$duration_ms" == "$NULL_VALUE" ]] && return 0
-
- local duration_fmt
- duration_fmt=$(format_duration "$duration_ms")
- [[ -n "$duration_fmt" ]] && echo -n "${TIME_ICON} ${LIGHT_GRAY}${duration_fmt}${NC}"
-}
-
-build_version_component() {
- local version="$1"
-
- [[ -z "$version" || "$version" == "$NULL_VALUE" ]] && return 0
- echo -n "${VERSION_ICON} ${GRAY}v${version}${NC}"
-}
-
-# ============================================================
-# MAIN
-# ============================================================
-
-main() {
- # Read input
- local input
- input=$(cat) || {
- echo "Error: Failed to read stdin" >&2
- exit 1
- }
-
- log_debug "Status line triggered (v${STATUSLINE_VERSION})"
-
- # Parse JSON
- local parsed
- if check_jq; then
- parsed=$(parse_with_jq "$input")
- log_debug "Using jq for JSON parsing"
- else
- parsed=$(parse_without_jq "$input")
- log_debug "Using bash fallback for JSON parsing"
- fi
-
- if [[ -z "$parsed" ]]; then
- echo "Error: Failed to parse input" >&2
- exit 1
- fi
-
- # Extract fields
- local model_name current_dir context_size current_usage
- local total_input total_output cost_usd duration_ms version session_id
- {
- read -r model_name
- read -r current_dir
- read -r context_size
- read -r current_usage
- read -r total_input
- read -r total_output
- read -r cost_usd
- read -r duration_ms
- read -r version
- read -r session_id
- } <<< "$parsed"
-
- log_debug "Parsed: model=$model_name, dir=$current_dir, context=$current_usage/$context_size, cost=$cost_usd, duration=$duration_ms"
-
- # Get git info
- local git_data
- git_data=$(get_git_info "$current_dir")
-
- # Build components
- local output=""
-
- # Line 1: Model | Directory | Git | Version
- output+=$(build_model_component "$model_name")
- output+=$(sep)
- output+=$(build_directory_component "$current_dir")
-
- local git_component
- git_component=$(build_git_component "$git_data")
- [[ -n "$git_component" ]] && { output+=$(sep); output+="$git_component"; }
-
- local version_component
- version_component=$(build_version_component "$version")
- [[ -n "$version_component" ]] && { output+=$(sep); output+="$version_component"; }
-
- # Line 2: Context
- output+=$'\n'
- output+=$(build_context_component "$context_size" "$current_usage")
-
- # Line 3: Cost | Tokens | Time
- local cost_component token_component time_component
- cost_component=$(build_cost_component "$cost_usd" "$duration_ms")
- token_component=$(build_token_component "$total_input" "$total_output" "$duration_ms")
- time_component=$(build_time_component "$duration_ms")
-
- if [[ -n "$cost_component" || -n "$token_component" || -n "$time_component" ]]; then
- output+=$'\n'
- local first=1
- if [[ -n "$cost_component" ]]; then
- output+="$cost_component"
- first=0
- fi
- if [[ -n "$token_component" ]]; then
- [[ "$first" -eq 0 ]] && output+=$(sep)
- output+="$token_component"
- first=0
- fi
- if [[ -n "$time_component" ]]; then
- [[ "$first" -eq 0 ]] && output+=$(sep)
- output+="$time_component"
- fi
- fi
-
- echo -e "$output"
-}
-
-main "$@"