@@ -84,6 +84,7 @@ import { useThreadSelectionStore } from "../threadSelectionStore";
8484import { formatWorktreePathForDisplay , getOrphanedWorktreePathForThread } from "../worktreeCleanup" ;
8585import { isNonEmpty as isNonEmptyString } from "effect/String" ;
8686import {
87+ resolveProjectStatusIndicator ,
8788 resolveSidebarNewThreadEnvMode ,
8889 resolveThreadRowClassName ,
8990 resolveThreadStatusPill ,
@@ -1340,13 +1341,22 @@ export default function Sidebar() {
13401341 if ( byDate !== 0 ) return byDate ;
13411342 return b . id . localeCompare ( a . id ) ;
13421343 } ) ;
1344+ const projectStatus = resolveProjectStatusIndicator (
1345+ projectThreads . map ( ( thread ) =>
1346+ resolveThreadStatusPill ( {
1347+ thread,
1348+ hasPendingApprovals : derivePendingApprovals ( thread . activities ) . length > 0 ,
1349+ hasPendingUserInput : derivePendingUserInputs ( thread . activities ) . length > 0 ,
1350+ } ) ,
1351+ ) ,
1352+ ) ;
13431353 const isThreadListExpanded = expandedThreadListsByProject . has ( project . id ) ;
13441354 const hasHiddenThreads = projectThreads . length > THREAD_PREVIEW_LIMIT ;
13451355 const visibleThreads =
13461356 hasHiddenThreads && ! isThreadListExpanded
13471357 ? projectThreads . slice ( 0 , THREAD_PREVIEW_LIMIT )
13481358 : projectThreads ;
1349- const orderedProjectThreadIds = projectThreads . map ( ( t ) => t . id ) ;
1359+ const orderedProjectThreadIds = projectThreads . map ( ( thread ) => thread . id ) ;
13501360
13511361 return (
13521362 < SortableProjectItem key = { project . id } projectId = { project . id } >
@@ -1369,11 +1379,28 @@ export default function Sidebar() {
13691379 } ) ;
13701380 } }
13711381 >
1372- < ChevronRightIcon
1373- className = { `-ml-0.5 size-3.5 shrink-0 text-muted-foreground/70 transition-transform duration-150 ${
1374- project . expanded ? "rotate-90" : ""
1375- } `}
1376- />
1382+ { ! project . expanded && projectStatus ? (
1383+ < span
1384+ aria-hidden = "true"
1385+ title = { projectStatus . label }
1386+ className = { `-ml-0.5 relative inline-flex size-3.5 shrink-0 items-center justify-center ${ projectStatus . colorClass } ` }
1387+ >
1388+ < span className = "absolute inset-0 flex items-center justify-center transition-opacity duration-150 group-hover/project-header:opacity-0" >
1389+ < span
1390+ className = { `size-[9px] rounded-full ${ projectStatus . dotClass } ${
1391+ projectStatus . pulse ? "animate-pulse" : ""
1392+ } `}
1393+ />
1394+ </ span >
1395+ < ChevronRightIcon className = "absolute inset-0 m-auto size-3.5 text-muted-foreground/70 opacity-0 transition-opacity duration-150 group-hover/project-header:opacity-100" />
1396+ </ span >
1397+ ) : (
1398+ < ChevronRightIcon
1399+ className = { `-ml-0.5 size-3.5 shrink-0 text-muted-foreground/70 transition-transform duration-150 ${
1400+ project . expanded ? "rotate-90" : ""
1401+ } `}
1402+ />
1403+ ) }
13771404 < ProjectFavicon cwd = { project . cwd } />
13781405 < span className = "flex-1 truncate text-xs font-medium text-foreground/90" >
13791406 { project . name }
0 commit comments