Skill: fly3094/seo-content-pro (version 1.4.0)

--- name: seo-content-pro description: Advanced SEO content creation with AI humanization, image generation, multi-language support, content refresh, SEO scoring, and competitor analysis. Perfect for content creators and agencies. author: fly3094 version: 1.4.0 tags: [seo, content, writing, article, blog, marketing, multi-language, research, video-seo, ai-detection, youtube, bilibili, transcript] support: paypal: [REDACTED_SECRET] email: [REDACTED_SECRET] metadata: clawdbot: emoji: 📝 requires: bins: - python3 - curl config: env: CONTENT_TONE: description: Default tone (professional|casual|technical|friendly) default: "professional" required: false DEFAULT_LENGTH: description: Default word count default: "2000" required: false CONTENT_LANGUAGE: description: Target language (en|zh|es|fr|de|ja) default: "en" required: false SEARXNG_URL: description: SearXNG instance for privacy-respecting research default: "http://localhost:8080" required: false --- # SEO Content Pro 📝 **Rank higher on Google. Write faster.** AI-powered SEO content that competes with top 10 results. **Time saved:** 5 hours/article → 30 minutes/article **Result:** 1500-3000 word articles with SEO score 80+ ## What It Does - 🔍 **Topic Research**: Analyzes top-ranking content using SearXNG (privacy-respecting, no tracking) - 📋 **Outline Generation**: Creates SEO-optimized article structures (H1/H2/H3 hierarchy) - ✍️ **First Draft**: Writes 1500-3000 word articles in 6 languages - 🎯 **Keyword Integration**: Suggests and integrates primary/secondary keywords naturally - 📊 **Competitor Analysis**: Identifies content gaps vs top 10 ranking pages - 🌐 **Multi-language**: English, Chinese, Spanish, French, German, Japanese - 🔄 **Content Refresh**: Update old articles with new data and insights - 📈 **SEO Score**: Get content quality score (0-100) with specific improvement suggestions - 🤖 **AI Humanization** (v1.2 NEW): Detect and transform AI-generated text to bypass AI detectors - 🖼️ **Image Generation** (v1.2 NEW): Generate featured images using Google Gemini 3 Pro Image API - 🎬 **Video SEO** (v1.4 NEW): Optimize YouTube/B 站 video titles, descriptions, tags, and transcripts - 📝 **Transcript Processing** (v1.4 NEW): Extract and optimize video transcripts for SEO ## Quick Start (2 minutes) ```bash # 1. Install clawhub install seo-content-pro # 2. Create your first article # Just ask: "Write a 2000-word SEO article about AI automation tools" ``` **Full workflow example:** ``` User: Create SEO article about "best AI automation tools" - 2500 words AI: 1. 🔍 Researching top 10 ranking pages... 2. 📋 Generating SEO-optimized outline... 3. ✍️ Writing 2500-word draft... 4. 📊 Analyzing SEO score: 85/100 5. 🎯 Keyword density: 2.1% (optimal) 6. ✅ Article ready! Word count: 2,547 Reading time: 11 minutes SEO Score: 85/100 Primary keyword: "AI automation tools" (18 mentions) Secondary keywords: automation software, AI tools, workflow automation ``` ## New Features in v1.2.0 ### 🤖 AI Content Humanization Detect and transform AI-generated text to make it more natural and bypass AI detectors. **Usage:** ```bash # Humanize existing content python3 scripts/humanize.py --input article.md --output article-humanized.md # Detect AI content python3 scripts/detect_ai.py --input article.md # Compare before/after python3 scripts/compare.py --input article.md ``` **AI Detection Patterns (16 types):** - 🔴 Critical: Citation bugs, knowledge cutoff, chatbot artifacts - 🟠 High: AI vocabulary, significance inflation, promotional language - 🟡 Medium: Superficial analysis, filler phrases - 🟢 Style: Curly quotes, em-dashes overuse ### 🎬 Video SEO (v1.4 NEW) Optimize videos for YouTube and B 站 (Bilibili) to rank higher in video search results. **Usage:** ```bash # Optimize YouTube video python3 scripts/video_seo.py --platform youtube --title "AI Automation Tutorial" --duration "10:25" # Optimize B 站 video python3 scripts/video_seo.py --platform bilibili --title "AI 自动化教程" --tags "[AI,自动化，教程]" # Process transcript python3 scripts/transcript.py --input video.srt --output optimized.txt ``` **Features:** - Title optimization (under 60 characters for YouTube, under 80 for B 站) - Description generation with timestamps - Tag suggestions based on topic - Transcript SEO optimization - Chapter markers for long videos ### 🖼️ Featured Image Generation Generate custom featured images for your articles using Google Gemini 3 Pro Image API. **Usage:** ```bash # Generate new image python3 scripts/generate_image.py --prompt "AI automation technology" --filename featured.png # With resolution option python3 scripts/generate_image.py --prompt "SEO dashboard" --filename seo-image.png --resolution 2K # Edit existing image python3 scripts/generate_image.py --prompt "Make it more professional" --input-image old.png --filename new.png ``` **Resolution Options:** - 1K (default) - ~1024px, fast iteration - 2K - ~2048px, standard quality - 4K - ~4096px, high resolution **API Key:** Set `GEMINI_API_KEY` environment variable or use `--api-key` argument. ### Complete Workflow (v1.2) ```bash # 1. Generate SEO content # Ask AI: "Create SEO article about AI automation tools - 2500 words" # 2. Humanize content (optional) python3 scripts/humanize.py --input article.md --output article-humanized.md # 3. Generate featured image python3 scripts/generate_image.py --prompt "AI automation dashboard" --filename featured.png --resolution 2K # 4. Detect AI content (optional, for quality check) python3 scripts/detect_ai.py --input article.md # 5. Review SEO score # AI will provide SEO analysis with score and suggestions ``` ## Commands ### Research a Topic ``` Research "[keyword/topic]" for SEO content ``` ### Generate Outline ``` Create outline for "[article title]" targeting "[primary keyword]" ``` ### Write Draft ``` Write draft for "[article title]" using outline, 2000 words, tone: professional ``` ### Full Workflow ``` Create SEO article about "[topic]" - research, outline, and draft (2500 words) ``` ### Content Refresh ``` Update and improve this article with latest data and SEO best practices ``` ### SEO Analysis ``` Analyze this content and provide SEO score with improvement suggestions ``` ### Multi-language ``` Create SEO article about "[topic]" in Chinese, 2000 words ``` ## Configuration ### Environment Variables ```bash # Default content tone export CONTENT_TONE="professional" # professional|casual|technical|friendly # Default word count export DEFAULT_LENGTH="2000" # Include FAQ section export INCLUDE_FAQ="true" # true|false # Target language export CONTENT_LANGUAGE="en" # en|zh|es|fr|de|ja # SearXNG instance (for privacy-respecting research) export SEARXNG_URL="http://localhost:8080" ``` ### OpenClaw Config ```json { "env": { "CONTENT_TONE": "professional", "DEFAULT_LENGTH": "2000", "INCLUDE_FAQ": "true", "CONTENT_LANGUAGE": "en" } } ``` ## Output Format Each article includes: - **Meta Title** (50-60 characters) - **Meta Description** (150-160 characters) - **H1 Title** (engaging, includes primary keyword) - **Introduction** (150-200 words, hooks reader) - **H2/H3 Sections** (proper hierarchy, keyword-optimized) - **Conclusion with CTA** (clear next steps) - **Internal/External Link Suggestions** - **FAQ Section** (3-5 questions with answers) - **SEO Score** (0-100 with breakdown) ## Example Usage ### Basic Article ``` User: Create SEO article about "best AI automation tools for small business" - 2500 words Assistant: 1. 🔍 Researching top 10 ranking pages... 2. 📊 Analyzing content gaps and keyword opportunities... 3. 📋 Generating optimized outline... 4. ✍️ Writing 2500-word draft with H2/H3 structure... 5. 📈 Calculating SEO score and suggestions... ✅ Article ready! SEO Score: 87/100 ``` ### Multi-language ``` User: Create SEO article about "remote work productivity" in Chinese, 2000 words Assistant: Generating Chinese content for "远程工作效率"... ✅ 文章完成！SEO 分数：85/100 ``` ### Content Refresh ``` User: [paste old article] Update this article with 2026 data and improve SEO Assistant: 1. Analyzing current content... 2. Researching latest data and statistics... 3. Identifying SEO improvements... 4. Updating with fresh insights... ✅ Refreshed! SEO Score improved from 62 to 89 (+27 points) ``` ## SEO Score Breakdown Your content is scored on: | Factor | Weight | Description | |--------|--------|-------------| | Keyword Usage | 20% | Primary/secondary keyword placement | | Content Length | 15% | Optimal word count for topic | | Readability | 15% | Flesch score, sentence structure | | Heading Structure | 15% | Proper H1/H2/H3 hierarchy | | Meta Tags | 10% | Title and description optimization | | Internal Links | 10% | Suggested internal linking | | External Links | 10% | Quality external references | | FAQ Section | 5% | Comprehensive FAQ coverage | ## Integration with Other Skills ### social-media-automator ``` 1. Create SEO article with seo-content-pro 2. Generate social posts with social-media-automator 3. Schedule and publish across platforms ``` ### rss-to-social ``` 1. Monitor industry RSS feeds with rss-to-social 2. Identify trending topics 3. Create content with seo-content-pro 4. Auto-publish to social media ``` Complete content automation loop! 🔄 ## Use Cases ### Content Marketers - Scale content production 5-10x - Maintain consistent quality - Target multiple keywords efficiently ### SEO Agencies - White-label content creation - Serve more clients with same team - Standardize quality across writers ### Solopreneurs - Create professional content without hiring - Save $500-2000/month on writing costs - Focus on business, not content creation ### Multi-language Businesses - Localize content for different markets - Maintain brand voice across languages - Scale globally with consistent quality ## Tips for Best Results 1. **Provide Context**: Tell the skill your target audience and goal 2. **Specify Tone**: Match your brand voice (professional, casual, technical) 3. **Add Examples**: Share articles you like for style reference 4. **Review & Edit**: AI draft is a starting point – add your expertise 5. **Update Regularly**: Use content refresh quarterly to keep articles current 6. **Target Long-tail**: More specific keywords = easier to rank ## Pricing Integration This skill powers LobsterLabs content services: | Service | Price | Delivery | |---------|-------|----------| | Single Article | $300-500 | 3-5 days | | Monthly Pack (4 articles) | $1,500-2,500 | Monthly | | White-label Agency | $3,000+/month | Unlimited | | Content + Social Bundle | $2,000-4,000/month | Full service | **ROI Example:** - Cost: $2,000/month (4 articles + social) - Client revenue from content: $10,000-50,000/month - ROI: 5-25x Contact: PayPal [REDACTED_SECRET] ## Troubleshooting ### Low SEO Score - Check keyword density (1-2% for primary keyword) - Add more H2/H3 subheadings - Increase content length if under 1500 words - Add FAQ section if missing ### Research Issues - Verify SearXNG instance is running - Check internet connection - Try alternative search terms ### Language Quality - Specify language explicitly in command - For best results, use native language - Review and adjust cultural references ## Changelog ### 1.0.0 (2026-03-07) - Initial release - Multi-language support (6 languages) - Content refresh feature - SEO scoring system - Competitor analysis - SearXNG integration - Integrations with social-media-automator and rss-to-social --- ## 💖 支持作者 如果你觉得这个技能有用，请考虑打赏支持： - **PayPal**: [REDACTED_SECRET] - **邮箱**: [REDACTED_SECRET] 你的支持是我持续改进的动力！ --- ## 🆕 新增功能（v1.1.0） ### AI 标题生成器 - 5 种标题模板（How-to、List、Question、Secret、Comparison） - A/B 测试支持，生成 3-10 个变体 - 标题评分系统（0-100 分） - 爆款标题特征分析 ### 使用示例 ```bash # 生成标题 python3 scripts/title_generator.py "SEO 内容写作" "写出爆款文章" 10 # 输出示例： 1. [85 分] 如何在 30 分钟内写出爆款文章（完整指南） 2. [90 分] 3 个 SEO 内容写作技巧，第 3 个太实用了 3. [80 分] 为什么你的 SEO 内容总是失败？原因在这里 ``` ### A/B 测试工作流 1. 生成 5-10 个标题变体 2. 选择评分最高的 3 个 3. 在不同平台/时间测试 4. 分析数据，选择最佳标题

