Skip to content

Per Pane Tabs

nick3 edited this page May 28, 2026 · 1 revision

Per-Pane Tabs

A terminal pane can hold multiple tabs. Each tab is its own PTY connection — completely independent of the others, even when they all point at the same host. There is no tmux switch-client, no shared shell, no command-leakage between tabs.


The model

Terminal Pane
├── Tab 1 → PTY 1 → SSH → tmux session "clusterspace-pane-abc-1"
├── Tab 2 → PTY 2 → SSH → tmux session "clusterspace-pane-abc-2"
└── Tab 3 → PTY 3 → SSH → tmux session "clusterspace-pane-abc-3"

Each tab opens its own SSH connection. Each connection attaches to its own named tmux session on the host. Switching tabs is pure CSS: hide the old tab's xterm element, show the new one's. No commands typed, no state shared.

This is intentionally different from a tmux-window-switcher approach. We tried that first and it had three problems:

  1. The tmux switch-client -t <session> command was visible in the user's shell (race conditions between sending the command and tmux rendering).
  2. Nested tmux sessions caused unset-TMUX workarounds that were brittle.
  3. Long-running commands in one window could swallow input intended for another.

The PTY-per-tab approach gives one extra SSH process per tab (negligible cost on any reasonable machine) and complete isolation.


Creating a tab

Click the + button at the right edge of the tab strip. You'll be prompted to name the tab.

  • For local terminals, the name is just a label (and the tmux session name on the host, if you choose to wrap in tmux).
  • For SSH panes, the name doubles as the tmux session name. Pick something memorable like build, monitor, logs.

The tab strip stays out of the way: minimal until you have ≥2 tabs, then it shows up with the active tab highlighted (accent bar + solid border). Hover any tab for close (×) and rename actions.


Closing a tab

Click the × on a tab. The kill-confirm dialog asks whether to also destroy the remote tmux session:

  • Keep remote session (default) — local PTY dies, the tmux session keeps running on the host. You can reattach later from this pane or any other pane on the same host.
  • Destroy remote session — sends tmux kill-session -t <name> before killing the PTY. Use this if you're sure you don't want to come back to it.

Recovery: legacy session names

If you used ClusterSpace before the fleet-term → clusterspace rename (or just renamed a server), your old tmux sessions on the host won't match the new naming convention.

Right-click the pane → Attach to tmux session… → the picker:

  1. Auto-lists existing sessions on the host (works only with key-based SSH auth — password auth doesn't get an automatic listing because we'd have to ask you for the password again to run tmux list-sessions)
  2. Manual entry — type any session name and we'll tmux new-session -A -s <name> it (creates if absent, attaches if present)
  3. Legacy suggestion — for servers you used pre-rename, a one-click suggestion fleet-term-<server-short> is offered

The picker is the same UI for both pane-level attachment and tab-level creation.


Visual design notes

  • Active tab has a solid background, a colored accent bar at the top, and bold text
  • Inactive tabs are dashed-border to suggest "click to switch"
  • Hover lifts inactive tabs slightly and reveals the close button
  • The + button is far enough from the last tab not to be confused with it
  • When you have only one tab, the strip collapses entirely — no chrome wasted

Backend notes

The PTY manager (src/main/pty-manager.ts) keys PTYs by a compound (paneId, tabKey) so panes and tabs are addressed uniformly. The renderer maintains all tabs' xterm instances simultaneously, hiding inactive ones via CSS — guarded by a fit() check that skips when the hidden element has 0×0 dimensions (otherwise xterm throws).


See also

Clone this wiki locally