diff --git a/src/renderer/src/components/tab-bar/TabBarCreateEntryRow.test.tsx b/src/renderer/src/components/tab-bar/TabBarCreateEntryRow.test.tsx index b56930f9029..f8801ae6122 100644 --- a/src/renderer/src/components/tab-bar/TabBarCreateEntryRow.test.tsx +++ b/src/renderer/src/components/tab-bar/TabBarCreateEntryRow.test.tsx @@ -147,6 +147,8 @@ describe('EntryActionRow', () => { }) expect(container.querySelector('[data-agent-icon]')).toBeNull() + // Guard against the row rendering no icon at all, which "no agent icon" alone would pass. + expect(container.querySelector('svg.lucide-square-terminal')).toBeTruthy() expect(container.textContent).toContain('Switch to tab') }) }) diff --git a/src/renderer/src/lib/open-tab-occupant-agent.test.ts b/src/renderer/src/lib/open-tab-occupant-agent.test.ts index f5d524f8b10..85ab0f4cb49 100644 --- a/src/renderer/src/lib/open-tab-occupant-agent.test.ts +++ b/src/renderer/src/lib/open-tab-occupant-agent.test.ts @@ -111,7 +111,6 @@ describe('resolveOpenTabOccupantAgent', () => { }) it('uses the tab-strip title identity when hooks have not reported yet', () => { - expect(resolve({ recordTitle: 'grok' })).toBe('grok') expect(resolve({ title: 'grok' })).toBe('grok') }) @@ -119,14 +118,13 @@ describe('resolveOpenTabOccupantAgent', () => { expect( resolve({ launchAgent: 'claude', - recordTitle: 'fix grok parser', title: 'fix grok parser' }) ).toBe('claude') }) it('does not treat a hyphenated grok mention as occupancy', () => { - expect(resolve({ recordTitle: 'session-scanner-grok-parser' })).toBeNull() + expect(resolve({ title: 'session-scanner-grok-parser' })).toBeNull() }) it('uses the focused sleeping session, matching useTabAgent', () => { diff --git a/src/renderer/src/lib/open-tab-occupant-agent.ts b/src/renderer/src/lib/open-tab-occupant-agent.ts index 6a4562ba55c..40d4f0df74e 100644 --- a/src/renderer/src/lib/open-tab-occupant-agent.ts +++ b/src/renderer/src/lib/open-tab-occupant-agent.ts @@ -18,10 +18,12 @@ import { resolveTabAgentFromSignals } from './use-tab-agent' export type OpenTabOccupantAgentInput = { tabId: string - /** Visible search/tab-strip label. Used only when the terminal record title is empty. */ + /** + * Resolved unified tab label — the same string the tab strip feeds `useTabAgent`. + * The terminal record's own title is not used: it can stay a stale "Terminal N" + * while the unified label already carries the live OSC title. + */ title?: string - /** OSC title `useTabAgent` reads. */ - recordTitle?: string defaultTitle?: string launchAgent?: TuiAgent layout?: TerminalLayoutSnapshot @@ -38,7 +40,6 @@ export type OpenTabOccupantAgentInput = { export function resolveOpenTabOccupantAgent({ tabId, title, - recordTitle, defaultTitle, launchAgent, layout, @@ -61,7 +62,7 @@ export function resolveOpenTabOccupantAgent({ const sleepingSessionAgent = focusedPaneKey ? (sleepingAgentSessionsByPaneKey[focusedPaneKey]?.agent ?? null) : null - const oscTitle = recordTitle?.trim() || title?.trim() || '' + const oscTitle = title?.trim() || '' const explicitTitleAgent = resolveExplicitTerminalTitleAgentType(oscTitle) const fallbackAgentSignal = launchAgent ? explicitTitleAgent === launchAgent diff --git a/src/renderer/src/lib/workspace-tab-palette-search.test.ts b/src/renderer/src/lib/workspace-tab-palette-search.test.ts index 68053539caa..7570213dd6a 100644 --- a/src/renderer/src/lib/workspace-tab-palette-search.test.ts +++ b/src/renderer/src/lib/workspace-tab-palette-search.test.ts @@ -569,6 +569,15 @@ describe('workspace-tab-palette-search', () => { expect(searchWorkspaceTabs(titledOnly, 'grok')[0]?.occupantAgent).toBe('grok') }) + it('stamps occupancy from the live unified label when the terminal record title is stale', () => { + const staleRecord = buildEntries({ + tabsByWorktree: { 'wt-1': [makeTerminalTab({ title: 'Terminal 1' })] }, + unifiedTabsByWorktree: { 'wt-1': [makeUnifiedTab({ label: 'grok' })] } + }) + expect(staleRecord[0]?.title).toBe('grok') + expect(staleRecord[0]?.occupantAgent).toBe('grok') + }) + it('does not stamp grok occupancy from a hyphenated filename-style title', () => { const hyphenated = buildEntries({ tabsByWorktree: { 'wt-1': [makeTerminalTab({ title: 'session-scanner-grok-parser' })] }, diff --git a/src/renderer/src/lib/workspace-tab-palette-search.ts b/src/renderer/src/lib/workspace-tab-palette-search.ts index 85ec837a2ed..b35e1154b23 100644 --- a/src/renderer/src/lib/workspace-tab-palette-search.ts +++ b/src/renderer/src/lib/workspace-tab-palette-search.ts @@ -275,8 +275,8 @@ export function buildSearchableWorkspaceTabs({ agentMetadata: collectAgentMetadataFromIndex(agentIndex, tab.entityId, worktree.id), occupantAgent: resolveOpenTabOccupantAgent({ tabId: tab.entityId, + // The unified label, not terminalTab.title: the record can lag it (see above). title, - recordTitle: terminalTab?.title, defaultTitle: terminalTab?.defaultTitle, launchAgent: terminalTab?.launchAgent, layout: terminalLayoutsByTabId?.[tab.entityId],