Files
ai-setup/home-configs/claude/hooks/switch-account-hook.sh
vitaly fe439fd4a6 feat: автодобавление Claude-аккаунта через /add-account
- новый хук add-account-hook.sh: сохраняет текущий аккаунт по реальному
  email (claude auth status), запускает OAuth-логин в фоне и после успеха
  сам сохраняет новый аккаунт в ~/.claude/accounts + делает его current
- switch-account-hook.sh: активный аккаунт определяется через
  claude auth status, а не через хрупкий файл current - защита от порчи
  сохранённых credentials при рассинхроне токена
- скилл add-account: краткая инструкция после срабатывания хука
- ai-setup.sh: деплой add-account-hook + регистрация в UserPromptSubmit

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-12 08:19:46 +03:00

56 lines
2.6 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
# UserPromptSubmit hook: перехватывает /switch-account и обновляет аккаунт.
# Используем exit 0 (не exit 2) чтобы Claude ответил - это единственный способ
# обновить статусную строку, т.к. Claude Code перерисовывает её только после ответа LLM.
input=$(cat)
prompt=$(echo "$input" | jq -r '.user_prompt // .prompt // empty' 2>/dev/null)
# Нормализуем: убираем пробелы и слэш в начале
normalized=$(echo "$prompt" | sed 's|^[[:space:]]*/||; s|[[:space:]]*$||')
[ "$normalized" != "switch-account" ] && exit 0
# --- Переключаем аккаунт ---
ACCOUNTS_DIR="$HOME/.claude/accounts"
CREDS="$HOME/.claude/.credentials.json"
CURRENT_FILE="$ACCOUNTS_DIR/current"
mkdir -p "$ACCOUNTS_DIR"
mapfile -t accounts < <(ls "$ACCOUNTS_DIR"/*.credentials.json 2>/dev/null \
| xargs -I{} basename {} .credentials.json | sort)
if [ ${#accounts[@]} -eq 0 ]; then
echo "Аккаунты не настроены. Создай ~/.claude/accounts/<name>.credentials.json для каждого аккаунта." >&2
exit 2
fi
# Реальный активный аккаунт — источник истины claude auth status (а не хрупкий
# файл current). Это защищает от порчи сохранённых credentials при рассинхроне.
current=$(claude auth status 2>/dev/null | jq -r '.email // empty' 2>/dev/null)
[ -z "$current" ] && current=$(cat "$CURRENT_FILE" 2>/dev/null || echo "")
# Найти следующий по кругу
idx=-1
for i in "${!accounts[@]}"; do
[ "${accounts[$i]}" = "$current" ] && idx=$i && break
done
next_idx=$(( (idx + 1) % ${#accounts[@]} ))
next="${accounts[$next_idx]}"
# Сохранить текущие (возможно обновлённые Claude Code) токены обратно в файл аккаунта
if [ -n "$current" ] && [ -f "$CREDS" ]; then
cp "$CREDS" "$ACCOUNTS_DIR/${current}.credentials.json"
chmod 600 "$ACCOUNTS_DIR/${current}.credentials.json"
fi
cp "$ACCOUNTS_DIR/${next}.credentials.json" "$CREDS"
chmod 600 "$CREDS"
echo "$next" > "$CURRENT_FILE"
# exit 0 (не exit 2): оригинальный /switch-account доходит до Claude,
# Claude загружает скилл switch-account, скилл велит ответить только "✓" (1 токен).
# Это единственный способ обновить статусную строку без лишних токенов.
exit 0