Take a post idea and generate 3 complete draft variations, each with a different hook and structure. Each variation includes 2 alternative hooks. All posts follow the bundled best-practice guide for hooks, formatting, writing tactics, and engagement mechanics.
How this skill is triggered — by the user, by Claude, or both
Slash command
/linkedin-content-engine:variation-writerThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Generates 3 distinct, ready-to-post LinkedIn drafts for each idea. Each uses a different hook formula AND a different post structure. Every draft includes 2 alternative hooks so the user can mix and match.
Generates 3 distinct, ready-to-post LinkedIn drafts for each idea. Each uses a different hook formula AND a different post structure. Every draft includes 2 alternative hooks so the user can mix and match.
Before writing ANY post, read references/best-practice-guide.md in this skill's directory. That guide is the operating manual. Every post must follow its principles — hooks, formatting, structure, writing tactics, and engagement mechanics. The guide contains 10 hook formulas, 6 post outlines, formatting rules, and checklists that directly shape output quality.
/generate and selects ideas to developimport sqlite3, json, os, glob
# Find feeds.db
for db_path in glob.glob('/sessions/*/mnt/*/LinkedIn Feed Tracker/feeds.db'):
break
conn = sqlite3.connect(db_path)
conn.row_factory = sqlite3.Row
# Load the idea
idea = dict(conn.execute("SELECT * FROM content_ideas WHERE id = ?", (idea_id,)).fetchone())
# Load voice config
voice = conn.execute("SELECT * FROM user_voice_config WHERE id = 1").fetchone()
if voice:
voice = dict(voice)
system_prompt = voice.get('system_prompt', '')
authority_topics = json.loads(voice.get('authority_topics', '[]'))
else:
system_prompt = ''
authority_topics = []
# Load source posts that inspired this idea (from Plugin 1 scoring)
source_ids = json.loads(idea.get('source_post_ids', '[]'))
source_posts = []
if source_ids:
placeholders = ','.join(['?'] * len(source_ids))
source_posts = [dict(r) for r in conn.execute(f"""
SELECT author_name, content, content_short, likes, comments, relevance_score, focus_areas
FROM posts WHERE id IN ({placeholders})
""", source_ids).fetchall()]
# Load hook performance (learning loop)
try:
hook_perf = [dict(r) for r in conn.execute("""
SELECT hook_type, avg_likes, avg_comments, sample_count, confidence
FROM hook_performance
ORDER BY confidence DESC
""").fetchall()]
except:
hook_perf = []
conn.close()
From the best-practice guide, pick 3 DIFFERENT combinations. Never repeat a hook formula or structure across the 3 versions.
10 Hook Formulas (Section 11 of guide):
6 Post Structures (Section 12 of guide):
Selection strategy:
For each version, write a complete, ready-to-copy-paste LinkedIn post plus 2 alternative hooks.
Non-negotiable quality standards (from the guide):
Hook (first 2 lines):
Structure:
Writing:
Engagement:
Formatting (exactly as it would appear on LinkedIn):
Voice:
For each of the 3 versions, present:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
VERSION [N] — [HOOK FORMULA NAME] + [STRUCTURE NAME]
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
PRIMARY HOOK:
[The main hook — this is the default opening]
ALT HOOK A:
[A different opening using a different formula from the 10]
ALT HOOK B:
[Another option — different angle or emotional register]
───────────────────────────────────────────
[Full post text using the primary hook, formatted exactly as it would appear on LinkedIn — short paragraphs, line breaks, symbols, ready to copy-paste]
───────────────────────────────────────────
[X] words | [Hook formula] + [Structure] | Inspired by [N] posts scoring [X]+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
After showing all 3 versions, present the pre-post checklist from the guide (Section 13):
PRE-POST CHECKLIST:
□ Hook test — would you stop scrolling for these first 2 lines?
□ Specificity — concrete numbers, timeframes, examples?
□ One idea — single clear takeaway?
□ Format — short paragraphs, line breaks, mobile-readable?
□ Voice — read it out loud, does it sound like you?
□ CTA — clear, specific question at the end?
□ Proof — every claim backed by result or data?
□ Links — moved to first comment (not in post body)?
Then ask:
Pick a version:
- "1", "2", or "3" — Mark as your pick
- "1 with hook B" — Use version 1 but swap in alt hook B
- "blend 1+3" — Combine elements from two versions
- "tweak 2: [instructions]" — Edit a specific version
- "regenerate" — 3 new versions with different hooks/structures
- "next" — Move to the next idea
conn = sqlite3.connect(db_path)
cursor = conn.cursor()
cursor.execute("""CREATE TABLE IF NOT EXISTS content_variations (
id INTEGER PRIMARY KEY AUTOINCREMENT,
idea_id INTEGER NOT NULL,
hook_type TEXT NOT NULL,
structure_type TEXT,
full_text TEXT NOT NULL,
headline TEXT,
alt_hooks TEXT,
self_score REAL,
actual_performance_json TEXT,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
posted_at DATETIME,
FOREIGN KEY (idea_id) REFERENCES content_ideas(id)
)""")
for draft in drafts:
cursor.execute("""
INSERT INTO content_variations
(idea_id, hook_type, structure_type, full_text, headline, alt_hooks)
VALUES (?, ?, ?, ?, ?, ?)
""", (
idea_id,
draft['hook_type'],
draft['structure_type'],
draft['full_text'],
draft['full_text'].split('\n')[0][:80],
json.dumps(draft['alt_hooks'])
))
conn.commit()
conn.close()
When user picks a version:
content_ideas.status to 'used'content_ideas.used_at to nowcontent_ideas.notesAfter the user picks their versions, suggest optimal posting times based on the guide (Section 7):
SUGGESTED POSTING SCHEDULE:
Based on your audience and the research:
[Day], [Time window] — [Topic/Version] — [Reason]
Example: "Wednesday, 3-5 PM — Version 1 (Story hook) — midweek afternoon peaks for B2B"
Remember:
- Space posts at least 18 hours apart
- Add a first comment within 2 minutes of posting (seed engagement, house any links)
- Stay active replying to comments for the first 60 minutes — that's the algorithm's test window
If user says "regenerate":
If the user has the linkedin-post-dev Cowork skill installed, the variation-writer should follow the same output conventions: 3 versions per topic, each with primary hook + 2 alt hooks, formatted for direct copy-paste. The key difference is that Plugin 2's input comes from scored feed data rather than manually provided topics.
| Error | Message |
|---|---|
| Idea not found | "Idea [ID] doesn't exist. Run /generate to create ideas first." |
| No voice config | "Run /setup-content-engine to configure your voice before generating drafts." |
| Idea already used | "This idea was already used on [date]. Want to regenerate anyway?" |
| Best-practice guide missing | "Warning: best-practice-guide.md not found in references/. Posts will use default quality standards." |
Creates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.
npx claudepluginhub stevegustafson32/linkedin-content-engine-plugin