Skip to content

fix(vscode): keep @ mention search open across spaces - #13592

Merged
marius-kilocode merged 11 commits into
Kilo-Org:mainfrom
sylwester-liljegren:fix/mention-query-spaces
Sep 4, 2026
Merged

fix(vscode): keep @ mention search open across spaces#13592
marius-kilocode merged 11 commits into
Kilo-Org:mainfrom
sylwester-liljegren:fix/mention-query-spaces

Conversation

@sylwester-liljegren

Copy link
Copy Markdown
Contributor

Issue

No existing issue found for this behavior (searched open issues for mention / mention space filename). Reported directly by a user of the VS Code extension.

Context

Typing @ in the chat input opens the mention list, but the first space closed it. The trigger pattern only matched a query of non-whitespace characters, so any file or folder whose name contains a space was unreachable through @ search — the user had to fall back to "Browse files...". Everything downstream of selection already supports spaced paths (syncMentionedPaths, buildFileAttachments, seedFromParts, mention span highlighting); only the trigger stopped early.

Implementation

AT_PATTERN now allows spaces in the in-progress query. Two boundaries keep that from being greedy in the wrong direction:

  • The query never spans a newline.
  • The query never spans a later @, so a second mention starts its own query instead of swallowing the first. An @ that is not preceded by whitespace stays inside the query, so scoped paths like @node_modules/@types/node still resolve.

Allowing spaces means ordinary prose typed after a completed mention (@README.md and then ...) also matches the trigger, which would leave the dropdown open and let it consume Enter via the always-present "Browse files..." fallback. Two guards in useFileMention prevent that:

  • When a file search for a spaced query comes back with no file/folder results, the dropdown closes and that query is remembered as dead for that @ offset, so continuing the sentence does not reopen it on every keystroke. Editing back to a query that can still match clears the flag, and switching session scope resets it.
  • Enter/Tab is not consumed when the highlighted entry is the file-picker fallback and the query contains whitespace, so sending the message wins over browsing files during the debounce window before the search resolves.

The dead-query heuristic is deliberately driven by search results rather than a synchronous local filter: the locally cached list is only the top slice for a shorter prefix, so closing on a local miss would break exactly the large-repo case this fix targets.

Screenshots / Video

N/A — no visual/layout change. The mention dropdown is the existing component; only when it stays open changed.

How to Test

Manual/local verification

Executed by the agent:

  • bun test tests/unit/file-mention-utils.test.ts tests/unit/use-file-mention.test.ts tests/unit/agent-manager-worktree-reference.test.ts tests/unit/prompt-input-utils.test.ts from packages/kilo-vscode/ — 209 pass, 0 fail. Covers the new cases: spaced query captured, second mention not swallowed, scoped @types path preserved, no newline spanning, dropdown stays open and renders a spaced-path result, dropdown closes and stays closed while prose is typed after a mention, Enter not consumed for a spaced query offering only the file picker.
  • bun run typecheck and bun run lint from packages/kilo-vscode/ — clean.
  • bun run format from packages/kilo-vscode/ — no changes.

Reviewer test steps

  1. Create a file with a space in its name, e.g. docs/my report.txt.
  2. In the Kilo chat input, type @my rep — the dropdown stays open and docs/my report.txt is offered; press Enter to insert it.
  3. Continue typing a sentence after the inserted mention (@docs/my report.txt please summarize this) — the dropdown closes once the search resolves and does not flicker back on later keystrokes; Enter sends the message.
  4. Type @node_modules/@types — scoped paths still resolve.
  5. Type @src/a.ts and @b — the second @ starts a fresh query and selecting a result does not overwrite the first mention.

Blocked checks and substitute verification

  • The full bun run test:unit suite from packages/kilo-vscode/ could not be used as a clean signal on this Windows machine: 91 tests fail on main-unrelated environment issues (POSIX path expectations such as /repo vs C:\repo, EPERM on symlink, missing echo/pwd, and esbuild-child timeouts). None of the failures are in mention code. Substitute verification was the targeted test files listed above plus package typecheck and lint.

Checklist

  • Issue linked above, or exception explained
  • Tests/verification described
  • Screenshots/video included for visual changes, or marked N/A
  • Changeset considered for user-facing changes
  • I personally reviewed the diff and can explain the changes, including any AI-assisted work.

