@neurolint/cli
Version:
NeuroLint CLI for React/Next.js modernization with advanced 6-layer orchestration and intelligent AST transformations
1,065 lines (927 loc) • 29.7 kB
JavaScript
/**
* NeuroLint Pro Enhanced - Premium Debugging Service with Advanced AST Capabilities
*
* Implements IMPLEMENTATION_PATTERNS.md with enhanced AST transformations:
* - Enhanced AST Transformation Engine
* - Type-Aware Transformations
* - Next.js App Router Intelligence
* - Component Relationship Analysis
* - Performance-Aware Optimizations
*
* CRITICAL: Maintains backward compatibility with existing layer system
*/
const fs = require("fs");
const path = require("path");
const { execSync } = require("child_process");
// Import enhanced AST capabilities
let EnhancedASTEngine,
TypeAwareTransforms,
NextJSIntelligence,
ComponentRelationshipAnalyzer,
PerformanceOptimizer;
try {
({ EnhancedASTEngine } = require("./lib/enhanced-ast-engine"));
({ TypeAwareTransforms } = require("./lib/type-aware-transforms"));
({ NextJSIntelligence } = require("./lib/nextjs-intelligence"));
({
ComponentRelationshipAnalyzer,
} = require("./lib/component-relationship-analyzer"));
({ PerformanceOptimizer } = require("./lib/performance-optimizer"));
} catch (error) {
console.warn(
"[NEUROLINT PRO] Enhanced AST modules not available, falling back to basic mode:",
error.message,
);
}
/**
* Core Architecture Principles (from IMPLEMENTATION_PATTERNS.md)
* Layers must execute in order (1→2→3→4→5→6) because each builds on the previous
*/
const LAYER_EXECUTION_ORDER = [
{
id: 1,
name: "Configuration",
description: "Foundation setup",
useAST: false,
},
{
id: 2,
name: "Entity Cleanup",
description: "Preprocessing patterns",
useAST: false,
},
{
id: 3,
name: "Components",
description: "React/TS specific fixes",
useAST: true,
},
{
id: 4,
name: "Hydration",
description: "Runtime safety guards",
useAST: true,
},
{
id: 5,
name: "Next.js App Router",
description: "Next.js specific optimizations",
useAST: true,
},
{
id: 6,
name: "Testing & Validation",
description: "Testing patterns and validation",
useAST: true,
},
];
/**
* Enhanced Layer Dependency Manager with AST awareness
*/
class EnhancedLayerDependencyManager {
static DEPENDENCIES = {
1: [], // Configuration has no dependencies
2: [1], // Entity cleanup depends on config foundation
3: [1, 2], // Components depend on config + cleanup
4: [1, 2, 3], // Hydration depends on all previous layers
5: [1, 2, 3, 4], // Next.js depends on all core layers
6: [1, 2, 3, 4, 5], // Testing depends on all previous layers
};
static LAYER_INFO = {
1: { name: "Configuration", critical: true, useAST: false },
2: { name: "Entity Cleanup", critical: false, useAST: false },
3: { name: "Components", critical: false, useAST: true },
4: { name: "Hydration", critical: false, useAST: true },
5: { name: "Next.js App Router", critical: false, useAST: true },
6: { name: "Testing & Validation", critical: false, useAST: true },
};
/**
* Enhanced layer suggestion with AST-based analysis
*/
static suggestLayers(code, filename, astEngine = null) {
const recommended = [];
const reasons = [];
// Always recommend config layer for foundation
recommended.push(1);
reasons.push("Configuration layer provides essential foundation");
// Enhanced analysis if AST engine is available
if (astEngine && EnhancedASTEngine) {
const parseResult = astEngine.parseCode(code, filename);
if (parseResult.success) {
const context = astEngine.semanticContext.get(filename);
// Smart layer detection based on semantic analysis
const astRecommendations = this.getASTRecommendations(
parseResult.ast,
context,
);
recommended.push(...astRecommendations.layers);
reasons.push(...astRecommendations.reasons);
} else {
// Fall back to regex-based analysis
const regexRecommendations = this.getRegexRecommendations(code);
recommended.push(...regexRecommendations.layers);
reasons.push(...regexRecommendations.reasons);
}
} else {
// Original regex-based analysis
const regexRecommendations = this.getRegexRecommendations(code);
recommended.push(...regexRecommendations.layers);
reasons.push(...regexRecommendations.reasons);
}
return {
recommended: [...new Set(recommended)].sort((a, b) => a - b),
reasons,
};
}
static getASTRecommendations(ast, context) {
const layers = [];
const reasons = [];
// Layer 2: Pattern fixes
if (
context.dependencies.has("console.log") ||
this.hasHTMLEntities(context)
) {
layers.push(2);
reasons.push("Entity cleanup needed based on AST analysis");
}
// Layer 3: Component fixes
if (context.components.size > 0) {
layers.push(3);
reasons.push("React components detected - component fixes recommended");
}
// Layer 4: Hydration fixes
if (
context.dependencies.has("localStorage") ||
context.dependencies.has("window")
) {
layers.push(4);
reasons.push("Browser API usage detected - hydration safety needed");
}
// Layer 5: Next.js optimizations
if (
context.dependencies.has("next") ||
this.isNextJSFile(context.filename)
) {
layers.push(5);
reasons.push(
"Next.js usage detected - App Router optimizations available",
);
}
// Layer 6: Testing enhancements
if (context.components.size > 2 || this.hasComplexLogic(context)) {
layers.push(6);
reasons.push(
"Complex component structure - testing enhancements recommended",
);
}
return { layers, reasons };
}
static getRegexRecommendations(code) {
const layers = [];
const reasons = [];
// Check for HTML entities or old patterns
if (/"|&|<|>|console\.log/.test(code)) {
layers.push(2);
reasons.push("Entity cleanup needed for HTML entities and old patterns");
}
// Check for React components needing fixes
if (code.includes("map(") && code.includes("<") && !code.includes("key=")) {
layers.push(3);
reasons.push("Component fixes needed for missing key props");
}
// Check for hydration issues
if (code.includes("localStorage") && !code.includes("typeof window")) {
layers.push(4);
reasons.push("Hydration fixes needed for SSR safety");
}
// Check for Next.js patterns
if (code.includes("next/") || code.includes("'use client'")) {
layers.push(5);
reasons.push("Next.js patterns detected");
}
return { layers, reasons };
}
static hasHTMLEntities(context) {
// Enhanced check for HTML entities in AST context
return false; // Placeholder implementation
}
static isNextJSFile(filename) {
const nextJSPatterns = [
"page.tsx",
"page.ts",
"page.jsx",
"page.js",
"layout.tsx",
"layout.ts",
"layout.jsx",
"layout.js",
"route.ts",
"route.js",
];
const basename = path.basename(filename);
return nextJSPatterns.includes(basename);
}
static hasComplexLogic(context) {
return context.hooks.size > 3 || context.components.size > 5;
}
// Original methods for backward compatibility
static validateAndCorrectLayers(requestedLayers) {
const warnings = [];
const autoAdded = [];
let correctedLayers = [...requestedLayers];
// Sort layers in execution order
correctedLayers.sort((a, b) => a - b);
// Check dependencies for each requested layer
for (const layerId of requestedLayers) {
const dependencies = this.DEPENDENCIES[layerId] || [];
const missingDeps = dependencies.filter(
(dep) => !correctedLayers.includes(dep),
);
if (missingDeps.length > 0) {
// Auto-add missing dependencies
correctedLayers.push(...missingDeps);
autoAdded.push(...missingDeps);
warnings.push(
`Layer ${layerId} (${this.LAYER_INFO[layerId]?.name}) requires ` +
`${missingDeps.map((dep) => `${dep} (${this.LAYER_INFO[dep]?.name})`).join(", ")}. ` +
`Auto-added missing dependencies.`,
);
}
}
// Remove duplicates and sort
correctedLayers = [...new Set(correctedLayers)].sort((a, b) => a - b);
return {
correctedLayers,
warnings,
autoAdded,
};
}
}
/**
* Enhanced Transformation Validator with AST support
*/
class EnhancedTransformationValidator {
static validateTransformation(before, after, layerId, astEngine = null) {
// Skip validation if no changes were made
if (before === after) {
return { shouldRevert: false, reason: "No changes made" };
}
// Enhanced validation for AST-enabled layers
if (astEngine && this.isASTLayer(layerId)) {
return this.validateASTTransformation(before, after, astEngine);
}
// Original validation for regex-based layers
return this.validateRegexTransformation(before, after);
}
static isASTLayer(layerId) {
return layerId >= 3 && layerId <= 6; // Layers 3-6 use AST
}
static validateASTTransformation(before, after, astEngine) {
// Parse both versions with AST
const beforeParse = astEngine.parseCode(before, "before.tsx");
const afterParse = astEngine.parseCode(after, "after.tsx");
if (!beforeParse.success) {
return { shouldRevert: false, reason: "Original code has syntax issues" };
}
if (!afterParse.success) {
return {
shouldRevert: true,
reason: `AST transformation introduced syntax error: ${afterParse.error}`,
};
}
// Additional AST-based validation could be added here
return { shouldRevert: false };
}
static validateRegexTransformation(before, after) {
// Original validation logic
const syntaxCheck = this.validateSyntax(after);
if (!syntaxCheck.valid) {
return {
shouldRevert: true,
reason: `Syntax error: ${syntaxCheck.error}`,
};
}
const corruptionCheck = this.detectCorruption(before, after);
if (corruptionCheck.detected) {
return {
shouldRevert: true,
reason: `Corruption detected: ${corruptionCheck.pattern}`,
};
}
const logicalCheck = this.validateLogicalIntegrity(before, after);
if (!logicalCheck.valid) {
return {
shouldRevert: true,
reason: `Logical issue: ${logicalCheck.reason}`,
};
}
return { shouldRevert: false };
}
// Original validation methods
static validateSyntax(code) {
try {
const openBraces = (code.match(/\{/g) || []).length;
const closeBraces = (code.match(/\}/g) || []).length;
const openParens = (code.match(/\(/g) || []).length;
const closeParens = (code.match(/\)/g) || []).length;
if (openBraces !== closeBraces) {
return { valid: false, error: "Mismatched braces" };
}
if (openParens !== closeParens) {
return { valid: false, error: "Mismatched parentheses" };
}
return { valid: true };
} catch (error) {
return {
valid: false,
error: error instanceof Error ? error.message : "Unknown syntax error",
};
}
}
static detectCorruption(before, after) {
const corruptionPatterns = [
{
name: "Double function calls",
regex: /onClick=\{[^}]*\([^)]*\)\s*=>\s*\(\)\s*=>/g,
},
{
name: "Malformed event handlers",
regex: /onClick=\{[^}]*\)\([^)]*\)$/g,
},
{
name: "Invalid JSX attributes",
regex: /\w+=\{[^}]*\)[^}]*\}/g,
},
{
name: "Broken import statements",
regex: /import\s*{\s*\n\s*import\s*{/g,
},
];
for (const pattern of corruptionPatterns) {
if (pattern.regex.test(after) && !pattern.regex.test(before)) {
return {
detected: true,
pattern: pattern.name,
};
}
}
return { detected: false };
}
static validateLogicalIntegrity(before, after) {
const beforeImports = this.extractImports(before);
const afterImports = this.extractImports(after);
const removedImports = beforeImports.filter(
(imp) => !afterImports.includes(imp),
);
const criticalImports = ["React", "useState", "useEffect"];
const removedCritical = removedImports.filter((imp) =>
criticalImports.some((critical) => imp.includes(critical)),
);
if (removedCritical.length > 0) {
return {
valid: false,
reason: `Critical imports removed: ${removedCritical.join(", ")}`,
};
}
return { valid: true };
}
static extractImports(code) {
const importRegex = /import\s+.*?\s+from\s+['"][^'"]+['"]/g;
return code.match(importRegex) || [];
}
}
/**
* Enhanced Layer Execution with AST capabilities
*/
async function executeEnhancedLayers(code, enabledLayers, options = {}) {
let current = code;
const results = [];
const states = [code];
const filename = options.filename || "unknown.tsx";
// Initialize enhanced AST engines if available
let astEngine = null;
let typeAwareTransforms = null;
let nextJSIntelligence = null;
let relationshipAnalyzer = null;
let performanceOptimizer = null;
if (EnhancedASTEngine) {
try {
astEngine = new EnhancedASTEngine();
if (TypeAwareTransforms) {
typeAwareTransforms = new TypeAwareTransforms(astEngine);
}
if (NextJSIntelligence) {
nextJSIntelligence = new NextJSIntelligence(astEngine);
}
if (ComponentRelationshipAnalyzer) {
relationshipAnalyzer = new ComponentRelationshipAnalyzer(astEngine);
}
if (PerformanceOptimizer) {
performanceOptimizer = new PerformanceOptimizer(
astEngine,
relationshipAnalyzer,
);
}
} catch (error) {
console.warn(
"[NEUROLINT PRO] Failed to initialize AST engines:",
error.message,
);
}
}
const totalLayers = enabledLayers.length;
let completed = 0;
for (const layerId of enabledLayers) {
const previous = current;
const startTime = performance.now();
if (options.verbose) {
console.log(
`\n🔧 [Layer ${layerId}] ${LAYER_EXECUTION_ORDER.find((l) => l.id === layerId)?.name || "Unknown"}`,
);
}
try {
let transformed = current;
const layerInfo = LAYER_EXECUTION_ORDER.find((l) => l.id === layerId);
// Execute layer with appropriate method (AST or regex)
if (layerInfo?.useAST && astEngine) {
transformed = await executeASTLayer(layerId, current, filename, {
astEngine,
typeAwareTransforms,
nextJSIntelligence,
relationshipAnalyzer,
performanceOptimizer,
options,
});
} else {
transformed = await executeRegexLayer(layerId, current, options);
}
// Validate transformation
const validation = EnhancedTransformationValidator.validateTransformation(
previous,
transformed,
layerId,
astEngine,
);
if (validation.shouldRevert) {
console.warn(`⚠️ [Layer ${layerId}] Reverting: ${validation.reason}`);
current = previous; // Rollback
results.push({
layerId,
success: false,
code: previous,
executionTime: performance.now() - startTime,
changeCount: 0,
revertReason: validation.reason,
});
} else {
current = transformed; // Accept changes
states.push(current);
const changeCount = calculateChanges(previous, transformed);
const improvements = detectImprovements(previous, transformed, layerId);
results.push({
layerId,
success: true,
code: current,
executionTime: performance.now() - startTime,
changeCount,
improvements,
});
if (options.verbose && changeCount > 0) {
console.log(`✅ [Layer ${layerId}] Applied ${changeCount} changes`);
improvements.forEach((improvement) => {
console.log(` 📝 ${improvement}`);
});
}
}
} catch (error) {
console.error(`❌ [Layer ${layerId}] Error: ${error.message}`);
results.push({
layerId,
success: false,
code: previous,
executionTime: performance.now() - startTime,
changeCount: 0,
error: error.message,
});
current = previous; // Keep safe state
}
completed++;
if (options.onProgress) {
options.onProgress({
completed,
total: totalLayers,
percentage: Math.round((completed / totalLayers) * 100),
currentLayer: layerId,
});
}
}
// Generate comprehensive analysis if AST engines are available
let analysis = null;
if (astEngine && relationshipAnalyzer && performanceOptimizer) {
try {
const parseResult = astEngine.parseCode(current, filename);
if (parseResult.success) {
const context = astEngine.semanticContext.get(filename);
const relationshipAnalysis =
relationshipAnalyzer.analyzeComponentRelationships(
parseResult.ast,
context,
);
const performanceAnalysis = performanceOptimizer.optimizePerformance(
parseResult.ast,
context,
);
analysis = {
components: relationshipAnalysis.components,
dataFlow: relationshipAnalysis.dataFlow,
optimizations: relationshipAnalysis.optimizations.concat(
performanceAnalysis.optimizations,
),
performanceMetrics: performanceAnalysis.metrics,
recommendedLayers: EnhancedLayerDependencyManager.suggestLayers(
current,
filename,
astEngine,
).recommended,
detectedIssues: generateIssueReport(results),
confidence: calculateConfidence(results),
estimatedImpact: estimateImpact(results),
};
}
} catch (error) {
console.warn(
"[NEUROLINT PRO] Analysis generation failed:",
error.message,
);
}
}
return {
success: results.every((r) => r.success),
dryRun: options.dryRun || false,
originalCode: code,
transformed: current,
layers: results,
states,
totalExecutionTime: results.reduce((sum, r) => sum + r.executionTime, 0),
successfulLayers: results.filter((r) => r.success).length,
analysis,
};
}
/**
* Execute AST-based layer transformation
*/
async function executeASTLayer(layerId, code, filename, engines) {
const {
astEngine,
typeAwareTransforms,
nextJSIntelligence,
relationshipAnalyzer,
performanceOptimizer,
options,
} = engines;
const parseResult = astEngine.parseCode(code, filename);
if (!parseResult.success) {
// Fall back to regex-based transformation
console.warn(
`[Layer ${layerId}] AST parsing failed, falling back to regex`,
);
return await executeRegexLayer(layerId, code, options);
}
const context = astEngine.semanticContext.get(filename);
let transformations = [];
// Apply layer-specific AST transformations
switch (layerId) {
case 3: // Components layer
if (typeAwareTransforms) {
transformations.push(
...typeAwareTransforms.analyzeComponentProps(
parseResult.ast,
context,
),
);
transformations.push(
...typeAwareTransforms.enhanceComponentPropsWithLibraryTypes(
parseResult.ast,
context,
),
);
}
transformations.push(
...astEngine.transformMissingKeys(parseResult.ast, context),
);
transformations.push(
...astEngine.transformImports(parseResult.ast, context),
);
break;
case 4: // Hydration layer
if (nextJSIntelligence) {
transformations.push(
...nextJSIntelligence.fixSSRHydrationIssues(parseResult.ast, context),
);
transformations.push(
...nextJSIntelligence.analyzeClientDirectiveNeeds(
parseResult.ast,
context,
),
);
}
break;
case 5: // Next.js layer
if (nextJSIntelligence) {
transformations.push(
...nextJSIntelligence.transformNextJsPatterns(
parseResult.ast,
context,
),
);
transformations.push(
...nextJSIntelligence.optimizeServerComponents(
parseResult.ast,
context,
),
);
transformations.push(
...nextJSIntelligence.optimizeMetadata(parseResult.ast, context),
);
}
break;
case 6: // Testing & Validation layer
if (typeAwareTransforms) {
transformations.push(
...typeAwareTransforms.transformWithTypeAwareness(
parseResult.ast,
context,
),
);
}
if (performanceOptimizer) {
const perfOptimizations = performanceOptimizer.optimizePerformance(
parseResult.ast,
context,
);
transformations.push(...perfOptimizations.optimizations);
}
break;
}
// Apply transformations to AST
transformations.forEach((transformation) => {
if (transformation.action && typeof transformation.action === "function") {
try {
transformation.action();
} catch (error) {
console.warn(
`[Layer ${layerId}] Transformation failed:`,
error.message,
);
}
}
});
// Generate code from modified AST
const codeResult = astEngine.generateCode(parseResult.ast, code);
if (!codeResult.success) {
console.warn(
`[Layer ${layerId}] Code generation failed, falling back to original`,
);
return code;
}
return codeResult.code;
}
/**
* Execute regex-based layer transformation (original method)
* FIXED: Now properly delegates to standard engine transformations
*/
async function executeRegexLayer(layerId, code, options) {
// Import and use the standard engine's transformation functions
try {
const standardEngine = require("./neurolint-pro.js");
// Call the standard engine directly for this layer
console.log(
`[ENHANCED ENGINE] Delegating Layer ${layerId} to standard engine`,
);
// Use the standard engine's applyLayerTransformations function
if (typeof standardEngine.applyLayerTransformations === "function") {
return standardEngine.applyLayerTransformations(layerId, code, options);
}
// If the function doesn't exist, fall back to the full standard engine
const result = await standardEngine(
code,
options.filename || "unknown.tsx",
true,
[layerId],
{
...options,
isDemoMode: true,
singleFile: true,
},
);
return result.transformed || code;
} catch (error) {
console.warn(
`[ENHANCED ENGINE] Standard engine fallback failed for Layer ${layerId}:`,
error.message,
);
// Last resort: return original code to prevent crashes
return code;
}
}
// Helper functions
function calculateChanges(before, after) {
const beforeLines = before.split("\n");
const afterLines = after.split("\n");
let changes = Math.abs(beforeLines.length - afterLines.length);
const minLength = Math.min(beforeLines.length, afterLines.length);
for (let i = 0; i < minLength; i++) {
if (beforeLines[i] !== afterLines[i]) changes++;
}
return changes;
}
function detectImprovements(before, after, layerId) {
const improvements = [];
const layerNames = {
1: "Configuration modernized",
2: "Patterns cleaned up",
3: "Components enhanced",
4: "Hydration safety added",
5: "Next.js optimized",
6: "Testing improved",
};
if (before !== after) {
improvements.push(layerNames[layerId] || `Layer ${layerId} improvements`);
}
return improvements;
}
function generateIssueReport(results) {
const issues = [];
results.forEach((result) => {
if (!result.success) {
issues.push({
type: "execution-error",
severity: "high",
description: `Layer ${result.layerId} failed: ${result.error || result.revertReason}`,
fixedByLayer: result.layerId,
pattern: "Layer execution failure",
});
}
});
return issues;
}
function calculateConfidence(results) {
const successRate = results.filter((r) => r.success).length / results.length;
return Math.max(0.5, successRate); // Minimum 50% confidence
}
function estimateImpact(results) {
const totalChanges = results.reduce(
(sum, r) => sum + (r.changeCount || 0),
0,
);
const successfulLayers = results.filter((r) => r.success).length;
let level = "low";
if (totalChanges > 20 || successfulLayers > 4) {
level = "high";
} else if (totalChanges > 5 || successfulLayers > 2) {
level = "medium";
}
return {
level,
description: `${totalChanges} total changes across ${successfulLayers} layers`,
estimatedFixTime: `${Math.max(30, totalChanges * 5)} seconds`,
};
}
/**
* Main NeuroLint Pro Enhanced Entry Point
*/
async function NeuroLintProEnhanced(
code,
filePath,
dryRun = true,
requestedLayers = null,
options = {},
) {
try {
const filename = filePath || "unknown.tsx";
console.log(
`[NEUROLINT PRO ENHANCED] Starting analysis${dryRun ? " (dry-run)" : ""}...`,
);
// Initialize AST engine for layer suggestion if available
let astEngine = null;
if (EnhancedASTEngine) {
try {
astEngine = new EnhancedASTEngine();
} catch (error) {
console.warn(
"[NEUROLINT PRO] AST engine initialization failed:",
error.message,
);
}
}
// Determine layers to execute
let layersToExecute;
if (requestedLayers && Array.isArray(requestedLayers)) {
const validation =
EnhancedLayerDependencyManager.validateAndCorrectLayers(
requestedLayers,
);
layersToExecute = validation.correctedLayers;
if (validation.warnings.length > 0 && options.verbose) {
validation.warnings.forEach((warning) =>
console.warn(`⚠️ ${warning}`),
);
}
} else {
// Auto-suggest layers based on code analysis
const suggestion = EnhancedLayerDependencyManager.suggestLayers(
code,
filename,
astEngine,
);
layersToExecute = suggestion.recommended;
if (options.verbose) {
console.log(
"🎯 Recommended layers:",
suggestion.recommended.join(", "),
);
suggestion.reasons.forEach((reason) => console.log(` 📋 ${reason}`));
}
}
// Execute layers with enhanced capabilities
const result = await executeEnhancedLayers(code, layersToExecute, {
...options,
filename,
dryRun,
verbose: options.verbose || false,
onProgress: options.onProgress,
});
console.log(
`[NEUROLINT PRO ENHANCED] Analysis complete in ${result.totalExecutionTime.toFixed(0)}ms`,
);
return result;
} catch (error) {
console.error("[NEUROLINT PRO ENHANCED] Critical error:", error);
return {
success: false,
error: error.message,
originalCode: code,
transformed: code,
layers: [],
states: [code],
totalExecutionTime: 0,
successfulLayers: 0,
};
}
}
// Export the enhanced engine
module.exports = NeuroLintProEnhanced;
// CLI usage
if (require.main === module) {
const args = process.argv.slice(2);
if (args.length === 0) {
console.log(`
NeuroLint Pro Enhanced - Premium React/Next.js Code Fixing Service
Usage:
node neurolint-pro-enhanced.js <file> [options]
Options:
--dry-run Preview changes without applying them (default)
--apply Actually apply the fixes
--layers=1,2,3,4 Specify which layers to run
--verbose Show detailed output
Examples:
node neurolint-pro-enhanced.js src/components/Button.tsx --dry-run --verbose
node neurolint-pro-enhanced.js src/pages/index.tsx --apply --layers=3,4,5
`);
process.exit(0);
}
const filePath = args[0];
const dryRun = !args.includes("--apply");
const verbose = args.includes("--verbose");
let requestedLayers = null;
const layersArg = args.find((arg) => arg.startsWith("--layers="));
if (layersArg) {
requestedLayers = layersArg.split("=")[1].split(",").map(Number);
}
if (!fs.existsSync(filePath)) {
console.error(`❌ File not found: ${filePath}`);
process.exit(1);
}
const code = fs.readFileSync(filePath, "utf8");
NeuroLintProEnhanced(code, filePath, dryRun, requestedLayers, { verbose })
.then((result) => {
if (result.success) {
console.log(`\n✅ Analysis completed successfully`);
console.log(
`📊 ${result.successfulLayers}/${result.layers.length} layers succeeded`,
);
if (!dryRun && result.transformed !== result.originalCode) {
fs.writeFileSync(filePath, result.transformed);
console.log(`💾 File updated: ${filePath}`);
}
} else {
console.log(`\n❌ Analysis failed: ${result.error}`);
process.exit(1);
}
})
.catch((error) => {
console.error(`\n💥 Fatal error: ${error.message}`);
process.exit(1);
});
}