Skip to content

Commit a00ef87

Browse files
oaeenclaude
andcommitted
feat: support cmux
Add cmux (https://github.com/manaflow-ai/cmux) to the terminal list. cmux's CLI talks to the cmux daemon over a Unix socket that rejects client processes which are not descendants of cmux.app itself, so we cannot shell out to `cmux <path>` from OpenInTerminal-Lite — the daemon closes the connection during the handshake ("only processes started inside cmux can connect"). LaunchServices `open -a cmux.app <path>` works but cmux's openFile handler creates a brand-new window for every call, defeating the "in existing terminal" expectation. Use cmux's AppleScript dictionary instead: `new tab in front window` plus `input text "cd <path>" to focused terminal of newTab`. This stays inside the existing window, adds one workspace per click, and bypasses the socket auth entirely by going through AppleEvents. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 7ad818f commit a00ef87

2 files changed

Lines changed: 26 additions & 3 deletions

File tree

OpenInTerminalCore/App.swift

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,28 @@ extension App: Openable {
6464
path = desktopPath
6565
}
6666

67-
if SupportedApps.is(self, is: .terminal) {
67+
if SupportedApps.is(self, is: .cmux) {
68+
// cmux rejects socket clients that are not descendants of
69+
// cmux.app, so we cannot drive it via its CLI from here.
70+
// Instead, use its AppleScript dictionary: make a new tab
71+
// in the front window, then type `cd <path>` into the new
72+
// tab's focused terminal. This stays inside the existing
73+
// window instead of opening a new one.
74+
let shellQuoted = "'" + path.replacingOccurrences(of: "'", with: "'\\''") + "'"
75+
let asQuoted = shellQuoted
76+
.replacingOccurrences(of: "\\", with: "\\\\")
77+
.replacingOccurrences(of: "\"", with: "\\\"")
78+
let source = """
79+
tell application "\(self.name)"
80+
activate
81+
set w to front window
82+
set newTab to (new tab in w)
83+
set term to focused terminal of newTab
84+
input text "cd \(asQuoted) && clear" & (ASCII character 10) to term
85+
end tell
86+
"""
87+
try excute(source)
88+
} else if SupportedApps.is(self, is: .terminal) {
6889
// this app is supported: Terminal
6990
let url = URL(fileURLWithPath: path)
7091
guard let terminal = SBApplication(bundleIdentifier: SupportedApps.terminal.bundleId) as TerminalApplication?,

OpenInTerminalCore/SupportedApps.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ public enum SupportedApps: String, CaseIterable {
2222
case githubDesktop = "GitHub Desktop"
2323
case fork = "Fork"
2424
case ghostty = "Ghostty"
25-
25+
case cmux = "cmux"
26+
2627
// MARK: - Editors
2728
case textEdit = "TextEdit"
2829
case xcode = "Xcode"
@@ -70,7 +71,7 @@ public enum SupportedApps: String, CaseIterable {
7071

7172
public var type: AppType {
7273
switch self {
73-
case .terminal, .iTerm, .hyper, .alacritty, .kitty, .wezterm, .tabby, .warp, .githubDesktop, .fork, .ghostty:
74+
case .terminal, .iTerm, .hyper, .alacritty, .kitty, .wezterm, .tabby, .warp, .githubDesktop, .fork, .ghostty, .cmux:
7475
return .terminal
7576
default:
7677
return .editor
@@ -116,6 +117,7 @@ public enum SupportedApps: String, CaseIterable {
116117
case .githubDesktop: return ""
117118
case .fork: return ""
118119
case .ghostty: return "com.mitchellh.ghostty"
120+
case .cmux: return "com.cmuxterm.app"
119121
// Editors
120122
case .textEdit: return "com.apple.TextEdit"
121123
case .xcode: return "com.apple.Xcode"

0 commit comments

Comments
 (0)