Skip to content
Marketing
Skill

/adapt-copy

Adapt post copy per platform: character limits, hashtags, tone and the right CTA mechanism. \"rewrite this caption for LinkedIn\"

From plugin
socialforge
4221 skills5 agents18 commands

Claude Code

$ npx -y skills add indranilbanerjee/socialforge --skill adapt-copy --agent claude-code

SKILL.md

adapt-copy.SKILL.md
name: adapt-copy
description: "Adapt post copy per platform: character limits, hashtags, tone and the right CTA mechanism. \"rewrite this caption for LinkedIn\""
argument-hint: "[--post <id>] [--all] [--platform <name>]"
effort: medium
user-invocable: true

/socialforge:adapt-copy — Copy Adapter

> **Script location.** If your host does not set `${CLAUDE_PLUGIN_ROOT}`, the scripts are in this plugin's `scripts/` folder, next to `skills/`. Run them with Python 3.10 or newer: `python`, or `python3` where `python` is not found (macOS, many Linux systems).

Transform a single caption brief into platform-optimized copy for each target platform.

Context efficiency

Asset-heavy skill. **Grep before Read** the asset catalog (`${CLAUDE_PLUGIN_DATA}/socialforge/brands/<brand>/asset-index.json`) — never list the asset directory. Reference generated images / videos by path, not by loading metadata. Brand profile loads once per session.

Process (Per Post x Per Platform)

1. Load post brief (topic, caption_brief, CTA, hashtags, campaign) 2. Load brand-config.json (tone, hashtags, language settings) 3. Load compliance-rules.json (banned phrases, disclaimers) 4. For X/Twitter posts with live-source context, read the optional [X/Twitter research intake](../../references/x-twitter-research-intake.md) note and use only reviewed evidence 5. Write platform-specific copy (tone and structure per platform, within these limits):

| Platform | Tone | Limit | Hashtags: aim / script cap | Link | |----------|------|-------|----------------------------|------| | LinkedIn | Professional | 3,000 chars (140 before fold) | 3-5 / 5 | Direct URL | | Instagram | Conversational | 2,200 chars | 3-5 / 5 (first comment) | Link in bio | | X/Twitter | Punchy, concise | 280, counted by weight (emoji and CJK 2, any URL 23) | 1-2 / 2 | Direct URL | | Facebook | Casual | 500 chars optimal (63,206 hard limit) | 1-3 / 3 | Direct URL | | YouTube | Description format | 5,000 chars | 3-5 / 5 | Direct URLs | | TikTok | Casual, trend-aware | 2,200 chars | 3-5 / 10 (trending + branded) | Link in bio | | Pinterest | Search-friendly description | 800 chars | 5-10 / 20 | Direct URL | | Threads | Conversational | 500 chars | 1 / 1 | Direct URL | | Bluesky | Concise, community-first | 300 chars | 1-2 / 2 (via tag facets) | Direct URL |

**The limits are data, and not all of them are confirmed.** `scripts/platform_limits.json` records every number with its source URL, the date it was checked and a status: confirmed (a primary platform page says it), differs, or unsourced (SocialForge's working value, no readable primary page). On 2026-10-04 the character limits for Instagram, Facebook and TikTok were unsourced (third-party pages report 4,000 for TikTok; unconfirmed, so 2,200 stays as the safe cap), as is every fold position. Run `python "${CLAUDE_PLUGIN_ROOT}/scripts/adapt_copy.py" --sources` before telling anyone a limit is official; platforms change limits without notice. "Aim" is a working range from SocialForge's platform notes, not a platform rule. The script cap is how many hashtags `adapt_copy.py` keeps.

6. Measure and fit every variant with `adapt_copy.py` (see "Run the adapter" below) 7. Apply brand hashtags (always_include + campaign-specific), up to each platform's cap, and tell the user which ones the cap dropped 8. Run compliance check - flag banned phrases, add disclaimers 9. Handle bilingual posts if configured 10. Save to `production/copy/post-{id}-{platform}-copy.txt`

**No significance markers.** Never write a line whose only job is to announce that the next line matters: "here's the thing", "the thing is,", "here's the kicker", "here's where it gets interesting", "that's the part that got me", "let that sink in", "read that again". They read as machine-written, and on a 280-character platform they spend budget the point needs. Lead with the specific instead — "Approvals went from 14 days to 31" beats "Here's the thing about approval timelines". Same for stacked soft adverbs (honestly / genuinely / truly / literally / actually / basically): at most one per caption, never two in a sentence.

This is a writing rule enforced by the copy-adapter agent, not a scan. SocialForge ships no AI-tell scanner on purpose — caption-length copy has no document structure to measure, and per-1000-word metrics are noise at 280 characters.

When the post's CTA is a conversation (a keyword that opens a DM, a WhatsApp or Messenger thread), read [conversational-commerce.md](../../references/conversational-commerce.md): opt-in and 24-hour-window rules, and playbooks for the post, the first reply, the handoff, and templates.

Run the adapter

Write each variant **without** the CTA and without hashtags, then measure and fit it:

python "${CLAUDE_PLUGIN_ROOT}/scripts/adapt_copy.py" --text "<the variant>" --platform x --brand <slug> --cta "<CTA wording and URL>" --campaign-hashtags "#Tag1" "#Tag2"

Read these fields of the JSON it prints:

  • `within_limit`, `post_char_count`, `char_limit` - the post measured against the limit: `post_text`, which is the copy plus any hashtags the platform shows in the post (`char_count` is the copy alone). `count_method` says how it was counted: `code_points` (plain characters) everywhere except X, which is `x_weighted`: emoji and CJK characters count 2 and every URL counts 23 however long it is, so X's `char_count` is not `len(copy)`. If `within_limit` is false, shorten the copy or the CTA.
  • `copy` - the variant with the CTA turned into the platform's mechanism. If it is shorter than what you wrote, the script cut it mechanically: tighten the prose and run it again rather than shipping the cut.
  • `post_text` - what to publish: the copy with the hashtags appended where the platform puts them in the post. Tags given without `#` get one.
  • `hashtags`, `first_comment` - the hashtags, and where they go when they are not in the post (Instagram: first comment).
  • `hashtags_dropped` - the hashtags the
Read more
@indranilbanerjee
Ships withsocialforge

Your client wants 30 days of social content across six platforms with brand-faithful imagery, AI-generated video, and provenance signed for EU markets. You have five days.

4221 skills5 agents
Get the whole plugin

Stars on GitHub

Momentum

stars in total
42
Star history of indranilbanerjee/socialforge on GitHub, a chart by star-history.com

Other skills on socialforge.

More skills from other plugins.

seo

seo

Comprehensive SEO analysis for any website or business type. Full site audits, single-page analysis, technical SEO (crawlability,…

@agricidaniel@agricidanielInstall Skill
brag

brag

Turn the current project website into a short, polished, shareable launch video using Hyperframes. Use when someone says "/brag",…

brag2w21k
@latent-spaces@latent-spacesInstall Skill
geo-audit

geo-audit

Full website GEO+SEO audit with parallel subagent delegation. Orchestrates a comprehensive Generative Engine Optimization audit…

Questions about adapt-copy.

Which coding agents can use adapt-copy?
adapt-copy installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.