#
tokens: 21790/50000 1/274 files (page 25/29)
lines: on (toggle) GitHub
raw markdown copy reset
This is page 25 of 29. Use http://codebase.md/tosin2013/documcp?lines=true&page={x} to view the full context.

# Directory Structure

```
├── .dockerignore
├── .eslintignore
├── .eslintrc.json
├── .github
│   ├── agents
│   │   ├── documcp-ast.md
│   │   ├── documcp-deploy.md
│   │   ├── documcp-memory.md
│   │   ├── documcp-test.md
│   │   └── documcp-tool.md
│   ├── copilot-instructions.md
│   ├── dependabot.yml
│   ├── ISSUE_TEMPLATE
│   │   ├── automated-changelog.md
│   │   ├── bug_report.md
│   │   ├── bug_report.yml
│   │   ├── documentation_issue.md
│   │   ├── feature_request.md
│   │   ├── feature_request.yml
│   │   ├── npm-publishing-fix.md
│   │   └── release_improvements.md
│   ├── PULL_REQUEST_TEMPLATE.md
│   ├── release-drafter.yml
│   └── workflows
│       ├── auto-merge.yml
│       ├── ci.yml
│       ├── codeql.yml
│       ├── dependency-review.yml
│       ├── deploy-docs.yml
│       ├── README.md
│       ├── release-drafter.yml
│       └── release.yml
├── .gitignore
├── .husky
│   ├── commit-msg
│   └── pre-commit
├── .linkcheck.config.json
├── .markdown-link-check.json
├── .nvmrc
├── .pre-commit-config.yaml
├── .versionrc.json
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── commitlint.config.js
├── CONTRIBUTING.md
├── docker-compose.docs.yml
├── Dockerfile.docs
├── docs
│   ├── .docusaurus
│   │   ├── docusaurus-plugin-content-docs
│   │   │   └── default
│   │   │       └── __mdx-loader-dependency.json
│   │   └── docusaurus-plugin-content-pages
│   │       └── default
│   │           └── __plugin.json
│   ├── adrs
│   │   ├── 001-mcp-server-architecture.md
│   │   ├── 002-repository-analysis-engine.md
│   │   ├── 003-static-site-generator-recommendation-engine.md
│   │   ├── 004-diataxis-framework-integration.md
│   │   ├── 005-github-pages-deployment-automation.md
│   │   ├── 006-mcp-tools-api-design.md
│   │   ├── 007-mcp-prompts-and-resources-integration.md
│   │   ├── 008-intelligent-content-population-engine.md
│   │   ├── 009-content-accuracy-validation-framework.md
│   │   ├── 010-mcp-resource-pattern-redesign.md
│   │   └── README.md
│   ├── api
│   │   ├── .nojekyll
│   │   ├── assets
│   │   │   ├── hierarchy.js
│   │   │   ├── highlight.css
│   │   │   ├── icons.js
│   │   │   ├── icons.svg
│   │   │   ├── main.js
│   │   │   ├── navigation.js
│   │   │   ├── search.js
│   │   │   └── style.css
│   │   ├── hierarchy.html
│   │   ├── index.html
│   │   ├── modules.html
│   │   └── variables
│   │       └── TOOLS.html
│   ├── assets
│   │   └── logo.svg
│   ├── development
│   │   └── MCP_INSPECTOR_TESTING.md
│   ├── docusaurus.config.js
│   ├── explanation
│   │   ├── architecture.md
│   │   └── index.md
│   ├── guides
│   │   ├── link-validation.md
│   │   ├── playwright-integration.md
│   │   └── playwright-testing-workflow.md
│   ├── how-to
│   │   ├── analytics-setup.md
│   │   ├── custom-domains.md
│   │   ├── documentation-freshness-tracking.md
│   │   ├── github-pages-deployment.md
│   │   ├── index.md
│   │   ├── local-testing.md
│   │   ├── performance-optimization.md
│   │   ├── prompting-guide.md
│   │   ├── repository-analysis.md
│   │   ├── seo-optimization.md
│   │   ├── site-monitoring.md
│   │   ├── troubleshooting.md
│   │   └── usage-examples.md
│   ├── index.md
│   ├── knowledge-graph.md
│   ├── package-lock.json
│   ├── package.json
│   ├── phase-2-intelligence.md
│   ├── reference
│   │   ├── api-overview.md
│   │   ├── cli.md
│   │   ├── configuration.md
│   │   ├── deploy-pages.md
│   │   ├── index.md
│   │   ├── mcp-tools.md
│   │   └── prompt-templates.md
│   ├── research
│   │   ├── cross-domain-integration
│   │   │   └── README.md
│   │   ├── domain-1-mcp-architecture
│   │   │   ├── index.md
│   │   │   └── mcp-performance-research.md
│   │   ├── domain-2-repository-analysis
│   │   │   └── README.md
│   │   ├── domain-3-ssg-recommendation
│   │   │   ├── index.md
│   │   │   └── ssg-performance-analysis.md
│   │   ├── domain-4-diataxis-integration
│   │   │   └── README.md
│   │   ├── domain-5-github-deployment
│   │   │   ├── github-pages-security-analysis.md
│   │   │   └── index.md
│   │   ├── domain-6-api-design
│   │   │   └── README.md
│   │   ├── README.md
│   │   ├── research-integration-summary-2025-01-14.md
│   │   ├── research-progress-template.md
│   │   └── research-questions-2025-01-14.md
│   ├── robots.txt
│   ├── sidebars.js
│   ├── sitemap.xml
│   ├── src
│   │   └── css
│   │       └── custom.css
│   └── tutorials
│       ├── development-setup.md
│       ├── environment-setup.md
│       ├── first-deployment.md
│       ├── getting-started.md
│       ├── index.md
│       ├── memory-workflows.md
│       └── user-onboarding.md
├── jest.config.js
├── LICENSE
├── Makefile
├── MCP_PHASE2_IMPLEMENTATION.md
├── mcp-config-example.json
├── mcp.json
├── package-lock.json
├── package.json
├── README.md
├── release.sh
├── scripts
│   └── check-package-structure.cjs
├── SECURITY.md
├── setup-precommit.sh
├── src
│   ├── benchmarks
│   │   └── performance.ts
│   ├── index.ts
│   ├── memory
│   │   ├── contextual-retrieval.ts
│   │   ├── deployment-analytics.ts
│   │   ├── enhanced-manager.ts
│   │   ├── export-import.ts
│   │   ├── freshness-kg-integration.ts
│   │   ├── index.ts
│   │   ├── integration.ts
│   │   ├── kg-code-integration.ts
│   │   ├── kg-health.ts
│   │   ├── kg-integration.ts
│   │   ├── kg-link-validator.ts
│   │   ├── kg-storage.ts
│   │   ├── knowledge-graph.ts
│   │   ├── learning.ts
│   │   ├── manager.ts
│   │   ├── multi-agent-sharing.ts
│   │   ├── pruning.ts
│   │   ├── schemas.ts
│   │   ├── storage.ts
│   │   ├── temporal-analysis.ts
│   │   ├── user-preferences.ts
│   │   └── visualization.ts
│   ├── prompts
│   │   └── technical-writer-prompts.ts
│   ├── scripts
│   │   └── benchmark.ts
│   ├── templates
│   │   └── playwright
│   │       ├── accessibility.spec.template.ts
│   │       ├── Dockerfile.template
│   │       ├── docs-e2e.workflow.template.yml
│   │       ├── link-validation.spec.template.ts
│   │       └── playwright.config.template.ts
│   ├── tools
│   │   ├── analyze-deployments.ts
│   │   ├── analyze-readme.ts
│   │   ├── analyze-repository.ts
│   │   ├── check-documentation-links.ts
│   │   ├── deploy-pages.ts
│   │   ├── detect-gaps.ts
│   │   ├── evaluate-readme-health.ts
│   │   ├── generate-config.ts
│   │   ├── generate-contextual-content.ts
│   │   ├── generate-llm-context.ts
│   │   ├── generate-readme-template.ts
│   │   ├── generate-technical-writer-prompts.ts
│   │   ├── kg-health-check.ts
│   │   ├── manage-preferences.ts
│   │   ├── manage-sitemap.ts
│   │   ├── optimize-readme.ts
│   │   ├── populate-content.ts
│   │   ├── readme-best-practices.ts
│   │   ├── recommend-ssg.ts
│   │   ├── setup-playwright-tests.ts
│   │   ├── setup-structure.ts
│   │   ├── sync-code-to-docs.ts
│   │   ├── test-local-deployment.ts
│   │   ├── track-documentation-freshness.ts
│   │   ├── update-existing-documentation.ts
│   │   ├── validate-content.ts
│   │   ├── validate-documentation-freshness.ts
│   │   ├── validate-readme-checklist.ts
│   │   └── verify-deployment.ts
│   ├── types
│   │   └── api.ts
│   ├── utils
│   │   ├── ast-analyzer.ts
│   │   ├── code-scanner.ts
│   │   ├── content-extractor.ts
│   │   ├── drift-detector.ts
│   │   ├── freshness-tracker.ts
│   │   ├── language-parsers-simple.ts
│   │   ├── permission-checker.ts
│   │   └── sitemap-generator.ts
│   └── workflows
│       └── documentation-workflow.ts
├── test-docs-local.sh
├── tests
│   ├── api
│   │   └── mcp-responses.test.ts
│   ├── benchmarks
│   │   └── performance.test.ts
│   ├── edge-cases
│   │   └── error-handling.test.ts
│   ├── functional
│   │   └── tools.test.ts
│   ├── integration
│   │   ├── kg-documentation-workflow.test.ts
│   │   ├── knowledge-graph-workflow.test.ts
│   │   ├── mcp-readme-tools.test.ts
│   │   ├── memory-mcp-tools.test.ts
│   │   ├── readme-technical-writer.test.ts
│   │   └── workflow.test.ts
│   ├── memory
│   │   ├── contextual-retrieval.test.ts
│   │   ├── enhanced-manager.test.ts
│   │   ├── export-import.test.ts
│   │   ├── freshness-kg-integration.test.ts
│   │   ├── kg-code-integration.test.ts
│   │   ├── kg-health.test.ts
│   │   ├── kg-link-validator.test.ts
│   │   ├── kg-storage-validation.test.ts
│   │   ├── kg-storage.test.ts
│   │   ├── knowledge-graph-enhanced.test.ts
│   │   ├── knowledge-graph.test.ts
│   │   ├── learning.test.ts
│   │   ├── manager-advanced.test.ts
│   │   ├── manager.test.ts
│   │   ├── mcp-resource-integration.test.ts
│   │   ├── mcp-tool-persistence.test.ts
│   │   ├── schemas.test.ts
│   │   ├── storage.test.ts
│   │   ├── temporal-analysis.test.ts
│   │   └── user-preferences.test.ts
│   ├── performance
│   │   ├── memory-load-testing.test.ts
│   │   └── memory-stress-testing.test.ts
│   ├── prompts
│   │   ├── guided-workflow-prompts.test.ts
│   │   └── technical-writer-prompts.test.ts
│   ├── server.test.ts
│   ├── setup.ts
│   ├── tools
│   │   ├── all-tools.test.ts
│   │   ├── analyze-coverage.test.ts
│   │   ├── analyze-deployments.test.ts
│   │   ├── analyze-readme.test.ts
│   │   ├── analyze-repository.test.ts
│   │   ├── check-documentation-links.test.ts
│   │   ├── deploy-pages-kg-retrieval.test.ts
│   │   ├── deploy-pages-tracking.test.ts
│   │   ├── deploy-pages.test.ts
│   │   ├── detect-gaps.test.ts
│   │   ├── evaluate-readme-health.test.ts
│   │   ├── generate-contextual-content.test.ts
│   │   ├── generate-llm-context.test.ts
│   │   ├── generate-readme-template.test.ts
│   │   ├── generate-technical-writer-prompts.test.ts
│   │   ├── kg-health-check.test.ts
│   │   ├── manage-sitemap.test.ts
│   │   ├── optimize-readme.test.ts
│   │   ├── readme-best-practices.test.ts
│   │   ├── recommend-ssg-historical.test.ts
│   │   ├── recommend-ssg-preferences.test.ts
│   │   ├── recommend-ssg.test.ts
│   │   ├── simple-coverage.test.ts
│   │   ├── sync-code-to-docs.test.ts
│   │   ├── test-local-deployment.test.ts
│   │   ├── tool-error-handling.test.ts
│   │   ├── track-documentation-freshness.test.ts
│   │   ├── validate-content.test.ts
│   │   ├── validate-documentation-freshness.test.ts
│   │   └── validate-readme-checklist.test.ts
│   ├── types
│   │   └── type-safety.test.ts
│   └── utils
│       ├── ast-analyzer.test.ts
│       ├── content-extractor.test.ts
│       ├── drift-detector.test.ts
│       ├── freshness-tracker.test.ts
│       └── sitemap-generator.test.ts
├── tsconfig.json
└── typedoc.json
```

