diff --git a/packages/ui/src/components/chat/ChatInput.tsx b/packages/ui/src/components/chat/ChatInput.tsx index 96cef170..64696d3f 100644 --- a/packages/ui/src/components/chat/ChatInput.tsx +++ b/packages/ui/src/components/chat/ChatInput.tsx @@ -69,6 +69,7 @@ import { buildSessionTargetOptions } from '@/sync/session-worktree-contract'; import { usePermissionStore } from '@/stores/permissionStore'; import { extractGitChangedFiles } from './changedFiles'; import { useI18n } from '@/lib/i18n'; +import { sessionEvents } from '@/lib/sessionEvents'; import { fetchResponseStyleInstruction } from '@/lib/responseStyle'; import { wrapSystemReminder } from '@/lib/systemReminder'; import { getSyncMessages } from '@/sync/sync-refs'; @@ -1044,6 +1045,8 @@ const ChatInputComponent: React.FC = ({ onOpenSettings, scrollTo const currentGitStatus = useGitStore((state) => currentDirectory ? state.directories.get(currentDirectory)?.status ?? null : null, ); + const ensureGitStatus = useGitStore((state) => state.ensureStatus); + const fetchGitStatus = useGitStore((state) => state.fetchStatus); const [showAbortStatus, setShowAbortStatus] = React.useState(false); const setSessionAutoAccept = usePermissionStore((state) => state.setSessionAutoAccept); const composerHighlightRef = React.useRef(null); @@ -1065,6 +1068,19 @@ const ChatInputComponent: React.FC = ({ onOpenSettings, scrollTo setImagePreviewOpen(open); }, [setImagePreviewOpen]); + React.useEffect(() => { + if (!currentDirectory || !runtimeGit) return; + void ensureGitStatus(currentDirectory, runtimeGit); + }, [currentDirectory, runtimeGit, ensureGitStatus]); + + React.useEffect(() => { + if (!currentDirectory || !runtimeGit) return; + return sessionEvents.onGitRefreshHint((hint) => { + if (normalizePath(hint.directory) !== normalizePath(currentDirectory)) return; + void fetchGitStatus(currentDirectory, runtimeGit); + }); + }, [currentDirectory, runtimeGit, fetchGitStatus]); + const handleStartReviewFlow = React.useCallback(async (execution: ReviewFlowExecution) => { if (!currentSessionId) return; const directory = useSessionUIStore.getState().getDirectoryForSession(currentSessionId) || currentDirectory || ''; @@ -3556,7 +3572,6 @@ const ChatInputComponent: React.FC = ({ onOpenSettings, scrollTo ); const selectedDraftProjectIsGitRepo = useIsGitRepo(selectedDraftProjectPath); const hasDraftBranchList = Boolean(selectedDraftProjectBranches?.all); - const fetchGitStatus = useGitStore((state) => state.fetchStatus); const fetchBranches = useGitStore((state) => state.fetchBranches); const [isDiscoveringDraftBranches, setIsDiscoveringDraftBranches] = React.useState(false); diff --git a/packages/ui/src/components/chat/PendingChangesBar.tsx b/packages/ui/src/components/chat/PendingChangesBar.tsx index 5ef7ab55..bd8cb31d 100644 --- a/packages/ui/src/components/chat/PendingChangesBar.tsx +++ b/packages/ui/src/components/chat/PendingChangesBar.tsx @@ -4,8 +4,6 @@ import { useGitStore, useIsGitRepo } from '@/stores/useGitStore'; import { useUIStore } from '@/stores/useUIStore'; import { RuntimeAPIContext } from '@/contexts/runtimeAPIContext'; import { useMobileAppActions } from '@/apps/mobileAppContext'; -import { sessionEvents } from '@/lib/sessionEvents'; -import { normalizePath } from '@/components/session/sidebar/utils'; import { Icon } from "@/components/icon/Icon"; import { cn } from '@/lib/utils'; import { @@ -28,8 +26,6 @@ export const PendingChangesBar: React.FC = React.memo(() => { const gitStatus = useGitStore((s) => currentDirectory ? s.directories.get(currentDirectory)?.status ?? null : null, ); - const ensureStatus = useGitStore((s) => s.ensureStatus); - const fetchStatus = useGitStore((s) => s.fetchStatus); const mobileActions = useMobileAppActions(); // Close popover when clicking outside @@ -46,26 +42,6 @@ export const PendingChangesBar: React.FC = React.memo(() => { return () => document.removeEventListener("mousedown", handleClickOutside); }, [isExpanded]); - // Seed git store for currentDirectory so the bar can render independently of - // DiffView/GitView/right-sidebar mounting. ensureStatus has a 5s staleness - // gate and inFlightStatusFetchesByDirectory dedupes against concurrent callers. - React.useEffect(() => { - if (!currentDirectory || !runtime?.git) return; - void ensureStatus(currentDirectory, runtime.git); - }, [currentDirectory, runtime?.git, ensureStatus]); - - // Mirror the onGitRefreshHint listener that lives in DiffView/GitView so the - // bar refreshes after mutating tools (edit/write/apply_patch/bash/...) even - // when neither of those views is open — e.g. VS Code runtime. - React.useEffect(() => { - if (!currentDirectory || !runtime?.git) return; - const git = runtime.git; - return sessionEvents.onGitRefreshHint((hint) => { - if (normalizePath(hint.directory) !== normalizePath(currentDirectory)) return; - void fetchStatus(currentDirectory, git); - }); - }, [currentDirectory, runtime?.git, fetchStatus]); - const gitChangedFiles = React.useMemo(() => { if (isGitRepo !== true || !gitStatus || gitStatus.isClean) return []; return extractGitChangedFiles(gitStatus.files, gitStatus.diffStats, currentDirectory);