Update CLAUDE.md with current architecture and implementation details
Add ProtonMail bridge, body cache, credentials, SMTP, setup wizard, and key development notes including the UIDVALIDITY/UIDNEXT imap-proto quirk. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
e858236f51
commit
45f8355a9e
1 changed files with 41 additions and 6 deletions
47
CLAUDE.md
47
CLAUDE.md
|
|
@ -4,19 +4,23 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
|
|||
|
||||
## Project Overview
|
||||
|
||||
**tui_mail** is a TUI email client built with Rust and Ratatui. It connects to IMAP servers (including Gmail) and displays inbox messages with a split-pane interface: email list on top, message preview on the bottom.
|
||||
**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
|
||||
# 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
|
||||
|
||||
|
|
@ -49,26 +53,55 @@ Connection details: localhost:143 (IMAP) or localhost:993 (IMAPS). See `MAIL_SER
|
|||
|
||||
## 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)
|
||||
- **`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`
|
||||
- **`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
|
||||
- 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 (Gmail)
|
||||
- **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 parsing 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
|
||||
|
||||
|
|
@ -76,3 +109,5 @@ Connection details: localhost:143 (IMAP) or localhost:993 (IMAPS). See `MAIL_SER
|
|||
- 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
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue