From 1ea071adb68148334453a096e5a5414dad68f94e Mon Sep 17 00:00:00 2001 From: Mohamed Boudra Date: Tue, 3 Feb 2026 09:48:23 +0700 Subject: [PATCH] fix: improve file path display and TodoWrite executing state handling --- packages/app/src/components/git-diff-pane.tsx | 16 ++++++++-- packages/app/src/types/stream.test.ts | 29 +++++++++++++++++++ packages/app/src/types/stream.ts | 22 ++++++++++++++ 3 files changed, 65 insertions(+), 2 deletions(-) diff --git a/packages/app/src/components/git-diff-pane.tsx b/packages/app/src/components/git-diff-pane.tsx index 328f9c3e9..ed863eb26 100644 --- a/packages/app/src/components/git-diff-pane.tsx +++ b/packages/app/src/components/git-diff-pane.tsx @@ -359,8 +359,13 @@ const DiffFileSection = memo(function DiffFileSection({ color={theme.colors.foregroundMuted} /> - - {file.path} + + {file.path.split("/").pop()} + + {file.path.includes("/") + ? ` ${file.path.slice(0, file.path.lastIndexOf("/"))}` + : ""} + {file.isNew && ( @@ -1381,6 +1386,13 @@ const styles = StyleSheet.create((theme) => ({ color: theme.colors.foreground, flex: 1, }, + fileName: { + fontWeight: theme.fontWeight.semibold, + }, + fileDir: { + color: theme.colors.foregroundMuted, + fontWeight: theme.fontWeight.normal, + }, newBadge: { backgroundColor: "rgba(46, 160, 67, 0.2)", paddingHorizontal: theme.spacing[2], diff --git a/packages/app/src/types/stream.test.ts b/packages/app/src/types/stream.test.ts index 5e69a3828..53f024566 100644 --- a/packages/app/src/types/stream.test.ts +++ b/packages/app/src/types/stream.test.ts @@ -722,6 +722,31 @@ function testTodoWriteToolCallCreatesTodoList() { ); } +function testTodoWriteToolCallExecutingDoesNotRenderToolCall() { + const timestamp = new Date("2025-01-01T12:32:00Z"); + const event = toolTimelineWithInput({ + provider: "claude", + name: "TodoWrite", + status: "executing", + input: { + todos: [{ content: "Task", status: "pending" }], + }, + }); + + const state = reduceStreamUpdate([], event, timestamp); + const todoEntries = state.filter( + (item): item is TodoListItem => item.kind === "todo_list" + ); + const toolCalls = state.filter((item) => item.kind === "tool_call"); + + assert.strictEqual(todoEntries.length, 1); + assert.strictEqual( + toolCalls.length, + 0, + "TodoWrite (executing) should not render as a tool call" + ); +} + function testTimelineIdStabilityAfterRemovals() { const timestamp = new Date('2025-01-01T12:35:00Z'); @@ -1097,6 +1122,10 @@ describe('stream timeline reducers', () => { it('retains hydrated user messages across providers', testHydratedUserMessagesPersist); it('consolidates todo list updates', testTodoListConsolidation); it('renders TodoWrite as a task list', testTodoWriteToolCallCreatesTodoList); + it( + "does not render TodoWrite (executing) as a tool call", + testTodoWriteToolCallExecutingDoesNotRenderToolCall + ); it('keeps timeline ids stable after list shrinkage', testTimelineIdStabilityAfterRemovals); it('deduplicates live tool call entries', testToolCallDeduplicationLive); it('deduplicates hydrated tool call entries', testToolCallDeduplicationHydrated); diff --git a/packages/app/src/types/stream.ts b/packages/app/src/types/stream.ts index 328cca579..ff8114ec2 100644 --- a/packages/app/src/types/stream.ts +++ b/packages/app/src/types/stream.ts @@ -764,6 +764,28 @@ export function reduceStreamUpdate( break; } + if ( + event.provider === "claude" && + (normalizedToolName === "todowrite" || + normalizedToolName === "todo_write") + ) { + // For Claude: TodoWrite often appears as a tool call that never resolves. Always render it + // as Tasks when possible and otherwise hide it to avoid a stuck loading tool call. + const tasks = extractTaskEntriesFromToolCall(item.name, item.input); + if (tasks) { + nextState = appendTodoList( + state, + event.provider, + tasks.map((entry) => ({ + text: entry.text, + completed: entry.completed, + })), + timestamp + ); + } + break; + } + const tasks = extractTaskEntriesFromToolCall( item.name, item.input