From 00d8c1a92c153d1988df0888c0648e149282408e Mon Sep 17 00:00:00 2001 From: Paul D'Ambra Date: Sun, 17 May 2026 13:34:42 +0000 Subject: [PATCH 1/3] fix(tasks): show renames instantly in sidebar and never overwrite them Two related issues with manual task renames: 1. The sidebar task list reads from the ["tasks", "summaries"] query cache (via useTaskSummaries), but the rename optimistic update and onSuccess invalidation only touched ["tasks", "list"]. The sidebar therefore waited up to 30s (the polling interval) to show the new title, even though the header updated instantly. Now both caches are updated optimistically and invalidated on success. 2. useChatTitleGenerator skipped the title_manually_set check on the first generation, so if a user renamed a task before the first prompt's auto- title finished, their rename got clobbered. title_manually_set is now respected unconditionally. Generated-By: PostHog Code Task-Id: 07a0cd34-65e0-4e58-bbc9-d9d103d1f251 --- .../renderer/features/sidebar/components/SidebarMenu.tsx | 9 +++++++++ apps/code/src/renderer/features/tasks/hooks/useTasks.ts | 3 +++ 2 files changed, 12 insertions(+) diff --git a/apps/code/src/renderer/features/sidebar/components/SidebarMenu.tsx b/apps/code/src/renderer/features/sidebar/components/SidebarMenu.tsx index 05fb194af..8edd66f80 100644 --- a/apps/code/src/renderer/features/sidebar/components/SidebarMenu.tsx +++ b/apps/code/src/renderer/features/sidebar/components/SidebarMenu.tsx @@ -18,6 +18,7 @@ import { useWorkspaces } from "@features/workspace/hooks/useWorkspace"; import { useTaskContextMenu } from "@hooks/useTaskContextMenu"; import { ScrollArea, Separator } from "@posthog/quill"; import { Box, Flex } from "@radix-ui/themes"; +import type { Schemas } from "@renderer/api/generated"; import type { Task } from "@shared/types"; import { useNavigationStore } from "@stores/navigationStore"; import { useRendererWindowFocusStore } from "@stores/rendererWindowFocusStore"; @@ -273,6 +274,13 @@ function SidebarMenuComponent() { : task, ), ); + queryClient.setQueriesData( + { queryKey: ["tasks", "summaries"] }, + (old) => + old?.map((task) => + task.id === taskId ? { ...task, title: newTitle } : task, + ), + ); // Sync to session store so notifications use the updated title getSessionService().updateSessionTaskTitle(taskId, newTitle); @@ -286,6 +294,7 @@ function SidebarMenuComponent() { log.error("Failed to rename task", error); // Refetch to revert optimistic update on failure queryClient.invalidateQueries({ queryKey: ["tasks", "list"] }); + queryClient.invalidateQueries({ queryKey: ["tasks", "summaries"] }); } }, [setEditingTaskId, updateTask, queryClient, log], diff --git a/apps/code/src/renderer/features/tasks/hooks/useTasks.ts b/apps/code/src/renderer/features/tasks/hooks/useTasks.ts index 07c5f7e6b..32491e6b5 100644 --- a/apps/code/src/renderer/features/tasks/hooks/useTasks.ts +++ b/apps/code/src/renderer/features/tasks/hooks/useTasks.ts @@ -136,6 +136,9 @@ export function useUpdateTask() { onSuccess: (_, { taskId }) => { queryClient.invalidateQueries({ queryKey: taskKeys.lists() }); queryClient.invalidateQueries({ queryKey: taskKeys.detail(taskId) }); + queryClient.invalidateQueries({ + queryKey: [...taskKeys.all, "summaries"], + }); }, }, ); From bffacd93b6a307a336204aa5308f9831ec9128ea Mon Sep 17 00:00:00 2001 From: Paul D'Ambra Date: Sun, 17 May 2026 13:52:56 +0000 Subject: [PATCH 2/3] fix(tasks): also write auto-titles into the summaries cache MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The auto-title path calls client.updateTask directly (not via useUpdateTask), so the onSuccess invalidation added earlier in this PR doesn't fire here. Without this, an auto-generated title would still take up to 30 s to appear in the sidebar — the same root cause this PR fixes for manual renames. Generated-By: PostHog Code Task-Id: 07a0cd34-65e0-4e58-bbc9-d9d103d1f251 --- .../features/sessions/hooks/useChatTitleGenerator.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/apps/code/src/renderer/features/sessions/hooks/useChatTitleGenerator.ts b/apps/code/src/renderer/features/sessions/hooks/useChatTitleGenerator.ts index 048436046..22f748019 100644 --- a/apps/code/src/renderer/features/sessions/hooks/useChatTitleGenerator.ts +++ b/apps/code/src/renderer/features/sessions/hooks/useChatTitleGenerator.ts @@ -4,6 +4,7 @@ import { sessionStoreSetters, useSessionStore, } from "@features/sessions/stores/sessionStore"; +import type { Schemas } from "@renderer/api/generated"; import type { Task } from "@shared/types"; import { enrichDescriptionWithFileContent, @@ -88,6 +89,13 @@ export function useChatTitleGenerator(taskId: string): void { task.id === taskId ? { ...task, title } : task, ), ); + queryClient.setQueriesData( + { queryKey: ["tasks", "summaries"] }, + (old) => + old?.map((task) => + task.id === taskId ? { ...task, title } : task, + ), + ); getSessionService().updateSessionTaskTitle(taskId, title); log.debug("Updated task title from conversation", { taskId, From 4960647f74d87345c2d92119d5246a22e6da3ae8 Mon Sep 17 00:00:00 2001 From: Paul D'Ambra Date: Sun, 17 May 2026 14:09:40 +0000 Subject: [PATCH 3/3] test(tasks): assert auto-title writes to both list and summaries caches Regression guard for the previous commit so the summaries-cache write in useChatTitleGenerator can't be silently dropped. Generated-By: PostHog Code Task-Id: 07a0cd34-65e0-4e58-bbc9-d9d103d1f251 --- .../features/sessions/hooks/useChatTitleGenerator.test.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/apps/code/src/renderer/features/sessions/hooks/useChatTitleGenerator.test.ts b/apps/code/src/renderer/features/sessions/hooks/useChatTitleGenerator.test.ts index ee11f6323..a68a1d52f 100644 --- a/apps/code/src/renderer/features/sessions/hooks/useChatTitleGenerator.test.ts +++ b/apps/code/src/renderer/features/sessions/hooks/useChatTitleGenerator.test.ts @@ -101,6 +101,14 @@ describe("useChatTitleGenerator", () => { title: "Fix login bug", }); }); + expect(mockSetQueriesData).toHaveBeenCalledWith( + { queryKey: ["tasks", "list"] }, + expect.any(Function), + ); + expect(mockSetQueriesData).toHaveBeenCalledWith( + { queryKey: ["tasks", "summaries"] }, + expect.any(Function), + ); }); it.each([