Skip to content

Latest commit

 

History

History
125 lines (87 loc) · 6.11 KB

File metadata and controls

125 lines (87 loc) · 6.11 KB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project Overview

Telegram bot providing remote access to Claude Code. Python 3.10+, built with Poetry, using python-telegram-bot for Telegram and claude-agent-sdk for Claude Code integration.

Commands

make dev              # Install all deps (including dev)
make install          # Production deps only
make run              # Run the bot
make run-debug        # Run with debug logging
make test             # Run tests with coverage
make lint             # Black + isort + flake8 + mypy
make format           # Auto-format with black + isort

# Run a single test
poetry run pytest tests/unit/test_config.py -k test_name -v

# Type checking only
poetry run mypy src

Architecture

Dual Claude Integration (SDK primary, CLI fallback)

ClaudeIntegration (facade in src/claude/facade.py) wraps two backends:

  • ClaudeSDKManager (src/claude/sdk_integration.py) -- Primary. Uses claude-agent-sdk async query() with streaming. Session IDs come from Claude's ResultMessage, not generated locally.
  • ClaudeProcessManager (src/claude/integration.py) -- Legacy CLI subprocess fallback. Used when SDK fails with JSON decode or TaskGroup errors.

Sessions auto-resume: per user+directory, persisted in SQLite, temporary IDs (temp_*) are never sent to Claude for resume.

Request Flow

Agentic mode (default, AGENTIC_MODE=true):

Telegram message -> Security middleware (group -3) -> Auth middleware (group -2)
-> Rate limit (group -1) -> MessageOrchestrator.agentic_text() (group 10)
-> ClaudeIntegration.run_command() -> SDK (with CLI fallback)
-> Response parsed -> Stored in SQLite -> Sent back to Telegram

External triggers (webhooks, scheduler):

Webhook POST /webhooks/{provider} -> Signature verification -> Deduplication
-> Publish WebhookEvent to EventBus -> AgentHandler.handle_webhook()
-> ClaudeIntegration.run_command() -> Publish AgentResponseEvent
-> NotificationService -> Rate-limited Telegram delivery

Classic mode (AGENTIC_MODE=false): Same middleware chain, but routes through full command/message handlers in src/bot/handlers/ with 13 commands and inline keyboards.

Dependency Injection

Bot handlers access dependencies via context.bot_data:

context.bot_data["auth_manager"]
context.bot_data["claude_integration"]
context.bot_data["storage"]
context.bot_data["security_validator"]

Key Directories

  • src/config/ -- Pydantic Settings v2 config with env detection, feature flags (features.py)
  • src/bot/handlers/ -- Telegram command, message, and callback handlers (classic mode)
  • src/bot/middleware/ -- Auth, rate limit, security input validation
  • src/bot/features/ -- Git integration, file handling, quick actions, session export
  • src/bot/orchestrator.py -- MessageOrchestrator: routes to agentic or classic handlers
  • src/claude/ -- Claude integration facade, SDK/CLI managers, session management, tool monitoring
  • src/storage/ -- SQLite via aiosqlite, repository pattern (users, sessions, messages, tool_usage, audit_log, cost_tracking)
  • src/security/ -- Multi-provider auth (whitelist + token), input validators, rate limiter, audit logging
  • src/events/ -- EventBus (async pub/sub), event types, AgentHandler, EventSecurityMiddleware
  • src/api/ -- FastAPI webhook server, GitHub HMAC-SHA256 + Bearer token auth
  • src/scheduler/ -- APScheduler cron jobs, persistent storage in SQLite
  • src/notifications/ -- NotificationService, rate-limited Telegram delivery

Security Model

5-layer defense: authentication (whitelist/token) -> directory isolation (APPROVED_DIRECTORY + path traversal prevention) -> input validation (blocks .., ;, &&, $(), etc.) -> rate limiting (token bucket) -> audit logging.

SecurityValidator blocks access to secrets (.env, .ssh, id_rsa, .pem) and dangerous shell patterns.

Webhook authentication: GitHub HMAC-SHA256 signature verification, generic Bearer token for other providers, atomic deduplication via webhook_events table.

Configuration

Settings loaded from environment variables via Pydantic Settings. Required: TELEGRAM_BOT_TOKEN, TELEGRAM_BOT_USERNAME, APPROVED_DIRECTORY. Key optional: ALLOWED_USERS (comma-separated Telegram IDs), USE_SDK (default true), ANTHROPIC_API_KEY, ENABLE_MCP, MCP_CONFIG_PATH.

Agentic platform settings: AGENTIC_MODE (default true), ENABLE_API_SERVER, API_SERVER_PORT (default 8080), GITHUB_WEBHOOK_SECRET, WEBHOOK_API_SECRET, ENABLE_SCHEDULER, NOTIFICATION_CHAT_IDS.

Output verbosity: VERBOSE_LEVEL (default 1, range 0-2). Controls how much of Claude's background activity is shown to the user in real-time. 0 = quiet (only final response, typing indicator still active), 1 = normal (tool names + reasoning snippets shown during execution), 2 = detailed (tool names with input summaries + longer reasoning text). Users can override per-session via /verbose 0|1|2. A persistent typing indicator is refreshed every ~2 seconds at all levels.

Feature flags in src/config/features.py control: MCP, git integration, file uploads, quick actions, session export, image uploads, conversation mode, agentic mode, API server, scheduler.

Code Style

  • Black (88 char line length), isort (black profile), flake8, mypy strict
  • pytest-asyncio with asyncio_mode = "auto"
  • structlog for all logging (JSON in prod, console in dev)
  • Type hints required on all functions (disallow_untyped_defs = true)

Adding a New Bot Command

Agentic mode

Agentic mode has minimal commands (/start, /new, /status, /verbose). To add a new command:

  1. Add handler function in src/bot/orchestrator.py
  2. Register in MessageOrchestrator._register_agentic_handlers()
  3. Add to MessageOrchestrator.get_bot_commands() for Telegram's command menu
  4. Add audit logging for the command

Classic mode

  1. Add handler function in src/bot/handlers/command.py
  2. Register in MessageOrchestrator._register_classic_handlers()
  3. Add to MessageOrchestrator.get_bot_commands() for Telegram's command menu
  4. Add audit logging for the command