diff --git a/client/src/components/Chat/Messages/Content/Parts/__tests__/AuthorHeader.spec.tsx b/client/src/components/Chat/Messages/Content/Parts/__tests__/AuthorHeader.spec.tsx
new file mode 100644
index 0000000000..066f6d253f
--- /dev/null
+++ b/client/src/components/Chat/Messages/Content/Parts/__tests__/AuthorHeader.spec.tsx
@@ -0,0 +1,29 @@
+import { render, screen } from '@testing-library/react';
+import AuthorHeader from '../AuthorHeader';
+
+const renderHeader = () =>
+ render(
} label="GitHub Agent" />);
+
+describe('AuthorHeader', () => {
+ it('restates the author with an icon and a heading', () => {
+ renderHeader();
+
+ expect(screen.getByTestId('author-icon')).toBeInTheDocument();
+ expect(screen.getByRole('heading', { name: 'GitHub Agent' })).toBeVisible();
+ });
+
+ it('only outdents past the avatar gutter where that gutter exists', () => {
+ renderHeader();
+
+ const header = screen.getByTestId('author-header');
+
+ expect(header).toHaveClass('w-full', 'md:-ml-9', 'md:w-[calc(100%+2.25rem)]');
+ expect(header).not.toHaveClass('-ml-9');
+ });
+
+ it('keeps the icon out of the accessible name', () => {
+ renderHeader();
+
+ expect(screen.getByTestId('author-icon').closest('[aria-hidden="true"]')).not.toBeNull();
+ });
+});
diff --git a/client/src/components/Chat/Messages/Content/Parts/__tests__/SteerPart.test.tsx b/client/src/components/Chat/Messages/Content/Parts/__tests__/SteerPart.test.tsx
index 94d16b098e..bd67cbd2d4 100644
--- a/client/src/components/Chat/Messages/Content/Parts/__tests__/SteerPart.test.tsx
+++ b/client/src/components/Chat/Messages/Content/Parts/__tests__/SteerPart.test.tsx
@@ -142,6 +142,13 @@ describe('SteerPart presentation', () => {
expect(part).toHaveClass('steer-render');
});
+ it('only outdents past the avatar gutter where that gutter exists', () => {
+ renderPart();
+ const part = screen.getByTestId('steer-part');
+ expect(part).toHaveClass('w-full', 'md:-ml-9', 'md:w-[calc(100%+2.25rem)]');
+ expect(part).not.toHaveClass('-ml-9');
+ });
+
it('renders steer attachments', () => {
renderPart([
{ file_id: 'f1', filename: 'notes.pdf', type: 'application/pdf' },
diff --git a/client/src/components/Chat/Messages/ui/MessageRow.tsx b/client/src/components/Chat/Messages/ui/MessageRow.tsx
index 44b303a39c..9427258f3c 100644
--- a/client/src/components/Chat/Messages/ui/MessageRow.tsx
+++ b/client/src/components/Chat/Messages/ui/MessageRow.tsx
@@ -49,26 +49,16 @@ export default function MessageRow({
className={cn(
'message-render group mx-auto flex min-w-0 flex-1 font-theme-ui transition-[max-width] duration-theme-normal motion-reduce:transition-none',
'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-text-primary',
- isCreatedByUser ? 'justify-end' : 'items-start gap-3',
+ isCreatedByUser ? 'justify-end' : 'items-start',
widthClass,
className,
)}
>
- {showAssistantHeader && (
-
- )}
-
) : (
+
+ {icon}
+
{headerPrefix}
{label}
diff --git a/client/src/components/Chat/Messages/ui/__tests__/MessageRow.spec.tsx b/client/src/components/Chat/Messages/ui/__tests__/MessageRow.spec.tsx
index 5ac311f5b7..33b37a60af 100644
--- a/client/src/components/Chat/Messages/ui/__tests__/MessageRow.spec.tsx
+++ b/client/src/components/Chat/Messages/ui/__tests__/MessageRow.spec.tsx
@@ -62,6 +62,32 @@ describe('MessageRow', () => {
expect(screen.getByRole('heading', { name: /Assistant/ })).toBeVisible();
});
+ it('carries the assistant avatar inside the heading without naming it', () => {
+ renderRow({ isCreatedByUser: false });
+
+ const avatar = screen.getByTestId('message-icon').parentElement;
+
+ /** The accessible name resolves only when `aria-hidden` excludes the avatar. */
+ expect(screen.getByRole('heading', { name: 'Message from Assistant' })).toContainElement(
+ screen.getByTestId('message-icon'),
+ );
+ expect(avatar).toHaveAttribute('aria-hidden', 'true');
+ expect(avatar).toHaveClass('size-6', 'md:absolute', 'md:left-0', 'md:top-0.5');
+ });
+
+ it('reserves the avatar gutter on desktop only so mobile content starts flush left', () => {
+ renderRow({ isCreatedByUser: false });
+
+ const row = screen.getByLabelText('Assistant message');
+ const agentTurn = row.querySelector('.agent-turn');
+
+ expect(agentTurn).toHaveClass('md:pl-9');
+ expect(agentTurn).not.toHaveClass('pl-9');
+ expect(row).not.toHaveClass('gap-3');
+ expect(row.children).toHaveLength(1);
+ expect(screen.getAllByTestId('message-icon')).toHaveLength(1);
+ });
+
it('preserves the assistant turn marker for parallel content', () => {
renderRow({ isCreatedByUser: false, hasParallelContent: true });
@@ -89,7 +115,7 @@ describe('MessageRow', () => {
const row = screen.getByLabelText('Assistant message');
const messageSurface = screen.getByTestId('message-body');
- expect(row.querySelector('.agent-turn')).toHaveClass('w-full');
+ expect(row.querySelector('.agent-turn')).toHaveClass('w-full', 'md:pl-9');
expect(messageSurface).toHaveClass('w-full');
});