# Contributing Thank you for considering a contribution. Before you start, **read [`AGENTS.md`](AGENTS.md)** — it codifies the non-negotiable rules every change (human or AI) must respect. ## Quick path 1. Fork, branch off `main` (`feat/` or `fix/`). 2. Run the same gates CI runs before pushing: ```sh cargo fmt --all -- --check cargo clippy --all-targets --all-features -- -D warnings cargo test --all-features cargo deny check # cargo install cargo-deny ``` 3. Use [Conventional Commits](https://www.conventionalcommits.org/) (`feat:`, `fix:`, `docs:`, `refactor:`, `test:`, `ci:`, `chore:`, `perf:`). One concern per commit, one concern per PR. 4. Update `CHANGELOG.md` under `## [Unreleased]`. 5. Open a PR; CI must be green before review. ## What the reviewer will check The Definition of Done is in [`AGENTS.md §3`](AGENTS.md). In short: - Builds clean on Linux / macOS / Windows. - `fmt`, `clippy -D warnings`, `test`, `cargo deny` all pass. - If user-facing: screenshots **in both dark and light mode** attached to the PR description, plus a description of the keyboard path through any new UI. - If protocol-affecting: a real-world server reply added as a fixture to the `#[cfg(test)]` module in `src/diagnostics.rs`. - No `unwrap()` / `expect()` in non-test code without a `// SAFETY:` comment justifying it. - No new dependency added without verifying it is the latest stable on crates.io (`cargo search ` or `curl -s https://crates.io/api/v1/crates/`) and that `cargo deny check` accepts its licence. ## Translations The tool ships translations for 36 languages (11 non-Latin scripts) under `locales/.toml`. The set is: * `en` — base, hand-maintained by the maintainer. Every key the code looks up MUST exist here. * `nl` — native-quality (the maintainer is a Dutch speaker). * `ar`, `bg`, `bn`, `cs`, `da`, `de`, `el`, `es`, `fa`, `fi`, `fr`, `he`, `hi`, `hr`, `hu`, `id`, `it`, `ja`, `ko`, `no`, `pl`, `pt`, `ro`, `ru`, `sk`, `sr`, `sv`, `ta`, `te`, `th`, `tr`, `uk`, `vi`, `zh` — **machine-translated**, native review welcome. Each file's `locale.status_note` says so in that file's own language. The non-Latin scripts (CJK `zh`/`ja`/`ko`, Arabic `ar`/`fa`, Hebrew `he`, Indic `hi`/`bn`/`ta`/`te`, Thai `th`) rely on a system-installed font discovered at startup — see the README *Languages* table. The authoritative count lives in `src/i18n.rs` (`LOCALES`); keep this list and the README *Languages* table in sync when you add one. ### Reviewing a machine-translated file 1. Pick a file from the list above whose `status_note` is non-empty. 2. Read it side-by-side with `locales/en.toml` (same key order). 3. Focus on: * Natural phrasing (don't translate word-for-word from English). * Consistency with how the language's *own* tech press talks about email — Microsoft and Google ship localised admin panels; mirror their terminology where it makes sense. * Keep technical tokens in English: `SMTP AUTH`, `STARTTLS`, `XOAUTH2`, `MAIL FROM`, `App Password`, `Conditional Access`. That matches what users see in M365 admin and helps IT triage. 4. Open a PR that **also clears `locale.status_note`** if you can attest to native-quality. Mention which strings you reviewed in the PR body. ### Adding a brand-new language 1. Copy `locales/en.toml` to `locales/.toml`. 2. Translate the right-hand sides; keep the section structure and key names identical to en.toml. 3. Add an `include_str!` + an entry to `LOCALES` in `src/i18n.rs` (alphabetical-ish by code, doesn't matter for correctness). 4. Set a sensible `locale.native_name` (in your language) and `locale.english_name`. Leave `locale.status_note` saying "machine-translated, native review welcome" if you used an LLM, or empty if you can attest to native quality. 5. `cargo build --all-features && cargo test --all-features` — the lazy init panics on invalid TOML, so the build is the first check. 6. Open a PR. The **language selector** in the GUI (Advanced tab) only ever shows the user's OS locale + English. Adding more locales does NOT clutter the UI for users who don't speak those languages — they only see theirs. ## Reporting a security issue Please do **not** open a public issue. Email the maintainer using the address in the `Cargo.toml` `repository` page on crates.io, or open a private security advisory on GitHub.