Skip to content

Fix Files pane refresh after filesystem changes - #9589

Merged
teamleaderleo merged 6 commits into
manaflow-ai:mainfrom
jiancui-research:jiancui-research/fix-file-pane-refresh
Sep 25, 2026
Merged

teamleaderleo merged 6 commits into
manaflow-ai:mainfrom
jiancui-research:jiancui-research/fix-file-pane-refresh

Conversation

@jiancui-research

@jiancui-research jiancui-research commented Aug 4, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Reload the AppKit file outline when FileExplorerStore.contentRevision changes, even when the root item count stays the same.
  • Restore multi-level directory expansion and path-based selection after replacement nodes are loaded.
  • Add behavior-level regression coverage for nested file additions/removals and deep expansion/selection preservation.

Why

FileExplorerStore.reload() replaces the tree with new FileExplorerNode instances and increments contentRevision. The outline coordinator previously called reloadData() only when the root node count changed. Adding or removing a file inside an expanded directory leaves that count unchanged, so NSOutlineView continued displaying the pre-reload node instances.

The coordinator now treats a content revision change as a full outline invalidation. Expansion restoration uses a dynamic row-count loop because expanding a parent reveals additional descendant rows during the same pass.

References

Testing

Added to cmuxTests/FileExplorerStoreTests.swift:

  • testOutlineReplacesNestedRowsWhenContentRevisionChangesWithoutCountChanges
  • testRevisionReloadRestoresNestedExpansionAndSelection

Available local checks:

  • swiftc -frontend -parse Sources/FileExplorerView.swift cmuxTests/FileExplorerStoreTests.swift passed.
  • ./scripts/lint-pbxproj-test-wiring.sh passed (651 test files checked).

Local verification limitations on this workstation:

  • Focused cmux-unit test execution is unavailable because no full Xcode installation is present; xcode-select points to CommandLineTools.
  • A tagged app build is unavailable because Zig and full Xcode are missing.
  • CI is therefore the first compile/test signal for the AppKit regression tests.
  • Manual dogfood verification and a demo recording remain required before merge.

Demo Video

Pending a tagged build and manual dogfood verification.

  • Video URL or attachment: Not yet available.

Checklist

  • I tested the change locally
  • I added or updated tests for behavior changes
  • I updated docs/changelog if needed (not needed; no user-facing copy or public API changed)
  • I requested bot reviews after my latest commit
  • All code review bot comments are resolved
  • All human review comments are resolved

Summary by CodeRabbit

  • Bug Fixes

    • File explorer outlines now refresh when file contents change, even if the number of visible rows remains the same.
    • Nested expanded folders and selected files are preserved during refreshes.
    • Newly revealed nested items are correctly restored when expanding folders.
  • Tests

    • Added regression coverage for outline updates, expansion preservation, and file selection across reloads.

@coderabbitai

coderabbitai Bot commented Aug 4, 2026 •

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

Next included review available in 21 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used all 10 included reviews currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Repository: manaflow-ai/cmux/.coderabbit.yaml

Review profile: ASSERTIVE

Plan: Advanced

Run ID: fac03fee-3384-4328-b834-befd08734d24

📥 Commits

Reviewing files that changed from the base of the PR and between e03411f and d729991.

📒 Files selected for processing (2)
  • Sources/FileExplorerView.swift
  • cmuxTests/FileExplorerStoreTests.swift
📝 Walkthrough

Walkthrough

The File Explorer coordinator now detects content revisions, refreshes stale nested rows, and processes newly revealed descendants during expansion restoration. Regression tests verify row replacement, expansion preservation, and retained file selection.

Changes

File Explorer refresh

Layer / File(s) Summary
Revision-aware outline refresh
Sources/FileExplorerView.swift, cmuxTests/FileExplorerStoreTests.swift
The coordinator tracks store.contentRevision and reloads the outline when nested content changes without a root-count change. Tests verify stale rows are replaced.
Expansion and selection restoration
Sources/FileExplorerView.swift, cmuxTests/FileExplorerStoreTests.swift
Expansion restoration uses the live row count so newly revealed descendants are processed. Tests verify expansion and Keep.swift selection after reload.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

Suggested reviewers: austinywang

