SuperAPI AI Directory

knowledge-site-creator

Frontend & websites

View repository

Updated 10-15 14:26

About this skill

Knowledge Site Creator - Universal Knowledge Learning Website Generator

AI understands the topic, automatically creates content, generates the website, and deploys it with one click.

Core Philosophy

Design System First:

  • Reuse the design language (minimalism, color scheme, layout, interaction patterns)
  • Do not reuse specific page code
  • AI recreates all content based on the topic

Universal Learning Modes(Core Features):

  • Flashcard - Quick memorization
  • Learn - Progressive learning
  • Quiz - Knowledge assessment
  • Index - Quick lookup
  • Progress - Learning tracking

Zero Template Dependency:

  • No longer cp -r copying templates
  • AI references the design system and generates new pages
  • All copy, statistics, and introductions are created by AI

Trigger Methods

  • "Generate an XXX learning website"
  • "Create an XXX knowledge website"
  • "Make an XXX learning workshop"

Examples:

  • "Generate an evolutionary psychology concept learning website"
  • "Create a quantum mechanics basic concepts website"
  • "Make a traditional Chinese medicine meridians and acupoints learning workshop"

Workflow

User Perspective (One Sentence)

用户:"生成一个进化心理学学习网站"

AI自动执行:
✓ 分析"进化心理学"特点和价值
✓ 生成30个核心概念数据
✓ 创作首页文案、统计、介绍
✓ 参考设计系统生成页面
✓ 部署到 Vercel
✓ 返回:https://evolutionary-psychology.vercel.app

完成!

Implementation Process (AI Execution)

Step 1: Understand the Topic

AI deeply analyzes the topic and outputs a topic analysis:

主题分析 {
  领域: "进化心理学",
  特点: "跨学科(生物学+心理学),解释人类行为的底层逻辑",
  价值: "理解人性、改善关系、优化决策",
  受众: "心理学爱好者、自我提升者、教育工作者",
  表达: "科学严谨 + 生活化案例,避免学术术语堆砌"
}

Questions to Consider:

  • What field is this? (Discipline classification, knowledge characteristics)
  • Why is it important? (Learning value, application scenarios)
  • Who is the target audience? (Background, needs, pain points)
  • How to express it better? (Language style, case selection)

Step 2: Generate Data + Website Configuration

⚠️ Key: Generate two files, not just data!

2.1 Generate Data (wordData.js)

Universal Data Structure:

const WordRoots = [
  {
    id: 1,
    root: "适应性 (Adaptation)",     // 知识点名称
    origin: "核心理论",               // 分类/来源
    meaning: "通过自然选择进化出的有利特征",  // 一句话解释
    description: "详细说明(200-300字)...",
    examples: [                       // 应用案例/例子(3个)
      {
        word: "恐高症",
        meaning: "对高处的恐惧",
        breakdown: { root: "适应性" },
        explanation: "详细解释..."
      }
    ],
    quiz: {                           // 小测试(4选1)
      question: "以下哪个不是适应性的特征?",
      options: ["选项A", "选项B", "选项C", "选项D"],
      correctAnswer: 2                // 正确答案索引(0-3)
    }
  }
];

Generation Quantity: 20-30 by default, adjusted according to topic complexity

2.2 Generate Configuration (siteConfig.js) 🆕

AI-created, fully adapted to the topic:

const siteConfig = {
  // 基础信息
  topic: "进化心理学",
  siteName: "进化心理学概念工坊",
  itemName: "概念",                    // 单个知识点的称呼
  itemCount: 30,

  // 首页Hero区(AI创作)
  hero: {
    title: [
      "30个核心概念",
      "理解人类行为",
      "的底层逻辑"
    ],
    subtitle: "从适应性到配偶选择,系统掌握进化心理学核心框架",
    animation: {
      enabled: true,                   // 是否显示动画
      demoCount: 5                     // 动画展示几个概念
    }
  },

  // 统计卡片(AI生成,匹配主题特点)
  stats: [
    { value: "30", label: "核心概念" },
    { value: "100+", label: "生活应用" },
    { value: "15分钟", label: "每日学习" }
  ],

  // 底部介绍(AI创作)
  footer: {
    tagline: "像理解自己一样理解人性",
    description: "基于进化心理学的科学框架,用30个核心概念解释人类行为背后的生物学逻辑。从配偶选择到亲子关系,从群体合作到情绪反应,让你看懂人性的深层原因。"
  },

  // 按钮文案(AI适配)
  cta: {
    primary: "开始第一个概念 →",
    secondary: "闪卡复习"
  }
};

AI Creation Principles:

  • hero.title: Concise and powerful, 3 lines, highlighting the core value
  • hero.subtitle: Specifically explain what to learn and why to learn it
  • stats: Real, persuasive numbers that match the topic's characteristics
  • footer.tagline: One sentence that captures the point, catchy and memorable
  • footer.description: 2-3 sentences, clearly explaining what it is, what to learn, and what it is useful for

