WebSocket hub for multi-client Claude Code session synchronization. Enables seamless switching between sprite-mobile web UI and claude --resume terminal sessions.
Web Browsers → sprite-mobile:8081 (WebSocket proxy)
↓
claude-hub:9090 (this service)
↓
Claude processes + ~/.claude/projects/ session files
- WebSocket server on port 9090
- Multi-client broadcasting per session
- Client registration/unregistration
- Connection pooling
- Spawns headless Claude processes (
claude --print --output-format stream-json) - Routes user messages to Claude via stdin
- Parses stream-json protocol responses
- Broadcasts Claude output to all connected clients in real-time
- Interrupt support (kill process mid-generation)
- Auto-spawn on first client connection
- fsnotify watcher for Claude session files (
~/.claude/projects/-home-sprite/*.jsonl) - Detects terminal Claude processes via /proc scanning
- State machine:
IDLE → WEB_ONLY ⇄ TERMINAL_ONLY - Auto-kills headless process when terminal session detected
- Tails .jsonl files and broadcasts terminal messages to web clients
- Auto-respawns headless when terminal exits
- Service YAML configuration (
~/.sprite/services/claude-hub.yaml) - Startup script with env sourcing
- Graceful shutdown (SIGTERM/SIGINT handling)
- Health check endpoint (
/health) - Structured logging
- Basic sequential processing via headless process
- Interrupt support (works, could be enhanced)
- Future: Persistent queue for crash recovery
The recommended way to install claude-hub is via the sprite setup script:
cd /home/sprite
./sprite-setup.sh 12This will:
- Clone/update the claude-hub repository to
~/.claude-hub/ - Build the Go binary
- Create the service configuration
- Start the claude-hub service on port 9090
# Clone
git clone https://github.com/clouvet/claude-hub.git ~/.claude-hub
cd ~/.claude-hub
# Build
go build -o bin/claude-hub main.go
# Create service configuration
mkdir -p ~/.sprite/services
cat > ~/.sprite/services/claude-hub.yaml << EOF
name: claude-hub
port: 9090
command: $HOME/.claude-hub/scripts/start-service.sh
workdir: $HOME/.claude-hub
description: WebSocket hub for multi-client Claude Code session synchronization
EOF
# Start service
sprite-env services start claude-hubThe hub listens on port 9090 (internal only - accessed via sprite-mobile proxy).
Enable the WebSocket proxy in sprite-mobile:
cd ~/.sprite-mobile
USE_GO_HUB=true bun server.tsThen:
- Open sprite-mobile in browser
- Start a session and send messages (works via Go hub)
- Run
claude --resume <claude-session-uuid>in terminal - Hub auto-detects terminal, kills headless, starts watching file
- Messages from terminal appear in web UI in real-time
- Exit terminal - hub respawns headless process
hub.go- WebSocket hub (broadcast, routing)client.go- Client connection management
manager.go- Process lifecycle managementheadless.go- Claude process wrapperdetector.go- Terminal process detection
session.go- Session state trackingstate.go- State machine (IDLE, WEB_ONLY, TERMINAL_ONLY, TRANSITIONING)
watcher.go- fsnotify file watchingparser.go- JSONL parsing and content extraction
protocol.go- stream-json protocol types
Environment variables:
PORT- WebSocket port (default: 9090)HOME- User home directory for session file paths
Start the hub:
cd ~/.claude-hub
./bin/claude-hubTest multi-client sync:
- Open multiple browser tabs to same session
- Send messages from any tab
- Verify all tabs see messages and responses
Test terminal sync:
- Start session in web UI
- Get Claude session UUID from logs
- Run
claude --resume <uuid>in terminal - Send messages in terminal
- Verify web UI shows terminal messages in real-time
- Exit terminal
- Verify web UI returns to web mode
# Build
go build -o bin/claude-hub main.go
# Run with logs
./bin/claude-hub 2>&1 | tee hub.log
# Check for terminal processes
ps aux | grep claude
# Monitor session files
watch -n 1 'ls -lh ~/.claude/projects/-home-sprite/*.jsonl | tail -5'github.com/gorilla/websocket- WebSocket servergithub.com/fsnotify/fsnotify- File watching
- sprite-mobile - Web UI that proxies to this hub
MIT