Implements Phase 5 of AGENTS.md §11 (FR-8, FR-15):
- Message detail pane (GET /partials/message) with body, recommended
action, reply identity, template picker, editable draft, and history.
- internal/reply: OmniRoute (OpenAI-compatible) chat client and a
template-based draft generator. All non-JEV models go through
OmniRoute (§10).
- internal/mailops: SMTP send over smtp.gmail.com:587 with STARTTLS and
the app password, forcing IPv4 (§9); FR-15 reply identity (send as the
arrived-at X-Pm-Original-To address, else "Sam Rolfe"); threading via
In-Reply-To/References; -check-smtp safe verification; and a
[Gmail]/Sent Mail thread check.
- Migration v5 stores messages.message_id_header and drafts.sent_at;
mailfetch parses Message-ID.
- Send is user-triggered only: CSRF + UI confirm + confirm=yes guard,
no auto-send, duplicate-send refused. A sent reply files the original
under Replied-to/<address> and logs every step (FR-13).
- Tests for reply, mailops SMTP/identity/thread check, store drafts and
migration v5, and the server draft/edit/send guards.
- docs/phase5-replies.md, README, .env.example, docker-compose updated.
Co-Authored-By: Paperclip <noreply@paperclip.ing>