From f371528bccc133c1dfa1fdfbf57c4cf0b613c34e Mon Sep 17 00:00:00 2001 From: tk1475 <118763009+tk1475@users.noreply.github.com> Date: Mon, 28 Sep 2026 13:49:01 +0500 Subject: [PATCH 1/2] test: cover Project Worktrees subtitle preferring the description (#4889) Project Worktrees rows (pinned and grouped) should show a workspace's custom description and fall back to the branch only when the description is empty. The two description cases fail today because the subtitle is always the branch. Co-Authored-By: Claude Opus 5.5 (1M context) --- .../ProjectWorktreeSidebarTests.swift | 86 +++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 Examples/CmuxExtensionSidebarExamples/Tests/CmuxExtensionSidebarExamplesTests/ProjectWorktreeSidebarTests.swift diff --git a/Examples/CmuxExtensionSidebarExamples/Tests/CmuxExtensionSidebarExamplesTests/ProjectWorktreeSidebarTests.swift b/Examples/CmuxExtensionSidebarExamples/Tests/CmuxExtensionSidebarExamplesTests/ProjectWorktreeSidebarTests.swift new file mode 100644 index 000000000000..b05fded6e665 --- /dev/null +++ b/Examples/CmuxExtensionSidebarExamples/Tests/CmuxExtensionSidebarExamplesTests/ProjectWorktreeSidebarTests.swift @@ -0,0 +1,86 @@ +import CmuxSidebarProviderKit +@testable import CmuxExtensionSidebarExamples +import XCTest + +final class ProjectWorktreeSidebarTests: XCTestCase { + func testCustomDescriptionTakesPrecedenceOverBranch() throws { + let described = workspace( + title: "Described", + customDescription: "Custom workspace description", + isPinned: false, + branchSummary: "issue-4889-branch" + ) + let snapshot = CmuxSidebarProviderSnapshot( + sequence: 1, + selectedWorkspaceId: nil, + workspaces: [described] + ) + + let model = ProjectWorktreeSidebar().render(snapshot: snapshot) + + let project = try XCTUnwrap(model.sections.first { $0.id == "project:/tmp/project" }) + XCTAssertEqual(project.rows.map(\.workspaceId), [described.id]) + XCTAssertEqual(project.rows.first?.subtitle, .plain("Custom workspace description")) + } + + func testPinnedWorkspaceUsesCustomDescription() throws { + let pinned = workspace( + title: "Pinned", + customDescription: "Pinned description", + isPinned: true, + branchSummary: "main" + ) + let snapshot = CmuxSidebarProviderSnapshot( + sequence: 1, + selectedWorkspaceId: nil, + workspaces: [pinned] + ) + + let model = ProjectWorktreeSidebar().render(snapshot: snapshot) + + let section = try XCTUnwrap(model.sections.first { $0.id == "pinned" }) + XCTAssertEqual(section.rows.map(\.workspaceId), [pinned.id]) + XCTAssertEqual(section.rows.first?.subtitle, .plain("Pinned description")) + } + + func testBlankCustomDescriptionFallsBackToBranch() throws { + let blank = workspace( + title: "Blank", + customDescription: " \n", + isPinned: false, + branchSummary: "feature/sidebar" + ) + let snapshot = CmuxSidebarProviderSnapshot( + sequence: 1, + selectedWorkspaceId: nil, + workspaces: [blank] + ) + + let model = ProjectWorktreeSidebar().render(snapshot: snapshot) + + let project = try XCTUnwrap(model.sections.first { $0.id == "project:/tmp/project" }) + XCTAssertEqual(project.rows.first?.subtitle, .plain("feature/sidebar")) + } + + private func workspace( + title: String, + customDescription: String?, + isPinned: Bool, + branchSummary: String? + ) -> CmuxSidebarProviderWorkspace { + CmuxSidebarProviderWorkspace( + id: UUID(), + title: title, + customDescription: customDescription, + isPinned: isPinned, + rootPath: "/tmp/project", + projectRootPath: "/tmp/project", + branchSummary: branchSummary, + remoteDisplayTarget: nil, + remoteConnectionState: nil, + unreadCount: 0, + latestNotificationText: nil, + listeningPorts: [] + ) + } +} From 42d24eacf8f7b8fbbfea8c39012909e9ba586ff3 Mon Sep 17 00:00:00 2001 From: tk1475 <118763009+tk1475@users.noreply.github.com> Date: Mon, 28 Sep 2026 13:49:15 +0500 Subject: [PATCH 2/2] fix(examples): show custom description in Project Worktrees sidebar (#4889) The Project Worktrees example always used the branch as the row subtitle and ignored workspace.customDescription. Prefer the trimmed description and fall back to the branch, matching the Attention Queue and Dev Server examples. Co-Authored-By: Claude Opus 5.5 (1M context) --- .../ProjectWorktreeSidebar.swift | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/Examples/CmuxExtensionSidebarExamples/Sources/CmuxExtensionSidebarExamples/ProjectWorktreeSidebar.swift b/Examples/CmuxExtensionSidebarExamples/Sources/CmuxExtensionSidebarExamples/ProjectWorktreeSidebar.swift index 466fd5259059..829220d45dd8 100644 --- a/Examples/CmuxExtensionSidebarExamples/Sources/CmuxExtensionSidebarExamples/ProjectWorktreeSidebar.swift +++ b/Examples/CmuxExtensionSidebarExamples/Sources/CmuxExtensionSidebarExamples/ProjectWorktreeSidebar.swift @@ -23,7 +23,7 @@ public struct ProjectWorktreeSidebar: CmuxSidebarProvider { projectRootPath: nil, workspaces: snapshot.workspaces.filter(\.isPinned) ) - .render(subtitle: branchSubtitle) + .render(subtitle: rowSubtitle) ) var grouped: [String: [CmuxSidebarProviderWorkspace]] = [:] @@ -51,14 +51,17 @@ public struct ProjectWorktreeSidebar: CmuxSidebarProvider { projectRootPath: root == "no-folder" ? nil : root, workspaces: grouped[root] ?? [] ) - .render(subtitle: branchSubtitle) + .render(subtitle: rowSubtitle) ) } return renderModel(providerId: descriptor.id, snapshot: snapshot, sections: sections) } - private func branchSubtitle(_ workspace: CmuxSidebarProviderWorkspace) -> CmuxSidebarProviderText? { - trimmed(workspace.branchSummary).map(CmuxSidebarProviderText.plain) + private func rowSubtitle(_ workspace: CmuxSidebarProviderWorkspace) -> CmuxSidebarProviderText? { + if let description = trimmed(workspace.customDescription) { + return .plain(description) + } + return trimmed(workspace.branchSummary).map(CmuxSidebarProviderText.plain) } }