From d849742d225add34908ee367bdc38b8b487d1e5f Mon Sep 17 00:00:00 2001 From: Bohdan Triapitsyn Date: Sat, 22 Aug 2026 01:31:02 +0300 Subject: [PATCH] fix(chats): hide repository work status Prevent managed Chat drafts and sessions from inheriting an active project's repository context in the Work Status panel while retaining directory-independent status sections. --- packages/ui/src/components/chat/ChatContainer.tsx | 8 +++++++- .../ui/src/components/chat/work-status/DOCUMENTATION.md | 5 +++++ .../src/components/chat/work-status/WorkStatusPanel.tsx | 6 ++++-- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/packages/ui/src/components/chat/ChatContainer.tsx b/packages/ui/src/components/chat/ChatContainer.tsx index 5d370e3e..3aff86c8 100644 --- a/packages/ui/src/components/chat/ChatContainer.tsx +++ b/packages/ui/src/components/chat/ChatContainer.tsx @@ -60,6 +60,7 @@ import { findShellCommandForMessage, isUserShellMarkerMessage } from './lib/shel import { resolveChatPromptReadOnly } from './chatPromptReadOnly'; import { getRuntimeKey } from '@/lib/runtime-switch'; import { createFirstVisibleSessionPerformanceTracker } from '@/sync/session-load-performance'; +import { isChatDirectoryPath } from '@/lib/chatDirectories'; const EMPTY_MESSAGES: Array<{ info: Message; parts: Part[] }> = []; const IDLE_SESSION_STATUS = { type: 'idle' as const }; @@ -738,12 +739,15 @@ export const ChatContainer: React.FC = ({ const isVSCode = isVSCodeRuntime(); const chatSurfaceMode = useChatSurfaceMode(); const draftOpen = Boolean(newSessionDraft?.open); + const isManagedChatContext = draftOpen + ? newSessionDraft?.target === 'chat' + : isChatDirectoryPath(effectiveSessionDirectory); // A draft can target another project or a pending worktree before it has a // session. Keep the panel on that same directory so its project, MCP, and // usage readouts describe where the draft will run rather than the project // the user came from. const workStatusDirectory = draftOpen - ? newSessionDraft?.bootstrapPendingDirectory ?? newSessionDraft?.directoryOverride ?? effectiveSessionDirectory + ? (isManagedChatContext ? null : newSessionDraft?.bootstrapPendingDirectory ?? newSessionDraft?.directoryOverride ?? effectiveSessionDirectory) : effectiveSessionDirectory; const initError = useGlobalSyncStore((s) => s.error); // Despite the historical name, this now covers mobile too: the mobile @@ -1320,6 +1324,7 @@ export const ChatContainer: React.FC = ({ visible={showWorkStatusOverlay} sessionId={currentSessionId ?? null} directory={workStatusDirectory ?? null} + repositoryEnabled={!isManagedChatContext} /> ) : null} @@ -1342,6 +1347,7 @@ export const ChatContainer: React.FC = ({ visible={showWorkStatusPanel} sessionId={currentSessionId ?? null} directory={workStatusDirectory ?? null} + repositoryEnabled={!isManagedChatContext} /> ) : null} diff --git a/packages/ui/src/components/chat/work-status/DOCUMENTATION.md b/packages/ui/src/components/chat/work-status/DOCUMENTATION.md index 0d9b9712..d2a872c6 100644 --- a/packages/ui/src/components/chat/work-status/DOCUMENTATION.md +++ b/packages/ui/src/components/chat/work-status/DOCUMENTATION.md @@ -54,6 +54,11 @@ mode. It remains available on a new-session draft: when the draft targets a project or pending worktree, the panel uses that directory for project, MCP, and usage readouts before a session exists. +Managed Chats never render or warm the Project repository section. A Chat draft +also passes no fallback directory to the panel, so an active project's branch +cannot leak into the draft while directory-independent sections remain +available. + `rowRef` is a **callback ref, not an object ref**. An object ref gives no signal when the node attaches, so the measuring effect read `.current`, found nothing whenever the row mounted after the effect first ran, and only recovered on the diff --git a/packages/ui/src/components/chat/work-status/WorkStatusPanel.tsx b/packages/ui/src/components/chat/work-status/WorkStatusPanel.tsx index 3f769d58..af097a23 100644 --- a/packages/ui/src/components/chat/work-status/WorkStatusPanel.tsx +++ b/packages/ui/src/components/chat/work-status/WorkStatusPanel.tsx @@ -26,6 +26,8 @@ type Props = { /** Null on a new-session draft: repository readouts still apply. */ sessionId: string | null; directory: string | null; + /** Managed Chats have no project repository, even if another project remains active. */ + repositoryEnabled?: boolean; /** Whether the panel should currently occupy space. */ visible: boolean; /** @@ -63,7 +65,7 @@ const PANEL_TRANSITION_EASING = 'cubic-bezier(0.22, 1, 0.36, 1)'; * eat a visible slice of every row's trailing value, and the shadows already * say there is more to see. */ -export const WorkStatusPanel: React.FC = ({ sessionId, directory, visible, overlay = false }) => { +export const WorkStatusPanel: React.FC = ({ sessionId, directory, visible, repositoryEnabled = true, overlay = false }) => { const { t } = useI18n(); const setScrollTop = useUIStore((state) => state.setWorkStatusScrollTop); const setOverlayOpen = useUIStore((state) => state.setWorkStatusOverlayOpen); @@ -248,7 +250,7 @@ export const WorkStatusPanel: React.FC = ({ sessionId, directory, visible sessionId={sessionId} directory={directory} showSession={sectionVisible('session')} - showRepository={sectionVisible('repository')} + showRepository={repositoryEnabled && sectionVisible('repository')} goalRow={} /> {sectionVisible('usage') ? : null}