- Зачем:
- statusLine ссылался на ~/.claude/statusline-command.sh, которого install.sh
никогда не создавал, а сам скрипт не округлял проценты и резал путь по числу
сегментов вместо длины.
- Что:
- скрипт переписан: округление процентов до целых, порог длины пути в
переменной MAX_PATH_LEN (28), резервный разбор JSON без jq, USER/USERNAME и
HOSTNAME вместо hostname -s, нормализация обратных слэшей — для Git Bash.
- install.sh копирует statusline-command.sh в ~/.claude с правами 755.
- Проверка:
- printf '%s' "$json" | bash claude/.claude/statusline-command.sh на JSON с
дробными процентами, null в rate_limits и без блока rate_limits.
117 lines
4.0 KiB
Bash
Executable File
117 lines
4.0 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
# Статусная строка Claude Code. JSON приходит на stdin.
|
||
#
|
||
# user@host:.../dir (branch) | Model Name (NM context) ctx:N% | 5h:N% 7d:N%
|
||
#
|
||
# Работает в Linux и в Git Bash на Windows: без `hostname -s`, jq не обязателен.
|
||
|
||
# Порог, после которого путь сокращается до .../<последний каталог>
|
||
MAX_PATH_LEN="${STATUSLINE_MAX_PATH_LEN:-28}"
|
||
|
||
input="$(cat)"
|
||
|
||
# ── Разбор JSON ───────────────────────────────────────────────────────
|
||
|
||
# Числовое поле $2 внутри объекта $1 (резервный разбор, без jq).
|
||
json_num() {
|
||
printf '%s' "$input" \
|
||
| tr -d ' \t\n\r' \
|
||
| grep -o "\"$1\":{[^}]*}" \
|
||
| grep -o "\"$2\":[0-9.eE+-]*" \
|
||
| head -1 \
|
||
| cut -d: -f2
|
||
}
|
||
|
||
# Строковое поле $2 внутри объекта $1 (резервный разбор, без jq).
|
||
json_str() {
|
||
printf '%s' "$input" \
|
||
| tr -d '\n\r' \
|
||
| grep -o "\"$1\"[[:space:]]*:[[:space:]]*{[^}]*}" \
|
||
| grep -o "\"$2\"[[:space:]]*:[[:space:]]*\"[^\"]*\"" \
|
||
| head -1 \
|
||
| sed 's/.*"[[:space:]]*:[[:space:]]*"//; s/"$//'
|
||
}
|
||
|
||
if command -v jq >/dev/null 2>&1; then
|
||
IFS=$'\t' read -r cwd display_name ctx_pct rate5h rate7d <<EOF
|
||
$(printf '%s' "$input" | jq -r '
|
||
def num: if type == "number" then tostring else "" end;
|
||
[ (.workspace.current_dir // ""),
|
||
(.model.display_name // ""),
|
||
(.context_window.used_percentage | num),
|
||
(.rate_limits.five_hour.used_percentage | num),
|
||
(.rate_limits.seven_day.used_percentage | num)
|
||
] | @tsv' 2>/dev/null)
|
||
EOF
|
||
else
|
||
cwd="$(json_str workspace current_dir)"
|
||
display_name="$(json_str model display_name)"
|
||
ctx_pct="$(json_num context_window used_percentage)"
|
||
rate5h="$(json_num five_hour used_percentage)"
|
||
rate7d="$(json_num seven_day used_percentage)"
|
||
fi
|
||
|
||
# Проценты в JSON дробные — округляем до целых.
|
||
round_pct() {
|
||
case "$1" in
|
||
''|null) return 0 ;;
|
||
esac
|
||
awk -v v="$1" 'BEGIN { printf "%d", (v < 0 ? -int(-v + 0.5) : int(v + 0.5)) }' 2>/dev/null
|
||
}
|
||
|
||
ctx_pct="$(round_pct "$ctx_pct")"
|
||
rate5h="$(round_pct "$rate5h")"
|
||
rate7d="$(round_pct "$rate7d")"
|
||
|
||
# ── Путь ──────────────────────────────────────────────────────────────
|
||
|
||
# В Git Bash current_dir может прийти с обратными слэшами.
|
||
path="${cwd//\\//}"
|
||
home="${HOME//\\//}"
|
||
|
||
if [ -n "$home" ]; then
|
||
if [ "$path" = "$home" ]; then
|
||
path="~"
|
||
else
|
||
case "$path" in
|
||
"$home"/*) path="~${path#"$home"}" ;;
|
||
esac
|
||
fi
|
||
fi
|
||
|
||
if [ "${#path}" -gt "$MAX_PATH_LEN" ]; then
|
||
path=".../${path##*/}"
|
||
fi
|
||
|
||
# ── Остальные секции ──────────────────────────────────────────────────
|
||
|
||
branch=""
|
||
if [ -n "$cwd" ]; then
|
||
branch="$(git -C "$cwd" rev-parse --abbrev-ref HEAD 2>/dev/null)"
|
||
fi
|
||
|
||
# Размер контекста уже внутри display_name, убираем только префикс «Claude ».
|
||
model="${display_name#Claude }"
|
||
|
||
user="${USER:-${USERNAME:-$(id -un 2>/dev/null)}}"
|
||
host="${HOSTNAME:-$(hostname 2>/dev/null)}"
|
||
host="${host%%.*}"
|
||
|
||
GREEN=$'\033[32m'
|
||
YELLOW=$'\033[33m'
|
||
PURPLE=$'\033[35m'
|
||
CYAN=$'\033[36m'
|
||
RESET=$'\033[0m'
|
||
|
||
out="${GREEN}${user}@${host}${RESET}:${YELLOW}${path}${RESET}"
|
||
[ -n "$branch" ] && out="${out} ${PURPLE}(${branch})${RESET}"
|
||
out="${out} | ${CYAN}${model}${RESET}"
|
||
[ -n "$ctx_pct" ] && out="${out} ctx:${ctx_pct}%"
|
||
|
||
rates=""
|
||
[ -n "$rate5h" ] && rates="${rates} 5h:${rate5h}%"
|
||
[ -n "$rate7d" ] && rates="${rates} 7d:${rate7d}%"
|
||
[ -n "$rates" ] && out="${out} |${rates}"
|
||
|
||
printf '%s\n' "$out"
|