# Files

--------------------------------------------------------------------------------
/src/tools/validate-content.ts:
--------------------------------------------------------------------------------

```typescript
   1 | import { Tool } from "@modelcontextprotocol/sdk/types.js";
   2 | import * as fs from "fs/promises";
   3 | import * as path from "path";
   4 | import { exec } from "child_process";
   5 | import { promisify } from "util";
   6 | import { handleMemoryRecall } from "../memory/index.js";
   7 | // ESM-compatible dirname replacement - fallback for test environments
   8 | function getDirname(): string {
   9 |   // Use process.cwd() as fallback for all environments to avoid import.meta issues
  10 |   return process.cwd();
  11 | }
  12 | 
  13 | const currentDir = getDirname();
  14 | 
  15 | const execAsync = promisify(exec);
  16 | 
  17 | interface ValidationOptions {
  18 |   contentPath: string;
  19 |   analysisId?: string;
  20 |   validationType: "accuracy" | "completeness" | "compliance" | "all";
  21 |   includeCodeValidation: boolean;
  22 |   confidence: "strict" | "moderate" | "permissive";
  23 | }
  24 | 
  25 | interface ConfidenceMetrics {
  26 |   overall: number;
  27 |   breakdown: {
  28 |     technologyDetection: number;
  29 |     frameworkVersionAccuracy: number;
  30 |     codeExampleRelevance: number;
  31 |     architecturalAssumptions: number;
  32 |     businessContextAlignment: number;
  33 |   };
  34 |   riskFactors: RiskFactor[];
  35 | }
  36 | 
  37 | interface RiskFactor {
  38 |   type: "high" | "medium" | "low";
  39 |   category: string;
  40 |   description: string;
  41 |   impact: string;
  42 |   mitigation: string;
  43 | }
  44 | 
  45 | interface UncertaintyFlag {
  46 |   area: string;
  47 |   severity: "low" | "medium" | "high" | "critical";
  48 |   description: string;
  49 |   potentialImpact: string;
  50 |   clarificationNeeded: string;
  51 |   fallbackStrategy: string;
  52 | }
  53 | 
  54 | interface ValidationIssue {
  55 |   type: "error" | "warning" | "info";
  56 |   category: "accuracy" | "completeness" | "compliance" | "performance";
  57 |   location: {
  58 |     file: string;
  59 |     line?: number;
  60 |     section?: string;
  61 |   };
  62 |   description: string;
  63 |   evidence: string[];
  64 |   suggestedFix: string;
  65 |   confidence: number;
  66 | }
  67 | 
  68 | interface CodeValidationResult {
  69 |   overallSuccess: boolean;
  70 |   exampleResults: ExampleValidation[];
  71 |   confidence: number;
  72 | }
  73 | 
  74 | interface ExampleValidation {
  75 |   example: string;
  76 |   compilationSuccess: boolean;
  77 |   executionSuccess: boolean;
  78 |   issues: ValidationIssue[];
  79 |   confidence: number;
  80 | }
  81 | 
  82 | export interface ValidationResult {
  83 |   success: boolean;
  84 |   confidence: ConfidenceMetrics;
  85 |   issues: ValidationIssue[];
  86 |   uncertainties: UncertaintyFlag[];
  87 |   codeValidation?: CodeValidationResult;
  88 |   recommendations: string[];
  89 |   nextSteps: string[];
  90 | }
  91 | 
  92 | class ContentAccuracyValidator {
  93 |   private projectContext: any;
  94 |   private tempDir: string;
  95 | 
  96 |   constructor() {
  97 |     this.tempDir = path.join(currentDir, ".tmp");
  98 |   }
  99 | 
 100 |   async validateContent(
 101 |     options: ValidationOptions,
 102 |     context?: any,
 103 |   ): Promise<ValidationResult> {
 104 |     if (context?.meta?.progressToken) {
 105 |       await context.meta.reportProgress?.({ progress: 0, total: 100 });
 106 |     }
 107 | 
 108 |     const result: ValidationResult = {
 109 |       success: false,
 110 |       confidence: this.initializeConfidenceMetrics(),
 111 |       issues: [],
 112 |       uncertainties: [],
 113 |       recommendations: [],
 114 |       nextSteps: [],
 115 |     };
 116 | 
 117 |     // Load project context if analysis ID provided
 118 |     if (options.analysisId) {
 119 |       await context?.info?.("📊 Loading project context...");
 120 |       this.projectContext = await this.loadProjectContext(options.analysisId);
 121 |     }
 122 | 
 123 |     if (context?.meta?.progressToken) {
 124 |       await context.meta.reportProgress?.({ progress: 20, total: 100 });
 125 |     }
 126 | 
 127 |     // Determine if we should analyze application code vs documentation
 128 |     await context?.info?.("🔎 Analyzing content type...");
 129 |     const isApplicationValidation = await this.shouldAnalyzeApplicationCode(
 130 |       options.contentPath,
 131 |     );
 132 | 
 133 |     if (context?.meta?.progressToken) {
 134 |       await context.meta.reportProgress?.({ progress: 40, total: 100 });
 135 |     }
 136 | 
 137 |     // Perform different types of validation based on request
 138 |     if (
 139 |       options.validationType === "all" ||
 140 |       options.validationType === "accuracy"
 141 |     ) {
 142 |       await this.validateAccuracy(options.contentPath, result);
 143 |     }
 144 | 
 145 |     if (
 146 |       options.validationType === "all" ||
 147 |       options.validationType === "completeness"
 148 |     ) {
 149 |       await this.validateCompleteness(options.contentPath, result);
 150 |     }
 151 | 
 152 |     if (
 153 |       options.validationType === "all" ||
 154 |       options.validationType === "compliance"
 155 |     ) {
 156 |       if (isApplicationValidation) {
 157 |         await this.validateApplicationStructureCompliance(
 158 |           options.contentPath,
 159 |           result,
 160 |         );
 161 |       } else {
 162 |         await this.validateDiataxisCompliance(options.contentPath, result);
 163 |       }
 164 |     }
 165 | 
 166 |     // Code validation if requested
 167 |     if (options.includeCodeValidation) {
 168 |       result.codeValidation = await this.validateCodeExamples(
 169 |         options.contentPath,
 170 |       );
 171 |       // Set code example relevance confidence based on code validation results
 172 |       if (result.codeValidation) {
 173 |         const successRate =
 174 |           result.codeValidation.exampleResults.length > 0
 175 |             ? result.codeValidation.exampleResults.filter(
 176 |                 (e) => e.compilationSuccess,
 177 |               ).length / result.codeValidation.exampleResults.length
 178 |             : 1;
 179 |         result.confidence.breakdown.codeExampleRelevance = Math.round(
 180 |           successRate * 100,
 181 |         );
 182 |       }
 183 |     } else {
 184 |       // If code validation is skipped, assume reasonable confidence
 185 |       result.confidence.breakdown.codeExampleRelevance = 75;
 186 |     }
 187 | 
 188 |     // Set framework version accuracy based on technology detection confidence
 189 |     result.confidence.breakdown.frameworkVersionAccuracy = Math.min(
 190 |       90,
 191 |       result.confidence.breakdown.technologyDetection + 10,
 192 |     );
 193 | 
 194 |     // Set architectural assumptions confidence based on file structure and content analysis
 195 |     const filesAnalyzed = await this.getMarkdownFiles(options.contentPath);
 196 |     const hasStructuredContent = filesAnalyzed.length > 3; // Basic heuristic
 197 |     result.confidence.breakdown.architecturalAssumptions = hasStructuredContent
 198 |       ? 80
 199 |       : 60;
 200 | 
 201 |     // Calculate overall confidence and success
 202 |     this.calculateOverallMetrics(result);
 203 | 
 204 |     // Generate recommendations and next steps
 205 |     this.generateRecommendations(result, options);
 206 | 
 207 |     if (context?.meta?.progressToken) {
 208 |       await context.meta.reportProgress?.({ progress: 100, total: 100 });
 209 |     }
 210 | 
 211 |     const status = result.success ? "PASSED" : "ISSUES FOUND";
 212 |     await context?.info?.(
 213 |       `✅ Validation complete! Status: ${status} (${result.confidence.overall}% confidence, ${result.issues.length} issue(s))`,
 214 |     );
 215 | 
 216 |     return result;
 217 |   }
 218 | 
 219 |   private initializeConfidenceMetrics(): ConfidenceMetrics {
 220 |     return {
 221 |       overall: 0,
 222 |       breakdown: {
 223 |         technologyDetection: 0,
 224 |         frameworkVersionAccuracy: 0,
 225 |         codeExampleRelevance: 0,
 226 |         architecturalAssumptions: 0,
 227 |         businessContextAlignment: 0,
 228 |       },
 229 |       riskFactors: [],
 230 |     };
 231 |   }
 232 | 
 233 |   private async loadProjectContext(analysisId: string): Promise<any> {
 234 |     // Try to get analysis from memory system first
 235 |     try {
 236 |       const memoryRecall = await handleMemoryRecall({
 237 |         query: analysisId,
 238 |         type: "analysis",
 239 |         limit: 1,
 240 |       });
 241 | 
 242 |       // Handle the memory recall result structure
 243 |       if (
 244 |         memoryRecall &&
 245 |         memoryRecall.memories &&
 246 |         memoryRecall.memories.length > 0
 247 |       ) {
 248 |         const memory = memoryRecall.memories[0];
 249 | 
 250 |         // Handle wrapped content structure
 251 |         if (
 252 |           memory.data &&
 253 |           memory.data.content &&
 254 |           Array.isArray(memory.data.content)
 255 |         ) {
 256 |           // Extract the JSON from the first text content
 257 |           const firstContent = memory.data.content[0];
 258 |           if (
 259 |             firstContent &&
 260 |             firstContent.type === "text" &&
 261 |             firstContent.text
 262 |           ) {
 263 |             try {
 264 |               return JSON.parse(firstContent.text);
 265 |             } catch (parseError) {
 266 |               console.warn(
 267 |                 "Failed to parse analysis content from memory:",
 268 |                 parseError,
 269 |               );
 270 |             }
 271 |           }
 272 |         }
 273 | 
 274 |         // Try direct content or data access
 275 |         if (memory.content) {
 276 |           return memory.content;
 277 |         }
 278 |         if (memory.data) {
 279 |           return memory.data;
 280 |         }
 281 |       }
 282 |     } catch (error) {
 283 |       console.warn("Failed to retrieve from memory system:", error);
 284 |     }
 285 | 
 286 |     // Fallback to reading from cached analysis file
 287 |     try {
 288 |       const analysisPath = path.join(
 289 |         ".documcp",
 290 |         "analyses",
 291 |         `${analysisId}.json`,
 292 |       );
 293 |       const content = await fs.readFile(analysisPath, "utf-8");
 294 |       return JSON.parse(content);
 295 |     } catch {
 296 |       // Return default context if no analysis found
 297 |       return {
 298 |         metadata: { projectName: "unknown", primaryLanguage: "JavaScript" },
 299 |         technologies: {},
 300 |         dependencies: { packages: [] },
 301 |       };
 302 |     }
 303 |   }
 304 | 
 305 |   private async validateAccuracy(
 306 |     contentPath: string,
 307 |     result: ValidationResult,
 308 |   ): Promise<void> {
 309 |     const files = await this.getMarkdownFiles(contentPath);
 310 | 
 311 |     for (const file of files) {
 312 |       const content = await fs.readFile(file, "utf-8");
 313 | 
 314 |       // Check for common accuracy issues
 315 |       await this.checkTechnicalAccuracy(file, content, result);
 316 |       await this.checkFrameworkVersionCompatibility(file, content, result);
 317 |       await this.checkCommandAccuracy(file, content, result);
 318 |       await this.checkLinkValidity(file, content, result);
 319 |     }
 320 | 
 321 |     // Update confidence based on findings
 322 |     this.updateAccuracyConfidence(result);
 323 |   }
 324 | 
 325 |   private async checkTechnicalAccuracy(
 326 |     filePath: string,
 327 |     content: string,
 328 |     result: ValidationResult,
 329 |   ): Promise<void> {
 330 |     // Check for deprecated patterns
 331 |     const deprecatedPatterns = [
 332 |       {
 333 |         pattern: /npm install -g/,
 334 |         suggestion: "Use npx instead of global installs",
 335 |       },
 336 |       { pattern: /var\s+\w+/, suggestion: "Use const or let instead of var" },
 337 |       { pattern: /function\(\)/, suggestion: "Consider using arrow functions" },
 338 |       { pattern: /http:\/\//, suggestion: "Use HTTPS URLs for security" },
 339 |     ];
 340 | 
 341 |     for (const { pattern, suggestion } of deprecatedPatterns) {
 342 |       if (pattern.test(content)) {
 343 |         result.issues.push({
 344 |           type: "warning",
 345 |           category: "accuracy",
 346 |           location: { file: path.basename(filePath) },
 347 |           description: `Potentially outdated pattern detected: ${pattern.source}`,
 348 |           evidence: [content.match(pattern)?.[0] || ""],
 349 |           suggestedFix: suggestion,
 350 |           confidence: 80,
 351 |         });
 352 |       }
 353 |     }
 354 | 
 355 |     // Check for missing error handling in code examples
 356 |     const codeBlocks = this.extractCodeBlocks(content);
 357 |     for (const block of codeBlocks) {
 358 |       if (block.language === "javascript" || block.language === "typescript") {
 359 |         if (
 360 |           block.code.includes("await") &&
 361 |           !block.code.includes("try") &&
 362 |           !block.code.includes("catch")
 363 |         ) {
 364 |           result.issues.push({
 365 |             type: "warning",
 366 |             category: "accuracy",
 367 |             location: { file: path.basename(filePath) },
 368 |             description: "Async code without error handling",
 369 |             evidence: [block.code.substring(0, 100)],
 370 |             suggestedFix: "Add try-catch blocks for async operations",
 371 |             confidence: 90,
 372 |           });
 373 |         }
 374 |       }
 375 |     }
 376 |   }
 377 | 
 378 |   private async checkFrameworkVersionCompatibility(
 379 |     filePath: string,
 380 |     content: string,
 381 |     result: ValidationResult,
 382 |   ): Promise<void> {
 383 |     if (!this.projectContext) return;
 384 | 
 385 |     // Check if mentioned versions align with project dependencies
 386 |     const versionPattern = /@(\d+\.\d+\.\d+)/g;
 387 |     const matches = content.match(versionPattern);
 388 | 
 389 |     if (matches) {
 390 |       for (const match of matches) {
 391 |         const version = match.replace("@", "");
 392 | 
 393 |         result.uncertainties.push({
 394 |           area: "version-compatibility",
 395 |           severity: "medium",
 396 |           description: `Version ${version} mentioned in documentation`,
 397 |           potentialImpact: "May not match actual project dependencies",
 398 |           clarificationNeeded: "Verify version compatibility with project",
 399 |           fallbackStrategy: "Use generic version-agnostic examples",
 400 |         });
 401 |       }
 402 |     }
 403 |   }
 404 | 
 405 |   private async checkCommandAccuracy(
 406 |     filePath: string,
 407 |     content: string,
 408 |     result: ValidationResult,
 409 |   ): Promise<void> {
 410 |     const codeBlocks = this.extractCodeBlocks(content);
 411 | 
 412 |     for (const block of codeBlocks) {
 413 |       if (block.language === "bash" || block.language === "sh") {
 414 |         // Check for common command issues
 415 |         const commands = block.code
 416 |           .split("\n")
 417 |           .filter((line) => line.trim() && !line.startsWith("#"));
 418 | 
 419 |         for (const command of commands) {
 420 |           // Check for potentially dangerous commands
 421 |           const dangerousPatterns = [
 422 |             /rm -rf \//,
 423 |             /sudo rm/,
 424 |             /chmod 777/,
 425 |             /> \/dev\/null 2>&1/,
 426 |           ];
 427 | 
 428 |           for (const pattern of dangerousPatterns) {
 429 |             if (pattern.test(command)) {
 430 |               result.issues.push({
 431 |                 type: "error",
 432 |                 category: "accuracy",
 433 |                 location: { file: path.basename(filePath) },
 434 |                 description: "Potentially dangerous command in documentation",
 435 |                 evidence: [command],
 436 |                 suggestedFix: "Review and provide safer alternative",
 437 |                 confidence: 95,
 438 |               });
 439 |             }
 440 |           }
 441 | 
 442 |           // Check for non-portable commands (Windows vs Unix)
 443 |           if (command.includes("\\") && command.includes("/")) {
 444 |             result.issues.push({
 445 |               type: "warning",
 446 |               category: "accuracy",
 447 |               location: { file: path.basename(filePath) },
 448 |               description: "Mixed path separators in command",
 449 |               evidence: [command],
 450 |               suggestedFix:
 451 |                 "Use consistent path separators or provide OS-specific examples",
 452 |               confidence: 85,
 453 |             });
 454 |           }
 455 |         }
 456 |       }
 457 |     }
 458 |   }
 459 | 
 460 |   private async checkLinkValidity(
 461 |     filePath: string,
 462 |     content: string,
 463 |     result: ValidationResult,
 464 |   ): Promise<void> {
 465 |     const linkPattern = /\[([^\]]+)\]\(([^)]+)\)/g;
 466 |     const links: Array<{ text: string; url: string }> = [];
 467 |     let match;
 468 | 
 469 |     while ((match = linkPattern.exec(content)) !== null) {
 470 |       links.push({ text: match[1], url: match[2] });
 471 |     }
 472 | 
 473 |     for (const link of links) {
 474 |       // Check internal links
 475 |       if (!link.url.startsWith("http")) {
 476 |         const targetPath = path.resolve(path.dirname(filePath), link.url);
 477 |         try {
 478 |           await fs.access(targetPath);
 479 |         } catch {
 480 |           result.issues.push({
 481 |             type: "error",
 482 |             category: "accuracy",
 483 |             location: { file: path.basename(filePath) },
 484 |             description: `Broken internal link: ${link.url}`,
 485 |             evidence: [link.text],
 486 |             suggestedFix: "Fix the link path or create the missing file",
 487 |             confidence: 100,
 488 |           });
 489 |         }
 490 |       }
 491 | 
 492 |       // Flag external links for manual verification
 493 |       if (link.url.startsWith("http")) {
 494 |         result.uncertainties.push({
 495 |           area: "external-links",
 496 |           severity: "low",
 497 |           description: `External link: ${link.url}`,
 498 |           potentialImpact: "Link may become outdated or broken",
 499 |           clarificationNeeded: "Verify link is still valid",
 500 |           fallbackStrategy: "Archive important external content locally",
 501 |         });
 502 |       }
 503 |     }
 504 |   }
 505 | 
 506 |   private async validateCompleteness(
 507 |     contentPath: string,
 508 |     result: ValidationResult,
 509 |   ): Promise<void> {
 510 |     const files = await this.getMarkdownFiles(contentPath);
 511 |     const structure = await this.analyzeDiataxisStructure(contentPath);
 512 | 
 513 |     // Check for missing essential sections
 514 |     const requiredSections = [
 515 |       "tutorials",
 516 |       "how-to",
 517 |       "reference",
 518 |       "explanation",
 519 |     ];
 520 |     const missingSections = requiredSections.filter(
 521 |       (section) => !structure.sections.includes(section),
 522 |     );
 523 | 
 524 |     if (missingSections.length > 0) {
 525 |       result.issues.push({
 526 |         type: "warning",
 527 |         category: "completeness",
 528 |         location: { file: "documentation structure" },
 529 |         description: `Missing Diataxis sections: ${missingSections.join(", ")}`,
 530 |         evidence: structure.sections,
 531 |         suggestedFix:
 532 |           "Add missing Diataxis sections for complete documentation",
 533 |         confidence: 100,
 534 |       });
 535 |     }
 536 | 
 537 |     // Check content depth in each section
 538 |     for (const section of structure.sections) {
 539 |       const sectionFiles = files.filter((f) => f.includes(`/${section}/`));
 540 |       if (sectionFiles.length < 2) {
 541 |         result.issues.push({
 542 |           type: "info",
 543 |           category: "completeness",
 544 |           location: { file: section },
 545 |           description: `Limited content in ${section} section`,
 546 |           evidence: [`Only ${sectionFiles.length} files`],
 547 |           suggestedFix: "Consider adding more comprehensive coverage",
 548 |           confidence: 75,
 549 |         });
 550 |       }
 551 |     }
 552 | 
 553 |     // Update completeness confidence
 554 |     result.confidence.breakdown.businessContextAlignment = Math.max(
 555 |       0,
 556 |       100 - missingSections.length * 25,
 557 |     );
 558 |   }
 559 | 
 560 |   private async validateDiataxisCompliance(
 561 |     contentPath: string,
 562 |     result: ValidationResult,
 563 |   ): Promise<void> {
 564 |     const files = await this.getMarkdownFiles(contentPath);
 565 | 
 566 |     for (const file of files) {
 567 |       const content = await fs.readFile(file, "utf-8");
 568 |       const section = this.identifyDiataxisSection(file);
 569 | 
 570 |       if (section) {
 571 |         await this.checkSectionCompliance(file, content, section, result);
 572 |       }
 573 |     }
 574 |   }
 575 | 
 576 |   private async validateApplicationStructureCompliance(
 577 |     contentPath: string,
 578 |     result: ValidationResult,
 579 |   ): Promise<void> {
 580 |     // Analyze application source code for Diataxis compliance
 581 |     await this.validateSourceCodeDocumentation(contentPath, result);
 582 |     await this.validateApplicationArchitecture(contentPath, result);
 583 |     await this.validateInlineDocumentationPatterns(contentPath, result);
 584 |   }
 585 | 
 586 |   private async validateSourceCodeDocumentation(
 587 |     contentPath: string,
 588 |     result: ValidationResult,
 589 |   ): Promise<void> {
 590 |     const sourceFiles = await this.getSourceFiles(contentPath);
 591 | 
 592 |     for (const file of sourceFiles) {
 593 |       const content = await fs.readFile(file, "utf-8");
 594 | 
 595 |       // Check for proper JSDoc/TSDoc documentation
 596 |       await this.checkInlineDocumentationQuality(file, content, result);
 597 | 
 598 |       // Check for README files and their structure
 599 |       if (file.endsWith("README.md")) {
 600 |         await this.validateReadmeStructure(file, content, result);
 601 |       }
 602 | 
 603 |       // Check for proper module/class documentation
 604 |       await this.checkModuleDocumentation(file, content, result);
 605 |     }
 606 |   }
 607 | 
 608 |   private async validateApplicationArchitecture(
 609 |     contentPath: string,
 610 |     result: ValidationResult,
 611 |   ): Promise<void> {
 612 |     // Check if the application structure supports different types of documentation
 613 |     const hasToolsDir = await this.pathExists(path.join(contentPath, "tools"));
 614 |     const hasTypesDir = await this.pathExists(path.join(contentPath, "types"));
 615 |     // Check for workflows directory (currently not used but may be useful for future validation)
 616 |     // const hasWorkflowsDir = await this.pathExists(path.join(contentPath, 'workflows'));
 617 | 
 618 |     if (!hasToolsDir) {
 619 |       result.issues.push({
 620 |         type: "warning",
 621 |         category: "compliance",
 622 |         location: { file: "application structure" },
 623 |         description:
 624 |           "No dedicated tools directory found - may impact reference documentation organization",
 625 |         evidence: ["Missing /tools directory"],
 626 |         suggestedFix:
 627 |           "Organize tools into dedicated directory for better reference documentation",
 628 |         confidence: 80,
 629 |       });
 630 |     }
 631 | 
 632 |     if (!hasTypesDir) {
 633 |       result.issues.push({
 634 |         type: "info",
 635 |         category: "compliance",
 636 |         location: { file: "application structure" },
 637 |         description:
 638 |           "No types directory found - may impact API reference documentation",
 639 |         evidence: ["Missing /types directory"],
 640 |         suggestedFix: "Consider organizing types for better API documentation",
 641 |         confidence: 70,
 642 |       });
 643 |     }
 644 |   }
 645 | 
 646 |   private async validateInlineDocumentationPatterns(
 647 |     contentPath: string,
 648 |     result: ValidationResult,
 649 |   ): Promise<void> {
 650 |     const sourceFiles = await this.getSourceFiles(contentPath);
 651 | 
 652 |     for (const file of sourceFiles) {
 653 |       const content = await fs.readFile(file, "utf-8");
 654 | 
 655 |       // Check for proper function documentation that could support tutorials
 656 |       const functions = this.extractFunctions(content);
 657 |       for (const func of functions) {
 658 |         if (func.isExported && !func.hasDocumentation) {
 659 |           result.issues.push({
 660 |             type: "warning",
 661 |             category: "compliance",
 662 |             location: { file: path.basename(file), line: func.line },
 663 |             description: `Exported function '${func.name}' lacks documentation`,
 664 |             evidence: [func.signature],
 665 |             suggestedFix:
 666 |               "Add JSDoc/TSDoc documentation to support tutorial and reference content",
 667 |             confidence: 85,
 668 |           });
 669 |         }
 670 |       }
 671 | 
 672 |       // Check for proper error handling documentation
 673 |       const errorPatterns = content.match(/throw new \w*Error/g);
 674 |       if (errorPatterns && errorPatterns.length > 0) {
 675 |         const hasErrorDocs =
 676 |           content.includes("@throws") || content.includes("@error");
 677 |         if (!hasErrorDocs) {
 678 |           result.issues.push({
 679 |             type: "info",
 680 |             category: "compliance",
 681 |             location: { file: path.basename(file) },
 682 |             description:
 683 |               "Error throwing code found without error documentation",
 684 |             evidence: errorPatterns,
 685 |             suggestedFix:
 686 |               "Document error conditions to support troubleshooting guides",
 687 |             confidence: 75,
 688 |           });
 689 |         }
 690 |       }
 691 |     }
 692 |   }
 693 | 
 694 |   private identifyDiataxisSection(filePath: string): string | null {
 695 |     const sections = ["tutorials", "how-to", "reference", "explanation"];
 696 | 
 697 |     for (const section of sections) {
 698 |       if (filePath.includes(`/${section}/`)) {
 699 |         return section;
 700 |       }
 701 |     }
 702 | 
 703 |     return null;
 704 |   }
 705 | 
 706 |   private async checkSectionCompliance(
 707 |     filePath: string,
 708 |     content: string,
 709 |     section: string,
 710 |     result: ValidationResult,
 711 |   ): Promise<void> {
 712 |     const complianceRules = this.getDiataxisComplianceRules(section);
 713 | 
 714 |     for (const rule of complianceRules) {
 715 |       if (!rule.check(content)) {
 716 |         result.issues.push({
 717 |           type: "warning",
 718 |           category: "compliance",
 719 |           location: { file: path.basename(filePath), section },
 720 |           description: rule.message,
 721 |           evidence: [rule.evidence?.(content) || ""],
 722 |           suggestedFix: rule.fix,
 723 |           confidence: rule.confidence,
 724 |         });
 725 |       }
 726 |     }
 727 |   }
 728 | 
 729 |   private getDiataxisComplianceRules(section: string) {
 730 |     const rules: any = {
 731 |       tutorials: [
 732 |         {
 733 |           check: (content: string) =>
 734 |             content.includes("## Prerequisites") ||
 735 |             content.includes("## Requirements"),
 736 |           message: "Tutorial should include prerequisites section",
 737 |           fix: "Add a prerequisites or requirements section",
 738 |           confidence: 90,
 739 |         },
 740 |         {
 741 |           check: (content: string) => /step|Step|STEP/.test(content),
 742 |           message: "Tutorial should be organized in clear steps",
 743 |           fix: "Structure content with numbered steps or clear progression",
 744 |           confidence: 85,
 745 |         },
 746 |         {
 747 |           check: (content: string) => content.includes("```"),
 748 |           message: "Tutorial should include practical code examples",
 749 |           fix: "Add code blocks with working examples",
 750 |           confidence: 80,
 751 |         },
 752 |       ],
 753 |       "how-to": [
 754 |         {
 755 |           check: (content: string) => /how to|How to|HOW TO/.test(content),
 756 |           message: "How-to guide should focus on specific tasks",
 757 |           fix: "Frame content around achieving specific goals",
 758 |           confidence: 75,
 759 |         },
 760 |         {
 761 |           check: (content: string) => content.length > 500,
 762 |           message: "How-to guide should provide detailed guidance",
 763 |           fix: "Expand with more detailed instructions",
 764 |           confidence: 70,
 765 |         },
 766 |       ],
 767 |       reference: [
 768 |         {
 769 |           check: (content: string) => /##|###/.test(content),
 770 |           message: "Reference should be well-structured with clear sections",
 771 |           fix: "Add proper headings and organization",
 772 |           confidence: 95,
 773 |         },
 774 |         {
 775 |           check: (content: string) => /\|.*\|/.test(content),
 776 |           message: "Reference should include tables for structured information",
 777 |           fix: "Consider using tables for parameters, options, etc.",
 778 |           confidence: 60,
 779 |         },
 780 |       ],
 781 |       explanation: [
 782 |         {
 783 |           check: (content: string) =>
 784 |             content.includes("why") || content.includes("Why"),
 785 |           message: 'Explanation should address the "why" behind concepts',
 786 |           fix: "Include rationale and context for decisions/concepts",
 787 |           confidence: 80,
 788 |         },
 789 |         {
 790 |           check: (content: string) => content.length > 800,
 791 |           message: "Explanation should provide in-depth coverage",
 792 |           fix: "Expand with more comprehensive explanation",
 793 |           confidence: 70,
 794 |         },
 795 |       ],
 796 |     };
 797 | 
 798 |     return rules[section] || [];
 799 |   }
 800 | 
 801 |   private async validateCodeExamples(
 802 |     contentPath: string,
 803 |   ): Promise<CodeValidationResult> {
 804 |     const files = await this.getMarkdownFiles(contentPath);
 805 |     const allExamples: ExampleValidation[] = [];
 806 | 
 807 |     for (const file of files) {
 808 |       const content = await fs.readFile(file, "utf-8");
 809 |       const codeBlocks = this.extractCodeBlocks(content);
 810 | 
 811 |       for (const block of codeBlocks) {
 812 |         if (this.isValidatableLanguage(block.language)) {
 813 |           const validation = await this.validateCodeBlock(block, file);
 814 |           allExamples.push(validation);
 815 |         }
 816 |       }
 817 |     }
 818 | 
 819 |     return {
 820 |       overallSuccess: allExamples.every((e) => e.compilationSuccess),
 821 |       exampleResults: allExamples,
 822 |       confidence: this.calculateCodeValidationConfidence(allExamples),
 823 |     };
 824 |   }
 825 | 
 826 |   private extractCodeBlocks(
 827 |     content: string,
 828 |   ): Array<{ language: string; code: string; id: string }> {
 829 |     const codeBlockPattern = /```(\w+)?\n([\s\S]*?)```/g;
 830 |     const blocks: Array<{ language: string; code: string; id: string }> = [];
 831 |     let match;
 832 |     let index = 0;
 833 | 
 834 |     while ((match = codeBlockPattern.exec(content)) !== null) {
 835 |       blocks.push({
 836 |         language: match[1] || "text",
 837 |         code: match[2].trim(),
 838 |         id: `block-${index++}`,
 839 |       });
 840 |     }
 841 | 
 842 |     return blocks;
 843 |   }
 844 | 
 845 |   private isValidatableLanguage(language: string): boolean {
 846 |     const validatable = [
 847 |       "javascript",
 848 |       "typescript",
 849 |       "js",
 850 |       "ts",
 851 |       "json",
 852 |       "bash",
 853 |       "sh",
 854 |     ];
 855 |     return validatable.includes(language.toLowerCase());
 856 |   }
 857 | 
 858 |   private async validateCodeBlock(
 859 |     block: { language: string; code: string; id: string },
 860 |     filePath: string,
 861 |   ): Promise<ExampleValidation> {
 862 |     const validation: ExampleValidation = {
 863 |       example: block.id,
 864 |       compilationSuccess: false,
 865 |       executionSuccess: false,
 866 |       issues: [],
 867 |       confidence: 0,
 868 |     };
 869 | 
 870 |     try {
 871 |       if (block.language === "typescript" || block.language === "ts") {
 872 |         await this.validateTypeScriptCode(block.code, validation);
 873 |       } else if (block.language === "javascript" || block.language === "js") {
 874 |         await this.validateJavaScriptCode(block.code, validation);
 875 |       } else if (block.language === "json") {
 876 |         await this.validateJSONCode(block.code, validation);
 877 |       } else if (block.language === "bash" || block.language === "sh") {
 878 |         await this.validateBashCode(block.code, validation);
 879 |       }
 880 |     } catch (error: any) {
 881 |       validation.issues.push({
 882 |         type: "error",
 883 |         category: "accuracy",
 884 |         location: { file: path.basename(filePath) },
 885 |         description: `Code validation failed: ${error.message}`,
 886 |         evidence: [block.code.substring(0, 100)],
 887 |         suggestedFix: "Review and fix syntax errors",
 888 |         confidence: 95,
 889 |       });
 890 |     }
 891 | 
 892 |     return validation;
 893 |   }
 894 | 
 895 |   private async validateTypeScriptCode(
 896 |     code: string,
 897 |     validation: ExampleValidation,
 898 |   ): Promise<void> {
 899 |     // Ensure temp directory exists
 900 |     await fs.mkdir(this.tempDir, { recursive: true });
 901 | 
 902 |     const tempFile = path.join(this.tempDir, `temp-${Date.now()}.ts`);
 903 | 
 904 |     try {
 905 |       // Write code to temporary file
 906 |       await fs.writeFile(tempFile, code, "utf-8");
 907 | 
 908 |       // Try to compile with TypeScript
 909 |       const { stderr } = await execAsync(
 910 |         `npx tsc --noEmit --skipLibCheck ${tempFile}`,
 911 |       );
 912 | 
 913 |       if (stderr && stderr.includes("error")) {
 914 |         validation.issues.push({
 915 |           type: "error",
 916 |           category: "accuracy",
 917 |           location: { file: "code-example" },
 918 |           description: "TypeScript compilation error",
 919 |           evidence: [stderr],
 920 |           suggestedFix: "Fix TypeScript syntax and type errors",
 921 |           confidence: 90,
 922 |         });
 923 |       } else {
 924 |         validation.compilationSuccess = true;
 925 |         validation.confidence = 85;
 926 |       }
 927 |     } catch (error: any) {
 928 |       if (error.stderr && error.stderr.includes("error")) {
 929 |         validation.issues.push({
 930 |           type: "error",
 931 |           category: "accuracy",
 932 |           location: { file: "code-example" },
 933 |           description: "TypeScript compilation failed",
 934 |           evidence: [error.stderr],
 935 |           suggestedFix: "Fix compilation errors",
 936 |           confidence: 95,
 937 |         });
 938 |       }
 939 |     } finally {
 940 |       // Clean up temp file
 941 |       try {
 942 |         await fs.unlink(tempFile);
 943 |       } catch {
 944 |         // Ignore cleanup errors
 945 |       }
 946 |     }
 947 |   }
 948 | 
 949 |   private async validateJavaScriptCode(
 950 |     code: string,
 951 |     validation: ExampleValidation,
 952 |   ): Promise<void> {
 953 |     try {
 954 |       // Basic syntax check using Node.js
 955 |       new Function(code);
 956 |       validation.compilationSuccess = true;
 957 |       validation.confidence = 75;
 958 |     } catch (error: any) {
 959 |       validation.issues.push({
 960 |         type: "error",
 961 |         category: "accuracy",
 962 |         location: { file: "code-example" },
 963 |         description: `JavaScript syntax error: ${error.message}`,
 964 |         evidence: [code.substring(0, 100)],
 965 |         suggestedFix: "Fix JavaScript syntax errors",
 966 |         confidence: 90,
 967 |       });
 968 |     }
 969 |   }
 970 | 
 971 |   private async validateJSONCode(
 972 |     code: string,
 973 |     validation: ExampleValidation,
 974 |   ): Promise<void> {
 975 |     try {
 976 |       JSON.parse(code);
 977 |       validation.compilationSuccess = true;
 978 |       validation.confidence = 95;
 979 |     } catch (error: any) {
 980 |       validation.issues.push({
 981 |         type: "error",
 982 |         category: "accuracy",
 983 |         location: { file: "code-example" },
 984 |         description: `Invalid JSON: ${error.message}`,
 985 |         evidence: [code.substring(0, 100)],
 986 |         suggestedFix: "Fix JSON syntax errors",
 987 |         confidence: 100,
 988 |       });
 989 |     }
 990 |   }
 991 | 
 992 |   private async validateBashCode(
 993 |     code: string,
 994 |     validation: ExampleValidation,
 995 |   ): Promise<void> {
 996 |     // Basic bash syntax validation
 997 |     const lines = code
 998 |       .split("\n")
 999 |       .filter((line) => line.trim() && !line.startsWith("#"));
1000 | 
1001 |     for (const line of lines) {
1002 |       // Check for basic syntax issues
1003 |       if (line.includes("&&") && line.includes("||")) {
1004 |         validation.issues.push({
1005 |           type: "warning",
1006 |           category: "accuracy",
1007 |           location: { file: "code-example" },
1008 |           description: "Complex command chaining may be confusing",
1009 |           evidence: [line],
1010 |           suggestedFix:
1011 |             "Consider breaking into separate commands or adding explanation",
1012 |           confidence: 60,
1013 |         });
1014 |       }
1015 | 
1016 |       // Check for unquoted variables in dangerous contexts
1017 |       if (line.includes("rm") && /\$\w+/.test(line) && !/'.*\$.*'/.test(line)) {
1018 |         validation.issues.push({
1019 |           type: "warning",
1020 |           category: "accuracy",
1021 |           location: { file: "code-example" },
1022 |           description: "Unquoted variable in potentially dangerous command",
1023 |           evidence: [line],
1024 |           suggestedFix: "Quote variables to prevent word splitting",
1025 |           confidence: 80,
1026 |         });
1027 |       }
1028 |     }
1029 | 
1030 |     validation.compilationSuccess =
1031 |       validation.issues.filter((i) => i.type === "error").length === 0;
1032 |     validation.confidence = validation.compilationSuccess ? 70 : 20;
1033 |   }
1034 | 
1035 |   private calculateCodeValidationConfidence(
1036 |     examples: ExampleValidation[],
1037 |   ): number {
1038 |     if (examples.length === 0) return 0;
1039 | 
1040 |     const totalConfidence = examples.reduce(
1041 |       (sum, ex) => sum + ex.confidence,
1042 |       0,
1043 |     );
1044 |     return Math.round(totalConfidence / examples.length);
1045 |   }
1046 | 
1047 |   public async getMarkdownFiles(
1048 |     contentPath: string,
1049 |     maxDepth: number = 5,
1050 |   ): Promise<string[]> {
1051 |     const files: string[] = [];
1052 |     const excludedDirs = new Set([
1053 |       "node_modules",
1054 |       ".git",
1055 |       "dist",
1056 |       "build",
1057 |       ".next",
1058 |       ".nuxt",
1059 |       "coverage",
1060 |       ".tmp",
1061 |       "tmp",
1062 |       ".cache",
1063 |       ".vscode",
1064 |       ".idea",
1065 |       "logs",
1066 |       ".logs",
1067 |       ".npm",
1068 |       ".yarn",
1069 |     ]);
1070 | 
1071 |     const scan = async (
1072 |       dir: string,
1073 |       currentDepth: number = 0,
1074 |     ): Promise<void> => {
1075 |       if (currentDepth > maxDepth) return;
1076 | 
1077 |       try {
1078 |         const entries = await fs.readdir(dir, { withFileTypes: true });
1079 | 
1080 |         for (const entry of entries) {
1081 |           const fullPath = path.join(dir, entry.name);
1082 | 
1083 |           if (entry.isDirectory()) {
1084 |             // Skip excluded directories
1085 |             if (excludedDirs.has(entry.name) || entry.name.startsWith(".")) {
1086 |               continue;
1087 |             }
1088 | 
1089 |             // Prevent symlink loops
1090 |             try {
1091 |               const stats = await fs.lstat(fullPath);
1092 |               if (stats.isSymbolicLink()) {
1093 |                 continue;
1094 |               }
1095 |             } catch {
1096 |               continue;
1097 |             }
1098 | 
1099 |             await scan(fullPath, currentDepth + 1);
1100 |           } else if (entry.name.endsWith(".md")) {
1101 |             files.push(fullPath);
1102 | 
1103 |             // Limit total files to prevent memory issues
1104 |             if (files.length > 500) {
1105 |               console.warn("Markdown file limit reached (500), stopping scan");
1106 |               return;
1107 |             }
1108 |           }
1109 |         }
1110 |       } catch (error) {
1111 |         // Skip directories that can't be read
1112 |         console.warn(`Warning: Could not read directory ${dir}:`, error);
1113 |       }
1114 |     };
1115 | 
1116 |     try {
1117 |       await scan(contentPath);
1118 |     } catch (error) {
1119 |       console.warn("Error scanning directory:", error);
1120 |     }
1121 | 
1122 |     return files;
1123 |   }
1124 | 
1125 |   private async getSourceFiles(
1126 |     contentPath: string,
1127 |     maxDepth: number = 5,
1128 |   ): Promise<string[]> {
1129 |     const files: string[] = [];
1130 |     const excludedDirs = new Set([
1131 |       "node_modules",
1132 |       ".git",
1133 |       "dist",
1134 |       "build",
1135 |       ".next",
1136 |       ".nuxt",
1137 |       "coverage",
1138 |       ".tmp",
1139 |       "tmp",
1140 |       ".cache",
1141 |       ".vscode",
1142 |       ".idea",
1143 |       "logs",
1144 |       ".logs",
1145 |       ".npm",
1146 |       ".yarn",
1147 |     ]);
1148 | 
1149 |     const scan = async (
1150 |       dir: string,
1151 |       currentDepth: number = 0,
1152 |     ): Promise<void> => {
1153 |       if (currentDepth > maxDepth) return;
1154 | 
1155 |       try {
1156 |         const entries = await fs.readdir(dir, { withFileTypes: true });
1157 | 
1158 |         for (const entry of entries) {
1159 |           const fullPath = path.join(dir, entry.name);
1160 | 
1161 |           if (entry.isDirectory()) {
1162 |             // Skip excluded directories
1163 |             if (excludedDirs.has(entry.name) || entry.name.startsWith(".")) {
1164 |               continue;
1165 |             }
1166 | 
1167 |             // Prevent symlink loops
1168 |             try {
1169 |               const stats = await fs.lstat(fullPath);
1170 |               if (stats.isSymbolicLink()) {
1171 |                 continue;
1172 |               }
1173 |             } catch {
1174 |               continue;
1175 |             }
1176 | 
1177 |             await scan(fullPath, currentDepth + 1);
1178 |           } else if (
1179 |             entry.name.endsWith(".ts") ||
1180 |             entry.name.endsWith(".js") ||
1181 |             entry.name.endsWith(".md")
1182 |           ) {
1183 |             files.push(fullPath);
1184 | 
1185 |             // Limit total files to prevent memory issues
1186 |             if (files.length > 1000) {
1187 |               console.warn("File limit reached (1000), stopping scan");
1188 |               return;
1189 |             }
1190 |           }
1191 |         }
1192 |       } catch (error) {
1193 |         // Skip directories that can't be read
1194 |         console.warn(`Warning: Could not read directory ${dir}:`, error);
1195 |       }
1196 |     };
1197 | 
1198 |     try {
1199 |       await scan(contentPath);
1200 |     } catch (error) {
1201 |       console.warn("Error scanning directory:", error);
1202 |     }
1203 | 
1204 |     return files;
1205 |   }
1206 | 
1207 |   private async pathExists(filePath: string): Promise<boolean> {
1208 |     try {
1209 |       await fs.access(filePath);
1210 |       return true;
1211 |     } catch {
1212 |       return false;
1213 |     }
1214 |   }
1215 | 
1216 |   private extractFunctions(content: string): Array<{
1217 |     name: string;
1218 |     line: number;
1219 |     signature: string;
1220 |     isExported: boolean;
1221 |     hasDocumentation: boolean;
1222 |   }> {
1223 |     const functions: Array<{
1224 |       name: string;
1225 |       line: number;
1226 |       signature: string;
1227 |       isExported: boolean;
1228 |       hasDocumentation: boolean;
1229 |     }> = [];
1230 |     const lines = content.split("\n");
1231 | 
1232 |     for (let i = 0; i < lines.length; i++) {
1233 |       const line = lines[i];
1234 | 
1235 |       // Match function declarations and exports
1236 |       const functionMatch = line.match(
1237 |         /^(export\s+)?(async\s+)?function\s+(\w+)/,
1238 |       );
1239 |       const arrowMatch = line.match(
1240 |         /^(export\s+)?(?:const|let|var)\s+(\w+)\s*=\s*(async\s+)?\(/,
1241 |       );
1242 | 
1243 |       if (functionMatch) {
1244 |         const name = functionMatch[3];
1245 |         const isExported = !!functionMatch[1];
1246 |         const hasDocumentation = this.checkForDocumentation(lines, i);
1247 | 
1248 |         functions.push({
1249 |           name,
1250 |           line: i + 1,
1251 |           signature: line.trim(),
1252 |           isExported,
1253 |           hasDocumentation,
1254 |         });
1255 |       } else if (arrowMatch) {
1256 |         const name = arrowMatch[2];
1257 |         const isExported = !!arrowMatch[1];
1258 |         const hasDocumentation = this.checkForDocumentation(lines, i);
1259 | 
1260 |         functions.push({
1261 |           name,
1262 |           line: i + 1,
1263 |           signature: line.trim(),
1264 |           isExported,
1265 |           hasDocumentation,
1266 |         });
1267 |       }
1268 |     }
1269 | 
1270 |     return functions;
1271 |   }
1272 | 
1273 |   private async checkInlineDocumentationQuality(
1274 |     _file: string,
1275 |     _content: string,
1276 |     _result: ValidationResult,
1277 |   ): Promise<void> {
1278 |     // Implementation for checking JSDoc/TSDoc quality
1279 |     // This could check for proper parameter documentation, return types, etc.
1280 |   }
1281 | 
1282 |   private async validateReadmeStructure(
1283 |     _file: string,
1284 |     content: string,
1285 |     result: ValidationResult,
1286 |   ): Promise<void> {
1287 |     // Check if README follows good structure
1288 |     const hasTitle = /^#\s+/.test(content);
1289 |     const hasDescription =
1290 |       content.includes("## Description") || content.includes("## Overview");
1291 |     const hasInstallation =
1292 |       content.includes("## Installation") || content.includes("## Setup");
1293 |     const hasUsage =
1294 |       content.includes("## Usage") || content.includes("## Getting Started");
1295 | 
1296 |     if (!hasTitle) {
1297 |       result.issues.push({
1298 |         type: "warning",
1299 |         category: "compliance",
1300 |         location: { file: "README.md" },
1301 |         description: "README missing clear title",
1302 |         evidence: ["No H1 heading found"],
1303 |         suggestedFix: "Add clear title with # heading",
1304 |         confidence: 90,
1305 |       });
1306 |     }
1307 | 
1308 |     if (!hasDescription && !hasInstallation && !hasUsage) {
1309 |       result.issues.push({
1310 |         type: "warning",
1311 |         category: "compliance",
1312 |         location: { file: "README.md" },
1313 |         description:
1314 |           "README lacks essential sections (description, installation, usage)",
1315 |         evidence: ["Missing standard README sections"],
1316 |         suggestedFix:
1317 |           "Add sections for description, installation, and usage following Diataxis principles",
1318 |         confidence: 85,
1319 |       });
1320 |     }
1321 |   }
1322 | 
1323 |   private async checkModuleDocumentation(
1324 |     _file: string,
1325 |     _content: string,
1326 |     _result: ValidationResult,
1327 |   ): Promise<void> {
1328 |     // Implementation for checking module-level documentation
1329 |     // This could check for file-level JSDoc, proper exports documentation, etc.
1330 |   }
1331 | 
1332 |   private checkForDocumentation(
1333 |     lines: string[],
1334 |     functionLineIndex: number,
1335 |   ): boolean {
1336 |     // Look backwards from the function line to find documentation
1337 |     let checkIndex = functionLineIndex - 1;
1338 | 
1339 |     // Skip empty lines
1340 |     while (checkIndex >= 0 && lines[checkIndex].trim() === "") {
1341 |       checkIndex--;
1342 |     }
1343 | 
1344 |     // Check if we found the end of a JSDoc comment
1345 |     if (checkIndex >= 0 && lines[checkIndex].trim() === "*/") {
1346 |       // Look backwards to find the start of the JSDoc block
1347 |       let jsDocStart = checkIndex;
1348 |       while (jsDocStart >= 0) {
1349 |         const line = lines[jsDocStart].trim();
1350 |         if (line.startsWith("/**")) {
1351 |           return true; // Found complete JSDoc block
1352 |         }
1353 |         if (!line.startsWith("*") && line !== "*/") {
1354 |           break; // Not part of JSDoc block
1355 |         }
1356 |         jsDocStart--;
1357 |       }
1358 |     }
1359 | 
1360 |     // Also check for single-line JSDoc comments
1361 |     if (
1362 |       checkIndex >= 0 &&
1363 |       lines[checkIndex].trim().startsWith("/**") &&
1364 |       lines[checkIndex].includes("*/")
1365 |     ) {
1366 |       return true;
1367 |     }
1368 | 
1369 |     return false;
1370 |   }
1371 | 
1372 |   private async shouldAnalyzeApplicationCode(
1373 |     contentPath: string,
1374 |   ): Promise<boolean> {
1375 |     // Check if the path contains application source code vs documentation
1376 |     const hasSrcDir = await this.pathExists(path.join(contentPath, "src"));
1377 |     const hasPackageJson = await this.pathExists(
1378 |       path.join(contentPath, "package.json"),
1379 |     );
1380 |     const hasTypescriptFiles = (await this.getSourceFiles(contentPath)).some(
1381 |       (file) => file.endsWith(".ts"),
1382 |     );
1383 | 
1384 |     // If path ends with 'src' or is a project root with src/, analyze as application code
1385 |     if (
1386 |       contentPath.endsWith("/src") ||
1387 |       contentPath.endsWith("\\src") ||
1388 |       (hasSrcDir && hasPackageJson)
1389 |     ) {
1390 |       return true;
1391 |     }
1392 | 
1393 |     // If path contains TypeScript/JavaScript files and package.json, treat as application code
1394 |     if (hasTypescriptFiles && hasPackageJson) {
1395 |       return true;
1396 |     }
1397 | 
1398 |     // If path is specifically a documentation directory, analyze as documentation
1399 |     if (contentPath.includes("/docs") || contentPath.includes("\\docs")) {
1400 |       return false;
1401 |     }
1402 | 
1403 |     return false;
1404 |   }
1405 | 
1406 |   private async analyzeDiataxisStructure(
1407 |     contentPath: string,
1408 |   ): Promise<{ sections: string[] }> {
1409 |     const sections: string[] = [];
1410 | 
1411 |     try {
1412 |       const entries = await fs.readdir(contentPath, { withFileTypes: true });
1413 | 
1414 |       for (const entry of entries) {
1415 |         if (entry.isDirectory()) {
1416 |           const dirName = entry.name;
1417 |           if (
1418 |             ["tutorials", "how-to", "reference", "explanation"].includes(
1419 |               dirName,
1420 |             )
1421 |           ) {
1422 |             sections.push(dirName);
1423 |           }
1424 |         }
1425 |       }
1426 |     } catch {
1427 |       // Directory doesn't exist
1428 |     }
1429 | 
1430 |     return { sections };
1431 |   }
1432 | 
1433 |   private updateAccuracyConfidence(result: ValidationResult): void {
1434 |     const errorCount = result.issues.filter((i) => i.type === "error").length;
1435 |     const warningCount = result.issues.filter(
1436 |       (i) => i.type === "warning",
1437 |     ).length;
1438 | 
1439 |     // Base confidence starts high and decreases with issues
1440 |     let confidence = 95;
1441 |     confidence -= errorCount * 20;
1442 |     confidence -= warningCount * 5;
1443 |     confidence = Math.max(0, confidence);
1444 | 
1445 |     result.confidence.breakdown.technologyDetection = confidence;
1446 |   }
1447 | 
1448 |   private calculateOverallMetrics(result: ValidationResult): void {
1449 |     const breakdown = result.confidence.breakdown;
1450 |     const values = Object.values(breakdown).filter((v) => v > 0);
1451 | 
1452 |     if (values.length > 0) {
1453 |       result.confidence.overall = Math.round(
1454 |         values.reduce((a, b) => a + b, 0) / values.length,
1455 |       );
1456 |     }
1457 | 
1458 |     // Determine overall success
1459 |     const criticalIssues = result.issues.filter(
1460 |       (i) => i.type === "error",
1461 |     ).length;
1462 |     result.success = criticalIssues === 0;
1463 | 
1464 |     // Add risk factors based on issues
1465 |     if (criticalIssues > 0) {
1466 |       result.confidence.riskFactors.push({
1467 |         type: "high",
1468 |         category: "accuracy",
1469 |         description: `${criticalIssues} critical accuracy issues found`,
1470 |         impact: "Users may encounter broken examples or incorrect information",
1471 |         mitigation: "Fix all critical issues before publication",
1472 |       });
1473 |     }
1474 | 
1475 |     const uncertaintyCount = result.uncertainties.length;
1476 |     if (uncertaintyCount > 5) {
1477 |       result.confidence.riskFactors.push({
1478 |         type: "medium",
1479 |         category: "completeness",
1480 |         description: `${uncertaintyCount} areas requiring clarification`,
1481 |         impact: "Documentation may lack specificity for user context",
1482 |         mitigation: "Address high-priority uncertainties with user input",
1483 |       });
1484 |     }
1485 |   }
1486 | 
1487 |   private generateRecommendations(
1488 |     result: ValidationResult,
1489 |     _options: ValidationOptions,
1490 |   ): void {
1491 |     const recommendations: string[] = [];
1492 |     const nextSteps: string[] = [];
1493 | 
1494 |     // Generate recommendations based on issues found
1495 |     const errorCount = result.issues.filter((i) => i.type === "error").length;
1496 |     if (errorCount > 0) {
1497 |       recommendations.push(
1498 |         `Fix ${errorCount} critical accuracy issues before publication`,
1499 |       );
1500 |       nextSteps.push("Review and resolve all error-level validation issues");
1501 |     }
1502 | 
1503 |     const warningCount = result.issues.filter(
1504 |       (i) => i.type === "warning",
1505 |     ).length;
1506 |     if (warningCount > 0) {
1507 |       recommendations.push(
1508 |         `Address ${warningCount} potential accuracy concerns`,
1509 |       );
1510 |       nextSteps.push(
1511 |         "Review warning-level issues and apply fixes where appropriate",
1512 |       );
1513 |     }
1514 | 
1515 |     const uncertaintyCount = result.uncertainties.filter(
1516 |       (u) => u.severity === "high" || u.severity === "critical",
1517 |     ).length;
1518 |     if (uncertaintyCount > 0) {
1519 |       recommendations.push(
1520 |         `Clarify ${uncertaintyCount} high-uncertainty areas`,
1521 |       );
1522 |       nextSteps.push("Gather user input on areas flagged for clarification");
1523 |     }
1524 | 
1525 |     // Code validation recommendations
1526 |     if (result.codeValidation && !result.codeValidation.overallSuccess) {
1527 |       recommendations.push(
1528 |         "Fix code examples that fail compilation or execution tests",
1529 |       );
1530 |       nextSteps.push(
1531 |         "Test all code examples in appropriate development environment",
1532 |       );
1533 |     }
1534 | 
1535 |     // Completeness recommendations
1536 |     const missingCompliance = result.issues.filter(
1537 |       (i) => i.category === "compliance",
1538 |     ).length;
1539 |     if (missingCompliance > 0) {
1540 |       recommendations.push(
1541 |         "Improve Diataxis framework compliance for better user experience",
1542 |       );
1543 |       nextSteps.push(
1544 |         "Restructure content to better align with Diataxis principles",
1545 |       );
1546 |     }
1547 | 
1548 |     // General recommendations based on confidence level
1549 |     if (result.confidence.overall < 70) {
1550 |       recommendations.push(
1551 |         "Overall confidence is below recommended threshold - consider comprehensive review",
1552 |       );
1553 |       nextSteps.push(
1554 |         "Conduct manual review of generated content before publication",
1555 |       );
1556 |     }
1557 | 
1558 |     if (recommendations.length === 0) {
1559 |       recommendations.push("Content validation passed - ready for publication");
1560 |       nextSteps.push("Deploy documentation and monitor for user feedback");
1561 |     }
1562 | 
1563 |     result.recommendations = recommendations;
1564 |     result.nextSteps = nextSteps;
1565 |   }
1566 | }
1567 | 
1568 | export const validateDiataxisContent: Tool = {
1569 |   name: "validate_diataxis_content",
1570 |   description:
1571 |     "Validate the accuracy, completeness, and compliance of generated Diataxis documentation",
1572 |   inputSchema: {
1573 |     type: "object",
1574 |     properties: {
1575 |       contentPath: {
1576 |         type: "string",
1577 |         description: "Path to the documentation directory to validate",
1578 |       },
1579 |       analysisId: {
1580 |         type: "string",
1581 |         description:
1582 |           "Optional repository analysis ID for context-aware validation",
1583 |       },
1584 |       validationType: {
1585 |         type: "string",
1586 |         enum: ["accuracy", "completeness", "compliance", "all"],
1587 |         default: "all",
1588 |         description: "Type of validation to perform",
1589 |       },
1590 |       includeCodeValidation: {
1591 |         type: "boolean",
1592 |         default: true,
1593 |         description: "Whether to validate code examples for correctness",
1594 |       },
1595 |       confidence: {
1596 |         type: "string",
1597 |         enum: ["strict", "moderate", "permissive"],
1598 |         default: "moderate",
1599 |         description:
1600 |           "Validation confidence level - stricter levels catch more issues",
1601 |       },
1602 |     },
1603 |     required: ["contentPath"],
1604 |   },
1605 | };
1606 | 
1607 | /**
1608 |  * Validates Diataxis-compliant documentation content for accuracy, completeness, and compliance.
1609 |  *
1610 |  * Performs comprehensive validation of documentation content including accuracy verification,
1611 |  * completeness assessment, compliance checking, and code example validation. Uses advanced
1612 |  * confidence scoring and risk assessment to provide detailed validation results with
1613 |  * actionable recommendations.
1614 |  *
1615 |  * @param args - The validation parameters
1616 |  * @param args.contentPath - Path to the documentation content directory
1617 |  * @param args.analysisId - Optional repository analysis ID for context-aware validation
1618 |  * @param args.validationType - Type of validation to perform: "accuracy", "completeness", "compliance", or "all"
1619 |  * @param args.includeCodeValidation - Whether to validate code examples and syntax
1620 |  * @param args.confidence - Validation confidence level: "strict", "moderate", or "permissive"
1621 |  *
1622 |  * @returns Promise resolving to comprehensive validation results
1623 |  * @returns success - Whether validation passed overall
1624 |  * @returns confidence - Confidence metrics and risk assessment
1625 |  * @returns issues - Array of validation issues found
1626 |  * @returns uncertainties - Areas requiring clarification
1627 |  * @returns codeValidation - Code example validation results
1628 |  * @returns recommendations - Suggested improvements
1629 |  * @returns nextSteps - Recommended next actions
1630 |  *
1631 |  * @throws {Error} When content path is inaccessible
1632 |  * @throws {Error} When validation processing fails
1633 |  *
1634 |  * @example
1635 |  * ```typescript
1636 |  * // Comprehensive validation
1637 |  * const result = await handleValidateDiataxisContent({
1638 |  *   contentPath: "./docs",
1639 |  *   validationType: "all",
1640 |  *   includeCodeValidation: true,
1641 |  *   confidence: "moderate"
1642 |  * });
1643 |  *
1644 |  * console.log(`Validation success: ${result.success}`);
1645 |  * console.log(`Overall confidence: ${result.confidence.overall}%`);
1646 |  * console.log(`Issues found: ${result.issues.length}`);
1647 |  *
1648 |  * // Strict accuracy validation
1649 |  * const accuracy = await handleValidateDiataxisContent({
1650 |  *   contentPath: "./docs",
1651 |  *   validationType: "accuracy",
1652 |  *   confidence: "strict"
1653 |  * });
1654 |  * ```
1655 |  *
1656 |  * @since 1.0.0
1657 |  */
1658 | export async function handleValidateDiataxisContent(
1659 |   args: any,
1660 |   context?: any,
1661 | ): Promise<ValidationResult> {
1662 |   await context?.info?.("🔍 Starting Diataxis content validation...");
1663 | 
1664 |   const validator = new ContentAccuracyValidator();
1665 | 
1666 |   // Add timeout protection to prevent infinite hangs
1667 |   const timeoutMs = 120000; // 2 minutes
1668 |   let timeoutHandle: NodeJS.Timeout;
1669 |   const timeoutPromise = new Promise<ValidationResult>((_, reject) => {
1670 |     timeoutHandle = setTimeout(() => {
1671 |       reject(
1672 |         new Error(
1673 |           `Validation timed out after ${
1674 |             timeoutMs / 1000
1675 |           } seconds. This may be due to a large directory structure. Try validating a smaller subset or specific directory.`,
1676 |         ),
1677 |       );
1678 |     }, timeoutMs);
1679 |   });
1680 | 
1681 |   const validationPromise = validator.validateContent(args, context);
1682 | 
1683 |   try {
1684 |     const result = await Promise.race([validationPromise, timeoutPromise]);
1685 |     clearTimeout(timeoutHandle!);
1686 |     return result;
1687 |   } catch (error: any) {
1688 |     clearTimeout(timeoutHandle!);
1689 |     // Return a partial result with error information
1690 |     return {
1691 |       success: false,
1692 |       confidence: {
1693 |         overall: 0,
1694 |         breakdown: {
1695 |           technologyDetection: 0,
1696 |           frameworkVersionAccuracy: 0,
1697 |           codeExampleRelevance: 0,
1698 |           architecturalAssumptions: 0,
1699 |           businessContextAlignment: 0,
1700 |         },
1701 |         riskFactors: [
1702 |           {
1703 |             type: "high",
1704 |             category: "validation",
1705 |             description: "Validation process failed or timed out",
1706 |             impact: "Unable to complete content validation",
1707 |             mitigation:
1708 |               "Try validating a smaller directory or specific subset of files",
1709 |           },
1710 |         ],
1711 |       },
1712 |       issues: [],
1713 |       uncertainties: [],
1714 |       recommendations: [
1715 |         "Validation failed or timed out",
1716 |         "Consider validating smaller directory subsets",
1717 |         "Check for very large files or deep directory structures",
1718 |         `Error: ${error.message}`,
1719 |       ],
1720 |       nextSteps: [
1721 |         "Verify the content path is correct and accessible",
1722 |         "Try validating specific subdirectories instead of the entire project",
1723 |         "Check for circular symlinks or very deep directory structures",
1724 |       ],
1725 |     };
1726 |   }
1727 | }
1728 | 
1729 | interface GeneralValidationResult {
1730 |   success: boolean;
1731 |   linksChecked: number;
1732 |   brokenLinks: string[];
1733 |   codeBlocksValidated: number;
1734 |   codeErrors: string[];
1735 |   recommendations: string[];
1736 |   summary: string;
1737 | }
1738 | 
1739 | export async function validateGeneralContent(
1740 |   args: any,
1741 | ): Promise<GeneralValidationResult> {
1742 |   const {
1743 |     contentPath,
1744 |     validationType = "all",
1745 |     includeCodeValidation = true,
1746 |     followExternalLinks = false,
1747 |   } = args;
1748 | 
1749 |   const result: GeneralValidationResult = {
1750 |     success: true,
1751 |     linksChecked: 0,
1752 |     brokenLinks: [],
1753 |     codeBlocksValidated: 0,
1754 |     codeErrors: [],
1755 |     recommendations: [],
1756 |     summary: "",
1757 |   };
1758 | 
1759 |   try {
1760 |     // Get all markdown files
1761 |     const validator = new ContentAccuracyValidator();
1762 |     const files = await validator.getMarkdownFiles(contentPath);
1763 | 
1764 |     // Check links if requested
1765 |     if (validationType === "all" || validationType === "links") {
1766 |       for (const file of files) {
1767 |         const content = await fs.readFile(file, "utf-8");
1768 |         const links = extractLinksFromMarkdown(content);
1769 | 
1770 |         for (const link of links) {
1771 |           result.linksChecked++;
1772 | 
1773 |           // Skip external links unless explicitly requested
1774 |           if (link.startsWith("http") && !followExternalLinks) continue;
1775 | 
1776 |           // Check internal links
1777 |           if (!link.startsWith("http")) {
1778 |             const fullPath = path.resolve(path.dirname(file), link);
1779 |             try {
1780 |               await fs.access(fullPath);
1781 |             } catch {
1782 |               result.brokenLinks.push(`${path.basename(file)}: ${link}`);
1783 |               result.success = false;
1784 |             }
1785 |           }
1786 |         }
1787 |       }
1788 |     }
1789 | 
1790 |     // Validate code blocks if requested
1791 |     if (
1792 |       includeCodeValidation &&
1793 |       (validationType === "all" || validationType === "code")
1794 |     ) {
1795 |       for (const file of files) {
1796 |         const content = await fs.readFile(file, "utf-8");
1797 |         const codeBlocks = extractCodeBlocks(content);
1798 | 
1799 |         for (const block of codeBlocks) {
1800 |           result.codeBlocksValidated++;
1801 | 
1802 |           // Basic syntax validation
1803 |           if (block.language && block.code.trim()) {
1804 |             if (block.language === "javascript" || block.language === "js") {
1805 |               try {
1806 |                 // Basic JS syntax check - look for common issues
1807 |                 if (
1808 |                   block.code.includes("console.log") &&
1809 |                   !block.code.includes(";")
1810 |                 ) {
1811 |                   result.codeErrors.push(
1812 |                     `${path.basename(file)}: Missing semicolon in JS code`,
1813 |                   );
1814 |                 }
1815 |               } catch (error) {
1816 |                 result.codeErrors.push(
1817 |                   `${path.basename(file)}: JS syntax error - ${error}`,
1818 |                 );
1819 |                 result.success = false;
1820 |               }
1821 |             }
1822 |           }
1823 |         }
1824 |       }
1825 |     }
1826 | 
1827 |     // Generate recommendations
1828 |     if (result.brokenLinks.length > 0) {
1829 |       result.recommendations.push(
1830 |         `Fix ${result.brokenLinks.length} broken internal links`,
1831 |       );
1832 |       result.recommendations.push(
1833 |         "Run documentation build to catch additional link issues",
1834 |       );
1835 |     }
1836 | 
1837 |     if (result.codeErrors.length > 0) {
1838 |       result.recommendations.push(
1839 |         `Review and fix ${result.codeErrors.length} code syntax issues`,
1840 |       );
1841 |     }
1842 | 
1843 |     if (result.success) {
1844 |       result.recommendations.push(
1845 |         "Content validation passed - no critical issues found",
1846 |       );
1847 |     }
1848 | 
1849 |     // Create summary
1850 |     result.summary = `Validated ${files.length} files, ${
1851 |       result.linksChecked
1852 |     } links, ${result.codeBlocksValidated} code blocks. ${
1853 |       result.success
1854 |         ? "PASSED"
1855 |         : `ISSUES FOUND: ${
1856 |             result.brokenLinks.length + result.codeErrors.length
1857 |           }`
1858 |     }`;
1859 | 
1860 |     return result;
1861 |   } catch (error) {
1862 |     result.success = false;
1863 |     result.recommendations.push(`Validation failed: ${error}`);
1864 |     result.summary = `Validation error: ${error}`;
1865 |     return result;
1866 |   }
1867 | }
1868 | 
1869 | // Helper function to extract links from markdown
1870 | function extractLinksFromMarkdown(content: string): string[] {
1871 |   const linkRegex = /\[([^\]]*)\]\(([^)]+)\)/g;
1872 |   const links: string[] = [];
1873 |   let match;
1874 | 
1875 |   while ((match = linkRegex.exec(content)) !== null) {
1876 |     links.push(match[2]); // The URL part
1877 |   }
1878 | 
1879 |   return links;
1880 | }
1881 | 
1882 | // Helper function to extract code blocks from markdown
1883 | function extractCodeBlocks(
1884 |   content: string,
1885 | ): { language: string; code: string }[] {
1886 |   const codeBlockRegex = /```(\w+)?\n([\s\S]*?)```/g;
1887 |   const blocks: { language: string; code: string }[] = [];
1888 |   let match;
1889 | 
1890 |   while ((match = codeBlockRegex.exec(content)) !== null) {
1891 |     blocks.push({
1892 |       language: match[1] || "text",
1893 |       code: match[2],
1894 |     });
1895 |   }
1896 | 
1897 |   return blocks;
1898 | }
1899 | 
```
Page 25/29FirstPrevNextLast