From 476f367c9d108a79933f00ba40853ddf2bb28b86 Mon Sep 17 00:00:00 2001
From: Neil <4138956+nwparker@users.noreply.github.com>
Date: Sun, 24 May 2026 00:25:27 -0700
Subject: [PATCH] Use square repo badges (#2744)
---
src/renderer/src/components/TaskPage.tsx | 20 +++++------
.../src/components/WorktreeJumpPalette.tsx | 21 ++----------
.../activity/ActivityPrototypePage.tsx | 3 +-
.../automations/AutomationsPage.tsx | 6 ++--
.../github/IssueSourceIndicator.tsx | 8 ++---
.../components/github/IssueSourceSelector.tsx | 2 +-
.../src/components/repo/RepoBadgeLabel.tsx | 33 +++++++++++++++++++
.../src/components/repo/RepoCombobox.tsx | 8 ++---
.../src/components/repo/RepoDotLabel.tsx | 23 -------------
.../components/settings/QuickCommandsPane.tsx | 12 ++-----
.../settings/RepositoryIconPicker.tsx | 2 +-
.../components/settings/SettingsSidebar.tsx | 9 +++--
.../sidebar/SetupScriptPromptCard.tsx | 6 ++--
.../src/components/sidebar/SidebarFilter.tsx | 4 +--
.../SidebarRepositoryFilterSection.tsx | 8 ++---
.../sidebar/WorkspaceKanbanCard.tsx | 6 ++--
.../src/components/sidebar/WorktreeCard.tsx | 9 ++---
.../src/components/sidebar/WorktreeList.tsx | 6 ++--
.../TerminalQuickCommandDialog.tsx | 4 +--
.../src/components/ui/repo-multi-combobox.tsx | 10 ++++--
20 files changed, 92 insertions(+), 108 deletions(-)
create mode 100644 src/renderer/src/components/repo/RepoBadgeLabel.tsx
delete mode 100644 src/renderer/src/components/repo/RepoDotLabel.tsx
diff --git a/src/renderer/src/components/TaskPage.tsx b/src/renderer/src/components/TaskPage.tsx
index 3408f4267..8ac129ee3 100644
--- a/src/renderer/src/components/TaskPage.tsx
+++ b/src/renderer/src/components/TaskPage.tsx
@@ -72,7 +72,7 @@ import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'
import RepoMultiCombobox from '@/components/ui/repo-multi-combobox'
import TeamMultiCombobox from '@/components/ui/team-multi-combobox'
-import RepoDotLabel from '@/components/repo/RepoDotLabel'
+import RepoBadgeLabel from '@/components/repo/RepoBadgeLabel'
import IssueSourceIndicator, { sameGitHubOwnerRepo } from '@/components/github/IssueSourceIndicator'
import IssueSourceSelector, { issueSourceChipClass } from '@/components/github/IssueSourceSelector'
import { reconcileLinearTeamSelection } from '@/components/task-page-linear-team-selection'
@@ -4447,7 +4447,7 @@ export default function TaskPage(): React.JSX.Element {
// Why: unify feature 1 (indicator) and feature 2 (selector)
// into a single chip per repo. Rendering both separately
// produced visually redundant output — two local-repo
- // dot-labels, duplicate slugs. The selector's active pill
+ // badge labels, duplicate slugs. The selector's active pill
// + tooltip already announce the source, so the "Issues
// from {slug}" chip is only shown when the selector does
// not render (no upstream remote — nothing to toggle).
@@ -4461,7 +4461,7 @@ export default function TaskPage(): React.JSX.Element {
{rows.map((s) => {
const repo = selectedRepos.find((r) => r.id === s.repoId)
- const showDotLabel = selectedRepos.length > 1 && repo
+ const showRepoBadgeLabel = selectedRepos.length > 1 && repo
const selectorRenderable = hasUpstreamCandidateDivergence(s)
// Why: the static indicator has its own wrapping
// chip styles, so we render it standalone and don't
@@ -4474,7 +4474,7 @@ export default function TaskPage(): React.JSX.Element {
issues={s.sources.issues}
prs={s.sources.prs}
localRepo={
- showDotLabel && repo
+ showRepoBadgeLabel && repo
? { displayName: repo.displayName, color: repo.badgeColor }
: undefined
}
@@ -4492,11 +4492,11 @@ export default function TaskPage(): React.JSX.Element {
// uses `inline-flex`, so the visual rendering is identical.
return (
- {showDotLabel ? (
-
) : null}
@@ -5008,10 +5008,10 @@ export default function TaskPage(): React.JSX.Element {
{selectedRepos.length > 1 && itemRepo ? (
// Why: disambiguate rows when multiple repos are in
// the merged list — a single-repo view doesn't need it.
-
) : null}
@@ -6002,7 +6002,7 @@ export default function TaskPage(): React.JSX.Element {
{selectedRepos.map((r) => (
-
+
))}
diff --git a/src/renderer/src/components/WorktreeJumpPalette.tsx b/src/renderer/src/components/WorktreeJumpPalette.tsx
index 06fbafa27..30785942c 100644
--- a/src/renderer/src/components/WorktreeJumpPalette.tsx
+++ b/src/renderer/src/components/WorktreeJumpPalette.tsx
@@ -46,6 +46,7 @@ import {
ORCA_BROWSER_FOCUS_REQUEST_EVENT,
queueBrowserFocusRequest
} from '@/components/browser-pane/browser-focus'
+import { RepoBadgeMark } from '@/components/repo/RepoBadgeLabel'
import type { BrowserPage, BrowserWorkspace, Worktree } from '../../../shared/types'
import { isGitRepoKind } from '../../../shared/repo-kind'
@@ -1043,15 +1044,7 @@ export default function WorktreeJumpPalette(): React.JSX.Element | null {
{repoName && (
-
+
{entry.match.repoRange ? (
{browserRepoName && (
-
+
-
+
{repo.displayName}
diff --git a/src/renderer/src/components/automations/AutomationsPage.tsx b/src/renderer/src/components/automations/AutomationsPage.tsx
index 3fdef61a9..27cfef31e 100644
--- a/src/renderer/src/components/automations/AutomationsPage.tsx
+++ b/src/renderer/src/components/automations/AutomationsPage.tsx
@@ -36,7 +36,7 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip'
import { useAppStore } from '@/store'
import { cn } from '@/lib/utils'
-import RepoDotLabel from '@/components/repo/RepoDotLabel'
+import RepoBadgeLabel from '@/components/repo/RepoBadgeLabel'
import { AGENT_CATALOG } from '@/lib/agent-catalog'
import { useRepoMap, useWorktreeMap } from '@/store/selectors'
import { activateAndRevealWorktree } from '@/lib/worktree-activation'
@@ -1496,10 +1496,10 @@ export default function AutomationsPage(): React.JSX.Element {
{automationRepo ? (
-
) : (
Unknown project
diff --git a/src/renderer/src/components/github/IssueSourceIndicator.tsx b/src/renderer/src/components/github/IssueSourceIndicator.tsx
index 1abbc879f..a5ce266f6 100644
--- a/src/renderer/src/components/github/IssueSourceIndicator.tsx
+++ b/src/renderer/src/components/github/IssueSourceIndicator.tsx
@@ -1,6 +1,6 @@
import React from 'react'
import type { GitHubOwnerRepo } from '../../../../shared/types'
-import RepoDotLabel from '@/components/repo/RepoDotLabel'
+import RepoBadgeLabel from '@/components/repo/RepoBadgeLabel'
import { cn } from '@/lib/utils'
export type IssueSourceIndicatorProps = {
@@ -84,13 +84,13 @@ export default function IssueSourceIndicator({
>
{localRepo ? (
// Why: when multiple repos are selected, a bare "Issues from X/Y" chip
- // doesn't tell the user which local repo it describes. The dot-label
+ // doesn't tell the user which local repo it describes. The badge label
// prefix pins the chip to the same visual identity used elsewhere in
// the Tasks view (row disambiguator, composer target dropdown).
-
) : null}
diff --git a/src/renderer/src/components/github/IssueSourceSelector.tsx b/src/renderer/src/components/github/IssueSourceSelector.tsx
index a92009484..c88567a9c 100644
--- a/src/renderer/src/components/github/IssueSourceSelector.tsx
+++ b/src/renderer/src/components/github/IssueSourceSelector.tsx
@@ -54,7 +54,7 @@ function segmentClass(state: PillState, disabled: boolean | undefined): string {
}
// Why: exported so the Tasks-header row can wrap the selector (and the
-// optional per-repo dot-label prefix) in the same pill shape used by the
+// optional per-repo badge label prefix) in the same pill shape used by the
// static `IssueSourceIndicator`. Keeping the styling here means the chip
// and its segments stay visually consistent.
export const issueSourceChipClass =
diff --git a/src/renderer/src/components/repo/RepoBadgeLabel.tsx b/src/renderer/src/components/repo/RepoBadgeLabel.tsx
new file mode 100644
index 000000000..eac57abc0
--- /dev/null
+++ b/src/renderer/src/components/repo/RepoBadgeLabel.tsx
@@ -0,0 +1,33 @@
+import type { CSSProperties } from 'react'
+import { cn } from '@/lib/utils'
+
+type RepoBadgeMarkProps = {
+ color: string | null | undefined
+ className?: string
+}
+
+export function RepoBadgeMark({ color, className }: RepoBadgeMarkProps) {
+ const style: CSSProperties | undefined = color ? { backgroundColor: color } : undefined
+
+ return (
+
+ )
+}
+
+type RepoBadgeLabelProps = {
+ name: string
+ color: string
+ className?: string
+ badgeClassName?: string
+}
+
+function RepoBadgeLabel({ name, color, className, badgeClassName }: RepoBadgeLabelProps) {
+ return (
+
+
+ {name}
+
+ )
+}
+
+export default RepoBadgeLabel
diff --git a/src/renderer/src/components/repo/RepoCombobox.tsx b/src/renderer/src/components/repo/RepoCombobox.tsx
index 408db9162..78365c7d7 100644
--- a/src/renderer/src/components/repo/RepoCombobox.tsx
+++ b/src/renderer/src/components/repo/RepoCombobox.tsx
@@ -14,7 +14,7 @@ import { isGitRepoKind } from '../../../../shared/repo-kind'
import { searchRepos } from '@/lib/repo-search'
import { cn } from '@/lib/utils'
import type { Repo } from '../../../../shared/types'
-import RepoDotLabel from './RepoDotLabel'
+import RepoBadgeLabel from './RepoBadgeLabel'
type RepoComboboxProps = {
repos: Repo[]
@@ -174,10 +174,10 @@ export default function RepoCombobox({
>
{selectedRepo ? (
-
{selectedRepo.connectionId && (
@@ -221,7 +221,7 @@ export default function RepoCombobox({
/>
-
-
- {name}
-
- )
-}
-
-export default RepoDotLabel
diff --git a/src/renderer/src/components/settings/QuickCommandsPane.tsx b/src/renderer/src/components/settings/QuickCommandsPane.tsx
index 99df91108..ac4f03d5a 100644
--- a/src/renderer/src/components/settings/QuickCommandsPane.tsx
+++ b/src/renderer/src/components/settings/QuickCommandsPane.tsx
@@ -17,7 +17,7 @@ import { Button } from '../ui/button'
import { Command, CommandItem, CommandList } from '../ui/command'
import { Label } from '../ui/label'
import { Popover, PopoverContent, PopoverTrigger } from '../ui/popover'
-import RepoDotLabel from '../repo/RepoDotLabel'
+import RepoBadgeLabel, { RepoBadgeMark } from '../repo/RepoBadgeLabel'
import { cn } from '@/lib/utils'
import { useConfirmationDialog } from '@/components/confirmation-dialog'
@@ -270,7 +270,7 @@ export function QuickCommandsPane({
isSelected ? 'opacity-70' : 'opacity-0'
)}
/>
-
{scope.type === 'repo' ? (
<>
-
+
{getScopeLabel(scope, repoById)}
>
) : (
diff --git a/src/renderer/src/components/settings/RepositoryIconPicker.tsx b/src/renderer/src/components/settings/RepositoryIconPicker.tsx
index a0f90a20a..fa08c9601 100644
--- a/src/renderer/src/components/settings/RepositoryIconPicker.tsx
+++ b/src/renderer/src/components/settings/RepositoryIconPicker.tsx
@@ -156,7 +156,7 @@ export function RepositoryIconPicker({
type="button"
onClick={() => updateRepo(repo.id, { badgeColor: color })}
className={cn(
- 'size-7 rounded-full transition-all',
+ 'size-7 rounded-[4px] transition-all',
repo.badgeColor === color
? 'ring-2 ring-foreground ring-offset-2 ring-offset-background'
: 'hover:ring-1 hover:ring-muted-foreground hover:ring-offset-2 hover:ring-offset-background'
diff --git a/src/renderer/src/components/settings/SettingsSidebar.tsx b/src/renderer/src/components/settings/SettingsSidebar.tsx
index 253b641a3..4d661efac 100644
--- a/src/renderer/src/components/settings/SettingsSidebar.tsx
+++ b/src/renderer/src/components/settings/SettingsSidebar.tsx
@@ -2,6 +2,7 @@ import type { RefObject } from 'react'
import { ArrowLeft, Search, Server, type LucideIcon, type LucideProps } from 'lucide-react'
import { useShortcutLabel } from '@/hooks/useShortcutLabel'
import { cn } from '@/lib/utils'
+import { RepoBadgeMark } from '../repo/RepoBadgeLabel'
import { Button } from '../ui/button'
import { Input } from '../ui/input'
@@ -161,14 +162,12 @@ export function SettingsSidebar({
}
className={navItemClassName(isActive)}
>
-
{section.title}
{section.isRemote && (
diff --git a/src/renderer/src/components/sidebar/SetupScriptPromptCard.tsx b/src/renderer/src/components/sidebar/SetupScriptPromptCard.tsx
index e433c0f1c..d0d79c6de 100644
--- a/src/renderer/src/components/sidebar/SetupScriptPromptCard.tsx
+++ b/src/renderer/src/components/sidebar/SetupScriptPromptCard.tsx
@@ -7,6 +7,7 @@ import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip
import { track } from '@/lib/telemetry'
import { cn } from '@/lib/utils'
import { getRepositoryLocalCommandsSectionId } from '@/components/settings/repository-settings-targets'
+import { RepoBadgeMark } from '@/components/repo/RepoBadgeLabel'
import {
checkRuntimeHooks,
inspectRuntimeSetupScriptImports,
@@ -352,10 +353,7 @@ function SetupScriptPromptCard(): React.JSX.Element | null {
<>
Automate workspace setup for{' '}
-
+
{activeRepo.displayName}
diff --git a/src/renderer/src/components/sidebar/SidebarFilter.tsx b/src/renderer/src/components/sidebar/SidebarFilter.tsx
index 389e20006..38893d394 100644
--- a/src/renderer/src/components/sidebar/SidebarFilter.tsx
+++ b/src/renderer/src/components/sidebar/SidebarFilter.tsx
@@ -16,7 +16,7 @@ import {
DropdownMenuTrigger
} from '@/components/ui/dropdown-menu'
import { Tooltip, TooltipTrigger, TooltipContent } from '@/components/ui/tooltip'
-import RepoDotLabel from '@/components/repo/RepoDotLabel'
+import RepoBadgeLabel from '@/components/repo/RepoBadgeLabel'
import { searchRepos } from '@/lib/repo-search'
import { cn } from '@/lib/utils'
import { DEFAULT_SHOW_SLEEPING_WORKSPACES } from '../../../../shared/constants'
@@ -234,7 +234,7 @@ const SidebarFilter = React.memo(function SidebarFilter({
className="mx-1 my-0.5 items-center gap-2 rounded-[7px] px-2 py-1 text-[12px] leading-5 font-medium data-[selected=true]:bg-black/8 dark:data-[selected=true]:bg-white/14"
>
-
-
-