Get in Touch

N/A

The mention trigger stopped at the first space, so files whose names contain spaces could not be found. Allow spaces in the in-progress query, bounded by newlines and by a later ' @' so a second mention starts its own query, and close the dropdown once a spaced query resolves to no matches so ordinary prose after a mention neither reopens it nor steals Enter.
@kilo-code-bot

kilo-code-bot Bot commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Files Reviewed (1 file)
  • packages/kilo-vscode/webview-ui/src/hooks/file-mention-utils.ts
Previous Review Summaries (9 snapshots, latest commit fccc74a)

Current summary above is authoritative. Previous snapshots are kept for context only.

Previous review (commit fccc74a)

Status: No Issues Found | Recommendation: Merge

Files Reviewed (6 files)
  • .changeset/mention-query-spaces.md
  • packages/kilo-vscode/tests/unit/file-mention-utils.test.ts
  • packages/kilo-vscode/tests/unit/use-file-mention.test.ts
  • packages/kilo-vscode/webview-ui/src/components/chat/PromptInput.tsx
  • packages/kilo-vscode/webview-ui/src/hooks/file-mention-utils.ts
  • packages/kilo-vscode/webview-ui/src/hooks/useFileMention.ts

Previous review (commit f9cc1ae)

Status: No Issues Found | Recommendation: Merge

Files Reviewed (5 files)
  • .changeset/mention-query-spaces.md
  • packages/kilo-vscode/tests/unit/file-mention-utils.test.ts
  • packages/kilo-vscode/tests/unit/use-file-mention.test.ts
  • packages/kilo-vscode/webview-ui/src/hooks/file-mention-utils.ts
  • packages/kilo-vscode/webview-ui/src/hooks/useFileMention.ts

Previous review (commit 673b5e9)

Status: No Issues Found | Recommendation: Merge

Files Reviewed (2 files)
  • packages/kilo-vscode/tests/unit/use-file-mention.test.ts
  • packages/kilo-vscode/webview-ui/src/hooks/useFileMention.ts

Previous review (commit 456676b)

Status: 1 Issue Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 1
SUGGESTION 0
Issue Details (click to expand)

WARNING

File Line Issue
packages/kilo-vscode/webview-ui/src/hooks/useFileMention.ts 322 Spaced chat-title search can close before sessions arrive
Files Reviewed (6 files)
  • .changeset/mention-query-spaces.md
  • packages/kilo-vscode/tests/unit/file-mention-utils.test.ts
  • packages/kilo-vscode/tests/unit/use-file-mention.test.ts
  • packages/kilo-vscode/webview-ui/src/components/chat/PromptInput.tsx
  • packages/kilo-vscode/webview-ui/src/hooks/file-mention-utils.ts
  • packages/kilo-vscode/webview-ui/src/hooks/useFileMention.ts - 1 issue

Fix these issues in Kilo Cloud

Previous review (commit 881d756)

Status: No Issues Found | Recommendation: Merge

Files Reviewed (4 files)
  • packages/kilo-vscode/tests/unit/file-mention-utils.test.ts
  • packages/kilo-vscode/tests/unit/use-file-mention.test.ts
  • packages/kilo-vscode/webview-ui/src/hooks/file-mention-utils.ts
  • packages/kilo-vscode/webview-ui/src/hooks/useFileMention.ts

Previous review (commit 916b94f)

Status: 1 Issue Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 1
SUGGESTION 0
Issue Details (click to expand)

WARNING

File Line Issue
packages/kilo-vscode/webview-ui/src/hooks/file-mention-utils.ts 161 mentionSettled closes spaced-filename search when a shorter known token is a prefix
Files Reviewed (6 files)
  • .changeset/mention-query-spaces.md
  • packages/kilo-vscode/tests/unit/file-mention-utils.test.ts
  • packages/kilo-vscode/tests/unit/session-provider-activity.test.ts
  • packages/kilo-vscode/tests/unit/use-file-mention.test.ts
  • packages/kilo-vscode/webview-ui/src/hooks/file-mention-utils.ts - 1 issue
  • packages/kilo-vscode/webview-ui/src/hooks/useFileMention.ts

Fix these issues in Kilo Cloud

Previous review (commit e4d321f)

