csvlod-ai-mcp-server
Version:
CSVLOD-AI MCP Server v3.0 with Quantum Context Intelligence - Revolutionary Context Intelligence Engine and Multimodal Processor for sovereign AI development
157 lines • 6.47 kB
JavaScript
import * as fs from 'fs/promises';
import * as path from 'path';
export class CSVLODValidator {
async validate(projectPath, options) {
const issues = [];
const suggestions = [];
let score = 100;
// Check for required files
const requiredFiles = ['.csvlod/AI-CONTEXT.md', '.csvlod/AGENT-MANIFEST.yaml'];
for (const file of requiredFiles) {
const filePath = path.join(projectPath, file);
try {
await fs.access(filePath);
}
catch {
issues.push({
severity: 'error',
category: 'structure',
message: `Missing required file: ${file}`,
file,
});
score -= 20;
}
}
// Check .context directory structure
const contextPath = path.join(projectPath, '.context');
try {
const stats = await fs.stat(contextPath);
if (!stats.isDirectory()) {
issues.push({
severity: 'error',
category: 'structure',
message: '.context exists but is not a directory',
});
score -= 30;
}
else {
// Validate CSVLOD categories
const categories = await fs.readdir(contextPath);
const requiredCategories = ['considerations', 'standards', 'visions'];
const optionalCategories = ['landscapes', 'outlines', 'designs'];
for (const required of requiredCategories) {
if (!categories.includes(required)) {
issues.push({
severity: 'error',
category: 'taxonomy',
message: `Missing required CSVLOD category: ${required}`,
});
score -= 10;
}
}
if (options?.strict) {
for (const optional of optionalCategories) {
if (!categories.includes(optional)) {
issues.push({
severity: 'warning',
category: 'taxonomy',
message: `Missing optional CSVLOD category: ${optional}`,
});
score -= 5;
}
}
}
// Check for README in each category
for (const category of categories) {
const readmePath = path.join(contextPath, category, 'README.md');
try {
await fs.access(readmePath);
}
catch {
issues.push({
severity: 'warning',
category: 'documentation',
message: `Missing README.md in ${category} directory`,
file: readmePath,
});
suggestions.push(`Add README.md to .context/${category}/ to describe its purpose`);
}
}
}
}
catch {
issues.push({
severity: 'error',
category: 'structure',
message: 'Missing .context directory',
});
score -= 30;
}
// Validate AI-CONTEXT.md content
try {
const aiContextContent = await fs.readFile(path.join(projectPath, '.csvlod', 'AI-CONTEXT.md'), 'utf-8');
if (aiContextContent.length < 100) {
issues.push({
severity: 'warning',
category: 'content',
message: '.csvlod/AI-CONTEXT.md seems too short to be effective',
file: '.csvlod/AI-CONTEXT.md',
});
suggestions.push('Expand .csvlod/AI-CONTEXT.md with more detailed project information');
}
const requiredSections = ['Project Overview', 'Core Principles', 'AI Agent Instructions'];
for (const section of requiredSections) {
if (!aiContextContent.includes(section)) {
issues.push({
severity: 'warning',
category: 'content',
message: `.csvlod/AI-CONTEXT.md missing recommended section: ${section}`,
file: '.csvlod/AI-CONTEXT.md',
});
}
}
}
catch {
// File doesn't exist, already reported
}
// Validate AGENT-MANIFEST.yaml structure
try {
const manifestContent = await fs.readFile(path.join(projectPath, '.csvlod', 'AGENT-MANIFEST.yaml'), 'utf-8');
// Basic YAML structure validation
if (!manifestContent.includes('version:')) {
issues.push({
severity: 'error',
category: 'manifest',
message: '.csvlod/AGENT-MANIFEST.yaml missing version field',
file: '.csvlod/AGENT-MANIFEST.yaml',
});
}
if (!manifestContent.includes('capabilities:')) {
issues.push({
severity: 'warning',
category: 'manifest',
message: '.csvlod/AGENT-MANIFEST.yaml missing capabilities section',
file: '.csvlod/AGENT-MANIFEST.yaml',
});
suggestions.push('Define agent capabilities in .csvlod/AGENT-MANIFEST.yaml');
}
}
catch {
// File doesn't exist, already reported
}
// Add general suggestions based on score
if (score < 50) {
suggestions.push('Run `csvlod init` to set up basic CSVLOD structure');
}
else if (score < 80) {
suggestions.push('Review CSVLOD documentation to improve compliance');
}
return {
valid: issues.filter(i => i.severity === 'error').length === 0,
score: Math.max(0, score),
issues,
suggestions,
};
}
}
//# sourceMappingURL=validator.js.map