Skip to content

2.0.0: one import, a letter grade, and a CLI - #3

Merged
IgnaceMaes merged 1 commit into
mainfrom
release/2.0.0
Sep 1, 2026
Merged

2.0.0: one import, a letter grade, and a CLI#3
IgnaceMaes merged 1 commit into
mainfrom
release/2.0.0

Conversation

@IgnaceMaes

Copy link
Copy Markdown
Member

Reworks the public interface around the calls people actually make, puts a letter on the grade, and ships the grade as a CLI. Carries a major changeset, so merging opens the version PR that cuts 2.0.0.

What changes

  • npx mailgrade acme.com. The package has a bin: the grade in a terminal (letter, verdict, per-mechanism headlines, and the fixes), with --json for scripts and --strict for CI, where a non-zero exit catches the day someone "temporarily" weakens the DMARC record. Zero dependencies, like everything else here.
  • A letter on the grade. DomainGrade carries letter, "A+" down to "F". The verdict sets the band and the details move within it; +all is an automatic F. The rubric lives in spec/grade.json, so ports share it.
  • One import. gradeDomain, verifyMessage and analyzeHeaders are on mailgrade itself. Every existing entry point still resolves; the subpaths are now for narrowing a bundle, not for finding the API.
  • No setup. resolver is optional everywhere it was required, defaulting to DNS over HTTPS. A Node service that wants the system resolver still passes nodeResolver() from mailgrade/node-dns.
  • Headers you can use. verifyMessage takes mta and returns authResults and headers: a folded, CRLF-terminated Received-SPF and Authentication-Results block, ready to prepend. Embedded values come off the wire, so they are sanitised on the way in, and the folder is quote-aware.
  • Prose pass. Em dashes, -- stand-ins and a stray are gone from the docs and comments across the repo.

Breaking

  • The root barrel is a curated list rather than export *, so roughly 25 internals no longer appear on mailgrade. Each is still exported from the entry point for its own area.
  • The JSON conformance corpus is no longer published in the tarball, and the mailgrade/spec/* subpath is gone with it. The corpus stays in the repository.
  • checkDomain is now gradeDomain; the pure function that held that name is now gradeRecords. DohOptions is now GradeDomainOptions.

Checks

pnpm check is green locally: oxlint, tsc, 288 tests across 10 files, tsdown build, publint, and attw --profile node16 (all entry points 🟢 for CJS, ESM and bundler).

🤖 Generated with Claude Code

Rework the public interface around the calls people actually make. The
headline calls (gradeDomain, verifyMessage, analyzeHeaders) are on the root
barrel, resolver is optional everywhere and defaults to DNS over HTTPS, and
DomainGrade carries a letter from "A+" to "F" with the rubric in the spec
corpus.

Adds a bin: npx mailgrade <domain> prints the grade, with --json for scripts
and --strict for CI. verifyMessage takes mta and returns a folded,
CRLF-terminated Received-SPF and Authentication-Results block, sanitised
against header injection.

BREAKING CHANGE: the root barrel is a curated list rather than export *, the
spec corpus is no longer published in the tarball, checkDomain is now
gradeDomain and the old gradeDomain is gradeRecords.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@IgnaceMaes
IgnaceMaes merged commit 0daa53b into main Sep 1, 2026
4 checks passed
@github-actions github-actions Bot mentioned this pull request Sep 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant