From 3b36026477850792a587deab3dae218602237c95 Mon Sep 17 00:00:00 2001 From: Brendonovich <14191578+Brendonovich@users.noreply.github.com> Date: Fri, 25 Sep 2026 06:44:40 +0000 Subject: [PATCH 1/5] fix(app): unify session project icon resolution --- packages/app/src/home/sessions/controller.tsx | 1 + packages/app/src/home/sessions/records.test.ts | 12 ++++++++++++ packages/app/src/home/sessions/records.ts | 12 +++++++----- packages/app/src/runtime/server/runtime.tsx | 9 +++++++++ packages/app/src/session/screen.tsx | 5 +++++ .../src/session/session-identity-header.tsx | 7 ++----- packages/app/src/session/summary/panel.tsx | 3 ++- .../app/src/session/summary/project-card.tsx | 8 +++++--- .../src/session/timeline/message-timeline.tsx | 3 ++- packages/app/src/shell/layout/helpers.test.ts | 18 ++++++++++++++++++ packages/app/src/shell/layout/helpers.ts | 16 +++++++++++++++- packages/app/src/shell/titlebar/tab-nav.tsx | 4 ++-- packages/app/src/shell/titlebar/titlebar.tsx | 3 +-- 13 files changed, 81 insertions(+), 20 deletions(-) diff --git a/packages/app/src/home/sessions/controller.tsx b/packages/app/src/home/sessions/controller.tsx index ffa83a61ecf9..6f9a3a60c3a7 100644 --- a/packages/app/src/home/sessions/controller.tsx +++ b/packages/app/src/home/sessions/controller.tsx @@ -86,6 +86,7 @@ export function createHomeSessionsController(home: HomeController) { sessions: indexedSessions, projectDirectories, projects: home.project.list, + resolveProject: (session) => home.server.focusedContext()?.projects.forSession(session), }), ) const records = createMemo(() => allRecords().slice(0, HOME_SESSION_LIMIT)) diff --git a/packages/app/src/home/sessions/records.test.ts b/packages/app/src/home/sessions/records.test.ts index d15bc9724e4c..f5ebd3d20842 100644 --- a/packages/app/src/home/sessions/records.test.ts +++ b/packages/app/src/home/sessions/records.test.ts @@ -58,6 +58,18 @@ describe("buildHomeSessionRecords", () => { expect(records[0]?.project.worktree).toBe("/repo/a/packages/app") }) + + test("uses the same resolved project as session tabs, including stored projects", () => { + const stored = { id: "project-b", worktree: "/repo/b", expanded: false, icon: { override: "stored-icon" } } + const records = buildHomeSessionRecords({ + sessions: () => [session("b", "/repo/b", "project-b")], + projectDirectories: () => undefined, + projects: () => [], + resolveProject: () => stored, + }) + + expect(records[0]?.project).toBe(stored) + }) }) describe("homeSessionLocation", () => { diff --git a/packages/app/src/home/sessions/records.ts b/packages/app/src/home/sessions/records.ts index d7528477d939..b2a00bcf4f14 100644 --- a/packages/app/src/home/sessions/records.ts +++ b/packages/app/src/home/sessions/records.ts @@ -18,6 +18,7 @@ export function buildHomeSessionRecords(input: { sessions: () => SessionInfo[] projectDirectories: () => string[] | undefined projects: () => LocalProject[] + resolveProject?: (session: SessionInfo) => LocalProject | undefined }) { const selected = input.projectDirectories() const directories = selected ? new Set(selected.map(pathKey)) : undefined @@ -27,11 +28,12 @@ export function buildHomeSessionRecords(input: { return [...new Map(sessions.map((session) => [session.id, session] as const)).values()] .sort(compareSessionTime) .map((session) => { - const project = homeProjectForSession(session, input.projects()) ?? { - id: session.projectID, - worktree: session.location.directory, - expanded: false, - } + const project = input.resolveProject?.(session) ?? + homeProjectForSession(session, input.projects()) ?? { + id: session.projectID, + worktree: session.location.directory, + expanded: false, + } return { session, project, projectName: displayName(project) } }) } diff --git a/packages/app/src/runtime/server/runtime.tsx b/packages/app/src/runtime/server/runtime.tsx index e8e83533f7fb..c3502f35ac4d 100644 --- a/packages/app/src/runtime/server/runtime.tsx +++ b/packages/app/src/runtime/server/runtime.tsx @@ -18,6 +18,8 @@ import { showToast } from "@/shell/notifications/toast" import { formatServerError } from "./errors" import { useSettings } from "@/settings/model" import { timelinePreset } from "@opencode/session-ui/timeline/detail" +import type { SessionInfo } from "@opencode/client/promise" +import { projectForSession } from "@/shell/layout/helpers" export const { use: useGlobal, provider: GlobalProvider } = createSimpleContext({ name: "Global", @@ -180,6 +182,12 @@ function createServerController( } const projectsList = createMemo(() => projects.list().map(enrich)) + const forSession = (session: SessionInfo) => { + const opened = projectForSession(session, projectsList()) + if (opened) return opened + const stored = projectForSession(session, sync.data.project) + return stored ? { ...stored, expanded: false } : undefined + } const recentlyClosedList = createMemo(() => { const known = new Set(sync.data.project.map((project) => pathKey(project.worktree))) return projects @@ -200,6 +208,7 @@ function createServerController( projects: { ...projects, list: projectsList, + forSession, resolve: enrich, recentlyClosed: recentlyClosedList, }, diff --git a/packages/app/src/session/screen.tsx b/packages/app/src/session/screen.tsx index 71fe3a9a2519..55c58ca6f422 100644 --- a/packages/app/src/session/screen.tsx +++ b/packages/app/src/session/screen.tsx @@ -68,6 +68,10 @@ function SessionScreenContent(props: { session: SessionModel; browser: ReturnTyp const info = session.data.info() return info ? projectForSession(info, server.ctx.sync.data.project) : undefined }) + const detailsAvatarProject = createMemo(() => { + const info = session.data.info() + return info ? server.ctx.projects.forSession(info) : undefined + }) const isDesktop = session.isDesktop const btw = createSessionBtw(session) const screen = createSessionScreenLayout(session) @@ -201,6 +205,7 @@ function SessionScreenContent(props: { session: SessionModel; browser: ReturnTyp { + if (props.session) return server.ctx.projects.forSession(props.session) const projects = server.ctx.projects.list() - if (props.session) - return ( - projectForSession(props.session, projects) ?? projectForSession(props.session, server.ctx.sync.data.project) - ) const value = directory() if (!value) return undefined const key = pathKey(value) diff --git a/packages/app/src/session/summary/panel.tsx b/packages/app/src/session/summary/panel.tsx index fc646af893a8..c9881aeec18f 100644 --- a/packages/app/src/session/summary/panel.tsx +++ b/packages/app/src/session/summary/panel.tsx @@ -16,6 +16,7 @@ export function SessionSummaryPanel(props: { shown?: boolean mobile?: boolean project: Project + avatarProject?: Pick & { id?: string } avatar?: JSX.Element directory: string local: boolean @@ -44,7 +45,7 @@ export function SessionSummaryPanel(props: { return (
- + & { id?: string } + avatarProject?: Pick & { id?: string } avatar?: JSX.Element }>, ) { const settings = useSettings() const contentID = createUniqueId() const expanded = settings.sessionSummary.projectExpanded + const avatarProject = () => props.avatarProject ?? props.project return (