Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
133 changes: 96 additions & 37 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@

<p align="center">
<img src="assets/telegram.svg" alt="Telegram" height="80">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<img src="assets/claude.svg" alt="Claude Code" height="80">
</p>

# TeleClaude

**A Python framework for building Telegram bots that use [Claude Code](https://github.com/anthropics/claude-code) to read, plan, and edit their own codebase - with human-in-the-loop approval, voice transcription via OpenAI Whisper, and self-restarting deployment.**
**Build Telegram apps that can be developed from Telegram.**

TeleClaude is a Python base app for Telegram-first products that pair naturally with [Claude Code](https://github.com/anthropics/claude-code). You message your running bot, Claude Code reads the repo, proposes a plan, and you approve the change from Telegram. The bot can then restart and pick up the new code.

<sub>`anthropic` `claude-code` `claude-code-channels` `telegram-bot` `ai-agent` `self-improving-software` `whisper` `voice-to-code` `agentic-coding` `python`</sub>
It is useful when the product interface is Telegram, and you want the development loop to live there too.

<sub>`anthropic` `claude-code` `telegram-bot` `ai-agent` `human-in-the-loop` `whisper` `voice-to-code` `agentic-coding` `python`</sub>

<p align="center">
<a href="https://pypi.org/project/teleclaude/"><img src="https://img.shields.io/pypi/v/teleclaude?color=blue" alt="PyPI"></a>
Expand All @@ -18,15 +21,40 @@

---

## The idea: let Claude Code edit itself through Telegram
## Why this exists

I kept building small Telegram apps and wanted a smoother loop:

Your bot is a thin Telegram relay. **[Claude Code](https://github.com/anthropics/claude-code) is the agentic part** - it reads the codebase, proposes changes, and writes files when you approve. The bot just forwards your messages to Claude Code and sends back the response.
1. Ask the running app for a change
2. Let Claude Code inspect the repo
3. Review the plan in Telegram
4. Approve or reject the edit
5. Restart the bot when the change is ready

The result is a **closed-loop development cycle**: `chat -> analyze -> plan -> approve -> edit -> restart`. No IDE, no SSH, no deploy pipeline. Just a conversation with your running application from your phone - or even a voice message transcribed via [Whisper](https://github.com/openai/whisper).
For many changes, that means no SSH session and no IDE round-trip. Just a controlled Claude Code workflow from the same place the app already lives.

**What about [Claude Code Channels](https://docs.anthropic.com/en/docs/claude-code/channels)?** Anthropic's official Telegram/Discord/iMessage channels are a promising direction, but they're still in research preview - when we last tested them, the experience wasn't stable enough for production use. TeleClaude was built to fill that gap: your bot runs Claude Code as a subprocess on the server where it's deployed, with a plan/approve workflow and self-restart baked in. No local machine needed, no `--channels` flag, no Bun dependency - just `pip install` and go. If Channels matures into a solid production path, we'd love to add it as an alternative backend - [contributions welcome](https://github.com/ofir5300/teleclaude/issues).
TeleClaude is the base layer for that workflow: a Telegram bot framework, a Claude Code session wrapper, a plan/approve flow, and a few practical controls for running bots in the wild.

<img src="assets/claude-bot.png" alt="Claude Bot" width="60">
## Demo

<p align="center">
<a href="assets/example-from-polybot.png"><img src="assets/example-from-polybot.png" alt="Claude Code control menu inside a running Telegram bot" width="360"></a>
</p>

<p align="center"><sub>Claude Code controls inside a running Telegram app: model, session, availability, flush, restart, and usage-limit watcher.</sub></p>

## What you get

- **Telegram interface for Claude Code** - send free text or voice messages to your running app.
- **Read-only planning before edits** - Claude Code analyzes first, then waits for approval.
- **Approve/reject from Telegram** - keep a human in the loop before files change.
- **Session controls** - pin, clear, flush, and hand off context between Claude Code sessions.
- **Model switching** - choose Opus, Sonnet, or Haiku from the bot menu.
- **Context window visibility** - see token usage, trend, peak, and estimated turns remaining from Telegram.
- **Usage-limit reset watcher** - get a Telegram alert when Claude Code's usage window resets. This alone can be useful as a Claude Code notifier.
- **Voice messages** - optional Whisper transcription for voice-to-Claude workflows.
- **Self-restart** - restart the bot process after changes so the running app picks up the new code.
- **Custom commands** - subclass the base bot and add your own Telegram commands.

## How it works

Expand All @@ -40,17 +68,18 @@ The result is a **closed-loop development cycle**: `chat -> analyze -> plan -> a
+----------------+ +-----------------+ +--------------------+
```

<a href="assets/example-from-polybot.png"><img align="right" src="assets/example-from-polybot.png" alt="Claude control example from PolyBot" height="190"></a>
Example flow:

1. You send a message in Telegram
2. TeleClaude routes it to Claude Code in **read-only plan mode**
3. Claude analyzes your codebase and proposes a plan
4. You `/approve` or `/reject` from Telegram
5. On approve, Claude executes with file-edit permissions
6. `/restart` reloads the bot to pick up code changes
7. The application is now running its improved version of itself
```text
You: add a /status command that shows the last 5 git commits
Claude: reads the repo and proposes a plan
You: tap Approve Plan in the /claude menu (or send /approve)
Claude: edits the files
You: tap Restart Bot in the /claude menu (or send /restart)
Bot: running with the new /status command
```

<br clear="right">
The important bit is that Claude Code does not get write access by default. Normal messages run in read-only plan mode. File edits only happen after you approve the pending plan.

## Quickstart

Expand Down Expand Up @@ -91,27 +120,30 @@ except KeyboardInterrupt:
bot.stop_polling()
```

That's it. Send any message in Telegram and Claude Code responds. Built-in commands:
Send any message in Telegram and Claude Code responds.

## Built-in commands

| Command | What it does |
| ----------- | ------------------------------------------------------------------- |
| Free text | Chat with Claude Code (read-only mode) |
| Voice msg | Transcribed via Whisper, then routed to Claude |
| `/claude` | Interactive menu: model switcher, session info, flush, approve/reject |
| `/approve` | Execute Claude's pending plan (allows file edits) |
| `/reject` | Discard the pending plan |
| `/session` | Session management (`/session pin <id>`, `/session clear`) |
| `/context` | Check Claude Code availability (rate-limit detection) |
| `/restart` | Restart the bot process (picks up code changes) |
| `/help` | Show all available commands |
| Command | What it does |
| ----------- | --------------------------------------------------------------------- |
| Free text | Chat with Claude Code in read-only plan mode |
| Voice msg | Transcribed via Whisper, then routed to Claude Code |
| `/claude` | Interactive menu: availability, model, session, flush, approve/reject, watcher, restart |
| `/approve` | Execute Claude's pending plan with file-edit permissions; also available in the menu |
| `/reject` | Discard the pending plan; also available in the menu |
| `/session` | Session management (`/session pin <id>`, `/session clear`) |
| `/context` | Check Claude Code availability and context usage; also available in the menu |
| Watcher | Toggle from `/claude`; pings when Claude Code's usage-limit window resets |
| `/restart` | Restart the bot process so code changes take effect; also available in the menu |
| `/help` | Show all available commands |

### Add your own commands
## Add your own commands

Subclass `TeleClaudeBot` and override `domain_commands()` to register custom `/commands`:

```python
import subprocess
from teleclaude import ClaudeSession, TeleClaudeBot, kill_previous
from teleclaude import TeleClaudeBot

class MyBot(TeleClaudeBot):
def domain_commands(self):
Expand All @@ -138,22 +170,31 @@ Other hooks you can override:

## Features

### Context window telemetry

TeleClaude parses Claude Code's JSON output and surfaces useful session stats in Telegram: cost, turns, token usage, context-window percentage, trend, peak usage, average growth, and estimated turns remaining. You do not need to open a terminal just to know whether the current Claude Code session is getting crowded.

### Usage-limit reset watcher

The `/claude` menu includes a persistent usage-limit watcher. When enabled, it probes Claude Code in the background, detects rate-limit windows, and sends a Telegram alert when the window resets. Even if you are not using TeleClaude as a full bot framework yet, this can be useful as a lightweight Claude Code availability notifier.

### Voice messages

Send a voice message in Telegram and it gets auto-transcribed via [OpenAI Whisper](https://github.com/openai/whisper), then routed to Claude. Install the optional dependency:
Send a voice message in Telegram and TeleClaude transcribes it with [OpenAI Whisper](https://github.com/openai/whisper), then routes the text to Claude Code. Install the optional dependency:

```bash
pip install openai-whisper
```

The Whisper model (`base`) is lazy-loaded on first voice message. If not installed, the bot replies with install instructions.
The Whisper model (`base`) is lazy-loaded on first voice message. If Whisper is not installed, the bot replies with install instructions.

### Session handoff

The `/claude` menu includes **Flush & New Session**, which:

1. Asks Claude to write a `.handoff.md` summary of the current session context
2. Clears the session pin
3. On the next message, a new session bootstraps from `.handoff.md` automatically
3. Bootstraps the next session from `.handoff.md`

To enable automatic handoff bootstrap, pass `bootstrap_file` to `ClaudeSession`:

Expand All @@ -163,7 +204,23 @@ session = ClaudeSession(project_dir=".", bootstrap_file=".handoff.md")

### Rate-limit detection

When Claude returns a rate-limit error, the bot automatically starts background polling (every 5 min, up to 12 h) and notifies you when Claude is back online. You can also manually check via `/context` or the `/claude` menu.
When Claude returns a rate-limit error, the bot starts background polling every 5 minutes for up to 12 hours and notifies you when Claude is back online. You can also check manually with `/context` or the `/claude` menu.

## If you are an agent reading this

TeleClaude is a base app/framework, not a finished single-purpose bot. If you are Claude Code or another coding agent evaluating this repo:

- Start with `teleclaude/base_bot.py` for the Telegram app surface.
- Use `teleclaude/session_cli.py` for the Claude Code subprocess/session wrapper.
- Extend behavior through `domain_commands()`, `on_domain_callback()`, `help_text()`, `on_restart()`, and `plan_prompt_wrapper()` instead of patching the base flow.
- Preserve the plan/approve/reject safety model: free text should plan first; edits happen only after approval.
- Treat `/claude` as the primary control surface; several direct commands also exist as menu buttons.

### Why not Claude Code Channels?

[Claude Code Channels](https://docs.anthropic.com/en/docs/claude-code/channels) is Anthropic's official direction for connecting Claude Code to Telegram, Discord, and iMessage. It is promising, but when this project started it was still a research-preview path and not stable enough for the bots I was running.

TeleClaude takes a simpler approach: your bot runs Claude Code as a subprocess on the same server where the app is deployed. No local machine needs to stay open, no `--channels` flag, and no Bun dependency. If Channels becomes the right production backend later, TeleClaude can add it behind the same session interface.

## Configuration reference

Expand Down Expand Up @@ -195,9 +252,11 @@ cd example && cp .env.example .env # fill in your tokens
python main.py
```

## Contributing
## Project status

TeleClaude is usable, packaged on PyPI, and already extracted from real Telegram bots. It is still early. Expect some rough edges around deployment style, Claude Code CLI behavior, and long-running bot operations.

Contributions welcome! Open an issue or PR on [GitHub](https://github.com/ofir5300/teleclaude).
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should still deliver the message that contribution is welcome....

If you are building Telegram-first tools with Claude Code, try it on a small bot and open an issue with what breaks. Contributions are welcome, especially from people running real bots: bug reports, docs fixes, screenshots/GIFs, and small framework improvements are all useful signal.

## License

Expand Down