1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#!/bin/bash
# Usage: statusline.sh [--short-model]
# --short-model Show abbreviated model name (e.g., "sonnet-4.5")
# Default shows the full model ID
# Read JSON input from stdin
input=$(cat)
# Extract model name
model_id=$(echo "$input" | jq -r '.model.id')
if [[ "$1" == "--short-model" ]]; then
model=$(echo "$model_id" | sed -E 's/^.*claude-//; s/-[0-9]{8,}.*$//; s/^([a-z]+)-([0-9]+)-([0-9]+)$/\1-\2.\3/')
else
model="$model_id"
fi
# Get the default model from settings and format it the same way
default_model=$(jq -r '.model // "sonnet"' ~/.claude/settings.json)
# Only show model if it's not the default
if [[ "$model" =~ ^${default_model} ]]; then
model=''
fi
# Get current working directory
cwd=$(echo "$input" | jq -r '.workspace.current_dir')
# Get output style
style=$(echo "$input" | jq -r '.output_style.name')
# Get git repository name and root (or fall back to current directory)
repo=''
git_root=''
if git -C "$cwd" rev-parse --git-dir > /dev/null 2>&1; then
git_root=$(git -C "$cwd" rev-parse --show-toplevel 2>/dev/null)
repo=$(basename "$git_root" 2>/dev/null)
fi
if [ -z "$repo" ]; then
repo=$(basename "$cwd")
fi
# Calculate relative path if cwd differs from git root
rel_path=''
if [ -n "$git_root" ] && [ "$cwd" != "$git_root" ]; then
rel_path="${cwd#$git_root/}"
fi
# Get git branch
branch=$(git -C "$cwd" branch --show-current 2>/dev/null || echo '')
# Calculate context window usage
ctx=''
usage=$(echo "$input" | jq '.context_window.current_usage')
if [ "$usage" != 'null' ]; then
cur=$(($(echo "$usage" | jq '.input_tokens + .cache_creation_input_tokens + .cache_read_input_tokens')))
sz=$(echo "$input" | jq '.context_window.context_window_size')
pct=$((cur * 100 / sz))
# Format token counts as "125k" or "1.0M"
fmt_tokens() {
if [ "$1" -ge 1000000 ]; then
printf '%s.%sM' $(($1 / 1000000)) $(($1 % 1000000 / 100000))
else
printf '%sk' $(($1 / 1000))
fi
}
cur_fmt=$(fmt_tokens "$cur")
sz_fmt=$(fmt_tokens "$sz")
# Color shifts with usage: green < 50%, yellow 50-80%, red > 80%
if [ "$pct" -gt 80 ]; then
color='31' # red
elif [ "$pct" -gt 50 ]; then
color='33' # yellow
else
color='32' # green
fi
ctx=$(printf " \033[2m•\033[0m \033[%sm%s/%s %s%%\033[0m" "$color" "$cur_fmt" "$sz_fmt" "$pct")
fi
# Format output style
sty=''
if [ "$style" != 'null' ] && [ "$style" != 'default' ]; then
sty=$(printf " \033[2m•\033[0m \033[35m%s\033[0m" "$style")
fi
# Calculate session cost
cost=''
total_input=$(echo "$input" | jq '.context_window.total_input_tokens // 0')
total_output=$(echo "$input" | jq '.context_window.total_output_tokens // 0')
if [ "$total_input" != "0" ] || [ "$total_output" != "0" ]; then
# Pricing per million tokens (as of Jan 2025)
# Opus 4.5: $15 input, $75 output
# Sonnet 4.5: $3 input, $15 output
# Haiku 4.5: $0.80 input, $4 output
if [[ "$model_id" =~ opus ]]; then
input_cost=$(echo "scale=4; $total_input * 15 / 1000000" | bc)
output_cost=$(echo "scale=4; $total_output * 75 / 1000000" | bc)
elif [[ "$model_id" =~ haiku ]]; then
input_cost=$(echo "scale=4; $total_input * 0.80 / 1000000" | bc)
output_cost=$(echo "scale=4; $total_output * 4 / 1000000" | bc)
else
# Default to Sonnet pricing
input_cost=$(echo "scale=4; $total_input * 3 / 1000000" | bc)
output_cost=$(echo "scale=4; $total_output * 15 / 1000000" | bc)
fi
total_cost=$(echo "scale=4; $input_cost + $output_cost" | bc)
# Only show if non-zero
if (( $(echo "$total_cost > 0" | bc -l) )); then
cost=$(printf " \033[2m•\033[0m \033[36m\$%.2f\033[0m" "$total_cost")
fi
fi
# Build location string (repo:branch/path or just repo)
loc=$(printf "\033[34m%s\033[0m" "$repo")
if [ -n "$branch" ]; then
loc=$(printf "%s\033[2m:\033[0m\033[36m%s\033[0m" "$loc" "$branch")
fi
if [ -n "$rel_path" ]; then
loc=$(printf "%s\033[2m/\033[0m\033[33m%s\033[0m" "$loc" "$rel_path")
fi
# Build the status line with left-aligned prefix
# Format: ✴ model • location • context • cost • style
parts=""
if [ -n "$model" ]; then
parts=$(printf "\033[32m%s\033[0m" "$model")
if [ -n "$loc" ] || [ -n "$ctx" ] || [ -n "$cost" ] || [ -n "$sty" ]; then
parts=$(printf '%s \033[2m•\033[0m' "$parts")
fi
fi
# Add location
if [ -n "$loc" ]; then
parts="${parts} ${loc}"
fi
# Add remaining parts
parts="${parts}${ctx}${cost}${sty}"
# Current time
parts=$(printf "%s \033[2m•\033[0m %s" "$parts" "$(date +%H:%M)")
printf "✴️ %s\n" "$parts"