Skip to content

Add Claude Binary Path setting - #2514

Merged
lawrencecchen merged 4 commits into
mainfrom
feat-custom-claude-path
Apr 1, 2026
Merged

lawrencecchen merged 4 commits into
mainfrom
feat-custom-claude-path

Conversation

@lawrencecchen

@lawrencecchen lawrencecchen commented Apr 1, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Adds a "Claude Binary Path" text field in Settings > Automation > Claude Code Integration
  • When set, the custom path takes priority over PATH lookup in the bundled claude wrapper, cmux claude-teams CLI, and UserDefaults
  • Solves the case where users have claude installed outside PATH or aliased in their shell profile

Test plan

  • Open Settings > Automation, verify new "Claude Binary Path" field appears below the hooks toggle
  • Leave empty, verify claude and cmux claude-teams resolve via PATH as before
  • Set to a valid claude binary path, verify it's used instead of PATH
  • Set to an invalid path, verify fallback to PATH resolution
  • Reset all settings, verify the field clears

Summary by cubic

Added a “Claude Binary Path” setting so users can point to a specific claude binary when PATH or aliases don’t apply. It’s in its own settings card and is respected by the claude wrapper, cmux claude-teams, and terminal sessions via CMUX_CUSTOM_CLAUDE_PATH, with safe fallbacks.

  • New Features

    • Respects CMUX_CUSTOM_CLAUDE_PATH and UserDefaults key claudeCodeCustomClaudePath; resolution: custom → PATH lookup → bundled binary.
    • App injects CMUX_CUSTOM_CLAUDE_PATH per session so shells use the chosen binary.
    • Localized UI (EN/JA); Reset All clears the field.
  • Bug Fixes

    • Trim whitespace, ignore empty values, and require real executables; reject directories.
    • Use a symlink-safe self-reference guard (-ef) to skip the wrapper itself.

Written for commit 66d286e. Summary will update on new commits.

Summary by CodeRabbit

  • New Features

    • Added a “Claude Binary Path” setting so users can specify a custom Claude executable; the app now prefers this custom path (from settings or a launcher-provided env) when launching Claude Code and Reset Settings clears it.
    • The per-surface runtime environment now includes the configured custom path so launched sessions use the specified binary when applicable.
  • Localization

    • Added English and Japanese labels, placeholder, and subtitle for the custom Claude path setting.

Users who install claude outside PATH (or wrap it with aliases) can now
set an explicit path in Settings > Automation > Claude Code. The setting
is respected by the bundled claude wrapper, claude-teams CLI, and
UserDefaults fallback.
@vercel

vercel Bot commented Apr 1, 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 Apr 1, 2026 11:09pm

@coderabbitai

coderabbitai Bot commented Apr 1, 2026 •

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: f5db4861-442c-4efe-a248-8248c5f27027

📥 Commits

Reviewing files that changed from the base of the PR and between b9fc1eb and 66d286e.

📒 Files selected for processing (2)
  • CLI/cmux.swift
  • Resources/bin/claude
🚧 Files skipped from review as they are similar to previous changes (2)
  • Resources/bin/claude
  • CLI/cmux.swift

📝 Walkthrough

Walkthrough

Adds a user-configurable Claude executable path: persisted UserDefaults key and Settings UI, managed environment injection of CMUX_CUSTOM_CLAUDE_PATH, CLI/wrapper resolution updated to prefer custom paths (env → UserDefaults → PATH/bundled) and still avoid the CMUX wrapper.

Changes

Cohort / File(s) Summary
Settings & UI
Sources/cmuxApp.swift
New claudeCodeCustomClaudePath key and customClaudePath(defaults:); @AppStorage TextField for "Claude Binary Path"; reset clears value.
Localization
Resources/Localizable.xcstrings
Added settings.automation.claudeCode.customPath, .placeholder, and .subtitle (en/ja) for the new settings UI.
CLI executable resolution
CLI/cmux.swift
runClaudeTeams now checks CMUX_CUSTOM_CLAUDE_PATH then stored claudeCodeCustomClaudePath (trimmed, non-empty, executable, not wrapper) before falling back to PATH/bundled search; execv/execvp selection preserved.
Managed env injection (runtime)
Sources/GhosttyTerminalView.swift
Sets CMUX_CUSTOM_CLAUDE_PATH in per-surface managed startup environment when a custom path exists.
Wrapper script
Resources/bin/claude
find_real_claude() now returns CMUX_CUSTOM_CLAUDE_PATH immediately when set, trimmed, executable, and not the wrapper itself; otherwise retains prior PATH/bundled lookup logic.

