dashboard: persistent Plan/Todo panel — sticky pinned, diff successive TodoWrite/UpdateTodos calls #964

Closed
opened 2026-05-08 12:15:10 +00:00 by claude-desktop · 1 comment
Collaborator

User story

As an operator I want the agent's current plan / todo list pinned at the top of the run view (not buried in chat scroll) and updated as a diff on each TodoWrite call, so I can see "+ added 'Run tests'" instead of the timeline duping the whole list ten times.

Context

Claude Code uses TodoWrite (pending/in_progress/completed); cursor uses UpdateTodos + CreatePlan. Both providers update the full list each call. Without diffing, the timeline becomes 80% TodoWrite repaint.

Acceptance criteria

  • <PlanPanel> component pinned position: sticky top-0 inside the planner drawer / monitor detail view. Hidden when no plan/todos exist.
  • State updated by SSE: tool call kind todos or plan. The component reads only the latest full list (current state of truth) — the timeline event is a hint to refresh, not the data source.
  • Server-side: maintain record.plan: PlanItem[] and record.todos: TodoItem[] on TaskRecord. Computed from the most recent todos / plan tool call event. Broadcast on changes.
  • Successive todos events are not duplicated in the timeline — emit one collapsed "Updated todos" entry instead. Keep the full list in record.todos.
  • Each todo row: lucide icon per status (Circle pending, Loader2 in_progress, Check completed), Tokyo Night row tint for in_progress.
  • Click row to scroll the timeline to the event that introduced it (when available).

Out of scope

  • Editing todos from the UI.
  • Plan-vs-Todo conflation: keep two separate panes/tabs even though both use the same primitive.

Dependencies

  • Depends on the <ToolCard> ticket — uses the same primitives.
  • Depends on #954todos / plan ToolKind mapping.

References

## User story As an operator I want the agent's current plan / todo list pinned at the top of the run view (not buried in chat scroll) and updated as a *diff* on each TodoWrite call, so I can see "+ added 'Run tests'" instead of the timeline duping the whole list ten times. ## Context Claude Code uses `TodoWrite` (`pending/in_progress/completed`); cursor uses `UpdateTodos` + `CreatePlan`. Both providers update the full list each call. Without diffing, the timeline becomes 80% TodoWrite repaint. ## Acceptance criteria - [ ] `<PlanPanel>` component pinned `position: sticky top-0` inside the planner drawer / monitor detail view. Hidden when no plan/todos exist. - [ ] State updated by SSE: tool call kind `todos` or `plan`. The component reads only the *latest* full list (`current state of truth`) — the timeline event is a hint to refresh, not the data source. - [ ] Server-side: maintain `record.plan: PlanItem[]` and `record.todos: TodoItem[]` on `TaskRecord`. Computed from the most recent `todos` / `plan` tool call event. Broadcast on changes. - [ ] Successive `todos` events are *not* duplicated in the timeline — emit one collapsed "Updated todos" entry instead. Keep the full list in `record.todos`. - [ ] Each todo row: lucide icon per status (`Circle` pending, `Loader2` in_progress, `Check` completed), Tokyo Night row tint for `in_progress`. - [ ] Click row to scroll the timeline to the event that introduced it (when available). ## Out of scope - Editing todos from the UI. - Plan-vs-Todo conflation: keep two separate panes/tabs even though both use the same primitive. ## Dependencies - Depends on the `<ToolCard>` ticket — uses the same primitives. - Depends on #954 — `todos` / `plan` `ToolKind` mapping. ## References - Open Claude Code feature request: https://github.com/anthropics/claude-code/issues/8723 - Cursor typed `UpdateTodosToolCall` / `CreatePlanToolCall`: `node_modules/.bun/@cursor+sdk@1.0.12/.../tool-call-types.d.ts`
Collaborator

🤖 Auto-assigned to dev (heuristic: area:dashboard + body 1970 bytes (≤ 2 KB) — code role). Reply /unassign to reroute.

🤖 Auto-assigned to **dev** (heuristic: area:dashboard + body 1970 bytes (≤ 2 KB) — code role). Reply `/unassign` to reroute.
Sign in to join this conversation.
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Reference
charles/claude-hooks#964
No description provided.