🚥 Pre-merge checks | ✅ 25
✅ Passed checks (25 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: refreshing the Files pane after filesystem changes.
Description check ✅ Passed The description explains what changed, why, testing performed, limitations, and remaining review steps.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Cmux Swift Actor Isolation ✅ Passed The production diff only changes the existing @MainActor FileExplorerPanelView.Coordinator; store access remains on that boundary, and the other changes are tests.
Cmux Swift Blocking Runtime ✅ Passed The production diff adds revision tracking and deterministic outline-row traversal only; it adds no blocking waits, sleeps, delayed dispatch, main-queue sync, semaphores, or locks. Test polling was...
Cmux Browser Automation Off-Main ✅ Passed The cumulative PR diff changes FileExplorerView and tests only; TerminalController.swift and ControlCommandExecutionPolicy.swift have no changes, so no browser automation routing is introduced or w...
Cmux Expensive Synchronous Load ✅ Passed The production diff only adds contentRevision tracking, NSOutlineView reloads, and expansion restoration; it adds no agent-history loader, large JSON/JSONL parse, or synchronous broad scan.
Cmux Cache Substitution Correctness ✅ Passed The diff only changes NSOutlineView refresh and expansion restoration, plus regression tests; it does not replace an authoritative read in a persistence, history, undo, or snapshot path.
Cmux No Hacky Sleeps ✅ Passed The PR changes only Swift source and Swift tests; the rule scopes non-Swift runtime/scripts, and the added waits are test-only scaffolding.
Cmux Algorithmic Complexity ✅ Passed Production diff adds an O(visible rows) loop with Set membership and an O(1) revision check; no new nested scan or sort was introduced. Existing sorting/selection scans are unchanged.
Cmux Swift Concurrency ✅ Passed The PR adds no legacy async pattern. Production changes only track contentRevision and adjust NSOutlineView restoration; existing Combine/Task code is unchanged, and tests use async/await.
Cmux Swift @Concurrent ✅ Passed The diff adds no @concurrent or nonisolated async work; changed coordinator methods are synchronous @MainActor UI work, and the new async test runs in the existing @MainActor suite.
Cmux Swift Package Boundaries ✅ Passed Production diff only updates FileExplorerView.Coordinator's NSOutlineView refresh and expansion glue; FileExplorerStore and package boundaries are unchanged, while added tests are exempt.
Cmux Swiftpm Lockfiles ✅ Passed The PR range changes only Sources/FileExplorerView.swift and cmuxTests/FileExplorerStoreTests.swift; it changes no Package.swift, Package.resolved, .gitignore, workflow, or Xcode project package re...
Cmux Swift Logging ✅ Passed The cumulative PR diff adds no print, debugPrint, dump, NSLog, ad hoc logging, Logger, or sensitive-data logging; changes only outline refresh logic and tests.
Cmux User-Facing Error Privacy ✅ Passed The production diff only changes outline reload and expansion logic; it adds no user-facing errors, alerts, command output, recovery copy, or diagnostic text. Added tests are allowed.
Cmux Full Internationalization ✅ Passed The PR changes only outline refresh logic and tests; it adds no user-facing text, localization keys, catalogs, web messages, or locale files.
Cmux Swiftui State Layout ✅ Passed The PR changes only AppKit NSOutlineView coordinator logic and tests; it adds no SwiftUI state, GeometryReader, lazy/list row store references, or render-time state mutation.
Cmux Architecture Rethink ✅ Passed The diff adds revision comparison and dynamic expansion traversal in the existing Coordinator; it adds no production timing, polling, locks, observers, or side channels, and store paths remain the...
Cmux Swift Auxiliary Window Close Shortcuts ✅ Passed The PR changes an existing NSViewRepresentable coordinator and test fixtures; it adds no standalone window or identifier assignment. The auxiliary-window lint also passes.
Cmux Source Artifacts ✅ Passed The PR changes only Sources/FileExplorerView.swift and cmuxTests/FileExplorerStoreTests.swift; both are intentional hand-written source and behavior tests, with no artifact-like paths or generated...
Cmux No Test Or Debug Seam In Production Source ✅ Passed The PR adds no test/debug seam in Sources; production changes only track contentRevision and restore expansion, while ForTesting calls remain in cmuxTests.
Cmux No Ambient Global State ✅ Passed The production diff adds only private coordinator state and instance logic in FileExplorerPanelView.Coordinator; it adds no top-level API, mutable global, static namespace, or new singleton.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Sep 25, 2026 •

Copy link
Copy Markdown
Contributor

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

@teamleaderleo

Copy link
Copy Markdown
Collaborator

Thank you for this, @jiancui-research! Having the Files pane pick up changes inside expanded folders (and keep them expanded) is really nice. It's reviewed, up to date with main and CI is running. The one thing left before we can merge is the CLA: just comment the line below and we'll land it :D

I have read the CLA Document v2.2 and I hereby sign the CLA

@jiancui-research

Copy link
Copy Markdown
Contributor Author

I have read the CLA Document v2.2 and I hereby sign the CLA

github-actions Bot added a commit that referenced this pull request Sep 25, 2026
@teamleaderleo
teamleaderleo merged commit 2e269cd into manaflow-ai:main Sep 25, 2026
54 of 55 checks passed
@teamleaderleo

Copy link
Copy Markdown
Collaborator

Merged, thank you @jiancui-research! The Files pane now keeps up with changes inside expanded folders :D

@github-actions

Copy link
Copy Markdown
Contributor

Merge receipt for d729991857: every check was green at merge (13 verified; 13 skipped by policy). Full suite runs on main after merge.

rustybret pushed a commit to rustybret/bmux that referenced this pull request Sep 25, 2026
1348db7 test: stop asserting SwiftUI rows in the sidebar AX walk again (manaflow-ai#14625)
2e269cd Fix Files pane refresh after filesystem changes (manaflow-ai#9589)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants