26e2baa89c2daeb89ca6692e739131c56f4c745c
Before: openTerminal() never closed the previous WebSocket. After A→B→A, two WS connections to session A both wrote to _term → double keystroke echoes. Rapid switches triggered a CONNECTING-state send error and reconnect loop. After: openTerminal() nulls _currentSession, clears reconnect timer, and closes _ws before opening a new connection. connect() event handlers now capture the WS instance in a local const and check 'ws !== _ws' on entry so stale connections silently ignore all events. Tests: three new regression tests verify: - openTerminal() calls close() on the previous WS (Bug 1) - stale open handler does not send on new WS after switch (Bug 2) - stale close handler does not schedule reconnect after switch (Bug 2)
muxplex
A web-based dashboard for tmux sessions. Access and manage all your tmux sessions from any device — browser, phone, tablet.
Features
- Live tile grid showing all running tmux sessions
- Click any session to open a full interactive terminal
- Bell/activity notifications across sessions
- Multi-device support with state sync
- Mobile-friendly, responsive, PWA-capable
- Works over Tailscale private network
Stack
- Backend: Python FastAPI coordinator (
coordinator/) - Frontend: Vanilla JS + xterm.js (
frontend/) - Terminal: ttyd (WebSocket bridge to tmux)
- Proxy: Caddy
Running
# Install dependencies
pip install -r requirements.txt
# Start coordinator (from this directory)
python -m uvicorn coordinator.main:app --host 0.0.0.0 --port 8099
# Start Caddy proxy
caddy run --config Caddyfile
Development
# Run tests
python -m pytest
Brand assets
Design language, tokens, and brand assets in assets/branding/.
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%