Загрузка данных


#!/usr/bin/env bash
set -euo pipefail

API_KEY="${1:-${CODEX_LB_API_KEY:-${OPENAI_API_KEY:-}}}"
BASE_URL="https://codex.sale"
CODEX_DIR="${HOME}/.codex"
AUTH_PATH="${CODEX_DIR}/auth.json"
CONFIG_PATH="${CODEX_DIR}/config.toml"
ENV_PATH="${CODEX_DIR}/codex-sale.env"
VSCODE_SERVER_ENV_PATH="${HOME}/.vscode-server/server-env-setup"
BACKUP_DIR="${CODEX_DIR}/backups/codex-sale-$(date +%Y%m%d-%H%M%S)-$$"

write_file() {
  local path="$1"
  local mode="$2"

  mkdir -p "$(dirname "$path")"
  sed 's/^        //' > "$path"
  chmod "$mode" "$path"
}

write_env_file() {
  local path="$1"
  local mode="${2:-600}"

  write_file "$path" "$mode" <<EOF
export CODEX_LB_API_KEY="$API_KEY"
export OPENAI_API_KEY="$API_KEY"
EOF
}

patch_vscode_codex_binaries() {
  local patched_count=0
  local codex_path=""
  local backup_path=""
  local root=""

  while IFS= read -r codex_path; do
    [[ -n "$codex_path" ]] || continue

    backup_path="${codex_path}.codex-sale-real"

    if [[ -f "$backup_path" ]]; then
      write_file "$codex_path" 700 <<EOF
#!/usr/bin/env bash
set -euo pipefail
source "$ENV_PATH"
exec "$backup_path" "\$@"
EOF
      patched_count=$((patched_count + 1))
      echo "Refreshed VS Code Codex wrapper: $codex_path"
      continue
    fi

    mv "$codex_path" "$backup_path"
    write_file "$codex_path" 700 <<EOF
#!/usr/bin/env bash
set -euo pipefail
source "$ENV_PATH"
exec "$backup_path" "\$@"
EOF
    patched_count=$((patched_count + 1))
    echo "Patched VS Code Codex launcher: $codex_path"
  done < <(
    for root in "$HOME/.vscode/extensions" "$HOME/.vscode-server/extensions" "$HOME/.vscode-insiders/extensions" "$HOME/.vscode-server-insiders/extensions"; do
      [[ -d "$root" ]] || continue
      find "$root" -type f -path '*/openai.chatgpt-*/bin/*/codex' 2>/dev/null
    done | sort -u
  )

  if [[ "$patched_count" -eq 0 ]]; then
    echo "No VS Code OpenAI/Codex extension binary found to patch."
    echo "Install/open the Codex extension in VS Code first, then rerun this script."
  fi
}

stop_codex_processes() {
  local codex_pids

  codex_pids="$(
    ps -u "$(id -u)" -o pid=,args= |
      awk '/openai[.]chatgpt-.*\/bin\/.*\/codex app-server/ { print $1 }'
  )"

  if [[ -z "$codex_pids" ]]; then
    echo "Codex VS Code app-server was not running."
    return 0
  fi

  echo "Stopping Codex VS Code app-server: $codex_pids"
  kill $codex_pids 2>/dev/null || true

  for _ in 1 2 3 4 5; do
    sleep 1
    codex_pids="$(
      ps -u "$(id -u)" -o pid=,args= |
        awk '/openai[.]chatgpt-.*\/bin\/.*\/codex app-server/ { print $1 }'
    )"
    [[ -z "$codex_pids" ]] && break
  done

  if [[ -n "$codex_pids" ]]; then
    echo "Codex app-server is still running, forcing stop: $codex_pids"
    kill -9 $codex_pids 2>/dev/null || true
  fi
}

restart_vscode_server() {
  local server_pids
  local extension_host_pids

  stop_codex_processes

  extension_host_pids="$(
    ps -u "$(id -u)" -o pid=,args= |
      awk '/[.]vscode-server\/cli\/servers\/.*\/server\/out\/bootstrap-fork --type=extensionHost/ { print $1 }'
  )"

  if [[ -n "$extension_host_pids" ]]; then
    echo "Stopping VS Code extension host: $extension_host_pids"
    kill $extension_host_pids 2>/dev/null || true
  fi

  server_pids="$(
    ps -u "$(id -u)" -o pid=,args= |
      awk '/[.]vscode-server\/cli\/servers\/.*\/server\/out\/server-main[.]js/ { print $1 }'
  )"

  if [[ -z "$server_pids" ]]; then
    echo "VS Code Server was not running."
    return 0
  fi

  echo "Restarting VS Code Server so CODEX_LB_API_KEY is loaded: $server_pids"
  kill $server_pids 2>/dev/null || true
}

if [ -z "$API_KEY" ]; then
  echo "Usage: bash <(curl -fsSL https://codex.sale/i) <api-key>" >&2
  exit 1
fi

BASE_URL="${BASE_URL%/}"

mkdir -p "$CODEX_DIR" "$BACKUP_DIR"

if [[ -f "$AUTH_PATH" ]]; then
  cp "$AUTH_PATH" "$BACKUP_DIR/auth.json"
fi

if [[ -f "$CONFIG_PATH" ]]; then
  cp "$CONFIG_PATH" "$BACKUP_DIR/config.toml"
fi

if [[ -f "$ENV_PATH" ]]; then
  cp "$ENV_PATH" "$BACKUP_DIR/codex-sale.env"
fi

if [[ -f "$VSCODE_SERVER_ENV_PATH" ]]; then
  cp "$VSCODE_SERVER_ENV_PATH" "$BACKUP_DIR/vscode-server-env-setup"
fi

umask 077

write_env_file "$ENV_PATH" 600
write_env_file "$VSCODE_SERVER_ENV_PATH" 700

cat > "$AUTH_PATH" <<EOF
{
  "auth_mode": "apikey",
  "OPENAI_API_KEY": "$API_KEY"
}
EOF

cat > "$CONFIG_PATH" <<EOF
model = "gpt-5.6-luna"
model_reasoning_effort = "high"
model_provider = "codex-sale"

[model_providers.codex-sale]
name = "Codex Sale"
base_url = "$BASE_URL/v1"
wire_api = "responses"
env_key = "CODEX_LB_API_KEY"
supports_websockets = false
requires_openai_auth = true
EOF

chmod 600 "$AUTH_PATH" "$CONFIG_PATH" "$ENV_PATH"
patch_vscode_codex_binaries

printf '\n'
echo "Codex VS Code config updated."
echo "Auth:     $AUTH_PATH"
echo "Config:   $CONFIG_PATH"
echo "Env:      $ENV_PATH"
echo "VS Code: $VSCODE_SERVER_ENV_PATH"
echo "Endpoint: $BASE_URL/v1"
echo "Backup:   $BACKUP_DIR"
printf '\n'
restart_vscode_server
printf '\n'
echo "Reconnect/reload VS Code if the window disconnects."