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