# Universal macOS background auto-updater script for the Cursor AI editor. Automates updates daily at 10:00 AM using Homebrew and launchd without losing custom multi-profile settings, account data, or…

> Source: <https://gist.github.com/jimilchoksi/e21c23e16f08f59dbe1f13f2af701d60>
> Published: 2026-09-29 06:55:03+00:00

|  | #!/bin/bash | 
|  | USER_HOME="$HOME" | 
|  | USER_NAME=$(whoami) | 
|  | SCRIPT_DIR="$USER_HOME/Scripts" | 
|  | SCRIPT_PATH="$SCRIPT_DIR/auto_update_cursor.sh" | 
|  | PLIST_PATH="$USER_HOME/Library/LaunchAgents/com.user.autoupdatecursor.plist" | 
|  | LOG_PATH="$USER_HOME/Library/Logs/cursor_update.log" | 
|  | install_updater() { | 
|  | echo "" | 
|  | echo "=== Setting up Universal Cursor Auto-Updater ===" | 
|  | # 1. Ensure Homebrew is installed | 
|  | if ! command -v brew &> /dev/null && [ ! -f /opt/homebrew/bin/brew ] && [ ! -f /usr/local/bin/brew ]; then | 
|  | echo "❌ Error: Homebrew is not installed on this Mac. Please install Homebrew first." | 
|  | return 1 | 
|  | fi | 
|  | # 2. Check if manual copy of Cursor exists and link to Homebrew | 
|  | echo "Checking Cursor installation status..." | 
|  | if [ -d "/Applications/Cursor.app" ]; then | 
|  | echo "Cursor found in Applications. Linking Homebrew to manage it..." | 
|  | /opt/homebrew/bin/brew install --cask --force cursor \|\| /usr/local/bin/brew install --cask --force cursor | 
|  | else | 
|  | echo "Installing Cursor via Homebrew..." | 
|  | /opt/homebrew/bin/brew install --cask cursor \|\| /usr/local/bin/brew install --cask cursor | 
|  | fi | 
|  | # 3. Create directories and local automation runner script | 
|  | mkdir -p "$SCRIPT_DIR" | 
|  | echo "Generating update script at $SCRIPT_PATH..." | 
|  | cat << 'INNER_EOF' > "$SCRIPT_PATH" | 
|  | #!/bin/bash | 
|  | export PATH="/opt/homebrew/bin:/usr/local/bin:$PATH" | 
|  | echo "--- Cursor Update Check: $(date) ---" | 
|  | brew update 2>&1 | 
|  | brew upgrade --cask cursor 2>&1 | 
|  | echo "------------------------------------------------" | 
|  | INNER_EOF | 
|  | chmod +x "$SCRIPT_PATH" | 
|  | # 4. Clean up old background agent iterations if they exist | 
|  | if launchctl list \| grep -q "com.user.autoupdatecursor"; then | 
|  | launchctl unload "$PLIST_PATH" 2>/dev/null | 
|  | fi | 
|  | # 5. Generate background launch agent configuration plist | 
|  | echo "Generating configuration agent file..." | 
|  | cat << INNER_EOF > "$PLIST_PATH" | 
|  | <?xml version="1.0" encoding="UTF-8"?> | 
|  | <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://apple.com"> | 
|  | <plist version="1.0"> | 
|  | <dict> | 
|  | <key>Label</key> | 
|  | <string>com.user.autoupdatecursor</string> | 
|  | <key>ProgramArguments</key> | 
|  | <array> | 
|  | <string>/bin/bash</string> | 
|  | <string>$SCRIPT_PATH</string> | 
|  | </array> | 
|  | <key>StartCalendarInterval</key> | 
|  | <dict> | 
|  | <key>Hour</key> | 
|  | <integer>10</integer> | 
|  | <key>Minute</key> | 
|  | <integer>0</integer> | 
|  | </dict> | 
|  | <key>RunAtLoad</key> | 
|  | <true/> | 
|  | <key>StandardOutPath</key> | 
|  | <string>$LOG_PATH</string> | 
|  | <key>StandardErrorPath</key> | 
|  | <string>$LOG_PATH</string> | 
|  | </dict> | 
|  | </plist> | 
|  | INNER_EOF | 
|  | # 6. Load and start the updater agent | 
|  | echo "Activating automatic updates in the background..." | 
|  | launchctl load "$PLIST_PATH" | 
|  | launchctl kickstart -k gui/$(id -u)/com.user.autoupdatecursor | 
|  | echo "✅ Success! Cursor will now update quietly every day at 10:00 AM." | 
|  | echo "Logs are available at: ~/Library/Logs/cursor_update.log" | 
|  | } | 
|  | disable_updater() { | 
|  | echo "" | 
|  | echo "=== Disabling Background Updates ===" | 
|  | if [ -f "$PLIST_PATH" ]; then | 
|  | launchctl unload "$PLIST_PATH" 2>/dev/null | 
|  | echo "⏸️ Background agent paused. Auto-updates will stop running until re-enabled." | 
|  | else | 
|  | echo "⚠️ No active update scheduler configuration found to disable." | 
|  | fi | 
|  | } | 
|  | delete_updater() { | 
|  | echo "" | 
|  | echo "=== Uninstalling Cursor Auto-Updater system ===" | 
|  | # Stop background agent process cleanly | 
|  | if [ -f "$PLIST_PATH" ]; then | 
|  | launchctl unload "$PLIST_PATH" 2>/dev/null | 
|  | rm -f "$PLIST_PATH" | 
|  | echo "🗑️ Removed LaunchAgent scheduler configuration file." | 
|  | fi | 
|  | # Remove the underlying runner execution script | 
|  | if [ -f "$SCRIPT_PATH" ]; then | 
|  | rm -f "$SCRIPT_PATH" | 
|  | echo "🗑️ Removed local update execution script file." | 
|  | fi | 
|  | # Remove generated local log files | 
|  | if [ -f "$LOG_PATH" ]; then | 
|  | rm -f "$LOG_PATH" | 
|  | echo "🗑️ Removed tracker automation update log files." | 
|  | fi | 
|  | echo "✅ Complete cleanup finished. The auto-updater has been completely removed." | 
|  | } | 
|  | # --- Interactive Terminal Choice Menu Interface --- | 
|  | echo "=============================================" | 
|  | echo " Cursor macOS Auto-Update Manager " | 
|  | echo "=============================================" | 
|  | echo "Logged in user: $USER_NAME" | 
|  | echo "" | 
|  | echo "Select an action to perform:" | 
|  | echo "1) Enable / Install (Setup automated daily check)" | 
|  | echo "2) Disable / Pause (Keep files, stop background runs)" | 
|  | echo "3) Delete / Remove (Completely wipe out all script files)" | 
|  | echo "4) Exit" | 
|  | echo "----------------------------------------------" | 
|  | read -p "Enter choice [1-4]: " choice | 
|  | case $choice in | 
|  | 1) install_updater ;; | 
|  | 2) disable_updater ;; | 
|  | 3) delete_updater ;; | 
|  | 4) echo "Exiting application."; exit 0 ;; | 
|  | *) echo "❌ Invalid input item choice. Exiting script execution."; exit 1 ;; | 
|  | esac |
