muxplex 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. muxplex-0.1.0/.github/workflows/ci.yml +35 -0
  2. muxplex-0.1.0/.github/workflows/publish.yml +27 -0
  3. muxplex-0.1.0/.gitignore +30 -0
  4. muxplex-0.1.0/PKG-INFO +396 -0
  5. muxplex-0.1.0/README.md +360 -0
  6. muxplex-0.1.0/assets/branding/DESIGN-SYSTEM.md +857 -0
  7. muxplex-0.1.0/assets/branding/README.md +40 -0
  8. muxplex-0.1.0/assets/branding/favicons/apple-touch-icon.png +0 -0
  9. muxplex-0.1.0/assets/branding/favicons/favicon-16.png +0 -0
  10. muxplex-0.1.0/assets/branding/favicons/favicon-32.png +0 -0
  11. muxplex-0.1.0/assets/branding/favicons/favicon-48.png +0 -0
  12. muxplex-0.1.0/assets/branding/favicons/favicon.ico +0 -0
  13. muxplex-0.1.0/assets/branding/icons/muxplex-icon-1024.png +0 -0
  14. muxplex-0.1.0/assets/branding/icons/muxplex-icon-128.png +0 -0
  15. muxplex-0.1.0/assets/branding/icons/muxplex-icon-16.png +0 -0
  16. muxplex-0.1.0/assets/branding/icons/muxplex-icon-192.png +0 -0
  17. muxplex-0.1.0/assets/branding/icons/muxplex-icon-22.png +0 -0
  18. muxplex-0.1.0/assets/branding/icons/muxplex-icon-24.png +0 -0
  19. muxplex-0.1.0/assets/branding/icons/muxplex-icon-256.png +0 -0
  20. muxplex-0.1.0/assets/branding/icons/muxplex-icon-32.png +0 -0
  21. muxplex-0.1.0/assets/branding/icons/muxplex-icon-48.png +0 -0
  22. muxplex-0.1.0/assets/branding/icons/muxplex-icon-512.png +0 -0
  23. muxplex-0.1.0/assets/branding/icons/muxplex-icon-64.png +0 -0
  24. muxplex-0.1.0/assets/branding/lockup/lockup-on-dark-32.png +0 -0
  25. muxplex-0.1.0/assets/branding/lockup/lockup-on-dark-64.png +0 -0
  26. muxplex-0.1.0/assets/branding/lockup/lockup-on-light-32.png +0 -0
  27. muxplex-0.1.0/assets/branding/lockup/lockup-on-light-64.png +0 -0
  28. muxplex-0.1.0/assets/branding/og/og-dark.png +0 -0
  29. muxplex-0.1.0/assets/branding/og/og-light.png +0 -0
  30. muxplex-0.1.0/assets/branding/pwa/pwa-192.png +0 -0
  31. muxplex-0.1.0/assets/branding/pwa/pwa-512.png +0 -0
  32. muxplex-0.1.0/assets/branding/svg/icon/muxplex-icon-dark.svg +18 -0
  33. muxplex-0.1.0/assets/branding/svg/icon/muxplex-icon-light.svg +18 -0
  34. muxplex-0.1.0/assets/branding/svg/lockup/lockup-on-dark.svg +20 -0
  35. muxplex-0.1.0/assets/branding/svg/lockup/lockup-on-light.svg +21 -0
  36. muxplex-0.1.0/assets/branding/svg/wordmark/wordmark-on-dark.svg +11 -0
  37. muxplex-0.1.0/assets/branding/svg/wordmark/wordmark-on-light.svg +11 -0
  38. muxplex-0.1.0/assets/branding/tokens.css +355 -0
  39. muxplex-0.1.0/assets/branding/tokens.json +214 -0
  40. muxplex-0.1.0/assets/branding/wordmark/wordmark-on-dark-32.png +0 -0
  41. muxplex-0.1.0/assets/branding/wordmark/wordmark-on-dark-64.png +0 -0
  42. muxplex-0.1.0/assets/branding/wordmark/wordmark-on-light-32.png +0 -0
  43. muxplex-0.1.0/assets/branding/wordmark/wordmark-on-light-64.png +0 -0
  44. muxplex-0.1.0/docs/how-we-built-the-muxplex-brand.md +237 -0
  45. muxplex-0.1.0/docs/plans/2026-03-26-web-tmux-dashboard-design.md +318 -0
  46. muxplex-0.1.0/docs/plans/2026-03-26-web-tmux-phase1-backend.md +3489 -0
  47. muxplex-0.1.0/docs/plans/2026-03-26-web-tmux-phase2a-frontend-static.md +1717 -0
  48. muxplex-0.1.0/docs/plans/2026-03-26-web-tmux-phase2b-javascript.md +1909 -0
  49. muxplex-0.1.0/docs/plans/2026-03-27-session-sidebar-design.md +139 -0
  50. muxplex-0.1.0/docs/plans/2026-03-27-session-sidebar-implementation.md +1414 -0
  51. muxplex-0.1.0/docs/plans/2026-03-28-auth-design.md +254 -0
  52. muxplex-0.1.0/docs/plans/2026-03-28-auth-phase1-infrastructure.md +1074 -0
  53. muxplex-0.1.0/docs/plans/2026-03-28-auth-phase2-ui-cli.md +1066 -0
  54. muxplex-0.1.0/docs/plans/2026-03-28-packaging-for-distribution.md +804 -0
  55. muxplex-0.1.0/docs/plans/2026-03-29-settings-design.md +211 -0
  56. muxplex-0.1.0/docs/plans/2026-03-29-settings-phase1.md +1395 -0
  57. muxplex-0.1.0/docs/plans/2026-03-29-settings-phase2.md +1110 -0
  58. muxplex-0.1.0/docs/plans/2026-03-30-multi-device-federation-design.md +270 -0
  59. muxplex-0.1.0/docs/plans/2026-03-30-multi-device-federation-phase1.md +1067 -0
  60. muxplex-0.1.0/docs/plans/2026-03-30-multi-device-federation-phase2.md +2279 -0
  61. muxplex-0.1.0/docs/plans/2026-03-30-multi-device-federation-phase3.md +1321 -0
  62. muxplex-0.1.0/docs/plans/2026-03-31-cli-phase1-config-serve.md +815 -0
  63. muxplex-0.1.0/docs/plans/2026-03-31-cli-phase2-service-commands.md +1095 -0
  64. muxplex-0.1.0/docs/plans/2026-03-31-cli-service-refactor-design.md +392 -0
  65. muxplex-0.1.0/docs/plans/2026-04-03-tls-phase1-foundation.md +1246 -0
  66. muxplex-0.1.0/docs/plans/2026-04-03-tls-phase2-autodetect.md +1231 -0
  67. muxplex-0.1.0/docs/plans/2026-04-03-tls-setup-design.md +203 -0
  68. muxplex-0.1.0/docs/plans/2026-04-04-device-selector.md +751 -0
  69. muxplex-0.1.0/docs/plans/2026-04-04-tls-nudge-design.md +67 -0
  70. muxplex-0.1.0/docs/plans/README.md +5 -0
  71. muxplex-0.1.0/docs/screenshots/settings-commands.png +0 -0
  72. muxplex-0.1.0/docs/screenshots/settings-display.png +0 -0
  73. muxplex-0.1.0/docs/screenshots/settings-multidevice.png +0 -0
  74. muxplex-0.1.0/docs/screenshots/settings-sessions.png +0 -0
  75. muxplex-0.1.0/muxplex/__init__.py +0 -0
  76. muxplex-0.1.0/muxplex/__main__.py +5 -0
  77. muxplex-0.1.0/muxplex/auth.py +232 -0
  78. muxplex-0.1.0/muxplex/bells.py +177 -0
  79. muxplex-0.1.0/muxplex/cli.py +1067 -0
  80. muxplex-0.1.0/muxplex/frontend/app.js +2556 -0
  81. muxplex-0.1.0/muxplex/frontend/apple-touch-icon.png +0 -0
  82. muxplex-0.1.0/muxplex/frontend/favicon-32.png +0 -0
  83. muxplex-0.1.0/muxplex/frontend/favicon.ico +0 -0
  84. muxplex-0.1.0/muxplex/frontend/index.html +251 -0
  85. muxplex-0.1.0/muxplex/frontend/login.html +192 -0
  86. muxplex-0.1.0/muxplex/frontend/manifest.json +15 -0
  87. muxplex-0.1.0/muxplex/frontend/pwa-192.png +0 -0
  88. muxplex-0.1.0/muxplex/frontend/pwa-512.png +0 -0
  89. muxplex-0.1.0/muxplex/frontend/style.css +1862 -0
  90. muxplex-0.1.0/muxplex/frontend/terminal.js +605 -0
  91. muxplex-0.1.0/muxplex/frontend/tests/test_app.mjs +4301 -0
  92. muxplex-0.1.0/muxplex/frontend/tests/test_terminal.mjs +994 -0
  93. muxplex-0.1.0/muxplex/frontend/vendor/addon-image.js +3 -0
  94. muxplex-0.1.0/muxplex/frontend/vendor/xterm-addon-fit.js +2 -0
  95. muxplex-0.1.0/muxplex/frontend/vendor/xterm-addon-search.js +2 -0
  96. muxplex-0.1.0/muxplex/frontend/vendor/xterm-addon-web-links.js +2 -0
  97. muxplex-0.1.0/muxplex/frontend/vendor/xterm.css +209 -0
  98. muxplex-0.1.0/muxplex/frontend/vendor/xterm.js +2 -0
  99. muxplex-0.1.0/muxplex/frontend/wordmark-on-dark.svg +11 -0
  100. muxplex-0.1.0/muxplex/main.py +1139 -0
  101. muxplex-0.1.0/muxplex/service.py +291 -0
  102. muxplex-0.1.0/muxplex/sessions.py +140 -0
  103. muxplex-0.1.0/muxplex/settings.py +121 -0
  104. muxplex-0.1.0/muxplex/state.py +184 -0
  105. muxplex-0.1.0/muxplex/tests/__init__.py +0 -0
  106. muxplex-0.1.0/muxplex/tests/test_api.py +2600 -0
  107. muxplex-0.1.0/muxplex/tests/test_auth.py +527 -0
  108. muxplex-0.1.0/muxplex/tests/test_bells.py +318 -0
  109. muxplex-0.1.0/muxplex/tests/test_cli.py +2140 -0
  110. muxplex-0.1.0/muxplex/tests/test_frontend_css.py +2138 -0
  111. muxplex-0.1.0/muxplex/tests/test_frontend_html.py +1421 -0
  112. muxplex-0.1.0/muxplex/tests/test_frontend_js.py +2585 -0
  113. muxplex-0.1.0/muxplex/tests/test_integration.py +213 -0
  114. muxplex-0.1.0/muxplex/tests/test_readme.py +274 -0
  115. muxplex-0.1.0/muxplex/tests/test_service.py +665 -0
  116. muxplex-0.1.0/muxplex/tests/test_sessions.py +262 -0
  117. muxplex-0.1.0/muxplex/tests/test_settings.py +731 -0
  118. muxplex-0.1.0/muxplex/tests/test_state.py +311 -0
  119. muxplex-0.1.0/muxplex/tests/test_tls.py +577 -0
  120. muxplex-0.1.0/muxplex/tests/test_ttyd.py +326 -0
  121. muxplex-0.1.0/muxplex/tests/test_ws_proxy.py +444 -0
  122. muxplex-0.1.0/muxplex/tls.py +380 -0
  123. muxplex-0.1.0/muxplex/ttyd.py +224 -0
  124. muxplex-0.1.0/pyproject.toml +68 -0
  125. muxplex-0.1.0/pyrightconfig.json +5 -0
  126. muxplex-0.1.0/scripts/render-brand-assets.py +438 -0
  127. muxplex-0.1.0/scripts/spike_bell_flag.py +80 -0
  128. muxplex-0.1.0/uv.lock +912 -0
