Skip to content

Add a configurable keyboard shortcut to open the diff viewer - #5178

Merged
austinywang merged 7 commits into
mainfrom
issue-5169-diff-viewer-shortcut
Jun 2, 2026
Merged

austinywang merged 7 commits into
mainfrom
issue-5169-diff-viewer-shortcut

Conversation

@austinywang

@austinywang austinywang commented Jun 2, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Adds a configurable keyboard shortcut to open the diff viewer for the focused workspace, rebindable in Settings like every other cmux shortcut.

cmux already opens the diff viewer via the cmux diff CLI and the Open Diff Viewer command-palette entry (which spawns that CLI). This wires up a first-class keyboard shortcut that goes through the same shared diff-open path — no duplicated diff-open logic.

What changed

  • New openDiffViewer action in KeyboardShortcutSettings.Action (label "Open Diff Viewer"). It's automatically visible/editable in Settings → Keyboard Shortcuts (settingsVisibleActions + ShortcutSettingRow) and configurable via ~/.config/cmux/cmux.json (shortcuts.openDiffViewer) through KeyboardShortcutSettingsFileStore.
  • Shared action path: extracted the command palette's diff launcher into AppDelegate.openDiffViewerForFocusedWorkspace(for:). Both the command palette and the new shortcut now funnel through it (it spawns cmux diff --unstaged --workspace … --focus true for the focused workspace). The per-workspace working-directory resolution was lifted to Workspace.resolvedWorkingDirectory() and reused by the existing configured-action path too.
  • Dispatch: AppDelegate.handleCustomShortcut gets a matchConfiguredShortcut(event:action:.openDiffViewer) branch that opens the diff viewer for the event window's focused workspace (beeps on failure, matching the palette).

Default shortcut: Cmd+Ctrl+D

The issue proposed Cmd+Shift+D ("D" for Diff), but that collides with Split Down. The entire Cmd-based "D" family is already taken by split actions:

Chord Action
Cmd+D Split Right
Cmd+Shift+D Split Down
Cmd+Opt+D Split Browser Right
Cmd+Shift+Opt+D Split Browser Down

Cmd+Ctrl+D is free, keeps the "D for Diff" mnemonic, and matches cmux's existing Cmd+Ctrl+<letter> app-shortcut family (Cmd+Ctrl+W Close Window, Cmd+Ctrl+F Toggle Full Screen). The added dispatch test asserts the default is conflict-free.

Docs & localization

  • web/data/cmux-shortcuts.ts gains an openDiffViewer entry (renders into both the keyboard-shortcuts docs page and the shortcuts.bindings configuration docs table automatically).
  • Added shortcut.openDiffViewer.label (en + ja) to Resources/Localizable.xcstrings.

Tests

Added testOpenDiffViewerShortcutDefaultsToCmdCtrlDAndRoutesToSharedDiffPath to cmuxTests/AppDelegateShortcutRoutingTests.swift: dispatches a Cmd+Ctrl+D key event through handleCustomShortcut and asserts it routes to the shared diff-open path (via a debugOpenDiffViewerHandler test seam, so no subprocess is spawned), the default resolves to Cmd+Ctrl+D, it's conflict-free, and it's in settingsVisibleActions.

Closes #5169

🤖 Generated with Claude Code


View with Codesmith Autofix with Codesmith
Need help on this PR? Tag @codesmith with what you need. Autofix is disabled.


Note

Low Risk
UI and shortcut wiring around an existing CLI spawn path; no auth or data-model changes, with minor subprocess-launch surface consolidated from the palette.

Overview
Adds a first-class Open Diff Viewer keyboard shortcut (default ⌃⌘⇧D) that opens unstaged diffs for the focused workspace via the bundled cmux diff CLI, rebindable in Settings and cmux.json like other shortcuts.

