UNPKG

promachos

Version:

Standardized protocol for human-AI collaboration - making AI assistance predictable, trackable, and scalable

252 lines (226 loc) • 8.92 kB
import chalk from 'chalk'; import inquirer from 'inquirer'; import ora from 'ora'; import { ProjectDetector } from '../utils/detector.js'; import { ConfigManager } from '../utils/config.js'; export async function initCommand(options) { console.log(chalk.blue('šŸš€ Initializing Promachos in current directory...\n')); const configManager = new ConfigManager(); // Check if already initialized if (configManager.isInitialized() && !options.force) { console.log(chalk.yellow('āš ļø Promachos is already initialized in this directory.')); console.log(chalk.gray('Use --force to reinitialize.')); return; } try { // Start project analysis const spinner = ora('Analyzing project...').start(); const detector = new ProjectDetector(); // Detect project type and metadata const [projectType, metadata] = await Promise.all([ detector.detectProjectType(), detector.getProjectMetadata() ]); spinner.succeed('Project analysis complete'); // Show detection results console.log(chalk.green('\nšŸ“Š Project Analysis Results:')); console.log(` ${chalk.bold('Name:')} ${metadata.name}`); console.log(` ${chalk.bold('Type:')} ${projectType.type} ${projectType.framework ? `(${projectType.framework})` : ''}`); console.log(` ${chalk.bold('Files:')} ${metadata.size.files.toLocaleString()}`); console.log(` ${chalk.bold('Lines:')} ${metadata.size.lines.toLocaleString()}`); if (metadata.languages.length > 0) { console.log(` ${chalk.bold('Languages:')} ${metadata.languages.map(l => `${l.language} (${l.percentage}%)`).join(', ')}`); } // Interactive configuration if not auto mode let config = { project: { name: metadata.name, type: options.type || projectType.type, language: 'english', framework: projectType.framework, metadata: { files: metadata.size.files, lines: metadata.size.lines, languages: metadata.languages } }, behavior: { verbosity: 'balanced', explain_reasoning: true, ask_before_execute: true, max_retries: 3 }, output: { format: 'markdown', save_artifacts: true, include_metrics: true }, cli: { auto_copy_clipboard: false, auto_open_browser: false, show_progress: true, colored_output: true } }; // Set default AI assistant for auto mode if (options.auto) { config.project.ai_assistant = 'claude'; } // Interactive setup unless auto mode if (!options.auto) { console.log(chalk.blue('\nšŸ”§ Configuration Setup:')); const answers = await inquirer.prompt([ { type: 'input', name: 'projectName', message: 'Project name:', default: metadata.name }, { type: 'list', name: 'projectType', message: 'What type of project is this?', choices: [ { name: `${projectType.type} (auto-detected)`, value: projectType.type }, { name: 'Web Application', value: 'web-app' }, { name: 'API/Backend', value: 'api' }, { name: 'Library/Package', value: 'library' }, { name: 'Mobile App', value: 'mobile' }, { name: 'Desktop App', value: 'desktop' }, { name: 'Data Science', value: 'data-science' }, { name: 'DevOps/Infrastructure', value: 'devops' }, { name: 'Other', value: 'other' } ], default: 0 }, { type: 'list', name: 'verbosity', message: 'How verbose should the AI assistant be?', choices: [ { name: 'Minimal - Brief responses', value: 'minimal' }, { name: 'Balanced - Standard detail', value: 'balanced' }, { name: 'Detailed - Comprehensive explanations', value: 'detailed' } ], default: 1 }, { type: 'confirm', name: 'explainReasoning', message: 'Should the AI explain its reasoning?', default: true }, { type: 'confirm', name: 'askBeforeExecute', message: 'Ask for permission before making changes?', default: true }, { type: 'confirm', name: 'autoCopy', message: 'Automatically copy prompts to clipboard?', default: false }, { type: 'list', name: 'aiAssistant', message: 'Which AI assistant will you primarily use?', choices: [ { name: 'Claude (Anthropic)', value: 'claude' }, { name: 'ChatGPT (OpenAI)', value: 'chatgpt' }, { name: 'GitHub Copilot', value: 'copilot' }, { name: 'Cursor', value: 'cursor' }, { name: 'Other/Multiple', value: 'generic' } ], default: 0 } ]); // Update config with answers config.project.name = answers.projectName; config.project.type = answers.projectType; config.behavior.verbosity = answers.verbosity; config.behavior.explain_reasoning = answers.explainReasoning; config.behavior.ask_before_execute = answers.askBeforeExecute; config.cli.auto_copy_clipboard = answers.autoCopy; config.project.ai_assistant = answers.aiAssistant; } // Initialize project const initSpinner = ora('Creating Promachos structure...').start(); const success = configManager.initializeProject(config); if (success) { initSpinner.succeed('Promachos initialized successfully!'); console.log(chalk.green('\nāœ… Setup Complete!')); // Determine AI instructions filename const aiFileNames = { 'claude': 'CLAUDE.md', 'chatgpt': 'CHATGPT.md', 'copilot': 'COPILOT.md', 'cursor': 'CURSOR.md', 'generic': 'AI_ASSISTANT.md' }; const aiFileName = aiFileNames[config.project.ai_assistant] || 'AI_ASSISTANT.md'; console.log(chalk.gray('\nCreated:')); console.log(chalk.gray(` ${aiFileName.padEnd(28)} # AI assistant instructions`)); console.log(chalk.gray(' .promachos/')); console.log(chalk.gray(' ā”œā”€ā”€ README.md # Protocol directory guide')); console.log(chalk.gray(' ā”œā”€ā”€ config.yaml # Collaboration rules')); console.log(chalk.gray(' ā”œā”€ā”€ project.md # Project description')); console.log(chalk.gray(' ā”œā”€ā”€ context.md # Decision history')); console.log(chalk.gray(' ā”œā”€ā”€ progress.json # Progress tracking')); console.log(chalk.gray(' ā”œā”€ā”€ tasks.json # Task management')); console.log(chalk.gray(' ā”œā”€ā”€ artifacts/ # AI outputs')); console.log(chalk.gray(' └── logs/ # Audit trail')); console.log(chalk.blue('\nšŸš€ Next Steps:')); console.log(` 1. ${chalk.cyan('promachos start')} - Generate your first AI prompt`); console.log(` 2. Edit ${chalk.cyan('.promachos/project.md')} to describe your goals`); console.log(` 3. ${chalk.cyan('promachos status')} - Check your progress`); // Show project-specific recommendations if (projectType.type !== 'unknown') { console.log(chalk.yellow('\nšŸ’” Recommendations for your project:')); showProjectRecommendations(projectType.type, projectType.framework); } } else { initSpinner.fail('Failed to initialize Promachos'); process.exit(1); } } catch (error) { console.error(chalk.red(`\nāŒ Error: ${error.message}`)); process.exit(1); } } /** * Show project-specific recommendations */ function showProjectRecommendations(type, framework) { const recommendations = { 'react': [ 'Consider using the analyze command to check component structure', 'Focus on component reusability and prop validation', 'Monitor bundle size and performance' ], 'nodejs': [ 'Review API endpoint structure and error handling', 'Check for security best practices', 'Monitor dependencies for vulnerabilities' ], 'python': [ 'Use type hints for better code documentation', 'Follow PEP 8 style guidelines', 'Consider adding automated testing' ], 'nextjs': [ 'Optimize for Core Web Vitals', 'Review SSR/SSG usage patterns', 'Check SEO implementation' ] }; const tips = recommendations[type] || recommendations[framework] || [ 'Regular code reviews and refactoring', 'Maintain good documentation', 'Implement proper testing strategies' ]; tips.forEach((tip, index) => { console.log(` ${index + 1}. ${tip}`); }); }