"use client";
import { Button } from "@/components/ui/button";
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from "@/components/ui/tooltip";
import { List, HelpCircle } from "lucide-react";
import { cn } from "@/lib/utils";
import { useState } from "react";
import { PlanItem, TaskPlan } from "@open-swe/shared/open-swe/types";
import {
HoverCard,
HoverCardContent,
HoverCardTrigger,
} from "@/components/ui/hover-card";
interface ProgressBarProps {
taskPlan?: TaskPlan;
className?: string;
onOpenSidebar?: () => void;
}
export function ProgressBar({
taskPlan,
className,
onOpenSidebar,
}: ProgressBarProps) {
const [showLegend, setShowLegend] = useState(false);
if (!taskPlan || !taskPlan.tasks.length) {
return (
);
}
const currentTask = taskPlan.tasks[taskPlan.activeTaskIndex];
if (!currentTask || !currentTask.planRevisions.length) {
return (
);
}
const activeRevision =
currentTask.planRevisions[currentTask.activeRevisionIndex];
const planItems = [...activeRevision.plans].sort((a, b) => a.index - b.index);
// Find the current task (lowest index among uncompleted tasks)
const currentTaskIndex = planItems
.filter((item) => !item.completed)
.reduce(
(min, item) => (item.index < min ? item.index : min),
Number.POSITIVE_INFINITY,
);
const getItemState = (
item: PlanItem,
): "completed" | "current" | "remaining" => {
if (item.completed) return "completed";
if (item.index === currentTaskIndex) return "current";
return "remaining";
};
const completedCount = planItems.filter((item) => item.completed).length;
const progressPercentage =
planItems.length > 0 ? (completedCount / planItems.length) * 100 : 0;
const getSegmentColor = (state: string) => {
switch (state) {
case "completed":
return "bg-green-400";
case "current":
return "bg-blue-400";
default:
return "bg-gray-200";
}
};
return (
{/* Compact header */}
Plan Progress
Plan Progress
Shows the current progress of the AI agent's plan
execution.
{Math.round(progressPercentage)}%
{/* Legend - conditionally shown */}
{showLegend && (
)}
{/* Progress Stats */}
{completedCount} of {planItems.length} tasks completed
Task #{currentTask.taskIndex + 1}
{/* Progress Bar */}
{planItems.map((item) => {
const state = getItemState(item);
const segmentWidth = `${100 / planItems.length}%`;
return (
Task #{item.index + 1}
{state === "completed"
? "Completed"
: state === "current"
? "Current"
: "Pending"}
{item.plan}
);
})}
);
}