Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Development skills for AI coding agents. Plug into your favorite AI coding tool
| `ios-application-dev` | iOS application development guide covering UIKit, SnapKit, and SwiftUI. Touch targets, safe areas, navigation patterns, Dynamic Type, Dark Mode, accessibility, collection views, and Apple HIG compliance. |
| `shader-dev` | Comprehensive GLSL shader techniques for creating stunning visual effects — ray marching, SDF modeling, fluid simulation, particle systems, procedural generation, lighting, post-processing, and more. ShaderToy-compatible. |
| `gif-sticker-maker` | Convert photos (people, pets, objects, logos) into 4 animated GIF stickers with captions. Funko Pop / Pop Mart style, powered by MiniMax Image & Video Generation API. |
| `social-media-kit` | Generate branded image packs for social media platforms. Supports Instagram (Post, Story), X/Twitter, YouTube thumbnails, and LinkedIn. Batch generation with platform-specific aspect ratios via MiniMax Image API. |
| `minimax-pdf` | Generate, fill, and reformat PDF documents with a token-based design system. CREATE polished PDFs from scratch (15 cover styles), FILL existing form fields, or REFORMAT documents into a new design. Print-ready output with typography and color derived from document type. |
| `pptx-generator` | Generate, edit, and read PowerPoint presentations. Create from scratch with PptxGenJS (cover, TOC, content, section divider, summary slides), edit existing PPTX via XML workflows, or extract text with markitdown. |
| `minimax-xlsx` | Open, create, read, analyze, edit, or validate Excel/spreadsheet files (.xlsx, .xlsm, .csv, .tsv). Covers creating new xlsx from scratch via XML templates, reading and analyzing with pandas, editing existing files with zero format loss, formula recalculation, validation, and professional financial formatting. |
Expand Down
1 change: 1 addition & 0 deletions README_zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
| `ios-application-dev` | iOS 应用开发指南,涵盖 UIKit、SnapKit 和 SwiftUI。触控目标、安全区域、导航模式、Dynamic Type、深色模式、无障碍、集合视图,符合 Apple HIG 规范。 |
| `shader-dev` | 全面的 GLSL 着色器技术,用于创建惊艳的视觉效果 — 光线行进、SDF 建模、流体模拟、粒子系统、程序化生成、光照、后处理等。兼容 ShaderToy。 |
| `gif-sticker-maker` | 将照片(人物、宠物、物品、Logo)转换为 4 张带字幕的动画 GIF 贴纸。Funko Pop / Pop Mart 盲盒风格,基于 MiniMax 图片与视频生成 API。 |
| `social-media-kit` | 为社交媒体平台批量生成品牌图片。支持 Instagram(帖子、故事)、X/Twitter、YouTube 缩略图和 LinkedIn。通过 MiniMax 图片生成 API 按平台规格批量创建。 |
| `minimax-pdf` | 基于 token 化设计系统生成、填写和重排 PDF 文档。支持三种模式:CREATE(从零生成,15 种封面风格)、FILL(填写现有表单字段)、REFORMAT(将已有文档重排为新设计)。排版与配色由文档类型自动推导,输出即可打印。 |
| `pptx-generator` | 生成、编辑和读取 PowerPoint 演示文稿。支持用 PptxGenJS 从零创建(封面、目录、内容、分节页、总结页),通过 XML 工作流编辑现有 PPTX,或用 markitdown 提取文本。 |
| `minimax-xlsx` | 打开、创建、读取、分析、编辑或验证 Excel/电子表格文件(.xlsx、.xlsm、.csv、.tsv)。支持通过 XML 模板从零创建 xlsx、使用 pandas 读取分析、零格式损失编辑现有文件、公式重算与验证、专业财务格式化。 |
Expand Down
133 changes: 133 additions & 0 deletions skills/social-media-kit/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
---
name: social-media-kit
description: |
Generate branded social media content packs using MiniMax Image API.
Use when: creating social media posts, generating branded images for multiple platforms,
batch content creation for Instagram, X/Twitter, YouTube, LinkedIn.
Triggers: social media, content pack, Instagram post, YouTube thumbnail, branded images,
marketing visuals, social content, platform images.
license: MIT
metadata:
version: "1.0"
category: creative-tools
output_format: png
sources:
- MiniMax Image Generation API (image-01)
---

# Social Media Kit

Generate branded image packs for social media platforms.

## Prerequisites

Before starting, ensure:

1. **Python venv** is activated with dependencies from [requirements.txt](references/requirements.txt) installed
2. **`MINIMAX_API_KEY`** is exported (e.g. `export MINIMAX_API_KEY='your-key'`)

If any prerequisite is missing, set it up first. Do NOT proceed without both.

## Workflow

### Step 0: Brand Brief

Collect brand information from the user:

> "Tell me about your brand or product. I need: name, visual style (colors, mood), and what the content is about."

Extract:
- **Brand name** - used in file naming
- **Visual style** - colors, mood, aesthetic direction
- **Content theme** - what the images should communicate
- **Target audience** - informs composition and style

### Step 1: Platform Selection

Present the available platforms. Reference [platform-specs.md](references/platform-specs.md) for dimensions.

| Platform | Format | Aspect Ratio |
|----------|--------|--------------|
| Instagram Post | Square | 1:1 |
| Instagram Story | Vertical | 9:16 |
| X/Twitter Post | Landscape | 16:9 |
| YouTube Thumbnail | Landscape | 16:9 |
| LinkedIn Post | Landscape | 16:9 |

Ask the user:
> "Which platforms do you need images for? Pick all that apply, or say 'all' for the full set."

### Step 2: Prompt Engineering

For each selected platform, craft an image generation prompt that accounts for:

1. **Composition** - square images need centered subjects, wide images need horizontal layouts, tall images need vertical stacking
2. **Brand elements** - incorporate the brand colors and style
3. **Text-safe zones** - leave space for overlay text on thumbnails and posts
4. **Platform conventions** - YouTube thumbnails are bold and high-contrast, Instagram posts are polished and aspirational, LinkedIn is professional

**Prompt template per platform:**

- **Instagram Post (1:1):** `"{content theme}, centered composition, {visual style}, clean and polished, social media post, square format"`
- **Instagram Story (9:16):** `"{content theme}, vertical composition, {visual style}, full-height layout, mobile-first design"`
- **X/Twitter Post (16:9):** `"{content theme}, wide horizontal composition, {visual style}, clean background, room for text overlay"`
- **YouTube Thumbnail (16:9):** `"{content theme}, bold and eye-catching, {visual style}, high contrast, dramatic lighting, thumbnail style"`
- **LinkedIn Post (16:9):** `"{content theme}, professional and clean, {visual style}, corporate-friendly, modern business aesthetic"`

### Step 3: Generate Images

**Tool**: `scripts/social_kit.py`

Generate all images in one batch:

```bash
python3 scripts/social_kit.py \
--brand "Brand Name" \
--prompt "content theme, visual style" \
--platforms instagram_post instagram_story x_post youtube_thumb linkedin_post \
-o output/
```

Or generate individually with `minimax_image.py`:

```bash
python3 scripts/minimax_image.py "prompt for instagram" -o output/brand_instagram_post.png --ratio 1:1
python3 scripts/minimax_image.py "prompt for story" -o output/brand_instagram_story.png --ratio 9:16
python3 scripts/minimax_image.py "prompt for x" -o output/brand_x_post.png --ratio 16:9
python3 scripts/minimax_image.py "prompt for youtube" -o output/brand_youtube_thumb.png --ratio 16:9
python3 scripts/minimax_image.py "prompt for linkedin" -o output/brand_linkedin_post.png --ratio 16:9
```

All calls are independent - **run concurrently** for speed.

### Step 4: Review & Iterate

