Skip to content

feat(gmail): add --cc/--bcc on draft, send, reply, and forward - #54

Merged
MaximeGaudin merged 8 commits into
MaximeGaudin:mainfrom
clement-gladia:feat/gmail-cc-bcc
Jul 30, 2026
Merged

feat(gmail): add --cc/--bcc on draft, send, reply, and forward#54
MaximeGaudin merged 8 commits into
MaximeGaudin:mainfrom
clement-gladia:feat/gmail-cc-bcc

Conversation

@clement-gladia

@clement-gladia clement-gladia commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

What

Add --cc / --bcc (comma-separated) on all outgoing Gmail compose paths:

  • void gmail draft create / draft update
  • void send --via gmail
  • void reply
  • void forward / void gmail forward
  • MCP send / reply / forward

Cc/Bcc headers are emitted after To and before Subject/MIME so Gmail honors them.

Depends on #47 (Gmail signature support) — this branch is stacked on feat/gmail-draft-signature.

Docs & tests

  • docs/commands.md — Acting + Gmail sections; draft --reply-to note that original From/To/Cc fold into To and --cc/--bcc are additive
  • docs/mcp.mdcc / bcc on write tools
  • README.md — Gmail examples include send/reply/draft (no longer “drafts only”)
  • Unit tests cover Cc/Bcc header order on plain and attachment compose (empty/whitespace omitted)

Checklist

  • ./scripts/check.sh passes (fmt, clippy, tests)
  • CHANGELOG.md updated under [Unreleased] (user-visible changes only)
  • Docs updated (README.md / docs/) if behavior or flags changed

Made with Cursor

clement-gladia and others added 6 commits July 27, 2026 17:09
Emit Cc/Bcc headers after To and before Subject/MIME so Gmail honors them
on all outgoing compose paths, including MCP write tools.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@MaximeGaudin

Copy link
Copy Markdown
Owner

Review feedback

Recommendation: Request changes (process + one hardening ask). The novel --cc/--bcc tip looks solid once the stack lands.

Context: Reviewed in local mode. Effective novel delta is vs #47 tip (feat/gmail-draft-signature); most of the 29-commit diff is that stacked signature work (already approved on #47). Local ./scripts/check.sh passed on tip 586631d. GitHub CI: no checks reported on this branch.

Blockers (process)

  1. Draft + unmerged dependency — This PR depends on Add optional Gmail signature on all outgoing compose paths #47. Please merge Add optional Gmail signature on all outgoing compose paths #47 first (or explicitly accept a combined merge), rebase feat/gmail-cc-bcc onto main, then mark this PR ready for review.
  2. CI never ran on this tip. After rebase / marking ready, push so Actions records a green run (local check already passed).

Should-fix

  1. Header CR/LF injection in address fieldspush_address_headers interpolates user --cc / --bcc (and historically To) into RFC 2822 headers without stripping \r/\n. Same pre-existing class as To, but worth rejecting control characters in address fields — especially for MCP send / reply / forward. Location: crates/void-gmail/src/connector/compose.rs (push_address_headers).

Looks good

  • Intent fits (agent/terminal-first); Conventional Commits; CHANGELOG + docs/MCP coverage.
  • No dependency / lockfile / workflow changes.
  • ComposeRecipients / DraftRecipients + shared header helper; Gmail-only fields on MessageContent / ForwardOptions match existing subject / signature patterns; construction sites updated.
  • Unit tests cover Cc/Bcc order (plain + attachment) and empty/whitespace omission.
  • Stacked OAuth bits from Add optional Gmail signature on all outgoing compose paths #47 (include_granted_scopes=true, refresh-token preserve, TTY gate, narrowed insufficient-scope matching) look correct; not re-litigating that PR here.

Summary

Land #47 → rebase this tip → mark ready → confirm CI. Optionally harden address headers against CR/LF. Novel cc/bcc implementation itself is merge-ready after those process gates.

@clement-gladia
clement-gladia marked this pull request as ready for review July 29, 2026 10:58
@MaximeGaudin

Copy link
Copy Markdown
Owner

PR Review — #54: feat(gmail): add --cc/--bcc on draft, send, reply, and forward

Recommendation: Merge ✓
Author: clement-gladia · +492/-63 across 21 files · CI: all green (macOS/Ubuntu/Windows + Coverage + Format + MSRV + cargo-deny)
Review mode: Local — full checkout, ./scripts/check.sh passed on tip 812538c

1. Intent & fit

Fits. The PR adds --cc / --bcc (comma-separated) on all outgoing Gmail compose paths: draft create/update, send, reply, forward, and MCP write tools. This is a natural extension of the existing Gmail compose surface and matches the agent/terminal-first philosophy. Focused on a single logical change, Conventional Commits observed, CHANGELOG + docs updated.

Dependency on #47 (Gmail signature) is already merged — the branch was rebased onto main (merge commit 0a1f606). The effective novel delta is the cc/bcc implementation plus the CR/LF hardening fix requested in the prior review round.

2. Security · Verdict: clean

  • Dependencies: None added. No changes to Cargo.toml, Cargo.lock, or deny.toml.
  • Code-level: No new network calls, unsafe blocks, Command::new, env reads, filesystem reaches, or CI/workflow changes.
  • Header injection hardening: reject_header_injection rejects any byte where is_ascii_control() is true (covers CR, LF, NUL, and all 0x00–0x1F + 0x7F). Applied to To, Cc, and Bcc fields via push_address_headers. Tests verify rejection on all three fields with \r\n and bare \n/\r variants.
  • Data handling: No credential/token code touched; no new persistence paths; compose functions only format RFC 2822 headers for the Gmail API.

3. Code review

Implementation patterns

Conforms. The PR follows the established pattern for Gmail-specific fields on MessageContent (same as subject, append_signature, signature_from — added to both Text and File variants with accessor methods). All construction sites are updated:

  • Non-Gmail connectors destructure with .. (don't need explicit cc/bcc)
  • ForwardOptions grows cc/bcc fields; Slack/Telegram forward impls accept the struct but ignore those fields (Slack reads only comment, Telegram uses _options)
  • ComposeRecipients / DraftRecipients structs + shared push_address_headers helper is a clean abstraction matching the single-responsibility of compose.rs

Test coverage · Verdict: adequate

New tests cover:

  • Header ordering: To < Cc < Bcc < Subject for both plain and attachment compose
  • Empty/whitespace Cc/Bcc omission
  • CR/LF injection rejection on To, Cc, and Bcc (both compose paths)
  • Existing tests updated for the compose_rfc2822Result<String> return type change

Conventions followed: wiremock::MockServer, tempfile-style temp paths, no real network, deterministic inputs.

Blockers

None.

Should-fix

None.

Nits

None identified. The implementation is clean and well-structured.

Summary

Solid, focused PR that extends the Gmail compose surface with Cc/Bcc support across all outgoing paths. The CR/LF injection hardening (addressing the prior review feedback) is well-implemented with proper test coverage. No security concerns, no dependency changes, no pattern deviations. CI fully green across all platforms. Ready to merge.

@MaximeGaudin MaximeGaudin left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM — clean implementation, solid test coverage, no security concerns. Ready to merge.

@MaximeGaudin
MaximeGaudin merged commit 40a07e6 into MaximeGaudin:main Jul 30, 2026
7 checks passed
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.

2 participants