Index of every page on this site: llms.txt
All skills
Run it yourself

Find tweet ideas, plan launch posts, and draft or polish tweets with code cards, stat cards, or screenshot wraps. Use for content strategy, what to post, when to post, or an X post.

  • 6 files
  • 42.7 KB
  • MIT
  • Updated last month
  • GitHub
Use this Skill: https://skilld.dev/gh/harlan-zw/harlan-agent-kit/tweet

Nothing lands on disk. Nothing to clean up.

Fork this Skill

Edit a local copy. It keeps the author and licence.

SKILL.md

≈47 tokens for metadata: the name and description. ≈2.4k when used: this file. ≈1.9k more on demand in 2 files.

Description uses 2.4% of example budget

Before choosing a Skill, your Agent reads its name and description. All available Skills share that space.

  • A shorter description leaves more room for other Skills. This entry exceeds our 1% size suggestion.

In our Claude Code example, all Skill names and descriptions share 8,000 characters. This Skill uses ≈189 characters, or 2.4%.

The 1% threshold is a size suggestion. Longer descriptions can still fit.

Your model, settings, and other Skills decide how much text your Agent can read.

Example settings and source

The example uses a 200k-token context and default Claude Code settings. The count includes the name, description, separators, and when_to_use when present. Codex also counts local file paths.

Skit's source and limits: Codex 0.160.1, Claude Code 2.1.292.

Tweet Skill

Find content opportunities, plan launch posts, and draft tweets. Add a visual when it helps the reader. Keep planning and polishing in this Skill.

Authority

Drafting does not authorize posting, replying, scheduling, or tagging accounts in a published post. Show the exact text and wait for publication approval. Never invent metrics, engagement, personal experience, or product claims.

Gotchas

  • Character count is tricky -- URLs always count as 23 chars (t.co wrapping). Emojis count as 2. Newlines count as 1. Don't trust naive length checks.
  • Twitter crops images at 16:9 in timeline -- all templates output 1600x900 for this reason. Non-16:9 images get cropped unpredictably.
  • Don't over-polish -- tweets that sound too perfect feel like marketing. Preserve the user's natural voice, just fix obvious issues.
  • Thread vs single tweet -- default to one post. Use a thread when the user requests it or the meaning needs it.
  • Screenshot dependencies -- sharp and @resvg/resvg-js need to be installed. If they're not global, install to a temp dir, don't pollute the project.
  • Hot takes can backfire -- always flag the hot take variation as risky. The user should consciously opt in, not accidentally post something inflammatory.
  • Use a visual when it earns attention -- suggest one when it helps the reader understand or assess the point.
  • Before finalizing, load the installed Brundlefly im-part-human Skill. Preserve supplied facts and voice.

Data Storage

Track tweet history for voice consistency:

# After finalizing a tweet, log it
echo "$(date -I) | VISUAL_TYPE | FINAL_TWEET_TEXT" >> "${CLAUDE_PLUGIN_DATA}/tweet-history.log"

On subsequent runs, read recent history to maintain consistent voice and avoid repeating hooks/angles.

Input and mode

Predict the reader's attention in the feed before choosing scope and depth. Lead with the most useful point. Keep secondary changes brief or link to them. Do not turn every release feature into another post or visual by default.

Select the mode from the user's request:

Request Mode Next step
Ideas, content strategy, what to post, or no input Discovery Read planning, then offer ranked ideas.
A launch, release notes, changelog, or a new project Launch Read planning, then offer launch approaches.
A draft, topic, screenshot, or code snippet Draft Start Step 1.
Posting time or cadence only Planning Read planning and playbook. Answer the request.

An explicit request wins over inferred input type. If the user asks to polish a release tweet, use Draft mode. If the user supplies an image without planning context, use Draft mode.

Read both References when the user asks for a content plan. After a Discovery or Launch choice, continue at Step 1 with the chosen angle. Keep that angle. Do not repeat research or produce another set of initial approaches. If the user already selected exact copy, skip Step 2. Generate a visual only when requested or useful.

Step 1: Analyze Input & Select Visual Strategy

Choose a visual only when requested or when it helps the reader understand or assess the point. Otherwise select No visual. Do not ask for an image merely because the input is text.

Input type Visual template When to use
Screenshot/image path wrap-screenshot.mjs User has an existing screenshot to polish
Code snippet or mentions code code-card.mjs Showing a specific API, config, or code example
Release/launch with metrics stat-card.mjs GitHub stars, downloads, benchmarks, version milestones
General text, no useful visual No visual The text conveys the point without an image

An explicit request for a visual wins. For a useful visual, choose the best fit from the table. If more than one fits, briefly suggest the best fit and why.

Theme Selection

If a visual is selected, pick its theme. All templates share 6 color themes:

Theme Vibe Best for
midnight Deep blue, electric accents General dev content, default choice
ocean Teal/cyan, calm Nuxt/Vue ecosystem (matches brand colors)
sunset Warm orange/purple Creative tools, design content
forest Green, natural Performance, sustainability, growth metrics
lavender Purple, elegant TypeScript, DX tooling
ember Red, intense Breaking changes, critical fixes, hot takes

