mirror-magi-meta-agent
Version:
AI-powered development planning and execution system with Supabase integration
456 lines (369 loc) ⢠14.7 kB
JavaScript
const fs = require('fs').promises;
const path = require('path');
const readline = require('readline');
/**
* AI Plan Converter
* Helps convert AI-generated development plans into structured format
*/
class AIPlanConverter {
constructor() {
this.rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
this.structuredPlan = null;
}
async start() {
console.log('š¤ā”ļøš AI Plan Converter');
console.log('ā'.repeat(50));
console.log('Convert your AI-generated plan into structured format\n');
try {
await this.showWorkflow();
await this.startConversion();
} catch (error) {
console.error('ā Error:', error.message);
} finally {
this.rl.close();
}
}
async showWorkflow() {
console.log('š CONVERSION WORKFLOW:');
console.log('ā'.repeat(30));
console.log('1. Generate plan with AI (ChatGPT, Claude, etc.)');
console.log('2. Convert to structured JSON format');
console.log('3. Validate and refine structure');
console.log('4. Execute with Claude Code Max');
console.log('');
}
async startConversion() {
const choice = await this.askQuestion('What would you like to do?\n1. Create new structured plan from AI output\n2. Generate AI prompt template\n3. Validate existing plan structure\n4. Show example conversion\n\nChoose (1-4): ');
switch (choice.trim()) {
case '1':
await this.createStructuredPlan();
break;
case '2':
await this.showAIPromptTemplate();
break;
case '3':
await this.validatePlan();
break;
case '4':
await this.showExampleConversion();
break;
default:
console.log('Invalid choice. Starting new plan creation...');
await this.createStructuredPlan();
}
}
async createStructuredPlan() {
console.log('\nšļø CREATE STRUCTURED PLAN');
console.log('ā'.repeat(40));
console.log('This will guide you through converting your AI plan\n');
// Step 1: Basic plan info
const goal = await this.askQuestion('š Project goal (copy from AI plan): ');
// Step 2: Context gathering
console.log('\nš§ PROJECT CONTEXT:');
const requiredFeatures = await this.askQuestion('Required features (comma-separated): ');
const designSystem = await this.askQuestion('Design system/tech stack: ');
const dataSource = await this.askQuestion('Data source: ');
const userRequirements = await this.askQuestion('User requirements (comma-separated): ');
// Step 3: Create base structure
this.structuredPlan = {
id: `plan_${Date.now()}`,
goal: goal.trim(),
status: 'draft',
created: new Date().toISOString(),
context: {
requiredFeatures: requiredFeatures.split(',').map(f => f.trim()).filter(f => f),
designSystem: designSystem.trim(),
dataSource: dataSource.trim(),
userRequirements: userRequirements.split(',').map(r => r.trim()).filter(r => r)
},
phases: []
};
// Step 4: Add phases
await this.addPhases();
// Step 5: Save plan
await this.savePlan();
}
async addPhases() {
console.log('\nš ADD PHASES');
console.log('ā'.repeat(20));
console.log('Now add the phases from your AI plan\n');
let phaseCounter = 1;
while (true) {
console.log(`\nšø PHASE ${phaseCounter}:`);
const phaseName = await this.askQuestion('Phase name (or "done" to finish): ');
if (phaseName.toLowerCase() === 'done') {
break;
}
const phaseDescription = await this.askQuestion('Phase description: ');
const phase = {
id: `phase_${Date.now()}_${phaseCounter}`,
name: phaseName.trim(),
description: phaseDescription.trim(),
tasks: []
};
// Add tasks to this phase
await this.addTasksToPhase(phase);
this.structuredPlan.phases.push(phase);
phaseCounter++;
console.log(`ā
Phase "${phaseName}" added with ${phase.tasks.length} tasks`);
}
}
async addTasksToPhase(phase) {
console.log(`\nš ADD TASKS TO: ${phase.name}`);
console.log('ā'.repeat(30));
let taskCounter = 1;
while (true) {
const addTask = await this.askQuestion(`Add task ${taskCounter} to this phase? (y/n): `);
if (!addTask.toLowerCase().startsWith('y')) {
break;
}
const taskDescription = await this.askQuestion('Task description: ');
const taskType = await this.askQuestion('Task type (component_creation, api_integration, configuration, testing_implementation, feature_development): ');
// Basic task structure
const task = {
id: `task_${Date.now()}_${String(taskCounter).padStart(3, '0')}`,
description: taskDescription.trim(),
type: taskType.trim() || 'feature_development',
dependencies: [],
specifics: {}
};
// Add specifics based on task type
await this.addTaskSpecifics(task);
phase.tasks.push(task);
taskCounter++;
console.log(`ā
Task added: ${taskDescription}`);
}
}
async addTaskSpecifics(task) {
console.log(`\nš§ TASK SPECIFICS FOR: ${task.description}`);
const addSpecifics = await this.askQuestion('Add specific implementation details? (y/n): ');
if (!addSpecifics.toLowerCase().startsWith('y')) {
return;
}
switch (task.type) {
case 'component_creation':
const componentName = await this.askQuestion('Component name: ');
const filePath = await this.askQuestion('File path (e.g., src/components/MyComponent.tsx): ');
const props = await this.askQuestion('Component props (JSON format or leave empty): ');
task.specifics.componentName = componentName.trim();
task.specifics.filePath = filePath.trim();
if (props.trim()) {
try {
task.specifics.props = JSON.parse(props);
} catch (e) {
task.specifics.props = props.trim();
}
}
break;
case 'api_integration':
const apiEndpoints = await this.askQuestion('API endpoints (comma-separated): ');
const apiMethods = await this.askQuestion('HTTP methods (GET, POST, etc.): ');
task.specifics.apiEndpoints = apiEndpoints.split(',').map(e => e.trim()).filter(e => e);
task.specifics.methods = apiMethods.trim();
break;
case 'configuration':
const configFiles = await this.askQuestion('Configuration files (comma-separated): ');
task.specifics.configFiles = configFiles.split(',').map(f => f.trim()).filter(f => f);
break;
default:
const customSpecs = await this.askQuestion('Any custom specifics (JSON format or leave empty): ');
if (customSpecs.trim()) {
try {
Object.assign(task.specifics, JSON.parse(customSpecs));
} catch (e) {
task.specifics.notes = customSpecs.trim();
}
}
break;
}
}
async savePlan() {
console.log('\nš¾ SAVE STRUCTURED PLAN');
console.log('ā'.repeat(30));
// Show plan summary
this.showPlanSummary();
const save = await this.askQuestion('\nā
Save this structured plan? (y/n): ');
if (save.toLowerCase().startsWith('y')) {
// Ensure state directory exists
try {
await fs.mkdir('state', { recursive: true });
} catch (e) {
// Directory already exists
}
const planPath = path.join('state', 'master-plan.json');
await fs.writeFile(planPath, JSON.stringify(this.structuredPlan, null, 2));
console.log('\nš Plan saved successfully!');
console.log('š Location: state/master-plan.json');
console.log('\nš” Next steps:');
console.log('⢠Validate structure: npm run plan:view');
console.log('⢠Refine with AI: npm run plan:discuss');
console.log('⢠Edit details: npm run plan:edit');
console.log('⢠Start execution: npm run plan:continue');
} else {
console.log('Plan not saved.');
}
}
showPlanSummary() {
console.log('\nš PLAN SUMMARY:');
console.log(`šÆ Goal: ${this.structuredPlan.goal}`);
console.log(`š Phases: ${this.structuredPlan.phases.length}`);
const totalTasks = this.structuredPlan.phases.reduce((sum, phase) => sum + phase.tasks.length, 0);
console.log(`š Total Tasks: ${totalTasks}`);
console.log('\nš Phase Breakdown:');
this.structuredPlan.phases.forEach((phase, index) => {
console.log(`${index + 1}. ${phase.name} (${phase.tasks.length} tasks)`);
});
}
async showAIPromptTemplate() {
console.log('\nš AI PROMPT TEMPLATE');
console.log('ā'.repeat(40));
console.log('Copy this prompt to ChatGPT, Claude, or any AI:\n');
const projectGoal = await this.askQuestion('Enter your project goal for the prompt: ');
const prompt = `I need a comprehensive development plan for: ${projectGoal}
Please provide a detailed plan that includes:
1. PROJECT OVERVIEW
- Clear goal statement
- Key requirements and features needed
- Technical approach/stack
- User requirements (mobile-friendly, accessibility, etc.)
2. DEVELOPMENT PHASES
For each phase, provide:
- Phase name and purpose
- Detailed description of what gets accomplished
- List of specific tasks/components to build
- Dependencies between tasks
3. SPECIFIC TASKS
For each task, include:
- Exact component/file names to create
- Specific functionality to implement
- Technical details (props, types, API endpoints)
- Files that need to be created or modified
- Dependencies on other tasks
4. VALIDATION & SUCCESS CRITERIA
- How to test each component/feature
- What success looks like for each task
- Integration points to verify
Make this plan specific enough that a developer could implement it step-by-step without guessing about details.`;
console.log('ā'.repeat(80));
console.log(prompt);
console.log('ā'.repeat(80));
console.log('\nš” After getting AI response:');
console.log('⢠Run this script again and choose option 1');
console.log('⢠Copy the AI plan details into the guided prompts');
console.log('⢠Validate with: npm run plan:view');
}
async validatePlan() {
console.log('\nā
VALIDATE EXISTING PLAN');
console.log('ā'.repeat(30));
try {
const planPath = path.join('state', 'master-plan.json');
const planData = await fs.readFile(planPath, 'utf8');
const plan = JSON.parse(planData);
console.log('š Plan found:', plan.goal);
// Use the complete plan viewer for validation
const CompletePlanViewer = require('./view-complete-plan');
const viewer = new CompletePlanViewer();
viewer.plan = plan;
const checks = viewer.validatePlanStructure();
const allPassed = checks.every(check => check.passed);
console.log('\nā
STRUCTURE VALIDATION:');
checks.forEach(check => {
const icon = check.passed ? 'ā
' : 'ā';
console.log(`${icon} ${check.description}`);
if (!check.passed && check.suggestion) {
console.log(` š” ${check.suggestion}`);
}
});
console.log(`\n${allPassed ? 'š' : 'ā ļø'} Plan Structure: ${allPassed ? 'VALID' : 'NEEDS ATTENTION'}`);
if (allPassed) {
console.log('\nš” Your plan is ready for execution!');
console.log(' Run: npm run plan:continue');
} else {
console.log('\nš” Fix issues with:');
console.log(' npm run plan:edit');
}
} catch (error) {
console.log('ā No plan found or invalid JSON format');
console.log('š” Create a plan with option 1 first');
}
}
async showExampleConversion() {
console.log('\nš EXAMPLE CONVERSION');
console.log('ā'.repeat(40));
console.log('\nš¤ AI-GENERATED PLAN:');
console.log('ā'.repeat(25));
console.log(`PROJECT: User Dashboard with Analytics
PHASE 1: Foundation Setup
- Create main dashboard component
- Set up routing
- Basic layout structure
PHASE 2: Data Integration
- Connect to analytics API
- Create data models
- Implement state management
PHASE 3: UI Components
- Build charts component
- Create settings panel
- Add notifications display`);
console.log('\nš STRUCTURED VERSION:');
console.log('ā'.repeat(25));
const examplePlan = {
"id": "plan_1703089234567",
"goal": "Create a user dashboard with analytics charts, settings panel, and real-time notifications",
"status": "draft",
"created": "2024-12-20T14:30:00.000Z",
"context": {
"requiredFeatures": ["analytics charts", "user settings", "notifications"],
"designSystem": "Tailwind CSS",
"dataSource": "REST API",
"userRequirements": ["mobile-friendly", "accessibility"]
},
"phases": [
{
"id": "phase_1703089234567_1",
"name": "Foundation Setup",
"description": "Create basic dashboard structure and routing",
"tasks": [
{
"id": "task_1703089234567_001",
"description": "Create UserDashboard main component with responsive layout",
"type": "component_creation",
"dependencies": [],
"specifics": {
"componentName": "UserDashboard",
"filePath": "src/components/UserDashboard.tsx",
"props": {
"user": "User",
"analytics": "AnalyticsData"
}
}
}
]
}
]
};
console.log(JSON.stringify(examplePlan, null, 2));
console.log('\nš” KEY DIFFERENCES:');
console.log('⢠Specific file paths instead of vague descriptions');
console.log('⢠Exact component names and props');
console.log('⢠Structured task types for automation');
console.log('⢠Dependencies clearly defined');
console.log('⢠Implementation specifics included');
await this.askQuestion('\nPress Enter to continue...');
}
askQuestion(question) {
return new Promise((resolve) => {
this.rl.question(question, resolve);
});
}
}
// Run the AI plan converter
if (require.main === module) {
const converter = new AIPlanConverter();
converter.start().catch(console.error);
}
module.exports = AIPlanConverter;