Skip to content

[Amber] Fix: [Amber] Todo/TodoWrite Visualization#848

Open
github-actions[bot] wants to merge 1 commit intomainfrom
amber/issue-847-amber-todo-todowrite-visualization
Open

[Amber] Fix: [Amber] Todo/TodoWrite Visualization#848
github-actions[bot] wants to merge 1 commit intomainfrom
amber/issue-847-amber-todo-todowrite-visualization

Conversation

@github-actions
Copy link
Copy Markdown
Contributor

@github-actions github-actions bot commented Mar 8, 2026

Automated Fix by Amber Agent

This PR addresses issue #847 using the Amber background agent.

Changes Summary

  • Action Type: auto-fix
  • Commit: 468ac5c (rebased as 30feeb0)
  • Triggered by: Issue label/command
  • Adds TodoWrite tool visualization with structured task list UI
  • Includes task status icons (completed, in-progress, pending) and priority badges
  • Smart summary showing task counts by status in collapsed view

Fixes Applied (PR Fixer Session)

  • Rebased on main to resolve merge conflict in tool-message.tsx (kept both TodoWrite and AskUserQuestion summaries)
  • Fixed unsafe type assertion in parseTodoItems — now validates each element has required content and status properties (CodeRabbit review)
  • Added fallback icon for unexpected status values in TodoListView (CodeRabbit review)

Pre-merge Checklist

  • All linters pass
  • All tests pass (frontend build succeeds)
  • Changes follow project conventions (CLAUDE.md)
  • No scope creep beyond issue description
  • CodeRabbit review comments addressed

Reviewer Notes

This PR was automatically generated. Please review:

  1. Code quality and adherence to standards
  2. Test coverage for changes
  3. No unintended side effects

🤖 Generated with Amber Background Agent

Closes #847

@ambient-code ambient-code bot added this to the Merge Queue milestone Mar 10, 2026
@Gkrumbach07
Copy link
Copy Markdown
Contributor

@coderabbitai full review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 11, 2026

✅ Actions performed

Full review triggered.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 11, 2026

Important

Review skipped

Bot user detected.

To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 3628df12-f06c-4739-bda0-2c3d84215f10

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This change adds TodoWrite-specific visualization support to the tool-message component. It introduces a TodoItem type and parsing logic, implements a TodoListView component to render tasks with status indicators and priority badges, and updates tool summary generation to display formatted task counts and statuses. The tool header now displays a ListTodo icon for TodoWrite tools.

Changes

Cohort / File(s) Summary
TodoWrite UI Enhancement
components/frontend/src/components/ui/tool-message.tsx
Introduced TodoItem type, parseTodoItems helper, and isTodoWriteTool checker. Implemented TodoListView component for rendering task entries with status icons and optional priority badge. Enhanced generateToolSummary to count and format task statuses. Updated tool rendering to display ListTodo icon and structured task list for TodoWrite tools.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch amber/issue-847-amber-todo-todowrite-visualization
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch amber/issue-847-amber-todo-todowrite-visualization

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@components/frontend/src/components/ui/tool-message.tsx`:
- Around line 38-43: The parseTodoItems function unsafely casts input.todos to
TodoItem[]; update parseTodoItems to validate each array element has the
required fields (e.g., content as string and status as expected enum/string)
before returning; either filter out invalid entries or return null if any
element is malformed. Reference parseTodoItems and ensure the output shape
matches what TodoListView expects (accessing todo.content and todo.status) by
performing a type guard check on each item and returning a correctly typed
TodoItem[] or null.
- Around line 53-61: The rendering logic for todo.status (checked in the
component that uses todo.status and icons Check and Loader2) lacks a fallback
for unexpected values; update the JSX to include a default branch that renders a
sensible fallback icon or placeholder (e.g., a neutral icon or aria-hidden empty
circle) when todo.status is not "completed", "in_progress", or "pending", and
ensure it provides appropriate accessibility attributes (aria-label or title) so
unexpected statuses still display meaningfully.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: aa501764-3a24-4b2e-918e-ee152959e6d2

📥 Commits

Reviewing files that changed from the base of the PR and between 9180a41 and 468ac5c.

📒 Files selected for processing (1)
  • components/frontend/src/components/ui/tool-message.tsx

Comment on lines +38 to +43
const parseTodoItems = (input?: Record<string, unknown>): TodoItem[] | null => {
if (!input) return null;
const todos = input.todos;
if (!Array.isArray(todos) || todos.length === 0) return null;
return todos as TodoItem[];
};
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Unsafe type assertion may cause runtime errors with malformed data.

parseTodoItems casts the array directly to TodoItem[] without validating that each element has the required content and status properties. If the backend sends incomplete data, accessing todo.status or todo.content in TodoListView will silently fail or render incorrectly.

🛡️ Proposed fix to add validation
 const parseTodoItems = (input?: Record<string, unknown>): TodoItem[] | null => {
   if (!input) return null;
   const todos = input.todos;
   if (!Array.isArray(todos) || todos.length === 0) return null;
-  return todos as TodoItem[];
+  return todos
+    .filter(
+      (t): t is TodoItem =>
+        t != null &&
+        typeof t === "object" &&
+        typeof (t as Record<string, unknown>).content === "string" &&
+        ["pending", "in_progress", "completed"].includes(
+          (t as Record<string, unknown>).status as string
+        )
+    );
 };
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const parseTodoItems = (input?: Record<string, unknown>): TodoItem[] | null => {
if (!input) return null;
const todos = input.todos;
if (!Array.isArray(todos) || todos.length === 0) return null;
return todos as TodoItem[];
};
const parseTodoItems = (input?: Record<string, unknown>): TodoItem[] | null => {
if (!input) return null;
const todos = input.todos;
if (!Array.isArray(todos) || todos.length === 0) return null;
return todos
.filter(
(t): t is TodoItem =>
t != null &&
typeof t === "object" &&
typeof (t as Record<string, unknown>).content === "string" &&
["pending", "in_progress", "completed"].includes(
(t as Record<string, unknown>).status as string
)
);
};
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/frontend/src/components/ui/tool-message.tsx` around lines 38 - 43,
The parseTodoItems function unsafely casts input.todos to TodoItem[]; update
parseTodoItems to validate each array element has the required fields (e.g.,
content as string and status as expected enum/string) before returning; either
filter out invalid entries or return null if any element is malformed. Reference
parseTodoItems and ensure the output shape matches what TodoListView expects
(accessing todo.content and todo.status) by performing a type guard check on
each item and returning a correctly typed TodoItem[] or null.

