import type { ReactNode } from "react"; import { IconCircleCheck, IconCircleDashed, IconMessageQuestion, IconProgressCheck, IconShieldQuestion, } from "@tabler/icons-react"; import { CompositorSpin } from "@kandev/ui/compositor-spin"; import { Tooltip, TooltipContent, TooltipTrigger } from "@kandev/ui/tooltip"; import { useTranslation } from "react-i18next"; import type { ForegroundActivity, TaskSessionState, TaskState } from "@/lib/types/http"; import { InterruptedTaskIcon, isTerminalInterruptedState, shouldUsePermissionTaskIcon, shouldUseQuestionTaskIcon, } from "@/lib/ui/state-icons"; import { classifyTask } from "./task-classify"; export type TaskStateIconProps = { sessionState?: TaskSessionState; state?: TaskState; foregroundActivity?: ForegroundActivity | null; hasPendingClarification?: boolean; hasPendingPermission?: boolean; isOnLastWorkflowStep?: boolean; interrupted?: boolean; /** * True when the task is waiting on the operator to notice, not on the * operator to act — a settled session with a positively-sampled background * process still live (spec: docs/specs/disambiguate-waiting/spec.md). * Outranked by pending-input (permission/clarification) and by an active * foregroundActivity (AC-34). */ parkedOnBackgroundWork?: boolean; accessibleLabel?: string; showBackgroundTooltip?: boolean; }; const BACKGROUND_WORK_RUNNING_LABEL_KEY = "task:backgroundWorkIsRunning"; function computeIsInProgress(state?: TaskState, sessionState?: TaskSessionState): boolean { return classifyTask(sessionState, state) === "in_progress"; } function computeIsPreparing(state?: TaskState, sessionState?: TaskSessionState): boolean { if (state === "SCHEDULING") return true; return sessionState === "STARTING" && classifyTask(sessionState, state) !== "review"; } function withAccessibleLabel(node: ReactNode, label?: string) { if (!label) return node; return ( {node} ); } function BackgroundWorkTaskIcon({ showTooltip }: { showTooltip: boolean }) { const { t } = useTranslation(); const spinner = ( ); if (!showTooltip) return spinner; return ( {spinner} {t(BACKGROUND_WORK_RUNNING_LABEL_KEY)} ); } function TaskRunningIcon({ phase, className, }: { phase: "running" | "preparing"; className: string; }) { return ( ); } function TaskReviewIcon({ isOnLastWorkflowStep, accessibleLabel, }: Pick) { if (isOnLastWorkflowStep) { return withAccessibleLabel(