v1.0.6
Silent-error audit: verified writes and honest reporting everywhere
v1.0.5 fixed archive/trash/move reporting success for messages that were never moved. This release is the result of auditing the whole CLI for that same class of bug — success reported without verifying the effect, and errors discarded on the way up. Every fix below landed test-first against a test server injected with the exact misbehavior (writes acknowledged but not applied, FETCH failing mid-stream, unstable SEARCH answers).
Fetch results are no longer trusted blindly
- A FETCH that fails mid-stream now surfaces as an error. Previously the error was swallowed and the partial message list was returned as if complete, so
extract,classify,summarize,digest,attachments,fetch-and-parse,unsubscribe, and reply composition could all silently operate on a truncated read. - Requested UIDs the server doesn't return no longer vanish.
extract,unsubscribe,attachments, andsummarizewith--uidnow emit a"type":"error"row for each UID that wasn't found (typo'd, already deleted, wrong mailbox) and count it in the summary'sfailed. Before, those UIDs simply produced no output at all.
Flag writes are verified like moves
mark-readandflagnow verify every STORE. Work happens in chunks of 250 UIDs; each chunk is confirmed withUID SEARCHto be in the requested flag state, stragglers are retried once, and anything still wrong gets a"type":"error"row, afailedcount in the summary, and a non-zero exit. Previously a single unverifiedUID STOREOK produced a success row for every input UID — including UIDs that don't exist.
Honest status reporting
cleanup-labelsno longer reports"status":"ok"for labels it failed to delete. A rejected DELETE now emits"status":"failed"with the full error envelope (including how many messages had already been moved) and is counted infailed. Before, the failure was only a stderr warning while the NDJSON stream claimed success.watchno longer emits phantom events. Each poll'sUID SEARCHis re-run until two consecutive answers agree, so one flaky answer (seen with Proton Bridge's virtual All Mail) can no longer diff into a burst of fakeexpunge/newevents.apply-labelssurfaces state-DB write failures instead of discarding them (a lostappliedrecord silently re-applies labels on the next run), andimport's APPEND error message now correctly labels the message index instead of calling it a UID.
Test infrastructure
imaptestgainedWithMailboxWrapperandWithUserWrapper, letting tests decorate the in-memory server's backend with real-world misbehavior (acknowledged-but-ignored writes, mid-stream FETCH failures, unstable SEARCH results, rejected DELETEs). All of the above fixes are locked in by regression tests built on them.
Full Changelog: v1.0.5...v1.0.6