CursorPro 后台管理系统 v1.0

功能:
- 激活码管理 (Pro/Auto 两种类型)
- 账号池管理
- 设备绑定记录
- 使用日志
- 搜索/筛选功能
- 禁用/启用功能 (支持退款参考)
- 全局设置 (换号间隔、额度消耗等)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
ccdojox-crypto
2025-12-16 20:54:44 +08:00
commit 9e2333c90c
62 changed files with 9567 additions and 0 deletions

228
extension/LICENSE.txt Normal file
View File

@@ -0,0 +1,228 @@
MIT License
Copyright (c) 2024 CursorPro
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.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

5
extension/media/icon.svg Normal file
View File

@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M12 2L2 7l10 5 10-5-10-5z"/>
<path d="M2 17l10 5 10-5"/>
<path d="M2 12l10 5 10-5"/>
</svg>

After

Width:  |  Height:  |  Size: 266 B

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

76
extension/package.json Normal file
View File

@@ -0,0 +1,76 @@
{
"name": "cursorpro",
"displayName": "CursorPro",
"description": "Cursor 账号管理与换号工具",
"version": "0.4.5",
"publisher": "cursorpro",
"repository": {
"type": "git",
"url": "https://github.com/cursorpro/cursorpro-extension"
},
"engines": {
"vscode": "^1.80.0"
},
"categories": [
"Other"
],
"extensionKind": [
"ui"
],
"activationEvents": [
"onStartupFinished"
],
"main": "./out/extension.js",
"contributes": {
"commands": [
{
"command": "cursorpro.showPanel",
"title": "CursorPro: 打开控制面板"
},
{
"command": "cursorpro.switchAccount",
"title": "CursorPro: 立即换号"
}
],
"viewsContainers": {
"activitybar": [
{
"id": "cursorpro-sidebar",
"title": "CursorPro",
"icon": "media/icon.svg"
}
]
},
"views": {
"cursorpro-sidebar": [
{
"type": "webview",
"id": "cursorpro.mainView",
"name": "控制面板"
}
]
},
"configuration": {
"title": "CursorPro",
"properties": {
"cursorpro.cursorPath": {
"type": "string",
"default": "",
"description": "手动设置 Cursor 安装路径如果自动检测失败。例如C:\\Program Files\\cursor 或 /Applications/Cursor.app"
}
}
}
},
"scripts": {
"vscode:prepublish": "npm run compile",
"compile": "tsc -p ./",
"watch": "tsc -watch -p ./",
"lint": "eslint src --ext ts"
},
"devDependencies": {
"@types/node": "^20.0.0",
"@types/vscode": "^1.80.0",
"esbuild": "^0.27.0",
"typescript": "^5.0.0"
}
}

View File

