telegram-commandcode
by qrak
README.md
# telegram-commandcode v2
**Async Python Telegram bot for Command Code CLI** — Hermes Agent architecture patterns.
Control your AI coding agent from Telegram with streaming progress, persistent sessions,
and resilient message delivery. Rewritten in Python with `python-telegram-bot` 20.x.
```
Telegram
↕
┌──────────┴──────────┐
│ bot.py (gateway) │ Async Python PTB bot
│ index.js (MCP) │ Node.js MCP server (unchanged)
└──────────┬──────────┘
↕
command code CLI
```
## Two Modes
| Mode | File | Language | Direction | Purpose |
|---|---|---|---|---|
| **Bot Daemon** | `telegram_commandcode/bot.py` | Python | Telegram → CC | Async gateway with streaming progress |
| **MCP Server** | `index.js` | Node.js | CC → Telegram | Agent sends messages, files, photos |
## Architecture (v2)
```
telegram_commandcode/
├── bot.py # PTB Application — entry point & lifecycle
├── gateway.py # Async event router — non-blocking dispatch
├── commands.py # 46+ slash command handlers
├── executor.py # Async subprocess runner for `cmd`
├── session.py # Persistent session state (JSON-backed)
├── formatter.py # MarkdownV2 escaping & safe formatting
├── chunking.py # Smart 4096-char split + file fallback
└── __init__.py
```
### Key Architectural Patterns
| Pattern | Implementation |
|---|---|
| **Decoupled Gateway** | PTB message handler is thin — never blocks. Long work dispatched via `asyncio.create_task()` in per-chat `asyncio.Lock` |
| **Persistent Sessions** | `ChatSession` dataclass stored in `~/.commandcode/telegram_sessions.json`. Survives restarts |
| **Streaming Progress** | Edit-in-place: one status message, progressively edited with stages (🤔→✅/❌). No message flooding |
| **Resilient Chunking** | `SmartSplitter`: splits at paragraph → sentence → word boundaries, capped at 4000 chars. File fallback at 15K chars |
| **Error Boundaries** | Every `send_message`/`edit_message_text` wrapped with parse-fallback. Reactions are best-effort |
## Quick Install
```bash
# Clone and install
git clone https://github.com/qrak/telegram-commandcode.git
cd telegram-commandcode
pip install -e "."
# Or with voice transcription support
pip install -e ".[voice]"
```
### Requirements
- Python 3.11+
- `python-telegram-bot[job-queue]>=20.8`
- Command Code CLI (`cmd`) installed and on PATH
- (Optional) `openai` for voice transcription
## Setup
```bash
# 1. Get bot token from @BotFather
# 2. Set environment variables
export TELEGRAM_BOT_TOKEN="123456:ABC..."
export TELEGRAM_ALLOWED_USERS="any" # or comma-separated user IDs
# 3. Start the bot
telegram-commandcode
# or: python -m telegram_commandcode.bot
```
### Env Vars
| Variable | Default | Description |
|---|---|---|
| `TELEGRAM_BOT_TOKEN` | *(required)* | Bot token from @BotFather |
| `TELEGRAM_ALLOWED_USERS` | `any` | Comma-separated user IDs |
| `COMMAND_CODE_CMD` | `cmd` | Path to Command Code binary |
| `COMMAND_CODE_YOLO` | `true` | `false` → read-only mode |
| `COMMAND_CODE_MAX_TURNS` | `20` | Max conversation turns per prompt |
| `OPENAI_API_KEY` | *(optional)* | For voice message transcription |
### systemd Service (persistent)
```ini
# ~/.config/systemd/user/telegram-commandcode.service
[Unit]
Description=Telegram Command Code Bot
After=network-online.target
[Service]
Type=simple
ExecStart=/home/user/.local/bin/telegram-commandcode
Environment="TELEGRAM_BOT_TOKEN=your_token"
Environment="COMMAND_CODE_YOLO=true"
Restart=always
RestartSec=5
[Install]
WantedBy=default.target
```
```bash
systemctl --user daemon-reload
systemctl --user enable --now telegram-commandcode.service
```
## Features
| Feature | Description |
|---|---|
| 👀 **Reactions** | 👀 while processing, ✅ on success, ❌ on error |
| 📷 **Photo reception** | Photos downloaded and passed to `cmd` |
| 📄 **File reception** | Documents sent to `/tmp/telegram-cmd/` |
| 🎤 **Voice transcription** | OpenAI Whisper (requires `OPENAI_API_KEY`) |
| 📎 **Auto-send files** | `MEDIA:/path` in output → auto-attached |
| 👥 **Group chat** | Responds when @mentioned or replied to |
| ✏️ **Single-message editing** | Status message edited in-place — no chat clutter |
| 🔄 **Session chaining** | `/resume` reads CC session history |
| 🎯 **Goal tracking** | `/goal <text>` sets standing objective |
| 🧭 **Mid-session steering** | `/steer <text>` guides all subsequent prompts |
| 📋 **Prompt queueing** | `/queue <prompt>` queues for next turn |
| 🔄 **Background tasks** | `/background <prompt>` runs detached |
| ⚙️ **Config persistence** | Model/provider/effort persist to `~/.commandcode/config.json` |
## Slash Commands
All 46+ commands from the Node.js version are implemented. Type `/` in Telegram to see the menu.
**CLI-mapped**: `/feedback`, `/learntaste`, `/login`, `/logout`, `/mcp`, `/skills`, `/taste`, `/info`, `/version`, `/update`
**Config & session**: `/status`, `/model`, `/effort`, `/provider`, `/add-dir`, `/goal`, `/steer`, `/plan`, `/compact-mode`, `/configure-models`, `/context`
**Session control**: `/resume`, `/clear`, `/new`, `/fork`, `/rename`, `/undo`, `/retry`, `/queue`, `/background`, `/stop`, `/reload`
**Prompt-based**: `/review`, `/init`, `/memory`, `/pr-comments`, `/agents`, `/cmd`
## MCP Server (unchanged)
The Node.js MCP server (`index.js`) remains for Command Code → Telegram direction:
```bash
cmd mcp add telegram \
-e TELEGRAM_BOT_TOKEN=*** \
-e TELEGRAM_DEFAULT_CHAT_ID=1141080547 \
-- npx github:qrak/telegram-commandcode
```
## License
MIT
This server cannot be deployed
Maintenance
ActivityStale
ResponsivenessNo issues