diff --git a/packages/app/src/components/sidebar-workspace-list.tsx b/packages/app/src/components/sidebar-workspace-list.tsx
index 1af1386d5..4eb46ea30 100644
--- a/packages/app/src/components/sidebar-workspace-list.tsx
+++ b/packages/app/src/components/sidebar-workspace-list.tsx
@@ -55,6 +55,7 @@ import { buildSidebarShortcutModel } from '@/utils/sidebar-shortcuts'
import { hasVisibleOrderChanged, mergeWithRemainder } from '@/utils/sidebar-reorder'
import { decideLongPressMove } from '@/utils/sidebar-gesture-arbitration'
import { confirmDialog } from '@/utils/confirm-dialog'
+import { projectIconPlaceholderLabelFromDisplayName } from '@/utils/project-display-name'
const PASEO_WORKTREE_PATH_MARKER = '/.paseo/worktrees'
@@ -416,6 +417,8 @@ function ProjectHeaderRow({
menuController: null,
debugId: `project:${project.projectKey}`,
})
+ const placeholderLabel = projectIconPlaceholderLabelFromDisplayName(displayName)
+ const placeholderInitial = placeholderLabel.charAt(0).toUpperCase()
const handlePress = useCallback(() => {
if (interaction.didLongPressRef.current) {
@@ -449,7 +452,7 @@ function ProjectHeaderRow({
) : (
- {displayName.charAt(0).toUpperCase()}
+ {placeholderInitial}
)}
diff --git a/packages/app/src/utils/project-display-name.test.ts b/packages/app/src/utils/project-display-name.test.ts
new file mode 100644
index 000000000..0a5307878
--- /dev/null
+++ b/packages/app/src/utils/project-display-name.test.ts
@@ -0,0 +1,27 @@
+import { describe, expect, it } from "vitest";
+import {
+ projectDisplayNameFromProjectId,
+ projectIconPlaceholderLabelFromDisplayName,
+} from "./project-display-name";
+
+describe("projectDisplayNameFromProjectId", () => {
+ it("shows owner and repo for GitHub remote ids", () => {
+ expect(projectDisplayNameFromProjectId("remote:github.com/getpaseo/paseo")).toBe(
+ "getpaseo/paseo"
+ );
+ });
+
+ it("shows the trailing directory name for local projects", () => {
+ expect(projectDisplayNameFromProjectId("/Users/me/dev/paseo")).toBe("paseo");
+ });
+});
+
+describe("projectIconPlaceholderLabelFromDisplayName", () => {
+ it("uses repo name instead of owner for GitHub-style display names", () => {
+ expect(projectIconPlaceholderLabelFromDisplayName("getpaseo/paseo")).toBe("paseo");
+ });
+
+ it("returns the original display name when it has no path separator", () => {
+ expect(projectIconPlaceholderLabelFromDisplayName("paseo")).toBe("paseo");
+ });
+});
diff --git a/packages/app/src/utils/project-display-name.ts b/packages/app/src/utils/project-display-name.ts
index 9dce1588a..1d251e051 100644
--- a/packages/app/src/utils/project-display-name.ts
+++ b/packages/app/src/utils/project-display-name.ts
@@ -7,3 +7,15 @@ export function projectDisplayNameFromProjectId(projectId: string): string {
const segments = projectId.split(/[\\/]/).filter(Boolean);
return segments[segments.length - 1] || projectId;
}
+
+export function projectIconPlaceholderLabelFromDisplayName(
+ displayName: string
+): string {
+ const trimmedDisplayName = displayName.trim();
+ if (!trimmedDisplayName) {
+ return "";
+ }
+
+ const segments = trimmedDisplayName.split("/").filter(Boolean);
+ return segments[segments.length - 1] || trimmedDisplayName;
+}