package cmd import ( "crypto/rand" "crypto/sha256" "crypto/sha512" "encoding/hex" "encoding/json" "fmt" "os" "os/exec" "path/filepath" "runtime" "time" "github.com/google/uuid" ) func sha256hex() string { b := make([]byte, 32) _, _ = rand.Read(b) h := sha256.Sum256(b) return hex.EncodeToString(h[:]) } func sha512hex() string { b := make([]byte, 64) _, _ = rand.Read(b) h := sha512.Sum512(b) return hex.EncodeToString(h[:]) } func newUUID() string { return uuid.New().String() } func log(icon, msg string) { fmt.Printf(" %s %s\n", icon, msg) } func getCursorGlobalStorage() string { switch runtime.GOOS { case "darwin": home, _ := os.UserHomeDir() return filepath.Join(home, "Library", "Application Support", "Cursor", "User", "globalStorage") case "windows": appdata := os.Getenv("APPDATA") return filepath.Join(appdata, "Cursor", "User", "globalStorage") default: xdg := os.Getenv("XDG_CONFIG_HOME") if xdg == "" { home, _ := os.UserHomeDir() xdg = filepath.Join(home, ".config") } return filepath.Join(xdg, "Cursor", "User", "globalStorage") } } func getCursorRoot() string { gs := getCursorGlobalStorage() return filepath.Dir(filepath.Dir(gs)) } func generateNewIDs() map[string]string { return map[string]string{ "telemetry.machineId": sha256hex(), "telemetry.macMachineId": sha512hex(), "telemetry.devDeviceId": newUUID(), "telemetry.sqmId": "{" + fmt.Sprintf("%s", newUUID()+"") + "}", "storage.serviceMachineId": newUUID(), } } func killCursor() { log("", "Stopping Cursor processes...") switch runtime.GOOS { case "windows": exec.Command("taskkill", "/F", "/IM", "Cursor.exe").Run() default: exec.Command("pkill", "-x", "Cursor").Run() exec.Command("pkill", "-f", "Cursor.app").Run() } log("", "Cursor stopped (or was not running)") } func updateStorageJSON(storagePath string, ids map[string]string) { if _, err := os.Stat(storagePath); os.IsNotExist(err) { log("", fmt.Sprintf("storage.json not found: %s", storagePath)) return } if runtime.GOOS == "darwin" { exec.Command("chflags", "nouchg", storagePath).Run() exec.Command("chmod", "644", storagePath).Run() } data, err := os.ReadFile(storagePath) if err != nil { log("", fmt.Sprintf("storage.json read error: %v", err)) return } var obj map[string]interface{} if err := json.Unmarshal(data, &obj); err != nil { log("", fmt.Sprintf("storage.json parse error: %v", err)) return } for k, v := range ids { obj[k] = v } out, err := json.MarshalIndent(obj, "", " ") if err != nil { log("", fmt.Sprintf("storage.json marshal error: %v", err)) return } if err := os.WriteFile(storagePath, out, 0644); err != nil { log("", fmt.Sprintf("storage.json write error: %v", err)) return } log("", "storage.json updated") } func updateStateVscdb(dbPath string, ids map[string]string) { if _, err := os.Stat(dbPath); os.IsNotExist(err) { log("", fmt.Sprintf("state.vscdb not found: %s", dbPath)) return } if runtime.GOOS == "darwin" { exec.Command("chflags", "nouchg", dbPath).Run() exec.Command("chmod", "644", dbPath).Run() } if err := updateVscdbPureGo(dbPath, ids); err != nil { log("", fmt.Sprintf("state.vscdb error: %v", err)) } else { log("", "state.vscdb updated") } } func updateMachineIDFile(machineID, cursorRoot string) { var candidates []string if runtime.GOOS == "linux" { candidates = []string{ filepath.Join(cursorRoot, "machineid"), filepath.Join(cursorRoot, "machineId"), } } else { candidates = []string{filepath.Join(cursorRoot, "machineId")} } filePath := candidates[0] for _, c := range candidates { if _, err := os.Stat(c); err == nil { filePath = c break } } if err := os.MkdirAll(filepath.Dir(filePath), 0755); err != nil { log("", fmt.Sprintf("machineId dir error: %v", err)) return } if runtime.GOOS == "darwin" { if _, err := os.Stat(filePath); err == nil { exec.Command("chflags", "nouchg", filePath).Run() exec.Command("chmod", "644", filePath).Run() } } if err := os.WriteFile(filePath, []byte(machineID+"\n"), 0644); err != nil { log("", fmt.Sprintf("machineId write error: %v", err)) return } log("", fmt.Sprintf("machineId file updated (%s)", filepath.Base(filePath))) } var dirsToWipe = []string{ "Session Storage", "Local Storage", "IndexedDB", "Cache", "Code Cache", "GPUCache", "Service Worker", "Network", "Cookies", "Cookies-journal", } func deepClean(cursorRoot string) { log("", "Deep-cleaning session data...") wiped := 0 for _, name := range dirsToWipe { target := filepath.Join(cursorRoot, name) if _, err := os.Stat(target); os.IsNotExist(err) { continue } info, err := os.Stat(target) if err != nil { continue } if info.IsDir() { if err := os.RemoveAll(target); err == nil { wiped++ } } else { if err := os.Remove(target); err == nil { wiped++ } } } log("", fmt.Sprintf("Wiped %d cache/session items", wiped)) } func HandleResetHwid(doDeepClean, dryRun bool) error { fmt.Print("\nCursor HWID Reset\n\n") fmt.Println(" Resets all machine / telemetry IDs so Cursor sees a fresh install.") fmt.Print(" Cursor must be closed — it will be killed automatically.\n\n") globalStorage := getCursorGlobalStorage() cursorRoot := getCursorRoot() if _, err := os.Stat(globalStorage); os.IsNotExist(err) { fmt.Printf("Cursor config not found at:\n %s\n", globalStorage) fmt.Println(" Make sure Cursor is installed and has been run at least once.") os.Exit(1) } if dryRun { fmt.Println(" [DRY RUN] Would reset IDs in:") fmt.Printf(" %s\n", filepath.Join(globalStorage, "storage.json")) fmt.Printf(" %s\n", filepath.Join(globalStorage, "state.vscdb")) fmt.Printf(" %s\n", filepath.Join(cursorRoot, "machineId")) return nil } killCursor() time.Sleep(800 * time.Millisecond) newIDs := generateNewIDs() log("", "Generated new IDs:") for k, v := range newIDs { fmt.Printf(" %s: %s\n", k, v) } fmt.Println() log("", "Updating storage.json...") updateStorageJSON(filepath.Join(globalStorage, "storage.json"), newIDs) log("", "Updating state.vscdb...") updateStateVscdb(filepath.Join(globalStorage, "state.vscdb"), newIDs) log("", "Updating machineId file...") updateMachineIDFile(newIDs["telemetry.machineId"], cursorRoot) if doDeepClean { fmt.Println() deepClean(cursorRoot) } fmt.Print("\nHWID reset complete. You can now restart Cursor.\n\n") return nil }