From 5a5d7b938615e274bbdb631dd2b57d1d4b7a7b53 Mon Sep 17 00:00:00 2001 From: Brooklyn Nicholson Date: Mon, 27 Jul 2026 16:05:19 -0500 Subject: [PATCH] feat(desktop): pin Home to the top of the project sidebar MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Home leads the overview above the active project and outside any drag order, drills in to a flat chat list (it has no repo or worktree structure), and overlays live sessions so a brand-new detached chat appears instantly. Starting a chat from inside Home stays detached instead of picking up the configured default project dir. Rename and delete are hidden — there's no record behind the row. --- apps/desktop/src/app/chat/sidebar/index.tsx | 31 ++++++---- .../chat/sidebar/projects/entered-content.tsx | 6 ++ .../app/chat/sidebar/projects/model.test.ts | 26 +++++++- .../src/app/chat/sidebar/projects/model.ts | 17 ++++-- .../sidebar/projects/overview-row.test.tsx | 8 +++ .../chat/sidebar/projects/overview-row.tsx | 10 ++-- .../sidebar/projects/workspace-groups.test.ts | 46 +++++++++++++++ .../chat/sidebar/projects/workspace-groups.ts | 59 ++++++++++++++++--- .../src/app/chat/sidebar/sessions-section.tsx | 51 +++++++++------- apps/desktop/src/store/projects.test.ts | 36 +++++++++-- apps/desktop/src/store/projects.ts | 20 +++++-- 11 files changed, 251 insertions(+), 59 deletions(-) diff --git a/apps/desktop/src/app/chat/sidebar/index.tsx b/apps/desktop/src/app/chat/sidebar/index.tsx index c1f00e5777c..8652ade4e2f 100644 --- a/apps/desktop/src/app/chat/sidebar/index.tsx +++ b/apps/desktop/src/app/chat/sidebar/index.tsx @@ -615,7 +615,13 @@ export function ChatSidebar({ const sorted = sortProjectsForOverview( projectTree .filter(node => !(node.isAuto && dismissed.has(node.id))) - .map(project => ({ ...project, repos: orderRepos(project.repos) })), + .map(project => ({ + ...project, + // Home is synthetic, so its name is ours to translate — every other + // label is a repo basename or a name the user typed. + label: project.isNoProject ? s.projects.home : project.label, + repos: orderRepos(project.repos) + })), activeProjectId ) @@ -623,7 +629,7 @@ export function ChatSidebar({ // (default) returns `sorted` untouched; projects the user hasn't ordered yet // keep their sorted position rather than jumping the hand-picked list. return orderProjectsByIds(sorted, projectOrderIds) - }, [showAllProfiles, projectTree, dismissedAutoProjects, orderRepos, activeProjectId, projectOrderIds]) + }, [showAllProfiles, projectTree, dismissedAutoProjects, orderRepos, activeProjectId, projectOrderIds, s]) // The overview only renders in grouped mode; the model stays live regardless // so scoping is consistent across views. @@ -685,7 +691,9 @@ export function ChatSidebar({ // The live-session overlay (creates/evictions) is applied per-repo in // RepoFlatSection, AFTER the visual git-worktree lanes are merged in (so // out-of-tree worktrees can be placed). Here we just order the snapshot. - return { ...hydrated, repos: orderRepos(hydrated.repos) } + // The label comes from the overview node either way — that's the model's + // presentation copy (Home is translated there), not the raw payload's. + return { ...hydrated, label: overviewEnteredProject.label, repos: orderRepos(hydrated.repos) } }, [overviewEnteredProject, enteredProjectTree, orderRepos]) // Overlay live `$sessions` onto the entered project so a just-created session @@ -785,7 +793,7 @@ export function ChatSidebar({ // Preview rows come from the backend tree (each project carries its // most-recent sessions), overlaid with live $sessions so a just-created // session shows under its project instantly (and with its working arc), - // matching the flat Recents list. Keyed by project path for the rows. + // matching the flat Recents list. Keyed by project id for the rows. const overviewPreviews = useMemo>( () => overlayLivePreviews(projectOverview ?? [], agentSessions, projects, PROJECT_PREVIEW_COUNT, removedSessionIds), [projectOverview, agentSessions, projects, removedSessionIds] @@ -1304,12 +1312,15 @@ export function ChatSidebar({ {enteredProject.path && ( )} - + {/* Home has no folder and no record to rename, theme, or delete. */} + {!enteredProject.isNoProject && ( + + )}