Agent plan
ProThe plan an agent writes before it acts: edit, reorder or add steps while it is a draft, then watch it work through them as a live checklist.
Plan6 steps
Claude Opus 5.5Add rate limiting to the public API
- An agent should show and get approval for its plan before it edits code, runs commands or touches production.
- A person needs to adjust the agent's plan (rename, reorder, remove or add steps) and then watch the same plan execute.
- A side panel or chat message that tracks a multi-step task with a live current step, failures that need a decision, and a final summary.
- Use agent-run for a streaming transcript of everything the agent did, with tool calls and output, rather than a checklist of steps.
- Use agent-approvals when the person approves individual risky actions one at a time instead of a whole plan up front.
- Use agent-tasks for a queue of independent tasks across agents rather than one ordered plan.
- Use research-run for search and reading progress that ends in a cited answer.
Installation
Pro source and install commands unlock with a Pro plan.
import { AgentPlan, type AgentPlanStep } from "@/components/arc/agent-plan/agent-plan"; // With no props it shows a sample plan and simulates the run.export function PlanDemo() { return <AgentPlan />;} // Driven by your agent.export function AgentPlanPanel({ run }) { return ( <AgentPlan goal={run.goal} steps={run.steps} // [{ id, title, state, substeps, note, error, duration }] status={run.status} // "draft" | "running" | "paused" | "done" summary={run.summary} model={{ name: "Claude Sonnet 5.5", mark: <ClaudeMark /> }} onChange={steps => run.updateDraft(steps)} onKeepPlanning={() => run.suggestStep()} onApprove={steps => run.start(steps)} onPauseChange={paused => (paused ? run.pause() : run.resume())} onStepAction={({ type, step }) => (type === "retry" ? run.retry(step.id) : run.skip(step.id))} /> );} // A step the agent is working on, and one it inserted.const steps: AgentPlanStep[] = [ { id: "store", title: "Keep request counters in Redis with a 60 second TTL", state: "active", substeps: ["Read lib/redis.ts", "Ran 6 tests"] }, { id: "fallback", title: "Fall back to in-memory counters when Redis is down", note: "Added by agent" },];AgentPlan
The plan an agent writes before it acts, then works through as a live checklist. A header shows the model mark, "Plan · 6 steps" and the goal. While the plan is a draft every step can be renamed in place, dragged or moved with Alt and the arrow keys, removed, or added to, and Keep planning streams one more suggested step in before the last one. Approve plan locks it: the grips become status rings, the header counts "3 of 6" over a thin progress line, the current step shimmers beside a small spinner with its activity lines underneath, and a finished step draws its check and settles to secondary text with its time on the right. The agent can insert a step mid-run (it slides in with an "Added by agent" note), a failed step offers Retry and Skip, the run can be paused and resumed, and the footer ends with a one line summary and the total time. Without `status` it runs a simulated agent so the whole journey can be tried in place.
stepsAgentPlanStep[]sampleStepsThe plan. Each step has an id and a title, and optionally a state ("pending", "active", "done", "failed" or "skipped"), substeps (short activity lines; the first word, such as Read, Edited, Created, Searched or Ran, picks the icon), a note ("Added by agent"), an error for a failed step, and a duration in seconds for a done step. A new array replaces the plan on screen.status"draft" | "running" | "paused" | "done"–Where the plan stands. Pass it to drive the plan from your agent: the component then never changes status or steps on its own and reports every action through the callbacks. Leave it out to run the built-in simulation.goalstring"Add rate limiting to the public API"What the plan is for, shown under the header and used in the plan's accessible name.model{ name: string; mark?: ReactNode }{ name: "Claude Opus 5.5", mark: <ClaudeBrandMark /> }The model that wrote the plan. The 16px mark sits in the header and before agent notes; the name shows in the header while the plan is a draft.summarystring–One line shown after "Done in 4m 35s." when the plan finishes. It streams in. The total time is the sum of the done steps' durations.onApprove(steps: AgentPlanStep[]) => void–Called by Approve plan with the steps in their final order, titles trimmed and empty steps removed. Start your agent here and set status to "running".onChange(steps: AgentPlanStep[]) => void–Called after each draft edit: a rename (on Enter or blur), a reorder (on drop or key press), a removal, an added step, or a suggested step that finished streaming.onStepAction(action: { type: "retry" | "skip"; step: AgentPlanStep }) => void–Called when someone retries or skips a failed step. Focus is handled for you; update the step's state in `steps`.onKeepPlanning() => void–Called by Keep planning. Ask the agent for one more step and add it to `steps`.onPauseChange(paused: boolean) => void–Called by Pause (true) and Resume (false). Pause your agent and set status to "paused", or back to "running".classNamestring–Class on the root element.- Tab
- In a draft, moves through each step's grip, title and remove button, then Add step, Keep planning and Approve plan. While running, reaches Retry and Skip on a failed step and Pause or Resume.
- Alt+Arrow uporArrow down
- In a step title, moves that step up or down and keeps the caret in place.
- Arrow uporArrow down
- On a step's grip, moves that step up or down.
- Enter
- In a step title, saves the rename without leaving the field.
- Escape
- In a step title, undoes the rename since the field was focused.
- Backspace
- In an empty step title, removes the step and moves focus to the step above.
- The plan is a section named after the model and the goal; the steps are an ordered list, so a screen reader announces the count and each position.
- Every step announces its state in words (Pending, In progress, Done, Failed, Skipped) before its title. Each state also has its own shape, a ring, a spinning arc, two bars, a disc with a check, a disc with an exclamation mark or a dashed ring, so it never rests on color.
- A failed step shows the word Failed with its reason and two labelled buttons. Skipped steps say Skipped beside the title.
- Titles are labelled text areas described by a hidden hint that explains Alt plus the arrow keys and Escape. Grips and remove buttons are named after their step and position.
- Edits, approval, each finished step, an inserted step, a failure, pause and the final summary are announced through one polite status region, including that the preview is a simulation.
- Focus follows the action: a moved step keeps focus, a removed step hands it to its neighbour, Approve plan hands it to Pause, and Retry or Skip hand it back to Pause.
- The progress line is a progressbar with a text value ("2 of 6 steps finished"), hidden while the plan is a draft.
- Pointer focus draws no ring; keyboard focus shows Arc's shared focus ring, inset on controls inside clipped rows.
- Reorders, inserts, removals and activity lines move on a critically damped spring (about 260ms, no bounce), so rows slide and grow without overshoot.
- Completing a step draws its check as a stroke over about 220ms while the disc fades up beneath it, and the title color settles from primary to secondary.
- The current step's title shimmers with Arc's text shimmer beside a spinning arc; pausing stops both and swaps the arc for a pause glyph.
- A suggested step streams its title in chunks of a few words every 34ms, each chunk only fading in. A step the agent inserts arrives with a faint accent wash that fades out over about 1.8s.
- Counts roll with tabular digits in a reserved width. The header label, footer actions and status icons swap with one short crossfade, and the footer's height follows on the same spring.
- Reduced motion keeps every state, label, focus move and announcement but drops travel, the spinner, the stroke draw, the wash and the chunk fades.
- A container query tightens padding below 420px; the step grid keeps a fixed lead and trail column so titles wrap the same way in draft and while running and never shift on approve.
- Draft footer buttons share the row equally on narrow containers, and the done summary wraps above Start over.
- With a mouse the remove button appears on hover or focus; on touch it stays visible. Grips accept touch drags without scrolling the page.
- Reads well from 320px to about 760px wide; the demo caps it at 560px.
- The simulation schedules exactly one timer per state change, so pausing simply drops it and nothing runs while the plan is idle.
- Streaming uses one requestAnimationFrame clock with catch-up and appends spans; settled chunks never re-render or re-mount.
- Only transform and opacity animate on rows, except the brief height spring when a row or activity line enters or leaves.
- The shimmer runs only on the active step and only while it is on screen and the page is visible.
Notes for AI
Give your coding assistant the Markdown reference instead of screenshots.
- Use it for the plan step of a coding or operations agent: the agent proposes steps, a person edits and approves, then the same card tracks execution. It is not an onboarding checklist and not a run log.
- Write step titles as instructions ("Add a sliding window limiter to the API middleware"). Keep substeps to short past-tense activity starting with a verb such as Read, Edited, Created, Searched, Found, Ran or Measured; the verb picks the icon.
- Pass `status` when wiring a real agent. Then the component is fully controlled by `steps` and `status`: set one step to "active" at a time, append substeps as the agent reports them, set "done" with a duration in seconds, and set "failed" with an error to show Retry and Skip.
- Insert steps the agent adds mid-run with `note: "Added by agent"`; they slide in where you place them in the array.
- Keep planning calls onKeepPlanning; add the agent's suggestion to `steps` yourself. In the simulation it streams one of three sample suggestions in before the last step.
- The default model is Claude Opus 5.5 with its brand mark. Pass `model` with your own name and a 16px mark for another model.
The full library index for assistants is at /llms.txt.