crmux 0.7.0

A TUI viewer for Claude Code sessions in tmux
crmux-0.7.0 is not a library.

crmux

A TUI viewer for Claude Code sessions in tmux.

Inspired by cmux. crmux brings a similar multi-session management experience using tmux and a terminal UI.

  • Monitor multiple Claude Code sessions from a single sidebar and preview their output
  • Mark sessions to preview multiple panes simultaneously
  • Switch to any session's tmux pane instantly
  • Send prompts directly via tmux send-keys in input mode without leaving crmux
  • Pulse animation to highlight sessions that need attention (approval idle, stale idle)

Demo

gif

Prerequisites

Installation

From crates.io (Recommended)

cargo install crmux

After installation, make sure ~/.cargo/bin is in your PATH, then you can run:

crmux

Build from source

git clone https://github.com/maedana/crmux.git
cd crmux
cargo build --release

Usage

Run inside a tmux session:

crmux

Keybindings

Keybindings are shown in the app footer. Run crmux -h or press ? in the app to see all available keybindings.

Claude Code Hook Setup (Optional)

By configuring Claude Code hooks, crmux can display additional session metadata such as the model name and context window usage.

Add the following to ~/.claude/settings.json:

{
  "hooks": {
    "SessionStart": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "crmux notify session-start"
          }
        ]
      }
    ]
  }
}

To also display model display name (e.g. "Opus") and context window usage percentage, configure a statusLine command. The simplest setup uses crmux notify status-update directly:

{
  "statusLine": {
    "type": "command",
    "command": "crmux notify status-update",
    "padding": 0
  }
}

Note: The statusLine command's stdout is used as Claude Code's own status line display. Since crmux notify produces no output, Claude Code's status line will be blank with this setup. If you want both crmux sidebar info and Claude Code's status line, use a wrapper script instead.

Create ~/.local/bin/ccstatus:

#!/bin/bash
input=$(cat)

# Notify crmux of status update (non-blocking)
echo "$input" | crmux notify status-update &

MODEL=$(echo "$input" | jq -r '.model.display_name')
CONTEXT_SIZE=$(echo "$input" | jq -r '.context_window.context_window_size')
USAGE=$(echo "$input" | jq '.context_window.current_usage')

if [ "$USAGE" != "null" ]; then
    CURRENT_TOKENS=$(echo "$USAGE" | jq '.input_tokens + .cache_creation_input_tokens + .cache_read_input_tokens')
    PERCENT_USED=$((CURRENT_TOKENS * 100 / CONTEXT_SIZE))
    echo "[$MODEL] Context: ${PERCENT_USED}%"
else
    echo "[$MODEL] Context: 0%"
fi
{
  "statusLine": {
    "type": "command",
    "command": "ccstatus",
    "padding": 0
  }
}

Roadmap

  • Display worktree info per session
  • Programmatic control from external tools (e.g. tmux-style subcommands, MCP server)

Limitations

Input mode uses tmux send-keys to forward keystrokes, which has inherent limitations:

  • Modifier keys: Some modifier key combinations (e.g. Shift+Enter, Ctrl+Enter) cannot be accurately reproduced via tmux send-keys
  • Terminal dependency: Terminals without Kitty keyboard protocol support (VTE-based terminals such as XFCE Terminal, GNOME Terminal) cannot distinguish some modified key events from their unmodified counterparts
  • Paste on macOS: Cmd+v is intercepted by the terminal emulator and never reaches crmux as a key event. Text paste works via bracketed paste, but image paste (used by Claude Code) cannot be forwarded. On Linux, Ctrl+v is forwarded as a key event, so image paste works through the target Claude Code session.

License

MIT