This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
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.
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 srcClaudeIntegration (facade in src/claude/facade.py) wraps two backends:
ClaudeSDKManager(src/claude/sdk_integration.py) -- Primary. Usesclaude-agent-sdkasyncquery()with streaming. Session IDs come from Claude'sResultMessage, 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.
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.
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"]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 validationsrc/bot/features/-- Git integration, file handling, quick actions, session exportsrc/bot/orchestrator.py-- MessageOrchestrator: routes to agentic or classic handlerssrc/claude/-- Claude integration facade, SDK/CLI managers, session management, tool monitoringsrc/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 loggingsrc/events/-- EventBus (async pub/sub), event types, AgentHandler, EventSecurityMiddlewaresrc/api/-- FastAPI webhook server, GitHub HMAC-SHA256 + Bearer token authsrc/scheduler/-- APScheduler cron jobs, persistent storage in SQLitesrc/notifications/-- NotificationService, rate-limited Telegram delivery
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.
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.
- 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)
Agentic mode has minimal commands (/start, /new, /status, /verbose). To add a new command:
- Add handler function in
src/bot/orchestrator.py - Register in
MessageOrchestrator._register_agentic_handlers() - Add to
MessageOrchestrator.get_bot_commands()for Telegram's command menu - Add audit logging for the command
- Add handler function in
src/bot/handlers/command.py - Register in
MessageOrchestrator._register_classic_handlers() - Add to
MessageOrchestrator.get_bot_commands()for Telegram's command menu - Add audit logging for the command