# 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`](USAGE.md) for setup instructions, keyboard shortcuts, and configuration reference. ## Build and Run Commands ```bash # 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: ```bash # 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