Sequence Diagram

sequenceDiagram
    participant User
    participant Settings as Settings UI
    participant Storage as UserDefaults
    participant Ghostty as GhosttyTerminalView
    participant CLI as CLI/cmux.swift
    participant Wrapper as Resources/bin/claude
    participant Claude as Claude Binary

    User->>Settings: set custom Claude path
    Settings->>Storage: save claudeCodeCustomClaudePath
    User->>Ghostty: launch Claude integration
    Ghostty->>Storage: read customClaudePath()
    alt custom path present
        Ghostty->>Ghostty: set CMUX_CUSTOM_CLAUDE_PATH
    end
    Ghostty->>CLI: exec Claude integration (managed env)
    CLI->>CLI: check CMUX_CUSTOM_CLAUDE_PATH (trim, executable, not wrapper)
    alt env custom valid
        CLI->>Claude: execv(custom path)
    else
        CLI->>Storage: read claudeCodeCustomClaudePath (trim, executable, not wrapper)
        alt stored custom valid
            CLI->>Claude: execv(stored custom path)
        else
            CLI->>Wrapper: execvp("claude")
            Wrapper->>Wrapper: find_real_claude() (considers CMUX_CUSTOM_CLAUDE_PATH then PATH/bundled)
            Wrapper->>Claude: exec real claude
        end
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐰 I sniffed the paths where binaries hide,
A custom trail the user laid with pride,
From prefs to env the rabbit paved the way,
So Claude can hop in, no lost ballet,
🥕 Tiny hops, clean code, and carrots all day.

