import * as vscode from "vscode"; import { ICViewProvider } from "./views/ICViewProvider"; import { showICHelperPanel } from "./panels/ICHelperPanel"; import { VCDViewerPanel, VCDViewerEditorProvider } from "./panels/VCDViewerPanel"; import { ChatHistoryManager } from "./utils/chatHistoryManager"; import { ICCoderAuthenticationProvider } from "./services/icCoderAuthProvider"; import { VCDFileServer } from "./services/vcdFileServer"; import { isTokenExpired } from "./utils/jwtUtils"; import { NotificationService } from "./services/notificationService"; import { InvitationService } from "./services/invitationService"; import { ICCoderCodeActionProvider } from "./providers/codeActionProvider"; import { setCustomConfig } from "./config/settings"; export async function activate(context: vscode.ExtensionContext) { console.log("🎉 IC Coder 插件已激活!"); // 加载保存的配置 const savedSettings = context.globalState.get('generalSettings') as any; if (savedSettings?.backendUrl) { setCustomConfig({ backendUrl: savedSettings.backendUrl, }); } // 创建装饰类型(代码旁边的提示) const decorationType = vscode.window.createTextEditorDecorationType({ after: { contentText: ' Ctrl+L 添加到 IC Coder 对话', color: '#888', fontStyle: 'italic', margin: '0 0 0 1em' } }); // 更新装饰 const updateDecorations = () => { const editor = vscode.window.activeTextEditor; if (!editor) return; if (!editor.selection.isEmpty) { const range = new vscode.Range(editor.selection.end, editor.selection.end); const decoration = { range }; editor.setDecorations(decorationType, [decoration]); } else { editor.setDecorations(decorationType, []); } }; context.subscriptions.push( vscode.window.onDidChangeTextEditorSelection(updateDecorations), vscode.window.onDidChangeActiveTextEditor(updateDecorations) ); updateDecorations(); // 初始化通知服务 const notificationService = NotificationService.getInstance(context); console.log('[Extension] 通知服务已初始化'); // 【已禁用】登录和 token 验证 - 无需登录即可使用 // const storedSessions = context.globalState.get('icCoderSessions', []); // console.log('[Extension] 检查 sessions 数量:', storedSessions.length); // // if (storedSessions.length > 0) { // const session = storedSessions[0]; // const token = session.accessToken; // console.log('[Extension] 检查 token 是否过期...'); // // if (token) { // const expired = isTokenExpired(token); // console.log('[Extension] token 过期检查结果:', expired); // // if (expired) { // await context.globalState.update('icCoderSessions', []); // await context.globalState.update('icCoderUserInfo', undefined); // console.log('[Extension] Token 已过期,已清除所有登录状态'); // } // } // } // 初始化 VCD 文件服务器 const vcdFileServer = new VCDFileServer(context.extensionUri); vcdFileServer.start().then((port) => { console.log(`VCD 文件服务器已启动,端口: ${port}`); }).catch((error) => { console.error("启动 VCD 文件服务器失败:", error); }); // 在插件停用时关闭服务器 context.subscriptions.push({ dispose: () => vcdFileServer.stop() }); // 【已禁用】Authentication Provider 注册 - 无需登录 const authProvider = new ICCoderAuthenticationProvider(context); // context.subscriptions.push( // vscode.authentication.registerAuthenticationProvider( // "iccoder", // "IC Coder", // authProvider // ) // ); // 【已禁用】登录状态检查 - 直接打开聊天面板 vscode.commands.executeCommand("ic-coder.openChat"); // 注册命令:打开助手面板 const openPanelCommand = vscode.commands.registerCommand( "ic-coder.openPanel", async () => { await showICHelperPanel(context); } ); // 注册命令:打开聊天(用于侧边栏) const openChatCommand = vscode.commands.registerCommand( "ic-coder.openChat", async () => { await showICHelperPanel(context); } ); // 注册命令:打开 VCD 波形查看器 const openVCDViewerCommand = vscode.commands.registerCommand( "ic-coder.openVCDViewer", async (vcdFilePath?: string) => { if (!vcdFilePath) { // 如果没有提供文件路径,让用户选择 VCD 文件 const fileUri = await vscode.window.showOpenDialog({ canSelectFiles: true, canSelectFolders: false, canSelectMany: false, filters: { "VCD 文件": ["vcd"], "所有文件": ["*"], }, title: "选择 VCD 文件", }); if (fileUri && fileUri[0]) { vcdFilePath = fileUri[0].fsPath; } else { return; } } VCDViewerPanel.createOrShow(context.extensionUri, vcdFilePath, vcdFileServer); } ); // 注册命令:在浏览器中打开 VCD 波形查看器 const openVCDViewerInBrowserCommand = vscode.commands.registerCommand( "ic-coder.openVCDViewerInBrowser", async (vcdFilePath?: string) => { if (!vcdFilePath) { const fileUri = await vscode.window.showOpenDialog({ canSelectFiles: true, canSelectFolders: false, canSelectMany: false, filters: { "VCD 文件": ["vcd"], "所有文件": ["*"], }, title: "选择 VCD 文件", }); if (fileUri && fileUri[0]) { vcdFilePath = fileUri[0].fsPath; } else { return; } } // 注册文件到服务器 const fileId = vcdFileServer.registerFile(vcdFilePath); const viewerUrl = vcdFileServer.getViewerUrl(fileId); // 在默认浏览器中打开 vscode.env.openExternal(vscode.Uri.parse(viewerUrl)); vscode.window.showInformationMessage(`波形查看器已在浏览器中打开`); } ); // 注册命令:打开用户手册 const openUserManualCommand = vscode.commands.registerCommand( "ic-coder.openUserManual", async () => { const manualPath = vscode.Uri.joinPath(context.extensionUri, "media", "USER_MANUAL.md"); await vscode.commands.executeCommand("markdown.showPreview", manualPath); } ); // 注册命令:用户登录 const loginCommand = vscode.commands.registerCommand( "ic-coder.login", async (options?: { forceReauth?: boolean }) => { try { const forceReauth = options?.forceReauth === true; const session = await vscode.authentication.getSession("iccoder", [], { createIfNone: false, }); const expired = session?.accessToken ? isTokenExpired(session.accessToken) : null; // 会话仍有效时,直接打开聊天面板 if (session && expired === false && !forceReauth) { vscode.commands.executeCommand("ic-coder.openChat"); return; } // 1) 清空当前登录状态信息 await authProvider.clearSessionsForRelogin(); await context.globalState.update("icCoderSessions", []); await context.globalState.update("icCoderUserInfo", undefined); // 2) 重新登录(强制新会话) await vscode.authentication.getSession("iccoder", [], { clearSessionPreference: true, forceNewSession: true, }); } catch (error) { vscode.window.showErrorMessage(`登录失败: ${error}`); } } ); // 注册命令:用户登出 const logoutCommand = vscode.commands.registerCommand( "ic-coder.logout", async () => { try { const session = await vscode.authentication.getSession("iccoder", [], { createIfNone: false }); if (session) { // 调用 authProvider 的 removeSession 方法 await authProvider.removeSession(session.id); // 清除邀请码验证状态 await InvitationService.clearVerificationStatus(context); } else { vscode.window.showInformationMessage("当前未登录"); } } catch (error) { vscode.window.showInformationMessage("当前未登录"); } } ); // 注册命令:更换邀请码 const changeInvitationCodeCommand = vscode.commands.registerCommand( "ic-coder.changeInvitationCode", async () => { const confirm = await vscode.window.showWarningMessage( '确定要更换邀请码吗?', '确定', '取消' ); if (confirm === '确定') { await InvitationService.clearVerificationStatus(context); vscode.window.showInformationMessage('已清除邀请码,请重新验证'); } } ); // 注册命令:测试系统通知 const testNotificationCommand = vscode.commands.registerCommand( "ic-coder.testNotification", () => { console.log('[Extension] ========== 测试通知命令被调用 =========='); // 先显示 VS Code 通知确认命令执行 vscode.window.showInformationMessage('正在测试系统通知...'); // 发送系统通知 notificationService.success( 'IC Coder - 测试通知', '系统通知功能正常工作!', () => { vscode.window.showInformationMessage('您点击了系统通知!'); } ); console.log('[Extension] 测试通知命令执行完成'); } ); // 注册命令:将选中代码添加到对话 const addCodeToChat = vscode.commands.registerCommand( "ic-coder.addCodeToChat", async () => { console.log('[addCodeToChat] 命令触发'); const editor = vscode.window.activeTextEditor; if (!editor) { console.log('[addCodeToChat] 没有活动编辑器'); return; } const selection = editor.selection; const selectedText = editor.document.getText(selection); if (!selectedText) { vscode.window.showWarningMessage("请先选择代码"); return; } const fileName = editor.document.fileName; const startLine = selection.start.line + 1; const endLine = selection.end.line + 1; // 检查是否已有打开的面板 let panel = (global as any).currentICHelperPanel; let needCreatePanel = false; if (!panel) { needCreatePanel = true; } else { // 尝试访问 webview,如果抛出异常说明已销毁 try { const _ = panel.webview; } catch (e) { needCreatePanel = true; } } console.log('[addCodeToChat] 需要创建面板:', needCreatePanel); if (needCreatePanel) { console.log('[addCodeToChat] 正在打开面板...'); await showICHelperPanel(context); panel = (global as any).currentICHelperPanel; console.log('[addCodeToChat] 面板打开后状态:', panel ? '成功' : '失败'); // 如果面板仍未创建(如未登录),直接返回 if (!panel) { console.log('[addCodeToChat] 面板创建失败,退出'); return; } } // 发送代码上下文 console.log('[addCodeToChat] 准备发送代码到面板'); setTimeout(() => { try { if (panel?.webview) { console.log('[addCodeToChat] 发送 addCodeContext 消息'); panel.webview.postMessage({ command: 'addCodeContext', fileName, startLine, endLine, code: selectedText, languageId: editor.document.languageId }); } } catch (e) { console.log('[addCodeToChat] 发送消息失败:', e); } }, 500); } ); // 注册命令:查看会话历史 // TODO: 这些命令需要根据新的任务架构重新实现 // 暂时注释掉,等待重新实现 /* const viewHistoryCommand = vscode.commands.registerCommand( "ic-coder.viewHistory", () => { vscode.window.showInformationMessage("此功能正在重构中,敬请期待"); } ); const newSessionCommand = vscode.commands.registerCommand( "ic-coder.newSession", () => { vscode.window.showInformationMessage("此功能正在重构中,敬请期待"); } ); const exportSessionCommand = vscode.commands.registerCommand( "ic-coder.exportSession", () => { vscode.window.showInformationMessage("此功能正在重构中,敬请期待"); } ); const deleteSessionCommand = vscode.commands.registerCommand( "ic-coder.deleteSession", () => { vscode.window.showInformationMessage("此功能正在重构中,敬请期待"); } ); const clearHistoryCommand = vscode.commands.registerCommand( "ic-coder.clearHistory", () => { vscode.window.showInformationMessage("此功能正在重构中,敬请期待"); } ); const searchSessionCommand = vscode.commands.registerCommand( "ic-coder.searchSession", () => { vscode.window.showInformationMessage("此功能正在重构中,敬请期待"); } ); */ // 注册侧边栏视图 const viewProvider = new ICViewProvider(context.extensionUri, context); const viewRegistration = vscode.window.registerWebviewViewProvider( "ic-coder.mainView", viewProvider, { webviewOptions: { retainContextWhenHidden: true } } ); // 注册 VCD 自定义编辑器 const vcdEditorProvider = VCDViewerEditorProvider.register(context, vcdFileServer); // 注册 Code Action Provider const codeActionProvider = vscode.languages.registerCodeActionsProvider( { scheme: 'file' }, new ICCoderCodeActionProvider(), { providedCodeActionKinds: [vscode.CodeActionKind.RefactorRewrite] } ); // 添加到订阅 context.subscriptions.push( openPanelCommand, openChatCommand, openVCDViewerCommand, openVCDViewerInBrowserCommand, openUserManualCommand, loginCommand, logoutCommand, changeInvitationCodeCommand, testNotificationCommand, addCodeToChat, // testTrialUserCommand, // testExpiredUserCommand, // TODO: 等待重新实现这些命令 // viewHistoryCommand, // newSessionCommand, // exportSessionCommand, // deleteSessionCommand, // clearHistoryCommand, // searchSessionCommand, viewRegistration, vcdEditorProvider, codeActionProvider ); } export function deactivate() {}