Default to ocean for Nuxt ecosystem content, midnight for everything else.

Chrome Selection (wrap-screenshot only)

Chrome Look Best for
terminal macOS terminal with traffic lights + monospace title CLI tools, terminal output
browser Browser-style with URL bar Web apps, UI screenshots
minimal Thin top bar, no buttons Clean look, design screenshots
none Just the image on background When the content speaks for itself

Step 2: Tweet Text Iteration

Initial Review

Read the draft and identify:

  • Character count (280 limit, flag if over)
  • Weak opening (first 5 words matter most in timeline)
  • Missing context that makes the tweet confusing to outsiders
  • Corporate speak ("excited to announce", "thrilled to share")
  • Starting with "I" (reframe to lead with value)

Generate Variations

Default to one polished draft. Offer alternatives when requested or when the user needs to choose an angle. Keep the set small. These are available approaches, not a required checklist:

  1. Fixed original -- same voice/intent, fix obvious issues
  2. Value-first -- reframe around what the reader gets. "Free tool that does X" over "I built X"
  3. Show-don't-tell -- lead with the visual/demo. "Watch:" or "Before/after:" framing
  4. Provocative -- stronger opinion or contrarian angle (flag as higher risk)

For each variation show:

  • The tweet text
  • Character count
  • What changed and why
  • A visual template and theme only when they help explain this angle; otherwise No visual

Rules for Good Tweets

  • No hashtags unless the user explicitly includes them
  • No emojis unless the user's draft already uses them
  • Match the user's voice
  • If referencing code/tech, be specific not vague
  • Front-load the hook in the first line

Iterate

If alternatives are needed, ask which direction they prefer. Keep iterating until they're happy.

Step 3: Generate Visual

If No visual is selected, skip this step and continue to Step 4. Based on the selected template, create a temporary script in scratchpad.

3a. Screenshot Wrapping (wrap-screenshot.mjs)

Use the Read tool to view the screenshot first. Then customize:

  • INPUT_PATH -- the screenshot file path
  • OUTPUT_PATH -- same directory, append -twitter before extension
  • TITLE -- contextual title based on content:
    • Terminal: claude — ~/project or the command shown
    • Browser: URL or page title
    • Generic: filename or brief description
  • THEME -- selected theme
  • CHROME -- selected chrome style

3b. Code Card (code-card.mjs)

Extract the most interesting code snippet (max ~20 lines, the card clips overflow). Customize:

  • CODE -- the code to display (clean it up: remove irrelevant imports, focus on the "aha" moment)
  • LANGUAGE -- for the title bar label
  • TITLE -- optional override (e.g., "nuxt.config.ts" or "Usage")
  • THEME -- selected theme
  • OUTPUT_PATH -- descriptive name

Tips for good code cards:

  • Show the simplest usage, not the full API
  • 5-15 lines is ideal; under 5 feels empty, over 20 gets cramped
  • Include a comment that explains what's happening if the code isn't self-evident
  • Remove type annotations if they add noise without clarity

3c. Stat Card (stat-card.mjs)

For milestones, releases with impressive numbers, benchmarks. Customize:

  • HEADLINE -- project name + version or milestone label
  • SUBHEADLINE -- one-line description
  • STATS -- array of { label, value } objects (2-4 stats, 3 is ideal)
  • THEME -- selected theme
  • OUTPUT_PATH -- descriptive name

Tips for good stat cards:

  • Use verified numbers. Never round up metrics to make them look better.
  • Use human-readable units ("45k" not "44,892")
  • Lead with the most impressive stat
  • Pair with a tweet that gives context the card doesn't

3d. Run the Script

node /path/to/scratchpad/template.mjs

Dependencies (sharp, @resvg/resvg-js) should be available globally or in the project. If not, install to scratchpad:

cd /path/to/scratchpad && pnpm init && pnpm add sharp @resvg/resvg-js

3e. Verify Output

Read the output image to verify it looks correct. Show the user the result. If something looks off (text overflow, bad contrast, wrong theme), fix and re-run.

Step 4: Final Output

Present:

  • The final tweet text with character count
  • The generated visual, when requested or useful
  • Suggested accounts to tag only when they serve the requested post (max 2)
  • Suggested posting time (if relevant), using the user's audience and timezone

Log to ${CLAUDE_PLUGIN_DATA}/tweet-history.log. Use none as VISUAL_TYPE when no visual was generated.

Keep the handoff brief. Do not append a routine menu of more variants, themes, or follow-up posts.

Source: SKILL.md on GitHub

skilld matched fixed text patterns in SKILL.md and file names. Patterns miss obfuscated code.

skilld run checks every file with the same patterns. It asks for approval before it loads a Skill with a behavior marked Needs approval.

No third-party reports yet.

Signed by skilld at 2a530d0. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 2 days ago.

Activeupdated last month
argument-hint
[draft, topic, release notes, screenshot, or ideas]

README badge

README badge for harlan-zw/harlan-agent-kit/tweet