UNPKG

@sbeeredd04/auto-git

Version:

AI-powered Git automation with intelligent commit decisions using Gemini function calling, smart diff optimization, push control, and enhanced interactive terminal session with persistent command history

317 lines (276 loc) 6.9 kB
import chalk from 'chalk'; import boxen from 'boxen'; import ora from 'ora'; /** * Centralized logging utility for Auto-Git * Provides colorized, boxed, and professional console output */ class Logger { constructor() { this.spinner = null; this.verbose = false; } /** * Set verbose mode for detailed logging */ setVerbose(verbose = true) { this.verbose = verbose; } /** * Create a styled box for important messages */ _createBox(message, options = {}) { return boxen(message, { padding: 1, margin: 1, borderStyle: 'round', borderColor: 'blue', ...options }); } /** * Success message with green box */ success(message, details = null) { const content = details ? `${chalk.bold.green('SUCCESS')}\n\n${message}\n\n${chalk.dim(details)}` : `${chalk.bold.green('SUCCESS')}\n\n${message}`; console.log(this._createBox(content, { borderColor: 'green', borderStyle: 'double' })); } /** * Error message with red box */ error(message, details = null) { const content = details ? `${chalk.bold.red('ERROR')}\n\n${message}\n\n${chalk.dim(details)}` : `${chalk.bold.red('ERROR')}\n\n${message}`; console.error(this._createBox(content, { borderColor: 'red', borderStyle: 'double' })); } /** * Warning message with yellow box */ warning(message, details = null) { const content = details ? `${chalk.bold.yellow('WARNING')}\n\n${message}\n\n${chalk.dim(details)}` : `${chalk.bold.yellow('WARNING')}\n\n${message}`; console.warn(this._createBox(content, { borderColor: 'yellow' })); } /** * Info message with blue styling */ info(message, title = 'INFO') { console.log(chalk.blue(`[${title}]`), chalk.white(message)); } /** * Debug message (only shown in verbose mode) */ debug(message) { if (this.verbose) { console.log(chalk.dim(`[DEBUG] ${message}`)); } } /** * Status update with colored prefix */ status(message, type = 'info') { const colors = { info: chalk.blue, success: chalk.green, warning: chalk.yellow, error: chalk.red, processing: chalk.cyan }; const color = colors[type] || chalk.white; console.log(color('▶'), chalk.white(message)); } /** * Section header with styled box */ section(title, subtitle = null) { const content = subtitle ? `${chalk.bold.white(title)}\n${chalk.dim(subtitle)}` : chalk.bold.white(title); console.log(this._createBox(content, { borderColor: 'cyan', borderStyle: 'classic', padding: { top: 0, bottom: 0, left: 2, right: 2 } })); } /** * Configuration display */ config(title, items) { let content = chalk.bold.blue(title) + '\n\n'; Object.entries(items).forEach(([key, value]) => { const displayValue = typeof value === 'boolean' ? (value ? chalk.green('✓ Yes') : chalk.red('✗ No')) : chalk.white(value); content += `${chalk.cyan(key.padEnd(20))} ${displayValue}\n`; }); console.log(this._createBox(content.trim(), { borderColor: 'blue', padding: 1 })); } /** * Repository status display */ repoStatus(branch, hasRemote, apiKeySet) { const items = { 'Repository': chalk.green('✓ Valid Git repository'), 'Branch': chalk.white(branch), 'Remote': hasRemote ? chalk.green('✓ Configured') : chalk.yellow('✗ Not configured'), 'API Key': apiKeySet ? chalk.green('✓ Set') : chalk.red('✗ Missing') }; this.config('REPOSITORY STATUS', items); } /** * Watch configuration display */ watchConfig(paths, debounceMs, recursive) { const items = { 'Watch Paths': paths.join(', '), 'Debounce Time': `${debounceMs}ms`, 'Recursive': recursive, 'Mode': 'File watching active' }; this.config('WATCH CONFIGURATION', items); } /** * File change notification */ fileChange(event, path) { console.log( chalk.cyan('▶ File Change:'), chalk.yellow(event), chalk.dim('→'), chalk.white(path) ); } /** * Processing stage indicator */ stage(message, type = 'info') { const symbols = { info: '▶', success: '✓', error: '✗', processing: '●' }; const colors = { info: chalk.blue, success: chalk.green, error: chalk.red, processing: chalk.cyan }; const symbol = symbols[type] || '▶'; const color = colors[type] || chalk.white; console.log(color(symbol), chalk.white(message)); } /** * Start a spinner for long operations */ startSpinner(text, type = 'dots') { this.stopSpinner(); // Stop any existing spinner this.spinner = ora({ text: chalk.cyan(text), spinner: type, color: 'cyan' }).start(); return this.spinner; } /** * Update spinner text */ updateSpinner(text) { if (this.spinner) { this.spinner.text = chalk.cyan(text); } } /** * Stop spinner with success */ succeedSpinner(text) { if (this.spinner) { this.spinner.succeed(chalk.green(text)); this.spinner = null; } } /** * Stop spinner with failure */ failSpinner(text) { if (this.spinner) { this.spinner.fail(chalk.red(text)); this.spinner = null; } } /** * Stop spinner without message */ stopSpinner() { if (this.spinner) { this.spinner.stop(); this.spinner = null; } } /** * Simple divider line */ divider() { console.log(chalk.dim('─'.repeat(process.stdout.columns || 80))); } /** * Blank line for spacing */ space() { console.log(); } /** * Final result display */ result(success, message, details = null) { if (success) { this.success(message, details); } else { this.error(message, details); } } /** * Setup instructions display */ setup(steps) { const content = steps.map((step, index) => `${chalk.bold.cyan(`${index + 1}.`)} ${step}` ).join('\n\n'); console.log(this._createBox( `${chalk.bold.blue('AUTO-GIT SETUP')}\n\n${content}`, { borderColor: 'blue', borderStyle: 'double', padding: 1 } )); } /** * Commit summary display */ commitSummary(message, hasRemote) { const operation = hasRemote ? 'Committed and Pushed' : 'Committed (Local Only)'; const content = `${chalk.bold.green(operation)}\n\n${chalk.white(message)}`; console.log(this._createBox(content, { borderColor: 'green', borderStyle: hasRemote ? 'double' : 'single' })); } } // Export singleton instance export default new Logger();