--------- 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>
105 lines
2.8 KiB
TypeScript
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();
|