Comment on lines +53 to +61
{todo.status === "completed" && (
<Check className="w-3.5 h-3.5 text-green-500" />
)}
{todo.status === "in_progress" && (
<Loader2 className="w-3.5 h-3.5 text-blue-500 animate-spin" />
)}
{todo.status === "pending" && (
<div className="w-3.5 h-3.5 rounded-full border-2 border-muted-foreground/40" />
)}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Missing fallback for unexpected status values.

If todo.status contains an unexpected value (not one of the three defined statuses), no icon will be rendered. Consider adding a fallback for robustness.

🛡️ Proposed fix to add fallback
           {todo.status === "pending" && (
             <div className="w-3.5 h-3.5 rounded-full border-2 border-muted-foreground/40" />
           )}
+          {!["completed", "in_progress", "pending"].includes(todo.status) && (
+            <div className="w-3.5 h-3.5 rounded-full border-2 border-muted-foreground/40" />
+          )}

Note: If the validation fix in parseTodoItems is applied, this becomes redundant.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{todo.status === "completed" && (
<Check className="w-3.5 h-3.5 text-green-500" />
)}
{todo.status === "in_progress" && (
<Loader2 className="w-3.5 h-3.5 text-blue-500 animate-spin" />
)}
{todo.status === "pending" && (
<div className="w-3.5 h-3.5 rounded-full border-2 border-muted-foreground/40" />
)}
{todo.status === "completed" && (
<Check className="w-3.5 h-3.5 text-green-500" />
)}
{todo.status === "in_progress" && (
<Loader2 className="w-3.5 h-3.5 text-blue-500 animate-spin" />
)}
{todo.status === "pending" && (
<div className="w-3.5 h-3.5 rounded-full border-2 border-muted-foreground/40" />
)}
{!["completed", "in_progress", "pending"].includes(todo.status) && (
<div className="w-3.5 h-3.5 rounded-full border-2 border-muted-foreground/40" />
)}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/frontend/src/components/ui/tool-message.tsx` around lines 53 - 61,
The rendering logic for todo.status (checked in the component that uses
todo.status and icons Check and Loader2) lacks a fallback for unexpected values;
update the JSX to include a default branch that renders a sensible fallback icon
or placeholder (e.g., a neutral icon or aria-hidden empty circle) when
todo.status is not "completed", "in_progress", or "pending", and ensure it
provides appropriate accessibility attributes (aria-label or title) so
unexpected statuses still display meaningfully.

@ambient-code ambient-code bot modified the milestones: Merge Queue, Review Queue Mar 12, 2026
@jeremyeder
Copy link
Copy Markdown
Contributor

This should be closed and re-opened with clean requirements including being feature flagged off to start.

@ambient-code
Copy link
Copy Markdown
Contributor

ambient-code bot commented Apr 7, 2026

Review Queue Status

Check Status Detail
CI ✅ pass pass
Conflicts ❌ FAIL ---
Reviews ✅ pass REVIEW_REQUIRED

Action needed: Resolve merge conflicts (rebase on main)

Auto-generated by Review Queue workflow. Updated when PR changes.

@github-actions github-actions bot added this to the Review Queue milestone Apr 7, 2026
@Gkrumbach07 Gkrumbach07 added the ambient-code:managed PR managed by AI automation label Apr 7, 2026
Renders TodoWrite tool calls as a structured task list with status icons
(completed/in_progress/pending), priority badges, and a smart summary
showing task counts by status in the collapsed view.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@ambient-code ambient-code bot force-pushed the amber/issue-847-amber-todo-todowrite-visualization branch from 468ac5c to 30feeb0 Compare April 7, 2026 19:31
@ambient-code
Copy link
Copy Markdown
Contributor

ambient-code bot commented Apr 7, 2026

PR Fixer: Issues Resolved

  1. Merge conflict resolved — Rebased on main. The conflict was in tool-message.tsx where the TodoWrite summary code overlapped with a new AskUserQuestion summary added on main. Both are now included.

  2. CodeRabbit review comments addressed:

    • parseTodoItems now validates each array element has the required content and status properties instead of an unsafe cast.
    • TodoListView now renders a fallback icon for unexpected status values.
  3. Frontend build verifiednext build passes with zero errors.

🤖 Session

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ambient-code:managed PR managed by AI automation auto-fix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Amber] Todo/TodoWrite Visualization

2 participants