Skip to content

fix(web): files panel and @ search follow the .code-workspace folder list - #325

Merged
LoganRupe merged 2 commits into
multi-repo-workspacesfrom
bug/323/files-panel-follows-workspace-folders
Sep 30, 2026
Merged

LoganRupe merged 2 commits into
multi-repo-workspacesfrom
bug/323/files-panel-follows-workspace-folders

Conversation

@LoganRupe

@LoganRupe LoganRupe commented Sep 29, 2026 •

Copy link
Copy Markdown
Owner

What Changed

For a .code-workspace project, the files panel and @ search now show every folder the file lists that exists on disk, git or not, however many repos there are. Diffs, checkpoints, PRs and git status still use repoRoots.

ChatView reads the folder list through the existing readWorkspaceFile query instead of storing it on the project, as #323 suggested. That means no new column and no migration 060. The folders dialog now re-reads the file when it opens and after a save, so the panel follows edits without a reload. In an isolated run, a repo that has its own worktree is shown as that worktree. Multi-repo isolated runs used to show the original checkouts here. Each root keeps its repo's name, so two repos named app show as client/app and server/app rather than their worktrees' app and app-2. The tree remounts when a folder's path changes under the same name, so it doesn't keep showing the old folder's contents.

The file components' repoRoots prop is now roots, since it can hold plain folders.

Why

With two or more repos, the panel and @ search only showed the git folders, so a listed plain folder like docs was missing. With one repo, they showed the whole folder the file sits in, so unlisted folders appeared.

Not covered here: a workspace that lists a single folder still shows the whole workspace folder, and one-repo workspaces still offer Initialize Git.

Fixes #323

UI Changes

Before (b36c4d2) on the left, this branch on the right. Two repos plus a listed plain docs folder, then one repo with docs and an unlisted luigi folder.

_Video:

compare.mp4

…list

For a .code-workspace project the files panel and @ search now span every
folder the file lists that exists on disk, git or not, instead of the git
repos (two or more) or the whole workspace folder (one). Git surfaces keep
using repoRoots.

Fixes #323
Copilot AI balanced review requested due to automatic review settings September 29, 2026 23:02
@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L labels Sep 29, 2026

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot review overview

🟡 Changes recommended

The file browser retains path-keyed caches when refreshed roots change, potentially showing files from the previous folder.

Review effort: Balanced
Findings: 1 Medium severity

Open (1)
What changed in this PR

Updates workspace-backed file browsing and @ search to use listed .code-workspace folders while preserving Git-specific repoRoots.

Changes:

  • Resolves file roots from existing workspace folders with worktree substitution.
  • Refreshes workspace-file data after dialog reads and saves.
  • Renames file component props from repoRoots to generalized roots.
File Description
apps/​web/​src/​lib/​projectFileRoots.ts Resolves workspace file roots.
apps/​web/​src/​lib/​projectFileRoots.test.ts Tests root resolution behavior.
apps/​web/​src/​components/​ProjectFoldersDialog.tsx Refreshes workspace data on open/save.
apps/​web/​src/​components/​files/​FilePreviewPanel.tsx Passes generalized roots to file UI.
apps/​web/​src/​components/​files/​FileBrowserPanel.tsx Browses and searches generalized roots.
apps/​web/​src/​components/​files/​FileBreadcrumbs.tsx Labels generalized root breadcrumbs.
apps/​web/​src/​components/​ChatView.tsx Connects workspace-file folders to browsing and mentions.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread apps/web/src/components/files/FilePreviewPanel.tsx
@LoganRupe

Copy link
Copy Markdown
Owner Author

@dotrahat could you review this when you get a chance?

The file tree cached folders by their label, so a listed folder whose path
changed under the same name (docs -> archive/docs) kept showing the old
contents; it now remounts when its roots change. Roots now carry the label
of the folder they came from, so an isolated run of two repos named `app`
shows client/app and server/app instead of their worktrees' app and app-2,
in the tree, the breadcrumbs and @ search.
@LoganRupe

LoganRupe commented Sep 30, 2026 •

Copy link
Copy Markdown
Owner Author

Follow-up: an isolated run of client/app + server/app, then docs repointed to archive/docs while expanded. Left is b485d3c, right is b7ee2cd

