Replace 'post reply' with '--replying-to' option on 'post draft'#12
Replace 'post reply' with '--replying-to' option on 'post draft'#12
Conversation
- Remove 'Reply' command (~145 lines) - Add --replying-to <uid> and --reply-mailbox <name> options to Draft - Fetch original message and set In-Reply-To/References headers - Default --reply-mailbox to INBOX (UIDs are mailbox-scoped) - Fix blockquote CSS: remove paragraph margins for compact quotes Closes #11
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f0951bb632
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| @@ -113,7 +113,6 @@ struct PostCLI: AsyncParsableCommand { | |||
| Quota.self, | |||
| Attachment.self, | |||
| Draft.self, | |||
There was a problem hiding this comment.
Restore a complete reply workflow after removing
post reply
Removing Reply.self from the command list drops the only path that auto-derived sender, recipients, and Re: subject from the original message, but the new --replying-to support in post draft only adds threading headers and still depends on explicit --from, --to, and --subject. In practice, existing post reply <uid> --body ... scripts now have no equivalent one-command replacement and the documented migration to post draft --replying-to <uid> --body ... fails with missing required options before execution.
Useful? React with 👍 / 👎.
Make --from, --to, and --subject optional when --replying-to is set. Auto-derive from original message: - from: original.to.first (sender becomes original recipient) - to: original.from (reply to original sender) - subject: 'Re: ' + original.subject (add Re: prefix if missing) Restores the UX convenience of the old 'post reply' command. Usage: post draft --replying-to 13106 --body reply.md No need to specify --from, --to, or --subject explicitly.
Update: Auto-Derive from/to/subjectGood catch by the bot! The initial implementation required explicit Fixed in commit
|
| Field | Auto-derived from |
|---|---|
--from |
original.to.first (your address from original's recipients) |
--to |
original.from (reply to original sender) |
--subject |
"Re: " + original.subject (add Re: prefix if missing) |
New Usage
# Minimal reply (auto-derives from/to/subject)
post draft --replying-to 13106 --body reply.md
# Explicit override (if needed)
post draft --replying-to 13106 --body reply.md --to custom@example.com
# Old workflow still works
post draft --from me@example.com --to them@example.com --subject "Test" --body draft.mdMigration Now Complete
# Old
post reply 13106 --body "My reply"
# New (exact equivalent)
post draft --replying-to 13106 --body "My reply"✅ Tested with UID 1592 — auto-derived from/to/subject correctly.
- Add --reply-all flag to post draft - When used with --replying-to, includes all original recipients in CC (excludes sender and primary recipient) - Add cc field to MessageDetail struct - Populate cc from SwiftMail MessageInfo.cc Usage: post draft --replying-to 13106 --reply-all --body reply.md
Update: Added
|
Allow creating empty reply drafts for inline editing in email client. Usage: post draft --replying-to 13106 Creates a threaded reply with: - Auto-derived from/to/subject - In-Reply-To and References headers - Empty body for inline composition in Mail.app Body is still required for non-reply drafts.
Update: Made
|
When creating a reply draft without --body, auto-quote the entire original message (like Mail.app Reply behavior). Format: - Two blank lines at top (cursor position for inline editing) - Attribution header: 'On DD.MM.YYYY, at HH:MM, sender wrote:' - Full quoted original (Markdown, each line prefixed with '>') Usage: post draft --replying-to 12731 # → Creates draft with empty top + full quoted original This matches native email client behavior when you press Reply.
Update: Auto-Quote Original When Body OmittedNow when you omit Changes in commit
|
Detect format AFTER resolving final body (including derivedBody). Previously: - Format detected from empty string when body was nil - Always treated as plain text - Markdown quote markers (>) rendered literally Now: - Format detected from final resolved body - Auto-quoted body (with >) correctly detected as Markdown - Renders as proper HTML blockquotes in email client Result: Auto-quoted replies now have gray blockquote bars instead of literal '>' characters.
Fix: Markdown Format Detection for Auto-Quoted RepliesFixed the format detection so auto-quoted replies render as proper HTML blockquotes instead of literal Changes in commit
|
- Move attribution header ('On ... wrote:') inside the blockquote
- Add two blank lines with spaces at top (prevents trimming)
- Creates empty paragraph space for cursor in Mail.app
Result matches Mail.app native Reply:
1. Two empty lines at top
2. > On DD.MM.YYYY, at HH:MM, sender wrote:
3. >
4. > [quoted message]
Fix: Attribution Header Inside Blockquote + Empty Top LinesFixed the quote formatting to match Mail.app's native Reply exactly. Changes in commit
|
Use > <br> for empty lines in quoted text to preserve paragraph spacing in HTML rendering. Standard Markdown blockquotes collapse consecutive lines, so empty lines (>) don't create visual paragraph breaks. Using <br> tags ensures proper spacing between paragraphs in the quoted original. Result: Quoted text now has proper paragraph breaks matching the original email formatting.
Fix: Preserve Paragraph Breaks in Quoted TextFixed paragraph spacing in quoted replies using Changes in commit
|
Switch from original.markdown() to original.textBody for quoting. Problem: HTMLToMarkdown converter collapses paragraph breaks when converting HTML to Markdown, losing blank lines between paragraphs. Solution: Use plain text body directly, which preserves original formatting including blank lines. Trade-off: Links are plain text instead of Markdown formatted, but paragraph breaks are preserved correctly. Mail.app will still render plain URLs as clickable links.
Use plain '>' for empty lines instead of '> <br>'. Let Markdown-to-HTML handle blockquote rendering naturally.
Known Issue: Blockquote Paragraph BreaksThe Markdown we generate is correct with proper > Para 1
>
> Para 2However, SwiftText's MarkdownToHTML converter collapses consecutive blockquote lines, losing paragraph breaks in the HTML output. Filed SwiftText IssueSwiftText #8: MarkdownToHTML collapses blockquote paragraphs Current WorkaroundNone yet. The quoted text will have compressed paragraphs until SwiftText is fixed. Long-term FixOnce SwiftText #8 is resolved, the paragraph breaks will render correctly without any changes to Post code. |
Changed from ' \n \n' to '\n\n' for leading blank lines. Note: Leading whitespace is still being trimmed somewhere (possibly SwiftMail or email body normalization). Once SwiftText #8 is fixed to preserve leading blank lines as empty <p></p> tags, this will work correctly. For now, the main reply functionality works - just missing the empty paragraphs at the top.
- SwiftText 1.1.4: Fixes blockquote paragraph breaks and leading blank lines - SwiftMCP 1.4.0: Stability improvements This should fix: - Paragraph breaks in quoted replies - Empty paragraphs at top of reply drafts
Removed the '\n>\n' blank quote line after the attribution header. Before: > On ... wrote: > > Body text After: > On ... wrote: > Body text This matches Mail.app's native Reply formatting more closely.
Reverted previous commit - the blank line after 'On ... wrote:' should be preserved for proper Mail.app formatting. Format: > On ... wrote: > > Body text
Changed blockquote p CSS: - margin: 0.5em 0 0 0 (top spacing between paragraphs) - margin-top: 0 on first-child (no space before first para) This creates visible spacing for empty <p></p> tags (like the blank line after 'On ... wrote:') while keeping the first paragraph tight against the attribution header.
Use original.markdown() instead of original.textBody for quoting. Benefits: - HTML emails: Preserves formatting, links, lists, etc. - Plain text emails: Falls back to plain text automatically - Paragraph breaks: Preserved correctly in both cases The markdown() method handles both HTML and plain text emails: 1. If HTML exists: HTMLToMarkdown conversion 2. If plain text only: Returns text as-is 3. Empty: Returns empty string Result: Quoted replies now preserve original formatting for all email types.
Summary
Replaces the separate
post replycommand with--replying-to <uid>and--reply-mailbox <name>options onpost draft.Changes
1. Remove
post replycommandReplystruct (~145 lines)2. Add reply functionality to
post draft--replying-to <uid>- UID of message to reply to--reply-mailbox <name>- Mailbox containing original (default: INBOX)In-Reply-Tofromoriginal.messageIdReferenceschain (appends original's Message-ID)3. Fix blockquote CSS
blockquote p { margin: 0; }to remove excessive vertical paddingWhy This Design?
Single Unified Command
draftandreplyFull Format Support
AI-Friendly Workflow
AI agents can now:
post fetch 12345 --json> quoted text)post draft --replying-to 12345 --body reply.mdMarkdown handles the quoting style — no CLI auto-quote logic needed.
Usage Examples
Testing
✅ Created reply draft to UID 13106 with:
Breaking Change
Removes
post replycommand.Migration:
Closes
#11