path: README.md
content: # SEO Content Pro v1.1.0

高级 SEO 内容创作工具，支持多语言、A/B 测试、AI 标题生成器。

## ✨ 功能特性

### v1.1.0 新增
- 🎯 **AI 标题生成器** - 自动生成多个吸引人的标题选项
- 🧪 **A/B 测试支持** - 测试不同标题和内容的效果
- 📊 **竞品分析集成** - 分析竞争对手内容策略

### 核心功能
- 🌍 **多语言支持** - en/zh/es/fr/de/ja
- 📝 **SEO 评分** - 实时评估内容 SEO 质量
- 🔄 **内容刷新** - 自动更新旧内容
- 🔍 **关键词研究** - 智能关键词建议

## 🚀 快速开始

```bash
# 安装
clawhub install seo-content-pro

# 使用
/seo-content-pro 写一篇关于 AI 的 SEO 文章

# 生成标题
/seo-content-pro --generate-titles "人工智能在医疗领域的应用"

# A/B 测试
/seo-content-pro --ab-test "标题 A" "标题 B" --topic "AI 技术"
```

## 💰 支持作者

如果这个技能对你有帮助，欢迎打赏支持：

- **PayPal**: [REDACTED_SECRET]
- **Email**: [REDACTED_SECRET]

## 📖 使用案例

