diff --git a/src/components/context-menu/context-menu-utils.ts b/src/components/context-menu/context-menu-utils.ts index 01fcacc9a..cfe093f3a 100644 --- a/src/components/context-menu/context-menu-utils.ts +++ b/src/components/context-menu/context-menu-utils.ts @@ -67,6 +67,10 @@ export function parseContextTarget(contextId: ContextId, data: ContextDataset): return data.tabId && data.paneId ? { kind: 'pane', tabId: data.tabId, paneId: data.paneId } : null + case ContextIds.PaneHeader: + return data.tabId && data.paneId + ? { kind: 'pane', tabId: data.tabId, paneId: data.paneId } + : null case ContextIds.PaneDivider: return data.tabId && data.splitId ? { kind: 'pane-divider', tabId: data.tabId, splitId: data.splitId } diff --git a/src/components/panes/PaneHeader.tsx b/src/components/panes/PaneHeader.tsx index 7e628281f..7f979e55f 100644 --- a/src/components/panes/PaneHeader.tsx +++ b/src/components/panes/PaneHeader.tsx @@ -126,6 +126,8 @@ export default function PaneHeader({ : isActive ? 'bg-muted' : 'bg-muted/50 text-muted-foreground' )} data-context={ContextIds.PaneHeader} + data-tab-id={tabId} + data-pane-id={paneId} onDoubleClick={isRenaming ? undefined : onDoubleClick} role="banner" aria-label={`Pane: ${title}`} diff --git a/test/unit/client/components/context-menu/context-menu-utils.test.ts b/test/unit/client/components/context-menu/context-menu-utils.test.ts index 955230047..9ca5409d0 100644 --- a/test/unit/client/components/context-menu/context-menu-utils.test.ts +++ b/test/unit/client/components/context-menu/context-menu-utils.test.ts @@ -54,6 +54,35 @@ describe('parseContextTarget', () => { expect(result).toEqual({ kind: 'tab', tabId: 'tab-1' }) }) + it('parseContextTarget for PaneHeader returns the exact pane target', () => { + const result = parseContextTarget(ContextIds.PaneHeader, { + tabId: 'tab-header', + paneId: 'pane-header', + }) + + expect(result).toEqual({ + kind: 'pane', + tabId: 'tab-header', + paneId: 'pane-header', + }) + }) + + it('parseContextTarget for PaneHeader returns null when tabId is missing', () => { + const result = parseContextTarget(ContextIds.PaneHeader, { + paneId: 'pane-header', + }) + + expect(result).toBeNull() + }) + + it('parseContextTarget for PaneHeader returns null when paneId is missing', () => { + const result = parseContextTarget(ContextIds.PaneHeader, { + tabId: 'tab-header', + }) + + expect(result).toBeNull() + }) + it('parseContextTarget for FreshAgent preserves pane and session flavor identity', () => { const result = parseContextTarget(ContextIds.FreshAgent, { tabId: 'tab-1', diff --git a/test/unit/client/components/panes/PaneHeader.test.tsx b/test/unit/client/components/panes/PaneHeader.test.tsx index cbb912c38..30ec2ff62 100644 --- a/test/unit/client/components/panes/PaneHeader.test.tsx +++ b/test/unit/client/components/panes/PaneHeader.test.tsx @@ -137,6 +137,25 @@ describe('PaneHeader', () => { expect(screen.getByText('My Terminal')).toBeInTheDocument() }) + it('renders its pane-header context marker and exact pane identity', () => { + render( + + ) + + const header = screen.getByRole('banner', { name: 'Pane: My Terminal' }) + expect(header).toHaveAttribute('data-context', 'pane-header') + expect(header).toHaveAttribute('data-tab-id', 'tab-header') + expect(header).toHaveAttribute('data-pane-id', 'pane-header') + }) + it('renders status indicator', () => { render(