feat(app): Help > Share gclo by email, a ready-to-send invitation with download links #164

Merged
james.maes merged 4 commits from feat/share-invitation into main 2026-11-11 01:32:28 +00:00
Owner

What

Help > Share gclo by email… opens a new message in the user's email program with an invitation already written: what gclo is, where to download the latest release, how to install it (the installer, and Scoop for the command line), where the documentation is, and where to send feedback. No recipient is filled in; the user types an address and sends.

  • ShareInvitation (in gclo.ViewModels) writes the subject, the body, and the mailto: link, and keeps the link under 2,000 characters.
  • The shell hands the link to the system. If no email program takes it, the invitation is copied to the clipboard and shown in a dialog, to paste into a message by hand.
  • gclo sends nothing itself, and nothing about the user, their accounts, or their repositories is in the text.

Why

Closes #163

How it was tested

  • ShareInvitationTests: the body's content and links, a recipient-less link that decodes back to exactly the subject and body, its length, CR LF line ends, a trailing slash on the repository address, and refused inputs.
  • A UI smoke test: under the UI test fixture the invitation is shown in the app instead of being handed to an email program, so the test reads it and nothing opens on the machine that runs the suite.
  • Local gates (without the UI suite so far): 1014 engine and 212 CLI tests, 100% line coverage on the three gated assemblies, zero warnings, format clean. The UI suite will be run before merge.

Checklist

  • Commits are signed and signed off (git commit -S -s)
  • Zero build warnings; format and lint are clean
  • Tests added or updated; the 100% coverage gate still passes
  • Docs updated for user-visible changes (README); threat model: no new data leaves the app, the link is handed to the system's own handler
  • No secrets, credentials, or personal data
  • New dependencies are justified below, or none were added (none)
  • Substantial AI assistance, if any, is noted here: written with Claude Code

🤖 Generated with Claude Code

## What **Help > Share gclo by email…** opens a new message in the user's email program with an invitation already written: what gclo is, where to download the latest release, how to install it (the installer, and Scoop for the command line), where the documentation is, and where to send feedback. No recipient is filled in; the user types an address and sends. - `ShareInvitation` (in `gclo.ViewModels`) writes the subject, the body, and the `mailto:` link, and keeps the link under 2,000 characters. - The shell hands the link to the system. If no email program takes it, the invitation is copied to the clipboard and shown in a dialog, to paste into a message by hand. - gclo sends nothing itself, and nothing about the user, their accounts, or their repositories is in the text. ## Why Closes #163 ## How it was tested - `ShareInvitationTests`: the body's content and links, a recipient-less link that decodes back to exactly the subject and body, its length, CR LF line ends, a trailing slash on the repository address, and refused inputs. - A UI smoke test: under the UI test fixture the invitation is shown in the app instead of being handed to an email program, so the test reads it and nothing opens on the machine that runs the suite. - Local gates (without the UI suite so far): 1014 engine and 212 CLI tests, 100% line coverage on the three gated assemblies, zero warnings, format clean. The UI suite will be run before merge. ## Checklist - [x] Commits are signed and signed off (`git commit -S -s`) - [x] Zero build warnings; format and lint are clean - [x] Tests added or updated; the 100% coverage gate still passes - [x] Docs updated for user-visible changes (README); threat model: no new data leaves the app, the link is handed to the system's own handler - [x] No secrets, credentials, or personal data - [x] New dependencies are justified below, or none were added (none) - [x] Substantial AI assistance, if any, is noted here: written with Claude Code 🤖 Generated with [Claude Code](https://claude.com/claude-code)
james.maes added 1 commit 2026-11-10 23:14:26 +00:00
Help > Share gclo by email opens a new message in the user's email program
with an invitation already written: what gclo is, where to download the
latest release, how to install it (the installer, and Scoop for the command
line), where the documentation is, and where to send feedback. No
recipient is filled in, so the user types an address and sends. gclo
itself sends nothing, and nothing about the user, their accounts, or their
repositories is in the text.

- ShareInvitation (gclo.ViewModels) writes the subject, the body, and the
  mailto link, and keeps the link short enough for mail programs that cut
  long ones.
- The shell hands the link to the system. When no email program takes it,
  the invitation is copied to the clipboard and shown, to be pasted into a
  message by hand. Under the UI test fixture it is only shown, so the
  suite opens nothing on the machine it runs on.

Closes #163

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Signed-off-by: James Maes <james@kof22.com>
james.maes added 1 commit 2026-11-11 01:08:36 +00:00
The text box was given its text before it was told to take several lines,
and a one-line box keeps only the first line of what it is given. Found by
the UI test for this dialog on its first run.

