#!/usr/bin/env bash set -euo pipefail # Çağrıldığı dizini kaydet — Claude Code burada açılacak ORIG_DIR="$PWD" SCRIPT_DIR="$(dirname "$(readlink -f "$0")")" # ────────────────────────────────────────────── # optoant LLM Gateway → Claude Code Launcher # ────────────────────────────────────────────── # Usage: ./cc.sh [claude-args...] # ./cc.sh # Claude'u gateway'e bağlı başlatır # ./cc.sh --print # Sadece env'leri göster, Claude'u başlatma # ./cc.sh --restart # Gateway'i yeniden başlat (Air kill + up) # ./cc.sh --logs # Gateway loglarını canlı izle (tail -f) # ANTHROPIC_BASE_URL="http://localhost:8000/anthropic" ./cc.sh # ────────────────────────────────────────────── # Gateway ve .env için script'in kendi dizinine geç cd "$SCRIPT_DIR" GATEWAY_PORT="${PORT:-8000}" GATEWAY_URL="http://localhost:${GATEWAY_PORT}" ANTHROPIC_ENDPOINT="${ANTHROPIC_BASE_URL:-${GATEWAY_URL}/anthropic}" # ── .env'yi yükle (varsa) ── if [[ -f .env ]]; then set -a source .env set +a fi # ── Air ile gateway çalışıyor mu? ── check_gateway() { if curl -sf "${GATEWAY_URL}/health" > /dev/null 2>&1; then return 0 fi return 1 } # ── Gateway'i Air ile başlat ── start_gateway() { echo "🚀 Gateway başlatılıyor (air)..." air > /tmp/optoant-air.log 2>&1 & AIR_PID=$! echo " Air PID: $AIR_PID | Log: /tmp/optoant-air.log" echo -n " Health check bekleniyor" for i in $(seq 1 15); do if check_gateway; then echo " OK" echo " 💡 Logları canlı izlemek için: tail -f /tmp/optoant-air.log" return 0 fi echo -n "." sleep 1 done echo " TIMEOUT" echo "❌ Gateway başlatılamadı. Son log satırları:" tail -20 /tmp/optoant-air.log return 1 } # ── Sadece env'leri göster ── print_env() { echo "┌─ optoant → Claude Code Environment" echo "│ ANTHROPIC_BASE_URL=${ANTHROPIC_ENDPOINT}" echo "│ ANTHROPIC_API_KEY=${OPENAI_KEY:0:20}... (masked)" echo "│ OPENAI_BACKEND=${OPENAI_BACKEND:-http://10.80.80.70:8080}" echo "│ OPENAI_MODEL=${OPENAI_MODEL:-deepseek/deepseek-v4-pro}" echo "│ Gateway: ${GATEWAY_URL}/health" echo "└─" } # ── Ana mantık ── case "${1:-}" in --print|-p) print_env exit 0 ;; --restart|-r) echo "♻️ Gateway yeniden başlatılıyor..." pkill -f "air" 2>/dev/null || true pkill -f "tmp/main" 2>/dev/null || true sleep 2 start_gateway print_env echo "✅ Gateway hazır. ./cc.sh ile Claude'u başlat." exit 0 ;; --logs|-l) echo "📋 Gateway logları (tail -f /tmp/optoant-air.log):" echo "──────────────────────────────────────────────" tail -f /tmp/optoant-air.log exit 0 ;; --help|-h) sed -n '2,10p' "$0" exit 0 ;; esac # ── Gateway kontrol et, yoksa başlat ── if ! check_gateway; then echo "⚠️ Gateway çalışmıyor." start_gateway fi print_env # ── Claude Code'u başlat ── echo "┌─ Claude Code başlatılıyor..." echo "│ Not: Streaming desteklenmiyor. ~/.claude/settings.json'a" echo '│ "stream": false eklendi.' echo "│ Çıkmak için: exit veya Ctrl+C" echo "└─" echo "" if [[ $EUID -eq 0 ]]; then # ── Root: non-root kullanıcı oluştur, projeyi kopyala, su ile başlat ── CLAUD_USER="optoant-claude" if ! id "$CLAUD_USER" &>/dev/null; then echo "👤 Non-root kullanıcı oluşturuluyor: $CLAUD_USER" useradd -m -s /bin/bash "$CLAUD_USER" if [[ -d /root/.claude ]]; then cp -r /root/.claude "/home/${CLAUD_USER}/" chown -R "${CLAUD_USER}:${CLAUD_USER}" "/home/${CLAUD_USER}/.claude" fi fi echo "👤 Claude Code '$CLAUD_USER' kullanıcısı ile başlatılıyor..." CLAUD_HOME="/home/${CLAUD_USER}" CLAUD_PROJECT="${CLAUD_HOME}/opantoantro" if [[ ! -d "${CLAUD_PROJECT}" ]]; then echo "📁 Proje kopyalanıyor: ${CLAUD_PROJECT}" cp -r /root/opantoantro "${CLAUD_PROJECT}" chown -R "${CLAUD_USER}:${CLAUD_USER}" "${CLAUD_PROJECT}" fi CLAUD_BIN="/usr/local/bin/claude" if [[ ! -x "$CLAUD_BIN" ]]; then SRC=$(find /root/.nvm -name "claude" -o -name "claude.exe" -type f 2>/dev/null | head -1) if [[ -z "$SRC" ]]; then echo "❌ claude binary bulunamadı. Önce: npm install -g @anthropic-ai/claude-code" exit 1 fi cp "$SRC" "$CLAUD_BIN" chmod 755 "$CLAUD_BIN" echo "📦 Claude Code kopyalandı: ${CLAUD_BIN}" fi CLAUD_RUNNER="/tmp/cc-run-${CLAUD_USER}.sh" cat > "$CLAUD_RUNNER" <<- WRAPPER #!/usr/bin/env bash cd "${ORIG_DIR}" 2>/dev/null || cd "${CLAUD_PROJECT}" export ANTHROPIC_BASE_URL="${ANTHROPIC_ENDPOINT}" export ANTHROPIC_API_KEY="${ANTHROPIC_API_KEY:-${OPENAI_KEY:-}}" exec "${CLAUD_BIN}" "\$@" WRAPPER chmod +x "$CLAUD_RUNNER" SAFE_ARGS="" for arg in "$@"; do SAFE_ARGS="${SAFE_ARGS} $(printf '%q' "$arg")" done su - "${CLAUD_USER}" -c "${CLAUD_RUNNER}${SAFE_ARGS}" rm -f "$CLAUD_RUNNER" else # ── Non-root: doğrudan başlat ── cd "$ORIG_DIR" ANTHROPIC_BASE_URL="${ANTHROPIC_ENDPOINT}" \ ANTHROPIC_API_KEY="${ANTHROPIC_API_KEY:-${OPENAI_KEY:-}}" \ claude "$@" fi