compare-followup.mp4

@LoganRupe
LoganRupe merged commit 75c7d8e into multi-repo-workspaces Sep 30, 2026
7 of 18 checks passed
@dotrahat

dotrahat commented Sep 30, 2026 •

Copy link
Copy Markdown

@LoganRupe Thanks for turning this around so fast. It merged before I finished, so here's my review as follow-ups. I tested an AppImage built from 75c7d8e37 against the four scenarios from #323, plus the folders dialog, edits made outside the app, and isolated runs.

Test results

Setup Result
A Two repos, listed plain docs Pass: panel shows api, web, docs; @release.md finds docs/release.md
B One repo, listed docs Pass: panel shows api, docs, no .code-workspace file
C Two repos, listed docs, unlisted luigi Pass: docs shown, luigi hidden, @yoshi finds nothing
D One repo, listed docs, unlisted luigi Pass: luigi and the workspace file hidden, @yoshi finds nothing
E Add a folder in Manage folders, save, reopen Pass: the new folder is listed and the panel updates without a reload
F Edit the .code-workspace in a text editor The panel doesn't update until Manage folders is opened, even after switching projects
G New worktree thread in the two-repo project Pass: roots keep their repo names and api shows the worktree copy
H Make the one-repo project's .code-workspace unreadable, reopen the app, then make it readable again The app warns that the file is unavailable and the panel falls back to the whole workspace folder, including luigi. After the file is readable again the panel stays on that layout, through project switches and the panel's refresh button, until Manage folders is opened or the app restarts

E also fixes a bug I was about to file: the dialog used a cached read for 30 seconds, so reopening it soon after a save showed the old folder list, and saving that list dropped folders from the file without a warning. refresh: true and the re-read after save cover it.

The new tests pass, the web typecheck is clean, and lint shows no new warnings in the changed files.

Follow-ups

1. Chat file links still resolve against repoRoots. markdownRepoRoots is still the git-only list, and only with two or more repos (ChatView.tsx:10006-10008). A link to a file in docs/ works because its path relative to the workspace folder happens to match the tree label docs. It doesn't match for a folder outside the workspace folder (../notes), a nested entry (notes/2026, labelled 2026), or isolated runs. I tested both folder cases: each link opened its file but didn't highlight it, and for ../notes the files panel collapsed instead. In the G test, clicking the agent's link to api/WORKTREE.md opened the file at its worktree path under .t3, but didn't highlight it in the files panel: the panel now shows the worktrees, while links are still matched against the original checkouts. Passing the paths from resolveProjectFileRoots as the link roots should line them up.

2. The folder list only refreshes through Manage folders (F, H). Nothing reliably re-reads the chat view's readWorkspaceFile query except the dialog, which forces a fresh read. In testing, an edit made in VS Code didn't reach the panel, and after a failed read the panel kept showing the fallback even once the file was readable again. Switching projects didn't bring the list back, and neither did the panel's refresh button, which reloads the folders' contents rather than the list. The fallback itself is the pre-PR layout: repoRoots, or the whole workspace folder for one repo, so unlisted folders appear and @ search covers them. From the code, the same fallback also shows while the first read is in flight, and the tree remounts when the real list arrives; locally that's too quick to notice, but it would be longer over a slow remote connection. Re-reading the file from the panel's refresh button and on window focus would cover edits and recovery, and waiting for the read instead of falling back would stop the old layout showing at all.

3. One-repo workspaces can't start isolated runs. The PR notes that one-repo workspaces still offer Initialize Git. The effect is wider: with one repo, isGitRepo checks the workspace folder (ChatView.tsx:3841-3843), which has no .git, so the whole git toolbar is hidden, including New worktree. I couldn't run G for the one-repo project for that reason. Same root cause as Initialize Git, so it probably belongs in the same follow-up.

4. Not covered here, for a decision later:

  • Mobile's file tree and @ search still use the whole workspace folder.
  • Plain folders can now be @-referenced, but the agent is still only given repoRoots. A listed folder outside the workspace folder isn't under the agent's working directory or extra directories, and in isolated runs no plain folder is under the worktree. So an @ reference to one can point the agent at a path it needs approval for, or can't write to.

Happy to open issues for any of these.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants