Skip to content

add active session switching and consistent terminal selector sheets - #21

Merged
h3nock merged 8 commits into
mainfrom
feature/active-session-switcher
Jul 31, 2026
Merged

add active session switching and consistent terminal selector sheets#21
h3nock merged 8 commits into
mainfrom
feature/active-session-switcher

Conversation

@h3nock

@h3nock h3nock commented Jul 30, 2026

Copy link
Copy Markdown
Owner

Summary

Adds an active tmux session switcher to the terminal and aligns the Sessions, Windows, and Panes sheets with a consistent iOS design.

What changed

  • Adds a Sessions sheet accessible from the terminal dock.
  • Shows every active tmux session with its server, runtime state, and current-session indicator.
  • Supports switching sessions and disconnecting directly from a session row.
  • When the current session is disconnected, automatically switches to the next session shown in the list.
  • Adds a server-aware New Session flow:
    • Starts immediately when only one server exists.
    • Presents Choose Server when multiple servers exist.
    • Places the current server first.
  • Cancelling New Session setup returns to the screen where the flow started.
  • Aligns Sessions, Windows, and Panes with shared sheet styling, selection indicators, close controls, and standard 44-point action buttons.

Validation

  • 78 focused tests pass with zero failures:
    • ActiveSessionSwitcherProjectionTests
    • PanePreviewLayoutTests
    • GhosttyPhoneChromeLayoutTests
    • RemuxRootModelTests
  • Validated on both the simulator and a physical device.
  • Manually checked Sessions, Windows, and Panes using real tmux sessions.

Screenshots

Before After

Summary by CodeRabbit

  • New Features
    • Switch between active terminal sessions, disconnect sessions, or create new workspaces directly from the terminal.
    • View session status indicators, current-session highlights, and clearer server connection details.
    • Access Sessions and Library actions from updated keyboard controls.
  • Improvements
    • Redesigned terminal selection sheets with clearer selection states and consistent actions.
    • Improved sheet sizing, scrolling, accessibility, and compact layouts on smaller screens.
    • Setup cancellation returns to the screen where setup began.
    • Session ordering and selection now behave more predictably after disconnection.

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 30, 2026

Copy link
Copy Markdown

Deploying getremux with  Cloudflare Pages  Cloudflare Pages

Latest commit: 8440c85
Status: ✅  Deploy successful!
Preview URL: https://5a228d17.getremux.pages.dev
Branch Preview URL: https://feature-active-session-switc.getremux.pages.dev

View logs

@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 943e49be-d31c-434f-93bb-25b589d355d3

📥 Commits

Reviewing files that changed from the base of the PR and between bedd1bd and 8440c85.

📒 Files selected for processing (2)
  • RemuxApp/Sources/Ghostty/GhosttySurfaceSelectionSheet.swift
  • RemuxApp/Sources/Ghostty/TerminalSelectionSheetStyle.swift

📝 Walkthrough

Walkthrough

The PR adds active-session switching and disconnection flows, preserves setup cancellation destinations, introduces shared terminal runtime indicators, and refactors terminal selection sheets around shared styling, content-based sizing, and unified pane-count APIs.

Changes

Active-session switching and setup state

