skills/typefully-draft/SKILL.md
Draft and queue social posts via the Typefully v2 API across X, LinkedIn, Threads, Bluesky, Mastodon, and any other connected account in a Typefully social set. Creates a draft you review in the Typefully app/web before it auto-posts, optionally schedules to a specific time, queues into the next free slot, returns a shareable preview link, or scopes to specific platforms via --targets. Supports single posts and threads. Reads TYPEFULLY_API_KEY and TYPEFULLY_SOCIAL_SET_ID from ~/.claude/.env. Use when user wants to schedule, queue, draft, or cross-post to any Typefully-connected platform.
npx skillsauth add RonanCodes/ronan-skills typefully-draftInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Draft a post into Typefully so it stays in your review loop before it goes live. Threads, scheduling, shareable preview links, and per-platform targeting are first-class. Posts never bypass the Typefully approval gate, which keeps connected accounts (e.g. @ronancodes) clear of bot-flag risk.
This skill wraps the Typefully v2 API. Drafts are scoped to a social set — a collection of connected platform accounts (X, LinkedIn, Threads, Bluesky, Mastodon). One draft can target one platform or all of them.
# Single post, all four platforms (default targets: x,linkedin,threads,bluesky)
/ro:typefully-draft "shipped a 16:9 promo for connectionshelper.app today. PH next month."
# Single post, scheduled for a specific time (UTC)
/ro:typefully-draft "good morning EU" --schedule "2026-04-26T07:00:00Z"
# Queue into the social set's next free slot
/ro:typefully-draft "build-in-public day 3: shipped k6 load tests" --queue-next
# Thread on X + Bluesky only
/ro:typefully-draft --thread "Day 1 of launching connectionshelper.app.\n---\nThe stack: TanStack Start, Cloudflare Workers, D1, Drizzle.\n---\nWhat I'm watching this week: r/NYTConnections." --targets x,bluesky
# Get a shareable preview URL (for showing a friend before approval)
/ro:typefully-draft "thinking about a new tagline" --share
# LinkedIn-only post (different rhythm than X; don't blanket cross-post)
/ro:typefully-draft "engineering deep-dive on D1 caching" --targets linkedin
Typefully account at https://typefully.com. Free plan supports the API.
API key from Typefully → Settings → API → New API Key.
Social set ID (the group of connected accounts) — find it via:
curl -H "Authorization: Bearer $TYPEFULLY_API_KEY" \
https://api.typefully.com/v2/social-sets | jq
Add both to ~/.claude/.env:
# Typefully
TYPEFULLY_API_KEY=<your-key>
TYPEFULLY_SOCIAL_SET_ID=<numeric-id>
curl, jq, and python3 (all standard on macOS).
Typefully v2 uses the standard bearer-token format:
Authorization: Bearer <your-key>
(Earlier v1 used X-API-Key; that version is no longer the recommended path.)
/ro:write-copy.POST /2/tweets — that path has bot-flag risk on a personal-brand account and requires a Twitter Developer app. Same calculus for LinkedIn (their OAuth posts API) or Bluesky (the AT Protocol).--schedule or --queue-next to schedule, but you should still eyeball in the Typefully app before the scheduled time hits.POST /v2/social-sets/{id}/media/upload; that's a future addition.set -a && source "$(ro context env)" && set +a
[ -n "$TYPEFULLY_API_KEY" ] && [ -n "$TYPEFULLY_SOCIAL_SET_ID" ] || {
echo "Missing TYPEFULLY_API_KEY or TYPEFULLY_SOCIAL_SET_ID in ~/.claude/.env" >&2
exit 1
}
The wrapper script handles this. Schema:
{
"platforms": {
"x": { "enabled": true, "posts": [{ "text": "..." }] },
"linkedin": { "enabled": true, "posts": [{ "text": "..." }] },
"threads": { "enabled": true, "posts": [{ "text": "..." }] },
"bluesky": { "enabled": true, "posts": [{ "text": "..." }] }
},
"publish_at": "2026-04-26T09:00:00Z",
"share": false
}
Threading: posts is an array. The script splits the input on \n---\n (a clearer human marker than four-newlines) and emits one { "text": ... } per part.
Optional fields:
| Field | Use |
|---|---|
| publish_at | ISO 8601 UTC, or "now", or "next-free-slot" for queued posting |
| share | true to receive a public preview URL in the response |
curl -sS -X POST "https://api.typefully.com/v2/social-sets/${TYPEFULLY_SOCIAL_SET_ID}/drafts" \
-H "Authorization: Bearer $TYPEFULLY_API_KEY" \
-H "Content-Type: application/json" \
-d "$payload" | jq
The response includes id, private_url, share_url (if share=true), and per-platform *_published_url fields once published. Open https://typefully.com/?d=<id> to review and approve.
scripts/draft.sh is the entry point invoked by the slash command.
bash scripts/draft.sh "<text>" # all 4 platforms
bash scripts/draft.sh "<text>" --targets x # X only
bash scripts/draft.sh --thread "p1\n---\np2\n---\np3" --targets x # X-only thread
bash scripts/draft.sh "<text>" --schedule "2026-04-26T09:00:00Z"
bash scripts/draft.sh "<text>" --queue-next
bash scripts/draft.sh "<text>" --share
--targets controls which platforms.<name>.enabled flags get flipped to true. Without --targets the default is x,linkedin,threads,bluesky (all four flipped on).
If you target a platform that isn't connected to your social set, the API returns 400. Connect the platform in Typefully first or scope --targets to the ones you have.
When Claude composes the post text inside the conversation, load /ro:write-copy first. The rules that bite hardest on social:
--schedule or --queue-next. Default is "draft only"; user should approve in the Typefully UI before publish.--share with --schedule. Pick one: a preview link is for "show a friend, then I'll publish manually"; a schedule is for "publish at this time, no further intervention." Combining them implies a workflow that doesn't exist.--targets to scope a draft to one platform when the voice doesn't translate./ro:write-copy — voice rules (em-dashes, AI-tells, scroll-stop hooks)/ro:x-scan — read-only X scraper for trend / competitor research/ro:linkedin-scan — read-only LinkedIn scraper for competitor analysis/ro:trend-scan — find what's trending before draftingtesting
--- name: linear-pipeline description: The Fable orchestrator for a single dispatched Linear ticket. Holds almost no context itself; it receives `--issue <ID> --detached`, decides the stage sequence, and fans out a sub-agent per stage, passing forward only each stage's artifact (never re-derived, never inlined into its own context). Step zero, before any planning or stage routing, is a boundary triage against `canon/security-boundary.md` (#199): a match tags Ronan Connolly and stops the run, no
development
--- name: in-your-face description: Capture a chat-only answer into a durable artifact (markdown + HTML, PDF when cheap) and launch it automatically so the user cannot miss it. Use when user says "in your face", "don't let me lose this", "save that answer", "make that durable", or right after answering a substantive side question (a recipe, comparison, how-to, or generated prompt) that would otherwise die with the context. category: workflow argument-hint: [--no-open] [--vault <short>] [hint of
tools
One-shot headless OpenAI Codex CLI calls for background/admin AI tasks — summaries, classification, extraction, admin glue. The default engine for anything that runs AI constantly in the background (daemon-driven, per-event), because it bills the flat ChatGPT subscription instead of Claude usage or per-token API spend, and it keeps working while Claude is rate-limited. NEVER for coding — coding stays Claude. Use when a skill or daemon needs a cheap always-on AI call, when the user says "use codex", "ask codex", "codex as backup", or when building a background summarizer/classifier into a listener or loop. Reads auth from ~/.codex/auth.json (ChatGPT account, no API key).
research
Turn a warranty rejection, repair quote, or RMA email into a cited decision brief — legal read (NL/EU consumer law), is the part user-serviceable, live part and new-unit prices, repair-vs-DIY-vs-new economics, before-you-send-it checklist, deadlines. Use when the user pastes or screenshots a repair quote, warranty rejection, "not covered" email, onderzoekskosten fee, or asks "should I repair or replace this".