UNPKG

remcode

Version:

Turn your AI assistant into a codebase expert. Intelligent code analysis, semantic search, and software engineering guidance through MCP integration.

312 lines (311 loc) 9.75 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.logger = exports.defaultLoggerConfig = exports.LogLevelNames = exports.LogLevel = void 0; exports.configureLogger = configureLogger; exports.createLogger = createLogger; exports.getLogger = getLogger; exports.logError = logError; exports.getLogLevel = getLogLevel; exports.setLogLevel = setLogLevel; exports.enableFileLogging = enableFileLogging; exports.disableFileLogging = disableFileLogging; const fs = __importStar(require("fs")); const path = __importStar(require("path")); const util = __importStar(require("util")); // Import chalk with compatibility for both CommonJS and ES modules let chalk; try { chalk = require('chalk'); } catch (error) { // Fallback for when chalk is not available or in ES module format chalk = { gray: (text) => text, magenta: (text) => text, blue: (text) => text, yellow: (text) => text, red: (text) => text, white: (text) => text, bgRed: { white: (text) => text } }; } /** * Log levels */ var LogLevel; (function (LogLevel) { LogLevel[LogLevel["TRACE"] = 0] = "TRACE"; LogLevel[LogLevel["DEBUG"] = 1] = "DEBUG"; LogLevel[LogLevel["INFO"] = 2] = "INFO"; LogLevel[LogLevel["WARN"] = 3] = "WARN"; LogLevel[LogLevel["ERROR"] = 4] = "ERROR"; LogLevel[LogLevel["FATAL"] = 5] = "FATAL"; LogLevel[LogLevel["SILENT"] = 6] = "SILENT"; })(LogLevel || (exports.LogLevel = LogLevel = {})); /** * Log level names for display */ exports.LogLevelNames = { [LogLevel.TRACE]: 'TRACE', [LogLevel.DEBUG]: 'DEBUG', [LogLevel.INFO]: 'INFO', [LogLevel.WARN]: 'WARN', [LogLevel.ERROR]: 'ERROR', [LogLevel.FATAL]: 'FATAL', [LogLevel.SILENT]: 'SILENT' }; /** * Default logger configuration */ exports.defaultLoggerConfig = { level: process.env.NODE_ENV === 'production' ? LogLevel.INFO : LogLevel.DEBUG, colors: process.stdout.isTTY, timestamp: true, logToFile: false, logFormat: 'text' }; /** * Global logger configuration */ let globalConfig = { ...exports.defaultLoggerConfig }; /** * Configure global logger settings */ function configureLogger(config) { globalConfig = { ...globalConfig, ...config }; // Set up file logging if enabled if (globalConfig.logToFile && globalConfig.logFilePath) { const dir = path.dirname(globalConfig.logFilePath); if (!fs.existsSync(dir)) { fs.mkdirSync(dir, { recursive: true }); } } } /** * Format a log record for output */ function formatLogRecord(record, config) { if (config.logFormat === 'json') { return JSON.stringify({ timestamp: record.timestamp.toISOString(), level: exports.LogLevelNames[record.level], name: record.name, message: record.message, ...record.metadata, ...(record.error ? { error: { name: record.error.name, message: record.error.message, stack: record.error.stack } } : {}) }); } // Text format let output = ''; if (config.timestamp) { const timestamp = record.timestamp.toISOString(); output += config.colors ? chalk.gray(timestamp) + ' ' : timestamp + ' '; } const levelName = exports.LogLevelNames[record.level]; if (config.colors) { let levelColor; switch (record.level) { case LogLevel.TRACE: levelColor = chalk.magenta; break; case LogLevel.DEBUG: levelColor = chalk.gray; break; case LogLevel.INFO: levelColor = chalk.blue; break; case LogLevel.WARN: levelColor = chalk.yellow; break; case LogLevel.ERROR: levelColor = chalk.red; break; case LogLevel.FATAL: levelColor = chalk.bgRed.white; break; default: levelColor = chalk.white; } output += `[${levelColor(levelName)}] `; } else { output += `[${levelName}] `; } output += `${record.name}: ${record.message}`; if (record.metadata && Object.keys(record.metadata).length > 0) { output += ' ' + util.inspect(record.metadata, { colors: config.colors, depth: 4 }); } if (record.error) { output += '\n' + (config.colors ? chalk.red(record.error.stack || record.error.message) : (record.error.stack || record.error.message)); } return output; } /** * Write a log record to the configured outputs */ function writeLogRecord(record, config) { // Skip if level is below configured level if (record.level < config.level) return; const formattedLog = formatLogRecord(record, config); // Write to console if (record.level >= LogLevel.ERROR) { console.error(formattedLog); } else if (record.level >= LogLevel.WARN) { console.warn(formattedLog); } else { console.log(formattedLog); } // Write to file if enabled if (config.logToFile && config.logFilePath) { try { fs.appendFileSync(config.logFilePath, formattedLog + '\n', 'utf8'); } catch (error) { console.error(`Failed to write to log file: ${error instanceof Error ? error.message : String(error)}`); } } } /** * Create a logger instance */ function createLogger(name, baseMetadata = {}) { const createLogMethod = (level) => { return (message, errorOrMetadata, metadata) => { let error; let combinedMetadata; // Handle flexible parameters if (errorOrMetadata instanceof Error) { error = errorOrMetadata; combinedMetadata = { ...baseMetadata, ...metadata }; } else if (errorOrMetadata && typeof errorOrMetadata === 'object') { combinedMetadata = { ...baseMetadata, ...errorOrMetadata }; } else { combinedMetadata = { ...baseMetadata }; } const record = { timestamp: new Date(), level, name, message, metadata: combinedMetadata, error }; writeLogRecord(record, globalConfig); }; }; return { trace: createLogMethod(LogLevel.TRACE), debug: createLogMethod(LogLevel.DEBUG), info: createLogMethod(LogLevel.INFO), warn: createLogMethod(LogLevel.WARN), error: createLogMethod(LogLevel.ERROR), fatal: createLogMethod(LogLevel.FATAL), log: (level, message, error, metadata) => { const combinedMetadata = { ...baseMetadata, ...metadata }; const record = { timestamp: new Date(), level, name, message, metadata: combinedMetadata, error }; writeLogRecord(record, globalConfig); }, child: (childName) => createLogger(`${name}:${childName}`, baseMetadata), withMetadata: (additionalMetadata) => { return createLogger(name, { ...baseMetadata, ...additionalMetadata }); } }; } /** * Global logger instance */ exports.logger = createLogger('Remcode'); /** * Get a logger instance for a specific component */ function getLogger(component) { return createLogger(component); } /** * Log an error with stack trace */ function logError(error, context) { const component = context || 'Error'; const logger = getLogger(component); logger.error('An error occurred', error); } /** * Get the current log level */ function getLogLevel() { return globalConfig.level; } /** * Set the current log level */ function setLogLevel(level) { globalConfig.level = level; } /** * Enable file logging */ function enableFileLogging(filePath, format = 'text') { configureLogger({ logToFile: true, logFilePath: filePath, logFormat: format }); } /** * Disable file logging */ function disableFileLogging() { configureLogger({ logToFile: false }); }