Turn AI CLIs into Production-Ready Services
Bridge powerful AI CLIs (Claude Code, OpenCode) into persistent, secure, production-grade interactive services.
Quick Start · Features · Architecture · Docs · Discussions · 简体中文
# One-line installation
curl -sL https://raw.githubusercontent.com/hrygo/hotplex/main/install.sh | bash
# Or build from source
make build
# Start with Slack (or any platform)
export HOTPLEX_SLACK_BOT_TOKEN=xoxb-...
export HOTPLEX_SLACK_APP_TOKEN=xapp-...
./hotplexd --config configs/chatapps/slack.yaml| Component | Version |
|---|---|
| Go | 1.25+ |
| AI CLI | Claude Code or OpenCode |
| 🔄 Session Pooling | Long-lived CLI processes with instant reconnection |
| 🌊 Full-Duplex Streaming | Sub-second token delivery via Go channels |
| 🛡️ Regex WAF | Block destructive commands (rm -rf /, mkfs, etc.) |
| 🔒 PGID Isolation | Clean process termination, no zombies |
| 💬 Multi-Platform | Slack · Telegram · Feishu · DingTalk |
| 📦 Go SDK | Embed directly in your Go app with zero overhead |
| 🔌 WebSocket Gateway | Language-agnostic access via hotplexd daemon |
| 📊 OpenTelemetry | Built-in metrics and tracing support |
| 🐳 Docker Ready | Run multiple isolated bots with one command |
The missing control plane for AI agents in production
| Challenge | HotPlex Solution |
|---|---|
| AI agents spin up fresh each request | Persistent sessions - CLI stays alive, reuses context |
| No safety for destructive commands | Regex WAF - Programmable firewall for shell instructions |
| Hard to scale AI interactions | Process multiplexing - Hundreds of concurrent sessions |
| Integration complexity | ChatApps - One codebase, multiple platforms |
| Enterprise-grade security | PGID isolation + filesystem jail + container sandbox |
┌─────────────────────────────────────────────────────────────────┐
│ ChatApps Layer │
│ Slack · Telegram · Feishu · DingTalk │
└────────────────────────────┬────────────────────────────────────┘
│
┌────────────────────────────▼────────────────────────────────────┐
│ WebSocket Gateway │
│ (hotplexd daemon / Go SDK) │
└────────────────────────────┬────────────────────────────────────┘
│
┌────────────────────────────▼────────────────────────────────────┐
│ Engine / Runner │
│ I/O Multiplexing · Session Pool · Events │
└────────────────────────────┬────────────────────────────────────┘
│
┌────────────────────┼────────────────────┐
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│ Claude │ │ OpenCode│ │ Custom │
│ CLI │ │ CLI │ │ Provider│
└─────────┘ └─────────┘ └─────────┘
| Layer | Implementation |
|---|---|
| Tool Governance | AllowedTools config - restrict agent capabilities |
| Danger WAF | Regex interception - block rm -rf /, mkfs, dd |
| Process Isolation | PGID-based termination - no orphaned processes |
| Filesystem Jail | WorkDir lockdown - confined to project root |
| Container Sandbox | Docker (BaaS) - OS-level isolation & limits |
import (
"context"
"fmt"
"time"
"github.com/hrygo/hotplex"
"github.com/hrygo/hotplex/types"
)
engine, err := hotplex.NewEngine(hotplex.EngineOptions{
Timeout: 5 * time.Minute,
IdleTimeout: 30 * time.Minute,
})
if err != nil {
panic(err)
}
defer engine.Close()
cfg := &types.Config{
WorkDir: "/path/to/project",
SessionID: "user-session-123",
}
engine.Execute(context.Background(), cfg, "Refactor this function", func(eventType string, data any) error {
if msg, ok := data.(*types.StreamMessage); ok {
fmt.Print(msg.Content) // Streaming response
}
return nil
})# configs/chatapps/slack.yaml
platform: slack
mode: socket
provider:
type: claude-code
default_model: sonnet
engine:
work_dir: ~/projects/hotplex
timeout: 30m
idle_timeout: 1h
security:
owner:
primary: ${HOTPLEX_SLACK_PRIMARY_OWNER}
policy: trusted
assistant:
bot_user_id: ${HOTPLEX_SLACK_BOT_USER_ID}
dm_policy: allow
group_policy: multibotexport HOTPLEX_SLACK_BOT_USER_ID=B12345
export HOTPLEX_SLACK_BOT_TOKEN=xoxb-...
export HOTPLEX_SLACK_APP_TOKEN=xapp-...
./hotplexd --config configs/chatapps/slack.yamlconst ws = new WebSocket('ws://localhost:8080/ws/v1/agent');
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
console.log(data.type, data.content);
};
ws.send(JSON.stringify({
type: 'execute',
prompt: 'Hello, AI!'
}));| 🚀 Deployment Guide | Docker, production setup |
| 💬 ChatApps Manual | Slack, Telegram, Feishu, DingTalk |
| 🛠 Go SDK Reference | Complete SDK documentation |
| 🔒 Security Guide | WAF, isolation, best practices |
| 📊 Observability | Metrics, tracing, logging |
Contributions are welcome! Please read our Contributing Guide for details.
# Development setup
go mod download # Install dependencies
make test # Run tests
make lint # Run linter
make build # Build binary
# Submit a PR
git checkout -b feat/your-feature
git commit -m "feat: add awesome feature"
gh pr create --fillMIT License © 2024-present HotPlex Contributors
