Problem or Opportunity
The ACP chat already has a PlanPanel (src/renderer/components/chat/PlanPanel.tsx) that renders the agent's execution plan entries from the ACP session/update event. However, the current panel is a flat, single-line list with no expandable detail, no scroll constraint, and no task-name/task-detail split. When the plan grows long, it pushes the message thread down and the user cannot see the full task description — only a truncated one-liner.
The user needs to:
- See each task's name (short title) and detail (full description) separately.
- Click the task title to expand the detail like an accordion.
- Have a scrollable area so a long plan doesn't crowd out the chat.
- Watch the agent update the list in real time (the agent — not the human — modifies the list).
Proposed Solution
Enhance PlanPanel.tsx to:
1. Accordion-style task entries
- Replace the flat
<ul> with a Radix <Accordion> (already available at components/ui/accordion.tsx).
- Each
PlanEntry becomes an AccordionItem:
AccordionTrigger: shows the status icon (✓ completed / spinner in_progress / ○ pending), priority dot, and entry.content as the task name.
AccordionContent: renders entry.detail (or entry._meta?.detail) as the expanded task detail.
- Gracefully degrade: if
detail is absent, render a non-expandable row (no accordion chevron).
2. Task name + task detail split
- The ACP
PlanEntry type (src/renderer/lib/acp-api.ts:150) already has [k: string]: unknown, so agents can include a detail field today without protocol changes.
- The UI reads
entry.content as the task name and entry.detail as the detail.
- Agents that don't send
detail still render correctly (just no expansion).
3. Scrollable area
- Wrap the accordion list in
<ScrollArea> (components/ui/scroll-area.tsx) with a max-h constraint (e.g., 240px or 40vh).
- This prevents a long plan from pushing the chat message list down.
4. Keep checkbox/status semantics
completed → checkmark circle (green, line-through text)
in_progress → spinner (amber)
pending → empty circle (muted)
How the ACP protocol already supports this
The ACP spec (agent-plan) defines:
session/update with sessionUpdate: "plan" carries entries: PlanEntry[].
- Each
PlanEntry has content (human-readable description), priority (high/medium/low), and status (pending/in_progress/completed).
- The extensibility spec allows custom fields via
_meta and arbitrary keys — so detail is valid today.
- The agent sends the complete list on each update; the client replaces the entire plan. This is already wired in the backend (
src-tauri/src/acp/client.rs:259) and store (src/renderer/stores/acp-store.ts:1411).
No protocol or backend changes are needed. This is a frontend-only enhancement.
Implementation notes
- UI primitives already available:
accordion.tsx, scroll-area.tsx, checkbox.tsx, collapsible.tsx — all present in src/renderer/components/ui/.
- Type:
PlanEntry in acp-api.ts already accepts extra fields via [k: string]: unknown.
- Mount site:
AgentChatPanel.tsx:179 — <PlanPanel entries={plan} />.
- Store:
acp-store.ts:164 — plans: Record<SessionId, PlanEntry[]>.
Alternatives Considered
- Use
collapsible.tsx instead of accordion.tsx: Collapsible allows multiple open items; accordion is single-open. Accordion is better for a task list where the user typically focuses on one task at a time.
- Add a separate "Plan" tab/panel: Would separate the plan from the chat flow. The inline approach keeps the plan visible during the conversation, which matches the user's "know what the current step is" requirement.
- Wait for the ACP
plan_update RFID: The plan-operations RFID proposes multi-plan support, markdown content, and file URIs. This is future work and not needed for the current enhancement.
Success Criteria
- Agent sends a plan with entries containing
content (task name) and optional detail (task detail).
- User sees the task list in the chat panel with status icons and priority dots.
- User can click a task title to expand the detail in an accordion.
- Long plans are scrollable and don't push the chat messages out of view.
- Agents that don't send
detail still render correctly (non-expandable rows).
- The UI gracefully handles empty plans (renders nothing, as it does today).
Additional Context
Current PlanPanel.tsx (flat list, no detail, no scroll):
<ul className="flex flex-col gap-1 px-3 py-2">
{entries.map((entry, i) => (
<li key={i} className="flex items-center gap-2 text-xs">
<StatusIcon status={entry.status} />
<span className="priority-dot" />
<span className="truncate">{entry.content}</span>
</li>
))}
</ul>
ACP PlanEntry schema (extensible):
export interface PlanEntry {
content: string // → task name
priority?: PlanEntryPriority
status?: PlanEntryStatus
[k: string]: unknown // → detail can live here
}
Problem or Opportunity
The ACP chat already has a
PlanPanel(src/renderer/components/chat/PlanPanel.tsx) that renders the agent's execution plan entries from the ACPsession/updateevent. However, the current panel is a flat, single-line list with no expandable detail, no scroll constraint, and no task-name/task-detail split. When the plan grows long, it pushes the message thread down and the user cannot see the full task description — only a truncated one-liner.The user needs to:
Proposed Solution
Enhance
PlanPanel.tsxto:1. Accordion-style task entries
<ul>with a Radix<Accordion>(already available atcomponents/ui/accordion.tsx).PlanEntrybecomes anAccordionItem:AccordionTrigger: shows the status icon (✓ completed / spinner in_progress / ○ pending), priority dot, andentry.contentas the task name.AccordionContent: rendersentry.detail(orentry._meta?.detail) as the expanded task detail.detailis absent, render a non-expandable row (no accordion chevron).2. Task name + task detail split
PlanEntrytype (src/renderer/lib/acp-api.ts:150) already has[k: string]: unknown, so agents can include adetailfield today without protocol changes.entry.contentas the task name andentry.detailas the detail.detailstill render correctly (just no expansion).3. Scrollable area
<ScrollArea>(components/ui/scroll-area.tsx) with amax-hconstraint (e.g., 240px or 40vh).4. Keep checkbox/status semantics
completed→ checkmark circle (green, line-through text)in_progress→ spinner (amber)pending→ empty circle (muted)How the ACP protocol already supports this
The ACP spec (agent-plan) defines:
session/updatewithsessionUpdate: "plan"carriesentries: PlanEntry[].PlanEntryhascontent(human-readable description),priority(high/medium/low), andstatus(pending/in_progress/completed)._metaand arbitrary keys — sodetailis valid today.src-tauri/src/acp/client.rs:259) and store (src/renderer/stores/acp-store.ts:1411).No protocol or backend changes are needed. This is a frontend-only enhancement.
Implementation notes
accordion.tsx,scroll-area.tsx,checkbox.tsx,collapsible.tsx— all present insrc/renderer/components/ui/.PlanEntryinacp-api.tsalready accepts extra fields via[k: string]: unknown.AgentChatPanel.tsx:179—<PlanPanel entries={plan} />.acp-store.ts:164—plans: Record<SessionId, PlanEntry[]>.Alternatives Considered
collapsible.tsxinstead ofaccordion.tsx: Collapsible allows multiple open items; accordion is single-open. Accordion is better for a task list where the user typically focuses on one task at a time.plan_updateRFID: The plan-operations RFID proposes multi-plan support, markdown content, and file URIs. This is future work and not needed for the current enhancement.Success Criteria
content(task name) and optionaldetail(task detail).detailstill render correctly (non-expandable rows).Additional Context
Current
PlanPanel.tsx(flat list, no detail, no scroll):ACP PlanEntry schema (extensible):