thunderbird-patch-review
Simple email patch review tool for Thunderbird
git clone git://mccd.space/thunderbird-patch-reviewcommit 757f76f663162a6357b637073e2ace0b5bfc8e37
parent 2df389571ea748c01f4a29c01c1e8febef1ad13c
Author: Pi Agent <agent@pi.local>
Date: Sun, 19 Jul 2026 10:38:54 +0200
README: finish the man-page-to-HTML conversion
The HTML draft stopped at <h2>Installation</h2> and left the rest of
the README as raw groff-text input. Finish the conversion: definition
lists for Configuration, Permissions, and Files; an ordered list for
Review workflow; <pre><code> for the zip command block; <a href> for
the introductory post and the mailing list; and the trailing
headings (Sourcehut integration, Caveats, See also, Contributing,
Author) as plain prose.
Diffstat:
| A | README.html | | | 172 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
1 file changed, 172 insertions(+), 0 deletions(-)
diff --git a/README.html b/README.html
@@ -0,0 +1,171 @@
+<main>
+ <h1>Thunderbird Patch Review</h1>
+ <p>Review git patches from email inside Thunderbird</p>
+ <h2>Synopsis</h2>
+ <p>A Thunderbird MailExtension. Open a patch email, press Review,
+ comment on hunks, send the review as a mailing-list reply, and apply
+ the series to a local repository with git-am(1).</p>
+ <h2>Description</h2>
+
+ <p>patch-review brings a review interface to git-by-email workflows
+ (git-send-email(1) style). When the selected messages (or thread)
+ look like a patch -- a [PATCH] subject tag or a unified diff in the
+ body -- the Review button in the main toolbar becomes active. It
+ opens a dedicated review tab that shows the whole series: cover
+ letter, per- patch commit messages, and every file and hunk rendered
+ as a colored diff. Within replaced lines, the span that actually
+ changed gets a stronger highlight, computed from the common prefix
+ and suffix of each deleted/added line pair.</p>
+
+ <p>Clicking a diff line attaches an inline comment to it; comments
+ are saved as drafts (keyed by Message-ID) and survive restarting
+ Thunderbird. Send review turns the comments of each commented patch
+ into one plain-text reply-to-all, quoting the relevant hunks kernel-
+ style with the comments interleaved unquoted below the lines they
+ target, and sends the replies immediately; the draft comments are
+ then cleared and the review tab closes. The attached drop-down
+ offers Preview in compose instead, which leaves the reply drafts
+ open in compose windows. A reply that fails to send also stays open,
+ so nothing is lost. Apply series runs git am --3way on the raw patch
+ messages in the configured repository. On conflict git am --abort is
+ run and its output reported, leaving the repository untouched. Its
+ drop-down offers Modify and apply -- apply, then open the touched
+ files in your editor -- and Download patchset -- save the raw series
+ as one mbox file, ready for git am.</p>
+
+ <h2>Installation</h2>
+ <p>Package the extension as an .xpi and install it via the Add-ons
+ Manager gear menu (Install Add-on From File...). From the project
+ root:</p>
+ <pre><code>(cd extension && zip -qrX ../patch-review.xpi .)</code></pre>
+ <p>The subshell runs the zip(1) from inside extension/ so the archive
+ holds manifest.json at its root, not under extension/. git(1) is a
+ dependency (for Apply). For development, instead pick Tools ->
+ Developer Tools -> Debug Add-ons -> Load Temporary Add-on...,
+ and select extension/manifest.json; it is dropped on restart.</p>
+
+ <h2>Configuration</h2>
+ <p>Open the extension's preferences:</p>
+ <dl>
+ <dt>Editor command</dt>
+ <dd><p>Run from the repository after a successful apply, with the
+ changed files as arguments. Use a non-blocking GUI-capable command
+ such as <code>code -n</code> or <code>emacsclient -n</code>; a bare
+ terminal editor has no terminal to open in. Empty means
+ <code>$EDITOR</code>.</p></dd>
+
+ <dt>Apply strategy</dt>
+ <dd><p><code>git am --3way</code> (default) or plain
+ <code>git am</code>.</p></dd>
+
+ <dt>Repository mappings</dt>
+ <dd><p>Substring matches against a patch's List-Id header or
+ sender, mapped to an absolute repository path. When no mapping
+ matches, the last path a series was applied to is used; it is
+ remembered until changed.</p></dd>
+ </dl>
+ <p>Repository paths can be chosen with the Browse button, which opens
+ Thunderbird's native directory chooser; the path field stays editable
+ either way.</p>
+
+ <h2>Permissions</h2>
+ <p>The extension requests the fewest permissions it needs; none are
+ granted to remote content.</p>
+ <dl>
+ <dt>messagesRead</dt>
+ <dd><p>Reads the selected message and its sibling patches in the
+ same folder (subject, author, body) to build the review.</p></dd>
+
+ <dt>accountsRead</dt>
+ <dd><p>Resolves the default identity of the account that owns the
+ reviewed message, for the From-address label and
+ send-as.</p></dd>
+
+ <dt>storage</dt>
+ <dd><p>Persists draft comments (keyed by Message-ID) across
+ restarts, plus the editor command, apply strategy, repo mappings,
+ and the last applied repository path.</p></dd>
+
+ <dt>compose, (compose.send)</dt>
+ <dd><p>Opens reply-to-all compose windows from Send review and
+ sends them in Send now mode. Without compose.send the review can
+ only be previewed in compose, never sent.</p></dd>
+
+ <dt>downloads</dt>
+ <dd><p>Writes the Download patchset .mbox to disk.</p></dd>
+
+ <dt>tabs</dt>
+ <dd><p>Opens the review tab and removes it after a successful
+ send.</p></dd>
+ </dl>
+ <p>The privileged Apply, Browse... , and Open editor code does not use
+ a Mozilla permission: it is a WebExtension Experiment
+ (<code>experiment_apis.patchHost</code>) shipped inside the XPI and
+ runs only when the extension is loaded.</p>
+
+ <h2>Sourcehut integration</h2>
+ <p>When the series arrives via a sourcehut mailing list (a
+ lists.sr.ht address in the List-Id or recipients), the review tab
+ shows a set status checkbox with the patchset states sourcehut
+ understands: APPROVED, NEEDS_REVISION, REJECTED, PROPOSED,
+ SUPERSEDED, APPLIED. When enabled, the first reply of the review
+ carries an X-Sourcehut-Patchset-Update header with the chosen status,
+ which sourcehut applies to the patchset. A status can also be sent
+ without any line comments -- Send review then sends a single, empty
+ reply to the cover letter (or first patch) carrying just the
+ header.</p>
+
+ <h2>Review workflow</h2>
+ <ol>
+ <li>Select any message of the series -- or the whole thread -- and
+ press Review in the main toolbar.</li>
+ <li>The tab collects the sibling patches from the same folder (same
+ series tag, version, and patch count).</li>
+ <li>Click lines, write comments; Ctrl+Enter saves. "Comment on
+ patch" attaches a general remark instead.</li>
+ <li>Send review: one reply per commented patch, sent immediately
+ (or use the drop-down to preview first).</li>
+ <li>Apply series: git am into the mapped repository, then Open
+ editor on the touched files.</li>
+ </ol>
+
+ <h2>Files</h2>
+ <dl>
+ <dt>extension/</dt>
+ <dd><p>The MailExtension (manifest v2, vanilla ES modules, no
+ build step).</p></dd>
+
+ <dt>extension/api/patchHost/</dt>
+ <dd><p>The privileged part (a WebExtension Experiment): runs
+ git-am(1) and the editor through Thunderbird's Subprocess API and
+ shows the directory chooser with nsIFilePicker. Everything outside
+ this directory runs as ordinary sandboxed WebExtension
+ code.</p></dd>
+
+ <dt>tests/</dt>
+ <dd><p><code>node tests/run.mjs</code> exercises the pure modules
+ (subject parsing, diff parsing, reply formatting) against fixtures
+ generated by git-format-patch(1), and checks the experiment's
+ manifest wiring. Regenerate fixtures with
+ <code>tests/gen-fixtures.sh</code>.</p></dd>
+ </dl>
+
+ <h2>Caveats</h2>
+ <p>Patches arriving as attachments, HTML-only mail, and reviewing
+ from a git worktree preview are not supported yet. Series collection
+ searches the folder of the opened message only.</p>
+
+ <h2>See also</h2>
+ <p>The introductory post can be found at
+ <a href="https://mccd.space/posts/26-07-18/3-patch-review-tool-for-thunderbird">https://mccd.space/posts/26-07-18/3-patch-review-tool-for-thunderbird</a>.</p>
+
+ <h2>Contributing</h2>
+ <p>Disclaimer: this plugin was vibe coded -- written by an AI agent
+ under human direction.</p>
+ <p>Contributions and bug reports go to the mailing list:
+ <a href="mailto:~marcc/thunderbird-review-plugin@lists.sr.ht">~marcc/thunderbird-review-plugin@lists.sr.ht</a>.</p>
+
+ <h2>Author</h2>
+ <p>Marc Coquand <marc@coquand.email><br>
+ patch-review 0.1.0 -- July 2026</p>
+</main>
+\ No newline at end of file