Skip to content

Instantly share code, notes, and snippets.

@BradKML
Created February 13, 2025 09:13
Show Gist options
  • Save BradKML/b84675c356007c8029ce927c484f4cc6 to your computer and use it in GitHub Desktop.
Save BradKML/b84675c356007c8029ce927c484f4cc6 to your computer and use it in GitHub Desktop.
Draft of an alternative Cursor WSL fixer
#!/bin/bash
# =================================================================
# Cursor WSL Fix Installation Script v1.2
# Combines solutions from @ddwang and @swayducky
# With additional process management and safety features
# =================================================================
# Color codes for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
# Print functions
print_status() { echo -e "${GREEN}[+]${NC} $1"; }
print_error() { echo -e "${RED}[!]${NC} $1"; }
print_warning() { echo -e "${YELLOW}[*]${NC} $1"; }
print_info() { echo -e "${BLUE}[i]${NC} $1"; }
# Define common paths and variables
POWERSHELL="/mnt/c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe"
if [ ! -x "$POWERSHELL" ]; then
POWERSHELL="/mnt/c/WINDOWS/System32/WindowsPowerShell/v1.0/powershell.exe" # Alternative path
fi
# Script version for tracking
SCRIPT_VERSION="1.2"
SCRIPT_DATE="2024-02-13"
# Check if we're in a devcontainer with improved detection
IN_DEVCONTAINER=false
if [ -f /.dockerenv ] || [ -f /run/.containerenv ] || [ -d /home/devcontainers ] || \
[ -n "$REMOTE_CONTAINERS" ] || [ -n "$CODESPACES" ] || [ -n "$DEVCONTAINER" ]; then
IN_DEVCONTAINER=true
fi
# Verify WSL environment
verify_wsl() {
if ! grep -qi microsoft /proc/version && ! grep -qi wsl /proc/version; then
print_error "This script must be run in WSL"
return 1
fi
return 0
}
# Verify root privileges
verify_root() {
if [ "$EUID" -ne 0 ]; then
print_error "Please run this script with sudo"
return 1
fi
return 0
}
# Function to run PowerShell commands safely with improved error handling
run_powershell() {
local cmd="$1"
local error_msg="${2:-PowerShell command failed}"
if [ ! -x "$POWERSHELL" ]; then
print_error "PowerShell not found at expected locations"
return 1
fi
local output
if ! output=$("$POWERSHELL" -Command "$cmd" 2>&1); then
print_error "$error_msg: $output"
return 1
fi
echo "$output"
return 0
}
# Get current non-root user with validation
get_real_user() {
local real_user
if [ -n "$SUDO_USER" ]; then
real_user="$SUDO_USER"
else
real_user=$(whoami)
fi
# Verify user exists and is not root
if ! id "$real_user" >/dev/null 2>&1 || [ "$real_user" = "root" ]; then
print_error "Could not determine valid non-root user"
return 1
fi
echo "$real_user"
return 0
}
# Get Windows username with improved detection and validation
get_windows_user() {
local win_user
local system_dirs=("All Users" "Default" "Default User" "Public" "desktop.ini" "Administrator")
local cursor_found=false
print_info "Detecting Windows username..."
# Method 1: Direct CMD query with verification
win_user=$(cmd.exe /c "echo %USERNAME%" 2>/dev/null | tr -d '\r\n')
if [ -n "$win_user" ] && [ -d "/mnt/c/Users/${win_user}" ] && \
[ -d "/mnt/c/Users/${win_user}/AppData/Local/Programs/cursor" ]; then
print_info "Found Cursor installation for user: $win_user (Method 1)"
echo "$win_user"
return 0
fi
# Method 2: Search Users directory for Cursor installation
print_info "Searching for Cursor installation in user directories..."
for user_dir in /mnt/c/Users/*; do
local dirname=$(basename "$user_dir")
# Skip system directories
local is_system_dir=false
for sys_dir in "${system_dirs[@]}"; do
if [ "$dirname" = "$sys_dir" ]; then
is_system_dir=true
break
fi
done
if [ "$is_system_dir" = true ]; then
continue
fi
# Check for Cursor installation
if [ -d "$user_dir/AppData/Local/Programs/cursor" ]; then
print_info "Found Cursor installation for user: $dirname (Method 2)"
cursor_found=true
win_user="$dirname"
break
fi
done
if [ "$cursor_found" = true ]; then
echo "$win_user"
return 0
fi
# If we get here, we couldn't find the installation
print_error "Could not find Cursor installation in any user directory"
print_info "Checked directories in /mnt/c/Users/:"
for user_dir in /mnt/c/Users/*; do
local dirname=$(basename "$user_dir")
local is_system_dir=false
for sys_dir in "${system_dirs[@]}"; do
if [ "$dirname" = "$sys_dir" ]; then
is_system_dir=true
break
fi
done
if [ "$is_system_dir" = false ]; then
print_info " - $dirname"
fi
done
return 1
}
# Check dependencies with improved validation
check_dependencies() {
local deps=("wget" "curl")
if [ "$IN_DEVCONTAINER" = true ]; then
deps+=("cron")
else
deps+=("systemctl")
fi
local missing_deps=()
local installed_deps=()
print_info "Checking dependencies..."
# Check PowerShell separately
if ! command -v "/mnt/c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe" >/dev/null 2>&1 && \
! command -v "/mnt/c/WINDOWS/System32/WindowsPowerShell/v1.0/powershell.exe" >/dev/null 2>&1; then
print_error "PowerShell not found in expected Windows locations"
return 1
fi
# Check other dependencies
for dep in "${deps[@]}"; do
if ! command -v "$dep" >/dev/null 2>&1; then
missing_deps+=("$dep")
else
installed_deps+=("$dep")
fi
done
# Report status
if [ ${#installed_deps[@]} -gt 0 ]; then
print_status "Found dependencies: ${installed_deps[*]}"
fi
if [ ${#missing_deps[@]} -ne 0 ]; then
print_warning "Missing dependencies: ${missing_deps[*]}"
print_info "Installing missing dependencies..."
# Update package list if it's older than 1 hour
if [ ! -f "/var/cache/apt/pkgcache.bin" ] || \
[ "$(stat -c %Y /var/cache/apt/pkgcache.bin)" -lt "$(( $(date +%s) - 3600 ))" ]; then
print_info "Updating package list..."
if ! apt-get update; then
print_error "Failed to update package list"
return 1
fi
fi
if ! apt-get install -y "${missing_deps[@]}"; then
print_error "Failed to install dependencies"
return 1
fi
print_status "Successfully installed missing dependencies"
fi
# Verify cron service in devcontainer
if [ "$IN_DEVCONTAINER" = true ]; then
print_info "Checking cron service..."
if ! service cron status >/dev/null 2>&1; then
print_warning "Cron service is not running"
if ! service cron start; then
print_error "Failed to start cron service"
return 1
fi
print_status "Successfully started cron service"
fi
fi
return 0
}
# Check and handle running Cursor instances with improved process management
check_cursor_process() {
print_info "Checking for running Cursor instances..."
# Try to find Cursor process in Windows
local cursor_running
local check_attempts=0
local max_attempts=3
while [ $check_attempts -lt $max_attempts ]; do
if ! cursor_running=$(run_powershell "Get-Process cursor -ErrorAction SilentlyContinue"); then
((check_attempts++))
if [ $check_attempts -eq $max_attempts ]; then
print_warning "Could not check Cursor process status after $max_attempts attempts. Proceeding anyway..."
return 0
fi
sleep 1
continue
fi
break
done
if [ -n "$cursor_running" ]; then
print_warning "Cursor is currently running in Windows"
print_info "Process details:"
run_powershell "Get-Process cursor | Select-Object Id, ProcessName, StartTime, CPU | Format-Table -AutoSize"
# Ask user for action
while true; do
echo -e "${YELLOW}Choose an action:${NC}"
echo "1) Automatically close Cursor"
echo "2) I'll close it manually (wait)"
echo "3) Abort installation"
read -p "Enter choice [1-3]: " choice
case $choice in
1)
print_info "Attempting to close Cursor..."
if run_powershell "Stop-Process -Name cursor -Force -ErrorAction SilentlyContinue"; then
print_status "Successfully closed Cursor"
# Wait a moment to ensure process is fully terminated
sleep 2
# Double-check if it's really closed
if [ -n "$(run_powershell "Get-Process cursor -ErrorAction SilentlyContinue")" ]; then
print_error "Failed to close Cursor completely. Please close it manually"
continue
fi
else
print_error "Failed to close Cursor automatically"
continue
fi
break
;;
2)
print_info "Waiting for you to close Cursor..."
local wait_dots=0
while [ -n "$(run_powershell "Get-Process cursor -ErrorAction SilentlyContinue")" ]; do
echo -n "."
((wait_dots++))
if [ $wait_dots -eq 60 ]; then
echo ""
print_warning "Still waiting for Cursor to close..."
wait_dots=0
fi
sleep 1
done
echo ""
print_status "Cursor has been closed"
break
;;
3)
print_error "Installation aborted by user"
exit 1
;;
*)
print_error "Invalid choice. Please enter 1, 2, or 3"
;;
esac
done
else
print_status "No running Cursor instances found"
fi
}
# Verify Cursor is closed with improved checking
verify_cursor_closed() {
local max_attempts=5
local attempt=1
local check_interval=2
print_info "Verifying Cursor is fully closed..."
while [ $attempt -le $max_attempts ]; do
local process_check
if ! process_check=$(run_powershell "Get-Process cursor -ErrorAction SilentlyContinue"); then
print_warning "Process check failed on attempt $attempt"
sleep $check_interval
((attempt++))
continue
fi
if [ -z "$process_check" ]; then
print_status "Verified Cursor is not running"
return 0
fi
print_warning "Attempt $attempt of $max_attempts: Cursor is still running..."
if [ $attempt -eq $max_attempts ]; then
print_error "Could not verify Cursor is closed after $max_attempts attempts"
return 1
fi
sleep $check_interval
((attempt++))
done
return 1
}
# Verify Cursor installation with improved checks
verify_cursor_installation() {
local win_user=$1
local cursor_path="/mnt/c/Users/${win_user}/AppData/Local/Programs/cursor"
local bin_path="${cursor_path}/resources/app/bin"
print_info "Verifying Cursor installation..."
# Check main installation directory
if [ ! -d "$cursor_path" ]; then
print_error "Cursor installation not found at $cursor_path"
print_info "Please ensure Cursor is installed in Windows first"
return 1
fi
# Check bin directory
if [ ! -d "$bin_path" ]; then
print_error "Cursor bin directory not found at $bin_path"
print_info "Your Cursor installation might be corrupted"
return 1
}
# Check for existing cursor script
if [ -f "${bin_path}/cursor" ]; then
print_status "Found existing cursor script"
# Verify file permissions
if [ ! -x "${bin_path}/cursor" ]; then
print_warning "Existing cursor script is not executable"
fi
else
print_info "No existing cursor script found - will create new one"
fi
print_status "Cursor installation verified successfully"
return 0
}
# Create the fix-cursor script with improved error handling and logging
create_fix_script() {
local win_user=$1
local script_path="/usr/local/sbin/fix-cursor"
local temp_script="${script_path}.tmp"
print_info "Creating fix-cursor script..."
# Create script in a temporary file first
cat > "$temp_script" << EOF
#!/bin/bash
# Configuration
CURSOR_BIN_PATH="/mnt/c/Users/${win_user}/AppData/Local/Programs/cursor/resources/app/bin"
SCRIPT_URL="https://gist.githubusercontent.com/swayducky/8ba8f2db156c7f445d562cdc12c0ddb4/raw/cursor"
BACKUP_SUFFIX=\$(date +%Y%m%d_%H%M%S)
BACKUP_DIR="\${HOME}/.cursor-backups"
LOG_DIR="\${HOME}/.cursor-fix/logs"
LAST_RUN_FILE="\${HOME}/.cursor-fix/last_run"
SCRIPT_VERSION="$SCRIPT_VERSION"
# Create necessary directories
mkdir -p "\${BACKUP_DIR}" "\${LOG_DIR}" "\$(dirname \${LAST_RUN_FILE})"
# Logging function with timestamps and log rotation
log() {
local max_log_size=5242880 # 5MB
local log_file="\${LOG_DIR}/cursor-fix.log"
local message="\$(date '+%Y-%m-%d %H:%M:%S') \$1"
# Rotate log if needed
if [ -f "\$log_file" ] && [ \$(stat -f%z "\$log_file" 2>/dev/null || stat -c%s "\$log_file") -gt \$max_log_size ]; then
mv "\$log_file" "\${log_file}.\${BACKUP_SUFFIX}"
gzip "\${log_file}.\${BACKUP_SUFFIX}"
fi
echo "\$message" >> "\$log_file"
echo "\$1"
}
# Error handling function with cleanup
handle_error() {
log "ERROR: \$1"
# Attempt to restore from backup if available
if [ -n "\$CURRENT_BACKUP" ] && [ -f "\$CURRENT_BACKUP" ]; then
log "Attempting to restore from backup \$CURRENT_BACKUP"
if cp "\$CURRENT_BACKUP" "\${CURSOR_BIN_PATH}/cursor"; then
log "Successfully restored from backup"
else
log "Failed to restore from backup"
fi
fi
exit 1
}
# Check if we're in a devcontainer
IN_DEVCONTAINER=false
if [ -f /.dockerenv ] || [ -f /run/.containerenv ] || [ -d /home/devcontainers ] || \
[ -n "\$REMOTE_CONTAINERS" ] || [ -n "\$CODESPACES" ] || [ -n "\$DEVCONTAINER" ]; then
IN_DEVCONTAINER=true
fi
# Check if Cursor is running (with devcontainer handling)
check_cursor_running() {
if [ "\$IN_DEVCONTAINER" = true ]; then
log "Running in devcontainer - skipping process check"
return 0
fi
POWERSHELL="/mnt/c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe"
if [ ! -x "\$POWERSHELL" ]; then
POWERSHELL="/mnt/c/WINDOWS/System32/WindowsPowerShell/v1.0/powershell.exe"
fi
if [ ! -x "\$POWERSHELL" ]; then
log "WARNING: PowerShell not accessible - skipping process check"
return 0
fi
local max_attempts=3
local attempt=1
while [ \$attempt -le \$max_attempts ]; do
if [ -n "\$(\$POWERSHELL -Command "Get-Process cursor -ErrorAction SilentlyContinue")" ]; then
log "ERROR: Cursor is currently running. Please close it before running the fix"
return 1
fi
((attempt++))
sleep 1
done
return 0
}
# Process check with devcontainer handling
if [ "\$IN_DEVCONTAINER" = false ]; then
if ! check_cursor_running; then
handle_error "Please close Cursor before running the fix"
fi
fi
# Check if cursor binary directory exists
if [ ! -d "\${CURSOR_BIN_PATH}" ]; then
handle_error "Cursor installation not found at \${CURSOR_BIN_PATH}"
fi
# Backup existing cursor script
CURRENT_BACKUP=""
if [ -f "\${CURSOR_BIN_PATH}/cursor" ]; then
CURRENT_BACKUP="\${BACKUP_DIR}/cursor_\${BACKUP_SUFFIX}"
if ! cp "\${CURSOR_BIN_PATH}/cursor" "\$CURRENT_BACKUP"; then
handle_error "Failed to create backup"
fi
log "Created backup at \$CURRENT_BACKUP"
fi
# Download and install new script with verification
log "Downloading new cursor script..."
TEMP_SCRIPT="\${CURSOR_BIN_PATH}/cursor.tmp"
DOWNLOAD_SUCCESS=false
# Try wget first
if wget -q --spider "\$SCRIPT_URL" 2>/dev/null; then
if wget -O "\$TEMP_SCRIPT" "\$SCRIPT_URL" 2>/dev/null; then
DOWNLOAD_SUCCESS=true
fi
fi
# Try curl if wget fails
if [ "\$DOWNLOAD_SUCCESS" = false ]; then
if curl -s -f -I "\$SCRIPT_URL" >/dev/null; then
if curl -s "\$SCRIPT_URL" -o "\$TEMP_SCRIPT"; then
DOWNLOAD_SUCCESS=true
fi
fi
fi
if [ "\$DOWNLOAD_SUCCESS" = false ]; then
handle_error "Failed to download new cursor script"
fi
# Verify downloaded script
if [ ! -s "\$TEMP_SCRIPT" ]; then
handle_error "Downloaded script is empty"
fi
# Install new script
mv "\$TEMP_SCRIPT" "\${CURSOR_BIN_PATH}/cursor" || handle_error "Failed to install new script"
chmod +x "\${CURSOR_BIN_PATH}/cursor" || handle_error "Failed to set permissions"
# Clean up old server installations with backup
if [ -d "\${HOME}/.cursor-server" ]; then
local server_backup="\${HOME}/.cursor-server_\${BACKUP_SUFFIX}"
if ! mv "\${HOME}/.cursor-server" "\$server_backup"; then
log "Warning: Failed to backup old server installation"
else
log "Backed up old server installation to \$server_backup"
# Optional: Compress the backup
if command -v tar >/dev/null 2>&1; then
tar czf "\${server_backup}.tar.gz" "\$server_backup" && rm -rf "\$server_backup"
log "Compressed server backup to \${server_backup}.tar.gz"
fi
fi
fi
# Update last run timestamp and version
echo "\$(date '+%Y-%m-%d %H:%M:%S')" > "\$LAST_RUN_FILE"
echo "\$SCRIPT_VERSION" >> "\$LAST_RUN_FILE"
log "Successfully updated cursor script (version \$SCRIPT_VERSION)"
EOF
# Make the temporary script executable
chmod +x "$temp_script" || return 1
# Move the temporary script to the final location
mv "$temp_script" "$script_path" || return 1
print_status "Successfully created fix-cursor script"
return 0
}
# Setup cron job with improved error handling and verification
setup_cron_job() {
local real_user=$1
print_info "Setting up cron job for daily fixes..."
# Check if cron service is running
if ! service cron status >/dev/null 2>&1; then
print_warning "Cron service is not running"
if ! service cron start; then
print_error "Failed to start cron service"
return 1
fi
print_status "Started cron service"
fi
# Create a temporary file for the new crontab
local temp_cron=$(mktemp)
# Get existing crontab
su - "$real_user" -c "crontab -l" > "$temp_cron" 2>/dev/null || echo "" > "$temp_cron"
# Remove any existing cursor fix entries
sed -i '/fix-cursor/d' "$temp_cron"
# Add new job with random minute to avoid system load spikes
local random_minute=$((RANDOM % 60))
echo "$random_minute 4 * * * /usr/local/sbin/fix-cursor" >> "$temp_cron"
# Install new crontab
if ! su - "$real_user" -c "crontab $temp_cron"; then
rm -f "$temp_cron"
print_error "Failed to install crontab"
return 1
fi
# Cleanup
rm -f "$temp_cron"
# Verify installation
if ! su - "$real_user" -c "crontab -l" | grep -q "fix-cursor"; then
print_error "Failed to verify cron job installation"
return 1
fi
print_status "Cron job successfully configured to run daily at 4:$random_minute AM"
return 0
}
# Create systemd service files with improved configuration and validation
create_systemd_services() {
local real_user=$1
local user_home=$(eval echo ~${real_user})
local systemd_dir="${user_home}/.config/systemd/user"
print_info "Creating systemd service files..."
# Create systemd directory with proper permissions
mkdir -p "$systemd_dir"
chmod 700 "$systemd_dir"
# Create service file with improved configuration
cat > "${systemd_dir}/cursor-fix.service" << 'EOFSERVICE'
[Unit]
Description=Cursor WSL Fix Monitor
After=network-online.target
Wants=network-online.target
StartLimitIntervalSec=300
StartLimitBurst=3
[Service]
Type=oneshot
ExecStart=/usr/local/sbin/fix-cursor
StandardOutput=append:/home/%u/.cursor-fix/logs/service.log
StandardError=append:/home/%u/.cursor-fix/logs/service.log
Restart=on-failure
RestartSec=30s
Environment="DISPLAY=:0"
# Security hardening
NoNewPrivileges=yes
ProtectSystem=full
ProtectHome=read-only
PrivateTmp=yes
[Install]
WantedBy=default.target
EOFSERVICE
# Create timer file with randomized start time
cat > "${systemd_dir}/cursor-fix.timer" << 'EOFTIMER'
[Unit]
Description=Check Cursor WSL Fix Daily
After=network-online.target
Wants=network-online.target
[Timer]
OnBootSec=5min
OnUnitActiveSec=1d
RandomizedDelaySec=1800
Persistent=true
AccuracySec=1s
[Install]
WantedBy=timers.target
EOFTIMER
# Fix permissions
chown -R ${real_user}:${real_user} "${user_home}/.config/systemd"
# Verify service files
if [ ! -f "${systemd_dir}/cursor-fix.service" ] || [ ! -f "${systemd_dir}/cursor-fix.timer" ]; then
print_error "Failed to create systemd service files"
return 1
fi
print_status "Successfully created systemd service files"
return 0
}
# Add alias and environment setup to shell configuration with improved handling
add_shell_alias() {
local real_user=$1
local user_home=$(eval echo ~${real_user})
local shell_rc
local config_block="
# Cursor WSL Fix Configuration
alias fix-cursor='/usr/local/sbin/fix-cursor'
export DONT_PROMPT_WSL_INSTALL=1
# Cursor WSL Fix Path
if [ -d /usr/local/sbin ]; then
export PATH=\$PATH:/usr/local/sbin
fi
# Cursor WSL Fix Version
export CURSOR_FIX_VERSION=\"$SCRIPT_VERSION\"
"
print_info "Setting up shell configuration..."
# Determine shell configuration file
if [ -f "${user_home}/.zshrc" ]; then
shell_rc="${user_home}/.zshrc"
print_info "Using ZSH configuration"
else
shell_rc="${user_home}/.bashrc"
print_info "Using Bash configuration"
fi
# Create backup of shell configuration
if [ -f "$shell_rc" ]; then
cp "$shell_rc" "${shell_rc}.backup-$(date +%Y%m%d_%H%M%S)"
print_info "Created backup of shell configuration"
fi
# Remove any existing Cursor WSL Fix configuration
if grep -q "Cursor WSL Fix Configuration" "$shell_rc"; then
print_info "Removing existing Cursor configuration..."
sed -i '/# Cursor WSL Fix Configuration/,/# End Cursor WSL Fix Configuration/d' "$shell_rc"
fi
# Add new configuration block
echo -e "$config_block" >> "$shell_rc"
# Fix permissions
chown ${real_user}:${real_user} "$shell_rc"
chmod 644 "$shell_rc"
print_status "Successfully updated shell configuration"
return 0
}
# Enable systemd service for user with improved error handling and verification
enable_systemd_service() {
local real_user=$1
if [ "$IN_DEVCONTAINER" = true ]; then
print_warning "Running in devcontainer environment - skipping systemd service setup"
return 0
fi
print_info "Enabling systemd services..."
# Reload systemd daemon
if ! su - ${real_user} -c "systemctl --user daemon-reload"; then
print_warning "Failed to reload systemd daemon - attempting to continue"
fi
# Enable and start timer
local systemd_commands=(
"systemctl --user enable cursor-fix.timer"
"systemctl --user start cursor-fix.timer"
"systemctl --user enable cursor-fix.service"
)
for cmd in "${systemd_commands[@]}"; do
print_info "Running: $cmd"
if ! su - ${real_user} -c "$cmd"; then
print_error "Failed to execute: $cmd"
return 1
fi
done
# Verify service status
if ! su - ${real_user} -c "systemctl --user status cursor-fix.timer" >/dev/null 2>&1; then
print_error "Failed to verify timer status"
return 1
fi
print_status "Successfully enabled systemd services"
return 0
}
# Main installation process with improved flow and error handling
main() {
trap cleanup ERR
local start_time=$(date +%s)
print_status "Starting Cursor WSL Fix installation (version $SCRIPT_VERSION)..."
# Get real user first
local real_user
if ! real_user=$(get_real_user); then
print_error "Failed to determine real user"
exit 1
fi
# Initial environment checks
if ! verify_wsl || ! verify_root; then
exit 1
fi
# Check for devcontainer environment
if [ "$IN_DEVCONTAINER" = true ]; then
print_warning "======================================================"
print_warning "Running in a devcontainer environment"
print_warning "Some features will be limited:"
print_warning "- Systemd services will not be available"
print_warning "- Using cron job for automated fixes"
print_warning "- Some Windows process checks might be restricted"
print_warning "======================================================"
sleep 2
fi
# Check dependencies
if ! check_dependencies; then
print_error "Failed to verify dependencies"
exit 1
fi
# Get Windows username
local win_user
if ! win_user=$(get_windows_user); then
print_error "Failed to detect Windows username"
exit 1
fi
print_status "Detected Windows username: $win_user"
# Verify Cursor installation
if ! verify_cursor_installation "$win_user"; then
exit 1
fi
# Process checking
if [ "$IN_DEVCONTAINER" = true ]; then
print_warning "Process checking might be limited in devcontainer environment"
print_info "Please ensure Cursor is closed manually before proceeding"
read -p "Press Enter to continue after closing Cursor..."
else
check_cursor_process
if ! verify_cursor_closed; then
print_error "Could not ensure Cursor is closed. Please close it manually and try again"
exit 1
fi
fi
print_status "Proceeding with installation..."
# Create directories
local user_home=$(eval echo ~${real_user})
mkdir -p "${user_home}/.cursor-fix/logs" "${user_home}/.cursor-fix/backup"
chown -R ${real_user}:${real_user} "${user_home}/.cursor-fix"
# Backup current cursor script
if [ -f "/usr/local/sbin/fix-cursor" ]; then
cp "/usr/local/sbin/fix-cursor" "${user_home}/.cursor-fix/backup/cursor.backup-$(date +%Y%m%d_%H%M%S)"
fi
# Installation steps
print_status "Creating fix-cursor script..."
if ! create_fix_script "$win_user"; then
print_error "Failed to create fix-cursor script"
exit 1
fi
if [ "$IN_DEVCONTAINER" = true ]; then
print_info "Setting up cron job for automated fixes..."
if ! setup_cron_job "$real_user"; then
print_warning "Failed to set up cron job - manual runs will be required"
fi
else
print_status "Creating systemd service files..."
if ! create_systemd_services "$real_user"; then
print_error "Failed to create systemd services"
exit 1
fi
fi
print_status "Adding shell configuration..."
if ! add_shell_alias "$real_user"; then
print_error "Failed to update shell configuration"
exit 1
fi
if [ "$IN_DEVCONTAINER" = false ]; then
print_status "Enabling systemd service..."
if ! enable_systemd_service "$real_user"; then
print_error "Failed to enable systemd service"
exit 1
fi
fi
# Final process check before applying fix
print_status "Running initial fix..."
if [ "$IN_DEVCONTAINER" = true ]; then
print_warning "Running fix in devcontainer environment - some features might be limited"
su - "$real_user" -c "/usr/local/sbin/fix-cursor"
else
if ! cursor_status=$(run_powershell "Get-Process cursor -ErrorAction SilentlyContinue"); then
print_warning "Could not check Cursor process status. Proceeding anyway..."
elif [ -n "$cursor_status" ]; then
print_error "Cursor was reopened during installation. Please close it and run 'fix-cursor' manually"
print_warning "Other components have been installed successfully"
exit 1
else
su - "$real_user" -c "/usr/local/sbin/fix-cursor"
fi
fi
# Calculate installation time
local end_time=$(date +%s)
local duration=$((end_time - start_time))
print_status "Installation complete! (Duration: ${duration}s)"
print_info "Logs are available in ~/.cursor-fix/logs/"
if [ "$IN_DEVCONTAINER" = true ]; then
print_warning "================================================================"
print_warning "Devcontainer Installation Notes:"
print_warning "1. The fix-cursor command is available but must be run manually"
print_warning "2. A cron job has been set up for daily fixes"
print_warning "3. Some Windows process checks may be limited"
print_warning "4. Please test the fix manually by running: fix-cursor"
print_warning "================================================================"
else
print_warning "Please restart your terminal or run: source ~/.bashrc (or ~/.zshrc)"
print_warning "The fix will be automatically applied daily and after system boot"
# Display service status
print_info "Checking service status..."
su - "$real_user" -c "systemctl --user status cursor-fix.timer"
fi
}
# Run main installation
main
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment