# cmux-ctl

[![PyPI version](https://img.shields.io/pypi/v/cmux-ctl)](https://pypi.org/project/cmux-ctl/)
[![Python 3.10+](https://img.shields.io/pypi/pyversions/cmux-ctl)](https://pypi.org/project/cmux-ctl/)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)

A terminal dashboard for orchestrating [cmux](https://cmux.dev) workspaces and [Claude Code](https://docs.anthropic.com/en/docs/claude-code) agents.

Built with [Textual](https://textual.textualize.io/).

![cmux-ctl dashboard](https://raw.githubusercontent.com/alaasdk/cmux-ctl/main/docs/screenshot.png)

## Features

- **Real-time dashboard** — grid of workspace cards, auto-refreshing every 3 seconds
- **Agent state tracking** — running, waiting for input, idle, with color-coded borders
- **Live terminal preview** — last 15 lines of each workspace's terminal output
- **Launch agents** — start Claude Code in new or existing workspaces from the dashboard
- **Send input / stop agents** — interact with agents without switching windows
- **Notification badges** — unread alerts surfaced per workspace
- **Stale detection** — agents whose output hasn't changed in 30s are flagged
- **Keyboard-first** — full grid navigation, no mouse required
- **Web mode** — run the same dashboard in your browser via `textual-serve`

## Prerequisites

- macOS with [cmux](https://cmux.dev) installed and running
- Python 3.10+

## Installation

### pipx (recommended)

```bash
pipx install cmux-ctl
```

### pip

```bash
pip install cmux-ctl
```

### From source

```bash
git clone https://github.com/alaasdk/cmux-ctl.git
cd cmux-ctl
pip install -e .
```

## Usage

### Terminal

```bash
cmux-ctl
```

### Browser

```bash
pip install cmux-ctl[web]
cmux-ctl-web
```

Opens the dashboard at `http://localhost:8000`. Pass `--host 0.0.0.0` to expose on your network, or `--port 3000` to change the port.

The dashboard connects to cmux automatically and displays all active workspaces.

## Keybindings

| Key | Action |
|---|---|
| `q` | Quit |
| `r` | Refresh |
| `l` | Launch agent |
| `s` | Stop agent (sends Ctrl+C) |
| `i` | Send input to agent |
| `Enter` | Switch to workspace in cmux |
| `Tab` / `Shift+Tab` | Next / previous card |
| Arrow keys | Grid navigation |

## Configuration

| Environment Variable | Description | Default |
|---|---|---|
| `CMUX_BIN` | Path to the cmux binary | `/Applications/cmux.app/Contents/Resources/bin/cmux` |

## How it works

cmux-ctl communicates with cmux entirely through its CLI:

1. **`cmux tree --all --json`** — discovers all workspaces, panes, and surfaces
2. **`cmux sidebar-state`** — reads workspace metadata (cwd, git branch, PR links, agent state)
3. **`cmux read-screen`** — captures terminal output for live preview
4. **Session map** (`/tmp/cmux-session-map.json`) — detects active Claude Code sessions

The dashboard polls every 3 seconds for workspace state and every 2 seconds for terminal content. Agent state is determined from sidebar metadata, screen content heuristics (e.g., detecting Claude Code's UI patterns), and the session map.

## Development

```bash
git clone https://github.com/alaasdk/cmux-ctl.git
cd cmux-ctl
pip install -e ".[web]"

# Run with Textual dev mode (live CSS reload, console)
make dev

# Run in browser
make web
```

## License

[MIT](LICENSE)
