diff --git a/docs/multi-step-integration-guide.md b/docs/multi-step-integration-guide.md
new file mode 100644
index 0000000..84e271f
--- /dev/null
+++ b/docs/multi-step-integration-guide.md
@@ -0,0 +1,491 @@
+# Multi-Step README Generation Pipeline - Integration Guide
+
+This guide provides complete instructions for integrating the multi-step README generation pipeline into an existing Next.js application, specifically for the ReadmeGenAI project.
+
+## ๐ Overview
+
+The new pipeline solves the token limit issues by:
+- **Section-by-section generation**: Each section is generated individually within token limits
+- **Retry logic**: Failed sections are automatically retried with simplified prompts
+- **Smart dependency management**: Sections are generated in optimal order based on dependencies
+- **Continuation support**: Truncated content can be automatically completed
+- **Fallback mechanisms**: Critical sections always have fallback content
+
+## ๐ Quick Integration
+
+### 1. Install Dependencies
+
+```bash
+npm install @google/generative-ai @octokit/rest
+```
+
+### 2. Replace Existing API Route
+
+Replace the content of `src/app/api/generate/route.ts`:
+
+```typescript
+import { handleReadmeGeneration } from '@/lib/multi-step-readme-generator';
+
+export async function POST(request: Request) {
+ return handleReadmeGeneration(request);
+}
+```
+
+### 3. Environment Variables
+
+Ensure these environment variables are set:
+
+```env
+GEMINI_API_KEY=your_gemini_api_key
+GITHUB_TOKEN=your_github_token # Optional but recommended for higher rate limits
+```
+
+### 4. Update Frontend (Optional)
+
+Enhance the frontend to show generation progress:
+
+```typescript
+// In your component
+const [generationStats, setGenerationStats] = useState(null);
+
+const handleGenerate = async (githubUrl: string) => {
+ setIsLoading(true);
+
+ try {
+ const response = await fetch('/api/generate', {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify({ githubUrl }),
+ });
+
+ const result = await response.json();
+
+ if (result.success) {
+ setReadme(result.readme);
+ setGenerationStats(result.stats);
+ } else {
+ setError(result.error);
+ }
+ } catch (error) {
+ setError('Generation failed');
+ } finally {
+ setIsLoading(false);
+ }
+};
+```
+
+## ๐ง Advanced Configuration
+
+### Custom Configuration
+
+You can customize the generation behavior:
+
+```typescript
+import { MultiStepReadmeGenerator } from '@/lib/multi-step-readme-generator';
+
+const generator = new MultiStepReadmeGenerator(
+ process.env.GEMINI_API_KEY!,
+ process.env.GITHUB_TOKEN,
+ {
+ maxRetries: 5, // Increase retries for better reliability
+ maxTokensPerSection: 1000, // Allow longer sections
+ temperature: 0.5, // More conservative generation
+ concurrentSections: 2, // Reduce concurrency to avoid rate limits
+ enableContinuation: true, // Enable automatic continuation
+ }
+);
+```
+
+### Custom Section Planning
+
+Define custom sections for specific project types:
+
+```typescript
+import { SectionPlanner, ReadmeSection } from '@/lib/multi-step-readme-generator';
+
+// Custom sections for a specific project type
+const customSections: ReadmeSection[] = [
+ {
+ id: 'header',
+ title: 'Project Header',
+ priority: 'critical',
+ order: 1,
+ estimatedTokens: 200,
+ dependencies: [],
+ },
+ {
+ id: 'quick-start',
+ title: 'Quick Start',
+ priority: 'high',
+ order: 2,
+ estimatedTokens: 400,
+ dependencies: ['header'],
+ },
+ // ... more sections
+];
+
+const result = await assembler.generateCompleteReadme(
+ metadata,
+ structure,
+ customSections
+);
+```
+
+## ๐ Monitoring and Analytics
+
+### Generation Stats
+
+The new pipeline provides detailed statistics:
+
+```typescript
+interface GenerationStats {
+ sectionsGenerated: number; // How many sections were successfully generated
+ sectionsTotal: number; // Total sections planned
+ tokensUsed: number; // Total tokens consumed
+ timeElapsed: number; // Generation time in milliseconds
+}
+```
+
+### Error Handling
+
+Comprehensive error information:
+
+```typescript
+interface GenerationResult {
+ success: boolean;
+ readme?: string;
+ stats: GenerationStats;
+ errors: string[]; // Detailed error messages
+}
+```
+
+### Logging Integration
+
+Add logging to track generation performance:
+
+```typescript
+// In your API route
+const result = await generator.generateReadme(githubUrl);
+
+// Log metrics
+console.log(`README generated for ${githubUrl}:`, {
+ success: result.success,
+ sectionsGenerated: result.stats.sectionsGenerated,
+ timeElapsed: result.stats.timeElapsed,
+ tokensUsed: result.stats.tokensUsed,
+});
+
+// Log errors for debugging
+if (result.errors.length > 0) {
+ console.error('Generation errors:', result.errors);
+}
+```
+
+## ๐ Migration from Existing Implementation
+
+### Step 1: Backup Current Implementation
+
+```bash
+# Backup current generate route
+cp src/app/api/generate/route.ts src/app/api/generate/route.ts.backup
+```
+
+### Step 2: Gradual Migration
+
+Implement a feature flag for gradual rollout:
+
+```typescript
+// src/app/api/generate/route.ts
+import { handleReadmeGeneration as newHandler } from '@/lib/multi-step-readme-generator';
+import { handleReadmeGeneration as oldHandler } from '@/lib/old-readme-generator';
+
+export async function POST(request: Request) {
+ const useNewPipeline = process.env.USE_NEW_README_PIPELINE === 'true';
+
+ if (useNewPipeline) {
+ return newHandler(request);
+ } else {
+ return oldHandler(request);
+ }
+}
+```
+
+### Step 3: A/B Testing
+
+Compare old vs new implementation:
+
+```typescript
+export async function POST(request: Request) {
+ const body = await request.json();
+ const { githubUrl, useNewPipeline } = body;
+
+ if (useNewPipeline) {
+ return handleReadmeGeneration(request);
+ } else {
+ // Use old implementation
+ return oldReadmeGeneration(request);
+ }
+}
+```
+
+## ๐ ๏ธ Troubleshooting
+
+### Common Issues and Solutions
+
+#### 1. Token Limit Exceeded
+
+**Problem**: Even individual sections exceed token limits
+**Solution**: Reduce `maxTokensPerSection` or simplify prompts
+
+```typescript
+const generator = new MultiStepReadmeGenerator(apiKey, githubToken, {
+ maxTokensPerSection: 600, // Reduce from default 800
+});
+```
+
+#### 2. Rate Limiting
+
+**Problem**: API rate limits exceeded
+**Solution**: Reduce concurrency and add delays
+
+```typescript
+const generator = new MultiStepReadmeGenerator(apiKey, githubToken, {
+ concurrentSections: 1, // Generate one section at a time
+});
+```
+
+#### 3. GitHub API Rate Limits
+
+**Problem**: Repository analysis fails due to rate limits
+**Solution**: Provide GitHub token and implement caching
+
+```typescript
+// Implement simple caching
+const cache = new Map();
+
+class CachedRepositoryAnalyzer extends RepositoryAnalyzer {
+ async analyzeRepository(owner: string, repo: string) {
+ const key = `${owner}/${repo}`;
+
+ if (cache.has(key)) {
+ return cache.get(key);
+ }
+
+ const result = await super.analyzeRepository(owner, repo);
+ cache.set(key, result);
+
+ return result;
+ }
+}
+```
+
+#### 4. Incomplete Sections
+
+**Problem**: Some sections are consistently incomplete
+**Solution**: Increase retries or customize prompts
+
+```typescript
+// Custom prompt for problematic section
+const customPrompts = {
+ installation: `Generate concise installation instructions for "${metadata.name}".
+
+ Context: ${structure.techStack.primary} project
+
+ Requirements:
+ - Prerequisites (if any)
+ - Single command installation
+ - Verification step
+
+ Keep it under 300 words. Return only markdown.`,
+};
+```
+
+### Debug Mode
+
+Enable detailed logging:
+
+```typescript
+// Set environment variable
+process.env.DEBUG_README_GENERATION = 'true';
+
+// In the generator
+if (process.env.DEBUG_README_GENERATION === 'true') {
+ console.log('Section generation details:', {
+ sectionId,
+ prompt: prompt.substring(0, 200) + '...',
+ result: result.success ? 'success' : 'failed',
+ tokensUsed: result.tokensUsed,
+ });
+}
+```
+
+## ๐ Performance Optimizations
+
+### 1. Caching Strategy
+
+Implement Redis caching for repository analysis:
+
+```typescript
+import Redis from 'ioredis';
+
+const redis = new Redis(process.env.REDIS_URL);
+
+class CachedAnalyzer extends RepositoryAnalyzer {
+ async analyzeRepository(owner: string, repo: string) {
+ const key = `repo:${owner}:${repo}`;
+ const cached = await redis.get(key);
+
+ if (cached) {
+ return JSON.parse(cached);
+ }
+
+ const result = await super.analyzeRepository(owner, repo);
+ await redis.setex(key, 3600, JSON.stringify(result)); // 1 hour cache
+
+ return result;
+ }
+}
+```
+
+### 2. Background Processing
+
+For large repositories, use background jobs:
+
+```typescript
+import Bull from 'bull';
+
+const readmeQueue = new Bull('readme generation');
+
+// API route for immediate response
+export async function POST(request: Request) {
+ const { githubUrl } = await request.json();
+
+ const job = await readmeQueue.add('generate', { githubUrl });
+
+ return Response.json({
+ jobId: job.id,
+ status: 'queued',
+ });
+}
+
+// Background worker
+readmeQueue.process('generate', async (job) => {
+ const { githubUrl } = job.data;
+ const generator = new MultiStepReadmeGenerator(...);
+
+ return generator.generateReadme(githubUrl);
+});
+```
+
+### 3. Streaming Responses
+
+Stream sections as they're generated:
+
+```typescript
+export async function POST(request: Request) {
+ const { githubUrl } = await request.json();
+
+ const stream = new ReadableStream({
+ async start(controller) {
+ const generator = new MultiStepReadmeGenerator(...);
+
+ // Override assembler to stream results
+ const originalAssembler = generator.assembler;
+ generator.assembler.generateSectionsInBatches = async (...args) => {
+ // Stream each section as it's completed
+ // Implementation details...
+ };
+
+ const result = await generator.generateReadme(githubUrl);
+ controller.close();
+ },
+ });
+
+ return new Response(stream, {
+ headers: {
+ 'Content-Type': 'text/event-stream',
+ 'Cache-Control': 'no-cache',
+ 'Connection': 'keep-alive',
+ },
+ });
+}
+```
+
+## ๐งช Testing
+
+### Unit Tests
+
+```typescript
+// __tests__/readme-generator.test.ts
+import { MultiStepReadmeGenerator, RepositoryAnalyzer } from '@/lib/multi-step-readme-generator';
+
+describe('MultiStepReadmeGenerator', () => {
+ it('should generate complete README for public repository', async () => {
+ const generator = new MultiStepReadmeGenerator(
+ process.env.GEMINI_API_KEY,
+ process.env.GITHUB_TOKEN
+ );
+
+ const result = await generator.generateReadme(
+ 'https://github.com/octocat/Hello-World'
+ );
+
+ expect(result.success).toBe(true);
+ expect(result.readme).toContain('# Hello-World');
+ expect(result.stats.sectionsGenerated).toBeGreaterThan(0);
+ });
+});
+```
+
+### Integration Tests
+
+```typescript
+describe('API Integration', () => {
+ it('should handle README generation request', async () => {
+ const response = await fetch('/api/generate', {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify({
+ githubUrl: 'https://github.com/octocat/Hello-World'
+ }),
+ });
+
+ const result = await response.json();
+
+ expect(response.status).toBe(200);
+ expect(result.success).toBe(true);
+ expect(result.readme).toBeDefined();
+ });
+});
+```
+
+## ๐ API Reference
+
+### Main Classes
+
+- **`MultiStepReadmeGenerator`**: Main orchestrator class
+- **`RepositoryAnalyzer`**: Analyzes GitHub repositories
+- **`SectionPlanner`**: Plans optimal README sections
+- **`SectionGenerator`**: Generates individual sections
+- **`ReadmeAssembler`**: Assembles and validates final README
+
+### Configuration Options
+
+```typescript
+interface GenerationConfig {
+ maxRetries: number; // Default: 3
+ maxTokensPerSection: number; // Default: 800
+ temperature: number; // Default: 0.7
+ concurrentSections: number; // Default: 3
+ enableContinuation: boolean; // Default: true
+}
+```
+
+### Section Types
+
+- **Critical**: `header`, `description`, `installation`
+- **High**: `features`, `usage`, `api`
+- **Medium**: `configuration`, `development`, `contributing`, `deployment`
+- **Low**: `testing`, `examples`
+
+This comprehensive integration guide provides everything needed to successfully implement the multi-step README generation pipeline in the ReadmeGenAI project, solving the token limit issues while providing a more robust and reliable generation process.
\ No newline at end of file
diff --git a/public/robots.txt b/public/robots.txt
new file mode 100644
index 0000000..8603b53
--- /dev/null
+++ b/public/robots.txt
@@ -0,0 +1,9 @@
+# *
+User-agent: *
+Allow: /
+
+# Host
+Host: https://readmegen-ai.vercel.app
+
+# Sitemaps
+Sitemap: https://readmegen-ai.vercel.app/sitemap.xml
diff --git a/public/sitemap-0.xml b/public/sitemap-0.xml
new file mode 100644
index 0000000..2f06acb
--- /dev/null
+++ b/public/sitemap-0.xml
@@ -0,0 +1,8 @@
+
+
+https://readmegen-ai.vercel.app2026-04-04T06:46:25.330Zweekly1
+https://readmegen-ai.vercel.app/docs2026-04-04T06:46:25.330Zmonthly0.8
+https://readmegen-ai.vercel.app/examples2026-04-04T06:46:25.330Zmonthly0.8
+https://readmegen-ai.vercel.app/features2026-04-04T06:46:25.330Zmonthly0.8
+https://readmegen-ai.vercel.app/generate2026-04-04T06:46:25.330Zweekly0.9
+
\ No newline at end of file
diff --git a/public/sitemap.xml b/public/sitemap.xml
new file mode 100644
index 0000000..b3a9e11
--- /dev/null
+++ b/public/sitemap.xml
@@ -0,0 +1,4 @@
+
+
+https://readmegen-ai.vercel.app/sitemap-0.xml
+
\ No newline at end of file
diff --git a/src/app/api/generate/route.ts b/src/app/api/generate/route.ts
index acb17e5..41d7c29 100644
--- a/src/app/api/generate/route.ts
+++ b/src/app/api/generate/route.ts
@@ -1,40 +1,36 @@
-import { NextResponse } from "next/server";
-import { getGeminiModel } from "@/lib/gemini";
-import { getRepoData, getRepoContents } from "@/lib/octokit";
-import { SUPPORTED_LANGUAGES } from "@/constants/languages";
+import { NextRequest, NextResponse } from "next/server";
+import { MultiStepReadmeGenerator } from "@/lib/multi-step-readme-generator";
export const dynamic = "force-dynamic";
/**
- * AI README Generation Endpoint
- * Optimized for data accuracy, clean prompt interpolation, and multi-language support.
+ * Enhanced Multi-Step README Generation Endpoint
*
- * @param {Request} req - The incoming Next.js/standard Web API Request object containing the repo URL and optional language.
- * @returns {Promise} A JSON response containing the generated Markdown or an error message.
+ * This endpoint uses a sophisticated multi-step approach to generate READMEs:
+ * 1. Repository Analysis - Smart analysis with token-conscious filtering
+ * 2. Section Planning - Dynamic sections based on project type
+ * 3. Section Generation - Individual section generation within token limits
+ * 4. Assembly & Validation - Retry logic and fallback mechanisms
+ *
+ * Fixes token limit issues from issue #101 by generating sections individually.
*/
-export async function POST(req: Request) {
- let rawUrl: string;
- let language: string;
+export async function POST(request: NextRequest) {
try {
- const body = await req.json();
- rawUrl = body.url;
- language = body.language || "English";
- } catch {
- return NextResponse.json({ error: "Invalid JSON body" }, { status: 400 });
- }
+ const body = await request.json();
+ const { url: githubUrl } = body;
- try {
- const trimmedUrl = rawUrl?.trim();
- if (!trimmedUrl) {
+ // Validate required fields
+ if (!githubUrl) {
return NextResponse.json(
{ error: "GitHub URL is required" },
{ status: 400 },
);
}
+ // Validate GitHub URL format
let parsedUrl: URL;
try {
- parsedUrl = new URL(trimmedUrl);
+ parsedUrl = new URL(githubUrl.trim());
} catch {
return NextResponse.json(
{ error: "Please provide a valid URL" },
@@ -63,107 +59,78 @@ export async function POST(req: Request) {
);
}
- const [repoInfo, repoContents] = await Promise.all([
- getRepoData(owner, repo),
- getRepoContents(owner, repo),
- ]);
-
- const files = Array.isArray(repoContents)
- ? repoContents.map((f: { name: string }) => f.name)
- : [];
- const fileListString =
- files.length > 0 ? files.join(", ") : "Standard repository structure";
-
- // Tech Stack detection logic
- const hasNode = files.includes("package.json");
- const hasPython =
- files.includes("requirements.txt") || files.includes("setup.py");
- const hasDocker =
- files.includes("Dockerfile") || files.includes("docker-compose.yml");
-
- // Fix: Cleanly joined Tech Stack labels
- const stackLabels =
- [
- hasNode && "Node.js Environment",
- hasPython && "Python Environment",
- hasDocker && "Containerized",
- ]
- .filter(Boolean)
- .join(", ") || "Generic Software Environment";
-
- // Fix: Dynamic License detection
- const licenseName =
- repoInfo?.license?.name ||
- repoInfo?.license?.spdx_id ||
- "the repository's license file";
-
- const model = getGeminiModel();
-
- // Fix: Prompt updated with neutral fallbacks and dynamic license
- const prompt = `
-**Role**: You are a Principal Solutions Architect and World-Class Technical Writer.
-**Task**: Generate a professional, high-conversion README.md for the GitHub repository: "${repo}" in the following language: **${language}**.
-
----
-### 1. PROJECT CONTEXT (VERIFIED DATA)
-- **Project Name**: ${repo}
-- **Description**: ${repoInfo?.description || "No description provided."}
-- **Primary Language**: ${repoInfo?.language || "Language unknown"}
-- **Detected Root Files**: ${fileListString}
-- **Tech Stack Context**: ${stackLabels}
-
----
-### 2. STRICT README STRUCTURE REQUIREMENTS
-
-1. **Visual Header**:
- - Center-aligned H1 with project name.
- - A compelling 1-sentence tagline describing the **Value Proposition**.
- - A centered row of Shields.io badges (Build, License, PRs Welcome, Stars).
-
-2. **The Strategic "Why" (Overview)**:
- - **The Problem**: Use a blockquote to describe the real-world pain point this project solves.
- - **The Solution**: Explain how this project provides a superior outcome for the user.
-
-3. **Key Features**:
- - Minimum 5 features. Use emojis and focus on **User Benefits**.
-
-4. **Technical Architecture**:
- - Provide a table of the tech stack: | Technology | Purpose | Key Benefit |.
- - Create a tree-style directory structure code block using ๐ for folders and ๐ for files based on the file manifest provided.
-
-5. **Operational Setup**:
- - **Prerequisites**: List required runtimes.
- - **Installation**: Provide step-by-step terminal commands.
- ${hasNode ? "- Use npm/yarn/pnpm since package.json was detected." : ""}
- ${hasPython ? "- Use pip/venv since Python markers were detected." : ""}
- - **Environment**: If any .env or config files are in the manifest, include a configuration section.
-
-6. **Community & Governance**:
- - Professional "Contributing" section (Fork -> Branch -> PR).
- - Detailed "License" section: Reference ${licenseName} and provide a summary of permissions.
-
----
-### 3. TONE & STYLE
-- **Tone**: Authoritative, polished, and developer-centric.
-- **Visuals**: Extensive use of Markdown formatting.
-- **Constraint**: Return ONLY the raw Markdown. No conversational filler.
- `;
-
- const result = await model.generateContent(prompt);
- const response = await result.response;
- const markdown = response.text().trim();
- const cleanMarkdown = markdown
- .replace(/^```(markdown|md)?\n/, "")
- .replace(/\n```$/, "");
+ // Initialize the multi-step generator with enhanced configuration
+ const generator = new MultiStepReadmeGenerator(
+ process.env.GEMINI_API_KEY!,
+ process.env.GITHUB_TOKEN, // Optional GitHub token for higher rate limits
+ {
+ maxRetries: 3,
+ maxTokensPerSection: 800, // Smaller token limit per section
+ temperature: 0.7,
+ concurrentSections: 3, // Generate multiple sections in parallel
+ enableContinuation: true, // Enable automatic continuation for truncated content
+ },
+ );
- return NextResponse.json({ markdown: cleanMarkdown });
- } catch (error: unknown) {
- const message =
- error instanceof Error ? error.message : "Internal Server Error";
- console.error("README Generation Failed:", message);
+ // Generate README with detailed tracking
+ const startTime = Date.now();
+ console.log("Starting multi-step README generation for", githubUrl);
+
+ const result = await generator.generateReadme(githubUrl);
+ const endTime = Date.now();
+
+ // Log generation statistics for monitoring
+ console.log("README generation completed for", githubUrl, {
+ success: result.success,
+ sectionsGenerated: result.stats.sectionsGenerated,
+ sectionsTotal: result.stats.sectionsTotal,
+ tokensUsed: result.stats.tokensUsed,
+ timeElapsed: endTime - startTime,
+ errors: result.errors.length,
+ });
+
+ if (!result.success) {
+ console.error("README generation failed:", result.errors);
+ return NextResponse.json(
+ {
+ error: "Failed to generate README using multi-step pipeline",
+ details: result.errors,
+ stats: result.stats,
+ },
+ { status: 500 },
+ );
+ }
+ // Return successful result with enhanced metadata
+ return NextResponse.json({
+ success: true,
+ markdown: result.readme, // Keep 'markdown' key for compatibility with existing frontend
+ stats: {
+ sectionsGenerated: result.stats.sectionsGenerated,
+ sectionsTotal: result.stats.sectionsTotal,
+ tokensUsed: result.stats.tokensUsed,
+ timeElapsed: result.stats.timeElapsed,
+ generationMethod: "multi-step", // Indicate the method used
+ },
+ metadata: {
+ name: result.metadata?.name,
+ description: result.metadata?.description,
+ language: result.metadata?.language,
+ stars: result.metadata?.stars,
+ license: result.metadata?.license,
+ projectType: result.structure?.projectType,
+ techStack: result.structure?.techStack.primary,
+ frameworks: result.structure?.techStack.frameworks,
+ },
+ warnings: result.errors.length > 0 ? result.errors : undefined,
+ });
+ } catch (error) {
+ console.error("Multi-step README generation API error:", error);
return NextResponse.json(
- { error: "Failed to generate README. Check your URL and try again." },
+ {
+ error: "Internal server error in multi-step README generation",
+ message: error instanceof Error ? error.message : "Unknown error",
+ },
{ status: 500 },
);
}
diff --git a/src/app/api/generate/route.ts.backup b/src/app/api/generate/route.ts.backup
new file mode 100644
index 0000000..acb17e5
--- /dev/null
+++ b/src/app/api/generate/route.ts.backup
@@ -0,0 +1,170 @@
+import { NextResponse } from "next/server";
+import { getGeminiModel } from "@/lib/gemini";
+import { getRepoData, getRepoContents } from "@/lib/octokit";
+import { SUPPORTED_LANGUAGES } from "@/constants/languages";
+
+export const dynamic = "force-dynamic";
+
+/**
+ * AI README Generation Endpoint
+ * Optimized for data accuracy, clean prompt interpolation, and multi-language support.
+ *
+ * @param {Request} req - The incoming Next.js/standard Web API Request object containing the repo URL and optional language.
+ * @returns {Promise} A JSON response containing the generated Markdown or an error message.
+ */
+export async function POST(req: Request) {
+ let rawUrl: string;
+ let language: string;
+ try {
+ const body = await req.json();
+ rawUrl = body.url;
+ language = body.language || "English";
+ } catch {
+ return NextResponse.json({ error: "Invalid JSON body" }, { status: 400 });
+ }
+
+ try {
+ const trimmedUrl = rawUrl?.trim();
+ if (!trimmedUrl) {
+ return NextResponse.json(
+ { error: "GitHub URL is required" },
+ { status: 400 },
+ );
+ }
+
+ let parsedUrl: URL;
+ try {
+ parsedUrl = new URL(trimmedUrl);
+ } catch {
+ return NextResponse.json(
+ { error: "Please provide a valid URL" },
+ { status: 400 },
+ );
+ }
+
+ if (
+ parsedUrl.hostname !== "github.com" &&
+ parsedUrl.hostname !== "www.github.com"
+ ) {
+ return NextResponse.json(
+ { error: "Only GitHub URLs are supported" },
+ { status: 400 },
+ );
+ }
+
+ const pathSegments = parsedUrl.pathname.split("/").filter(Boolean);
+ const owner = pathSegments[0];
+ const repo = pathSegments[1];
+
+ if (!owner || !repo) {
+ return NextResponse.json(
+ { error: "URL must include owner and repository name" },
+ { status: 400 },
+ );
+ }
+
+ const [repoInfo, repoContents] = await Promise.all([
+ getRepoData(owner, repo),
+ getRepoContents(owner, repo),
+ ]);
+
+ const files = Array.isArray(repoContents)
+ ? repoContents.map((f: { name: string }) => f.name)
+ : [];
+ const fileListString =
+ files.length > 0 ? files.join(", ") : "Standard repository structure";
+
+ // Tech Stack detection logic
+ const hasNode = files.includes("package.json");
+ const hasPython =
+ files.includes("requirements.txt") || files.includes("setup.py");
+ const hasDocker =
+ files.includes("Dockerfile") || files.includes("docker-compose.yml");
+
+ // Fix: Cleanly joined Tech Stack labels
+ const stackLabels =
+ [
+ hasNode && "Node.js Environment",
+ hasPython && "Python Environment",
+ hasDocker && "Containerized",
+ ]
+ .filter(Boolean)
+ .join(", ") || "Generic Software Environment";
+
+ // Fix: Dynamic License detection
+ const licenseName =
+ repoInfo?.license?.name ||
+ repoInfo?.license?.spdx_id ||
+ "the repository's license file";
+
+ const model = getGeminiModel();
+
+ // Fix: Prompt updated with neutral fallbacks and dynamic license
+ const prompt = `
+**Role**: You are a Principal Solutions Architect and World-Class Technical Writer.
+**Task**: Generate a professional, high-conversion README.md for the GitHub repository: "${repo}" in the following language: **${language}**.
+
+---
+### 1. PROJECT CONTEXT (VERIFIED DATA)
+- **Project Name**: ${repo}
+- **Description**: ${repoInfo?.description || "No description provided."}
+- **Primary Language**: ${repoInfo?.language || "Language unknown"}
+- **Detected Root Files**: ${fileListString}
+- **Tech Stack Context**: ${stackLabels}
+
+---
+### 2. STRICT README STRUCTURE REQUIREMENTS
+
+1. **Visual Header**:
+ - Center-aligned H1 with project name.
+ - A compelling 1-sentence tagline describing the **Value Proposition**.
+ - A centered row of Shields.io badges (Build, License, PRs Welcome, Stars).
+
+2. **The Strategic "Why" (Overview)**:
+ - **The Problem**: Use a blockquote to describe the real-world pain point this project solves.
+ - **The Solution**: Explain how this project provides a superior outcome for the user.
+
+3. **Key Features**:
+ - Minimum 5 features. Use emojis and focus on **User Benefits**.
+
+4. **Technical Architecture**:
+ - Provide a table of the tech stack: | Technology | Purpose | Key Benefit |.
+ - Create a tree-style directory structure code block using ๐ for folders and ๐ for files based on the file manifest provided.
+
+5. **Operational Setup**:
+ - **Prerequisites**: List required runtimes.
+ - **Installation**: Provide step-by-step terminal commands.
+ ${hasNode ? "- Use npm/yarn/pnpm since package.json was detected." : ""}
+ ${hasPython ? "- Use pip/venv since Python markers were detected." : ""}
+ - **Environment**: If any .env or config files are in the manifest, include a configuration section.
+
+6. **Community & Governance**:
+ - Professional "Contributing" section (Fork -> Branch -> PR).
+ - Detailed "License" section: Reference ${licenseName} and provide a summary of permissions.
+
+---
+### 3. TONE & STYLE
+- **Tone**: Authoritative, polished, and developer-centric.
+- **Visuals**: Extensive use of Markdown formatting.
+- **Constraint**: Return ONLY the raw Markdown. No conversational filler.
+ `;
+
+ const result = await model.generateContent(prompt);
+ const response = await result.response;
+ const markdown = response.text().trim();
+ const cleanMarkdown = markdown
+ .replace(/^```(markdown|md)?\n/, "")
+ .replace(/\n```$/, "");
+
+ return NextResponse.json({ markdown: cleanMarkdown });
+ } catch (error: unknown) {
+ const message =
+ error instanceof Error ? error.message : "Internal Server Error";
+ console.error("README Generation Failed:", message);
+
+ return NextResponse.json(
+ { error: "Failed to generate README. Check your URL and try again." },
+ { status: 500 },
+ );
+ }
+}
diff --git a/src/components/Generator/SearchInput.tsx b/src/components/Generator/SearchInput.tsx
index dc3829b..d590c90 100644
--- a/src/components/Generator/SearchInput.tsx
+++ b/src/components/Generator/SearchInput.tsx
@@ -29,20 +29,6 @@ export const SearchInput = ({
const [language, setLanguage] = useState("English");
const [error, setError] = useState(null);
- const languages = [
- "English",
- "Spanish",
- "French",
- "German",
- "Chinese",
- "Japanese",
- "Korean",
- "Portuguese",
- "Russian",
- "Arabic",
- "Turkish",
- ];
-
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
setError(null);
@@ -88,7 +74,7 @@ export const SearchInput = ({
onChange={(e) => setLanguage(e.target.value)}
className="bg-zinc-900/50 border border-white/10 rounded-2xl px-6 py-6 text-white focus:outline-none focus:ring-2 focus:ring-blue-500/50 transition-all backdrop-blur-xl appearance-none cursor-pointer min-w-[140px]"
>
- {languages.map((lang) => (
+ {SUPPORTED_LANGUAGES.map((lang) => (
+
+Requirements:
+- Use HTML for perfect alignment
+- Create an engaging tagline that explains what the project does
+- Include realistic badge URLs appropriate for ${structure.projectType} projects
+- Make it visually appealing and professional
+- Add a horizontal rule (---) after the header
+
+Return only the markdown/HTML content, no explanations.`,
+
+ description: `Generate a compelling strategic description section for "${metadata.name}".
+
+Context: ${baseContext}
+Project Type: ${structure.projectType}
+Technologies: ${structure.techStack.primary}, ${structure.techStack.frameworks.join(", ")}
+
+Create two main sections:
+
+## The Strategic "Why"
+> Start with a blockquote explaining the problem this project solves. What pain point does it address? Why does this project exist?
+
+Follow with 2-3 paragraphs that explain:
+- The core problem in the industry/domain
+- How this project solves it uniquely
+- The value it provides to users
+- Who the target audience is
+
+Make it engaging and professional. Focus on the business case and user benefits, not just technical features.
+
+Requirements:
+- Start with "## The Strategic \"Why\"" as the section header
+- Use blockquote (>) for the opening problem statement
+- Write in a professional, compelling tone
+- Avoid technical jargon - focus on benefits
+- 3-4 well-structured paragraphs total
+- No placeholder text - create realistic, specific content
+
+Return only the markdown content.`,
+
+ features: `Generate a comprehensive "Key Features" section for "${metadata.name}".
+
+Context: ${baseContext}
+Tech Stack: ${structure.techStack.primary}, ${structure.techStack.frameworks.join(", ")}
+Project Type: ${structure.projectType}
+
+Create a section called "## Key Features" with 6-8 compelling features that highlight:
+- Core functionality and capabilities
+- Technical advantages (performance, scalability, etc.)
+- User experience benefits
+- Integration capabilities
+- Developer experience improvements
+
+Format each feature as:
+* ๐ **Feature Name**: Clear description explaining the benefit and impact
+
+Example format:
+## Key Features
+
+* โจ **AI-Powered Analysis**: Intelligently parses your repository's code, dependencies, and structure to understand its core purpose and components.
+* ๐ **Instant Generation**: Get a complete, production-ready solution in mere seconds, drastically reducing development overhead.
+
+Requirements:
+- Use bullet points with meaningful emojis
+- Bold the feature name
+- Focus on user benefits, not just technical specs
+- Make each description 1-2 sentences
+- Use action-oriented language
+- Be specific about value propositions
+- No placeholder content - generate realistic features based on the project type
+
+Return only the markdown content.`,
+
+ installation: `Generate comprehensive installation and setup instructions for "${metadata.name}".
+
+Context: ${baseContext}
+Package Files: ${structure.packageFiles.join(", ")}
+Tech Stack: ${structure.techStack.primary}
+Project Type: ${structure.projectType}
+
+Create a detailed "## Operational Setup" section with:
+
+### Prerequisites
+List specific software requirements with versions
+
+### Installation
+Step-by-step installation process with multiple package managers if applicable
+
+### Environment Configuration
+Explain any required environment variables or configuration files
+
+Format example:
+## Operational Setup
+
+Follow these steps to get ${metadata.name} up and running on your local machine.
+
+### Prerequisites
+
+Ensure you have the following installed:
+
+* **Node.js**: LTS version (e.g., 18.x or 20.x)
+* **npm** (Node Package Manager), **yarn**, or **pnpm** (preferred)
+
+### Installation
+
+1. **Clone the repository**:
+ \`\`\`bash
+ git clone https://github.com/user/repo.git
+ cd repo
+ \`\`\`
+
+2. **Install dependencies**:
+ [Include commands for different package managers]
+
+3. **Start the development server**:
+ [Include appropriate start commands]
+
+### Environment Configuration
+[Explain .env setup if needed]
+
+Requirements:
+- Use numbered lists for steps
+- Include code blocks with proper syntax highlighting
+- Provide multiple installation options when relevant
+- Be specific about versions and requirements
+- Include verification steps
+- No placeholder content
+
+Return only the markdown content.`,
+
+ usage: `Generate usage examples for "${metadata.name}".
+
+Context: ${baseContext}
+Project Type: ${structure.projectType}
+
+Requirements:
+- Basic usage example
+- Code examples with syntax highlighting
+- Input/output examples if applicable
+- Common use cases
+- Links to more examples if needed
+
+Return only the markdown content.`,
+
+ api: `Generate API documentation section for "${metadata.name}".
+
+Context: ${baseContext}
+
+Requirements:
+- API overview
+- Authentication (if applicable)
+- Main endpoints or functions
+- Request/response examples
+- Error handling
+
+Return only the markdown content.`,
+
+ configuration: `Generate configuration section for "${metadata.name}".
+
+Context: ${baseContext}
+Config Files: ${structure.configFiles.join(", ")}
+
+Requirements:
+- Configuration options
+- Environment variables
+- Config file examples
+- Default values
+- Important settings
+
+Return only the markdown content.`,
+
+ development: `Generate development setup section for "${metadata.name}".
+
+Context: ${baseContext}
+
+Requirements:
+- Local development setup
+- Development dependencies
+- Build process
+- Development server
+- File structure overview
+
+Return only the markdown content.`,
+
+ contributing: `Generate comprehensive contributing guidelines for "${metadata.name}".
+
+Context: ${baseContext}
+Project Type: ${structure.projectType}
+
+Create a detailed section explaining how to contribute with:
+- Welcoming introduction
+- Step-by-step contribution process
+- Code standards and requirements
+- Reference to code of conduct
+
+Format as subsection of larger "Community & Governance" section:
+
+### Contributing
+
+We encourage and appreciate community contributions. If you're looking to contribute, please follow these guidelines:
+
+1. **Fork** the repository.
+2. **Create a new branch** for your feature or bug fix: \`git checkout -b feature/your-feature-name\` or \`bugfix/issue-description\`.
+3. **Commit your changes** with clear and concise messages.
+4. **Push your branch** to your forked repository.
+5. **Open a Pull Request** against the \`main\` branch of this repository, describing your changes in detail.
+
+Please ensure your code adheres to the project's coding standards and includes appropriate tests. For more details, please refer to our [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md).
+
+Requirements:
+- Welcoming and encouraging tone
+- Clear step-by-step process
+- Mention testing and code standards
+- Professional formatting
+- No placeholder content
+
+Return only the markdown content.`,
+
+ deployment: `Generate deployment section for "${metadata.name}".
+
+Context: ${baseContext}
+Project Type: ${structure.projectType}
+
+Requirements:
+- Deployment options
+- Build process
+- Environment setup
+- Platform-specific instructions
+- Best practices
+
+Return only the markdown content.`,
+
+ examples: `Generate examples section for "${metadata.name}".
+
+Context: ${baseContext}
+
+Requirements:
+- Code examples
+- Use case scenarios
+- Working demos
+- Integration examples
+- Links to live examples
+
+Return only the markdown content.`,
+
+ testing: `Generate testing section for "${metadata.name}".
+
+Context: ${baseContext}
+Tools: ${structure.techStack.tools.join(", ")}
+
+Requirements:
+- How to run tests
+- Test types available
+- Coverage information
+- Writing tests
+- Testing best practices
+
+Return only the markdown content.`,
+
+ license: `Generate a professional license section for "${metadata.name}".
+
+Context: ${baseContext}
+License: ${metadata.license || "MIT License"}
+
+Create a comprehensive "## Community & Governance" section that includes:
+
+### Contributing subsection
+### License subsection with detailed explanation
+
+Format example:
+## Community & Governance
+
+We welcome contributions and feedback from the community to make ${metadata.name} even better!
+
+### Contributing
+
+We encourage and appreciate community contributions. If you're looking to contribute, please follow these guidelines:
+
+1. **Fork** the repository.
+2. **Create a new branch** for your feature or bug fix: \`git checkout -b feature/your-feature-name\`.
+3. **Commit your changes** with clear and concise messages.
+4. **Push your branch** to your forked repository.
+5. **Open a Pull Request** against the \`main\` branch, describing your changes in detail.
+
+### License
+
+This project is licensed under the **${metadata.license || "MIT License"}**.
+
+[Include 2-3 sentences explaining what this license allows and its key terms]
+
+For the full text of the license, please see the [LICENSE](LICENSE) file in this repository.
+
+Requirements:
+- Professional, welcoming tone
+- Clear contribution process
+- Detailed license explanation
+- No placeholder content
+
+Return only the markdown content.`,
+
+ architecture: `Generate a comprehensive "Technical Architecture" section for "${metadata.name}".
+
+Context: ${baseContext}
+Tech Stack: ${structure.techStack.primary}, ${structure.techStack.frameworks.join(", ")}, ${structure.techStack.tools.join(", ")}
+Project Type: ${structure.projectType}
+
+Create a section that includes:
+1. Architecture overview paragraph
+2. Technology stack table
+3. Key benefits explanation
+
+Format example:
+## Technical Architecture
+
+${metadata.name} is built on a robust and modern tech stack designed for performance, scalability, and an excellent developer experience.
+
+| Technology | Purpose | Key Benefit |
+| :------------ | :------------------------- | :----------------------------------------- |
+| **Technology1** | Primary Purpose | Main advantage or benefit |
+| **Technology2**| Secondary Purpose | Performance/Developer experience benefit |
+
+Requirements:
+- Start with compelling architecture description
+- Use a well-formatted table with technology, purpose, and benefit columns
+- Include 4-8 key technologies from the tech stack
+- Focus on business benefits, not just technical specs
+- Professional tone
+- No placeholder content - use actual technologies detected
+
+Return only the markdown content.`,
+
+ structure: `Generate a "Directory Structure" visualization for "${metadata.name}".
+
+Context: ${baseContext}
+Directories: ${structure.directories.join(", ")}
+Root Files: ${structure.rootFiles.join(", ")}
+Project Type: ${structure.projectType}
+
+Create a section with:
+1. Brief introduction
+2. Tree-style directory structure
+3. Explanations for key directories/files
+
+Format example:
+### Directory Structure
+
+\`\`\`
+.
+โโโ ๐ directory1 # Purpose description
+โโโ ๐ directory2 # Purpose description
+โโโ ๐ important-file.json # File description
+โโโ ๐ config-file.js # Configuration file purpose
+โโโ ๐ README.md # This README file
+\`\`\`
+
+Requirements:
+- Use tree structure with appropriate Unicode characters
+- Add folder (๐) and file (๐) emojis
+- Include brief descriptions for each major item
+- Focus on the most important 8-12 items
+- Make descriptions helpful for new developers
+- Use actual directories and files detected in the repository
+
+Return only the markdown content.`,
+ };
+
+ return (
+ sectionPrompts[sectionId] ||
+ this.buildGenericSectionPrompt(sectionId, metadata, structure)
+ );
+ }
+
+ /**
+ * Build base context string to avoid repetition
+ */
+ private buildBaseContext(
+ metadata: RepositoryMetadata,
+ structure: RepositoryStructure,
+ ): string {
+ return `
+Repository: ${metadata.name}
+Description: ${metadata.description || "No description provided"}
+Language: ${metadata.language || "Multiple"}
+Stars: ${metadata.stars}
+Project Type: ${structure.projectType}
+Primary Tech: ${structure.techStack.primary}
+Frameworks: ${structure.techStack.frameworks.join(", ") || "None"}
+`.trim();
+ }
+
+ /**
+ * Generic section prompt for unknown sections
+ */
+ private buildGenericSectionPrompt(
+ sectionId: string,
+ metadata: RepositoryMetadata,
+ structure: RepositoryStructure,
+ ): string {
+ return `Generate a "${sectionId}" section for the repository "${metadata.name}".
+
+Context: ${this.buildBaseContext(metadata, structure)}
+
+Requirements:
+- Professional markdown format
+- Clear and concise content
+- Relevant to the project type
+- Follow README best practices
+
+Return only the markdown content.`;
+ }
+
+ /**
+ * Continue generation for truncated content
+ */
+ private async continueGeneration(
+ sectionId: string,
+ partialContent: string,
+ metadata: RepositoryMetadata,
+ structure: RepositoryStructure,
+ ): Promise {
+ const prompt = `Continue the following "${sectionId}" section for "${metadata.name}":
+
+${partialContent}
+
+Project Context: ${this.buildBaseContext(metadata, structure)}
+
+Continue from where it left off. Complete the section with proper markdown formatting.
+Return only the continuation content.`;
+
+ return this.callAI(prompt, `${sectionId}-continuation`);
+ }
+
+ /**
+ * Call AI model with proper error handling and token management
+ */
+ private async callAI(
+ prompt: string,
+ sectionId: string,
+ ): Promise {
+ try {
+ const model = this.genAI.getGenerativeModel({
+ model: "gemini-1.5-pro",
+ generationConfig: {
+ temperature: this.config.temperature,
+ topP: 0.95,
+ maxOutputTokens: this.config.maxTokensPerSection,
+ },
+ });
+
+ const result = await model.generateContent(prompt);
+ const response = result.response;
+ const content = response.text();
+
+ // Check if response was truncated
+ const truncated = this.isResponseTruncated(content, sectionId);
+
+ return {
+ success: true,
+ content: content.trim(),
+ tokensUsed: this.estimateTokens(prompt + content),
+ truncated,
+ };
+ } catch (error) {
+ return {
+ success: false,
+ error: `AI generation failed: ${error}`,
+ };
+ }
+ }
+
+ /**
+ * Detect if response was truncated
+ */
+ private isResponseTruncated(content: string, sectionId: string): boolean {
+ const truncationIndicators = [
+ "...",
+ "truncated",
+ "continued",
+ "[end of response]",
+ ];
+
+ const contentLower = content.toLowerCase();
+ const hasIndicators = truncationIndicators.some((indicator) =>
+ contentLower.includes(indicator),
+ );
+
+ // Check if content ends abruptly without proper markdown closure
+ const endsAbruptly =
+ !content.trim().endsWith(".") &&
+ !content.trim().endsWith("\n") &&
+ content.length > 100;
+
+ // Section-specific checks
+ const sectionChecks: Record = {
+ installation: !content.includes("```") && content.length > 200,
+ usage: !content.includes("```") && content.length > 200,
+ api: !content.includes("```") && content.length > 300,
+ };
+
+ return hasIndicators || endsAbruptly || sectionChecks[sectionId] || false;
+ }
+
+ /**
+ * Estimate token usage (rough approximation)
+ */
+ private estimateTokens(text: string): number {
+ // Rough estimation: 1 token โ 4 characters for English text
+ return Math.ceil(text.length / 4);
+ }
+}
+
+// ============================================================================
+// README ASSEMBLER WITH RETRY LOGIC
+// ============================================================================
+
+export class ReadmeAssembler {
+ private sectionGenerator: SectionGenerator;
+ private config: GenerationConfig;
+
+ constructor(
+ sectionGenerator: SectionGenerator,
+ config: Partial = {},
+ ) {
+ this.sectionGenerator = sectionGenerator;
+ this.config = {
+ maxRetries: 3,
+ maxTokensPerSection: 800,
+ temperature: 0.7,
+ concurrentSections: 3,
+ enableContinuation: true,
+ ...config,
+ };
+ }
+
+ /**
+ * Generate complete README with retry logic and section management
+ */
+ async generateCompleteReadme(
+ metadata: RepositoryMetadata,
+ structure: RepositoryStructure,
+ customSections?: ReadmeSection[],
+ ): Promise<{
+ success: boolean;
+ readme?: string;
+ sectionsGenerated: number;
+ sectionsTotal: number;
+ errors: string[];
+ tokensUsed: number;
+ }> {
+ // Plan sections
+ const sections =
+ customSections || SectionPlanner.planSections(metadata, structure);
+ const optimizedSections = SectionPlanner.optimizeSectionOrder(sections);
+
+ const results: Record = {};
+ const errors: string[] = [];
+ let totalTokens = 0;
+
+ // Generate sections with controlled concurrency
+ await this.generateSectionsInBatches(
+ optimizedSections,
+ metadata,
+ structure,
+ results,
+ errors,
+ );
+
+ // Calculate tokens used
+ totalTokens = Object.values(results).reduce(
+ (sum, result) => sum + (result.tokensUsed || 0),
+ 0,
+ );
+
+ // Assemble final README
+ const readme = this.assembleReadme(optimizedSections, results);
+ const successfulSections = Object.values(results).filter(
+ (r) => r.success,
+ ).length;
+
+ return {
+ success: successfulSections > 0,
+ readme,
+ sectionsGenerated: successfulSections,
+ sectionsTotal: optimizedSections.length,
+ errors,
+ tokensUsed: totalTokens,
+ };
+ }
+
+ /**
+ * Generate sections in controlled batches to manage API limits
+ */
+ private async generateSectionsInBatches(
+ sections: ReadmeSection[],
+ metadata: RepositoryMetadata,
+ structure: RepositoryStructure,
+ results: Record,
+ errors: string[],
+ ): Promise {
+ const batches = this.createSectionBatches(sections);
+
+ for (let batchIndex = 0; batchIndex < batches.length; batchIndex++) {
+ const batch = batches[batchIndex];
+ console.log(
+ `Generating batch ${batchIndex + 1}/${batches.length} with sections: ${batch.map((s) => s.id).join(", ")}`,
+ );
+
+ // Generate sections in current batch concurrently
+ const batchPromises = batch.map(async (section) => {
+ const context = this.buildSectionContext(section, results);
+ const result = await this.sectionGenerator.generateSection(
+ section.id,
+ metadata,
+ structure,
+ context,
+ );
+
+ results[section.id] = result;
+
+ if (!result.success) {
+ errors.push(`Failed to generate ${section.id}: ${result.error}`);
+ }
+
+ return result;
+ });
+
+ await Promise.all(batchPromises);
+
+ // Add delay between batches to respect API limits
+ if (batchIndex < batches.length - 1) {
+ await this.delay(1000); // 1 second delay
+ }
+ }
+
+ // Retry failed critical sections
+ await this.retryFailedCriticalSections(
+ sections,
+ metadata,
+ structure,
+ results,
+ errors,
+ );
+ }
+
+ /**
+ * Create batches respecting dependencies and concurrency limits
+ */
+ private createSectionBatches(sections: ReadmeSection[]): ReadmeSection[][] {
+ const batches: ReadmeSection[][] = [];
+ const processed = new Set();
+ const remaining = [...sections];
+
+ while (remaining.length > 0) {
+ const currentBatch: ReadmeSection[] = [];
+ const toRemove: number[] = [];
+
+ for (
+ let i = 0;
+ i < remaining.length &&
+ currentBatch.length < this.config.concurrentSections;
+ i++
+ ) {
+ const section = remaining[i];
+
+ // Check if dependencies are satisfied
+ const dependenciesSatisfied = section.dependencies.every((depId) =>
+ processed.has(depId),
+ );
+
+ if (dependenciesSatisfied) {
+ currentBatch.push(section);
+ processed.add(section.id);
+ toRemove.push(i);
+ }
+ }
+
+ // Remove processed sections (in reverse order to maintain indices)
+ for (let i = toRemove.length - 1; i >= 0; i--) {
+ remaining.splice(toRemove[i], 1);
+ }
+
+ if (currentBatch.length > 0) {
+ batches.push(currentBatch);
+ } else if (remaining.length > 0) {
+ // If no sections can be processed, there might be circular dependencies
+ // Add the first remaining section to break the cycle
+ const section = remaining.shift()!;
+ processed.add(section.id);
+ batches.push([section]);
+ }
+ }
+
+ return batches;
+ }
+
+ /**
+ * Build context for section generation based on previously generated sections
+ */
+ private buildSectionContext(
+ section: ReadmeSection,
+ results: Record,
+ ): Record {
+ const context: Record = {};
+
+ for (const depId of section.dependencies) {
+ const depResult = results[depId];
+ if (depResult && depResult.success && depResult.content) {
+ context[depId] = depResult.content;
+ }
+ }
+
+ return context;
+ }
+
+ /**
+ * Retry failed critical sections with simplified prompts
+ */
+ private async retryFailedCriticalSections(
+ sections: ReadmeSection[],
+ metadata: RepositoryMetadata,
+ structure: RepositoryStructure,
+ results: Record,
+ errors: string[],
+ ): Promise {
+ const failedCriticalSections = sections.filter(
+ (section) =>
+ section.priority === "critical" &&
+ (!results[section.id] || !results[section.id].success),
+ );
+
+ if (failedCriticalSections.length === 0) {
+ return;
+ }
+
+ console.log(
+ `Retrying ${failedCriticalSections.length} failed critical sections...`,
+ );
+
+ for (const section of failedCriticalSections) {
+ try {
+ // Use simplified prompt for retry
+ const simplifiedResult = await this.generateSimplifiedSection(
+ section.id,
+ metadata,
+ structure,
+ );
+
+ if (simplifiedResult.success) {
+ results[section.id] = simplifiedResult;
+ // Remove error from errors array
+ const errorIndex = errors.findIndex((error) =>
+ error.includes(section.id),
+ );
+ if (errorIndex !== -1) {
+ errors.splice(errorIndex, 1);
+ }
+ }
+ } catch (error) {
+ console.error(`Failed to retry section ${section.id}:`, error);
+ }
+ }
+ }
+
+ /**
+ * Generate simplified version of section for fallback
+ */
+ private async generateSimplifiedSection(
+ sectionId: string,
+ metadata: RepositoryMetadata,
+ structure: RepositoryStructure,
+ ): Promise {
+ const simplifiedPrompts: Record = {
+ header: `# ${metadata.name}\n\n${metadata.description || "A software project."}\n\n`,
+ description: `## Description\n\n${metadata.description || `${metadata.name} is a ${structure.techStack.primary} project.`}`,
+ features: `## Features\n\n- Feature 1\n- Feature 2\n- Feature 3`,
+ installation: `## Installation\n\n\`\`\`bash\n# Clone the repository\ngit clone https://github.com/user/${metadata.name}.git\ncd ${metadata.name}\n\`\`\``,
+ usage: `## Usage\n\nBasic usage example:\n\n\`\`\`${structure.techStack.primary}\n// Your code here\n\`\`\``,
+ license: `## License\n\nThis project is licensed under the ${metadata.license || "MIT"} License.`,
+ };
+
+ const content =
+ simplifiedPrompts[sectionId] ||
+ `## ${sectionId.charAt(0).toUpperCase() + sectionId.slice(1)}\n\nTODO: Add ${sectionId} information.`;
+
+ return {
+ success: true,
+ content,
+ tokensUsed: this.estimateTokens(content),
+ };
+ }
+
+ /**
+ * Assemble final README from section results
+ */
+ private assembleReadme(
+ sections: ReadmeSection[],
+ results: Record,
+ ): string {
+ const readmeParts: string[] = [];
+
+ for (const section of sections) {
+ const result = results[section.id];
+
+ if (result && result.success && result.content) {
+ readmeParts.push(result.content);
+ readmeParts.push(""); // Add empty line between sections
+ } else {
+ // Add placeholder for failed sections
+ readmeParts.push(`## ${section.title}`);
+ readmeParts.push(
+ "*This section could not be generated automatically.*",
+ );
+ readmeParts.push("");
+ }
+ }
+
+ return readmeParts.join("\n").trim();
+ }
+
+ /**
+ * Utility function to add delays
+ */
+ private delay(ms: number): Promise {
+ return new Promise((resolve) => setTimeout(resolve, ms));
+ }
+
+ /**
+ * Estimate token usage
+ */
+ private estimateTokens(text: string): number {
+ return Math.ceil(text.length / 4);
+ }
+}
+
+// ============================================================================
+// MAIN MULTI-STEP README GENERATOR
+// ============================================================================
+
+export class MultiStepReadmeGenerator {
+ private analyzer: RepositoryAnalyzer;
+ private sectionGenerator: SectionGenerator;
+ private assembler: ReadmeAssembler;
+
+ constructor(
+ geminiApiKey: string,
+ githubToken?: string,
+ config: Partial = {},
+ ) {
+ this.analyzer = new RepositoryAnalyzer(githubToken);
+ this.sectionGenerator = new SectionGenerator(geminiApiKey, config);
+ this.assembler = new ReadmeAssembler(this.sectionGenerator, config);
+ }
+
+ /**
+ * Main function to generate complete README
+ */
+ async generateReadme(githubUrl: string): Promise<{
+ success: boolean;
+ readme?: string;
+ metadata?: RepositoryMetadata;
+ structure?: RepositoryStructure;
+ sections?: ReadmeSection[];
+ stats: {
+ sectionsGenerated: number;
+ sectionsTotal: number;
+ tokensUsed: number;
+ timeElapsed: number;
+ };
+ errors: string[];
+ }> {
+ const startTime = Date.now();
+
+ try {
+ // Extract owner and repo from URL
+ const { owner, repo } = this.parseGithubUrl(githubUrl);
+
+ // Step 1: Analyze repository
+ console.log("Step 1: Analyzing repository...");
+ const { metadata, structure } = await this.analyzer.analyzeRepository(
+ owner,
+ repo,
+ );
+
+ // Step 2: Plan sections
+ console.log("Step 2: Planning README sections...");
+ const sections = SectionPlanner.planSections(metadata, structure);
+
+ // Step 3: Generate README
+ console.log("Step 3: Generating README sections...");
+ const result = await this.assembler.generateCompleteReadme(
+ metadata,
+ structure,
+ sections,
+ );
+
+ const endTime = Date.now();
+
+ return {
+ success: result.success,
+ readme: result.readme,
+ metadata,
+ structure,
+ sections,
+ stats: {
+ sectionsGenerated: result.sectionsGenerated,
+ sectionsTotal: result.sectionsTotal,
+ tokensUsed: result.tokensUsed,
+ timeElapsed: endTime - startTime,
+ },
+ errors: result.errors,
+ };
+ } catch (error) {
+ const endTime = Date.now();
+
+ return {
+ success: false,
+ stats: {
+ sectionsGenerated: 0,
+ sectionsTotal: 0,
+ tokensUsed: 0,
+ timeElapsed: endTime - startTime,
+ },
+ errors: [`Generation failed: ${error}`],
+ };
+ }
+ }
+
+ /**
+ * Parse GitHub URL to extract owner and repository name
+ */
+ private parseGithubUrl(url: string): { owner: string; repo: string } {
+ const match = url.match(/github\.com\/([^\/]+)\/([^\/]+)/);
+
+ if (!match) {
+ throw new Error("Invalid GitHub URL format");
+ }
+
+ return {
+ owner: match[1],
+ repo: match[2].replace(/\.git$/, ""), // Remove .git suffix if present
+ };
+ }
+}
+
+// ============================================================================
+// INTEGRATION HELPER FOR NEXT.JS API ROUTES
+// ============================================================================
+
+export async function handleReadmeGeneration(
+ request: Request,
+): Promise {
+ try {
+ const body = await request.json();
+ const { githubUrl } = body;
+
+ if (!githubUrl) {
+ return Response.json(
+ { error: "GitHub URL is required" },
+ { status: 400 },
+ );
+ }
+
+ // Initialize generator with environment variables
+ const generator = new MultiStepReadmeGenerator(
+ process.env.GEMINI_API_KEY!,
+ process.env.GITHUB_TOKEN, // Optional
+ {
+ maxRetries: 3,
+ maxTokensPerSection: 800,
+ temperature: 0.7,
+ concurrentSections: 3,
+ enableContinuation: true,
+ },
+ );
+
+ const result = await generator.generateReadme(githubUrl);
+
+ if (!result.success) {
+ return Response.json(
+ {
+ error: "Failed to generate README",
+ details: result.errors,
+ },
+ { status: 500 },
+ );
+ }
+
+ return Response.json({
+ success: true,
+ readme: result.readme,
+ stats: result.stats,
+ metadata: {
+ name: result.metadata?.name,
+ description: result.metadata?.description,
+ language: result.metadata?.language,
+ stars: result.metadata?.stars,
+ },
+ });
+ } catch (error) {
+ return Response.json(
+ { error: `Internal server error: ${error}` },
+ { status: 500 },
+ );
+ }
+}