Thanks for your interest in contributing to Herald!
- Python 3.11+
- uv (Python package manager)
- A Telegram bot token (for integration testing)
# Clone the repo
git clone https://github.com/joshuaoliphant/herald.git
cd herald
# Install all dependencies (including dev)
uv sync
# Run tests
uv run pytest
# Run linter
uv run ruff check src tests- Formatter/Linter: Ruff
- Line length: 100 characters
- Target: Python 3.11+
- All files should start with a two-line
ABOUTME:comment explaining what the file does
Run linting before submitting:
uv run ruff check src testsHerald follows Test-Driven Development (TDD):
- Write a failing test first
- Write minimal code to make it pass
- Refactor while keeping tests green
# Run full test suite
uv run pytest
# Run specific test file
uv run pytest tests/test_config.py
# Run with verbose output
uv run pytest -vThe test suite currently has 286+ tests covering:
- Configuration parsing and validation
- Executor (Claude Agent SDK) interaction
- Webhook handler (message routing, authorization, streaming)
- Heartbeat system (scheduling, delivery, prompt processing)
- Chat history persistence
- Message formatting (Telegram MarkdownV2)
- Fork the repository
- Create a feature branch (
git checkout -b feature/my-feature) - Write tests for your changes
- Ensure all tests pass (
uv run pytest) - Ensure linting passes (
uv run ruff check src tests) - Commit with descriptive messages
- Push to your fork and open a PR
src/herald/
├── main.py # Entry point, uvicorn server
├── config.py # Pydantic settings from environment
├── webhook.py # FastAPI webhook handler, Telegram integration
├── executor.py # Claude Agent SDK client management
├── formatter.py # Telegram MarkdownV2 formatting
├── chat_history.py # Conversation persistence to markdown
└── heartbeat/ # Proactive check-in system
├── config.py # Heartbeat-specific settings
├── scheduler.py # Periodic execution scheduler
├── delivery.py # Alert delivery to Telegram
└── processor.py # Heartbeat prompt processing
Open an issue on GitHub if you have questions or need help getting started.