UNPKG

faf-cli

Version:

😽 TURBO-CAT: The Rapid Catalytic Converter • Project DNA ✨ for ANY AI • Fully Integrated with React, Next.js, Svelte, TypeScript, Vite & n8n • FREE FOREVER • 10,000+ developers • Championship Edition

148 lines • 6.48 kB
"use strict"; /** * šŸ” faf audit - Audit Command * Check .faf file freshness and completeness gaps */ Object.defineProperty(exports, "__esModule", { value: true }); exports.auditFafFile = auditFafFile; const colors_1 = require("../fix-once/colors"); const fs_1 = require("fs"); const yaml_1 = require("../fix-once/yaml"); const file_utils_1 = require("../utils/file-utils"); const faf_compiler_1 = require("../compiler/faf-compiler"); async function auditFafFile(file, options = {}) { try { const fafPath = file || (await (0, file_utils_1.findFafFile)()); if (!fafPath) { console.log(colors_1.chalk.red("āŒ No .faf file found")); console.log(colors_1.chalk.yellow('šŸ’” Run "faf init" to create one')); process.exit(1); } console.log(colors_1.chalk.blue(`šŸ” Auditing: ${fafPath}`)); // Read and parse .faf file const content = await fs_1.promises.readFile(fafPath, "utf-8"); const fafData = (0, yaml_1.parse)(content); const warnDays = parseInt(options.warnDays || "7"); const errorDays = parseInt(options.errorDays || "30"); let auditScore = 100; const issues = []; const warnings = []; // 1. File Age Audit const modTime = await (0, file_utils_1.getFileModTime)(fafPath); if (modTime) { const daysSincemod = (0, file_utils_1.daysSinceModified)(modTime); if (daysSincemod >= errorDays) { issues.push(`File is ${daysSincemod} days old (critical staleness)`); auditScore -= 30; } else if (daysSincemod >= warnDays) { warnings.push(`File is ${daysSincemod} days old (consider refresh)`); auditScore -= 10; } } // 2. Generated Timestamp Audit if (fafData.generated) { try { const generatedDate = new Date(fafData.generated); const daysSinceGenerated = (0, file_utils_1.daysSinceModified)(generatedDate); if (daysSinceGenerated >= errorDays) { issues.push(`Generated timestamp is ${daysSinceGenerated} days old`); auditScore -= 20; } else if (daysSinceGenerated >= warnDays) { warnings.push(`Generated timestamp is ${daysSinceGenerated} days old`); auditScore -= 5; } } catch { issues.push("Invalid generated timestamp format"); auditScore -= 15; } } else { issues.push("Missing generated timestamp"); auditScore -= 20; } // 3. Completeness Audit const compiler = new faf_compiler_1.FafCompiler(); const scoreResult = await compiler.compile(fafPath); const completenessScore = scoreResult.score || 0; if (completenessScore < 50) { issues.push(`Low completeness score: ${Math.round(completenessScore)}%`); auditScore -= 25; } else if (completenessScore < 70) { warnings.push(`Moderate completeness score: ${Math.round(completenessScore)}%`); auditScore -= 10; } // 4. Critical Sections Audit const criticalSections = ["project", "ai_instructions", "scores"]; criticalSections.forEach((section) => { if (!fafData[section] || Object.keys(fafData[section]).length === 0) { issues.push(`Missing critical section: ${section}`); auditScore -= 15; } }); // 5. Quality Indicators Audit const hasAiInstructions = fafData.ai_instructions && Object.keys(fafData.ai_instructions).length > 0; if (!hasAiInstructions) { warnings.push("Missing AI instructions for context handoff"); auditScore -= 5; } const hasHumanContext = fafData.human_context && (fafData.human_context.who || fafData.human_context.what || fafData.human_context.why); if (!hasHumanContext) { warnings.push("Missing human context (6 Ws) for deeper understanding"); auditScore -= 10; } // Display Results auditScore = Math.max(0, Math.min(100, auditScore)); if (auditScore >= 90) { console.log(colors_1.chalk.green(`ā˜‘ļø Audit Score: ${auditScore}% - Excellent`)); } else if (auditScore >= 70) { console.log(colors_1.chalk.yellow(`āš ļø Audit Score: ${auditScore}% - Good`)); } else { console.log(colors_1.chalk.red(`🚨 Audit Score: ${auditScore}% - Needs Attention`)); } // Show Issues if (issues.length > 0) { console.log(colors_1.chalk.red("\n🚨 Critical Issues:")); issues.forEach((issue, index) => { console.log(colors_1.chalk.red(` ${index + 1}. ${issue}`)); }); } // Show Warnings if (warnings.length > 0) { console.log(colors_1.chalk.yellow("\nāš ļø Warnings:")); warnings.forEach((warning, index) => { console.log(colors_1.chalk.yellow(` ${index + 1}. ${warning}`)); }); } // Recommendations if (auditScore < 100) { console.log(colors_1.chalk.blue("\nšŸ’” Recommendations:")); if (auditScore < 70) { console.log(colors_1.chalk.blue(' • Run "faf sync" to update with latest project changes')); console.log(colors_1.chalk.blue(' • Run "faf score --details" to identify missing context')); } if (issues.some((i) => i.includes("days old"))) { console.log(colors_1.chalk.blue(' • Consider regenerating .faf file with "faf init --force"')); } if (completenessScore < 70) { console.log(colors_1.chalk.blue(" • Add missing context sections to improve AI understanding")); } } // Exit with appropriate code if (issues.length > 0) { process.exit(1); } } catch (error) { console.log(colors_1.chalk.red("šŸ’„ Audit failed:")); console.log(colors_1.chalk.red(error instanceof Error ? error.message : String(error))); process.exit(1); } } //# sourceMappingURL=audit.js.map