Show the generated images to the user. For each image:
- If the user approves, keep it
- If they want changes, regenerate with an adjusted prompt
- Offer to generate variations (up to 4 per platform via the `--n` flag)

### Step 5: Deliver

Output format:
1. Summary line with count
2. File listing with platform labels

```
Social media kit created: 5 images for "Brand Name"

Instagram Post (1:1): output/brand_instagram_post.png
Instagram Story (9:16): output/brand_instagram_story.png
X/Twitter Post (16:9): output/brand_x_post.png
YouTube Thumbnail (16:9): output/brand_youtube_thumb.png
LinkedIn Post (16:9): output/brand_linkedin_post.png
```

## Rules

- Always use the correct aspect ratio for each platform. Wrong dimensions look unprofessional.
- All image prompts must be in **English** regardless of user language.
- File names follow the pattern: `{brand}_{platform}.png` (lowercase, underscores).
- Generate at least 1 image per selected platform. Offer variations if the user wants options.
- YouTube thumbnails need bold, high-contrast compositions. They are viewed at small sizes.
- Instagram Stories are viewed on mobile. Keep visual elements large and centered.
47 changes: 47 additions & 0 deletions skills/social-media-kit/references/platform-specs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Social Media Platform Specs

Image dimensions and aspect ratios for major social media platforms.

## Platform Reference

| Platform | Format | Recommended Size | Aspect Ratio | MiniMax Ratio | Notes |
|----------|--------|-----------------|--------------|---------------|-------|
| Instagram Post | Square | 1080 x 1080 | 1:1 | `1:1` | Feed post, most common format |
| Instagram Story | Vertical | 1080 x 1920 | 9:16 | `9:16` | Full-screen mobile |
| Instagram Reel Cover | Vertical | 1080 x 1920 | 9:16 | `9:16` | Same as Story |
| X/Twitter Post | Landscape | 1200 x 675 | 16:9 | `16:9` | In-feed image |
| X/Twitter Header | Wide | 1500 x 500 | 3:1 | `21:9` | Profile banner (closest match) |
| YouTube Thumbnail | Landscape | 1280 x 720 | 16:9 | `16:9` | Video thumbnail |
| LinkedIn Post | Landscape | 1200 x 627 | ~16:9 | `16:9` | In-feed image |
| LinkedIn Banner | Wide | 1584 x 396 | 4:1 | `21:9` | Profile banner (closest match) |
| Facebook Post | Landscape | 1200 x 630 | ~16:9 | `16:9` | In-feed image |

## MiniMax Supported Aspect Ratios

The MiniMax Image API (`image-01`) supports these aspect ratios:

- `1:1` — Square (Instagram Post)
- `16:9` — Landscape (X, YouTube, LinkedIn, Facebook)
- `4:3` — Classic landscape
- `3:2` — Photo landscape
- `2:3` — Portrait
- `3:4` — Classic portrait
- `9:16` — Vertical (Instagram Story, Reels, TikTok)
- `21:9` — Ultra-wide (banners, headers)

## Composition Tips

### Square (1:1)
- Center the subject
- Keep important elements away from edges
- Works for both product shots and lifestyle images

### Landscape (16:9)
- Use the rule of thirds horizontally
- Leave space for text overlays on one side
- YouTube thumbnails: make text large, use high contrast

### Vertical (9:16)
- Stack elements vertically
- Keep the focal point in the upper 2/3 (bottom may be cut by UI elements)
- Use the full height for impact
1 change: 1 addition & 0 deletions skills/social-media-kit/references/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
requests>=2.28.0
133 changes: 133 additions & 0 deletions skills/social-media-kit/scripts/minimax_image.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
#!/usr/bin/env python3
# SPDX-License-Identifier: MIT
"""
MiniMax Text-to-Image — synchronous generation.

Usage:
python minimax_image.py "A cat in space" -o cat.png
python minimax_image.py "Mountain landscape" -o bg.png --ratio 16:9
python minimax_image.py "Product icons" -o icons.png -n 4 --ratio 1:1

Env: MINIMAX_API_KEY (required)
"""

