fix(desktop): label a url chip with its host and path

The composer labeled a `@url:` chip with `refLabel`, which takes the last
path segment — three PR links all read as their number. The transcript had
its own better labeler that stopped at the hostname, so the same reference
read differently before and after send.

One `refChipLabel` now serves both: host without `www.`, path riding along
for the chip's existing truncate to cut, and the full value on the chip's
title so a cut-off link is still readable on hover.
This commit is contained in:
Brooklyn Nicholson 2026-07-26 15:23:35 -05:00
parent 59529afee0
commit ee09162e45
2 changed files with 18 additions and 16 deletions

View file

@ -11,11 +11,11 @@ import {
directiveIconElement,
directiveIconSvg,
formatRefValue,
refChipLabel,
slashChipClass,
type SlashChipKind,
slashIconElement
} from '@/components/assistant-ui/directive-text'
import { sessionRefFallbackLabel } from '@/lib/session-refs'
export const RICH_INPUT_SLOT = 'composer-rich-input'
@ -35,10 +35,6 @@ export function unquoteRef(raw: string) {
return quoted ? raw.slice(1, -1) : raw.replace(/[,.;!?]+$/, '')
}
export function refLabel(id: string) {
return id.split(/[\\/]/).filter(Boolean).pop() || id
}
/** Always-quote variant of formatRefValue — chips need a fence even for safe values. */
export function quoteRefValue(value: string) {
if (!value.includes('`')) {
@ -60,9 +56,9 @@ export function refChipHtml(kind: string, rawValue: string, displayLabel?: strin
const id = unquoteRef(rawValue)
const text = `@${kind}:${quoteRefValue(id)}`
const label = displayLabel || (kind === 'session' ? sessionRefFallbackLabel(id) : refLabel(id))
const label = displayLabel || refChipLabel(kind, id)
return `<span contenteditable="false" data-ref-text="${escapeHtml(text)}" data-ref-id="${escapeHtml(id)}" data-ref-kind="${escapeHtml(kind)}" class="${DIRECTIVE_CHIP_CLASS}">${directiveIconSvg(kind)}<span class="truncate">${escapeHtml(label)}</span></span>`
return `<span contenteditable="false" title="${escapeHtml(id)}" data-ref-text="${escapeHtml(text)}" data-ref-id="${escapeHtml(id)}" data-ref-kind="${escapeHtml(kind)}" class="${DIRECTIVE_CHIP_CLASS}">${directiveIconSvg(kind)}<span class="truncate">${escapeHtml(label)}</span></span>`
}
export function refChipElement(kind: string, rawValue: string, displayLabel?: string) {
@ -72,12 +68,13 @@ export function refChipElement(kind: string, rawValue: string, displayLabel?: st
const label = document.createElement('span')
chip.contentEditable = 'false'
chip.title = id
chip.dataset.refText = text
chip.dataset.refId = id
chip.dataset.refKind = kind
chip.className = DIRECTIVE_CHIP_CLASS
label.className = 'truncate'
label.textContent = displayLabel || (kind === 'session' ? sessionRefFallbackLabel(id) : refLabel(id))
label.textContent = displayLabel || refChipLabel(kind, id)
chip.append(directiveIconElement(kind), label)
return chip

View file

@ -277,7 +277,7 @@ function parseDirectiveText(text: string): Unstable_DirectiveSegment[] {
start: match.index ?? 0,
end: (match.index ?? 0) + match[0].length,
type: match[1] || 'file',
label: shortLabel(match[1] as HermesRefType, id),
label: refChipLabel(match[1] || 'file', id),
id
}
}),
@ -320,25 +320,30 @@ function parseDirectiveText(text: string): Unstable_DirectiveSegment[] {
return segments
}
function shortLabel(type: HermesRefType, id: string): string {
/** Display text for a `@kind:value` chip. Shared with the composer's
* contenteditable chips so a link reads the same before and after send: the
* host leads (scheme and `www.` are noise) and the path rides along for the
* chip's `truncate` to cut — a bare hostname can't tell two links apart. */
export function refChipLabel(type: string, id: string): string {
if (type === 'terminal') {
return id || 'terminal'
}
if (type === 'session') {
return sessionRefFallbackLabel(id)
}
if (type === 'url') {
try {
const parsed = new URL(id)
const { hostname, pathname, search } = new URL(id)
const path = `${pathname}${search}`.replace(/\/$/, '')
return parsed.hostname || id
return `${hostname.replace(/^www\./i, '')}${path}` || id
} catch {
return id
}
}
if (type === 'session') {
return sessionRefFallbackLabel(id)
}
const tail = id.split(/[\\/]/).filter(Boolean).pop()
return tail || id