Files
claude-task-master/apps/extension/src/utils/logger.ts
DavidMaliglowka 64302dc191 feat(extension): complete VS Code extension with kanban board interface (#997)
---------
Co-authored-by: DavidMaliglowka <13022280+DavidMaliglowka@users.noreply.github.com>
Co-authored-by: Ralph Khreish <35776126+Crunchyman-ralph@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-08-01 14:04:22 +02:00

105 lines
2.8 KiB
TypeScript

import * as vscode from 'vscode';
/**
* Logger interface for dependency injection
*/
export interface ILogger {
log(message: string, ...args: any[]): void;
error(message: string, ...args: any[]): void;
warn(message: string, ...args: any[]): void;
debug(message: string, ...args: any[]): void;
show(): void;
dispose(): void;
}
/**
* Logger that outputs to VS Code's output channel instead of console
* This prevents interference with MCP stdio communication
*/
export class ExtensionLogger implements ILogger {
private static instance: ExtensionLogger;
private outputChannel: vscode.OutputChannel;
private debugMode: boolean;
private constructor() {
this.outputChannel = vscode.window.createOutputChannel('TaskMaster');
const config = vscode.workspace.getConfiguration('taskmaster');
this.debugMode = config.get<boolean>('debug.enableLogging', true);
}
static getInstance(): ExtensionLogger {
if (!ExtensionLogger.instance) {
ExtensionLogger.instance = new ExtensionLogger();
}
return ExtensionLogger.instance;
}
log(message: string, ...args: any[]): void {
if (!this.debugMode) {
return;
}
const timestamp = new Date().toISOString();
const formattedMessage = this.formatMessage(message, args);
this.outputChannel.appendLine(`[${timestamp}] ${formattedMessage}`);
}
error(message: string, ...args: any[]): void {
const timestamp = new Date().toISOString();
const formattedMessage = this.formatMessage(message, args);
this.outputChannel.appendLine(`[${timestamp}] ERROR: ${formattedMessage}`);
}
warn(message: string, ...args: any[]): void {
if (!this.debugMode) {
return;
}
const timestamp = new Date().toISOString();
const formattedMessage = this.formatMessage(message, args);
this.outputChannel.appendLine(`[${timestamp}] WARN: ${formattedMessage}`);
}
debug(message: string, ...args: any[]): void {
if (!this.debugMode) {
return;
}
const timestamp = new Date().toISOString();
const formattedMessage = this.formatMessage(message, args);
this.outputChannel.appendLine(`[${timestamp}] DEBUG: ${formattedMessage}`);
}
private formatMessage(message: string, args: any[]): string {
if (args.length === 0) {
return message;
}
// Convert objects to JSON for better readability
const formattedArgs = args.map((arg) => {
if (typeof arg === 'object' && arg !== null) {
try {
return JSON.stringify(arg, null, 2);
} catch {
return String(arg);
}
}
return String(arg);
});
return `${message} ${formattedArgs.join(' ')}`;
}
show(): void {
this.outputChannel.show();
}
dispose(): void {
this.outputChannel.dispose();
}
setDebugMode(enabled: boolean): void {
this.debugMode = enabled;
}
}
// Export a singleton instance for convenience
export const logger = ExtensionLogger.getInstance();