Conversation
`@` opened the mention menu only at the start of the input or after a space, so `我想@张三` or `fix this bug@alpha` opened nothing. `@` now opens wherever it is typed. `$`, `/` and `、` keep the word-boundary guard so code and paths stay plain text. A glued `@` followed by a domain shape (`gabi@example.com`) is an email address, not a mention attempt, so the menu closes instead of matching the domain against skills, files, or sessions. A standalone `@README.md` remains a file mention. `isTriggerGluedToWord` and `looksLikeEmailAddress` in mention-trigger.ts own both shapes. Refs LodyAI#1152 Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Author
|
这个改动虽然是个人的一个习惯之举,但我觉得从产品的角度来看,这是一个可以优化的小需求,就斗胆pr了,希望咱们团队负责产品优化的伙伴可以看看~ |
Gabyran
marked this pull request as ready for review
September 30, 2026 08:05
Lampese
self-requested a review
September 30, 2026 08:23
Lampese
requested changes
Sep 30, 2026
| triggerIndex: number, | ||
| search: string | ||
| ): boolean { | ||
| return isTriggerGluedToWord(value, triggerIndex) && DOMAIN_QUERY_RE.test(search); |
Contributor
There was a problem hiding this comment.
好像这里的邮箱正则会拦截所有“紧贴前文且包含点号”的 @ 查询,而不只是邮箱
比如:
- 请@README.md
- 我想@GPT-5.6-Code-Reviewer
这些情况都会命中 DOMAIN_QUERY_RE,随后 onMentionUpdate 就直接 continue 了,菜单不会打开
The email check closed the menu for any `@` glued to the preceding text whose query had a dot, so `请@README.md` and `我想@GPT-5.6-Code-Reviewer` never opened. Glued-after-CJK is the main case this feature exists for. An address now needs both an ASCII local part right against the `@` and a domain ending in an alphabetic TLD. CJK before the trigger, or a dotted name whose last label is not letters-only, keeps the menu open. Refs LodyAI#1152 Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The address check only matched a finished domain, so typing `gabi@example.com.cn` reopened the menu at `example.`, `example.c`, `example.com.` and `example.com.c` before closing again. Close from the first dot once the local part is ASCII: the domain regex now accepts an empty or partial letters-only tail. CJK before the trigger and names whose last label is not letters-only still keep the menu open. Refs LodyAI#1152 Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Gabyran
marked this pull request as draft
September 30, 2026 09:34
Escape closed the menu, but the next keystroke reopened it, so a user had no way to say "plain text here" when the email heuristic or any other guess got it wrong. Escape now records the trigger it dismissed. Typing on after it keeps the menu closed; text inserted before it shifts the record by the same rule mention ranges use (`remapDismissedTrigger`). Deleting the trigger, clearing the input, or typing a new trigger opens the menu again. Refs LodyAI#1152 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…h word-guard docs
Gabyran
marked this pull request as ready for review
October 1, 2026 04:04
Author
|
进行了一些改动,但由于其中逻辑确实复杂,也不确定自己是否解决了所有场景。附上更新后的对话链接:https://share.lody.ai/s/r173jnvz23xfcqx3nmsayjme5s8fdyby#access=v1.0e92410c5703b8ca354ff8aede6858bf42fc8cd288cdad70443d8384031fef7c 祝节日快乐! |
Contributor
同乐!我觉得这个改动其实挺需要斟酌的,倒不是技术的问题,我也去调研了一下几个常见的产品,发到这里供参考:
因此这个问题我觉得可以先暂时挂起一下,我们也考虑一下有没有更好的解决方案 |
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Related issue
Closes #1152
Problem / pressure
@opens the composer's mention menu only at the start of the input or after a space or newline. In scripts written without spaces (Chinese, Japanese), or when English or code is mixed into a sentence,我想@张三andfix this bug@alphaopen nothing, so the user has to stop and insert a space before@.Simply dropping the boundary guard has a cost: an email address being typed (
gabi@example.com) would be matched against skills, files, and sessions by its domain. Detecting addresses must not swallow real mentions, though:请@README.mdand我想@GPT-5.6-Code-Reviewerare mentions glued to CJK text, the very case this change is for.Summary
@no longer needs a word boundary before it inMentionInput's trigger detection.$,/and、keep the guard, soprice$100,${x}andsrc/foostay plain text.gabi@example.,gabi@example.com.,gabi@example.com.cn), so it neither matches items nor reopens mid-address. It needs both an ASCII local part right against the@and dotted domain labels ending in a letters-only tail. CJK before the@(请@README.md), a standalone@README.mdoropen @package.json, a path (bug@src/a.b) and a name whose last label is not letters-only (bug@GPT-5.6-Code-Reviewer) keep the menu open. A partialuser@examplealso keeps it open because there is no dot yet and it is still ambiguous.@keeps the menu closed; text inserted before it shifts the record by the same rule mention ranges use (remapDismissedTriggerinmention-input-core.ts). Deleting the trigger, clearing the input, or typing a new trigger opens the menu again. This is the fallback for anything the email heuristic gets wrong.mention-trigger.tsowns both shapes throughisTriggerGluedToWord(the$guard, replacing three inline lines) andlooksLikeEmailAddress.mention-input-trigger.test.tsx(26 tests) and aremapDismissedTriggercase inmention-input-core.test.tsdrives the realMentionInputand asserts the open/closed state.Open questions for maintainers
ui/mention/AGENTS.mddescribes the mention package as a product-neutral primitive, but this PR hard-codestrigger === '@'and an email heuristic in it. The existingtrigger === '#'special case is precedent, though no production composer uses#(the composer configures@,$,/,、). The alternative is a per-trigger predicate onMentionRoot, for exampleshouldOpen?: ({ trigger, value, triggerIndex, query }) => boolean, defaulting to today's word-boundary guard, with the composer supplying the@rule and the email heuristic living undercomponents/mentions/. That removes'@'and email knowledge from the primitive at the cost of one more prop and a stable-identity requirement for the callback. I kept this PR minimal so you can pick before more code is written.user@gmailhas the menu open and Enter selects the highlighted item; it closes atgmail.and stays closed.bug@readme.md(English word, then a dotted name) is indistinguishable from an address, so it closes; typing a space first opens the file menu.bug@GPT-5.6-Code-Reviewer(ASCII word glued to a dotted role name) closes atGPT-5.and reopens atGPT-5.6, one flicker; with CJK before the@it stays open throughout.git@github.com:org/repo.gitis not a pure domain, so the menu re-opens after the colon.AGENTS.md, since that needs maintainer approval.Visual explanation
Trigger decision for each candidate trigger in
onMentionUpdate(new nodes marked with*):flowchart TD A[candidate trigger at index i] --> S{"dismissed by Escape?*"} S -- yes --> X[skip candidate] S -- no --> B{trigger is # or @?} B -- yes --> D B -- no --> C{"isTriggerGluedToWord(value, i)*"} C -- yes, e.g. price$100 --> X C -- no --> D{"trigger is @ and looksLikeEmailAddress(value, i, query)*<br/>ASCII local part + dotted labels, letters-only tail"} D -- yes, e.g. gabi@example. --> X D -- no --> E[existing checks: whitespace in query, interfering text] E --> F[open menu]Before / after
我想@opens nothing; a space is required first.我想@opens the mention menu.fix this bug@alphaopens nothing.alpha.gabi@example.comopens nothing..com.cn.@README.mdopens the file menu.请@README.mdopens nothing.我想@GPT-5.6-Code-Revieweropens nothing.price$100stays plain text.user@gm, Escape, keep typingail: the menu reopens on the next key.@; a new@or retyping it opens again.Test plan
npx vitest run tests/mention-input-trigger.test.tsx tests/mention-input-core.test.ts: 26 + 13 passed. The cases added for review feedback fail against the previous commit and pass now, and the keystroke-by-keystrokegabi@example.com.cntest fails against the version that reopened the menu atexample.andexample.com..npx vitest run tests/mention: 16 files, 231 tests passed. The two "stays closed after Escape" cases fail with the previousmention-input.tsx; the three "opens again" cases guard against over-dismissal and pass on both.combined-mention-textarea-activation,path-mention-insert,session-mention-insert,issue-pr-mention-freshness,agent-role-mention-source): 49 passed.packages/components:npm run typecheck(tsgo) clean.oxlint --type-awareonsrc/ui/mention: 28 warnings, identical tomain, no new ones.oxfmt --checkon the three changed files: clean, except the untouchedfindTriggerCandidatestrailing comma that already fails onmain; I left that line as is to keep the diff focused.packages/componentssuite (npx vitest run): 541 files, 4584 tests passed.pnpm check(full CI), and no manual test with a native Chinese IME. IME composition is guarded by the existingisComposingRefearly return, which this change does not touch.Context handoff
Original user prompt
Show original prompt
Shared conversation
Status: shared
Link: https://share.lody.ai/s/r173jnvz23xfcqx3nmsayjme5s8fdyby#access=v1.0e92410c5703b8ca354ff8aede6858bf42fc8cd288cdad70443d8384031fef7c
Additional link (review session of the same change): https://share.lody.ai/s/r17eggz7pjzaz9thh56bc31mg98fdk3n#access=v1.65e633f43f6f9378004ce3efa67aa0a6142906858b5d423204499745a3440aba
🤖 Generated with Claude Code