🚥 Pre-merge checks | ✅ 2 | ❌ 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 (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: adding a Claude Binary Path setting. It directly relates to the primary feature introduced across all modified files.
Description check ✅ Passed The description covers the summary and test plan sections from the template, though the Demo Video, Review Trigger, and Checklist sections are incomplete or missing.

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

✨ 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 feat-custom-claude-path

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.

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 44e2d6039a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread Resources/bin/claude Outdated
Comment on lines +12 to +14
if [[ -n "${CMUX_CUSTOM_CLAUDE_PATH:-}" && -x "$CMUX_CUSTOM_CLAUDE_PATH" ]]; then
printf '%s' "$CMUX_CUSTOM_CLAUDE_PATH"
return 0

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Prevent wrapper from exec'ing itself via custom path

In find_real_claude, the new CMUX_CUSTOM_CLAUDE_PATH branch accepts any executable path without excluding the wrapper itself. If a user sets “Claude Binary Path” to the cmux wrapper path (a realistic mistake after running which claude inside cmux), the script resolves REAL_CLAUDE to itself and repeatedly execs itself, hanging claude invocations instead of falling back to PATH. Please reject self-references (and symlinks to self) before returning the custom path.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed. Wrapper now resolves both paths and compares, skipping if custom path points to itself. Also uses -f to reject directories.

— Claude Code

Separates it from the hooks toggle so the note text clearly applies
only to the integration toggle.
@greptile-apps

greptile-apps Bot commented Apr 1, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds a "Claude Binary Path" setting under Settings > Automation > Claude Code Integration, allowing users to point cmux at a claude binary that lives outside their PATH. The custom path is stored in UserDefaults, injected as CMUX_CUSTOM_CLAUDE_PATH into every new terminal surface, and honored in both the bundled Resources/bin/claude shell wrapper and the cmux claude-teams CLI — with graceful fallback to normal PATH resolution when the path is empty or non-executable. Localization (EN + JA) is properly covered.

Key findings:

  • Missing whitespace trim — ClaudeCodeIntegrationSettings.customClaudePath() does not call .trimmingCharacters(in: .whitespacesAndNewlines) before the empty check, unlike the analogous PreferredEditorSettings.resolvedCommand() in the same file. A path entered with accidental leading/trailing spaces will silently fail the executability check and fall back to PATH with no user feedback.
  • Silent env-var override — In the cmux claude-teams CLI, CMUX_CUSTOM_CLAUDE_PATH from the process environment is checked before the UserDefaults value. Any external process or shell config that sets this variable will silently override whatever the user configured in Settings, which may be surprising.
  • Narrow text field — The TextField is pinned to 200 pt, which is often insufficient for real file-system paths and forces users to scroll to verify the full entry.

Confidence Score: 3/5

  • Safe to merge with minor fixes — the missing whitespace trim is a P1 that causes silent fallback but does not break the fallback path itself.
  • Core logic is sound: every consumer validates executability before using the custom path, so invalid or mistyped paths always fall back gracefully. However, the missing whitespace trim in customClaudePath() means a plausible user error (trailing space) produces a silent failure, which is inconsistent with how similar settings are handled elsewhere in the file. The fixed-width text field is a UX concern but not a blocker.
  • Sources/cmuxApp.swift — the customClaudePath() helper and the Settings TextField width both need attention before merge.

Important Files Changed

Filename Overview
CLI/cmux.swift Adds two-source custom-path lookup (env var then UserDefaults) before falling back to PATH/bundled binary; logic is correct but the env-var-first precedence creates a silent override over the Settings UI value.
Resources/bin/claude Shell wrapper correctly checks CMUX_CUSTOM_CLAUDE_PATH with -x (executable) guard at the top of find_real_claude() before the PATH scan; fallback behavior is preserved.
Sources/GhosttyTerminalView.swift Injects CMUX_CUSTOM_CLAUDE_PATH into new terminal surfaces when a non-empty custom path is stored; downstream scripts and CLI validate executability before using it, so invalid paths gracefully fall back.
Sources/cmuxApp.swift Adds customClaudePathKey, customClaudePath() helper, @AppStorage binding, Settings UI row, and reset logic; customClaudePath() is missing whitespace trimming (unlike the analogous PreferredEditorSettings.resolvedCommand()), and the 200 pt fixed-width text field is too narrow for typical file-system paths.
Resources/Localizable.xcstrings Adds English and Japanese translations for the three new string keys (label, subtitle, placeholder); both locales are present and consistent with the surrounding file's format.

Sequence Diagram

sequenceDiagram
    participant User
    participant SettingsUI as Settings UI (cmuxApp.swift)
    participant UserDefaults
    participant TerminalSurface as GhosttyTerminalView
    participant ShellWrapper as Resources/bin/claude
    participant CLI as cmux claude-teams (CLI/cmux.swift)
    participant RealClaude as Real claude binary

    User->>SettingsUI: Enter custom claude path
    SettingsUI->>UserDefaults: Store via @AppStorage(claudeCodeCustomClaudePath)

    User->>TerminalSurface: Open new terminal
    TerminalSurface->>UserDefaults: customClaudePath() → non-empty string?
    alt Non-empty path
        TerminalSurface->>TerminalSurface: setManagedEnv(CMUX_CUSTOM_CLAUDE_PATH, path)
    end

    User->>ShellWrapper: runs `claude` in terminal
    ShellWrapper->>ShellWrapper: find_real_claude()
    alt CMUX_CUSTOM_CLAUDE_PATH set & executable
        ShellWrapper->>RealClaude: exec custom path
    else
        ShellWrapper->>ShellWrapper: scan PATH (skip self dir)
        ShellWrapper->>RealClaude: exec PATH-resolved binary
    end

    User->>CLI: cmux claude-teams
    CLI->>CLI: check CMUX_CUSTOM_CLAUDE_PATH env var + isExecutable
    alt env var valid
        CLI->>RealClaude: execv(custom path)
    else
        CLI->>UserDefaults: read claudeCodeCustomClaudePath + isExecutable
        alt UserDefaults value valid
            CLI->>RealClaude: execv(UserDefaults path)
        else
            CLI->>RealClaude: execvp("claude") via PATH / bundled binary
        end
    end
Loading

Reviews (1): Last reviewed commit: "Move Claude Binary Path to its own setti..." | Re-trigger Greptile

Comment thread Sources/cmuxApp.swift
Comment on lines 5393 to +5403

SettingsCard {
SettingsCardRow(
String(localized: "settings.automation.claudeCode.customPath", defaultValue: "Claude Binary Path"),
subtitle: String(localized: "settings.automation.claudeCode.customPath.subtitle", defaultValue: "Custom path to the claude binary. Leave empty to use PATH.")
) {
TextField(
String(localized: "settings.automation.claudeCode.customPath.placeholder", defaultValue: "e.g. /usr/local/bin/claude"),
text: $customClaudePath
)
.textFieldStyle(.roundedBorder)

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 Fixed-width text field may be too narrow for long paths

The TextField is constrained to 200 points, which is often insufficient for real filesystem paths (e.g., /Users/username/.volta/bin/claude or paths inside Homebrew's opt tree). Users will need to scroll within the field to verify what they typed, which makes accidental typos hard to spot.

Consider using .frame(maxWidth: .infinity) or a larger fixed width, or following the pattern used for the "Preferred Editor" field elsewhere in the view, to give users enough room to read the full path they've entered.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Comment thread CLI/cmux.swift
Comment on lines +9691 to +9702
let claudeExecutablePath: String? = {
// Check custom path from Settings > Automation > Claude Code
if let custom = launcherEnvironment["CMUX_CUSTOM_CLAUDE_PATH"],
!custom.isEmpty,
FileManager.default.isExecutableFile(atPath: custom) {
return custom
}
if let custom = UserDefaults.standard.string(forKey: "claudeCodeCustomClaudePath"),
!custom.isEmpty,
FileManager.default.isExecutableFile(atPath: custom) {
return custom
}

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 CMUX_CUSTOM_CLAUDE_PATH env var overrides the Settings UI silently

The two-source lookup has a subtle precedence issue: any process that injects CMUX_CUSTOM_CLAUDE_PATH into the environment before invoking cmux claude-teams will silently override whatever the user configured in Settings > Automation. This includes the GUI app itself (which sets the env var from the UserDefaults value in GhosttyTerminalView.swift), but also any external script or shell function that happens to set this variable.

In practice, for the GUI-launched path the env var and UserDefaults are always in sync (both come from the same UserDefaults key), so the env-var branch will always win for that case and the UserDefaults branch is effectively dead code in GUI-launched terminals. The UserDefaults branch is only reachable when cmux claude-teams is run directly from the shell without the app setting the env var.

This is probably intentional, but it's worth confirming that having a hidden override mechanism (env var) that takes priority over the visible Settings UI is the desired UX — particularly because there is no user-visible indication that a different path is being used when the env var is set externally.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The env var taking precedence over UserDefaults is intentional: the app sets it per-session from the same UserDefaults value. The env var path exists so the bundled wrapper script can read the setting without accessing UserDefaults directly. In practice they always agree.

— Claude Code

Comment thread Sources/cmuxApp.swift
Comment on lines +3933 to +3936
static func customClaudePath(defaults: UserDefaults = .standard) -> String? {
let value = defaults.string(forKey: customClaudePathKey) ?? ""
return value.isEmpty ? nil : value
}

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.

P1 Missing whitespace trimming before use

customClaudePath() does not trim leading/trailing whitespace from the stored value. If a user accidentally enters a path with surrounding spaces, both FileManager.default.isExecutableFile(atPath:) in the CLI and the -x check in the shell wrapper will silently fail, causing a quiet fallback to PATH resolution with no indication of why the custom path was ignored.

This is inconsistent with the existing pattern used by PreferredEditorSettings.resolvedCommand() in the same file, which applies .trimmingCharacters(in: .whitespacesAndNewlines) before the empty check. The same trimming should be applied here to stay consistent and avoid confusing silent fallbacks.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed. customClaudePath() now trims whitespace before the empty check.

— Claude Code

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

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@CLI/cmux.swift`:
- Around line 9691-9709: The custom-path branches for claudeExecutablePath
accept unnormalized values and don't guard against pointing at our cmux wrapper;
normalize both environment and UserDefaults values (expand ~, trim whitespace,
resolve symlinks) before using FileManager checks, and additionally call
isCmuxClaudeWrapper(on the resolved path) to reject wrapper self-references; if
the normalized path is non-empty, executable, and not isCmuxClaudeWrapper,
return it, otherwise continue to the existing
resolveClaudeExecutable/bundledClaudePath fallback.

In `@Resources/bin/claude`:
- Around line 12-14: The check for a custom Claude path currently accepts
executable directories, which lets an invalid directory bypass PATH lookup;
change the guard around CMUX_CUSTOM_CLAUDE_PATH so it validates that the path
exists as a regular file and is executable (use a file-test + executable-test)
before printing and returning, ensuring directories are rejected and the script
falls back to PATH lookup; update the conditional that references
CMUX_CUSTOM_CLAUDE_PATH in the Resources/bin/claude entry point accordingly.

In `@Sources/cmuxApp.swift`:
- Around line 3933-3936: customClaudePath(defaults:) treats a string of only
whitespace as a valid path; change it to trim whitespace/newlines (e.g., use
trimmingCharacters(in: .whitespacesAndNewlines)) on the retrieved value and
return nil when the trimmed string is empty so whitespace-only entries are
treated as unset, preserving the existing default argument and behavior
otherwise.

In `@Sources/GhosttyTerminalView.swift`:
- Around line 3759-3761: Trim the custom Claude path before exporting and avoid
setting an empty/whitespace-only value: call
ClaudeCodeIntegrationSettings.customClaudePath(), apply .trimmingCharacters(in:
.whitespacesAndNewlines) to the result, and only call
setManagedEnvironmentValue("CMUX_CUSTOM_CLAUDE_PATH", trimmedPath) if
trimmedPath is not empty; otherwise do not set the environment variable. Ensure
you reference the existing ClaudeCodeIntegrationSettings.customClaudePath()
retrieval and the setManagedEnvironmentValue call.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: f6d14e03-ea40-4c4e-ba41-f5d58d5aa5ef

📥 Commits

Reviewing files that changed from the base of the PR and between e9b2090 and 44e2d60.

📒 Files selected for processing (5)
  • CLI/cmux.swift
  • Resources/Localizable.xcstrings
  • Resources/bin/claude
  • Sources/GhosttyTerminalView.swift
  • Sources/cmuxApp.swift

Comment thread CLI/cmux.swift
Comment thread Resources/bin/claude Outdated
Comment thread Sources/cmuxApp.swift
Comment thread Sources/GhosttyTerminalView.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 5 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="Sources/cmuxApp.swift">

<violation number="1" location="Sources/cmuxApp.swift:3934">
P2: Trim whitespace/newlines for the custom Claude path. As written, a whitespace-only value is treated as a path and still overrides PATH, so the wrapper won’t fall back to PATH even though the field appears empty.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread Sources/cmuxApp.swift Outdated
- Trim whitespace in customClaudePath() before returning
- CLI: skip custom path if it's the cmux wrapper (isCmuxClaudeWrapper)
- Wrapper: resolve real paths and skip if custom path == self
- Wrapper: use -f check to reject directories

@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 the current code and only fix it if needed.

Inline comments:
In `@CLI/cmux.swift`:
- Around line 9698-9703: The loop that selects a candidate path (the for raw in
candidates block) currently only checks
FileManager.default.isExecutableFile(atPath:) and isCmuxClaudeWrapper(at:),
which allows directories to be chosen; update the selection to also verify the
candidate is a regular file (e.g., guard FileManager.default.fileExists and that
it is not a directory / is a regular file) before checking executability and
isCmuxClaudeWrapper so directory-valued custom paths are rejected the same way
the wrapper's [[ -f ... && -x ... ]] check does.

In `@Resources/bin/claude`:
- Around line 18-20: The self-reference guard currently compares paths as
strings using custom_real and self_real which fails for symlinked wrappers;
change the if condition that compares custom_real and self_real to use the
filesystem identity test (-ef) so the script detects "same file" even through
symlinks (i.e., replace the string comparison in the if [[ ... ]] block with a
test using -ef against custom_real and self_real and preserve the existing
behavior of exiting/avoiding recursion when they refer to the same file).
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: e3cc5d67-2b4e-439f-ab17-7e31df58ac3d

📥 Commits

Reviewing files that changed from the base of the PR and between e7bd964 and b9fc1eb.

📒 Files selected for processing (3)
  • CLI/cmux.swift
  • Resources/bin/claude
  • Sources/cmuxApp.swift
🚧 Files skipped from review as they are similar to previous changes (1)
  • Sources/cmuxApp.swift

Comment thread CLI/cmux.swift
Comment thread Resources/bin/claude Outdated
- CLI: check isDirectory before accepting custom path
- Wrapper: use bash -ef test instead of string path comparison to catch
  symlinked self-references

This branch was successfully deployed

1 active deployment
Preview — 66d286ee Deployed Apr 1, 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.

1 participant