@@ -0,0 +1,280 @@
#!/bin/bash
# ==============================================
# CursorPro - macOS 机器码重置脚本
# 一次授权,永久免密
# 纯 Shell 实现,不依赖 Python
# ==============================================
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# 路径定义
CURSOR_APP="/Applications/Cursor.app"
CURSOR_OUT="$CURSOR_APP/Contents/Resources/app/out"
MAIN_JS="$CURSOR_OUT/main.js"
UUID_PLIST="/Library/Preferences/SystemConfiguration/com.apple.platform.uuid.plist"
# 用户数据路径
USER_HOME="$HOME"
CURSOR_DATA="$USER_HOME/Library/Application Support/Cursor"
STORAGE_JSON="$CURSOR_DATA/User/globalStorage/storage.json"
STATE_VSCDB="$CURSOR_DATA/User/globalStorage/state.vscdb"
MACHINEID_FILE="$CURSOR_DATA/machineid"
# 备份目录
BACKUP_DIR="$USER_HOME/CursorPro_backups"
echo ""
echo -e "${BLUE}======================================${NC}"
echo -e "${BLUE} CursorPro macOS 机器码重置工具${NC}"
echo -e "${BLUE}======================================${NC}"
echo ""
# 检查 Cursor 是否安装
if [ ! -d "$CURSOR_APP" ]; then
echo -e "${RED}错误: 未找到 Cursor 应用${NC}"
echo "请确保 Cursor 安装在 /Applications/Cursor.app"
exit 1
fi
# 创建备份目录
mkdir -p "$BACKUP_DIR" 2>/dev/null
# ============================================
# 第一步:检测并设置权限(一次性)
# ============================================
echo -e "${YELLOW}[步骤 1/7] 检查权限...${NC}"
NEED_SUDO=false
# 检查 main.js 权限
if [ ! -w "$MAIN_JS" ] 2>/dev/null; then
NEED_SUDO=true
echo " - main.js: 需要授权"
else
echo -e " - main.js: ${GREEN}已有权限${NC}"
fi
# 检查 UUID plist 权限(文件可能不存在)
if [ -f "$UUID_PLIST" ]; then
if [ ! -w "$UUID_PLIST" ] 2>/dev/null; then
NEED_SUDO=true
echo " - UUID plist: 需要授权"
else
echo -e " - UUID plist: ${GREEN}已有权限${NC}"
fi
else
echo -e " - UUID plist: ${YELLOW}文件不存在,跳过${NC}"
fi
# 如果需要授权
if [ "$NEED_SUDO" = true ]; then
echo ""
echo -e "${YELLOW}首次运行,需要管理员权限${NC}"
echo -e "${YELLOW}授权后以后重置不再需要输入密码${NC}"
echo ""
# 请求 sudo 权限
sudo -v || { echo -e "${RED}授权失败${NC}"; exit 1; }
# 修改 Cursor 目录权限
if [ ! -w "$MAIN_JS" ] 2>/dev/null; then
echo " 正在修改 Cursor 目录权限..."
sudo chown -R $(whoami) "$CURSOR_OUT" 2>/dev/null || true
sudo chmod -R u+rw "$CURSOR_OUT" 2>/dev/null || true
echo -e " ${GREEN}✓ Cursor 目录权限已修改${NC}"
fi
# 修改 UUID plist 权限(如果文件存在)
if [ -f "$UUID_PLIST" ] && [ ! -w "$UUID_PLIST" ] 2>/dev/null; then
echo " 正在修改 UUID plist 权限..."
sudo chown $(whoami) "$UUID_PLIST" 2>/dev/null || true
echo -e " ${GREEN}✓ UUID plist 权限已修改${NC}"
fi
echo ""
echo -e "${GREEN}✓ 权限设置完成!以后重置不再需要密码${NC}"
fi
echo ""
# ============================================
# 第二步:关闭 Cursor
# ============================================
echo -e "${YELLOW}[步骤 2/7] 关闭 Cursor...${NC}"
if pgrep -x "Cursor" > /dev/null; then
killall Cursor 2>/dev/null || true
echo " 等待 Cursor 完全退出..."
sleep 3
echo -e " ${GREEN}✓ Cursor 已关闭${NC}"
else
echo -e " ${GREEN}✓ Cursor 未运行${NC}"
fi
echo ""
# ============================================
# 第三步Patch main.js
# ============================================
echo -e "${YELLOW}[步骤 3/7] Patch main.js...${NC}"
if [ ! -f "$MAIN_JS" ]; then
echo -e " ${RED}警告: 未找到 main.js${NC}"
else
# 检查是否已经 patch 过
if grep -q 'uuidgen' "$MAIN_JS" 2>/dev/null; then
echo -e " ${GREEN}✓ main.js 已经 Patch 过,跳过${NC}"
else
# 检查目标字符串
if grep -q 'ioreg -rd1 -c IOPlatformExpertDevice' "$MAIN_JS"; then
# 备份到用户目录
BACKUP_FILE="$BACKUP_DIR/main.js.backup_$(date +%s)"
cp "$MAIN_JS" "$BACKUP_FILE" 2>/dev/null
if [ $? -eq 0 ]; then
echo " 备份已创建: $BACKUP_FILE"
fi
# 使用 perl 替换macOS 自带,比 sed 更可靠处理特殊字符)
perl -i -pe 's/ioreg -rd1 -c IOPlatformExpertDevice/UUID=\$(uuidgen | tr '"'"'[:upper:]'"'"' '"'"'[:lower:]'"'"');echo "IOPlatformUUID = "\$UUID";/g' "$MAIN_JS" 2>/dev/null
if [ $? -eq 0 ]; then
echo -e " ${GREEN}✓ main.js Patch 成功${NC}"
else
echo -e " ${RED}✗ main.js Patch 失败${NC}"
fi
else
echo -e " ${YELLOW}警告: 未找到目标字符串,可能已 patch 或版本不兼容${NC}"
fi
fi
fi
echo ""
# ============================================
# 第四步:重置系统 UUID
# ============================================
echo -e "${YELLOW}[步骤 4/7] 重置系统 UUID...${NC}"
if [ ! -f "$UUID_PLIST" ]; then
echo -e " ${YELLOW}提示: UUID plist 文件不存在,跳过${NC}"
else
NEW_SYS_UUID=$(uuidgen | tr '[:upper:]' '[:lower:]')
/usr/libexec/PlistBuddy -c "Set :IOPlatformUUID $NEW_SYS_UUID" "$UUID_PLIST" 2>/dev/null || \
/usr/libexec/PlistBuddy -c "Add :IOPlatformUUID string $NEW_SYS_UUID" "$UUID_PLIST" 2>/dev/null || true
echo -e " ${GREEN}✓ 系统 UUID 已重置: $NEW_SYS_UUID${NC}"
fi
echo ""
# ============================================
# 第五步:重置 storage.json
# ============================================
echo -e "${YELLOW}[步骤 5/7] 重置 storage.json...${NC}"
# 生成新的机器码64位十六进制
NEW_MACHINE_ID=$(uuidgen | tr -d '-' | tr '[:upper:]' '[:lower:]')$(uuidgen | tr -d '-' | tr '[:upper:]' '[:lower:]')
NEW_MAC_MACHINE_ID=$(uuidgen | tr -d '-' | tr '[:upper:]' '[:lower:]')$(uuidgen | tr -d '-' | tr '[:upper:]' '[:lower:]')
NEW_DEV_DEVICE_ID=$(uuidgen | tr '[:upper:]' '[:lower:]')
NEW_SQM_ID="{$(uuidgen | tr '[:lower:]' '[:upper:]')}"
if [ -f "$STORAGE_JSON" ]; then
# 备份
cp "$STORAGE_JSON" "$BACKUP_DIR/storage.json.backup_$(date +%s)" 2>/dev/null
# 使用 sed 替换 JSON 中的值macOS sed 语法)
# machineId
sed -i '' "s/\"telemetry\.machineId\"[[:space:]]*:[[:space:]]*\"[^\"]*\"/\"telemetry.machineId\": \"$NEW_MACHINE_ID\"/g" "$STORAGE_JSON" 2>/dev/null
# macMachineId
sed -i '' "s/\"telemetry\.macMachineId\"[[:space:]]*:[[:space:]]*\"[^\"]*\"/\"telemetry.macMachineId\": \"$NEW_MAC_MACHINE_ID\"/g" "$STORAGE_JSON" 2>/dev/null
# devDeviceId
sed -i '' "s/\"telemetry\.devDeviceId\"[[:space:]]*:[[:space:]]*\"[^\"]*\"/\"telemetry.devDeviceId\": \"$NEW_DEV_DEVICE_ID\"/g" "$STORAGE_JSON" 2>/dev/null
# sqmId
sed -i '' "s/\"telemetry\.sqmId\"[[:space:]]*:[[:space:]]*\"[^\"]*\"/\"telemetry.sqmId\": \"$NEW_SQM_ID\"/g" "$STORAGE_JSON" 2>/dev/null
echo -e " ${GREEN}✓ storage.json 已更新 (4个ID)${NC}"
else
echo -e " ${YELLOW}警告: 未找到 storage.json${NC}"
fi
echo ""
# ============================================
# 第六步:重置 SQLite 数据库
# ============================================
echo -e "${YELLOW}[步骤 6/7] 重置 SQLite 数据库...${NC}"
NEW_SERVICE_MACHINE_ID=$(uuidgen | tr '[:upper:]' '[:lower:]')
if [ -f "$STATE_VSCDB" ]; then
# 备份
cp "$STATE_VSCDB" "$BACKUP_DIR/state.vscdb.backup_$(date +%s)" 2>/dev/null
# 使用 sqlite3 命令macOS 自带)
sqlite3 "$STATE_VSCDB" "UPDATE ItemTable SET value = '$NEW_SERVICE_MACHINE_ID' WHERE key = 'storage.serviceMachineId';" 2>/dev/null
if [ $? -eq 0 ]; then
echo -e " ${GREEN}✓ state.vscdb 已更新 (serviceMachineId)${NC}"
else
# 如果更新失败,尝试插入
sqlite3 "$STATE_VSCDB" "INSERT OR REPLACE INTO ItemTable (key, value) VALUES ('storage.serviceMachineId', '$NEW_SERVICE_MACHINE_ID');" 2>/dev/null
echo -e " ${GREEN}✓ state.vscdb 已更新${NC}"
fi
else
echo -e " ${YELLOW}警告: 未找到 state.vscdb${NC}"
fi
# 更新 machineid 文件
echo ""
if [ -d "$(dirname "$MACHINEID_FILE")" ]; then
echo "${NEW_MACHINE_ID:0:64}" > "$MACHINEID_FILE"
echo -e " ${GREEN}✓ machineid 文件已更新${NC}"
else
echo -e " ${YELLOW}警告: 未找到 machineid 目录${NC}"
fi
# 清理缓存
rm -rf "$CURSOR_DATA/Cache" 2>/dev/null || true
rm -rf "$CURSOR_DATA/CachedData" 2>/dev/null || true
rm -rf "$CURSOR_DATA/GPUCache" 2>/dev/null || true
echo -e " ${GREEN}✓ 缓存已清理${NC}"
echo ""
# ============================================
# 第七步:重新打开 Cursor
# ============================================
echo -e "${YELLOW}[步骤 7/7] 重新打开 Cursor...${NC}"
sleep 1
open "$CURSOR_APP"
echo -e " ${GREEN}✓ Cursor 已启动${NC}"
echo ""
echo -e "${GREEN}======================================${NC}"
echo -e "${GREEN} ✅ 机器码重置完成!${NC}"
echo -e "${GREEN}======================================${NC}"
echo ""
echo "已重置的内容:"
echo " ✓ main.js (ioreg patch)"
echo " ✓ storage.json (4个ID)"
echo " ✓ state.vscdb (serviceMachineId)"
echo " ✓ machineid 文件"
echo " ✓ 缓存已清理"
echo ""
echo "新机器码信息:"
echo " machineId: ${NEW_MACHINE_ID:0:32}..."
echo " devDeviceId: $NEW_DEV_DEVICE_ID"
echo " serviceMachineId: $NEW_SERVICE_MACHINE_ID"
echo ""
echo "备份位置: $BACKUP_DIR"
echo ""
echo -e "${BLUE}此窗口可以关闭${NC}"
echo ""