@emailens/cli 0.6.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -5,7 +5,7 @@
5
5
  <img src="./docs/wordmark-light.svg" alt="emailens / cli" width="444">
6
6
  </picture>
7
7
 
8
- **The rendering linter for email, in your terminal**
8
+ **The email rendering linter for terminal and CI**
9
9
 
10
10
  [![CI](https://github.com/emailens/cli/actions/workflows/ci.yml/badge.svg)](https://github.com/emailens/cli/actions/workflows/ci.yml)
11
11
  [![npm](https://img.shields.io/npm/v/@emailens/cli)](https://www.npmjs.com/package/@emailens/cli)
@@ -14,15 +14,40 @@
14
14
 
15
15
  </div>
16
16
 
17
- CLI tool for email compatibility analysis; preview how your emails render across 21 email clients (Gmail, Outlook, Apple Mail, Yahoo, Samsung, Thunderbird, HEY, Proton Mail, AOL, Fastmail, Superhuman).
17
+ Your email looks perfect in Apple Mail. Gmail strips half the CSS. Outlook renders it in Word.
18
18
 
19
- Point it at **HTML, MJML, Maizzle or React Email**. The format is detected from the file extension, the template is compiled with your project's own compiler, and what gets linted is the HTML your readers actually receive.
19
+ `@emailens/cli` checks HTML, React Email, MJML, and Maizzle against real client behavior across 21 email clients. It flags compatibility issues before they ship, in your terminal, in CI, or in your AI workflow.
20
20
 
21
- Across the 255 CSS and HTML features we track, only 6 are fully supported in every major client ([see the data](https://emailens.dev/email-css/report)). This tool catches the other 249 before your users do.
21
+ The quickest way to try it:
22
22
 
23
- ![emailens lint output showing errors and warnings across email clients](./docs/lint-demo.png)
23
+ ```bash
24
+ npx @emailens/cli lint email.html
25
+ ```
26
+
27
+ If you want a hosted preview, screenshots, and team workflows, see [emailens.dev](https://emailens.dev).
28
+
29
+ ## Why Emailens
30
+
31
+ Email clients are the hardest frontend target in existence. Every client has different CSS support, different rendering engines, and different failure modes.
32
+
33
+ Emailens gives you:
34
+
35
+ - per-client compatibility scoring across 21 clients
36
+ - file:line reporting for HTML inputs
37
+ - CI-safe exit codes for build pipelines
38
+ - support for React Email, MJML, Maizzle, and raw HTML
39
+ - local/offline usage with no account required
40
+
41
+ ## The ecosystem
24
42
 
25
- > **Prefer AI?** Use the [MCP server](https://github.com/emailens/mcp); same engine, works with Claude, Cursor, and any MCP client.
43
+ | Project | Purpose | Start here |
44
+ |---|---|---|
45
+ | [@emailens/engine](https://github.com/emailens/engine) | Core analysis engine and library API | If you want to build on top of it |
46
+ | [@emailens/cli](https://github.com/emailens/cli) | Terminal linting and CI checks | Best first stop |
47
+ | [@emailens/mcp](https://github.com/emailens/mcp) | Claude/Cursor/AI agent integration | If you want AI-assisted email QA |
48
+ | [emailens/action](https://github.com/emailens/action) | GitHub Action quality gate | If you want PR blocking |
49
+ | [emailens/vscode](https://github.com/emailens/vscode) | VS Code linting and preview | If you want editor feedback |
50
+ | [emailens.dev](https://emailens.dev) | Hosted previews, screenshots, team workflows | If you want team-grade QA and shareable reports |
26
51
 
27
52
  ## Install
28
53
 
@@ -30,35 +55,80 @@ Across the 255 CSS and HTML features we track, only 6 are fully supported in eve
30
55
  npm install -g @emailens/cli
31
56
  ```
32
57
 
33
- Or use with npx:
58
+ Or use it without installing:
34
59
 
35
60
  ```bash
36
- npx @emailens/cli analyze email.html
61
+ npx @emailens/cli lint email.html
37
62
  ```
38
63
 
39
- ## Commands
64
+ Maizzle HTML needs `@maizzle/framework@5` installed beside the CLI. A `.vue` file needs `@maizzle/framework@6`. One install is one major.
40
65
 
41
- ### `emailens analyze <file>`
66
+ ## Quick start
42
67
 
43
- Analyze CSS compatibility and get per-client scores.
68
+ ### Check a single file
44
69
 
45
70
  ```bash
46
71
  emailens analyze email.html
47
72
  emailens analyze email.html --clients gmail-web,outlook-windows
48
73
  emailens analyze email.html --json
49
- cat email.html | emailens analyze -
50
74
  ```
51
75
 
52
- Warnings show where the property is used, and how many other places share the
53
- problem:
76
+ ### Lint in CI
54
77
 
78
+ ```bash
79
+ npx @emailens/cli lint 'emails/**/*.{html,tsx,mjml}' --fail-on-warning
55
80
  ```
56
- ⚠ Outlook (New) (1 issue)
57
- ⚠ border-radius (4:8 +2 more): Outlook (New) does not support "border-radius".
81
+
82
+ ### Preview a render
83
+
84
+ ```bash
85
+ emailens preview email.html
86
+ emailens preview email.html --dark-mode
87
+ emailens preview email.html --screenshots --out ./screenshots
88
+ ```
89
+
90
+ ### Fix common issues
91
+
92
+ ```bash
93
+ emailens fix email.html
94
+ emailens fix email.html -o fixed.html
95
+ ```
96
+
97
+ ## What the output looks like
98
+
99
+ ```text
100
+ src/emails/welcome.html
101
+ error 12:8 outlook-windows border-radius Not supported in Outlook Windows
102
+ warn spam caps-ratio 20%+ of words are ALL CAPS
103
+
104
+ 2 files | 1 error | 1 warning
58
105
  ```
59
106
 
60
- `--json` carries the full `loc` / `locs` for each warning. As with `lint`,
61
- positions are reported for HTML input only, see below.
107
+ This is intentionally readable in a terminal and structured enough for CI, editors, and agents.
108
+
109
+ ## Supported formats
110
+
111
+ Point it at:
112
+
113
+ - HTML
114
+ - JSX / React Email
115
+ - MJML
116
+ - Maizzle
117
+
118
+ Format is detected from the file extension, and the CLI compiles your template before it analyzes the actual HTML that would be sent.
119
+
120
+ ## Commands
121
+
122
+ ### `emailens analyze <file>`
123
+
124
+ Analyze CSS compatibility and get per-client scores.
125
+
126
+ ```bash
127
+ emailens analyze email.html
128
+ emailens analyze email.html --clients gmail-web,outlook-windows
129
+ emailens analyze email.html --json
130
+ cat email.html | emailens analyze -
131
+ ```
62
132
 
63
133
  ### `emailens preview <file>`
64
134
 
@@ -78,93 +148,47 @@ Export a self-contained HTML or JSON report.
78
148
  ```bash
79
149
  emailens export email.html -o ./report
80
150
  emailens export email.html --json -o ./report
81
- emailens export email.html --dark-mode --screenshots -o ./report
82
- ```
83
-
84
- ### `emailens fix <file>`
85
-
86
- Generate AI-powered fixes for email compatibility issues. Uses `@emailens/engine` analysis to build a structured prompt, then calls Claude to fix structural issues (table layouts, VML, MSO conditionals) that static snippets can't handle.
87
-
88
- Requires `ANTHROPIC_API_KEY` environment variable and the optional `@anthropic-ai/sdk` dependency.
89
-
90
- ```bash
91
- emailens fix email.html # Fix and print to stdout
92
- emailens fix email.html -o fixed.html # Write to file
93
- emailens fix email.html --estimate # Show token estimate only (no AI call)
94
- emailens fix email.html --clients outlook-windows # Scope to one client
95
- emailens fix email.html --json # Full JSON output with metadata
96
- emailens fix email.html --max-tokens 8000 # Limit prompt size
97
- cat email.html | emailens fix - --format jsx # Pipe from stdin
98
151
  ```
99
152
 
100
- | Flag | Alias | Description |
101
- |------|-------|-------------|
102
- | `--format` | `-f` | Input format: `html`, `jsx`, `mjml`, `maizzle` |
103
- | `--clients` | `-c` | Comma-separated client IDs to scope the fix |
104
- | `--output` | `-o` | Write fixed code to file instead of stdout |
105
- | `--json` | | Output as JSON (includes token estimates and metadata) |
106
- | `--quiet` | `-q` | Suppress spinners and decorations |
107
- | `--estimate` | | Only show token estimate without calling the AI |
108
- | `--max-tokens` | | Maximum input tokens for the prompt (default: 16000) |
109
-
110
153
  ### `emailens lint <file|glob>`
111
154
 
112
- CI/CD-friendly linting with structured exit codes. Flattens all audit checks (compatibility, content hygiene, links, accessibility, images, inbox preview, size, template variables, content overflow, visual bugs, dark-mode and mobile contrast, design consistency) into a unified issue list.
155
+ CI-friendly linting with structured exit codes.
113
156
 
114
157
  ```bash
115
158
  emailens lint email.html
116
159
  emailens lint src/*.html
117
160
  emailens lint email.html --json
118
161
  emailens lint email.html --fail-on-warning
119
- emailens lint email.html --skip spam,links
120
162
  emailens lint email.html --max-warnings 5
121
163
  ```
122
164
 
123
165
  | Flag | Alias | Description |
124
166
  |------|-------|-------------|
125
- | `--format` | `-f` | Input format: `html`, `jsx`, `mjml`, `maizzle` |
167
+ | `--format` | `-f` | Input format: `html`, `jsx`, `mjml`, `maizzle`. `.vue` is `maizzle`. A pasted Vue file with no flag is detected. |
126
168
  | `--json` | | Output as JSON |
127
169
  | `--fail-on-warning` | | Exit 2 if warnings found |
128
- | `--skip` | | Comma-separated checks to skip: `spam,links,accessibility,images,compatibility,inboxPreview,size,templateVariables,overflow,visual,darkContrast,mobileContrast,design` |
170
+ | `--skip` | | Comma-separated checks to skip: `spam,links,accessibility,images,compatibility,inboxPreview,size,templateVariables,overflow,visual,darkContrast,mobileContrast,design,vml,styleSurvival,targeting` |
171
+ | `--targeting-policy` | | `progressive` (default), `strict`, or `lenient` |
129
172
  | `--max-warnings` | | Fail if more than n warnings |
130
173
 
131
- **Exit codes:**
174
+ Exit codes:
175
+
132
176
  - `0`: clean
133
177
  - `1`: errors found
134
178
  - `2`: warnings only (with `--fail-on-warning` or `--max-warnings` exceeded)
135
179
 
136
- **Output format:**
137
-
138
- ```
139
- src/emails/welcome.html
140
- error 12:8 outlook-windows border-radius Not supported in Outlook Windows
141
- warn spam caps-ratio 20%+ of words are ALL CAPS
180
+ ### `emailens clients`
142
181
 
143
- src/emails/newsletter.html
144
- pass No issues found
182
+ List all 21 supported clients.
145
183
 
146
- 2 files | 1 error | 1 warning
184
+ ```bash
185
+ emailens clients
186
+ emailens clients --json
147
187
  ```
148
188
 
149
- Issues that belong to a specific place in the file carry a `line:col`; findings
150
- about the document as a whole (spam signals, Gmail clipping, inbox preview) have
151
- no position and leave the column blank. With `--json`, each issue carries a
152
- `loc` object instead (`line`, `column`, `endLine`, `endColumn`, `offset`,
153
- `length`) for editors, annotations, and agents that need to point at or edit
154
- the exact source.
155
-
156
- One property can break in many places, so CSS issues also carry `locs`: every
157
- occurrence in document order, with `loc` as the first, and `locsTruncated: true`
158
- when there were more than 100.
159
-
160
- Positions are reported for **HTML sources only**. JSX, MJML and Maizzle are
161
- compiled before analysis, so a line number would refer to generated output
162
- rather than the file you wrote; the CLI omits it rather than print one that
163
- looks authoritative and isn't.
189
+ ## GitHub Actions
164
190
 
165
- #### CI / GitHub Actions
166
-
167
- Drop this into `.github/workflows/email-lint.yml` to fail PRs that introduce broken email CSS, spam triggers, or accessibility regressions:
191
+ Add a PR gate to fail builds when email regressions appear:
168
192
 
169
193
  ```yaml
170
194
  name: Email lint
@@ -187,125 +211,25 @@ jobs:
187
211
  run: npx -y @emailens/cli lint 'emails/**/*.{html,tsx,mjml}' --fail-on-warning
188
212
  ```
189
213
 
190
- For React Email / MJML / Maizzle source files, the CLI auto-detects the format from the extension. Want full preview reports (with screenshots and shareable links) on every PR? Use the [Emailens GitHub Action](https://github.com/marketplace/actions/emailens-email-preview-check) instead; it wraps the same engine.
191
-
192
- ### `.emailensrc`
193
-
194
- The project file the [VS Code extension](https://github.com/emailens/vscode)
195
- already reads, so the editor and CI agree about what matters. Put it at the
196
- repo root, or use an `emailens` key in `package.json`:
197
-
198
- ```json
199
- {
200
- "skip": ["spam"],
201
- "rules": {
202
- "border-radius": "error",
203
- "font-size": "off"
204
- }
205
- }
206
- ```
207
-
208
- **`rules`** sets the severity of one rule, keyed by the code `lint` prints: a
209
- CSS property (`border-radius`) or a rule id (`insecure-link`). `off` drops it
210
- entirely. Promoting a rule to `error` makes it exit 1, which is the point:
211
- without this the only control is `--skip`, and a team that cares about one
212
- Outlook property has to keep the whole compatibility check at warning level.
213
-
214
- A rule demoted in the editor that still fails the build is the worst of both
215
- worlds, and this is the file that stops that happening.
214
+ ## AI and MCP
216
215
 
217
- **Precedence.** A command-line flag wins over the file; it is an explicit
218
- choice for one invocation. In the editor it is the other way round: the repo's
219
- file wins over personal settings, because those are ambient and the file is
220
- the team's.
221
-
222
- A malformed file is linted without rather than fatal. A severity that is not
223
- one of `error`, `warning`, `info`, `off` is named on stderr and ignored, so a
224
- typo cannot quietly leave a rule on that you believe is off. Warnings go to
225
- stderr, so `lint --json | jq` stays parseable.
226
-
227
- ### `emailens clients`
228
-
229
- List all 21 supported email clients.
216
+ Prefer AI? Use the [MCP server](https://github.com/emailens/mcp). It gives your coding agent access to the same analysis engine and lets it preview, audit, fix, and diff email templates.
230
217
 
231
218
  ```bash
232
- emailens clients
233
- emailens clients --json
219
+ claude mcp add emailens -- npx -y @emailens/mcp
234
220
  ```
235
221
 
236
- ## Options
237
-
238
- All file-processing commands share:
222
+ ## Why not just use the hosted app?
239
223
 
240
- | Flag | Alias | Description |
241
- |------|-------|-------------|
242
- | `--format` | `-f` | Input format: `html`, `jsx`, `mjml`, `maizzle` |
243
- | `--clients` | `-c` | Comma-separated client IDs to filter |
244
- | `--json` | | Output JSON instead of terminal table |
245
- | `--quiet` | `-q` | Suppress spinners and decorations |
224
+ You can. But the open-source tools are what let developers:
246
225
 
247
- Preview and export add:
226
+ - validate before a push
227
+ - fail CI before a broken email ships
228
+ - run audits offline
229
+ - keep email QA in their editor and terminal
230
+ - build local automation without signing up for a platform
248
231
 
249
- | Flag | Alias | Description |
250
- |------|-------|-------------|
251
- | `--dark-mode` | `-d` | Include dark mode simulation |
252
- | `--screenshots` | | Capture screenshots (requires `BROWSERLESS_URL`) |
253
- | `--out` | `-o` | Output directory |
254
-
255
- ## AI Fixes
256
-
257
- The `fix` command requires an `ANTHROPIC_API_KEY` environment variable and the `@anthropic-ai/sdk` package:
258
-
259
- ```bash
260
- npm install @anthropic-ai/sdk
261
- export ANTHROPIC_API_KEY=sk-ant-...
262
- ```
263
-
264
- Use `--estimate` to check token usage before making an API call:
265
-
266
- ```bash
267
- emailens fix email.html --estimate
268
- # Input tokens: ~4,200
269
- # Output tokens: ~5,400
270
- # Warnings: 23 (5 structural)
271
- ```
272
-
273
- ## Framework Support
274
-
275
- The CLI can compile React Email (JSX/TSX), MJML, and Maizzle templates to HTML before analysis. Format is auto-detected from file extension, or specify with `--format`.
276
-
277
- ```bash
278
- emailens analyze newsletter.tsx # Auto-detected as JSX
279
- emailens analyze template.mjml # Auto-detected as MJML
280
- emailens preview email.html --format maizzle # Explicit format
281
- ```
282
-
283
- Framework compilers are optional peer dependencies; install only what you need:
284
-
285
- ```bash
286
- npm install sucrase react @react-email/components @react-email/render # For JSX
287
- npm install mjml # For MJML
288
- npm install @maizzle/framework # For Maizzle
289
- ```
290
-
291
- ## Screenshots
292
-
293
- Screenshots require a [Browserless](https://www.browserless.io/) instance and `playwright-core`:
294
-
295
- ```bash
296
- npm install playwright-core
297
- export BROWSERLESS_URL=ws://localhost:3000
298
- emailens preview email.html --screenshots --out ./screenshots
299
- ```
300
-
301
- ## Piping
302
-
303
- Read from stdin with `-`:
304
-
305
- ```bash
306
- cat email.html | emailens analyze -
307
- echo '<html><body>Hello</body></html>' | emailens preview - --json
308
- ```
232
+ The hosted SaaS adds screenshot previews, shared reports, and team workflows. The OSS tools give you the developer-first layer.
309
233
 
310
234
  ## License
311
235
 
@@ -314,3 +238,4 @@ MIT
314
238
  ---
315
239
 
316
240
  If this saved you from an Outlook surprise, [a star](https://github.com/emailens/cli) helps other email developers find it.
241
+