Skip to content

Add per-tab remote indicator and Disconnect SSH tab context action - #162

Merged
austinywang merged 1 commit into
mainfrom
ssh-pane-indicator-rebased
Jul 8, 2026
Merged

austinywang merged 1 commit into
mainfrom
ssh-pane-indicator-rebased

Conversation

@austinywang

@austinywang austinywang commented Jul 8, 2026 •

Copy link
Copy Markdown

Re-lands the never-merged ssh-pane-remote-indicator branch (f3b3658, built for manaflow-ai/cmux#5949), rebased onto current main:

  • Tab/TabItem gain showsRemoteIndicator (rendered as a small network glyph after the tab title, with accessibility text), threaded through createTab/updateTab/splitPane.
  • New TabContextAction.disconnectRemote, shown only when the host's tabContextDisconnectRemoteAvailabilityProvider returns true. Localized en + ja.

Rebase-specific integration on top of the original commit:

Consumed by pane-scoped cmux ssh --pane (manaflow-ai/cmux#7521). The cmux submodule pointer will reference this commit once it lands on main.

🤖 Generated with Claude Code


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


Summary by cubic

Add a per-tab remote connection indicator and an optional “Disconnect SSH” tab context action so hosts can signal remote tabs and let users disconnect from SSH.

  • New Features

    • Tabs support showsRemoteIndicator; shown as a small “network” icon next to the title with an accessibility label. Available via createTab, updateTab, and splitPane.
    • New context action disconnectRemote (“Disconnect SSH”), shown only when tabContextDisconnectRemoteAvailabilityProvider returns true. Localized in en and ja.
    • updateTab now updates when only showsRemoteIndicator changes.
  • Migration

    • Set showsRemoteIndicator when creating or updating tabs that are connected remotely.
    • Implement tabContextDisconnectRemoteAvailabilityProvider to surface the “Disconnect SSH” menu item.
    • Handle the new TabContextAction.disconnectRemote in your context menu action handler.

Written for commit 7312bce. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • New Features

    • Tabs can now display a remote connection indicator when connected over SSH.
    • A new “Disconnect SSH” option appears in the tab menu when available.
  • Bug Fixes

    • Remote connection status now stays visible across tab updates and split-pane actions.
    • Existing content continues to load correctly even when older saved data doesn’t include the new status field.
  • Documentation / Localization

    • Added new user-facing text in English and Japanese for remote connection status and disconnect actions.

@coderabbitai

coderabbitai Bot commented Jul 8, 2026 •

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds a showsRemoteIndicator flag to TabItem/Tab models with Codable support, threads it through BonsplitController create/update/split APIs, renders a network indicator icon and accessibility text in the tab UI, and adds a conditional "Disconnect SSH" context-menu action backed by a new availability provider, replacing toggleFullWidthTab. Includes localized strings and a new test.

Changes

Remote SSH indicator and disconnect action

Layer / File(s) Summary
Tab model updates
Sources/Bonsplit/Internal/Models/TabItem.swift, Sources/Bonsplit/Public/Types/Tab.swift
Adds showsRemoteIndicator boolean with default value, initializer wiring, and Codable encode/decode (with backward-compatible default) to TabItem; mirrors the property on Tab with initializer and TabItem-conversion support.
Controller API and action type
Sources/Bonsplit/Public/BonsplitController.swift, Sources/Bonsplit/Public/Types/TabContextAction.swift
Adds tabContextDisconnectRemoteAvailabilityProvider closure property; extends createTab, updateTab, and both splitPane overloads to thread showsRemoteIndicator; replaces toggleFullWidthTab case with disconnectRemote in TabContextAction.
Tab bar UI and context menu
Sources/Bonsplit/Internal/Views/TabBarView.swift, Sources/Bonsplit/Internal/Views/TabItemView.swift
Adds canDisconnectRemote to TabContextMenuState, populated from the new provider; renders a network icon and "Connected over SSH" accessibility text when showsRemoteIndicator is true; adds a conditional "Disconnect SSH" menu item.
Localization and tests
Sources/Bonsplit/Resources/en.lproj/Localizable.strings, Sources/Bonsplit/Resources/ja.lproj/Localizable.strings, Tests/BonsplitTests/BonsplitTests.swift
Adds English and Japanese strings for "Disconnect SSH" and "Connected over SSH"; adds a test validating conditional menu presence and the .disconnectRemote action dispatch.

Estimated code review effort: 2 (Simple) | ~15 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Host
  participant BonsplitController
  participant TabBarView
  participant TabContextMenuBuilder

  Host->>BonsplitController: createTab(showsRemoteIndicator: true)
  BonsplitController-->>Host: TabID

  TabBarView->>BonsplitController: tabContextDisconnectRemoteAvailabilityProvider(tabID, paneID)
  BonsplitController-->>TabBarView: canDisconnectRemote
  TabBarView->>TabContextMenuBuilder: makeMenu(state)
  TabContextMenuBuilder-->>TabBarView: menu with "Disconnect SSH" item (if available)
Loading

Possibly related PRs

  • manaflow-ai/bonsplit#158: Both PRs modify the same tab context-menu construction pipeline (TabContextMenuState/TabContextMenuBuilder) to conditionally show menu items.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: per-tab remote indicators plus the new Disconnect SSH tab context action.
✨ 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 ssh-pane-indicator-rebased

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.

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
Sources/Bonsplit/Public/BonsplitController.swift (1)

232-235: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

requestTabContextAction still references .toggleFullWidthTab — ensure the merge conflict in TabContextAction.swift is resolved to keep this case.

Line 232 checks if action == .toggleFullWidthTab and routes to requestTabFullWidthToggle. If the unresolved merge conflict in TabContextAction.swift (lines 24–28) is resolved by removing toggleFullWidthTab, this line will fail to compile. The full-width-tab infrastructure (lines 107–109, 779–792) also depends on it.

🤖 Prompt for 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.

In `@Sources/Bonsplit/Public/BonsplitController.swift` around lines 232 - 235, The
`requestTabContextAction` flow in `BonsplitController` still depends on
`.toggleFullWidthTab`, so make sure the merge conflict in
`TabContextAction.swift` is resolved by keeping that enum case and any related
API surface intact. Update the `TabContextAction` definition and any associated
switch handling so the `.toggleFullWidthTab` branch remains valid for
`requestTabFullWidthToggle`, and verify the full-width-tab support used
elsewhere in the controller continues to compile and route correctly.
🤖 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/Bonsplit/Public/Types/TabContextAction.swift`:
- Around line 24-28: Resolve the unresolved merge conflict in TabContextAction
by removing the literal conflict markers and keeping both enum cases,
toggleFullWidthTab and disconnectRemote, so the file compiles cleanly. Make sure
TabContextAction still includes toggleFullWidthTab because BonsplitController
uses it in its action handling and full-width-tab flow, and add disconnectRemote
alongside it rather than replacing it.

---

Outside diff comments:
In `@Sources/Bonsplit/Public/BonsplitController.swift`:
- Around line 232-235: The `requestTabContextAction` flow in
`BonsplitController` still depends on `.toggleFullWidthTab`, so make sure the
merge conflict in `TabContextAction.swift` is resolved by keeping that enum case
and any related API surface intact. Update the `TabContextAction` definition and
any associated switch handling so the `.toggleFullWidthTab` branch remains valid
for `requestTabFullWidthToggle`, and verify the full-width-tab support used
elsewhere in the controller continues to compile and route correctly.
🪄 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: 868d8dfc-ae9c-4ead-aad2-61cc94a34c76

📥 Commits

Reviewing files that changed from the base of the PR and between fb5307f and 5cbe2bf.

📒 Files selected for processing (9)
  • Sources/Bonsplit/Internal/Models/TabItem.swift
  • Sources/Bonsplit/Internal/Views/TabBarView.swift
  • Sources/Bonsplit/Internal/Views/TabItemView.swift
  • Sources/Bonsplit/Public/BonsplitController.swift
  • Sources/Bonsplit/Public/Types/Tab.swift
  • Sources/Bonsplit/Public/Types/TabContextAction.swift
  • Sources/Bonsplit/Resources/en.lproj/Localizable.strings
  • Sources/Bonsplit/Resources/ja.lproj/Localizable.strings
  • Tests/BonsplitTests/BonsplitTests.swift

Comment on lines +24 to +28
<<<<<<< HEAD
case toggleFullWidthTab
=======
case disconnectRemote
>>>>>>> 57f8850 (Add per-tab remote indicator and Disconnect SSH tab context action)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win

Unresolved git merge conflict markers will prevent compilation.

The file contains literal <<<<<<< HEAD, =======, and >>>>>>> markers at lines 24–28. This will cause a Swift compilation failure. The conflict must be resolved before merge.

Additionally, if the resolution removes case toggleFullWidthTab (as the PR summary suggests), BonsplitController.swift line 232 (if action == .toggleFullWidthTab) and the full-width-tab infrastructure at lines 107–109 and 779–792 will fail to compile. The controller still actively uses toggleFullWidthTab, so the resolution should keep both cases.

🔧 Proposed resolution: keep both cases
     case toggleZoom
-<<<<<<< HEAD
-    case toggleFullWidthTab
-=======
     case disconnectRemote
->>>>>>> 57f8850 (Add per-tab remote indicator and Disconnect SSH tab context action)
+    case toggleFullWidthTab
+    case disconnectRemote
🧰 Tools
🪛 GitHub Actions: CI / 0_tests.txt

[error] 24-26: Swift compilation error: source control conflict marker in source file (found '<<<<<<< HEAD' / '=======').

🪛 GitHub Actions: CI / tests

[error] 24-24: Swift compilation failed during swift test/emit-module. Error: source control conflict marker in source file (<<<<<<< HEAD / =======).

🤖 Prompt for 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.

In `@Sources/Bonsplit/Public/Types/TabContextAction.swift` around lines 24 - 28,
Resolve the unresolved merge conflict in TabContextAction by removing the
literal conflict markers and keeping both enum cases, toggleFullWidthTab and
disconnectRemote, so the file compiles cleanly. Make sure TabContextAction still
includes toggleFullWidthTab because BonsplitController uses it in its action
handling and full-width-tab flow, and add disconnectRemote alongside it rather
than replacing it.

@greptile-apps

greptile-apps Bot commented Jul 8, 2026

Copy link
Copy Markdown

Greptile Summary

This PR adds remote-connection state and context-menu support for SSH tabs. The main changes are:

  • New showsRemoteIndicator tab state across public and internal models.
  • Remote indicator rendering and accessibility text in tab items.
  • Provider-gated Disconnect SSH context-menu action.
  • English and Japanese strings plus menu coverage.

Confidence Score: 2/5

The package is not safe to merge while TabContextAction.swift contains unresolved conflict markers.

  • Swift cannot parse the changed enum body.
  • The new context action and the existing full-width action are both inside the conflicted region.
  • The rest of the remote-indicator threading follows the existing tab metadata patterns.

Sources/Bonsplit/Public/Types/TabContextAction.swift

Important Files Changed

Filename Overview
Sources/Bonsplit/Public/Types/TabContextAction.swift Adds the new context action but leaves unresolved conflict markers in the enum.
Sources/Bonsplit/Public/BonsplitController.swift Threads showsRemoteIndicator through create, update, and split paths and adds the availability provider.
Sources/Bonsplit/Internal/Views/TabItemView.swift Renders the remote indicator, adds accessibility text, and inserts the gated context-menu item.
Sources/Bonsplit/Internal/Views/TabBarView.swift Adds canDisconnectRemote to menu state and derives it from the controller provider.
Sources/Bonsplit/Internal/Models/TabItem.swift Adds persisted remote-indicator state with a default for older encoded tab data.
Sources/Bonsplit/Public/Types/Tab.swift Adds the public remote-indicator property and maps it from internal tab items.
Tests/BonsplitTests/BonsplitTests.swift Covers visibility and dispatch for the Disconnect SSH context-menu item.

Reviews (1): Last reviewed commit: "Add per-tab remote indicator and Disconn..." | Re-trigger Greptile

Comment on lines +24 to +28
<<<<<<< HEAD
case toggleFullWidthTab
=======
case disconnectRemote
>>>>>>> 57f8850 (Add per-tab remote indicator and Disconnect SSH tab context action)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P0 Unresolved Conflict Blocks Build

The enum body still contains merge-conflict markers. Any target that compiles Bonsplit will fail to parse this file, so neither toggleFullWidthTab nor the new disconnectRemote action can be used until both cases are kept without the markers.

Suggested change
<<<<<<< HEAD
case toggleFullWidthTab
=======
case disconnectRemote
>>>>>>> 57f8850 (Add per-tab remote indicator and Disconnect SSH tab context action)
case toggleFullWidthTab
case disconnectRemote

- Tab/TabItem gain showsRemoteIndicator (rendered as a small network glyph
  after the tab title, with accessibility text)
- BonsplitController.updateTab/createTab/splitPane carry the new field
- New TabContextAction.disconnectRemote, shown only when the host's
  tabContextDisconnectRemoteAvailabilityProvider returns true
@austinywang
austinywang force-pushed the ssh-pane-indicator-rebased branch from 5cbe2bf to 7312bce Compare July 8, 2026 01:25
@austinywang
austinywang merged commit f01ee06 into main Jul 8, 2026
4 checks passed
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.

2 participants