Skip to content

fix(desktop): snap caret out of agent mention chips#2712

Open
marcoleejr wants to merge 2 commits into
block:mainfrom
marcoleejr:fix/agent-mention-caret-snap
Open

fix(desktop): snap caret out of agent mention chips#2712
marcoleejr wants to merge 2 commits into
block:mainfrom
marcoleejr:fix/agent-mention-caret-snap

Conversation

@marcoleejr

@marcoleejr marcoleejr commented Jul 24, 2026

Copy link
Copy Markdown

Summary

Fixes #2707.

With Keep addressed agents active (persistent auto-tag), the composer re-inserts @AgentName after each send. Agent mentions are decorations on plain text, not atom nodes, and the leading @ is rendered at width: 0. A click that looks like the start of the chip often lands inside the display name; the next keystrokes (or Backspace/Delete) mutate that name, the decoration dies, and the agent is no longer tagged.

This PR treats agent chips as non-editable caret space and atomic units:

  1. snapCaretOutOfAgentMention — if the empty caret is strictly inside @Name, move it just after the mention (consuming the trailing space hydration always inserts).
  2. appendTransaction — apply that snap after selection changes (clicks, arrows).
  3. handleTextInput — if input would land inside a chip, insert after the chip instead of corrupting the name.
  4. handleKeyDown (Backspace/Delete) — remove the whole chip (@Name + trailing space) instead of nibbling letters:
    • interior caret → either key deletes the chip
    • Backspace at end of name or just after trailing space → chip
    • Delete at start of chip (before @) → chip

Edge positions for typing stay put (before @ for normal Backspace into prior text when not using atomic delete rules above; after-name typing still works). Human-only mentions are unchanged.

How it was implemented

  • Pure helpers in mentionHighlightExtension.ts (findAgentMentionRanges, snapCaretOutOfAgentMention, withTrailingSpace, agentMentionChipDeleteRange) so the policy is unit-testable without the full editor.
  • Wired into the existing TipTap plugin that already owns agent decoration ranges — single source of truth for “what is an agent chip”.

Test plan

  • Unit tests for range finding + caret snap (interior → after trailing space; edges untouched; multi-agent; empty agent list)
  • Unit tests for atomic Backspace/Delete (interior, end/after-space, Delete-at-start, two chips, no trailing space)
  • node --test src/features/messages/lib/mentionHighlightExtension.test.mjs — 35/35 pass
  • Manual (desktop): enable keep-addressed-agents, @ an agent in a thread, send a few messages, click the chip / place caret mid-name, type — text should land after the chip; Backspace/Delete on the chip should remove it whole; the tag should remain intact when typing after it

Notes

Out of scope: turning mentions into real atom nodes (larger rewrite). This is the minimal fix for the auto-tag breakage path reported in #2707.

@marcoleejr
marcoleejr requested a review from a team as a code owner July 24, 2026 12:00
Agent mentions in the composer are decorations over plain text, not atom
nodes, and the leading @ is width:0. With persistent auto-tag, clicks that
look like the start of a chip often land inside the display name; typing
then mutates the name and drops the decoration so the agent stops being
tagged.

Snap an empty caret out of the interior of agent mentions (after the
trailing space hydration inserts), and rewrite text input that would land
inside a chip so it inserts after the chip instead.

Fixes block#2707

Signed-off-by: Marco Lee <mv.lee18@gmail.com>
@marcoleejr
marcoleejr force-pushed the fix/agent-mention-caret-snap branch from d87653c to 0b51196 Compare July 25, 2026 06:07
Backspace/Delete inside (or at the edges of) a persistent agent chip no
longer nibbles the display name character-by-character — that killed the
decoration and broke auto-tag the same way mid-chip typing did.

- Interior caret: either key removes `@Name` + trailing space
- Backspace at end of name or just after the trailing space: whole chip
- Delete at the start of the chip (before `@`): whole chip

Follow-up to the caret-snap work for block#2707.

Signed-off-by: Marco Lee <mv.lee18@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] when using auto-tag agent, the cursor often slips back into the agents name, and typing breaks it

1 participant