autark-cli 0.5.3 → 0.5.4

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.
Files changed (2) hide show
  1. package/autark.mjs +9 -0
  2. package/package.json +1 -1
package/autark.mjs CHANGED
@@ -862,6 +862,7 @@ async function mailLint(rest) {
862
862
  'compound-question': 'Compound a/b questions ("are you X or Y...") read as AI hedging across alternatives. Humans ask one specific thing. Drop the "or" and pick the more specific half.',
863
863
  'too-long': 'Cold outreach over 400 chars (~4-6 short lines) reads as a pitch deck, not a peer note. If you wrote more, you\'re explaining instead of asking. Cut to the single sharpest sentence.',
864
864
  'no-anchor-sig': 'Without a clickable name in the signature, the recipient has to type your name into Google to figure out who you are. The HTML <a href> / markdown [name](url) sig is the single biggest "who is this person?" mitigator. Plain "Kushal" alone is a tell.',
865
+ 'html-in-text': 'Layout HTML tags (<div>, <p>, <br>, <span>) in the body get sent through `autark mail send --text` as text/plain — the recipient sees the literal markup in their Gmail / Outlook (we have screenshots of this happening). For paragraph breaks use a blank line. For the signature link, the single <a href="...">name</a> is allowed (recipients see "name" rendered if the inbox does any html-detection, or the raw href if not — both fine).',
865
866
  }
866
867
 
867
868
  const violations = []
@@ -889,6 +890,14 @@ async function mailLint(rest) {
889
890
  const hasMdAnchor = /\[[^\]]+\]\(https?:\/\/[^)]+\)/.test(body)
890
891
  const hasHtmlAnchor = /<a\b[^>]*href\s*=\s*["']https?:\/\/[^"']+["'][^>]*>[^<]+<\/a>/i.test(body)
891
892
  if (!hasMdAnchor && !hasHtmlAnchor) violations.push({ rule: 'no-anchor-sig', detail: 'no clickable name in signature', why: WHY['no-anchor-sig'] })
893
+ // Layout HTML tags in the body. Catches the autark-2026-05-28 footgun where
894
+ // an agent wrote <div>...</div><br> markup, passed it to `mail send --text`,
895
+ // and 6 recipients saw raw markup in their Gmail. The <a href> signature
896
+ // tag is whitelisted because no-anchor-sig depends on it.
897
+ const layoutTagMatch = body.match(/<\s*\/?\s*(div|p|br|span|hr|table|tr|td|th|font|b|i|u|strong|em)\b[^>]*>/gi) || []
898
+ for (const tag of layoutTagMatch) {
899
+ violations.push({ rule: 'html-in-text', detail: tag, why: WHY['html-in-text'] })
900
+ }
892
901
 
893
902
  if (violations.length === 0) {
894
903
  console.log(JSON.stringify({ clean: true, length: len }, null, 2))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "autark-cli",
3
- "version": "0.5.3",
3
+ "version": "0.5.4",
4
4
  "description": "CLI for autark \u2014 hypothesis-driven product runbooks. Track products, hypotheses, runs, and actions from the terminal.",
5
5
  "type": "module",
6
6
  "license": "MIT",