mr-claude-stats 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +67 -0
- package/bin/mr-claude-stats +110 -0
- package/package.json +25 -0
package/README.md
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# mr-claude-stats
|
|
2
|
+
|
|
3
|
+
The most accurate statusline for Claude Code CLI with a colorful progress bar.
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- Accurate context token counting (reads from transcript)
|
|
10
|
+
- Colorful gradient progress bar (green → yellow → orange → red)
|
|
11
|
+
- Caches last value to avoid flickering on slash commands
|
|
12
|
+
- Shows model name and token usage
|
|
13
|
+
- Lightweight bash script (no dependencies)
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install -g mr-claude-stats
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Or with bun:
|
|
22
|
+
```bash
|
|
23
|
+
bun install -g mr-claude-stats
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Setup
|
|
27
|
+
|
|
28
|
+
Add to your `~/.claude/settings.json`:
|
|
29
|
+
|
|
30
|
+
```json
|
|
31
|
+
{
|
|
32
|
+
"statusLine": {
|
|
33
|
+
"type": "command",
|
|
34
|
+
"command": "mr-claude-stats"
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## What it shows
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
████████████████████████████████░░░░░░░░░░░░░░░░░░░░░░░░░░░░
|
|
43
|
+
Opus 4.5 130k/200k (65%)
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
- **Line 1**: Progress bar with color gradient based on usage
|
|
47
|
+
- **Line 2**: Model name (left) and token usage (right)
|
|
48
|
+
|
|
49
|
+
## Why this is more accurate
|
|
50
|
+
|
|
51
|
+
Other statusline tools use `total_input_tokens` + `total_output_tokens` from the statusline JSON, which are **cumulative session totals** (buggy).
|
|
52
|
+
|
|
53
|
+
This tool reads directly from the **transcript file** and calculates:
|
|
54
|
+
```
|
|
55
|
+
input_tokens + cache_creation_input_tokens + cache_read_input_tokens + autocompact_buffer
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
This matches the official `/context` command output.
|
|
59
|
+
|
|
60
|
+
## Requirements
|
|
61
|
+
|
|
62
|
+
- `jq` (JSON processor)
|
|
63
|
+
- `bash`
|
|
64
|
+
|
|
65
|
+
## License
|
|
66
|
+
|
|
67
|
+
MIT
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
export LC_NUMERIC=C
|
|
3
|
+
input=$(cat)
|
|
4
|
+
|
|
5
|
+
MODEL=$(echo "$input" | jq -r '.model.display_name // "Claude"')
|
|
6
|
+
CONTEXT=$(echo "$input" | jq -r '.context_window.context_window_size // 200000')
|
|
7
|
+
TRANSCRIPT=$(echo "$input" | jq -r '.transcript_path // ""')
|
|
8
|
+
|
|
9
|
+
# Cache para persistir último valor conhecido
|
|
10
|
+
CACHE_FILE="/tmp/statusline_cache_${SESSION_ID:-default}"
|
|
11
|
+
SESSION_ID=$(echo "$input" | jq -r '.session_id // "default"')
|
|
12
|
+
CACHE_FILE="/tmp/statusline_cache_${SESSION_ID}"
|
|
13
|
+
|
|
14
|
+
# Ler usage do último request com usage válido no transcript
|
|
15
|
+
TOTAL=0
|
|
16
|
+
if [ -n "$TRANSCRIPT" ] && [ -f "$TRANSCRIPT" ]; then
|
|
17
|
+
# Buscar último entry que tem usage (ignorar comandos locais sem usage)
|
|
18
|
+
LAST_USAGE=$(tac "$TRANSCRIPT" 2>/dev/null | jq -s '[.[] | select(.usage != null or .message.usage != null)] | .[0] | .usage // .message.usage' 2>/dev/null)
|
|
19
|
+
if [ -n "$LAST_USAGE" ] && [ "$LAST_USAGE" != "null" ]; then
|
|
20
|
+
INPUT_T=$(echo "$LAST_USAGE" | jq -r '.input_tokens // 0')
|
|
21
|
+
CACHE_CREATE=$(echo "$LAST_USAGE" | jq -r '.cache_creation_input_tokens // 0')
|
|
22
|
+
CACHE_READ=$(echo "$LAST_USAGE" | jq -r '.cache_read_input_tokens // 0')
|
|
23
|
+
OUTPUT_T=$(echo "$LAST_USAGE" | jq -r '.output_tokens // 0')
|
|
24
|
+
# Total = input atual + cache + output + buffer de autocompact (45k)
|
|
25
|
+
MESSAGES=$((INPUT_T + CACHE_CREATE + CACHE_READ + OUTPUT_T))
|
|
26
|
+
AUTOCOMPACT_BUFFER=45000
|
|
27
|
+
TOTAL=$((MESSAGES + AUTOCOMPACT_BUFFER))
|
|
28
|
+
# Salvar no cache
|
|
29
|
+
echo "$TOTAL" > "$CACHE_FILE"
|
|
30
|
+
fi
|
|
31
|
+
fi
|
|
32
|
+
|
|
33
|
+
# Se não encontrou, usar cache anterior
|
|
34
|
+
if [ "$TOTAL" -eq 0 ] && [ -f "$CACHE_FILE" ]; then
|
|
35
|
+
TOTAL=$(cat "$CACHE_FILE" 2>/dev/null || echo 45000)
|
|
36
|
+
fi
|
|
37
|
+
|
|
38
|
+
# Fallback final
|
|
39
|
+
if [ "$TOTAL" -eq 0 ]; then
|
|
40
|
+
TOTAL=45000
|
|
41
|
+
fi
|
|
42
|
+
PERCENT=$((TOTAL * 100 / CONTEXT))
|
|
43
|
+
|
|
44
|
+
# Cores ANSI (pastel)
|
|
45
|
+
BLUE='\033[38;5;117m'
|
|
46
|
+
GREEN='\033[38;5;114m'
|
|
47
|
+
YELLOW='\033[38;5;186m'
|
|
48
|
+
ORANGE='\033[38;5;216m'
|
|
49
|
+
RED='\033[38;5;174m'
|
|
50
|
+
GRAY='\033[38;5;242m'
|
|
51
|
+
RESET='\033[0m'
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
# Formatar tokens
|
|
55
|
+
format_tokens() {
|
|
56
|
+
local n=$1
|
|
57
|
+
if [ $n -ge 1000 ]; then
|
|
58
|
+
echo "$((n / 1000))k"
|
|
59
|
+
else
|
|
60
|
+
echo "$n"
|
|
61
|
+
fi
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
TOTAL_FMT=$(format_tokens $TOTAL)
|
|
65
|
+
CONTEXT_FMT=$(format_tokens $CONTEXT)
|
|
66
|
+
|
|
67
|
+
# Barra de 60 caracteres com gradiente
|
|
68
|
+
BAR_SIZE=60
|
|
69
|
+
FILLED=$((PERCENT * BAR_SIZE / 100))
|
|
70
|
+
EMPTY=$((BAR_SIZE - FILLED))
|
|
71
|
+
|
|
72
|
+
# Thresholds para cores (em chars)
|
|
73
|
+
T1=$((BAR_SIZE * 25 / 100)) # 25% = 15 chars
|
|
74
|
+
T2=$((BAR_SIZE * 50 / 100)) # 50% = 30 chars
|
|
75
|
+
T3=$((BAR_SIZE * 75 / 100)) # 75% = 45 chars
|
|
76
|
+
|
|
77
|
+
BAR=""
|
|
78
|
+
for ((i=0; i<FILLED; i++)); do
|
|
79
|
+
if [ $i -lt $T1 ]; then
|
|
80
|
+
BAR+="${GREEN}█"
|
|
81
|
+
elif [ $i -lt $T2 ]; then
|
|
82
|
+
BAR+="${YELLOW}█"
|
|
83
|
+
elif [ $i -lt $T3 ]; then
|
|
84
|
+
BAR+="${ORANGE}█"
|
|
85
|
+
else
|
|
86
|
+
BAR+="${RED}█"
|
|
87
|
+
fi
|
|
88
|
+
done
|
|
89
|
+
BAR+="${GRAY}"
|
|
90
|
+
for ((i=0; i<EMPTY; i++)); do BAR+="░"; done
|
|
91
|
+
BAR+="${RESET}"
|
|
92
|
+
|
|
93
|
+
# Cor do texto baseada no percentual
|
|
94
|
+
if [ $PERCENT -lt 25 ]; then
|
|
95
|
+
TEXT_COLOR=$GREEN
|
|
96
|
+
elif [ $PERCENT -lt 50 ]; then
|
|
97
|
+
TEXT_COLOR=$YELLOW
|
|
98
|
+
elif [ $PERCENT -lt 75 ]; then
|
|
99
|
+
TEXT_COLOR=$ORANGE
|
|
100
|
+
else
|
|
101
|
+
TEXT_COLOR=$RED
|
|
102
|
+
fi
|
|
103
|
+
|
|
104
|
+
# Info formatada com largura fixa (18 chars total)
|
|
105
|
+
RIGHT=$(printf "%18s" "${TOTAL_FMT}/${CONTEXT_FMT} (${PERCENT}%)")
|
|
106
|
+
|
|
107
|
+
# Row 1: Barra
|
|
108
|
+
echo -e "$BAR"
|
|
109
|
+
# Row 2: Model (azul) esquerda, tokens (cor) direita
|
|
110
|
+
echo -e "${BLUE}$(printf "%-42s" "$MODEL")${RESET}${TEXT_COLOR}${RIGHT}${RESET}"
|
package/package.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "mr-claude-stats",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Accurate statusline for Claude Code CLI with colorful progress bar",
|
|
5
|
+
"bin": {
|
|
6
|
+
"mr-claude-stats": "./bin/mr-claude-stats"
|
|
7
|
+
},
|
|
8
|
+
"keywords": [
|
|
9
|
+
"claude",
|
|
10
|
+
"claude-code",
|
|
11
|
+
"statusline",
|
|
12
|
+
"cli",
|
|
13
|
+
"tokens",
|
|
14
|
+
"context"
|
|
15
|
+
],
|
|
16
|
+
"author": "MrIago",
|
|
17
|
+
"license": "MIT",
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "https://github.com/MrIago/mr-claude-stats"
|
|
21
|
+
},
|
|
22
|
+
"engines": {
|
|
23
|
+
"node": ">=14"
|
|
24
|
+
}
|
|
25
|
+
}
|