⌃⌘⇧D avoids macOS swallowing plain ⌃⌘D (“Look Up”) and conflicts with existing ⌘D split chords. Settings, ShortcutAction, docs (cmux-shortcuts.ts), search synonyms, and broad shortcut.openDiffViewer.label localizations are wired through.

Diff launching is centralized in AppDelegate.openDiffViewerForFocusedWorkspace(for:) with subprocess retention and safer DEBUG logging; the command palette and the new shortcut both call it. ContentView drops its duplicate launcher. Workspace.resolvedWorkingDirectory() picks the cwd for diff/commands (focused panel → terminal request → workspace directory).

Failures beep, matching the palette. A routing test uses debugOpenDiffViewerHandler so no real subprocess runs.

Reviewed by Cursor Bugbot for commit f5c3051. Bugbot is set up for automated code reviews on this repo. Configure here.


Summary by cubic

Adds a configurable keyboard shortcut to open the diff viewer for the focused workspace through the same shared path as the command palette. Default is Cmd+Ctrl+Shift+D to avoid macOS “Look Up” and split-view conflicts (addresses #5169).

  • New Features

    • Added openDiffViewer action, visible in Settings → Keyboard Shortcuts and configurable via ~/.config/cmux/cmux.json (shortcuts.openDiffViewer); default Cmd+Ctrl+Shift+D with palette-style beep on failure.
    • Updated docs (web/data/cmux-shortcuts.ts) and added label localization across all catalog locales.
  • Refactors

    • Centralized diff launching in AppDelegate.openDiffViewerForFocusedWorkspace(...) (spawns cmux diff --unstaged ...), with subprocess retention in production and sanitized DEBUG logs (pid/status/output-bytes); palette now calls this shared path. Fixed Release build by hoisting diffViewerProcesses out of #if DEBUG and gating debugOpenDiffViewerHandler behind DEBUG.
    • Added Workspace.resolvedWorkingDirectory() with an explicit fallback order (focused panel’s tracked directory → its terminal’s requested directory → workspace’s current directory). Updated dispatch test to assert the Cmd+Ctrl+Shift+D default, no conflicts, and shared-path routing.

Written for commit f5c3051. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • New Features

    • Added a keyboard shortcut (Cmd+Ctrl+Shift+D) and command-palette action to open the Diff Viewer for the focused workspace; launching uses a single shared path and selects an appropriate working directory (workspace or home). Failures produce an audible alert.
  • Localization

    • Added localized labels for the Diff Viewer shortcut (including English and Japanese).
  • Tests

    • Added a test ensuring the default shortcut routes to the shared Diff Viewer path and is configurable in Settings.

cmux already opens the diff viewer via the `cmux diff` CLI and the
"Open Diff Viewer" command-palette entry (which spawns that CLI). This
adds a first-class, user-rebindable keyboard shortcut that opens the
diff viewer for the focused workspace through the same shared path, with
no duplicated diff-open logic.

- Register an `openDiffViewer` action in KeyboardShortcutSettings (label
  "Open Diff Viewer"); it is automatically visible/editable in Settings
  and configurable via ~/.config/cmux/cmux.json.
- Default Cmd+Ctrl+D: Cmd+Shift+D collides with Split Down and the whole
  Cmd-based "D" family is taken by split actions, so use Cmd+Ctrl+D,
  which is free and matches cmux's Cmd+Ctrl+<letter> app-shortcut family
  (Close Window, Toggle Full Screen).
- Extract the command palette's diff launcher into a shared
  AppDelegate.openDiffViewerForFocusedWorkspace(for:); the palette and
  the shortcut both call it (spawning `cmux diff`). Lift cwd resolution
  to Workspace.resolvedWorkingDirectory().
- Update docs (web/data/cmux-shortcuts.ts feeds both the keyboard
  shortcut and configuration docs pages) and add en/ja localization.
- Add a dispatch test asserting Cmd+Ctrl+D routes to the shared path and
  that the default is conflict-free.

Closes #5169

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@vercel

vercel Bot commented Jun 2, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
cmux Ready Ready Preview, Comment Jun 2, 2026 11:05am
cmux-staging Building Building Preview, Comment Jun 2, 2026 11:05am

@coderabbitai

coderabbitai Bot commented Jun 2, 2026 •

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

Pull request was closed or merged during review

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds a configurable Cmd+Ctrl+Shift+D keyboard shortcut and central AppDelegate entrypoint to open the diff viewer for the focused workspace; implements subprocess launch/retention, workspace cwd resolution, command-palette wiring, a routing test, and localization/web shortcut metadata.

Changes

Open Diff Viewer Keyboard Shortcut

Layer / File(s) Summary
Shortcut Action Definition
Sources/KeyboardShortcutSettings.swift, Packages/CmuxSettings/..., Packages/CmuxSettings/Sources/CmuxSettings/Values/ShortcutAction+Defaults.swift, web/data/cmux-shortcuts.ts, Resources/Localizable.xcstrings
New openDiffViewer action added to KeyboardShortcutSettings and ShortcutAction (defaults, display name, and group). Default shortcut set to Cmd+Ctrl+Shift+D; web shortcut metadata and localization key shortcut.openDiffViewer.label added.
Workspace cwd resolution & AppDelegate launch
Sources/Workspace.swift, Sources/AppDelegate.swift
Adds Workspace.resolvedWorkingDirectory() and AppDelegate.openDiffViewerForFocusedWorkspace() plus launchDiffViewerProcess() which spawns cmux diff with focused workspace/surface and cwd, retains subprocesses, streams output, and handles exit. Includes DEBUG test seam and PID-retained process map; wires shortcut dispatch.
Command Palette Integration
Sources/ContentView.swift
Command-palette openDiffViewer now delegates to AppDelegate.openDiffViewerForFocusedWorkspace(); configuredActionBaseCwd() uses Workspace.resolvedWorkingDirectory() with home fallback.
Shortcut Routing Test Coverage
cmuxTests/AppDelegateShortcutRoutingTests.swift
Test verifies default Cmd+Ctrl+Shift+D binding, Settings visibility, normalized acceptance, and that the key event routes to the shared debugOpenDiffViewerHandler and is consumed without launching a subprocess.
Curated settings synonyms
Packages/CmuxSettingsUI/Sources/CmuxSettingsUI/Navigation/CuratedSettingEntry+Default.swift
Expands keyboardShortcuts curated entry synonyms to include additional shortcut/diff-related search keywords.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • manaflow-ai/cmux#4451: Implements the cmux diff CLI subcommand invoked by the subprocess launcher added in this PR.
  • manaflow-ai/cmux#4445: Overlaps AppDelegate shortcut routing/dispatch changes used by this PR.
  • manaflow-ai/cmux#4406: Touches the same AppDelegate shortcut handling/dispatch path that this PR extends.

Poem

🐇 I tapped Cmd+Ctrl+Shift+D with glee,
The diff viewer hopped up for me,
One shared route, no duplicated maze,
Subprocess launched, the rabbit lauds the ways,
Reviews made light — hop, click, and see!


Caution

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

  • Ignore

❌ Failed checks (1 error, 1 warning)

Check name Status Explanation Resolution
Cmux Architecture Rethink ❌ Error Test seam debugOpenDiffViewerHandler bypasses focused-workspace precondition check, masking production invariant and allowing test to pass if workspace resolution breaks. Move guard let workspace check before #if DEBUG block to validate the seam only after precondition is verified.
Docstring Coverage ⚠️ Warning Docstring coverage is 14.29% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (16 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: adding a configurable keyboard shortcut to open the diff viewer.
Description check ✅ Passed The PR description is comprehensive, covering what changed, why, default shortcut choice with conflict analysis, and tests. However, testing instructions and demo video sections are absent from the description template sections.
Linked Issues check ✅ Passed All coding requirements from #5169 are met: new openDiffViewer action with label, visible in Settings and configurable via cmux.json, shared diff-open path reused, dispatch logic added with test, docs updated, non-conflicting default chosen (Cmd+Ctrl+Shift+D).
Out of Scope Changes check ✅ Passed All changes are scoped to the stated objectives: adding the keyboard shortcut feature, centralizing diff launching, adding localization, updating docs, and adding tests. No unrelated changes detected.
Cmux Swift Actor Isolation ✅ Passed AppDelegate and Workspace are @MainActor, diffViewerProcesses is private on MainActor, terminationHandler wraps accesses in Task @MainActor, ShortcutAction is Sendable—no isolation violations.
Cmux Swift Blocking Runtime ✅ Passed New diff viewer code avoids blocking patterns: uses async subprocess launching with termination callbacks instead of blocking waits or sleeps.
Cmux No Hacky Sleeps ✅ Passed No hacky sleeps, timers, or fixed delays found in non-Swift code. Only change is adding a shortcut entry to web/data/cmux-shortcuts.ts data structure.
Cmux Algorithmic Complexity ✅ Passed All new code maintains O(1) complexity on scalable collections: resolvedWorkingDirectory() uses fixed 3-element array with O(1) lookups; no loops over workspaces/panels or nested scans detected.
Cmux Swift Concurrency ✅ Passed Task { @MainActor in } in process.terminationHandler is a legitimate callback boundary pattern with precedent in CloudVMActionLauncher and AppDelegate+CmuxSSHURL. No new problematic async patterns.
Cmux Swift @Concurrent ✅ Passed New Swift methods are synchronous (not async), properly @MainActor-isolated, and correctly use Task { @MainActor } for callbacks. No missing or invalid @concurrent annotations.
Cmux Swift File And Package Boundaries ✅ Passed Moves diff launcher from ContentView to AppDelegate: +126 lines (under 250 limit). Subprocess launching is existing AppDelegate pattern. No oversized new files, no responsibility mixing.
Cmux Swift Logging ✅ Passed All logging in new diff-viewer code is #if DEBUG guarded with cmuxDebugLog; no print/debugPrint/dump/NSLog in production code; no secrets exposed; fully compliant with swift-logging.md.
Cmux User-Facing Error Privacy ✅ Passed All user-facing text is generic ("Open Diff Viewer"). DEBUG logging is safe. Error handling silent. No vendor names, internal details, or sensitive data exposed to users.
Cmux Full Internationalization ✅ Passed All user-facing strings properly localized: KeyboardShortcutSettings uses String(localized:) for 20 locales; web shortcuts use en+ja per design pattern.
Cmux Swiftui State Layout ✅ Passed PR adds model/AppKit code and removes duplicate ContentView logic. No new @Published/@StateObject/@State in SwiftUI Views, GeometryReader layout changes, or render-time mutations.
Cmux Swift Auxiliary Window Close Shortcuts ✅ Passed PR adds diff viewer shortcut by spawning subprocess only; no NSWindow, NSPanel, NSWindowController, or SwiftUI Window/WindowGroup objects created requiring cmux.* identifiers.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch issue-5169-diff-viewer-shortcut

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 Jun 2, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

Adds a configurable Cmd+Ctrl+Shift+D keyboard shortcut to open the diff viewer for the focused workspace. The diff-launch logic previously duplicated inside CommandPaletteDiffViewerLauncher (in ContentView.swift) is extracted into AppDelegate.openDiffViewerForFocusedWorkspace(for:), and both the command palette and the new shortcut now call that single path.

  • Centralized diff launch: launchDiffViewerProcess handles subprocess creation, pipe draining, process retention, and async beep-on-failure; the old CommandPaletteDiffViewerLauncher class is deleted.
  • Workspace.resolvedWorkingDirectory(): three-tier CWD fallback (panel tracked dir → terminal requested dir → workspace current dir) extracted from ContentView and reused by both the diff path and configured-action CWD resolution.
  • Full localization: shortcut.openDiffViewer.label covers all 20 app locales in Localizable.xcstrings; web docs entry in cmux-shortcuts.ts follows the existing en/ja-only LocalizedText type constraint; shortcut default is exposed to settingsVisibleActions and the cmux.json config store.

Confidence Score: 5/5

Safe to merge — the change is a straightforward shortcut wiring and subprocess-launch refactor with no new data paths or auth surfaces.

The diff-launch logic is correctly centralized, actor isolation is handled (termination-handler mutations go through Task @mainactor), all 20 app locales are covered, and the test seam prevents subprocess spawning in CI. No correctness issues found in the changed paths.

No files require special attention.

Important Files Changed

Filename Overview
Sources/AppDelegate.swift Adds openDiffViewerForFocusedWorkspace and launchDiffViewerProcess; moves subprocess management from ContentView, retains processes in a diffViewerProcesses dict, drains pipes in termination handler, and adds the handleCustomShortcut branch for .openDiffViewer. Actor isolation is correct (Task @mainactor for dict mutations from the background termination handler).
Sources/ContentView.swift Removes the now-obsolete CommandPaletteDiffViewerLauncher class and openDiffViewerFromCommandPalette; command-palette registration now delegates to AppDelegate.shared?.openDiffViewerForFocusedWorkspace. configuredActionBaseCwd() collapses to a one-liner calling Workspace.resolvedWorkingDirectory().
Sources/Workspace.swift Adds resolvedWorkingDirectory() extracting the three-tier CWD fallback previously duplicated in ContentView and AppDelegate.
Sources/KeyboardShortcutSettings.swift Adds .openDiffViewer case with localized label and default Cmd+Ctrl+Shift+D; comment explains why Cmd+Ctrl+D is reserved by macOS.
Resources/Localizable.xcstrings Adds shortcut.openDiffViewer.label with translations for all 20 supported app locales, addressing the gap from the prior review thread.
cmuxTests/AppDelegateShortcutRoutingTests.swift Adds routing test asserting conflict-free default, settingsVisibleActions membership, and shared-path dispatch via debugOpenDiffViewerHandler test seam.
web/data/cmux-shortcuts.ts Adds openDiffViewer entry with correct combo and en/ja descriptions matching the LocalizedText type used throughout the file.

Sequence Diagram

sequenceDiagram
    participant User
    participant AppKit as AppKit Event Monitor
    participant AD as AppDelegate
    participant WS as Workspace
    participant CLI as cmux diff CLI

    Note over User,CLI: Keyboard shortcut path (new)
    User->>AppKit: Cmd+Ctrl+Shift+D key event
    AppKit->>AD: handleCustomShortcut(event:)
    AD->>AD: matchConfiguredShortcut(.openDiffViewer)
    AD->>AD: openDiffViewerForFocusedWorkspace(for: tabManager)
    AD->>WS: resolvedWorkingDirectory()
    WS-->>AD: cwd string
    AD->>AD: launchDiffViewerProcess(...)
    AD->>CLI: Process.run()
    CLI-->>AD: terminationHandler (background)
    AD->>AD: "Task @MainActor remove from diffViewerProcesses"

    Note over User,CLI: Command palette path (unchanged)
    User->>AD: palette.openDiffViewer
    AD->>AD: openDiffViewerForFocusedWorkspace(for: tabManager)
    AD->>CLI: same launchDiffViewerProcess path
Loading

Reviews (7): Last reviewed commit: "Fix Open Diff Viewer: show in Settings U..." | Re-trigger Greptile

Comment thread Resources/Localizable.xcstrings

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

1 issue found across 7 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread Sources/Workspace.swift

@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: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@Sources/AppDelegate.swift`:
- Around line 5945-5956: The debug logging in the openDiffViewer exit path
(around outputCollector.finish(), terminatedProcess.processIdentifier and
terminatedProcess.terminationStatus) currently emits raw child process output
and workspace paths via cmuxDebugLog; change it to avoid any raw stdout/stderr
or cwd strings and instead log only non-sensitive metadata: terminationStatus,
processIdentifier, and a byte/character count of the trimmed output (e.g.,
output.count or limitedDetail.count), and remove any direct detail or path
contents; apply the same change to the other similar cmuxDebugLog usage that
logs diff-viewer output so both places report status, ids and size only.

In `@web/data/cmux-shortcuts.ts`:
- Around line 223-227: The shortcut entry openDiffViewer in cmux-shortcuts.ts
currently provides description only for en and ja so other locales fall back to
English; update localization by moving the description strings into next-intl
message keys (e.g., "shortcuts.openDiffViewer") and replace the hardcoded
description object in openDiffViewer with a reference that resolves via the same
i18n pipeline used by keyboard-shortcuts.tsx, or alternatively add explicit
localized strings for every supported locale from your routing list; ensure
keyboard-shortcuts.tsx reads the message key for rendering so all locales get
proper translations rather than defaulting to English.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: c3e3544f-ae9c-4990-a69d-e89d9ad8eae6

📥 Commits

Reviewing files that changed from the base of the PR and between 9eece11 and b759ca2.

📒 Files selected for processing (7)
  • Resources/Localizable.xcstrings
  • Sources/AppDelegate.swift
  • Sources/ContentView.swift
  • Sources/KeyboardShortcutSettings.swift
  • Sources/Workspace.swift
  • cmuxTests/AppDelegateShortcutRoutingTests.swift
  • web/data/cmux-shortcuts.ts

Comment thread Sources/AppDelegate.swift Outdated
Comment thread web/data/cmux-shortcuts.ts
…g logs

- Populate all 20 catalog locales for shortcut.openDiffViewer.label,
  reusing command.openDiffViewer.title's existing translations (identical
  English source). [greptile P1]
- resolvedWorkingDirectory() now delegates to the existing
  configTrackingDirectory(for:) helper instead of duplicating the
  candidate-resolution logic. [cubic P3]
- Diff-viewer DEBUG logs report only status, pid, and an output byte
  count — no raw child output or workspace cwd. [coderabbit]

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

@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: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@Sources/AppDelegate.swift`:
- Around line 6026-6028: The debug log in the openDiffViewer failure currently
prints error.localizedDescription which may contain file paths; change the log
to avoid sensitive content by logging only the error type (e.g., type(of:
error)) and any already-redacted metadata (do not include raw startup commands,
cwd, or localizedDescription). Update the call to cmuxDebugLog in the
openDiffViewer failure path to emit a non-sensitive message containing the
error's type and contextual, non-private flags/ids/byte counts instead of
error.localizedDescription.

In `@Sources/Workspace.swift`:
- Around line 11593-11597: resolvedWorkingDirectory() currently returns only
configTrackingDirectory(for: focusedPanelId); update it to implement the
documented 3-tier fallback: if configTrackingDirectory(for: focusedPanelId) is
non-nil return it, otherwise try terminalRequestedDirectory(for:
focusedPanelId), and if that is nil return the workspace property
currentDirectory (or nil if currentDirectory is nil) so the function returns the
first non-nil of configTrackingDirectory(for:),
terminalRequestedDirectory(for:), and currentDirectory.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: a52699a1-cb36-4826-bde6-d066dd7e1cec

📥 Commits

Reviewing files that changed from the base of the PR and between 613e5e3 and fdcdd19.

📒 Files selected for processing (3)
  • Resources/Localizable.xcstrings
  • Sources/AppDelegate.swift
  • Sources/Workspace.swift

Comment thread Sources/AppDelegate.swift
Comment thread Sources/Workspace.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.

1 issue found across 3 files (changes from recent commits).

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread Sources/AppDelegate.swift Outdated
…ebug seam

`diffViewerProcesses` and the `debugOpenDiffViewerHandler` test seam were
declared inside AppDelegate's `#if DEBUG` block, but
`openDiffViewerForFocusedWorkspace`/`launchDiffViewerProcess` referenced them
unconditionally — so the Release build failed with "cannot find
'debugOpenDiffViewerHandler' in scope" and "no member 'diffViewerProcesses'"
(release-build CI job; the Debug `tests` build compiled fine, which is why it
slipped through initially).

- `diffViewerProcesses` is production state (CLI process retention) → declared
  outside `#if DEBUG`.
- `debugOpenDiffViewerHandler` stays a DEBUG-only seam; its use is now
  `#if DEBUG`-gated, matching the existing `debugCloseMainWindowConfirmationHandler`
  pattern.

Verified with a local `xcodebuild -configuration Release` (arm64): the cmux app
target compiles cleanly.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ailure

Process spawn failures surface file paths via error.localizedDescription
(e.g. "The file doesn't exist at /path/to/bin/cmux"). Consistent with the
rest of this DEBUG log's path/output redaction, log type(of: error) instead.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ngDirectory

CodeRabbit (blocking) flagged that the delegating one-liner didn't visibly honor
the documented three-tier order. Spell the tiers out in the method body —
panelDirectories[focusedPanelId] -> focused terminal's requestedWorkingDirectory
-> currentDirectory -> nil — matching configTrackingDirectory(for:)'s behavior.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

@cursor cursor 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.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit c79752d. Configure here.

Comment thread Sources/Workspace.swift
…'t eat

Two real bugs the first pass missed (verified by driving the running app):

1. Settings UI: the keyboard-shortcuts pane is rendered from the
   CmuxSettings.ShortcutAction package enum, NOT KeyboardShortcutSettings.Action.
   `openDiffViewer` was never added there, so "Open Diff Viewer" never appeared in
   Settings and couldn't be rebound in the UI. Add the case (+ group, displayName,
   defaultStroke) and a search synonym so "open diff" surfaces the Keyboard
   Shortcuts section.

2. Default shortcut: macOS reserves Cmd+Ctrl+D for "Look Up & data detectors" and
   swallows the key before it reaches the app's monitor (confirmed: a Cmd+Ctrl+D
   keystroke never reaches handleCustomShortcut, while Cmd+, does). The rest of the
   Cmd+D family is taken by split actions, so move the default to Cmd+Ctrl+Shift+D,
   which reaches cmux and opens the viewer (verified end-to-end).

