import { formatDuration } from "@/lib/format"; import type { DashboardStartupMode } from "@/lib/tui/dashboard/use-dashboard-run-control"; import { formatFindingTitleForDisplay } from "@/lib/tui/sessions/finding-title"; import { PriorityText } from "@/lib/tui/sessions/priority-text"; import { extractFindingsFromStats, extractFixesFromStats, formatBatchFirstIssueSummary, formatHandoffCommands, formatHandoffSummary, formatLastRunIssueSummary, formatPriorityBreakdown, formatProjectStatsSummary, formatRelativeTime, hasBatchFirstSummary, } from "@/lib/tui/sessions/session-display"; import { TUI_COLORS } from "@/lib/tui/shared/colors"; import { Spinner } from "@/lib/tui/shared/Spinner"; import type { ProjectStats, SessionStats } from "@/lib/types"; import { toSingleLine } from "./session-detail-parts"; const LAST_RUN_STATUS_DISPLAY: Partial< Record > = { completed: { text: "completed", color: TUI_COLORS.status.success }, failed: { text: "failed", color: TUI_COLORS.status.error }, interrupted: { text: "interrupted", color: TUI_COLORS.status.warning }, running: { text: "running", color: TUI_COLORS.status.pending }, }; function getLastRunStatusDisplay(status: SessionStats["status"]): { text: string; color: string } { return LAST_RUN_STATUS_DISPLAY[status] ?? { text: "unknown", color: TUI_COLORS.status.inactive }; } function getLastRunHandoffDisplay(stats: SessionStats): { summary: string | null; applyCommand: string | null; } { if (stats.handoffStatus === "applied-auto") { return { summary: "auto applied.", applyCommand: null, }; } if (stats.handoffStatus === "pending-apply") { const [applyCommand] = formatHandoffCommands(stats.handoffId, stats.handoffStatus); return { summary: applyCommand ? null : "pending apply.", applyCommand: applyCommand ?? null, }; } return { summary: formatHandoffSummary(stats.handoffStatus, stats.commitSha), applyCommand: null, }; } interface IdleStateViewProps { isGitRepo: boolean; startupMode: DashboardStartupMode; isStopping: boolean; lastSessionStats: SessionStats | null; projectStats: ProjectStats | null; canFixPendingSession: boolean; } export function IdleStateView({ isGitRepo, startupMode, isStopping, lastSessionStats, projectStats, canFixPendingSession, }: IdleStateViewProps) { const lastRunStatusDisplay = lastSessionStats ? getLastRunStatusDisplay(lastSessionStats.status) : null; const lastRunFixes = lastSessionStats ? extractFixesFromStats(lastSessionStats).sort((a, b) => a.priority.localeCompare(b.priority)) : []; const lastRunFindings = lastSessionStats ? extractFindingsFromStats(lastSessionStats).sort((a, b) => { const left = a.priority ?? Number.POSITIVE_INFINITY; const right = b.priority ?? Number.POSITIVE_INFINITY; return left - right || a.title.localeCompare(b.title); }) : []; const lastRunSummary = lastSessionStats ? `${ hasBatchFirstSummary(lastSessionStats) ? formatBatchFirstIssueSummary(lastSessionStats) : formatLastRunIssueSummary( lastSessionStats.totalFixes, lastSessionStats.totalSkipped, lastSessionStats.iterations ) }${ lastSessionStats.totalDuration !== undefined ? ` · ${formatDuration(lastSessionStats.totalDuration)}` : "" }` : null; const lastRunHandoffDisplay = lastSessionStats ? getLastRunHandoffDisplay(lastSessionStats) : null; return ( {!isGitRepo && ( Not a git repository Run "git init" to initialize )} {isStopping ? ( Stopping review... ) : startupMode === "review" ? ( Starting review... ) : startupMode === "fix" ? ( Starting fix... ) : ( No active session )} Start a review by pressing "r" {projectStats && projectStats.totalFixes > 0 && ( Project stats {formatProjectStatsSummary(projectStats.totalFixes, projectStats.sessionCount)} {formatPriorityBreakdown(projectStats.priorityCounts).map((item, idx, arr) => ( {item.count} {idx < arr.length - 1 && · } ))} )} {lastSessionStats && lastRunStatusDisplay && lastRunSummary && ( Last run {lastRunStatusDisplay.text} ({formatRelativeTime(lastSessionStats.timestamp)}) {lastRunSummary} {lastRunFindings.length > 0 && ( {lastRunFindings.map((finding) => { return ( {toSingleLine(formatFindingTitleForDisplay(finding.title))} ); })} )} {lastRunFixes.length > 0 && ( Recent fixes {lastRunFixes.map((fix) => ( {toSingleLine(fix.title)} ))} )} {lastRunHandoffDisplay?.summary && ( Handoff: {lastRunHandoffDisplay.summary} )} {lastRunHandoffDisplay?.applyCommand && ( Handoff: {lastRunHandoffDisplay.applyCommand} )} {canFixPendingSession && ( Press "f" to fix issues )} )} ); }