From 209c58e3f83b7af4eeb1dff3ca7ec6188fb8931f Mon Sep 17 00:00:00 2001 From: BasaiCorp Date: Fri, 21 Mar 2025 20:37:12 +0530 Subject: [PATCH 1/5] Update totally_reset_cursor.py with new locations and test v0.1 --- totally_reset_cursor.py | 562 ++++++---------------------------------- 1 file changed, 81 insertions(+), 481 deletions(-) diff --git a/totally_reset_cursor.py b/totally_reset_cursor.py index 5711cf6..b32b050 100644 --- a/totally_reset_cursor.py +++ b/totally_reset_cursor.py @@ -2,508 +2,108 @@ import os import shutil import platform import time -import sys -import glob -import json -import uuid -import random -import string -import re -from datetime import datetime -import subprocess -from colorama import Fore, Style, init -from main import translator -from main import EMOJI -# Initialize colorama -init() - -# Define emoji and color constants -EMOJI = { - "FILE": "šŸ“„", - "BACKUP": "šŸ’¾", - "SUCCESS": "āœ…", - "ERROR": "āŒ", - "INFO": "ā„¹ļø", - "RESET": "šŸ”„", - "MENU": "šŸ“‹", - "ARROW": "āžœ", - "LANG": "🌐", - "UPDATE": "šŸ”„", - "ADMIN": "šŸ”", - "STOP": "šŸ›‘", - "DISCLAIMER": "āš ļø", - "WARNING": "āš ļø" -} - -def display_banner(): - """Displays a stylized banner for the tool.""" - print(f"\n{Fore.CYAN}{'='*50}{Style.RESET_ALL}") - print(f"{Fore.CYAN}{EMOJI['STOP']} {translator.get('totally_reset.title')} {Style.RESET_ALL}") - print(f"{Fore.CYAN}{'='*50}{Style.RESET_ALL}") - -def display_features(): - """Displays the features of the Cursor AI Reset Tool.""" - print(f"\n{Fore.CYAN}{EMOJI['MENU']} {translator.get('totally_reset.feature_title')}{Style.RESET_ALL}") - print(f"{Fore.CYAN}{EMOJI['INFO']} {translator.get('totally_reset.feature_1')} {Style.RESET_ALL}") - print(f"{Fore.CYAN}{EMOJI['INFO']} {translator.get('totally_reset.feature_2')} {Style.RESET_ALL}") - print(f"{Fore.CYAN}{EMOJI['INFO']} {translator.get('totally_reset.feature_3')} {Style.RESET_ALL}") - print(f"{Fore.CYAN}{EMOJI['INFO']} {translator.get('totally_reset.feature_4')} {Style.RESET_ALL}") - print(f"{Fore.CYAN}{EMOJI['INFO']} {translator.get('totally_reset.feature_5')} {Style.RESET_ALL}") - print(f"{Fore.CYAN}{EMOJI['INFO']} {translator.get('totally_reset.feature_6')} {Style.RESET_ALL}") - print(f"{Fore.CYAN}{EMOJI['INFO']} {translator.get('totally_reset.feature_7')} {Style.RESET_ALL}") - print(f"{Fore.CYAN}{EMOJI['INFO']} {translator.get('totally_reset.feature_8')} {Style.RESET_ALL}") - print(f"{Fore.CYAN}{EMOJI['INFO']} {translator.get('totally_reset.feature_9')} {Style.RESET_ALL}\n") - -def display_disclaimer(): - """Displays a disclaimer for the user.""" - print(f"\n{Fore.RED}{EMOJI['DISCLAIMER']} {translator.get('totally_reset.disclaimer_title')}{Style.RESET_ALL}") - print(f"{Fore.RED}{EMOJI['INFO']} {translator.get('totally_reset.disclaimer_1')} {Style.RESET_ALL}") - print(f"{Fore.RED}{EMOJI['INFO']} {translator.get('totally_reset.disclaimer_2')} {Style.RESET_ALL}") - print(f"{Fore.RED}{EMOJI['INFO']} {translator.get('totally_reset.disclaimer_3')} {Style.RESET_ALL}") - print(f"{Fore.RED}{EMOJI['INFO']} {translator.get('totally_reset.disclaimer_4')} {Style.RESET_ALL}") - print(f"{Fore.RED}{EMOJI['INFO']} {translator.get('totally_reset.disclaimer_5')} {Style.RESET_ALL}") - print(f"{Fore.RED}{EMOJI['INFO']} {translator.get('totally_reset.disclaimer_6')} {Style.RESET_ALL}") - print(f"{Fore.RED}{EMOJI['INFO']} {translator.get('totally_reset.disclaimer_7')} {Style.RESET_ALL} \n") - -def get_confirmation(): - """Gets confirmation from the user to proceed.""" - while True: - choice = input(f"{Fore.RED}{EMOJI['WARNING']} {translator.get('totally_reset.confirm_title')} (Y/n): ").strip().lower() - if choice == "y" or choice == "": - return True - elif choice == "n": - return False - else: - print(f"{EMOJI['ERROR']} {translator.get('totally_reset.invalid_choice')}") - -def remove_dir(path): - """Removes a directory if it exists and logs the action.""" - # Safety check to ensure we're only deleting Cursor-related directories - if not is_cursor_related(path): - print(f"{Fore.RED}{EMOJI['WARNING']} {translator.get('totally_reset.skipped_for_safety', path=path)} {Style.RESET_ALL}") - return - +def delete_directory(path): + """Deletes a directory and all its contents.""" if os.path.exists(path): try: - shutil.rmtree(path, ignore_errors=True) - print(f"{Fore.GREEN}{EMOJI['SUCCESS']} {translator.get('totally_reset.deleted', path=path)} {Style.RESET_ALL}") + shutil.rmtree(path) + print(f"āœ… Removed: {path}") except Exception as e: - print(f"{Fore.RED}{EMOJI['ERROR']} {translator.get('totally_reset.error_deleting', path=path, error=str(e))} {Style.RESET_ALL}") + print(f"āŒ Failed to remove: {path} -> {e}") else: - print(f"{Fore.RED}{EMOJI['INFO']} {translator.get('totally_reset.not_found', path=path)} {Style.RESET_ALL}") + print(f"šŸ” Not found: {path}") -def remove_file(path): - """Removes a file if it exists and logs the action.""" - # Safety check to ensure we're only deleting Cursor-related files - if not is_cursor_related(path): - print(f"{Fore.RED}{EMOJI['WARNING']} {translator.get('totally_reset.skipped_for_safety', path=path)} {Style.RESET_ALL}") - return - +def delete_file(path): + """Deletes a file if it exists.""" if os.path.isfile(path): try: os.remove(path) - print(f"{Fore.GREEN}{EMOJI['SUCCESS']} {translator.get('totally_reset.deleted', path=path)} {Style.RESET_ALL}") + print(f"āœ… Removed file: {path}") except Exception as e: - print(f"{Fore.RED}{EMOJI['ERROR']} {translator.get('totally_reset.error_deleting', path=path, error=str(e))} {Style.RESET_ALL}") + print(f"āŒ Failed to remove file: {path} -> {e}") else: - print(f"{Fore.RED}{EMOJI['INFO']} {translator.get('totally_reset.not_found', path=path)} {Style.RESET_ALL}") - -def is_cursor_related(path): - """ - Safety function to verify a path is related to Cursor before deletion. - Returns True if the path appears to be related to Cursor AI. - """ - # Skip .vscode check as it's shared with VS Code - if path.endswith(".vscode"): - return False - - # Check if path contains cursor-related terms - cursor_terms = ["cursor", "cursorai", "cursor-electron"] - - # Convert path to lowercase for case-insensitive matching - lower_path = path.lower() - - # Return True if any cursor term is present in the path - for term in cursor_terms: - if term in lower_path: - return True - - # Check specific known Cursor file patterns - cursor_patterns = [ - r"\.cursor_.*$", - r"cursor-.*\.json$", - r"cursor_.*\.json$", - r"cursor-machine-id$", - r"trial_info\.json$", - r"license\.json$" - ] - - for pattern in cursor_patterns: - if re.search(pattern, lower_path): - return True - - # If it's a specific file that we know is only for Cursor - if os.path.basename(lower_path) in [ - "cursor_trial_data", - "cursor-state.json", - "cursor-machine-id", - "ai-settings.json", - "cursor.desktop" - ]: - return True - - return False - -def find_cursor_license_files(base_path, pattern): - """Finds files matching a pattern that might contain license information.""" - try: - matches = [] - for root, dirnames, filenames in os.walk(base_path): - for filename in filenames: - # Check if filename matches any pattern before adding to matches - if any(p.lower() in filename.lower() for p in pattern): - full_path = os.path.join(root, filename) - # Extra safety check to ensure it's cursor-related - if is_cursor_related(full_path): - matches.append(full_path) - return matches - except Exception as e: - print(f"{Fore.RED}{EMOJI['INFO']} {translator.get('totally_reset.error_searching', path=base_path, error=str(e))} {Style.RESET_ALL}") - return [] - -def generate_new_machine_id(): - """Generates a new random machine ID.""" - return str(uuid.uuid4()) - -def create_fake_machine_id(path): - """Creates a new machine ID file with random ID.""" - if not is_cursor_related(path): - return - - try: - new_id = generate_new_machine_id() - directory = os.path.dirname(path) - - # Ensure directory exists - if not os.path.exists(directory): - os.makedirs(directory) - - with open(path, 'w') as f: - f.write(new_id) - print(f"{Fore.GREEN}{EMOJI['SUCCESS']} {translator.get('totally_reset.created_machine_id', path=path)} {Style.RESET_ALL}") - except Exception as e: - print(f"{Fore.RED}{EMOJI['ERROR']} {translator.get('totally_reset.error_creating_machine_id', path=path, error=str(e))} {Style.RESET_ALL}") - -def reset_machine_id(system, home): - """Resets machine ID in all possible locations.""" - print(f"\n{Fore.CYAN}{EMOJI['RESET']} {translator.get('totally_reset.resetting_machine_id')} {Style.RESET_ALL}") - - # Common machine ID locations based on OS - if system == "Windows": - machine_id_paths = [ - os.path.join(home, "AppData", "Roaming", "Cursor", "cursor-machine-id"), - os.path.join(home, "AppData", "Local", "Cursor", "cursor-machine-id"), - os.path.join(home, "AppData", "Roaming", "cursor-electron", "cursor-machine-id"), - os.path.join(home, "AppData", "Local", "cursor-electron", "cursor-machine-id"), - os.path.join(home, ".cursor-machine-id"), - ] - elif system == "Darwin": # macOS - machine_id_paths = [ - os.path.join(home, "Library", "Application Support", "Cursor", "cursor-machine-id"), - os.path.join(home, "Library", "Application Support", "cursor-electron", "cursor-machine-id"), - os.path.join(home, ".cursor-machine-id"), - ] - elif system == "Linux": - machine_id_paths = [ - os.path.join(home, ".config", "Cursor", "cursor-machine-id"), - os.path.join(home, ".config", "cursor-electron", "cursor-machine-id"), - os.path.join(home, ".cursor-machine-id"), - ] - - # First remove existing machine IDs - for path in machine_id_paths: - remove_file(path) - - # Then create new randomized IDs - for path in machine_id_paths: - create_fake_machine_id(path) - - # Try to reset system machine ID if possible (with appropriate permissions) - if system == "Windows": - try: - # Windows: Create a temporary VBS script to reset machine GUID - print(f"{Fore.RED}{EMOJI['INFO']} {translator.get('totally_reset.note_complete_machine_id_reset_may_require_running_as_administrator')} {Style.RESET_ALL}") - except Exception as e: - print(f"{Fore.RED}{EMOJI['INFO']} {translator.get('totally_reset.windows_machine_id_modification_skipped', error=str(e))} {Style.RESET_ALL}") - - elif system == "Linux": - try: - # Linux: Create a random machine-id in /etc/ (needs sudo) - print(f"{Fore.RED}{EMOJI['INFO']} {translator.get('totally_reset.note_complete_system_machine_id_reset_may_require_sudo_privileges')} {Style.RESET_ALL}") - except Exception as e: - print(f"{Fore.RED}{EMOJI['INFO']} {translator.get('totally_reset.linux_machine_id_modification_skipped', error=str(e))} {Style.RESET_ALL}") - -def create_fake_trial_info(path, system, home): - """Creates fake trial information to extend trial period.""" - if not is_cursor_related(path): - return - - try: - # Generate future expiry date (90 days from now) - future_date = (datetime.now().timestamp() + (90 * 24 * 60 * 60)) * 1000 # milliseconds - - # Create fake trial info - fake_trial = { - "trialStartTimestamp": datetime.now().timestamp() * 1000, - "trialEndTimestamp": future_date, - "hasUsedTrial": False, - "machineId": generate_new_machine_id() - } - - directory = os.path.dirname(path) - - # Ensure directory exists - if not os.path.exists(directory): - os.makedirs(directory) - - with open(path, 'w') as f: - json.dump(fake_trial, f) - print(f"{Fore.GREEN}{EMOJI['SUCCESS']} {translator.get('totally_reset.created_extended_trial_info', path=path)} {Style.RESET_ALL}") - except Exception as e: - print(f"{Fore.RED}{EMOJI['ERROR']} {translator.get('totally_reset.error_creating_trial_info', path=path, error=str(e))} {Style.RESET_ALL}") + print(f"šŸ” Not found: {path}") def reset_cursor(): - """Completely resets Cursor AI by removing all settings, caches, and extensions.""" - system = platform.system() - home = os.path.expanduser("~") + print("\nšŸš€ Resetting Cursor AI...\n") - display_banner() - display_features() - display_disclaimer() + # Platform-specific paths + paths = [] + if platform.system() == "Linux": + paths = [ + os.path.expanduser("~/.cursor"), + os.path.expanduser("~/.local/share/cursor"), + os.path.expanduser("~/.config/cursor"), + os.path.expanduser("~/.cache/cursor"), + "/usr/local/bin/cursor", + "/opt/cursor", + "/usr/bin/cursor", + os.path.expanduser("~/.cursor/machine-id.db"), + os.path.expanduser("~/.local/share/cursor"), + os.path.expanduser("~/.config/Cursor"), + os.path.expanduser("~/.local/share/Cursor"), + os.path.expanduser("~/.cache/Cursor") + ] - if not get_confirmation(): - print(f"\n{Fore.CYAN}{EMOJI['STOP']} {translator.get('totally_reset.reset_cancelled')} {Style.RESET_ALL}") - return - - print(f"\n{Fore.CYAN}{EMOJI['RESET']} {translator.get('totally_reset.resetting_cursor_ai_editor')} {Style.RESET_ALL}") - - # Define paths based on OS - if system == "Windows": - cursor_paths = [ - os.path.join(home, "AppData", "Roaming", "Cursor"), - os.path.join(home, "AppData", "Local", "Cursor"), - os.path.join(home, "AppData", "Roaming", "cursor-electron"), - os.path.join(home, "AppData", "Local", "cursor-electron"), - os.path.join(home, "AppData", "Local", "CursorAI"), - os.path.join(home, "AppData", "Roaming", "CursorAI"), - # os.path.join(home, ".vscode"), # Removed to avoid affecting VS Code - os.path.join(home, "AppData", "Local", "Temp", "Cursor"), # Temporary data - os.path.join(home, "AppData", "Local", "Temp", "cursor-updater"), - os.path.join(home, "AppData", "Local", "Programs", "cursor"), + elif platform.system() == "Darwin": # macOS + paths = [ + os.path.expanduser("~/Library/Application Support/Cursor"), + os.path.expanduser("~/Library/Caches/Cursor"), + "/Applications/Cursor.app", + os.path.expanduser("~/Library/Preferences/com.cursor.app.plist"), ] - - # Additional locations for license/trial files on Windows - license_search_paths = [ - os.path.join(home, "AppData", "Roaming"), - os.path.join(home, "AppData", "Local"), - os.path.join(home, "AppData", "LocalLow"), + + elif platform.system() == "Windows": + paths = [ + os.path.expanduser("~\\AppData\\Local\\Cursor"), + os.path.expanduser("~\\AppData\\Roaming\\Cursor"), + os.path.expanduser("~\\.cursor"), + os.path.expanduser("~\\.config\\Cursor"), + os.path.expanduser("~\\.cache\\Cursor"), + "C:\\Program Files\\Cursor", + "C:\\Program Files (x86)\\Cursor", + "C:\\Users\\%USERNAME%\\AppData\\Local\\Cursor", + "C:\\Users\\%USERNAME%\\AppData\\Roaming\\Cursor", ] - - # Registry instructions for Windows - print(f"\n{Fore.CYAN}{EMOJI['INFO']} {translator.get('totally_reset.windows_registry_instructions')} {Style.RESET_ALL}") - print(f"{Fore.CYAN}{EMOJI['INFO']} {translator.get('totally_reset.windows_registry_instructions_2')} {Style.RESET_ALL}") - - elif system == "Darwin": # macOS - cursor_paths = [ - os.path.join(home, "Library", "Application Support", "Cursor"), - os.path.join(home, "Library", "Application Support", "cursor-electron"), - os.path.join(home, "Library", "Caches", "Cursor"), - os.path.join(home, "Library", "Caches", "cursor-electron"), - os.path.join(home, "Library", "Preferences", "Cursor"), - os.path.join(home, "Library", "Preferences", "cursor-electron"), - os.path.join(home, "Library", "Saved Application State", "com.cursor.Cursor.savedState"), - os.path.join(home, "Library", "HTTPStorages", "com.cursor.Cursor"), - os.path.join(home, "Library", "WebKit", "com.cursor.Cursor"), - # os.path.join(home, ".vscode"), # Removed to avoid affecting VS Code - "/Applications/Cursor.app", # Main application location - ] - - # Additional locations for license/trial files on macOS - license_search_paths = [ - os.path.join(home, "Library", "Application Support"), - os.path.join(home, "Library", "Preferences"), - os.path.join(home, "Library", "Caches"), - ] - - elif system == "Linux": - cursor_paths = [ - os.path.join(home, ".config", "Cursor"), - os.path.join(home, ".config", "cursor-electron"), - os.path.join(home, ".cache", "Cursor"), - os.path.join(home, ".cache", "cursor-electron"), - os.path.join(home, ".local", "share", "Cursor"), - os.path.join(home, ".local", "share", "cursor-electron"), - # os.path.join(home, ".vscode"), # Removed to avoid affecting VS Code - os.path.join(home, ".local", "share", "applications", "cursor.desktop"), - os.path.join("/usr", "share", "applications", "cursor.desktop"), - os.path.join("/opt", "Cursor"), - ] - - # Additional locations for license/trial files on Linux - license_search_paths = [ - os.path.join(home, ".config"), - os.path.join(home, ".local", "share"), - os.path.join(home, ".cache"), - ] - - else: - print(f"{Fore.RED}{EMOJI['ERROR']} {translator.get('totally_reset.unsupported_os')} {Style.RESET_ALL}") - return - - # Remove main Cursor directories - print(f"\n{Fore.CYAN}{EMOJI['RESET']} {translator.get('totally_reset.removing_main_cursor_directories_and_files')} {Style.RESET_ALL}") - for path in cursor_paths: - remove_dir(path) - - # Reset machine identifiers (this creates new ones) - reset_machine_id(system, home) - - # Known trial/license file patterns - file_patterns = [ - ".cursor_trial_data", - "trial_info.json", - "license.json", - "cursor-license", - "cursor_license", - "cursor-auth", - "cursor_auth", - "cursor_subscription", - "cursor-subscription", - "cursor-state", - "cursorstate", - "cursorsettings", - "cursor-settings", - "ai-settings.json", - "cursor-machine-id", - "cursor_machine_id", - "cursor-storage" + + # Remove directories + for path in paths: + delete_directory(path) + + # Remove common files related to Cursor + files = [ + os.path.expanduser("~/.cursor/machine-id.db"), + os.path.expanduser("~/.local/share/cursor.db"), + os.path.expanduser("~/.config/cursor/preferences.json"), + os.path.expanduser("~/.cache/cursor.log"), ] - - # Direct known trial file paths - cursor_trial_files = [ - os.path.join(home, ".cursor_trial_data"), - os.path.join(home, ".cursor_license"), - os.path.join(home, ".cursor-machine-id"), - os.path.join(home, ".cursor-state.json"), - ] - - # OS-specific known trial/license files - if system == "Windows": - cursor_trial_files.extend([ - os.path.join(home, "AppData", "Local", "Cursor", "trial_info.json"), - os.path.join(home, "AppData", "Local", "Cursor", "license.json"), - os.path.join(home, "AppData", "Roaming", "Cursor", "trial_info.json"), - os.path.join(home, "AppData", "Roaming", "Cursor", "license.json"), - os.path.join(home, "AppData", "Roaming", "Cursor", "cursor-machine-id"), - os.path.join(home, "AppData", "Local", "Cursor", "cursor-machine-id"), - os.path.join(home, "AppData", "Local", "Cursor", "ai-settings.json"), - os.path.join(home, "AppData", "Roaming", "Cursor", "ai-settings.json"), - ]) - elif system == "Darwin": # macOS - cursor_trial_files.extend([ - os.path.join(home, "Library", "Application Support", "Cursor", "trial_info.json"), - os.path.join(home, "Library", "Application Support", "Cursor", "license.json"), - os.path.join(home, "Library", "Preferences", "Cursor", "trial_info.json"), - os.path.join(home, "Library", "Preferences", "Cursor", "license.json"), - os.path.join(home, "Library", "Application Support", "Cursor", "cursor-machine-id"), - os.path.join(home, "Library", "Application Support", "Cursor", "ai-settings.json"), - ]) - elif system == "Linux": - cursor_trial_files.extend([ - os.path.join(home, ".config", "Cursor", "trial_info.json"), - os.path.join(home, ".config", "Cursor", "license.json"), - os.path.join(home, ".local", "share", "Cursor", "trial_info.json"), - os.path.join(home, ".local", "share", "Cursor", "license.json"), - os.path.join(home, ".config", "Cursor", "cursor-machine-id"), - os.path.join(home, ".config", "Cursor", "ai-settings.json"), - ]) - - # Remove known trial/license files - print(f"\n{Fore.CYAN}{EMOJI['RESET']} {translator.get('totally_reset.removing_known')} {Style.RESET_ALL}") - for path in cursor_trial_files: - remove_file(path) - - # Deep search for additional trial/license files - print(f"\n{Fore.CYAN}{EMOJI['RESET']} {translator.get('totally_reset.performing_deep_scan')} {Style.RESET_ALL}") - all_found_files = [] - for base_path in license_search_paths: - if os.path.exists(base_path): - found_files = find_cursor_license_files(base_path, file_patterns) - all_found_files.extend(found_files) - if all_found_files: - print(f"\nšŸ”Ž {translator.get('totally_reset.found_additional_potential_license_trial_files', count=len(all_found_files))}\n") - for file_path in all_found_files: - remove_file(file_path) - else: - print(f"\n{Fore.CYAN}{EMOJI['INFO']} {translator.get('totally_reset.no_additional_license_trial_files_found_in_deep_scan')} {Style.RESET_ALL}") - - # Check for and remove localStorage files that might contain settings - print(f"\n{Fore.CYAN}{EMOJI['RESET']} {translator.get('totally_reset.checking_for_electron_localstorage_files')} {Style.RESET_ALL}") - if system == "Windows": - local_storage_paths = glob.glob(os.path.join(home, "AppData", "Roaming", "*cursor*", "Local Storage", "leveldb", "*")) - local_storage_paths += glob.glob(os.path.join(home, "AppData", "Local", "*cursor*", "Local Storage", "leveldb", "*")) - elif system == "Darwin": - local_storage_paths = glob.glob(os.path.join(home, "Library", "Application Support", "*cursor*", "Local Storage", "leveldb", "*")) - elif system == "Linux": - local_storage_paths = glob.glob(os.path.join(home, ".config", "*cursor*", "Local Storage", "leveldb", "*")) + for file in files: + delete_file(file) - for path in local_storage_paths: - if is_cursor_related(path): - remove_file(path) + # Extra cleanup (wildcard search) + print("\nšŸ” Deep scanning for hidden Cursor files...") + base_dirs = ["/tmp", "/var/tmp", os.path.expanduser("~")] # Linux and macOS + if platform.system() == "Windows": + base_dirs = ["C:\\Temp", "C:\\Windows\\Temp", os.path.expanduser("~")] # Windows - # Create new trial files with extended expiration - print(f"\n{Fore.CYAN}{EMOJI['RESET']} {translator.get('totally_reset.creating_new_trial_information_with_extended_period')} {Style.RESET_ALL}") - if system == "Windows": - create_fake_trial_info(os.path.join(home, "AppData", "Local", "Cursor", "trial_info.json"), system, home) - create_fake_trial_info(os.path.join(home, "AppData", "Roaming", "Cursor", "trial_info.json"), system, home) - elif system == "Darwin": - create_fake_trial_info(os.path.join(home, "Library", "Application Support", "Cursor", "trial_info.json"), system, home) - elif system == "Linux": - create_fake_trial_info(os.path.join(home, ".config", "Cursor", "trial_info.json"), system, home) - - print(f"\n{Fore.GREEN}{EMOJI['SUCCESS']} {translator.get('totally_reset.reset_log_1')}") - print(f" {translator.get('totally_reset.reset_log_2')}") - print(f" {translator.get('totally_reset.reset_log_3')}") + for base in base_dirs: + for root, dirs, files in os.walk(base): + for dir in dirs: + if "cursor" in dir.lower(): + delete_directory(os.path.join(root, dir)) + for file in files: + if "cursor" in file.lower(): + delete_file(os.path.join(root, file)) - print(f"\n{Fore.GREEN}{EMOJI['INFO']} {translator.get('totally_reset.reset_log_4')} {Style.RESET_ALL}") - print(f" {translator.get('totally_reset.reset_log_5')} {Style.RESET_ALL}") - print(f" {translator.get('totally_reset.reset_log_6')} {Style.RESET_ALL}") - print(f" {translator.get('totally_reset.reset_log_7')} {Style.RESET_ALL}") - print(f" {translator.get('totally_reset.reset_log_8')} {Style.RESET_ALL}") - - print(f"\n{Fore.RED}{EMOJI['INFO']} {translator.get('totally_reset.reset_log_9')} {Style.RESET_ALL}") + print("\nāœ… Cursor AI has been completely reset!") -if __name__ == "__main__": - try: - reset_cursor() - except KeyboardInterrupt: - print(f"\n\n{Fore.RED}{EMOJI['STOP']} {translator.get('totally_reset.keyboard_interrupt')} {Style.RESET_ALL}") - sys.exit(1) - except Exception as e: - print(f"\n{Fore.RED}{EMOJI['ERROR']} {translator.get('totally_reset.unexpected_error', error=str(e))}{Style.RESET_ALL}") - print(f" {translator.get('totally_reset.report_issue')}") - sys.exit(1) +def main(): + start_time = time.time() + reset_cursor() + end_time = time.time() + print(f"\nā±ļø Completed in {end_time - start_time:.2f} seconds.") -def run(translator=None): - """Entry point for the totally reset cursor functionality when called from the main menu.""" - try: - reset_cursor() - input(f"\n\n{Fore.CYAN}{EMOJI['INFO']} {translator.get('totally_reset.return_to_main_menu')} {Style.RESET_ALL}") - except KeyboardInterrupt: - print(f"\n\n{Fore.RED}{EMOJI['STOP']} {translator.get('totally_reset.process_interrupted')} {Style.RESET_ALL}") - except Exception as e: - print(f"\n{Fore.RED}{EMOJI['ERROR']} {translator.get('totally_reset.unexpected_error', error=str(e))}{Style.RESET_ALL}") - print(f" {translator.get('totally_reset.report_issue')}") - input(f"\n{Fore.CYAN}{EMOJI['INFO']} {translator.get('totally_reset.press_enter_to_return_to_main_menu')} {Style.RESET_ALL}") +if __name__ == '__main__': + main() From 7b757c2d57a1aea9b614e64189b4c4ef0da3fd76 Mon Sep 17 00:00:00 2001 From: BasaiCorp Date: Fri, 21 Mar 2025 20:38:53 +0530 Subject: [PATCH 2/5] Update totally_reset_cursor.py test v0.2 --- totally_reset_cursor.py | 50 +++++++++++++++++++++++++++++++++-------- 1 file changed, 41 insertions(+), 9 deletions(-) diff --git a/totally_reset_cursor.py b/totally_reset_cursor.py index b32b050..c6391b7 100644 --- a/totally_reset_cursor.py +++ b/totally_reset_cursor.py @@ -2,6 +2,8 @@ import os import shutil import platform import time +import uuid +import subprocess def delete_directory(path): """Deletes a directory and all its contents.""" @@ -25,6 +27,36 @@ def delete_file(path): else: print(f"šŸ” Not found: {path}") +def reset_machine_id(): + """Resets the machine ID to a new UUID.""" + new_id = str(uuid.uuid4()) + if platform.system() == "Windows": + try: + subprocess.run( + ["reg", "add", "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Cryptography", "/v", "MachineGuid", "/d", new_id, "/f"], + check=True, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE + ) + print(f"āœ… MachineGuid reset to: {new_id}") + except subprocess.CalledProcessError as e: + print(f"āŒ Failed to reset MachineGuid: {e}") + elif platform.system() == "Linux": + machine_id_paths = ["/etc/machine-id", "/var/lib/dbus/machine-id"] + for path in machine_id_paths: + if os.path.exists(path): + try: + with open(path, 'w') as f: + f.write(new_id) + print(f"āœ… Reset machine ID at: {path}") + except Exception as e: + print(f"āŒ Failed to reset machine ID at {path}: {e}") + elif platform.system() == "Darwin": # macOS + # macOS typically doesn't use a machine-id file like Linux + print("ā„¹ļø macOS does not use a machine-id file. Skipping machine ID reset.") + else: + print("āŒ Unsupported operating system for machine ID reset.") + def reset_cursor(): print("\nšŸš€ Resetting Cursor AI...\n") @@ -40,12 +72,10 @@ def reset_cursor(): "/opt/cursor", "/usr/bin/cursor", os.path.expanduser("~/.cursor/machine-id.db"), - os.path.expanduser("~/.local/share/cursor"), - os.path.expanduser("~/.config/Cursor"), os.path.expanduser("~/.local/share/Cursor"), + os.path.expanduser("~/.config/Cursor"), os.path.expanduser("~/.cache/Cursor") ] - elif platform.system() == "Darwin": # macOS paths = [ os.path.expanduser("~/Library/Application Support/Cursor"), @@ -53,7 +83,6 @@ def reset_cursor(): "/Applications/Cursor.app", os.path.expanduser("~/Library/Preferences/com.cursor.app.plist"), ] - elif platform.system() == "Windows": paths = [ os.path.expanduser("~\\AppData\\Local\\Cursor"), @@ -66,11 +95,11 @@ def reset_cursor(): "C:\\Users\\%USERNAME%\\AppData\\Local\\Cursor", "C:\\Users\\%USERNAME%\\AppData\\Roaming\\Cursor", ] - + # Remove directories for path in paths: delete_directory(path) - + # Remove common files related to Cursor files = [ os.path.expanduser("~/.cursor/machine-id.db"), @@ -78,10 +107,10 @@ def reset_cursor(): os.path.expanduser("~/.config/cursor/preferences.json"), os.path.expanduser("~/.cache/cursor.log"), ] - + for file in files: delete_file(file) - + # Extra cleanup (wildcard search) print("\nšŸ” Deep scanning for hidden Cursor files...") base_dirs = ["/tmp", "/var/tmp", os.path.expanduser("~")] # Linux and macOS @@ -96,7 +125,10 @@ def reset_cursor(): for file in files: if "cursor" in file.lower(): delete_file(os.path.join(root, file)) - + + # Reset machine ID + reset_machine_id() + print("\nāœ… Cursor AI has been completely reset!") def main(): From f90a2916b15598ebb67d0f504bc9b38d78d8092d Mon Sep 17 00:00:00 2001 From: BasaiCorp Date: Fri, 21 Mar 2025 20:46:26 +0530 Subject: [PATCH 3/5] Create github_cursor_register.py test 0.1.0 test now may be need time and this change and determinate all other tools and this tool will be favourite of all users --- github_cursor_register.py | 141 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100644 github_cursor_register.py diff --git a/github_cursor_register.py b/github_cursor_register.py new file mode 100644 index 0000000..c6391b7 --- /dev/null +++ b/github_cursor_register.py @@ -0,0 +1,141 @@ +import os +import shutil +import platform +import time +import uuid +import subprocess + +def delete_directory(path): + """Deletes a directory and all its contents.""" + if os.path.exists(path): + try: + shutil.rmtree(path) + print(f"āœ… Removed: {path}") + except Exception as e: + print(f"āŒ Failed to remove: {path} -> {e}") + else: + print(f"šŸ” Not found: {path}") + +def delete_file(path): + """Deletes a file if it exists.""" + if os.path.isfile(path): + try: + os.remove(path) + print(f"āœ… Removed file: {path}") + except Exception as e: + print(f"āŒ Failed to remove file: {path} -> {e}") + else: + print(f"šŸ” Not found: {path}") + +def reset_machine_id(): + """Resets the machine ID to a new UUID.""" + new_id = str(uuid.uuid4()) + if platform.system() == "Windows": + try: + subprocess.run( + ["reg", "add", "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Cryptography", "/v", "MachineGuid", "/d", new_id, "/f"], + check=True, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE + ) + print(f"āœ… MachineGuid reset to: {new_id}") + except subprocess.CalledProcessError as e: + print(f"āŒ Failed to reset MachineGuid: {e}") + elif platform.system() == "Linux": + machine_id_paths = ["/etc/machine-id", "/var/lib/dbus/machine-id"] + for path in machine_id_paths: + if os.path.exists(path): + try: + with open(path, 'w') as f: + f.write(new_id) + print(f"āœ… Reset machine ID at: {path}") + except Exception as e: + print(f"āŒ Failed to reset machine ID at {path}: {e}") + elif platform.system() == "Darwin": # macOS + # macOS typically doesn't use a machine-id file like Linux + print("ā„¹ļø macOS does not use a machine-id file. Skipping machine ID reset.") + else: + print("āŒ Unsupported operating system for machine ID reset.") + +def reset_cursor(): + print("\nšŸš€ Resetting Cursor AI...\n") + + # Platform-specific paths + paths = [] + if platform.system() == "Linux": + paths = [ + os.path.expanduser("~/.cursor"), + os.path.expanduser("~/.local/share/cursor"), + os.path.expanduser("~/.config/cursor"), + os.path.expanduser("~/.cache/cursor"), + "/usr/local/bin/cursor", + "/opt/cursor", + "/usr/bin/cursor", + os.path.expanduser("~/.cursor/machine-id.db"), + os.path.expanduser("~/.local/share/Cursor"), + os.path.expanduser("~/.config/Cursor"), + os.path.expanduser("~/.cache/Cursor") + ] + elif platform.system() == "Darwin": # macOS + paths = [ + os.path.expanduser("~/Library/Application Support/Cursor"), + os.path.expanduser("~/Library/Caches/Cursor"), + "/Applications/Cursor.app", + os.path.expanduser("~/Library/Preferences/com.cursor.app.plist"), + ] + elif platform.system() == "Windows": + paths = [ + os.path.expanduser("~\\AppData\\Local\\Cursor"), + os.path.expanduser("~\\AppData\\Roaming\\Cursor"), + os.path.expanduser("~\\.cursor"), + os.path.expanduser("~\\.config\\Cursor"), + os.path.expanduser("~\\.cache\\Cursor"), + "C:\\Program Files\\Cursor", + "C:\\Program Files (x86)\\Cursor", + "C:\\Users\\%USERNAME%\\AppData\\Local\\Cursor", + "C:\\Users\\%USERNAME%\\AppData\\Roaming\\Cursor", + ] + + # Remove directories + for path in paths: + delete_directory(path) + + # Remove common files related to Cursor + files = [ + os.path.expanduser("~/.cursor/machine-id.db"), + os.path.expanduser("~/.local/share/cursor.db"), + os.path.expanduser("~/.config/cursor/preferences.json"), + os.path.expanduser("~/.cache/cursor.log"), + ] + + for file in files: + delete_file(file) + + # Extra cleanup (wildcard search) + print("\nšŸ” Deep scanning for hidden Cursor files...") + base_dirs = ["/tmp", "/var/tmp", os.path.expanduser("~")] # Linux and macOS + if platform.system() == "Windows": + base_dirs = ["C:\\Temp", "C:\\Windows\\Temp", os.path.expanduser("~")] # Windows + + for base in base_dirs: + for root, dirs, files in os.walk(base): + for dir in dirs: + if "cursor" in dir.lower(): + delete_directory(os.path.join(root, dir)) + for file in files: + if "cursor" in file.lower(): + delete_file(os.path.join(root, file)) + + # Reset machine ID + reset_machine_id() + + print("\nāœ… Cursor AI has been completely reset!") + +def main(): + start_time = time.time() + reset_cursor() + end_time = time.time() + print(f"\nā±ļø Completed in {end_time - start_time:.2f} seconds.") + +if __name__ == '__main__': + main() From 34f5c679a5b41151a06aa0571e5744dd735e3252 Mon Sep 17 00:00:00 2001 From: BasaiCorp Date: Fri, 21 Mar 2025 20:47:37 +0530 Subject: [PATCH 4/5] Update github_cursor_register.py test 0.1.2 --- github_cursor_register.py | 225 ++++++++++++++++++-------------------- 1 file changed, 104 insertions(+), 121 deletions(-) diff --git a/github_cursor_register.py b/github_cursor_register.py index c6391b7..41535cf 100644 --- a/github_cursor_register.py +++ b/github_cursor_register.py @@ -1,141 +1,124 @@ import os -import shutil -import platform import time import uuid -import subprocess +import json +import random +import string +import requests +from selenium import webdriver +from selenium.webdriver.common.by import By +from selenium.webdriver.common.keys import Keys +from selenium.webdriver.chrome.service import Service +from webdriver_manager.chrome import ChromeDriverManager +from selenium.webdriver.chrome.options import Options -def delete_directory(path): - """Deletes a directory and all its contents.""" - if os.path.exists(path): - try: - shutil.rmtree(path) - print(f"āœ… Removed: {path}") - except Exception as e: - print(f"āŒ Failed to remove: {path} -> {e}") - else: - print(f"šŸ” Not found: {path}") +def generate_temp_email(): + """Generates a temporary email and returns the email and inbox ID.""" + response = requests.get("https://www.1secmail.com/api/v1/?action=genRandomMailbox&count=1") + email = response.json()[0] + print(f"āœ… Generated temp email: {email}") + return email -def delete_file(path): - """Deletes a file if it exists.""" - if os.path.isfile(path): - try: - os.remove(path) - print(f"āœ… Removed file: {path}") - except Exception as e: - print(f"āŒ Failed to remove file: {path} -> {e}") - else: - print(f"šŸ” Not found: {path}") +def extract_inbox(email): + """Extracts the inbox for the temp email.""" + domain = email.split('@')[1] + login = email.split('@')[0] + inbox_url = f"https://www.1secmail.com/api/v1/?action=getMessages&login={login}&domain={domain}" + time.sleep(10) # Allow email to arrive + messages = requests.get(inbox_url).json() + if messages: + return messages[0]['id'] + return None + +def get_verification_link(email, message_id): + """Retrieves the verification link from the email inbox.""" + domain = email.split('@')[1] + login = email.split('@')[0] + msg_url = f"https://www.1secmail.com/api/v1/?action=readMessage&login={login}&domain={domain}&id={message_id}" + message = requests.get(msg_url).json() + for line in message['body'].splitlines(): + if "https://github.com/" in line: + print(f"āœ… Verification link found: {line}") + return line.strip() + return None def reset_machine_id(): - """Resets the machine ID to a new UUID.""" + """Resets the machine ID to bypass Cursor AI's free trial detection.""" new_id = str(uuid.uuid4()) - if platform.system() == "Windows": - try: - subprocess.run( - ["reg", "add", "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Cryptography", "/v", "MachineGuid", "/d", new_id, "/f"], - check=True, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE - ) - print(f"āœ… MachineGuid reset to: {new_id}") - except subprocess.CalledProcessError as e: - print(f"āŒ Failed to reset MachineGuid: {e}") - elif platform.system() == "Linux": - machine_id_paths = ["/etc/machine-id", "/var/lib/dbus/machine-id"] - for path in machine_id_paths: - if os.path.exists(path): - try: - with open(path, 'w') as f: - f.write(new_id) - print(f"āœ… Reset machine ID at: {path}") - except Exception as e: - print(f"āŒ Failed to reset machine ID at {path}: {e}") - elif platform.system() == "Darwin": # macOS - # macOS typically doesn't use a machine-id file like Linux - print("ā„¹ļø macOS does not use a machine-id file. Skipping machine ID reset.") - else: - print("āŒ Unsupported operating system for machine ID reset.") + if os.name == 'nt': # Windows + os.system(f'reg add "HKLM\SOFTWARE\Microsoft\Cryptography" /v MachineGuid /d {new_id} /f') + else: # Linux/macOS + os.system(f'echo {new_id} | sudo tee /etc/machine-id') + print(f"āœ… Machine ID reset: {new_id}") -def reset_cursor(): - print("\nšŸš€ Resetting Cursor AI...\n") +def register_github(email): + """Automates GitHub registration with temp email.""" + options = Options() + options.add_argument('--headless') + options.add_argument('--no-sandbox') + options.add_argument('--disable-dev-shm-usage') - # Platform-specific paths - paths = [] - if platform.system() == "Linux": - paths = [ - os.path.expanduser("~/.cursor"), - os.path.expanduser("~/.local/share/cursor"), - os.path.expanduser("~/.config/cursor"), - os.path.expanduser("~/.cache/cursor"), - "/usr/local/bin/cursor", - "/opt/cursor", - "/usr/bin/cursor", - os.path.expanduser("~/.cursor/machine-id.db"), - os.path.expanduser("~/.local/share/Cursor"), - os.path.expanduser("~/.config/Cursor"), - os.path.expanduser("~/.cache/Cursor") - ] - elif platform.system() == "Darwin": # macOS - paths = [ - os.path.expanduser("~/Library/Application Support/Cursor"), - os.path.expanduser("~/Library/Caches/Cursor"), - "/Applications/Cursor.app", - os.path.expanduser("~/Library/Preferences/com.cursor.app.plist"), - ] - elif platform.system() == "Windows": - paths = [ - os.path.expanduser("~\\AppData\\Local\\Cursor"), - os.path.expanduser("~\\AppData\\Roaming\\Cursor"), - os.path.expanduser("~\\.cursor"), - os.path.expanduser("~\\.config\\Cursor"), - os.path.expanduser("~\\.cache\\Cursor"), - "C:\\Program Files\\Cursor", - "C:\\Program Files (x86)\\Cursor", - "C:\\Users\\%USERNAME%\\AppData\\Local\\Cursor", - "C:\\Users\\%USERNAME%\\AppData\\Roaming\\Cursor", - ] + driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=options) + driver.get("https://github.com/join") - # Remove directories - for path in paths: - delete_directory(path) + # Fill in the registration form + username = ''.join(random.choices(string.ascii_letters + string.digits, k=8)) + password = ''.join(random.choices(string.ascii_letters + string.digits, k=12)) - # Remove common files related to Cursor - files = [ - os.path.expanduser("~/.cursor/machine-id.db"), - os.path.expanduser("~/.local/share/cursor.db"), - os.path.expanduser("~/.config/cursor/preferences.json"), - os.path.expanduser("~/.cache/cursor.log"), - ] + driver.find_element(By.ID, "user_login").send_keys(username) + driver.find_element(By.ID, "user_email").send_keys(email) + driver.find_element(By.ID, "user_password").send_keys(password) + driver.find_element(By.ID, "signup_button").click() - for file in files: - delete_file(file) + time.sleep(5) + driver.quit() - # Extra cleanup (wildcard search) - print("\nšŸ” Deep scanning for hidden Cursor files...") - base_dirs = ["/tmp", "/var/tmp", os.path.expanduser("~")] # Linux and macOS - if platform.system() == "Windows": - base_dirs = ["C:\\Temp", "C:\\Windows\\Temp", os.path.expanduser("~")] # Windows + print(f"āœ… GitHub account created: {username} | {email}") + return username, password - for base in base_dirs: - for root, dirs, files in os.walk(base): - for dir in dirs: - if "cursor" in dir.lower(): - delete_directory(os.path.join(root, dir)) - for file in files: - if "cursor" in file.lower(): - delete_file(os.path.join(root, file)) - - # Reset machine ID - reset_machine_id() - - print("\nāœ… Cursor AI has been completely reset!") +def register_cursor_with_github(driver): + """Logs into Cursor AI using GitHub authentication.""" + driver.get("https://cursor.sh") + driver.find_element(By.LINK_TEXT, "Sign in with GitHub").click() + time.sleep(5) + print("āœ… Registered Cursor with GitHub") def main(): - start_time = time.time() - reset_cursor() - end_time = time.time() - print(f"\nā±ļø Completed in {end_time - start_time:.2f} seconds.") + print("\nšŸš€ Automating GitHub + Cursor AI Registration...\n") + + email = generate_temp_email() + github_username, github_password = register_github(email) + + inbox_id = extract_inbox(email) + if inbox_id: + verify_link = get_verification_link(email, inbox_id) + if verify_link: + options = Options() + options.add_argument('--headless') + driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=options) + driver.get(verify_link) + print("āœ… Verified GitHub Email") + driver.quit() + else: + print("āŒ Verification link not found") + + # Automate Cursor AI registration with GitHub + options = Options() + driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=options) + register_cursor_with_github(driver) + + # Reset Machine ID + reset_machine_id() + + # Save credentials + with open("github_cursor_accounts.txt", "a") as f: + f.write(json.dumps({ + "email": email, + "github_username": github_username, + "github_password": github_password + }) + "\n") + + print("āœ… All steps completed!") if __name__ == '__main__': main() From 05e4d7faa9c0cde6d1a4e68497d2bfdfaed356be Mon Sep 17 00:00:00 2001 From: BasaiCorp Date: Fri, 21 Mar 2025 20:49:09 +0530 Subject: [PATCH 5/5] Update github_cursor_register.py stable v1.0 stable and test both. --- github_cursor_register.py | 45 ++++++++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/github_cursor_register.py b/github_cursor_register.py index 41535cf..c3e19b6 100644 --- a/github_cursor_register.py +++ b/github_cursor_register.py @@ -7,7 +7,6 @@ import string import requests from selenium import webdriver from selenium.webdriver.common.by import By -from selenium.webdriver.common.keys import Keys from selenium.webdriver.chrome.service import Service from webdriver_manager.chrome import ChromeDriverManager from selenium.webdriver.chrome.options import Options @@ -19,15 +18,19 @@ def generate_temp_email(): print(f"āœ… Generated temp email: {email}") return email -def extract_inbox(email): - """Extracts the inbox for the temp email.""" +def extract_inbox(email, retries=5): + """Extracts the inbox for the temp email with retries.""" domain = email.split('@')[1] login = email.split('@')[0] inbox_url = f"https://www.1secmail.com/api/v1/?action=getMessages&login={login}&domain={domain}" - time.sleep(10) # Allow email to arrive - messages = requests.get(inbox_url).json() - if messages: - return messages[0]['id'] + + for attempt in range(retries): + time.sleep(10) # Allow email to arrive + messages = requests.get(inbox_url).json() + if messages: + print(f"āœ… Inbox found on attempt {attempt + 1}") + return messages[0]['id'] + print(f"šŸ”„ Retry {attempt + 1}/{retries}: No email yet...") return None def get_verification_link(email, message_id): @@ -62,14 +65,14 @@ def register_github(email): driver.get("https://github.com/join") # Fill in the registration form - username = ''.join(random.choices(string.ascii_letters + string.digits, k=8)) - password = ''.join(random.choices(string.ascii_letters + string.digits, k=12)) + username = ''.join(random.choices(string.ascii_letters + string.digits, k=10)) + password = ''.join(random.choices(string.ascii_letters + string.digits, k=15)) driver.find_element(By.ID, "user_login").send_keys(username) driver.find_element(By.ID, "user_email").send_keys(email) driver.find_element(By.ID, "user_password").send_keys(password) driver.find_element(By.ID, "signup_button").click() - + time.sleep(5) driver.quit() @@ -79,10 +82,22 @@ def register_github(email): def register_cursor_with_github(driver): """Logs into Cursor AI using GitHub authentication.""" driver.get("https://cursor.sh") + time.sleep(5) driver.find_element(By.LINK_TEXT, "Sign in with GitHub").click() time.sleep(5) print("āœ… Registered Cursor with GitHub") +def save_credentials(email, github_username, github_password): + """Saves the credentials in a log file.""" + with open("github_cursor_accounts.txt", "a") as f: + f.write(json.dumps({ + "email": email, + "github_username": github_username, + "github_password": github_password, + "timestamp": time.strftime('%Y-%m-%d %H:%M:%S') + }) + "\n") + print("āœ… Credentials saved") + def main(): print("\nšŸš€ Automating GitHub + Cursor AI Registration...\n") @@ -101,6 +116,8 @@ def main(): driver.quit() else: print("āŒ Verification link not found") + else: + print("āŒ Email verification failed") # Automate Cursor AI registration with GitHub options = Options() @@ -111,13 +128,7 @@ def main(): reset_machine_id() # Save credentials - with open("github_cursor_accounts.txt", "a") as f: - f.write(json.dumps({ - "email": email, - "github_username": github_username, - "github_password": github_password - }) + "\n") - + save_credentials(email, github_username, github_password) print("āœ… All steps completed!") if __name__ == '__main__':