diff --git a/src/features/threads/utils/threadSummary.test.ts b/src/features/threads/utils/threadSummary.test.ts new file mode 100644 index 0000000000..cf0570574a --- /dev/null +++ b/src/features/threads/utils/threadSummary.test.ts @@ -0,0 +1,52 @@ +import { describe, expect, it } from "vitest"; +import { buildThreadSummaryFromThread } from "./threadSummary"; + +const baseThread = { + id: "thread-1", + name: "Server-provided name", + preview: "First message preview", + source: "vscode", +}; + +describe("buildThreadSummaryFromThread", () => { + it("prefers the server-provided thread name over the message preview", () => { + const summary = buildThreadSummaryFromThread({ + workspaceId: "workspace-1", + thread: baseThread, + fallbackIndex: 0, + }); + + expect(summary?.name).toBe("Server-provided name"); + }); + + it("keeps an explicit local rename ahead of the server-provided name", () => { + const summary = buildThreadSummaryFromThread({ + workspaceId: "workspace-1", + thread: baseThread, + fallbackIndex: 0, + getCustomName: () => "Local rename", + }); + + expect(summary?.name).toBe("Local rename"); + }); + + it("falls back to the message preview when the server has no name", () => { + const summary = buildThreadSummaryFromThread({ + workspaceId: "workspace-1", + thread: { ...baseThread, name: null }, + fallbackIndex: 0, + }); + + expect(summary?.name).toBe("First message preview"); + }); + + it("supports title as a compatibility fallback", () => { + const summary = buildThreadSummaryFromThread({ + workspaceId: "workspace-1", + thread: { ...baseThread, name: null, title: "Legacy title" }, + fallbackIndex: 0, + }); + + expect(summary?.name).toBe("Legacy title"); + }); +}); diff --git a/src/features/threads/utils/threadSummary.ts b/src/features/threads/utils/threadSummary.ts index a23a6c76ae..f9d30d932b 100644 --- a/src/features/threads/utils/threadSummary.ts +++ b/src/features/threads/utils/threadSummary.ts @@ -49,9 +49,10 @@ export function buildThreadSummaryFromThread({ const preview = asString(thread.preview ?? "").trim(); const customName = getCustomName?.(workspaceId, id); const fallbackName = `Agent ${fallbackIndex + 1}`; + const serverName = asString(thread.name ?? thread.title ?? "").trim(); const name = customName ? customName - : clampThreadName(preview) ?? fallbackName; + : clampThreadName(serverName || preview) ?? fallbackName; const metadata = extractThreadCodexMetadata(thread); if (shouldHideSubagentThreadFromSidebar(thread.source)) { return null;