fix(desktop): keep a bare URL's full text visible in chat markdown (#121007)

MarkdownLink nulled fallbackLabel whenever the link text matched the target
URL — exactly the bare-autolink case — so PrettyLink fell through to
urlSlugTitleLabel and rendered a host-only label (`ncpssd.org` for
https://www.ncpssd.org/), with the address readable only via hover/inspect.
The user could not read an address sent in chat.

The link's own text is always a legitimate fallback label; pass it through.
Labeled links are unchanged: their authored label already wins display, and
that shape (a label hiding the address) is PrettyLink's documented contract,
not a bug.

Salvaged from PR #38213 by Phantomthedog (the fallbackLabel change and the
localhost/example.com render tests), reworked to keep the change scoped to
the bare-autolink shape and reshaped into an end-to-end
MarkdownTextContent test alongside the existing session/filelinks suites.
This commit is contained in:
Phantomthedog
2026-09-24 18:59:40 -05:00
committed by brooklyn!
parent 71b79122ca
commit d38d2a8f0a
2 changed files with 48 additions and 1 deletions

View File

@@ -0,0 +1,40 @@
import { cleanup, render, screen } from '@testing-library/react'
import { afterEach, describe, expect, it } from 'vitest'
import { MarkdownTextContent } from './markdown-text'
afterEach(() => cleanup())
// End-to-end for the bare-autolink shape of #121007: a bare URL an agent sent
// must render with its full text visible — PrettyLink used to collapse it to a
// host-only label (`ncpssd.org`) with the address readable only via hover.
// Labeled links keep their authored label (that hiding is intended design).
describe('MarkdownTextContent bare URLs', () => {
it('shows the full URL text for a bare autolink', () => {
render(<MarkdownTextContent isRunning={false} text="See https://www.ncpssd.org/ for the database." />)
const link = screen.getByRole('link') as HTMLAnchorElement
expect(link.getAttribute('href')).toBe('https://www.ncpssd.org/')
expect(link.textContent).toContain('https://www.ncpssd.org/')
})
it('does not collapse a host-only URL to a bare hostname', () => {
render(<MarkdownTextContent isRunning={false} text="Docs live at https://example.com/ now." />)
const link = screen.getByRole('link') as HTMLAnchorElement
// urlSlugTitleLabel would render `example.com`; the full URL is the label.
expect(link.textContent).toContain('https://example.com/')
})
it('keeps the authored label for a labeled markdown link', () => {
render(<MarkdownTextContent isRunning={false} text="See [the database](https://www.ncpssd.org/) first." />)
const link = screen.getByRole('link') as HTMLAnchorElement
expect(link.getAttribute('href')).toBe('https://www.ncpssd.org/')
expect(link.textContent).toContain('the database')
expect(link.textContent).not.toContain('ncpssd.org/')
})
})

View File

@@ -345,7 +345,14 @@ function MarkdownLink({ children, className, href, ...props }: ComponentProps<'a
}
}
const fallbackLabel = text && normalizeExternalUrl(text) !== target ? text : undefined
// Always pass the link's own text as the fallback label so a bare URL stays
// fully visible (#121007): previously this was `undefined` when the child
// text matched the target URL (the bare-autolink case), so PrettyLink fell
// through to urlSlugTitleLabel — a host-only label like `ncpssd.org` with
// the address readable only via hover/inspect. The full URL is the label the
// sender actually wrote into the chat. Labeled links are unchanged: their
// authored label already wins display by design.
const fallbackLabel = text || undefined
return (
<PrettyLink className={cn('wrap-anywhere', className)} fallbackLabel={fallbackLabel} href={target} {...props} />