From 361cb06bf02015339bce7906d75df7015dfbb201 Mon Sep 17 00:00:00 2001 From: Shirone Date: Thu, 15 Jan 2026 19:11:25 +0100 Subject: [PATCH] fix(ui): improve React Query hooks and fix edge cases - Update query keys to include all relevant parameters (branches, agents) - Fix use-branches to pass includeRemote parameter to query key - Fix use-settings to include sources in agents query key - Update running-agents-view to use correct query key structure - Update use-spec-loading to properly use spec query hooks - Add missing queryClient invalidation in auto-mode mutations - Add missing cache invalidation in spec mutations after creation Co-Authored-By: Claude Opus 4.5 --- apps/ui/src/components/session-manager.tsx | 12 +++++++---- apps/ui/src/components/usage-popover.tsx | 4 ++-- .../worktree-panel/hooks/use-branches.ts | 6 ++++-- .../components/views/running-agents-view.tsx | 6 +++--- .../views/spec-view/hooks/use-spec-loading.ts | 10 ++++----- .../mutations/use-auto-mode-mutations.ts | 21 ++++++++++++++++--- .../hooks/mutations/use-github-mutations.ts | 6 +++++- .../src/hooks/mutations/use-spec-mutations.ts | 5 +++++ apps/ui/src/hooks/queries/use-settings.ts | 3 ++- apps/ui/src/hooks/queries/use-worktrees.ts | 3 ++- apps/ui/src/lib/query-keys.ts | 6 ++++-- 11 files changed, 57 insertions(+), 25 deletions(-) diff --git a/apps/ui/src/components/session-manager.tsx b/apps/ui/src/components/session-manager.tsx index c4b7f119..fb349a4a 100644 --- a/apps/ui/src/components/session-manager.tsx +++ b/apps/ui/src/components/session-manager.tsx @@ -1,4 +1,4 @@ -import { useState, useEffect, useCallback } from 'react'; +import { useState, useEffect, useCallback, useRef } from 'react'; import { createLogger } from '@automaker/utils/logger'; import { useQueryClient } from '@tanstack/react-query'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; @@ -119,6 +119,9 @@ export function SessionManager({ // Use React Query for sessions list - always include archived, filter client-side const { data: sessions = [], refetch: refetchSessions } = useSessions(true); + // Ref to track if we've done the initial running sessions check + const hasCheckedInitialRef = useRef(false); + // Check running state for all sessions const checkRunningSessions = useCallback(async (sessionList: SessionListItem[]) => { const api = getElectronAPI(); @@ -152,12 +155,13 @@ export function SessionManager({ } }, [queryClient, refetchSessions, checkRunningSessions]); - // Check running state on initial load + // Check running state on initial load (runs only once when sessions first load) useEffect(() => { - if (sessions.length > 0) { + if (sessions.length > 0 && !hasCheckedInitialRef.current) { + hasCheckedInitialRef.current = true; checkRunningSessions(sessions); } - }, [sessions.length > 0]); // Only run when sessions first load + }, [sessions, checkRunningSessions]); // Periodically check running state for sessions (useful for detecting when agents finish) useEffect(() => { diff --git a/apps/ui/src/components/usage-popover.tsx b/apps/ui/src/components/usage-popover.tsx index a4db928a..3032388c 100644 --- a/apps/ui/src/components/usage-popover.tsx +++ b/apps/ui/src/components/usage-popover.tsx @@ -304,7 +304,7 @@ export function UsagePopover() { variant="ghost" size="icon" className={cn('h-6 w-6', claudeLoading && 'opacity-80')} - onClick={() => !claudeLoading && fetchClaudeUsage(false)} + onClick={() => !claudeLoading && fetchClaudeUsage()} > @@ -411,7 +411,7 @@ export function UsagePopover() { variant="ghost" size="icon" className={cn('h-6 w-6', codexLoading && 'opacity-80')} - onClick={() => !codexLoading && fetchCodexUsage(false)} + onClick={() => !codexLoading && fetchCodexUsage()} > diff --git a/apps/ui/src/components/views/board-view/worktree-panel/hooks/use-branches.ts b/apps/ui/src/components/views/board-view/worktree-panel/hooks/use-branches.ts index eeca9729..7b84dfe9 100644 --- a/apps/ui/src/components/views/board-view/worktree-panel/hooks/use-branches.ts +++ b/apps/ui/src/components/views/board-view/worktree-panel/hooks/use-branches.ts @@ -22,9 +22,11 @@ export function useBranches() { const branches = branchData?.branches ?? []; const aheadCount = branchData?.aheadCount ?? 0; const behindCount = branchData?.behindCount ?? 0; + // Use conservative defaults (false) until data is confirmed + // This prevents the UI from assuming git capabilities before the query completes const gitRepoStatus: GitRepoStatus = { - isGitRepo: branchData?.isGitRepo ?? true, - hasCommits: branchData?.hasCommits ?? true, + isGitRepo: branchData?.isGitRepo ?? false, + hasCommits: branchData?.hasCommits ?? false, }; const fetchBranches = useCallback( diff --git a/apps/ui/src/components/views/running-agents-view.tsx b/apps/ui/src/components/views/running-agents-view.tsx index 4575b84e..326146e1 100644 --- a/apps/ui/src/components/views/running-agents-view.tsx +++ b/apps/ui/src/components/views/running-agents-view.tsx @@ -34,8 +34,8 @@ export function RunningAgentsView() { }, [refetch]); const handleStopAgent = useCallback( - (featureId: string) => { - stopFeature.mutate(featureId); + (featureId: string, projectPath: string) => { + stopFeature.mutate({ featureId, projectPath }); }, [stopFeature] ); @@ -168,7 +168,7 @@ export function RunningAgentsView() {