Skip to content

Instantly share code, notes, and snippets.

@sadegh19b
Last active March 10, 2025 02:11
Show Gist options
  • Save sadegh19b/d6d880320f643d93a318b15501882902 to your computer and use it in GitHub Desktop.
Save sadegh19b/d6d880320f643d93a318b15501882902 to your computer and use it in GitHub Desktop.
Cursor Trial Reset Tool
import os
import sys
import json
import uuid
import hashlib
import shutil
import sqlite3
import logging
from colorama import Fore, Style, init
# Set up logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
handlers=[
logging.StreamHandler(),
logging.FileHandler('reset_machine.log', encoding='utf-8')
]
)
logger = logging.getLogger(__name__)
# Initialize colorama
init()
# Define emoji constants
EMOJI = {
"FILE": "📄",
"BACKUP": "💾",
"SUCCESS": "✅",
"ERROR": "❌",
"INFO": "ℹ️",
"RESET": "🔄",
}
class MachineIDResetter:
def __init__(self):
# Determine the operating system
if sys.platform == "win32": # Windows
appdata = os.getenv("APPDATA")
if appdata is None:
raise EnvironmentError("APPDATA Environment Variable Not Set")
self.db_path = os.path.join(
appdata, "Cursor", "User", "globalStorage", "storage.json"
)
self.sqlite_path = os.path.join(
appdata, "Cursor", "User", "globalStorage", "state.vscdb"
)
elif sys.platform == "darwin": # macOS
self.db_path = os.path.abspath(os.path.expanduser(
"~/Library/Application Support/Cursor/User/globalStorage/storage.json"
))
self.sqlite_path = os.path.abspath(os.path.expanduser(
"~/Library/Application Support/Cursor/User/globalStorage/state.vscdb"
))
elif sys.platform == "linux": # Linux
self.db_path = os.path.abspath(os.path.expanduser(
"~/.config/Cursor/User/globalStorage/storage.json"
))
self.sqlite_path = os.path.abspath(os.path.expanduser(
"~/.config/Cursor/User/globalStorage/state.vscdb"
))
else:
raise NotImplementedError(f"Not Supported OS: {sys.platform}")
def generate_new_ids(self):
"""Generate new machine IDs"""
# Generate new UUID
dev_device_id = str(uuid.uuid4())
# Generate new machineId (64-character hexadecimal)
machine_id = hashlib.sha256(os.urandom(32)).hexdigest()
# Generate new macMachineId (128-character hexadecimal)
mac_machine_id = hashlib.sha512(os.urandom(64)).hexdigest()
# Generate new sqmId
sqm_id = "{" + str(uuid.uuid4()).upper() + "}"
return {
"telemetry.devDeviceId": dev_device_id,
"telemetry.macMachineId": mac_machine_id,
"telemetry.machineId": machine_id,
"telemetry.sqmId": sqm_id,
"storage.serviceMachineId": dev_device_id, # Add storage.serviceMachineId
}
def update_sqlite_db(self, new_ids):
"""Update machine IDs in the SQLite database"""
try:
print(f"{Fore.CYAN}{EMOJI['INFO']} Updating SQLite database...{Style.RESET_ALL}")
conn = sqlite3.connect(self.sqlite_path)
cursor = conn.cursor()
cursor.execute("""
CREATE TABLE IF NOT EXISTS ItemTable (
key TEXT PRIMARY KEY,
value TEXT
)
""")
updates = [
(key, value) for key, value in new_ids.items()
]
for key, value in updates:
cursor.execute("""
INSERT OR REPLACE INTO ItemTable (key, value)
VALUES (?, ?)
""", (key, value))
print(f"{EMOJI['INFO']} {Fore.CYAN} Updating pair: {key}{Style.RESET_ALL}")
conn.commit()
conn.close()
print(f"{Fore.GREEN}{EMOJI['SUCCESS']} SQLite database updated successfully{Style.RESET_ALL}")
return True
except Exception as e:
print(f"{Fore.RED}{EMOJI['ERROR']} Error updating SQLite database: {str(e)}{Style.RESET_ALL}")
return False
def update_system_ids(self, new_ids):
"""Update system-level IDs"""
try:
print(f"{Fore.CYAN}{EMOJI['INFO']} Updating system IDs...{Style.RESET_ALL}")
if sys.platform.startswith("win"):
self._update_windows_machine_guid()
elif sys.platform == "darwin":
self._update_macos_platform_uuid(new_ids)
print(f"{Fore.GREEN}{EMOJI['SUCCESS']} System IDs updated successfully{Style.RESET_ALL}")
return True
except Exception as e:
print(f"{Fore.RED}{EMOJI['ERROR']} System IDs update failed: {str(e)}{Style.RESET_ALL}")
logger.error(f"System IDs update failed: {e}")
return False
def _update_windows_machine_guid(self):
"""Update Windows MachineGuid"""
try:
import winreg
key = winreg.OpenKey(
winreg.HKEY_LOCAL_MACHINE,
"SOFTWARE\\Microsoft\\Cryptography",
0,
winreg.KEY_WRITE | winreg.KEY_WOW64_64KEY
)
new_guid = str(uuid.uuid4())
winreg.SetValueEx(key, "MachineGuid", 0, winreg.REG_SZ, new_guid)
winreg.CloseKey(key)
logger.info("Windows MachineGuid updated successfully")
except PermissionError:
logger.error("Permission denied: Run as administrator to update Windows MachineGuid")
raise
except Exception as e:
logger.error(f"Failed to update Windows MachineGuid: {e}")
raise
def _update_macos_platform_uuid(self, new_ids):
"""Update macOS Platform UUID"""
try:
uuid_file = "/var/root/Library/Preferences/SystemConfiguration/com.apple.platform.uuid.plist"
if os.path.exists(uuid_file):
# Use sudo to execute the plutil command
cmd = f'sudo plutil -replace "UUID" -string "{new_ids["telemetry.macMachineId"]}" "{uuid_file}"'
result = os.system(cmd)
if result == 0:
logger.info("macOS Platform UUID updated successfully")
else:
raise Exception("Failed to execute plutil command")
except Exception as e:
logger.error(f"Failed to update macOS Platform UUID: {e}")
raise
def reset_machine_ids(self):
"""Reset machine IDs and back up the original files"""
try:
print(f"{Fore.CYAN}{EMOJI['INFO']} Checking...{Style.RESET_ALL}")
if not os.path.exists(self.db_path):
print(f"{Fore.RED}{EMOJI['ERROR']} File not found: {self.db_path}{Style.RESET_ALL}")
return False
if not os.access(self.db_path, os.R_OK | os.W_OK):
print(f"{Fore.RED}{EMOJI['ERROR']} No permission to access file.{Style.RESET_ALL}")
return False
print(f"{Fore.CYAN}{EMOJI['FILE']} Reading...{Style.RESET_ALL}")
with open(self.db_path, "r", encoding="utf-8") as f:
config = json.load(f)
backup_path = self.db_path + ".bak"
if not os.path.exists(backup_path):
print(f"{Fore.YELLOW}{EMOJI['BACKUP']} Creating backup: {backup_path}{Style.RESET_ALL}")
shutil.copy2(self.db_path, backup_path)
else:
print(f"{Fore.YELLOW}{EMOJI['INFO']} Backup file already exists.{Style.RESET_ALL}")
print(f"{Fore.CYAN}{EMOJI['RESET']} Generating new IDs...{Style.RESET_ALL}")
new_ids = self.generate_new_ids()
# Update the configuration file
config.update(new_ids)
print(f"{Fore.CYAN}{EMOJI['FILE']} Saving JSON...{Style.RESET_ALL}")
with open(self.db_path, "w", encoding="utf-8") as f:
json.dump(config, f, indent=4)
# Update the SQLite database
self.update_sqlite_db(new_ids)
# Update system IDs
self.update_system_ids(new_ids)
print(f"{Fore.GREEN}{EMOJI['SUCCESS']} Machine IDs reset successfully!{Style.RESET_ALL}")
print(f"\n{Fore.CYAN}New IDs:{Style.RESET_ALL}")
for key, value in new_ids.items():
print(f"{EMOJI['INFO']} {key}: {Fore.GREEN}{value}{Style.RESET_ALL}")
return True
except PermissionError as e:
print(f"{Fore.RED}{EMOJI['ERROR']} Permission error: {str(e)}{Style.RESET_ALL}")
print(f"{Fore.YELLOW}{EMOJI['INFO']} Please run this script as administrator.{Style.RESET_ALL}")
return False
except Exception as e:
print(f"{Fore.RED}{EMOJI['ERROR']} An error occurred: {str(e)}{Style.RESET_ALL}")
return False
def run():
"""Convenience function to directly call the reset functionality"""
print(f"\n{Fore.CYAN}{'='*50}{Style.RESET_ALL}")
print(f"{Fore.CYAN}{EMOJI['RESET']} Cursor Machine ID Resetter{Style.RESET_ALL}")
print(f"{Fore.CYAN}{'='*50}{Style.RESET_ALL}")
resetter = MachineIDResetter()
resetter.reset_machine_ids()
print(f"\n{Fore.CYAN}{'='*50}{Style.RESET_ALL}")
input(f"{EMOJI['INFO']} Press Enter to exit...")
if __name__ == "__main__":
run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment