Skip to content

Releases: shbernal/caniemail-ai-tooling

v0.2.2

Choose a tag to compare

@shbernal shbernal released this 04 Sep 15:36

v0.2.2

A live fetch now has to return something shaped like the dataset before it is
believed. A 200 carrying valid JSON with no feature records indexed to zero
features and was returned as source: "live" with no warning, so an endpoint that
had moved produced a confident empty matrix: search_features reported every
feature as nonexistent, and check_feature_support and lint_email failed with "No
client matches", which reads as the caller's typo. A body that fails the check
now takes the same route as a 500, down to the cache and then the bundle, with
the warning that says so.

The live-fetch test runs nightly instead of never. It has always been gated
behind CANIEMAIL_TEST_NETWORK=1 so a caniemail.com outage could not read as a
broken commit, but nothing ever set that variable, and the one path that talks
to upstream had no automated coverage at all.

Nothing changes for a caller getting real data.

v0.2.1

Choose a tag to compare

@shbernal shbernal released this 30 Aug 10:57

v0.2.1

Markup using the command and commandfor attributes is now linted.

caniemail added command and commandfor attributes upstream, and the title
tables only derived attribute names from singular "X attribute" titles — the
one existing plural, srcset and sizes attributes, was reachable only because
it had been written into a hardcoded table. Both now come from one rule, so
the next multi-attribute feature is picked up without a release here.

The offline dataset snapshot both surfaces ship moves from 2026-07-20 to
2026-08-10: one feature added, none removed, and thirteen verdict cells
changed across css-inset and html-popover. Detection output is unchanged
on every fixture.

No API changes. Anything reading 0.2.0's output keeps working.

v0.2.0

Choose a tag to compare

@shbernal shbernal released this 05 Aug 13:50

v0.2.0

lint_email returns a different shape. A finding carries only what its verdict
decides, with everything constant across a feature's findings hoisted into a
features legend keyed by slug; positions are "line:col-line:col" strings;
and version_requested has moved off the entries of check_feature_support's
support array onto the result. Anything reading those fields off a finding
follows the legend instead.

Nothing was removed from what a result tells you, and a lint of a realistic
newsletter against all 48 clients costs about half what it did — 75KB to 41KB,
roughly 19k tokens to 10k. Findings now report every occurrence of a feature
rather than the first.

Also: the MCP server revalidates its dataset every 15 minutes instead of
loading once at startup, a version pin resolves per client instead of failing
the whole call, the dataset cache is covered by tests against a loopback
server, and a weekly workflow refetches the snapshot so it cannot decay
unnoticed.

See CHANGELOG.md for the full entry.