File size: 9,848 Bytes
95dd43a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92f3410
95dd43a
92f3410
 
95dd43a
92f3410
95dd43a
92f3410
95dd43a
 
92f3410
 
 
95dd43a
 
 
92f3410
 
 
95dd43a
 
92f3410
 
 
 
95dd43a
 
 
92f3410
 
 
 
 
95dd43a
 
92f3410
 
95dd43a
92f3410
 
 
 
 
 
 
95dd43a
 
 
 
92f3410
95dd43a
92f3410
 
95dd43a
92f3410
95dd43a
92f3410
95dd43a
92f3410
 
 
 
95dd43a
92f3410
95dd43a
92f3410
95dd43a
 
92f3410
 
95dd43a
 
 
92f3410
 
 
 
 
95dd43a
 
92f3410
 
 
95dd43a
 
92f3410
 
95dd43a
92f3410
 
 
 
 
 
95dd43a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30e5fc4
6e1b170
30e5fc4
 
 
6e1b170
30e5fc4
6e1b170
 
 
 
 
 
 
 
30e5fc4
 
 
 
 
6e1b170
 
 
 
 
30e5fc4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6e1b170
 
 
 
 
 
30e5fc4
 
6e1b170
30e5fc4
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
"""Context7-powered documentation agent for deployment readiness."""

from __future__ import annotations

import os
from typing import Any, Dict, List, Optional

from enhanced_mcp_client import EnhancedMCPClient
from schemas import ReadinessPlan, ReadinessRequest


class DocumentationLookupAgent:
    """Uses Context7 MCP to lookup framework/platform documentation."""

    def __init__(self):
        self.mcp_client = EnhancedMCPClient()

    async def extract_framework_from_request(self, request: ReadinessRequest) -> Optional[str]:
        """Extract framework/library from code summary with multi-framework support."""
        code_lower = request.code_summary.lower()
        infra_lower = (request.infra_notes or "").lower()
        combined = f"{code_lower} {infra_lower}"
        
        # Extended framework detection with priority order
        frameworks = {
            # React ecosystem (highest priority)
            "next.js": "next.js",
            "nextjs": "next.js",
            "remix": "remix",
            "gatsby": "gatsby",
            # Python frameworks
            "django": "django",
            "fastapi": "fastapi",
            "flask": "flask",
            "fastapi": "fastapi",
            "starlette": "starlette",
            # Node.js frameworks
            "express": "express",
            "nestjs": "nestjs",
            "koa": "koa",
            "hapi": "hapi",
            # Frontend frameworks
            "react": "react",
            "vue": "vue",
            "angular": "angular",
            "svelte": "svelte",
            "nuxt": "nuxt",
            # Other
            "spring": "spring",
            "rails": "rails",
            "laravel": "laravel",
        }
        
        # Check for multiple frameworks (return the most specific one)
        detected = []
        for key, framework in frameworks.items():
            if key in combined:
                detected.append((len(key), framework))  # Prioritize longer matches
        
        if detected:
            # Return the most specific (longest) match
            detected.sort(reverse=True, key=lambda x: x[0])
            return detected[0][1]
        
        return None

    async def extract_platform_from_request(self, request: ReadinessRequest) -> Optional[str]:
        """Extract deployment platform from infra notes with multi-platform support."""
        infra_lower = (request.infra_notes or "").lower()
        code_lower = (request.code_summary or "").lower()
        combined = f"{infra_lower} {code_lower}"
        
        # Extended platform detection
        platforms = {
            # Serverless/Edge
            "vercel": "vercel",
            "netlify": "netlify",
            "cloudflare": "cloudflare",
            "cloudflare pages": "cloudflare",
            # Cloud providers
            "aws": "aws",
            "amazon web services": "aws",
            "azure": "azure",
            "microsoft azure": "azure",
            "gcp": "gcp",
            "google cloud": "gcp",
            "google cloud platform": "gcp",
            # PaaS
            "railway": "railway",
            "render": "render",
            "fly.io": "fly.io",
            "flyio": "fly.io",
            "heroku": "heroku",
            "digitalocean": "digitalocean",
            "digital ocean": "digitalocean",
            # Containers/Orchestration
            "kubernetes": "kubernetes",
            "k8s": "kubernetes",
            "docker": "docker",
            "docker compose": "docker",
            "docker-compose": "docker",
        }
        
        # Check for multiple platforms (return the most specific one)
        detected = []
        for key, platform in platforms.items():
            if key in combined:
                detected.append((len(key), platform))
        
        if detected:
            detected.sort(reverse=True, key=lambda x: x[0])
            return detected[0][1]
        
        return None

    async def lookup_deployment_docs(
        self, request: ReadinessRequest, plan: ReadinessPlan
    ) -> Dict[str, Any]:
        """Comprehensive documentation lookup for deployment readiness."""
        framework = await self.extract_framework_from_request(request)
        platform = await self.extract_platform_from_request(request)
        
        docs_results = {
            "framework": framework,
            "platform": platform,
            "lookups": []
        }

        if not framework and not platform:
            docs_results["lookups"].append({
                "type": "general",
                "topic": "deployment best practices",
                "status": "no_framework_detected"
            })
            return docs_results

        # Lookup framework deployment docs
        if framework:
            framework_docs = await self.mcp_client.lookup_documentation(
                framework, "deployment guide"
            )
            docs_results["lookups"].append({
                "type": "framework_deployment",
                "framework": framework,
                "docs": framework_docs,
                "status": "found" if framework_docs.get("success") else "not_found"
            })

        # Lookup platform-specific docs
        if platform:
            platform_docs = await self.mcp_client.lookup_documentation(
                platform, "deployment configuration"
            )
            docs_results["lookups"].append({
                "type": "platform_deployment",
                "platform": platform,
                "docs": platform_docs,
                "status": "found" if platform_docs.get("success") else "not_found"
            })

        # Check dependency compatibility
        if framework:
            # Extract dependencies from code summary (simplified)
            deps = []  # Would parse from package.json, requirements.txt, etc.
            compat_check = await self.mcp_client.check_dependency_compatibility(
                deps, framework
            )
            docs_results["lookups"].append({
                "type": "dependency_compatibility",
                "result": compat_check,
                "status": "checked"
            })

        # Validate deployment configs
        if platform:
            config_validation = await self.mcp_client.validate_deployment_config(
                "dockerfile", "", platform  # Would have actual config content
            )
            docs_results["lookups"].append({
                "type": "config_validation",
                "result": config_validation,
                "status": "validated"
            })

        # Get deployment runbook
        if framework and platform:
            runbook = await self.mcp_client.get_deployment_runbook(
                framework, platform, "production"
            )
            docs_results["lookups"].append({
                "type": "deployment_runbook",
                "result": runbook,
                "status": "generated"
            })

        # Environment variables check
        if framework:
            env_check = await self.mcp_client.check_environment_variables(
                [], framework  # Would extract from request
            )
            docs_results["lookups"].append({
                "type": "environment_variables",
                "result": env_check,
                "status": "checked"
            })

        # Migration guide if needed
        if framework:
            migration_guide = await self.mcp_client.get_migration_guide(
                framework, "database"
            )
            docs_results["lookups"].append({
                "type": "migration_guide",
                "result": migration_guide,
                "status": "found"
            })

        # Observability setup
        if framework and platform:
            observability = await self.mcp_client.get_observability_setup(
                framework, platform
            )
            docs_results["lookups"].append({
                "type": "observability_setup",
                "result": observability,
                "status": "found"
            })

        return docs_results

    def generate_readme(self, analysis: Dict[str, Any]) -> str:
        """Generate a professional README.md based on analysis."""
        framework = analysis.get("framework", "Project")
        summary = analysis.get("code_summary", "No summary available.")
        dependencies = analysis.get("dependencies", [])
        platform = analysis.get("platform", "Not configured")
        
        # Badges
        badges = f"![{framework}](https://img.shields.io/badge/{framework}-black?style=for-the-badge&logo={framework.lower()})\n"
        if platform != "Not configured":
            badges += f"![{platform}](https://img.shields.io/badge/{platform}-black?style=for-the-badge&logo={platform.lower()})\n"
        
        readme = f"""# {framework.title()} Project

{badges}

## πŸš€ Overview
{summary}

## πŸ› οΈ Tech Stack
| Component | Details |
|-----------|---------|
| **Framework** | {framework} |
| **Platform** | {platform} |
| **Dependencies** | {len(dependencies)} packages |

## πŸ“¦ Installation

```bash
"""
        if analysis.get("package_manager") == "npm":
            readme += "npm install\nnpm run dev\n"
        elif analysis.get("package_manager") == "pip":
            readme += "pip install -r requirements.txt\npython app.py\n"
        else:
            readme += "# Install dependencies\n# Run application\n"
            
        readme += """```

## 🚒 Deployment

This project is ready for deployment via **Deploy Ready Copilot**.

### Steps
1. Connect your GitHub repository.
2. Select your target platform ({platform}).
3. Click "Deploy".

---
*Generated by [Deploy Ready Copilot](https://huggingface.co/spaces/HIMANSHUKUMARJHA/deploy-ready-copilot)*
"""
        return readme