UNPKG

fge-cli

Version:

A CLI tool to initialize new projects with Gemini and PRD markdown files.

158 lines (127 loc) 8.12 kB
#!/usr/bin/env node const fs = require('fs'); const path = require('path'); // const fetch = require('node-fetch'); // 不再需要 node-fetch const { GoogleGenerativeAI } = require('@google/generative-ai'); // 导入 Google Generative AI SDK // --- 配置 --- const PRD_FILE_NAME = 'PRD.md'; const TASK_FILE_NAME = 'TASK.md'; // const GEMINI_API_URL = 'https://generativelanguage.googleapis.com/v1beta/models/gemini-pro:generateContent'; // 不再需要这个 URL const MODEL_NAME = 'gemini-2.5-flash'; // 使用的模型,如果你想尝试 'gemini-2.5-flash' 也可以在这里更改 // --- 核心函数 --- async function generateTasks() { console.log(`Starting to generate ${TASK_FILE_NAME} from ${PRD_FILE_NAME}...`); // 1. 获取 GEMINI_API_KEY const geminiApiKey = process.env.GEMINI_API_KEY; if (!geminiApiKey) { console.error('\n❌ Error: GEMINI_API_KEY environment variable is not set.'); console.error('Please set it in your ~/.zshrc or ~/.bashrc file, like:'); console.error(' export GEMINI_API_KEY="YOUR_ACTUAL_GEMINI_API_KEY"'); console.error('Then run: source ~/.zshrc (or ~/.bashrc)'); process.exit(1); } console.log('✅ GEMINI_API_KEY found.'); // 初始化 GoogleGenerativeAI 客户端 const genAI = new GoogleGenerativeAI(geminiApiKey); // API 密钥直接传递给构造函数 // 2. 读取 PRD.md 内容 const prdFilePath = path.join(process.cwd(), PRD_FILE_NAME); let prdContent; try { prdContent = fs.readFileSync(prdFilePath, 'utf8'); if (!prdContent.trim()) { console.warn(`⚠️ Warning: ${PRD_FILE_NAME} is empty. Generating an empty TASK.md.`); fs.writeFileSync(TASK_FILE_NAME, '# Project Tasks\n\nNo requirements found in PRD.md to generate tasks.'); console.log(`✨ Empty ${TASK_FILE_NAME} generated.`); process.exit(0); } } catch (error) { if (error.code === 'ENOENT') { console.error(`\n❌ Error: ${PRD_FILE_NAME} not found in the current directory.`); console.error(`Please ensure you are in a project directory containing ${PRD_FILE_NAME}.`); } else { console.error(`\n❌ Error reading ${PRD_FILE_NAME}: ${error.message}`); } process.exit(1); } console.log(`✅ ${PRD_FILE_NAME} read successfully.`); // 3. 构建 Gemini API 提示词 (Prompt Engineering!) // 这是核心部分,你需要根据实际需求调整,以获得最佳结果。 const prompt = ` You are an expert project manager and senior software engineer. Your primary goal is to meticulously analyze the provided Product Requirement Document (PRD) and **deduce all necessary, actionable tasks** required for its complete technical implementation. This includes, but is not limited to, user stories, functional requirements, non-functional requirements, and the granular technical tasks needed to bring them to life. For each derived task, ensure it is: * **Actionable and Specific**: Clearly define what needs to be done. * **Traceable to PRD**: Where applicable, implicitly or explicitly link back to the originating PRD requirement or concept. * **Granular**: Break down complex requirements into smaller, manageable sub-tasks where appropriate. Format the output exclusively as a Markdown task list. **All tasks, including sub-tasks, must initially be marked as incomplete (\`[ ]\`). The format for a completed task should be \`[x]\`.** Organize the tasks logically using clear Markdown headings and sub-headings to denote hierarchy and categorization. Consider the following categories: ## User Stories * Represent the "As a [User Role], I want to [Action], so that [Benefit]" format, directly derived from user-centric needs in the PRD. ## Functional Requirements * Core features and functionalities described in the PRD. * Break these down into more specific actions or system behaviors. ## Non-Functional Requirements (NFRs) * Tasks related to performance, security, scalability, usability, maintainability, etc., as implied or explicitly stated in the PRD. These are crucial for the system's quality attributes. ## Technical Design & Architecture Tasks * High-level architectural decisions, system design, and technology stack choices. ## Backend Development Tasks * API development, database interactions, business logic implementation, third-party integrations, data processing, etc. ## Frontend Development Tasks * User interface (UI) implementation, user experience (UX) flows, data presentation, client-side logic, responsiveness, etc. ## Data & Database Tasks * Schema design, migration scripts, data modeling, storage considerations, optimization. ## DevOps & Infrastructure Tasks * Deployment pipelines, environment setup, monitoring, logging, cloud resource provisioning, scaling. ## Testing & Quality Assurance Tasks * Unit tests, integration tests, system tests, acceptance criteria definition, test case creation, performance testing. ## Documentation Tasks * API documentation, technical design documents, user manuals, deployment guides. --- **Crucial Directives:** * **Infer Deeply**: Go beyond surface-level extraction. If the PRD states "users can log in," infer the underlying needs for password hashing, session management, error handling, forgotten password flows, etc., and list them as granular tasks. * **No Redundancy**: Avoid duplicating tasks; categorize them appropriately. * **No Conversational Filler**: The output must be *only* the Markdown task list. Do not include any introductory phrases, explanations, or concluding remarks. --- PRD Content: ${prdContent} --- Generated Tasks: `; // 4. 调用 Gemini API console.log('🚀 Calling Gemini API to generate tasks...'); try { const model = genAI.getGenerativeModel({ model: MODEL_NAME }); // 获取模型实例 const result = await model.generateContent(prompt); // 直接传递 prompt const response = await result.response; // 获取响应 let generatedTasksContent = ''; if (response && response.text()) { generatedTasksContent = response.text(); // 确保以 # Project Tasks 开头,并清理可能的AI额外文本 if (!generatedTasksContent.trim().startsWith('# Project Tasks')) { generatedTasksContent = '# Project Tasks\n\n' + generatedTasksContent; } // 移除可能的多余 --- 或其他非任务内容,确保从标题开始 generatedTasksContent = generatedTasksContent.replace(/^---[\s\S]*?(?=\# Project Tasks|$)/m, '').trim(); } else { console.warn('⚠️ Warning: Gemini API response did not contain expected content. Response:', JSON.stringify(response, null, 2)); generatedTasksContent = '# Project Tasks\n\nCould not generate tasks from PRD. Please check the PRD content or API response.'; } // 5. 写入 TASK.md 文件 fs.writeFileSync(TASK_FILE_NAME, generatedTasksContent); console.log(`🎉 Successfully generated ${TASK_FILE_NAME}!`); console.log(`You can now check '${TASK_FILE_NAME}' for your project tasks.`); } catch (error) { console.error(`\n❌ Error calling Gemini API: ${error.message}`); console.error('Please check your API key, network connection, or the PRD content.'); // 针对具体的API错误,可以尝试解析错误信息并给出更详细的提示 if (error.message.includes('API key not valid')) { console.error('Hint: Your GEMINI_API_KEY might be incorrect or revoked. Please verify it on Google AI Studio.'); } else if (error.message.includes('Quota exceeded')) { console.error('Hint: You might have hit your API quota limit. Please check your usage on Google AI Studio.'); } else if (error.message.includes('Network error')) { console.error('Hint: There might be an issue with your internet connection.'); } process.exit(1); } } // 执行主函数 generateTasks();