| Age | Commit message (Collapse) | Author | Files | Lines |
|
The previous commit, the spec and the plan all said notmuch exits 0 on a
malformed query while printing something that is not a count, and that
validating the output as an integer therefore catches it. Measured properly,
that is wrong in a way worth recording, because the truth is worse.
notmuch fails two different ways. A rejected query prints nothing and exits 1:
`notmuch count 'tag:unread and ('`. A query Xapian merely misparses returns a
plausible wrong number and exits 0: `notmuch count 'tag:unread and (('` gives
41, and `'tag:unread and tag:'` gives 3. The second is undetectable by any
check on the output, which is why the original claim was not just imprecise
but inverted: the case it described as caught is the case nothing can catch.
The integer validation still earns its place, on the first failure mode, where
empty output would otherwise render as an empty inbox. The real defence
against the second is that QUERY is a fixed string and is never built from
anything, which the comment now says.
The earlier measurement that produced the wrong claim read 40 as mangled
output when it was a successful parse answering a different question.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WWL8JYHu7yhAdtx5pU9PMU
|
|
Seven tasks, ordered so the thing most likely to be wrong is checked first.
The watcher script comes before any QML because it is the only piece with a
real runnable check and needs no compositor. The component skeleton gets its
own commit because the failure it guards against is invisible: a config whose
only window is hidden exits straight after logging Configuration Loaded and
reports no error.
Two decisions changed while reading the existing components. The drawer is a
fullscreen overlay with content anchored top right, which is the idiom both
other panels use and what gives click-outside and Escape for free, rather
than a small anchored window. And its exclusionMode is Normal rather than the
Ignore those two use, so waybar's exclusive zone places it below the bar
without this component carrying the bar's 42px height as a constant to drift.
Also records a trap measured this session: notmuch exits 0 even for a
malformed query, printing something that is not a count, so every count is
validated as an integer rather than trusting the exit status. A failure that
rendered as 0 would look exactly like an empty inbox.
The live-config task needs real absolute paths, because waybar's exec and
Hyprland's Lua strings do not expand a tilde. They are written as <repo> and
<home> placeholders with a note to substitute, since the gitleaks hook blocks
committed home paths and was right to reject the first attempt.
The spec was updated to match both changes.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WWL8JYHu7yhAdtx5pU9PMU
|
|
qtmaildir scopes an account with a path glob, so the obvious move was to copy
that query. It is wrong for this panel. notmuch deduplicates by message id, so
a message that arrived at two configured addresses is one message with two
paths, and a path glob counts it under both accounts: the five accounts here
sum to 102 against a global total of 101.
The icon shows one global total and the panel header repeats it, so rows that
sum to a different number would look like a bug. Counting by the account tag,
which is a property of the message and therefore singular, makes the rows sum
to the header. The cost is that a cross posted message appears under only the
account the post-new hook attributed it to.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WWL8JYHu7yhAdtx5pU9PMU
|
|
Replaces three waybar modules that each poll the Gmail API through a python
script with its own credentials file, cover three of five accounts, and open
Thunderbird. Everything they fetch over the network is already in the local
notmuch index, tagged per account.
Two decisions carry most of the design. Counts are scoped to
"tag:unread and tag:inbox" rather than plain "tag:unread", which for one
account is the difference between 32 and 41, because the inbox number is the
one that means new mail worth looking at. And the waybar module runs in
continuous mode with an inotifywait loop, so waybar owns the watcher process
and there is no daemon to supervise on a machine with no systemd; the watch is
on the xapian directory rather than on named files because a commit replaces
them, which breaks a watch held on a file.
The account list is not in the component. qtmaildir.conf already has one
[account.<key>] section per account, where <key> is the notmuch tag suffix,
carrying a display label and a colour, so the panel parses that and a new
account appears without touching QML.
Thread level actions are out of scope because they are blocked rather than
deferred: qtmaildir takes no arguments, so nothing can tell it which thread
to open.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WWL8JYHu7yhAdtx5pU9PMU
|