Skip to content

feat: email quality toolkit slice 1 — size, plain text, JSON trace, inspector polish - #49

Merged
atherdon merged 5 commits into
mainfrom
feat/quality-toolkit-slice1
Oct 24, 2026
Merged

atherdon merged 5 commits into
mainfrom
feat/quality-toolkit-slice1

Conversation

@atherdon

Copy link
Copy Markdown
Contributor

Summary

Applies the changes from the uploaded toolkit-slice1-inspector-polish.patch and incorporates inspector-guide.md into the docs.

What landed

  • Size budget: measureSize(result) — UTF-8 bytes, Gmail ~102 KB clip risk (ok / near / over), per-part sizes, clipped parts, unsubscribe-after-clip warning.
  • Plain text: toText(html) — headings → uppercase, lists → - item, links → label (url), entities decoded, preheader kept, styles/scripts dropped, wrap at 78 columns.
  • JSON trace: traceJson / traceJsonText, served at /trace.json on the dev server, and written by inspect --json.
  • Inspector polish: size section + meter, plain-text section, Light/Dark preview (pinned color-scheme via withScheme), previous/next part navigation, select-all on source blocks.
  • Subpath: @llazyemail/template-runtime-display/quality exports measureSize, toText, byteLength.
  • CLI: no crash when stdout is closed (e.g. | head).

Docs

  • Moved the guide into docs/inspector.md.
  • Updated docs/email-quality-toolkit.md with the shipped status for this slice.
  • README, AGENTS.md, llms.txt, llms-full.txt updated.
  • Deleted the temporary source files (inspector-guide.md and the patch).

Tests

  • New test/quality.test.ts and test/polish.test.ts.
  • 100% coverage on statements, branches, functions, and lines.
  • Prettier clean.

Test plan

  • npm run check passes
  • npm run test:coverage shows 100%
  • npx template-runtime-display inspect ./examples/inspect-demo.mjs --json trace.json writes both the report and the JSON
  • Dev server serves /trace.json
  • Light/Dark toggle appears in the document preview

Closes the temporary files that were added for this work. Next slices will add the linter and dark-mode contrast rules.

…nspector polish

Implements the first slice of the quality toolkit from the uploaded patch:

- measureSize: UTF-8 bytes, Gmail 102 KB clip risk, clipped parts, unsubscribe warning
- toText: plain-text alternative from HTML (headings, lists, links, entities, wrap)
- traceJson / traceJsonText and /trace.json + inspect --json
- Inspector: size section, plain-text section, Light/Dark preview via withScheme,
  previous/next part navigation, select-all source
- Subpath export @llazyemail/template-runtime-display/quality
- CLI stability (no crash on closed stdout)

Moves the inspector guide into docs/inspector.md, updates the quality toolkit
status in docs/email-quality-toolkit.md, and removes the temporary source files.

All tests pass with 100% coverage. Prettier clean.
@github-actions

github-actions Bot commented Oct 23, 2026 •

Copy link
Copy Markdown

Rendered emails

This PR rendered email templates.

Open the run → Artifacts → download → open index.html.

Comment thread src/quality/text.ts Fixed
Comment thread src/quality/text.ts Fixed
Comment thread src/quality/text.ts Fixed
Comment thread src/quality/text.ts Fixed
Comment thread src/quality/text.ts Fixed
Comment thread src/quality/text.ts Fixed
Comment thread src/quality/text.ts Fixed
atherdon and others added 2 commits October 23, 2026 21:00
The previous /<[^>]*>/g could backtrack on inputs that start with '<'
and contain many '<' without a matching '>'. The new implementation
walks the string once with indexOf and keeps any unclosed tag as text,
so it is linear and cannot loop.
…racter sanitization'

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
Comment thread src/quality/text.ts Fixed
Comment thread src/quality/text.ts Fixed
Comment thread src/quality/text.ts Fixed
ESLint no-irregular-whitespace flagged the raw U+00A0 inside the
character class on the line that collapses runs of spaces. Use the
explicit \\u00A0 escape so the source stays ASCII-clean and lint passes.
CodeQL flagged several polynomial regular expressions on library input
and incomplete multi-character sanitization in src/quality/text.ts.

- Comments, head/style/script pairs, and display:none blocks are now
  removed with linear indexOf scans.
- Preheader extraction walks spans with indexOf instead of a
  backtracking regex.
- Anchors and headings are rewritten with the same linear style.

The previous do-while replace loop is gone. Behavior for well-formed
email HTML is unchanged, and unclosed constructs no longer risk
quadratic backtracking. Coverage remains 100%.
@atherdon
atherdon merged commit 265617b into main Oct 24, 2026
7 checks passed
@atherdon
atherdon deleted the feat/quality-toolkit-slice1 branch October 24, 2026 03:35
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.

2 participants