v0.4 makes failures fail loudly. v0.3 left a handful of silent failure modes — a typoed updated: value silently skewed sort and staleness filters; a wikilink alias didn't match area: queries despite literally naming the area; a timestamp with a TZ offset got UTC-sliced into a different calendar date. v0.4 makes each one either correct or loud.
Highlights:
- Every Obsidian wikilink shape for
area:— bare, quoted,[[Foo]],[[Path/Foo]],[[Target|Alias]], plus the unquoted-array form — now collapses to one canonical form. - Frontmatter dates with TZ offsets preserve the user's calendar date instead of UTC-slicing.
- Impossible dates (e.g.
updated: 2026-13-45) surface in a newdateErrorsresponse field rather than silently rolling over vianew Date(). - CodeQL static analysis is on for application code and workflow YAML; supply-chain hardening pins the only third-party Action to a commit SHA.
find_projectcaches parsed dates on eachProjectSummary;daily_review_statusparallelizes its three independent I/O ops.
Breaking: The find_project response field lastReviewed is renamed to last_reviewed, matching the YAML field name (last-reviewed) and the snake_case MCP API convention. Clients reading the field by name will need to update; the sort token (the public API the field name didn't appear in) was already last_reviewed.
Security
ci.ymltest job declares an explicitpermissions: contents: readblock; the implicit broadGITHUB_TOKENis no longer inherited (#22).pnpm/action-setup(the only third-party action) is pinned to a commit SHA in bothci.ymlandrelease.yml; Dependabot'sgithub-actionsecosystem keeps the SHA current (#23).- CodeQL static analysis enabled for the
javascript-typescriptandactionslanguage packs, using thesecurity-and-qualityquery suite, scheduled weekly. - Replaced the unmaintained
gray-matter(pinnedjs-yaml@^3.13.1) with@11ty/gray-matter(js-yaml@^4.2.0), clearing GHSA-h67p-54hq-rp68 (quadratic-complexity DoS in js-yaml v3 via repeated YAML merge keys).
Fixed
find_project:area: [[Foo]]written unquoted in YAML — parsed by js-yaml as a nested array — no longer silently drops toundefined(#15).find_project:area:written as a wikilink alias ([[Areas/Health|Health]]) or path target ([[Areas/Health]]) now matches the alias / last path segment (#16).find_project: date fields carrying a timezone offset (e.g.due: 2026-06-30T20:00:00-08:00) now preserve the user's calendar date instead of UTC-slicing (#14).find_project: impossible dates in frontmatter no longer roll over silently vianew Date(); the project still appears in unfiltered results but the bad value surfaces in the newdateErrorsfield (#18).parseFrontmatter: works around a latent@11ty/gray-matterbug where the library's cache stripped its own non-enumerablematterproperty on repeated parses of identical content.find_project:value instanceof Datefallback now caches local-midnight Date instead of js-yaml's UTC midnight, eliminating a residual TZ inconsistency in theupdated_sincefilter.
Changed
- Breaking:
find_projectresponse:lastReviewedfield renamed tolast_reviewed(#20). The internalSORT_KEY_MAPindirection is gone; adding a new identity-mapped sort key now requires only the Zod enum andProjectSortKeyunion. find_projectresponse: newdateErrors?: Array<{field, value}>field carrying per-field date-parse failures.find_projecttool description and parameter.describe()strings refreshed to reflect post-#18 exclusion criteria and the expandedarea:normalization surface.
Performance
daily_review_status:inboxStatusparallelizes its three independent I/O ops viaPromise.all(#17).find_project: parsedDateobjects are stashed on eachProjectSummaryand reused by bothdaysSinceUpdateand theupdated_sincefilter (#19).
See CHANGELOG.md for full notes.