1.1.0
A correctness, portability and performance pass. The headline change is that the
plugin no longer mistakes writing about someone for having contacted them.
Upgrade notes
Read these four before upgrading — each changes behaviour you may already rely
on.
-
Mentions that record an intention no longer count as contact. A link
inside an unchecked to-do, a blockquote, a code fence, or an embed is now
ignored. Previously, writing- [ ] reach out to [[Sam]]marked Sam as
contacted and cleared their overdue status — the reminder deleted itself the
moment you acted on it. A completed task (- [x] called Sam) still counts.Effect on existing vaults: some people will now show as less recently
contacted, and more will appear overdue. That is the correction, not a
regression. Turn it off with Ignore mentions that aren't contact if you
prefer the old behaviour. -
Settings migrate automatically.
peopleFolderbecomespersonFolders(a
list) andjournalFoldersbecomesjournalSources(a folder plus a moment
format). Your existing values are carried over and first-run detection is
suppressed, so nothing is overwritten. No action needed. -
Log lines are written differently. The heading is now a level-2
##, and
the date links the day's note by its real title —
- [[Aug 14, 2026|2026-08-14]]— or is written as a plain date when no note
exists for that day. Previously it always emitted[[YYYY-MM-DD]], which
created an unresolvable link in every person note when your daily notes are
named anything else. Existing log entries are left alone. -
minAppVersionis now 1.7.2 (was 1.5.0), becauserevealLeafis awaited.
Added
- Configurable date formats. Dates come from a moment.js pattern per folder,
the same format Daily Notes and Periodic Notes use, so you can paste yours in
— including folder-nesting patterns likeYYYY/MM/YYYY-MM-DD. Previously four
hardcoded patterns were tried, which silently ignored most real-world naming
schemes, including three of Periodic Notes' five defaults. Day-first formats
(DD-MM-YYYY) now parse correctly instead of being read a month off. - First-run detection. On a fresh install the plugin reads your Periodic
Notes or core Daily Notes configuration for the journal folder and format, and
looks for a folder named People, Contacts, Friends or similar. - People can be identified three ways, in any combination: a list of
folders, tags matched as a prefix (personalso claims#person/work), or a
frontmatter marker such astype: person. Tags and markers find people
anywhere in the vault, so a vault organised by area rather than by type works. - Date-field fallback. A note whose filename has no date can be dated by a
frontmatter field (date:by default), which makes note-per-meeting
workflows work. - Diagnostics. Settings shows real counts — people found, notes scanned,
notes successfully dated, interactions derived — and every empty state names
the actual cause rather than implying you have nobody to contact. - Unknown-tier warning. Deleting a tier used to silently stop tracking
everyone assigned to it. Deletion now warns with the count, and affected
people are flagged in the dashboard instead of appearing unclassified. - A clickable last-contact date that opens the note the interaction came from.
- Configurable creation-date fields, with a broader default set (
created,
Created,date created,ctime, …) and support for[[wikilink]]-wrapped
dates. People whose baseline came from the file's timestamp rather than real
data are labelled estimated, since sync andgit cloneboth reset it. - An exclusion list for templates, MOCs and index notes, plus automatic skipping
of notes containing unrendered{{placeholders}}. - Mobile layout: rows stack, and row actions are always visible rather than
revealed on hover.
Fixed
Data integrity
- The body log write is now atomic. Logging contact and then immediately
changing that row's tier could silently discard the log entry entirely — both
actions reported success. - Writes are serialized per note, and undo snapshots are taken inside that
sequence. Two overlapping actions previously merged into one snapshot, so a
single undo reversed a change you never asked to reverse, and the undo/redo
stacks could desynchronize. - The Undo link in a confirmation toast now reverses that action. Because
toasts last seven seconds, two could be on screen at once and clicking either
undid whichever action was newest. - Empty and impossible dates are rejected. Clearing the date field in the log
dialog wrote an empty value, destroying any existingprm-last-contactedand
writing a- [[]]link. A stored date like2026-13-45passed validation and
gave someone a future last-contact, so they never became overdue again. processFrontMatterfailures are caught and reported. One note with malformed
YAML previously produced a written body bullet, no frontmatter update, no undo
entry, and no message of any kind.- The contact importer re-checks each field against the note's current value at
the moment of writing, so only fill empty fields still means that if you
edited the note after generating the preview. - The log heading is located through the metadata cache, which is fence-aware. A
## Contact logshown as an example inside a code block could capture entries.
Undo
- A multi-file undo that fails partway rolls back what it already wrote, rather
than leaving half a bulk import reverted. - Snapshot paths follow a note when it is renamed. Previously a rename made undo
permanently impossible. - An undo blocked by an external edit is kept rather than silently discarded, so
it can be retried once the conflict clears. - History is capped by size (32 MB) as well as count. Repeated bulk imports
could retain hundreds of megabytes.
Interaction handling
- Two notes dated the same day count as one interaction, not two.
Contact import
- Names in non-Latin scripts are matched.
李伟,Иван Петровandمحمد علي
previously normalized to an empty string, making the importer inert for entire
scripts. - Word order and honorifics are handled, so
Rivera, SamandDr. Sam Rivera
both findSam Rivera. vCard's ownN:field is family-name-first, so this
was the common case. - Non-US birthdays are no longer corrupted.
17/04/1999became month 17, which
was written to the note and then silently never displayed. Genuinely ambiguous
dates are dropped rather than guessed. - Nicknames are merged into whichever alias key the note already uses, instead of
creating a secondaliases:alongside an existingalias:. - Google's
myContactssystem label is filtered out of imported labels.
Interface
- Folder settings are normalized, so
People\Friends, a leading/, and
accented folder names typed on macOS all resolve. Folders are validated and
offer autocomplete. - Snoozing from the reach-out flow no longer marks someone handled and skips
them when you press Escape without choosing. - Note previews release their rendered content as you advance, instead of
accumulating live render subtrees for every person in a session. - The status bar element is created once, rather than re-registering its click
handler each time the setting is toggled.
Performance
- The dashboard renders once per change on the next animation frame, instead of
up to three times per click, and skips rendering entirely while its pane is
hidden — a background tab was previously paying full DOM construction cost on
every metadata change anywhere in the vault. - The search box filters rows that are already built. Typing previously rebuilt
every row per keystroke. - Each row's tier control is a button that opens the existing picker rather than
a<select>carrying an option per tier, which accounted for roughly 45% of
render cost. metadataCachechange events are filtered to files that can actually affect
the index, so editing an unrelated note costs nothing.- Filename-to-date parsing is memoized, with a fast path that skips moment
entirely for ISO dates and an early exit for filenames containing no digits. - Settings writes are debounced. Typing a folder name previously triggered a
reindex, a render and a disk write per character. - Bulk imports yield to the event loop in chunks and report progress, instead of
freezing the window.
Measured on a 2,600-file vault: a dashboard action goes from roughly 124 ms to
under 10 ms, typing a search query from about 405 ms to 25 ms, and a full reindex
sits at 2.6 ms. Figures come from the real bundled code driven in a Node harness
and in Chromium, not from Electron, so treat them as indicative of the direction
and rough magnitude rather than exact.