mirror-magi-meta-agent
Version:
AI-powered development planning and execution system with Supabase integration
182 lines (156 loc) ⢠5.75 kB
JavaScript
const fs = require('fs').promises;
const path = require('path');
async function validateConfiguration() {
console.log('š Validating Mirror Magi Meta-Agent Configuration...\n');
const baseDir = path.join(__dirname, '..');
const configDir = path.join(baseDir, 'config');
const stateDir = path.join(baseDir, 'state');
const results = {
passed: 0,
failed: 0,
warnings: 0,
errors: []
};
try {
// Check required files exist
await checkFileExists(path.join(configDir, 'project-config.json'), 'Project configuration file', results);
await checkFileExists(path.join(configDir, 'agent-persona.md'), 'Agent persona file', results);
await checkFileExists(path.join(configDir, 'command-templates.json'), 'Command templates file', results);
await checkFileExists(path.join(stateDir, 'project-state.json'), 'Project state file', results);
// Validate JSON files
await validateJsonFile(path.join(configDir, 'project-config.json'), 'Project configuration', results);
await validateJsonFile(path.join(configDir, 'command-templates.json'), 'Command templates', results);
await validateJsonFile(path.join(stateDir, 'project-state.json'), 'Project state', results);
// Validate project configuration content
await validateProjectConfig(path.join(configDir, 'project-config.json'), results);
// Check for placeholder content
await checkForPlaceholders(path.join(configDir, 'project-config.json'), results);
await checkForPlaceholders(path.join(configDir, 'agent-persona.md'), results);
console.log('\n' + '='.repeat(60));
console.log('š VALIDATION SUMMARY');
console.log('='.repeat(60));
console.log(`ā
Passed: ${results.passed}`);
console.log(`ā ļø Warnings: ${results.warnings}`);
console.log(`ā Failed: ${results.failed}`);
if (results.errors.length > 0) {
console.log('\nšØ ISSUES FOUND:');
results.errors.forEach(error => {
console.log(` ${error}`);
});
}
if (results.failed === 0) {
console.log('\nš Configuration validation passed!');
if (results.warnings > 0) {
console.log('š” Consider addressing the warnings above for optimal performance.');
}
} else {
console.log('\nā Configuration validation failed. Please fix the issues above.');
process.exit(1);
}
} catch (error) {
console.error('ā Validation failed:', error.message);
process.exit(1);
}
}
async function checkFileExists(filePath, description, results) {
try {
await fs.access(filePath);
console.log(`ā
${description} exists`);
results.passed++;
} catch {
console.log(`ā ${description} missing: ${filePath}`);
results.errors.push(`Missing file: ${filePath}`);
results.failed++;
}
}
async function validateJsonFile(filePath, description, results) {
try {
const content = await fs.readFile(filePath, 'utf8');
JSON.parse(content);
console.log(`ā
${description} is valid JSON`);
results.passed++;
} catch (error) {
if (error.code === 'ENOENT') {
// File doesn't exist, already handled in checkFileExists
return;
}
console.log(`ā ${description} has invalid JSON: ${error.message}`);
results.errors.push(`Invalid JSON in ${filePath}: ${error.message}`);
results.failed++;
}
}
async function validateProjectConfig(filePath, results) {
try {
const content = await fs.readFile(filePath, 'utf8');
const config = JSON.parse(content);
// Check required fields
const requiredFields = [
'project.name',
'project.description',
'project.tech_stack',
'directory_structure',
'code_standards'
];
for (const field of requiredFields) {
const value = getNestedValue(config, field);
if (!value) {
console.log(`ā ļø Missing or empty required field: ${field}`);
results.warnings++;
} else {
console.log(`ā
Required field present: ${field}`);
results.passed++;
}
}
// Check if project name is still default
if (config.project?.name === 'Your Project Name') {
console.log(`ā ļø Project name is still set to default value`);
results.warnings++;
}
} catch (error) {
if (error.code !== 'ENOENT') {
console.log(`ā Error validating project config: ${error.message}`);
results.errors.push(`Error validating project config: ${error.message}`);
results.failed++;
}
}
}
async function checkForPlaceholders(filePath, results) {
try {
const content = await fs.readFile(filePath, 'utf8');
const placeholders = [
'Your Project Name',
'[Your Application Name]',
'[Your Tech Stack]',
'[Frontend Framework]',
'[Backend Technology]',
'example_domain_1'
];
let foundPlaceholders = 0;
for (const placeholder of placeholders) {
if (content.includes(placeholder)) {
foundPlaceholders++;
}
}
if (foundPlaceholders > 0) {
console.log(`ā ļø Found ${foundPlaceholders} placeholder(s) in ${path.basename(filePath)}`);
results.warnings++;
} else {
console.log(`ā
No placeholders found in ${path.basename(filePath)}`);
results.passed++;
}
} catch (error) {
if (error.code !== 'ENOENT') {
console.log(`ā Error checking placeholders in ${filePath}: ${error.message}`);
results.failed++;
}
}
}
function getNestedValue(obj, path) {
return path.split('.').reduce((current, key) => current?.[key], obj);
}
// Run validation if called directly
if (require.main === module) {
validateConfiguration().catch(console.error);
}
module.exports = { validateConfiguration };