UNPKG

filetree-pro

Version:

A powerful file tree generator for VS Code and Cursor. Generate beautiful file trees in multiple formats with smart exclusions and custom configurations.

245 lines (205 loc) 6.81 kB
import * as vscode from 'vscode'; import { CopilotAnalysis } from '../types'; export class CopilotService { private _isCopilotAvailable: boolean = false; private analysisCache = new Map<string, CopilotAnalysis>(); constructor() { this.checkCopilotAvailability(); } private async checkCopilotAvailability(): Promise<void> { try { const copilotExtension = vscode.extensions.getExtension('github.copilot'); this._isCopilotAvailable = !!copilotExtension && copilotExtension.isActive; if (this._isCopilotAvailable) { console.log('GitHub Copilot is available and active'); } else { console.log('GitHub Copilot is not available or not active'); } } catch (error) { console.error('Error checking Copilot availability:', error); this._isCopilotAvailable = false; } } isCopilotAvailable(): boolean { return this._isCopilotAvailable; } isAvailable(): boolean { return this._isCopilotAvailable; } async analyzeFile(uri: vscode.Uri): Promise<CopilotAnalysis | null> { if (!this._isCopilotAvailable) { return null; } const cacheKey = uri.fsPath; if (this.analysisCache.has(cacheKey)) { return this.analysisCache.get(cacheKey) || null; } try { const content = await this.getFileContent(uri); if (!content) { return null; } const analysis = await this.performAnalysis(uri, content); this.analysisCache.set(cacheKey, analysis); return analysis; } catch (error) { console.error('Error analyzing file with Copilot:', error); return null; } } private async getFileContent(uri: vscode.Uri): Promise<string> { try { const content = await vscode.workspace.fs.readFile(uri); return Buffer.from(content).toString('utf8'); } catch (error) { console.error('Error reading file content:', error); return ''; } } private async performAnalysis(uri: vscode.Uri, content: string): Promise<CopilotAnalysis> { const fileName = uri.fsPath.split('/').pop() || ''; const fileExtension = fileName.split('.').pop() || ''; const prompt = this.buildAnalysisPrompt(fileName, fileExtension, content); try { // Use Copilot Chat API to analyze the file const response = await vscode.commands.executeCommand('github.copilot.chat', { messages: [ { role: 'user', content: prompt, }, ], }); return this.parseAnalysisResponse(response); } catch (error) { console.error('Error calling Copilot Chat API:', error); return this.generateFallbackAnalysis(content); } } private buildAnalysisPrompt(fileName: string, fileExtension: string, content: string): string { return `Please analyze this ${fileExtension} file and provide: 1. A brief summary of what this file does (1-2 sentences) 2. The complexity level (low/medium/high) based on code structure 3. 2-3 suggestions for improvement or refactoring 4. Any potential issues or best practices violations File: ${fileName} Content: \`\`\`${fileExtension} ${content.substring(0, 2000)}${content.length > 2000 ? '...' : ''} \`\`\` Please respond in JSON format: { "summary": "brief description", "complexity": "low|medium|high", "suggestions": ["suggestion1", "suggestion2"], "issues": ["issue1", "issue2"] }`; } private parseAnalysisResponse(response: any): CopilotAnalysis { try { if (typeof response === 'string') { const jsonMatch = response.match(/\{[\s\S]*\}/); if (jsonMatch) { const parsed = JSON.parse(jsonMatch[0]); return { summary: parsed.summary, complexity: parsed.complexity, suggestions: parsed.suggestions, recommendations: parsed.issues, }; } } // Fallback parsing return { summary: 'Analysis completed', complexity: 'medium', suggestions: ['Consider adding comments', 'Review code structure'], }; } catch (error) { console.error('Error parsing Copilot response:', error); return { summary: 'Analysis completed', complexity: 'medium', suggestions: ['Consider adding comments', 'Review code structure'], }; } } private generateFallbackAnalysis(content: string): CopilotAnalysis { const lines = content.split('\n').length; const complexity = lines > 100 ? 'high' : lines > 50 ? 'medium' : 'low'; return { summary: `File contains ${lines} lines of code`, complexity, suggestions: ['Consider adding documentation', 'Review for potential optimizations'], }; } getFileAnalysis(uri: vscode.Uri): CopilotAnalysis | null { return this.analysisCache.get(uri.fsPath) || null; } async getProjectSuggestions(): Promise<string[]> { if (!this._isCopilotAvailable) { return []; } try { const workspaceFolders = vscode.workspace.workspaceFolders; if (!workspaceFolders) { return []; } const prompt = `Analyze this project structure and provide 3-5 suggestions for: 1. File organization improvements 2. Naming conventions 3. Project structure optimization 4. Best practices recommendations Please provide specific, actionable suggestions.`; const response = await vscode.commands.executeCommand('github.copilot.chat', { messages: [ { role: 'user', content: prompt, }, ], }); if (typeof response === 'string') { return response.split('\n').filter(line => line.trim().length > 0); } return []; } catch (error) { console.error('Error getting project suggestions:', error); return []; } } async suggestFileOrganization(): Promise<string[]> { if (!this._isCopilotAvailable) { return []; } try { const prompt = `Based on the current project structure, suggest file organization improvements including: 1. Folder structure recommendations 2. File naming conventions 3. Separation of concerns 4. Module organization Provide specific, actionable recommendations.`; const response = await vscode.commands.executeCommand('github.copilot.chat', { messages: [ { role: 'user', content: prompt, }, ], }); if (typeof response === 'string') { return response.split('\n').filter(line => line.trim().length > 0); } return []; } catch (error) { console.error('Error getting file organization suggestions:', error); return []; } } clearCache(): void { this.analysisCache.clear(); } dispose(): void { this.clearCache(); } }