LinkedIn Post Generator
Generate LinkedIn posts from shared source material, written in each user's personal style.
How It Works
- Personal style profile — stored locally at
~/.config/casper/linkedin-style.md (never committed)
- Source config — stored locally at
~/.config/casper/linkedin-sources.md (never committed)
- Shared source material — meeting transcripts, Slack dumps, docs in
source-material/
- Prompt template — extraction rules, voice guidelines, few-shot examples in
references/prompt-template.md
First Run: Style Setup
Check if ~/.config/casper/linkedin-style.md exists.
If it does NOT exist, run the style setup flow:
- Say: "Welcome to the LinkedIn Post Generator! Before we start, I need to understand your writing style."
- Say: "Share 3 LinkedIn posts that match the style you want. You can either paste the post links (e.g.
https://linkedin.com/posts/...) or paste the text directly."
- Wait for the user to provide 3 posts
- If the user provides LinkedIn URLs, fetch the post content using the apify-scrapers skill:
python ${CLAUDE_PLUGIN_ROOT}/skills/apify-scrapers/scripts/scrape_linkedin_posts.py search "{url}" --max-posts 1
Extract the post text from the JSON output. If a URL fails to fetch, ask the user to paste that post's text instead.
- Analyze the posts for: tone, sentence length, vocabulary, formatting habits, hook style, CTA style, use of questions, paragraph length, overall energy
- Create
~/.config/casper/ directory if it doesn't exist
- Save the analysis to
~/.config/casper/linkedin-style.md using this format:
# LinkedIn Style Profile
Generated: [date]
## Tone
[analysis]
## Structure Patterns
[paragraph length, line breaks, formatting habits]
## Hook Style
[how they open posts]
## CTA / Closing Style
[how they end posts — questions, challenges, etc.]
## Vocabulary & Phrases
[distinctive phrases, word choices, energy level]
## Sample Posts
[the 3 original posts, for reference]
- Confirm: "Got it! Your style profile is saved. You can update it anytime with
/casper:generate-linkedin-post --setup"
First Run: Source Material Check
After style setup completes (or if style exists but source-material/ is empty), check for source material:
- Check if
source-material/ contains any .md files besides README.md
- If empty, guide the user:
- Say: "You don't have any source material yet. I need content to generate posts from — meeting transcripts, notes, Slack conversations, etc."
- Present options:
- "Connect integrations" — run the
--setup-sources flow to configure Fireflies, Slack, or Google Drive auto-pulling
- "Paste something manually" — run the
--add-source flow to let the user paste a transcript, notes, or other content
- Wait for user choice and proceed with the selected flow
- If source material exists, proceed with generation
Normal Run: Post Generation
If style config exists and source material is available, proceed with generation:
- Read
~/.config/casper/linkedin-style.md
- Read ALL files in
${CLAUDE_PLUGIN_ROOT}/skills/linkedin-post-generator/source-material/ (excluding README.md)
- Read
${CLAUDE_PLUGIN_ROOT}/skills/linkedin-post-generator/references/prompt-template.md
- Apply the confidentiality rules from the prompt template (no financials, no client names, no pipeline, no team member names)
- Generate 2-4 post options based on the source material, written in the user's personal style
- Present them in a clean, copy-paste-ready format
Flags
| Flag |
Behavior |
| (none) |
Normal generation flow |
--setup |
Re-run style setup, overwrite existing config |
--setup-sources |
Configure which Fireflies, Slack, and Drive sources to pull from |
--refresh |
Pull fresh source material from configured integrations, then generate |
--view-style |
Read and display ~/.config/casper/linkedin-style.md |
--view-sources |
List and summarize all files in source-material/ |
--add-source |
Prompt user to paste new content, save as new .md file in source-material/ |
Flag Details
--setup-sources
Interactive setup for automatic source pulling. Read references/source-integrations.md for full details.
- Ask: "What's your work email address? This is used to filter transcripts to only meetings you attended."
- Save as
user_email in the config
- Ask: "Which sources do you want to connect?" Present options:
- Fireflies.ai — pulls meeting transcripts (needs
FIREFLIES_API_KEY env var)
- Slack — pulls messages from channels (needs
SLACK_BOT_TOKEN env var)
- Google Drive — pulls docs and transcripts (needs OAuth setup via google-workspace skill)
- For each selected source, check if the required env var / credentials exist. If missing, provide setup instructions:
- Fireflies: "Set
FIREFLIES_API_KEY in your environment. Get your API key from https://app.fireflies.ai/api"
- Slack: "Set
SLACK_BOT_TOKEN in your environment. Create a Slack app at https://api.slack.com/apps"
- Google Drive: "Run the google-workspace skill setup to configure OAuth."
- For each enabled source, gather configuration:
- Fireflies: search terms (or leave empty for all recent) and days_back
- Slack: which channels to pull from — list available channels if possible, otherwise ask the user
- Google Drive: search terms, days_back
- Save to
~/.config/casper/linkedin-sources.md
- Confirm: "Source config saved. Run
/casper:generate-linkedin-post --refresh to pull fresh content."
--refresh
Pull fresh source material from all configured integrations before generating posts. Read references/source-integrations.md for the full integration workflow.
Summary of the flow:
- Read
~/.config/casper/linkedin-sources.md — if missing, run --setup-sources first
- For each enabled source, call the existing Casper skill scripts:
- Fireflies:
python ${CLAUDE_PLUGIN_ROOT}/skills/transcript-search/scripts/fireflies_transcript_search.py "{term}" --days-back {N} --content --json
- After fetching, filter results to only transcripts where
user_email (from source config) appears in the transcript's participants array
- Slack:
python ${CLAUDE_PLUGIN_ROOT}/skills/slack-automation/scripts/slack_search.py read "{channel}" --days {N}
- Google Drive:
python ${CLAUDE_PLUGIN_ROOT}/skills/google-workspace/scripts/gdrive_search.py files "{term}" --modified-days {N} --json
- Convert JSON output to clean markdown and save to
source-material/:
- Fireflies:
fireflies-{YYYY-MM-DD}-{title-slug}.md
- Slack:
slack-{channel}-{YYYY-MM-DD}.md
- Google Drive:
gdrive-{title-slug}-{YYYY-MM-DD}.md
- Proceed with normal generation
--view-style
Read ~/.config/casper/linkedin-style.md and display it. If it doesn't exist, say "No style profile found. Run /casper:generate-linkedin-post --setup to create one."
--view-sources
List all .md files in ${CLAUDE_PLUGIN_ROOT}/skills/linkedin-post-generator/source-material/ (excluding README.md). For each file, show the filename and a 1-line summary of its contents.
--add-source
- Ask: "Paste the content you want to add as source material (meeting transcript, Slack dump, notes, etc.)"
- Ask: "What should I name this source file? (e.g.,
team-standup-jan-2025)"
- Save as
${CLAUDE_PLUGIN_ROOT}/skills/linkedin-post-generator/source-material/[name].md
- Confirm: "Source material saved. It will be included in future post generation."
Reference Files
| File |
When to Read |
references/prompt-template.md |
Every generation run — contains voice rules, few-shot examples, confidentiality rules |
references/source-integrations.md |
When running --refresh or --setup-sources — contains script paths, arguments, output conversion |
references/style-setup.md |
When running --setup — contains analysis framework for style profiling |
source-material/*.md |
Every generation run — raw content to extract post ideas from |
Converted and distributed by TomeVault — claim your Tome and manage your conversions.
1---2name: casper-studios-casper-marketplace-linkedin-post-generator3description: LinkedIn Post Generator4---56# LinkedIn Post Generator78Generate LinkedIn posts from shared source material, written in each user's personal style.910## How It Works11121. **Personal style profile** — stored locally at `~/.config/casper/linkedin-style.md` (never committed)132. **Source config** — stored locally at `~/.config/casper/linkedin-sources.md` (never committed)143. **Shared source material** — meeting transcripts, Slack dumps, docs in `source-material/`154. **Prompt template** — extraction rules, voice guidelines, few-shot examples in `references/prompt-template.md`1617## First Run: Style Setup1819Check if `~/.config/casper/linkedin-style.md` exists.2021**If it does NOT exist**, run the style setup flow:22231. Say: "Welcome to the LinkedIn Post Generator! Before we start, I need to understand your writing style."242. Say: "Share 3 LinkedIn posts that match the style you want. You can either paste the post links (e.g. `https://linkedin.com/posts/...`) or paste the text directly."253. Wait for the user to provide 3 posts264. **If the user provides LinkedIn URLs**, fetch the post content using the apify-scrapers skill:27 ```bash28 python ${CLAUDE_PLUGIN_ROOT}/skills/apify-scrapers/scripts/scrape_linkedin_posts.py search "{url}" --max-posts 129 ```30 Extract the post text from the JSON output. If a URL fails to fetch, ask the user to paste that post's text instead.315. Analyze the posts for: tone, sentence length, vocabulary, formatting habits, hook style, CTA style, use of questions, paragraph length, overall energy326. Create `~/.config/casper/` directory if it doesn't exist337. Save the analysis to `~/.config/casper/linkedin-style.md` using this format:3435```markdown36# LinkedIn Style Profile37Generated: [date]3839## Tone40[analysis]4142## Structure Patterns43[paragraph length, line breaks, formatting habits]4445## Hook Style46[how they open posts]4748## CTA / Closing Style49[how they end posts — questions, challenges, etc.]5051## Vocabulary & Phrases52[distinctive phrases, word choices, energy level]5354## Sample Posts55[the 3 original posts, for reference]56```57588. Confirm: "Got it! Your style profile is saved. You can update it anytime with `/casper:generate-linkedin-post --setup`"5960## First Run: Source Material Check6162After style setup completes (or if style exists but source-material/ is empty), check for source material:63641. Check if `source-material/` contains any `.md` files besides `README.md`652. **If empty**, guide the user:66 - Say: "You don't have any source material yet. I need content to generate posts from — meeting transcripts, notes, Slack conversations, etc."67 - Present options:68 - **"Connect integrations"** — run the `--setup-sources` flow to configure Fireflies, Slack, or Google Drive auto-pulling69 - **"Paste something manually"** — run the `--add-source` flow to let the user paste a transcript, notes, or other content70 - Wait for user choice and proceed with the selected flow713. **If source material exists**, proceed with generation7273## Normal Run: Post Generation7475**If style config exists and source material is available**, proceed with generation:76771. Read `~/.config/casper/linkedin-style.md`782. Read ALL files in `${CLAUDE_PLUGIN_ROOT}/skills/linkedin-post-generator/source-material/` (excluding README.md)793. Read `${CLAUDE_PLUGIN_ROOT}/skills/linkedin-post-generator/references/prompt-template.md`804. Apply the confidentiality rules from the prompt template (no financials, no client names, no pipeline, no team member names)815. Generate 2-4 post options based on the source material, written in the user's personal style826. Present them in a clean, copy-paste-ready format8384## Flags8586| Flag | Behavior |87|------|----------|88| (none) | Normal generation flow |89| `--setup` | Re-run style setup, overwrite existing config |90| `--setup-sources` | Configure which Fireflies, Slack, and Drive sources to pull from |91| `--refresh` | Pull fresh source material from configured integrations, then generate |92| `--view-style` | Read and display `~/.config/casper/linkedin-style.md` |93| `--view-sources` | List and summarize all files in `source-material/` |94| `--add-source` | Prompt user to paste new content, save as new `.md` file in `source-material/` |9596## Flag Details9798### `--setup-sources`99100Interactive setup for automatic source pulling. Read `references/source-integrations.md` for full details.1011021. Ask: "What's your work email address? This is used to filter transcripts to only meetings you attended."103 - Save as `user_email` in the config1042. Ask: "Which sources do you want to connect?" Present options:105 - **Fireflies.ai** — pulls meeting transcripts (needs `FIREFLIES_API_KEY` env var)106 - **Slack** — pulls messages from channels (needs `SLACK_BOT_TOKEN` env var)107 - **Google Drive** — pulls docs and transcripts (needs OAuth setup via google-workspace skill)1083. For each selected source, check if the required env var / credentials exist. If missing, provide setup instructions:109 - **Fireflies**: "Set `FIREFLIES_API_KEY` in your environment. Get your API key from https://app.fireflies.ai/api"110 - **Slack**: "Set `SLACK_BOT_TOKEN` in your environment. Create a Slack app at https://api.slack.com/apps"111 - **Google Drive**: "Run the google-workspace skill setup to configure OAuth."1124. For each enabled source, gather configuration:113 - **Fireflies**: search terms (or leave empty for all recent) and days_back114 - **Slack**: which channels to pull from — list available channels if possible, otherwise ask the user115 - **Google Drive**: search terms, days_back1165. Save to `~/.config/casper/linkedin-sources.md`1176. Confirm: "Source config saved. Run `/casper:generate-linkedin-post --refresh` to pull fresh content."118119### `--refresh`120121Pull fresh source material from all configured integrations before generating posts. Read `references/source-integrations.md` for the full integration workflow.122123**Summary of the flow:**1241251. Read `~/.config/casper/linkedin-sources.md` — if missing, run `--setup-sources` first1262. For each enabled source, call the existing Casper skill scripts:127 - **Fireflies**: `python ${CLAUDE_PLUGIN_ROOT}/skills/transcript-search/scripts/fireflies_transcript_search.py "{term}" --days-back {N} --content --json`128 - After fetching, filter results to only transcripts where `user_email` (from source config) appears in the transcript's `participants` array129 - **Slack**: `python ${CLAUDE_PLUGIN_ROOT}/skills/slack-automation/scripts/slack_search.py read "{channel}" --days {N}`130 - **Google Drive**: `python ${CLAUDE_PLUGIN_ROOT}/skills/google-workspace/scripts/gdrive_search.py files "{term}" --modified-days {N} --json`1313. Convert JSON output to clean markdown and save to `source-material/`:132 - Fireflies: `fireflies-{YYYY-MM-DD}-{title-slug}.md`133 - Slack: `slack-{channel}-{YYYY-MM-DD}.md`134 - Google Drive: `gdrive-{title-slug}-{YYYY-MM-DD}.md`1354. Proceed with normal generation136137### `--view-style`138139Read `~/.config/casper/linkedin-style.md` and display it. If it doesn't exist, say "No style profile found. Run `/casper:generate-linkedin-post --setup` to create one."140141### `--view-sources`142143List all `.md` files in `${CLAUDE_PLUGIN_ROOT}/skills/linkedin-post-generator/source-material/` (excluding `README.md`). For each file, show the filename and a 1-line summary of its contents.144145### `--add-source`1461471. Ask: "Paste the content you want to add as source material (meeting transcript, Slack dump, notes, etc.)"1482. Ask: "What should I name this source file? (e.g., `team-standup-jan-2025`)"1493. Save as `${CLAUDE_PLUGIN_ROOT}/skills/linkedin-post-generator/source-material/[name].md`1504. Confirm: "Source material saved. It will be included in future post generation."151152## Reference Files153154| File | When to Read |155|------|-------------|156| `references/prompt-template.md` | Every generation run — contains voice rules, few-shot examples, confidentiality rules |157| `references/source-integrations.md` | When running `--refresh` or `--setup-sources` — contains script paths, arguments, output conversion |158| `references/style-setup.md` | When running `--setup` — contains analysis framework for style profiling |159| `source-material/*.md` | Every generation run — raw content to extract post ideas from |160161---162> Converted and distributed by [TomeVault](https://tomevault.io/claim/casper-studios) — claim your Tome and manage your conversions.163<!-- tomevault:4.0:skill_md:2026-04-13 -->