feat(web): FUE + composer hint for session @-mentions (#1274)

* feat(web): FUE + placeholder for rich composer session @-mentions

Discover session @-mentions via composer-grounded FUE and always-on
placeholder copy when rich composer is active (#1273).

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(web): notify onFocus after programmatic rich-composer autofocus

Playwright headless (and some engines) skip the DOM focus event for
element.focus(), so FUE engage never ran. Call the onFocus prop after
autofocus so discovery still works.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(web): engage rich-composer FUE on mount

DOM focus events are unreliable for programmatic autofocus (and in
Playwright). Treat the live rich composer as the affordance and open
the callout when the rich path mounts.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(web): measure FueCallout height; ellipsis rich placeholder

Bot review on #1274: position from real panel height (ResizeObserver)
so multi-line FUE bodies clear the composer, and keep long mention
placeholders on one ellipsized line in the input row.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(web): Escape dismisses rich-composer FUE; keep expand flex chain

Escape while the mention FUE is engaging only dismisses the callout
(no abort/collapse). FUE anchor is a flex container so expanded
RichComposerInput still fills height. Mock resolveComposerPlaceholderKey
in sendError tests.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
HeavyGee
2026-08-04 11:18:21 +08:00
committed by GitHub
co-authored by Cursor
parent a0c676818f
commit f6da005b50
9 changed files with 176 additions and 28 deletions
@@ -83,7 +83,11 @@ vi.mock('@assistant-ui/react', async () => {
}
})
vi.mock('@/lib/composerSegments', () => ({ isRichComposerMentionsEnabled: () => false }))
vi.mock('@/lib/composerSegments', () => ({
isRichComposerMentionsEnabled: () => false,
resolveComposerPlaceholderKey: ({ showContinueHint }: { showContinueHint: boolean }) =>
showContinueHint ? 'misc.typeMessage' : 'misc.typeAMessage',
}))
vi.mock('@/hooks/useComposerDraft', () => ({
useComposerDraft: (sessionId: string | undefined) => ({ sessionId, complete: true, restoredAny: false }),
}))