Show an @ mention picker in the Chat composer #240
- LA
Closes #239
## What changes
Typing `@` at a word boundary in the Chat composer opens a compact list above it: the Planner (`chopin`) first, then people present in the document, then people who have posted in this Chat, deduplicated case-insensitively, current user excluded. Rows are a 20px avatar (the Planner mark for `chopin`) and the login, in the `chrome` type role; the list shows at most 8 rows and scrolls, and never exceeds the composer width.
- **Keyboard:** ↑/↓ move, Enter or Tab insert `@login ` and close, Esc dismisses and keeps the typed text, IME composition never selects. - **Trigger:** same boundary rule as `addressed()`, so `a@b.com` never opens the list; no matches closes the list (no empty row); the caret must be at the end of the login. - **Avatars:** `https://github.com/<login>.png?size=40`, `alt=""`, falling back to the login's initial on a `selected` tile. - **Semantics:** the textarea is a `combobox` with `aria-activedescendant` onto a `listbox` named "Mentions". Only one picker is open at a time; the `#` reference picker is untouched and wins if both could apply. - **Unchanged:** routing. Only `@chopin` starts a Planner turn (`packages/protocol/address.ts`); mentioning a person is text only, with no server, notification or protocol change. The transcript already renders mentions without the `@`, so it needed no change. With `agent` off the Planner row is omitted.
The composer is now always a `combobox` (the `@` list needs no server support), so the "server without chat references" e2e now expects `combobox` and scopes its "no listbox" check to the document-reference list.
## Verification
- `bun test`: 1817 pass, 0 fail. New `apps/web/src/chat/mentions.test.ts` covers trigger detection (including `a@b.com` and agreement with `addressed()`), ordering, dedupe, filtering, insertion and keyboard. - `bun run types`: all 9 checks exit 0. `bun run ci`: passes. - `bun run e2e`: full suite 291 passed / 4 failed on first run. Three were from this change (a test of mine, the capability-fallback test above, and an sr-only hint I then removed) and pass after fixing. `sidecar.e2e.ts:551` ("decision cards save independently with progressive custom answers") fails identically on `origin/main` with this change stashed; unrelated. - New `e2e/chat-mentions.e2e.ts` covers open → navigate → filter → select → send at desktop (payload `to: "planner"` only for `@chopin`, `"room"` for a person) and a 390px Chat panel (inside the viewport and the panel, no horizontal overflow). - Visual check used the repo's Playwright harness (fake GitHub, three real sessions) rather than agent-browser, because that harness already provides authenticated multi-user rooms.
## Screenshots
Before (typing `@`, nothing happens) and after, desktop and 390px wide:





lavaman131assigned lavaman131last month on GitHub
- MA
Reviewed mention triggering, ordering and deduplication, filtering, insertion, keyboard/IME behavior, reference-picker priority, and unchanged message routing. Only @chopin starts a Planner turn; person mentions remain text without notifications. No blocking issues found.
Reran mention and chat-reference tests: 43 passed, 0 failed. Desktop and narrow-panel browser coverage is included; validation, browser integration, and container CI all pass.
MaggieAppletonhead-ref-force-pushed ce05576637f4last month on GitHub
MaggieAppletonmerged 3e57e40ea6dalast month on GitHub
MaggieAppletonhead-ref-deletedlast month on GitHub