### 案例 1：博客文章创作
```
/seo-content-pro 写一篇关于机器学习入门的博客文章，2000 字，专业语气
```

### 案例 2：多语言内容
```
/seo-content-pro 写一篇产品介绍，语言=zh,en，语气=friendly
```

### 案例 3：A/B 测试标题
```
/seo-content-pro --generate-titles "5 个机器学习技巧" --count 10
```

## 📝 更新日志

### v1.1.0 (2026-03-17)
- ✅ 新增 AI 标题生成器
- ✅ 新增 A/B 测试支持
- ✅ 竞品分析集成

### v1.0.2
- 多语言支持
- SEO 评分系统

## 📄 License

MIT License


path: package.json
content: {
  "name": "seo-content-pro",
  "version": "1.4.0",
  "description": "Advanced SEO content creation with AI humanization, image generation, multi-language support",
  "author": "fly3094",
  "license": "MIT",
  "keywords": [
    "seo",
    "content",
    "writing",
    "article",
    "blog",
    "marketing",
    "ai-humanization",
    "image-generation"
  ],
  "repository": "https://github.com/lobsterlabs/seo-content-pro",
  "support": {
    "paypal": "[REDACTED_SECRET]",
    "email": "[REDACTED_SECRET]"
  }
}

path: scripts/detect_ai.py
content: #!/usr/bin/env python3
"""Detect AI patterns in text based on Wikipedia's Signs of AI Writing."""
import argparse, json, re, sys
from pathlib import Path
from dataclasses import dataclass, field

SCRIPT_DIR = Path(__file__).parent
PATTERNS = json.loads((SCRIPT_DIR / "patterns.json").read_text())

@dataclass
class DetectionResult:
    significance_inflation: list = field(default_factory=list)
    notability_emphasis: list = field(default_factory=list)
    superficial_analysis: list = field(default_factory=list)
    promotional_language: list = field(default_factory=list)
    vague_attributions: list = field(default_factory=list)
    challenges_formula: list = field(default_factory=list)
    ai_vocabulary: list = field(default_factory=list)
    copula_avoidance: list = field(default_factory=list)
    filler_phrases: list = field(default_factory=list)
    chatbot_artifacts: list = field(default_factory=list)
    hedging_phrases: list = field(default_factory=list)
    negative_parallelisms: list = field(default_factory=list)
    rule_of_three: list = field(default_factory=list)
    markdown_artifacts: list = field(default_factory=list)
    citation_bugs: list = field(default_factory=list)
    knowledge_cutoff: list = field(default_factory=list)
    curly_quotes: int = 0
    em_dashes: int = 0
    total_issues: int = 0
    ai_probability: str = "low"
    word_count: int = 0

def find_matches(text: str, patterns: list) -> list:
    matches, lower = [], text.lower()
    for p in patterns:
        count = lower.count(p.lower())
        if count > 0:
            matches.append((p, count))
    return sorted(matches, key=lambda x: -x[1])

