// channels
LinkedIn Post
/ttm-linkedin-post
Generate a LinkedIn post in your voice. First run interviews you for 2-5 author profiles to mimic, scrapes their recent posts via Playwright MCP, and builds .taketomarket/PLAYBOOKS/linkedin-base.md. Subsequent runs use that base + post history + news web search to draft posts. Final draft passes through /ttm-humanize before output.
Overview
Invoke with ttm-linkedin-post to generate a LinkedIn post in your own voice. On the first run it interviews you for 2-5 author profiles to mimic, scrapes their recent posts via the Playwright MCP, and builds .taketomarket/PLAYBOOKS/linkedin-base.md — a synthesized style base derived from those creators.
Subsequent runs use that base plus your post history and a news web search to draft posts. The skill applies LinkedIn-specific patterns (hook, scannable structure, comment-bait, no link in the body), generates 2-3 draft candidates with different hooks, and lets you pick or iterate. The final chosen draft passes through /ttm-humanize before it is written out as a ready-to-post draft.
Flags: --rebuild-base re-interviews and re-scrapes authors to refresh linkedin-base.md; --no-news skips the news web search; --topic <text> seeds the topic for this post.
How it works
The skill follows the LinkedIn Post workflow at ${CLAUDE_PLUGIN_ROOT}/workflows/channel/linkedin-post.md.
Step 0: First-run inline education
Read .taketomarket/CONFIG.md. Parse first_run_seen (object) and inline_education (boolean, default true).
If inline_education is false: skip this step. Else if first_run_seen.ttm-linkedin-post is not true, print the explainer below verbatim, then mark this skill as seen:
node "${CLAUDE_PLUGIN_ROOT}/bin/ttm-tools.cjs" first-run mark ttm-linkedin-postUse this exact check (bash) to decide whether to print: node "${CLAUDE_PLUGIN_ROOT}/bin/ttm-tools.cjs" first-run check ttm-linkedin-post --raw — the JSON seen field is true once the explainer has run before.
Explainer for /ttm-linkedin-post
/ttm-linkedin-post generates a LinkedIn post from a campaign brief or a raw thought, applies the LinkedIn-specific patterns (hook, scannable structure, comment-bait, no link in body), and routes it through the gate wall. Output is a ready-to-post draft plus a comment-thread plan.
Why it matters: LinkedIn rewards a specific format that violates general copywriting rules (short lines, deliberate whitespace, no-link bodies). Generic LLM output writes essays; this skill writes posts that match the platform's actual distribution mechanics.
(Canonical source: references/inline-education-blurbs.md. Embedded verbatim because workflows do not @-resolve files at runtime.)
Required reading:
${CLAUDE_PLUGIN_ROOT}/references/linkedin-post-patterns.md${CLAUDE_PLUGIN_ROOT}/playbooks/linkedin.md${CLAUDE_PLUGIN_ROOT}/references/playwright-mcp-setup.md${CLAUDE_PLUGIN_ROOT}/templates/linkedin-base-template.md.taketomarket/POSITIONING.md,BRAND.md,PRODUCT-DNA.md,ICP.md.taketomarket/PLAYBOOKS/linkedin-base.md(created on first run).taketomarket/CAMPAIGNS/linkedin/post-history.md(created on first run)
Step 1: Detect first-run
Check if .taketomarket/PLAYBOOKS/linkedin-base.md exists.
- If NOT (or
--rebuild-baseflag): go to Step 2 (interview + scrape). - If YES: go to Step 6 (generate post).
Step 2: First-run author interview
AskUserQuestion (priority: critical):
- "Which 2-5 LinkedIn creators write in the style you want to mimic? Paste their profile URLs."
- Freeform, expect 2-5 URLs.
Step 3: Playwright check
node ${CLAUDE_PLUGIN_ROOT}/bin/ttm-tools.cjs playwright-check --rawIf detected = false: print "Author scraping needs Playwright MCP. Run /ttm-playwright-setup first." Then exit the workflow.
Also check the extension capability:
node ${CLAUDE_PLUGIN_ROOT}/bin/ttm-tools.cjs config read --rawIf playwright_mcp_extension is not true: print "Author scraping needs the Chrome extension bridge (--extension) so Playwright can use your logged-in LinkedIn session. Re-run /ttm-playwright-setup and re-add Playwright with the --extension flag, then retry." Exit.
Step 4: Scrape authors
For each profile URL:
- Call
browser_navigatewith the URL (Playwright MCP uses logged-in Chrome session via the bridge → reaches authenticated LinkedIn). - Call
browser_snapshotto read rendered DOM. - Scroll-and-snapshot loop until ~10-20 posts are captured.
For each post: capture text + engagement count + post type (text / image / carousel / video).
Save raw scrapes to .taketomarket/CAMPAIGNS/linkedin/scrapes/<author-handle>.md.
Step 5: Analyze + build linkedin-base.md
For each author:
- Compute sentence length distribution.
- Extract hook patterns (first 80 chars of each post).
- Identify recurring structure templates.
- Extract recurring phrases / voice tics.
- Note topics + cadence.
Synthesize across authors. Apply references/linkedin-post-patterns.md framework. Fill in templates/linkedin-base-template.md placeholders. Write to .taketomarket/PLAYBOOKS/linkedin-base.md.
Step 6: Load context for this post
- Load linkedin-base.md, POSITIONING, BRAND, PRODUCT-DNA, ICP.
- Load post-history.md and extract from each row (pipe-format
| YYYY-MM-DD | <topic-tag> | <hook-pattern> | <slug> | <link> |):<topic-tag>values from the last 30 days — these are the canonical topic keys (set by frontmattertopicin Step 11 and copied into the history row in Step 12).<hook-pattern>values from the last 5 rows.
- Avoid: any
<topic-tag>that appears in the last 30 days; any<hook-pattern>that appears in the last 5 posts.
Step 7: Web search for news angles
Unless --no-news:
- Read
.taketomarket/ICP.md(top headings: industry, segments) +.taketomarket/POSITIONING.md## Category. Extract 2-3 industry terms. - Construct 1-2 WebSearch queries combining those terms with
2026and platform-specific operators (e.g.,site:techcrunch.com). - Pass
recency:7d(or equivalent) to scope to last 7 days. - Surface 3-5 recent stories. Rank by relevance to product positioning.
AskUserQuestion (non-critical, default: top-ranked):
- "Found these recent stories. Use one as an angle, or write standalone?"
- options: list 3-5 stories + "Standalone, no news angle"
Step 8: Determine post topic
If --topic flag passed: use that.
Else: AskUserQuestion (priority: critical):
- "What's the topic for today's post?"
- options:
- "Use selected news story" (if Step 7 produced one)
- "Recent product update / behind-the-scenes"
- "Lesson from this week"
- "Counter-take on conventional wisdom"
- "Other (freeform)"
Step 9: Generate 2-3 draft candidates
Apply linkedin-base.md style + chosen topic. Generate 2-3 candidates with different hook patterns from references/linkedin-post-patterns.md ## Hook patterns.
Present each to user.
Step 10: Pick or iterate
AskUserQuestion (priority: critical):
- "Which draft?"
- options: ["A", "B", "C", "Show me 3 more", "Combine these"]
Loop until user picks.
Step 11: Mandatory humanize
Generate slug via node ${CLAUDE_PLUGIN_ROOT}/bin/ttm-tools.cjs slug "<topic-summary>" --raw for consistency with the codebase's existing slug convention. Generate timestamp via node ${CLAUDE_PLUGIN_ROOT}/bin/ttm-tools.cjs timestamp --raw.
Write the chosen draft to .taketomarket/CAMPAIGNS/linkedin/drafts/<timestamp>-<slug>.md (frontmatter: topic, hook_pattern, status: draft).
Then invoke /ttm-humanize <path> via Skill tool. Re-read the file after humanize completes — it now contains the rewritten version.
Step 12: Save + history append
- Print the humanized post text to the user (read from the file you wrote in Step 11).
- Update frontmatter in
.taketomarket/CAMPAIGNS/linkedin/drafts/<timestamp>-<slug>.md: changestatus: draft→status: ready. - Append to
post-history.md:
| YYYY-MM-DD | <topic-tag> | <hook-pattern> | <slug> | <link-to-draft> |Step 13: Print next steps + cadence suggestion
✓ Post ready. Copy from .taketomarket/CAMPAIGNS/linkedin/drafts/<file>.md
Want daily cadence? If you have a scheduler skill installed (e.g. /schedule),
you can set up a recurring run — example syntax:
/schedule create "0 9 * * 1-5" "/ttm-linkedin-post"
This would run the skill every weekday at 9am. You'd review + post manually.
No scheduler? Re-run /ttm-linkedin-post when you want the next post.
Next: /ttm-next | /ttm-stateWhat if this doesn't fit?
Looks like /ttm-linkedin-post can't do that yet.
- Want a new skill?
/ttm-request-skill - Existing skill needs work?
/ttm-improve-skill