From 446e06fdc65b4616218e66ed64ecc5b614213ee3 Mon Sep 17 00:00:00 2001 From: Wes Date: Sat, 4 Apr 2026 10:59:51 -0700 Subject: [PATCH] fix: display all project directories in sidebar and toolbar (#96) The ProjectOption type used a singular workingDir that only captured the first directory. Switch to workingDirs array so every directory added in the project dialog is shown in the context panel, toolbar tooltip, and project selector dropdown. Co-authored-by: Claude Opus 4.6 --- ui/goose2/src/features/chat/ui/ChatInput.tsx | 2 +- .../src/features/chat/ui/ChatInputToolbar.tsx | 8 +++++-- ui/goose2/src/features/chat/ui/ChatView.tsx | 4 ++-- .../src/features/chat/ui/ContextPanel.tsx | 23 ++++++++++++------- .../chat/ui/__tests__/ChatInput.test.tsx | 4 ++-- .../chat/ui/__tests__/ContextPanel.test.tsx | 4 ++-- ui/goose2/src/features/home/ui/HomeScreen.tsx | 2 +- 7 files changed, 29 insertions(+), 18 deletions(-) diff --git a/ui/goose2/src/features/chat/ui/ChatInput.tsx b/ui/goose2/src/features/chat/ui/ChatInput.tsx index 0176c34681..14b48aef65 100644 --- a/ui/goose2/src/features/chat/ui/ChatInput.tsx +++ b/ui/goose2/src/features/chat/ui/ChatInput.tsx @@ -28,7 +28,7 @@ export interface ModelOption { export interface ProjectOption { id: string; name: string; - workingDir?: string | null; + workingDirs: string[]; color?: string | null; } diff --git a/ui/goose2/src/features/chat/ui/ChatInputToolbar.tsx b/ui/goose2/src/features/chat/ui/ChatInputToolbar.tsx index 975bcfa22b..1c425fd9b2 100644 --- a/ui/goose2/src/features/chat/ui/ChatInputToolbar.tsx +++ b/ui/goose2/src/features/chat/ui/ChatInputToolbar.tsx @@ -111,7 +111,9 @@ export function ChatInputToolbar({ (project) => project.id === selectedProjectId, ); const projectLabel = selectedProject?.name ?? "No project"; - const projectTitle = selectedProject?.workingDir ?? undefined; + const projectTitle = selectedProject?.workingDirs.length + ? selectedProject.workingDirs.join(", ") + : undefined; const providerLabel = availableProviderItems.find((provider) => provider.id === selectedProvider) ?.label ?? formatProviderLabel(selectedProvider); @@ -219,7 +221,9 @@ export function ChatInputToolbar({ ...availableProjects.map((project) => ({ value: project.id, label: project.name, - description: project.workingDir ?? undefined, + description: project.workingDirs.length + ? project.workingDirs.join(", ") + : undefined, icon: , })), ], diff --git a/ui/goose2/src/features/chat/ui/ChatView.tsx b/ui/goose2/src/features/chat/ui/ChatView.tsx index d6d6dde6e0..a960f81c07 100644 --- a/ui/goose2/src/features/chat/ui/ChatView.tsx +++ b/ui/goose2/src/features/chat/ui/ChatView.tsx @@ -112,7 +112,7 @@ export function ChatView({ .map((projectInfo) => ({ id: projectInfo.id, name: projectInfo.name, - workingDir: projectInfo.workingDirs[0] ?? null, + workingDirs: projectInfo.workingDirs, color: projectInfo.color, })), [projects], @@ -451,7 +451,7 @@ export function ChatView({ diff --git a/ui/goose2/src/features/chat/ui/ContextPanel.tsx b/ui/goose2/src/features/chat/ui/ContextPanel.tsx index 95c4fcd45c..1694d98f87 100644 --- a/ui/goose2/src/features/chat/ui/ContextPanel.tsx +++ b/ui/goose2/src/features/chat/ui/ContextPanel.tsx @@ -17,7 +17,7 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/shared/ui/tabs"; interface ContextPanelProps { projectName?: string; projectColor?: string; - projectWorkingDir?: string | null; + projectWorkingDirs?: string[]; } type ContextPanelTab = "details" | "files"; @@ -52,16 +52,17 @@ function Widget({ export function ContextPanel({ projectName, projectColor, - projectWorkingDir, + projectWorkingDirs = [], }: ContextPanelProps) { const [activeTab, setActiveTab] = useState("details"); + const primaryWorkingDir = projectWorkingDirs[0] ?? null; const { data: gitState, error, isLoading, isFetching, refetch, - } = useGitState(projectWorkingDir, activeTab === "details"); + } = useGitState(primaryWorkingDir, activeTab === "details"); const gitErrorMessage = error instanceof Error ? error.message : "Unable to read git status."; @@ -94,7 +95,7 @@ export function ContextPanel({ variant="ghost" size="icon-xs" onClick={() => void refetch()} - disabled={!projectWorkingDir || isFetching} + disabled={!primaryWorkingDir || isFetching} className="rounded-md" aria-label="Refresh git status" title="Refresh git status" @@ -125,11 +126,17 @@ export function ContextPanel({ ) : (

No project assigned.

)} -

- {projectWorkingDir ?? "Folder not set"} -

+ {projectWorkingDirs.length > 0 ? ( + projectWorkingDirs.map((dir) => ( +

+ {dir} +

+ )) + ) : ( +

Folder not set

+ )} - {!projectWorkingDir ? null : isLoading && !gitState ? ( + {!primaryWorkingDir ? null : isLoading && !gitState ? (
Loading git status… diff --git a/ui/goose2/src/features/chat/ui/__tests__/ChatInput.test.tsx b/ui/goose2/src/features/chat/ui/__tests__/ChatInput.test.tsx index 032b35be03..ecaeacde70 100644 --- a/ui/goose2/src/features/chat/ui/__tests__/ChatInput.test.tsx +++ b/ui/goose2/src/features/chat/ui/__tests__/ChatInput.test.tsx @@ -143,7 +143,7 @@ describe("ChatInput", () => { { id: "project-1", name: "goose2", - workingDir: "/Users/wesb/dev/goose2", + workingDirs: ["/Users/wesb/dev/goose2"], }, ]} />, @@ -169,7 +169,7 @@ describe("ChatInput", () => { { id: "project-1", name: "goose2", - workingDir: "/Users/wesb/dev/goose2", + workingDirs: ["/Users/wesb/dev/goose2"], }, ]} />, diff --git a/ui/goose2/src/features/chat/ui/__tests__/ContextPanel.test.tsx b/ui/goose2/src/features/chat/ui/__tests__/ContextPanel.test.tsx index aa68aa0c86..9f5dd90103 100644 --- a/ui/goose2/src/features/chat/ui/__tests__/ContextPanel.test.tsx +++ b/ui/goose2/src/features/chat/ui/__tests__/ContextPanel.test.tsx @@ -54,7 +54,7 @@ describe("ContextPanel", () => { , ); @@ -87,7 +87,7 @@ describe("ContextPanel", () => { refetch: vi.fn(), }); - render(); + render(); expect(screen.getByText("Not a git repository.")).toBeInTheDocument(); }); diff --git a/ui/goose2/src/features/home/ui/HomeScreen.tsx b/ui/goose2/src/features/home/ui/HomeScreen.tsx index e21b82bdb9..4c7c61ca58 100644 --- a/ui/goose2/src/features/home/ui/HomeScreen.tsx +++ b/ui/goose2/src/features/home/ui/HomeScreen.tsx @@ -132,7 +132,7 @@ export function HomeScreen({ onStartChat, onCreateProject }: HomeScreenProps) { availableProjects={projects.map((project) => ({ id: project.id, name: project.name, - workingDir: project.workingDirs[0] ?? null, + workingDirs: project.workingDirs, color: project.color, }))} onProjectChange={setSelectedProjectId}