Skip to content

ACP Chat: Enhance PlanPanel with accordion task detail, scrollable area, and task name/detail split #410

Description

@gnoviawan

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:

  1. See each task's name (short title) and detail (full description) separately.
  2. Click the task title to expand the detail like an accordion.
  3. Have a scrollable area so a long plan doesn't crowd out the chat.
  4. 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:164plans: 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
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    aiAI-powered featureenhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions