From 9d13a7441ab5433dde39e89f0e7d99e447a2b80e Mon Sep 17 00:00:00 2001 From: brennanb2025 Date: Tue, 23 Jun 2026 14:56:55 -0700 Subject: [PATCH] Unify folder workspace card identity Co-authored-by: Orca --- .../WorktreeCard.affiliate-list-mode.test.tsx | 1 + .../WorktreeCard.compact-hover.test.tsx | 75 +++++++++++++++++++ ...orktreeCard.hosted-review-refresh.test.tsx | 1 + .../sidebar/WorktreeCard.lineage.test.tsx | 1 + .../WorktreeCard.pinned-repo-icon.test.tsx | 1 + .../sidebar/WorktreeCard.pr-display.test.tsx | 1 + .../WorktreeCard.quick-actions.test.tsx | 9 ++- ...WorktreeCard.ssh-reconnect-prompt.test.tsx | 1 + .../src/components/sidebar/WorktreeCard.tsx | 58 ++++++++------ .../WorktreeCardDisplayMenuSection.test.tsx | 22 ++++++ .../WorktreeCardDisplayMenuSection.tsx | 6 +- .../sidebar/WorktreeCardStatusSlot.test.tsx | 23 +++++- .../sidebar/WorktreeCardStatusSlot.tsx | 11 ++- .../sidebar-workspace-option-items.test.ts | 26 +++++++ .../sidebar/sidebar-workspace-option-items.ts | 21 +++++- src/renderer/src/i18n/locales/en.json | 10 ++- src/renderer/src/i18n/locales/es.json | 38 ++++++---- src/renderer/src/i18n/locales/ja.json | 40 +++++----- src/renderer/src/i18n/locales/ko.json | 32 ++++---- src/renderer/src/i18n/locales/zh.json | 32 ++++---- 20 files changed, 312 insertions(+), 97 deletions(-) diff --git a/src/renderer/src/components/sidebar/WorktreeCard.affiliate-list-mode.test.tsx b/src/renderer/src/components/sidebar/WorktreeCard.affiliate-list-mode.test.tsx index 910fd31e1de..31e29c83984 100644 --- a/src/renderer/src/components/sidebar/WorktreeCard.affiliate-list-mode.test.tsx +++ b/src/renderer/src/components/sidebar/WorktreeCard.affiliate-list-mode.test.tsx @@ -30,6 +30,7 @@ vi.mock('@/store', () => ({ linearIssueCache: {}, openModal, openTaskPage: vi.fn(), + projectGroups: [], ptyIdsByTabId: {}, remoteBranchConflictByWorktreeId: {}, renamingWorktreeId: null, diff --git a/src/renderer/src/components/sidebar/WorktreeCard.compact-hover.test.tsx b/src/renderer/src/components/sidebar/WorktreeCard.compact-hover.test.tsx index d93201f4738..b37e5e671aa 100644 --- a/src/renderer/src/components/sidebar/WorktreeCard.compact-hover.test.tsx +++ b/src/renderer/src/components/sidebar/WorktreeCard.compact-hover.test.tsx @@ -17,6 +17,7 @@ const setWorkspacePortScanRefreshing = vi.fn() let worktreeCardProperties: WorktreeCardProperty[] = ['status', 'ports'] let hostedReviewCache: Record = {} +let projectGroups: unknown[] = [] let workspacePortScan: { key: string; result: WorkspacePortScanResult } | null = null let settings: Partial | null = { compactWorktreeCards: true } @@ -35,6 +36,7 @@ vi.mock('@/store', () => ({ linearIssueCache: {}, openModal, openTaskPage, + projectGroups, ptyIdsByTabId: {}, recordFeatureInteraction, remoteBranchConflictByWorktreeId: {}, @@ -172,6 +174,7 @@ describe('WorktreeCard compact hover details', () => { vi.clearAllMocks() worktreeCardProperties = ['status', 'ports'] hostedReviewCache = {} + projectGroups = [] workspacePortScan = null settings = { compactWorktreeCards: true } }) @@ -561,6 +564,78 @@ describe('WorktreeCard compact hover details', () => { expect(markup).toContain('text-[13px] leading-5') }) + it('does not show a folder path row in new-card mode when no project groups exist', async () => { + settings = { compactWorktreeCards: false, experimentalNewWorktreeCardStyle: true } + worktreeCardProperties = ['status', 'branch'] + const { default: WorktreeCard } = await import('./WorktreeCard') + + const markup = renderToStaticMarkup( + + ) + + expect(markup).not.toContain('data-worktree-card-meta-row=""') + expect(markup).toContain('Docs folder') + expect(markup).not.toContain('/Users/x/projects/my-app') + }) + + it('shows a folder path row in new-card mode through the branch setting when project groups exist', async () => { + settings = { compactWorktreeCards: false, experimentalNewWorktreeCardStyle: true } + worktreeCardProperties = ['status', 'branch'] + projectGroups = [{ id: 'group-1' }] + const { default: WorktreeCard } = await import('./WorktreeCard') + + const markup = renderToStaticMarkup( + + ) + + expect(markup).toContain('data-worktree-card-meta-row=""') + expect(markup).toContain(' /Users/x/projects/my-app ') + expect(markup).not.toContain('>Folder') + }) + + it('keeps hidden folder path identity available from the new-card hover', async () => { + settings = { compactWorktreeCards: false, experimentalNewWorktreeCardStyle: true } + worktreeCardProperties = ['status'] + projectGroups = [{ id: 'group-1' }] + const { default: WorktreeCard } = await import('./WorktreeCard') + + const markup = renderToStaticMarkup( + + ) + + expect(markup).not.toContain('data-worktree-card-meta-row=""') + expect(markup).toContain('data-hover-open-delay="100"') + expect(markup).toContain('/Users/x/projects/my-app') + expect(markup).toContain('Docs folder') + }) + it('shows the branch row for migrated Default cards with branch enabled', async () => { settings = { compactWorktreeCards: false } worktreeCardProperties = ['status', 'branch'] diff --git a/src/renderer/src/components/sidebar/WorktreeCard.hosted-review-refresh.test.tsx b/src/renderer/src/components/sidebar/WorktreeCard.hosted-review-refresh.test.tsx index f233618f162..48ce2425822 100644 --- a/src/renderer/src/components/sidebar/WorktreeCard.hosted-review-refresh.test.tsx +++ b/src/renderer/src/components/sidebar/WorktreeCard.hosted-review-refresh.test.tsx @@ -33,6 +33,7 @@ vi.mock('@/store', () => ({ issueCache: {}, linearIssueCache: {}, openModal, + projectGroups: [], remoteBranchConflictByWorktreeId: {}, settings: { experimentalNewWorktreeCardStyle: true }, sshConnectionStates: new Map(), diff --git a/src/renderer/src/components/sidebar/WorktreeCard.lineage.test.tsx b/src/renderer/src/components/sidebar/WorktreeCard.lineage.test.tsx index e144c5182ee..71fa30bed26 100644 --- a/src/renderer/src/components/sidebar/WorktreeCard.lineage.test.tsx +++ b/src/renderer/src/components/sidebar/WorktreeCard.lineage.test.tsx @@ -24,6 +24,7 @@ vi.mock('@/store', () => ({ issueCache: {}, linearIssueCache: {}, openModal, + projectGroups: [], remoteBranchConflictByWorktreeId: {}, settings: null, sshConnectionStates: new Map(), diff --git a/src/renderer/src/components/sidebar/WorktreeCard.pinned-repo-icon.test.tsx b/src/renderer/src/components/sidebar/WorktreeCard.pinned-repo-icon.test.tsx index 37b5426cfdf..88d5d65d818 100644 --- a/src/renderer/src/components/sidebar/WorktreeCard.pinned-repo-icon.test.tsx +++ b/src/renderer/src/components/sidebar/WorktreeCard.pinned-repo-icon.test.tsx @@ -25,6 +25,7 @@ vi.mock('@/store', () => ({ issueCache: {}, linearIssueCache: {}, openModal, + projectGroups: [], remoteBranchConflictByWorktreeId: {}, settings, sshConnectionStates: new Map(), diff --git a/src/renderer/src/components/sidebar/WorktreeCard.pr-display.test.tsx b/src/renderer/src/components/sidebar/WorktreeCard.pr-display.test.tsx index 83311e622da..dbf90b0faa2 100644 --- a/src/renderer/src/components/sidebar/WorktreeCard.pr-display.test.tsx +++ b/src/renderer/src/components/sidebar/WorktreeCard.pr-display.test.tsx @@ -29,6 +29,7 @@ vi.mock('@/store', () => ({ issueCache: {}, linearIssueCache: {}, openModal, + projectGroups: [], remoteBranchConflictByWorktreeId: {}, settings, sshConnectionStates: new Map(), diff --git a/src/renderer/src/components/sidebar/WorktreeCard.quick-actions.test.tsx b/src/renderer/src/components/sidebar/WorktreeCard.quick-actions.test.tsx index ced090972f4..bdade1701d0 100644 --- a/src/renderer/src/components/sidebar/WorktreeCard.quick-actions.test.tsx +++ b/src/renderer/src/components/sidebar/WorktreeCard.quick-actions.test.tsx @@ -35,6 +35,7 @@ vi.mock('@/store', () => ({ hostedReviewCache: {}, issueCache: {}, openModal, + projectGroups: [], remoteBranchConflictByWorktreeId: {}, settings, sshConnectionStates: new Map(), @@ -181,7 +182,7 @@ describe('WorktreeCard quick actions', () => { expect(markup).not.toContain('bg-black/[0.08]') }) - it('renders folder kind and directory in the detailed metadata row', () => { + it('renders folder directory name in the detailed metadata row without a Folder badge', () => { const markup = renderToStaticMarkup( { ) expect(markup).toContain('Docs folder') - expect(markup).toContain('>Folder') + expect(markup).not.toContain('>Folder') expect(markup).toContain('>quick-action') expect(markup).toContain('data-worktree-card-meta-row=""') }) - it('renders synthetic folder workspace directory in the detailed metadata row', () => { + it('renders synthetic folder workspace directory name in the detailed metadata row without a Folder badge', () => { const markup = renderToStaticMarkup( { ) expect(markup).toContain('Docs folder') - expect(markup).toContain('>Folder') + expect(markup).not.toContain('>Folder') expect(markup).toContain('>quick-action') expect(markup).toContain('data-worktree-card-meta-row=""') }) diff --git a/src/renderer/src/components/sidebar/WorktreeCard.ssh-reconnect-prompt.test.tsx b/src/renderer/src/components/sidebar/WorktreeCard.ssh-reconnect-prompt.test.tsx index 64e61f6a532..9af104c6c18 100644 --- a/src/renderer/src/components/sidebar/WorktreeCard.ssh-reconnect-prompt.test.tsx +++ b/src/renderer/src/components/sidebar/WorktreeCard.ssh-reconnect-prompt.test.tsx @@ -28,6 +28,7 @@ vi.mock('@/store', () => ({ issueCache: {}, linearIssueCache: {}, openModal, + projectGroups: [], remoteBranchConflictByWorktreeId: {}, runtimeStatusByEnvironmentId, settings: null, diff --git a/src/renderer/src/components/sidebar/WorktreeCard.tsx b/src/renderer/src/components/sidebar/WorktreeCard.tsx index 5759f90ee7c..668a590e7c5 100644 --- a/src/renderer/src/components/sidebar/WorktreeCard.tsx +++ b/src/renderer/src/components/sidebar/WorktreeCard.tsx @@ -26,7 +26,7 @@ import WorktreeCardAgents from './WorktreeCardAgents' import { WorktreeCardStatusSlot } from './WorktreeCardStatusSlot' import { cn } from '@/lib/utils' import { activateWorktreeFromSidebar } from '@/lib/sidebar-worktree-activation' -import { getRepoKindLabel, isFolderRepo } from '../../../../shared/repo-kind' +import { isFolderRepo } from '../../../../shared/repo-kind' import type { HostedReviewInfo } from '../../../../shared/hosted-review' import type { GitHubWorkItem, @@ -222,6 +222,7 @@ const WorktreeCard = React.memo(function WorktreeCard({ const fetchIssue = useAppStore((s) => s.fetchIssue) const fetchLinearIssue = useAppStore((s) => s.fetchLinearIssue) const cardProps = useAppStore((s) => s.worktreeCardProperties) + const projectGroups = useAppStore((s) => s.projectGroups) const newCardStyle = settings?.experimentalNewWorktreeCardStyle === true const compactCards = !newCardStyle && settings?.compactWorktreeCards === true const activeSurfaceIsSecondary = isActiveSurface && activeSurfaceVariant === 'secondary' @@ -361,6 +362,22 @@ const WorktreeCard = React.memo(function WorktreeCard({ const folderWorkspaceId = workspaceScope?.type === 'folder' ? workspaceScope.folderWorkspaceId : null const isFolder = repo ? isFolderRepo(repo) : folderWorkspaceId !== null + const hasProjectGroups = projectGroups.length > 0 + const branchIdentityDisplay = !isFolder && branch.length > 0 ? branch : undefined + const folderPathIdentityDisplay = + isFolder && hasProjectGroups && worktree.path.trim().length > 0 ? worktree.path : undefined + const identityDisplay = branchIdentityDisplay ?? folderPathIdentityDisplay + const hasPathIdentityEnabled = cardProps.includes('branch') + const showIdentityInNewCard = newCardStyle && hasPathIdentityEnabled && Boolean(identityDisplay) + const folderMetaRowContent = newCardStyle + ? hasPathIdentityEnabled && Boolean(folderPathIdentityDisplay) + : isFolder + const statusIdentityLabel = hasProjectGroups + ? translate( + 'auto.components.sidebar.WorktreeCard.branchFolderPathIdentity', + 'Branch or folder path' + ) + : translate('auto.components.sidebar.WorktreeCard.branchIdentity', 'Branch') const hostedReviewCacheKey = repo && branch ? getHostedReviewCacheKey( @@ -1044,7 +1061,8 @@ const WorktreeCard = React.memo(function WorktreeCard({ const showBranch = !isFolder && branch.length > 0 && - (newCardStyle ? cardProps.includes('branch') : !compactCards || branch !== worktree.displayName) + !newCardStyle && + (!compactCards || branch !== worktree.displayName) // Why: rebases already surface in source control; keep dense cards from // carrying a persistent rebase chip while preserving other interruption cues. const showConflictOperationBadge = @@ -1063,30 +1081,28 @@ const WorktreeCard = React.memo(function WorktreeCard({ const hasDetailedMetaRowContent = Boolean( (showRepoBadgeInMetaRow && repo) || showHostContextBadge || - isFolder || + folderMetaRowContent || showBranch || + showIdentityInNewCard || showDetachedHeadInMetaRow || showConflictOperationBadge || cacheStartedAt != null || showMetaRowDetails ) const hasMetaRow = compactCards - ? hasMetadataBadge || (newCardStyle && showBranch) || cacheStartedAt != null + ? hasMetadataBadge || cacheStartedAt != null : hasDetailedMetaRowContent const showHeaderActions = showTitleRowPrimary || showDeleteQuickAction // Why: the hover owns full identity when the row truncates; normalize once // so title/branch de-dupe and identity-only hover eligibility stay in sync. const trimmedVisibleCardTitle = visibleCardTitle.trim() const showBranchIdentityHover = newCardStyle - ? !isFolder && - branch.length > 0 && + ? Boolean(identityDisplay) && !cardProps.includes('branch') && - branch !== trimmedVisibleCardTitle + identityDisplay !== trimmedVisibleCardTitle : compactCards && showBranch const hoverBranchName = newCardStyle - ? !isFolder && branch.length > 0 - ? branch - : undefined + ? identityDisplay : showBranchIdentityHover ? branch : undefined @@ -1244,7 +1260,8 @@ const WorktreeCard = React.memo(function WorktreeCard({ onToggleUnread={handleToggleUnreadQuick} prDisplay={hoverReview} newCardStyle={newCardStyle} - hasBranchIdentity={!isFolder && branch.length > 0} + hasBranchIdentity={Boolean(identityDisplay)} + branchIdentityLabel={statusIdentityLabel} /> ) : null} @@ -1357,17 +1374,6 @@ const WorktreeCard = React.memo(function WorktreeCard({ } /> - {isFolder && ( - - {repo - ? getRepoKindLabel(repo) - : translate('auto.components.sidebar.WorktreeCard.93aebe4529', 'Folder')} - - )} - {typeof worktree.firstAgentMessageRenameError === 'string' && worktree.firstAgentMessageRenameError.length > 0 && !titleRenaming ? ( @@ -1527,7 +1533,13 @@ const WorktreeCard = React.memo(function WorktreeCard({ )} - {isFolder ? ( + {showIdentityInNewCard ? ( + + ) : isFolder && !newCardStyle ? ( ({ useAppStore: (selector: (state: unknown) => unknown) => selector({ agentActivityDisplayMode: 'compact', + projectGroups, setAgentActivityDisplayMode, setWorktreeCardMode, setWorktreeCardProperties, @@ -112,6 +114,7 @@ function renderMenu(): void { beforeEach(() => { settings = { compactWorktreeCards: false, experimentalNewWorktreeCardStyle: false } + projectGroups = [] worktreeCardProperties = [ 'status', 'unread', @@ -153,4 +156,23 @@ describe('WorktreeCardDisplayMenuSection', () => { expect(setWorktreeCardMode).toHaveBeenCalledWith('Compact') }) + + it('keeps branch-only copy when project groups are unavailable', () => { + settings = { compactWorktreeCards: false, experimentalNewWorktreeCardStyle: true } + + renderMenu() + + expect(container?.textContent).toContain('Branch name') + expect(container?.textContent).not.toContain('Branch / folder path') + }) + + it('mentions folder paths when project groups can create folder workspaces', () => { + settings = { compactWorktreeCards: false, experimentalNewWorktreeCardStyle: true } + projectGroups = [{ id: 'group-1' }] + + renderMenu() + + expect(container?.textContent).toContain('Branch / folder path') + expect(container?.textContent).not.toContain('Branch name') + }) }) diff --git a/src/renderer/src/components/sidebar/WorktreeCardDisplayMenuSection.tsx b/src/renderer/src/components/sidebar/WorktreeCardDisplayMenuSection.tsx index f2447813ca5..535ab541435 100644 --- a/src/renderer/src/components/sidebar/WorktreeCardDisplayMenuSection.tsx +++ b/src/renderer/src/components/sidebar/WorktreeCardDisplayMenuSection.tsx @@ -32,6 +32,7 @@ export function WorktreeCardDisplayMenuSection({ const setWorktreeCardMode = useAppStore((s) => s.setWorktreeCardMode) const agentActivityDisplayMode = useAppStore((s) => s.agentActivityDisplayMode) const setAgentActivityDisplayMode = useAppStore((s) => s.setAgentActivityDisplayMode) + const projectGroups = useAppStore((s) => s.projectGroups) const newCardStyle = settings?.experimentalNewWorktreeCardStyle === true const cardLayout = settings?.compactWorktreeCards ? 'compact' : 'detailed' const cardLayoutLabel = @@ -39,9 +40,10 @@ export function WorktreeCardDisplayMenuSection({ const visiblePropertyCount = PROPERTY_OPTIONS.filter((opt) => worktreeCardProperties.includes(opt.id) ).length + const hasProjectGroups = projectGroups.length > 0 const worktreeCardPropertyOptions = useMemo( - () => getWorktreeCardPropertyOptions({ newCardStyle }), - [newCardStyle] + () => getWorktreeCardPropertyOptions({ newCardStyle, hasProjectGroups }), + [newCardStyle, hasProjectGroups] ) const handleWorktreeCardPropertyChange = useCallback( (properties: readonly WorktreeCardProperty[], checked: boolean): void => { diff --git a/src/renderer/src/components/sidebar/WorktreeCardStatusSlot.test.tsx b/src/renderer/src/components/sidebar/WorktreeCardStatusSlot.test.tsx index 13cf96fe897..4fdb666088a 100644 --- a/src/renderer/src/components/sidebar/WorktreeCardStatusSlot.test.tsx +++ b/src/renderer/src/components/sidebar/WorktreeCardStatusSlot.test.tsx @@ -205,7 +205,7 @@ describe('WorktreeCardStatusSlot', () => { expect(markup).not.toContain('bg-neutral-500/40') }) - it('uses a branch icon instead of the quiet active dot when new card style has no review', () => { + it('uses a branch icon with branch-only tooltip copy by default', () => { const markup = renderToStaticMarkup( { ) expect(markup).toContain('Branch') + expect(markup).not.toContain('Branch or folder path') expect(markup).toContain('lucide-git-branch') expect(markup).toContain('size-[13px] translate-x-px text-muted-foreground/70') expect(markup).toContain('text-muted-foreground/70') expect(markup).not.toContain('bg-emerald-500') }) + it('uses context-aware branch or folder path tooltip copy', () => { + const markup = renderToStaticMarkup( + + ) + + expect(markup).toContain('Branch or folder path') + expect(markup).toContain('lucide-git-branch') + }) + it('keeps the quiet dot when the row has no branch identity', () => { const markup = renderToStaticMarkup( (['active', 'done', 'inactive']) // Why: a missing review display can also mean provider state is unavailable, -// so the passive label names the branch cue without claiming no review exists. -const BRANCH_STATUS_LABEL = 'Branch' +// so the passive label names the identity cue without claiming no review exists. +function getDefaultBranchIdentityLabel(): string { + return translate('auto.components.sidebar.WorktreeCardStatusSlot.branchIdentity', 'Branch') +} // Why: branch-style SVGs are optically left-heavy; this keeps them aligned with // the centered activity dots in the shared status column. const compactReviewAndBranchStatusIconClassName = 'size-[13px] translate-x-px' @@ -93,6 +97,7 @@ export function WorktreeCardStatusSlot({ prDisplay = null, newCardStyle = false, hasBranchIdentity = false, + branchIdentityLabel, className }: WorktreeCardStatusSlotProps): React.JSX.Element | null { const status = useWorktreeActivityStatus(worktreeId) @@ -112,7 +117,7 @@ export function WorktreeCardStatusSlot({ canShowReviewStatus && prDisplay ? getReviewStatusTooltip(prDisplay) : canShowBranchStatus - ? BRANCH_STATUS_LABEL + ? (branchIdentityLabel ?? getDefaultBranchIdentityLabel()) : statusLabel const passiveStatusTooltip = newCardStyle && isUnread ? `${passiveStatusLabel} · Unread` : passiveStatusLabel diff --git a/src/renderer/src/components/sidebar/sidebar-workspace-option-items.test.ts b/src/renderer/src/components/sidebar/sidebar-workspace-option-items.test.ts index e43f8b9d7ca..40efe8f0937 100644 --- a/src/renderer/src/components/sidebar/sidebar-workspace-option-items.test.ts +++ b/src/renderer/src/components/sidebar/sidebar-workspace-option-items.test.ts @@ -36,4 +36,30 @@ describe('worktree card property options', () => { expect(options.map((option) => option.label)).toContain('Linear issues') expect(options.map((option) => option.label)).toContain('Automation') }) + + it('uses branch-only copy by default and without project groups', () => { + const defaultOptions = getWorktreeCardPropertyOptions() + const newCardOptions = getWorktreeCardPropertyOptions({ + newCardStyle: true, + hasProjectGroups: false + }) + + expect(defaultOptions.find((option) => option.id === 'branch')?.label).toBe('Branch name') + expect(newCardOptions.find((option) => option.id === 'branch')?.label).toBe('Branch name') + }) + + it('keeps branch-only copy for legacy cards even with project groups', () => { + const options = getWorktreeCardPropertyOptions({ hasProjectGroups: true }) + + expect(options.find((option) => option.id === 'branch')?.label).toBe('Branch name') + }) + + it('mentions folder paths only for new card style with project groups', () => { + const options = getWorktreeCardPropertyOptions({ + newCardStyle: true, + hasProjectGroups: true + }) + + expect(options.find((option) => option.id === 'branch')?.label).toBe('Branch / folder path') + }) }) diff --git a/src/renderer/src/components/sidebar/sidebar-workspace-option-items.ts b/src/renderer/src/components/sidebar/sidebar-workspace-option-items.ts index 1772ea4c14d..64c165573c8 100644 --- a/src/renderer/src/components/sidebar/sidebar-workspace-option-items.ts +++ b/src/renderer/src/components/sidebar/sidebar-workspace-option-items.ts @@ -158,21 +158,36 @@ const ISSUE_WORKTREE_CARD_PROPERTY_OPTIONS: WorktreeCardPropertyOption[] = [ type WorktreeCardPropertyOptionsInput = { newCardStyle?: boolean + hasProjectGroups?: boolean } export function getWorktreeCardPropertyOptions({ - newCardStyle = false + newCardStyle = false, + hasProjectGroups = false }: WorktreeCardPropertyOptionsInput = {}): WorktreeCardPropertyOption[] { const issueOptions = newCardStyle ? ISSUE_WORKTREE_CARD_PROPERTY_OPTIONS : [TASK_WORKTREE_CARD_PROPERTY_OPTION] + const branchOption: WorktreeCardPropertyOption = { + id: 'branch', + properties: ['branch'], + get label() { + return newCardStyle && hasProjectGroups + ? translate( + 'auto.components.sidebar.SidebarWorkspaceOptionsMenu.folderPathIdentity', + 'Branch / folder path' + ) + : translate('auto.components.sidebar.SidebarWorkspaceOptionsMenu.219ebf1961', 'Branch name') + } + } if (newCardStyle) { - return [...issueOptions, ...BASE_WORKTREE_CARD_PROPERTY_OPTIONS.slice(1)] + return [...issueOptions, ...BASE_WORKTREE_CARD_PROPERTY_OPTIONS.slice(1, -1), branchOption] } return [ BASE_WORKTREE_CARD_PROPERTY_OPTIONS[0], ...issueOptions, - ...BASE_WORKTREE_CARD_PROPERTY_OPTIONS.slice(1) + ...BASE_WORKTREE_CARD_PROPERTY_OPTIONS.slice(1, -1), + branchOption ] } diff --git a/src/renderer/src/i18n/locales/en.json b/src/renderer/src/i18n/locales/en.json index 9c39c9bccff..ce3555d7062 100644 --- a/src/renderer/src/i18n/locales/en.json +++ b/src/renderer/src/i18n/locales/en.json @@ -3750,7 +3750,8 @@ "8d62c68b35": "Notes", "2d74665a56": "Ports", "65a9820bd1": "Agent statuses", - "219ebf1961": "Branch name" + "219ebf1961": "Branch name", + "folderPathIdentity": "Branch / folder path" }, "SshDisconnectedDialog": { "ca4a7892af": "Connecting...", @@ -3826,7 +3827,9 @@ "021538e1d1": "SSH disconnected", "runtimeHostDisconnected": "Server disconnected", "runtimeHostProject": "Project on Orca server", - "automationCreated": "Created by automation" + "automationCreated": "Created by automation", + "branchIdentity": "Branch", + "branchFolderPathIdentity": "Branch or folder path" }, "WorktreeCardAgents": { "1b0a156717": "Agents" @@ -4264,6 +4267,9 @@ "current": "Current", "searchPlaceholder": "Search worktrees...", "empty": "No matching eligible worktrees." + }, + "WorktreeCardStatusSlot": { + "branchIdentity": "Branch" } }, "shared": { diff --git a/src/renderer/src/i18n/locales/es.json b/src/renderer/src/i18n/locales/es.json index eafb7919e08..c862f5300fe 100644 --- a/src/renderer/src/i18n/locales/es.json +++ b/src/renderer/src/i18n/locales/es.json @@ -3736,7 +3736,8 @@ "automation": "Automation", "2d74665a56": "Puertos", "65a9820bd1": "Estados del agente", - "219ebf1961": "Nombre de rama" + "219ebf1961": "Nombre de rama", + "folderPathIdentity": "Rama / ruta de carpeta" }, "SshDisconnectedDialog": { "ca4a7892af": "Conectando...", @@ -3812,7 +3813,9 @@ "021538e1d1": "SSH desconectado", "runtimeHostDisconnected": "Server disconnected", "runtimeHostProject": "Project on Orca server", - "automationCreated": "Created by automation" + "automationCreated": "Created by automation", + "branchIdentity": "Rama", + "branchFolderPathIdentity": "Rama o ruta de carpeta" }, "WorktreeCardAgents": { "1b0a156717": "Agents" @@ -4264,6 +4267,9 @@ "current": "Actual", "searchPlaceholder": "Buscar árboles de trabajo...", "empty": "No hay árboles de trabajo elegibles que coincidan." + }, + "WorktreeCardStatusSlot": { + "branchIdentity": "Rama" } }, "shared": { @@ -6217,19 +6223,19 @@ "29154326bb": "en", "ab20575a8a": "apagado", "ab3a1f9068": "wsl.exe", - "ask_before_closing_running_terminals_title": "Ask Before Closing Running Terminals", - "ask_before_closing_running_terminals_description": "Show a confirmation before closing a terminal that has a running command or agent.", + "ask_before_closing_running_terminals_title": "Preguntar antes de cerrar terminales en ejecución", + "ask_before_closing_running_terminals_description": "Muestra una confirmación antes de cerrar un terminal que tiene un comando o agente en ejecución.", "scrollSpeed": { - "title": "Scroll Speed", - "description": "Tune normal terminal scrollback, fast modifier scrolling, and full-screen TUI wheel speed.", - "helper": "Adjust how wheel input feels in scrollback and in mouse-aware terminal apps.", - "reset": "Reset", + "title": "Velocidad de desplazamiento", + "description": "Ajusta el desplazamiento normal del terminal, el desplazamiento rápido con modificador y la velocidad de rueda en TUI de pantalla completa.", + "helper": "Ajusta cómo se siente la entrada de la rueda en el historial de desplazamiento y en apps de terminal compatibles con el ratón.", + "reset": "Restablecer", "normal": "Normal", - "normalDescription": "Scrollback wheel multiplier.", - "fast": "Fast", - "fastDescription": "Extra multiplier while scrolling with a modifier key.", + "normalDescription": "Multiplicador de la rueda en el historial.", + "fast": "Rápido", + "fastDescription": "Multiplicador extra al desplazarse con una tecla modificadora.", "tui": "TUI", - "tuiDescription": "Discrete wheel reports for full-screen terminal apps." + "tuiDescription": "Informes discretos de rueda para apps de terminal de pantalla completa." } }, "TerminalSettingsPreview": { @@ -7865,11 +7871,11 @@ "keyword_yaml": "yaml", "keyword_custom": "custom" }, - "ask_before_closing_running_terminals_title": "Ask Before Closing Running Terminals", - "ask_before_closing_running_terminals_description": "Show a confirmation before closing a terminal that has a running command or agent.", + "ask_before_closing_running_terminals_title": "Preguntar antes de cerrar terminales en ejecución", + "ask_before_closing_running_terminals_description": "Muestra una confirmación antes de cerrar un terminal que tiene un comando o agente en ejecución.", "scrollSpeed": { - "title": "Scroll Speed", - "description": "Tune normal terminal scrollback, fast modifier scrolling, and full-screen TUI wheel speed." + "title": "Velocidad de desplazamiento", + "description": "Ajusta el desplazamiento normal del terminal, el desplazamiento rápido con modificador y la velocidad de rueda en TUI de pantalla completa." } }, "windows": { diff --git a/src/renderer/src/i18n/locales/ja.json b/src/renderer/src/i18n/locales/ja.json index 01f3290bdc4..8e3e74dba75 100644 --- a/src/renderer/src/i18n/locales/ja.json +++ b/src/renderer/src/i18n/locales/ja.json @@ -3717,7 +3717,8 @@ "2d74665a56": "ポート", "65a9820bd1": "Agent ステータス", "219ebf1961": "ブランチ名", - "automation": "Automation" + "automation": "Automation", + "folderPathIdentity": "ブランチ / フォルダパス" }, "SshDisconnectedDialog": { "ca4a7892af": "接続中...", @@ -3793,7 +3794,9 @@ "021538e1d1": "SSH が切断されました", "runtimeHostDisconnected": "Server disconnected", "runtimeHostProject": "Project on Orca server", - "automationCreated": "Created by automation" + "automationCreated": "Created by automation", + "branchIdentity": "ブランチ", + "branchFolderPathIdentity": "ブランチまたはフォルダパス" }, "WorktreeCardAgents": { "1b0a156717": "Agents" @@ -4264,6 +4267,9 @@ "current": "現在", "searchPlaceholder": "ワークツリーを検索...", "empty": "一致する対象ワークツリーがありません。" + }, + "WorktreeCardStatusSlot": { + "branchIdentity": "ブランチ" } }, "shared": { @@ -6239,19 +6245,19 @@ "29154326bb": "の上", "ab20575a8a": "オフ", "ab3a1f9068": "wsl.exe", - "ask_before_closing_running_terminals_title": "Ask Before Closing Running Terminals", - "ask_before_closing_running_terminals_description": "Show a confirmation before closing a terminal that has a running command or agent.", + "ask_before_closing_running_terminals_title": "実行中のターミナルを閉じる前に確認", + "ask_before_closing_running_terminals_description": "実行中のコマンドまたはエージェントがあるターミナルを閉じる前に確認を表示します。", "scrollSpeed": { - "title": "Scroll Speed", - "description": "Tune normal terminal scrollback, fast modifier scrolling, and full-screen TUI wheel speed.", - "helper": "Adjust how wheel input feels in scrollback and in mouse-aware terminal apps.", - "reset": "Reset", - "normal": "Normal", - "normalDescription": "Scrollback wheel multiplier.", - "fast": "Fast", - "fastDescription": "Extra multiplier while scrolling with a modifier key.", + "title": "スクロール速度", + "description": "通常のターミナルスクロールバック、修飾キー付き高速スクロール、全画面 TUI のホイール速度を調整します。", + "helper": "スクロールバックやマウス対応ターミナルアプリでのホイール操作の感触を調整します。", + "reset": "リセット", + "normal": "通常", + "normalDescription": "スクロールバックのホイール倍率。", + "fast": "高速", + "fastDescription": "修飾キーを押しながらスクロールするときの追加倍率。", "tui": "TUI", - "tuiDescription": "Discrete wheel reports for full-screen terminal apps." + "tuiDescription": "全画面ターミナルアプリ向けの離散的なホイール通知。" } }, "TerminalSettingsPreview": { @@ -7887,11 +7893,11 @@ "33031c1465": "文字サイズ", "0fe0073f0c": "新規ペインとライブ アップデートのデフォルトの terminal フォント サイズ。", "5930244899": "フォントサイズ", - "ask_before_closing_running_terminals_title": "Ask Before Closing Running Terminals", - "ask_before_closing_running_terminals_description": "Show a confirmation before closing a terminal that has a running command or agent.", + "ask_before_closing_running_terminals_title": "実行中のターミナルを閉じる前に確認", + "ask_before_closing_running_terminals_description": "実行中のコマンドまたはエージェントがあるターミナルを閉じる前に確認を表示します。", "scrollSpeed": { - "title": "Scroll Speed", - "description": "Tune normal terminal scrollback, fast modifier scrolling, and full-screen TUI wheel speed." + "title": "スクロール速度", + "description": "通常のターミナルスクロールバック、修飾キー付き高速スクロール、全画面 TUI のホイール速度を調整します。" } }, "windows": { diff --git a/src/renderer/src/i18n/locales/ko.json b/src/renderer/src/i18n/locales/ko.json index 1922d7953c2..5e9625ab84b 100644 --- a/src/renderer/src/i18n/locales/ko.json +++ b/src/renderer/src/i18n/locales/ko.json @@ -3717,7 +3717,8 @@ "2d74665a56": "포트", "65a9820bd1": "Agent 상태", "219ebf1961": "브랜치 이름", - "automation": "자동화" + "automation": "자동화", + "folderPathIdentity": "브랜치 / 폴더 경로" }, "SshDisconnectedDialog": { "ca4a7892af": "연결 중...", @@ -3793,7 +3794,9 @@ "021538e1d1": "SSH 연결이 끊어졌습니다.", "runtimeHostDisconnected": "Server disconnected", "runtimeHostProject": "Project on Orca server", - "automationCreated": "Created by automation" + "automationCreated": "Created by automation", + "branchIdentity": "브랜치", + "branchFolderPathIdentity": "브랜치 또는 폴더 경로" }, "WorktreeCardAgents": { "1b0a156717": "Agents" @@ -4264,6 +4267,9 @@ "current": "현재", "searchPlaceholder": "워크트리 검색...", "empty": "일치하는 적격 워크트리가 없습니다." + }, + "WorktreeCardStatusSlot": { + "branchIdentity": "브랜치" } }, "shared": { @@ -6205,16 +6211,16 @@ "ask_before_closing_running_terminals_title": "실행 중인 Terminals을 닫기 전에 확인", "ask_before_closing_running_terminals_description": "실행 중인 명령이나 agent가 있는 terminal을 닫기 전에 확인 창을 표시합니다.", "scrollSpeed": { - "title": "Scroll Speed", - "description": "Tune normal terminal scrollback, fast modifier scrolling, and full-screen TUI wheel speed.", - "helper": "Adjust how wheel input feels in scrollback and in mouse-aware terminal apps.", - "reset": "Reset", - "normal": "Normal", - "normalDescription": "Scrollback wheel multiplier.", - "fast": "Fast", - "fastDescription": "Extra multiplier while scrolling with a modifier key.", + "title": "스크롤 속도", + "description": "일반 터미널 스크롤백, 수정 키 빠른 스크롤, 전체 화면 TUI 휠 속도를 조정합니다.", + "helper": "스크롤백과 마우스 지원 터미널 앱에서 휠 입력의 느낌을 조정합니다.", + "reset": "재설정", + "normal": "일반", + "normalDescription": "스크롤백 휠 배율.", + "fast": "빠름", + "fastDescription": "수정 키로 스크롤할 때의 추가 배율.", "tui": "TUI", - "tuiDescription": "Discrete wheel reports for full-screen terminal apps." + "tuiDescription": "전체 화면 터미널 앱을 위한 개별 휠 보고." } }, "TerminalSettingsPreview": { @@ -7853,8 +7859,8 @@ "ask_before_closing_running_terminals_title": "실행 중인 Terminals을 닫기 전에 확인", "ask_before_closing_running_terminals_description": "실행 중인 명령이나 agent가 있는 terminal을 닫기 전에 확인을 표시합니다.", "scrollSpeed": { - "title": "Scroll Speed", - "description": "Tune normal terminal scrollback, fast modifier scrolling, and full-screen TUI wheel speed." + "title": "스크롤 속도", + "description": "일반 터미널 스크롤백, 수정 키 빠른 스크롤, 전체 화면 TUI 휠 속도를 조정합니다." } }, "windows": { diff --git a/src/renderer/src/i18n/locales/zh.json b/src/renderer/src/i18n/locales/zh.json index ff179118724..6d57d90932e 100644 --- a/src/renderer/src/i18n/locales/zh.json +++ b/src/renderer/src/i18n/locales/zh.json @@ -3717,7 +3717,8 @@ "2d74665a56": "端口", "65a9820bd1": "Agent 状态", "219ebf1961": "分支名称", - "automation": "Automation" + "automation": "Automation", + "folderPathIdentity": "分支 / 文件夹路径" }, "SshDisconnectedDialog": { "ca4a7892af": "正在连接...", @@ -3793,7 +3794,9 @@ "021538e1d1": "SSH 已断开连接", "runtimeHostDisconnected": "Server disconnected", "runtimeHostProject": "Project on Orca server", - "automationCreated": "Created by automation" + "automationCreated": "Created by automation", + "branchIdentity": "分支", + "branchFolderPathIdentity": "分支或文件夹路径" }, "WorktreeCardAgents": { "1b0a156717": "Agents" @@ -4264,6 +4267,9 @@ "current": "当前", "searchPlaceholder": "搜索工作树...", "empty": "没有匹配的可用工作树。" + }, + "WorktreeCardStatusSlot": { + "branchIdentity": "分支" } }, "shared": { @@ -6205,16 +6211,16 @@ "ask_before_closing_running_terminals_title": "关闭运行中的 Terminal 前询问", "ask_before_closing_running_terminals_description": "在关闭有运行中命令或 agent 的 terminal 前显示确认。", "scrollSpeed": { - "title": "Scroll Speed", - "description": "Tune normal terminal scrollback, fast modifier scrolling, and full-screen TUI wheel speed.", - "helper": "Adjust how wheel input feels in scrollback and in mouse-aware terminal apps.", - "reset": "Reset", - "normal": "Normal", - "normalDescription": "Scrollback wheel multiplier.", - "fast": "Fast", - "fastDescription": "Extra multiplier while scrolling with a modifier key.", + "title": "滚动速度", + "description": "调整普通终端回滚、修饰键快速滚动以及全屏 TUI 鼠标滚轮速度。", + "helper": "调整在回滚区域和支持鼠标的终端应用中的滚轮输入手感。", + "reset": "重置", + "normal": "普通", + "normalDescription": "回滚滚轮倍率。", + "fast": "快速", + "fastDescription": "按住修饰键滚动时的额外倍率。", "tui": "TUI", - "tuiDescription": "Discrete wheel reports for full-screen terminal apps." + "tuiDescription": "面向全屏终端应用的离散滚轮报告。" } }, "TerminalSettingsPreview": { @@ -7853,8 +7859,8 @@ "ask_before_closing_running_terminals_title": "关闭运行中的 Terminal 前询问", "ask_before_closing_running_terminals_description": "在关闭有运行中命令或 agent 的 terminal 前显示确认。", "scrollSpeed": { - "title": "Scroll Speed", - "description": "Tune normal terminal scrollback, fast modifier scrolling, and full-screen TUI wheel speed." + "title": "滚动速度", + "description": "调整普通终端回滚、修饰键快速滚动以及全屏 TUI 鼠标滚轮速度。" } }, "windows": {