diff --git a/src/renderer/src/components/tab-bar/SortableTab.rename-shortcut.test.tsx b/src/renderer/src/components/tab-bar/SortableTab.rename-shortcut.test.tsx
index 561fd9e0cc95..3885b09578e0 100644
--- a/src/renderer/src/components/tab-bar/SortableTab.rename-shortcut.test.tsx
+++ b/src/renderer/src/components/tab-bar/SortableTab.rename-shortcut.test.tsx
@@ -264,6 +264,7 @@ async function renderSortableTab({
const module = await import('./SortableTab')
return module.default({
tab: makeTerminalTab() as never,
+ agent: null,
unifiedTabId: 'terminal-tab-1',
groupId: 'group-1',
tabCount: 1,
diff --git a/src/renderer/src/components/tab-bar/SortableTab.tsx b/src/renderer/src/components/tab-bar/SortableTab.tsx
index 746fe031e4e3..1c5a9df5e4c4 100644
--- a/src/renderer/src/components/tab-bar/SortableTab.tsx
+++ b/src/renderer/src/components/tab-bar/SortableTab.tsx
@@ -2,13 +2,13 @@ import { useCallback, useEffect, useState } from 'react'
import { useSortable } from '@dnd-kit/sortable'
import { X, Minimize2, Pin } from 'lucide-react'
import { stripLeadingAgentTitleDecoration } from '../../../../shared/agent-title-decoration'
-import { useTabAgent } from '@/lib/use-tab-agent'
import { getAgentLabel } from '@/lib/agent-catalog'
import { basename } from '@/lib/path'
import { isImeCompositionKeyDown } from '@/lib/ime-composition-keyboard-event'
import { Input } from '@/components/ui/input'
import { TabHoverCard } from './TabHoverCard'
import type { TerminalTab } from '../../../../shared/terminal-tab-types'
+import type { TerminalAgent } from '../../../../shared/terminal-agent'
import type { TabDragItemData } from '../tab-group/useTabDragSplit'
import { useAppStore } from '../../store'
import {
@@ -33,9 +33,18 @@ import {
terminalTabHasUnreadActivity
} from './terminal-tab-activity-status'
import { CLOSE_ALL_CONTEXT_MENUS_EVENT } from '@/lib/close-all-context-menus'
+import type { NativeChatTabSession } from './tab-session-history-switch'
-type SortableTabProps = {
- tab: TerminalTab
+/** What the strip draws for a terminal or native chat tab; never a source of agent identity. */
+type SortableTabModel = Pick<
+ TerminalTab,
+ 'id' | 'worktreeId' | 'title' | 'customTitle' | 'color' | 'shellOverride' | 'launchAgent'
+>
+
+export type SortableTabProps = {
+ tab: SortableTabModel
+ /** The tab's agent, resolved by the caller from its own source of truth (pane signals or the chat's provider). */
+ agent: TerminalAgent | null
unifiedTabId: string
groupId: string
tabCount: number
@@ -63,12 +72,13 @@ type SortableTabProps = {
/** Toggle the tab between terminal and native chat view. */
onToggleViewMode?: () => void
canSplitTerminal?: boolean
- /** Set only for a native chat tab: the chat session it shows. */
- structuredSessionId?: string
+ /** Set only for a native chat tab. */
+ nativeChat?: NativeChatTabSession
}
export default function SortableTab({
tab,
+ agent: tabAgent,
unifiedTabId,
groupId,
tabCount,
@@ -93,7 +103,7 @@ export default function SortableTab({
isChatView = false,
onToggleViewMode,
canSplitTerminal = true,
- structuredSessionId
+ nativeChat
}: SortableTabProps): React.JSX.Element {
// Why: agent-completion unread exists even with terminal-attention off; collapse both sources to one primitive so unrelated tabs don't re-render.
const hasUnreadActivity = useAppStore((s) =>
@@ -118,9 +128,6 @@ export default function SortableTab({
// Why: shellOverride is stamped at create time, so changing the default shell later won't repaint existing tabs.
const shellForIcon = tab.shellOverride
- // Why: use hook status + title evidence so the icon reflects the harness running now, not just the launch command.
- const tabAgent = useTabAgent(tab)
-
// Why: with a provider icon shown, strip the agent's own leading glyph so the tab doesn't show two icons for one agent.
const displayTitle =
tab.customTitle ?? (tabAgent ? stripLeadingAgentTitleDecoration(tab.title) : tab.title)
@@ -412,7 +419,7 @@ export default function SortableTab({
isChatView={isChatView}
onToggleViewMode={onToggleViewMode}
canSplitTerminal={canSplitTerminal}
- structuredSessionId={structuredSessionId}
+ nativeChat={nativeChat}
/>
>
)
diff --git a/src/renderer/src/components/tab-bar/SortableTab.update-depth-probe.test.tsx b/src/renderer/src/components/tab-bar/SortableTab.update-depth-probe.test.tsx
index 0f9ad5e767f9..779f177a3170 100644
--- a/src/renderer/src/components/tab-bar/SortableTab.update-depth-probe.test.tsx
+++ b/src/renderer/src/components/tab-bar/SortableTab.update-depth-probe.test.tsx
@@ -68,8 +68,6 @@ vi.mock('@dnd-kit/sortable', () => ({
})
}))
-vi.mock('@/lib/use-tab-agent', () => ({ useTabAgent: () => null }))
-
vi.mock('@/components/ui/tooltip', () => ({
TooltipProvider: ({ children }: { children: ReactNode }) => <>{children}>,
Tooltip: ({ children }: { children: ReactNode }) =>
{children}
,
@@ -144,6 +142,7 @@ function Harness({ tab }: { tab: TerminalTab }): ReactElement {
return (
({ toast: { success: vi.fn(), error: vi.fn() } }))
vi.mock('./TabSessionSurfaceSwitchMenuItems', () => ({
TabSessionSurfaceSwitchMenuItems: ({
tab,
- structuredSessionId,
+ nativeChat,
leadingSeparator
}: {
tab: { id: string }
- structuredSessionId?: string
+ nativeChat?: { sessionId: string }
leadingSeparator: boolean
}) => (
)
@@ -116,16 +116,7 @@ function renderMenu(overrides: Partial {
root.render(
{
})
it('offers the session-history chat/CLI move right above Pin Tab', () => {
- const { container } = renderMenu({ structuredSessionId: 'orca-chat-1' })
+ const { container } = renderMenu({ nativeChat: { sessionId: 'orca-chat-1', agent: 'codex' } })
const marker = getSurfaceSwitchMarker(container)
expect(marker.getAttribute('data-tab-id')).toBe('term-1')
diff --git a/src/renderer/src/components/tab-bar/SortableTabContextMenu.tsx b/src/renderer/src/components/tab-bar/SortableTabContextMenu.tsx
index 94b715d18389..d77345a17c61 100644
--- a/src/renderer/src/components/tab-bar/SortableTabContextMenu.tsx
+++ b/src/renderer/src/components/tab-bar/SortableTabContextMenu.tsx
@@ -22,6 +22,7 @@ import { formatShortcutLabel, useOptionalShortcutLabel } from '@/hooks/useShortc
import { translate } from '@/i18n/i18n'
import { TerminalTabSplitMenuSection } from './TerminalTabSplitMenuSection'
import { TabSessionSurfaceSwitchMenuItems } from './TabSessionSurfaceSwitchMenuItems'
+import type { NativeChatTabSession } from './tab-session-history-switch'
import { TAB_CONTEXT_MENU_CONTENT_CLASS } from './tab-context-menu-sizing'
import { CopyTabIdMenuItem } from './CopyTabIdMenuItem'
@@ -89,7 +90,7 @@ const TAB_COLORS = [
] as const
type SortableTabContextMenuProps = {
- tab: TerminalTab
+ tab: Pick
unifiedTabId: string
groupId: string
isActive: boolean
@@ -118,8 +119,8 @@ type SortableTabContextMenuProps = {
/** Toggle the tab between terminal and native chat view. */
onToggleViewMode?: () => void
canSplitTerminal?: boolean
- /** Set only for a native chat tab: the chat session it shows. */
- structuredSessionId?: string
+ /** Set only for a native chat tab. */
+ nativeChat?: NativeChatTabSession
}
export function SortableTabContextMenu({
@@ -146,7 +147,7 @@ export function SortableTabContextMenu({
isChatView = false,
onToggleViewMode,
canSplitTerminal = true,
- structuredSessionId
+ nativeChat
}: SortableTabContextMenuProps): React.JSX.Element {
const keybindings = useAppStore((state) => state.keybindings)
const splitRightShortcut = formatShortcutLabel('terminal.splitRight', keybindings)
@@ -193,7 +194,7 @@ export function SortableTabContextMenu({
) : null}
diff --git a/src/renderer/src/components/tab-bar/TabBar.context-menu.test.ts b/src/renderer/src/components/tab-bar/TabBar.context-menu.test.ts
index e83f32a48521..8c5b649ba749 100644
--- a/src/renderer/src/components/tab-bar/TabBar.context-menu.test.ts
+++ b/src/renderer/src/components/tab-bar/TabBar.context-menu.test.ts
@@ -120,6 +120,12 @@ vi.mock('./SortableTab', () => ({
}
}))
+vi.mock('./TerminalSortableTab', () => ({
+ default: function SortableTab(props: Record) {
+ return { type: 'SortableTab', props }
+ }
+}))
+
vi.mock('./EditorFileTab', () => ({
default: function EditorFileTab(props: Record) {
return { type: 'EditorFileTab', props }
diff --git a/src/renderer/src/components/tab-bar/TabBarItemRow.test.tsx b/src/renderer/src/components/tab-bar/TabBarItemRow.test.tsx
index 90fbfc385f46..7cef72ac4783 100644
--- a/src/renderer/src/components/tab-bar/TabBarItemRow.test.tsx
+++ b/src/renderer/src/components/tab-bar/TabBarItemRow.test.tsx
@@ -11,6 +11,7 @@ import {
import { i18n } from '@/i18n/i18n'
import type { TabBarItem } from './tab-bar-item-model'
import type { WorkspaceVisibleTabType } from '../../../../shared/tab-types'
+import type { AgentType } from '../../../../shared/agent-status-types'
import {
renderTabBarItems,
type TabBarItemSurfaceProps,
@@ -22,6 +23,8 @@ globalThis.IS_REACT_ACT_ENVIRONMENT = true
type TabProps = {
tab?: { id: string; title: string }
+ agent?: string | null
+ nativeChat?: { sessionId: string; agent: string | undefined }
isActive: boolean
isPinned: boolean
onActivate: (id: string) => void
@@ -53,7 +56,17 @@ vi.mock('./EditorFileTab', () => ({
}))
/** Rebuilt on every call, like the strip's projections: equal content, never the same objects. */
-function buildItems({ terminalPinned = false, browserTitle = 'Example' } = {}): TabBarItem[] {
+function buildItems({
+ terminalPinned = false,
+ browserTitle = 'Example',
+ sessionLabel = 'Session',
+ sessionAgent
+}: {
+ terminalPinned?: boolean
+ browserTitle?: string
+ sessionLabel?: string
+ sessionAgent?: AgentType
+} = {}): TabBarItem[] {
return [
{
type: 'terminal',
@@ -117,7 +130,8 @@ function buildItems({ terminalPinned = false, browserTitle = 'Example' } = {}):
groupId: 'group-1',
worktreeId: 'wt-1',
contentType: 'agent-session',
- label: 'Session',
+ ...(sessionAgent ? { agentSessionAgent: sessionAgent } : {}),
+ label: sessionLabel,
customLabel: null,
color: null,
sortOrder: 3,
@@ -133,6 +147,8 @@ type StripInputs = {
managedBrowserCreationEnabled?: boolean
terminalPinned?: boolean
browserTitle?: string
+ sessionLabel?: string
+ sessionAgent?: AgentType
activeTabType?: WorkspaceVisibleTabType
activeClientHostedBrowserRowId?: string | null
statusByRelativePath?: TabBarItemSurfaceRuntime['statusByRelativePath']
@@ -144,6 +160,8 @@ function Strip({
managedBrowserCreationEnabled = false,
terminalPinned,
browserTitle,
+ sessionLabel,
+ sessionAgent,
activeTabType = 'terminal',
activeClientHostedBrowserRowId = null,
statusByRelativePath = STATUS_BY_RELATIVE_PATH
@@ -187,7 +205,7 @@ function Strip({
return (
<>
{renderTabBarItems({
- items: buildItems({ terminalPinned, browserTitle }),
+ items: buildItems({ terminalPinned, browserTitle, sessionLabel, sessionAgent }),
props,
runtime,
actions,
@@ -338,6 +356,25 @@ describe('tab strip rows', () => {
expect(tabRenders).toHaveLength(TAB_IDS.length + 1)
})
+ it.each([
+ 'Hermes automation deprecation',
+ 'Claude Code review',
+ 'Review Grok usage',
+ 'OpenCode launch-flow design'
+ ])('shows a native chat with its own provider when its name is "%s"', (sessionLabel) => {
+ renderStrip({ sessionLabel, sessionAgent: 'codex' })
+
+ expect(lastRender('session-1').tab?.title).toBe(sessionLabel)
+ expect(lastRender('session-1').agent).toBe('codex')
+ expect(lastRender('session-1').nativeChat).toEqual({ sessionId: 'session-1', agent: 'codex' })
+ })
+
+ it('shows no agent for a native chat whose provider is not recorded', () => {
+ renderStrip({ sessionLabel: 'Hermes automation deprecation' })
+
+ expect(lastRender('session-1').agent).toBeNull()
+ })
+
it.each(TAB_IDS)('retires a client-hosted row selection when %s is activated', (tabId) => {
renderStrip()
selectClientHostedBrowserRow({
diff --git a/src/renderer/src/components/tab-bar/TabBarItemRow.tsx b/src/renderer/src/components/tab-bar/TabBarItemRow.tsx
index f2d1fc324c67..04b010cc1230 100644
--- a/src/renderer/src/components/tab-bar/TabBarItemRow.tsx
+++ b/src/renderer/src/components/tab-bar/TabBarItemRow.tsx
@@ -2,10 +2,9 @@ import { memo } from 'react'
import { useTranslation } from 'react-i18next'
import { shallow } from 'zustand/shallow'
import type { GitFileStatus } from '../../../../shared/git-status-types'
-import type { TerminalTab } from '../../../../shared/terminal-tab-types'
-import { isTuiAgent } from '../../../../shared/tui-agent-config'
import type { OpenFile } from '../../store/slices/editor'
import SortableTab from './SortableTab'
+import TerminalSortableTab from './TerminalSortableTab'
import EditorFileTab from './EditorFileTab'
import BrowserTab from './BrowserTab'
import type { DropIndicator } from './drop-indicator'
@@ -13,6 +12,7 @@ import type { TabDragItemData } from '../tab-group/useTabDragSplit'
import { getTabDragLabel, resolveTerminalItemTab, type TabBarItem } from './tab-bar-item-model'
import type { TabBarItemActions } from './use-tab-bar-item-actions'
import { useStructuredChatTabConversationName } from '@/runtime/structured-conversation-name'
+import { agentTypeToIconAgent } from '@/lib/agent-status'
// Why only values and `actions`: anything a tab draws must be a compared prop, or a skipped render shows it stale.
type TabBarItemRowProps = {
@@ -96,7 +96,7 @@ function TabBarItemRow({
}
if (item.type === 'terminal') {
return (
- {}}
canSplitTerminal={false}
- structuredSessionId={item.data.entityId}
+ nativeChat={nativeChat}
/>
)
}
diff --git a/src/renderer/src/components/tab-bar/TabSessionSurfaceSwitchMenuItems.test.tsx b/src/renderer/src/components/tab-bar/TabSessionSurfaceSwitchMenuItems.test.tsx
index 1c9dc908b105..ee50c45b2cbe 100644
--- a/src/renderer/src/components/tab-bar/TabSessionSurfaceSwitchMenuItems.test.tsx
+++ b/src/renderer/src/components/tab-bar/TabSessionSurfaceSwitchMenuItems.test.tsx
@@ -134,8 +134,10 @@ function renderItemsNow(structuredSessionId?: string): void {
Open
diff --git a/src/renderer/src/components/tab-bar/TabSessionSurfaceSwitchMenuItems.tsx b/src/renderer/src/components/tab-bar/TabSessionSurfaceSwitchMenuItems.tsx
index 10c31b0f9c06..5daf01e0399d 100644
--- a/src/renderer/src/components/tab-bar/TabSessionSurfaceSwitchMenuItems.tsx
+++ b/src/renderer/src/components/tab-bar/TabSessionSurfaceSwitchMenuItems.tsx
@@ -11,6 +11,7 @@ import {
lookupTabSessionHistoryRow,
resolveTabSessionHistorySubject,
resolveTabSessionSwitch,
+ type NativeChatTabSession,
type TabSessionHistorySubject,
type TabSessionSwitch
} from './tab-session-history-switch'
@@ -30,13 +31,13 @@ function resolveMove(
// Mounted only while the menu is open, so the history lookup runs per right-click, not per tab.
function useTabSessionSwitch(
- tab: Pick,
- structuredSessionId: string | undefined
+ tab: Pick,
+ nativeChat: NativeChatTabSession | undefined
): ResolvedTabSessionSwitch | null {
const [subject] = useState(() =>
resolveTabSessionHistorySubject(useAppStore.getState(), {
- tab: { id: tab.id, worktreeId: tab.worktreeId, launchAgent: tab.launchAgent },
- structuredSessionId
+ tab: { id: tab.id, worktreeId: tab.worktreeId },
+ nativeChat
})
)
// Only a fresh reply carries current chat ownership, so nothing is offered before it lands.
@@ -70,14 +71,14 @@ function useTabSessionSwitch(
* that shows that session and hidden wherever the row would not offer it. */
export function TabSessionSurfaceSwitchMenuItems({
tab,
- structuredSessionId,
+ nativeChat,
leadingSeparator
}: {
- tab: Pick
- structuredSessionId?: string
+ tab: Pick
+ nativeChat?: NativeChatTabSession
leadingSeparator: boolean
}): React.JSX.Element | null {
- const resolved = useTabSessionSwitch(tab, structuredSessionId)
+ const resolved = useTabSessionSwitch(tab, nativeChat)
const targetState = useAppStore(
useShallow((state) => ({
projects: state.projects,
diff --git a/src/renderer/src/components/tab-bar/TerminalSortableTab.tsx b/src/renderer/src/components/tab-bar/TerminalSortableTab.tsx
new file mode 100644
index 000000000000..ec53f4754585
--- /dev/null
+++ b/src/renderer/src/components/tab-bar/TerminalSortableTab.tsx
@@ -0,0 +1,11 @@
+import { useTabAgent } from '@/lib/use-tab-agent'
+import type { TerminalTab } from '../../../../shared/terminal-tab-types'
+import SortableTab, { type SortableTabProps } from './SortableTab'
+
+type TerminalSortableTabProps = Omit & { tab: TerminalTab }
+
+/** A terminal pane can change agents, so its identity is inferred from live pane signals. */
+export default function TerminalSortableTab(props: TerminalSortableTabProps): React.JSX.Element {
+ const agent = useTabAgent(props.tab)
+ return
+}
diff --git a/src/renderer/src/components/tab-bar/tab-session-history-switch.test.ts b/src/renderer/src/components/tab-bar/tab-session-history-switch.test.ts
index 8fb3188fb134..bcb2c770f51b 100644
--- a/src/renderer/src/components/tab-bar/tab-session-history-switch.test.ts
+++ b/src/renderer/src/components/tab-bar/tab-session-history-switch.test.ts
@@ -175,8 +175,8 @@ describe('resolveTabSessionHistorySubject', () => {
it('finds a native chat tab by the chat it shows', () => {
expect(
resolveTabSessionHistorySubject(makeState(), {
- tab: { id: 'unified-1', worktreeId: WORKTREE_ID, launchAgent: 'codex' },
- structuredSessionId: 'orca-chat-1'
+ tab: { id: 'unified-1', worktreeId: WORKTREE_ID },
+ nativeChat: { sessionId: 'orca-chat-1', agent: 'codex' }
})
).toEqual({ ...chatSubject })
})
@@ -184,19 +184,19 @@ describe('resolveTabSessionHistorySubject', () => {
it('finds a chat of any agent whose CLI can open a copy', () => {
expect(
resolveTabSessionHistorySubject(makeState(), {
- tab: { id: 'unified-1', worktreeId: WORKTREE_ID, launchAgent: 'grok' },
- structuredSessionId: 'orca-chat-1'
+ tab: { id: 'unified-1', worktreeId: WORKTREE_ID },
+ nativeChat: { sessionId: 'orca-chat-1', agent: 'grok' }
})
).toEqual({ ...chatSubject })
})
it.each(['opencode', 'omp'] as const)(
'skips a %s chat, whose CLI cannot open a copy',
- (launchAgent) => {
+ (agent) => {
expect(
resolveTabSessionHistorySubject(makeState(), {
- tab: { id: 'unified-1', worktreeId: WORKTREE_ID, launchAgent },
- structuredSessionId: 'orca-chat-1'
+ tab: { id: 'unified-1', worktreeId: WORKTREE_ID },
+ nativeChat: { sessionId: 'orca-chat-1', agent }
})
).toBeNull()
}
@@ -285,12 +285,8 @@ describe('resolveTabSessionHistorySubject', () => {
).toBeNull()
expect(
resolveTabSessionHistorySubject(state, {
- tab: {
- id: 'unified-1',
- worktreeId: WORKTREE_ID,
- launchAgent: 'claude'
- },
- structuredSessionId: 'orca-chat-1'
+ tab: { id: 'unified-1', worktreeId: WORKTREE_ID },
+ nativeChat: { sessionId: 'orca-chat-1', agent: 'claude' }
})
).toBeNull()
})
@@ -301,12 +297,8 @@ describe('resolveTabSessionHistorySubject', () => {
})
expect(
resolveTabSessionHistorySubject(state, {
- tab: {
- id: 'unified-1',
- worktreeId: WORKTREE_ID,
- launchAgent: 'claude'
- },
- structuredSessionId: 'orca-chat-1'
+ tab: { id: 'unified-1', worktreeId: WORKTREE_ID },
+ nativeChat: { sessionId: 'orca-chat-1', agent: 'claude' }
})
).toMatchObject({
kind: 'chat',
diff --git a/src/renderer/src/components/tab-bar/tab-session-history-switch.ts b/src/renderer/src/components/tab-bar/tab-session-history-switch.ts
index 7eac50cd99c8..72f996eff4e4 100644
--- a/src/renderer/src/components/tab-bar/tab-session-history-switch.ts
+++ b/src/renderer/src/components/tab-bar/tab-session-history-switch.ts
@@ -21,6 +21,7 @@ import {
import type { AgentSessionHandleProvider } from '../../../../shared/agent-session-provider-handle'
import { agentForksConversations } from '../../../../shared/agent-resume-argv'
import type { TerminalTab } from '../../../../shared/terminal-tab-types'
+import type { AgentType } from '../../../../shared/agent-status-types'
import { resolveAiVaultSessionSurfaceSwitchTargets } from '../right-sidebar/ai-vault-session-surface-switch'
import { resolveAiVaultHistoryRowResume } from '../right-sidebar/ai-vault-session-resume-in-chat-workspace'
import { resolveAiVaultTargetWorkspacePath } from '../right-sidebar/ai-vault-session-launch-target'
@@ -100,12 +101,18 @@ export function canPaneOfferResumeInNewChat(
)
}
+/** A native chat tab's session and the provider recorded when it was created. */
+export type NativeChatTabSession = {
+ sessionId: string
+ agent: AgentType | undefined
+}
+
export function resolveTabSessionHistorySubject(
state: AppState,
args: {
- tab: Pick
- /** Set only for a native chat tab: the chat session it shows. */
- structuredSessionId?: string
+ tab: Pick
+ /** Set only for a native chat tab. */
+ nativeChat?: NativeChatTabSession
/** Narrows a terminal tab to one pane's own conversation instead of the tab's best one. */
paneKey?: string
}
@@ -119,13 +126,13 @@ export function resolveTabSessionHistorySubject(
? { workspaceId, request }
: null
}
- if (args.structuredSessionId !== undefined) {
+ if (args.nativeChat) {
// A chat tab's only move is opening a copy in its CLI.
const target =
- args.tab.launchAgent && agentForksConversations(args.tab.launchAgent)
+ args.nativeChat.agent && agentForksConversations(args.nativeChat.agent)
? workspace(args.tab.worktreeId, 'chat')
: null
- return target ? { ...target, kind: 'chat', sessionId: args.structuredSessionId } : null
+ return target ? { ...target, kind: 'chat', sessionId: args.nativeChat.sessionId } : null
}
// The pane-to-conversation mapping tab titles use, limited to agents still running: once the agent
// exits, the tab title keeps its conversation but the move is no longer offered.
diff --git a/src/renderer/src/components/tab-bar/tab-title-tooltip.test.tsx b/src/renderer/src/components/tab-bar/tab-title-tooltip.test.tsx
index 3522861dd0f6..08547cc98439 100644
--- a/src/renderer/src/components/tab-bar/tab-title-tooltip.test.tsx
+++ b/src/renderer/src/components/tab-bar/tab-title-tooltip.test.tsx
@@ -1,17 +1,14 @@
import { cloneElement, isValidElement, type ReactElement, type ReactNode } from 'react'
import { renderToStaticMarkup } from 'react-dom/server'
-import { beforeEach, describe, expect, it, vi } from 'vitest'
+import { describe, expect, it, vi } from 'vitest'
import type { BrowserTab as BrowserTabState } from '../../../../shared/browser-workspace-types'
import type { TerminalTab } from '../../../../shared/terminal-tab-types'
-import type { TuiAgent } from '../../../../shared/tui-agent'
import type { OpenFile } from '../../store/slices/editor'
import type { TabDragItemData } from '../tab-group/useTabDragSplit'
import BrowserTab from './BrowserTab'
import EditorFileTab from './EditorFileTab'
import SortableTab from './SortableTab'
-let mockTabAgent: TuiAgent | null = null
-
vi.mock('@dnd-kit/sortable', () => ({
useSortable: ({ id }: { id: string }) => ({
attributes: {
@@ -97,10 +94,6 @@ vi.mock('../../../../shared/agent-title-decoration', () => ({
title.replace(/^(?:[✳✦⏲◇✋⠀-⣿]+|[.*]\s)\s*/, '').trimStart() || title
}))
-vi.mock('@/lib/use-tab-agent', () => ({
- useTabAgent: () => mockTabAgent
-}))
-
vi.mock('../../store', () => ({
useAppStore: (selector: (state: { unreadTerminalTabs: Record }) => unknown) =>
selector({ unreadTerminalTabs: {} })
@@ -251,14 +244,11 @@ function makeEditorFile(overrides: Partial = {}):
}
describe('tab title tooltips', () => {
- beforeEach(() => {
- mockTabAgent = null
- })
-
it('uses the terminal custom title for the visible label and tooltip trigger content', () => {
const markup = renderToStaticMarkup(
{
})
it("shows the provider icon while stripping the agent's leading status glyph from the label", () => {
- mockTabAgent = 'claude'
const markup = renderToStaticMarkup(
state.tabsByWorktree[WORKTREE_ID]?.[0]) as TerminalTab