def detect(text: str) -> DetectionResult:
    r = DetectionResult()
    r.word_count = len(text.split())
    r.significance_inflation = find_matches(text, PATTERNS["significance_inflation"])
    r.notability_emphasis = find_matches(text, PATTERNS["notability_emphasis"])
    r.superficial_analysis = find_matches(text, PATTERNS["superficial_analysis"])
    r.promotional_language = find_matches(text, PATTERNS["promotional_language"])
    r.vague_attributions = find_matches(text, PATTERNS["vague_attributions"])
    r.challenges_formula = find_matches(text, PATTERNS["challenges_formula"])
    r.ai_vocabulary = find_matches(text, PATTERNS["ai_vocabulary"])
    r.copula_avoidance = find_matches(text, list(PATTERNS["copula_avoidance"].keys()))
    r.filler_phrases = find_matches(text, list(PATTERNS["filler_replacements"].keys()))
    r.chatbot_artifacts = find_matches(text, PATTERNS["chatbot_artifacts"])
    r.hedging_phrases = find_matches(text, PATTERNS["hedging_phrases"])
    r.negative_parallelisms = find_matches(text, PATTERNS["negative_parallelisms"])
    r.rule_of_three = find_matches(text, PATTERNS["rule_of_three_patterns"])
    r.markdown_artifacts = find_matches(text, PATTERNS["markdown_artifacts"])
    r.citation_bugs = find_matches(text, PATTERNS["citation_bugs"])
    r.knowledge_cutoff = find_matches(text, PATTERNS["knowledge_cutoff"])
    r.curly_quotes = len(re.findall(r'[""'']', text))
    r.em_dashes = text.count("—") + text.count(" -- ")
    
    r.total_issues = (
        sum(c for _, c in r.significance_inflation) + sum(c for _, c in r.notability_emphasis) +
        sum(c for _, c in r.superficial_analysis) + sum(c for _, c in r.promotional_language) +
        sum(c for _, c in r.vague_attributions) + sum(c for _, c in r.challenges_formula) +
        sum(c for _, c in r.ai_vocabulary) + sum(c for _, c in r.copula_avoidance) +
        sum(c for _, c in r.filler_phrases) + sum(c for _, c in r.chatbot_artifacts) * 3 +
        sum(c for _, c in r.hedging_phrases) + sum(c for _, c in r.negative_parallelisms) +
        sum(c for _, c in r.markdown_artifacts) * 2 + sum(c for _, c in r.citation_bugs) * 5 +
        sum(c for _, c in r.knowledge_cutoff) * 3 + r.curly_quotes + (r.em_dashes if r.em_dashes > 3 else 0)
    )
    
    density = r.total_issues / max(r.word_count, 1) * 100
    if r.citation_bugs or r.knowledge_cutoff or r.chatbot_artifacts:
        r.ai_probability = "very high"
    elif density > 5 or r.total_issues > 30:
        r.ai_probability = "high"
    elif density > 2 or r.total_issues > 15:
        r.ai_probability = "medium"
    return r

def print_section(title: str, items: list, replacements: dict = None):
    if not items:
        return
    print(f"{title}:")
    for phrase, count in items:
        if replacements and phrase in replacements:
            repl = replacements[phrase]
            arrow = f' → "{repl}"' if repl else " → (remove)"
            print(f"  • \"{phrase}\"{arrow}: {count}x")
        else:
            print(f"  • {phrase}: {count}x")
    print()

def print_report(r: DetectionResult):
    icons = {"very high": "🔴", "high": "🟠", "medium": "🟡", "low": "🟢"}
    print(f"\n{'='*60}")
    print(f"AI DETECTION SCAN - {r.total_issues} issues ({r.word_count} words)")
    print(f"AI Probability: {icons.get(r.ai_probability, '')} {r.ai_probability.upper()}")
    print(f"{'='*60}\n")
    
    if r.citation_bugs:
        print("⚠️  CRITICAL: CHATGPT CITATION BUGS")
        print_section("Citation Artifacts", r.citation_bugs)
    if r.knowledge_cutoff:
        print("⚠️  CRITICAL: KNOWLEDGE CUTOFF PHRASES")
        print_section("Cutoff Phrases", r.knowledge_cutoff)
    if r.chatbot_artifacts:
        print("⚠️  HIGH: CHATBOT ARTIFACTS")
        print_section("Artifacts", r.chatbot_artifacts)
    if r.markdown_artifacts:
        print("⚠️  MARKDOWN DETECTED")
        print_section("Markdown", r.markdown_artifacts)
    
    print_section("SIGNIFICANCE INFLATION", r.significance_inflation)
    print_section("PROMOTIONAL LANGUAGE", r.promotional_language)
    print_section("AI VOCABULARY", r.ai_vocabulary)
    print_section("SUPERFICIAL -ING", r.superficial_analysis)
    print_section("COPULA AVOIDANCE", r.copula_avoidance, PATTERNS["copula_avoidance"])
    print_section("FILLER PHRASES", r.filler_phrases, PATTERNS["filler_replacements"])
    print_section("VAGUE ATTRIBUTIONS", r.vague_attributions)
    print_section("CHALLENGES FORMULA", r.challenges_formula)
    print_section("HEDGING", r.hedging_phrases)
    print_section("NEGATIVE PARALLELISMS", r.negative_parallelisms)
    print_section("NOTABILITY EMPHASIS", r.notability_emphasis)
    
    if r.curly_quotes:
        print(f"CURLY QUOTES: {r.curly_quotes} (ChatGPT signature)\n")
    if r.em_dashes > 3:
        print(f"EM DASHES: {r.em_dashes} (excessive)\n")
    if r.total_issues == 0:
        print("✓ No AI patterns detected.\n")

def main():
    parser = argparse.ArgumentParser(description="Detect AI patterns in text")
    parser.add_argument("input", nargs="?", help="Input file (or stdin)")
    parser.add_argument("--json", "-j", action="store_true", help="JSON output")
    parser.add_argument("--score-only", "-s", action="store_true", help="Score and probability only")
    args = parser.parse_args()
    
    text = Path(args.input).read_text() if args.input else sys.stdin.read()
    result = detect(text)
    
    if args.json:
        print(json.dumps({
            "total_issues": result.total_issues, "word_count": result.word_count,
            "ai_probability": result.ai_probability, "significance_inflation": result.significance_inflation,
            "promotional_language": result.promotional_language, "ai_vocabulary": result.ai_vocabulary,
            "chatbot_artifacts": result.chatbot_artifacts, "citation_bugs": result.citation_bugs,
            "filler_phrases": result.filler_phrases, "curly_quotes": result.curly_quotes, "em_dashes": result.em_dashes,
        }, indent=2))
    elif args.score_only:
        print(f"Issues: {result.total_issues} | Words: {result.word_count} | AI: {result.ai_probability}")
    else:
        print_report(result)

