/** * TaskManagerPanel — displays and manages background tasks. * Uses real JSON API endpoint /api/tasks/:sessionId */ import { useState, useEffect, useCallback } from "react"; import { Play, Square, RefreshCw, Clock, CheckCircle, XCircle, AlertCircle, Loader2 } from "lucide-react"; interface Task { id: string; description: string; command?: string; status: "running" | "completed" | "stopped" | "failed"; createdAt: number; output: string; } interface TaskManagerPanelProps { sessionId: number; onSlashCommand: (command: string, args?: string) => Promise; } export function TaskManagerPanel({ sessionId }: TaskManagerPanelProps) { const [tasks, setTasks] = useState([]); const [loading, setLoading] = useState(false); const [expandedTask, setExpandedTask] = useState(null); const refreshTasks = useCallback(async () => { setLoading(true); try { const res = await fetch(`/api/tasks/${sessionId}`); if (res.ok) { const data = await res.json(); if (Array.isArray(data)) setTasks(data); } } catch { // ignore fetch errors } finally { setLoading(false); } }, [sessionId]); useEffect(() => { refreshTasks(); // Auto-refresh every 3 seconds while panel is open const interval = setInterval(refreshTasks, 3000); return () => clearInterval(interval); }, [refreshTasks]); const statusIcon = (status: string) => { switch (status) { case "running": return ; case "completed": return ; case "stopped": return ; case "failed": return ; default: return ; } }; return (

Background Tasks ({tasks.length})

{tasks.length === 0 ? (

No background tasks

Tasks created via TaskCreate tool will appear here

) : (
{tasks.map((task) => (
{expandedTask === task.id && (
                    {task.output || "(no output yet)"}
                  
)}
))}
)}
); }