fix(at-mention): nested .gitignore via shared util#129
Merged
Conversation
@paulo70015 reported every @ query returning "no files match" on Flutter projects. Diagnosis: the picker walker did not honor .gitignore, so the 500-result cap filled with ios/Pods/ before the alphabetical walk reached lib/. Rather than grow the hardcoded ignore list per framework (Pods, DerivedData, target, vendor, …), trust the project's own .gitignore — same source of truth fzf, ripgrep, and the rest of the ecosystem use. - new `src/gitignore.ts` lifts loadGitignoreAt + ignoredByLayers out of the semantic chunker, so the @ picker walker and the indexer share one nested-gitignore implementation - `listFilesWithStats(Sync|Async)` push a layer per directory's .gitignore as it descends; statBatch checks the merged layer set before stat'ing - default maxResults bumped 500 → 2000 - opt-out via `respectGitignore: false` on ListFilesOptions - `chunker.ts` switches to the shared util — no behavior change Tests cover root + nested .gitignore, negation (`!keep.log`), opt-out, and the existing skip / cap / DFS-order contracts.
c95a21b to
84fa813
Compare
This was referenced May 2, 2026
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.
Closes #128.
Why
@paulo70015 reported that on macOS Flutter projects every
@query (@lib/main.dart,@lib,@test,@pubspec.yaml) returned "no files match" — even though the files existed and weren't gitignored.Diagnosis
The picker walker did not honor
.gitignore. The 500-result cap filled withios/Pods/(alphabetically beforelib/) before the walk reached the user's source code.Fix — trust the project's own ignore rules, not a hardcoded list
Rather than grow
DEFAULT_PICKER_IGNORE_DIRSper-framework (Pods, DerivedData, target, vendor, _build, …), trust the project's.gitignore. Same source of truth thatfzf,ripgrep,fd, and the rest of the ecosystem use.src/gitignore.tsliftsloadGitignoreAt+ignoredByLayersout of the semantic chunker, so the @ picker walker and the indexer share one nested-gitignore implementationlistFilesWithStats(Sync|Async)push a layer per directory's.gitignoreas they descendstatBatchchecks the merged layer set before stat'ing — no syscalls for files we'll dropmaxResultsbumped from 500 → 2000respectGitignore: falseopt-out for raw walkschunker.tsswitches to the shared util — no behavior change thereNo git binary required (we just read
.gitignorefiles via the existingignorenpm package). Works in projects without git, in containers, on first launch — same correctness asgit ls-filesfor typical projects.Verification
npm run verify— typecheck, lint, build, 1817 tests all green.gitignore, negation patterns (!keep.log), and the opt-out pathOut of scope
~/.config/git/ignoreand.git/info/exclude— easy follow-up if anyone reports needing them; the layer model already supports it