if __name__ == "__main__":
    main()


path: scripts/generate_image.py
content: #!/usr/bin/env python3
# /// script
# requires-python = ">=3.10"
# dependencies = [
#     "google-genai>=1.0.0",
#     "pillow>=10.0.0",
# ]
# ///
"""
Generate images using Google's Nano Banana Pro (Gemini 3 Pro Image) API.

Usage:
    uv run generate_image.py --prompt "your image description" --filename "output.png" [--resolution 1K|2K|4K] [--api-key KEY]
"""

import argparse
import os
import sys
from pathlib import Path


def get_api_key(provided_key: str | None) -> str | None:
    """Get API key from argument first, then environment."""
    if provided_key:
        return provided_key
    return os.environ.get("GEMINI_API_KEY")


def main():
    parser = argparse.ArgumentParser(
        description="Generate images using Nano Banana Pro (Gemini 3 Pro Image)"
    )
    parser.add_argument(
        "--prompt", "-p",
        required=True,
        help="Image description/prompt"
    )
    parser.add_argument(
        "--filename", "-f",
        required=True,
        help="Output filename (e.g., sunset-mountains.png)"
    )
    parser.add_argument(
        "--input-image", "-i",
        help="Optional input image path for editing/modification"
    )
    parser.add_argument(
        "--resolution", "-r",
        choices=["1K", "2K", "4K"],
        default="1K",
        help="Output resolution: 1K (default), 2K, or 4K"
    )
    parser.add_argument(
        "--api-key", "-k",
        help="Gemini API key (overrides GEMINI_API_KEY env var)"
    )

    args = parser.parse_args()

    # Get API key
    [REDACTED_SECRET])
    if not [REDACTED_SECRET]"Error: No API key provided.", file=sys.stderr)
        print("Please either:", file=sys.stderr)
        print("  1. Provide --api-key argument", file=sys.stderr)
        print("  2. Set GEMINI_API_KEY environment variable", file=sys.stderr)
        sys.exit(1)

    # Import here after checking API key to avoid slow import on error
    from google import genai
    from google.genai import types
    from PIL import Image as PILImage

    # Initialise client
    client = genai.Client([REDACTED_SECRET])

    # Set up output path
    output_path = Path(args.filename)
    output_path.parent.mkdir(parents=True, exist_ok=True)

    # Load input image if provided
    input_image = None
    output_resolution = args.resolution
    if args.input_image:
        try:
            input_image = PILImage.open(args.input_image)
            print(f"Loaded input image: {args.input_image}")

            # Auto-detect resolution if not explicitly set by user
            if args.resolution == "1K":  # Default value
                # Map input image size to resolution
                width, height = input_image.size
                max_dim = max(width, height)
                if max_dim >= 3000:
                    output_resolution = "4K"
                elif max_dim >= 1500:
                    output_resolution = "2K"
                else:
                    output_resolution = "1K"
                print(f"Auto-detected resolution: {output_resolution} (from input {width}x{height})")
        except Exception as e:
            print(f"Error loading input image: {e}", file=sys.stderr)
            sys.exit(1)

    # Build contents (image first if editing, prompt only if generating)
    if input_image:
        contents = [input_image, args.prompt]
        print(f"Editing image with resolution {output_resolution}...")
    else:
        contents = args.prompt
        print(f"Generating image with resolution {output_resolution}...")

    try:
        response = client.models.generate_content(
            model="gemini-3-pro-image-preview",
            contents=contents,
            config=types.GenerateContentConfig(
                response_modalities=["TEXT", "IMAGE"],
                image_config=types.ImageConfig(
                    image_size=output_resolution
                )
            )
        )

        # Process response and convert to PNG
        image_saved = False
        for part in response.parts:
            if part.text is not None:
                print(f"Model response: {part.text}")
            elif part.inline_data is not None:
                # Convert inline data to PIL Image and save as PNG
                from io import BytesIO

                # inline_data.data is already bytes, not base64
                image_data = part.inline_data.data
                if isinstance(image_data, str):
                    # If it's a string, it might be base64
                    import base64
                    image_data = base64.b64decode(image_data)

                image = PILImage.open(BytesIO(image_data))

                # Ensure RGB mode for PNG (convert RGBA to RGB with white background if needed)
                if image.mode == 'RGBA':
                    rgb_image = PILImage.new('RGB', image.size, (255, 255, 255))
                    rgb_image.paste(image, mask=image.split()[3])
                    rgb_image.save(str(output_path), 'PNG')
                elif image.mode == 'RGB':
                    image.save(str(output_path), 'PNG')
                else:
                    image.convert('RGB').save(str(output_path), 'PNG')
                image_saved = True

        if image_saved:
            full_path = output_path.resolve()
            print(f"\nImage saved: {full_path}")
        else:
            print("Error: No image was generated in the response.", file=sys.stderr)
            sys.exit(1)

    except Exception as e:
        print(f"Error generating image: {e}", file=sys.stderr)
        sys.exit(1)


if __name__ == "__main__":
    main()


path: scripts/humanize.py
content: #!/usr/bin/env python3
"""Transform AI text to bypass detection."""
import argparse, json, re, sys
from pathlib import Path

SCRIPT_DIR = Path(__file__).parent
PATTERNS = json.loads((SCRIPT_DIR / "patterns.json").read_text())

