#!/bin/bash input=$(cat) cwd=$(echo "$input" | jq -r '.cwd') model=$(echo "$input" | jq -r '.model.display_name // empty') model_id=$(echo "$input" | jq -r '.model.id // empty') five_pct=$(echo "$input" | jq -r '.rate_limits.five_hour.used_percentage // empty') five_reset=$(echo "$input" | jq -r '.rate_limits.five_hour.resets_at // empty') week_pct=$(echo "$input" | jq -r '.rate_limits.seven_day.used_percentage // empty') week_reset=$(echo "$input" | jq -r '.rate_limits.seven_day.resets_at // empty') ctx_pct=$(echo "$input" | jq -r '.context_window.used_percentage // empty') branch=$(git -C "$cwd" --no-optional-locks symbolic-ref --short HEAD 2>/dev/null) short_cwd="${cwd/#$HOME/\~}" printf "\033[00;37m%s\033[00m" "$short_cwd" [ -n "$branch" ] && printf " \033[00;37m[%s]\033[00m" "$branch" [ -n "$model" ] && printf " \033[38;5;173m%s\033[00m" "$model" # Форматирует оставшееся время до сброса лимита fmt_remaining() { local reset_ts="$1" local now now=$(date +%s) local diff=$(( reset_ts - now )) [ "$diff" -le 0 ] && echo "скоро" && return local d=$(( diff / 86400 )) local h=$(( (diff % 86400) / 3600 )) local m=$(( (diff % 3600) / 60 )) if [ "$d" -gt 0 ]; then echo "${d}д${h}ч" elif [ "$h" -gt 0 ]; then echo "${h}ч${m}м" else echo "${m}м" fi } # Возвращает ANSI-цвет по проценту: зелёный <40%, жёлтый 40-60%, красный >=60% pct_color() { local pct="$1" if [ "$pct" -lt 40 ]; then printf '\033[00;32m' elif [ "$pct" -lt 60 ]; then printf '\033[00;33m' else printf '\033[00;31m' fi } # --- Баланс DeepSeek --- # Моментально показываем кэшированный баланс, в фоне обновляем через API. if [[ "$model_id" == *deepseek* ]]; then cache_file="$HOME/.cache/ai-setup/deepseek_balance" if [ -f "$cache_file" ]; then balance=$(head -1 "$cache_file") [ -n "$balance" ] && printf " \033[00;35m\$%s\033[00m" "$balance" fi # Фоновое обновление баланса (не чаще раза в 30 секунд) refresh_ts="$HOME/.cache/ai-setup/deepseek_balance_refresh_ts" now=$(date +%s) last=$(cat "$refresh_ts" 2>/dev/null || echo 0) if [ $(( now - last )) -gt 30 ]; then key_file="$HOME/.config/ai-setup/deepseek_key" if [ -f "$key_file" ]; then echo "$now" > "$refresh_ts" 2>/dev/null ( api_key=$(cat "$key_file") resp=$(curl -s --max-time 10 "https://api.deepseek.com/user/balance" \ -H "Authorization: Bearer $api_key" \ -H "Accept: application/json" 2>/dev/null) if [ -n "$resp" ]; then new_balance=$(echo "$resp" | python3 -c " import sys, json d = json.load(sys.stdin) infos = d.get('balance_infos', []) if infos: curr = infos[0].get('currency', '') total = infos[0].get('total_balance', '0') print(f'{total} {curr}') " 2>/dev/null) if [ -n "$new_balance" ]; then echo "$new_balance" > "$cache_file" fi fi ) & fi fi else # Рейт-лимиты для НЕ-DeepSeek провайдеров # Кеш специфичен для провайдера (по model_id) чтобы не смешивать claude/kimi/openrouter _cache_key=$(echo "${model_id:-unknown}" | sed 's/[^a-zA-Z0-9._-]/_/g') RATE_CACHE="$HOME/.cache/ai-setup/rate_limits_${_cache_key}.cache" mkdir -p "$HOME/.cache/ai-setup" # Если есть свежие данные - сохранить в кеш if [ -n "$five_pct" ] || [ -n "$week_pct" ]; then { echo "FIVE_PCT=${five_pct}" echo "FIVE_RESET=${five_reset}" echo "WEEK_PCT=${week_pct}" echo "WEEK_RESET=${week_reset}" } > "$RATE_CACHE" fi # Если нет данных - читать из кеша (старт сессии до первого запроса) if [ -z "$five_pct" ] && [ -z "$week_pct" ] && [ -f "$RATE_CACHE" ]; then # shellcheck source=/dev/null source "$RATE_CACHE" 2>/dev/null five_pct="${FIVE_PCT:-}" five_reset="${FIVE_RESET:-}" week_pct="${WEEK_PCT:-}" week_reset="${WEEK_RESET:-}" fi if [ -n "$five_pct" ] && [ -n "$five_reset" ]; then five_int=$(printf '%.0f' "$five_pct") remaining=$(fmt_remaining "$five_reset") color=$(pct_color "$five_int") printf " %s%s:%s%%\033[00m" "$color" "$remaining" "$five_int" fi if [ -n "$week_pct" ] && [ -n "$week_reset" ]; then week_int=$(printf '%.0f' "$week_pct") remaining=$(fmt_remaining "$week_reset") color=$(pct_color "$week_int") printf " %s%s:%s%%\033[00m" "$color" "$remaining" "$week_int" fi fi # ctx:0% при старте новой сессии (нет данных от API) [ -z "$ctx_pct" ] && ctx_pct="0" if [ -n "$ctx_pct" ]; then ctx_int=$(printf '%.0f' "$ctx_pct") color=$(pct_color "$ctx_int") printf " %sctx:%s%%\033[00m" "$color" "$ctx_int" # Звуковой сигнал при первом достижении 60% alert_file="$HOME/.cache/ai-setup/ctx_alert_state" if [ "$ctx_int" -ge 60 ]; then if [ ! -f "$alert_file" ] || [ "$(cat "$alert_file")" != "alerted" ]; then mkdir -p "$HOME/.cache/ai-setup" echo "alerted" > "$alert_file" (timeout 1s paplay /usr/share/sounds/freedesktop/stereo/alarm-clock-elapsed.oga 2>/dev/null; true) & fi elif [ "$ctx_int" -lt 50 ]; then rm -f "$alert_file" 2>/dev/null fi fi exit 0