From c47dca92e73faa4a7d8d4e2179c0afa47af37098 Mon Sep 17 00:00:00 2001 From: Jake Leventhal Date: Tue, 14 Jul 2026 19:40:19 -0400 Subject: [PATCH 1/4] Add standalone chats sidebar section --- apps/web/src/components/CommandPalette.tsx | 10 +- apps/web/src/components/Sidebar.tsx | 279 ++++++++++++++++++++- apps/web/src/generalChats.test.ts | 59 +++++ apps/web/src/generalChats.ts | 33 +++ apps/web/src/hooks/useHandleNewThread.ts | 3 +- 5 files changed, 366 insertions(+), 18 deletions(-) create mode 100644 apps/web/src/generalChats.test.ts create mode 100644 apps/web/src/generalChats.ts diff --git a/apps/web/src/components/CommandPalette.tsx b/apps/web/src/components/CommandPalette.tsx index 8dccf984457..65fbf09d02f 100644 --- a/apps/web/src/components/CommandPalette.tsx +++ b/apps/web/src/components/CommandPalette.tsx @@ -112,6 +112,7 @@ import { AzureDevOpsIcon, BitbucketIcon, GitHubIcon, GitLabIcon } from "./Icons" import { ProjectFavicon } from "./ProjectFavicon"; import { ThreadRowLeadingStatus, ThreadRowTrailingStatus } from "./ThreadStatusIndicators"; import { primaryServerKeybindingsAtom } from "../state/server"; +import { excludeGeneralChatsProject } from "../generalChats"; import { resolveShortcutCommand } from "../keybindings"; import { Command, @@ -474,6 +475,7 @@ function OpenCommandPaletteDialog(props: { const { activeDraftThread, activeThread, defaultProjectRef, handleNewThread } = useHandleNewThread(); const projects = useProjects(); + const regularProjects = useMemo(() => excludeGeneralChatsProject(projects), [projects]); const threads = useThreadShells(); const keybindings = useAtomValue(primaryServerKeybindingsAtom); const [viewStack, setViewStack] = useState([]); @@ -653,7 +655,7 @@ function OpenCommandPaletteDialog(props: { const projectSearchItems = useMemo( () => buildProjectActionItems({ - projects, + projects: regularProjects, valuePrefix: "project", icon: (project) => ( buildProjectActionItems({ - projects, + projects: regularProjects, valuePrefix: "new-thread-in", shortcutCommand: "chat.new", icon: (project) => ( @@ -692,7 +694,7 @@ function OpenCommandPaletteDialog(props: { ); }, }), - [activeDraftThread, activeThread, defaultProjectRef, handleNewThread, projects], + [activeDraftThread, activeThread, defaultProjectRef, handleNewThread, regularProjects], ); const allThreadItems = useMemo( diff --git a/apps/web/src/components/Sidebar.tsx b/apps/web/src/components/Sidebar.tsx index 21525b56b77..6860148f858 100644 --- a/apps/web/src/components/Sidebar.tsx +++ b/apps/web/src/components/Sidebar.tsx @@ -43,8 +43,10 @@ import { restrictToFirstScrollableAncestor, restrictToVerticalAxis } from "@dnd- import { CSS } from "@dnd-kit/utilities"; import { type ContextMenuItem, + DEFAULT_MODEL, DEFAULT_SERVER_SETTINGS, ProjectId, + ProviderInstanceId, type ScopedThreadRef, type ResolvedKeybindingsConfig, type SidebarProjectGroupingMode, @@ -221,6 +223,13 @@ import { type SidebarProjectSnapshot, } from "../sidebarProjectGrouping"; import { SidebarProviderUpdatePill } from "./sidebar/SidebarProviderUpdatePill"; +import { + excludeGeneralChatsProject, + findGeneralChatsProject, + GENERAL_CHATS_PROJECT_ID, + GENERAL_CHATS_PROJECT_TITLE, + GENERAL_CHATS_WORKSPACE_ROOT, +} from "../generalChats"; const SIDEBAR_SORT_LABELS: Record = { updated_at: "Last user message", created_at: "Created at", @@ -931,6 +940,7 @@ interface SidebarProjectThreadListProps { openPrLink: (event: React.MouseEvent, prUrl: string) => void; expandThreadListForProject: (projectKey: string) => void; collapseThreadListForProject: (projectKey: string) => void; + emptyLabel?: string; } const SidebarProjectThreadList = memo(function SidebarProjectThreadList( @@ -971,6 +981,7 @@ const SidebarProjectThreadList = memo(function SidebarProjectThreadList( openPrLink, expandThreadListForProject, collapseThreadListForProject, + emptyLabel = "No threads yet", } = props; const showMoreButtonRender = useMemo(() =>