tuimail/CLAUDE.md
2026-02-25 19:43:55 +01:00

5 KiB

CLAUDE.md

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

Project Overview

tui_mail is a TUI email client built with Rust and Ratatui. It supports standard IMAP servers (including Gmail) and ProtonMail (via an in-process bridge). It displays inbox messages with a split-pane interface: email list on top, message preview on the bottom.

User documentation: see USAGE.md for setup instructions, keyboard shortcuts, and configuration reference.

Build and Run Commands

# Build the project (standard IMAP)
cargo build

# Run the application
cargo run

# Build/run with ProtonMail support
cargo build --features proton
cargo run --features proton

# Build optimized release version
cargo build --release

# Check code without building
cargo check

# Format code
cargo fmt

# Run clippy linter
cargo clippy

Test Mail Server

A Docker-based IMAP mail server is available for testing:

# Start the mail server
docker-compose up -d

# Create a test user
docker exec -it mailserver setup email add test@example.com password123

# Stop the mail server
docker-compose down

Connection details: localhost:143 (IMAP) or localhost:993 (IMAPS). See MAIL_SERVER_SETUP.md for detailed usage including Gmail configuration.

Architecture

Main app (src/)

  • src/main.rs — Terminal setup/teardown, delegates to lib::main
  • src/lib.rs — Main event loop, UI rendering, worker thread coordination
  • src/inbox.rs — IMAP inbox operations (refresh, fetch older, fetch body, search, delete)
  • src/connect.rs — IMAP connection handling (plain TCP and TLS)
  • src/config.rs — Configuration loading from config.toml; provider selection (IMAP vs Proton)
  • src/credentials.rs — OS keychain access via the keyring crate
  • src/smtp.rs — Outgoing mail via SMTP using lettre
  • src/setup.rs — First-run interactive setup wizard
  • src/store.rs — Local encrypted body cache (AES-256-GCM, key stored in storage.key file)

ProtonMail bridge (proton-bridge/)

A separate workspace crate that runs as an in-process local IMAP/SMTP server.

  • proton-bridge/src/lib.rs — Entry point (start()); authenticates with ProtonMail API, binds local ports, spawns async tasks
  • proton-bridge/src/imap_server.rs — Local IMAP server (LOGIN, SELECT, FETCH, SEARCH, STORE, EXPUNGE)
  • proton-bridge/src/smtp_server.rs — Local SMTP server for outgoing mail
  • proton-bridge/src/api.rs — ProtonMail REST API client (message list, fetch, delete, send)
  • proton-bridge/src/auth.rs — SRP authentication and session management
  • proton-bridge/src/crypto.rs — PGP key derivation and message decryption/encryption
  • proton-bridge/src/store.rs — In-memory message metadata store for the bridge
  • proton-bridge/src/srp.rs — SRP-6a implementation matching ProtonMail's go-srp

Key patterns

  • IMAP operations run in a background worker thread communicating via mpsc channels, keeping the UI responsive
  • Emails are loaded in batches of 50, with lazy loading when scrolling past the end
  • A navigation debounce (150 ms) avoids firing body fetches on every keypress while scrolling
  • The worker checks wanted_body_seq (an AtomicU32) to drop stale body requests
  • Body cache: fetched message bodies are AES-256-GCM encrypted and written to {data_dir}/tuimail/bodies/{hash}.enc; cache key is the Message-ID header value
  • Credentials (IMAP/SMTP/Proton passwords) are stored in the OS keychain via keyring
  • The encryption key for the body cache is stored in {data_dir}/tuimail/storage.key (mode 0600) to avoid repeated keychain prompts
  • Tab switches focus between inbox list and preview pane
  • Selection is preserved across refreshes by matching IMAP sequence numbers

Key Dependencies

  • ratatui (0.30): TUI framework providing widgets, layouts, and rendering
  • crossterm (0.29): Cross-platform terminal manipulation (raw mode, events, alternate screen)
  • imap (2.4): IMAP protocol client
  • native-tls (0.2): TLS support for secure IMAP connections
  • lettre (0.11): SMTP client for sending mail
  • chrono (0.4): Date parsing and timezone conversion
  • mailparse (0.15): MIME email paursing for body extraction
  • aes-gcm (0.10): AES-256-GCM authenticated encryption for the body cache
  • keyring (3): OS keychain access (apple-native / linux-native / windows-native)
  • dirs (5): Platform-correct data directory paths

Development Notes

  • Uses Rust edition 2024
  • Terminal is set to raw mode to capture individual key presses
  • The alternate screen prevents terminal history pollution
  • config.toml contains credentials and is gitignored — see config.toml.example for the format
  • proton-bridge/bridge.toml contains ProtonMail credentials and is gitignored
  • The ProtonMail bridge imap_server SELECT response must not include UIDVALIDITY/UIDNEXT lines — imap-proto 0.10 (used by imap 2.4) does not fully consume them, causing tag desync on subsequent commands