Repository navigation
Releases: darecstowell/LembicKit
Release list
0.5.0: every format agrees, faster range changes, safer contacts
LembicKit 0.5.0 makes every export format agree, makes scope changes fast, and closes a contacts gap in Release builds. It has no breaking API changes.
Highlights
PDF, DOCX, CSV, and XLSX now match the .txt. With a scrubber on, the prepared-record APIs can take the group roster, so Member N numbers and anonymize aliases are the same in every format of one export. Before, a group member who never wrote could shift the numbers.
Fast scope changes. The new Export.ScopeRenderer holds one conversation and renders any date range with the same output as Export.render(records:...). It runs the detectors and scrubbers once, not on each change. cancel() stops a pass in progress.
Release builds read only the real Contacts. A Release app no longer reads a bundled DemoData/contacts.vcf or the LEMBIC_CONTACTS variable, so a stray file cannot replace the user's names. Debug builds and the CLI still honor LEMBIC_CONTACTS.
Correct dates, counts, and order. A seconds-era date too large to convert is now an unknown date, not a wrong one. A 1:1 chat with more than one handle row no longer counts each message twice. Conversations with the same last date keep a stable order.
Upgrading from 0.4.0
- No code change is required. All old signatures still work.
- Recommended, if you render groups to PDF, DOCX, CSV, or XLSX: call
preparedRedactedRecords(_:conversation:labels:scope:redactions:)orunredactedPreparedRecords(_:conversation:labels:scope:). These add the roster andExport.knownNames(for:labels:)for you, asrender(_:)does. Thegroup:overloads take the roster alone. - If you re-render as the user changes a range: use
Export.ScopeRendererin place of repeatedExport.render(records:...)calls. - If you script the CLI:
lembic-cli exportnow renders throughExport.render, so note-to-self echoes drop and groups get speaker labels and a header.--sample --contactsnow reads Contacts, so a TCC prompt can show.
Also fixed
- The email ReDoS test no longer fails on a busy machine. It still catches the old slow regex.
- Internal: one module for body splices, one rule table for detectors, and one schema read per extraction. Output is byte-for-byte the same.
Every change, with details: CHANGELOG.md
0.4.0: real anonymization, stable IDs, nothing dropped silently
LembicKit 0.4.0 makes exports safer to share and harder to get wrong. Anonymize now hides real names, saved data survives renames, and no message is dropped or shown wrong without a trace. It is also much faster.
This is a pre-1.0 minor release with breaking changes. Read Upgrading from 0.3.1 before you update.
Highlights
Anonymize hides names everywhere, not only in labels. Contact, owner, and member names, and each part of them, are replaced in message text too. Enabled scrubbers also reach the header, group name, roster, labels, and event lines, so a phone number used as a group name is not left behind.
Saved data stays attached. Conversation.id is now stable (chat: plus the smallest chat.guid). A contact rename, a group rename, a member change, or a Contacts grant no longer moves it, so per-conversation settings and redactions stay with the right chat.
Redactions follow the message. A RedactionAnchor saves a keyed fingerprint of the hidden text. If the message changes, you can move the redaction or hide the whole message. A redaction that no longer fits hides the whole message: it fails closed.
Nothing leaks, nothing vanishes. Unsent text never appears. Failed sends and pending Send Later messages no longer read as sent. A damaged message is tagged [message may be incomplete], never shown as normal. Skipped rows are reported with a reason, not dropped.
More secrets flagged. New categories for ID numbers (passports, licenses, national and health IDs), recovery keys and backup codes, and Invisible Ink messages. Password and private key flags now cover the whole value.
macOS 14 works again. The schema check fails only on the core columns. A missing optional column turns off one feature, not the whole export.
Faster, same output. Secret detection is about 15 times faster on a 22,000-message thread (666 ms to 42 ms). On a 200,000-message thread, extraction drops from 4.5 s to 1.7 s and the text transcript from 1.8 s to 1.15 s.
Upgrading from 0.3.1
- Saved data keyed by
Conversation.id: look up old keys in the newConversation.legacyIDsand move the data to the newidonce. - Exhaustive
switchonSecretCategory: addidNumber,recoveryKey, andinvisibleInk. - Renamed APIs:
Export.records,Export.preparedRecords, andRendered.recordsare nowunredactedRecords,unredactedPreparedRecords, andRendered.unredactedRecords. The old names still compile, with a deprecation warning. - If you parse the output: the header now says "Messages transcript" (SMS and RCS export too), the header names its time zone, and JSONL
"d"carries the UTC offset (2026-11-01T01:10:00-06:00). - If you call the static prepared-record APIs with anonymize on: pass
Export.knownNames(for:labels:)inscope.knownNames, asrender(_:)does. Otherwise names in message text are not hidden.
Also fixed
- Old rows stored in seconds show their real date (2016, not 2000-12-31). DST fall-back hours read correctly.
- Group rosters are complete. Different groups no longer merge, and one group no longer splits when a member uses a second handle. Group events no longer tell a false story.
- Stickers, Genmoji, voice-note transcriptions, Apple Pay, polls, and other app messages render. Placeholders sit where they belong.
- Reactions on different parts of one message are counted apart.
- Non-US contacts resolve to names. Business chats keep their real id. A note to self shows each note once.
- Fewer false flags and missed secrets in the detectors and the code, email, and phone scrubbers.
Every change, with details: CHANGELOG.md
0.3.1
Patch release bundling six merged bug fixes (#5–#9, #11).
Security
- Exclude unsent/retracted (Undo Send) messages from exports (#11)
- Merge overlapping/nested redaction spans so no source text can leak (#8)
- Harden the opt-in email scrubber regex against catastrophic backtracking / ReDoS (#7)
- Stop the password and standing-code detectors from firing on ordinary prose (#5)
Fixed
- Gate the space-separated SSN form on a nearby
ssn/social securitykeyword (#6) - Region-aware phone normalization so non-US contacts resolve and union correctly (#9)
Full notes: CHANGELOG.md
0.3.0
Changed
- Removed
unsafeFlagsfrom the package manifest so LembicKit can be consumed as a normal versioned SwiftPM dependency (.package(url:, from:)). Thelembic-clitarget no longer embeds an Info.plist; its--contactsagainst the system Contacts store now falls back to plain numbers, while theLEMBIC_CONTACTSvCard path and the Lembic app are unaffected.
Added
SECURITY.md,CONTRIBUTING.md,CHANGELOG.md, GitHub issue forms, and a pull-request template.
Fixed
- Removed two stray tags at the end of the README.