// ======================================== // LiteTaskDetailPage Component // ======================================== // Lite task detail page with multi-tab task view supporting: // - Lite-Plan/Lite-Fix: Tasks, Plan, Diagnoses, Context, Summary tabs // - Multi-CLI: Tasks, Discussion, Context, Summary tabs // - Context Package parsing with collapsible sections // - Exploration packages with multiple analysis angles // - Flowchart visualization for implementation steps import * as React from 'react'; import { useParams, useNavigate } from 'react-router-dom'; import { useIntl } from 'react-intl'; import { ArrowLeft, FileEdit, Wrench, XCircle, CheckCircle, Code, Zap, ListTodo, Package, FileCode, Settings, BookOpen, Search, Folder, MessageSquare, FileText, ChevronRight, Ruler, Stethoscope, } from 'lucide-react'; import { useLiteTaskSession } from '@/hooks/useLiteTasks'; import { Flowchart } from '@/components/shared/Flowchart'; import { Button } from '@/components/ui/Button'; import { Badge } from '@/components/ui/Badge'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/Card'; import { TabsNavigation } from '@/components/ui/TabsNavigation'; import { Collapsible, CollapsibleTrigger, CollapsibleContent } from '@/components/ui/Collapsible'; // ======================================== // Type Definitions // ======================================== type SessionType = 'lite-plan' | 'lite-fix' | 'multi-cli-plan'; type LitePlanTab = 'tasks' | 'plan' | 'diagnoses' | 'context' | 'summary'; type MultiCliTab = 'tasks' | 'discussion' | 'context'; type TaskTabValue = 'task' | 'context'; // Exploration Structure interface Exploration { name: string; path: string; content?: string; } // ======================================== // Main Component // ======================================== /** * LiteTaskDetailPage component - Display single lite task session with multi-tab view * Supports: * - Lite-Plan/Lite-Fix: Tasks, Plan, Diagnoses, Context, Summary tabs * - Multi-CLI: Tasks, Discussion, Context, Summary tabs * - Context Package parsing with collapsible sections * - Exploration packages with multiple analysis angles * - Flowchart visualization for implementation steps */ export function LiteTaskDetailPage() { const { sessionId } = useParams<{ sessionId: string }>(); const navigate = useNavigate(); const { formatMessage } = useIntl(); // Session type state const [sessionType, setSessionType] = React.useState('lite-plan'); // Fetch session data const { session, isLoading, error, refetch } = useLiteTaskSession(sessionId, sessionType); // Tab states const [litePlanActiveTab, setLitePlanActiveTab] = React.useState('tasks'); const [multiCliActiveTab, setMultiCliActiveTab] = React.useState('tasks'); const [activeTaskTabs, setActiveTaskTabs] = React.useState>({}); // Detect session type from data React.useEffect(() => { if (session?.type) { setSessionType(session.type); } }, [session]); const handleBack = () => { navigate('/lite-tasks'); }; const handleTaskTabChange = (taskId: string, tab: TaskTabValue) => { setActiveTaskTabs(prev => ({ ...prev, [taskId]: tab })); }; // Loading state if (isLoading) { return (
); } // Error state if (error) { return (

{formatMessage({ id: 'common.errors.loadFailed' })}

{error.message}

); } // Not found state if (!session) { return (

{formatMessage({ id: 'liteTasksDetail.notFound.title' })}

