From 38222d07c8f7396ae973e378fb3f607628b04a02 Mon Sep 17 00:00:00 2001 From: Bohdan Triapitsyn Date: Thu, 23 Jul 2026 16:46:20 +0300 Subject: [PATCH] fix: include active root sessions in Recent sidebar Recent now shows active root sessions immediately, even if they are older than 48 hours Archived sessions and subtasks still stay out of Recent Added coverage and documentation for the new recency rules --- .../src/components/session/SessionSidebar.tsx | 19 +++++---- .../session/sidebar/DOCUMENTATION.md | 1 + .../session/sidebar/activitySections.test.ts | 39 +++++++++++++++++++ .../session/sidebar/activitySections.ts | 13 +++---- 4 files changed, 57 insertions(+), 15 deletions(-) create mode 100644 packages/ui/src/components/session/sidebar/activitySections.test.ts diff --git a/packages/ui/src/components/session/SessionSidebar.tsx b/packages/ui/src/components/session/SessionSidebar.tsx index 52ee121c..2a3d9f27 100644 --- a/packages/ui/src/components/session/SessionSidebar.tsx +++ b/packages/ui/src/components/session/SessionSidebar.tsx @@ -78,6 +78,7 @@ import { orderSessionsByLifecycleScopes, useSessionOrderingStore, } from '@/sync/session-ordering'; +import { useGlobalSessionStatusStore } from '@/sync/global-session-status'; import { refreshGlobalSessions, refreshGlobalSessionsForDirectories, @@ -270,6 +271,10 @@ const SessionSidebarComponent: React.FC = ({ (state) => isVisible ? state.rankById : EMPTY_SESSION_ORDER_RANKS, [isVisible], )); + const activeSessionIds = useGlobalSessionStatusStore(useShallow( + (state) => isVisible ? [...state.statusById.keys()].sort() : EMPTY_STRING_ARRAY, + )); + const activeSessionIdSet = React.useMemo(() => new Set(activeSessionIds), [activeSessionIds]); const togglePinnedSession = useSessionPinnedStore((state) => state.toggle); const [collapsedGroups, setCollapsedGroups] = React.useState>(() => { try { @@ -1263,16 +1268,16 @@ const SessionSidebarComponent: React.FC = ({ return meta; }, [projectSections, homeDirectory]); - const activeNowSessions = React.useMemo(() => { + const recentSessions = React.useMemo(() => { if (!showRecentSection || isVSCode) { return []; } - return deriveRecentSessions(sessions) + return deriveRecentSessions(sessions, activeSessionIdSet) .sort((a, b) => compareSessionsByLifecycleOrder(a, b, pinnedSessionIds, sessionOrderRanks)); - }, [isVSCode, pinnedSessionIds, sessionOrderRanks, sessions, showRecentSection]); + }, [activeSessionIdSet, isVSCode, pinnedSessionIds, sessionOrderRanks, sessions, showRecentSection]); - // Prefetch is wired below, after recentSessionIds is computed. + // Prefetch is wired below, after recentSessions is computed. const activitySections = React.useMemo(() => { // VS Code renders the full grouped project view (one group per open @@ -1282,8 +1287,6 @@ const SessionSidebarComponent: React.FC = ({ return []; } - const recentSessions = activeNowSessions; - const toItem = (session: Session) => { const existing = sessionSidebarMetaById.get(session.id); const sessionDirectory = normalizePath((session as Session & { directory?: string | null }).directory ?? null); @@ -1316,7 +1319,7 @@ const SessionSidebarComponent: React.FC = ({ return [ { key: 'active-now' as const, title: t('sessions.sidebar.activity.recentTitle'), items }, ]; - }, [activeNowSessions, filterSessionNodesForSearch, hasSessionSearchQuery, isVSCode, normalizedSessionSearchQuery, sessionSidebarMetaById, showRecentSection, t]); + }, [filterSessionNodesForSearch, hasSessionSearchQuery, isVSCode, normalizedSessionSearchQuery, recentSessions, sessionSidebarMetaById, showRecentSection, t]); const hasActivitySectionItems = React.useMemo( () => activitySections.some((section) => section.items.length > 0), @@ -1728,7 +1731,7 @@ const SessionSidebarComponent: React.FC = ({