@@ -0,0 +1,35 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ permissions:
10
+ contents: read
11
+
12
+ jobs:
13
+ test:
14
+ runs-on: ubuntu-latest
15
+ timeout-minutes: 15
16
+ strategy:
17
+ fail-fast: false
18
+ matrix:
19
+ python-version: ["3.11", "3.12", "3.13"]
20
+ steps:
21
+ - uses: actions/checkout@v4 # checks out muxplex repo
22
+
23
+ - name: Install uv
24
+ uses: astral-sh/setup-uv@v4
25
+ with:
26
+ enable-cache: true
27
+
28
+ - name: Set up Python ${{ matrix.python-version }}
29
+ run: uv python install ${{ matrix.python-version }}
30
+
31
+ - name: Install dependencies
32
+ run: uv sync --extra dev
33
+
34
+ - name: Run tests
35
+ run: uv run pytest -v
@@ -0,0 +1,27 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*"
7
+
8
+ permissions:
9
+ contents: read # Required for actions/checkout
10
+ id-token: write # Required for OIDC Trusted Publisher
11
+
12
+ jobs:
13
+ publish:
14
+ runs-on: ubuntu-latest
15
+ timeout-minutes: 15
16
+ environment: pypi
17
+ steps:
18
+ - uses: actions/checkout@v4
19
+
20
+ - name: Install uv
21
+ uses: astral-sh/setup-uv@v4
22
+
23
+ - name: Build package
24
+ run: uv build
25
+
26
+ - name: Publish to PyPI
27
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,30 @@
1
+ # Python bytecode
2
+ __pycache__/
3
+ *.pyc
4
+ *.pyo
5
+ *.pyd
6
+
7
+ # Virtual environment
8
+ .venv/
9
+ venv/
10
+ env/
11
+
12
+ # Distribution / packaging
13
+ dist/
14
+ build/
15
+ *.egg-info/
16
+
17
+ # Test/coverage artifacts
18
+ .coverage
19
+ .pytest_cache/
20
+ htmlcov/
21
+
22
+ # OS artifacts
23
+ .DS_Store
24
+ Thumbs.db
25
+
26
+ # IDE
27
+ .idea/
28
+ .vscode/
29
+ *.swp
30
+ *.swo
muxplex-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,396 @@
1
+ Metadata-Version: 2.4
2
+ Name: muxplex
3
+ Version: 0.1.0
4
+ Summary: Web-based tmux session dashboard — access all your tmux sessions from any browser
5
+ Project-URL: Repository, https://github.com/bkrabach/muxplex
6
+ Project-URL: Issues, https://github.com/bkrabach/muxplex/issues
7
+ Author-email: Brian Krabach <brian@krabach.com>
8
+ License: MIT
9
+ Keywords: dashboard,session-manager,terminal,tmux,web
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Environment :: Web Environment
12
+ Classifier: Framework :: FastAPI
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Topic :: System :: Systems Administration
19
+ Classifier: Topic :: Terminals :: Terminal Emulators/X Terminals
20
+ Requires-Python: >=3.11
21
+ Requires-Dist: aiofiles>=23.0
22
+ Requires-Dist: cryptography
23
+ Requires-Dist: fastapi>=0.115.0
24
+ Requires-Dist: httpx>=0.27.0
25
+ Requires-Dist: itsdangerous>=2.1.0
26
+ Requires-Dist: python-multipart>=0.0.9
27
+ Requires-Dist: python-pam>=1.8.4
28
+ Requires-Dist: six>=1.16.0
29
+ Requires-Dist: uvicorn[standard]>=0.30.0
30
+ Requires-Dist: websockets>=11.0
31
+ Provides-Extra: dev
32
+ Requires-Dist: beautifulsoup4>=4.12; extra == 'dev'
33
+ Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
34
+ Requires-Dist: pytest>=8.0.0; extra == 'dev'
35
+ Description-Content-Type: text/markdown
36
+
37
+ # muxplex
38
+
39
+ **Web-based tmux session dashboard — access, monitor, and manage all your tmux sessions from any browser on any device.**
40
+
41
+ ![muxplex dashboard](https://raw.githubusercontent.com/bkrabach/muxplex/main/assets/branding/og/og-dark.png)
42
+
43
+ ---
44
+
45
+ ## Features
46
+
47
+ ### Dashboard
48
+
49
+ - **Live session grid** — preview tiles with ANSI-colored terminal snapshots, auto-refreshed
50
+ - **Two view modes** — Auto (scrollable grid) and Fit (all sessions fill the viewport)
51
+ - **Hover preview** — full-size overlay of session content on tile hover
52
+ - **Activity indicators** — bell notification badges on tiles; amber favicon dot + `(N)` count in browser tab title when sessions have unseen activity
53
+ - **Session creation** — `+` button with device selector dropdown when multi-device is enabled; custom command template support
54
+ - **Session deletion** — `×` button with custom command template support
55
+ - **Mobile-friendly** — responsive layout, PWA-capable for home-screen install
56
+
57
+ ### Terminal
58
+
59
+ - **Full interactive terminal** — powered by xterm.js + ttyd
60
+ - **Native clipboard** — Ctrl+Shift+C to copy, Ctrl+Shift+V to paste
61
+ - **Mouse select auto-copy** — selecting text copies to system clipboard on release
62
+ - **OSC 52 tmux clipboard bridge** — tmux copy mode selections go to system clipboard
63
+ - **Search** — Ctrl+F opens a search bar to find text in terminal scrollback (xterm-addon-search)
64
+ - **Clickable URLs** — Ctrl+Click (Cmd+Click on macOS) opens URLs in terminal output in a new tab (xterm-addon-web-links)
65
+ - **Inline image rendering** — Sixel and iTerm2 graphic protocols for tools like yazi file manager (xterm-addon-image)
66
+ - **Sidebar session switcher** — quick-switch between sessions with live previews
67
+
68
+ ### Settings
69
+
70
+ - **In-browser settings panel** — gear icon or `,` shortcut
71
+ - **Display** — font size, grid columns, hover delay, view mode, device badges, activity indicator
72
+ - **Sessions** — default session, sort order, hidden sessions, auto-open, bell sound, notifications
73
+ - **Commands** — custom create/delete session templates
74
+ - **Multi-Device** — remote instance federation
75
+ - **CLI** — `muxplex config list/get/set/reset`
76
+
77
+ ### Multi-Device
78
+
79
+ - **Remote session aggregation** — federate multiple muxplex instances into a unified dashboard view
80
+ - **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
81
+ - **Remote bell-clear** — opening a session on a remote device automatically clears its activity notification via federation API (`POST /api/bell/clear`)
82
+ - **Unique session keys** — sessions identified by `remoteId:name` across devices, preventing bell-state collisions for identically-named sessions on different machines
83
+
84
+ ### Service Management
85
+
86
+ - `muxplex service install/start/stop/restart/status/logs/uninstall`
87
+ - **Platform-aware** — systemd user service on Linux/WSL, launchd agent on macOS
88
+ - **Config-driven** — service reads all options from `~/.config/muxplex/settings.json` (no flags in the service file)
89
+
90
+ ### Authentication
91
+
92
+ - **PAM authentication** — Linux/macOS system credentials
93
+ - **Password mode** — auto-generated or set via `MUXPLEX_PASSWORD` env var
94
+ - **Localhost bypass** — no auth needed on 127.0.0.1
95
+ - **Secure session cookies** — signed with configurable TTL
96
+
97
+ ### Developer Tools
98
+
99
+ - `muxplex doctor` — dependency + config diagnostics with update check
100
+ - `muxplex upgrade` — smart version check + auto-update + service restart
101
+ - `muxplex config` — CLI settings management
102
+
103
+ ### HTTPS / TLS
104
+
105
+ - `muxplex setup-tls` — auto-detect and set up TLS certificates
106
+ - **Tailscale** — real Let's Encrypt certs via `tailscale cert` (recommended)
107
+ - **mkcert** — locally-trusted certs, zero browser warnings
108
+ - **Self-signed** — fallback for immediate HTTPS (browser shows warning)
109
+ - Required for browser clipboard API on non-localhost
110
+
111
+ ---
112
+
113
+ ## Prerequisites
114
+
115
+ - **Python 3.11+** — installed via `uv` or system Python
116
+ - **tmux** — terminal multiplexer
117
+ - macOS: `brew install tmux`
118
+ - Ubuntu/WSL: `sudo apt install tmux`
119
+ - **ttyd** — terminal sharing over HTTP (required for interactive terminal access)
120
+ - macOS: `brew install ttyd`
121
+ - Ubuntu/WSL: `sudo apt install ttyd` or `sudo snap install ttyd`
122
+ - Other: https://github.com/tsl0922/ttyd#installation
123
+
124
+ > **Tip:** Run `muxplex doctor` to check all dependencies and system status.
125
+
126
+ ---
127
+
128
+ ## Quick Start (uvx — no install)
129
+
130
+ Run muxplex directly without installing anything permanently:
131
+
132
+ ```bash
133
+ uvx --from git+https://github.com/bkrabach/muxplex muxplex
134
+ ```
135
+
136
+ Then open **http://localhost:8088** in your browser.
137
+
138
+ > **Note:** `uvx` is part of [uv](https://docs.astral.sh/uv/). Install uv with `curl -LsSf https://astral.sh/uv/install.sh | sh`.
139
+
140
+ ---
141
+
142
+ ## Install Permanently
143
+
144
+ ```bash
145
+ uv tool install git+https://github.com/bkrabach/muxplex
146
+ muxplex doctor # verify dependencies
147
+ ```
148
+
149
+ Then run it any time with:
150
+
151
+ ```bash
152
+ muxplex
153
+ ```
154
+
155
+ ---
156
+
157
+ ## Install as a Service
158
+
159
+ ```bash
160
+ muxplex service install
161
+ # → prompts to set host to 0.0.0.0 for network access
162
+ ```
163
+
164
+ The service starts automatically on login (macOS) or at boot (Linux) and restarts on failure.
165
+
166
+ ```bash
167
+ # Open in browser
168
+ open http://localhost:8088
169
+ ```
170
+
171
+ To stop and remove:
172
+
173
+ ```bash
174
+ muxplex service uninstall
175
+ ```
176
+
177
+ ---
178
+
179
+ ## CLI Reference
180
+
181
+ ```
182
+ muxplex Start server (default)
183
+ muxplex serve [flags] Start with CLI flag overrides
184
+ muxplex service install Install + enable + start as OS service
185
+ muxplex service uninstall Stop + disable + remove
186
+ muxplex service start|stop|restart Manage running service
187
+ muxplex service status Show service status
188
+ muxplex service logs Tail service logs
189
+ muxplex config Show all settings
190
+ muxplex config get <key> Show one setting
191
+ muxplex config set <key> <value> Set a setting
192
+ muxplex config reset [key] Reset one or all to defaults
193
+ muxplex upgrade [--force] Smart update with version check
194
+ muxplex doctor Check dependencies + config
195
+ muxplex show-password Show current auth password
196
+ muxplex reset-secret Regenerate signing secret
197
+ muxplex setup-tls [--method auto] Set up TLS certs (Tailscale/mkcert/self-signed)
198
+ muxplex setup-tls --status Show current TLS configuration
199
+ ```
200
+
201
+ ### Service management
202
+
203
+ ```bash
204
+ muxplex service install # Write service file + enable + start
205
+ muxplex service uninstall # Stop + disable + remove service file
206
+ muxplex service start # Start the service
207
+ muxplex service stop # Stop the service
208
+ muxplex service restart # Stop + start
209
+ muxplex service status # Show running/stopped + PID
210
+ muxplex service logs # Tail service logs
211
+ ```
212
+
213
+ 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:
214
+
215
+ ```bash
216
+ muxplex config set host 0.0.0.0
217
+ muxplex service restart
218
+ ```
219
+
220
+ ### Examples
221
+
222
+ ```bash
223
+ # Start with defaults from settings.json
224
+ muxplex
225
+
226
+ # Override port for this run only
227
+ muxplex --port 9000
228
+
229
+ # Override host for this run only
230
+ muxplex serve --host 0.0.0.0
231
+ ```
232
+
233
+ ### HTTPS / TLS setup
234
+
235
+ ```bash
236
+ # Auto-detect the best TLS method and set up certificates
237
+ muxplex setup-tls
238
+
239
+ # Use a specific TLS method
240
+ muxplex setup-tls --method tailscale
241
+ muxplex setup-tls --method mkcert
242
+ muxplex setup-tls --method selfsigned
243
+
244
+ # Show current TLS status and configuration
245
+ muxplex setup-tls --status
246
+
247
+ # Override TLS cert/key for a single run (without saving to config)
248
+ muxplex serve --tls-cert /path/cert.pem --tls-key /path/key.pem
249
+
250
+ # Check TLS configuration and dependencies
251
+ muxplex doctor
252
+ ```
253
+
254
+ 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.
255
+
256
+ > **Note:** Tailscale certs have a 90-day expiry. Run `muxplex setup-tls --method tailscale` to renew when needed.
257
+
258
+ ---
259
+
260
+ ## Configuration
261
+
262
+ All settings are stored in `~/.config/muxplex/settings.json`.
263
+
264
+ | Key | Default | Description |
265
+ |---|---|---|
266
+ | `host` | `127.0.0.1` | Bind address (set to `0.0.0.0` for network access) |
267
+ | `port` | `8088` | Server port |
268
+ | `auth` | `pam` | Authentication mode: `pam` or `password` |
269
+ | `session_ttl` | `604800` | Session cookie TTL in seconds (7 days; 0 = browser session) |
270
+ | `default_session` | `null` | Session to auto-open on load |
271
+ | `sort_order` | `manual` | Session ordering: `manual`, `alphabetical`, `recent` |
272
+ | `hidden_sessions` | `[]` | Sessions hidden from the dashboard |
273
+ | `window_size_largest` | `false` | Auto-set tmux `window-size largest` on connect |
274
+ | `auto_open_created` | `true` | Auto-open newly created sessions |
275
+ | `new_session_template` | `tmux new-session -d -s {name}` | Command template for creating sessions |
276
+ | `delete_session_template` | `tmux kill-session -t {name}` | Command template for deleting sessions |
277
+ | `device_name` | `""` (hostname) | Display name for this device |
278
+ | `federation_key` | `""` | Server-to-server authentication key for federation |
279
+ | `remote_instances` | `[]` | Remote muxplex instances to aggregate |
280
+ | `multi_device_enabled` | `false` | Enable multi-instance federation |
281
+ | `tls_cert` | `""` | Path to TLS certificate file (empty = HTTP) |
282
+ | `tls_key` | `""` | Path to TLS private key file (empty = HTTP) |
283
+
284
+ **Priority:** CLI flags > `settings.json` > defaults.
285
+
286
+ ---
287
+
288
+ ## Keyboard Shortcuts
289
+
290
+ | Shortcut | Action |
291
+ |---|---|
292
+ | Ctrl+Shift+C | Copy terminal selection to system clipboard |
293
+ | Ctrl+Shift+V | Paste from system clipboard into terminal |
294
+ | Ctrl+F | Open terminal search bar |
295
+ | Enter / Shift+Enter | Next / previous search match |
296
+ | Ctrl+Click (Cmd+Click) | Open URL in new tab |
297
+ | `,` (comma) | Open settings |
298
+ | Escape | Close settings / return to dashboard |
299
+
300
+ Mouse select in the terminal auto-copies to the system clipboard on release.
301
+
302
+ ---
303
+
304
+ ## Platform Support
305
+
306
+ | Platform | Service | Auth |
307
+ |---|---|---|
308
+ | Linux (Ubuntu/Debian) | systemd user service | PAM |
309
+ | macOS | launchd agent | PAM |
310
+ | WSL | systemd user service | PAM |
311
+
312
+ ---
313
+
314
+ ## Project Structure
315
+
316
+ ```
317
+ muxplex/
318
+ ├── muxplex/
319
+ │ ├── __init__.py
320
+ │ ├── __main__.py # python -m muxplex entry
321
+ │ ├── cli.py # CLI entry point and subcommand dispatch
322
+ │ ├── main.py # FastAPI app, routes, WebSocket proxy
323
+ │ ├── auth.py # PAM/password auth middleware
324
+ │ ├── sessions.py # tmux session enumeration + snapshots
325
+ │ ├── bells.py # Bell flag detection + clear rules
326
+ │ ├── state.py # Persistent state (JSON)
327
+ │ ├── settings.py # User settings management
328
+ │ ├── service.py # Service install/start/stop (systemd + launchd)
329
+ │ ├── ttyd.py # ttyd process lifecycle
330
+ │ ├── frontend/
331
+ │ │ ├── index.html # Main SPA
332
+ │ │ ├── login.html # Login page
333
+ │ │ ├── app.js # Dashboard, sidebar, settings, previews
334
+ │ │ ├── terminal.js # xterm.js terminal + clipboard
335
+ │ │ ├── style.css # All styles (dark theme)
336
+ │ │ ├── manifest.json # PWA manifest
337
+ │ │ ├── wordmark-on-dark.svg
338
+ │ │ └── tests/ # JavaScript unit tests
339
+ │ └── tests/ # Python tests (pytest)
340
+ ├── assets/branding/ # Logos, icons, design system
341
+ ├── docs/plans/ # Historical design + implementation plans
342
+ ├── scripts/ # Utility scripts (asset generation)
343
+ ├── pyproject.toml
344
+ └── README.md
345
+ ```
346
+
347
+ ---
348
+
349
+ ## Development
350
+
351
+ ### Setup
352
+
353
+ ```bash
354
+ git clone https://github.com/bkrabach/muxplex
355
+ cd muxplex
356
+
357
+ # Install with dev dependencies
358
+ uv pip install -e ".[dev]"
359
+ ```
360
+
361
+ ### Run the server
362
+
363
+ ```bash
364
+ muxplex
365
+ # or directly:
366
+ python -m muxplex
367
+ ```
368
+
369
+ ### Run tests
370
+
371
+ ```bash
372
+ # Python tests (pytest)
373
+ python -m pytest muxplex/tests/ --ignore=muxplex/tests/test_integration.py
374
+
375
+ # JavaScript tests (node:test)
376
+ node --test muxplex/frontend/tests/test_terminal.mjs
377
+ node --test muxplex/frontend/tests/test_app.mjs
378
+ ```
379
+
380
+ ---
381
+
382
+ ## Brand Assets
383
+
384
+ Design language, color tokens, and brand assets live in `assets/branding/`. See [`assets/branding/DESIGN-SYSTEM.md`](assets/branding/DESIGN-SYSTEM.md) for the full design reference.
385
+
386
+ To regenerate PNG/favicon assets from SVG sources:
387
+
388
+ ```bash
389
+ python3 scripts/render-brand-assets.py
390
+ ```
391
+
392
+ ---
393
+
394
+ ## License
395
+
396
+ MIT