Skip to content

Commit 10293b1

Browse files
Flatten monorepo to single-package structure (#5)
1 parent f9f3d71 commit 10293b1

44 files changed

Lines changed: 224 additions & 372 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,4 @@ jobs:
4848
- uses: actions/upload-artifact@v4
4949
with:
5050
name: dist
51-
path: packages/*/dist/
51+
path: dist/

.github/workflows/release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ jobs:
2626
- run: npm run build
2727

2828
- name: Publish to npm
29-
run: npm publish -w packages/cli --access public
29+
run: npm publish --access public
3030
env:
3131
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
3232

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,5 @@ coverage/
3838
# Temporary
3939
tmp/
4040
.tmp/
41+
42+
CLAUDE.local.md

.prettierignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ node_modules/
22
dist/
33
coverage/
44
*.db
5-
packages/web/public/
5+
public/

README.md

Lines changed: 109 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -1,147 +1,165 @@
1-
# Clux
1+
<p align="center">
2+
<img src="logo.svg" alt="Clux" width="120" />
3+
</p>
24

3-
> **v0.2.0 — This project is under active development.** APIs, commands, and features may change without notice.
5+
<h1 align="center">Clux</h1>
46

5-
A tmux session multiplexer with a web dashboard and CLI. Clux lets you create, manage, and monitor multiple tmux sessions from the browser or command line. Run any command — LLM coding agents, dev servers, build scripts, or anything else. It supports inter-pane messaging, session tagging, and real-time output monitoring out of the box.
7+
<p align="center">
8+
<strong>A tmux session multiplexer for running parallel coding agents, with a web dashboard and CLI.</strong>
9+
</p>
610

7-
## Features
11+
<p align="center">
12+
<a href="https://www.npmjs.com/package/@clux-cli/cli"><img src="https://img.shields.io/npm/v/@clux-cli/cli" alt="npm version" /></a>
13+
<a href="https://github.com/devhelp/clux/blob/main/LICENSE"><img src="https://img.shields.io/npm/l/@clux-cli/cli" alt="license" /></a>
14+
<img src="https://img.shields.io/node/v/@clux-cli/cli" alt="node version" />
15+
</p>
816

9-
- Web dashboard with WebSocket live updates
10-
- Real-time monitoring of pane output
11-
- Create and manage tmux sessions running any command
12-
- Send input and capture output from any pane without attaching
13-
- Relay messages between panes
14-
- Tag, search, and describe sessions with persistent metadata (SQLite)
15-
- Export sessions to Markdown
16-
17-
## Prerequisites
18-
19-
- Node.js >= 18
20-
- tmux
17+
Clux wraps tmux into a programmable session manager designed for running multiple Claude Code instances (or any command) in parallel. It pairs a full-featured CLI with a browser dashboard that streams live terminal output over WebSocket. Sessions are enriched with tags, descriptions, and statistics, all persisted in SQLite so nothing is lost between restarts. Built-in inter-pane messaging lets your agents coordinate without manual copy-paste.
2118

2219
## Installation
2320

2421
```bash
25-
git clone <repo-url> && cd clux
26-
npm install
27-
npm run build
22+
npm install -g @clux-cli/cli
2823
```
2924

30-
## Web Dashboard
25+
Requires **Node.js 18+** and **tmux**.
3126

32-
The web package provides a browser UI backed by Express and WebSocket with live session state, pane output, and session management.
27+
<details>
28+
<summary>Install from source</summary>
3329

3430
```bash
35-
npm run dev:web
31+
git clone https://github.com/devhelp/clux.git && cd clux
32+
npm install
33+
npm run build
3634
```
3735

38-
The dashboard runs at `http://127.0.0.1:3456` by default. Configure via environment variables (see `.env.example`).
36+
This compiles TypeScript and bundles the CLI. You can then run it directly with `node dist/index.js` or link it globally with `npm link`.
3937

40-
## CLI
38+
</details>
4139

42-
After building, you can also manage sessions from the command line:
43-
44-
```bash
45-
node packages/cli/dist/index.js --help
46-
```
40+
## Quick Start
4741

48-
Or create an alias:
42+
Start a Claude session in your current project directory:
4943

5044
```bash
51-
alias clux="node $(pwd)/packages/cli/dist/index.js"
45+
clux claude
5246
```
5347

54-
### Quick Start
48+
The session name is auto-generated from your directory path. If a session for this directory already exists, clux switches you into it instead of creating a duplicate.
5549

56-
Create a session with an LLM agent:
50+
Open the web dashboard in another terminal to see all sessions at a glance:
5751

5852
```bash
59-
clux create my-project --command claude --path ~/projects/my-app
53+
clux web
6054
```
6155

62-
List running sessions:
56+
The dashboard is available at `http://127.0.0.1:3456` and shows live terminal output, session metadata, and management controls.
6357

64-
```bash
65-
clux ls
66-
```
67-
68-
Send a prompt to a running session:
58+
You can also manage sessions without attaching to them:
6959

7060
```bash
71-
clux send my-project "refactor the auth module"
61+
clux ls # list all sessions
62+
clux send my-session "run the tests" # send a command to a pane
63+
clux capture my-session --lines 100 # grab recent output
7264
```
7365

74-
Capture the current output:
66+
## Claude Sessions
67+
68+
The `clux claude` command is a shortcut purpose-built for Claude Code workflows. It creates a tmux session running `claude`, tags it with `claude` and `ai`, and immediately attaches. The session name is derived from the working directory — path segments are abbreviated to keep names readable (e.g. `/home/user/projects/clux` becomes `claude_h-u-projects-clux`).
7569

7670
```bash
77-
clux capture my-project --lines 100
71+
clux claude # auto-name from current directory
72+
clux claude my-agent # explicit name
73+
clux claude --path ~/other/repo # different working directory
74+
clux claude --detach # create without attaching
75+
clux claude --danger # run with --dangerously-skip-permissions
7876
```
7977

80-
Attach to a session interactively:
78+
The command is idempotent: if a session with the resolved name already exists, clux switches to it rather than failing.
8179

82-
```bash
83-
clux attach my-project
84-
```
80+
## CLI Commands
8581

86-
### Commands
82+
Every command supports `--help` for detailed usage.
8783

8884
| Command | Description |
8985
|---------|-------------|
90-
| `create <name>` | Create a new session. Supports `--command`, `--path`, `--layout` |
91-
| `list` / `ls` | List all sessions. Filter with `--tag` or `--search` |
92-
| `info <name>` | Detailed session info |
93-
| `attach <name>` | Attach to a session (Ctrl+B D to detach) |
94-
| `kill <name>` | Kill a session |
95-
| `send <name> <text>` | Send text to a pane. Use `--pane` to target a specific pane |
96-
| `capture <name>` | Capture pane output. `--all` for full scrollback, `-o` to write to file |
97-
| `monitor <name>` | Watch pane output in real-time |
98-
| `relay <name>` | Relay messages between panes (`--from`, `--to`, `--message` or `--capture`) |
99-
| `add-window <name> <win>` | Add a new window to a session |
100-
| `rename-window <name> <idx> <new>` | Rename a window |
101-
| `export <name>` | Export session to Markdown |
102-
| `tag <name> <tags...>` | Add or remove (`-r`) tags |
86+
| `create <name>` | Create a session. `--command`, `--path`, `--layout`, `--description`, `--tags` |
87+
| `claude [name]` | Create or switch to a Claude session. `--path`, `--detach`, `--danger` |
88+
| `list` / `ls` | List sessions. `--tag`, `--search` |
89+
| `info <name>` | Detailed session info (windows, panes, metadata, stats) |
90+
| `attach <name>` | Attach interactively. Ctrl+B D to detach |
91+
| `kill <name>` | Terminate a session |
92+
| `send <name> <text>` | Send text to a pane. `--pane`, `--no-enter` |
93+
| `capture <name>` | Capture pane output. `--lines`, `--all`, `--output` |
94+
| `monitor <name>` | Watch pane output live. `--pane`, `--interval` |
95+
| `relay <name>` | Relay between panes. `--from`, `--to`, `--message` or `--capture` |
96+
| `export <name>` | Export session to Markdown. `--output` |
97+
| `tag <name> <tags...>` | Add tags. `-r` to remove |
10398
| `describe <name> <text>` | Set session description |
104-
| `stats [name]` | Session statistics (commands sent, duration) |
99+
| `stats [name]` | Session statistics |
100+
| `add-window <name> <window>` | Add a window. `--command` |
101+
| `rename-window <name> <idx> <new>` | Rename a window |
102+
| `web` | Start the web dashboard. `--port`, `--host` |
105103

106-
## Project Structure
104+
The `relay` command enables inter-agent coordination. You can capture the output of one pane and pipe it as input to another — useful when one agent produces context that a second agent needs to act on. Use `--capture` to grab recent output from the source pane, or `--message` to send a literal string.
107105

108-
```
109-
clux/
110-
packages/
111-
core/ # Session management, tmux wrapper, metadata store
112-
cli/ # Commander-based CLI (@clux-cli/cli)
113-
web/ # Express + WebSocket dashboard (@clux-cli/web)
106+
```bash
107+
clux relay my-session --from 0.0 --to 0.1 --capture 50
108+
clux relay my-session --from 0.0 --to 0.1 --message "refactor complete, review the diff"
114109
```
115110

116-
This is an npm workspaces monorepo. The `core` package is a shared dependency used by both `cli` and `web`.
111+
## Web Dashboard
117112

118-
## Development
113+
Launch the dashboard with `clux web`. It runs at `http://127.0.0.1:3456` by default. For LAN access, bind to all interfaces with `--host 0.0.0.0`.
119114

120-
```bash
121-
# Build everything
122-
npm run build
115+
The dashboard connects via WebSocket and renders live terminal output using xterm.js. The sidebar lists all active sessions with real-time status — sessions running Claude are detected automatically via process inspection and flagged with a distinct badge, no manual tagging required.
116+
117+
From the browser you can create new sessions, switch between panes using tabs, send commands, relay messages between panes (with a preview of captured output before sending), export sessions to Markdown, and terminate sessions. The interface uses a dark theme built on Radix color tokens and is fully responsive, collapsing to a slide-in sidebar on mobile screens.
118+
119+
Under the hood, the dashboard leverages tmux control mode for sub-16ms push latency when available, falling back to polling if control mode is not supported.
120+
121+
## REST API
123122

124-
# Build individual packages
125-
npm run build:core
126-
npm run build:cli
127-
npm run build:web
123+
The web server exposes a REST API for programmatic access and automation.
128124

129-
# Run the web dashboard in dev mode
130-
npm run dev:web
125+
| Method | Endpoint | Description |
126+
|--------|----------|-------------|
127+
| GET | `/api/sessions` | List all sessions |
128+
| GET | `/api/sessions/:name` | Get session details |
129+
| POST | `/api/sessions` | Create session |
130+
| DELETE | `/api/sessions/:name` | Kill session |
131+
| POST | `/api/sessions/:name/send` | Send text to a pane |
132+
| GET | `/api/sessions/:name/capture/:paneId` | Capture pane output (`?lines=N`) |
133+
| GET | `/api/sessions/:name/export` | Export session as Markdown |
134+
| POST | `/api/sessions/:name/relay` | Relay between panes |
135+
| POST | `/api/sessions/:name/windows` | Add a window |
136+
| DELETE | `/api/sessions/:name/panes/:paneId` | Kill a pane |
137+
| PATCH | `/api/sessions/:name/windows/:index` | Rename a window |
138+
| GET | `/api/settings` | Server configuration |
131139

132-
# Run tests
133-
npm test
134-
npm run test:watch
135-
npm run test:coverage
140+
Clients can also connect via WebSocket on the same host and port. Messages are JSON-encoded — use `subscribe` to stream live pane output, `send` to push text to a pane, and `input` to forward raw terminal keystrokes.
136141

137-
# Lint and format
138-
npm run lint
139-
npm run lint:fix
140-
npm run format
141-
npm run format:check
142+
## Architecture
142143

143-
# Clean build artifacts
144-
npm run clean
144+
The codebase is a single TypeScript package organized into three logical modules under `src/`: `core/` (tmux session management, SQLite metadata store, terminal parser, process detection), `cli/` (Commander-based commands), and `web/` (Express + WebSocket dashboard). TypeScript compiles to `dist/`, then esbuild bundles everything into a single `dist/index.js` for distribution. Session metadata is stored in SQLite at `~/.clux/sessions.db` with WAL mode enabled.
145+
146+
## Configuration
147+
148+
The web dashboard binds to `127.0.0.1:3456` by default. Override with CLI flags (`clux web --port 8080 --host 0.0.0.0`) or environment variables (`PORT`, `HOST`). All sessions are created with a 50,000-line scrollback buffer. Supported pane layouts: `tiled`, `even-horizontal`, `even-vertical`, `main-horizontal`, `main-vertical`.
149+
150+
## Development
151+
152+
For contributors working on clux itself:
153+
154+
```bash
155+
git clone https://github.com/devhelp/clux.git && cd clux
156+
npm install
157+
npm run build # compile TypeScript + esbuild bundle
158+
npm run dev:web # compile and run web dashboard locally
159+
npm test # run tests (vitest)
160+
npm run test:coverage # tests with coverage
161+
npm run lint # eslint
162+
npm run format:check # prettier check
145163
```
146164

147165
## License

esbuild.mjs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import * as esbuild from 'esbuild';
2+
import path from 'path';
3+
import fs from 'fs';
4+
import { fileURLToPath } from 'url';
5+
6+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
7+
8+
await esbuild.build({
9+
entryPoints: [path.join(__dirname, 'dist/index.js')],
10+
bundle: true,
11+
platform: 'node',
12+
target: 'node18',
13+
outfile: path.join(__dirname, 'dist/index.js'),
14+
allowOverwrite: true,
15+
external: ['better-sqlite3'],
16+
});
17+
18+
fs.cpSync(
19+
path.join(__dirname, 'public'),
20+
path.join(__dirname, 'dist/public'),
21+
{ recursive: true },
22+
);

0 commit comments

Comments
 (0)