fix(desktop): stop hoisting an @ ref that is already inline in the prose

displayContentForMessage re-derived every ref from the attached context
block and re-emitted it as a detached list above the text. Now that the
token survives expansion, that list duplicated the inline chip. Hoist
only the refs the prose is missing, so turns persisted by an older
backend still render their chips.
This commit is contained in:
Brooklyn Nicholson 2026-07-27 22:55:24 -05:00
parent 045811f5be
commit 73f8ddbb8b
2 changed files with 19 additions and 1 deletions

View file

@ -220,6 +220,19 @@ describe('toChatMessages', () => {
expect(chatMessageText(message)).toBe('@file:foo.ts\n\nlook')
})
it('leaves an inline @ ref in place instead of hoisting a duplicate', () => {
const [message] = toChatMessages([
{
role: 'user',
content:
'summarize @file:`src/main.ts` for me\n\n--- Attached Context ---\n\n📄 @file:`src/main.ts` (10 tokens)\n```ts\nconst x = 1\n```',
timestamp: 1
}
])
expect(chatMessageText(message)).toBe('summarize @file:`src/main.ts` for me')
})
it('projects durable timeline kinds without inspecting their text', () => {
const messages = toChatMessages([
{ role: 'user', content: 'real user turn', timestamp: 1 },

View file

@ -311,7 +311,12 @@ function displayContentForMessage(role: SessionMessage['role'], content: unknown
const attachedContext = textContent.slice(marker.index + marker[0].length)
const refs = [...new Set(Array.from(attachedContext.matchAll(CONTEXT_REF_RE)).map(match => match[0]))]
return [refs.join('\n'), visibleText].filter(Boolean).join('\n\n') || visibleText
// The prose keeps the `@file:` token the user typed, so it already chips in
// place. Only hoist a ref the prose is missing — a turn persisted by an older
// backend that stripped the tokens. Re-listing an inline ref would chip twice.
const missing = refs.filter(ref => !visibleText.includes(ref))
return [missing.join('\n'), visibleText].filter(Boolean).join('\n\n') || visibleText
}
function transcriptContent(displayKind: SessionMessage['display_kind'], content: string): string | null {