feat: add file @-mention autocomplete with project file scanning#147
Merged
feat: add file @-mention autocomplete with project file scanning#147
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5297f70dd8
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
Extend the mention system to show session files alongside personas: - MentionAutocomplete now renders two sections: Personas and Files - FileMentionItem type for file suggestions (resolvedPath, displayPath, filename, kind) - MentionItem union type (persona | file) for unified selection handling - useMentionDetection accepts files param, filters both lists on query - confirmMention returns MentionItem instead of Persona - Extract mention handlers into useMentionHandlers hook (keeps ChatInput under 500 lines) - File data sourced from ArtifactPolicyContext.getAllSessionArtifacts() - Selecting a file inserts its resolved path into the message text - Selecting a persona still switches the active persona (unchanged behavior) - Add i18n key mention.filesTitle for the files section header
Replace manual absolute positioning with shared/ui Popover primitives so the dropdown gets viewport collision detection and portal rendering. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add a Tauri command that scans project roots for files usable in @ mention completion.\n\nThe scan deduplicates roots and file paths, skips common generated directories,\nlimits traversal depth and result count, and runs in a blocking task to avoid\nstalling the async runtime.\n\nExpose the command through the frontend system API so chat mention handlers can\nrequest project files.
Load project file paths from configured working directories and merge them\nwith session artifacts in mention autocomplete results.\n\nWhen selecting a project, mention suggestions now include matching files even\nbefore they have been attached in the current session, and retain deduped\nabsolute paths for insertion.\n\nAdd a chat input test for file mention selection and include the Spanish\ntranslation for the files section heading.
Add scrollIntoView({ block: "nearest" }) via ref map so the active
item stays visible when arrowing through the popover list.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace includes() with an fzf-style subsequence matcher so queries like "crates/sprout-acp/.rs" match files whose path contains those characters in order (e.g. acp.rs, config.rs in that directory). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The loadedRootsKeyRef dedup guard prevented the second mount in React StrictMode from fetching files, while the first mount's response was cancelled by cleanup. Remove the ref guard — the sameStringArray check in setProjectFilePaths already prevents unnecessary state updates. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…cement Use a pendingCursorRef + useEffect triggered by text changes instead of rAF to set focus and cursor position after mention selection. This is React-idiomatic — the effect runs after React flushes the new text into the DOM, avoiding timing hacks. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Expand biome.json includes array to multi-line format - Exclude .worktrees and .claude/worktrees from biome checks - Add biome-ignore for intentional text dependency in cursor effect Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Type the listFilesForMentions mock with explicit parameter types instead of rest spread to satisfy tsc --noEmit. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The mock IPC fallback returns null for unknown commands, which crashes the mention handler expecting a string array. Add the mock so E2E draft tests can render the chat view. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace the hardcoded should_skip_dir list with the `ignore` crate (from ripgrep) which respects .gitignore, .git/info/exclude, and global gitignore. This automatically handles project-specific ignores instead of maintaining a static list of directory names. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Two fixes: 1. File scanner: add follow_links(false) explicitly and canonicalize all paths to reject any that escape the project roots. Prevents symlink loops and path leakage. 2. Mention filtering: useMentionDetection hook now owns all filtering and exposes filteredPersonas/filteredFiles. MentionAutocomplete renders pre-filtered results instead of re-running the same fuzzy match on every keystroke. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Collapse redundant persona header branches into a single condition
- Remove replace(/\s{2,}/g, " ") from mention insertion which silently
ate intentional double spaces (markdown, code blocks)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Prevents stale files from a previous project appearing in mention results while the new scan is in flight. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
d5a4a30 to
649943d
Compare
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.
Category: new-feature
User Impact: Users can now mention project files by typing
@in the chat input, with fuzzy path matching and automatic filtering based on .gitignore rules.Problem: The @-mention popover only showed personas. When working in a project, there was no way to reference files from the chat input — users had to manually type or paste file paths, with no discovery or autocomplete.
Solution: Extend the mention system to scan project working directories for files and surface them alongside personas in the autocomplete popover. Uses fzf-style fuzzy subsequence matching so path-based queries like
crates/sprout-acp/.rswork naturally. The backend uses theignorecrate (from ripgrep) to respect.gitignoreat every level, keeping results clean without a hardcoded skip list.File changes
src-tauri/Cargo.toml / src-tauri/Cargo.lock
Add the
ignorecrate dependency for gitignore-aware directory walking.src-tauri/src/commands/system.rs
New
list_files_for_mentionsTauri command. Scans project roots usingignore::WalkBuilderwhich respects.gitignore, global gitignore, and.git/info/exclude. Enforces depth limits, result caps, symlink safety (follow_links(false)), and canonicalization to reject paths escaping project roots.src-tauri/src/lib.rs
Register the new
list_files_for_mentionscommand.src/shared/api/system.ts
Frontend API binding for the new Tauri command.
src/features/chat/hooks/useMentionHandlers.ts
New hook centralizing all mention logic: loads project files on mount, builds deduplicated
FileMentionItemlists from session artifacts + project files, owns fuzzy filtering, keyboard navigation, and selection handlers. Clears stale results immediately on project switch. UsesuseEffect(notrequestAnimationFrame) for post-selection cursor placement.src/features/chat/ui/MentionAutocomplete.tsx
Extended to render two sections (personas + files) with section headers. Accepts pre-filtered results from the hook (single filtering pass per keystroke). Adds
scrollIntoView({ block: "nearest" })so arrow-key navigation keeps the selected item visible. ExportsfuzzyMatch— an fzf-style subsequence matcher used across the mention system.src/features/chat/ui/ChatInput.tsx
Wraps the textarea in a Radix
Popover/PopoverAnchorfor mention autocomplete positioning with viewport collision detection. Wires upuseMentionHandlersand passes pre-filtered results toMentionAutocomplete.src/features/chat/ui/tests/MentionAutocomplete.test.tsx
New test file covering rendering, scroll-into-view behavior, aria-selected state, and fuzzyMatch unit tests including path subsequence matching.
src/features/chat/ui/tests/ChatInput.test.tsx
Add typed mock for
listFilesForMentionsand test for file mention selection inserting the resolved path.src/shared/i18n/locales/en/chat.json / es/chat.json
Add
mention.filesTitlei18n key for the files section header.tests/e2e/fixtures/tauri-mock.ts
Add
list_files_for_mentions,get_home_dir, andpath_existsto the Tauri IPC mock so E2E tests render correctly.biome.json
Exclude
.worktreesand.claude/worktreesdirectories from biome checks.Reproduction Steps
@in the chat input — the popover should show a "Mention a Persona" section and a "Files" section with project filessrc/— results should fuzzy-filter to matching files.gitignored directories (node_modules, dist, target, etc.) do not appear in resultsDemo
Screen.Recording.2026-04-10.at.8.05.06.AM.mov
🤖 Generated with Claude Code