Refs #163

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Signed-off-by: James Maes <james@kof22.com>
james.maes added 1 commit 2026-11-11 01:16:18 +00:00
The fallback dialog copied the invitation to the clipboard before it showed
itself. The clipboard belongs to the whole desktop: when another program
held it the dialog never appeared, and under the UI suite the copy overwrote
whatever the person at the machine had copied. The copy is now best effort,
the dialog says whether it happened, and the UI fixture skips it.

Refs #163

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Signed-off-by: James Maes <james@kof22.com>
james.maes added 1 commit 2026-11-11 01:32:04 +00:00
From the independent review of this pull request:
- The links are built from the parsed address (scheme, host, path); an address
  with a user name, a query or a fragment, and a version with a control
  character, are refused.
- An invitation too long for a link (FitsInALink) is shown for copying instead
  of being handed to a mail program that might cut it short.
- A launch that throws is treated like one that found no mail program.
- The log says what happened after it happened, including a dialog that could
  not be shown because another one is open.
- The clipboard copy is flushed, so the text survives gclo closing.
- The box that holds the text tells a screen reader why the dialog is there.
- The message no longer sends its reader to the issue tracker: filing an issue
  there needs an account, and registration is closed. The reader is asked to
  tell the sender.

Refs #163

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Signed-off-by: James Maes <james@kof22.com>
Author
Owner

Independent review and UI run

UI suite, first run on this branch. It found a defect in the feature itself: the fallback dialog showed only the subject line, because the text box was given its text before it was told to take several lines. Fixed (7ca752e). A second defect showed as an intermittent failure: the dialog depended on the clipboard, which belongs to the whole desktop, and under the suite the copy overwrote the clipboard of the machine running it. The copy is now best effort and the fixture skips it (124d081).

Independent review: MERGE AFTER FIXES. Fixed in 6f30a33:

  • links are built from the parsed address; user name, query, fragment and control characters are refused;
  • FitsInALink: an invitation too long for a link is shown for copying instead;
  • a launch that throws is treated like one that found no mail program;
  • the log states outcomes after they happened; a dialog blocked by another one is said;
  • clipboard flush; help text on the box for screen readers.

Checked and found correct by the reviewer: the mailto: encoding and its round trip through a WinRT Uri, the fixture seam being off in installed builds, nothing about the user in the text.

Changed beyond the review: the invitation no longer links to the issue tracker. Filing an issue on git.kof22.com needs an account and registration there is closed; the reader is asked to tell the sender.

Left open: when a mail handler is registered but not set up, Windows reports success and the fallback is not reached. A "copy the invitation text" route that is always available would close that; recorded for the next release.

Gates: build, 1,022 engine and 212 CLI tests, 100% line coverage, format. UI suite: 13 of 13 on consecutive runs. Note: the UI suite was unstable on the desktop it ran on today (runs of the same code alternated between 13 of 13 in 15 s and timeouts in table tests this change does not touch); recorded as its own item.

## Independent review and UI run **UI suite, first run on this branch.** It found a defect in the feature itself: the fallback dialog showed only the subject line, because the text box was given its text before it was told to take several lines. Fixed (7ca752e). A second defect showed as an intermittent failure: the dialog depended on the clipboard, which belongs to the whole desktop, and under the suite the copy overwrote the clipboard of the machine running it. The copy is now best effort and the fixture skips it (124d081). **Independent review: MERGE AFTER FIXES.** Fixed in 6f30a33: - links are built from the parsed address; user name, query, fragment and control characters are refused; - `FitsInALink`: an invitation too long for a link is shown for copying instead; - a launch that throws is treated like one that found no mail program; - the log states outcomes after they happened; a dialog blocked by another one is said; - clipboard flush; help text on the box for screen readers. Checked and found correct by the reviewer: the `mailto:` encoding and its round trip through a WinRT Uri, the fixture seam being off in installed builds, nothing about the user in the text. **Changed beyond the review:** the invitation no longer links to the issue tracker. Filing an issue on git.kof22.com needs an account and registration there is closed; the reader is asked to tell the sender. **Left open:** when a mail handler is registered but not set up, Windows reports success and the fallback is not reached. A "copy the invitation text" route that is always available would close that; recorded for the next release. **Gates:** build, 1,022 engine and 212 CLI tests, 100% line coverage, format. UI suite: 13 of 13 on consecutive runs. Note: the UI suite was unstable on the desktop it ran on today (runs of the same code alternated between 13 of 13 in 15 s and timeouts in table tests this change does not touch); recorded as its own item.
james.maes merged commit 0bdc43bd61 into main 2026-11-11 01:32:28 +00:00
Sign in to join this conversation.