CHANGELOG
=========

v0.4.0 (2026-03-05)
--------------------
- Add split_mbox_as_bytes() and split_and_dedupe_as_bytes() for
  working with raw message bytes without invoking the email parser.
  The regular split_mbox() and split_and_dedupe() now wrap these
  functions, so the splitting logic is shared.

- The bytes-level deduplication extracts Message-ID and List-Id
  headers directly from raw bytes using lightweight line scanning,
  avoiding the cost of full message parsing.

v0.3.1 (2026-03-04)
--------------------
- Lower minimum Python version from 3.11 to 3.9. The codebase already
  uses ``from __future__ import annotations`` everywhere, so no code
  changes were required.

- Clean up unused imports in test_formatting.py.

v0.3.0 (2026-03-04)
--------------------
- Add email serialization utilities ported from b4/bugspray:
  format_addrs(), wrap_header(), get_msg_as_bytes(). These replace
  Python's buggy as_bytes() with battle-tested RFC 2047 header
  encoding and line wrapping.

- Add minimize_thread() for creating compact thread views by
  stripping excessive quoting, multi-level quotes, and non-essential
  headers. Messages containing diffs/diffstats are preserved as-is.
  Accepts an optional keep_headers parameter for customizing which
  headers to retain. Compliant email signatures are split off before
  processing so trailing quoted blocks before a signature are
  correctly recognised and dropped.

- Add optional message authentication (DKIM, DMARC, ARC) via the
  authheaders library. Enable with LoreNode(add_auth_headers=True).
  Install the optional dependency with: pip install liblore[auth].

- Add reduce_quote_context option to minimize_thread() for more
  aggressive quote reduction: long quoted blocks preceding a reply
  are trimmed to just the last paragraph, with earlier content
  replaced by a "> [... skip NN lines ...]" marker. Only kicks in
  when more than 5 lines would be skipped.

v0.2.0 (2026-03-03)
--------------------
- Fix thread update fetching to use the per-message search endpoint
  (/{msgid}/?x=m&q=dt:{since}..) instead of a global query with
  mid:{msgid}. This scopes the search to the correct thread and
  filters by Date header (dt:) instead of commit date (d:).

- Fix get_mbox_by_query() to POST 'x=m' as request body, ensuring
  the server returns mbox format.

- Add get_thread_updates_since() convenience method for checking
  whether a thread has new messages. Accepts a datetime object and
  returns an empty list when there are no updates, making it easy
  to poll for changes. Uses the rt: (Received header) search prefix
  with epoch timestamps for reliable server-side date filtering.

- Refactor get_thread_by_msgid() to use GET /{msgid}/t.mbox.gz for
  full thread fetches (no since parameter), avoiding unnecessary
  query overhead.

v0.1.0 (2025-08-15)
--------------------
- Initial release.
- LoreNode class for interacting with public-inbox servers.
- Thread fetching by message ID and by search query.
- Single message fetching by message ID.
- Batch operations with rate limiting.
- Strict thread filtering and sort-by-received support.
- Configurable User-Agent and external session injection.
- Server validation via HEAD request to help endpoint.