Status: 1 Issue Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 1
SUGGESTION 0
Issue Details (click to expand)

WARNING

File Line Issue
packages/kilo-vscode/webview-ui/src/hooks/file-mention-utils.ts 161 mentionSettled closes spaced-filename search when a shorter known token is a prefix
Files Reviewed (4 files)
  • packages/kilo-vscode/tests/unit/file-mention-utils.test.ts
  • packages/kilo-vscode/tests/unit/use-file-mention.test.ts
  • packages/kilo-vscode/webview-ui/src/hooks/file-mention-utils.ts - 1 issue
  • packages/kilo-vscode/webview-ui/src/hooks/useFileMention.ts

Fix these issues in Kilo Cloud

Previous review (commit e4a3905)

Status: No Issues Found | Recommendation: Merge

Files Reviewed (4 files)
  • packages/kilo-vscode/tests/unit/file-mention-utils.test.ts
  • packages/kilo-vscode/tests/unit/use-file-mention.test.ts
  • packages/kilo-vscode/webview-ui/src/hooks/file-mention-utils.ts
  • packages/kilo-vscode/webview-ui/src/hooks/useFileMention.ts

Previous review (commit 6a224d2)

Status: No Issues Found | Recommendation: Merge

Files Reviewed (5 files)
  • .changeset/mention-query-spaces.md
  • packages/kilo-vscode/tests/unit/file-mention-utils.test.ts
  • packages/kilo-vscode/tests/unit/use-file-mention.test.ts
  • packages/kilo-vscode/webview-ui/src/hooks/file-mention-utils.ts
  • packages/kilo-vscode/webview-ui/src/hooks/useFileMention.ts

Reviewed by grok-4.6 · Input: 154.8K · Output: 16.8K · Cached: 595.5K

Review guidance: REVIEW.md from base branch main

@marius-kilocode

Copy link
Copy Markdown
Collaborator

Hi @sylwester-liljegren did you test this manually?

@sylwester-liljegren

Copy link
Copy Markdown
Contributor Author

Hi @marius-kilocode !

Yes, I have tested this myself and it works. The space key does not close the list of files anymore. The only way to close this is by clicking on Esc key AFAIK, but maybe we should add a cross somewhere in the mentions menu if it isn't obvious to the end-user. What is your opinion on this?

@marius-kilocode

Copy link
Copy Markdown
Collaborator
image Just tested it. This does seem to still trigger even after selection. Could you fine tune that a bit better so it's usable?

@sylwester-liljegren

Copy link
Copy Markdown
Contributor Author

@marius-kilocode , my goodness, it is worse than previously. Not sure if it is related to suggestions introduced by kilo-code-bot. But yeah, I'll definitely look into this. Thanks for catching up!

Allowing spaces in the query meant text typed after an inserted mention still matched the trigger, so the dropdown reopened and kept offering the already-selected file. Close it as soon as the query covers a complete mention token followed by whitespace, which is immediate and independent of what the pending file search returns. A query that is only a prefix of (or exactly) a known token still counts as editing that mention and stays open.
@sylwester-liljegren

Copy link
Copy Markdown
Contributor Author

Follow-up after testing: allowing spaces meant text typed after an already-inserted mention still matched the trigger, so the dropdown reopened and kept offering the file that had just been selected.

The dropdown now closes as soon as the query covers a complete mention token followed by whitespace (mentionSettled). That check is immediate and independent of what the pending file search returns, which is what the previous result-based heuristic got wrong. A query that is only a prefix of, or exactly equal to, a known token still counts as editing that mention and keeps the dropdown open, so deleting back into a mention behaves as before.

