diff options
Diffstat (limited to 'docs/superpowers/plans/2026-08-03-post-0.1.0-usability.md')
| -rw-r--r-- | docs/superpowers/plans/2026-08-03-post-0.1.0-usability.md | 91 |
1 files changed, 35 insertions, 56 deletions
diff --git a/docs/superpowers/plans/2026-08-03-post-0.1.0-usability.md b/docs/superpowers/plans/2026-08-03-post-0.1.0-usability.md index 49f4000..ebcbea9 100644 --- a/docs/superpowers/plans/2026-08-03-post-0.1.0-usability.md +++ b/docs/superpowers/plans/2026-08-03-post-0.1.0-usability.md @@ -189,7 +189,7 @@ taking that too literally. | 121 | The thread list shows nothing while a query is running | feedback | S | open, 2026-08-20, from the notes. Follows item 74, which fixed the status-bar half and left the list itself blank | | 122 | The README documents a version of the app that no longer exists | documentation | M | open, 2026-08-20, from the notes. Delete-to-trash is entirely undocumented, including a config key a user must now set | -| 123 | Sending mail is not designed | v2 | ? | open, 2026-08-20, from the notes. Brainstorm only, explicitly `#plan-only`; the user places most open UX behind it | +| 123 | Sending mail is not designed | v2 | L | **specified** 2026-08-20, on branch `compose-and-send`. Design in `docs/superpowers/specs/2026-08-20-compose-and-send-design.md`; read that, not this row. Send is a per-account `send_command` on stdin, so the no-network-protocol rule stands. Composer is a separate window, body is markdown via cmark-gfm, drafts autosave to the account's drafts folder. No code written | | 124 | The worker reads the index directory as the mail root | defect | S | **done** 2026-08-20, unreleased. `mailRootOf()` over `NOTMUCH_CONFIG_MAIL_ROOT`, correct under both layouts. Verified by migrating the developer's own index to NVMe the same day: cold start 38.6 s to 0.67 s | @@ -197,6 +197,11 @@ taking that too literally. | 126 | A link with `target="_blank"` does nothing when clicked | defect | S | **done** 2026-08-20, unreleased. `createWindow()` returns a relay page that receives the navigation, hands the URL to the browser and refuses. The URL cannot be read in `createWindow()` itself, which is why a relay rather than a lookup | | 127 | A link's context menu offers four browser actions that cannot work | defect | XS | **done** 2026-08-20, unreleased. Three Open-in actions removed, `CopyLinkToClipboard` kept. Item 126 made them more dangerous rather than less: with a real `createWindow()` they would have started working | +| 128 | No outbox: a send with no network fails instead of queueing | v2 | M | open, 2026-08-20, from the item 123 brainstorm. **Blocked on 123.** The seam is designed in (`MessageSender` is the one funnel), so this wraps it rather than reworking it. Needs its own indicator story first: items 18, 19, 28 and 54 are all an indicator lying, and 125 is one still open | +| 129 | No inline images in a composed message | v2 | M | open, 2026-08-20, from the item 123 brainstorm. **Blocked on 123.** Wanted by the user. `cid:` from the HTML part with `multipart/related` nested inside the alternative, the most nesting-heavy part of MIME assembly, and markdown offers no syntax for it | +| 130 | A message cannot be attached to another message directly | v2 | S | open, 2026-08-20, from the item 123 brainstorm. **Blocked on 123.** A `message/rfc822` part, which GMime builds natively. The manual route exists from 123's first commit: `save_message` writes the `.eml` and it is attached as a file | +| 131 | The markdown dialect and extensions are fixed | v2 | S | open, 2026-08-20, from the item 123 brainstorm. **Blocked on 123.** Configurable in the shape Hugo's config uses. Deliberately fixed initially: CommonMark plus autolink, strikethrough and tasklist | +| 132 | Every action must have a shortcut, and that no longer serves | policy | S | open, 2026-08-20, raised by the user during the item 123 brainstorm. `everyActionHasAShortcut` was written when the action list was short; item 123 adds six more, and each new action consumes a chord whether or not anyone would press it. Replacement is the shape `everyActionIsReachableFromAMenu()` already has: menu reachability required, shortcuts a chosen subset. **Not** done inside 123, which would confuse two changes | Sizes are rough: XS under an hour, S a sitting, M a session. @@ -998,61 +1003,35 @@ likely to have drifted, since both enumerate things that have been added to. ## 123. Sending mail is not designed -**Observed (user, from the notes):** "we should start brainstorming sending -emails. Most of the open issues are UX. #v2 #plan-only #new-branch". - -**Not a defect and not implementation work.** The note tags it `#plan-only`, and -this repo's own scope statement agrees: `CLAUDE.md` records that v1 is -read-and-organize only and that compose and send are v2. Recorded here so the -backlog stops being silent about the largest thing the user has written down. - -**What it blocks.** Item 72 (khard/khal) is explicitly placed after send by the -user's own note, and cannot be specified before it. The completion machinery -that would serve recipient completion already exists as `QueryCompleter`, and -the `QLineEdit::setCompleter` trap in `CLAUDE.md` applies directly to any -multi-recipient field, so there is prior art to reuse rather than a blank page. - -**What it does NOT change.** The architecture note that this application does -**no network protocol work at all** is load-bearing: fetching is `mbsync` via -`assets/mailsync.sh`, and sending should be an external script on the same -model, not an SMTP client written here. A design that puts a socket in this -process is out of scope regardless of how the UI turns out. - -**What exists on this machine, measured 2026-08-20, because the sentence above -assumes something that is not there.** "Sending should be an external script on -the same model" is easy to write and there is no such model to copy: the fetch -side has `mbsync`, and the send side has NOTHING. - -- No MTA is installed at all. `msmtp` and `sendmail` are both absent. -- neomutt sends over its OWN built-in SMTP, configured per account - (`smtp_url` and `smtp_pass` in `~/.config/neomutt/accounts/*.rc`), so the - working setup this application mirrors has no external send path either. -- All five accounts already configure a `drafts` folder, so the draft half has - somewhere to live before anything is decided. - -That is the first question for the user, and it is not a UX one: sending needs -either an MTA they choose to install and configure (msmtp being the obvious -one, and the only shape that keeps the no-network-protocol rule intact), or a -decision to relax that rule. Do not assume the first just because it is -tidier; installing and configuring an MTA is work they have not asked for, and -the credentials already exist in neomutt's files. - -**Approach.** Brainstorm first, on its own branch, producing a spec under -`docs/superpowers/specs/` before any code. The open questions are all UX, as the -note says: where a composer lives, how a draft is stored so `notmuch` can see -it, what reply and forward do to the thread the user is looking at, and how a -queued message reaches the sending script. - -**Constraints.** - -- **Ask the user before designing.** They have not said what they pictured, and - this is the item where guessing costs the most. -- Drafts are already visible to the app: item 67 counts them in the placeholder - pane, so a draft folder is configured and indexed. -- `#new-branch` is the user's own tag on it. - -**Size: `?`** until the brainstorm has happened. It is the largest open item by -some distance. +**Specified 2026-08-20.** Read +`docs/superpowers/specs/2026-08-20-compose-and-send-design.md` instead of this +section. Brainstormed with the user on branch `compose-and-send`; no code +written, which is what the note's `#plan-only` asked for. + +**The three constraints a reader needs before opening the spec.** + +- **There is no MTA on this machine**, measured 2026-08-20. `msmtp` and + `sendmail` are both absent, and neomutt sends over its own built-in SMTP. So + "an external script on the same model as `mailsync.sh`" had no model to copy. + The design keeps the no-network-protocol rule by making send a **per-account + `send_command`** taking the message on stdin, exactly as `[sync] command` + works. What the user installs behind it is their choice. +- **An account with no `send_command` is receive-only by construction**, which + is how one of the five accounts is meant to work. Reply, reply-all and forward + are disabled on its mail, with a ribbon in the message pane saying why. +- **The body is markdown**, parsed by cmark-gfm (autolink, strikethrough, + tasklist; tables off), sent as `multipart/alternative` or plain text per a + per-message toggle. A hand-written parser for a limited set was rejected + because it would be deleted wholesale the moment the set widened. + +**What it blocks and what it opened.** Item 72 (khard/khal) is placed after send +by the user's own note. The brainstorm opened items 128 to 132: an outbox, +inline images, attaching a message to a message, a configurable markdown +dialect, and a review of the every-action-has-a-shortcut rule. + +**Size: L.** Four new units, six new actions, and a new dependency +(`cmark-gfm`, already installed here, and a `REQUIRES` entry for the +SlackBuild). ## 125. A skipped sync leaves the spinner running for ever |
