Welcome to the Tux Developer Guide! This comprehensive resource covers everything you need to contribute to Tux development.
Who Is This For?
This guide is for:
- Contributors who want to add features or fix bugs
- Developers learning the Tux codebase
- Maintainers working on core systems
- Anyone interested in how Tux works internally
If you're using or deploying Tux, see the User Guide or Admin Guide instead.
Quick Navigation
🚀 Getting Started
New to Tux development? Start here:
- Development Setup - Set up your environment
- Project Structure - Understand the codebase
- First Contribution - Make your first PR
- Code Standards - Style guide and best practices
🏗️ Architecture
Understanding the system:
- Architecture Overview - High-level system design
- Bot Lifecycle - Startup/shutdown process
- Cog System - Module/plugin architecture
- Command System - Hybrid command implementation
- Permission System - Dynamic rank-based permissions
- Configuration System - Multi-source config loading
- Database Architecture - Controller + Service pattern
- Service Layer - Service architecture
🔧 Core Systems
Deep dives into key systems:
- Hot Reload - Development hot-reload system
- Error Handling - Error handling architecture
- Sentry Integration - Error tracking and tracing
- Task Monitor - Background task monitoring
- Logging - Loguru integration
- Prefix Manager - Guild prefix management
- Emoji Manager - Custom emoji system
- Plugin System - Plugin architecture
📐 Patterns & Best Practices
Learn our coding patterns:
- Database Patterns - Controller pattern, DI
- Error Patterns - Error handling best practices
- Async Patterns - Async/await guidelines
- Caching - Cache strategies
- Service Wrappers - External API patterns
📚 How-To Guides
Step-by-step tutorials:
- Creating a Cog - Add new command modules
- Creating Commands - Implement hybrid commands
- Database Operations - Use controllers
- UI Components - Views, modals, buttons
- External APIs - HTTP client and wrappers
- Adding Features - Feature implementation
- Config Options - Add configuration options
🧩 Module Deep Dives
Understanding key modules:
- Moderation System - Coordinator pattern
- Levels System - XP and ranking
- Snippets System - Text snippet management
- Code Execution - Godbolt/Wandbox integration
- Config Wizard - Interactive onboarding
🗄️ Database
Working with data:
- Models - SQLModel model creation
- Controllers - Controller pattern
- Base Controllers - Reusable base classes
- Migrations - Alembic workflow
- Testing - py-pglite test setup
🧪 Testing
Ensure quality:
- Testing Overview - Philosophy and strategy
- Unit Tests - Testing individual components
- Integration Tests - Testing interactions
- E2E Tests - End-to-end testing
- Fixtures - Test data management
- CI Pipeline - GitHub Actions
🛠️ CLI Tools
Development tools:
- CLI Overview - Typer-based CLI system
- Extending CLI - Add new commands
🎨 UI System
Building interfaces:
- Embeds - Create rich embeds
- Views - Interactive views
- Modals - User input forms
- Buttons - Interactive buttons
- Onboarding Wizard - Multi-step wizards
🤝 Contributing
Join the team:
- Git Workflow - Branching and PRs
- Code Review - Review guidelines
- Documentation - Writing docs
- Versioning - Semver and releases
- Design Decisions - ADRs
Quick Start
1. Set Up Environment
# Clone repository
git clone https://github.com/allthingslinux/tux.git
cd tux
# Install UV and dependencies
curl -LsSf https://astral.sh/uv/install.sh | sh
uv sync
# Set up pre-commit hooks
uv run pre-commit install
2. Start Development
# Start database
uv run docker up
# Run migrations
uv run db push
# Start bot with hot-reload
uv run tux start --debug
3. Make Changes
- Edit code in
src/tux/
- Bot automatically reloads on save
- Test in Discord
4. Run Quality Checks
# Run all checks
uv run dev all
# Or individually
uv run dev lint
uv run dev format
uv run dev type-check
uv run tests run
5. Submit PR
# Create branch
git checkout -b feature/my-feature
# Commit with conventional commits
git commit -m "feat: add awesome feature"
# Push and create PR
git push origin feature/my-feature
Project Overview
Tech Stack
- Language: Python 3.13+
- Framework: discord.py 2.6+
- Package Manager: UV
- Database: PostgreSQL with SQLModel + SQLAlchemy
- Migrations: Alembic
- Logging: Loguru
- Error Tracking: Sentry SDK
- HTTP Client: httpx
- CLI: Typer
- Type Checking: Basedpyright (strict mode)
- Linting/Formatting: Ruff
- Testing: pytest with py-pglite
- Documentation: MkDocs Material + mkdocstrings
Architecture Principles
- Async-first: All I/O operations use async/await
- Type safety: Strict type hints throughout
- Dependency Injection: Controllers injected via BaseCog
- Controller Pattern: Database access through controllers
- Service Layer: External APIs wrapped in services
- Plugin System: Extensible via plugins
- Hot Reload: Fast development iteration
- Comprehensive Testing: Unit, integration, and E2E tests
Codebase Structure
tux/
├── src/tux/ # Main source code
│ ├── core/ # Core bot functionality
│ │ ├── app.py # Application lifecycle
│ │ ├── bot.py # Bot class
│ │ ├── base_cog.py # Base class for cogs
│ │ ├── permission_system.py
│ │ └── setup/ # Startup orchestration
│ ├── database/
│ │ ├── models/ # SQLModel models
│ │ ├── controllers/ # Database controllers
│ │ ├── migrations/ # Alembic migrations
│ │ └── service.py # Database service
│ ├── modules/ # Command modules (cogs)
│ │ ├── moderation/ # Mod commands
│ │ ├── utility/ # Utility commands
│ │ ├── features/ # Feature modules
│ │ └── ...
│ ├── services/ # Service layer
│ │ ├── handlers/ # Event/error handlers
│ │ ├── hot_reload/ # Hot reload system
│ │ ├── moderation/ # Moderation coordinator
│ │ ├── sentry/ # Sentry integration
│ │ └── wrappers/ # API wrappers
│ ├── ui/ # UI components
│ │ ├── embeds.py # Embed creator
│ │ ├── views/ # Discord views
│ │ ├── modals/ # Discord modals
│ │ └── buttons.py # Buttons
│ ├── shared/ # Shared utilities
│ │ ├── config/ # Configuration system
│ │ ├── constants.py # Constants
│ │ └── exceptions.py # Custom exceptions
│ ├── help/ # Custom help system
│ └── plugins/ # Plugin system
├── scripts/ # CLI tools
│ ├── cli.py # Unified CLI
│ ├── db.py # Database CLI
│ ├── dev.py # Dev tools CLI
│ ├── tests.py # Test runner CLI
│ └── ...
├── tests/ # Test suite
│ ├── unit/ # Unit tests
│ ├── integration/ # Integration tests
│ ├── e2e/ # End-to-end tests
│ └── fixtures/ # Test fixtures
├── docs/ # Documentation
└── pyproject.toml # Project configuration
Development Workflow
Daily Development
# Start services
uv run docker up
# Start bot (with hot-reload)
uv run tux start --debug
# Make changes → bot reloads automatically
# Run checks before committing
uv run dev all
uv run tests run
Database Changes
# Modify models in src/tux/database/models/
# Generate migration
uv run db new "add user preferences"
# Review migration file in src/tux/database/migrations/versions/
# Apply migration
uv run db push
# Test changes
Adding a Command
- Create file in appropriate module directory
- Inherit from
BaseCog
- Add
@commands.hybrid_command
decorator - Implement command logic
- Add docstring (numpy format)
- Write tests
- Update documentation
Testing
# Run all tests
uv run tests run
# Run specific category
uv run pytest -m unit
uv run pytest -m integration
# Run specific file
uv run pytest tests/unit/test_config_loaders.py
# Run with coverage report
uv run tests coverage
Code Style
Type Hints
All functions must have type hints:
def get_user_rank(user_id: int, guild_id: int) -> int | None:
"""Get user's permission rank."""
...
Docstrings
Use numpy-style docstrings:
def timeout_user(user: discord.Member, duration: int, reason: str) -> Case:
"""
Timeout a user for a specified duration.
Parameters
----------
user : discord.Member
The user to timeout.
duration : int
Timeout duration in seconds.
reason : str
Reason for the timeout.
Returns
-------
Case
The created moderation case.
Raises
------
discord.Forbidden
Bot lacks permissions.
ValueError
Invalid duration.
"""
...
Async Patterns
Use async for I/O operations:
# ✅ Good
async def get_user_data(user_id: int) -> UserData:
async with self.db.session() as session:
result = await session.execute(...)
return result.scalar_one()
# ❌ Bad - blocking call
def get_user_data(user_id: int) -> UserData:
session = self.db.session()
result = session.execute(...)
return result.scalar_one()
Controller Pattern
Use controllers for database access:
# ✅ Good - via controller
class MyCog(BaseCog):
def __init__(self, bot: Tux) -> None:
super().__init__(bot)
self.case_controller = self.db.case
async def create_case(self, ...):
case = await self.case_controller.insert_case(...)
# ❌ Bad - direct database access
class MyCog(BaseCog):
async def create_case(self, ...):
async with db.session() as session:
case = Case(...)
session.add(case)
Key Concepts
Cogs (Modules)
Cogs are modular command groups:
class MyCog(BaseCog):
"""My command group."""
def __init__(self, bot: Tux) -> None:
super().__init__(bot)
self.controller = self.db.my_controller
@commands.hybrid_command()
async def mycommand(self, ctx: commands.Context[Tux]) -> None:
"""Command description."""
...
Hybrid Commands
Commands work as both slash and prefix commands:
@commands.hybrid_command(name="ban", aliases=["b"])
@commands.guild_only()
@requires_command_permission()
async def ban(
self,
ctx: commands.Context[Tux],
user: discord.Member,
*,
reason: str = "No reason provided",
) -> None:
"""Ban a user from the server."""
...
Permission Ranks
Dynamic rank-based permissions (0-7):
@requires_command_permission() # Uses default rank for command
async def moderate_command(self, ctx: commands.Context[Tux]) -> None:
"""Moderation command."""
...
Tools & Commands
Development Commands
# Bot management
uv run tux start # Start bot
uv run tux start --debug # Debug mode
uv run tux version # Version info
# Code quality
uv run dev lint # Lint with Ruff
uv run dev format # Format with Ruff
uv run dev type-check # Type check with Basedpyright
uv run dev lint-docstring # Lint docstrings
uv run dev all # All checks
# Database
uv run db push # Apply migrations
uv run db new "message" # Create migration
uv run db status # Migration status
uv run db health # Health check
uv run db tables # List tables
# Testing
uv run tests run # All tests with coverage
uv run tests quick # Quick run without coverage
uv run tests coverage # Coverage report
# Docker
uv run docker up # Start services
uv run docker down # Stop services
uv run docker logs # View logs
# Documentation
uv run docs serve # Serve docs locally
uv run docs build # Build static docs
Getting Help
Documentation
- Architecture - System design
- Patterns - Best practices
- Guides - How-to tutorials
- Reference - API and configuration reference
Community
- Discord Server - Ask in #development
- GitHub Discussions - Technical discussions
- GitHub Issues - Bug reports
Resources
- Python 3.13 Docs - Python reference
- discord.py Docs - Discord.py guide
- SQLModel Docs - Database models
- Typer Docs - CLI framework
What's Next?
New Contributors
- Development Setup - Get environment ready
- Project Structure - Learn the layout
- First Contribution - Make your first PR
Understanding the System
- Architecture Overview - High-level design
- Bot Lifecycle - How Tux starts
- Core Systems - Key subsystems
Building Features
- Creating a Cog - Add command module
- Database Operations - Work with data
- UI Components - Build interfaces
Ready to contribute? Start with Development Setup!