import { useState, useEffect, useCallback } from 'react'; import { createLogger } from '@automaker/utils/logger'; import { Bot, Folder, Loader2, RefreshCw, Square, Activity, FileText } from 'lucide-react'; import { getElectronAPI, RunningAgent } from '@/lib/electron'; import { useAppStore } from '@/store/app-store'; import { Button } from '@/components/ui/button'; import { cn } from '@/lib/utils'; import { useNavigate } from '@tanstack/react-router'; import { AgentOutputModal } from './board-view/dialogs/agent-output-modal'; const logger = createLogger('RunningAgentsView'); export function RunningAgentsView() { const [runningAgents, setRunningAgents] = useState([]); const [loading, setLoading] = useState(true); const [refreshing, setRefreshing] = useState(false); const [selectedAgent, setSelectedAgent] = useState(null); const { setCurrentProject, projects } = useAppStore(); const navigate = useNavigate(); const fetchRunningAgents = useCallback(async () => { try { const api = getElectronAPI(); if (api.runningAgents) { const result = await api.runningAgents.getAll(); if (result.success && result.runningAgents) { setRunningAgents(result.runningAgents); } } } catch (error) { logger.error('Error fetching running agents:', error); } finally { setLoading(false); setRefreshing(false); } }, []); // Initial fetch useEffect(() => { fetchRunningAgents(); }, [fetchRunningAgents]); // Auto-refresh every 2 seconds useEffect(() => { const interval = setInterval(() => { fetchRunningAgents(); }, 2000); return () => clearInterval(interval); }, [fetchRunningAgents]); // Subscribe to auto-mode events to update in real-time useEffect(() => { const api = getElectronAPI(); if (!api.autoMode) return; const unsubscribe = api.autoMode.onEvent((event) => { // When a feature completes or errors, refresh the list if (event.type === 'auto_mode_feature_complete' || event.type === 'auto_mode_error') { fetchRunningAgents(); } }); return () => { unsubscribe(); }; }, [fetchRunningAgents]); const handleRefresh = useCallback(() => { setRefreshing(true); fetchRunningAgents(); }, [fetchRunningAgents]); const handleStopAgent = useCallback( async (featureId: string) => { try { const api = getElectronAPI(); if (api.autoMode) { await api.autoMode.stopFeature(featureId); // Refresh list after stopping fetchRunningAgents(); } } catch (error) { logger.error('Error stopping agent:', error); } }, [fetchRunningAgents] ); const handleNavigateToProject = useCallback( (agent: RunningAgent) => { // Find the project by path const project = projects.find((p) => p.path === agent.projectPath); if (project) { setCurrentProject(project); navigate({ to: '/board' }); } }, [projects, setCurrentProject, navigate] ); const handleViewLogs = useCallback((agent: RunningAgent) => { setSelectedAgent(agent); }, []); if (loading) { return (
); } return (
{/* Header */}

Running Agents

{runningAgents.length === 0 ? 'No agents currently running' : `${runningAgents.length} agent${runningAgents.length === 1 ? '' : 's'} running across all projects`}

{/* Content */} {runningAgents.length === 0 ? (

No Running Agents

Agents will appear here when they are actively working on features. Start an agent from the Kanban board by dragging a feature to "In Progress".

) : (
{runningAgents.map((agent) => (
{/* Status indicator */}
{/* Agent info */}
{agent.title || agent.featureId} {agent.isAutoMode && ( AUTO )}
{agent.description && (

{agent.description}

)}
{/* Actions */}
))}
)} {/* Agent Output Modal */} {selectedAgent && ( setSelectedAgent(null)} projectPath={selectedAgent.projectPath} featureDescription={ selectedAgent.description || selectedAgent.title || selectedAgent.featureId } featureId={selectedAgent.featureId} featureStatus="running" /> )}
); }