#!/usr/bin/env bash # Qwen Code — Updater # Re-installs latest version from registry + re-applies patches. # Uses wrapper script so env vars work immediately in any shell. # # Usage: sudo bash uqwen_update.sh set -euo pipefail GITEA_TOKEN="${GITEA_TOKEN:-cadffcb0a6a3be728ac1ff619bb40c86588f6837}" REGISTRY_URL="https://npm.sensey24.ru/" NPM_SCOPE="@qwen-code" NPM_PACKAGE="@qwen-code/qwen-code" REPO_RAW="https://git.sensey24.ru/aibot777/unlimitedcoding/raw/branch/master/qwen" PRIVATE_CONFIG_BASE="https://git.sensey24.ru/aibot777/unlimitedcoding-config/raw/branch/main" OS="$(uname -s)" IS_MACOS=false [ "$OS" = "Darwin" ] && IS_MACOS=true if $IS_MACOS; then ENV_FILE="/etc/qwen-code-env.sh" else ENV_FILE="/etc/profile.d/qwen-code.sh" fi sedi() { if $IS_MACOS; then sed -i '' "$@" else sed -i "$@" fi } GREEN="\033[92m" CYAN="\033[96m" YELLOW="\033[93m" RED="\033[91m" BOLD="\033[1m" RESET="\033[0m" log() { echo -e "${GREEN}[+]${RESET} $*"; } info() { echo -e "${CYAN}[i]${RESET} $*"; } warn() { echo -e "${YELLOW}[~]${RESET} $*"; } err() { echo -e "${RED}[!]${RESET} $*" >&2; } create_wrapper() { local bin_name="$1" local bin_path bin_path=$(command -v "$bin_name" 2>/dev/null || echo "/usr/local/bin/$bin_name") local npm_root npm_root=$(npm root -g 2>/dev/null || echo "/usr/lib/node_modules") local real_bin real_bin=$(readlink -f "$bin_path" 2>/dev/null || true) if [ -z "$real_bin" ] || [ "$real_bin" = "$bin_path" ] || [ ! -f "$real_bin" ]; then for candidate_pkg in "@qwen-code/qwen-code" "qwen-code"; do for entry in "dist/index.js" "bin/index.js" "index.js"; do if [ -f "$npm_root/$candidate_pkg/$entry" ]; then real_bin="$npm_root/$candidate_pkg/$entry" break 2 fi done done fi if [ -z "$real_bin" ] || [ ! -f "$real_bin" ]; then warn "Could not find $bin_name entry point" return 1 fi rm -f "$bin_path" cat > "$bin_path" << WEOF #!/usr/bin/env bash [ -f $ENV_FILE ] && . $ENV_FILE exec node "$real_bin" "\$@" WEOF chmod +x "$bin_path" log "Wrapper: $bin_path -> $real_bin" } echo -e "${BOLD}" echo " +--------------------------------------+" echo " | Qwen Code — Updater |" echo " +--------------------------------------+" echo -e "${RESET}" # ---- Check current version ---- OLD_VER="" QWEN_BIN="" for candidate in qwen qwen-code; do if command -v "$candidate" &>/dev/null; then QWEN_BIN="$candidate" break fi done if [ -n "$QWEN_BIN" ]; then OLD_VER=$($QWEN_BIN --version 2>/dev/null || echo "unknown") info "Current: $QWEN_BIN $OLD_VER" else warn "Qwen Code not found. Will install fresh." fi # ---- Configure npm registry ---- info "Configuring npm registry: ${REGISTRY_URL}" npm config set "${NPM_SCOPE}:registry" "${REGISTRY_URL}" 2>/dev/null || true # ---- Update package ---- info "Installing latest ${NPM_PACKAGE}..." if npm install -g "${NPM_PACKAGE}" 2>&1; then log "Package updated" else err "npm install failed. Try: npm config set ${NPM_SCOPE}:registry http://npm.sensey24.ru/" exit 1 fi # Find binary after update for candidate in qwen qwen-code; do if command -v "$candidate" &>/dev/null; then QWEN_BIN="$candidate" break fi done # ---- Download and apply patches ---- TEMP_DIR=$(mktemp -d) cleanup() { rm -rf "$TEMP_DIR" 2>/dev/null || true; } trap cleanup EXIT info "Downloading patcher..." curl -fsSL -H "Authorization: token ${GITEA_TOKEN}" "$REPO_RAW/qwen_patcher.py" -o "$TEMP_DIR/qwen_patcher.py" curl -fsSL -H "Authorization: token ${GITEA_TOKEN}" "$PRIVATE_CONFIG_BASE/qwen_config.json" -o "$TEMP_DIR/qwen_config.json" info "Applying patches..." python3 "$TEMP_DIR/qwen_patcher.py" --settings-only --config "$TEMP_DIR/qwen_config.json" PATCH_EXIT=$? if [ $PATCH_EXIT -ne 0 ]; then warn "Settings-only patch returned $PATCH_EXIT, trying full patch..." python3 "$TEMP_DIR/qwen_patcher.py" --apply --config "$TEMP_DIR/qwen_config.json" fi # ---- Set env vars system-wide ---- API_KEY=$(python3 -c "import json; print(json.load(open('$TEMP_DIR/qwen_config.json'))['api_key'])") BASE_URL=$(python3 -c "import json; print(json.load(open('$TEMP_DIR/qwen_config.json'))['base_url'])") if $IS_MACOS; then launchctl setenv QWEN_API_KEY "$API_KEY" 2>/dev/null || true launchctl setenv QWEN_BASE_URL "$BASE_URL" 2>/dev/null || true cat > "$ENV_FILE" << ENVEOF export QWEN_API_KEY="$API_KEY" export QWEN_BASE_URL="$BASE_URL" ENVEOF chmod 644 "$ENV_FILE" REAL_HOME="$HOME" if [ -n "${SUDO_USER:-}" ] && [ "$SUDO_USER" != "root" ]; then REAL_HOME=$(eval echo "~$SUDO_USER") fi for rc_file in "$REAL_HOME/.zshrc" "$REAL_HOME/.bashrc"; do if [ -f "$rc_file" ] || [ "$rc_file" = "$REAL_HOME/.zshrc" ]; then if [ -f "$rc_file" ]; then sedi '/# Qwen env/d' "$rc_file" sedi '/qwen-code-env\.sh/d' "$rc_file" fi echo "[ -f $ENV_FILE ] && . $ENV_FILE # Qwen env" >> "$rc_file" fi done else ETC_ENV="/etc/environment" for kv in "QWEN_API_KEY=\"$API_KEY\"" "QWEN_BASE_URL=\"$BASE_URL\""; do KEY="${kv%%=*}" if grep -q "^${KEY}=" "$ETC_ENV" 2>/dev/null; then sedi "s|^${KEY}=.*|${kv}|" "$ETC_ENV" else echo "$kv" >> "$ETC_ENV" fi done mkdir -p /etc/profile.d cat > "$ENV_FILE" << PROF_EOF export QWEN_API_KEY="$API_KEY" export QWEN_BASE_URL="$BASE_URL" PROF_EOF chmod 644 "$ENV_FILE" fi # ---- Create wrapper (auto-loads env) ---- if [ -n "$QWEN_BIN" ]; then create_wrapper "$QWEN_BIN" fi NEW_VER=$($QWEN_BIN --version 2>/dev/null || echo "unknown") log "Version: $OLD_VER -> $NEW_VER" log "Update complete!" echo -e "Qwen works immediately — no need to source anything." echo ""