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 | 90 |
1 files changed, 36 insertions, 54 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 f562e97..980aefb 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 @@ -142,14 +142,14 @@ taking that too literally. | 75 | The tagging rules window forgets its size and its column widths | persistence | S | **done** 2026-08-13, shipped in 0.17.0. The window-kind question is left open, see the closed-items file | | 76 | Every field in the rules dialog is free text, so a rule is easy to get wrong | workflow | M | **done** 2026-08-13, shipped in 0.17.0. See `specs/2026-08-13-rule-builder-design.md` | | 77 | No way to see what a rule would collect, in the thread list | workflow | S | **done** 2026-08-13, shipped in 0.17.0 | -| 78 | No way to build a rule from something visible in a message | workflow | M | open, narrowed 2026-08-14; the search half split out as item 85, which is the road a rule is made from. Revisit once 85 has been used | +| 78 | No way to build a rule from something visible in a message | workflow | S | open, narrowed 2026-08-14; the search half shipped as item 85, which is the road a rule is made from. Now a shortcut across that road: the menus and the seeded-dialog path both exist. Use 85 first and see which values are worth promoting | | 80 | A rule with many conditions squeezes the rule list to one visible row | defect | XS | **done** 2026-08-13, shipped in 0.17.0. Follows item 76 | | 79 | Opening the rules dialog and saving destroys the first rule | defect | XS | **fixed on `rule-builder`** 2026-08-13, unreleased. Shipped in 0.16.0; damaged one real rule, repaired by hand | | 81 | No way to turn a saved query into a tagging rule | workflow | S | **done** 2026-08-14, unreleased; see `specs/2026-08-14-query-to-rule-design.md` | | 82 | A saved query cannot be edited, unpinned or deleted from the UI | defect | S | **done** 2026-08-13, shipped in 0.18.0. Right-click offers Edit, Pin/Unpin and Delete | | 83 | A rule named with spaces is written to the file and dropped by every reader | defect | S | **done** 2026-08-14, unreleased. The name is sanitised into an id, save validates, a bad id loads for repair | | 84 | A config problem blocks `test_mainwindow` on a modal nobody can dismiss | testing | S | open; measured 2026-08-14, `showWarnings()` calls `QMessageBox::warning` from the constructor | -| 85 | Nothing on screen can be searched for by right-clicking it | workflow | M | open; designed 2026-08-14, see `specs/2026-08-14-search-from-message-design.md`. Split from 78; rebuilds the details dialog as rows | +| 85 | Nothing on screen can be searched for by right-clicking it | workflow | M | **done** 2026-08-14, unreleased; see `specs/2026-08-14-search-from-message-design.md`. Split from 78; rebuilt the details dialog as rows | Sizes are rough: XS under an hour, S a sitting, M a session. @@ -483,26 +483,45 @@ query look fast is a worse trade than the wait. **Observed.** The user would like to select an address or another piece of a message in the main window, right-click, and be offered a rule built from it. -**Cause.** Not a defect, unbuilt. The thread list has a context menu (item -24) and the message pane is a `QWebEngineView` whose selection is inside the -render process. - -**Approach.** Start from the thread list's own context menu, where the -sender is already a value the model holds, rather than from a text selection -in the web view. A "Create rule from sender" entry that opens the rules -dialog with the query prefilled covers the case the user described and needs -no new plumbing. - -**Constraints.** JavaScript is disabled in the profile and must stay -disabled, so reading a selection out of the web view means -`QWebEnginePage::selectedText()` and nothing that injects script. Do that -part only if the sender case turns out not to be enough. +**Cause.** Not a defect, unbuilt. + +**Narrowed 2026-08-14, and most of the work is already done.** The search half +shipped as item 85, which is the road a rule is made from: search for a value, +save the query, create a rule from the saved query. What remains here is a +SHORTCUT across that road, and both of its halves now exist. + +- The menus are built and every surface already extracts its value as a + finished query (`SearchOffer`, `src/searchterm.h`). A rule entry is another + action beside the two search ones, not new plumbing. +- The seeded-dialog path exists from item 81: + `MainWindow::showTagRulesDialog(const TagRule &seed)`. A rule from a message + becomes a second caller of it, with a different seed, which is what item 81's + spec anticipated when it made the seed a whole `TagRule` rather than a query + string. + +**Approach.** Decide it after using item 85 for a while. Which values are worth +promoting straight to a rule is a usage question, and the earlier answer to it +was wrong (see below), so it is worth having the evidence first. + +**Constraints.** The original approach here said to start from the thread +list's context menu "where the sender is already a value the model holds". +**That is false and item 85 verified it.** `ThreadSummary::authors` comes from +`notmuch_thread_get_authors` and is a DISPLAY SUMMARY, reading `Alice, Bob` or +`Alice| Bob`, so a `from:` built from it matches nothing. A real address comes +from `MessageNode::from` or `ParsedMessage::from`, neither of which the thread +list carries. Any thread-list entry needs an address resolved from a message +first. + +JavaScript is disabled in the profile and must stay disabled. Item 85 reads a +body selection with `QWebEnginePage::selectedText()`, which injects no script; +reuse that rather than adding anything. The rules file is shared with mailctl, so a rule created here must go through `TagRules` and preserve unknown fields; see "Changing the shared rule format" in CLAUDE.md. -**Size: M.** +**Size: S**, down from M now that item 85 has built the menus and item 81 the +seeded dialog. ## 84. A config problem blocks `test_mainwindow` on a modal nobody can dismiss @@ -558,43 +577,6 @@ here. **Size: S.** The diagnosis is the expensive part and it is already done. -## 85. Nothing on screen can be searched for by right-clicking it - -**Observed (2026-08-14).** The user asked, while discussing item 78, to be able -to right-click a sender, a subject, a date, a tag chip or a piece of selected -body text and be offered a search built from it, both replacing the query bar -and narrowing what is already in it. The narrowing case is the one that decides -the shape: a query returning a thousand threads is refined by adding a second -condition, and today that means retyping a query the user never typed. - -**Cause.** Not a defect, unbuilt. `MessageView` has no context menu on any -surface, and `TagStrip` paints chips with no hit test and no signals. - -**Approach.** Designed 2026-08-14. **Read -`specs/2026-08-14-search-from-message-design.md` rather than planning from this -entry.** - -Three constraints decide whether to open the spec. **This is search only, and -that is the point**: item 78's rule shortcut is deliberately left out, because a -saved query can already be promoted to a rule and searching is the missing step -on that road, as well as the safe one. **The details dialog is rebuilt as rows**, -which the user wanted anyway, and its value labels must stay explicitly -`Qt::PlainText`: the current `QPlainTextEdit` is a deliberate protection against -markup in header values that come from strangers. And **Add to search -parenthesises both sides**, because the bar may hold a hand-written `or` and -`a or b AND c` binds the wrong way, silently widening a search meant to narrow. - -**Constraints.** The thread list is out of scope and the reason is worth -keeping: a row's `authors` comes from `notmuch_thread_get_authors` and is a -display summary reading `Alice, Bob`, so a `from:` built from it matches -nothing. Item 78's own approach line assumed otherwise. - -A mis-quoted query is not an error to notmuch, it matches zero, so the quoting -helper is tested against the constructed string rather than against a provoked -failure. - -**Size: M.** - ## Deferred, unsized, or split out Items noted while triaging but not part of the original list. Same numbering |
