Skip to content

Commit 9767b22

Browse files
feat(multiplexer): add client tests, docs, and monorepo integration
- Add comprehensive tests for MuxClient, ConsoleClient, EventsClient (50 tests) - Update root package.json to include nested web packages (./packages/**) - Add multiplexer README with build order and API documentation - Document nested workspace ESLint exception in CLAUDE.md 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 5cd638b commit 9767b22

6 files changed

Lines changed: 1059 additions & 3 deletions

File tree

CLAUDE.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,3 +172,26 @@ bun run dev # Backend with watch
172172
bun run dev:frontend # Frontend dev server
173173
bun run dev:all # Both concurrently
174174
```
175+
176+
### multiplexer
177+
178+
Rust-based session multiplexer with web interface. Contains nested TypeScript workspaces:
179+
180+
```bash
181+
cd packages/multiplexer
182+
cargo build # Build Rust binary
183+
cargo test # Run Rust tests
184+
185+
# Web packages (nested workspace)
186+
cd web
187+
bun install # Install web dependencies
188+
bun run build # Build all web packages
189+
bun run test # Run web tests
190+
bun run lint # Lint web packages
191+
```
192+
193+
**Build Order**: The frontend must be built before the Rust binary (static files are embedded):
194+
1. `cd packages/multiplexer/web/frontend && bun run build`
195+
2. `cd packages/multiplexer && cargo build`
196+
197+
**Nested Workspace Exception**: The web packages (`packages/multiplexer/web/*`) use standalone ESLint configs instead of `@shepherdjerred/eslint-config` due to Bun workspace resolution limitations with deeply nested packages. These configs follow the same patterns and rules as the shared config.

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
"private": true,
55
"workspaces": ["packages/*", "packages/multiplexer/web/*"],
66
"scripts": {
7-
"build": "bun run --filter='./packages/*' build",
8-
"test": "bun run --filter='./packages/*' test",
9-
"typecheck": "bun run --filter='./packages/*' typecheck",
7+
"build": "bun run --filter='./packages/**' build",
8+
"test": "bun run --filter='./packages/**' test",
9+
"typecheck": "bun run --filter='./packages/**' typecheck",
1010
"prepare": "husky"
1111
},
1212
"devDependencies": {

packages/multiplexer/README.md

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
# Multiplexer
2+
3+
A Rust-based session multiplexer for managing Claude Code sessions with both CLI/TUI and web interfaces.
4+
5+
## Prerequisites
6+
7+
- **Rust** (1.85+) - Install via [rustup](https://rustup.rs/)
8+
- **Bun** (1.3.5+) - Install via [bun.sh](https://bun.sh/)
9+
- **typeshare-cli** - Install via `cargo install typeshare-cli`
10+
11+
## Build Order
12+
13+
The frontend must be built before the Rust binary because static files are embedded at compile time.
14+
15+
```bash
16+
# 1. Install web dependencies
17+
cd web && bun install && cd ..
18+
19+
# 2. Build frontend (generates dist/ with static files)
20+
cd web/frontend && bun run build && cd ../..
21+
22+
# 3. Build Rust binary (embeds frontend dist/)
23+
cargo build --release
24+
```
25+
26+
Or use the full build command:
27+
28+
```bash
29+
cd web && bun run build && cd .. && cargo build --release
30+
```
31+
32+
## Running the Web Interface
33+
34+
Start the daemon with HTTP server enabled:
35+
36+
```bash
37+
# Start daemon with web interface on port 3030
38+
./target/release/mux daemon --http-port 3030
39+
```
40+
41+
Then open http://localhost:3030 in your browser.
42+
43+
### CLI Options
44+
45+
```bash
46+
mux daemon --help
47+
48+
Options:
49+
--http-port <PORT> Enable HTTP server on specified port
50+
--socket <PATH> Unix socket path (default: /tmp/mux.sock)
51+
```
52+
53+
## Development
54+
55+
### Web Packages
56+
57+
The web interface is split into three packages in `web/`:
58+
59+
- **@mux/shared** - Shared types (generated from Rust via typeshare)
60+
- **@mux/client** - TypeScript API client library
61+
- **@mux/frontend** - React frontend application
62+
63+
```bash
64+
cd web
65+
66+
# Development
67+
bun run dev # Start frontend dev server
68+
69+
# Testing
70+
bun run test # Run all web tests
71+
72+
# Linting
73+
bun run lint # Lint all web packages
74+
75+
# Building
76+
bun run build # Build all web packages
77+
```
78+
79+
### Rust Development
80+
81+
```bash
82+
# Run tests
83+
cargo test
84+
85+
# Format code
86+
cargo fmt
87+
88+
# Lint
89+
cargo clippy
90+
91+
# Run daemon in development
92+
cargo run -- daemon --http-port 3030
93+
```
94+
95+
### Regenerating Types
96+
97+
When Rust types change, regenerate TypeScript types:
98+
99+
```bash
100+
typeshare . --lang=typescript --output-file=web/shared/src/generated/index.ts
101+
```
102+
103+
This is automatically run during `cargo build`.
104+
105+
## Architecture
106+
107+
```
108+
multiplexer/
109+
├── src/ # Rust source code
110+
│ ├── api/ # HTTP/WebSocket API
111+
│ ├── core/ # Session management
112+
│ ├── tui/ # Terminal UI
113+
│ └── main.rs # CLI entry point
114+
├── web/ # TypeScript packages
115+
│ ├── shared/ # Shared types
116+
│ ├── client/ # API client
117+
│ └── frontend/ # React UI
118+
└── build.rs # Build script (typeshare + embed)
119+
```
120+
121+
## API Endpoints
122+
123+
### REST API
124+
125+
- `GET /api/sessions` - List all sessions
126+
- `GET /api/sessions/:id` - Get session by ID
127+
- `POST /api/sessions` - Create new session
128+
- `DELETE /api/sessions/:id` - Delete session
129+
- `POST /api/sessions/:id/archive` - Archive session
130+
- `POST /api/sessions/:id/access-mode` - Update access mode
131+
- `GET /api/recent-repos` - List recent repositories
132+
133+
### WebSocket Endpoints
134+
135+
- `/ws/console/:session_id` - Terminal console stream
136+
- `/ws/events` - Real-time session events

0 commit comments

Comments
 (0)