feat(chat): inline agent task list card in message history - #1305
feat(chat): inline agent task list card in message history#1305pedramamini wants to merge 1 commit into
Conversation
Agents that keep a working checklist emit it as a tool call: Claude Code
and OpenCode via TodoWrite (todos array), Codex via update_plan (plan
array). Until now that rendered as a single summary line with no way to
see the individual items or their states.
Add a shape-driven extractor that normalizes those payloads into a
common { content, status } list, plus an inline card in the message
history that shows a progress bar and the same one-line summary when
collapsed, and the full checklist with per-task states when expanded.
Detection keys off the payload shape rather than the tool name, so this
stays agent-agnostic - a new agent emitting the same structure gets the
richer rendering for free.
Also drops an unused @testing-library/user-event import from
TerminalOutput.test.tsx; the package is not installed, so the whole
suite failed to load.
📝 WalkthroughWalkthroughChangesThis change normalizes checklist-style tool payloads, renders them as expandable inline cards, integrates them into tool output, and adds utility and component coverage for TodoWrite and update_plan payloads. Agent task list display
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant ToolLog as Tool log
participant Extractor as extractAgentTaskList
participant Card as AgentTaskListCard
ToolLog->>Extractor: Pass toolState.input
Extractor-->>ToolLog: Return normalized taskList
ToolLog->>Card: Render taskList
Card-->>ToolLog: Toggle expanded task details
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Greptile SummaryIntroduces generic inline rendering for checklist-shaped agent tool calls.
Confidence Score: 5/5The PR appears safe to merge with no concrete changed-code defect identified. Checklist extraction rejects malformed lists, preserves generic rendering when extraction fails, and the new card renders normalized task data without altering persisted session state or agent execution. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart LR
A[Tool input payload] --> B{Checklist-shaped?}
B -- No --> C[Generic tool summary]
B -- Yes --> D[Normalize labels and statuses]
D --> E[Collapsed progress card]
E -->|User expands| F[Per-task status list]
Reviews (1): Last reviewed commit: "feat(chat): inline agent task list card ..." | Re-trigger Greptile |
There was a problem hiding this comment.
Pull request overview
Adds a generic, agent-agnostic task list rendering in the terminal message history by detecting checklist-shaped tool payloads (TodoWrite, update_plan, and similar) and showing them as an inline, collapsed-by-default card.
Changes:
- Introduces a shared task list extractor and one-line summary formatter (
extractAgentTaskList,summarizeAgentTaskList). - Adds an inline expandable
AgentTaskListCardUI and wires it intoTerminalOutputfor checklist tool inputs. - Adds unit and component tests to cover extraction, normalization, and rendering behavior.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| src/renderer/utils/agentTaskList.ts | New extractor and summary formatter to normalize checklist payload shapes across agents. |
| src/renderer/components/AgentTaskListCard.tsx | New inline UI card for collapsed/expanded task list display with progress. |
| src/renderer/components/TerminalOutput.tsx | Detects checklist payloads and renders the task list card instead of generic tool summaries. |
| src/tests/renderer/utils/agentTaskList.test.ts | New unit tests for extraction, status normalization, and summary formatting. |
| src/tests/renderer/components/TerminalOutput.test.tsx | Updates tests to validate collapsed-by-default and expansion behavior for task list cards. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if (!raw || typeof raw !== 'object' || Array.isArray(raw)) return null; | ||
| const item = raw as Record<string, unknown>; | ||
| const content = extractContent(item); | ||
| // Every entry must carry a label — a partial list would misreport progress. |
| const props = createDefaultProps({ session }); | ||
| render(<TerminalOutput {...props} />); | ||
|
|
||
| // Collapsed by default — individual items are not rendered |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/renderer/utils/agentTaskList.ts`:
- Around line 37-42: Update the checklist detection used by extractAgentTaskList
to avoid classifying arbitrary tool arguments as task lists. Require stronger
evidence such as recognized task status values on most items and/or an
allowlisted tool name, while preserving valid checklist extraction and ensuring
unrelated MCP tool summaries are not replaced with null toolSummary.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 499d6585-06d4-4cca-be00-ee6d4f030ba9
📒 Files selected for processing (5)
src/__tests__/renderer/components/TerminalOutput.test.tsxsrc/__tests__/renderer/utils/agentTaskList.test.tssrc/renderer/components/AgentTaskListCard.tsxsrc/renderer/components/TerminalOutput.tsxsrc/renderer/utils/agentTaskList.ts
| /** Keys whose array value may hold a checklist, in priority order. */ | ||
| const TASK_ARRAY_KEYS = ['todos', 'plan', 'tasks'] as const; | ||
|
|
||
| /** Keys that may hold an individual task's label, in priority order. */ | ||
| const CONTENT_KEYS = ['content', 'step', 'title', 'task', 'description', 'text'] as const; | ||
|
|
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check whether any other in-repo tool/schema definitions use "tasks"/"plan"/"todos"
# array fields with generic labels that could collide with this heuristic.
rg -nP --type=ts -C2 '\b(tasks|plan|todos)\s*:' src/main src/renderer -g '!**/*.test.*'Repository: RunMaestro/Maestro
Length of output: 5659
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Inspect the task-list heuristic and TerminalOutput integration points.
sed -n '1,130p' src/renderer/utils/agentTaskList.ts
printf '\n--- TerminalOutput task-list usages ---\n'
sed -n '700,740p' src/renderer/components/TerminalOutput.tsx 2>/dev/null || sed -n '700,740p' src/renderer/components/terminal/TerminalOutput.tsx
printf '\n--- agentTaskList usages ---\n'
rg -n "computeAgentTaskList|agentTaskList|toolSummary" src/renderer/components/TerminalOutput.tsx src/renderer -g '!**/*.test.*'Repository: RunMaestro/Maestro
Length of output: 7535
Narrow the checklist detection before replacing generic tool summaries.
TASK_ARRAY_KEYS and CONTENT_KEYS are tool-agnostic, and every 'tool' log entry has toolSummary set to null whenever extractAgentTaskList(...) matches. This can misrepresent unrelated MCP tool arguments with a matching shape such as tasks: [{ title, description }] as a checklist card; tighten the heuristic, e.g. require valid status values on a majority of items, an allowlist/tool-name guard, or both.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/renderer/utils/agentTaskList.ts` around lines 37 - 42, Update the
checklist detection used by extractAgentTaskList to avoid classifying arbitrary
tool arguments as task lists. Require stronger evidence such as recognized task
status values on most items and/or an allowlisted tool name, while preserving
valid checklist extraction and ensuring unrelated MCP tool summaries are not
replaced with null toolSummary.
Summary
Phase 1 of #429, implemented the generic way rather than as a Claude-Code-specific panel: agent checklists now render as an inline card in the message history.
Several agents keep a working checklist and emit it as a tool call - Claude Code and OpenCode via
TodoWrite(todosarray), Codex viaupdate_plan(planarray). Maestro previously collapsed all of that into a single summary line (Running tests (1/3)) with no way to see the individual items or their states.What changed
src/renderer/utils/agentTaskList.ts(new):extractAgentTaskList()normalizes any checklist-shaped tool payload into a common{ content, status }list. Detection keys off the payload shape, not the tool name, so any agent emitting the same structure gets the richer rendering for free. Status spellings are normalized (in-progress,done,COMPLETE, ...), and a list with any unlabeled entry is rejected outright so progress is never misreported.src/renderer/components/AgentTaskListCard.tsx(new): the inline card. Collapsed by default - a progress bar plus the exact same one-line summary that has always been shown. Click to expand the full checklist with per-task state glyphs (✓ done, ▸ in progress, ○ pending). Completed items are dimmed and struck through.TerminalOutput.tsx: routes checklist payloads to the card and drops the oldTodoWrite-specificsummarizeTodoshelper (its behavior now lives in the shared extractor).Design notes
Two deliberate calls, both worth a sanity check from the issue author:
Phases 2 and 3 from the issue (reading
~/.claude/tasks/, team coordination views) are intentionally out of scope here - they are Claude-Code-specific and deserve their own discussion.Testing
update_planrendering.src/__tests__/renderer/components/TerminalOutput.test.tsx: 125 passed.npm run lintclean.Drive-by: removed an unused
@testing-library/user-eventimport fromTerminalOutput.test.tsx. That package is not inpackage.jsonand is not installed, so the import made the entire suite fail to load before it ran a single test.closes #429
Summary by CodeRabbit
New Features
Tests