'use strict'; var __createBinding = this && this.__createBinding || (Object.create ? function (param0, param1, param2, param3) { if (param3 === undefined) { param3 = param2; } var descriptor = Object.getOwnPropertyDescriptor(param1, param2); if (!descriptor || ("get" in descriptor ? !param1.__esModule : descriptor.writable || descriptor.configurable)) { descriptor = { enumerable: true, get: function () { return param1[param2]; } }; } Object.defineProperty(param0, param3, descriptor); } : function (param0, param1, param2, param3) { if (param3 === undefined) { param3 = param2; } param0[param3] = param1[param2]; }); var __setModuleDefault = this && this.__setModuleDefault || (Object.create ? function (param0, param1) { Object.defineProperty(param0, "default", { enumerable: true, value: param1 }); } : function (param0, param1) { param0.default = param1; }); var __importStar = this && this.__importStar || function () { var getOwnPropNames = function (param0) { getOwnPropNames = Object.getOwnPropertyNames || function (param0) { var items = []; for (var propKey in param0) if (Object.prototype.hasOwnProperty.call(param0, propKey)) { items[items.length] = propKey; } return items; }; return getOwnPropNames(param0); }; return function (param0) { if (param0 && param0.__esModule) { return param0; } var obj = {}; if (param0 != null) { var items = getOwnPropNames(param0); for (var count = 0; count < items.length; count++) { if (items[count] !== "default") { __createBinding(obj, param0, items[count]); } } } __setModuleDefault(obj, param0); return obj; }; }(); Object.defineProperty(exports, '__esModule', { value: true }); exports.CursorProViewProvider = undefined; const vscode = __importStar(require("vscode")); const client_1 = require("../api/client"); const extension_1 = require("../extension"); const account_1 = require('../utils/account'); const path = __importStar(require("path")); const fs = __importStar(require('fs')); const child_process_1 = require('child_process'); const util_1 = require("util"); const sqlite_1 = require('../utils/sqlite'); const execAsync = util_1.promisify(child_process_1.exec); class CursorProViewProvider { constructor(extensionUri, context) { this._extensionUri = extensionUri; this._context = context; this._hostsPermissionGranted = false; this.SNI_PROXY_IP = "154.36.154.163"; this.CURSOR_DOMAINS = ["api2.cursor.sh", "api3.cursor.sh"]; this.HOSTS_MARKER_START = "# ===== CursorPro SNI Proxy Start ====="; this.HOSTS_MARKER_END = "# ===== CursorPro SNI Proxy End ====="; this._cachedCursorPath = null; this._onlineStatusUnsubscribe = client_1.onOnlineStatusChange(status => { this._postMessage({ 'type': "networkStatus", 'online': status }); }); } resolveWebviewView(webviewView, context, token) { this._view = webviewView; webviewView.webview.options = { 'enableScripts': true, 'localResourceRoots': [this._extensionUri] }; webviewView.webview.html = this._getHtmlContent(webviewView.webview); webviewView.webview.onDidReceiveMessage(async msg => { const config = { 'WZyWQ': "娌℃湁鍐欏叆鏉冮檺", 'ZXhkG': "seamlessRestored" }; switch (msg.type) { case "activate": await this._handleActivate(msg.key); break; case "switch": await this._handleSwitch(); break; case "resetMachineId": await this._handleResetMachineId(); break; case "disableUpdate": await this._handleDisableUpdate(); break; case "cleanEnv": await this._handleCleanEnv(); break; case "disable": await this._handleDisable(); break; case "toggleProxy": await this._handleToggleProxy(msg.enabled, msg.url); break; case 'getProxyStatus': await this._handleGetProxyStatus(); break; case "getState": await this._sendState(); break; case "retryConnect": await this._handleRetryConnect(); break; case "getSeamlessStatus": await this._handleGetSeamlessStatus(); break; case "injectSeamless": await this._handleInjectSeamless(); break; case "restoreSeamless": await this._handleRestoreSeamless(); break; case "toggleSeamless": await this._handleToggleSeamless(msg.enabled); break; case "getUserSwitchStatus": await this._handleGetUserSwitchStatus(); break; case "manualSeamlessSwitch": await this._handleManualSeamlessSwitch(); break; case "checkUsageBeforeSwitch": await this._handleCheckUsageBeforeSwitch(msg.email); break; case "confirmSwitch": await this._handleManualSeamlessSwitch(); break; case "getCursorPath": await this._handleGetCursorPath(); break; case 'getAccountUsage': await this._handleGetAccountUsage(msg.email); break; case "getAnnouncement": await this._handleGetAnnouncement(); break; case "checkVersion": await this._handleCheckVersion(); break; case "getCursorRunningPath": await this._handleGetCursorRunningPath(); break; case "reloadWindow": vscode.commands.executeCommand("workbench.action.reloadWindow"); break; case 'closeCursor': await account_1.closeCursor(); break; } }); this._sendState(); this._checkKeyStatus(); } async _checkKeyStatus() { const savedKey = this._context.globalState.get("cursorpro.key"); if (!savedKey) { return; } try { const verifyResult = await client_1.verifyKey(savedKey); if (verifyResult.success && verifyResult.valid) { await this._context.globalState.update("cursorpro.expireDate", verifyResult.expire_date); await this._context.globalState.update("cursorpro.switchRemaining", verifyResult.switch_remaining); await this._context.globalState.update("cursorpro.switchLimit", verifyResult.switch_limit); this._postMessage({ 'type': "keyStatusChecked", 'valid': true, 'expireDate': verifyResult.expire_date, 'switchRemaining': verifyResult.switch_remaining, 'switchLimit': verifyResult.switch_limit }); } else { this._postMessage({ 'type': "keyStatusChecked", 'valid': false, 'expired': true, 'error': verifyResult.error || "婵€娲荤爜宸茶繃鏈熸垨鏃犳晥" }); } } catch (modErr) { console.error("[CursorPro] 妫€鏌ユ縺娲荤爜鐘舵€佸け璐?", modErr); } } async _handleActivate(key) { try { const isSeamlessInjected = await this._isSeamlessInjected(); if (isSeamlessInjected) { this._postMessage({ 'type': "activated", 'success': false, 'error': "???????????????????" }); return; } this._cleanProxySettings(); const verifyResult = await client_1.verifyKey(key); if (verifyResult.success && verifyResult.valid) { console.log("[CursorPro] 婵€娲绘垚鍔燂紝鍚庣杩斿洖:", { 'expire_date': verifyResult.expire_date, 'switch_remaining': verifyResult.switch_remaining, 'switch_limit': verifyResult.switch_limit }); await this._context.globalState.update("cursorpro.key", key); await this._context.globalState.update("cursorpro.expireDate", verifyResult.expire_date); await this._context.globalState.update("cursorpro.switchRemaining", verifyResult.switch_remaining); await this._context.globalState.update("cursorpro.switchLimit", verifyResult.switch_limit); this._postMessage({ 'type': "activated", 'success': true, 'key': key, 'expireDate': verifyResult.expire_date, 'switchRemaining': verifyResult.switch_remaining, 'switchLimit': verifyResult.switch_limit }); extension_1.showStatusBar(); await this._handleGetUserSwitchStatus(); } else { this._postMessage({ 'type': "activated", 'success': false, 'error': verifyResult.error || "鎺堟潈鐮佹棤鏁? }); } } catch (activateErr) { this._postMessage({ 'type': "activated", 'success': false, 'error': "杩炴帴鏈嶅姟鍣ㄥけ璐? }); } } async _handleSwitch() { const savedKey = this._context.globalState.get("cursorpro.key"); if (!savedKey) { this._postMessage({ 'type': "showToast", 'message': "璇峰厛婵€娲绘巿鏉冪爜", 'icon': '鈿狅笍' }); return; } try { const switchResult = await client_1.switchSeamlessToken(savedKey); if (switchResult.switched) { await this._context.globalState.update("cursorpro.switchRemaining", switchResult.switchRemaining); this._postMessage({ 'type': "switched", 'success': true, 'email': switchResult.email, 'switchRemaining': switchResult.switchRemaining, 'switchLimit': this._context.globalState.get("cursorpro.switchLimit") || 100 }); const condition = switchResult.switchRemaining ?? 0; this._postMessage({ 'type': "userSwitchStatus", 'switchRemaining': condition, 'canSwitch': condition > 0, 'lockedAccount': switchResult.email ? { 'email': switchResult.email } : null }); } else { this._postMessage({ 'type': "switched", 'success': false, 'error': switchResult.message || '鎹㈠彿澶辫触' }); } } catch (switchErr) { this._postMessage({ 'type': 'switched', 'success': false, 'error': "杩炴帴鏈嶅姟鍣ㄥけ璐? }); } } async _writeAccountToLocal(accountData) { try { const condition = process.env.APPDATA || ''; const joinedPath = path.join(condition, "Cursor", "User", "globalStorage", "state.vscdb"); const joinedPath1 = path.join(condition, "Cursor", "User", "globalStorage", 'storage.json'); const joinedPath2 = path.join(condition, "Cursor", "machineid"); if (fs.existsSync(joinedPath)) { const items = []; if (accountData.accessToken) { items.push(["cursorAuth/accessToken", accountData.accessToken]); } if (accountData.refreshToken) { items.push(["cursorAuth/refreshToken", accountData.refreshToken]); } if (accountData.email) { items.push(["cursorAuth/cachedEmail", accountData.email]); } if (accountData.membership_type) { items.push(["cursorAuth/stripeMembershipType", accountData.membership_type]); } if (accountData.sign_up_type) { items.push(["cursorAuth/cachedSignUpType", accountData.sign_up_type]); } if (accountData.serviceMachineId) { items.push(["storage.serviceMachineId", accountData.serviceMachineId]); } await sqlite_1.sqliteSetBatch(joinedPath, items); console.log("[CursorPro] SQLite 鏁版嵁搴撳凡鏇存柊"); } if (fs.existsSync(joinedPath1)) { const parsed = JSON.parse(fs.readFileSync(joinedPath1, 'utf-8')); if (accountData.machineId) { parsed["telemetry.machineId"] = accountData.machineId; } if (accountData.macMachineId) { parsed['telemetry.macMachineId'] = accountData.macMachineId; } if (accountData.devDeviceId) { parsed["telemetry.devDeviceId"] = accountData.devDeviceId; } if (accountData.sqmId) { parsed["telemetry.sqmId"] = accountData.sqmId; } fs.writeFileSync(joinedPath1, JSON.stringify(parsed, null, 4)); console.log("[CursorPro] storage.json 宸叉洿鏂?); } if (accountData.machineId) { fs.writeFileSync(joinedPath2, accountData.machineId); console.log("[CursorPro] machineid 鏂囦欢宸叉洿鏂?); } if (accountData.registryGuid && process.platform === "win32") { try { const result = 'reg add "HKLM\SOFTWARE\Microsoft\Cryptography" /v MachineGuid /t REG_SZ /d "' + accountData.registryGuid + '" /f'; await execAsync(result); console.log("[CursorPro] 娉ㄥ唽琛?MachineGuid 宸叉洿鏂?); } catch (parseErr) { console.warn("[CursorPro] 娉ㄥ唽琛ㄥ啓鍏ュけ璐ワ紙鍙兘闇€瑕佺鐞嗗憳鏉冮檺锛?", parseErr); } } return true; } catch (writeErr) { console.error("[CursorPro] 鍐欏叆鏈湴澶辫触:", strIdx); vscode.window.showErrorMessage("鍐欏叆澶辫触: " + strIdx); return false; } } async _handleReset() { await this._context.globalState.update("cursorpro.key", undefined); await this._context.globalState.update("cursorpro.expireDate", undefined); await this._context.globalState.update("cursorpro.switchRemaining", undefined); extension_1.hideStatusBar(); this._postMessage({ 'type': 'reset', 'success': true }); vscode.window.showInformationMessage("鎻掍欢宸查噸缃?); } async _handleDisable() { await this._handleReset(); vscode.window.showInformationMessage("鎻掍欢宸插仠鐢?); } async _checkAdminPrivilege() { if (process.platform !== "win32") { return true; } try { await execAsync('reg query "HKLM\SOFTWARE\Microsoft\Cryptography" /v MachineGuid 2>nul'); const hostEntry = await execAsync("net session 2>nul").catch(() => ({ 'stdout': '', 'stderr': 'error' })); return !hostEntry.stderr; } catch (jsonErr) { return false; } } async _handleResetMachineId() { try { const platform = process.platform; if (platform === 'win32') { const adminprivilegeResult = await this._checkAdminPrivilege(); if (!adminprivilegeResult) { this._postMessage({ 'type': "adminPermissionRequired" }); return; } } const hostLine = account_1.getCursorPaths(); const { dbPath: charIdx, storagePath: lineItem, machineidPath: lineIdx } = hostLine; const module = require("crypto"); const str = module.randomBytes(32).toString("hex"); const str1 = module.randomBytes(32).toString("hex"); const proxyLine = module.randomUUID(); const result = '{' + module.randomUUID().toUpperCase() + '}'; let count = 0; let items = []; if (fs.existsSync(lineItem)) { let num = 3; while (num > 0) { try { const parsed = JSON.parse(fs.readFileSync(lineItem, "utf-8")); parsed["telemetry.machineId"] = str; parsed["telemetry.macMachineId"] = str1; parsed["telemetry.devDeviceId"] = proxyLine; parsed["telemetry.sqmId"] = result; fs.writeFileSync(lineItem, JSON.stringify(parsed, null, 4)); console.log("[CursorPro] storage.json 宸叉洿鏂?); count++; break; } catch (readErr) { num--; if (num === 0) { console.warn("[CursorPro] storage.json 鏇存柊澶辫触:", readErr.message); items.push("storage.json"); } else { await new Promise(param0 => setTimeout(param0, 100)); } } } } { let num = 3; while (num > 0) { try { const dirPath = path.dirname(lineIdx); if (!fs.existsSync(dirPath)) { fs.mkdirSync(dirPath, { 'recursive': true }); } fs.writeFileSync(lineIdx, str); console.log("[CursorPro] machineid 鏂囦欢宸叉洿鏂?); count++; break; } catch (writeErr) { num--; if (num === 0) { console.warn("[CursorPro] machineid 鏇存柊澶辫触:", writeErr.message); items.push("machineid"); } else { await new Promise(param0 => setTimeout(param0, 100)); } } } } if (fs.existsSync(charIdx)) { let num = 3; while (num > 0) { try { const proxyEntry = module.randomUUID(); const newHostsContent = await sqlite_1.sqliteSetBatch(charIdx, [['storage.serviceMachineId', proxyEntry]]); if (newHostsContent) { console.log("[CursorPro] SQLite 鏁版嵁搴撳凡鏇存柊"); count++; break; } else { throw new Error("sqliteSetBatch 杩斿洖 false"); } } catch (grantErr) { num--; if (num === 0) { console.warn("[CursorPro] SQLite 鏇存柊澶辫触:", grantErr.message); items.push("SQLite"); } else { await new Promise(param0 => setTimeout(param0, 500)); } } } } if (platform === "win32") { const hostsLines = module.randomUUID(); try { await execAsync('reg add "HKLM\SOFTWARE\Microsoft\Cryptography" /v MachineGuid /t REG_SZ /d "' + hostsLines + '" /f'); console.log("[CursorPro] 娉ㄥ唽琛?MachineGuid 宸叉洿鏂?); count++; } catch (regWriteErr) { console.warn("[CursorPro] 娉ㄥ唽琛ㄦ洿鏂板け璐ワ紙闇€瑕佺鐞嗗憳鏉冮檺锛夛紝宸茶烦杩?); items.push("娉ㄥ唽琛?); } } if (count >= 2) { this._postMessage({ 'type': "machineIdReset", 'success': true, 'needRestart': true, 'message': items.length > 0 ? "鏈哄櫒鐮侀噸缃垚鍔燂紙" + items.join(", ") + " 鏇存柊澶辫触锛屼笉褰卞搷浣跨敤锛? : "鏈哄櫒鐮侀噸缃垚鍔? }); } else { this._postMessage({ 'type': "showToast", 'message': "閲嶇疆閮ㄥ垎澶辫触: " + items.join(", ") + "銆傝鍏堝畬鍏ㄥ叧闂?Cursor 鍐嶈瘯", 'icon': '鈿狅笍' }); } } catch (hostsErr) { this._postMessage({ 'type': "showToast", 'message': "閲嶇疆鏈哄櫒鐮佸け璐? " + hostsErr, 'icon': '鉂? }); } } _generateRandomMAC() { const module = require("crypto"); const dbPath = module.randomBytes(6); dbPath[0] = (dbPath[0] | 2) & 254; return Array.from(dbPath).map(item => item.toString(16).padStart(2, '0')).join(':'); } async _handleDisableUpdate() { try { const condition = process.env.LOCALAPPDATA || ''; const joinedPath = path.join(condition, "cursor-updater"); if (fs.existsSync(joinedPath)) { if (fs.statSync(joinedPath).isDirectory()) { fs.rmSync(joinedPath, { 'recursive': true, 'force': true }); } else { fs.unlinkSync(joinedPath); } } fs.writeFileSync(joinedPath, ''); this._postMessage({ 'type': 'showToast', 'message': "宸茬鐢?Cursor 鑷姩鏇存柊", 'icon': '鉁? }); } catch (toggleErr) { this._postMessage({ 'type': "showToast", 'message': "绂佺敤鑷姩鏇存柊澶辫触: " + toggleErr, 'icon': '鉂? }); } } async _handleCleanEnv() { try { if (process.platform === "win32") { await execAsync("taskkill /F /IM Cursor.exe").catch(() => {}); } else { await execAsync("pkill -f Cursor").catch(() => {}); } await new Promise(param0 => setTimeout(param0, 2000)); const condition = process.env.APPDATA || ''; const condition1 = process.env.LOCALAPPDATA || ''; const condition2 = process.env.HOME || process.env.USERPROFILE || ''; let count = 0; if (process.platform === "win32") { const items = [path.join(condition, "Cursor"), path.join(condition1, "Cursor"), path.join(condition1, "cursor-updater"), path.join(condition2, ".cursor")]; for (const macPath of items) { try { if (fs.existsSync(macPath)) { fs.rmSync(macPath, { 'recursive': true, 'force': true }); count++; console.log("[CursorPro] 宸叉竻鐞? " + macPath); } } catch (statusErr) { console.warn("[CursorPro] 娓呯悊澶辫触: " + macPath, statusErr); } } } else { if (process.platform === "darwin") { const items = [path.join(condition2, "Library", "Application Support", "Cursor"), path.join(condition2, "Library", "Caches", "Cursor"), path.join(condition2, "Library", "Logs", "Cursor"), path.join(condition2, 'Library', "Application Support", 'Caches', "cursor-updater"), path.join(condition2, ".cursor")]; for (const storagePath of items) { try { if (fs.existsSync(storagePath)) { fs.rmSync(storagePath, { 'recursive': true, 'force': true }); count++; } } catch (pathErr) { console.warn("[CursorPro] 娓呯悊澶辫触: " + storagePath, pathErr); } } } else { const items = [path.join(condition2, ".config", "Cursor"), path.join(condition2, ".cache", "Cursor"), path.join(condition2, ".local", "share", "Cursor"), path.join(condition2, ".cursor")]; for (const machineIdPath of items) { try { if (fs.existsSync(machineIdPath)) { fs.rmSync(machineIdPath, { 'recursive': true, 'force': true }); count++; } } catch (seamlessErr) { console.warn("[CursorPro] 娓呯悊澶辫触: " + machineIdPath, seamlessErr); } } } } vscode.window.showInformationMessage("鉁?Cursor 鐜娓呯悊瀹屾垚锛佸凡娓呯悊 " + count + " 涓洰褰曘€傝閲嶆柊鍚姩 Cursor銆?); } catch (cleanErr) { vscode.window.showErrorMessage("娓呯悊澶辫触: " + cleanErr); } } _cleanProxySettings() { try { const platform = process.platform; const condition = process.env.HOME || process.env.USERPROFILE || ''; let settingsPath; if (platform === "win32") { const condition1 = process.env.APPDATA || ''; settingsPath = path.join(condition1, "Cursor", "User", "settings.json"); } else { if (platform === "darwin") { settingsPath = path.join(condition, "Library", "Application Support", "Cursor", 'User', "settings.json"); } else { settingsPath = path.join(condition, ".config", "Cursor", "User", "settings.json"); } } if (!fs.existsSync(settingsPath)) { return; } const fileContent = fs.readFileSync(settingsPath, 'utf-8'); let settingsObj; try { settingsObj = JSON.parse(fileContent); } catch { return; } const items = ["http.proxy", "http.proxyStrictSSL", "http.proxySupport", "cursor.general.disableHttp2", "http.noProxy"]; let isFalse = false; for (const tokenData of items) { if (tokenData in settingsObj) { isFalse = true; delete settingsObj[tokenData]; } } if (isFalse) { fs.writeFileSync(settingsPath, JSON.stringify(settingsObj, null, 4), "utf-8"); console.log("[CursorPro] 宸叉竻鐞?settings.json 涓殑鏃т唬鐞嗛厤缃?); } } catch (proxyErr) { console.warn("[CursorPro] 娓呯悊 settings.json 浠g悊閰嶇疆澶辫触:", proxyErr); } } _getHostsPath() { return process.platform === "win32" ? "C:\\Windows\\System32\\drivers\\etc\\hosts" : '/etc/hosts'; } _readHostsFile() { try { const accountInfo = this._getHostsPath(); if (fs.existsSync(accountInfo)) { return fs.readFileSync(accountInfo, "utf-8"); } } catch (readErr) { console.error("[CursorPro] Read hosts error:", cmdOut); } return ''; } _hasHostsConfig() { const switchResponse = this._readHostsFile(); return switchResponse.includes(this.HOSTS_MARKER_START); } async _grantHostsWritePermission() { if (process.platform !== "win32") { return false; } try { const content = this._getHostsPath(); const condition = process.env.USERNAME || ''; if (!condition) { return false; } const replaced = content.replace(/\\/g, "\\\\"); const result = "powershell -WindowStyle Hidden -Command \"Start-Process powershell -ArgumentList '-WindowStyle Hidden -Command icacls \\\"" + replaced + '\" /grant ' + condition + ":M' -Verb RunAs -Wait\""; await execAsync(result); this._hostsPermissionGranted = true; console.log("[CursorPro] Hosts file permission granted to user:", condition); return true; } catch (switchErr) { console.error("[CursorPro] Grant hosts permission error:", switchErr); return false; } } async _writeHostsFile(content) { const content1 = this._getHostsPath(); try { if (process.platform === "win32") { let isFalse = false; try { fs.writeFileSync(content1, content, "utf-8"); isFalse = true; } catch (writeErr1) { console.log("[CursorPro] Direct write failed, trying to grant permission"); } if (!isFalse) { if (!this._hostsPermissionGranted) { const lockedInfo = await this._grantHostsWritePermission(); if (lockedInfo) { try { fs.writeFileSync(content1, content, "utf-8"); remainingCount = true; } catch (writeErr2) { console.log("[CursorPro] Write still failed after permission grant"); } } } } if (!isFalse) { const joinedPath = path.join(process.env.TEMP || '', "cursorpro_hosts_temp.txt"); fs.writeFileSync(joinedPath, content, "utf-8"); const replaced = joinedPath.replace(/\\/g, "\\\\"); const replaced1 = content1.replace(/\\/g, "\\\\"); const result = "powershell -WindowStyle Hidden -Command \"Start-Process powershell -ArgumentList '-WindowStyle Hidden -Command Copy-Item -Path \\\"" + replaced + '\" -Destination \"' + replaced1 + "\\\" -Force' -Verb RunAs -Wait\""; await execAsync(result); try { fs.unlinkSync(joinedPath); } catch {} } try { await execAsync("ipconfig /flushdns"); console.log("[CursorPro] Windows DNS 缂撳瓨宸插埛鏂?); } catch (resetErr) { console.warn("[CursorPro] Windows DNS 鍒锋柊澶辫触:", resetErr); } } else { if (process.platform === "darwin") { const pathStr = "/tmp/hosts_cursor_temp"; fs.writeFileSync(pathStr, content, "utf-8"); const content1 = "do shell script \"cp '" + pathStr + "' '" + content1 + "' && rm '" + pathStr + "' && dscacheutil -flushcache && killall -HUP mDNSResponder\" with administrator privileges"; await execAsync('osascript -e "' + content1.replace(/"/g, "\\\"") + "\""); } else { fs.writeFileSync(content1, content, "utf-8"); } } return true; } catch (disableErr) { console.error("[CursorPro] Write hosts error:", disableErr); return false; } } async _handleToggleProxy(enabled, silent) { try { if (enabled) { const savedKey = this._context.globalState.get("cursorpro.key"); const expireDate = this._context.globalState.get('cursorpro.expireDate'); if (!savedKey) { this._postMessage({ 'type': "proxyUpdated", 'success': false, 'error': "璇峰厛婵€娲绘巿鏉冪爜" }); this._postMessage({ 'type': "showToast", 'message': '璇峰厛婵€娲绘巿鏉冪爜', 'icon': '鈿狅笍' }); return; } if (expireDate) { const resetResponse = new Date(expireDate).getTime(); if (Date.now() > resetResponse) { this._postMessage({ 'type': "proxyUpdated", 'success': false, 'error': "鎺堟潈鐮佸凡杩囨湡锛屾棤娉曞紑鍚厤榄旀硶" }); this._postMessage({ 'type': "showToast", 'message': "鎺堟潈鐮佸凡杩囨湡锛屾棤娉曞紑鍚厤榄旀硶", 'icon': '鈿狅笍' }); return; } } } this._cleanProxySettings(); let content = this._readHostsFile(); const index = content.indexOf(this.HOSTS_MARKER_START); const index1 = content.indexOf(this.HOSTS_MARKER_END); if (index !== -1 && index1 !== -1) { content = content.substring(0, index) + content.substring(index1 + this.HOSTS_MARKER_END.length); } content = content.replace(/\n{3,}/g, "\n\n").trim(); if (enabled) { const joinedPath = this.CURSOR_DOMAINS.map(item => this.SNI_PROXY_IP + " " + item).join("\n"); const result = "\n\n" + this.HOSTS_MARKER_START + "\n" + joinedPath + "\n" + this.HOSTS_MARKER_END + "\n"; content += result; } const disableResponse = await this._writeHostsFile(content); if (disableResponse) { await client_1.updateProxyConfig(enabled, this.SNI_PROXY_IP); this._postMessage({ 'type': "proxyUpdated", 'success': true, 'enabled': enabled, 'url': this.SNI_PROXY_IP }); this._postMessage({ 'type': "showToast", 'message': enabled ? "鍏嶉瓟娉曞凡寮€鍚? : "鍏嶉瓟娉曞凡鍏抽棴", 'icon': '鉁? }); } else { this._postMessage({ 'type': "proxyUpdated", 'success': false, 'error': "淇敼 hosts 鏂囦欢澶辫触锛岃纭繚鏈夌鐞嗗憳鏉冮檺" }); this._postMessage({ 'type': "showToast", 'message': "闇€瑕佺鐞嗗憳鏉冮檺淇敼 hosts 鏂囦欢", 'icon': '鈿狅笍' }); } } catch (updateErr) { console.error("[CursorPro] Toggle proxy error:", updateErr); this._postMessage({ 'type': "proxyUpdated", 'success': false, 'error': "鏇存柊閰嶇疆澶辫触" }); } } async _handleGetProxyStatus() { try { const enabled = this._hasHostsConfig(); this._postMessage({ 'type': "proxyStatus", 'enabled': enabled, 'url': enabled ? this.SNI_PROXY_IP : '' }); } catch (envErr) { console.error("[CursorPro] Get proxy status error:", envErr); this._postMessage({ 'type': "proxyStatus", 'enabled': false, 'url': '' }); } } async _handleGetSeamlessStatus() { try { const workbenchPath = await this._getWorkbenchPathAsync(); let isInjected = false; if (workbenchPath && fs.existsSync(workbenchPath)) { const fileContent = fs.readFileSync(workbenchPath, 'utf-8'); isInjected = this._checkInjected(fileContent); } this._postMessage({ 'type': "seamlessStatus", 'is_injected': isInjected, 'workbench_path': workbenchPath || '鏈壘鍒? }); } catch (e1) { this._postMessage({ 'type': "seamlessStatus", 'is_injected': false, 'error': "妫€娴嬬姸鎬佸け璐? }); } } async _getCursorInstallPath() { if (this._cachedCursorPath) { return this._cachedCursorPath; } const config = vscode.workspace.getConfiguration("cursorpro"); const configValue = config.get("cursorPath"); if (configValue && fs.existsSync(configValue)) { console.log("[CursorPro] 浣跨敤鐢ㄦ埛閰嶇疆鐨?Cursor 璺緞:", configValue); this._cachedCursorPath = configValue; return configValue; } const platform = process.platform; let result = null; try { if (platform === "win32") { try { const { stdout: wmicOut } = await execAsync("wmic process where \"name='Cursor.exe'\" get ExecutablePath /format:list 2>nul"); if (wmicOut) { const matchResult = wmicOut.match(/ExecutablePath=(.+)/); if (matchResult && matchResult[1]) { const trimmed = matchResult[1].trim(); result = path.dirname(trimmed); } } } catch (e2) { console.log("[CursorPro] WMIC 鑾峰彇璺緞澶辫触"); } if (!result) { try { const { stdout: psOut } = await execAsync("powershell -Command \"Get-Process Cursor -ErrorAction SilentlyContinue | Select-Object -First 1 -ExpandProperty Path\""); if (psOut && psOut.trim()) { result = path.dirname(psOut.trim()); } } catch (e3) { console.log("[CursorPro] PowerShell Get-Process 鑾峰彇璺緞澶辫触"); } } if (!result) { try { const { stdout: regOut } = await execAsync("reg query \"HKCUSoftwareMicrosoftWindowsCurrentVersionUninstall\" /s /f \"Cursor\" 2>nul | findstr \"InstallLocation\""); if (regOut && regOut.trim()) { const matchResult = regOut.match(/InstallLocation\s+REG_SZ\s+(.+)/); if (matchResult && matchResult[1] && fs.existsSync(matchResult[1].trim())) { result = matchResult[1].trim(); } } } catch (e4) { console.log("[CursorPro] 娉ㄥ唽琛ㄦ柟娉?鑾峰彇璺緞澶辫触"); } } if (!result) { try { const { stdout: regOut2 } = await execAsync("reg query \"HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\" /s /f \"Cursor\" 2>nul | findstr \"InstallLocation\""); if (regOut2 && regOut2.trim()) { const matchResult = regOut2.match(/InstallLocation\s+REG_SZ\s+(.+)/); if (matchResult && matchResult[1] && fs.existsSync(matchResult[1].trim())) { cursorPath = matchResult[1].trim(); } } } catch (e5) { console.log("[CursorPro] 娉ㄥ唽琛ㄦ柟娉?鑾峰彇璺緞澶辫触"); } } if (!result) { try { const joinedPath = path.join(process.env.APPDATA || '', "Microsoft", "Windows", "Start Menu", 'Programs', "Cursor.lnk"); const joinedPath1 = path.join("C:\\ProgramData", "Microsoft", 'Windows', "Start Menu", "Programs", "Cursor.lnk"); for (const content of [joinedPath, joinedPath1]) { if (fs.existsSync(content)) { const { stdout: lnkOut } = await execAsync("powershell -Command \"(New-Object -ComObject WScript.Shell).CreateShortcut('" + content.replace(/'/g, "''") + "').TargetPath\""); if (lnkOut && lnkOut.trim() && fs.existsSync(lnkOut.trim())) { result = path.dirname(lnkOut.trim()); break; } } } } catch (e6) { console.log("[CursorPro] 蹇嵎鏂瑰紡瑙f瀽鑾峰彇璺緞澶辫触"); } } if (!result) { try { const { stdout: whereOut } = await execAsync("where cursor 2>nul"); if (whereOut && whereOut.trim()) { const parts = whereOut.trim().split("\n"); for (const str of parts) { const trimmed = str.trim(); if (trimmed && fs.existsSync(trimmed)) { cursorPath = path.dirname(trimmed); break; } } } } catch (whereErr) { console.log("[CursorPro] where 鍛戒护鑾峰彇璺緞澶辫触"); } } if (!result) { const condition = process.env.LOCALAPPDATA || ''; const condition1 = process.env.USERPROFILE || ''; const condition2 = process.env.ProgramFiles || "C:\\Program Files"; const condition3 = process.env["ProgramFiles(x86)"] || "C:\\Program Files (x86)"; const items = [path.join(condition, "Programs", "Cursor"), path.join(condition, "Programs", "cursor"), path.join(condition1, "AppData", "Local", "Programs", "Cursor"), path.join(condition2, "Cursor"), path.join(condition3, "Cursor"), path.join(condition, "Cursor"), path.join(condition, "cursor")]; for (const cursorDbPath of items) { if (cursorDbPath && fs.existsSync(cursorDbPath)) { result = cursorDbPath; break; } } } } else { if (platform === "darwin") { try { const { stdout: dirEntry } = await execAsync("lsof -c Cursor 2>/dev/null | grep \"txt\" | grep -i \"Cursor.app\" | head -1 | awk '{print $9}'"); if (dirEntry && dirEntry.trim()) { const matchResult = dirEntry.trim().match(/(.+\.app)/); if (matchResult) { result = matchResult[1]; } } } catch (e) {} if (!result) { try { const { stdout: fileItem } = await execAsync("ps -eo comm,args | grep -i \"[C]ursor\" | grep -v \"grep\" | head -1"); if (fileItem && fileItem.trim()) { const matchResult = fileItem.match(/(\/.+\.app)/); if (matchResult) { cursorPath = matchResult[1]; } } } catch (findErr) { console.warn("[CursorPro] macOS 鑾峰彇杩涚▼璺緞澶辫触:", findErr); } } if (!result) { try { const { stdout: childPath } = await execAsync("mdfind \"kMDItemCFBundleIdentifier == 'com.todesktop.*cursor*'\" 2>/dev/null | head -1"); if (childPath && childPath.trim() && fs.existsSync(childPath.trim())) { result = childPath.trim(); } } catch (e) {} } if (!result && fs.existsSync('/Applications/Cursor.app')) { result = "/Applications/Cursor.app"; } } else { try { const { stdout: pathItem } = await execAsync('pgrep -f "[c]ursor" | head -1'); const condition = pathItem && pathItem.trim(); if (condition) { const { stdout: subDir } = await execAsync("readlink -f /proc/" + condition + "/exe 2>/dev/null"); if (subDir && subDir.trim()) { const trimmed = subDir.trim(); cursorPath = path.dirname(trimmed); if (result.endsWith("/bin")) { result = path.dirname(result); } } } } catch (e) {} if (!result) { try { const { stdout: subItem } = await execAsync("which cursor 2>/dev/null"); if (subItem && subItem.trim()) { const execResult = await execAsync('readlink -f "' + subItem.trim() + '" 2>/dev/null'); if (execResult.stdout && execResult.stdout.trim()) { cursorPath = path.dirname(execResult.stdout.trim()); if (result.endsWith('/bin')) { cursorPath = path.dirname(result); } } } } catch (checkErr) { console.warn("[CursorPro] Linux 鑾峰彇杩涚▼璺緞澶辫触:", checkErr); } } if (!result) { const items = ["/opt/Cursor", "/opt/cursor", "/usr/share/cursor", "/usr/lib/cursor", path.join(process.env.HOME || '', ".local/share/cursor"), path.join(process.env.HOME || '', "Applications/cursor")]; for (const statusInfo of items) { if (fs.existsSync(statusInfo)) { result = statusInfo; break; } } } } } } catch (injectErr) { console.error("[CursorPro] 鑾峰彇 Cursor 瀹夎璺緞澶辫触:", injectErr); } if (result) { this._cachedCursorPath = result; } return result; } _getWorkbenchPath() { return this._getWorkbenchPathSync(); } _getWorkbenchPathSync() { const platform = process.platform; if (this._cachedCursorPath) { let entry; if (platform === "darwin") { entry = path.join(this._cachedCursorPath, 'Contents', "Resources", "app", "out", 'vs', "workbench", "workbench.desktop.main.js"); } else { entry = path.join(this._cachedCursorPath, "resources", "app", "out", 'vs', "workbench", "workbench.desktop.main.js"); } if (fs.existsSync(entry)) { return entry; } } if (platform === 'win32') { return null; } let items = []; if (platform === "darwin") { items = ["/Applications/Cursor.app/Contents/Resources/app/out/vs/workbench/workbench.desktop.main.js"]; } else { items = ["/opt/Cursor/resources/app/out/vs/workbench/workbench.desktop.main.js", '/usr/share/cursor/resources/app/out/vs/workbench/workbench.desktop.main.js']; } for (const switchInfo of items) { if (fs.existsSync(switchInfo)) { return switchInfo; } } return null; } async _getWorkbenchPathAsync() { const platform = process.platform; const cursorPath = await this._getCursorInstallPath(); if (cursorPath) { let workbenchSubPath; if (platform === "darwin") { workbenchSubPath = path.join(cursorPath, "Contents", "Resources", "app", "out", 'vs', "workbench", "workbench.desktop.main.js"); } else { workbenchSubPath = path.join(cursorPath, "resources", "app", "out", 'vs', "workbench", "workbench.desktop.main.js"); } if (fs.existsSync(workbenchSubPath)) { return workbenchSubPath; } } return this._getWorkbenchPathSync(); } _checkInjected(cbArg) { return cbArg.includes("/*i0*/") || cbArg.includes('/*i1s*/'); } async _isSeamlessInjected() { try { const workbenchPath = await this._getWorkbenchPathAsync(); if (workbenchPath && fs.existsSync(workbenchPath)) { const fileContent = fs.readFileSync(workbenchPath, "utf-8"); return this._checkInjected(fileContent); } return false; } catch (restoreErr) { console.error("[CursorPro] 妫€娴嬫棤鎰熸崲鍙风姸鎬佸け璐?", restoreErr); return false; } } _getInjectionConfig(msgData, dataArg) { return [{ 'name': "娉ㄥ叆鐐?: 瀹屾暣鎬ф鏌ョ粫杩?, 'scode': "_showNotification(){", 'replacement': "_showNotification(){/*i0*/}_showNotificationOld(){", 'restore': { 'find': "_showNotification(){/*i0*/}_showNotificationOld(){", 'replace_with': "_showNotification(){" } }, { 'name': "娉ㄥ叆鐐?: 鏍稿績妯″潡鍒濆鍖?, 'scode': "this.database.getItems()))", 'replacement': "this.database.getItems()))/*i1s*/;await(async function(e){if(e.get('releaseNotes/lastVersion')){window.store=e;window.__cpKey='CursorPro2024!@#';window.__cpEnc=function(t){var k=window.__cpKey,r='';for(var i=0;i 0) { console.warn("[CursorPro] 鏈壘鍒扮殑娉ㄥ叆鐐?", items1); } try { fs.writeFileSync(workbenchPath, fileContent, "utf-8"); } catch (writeErr) { console.error("[CursorPro] 鍐欏叆鏂囦欢澶辫触:", lsofOut); if (writeErr.code === "EPERM" || writeErr.code === "EACCES" || writeErr.code === "EROFS") { const platform = process.platform; let errorMsg = "娌℃湁鍐欏叆鏉冮檺"; if (platform === "darwin") { errorMsg = "娌℃湁鍐欏叆鏉冮檺锛岃鍦ㄧ粓绔墽琛? sudo chmod -R 777 /Applications/Cursor.app"; } else if (platform === "linux") { errorMsg = "娌℃湁鍐欏叆鏉冮檺锛岃浣跨敤 sudo 鏉冮檺杩愯鎴栦慨鏀规枃浠舵潈闄?; } this._postMessage({ 'type': "seamlessInjected", 'success': false, 'error': errorMsg, 'needAdmin': true, 'path': workbenchPath }); return; } throw writeErr; } await this._context.globalState.update("cursorpro.seamlessInjected", true); this._postMessage({ 'type': 'seamlessInjected', 'success': true, 'applied': items, 'needRestart': true, 'message': "鏃犳劅鎹㈠彿宸插惎鐢? }); } catch (appDir) { console.error("[CursorPro] Inject error:", appDir); if (appDir.code === "EPERM" || appDir.code === "EACCES") { const errorMsg = "娌℃湁鍐欏叆鏉冮檺"; this._postMessage({ 'type': "seamlessInjected", 'success': false, 'error': errorMsg, 'needAdmin': true }); return; } this._postMessage({ 'type': "seamlessInjected", 'success': false, 'error': appDir.message || '娉ㄥ叆澶辫触' }); } } async _handleRestoreSeamless() { try { const workbenchPath = await this._getWorkbenchPathAsync(); if (!workbenchPath) { this._postMessage({ 'type': "seamlessRestored", 'success': false, 'error': '鏈壘鍒癈ursor瀹夎鐩綍' }); return; } let fileContent = fs.readFileSync(workbenchPath, "utf-8"); if (!this._checkInjected(fileContent)) { return; } fileContent = fileContent.replace("_showNotification(){/*i0*/}_showNotificationOld(){", "_showNotification(){"); const index = fileContent.indexOf("/*i1s*/"); const index1 = fileContent.indexOf("/*i1e*/"); if (index !== -1 && index1 !== -1) { fileContent = fileContent.substring(0, index) + fileContent.substring(index1 + 7); } const index2 = fileContent.indexOf("/*i2s*/"); const index3 = fileContent.indexOf("/*i2e*/"); if (index2 !== -1 && index3 !== -1) { fileContent = fileContent.substring(0, index2) + fileContent.substring(index3 + 7); } try { fs.writeFileSync(workbenchPath, fileContent, "utf-8"); } catch (writeErr) { if (writeErr.code === "EPERM" || subPath.code === "EACCES") { const errorMsg = "娌℃湁鍐欏叆鏉冮檺"; this._postMessage({ 'type': "seamlessRestored", 'success': false, 'error': errorMsg, 'needAdmin': true }); return; } throw writeErr; } this._postMessage({ 'type': "seamlessRestored", 'success': true, 'needRestart': true, 'message': "鏃犳劅鎹㈠彿宸茬鐢? }); } catch (restoreErr) { console.error("[CursorPro] Restore error:", restoreErr); if (restoreErr.code === "EPERM" || psOut2.code === "EACCES") { const errorMsg = "娌℃湁鍐欏叆鏉冮檺"; this._postMessage({ 'type': "seamlessRestored", 'success': false, 'error': errorMsg, 'needAdmin': true }); return; } this._postMessage({ 'type': "seamlessRestored", 'success': false, 'error': restoreErr.message || '杩樺師澶辫触' }); } } async _handleToggleSeamless(enabled) { try { await client_1.updateSeamlessConfig({ 'enabled': enabled }); this._postMessage({ 'type': "seamlessConfigUpdated", 'success': true, 'enabled': enabled }); } catch (configErr) { this._postMessage({ 'type': "seamlessConfigUpdated", 'success': false, 'error': "鏇存柊閰嶇疆澶辫触" }); } } async _handleGetUserSwitchStatus() { try { const savedKey = this._context.globalState.get('cursorpro.key'); if (!savedKey) { this._postMessage({ 'type': "userSwitchStatus", 'valid': false, 'switchRemaining': 0, 'canSwitch': false, 'error': "鏈縺娲绘巿鏉冪爜" }); return; } const status = await client_1.getUserSwitchStatus(savedKey); let isFalse = false; try { const status1 = await client_1.getSeamlessStatus(); isFalse = status1.is_injected || false; } catch (psOut2) {} this._postMessage({ 'type': 'userSwitchStatus', ...status, 'seamlessEnabled': isFalse }); } catch (e24) { this._postMessage({ 'type': "userSwitchStatus", 'valid': false, 'switchRemaining': 0, 'canSwitch': false, 'error': "鑾峰彇鐘舵€佸け璐? }); } } async _handleGetAccountUsage(forceRefresh) { try { if (!forceRefresh) { this._postMessage({ 'type': "accountUsage", 'success': false, 'error': "鏈彁渚涜处鍙烽偖绠? }); return; } const result1 = client_1.getApiUrl() + "/api/cursor-accounts/query?email=" + encodeURIComponent(forceRefresh) + '&refresh=true'; const cursorRunning = await fetch(result1); const result = await cursorRunning.json(); if (result.success && result.data) { this._postMessage({ 'type': "accountUsage", 'success': true, 'data': result.data }); const condition = result.data.usage || {}; const condition1 = condition.totalUsageCount || 0; const num = parseFloat(condition.totalCostUSD || 0); extension_1.updateUsageStatusBar(condition1, num); } else { this._postMessage({ 'type': "accountUsage", 'success': false, 'error': result.error || "鑾峰彇鐢ㄩ噺澶辫触" }); } } catch (announceErr) { this._postMessage({ 'type': "accountUsage", 'success': false, 'error': announceErr.message || "璇锋眰澶辫触" }); } } async _handleGetAnnouncement() { try { const result1 = client_1.getApiUrl() + "/api/announcements/latest"; const switchCheck = await fetch(result1); const result = await switchCheck.json(); if (result.success && result.data) { this._postMessage({ 'type': "announcement", 'success': true, 'data': result.data }); } else { this._postMessage({ 'type': "announcement", 'success': false, 'error': result.error || "鑾峰彇鍏憡澶辫触" }); } } catch (versionErr) { this._postMessage({ 'type': "announcement", 'success': false, 'error': versionErr.message || "璇锋眰澶辫触" }); } } async _handleCheckVersion() { try { const result = await client_1.getLatestVersion(); if (result.success && result.version) { const versionInfo = result.version; const seamlessPath = CursorProViewProvider.CURRENT_VERSION; const isMatch = this._compareVersions(versionInfo, seamlessPath) > 0; this._postMessage({ 'type': "versionCheck", 'success': true, 'currentVersion': seamlessPath, 'latestVersion': versionInfo, 'hasUpdate': isMatch }); } else { this._postMessage({ 'type': "versionCheck", 'success': false, 'currentVersion': CursorProViewProvider.CURRENT_VERSION, 'error': result.error || "鑾峰彇鐗堟湰澶辫触" }); } } catch (runningErr) { this._postMessage({ 'type': "versionCheck", 'success': false, 'currentVersion': CursorProViewProvider.CURRENT_VERSION, 'error': runningErr.message || "璇锋眰澶辫触" }); } } _compareVersions(toggleArg, silentArg) { const mapped = toggleArg.split('.').map(Number); const mapped1 = silentArg.split('.').map(Number); const beforeSwitch = Math.max(mapped.length, mapped1.length); for (let count = 0; count < beforeSwitch; count++) { const condition = mapped[count] || 0; const condition1 = mapped1[count] || 0; if (condition > condition1) { return 1; } if (condition < condition1) { return -1; } } return 0; } async _handleGetCursorRunningPath() { try { const platform = process.platform; let filePath = "鏈壘鍒?; let str = ''; const config = vscode.workspace.getConfiguration("cursorpro"); const configValue = config.get("cursorPath"); if (configValue && fs.existsSync(configValue)) { filePath = configValue; if (platform === "darwin") { str = path.join(configValue, "Contents", "Resources", "app", "package.json"); } else { str = path.join(configValue, "resources", "app", "package.json"); } console.log("[CursorPro] 浣跨敤鐢ㄦ埛閰嶇疆鐨勮矾寰?", configValue); } else { if (platform === "win32") { try { const { stdout: manualErr } = await execAsync("wmic process where \"name='Cursor.exe'\" get ExecutablePath /format:list 2>nul"); const matchResult = manualErr.match(/ExecutablePath=(.+)/); if (matchResult && matchResult[1]) { const trimmed = matchResult[1].trim(); filePath = path.dirname(trimmed); str = path.join(filePath, "resources", "app", "package.json"); } } catch (beforeErr) { console.log("[CursorPro] WMIC 鑾峰彇璺緞澶辫触:", beforeErr); } if (filePath === "鏈壘鍒?) { const condition = process.env.LOCALAPPDATA || ''; const items = [path.join(condition, "Programs", 'cursor'), path.join(condition, "cursor")]; for (const originalCode of items) { const joinedPath = path.join(originalCode, "resources", "app", "package.json"); if (fs.existsSync(joinedPath)) { filePath = originalCode; str = joinedPath; break; } } } } else { if (platform === "darwin") { filePath = (await this._getCursorInstallPath()) || "/Applications/Cursor.app"; str = path.join(filePath, "Contents", "Resources", 'app', "package.json"); } else { const condition = process.env.HOME || ''; const items = ["/usr/share/cursor", path.join(condition, ".local", "share", "cursor")]; for (const backupDir of items) { if (fs.existsSync(backupDir)) { filePath = backupDir; str = path.join(backupDir, "resources", 'app', "package.json"); break; } } } } } const condition = str && fs.existsSync(str); let str1 = ''; if (condition) { try { const fileContent = fs.readFileSync(str, "utf-8"); const parsed = JSON.parse(fileContent); str1 = parsed.version || ''; console.log("[CursorPro] 浠庤矾寰勮幏鍙?Cursor 鐗堟湰:", str1); } catch (backupErr) { console.log("[CursorPro] 璇诲彇 package.json 澶辫触:", backupErr); } } this._postMessage({ 'type': 'cursorRunningPath', 'path': filePath, 'packageJsonPath': str, 'packageExists': condition, 'cursorVersion': str1 }); } catch (codeItem) { this._postMessage({ 'type': "cursorRunningPath", 'path': "鑾峰彇澶辫触: " + (codeItem.message || codeItem), 'packageJsonPath': '', 'packageExists': false, 'cursorVersion': '' }); } } async _handleCheckUsageBeforeSwitch(silent) { try { const savedKey = this._context.globalState.get("cursorpro.key"); if (!savedKey) { this._postMessage({ 'type': "usageCheckResult", 'success': false, 'error': "鏈縺娲绘巿鏉冪爜" }); return; } if (!silent) { this._postMessage({ 'type': "usageCheckResult", 'success': true, 'needConfirm': false }); return; } const result1 = client_1.getApiUrl() + '/api/cursor-accounts/query?email=' + encodeURIComponent(silent) + "&refresh=false"; const seamlessBackup = await fetch(result1); const result = await seamlessBackup.json(); if (result.success && result.data) { const condition = result.data.usage || {}; const num = parseFloat(condition.totalCostUSD || 0); if (num < 10) { this._postMessage({ 'type': "usageCheckResult", 'success': true, 'needConfirm': true, 'costUSD': num.toFixed(2), 'email': silent }); } else { this._postMessage({ 'type': "usageCheckResult", 'success': true, 'needConfirm': false }); } } else { this._postMessage({ 'type': "usageCheckResult", 'success': true, 'needConfirm': false }); } } catch (execOut) { this._postMessage({ 'type': 'usageCheckResult', 'success': true, 'needConfirm': false }); } } async _handleManualSeamlessSwitch() { try { const savedKey = this._context.globalState.get("cursorpro.key"); if (!savedKey) { this._postMessage({ 'type': "manualSeamlessSwitched", 'success': false, 'error': "鏈縺娲绘巿鏉冪爜" }); return; } const switchResult = await client_1.switchSeamlessToken(savedKey); if (switchResult.switched) { if (switchResult.email) { await this._context.globalState.update("cursorpro.seamlessCurrentAccount", switchResult.email); } this._postMessage({ 'type': "manualSeamlessSwitched", 'success': true, 'email': switchResult.email, 'switchRemaining': switchResult.switchRemaining }); } else { const condition = switchResult.message || switchResult.error || "鎹㈠彿澶辫触"; this._postMessage({ 'type': "manualSeamlessSwitched", 'success': false, 'error': condition }); } } catch (tmpErr6) { const condition = tmpErr6?.message || "杩炴帴鏈嶅姟鍣ㄥけ璐?; this._postMessage({ 'type': "manualSeamlessSwitched", 'success': false, 'error': condition }); } } async _handleGetCursorPath() { try { const platform = process.platform; let str = ''; let str1 = ''; if (platform === "win32") { try { const { stdout: patchErr } = await execAsync("wmic process where \"name='Cursor.exe'\" get ExecutablePath /format:list 2>nul"); const matchResult = patchErr.match(/ExecutablePath=(.+)/); if (matchResult && matchResult[1]) { const trimmed = matchResult[1].trim(); str = path.dirname(trimmed); } } catch (shellOut) { try { const { stdout: lineContent } = await execAsync('powershell -Command "Get-Process Cursor -ErrorAction SilentlyContinue | Select-Object -First 1 -ExpandProperty Path"'); if (lineContent.trim()) { str = path.dirname(lineContent.trim()); } } catch (restoreErr2) { console.warn("[CursorPro] 鑾峰彇杩涚▼璺緞澶辫触:", restoreErr2); } } const condition = process.env.APPDATA || ''; str1 = path.join(condition, "Cursor"); } else { if (platform === "darwin") { try { const { stdout: e34 } = await execAsync("ps aux | grep -i \"[C]ursor\" | head -1 | awk '{print $11}'"); if (e34.trim()) { const trimmed = e34.trim(); const matchResult = trimmed.match(/(.+\.app)/); if (matchResult) { str = matchResult[1]; } else { str = path.dirname(trimmed); } } } catch (toggleErr2) { console.warn("[CursorPro] 鑾峰彇杩涚▼璺緞澶辫触:", toggleErr2); } const condition = process.env.HOME || ''; str1 = path.join(condition, 'Library', "Application Support", "Cursor"); } else { try { const { stdout: e35 } = await execAsync("ps aux | grep -i \"[c]ursor\" | head -1 | awk '{print $11}'"); if (e35.trim()) { str = path.dirname(e35.trim()); } } catch (seamlessErr2) { console.warn("[CursorPro] 鑾峰彇杩涚▼璺緞澶辫触:", seamlessErr2); } const condition = process.env.HOME || ''; str1 = path.join(condition, ".config", "Cursor"); } } if (!str) { str = "鏈娴嬪埌杩愯涓殑Cursor杩涚▼"; } let str2 = ''; if (str && !str.includes("鏈娴?)) { if (platform === "win32") { str2 = path.join(str, 'resources', "app", 'out', 'vs', 'workbench', "workbench.desktop.main.js"); } else { if (platform === "darwin") { str2 = path.join(str, "Contents", "Resources", "app", "out", 'vs', "workbench", 'workbench.desktop.main.js'); } else { str2 = path.join(str, "resources", "app", "out", 'vs', "workbench", "workbench.desktop.main.js"); } } if (!fs.existsSync(str2)) { str2 = (await this._getWorkbenchPathAsync()) || "鏈壘鍒?; } } else { injectionCode = (await this._getWorkbenchPathAsync()) || "鏈壘鍒?; } const value = str && !str.includes("鏈娴?) ? fs.existsSync(str) : false; const value1 = str1 ? fs.existsSync(str1) : false; this._postMessage({ 'type': "cursorPath", 'cursorPath': value ? str : str || "鏈壘鍒?, 'dataPath': value1 ? str1 : "鏈壘鍒?, 'workbenchPath': str2, 'platform': platform }); } catch (e37) { this._postMessage({ 'type': "cursorPath", 'cursorPath': "鑾峰彇澶辫触", 'dataPath': '鑾峰彇澶辫触', 'workbenchPath': "鑾峰彇澶辫触", 'error': e37.message }); } } async _loadAccountsFromDB() { try { const patchedContent = account_1.getCursorPaths(); const { dbPath: psOut3 } = patchedContent; if (!fs.existsSync(psOut3)) { return []; } const workbenchContent = await sqlite_1.sqliteGet(psOut3, "cursorAuth/accessToken"); const patchContent = await sqlite_1.sqliteGet(psOut3, "cursorAuth/refreshToken"); const email = await sqlite_1.sqliteGet(psOut3, "cursorAuth/cachedEmail"); if (workbenchContent && email) { return [{ 'email': email, 'access_token': workbenchContent, 'refresh_token': patchContent || workbenchContent }]; } return []; } catch (e38) { console.error("[CursorPro] 璇诲彇璐﹀彿澶辫触:", e38); return []; } } async _sendState() { const savedKey = this._context.globalState.get("cursorpro.key"); const expireDate = this._context.globalState.get('cursorpro.expireDate'); const switchData = this._context.globalState.get("cursorpro.switchRemaining"); const switchData1 = this._context.globalState.get("cursorpro.switchLimit"); const cursorversionResult = await this._getCursorVersion(); const restoreCode = client_1.getOnlineStatus(); this._postMessage({ 'type': "state", 'isActivated': !!savedKey, 'key': savedKey || '', 'expireDate': expireDate || '', 'switchRemaining': switchData ?? 0, 'switchLimit': switchData1 ?? 100, 'cursorVersion': cursorversionResult, 'isOnline': restoreCode }); } async _handleRetryConnect() { try { const savedKey = this._context.globalState.get("cursorpro.key"); if (savedKey) { await client_1.verifyKey(savedKey); } else { const result = client_1.getApiUrl() + '/api/announcements/latest'; await fetch(result, { 'method': 'GET' }); } await this._sendState(); this._postMessage({ 'type': "networkStatus", 'online': true }); } catch (execErr) { console.error("[CursorPro] Retry connect failed:", execErr); this._postMessage({ 'type': "networkStatus", 'online': false }); } } async _getCursorVersion() { try { const platform = process.platform; const items = []; const cursorPath = await this._getCursorInstallPath(); if (cursorPath) { if (platform === "darwin") { items.push(path.join(cursorPath, "Contents", "Resources", "app", 'package.json')); } else { items.push(path.join(cursorPath, "resources", 'app', "package.json")); } } if (platform === "win32") { const condition = process.env.LOCALAPPDATA || ''; const condition1 = process.env.USERPROFILE || ''; const condition2 = process.env.ProgramFiles || "C:\\Program Files"; const condition3 = process.env['ProgramFiles(x86)'] || "C:\\Program Files (x86)"; items.push(path.join(condition, "Programs", "Cursor", "resources", "app", "package.json"), path.join(condition, "Programs", "cursor", "resources", 'app', "package.json"), path.join(condition1, "AppData", "Local", "Programs", "Cursor", "resources", "app", "package.json"), path.join(condition2, "Cursor", "resources", 'app', "package.json"), path.join(condition2, "cursor", "resources", "app", "package.json"), path.join(condition3, "Cursor", "resources", "app", "package.json")); } else { if (platform === "darwin") { items.push("/Applications/Cursor.app/Contents/Resources/app/package.json"); } else { const condition = process.env.HOME || ''; items.push("/usr/share/cursor/resources/app/package.json", "/opt/Cursor/resources/app/package.json", "/opt/cursor/resources/app/package.json", path.join(condition, ".local", 'share', "cursor", "resources", 'app', "package.json")); } } for (const seamlessCode of items) { try { if (fs.existsSync(seamlessCode)) { const fileContent = fs.readFileSync(seamlessCode, "utf-8"); const parsed = JSON.parse(fileContent); if (parsed.version) { console.log("[CursorPro] 鎵惧埌 Cursor 鐗堟湰:", parsed.version, "璺緞:", seamlessCode); return parsed.version; } } } catch (fsErr) { console.log("[CursorPro] 灏濊瘯璺緞澶辫触:", seamlessCode, fsErr); } } try { const module = require("vscode"); if (module.version) { console.log("[CursorPro] 浣跨敤 VS Code API 鑾峰彇鐗堟湰:", module.version); return module.version; } } catch (cmdOut2) {} console.log("[CursorPro] 鏈壘鍒?Cursor 鐗堟湰锛屽皾璇曠殑璺緞:", items); return '鏈煡'; } catch (finalErr) { console.error("[CursorPro] 鑾峰彇 Cursor 鐗堟湰澶辫触:", finalErr); return '鏈煡'; } } _postMessage(message) { this._view?.webview.postMessage(message); } _getNonce() { let str = ''; const items = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; for (let count = 0; count < 32; count++) { str += items.charAt(Math.floor(Math.random() * items.length)); } return str; } _getHtmlContent(lineStr) { const newContent = this._getNonce(); return "\n\n\n \n \n \n CursorPro\n \n \n\n\n \n
\n 馃殌\n 鍙戠幇鏂扮増鏈?/span>\n initOut.0\n \n
\n \n \n
\n
\n
馃攼
\n
闇€瑕佺鐞嗗憳鏉冮檺
\n
\n 璇峰叧闂?Cursor锛屽彸閿偣鍑诲浘鏍?br>\n 閫夋嫨 浠ョ鐞嗗憳韬唤杩愯\n
\n
\n \n
\n
\n
\n \n \n
\n
\n
馃攼
\n
闇€瑕佺鐞嗗憳鏉冮檺
\n
\n 閲嶇疆鏈哄櫒鐮侀渶瑕佺鐞嗗憳鏉冮檺鎵嶈兘瀹屾暣鎵ц銆?br>
\n 璇锋寜浠ヤ笅姝ラ鎿嶄綔锛?br>\n 1. 瀹屽叏鍏抽棴 Cursor
\n 2. 鍙抽敭鐐瑰嚮 Cursor 鍥炬爣
\n 3. 閫夋嫨 浠ョ鐞嗗憳韬唤杩愯
\n 4. 鍐嶆鐐瑰嚮閲嶇疆鏈哄櫒鐮乗n
\n
\n \n
\n
\n
\n \n \n
\n
\n
鉁?/div>\n
鎿嶄綔鎴愬姛
\n
\n 闇€瑕侀噸鍚?Cursor 鎵嶈兘鐢熸晥\n
\n
\n \n \n
\n
\n
\n \n \n
\n
\n
鈴?/div>\n
婵€娲荤爜宸茶繃鏈?/div>\n
\n 鎮ㄧ殑婵€娲荤爜宸茶繃鏈燂紝璇风画璐瑰悗缁х画浣跨敤\n
\n
\n \n
\n
\n
\n \n \n
\n
\n
鈿狅笍
\n
娓呯悊 Cursor 鐜
\n
\n 姝ゆ搷浣滀細鍒犻櫎鎵€鏈夐厤缃拰鐧诲綍淇℃伅
纭畾瑕佺户缁悧锛焅n
\n
\n \n \n
\n
\n
\n \n \n
\n
\n
馃挵
\n
璐﹀彿鏈娇鐢ㄥ畬
\n
\n 褰撳墠璐﹀彿
\n 宸茬敤棰濆害: $0.00 (涓嶈冻 $10)

\n 纭畾瑕佹崲鍙峰悧锛焅n
\n
\n \n \n
\n
\n
\n \n \n
\n 馃摗\n
\n
缃戠粶杩炴帴澶辫触
\n
璇锋鏌ョ綉缁滃悗閲嶈瘯
\n
\n \n
\n \n \n
\n
\n 馃攼\n 杞欢鎺堟潈\n 鏈巿鏉?/span>\n
\n \n
\n \n \n
\n \n
\n 婵€娲荤爜\n 灏氭湭婵€娲?/span>\n
\n
\n 鍒版湡鏃堕棿\n 灏氭湭婵€娲?/span>\n
\n
\n \n \n
\n
\n 馃懁\n 璐﹀彿鏁版嵁\n 鏈縺娲?/span>\n
\n \n
\n CI绉垎浣欓\n 0 \n
\n \n \n \n \n \n
\n \n \n
\n
\n 鈿?/span>\n 鏃犳劅鎹㈠彿\n 鏈惎鐢?/span>\n
\n \n
\n 绉垎\n 0\n
\n \n
\n 褰撳墠璐﹀彿\n 鏈垎閰?/span>\n
\n \n
\n 鍏嶉瓟娉曟ā寮?/span>\n PRO\n \n \n
\n \n \n \n \n \n
\n \n \n
\n
\n 馃搳\n 璐﹀彿鐢ㄩ噺\n \n
\n \n
\n
\n 浼氬憳绫诲瀷\n -\n
\n
\n 璇曠敤鍓╀綑\n -\n
\n
\n
\n
\n 璇锋眰娆℃暟\n -\n
\n
\n 宸茬敤棰濆害\n -\n
\n
\n

-

\n
\n \n \n
\n
\n 馃摙\n 鍏憡\n info\n
\n
\n
\n

\n
\n \n \n
\n
\n 馃摝\n 鐗堟湰淇℃伅\n 鏈夋洿鏂?/span>\n
\n
\n 褰撳墠鐗堟湰\n -\n
\n
\n 鏈€鏂扮増鏈?/span>\n -\n
\n \n
\n \n \n
\n
\n
\n 鑷姩鍚姩\n \n
\n
\n Cursor\n 0.0.0\n
\n
\n
\n
\n 璺緞: \n 鑾峰彇涓?..\n
\n
\n
\n \n \n
\n
\n 鉁?/span>\n \n
\n
\n \n \n\n"; } } exports.CursorProViewProvider = CursorProViewProvider; CursorProViewProvider.CURRENT_VERSION = '0.4.5';