Updates the dispatch test and the keyboard-shortcut/configuration docs accordingly.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@austinywang

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

All previously-flagged items are addressed in the latest commits:

  • error.localizedDescription path leak → now logs type(of: error) (c05d39c)
  • resolvedWorkingDirectory() → inlined the explicit three-tier fallback (c79752d)
  • xcstrings → all 20 locales added; web i18n is en/ja-by-design for the whole shortcuts file (you accepted this)

Also fixed two functional bugs since: the shortcut now appears in the Settings UI (added to the CmuxSettings.ShortcutAction registry), and the default moved off the macOS-reserved Cmd+Ctrl+D to Cmd+Ctrl+Shift+D. Please re-review.

@coderabbitai

coderabbitai Bot commented Jun 2, 2026

Copy link
Copy Markdown

@austinywang Thanks for the detailed summary of what's been addressed! I'll kick off a fresh review of the updated commits now.

✅ Actions performed

Full review triggered.

@austinywang
austinywang merged commit 6c5ffc5 into main Jun 2, 2026
21 of 22 checks passed
@austinywang austinywang mentioned this pull request Jun 2, 2026

This branch was successfully deployed

1 active deployment
Preview – cmux — f5c3051b Deployed Jun 2, 2026 by vercel[bot]
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.

Add a configurable keyboard shortcut to open the diff viewer

1 participant