Skip to content

fix: repair build after #14/#15/#16 and guard COPYUID check - #17

Merged
bscott merged 1 commit into
masterfrom
fix/post-merge-integration
Aug 8, 2026
Merged

fix: repair build after #14/#15/#16 and guard COPYUID check#17
bscott merged 1 commit into
masterfrom
fix/post-merge-integration

Conversation

@bscott

@bscott bscott commented Aug 8, 2026

Copy link
Copy Markdown
Owner

Follow-up to merging #14, #15, and #16. Three items, all flagged during review of those PRs.

1. Master doesn't build (blocking)

#15 and #16 merge cleanly in git but collide semantically. #15's client_affected_test.go calls the pre-#16 ListMessages(mailbox, limit, offset, unreadOnly); #16 changed it to take ListOptions. Ported the three call sites.

2. COPYUID check needs a capability guard

The no-match detection in #15 reads copyData.SourceUIDs/DestUIDs. Two problems:

  • CopyCommand.Wait() returns &cmd.data unconditionally in go-imap v2, so copyData != nil is always true — dead code.
  • COPYUID is only emitted by servers advertising UIDPLUS (folded into IMAP4rev2). Without it, an empty pair means the server never reported, not nothing was copied. That would fail every successful copy / label / move.

Extracted copyMatchedNothing(), which only draws the conclusion when Caps().Has(imap.CapUIDPlus) guarantees the data is present.

#15's fixture pins Caps: imap.CapSet{imap.CapIMAP4rev2: {}}, so its suite could not catch this. Added client_copyuid_test.go with a plain IMAP4rev1 fixture.

Tradeoff, stated plainly: on a non-UIDPLUS server this necessarily weakens COPY no-match detection — the alternative is failing every real copy, which is strictly worse. MoveMessages still catches no-matches there via the STORE affected-count, pinned by TestMoveMissingUIDWithoutUIDPlusStillErrors. Proton Bridge is expected to advertise UIDPLUS, in which case nothing is lost.

All of #15's original tests pass unchanged.

3. --help-json schema gap

#16 added --flagged, --fields, and --compact without updating internal/cli/help.go. Per CLAUDE.md that output is the documented agent-integration contract, so the flags were invisible to it. Added them, plus --offset and --page which were already missing.

Verification

gofmt -l, go vet ./..., go test ./... all clean. Smoke-tested --help-json renders all eight mail list flags.

🤖 Generated with Claude Code

#15 and #16 merge cleanly in git but collide semantically: #15's
client_affected_test.go calls the pre-#16 ListMessages signature, so
master did not build. Ported those three call sites to ListOptions.

Also guards the no-match detection added in #15. CopyCommand.Wait()
returns &cmd.data unconditionally in go-imap v2, so the `copyData != nil`
half of the check was dead code and the result rested entirely on
COPYUID. COPYUID is only sent by servers advertising UIDPLUS (folded into
IMAP4rev2); without it an empty SourceUIDs/DestUIDs pair means the server
never reported, not that nothing was copied — which would have failed
every successful copy/label/move. Extracted copyMatchedNothing(), which
draws that conclusion only when the capability guarantees the data.

#15's fixture pins Caps to IMAP4rev2 and so could not cover this; added a
plain IMAP4rev1 fixture. On such a server COPY no-match detection is
necessarily weaker, but MoveMessages still catches it via the STORE
affected-count — pinned by TestMoveMissingUIDWithoutUIDPlusStillErrors.

Finally, adds #16's new mail list flags (--flagged, --fields, --compact)
to the --help-json schema per CLAUDE.md, along with --offset and --page,
which were already missing. That output is the documented agent contract.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@bscott
bscott merged commit 9345c82 into master Aug 8, 2026
1 check passed
@bscott
bscott deleted the fix/post-merge-integration branch August 8, 2026 23:00
bscott added a commit that referenced this pull request Aug 9, 2026
Marks the changelog entry as released rather than Unreleased, so the
tagged commit does not describe itself as pending.

Records that the release was validated against a live Proton Bridge
3.25.0 rather than only the in-memory test server, and that Bridge
advertises UIDPLUS, which resolves the open question from #15 and #17:
the COPYUID no-match check runs at full strength on Bridge, and the
capability guard costs nothing there while still protecting servers that
withhold COPYUID.

Co-authored-by: exe.dev user <exedev@discovery-lotus.exe.xyz>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant