// ========================================
// LiteContextContent Component
// ========================================
// Extracted from LiteTasksPage - renders context data sections for lite sessions
import * as React from 'react';
import { useIntl } from 'react-intl';
import {
Compass,
Stethoscope,
FolderOpen,
FileText,
Package,
ChevronDown,
ChevronRight,
AlertTriangle,
Code,
} from 'lucide-react';
import { Badge } from '@/components/ui/Badge';
import { Card, CardContent } from '@/components/ui/Card';
import {
ExplorationsSection,
AssetsCard,
ConflictDetectionCard,
} from '@/components/session-detail/context';
import type { ExplorationsData } from '@/components/session-detail/context/ExplorationsSection';
import type {
LiteSessionContext,
LiteDiagnosisItem,
LiteTaskSession,
} from '@/lib/api';
/**
* Convert diagnoses from either `items[]` (lite-scanner) or `data{}` (session-routes) format
* into a uniform LiteDiagnosisItem array.
*/
function getDiagnosisItems(diagnoses: LiteSessionContext['diagnoses']): LiteDiagnosisItem[] {
if (!diagnoses) return [];
if (diagnoses.items?.length) return diagnoses.items;
if (diagnoses.data) {
return Object.entries(diagnoses.data).map(([angle, content]) => ({
id: angle,
title: angle.replace(/-/g, ' ').replace(/^\w/, c => c.toUpperCase()),
...(typeof content === 'object' && content !== null ? content : {}),
})) as LiteDiagnosisItem[];
}
return [];
}
/**
* ContextSection - Collapsible section wrapper for context items
*/
function ContextSection({
icon,
title,
badge,
children,
defaultOpen = true,
}: {
icon: React.ReactNode;
title: string;
badge?: string;
children: React.ReactNode;
defaultOpen?: boolean;
}) {
const [isOpen, setIsOpen] = React.useState(defaultOpen);
return (
e.stopPropagation()}>
{isOpen && (
{children}
)}
);
}
/**
* ContextContent - Renders the context data sections for a lite session
*/
function ContextContent({
contextData,
session,
}: {
contextData: LiteSessionContext;
session: LiteTaskSession;
}) {
const { formatMessage } = useIntl();
const plan = session.plan || {};
const ctx = contextData.context;
const hasExplorations = !!(contextData.explorations?.manifest);
const diagnosisItems = getDiagnosisItems(contextData.diagnoses);
const hasDiagnoses = !!(contextData.diagnoses?.manifest || diagnosisItems.length > 0);
const hasContext = !!ctx;
const hasFocusPaths = !!(plan.focus_paths as string[] | undefined)?.length;
const hasSummary = !!(plan.summary as string | undefined);
const hasAnyContent = hasExplorations || hasDiagnoses || hasContext || hasFocusPaths || hasSummary;
if (!hasAnyContent) {
return (
{/* Explorations Section */}
{hasExplorations && (
}
title={formatMessage({ id: 'liteTasks.contextPanel.explorations' })}
badge={
contextData.explorations?.manifest?.exploration_count
? formatMessage(
{ id: 'liteTasks.contextPanel.explorationsCount' },
{ count: contextData.explorations.manifest.exploration_count }
)
: undefined
}
>
{!!contextData.explorations?.manifest?.task_description && (
{formatMessage({ id: 'liteTasks.contextPanel.taskDescription' })}:
{' '}
{String(contextData.explorations.manifest.task_description)}
)}
{!!contextData.explorations?.manifest?.complexity && (
{formatMessage({ id: 'liteTasks.contextPanel.complexity' })}:
{' '}
{String(contextData.explorations.manifest.complexity)}
)}
{contextData.explorations?.data && (
{Object.keys(contextData.explorations.data).map((angle) => (
{angle.replace(/-/g, ' ')}
))}
)}
)}
{/* Diagnoses Section */}
{hasDiagnoses && (
}
title={formatMessage({ id: 'liteTasks.contextPanel.diagnoses' })}
badge={
diagnosisItems.length > 0
? formatMessage(
{ id: 'liteTasks.contextPanel.diagnosesCount' },
{ count: diagnosisItems.length }
)
: undefined
}
>
{diagnosisItems.map((item, i) => (
{item.title || item.description || `Diagnosis ${i + 1}`}
))}
)}
{/* Context Package Section */}
{hasContext && ctx && (
}
title={formatMessage({ id: 'liteTasks.contextPanel.contextPackage' })}
>
{ctx.task_description && (
{formatMessage({ id: 'liteTasks.contextPanel.taskDescription' })}:{' '}
{ctx.task_description}
)}
{ctx.constraints && ctx.constraints.length > 0 && (
{formatMessage({ id: 'liteTasks.contextPanel.constraints' })}:
{ctx.constraints.map((c, i) => (
•
{c}
))}
)}
{ctx.focus_paths && ctx.focus_paths.length > 0 && (
{formatMessage({ id: 'liteTasks.contextPanel.focusPaths' })}:{' '}
{ctx.focus_paths.map((p, i) => (
{p}
))}
)}
{ctx.relevant_files && ctx.relevant_files.length > 0 && (
{formatMessage({ id: 'liteTasks.contextPanel.relevantFiles' })}:{' '}
{ctx.relevant_files.length}
{ctx.relevant_files.map((f, i) => {
const filePath = typeof f === 'string' ? f : f.path;
const reason = typeof f === 'string' ? undefined : f.reason;
return (
{i + 1}.
{filePath}
{reason && (
({reason})
)}
);
})}
)}
{ctx.dependencies && ctx.dependencies.length > 0 && (
{formatMessage({ id: 'liteTasks.contextPanel.dependencies' })}:
{ctx.dependencies.map((d, i) => {
const depInfo = typeof d === 'string'
? { name: d, type: '', version: '' }
: d as { name: string; type?: string; version?: string };
return (
{depInfo.name}
{depInfo.version && @{depInfo.version}}
);
})}
)}
{ctx.session_id && (
{formatMessage({ id: 'liteTasks.contextPanel.sessionId' })}:{' '}
{ctx.session_id}
)}
{ctx.metadata && (
{formatMessage({ id: 'liteTasks.contextPanel.metadata' })}:
{Object.entries(ctx.metadata).map(([k, v]) => (
{k}:
{String(v)}
))}
)}
)}
{/* Conflict Risks (simple inline list) */}
{ctx?.conflict_risks && Array.isArray(ctx.conflict_risks) && ctx.conflict_risks.length > 0 && (
}
title={formatMessage({ id: 'liteTasks.contextPanel.conflictRisks' })}
>
{ctx.conflict_risks.map((r, i) => {
const desc = typeof r === 'string' ? r : r.description;
const severity = typeof r === 'string' ? undefined : r.severity;
return (
-
{severity && {severity}}
{desc}
);
})}
)}
{/* Structured Conflict Detection (higher priority than simple conflict_risks) */}
{ctx?.conflict_detection && (
)}
{/* Assets */}
{ctx?.assets && (
)}
{/* Enhanced Explorations - when angle data has detail fields */}
{contextData.explorations?.data &&
Object.values(contextData.explorations.data).some(angle =>
angle.project_structure?.length || angle.relevant_files?.length || angle.patterns?.length
) && (
)}
{/* Focus Paths from Plan */}
{hasFocusPaths && (
}
title={formatMessage({ id: 'liteTasks.contextPanel.focusPaths' })}
>
{(plan.focus_paths as string[]).map((p, i) => (
{p}
))}
)}
{/* Plan Summary */}
{hasSummary && (
}
title={formatMessage({ id: 'liteTasks.contextPanel.summary' })}
>
{plan.summary as string}
)}
{/* Raw JSON Debug View */}
{contextData.context && (
}
title={formatMessage({ id: 'liteTasks.contextPanel.rawJson' })}
defaultOpen={false}
>
{JSON.stringify(contextData.context, null, 2)}
)}
);
}
export { ContextContent as LiteContextContent, ContextSection as LiteContextSection };