9adb459d9998d79b00737d0175664a11d5f1ccb9
Replace bare path.parent.mkdir() (no mode, defaults to umask ~0755) with _config_dir() which always creates ~/.config/muxplex with mode=0o700. This matches the pattern already used by generate_and_save_password() and ensures the config directory is never left traversable by other users. Also update the module docstring to reflect that the module now manages both passwords and signing secrets.
muxplex
Web-based tmux session dashboard — access and manage all your tmux sessions from any browser or mobile device.
Features
- Live session grid — thumbnail snapshots of every running tmux session, auto-refreshed
- Full interactive terminal — click any session to open a real terminal (powered by ttyd + xterm.js)
- Collapsible session sidebar — quick-switch between sessions without leaving the terminal view
- Bell & activity notifications — visual alerts when any session rings a bell or has new output
- Mobile-friendly responsive layout — works on phones and tablets; PWA-capable for home-screen install
- Works over Tailscale / private network — serve to any device on your network without exposing to the internet
Prerequisites
| Requirement | Notes |
|---|---|
| tmux | Must have at least one session running (tmux new -s main) |
| ttyd | WebSocket bridge — brew install ttyd (macOS) / apt install ttyd (Debian/Ubuntu) |
| Python 3.11+ | Required by the muxplex server |
Quick Start (uvx — no install)
Run muxplex directly without installing anything permanently:
uvx --from git+https://github.com/bkrabach/muxplex muxplex
Then open http://localhost:8088 in your browser.
Note:
uvxis part of uv. Install uv withcurl -LsSf https://astral.sh/uv/install.sh | sh.
Install Permanently
Install muxplex as a persistent CLI tool using uv tool:
uv tool install git+https://github.com/bkrabach/muxplex
Then run it any time with:
muxplex
Install as a Service (systemd)
User service (no sudo required)
# Install and enable the user systemd service
muxplex install-service
systemctl --user daemon-reload
systemctl --user enable --now muxplex
The service starts automatically when you log in and restarts on failure.
System-wide service (requires sudo)
# Install as a system service (runs at boot for all users)
muxplex install-service --system
sudo systemctl daemon-reload
sudo systemctl enable --now muxplex
Usage
muxplex [OPTIONS]
| Option | Default | Description |
|---|---|---|
--host HOST |
0.0.0.0 |
Interface to bind (use 127.0.0.1 to restrict to localhost) |
--port PORT |
8088 |
Port to listen on |
install-service |
— | Install a systemd service unit for muxplex |
--system |
— | (with install-service) Install as a system service instead of user service |
Examples
# Start on default host/port
muxplex
# Start on a specific port
muxplex --port 9000
# Start bound to localhost only
muxplex --host 127.0.0.1
# Install as a user systemd service
muxplex install-service
# Install as a system-wide systemd service
muxplex install-service --system
Development
Setup
git clone https://github.com/bkrabach/muxplex
cd muxplex
# Install with dev dependencies
uv pip install -e ".[dev]"
Run the server
muxplex
# or directly:
python -m muxplex
Run tests
# Python tests (pytest)
pytest
# JavaScript tests (node:test)
node --test muxplex/frontend/tests/test_terminal.mjs
node --test muxplex/frontend/tests/test_app.mjs
Architecture
muxplex/
├── pyproject.toml # Package metadata, entry points, dependencies
├── README.md # This file
├── scripts/ # Utility scripts (asset generation, etc.)
│ └── render-brand-assets.py
├── assets/
│ └── branding/ # Brand design system and generated assets
│ ├── DESIGN-SYSTEM.md
│ ├── tokens.json / tokens.css
│ ├── svg/ # Source SVG files
│ ├── og/ # Open Graph images (og-dark.png, og-light.png)
│ ├── icons/ # App icons
│ ├── favicons/ # Favicon variants
│ ├── pwa/ # PWA manifest icons
│ ├── lockup/ # Wordmark + icon lockup
│ └── wordmark/ # Text-only wordmark
└── muxplex/ # Python package
├── __init__.py
├── __main__.py # `python -m muxplex` entry point
├── cli.py # CLI argument parsing and `install-service` subcommand
├── main.py # FastAPI app: session API, bell hooks, WebSocket proxy to ttyd, static frontend
├── sessions.py # tmux session discovery and snapshot capture
├── bells.py # Bell/activity notification tracking
├── ttyd.py # ttyd process lifecycle management (spawn, kill, PID tracking)
├── state.py # Shared in-process state (sessions, bells, ttyd)
├── frontend/ # Static frontend assets (served as package data)
│ ├── index.html
│ ├── app.js
│ ├── terminal.js # xterm.js + WebSocket terminal init
│ ├── style.css
│ ├── manifest.json # PWA manifest
│ └── tests/ # JavaScript unit tests
└── tests/ # Python tests (pytest)
Brand Assets
Design language, color tokens, and brand assets live in assets/branding/. See assets/branding/DESIGN-SYSTEM.md for the full design reference.
To regenerate PNG/favicon assets from SVG sources:
python3 scripts/render-brand-assets.py
Description
Languages
Python
63.1%
JavaScript
30.5%
CSS
4%
HTML
1.4%
Go
1%
