Template. Replace placeholder values like {{YOUR_NAME}}, {{CONTENT_DIR}}, etc. with your own before using.

Content Creation

Twitter Posts

Generate standalone tweets (hot takes, data drops, observations) under 280 characters with humanizer passes and publish via X API.

MCP Required. This skill needs X API (custom script) to run.

Save to ~/.claude/skills/twitter-posts/SKILL.md
SKILL.md
---
name: twitter-posts
description: "Generate standalone single tweets (NOT threads) and publish via X API. Use when: creating individual tweets. Triggers on: tweet, tweets, standalone tweets, twitter post, write a tweet."
---

# Twitter/X Standalone Tweets

Generate 3 standalone single tweets — NOT threads (use `twitter-threads` for threads). Each tweet is independent and self-contained.

## Prerequisites

**Publishing uses the X API via `{{X_API_SCRIPT_PATH}}`.**

1. Env vars must be set: `TWITTER_API_KEY`, `TWITTER_API_SECRET`, `TWITTER_ACCESS_TOKEN`, `TWITTER_ACCESS_SECRET`
2. Dependencies installed: run `npm install` in `~/.claude/skills/x-api/` if needed
3. If API call fails, fall back to saving as markdown for manual posting

---

## Workflow

### Step 1: Source Content

Ask the user:
- **Option A: From existing content** → ask which folder in `{{CONTENT_DIR}}/`, then read relevant files
- **Option B: From scratch** → ask for topic or angle

### Step 2: Load Context

- Read `{{PROFILE_PATH}}` — identity, voice, experience

### Step 3: Generate 3 Tweet Variants

Each tweet: max 280 characters. No hashtags. No emojis unless genuinely useful.

**Variant 1 — Hot Take:**
Contrarian opinion that challenges conventional wisdom. Bold, confident, slightly provocative.
- "Every AI SDR company is just a glorified mail merge with a $200M valuation."
- "The best salespeople I know have never read a sales book."

**Variant 2 — Data Drop:**
Specific number + insight. No fluff, just the punch.
- "Cold email reply rates dropped 40% in 2 years. Meanwhile, personalized video outreach sits at 8%. The math is obvious."
- "I tracked 10,000 LinkedIn connection requests. The ones with no message had a 2x higher accept rate."

**Variant 3 — Observation/Story:**
Personal anecdote or industry observation. Micro-story in <280 chars.
- "Had coffee with a VP of Sales running a 15-person SDR team who's never heard of Clay. The gap between who knows and who doesn't is getting wider every month."
- "My best client came from a DM I almost didn't send. Persistence isn't glamorous but it pays."

**NON-NEGOTIABLE rules:**
- Humanizer pass - scan for and fix AI writing patterns (see `humanizer` skill): AI vocabulary, significance inflation, filler phrases, hedging, copula avoidance, generic conclusions.
- No false-contrast filler
- No revenue flex
- No em dashes (—) anywhere in content. Use regular dashes (-), commas, periods, or restructure. Em dashes are an obvious AI writing tell.
- EVERY tweet must be under 280 characters - verify count before presenting
- Match {{YOUR_NAME}}'s voice: direct, punchy, no corporate speak
- Use swear words naturally when they fit - "bullshit", "damn", "hell", "no shit" - this is how {{YOUR_NAME}} actually talks. 1 per tweet max, don't force it, but don't avoid it either. Sanitized language is a dead giveaway for AI.

### Step 4: User Review

Display all 3 tweets with character counts:

```
TWEET 1 — Hot Take ([X]/280 chars)
[tweet content]

TWEET 2 — Data Drop ([X]/280 chars)
[tweet content]

TWEET 3 — Observation/Story ([X]/280 chars)
[tweet content]
```

Ask: **"Approve all / Edit [#] / Regenerate [#] / Skip [#]?"**

### Step 5: Publish via X API

For each approved tweet, post using Bash:

```bash
node {{X_API_SCRIPT_PATH}} tweet "The tweet text here"
```

With an image:
```bash
node {{X_API_SCRIPT_PATH}} tweet "The tweet text here" "/path/to/image.jpg"
```

- The script returns JSON with `{ success: true, id: "...", text: "..." }` on success
- Supports JPG, PNG, GIF, and WEBP images
- Wait a few seconds between posting multiple tweets
- If the API call fails, display the error and save the tweet as markdown for manual posting

**Scheduling:** After user approves tweets, ask: **"Post now or schedule for later?"**

If scheduling:
1. Ask for date and time (assume ET unless specified otherwise)
2. Convert to UTC ISO string
3. Trigger the Trigger.dev scheduled task from the project at `{{TRIGGER_PROJECT_DIR}}`:
```bash
cd "{{TRIGGER_PROJECT_DIR}}" && npx trigger.dev@latest dev trigger schedule-tweet --payload '{"text":"Tweet text","scheduled_at":"2026-02-23T14:00:00Z"}'
```
Or with image:
```bash
cd "{{TRIGGER_PROJECT_DIR}}" && npx trigger.dev@latest dev trigger schedule-tweet --payload '{"text":"Tweet text","image_path":"/path/to/img.jpg","scheduled_at":"2026-02-23T14:00:00Z"}'
```

To view scheduled posts:
```bash
cd "{{TRIGGER_PROJECT_DIR}}" && npx tsx src/scripts/twitter/list_scheduled.ts
```

To cancel a scheduled post:
```bash
cd "{{TRIGGER_PROJECT_DIR}}" && npx tsx src/scripts/twitter/cancel_scheduled.ts <post-id>
```

### Step 6: Save Output

Save as `twitter-posts.md` in the source content folder or ask user where to save.

```markdown
# Twitter Posts — [Topic]

**Date:** [YYYY-MM-DD]

---

## Tweet 1: Hot Take
**Status:** [Posted / Scheduled / Ready for manual posting]
> [tweet content]

## Tweet 2: Data Drop
**Status:** [Posted / Scheduled / Ready for manual posting]
> [tweet content]

## Tweet 3: Observation/Story
**Status:** [Posted / Scheduled / Ready for manual posting]
> [tweet content]
```