Generate a personal voice guide for X (Twitter) and/or LinkedIn by scanning a user's past posts and iteratively refining with sample-and-feedback loops. Produces a structured markdown voice guide that sibling skills (create-x-content, create-linkedin-content) consume to draft in-voice posts. Different from brand-voice-extractor, which analyses company blogs/landing pages — this skill is for personal social voice.
npx gooseworks install --all # then, in Claude Code, Cursor, or Codex: /gooseworks use the generate-voice-guide skill
Turn a real person's past posts into a structured voice guide that other skills can use to draft in-voice content. Produces one guide per platform (X, LinkedIn, or both) with persona, dos/don'ts, banned phrases, hook patterns, format rules, and example posts.
This is an agent-executed skill — the agent handles scraping, analysis, drafting, and iteration via the tools available in the session. No bundled Python script.
create-x-content, create-linkedin-content, social-kit) needs a voice guide and one doesn't existWhen NOT to use: For analysing a company's blog/landing-page voice, use brand-voice-extractor instead. That's for corporate marketing voice; this one is for individual social voice.
Interactive:
/generate-voice-guideArgs mode:
/generate-voice-guide --profile @GooseworksAI --platforms x,linkedin --output ~/.goose-skills/voice-guidesAsk these up front if not supplied via flags:
@GooseworksAI), a LinkedIn profile URL, or both. You can mimic your own voice or someone else's."~/.goose-skills/voice-guides/voice-{x,linkedin}.md. Ok to use that, or prefer a different path?"For X:
apidojo/twitter-user-tweets-scraper (or whichever X scraper is available in the session) keyed to the handle.APIFY_API_TOKEN env var. If missing, surface a clear error with the setup link.For LinkedIn:
harvestapi/linkedin-profile-posts keyed to the profile URL.Fallback (no scraper available or posts paywalled): ask the user to paste 15–25 posts as plain text.
Store raw post text, engagement metrics (likes, views if available), and timestamps.
Use voice-x.md / voice-linkedin.md template references (see "Template Skeleton" below) to produce v1 of the guide. Do NOT copy content from them — only the structure.
Analyse the scraped posts for:
excited to share, leverage, game-changing, thrilled, etc.). List 10–20.This is where voice-guide quality is made. Do NOT skip iterations.
Each iteration:
Stopping rule: continue until the user explicitly says "this is good" AND at least 5 iterations have completed. 5 is a floor, not a ceiling. If the user says "good enough" at iteration 2, push back: "Voice guides need at least 5 rounds to actually lock in. Can we do 3 more?"
~/.goose-skills/voice-guides/voice-<platform>.md).~/.goose-skills/config.json:
{
"voice_guides": {
"x": "<absolute path to voice-x.md>",
"linkedin": "<absolute path to voice-linkedin.md>"
}
}/create-x-content --brief \"...\" and it'll use this voice guide automatically."Every generated voice guide should have these top-level sections, in order:
# Voice Guide: <Platform> — <Handle or Name>
## Persona
## The "Meat" Principle
## Dos
## Don'ts
## Banned Phrases
## Hook Patterns
## CTA Guidelines
## Format Rules
## Tone Calibration
## Example Posts That Exemplify The VoiceMatch the depth and specificity of a well-written voice guide — prose for persona, numbered lists for dos/don'ts, quoted examples with analysis. Aim for 120–250 lines.
~/.goose-skills/config.json is a lightweight cross-skill config. Schema:
{
"voice_guides": {
"x": "/absolute/path/to/voice-x.md",
"linkedin": "/absolute/path/to/voice-linkedin.md"
}
}Sibling skills read this to discover voice guide paths. Always use absolute paths.
| Input | Required | Default |
|---|---|---|
--profile | Yes (one of X handle, LinkedIn URL, or both) | — |
--platforms | No | x,linkedin if both profiles given, else matches supplied profiles |
--posts-x | No | 50 |
--posts-linkedin | No | 25 |
--output | No | ~/.goose-skills/voice-guides |
--iterations-min | No | 5 |
<output>/voice-x.md and/or <output>/voice-linkedin.md~/.goose-skills/config.json with voice guide pathsAPIFY_API_TOKEN) for scrapingWebFetch or read locally if the user has them) — not required to runcreate-x-content, create-linkedin-content, social-kit) needs a voice guide and one doesn't existapidojo/twitter-user-tweets-scraper (or whichever X scraper is available in the session) keyed to the handle.Assemble an expert/educator motion-graphic LISTICLE video ad from a config — a spoken authoritative voiceover carries a numbered listicle while N web-animated hyperframe beats (HTML plus the Web Animations API, one branded design system of alternating tiles, big hero numerals, and glass-pill callouts) are rendered frame-by-frame via Playwright and anchored to the VO's word-level timestamps, periodic color-graded B-roll windows give visual breath, and captions burn ONLY inside those B-roll windows (2-word chunks, ASS Format header carrying a Name field so none drop) with the VO mixed under a low music bed. This is the FREE deterministic assembly stage (Playwright beat render plus ffmpeg concat plus window-masked caption burn plus VO-and-music mix plus final composite) — the VO, the music bed, and the stock B-roll come from create-vo-elevenlabs, create-music-elevenlabs, and media-proxy. Use for the vo-anchored-motion-listicle format.
Assemble a stop-motion hand-swatch-cycle product-demo ad from a config — a sequence of still PLATES (one hand swiping a single-barrel cosmetic across a cream skin-patch, the barrel + swatch changing per plate while the hand, background, crop, and lighting stay locked) is PNG→mp4 loop-encoded at each plate's own stop-motion hold (fast motion frames 150–250ms, per-shade ~380ms, hero beats 1100–1800ms), concat-demuxed with HARD cuts into a silent master, closed on a Playwright HTML-rendered branded end card (serif tagline + sans subtitle + real logo SVG over a hero BG, never AI-rendered text), and muxed with a pre-sourced music track playing under the end card with a fade tail (no VO). This is the FREE deterministic assembly stage (loop-encode + concat-demux + end-card render + music mux); the master-anchor plate, shade plates, and end-card BG come from create-image-gpt-image-fal and the track from create-music-elevenlabs. Use for the stopmotion-hand-swatch-cycle format.
Assemble a split-screen creator ad from a config — a two-zone vertical composite where a supplied AI-creator lip-sync take fills the BOTTOM ~48% while real 16:9 product/demo clips run uncropped in the TOP ~52%, each top clip contain-fit with a darkened blurred cover-scale fill of the same clip (never black bars), a 3px brand-color divider between the zones, the creator slice cover-fit per the per-scene VO timing, scenes hard-concatenated with the body audio being the concatenated creator VO slices, an end card held on the last sharp frame ~3s, then the ASSEMBLED cut transcribed with local Whisper (not the raw VO — concat drops inter-scene silence) and word-level captions burned in the chosen style. This is the FREE deterministic assembly + caption stage (two-zone composite + blurred fill + divider + hard-concat + end card + captions); the VO comes from create-vo-elevenlabs, the anchor from create-image-gpt-image-fal, and the whole-VO lip-sync from a paid VEED Fabric 1.0 take (a no-atom upstream input). Use for the split-screen-creator format.