Repository navigation
Conversation
invalidateFromWatcher() only refreshes the parent directory of a changed path and only when it is already loaded, so external changes can leave the tree stale until a full page reload. Add file.tree.refreshAll() (force-reload every listed directory) and a refresh button in the sidebar header.
|
Hey! Your PR title Please update it to start with one of:
Where See CONTRIBUTING.md for details. |
|
Thanks for updating your PR! It now meets our contributing guidelines. 👍 |
|
Automated PR Cleanup Thank you for contributing to opencode. Due to the high volume of PRs from users and AI agents, we periodically close older PRs using automated criteria so maintainers can focus review time on the most active and community-supported contributions. This PR was closed because it matched the following cleanup criteria:
PRs created within the last month are not affected by this cleanup. If you believe this PR was closed incorrectly, or if you are still actively working on it, please leave a comment explaining why it should be reopened. A maintainer can review and reopen it if appropriate. Thanks again for taking the time to contribute. |
Issue for this PR
Related to #38125 and #27333 — when files change outside the app (or a watcher event is missed), the session file tree stays stale until a full page reload. There is no open issue for this exact button; #30661 asked for one but was auto-closed. Happy to move this under a new issue if you prefer.
Type of change
What does this PR do?
The tree only updates from
file.watcher.updatedevents, andinvalidateFromWatcher()inpackages/app/src/context/file/watcher.tsonly refreshes the parent directory of the changed path — and only when that directory is already loaded. So when I copy/edit/add files from outside the app, the sidebar keeps showing the old state until I reload the page.This adds a small manual escape hatch: a refresh button in the file browser sidebar header that force-reloads every directory currently listed. The tree store already tracks which dirs were listed and dedupes in-flight requests, so
refreshAll()just force-lists those again (never-loaded dirs are skipped, so nothing expands unexpectedly).Concretely:
refreshAll()on the tree store +file.tree.refreshAll(), an icon button in the sidebar header (existingoutline-reseticon; the header gets an optionalactionsslot, existing callers unaffected), asession.files.refreshstring in all locales, and unit tests for the store.How did you verify your code works?
packages/app/src/context/file/tree-store.test.ts(cached dirs not re-fetched on normal ops, force reload picks up new entries, never-loaded dirs are skipped)bun run test:unitinpackages/app: 728 pass, 0 failbun run typecheckpasses for@opencode-ai/app,@opencode-ai/session-ui,@opencode-ai/uiScreenshots / recordings
I'll add a short recording of the sidebar header with the new button.
Checklist