You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
pi-fff: support explicit index roots when Pi starts in $HOME #868
When Pi is launched from $HOME, pi-fff currently has an all-or-nothing choice: either index the entire home directory or disable home-directory indexing entirely.
In my case, $HOME contains several profile and project directories. Some are large or irrelevant and should not be indexed, while others are useful to have available to FFF. The current enableHomeDirScanning option cannot express that distinction.
Could pi-fff support an explicit allow-list of indexing roots, for example:
When Pi starts in $HOME, do not eagerly scan all of $HOME.
Create and retain indexes for the configured roots instead.
Continue respecting .gitignore and existing path constraints.
Leave the current behavior unchanged when indexRoots is unset.
This seems useful for users who work from their home directory but have large toolchains, build outputs, caches, or unrelated profiles below it.
I found #743 and the merged opt-out in #749. Those solve visibility and the all-home opt-out, but this request is specifically for granular, scoped indexing rather than a full-home scan.
[triage-bot] DESIGN NEEDED: indexRoots cannot be a config-only change — no PR opened.
Classified feature-request. Not a duplicate of #743/#749/#588 — those are the all-home opt-out, this is scoped multi-root. Confirmed no multi-root concept exists anywhere in the tree (grep -rn 'indexRoots|index_roots|multiRoot' → 0 hits outside this issue).
Blocker: one picker == one root
FilePicker holds a single base_path, set once at construction:
crates/fff-core/src/file_picker.rs:903 — base_path: path (scalar, no collection)
packages/shared/fff-api.ts — InitOptions.basePath is a single string
So indexRoots: ["/root/Projects", "/root/.pi"] cannot become one index. It has to become N pickers plus a fan-out/merge layer in pi-fff. That layer does not exist.
Why it is not small
Every search path in pi-fff assumes exactly one main index:
packages/pi-fff/src/index.ts:872 and :1074 — find_files / grep pick one picker
packages/pi-fff/src/index.ts:565 — @-mention autocomplete calls mixedSearch on one finder
Fan-out forces four decisions that are yours, not mine:
Score comparability. Fuzzy scores in score.rs are relative to the corpus of one index. Concatenating results from N independent indexes and sorting by score is not obviously correct — a match in a 200-file root will not rank fairly against one in a 200k-file root.
Pagination.pageIndex/pageSize are per-picker. A stable merged cursor across N indexes needs a new cursor encoding; grep already has its own cursor at index.ts:928.
Memory / retention. The reporter asks to retain the indexes. AuxFinderPool deliberately does the opposite: MAX_AUX = 3 with LRU eviction (aux-finders.ts:7, :90-95) and a 5-minute idle TTL (aux-finders.ts:8, :42-52). Pinning configured roots means N resident indexes plus N file watchers for the whole session. For this repo that is a perf decision, not an implementation detail.
Rough size if done faithfully: 500-700 LOC across config.ts, pi-fff.schema.json, aux-finders.ts, index.ts, tests, README.md. Under the hard limit, but it changes the single-index invariant of the extension, so I am not landing it speculatively.
Per-query scoped search outside cwd is implemented. An explicit path argument routes to a lazily-created aux picker (aux-finders.ts:167-184 → :126-153), so the agent can already search ~/Projects without indexing all of $HOME. What is missing is only the pre-warm and pin half — the index is built on first use and evicted after 5 min idle.
Note that with enableHomeDirScanning: false and cwd == $HOME the main picker fails outright at file_picker.rs:881-886 (surfaces via file-picker.ts:39-43 → index.ts:708), which is open issue #857. Any indexRoots work has to settle #857 first, since that is the exact configuration this request targets.
The easiest way to achieve this is to have a .ignore file where you ignore everything in your $HOME and unignore specifid directories .ignore works liike .gitignore but doesn't need git
Activity
gustav-fff commentedon Sep 10, 2026
[triage-bot] DESIGN NEEDED:
indexRootscannot be a config-only change — no PR opened.Classified feature-request. Not a duplicate of #743/#749/#588 — those are the all-home opt-out, this is scoped multi-root. Confirmed no multi-root concept exists anywhere in the tree (
grep -rn 'indexRoots|index_roots|multiRoot'→ 0 hits outside this issue).Blocker: one picker == one root
FilePickerholds a singlebase_path, set once at construction:crates/fff-core/src/file_picker.rs:903—base_path: path(scalar, no collection)packages/shared/fff-api.ts—InitOptions.basePathis a single stringSo
indexRoots: ["/root/Projects", "/root/.pi"]cannot become one index. It has to become N pickers plus a fan-out/merge layer in pi-fff. That layer does not exist.Why it is not small
Every search path in pi-fff assumes exactly one main index:
packages/pi-fff/src/index.ts:872and:1074—find_files/ grep pick one pickerpackages/pi-fff/src/index.ts:565—@-mention autocomplete callsmixedSearchon one finderpackages/pi-fff/src/index.ts:1317,:1332,:1351— health / scan-progress / rescan tools readmainFinderdirectlyFan-out forces four decisions that are yours, not mine:
score.rsare relative to the corpus of one index. Concatenating results from N independent indexes and sorting by score is not obviously correct — a match in a 200-file root will not rank fairly against one in a 200k-file root.pageIndex/pageSizeare per-picker. A stable merged cursor across N indexes needs a new cursor encoding; grep already has its own cursor atindex.ts:928.index.ts:932passes a singletimeBudgetMs: GREP_TIME_BUDGET_MSto one picker. Across N pickers this is either N× the wall clock or a divided budget that regresses per-root recall. Directly touches [Bug]: grep timeBudgetMs is ignored for zero-match searches #826/fix(grep): enforce_time_budget option for zero-match searches (#826) #827.AuxFinderPooldeliberately does the opposite:MAX_AUX = 3with LRU eviction (aux-finders.ts:7,:90-95) and a 5-minute idle TTL (aux-finders.ts:8,:42-52). Pinning configured roots means N resident indexes plus N file watchers for the whole session. For this repo that is a perf decision, not an implementation detail.Rough size if done faithfully: 500-700 LOC across
config.ts,pi-fff.schema.json,aux-finders.ts,index.ts, tests,README.md. Under the hard limit, but it changes the single-index invariant of the extension, so I am not landing it speculatively.Already works today (workaround for @Abdk4Moura)
Per-query scoped search outside cwd is implemented. An explicit
pathargument routes to a lazily-created aux picker (aux-finders.ts:167-184→:126-153), so the agent can already search~/Projectswithout indexing all of$HOME. What is missing is only the pre-warm and pin half — the index is built on first use and evicted after 5 min idle.Note that with
enableHomeDirScanning: falseand cwd ==$HOMEthe main picker fails outright atfile_picker.rs:881-886(surfaces viafile-picker.ts:39-43→index.ts:708), which is open issue #857. AnyindexRootswork has to settle #857 first, since that is the exact configuration this request targets.@dmtrKovalenko — needs your call
Not proceeding without an answer — the merge semantics are a design choice I should not guess at.
Honk-Honk 🪿
dmtrKovalenko commentedon Sep 11, 2026
The easiest way to achieve this is to have a .ignore file where you ignore everything in your $HOME and unignore specifid directories
.ignoreworks liike.gitignorebut doesn't need gitAbdk4Moura commentedon Sep 13, 2026
Thanks, this works for my use case. I appreciate the clarification.