smart-renamer
Version:
š Intelligent file and code naming suggestions based on project-specific naming conventions. Interactive CLI tool with AST-based code analysis for variables, functions, components, and more.
643 lines ⢠30.4 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.createProgram = createProgram;
const commander_1 = require("commander");
const config_manager_1 = require("../config/config-manager");
const naming_validator_1 = require("../core/naming-validator");
const suggestion_engine_1 = require("../core/suggestion-engine");
const file_watcher_1 = require("../core/file-watcher");
const ast_analyzer_1 = require("../core/ast-analyzer");
const code_validator_1 = require("../core/code-validator");
const inquirer_1 = __importDefault(require("inquirer"));
const fs_1 = require("fs");
const path_1 = require("path");
function createProgram() {
const program = new commander_1.Command();
program
.name('renamer')
.description('Intelligent file naming suggestions based on project conventions')
.version('1.2.0');
program
.command('init')
.description('Initialize naming convention for the current project')
.action(initCommand);
program
.command('set-convention <convention>')
.description('Set the naming convention for the project')
.action(setConventionCommand);
program
.command('watch')
.description('Monitor for new files and suggest names')
.option('-p, --patterns <patterns>', 'File patterns to watch (comma-separated)', '**/*')
.action(watchCommand);
program
.command('validate')
.description('Validate existing file names against the project convention')
.option('-f, --fix', 'Show suggested fixes for invalid names')
.action(validateCommand);
program
.command('suggest <filename>')
.description('Get naming suggestions for a specific file')
.action(suggestCommand);
program
.command('analyze')
.description('Analyze project structure and naming patterns (files + code)')
.option('--patterns <patterns>', 'Code file patterns to analyze (comma-separated)', '**/*.ts,**/*.tsx,**/*.js,**/*.jsx')
.option('--files-only', 'Analyze only file naming patterns')
.option('--code-only', 'Analyze only code naming patterns')
.action(analyzeCommand);
program
.command('rename')
.description('Rename files to follow the project naming convention')
.option('-d, --dry-run', 'Show what would be renamed without actually renaming')
.option('-f, --force', 'Rename all files without individual prompts')
.option('-i, --interactive', 'Ask yes/no for each file individually (default)')
.option('--keep <files>', 'Comma-separated list of files to keep unchanged')
.action(renameCommand);
program
.command('validate-code')
.description('Validate code naming conventions (variables, functions, components, etc.)')
.option('-f, --fix', 'Show suggested fixes for naming violations')
.option('--patterns <patterns>', 'File patterns to analyze (comma-separated)', '**/*.ts,**/*.tsx,**/*.js,**/*.jsx')
.action(validateCodeCommand);
program
.command('analyze-code')
.description('Analyze code structure and naming patterns')
.option('--patterns <patterns>', 'File patterns to analyze (comma-separated)', '**/*.ts,**/*.tsx,**/*.js,**/*.jsx')
.action(analyzeCodeCommand);
program
.command('fix-code')
.description('Interactive code renaming to follow naming conventions')
.option('-d, --dry-run', 'Show what would be changed without making changes')
.option('--patterns <patterns>', 'File patterns to analyze (comma-separated)', '**/*.ts,**/*.tsx,**/*.js,**/*.jsx')
.action(fixCodeCommand);
return program;
}
async function initCommand() {
console.log('š Initializing Renamer for your project...\n');
const configManager = new config_manager_1.ConfigManager();
if (configManager.configExists()) {
const { overwrite } = await inquirer_1.default.prompt([{
type: 'confirm',
name: 'overwrite',
message: 'naming.config already exists. Do you want to overwrite it?',
default: false
}]);
if (!overwrite) {
console.log('ā
Keeping existing configuration.');
return;
}
}
const suggestionEngine = new suggestion_engine_1.SuggestionEngine();
const detectedConvention = suggestionEngine.detectProjectConvention();
const questions = [
{
type: 'list',
name: 'convention',
message: 'Choose your preferred file naming convention:',
choices: [
'camelCase',
'snake_case',
'kebab-case',
'PascalCase',
'UPPER_SNAKE_CASE'
],
default: detectedConvention || 'camelCase'
},
{
type: 'input',
name: 'files',
message: 'File patterns to apply convention to:',
default: '*.ts,*.js'
},
{
type: 'list',
name: 'folders',
message: 'Folder naming convention:',
choices: [
'camelCase',
'snake_case',
'kebab-case',
'PascalCase',
'UPPER_SNAKE_CASE'
],
default: 'kebab-case'
},
{
type: 'input',
name: 'exceptions',
message: 'Files to exclude from convention (comma-separated):',
default: 'index,main,app'
},
{
type: 'confirm',
name: 'setupCodeConventions',
message: 'Do you want to set up code-level naming conventions (variables, functions, etc.)?',
default: true
}
];
const answers = await inquirer_1.default.prompt(questions);
const config = {
convention: answers.convention,
files: answers.files.split(',').map((s) => s.trim()),
folders: answers.folders,
exceptions: answers.exceptions.split(',').map((s) => s.trim()).filter(Boolean)
};
if (answers.setupCodeConventions) {
const codeQuestions = [
{
type: 'list',
name: 'variables',
message: 'Variable naming convention:',
choices: ['camelCase', 'snake_case', 'kebab-case', 'PascalCase', 'UPPER_SNAKE_CASE'],
default: 'camelCase'
},
{
type: 'list',
name: 'functions',
message: 'Function naming convention:',
choices: ['camelCase', 'snake_case', 'kebab-case', 'PascalCase', 'UPPER_SNAKE_CASE'],
default: 'camelCase'
},
{
type: 'list',
name: 'components',
message: 'React Component naming convention:',
choices: ['camelCase', 'snake_case', 'kebab-case', 'PascalCase', 'UPPER_SNAKE_CASE'],
default: 'PascalCase'
},
{
type: 'list',
name: 'constants',
message: 'Constant naming convention:',
choices: ['camelCase', 'snake_case', 'kebab-case', 'PascalCase', 'UPPER_SNAKE_CASE'],
default: 'UPPER_SNAKE_CASE'
},
{
type: 'list',
name: 'classes',
message: 'Class naming convention:',
choices: ['camelCase', 'snake_case', 'kebab-case', 'PascalCase', 'UPPER_SNAKE_CASE'],
default: 'PascalCase'
}
];
const codeAnswers = await inquirer_1.default.prompt(codeQuestions);
config.code = {
variables: codeAnswers.variables,
functions: codeAnswers.functions,
components: codeAnswers.components,
constants: codeAnswers.constants,
classes: codeAnswers.classes,
interfaces: 'PascalCase',
types: 'PascalCase',
enums: 'PascalCase'
};
}
configManager.saveConfig(config);
console.log('\nā
Configuration saved to naming.config');
console.log(`š File convention: ${config.convention}`);
console.log(`š Folder convention: ${config.folders}`);
if (config.code) {
console.log(`š§ Code conventions:`);
console.log(` Variables: ${config.code.variables}`);
console.log(` Functions: ${config.code.functions}`);
console.log(` Components: ${config.code.components}`);
console.log(` Constants: ${config.code.constants}`);
console.log(` Classes: ${config.code.classes}`);
}
if (detectedConvention && detectedConvention !== config.convention) {
console.log(`\nš” Note: Detected '${detectedConvention}' in existing files, but you chose '${config.convention}'`);
}
if (config.code) {
console.log(`\nš Try these commands:`);
console.log(` renamer validate-code # Check your code conventions`);
console.log(` renamer analyze-code # Analyze code patterns`);
}
}
async function setConventionCommand(convention) {
const validConventions = ['camelCase', 'snake_case', 'kebab-case', 'PascalCase', 'UPPER_SNAKE_CASE'];
if (!validConventions.includes(convention)) {
console.error(`ā Invalid convention '${convention}'. Valid options: ${validConventions.join(', ')}`);
process.exit(1);
}
const configManager = new config_manager_1.ConfigManager();
const config = configManager.loadConfig();
config.convention = convention;
configManager.saveConfig(config);
console.log(`ā
Convention set to '${convention}'`);
}
async function watchCommand(options) {
const configManager = new config_manager_1.ConfigManager();
const config = configManager.loadConfig();
const suggestionEngine = new suggestion_engine_1.SuggestionEngine();
const patterns = options.patterns.split(',').map(p => p.trim());
const watcher = new file_watcher_1.FileWatcher(process.cwd(), patterns);
console.log(`š Watching for new files with convention: ${config.convention}`);
console.log(`š Patterns: ${patterns.join(', ')}\n`);
watcher.on('fileAdded', (fileInfo) => {
const suggestion = suggestionEngine.suggestName(fileInfo.name, config.convention, config.exceptions);
if (suggestion.original !== suggestion.suggested) {
console.log(`\nš New file detected: ${fileInfo.name}`);
console.log(`š” Suggested name: ${suggestion.suggested}`);
console.log(`šÆ Convention: ${suggestion.convention}`);
console.log(`š Confidence: ${(suggestion.confidence * 100).toFixed(1)}%`);
}
});
watcher.on('error', (error) => {
console.error('ā File watcher error:', error);
});
watcher.start();
process.on('SIGINT', () => {
console.log('\nš Stopping file watcher...');
watcher.stop();
process.exit(0);
});
}
async function validateCommand(options) {
const configManager = new config_manager_1.ConfigManager();
const config = configManager.loadConfig();
const suggestionEngine = new suggestion_engine_1.SuggestionEngine();
console.log(`š Validating files against '${config.convention}' convention...\n`);
const files = suggestionEngine['getAllProjectFiles']();
const invalidFiles = [];
for (const file of files) {
if (file.isDirectory)
continue;
const validation = naming_validator_1.NamingValidator.validateName(file.name, config.convention, config.exceptions);
if (!validation.isValid && validation.expectedName) {
invalidFiles.push({
name: file.name,
suggested: validation.expectedName,
path: file.path
});
console.log(`ā ${file.name}`);
console.log(` š” Should be: ${validation.expectedName}`);
console.log(` š Path: ${file.path}\n`);
}
}
if (invalidFiles.length === 0) {
console.log('ā
All files follow the naming convention!');
}
else {
console.log(`\nš Found ${invalidFiles.length} files that don't follow the convention.`);
if (options.fix) {
console.log('\nš§ Suggested fixes:');
for (const file of invalidFiles) {
console.log(`mv "${file.name}" "${file.suggested}"`);
}
}
}
}
async function suggestCommand(filename) {
const configManager = new config_manager_1.ConfigManager();
const config = configManager.loadConfig();
const suggestionEngine = new suggestion_engine_1.SuggestionEngine();
console.log(`š Generating suggestions for: ${filename}\n`);
const suggestions = suggestionEngine.suggestMultipleNames(filename, config.convention, config.exceptions);
for (const suggestion of suggestions) {
const icon = suggestion.convention === config.convention ? 'ā' : ' ';
console.log(`${icon} ${suggestion.convention.padEnd(20)} ${suggestion.suggested.padEnd(30)} (${(suggestion.confidence * 100).toFixed(1)}%)`);
}
}
async function analyzeCommand(options) {
const configManager = new config_manager_1.ConfigManager();
const config = configManager.loadConfig();
console.log('š Project Analysis\n');
// Analyze file naming patterns (unless code-only)
if (!options.codeOnly) {
console.log('š File Naming Analysis');
console.log('ā'.repeat(40));
const suggestionEngine = new suggestion_engine_1.SuggestionEngine();
const analysis = suggestionEngine.analyzeProjectStructure();
console.log(`š Total files: ${analysis.totalFiles}`);
console.log(`šÆ Most common convention: ${analysis.mostCommon || 'None detected'}`);
console.log(`š File consistency: ${(analysis.consistency * 100).toFixed(1)}%\n`);
console.log('š File convention breakdown:');
for (const [convention, count] of Object.entries(analysis.conventions)) {
const percentage = analysis.totalFiles > 0 ? (count / analysis.totalFiles * 100).toFixed(1) : '0.0';
console.log(` ${convention.padEnd(20)} ${count.toString().padStart(3)} files (${percentage}%)`);
}
console.log('');
}
// Analyze code naming patterns (unless files-only)
if (!options.filesOnly) {
if (!config.code) {
console.log('ā ļø No code conventions configured. Run `renamer init` to set up code conventions.');
return;
}
console.log('š» Code Naming Analysis');
console.log('ā'.repeat(40));
const analyzer = new ast_analyzer_1.ASTAnalyzer();
const validator = new code_validator_1.CodeValidator();
const patterns = options.patterns ? options.patterns.split(',').map(p => p.trim()) :
['**/*.ts', '**/*.tsx', '**/*.js', '**/*.jsx'];
const analysis = analyzer.analyzeProject(process.cwd(), patterns);
const validationResult = validator.validateIdentifiers(analysis.identifiers, config.code);
console.log(`š» Total identifiers: ${analysis.totalIdentifiers}`);
console.log(`š Code consistency: ${(analysis.consistencyScore * 100).toFixed(1)}%`);
console.log(`šÆ Violations found: ${validationResult.totalViolations}\n`);
// Show breakdown by category
const categories = ['variables', 'functions', 'classes', 'constants'];
console.log('š Code convention breakdown:');
for (const category of categories) {
const conventions = analysis.conventions[category];
const total = Object.values(conventions).reduce((a, b) => a + b, 0);
if (total > 0) {
console.log(`\n ${category.charAt(0).toUpperCase() + category.slice(1)} (${total} total):`);
for (const [convention, count] of Object.entries(conventions)) {
const percentage = (count / total * 100).toFixed(1);
const icon = convention === config.code[category] ? 'ā
' : ' ';
console.log(` ${icon} ${convention.padEnd(20)} ${count.toString().padStart(3)} (${percentage}%)`);
}
}
}
console.log('');
// Show violations summary if any
if (validationResult.totalViolations > 0) {
console.log('ā Top Violations:');
for (const [type, count] of Object.entries(validationResult.violationsByType)) {
console.log(` ${type}: ${count} violations`);
}
console.log('');
}
}
// Overall recommendations
console.log('šÆ Recommendations');
console.log('ā'.repeat(40));
if (!options.codeOnly) {
const suggestionEngine = new suggestion_engine_1.SuggestionEngine();
const fileAnalysis = suggestionEngine.analyzeProjectStructure();
if (fileAnalysis.consistency < 0.8) {
console.log('š File naming could be improved:');
console.log(' ⢠Run `renamer validate --fix` to see file suggestions');
console.log(' ⢠Run `renamer rename --dry-run` to preview changes');
}
else {
console.log('ā
File naming is consistent!');
}
}
if (!options.filesOnly && config.code) {
const analyzer = new ast_analyzer_1.ASTAnalyzer();
const patterns = options.patterns ? options.patterns.split(',').map(p => p.trim()) :
['**/*.ts', '**/*.tsx', '**/*.js', '**/*.jsx'];
const codeAnalysis = analyzer.analyzeProject(process.cwd(), patterns);
const validator = new code_validator_1.CodeValidator();
const validationResult = validator.validateIdentifiers(codeAnalysis.identifiers, config.code);
if (validationResult.totalViolations > 0) {
console.log('š» Code naming could be improved:');
console.log(' ⢠Run `renamer validate-code --fix` to see code suggestions');
console.log(' ⢠Consider updating your naming conventions with `renamer init`');
}
else {
console.log('ā
Code naming follows conventions!');
}
}
console.log('\nš” Tip: Run `renamer init` to update your naming conventions');
}
async function renameCommand(options) {
const configManager = new config_manager_1.ConfigManager();
const config = configManager.loadConfig();
const suggestionEngine = new suggestion_engine_1.SuggestionEngine();
// Parse keep list
const keepFiles = options.keep ? options.keep.split(',').map(f => f.trim()) : [];
// Default exclusions - system files, config files, and common files
const defaultExclusions = [
'package.json', 'tsconfig.json', 'bun.lockb', 'naming.config',
'package-lock.json', 'yarn.lock', '.gitignore', 'LICENSE',
// Config files
'.eslintrc.js', '.eslintrc.json', '.prettierrc', '.prettierrc.json',
'babel.config.js', 'webpack.config.js', 'vite.config.js', 'rollup.config.js',
'jest.config.js', 'vitest.config.js', '.env.example', 'Dockerfile',
'docker-compose.yml', 'docker-compose.yaml'
];
// File extensions to exclude by default
const excludedExtensions = [
// Image files
'.jpg', '.jpeg', '.png', '.gif', '.bmp', '.svg', '.webp', '.ico', '.tiff',
// Markdown files
'.md', '.markdown',
// Declaration files (all languages)
'.d.ts', '.d.mts', '.d.cts', // TypeScript declarations
'.h', '.hpp', '.hxx', // C/C++ headers
'.hi', // Haskell interface files
'.pyi', // Python stub files
'.rbi', // Ruby interface files
'.rei', // ReasonML interface files
'.mli', // OCaml interface files
'.sig', // Standard ML signature files
'.fsi', // F# signature files
'.spec', // RPM spec files
'.def', // Definition files (various languages)
// Config file extensions
'.config.js', '.config.ts', '.config.json', '.yml', '.yaml', '.toml', '.ini'
];
console.log(`š Finding files to rename to '${config.convention}' convention...\n`);
const files = suggestionEngine['getAllProjectFiles']();
const filesToRename = [];
for (const file of files) {
if (file.isDirectory)
continue;
// Skip files that should be ignored
if (file.name.startsWith('.') && file.name !== '.gitignore')
continue;
if (defaultExclusions.includes(file.name))
continue;
if (keepFiles.includes(file.name))
continue;
// Check if file extension should be excluded
const fileExtension = file.extension.toLowerCase();
const hasExcludedExtension = excludedExtensions.some(ext => file.name.toLowerCase().endsWith(ext.toLowerCase()));
if (hasExcludedExtension) {
const fileType = fileExtension.match(/\.(jpg|jpeg|png|gif|bmp|svg|webp|ico|tiff)$/i) ? 'image' :
fileExtension.match(/\.(md|markdown)$/i) ? 'markdown' :
file.name.match(/\.d\.(ts|mts|cts)$/i) ? 'TypeScript declaration' :
fileExtension.match(/\.(h|hpp|hxx)$/i) ? 'C/C++ header' :
fileExtension.match(/\.(hi|pyi|rbi|rei|mli|sig|fsi|spec|def)$/i) ? 'declaration' : 'config';
console.log(`š Skipping ${file.name} (${fileType} files excluded by default)`);
continue;
}
// Skip files containing 'config' in the filename
if (file.name.toLowerCase().includes('config')) {
console.log(`š Skipping ${file.name} (config files excluded by default)`);
continue;
}
const validation = naming_validator_1.NamingValidator.validateName(file.name, config.convention, config.exceptions);
if (!validation.isValid && validation.expectedName) {
const newPath = (0, path_1.join)((0, path_1.dirname)(file.path), validation.expectedName);
filesToRename.push({
oldPath: file.path,
newPath,
oldName: file.name,
newName: validation.expectedName
});
}
}
if (filesToRename.length === 0) {
console.log('ā
All files already follow the naming convention!');
return;
}
if (options.dryRun) {
console.log(`š Would rename ${filesToRename.length} files:\n`);
for (const file of filesToRename) {
console.log(` ${file.oldName} ā ${file.newName}`);
}
console.log('\nš Dry run complete. No files were actually renamed.');
return;
}
// Interactive mode (default) - ask for each file individually
if (!options.force) {
console.log(`š Found ${filesToRename.length} files that can be renamed:\n`);
let successCount = 0;
let errorCount = 0;
let skippedCount = 0;
for (const file of filesToRename) {
const { shouldRename } = await inquirer_1.default.prompt([{
type: 'confirm',
name: 'shouldRename',
message: `Rename "${file.oldName}" to "${file.newName}"?`,
default: true
}]);
if (shouldRename) {
try {
(0, fs_1.renameSync)(file.oldPath, file.newPath);
console.log(`ā
${file.oldName} ā ${file.newName}`);
successCount++;
}
catch (error) {
console.log(`ā Failed to rename ${file.oldName}: ${error}`);
errorCount++;
}
}
else {
console.log(`āļø Skipped ${file.oldName}`);
skippedCount++;
}
console.log(''); // Empty line for readability
}
console.log(`š Completed: ${successCount} renamed, ${skippedCount} skipped, ${errorCount} failed`);
return;
}
// Force mode - rename all without asking
console.log(`š Renaming ${filesToRename.length} files...\n`);
let successCount = 0;
let errorCount = 0;
for (const file of filesToRename) {
try {
(0, fs_1.renameSync)(file.oldPath, file.newPath);
console.log(`ā
${file.oldName} ā ${file.newName}`);
successCount++;
}
catch (error) {
console.log(`ā Failed to rename ${file.oldName}: ${error}`);
errorCount++;
}
}
console.log(`\nš Completed: ${successCount} renamed, ${errorCount} failed`);
}
async function validateCodeCommand(options) {
const configManager = new config_manager_1.ConfigManager();
const config = configManager.loadConfig();
if (!config.code) {
console.log('ā ļø No code conventions configured. Run `renamer init` to set up code conventions.');
return;
}
const analyzer = new ast_analyzer_1.ASTAnalyzer();
const validator = new code_validator_1.CodeValidator();
const patterns = options.patterns ? options.patterns.split(',').map(p => p.trim()) :
['**/*.ts', '**/*.tsx', '**/*.js', '**/*.jsx'];
console.log(`š Validating code conventions...\n`);
console.log(`š Variables: ${config.code.variables}`);
console.log(`š§ Functions: ${config.code.functions}`);
console.log(`āļø Components: ${config.code.components}`);
console.log(`š Constants: ${config.code.constants}`);
console.log(`šļø Classes: ${config.code.classes}\n`);
const analysis = analyzer.analyzeProject(process.cwd(), patterns);
const validationResult = validator.validateIdentifiers(analysis.identifiers, config.code);
if (validationResult.totalViolations === 0) {
console.log('ā
All code follows the naming conventions!');
console.log(`š Analyzed ${validationResult.totalChecked} identifiers across ${analysis.identifiers.length > 0 ? 'multiple files' : 'no files'}`);
return;
}
console.log(`ā Found ${validationResult.totalViolations} naming violations:\n`);
// Group violations by file
const violationsByFile = {};
for (const violation of validationResult.violations) {
const filePath = violation.identifier.filePath;
if (!violationsByFile[filePath]) {
violationsByFile[filePath] = [];
}
violationsByFile[filePath].push(violation);
}
// Display violations by file
for (const [filePath, violations] of Object.entries(violationsByFile)) {
console.log(`š ${filePath}:`);
for (const violation of violations) {
const line = violation.identifier.line;
const type = violation.identifier.isReactComponent ? 'React Component' : violation.identifier.type;
console.log(` Line ${line}: ${type} "${violation.identifier.name}" should be "${violation.suggestedName}"`);
if (options.fix) {
const suggestions = validator.suggestFixes(violation.identifier, config.code);
if (suggestions.length > 0) {
console.log(` š” Alternatives: ${suggestions.join(', ')}`);
}
}
}
console.log('');
}
// Summary
console.log('š Violation Summary:');
for (const [type, count] of Object.entries(validationResult.violationsByType)) {
console.log(` ${type}: ${count} violations`);
}
console.log(`\nš Total: ${validationResult.totalViolations} violations in ${Object.keys(violationsByFile).length} files`);
if (!options.fix) {
console.log('\nš” Use --fix to see suggested alternatives');
}
}
async function analyzeCodeCommand(options) {
const analyzer = new ast_analyzer_1.ASTAnalyzer();
const patterns = options.patterns ? options.patterns.split(',').map(p => p.trim()) :
['**/*.ts', '**/*.tsx', '**/*.js', '**/*.jsx'];
console.log('š Analyzing code structure and naming patterns...\n');
const analysis = analyzer.analyzeProject(process.cwd(), patterns);
console.log(`š Total identifiers: ${analysis.totalIdentifiers}`);
console.log(`š Consistency score: ${(analysis.consistencyScore * 100).toFixed(1)}%\n`);
// Show breakdown by category
const categories = ['variables', 'functions', 'classes', 'constants'];
for (const category of categories) {
const conventions = analysis.conventions[category];
const total = Object.values(conventions).reduce((a, b) => a + b, 0);
if (total > 0) {
console.log(`š ${category.charAt(0).toUpperCase() + category.slice(1)} (${total} total):`);
for (const [convention, count] of Object.entries(conventions)) {
const percentage = (count / total * 100).toFixed(1);
console.log(` ${convention.padEnd(20)} ${count.toString().padStart(3)} (${percentage}%)`);
}
console.log('');
}
}
// Recommendations
if (analysis.consistencyScore < 0.8) {
console.log('š” Recommendations:');
console.log(' - Consider standardizing naming conventions across the project');
console.log(' - Use `renamer validate-code --fix` to see specific suggestions');
console.log(' - Run `renamer fix-code` for interactive refactoring');
}
else {
console.log('ā
Good consistency! Your code follows consistent naming patterns.');
}
}
async function fixCodeCommand(_options) {
console.log('š§ Code transformation feature coming soon!');
console.log('');
console.log('For now, you can:');
console.log('1. Use `renamer validate-code --fix` to see suggested changes');
console.log('2. Manually apply the suggestions in your IDE');
console.log('3. Set up ESLint rules for automated enforcement');
console.log('');
console.log('Interactive code refactoring will be available in a future update.');
}
//# sourceMappingURL=commands.js.map