#!/usr/bin/env bash # uninstall.sh — Stop Prefex and restore Claude Code settings # # Usage: # curl -fsSL https://prefex.vercel.app/uninstall.sh | bash # bash uninstall.sh # keep ~/.prefex data # bash uninstall.sh --purge # also remove ~/.prefex directory # # All install-state logic (PID stop, settings.json restore) is delegated to # `prefex uninstall`; this script handles the only thing the binary can't do # itself: remove its own executable. set -euo pipefail INSTALL_DIR="${HOME}/.prefex" PURGE=false for arg in "$@"; do [ "$arg" = "--purge" ] && PURGE=true; done if [ -t 1 ]; then BOLD="\033[1m"; GREEN="\033[0;32m"; YELLOW="\033[0;33m"; RESET="\033[0m" else BOLD=""; GREEN=""; YELLOW=""; RESET="" fi info() { printf "${GREEN}==>${RESET} %s\n" "$*"; } warn() { printf "${YELLOW}warn:${RESET} %s\n" "$*" >&2; } printf "\n${BOLD}Prefex — uninstall${RESET}\n\n" # ── Delegate lifecycle to the binary ───────────────────────────────────────── # `prefex uninstall` stops the daemon, restores ~/.claude/settings.json, and # optionally deletes ~/.prefex. The binary's exit code is non-fatal here so # the rest of the script (binary removal) still runs even if prefex isn't found. PREFEX_BIN="" for candidate in /usr/local/bin/prefex "${HOME}/bin/prefex"; do if [ -x "$candidate" ]; then PREFEX_BIN="$candidate" break fi done if [ -n "$PREFEX_BIN" ]; then UNINSTALL_FLAGS="" [ "$PURGE" = "true" ] && UNINSTALL_FLAGS="--purge" info "Running: prefex uninstall ${UNINSTALL_FLAGS}…" "$PREFEX_BIN" uninstall ${UNINSTALL_FLAGS} || true else warn "prefex binary not found — attempting manual cleanup." # Fallback: restore settings.json directly if binary is gone. BACKUP="${INSTALL_DIR}/backup_claude_code.json" SETTINGS="${HOME}/.claude/settings.json" if [ -f "$BACKUP" ] && command -v python3 &>/dev/null; then cp "$BACKUP" "$SETTINGS" && rm -f "$BACKUP" info "Restored ${SETTINGS} from backup." elif [ -f "$SETTINGS" ] && command -v python3 &>/dev/null; then python3 - "$SETTINGS" <<'PY' import json, sys path = sys.argv[1] try: cfg = json.loads(open(path).read()) cfg.setdefault('env', {})['ANTHROPIC_BASE_URL'] = 'https://api.anthropic.com' open(path, 'w').write(json.dumps(cfg, indent=2)) print("==> Reset ANTHROPIC_BASE_URL to https://api.anthropic.com") except Exception as e: print(f"warn: {e}", file=sys.stderr) PY fi # Stop by PID file if still running. PID_FILE="${INSTALL_DIR}/prefex.pid" if [ -f "$PID_FILE" ]; then PID=$(cat "$PID_FILE") kill "$PID" 2>/dev/null && info "Stopped PID $PID" || true rm -f "$PID_FILE" fi fi # ── Remove the binary (can't self-delete) ──────────────────────────────────── for bin_path in /usr/local/bin/prefex "${HOME}/bin/prefex"; do if [ -f "$bin_path" ]; then rm -f "$bin_path" && info "Removed ${bin_path}" fi done # Remove license key — tied to install; fresh one generated on reinstall. [ -f "${INSTALL_DIR}/license.json" ] && rm -f "${INSTALL_DIR}/license.json" \ && info "Removed license key." printf "\n${BOLD}Prefex uninstalled.${RESET}\n" printf "Claude Code will route directly to https://api.anthropic.com\n\n"