Layer / File(s) Summary
Session switcher and app integration
RemuxApp/Sources/App/*, RemuxApp/Sources/App/RootView.swift, RemuxAppTests/ActiveSessionSwitcherProjectionTests.swift
Adds session projection, ordering, selection, disconnection, server picking, runtime indicators, and terminal-originated workspace creation.
Setup and disconnection model behavior
RemuxApp/Sources/App/RemuxRootModel.swift, RemuxAppTests/RemuxRootModelTests.swift
Encapsulates setup state, preserves validation and cancellation metadata, and selects a remaining session after disconnection.
Project wiring and UI automation
Remux.xcodeproj/project.pbxproj, RemuxAppUITests/RemuxAppUITests.swift
Registers new sources and updates UI automation for disconnect and dedicated sheet dismissal controls.

Terminal navigation and presentation

Layer / File(s) Summary
Keyboard chrome navigation
RemuxApp/Sources/Ghostty/GhosttyKeyboardChrome.swift, RemuxAppTests/GhosttyPhoneChromeLayoutTests.swift
Adds Sessions and Library actions and applies compact sizing below the narrow-screen threshold.
Terminal sheet presentation
RemuxApp/Sources/Ghostty/GhosttySurfaceScreen.swift, RemuxApp/Sources/Ghostty/GhosttyKeyboardVisibilityProjection.swift
Separates terminal callbacks, uses viewport sizing, embeds preview sessions in sheet payloads, and derives sheet height from current grid content.

Selection-sheet geometry and styling

Layer / File(s) Summary
Projection and layout contracts
RemuxApp/Sources/Ghostty/GhosttyTerminalPresentationProjector.swift, RemuxApp/Sources/Ghostty/GhosttyTerminalScreenModeling.swift, RemuxApp/Sources/Tmux/TmuxTerminalScreenAdapter.swift, RemuxApp/Sources/Ghostty/PanePreviewLayout.swift
Removes detent-specific counts and introduces unified pane counting with simplified window and pane geometry metrics.
Shared selection-sheet UI
RemuxApp/Sources/Ghostty/TerminalSelectionSheetStyle.swift, RemuxApp/Sources/Ghostty/GhosttySurfaceSelectionSheet.swift
Adds shared palettes, scaffolds, close controls, actions, accessibility behavior, and selected-state tile styling.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related PRs

  • h3nock/remux#8: Modifies overlapping RemuxRootModel and RootView setup flows and callback wiring.
  • h3nock/remux#20: Modifies related session and terminal navigation flows in RootView and GhosttySurfaceScreen.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 2.74% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarizes the main changes: active session switching and consistent terminal selector sheets.
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.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/active-session-switcher

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.

@h3nock
h3nock marked this pull request as ready for review July 30, 2026 23:47
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits.
Credits must be used to enable repository wide code reviews.

@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

🧹 Nitpick comments (2)
RemuxApp/Sources/App/RemuxRootModel.swift (1)

281-295: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Credential/server repair setup doesn't return to the originating terminal on cancel.

beginServerRepair/beginCredentialRepair (and the underlying beginEditServer) never pass a cancelDestination, so they always default to .library. These flows are commonly entered from an active terminal (RootView's onUpdateCredentials/onEditServer), similar to beginNewWorkspace, which now correctly returns to the originating terminal via SetupCancelDestination.terminal(_:). For consistency with the new cancellation-destination feature, consider threading a cancelDestination through these repair entry points as well.

♻️ Sketch of the change
-func beginServerRepair(for workspaceID: SavedWorkspace.ID) async {
+func beginServerRepair(
+    for workspaceID: SavedWorkspace.ID,
+    cancelDestination: SetupCancelDestination = .library
+) async {
     guard let workspace = library.workspace(id: workspaceID) else {
         return
     }

-    await beginEditServer(serverID: workspace.serverID, reconnectWorkspaceID: workspaceID)
+    await beginEditServer(
+        serverID: workspace.serverID,
+        reconnectWorkspaceID: workspaceID,
+        cancelDestination: cancelDestination
+    )
 }

Also applies to: 297-325

🤖 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 `@RemuxApp/Sources/App/RemuxRootModel.swift` around lines 281 - 295, Thread a
SetupCancelDestination through beginServerRepair and beginCredentialRepair into
beginEditServer, using the originating terminal destination when these flows are
launched from RootView’s onUpdateCredentials/onEditServer. Preserve the existing
library fallback for callers without a terminal context, matching
beginNewWorkspace’s cancellation behavior.
RemuxApp/Sources/Ghostty/GhosttySurfaceSelectionSheet.swift (1)

527-543: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Duplicated tile chrome between window and pane selection tiles. GhosttyWindowSelectionTile and GhosttyPaneSelectionTile both apply the identical background/border/checkmark-overlay block against TerminalSelectionSheetPalette; extracting a shared ViewModifier (e.g. .terminalSelectionTileChrome(isSelected:chromeStyle:)) would keep future palette/selection-indicator tweaks in one place.

  • RemuxApp/Sources/Ghostty/GhosttySurfaceSelectionSheet.swift#L527-L543: replace this block with a shared tile-chrome modifier applied to the tile's content.
  • RemuxApp/Sources/Ghostty/GhosttySurfaceSelectionSheet.swift#L633-L649: apply the same shared modifier here instead of repeating the block.
🤖 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 `@RemuxApp/Sources/Ghostty/GhosttySurfaceSelectionSheet.swift` around lines 527
- 543, Extract the duplicated TerminalSelectionSheetPalette background, border,
and selected checkmark overlay from GhosttyWindowSelectionTile and
GhosttyPaneSelectionTile into a shared ViewModifier, such as
terminalSelectionTileChrome(isSelected:chromeStyle:). Replace the repeated
blocks at RemuxApp/Sources/Ghostty/GhosttySurfaceSelectionSheet.swift lines
527-543 and 633-649 with that modifier applied to each tile’s content,
preserving the existing selection styling and checkmark behavior at both sites.
🤖 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 `@RemuxApp/Sources/Ghostty/PanePreviewLayout.swift`:
- Around line 30-54: Update gridIdealHeight so single-row grids return
fullHeight before applying the scrolling height calculation. Preserve the
existing budget and multi-row peek behavior for grids that require scrolling.

---

Nitpick comments:
In `@RemuxApp/Sources/App/RemuxRootModel.swift`:
- Around line 281-295: Thread a SetupCancelDestination through beginServerRepair
and beginCredentialRepair into beginEditServer, using the originating terminal
destination when these flows are launched from RootView’s
onUpdateCredentials/onEditServer. Preserve the existing library fallback for
callers without a terminal context, matching beginNewWorkspace’s cancellation
behavior.

In `@RemuxApp/Sources/Ghostty/GhosttySurfaceSelectionSheet.swift`:
- Around line 527-543: Extract the duplicated TerminalSelectionSheetPalette
background, border, and selected checkmark overlay from
GhosttyWindowSelectionTile and GhosttyPaneSelectionTile into a shared
ViewModifier, such as terminalSelectionTileChrome(isSelected:chromeStyle:).
Replace the repeated blocks at
RemuxApp/Sources/Ghostty/GhosttySurfaceSelectionSheet.swift lines 527-543 and
633-649 with that modifier applied to each tile’s content, preserving the
existing selection styling and checkmark behavior at both sites.
🪄 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 Plus

Run ID: 37c32c03-d0e7-4e1a-b28a-2839ce618994

📥 Commits

Reviewing files that changed from the base of the PR and between b3c4d95 and f41c2ce.

📒 Files selected for processing (23)
  • Remux.xcodeproj/project.pbxproj
  • RemuxApp/Sources/App/ActiveSessionSwitcherView.swift
  • RemuxApp/Sources/App/ConnectionPresentation.swift
  • RemuxApp/Sources/App/RemuxActiveSessionCollection.swift
  • RemuxApp/Sources/App/RemuxRootModel.swift
  • RemuxApp/Sources/App/RootView.swift
  • RemuxApp/Sources/App/TerminalRuntimeStateIndicator.swift
  • RemuxApp/Sources/Ghostty/GhosttyKeyboardChrome.swift
  • RemuxApp/Sources/Ghostty/GhosttyKeyboardVisibilityProjection.swift
  • RemuxApp/Sources/Ghostty/GhosttySurfaceScreen.swift
  • RemuxApp/Sources/Ghostty/GhosttySurfaceSelectionSheet.swift
  • RemuxApp/Sources/Ghostty/GhosttyTerminalPresentationProjector.swift
  • RemuxApp/Sources/Ghostty/GhosttyTerminalScreenModeling.swift
  • RemuxApp/Sources/Ghostty/PanePreviewLayout.swift
  • RemuxApp/Sources/Ghostty/TerminalSelectionSheetStyle.swift
  • RemuxApp/Sources/Tmux/TmuxTerminalScreenAdapter.swift
  • RemuxAppTests/ActiveSessionSwitcherProjectionTests.swift
  • RemuxAppTests/GhosttyPhoneChromeLayoutTests.swift
  • RemuxAppTests/GhosttyTerminalPresentationProjectorTests.swift
  • RemuxAppTests/PanePreviewLayoutTests.swift
  • RemuxAppTests/RemuxRootModelTests.swift
  • RemuxAppTests/TmuxTerminalScreenAdapterTests.swift
  • RemuxAppUITests/RemuxAppUITests.swift
💤 Files with no reviewable changes (2)
  • RemuxAppTests/GhosttyTerminalPresentationProjectorTests.swift
  • RemuxAppTests/TmuxTerminalScreenAdapterTests.swift

Comment thread RemuxApp/Sources/Ghostty/PanePreviewLayout.swift
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 31, 2026

Copy link
Copy Markdown

Deploying remux with  Cloudflare Pages  Cloudflare Pages

Latest commit: 8440c85
Status: ✅  Deploy successful!
Preview URL: https://ab368f35.remux-agx.pages.dev
Branch Preview URL: https://feature-active-session-switc.remux-agx.pages.dev

View logs

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