Repository navigation
Conversation
Keep a reply's attribution line and a forward's header block readable next to right-to-left text. The line that introduces a quote is marked dir="ltr", as Gmail Web marks its own in English, since gog writes it in English: unmarked, it scrambles when a reply written in Hebrew quotes it. Each value taken from the original (every name and address, the date, and the forwarded subject) is wrapped in dir="auto", so it keeps its own direction and can't reorder the text around it; unmarked, a Hebrew name next to an address that starts with digits scrambles even in an English message. Gmail marks only a forward's sender this way. A value that doesn't parse is marked as a whole, and an empty value stays empty. The text/plain lines are unchanged. The quote's outer div also gets Gmail's gmail_quote_container class, and the forward's header block gets gmail_attr, like the reply's attribution line. Neither changes what Gmail shows. The quoted message is left as it came, including any gmail_quote_container of its own. The opening markup and the dir="auto" span live in a new gmail_quote_markup.go, shared by the reply, forward and mailbox renderers, with a helper that escapes a value before wrapping it. The tests use the shared opening constant in place of their own copies of the markup. Two older reply tests are removed: TestQuoteAttribution's cases now cover their date and escaping checks exactly, and TestQuoteLinesKeepTheirDirection their check that the quoted body passes through. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
🦞👀 Pull request received. I will update this pull request when review starts. ClawSweeper review completeClawSweeper finished reviewing this revision. The review result is being finalized. |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Codex review: needs maintainer review before merge. What this changesThis PR adds direction isolation and Gmail quote classes to shared HTML reply and forward headers. Example: Forward a message from ישראל ישראלי <0501234567@example.com> and quote it in a Hebrew-interface Gmail reply.
Review scores
ProductKind: Bug fix · Worth it: Yes · Fix scope: Complete Merge readiness✅ Ready for maintainer review Keep this PR open: current main still produces scrambled quote headers beside right-to-left text, and the focused fix has relevant live Gmail proof with no actionable findings. Priority: P2 Before mergeNone. FindingsNone. Agent review detailsHow this fits togetherGmail send and draft commands pass original message headers and bodies through shared composition formatters, producing plain-text and HTML MIME parts for the Gmail API. flowchart LR
A[Original Gmail message] --> B[Reply and forward commands]
B --> C[Shared composition formatters]
C --> D[Mailbox escaping and direction isolation]
D --> E[Plain and HTML MIME bodies]
E --> F[Gmail send and draft API]
Technical reviewBest possible solution: Land the shared direction-isolation fix while preserving plain-text output, escaped header values, and original quoted HTML. Do we have a high-confidence way to reproduce the issue? Current-main source exposes the missing direction isolation, and contributor screenshots plus baseline live Gmail draft/readback output demonstrate the failure; this review ran no target code. Is this the best way to solve the issue? The existing shared formatters are the correct owners, and the small common markup helper fixes the demonstrated HTML failure without adding a competing composition path. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning medium; reviewed against ea582609ec6e. Provenance checked
TestingProof path: shipped entry point. SecurityNone. EvidenceWhat I checked:
Likely related people:
Review metrics
LabelsLabel changes:
Label justifications:
Rating scale6/6 🦀 challenger crab · 5/6 🦞 diamond lobster · 4/6 🐚 platinum hermit · 3/6 🦐 gold shrimp · 2/6 🦪 silver shellfish · 1/6 🧂 unranked krab. Overall follows the weaker of proof and patch quality; ✨ marks media proof (a screenshot, video, or linked artifact) that directly shows the changed behavior. WorkflowClawSweeper edits this one comment on every review. Comment Reviewed October 22, 2026, 4:11 PM ET / 20:11 UTC. |
Preserve Gmail search results and reduce retry work: back off on recognized 403 rate limits, retain response bodies and read errors, cancel remaining detail fetches after a failure, and keep quoted operators out of label filters. Include nonempty Cc/Bcc in thread text and isolate reply/forward header direction without altering plain text or quoted HTML. Preserve requested false booleans in Drive and Sites list JSON for grouped fields, slash paths, and wildcards while leaving conditional fields omitted. Reproduces and incorporates #1242, #1246, #1247, #1248, and #1250; addresses #1241. Focused regression tests and independent Codex review pass. Co-authored-by: Serghei <xyrolle@gmail.com> Co-authored-by: Sebastien Tardif <SebTardif@ncf.ca> Co-authored-by: Kit <kit@alexpriest.com> Co-authored-by: Malo Bourgon <mbourgon@gmail.com>
|
Thanks for this fix. Incorporated into #1253 with contributor credit and a changelog acknowledgment: preserving reply and forward header direction next to right-to-left text, with Gmail quote classes and unchanged plain text and quoted HTML. The regression was reproduced before the change. Focused regression tests, the full remote |
What
People use gog in place of Gmail's own interface, so by default what gog writes should match what Gmail writes. This brings the markup of the line gog writes to introduce a quote, a reply's "On … wrote:" line or a forward's header block, in line with Gmail's, and goes a step further where Gmail's own lines still break next to right-to-left text. Before, that line broke in two ways:
<div dir="rtl">. gog's English line carried no direction of its own, so everyone reading that reply saw it scrambled::On Tue, Oct 20, 2026 at 12:30 PM … wrote,<From: Example Sender <sender@example.com. Gmail marks the line it writes with the direction of its own language,dir="ltr"for English.From: 0501234567> ישראל ישראלי@example.com>, with the link split in two.Both show in Gmail Web; see the screenshots under Behavior proof.
Changes
This covers every command that quotes a message:
gmail replyandreply-all,send,drafts createanddrafts updatewith--quote,drafts replyanddrafts reply-all, andgmail forwardandgmail drafts forward. They share the two formatters changed here.In line with Gmail:
dir="ltr", since gog writes it in English.dir="auto", as Gmail writes them:<strong class="gmail_sendername" dir="auto">and a<span dir="auto">around the bracketed address.dir="auto"gives the text the direction of its first letter and keeps it from reordering the text around it.gmail_quote_containerclass on the quote's outer div, andgmail_attron the forward's header block, as on the reply's attribution line. For the tested English messages, neither changed the delivered text part, the rendering or Gmail Web's "…" collapsing. They let tools that look for Gmail's markup find gog's quotes too; libredesk, for one, recognizes a quoted Gmail forward only bygmail_quote_container.Beyond Gmail, following the W3C's guidance for text of unknown direction:
<span dir="auto">too: the names and addresses in a reply's attribution line and a forward's To and Cc, the date, and the forwarded subject. In its English attribution line Gmail wraps a right-to-left sender name in invisible Unicode direction marks, and its To and Cc lines only as a whole, so a right-to-left name still scrambles them: a Gmail Web forward of a test message readTo: 42> דנה כהן@example.com>. The W3C recommendsdir="auto"on a tight element around names and addresses, and markup rather than control characters in HTML. The date is gog's English text unless the original's Date header doesn't parse; then it is shown as it came.Left alone, on purpose:
gmail_quote_container. Gmail Web removes that class when it quotes a message, keeping one per message; gog doesn't rewrite the original's markup. Other mail clients don't write Gmail's classes at all, the next reply from Gmail restores the one-container form, and in testing the nested form displayed and converted the same.The opening markup and the
dir="auto"span live in a newgmail_quote_markup.go, shared by the reply and forward formatters, with a helper that escapes a value before wrapping it.docs/gmail-workflows.mdmentions the direction marking.Not in this PR
Behavior proof
In Gmail Web
A forward and a quoted reply of the same synthetic message, sent from one account to another with a build of
mainand with this branch, as Gmail Web shows the delivered copies. The original is from a sender with a Hebrew name and an address that starts with digits, with Hebrew and Arabic recipients and a Hebrew subject. The last row is a reply started in Gmail's Hebrew interface, quoting the delivered forward.mainmainmainDrafts, read back with
gogLive against a personal Gmail account (
personalis an account alias); nothing is sent.proof_quote_direction.py(below; Python 3 standard library plusgog) inserts two synthetic source messages withgmail.users.messages.insert, both from a sender with a Hebrew name and an address that starts with digits. It saves adrafts replyof the first, which carries its own Gmail quote, and adrafts forwardof the second, which has a Hebrew subject and Hebrew and Arabic recipient names; the other commands share these formatters. Reading each draft back withgog gmail raw, it checks the HTML line that introduces the quote, that the reply's blockquote holds exactly the quoted message's HTML, and that the text/plain header lines read as expected with no invisible direction characters (all after removing carriage returns). It prints HTML one<br>per line. At the end it runsgmail trashon every draft and source message it recorded; its last check counts the trash commands that succeeded.Run against a build of current
mainwithout this change (gog-main: the two HTML checks fail, exit 1), then a build of this branch (gog-branch: all seven checks pass, exit 0):proof_quote_direction.pyTesting
TestQuoteLinesKeepTheirDirectionpins the whole HTML of a reply's quote and a forward's header block for a Hebrew sender with an address that starts with digits, a Hebrew subject and a Hebrew-named recipient: theltrline, both classes, eachdir="auto"element, the quoted message unchanged (its owngmail_quote_containerincluded), and text/plain lines without markup.TestForwardedHeaderLines(every header case, including unparseable values and escaping inside the new elements),TestForwardedHeaderLayout(which now also checks the opening markup for styling),TestGmailForward_HeaderBlockLikeGmail(both forward commands),TestQuoteAttribution(with new blank-sender and escaped-markup cases; no sender still reads "Original message:"), and the drafts, signature and note tests that locate the quote. They now use the shared opening constant instead of their own copies of the markup, and two older reply tests are removed:TestQuoteAttributionnow covers their date and escaping checks exactly, andTestQuoteLinesKeepTheirDirectiontheir check that the quoted body passes through.ltrmark, either class,dir="auto"on a name, the sender, an address, the date, the subject or an unparseable value, the escaping before it, the empty-value guard, the trim before it), rewriting the quoted message's container, or styling the opening markup fails a named test (19 of 19).make cigreen.🤖 Generated with Claude Code