def replace_bounded(text: str, old: str, new: str) -> tuple[str, int]:
    pattern = re.compile(re.escape(old), re.IGNORECASE) if " " in old or old.endswith(",") else re.compile(r"\b" + re.escape(old) + r"\b", re.IGNORECASE)
    matches = pattern.findall(text)
    return pattern.sub(new, text) if matches else text, len(matches)

def apply_replacements(text: str, replacements: dict) -> tuple[str, list]:
    changes = []
    for old, new in replacements.items():
        text, count = replace_bounded(text, old, new)
        if count:
            changes.append(f'"{old}" → "{new}"' if new else f'"{old}" removed')
    return text, changes

def fix_quotes(text: str) -> tuple[str, bool]:
    original = text
    for old, new in PATTERNS["curly_quotes"].items():
        text = text.replace(old, new)
    return text, text != original

def remove_chatbot_sentences(text: str) -> tuple[str, list]:
    changes = []
    for artifact in PATTERNS["chatbot_artifacts"]:
        pattern = re.compile(r"[^.!?\n]*" + re.escape(artifact) + r"[^.!?\n]*[.!?]?\s*", re.IGNORECASE)
        if pattern.search(text):
            changes.append(f'Removed "{artifact}" sentence')
            text = pattern.sub("", text)
    return text, changes

def strip_markdown(text: str) -> tuple[str, list]:
    changes = []
    if "**" in text:
        text = re.sub(r'\*\*([^*]+)\*\*', r'\1', text)
        changes.append("Stripped bold")
    if re.search(r'^#{1,6}\s', text, re.MULTILINE):
        text = re.sub(r'^#{1,6}\s+', '', text, flags=re.MULTILINE)
        changes.append("Stripped headers")
    if "```" in text:
        text = re.sub(r'```\w*\n?', '', text)
        changes.append("Stripped code blocks")
    return text, changes

def reduce_em_dashes(text: str) -> tuple[str, int]:
    count = text.count("—") + text.count(" -- ")
    text = re.sub(r"\s*—\s*", ", ", text)
    text = re.sub(r"\s+--\s+", ", ", text)
    return text, count

def remove_citations(text: str) -> tuple[str, list]:
    changes = []
    patterns = [
        (r'\[oai_citation:\d+[^\]]*\]\([^)]+\)', "oai_citation"),
        (r':contentReference\[oaicite:\d+\]\{[^}]+\}', "contentReference"),
        (r'turn0search\d+', "turn0search"), (r'turn0image\d+', "turn0image"),
        (r'\?utm_source=(chatgpt\.com|openai)', "ChatGPT UTM"),
    ]
    for pattern, name in patterns:
        if re.search(pattern, text):
            text = re.sub(pattern, '', text)
            changes.append(f"Removed {name}")
    return text, changes

def simplify_ing(text: str) -> tuple[str, list]:
    changes = []
    for word in ["highlighting", "underscoring", "emphasizing", "showcasing", "fostering"]:
        pattern = re.compile(rf',?\s*{word}\s+[^,.]+[,.]', re.IGNORECASE)
        if pattern.search(text):
            text = pattern.sub('. ', text)
            changes.append(f"Simplified {word} clause")
    return text, changes

def clean(text: str) -> str:
    text = re.sub(r" +", " ", text)
    text = re.sub(r"\n{3,}", "\n\n", text)
    text = re.sub(r",\s*,", ",", text)
    text = re.sub(r"(^|[.!?]\s+)([a-z])", lambda m: m.group(1) + m.group(2).upper(), text)
    return text.strip()

def transform(text: str, aggressive: bool = False) -> tuple[str, list]:
    all_changes = []
    text, changes = remove_citations(text); all_changes.extend(changes)
    text, changes = strip_markdown(text); all_changes.extend(changes)
    text, changes = remove_chatbot_sentences(text); all_changes.extend(changes)
    text, changes = apply_replacements(text, PATTERNS["copula_avoidance"]); all_changes.extend(changes)
    text, changes = apply_replacements(text, PATTERNS["filler_replacements"]); all_changes.extend(changes)
    text, fixed = fix_quotes(text)
    if fixed:
        all_changes.append("Fixed curly quotes")
    if aggressive:
        text, changes = simplify_ing(text); all_changes.extend(changes)
        text, count = reduce_em_dashes(text)
        if count > 2:
            all_changes.append(f"Replaced {count} em dashes")
    return clean(text), all_changes

def main():
    parser = argparse.ArgumentParser(description="Transform AI text to human-like")
    parser.add_argument("input", nargs="?", help="Input file (or stdin)")
    parser.add_argument("-o", "--output", help="Output file")
    parser.add_argument("-a", "--aggressive", action="store_true", help="Aggressive mode")
    parser.add_argument("-q", "--quiet", action="store_true", help="Suppress change log")
    args = parser.parse_args()
    
    text = Path(args.input).read_text() if args.input else sys.stdin.read()
    result, changes = transform(text, aggressive=args.aggressive)
    
    if not args.quiet and changes:
        print(f"CHANGES ({len(changes)}):", file=sys.stderr)
        for c in changes:
            print(f"  • {c}", file=sys.stderr)
    
    if args.output:
        Path(args.output).write_text(result)
        if not args.quiet:
            print(f"→ {args.output}", file=sys.stderr)
    else:
        print(result)

if __name__ == "__main__":
    main()


