中文 | English
Unified session orchestrator for terminal-based AI coding tools.
CodeCLI wraps Claude Code, Cursor Agent, OpenAI Codex CLI, OpenCode, and Bash into one control layer. Run multiple AI sessions simultaneously and manage them from your local terminal, Telegram, WeChat, an HTTP bridge, or a LangChain tool — all sharing one command system.
When you run multiple AI CLIs at once, things get messy fast:
- Switching between terminal windows for different tools
- Can't see session status remotely
- A tool is stuck on a
y/nconfirmation and you're not at your desk - TUI output is noisy and hard to read in messaging apps
- No unified way to manage sessions across tools
CodeCLI solves this by putting all your AI sessions behind one command interface, accessible from anywhere.
| Tool | Command | Default Executable |
|---|---|---|
| Claude Code | /claude [cwd] |
claude |
| Cursor Agent | /cursor [cwd] |
agent |
| OpenAI Codex CLI | /codex [cwd] |
codex |
| OpenCode | /opencode [cwd] |
opencode |
| Bash | /bash [cwd] [cmd] |
bash |
CodeCLI does not install these tools — you install them yourself, and CodeCLI launches, manages, and orchestrates them.
| Channel | Command | Use Case |
|---|---|---|
| Local CLI | python main.py cli |
Direct terminal access |
| Telegram | python main.py telegram |
Remote control from your phone |
python main.py weixin |
Remote control via WeChat (QR login) | |
| HTTP | python main.py http |
API bridge for external systems |
| Tool / LangChain | python main.py tool |
Embed in AI agent pipelines |
All channels share the same message handler and command system.
Requirements: Python 3.10+, at least one AI CLI tool installed.
# Clone the repository
git clone https://github.com/ax128/CodeCLI.git
cd CodeCLI
# Install dependencies
pip install -r requirements.lock # pinned for reproducible installs
# or: pip install -r requirements.txt
# Create runtime config (required)
cp config/codecli.example.json config/codecli.json
# Run locally
python main.py cli
# Start a Claude session
/claude /path/to/project
# Send a task
Review this project and list potential issues
# Check status
/status
# See output
/output- Create a bot with @BotFather and get your token
- Copy config:
cp config/codecli.example.json config/codecli.json - Pick a Telegram config name
<name>(e.g.agent) and setdefault_channel.chatto<name> - Set
channels.telegram.<name>.enabled=trueand configurebotToken - If
chatIdis empty, runpython main.py telegramand send any message to the bot within 120s — CodeCLI discovers and saves the chat ID
python main.py weixin
# First run: QR code is drawn in the terminal (install dependencies: pip install Pillow qrcode), then scan with WeChat; credentials saved automatically
# Subsequent runs: connects directlyOr login separately: python -m cli_orchestrator.weixin_login
WeChat uses a compact mobile /help view by default. Use /help cursor for Cursor-specific advanced commands.
Note: the WeChat channel is text-only (no images/files/voice).
- In
config/codecli.json, setchannels.http.<name>.enabled=trueand set a strongauthToken(notCHANGE_ME) - Run
python main.py http(usesdefault_channel.http) orpython main.py http:<name> - POST messages and poll events (default template uses
127.0.0.1:8787,/message,/events; auth viaX-CodeCLI-TokenorAuthorization: Bearer ...):
# Send one message
curl -sS -X POST "http://127.0.0.1:8787/message" \
-H "Content-Type: application/json" \
-H "X-CodeCLI-Token: <authToken>" \
-d '{"sender":"alice","text":"/status"}'
# Poll events (drains the queue for that sender)
curl -sS "http://127.0.0.1:8787/events?sender=alice" \
-H "X-CodeCLI-Token: <authToken>"Responses: POST /message returns {"ok": true, "accepted": true, "channel_key": "..."} and GET /events returns {"ok": true, "events": [{"text": "...", ...}]}.
./start.sh telegram # Run as background daemon with Telegram
./start.sh weixin # Run as background daemon with WeChat
./start.sh # Use default channel from configThe script kills any leftover CodeCLI processes, starts a new instance with nohup, writes logs to logs/codecli.out, and tails the log. Press Ctrl+C to detach — CodeCLI keeps running.
On shared hosts, review start.sh before using it as-is.
Multi-session management — Run multiple AI sessions in parallel, switch between them with /use <id>, send to a specific session with /1 text.
Clean output delivery — TUI chrome, ANSI codes, spinners, and box-drawing characters are stripped. Telegram and WeChat remote chat channels deliver final results by default, while HTTP keeps explicit request/response acknowledgements.
Output mode control — result mode (default) delivers only completed output. stream mode delivers incremental updates. Automatic policy switches to stream for long-running tasks like test suites.
Key injection — /enter, /esc, /tab, /y, /n, /key ctrl+c — handle confirmations and navigate TUI tools remotely.
State detection — Automatically detects running, idle, completed, need_confirmation, error, stopped.
Cross-channel ownership — Sessions track which channel started them. Use /handoff and /claim to transfer ownership between channels.
Message verification gate — Optional password protection with configurable TTL and startup grace period.
LangChain integration — Use CodeCLI as a LangChain Tool or LangGraph ToolNode, with structured responses including status_hint, next_suggested_commands, and full session state.
| Category | Commands |
|---|---|
| Start | /claude, /cursor, /codex, /opencode, /bash, /start <cmd> |
| Send | direct text, /1 text, /send [id] [--output result|stream] <text> |
| Confirm | /y, /n, /enter, /esc, /tab, /key <name> |
| Monitor | /status, /output, /screen, /logs, /watch, /list, /all |
| Mode | /mode [id] [result|stream] |
| Manage | /use <id>, /stop, /stopall, /kill <id>, /restart |
| Paths | /cd, /pwd, /ls [path], /paths, /cat <file> |
| Ownership | /owner, /handoff, /claim |
| System | /ping, /info, /help, /reboot, /exit |
All commands with [id] default to the active session when omitted.
cp config/codecli.example.json config/codecli.jsonconfig/codecli.json is required for all modes. Telegram and HTTP channels will not start unless their enabled flag is set to true (and HTTP requires a non-empty authToken; don’t leave it as CHANGE_ME).
Key sections in config/codecli.json:
| Section | Purpose |
|---|---|
default_channel |
Which channel starts by default |
channels.telegram |
Bot token, chat ID, file transfer password |
channels.weixin |
WeChat token, account ID (auto-filled by QR login) |
channels.http |
HTTP bridge bind address, port, auth token |
cli_path |
Override executable paths for each tool |
security.verification |
Optional message password gate |
output_policy.rules |
Custom automatic output mode rules |
worked_path |
Saved directory aliases (p1, p2, ...) |
See config/codecli.example.json for the full template.
LangChain is optional and not included in requirements.txt / requirements.lock. Install it before using create_langchain_tool(...) (e.g. pip install langchain pydantic).
from cli_orchestrator import create_langchain_tool
tool = create_langchain_tool(response_format="content")
result = tool.invoke({"message": "/claude /workspace/project"})
print(result["reply_text"])
print(result["active_session"])For LangGraph ToolNode, use response_format="content_and_artifact". See CODECLI_TOOL.md for the full structured response schema.
cli_orchestrator/
├── chat.py # Unified message handler for all channels
├── channels.py # Channel capability registry
├── manager.py # Session lifecycle management
├── process.py # PTY process control (pexpect + pyte)
├── commands/ # Command routing and handlers
├── chat_features/ # Help, paths, file transfer, message gate
├── manager_features/ # Watcher, notifications, restore
├── tools/ # Per-tool adapters (claude, cursor, codex, ...)
├── telegram_bot.py # Telegram long-polling adapter
├── weixin_channel.py # WeChat API client and monitor
├── http_channel.py # HTTP/JSON bridge adapter
├── langchain_tool.py # LangChain tool wrapper
└── protocol.py # Shared types and error model
All channels register capabilities with ChannelRegistry and then enter the shared Chat._handle_message() flow. Adding a new channel means adding registration + transport — no changes to session management or process control.
python -m compileall cli_orchestrator # Compile check
python -m pip check # Dependency checkThe current public release focuses on the runtime package and operator docs. Internal tests and demo scripts used during development are not included in this repository snapshot.
- Never commit
config/codecli.json— it may contain real tokens and passwords config/codecli.example.jsonis the safe template for version control- Treat
logs/andsessions/as local runtime data, not release artifacts - The message verification gate adds optional password protection for remote channels
- The tool channel bypasses the message gate (designed for programmatic access)
MIT License. See LICENSE.