From 522cebf127aff3098f9defae3a03c56a899d3def Mon Sep 17 00:00:00 2001 From: Bohdan Triapitsyn Date: Thu, 23 Apr 2026 10:55:27 +0300 Subject: [PATCH] fix: hide empty input status row Only show the pending changes accessory when workspace changes exist Remove wasted vertical space above the composer when the status row is empty --- packages/ui/src/components/chat/ChatInput.tsx | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/packages/ui/src/components/chat/ChatInput.tsx b/packages/ui/src/components/chat/ChatInput.tsx index 6801a3ca..be02e6c1 100644 --- a/packages/ui/src/components/chat/ChatInput.tsx +++ b/packages/ui/src/components/chat/ChatInput.tsx @@ -65,11 +65,13 @@ import { useChatSearchDirectory } from '@/hooks/useChatSearchDirectory'; import { opencodeClient } from '@/lib/opencode/client'; import { useProjectsStore } from '@/stores/useProjectsStore'; import { PROJECT_COLOR_MAP, PROJECT_ICON_MAP, getProjectIconImageUrl } from '@/lib/projectMeta'; -import { useGitBranches, useGitStore } from '@/stores/useGitStore'; +import { useGitBranches, useGitStore, useIsGitRepo } from '@/stores/useGitStore'; +import { useDirectoryStore } from '@/stores/useDirectoryStore'; import { useRuntimeAPIs } from '@/hooks/useRuntimeAPIs'; import { createWorktreeDraft } from '@/lib/worktreeSessionCreator'; import { buildSessionTargetOptions } from '@/sync/session-worktree-contract'; import { usePermissionStore } from '@/stores/permissionStore'; +import { extractGitChangedFiles } from './changedFiles'; const MAX_VISIBLE_TEXTAREA_LINES = 8; const EMPTY_QUEUE: QueuedMessage[] = []; @@ -750,6 +752,7 @@ const ChatInputComponent: React.FC = ({ onOpenSettings, scrollTo Promise.resolve((useSessionUIStore.getState().sendMessage as (...a: unknown[]) => unknown)(...args)), ).current; const currentSessionId = useSessionUIStore((s) => s.currentSessionId); + const currentDirectory = useDirectoryStore((s) => s.currentDirectory); const newSessionDraft = useSessionUIStore((s) => s.newSessionDraft); const newSessionDraftOpen = Boolean(newSessionDraft?.open); const setNewSessionDraftTarget = useSessionUIStore((s) => s.setNewSessionDraftTarget); @@ -792,6 +795,10 @@ const ChatInputComponent: React.FC = ({ onOpenSettings, scrollTo const { git: runtimeGit } = useRuntimeAPIs(); const { currentTheme } = useThemeSystem(); const chatSearchDirectory = useChatSearchDirectory(); + const isGitRepo = useIsGitRepo(currentDirectory); + const currentGitStatus = useGitStore((state) => + currentDirectory ? state.directories.get(currentDirectory)?.status ?? null : null, + ); const [showAbortStatus, setShowAbortStatus] = React.useState(false); const setSessionAutoAccept = usePermissionStore((state) => state.setSessionAutoAccept); const composerHighlightRef = React.useRef(null); @@ -3139,6 +3146,13 @@ const ChatInputComponent: React.FC = ({ onOpenSettings, scrollTo return draftBranchItems.find((item) => item.value === selectedValue)?.label ?? formatDirectoryName(selectedValue); }, [draftBranchItems, selectedDraftDirectory]); + const hasPendingChanges = React.useMemo(() => { + if (isGitRepo !== true || !currentGitStatus || currentGitStatus.isClean) { + return false; + } + return extractGitChangedFiles(currentGitStatus.files, currentGitStatus.diffStats, currentDirectory).length > 0; + }, [currentDirectory, currentGitStatus, isGitRepo]); + const selectedDraftBranchIsKnown = React.useMemo(() => { if (!selectedDraftDirectory) { return true; @@ -3448,7 +3462,7 @@ const ChatInputComponent: React.FC = ({ onOpenSettings, scrollTo showAbortStatus={showAbortStatus} showAssistantStatus={false} showTodos - leftAccessory={newSessionDraftOpen ? null : } + leftAccessory={newSessionDraftOpen || !hasPendingChanges ? null : } /> {showDraftTargetSelectors && selectedDraftProject ? (