Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/swift-file-length-budget.tsv
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# Format: max_lines<TAB>relative path
# Reduce counts as files shrink. CI fails if tracked files exceed this budget.
18705 CLI/cmux.swift
16364 Sources/TerminalController.swift
16373 Sources/TerminalController.swift
15762 Sources/ContentView.swift
13748 Sources/AppDelegate.swift
13702 Sources/Workspace.swift
Expand Down
3 changes: 0 additions & 3 deletions Resources/shell-integration/cmux-bash-integration.bash
Original file line number Diff line number Diff line change
Expand Up @@ -929,7 +929,6 @@ _cmux_preexec_command() {
if [[ -z "$_CMUX_TTY_NAME" ]]; then
local t
t="$(tty 2>/dev/null || true)"
t="${t##*/}"
[[ -n "$t" && "$t" != "not a tty" ]] && _CMUX_TTY_NAME="$t"
fi

Expand Down Expand Up @@ -958,7 +957,6 @@ _cmux_prompt_command() {
if [[ -z "$_CMUX_TTY_NAME" ]]; then
local t
t="$(tty 2>/dev/null || true)"
t="${t##*/}"
[[ "$t" != "not a tty" ]] && _CMUX_TTY_NAME="$t"
fi

Expand Down Expand Up @@ -995,7 +993,6 @@ _cmux_prompt_command() {
if [[ -z "$_CMUX_TTY_NAME" ]]; then
local t
t="$(tty 2>/dev/null || true)"
t="${t##*/}"
[[ "$t" != "not a tty" ]] && _CMUX_TTY_NAME="$t"
fi

Expand Down
2 changes: 0 additions & 2 deletions Resources/shell-integration/cmux-zsh-integration.zsh
Original file line number Diff line number Diff line change
Expand Up @@ -1074,7 +1074,6 @@ _cmux_preexec() {
if [[ -z "$_CMUX_TTY_NAME" ]]; then
local t
t="$(tty 2>/dev/null || true)"
t="${t##*/}"
[[ -n "$t" && "$t" != "not a tty" ]] && _CMUX_TTY_NAME="$t"
fi

Expand Down Expand Up @@ -1122,7 +1121,6 @@ _cmux_precmd() {
if [[ -z "$_CMUX_TTY_NAME" ]]; then
local t
t="$(tty 2>/dev/null || true)"
t="${t##*/}"
[[ -n "$t" && "$t" != "not a tty" ]] && _CMUX_TTY_NAME="$t"
fi

Expand Down
15 changes: 12 additions & 3 deletions Sources/TerminalController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,12 @@ class TerminalController {
return (workspaceId, panelId)
}

private static func portScanTTYName(from ttyName: String) -> String {
let trimmed = ttyName.trimmingCharacters(in: .whitespacesAndNewlines)
let candidate = trimmed.split(separator: "/").last.map(String.init) ?? trimmed
return candidate.isEmpty ? trimmed : candidate
}
Comment on lines +484 to +488

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 No unit test for portScanTTYName

The new portScanTTYName(from:) helper is the critical bridge that prevents a regression in port-scan behavior: it must convert /dev/ttys001 → ttys001 while leaving bare names like ttys001 untouched. It currently has no dedicated unit test. A simple parametric test covering /dev/ttys001, ttys001, an empty string, and a trailing-slash edge case (e.g. /dev/ttys001/) would lock in the invariant and prevent future accidental changes.


nonisolated static func normalizeReportedDirectory(_ directory: String) -> String {
let trimmed = directory.trimmingCharacters(in: .whitespacesAndNewlines)
guard !trimmed.isEmpty else { return directory }
Expand Down Expand Up @@ -4509,7 +4515,8 @@ class TerminalController {
tab.syncRemotePortScanTTYs()
_ = tab.applyPendingRemoteSurfacePortKickIfNeeded(to: surfaceId)
} else {
PortScanner.shared.registerTTY(workspaceId: workspaceId, panelId: surfaceId, ttyName: ttyName)
let scanTTYName = Self.portScanTTYName(from: ttyName)
PortScanner.shared.registerTTY(workspaceId: workspaceId, panelId: surfaceId, ttyName: scanTTYName)
}

result = .ok([
Expand Down Expand Up @@ -15972,7 +15979,8 @@ class TerminalController {
tab.syncRemotePortScanTTYs()
_ = tab.applyPendingRemoteSurfacePortKickIfNeeded(to: scope.panelId)
} else {
PortScanner.shared.registerTTY(workspaceId: scope.workspaceId, panelId: scope.panelId, ttyName: ttyName)
let scanTTYName = Self.portScanTTYName(from: ttyName)
PortScanner.shared.registerTTY(workspaceId: scope.workspaceId, panelId: scope.panelId, ttyName: scanTTYName)
}
}
return "OK"
Expand Down Expand Up @@ -16016,7 +16024,8 @@ class TerminalController {
tab.syncRemotePortScanTTYs()
_ = tab.applyPendingRemoteSurfacePortKickIfNeeded(to: surfaceId)
} else {
PortScanner.shared.registerTTY(workspaceId: tab.id, panelId: surfaceId, ttyName: ttyName)
let scanTTYName = Self.portScanTTYName(from: ttyName)
PortScanner.shared.registerTTY(workspaceId: tab.id, panelId: surfaceId, ttyName: scanTTYName)
}
}
return result
Expand Down
16 changes: 8 additions & 8 deletions cmuxTests/GhosttyConfigTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3567,7 +3567,7 @@ final class ZshShellIntegrationHandoffTests: XCTestCase {
cmuxLoadGhosttyIntegration: false,
cmuxLoadShellIntegration: true,
command: """
_CMUX_TTY_NAME=ttys999
_CMUX_TTY_NAME=/dev/ttys999
print -r -- "$(_cmux_report_tty_payload)"
""",
extraEnvironment: [
Expand All @@ -3577,7 +3577,7 @@ final class ZshShellIntegrationHandoffTests: XCTestCase {
]
)

XCTAssertEqual(output, "report_tty ttys999 --tab=11111111-1111-1111-1111-111111111111")
XCTAssertEqual(output, "report_tty /dev/ttys999 --tab=11111111-1111-1111-1111-111111111111")
}

func testShellIntegrationRelayReportTTYUsesWorkspaceIDInZsh() throws {
Expand All @@ -3604,7 +3604,7 @@ final class ZshShellIntegrationHandoffTests: XCTestCase {
cmuxLoadShellIntegration: true,
command: """
: > "\(logPath.path)"
_CMUX_TTY_NAME=ttys777
_CMUX_TTY_NAME=/dev/ttys777
_cmux_report_tty_via_relay
cat "\(logPath.path)"
""",
Expand All @@ -3618,7 +3618,7 @@ final class ZshShellIntegrationHandoffTests: XCTestCase {
)

XCTAssertTrue(
output.contains(#"rpc surface.report_tty {"workspace_id":"11111111-1111-1111-1111-111111111111","tty_name":"ttys777","surface_id":"22222222-2222-2222-2222-222222222222"}"#),
output.contains(#"rpc surface.report_tty {"workspace_id":"11111111-1111-1111-1111-111111111111","tty_name":"/dev/ttys777","surface_id":"22222222-2222-2222-2222-222222222222"}"#),
output
)
}
Expand Down Expand Up @@ -3741,7 +3741,7 @@ final class ZshShellIntegrationHandoffTests: XCTestCase {
cmuxLoadShellIntegration: true,
command: """
: > "\(logPath.path)"
_CMUX_TTY_NAME=ttys888
_CMUX_TTY_NAME=/dev/ttys888
_cmux_report_tty_via_relay
cat "\(logPath.path)"
""",
Expand All @@ -3755,7 +3755,7 @@ final class ZshShellIntegrationHandoffTests: XCTestCase {
)

XCTAssertTrue(
result.stdout.contains(#"rpc surface.report_tty {"workspace_id":"11111111-1111-1111-1111-111111111111","tty_name":"ttys888","surface_id":"22222222-2222-2222-2222-222222222222"}"#),
result.stdout.contains(#"rpc surface.report_tty {"workspace_id":"11111111-1111-1111-1111-111111111111","tty_name":"/dev/ttys888","surface_id":"22222222-2222-2222-2222-222222222222"}"#),
result.stdout
)
}
Expand Down Expand Up @@ -3783,7 +3783,7 @@ final class ZshShellIntegrationHandoffTests: XCTestCase {
cmuxLoadShellIntegration: true,
command: """
: > "\(logPath.path)"
_CMUX_TTY_NAME=ttys889
_CMUX_TTY_NAME=/dev/ttys889
_CMUX_TTY_REPORTED=0
_cmux_preexec_command "python3 -m http.server 8899"
for _cmux_i in $(seq 1 20); do
Expand All @@ -3802,7 +3802,7 @@ final class ZshShellIntegrationHandoffTests: XCTestCase {
)

XCTAssertTrue(
result.stdout.contains(#"rpc surface.report_tty {"workspace_id":"11111111-1111-1111-1111-111111111111","tty_name":"ttys889"}"#),
result.stdout.contains(#"rpc surface.report_tty {"workspace_id":"11111111-1111-1111-1111-111111111111","tty_name":"/dev/ttys889"}"#),
result.stdout
)
XCTAssertTrue(
Expand Down