Skip to content

1.1.0

Choose a tag to compare

@xuvi7 xuvi7 released this 17 Aug 18:04
· 18 commits to main since this release

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.

  1. 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.

  2. Settings migrate automatically. peopleFolder becomes personFolders (a
    list) and journalFolders becomes journalSources (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.

  3. 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.

  4. minAppVersion is now 1.7.2 (was 1.5.0), because revealLeaf is 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 like YYYY/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 (person also claims #person/work), or a
    frontmatter marker such as type: 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 and git clone both 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 existing prm-last-contacted and
    writing a - [[]] link. A stored date like 2026-13-45 passed validation and
    gave someone a future last-contact, so they never became overdue again.
  • processFrontMatter failures 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 log shown 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, Sam and Dr. Sam Rivera
    both find Sam Rivera. vCard's own N: field is family-name-first, so this
    was the common case.
  • Non-US birthdays are no longer corrupted. 17/04/1999 became 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 second aliases: alongside an existing alias:.
  • Google's myContacts system 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.
  • metadataCache change 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.