Add script and documentation

This commit is contained in:
2026-05-30 21:47:06 +07:00
parent a27eb5d0f7
commit 6f2c1b0b97
2 changed files with 399 additions and 0 deletions

361
claude_setup.sh Normal file
View File

@@ -0,0 +1,361 @@
#!/usr/bin/env bash
# ============================================================
# Claude Code Setup — Anthropic / GPT-5.5 / DeepSeek / Gemini
# Запуск: bash claude_setup.sh
# ============================================================
BASHRC="$HOME/.bashrc"
CONFIG_DIR="$HOME/.config/claude-launcher"
DEEPSEEK_KEY_FILE="$CONFIG_DIR/deepseek_key"
NPM_GLOBAL="$HOME/.npm-global"
PROXY_BIN="$HOME/.local/bin/claude-code-proxy"
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; CYAN='\033[0;36m'; NC='\033[0m'
info() { echo -e "${CYAN}[INFO]${NC} $*"; }
success() { echo -e "${GREEN}[OK]${NC} $*"; }
warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
err() { echo -e "${RED}[ERR]${NC} $*"; exit 1; }
# Запрет запуска от root
if [ "$EUID" -eq 0 ]; then
echo -e "${RED}Не запускайте этот скрипт через sudo!${NC}"
echo "Запустите просто: bash claude_setup.sh"
exit 1
fi
# ── 1. npm prefix в домашнюю папку ──────────────────────────
info "Настраиваю npm prefix..."
mkdir -p "$NPM_GLOBAL"
npm config set prefix "$NPM_GLOBAL"
success "npm prefix -> $NPM_GLOBAL"
# Добавляем npm-global в PATH прямо сейчас (для этого запуска скрипта)
export PATH="$NPM_GLOBAL/bin:$HOME/.local/bin:$PATH"
# Прописываем в .bashrc если ещё нет
if ! grep -q 'NPM_GLOBAL' "$BASHRC" 2>/dev/null; then
cat >> "$BASHRC" << 'PATHEOF'
# npm global без sudo
export NPM_GLOBAL="$HOME/.npm-global"
export PATH="$NPM_GLOBAL/bin:$HOME/.local/bin:$PATH"
PATHEOF
success "npm PATH добавлен в $BASHRC"
else
success "npm PATH уже есть в $BASHRC"
fi
# ── 2. Node.js ───────────────────────────────────────────────
info "Проверяю Node.js..."
if ! command -v node &>/dev/null; then
info "Устанавливаю Node.js (нужен sudo)..."
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
sudo apt-get install -y nodejs
fi
success "Node.js $(node --version)"
# ── 3. Claude Code ───────────────────────────────────────────
info "Проверяю Claude Code..."
if ! command -v claude &>/dev/null; then
info "Устанавливаю Claude Code..."
# Пробуем официальный инсталлер
if curl -fsSL https://claude.ai/install.sh | bash 2>/dev/null; then
success "Claude Code установлен (официальный инсталлер)"
else
# Fallback: npm в наш prefix (без sudo)
npm install -g @anthropic-ai/claude-code
success "Claude Code установлен (npm)"
fi
else
success "Claude Code уже установлен: $(claude --version 2>/dev/null | head -1)"
fi
# ── 4. claude-code-proxy (GPT) ───────────────────────────────
mkdir -p "$HOME/.local/bin"
install_proxy() {
info "Устанавливаю claude-code-proxy..."
ARCH=$(uname -m)
case "$ARCH" in
x86_64) ARCH_TAG="amd64" ;;
aarch64) ARCH_TAG="arm64" ;;
*) err "Неизвестная архитектура: $ARCH" ;;
esac
LATEST=$(curl -fsSL "https://api.github.com/repos/raine/claude-code-proxy/releases/latest" \
| grep '"tag_name"' | sed 's/.*"tag_name": *"\(.*\)".*/\1/')
[ -z "$LATEST" ] && err "Не удалось получить версию claude-code-proxy с GitHub"
TMP=$(mktemp -d)
trap "rm -rf $TMP" EXIT
URL="https://github.com/raine/claude-code-proxy/releases/download/${LATEST}/claude-code-proxy-linux-${ARCH_TAG}.tar.gz"
info "Скачиваю $URL"
curl -fsSL "$URL" -o "$TMP/proxy.tar.gz" || err "Не удалось скачать claude-code-proxy"
tar -xzf "$TMP/proxy.tar.gz" -C "$TMP"
BINARY=$(find "$TMP" -name "claude-code-proxy" -type f | head -1)
[ -z "$BINARY" ] && err "Бинарник не найден в архиве"
cp "$BINARY" "$PROXY_BIN"
chmod +x "$PROXY_BIN"
success "claude-code-proxy $LATEST -> $PROXY_BIN"
}
if [ -f "$PROXY_BIN" ]; then
CURRENT_VER=$("$PROXY_BIN" --version 2>/dev/null | head -1 || echo "unknown")
success "claude-code-proxy уже установлен ($CURRENT_VER)"
else
install_proxy
fi
# ── 5. antigravity-claude-proxy (Gemini) ────────────────────
info "Проверяю antigravity-claude-proxy..."
if command -v antigravity-claude-proxy &>/dev/null || command -v acc &>/dev/null; then
success "antigravity-claude-proxy уже установлен"
else
info "Устанавливаю antigravity-claude-proxy (npm, без sudo)..."
npm install -g antigravity-claude-proxy@latest
success "antigravity-claude-proxy установлен"
fi
# ── 6. Папка для конфигов ────────────────────────────────────
mkdir -p "$CONFIG_DIR"
# ── 7. Функции в .bashrc ─────────────────────────────────────
info "Прописываю функции запуска в $BASHRC..."
MARKER="# === CLAUDE LAUNCHER ==="
if grep -q "$MARKER" "$BASHRC" 2>/dev/null; then
warn "Блок уже есть в $BASHRC — обновляю..."
python3 - "$BASHRC" <<'PYEOF'
import sys
path = sys.argv[1]
with open(path, 'r') as f:
content = f.read()
marker = '# === CLAUDE LAUNCHER ==='
end_marker = '# === END CLAUDE LAUNCHER ==='
start = content.find(marker)
end = content.find(end_marker)
if start != -1 and end != -1:
new_content = content[:start] + content[end + len(end_marker):].lstrip('\n')
with open(path, 'w') as f:
f.write(new_content)
PYEOF
fi
cat >> "$BASHRC" << 'BASHEOF'
# === CLAUDE LAUNCHER ===
# ── claude_anthropic ──────────────────────────────────────────
claude_anthropic() {
unset ANTHROPIC_BASE_URL ANTHROPIC_AUTH_TOKEN ANTHROPIC_MODEL
unset ANTHROPIC_DEFAULT_OPUS_MODEL ANTHROPIC_DEFAULT_SONNET_MODEL
unset ANTHROPIC_DEFAULT_HAIKU_MODEL CLAUDE_CODE_SUBAGENT_MODEL
unset CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC
claude "$@"
}
# ── claude_gpt ────────────────────────────────────────────────
claude_gpt() {
local proxy_bin="$HOME/.local/bin/claude-code-proxy"
if [ ! -f "$proxy_bin" ]; then
echo "Ошибка: claude-code-proxy не найден. Перезапустите claude_setup.sh"
return 1
fi
# Проверяем авторизацию
if ! "$proxy_bin" codex auth status &>/dev/null; then
echo ""
echo "Авторизация ChatGPT не найдена."
echo "Сейчас появится ссылка или откроется браузер..."
echo ""
if ! "$proxy_bin" codex auth login 2>&1; then
echo ""
echo "Если браузер не открылся, попробуйте device flow:"
echo " claude-code-proxy codex auth device"
return 1
fi
fi
# Запускаем прокси в фоне (если ещё не запущен)
local proxy_pid=""
if ! pgrep -f "claude-code-proxy serve" &>/dev/null; then
"$proxy_bin" serve &>/tmp/claude-code-proxy.log &
proxy_pid=$!
sleep 1
fi
ANTHROPIC_BASE_URL=http://localhost:18765 \
ANTHROPIC_AUTH_TOKEN=dummy \
ANTHROPIC_MODEL=gpt-5.5 \
ANTHROPIC_DEFAULT_OPUS_MODEL=gpt-5.5 \
ANTHROPIC_DEFAULT_SONNET_MODEL=gpt-5.5 \
ANTHROPIC_DEFAULT_HAIKU_MODEL=gpt-5.4-mini \
CLAUDE_CODE_SUBAGENT_MODEL=gpt-5.4-mini \
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 \
claude "$@"
if [ -n "$proxy_pid" ]; then
kill "$proxy_pid" 2>/dev/null
wait "$proxy_pid" 2>/dev/null
fi
}
# ── claude_deepseek ───────────────────────────────────────────
claude_deepseek() {
local key_file="$HOME/.config/claude-launcher/deepseek_key"
local api_key=""
if [ -f "$key_file" ]; then
api_key=$(cat "$key_file")
fi
if [ -z "$api_key" ]; then
echo ""
echo "DeepSeek API ключ не найден."
echo "Получить ключ: https://platform.deepseek.com/api_keys"
echo ""
read -r -p "Введите ваш DeepSeek API ключ: " api_key
echo ""
if [ -z "$api_key" ]; then
echo "Ключ не введён. Выход."
return 1
fi
echo "Проверяю ключ..."
local http_code
http_code=$(curl -sf -o /dev/null -w "%{http_code}" \
https://api.deepseek.com/anthropic/v1/models \
-H "x-api-key: $api_key" 2>/dev/null || echo "000")
if [ "$http_code" = "200" ]; then
mkdir -p "$(dirname "$key_file")"
echo "$api_key" > "$key_file"
chmod 600 "$key_file"
echo "Ключ сохранён. В следующий раз вводить не нужно."
elif [ "$http_code" = "000" ]; then
echo "Не удалось проверить ключ (нет сети?). Сохраняю без проверки..."
mkdir -p "$(dirname "$key_file")"
echo "$api_key" > "$key_file"
chmod 600 "$key_file"
else
echo "Ключ недействителен (HTTP $http_code). Ключ не сохранён."
return 1
fi
fi
ANTHROPIC_BASE_URL=https://api.deepseek.com/anthropic \
ANTHROPIC_AUTH_TOKEN="$api_key" \
ANTHROPIC_MODEL=deepseek-chat \
ANTHROPIC_DEFAULT_OPUS_MODEL=deepseek-chat \
ANTHROPIC_DEFAULT_SONNET_MODEL=deepseek-chat \
ANTHROPIC_DEFAULT_HAIKU_MODEL=deepseek-chat \
CLAUDE_CODE_SUBAGENT_MODEL=deepseek-chat \
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 \
claude "$@"
}
# ── claude_gemini ─────────────────────────────────────────────
claude_gemini() {
local acc_cmd=""
command -v antigravity-claude-proxy &>/dev/null && acc_cmd="antigravity-claude-proxy"
command -v acc &>/dev/null && acc_cmd="acc"
if [ -z "$acc_cmd" ]; then
echo "Ошибка: antigravity-claude-proxy не найден. Перезапустите claude_setup.sh"
return 1
fi
# Запускаем прокси в фоне если не запущен
local proxy_pid=""
if ! curl -sf http://localhost:8080/health &>/dev/null; then
"$acc_cmd" start &>/tmp/antigravity-proxy.log &
proxy_pid=$!
echo "Запускаю Gemini прокси..."
local i=0
while [ $i -lt 15 ]; do
sleep 1
curl -sf http://localhost:8080/health &>/dev/null && break
i=$((i+1))
done
fi
# Проверяем наличие аккаунта
local acc_count
acc_count=$(curl -sf "http://localhost:8080/v1/models" 2>/dev/null | \
python3 -c "import sys,json; d=json.load(sys.stdin); print(len(d.get('data',[],'')))" 2>/dev/null || echo "0")
local has_auth
has_auth=$(curl -sf "http://localhost:8080/account-limits" 2>/dev/null || echo "")
if [ -z "$has_auth" ] || echo "$has_auth" | grep -qE '"accounts":\s*\[\]'; then
echo ""
echo "Google-аккаунт не найден."
echo ""
echo -e "\033[1;33m⚠ ВНИМАНИЕ: Используйте ОТДЕЛЬНЫЙ Google-аккаунт!\033[0m"
echo " Google может заблокировать аккаунты, использующие этот прокси."
echo ""
echo "Открываю http://localhost:8080 в браузере..."
echo "Перейдите: Accounts → Add Account → войдите через Google."
echo ""
# Открываем браузер
xdg-open "http://localhost:8080" 2>/dev/null || \
sensible-browser "http://localhost:8080" 2>/dev/null || \
echo "Откройте вручную: http://localhost:8080"
echo "Нажмите Enter после завершения авторизации в браузере..."
read -r
fi
echo "Запускаю Claude Code с Gemini..."
ANTHROPIC_BASE_URL=http://localhost:8080 \
ANTHROPIC_AUTH_TOKEN=dummy \
ANTHROPIC_MODEL=gemini-3.1-pro-high \
ANTHROPIC_DEFAULT_OPUS_MODEL=gemini-3.1-pro-high \
ANTHROPIC_DEFAULT_SONNET_MODEL=gemini-3.1-pro-low \
ANTHROPIC_DEFAULT_HAIKU_MODEL=gemini-3-flash \
CLAUDE_CODE_SUBAGENT_MODEL=gemini-3-flash \
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 \
claude "$@"
if [ -n "$proxy_pid" ]; then
kill "$proxy_pid" 2>/dev/null
wait "$proxy_pid" 2>/dev/null
fi
}
# === END CLAUDE LAUNCHER ===
BASHEOF
success "Функции добавлены в $BASHRC"
# ── 8. Итог ──────────────────────────────────────────────────
echo ""
echo -e "${GREEN}════════════════════════════════════════════════════${NC}"
echo -e "${GREEN} Установка завершена!${NC}"
echo -e "${GREEN}════════════════════════════════════════════════════${NC}"
echo ""
echo "Примените изменения:"
echo ""
echo -e " ${CYAN}source ~/.bashrc${NC}"
echo ""
echo "Доступные команды:"
echo -e " ${CYAN}claude_anthropic${NC} — оригинальный Claude (Anthropic API)"
echo -e " ${CYAN}claude_gpt${NC} — GPT-5.5 (ChatGPT Plus/Pro, браузерная авторизация)"
echo -e " ${CYAN}claude_deepseek${NC} — DeepSeek (API ключ сохраняется)"
echo -e " ${CYAN}claude_gemini${NC} — Gemini (Google OAuth через браузер)"
echo ""
echo "Все команды принимают стандартные флаги:"
echo -e " ${CYAN}claude_gpt --dangerously-skip-permissions${NC}"
echo ""
echo -e "${YELLOW}⚠️ Для Gemini используйте отдельный Google-аккаунт!${NC}"
echo ""
echo "Управление:"
echo -e " DeepSeek ключ: ${CYAN}rm $DEEPSEEK_KEY_FILE${NC} (сбросить)"
echo -e " GPT статус: ${CYAN}claude-code-proxy codex auth status${NC}"
echo -e " GPT выйти: ${CYAN}claude-code-proxy codex auth logout${NC}"
echo -e " Gemini WebUI: ${CYAN}http://localhost:8080${NC} (когда прокси запущен)"
echo ""