fix: статусбар показывает реальный email активного Claude-аккаунта

Статусбар слепо доверял accounts/current и показывал legacy-имя даже когда
активна сессия другого аккаунта. Теперь сверяем accessToken из
<current>.credentials.json с активным ~/.claude/.credentials.json и при
расхождении резолвим аккаунт по токену: локальный матч плюс account-email.sh
вместо haiku-велосипеда. Kimi-блок показывает alias (account1/account2).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Виталий Никитенко
2026-06-15 06:41:33 +03:00
parent 1cb4853dca
commit 61a4421ed2

View File

@@ -44,13 +44,19 @@ if [ -n "$model" ]; then
effort=$(echo "$input" | jq -r ".effort.level // empty") effort=$(echo "$input" | jq -r ".effort.level // empty")
# Аккаунт Claude.ai актуален только для нативных моделей Claude # Аккаунт Claude.ai актуален только для нативных моделей Claude
if [[ "$model_id" == claude-* ]]; then if [[ "$model_id" == claude-* ]]; then
account=$(cat ~/.claude/accounts/current 2>/dev/null)
ACCOUNTS_DIR="$HOME/.claude/accounts" ACCOUNTS_DIR="$HOME/.claude/accounts"
# Автоопределение: если current пуст или файл не существует — account=$(cat "$ACCOUNTS_DIR/current" 2>/dev/null)
# ищем аккаунт по access-токену в .credentials.json
if [ -z "$account" ] || [ ! -f "$ACCOUNTS_DIR/${account}.credentials.json" ]; then
current_token=$(jq -r '.claudeAiOauth.accessToken // empty' "$HOME/.claude/.credentials.json" 2>/dev/null) current_token=$(jq -r '.claudeAiOauth.accessToken // empty' "$HOME/.claude/.credentials.json" 2>/dev/null)
# current надёжен, только если его файл существует И токен совпадает с активной сессией.
account_token=""
if [ -n "$account" ] && [ -f "$ACCOUNTS_DIR/${account}.credentials.json" ]; then
account_token=$(jq -r '.claudeAiOauth.accessToken // empty' "$ACCOUNTS_DIR/${account}.credentials.json" 2>/dev/null)
fi
# Рассинхрон (пусто или чужой токен) — определяем аккаунт по активному токену.
if [ -z "$account" ] || [ "$account_token" != "$current_token" ]; then
account=""
if [ -n "$current_token" ]; then if [ -n "$current_token" ]; then
# 1) Локальный матч по токену среди сохранённых аккаунтов (мгновенно)
for f in "$ACCOUNTS_DIR"/*.credentials.json; do for f in "$ACCOUNTS_DIR"/*.credentials.json; do
[ ! -f "$f" ] && continue [ ! -f "$f" ] && continue
token=$(jq -r '.claudeAiOauth.accessToken // empty' "$f" 2>/dev/null) token=$(jq -r '.claudeAiOauth.accessToken // empty' "$f" 2>/dev/null)
@@ -60,18 +66,13 @@ if [ -n "$model" ]; then
break break
fi fi
done done
# Если токен не найден — спрашиваем haiku (один раз на аккаунт) # 2) Не нашли локально — резолвим email через account-email.sh (один раз на токен)
if [ -z "$account" ]; then if [ -z "$account" ]; then
sentinel="$HOME/.cache/ai-setup/email_fetch_token" sentinel="$HOME/.cache/ai-setup/email_fetch_token"
prev_token=$(cat "$sentinel" 2>/dev/null) if [ "$(cat "$sentinel" 2>/dev/null)" != "$current_token" ]; then
if [ "$prev_token" != "$current_token" ]; then
mkdir -p "$HOME/.cache/ai-setup" mkdir -p "$HOME/.cache/ai-setup"
echo "$current_token" > "$sentinel" echo "$current_token" > "$sentinel"
email=$(unset ANTHROPIC_BASE_URL ANTHROPIC_AUTH_TOKEN; \ email=$(bash "$HOME/.claude/hooks/account-email.sh" "$HOME/.claude/.credentials.json" 2>/dev/null)
echo 'какой имейл этого аккаунта? напиши только имейл без других слов.' | \
claude --print --model claude-haiku-4-5 --dangerously-skip-permissions \
--output-format text --max-turns 1 --tools "" --effort low 2>/dev/null)
email=$(echo "$email" | grep -oE '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}' | head -1)
if [ -n "$email" ]; then if [ -n "$email" ]; then
cp "$HOME/.claude/.credentials.json" "$ACCOUNTS_DIR/${email}.credentials.json" cp "$HOME/.claude/.credentials.json" "$ACCOUNTS_DIR/${email}.credentials.json"
chmod 600 "$ACCOUNTS_DIR/${email}.credentials.json" chmod 600 "$ACCOUNTS_DIR/${email}.credentials.json"
@@ -85,13 +86,10 @@ if [ -n "$model" ]; then
[ -n "$account" ] && printf " %s[%s]\033[00m" "$brand_color" "$account" [ -n "$account" ] && printf " %s[%s]\033[00m" "$brand_color" "$account"
fi fi
# Аккаунт/ключ Kimi — показываем email/имя из .meta, если оно есть, иначе alias. # Аккаунт/ключ Kimi — показываем alias (account1/account2/...).
if [ "${AI_LAUNCHER:-}" = "kimi" ]; then if [ "${AI_LAUNCHER:-}" = "kimi" ]; then
kimi_account=$(cat "$HOME/.config/ai-setup/kimi_keys/current" 2>/dev/null) kimi_account=$(cat "$HOME/.config/ai-setup/kimi_keys/current" 2>/dev/null)
if [ -n "$kimi_account" ]; then [ -n "$kimi_account" ] && printf " %s[%s]\033[00m" "$brand_color" "$kimi_account"
kimi_display=$(cat "$HOME/.config/ai-setup/kimi_keys/${kimi_account}.meta" 2>/dev/null || echo "$kimi_account")
printf " %s[%s]\033[00m" "$brand_color" "$kimi_display"
fi
fi fi
if [ -n "$effort" ]; then if [ -n "$effort" ]; then
printf " %s%s " "$brand_color" "$model" printf " %s%s " "$brand_color" "$model"