21 / 37 · Agents
Agent plan
A checklist the agent works through, with progress you can glance.
Plan0 of 5
- Read existing composer state
- Design the draft store
- Wire runtime persistence
- Add regression tests
- Update the docs
Installation
npx shadcn@latest add "@assistant-ui/elements-agent-plan"
Usage
import { AgentPlan } from "@/components/elements/agent-plan";
<AgentPlan
steps={["Read the file", "Draft the fix", "Run tests"]}
activeIndex={1}
/>Props
steps*readonly string[]Checklist items the agent works through in order.
activeIndex*numberIndex of the step currently running. Values past the end mark every step done.
classNamestringExtra classes merged onto the root.
Source
agent-plan.tsx"use client";
import { CheckIcon, Loader2Icon } from "lucide-react";
import { cn } from "@/lib/utils";
import { mono } from "./surfaces";
export function AgentPlan({
steps,
activeIndex,
className,
}: {
steps: readonly string[];
activeIndex: number;
className?: string;
}) {
const total = steps.length;
const allDone = activeIndex >= total;
const completed = allDone ? total : activeIndex;
const progress = total === 0 ? 0 : (completed / total) * 100;
return (
<div className={cn("flex w-full max-w-sm flex-col gap-3", className)}>
<div className="flex items-center justify-between">
<span className="text-[13.5px] font-medium">Plan</span>
<span className={cn(mono, "text-foreground/35 tabular-nums")}>
{completed} of {total}
</span>
</div>
<div className="bg-foreground/[0.06] h-[3px] w-full overflow-hidden rounded-full">
<span
className="bg-foreground/80 block h-full rounded-full transition-[width] duration-500"
style={{ width: `${progress}%` }}
/>
</div>
<ul className="flex flex-col gap-2.5">
{steps.map((step, i) => {
const done = allDone || i < activeIndex;
const active = !allDone && i === activeIndex;
return (
<li key={step} className="flex items-center gap-2.5 text-[13.5px]">
<span className="flex size-4 shrink-0 items-center justify-center">
{done ? (
<CheckIcon className="text-foreground/35 size-3.5" />
) : active ? (
<Loader2Icon className="text-foreground/90 size-3.5 animate-spin motion-reduce:animate-none" />
) : (
<span
aria-hidden
className="bg-foreground/15 size-1.5 rounded-full"
/>
)}
</span>
<span
className={cn(
done && "text-foreground/40",
active && "text-foreground/90",
!done && !active && "text-foreground/35",
)}
>
{step}
</span>
</li>
);
})}
</ul>
</div>
);
}