UNPKG

cortexweaver

Version:

CortexWeaver is a command-line interface (CLI) tool that orchestrates a swarm of specialized AI agents, powered by Claude Code and Gemini CLI, to assist in software development. It transforms a high-level project plan (plan.md) into a series of coordinate

342 lines 14.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.PersonaValidator = void 0; /** * PersonaValidator class for validation and comparison operations * Extracted from the main persona.ts file to handle validation and analysis */ class PersonaValidator { /** * Generate prompt template from persona */ generatePromptTemplate(persona, context = {}) { const sections = []; // Role and identity sections.push(`# ${persona.role}`); sections.push(''); sections.push(`## Identity`); sections.push(persona.coreIdentity); sections.push(''); // Primary responsibilities if (persona.primaryResponsibilities.length > 0) { sections.push('## Primary Responsibilities'); persona.primaryResponsibilities.forEach(responsibility => { sections.push(`- ${responsibility}`); }); sections.push(''); } // Context variables if (Object.keys(context).length > 0) { sections.push('## Current Context'); Object.entries(context).forEach(([key, value]) => { sections.push(`- ${key}: ${value}`); }); sections.push(''); } // Behavioral guidelines if (persona.behavioralGuidelines.length > 0) { sections.push('## Behavioral Guidelines'); persona.behavioralGuidelines.forEach(guideline => { sections.push(`- ${guideline}`); }); sections.push(''); } return sections.join('\n'); } /** * Compare two personas and generate a diff */ generatePersonaDiff(oldPersona, newPersona) { const changes = []; // Compare basic fields if (oldPersona.role !== newPersona.role) { changes.push({ field: 'role', type: 'modified', oldValue: oldPersona.role, newValue: newPersona.role }); } if (oldPersona.coreIdentity !== newPersona.coreIdentity) { changes.push({ field: 'coreIdentity', type: 'modified', oldValue: oldPersona.coreIdentity, newValue: newPersona.coreIdentity }); } // Compare arrays const responsibilityChanges = this.compareArrays(oldPersona.primaryResponsibilities, newPersona.primaryResponsibilities, 'primaryResponsibilities'); changes.push(...responsibilityChanges); const guidelineChanges = this.compareArrays(oldPersona.behavioralGuidelines, newPersona.behavioralGuidelines, 'behavioralGuidelines'); changes.push(...guidelineChanges); const metricsChanges = this.compareArrays(oldPersona.successMetrics, newPersona.successMetrics, 'successMetrics'); changes.push(...metricsChanges); const triggerChanges = this.compareArrays(oldPersona.adaptationTriggers, newPersona.adaptationTriggers, 'adaptationTriggers'); changes.push(...triggerChanges); return { oldVersion: oldPersona.version, newVersion: newPersona.version, changes, summary: this.generateChangeSummary(changes), timestamp: new Date().toISOString() }; } /** * Compare two arrays and generate change entries */ compareArrays(oldArray, newArray, fieldName) { const changes = []; // Find added items const added = newArray.filter(item => !oldArray.includes(item)); added.forEach(item => { changes.push({ field: fieldName, type: 'added', newValue: item }); }); // Find removed items const removed = oldArray.filter(item => !newArray.includes(item)); removed.forEach(item => { changes.push({ field: fieldName, type: 'removed', oldValue: item }); }); return changes; } /** * Generate a human-readable summary of changes */ generateChangeSummary(changes) { if (changes.length === 0) { return 'No changes detected'; } const changesByType = changes.reduce((acc, change) => { if (!acc[change.type]) acc[change.type] = 0; acc[change.type]++; return acc; }, {}); const summaryParts = []; if (changesByType.added) summaryParts.push(`${changesByType.added} additions`); if (changesByType.removed) summaryParts.push(`${changesByType.removed} removals`); if (changesByType.modified) summaryParts.push(`${changesByType.modified} modifications`); return summaryParts.join(', '); } /** * Validate persona structure and completeness */ validatePersonaStructure(persona) { const errors = []; const warnings = []; const suggestions = []; // Required field validation if (!persona.role || persona.role.trim() === '' || persona.role === 'Unknown Role') { errors.push('Role is required and must be properly defined'); } if (!persona.coreIdentity || persona.coreIdentity.trim() === '') { errors.push('Core identity is required'); } else if (persona.coreIdentity.length < 50) { warnings.push('Core identity is very short - consider adding more detail'); } // Content validation if (persona.primaryResponsibilities.length === 0) { warnings.push('No primary responsibilities defined'); } else if (persona.primaryResponsibilities.length < 3) { suggestions.push('Consider adding more primary responsibilities for clarity'); } if (persona.behavioralGuidelines.length === 0) { warnings.push('No behavioral guidelines defined'); } else if (persona.behavioralGuidelines.length < 3) { suggestions.push('Consider adding more behavioral guidelines'); } if (Object.keys(persona.interactionPatterns).length === 0) { warnings.push('No interaction patterns defined'); } if (persona.successMetrics.length === 0) { warnings.push('No success metrics defined'); } if (persona.adaptationTriggers.length === 0) { warnings.push('No adaptation triggers defined'); } // Metadata validation if (!persona.metadata.id || persona.metadata.id.trim() === '') { errors.push('Persona metadata must include a valid ID'); } if (!persona.metadata.name || persona.metadata.name.trim() === '') { warnings.push('Persona metadata should include a name'); } if (persona.metadata.tags.length === 0) { suggestions.push('Consider adding tags for better categorization'); } if (persona.metadata.capabilities.length === 0) { suggestions.push('Consider defining capabilities for this persona'); } // Version validation if (!persona.version.initialRelease || persona.version.initialRelease === 'Unknown') { warnings.push('Version information is incomplete'); } return { isValid: errors.length === 0, errors, warnings, suggestions, score: this.calculateValidationScore(errors, warnings, suggestions) }; } /** * Calculate a validation score based on errors, warnings, and suggestions */ calculateValidationScore(errors, warnings, suggestions) { let score = 100; // Deduct points for errors (critical issues) score -= errors.length * 25; // Deduct points for warnings (important issues) score -= warnings.length * 10; // Deduct fewer points for suggestions (nice-to-have improvements) score -= suggestions.length * 5; return Math.max(0, score); } /** * Validate persona content quality */ validatePersonaQuality(persona) { const assessment = { overall: 'good', scores: { completeness: 0, clarity: 0, specificity: 0, consistency: 0 }, recommendations: [] }; // Completeness assessment let completenessScore = 0; const requiredSections = [ 'role', 'coreIdentity', 'primaryResponsibilities', 'behavioralGuidelines', 'interactionPatterns', 'successMetrics', 'adaptationTriggers' ]; requiredSections.forEach(section => { if (section === 'role' && persona.role && persona.role !== 'Unknown Role') { completenessScore += 10; } else if (section === 'coreIdentity' && persona.coreIdentity && persona.coreIdentity.length > 50) { completenessScore += 15; } else if (section === 'interactionPatterns' && Object.keys(persona.interactionPatterns).length > 0) { completenessScore += 10; } else if (Array.isArray(persona[section]) && persona[section].length > 0) { completenessScore += 10; } }); assessment.scores.completeness = Math.min(100, completenessScore); // Clarity assessment (based on content length and structure) let clarityScore = 0; if (persona.coreIdentity.length > 100) clarityScore += 25; if (persona.primaryResponsibilities.length >= 3) clarityScore += 25; if (persona.behavioralGuidelines.length >= 3) clarityScore += 25; if (Object.keys(persona.interactionPatterns).length >= 2) clarityScore += 25; assessment.scores.clarity = clarityScore; // Specificity assessment let specificityScore = 0; if (persona.technicalExpertise && persona.technicalExpertise.length > 0) specificityScore += 20; if (persona.toolsAndTechniques && persona.toolsAndTechniques.length > 0) specificityScore += 20; if (persona.metadata.capabilities.length > 0) specificityScore += 20; if (persona.metadata.dependencies.length > 0) specificityScore += 20; if (persona.successMetrics.length >= 3) specificityScore += 20; assessment.scores.specificity = specificityScore; // Consistency assessment (basic checks for now) let consistencyScore = 80; // Start high and deduct for inconsistencies // Check if role is mentioned in core identity if (!persona.coreIdentity.toLowerCase().includes(persona.role.toLowerCase().split(' ')[0])) { consistencyScore -= 20; assessment.recommendations.push('Consider mentioning the role in the core identity'); } assessment.scores.consistency = Math.max(0, consistencyScore); // Calculate overall assessment const avgScore = Object.values(assessment.scores).reduce((sum, score) => sum + score, 0) / 4; if (avgScore >= 80) { assessment.overall = 'excellent'; } else if (avgScore >= 60) { assessment.overall = 'good'; } else if (avgScore >= 40) { assessment.overall = 'fair'; } else { assessment.overall = 'poor'; } // Add specific recommendations if (assessment.scores.completeness < 80) { assessment.recommendations.push('Add more comprehensive content to all sections'); } if (assessment.scores.clarity < 60) { assessment.recommendations.push('Improve clarity with more detailed descriptions'); } if (assessment.scores.specificity < 60) { assessment.recommendations.push('Add more specific technical details and capabilities'); } return assessment; } /** * Check if persona follows best practices */ validateBestPractices(persona) { const issues = []; const recommendations = []; // Check naming conventions if (persona.metadata.id !== persona.metadata.id.toLowerCase().replace(/\s+/g, '-')) { issues.push('Persona ID should be lowercase with hyphens instead of spaces'); } // Check role formatting if (!persona.role.includes('Agent') && !persona.role.includes('Specialist')) { recommendations.push('Consider including "Agent" or "Specialist" in the role title'); } // Check for action-oriented responsibilities const actionWords = ['create', 'develop', 'implement', 'design', 'analyze', 'validate', 'ensure', 'manage']; const hasActionOrientedResponsibilities = persona.primaryResponsibilities.some(resp => actionWords.some(word => resp.toLowerCase().includes(word))); if (!hasActionOrientedResponsibilities) { recommendations.push('Use action-oriented language in primary responsibilities'); } // Check interaction patterns structure const hasMultipleInteractionTypes = Object.keys(persona.interactionPatterns).length >= 2; if (!hasMultipleInteractionTypes) { recommendations.push('Define interaction patterns with multiple agent types or roles'); } // Check success metrics specificity const hasQuantifiableMetrics = persona.successMetrics.some(metric => /\d+|percentage|rate|time|score/.test(metric.toLowerCase())); if (!hasQuantifiableMetrics) { recommendations.push('Include quantifiable metrics where possible'); } return { followsBestPractices: issues.length === 0, issues, recommendations, practiceScore: Math.max(0, 100 - (issues.length * 20) - (recommendations.length * 10)) }; } } exports.PersonaValidator = PersonaValidator; //# sourceMappingURL=validator.js.map