// Auto-extracted from tasks-manager.js (verbatim) — augments TasksManager.prototype. Loaded after the base. Object.assign(TasksManager.prototype, { async viewTaskLogs(taskId) { // Open logs in a modal or new view const task = this.tasks.find(t => t.id === taskId); if (!task) return; // Load full logs for modal const fullLogs = await this.taskManager.readFullTaskLog(taskId); // Create modal with streaming logs const modal = document.createElement('div'); modal.className = 'task-logs-modal'; modal.innerHTML = `
`; document.body.appendChild(modal); // Update line count const lineCount = fullLogs.split('\n').length; const lineCountElement = modal.querySelector('.log-line-count'); if (lineCountElement) { lineCountElement.textContent = `(${lineCount} lines)`; } // Start streaming if task is running if (task.status === 'running' || task.status === 'queued') { this.startLogStreaming(taskId, modal); } // Store streaming controller this.activeLogStreams = this.activeLogStreams || new Map(); }, toggleLogStreaming(taskId) { const streamData = this.activeLogStreams?.get(taskId); if (!streamData) return; const toggleButton = document.getElementById(`log-toggle-${taskId}`); const statusIndicator = document.getElementById(`log-status-${taskId}`); if (streamData.isPaused) { // Resume streaming streamData.isPaused = false; if (toggleButton) toggleButton.textContent = '⏸️ Pause'; if (statusIndicator) { statusIndicator.textContent = '🔴 Live'; statusIndicator.className = 'status-indicator live'; } } else { // Pause streaming streamData.isPaused = true; if (toggleButton) toggleButton.textContent = '▶️ Resume'; if (statusIndicator) { statusIndicator.textContent = '⏸️ Paused'; statusIndicator.className = 'status-indicator paused'; } } }, });