import os
import sys
import json
import argparse
import requests

API_KEY = os.getenv("MINIMAX_API_KEY")
API_BASE = "https://api.minimax.io/v1"

ASPECT_RATIOS = ["1:1", "16:9", "4:3", "3:2", "2:3", "3:4", "9:16", "21:9"]


def _headers():
if not API_KEY:
raise SystemExit("ERROR: MINIMAX_API_KEY is not set.\n export MINIMAX_API_KEY='your-key'")
return {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json",
}


def generate_image(
prompt: str,
model: str = "image-01",
aspect_ratio: str = "1:1",
n: int = 1,
response_format: str = "url",
prompt_optimizer: bool = False,
seed: int = None,
) -> dict:
"""Generate image(s). Returns API response dict."""
payload = {
"model": model,
"prompt": prompt,
"aspect_ratio": aspect_ratio,
"n": n,
"response_format": response_format,
"prompt_optimizer": prompt_optimizer,
}
if seed is not None:
payload["seed"] = seed

resp = requests.post(
f"{API_BASE}/image_generation",
headers=_headers(),
json=payload,
timeout=120,
)
resp.raise_for_status()
data = resp.json()

base_resp = data.get("base_resp", {})
if base_resp.get("status_code", 0) != 0:
raise SystemExit(f"API Error [{base_resp.get('status_code')}]: {base_resp.get('status_msg')}")

return data


def download_and_save(url: str, output_path: str):
"""Download image from URL and save."""
resp = requests.get(url, timeout=60)
resp.raise_for_status()
with open(output_path, "wb") as f:
f.write(resp.content)
return len(resp.content)


def main():
p = argparse.ArgumentParser(description="MiniMax Text-to-Image")
p.add_argument("prompt", help="Image description (max 1500 chars)")
p.add_argument("-o", "--output", required=True, help="Output file path (.png/.jpg)")
p.add_argument("--model", default="image-01", help="Model (default: image-01)")
p.add_argument("--ratio", default="1:1", choices=ASPECT_RATIOS, help="Aspect ratio (default: 1:1)")
p.add_argument("-n", "--count", type=int, default=1, choices=range(1, 10), help="Number of images (1-9, default: 1)")
p.add_argument("--seed", type=int, default=None, help="Random seed for reproducibility")
p.add_argument("--optimize", action="store_true", help="Enable prompt auto-optimization")
p.add_argument("--base64", action="store_true", help="Use base64 response instead of URL")
args = p.parse_args()

os.makedirs(os.path.dirname(args.output) or ".", exist_ok=True)

fmt = "base64" if args.base64 else "url"
result = generate_image(
prompt=args.prompt,
model=args.model,
aspect_ratio=args.ratio,
n=args.count,
response_format=fmt,
prompt_optimizer=args.optimize,
seed=args.seed,
)

meta = result.get("metadata", {})
print(f"Generated: {meta.get('success_count', '?')} success, {meta.get('failed_count', '?')} failed")

if args.base64:
images = result.get("data", {}).get("image_base64", [])
import base64
for i, b64 in enumerate(images):
path = args.output if len(images) == 1 else _numbered_path(args.output, i)
raw = base64.b64decode(b64)
with open(path, "wb") as f:
f.write(raw)
print(f"OK: {len(raw)} bytes -> {path}")
else:
urls = result.get("data", {}).get("image_urls", [])
for i, url in enumerate(urls):
path = args.output if len(urls) == 1 else _numbered_path(args.output, i)
size = download_and_save(url, path)
print(f"OK: {size} bytes -> {path}")


def _numbered_path(path: str, index: int) -> str:
"""Insert index before extension: out.png -> out-0.png"""
base, ext = os.path.splitext(path)
return f"{base}-{index}{ext}"


if __name__ == "__main__":
main()
Loading