import type React from 'react'; import { useState, useEffect } from 'react'; import { Button } from '@/components/ui/button'; import { Loader2, Play } from 'lucide-react'; import { PriorityBadge } from './PriorityBadge'; import type { TaskMasterTask } from '../../webview/types'; import { useVSCodeContext } from '../../webview/contexts/VSCodeContext'; interface TaskMetadataSidebarProps { currentTask: TaskMasterTask; tasks: TaskMasterTask[]; complexity: any; isSubtask: boolean; onStatusChange: (status: TaskMasterTask['status']) => void; onDependencyClick: (depId: string) => void; isRegenerating?: boolean; isAppending?: boolean; } export const TaskMetadataSidebar: React.FC = ({ currentTask, tasks, complexity, isSubtask, onStatusChange, onDependencyClick, isRegenerating = false, isAppending = false }) => { const { sendMessage } = useVSCodeContext(); const [isLoadingComplexity, setIsLoadingComplexity] = useState(false); const [mcpComplexityScore, setMcpComplexityScore] = useState< number | undefined >(undefined); const [isStartingTask, setIsStartingTask] = useState(false); // Get complexity score from task const currentComplexityScore = complexity?.score; // Display logic - use MCP score if available, otherwise use current score const displayComplexityScore = mcpComplexityScore !== undefined ? mcpComplexityScore : currentComplexityScore; // Fetch complexity from MCP when needed const fetchComplexityFromMCP = async (force = false) => { if (!currentTask || (!force && currentComplexityScore !== undefined)) { return; } setIsLoadingComplexity(true); try { const complexityResult = await sendMessage({ type: 'mcpRequest', tool: 'complexity_report', params: {} }); if (complexityResult?.data?.report?.complexityAnalysis) { const taskComplexity = complexityResult.data.report.complexityAnalysis.tasks?.find( (t: any) => t.id === currentTask.id ); if (taskComplexity) { setMcpComplexityScore(taskComplexity.complexityScore); } } } catch (error) { console.error('Failed to fetch complexity from MCP:', error); } finally { setIsLoadingComplexity(false); } }; // Handle running complexity analysis for a task const handleRunComplexityAnalysis = async () => { if (!currentTask) { return; } setIsLoadingComplexity(true); try { // Run complexity analysis on this specific task await sendMessage({ type: 'mcpRequest', tool: 'analyze_project_complexity', params: { ids: currentTask.id.toString(), research: false } }); // After analysis, fetch the updated complexity report setTimeout(() => { fetchComplexityFromMCP(true); }, 1000); } catch (error) { console.error('Failed to run complexity analysis:', error); } finally { setIsLoadingComplexity(false); } }; // Handle starting a task const handleStartTask = async () => { if (!currentTask || isStartingTask) { return; } setIsStartingTask(true); try { // Send message to extension to open terminal const result = await sendMessage({ type: 'openTerminal', data: { taskId: currentTask.id, taskTitle: currentTask.title } }); // Handle the response if (result && !result.success) { console.error('Terminal execution failed:', result.error); // The extension will show VS Code error notification and webview toast } else if (result && result.success) { console.log('Terminal started successfully:', result.terminalName); } } catch (error) { console.error('Failed to start task:', error); // This handles network/communication errors } finally { // Reset loading state setIsStartingTask(false); } }; // Effect to handle complexity on task change useEffect(() => { if (currentTask?.id) { setMcpComplexityScore(undefined); if (currentComplexityScore === undefined) { fetchComplexityFromMCP(); } } }, [currentTask?.id, currentComplexityScore]); return (

Properties

{/* Status */}
Status
{/* Priority */}
Priority
{/* Complexity Score */}
{isLoadingComplexity ? (
Loading...
) : displayComplexityScore !== undefined ? (
{displayComplexityScore}/10
= 7 ? 'bg-red-500/20' : displayComplexityScore >= 4 ? 'bg-yellow-500/20' : 'bg-green-500/20' }`} >
= 7 ? 'bg-red-500' : displayComplexityScore >= 4 ? 'bg-yellow-500' : 'bg-green-500' }`} style={{ width: `${(displayComplexityScore || 0) * 10}%` }} />
) : currentTask?.status === 'done' || currentTask?.status === 'deferred' || currentTask?.status === 'review' ? (
N/A
) : ( <>
No complexity score available
)}
{/* Dependencies */} {currentTask.dependencies && currentTask.dependencies.length > 0 && (

Dependencies

{currentTask.dependencies.map((depId) => { // Convert both to string for comparison since depId might be string or number const depTask = tasks.find( (t) => String(t.id) === String(depId) ); const fullTitle = `Task ${depId}: ${depTask?.title || 'Unknown Task'}`; const truncatedTitle = fullTitle.length > 40 ? fullTitle.substring(0, 37) + '...' : fullTitle; return (
onDependencyClick(depId)} title={fullTitle} > {truncatedTitle}
); })}
)} {/* Divider after Dependencies */} {currentTask.dependencies && currentTask.dependencies.length > 0 && (
)} {/* Start Task Button */}
); };