95a65d0
fix(update): check file close errors (#1336)
Click to expand commit body
## What?
Checks file close errors during the update download and extraction flow.
The updater now handles `Close()` errors after writing the downloaded
release asset and after extracting binaries from `.tar.gz` and `.zip`
archives. Cleanup closes in error paths are explicitly ignored so they
do not mask the original copy error.
## Why?
Closes #716.
Some write failures can surface only when a file is closed. Ignoring
`Close()` could let the updater continue with an incomplete or unflushed
asset or extracted binary.
---------
Co-authored-by: FromSi <fromsi665@gmail.com>
## What?
Handles previously ignored daemon startup errors in `daemon/daemon.go`:
- checks `os.Remove` when cleaning up a stale daemon socket, while
ignoring `os.IsNotExist`
- checks `os.Chmod` when setting daemon socket permissions
- wraps both failures with contextual error messages
## Why?
Closes #714
Closes #719
Ignoring these errors could either hide stale socket cleanup failures,
leading to confusing daemon startup errors, or leave the daemon socket
with unintended permissions if `chmod` failed. Returning explicit errors
makes startup failures clearer and keeps socket permissions handling
safer.
---------
Co-authored-by: FromSi <fromsi665@gmail.com>
## What?
Logs write and close errors when writing debug image protocol output to
files.
The debug logger now wraps `WriteString` and `Close` calls for both
`DEBUG_IMAGE_PROTOCOL_LOG` and `DEBUG_KITTY_LOG`, while keeping the
existing `os.OpenFile` security lint annotations.
## Why?
Closes #751.
Ignoring file write and close errors can hide failures in debug logging
and make image protocol issues harder to diagnose. Logging these errors
through `loglevel.Debugf` keeps failures visible without changing normal
runtime behavior.
---------
Co-authored-by: FromSi <fromsi665@gmail.com>
Md Mushfiqur Rahim
and
FromSi
created
2c0a165
fix(plugin): check test assertions (#1338)
Click to expand commit body
## What?
Adds `ok` checks to Lua type assertions in HTTP plugin tests.
The tests now fail with descriptive `t.Fatalf` messages when values have
unexpected types instead of panicking.
## Why?
Closes #721.
Unchecked type assertions in tests can produce noisy panics that hide
the actual mismatch. Explicit checks make failures clearer and easier to
debug.
## What?
- remove the hard 50-message minimum chunk size in `FetchMailboxEmails`
- add a TLS IMAP recorder regression that verifies `limit=5` fetches
only `96:100` from a 100-message mailbox
## Why?
When callers request a small page, the fetcher should not over-fetch 50
messages before filtering and trimming. This keeps IMAP bandwidth and
server load proportional to the requested limit.
Fixes #1106
## What?
Removes the option to configure per-account settings in general
## Why?
This can already be achieved by going into the account settings. Doesn't
need another menu for it
Signed-off-by: drew <me@andrinoff.com>
## What?
Shows unread email counts next to folder names in the sidebar.
## Why?
Folder list showed folder names only, making it impossible to see which
folders have unread mail without opening each one.
This improves navigation efficiency.
Closes #645
---------
Signed-off-by: drew <me@andrinoff.com>
Co-authored-by: drew <me@andrinoff.com>
## What?
This PR contains the following updates:
| Package | Type | Update | Change |
|---|---|---|---|
|
[actions/github-script](https://redirect.github.com/actions/github-script)
| action | major | `v7` → `v9` |
---
### Release Notes
<details>
<summary>actions/github-script (actions/github-script)</summary>
###
[`v9.0.0`](https://redirect.github.com/actions/github-script/releases/tag/v9.0.0)
[Compare
Source](https://redirect.github.com/actions/github-script/compare/v9.0.0...v9.0.0)
**New features:**
- **`getOctokit` factory function** — Available directly in the script
context. Create additional authenticated Octokit clients with different
tokens for multi-token workflows, GitHub App tokens, and cross-org
access. See [Creating additional clients with
`getOctokit`](https://redirect.github.com/actions/github-script#creating-additional-clients-with-getoctokit)
for details and examples.
- **Orchestration ID in user-agent** — The `ACTIONS_ORCHESTRATION_ID`
environment variable is automatically appended to the user-agent string
for request tracing.
**Breaking changes:**
- **`require('@​actions/github')` no longer works in scripts.**
The upgrade to `@actions/github` v9 (ESM-only) means
`require('@​actions/github')` will fail at runtime. If you
previously used patterns like `const { getOctokit } =
require('@​actions/github')` to create secondary clients, use the
new injected `getOctokit` function instead — it's available directly in
the script context with no imports needed.
- `getOctokit` is now an injected function parameter. Scripts that
declare `const getOctokit = ...` or `let getOctokit = ...` will get a
`SyntaxError` because JavaScript does not allow `const`/`let`
redeclaration of function parameters. Use the injected `getOctokit`
directly, or use `var getOctokit = ...` if you need to redeclare it.
- If your script accesses other `@actions/github` internals beyond the
standard `github`/`octokit` client, you may need to update those
references for v9 compatibility.
##### What's Changed
- Add ACTIONS\_ORCHESTRATION\_ID to user-agent string by
[@​Copilot](https://redirect.github.com/Copilot) in
[#​695](https://redirect.github.com/actions/github-script/pull/695)
- ci: use deployment: false for integration test environments by
[@​salmanmkc](https://redirect.github.com/salmanmkc) in
[#​712](https://redirect.github.com/actions/github-script/pull/712)
- feat!: add getOctokit to script context, upgrade
[@​actions/github](https://redirect.github.com/actions/github) v9,
[@​octokit/core](https://redirect.github.com/octokit/core) v7, and
related packages by
[@​salmanmkc](https://redirect.github.com/salmanmkc) in
[#​700](https://redirect.github.com/actions/github-script/pull/700)
##### New Contributors
- [@​Copilot](https://redirect.github.com/Copilot) made their
first contribution in
[#​695](https://redirect.github.com/actions/github-script/pull/695)
**Full Changelog**:
<https://github.com/actions/github-script/compare/v8.0.0...v9.0.0>
###
[`v9`](https://redirect.github.com/actions/github-script/compare/v8.0.0...v9.0.0)
[Compare
Source](https://redirect.github.com/actions/github-script/compare/v8.0.0...v9.0.0)
###
[`v8.0.0`](https://redirect.github.com/actions/github-script/compare/v8.0.0...v8.0.0)
[Compare
Source](https://redirect.github.com/actions/github-script/compare/v8.0.0...v8.0.0)
###
[`v8`](https://redirect.github.com/actions/github-script/releases/tag/v8):
.0.0
[Compare
Source](https://redirect.github.com/actions/github-script/compare/v7.1.0...v8.0.0)
##### What's Changed
- Update Node.js version support to 24.x by
[@​salmanmkc](https://redirect.github.com/salmanmkc) in
[#​637](https://redirect.github.com/actions/github-script/pull/637)
- README for updating actions/github-script from v7 to v8 by
[@​sneha-krip](https://redirect.github.com/sneha-krip) in
[#​653](https://redirect.github.com/actions/github-script/pull/653)
##### ⚠️ Minimum Compatible Runner Version
**v2.327.1**\
[Release
Notes](https://redirect.github.com/actions/runner/releases/tag/v2.327.1)
Make sure your runner is updated to this version or newer to use this
release.
##### New Contributors
- [@​salmanmkc](https://redirect.github.com/salmanmkc) made their
first contribution in
[#​637](https://redirect.github.com/actions/github-script/pull/637)
- [@​sneha-krip](https://redirect.github.com/sneha-krip) made
their first contribution in
[#​653](https://redirect.github.com/actions/github-script/pull/653)
**Full Changelog**:
<https://github.com/actions/github-script/compare/v7.1.0...v8.0.0>
###
[`v7.1.0`](https://redirect.github.com/actions/github-script/releases/tag/v7.1.0)
[Compare
Source](https://redirect.github.com/actions/github-script/compare/v7.0.1...v7.1.0)
##### What's Changed
- Upgrade husky to v9 by
[@​benelan](https://redirect.github.com/benelan) in
[#​482](https://redirect.github.com/actions/github-script/pull/482)
- Add workflow file for publishing releases to immutable action package
by [@​Jcambass](https://redirect.github.com/Jcambass) in
[#​485](https://redirect.github.com/actions/github-script/pull/485)
- Upgrade IA Publish by
[@​Jcambass](https://redirect.github.com/Jcambass) in
[#​486](https://redirect.github.com/actions/github-script/pull/486)
- Fix workflow status badges by
[@​joshmgross](https://redirect.github.com/joshmgross) in
[#​497](https://redirect.github.com/actions/github-script/pull/497)
- Update usage of `actions/upload-artifact` by
[@​joshmgross](https://redirect.github.com/joshmgross) in
[#​512](https://redirect.github.com/actions/github-script/pull/512)
- Clear up package name confusion by
[@​joshmgross](https://redirect.github.com/joshmgross) in
[#​514](https://redirect.github.com/actions/github-script/pull/514)
- Update dependencies with `npm audit fix` by
[@​joshmgross](https://redirect.github.com/joshmgross) in
[#​515](https://redirect.github.com/actions/github-script/pull/515)
- Specify that the used script is JavaScript by
[@​timotk](https://redirect.github.com/timotk) in
[#​478](https://redirect.github.com/actions/github-script/pull/478)
- chore: Add Dependabot for NPM and Actions by
[@​nschonni](https://redirect.github.com/nschonni) in
[#​472](https://redirect.github.com/actions/github-script/pull/472)
- Define `permissions` in workflows and update actions by
[@​joshmgross](https://redirect.github.com/joshmgross) in
[#​531](https://redirect.github.com/actions/github-script/pull/531)
- chore: Add Dependabot for .github/actions/install-dependencies by
[@​nschonni](https://redirect.github.com/nschonni) in
[#​532](https://redirect.github.com/actions/github-script/pull/532)
- chore: Remove .vscode settings by
[@​nschonni](https://redirect.github.com/nschonni) in
[#​533](https://redirect.github.com/actions/github-script/pull/533)
- ci: Use github/setup-licensed by
[@​nschonni](https://redirect.github.com/nschonni) in
[#​473](https://redirect.github.com/actions/github-script/pull/473)
- make octokit instance available as octokit on top of github, to make
it easier to seamlessly copy examples from GitHub rest api or octokit
documentations by
[@​iamstarkov](https://redirect.github.com/iamstarkov) in
[#​508](https://redirect.github.com/actions/github-script/pull/508)
- Remove `octokit` README updates for v7 by
[@​joshmgross](https://redirect.github.com/joshmgross) in
[#​557](https://redirect.github.com/actions/github-script/pull/557)
- docs: add "exec" usage examples by
[@​neilime](https://redirect.github.com/neilime) in
[#​546](https://redirect.github.com/actions/github-script/pull/546)
- Bump ruby/setup-ruby from 1.213.0 to 1.222.0 by
[@​dependabot](https://redirect.github.com/dependabot)\[bot] in
[#​563](https://redirect.github.com/actions/github-script/pull/563)
- Bump ruby/setup-ruby from 1.222.0 to 1.229.0 by
[@​dependabot](https://redirect.github.com/dependabot)\[bot] in
[#​575](https://redirect.github.com/actions/github-script/pull/575)
- Clearly document passing inputs to the `script` by
[@​joshmgross](https://redirect.github.com/joshmgross) in
[#​603](https://redirect.github.com/actions/github-script/pull/603)
- Update README.md by
[@​nebuk89](https://redirect.github.com/nebuk89) in
[#​610](https://redirect.github.com/actions/github-script/pull/610)
##### New Contributors
- [@​benelan](https://redirect.github.com/benelan) made their
first contribution in
[#​482](https://redirect.github.com/actions/github-script/pull/482)
- [@​Jcambass](https://redirect.github.com/Jcambass) made their
first contribution in
[#​485](https://redirect.github.com/actions/github-script/pull/485)
- [@​timotk](https://redirect.github.com/timotk) made their first
contribution in
[#​478](https://redirect.github.com/actions/github-script/pull/478)
- [@​iamstarkov](https://redirect.github.com/iamstarkov) made
their first contribution in
[#​508](https://redirect.github.com/actions/github-script/pull/508)
- [@​neilime](https://redirect.github.com/neilime) made their
first contribution in
[#​546](https://redirect.github.com/actions/github-script/pull/546)
- [@​nebuk89](https://redirect.github.com/nebuk89) made their
first contribution in
[#​610](https://redirect.github.com/actions/github-script/pull/610)
**Full Changelog**:
<https://github.com/actions/github-script/compare/v7...v7.1.0>
###
[`v7.0.1`](https://redirect.github.com/actions/github-script/releases/tag/v7.0.1)
[Compare
Source](https://redirect.github.com/actions/github-script/compare/v7...v7.0.1)
##### What's Changed
- Avoid setting `baseUrl` to undefined when input is not provided by
[@​joshmgross](https://redirect.github.com/joshmgross) in
[#​439](https://redirect.github.com/actions/github-script/pull/439)
**Full Changelog**:
<https://github.com/actions/github-script/compare/v7.0.0...v7.0.1>
</details>
## Why?
Automated dependency update via Renovate.
---
### Configuration
📅 **Schedule**: (UTC)
- Branch creation
- At any time (no schedule defined)
- Automerge
- At any time (no schedule defined)
🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.
♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.
🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.
---
---
- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box
---
This PR has been generated by [Mend
Renovate](https://redirect.github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xOTUuMCIsInVwZGF0ZWRJblZlciI6IjQzLjE5NS4wIiwidGFyZ2V0QnJhbmNoIjoibWFzdGVyIiwibGFiZWxzIjpbImRlcGVuZGVuY2llcyJdfQ==-->
## What?
This PR contains the following updates:
| Package | Type | Update | Change |
|---|---|---|---|
|
[greenmail/standalone](https://redirect.github.com/greenmail-mail-test/greenmail/blob/master/greenmail-docker/standalone)
([source](https://redirect.github.com/greenmail-mail-test/greenmail)) |
service | patch | `2.1.3` → `2.1.8` |
---
### Release Notes
<details>
<summary>greenmail-mail-test/greenmail (greenmail/standalone)</summary>
###
[`v2.1.8`](https://redirect.github.com/greenmail-mail-test/greenmail/compare/release-2.1.7...release-2.1.8)
[Compare
Source](https://redirect.github.com/greenmail-mail-test/greenmail/compare/release-2.1.7...release-2.1.8)
###
[`v2.1.7`](https://redirect.github.com/greenmail-mail-test/greenmail/compare/release-2.1.6...release-2.1.7)
[Compare
Source](https://redirect.github.com/greenmail-mail-test/greenmail/compare/release-2.1.6...release-2.1.7)
###
[`v2.1.6`](https://redirect.github.com/greenmail-mail-test/greenmail/compare/release-2.1.5...release-2.1.6)
[Compare
Source](https://redirect.github.com/greenmail-mail-test/greenmail/compare/release-2.1.5...release-2.1.6)
###
[`v2.1.5`](https://redirect.github.com/greenmail-mail-test/greenmail/compare/release-2.1.4...release-2.1.5)
[Compare
Source](https://redirect.github.com/greenmail-mail-test/greenmail/compare/release-2.1.4...release-2.1.5)
###
[`v2.1.4`](https://redirect.github.com/greenmail-mail-test/greenmail/compare/release-2.1.3...release-2.1.4)
[Compare
Source](https://redirect.github.com/greenmail-mail-test/greenmail/compare/release-2.1.3...release-2.1.4)
</details>
## Why?
Automated dependency update via Renovate.
---
### Configuration
📅 **Schedule**: (UTC)
- Branch creation
- At any time (no schedule defined)
- Automerge
- At any time (no schedule defined)
🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.
♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.
🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.
---
---
- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box
---
This PR has been generated by [Mend
Renovate](https://redirect.github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xOTUuMCIsInVwZGF0ZWRJblZlciI6IjQzLjE5NS4wIiwidGFyZ2V0QnJhbmNoIjoibWFzdGVyIiwibGFiZWxzIjpbImRlcGVuZGVuY2llcyJdfQ==-->
## What?
Regenerates `gomod2nix.toml` to reflect the current `go.mod` / `go.sum`.
## Why?
Keeps the Nix build in sync with Go module changes. Without this, `nix
build` fails when new or upgraded Go deps are missing from
`gomod2nix.toml`. Generated automatically by the gomod2nix sync
workflow.
Floatpane Bot
created
3665262
chore: bump to avoid vulnerabilities (#1350)
f7725b5
fix: better integration, more tests (#1349)
Click to expand commit body
## What?
Add five new CI capabilities and harden the existing failure notifier.
**New workflows**
- `.github/workflows/security.yml` — govulncheck, gosec (SARIF upload),
trivy fs+config scan, CodeQL with `security-extended` queries.
- `.github/workflows/benchmarks.yml` — benchstat PR-vs-base comparison;
idempotent PR comment classifies result as regression / improvement /
neutral at ±3% threshold; posts as the bot identity via
`HOMEBREW_GITHUB_TOKEN`.
- `.github/workflows/integration.yml` — three jobs:
- **imap + smtp e2e**: spins up Greenmail as a service container, runs
real IMAPS/SMTPS tests against the `backend.Provider` interface.
- **cross-platform**: race-enabled `go test -race ./...` matrix across
linux/macos/windows.
- **fuzz**: auto-discovers every `func Fuzz*` and runs each for 30s.
**New tests / configs**
- `.golangci.yml` — version 2 config enabling 30+ linters (`errcheck`,
`govet`, `gosec`, `revive`, `gocritic`, `bodyclose`, `errorlint`, …)
with sensible per-path exclusions.
- `.github/workflows/ci.yml` — lint job now also runs `golangci-lint`
with the integration build tag.
- `tui/snapshot_test.go` + `tui/testdata/golden/*.txt` — ANSI-stripped
golden snapshots for `LogPanel` and `SearchOverlay` (empty / populated /
truncated / loading / error). Refresh with `go test ./tui -update`.
- `backend/search_bench_test.go` + `tui/render_bench_test.go` —
benchmarks for query parsing, tokenizer, log panel render, search
overlay render, inbox construction.
- `tests/integration/` — Go integration suite gated by `//go:build
integration`, plus a `docker-compose.yml` for running Greenmail locally.
**Failure notifier upgrades**
- Now fires on `master` pushes as well as PRs.
- PR → `REQUEST_CHANGES` review (existing behavior).
- master → opens a labeled `ci-failure` issue and drops a commit comment
on the merge SHA; dedupes repeated failures into the same issue.
- master + success → auto-closes prior bot-authored `ci-failure` issues
with a link to the passing run.
- Downloads the workflow log archive, parses it with `adm-zip`, and
extracts:
- failing Go packages (`FAIL\s+pkg/path`),
- failing test names (`--- FAIL: TestName`),
- build errors (`file.go:line:col: msg`).
- Per-job fix hints expanded: `make lint`, `go mod tidy`, `nix flake
check`, snap/flatpak validators, `goreleaser check`, `govulncheck`,
`docker compose -f tests/integration/docker-compose.yml up -d`, `go test
-fuzz=…`, etc.
## Why?
Makes it easier to detect issues with PRs
---------
Signed-off-by: drew <me@andrinoff.com>
Drew Smirnoff
created
50e2b81
fix(plugin): add URL format validation (#1341)
Click to expand commit body
## What?
Added url.Parse() call before scheme validation in plugin HTTP handler
to catch malformed URLs early and return a clear error to the Lua
script.
## Why?
Fixes #753.
## What?
Changes the test assertion due to #1329 changing the output to have
`info: ` in front of it. Due to the PR not being rebased to have the
#1316 commit.
## Why?
Tests fail.
Signed-off-by: drew <me@andrinoff.com>
## What?
Added an optional in-TUI log panel enabled with `--logs`. The panel is
backed by a small in-memory logger buffer and renders the latest log
entries at the bottom of the TUI without overwriting the active view.
The main TUI layout now reserves space for the log panel when it is
enabled, so the current screen receives a reduced height instead of
being drawn under the logs. The visual log panel itself lives in
`tui/log_panel.go`.
Also updated `internal/loglevel` so logs written through it are
consistently prefixed:
- `debug:`
- `verbose:`
- `info:`
Added `make run-log`, which starts Matcha with both debug logging and
the in-TUI log panel enabled:
```bash
make run-log
```
<img width="1400" height="800" alt="view"
src="https://github.com/user-attachments/assets/3325e34c-8b62-40b8-8642-fccb7b24615c"
/>
## Why?
While reviewing recent PRs, I noticed it was hard to observe logs
cleanly in the TUI. Logs written through `log.Printf` or
`internal/loglevel` could appear over the Bubble Tea screen, or required
redirecting stderr to a separate file.
This gives us a simple way to inspect runtime logs directly inside
Matcha while testing behavior such as TLS resumption, plugin loading,
background fetches, and other debug/verbose paths.
I did not search for an existing issue for this.
## What?
This PR contains the following updates:
| Package | Change |
[Age](https://docs.renovatebot.com/merge-confidence/) |
[Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [golang.org/x/crypto](https://pkg.go.dev/golang.org/x/crypto) |
[`v0.51.0` →
`v0.52.0`](https://cs.opensource.google/go/x/crypto/+/refs/tags/v0.51.0...refs/tags/v0.52.0)
|

|

|
## Why?
Automated dependency update via Renovate.
---
### Configuration
📅 **Schedule**: (UTC)
- Branch creation
- At any time (no schedule defined)
- Automerge
- At any time (no schedule defined)
🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.
♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.
🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.
---
---
- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box
---
This PR has been generated by [Mend
Renovate](https://redirect.github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xOTEuMiIsInVwZGF0ZWRJblZlciI6IjQzLjE5MS4yIiwidGFyZ2V0QnJhbmNoIjoibWFzdGVyIiwibGFiZWxzIjpbImRlcGVuZGVuY2llcyJdfQ==-->
## What?
- route image protocol debug messages through the standard logger
instead of writing directly to stdout
- add coverage that verifies debug output goes to the logger and leaves
stdout untouched
## Why?
Debug output should respect the application logging path instead of
bypassing logger formatting and destinations.
Fixes #701
## What?
- Wrap the JSON parser source error with `%w` instead of rendering it
with `%v`.
- Add regression coverage that preserves both `ErrParseFailed` and the
original `json.SyntaxError` in the error chain.
Closes #1050
## Why?
The i18n parser already wraps `ErrParseFailed`, but the underlying JSON
parse error was converted to text. That made `errors.As` unable to
recover the original cause from callers that need to inspect it.
## What?
`findAttachmentData` in `backend/pop3/pop3.go` had three error sites
that dropped underlying context:
- `gomail.CreateReader` returned an error but the wrapping call
discarded it with a static `"not a multipart message"` string.
- The `mr.NextPart()` loop broke on a non-EOF error without saving it,
so the final return at the bottom of the function reported "not found"
instead of the real read failure.
- The not-found error had no count of how many parts the loop actually
scanned, which made the failure hard to debug from a log line alone.
This PR wraps the `CreateReader` error with `%w`, captures the
`NextPart` error in a local `scanErr` and surfaces it as the final error
when it is set, and includes the scanned-parts count in the not-found
message.
## Why?
Fixes #688. The reporter noted the missing `%w` wrapping at the original
line 438. While poking at that site I noticed the silent `break` on
`mr.NextPart()` errors right above it. Those two paths share the same
downstream "not found" return, so a multipart parse error in the middle
of the stream looks identical to a genuinely missing part. The third
change (scanned-parts count) is the smallest possible nudge that makes
the two failure modes distinguishable in an error string without
changing the return type or call sites.
Fixes #688
## What?
- Add a shared quoted-printable writer helper that returns write and
close errors.
- Use it for plaintext-only and multipart text/html message parts.
- Add regression coverage for a failing quoted-printable flush.
Closes #614
## Why?
Ignoring `quotedprintable.Writer.Close()` can let email composition
continue with an incomplete or corrupted encoded body.
## What?
Handles `esc` in split view screen to close the split view, instead of
returning to the home screen.
## Why?
Closes #1313
Signed-off-by: drew <me@andrinoff.com>
## What?
Adds two global CLI flags for log verbosity:
- `--verbose` / `-V` raises the log level to verbose, which emits a
`matcha: loaded config with N account(s)` line once config loads.
Reserved for additional sites later.
- `--debug` raises the log level to debug, which enables the two
existing `debug:` log lines in the email-body cache path so they only
fire when explicitly requested.
A small `internal/loglevel` package holds the level state and the
`Debugf` / `Verbosef` / `Infof` helpers. Level state is
`sync/atomic`-backed so concurrent goroutines stay race-clean. The two
pre-existing `debug:` log sites in `main.go` are routed through
`loglevel.Debugf`.
The existing `-v` / `--version` short-circuit is preserved unchanged.
`--verbose` uses `-V` (capital) as its short form to avoid colliding
with `--version`.
Flags are parsed before subcommand dispatch by a small
`parseGlobalFlags` helper that strips them from `os.Args` so subcommand
parsers don't see them.
Documented in README under a new "Logging" section.
Unit tests cover the level-gating contract: Debugf/Verbosef/Infof each
fire only at their level or higher.
## Why?
Closes #576.
Today there is no way to control matcha's log verbosity from the CLI.
The repo has 106 `log.Printf` call sites, two of which already include a
`debug:` prefix that runs unconditionally. The issue asked for
`--verbose` / `--debug` flags to gate that output. This PR is the
smallest change that wires the flags through a level helper without
re-classifying every existing log line - that broader cleanup can happen
incrementally.
Default behavior is unchanged: 104 `log.Printf` calls still fire at the
default level. Only the two existing `debug:`-prefixed lines and the new
`Verbosef` config-load line are gated.
---------
Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
## What?
Added recipient validation in the composer for `To`, `Cc`, and `Bcc`
fields.
- Validate email fields with `mail.ParseAddress()` when leaving a
recipient field.
- Normalize display-name addresses to plain email addresses after
validation.
- Clear inline validation errors when the user edits the field again.
- Block sending when recipient fields are invalid or when no recipients
are provided.
- Show a composer notice for send-time validation problems.
- Added i18n keys for invalid recipient errors.
<img width="1400" height="800" alt="view"
src="https://github.com/user-attachments/assets/aa69d838-b5ab-48cf-ba89-bab79d1f69c6"
/>
## Why?
This prevents confusing SMTP failures caused by invalid recipient input
and gives users immediate feedback inside the composer.
Closes #648
Closes #734
---------
Signed-off-by: drew <me@andrinoff.com>
Co-authored-by: Andriy Chernov <andriy@floatpane.com>
## What?
Adds a top-level `defer func() { recover(); log }()` to
`(*Daemon).acceptLoop` so a panic in the accept goroutine logs with a
stack trace instead of taking down the whole daemon.
Closes #1119
## Why?
`daemon/daemon.go:120` launches `go d.acceptLoop()` with no panic
recovery. A panic inside the loop (or in `addClient` /
`daemonrpc.NewConn`) propagates up and the runtime aborts the process.
The sync loop, IDLE watcher, and connected clients all die with it. The
issue notes the same risk applies to the prior recovery fixes (#979 /
#980 / #981).
The recovery pattern matches the existing one at `main.go:4089`: log the
panic with a `runtime/debug.Stack()` trace and let the goroutine exit.
The daemon stops accepting new connections after a recovered panic, but
already-connected clients and the background sync loop keep running,
which is what the issue body asks for.
## What?
Added panic recovery to the async refresh goroutine in
`daemon/handler.go`.
## Why?
The goroutine had no panic recovery. A panic from any provider would
crash the entire daemon. Now it recovers and notifies subscribers
instead.
Closes #1121
## What?
Updates `flake.lock` to the latest revisions of all flake inputs
(`nixpkgs`, `flake-utils`, etc.).
## Why?
Keeps Nix inputs current so contributors and CI build against fresh
`nixpkgs`. Picks up upstream security and toolchain fixes. Generated
automatically by the flake-lock update workflow on changes to `go.sum`.
## What?
Regenerates `gomod2nix.toml` to reflect the current `go.mod` / `go.sum`.
## Why?
Keeps the Nix build in sync with Go module changes. Without this, `nix
build` fails when new or upgraded Go deps are missing from
`gomod2nix.toml`. Generated automatically by the gomod2nix sync
workflow.
## What?
Adds table-driven tests for `ParseLocale` covering:
- plain, hyphenated, and underscored English locale inputs
- fallback behavior for an unregistered language
- invalid empty and malformed locale inputs
## Why?
`ParseLocale` is a small public i18n helper with no dedicated tests. The
new tests lock down locale normalization, fallback direction, and
invalid-input behavior before more locale work is added.
Fixes #1075
supperShen
created
820ea01
feat(settings): add password meter (#1299)
Click to expand commit body
## What?
Adds real-time password feedback to the encryption settings screen.
- Shows whether the password and confirmation fields match while typing.
- Shows an informational password strength level: `weak`, `medium`, or
`strong`.
- Adds `internal/passwordstrength` with a `Meter` interface and a
`LibMeter` implementation backed by
`github.com/wagslane/go-password-validator`.
## Why?
Closes #628
Users previously only learned that password confirmation failed after
submitting the form. Inline feedback makes the encryption setup flow
clearer and helps users catch mistakes before attempting to enable
encryption.
The strength meter is informational only: weak passwords are not
rejected.
---------
Co-authored-by: Andriy Chernov <andriy@floatpane.com>
FromSi
and
Andriy Chernov
created
f7273d7
fix: skip TZID for date-only events (#1301)
Click to expand commit body
## What?
`parseEventTimestamp` now detects date-only iCalendar values
(`VALUE=DATE` or bare `YYYYMMDD`) and skips TZID re-anchoring for them.
Timed DTSTART/DTEND values with TZID keep the existing timezone
behavior.
## Why?
Closes #1058.
RFC 5545 DATE values have no timezone. Ignoring TZID for all-day events
prevents a stray TZID parameter from shifting the displayed date.
nanookclaw
created
adb6679
fix(pop3): batch delete in one session (#1292)
Click to expand commit body
POP3 batch deletion now sends requests like this:
```text
CONNECT
AUTH
UIDL
DELE 1
DELE 2
DELE 3
QUIT
```
`QUIT` is sent once at the end, so all `DELE` commands are committed in
one POP3 session.
Closes #555
Previously, batch deletion sent requests like this:
```text
CONNECT
AUTH
UIDL
DELE 1
QUIT
CONNECT
AUTH
UIDL
DELE 2
QUIT
CONNECT
AUTH
UIDL
DELE 3
QUIT
```
So deleting multiple emails repeated the full connection/authentication
cycle for every message.
Signed-off-by: drew <me@andrinoff.com>
FromSi
created
409fe1f
feat: prevent auto read and mark unread (#1298)
Click to expand commit body
## What?
Extends plugin API and adds 2 plugins for preventing auto read, and for
marking read/unread
## Why?
Closes #1240
Closes #1239
---------
Signed-off-by: drew <me@andrinoff.com>
## What?
Emited newlines outside `hyperlink()` call, link sits on single line and
works for Ghostty. And a small patch to fix split view rendering images,
when rendering was turned off.
## Why?
Ghostty terminates hyperlink region at newline boundary, so clickable
area was lost. Kitty/WezTerm carry URI across line breaks → worked
there.
Fixes #1291
---------
Signed-off-by: drew <me@andrinoff.com>
## What?
Updates the SMTP envelope sender for outgoing mail.
Matcha now uses `send_as_email` for `MAIL FROM` when it is configured.
If it is not configured, it keeps the existing fallback behavior.
This applies to regular email sending and calendar replies.
## Why?
Closes #1274
Previously, `MAIL FROM` was based on `fetch_email`, with `account.email`
as the fallback.
Now the order is:
```text
send_as_email -> fetch_email -> account.email
```
`fetch_email` is used to match incoming messages to an account. For
outgoing mail, the configured Send-As address should be used first.
## What?
Adds an `EnableDetailedDates` config option and a **General Settings**
toggle for showing detailed inbox dates. When enabled, inbox timestamps
render as absolute dates using the configured **Date Format** instead of
relative labels like “2 hours ago”.
## Why?
Closes #569
Some users prefer absolute dates in the inbox for clarity and
consistency. This enables that preference while keeping the existing
relative date behavior as the default.
---------
Co-authored-by: Andriy Chernov <andriy@floatpane.com>