muxplex
Web-based tmux session dashboard — access, monitor, and manage all your tmux sessions from any browser on any device.
Features
Dashboard
- Live session grid — preview tiles with ANSI-colored terminal snapshots, auto-refreshed
- Two view modes — Auto (scrollable grid) and Fit (all sessions fill the viewport)
- Hover preview — full-size overlay of session content on tile hover
- Activity indicators — bell notification badges on tiles; amber favicon dot +
(N)count in browser tab title when sessions have unseen activity - Session creation —
+button with device selector dropdown when multi-device is enabled; custom command template support - Session deletion —
×button with custom command template support - Mobile-friendly — responsive layout, PWA-capable for home-screen install
Terminal
- Full interactive terminal — powered by xterm.js + ttyd
- Native clipboard — Ctrl+Shift+C to copy, Cmd+V (macOS) / Ctrl+Shift+V (Linux) to paste
- Mouse select auto-copy — selecting text copies to system clipboard on release
- OSC 52 tmux clipboard bridge — tmux copy mode selections go to system clipboard
- Search — Ctrl+F opens a search bar to find text in terminal scrollback (xterm-addon-search)
- Clickable URLs — Ctrl+Click (Cmd+Click on macOS) opens URLs in terminal output in a new tab (xterm-addon-web-links)
- Inline image rendering — Sixel and iTerm2 graphic protocols for tools like yazi file manager (xterm-addon-image)
- Sidebar session switcher — quick-switch between sessions with live previews
Settings
- In-browser settings panel — gear icon or
,shortcut - Display — font size, grid columns, hover delay, view mode, device badges, activity indicator
- Sessions — default session, sort order, hidden sessions, auto-open, bell sound, notifications
- Commands — custom create/delete session templates
- Multi-Device — remote instance federation
- CLI —
muxplex config list/get/set/reset
Multi-Device
- Remote session aggregation — federate multiple muxplex instances into a unified dashboard view
- Device selector in new session —
+button shows a device dropdown when multi-device is enabled; create sessions on any connected instance directly from the dashboard - Remote bell-clear — opening a session on a remote device automatically clears its activity notification via federation API (
POST /api/bell/clear) - Unique session keys — sessions identified by
remoteId:nameacross devices, preventing bell-state collisions for identically-named sessions on different machines
Service Management
muxplex service install/start/stop/restart/status/logs/uninstall- Platform-aware — systemd user service on Linux/WSL, launchd agent on macOS
- Config-driven — service reads all options from
~/.config/muxplex/settings.json(no flags in the service file)
Authentication
- PAM authentication — Linux/macOS system credentials
- Password mode — auto-generated or set via
MUXPLEX_PASSWORDenv var - Localhost bypass — no auth needed on 127.0.0.1
- Secure session cookies — signed with configurable TTL
Developer Tools
muxplex doctor— dependency + config diagnostics with update checkmuxplex upgrade— smart version check + auto-update + service restartmuxplex config— CLI settings management
Agents & Automation
- Public HTTP API — the contract is discoverable at
/openapi.jsonand/docs; headless clients authenticate with a Bearer federation key - Terminal input over the API —
POST /api/sessions/{name}/inputlets an agent type into a live session (RCE by design, default-CLOSED, fenced byinput_enabled+input_allowed_sessions) - Vendor-neutral guide — point any agent (or a
curlscript) at Driving muxplex from an agent
HTTPS / TLS
muxplex setup-tls— auto-detect and set up TLS certificates- Tailscale — real Let's Encrypt certs via
tailscale cert(recommended when every client has Tailscale) - mkcert — locally-trusted certs, zero browser warnings (when mkcert is installed on each client)
- Local CA — persistent root CA + signed leaf for browser-trusted HTTPS on plain LAN names (
spark-1,192.168.1.5) without Tailscale or a public domain; install the CA once per client → see Trusting the local CA - Self-signed — fallback for immediate HTTPS (browser shows warning)
- Required for browser clipboard API on non-localhost, and for stable PWA install (browsers refuse to keep installed PWAs in standalone mode against an untrusted origin)
Prerequisites
- Python 3.11+ — installed via
uvor system Python - tmux — terminal multiplexer
- macOS:
brew install tmux - Ubuntu/WSL:
sudo apt install tmux
- macOS:
- ttyd — terminal sharing over HTTP (required for interactive terminal access)
- macOS:
brew install ttyd - Ubuntu/WSL:
sudo apt install ttydorsudo snap install ttyd - Other: https://github.com/tsl0922/ttyd#installation
- macOS:
Tip: Run
muxplex doctorto check all dependencies and system status.
Quick Start (uvx — no install)
Run muxplex directly without installing anything permanently:
uvx 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
uv tool install muxplex
muxplex doctor # verify dependencies
Upgrade later with either:
uv tool upgrade muxplex # standard uv workflow
muxplex upgrade # also restarts the service if installed
Installing from git instead?
uv tool install git+https://github.com/bkrabach/muxplextracks the default branch and gets unreleased commits. Do not pin a tag (...@v1.2.3) unless you mean it:uv tool upgraderesolves strictly within the recorded requirement, so a pinned rev reports "Nothing to upgrade" forever. Released versions on PyPI are the recommended path.
Then run it any time with:
muxplex
Install as a Service
muxplex service install
# → prompts to set host to 0.0.0.0 for network access
The service starts automatically on login (macOS) or at boot (Linux) and restarts on failure.
# Open in browser
open http://localhost:8088
To stop and remove:
muxplex service uninstall
CLI Reference
muxplex Start server (default)
muxplex serve [flags] Start with CLI flag overrides
muxplex service install Install + enable + start as OS service
muxplex service uninstall Stop + disable + remove
muxplex service start|stop|restart Manage running service
muxplex service status Show service status
muxplex service logs Tail service logs
muxplex config Show all settings
muxplex config get <key> Show one setting
muxplex config set <key> <value> Set a setting
muxplex config reset [key] Reset one or all to defaults
muxplex upgrade [--force] Smart update with version check
muxplex doctor Check dependencies + config
muxplex show-password Show current auth password
muxplex reset-secret Regenerate signing secret
muxplex setup-tls [--method auto] Set up TLS certs (Tailscale/mkcert/self-signed)
muxplex setup-tls --status Show current TLS configuration
muxplex env Print `eval`-able TMUX_TMPDIR export
muxplex tmux status Show whether muxplex's tmux config is active
muxplex tmux install [--dry-run] Install muxplex's tmux config (safe, reversible)
muxplex tmux uninstall Remove it, leaving your own config untouched
Service management
muxplex service install # Write service file + enable + start
muxplex service uninstall # Stop + disable + remove service file
muxplex service start # Start the service
muxplex service stop # Stop the service
muxplex service restart # Stop + start
muxplex service status # Show running/stopped + PID
muxplex service logs # Tail service logs
The service runs muxplex serve with no flags — it reads all options from ~/.config/muxplex/settings.json. To change host/port, edit the config (or use the Settings UI in the browser) and restart:
muxplex config set host 0.0.0.0
muxplex service restart
Recovering from a failed upgrade (v0.56.2 and earlier)
On v0.56.2 and earlier, muxplex upgrade (and its muxplex update alias) could leave the service down after a successful install. The upgrade process replaced muxplex's on-disk package files, then kept running its post-install steps (ensure the embedded agent panel is current, regenerate the service file, restart it) in that same, already-running process — which still had the old version of muxplex.cli / muxplex.service loaded in memory. A lazy cross-module import of a name that only existed in the new code could then fail with:
ImportError: cannot import name 'ensure_agent' from 'muxplex.cli'
leaving the service stopped even though the new version installed correctly.
muxplex v0.57.0+ fixes this at the root: upgrade() now hands the post-install steps off to a brand-new process of the just-installed version (an internal muxplex _finish-upgrade step), so those imports always resolve against the new code, never a stale cached module.
If you hit this on an affected version and the service is down after an upgrade, recover with:
muxplex service install # regenerates the service file and restarts it
# from whatever version is actually installed on disk
muxplex doctor # confirm the service is running again
muxplex service install is safe to run any time — it rebuilds the service file from scratch and doesn't depend on any in-memory state left over from a failed upgrade.
Examples
# Start with defaults from settings.json
muxplex
# Override port for this run only
muxplex --port 9000
# Override host for this run only
muxplex serve --host 0.0.0.0
HTTPS / TLS setup
# Auto-detect the best TLS method and set up certificates
muxplex setup-tls
# Use a specific TLS method
muxplex setup-tls --method tailscale
muxplex setup-tls --method mkcert
muxplex setup-tls --method selfsigned
muxplex setup-tls --method ca # persistent local CA + signed leaf
# Show current TLS status and configuration
muxplex setup-tls --status
# Override TLS cert/key for a single run (without saving to config)
muxplex serve --tls-cert /path/cert.pem --tls-key /path/key.pem
# Check TLS configuration and dependencies
muxplex doctor
Auto-detection priority: Tailscale (if tailscale is installed and a cert is available) → mkcert (if mkcert is installed) → self-signed (always available as a fallback). Use --method to override.
Note: Tailscale certs have a 90-day expiry. Run
muxplex setup-tls --method tailscaleto renew when needed.
When to use --method ca
The ca method is for the case where you want browser-trusted HTTPS on plain LAN names (e.g. https://my-host:8088, https://192.168.1.5:8088) but can't use Tailscale (no client install, blocked by IT policy, or the URL must be the bare LAN name) and don't want to buy a public domain.
It generates a persistent root CA in ~/.config/muxplex/ca/ and signs a 13-month leaf with it. The leaf's SAN automatically includes the hostname, <hostname>.local, localhost, the primary LAN IPv4 address, and the Tailscale MagicDNS name (if Tailscale is connected). Install the CA (not the leaf) once on each client; subsequent leaf rotations don't require re-trusting.
Not part of the auto cascade — must be opted into explicitly.
→ See docs/TRUSTING_THE_LOCAL_CA.md for per-platform install instructions (Windows, macOS, Linux, iOS, Android, Firefox).
Fetching the CA over the network: GET /api/ca
Installing the CA on each client previously required scp-ing it off the server, which needs SSH access the client may not have — and it's easy to grab the wrong file (muxplex.crt, the leaf the server presents on the wire) instead of the CA, producing "unable to get local issuer certificate". GET /api/ca serves the CA's public certificate directly over HTTP(S) — no SSH, no auth (a CA public cert isn't a secret; it's the trust anchor clients are meant to install), and no ambiguity about which file it is:
curl -k https://my-host:8088/api/ca -o muxplex-ca.crt
-k is acceptable only for this one bootstrap fetch of a public trust anchor (there's nothing sensitive to expose by skipping verification here). For high-trust setups, confirm the fingerprint out-of-band before trusting it:
openssl x509 -in muxplex-ca.crt -noout -fingerprint -sha256
Returns 404 if this server isn't using setup-tls --method ca (e.g. it's on Tailscale, mkcert, or self-signed instead).
tmux socket (the "invisible session" hazard)
muxplex looks for tmux sessions under a specific socket directory (the
tmux_socket_dir setting, mapped to tmux's TMUX_TMPDIR environment
variable). Any other tool or script that creates a tmux session without
setting the same TMUX_TMPDIR lands on a different tmux server and is
silently invisible to muxplex — tmux list-sessions from your interactive
shell will show it, but muxplex's dashboard, API, and Stream Deck sidecar
never will, because they're watching a different socket. This bites hardest
when tmux_socket_dir is left at its default (""): a systemd/launchd
service process doesn't inherit your login shell's TMUX_TMPDIR, so the
service quietly falls back to tmux's compiled-in default
(/tmp/tmux-$UID) even if your shell rc sets something else.
The one-line fix — run this before creating a session you want muxplex to see:
eval "$(muxplex env)"
tmux new-session -d -s my-session # now lands where muxplex can see it
muxplex env prints a single export TMUX_TMPDIR=... line (nothing else,
so eval is always safe) resolved from the configured tmux_socket_dir —
or, if that's unset, your shell's own TMUX_TMPDIR — or, failing both,
tmux's own default. GET /api/instance-info also exposes tmux_socket_dir
(the exact value the running server resolves, since that endpoint runs
inside the server process itself) so remote tools/agents can discover it
without SSH access or tribal knowledge.
Configuration
All settings are stored in ~/.config/muxplex/settings.json.
A † on a key means local-file-only (settings.LOCAL_ONLY_KEYS): it can
ONLY be changed by editing settings.json on disk. muxplex config set refuses
it with an error, PATCH /api/settings silently ignores it, and federation never
syncs it. See Editing local-file-only keys below.
| Key | Default | Description |
|---|---|---|
host |
127.0.0.1 |
Bind address (set to 0.0.0.0 for network access) |
port |
8088 |
Server port |
auth |
pam |
Authentication mode: pam or password |
session_ttl |
604800 |
Session cookie TTL in seconds (7 days; 0 = browser session) |
default_session |
null |
Session to auto-open on load |
sort_order |
manual |
Session ordering: manual, alphabetical, recent |
session_filter |
"" |
fnmatch-style glob pattern (case-insensitive), matched against each session's bare name, narrowing the grid and sidebar to matching sessions only. Empty string = no filter. Does not affect the favicon badge, page title, or mobile bottom sheet -- a filtered-out session's bell still surfaces there. |
hidden_sessions |
[] |
Sessions hidden from the dashboard |
views |
[] |
Named session views for grouping and filtering sessions. Each view entry may carry an optional match_names: [str] -- fnmatch-style glob patterns matched case-insensitively against a session's bare tmux name (never a device-qualified device_id:name key, since the qualifier is a UUID nobody would type). A session is in the view if it is pinned in sessions or matches a pattern -- a strict union; rules are resolved fresh on every read and never written back into sessions, so a rule-based view cannot decay. See docs/API_SEMANTICS.md and GET /api/views. |
stale_key_grace_hours |
24.0 |
Hours before a session key absent from all known live sessions is pruned from views/hidden_sessions (syncable; per-device bookkeeping is local-only). Federation-aware: a remote device's keys are only ever evaluated for pruning while that device is currently reachable (see "Stale-key pruning" below) -- an offline device's view membership is never touched. |
window_size_largest |
false |
Auto-set tmux window-size largest on connect |
auto_open_created |
true |
Auto-open newly created sessions |
new_session_template † |
tmux new-session -d -s {name} |
Command template for creating sessions |
delete_session_template † |
tmux kill-session -t {name} |
Command template for deleting sessions |
session_commands † |
[] |
Additional NAMED create/kill command pairs (see "Command pairs" below) |
tmux_theme |
brand |
Which shipped tmux theme muxplex tmux install renders. brand is built from muxplex's own UI tokens, so a window that rings a bell turns the same amber in your terminal that its tile turns in the dashboard. Alternatives: steel, catppuccin-mocha. Not federation-syncable -- it renders to a file on this host. |
tmux_copy_mode |
desktop |
Which copy-mode keybinding scheme muxplex tmux install (and PATCH /api/tmux-config) renders as ~/.config/muxplex/tmux.d/30-copy-mode.conf. desktop is tmux's own default (arrow keys, Page Up/Down, Home/End, and Ctrl+C behave like every other desktop text field; no fragment is written). vi renders the modal v/y selection flow for vi/vim muscle memory. Not federation-syncable -- it renders to a file on this host. |
input_enabled † |
false |
Global opt-in for POST /api/sessions/{name}/input (typing into sessions over the API). RCE by design — false makes the endpoint a hard 403. Local-file-only: can ONLY be set by editing settings.json on disk — deliberately not settable via PATCH /api/settings (a Bearer-key holder must not be able to self-authorize input) and not federation-syncable. |
input_allowed_sessions † |
["*"] (all sessions) |
Glob patterns (matched case-INsensitively — both name and pattern are .casefold()-ed before fnmatch.fnmatchcase, so behavior is deterministic across platforms) naming sessions that may receive API terminal input. The default is ["*"] — every session — so turning input_enabled on is all you need; you do not have to enumerate session names. Narrow it when you want to: ["amplifier-*"] for a prefix family, or an exact name (matches only itself). Both the list ["*"] and the bare string "*" are accepted. A session matching none of the patterns is a 403 even when input_enabled is true. Empty list = deny everything. This default changed — it used to be [] (deny-all), which meant flipping input_enabled on did nothing by itself; see the note below the table. Local-file-only: can ONLY be set by editing settings.json on disk — deliberately not settable via PATCH /api/settings and not federation-syncable. |
tmux_socket_dir † |
"" |
Override tmux's socket directory (maps to TMUX_TMPDIR). Set this if your tmux sessions live somewhere other than /tmp/tmux-$UID (e.g. a custom TMUX_TMPDIR in your shell rc) -- a systemd/launchd service does not inherit your login shell's environment, so without this the service can't see sessions created with a custom socket directory. |
focus_app † |
"" |
macOS only. The .app bundle name POST /api/focus runs open -a against to bring the muxplex PWA window to the foreground on this host. Empty = unconfigured (the endpoint returns 409 rather than silently doing nothing). Wayland and Windows are not supported -- Wayland has no portable activation path a headless server process can use; Windows has no muxplex port at all (see docs/API_SEMANTICS.md's POST /api/focus section for the full platform table). Local-file-only: can ONLY be set by editing settings.json on disk -- not settable via PATCH /api/settings and not federation-syncable. |
device_name |
"" (hostname) |
Display name for this device |
federation_key |
"" |
Server-to-server authentication key for federation |
remote_instances |
[] |
Remote muxplex instances to aggregate |
multi_device_enabled |
false |
Enable multi-instance federation |
tls_cert † |
"" |
Path to TLS certificate file (empty = HTTP) |
tls_key † |
"" |
Path to TLS private key file (empty = HTTP) |
fontSize |
14 |
Terminal font size (px) |
previewFontSize |
11 |
Tile/sidebar preview text font size (px), 8-24. Independent of fontSize, which drives only the live terminal. |
previewZoom |
100 |
Tile size / grid minimum column width scale (%), 50-200. 100 reproduces the default sizing. |
hoverPreviewDelay |
1500 |
Hover preview popup delay (ms). 0 = Off. The sole control for the popover (as of v0.47.0; folds in the retired showHoverPreview checkbox -- see below) |
gridColumns |
"auto" |
Number of grid columns ("auto" or integer) |
bellSound |
false |
Play audio sound on terminal bell |
viewMode |
"auto" |
Grid tile sizing: auto or fit |
deviceLabelPlacement |
"titlebar" |
Where a session's device label is drawn: titlebar (in the tile/sidebar header, the default), corner (inside the preview, anchored lower right), or off (not drawn). Presentation only — views store device-qualified keys, so session identity is unaffected. Honored by the PWA only; the soft deck and the muxplex-deck sidecar draw no device label at all. |
showDeviceBadges |
true |
Derived — do not edit. Maintained by the server as deviceLabelPlacement != "off". Retained so pre-v0.36 clients keep working; set deviceLabelPlacement instead. |
activityIndicator |
"both" |
Activity style: none, glow, dot, both |
gridViewMode |
"flat" |
Multi-device grid layout: flat, grouped, filtered |
sidebarOpen |
null |
Sidebar state: true, false, or null (auto-detect from screen width) |
agentPanelOpen |
null |
Agent chat panel state: true, false, or null (never toggled -- stays closed, unlike sidebarOpen there is no screen-width auto-detect) |
composeBarOpen |
null |
Terminal compose bar (typed input into a tmux session) state: true, false, or null (never toggled -- resolves to visible on every device width, more discoverable than the old mobile-only default) |
settings_updated_at |
0.0 |
Unix timestamp of last settings write (used for federation sync) |
views_updated_at |
0.0 |
Unix timestamp of last change to views/hidden_sessions specifically. Metadata like settings_updated_at, used to arbitrate views-specific federation sync conflicts independently of unrelated field changes (e.g. a fontSize edit no longer bumps this). Not itself a syncable setting -- see docs/API_SEMANTICS.md. |
Priority: CLI flags > settings.json > defaults.
Editing local-file-only keys
Keys marked † above are refused by the write path, by design:
$ muxplex config set focus_app "Muxplex"
error: 'focus_app' is local-file-only and cannot be set through patch_settings()
Edit the file directly instead. The path is the same on every platform —
~/.config/muxplex/settings.json — because it always derives from $HOME
(XDG_CONFIG_HOME is ignored):
$EDITOR ~/.config/muxplex/settings.json # add "focus_app": "Muxplex"
curl -s localhost:8088/api/instance-info # verify the SERVER sees it
Most †-keys take effect on the next request — no restart. The server
re-reads settings.json from disk every time it consults a setting (the same
way the federation key is read fresh per request), so a † edit is live as soon
as the file is saved. tls_cert / tls_key are the exception: muxplex serve
reads them once at startup to build its listener, so changing those needs
muxplex service restart.
Two things that make a good edit look like a no-op:
- A JSON syntax error silently discards the whole file. A stray trailing
comma reverts every setting to its default — no error, nothing in the
server log. If a change appears to do nothing, validate first:
python3 -m json.tool ~/.config/muxplex/settings.json. - A hand edit does not bump
settings_updated_at. Clients that refetch only when that timestamp changes won't notice; reload the PWA to pick the change up. The server itself is unaffected — it never consults the timestamp when reading.
⚠️ The terminal-input allowlist default changed.
input_allowed_sessionsused to default to[]— deny every session — so settinginput_enabled: truedid nothing on its own; you hit a second 403 and had to list session names by hand before anything worked. It now defaults to["*"], every session.What that means for you: turning
input_enabledon is now a single action that makes every session typeable over the API, including your own working panes. If you only want some sessions reachable, you must now say so explicitly, e.g."input_allowed_sessions": ["agent-*"]. What did not change:input_enabledis stillfalseout of the box, and both keys are still local-file-only — neither the API, a federation peer, nor an agent can set them.
→ Writing something that drives muxplex? The rows above define
input_enabled/input_allowed_sessionsas configuration. For the operational side — auth, the read endpoints, session lifecycle, the terminal-input contract and its threat model, and copy-pasteablecurlexamples — see docs/AGENT_GUIDE.md. It's vendor-neutral: point any agent or script at it.
Keyboard Shortcuts
| Shortcut | Action |
|---|---|
| Ctrl+Shift+C | Copy terminal selection to system clipboard |
| Cmd+V / Ctrl+Shift+V | Paste from system clipboard (native browser paste) |
| Ctrl+F | Open terminal search bar |
| Enter / Shift+Enter | Next / previous search match |
| Ctrl+Click (Cmd+Click) | Open URL in new tab |
, (comma) |
Open settings |
| Escape | Close settings / return to dashboard |
Mouse select in the terminal auto-copies to the system clipboard on release.
Platform Support
| Platform | Service | Auth |
|---|---|---|
| Linux (Ubuntu/Debian) | systemd user service | PAM |
| macOS | launchd agent | PAM |
| WSL | systemd user service | PAM |
POST /api/focus (foreground-focus for the muxplex PWA window) is
macOS-only. Linux/X11 is unreliable (a systemd user service doesn't
reliably carry DISPLAY), Wayland cannot work at all (no portable
activation path a headless server process can use), WSL has a Windows
browser window to raise rather than a Linux one, and Windows has no
muxplex port at all. See docs/API_SEMANTICS.md's POST /api/focus
section for the full per-platform table.
Project Structure
muxplex/
├── muxplex/
│ ├── __init__.py
│ ├── __main__.py # python -m muxplex entry
│ ├── cli.py # CLI entry point and subcommand dispatch
│ ├── main.py # FastAPI app, routes, WebSocket proxy
│ ├── auth.py # PAM/password auth middleware
│ ├── sessions.py # tmux session enumeration + snapshots
│ ├── bells.py # Bell flag detection + clear rules
│ ├── state.py # Persistent state (JSON)
│ ├── settings.py # User settings management
│ ├── service.py # Service install/start/stop (systemd + launchd)
│ ├── ttyd.py # ttyd process lifecycle
│ ├── frontend/
│ │ ├── index.html # Main SPA
│ │ ├── login.html # Login page
│ │ ├── app.js # Dashboard, sidebar, settings, previews
│ │ ├── terminal.js # xterm.js terminal + clipboard
│ │ ├── tokens.css # Design tokens — the ONE home for every value
│ │ ├── style.css # All styles (dark theme)
│ │ ├── manifest.json # PWA manifest
│ │ ├── wordmark-on-dark.svg
│ │ └── tests/ # JavaScript unit tests
│ └── tests/ # Python tests (pytest)
├── assets/branding/ # Logos, icons, design system
├── docs/plans/ # Historical design + implementation plans
├── scripts/ # Utility scripts (asset generation)
├── pyproject.toml
└── README.md
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)
python -m pytest muxplex/tests/ --ignore=muxplex/tests/test_integration.py
# JavaScript tests (node:test)
node --test muxplex/frontend/tests/test_terminal.mjs
node --test muxplex/frontend/tests/test_app.mjs
Brand Assets
Brand assets — logos, icons, favicons, OG images — live in assets/branding/.
Design language and colour tokens do not. They live in
docs/DESIGN_LANGUAGE.md (principles, components,
decisions) and muxplex/frontend/tokens.css
(every value). That is the one place to look up a token.
assets/branding/DESIGN-SYSTEM.md is superseded and kept only as brand
provenance — its palette derivation and contrast ratios are still good, its CSS
values are not. Nine of them silently disagreed with what the app renders; see
docs/DESIGN_LANGUAGE.md §3.4.
To regenerate PNG/favicon assets from SVG sources:
python3 scripts/render-brand-assets.py
Using muxplex with Amplifier (optional)
muxplex does not depend on Amplifier — Amplifier is just one optional way to drive it. A behavior bundle at bkrabach/amplifier-bundle-muxplex lets AI agents list, create, and monitor muxplex sessions with the server URL, federation key, and CA trust resolved for you instead of per-consumer.
Install it as a behavior bundle at the app level — added to your own Amplifier app/bundle configuration. It is not something muxplex itself pulls in.
→ See docs/AMPLIFIER.md for setup. Driving the raw API without Amplifier? docs/AGENT_GUIDE.md.
License
MIT
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file muxplex-0.58.0.tar.gz.
File metadata
- Download URL: muxplex-0.58.0.tar.gz
- Upload date:
- Size: 3.4 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2fc0177b3f48bf6132a0133eae0a8c16f934918d46567547eab4530a0d311697
|
|
| MD5 |
8aa3b0e4ccc1216f9c377ede0e213c6b
|
|
| BLAKE2b-256 |
c7d160b3c4f35a2d1927f024ae3aa4aadbb9c347de30bff3c968449d55ecaec2
|
Provenance
The following attestation bundles were made for muxplex-0.58.0.tar.gz:
Publisher:
publish.yml on bkrabach/muxplex
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
muxplex-0.58.0.tar.gz -
Subject digest:
2fc0177b3f48bf6132a0133eae0a8c16f934918d46567547eab4530a0d311697 - Sigstore transparency entry: 2534221280
- Sigstore integration time:
-
Permalink:
bkrabach/muxplex@89bd5ef13e00e4be7530f717dcbf596fd0cfcd6c -
Branch / Tag:
refs/tags/v0.58.0 - Owner: https://github.com/bkrabach
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@89bd5ef13e00e4be7530f717dcbf596fd0cfcd6c -
Trigger Event:
push
-
Statement type:
File details
Details for the file muxplex-0.58.0-py3-none-any.whl.
File metadata
- Download URL: muxplex-0.58.0-py3-none-any.whl
- Upload date:
- Size: 1.3 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4a6599fec5b35de10320acf27e9b1cb1a6853434f93902948901ab7e9365a254
|
|
| MD5 |
8560a45721c22be51f75d2500f487d54
|
|
| BLAKE2b-256 |
dd7ddf76d0b071a52efaf0aecad57b29515d3102a9a0a4543b898c665e2aab6a
|
Provenance
The following attestation bundles were made for muxplex-0.58.0-py3-none-any.whl:
Publisher:
publish.yml on bkrabach/muxplex
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
muxplex-0.58.0-py3-none-any.whl -
Subject digest:
4a6599fec5b35de10320acf27e9b1cb1a6853434f93902948901ab7e9365a254 - Sigstore transparency entry: 2534221703
- Sigstore integration time:
-
Permalink:
bkrabach/muxplex@89bd5ef13e00e4be7530f717dcbf596fd0cfcd6c -
Branch / Tag:
refs/tags/v0.58.0 - Owner: https://github.com/bkrabach
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@89bd5ef13e00e4be7530f717dcbf596fd0cfcd6c -
Trigger Event:
push
-
Statement type: