UNPKG

gitguide

Version:

AI-powered README generator for any project directory

466 lines (431 loc) โ€ข 18.1 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.GeminiService = void 0; const node_fetch_1 = __importDefault(require("node-fetch")); class GeminiService { constructor(apiKey) { this.apiUrl = 'https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent'; this.apiKey = apiKey; } async generateReadme(projectData) { const prompt = this.buildPrompt(projectData); const response = await (0, node_fetch_1.default)(`${this.apiUrl}?key=${this.apiKey}`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ contents: [{ parts: [{ text: prompt }] }], generationConfig: { temperature: 0.7, topK: 40, topP: 0.95, maxOutputTokens: 8000, } }) }); if (!response.ok) { const errorData = await response.json(); throw new Error(`Gemini API error: ${errorData.error?.message || 'Unknown error'}`); } const data = await response.json(); const content = data.candidates?.[0]?.content?.parts?.[0]?.text || ''; if (!content) { throw new Error('No content generated by Gemini API'); } const cleanedContent = this.cleanupGeneratedContent(content); return { content: cleanedContent, sections: this.extractSections(cleanedContent) }; } buildPrompt(projectData) { const techStack = this.detectTechStack(projectData); const projectType = this.detectProjectType(projectData); const codeAnalysis = this.analyzeCodeStructure(projectData); const fileContents = projectData.files .filter(file => file.content && file.type === 'file' && file.content.length > 10) .slice(0, 20) .map(file => `File: ${file.path}\n${file.content?.slice(0, 3000) || ''}`) .join('\n\n---\n\n'); return `You are an expert technical writer and software developer creating a comprehensive README.md for a project. CRITICAL INSTRUCTIONS: - Analyze the actual code files to understand what this application DOES - Write about the specific functionality, features, and purpose based on the code - DO NOT use generic descriptions - be specific about this project's actual capabilities - Include real installation steps based on the package.json and project structure - Mention actual components, routes, APIs, or features found in the code - If it's a CLI tool, describe the actual commands and options - If it's a web app, describe the actual pages and functionality PROJECT DETAILS: Name: ${projectData.name} Description: ${projectData.description || 'No description provided'} Primary Language: ${projectData.language || 'Not specified'} Version: ${projectData.version || '1.0.0'} Tech Stack: ${techStack} Project Type: ${projectType} Code Analysis: ${codeAnalysis} Files: ${projectData.structure.files} files across ${projectData.structure.directories} directories KEY FILES CONTENT: ${fileContents} Generate a comprehensive, professional README.md using ONLY pure markdown syntax (NO HTML tags). REQUIRED STRUCTURE: # ${projectData.name} > **${this.generateTagline(projectData, projectType)}** ${projectData.description || `A ${projectData.language} project built with modern best practices`} [![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE) [![Version](https://img.shields.io/badge/version-${projectData.version || '1.0.0'}-green.svg)]() ## โœจ Features ${this.generateFeatures(projectType, projectData)} ## ๐Ÿš€ Quick Start ### Prerequisites ${this.generatePrerequisites(projectData)} ### Installation \`\`\`bash ${this.generateInstallCommands(projectData)} \`\`\` ### Running the Application ${this.generateUsageExample(projectData, projectType)} ## ๐Ÿ“ Project Structure \`\`\` ${this.generateProjectStructure(projectData)} \`\`\` ## ๐Ÿ”ง Configuration ${this.generateConfigurationSection(projectData)} ## ๐Ÿ“– API Documentation ${this.generateApiDocumentation(projectData)} ## ๐Ÿ› ๏ธ Tech Stack ${this.generateTechStackDetails(techStack)} ## ๐Ÿ“š Documentation - [Getting Started](#-quick-start) - [Configuration](#configuration) - [API Reference](#api-reference) - [Examples](#examples) ## ๐Ÿค Contributing 1. Fork the repository 2. Create your feature branch (\`git checkout -b feature/amazing-feature\`) 3. Commit your changes (\`git commit -m 'Add amazing feature'\`) 4. Push to the branch (\`git push origin feature/amazing-feature\`) 5. Open a Pull Request ## ๐Ÿ“„ License This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. ## ๐Ÿ™ Acknowledgments - Built with ${projectData.language} - Thanks to all contributors - Inspired by modern development practices --- Made with โค๏ธ by the ${projectData.name} team REQUIREMENTS: 1. ANALYZE THE ACTUAL CODE - Don't use generic descriptions 2. Write about what this specific application actually does 3. Include real features found in the code 4. Use actual file names, component names, and functionality 5. Provide accurate installation and usage instructions 6. Use ONLY markdown syntax (no HTML) 7. Make it comprehensive but scannable 8. Include proper code formatting with language-specific syntax highlighting 9. Focus on clarity and professionalism`; } generateTagline(projectData, projectType) { const taglines = { 'Frontend Application': `๐Ÿš€ Modern ${projectData.language} application with sleek UI/UX`, 'Backend API': `โšก High-performance ${projectData.language} API built for scale`, 'Full-Stack Application': `๐Ÿ”ฅ Complete full-stack solution powered by ${projectData.language}`, 'CLI Tool': `๐Ÿ› ๏ธ Powerful command-line tool for developers`, 'Library': `๐Ÿ“š Essential ${projectData.language} library for modern development`, 'Python Application': `๐Ÿ Robust Python application with enterprise features`, 'JavaScript/Node.js Project': `โšก Modern JavaScript solution for the web`, 'default': `๐Ÿ’Ž Professional ${projectData.language} project` }; return taglines[projectType] || taglines.default; } analyzeCodeStructure(projectData) { const analysis = []; // Analyze package.json for scripts and dependencies const packageJson = projectData.files.find(f => f.name === 'package.json'); if (packageJson?.content) { try { const pkg = JSON.parse(packageJson.content); if (pkg.scripts) { analysis.push(`Available scripts: ${Object.keys(pkg.scripts).join(', ')}`); } if (pkg.bin) { analysis.push(`CLI commands: ${Object.keys(pkg.bin).join(', ')}`); } } catch (error) { // Ignore parse errors } } // Analyze main source files const sourceFiles = projectData.files.filter(f => f.type === 'file' && (f.path.includes('src/') || f.path.includes('lib/') || f.name.includes('index') || f.name.includes('main'))); if (sourceFiles.length > 0) { analysis.push(`Main source files: ${sourceFiles.map(f => f.name).join(', ')}`); } // Look for specific patterns const hasRoutes = projectData.files.some(f => f.content?.includes('route') || f.path.includes('route')); const hasComponents = projectData.files.some(f => f.path.includes('component') || f.content?.includes('component')); const hasAPI = projectData.files.some(f => f.path.includes('api') || f.content?.includes('express') || f.content?.includes('fastify')); const hasCLI = projectData.files.some(f => f.content?.includes('commander') || f.content?.includes('yargs') || f.content?.includes('#!/usr/bin/env')); if (hasRoutes) analysis.push('Contains routing functionality'); if (hasComponents) analysis.push('Uses component-based architecture'); if (hasAPI) analysis.push('Includes API/server functionality'); if (hasCLI) analysis.push('Command-line interface detected'); return analysis.length > 0 ? analysis.join(', ') : 'Standard project structure'; } generateFeatures(projectType, projectData) { const features = { 'Frontend Application': `- ๐ŸŽจ Modern, responsive design - โšก Optimized performance - ๐Ÿ“ฑ Mobile-first approach - ๐Ÿ”ง Easy customization - ๐ŸŒ Cross-browser compatibility`, 'Backend API': `- ๐Ÿ”„ RESTful API endpoints - ๐Ÿ”’ Secure authentication - ๐Ÿ“Š Built-in monitoring - ๐Ÿš€ Scalable architecture - ๐Ÿ“ Auto-generated documentation`, 'CLI Tool': `- โšก Fast execution - ๐ŸŽฏ Intuitive commands - ๐Ÿ“ File system integration - ๐Ÿ”ง Configurable options - ๐Ÿ’ป Cross-platform support`, 'default': `- โœจ Clean, modern architecture - ๐Ÿš€ High performance - ๐Ÿ”ง Easy to extend - ๐Ÿ“š Well documented - ๐Ÿงช Thoroughly tested` }; // TODO: Analyze actual code to generate specific features // This should be enhanced to read actual functionality from the code return features[projectType] || features.default; } generatePrerequisites(projectData) { if (projectData.files.some(f => f.name === 'package.json')) { return `- Node.js (v16 or higher) - npm or yarn package manager - Git for version control`; } if (projectData.files.some(f => f.name === 'requirements.txt')) { return `- Python 3.8 or higher - pip package manager - Virtual environment (recommended)`; } if (projectData.files.some(f => f.name === 'Cargo.toml')) { return `- Rust (latest stable version) - Cargo package manager`; } return `- Git for version control - Your favorite code editor - Terminal/command line interface`; } generateInstallCommands(projectData) { if (projectData.files.some(f => f.name === 'package.json')) { return `# Clone the repository git clone <repository-url> cd ${projectData.name} # Install dependencies npm install # Start development server npm run dev`; } if (projectData.files.some(f => f.name === 'requirements.txt')) { return `# Clone the repository git clone <repository-url> cd ${projectData.name} # Create virtual environment python -m venv venv source venv/bin/activate # On Windows: venv\\Scripts\\activate # Install dependencies pip install -r requirements.txt # Run the application python main.py`; } return `# Clone the repository git clone <repository-url> cd ${projectData.name} # Follow language-specific setup instructions`; } generateUsageExample(projectData, projectType) { if (projectType === 'CLI Tool') { return `\`\`\`bash # Basic usage ${projectData.name} --help # Run with options ${projectData.name} --config config.json \`\`\``; } return `\`\`\`bash # Start the application npm start # Or for development npm run dev \`\`\``; } generateProjectStructure(projectData) { const structure = projectData.files .filter(f => f.type === 'directory' || this.isImportantFile(f.name)) .slice(0, 20) .map(f => { const indent = f.path.split('/').length - 1; const prefix = ' '.repeat(indent); const icon = f.type === 'directory' ? '๐Ÿ“' : '๐Ÿ“„'; return `${prefix}${icon} ${f.name}`; }) .join('\n'); return structure || `๐Ÿ“ ${projectData.name}/ ๐Ÿ“„ README.md ๐Ÿ“„ package.json ๐Ÿ“ src/ ๐Ÿ“„ index.js`; } generateConfigurationSection(projectData) { const configFiles = projectData.files.filter(f => f.name.includes('config') || f.name.startsWith('.env') || f.name === 'tsconfig.json' || f.name === 'tailwind.config.js' || f.name === 'vite.config.js'); if (configFiles.length === 0) { return 'No specific configuration required. The application works with default settings.'; } const configList = configFiles.map(f => `- \`${f.name}\`: Configuration file`).join('\n'); return `The following configuration files are available:\n\n${configList}\n\nRefer to each file for specific configuration options.`; } generateApiDocumentation(projectData) { const hasAPI = projectData.files.some(f => f.path.includes('api') || f.content?.includes('express') || f.content?.includes('fastify') || f.content?.includes('router')); if (!hasAPI) { return 'This project does not include API endpoints.'; } return `API endpoints are available. Check the source code for specific routes and documentation. Common endpoints may include: - \`GET /\` - Main application route - Additional routes as defined in the source code Refer to the API source files for complete documentation.`; } generateTechStackDetails(techStack) { return `**Core Technologies:** ${techStack.split(', ').map(tech => `- ${tech}`).join('\n')} **Development Tools:** - Version Control: Git - Code Quality: ESLint, Prettier - Testing: Jest, Testing Library - Documentation: README, JSDoc`; } detectTechStack(projectData) { const techStack = []; const packageJson = projectData.files.find(f => f.name === 'package.json'); if (packageJson?.content) { try { const pkg = JSON.parse(packageJson.content); const deps = { ...pkg.dependencies, ...pkg.devDependencies }; if (deps.react) techStack.push('React'); if (deps.vue) techStack.push('Vue.js'); if (deps.angular) techStack.push('Angular'); if (deps.next) techStack.push('Next.js'); if (deps.express) techStack.push('Express.js'); if (deps.typescript) techStack.push('TypeScript'); if (deps.tailwindcss) techStack.push('Tailwind CSS'); if (deps.sass) techStack.push('Sass'); if (deps.webpack) techStack.push('Webpack'); if (deps.vite) techStack.push('Vite'); } catch (error) { // Ignore parse errors } } if (projectData.files.some(f => f.name === 'requirements.txt')) techStack.push('Python'); if (projectData.files.some(f => f.name === 'Cargo.toml')) techStack.push('Rust'); if (projectData.files.some(f => f.name === 'go.mod')) techStack.push('Go'); if (projectData.files.some(f => f.name === 'Dockerfile')) techStack.push('Docker'); return techStack.length > 0 ? techStack.join(', ') : projectData.language || 'Various Technologies'; } detectProjectType(projectData) { const packageJson = projectData.files.find(f => f.name === 'package.json'); if (packageJson?.content) { try { const pkg = JSON.parse(packageJson.content); const deps = { ...pkg.dependencies, ...pkg.devDependencies }; if (deps.react || deps.vue || deps.angular) return 'Frontend Application'; if (deps.next || deps.nuxt || deps.gatsby) return 'Full-Stack Application'; if (deps.express || deps.fastify || deps.koa) return 'Backend API'; if (pkg.bin) return 'CLI Tool'; if (pkg.main && !deps.express) return 'Library'; } catch (error) { // Ignore parse errors } } if (projectData.files.some(f => f.name === 'requirements.txt')) return 'Python Application'; if (projectData.files.some(f => f.name === 'Cargo.toml')) return 'Rust Application'; if (projectData.files.some(f => f.name === 'go.mod')) return 'Go Application'; return 'Software Project'; } isImportantFile(fileName) { const important = [ 'package.json', 'tsconfig.json', 'next.config.js', 'vite.config.js', 'requirements.txt', 'setup.py', 'Cargo.toml', 'go.mod', 'Dockerfile', 'README.md', 'LICENSE', '.env.example', 'config.js', 'index.js', 'main.py' ]; return important.includes(fileName); } cleanupGeneratedContent(content) { return content .replace(/^```markdown\s*\n/, '') .replace(/\n```$/, '') .replace(/\n{3,}/g, '\n\n') .trim(); } extractSections(content) { const sections = []; const lines = content.split('\n'); for (const line of lines) { const trimmedLine = line.trim(); if (trimmedLine.startsWith('# ') || trimmedLine.startsWith('## ')) { const sectionName = trimmedLine.replace(/^#+\s*/, '').replace(/[^\w\s]/g, '').trim(); if (sectionName) { sections.push(sectionName); } } } return sections; } } exports.GeminiService = GeminiService; //# sourceMappingURL=geminiService.js.map