Step 3: Reference the Design System and Generate Pages

⚠️ No more copying templates! AI references the design specifications and generates new pages

3.1 Design System Reference

⚠️ Reference Document:references/design-system.md - Complete design specifications

Core Points:

  • Color Scheme: Yellow theme color (#FBBF24), gray-toned text and background
  • Font: Inter font family, Courier New for code
  • Style: Minimalism, generous white space, clear hierarchy
  • Components: Rounded cards (12px), very light shadows
  • Spacing: 8px grid system, Hero section 96px white space

For detailed colors, fonts, spacing, and component styles, see design-system.md

3.2 Generated Page List

⚠️ Feature Reference:

  • references/core-patterns.md - Core learning mode implementation
  • references/code-quality.md - Code Quality Standards (must be followed)
  • references/seo-best-practices.md - SEO Optimization Guide 🆕
  • references/pwa-setup.md - PWA Configuration Guide

Code Quality Requirements(mandatory):

  • ✅ Error handling: All LocalStorage operations must have try-catch
  • ✅ XSS protection: Use textContent/createElement, direct innerHTML insertion of unescaped data is forbidden
  • ✅ DOM safety: Check that elements exist before all DOM operations
  • ✅ Avoid global pollution: Use module encapsulation or IIFE

For detailed rules, see references/code-quality.md。

AI references the design system and generates the following pages from scratch:

  1. index.html - Home page 🆕

    • Hero section: use siteConfig.hero.title/subtitle
    • Animation demo: from WordRoots dynamically load the first 5 (see core-patterns.md §9)
    • Statistics cards: use siteConfig.stats
    • CTA button: use siteConfig.cta
    • Footer: use siteConfig.footer
  2. learn.html - Learning page (see core-patterns.md §5)

    • Progressive card display
    • Previous/Next navigation
    • Mark as mastered feature
  3. flashcard.html - Flashcard page (see core-patterns.md §4)

    • Card flip animation
    • Keyboard shortcuts (←→ to flip pages, space to flip)
    • Progress display
  4. roots.html - Index page (see core-patterns.md §7)

    • Title adaptation:${itemName}索引
    • Search box + filters
    • Card grid layout
  5. progress.html - Progress page (see core-patterns.md §8)

    • Learning statistics
    • Mastered list
    • Achievement system
  6. root-detail.html - Detail page

    • Detailed concept explanation
    • Example display
    • Quiz questions (see core-patterns.md §6)
  7. css/minimal.css - Style files (see design-system.md)

    • Unified design system
    • Responsive layout
  8. js/storage.js - Storage logic (see core-patterns.md §3)

    • LocalStorage progress management
  9. manifest.json - PWA configuration (see pwa-setup.md §1)🆕

    • App name, icon, theme color
    • Supports installation to home screen
  10. sw.js - Service Worker (see pwa-setup.md §2)🆕

    • Cache static resources
    • Supports offline access
  11. icon-192.png / icon-512.png - PWA icons 🆕

    • Auto-generate: Use PIL to generate from configuration (yellow background + theme text)
    • Do not create manually: AI should automatically generate with Python PIL
  12. sitemap.xml - Sitemap (see seo-best-practices.md §4)🆕

    • List all page URLs
    • Submit to search engines
  13. robots.txt - Crawler directives (see seo-best-practices.md §5)🆕

    • Allow/disallow crawling rules
    • Sitemap location declaration

⚠️ Mandatory requirement: All HTML files must include complete meta tags

Each HTML file's <head> must include:

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>${siteConfig.siteName}</title>

  <!-- SEO 基础 -->
  <meta name="description" content="${siteConfig.footer.description}">
  <meta name="keywords" content="${siteConfig.topic},学习,知识,${siteConfig.itemName}">
  <meta name="author" content="乔木">
  <meta name="language" content="zh-CN">
  <meta name="robots" content="index, follow">
  <link rel="canonical" href="${currentPageUrl}">

  <!-- Open Graph (社交分享) -->
  <meta property="og:title" content="${siteConfig.siteName}">
  <meta property="og:description" content="${siteConfig.footer.description}">
  <meta property="og:type" content="website">
  <meta property="og:url" content="${currentPageUrl}">
  <meta property="og:image" content="${siteBaseUrl}/icon-512.png">
  <meta property="og:site_name" content="${siteConfig.siteName}">
  <meta property="og:locale" content="zh_CN">

  <!-- Twitter Card -->
  <meta name="twitter:card" content="summary_large_image">
  <meta name="twitter:site" content="@vista8">
  <meta name="twitter:creator" content="@vista8">
  <meta name="twitter:title" content="${siteConfig.siteName}">
  <meta name="twitter:description" content="${siteConfig.footer.description}">
  <meta name="twitter:image" content="${siteBaseUrl}/icon-512.png">

  <!-- Favicon (简单的 emoji data URI) -->
  <link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>📚</text></svg>">

  <!-- PWA 支持 🆕 -->
  <link rel="manifest" href="/manifest.json">
  <meta name="theme-color" content="#FBBF24">

  <!-- iOS Safari PWA 支持 -->
  <meta name="apple-mobile-web-app-capable" content="yes">
  <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
  <meta name="apple-mobile-web-app-title" content="${siteConfig.itemName}学习">
  <link rel="apple-touch-icon" href="/icon-192.png">

  <!-- Google Fonts -->
  <link rel="preconnect" href="https://fonts.googleapis.com">
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
  <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">

  <!-- 样式 -->
  <link rel="stylesheet" href="css/minimal.css">
</head>

Key principles:

  • ✅ Core learning modes (flashcards, study, test) stay consistent - refer to core-patterns.md
  • ✅ Design style (color scheme, fonts, layout) stays consistent - refer to design-system.md
  • ✅ All copy, titles, and descriptions are created by AI based on the topic
  • ✅ Code quality: Must comply with code-quality.md standards (error handling, XSS protection, DOM safety)🆕
  • ✅ PWA support: manifest.json + Service Worker + icons (offline access, installable)🆕
  • ✅ SEO optimization: complete meta tags + sitemap.xml + robots.txt + structured data 🆕
  • ✅ Semantic HTML: correct use of header, main, article, section and other tags 🆕
  • ✅ Mobile-first: responsive design + viewport meta + fast loading (< 3 seconds)🆕
  • ❌ Do not hardcode domain-specific content

Step 4: Create project structure

# 项目位置
mkdir -p "/Users/joe/Dropbox/code/${topic}-workshop"
cd "/Users/joe/Dropbox/code/${topic}-workshop"

# 创建目录结构
mkdir -p js css

# 写入数据
cat > js/wordData.js << 'EOF'
const WordRoots = [...];
EOF

# 写入配置 🆕
cat > js/siteConfig.js << 'EOF'
const siteConfig = {...};
EOF

# 写入页面(AI生成的HTML)
cat > index.html << 'EOF'
[AI生成的index.html]
EOF

# 写入其他页面...

# 🆕 自动生成 PWA 图标(用 PIL)
python3 << 'PYEOF'
from PIL import Image, ImageDraw, ImageFont

def create_icon(size, filename, text):
    # 创建黄色背景
    img = Image.new('RGB', (size, size), color='#FBBF24')
    draw = ImageDraw.Draw(img)

    # 尝试使用系统字体
    try:
        font_size = int(size * 0.25)
        font = ImageFont.truetype('/System/Library/Fonts/PingFang.ttc', font_size)
    except:
        font = ImageFont.load_default()

    # 获取文字边界框
    bbox = draw.textbbox((0, 0), text, font=font)
    text_width = bbox[2] - bbox[0]
    text_height = bbox[3] - bbox[1]

    # 居中位置
    x = (size - text_width) / 2
    y = (size - text_height) / 2

    # 绘制文字(深灰色)
    draw.text((x, y), text, font=font, fill='#1F2937')

    # 保存
    img.save(filename, 'PNG')

# 从主题生成图标文字(取前2-3个字)
icon_text = "${siteConfig.itemName}"[:3]  # 例如:"概念" → "概念"、"历史知识点" → "历史知"

# 生成两种尺寸
create_icon(192, 'icon-192.png', icon_text)
create_icon(512, 'icon-512.png', icon_text)
print("✓ PWA 图标生成完成")
PYEOF

Step 5: Data validation (mandatory quality check)

⚠️ Critical: AI-generated data must undergo complete validation to ensure quality and consistency

# ========================================
# 阶段 1:基础结构验证
# ========================================

echo "🔍 验证数据结构..."

# 1.1 检查数据文件存在且变量名正确
if ! grep -q "const WordRoots" js/wordData.js; then
  echo "❌ 错误:数据变量名不正确(应为 const WordRoots)"
  exit 1
fi

# 1.2 检查配置文件存在且变量名正确
if ! grep -q "const siteConfig" js/siteConfig.js; then
  echo "❌ 错误:配置文件缺失(应为 const siteConfig)"
  exit 1
fi

# ========================================
# 阶段 2:数据完整性验证
# ========================================

echo "🔍 验证数据完整性..."

# 2.1 使用 Node.js 进行深度验证
node -e "
const fs = require('fs');

// 读取数据文件
const dataContent = fs.readFileSync('js/wordData.js', 'utf-8');
eval(dataContent);  // 加载 WordRoots

let errors = [];
let warnings = [];

// 验证数据存在
if (typeof WordRoots === 'undefined') {
  console.error('❌ 严重错误:WordRoots 未定义');
  process.exit(1);
}

if (!Array.isArray(WordRoots) || WordRoots.length === 0) {
  console.error('❌ 严重错误:WordRoots 为空或不是数组');
  process.exit(1);
}

console.log(\`📊 数据量:\${WordRoots.length} 个知识点\`);

// 遍历每个知识点进行验证
WordRoots.forEach((item, index) => {
  const itemLabel = \`Item #\${item.id || index}\`;

  // 必需字段检查
  if (!item.id) errors.push(\`\${itemLabel}: 缺少 id\`);
  if (!item.root || item.root.trim() === '') errors.push(\`\${itemLabel}: 缺少 root(知识点名称)\`);
  if (!item.origin) warnings.push(\`\${itemLabel}: 缺少 origin(分类)\`);
  if (!item.meaning || item.meaning.trim() === '') errors.push(\`\${itemLabel}: 缺少 meaning(简短解释)\`);
  if (!item.description || item.description.trim() === '') errors.push(\`\${itemLabel}: 缺少 description(详细说明)\`);

  // 描述长度检查(应该详细但不过长)
  if (item.description && item.description.length < 50) {
    warnings.push(\`\${itemLabel}: description 太短(<50字),建议扩展为200-300字\`);
  }
  if (item.description && item.description.length > 1000) {
    warnings.push(\`\${itemLabel}: description 太长(>1000字),建议精简\`);
  }

  // 例子检查
  if (!item.examples || !Array.isArray(item.examples)) {
    errors.push(\`\${itemLabel}: 缺少 examples 数组\`);
  } else if (item.examples.length < 3) {
    errors.push(\`\${itemLabel}: examples 少于3个(当前 \${item.examples.length})\`);
  } else {
    // 验证每个例子的结构
    item.examples.forEach((ex, exIndex) => {
      if (!ex.word) errors.push(\`\${itemLabel}.examples[\${exIndex}]: 缺少 word\`);
      if (!ex.meaning) errors.push(\`\${itemLabel}.examples[\${exIndex}]: 缺少 meaning\`);
      if (!ex.explanation) warnings.push(\`\${itemLabel}.examples[\${exIndex}]: 缺少 explanation\`);
    });
  }

  // 测试题检查
  if (!item.quiz) {
    warnings.push(\`\${itemLabel}: 缺少 quiz(测试题)\`);
  } else {
    if (!item.quiz.question || item.quiz.question.trim() === '') {
      errors.push(\`\${itemLabel}.quiz: 缺少 question\`);
    }
    if (!item.quiz.options || !Array.isArray(item.quiz.options)) {
      errors.push(\`\${itemLabel}.quiz: 缺少 options 数组\`);
    } else if (item.quiz.options.length !== 4) {
      errors.push(\`\${itemLabel}.quiz: options 必须是4个(当前 \${item.quiz.options.length})\`);
    }
    if (typeof item.quiz.correctAnswer !== 'number') {
      errors.push(\`\${itemLabel}.quiz: correctAnswer 必须是数字\`);
    } else if (item.quiz.correctAnswer < 0 || item.quiz.correctAnswer > 3) {
      errors.push(\`\${itemLabel}.quiz: correctAnswer 越界(必须是0-3,当前 \${item.quiz.correctAnswer})\`);
    }
  }
});

// 输出验证结果
if (errors.length > 0) {
  console.error('\\n❌ 发现 ' + errors.length + ' 个错误:');
  errors.slice(0, 10).forEach(e => console.error('  - ' + e));
  if (errors.length > 10) console.error(\`  ... 还有 \${errors.length - 10} 个错误\`);
  process.exit(1);
}

if (warnings.length > 0) {
  console.warn('\\n⚠️  发现 ' + warnings.length + ' 个警告:');
  warnings.slice(0, 5).forEach(w => console.warn('  - ' + w));
  if (warnings.length > 5) console.warn(\`  ... 还有 \${warnings.length - 5} 个警告\`);
}

console.log('\\n✓ 数据验证通过');
" || exit 1

# ========================================
# 阶段 3:配置验证
# ========================================

echo "🔍 验证配置..."

node -e "
const fs = require('fs');
const configContent = fs.readFileSync('js/siteConfig.js', 'utf-8');
eval(configContent);

if (typeof siteConfig === 'undefined') {
  console.error('❌ siteConfig 未定义');
  process.exit(1);
}

// 验证必需字段
const required = ['topic', 'siteName', 'itemName', 'itemCount', 'hero', 'stats', 'footer', 'cta'];
const missing = required.filter(key => !siteConfig[key]);

if (missing.length > 0) {
  console.error('❌ siteConfig 缺少字段:' + missing.join(', '));
  process.exit(1);
}

// 验证 hero 结构
if (!siteConfig.hero.title || !Array.isArray(siteConfig.hero.title) || siteConfig.hero.title.length !== 3) {
  console.error('❌ siteConfig.hero.title 必须是3行数组');
  process.exit(1);
}

console.log('✓ 配置验证通过');
" || exit 1

echo ""
echo "✅ 所有验证通过!"

Step 6: Deployment (mandatory security check)

⚠️ Critical: Each project must be deployed independently; never share a GitHub repository

Deployment process (must be executed strictly in order):

# ========================================
# 阶段 1:部署前安全检查(必须执行)
# ========================================

# 1.1 检查并移除 Git 远程仓库(防止关联到其他项目的仓库)
if git remote -v 2>/dev/null | grep -q 'origin'; then
  echo "⚠️ 警告:检测到 Git 远程仓库,立即移除以避免冲突"
  git remote remove origin
  echo "✓ 已移除 Git 远程仓库"
fi

# 1.2 初始化本地 Git(仅本地,不推送到 GitHub)
git init
git add .
git commit -m "Initial commit: ${siteName}"

# 1.3 列出所有现有 workshop 项目(用于后续验证)
echo "📋 现有项目列表:"
ls -d /Users/joe/Dropbox/code/*-workshop 2>/dev/null | while read dir; do
  PROJECT_NAME=$(basename "$dir")
  if [ -f "$dir/.vercel/project.json" ]; then
    PROJECT_ID=$(cat "$dir/.vercel/project.json" | jq -r '.projectId' 2>/dev/null || echo "unknown")
    echo "  - $PROJECT_NAME (projectId: $PROJECT_ID)"
  fi
done

# ========================================
# 阶段 2:执行部署
# ========================================

echo "🚀 开始部署到 Vercel..."
vercel --prod --yes 2>&1 | tee /tmp/vercel-deploy-${projectName}.log

DEPLOY_STATUS=$?
if [ $DEPLOY_STATUS -ne 0 ]; then
  echo "❌ 部署失败,请检查日志:/tmp/vercel-deploy-${projectName}.log"
  exit 1
fi

# ========================================
# 阶段 3:部署后强制验证(必须执行)
# ========================================

echo ""
echo "🔍 部署后验证..."

# 3.1 验证 projectId 已生成
if [ ! -f ".vercel/project.json" ]; then
  echo "❌ 错误:未找到 .vercel/project.json"
  exit 1
fi

NEW_PROJECT_ID=$(cat .vercel/project.json | jq -r '.projectId')
NEW_PROJECT_NAME=$(cat .vercel/project.json | jq -r '.projectName')
echo "✓ 新项目:"
echo "  名称: $NEW_PROJECT_NAME"
echo "  ID: $NEW_PROJECT_ID"

# 3.2 提取部署 URL
DEPLOY_URL=$(grep -E "Production:|https://.*vercel.app" /tmp/vercel-deploy-${projectName}.log | grep -o "https://[^ ]*vercel.app" | head -1)
echo "✓ 部署 URL: $DEPLOY_URL"

# 3.3 验证新网站可访问
echo "🌐 验证新网站..."
HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" "$DEPLOY_URL" || echo "000")
if [ "$HTTP_STATUS" = "200" ] || [ "$HTTP_STATUS" = "304" ]; then
  echo "✓ 新网站可正常访问 (HTTP $HTTP_STATUS)"
else
  echo "⚠️ 警告:新网站返回 HTTP $HTTP_STATUS"
fi

# 3.4 检查其他项目是否受影响(关键步骤)
echo ""
echo "🔍 检查其他项目是否受影响..."
AFFECTED_PROJECTS=0

for dir in /Users/joe/Dropbox/code/*-workshop; do
  if [ "$dir" = "/Users/joe/Dropbox/code/${projectName}" ]; then
    continue  # 跳过当前项目
  fi

  if [ -f "$dir/.vercel/project.json" ]; then
    OLD_PROJECT_NAME=$(basename "$dir")
    OLD_PROJECT_ID=$(cat "$dir/.vercel/project.json" | jq -r '.projectId' 2>/dev/null)

    # 检查是否有相同的 projectId(这表示冲突)
    if [ "$OLD_PROJECT_ID" = "$NEW_PROJECT_ID" ]; then
      echo "❌ 严重错误:项目 $OLD_PROJECT_NAME 的 projectId 与新项目相同!"
      echo "   这意味着新项目覆盖了旧项目,需要立即修复。"
      AFFECTED_PROJECTS=$((AFFECTED_PROJECTS + 1))
    fi
  fi
done

if [ $AFFECTED_PROJECTS -gt 0 ]; then
  echo ""
  echo "❌ 检测到 $AFFECTED_PROJECTS 个项目受影响,部署失败!"
  echo "   请手动检查并修复冲突。"
  exit 1
fi

echo "✓ 所有现有项目未受影响"

# ========================================
# 阶段 3.5:移动端和 SEO 验证 🆕
# ========================================

echo ""
echo "📱 验证移动端适配..."

# 检查 viewport meta 标签(移动端必需)
VIEWPORT_CHECK=$(curl -s "$DEPLOY_URL" | grep -c 'viewport')
if [ "$VIEWPORT_CHECK" -gt 0 ]; then
  echo "✓ 移动端 viewport 配置正确"
else
  echo "⚠️ 警告:缺少 viewport meta 标签,移动端可能显示异常"
fi

# 检查 SEO meta 标签
echo "🔍 验证 SEO 配置..."
META_DESCRIPTION=$(curl -s "$DEPLOY_URL" | grep -c 'meta name="description"')
META_OG=$(curl -s "$DEPLOY_URL" | grep -c 'property="og:')

if [ "$META_DESCRIPTION" -gt 0 ]; then
  echo "✓ SEO description 已配置"
else
  echo "⚠️ 警告:缺少 SEO description"
fi

if [ "$META_OG" -gt 0 ]; then
  echo "✓ Open Graph 标签已配置(社交分享优化)"
else
  echo "⚠️ 警告:缺少 Open Graph 标签"
fi

# 模拟移动设备访问测试
echo "📱 模拟移动设备访问..."
MOBILE_STATUS=$(curl -s -o /dev/null -w "%{http_code}" \
  -H "User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.0 Mobile/15E148 Safari/604.1" \
  "$DEPLOY_URL")

if [ "$MOBILE_STATUS" = "200" ] || [ "$MOBILE_STATUS" = "304" ]; then
  echo "✓ 移动端访问正常 (HTTP $MOBILE_STATUS)"
else
  echo "⚠️ 警告:移动端访问异常 (HTTP $MOBILE_STATUS)"
fi

# ========================================
# 阶段 4:成功总结
# ========================================

echo ""
echo "✅ 部署成功!"
echo ""
echo "📊 部署信息:"
echo "  项目名称: $NEW_PROJECT_NAME"
echo "  项目 ID: $NEW_PROJECT_ID"
echo "  部署 URL: $DEPLOY_URL"
echo "  日志文件: /tmp/vercel-deploy-${projectName}.log"

Security principles (must be followed):

  1. ✅ No GitHub association: Do not connect to GitHub by default, to avoid repository sharing
  2. ✅ Mandatory pre-check: All Git remote repositories must be removed before deployment
  3. ✅ Mandatory post-verification: projectId uniqueness must be checked after deployment
  4. ✅ Automatic conflict detection: Report an error immediately when a conflict is found; do not allow continuation
  5. ✅ Complete logging: All deployment operations are logged to /tmp/

If conflicts still occur (extreme cases):

If verification passes but problems still exist in practice, perform emergency repair:

# 1. 立即列出所有 Vercel 项目
vercel ls

# 2. 检查每个本地项目的部署状态
cd /Users/joe/Dropbox/code
for dir in *-workshop; do
  echo "=== $dir ==="
  cd "$dir"
  if [ -f ".vercel/project.json" ]; then
    cat .vercel/project.json | jq -r '.projectName, .projectId'
  fi
  cd ..
done

# 3. 重新部署受影响的项目
cd /path/to/affected-project
vercel --prod --yes

# 4. 向用户报告冲突详情和修复结果

Success output template

✅ ${siteName} 已生成并部署!

📁 项目位置:${projectPath}
🌐 网站名称:${siteName}
📚 知识点数量:${itemCount}个
🔗 访问链接:${deployUrl}

🎯 核心特性:
- ✅ AI创作首页:根据主题生成标题、副标题、统计
- ✅ 动态动画:自动从数据加载,完全适配
- ✅ 通用学习模式:闪卡、渐进学习、测试、索引
- ✅ 极简设计:清晰的视觉层级,专注内容

🔧 下一步:
1. 打开网站查看效果
2. 审核AI生成的内容
3. 配置自定义域名(Vercel后台)

Implementation checklist

When AI executes this skill,it must strictly follow the orderto complete:

  • 1. Understand the topic - Analyze the domain's characteristics, value, audience, and mode of expression
  • 2. Generate data - Create wordData.js (const WordRoots)
  • 3. Generate configuration 🆕 - Create siteConfig.js (AI creates homepage copy)
  • 4. Generate pages 🆕 - Refer to the design system, generate HTML from scratch (do not copy templates)
  • 5. Create project - mkdir + write all files
  • 6. Validate data - Check data and configuration file integrity
  • 7. Secure deployment 🔒 - Execute the complete deployment process for Step 6 (including pre-checks + deployment + post-verification)
  • 8. Return information - Project path + URL + core features + security check results

Key improvements (compared with the old version)

❌ Issues with the old version

  • Relies on template copying (cp -r word-root-workshop)
  • crudely replaces copy with sed
  • Homepage copy is hardcoded and does not adapt to the theme
  • Animation examples are hardcoded with English words

✅ Advantages of the new version

  • Zero template dependency; AI generates the page from scratch
  • AI creates all copy after understanding the theme
  • The homepage fully adapts to the theme's characteristics
  • Animations are automatically loaded from the data

🎯 Core conceptual shift

旧版:复制 + 替换
新版:理解 + 创作

旧版:模板驱动
新版:设计系统驱动

旧版:硬编码文案
新版:AI创作内容

Notes

⚠️ The data structure remains unchanged:

  • Still uses const WordRoots and a fixed field structure
  • This is the foundation of the core learning modes (flashcards, learning, testing)

⚠️ Design style is maintained:

  • Minimalism, yellow theme color, Inter font
  • These ensure brand recognition

⚠️ AI has free rein:

  • Homepage copy, statistics, introductory text
  • Create based on the theme's characteristics; do not make everything the same

Vercel deployment best practices 🆕

Problem background

Vercel may automatically connect to a GitHub repository during deployment, causing multiple projects to share the same repository and triggering deployment conflicts:

  • New projects overwrite old projects' deployments
  • Old projects' URLs become invalid
  • GitHub repository associations become chaotic

Solution

1. Do not connect GitHub by default

# 仅使用本地 Git,不推送到 GitHub
git init
git add .
git commit -m "Initial commit"
vercel --prod --yes  # 只部署,不连接 GitHub

2. Verify after deployment

# 检查生成的 projectId 是否唯一
cat .vercel/project.json

# 应该看到类似:
# {"projectId":"prj_UNIQUE_ID_HERE",...}

3. Remediation when a conflict is discovered

If you discover after deployment that an old project is affected:

# 立即进入旧项目目录
cd /Users/joe/Dropbox/code/旧项目名称

# 重新部署旧项目
vercel --prod --yes

# 确认旧项目恢复正常
curl -I https://旧项目URL

Troubleshooting checklist

After deploying a new project, you must check:

  • The new project's .vercel/project.json in projectId whether it is unique
  • Whether the new project's Production URL is accessible (HTTP 200)
  • Whether the old project's URL (if it exists) is still accessible
  • Whether the "Linked to" information in the deployment logs is correct

Lessons learned (real production incident)

Incident timeline:2026-02-25

Incident description:

  1. Generate evolutionary-psychology-workshop(evolutionary psychology), deployed successfully
  2. Generate design-aesthetics-workshop(design aesthetics), deployed successfully
  3. The user discovered that word.qiaomu.ai(the original word root and affix website) was displaying evolutionary psychology content
  4. Inspection revealed that word-root-workshop 's Git repository had been overwritten with evolutionary psychology content

Root cause analysis:

# 事故前的状态
evolutionary-psychology-workshop → origin: https://github.com/joeseesun/word-root-workshop.git
word-root-workshop              → origin: https://github.com/joeseesun/word-root-workshop.git
                                   ↑↑↑ 两个项目共享同一个 GitHub 仓库

Why it happened:

  • The old version of the skill used cp -r word-root-workshop to copy the template
  • During copying, the .git/ directory was also copied (including the remote repository configuration)
  • During deployment, Vercel detected the Git remote repository and automatically associated it
  • Multiple projects were associated with the same GitHub repository, and later deployments overwrote earlier ones

Scope of damage:

  • ⛔ word.qiaomu.ai (production domain) displayed incorrect content
  • ⛔ word-root-workshop's Git history was polluted
  • ⛔ User experience is impaired and requires urgent fixing

Urgent Fix Steps:

# 1. 恢复 word-root-workshop 到原始状态
cd /Users/joe/Dropbox/code/word-root-workshop
git log --oneline  # 找到原始提交
git reset --hard 14cc7b0  # 恢复到原始词根词缀内容

# 2. 修复 vercel.json 配置冲突
# 移除不兼容的 routes 配置

# 3. 重新部署
vercel --prod --yes

# 4. 验证恢复
curl -sL https://word.qiaomu.ai/ | grep "词根词缀记忆工坊"

# 5. 清理其他项目的 Git 远程仓库
cd /Users/joe/Dropbox/code/evolutionary-psychology-workshop
git remote remove origin

Thorough Solution(already implemented in Step 6):

  1. Mandatory pre-check: automatically remove all Git remote repositories before deployment
  2. Mandatory post-verification: check projectId uniqueness after deployment
  3. Automatic conflict detection: iterate through all projects and immediately report an error when the same projectId is found
  4. Complete logging: record all deployment operations to /tmp/
  5. Zero-tolerance policy: any detected conflict is not allowed to continue

Long-term Preventive Measures:

  • ✅ Deprecate the template copy mechanism (cp -r), switch to generating from scratch
  • ✅ Implement mandatory security checks in Step 6
  • ✅ Update the implementation checklist to clearly define the "secure deployment" step
  • ✅ Add a "Lessons Learned" section to the documentation to prevent future generations from repeating the same mistakes

Lessons Learned Summary:

"Copy + Paste is the root of all evil. Template-driven approaches seem efficient, but in reality they plant hidden dangers. Only generating from scratch (design-system-driven) can ensure that each project is truly independent."

Impact:

  • Prompted a complete refactor of the skill from "template-driven" to "design-system-driven"
  • Established the core principle of "zero template dependency"
  • Established a comprehensive deployment security check mechanism

Batch Update Mechanism 🔄

Use Cases

When the skill's design system has updates (such as CSS bug fixes or style improvements), the updates need to be synchronized to all deployed workshop projects.

Typical Scenarios:

  • CSS style fixes: fixed responsive layout issues
  • Design improvements: optimized card shadows, spacing, and color schemes
  • Feature enhancements: added new interactive animations
  • Security updates: fixed XSS vulnerabilities or other security issues

Update Script

Script Location:scripts/update-css.sh

Usage:

# 1. 演练模式(仅列出将更新的项目)
bash scripts/update-css.sh --dry-run

# 2. 执行更新
bash scripts/update-css.sh

Workflow

The script automatically performs the following steps:

  1. Scan projects: automatically scan /Users/joe/Dropbox/code/*-workshop
  2. Smart comparison: use the cmp command to compare CSS files and skip projects that are already on the latest version
  3. Secure backup: automatically back up the old CSS as a .backup file before updating
  4. Git commit: automatically commit CSS changes (commit message: chore: update CSS from skill template)
  5. Redeploy: call vercel --prod --yes to redeploy to the production environment
  6. Failure rollback: if deployment fails, automatically restore the backed-up CSS
  7. Statistics report: output update statistics (number of successful/skipped/failed projects)

Usage Example

Step 1: Prepare the latest CSS

Fix or improve in the skill directory templates/minimal.css:

cd /Users/joe/.claude/skills/knowledge-site-creator
# 编辑 templates/minimal.css
# 修复 bug 或改进样式

Step 2: Preview the projects that will be updated

bash scripts/update-css.sh --dry-run

Example output:

🔍 演练模式(不会实际更新)

📁 CSS 源文件:/path/to/templates/minimal.css
📊 文件大小:12345 bytes

🔍 扫描 workshop 项目...

================================================
📦 项目:evolutionary-psychology-workshop
📝 将更新:/path/to/evolutionary-psychology-workshop/css/minimal.css
📝 将重新部署到 Vercel

================================================
📦 项目:word-root-workshop
✓ 跳过:CSS 已是最新版本

================================================
📊 更新总结

  ✅ 成功更新:1 个项目
  ⚠️  跳过:1 个项目

💡 这是演练模式,没有实际执行任何操作
   要实际执行,请运行:bash scripts/update-css.sh

Step 3: Execute the batch update

bash scripts/update-css.sh

Example output:

================================================
📦 项目:evolutionary-psychology-workshop
💾 已备份旧 CSS:/path/to/css/minimal.css.backup
✓ 已更新 CSS
🚀 重新部署到 Vercel...
✅ 部署成功

================================================
📊 更新总结

  ✅ 成功更新:1 个项目
  ⚠️  跳过:1 个项目

Security Features

  1. Smart skipping: automatically skip projects that are already on the latest version to avoid unnecessary deployments
  2. Automatic backup: Back up the old CSS as .backup file before updating
  3. Failure rollback: Automatically restore the backup when deployment fails
  4. Git records: All updates have a Git commit, making the history traceable
  5. Dry-run mode:--dry-run mode lets you first see what will be updated

Notes

⚠️ Pre-update checks:

  • Make sure templates/minimal.css has been tested
  • Use --dry-run to preview the items that will be updated first
  • Check whether any items are currently being accessed by users (avoid updating during peak hours)

⚠️ Post-update verification:

  • After the script completes, randomly spot-check the websites of 2-3 items
  • Confirm that the new styles take effect and do not break the layout
  • Check whether the mobile display is normal

⚠️ Failure handling:

  • If an item fails to deploy, the script will automatically roll back that item's CSS
  • Failed items do not affect updates to other items
  • You can manually enter the failed item's directory and use vercel --prod --yes to retry

Extensibility

Update types that can be extended in the future:

The current script only supports CSS updates, but the same mechanism can be extended to:

  • JavaScript file updates (js/storage.js , etc.)
  • HTML template updates (such as fixing missing meta tags)
  • Configuration file updates (vercel.json , etc.)
  • Batch migrations (such as data structure changes)

Extension method: Refer to update-css.sh to create similar scripts, such as update-storage.sh、update-meta-tags.sh , etc.