{"id":47666163,"url":"https://github.com/alexei-led/ccgram","last_synced_at":"2026-05-03T10:04:26.533Z","repository":{"id":337638910,"uuid":"1154348823","full_name":"alexei-led/ccgram","owner":"alexei-led","description":"Telegram ↔ tmux bridge for Claude Code, Codex CLI, and Gemini CLI. Monitor output, respond to prompts, manage parallel sessions.  Control AI coding agents from your phone.","archived":false,"fork":false,"pushed_at":"2026-04-02T15:33:46.000Z","size":16993,"stargazers_count":38,"open_issues_count":1,"forks_count":17,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-03T00:41:48.700Z","etag":null,"topics":["ai-coding","claude-code","cli","codex","codex-cli","developer-tools","gemini","gemini-cli","python","telegram","telegram-bot","tmux"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"six-ddc/ccbot","license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/alexei-led.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-02-10T09:35:58.000Z","updated_at":"2026-04-02T15:33:51.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/alexei-led/ccgram","commit_stats":null,"previous_names":["alexei-led/ccbot","alexei-led/ccgram"],"tags_count":85,"template":false,"template_full_name":null,"purl":"pkg:github/alexei-led/ccgram","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexei-led%2Fccgram","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexei-led%2Fccgram/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexei-led%2Fccgram/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexei-led%2Fccgram/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alexei-led","download_url":"https://codeload.github.com/alexei-led/ccgram/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexei-led%2Fccgram/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31467985,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-06T08:36:52.050Z","status":"ssl_error","status_checked_at":"2026-04-06T08:36:51.267Z","response_time":112,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai-coding","claude-code","cli","codex","codex-cli","developer-tools","gemini","gemini-cli","python","telegram","telegram-bot","tmux"],"created_at":"2026-04-02T11:58:25.328Z","updated_at":"2026-05-03T10:04:26.522Z","avatar_url":"https://github.com/alexei-led.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# CCGram — Control AI Coding Agents from Telegram\n\n[![CI](https://github.com/alexei-led/ccgram/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/alexei-led/ccgram/actions/workflows/ci.yml)\n[![PyPI](https://img.shields.io/pypi/v/ccgram)](https://pypi.org/project/ccgram/)\n[![Downloads](https://img.shields.io/pypi/dm/ccgram)](https://pypi.org/project/ccgram/)\n[![Python](https://img.shields.io/pypi/pyversions/ccgram)](https://pypi.org/project/ccgram/)\n[![Typed](https://img.shields.io/pypi/types/ccgram)](https://pypi.org/project/ccgram/)\n[![License](https://img.shields.io/github/license/alexei-led/ccgram)](LICENSE)\n[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)\n\n**Control AI coding agents from your phone.** CCGram bridges Telegram to tmux — monitor output, respond to prompts, and manage multiple sessions without touching your computer. Supports [Claude Code](https://docs.anthropic.com/en/docs/claude-code), [Codex CLI](https://github.com/openai/codex), [Gemini CLI](https://github.com/google-gemini/gemini-cli), [Pi](https://pi.dev), and plain shell sessions.\n\n---\n\n## Why CCGram?\n\nAI coding agents run in your terminal. When you step away — commuting, on the couch, or just away from your desk — the session keeps working, but you lose visibility and control.\n\nCCGram fixes this. It operates on **tmux**, not any agent SDK. Your agent process stays exactly where it is, in a tmux window on your machine. CCGram reads its output and sends keystrokes to it. This means:\n\n- **Desktop to phone, mid-conversation** — walk away and keep monitoring from Telegram\n- **Phone back to desktop, anytime** — `tmux attach` and you're back with full scrollback\n- **Multiple sessions in parallel** — each Telegram topic maps to a separate tmux window, each running a different agent\n\nOther Telegram bots wrap agent SDKs into isolated API sessions that can't be resumed in your terminal. CCGram is a thin control layer over tmux — the terminal stays the source of truth.\n\n---\n\n## How It Works\n\n```mermaid\ngraph LR\n  subgraph phone[\"📱 Telegram Group (Forum Topics)\"]\n    direction TB\n    T1[\"💬 api — Claude\"]\n    T2[\"💬 ui — Codex\"]\n    T3[\"💬 data — Gemini\"]\n    T4[\"💬 ops — Shell\"]\n    T5[\"💬 lab — Pi\"]\n  end\n\n  subgraph bridge[\"⚡ CCGram\"]\n    direction TB\n    B1[\"read output\\n(transcripts + terminal)\"]\n    B2[\"send keystrokes\\n(tmux send-keys)\"]\n    B3[\"instant notifications\\n(Claude hooks)\"]\n  end\n\n  subgraph machine[\"🖥️ Your Machine — tmux session\"]\n    direction TB\n    W1[\"window @0 · claude\"]\n    W2[\"window @1 · codex\"]\n    W3[\"window @2 · gemini\"]\n    W4[\"window @3 · bash\"]\n    W5[\"window @4 · pi\"]\n  end\n\n  phone -- \"messages / voice\" --\u003e bridge\n  bridge -- \"responses / live view\" --\u003e phone\n  bridge \u003c--\u003e machine\n\n  style phone fill:#e8f4fd,stroke:#0088cc,stroke-width:2px,color:#333\n  style bridge fill:#fff8e1,stroke:#f9a825,stroke-width:2px,color:#333\n  style machine fill:#f0faf0,stroke:#2ea44f,stroke-width:2px,color:#333\n```\n\nEach Telegram Forum topic binds to one tmux window. Messages you type are sent as keystrokes to the pane; responses are parsed from session transcripts and delivered back as Telegram messages.\n\n---\n\n## Features\n\n### Session Control\n\n- **Topic-per-agent** — each Telegram Forum topic is one tmux window running one agent CLI\n- **Interactive prompts** — AskUserQuestion, ExitPlanMode, and Permission dialogs rendered as inline keyboards\n- **Slash commands** — provider-aware menu (Claude `/cost`, Codex `/status`, Gemini `/chat`, Pi `/compact`, etc.); mismatched commands report errors\n- **Voice messages** — transcribed via Whisper API (OpenAI/Groq), shown with **Send / Discard** buttons before forwarding\n- **Multi-pane support** — auto-detects blocked panes in agent teams, surfaces prompts as alerts; `/panes` for overview\n- **Terminal screenshots** — capture the current pane (or any specific pane) as a PNG image\n- **Terminal live view** — auto-refreshing screenshots every 5 seconds via **Live** button or `/live` command; content-hash gating skips edits when nothing changed; auto-stops after timeout (configurable)\n- **File delivery** (`/send`) — send workspace files to Telegram: exact path (`/send docs/arch.png`), glob (`/send *.png`), substring search (`/send arch`), or interactive browser (`/send`). Project-scoped with security filtering (hidden files, credentials, gitignored, \u003e50 MB denied)\n- **Action toolbar** (`/toolbar`) — provider-specific inline buttons. Universal row: Screenshot, Ctrl-C, Live, Send. Provider row varies: Claude (Mode, Think, Esc), Codex (Esc, Enter, Tab), Gemini (Mode, YOLO, Esc), Pi (Esc, Enter, Tab), Shell (Enter, EOF, Suspend)\n- **Remote Control** — 📡 topic badge when RC is active; one-tap activation from status keyboard\n\n### Real-Time Monitoring\n\n- **Full status context** — status line shows what the agent is actually doing (\"📝 Writing tests for auth module\"), not a generic label\n- **Configurable topic emoji color scheme** — `CCGRAM_STATUS_MODE=system` (default, green = agent working) or `user` (green = idle, ready for input) — pick the convention that matches how you scan the topic list\n- **Completion summaries** — when an agent finishes, a single-line LLM summary of what was accomplished edits the Ready message in-place (~1-2s delay; static enriched Ready appears immediately)\n- **Enriched Ready message** — task checklist, turn count, and last status shown on completion\n- **Tool results** — tool use/result pairs, thinking content, Bash exit codes, and error/success indicators in batched output\n- **Tool-call visibility toggle** — `CCGRAM_HIDE_TOOL_CALLS=true` globally hides `tool_use`/`tool_result` messages; `/toolcalls` cycles per-window (`default → shown → hidden`). Hook events (Stop, errors, subagent updates) bypass the gate\n- **Entity-based formatting** — markdown converted to plain text + MessageEntity offsets; automatic plain text fallback, no parse errors\n\n### Session Management\n\n- **Directory browser** — create sessions from Telegram by navigating your file system\n- **Auto-sync** — create a tmux window manually and the bot auto-creates a matching topic\n- **Recovery** — Fresh / Continue / Resume keyboard when a session dies (buttons adapt per provider)\n- **Message history** — paginated browsing via `/history`\n- **Sessions dashboard** — `/sessions` shows all active sessions with status and kill buttons\n- **Persistent state** — bindings and read offsets survive bot restarts\n\n### Multi-Provider Support\n\n```mermaid\ngraph TB\n  subgraph providers[\"Agent Providers\"]\n    direction LR\n    C[\"🟠 Claude Code\\nhook events · resume · JSONL\"]\n    X[\"🧩 Codex CLI\\nresume · continue · JSONL\"]\n    G[\"♊ Gemini CLI\\nresume · continue · JSONL\"]\n    P[\"🥧 Pi\\nresume · continue · JSONL\"]\n    S[\"🐚 Shell\\nnl→command · raw mode\"]\n  end\n\n  subgraph detection[\"Auto-Detection\"]\n    D1[\"process name\\n(fast path)\"]\n    D2[\"ps -t tty\\n(JS runtime fallback)\"]\n    D3[\"pane title symbols\\n(Gemini fallback)\"]\n  end\n\n  providers --\u003e detection\n\n  style providers fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px,color:#333\n  style detection fill:#e8f4fd,stroke:#0088cc,stroke-width:2px,color:#333\n```\n\n- **Per-topic provider** — different topics can use different agents simultaneously\n- **Auto-detect** — externally created tmux windows are detected via process name, with `ps -t` TTY fallback for JS runtime wrappers (node/bun)\n- **[Emdash](https://emdash.ai) integration** — auto-discovers emdash tmux sessions; bind Telegram topics to emdash-managed agents with zero configuration\n\n### Shell Provider\n\n- **Chat-first** — type natural language → LLM generates a shell command → approve with one tap → output streams back\n- **Raw mode** — prefix with `!` to bypass the LLM and send commands directly\n- **Voice-to-command** — voice messages transcribed via Whisper, then routed through the LLM\n- **Dangerous command detection** — extra confirmation step before running destructive commands\n- **BYOK LLM** — OpenAI, Anthropic, xAI, DeepSeek, Groq, Ollama (zero new dependencies)\n\n### Inter-Agent Messaging (Swarm)\n\n```mermaid\ngraph LR\n  subgraph agents[\"Agent Windows\"]\n    A1[\"claude · api\"]\n    A2[\"codex · ui\"]\n    A3[\"shell · ops\"]\n  end\n\n  subgraph mailbox[\"~/.ccgram/mailbox/\"]\n    M[\"file-based\\nper-window inboxes\\nJSON messages · TTL\"]\n  end\n\n  subgraph telegram[\"Telegram\"]\n    N[\"silent notifications\\nin sender + recipient topics\"]\n    S[\"spawn approval\\ninline keyboard\"]\n  end\n\n  A1 -- \"ccgram msg send\" --\u003e mailbox\n  mailbox -- \"broker injects\\nvia send-keys\" --\u003e A2\n  A3 -- \"ccgram msg spawn\" --\u003e S\n  mailbox --\u003e N\n\n  style agents fill:#f0faf0,stroke:#2ea44f,stroke-width:2px,color:#333\n  style mailbox fill:#fce4ec,stroke:#c62828,stroke-width:2px,color:#333\n  style telegram fill:#e8f4fd,stroke:#0088cc,stroke-width:2px,color:#333\n```\n\n- Agents discover each other, exchange messages, broadcast notifications, and spawn new agents\n- File-based mailbox (`~/.ccgram/mailbox/`) — no database, no daemon\n- Broker delivers pending messages to idle windows automatically\n- Spawn approval requires Telegram keyboard confirmation\n- See **[docs/guides.md](docs/guides.md#inter-agent-messaging)** for setup and usage\n\n---\n\n## Quick Start\n\n### Prerequisites\n\n- **Python 3.14+**\n- **tmux** — installed and in PATH\n- **At least one agent CLI** — `claude` (default), `codex`, `gemini`, or `pi` installed and authenticated (or use `shell` with no extra install)\n\n### Install\n\n```bash\nuv tool install ccgram          # recommended\npipx install ccgram             # pipx\nbrew install alexei-led/tap/ccgram  # Homebrew (macOS)\n```\n\n### Configure\n\n1. Create a Telegram bot via [@BotFather](https://t.me/BotFather)\n2. In BotFather settings:\n   - **Allow Groups**: On\n   - **Group Privacy**: Off _(required to see all topic messages)_\n   - **Topics**: On\n3. Add the bot to a Telegram group with Topics enabled\n4. **Promote the bot to Administrator** with **Create Topics** and **Pin Messages** permissions\n5. Create `~/.ccgram/.env`:\n\n```ini\nTELEGRAM_BOT_TOKEN=your_bot_token_here\nALLOWED_USERS=your_telegram_user_id\nCCGRAM_GROUP_ID=your_telegram_group_id\n```\n\n\u003e Get your user ID from [@userinfobot](https://t.me/userinfobot). Get the group ID via [@RawDataBot](https://t.me/RawDataBot) (prefix the Peer ID with `-100`).\n\n### Install Claude Hooks (Claude Code only)\n\n```bash\nccgram hook --install\n```\n\nRegisters Claude Code hooks for automatic session tracking, instant interactive UI detection, API error alerting, and subagent/team notifications. Not needed for Codex, Gemini, or Pi.\n\n\u003e If hooks are missing, ccgram warns at startup with the fix command. Hooks are optional — terminal scraping works as fallback.\n\n### Run\n\n```bash\nccgram\n```\n\nOpen your Telegram group, create a new topic, send a message — a directory browser appears. Pick a project directory, choose your agent (Claude, Codex, Gemini, Pi, or Shell), choose session mode (`✅ Standard` or `🚀 YOLO`), and you're connected.\n\n---\n\n## Configuration Reference\n\n| Variable / Flag                | Default           | Description                                                                |\n| ------------------------------ | ----------------- | -------------------------------------------------------------------------- |\n| `TELEGRAM_BOT_TOKEN`           | _(required)_      | Bot token from @BotFather (env only)                                       |\n| `ALLOWED_USERS`                | _(required)_      | Comma-separated Telegram user IDs                                          |\n| `CCGRAM_DIR`                   | `~/.ccgram`       | Config and state directory                                                 |\n| `CCGRAM_PROVIDER`              | `claude`          | Default provider (`claude`, `codex`, `gemini`, `pi`, `shell`)              |\n| `CCGRAM_\u003cNAME\u003e_COMMAND`        | _(from provider)_ | Override launch command per provider                                       |\n| `CCGRAM_GROUP_ID`              | _(all groups)_    | Restrict to one Telegram group                                             |\n| `CCGRAM_STATUS_MODE`           | `system`          | Topic emoji color scheme: `system` (green=working) or `user` (green=ready) |\n| `CCGRAM_HIDE_TOOL_CALLS`       | `false`           | Global default for hiding `tool_use`/`tool_result` messages                |\n| `CCGRAM_LLM_PROVIDER`          | _(disabled)_      | LLM for shell command generation + completion summaries                    |\n| `CCGRAM_LLM_API_KEY`           | _(empty)_         | LLM API key (env only)                                                     |\n| `CCGRAM_WHISPER_PROVIDER`      | _(disabled)_      | Whisper provider for voice transcription (`openai`, `groq`)                |\n| `CCGRAM_LIVE_VIEW_INTERVAL`    | `5`               | Live view refresh interval in seconds                                      |\n| `CCGRAM_LIVE_VIEW_TIMEOUT`     | `300`             | Live view auto-stop timeout in seconds                                     |\n| `CCGRAM_SEND_SEARCH_DEPTH`     | `5`               | Max directory depth for `/send` file search                                |\n| `CCGRAM_SEND_MAX_RESULTS`      | `50`              | Max file results returned by `/send` search                                |\n| `AUTOCLOSE_DONE_MINUTES`       | `30`              | Auto-close completed topics after N minutes                                |\n| `AUTOCLOSE_DEAD_MINUTES`       | `10`              | Auto-close dead sessions after N minutes                                   |\n| `CCGRAM_PANE_LIFECYCLE_NOTIFY` | `false`           | Default for per-window pane create/close notifications                     |\n| `CCGRAM_MINIAPP_BASE_URL`      | _(disabled)_      | Externally reachable HTTPS URL for the Mini App dashboard                  |\n| `CCGRAM_MINIAPP_HOST`          | `127.0.0.1`       | Local aiohttp bind host for the Mini App server                            |\n| `CCGRAM_MINIAPP_PORT`          | `8765`            | Local aiohttp bind port for the Mini App server                            |\n\nFull reference: **[docs/guides.md](docs/guides.md#configuration)**\n\n---\n\n## Mini App Dashboard (Optional)\n\nCCGram ships an optional web dashboard that opens from a Telegram inline button and runs inside Telegram's WebApp container. Three surfaces are available in v3.0:\n\n- **Live terminal** — xterm.js stream of the bound tmux pane (read-only)\n- **Transcript** — paginated session history with full-text search\n- **Multi-pane grid** — every pane in the window in one view; click to focus\n\nThe Mini App is **disabled by default**. When `CCGRAM_MINIAPP_BASE_URL` is unset, neither the HTTP server nor the dashboard button are exposed.\n\n### Enable\n\n1. Set the three Mini App env vars:\n   ```ini\n   CCGRAM_MINIAPP_BASE_URL=https://ccgram.example.com\n   CCGRAM_MINIAPP_HOST=127.0.0.1\n   CCGRAM_MINIAPP_PORT=8765\n   ```\n2. Terminate TLS in front of the local aiohttp server (cloudflared, caddy, or nginx). The server listens on plain HTTP at `MINIAPP_HOST:MINIAPP_PORT`; the public domain in `MINIAPP_BASE_URL` must serve it over HTTPS — Telegram WebApps refuse plain HTTP.\n3. In [@BotFather](https://t.me/BotFather):\n   - `/setdomain` — register your domain\n   - `/newapp` — create a Mini App entry pointing to the same URL\n4. Restart `ccgram`. A new \"🪟 Dashboard\" button appears on the status bubble.\n\nTokens are HMAC-signed with the bot token, scoped to a single window + user, and expire on a short clock. There is no cross-window access — every API route validates the token on every call.\n\n### Reverse-proxy snippet (caddy)\n\n```\nccgram.example.com {\n  reverse_proxy 127.0.0.1:8765\n}\n```\n\nFor nginx, ensure `proxy_http_version 1.1` and the standard `Upgrade`/`Connection` headers are forwarded so the live terminal websocket works.\n\n---\n\n---\n\n## Development\n\n```bash\ngit clone https://github.com/alexei-led/ccgram.git\ncd ccgram\nuv sync --extra dev\n\nmake check        # fmt + lint + typecheck + unit + integration tests\nmake test-e2e     # E2E tests (requires agent CLIs, see docs/guides.md)\n```\n\n---\n\n## Documentation\n\n- **[docs/guides.md](docs/guides.md)** — CLI reference, configuration, voice messages, multi-instance setup, session recovery, testing\n- **[docs/providers.md](docs/providers.md)** — Provider details (Claude, Codex, Gemini, Pi, Shell), session modes, LLM configuration, custom launch commands\n\n---\n\n## Migrating from ccbot\n\nCCGram was previously named `ccbot`. If upgrading from v1.x:\n\n```bash\npip install ccgram          # or: brew install alexei-led/tap/ccgram\nmv ~/.ccbot ~/.ccgram       # migrate config directory\n# Update CCBOT_* env vars → CCGRAM_* (old vars still work with deprecation warnings)\nccgram hook --install       # re-install hooks\n```\n\n---\n\n## Acknowledgments\n\nInspired by [ccbot](https://github.com/six-ddc/ccbot) by [six-ddc](https://github.com/six-ddc), the original Telegram-to-Claude-Code bridge. Thanks for the spark.\n\n## License\n\n[MIT](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexei-led%2Fccgram","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falexei-led%2Fccgram","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexei-led%2Fccgram/lists"}