Releases: ajsap/mailferry
Release list
MailFerry v2.1.0 — IMAP Migration & Sync
MailFerry v2.1.0 — Feature Release
High-Performance Native IMAP Migration Engine.
OAuth 2.0 / modern authentication with a first-class mailferry auth
lifecycle, IMAP MULTIAPPEND batching, evidence-based server
identification, and a substantially polished operator experience.
Migration correctness, the statistics identity, terminal sanitisation
and SIGHUP handling are unchanged and still test-enforced. Existing
password migrations and existing mailferry.db / mailferry.toml
files continue to work untouched.
Added
- OAuth 2.0 / modern authentication (SASL XOAUTH2, and
OAUTHBEARER for standards-compliant servers). First-class
Microsoft 365 / Exchange Online and Google Workspace / Gmail,
plus a generic provider. Source and destination authenticate
independently — password↔OAuth, or two different providers, in one
run. The canonical 10-column CSV is unchanged: an endpoint opts in
with anoauth:<profile>password cell. - Three authentication models, kept deliberately distinct:
delegated(one user's own mailbox),application(Microsoft 365
app-only,IMAP.AccessAsApp— one tenant app → many mailboxes) and
service_account(Google domain-wide delegation → many mailboxes).
An administrative profile mints its tenant token once and shares
it across every mailbox and worker in the run. mailferry authcommand family —add/list/show/
test/refresh/remove. Browser loopback + PKCE (RFC 8252),
headless device code (RFC 8628) for Microsoft, and manual redirect
capture for Google.--usernames the mailbox you mean: it is sent
as the OIDClogin_hintand the account that actually signed in is
verified afterwards — on a mismatch nothing is saved.
auth testis a staged diagnostic: token → TLS → SASL →LIST,
then the server's full capability list and a plain-language verdict.- Secrets are never stored in configuration. Client secrets,
refresh tokens and service-account keys are held as external
references (env:/file:/keychain:/dpapi:/cmd:) and
resolved at run time — never written tomailferry.toml, the State
Database, logs, reports or traces. Storage uses the OS-native secure
store: macOS login keychain, Linux Secret Service, Windows DPAPI
(current-user scope), with a documented0600fallback. - IMAP MULTIAPPEND (RFC 3502) — several messages uploaded in one
APPEND command when the destination advertises it. On by default
with automatic batch sizing (--multiappend auto|off,
--multiappend-batch-size auto|N). On the built-in benchmark, 400
messages went from 400 append commands to 50. It is an
optimisation and nothing more: bodies still stream (memory stays
proportional to a chunk, not a batch), an unsupported destination
transparently uses one append per message, and every message keeps
its own durable state, destination UID, flags and INTERNALDATE.
Batch size is not concurrency. - Evidence-based server identification. MailFerry reports what the
server positively says about itself — OAuth provider, RFC 2971 IMAP
ID, vendor-private CAPABILITY, greeting banner, TLS certificate —
and displaysUnknownwhen the evidence is insufficient. There is
no hostname table, provider list or fingerprint database, and the
identifier is never given the hostname, so guessing from a domain is
structurally impossible. - Adaptive Dashboard. A Source / Destination panel reporting host,
server, auth, negotiated TLS and that connection's current speed;
for heterogeneous (MSP) runs it aggregates by identified platform
rather than showing one mailbox as if it spoke for the run. Plus a
live F3 mailbox inspector, one unified quit confirmation (Esc
never exits), a Runtime that freezes on completion, and a single
authoritative completion timestamp. - Interactive F9 Settings and an expanded typed configuration
surface, saved atomically tomailferry.tomlwith comments
preserved. - Documentation:
docs/OAUTH.md(the authentication model),
docs/OAUTH-SETUP.md(step-by-step Microsoft Entra and Google Cloud
configuration, verified against the official provider documentation
on 01/08/2026) anddocs/MULTIAPPEND.md.
Fixed
- Cancelling a run no longer abandons appends already on the wire.
A stopped transfer settles the commands it has already sent, so each
message's outcome is recorded rather than left ambiguous — removing
a path where a resume could copy a message twice. - A starting migration could fail if something was watching it.
SQLite does not applybusy_timeouttoPRAGMA journal_mode, so a
read-only observer (mailferry attach) opening the file during the
initial WAL switch could abort the run withdatabase is locked.
Schema initialisation now retries on lock contention. keychain:secret references are now resolvable on Linux (Secret
Service viasecret-tool); previously a reference could be stored
that only macOS could read back.
Verification
gofmt, go vet (darwin/linux/windows), the full unit and end-to-end
suites and the race detector all pass. Two clean builds of this commit
are byte-identical.
Known limitations
- macOS binaries are not yet Apple-notarised — Gatekeeper may block
the first launch and a one-time Open Anyway is expected. See
docs/INSTALLATION-MACOS.md;
never disable Gatekeeper. The signing pipeline is documented in
docs/RELEASING-MACOS.mdand planned for a future release. - Terminal/PTY regression tests are Linux-only and were not executed on
the macOS build host. - Real-provider verification to date covers the Microsoft 365
delegated browser flow. The device-code, app-only, Google
delegated and Google domain-wide-delegation paths, Windows DPAPI
storage and Linux Secret Service are implemented and unit-tested
against mocked providers, but have not yet been exercised against
live tenants.
Verifying your download
shasum -a 256 -c SHA256SUMS # macOS
sha256sum -c SHA256SUMS # LinuxFull changelog:
https://github.com/ajsap/mailferry/blob/main/CHANGELOG.md
MailFerry v2.0.3 — IMAP Migration & Sync
MailFerry v2.0.3 — Patch Release
High-Performance Native IMAP Migration Engine.
The polished Results experience: an interactive migration now finishes
on a native Results screen inside the TUI — verdict, statistics,
per-mailbox outcomes and a concise "Needs attention" summary — instead
of dropping to a raw text dump. Quitting returns a clean shell with a
short confirmation, never a duplicate report.
Added
- Results TUI with distinct verdicts: MIGRATION COMPLETE ·
COMPLETED WITH WARNINGS · NOTHING NEW TO COPY · DRY RUN. Run and
Messages panels, problems-first mailbox table, contextual panels
(adopted, prior-confirmed, dry-run plan, date range, portable mode),
Enter/F-keys/S/Q navigation. F6 doubles as the Failed Messages
browser after completion. Headless/non-TTY output remains structured
text — never a forced TUI. - Counter completeness:
synced = copied + adopted + prior-confirmed + plannedis now a tested invariant of the real
engine; new contextual lines and results.csv columns (msgs_prior,
msgs_planned) make idempotent reruns and dry runs self-explanatory. - RFC 2047 subject decoding in every interactive failed-message
surface, with clean ellipsis truncation and safe fallback. - Restored v1.x summary details: Run ID, mailbox timings, retries,
stalls, stale/remote/cancelled reporting, warned-mailbox breakdown.
Fixed
- Percentages never overstate completion: 100% appears only when
every message is genuinely accounted for (26,081 of 26,089 renders
99.9%, not 100%); progress also never rounds down to 0%.
No engine, protocol, state or data-handling changes. Existing
mailferry.db and mailferry.toml remain fully compatible. The v2.0.2
terminal sanitisation fix (confirmed on the affected macOS arm64
system) is preserved and re-verified in this release's gate.
macOS note: binaries remain unsigned/not notarised — Gatekeeper asks
for a one-time "Open Anyway" approval
(guide).
Verify downloads: shasum -a 256 -c SHA256SUMS
Issues: https://github.com/ajsap/mailferry/issues
Author: Andy Saputra andy@saputra.org · Licence: GNU AGPL v3.0
MailFerry v2.0.2 — IMAP Migration & Sync
Superseded release
This version contains known issues that have been resolved in v2.0.3. Users should upgrade to the latest stable release. This release is retained for historical and reproducibility purposes.
MailFerry v2.0.2 — Patch Release
High-Performance Native IMAP Migration Engine.
Fixes the "stair-step" terminal output defect at its actual root cause
— reproduced on real macOS arm64 with v2.0.0/v2.0.1, and this fix
verified on that same real environment before release.
Fixed
- Stair-step output: MailFerry writes ordinary
"\n"line output
and relies on the terminal’s output post-processing (OPOST/ONLCR)
for carriage returns. A terminal left in a raw-ish state by a
previously crashed full-screen program renders every subsequent run
as a stair-step from the very first banner line — and v2.0.1’s
capture/restore preserved that inherited state instead of healing
it. MailFerry now repairs thestty sanenewline flag subset before
its first byte of output (only when actually broken, with a one-line
notice), and every capture thereafter snapshots the sane state — no
exit path can hand a broken terminal back to the shell. Already-sane
terminals are untouched; pipes/non-TTY output are never modified;
TUI, headless and SSH/tmux/screen behaviour is unchanged.
Added
mailferry term-diag— supported terminal self-test (no servers, no
credentials, no data).MAILFERRY_TERM_DIAG=FILE— per-stage termios flag logging for field
diagnosis (flags only — never mailbox data).- PTY-level regression tests asserting that every rendered line begins
at column 1 on clean and pre-broken terminals, and that a broken
terminal ends healed.
No engine, protocol, state or data-handling changes: migration
behaviour is identical to v2.0.0/v2.0.1. Existing mailferry.db and
mailferry.toml are fully compatible.
macOS note: binaries remain unsigned/not notarised — Gatekeeper asks
for a one-time "Open Anyway" approval
(guide).
Verify downloads: shasum -a 256 -c SHA256SUMS
Issues: https://github.com/ajsap/mailferry/issues
Author: Andy Saputra andy@saputra.org · Licence: GNU AGPL v3.0
MailFerry v2.0.1 — IMAP Migration & Sync
Superseded release
This version contains known issues that have been resolved in v2.0.3. Users should upgrade to the latest stable release. This release is retained for historical and reproducibility purposes.
MailFerry v2.0.1 — Patch Release
High-Performance Native IMAP Migration Engine.
Patch release on top of v2.0.0: the terminal-state restoration
guarantee.
Fixed
- Terminal restoration is now a provable invariant. MailFerry
captures the exact terminal state before the TUI starts (both the
migration dashboard andmailferry attach) and restores it verbatim
on every return path — including TUI startup failures and hard-stop
timeouts — with idempotent defensive resets (primary screen, visible
cursor, mouse reporting off, attributes reset). A PTY-level termios
matrix across nine exit paths (completion, instant re-run, graceful
Ctrl+C, double Ctrl+C, SIGTERM, SIGHUP, --dry-run, attach quit and
attach Ctrl+C) verifies that no path can leave the shell with the
"stair-step" newline artefact, raw input, or hidden echo.
No engine, protocol, state or data-handling changes: migration
behaviour is byte-identical to v2.0.0. Existing mailferry.db and
mailferry.toml are fully compatible.
macOS note: binaries remain unsigned/not notarised for now — Gatekeeper
will ask for a one-time "Open Anyway" approval
(guide).
Verify downloads: shasum -a 256 -c SHA256SUMS
Issues: https://github.com/ajsap/mailferry/issues
Author: Andy Saputra andy@saputra.org · Licence: GNU AGPL v3.0
MailFerry v2.0.0 — IMAP Migration & Sync
Superseded release
This version contains known issues that have been resolved in v2.0.3. Users should upgrade to the latest stable release. This release is retained for historical and reproducibility purposes.
MailFerry v2.0.0 — Stable Release
High-Performance Native IMAP Migration Engine.
The complete native Go rewrite of MailFerry, published as the stable
v2.0.0 after three release candidates and a full internal release gate:
data integrity, idempotency, multi-process coordination, dry-run
zero-mutation and dedup-safety verification all passed on the exact
source commit this release was built from.
One static binary per platform — no Python, no imapsync, no runtime
dependencies. MailFerry never expunges or deletes mail during
migration, in any mode.
Everything in v2.0.0
- Native IMAP engine — streaming FETCH→APPEND, LITERAL+,
STARTTLS/SSL, COMPRESS=DEFLATE, watchdogs, per-host budgets - Bubble Tea TUI + headless parity — live dashboard, ten F1–F10
views, automatic TTY detection,--no-tui, graceful shutdown - SQLite State Database — per-message commits, resumable,
duplicate-free adoption, ack-lost APPEND reconciliation,
native per-OS locations, lazy creation,mailferry.dbcanonical - Self-healing — stall detection, Recovery Mode, progressive
isolation, persistent Failed Message Registry, COMPLETED WITH
WARNINGS - Multi-instance — shared State Database, atomic claiming, leases,
heartbeats, automatic takeover, clear "Mailbox already active"
reporting (verified with real OS processes, incl. kill-9 reclaim) - Whole-file CSV validation — every error in one pass; canonical
src*/dst*columns; obsolete v1 headers rejected with a rename hint --dry-run— mutating IMAP commands blocked inside the client
before any byte reaches the wire (proven: zero mutations observed)- ISO 8601 date-range migration —
--from/--to, inclusive,
INTERNALDATE-authoritative, persisted window, deterministic resume mailferry dedup— analysis by default;--executeis
reversible (quarantine move /\Deletedflag, EXPUNGE never
issued); strong multi-factor matching; interruption-safemailferry attach— read-only live monitor of running
migrations; never disturbs workers--portable— self-contained layout beside the executable- Zero-side-effect informational commands · restrictive 0700/0600
permissions · credential redaction everywhere
Notes
- macOS: binaries are not yet Developer-ID signed or notarised —
Gatekeeper will ask for a one-time "Open Anyway" approval
(guide).
This does not indicate malware; signing/notarisation is planned. - Linux amd64 was runtime-tested end-to-end; the other five targets are
cross-compiled from the same verified source (macOS arm64 previously
runtime-tested by the maintainer during the RC programme). - Upgrading from rc.2/rc.3: existing mailferry.db and mailferry.toml
are fully compatible — schema changes are additive; nothing to
delete or migrate.
Verify downloads: shasum -a 256 -c SHA256SUMS
Issues: https://github.com/ajsap/mailferry/issues
Author: Andy Saputra andy@saputra.org · Licence: GNU AGPL v3.0
MailFerry v2.0.0-rc.3 — IMAP Migration & Sync
MailFerry v2.0.0-rc.3 — Release Candidate
High-Performance Native IMAP Migration Engine.
This is the final planned Release Candidate of MailFerry v2.0.0 —
the complete rewrite of MailFerry from Python to Go. It exists to gather
real-world testing before v2.0.0 is declared production-ready.
This is a pre-release, not the latest stable version. v1.0.0
(Python) remains the last stable release. Test carefully and keep your
source mailboxes until you have verified results. MailFerry never
expunges or deletes mail on either server, in any mode.
Highlights of the Go rewrite
- Native standalone binaries — one static executable per platform;
no Python, no Perl, no imapsync, no external runtime. macOS
(Apple Silicon + Intel), Linux (amd64 + arm64), Windows (amd64 + arm64). - Native IMAP engine — pipelined streaming FETCH→APPEND with bounded
memory, LITERAL+, STARTTLS/SSL, COMPRESS=DEFLATE, watchdogs, per-host
connection budgets. - Bubble Tea + Lip Gloss TUI — live dashboard plus nine more views on
F1–F10 (digit aliases for SSH/tmux), detail popups, search, follow-mode
logs, pause/retry controls, graceful-shutdown dialog; automatic TTY
detection with a--no-tuiheadless mode driving the same engine. - SQLite state management — per-message commit protocol (pure Go, no
CGO); resumable and duplicate-free; ack-lost APPEND reconciliation. - Self-healing — stall detection, connection recovery, Recovery Mode
with progressive failed-message isolation, persistent Failed Message
Registry, COMPLETED WITH WARNINGS semantics. - Multi-instance clustering — shared State Database, atomic mailbox
claiming, automatic takeover from offline workers.
New in rc.3 — multi-instance hardening
- Concurrent multi-process operation is first-class: several
MailFerry processes safely share the canonicalmailferry.db
(unique run/worker identities, WAL, busy timeouts, atomic claiming,
leases, heartbeats). Held mailboxes are reported plainly —
Mailbox already active: … owned by worker … (run …)— never
processed twice, and taken over automatically when released or when
their owner dies (verified with real OS-process tests, including
kill‑9 reclaim and exactly-once delivery under contention). - No silent exits: runs that copy nothing say why; headless runs
stream coordination events; every exit path restores the terminal
(second-Ctrl+C and engine-panic paths fixed). - Canonical src/dst CSV format —
srchost,…,dstpassword; the v1
old*/new*header is rejected with a clear rename hint.
Carried from rc.2
- Native OS-standard application paths, resolved centrally and
created lazily:
macOS~/Library/Application Support/MailFerry/· Linux XDG
($XDG_CONFIG_HOME,$XDG_STATE_HOME,$XDG_CACHE_HOME) · Windows
%APPDATA%/%LOCALAPPDATA%. Precedence: CLI flags → mailferry.toml →
native default. mailferry.dbis the canonical per-user State Database (replacing
the./migration.dbworking-directory default). An old development
./migration.dbis detected and reported with explicit choices —
never silently adopted or duplicated.- Zero-side-effect informational commands:
--help,version,
about,changelog,roadmap,config pathscreate nothing — no
configuration, directories, logs or database. Configuration is
generated on the first operational run or explicitly via
mailferry config(regression-tested). - Correct canonical slogan: High-Performance Native IMAP Migration
Engine — enforced by an automated identity test. - Restrictive file permissions (0700 directories, 0600 config/DB/logs
where the platform supports POSIX permissions). - Go-native documentation: rewritten README and CONTRIBUTING, new
end-user macOS installation guide
(docs/INSTALLATION-MACOS.md).
Known limitations (please test and report)
- Not implemented yet (planned for final v2.0.0): deduplication
mode, date-range migration (--from/--to),mailferry attach,
--portablemode. - macOS binaries are not Developer-ID signed and not notarised —
Gatekeeper will ask for a one-time Open Anyway approval on
downloaded binaries. Expected for this RC; see the
macOS installation guide.
Never disable Gatekeeper. - Clustering and COMPRESS=DEFLATE are automated-suite-tested and still
under real-world validation (--compress offis the conservative
fallback while diagnosing). - Windows console support is cross-compiled with limited interactive
testing.
Install & verify
Download the binary for your platform, verify its checksum against
SHA256SUMS, make it executable, and run mailferry version — it must
report MailFerry v2.0.0-rc.3.
shasum -a 256 -c SHA256SUMS # sha256sum -c on LinuxIssues and feedback: https://github.com/ajsap/mailferry/issues
Author: Andy Saputra andy@saputra.org · Licence: GNU AGPL v3.0
MailFerry v2.0.0-rc.2 — IMAP Migration & Sync
MailFerry v2.0.0-rc.2 — Release Candidate
High-Performance Native IMAP Migration Engine.
This is the first published Release Candidate of MailFerry v2.0.0 —
the complete rewrite of MailFerry from Python to Go. It exists to gather
real-world testing before v2.0.0 is declared production-ready. (An
earlier internal candidate, rc.1, was superseded by this build before
public release; its content is documented in the changelog.)
This is a pre-release, not the latest stable version. v1.0.0
(Python) remains the last stable release. Test carefully and keep your
source mailboxes until you have verified results. MailFerry never
expunges or deletes mail on either server, in any mode.
Highlights of the Go rewrite
- Native standalone binaries — one static executable per platform;
no Python, no Perl, no imapsync, no external runtime. macOS
(Apple Silicon + Intel), Linux (amd64 + arm64), Windows (amd64 + arm64). - Native IMAP engine — pipelined streaming FETCH→APPEND with bounded
memory, LITERAL+, STARTTLS/SSL, COMPRESS=DEFLATE, watchdogs, per-host
connection budgets. - Bubble Tea + Lip Gloss TUI — live dashboard plus nine more views on
F1–F10 (digit aliases for SSH/tmux), detail popups, search, follow-mode
logs, pause/retry controls, graceful-shutdown dialog; automatic TTY
detection with a--no-tuiheadless mode driving the same engine. - SQLite state management — per-message commit protocol (pure Go, no
CGO); resumable and duplicate-free; ack-lost APPEND reconciliation. - Self-healing — stall detection, connection recovery, Recovery Mode
with progressive failed-message isolation, persistent Failed Message
Registry, COMPLETED WITH WARNINGS semantics. - Multi-instance clustering — shared State Database, atomic mailbox
claiming, automatic takeover from offline workers.
New since the rc.1 build
- Native OS-standard application paths, resolved centrally and
created lazily:
macOS~/Library/Application Support/MailFerry/· Linux XDG
($XDG_CONFIG_HOME,$XDG_STATE_HOME,$XDG_CACHE_HOME) · Windows
%APPDATA%/%LOCALAPPDATA%. Precedence: CLI flags → mailferry.toml →
native default. mailferry.dbis the canonical per-user State Database (replacing
the./migration.dbworking-directory default). An old development
./migration.dbis detected and reported with explicit choices —
never silently adopted or duplicated.- Zero-side-effect informational commands:
--help,version,
about,changelog,roadmap,config pathscreate nothing — no
configuration, directories, logs or database. Configuration is
generated on the first operational run or explicitly via
mailferry config(regression-tested). - Correct canonical slogan: High-Performance Native IMAP Migration
Engine — enforced by an automated identity test. - Restrictive file permissions (0700 directories, 0600 config/DB/logs
where the platform supports POSIX permissions). - Go-native documentation: rewritten README and CONTRIBUTING, new
end-user macOS installation guide
(docs/INSTALLATION-MACOS.md).
Known limitations (please test and report)
- Not implemented yet (planned for final v2.0.0): deduplication
mode, date-range migration (--from/--to),mailferry attach,
--portablemode. - macOS binaries are not Developer-ID signed and not notarised —
Gatekeeper will ask for a one-time Open Anyway approval on
downloaded binaries. Expected for this RC; see the
macOS installation guide.
Never disable Gatekeeper. - Clustering and COMPRESS=DEFLATE are automated-suite-tested and still
under real-world validation (--compress offis the conservative
fallback while diagnosing). - Windows console support is cross-compiled with limited interactive
testing.
Install & verify
Download the binary for your platform, verify its checksum against
SHA256SUMS, make it executable, and run mailferry version — it must
report MailFerry v2.0.0-rc.2.
shasum -a 256 -c SHA256SUMS # sha256sum -c on LinuxIssues and feedback: https://github.com/ajsap/mailferry/issues
Author: Andy Saputra andy@saputra.org · Licence: GNU AGPL v3.0
MailFerry v1.0.0 — IMAP Migration & Sync
First stable release of MailFerry — High-Performance Native IMAP Migration
Engine.
Added
- Native asyncio IMAP protocol core: pipelined commands, streamed message bodies
(constant memory), non-synchronising literals (LITERAL+), wire
compression (COMPRESS=DEFLATE), STARTTLS and implicit TLS with
certificate verification on by default, inactivity and byte-progress
watchdogs, capability-driven optimisation with--baselinefallback. - Migration, sync and backup in one command: fresh migration, fingerprint
adoption of destinations pre-synced by other tools (duplicate-free,
even after State Database loss), and incremental top-up runs; deletions
are never propagated; optional--sync-flagsre-applies flag changes. - Per-message State Database (SQLite WAL): planned/inflight/done/skipped
states, source→destination UID mapping viaAPPENDUID, UIDVALIDITY-aware
re-verification, crash-window reconciliation, mailbox leases,
import-statemigration from the legacy wrapper,compactmaintenance
command. - Scheduler: worker pools, per-host connection budgets, parallel folder
pipelines inside large mailboxes, throttle-aware backoff; authentication
failures are never auto-retried. - Folder planner: NAMESPACE/delimiter translation, special-use role mapping
(localisation-proof), Gmail virtual-folder policy, mUTF-7 Unicode names,
include/exclude globs, explicit--mapfile. - Live Dashboard: alternate-screen differential renderer, two-line MailFerry
banner, global progress (messages/data %, throughput, ETA, duplicates
prevented, reconnects, retries), per-mailbox operation verbs and detailed
Source Server / Destination Server panels; non-TTY status lines;
--json-progresssnapshots. - Reporting: session log, per-mailbox logs,
results.csv, end-of-run
summary, optional NDJSON event logs,--traceprotocol logging with
credential redaction. - CLI:
run,check(write-nothing preflight),init,import-state,
capabilities,verify,compact;--version,--about,--help;
exit codes 0/1/130/141. - Tooling: single-source version and identity (
mailferry/__init__.py),
release builder with branding/header/changelog/license validation and
SHA-256 checksums, AGPL source-header applier, end-to-end fake-IMAP test
suite (34 checks). - Packaging: standalone
mailferry.pyz(zipapp), source archive, wheel.