Human comments
This will be useful for file tree plugins to be more customizable
Summary
host.list_paths skips any entry whose name starts with ., plus node_modules and symlinks, with no way to opt in. Because BB's own file search runs through that command, quick-open cannot find .github/workflows/ci.yml — a file BB reads and previews perfectly well through host.read_file. The rule is hardcoded in the daemon's walker, not derived from gitignore, and callers (first-party or plugin) cannot override it.
I hit this building a file tree in a fileOpener plugin, but the plugin is incidental: the same gap is visible in BB's own UI, and that is what the repro below uses.
Versions and environment
- bb dev build from source at
6be45053be92f964895038fc374a45e759087479 (main), plus bb 0.38.0 desktop (same behavior).
- macOS 14 (Darwin 23.3.0), Node v26.7.0.
- Repository under test: this one (
.github/workflows/ci.yml is present).
Steps to reproduce
- Open a thread whose environment is a checkout of this repo.
- Open the secondary panel's file search (
+ → file search) and type ci.yml.
Or against the API directly, which is what I did:
curl -s "http://127.0.0.1:<port>/api/v1/environments/<envId>/paths?query=ci.yml&limit=5&includeFiles=true&includeDirectories=false"
Expected vs actual
Actual — .github/workflows/ci.yml is absent, and the four fuzzy matches returned are all unrelated:
query ci.yml -> 4 results: apps/mobile/e2e/flows/phase4a-conversation-rows.yaml,
apps/mobile/e2e/flows/phase4b-actions.yaml,
apps/mobile/e2e/flows/phase4b-interactions.yaml
query workflows -> 5 results: plugins/workflows/README.md, plugins/workflows/package.json, ...
query AGENTS.md -> 1 results: AGENTS.md # control: the endpoint works
Expected: .github/workflows/ci.yml appears for ci.yml. It is an ordinary YAML file, and BB is otherwise perfectly happy with it — reading the very same path through the host file API succeeds:
read .github/workflows/ci.yml -> OK, 7794 chars, sha d9d35944bf59
So one host command serves the file and another refuses to admit it exists.
Evidence
The exclusions are three unconditional continues in the recursive walker, listPathsRecursively:
if (entry.name.startsWith(".")) continue;
if (entry.name === "node_modules") continue;
if (entry.isSymbolicLink()) continue;
Note the dotfile rule is much broader than the node_modules one. It hides .github/, .claude/, .bb/, .vscode/ and everything under them — directories users edit routinely — while node_modules at least matches most people's intent most of the time.
What you ruled out
- Not gitignore: nothing reads an ignore file; the names are literals in the walker.
.github/workflows/ is committed and not ignored.
- Not the fuzzy ranker dropping it: raising
limit and querying workflows directly still returns nothing under .github/. The AGENTS.md control proves the endpoint and environment are right.
- Not a permissions or symlink artifact:
.github/workflows/ci.yml is a regular file and reads fine through host.read_file on the same host and root.
- Not a duplicate: searched open and closed for
list_paths dotfiles, file search hidden files, node_modules exclusion, listPathsRecursively — no matches.
- Not plugin-specific: the repro above is entirely first-party.
Suggested priority and effort
Medium priority, small-to-medium effort. It silently makes a class of real project files unreachable from quick-open, and the failure is invisible — the search returns other results, so it reads as "no such file" rather than "this file is filtered".
Suggested shape: make the exclusions caller-configurable on host.list_paths rather than baked into the walker — for example includeHidden and includeNodeModules (or a general exclude list), defaulting to today's behavior so nothing changes for existing callers. That keeps quick-open's defaults sane while letting a file tree offer "show hidden files" and letting a plugin decide for itself. Note this is a wire change and would need a HOST_DAEMON_PROTOCOL_VERSION bump per AGENTS.md.
If the appetite is smaller, narrowing the dotfile rule alone — skipping .git/ rather than every dot-leading name — would fix the reported symptom without a protocol change.
Found in bb thread thr_nnk8m7d8gw while building a Monaco fileOpener plugin; see also #2026 and #2072 from the same work.
AGENT GENERATED: by Claude Opus 5
Human comments
This will be useful for file tree plugins to be more customizable
Summary
host.list_pathsskips any entry whose name starts with., plusnode_modulesand symlinks, with no way to opt in. Because BB's own file search runs through that command, quick-open cannot find.github/workflows/ci.yml— a file BB reads and previews perfectly well throughhost.read_file. The rule is hardcoded in the daemon's walker, not derived from gitignore, and callers (first-party or plugin) cannot override it.I hit this building a file tree in a
fileOpenerplugin, but the plugin is incidental: the same gap is visible in BB's own UI, and that is what the repro below uses.Versions and environment
6be45053be92f964895038fc374a45e759087479(main), plus bb 0.38.0 desktop (same behavior)..github/workflows/ci.ymlis present).Steps to reproduce
+→ file search) and typeci.yml.Or against the API directly, which is what I did:
curl -s "http://127.0.0.1:<port>/api/v1/environments/<envId>/paths?query=ci.yml&limit=5&includeFiles=true&includeDirectories=false"Expected vs actual
Actual —
.github/workflows/ci.ymlis absent, and the four fuzzy matches returned are all unrelated:Expected:
.github/workflows/ci.ymlappears forci.yml. It is an ordinary YAML file, and BB is otherwise perfectly happy with it — reading the very same path through the host file API succeeds:So one host command serves the file and another refuses to admit it exists.
Evidence
The exclusions are three unconditional
continues in the recursive walker,listPathsRecursively:host.list_pathscommand params carrypath,query,limit,includeFiles,includeDirectories— nothing to relax the above.browseHostDirectoryapplies the same two name rules, so the interactive path browser cannot reach them either. (It does follow symlinks, deliberately — single-level browsing has no loop risk.)environments.paths(routes/environments.ts#L625),projects.paths(routes/projects.ts#L680), andfiles.listPaths(routes/files.ts#L292).host.read_filehas no equivalent exclusion, which is why the read above succeeds.Note the dotfile rule is much broader than the
node_modulesone. It hides.github/,.claude/,.bb/,.vscode/and everything under them — directories users edit routinely — whilenode_modulesat least matches most people's intent most of the time.What you ruled out
.github/workflows/is committed and not ignored.limitand queryingworkflowsdirectly still returns nothing under.github/. TheAGENTS.mdcontrol proves the endpoint and environment are right..github/workflows/ci.ymlis a regular file and reads fine throughhost.read_fileon the same host and root.list_paths dotfiles,file search hidden files,node_modules exclusion,listPathsRecursively— no matches.Suggested priority and effort
Medium priority, small-to-medium effort. It silently makes a class of real project files unreachable from quick-open, and the failure is invisible — the search returns other results, so it reads as "no such file" rather than "this file is filtered".
Suggested shape: make the exclusions caller-configurable on
host.list_pathsrather than baked into the walker — for exampleincludeHiddenandincludeNodeModules(or a generalexcludelist), defaulting to today's behavior so nothing changes for existing callers. That keeps quick-open's defaults sane while letting a file tree offer "show hidden files" and letting a plugin decide for itself. Note this is a wire change and would need aHOST_DAEMON_PROTOCOL_VERSIONbump per AGENTS.md.If the appetite is smaller, narrowing the dotfile rule alone — skipping
.git/rather than every dot-leading name — would fix the reported symptom without a protocol change.Found in bb thread
thr_nnk8m7d8gwwhile building a MonacofileOpenerplugin; see also #2026 and #2072 from the same work.