diff options
| author | Elvis Claros Castro <elvis@claros.ar> | 2026-09-26 18:47:40 -0300 |
|---|---|---|
| committer | Elvis Claros Castro <elvis@claros.ar> | 2026-09-26 18:47:40 -0300 |
| commit | d9738b4be2add82ff955f061c79316b0dc91768f (patch) | |
| tree | e0f31bb9f72dff315fc475f9e9f30322b69602ff /README.md | |
| download | posta-main.tar.gz posta-main.zip | |
Diffstat (limited to 'README.md')
| -rw-r--r-- | README.md | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/README.md b/README.md new file mode 100644 index 0000000..e57ddb9 --- /dev/null +++ b/README.md @@ -0,0 +1,126 @@ +# posta + +> *[Leé esto en castellano](README.es.md)* + +**posta** is a tiny, generic IMAP/SMTP mail client for your terminal. One +binary, JSON output by default, and named accounts in a single TOML file — +so your mailbox is as scriptable as any other API. + +The name comes from the *postas*: the relay stations of the colonial mail +routes of South America. In Argentine slang, *la posta* also means +"the real thing". + +```console +$ posta list --unread --max 3 --format table + UID DATE FROM SUBJECT + 7121 ● Fri, 17 Jul 2026 17:0… "Example ISP" <billing@isp.ex… Your invoice is ready + 7120 ● Fri, 17 Jul 2026 15:0… Meetup <events@meetup.examp… 🚀 Registration open + 7119 ● Fri, 17 Jul 2026 10:1… "bank@example.com" Card notice + +$ posta search 'FROM bank UNSEEN' | jq .uids +[7119, 7118, 7117] +``` + +## Features + +- **Works with any provider** — plain IMAP/SMTP with STARTTLS (`imap://`, + `smtp://`) or implicit TLS (`imaps://`, `smtps://`). Your own server, + Gmail, Fastmail, anything. +- **Multiple accounts** — named accounts in one config file, switched with + `--account`, `$POSTA_ACCOUNT`, or a `default_account`. +- **Script-friendly** — every command prints pretty JSON (pipe it to `jq`), + with `--format table` for humans. +- **Secrets your way** — literal passwords (the file is checked for loose + permissions and posta warns you) or `password_cmd` to fetch them from + `pass`, a keyring, or any command. +- **Safe by default** — reading never marks messages as seen + (`BODY.PEEK` everywhere); opt in with `--mark-read` or `posta mark read`. +- **No config file needed** — everything can come from `POSTA_*` environment + variables, handy for CI and one-off scripts. + +## Install + +```sh +git clone https://git.all.ar/pub/posta.git +cd posta +cargo install --path . +``` + +## Configure + +`~/.config/posta/config.toml` (or `$POSTA_CONFIG`, or `--config FILE`): + +```toml +default_account = "personal" + +[accounts.personal] +email = "alice@example.com" +display_name = "Alice Example" +imap_url = "imap://alice@example.com@mail.example.com:143" +smtp_url = "smtp://alice@example.com@mail.example.com:587" +password_cmd = "pass show mail/personal" # or: password = "..." (chmod 600!) + +[accounts.work] +email = "alice@work.example" +imap_url = "imaps://alice@imap.work.example" # implicit TLS, port 993 +smtp_url = "smtps://alice@smtp.work.example" # implicit TLS, port 465 +password_cmd = "secret-tool lookup mail work" +sent_folder = "Sent Items" +trash_folder = "Deleted" +``` + +The user part of a URL may itself contain `@` +(`imap://alice@example.com@mail.example.com`); the host starts after the +*last* one. `imap_password[_cmd]` / `smtp_password[_cmd]` override the shared +password per protocol when they differ. + +Environment variables override any field of the selected account: +`POSTA_IMAP_URL`, `POSTA_SMTP_URL`, `POSTA_PASSWORD`, `POSTA_PASSWORD_CMD`, +`POSTA_IMAP_PASSWORD`, `POSTA_SMTP_PASSWORD`, `POSTA_EMAIL`, +`POSTA_DISPLAY_NAME`, `POSTA_SENT_FOLDER`, `POSTA_TRASH_FOLDER`, +plus `POSTA_ACCOUNT` and `POSTA_CONFIG`. + +## Use + +```sh +posta accounts # configured accounts +posta status # message/unread counts +posta folders # list mailboxes +posta list --unread # newest first +posta list --query 'FROM bank SINCE 1-Jul-2026' +posta get 7119 # headers + text body, as JSON +posta get 7119 --html # prefer the HTML part +posta get 7119 --raw > msg.eml # raw RFC 822 source +posta send --to bob@example.com --subject 'Hi' --body 'Hello!' +git log | posta send --to bob@example.com --subject 'Changelog' +posta mark read 7119 7120 # also: unread, flagged, unflagged +posta move 7119 --to Archives +posta delete 7119 # moves to the trash folder +posta search 'FROM bank UNSEEN' # raw IMAP SEARCH, prints UIDs +``` + +Global flags: `--account/-a NAME`, `--config FILE`, +`--format json|table`, and `--folder` on folder-scoped commands. + +Every command opens a fresh session and logs out; there is no daemon, +cache, or local state. + +## Notes + +- `send` appends a copy to the sent folder over IMAP (skip with + `--no-record`). +- `move`/`delete` use `UID MOVE` when the server supports it, falling back + to `COPY` + `\Deleted` + `EXPUNGE`. +- TLS is always required; plain-text connections are not supported. + +## Development + +```sh +cargo test # unit + CLI integration tests, no server needed +cargo clippy --all-targets -- -D warnings +cargo fmt --check +``` + +## License + +[MIT](LICENSE) |