| Age | Commit message (Collapse) | Author | Files | Lines |
|
Write to a temp file and rename, so the hook can never read a partial
file. Fields this version does not understand round-trip untouched,
which is what makes the format belong to neither tool.
|
|
Account tags must run before topic rules, which is what the stage field
is for. Disabled rules stay loaded so a UI can re-enable them.
|
|
One typo must not stop the other rules from tagging. A missing file and
a file that will not parse are tracked separately: the hook may run on
the first and must refuse on the second.
|
|
The rules that tag incoming mail live in a notmuch post-new hook as
hand-written shell. This is the first piece of moving them into a JSON
store that both this tool and qtmaildir read.
A rule carries no scope: the hook supplies tag:new, a dry run supplies
nothing. Unknown fields are kept per rule so the format belongs to
neither tool.
|
|
|
|
mailctl is a deliberately narrow CLI wrapper around notmuch, built so an
AI coding agent can search and organize local mail with no ability to
send. There is no SMTP, reply, or compose code path in the tool.
Safety model:
- reads run freely, mutations are gated
- tag changes are dry-run until --apply
- cross-account mutations need an explicit --all-accounts
- destructive tags need --apply and --confirm-destructive
- bulk mutations are capped by --max-messages
- every applied mutation is audited to a local log
Accounts are not in the source. They load from
~/.config/mailctl/accounts.json and are validated against both the
schema and the actual maildirs on disk at import time, so a typo cannot
produce a query matching nothing or a draft under the wrong identity.
Ships with mailsync.sh (a separate mbsync + notmuch new driver, meant
for cron) and mail-organize, a Claude Code skill that makes mailctl the
only sanctioned interface to the user's mail.
Licensed GPLv2-only.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|