path: scripts/patterns.json
content: {
  "significance_inflation": [
    "stands as", "serves as", "is a testament", "is a reminder",
    "vital role", "significant role", "crucial role", "pivotal role",
    "key role", "pivotal moment", "key moment", "key turning point",
    "underscores its importance", "highlights its importance",
    "underscores its significance", "highlights its significance",
    "reflects broader", "symbolizing its ongoing", "symbolizing its enduring",
    "symbolizing its lasting", "contributing to the", "setting the stage for",
    "marking the", "shaping the", "represents a shift", "marks a shift",
    "evolving landscape", "focal point", "indelible mark", "deeply rooted",
    "enduring legacy", "rich tapestry", "broader movement"
  ],
  "notability_emphasis": [
    "independent coverage", "local media outlets", "regional media outlets",
    "national media outlets", "music outlets", "business outlets", "tech outlets",
    "profiled in", "written by a leading expert", "active social media presence",
    "has been featured in", "has been cited in", "maintains a strong digital presence"
  ],
  "superficial_analysis": [
    "highlighting", "underscoring", "emphasizing", "ensuring",
    "reflecting", "symbolizing", "contributing to", "cultivating",
    "fostering", "encompassing", "showcasing", "valuable insights",
    "align with", "aligns with", "resonate with", "resonates with"
  ],
  "promotional_language": [
    "boasts a", "boasts an", "vibrant", "rich cultural heritage",
    "profound", "enhancing its", "exemplifies", "commitment to",
    "natural beauty", "nestled", "in the heart of", "groundbreaking",
    "renowned", "breathtaking", "must-visit", "stunning", "bustling",
    "game-changing", "cutting-edge", "state-of-the-art", "world-class",
    "best-in-class", "industry-leading", "innovative", "revolutionary"
  ],
  "vague_attributions": [
    "industry reports", "observers have cited", "experts argue",
    "experts believe", "some critics argue", "several sources",
    "several publications", "according to experts", "widely regarded",
    "it is widely believed", "many believe", "some would say"
  ],
  "challenges_formula": [
    "despite its", "faces several challenges", "despite these challenges",
    "challenges and legacy", "future outlook", "future prospects",
    "looking ahead", "moving forward", "going forward"
  ],
  "ai_vocabulary": [
    "additionally", "align with", "crucial", "delve", "emphasizing",
    "enduring", "enhance", "fostering", "garner", "highlight",
    "interplay", "intricate", "intricacies", "key", "landscape",
    "pivotal", "showcase", "showcasing", "tapestry", "testament",
    "underscore", "underscores", "valuable", "vibrant", "nuanced",
    "multifaceted", "paradigm", "synergy", "realm", "underpins",
    "unraveling", "unveiling", "leveraging", "furthermore", "moreover",
    "consequently", "subsequently", "henceforth", "thereby", "wherein",
    "thereof", "whatsoever", "nevertheless", "notwithstanding"
  ],
  "copula_avoidance": {
    "serves as a": "is a",
    "serves as an": "is an",
    "serves as the": "is the",
    "stands as a": "is a",
    "stands as an": "is an",
    "stands as the": "is the",
    "marks a": "is a",
    "marks an": "is an",
    "marks the": "is the",
    "represents a": "is a",
    "represents an": "is an",
    "represents the": "is the",
    "boasts a": "has a",
    "boasts an": "has an",
    "boasts the": "has the",
    "features a": "has a",
    "features an": "has an",
    "features the": "has the",
    "offers a": "has a",
    "offers an": "has an"
  },
  "filler_replacements": {
    "in order to": "to",
    "due to the fact that": "because",
    "at this point in time": "now",
    "at the present time": "now",
    "has the ability to": "can",
    "it is important to note that": "",
    "it should be noted that": "",
    "it is worth noting that": "",
    "it is crucial to note that": "",
    "it is critical to remember that": "",
    "it goes without saying that": "",
    "needless to say": "",
    "Additionally,": "",
    "Furthermore,": "",
    "Moreover,": "",
    "In conclusion,": "",
    "To summarize,": "",
    "In summary,": "",
    "Overall,": "",
    "utilize": "use",
    "utilizes": "uses",
    "utilizing": "using",
    "utilization": "use",
    "leverage": "use",
    "leverages": "uses",
    "leveraging": "using",
    "facilitate": "help",
    "facilitates": "helps",
    "facilitating": "helping",
    "implement": "add",
    "implements": "adds",
    "prioritize": "focus on",
    "prioritizes": "focuses on",
    "optimize": "improve",
    "optimizes": "improves",
    "streamline": "simplify",
    "streamlines": "simplifies"
  },
  "chatbot_artifacts": [
    "I hope this helps",
    "Let me know if",
    "Would you like me to",
    "Great question",
    "Excellent question",
    "You're absolutely right",
    "That's a great point",
    "That's an excellent point",
    "Certainly!",
    "Of course!",
    "Absolutely!",
    "Happy to help",
    "I'd be happy to",
    "Feel free to",
    "Don't hesitate to",
    "Here is a",
    "Here's a",
    "I can help you with",
    "As an AI",
    "As a language model",
    "As an AI language model"
  ],
  "hedging_phrases": [
    "it could potentially",
    "it might possibly",
    "arguably",
    "it could be argued that",
    "some would say",
    "in some ways",
    "to some extent",
    "in certain respects",
    "may vary",
    "results may vary"
  ],
  "negative_parallelisms": [
    "not only", "but also",
    "it's not just about", "it's about",
    "it is not merely", "it is",
    "not just", "but",
    "no longer", "instead"
  ],
  "rule_of_three_patterns": [
    "innovation, inspiration, and",
    "engage, educate, and",
    "plan, execute, and",
    "design, develop, and",
    "research, develop, and",
    "create, collaborate, and",
    "learn, grow, and"
  ],
  "markdown_artifacts": [
    "**", "##", "###", "```",
    "* **", "- **", "1. **"
  ],
  "citation_bugs": [
    "oaicite", "oai_citation", "contentReference",
    "turn0search", "turn0image", "utm_source=chatgpt",
    "utm_source=openai", "attached_file", "grok_card"
  ],
  "knowledge_cutoff": [
    "as of my last", "as of my knowledge",
    "up to my last training", "based on available information",
    "while specific details are limited",
    "not widely available", "not widely documented",
    "in the provided sources", "in available sources"
  ],
  "curly_quotes": {
    "\u201c": "\"",
    "\u201d": "\"",
    "\u2018": "'",
    "\u2019": "'"
  },
  "em_dash_patterns": ["—", " — ", "-- "]
}


