diff --git a/apps/desktop/src/app/chat/session-tile.tsx b/apps/desktop/src/app/chat/session-tile.tsx index a2de9a3781a3..e1e149a29d60 100644 --- a/apps/desktop/src/app/chat/session-tile.tsx +++ b/apps/desktop/src/app/chat/session-tile.tsx @@ -286,31 +286,15 @@ export function SessionTilePane({ storedSessionId }: { storedSessionId: string } * activity lands it there — resolving through the tree keeps its tab titled * and tinted instead of a grey "Session" placeholder. */ export function tileStoredRow(storedSessionId: string): SessionInfo | undefined { - const fromList = $sessions.get().find(s => sessionMatchesStoredId(s, storedSessionId)) + const match = (s: SessionInfo) => sessionMatchesStoredId(s, storedSessionId) - if (fromList) { - return fromList - } - - for (const project of $projectTree.get()) { - for (const repo of project.repos) { - for (const group of repo.groups) { - const row = group.sessions.find(s => sessionMatchesStoredId(s, storedSessionId)) - - if (row) { - return row - } - } - } - - const preview = project.previewSessions?.find(s => sessionMatchesStoredId(s, storedSessionId)) - - if (preview) { - return preview - } - } - - return undefined + return ( + $sessions.get().find(match) ?? + $projectTree + .get() + .flatMap(p => [...p.repos.flatMap(r => r.groups.flatMap(g => g.sessions)), ...(p.previewSessions ?? [])]) + .find(match) + ) } function tileTitle(storedSessionId: string): string { @@ -416,6 +400,8 @@ export function SessionTabMenu({ /** Layout-tree pane id — powers the Close-others/right/all verbs. */ tabPaneId: string }) { + // Subscribe for reactivity; the row is read imperatively via tileStoredRow + // (which spans both sources), so the values themselves are unused here. useStore($sessions) useStore($projectTree) const pinnedSessionIds = useStore($pinnedSessionIds) diff --git a/apps/desktop/src/store/session-color.ts b/apps/desktop/src/store/session-color.ts index 3607d1b607fa..9c0871c63916 100644 --- a/apps/desktop/src/store/session-color.ts +++ b/apps/desktop/src/store/session-color.ts @@ -4,7 +4,7 @@ import { sessionProjectColor } from '@/app/chat/sidebar/projects/workspace-group import { Codecs, persistentAtom } from '@/lib/persisted' import { $projects } from '@/store/projects' import { $sessions, sessionPinId } from '@/store/session' -import type { SessionInfo } from '@/types/hermes' +import type { ProjectInfo, SessionInfo } from '@/types/hermes' // Per-session color OVERRIDES — a user-picked color that wins over the inherited // project color (#66565 layer 2). Desktop-local like pins, keyed by the DURABLE @@ -39,13 +39,21 @@ export function setSessionColorOverride(durableId: string, color: null | string) // // Precedence in one place: an explicit per-session override wins over the // inherited project color. Agent-set color (#66565 layer 3) slots in here too. +function resolveSessionColor( + session: SessionInfo, + projects: ProjectInfo[], + overrides: Record +): string | undefined { + return overrides[sessionPinId(session)] ?? sessionProjectColor(session, projects) ?? undefined +} + export const $sessionColorById = computed( [$sessions, $projects, $sessionColorOverrides], (sessions, projects, overrides) => { const map: Record = {} for (const session of sessions) { - const color = overrides[sessionPinId(session)] ?? sessionProjectColor(session, projects) + const color = resolveSessionColor(session, projects, overrides) if (color) { map[session.id] = color @@ -59,17 +67,12 @@ export const $sessionColorById = computed( // The color for a single session object (the tabs already hold the SessionInfo // they render, so they resolve through the same map the sidebar reads). A row // that isn't in `$sessions` — e.g. a project-tree session older than the -// paginated recents page, opened as a tab — misses the map, so fall back to -// resolving it directly through the same precedence the map uses. +// paginated recents page, opened as a tab — misses the map, so fall back to the +// same resolver the map is built from. export function sessionColorFor(session: null | SessionInfo | undefined): string | undefined { if (!session) { return undefined } - return ( - $sessionColorById.get()[session.id] ?? - $sessionColorOverrides.get()[sessionPinId(session)] ?? - sessionProjectColor(session, $projects.get()) ?? - undefined - ) + return $sessionColorById.get()[session.id] ?? resolveSessionColor(session, $projects.get(), $sessionColorOverrides.get()) }