Skip to content

feat: support draft editing and file-sourced draft bodies - #77

Merged
addisonkline merged 1 commit into
mainfrom
kline/v2-drafts
Jun 22, 2026
Merged

feat: support draft editing and file-sourced draft bodies#77
addisonkline merged 1 commit into
mainfrom
kline/v2-drafts

Conversation

@addisonkline

Copy link
Copy Markdown
Collaborator

Summary

Two enhancements to message drafts in MAIL:

  1. mail compose --body-file — the draft body can now be read from a file via -F/--body-file PATH as an alternative to the inline positional body. Exactly one of the two must be supplied.
  2. PATCH /drafts/{draft_id} — a new endpoint letting an authenticated user-agent update an existing draft's subject, body, reply_to, and tags. Only supplied fields change (tags: [] clears, omitted leaves unchanged), and updated_at is refreshed on any edit. Exposed in the CLI as mail draft-edit (alias de).

Changes

  • Protocol: DraftPatchRequest (all-optional fields) + DraftPatchResponse.
  • Server: validate_patch_draft_request validator, PATCH /drafts/{draft_id} route (mirrors the patch_webhook precedent), and patch_draft on the backend base + memory impl (model_copy + updated_at, 404 on unknown/foreign draft).
  • CLI: shared _body.py body resolver; optional positional body for compose; new draft-edit command.
  • Spec/docs: regenerated spec/openapi.yaml; updated http.md, cli.md, and quickstart.md.

Design notes

  • Per the answered design questions: --body-file is an explicit flag (not a @path/auto-detect convention), and PATCH does not guard against editing already-sent drafts (sent_at is never set under current behavior, so the guard couldn't trigger).
  • reply_to is editable via PATCH, matching compose.

Testing

  • 7 new integration tests (update / partial / clear-tags / 422 / 404 / cross-user isolation / edit-then-send) and 4 new client-command tests (file body, both/neither errors, draft-edit request shape); updated existing compose tests for the new body_file arg.
  • Full suite: 443 passed, 6 xfailed (xfails are pre-existing NotImplementedError stubs). ruff clean on all touched files; OpenAPI drift test passes.

🤖 Generated with Claude Code

Add two draft enhancements:

1. `mail compose` can now read a draft body from a file via
   `-F`/`--body-file PATH` as an alternative to the inline positional
   body. Exactly one of the two must be supplied.

2. A new `PATCH /drafts/{draft_id}` endpoint lets an authenticated
   user-agent update an existing draft's subject, body, reply_to, and
   tags. Only supplied fields change (tags: [] clears, omitted leaves
   unchanged) and updated_at is refreshed on any edit. Exposed in the
   CLI as `mail draft-edit` (alias `de`).

Regenerates spec/openapi.yaml and updates the HTTP and CLI docs.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@addisonkline
addisonkline merged commit 24f6e08 into main Jun 22, 2026
2 checks passed
@addisonkline
addisonkline deleted the kline/v2-drafts branch June 22, 2026 20:57
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