validate_content
Check content quality by validating broken links, code syntax, references, and basic accuracy in documentation files.
Instructions
Validate general content quality: broken links, code syntax, references, and basic accuracy
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| contentPath | Yes | Path to the content directory to validate | |
| validationType | No | Type of validation: links, code, references, or all | all |
| includeCodeValidation | No | Whether to validate code blocks | |
| followExternalLinks | No | Whether to validate external URLs (slower) |
Implementation Reference
- src/tools/validate-content.ts:1751-1820 (handler)Main execution handler for the validate_content tool. Creates ContentAccuracyValidator instance and orchestrates the validation process with timeout protection and progress reporting.export async function handleValidateDiataxisContent( args: any, context?: any, ): Promise<ValidationResult> { await context?.info?.("🔍 Starting Diataxis content validation..."); const validator = new ContentAccuracyValidator(); // Add timeout protection to prevent infinite hangs const timeoutMs = 120000; // 2 minutes let timeoutHandle: NodeJS.Timeout; const timeoutPromise = new Promise<ValidationResult>((_, reject) => { timeoutHandle = setTimeout(() => { reject( new Error( `Validation timed out after ${ timeoutMs / 1000 } seconds. This may be due to a large directory structure. Try validating a smaller subset or specific directory.`, ), ); }, timeoutMs); }); const validationPromise = validator.validateContent(args, context); try { const result = await Promise.race([validationPromise, timeoutPromise]); clearTimeout(timeoutHandle!); return result; } catch (error: any) { clearTimeout(timeoutHandle!); // Return a partial result with error information return { success: false, confidence: { overall: 0, breakdown: { technologyDetection: 0, frameworkVersionAccuracy: 0, codeExampleRelevance: 0, architecturalAssumptions: 0, businessContextAlignment: 0, }, riskFactors: [ { type: "high", category: "validation", description: "Validation process failed or timed out", impact: "Unable to complete content validation", mitigation: "Try validating a smaller directory or specific subset of files", }, ], }, issues: [], uncertainties: [], recommendations: [ "Validation failed or timed out", "Consider validating smaller directory subsets", "Check for very large files or deep directory structures", `Error: ${error.message}`, ], nextSteps: [ "Verify the content path is correct and accessible", "Try validating specific subdirectories instead of the entire project", "Check for circular symlinks or very deep directory structures", ], }; } }
- Tool schema definition and registration export. Defines input parameters for content validation. Referenced as 'validate_content' in other tools' prompts.export const validateDiataxisContent: Tool = { name: "validate_diataxis_content", description: "Validate the accuracy, completeness, and compliance of generated Diataxis documentation", inputSchema: { type: "object", properties: { contentPath: { type: "string", description: "Path to the documentation directory to validate", }, analysisId: { type: "string", description: "Optional repository analysis ID for context-aware validation", }, validationType: { type: "string", enum: ["accuracy", "completeness", "compliance", "all"], default: "all", description: "Type of validation to perform", }, includeCodeValidation: { type: "boolean", default: true, description: "Whether to validate code examples for correctness", }, confidence: { type: "string", enum: ["strict", "moderate", "permissive"], default: "moderate", description: "Validation confidence level - stricter levels catch more issues", }, }, required: ["contentPath"], }, };
- src/tools/validate-content.ts:96-237 (helper)Core ContentAccuracyValidator class with validateContent method implementing the validation logic: accuracy checks, completeness analysis, Diataxis compliance, code example validation, confidence scoring, and recommendations.class ContentAccuracyValidator { private projectContext: any; private tempDir: string; private executionSimulator: ExecutionSimulator | null = null; private useExecutionSimulation: boolean; constructor(useExecutionSimulation: boolean = true) { this.tempDir = path.join(currentDir, ".tmp"); this.useExecutionSimulation = useExecutionSimulation; // Initialize execution simulator if enabled if (useExecutionSimulation) { this.executionSimulator = createExecutionSimulator({ maxDepth: 5, maxSteps: 50, timeoutMs: 15000, detectNullRefs: true, detectTypeMismatches: true, detectUnreachableCode: true, confidenceThreshold: 0.6, }); } } async validateContent( options: ValidationOptions, context?: any, ): Promise<ValidationResult> { if (context?.meta?.progressToken) { await context.meta.reportProgress?.({ progress: 0, total: 100 }); } const result: ValidationResult = { success: false, confidence: this.initializeConfidenceMetrics(), issues: [], uncertainties: [], recommendations: [], nextSteps: [], }; // Load project context if analysis ID provided if (options.analysisId) { await context?.info?.("📊 Loading project context..."); this.projectContext = await this.loadProjectContext(options.analysisId); } if (context?.meta?.progressToken) { await context.meta.reportProgress?.({ progress: 20, total: 100 }); } // Determine if we should analyze application code vs documentation await context?.info?.("🔎 Analyzing content type..."); const isApplicationValidation = await this.shouldAnalyzeApplicationCode( options.contentPath, ); if (context?.meta?.progressToken) { await context.meta.reportProgress?.({ progress: 40, total: 100 }); } // Perform different types of validation based on request if ( options.validationType === "all" || options.validationType === "accuracy" ) { await this.validateAccuracy(options.contentPath, result); } if ( options.validationType === "all" || options.validationType === "completeness" ) { await this.validateCompleteness(options.contentPath, result); } if ( options.validationType === "all" || options.validationType === "compliance" ) { if (isApplicationValidation) { await this.validateApplicationStructureCompliance( options.contentPath, result, ); } else { await this.validateDiataxisCompliance(options.contentPath, result); } } // Code validation if requested if (options.includeCodeValidation) { result.codeValidation = await this.validateCodeExamples( options.contentPath, ); // Set code example relevance confidence based on code validation results if (result.codeValidation) { const successRate = result.codeValidation.exampleResults.length > 0 ? result.codeValidation.exampleResults.filter( (e) => e.compilationSuccess, ).length / result.codeValidation.exampleResults.length : 1; result.confidence.breakdown.codeExampleRelevance = Math.round( successRate * 100, ); } } else { // If code validation is skipped, assume reasonable confidence result.confidence.breakdown.codeExampleRelevance = 75; } // Set framework version accuracy based on technology detection confidence result.confidence.breakdown.frameworkVersionAccuracy = Math.min( 90, result.confidence.breakdown.technologyDetection + 10, ); // Set architectural assumptions confidence based on file structure and content analysis const filesAnalyzed = await this.getMarkdownFiles(options.contentPath); const hasStructuredContent = filesAnalyzed.length > 3; // Basic heuristic result.confidence.breakdown.architecturalAssumptions = hasStructuredContent ? 80 : 60; // Calculate overall confidence and success this.calculateOverallMetrics(result); // Generate recommendations and next steps this.generateRecommendations(result, options); if (context?.meta?.progressToken) { await context.meta.reportProgress?.({ progress: 100, total: 100 }); } const status = result.success ? "PASSED" : "ISSUES FOUND"; await context?.info?.( `✅ Validation complete! Status: ${status} (${result.confidence.overall}% confidence, ${result.issues.length} issue(s))`, ); return result; }
- References to "validate_content" tool in relatedTools arrays and nextSteps, confirming usage as validate_content tool name in workflows."validate_content", "setup_structure", ], }); } } // Style improvement prompts based on health scores if ( promptTypes.includes("style_improvement") && documentationContext.readmeHealth && documentationContext.readmeHealth < 80 ) { prompts.push({ id: "style-improvement-prompt", title: "Documentation Style Enhancement", category: "style_improvement", audience, priority: "medium", prompt: `Improve the writing style and clarity of existing documentation. Focus on ${audience} readability, consistent tone, and professional presentation.`, context: `Current README health score: ${documentationContext.readmeHealth}/100`, expectedOutput: "Refined documentation with improved clarity, consistency, and professional tone", integrationHints: [ "Use evaluate_readme_health metrics for focus areas", "Apply readme_best_practices guidelines", "Validate improvements with content validation", ], relatedTools: [ "evaluate_readme_health", "readme_best_practices", "validate_content", ], }); } // Advanced integration prompts for comprehensive level if (integrationLevel === "comprehensive" || integrationLevel === "advanced") { prompts.push({ id: "deployment-docs-prompt", title: "Deployment Documentation", category: "deployment_optimization", audience, priority: "medium", prompt: `Create deployment documentation that integrates with the recommended static site generator and deployment workflow. Include environment setup, build process, and troubleshooting.`, context: `Project has CI: ${projectContext.hasCI}, Package manager: ${projectContext.packageManager}`, expectedOutput: "Complete deployment guide with step-by-step instructions and troubleshooting", integrationHints: [ "Use recommend_ssg output for deployment strategy", "Reference deploy_pages workflow", "Include verify_deployment checklist", ], relatedTools: [ "recommend_ssg", "deploy_pages", "verify_deployment", "test_local_deployment", ], }); } return prompts; } /** * Generate integration recommendations based on cross-tool insights */ function generateIntegrationRecommendations( projectContext: ProjectContext, documentationContext: DocumentationContext, _prompts: TechnicalWriterPrompt[], ): string[] { const recommendations: string[] = []; recommendations.push( "Run analyze_repository first to establish comprehensive project context", ); if (!documentationContext.readmeExists) { recommendations.push( "Use generate_readme_template to create initial README structure", ); } if (documentationContext.documentationGaps.length > 0) { recommendations.push( "Execute detect_documentation_gaps to identify all missing content areas", ); } if (projectContext.hasTests) { recommendations.push( "Include testing documentation using repository analysis insights", ); } if (projectContext.hasCI) { recommendations.push( "Document CI/CD workflow using deployment tool integration", ); } recommendations.push( "Validate all generated content using validate_content tool", ); recommendations.push( "Check documentation links with check_documentation_links after content creation", ); return recommendations; } /** * Generate next steps based on prompts and integration level */ function generateNextSteps( prompts: TechnicalWriterPrompt[], integrationLevel: string, ): NextStep[] { const steps: NextStep[] = []; steps.push({ action: "Execute high-priority prompts first to address critical documentation gaps", toolRequired: "generate_technical_writer_prompts", priority: "high", }); steps.push({ action: "Use generated prompts with AI writing tools for content creation", toolRequired: "optimize_readme", priority: "high", }); steps.push({ action: "Validate generated content using DocuMCP validation tools", toolRequired: "validate_content", priority: "medium", }); if (integrationLevel === "comprehensive" || integrationLevel === "advanced") { steps.push({ action: "Run full documentation workflow using integrated tool chain", toolRequired: "analyze_repository", priority: "medium", }); steps.push({ action: "Test documentation with target audience using deployment tools", toolRequired: "test_local_deployment", priority: "low", }); } steps.push({ action: "Iterate on content based on validation feedback and best practices analysis", toolRequired: "readme_best_practices", priority: "low", }); return steps; } /** * Helper functions */ async function fileExists(path: string): Promise<boolean> { try { await fs.access(path); return true; } catch { return false; } } async function hasTestFiles(projectPath: string): Promise<boolean> { try { const files = await fs.readdir(projectPath, { recursive: true }); return files.some( (file) => typeof file === "string" && (file.includes("test") || file.includes("spec") || file.endsWith(".test.js") || file.endsWith(".spec.js")), ); } catch { return false; } } async function hasCIConfig(projectPath: string): Promise<boolean> { const ciFiles = [ ".github/workflows", ".gitlab-ci.yml", "circle.yml", ".travis.yml", ]; for (const ciFile of ciFiles) { if (await fileExists(join(projectPath, ciFile))) { return true; } } return false; } function categorizePrompts( prompts: TechnicalWriterPrompt[], ): Record<string, number> { const categories: Record<string, number> = {}; for (const prompt of prompts) { categories[prompt.category] = (categories[prompt.category] || 0) + 1; } return categories; } function calculateConfidenceScore( projectContext: ProjectContext, documentationContext: DocumentationContext, ): number { let score = 50; // Base score // Increase confidence based on available context if (projectContext.projectType !== "unknown") score += 20; if (projectContext.languages.length > 0) score += 15; if (projectContext.frameworks.length > 0) score += 10; if (documentationContext.readmeExists) score += 5; return Math.min(score, 100); }