agentic-data-stack-community
Version:
AI Agentic Data Stack Framework - Community Edition. Open source data engineering framework with 4 core agents, essential templates, and 3-dimensional quality validation.
329 lines (271 loc) ⢠9.29 kB
JavaScript
/**
* Validation Script for AI Agentic Data Stack Framework - Community Edition
*
* This script validates framework installation and configuration
*/
const fs = require('fs-extra');
const path = require('path');
const chalk = require('chalk');
const yaml = require('yaml');
async function main() {
console.log(chalk.bold.blue('\nš Validating AI Agentic Data Stack Framework - Community Edition\n'));
const results = {
framework: await validateFramework(),
agents: await validateAgents(),
templates: await validateTemplates(),
examples: await validateExamples(),
cli: await validateCLI()
};
// Display results
displayResults(results);
// Exit with appropriate code
const hasErrors = Object.values(results).some(result => !result.valid);
process.exit(hasErrors ? 1 : 0);
}
async function validateFramework() {
console.log('š¦ Validating framework structure...');
const requiredFiles = [
'package.json',
'tools/cli.js',
'agents/',
'templates/',
'examples/',
'validation_scripts/'
];
const missing = [];
const found = [];
for (const file of requiredFiles) {
const filePath = path.join(__dirname, '..', file);
if (await fs.pathExists(filePath)) {
found.push(file);
console.log(` ā
${file}`);
} else {
missing.push(file);
console.log(` ā ${file}`);
}
}
// Validate package.json
let packageValid = false;
try {
const packageJson = await fs.readJSON(path.join(__dirname, '../package.json'));
if (packageJson.name && packageJson.version && packageJson.community) {
packageValid = true;
console.log(' ā
package.json structure valid');
} else {
console.log(' ā package.json missing required fields');
}
} catch (error) {
console.log(' ā package.json invalid or missing');
}
return {
valid: missing.length === 0 && packageValid,
found: found.length,
missing: missing.length,
details: missing.length > 0 ? `Missing files: ${missing.join(', ')}` : 'All required files present'
};
}
async function validateAgents() {
console.log('\nš¤ Validating AI agents...');
const agentsPath = path.join(__dirname, '../agents');
const requiredAgents = [
'data-engineer.yaml',
'data-analyst.yaml',
'data-product-manager.yaml',
'data-quality-engineer.yaml'
];
let validAgents = 0;
const issues = [];
for (const agentFile of requiredAgents) {
const agentPath = path.join(agentsPath, agentFile);
if (await fs.pathExists(agentPath)) {
try {
const agentData = yaml.parse(await fs.readFile(agentPath, 'utf8'));
// Validate agent structure
if (agentData.agent_metadata && agentData.core_capabilities && agentData.deliverables) {
validAgents++;
console.log(` ā
${agentFile}`);
} else {
issues.push(`${agentFile}: Invalid structure`);
console.log(` ā ${agentFile} - Invalid structure`);
}
} catch (error) {
issues.push(`${agentFile}: ${error.message}`);
console.log(` ā ${agentFile} - Parse error`);
}
} else {
issues.push(`${agentFile}: Missing`);
console.log(` ā ${agentFile} - Missing`);
}
}
return {
valid: validAgents === requiredAgents.length,
found: validAgents,
expected: requiredAgents.length,
details: issues.length > 0 ? issues.join('; ') : `All ${validAgents} agents valid`
};
}
async function validateTemplates() {
console.log('\nš Validating templates...');
const templatesPath = path.join(__dirname, '../templates');
if (!await fs.pathExists(templatesPath)) {
return {
valid: false,
found: 0,
expected: 20,
details: 'Templates directory missing'
};
}
let validTemplates = 0;
let totalTemplates = 0;
const issues = [];
// Check each category directory
const categories = await fs.readdir(templatesPath);
for (const category of categories) {
const categoryPath = path.join(templatesPath, category);
const stat = await fs.stat(categoryPath);
if (stat.isDirectory()) {
const templates = await fs.readdir(categoryPath);
for (const template of templates) {
if (template.endsWith('.yaml') || template.endsWith('.yml')) {
totalTemplates++;
const templatePath = path.join(categoryPath, template);
try {
const templateData = yaml.parse(await fs.readFile(templatePath, 'utf8'));
if (templateData.template_metadata && templateData.template_metadata.name) {
validTemplates++;
} else {
issues.push(`${category}/${template}: Invalid structure`);
}
} catch (error) {
issues.push(`${category}/${template}: Parse error`);
}
}
}
}
}
console.log(` š Found ${validTemplates}/${totalTemplates} valid templates`);
return {
valid: validTemplates >= 15, // Allow some flexibility
found: validTemplates,
expected: 20,
details: issues.length > 0 ?
`${issues.length} template issues found` :
`${validTemplates} templates validated successfully`
};
}
async function validateExamples() {
console.log('\nš Validating examples...');
const examplesPath = path.join(__dirname, '../examples');
if (!await fs.pathExists(examplesPath)) {
return {
valid: false,
found: 0,
expected: 1,
details: 'Examples directory missing'
};
}
const examples = await fs.readdir(examplesPath);
let validExamples = 0;
const issues = [];
for (const example of examples) {
const examplePath = path.join(examplesPath, example);
const stat = await fs.stat(examplePath);
if (stat.isDirectory()) {
const readmePath = path.join(examplePath, 'README.md');
if (await fs.pathExists(readmePath)) {
validExamples++;
console.log(` ā
${example}`);
} else {
issues.push(`${example}: Missing README.md`);
console.log(` ā ${example} - Missing README.md`);
}
}
}
return {
valid: validExamples >= 1,
found: validExamples,
expected: 1,
details: issues.length > 0 ? issues.join('; ') : `${validExamples} examples validated`
};
}
async function validateCLI() {
console.log('\nā” Validating CLI...');
const cliPath = path.join(__dirname, 'cli.js');
if (!await fs.pathExists(cliPath)) {
return {
valid: false,
details: 'CLI script missing'
};
}
// Check if CLI is executable
try {
const stats = await fs.stat(cliPath);
const isExecutable = !!(stats.mode & parseInt('111', 8));
if (isExecutable) {
console.log(' ā
CLI script is executable');
} else {
console.log(' ā ļø CLI script is not executable');
}
// Basic syntax check
const cliContent = await fs.readFile(cliPath, 'utf8');
if (cliContent.includes('#!/usr/bin/env node') && cliContent.includes('program.parse')) {
console.log(' ā
CLI script structure valid');
return {
valid: true,
details: 'CLI validated successfully'
};
} else {
return {
valid: false,
details: 'CLI script structure invalid'
};
}
} catch (error) {
return {
valid: false,
details: `CLI validation error: ${error.message}`
};
}
}
function displayResults(results) {
console.log('\n' + '='.repeat(60));
console.log(chalk.bold('š VALIDATION RESULTS'));
console.log('='.repeat(60));
let allValid = true;
Object.entries(results).forEach(([category, result]) => {
const icon = result.valid ? 'ā
' : 'ā';
const status = result.valid ? chalk.green('PASS') : chalk.red('FAIL');
console.log(`\n${icon} ${category.toUpperCase()}: ${status}`);
console.log(` ${result.details}`);
if (result.found !== undefined && result.expected !== undefined) {
console.log(` Found: ${result.found}/${result.expected}`);
}
if (!result.valid) {
allValid = false;
}
});
console.log('\n' + '='.repeat(60));
if (allValid) {
console.log(chalk.green.bold('š ALL VALIDATIONS PASSED'));
console.log('Framework is ready for use!');
} else {
console.log(chalk.red.bold('ā VALIDATION FAILURES DETECTED'));
console.log('Please fix the issues above before using the framework.');
}
console.log('\nš Community Edition Features:');
console.log(' ā
4 Core AI Agents');
console.log(' ā
20 Essential Templates');
console.log(' ā
3-Dimensional Quality Framework');
console.log(' ā
Community Examples and CLI');
console.log('\nš¢ Enterprise Edition Adds:');
console.log(' ⢠4 Additional Specialized Agents');
console.log(' ⢠68 More Interactive Templates');
console.log(' ⢠7-Dimensional Quality Framework');
console.log(' ⢠Real-time Collaboration & ML Enhancement');
console.log('\nš Contact: enterprise@agenticdata.com');
console.log('='.repeat(60));
}
if (require.main === module) {
main();
}