Files
claude-task-master/apps/extension/src/webview/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

156 lines
3.8 KiB
TypeScript

/**
* Webview Logger Utility
* Provides conditional logging based on environment
*/
type LogLevel = 'log' | 'warn' | 'error' | 'debug' | 'info';
interface LogEntry {
level: LogLevel;
message: string;
data?: any;
timestamp: number;
}
class WebviewLogger {
private static instance: WebviewLogger;
private enabled: boolean;
private logHistory: LogEntry[] = [];
private maxHistorySize = 100;
private constructor() {
// Enable logging in development, disable in production
// Check for development mode via various indicators
this.enabled = this.isDevelopment();
}
static getInstance(): WebviewLogger {
if (!WebviewLogger.instance) {
WebviewLogger.instance = new WebviewLogger();
}
return WebviewLogger.instance;
}
private isDevelopment(): boolean {
// Check various indicators for development mode
// VS Code webviews don't have process.env, so we check other indicators
return (
// Check if running in localhost (development server)
window.location.hostname === 'localhost' ||
// Check for development query parameter
window.location.search.includes('debug=true') ||
// Check for VS Code development mode indicator
(window as any).__VSCODE_DEV_MODE__ === true ||
// Default to false in production
false
);
}
private addToHistory(entry: LogEntry): void {
this.logHistory.push(entry);
if (this.logHistory.length > this.maxHistorySize) {
this.logHistory.shift();
}
}
private logMessage(level: LogLevel, message: string, ...args: any[]): void {
const entry: LogEntry = {
level,
message,
data: args.length > 0 ? args : undefined,
timestamp: Date.now()
};
this.addToHistory(entry);
if (!this.enabled) {
return;
}
// Format the message with timestamp
const timestamp = new Date().toISOString();
const prefix = `[${timestamp}] [${level.toUpperCase()}]`;
// Use appropriate console method
switch (level) {
case 'error':
console.error(prefix, message, ...args);
break;
case 'warn':
console.warn(prefix, message, ...args);
break;
case 'debug':
console.debug(prefix, message, ...args);
break;
case 'info':
console.info(prefix, message, ...args);
break;
default:
console.log(prefix, message, ...args);
}
}
log(message: string, ...args: any[]): void {
this.logMessage('log', message, ...args);
}
error(message: string, ...args: any[]): void {
// Always log errors, even in production
const entry: LogEntry = {
level: 'error',
message,
data: args.length > 0 ? args : undefined,
timestamp: Date.now()
};
this.addToHistory(entry);
console.error(`[${new Date().toISOString()}] [ERROR]`, message, ...args);
}
warn(message: string, ...args: any[]): void {
this.logMessage('warn', message, ...args);
}
debug(message: string, ...args: any[]): void {
this.logMessage('debug', message, ...args);
}
info(message: string, ...args: any[]): void {
this.logMessage('info', message, ...args);
}
// Enable/disable logging dynamically
setEnabled(enabled: boolean): void {
this.enabled = enabled;
if (enabled) {
console.log('[WebviewLogger] Logging enabled');
}
}
// Get log history (useful for debugging)
getHistory(): LogEntry[] {
return [...this.logHistory];
}
// Clear log history
clearHistory(): void {
this.logHistory = [];
}
// Export logs as string (useful for bug reports)
exportLogs(): string {
return this.logHistory
.map((entry) => {
const timestamp = new Date(entry.timestamp).toISOString();
const data = entry.data ? JSON.stringify(entry.data) : '';
return `[${timestamp}] [${entry.level.toUpperCase()}] ${entry.message} ${data}`;
})
.join('\n');
}
}
// Export singleton instance
export const logger = WebviewLogger.getInstance();
// Export type for use in other files
export type { WebviewLogger };