Repository navigation
feat(sidebar): make listening ports clickable to open in browser - #1844
Conversation
Wrap each sidebar port in a Button that opens http://localhost:{port}
in the cmux built-in browser (or system browser as fallback), matching
the existing PR link click behavior.
Fixes manaflow-ai#1602
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
@mvanhorn is attempting to deploy a commit to the Manaflow Team on Vercel. A member of the Team first needs to authorize it. |
|
To use Codex here, create a Codex account and connect to github. |
📝 WalkthroughWalkthroughPorts in the sidebar are now rendered as individual clickable buttons. Clicking a port calls a new handler that constructs Changes
Sequence DiagramsequenceDiagram
actor User
participant ContentView as ContentView<br/>(Port Button)
participant openPortLink as openPortLink<br/>Function
participant TabManager as tabManager
participant NSWorkspace as NSWorkspace
User->>ContentView: Click port button
ContentView->>openPortLink: openPortLink(port)
openPortLink->>openPortLink: Construct http://localhost:port
openPortLink->>ContentView: updateSelection()
openPortLink->>TabManager: openBrowser(url)
alt Browser opened successfully
TabManager-->>openPortLink: returns non-nil
else Browser method fails
TabManager-->>openPortLink: returns nil
openPortLink->>NSWorkspace: open(url)
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
📝 Coding Plan
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. Comment |
Greptile SummaryThis PR makes listening-port entries in the cmux sidebar interactive: each port number becomes a clickable button that opens Two issues need attention before merging:
Confidence Score: 3/5
Important Files Changed
Sequence DiagramsequenceDiagram
participant User
participant SidebarPortButton
participant openPortLink
participant tabManager
participant NSWorkspace
User->>SidebarPortButton: Click `:8080`
SidebarPortButton->>openPortLink: openPortLink(8080)
openPortLink->>openPortLink: guard URL(string: "http://localhost:8080")
openPortLink->>openPortLink: updateSelection()
openPortLink->>tabManager: openBrowser(inWorkspace:, url:, preferSplitRight: true, insertAtEnd: true)
alt Browser pane opened successfully
tabManager-->>openPortLink: returns non-nil
Note over openPortLink: Done — URL shown in cmux pane
else Browser pane unavailable
tabManager-->>openPortLink: returns nil
openPortLink->>NSWorkspace: open(url)
NSWorkspace-->>User: Opens in system browser
end
Last reviewed commit: "feat(sidebar): make ..." |
| .underline() | ||
| } | ||
| .buttonStyle(.plain) | ||
| .safeHelp(String(localized: "sidebar.port.openTooltip", defaultValue: "Open localhost:\(port)")) |
There was a problem hiding this comment.
Localization key missing from
Localizable.xcstrings
The new key sidebar.port.openTooltip is used here but was never added to Resources/Localizable.xcstrings. The CLAUDE.md style guide is explicit: "All user-facing strings must be localized. Keys go in Resources/Localizable.xcstrings with translations for all supported languages."
The existing parallel key sidebar.pullRequest.openTooltip has entries for 16 languages (en, ja, zh-Hans, zh-Hant, ko, de, es, fr, it, da, pl, ru, bs, ar, nb, pt-BR, th, tr). Without the new key, non-English users will always see the defaultValue fallback string, and the string will never be picked up by translators.
Context Used: CLAUDE.md (source)
| private func openPortLink(_ port: Int) { | ||
| guard let url = URL(string: "http://localhost:\(port)") else { return } | ||
| updateSelection() | ||
| if tabManager.openBrowser( | ||
| inWorkspace: tab.id, | ||
| url: url, | ||
| preferSplitRight: true, | ||
| insertAtEnd: true | ||
| ) == nil { | ||
| NSWorkspace.shared.open(url) | ||
| } | ||
| } |
There was a problem hiding this comment.
User preference for in-app browser not respected
openPortLink unconditionally attempts to open URLs in the cmux browser pane, while the analogous openPullRequestLink (which this function mirrors) gates that behavior behind the openSidebarPullRequestLinksInCmuxBrowser user preference:
// openPullRequestLink checks the preference first
if openSidebarPullRequestLinksInCmuxBrowser {
if tabManager.openBrowser(...) == nil {
NSWorkspace.shared.open(url)
}
return
}
NSWorkspace.shared.open(url)A user who has toggled the setting to always use the system browser (i.e., openSidebarPullRequestLinksInCmuxBrowser = false) will find that PR links open in the system browser, while clicking a port number opens in the cmux browser pane — an inconsistent and surprising experience. The fix would either be to read the same preference, or to introduce a dedicated openSidebarPortLinksInCmuxBrowser preference with its own toggle in Settings.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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/ContentView.swift`:
- Line 11079: Replace the bare Text literal that displays the port (currently
Text(":\(port)") in ContentView) with a localized string using
String(localized:..., defaultValue:...) so the user-facing port label is
localizable; update the Text initializer to pass the localized string
constructed with the port value (referencing the existing port variable) and add
the localization key (e.g., "port.label") with appropriate English and Japanese
entries in Resources/Localizable.xcstrings.
- Localize port label text with String(localized:) instead of bare literal - Add sidebar.port.label and sidebar.port.openTooltip keys to Localizable.xcstrings with English and Japanese translations - Respect openSidebarPullRequestLinksInCmuxBrowser user preference in openPortLink, matching the openPullRequestLink pattern exactly Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
1 issue found across 2 files (changes from recent commits).
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/ContentView.swift">
<violation number="1" location="Sources/ContentView.swift:11798">
P2: Port links are incorrectly gated by a PR-link-only preference, causing port clicks to skip in-app opening when that unrelated setting is off.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
| if openSidebarPullRequestLinksInCmuxBrowser { | ||
| if tabManager.openBrowser( | ||
| inWorkspace: tab.id, | ||
| url: url, | ||
| preferSplitRight: true, | ||
| insertAtEnd: true | ||
| ) == nil { | ||
| NSWorkspace.shared.open(url) | ||
| } | ||
| return | ||
| } | ||
| NSWorkspace.shared.open(url) |
There was a problem hiding this comment.
P2: Port links are incorrectly gated by a PR-link-only preference, causing port clicks to skip in-app opening when that unrelated setting is off.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At Sources/ContentView.swift, line 11798:
<comment>Port links are incorrectly gated by a PR-link-only preference, causing port clicks to skip in-app opening when that unrelated setting is off.</comment>
<file context>
@@ -11795,14 +11795,18 @@ private struct TabItemView: View, Equatable {
- insertAtEnd: true
- ) == nil {
- NSWorkspace.shared.open(url)
+ if openSidebarPullRequestLinksInCmuxBrowser {
+ if tabManager.openBrowser(
+ inWorkspace: tab.id,
</file context>
| if openSidebarPullRequestLinksInCmuxBrowser { | |
| if tabManager.openBrowser( | |
| inWorkspace: tab.id, | |
| url: url, | |
| preferSplitRight: true, | |
| insertAtEnd: true | |
| ) == nil { | |
| NSWorkspace.shared.open(url) | |
| } | |
| return | |
| } | |
| NSWorkspace.shared.open(url) | |
| if tabManager.openBrowser( | |
| inWorkspace: tab.id, | |
| url: url, | |
| preferSplitRight: true, | |
| insertAtEnd: true | |
| ) == nil { | |
| NSWorkspace.shared.open(url) | |
| } |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
Sources/ContentView.swift (1)
11798-11809: Consider using a dedicated setting key for port-link open behavior.
openPortLinkcurrently reusesopenSidebarPullRequestLinksInCmuxBrowser. A port-specific key (with fallback migration from the current key) would avoid semantic coupling and future settings confusion.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@Sources/ContentView.swift` around lines 11798 - 11809, The code currently uses the openSidebarPullRequestLinksInCmuxBrowser boolean to control port link opening, creating semantic coupling; define a new dedicated setting key (e.g., openPortLink or similar) and use it in this block instead of openSidebarPullRequestLinksInCmuxBrowser, while preserving backward compatibility by migrating or falling back to the old key when the new key is unset. Update the logic that checks openSidebarPullRequestLinksInCmuxBrowser to read the new setting (and if nil/absent, read the old setting and optionally write it to the new key), and ensure tabManager.openBrowser(...) and NSWorkspace.shared.open(url) behavior remains identical when driven by the new key.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@Sources/ContentView.swift`:
- Around line 11798-11809: The code currently uses the
openSidebarPullRequestLinksInCmuxBrowser boolean to control port link opening,
creating semantic coupling; define a new dedicated setting key (e.g.,
openPortLink or similar) and use it in this block instead of
openSidebarPullRequestLinksInCmuxBrowser, while preserving backward
compatibility by migrating or falling back to the old key when the new key is
unset. Update the logic that checks openSidebarPullRequestLinksInCmuxBrowser to
read the new setting (and if nil/absent, read the old setting and optionally
write it to the new key), and ensure tabManager.openBrowser(...) and
NSWorkspace.shared.open(url) behavior remains identical when driven by the new
key.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 53e711ac-8169-4754-828c-bd7e5c47f46a
📒 Files selected for processing (2)
Resources/Localizable.xcstringsSources/ContentView.swift
✅ Files skipped from review due to trivial changes (1)
- Resources/Localizable.xcstrings
|
Thank you for the contribution! |
Port links were reusing the PR-link preference (openSidebarPullRequestLinksInCmuxBrowser), causing inconsistent behavior when users toggled that setting. Adds a dedicated openSidebarPortLinksInCmuxBrowser setting with its own toggle in Settings so port and PR link behavior can be controlled independently. Addresses review feedback from #1844
…2219) Port links were reusing the PR-link preference (openSidebarPullRequestLinksInCmuxBrowser), causing inconsistent behavior when users toggled that setting. Adds a dedicated openSidebarPortLinksInCmuxBrowser setting with its own toggle in Settings so port and PR link behavior can be controlled independently. Addresses review feedback from #1844 Co-authored-by: Lawrence Chen <lawrencecchen@users.noreply.github.com>
|
Thanks for the merge! Happy to contribute to cmux. |
…aflow-ai#1844) * feat(sidebar): make listening ports clickable to open in browser Wrap each sidebar port in a Button that opens http://localhost:{port} in the cmux built-in browser (or system browser as fallback), matching the existing PR link click behavior. Fixes manaflow-ai#1602 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: address bot review feedback on port clickability - Localize port label text with String(localized:) instead of bare literal - Add sidebar.port.label and sidebar.port.openTooltip keys to Localizable.xcstrings with English and Japanese translations - Respect openSidebarPullRequestLinksInCmuxBrowser user preference in openPortLink, matching the openPullRequestLink pattern exactly Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Port links were reusing the PR-link preference (openSidebarPullRequestLinksInCmuxBrowser), causing inconsistent behavior when users toggled that setting. Adds a dedicated openSidebarPortLinksInCmuxBrowser setting with its own toggle in Settings so port and PR link behavior can be controlled independently. Addresses review feedback from manaflow-ai#1844
…(#2219) Port links were reusing the PR-link preference (openSidebarPullRequestLinksInCmuxBrowser), causing inconsistent behavior when users toggled that setting. Adds a dedicated openSidebarPortLinksInCmuxBrowser setting with its own toggle in Settings so port and PR link behavior can be controlled independently. Addresses review feedback from manaflow-ai/cmux#1844 Co-authored-by: Lawrence Chen <lawrencecchen@users.noreply.github.com>
Port links were reusing the PR-link preference (openSidebarPullRequestLinksInCmuxBrowser), causing inconsistent behavior when users toggled that setting. Adds a dedicated openSidebarPortLinksInCmuxBrowser setting with its own toggle in Settings so port and PR link behavior can be controlled independently. Addresses review feedback from manaflow-ai#1844
Summary
http://localhost:{port}in the cmux built-in browser paneContentView.swift:11046-11068)Testing
openPortLinkfunction mirrorsopenPullRequestLinkatContentView.swift:11768- sametabManager.openBrowsercall withpreferSplitRight: true.buttonStyle(.plain)and.safeHelp()for accessibility, matching PR link buttonsString(localized: "sidebar.port.openTooltip", defaultValue: "Open localhost:\(port)")TabItemView's.equatable()scope)Demo Video
Review Trigger (Copy/Paste as PR comment)
Checklist
This contribution was developed with AI assistance (Claude Code).
Fixes #1602
Summary by cubic
Make sidebar listening ports clickable. Clicking opens http://localhost:{port} in the built-in browser, with a system browser fallback.
sidebar.port.labelandsidebar.port.openTooltip(English, Japanese).Written for commit 5b20bf0. Summary will update on new commits.
Summary by CodeRabbit
New Features
Documentation