Files
ai-setup/home-configs/claude/hooks/switch-account-hook.sh
vitaly 08f23e857e feat: прямая перерисовка статусной строки через TTY escape-коды
SIGWINCH и TIOCSWINSZ не заставляют Claude Code обновить статусную строку.
Запускаем statusline-command.sh с кешем и пишем результат напрямую
в TTY claude через \0337 (save cursor) / \033[999B / \033[2K / \0338.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 21:22:36 +03:00

63 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 без участия 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
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]}"
cp "$ACCOUNTS_DIR/${next}.credentials.json" "$CREDS"
chmod 600 "$CREDS"
echo "$next" > "$CURRENT_FILE"
echo "Аккаунт: ${current:-?} -> ${next} (всего: ${#accounts[@]})" >&2
# Обновляем статусную строку: перерисовываем последнюю строку напрямую в TTY
sh_pid=$PPID
claude_pid=$(awk '/PPid/{print $2}' /proc/$sh_pid/status 2>/dev/null)
if [ -n "$claude_pid" ]; then
tty_dev=$(ps -o tty= -p "$claude_pid" 2>/dev/null | tr -d ' ')
if [ -n "$tty_dev" ] && [ "$tty_dev" != "?" ]; then
# Запускаем statusline-command.sh с кешированными данными и перерисовываем последнюю строку
cache_file=$(ls "$HOME/.cache/ai-setup/rate_limits_"*.cache 2>/dev/null | head -1)
model_id=$(basename "${cache_file}" .cache | sed 's/rate_limits_//')
( sleep 0.2
# Собираем данные из кеша для statusline
mock_json="{\"cwd\":\"$(echo "$input" | jq -r '.cwd // empty')\",\"model\":{\"display_name\":\"\",\"id\":\"$model_id\"},\"rate_limits\":{},\"context_window\":{}}"
new_line=$(echo "$mock_json" | bash "$HOME/.claude/statusline-command.sh" 2>/dev/null)
# Перерисовываем последнюю строку через escape-коды
printf '\0337\033[999B\033[2K%s\0338' "$new_line" > "/dev/$tty_dev"
) &
fi
fi
exit 2