Agent-First Mail v0.2: One Push, All or Nothing
v0.2 tightens the push boundary into a single all-or-nothing operation, adds a draft preview, unifies message restore and lifecycle-agnostic case reads, lets you archive a message directly, and lets a workspace live in a subdirectory.
afmail v0.1 drew one line: your agent reads and works entirely in local files, and the real mailbox only changes when you say --confirm. v0.2 keeps that line and makes the work behind it simpler — starting with the boundary itself.
One push, all or nothing
In v0.1 the push boundary was real but split across verbs — you previewed and confirmed archives, sends, and the rest as separate pushes. That left room for a half-applied state (some effects pushed, others still queued) and made the agent decide which push, in what order.
v0.2 collapses it into a single operation. Everything queued in .afmail/push/ applies together, or nothing does:
afmail push list # inspect everything queued
afmail push # preview the entire pending queue (dry run)
afmail push --confirm # apply the whole queue to the real mailbox, all or nothing
The boundary is now exactly one decision — is the whole queue ready to hit the real mailbox? — with no partial state to reason about. The agent’s job shrinks to “queue effects locally; ask the human to push once.”
Read before you send
Drafts are still worked inside a case, with a tighter loop: build a reply, change it, validate it, and now read the full rendered draft before it ever leaves your machine.
afmail case draft reply c20260617001 message_inbox_88213_4
afmail case draft change c20260617001 reply-message_inbox_88213_4.md --body "Thanks — checking now."
afmail case draft validate c20260617001 reply-message_inbox_88213_4.md
afmail case draft show c20260617001 reply-message_inbox_88213_4.md # exactly what will be sent
Sending is still a queued effect — nothing goes out until the one push above.
Restore, read, and archive without ceremony
v0.2 evens out the case and message lifecycle so reads and moves don’t depend on where a thing currently sits:
- One restore path. Pull a message back to triage from spam, trash, or the direct archive with a single
afmail message restore <id>— unified across lifecycles instead of a different command per origin. - Lifecycle-agnostic case reads. Reading a case works the same whether it’s open or archived; you don’t have to know its current state to look at it.
- Archive a message directly. Send a message straight into the archive when it doesn’t need a case at all.
A workspace can live in a subdirectory
Like git finding its repo from a nested directory, afmail now resolves its workspace by walking up the tree — so a mailbox workspace can sit inside a larger project, and commands work from any subdirectory of it.
Install
brew install agentfirstkit/tap/afmail # macOS / Linux
scoop bucket add agentfirstkit https://github.com/agentfirstkit/scoop-bucket
scoop install afmail # Windows
cargo install agent-first-mail # any platform
After installing, run afmail skill install so your agent reloads afmail’s behavior rules.