# tabby-tmux-restore

Auto-restore tmux session attachments after SSH reconnect in Tabby.

When your PC sleeps or loses internet, SSH connections die but tmux sessions survive on the server. This plugin remembers which Tabby tab was connected to which tmux session and automatically re-attaches after SSH reconnects — zero manual steps.

## Requirements

- **Tabby** 1.0.230+ (tested on this version)
- **tmux** on the server with title sequences enabled

## Server-side setup

Add to `~/.tmux.conf` on the server:

```bash
# Send session name as terminal title
set -g set-titles on
set -g set-titles-string "#{session_name}"

# Allow passthrough of title sequences
set -g allow-passthrough on
```

Then reload: `tmux source-file ~/.tmux.conf`

## Install

### From Tabby Plugin Manager

Settings → Plugins → search `tabby-tmux-restore` → Install → Restart Tabby

### From npm (manual)

```powershell
cd %APPDATA%\tabby\plugins
npm install tabby-tmux-restore --legacy-peer-deps
```

Restart Tabby.

## How it works

1. **Title detection**: When you attach to a tmux session, tmux sends the session name as a terminal title via OSC escape sequence. The plugin captures this via Tabby's `titleChange` EventEmitter.

2. **State persistence**: The plugin saves a mapping of `{SSH profile + host → tmux session name}` to a JSON state file on disk.

3. **Reconnect detection**: When SSH reconnects (detected via `sessionChanged$` observable), the plugin looks up the saved tmux session for this tab.

4. **Auto-restore**: After a 1.5s delay (to let the shell initialize), the plugin sends `tmux attach -t <session>` to the terminal. If the first attempt doesn't succeed, it retries once at 4s.

## State file

- **Windows**: `%APPDATA%\tabby-tmux-restore\state.json`
- **macOS/Linux**: `~/.config/tabby-tmux-restore/state.json`

You can view or edit this file to see or fix tab-to-session mappings.

## Multi-tab support

The plugin supports multiple tabs to the same server with different tmux sessions. It uses Tabby's **custom tab title** (`customTitle`) to disambiguate tabs:

- When a tmux session is detected (e.g., "ops"), the plugin sets `customTitle = "tmux:ops"`
- This makes each tab's state key unique, even with the same SSH profile
- Tabby persists `customTitle` in its recovery token, so it survives restarts

**Important**: The plugin manages `customTitle` for SSH tabs where tmux sessions are detected. If you manually clear or edit the custom title (removing the `tmux:` prefix), that tab reverts to single-slot-per-host behavior.

## Known limitations

- **Session name format**: Only tmux session names matching `^[a-zA-Z][a-zA-Z0-9_-]{0,63}$` are detected. Names starting with numbers or containing special characters are ignored (to avoid false positives from shell prompts).

- **tmux colons**: tmux converts `:` in session names to `_` (colon is reserved as tmux's separator). Use hyphens instead.

- **customTitle ownership**: The plugin overwrites `customTitle` on SSH tabs when a tmux session is detected. Manual custom titles set by the user will be replaced with `tmux:<session>`. Clearing the custom title opts the tab back into legacy single-slot behavior.

## Troubleshooting

- **Tab title not updating**: Verify `set-titles on` and `allow-passthrough on` are in your tmux.conf and reloaded.
- **Plugin not loading**: Tabby requires an `author` field in package.json. If you build from source, ensure it's present.
- **Not auto-attaching after reconnect**: Check `state.json` has the correct mapping. The plugin waits 1.5s after reconnect before sending the command.
- **Wrong session attached**: Delete the entry from `state.json` and re-attach manually. The plugin will learn the new mapping.

## Development

```bash
npm install --legacy-peer-deps
npm run build      # production build
npm run watch      # dev build with watch
```

Built with TypeScript 5.x. Peer dependencies (`tabby-core`, `tabby-terminal`) are provided by Tabby at runtime.

## License

MIT
