diff --git a/README.md b/README.md index 099207a..b265998 100644 --- a/README.md +++ b/README.md @@ -27,35 +27,86 @@ this is a mistake. ### 💻 System Support -**Windows** ✅ AMD64 & ARM64 -**macOS** ✅ AMD64 & ARM64 -**Linux** ✅ AMD64 & ARM64 +**Windows** ✅ x64 +**macOS** ✅ Intel & M-series +**Linux** ✅ x64 & ARM64 ### 📥 Installation +#### Automatic Installation (Recommended) + **Linux/macOS** ```bash -curl -fsSL https://raw.githubusercontent.com/yuaotian/go-cursor-help/master/install.sh | bash +curl -fsSL https://raw.githubusercontent.com/yuaotian/go-cursor-help/master/scripts/install.sh | sudo bash ``` -**Windows** (Run in PowerShell as Admin) +**Windows** (Run PowerShell as Admin) ```powershell -Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; $arch = if ([Environment]::Is64BitOperatingSystem) { if ([System.Runtime.InteropServices.RuntimeInformation]::ProcessArchitecture -eq 'Arm64') { 'arm64' } else { 'amd64' } } else { 'amd64' }; $ver = (irm https://api.github.com/repos/yuaotian/go-cursor-help/releases/latest).tag_name.TrimStart('v'); $outfile = "$env:TEMP\cursor_id_modifier.exe"; irm "https://github.com/yuaotian/go-cursor-help/releases/download/v${ver}/cursor_id_modifier_${ver}_windows_${arch}.exe" -OutFile $outfile; & $outfile; Remove-Item -Path $outfile -ErrorAction SilentlyContinue +irm https://raw.githubusercontent.com/yuaotian/go-cursor-help/master/scripts/install.ps1 | iex ``` +The installation script will automatically: +- Request necessary privileges (sudo/admin) +- Close any running Cursor instances +- Backup existing configuration +- Install the tool +- Add it to system PATH +- Clean up temporary files + +#### Manual Installation + +1. Download the latest release for your system from the [releases page](https://github.com/yuaotian/go-cursor-help/releases) +2. Extract and run with administrator/root privileges: + ```bash + # Linux/macOS + sudo ./cursor-id-modifier + + # Windows (PowerShell Admin) + .\cursor-id-modifier.exe + ``` + +#### Manual Configuration Method + +1. Close Cursor completely +2. Navigate to the configuration file location: + - Windows: `%APPDATA%\Cursor\User\globalStorage\storage.json` + - macOS: `~/Library/Application Support/Cursor/User/globalStorage/storage.json` + - Linux: `~/.config/Cursor/User/globalStorage/storage.json` +3. Create a backup of `storage.json` +4. Edit `storage.json` and update these fields with new random UUIDs: + ```json + { + "telemetry.machineId": "generate-new-uuid", + "telemetry.macMachineId": "generate-new-uuid", + "telemetry.devDeviceId": "generate-new-uuid", + "telemetry.sqmId": "generate-new-uuid", + "lastModified": "2024-01-01T00:00:00.000Z", + "version": "1.0.1" + } + ``` +5. Save the file and restart Cursor + ### 🔧 Technical Details -The program modifies Cursor's `storage.json` config file: +#### Configuration Files +The program modifies Cursor's `storage.json` config file located at: - Windows: `%APPDATA%\Cursor\User\globalStorage\` - macOS: `~/Library/Application Support/Cursor/User/globalStorage/` - Linux: `~/.config/Cursor/User/globalStorage/` -Generates new unique identifiers for: +#### Modified Fields +The tool generates new unique identifiers for: - `telemetry.machineId` - `telemetry.macMachineId` - `telemetry.devDeviceId` - `telemetry.sqmId` +#### Safety Features +- Automatic backup of existing configuration +- Safe process termination +- Atomic file operations +- Error handling and rollback + --- # 🌏 Chinese @@ -73,37 +124,99 @@ this is a mistake. ### 💻 系统支持 -**Windows** ✅ AMD64和ARM64 -**macOS** ✅ AMD64和ARM64 -**Linux** ✅ AMD64和ARM64 +**Windows** ✅ x64 +**macOS** ✅ Intel和M系列 +**Linux** ✅ x64和ARM64 ### 📥 安装方法 +#### 自动安装(推荐) + **Linux/macOS** ```bash -curl -fsSL https://raw.githubusercontent.com/yuaotian/go-cursor-help/master/install.sh | bash +curl -fsSL https://raw.githubusercontent.com/yuaotian/go-cursor-help/master/scripts/install.sh | sudo bash ``` **Windows** (以管理员身份运行PowerShell) ```powershell -Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; $arch = if ([Environment]::Is64BitOperatingSystem) { if ([System.Runtime.InteropServices.RuntimeInformation]::ProcessArchitecture -eq 'Arm64') { 'arm64' } else { 'amd64' } } else { 'amd64' }; $ver = (irm https://api.github.com/repos/yuaotian/go-cursor-help/releases/latest).tag_name.TrimStart('v'); $outfile = "$env:TEMP\cursor_id_modifier.exe"; irm "https://github.com/yuaotian/go-cursor-help/releases/download/v${ver}/cursor_id_modifier_${ver}_windows_${arch}.exe" -OutFile $outfile; & $outfile; Remove-Item -Path $outfile -ErrorAction SilentlyContinue +irm https://raw.githubusercontent.com/yuaotian/go-cursor-help/master/scripts/install.ps1 | iex ``` +安装脚本会自动: +- 请求必要的权限(sudo/管理员) +- 关闭所有运行中的Cursor实例 +- 备份现有配置 +- 安装工具 +- 添加到系统PATH +- 清理临时文件 + +#### 手动安装 + +1. 从[发布页面](https://github.com/yuaotian/go-cursor-help/releases)下载适合您系统的最新版本 +2. 解压并以管理员/root权限运行: + ```bash + # Linux/macOS + sudo ./cursor-id-modifier + + # Windows (PowerShell 管理员) + .\cursor-id-modifier.exe + ``` + +#### 手动配置方法 + +1. 完全关闭 Cursor +2. 找到配置文件位置: + - Windows: `%APPDATA%\Cursor\User\globalStorage\storage.json` + - macOS: `~/Library/Application Support/Cursor/User/globalStorage/storage.json` + - Linux: `~/.config/Cursor/User/globalStorage/storage.json` +3. 备份 `storage.json` +4. 编辑 `storage.json` 并更新以下字段(使用新的随机UUID): + ```json + { + "telemetry.machineId": "生成新的uuid", + "telemetry.macMachineId": "生成新的uuid", + "telemetry.devDeviceId": "生成新的uuid", + "telemetry.sqmId": "生成新的uuid", + "lastModified": "2024-01-01T00:00:00.000Z", + "version": "1.0.1" + } + ``` +5. 保存文件并重启 Cursor + ### 🔧 技术细节 -程序修改Cursor的`storage.json`配置文件: +#### 配置文件 +程序修改Cursor的`storage.json`配置文件,位于: - Windows: `%APPDATA%\Cursor\User\globalStorage\` - macOS: `~/Library/Application Support/Cursor/User/globalStorage/` - Linux: `~/.config/Cursor/User/globalStorage/` -生成新的唯一标识符: +#### 修改字段 +工具会生成新的唯一标识符: - `telemetry.machineId` - `telemetry.macMachineId` - `telemetry.devDeviceId` - `telemetry.sqmId` +#### 安全特性 +- 自动备份现有配置 +- 安全的进程终止 +- 原子文件操作 +- 错误处理和回滚 + ## 📄 License MIT License Copyright (c) 2024 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + diff --git a/install.sh b/install.sh deleted file mode 100755 index 08a47ce..0000000 --- a/install.sh +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env bash - -# Error handling -error() { - echo -e "\033[31m\033[1mError:\033[0m $1" >&2 - exit 1 -} - -# Detect platform -OS=$(uname -s | tr '[:upper:]' '[:lower:]') -ARCH=$(uname -m) - -# Get latest version -VERSION=$(curl -sL "https://api.github.com/repos/realies/go-cursor-help/releases/latest" | grep '"tag_name":' | sed -E 's/.*"v([^"]+)".*/\1/') -[ -z "$VERSION" ] && error "Could not determine latest version" - -# Get binary name based on platform -case "$OS" in - linux*) - case "$ARCH" in - x86_64) BINARY="cursor_id_modifier_${VERSION}_linux_amd64" ;; - aarch64|arm64) BINARY="cursor_id_modifier_${VERSION}_linux_arm64" ;; - *) error "Unsupported Linux architecture: $ARCH" ;; - esac - ;; - darwin*) - case "$ARCH" in - x86_64) BINARY="cursor_id_modifier_${VERSION}_darwin_amd64" ;; - arm64) BINARY="cursor_id_modifier_${VERSION}_darwin_arm64" ;; - *) error "Unsupported macOS architecture: $ARCH" ;; - esac - ;; - *) error "Unsupported operating system: $OS" ;; -esac - -# Set up cleanup trap -trap 'rm -f "./${BINARY}"' EXIT - -# Download and run -DOWNLOAD_URL="https://github.com/realies/go-cursor-help/releases/download/v${VERSION}/${BINARY}" -echo "Downloading from: ${DOWNLOAD_URL}" - -# Download with error checking -if ! curl -fL "$DOWNLOAD_URL" -o "./${BINARY}"; then - error "Download failed. HTTP error from GitHub" -fi - -chmod +x "./${BINARY}" -echo "Running cursor-id-modifier..." -sudo "./${BINARY}" diff --git a/scripts/build_all.bat b/scripts/build_all.bat new file mode 100644 index 0000000..0ae443f --- /dev/null +++ b/scripts/build_all.bat @@ -0,0 +1,128 @@ +@echo off +setlocal EnableDelayedExpansion + +:: Messages / 消息 +set "EN_MESSAGES[0]=Starting build process for version" +set "EN_MESSAGES[1]=Using optimization flags:" +set "EN_MESSAGES[2]=Cleaning old builds..." +set "EN_MESSAGES[3]=Cleanup completed" +set "EN_MESSAGES[4]=bin directory does not exist, no cleanup needed" +set "EN_MESSAGES[5]=Starting builds for all platforms..." +set "EN_MESSAGES[6]=Building for" +set "EN_MESSAGES[7]=Build successful:" +set "EN_MESSAGES[8]=Build failed for" +set "EN_MESSAGES[9]=All builds completed! Total time:" +set "EN_MESSAGES[10]=seconds" + +set "CN_MESSAGES[0]=开始构建版本" +set "CN_MESSAGES[1]=使用优化标志:" +set "CN_MESSAGES[2]=正在清理旧的构建文件..." +set "CN_MESSAGES[3]=清理完成" +set "CN_MESSAGES[4]=bin 目录不存在,无需清理" +set "CN_MESSAGES[5]=开始编译所有平台..." +set "CN_MESSAGES[6]=正在构建" +set "CN_MESSAGES[7]=构建成功:" +set "CN_MESSAGES[8]=构建失败:" +set "CN_MESSAGES[9]=所有构建完成!总耗时:" +set "CN_MESSAGES[10]=秒" + +:: 设置版本信息 / Set version +set VERSION=2.0.0 + +:: 设置颜色代码 / Set color codes +set "GREEN=[32m" +set "RED=[31m" +set "YELLOW=[33m" +set "RESET=[0m" + +:: 设置编译优化标志 / Set build optimization flags +set "LDFLAGS=-s -w" +set "BUILDMODE=pie" +set "GCFLAGS=-N -l" + +:: 设置 CGO / Set CGO +set CGO_ENABLED=0 + +:: 检测系统语言 / Detect system language +for /f "tokens=2 delims==" %%a in ('wmic os get OSLanguage /value') do set OSLanguage=%%a +if "%OSLanguage%"=="2052" (set LANG=cn) else (set LANG=en) + +:: 显示编译信息 / Display build info +echo %YELLOW%!%LANG%_MESSAGES[0]! %VERSION%%RESET% +echo %YELLOW%!%LANG%_MESSAGES[1]! LDFLAGS=%LDFLAGS%, BUILDMODE=%BUILDMODE%%RESET% +echo %YELLOW%CGO_ENABLED=%CGO_ENABLED%%RESET% + +:: 清理旧的构建文件 / Clean old builds +echo %YELLOW%!%LANG%_MESSAGES[2]!%RESET% +if exist "..\bin" ( + rd /s /q "..\bin" + echo %GREEN%!%LANG%_MESSAGES[3]!%RESET% +) else ( + echo %YELLOW%!%LANG%_MESSAGES[4]!%RESET% +) + +:: 创建输出目录 / Create output directory +mkdir "..\bin" 2>nul + +:: 定义目标平台数组 / Define target platforms array +set platforms[0].os=windows +set platforms[0].arch=amd64 +set platforms[0].ext=.exe +set platforms[0].suffix= + +set platforms[1].os=darwin +set platforms[1].arch=amd64 +set platforms[1].ext= +set platforms[1].suffix=_intel + +set platforms[2].os=darwin +set platforms[2].arch=arm64 +set platforms[2].ext= +set platforms[2].suffix=_m1 + +set platforms[3].os=linux +set platforms[3].arch=amd64 +set platforms[3].ext= +set platforms[3].suffix= + +:: 设置开始时间 / Set start time +set start_time=%time% + +:: 编译所有目标 / Build all targets +echo !%LANG%_MESSAGES[5]! + +for /L %%i in (0,1,3) do ( + set "os=!platforms[%%i].os!" + set "arch=!platforms[%%i].arch!" + set "ext=!platforms[%%i].ext!" + set "suffix=!platforms[%%i].suffix!" + + echo. + echo !%LANG%_MESSAGES[6]! !os! !arch!... + + set GOOS=!os! + set GOARCH=!arch! + + :: 构建输出文件名 / Build output filename + set "outfile=..\bin\cursor_id_modifier_v%VERSION%_!os!_!arch!!suffix!!ext!" + + :: 执行构建 / Execute build + go build -trimpath -buildmode=%BUILDMODE% -ldflags="%LDFLAGS%" -gcflags="%GCFLAGS%" -o "!outfile!" ..\main.go + + if !errorlevel! equ 0 ( + echo %GREEN%!%LANG%_MESSAGES[7]! !outfile!%RESET% + ) else ( + echo %RED%!%LANG%_MESSAGES[8]! !os! !arch!%RESET% + ) +) + +:: 计算总耗时 / Calculate total time +set end_time=%time% +set /a duration = %end_time:~0,2% * 3600 + %end_time:~3,2% * 60 + %end_time:~6,2% - (%start_time:~0,2% * 3600 + %start_time:~3,2% * 60 + %start_time:~6,2%) + +echo. +echo %GREEN%!%LANG%_MESSAGES[9]! %duration% !%LANG%_MESSAGES[10]!%RESET% +if exist "..\bin" dir /b "..\bin" + +pause +endlocal \ No newline at end of file diff --git a/scripts/build_all.sh b/scripts/build_all.sh new file mode 100644 index 0000000..d7e38a9 --- /dev/null +++ b/scripts/build_all.sh @@ -0,0 +1,155 @@ +#!/bin/bash + +# 设置颜色代码 / Set color codes +GREEN='\033[0;32m' +RED='\033[0;31m' +NC='\033[0m' # No Color / 无颜色 + +# Messages / 消息 +EN_MESSAGES=( + "Starting build process for version" + "Cleaning old builds..." + "Creating bin directory..." + "Failed to create bin directory" + "Building for" + "Successfully built:" + "Failed to build for" + "Build Summary:" + "Successful builds:" + "Failed builds:" + "Generated files:" + "Build process interrupted" + "Error:" +) + +CN_MESSAGES=( + "开始构建版本" + "正在清理旧的构建文件..." + "正在创建bin目录..." + "创建bin目录失败" + "正在构建" + "构建成功:" + "构建失败:" + "构建摘要:" + "成功构建数:" + "失败构建数:" + "生成的文件:" + "构建过程被中断" + "错误:" +) + +# 版本信息 / Version info +VERSION="1.0.0" + +# Detect system language / 检测系统语言 +detect_language() { + if [[ $(locale | grep "LANG=zh_CN") ]]; then + echo "cn" + else + echo "en" + fi +} + +# Get message based on language / 根据语言获取消息 +get_message() { + local index=$1 + local lang=$(detect_language) + + if [[ "$lang" == "cn" ]]; then + echo "${CN_MESSAGES[$index]}" + else + echo "${EN_MESSAGES[$index]}" + fi +} + +# 错误处理函数 / Error handling function +handle_error() { + echo -e "${RED}$(get_message 12) $1${NC}" + exit 1 +} + +# 清理函数 / Cleanup function +cleanup() { + echo "$(get_message 1)" + rm -rf ../bin +} + +# 创建输出目录 / Create output directory +create_output_dir() { + echo "$(get_message 2)" + mkdir -p ../bin || handle_error "$(get_message 3)" +} + +# 构建函数 / Build function +build() { + local os=$1 + local arch=$2 + local suffix=$3 + + echo -e "\n$(get_message 4) $os ($arch)..." + + output_name="../bin/cursor_id_modifier_v${VERSION}_${os}_${arch}${suffix}" + + GOOS=$os GOARCH=$arch go build -o "$output_name" ../main.go + + if [ $? -eq 0 ]; then + echo -e "${GREEN}✓ $(get_message 5) ${output_name}${NC}" + else + echo -e "${RED}✗ $(get_message 6) $os $arch${NC}" + return 1 + fi +} + +# 主函数 / Main function +main() { + # 显示构建信息 / Display build info + echo "$(get_message 0) ${VERSION}" + + # 清理旧文件 / Clean old files + cleanup + + # 创建输出目录 / Create output directory + create_output_dir + + # 定义构建目标 / Define build targets + declare -A targets=( + ["windows_amd64"]=".exe" + ["darwin_amd64"]="" + ["darwin_arm64"]="" + ["linux_amd64"]="" + ) + + # 构建计数器 / Build counters + local success_count=0 + local fail_count=0 + + # 遍历所有目标进行构建 / Build all targets + for target in "${!targets[@]}"; do + os=${target%_*} + arch=${target#*_} + suffix=${targets[$target]} + + if build "$os" "$arch" "$suffix"; then + ((success_count++)) + else + ((fail_count++)) + fi + done + + # 显示构建结果 / Display build results + echo -e "\n$(get_message 7)" + echo -e "${GREEN}$(get_message 8) $success_count${NC}" + if [ $fail_count -gt 0 ]; then + echo -e "${RED}$(get_message 9) $fail_count${NC}" + fi + + # 显示生成的文件列表 / Display generated files + echo -e "\n$(get_message 10)" + ls -1 ../bin +} + +# 捕获错误信号 / Catch error signals +trap 'echo -e "\n${RED}$(get_message 11)${NC}"; exit 1' INT TERM + +# 执行主函数 / Execute main function +main \ No newline at end of file diff --git a/scripts/install.ps1 b/scripts/install.ps1 new file mode 100644 index 0000000..b7101ed --- /dev/null +++ b/scripts/install.ps1 @@ -0,0 +1,216 @@ +# Auto-elevate to admin rights if not already running as admin +if (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) { + Write-Host "Requesting administrator privileges..." + Start-Process powershell.exe "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`"" -Verb RunAs + Exit +} + +# Set TLS to 1.2 / 设置 TLS 为 1.2 +[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 + +# Colors for output / 输出颜色 +$Red = "`e[31m" +$Green = "`e[32m" +$Blue = "`e[36m" +$Yellow = "`e[33m" +$Reset = "`e[0m" + +# Messages / 消息 +$EN_MESSAGES = @( + "Starting installation...", + "Detected architecture:", + "Only 64-bit Windows is supported", + "Latest version:", + "Creating installation directory...", + "Downloading latest release from:", + "Failed to download binary:", + "Downloaded file not found", + "Installing binary...", + "Failed to install binary:", + "Adding to PATH...", + "Cleaning up...", + "Installation completed successfully!", + "You can now use 'cursor-id-modifier' from any terminal (you may need to restart your terminal first)", + "Checking for running Cursor instances...", + "Found running Cursor processes. Attempting to close them...", + "Successfully closed all Cursor instances", + "Failed to close Cursor instances. Please close them manually", + "Backing up storage.json...", + "Backup created at:" +) + +$CN_MESSAGES = @( + "开始安装...", + "检测到架构:", + "仅支持64位Windows系统", + "最新版本:", + "正在创建安装目录...", + "正在从以下地址下载最新版本:", + "下载二进制文件失败:", + "未找到下载的文件", + "正在安装程序...", + "安装二进制文件失败:", + "正在添加到PATH...", + "正在清理...", + "安装成功完成!", + "现在可以在任何终端中使用 'cursor-id-modifier' 了(可能需要重启终端)", + "正在检查运行中的Cursor进程...", + "发现正在运行的Cursor进程,尝试关闭...", + "成功关闭所有Cursor实例", + "无法关闭Cursor实例,请手动关闭", + "正在备份storage.json...", + "备份已创建于:" +) + +# Detect system language / 检测系统语言 +function Get-SystemLanguage { + if ((Get-Culture).Name -like "zh-CN") { + return "cn" + } + return "en" +} + +# Get message based on language / 根据语言获取消息 +function Get-Message($Index) { + $lang = Get-SystemLanguage + if ($lang -eq "cn") { + return $CN_MESSAGES[$Index] + } + return $EN_MESSAGES[$Index] +} + +# Functions for colored output / 彩色输出函数 +function Write-Status($Message) { + Write-Host "${Blue}[*]${Reset} $Message" +} + +function Write-Success($Message) { + Write-Host "${Green}[✓]${Reset} $Message" +} + +function Write-Warning($Message) { + Write-Host "${Yellow}[!]${Reset} $Message" +} + +function Write-Error($Message) { + Write-Host "${Red}[✗]${Reset} $Message" + Exit 1 +} + +# Close Cursor instances / 关闭Cursor实例 +function Close-CursorInstances { + Write-Status (Get-Message 14) + $cursorProcesses = Get-Process "Cursor" -ErrorAction SilentlyContinue + + if ($cursorProcesses) { + Write-Status (Get-Message 15) + try { + $cursorProcesses | ForEach-Object { $_.CloseMainWindow() | Out-Null } + Start-Sleep -Seconds 2 + $cursorProcesses | Where-Object { !$_.HasExited } | Stop-Process -Force + Write-Success (Get-Message 16) + } catch { + Write-Error (Get-Message 17) + } + } +} + +# Backup storage.json / 备份storage.json +function Backup-StorageJson { + Write-Status (Get-Message 18) + $storageJsonPath = "$env:APPDATA\Cursor\User\globalStorage\storage.json" + if (Test-Path $storageJsonPath) { + $backupPath = "$storageJsonPath.backup" + Copy-Item -Path $storageJsonPath -Destination $backupPath -Force + Write-Success "$(Get-Message 19) $backupPath" + } +} + +# Get latest release version from GitHub / 从GitHub获取最新版本 +function Get-LatestVersion { + $repo = "yuaotian/go-cursor-help" + $release = Invoke-RestMethod -Uri "https://api.github.com/repos/$repo/releases/latest" + return $release.tag_name +} + +# Main installation process / 主安装过程 +Write-Status (Get-Message 0) + +# Close any running Cursor instances +Close-CursorInstances + +# Backup storage.json +Backup-StorageJson + +# Get system architecture / 获取系统架构 +$arch = if ([Environment]::Is64BitOperatingSystem) { "amd64" } else { "386" } +Write-Status "$(Get-Message 1) $arch" + +if ($arch -ne "amd64") { + Write-Error (Get-Message 2) +} + +# Get latest version / 获取最新版本 +$version = Get-LatestVersion +Write-Status "$(Get-Message 3) $version" + +# Set up paths / 设置路径 +$installDir = "$env:ProgramFiles\cursor-id-modifier" +$binaryName = "cursor_id_modifier_${version}_windows_amd64.exe" +$downloadUrl = "https://github.com/yuaotian/go-cursor-help/releases/download/$version/$binaryName" +$tempFile = "$env:TEMP\$binaryName" + +# Create installation directory / 创建安装目录 +Write-Status (Get-Message 4) +if (-not (Test-Path $installDir)) { + New-Item -ItemType Directory -Path $installDir -Force | Out-Null +} + +# Download binary / 下载二进制文件 +Write-Status "$(Get-Message 5) $downloadUrl" +try { + Invoke-WebRequest -Uri $downloadUrl -OutFile $tempFile +} catch { + Write-Error "$(Get-Message 6) $_" +} + +# Verify download / 验证下载 +if (-not (Test-Path $tempFile)) { + Write-Error (Get-Message 7) +} + +# Install binary / 安装二进制文件 +Write-Status (Get-Message 8) +try { + Move-Item -Force $tempFile "$installDir\cursor-id-modifier.exe" +} catch { + Write-Error "$(Get-Message 9) $_" +} + +# Add to PATH if not already present / 如果尚未添加则添加到PATH +$userPath = [Environment]::GetEnvironmentVariable("Path", "User") +if ($userPath -notlike "*$installDir*") { + Write-Status (Get-Message 10) + [Environment]::SetEnvironmentVariable( + "Path", + "$userPath;$installDir", + "User" + ) +} + +# Create shortcut in Start Menu / 在开始菜单创建快捷方式 +$startMenuPath = "$env:ProgramData\Microsoft\Windows\Start Menu\Programs\cursor-id-modifier.lnk" +$shell = New-Object -ComObject WScript.Shell +$shortcut = $shell.CreateShortcut($startMenuPath) +$shortcut.TargetPath = "$installDir\cursor-id-modifier.exe" +$shortcut.Save() + +# Cleanup / 清理 +Write-Status (Get-Message 11) +if (Test-Path $tempFile) { + Remove-Item -Force $tempFile +} + +Write-Success (Get-Message 12) +Write-Success (Get-Message 13) +Write-Host "" \ No newline at end of file diff --git a/scripts/install.sh b/scripts/install.sh new file mode 100755 index 0000000..ae2ff6c --- /dev/null +++ b/scripts/install.sh @@ -0,0 +1,251 @@ +#!/bin/bash + +set -e + +# Colors for output / 输出颜色 +RED='\033[0;31m' +GREEN='\033[0;32m' +BLUE='\033[0;36m' +YELLOW='\033[0;33m' +NC='\033[0m' # No Color / 无颜色 + +# Messages / 消息 +EN_MESSAGES=( + "Starting installation..." + "Detected OS:" + "Downloading latest release..." + "URL:" + "Installing binary..." + "Cleaning up..." + "Installation completed successfully!" + "You can now use 'sudo %s' from your terminal" + "Failed to download binary from:" + "Failed to download the binary" + "curl is required but not installed. Please install curl first." + "sudo is required but not installed. Please install sudo first." + "Unsupported operating system" + "Unsupported architecture:" + "Checking for running Cursor instances..." + "Found running Cursor processes. Attempting to close them..." + "Successfully closed all Cursor instances" + "Failed to close Cursor instances. Please close them manually" + "Backing up storage.json..." + "Backup created at:" + "This script requires root privileges. Requesting sudo access..." +) + +CN_MESSAGES=( + "开始安装..." + "检测到操作系统:" + "正在下载最新版本..." + "下载地址:" + "正在安装程序..." + "正在清理..." + "安装成功完成!" + "现在可以在终端中使用 'sudo %s' 了" + "从以下地址下载二进制文件失败:" + "下载二进制文件失败" + "需要 curl 但未安装。请先安装 curl。" + "需要 sudo 但未安装。请先安装 sudo。" + "不支持的操作系统" + "不支持的架构:" + "正在检查运行中的Cursor进程..." + "发现正在运行的Cursor进程,尝试关闭..." + "成功关闭所有Cursor实例" + "无法关闭Cursor实例,请手动关闭" + "正在备份storage.json..." + "备份已创建于:" + "此脚本需要root权限。正在请求sudo访问..." +) + +# Detect system language / 检测系统语言 +detect_language() { + if [[ $(locale | grep "LANG=zh_CN") ]]; then + echo "cn" + else + echo "en" + fi +} + +# Get message based on language / 根据语言获取消息 +get_message() { + local index=$1 + local lang=$(detect_language) + + if [[ "$lang" == "cn" ]]; then + echo "${CN_MESSAGES[$index]}" + else + echo "${EN_MESSAGES[$index]}" + fi +} + +# Print with color / 带颜色打印 +print_status() { + echo -e "${BLUE}[*]${NC} $1" +} + +print_success() { + echo -e "${GREEN}[✓]${NC} $1" +} + +print_warning() { + echo -e "${YELLOW}[!]${NC} $1" +} + +print_error() { + echo -e "${RED}[✗]${NC} $1" + exit 1 +} + +# Check and request root privileges / 检查并请求root权限 +check_root() { + if [ "$EUID" -ne 0 ]; then + print_status "$(get_message 20)" + if command -v sudo >/dev/null 2>&1; then + exec sudo bash "$0" "$@" + else + print_error "$(get_message 11)" + fi + fi +} + +# Close Cursor instances / 关闭Cursor实例 +close_cursor_instances() { + print_status "$(get_message 14)" + + if pgrep -x "Cursor" >/dev/null; then + print_status "$(get_message 15)" + if pkill -x "Cursor" 2>/dev/null; then + sleep 2 + print_success "$(get_message 16)" + else + print_error "$(get_message 17)" + fi + fi +} + +# Backup storage.json / 备份storage.json +backup_storage_json() { + print_status "$(get_message 18)" + local storage_path + + if [ "$(uname)" == "Darwin" ]; then + storage_path="$HOME/Library/Application Support/Cursor/User/globalStorage/storage.json" + else + storage_path="$HOME/.config/Cursor/User/globalStorage/storage.json" + fi + + if [ -f "$storage_path" ]; then + cp "$storage_path" "${storage_path}.backup" + print_success "$(get_message 19) ${storage_path}.backup" + fi +} + +# Detect OS / 检测操作系统 +detect_os() { + if [[ "$OSTYPE" == "darwin"* ]]; then + echo "macos" + elif [[ "$OSTYPE" == "linux-gnu"* ]]; then + echo "linux" + else + print_error "$(get_message 12)" + fi +} + +# Get latest release version from GitHub / 从GitHub获取最新版本 +get_latest_version() { + local repo="yuaotian/go-cursor-help" + curl -s "https://api.github.com/repos/${repo}/releases/latest" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/' +} + +# Get the binary name based on OS and architecture / 根据操作系统和架构获取二进制文件名 +get_binary_name() { + OS=$(detect_os) + ARCH=$(uname -m) + VERSION=$(get_latest_version) + + case "$ARCH" in + x86_64) + echo "cursor_id_modifier_${VERSION}_${OS}_amd64" + ;; + aarch64|arm64) + echo "cursor_id_modifier_${VERSION}_${OS}_arm64" + ;; + *) + print_error "$(get_message 13) $ARCH" + ;; + esac +} + +# Install the binary / 安装二进制文件 +install_binary() { + OS=$(detect_os) + BINARY_NAME=$(get_binary_name) + REPO="yuaotian/go-cursor-help" + VERSION=$(get_latest_version) + DOWNLOAD_URL="https://github.com/${REPO}/releases/download/${VERSION}/${BINARY_NAME}" + TMP_DIR=$(mktemp -d) + FINAL_BINARY_NAME="cursor-id-modifier" + + print_status "$(get_message 2)" + print_status "$(get_message 3) ${DOWNLOAD_URL}" + + if ! curl -L -f "$DOWNLOAD_URL" -o "$TMP_DIR/$BINARY_NAME"; then + print_error "$(get_message 8) $DOWNLOAD_URL" + fi + + if [ ! -f "$TMP_DIR/$BINARY_NAME" ]; then + print_error "$(get_message 9)" + fi + + print_status "$(get_message 4)" + INSTALL_DIR="/usr/local/bin" + + # Create directory if it doesn't exist / 如果目录不存在则创建 + mkdir -p "$INSTALL_DIR" + + # Move binary to installation directory / 移动二进制文件到安装目录 + mv "$TMP_DIR/$BINARY_NAME" "$INSTALL_DIR/$FINAL_BINARY_NAME" + chmod +x "$INSTALL_DIR/$FINAL_BINARY_NAME" + + # Cleanup / 清理 + print_status "$(get_message 5)" + rm -rf "$TMP_DIR" + + print_success "$(get_message 6)" + printf "${GREEN}[✓]${NC} $(get_message 7)\n" "$FINAL_BINARY_NAME" +} + +# Check for required tools / 检查必需工具 +check_requirements() { + if ! command -v curl >/dev/null 2>&1; then + print_error "$(get_message 10)" + fi + + if ! command -v sudo >/dev/null 2>&1; then + print_error "$(get_message 11)" + fi +} + +# Main installation process / 主安装过程 +main() { + print_status "$(get_message 0)" + + # Check root privileges / 检查root权限 + check_root "$@" + + # Close Cursor instances / 关闭Cursor实例 + close_cursor_instances + + # Backup storage.json / 备份storage.json + backup_storage_json + + OS=$(detect_os) + print_status "$(get_message 1) $OS" + + check_requirements + install_binary +} + +# Run main function / 运行主函数 +main "$@" \ No newline at end of file