{"id":"promote","name":"promote","summary":"ASCII表とCodeSnapレンダリングを使ってX/Twitterリリースプロモーション投稿を生成します。","body":"# /promote — Release Promotion Post Generator\n\nGenerate data-driven X/Twitter posts for plugin releases with ASCII cards ready for CodeSnap screenshots.\n\n## When to use\n\nRun `/promote vX.Y.Z` after tagging a release. Optionally add a title: `/promote v2.8.0 \"LiveView Streams Overhaul\"`.\n\n## Output\n\nAll files go to `scratchpad/x-posts/{version}-release.md` (create directory if needed).\n\nThe output file contains three sections:\n1. **ASCII Card** — box-drawing table for CodeSnap screenshot\n2. **Tweet Thread** — 3-5 tweets in proven format\n3. **CodeSnap Command** — exact CLI command to render the card\n4. **Fact-Check** — every claim with verifiable data source\n\n## Execution Flow\n\n### Step 1: Gather Data\n\nCollect these metrics (all are verifiable commands — run them, don't estimate):\n\n| Metric | How to get it |\n|--------|---------------|\n| File count + insertions/deletions | `git diff --stat {prev-tag}..{tag}` |\n| Skill count | `ls plugins/elixir-phoenix/skills/ \\| wc -l` |\n| Agent count | `ls plugins/elixir-phoenix/agents/*.md \\| wc -l` |\n| Iron Law count | Grep for numbered Iron Laws in CLAUDE.md |\n| Eval scores | `make eval-all` (run it, report actual numbers) |\n| Changelog entries | Read CHANGELOG.md for this version's section |\n| Before/after metrics | Depends on release — look for quantifiable changes |\n\nThe strongest posts have **before/after comparisons**. Look for changes in CHANGELOG.md that have measurable deltas (line counts, counts of affected files, error rates, coverage numbers).\n\n### Step 2: Write the ASCII Card\n\nThe card is the visual centerpiece — it gets screenshotted via CodeSnap and attached to tweet 1.\n\nRules:\n- **Exactly 72 characters wide** (including borders) — consistent with past posts\n- Use Unicode box-drawing: `┌─┐│└┘╞═╡╤╪╧` for borders and separators\n- Include: version + title, headline stats, before/after table, repo URL\n- The table content comes from Step 1 data — pick the 3-5 most impressive changes\n- **VERIFY ALIGNMENT**: After writing the table, run a Python script to check every line has the same visual width. Off-by-one errors are the most common problem — em dashes (`—`) and arrows (`→`) are single-width but easy to miscount. Every line between the top `┌` and bottom `└` borders must be exactly 72 visual characters\n\nAlso save the ASCII card as a separate `.txt` file at `scratchpad/x-posts/{version}-table.txt` for CodeSnap input.\n\nSee `${CLAUDE_SKILL_DIR}/references/templates.md` for the proven card format and past examples.\n\n### Step 3: Write the Tweet Thread\n\nFollow the **hook → findings → details → CTA** structure. Read `${CLAUDE_SKILL_DIR}/references/templates.md` for proven tweet patterns.\n\n**Thread rules (from analytics on 7 posts, 6.9K-9.9K views):**\n\n- **Tweet 1 (Hook)**: Version + one compelling sentence about what changed. Include headline stats (files changed, skills, agents). Repo link here — not in a reply. Add `#ElixirLang #ClaudeCode` hashtags.\n- **Tweet 2-3 (Findings)**: The specific changes with numbers. Use numbered lists. Before/after metrics are the highest-performing content type.\n- **Tweet 4-5 (Details/CTA)**: Additional changes + soft CTA (\"Try it and let me know how it feels\"). Link to release page.\n- **Max 5 tweets** — casual readers drop off after 4-6. If you have more content, cut the least impactful items.\n\n**Voice and tone:**\n- Data-heavy, transparent, no-hype — this is the proven #1 strength\n- Write like a builder sharing real numbers, not a marketer\n- Concrete numbers over adjectives (\"32/40 descriptions rewritten\" not \"improved many descriptions\")\n- Never mention API costs or token prices — subscription user, cost per call is irrelevant\n\n### Step 4: CodeSnap Command\n\nOutput the exact command to render the ASCII card as an image. The card `.txt` file from Step 2 is the input.\n\nUse the config file at `scratchpad/x-posts/codesnap-claude-dark.json` (dark gradient, tight margins, no watermark):\n\n```\ncodesnap -f scratchpad/x-posts/{version}-table.txt \\\n  -o scratchpad/x-posts/{version}-card.png \\\n  --config scratchpad/x-posts/codesnap-claude-dark.json \\\n  --title \"claude-elixir-phoenix {version}\" \\\n  -l text\n```\n\nThen render and verify the image looks correct by reading the output PNG.\n\n### Step 5: Fact-Check\n\nEvery claim in the tweets must have a corresponding entry in the fact-check section:\n\n```markdown\n## Fact-Check\n\n- File stats: `git diff --stat {prev}..{tag}` (output: N files, +X/-Y)\n- Eval scores: `make eval-all` output — N skills avg X.XXX, N agents X.XXX\n- [claim]: [exact command or file:line that proves it]\n```\n\nIf a claim can't be verified with a command or file reference, flag it as **UNVERIFIED** and suggest rewording.\n\n## Bundling Strategy\n\nWhen deciding whether a release warrants its own post:\n\n- **Standalone post**: Major features, impressive before/after metrics, new capabilities\n- **Bundle with next release**: Bug fixes, description tweaks, minor config changes\n- **Skip entirely**: Patch releases with <5 files changed and no user-facing changes\n\nThe v2.6.1 post (37 likes, 1.4K views) vs v2.6.0 (150 likes, 5.5K views) demonstrates this — back-to-back releases dilute signal. When in doubt, wait and bundle.","author":"@oliver-kriska","ownerProfile":null,"authorContacts":null,"sourceUrl":"https://github.com/oliver-kriska/claude-elixir-phoenix/tree/main/.claude/skills/promote","license":"MIT","category":"writing","lang":"en","tokens":1330,"stars":0,"calls30d":2,"claimed":false,"visibility":"public","origin":"crawler","version":"0.1.0","createdAt":"2026-08-22","updatedAt":"2026-08-22","files":[{"path":"references/templates.md","size":8733,"sha256":"7a8bc1252ed26ca709cfd129c3d48dca63c0852341075153f2d23454a87036fe"}],"requires":{"mcp":[],"tools":[]},"safety":{"flags":[{"code":"code.eval","kind":"dangerous-code","where":"references/templates.md:127","excerpt":"eval (","message":"evaluates code at runtime","severity":"warn"}],"scannedAt":"2026-08-22","hasScripts":false,"networkEndpoints":[]}}