claude-git-hooks
Version:
Git hooks with Claude CLI for code analysis and automatic commit messages
142 lines (126 loc) • 4.64 kB
JavaScript
/**
* File: logger.js
* Purpose: Provides three-level logging system (user, debug, error)
*
* Key features:
* - User logs: Simple, colored messages for end users
* - Debug logs: Technical details with [file/class - method] format
* - Error logs: Full error context with [file/class - method] format
*
* Usage:
* import logger from './logger.js';
* logger.info('User message');
* logger.debug('file-name - methodName', 'Debug message', { data });
* logger.error('file-name - methodName', 'Error message', error);
*/
class Logger {
constructor({ debugMode = false } = {}) {
this.debugMode = debugMode;
this.colors = {
reset: '\x1b[0m',
red: '\x1b[31m',
green: '\x1b[32m',
yellow: '\x1b[33m',
blue: '\x1b[34m',
gray: '\x1b[90m'
};
}
/**
* User-facing informational message (always shown)
* Why: Provides feedback about what the tool is doing
*
* @param {string} message - Simple message for end users
*/
info(message) {
console.log(`${this.colors.blue}ℹ️ ${message}${this.colors.reset}`);
}
/**
* User-facing success message (always shown)
* Why: Confirms successful operations to the user
*
* @param {string} message - Success message
*/
success(message) {
console.log(`${this.colors.green}✅ ${message}${this.colors.reset}`);
}
/**
* User-facing warning message (always shown)
* Why: Alerts user to non-critical issues
*
* @param {string} message - Warning message
*/
warning(message) {
console.log(`${this.colors.yellow}⚠️ ${message}${this.colors.reset}`);
}
/**
* Developer-facing debug message (only in debug mode)
* Why: Provides technical details for troubleshooting without cluttering normal output
*
* Format: [DEBUG timestamp] [context] message
* Context format: "file/class - method"
*
* @param {string} context - Location identifier (e.g., "file-analyzer - analyzeFile")
* @param {string} message - Debug message
* @param {Object} data - Optional data to log as JSON
*/
debug(context, message, data = {}) {
if (!this.debugMode) return;
const timestamp = new Date().toISOString();
console.log(
`${this.colors.gray}[DEBUG ${timestamp}] [${context}] ${message}${this.colors.reset}`
);
if (Object.keys(data).length > 0) {
console.log(this.colors.gray, JSON.stringify(data, null, 2), this.colors.reset);
}
}
/**
* Error message with full context (always shown)
* Why: Provides complete error information for debugging issues
*
* Format: ❌ [context] message
* Context format: "file/class - method"
*
* @param {string} context - Location identifier (e.g., "file-analyzer - analyzeFile")
* @param {string} message - Error message
* @param {Error} error - Optional error object with stack trace and context
*/
error(context, message, error = null) {
console.error(`${this.colors.red}❌ [${context}] ${message}${this.colors.reset}`);
if (error) {
console.error(`${this.colors.red}Error details:${this.colors.reset}`, error.message || error);
// Show stack trace only in debug mode to avoid overwhelming users
if (error.stack && this.debugMode) {
console.error(`${this.colors.gray}Stack trace:${this.colors.reset}`);
console.error(error.stack);
}
// Log additional context if available (custom error properties)
if (error.context) {
console.error(`${this.colors.gray}Context:${this.colors.reset}`, error.context);
}
// Log cause chain if available (Error.cause from Node.js 16.9+)
if (error.cause) {
console.error(`${this.colors.gray}Caused by:${this.colors.reset}`, error.cause);
}
}
}
/**
* Set debug mode dynamically
* Why: Allows enabling debug mode at runtime
*
* @param {boolean} enabled - Whether to enable debug mode
*/
setDebugMode(enabled) {
this.debugMode = enabled;
}
/**
* Check if debug mode is enabled
*
* @returns {boolean} True if debug mode is active
*/
isDebugMode() {
return this.debugMode;
}
}
// Export singleton instance
// Why: Single logger instance ensures consistent debug mode across entire application
export default new Logger();