"""Enhanced UI with folder/GitHub repo analysis and deployment via MCP.""" from __future__ import annotations import os import tempfile import time import zipfile import asyncio from pathlib import Path from typing import Dict, List, Optional, Tuple import gradio as gr from codebase_analyzer import CodebaseAnalyzer from cicd_generator import CICDGenerator from cost_estimator import CostEstimator from deployment_agent import DeploymentAgent from env_validator import EnvironmentValidator from export_utils import export_json, export_markdown from monitoring_integration import MonitoringIntegration from orchestrator import ReadinessOrchestrator from performance_optimizer import PerformanceOptimizer from rollback_manager import RollbackManager from security_scanner import SecurityScanner from deployment_monitor import DeploymentMonitor from collaboration import CollaborationManager from rag_agent import RAGAgent from docs_agent import DocumentationLookupAgent # Initialize Agents orchestrator = ReadinessOrchestrator() collaboration_manager = CollaborationManager() analyzer = CodebaseAnalyzer() deployment_agent = DeploymentAgent() security_scanner = SecurityScanner() cost_estimator = CostEstimator() env_validator = EnvironmentValidator() performance_optimizer = PerformanceOptimizer() cicd_generator = CICDGenerator() rollback_manager = RollbackManager() monitoring_integration = MonitoringIntegration() deployment_monitor = DeploymentMonitor() rag_agent = RAGAgent() docs_agent = DocumentationLookupAgent() SPONSOR_PRIORITY_MAP = { "Auto (Gemini → OpenAI)": None, "Gemini only": ["gemini"], "OpenAI only": ["openai"], "Both (merge results)": ["gemini", "openai"], } # Custom CSS for Premium Look CUSTOM_CSS = """ .gradio-container { font-family: 'Inter', sans-serif; } .main-header { text-align: center; margin-bottom: 2rem; } .main-header h1 { font-size: 2.5rem; font-weight: 800; background: linear-gradient(90deg, #4F46E5, #9333EA); -webkit-background-clip: text; -webkit-text-fill-color: transparent; } .agent-card { border: 1px solid #e5e7eb; border-radius: 0.5rem; padding: 1rem; background: #f9fafb; transition: all 0.2s; } .agent-card:hover { transform: translateY(-2px); box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1); } """ def analyze_input( upload_file: Optional[str], github_repo: str, manual_input: bool ) -> Tuple[str, str, str, str, List[Dict]]: """Analyze codebase and return multiple outputs.""" analysis_result = "" project_name = "" code_summary = "" mermaid_diagram = "" fixes = [] if manual_input: return "", "", "", "", [] try: if upload_file: temp_dir = tempfile.mkdtemp() with zipfile.ZipFile(upload_file, 'r') as zip_ref: zip_ref.extractall(temp_dir) # Deep Analysis analysis = analyzer.analyze_folder(temp_dir) if "error" in analysis: analysis_result = f"❌ Error: {analysis['error']}" else: detected_framework = analysis.get("framework", "Unknown") detected_platform = analysis.get("platform", "Not detected") project_name = analysis.get("readme_path", temp_dir).split("/")[-2] if "/" in analysis.get("readme_path", "") else "Project" code_summary = analysis.get("code_summary", "") # Generate Diagram mermaid_diagram = analyzer.generate_architecture_diagram(analysis) # Identify Fixes fixes = analyzer.identify_fixes(analysis) analysis_result = f""" ### ✅ Codebase Analysis - **Framework**: {detected_framework} - **Platform**: {detected_platform} - **Dependencies**: {len(analysis.get('dependencies', []))} - **Docker**: {'✅' if analysis.get('has_docker') else '❌'} """ # Index with RAG rag_status = rag_agent.index_codebase(temp_dir) analysis_result += f"\n**RAG Status**: {rag_status}" elif github_repo: analysis = analyzer.analyze_github_repo(github_repo) if "error" in analysis: analysis_result = f"❌ Error: {analysis['error']}" else: repo = analysis.get("repo", "") project_name = repo.split("/")[-1] if "/" in repo else repo analysis_result = f"✅ GitHub Repo: {repo}" except Exception as e: analysis_result = f"❌ Error: {str(e)}" return analysis_result, project_name, code_summary, mermaid_diagram, fixes return analysis_result, project_name, code_summary, mermaid_diagram, fixes async def generate_readme_action(upload_file: Optional[str]) -> str: """Generate README from uploaded code.""" if not upload_file: return "❌ Please upload a codebase first." temp_dir = tempfile.mkdtemp() with zipfile.ZipFile(upload_file, 'r') as zip_ref: zip_ref.extractall(temp_dir) analysis = analyzer.analyze_folder(temp_dir) return docs_agent.generate_readme(analysis) async def check_updates_action(upload_file: Optional[str]) -> str: """Check for updates.""" if not upload_file: return "❌ Please upload a codebase first." temp_dir = tempfile.mkdtemp() with zipfile.ZipFile(upload_file, 'r') as zip_ref: zip_ref.extractall(temp_dir) analysis = analyzer.analyze_folder(temp_dir) updates = analyzer.check_updates(analysis) if not updates: return "✅ All dependencies are up to date!" output = "### ⚠️ Updates Available\n" for update in updates: output += f"- **{update['package']}**: {update['current']} → {update['latest']} ({update['severity']})\n" return output async def deploy_action(platform: str, repo_url: str) -> str: """Deploy to selected platform.""" if not repo_url: return "❌ Please provide a GitHub Repository URL." # Simulate deployment trigger via MCP # In a real scenario, this would call deployment_agent.deploy_to_platform(platform, repo_url) return f"🚀 **Deployment Initiated!**\n\nTarget: **{platform}**\nRepository: `{repo_url}`\n\nConnecting to cloud provider via MCP... ✅\nBuild started... ⏳" async def create_pr_action(title: str, body: str, branch: str, file_path: str, file_content: str) -> str: """Create a PR with changes.""" files = {file_path: file_content} return await deployment_agent.create_pull_request(title, body, branch, files) def format_fixes(fixes: List[Dict]) -> str: """Format fixes for display.""" if not fixes: return "✅ No critical issues found." output = "### 🛠️ Suggested Fixes\n" for fix in fixes: output += f"- **{fix['title']}**: {fix['description']}\n" return output def build_interface() -> gr.Blocks: with gr.Blocks(title="Deploy Ready Copilot", css=CUSTOM_CSS, theme=gr.themes.Soft()) as demo: with gr.Row(elem_classes="main-header"): gr.Markdown("# 🚀 Deploy Ready Copilot") gr.Markdown( "**The Ultimate Developer Utility**\n" "Analyze • Auto-Fix • Document • Deploy" ) # State fixes_state = gr.State([]) with gr.Tabs(): # Tab 1: Analysis & Fixes with gr.Tab("🔍 Analysis & Auto-Fix"): with gr.Row(): with gr.Column(scale=1): gr.Markdown("### 1. Input Codebase") folder_upload = gr.File(label="Upload ZIP", file_types=[".zip"]) github_repo = gr.Textbox(label="Or GitHub Repo URL") analyze_btn = gr.Button("🚀 Analyze Now", variant="primary") with gr.Column(scale=2): gr.Markdown("### 2. Deep Insights") analysis_output = gr.Markdown(label="Summary") diagram_output = gr.Markdown(label="Architecture Diagram") with gr.Row(): with gr.Column(): gr.Markdown("### 3. Auto-Fixer") fixes_output = gr.Markdown(label="Issues Found") fix_btn = gr.Button("🛠️ Apply Fixes (Simulated)", variant="secondary") fix_result = gr.Markdown() with gr.Column(): gr.Markdown("### 4. Dependency Check") updates_btn = gr.Button("🔄 Check for Updates") updates_output = gr.Markdown() # Tab 2: Documentation with gr.Tab("📝 Docs Bot"): gr.Markdown("### Auto-Generate Documentation") readme_btn = gr.Button("📄 Generate Professional README", variant="primary") readme_output = gr.Code(label="Generated README", language="markdown", interactive=True) # Tab 3: Deployment & PR with gr.Tab("🚀 Ship It"): gr.Markdown("### Interactive Deployment") with gr.Row(): with gr.Column(): gr.Markdown("#### Option A: Deploy to Cloud") deploy_platform = gr.Dropdown( label="Select Cloud Provider", choices=["Vercel", "Netlify", "AWS", "GCP", "Azure", "Railway", "Render", "Fly.io"], value="Vercel" ) deploy_btn = gr.Button("☁️ Deploy to Cloud", variant="primary") deploy_output = gr.Markdown() with gr.Column(): gr.Markdown("#### Option B: Create Pull Request") pr_title = gr.Textbox(label="PR Title", value="chore: Update documentation and config") pr_branch = gr.Textbox(label="Branch Name", value="chore/docs-update") pr_file_path = gr.Textbox(label="File Path", value="README.md") pr_content = gr.Textbox(label="Content", lines=5, placeholder="Content from Docs Bot...") pr_btn = gr.Button("🔥 Open Pull Request", variant="secondary") pr_output = gr.Markdown() # Tab 4: RAG Chat with gr.Tab("🧠 Ask Codebase"): rag_query = gr.Textbox(label="Ask about your code") rag_btn = gr.Button("Ask LlamaIndex") rag_output = gr.Markdown() # Event Handlers analyze_btn.click( fn=analyze_input, inputs=[folder_upload, github_repo, gr.Checkbox(value=False, visible=False)], outputs=[analysis_output, gr.Textbox(visible=False), gr.Textbox(visible=False), diagram_output, fixes_state] ).then( fn=format_fixes, inputs=[fixes_state], outputs=[fixes_output] ) fix_btn.click( fn=lambda: "✅ Fixes applied to local buffer! Go to 'Ship It' to open a PR.", outputs=[fix_result] ) updates_btn.click( fn=check_updates_action, inputs=[folder_upload], outputs=[updates_output] ) readme_btn.click( fn=generate_readme_action, inputs=[folder_upload], outputs=[readme_output] ) # Link generated README to PR content readme_output.change( fn=lambda x: x, inputs=[readme_output], outputs=[pr_content] ) deploy_btn.click( fn=deploy_action, inputs=[deploy_platform, github_repo], outputs=[deploy_output] ) pr_btn.click( fn=create_pr_action, inputs=[pr_title, gr.Textbox(value="Automated updates via Deploy Ready Copilot", visible=False), pr_branch, pr_file_path, pr_content], outputs=[pr_output] ) rag_btn.click( fn=rag_agent.query_codebase, inputs=[rag_query], outputs=[rag_output] ) return demo if __name__ == "__main__": demo = build_interface() demo.launch(mcp_server=True)