path: scripts/title_generator.py
content: #!/usr/bin/env python3
"""
AI 标题生成器 - 生成 10 万 + 爆款标题
支持 A/B 测试，生成多个变体
"""

import sys
import json

# 标题模板库
TITLE_TEMPLATES = {
    "how_to": [
        "如何在{time}内{result}（完整指南）",
        "{number}个简单步骤，教你{result}",
        "{result}的终极指南（{year}最新版）",
    ],
    "list": [
        "{number}个{topic}技巧，第{highlight}个太实用了",
        "{number}个{topic}错误，你中了几个？",
        "Top {number}：{topic}最佳实践",
    ],
    "question": [
        "为什么你的{topic}总是失败？原因在这里",
        "{topic}真的有用吗？实测告诉你",
        "如何用{topic}实现{result}？",
    ],
    "secret": [
        "{number}个{topic}秘密，专家不会告诉你",
        "揭秘：{result}背后的真相",
        "{topic}内幕：{number}个不为人知的技巧",
    ],
    "comparison": [
        "{A} vs {B}：哪个更适合你？",
        "{number}个{topic}工具对比，最佳是...",
        "我用{A}和{B}做了{result}，差距惊人",
    ],
}

def generate_titles(topic, result="", number=5, style="all"):
    """生成标题变体"""
    titles = []
    
    if style == "all":
        styles = list(TITLE_TEMPLATES.keys())
    else:
        styles = [style]
    
    for style in styles:
        templates = TITLE_TEMPLATES.get(style, [])
        for template in templates[:number]:
            title = template.format(
                topic=topic,
                result=result or topic,
                number=3,
                time="30 分钟",
                year="2026",
                highlight=3,
                A="工具 A",
                B="工具 B"
            )
            titles.append(title)
    
    return titles[:number]

def score_title(title):
    """简单标题评分（基于长度、关键词等）"""
    score = 0
    
    # 长度评分（理想 20-40 字）
    length = len(title)
    if 20 <= length <= 40:
        score += 30
    elif 15 <= length <= 50:
        score += 20
    else:
        score += 10
    
    # 数字加分
    if any(c.isdigit() for c in title):
        score += 20
    
    # 问题加分
    if "?" in title or "？" in title:
        score += 15
    
    # 情感词加分
    emotion_words = ["终极", "完整", "秘密", "揭秘", "惊人", "实用"]
    if any(word in title for word in emotion_words):
        score += 20
    
    # 括号加分
    if "(" in title or "（" in title:
        score += 15
    
    return min(score, 100)

if __name__ == "__main__":
    topic = sys.argv[1] if len(sys.argv) > 1 else "SEO 内容写作"
    result = sys.argv[2] if len(sys.argv) > 2 else ""
    number = int(sys.argv[3]) if len(sys.argv) > 3 else 10
    
    titles = generate_titles(topic, result, number)
    
    print(f"=== AI 标题生成器 ===")
    print(f"主题：{topic}")
    print(f"生成数量：{len(titles)}\n")
    
    for i, title in enumerate(titles, 1):
        score = score_title(title)
        print(f"{i}. [{score}分] {title}")


path: seo-content-pro-ab-test.py
content: #!/usr/bin/env python3
"""
A/B 测试支持模块
用于测试不同标题的效果
"""

import json
import random
from typing import List, Dict

class ABTest:
    def __init__(self, variants: List[str]):
        self.variants = variants
        self.results = {variant: {"impressions": 0, "clicks": 0} for variant in variants}
    
    def get_variant(self) -> str:
        """随机获取一个变体用于展示"""
        return random.choice(self.variants)
    
    def record_impression(self, variant: str):
        """记录展示次数"""
        if variant in self.results:
            self.results[variant]["impressions"] += 1
    
    def record_click(self, variant: str):
        """记录点击次数"""
        if variant in self.results:
            self.results[variant]["clicks"] += 1
    
    def get_ctr(self, variant: str) -> float:
        """计算点击率 (CTR)"""
        if variant not in self.results:
            return 0.0
        impressions = self.results[variant]["impressions"]
        clicks = self.results[variant]["clicks"]
        return clicks / impressions if impressions > 0 else 0.0
    
    def get_best_performer(self) -> str:
        """获取表现最好的变体"""
        best_variant = self.variants[0]
        best_ctr = 0.0
        
        for variant in self.variants:
            ctr = self.get_ctr(variant)
            if ctr > best_ctr:
                best_ctr = ctr
                best_variant = variant
        
        return best_variant
    
    def get_report(self) -> Dict:
        """生成 A/B 测试报告"""
        report = {
            "variants": {},
            "best_performer": self.get_best_performer(),
            "total_impressions": sum(v["impressions"] for v in self.results.values()),
            "total_clicks": sum(v["clicks"] for v in self.results.values())
        }
        
        for variant, data in self.results.items():
            report["variants"][variant] = {
                "impressions": data["impressions"],
                "clicks": data["clicks"],
                "ctr": self.get_ctr(variant)
            }
        
        return report

if __name__ == "__main__":
    # 示例使用
    titles = [
        "如何在30分钟内写出爆款文章（完整指南）",
        "3个SEO内容写作技巧，第3个太实用了",
        "为什么你的SEO内容总是失败？原因在这里"
    ]
    
    ab_test = ABTest(titles)
    
    # 模拟测试数据
    for _ in range(100):
        variant = ab_test.get_variant()
        ab_test.record_impression(variant)
        if random.random() < 0.15:  # 15% 点击率
            ab_test.record_click(variant)
    
    report = ab_test.get_report()
    print(json.dumps(report, indent=2, ensure_ascii=False))

Security scan verdicts — ClawScan: suspicious | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (CRITICAL)