Skip to content

fix(ui): ⌘O opens macOS Documents folder instead of workspace directory - #2056

Closed
BillionClaw wants to merge 2 commits into
manaflow-ai:mainfrom
BillionClaw:clawoss/fix/2010-open-folder-shortcut
Closed

BillionClaw wants to merge 2 commits into
manaflow-ai:mainfrom
BillionClaw:clawoss/fix/2010-open-folder-shortcut

Conversation

@BillionClaw

@BillionClaw BillionClaw commented Mar 24, 2026 •

Copy link
Copy Markdown
Contributor

⌘O (Open Folder) and the File → Open Folder… menu item both opened an NSOpenPanel
without setting directoryURL, causing macOS to default to ~/Documents regardless of
the current workspace.

The fix sets panel.directoryURL to the selected workspace's currentDirectory
before displaying the panel — the same approach already used by the terminal panel's
"Reveal in Finder" action. If no workspace is selected or the directory is empty/
invalid, the panel falls back to the default behavior.

Changed files:

  • Sources/ContentView.swift: command palette "Open Folder" handler
  • Sources/cmuxApp.swift: File menu "Open Folder…" handler

Fixes #2010


Summary by cubic

Fixes ⌘O and File → Open Folder… so the open dialog starts in the active workspace directory instead of ~/Documents (Fixes #2010). Both the command palette and File menu set NSOpenPanel.directoryURL from the selected workspace when valid, with a safe fallback.

Written for commit 1939f91. Summary will update on new commits.

Summary by CodeRabbit

  • Improvements

    • The "Open Folder..." dialog now defaults to the currently selected workspace directory, streamlining folder navigation.
  • Documentation

    • Removed the Claude Code Hooks integration documentation section.

Claude Code integration is now enabled by default (PR manaflow-ai#247, 0.60.0), so
the manual hooks configuration in settings.json is no longer needed.
Kept OpenAI Codex and OpenCode integration examples which are still
relevant. Fixes manaflow-ai#2009.
NSOpenPanel defaults to ~/Documents when directoryURL is not set.
Both the command palette "Open Folder" handler and the File menu
handler now set panel.directoryURL to the selected workspace's
currentDirectory (if it exists and is non-empty), matching the
behavior of the terminal panel 'Open in Finder' actions.

Fixes manaflow-ai#2010
@vercel

vercel Bot commented Mar 24, 2026

Copy link
Copy Markdown

@BillionClaw is attempting to deploy a commit to the Manaflow Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai

coderabbitai Bot commented Mar 24, 2026 •

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

Updated the "Open Folder…" command to preselect the currently selected workspace's directory in the macOS file picker, validating the path exists before applying it. Removed Claude Code Hooks documentation section.

Changes

Cohort / File(s) Summary
File Picker Directory Preselection
Sources/ContentView.swift, Sources/cmuxApp.swift
Both files implement identical logic to preselect NSOpenPanel's directoryURL based on the selected workspace's currentDirectory, with validation to ensure the path is non-empty and exists on disk.
Documentation Updates
docs/notifications.md
Removed the "Claude Code Hooks" integration section, including instructions for configuring notification hooks with idle_prompt and permission_prompt matchers.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Possibly related PRs

Poem

🐰 A folder opens where it should have all along,
No more lost in Documents, the workspace is strong!
The picker remembers where the rabbit did roam,
And Claude's old hooks find a rest, work is done. 🍀

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the fix: it clearly identifies that ⌘O (the keyboard shortcut) now opens the workspace directory instead of the macOS Documents folder.
Description check ✅ Passed The PR description includes a clear summary of the problem, the solution approach, affected files, and references the linked issue. Testing checklist items are provided for the author to complete.
Linked Issues check ✅ Passed The code changes fully address issue #2010 by setting NSOpenPanel.directoryURL to the selected workspace's currentDirectory in both the command palette and File menu handlers, ensuring the file picker opens at the workspace directory instead of ~/Documents.
Out of Scope Changes check ✅ Passed All changes are directly related to fixing issue #2010. The documentation change (removing Claude Code Hooks section) appears to be unrelated to the workspace directory fix and may warrant attention, but is minor and does not impact the core functionality being fixed.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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 and usage tips.

@greptile-apps

greptile-apps Bot commented Mar 24, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes the long-standing UX issue where ⌘O / File → Open Folder… always opened macOS's default ~/Documents picker instead of the current workspace's directory. The fix seeds NSOpenPanel.directoryURL with the selected workspace's currentDirectory (with appropriate guards for empty/missing paths) in both the command-palette handler (ContentView.swift) and the File-menu handler (cmuxApp.swift).

  • Core fix is correct and well-guarded — trims whitespace, checks for emptiness, checks filesystem existence, and falls back gracefully when no workspace is selected or the path is invalid.
  • Follows existing pattern — mirrors the same approach used by the terminal panel's "Reveal in Finder" action.
  • Minor defensive improvement available — FileManager.default.fileExists(atPath:) does not distinguish files from directories; using fileExists(atPath:isDirectory:) would make the intent explicit and guard against a stale currentDirectory that resolves to a file.
  • Unrelated docs change — docs/notifications.md silently removes the 31-line "Claude Code Hooks" integration section (idle_prompt / permission_prompt hook examples). This isn't mentioned anywhere in the PR description; it's worth confirming this deletion is intentional and not an accidental squash artifact.

Confidence Score: 4/5

  • Safe to merge once the undocumented docs deletion is confirmed as intentional.
  • The Swift fix is small, focused, and logically sound — it mirrors a pattern already proven elsewhere in the codebase, and all failure modes fall back gracefully to the previous behavior. The only point of concern is the unexplained removal of the Claude Code Hooks documentation section, which is unrelated to the stated fix and could be an unintentional commit artifact. Once that is clarified the PR is ready to merge.
  • docs/notifications.md — the Claude Code Hooks section was silently removed; needs confirmation this was intentional.

Important Files Changed

Filename Overview
Sources/ContentView.swift Adds directoryURL seeding for the command-palette "Open Folder" NSOpenPanel. Logic is correct and well-guarded; minor improvement possible by also asserting the path is a directory with fileExists(atPath:isDirectory:).
Sources/cmuxApp.swift Identical directoryURL fix applied to the File → Open Folder… menu handler. Same minor defensive-check opportunity as ContentView.swift.
docs/notifications.md Removes the entire "Claude Code Hooks" integration section (31 lines) without explanation in the PR description. Unrelated to the ⌘O fix and worth confirming the deletion is intentional.

Sequence Diagram

sequenceDiagram
    participant User
    participant Handler as ⌘O / File Menu Handler
    participant TM as TabManager
    participant FM as FileManager
    participant Panel as NSOpenPanel

    User->>Handler: Press ⌘O (or File → Open Folder…)
    Handler->>TM: selectedWorkspace
    alt workspace selected
        TM-->>Handler: workspace.currentDirectory
        Handler->>Handler: trim whitespace
        alt directory non-empty
            Handler->>FM: fileExists(atPath: directory)
            FM-->>Handler: exists = true/false
            alt exists == true
                Handler->>Panel: directoryURL = URL(fileURLWithPath: directory)
            else not found or empty
                Note over Handler,Panel: panel falls back to macOS default
            end
        end
    else no workspace
        Note over Handler,Panel: panel falls back to macOS default
    end
    Handler->>Panel: runModal()
    Panel-->>User: Folder picker (seeded to workspace dir)
    User->>Panel: Selects folder → OK
    Panel-->>Handler: url
    Handler->>TM: addWorkspace(workingDirectory: url.path)
Loading

Reviews (1): Last reviewed commit: "fix(ui): ⌘O opens macOS Documents folder..." | Re-trigger Greptile

Comment thread Sources/ContentView.swift
Comment on lines +5981 to +5982
if !directory.isEmpty, FileManager.default.fileExists(atPath: directory) {
panel.directoryURL = URL(fileURLWithPath: directory, isDirectory: true)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Verify path is a directory, not just that it exists

FileManager.default.fileExists(atPath:) returns true for both files and directories. If workspace.currentDirectory ever resolves to a file path (e.g., due to a stale workspace record), the URL would still be set as isDirectory: true and passed to NSOpenPanel.directoryURL. Using the isDirectory: variant explicitly confirms the path is a directory before using it:

Suggested change
if !directory.isEmpty, FileManager.default.fileExists(atPath: directory) {
panel.directoryURL = URL(fileURLWithPath: directory, isDirectory: true)
if !directory.isEmpty, FileManager.default.fileExists(atPath: directory, isDirectory: &isDir), isDir.boolValue {

Full suggestion (requires adding var isDir: ObjCBool = false before the check):

if let workspace = tabManager.selectedWorkspace {
    let directory = workspace.currentDirectory.trimmingCharacters(in: .whitespacesAndNewlines)
    var isDir: ObjCBool = false
    if !directory.isEmpty, FileManager.default.fileExists(atPath: directory, isDirectory: &isDir), isDir.boolValue {
        panel.directoryURL = URL(fileURLWithPath: directory, isDirectory: true)
    }
}

Same pattern applies to the equivalent block in Sources/cmuxApp.swift.

@cubic-dev-ai cubic-dev-ai Bot 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.

No issues found across 3 files

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

🧹 Nitpick comments (1)
Sources/ContentView.swift (1)

5979-5984: Validate that the path is a directory before assigning panel.directoryURL.

At Line 5981, fileExists(atPath:) also returns true for regular files. That can set a non-directory URL as the panel’s start location and break the intended fallback behavior.

Proposed fix
                 if let workspace = tabManager.selectedWorkspace {
                     let directory = workspace.currentDirectory.trimmingCharacters(in: .whitespacesAndNewlines)
-                    if !directory.isEmpty, FileManager.default.fileExists(atPath: directory) {
+                    var isDirectory: ObjCBool = false
+                    if !directory.isEmpty,
+                       FileManager.default.fileExists(atPath: directory, isDirectory: &isDirectory),
+                       isDirectory.boolValue {
                         panel.directoryURL = URL(fileURLWithPath: directory, isDirectory: true)
                     }
                 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Sources/ContentView.swift` around lines 5979 - 5984, When setting
panel.directoryURL from the workspace path (in the block referencing
tabManager.selectedWorkspace and workspace.currentDirectory), validate that the
path is actually a directory — not just an existing file — before assigning it
to panel.directoryURL; use FileManager.fileExists(atPath:isDirectory:) (or
URL.resourceValues for .isDirectory) to check the isDirectory flag and only set
panel.directoryURL when isDirectory is true so the panel’s fallback behavior
remains intact.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@Sources/cmuxApp.swift`:
- Around line 596-601: The code sets panel.directoryURL whenever the path exists
but doesn't ensure it's a directory; update the check around
activeTabManager.selectedWorkspace -> workspace.currentDirectory so you only set
panel.directoryURL when the path both exists and is a directory (use
FileManager.default.fileExists(atPath:isDirectory:) or equivalent to test
isDirectory and only assign to panel.directoryURL when isDirectory is true),
otherwise leave panel.directoryURL unset to allow default behavior.

---

Nitpick comments:
In `@Sources/ContentView.swift`:
- Around line 5979-5984: When setting panel.directoryURL from the workspace path
(in the block referencing tabManager.selectedWorkspace and
workspace.currentDirectory), validate that the path is actually a directory —
not just an existing file — before assigning it to panel.directoryURL; use
FileManager.fileExists(atPath:isDirectory:) (or URL.resourceValues for
.isDirectory) to check the isDirectory flag and only set panel.directoryURL when
isDirectory is true so the panel’s fallback behavior remains intact.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 74927850-40ae-4c1b-9a8c-22446427667c

📥 Commits

Reviewing files that changed from the base of the PR and between 441118b and 1939f91.

📒 Files selected for processing (3)
  • Sources/ContentView.swift
  • Sources/cmuxApp.swift
  • docs/notifications.md
💤 Files with no reviewable changes (1)
  • docs/notifications.md

Comment thread Sources/cmuxApp.swift
Comment on lines +596 to +601
if let workspace = activeTabManager.selectedWorkspace {
let directory = workspace.currentDirectory.trimmingCharacters(in: .whitespacesAndNewlines)
if !directory.isEmpty, FileManager.default.fileExists(atPath: directory) {
panel.directoryURL = URL(fileURLWithPath: directory, isDirectory: true)
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify whether `currentDirectory` is guaranteed to always be a directory.
# Expected: assignments/initialization sites should only use directory sources
# (workspace roots, cwd, validated directory paths).

rg -n --type swift -C4 '\b(var|let)\s+currentDirectory\b'
rg -n --type swift -C4 '\bcurrentDirectory\s*='
rg -n --type swift -C4 '\bcurrentDirectory\b.*(URL|path|cwd|workingDirectory)'

Repository: manaflow-ai/cmux

Length of output: 10968


Ensure panel.directoryURL is set only for actual directories.

At Line 598, the code checks only path existence. If workspace.currentDirectory is a file path, Line 599 still forces a directory URL and can open from an unexpected location instead of falling back to default behavior.

Proposed fix
                     if let workspace = activeTabManager.selectedWorkspace {
                         let directory = workspace.currentDirectory.trimmingCharacters(in: .whitespacesAndNewlines)
-                        if !directory.isEmpty, FileManager.default.fileExists(atPath: directory) {
+                        var isDirectory: ObjCBool = false
+                        if !directory.isEmpty,
+                           FileManager.default.fileExists(atPath: directory, isDirectory: &isDirectory),
+                           isDirectory.boolValue {
                             panel.directoryURL = URL(fileURLWithPath: directory, isDirectory: true)
                         }
                     }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if let workspace = activeTabManager.selectedWorkspace {
let directory = workspace.currentDirectory.trimmingCharacters(in: .whitespacesAndNewlines)
if !directory.isEmpty, FileManager.default.fileExists(atPath: directory) {
panel.directoryURL = URL(fileURLWithPath: directory, isDirectory: true)
}
}
if let workspace = activeTabManager.selectedWorkspace {
let directory = workspace.currentDirectory.trimmingCharacters(in: .whitespacesAndNewlines)
var isDirectory: ObjCBool = false
if !directory.isEmpty,
FileManager.default.fileExists(atPath: directory, isDirectory: &isDirectory),
isDirectory.boolValue {
panel.directoryURL = URL(fileURLWithPath: directory, isDirectory: true)
}
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Sources/cmuxApp.swift` around lines 596 - 601, The code sets
panel.directoryURL whenever the path exists but doesn't ensure it's a directory;
update the check around activeTabManager.selectedWorkspace ->
workspace.currentDirectory so you only set panel.directoryURL when the path both
exists and is a directory (use
FileManager.default.fileExists(atPath:isDirectory:) or equivalent to test
isDirectory and only assign to panel.directoryURL when isDirectory is true),
otherwise leave panel.directoryURL unset to allow default behavior.

@lawrencecchen

Copy link
Copy Markdown
Contributor

Thanks for the contribution! This has been addressed by #2034 which was just merged.

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.

⌘O opens macOS Documents folder instead of intended action

2 participants