skills/blog-persona/SKILL.md
Create and manage writing personas with NNGroup 4-dimension tone framework (Funny-Serious, Formal-Casual, Respectful-Irreverent, Enthusiastic-Matter-of-fact). Personas define readability targets, sentence length distribution, vocabulary tier, contraction frequency, and summary box label. Used by blog-write and blog-rewrite to enforce consistent voice. Use when user says "persona", "voice", "tone", "writing style", "brand voice", "create persona", "use persona".
npx skillsauth add agricidaniel/claude-blog blog-personaInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Create, store, and enforce writing personas based on the NNGroup 4-dimension tone framework and CMI Brand Voice Chart. Personas ensure consistent voice across all blog content produced by blog-write and blog-rewrite.
| Command | Purpose |
|---------|---------|
| /blog persona create | Interactive interview to build a new persona |
| /blog persona list | Show all saved personas |
| /blog persona use <name> | Set active persona for current session |
| /blog persona show <name> | Display full persona profile |
Run the 6-step interactive interview. Ask each step, wait for response, then proceed.
Ask the user for:
Present each dimension as a 0.0 to 1.0 slider. Explain both ends with examples.
| Dimension | 0.0 End | 1.0 End | Example at 0.0 | Example at 1.0 | |-----------|---------|---------|-----------------|-----------------| | funny_serious | Funny | Serious | "Let's be real, nobody reads Terms of Service" | "Understanding legal agreements protects your business" | | formal_casual | Formal | Casual | "We are pleased to announce" | "Guess what - we shipped it!" | | respectful_irreverent | Respectful | Irreverent | "We appreciate your patience" | "Yeah, that old way was broken" | | enthusiastic_matter_of_fact | Enthusiastic | Matter-of-fact | "This changes everything!" | "Here are the results." |
Defaults if user is unsure: [0.6, 0.5, 0.3, 0.5] (slightly serious, balanced formality,
respectful, balanced enthusiasm).
Ask the user to pick a vocabulary tier first, then auto-suggest the matching readability band (user can override).
| Setting | What to Ask | Default | |---------|-------------|---------| | Vocabulary tier | Consumer, Professional, or Technical | Professional | | Readability band | Auto-filled from tier (see table below) | Grade 8-10 | | Sentence length mean | Average words per sentence | 18 | | Sentence length std | Variation in sentence length | 6 | | Contraction frequency | 0.0 (never) to 1.0 (always) | 0.6 | | Max passive voice | Percentage cap on passive constructions | 10% |
Ask for 3-5 items in each list. Provide starter examples based on the tone dimensions.
Example Do's: "Use data to back claims", "Address the reader as you", "Open with a question or stat"
Example Don'ts: "Don't use jargon without defining it", "Don't start sentences with There is/There are", "Don't use cliches like game-changer"
The label used for summary/takeaway boxes in blog posts. Ask user to pick one:
Ask if the user has 1-3 URLs of existing content that exemplifies the desired voice. Store URLs in the persona for future reference. If provided, read each URL and extract:
Compare extracted values with the persona settings and flag any mismatches.
Write the completed persona as JSON to:
skills/blog/references/personas/<name>.json
Use kebab-case for the filename (e.g., acme-saas.json).
{
"name": "acme-saas",
"description": "Professional SaaS voice for B2B marketing content",
"brand": "Acme Corp",
"industry": "SaaS",
"audience": "Marketing managers at mid-market companies",
"mission": "Help marketing teams automate reporting",
"tone_dimensions": {
"funny_serious": 0.7,
"formal_casual": 0.4,
"respectful_irreverent": 0.2,
"enthusiastic_matter_of_fact": 0.5
},
"readability": {
"flesch_grade_min": 8,
"flesch_grade_max": 10,
"flesch_ease_min": 50,
"flesch_ease_max": 60
},
"style": {
"sentence_length_mean": 18,
"sentence_length_std": 6,
"contraction_frequency": 0.6,
"passive_voice_max_pct": 10,
"vocabulary_tier": "professional",
"summary_label": "Key Takeaways"
},
"voice_samples": [],
"do": [
"Use data to back every major claim",
"Address the reader directly as you",
"Lead sections with actionable insight"
],
"dont": [
"Don't use buzzwords without context",
"Don't write sentences longer than 30 words",
"Don't open with We at Acme"
]
}
| Tier | Flesch Grade | Flesch Ease | Typical Use | |------|-------------|-------------|-------------| | Consumer | 6-8 | 60-80 | Health, lifestyle, personal finance | | Professional | 8-10 | 50-60 | B2B, marketing, management | | Technical | 10-12 | 30-50 | Engineering, medical, legal |
When the user picks a tier, auto-fill the readability fields. Let them override if they want a non-standard combination (e.g., technical vocabulary at consumer readability for explainer content).
When a persona is active (via /blog persona use <name>), the writer agent loads
the persona JSON and enforces these constraints during generation:
If validation fails, flag the specific violations and suggest edits.
Glob skills/blog/references/personas/*.json and display a table:
| Persona | Industry | Audience | Vocabulary | |---------|----------|----------|------------| | acme-saas | SaaS | Marketing managers | Professional |
If no personas exist, prompt the user to create one.
Read the specified persona JSON and display it as a formatted summary with all tone dimensions, style rules, and do/dont lists.
Read the persona JSON and confirm activation. Print a summary of the key constraints that will be enforced. The persona stays active for the current conversation session. Blog-write and blog-rewrite check for the active persona before generating content.
development
Research what people are actually saying about a topic in the last 30 days across Reddit, X / Twitter, YouTube, Hacker News, dev.to, Medium, and other public discourse platforms. API-free; uses WebSearch with platform-targeted site operators plus recency filters. Produces DISCOURSE.md (a structured brief) and JSON output the writer can consume. Complements blog-researcher (which focuses on authority sources) with a recency-and-engagement lens. Use when user says "blog discourse", "discourse research", "what are people saying about", "research what people are saying", "voice of customer", "social listening", "30-day research", "trend research", "what's the discussion on", "real-time research", "practitioner discourse", "/blog discourse".
documentation
Establish durable brand and voice context for cross-skill consumption. Generates BRAND.md (audience, positioning, do/don't editorial rules, taboo phrases, competitor differentiation) and VOICE.md (existing persona JSON re-expressed as readable prose), both written to the project root. When present, all blog sub-skills auto-load these files before writing or reviewing. Pairs with blog-persona, which manages the structured persona JSON. Use when user says "blog brand", "create brand context", "brand voice doc", "BRAND.md", "VOICE.md", "establish editorial brand", "brand guidelines for blog".
testing
Translate existing blog posts into one or more target languages with SEO-optimized localization. Produces native-quality translations that preserve markdown structure, frontmatter, schema JSON-LD, image and chart embeds, and citation capsules. Localizes keywords, meta tags, numbers, dates, currencies, and quote styles per locale. Flags machine-translation artifacts for review. Run BEFORE blog-localize: this handles language conversion; localize handles cultural adaptation after translation completes. Use when user says "translate blog", "blog translate", "uebersetzen", "traduire", "traducir", "translate post", "blog auf Deutsch", "blog en espanol".
testing
One-command multilingual blog creation. Writes a blog post, translates it into user-specified languages, applies cultural adaptation, and emits hreflang tags, sitemap entries, and a CMS-ready language map. The complete write-to-publish pipeline for international content. Orchestrates blog-write, blog-translate, blog-localize, and (optionally) seo-hreflang. Use when user says "multilingual blog", "blog multilingual", "write in multiple languages", "international blog", "mehrsprachiger Blog", "blog multilingue", "blog multilingue", "create blog in German and French".