From joeseesun-knowledge-site-creator
Generates a complete knowledge learning website for any topic. AI analyzes the subject, creates content, builds pages, and deploys automatically to Vercel.
How this skill is triggered — by the user, by Claude, or both
Slash command
/joeseesun-knowledge-site-creator:knowledge-site-creatorThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
**AI理解主题,自动创作内容,生成网站,一键部署。**
AI理解主题,自动创作内容,生成网站,一键部署。
设计系统优先:
通用学习模式(核心功能):
零模板依赖:
cp -r 复制模板示例:
用户:"生成一个进化心理学学习网站"
AI自动执行:
✓ 分析"进化心理学"特点和价值
✓ 生成30个核心概念数据
✓ 创作首页文案、统计、介绍
✓ 参考设计系统生成页面
✓ 部署到 Vercel
✓ 返回:https://evolutionary-psychology.vercel.app
完成!
AI深入分析主题,输出主题分析:
主题分析 {
领域: "进化心理学",
特点: "跨学科(生物学+心理学),解释人类行为的底层逻辑",
价值: "理解人性、改善关系、优化决策",
受众: "心理学爱好者、自我提升者、教育工作者",
表达: "科学严谨 + 生活化案例,避免学术术语堆砌"
}
思考问题:
⚠️ 关键:生成两个文件,不只是数据!
通用数据结构:
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)
}
}
];
生成数量:默认20-30个,根据主题复杂度调整
AI创作,完全适配主题:
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创作原则:
hero.title: 简洁有力,3行,突出核心价值hero.subtitle: 具体说明学什么,为什么学stats: 真实、有说服力的数字,匹配主题特点footer.tagline: 一句话点题,朗朗上口footer.description: 2-3句,说清楚是什么、学什么、有什么用⚠️ 不再复制模板!AI参考设计规范,生成新页面
⚠️ 参考文档:references/design-system.md - 完整的设计规范
核心要点:
详细配色、字体、间距、组件样式见 design-system.md
⚠️ 功能参考:
references/core-patterns.md - 核心学习模式实现references/code-quality.md - 代码质量标准(必须遵守)references/seo-best-practices.md - SEO优化指南 🆕references/pwa-setup.md - PWA配置指南代码质量要求(强制):
详细规则见 references/code-quality.md。
AI参考设计系统,从零生成以下页面:
index.html - 首页 🆕
siteConfig.hero.title/subtitleWordRoots 动态加载前5个(见core-patterns.md §9)siteConfig.statssiteConfig.ctasiteConfig.footerlearn.html - 学习页(见core-patterns.md §5)
flashcard.html - 闪卡页(见core-patterns.md §4)
roots.html - 索引页(见core-patterns.md §7)
${itemName}索引progress.html - 进度页(见core-patterns.md §8)
root-detail.html - 详情页
css/minimal.css - 样式文件(见design-system.md)
js/storage.js - 存储逻辑(见core-patterns.md §3)
manifest.json - PWA 配置(见pwa-setup.md §1)🆕
sw.js - Service Worker(见pwa-setup.md §2)🆕
icon-192.png / icon-512.png - PWA 图标 🆕
sitemap.xml - 网站地图(见seo-best-practices.md §4)🆕
robots.txt - 爬虫指令(见seo-best-practices.md §5)🆕
⚠️ 强制要求:所有 HTML 文件必须包含完整的 meta 标签
每个 HTML 文件的 <head> 必须包含:
<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>
关键原则:
# 项目位置
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
⚠️ 关键:AI 生成的数据必须经过完整验证,确保质量和一致性
# ========================================
# 阶段 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 "✅ 所有验证通过!"
⚠️ 关键:每个项目必须独立部署,绝不共享 GitHub 仓库
部署流程(必须严格按顺序执行):
# ========================================
# 阶段 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"
安全原则(必须遵守):
如果仍然发生冲突(极端情况):
如果验证通过但实际仍有问题,执行紧急修复:
# 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. 向用户报告冲突详情和修复结果
✅ ${siteName} 已生成并部署!
📁 项目位置:${projectPath}
🌐 网站名称:${siteName}
📚 知识点数量:${itemCount}个
🔗 访问链接:${deployUrl}
🎯 核心特性:
- ✅ AI创作首页:根据主题生成标题、副标题、统计
- ✅ 动态动画:自动从数据加载,完全适配
- ✅ 通用学习模式:闪卡、渐进学习、测试、索引
- ✅ 极简设计:清晰的视觉层级,专注内容
🔧 下一步:
1. 打开网站查看效果
2. 审核AI生成的内容
3. 配置自定义域名(Vercel后台)
AI 执行此 skill 时,必须严格按顺序完成:
cp -r word-root-workshop)旧版:复制 + 替换
新版:理解 + 创作
旧版:模板驱动
新版:设计系统驱动
旧版:硬编码文案
新版:AI创作内容
⚠️ 数据结构不变:
const WordRoots 和固定字段结构⚠️ 设计风格保持:
⚠️ AI自由发挥:
Vercel 在部署时可能会自动连接 GitHub 仓库,导致多个项目共享同一个仓库,引发部署冲突:
1. 默认不连接 GitHub
# 仅使用本地 Git,不推送到 GitHub
git init
git add .
git commit -m "Initial commit"
vercel --prod --yes # 只部署,不连接 GitHub
2. 部署后验证
# 检查生成的 projectId 是否唯一
cat .vercel/project.json
# 应该看到类似:
# {"projectId":"prj_UNIQUE_ID_HERE",...}
3. 发现冲突时的补救
如果部署后发现旧项目受影响:
# 立即进入旧项目目录
cd /Users/joe/Dropbox/code/旧项目名称
# 重新部署旧项目
vercel --prod --yes
# 确认旧项目恢复正常
curl -I https://旧项目URL
部署新项目后,必须检查:
.vercel/project.json 中的 projectId 是否唯一事故时间线:2026-02-25
事故描述:
evolutionary-psychology-workshop(进化心理学),成功部署design-aesthetics-workshop(设计美学),成功部署word-root-workshop 项目的 Git 仓库被进化心理学内容覆盖根本原因分析:
# 事故前的状态
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 仓库
为什么会发生:
cp -r word-root-workshop 复制模板.git/ 目录也一起复制了(包含远程仓库配置)损害范围:
紧急修复步骤:
# 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
彻底解决方案(已在 Step 6 实施):
长期防范措施:
cp -r),改用从零生成教训总结:
"Copy + Paste 是万恶之源。模板驱动看似高效,实则埋下了隐患。只有从零生成(设计系统驱动),才能确保每个项目真正独立。"
影响:
当 skill 的设计系统有更新(如 CSS bug 修复、样式改进)时,需要将更新同步到所有已部署的 workshop 项目。
典型场景:
脚本位置:scripts/update-css.sh
使用方法:
# 1. 演练模式(仅列出将更新的项目)
bash scripts/update-css.sh --dry-run
# 2. 执行更新
bash scripts/update-css.sh
脚本自动执行以下步骤:
/Users/joe/Dropbox/code/*-workshopcmp 命令对比 CSS 文件,跳过已是最新版本的项目.backup 文件chore: update CSS from skill template)vercel --prod --yes 重新部署到生产环境步骤 1:准备最新的 CSS
在 skill 目录中修复或改进 templates/minimal.css:
cd /Users/joe/.claude/skills/knowledge-site-creator
# 编辑 templates/minimal.css
# 修复 bug 或改进样式
步骤 2:预览将更新的项目
bash scripts/update-css.sh --dry-run
输出示例:
🔍 演练模式(不会实际更新)
📁 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
步骤 3:执行批量更新
bash scripts/update-css.sh
输出示例:
================================================
📦 项目:evolutionary-psychology-workshop
💾 已备份旧 CSS:/path/to/css/minimal.css.backup
✓ 已更新 CSS
🚀 重新部署到 Vercel...
✅ 部署成功
================================================
📊 更新总结
✅ 成功更新:1 个项目
⚠️ 跳过:1 个项目
.backup 文件--dry-run 模式让你先看看会更新什么⚠️ 更新前检查:
templates/minimal.css 已经过测试--dry-run 先预览将更新的项目⚠️ 更新后验证:
⚠️ 失败处理:
vercel --prod --yes 重试未来可扩展的更新类型:
当前脚本仅支持 CSS 更新,但同样的机制可以扩展到:
js/storage.js 等)vercel.json 等)扩展方法:参考 update-css.sh 创建类似脚本,如 update-storage.sh、update-meta-tags.sh 等。
npx claudepluginhub joeseesun/qiaomu-knowledge-site-creatorGenerates complete websites from natural language prompts via the EvoWeb API. Creates HTML, CSS, JavaScript, and content. Build landing pages, portfolios, and business sites quickly.
Guides creation of production-ready Power Pages code sites as SPAs using React, Angular, Vue, or Astro, from requirements discovery to deployment with live dev server previews and git commits.
Clones inspiration websites exactly via browser extraction, customizes section-by-section with user content and AI-generated images, then deploys conversion-focused landing pages to Vercel.