## 当前状态 - 插件界面已完成重命名 (cursorpro → hummingbird) - 双账号池 UI 已实现 (Auto/Pro 卡片) - 后端已切换到 MySQL 数据库 - 添加了 Cursor 官方用量 API 文档 ## 已知问题 (待修复) 1. 激活时检查账号导致无账号时激活失败 2. 未启用无感换号时不应获取账号 3. 账号用量模块不显示 (seamless 未启用时应隐藏) 4. 积分显示为 0 (后端未正确返回) 5. Auto/Pro 双密钥逻辑混乱,状态不同步 6. 账号添加后无自动分析功能 ## 下一版本计划 - 重构数据模型,优化账号状态管理 - 实现 Cursor API 自动分析账号 - 修复激活流程,不依赖账号 - 启用无感时才分配账号 - 完善账号用量实时显示 ## 文件说明 - docs/系统设计文档.md - 完整架构设计 - cursor 官方用量接口.md - Cursor API 文档 - 参考计费/ - Vibeviewer 开源项目参考 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
222 lines
7.2 KiB
JavaScript
222 lines
7.2 KiB
JavaScript
'use strict';
|
||
|
||
// ============================================
|
||
// 蜂鸟Pro Extension
|
||
// ============================================
|
||
|
||
Object.defineProperty(exports, "__esModule", { value: true });
|
||
|
||
const vscode = require('vscode');
|
||
const provider_1 = require('./webview/provider');
|
||
const fs = require('fs');
|
||
const path = require('path');
|
||
|
||
let usageStatusBarItem;
|
||
|
||
// 创建输出通道
|
||
exports.outputChannel = vscode.window.createOutputChannel('蜂鸟Pro');
|
||
|
||
/**
|
||
* 日志函数
|
||
*/
|
||
function log(message) {
|
||
const timestamp = new Date().toLocaleTimeString();
|
||
exports.outputChannel.appendLine('[' + timestamp + '] ' + message);
|
||
console.log('[蜂鸟Pro] ' + message);
|
||
}
|
||
exports.log = log;
|
||
|
||
/**
|
||
* 清理 Service Worker 缓存
|
||
*/
|
||
function cleanServiceWorkerCache() {
|
||
try {
|
||
const platform = process.platform;
|
||
const cachePaths = [];
|
||
|
||
if (platform === 'win32') {
|
||
const appData = process.env.APPDATA || '';
|
||
const localAppData = process.env.LOCALAPPDATA || '';
|
||
cachePaths.push(
|
||
path.join(appData, 'Cursor', 'Service Worker'),
|
||
path.join(localAppData, 'Cursor', 'Service Worker'),
|
||
path.join(appData, 'Cursor', 'GPUCache'),
|
||
path.join(localAppData, 'Cursor', 'GPUCache')
|
||
);
|
||
} else if (platform === 'darwin') {
|
||
const home = process.env.HOME || '';
|
||
cachePaths.push(
|
||
path.join(home, 'Library', 'Application Support', 'Cursor', 'Service Worker'),
|
||
path.join(home, 'Library', 'Caches', 'Cursor', 'Service Worker')
|
||
);
|
||
} else {
|
||
const home = process.env.HOME || '';
|
||
cachePaths.push(
|
||
path.join(home, '.config', 'Cursor', 'Service Worker'),
|
||
path.join(home, '.cache', 'Cursor', 'Service Worker')
|
||
);
|
||
}
|
||
|
||
for (const cachePath of cachePaths) {
|
||
if (!fs.existsSync(cachePath)) continue;
|
||
|
||
// 清理 ScriptCache
|
||
const scriptCachePath = path.join(cachePath, 'ScriptCache');
|
||
if (fs.existsSync(scriptCachePath)) {
|
||
try {
|
||
const files = fs.readdirSync(scriptCachePath);
|
||
for (const file of files) {
|
||
try {
|
||
fs.unlinkSync(path.join(scriptCachePath, file));
|
||
} catch (e) {}
|
||
}
|
||
console.log('[蜂鸟Pro] Service Worker ScriptCache 已清理:', scriptCachePath);
|
||
} catch (e) {}
|
||
}
|
||
|
||
// 清理 CacheStorage
|
||
const cacheStoragePath = path.join(cachePath, 'CacheStorage');
|
||
if (fs.existsSync(cacheStoragePath)) {
|
||
try {
|
||
deleteFolderRecursive(cacheStoragePath);
|
||
console.log('[蜂鸟Pro] Service Worker CacheStorage 已清理:', cacheStoragePath);
|
||
} catch (e) {}
|
||
}
|
||
|
||
// 清理 Database
|
||
const databasePath = path.join(cachePath, 'Database');
|
||
if (fs.existsSync(databasePath)) {
|
||
try {
|
||
deleteFolderRecursive(databasePath);
|
||
console.log('[蜂鸟Pro] Service Worker Database 已清理:', databasePath);
|
||
} catch (e) {}
|
||
}
|
||
}
|
||
} catch (error) {
|
||
console.log('[蜂鸟Pro] 清理 Service Worker 缓存时出错:', error);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 递归删除文件夹
|
||
*/
|
||
function deleteFolderRecursive(folderPath) {
|
||
if (fs.existsSync(folderPath)) {
|
||
fs.readdirSync(folderPath).forEach(file => {
|
||
const curPath = path.join(folderPath, file);
|
||
if (fs.lstatSync(curPath).isDirectory()) {
|
||
deleteFolderRecursive(curPath);
|
||
} else {
|
||
try {
|
||
fs.unlinkSync(curPath);
|
||
} catch (e) {}
|
||
}
|
||
});
|
||
try {
|
||
fs.rmdirSync(folderPath);
|
||
} catch (e) {}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 激活扩展
|
||
*/
|
||
function activate(context) {
|
||
// 清理 Service Worker 缓存
|
||
cleanServiceWorkerCache();
|
||
|
||
// 创建 WebView Provider
|
||
const viewProvider = new provider_1.HummingbirdProViewProvider(context.extensionUri, context);
|
||
|
||
// 注册 WebView
|
||
context.subscriptions.push(
|
||
vscode.window.registerWebviewViewProvider('hummingbird.mainView', viewProvider)
|
||
);
|
||
|
||
// 创建状态栏项
|
||
usageStatusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right, 100);
|
||
usageStatusBarItem.text = '$(dashboard) 用量: --';
|
||
usageStatusBarItem.tooltip = '点击查看账号用量详情';
|
||
usageStatusBarItem.command = 'hummingbird.showPanel';
|
||
usageStatusBarItem.backgroundColor = new vscode.ThemeColor('statusBarItem.prominentBackground');
|
||
|
||
// 如果有保存的 key,显示状态栏
|
||
const savedKey = context.globalState.get('hummingbird.key');
|
||
if (savedKey) {
|
||
usageStatusBarItem.show();
|
||
}
|
||
|
||
context.subscriptions.push(usageStatusBarItem);
|
||
|
||
// 设置同步的键
|
||
context.globalState.setKeysForSync(['hummingbird.key']);
|
||
|
||
// 注册显示面板命令
|
||
context.subscriptions.push(
|
||
vscode.commands.registerCommand('hummingbird.showPanel', () => {
|
||
vscode.commands.executeCommand('hummingbird.mainView.focus');
|
||
})
|
||
);
|
||
}
|
||
exports.activate = activate;
|
||
|
||
/**
|
||
* 停用扩展
|
||
*/
|
||
function deactivate() {
|
||
console.log('蜂鸟Pro 插件已停用');
|
||
}
|
||
exports.deactivate = deactivate;
|
||
|
||
/**
|
||
* 显示状态栏
|
||
*/
|
||
function showStatusBar() {
|
||
if (usageStatusBarItem) {
|
||
usageStatusBarItem.show();
|
||
}
|
||
}
|
||
exports.showStatusBar = showStatusBar;
|
||
|
||
/**
|
||
* 隐藏状态栏
|
||
*/
|
||
function hideStatusBar() {
|
||
if (usageStatusBarItem) {
|
||
usageStatusBarItem.hide();
|
||
}
|
||
}
|
||
exports.hideStatusBar = hideStatusBar;
|
||
|
||
/**
|
||
* 更新用量状态栏
|
||
* @param {number} requestCount - 请求次数
|
||
* @param {number|string} usageCost - 已用额度
|
||
*/
|
||
function updateUsageStatusBar(requestCount, usageCost) {
|
||
if (usageStatusBarItem) {
|
||
const count = typeof requestCount === 'number' ? requestCount : requestCount;
|
||
const cost = typeof usageCost === 'number' ? usageCost : parseFloat(usageCost.toString().replace('$', '')) || 0;
|
||
const costDisplay = typeof usageCost === 'number' ? '$' + usageCost.toFixed(2) : usageCost;
|
||
|
||
usageStatusBarItem.text = '$(dashboard) ' + count + '次 | ' + costDisplay;
|
||
usageStatusBarItem.tooltip = '请求次数: ' + count + '\n已用额度: ' + costDisplay + '\n点击查看详情';
|
||
|
||
// 根据用量设置颜色
|
||
if (cost >= 10) {
|
||
// 高用量 - 红色警告
|
||
usageStatusBarItem.backgroundColor = new vscode.ThemeColor('statusBarItem.errorBackground');
|
||
usageStatusBarItem.color = undefined;
|
||
} else if (cost >= 5) {
|
||
// 中用量 - 黄色警告
|
||
usageStatusBarItem.backgroundColor = new vscode.ThemeColor('statusBarItem.warningBackground');
|
||
usageStatusBarItem.color = undefined;
|
||
} else {
|
||
// 低用量 - 绿色
|
||
usageStatusBarItem.backgroundColor = undefined;
|
||
usageStatusBarItem.color = '#4ade80';
|
||
}
|
||
}
|
||
}
|
||
exports.updateUsageStatusBar = updateUsageStatusBar;
|