for (const token of [...tokens, TERMINAL_MENTION, GIT_CHANGES_MENTION]) {
if (query.length <= token.length) continue
if (!query.startsWith(token)) continue
if (/\s/.test(query[token.length] ?? "")) return true

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WARNING: mentionSettled treats any shorter known token followed by a space as complete, which can close @ search for spaced filenames.

query.startsWith(token) plus a following whitespace character returns true on the first match. Unlike syncMentionedPaths / findMentionRange in this file, the loop is not longest-first, and it never checks whether query is still a prefix of a longer known token — the behavior the comment above describes.

That is reachable in this PR's own feature: knownPaths is sticky, so after mentioning a folder named my, typing @my report makes syncMentionedPaths re-add my (the space after my is a valid boundary). mentionSettled("my report", {"my"}) then closes the dropdown and never searches for my report.txt. The same happens for builtins (terminal, git-changes) on every @terminal … query, even with an empty token set.

Suggestion: return false first when any token is equal to the query or has the query as a prefix; only then treat token + whitespace as settled. Also consider setting the existing dead query on select (token + trailing space) instead of inferring settlement from every shorter path still in mentionedPaths.


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch — this was a real bug in the feature's own path, fixed in 881d756.

The rule no longer consults every known token. useFileMention now records the mention actually inserted at each @ offset (in selectMention and insertFilePickerResult), and mentionSettled(query, token, tokens) only settles when the query continues past that token. Since knownPaths is sticky, a folder named my mentioned earlier no longer closes the search for a new @my report.txt, and a typed @terminal notes.txt no longer settles just because terminal is a builtin — a builtin has to have been inserted at that @ too.

I also took the prefix half of your suggestion: settlement returns false while any known token is longer than the query and still has it as a prefix, so a query growing toward a longer known path keeps searching.

On setting dead at select time instead: keying to the insertion offset does the same work but stays reversible — deleting back into the mention makes the query a prefix again and reopens the dropdown, which a sticky dead query would not.

New coverage in use-file-mention.test.ts (spaced path starting like an earlier mention keeps searching; typing after a genuinely selected file/builtin mention stays closed) and rewritten mentionSettled cases in file-mention-utils.test.ts.

Sylwester Liljegren added 2 commits September 1, 2026 21:27
The test bundles the fixture's whole webview graph with esbuild and runs it in a spawned process, which does not reliably fit in bun test's 5s default budget and has started timing out in CI. The work itself passes; only the budget was too tight.
mentionSettled tested every known token, and knownPaths is sticky for the whole session, so a short earlier mention such as a folder named 'my' closed the search for a genuinely new '@my report.txt'. Builtins had the same problem for any typed '@Terminal ...' query. Settlement now keys off the mention actually inserted at that '@' offset, and stays open while the query is still growing toward a longer known path.
@sylwester-liljegren

Copy link
Copy Markdown
Contributor Author

@marius-kilocode I have fixed the issue now. I tested it more thoroughly and I couldn't find anything. But feel free to test again before merging this PR into main.

@marius-kilocode

Copy link
Copy Markdown
Collaborator

Retested 881d75637b in isolated VS Code. Filenames with spaces stay searchable, and the normal select-then-continue flow no longer reopens the dropdown. The original issue I reported is fixed.

@sylwester-liljegren, can we also make inline @ search find past-chat titles directly? I checked the current search path: @past offers Past chats, but searching chat titles still requires selecting that entry and using the separate Search sessions field. We should fix that too so @ can find both files and past chats.

Validation: 225 focused tests passed, and the extension build, lint, and type checks passed.

@marius-kilocode

Copy link
Copy Markdown
Collaborator
file-02b7b0f6364f25e9d7546eb0759e69dc file-c293f3d59717386fb41abe364b57a377

Here some screenshots. I guess if we add this it would make sense to have it consistently across all searchable results. So that 'Past chats' as search term would also find the actual past chats element, would you agree?

@sylwester-liljegren

Copy link
Copy Markdown
Contributor Author

Hi, @marius-kilocode !

Thanks for your feedback!

I'll look into this more closely after my work. It should be possible to make it work, but just to confirm my understanding of your request: You'd like to remove the "Past chats" option and instead make past chats searchable the same way as files in the current repo? Is there anything about file search index architecture that needs to be considered when implementing these requested changes?

@marius-kilocode

Copy link
Copy Markdown
Collaborator

No my argument is if we allow to search for a search string with space like 'past chats' it should not only include files in that search but also include all other searchable elements in our context menu.

@sylwester-liljegren

Copy link
Copy Markdown
Contributor Author

I see your point now, @marius-kilocode . In that case, I'll fix it today after my work :)

Spaced queries only reached files, so '@past chats' or '@git changes' matched nothing and chat titles were reachable only after opening the Past chats picker. Mention labels and queries are now compared with hyphens and whitespace normalised, so every special entry answers the way its label reads, and a typed query also ranks directory-scoped past chats inline ahead of the file results. The session list is fetched once per scope on the first typed character, so a bare '@' still costs nothing extra.
@sylwester-liljegren

Copy link
Copy Markdown
Contributor Author

@marius-kilocode implemented in 13b6005c, both parts of what you asked for.

Every menu entry answers to its label, not just files. Mention labels and the query are now compared with hyphens and whitespace normalised to one separator, so @past chats, @git changes, @search worktrees all match the entry they read like — previously the aliases were matched by raw prefix, so any query containing a space could only ever hit files. The same matcher is used by the synchronous filter, so entries do not flicker out between keystrokes.

Past chats rank inline. A typed @ query now also fuzzy-matches directory-scoped chat titles (same filterSessions ranking the picker uses) and shows the top 3 above the file results, so @fix auth finds the chat directly; selecting one inserts the @Title mention exactly as the picker does. The Past chats entry stays for browsing the full list. The session list is fetched once per scope on the first typed character — a bare @ still posts nothing extra, which the Agent Manager worktree test asserts.

One detail worth flagging: inline results are built from a shared candidate list, so selectMention re-resolves the token for the picked chat. Without that, two chats with the same title would insert the same @Title and overwrite each other in knownSessions.

Tests: new coverage for spaced label matching (buildMentionResults, filterMentionResults, getPastChatsMentionResult), inline chat search end-to-end in use-file-mention.test.ts (list arrives, title matches, selection inserts the token), and the bare-@ no-fetch guarantee. 308 focused tests pass, plus typecheck, lint, knip, and format clean.

…paces

# Conflicts:
#	packages/kilo-vscode/tests/unit/session-provider-activity.test.ts
Comment thread packages/kilo-vscode/webview-ui/src/hooks/useFileMention.ts
Sylwester Liljegren added 3 commits September 3, 2026 22:20
Inline chat results arrive from an async fetch, but the prose heuristic closed the menu as soon as the file search came back empty, which is exactly what happens while typing a chat title. The close is now held while that scope's fetch is in flight and applied only once the list is known and still matches nothing, bounded by a grace timer so a lost reply cannot disable it.
The Browse files entry ends every list as a fallback, so a spaced query kept it out of the way: Enter sent the message and the prose heuristic closed the menu. A query that spells the entry out is a choice rather than prose, so both checks now make an exception for it and Enter opens the picker, whose result replaces the typed query including its spaces.
Files, past chats and the menu entries were emitted as fixed groups, so a chat title the query merely scattered across outranked a literal filename match, and the entries could only ever appear in their reserved slot. Everything is now scored against the query on one scale and sorted by fit, with a relevance floor that keeps a loose subsequence from dragging entries and chats into every short query. Browse files is never dropped, since reaching a file outside the workspace must not depend on what the query matches; it simply sinks to the bottom when ignored. The selection starts on the best answer, and a bare @ keeps the curated menu order.

Matching now has a single definition: the prose heuristic and the synchronous filter ask the ranking rather than testing label prefixes of their own, which is what made a fully typed 'browse files...' match the list and miss the prose check.
@sylwester-liljegren

Copy link
Copy Markdown
Contributor Author

@marius-kilocode , I have fixed so that "@git changes", "@past chats", and "@browse files" are matched by the inline search. For "@past chats", it opens up a separate search through previous chats as per your suggestion. Similarily, for "@git changes", it correctly inserts "@git-changes", and for "@browse files", it opens up the filepicker to choose a file outside of the workspace.

I also have made some changes regarding scoring and ordering of all entries appearing in the mentions dropdown, and it seems to me that it works so much faster. I hope that there is no catch to that, so feel free to try it for yourself and let me hear your feedback on this. Maybe some introduced features should be contained in a separate pull request, but I'll await your opinion on the current state of this PR.

@marius-kilocode
marius-kilocode merged commit 3dced72 into Kilo-Org:main Sep 4, 2026
25 checks passed
@marius-kilocode

Copy link
Copy Markdown
Collaborator

Thanks @sylwester-liljegren, this works well now. Merged.

@sylwester-liljegren

Copy link
Copy Markdown
Contributor Author

Perfect, thanks @marius-kilocode ! I'll go through the other PR concerning mentions in a multi-root workspace setting then :)

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.

2 participants