import type { Thread } from "../types"; import { findLatestProposedPlan, isLatestTurnSettled } from "../session-logic"; export interface ThreadStatusPill { label: | "Working" | "Connecting" | "Completed" | "Pending Approval" | "Awaiting Input" | "Plan Ready"; colorClass: string; dotClass: string; pulse: boolean; } type ThreadStatusInput = Pick< Thread, "interactionMode" | "latestTurn" | "lastVisitedAt" | "proposedPlans" | "session" >; export function hasUnseenCompletion(thread: ThreadStatusInput): boolean { if (!thread.latestTurn?.completedAt) return false; const completedAt = Date.parse(thread.latestTurn.completedAt); if (Number.isNaN(completedAt)) return false; if (!thread.lastVisitedAt) return true; const lastVisitedAt = Date.parse(thread.lastVisitedAt); if (Number.isNaN(lastVisitedAt)) return true; return completedAt > lastVisitedAt; } export function resolveThreadStatusPill(input: { thread: ThreadStatusInput; hasPendingApprovals: boolean; hasPendingUserInput: boolean; }): ThreadStatusPill | null { const { hasPendingApprovals, hasPendingUserInput, thread } = input; if (hasPendingApprovals) { return { label: "Pending Approval", colorClass: "text-amber-600 dark:text-amber-300/90", dotClass: "bg-amber-500 dark:bg-amber-300/90", pulse: false, }; } if (hasPendingUserInput) { return { label: "Awaiting Input", colorClass: "text-indigo-600 dark:text-indigo-300/90", dotClass: "bg-indigo-500 dark:bg-indigo-300/90", pulse: false, }; } if (thread.session?.status === "running") { return { label: "Working", colorClass: "text-sky-600 dark:text-sky-300/80", dotClass: "bg-sky-500 dark:bg-sky-300/80", pulse: true, }; } if (thread.session?.status === "connecting") { return { label: "Connecting", colorClass: "text-sky-600 dark:text-sky-300/80", dotClass: "bg-sky-500 dark:bg-sky-300/80", pulse: true, }; } const hasPlanReadyPrompt = !hasPendingUserInput && thread.interactionMode === "plan" && isLatestTurnSettled(thread.latestTurn, thread.session) && findLatestProposedPlan(thread.proposedPlans, thread.latestTurn?.turnId ?? null) !== null; if (hasPlanReadyPrompt) { return { label: "Plan Ready", colorClass: "text-violet-600 dark:text-violet-300/90", dotClass: "bg-violet-500 dark:bg-violet-300/90", pulse: false, }; } if (hasUnseenCompletion(thread)) { return { label: "Completed", colorClass: "text-emerald-600 dark:text-emerald-300/90", dotClass: "bg-emerald-500 dark:bg-emerald-300/90", pulse: false, }; } return null; }