CCGram

repository·main·Indexed 42 days ago

https://github.com/alexei-led/ccgram

A tool to manage and monitor AI coding agents (such as Claude Code, Codex, and Gemini) from Telegram via terminal multiplexers like tmux, herdr, or agterm. It bridges Telegram topics to terminal-session targets, allowing users to send commands, view live terminal screenshots, and interact with agent prompts from mobile or desktop devices.

Tokens
99.2K
Snippets
210
Records
455
Agent score
52%

What's inside CCGram

  1. Core features of CCGram

    main

    CCGram provides several features designed for remote AI development via Telegram:

    • Multi-Agent Support: Control various agents including Claude, Codex, Gemini, Pi, and Shell.
    • Voice Mode: Use phone-native voice prompts with options to send or discard.
    • Shell LLM: Convert natural language into terminal commands with an approval step.
    • Worktree Topics: Create new Telegram topics that automatically spin up new tasks in isolated git worktrees/branches.
    • Live Inspection: Monitor progress via screenshots, live view, or transcripts.
    • Artifact Fetch: Use commands to /send files from the remote agent back to your Telegram chat.
  2. Architecture Refactor Overview and Targets

    main

    The CCGram architecture is undergoing a modularity refactor to address significant coupling and complexity issues. The refactor targets six primary areas to improve maintainability and split large, monolithic files into cohesive modules:

    1. Message Delivery: Splitting message_queue.py into four files to separate queue primitives, Claude tool batching, batch formatting, and status bubble I/O.
    2. Shell Prompt Setup: Consolidating ensure_setup logic behind a single orchestrator (shell_prompt_orchestrator.py) to replace duplicated logic across multiple handlers.
    3. Polling Strategies: Splitting the TerminalStatusStrategy class and extending the registry to support instance methods via a new register_bound capability.
    4. Toolbar: Decoupling TOML configuration, key dispatch, and Claude pane scraping. Scraping logic is moved to AgentProvider.scrape_current_mode.
    5. Screenshot Callbacks: Extracting screenshot-related concerns into status_bar_actions.py.
    6. WindowView Adoption: Migrating various handlers to use the WindowView frozen dataclass instead of direct session_manager access to reduce coupling.
  3. Understand the CCGram Project Summary

    main

    CCGram bridges Telegram topics to terminal multiplexer windows that run AI coding agents.

    Key architectural concepts:

    • Mapping: One Telegram topic maps to exactly one terminal-session target. This target can be a tmux window, a guarded Herdr agent session, or an agterm session UUID. A single shared Herdr tab may contain multiple targets.
    • Identity: The system uses window_id as the internal unique identifier. Never use display names for identity.
    • Message Handling: Message parsing preserves the full content; splitting only occurs at the Telegram send event.
    • Provider Behavior: Capabilities and behavior are determined on a per-window basis.
  4. Overview of Session Monitoring Architecture

    main

    The session_monitor.py acts as the central coordinator for the entire system. It manages the lifecycle of sessions by composing several specialized modules:

    • event_reader.py: Performs stateless, pure I/O to read new events.
    • transcript_reader.py: Parses per-session JSONL files and uses an mtime cache for efficiency.
    • session_lifecycle.py: Reconciles changes in the session map and handles session termination.
    • idle_tracker.py: Tracks activity timestamps per session.
    • delivery_contract.py: Manages the receipt/outcome contract for messages.
    • message_queue.py: Handles the ordered delivery pipeline.

    The transcript_reader.py interacts with the AgentProvider protocol (specifically seed_task_state and apply_task_entries) to allow providers like ClaudeProvider to maintain their own internal task states.

  5. Overview of CCGram Architecture

    main

    CCGram acts as a Telegram control plane for AI coding agents hosted in tmux sessions. It maps Telegram Forum topics to specific tmux windows, allowing one topic to control one agent session.

    Key architectural components include:

    • Telegram UX Handlers: Manage interaction via Telegram commands and callbacks.
    • Provider Abstraction: A unified interface for different AI providers (e.g., Claude, Gemini, Codex).
    • Tmux Manager: Infrastructure for terminal I/O and window management.
    • Session/Window State: Stores metadata about active sessions, including worktrees, providers, and transcripts.
    • Polling System: Monitors agent status and terminal output to update the Telegram UI.
  6. Understand the Informative Telegram Output format

    main

    CCGram provides enhanced status updates via Telegram to give developers better visibility into AI agent progress.

    Status Display

    • Active Status: Displays a single-line status with an emoji prefix and the raw status text (e.g., 📝 Writing tests for auth module).
    • Ready/Completion Status: When a task is finished, the output includes a checklist of completed tasks, the number of tasks done, and the total number of turns taken.

    Example Completion Formats:

    Standard Ready:

    ✓ Ready
    ━━━━━━━━━━━━━━━━━━━━
    ✔ write unit tests
    ✔ run linter
    ✔ fix formatting
    3/3 tasks done · 12 turns

    Enriched with LLM Summary (appears ~1-2s after completion):

    ✓ Done — wrote 3 test files for auth module, all 47 tests passing
    ━━━━━━━━━━━━━━━━━━━━
    ✔ write unit tests
    ✔ run linter
    ✔ fix formatting
    3/3 tasks done · 12 turns

    Fallback (no tasks tracked):

    ✓ Ready
    Last: Running make test · 12 turns
  7. Understand the Shell Provider Architecture

    main

    The ShellProvider is a specialized implementation designed to orchestrate terminal environments. It is composed of several layers:

    • Handlers (handlers/): Responsible for low-level shell operations including shell_commands.py, shell_capture.py, shell_context.py, and shell_prompt_orchestrator.py.
    • Providers (providers/): A thin shell.py layer and shell_infra.py utilities that inherit from the JsonlProvider base.
    • Prompt Orchestration: The system can manipulate terminal prompts (PS1) using modes like append ⌘N⌘ or replace mode: {prefix}:N❯ via setup_shell_prompt().
    • Optional LLM Integration: Can include an llm/ component for Natural Language to command generation via get_completer().
  8. How CCGram manages cross-process communication via hooks

    main

    CCGram uses a separate subprocess (hook.py) to interact with AI agents (like Claude Code). Because these are separate processes, they do not share memory or imports. Instead, they communicate through a file-based contract:

    1. session_map.json: Used for session state.
    2. events.jsonl: Used for event streaming.

    Approximately 10 modules in the core system depend on these file schemas to monitor agent activity. When extending the system, ensure any new process-to-process communication is mediated by a stable, versioned schema to avoid breaking the session_monitor.

  9. Understand the Informative Telegram Output tiers

    main

    CCGram uses a two-tier approach to provide visibility into what AI agents are doing via Telegram without being overly chatty:

    1. Tier 1 (Static/Always Active): Provides immediate, non-LLM-dependent visibility. It includes:

      • Full status text with emoji prefixes.
      • An enriched "Ready" message that includes the last known status and a task checklist.
      • Improved display for tool batch results.
    2. Tier 2 (LLM-Enhanced): An optional, asynchronous layer that triggers upon task completion. If an LLM is configured, CCGram makes an async call to summarize accomplishments and then edits the existing "Ready" message in-place with the summary.

    Fallback Behavior: If no LLM is configured, CCGram gracefully falls back to Tier 1 only.

  10. Unify recovery flows with RecoveryBanner

    main

    CCGram uses a unified RecoveryBanner dataclass in handlers/recovery_callbacks.py to handle agent session interruptions. This banner provides interactive buttons to restore or resume sessions.

    Recovery Modes

    • dead: The session has completely failed and needs a fresh start.
    • restore: Re-instating a previous state.
    • resume: Continuing an existing session.

    Commands

    • /restore: Re-displays the recovery banner to allow the user to attempt state restoration.
    • /resume: Invokes the cross-project picker using a new entry formatter (showing timestamp, last 4 characters of ID, and message count).
  11. Modify tool-call visibility settings

    main

    CCGram allows controlling whether tool_use and tool_result messages are visible. This is managed through a layered approach:

    • Persistence: The tool_call_visibility field (values: default, shown, or hidden) is stored in src/ccgram/window_state_store.py.
    • Feature Interface: Use the read/write projections in src/ccgram/window_state_ports/tool_state.py to interact with visibility (e.g., get_tool_call_visibility, set_tool_call_visibility, set_batch_mode).
    • Message Pipeline: The _handle_content_task function in src/ccgram/handlers/messaging_pipeline/message_queue.py acts as a gate; hidden entries are dropped before registration unless they are StatusUpdateTask hook events.
    • User Command: The /toolcalls command in src/ccgram/handlers/messaging_pipeline/topic_commands.py allows users to cycle through these modes.
  12. Understand the Herdr Tab-Identity Model

    main

    In CCGram's Herdr integration, the core mental model is that a topic is equivalent to a tab.

    Key characteristics of this model:

    • Identity: A WindowRef represents a single tab. The window_id is set to the tab_id.
    • Naming: Tabs are labeled using the format "<workspace> ▸ <tab>" (e.g., "ccgram ▸ herdr-support").
    • Filtering: Internal workspace and tab labels starting with __ (e.g., __*__) are filtered out of list_windows results.
    • CRUD Operations:
      • create_window returns the tab_id from the created tab.
      • kill_window performs a tab close.
      • rename_window performs a tab rename.
      • find_window works via tab get using the tab_id.