{formatMessage({ id: 'liteTasksDetail.notFound.message' })}

); } const isLitePlan = session.type === 'lite-plan'; const isLiteFix = session.type === 'lite-fix'; const isMultiCli = session.type === 'multi-cli-plan'; return (
{/* Header */}

{session.title || session.id || session.session_id}

{(session.title || (session.session_id && session.session_id !== session.id)) && (

{session.id || session.session_id}

)}
{isLitePlan ? : isLiteFix ? : } {formatMessage({ id: isLitePlan ? 'liteTasks.type.plan' : isLiteFix ? 'liteTasks.type.fix' : 'liteTasks.type.multiCli' }) as React.ReactNode}
{/* Session Type-Specific Tabs */} {isMultiCli ? ( setMultiCliActiveTab(v as MultiCliTab)} tabs={[ { value: 'tasks', label: formatMessage({ id: 'liteTasksDetail.tabs.tasks' }), icon: , }, { value: 'discussion', label: formatMessage({ id: 'liteTasksDetail.tabs.discussion' }), icon: , }, { value: 'context', label: formatMessage({ id: 'liteTasksDetail.tabs.context' }), icon: , }, { value: 'summary', label: formatMessage({ id: 'liteTasksDetail.tabs.summary' }), icon: , }, ]} /> ) : ( setLitePlanActiveTab(v as LitePlanTab)} tabs={[ { value: 'tasks', label: formatMessage({ id: 'liteTasksDetail.tabs.tasks' }), icon: , }, { value: 'plan', label: formatMessage({ id: 'liteTasksDetail.tabs.plan' }), icon: , }, ...(isLiteFix ? [ { value: 'diagnoses' as const, label: formatMessage({ id: 'liteTasksDetail.tabs.diagnoses' }), icon: , }, ] : []), { value: 'context', label: formatMessage({ id: 'liteTasksDetail.tabs.context' }), icon: , }, { value: 'summary', label: formatMessage({ id: 'liteTasksDetail.tabs.summary' }), icon: , }, ]} /> )} {/* Task List with Multi-Tab Content */}
{session.tasks?.map((task, index) => { const taskId = task.task_id || task.id || `T${index + 1}`; const activeTaskTab = activeTaskTabs[taskId] || 'task'; const hasFlowchart = task.flow_control?.implementation_approach && task.flow_control.implementation_approach.length > 0; return ( {/* Task Header */}
{/* Left: Task ID, Title, Description */}
{taskId} {task.priority && ( {task.priority} )} {hasFlowchart && ( Flowchart )}

{task.title || 'Untitled Task'}

{task.description && (

{task.description}

)}
{/* Right: Meta Information */}
{/* Dependencies - show task IDs */} {task.context?.depends_on && task.context.depends_on.length > 0 && (
{task.context.depends_on.map((depId, idx) => ( {depId} ))}
)} {/* Target Files Count */} {task.flow_control?.target_files && task.flow_control.target_files.length > 0 && ( {task.flow_control.target_files.length} file{task.flow_control.target_files.length > 1 ? 's' : ''} )} {/* Implementation Steps Count */} {task.flow_control?.implementation_approach && task.flow_control.implementation_approach.length > 0 && ( {task.flow_control.implementation_approach.length} step{task.flow_control.implementation_approach.length > 1 ? 's' : ''} )}
{/* Multi-Tab Content */}
handleTaskTabChange(taskId, v as TaskTabValue)} tabs={[ { value: 'task', label: 'Task', icon: , }, { value: 'context', label: 'Context', icon: , }, ]} /> {/* Task Tab - Implementation Details */} {activeTaskTab === 'task' && (
{/* Flowchart */} {hasFlowchart && task.flow_control && (
Implementation Flow
)} {/* Target Files */} {task.flow_control?.target_files && task.flow_control.target_files.length > 0 && (
Target Files
{task.flow_control.target_files.map((file, idx) => { const displayPath = typeof file === 'string' ? file : (file.path || file.name || 'Unknown'); return ( {displayPath} ); })}
)} {/* Dependencies */} {task.context?.depends_on && task.context.depends_on.length > 0 && (
Dependencies
{task.context.depends_on.map((dep, idx) => ( {dep} ))}
)}
)} {/* Context Tab - Planning Context */} {activeTaskTab === 'context' && (
{/* Focus Paths */} {task.context?.focus_paths && task.context.focus_paths.length > 0 && (
Focus Paths
{task.context.focus_paths.map((path, idx) => ( {path} ))}
)} {/* Acceptance Criteria */} {task.context?.acceptance && task.context.acceptance.length > 0 && (
Acceptance Criteria
    {task.context.acceptance.map((criteria, idx) => (
  • {idx + 1}. {criteria}
  • ))}
)} {/* Tech Stack from Session Metadata */} {!!session.metadata?.tech_stack && (
Tech Stack
{(session.metadata.tech_stack as string[]).map((tech, idx) => ( {tech} ))}
)} {/* Conventions from Session Metadata */} {!!session.metadata?.conventions && (
Conventions
    {(session.metadata.conventions as string[]).map((conv, idx) => (
  • {conv}
  • ))}
)}
)}
); })}
{/* Session-Level Explorations (if available) */} {!!session.metadata?.explorations && ( Explorations {(session.metadata.explorations as Exploration[]).length}
{(session.metadata.explorations as Exploration[]).map((exp, idx) => ( {exp.name} {exp.content && ( Has Content )} {exp.content ? (
{exp.content}
) : (
No content available for this exploration.
)}
))}
)}
); } export default LiteTaskDetailPage;