Загрузка данных
#!/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."