feat: 自动化项目丰富 - 添加 CI/CD、实战案例和提示词

## 新增内容

### GitHub Actions 工作流
- ci.yml: Markdown lint、链接检查、项目结构验证
- welcome.yml: 自动欢迎新贡献者
- labeler.yml: PR 自动标签

### Issue 模板
- prompt_contribution.md: 提示词贡献模板
- documentation.md: 文档改进模板
- config.yml: 模板配置(含社区链接)

### 实战案例
- 02-blog-system.md: 个人博客系统(Next.js + MDX)
- 04-cli-tool.md: 命令行工具(Python + Click)
- 05-chrome-extension.md: Chrome 扩展(网页笔记助手)

### 编程提示词
- debug-expert.md: 调试专家提示词
- code-review.md: 代码审查提示词
- architecture-design.md: 架构设计提示词

## 相关 Issues
- #5 完善 Wiki 文档
- #6 添加更多实战案例
- #7 扩充提示词库
- #8 激活社区讨论
This commit is contained in:
tukuaiai
2025-12-18 16:13:40 +08:00
parent bfa0694868
commit 5423dd1fe8
14 changed files with 2049 additions and 16 deletions
@@ -0,0 +1,209 @@
# 实战案例:个人博客系统
> 难度:⭐⭐ 中等 | 预计时间:2-4 小时 | 技术栈:Next.js + MDX
## 🎯 项目目标
构建一个支持 Markdown 的个人博客系统,具备:
- 文章列表和详情页
- 标签分类
- 代码高亮
- 响应式设计
## 📋 开始前的准备
### 环境要求
- Node.js 18+
- 包管理器(npm/pnpm/yarn
### 第一步:需求澄清
复制以下提示词给 AI
```
我想用 Vibe Coding 的方式开发一个个人博客系统。
技术要求:
- 框架:Next.js 14 (App Router)
- 内容:MDX 格式的 Markdown 文章
- 样式:Tailwind CSS
- 部署:Vercel
功能需求:
1. 首页显示文章列表(标题、日期、摘要)
2. 文章详情页(支持代码高亮)
3. 标签页面(按标签筛选文章)
4. 关于页面
请帮我:
1. 确认技术栈是否合适
2. 生成项目结构
3. 一步步指导我完成开发
要求:每完成一步问我是否成功,再继续下一步。
```
## 🏗️ 项目结构
```
my-blog/
├── app/
│ ├── layout.tsx # 根布局
│ ├── page.tsx # 首页
│ ├── posts/
│ │ └── [slug]/
│ │ └── page.tsx # 文章详情
│ ├── tags/
│ │ └── [tag]/
│ │ └── page.tsx # 标签页
│ └── about/
│ └── page.tsx # 关于页
├── components/
│ ├── Header.tsx
│ ├── Footer.tsx
│ ├── PostCard.tsx
│ └── MDXContent.tsx
├── content/
│ └── posts/ # MDX 文章
│ ├── hello-world.mdx
│ └── vibe-coding.mdx
├── lib/
│ └── posts.ts # 文章处理逻辑
└── tailwind.config.js
```
## 🔧 核心代码片段
### 文章处理逻辑 (lib/posts.ts)
```typescript
import fs from 'fs'
import path from 'path'
import matter from 'gray-matter'
const postsDirectory = path.join(process.cwd(), 'content/posts')
export interface Post {
slug: string
title: string
date: string
tags: string[]
excerpt: string
content: string
}
export function getAllPosts(): Post[] {
const fileNames = fs.readdirSync(postsDirectory)
const posts = fileNames
.filter(name => name.endsWith('.mdx'))
.map(fileName => {
const slug = fileName.replace(/\.mdx$/, '')
const fullPath = path.join(postsDirectory, fileName)
const fileContents = fs.readFileSync(fullPath, 'utf8')
const { data, content } = matter(fileContents)
return {
slug,
title: data.title,
date: data.date,
tags: data.tags || [],
excerpt: data.excerpt || content.slice(0, 150),
content
}
})
.sort((a, b) => (a.date < b.date ? 1 : -1))
return posts
}
export function getPostBySlug(slug: string): Post | undefined {
return getAllPosts().find(post => post.slug === slug)
}
```
### 文章卡片组件 (components/PostCard.tsx)
```tsx
import Link from 'next/link'
import { Post } from '@/lib/posts'
export function PostCard({ post }: { post: Post }) {
return (
<article className="border-b border-gray-200 py-6">
<Link href={`/posts/${post.slug}`}>
<h2 className="text-xl font-bold hover:text-blue-600">
{post.title}
</h2>
</Link>
<time className="text-sm text-gray-500">{post.date}</time>
<p className="mt-2 text-gray-600">{post.excerpt}</p>
<div className="mt-2 flex gap-2">
{post.tags.map(tag => (
<Link
key={tag}
href={`/tags/${tag}`}
className="text-xs bg-gray-100 px-2 py-1 rounded hover:bg-gray-200"
>
#{tag}
</Link>
))}
</div>
</article>
)
}
```
## 📝 示例文章格式
```mdx
---
title: "Hello World"
date: "2024-01-01"
tags: ["入门", "博客"]
excerpt: "这是我的第一篇博客文章"
---
# Hello World
欢迎来到我的博客!
## 代码示例
```javascript
console.log('Hello, Vibe Coding!')
```
## 总结
这就是我的第一篇文章。
```
## 🚀 部署步骤
1. 推送代码到 GitHub
2. 在 Vercel 导入项目
3. 自动部署完成
## ✅ 验收清单
- [ ] 首页正确显示文章列表
- [ ] 点击文章可以进入详情页
- [ ] 代码块有语法高亮
- [ ] 标签页面可以筛选文章
- [ ] 移动端显示正常
- [ ] 部署到 Vercel 成功
## 🔗 相关资源
- [Next.js 文档](https://nextjs.org/docs)
- [MDX 文档](https://mdxjs.com/)
- [Tailwind CSS](https://tailwindcss.com/)
## 💡 进阶挑战
完成基础版本后,可以尝试:
- 添加搜索功能
- 添加评论系统(Giscus
- 添加 RSS 订阅
- 添加暗色模式
- 添加阅读时间估算
@@ -0,0 +1,298 @@
# 实战案例:命令行工具
> 难度:⭐⭐ 中等 | 预计时间:1-2 小时 | 技术栈:Python + Click
## 🎯 项目目标
构建一个实用的命令行工具,实现:
- 文件批量重命名
- 支持多种命名规则
- 预览和确认机制
- 彩色输出
## 📋 开始前的准备
### 环境要求
- Python 3.8+
- pip
### 第一步:需求澄清
复制以下提示词给 AI
```
我想用 Vibe Coding 的方式开发一个文件批量重命名的命令行工具。
技术要求:
- 语言:Python 3.8+
- CLI 框架:Click
- 输出美化:Rich
功能需求:
1. 支持多种重命名规则:
- 添加前缀/后缀
- 替换文本
- 序号命名
- 日期命名
2. 预览模式(不实际执行)
3. 递归处理子目录(可选)
4. 支持文件类型过滤
请帮我:
1. 确认技术栈是否合适
2. 生成项目结构
3. 一步步指导我完成开发
要求:每完成一步问我是否成功,再继续下一步。
```
## 🏗️ 项目结构
```
file-renamer/
├── renamer/
│ ├── __init__.py
│ ├── cli.py # CLI 入口
│ ├── core.py # 核心逻辑
│ └── rules.py # 重命名规则
├── tests/
│ └── test_core.py
├── pyproject.toml
└── README.md
```
## 🔧 核心代码
### CLI 入口 (renamer/cli.py)
```python
import click
from rich.console import Console
from rich.table import Table
from .core import FileRenamer
from .rules import PrefixRule, SuffixRule, ReplaceRule, SequenceRule
console = Console()
@click.group()
@click.version_option(version='1.0.0')
def cli():
"""文件批量重命名工具"""
pass
@cli.command()
@click.argument('directory', type=click.Path(exists=True))
@click.option('--prefix', '-p', help='添加前缀')
@click.option('--suffix', '-s', help='添加后缀')
@click.option('--replace', '-r', nargs=2, help='替换文本 (旧文本 新文本)')
@click.option('--sequence', '-n', is_flag=True, help='序号命名')
@click.option('--ext', '-e', multiple=True, help='文件扩展名过滤')
@click.option('--recursive', '-R', is_flag=True, help='递归处理子目录')
@click.option('--dry-run', '-d', is_flag=True, help='预览模式')
def rename(directory, prefix, suffix, replace, sequence, ext, recursive, dry_run):
"""批量重命名文件"""
renamer = FileRenamer(directory, recursive=recursive, extensions=ext)
# 添加规则
if prefix:
renamer.add_rule(PrefixRule(prefix))
if suffix:
renamer.add_rule(SuffixRule(suffix))
if replace:
renamer.add_rule(ReplaceRule(replace[0], replace[1]))
if sequence:
renamer.add_rule(SequenceRule())
if not renamer.rules:
console.print("[red]错误:请至少指定一个重命名规则[/red]")
return
# 获取预览
changes = renamer.preview()
if not changes:
console.print("[yellow]没有找到匹配的文件[/yellow]")
return
# 显示预览表格
table = Table(title="重命名预览")
table.add_column("原文件名", style="cyan")
table.add_column("新文件名", style="green")
for old, new in changes:
table.add_row(old, new)
console.print(table)
console.print(f"\n共 [bold]{len(changes)}[/bold] 个文件")
if dry_run:
console.print("[yellow]预览模式,未执行实际操作[/yellow]")
return
# 确认执行
if click.confirm('确认执行重命名?'):
renamer.execute()
console.print("[green]✓ 重命名完成![/green]")
else:
console.print("[yellow]已取消[/yellow]")
if __name__ == '__main__':
cli()
```
### 核心逻辑 (renamer/core.py)
```python
import os
from pathlib import Path
from typing import List, Tuple
class FileRenamer:
def __init__(self, directory: str, recursive: bool = False, extensions: tuple = ()):
self.directory = Path(directory)
self.recursive = recursive
self.extensions = extensions
self.rules = []
def add_rule(self, rule):
self.rules.append(rule)
def get_files(self) -> List[Path]:
pattern = '**/*' if self.recursive else '*'
files = []
for path in self.directory.glob(pattern):
if path.is_file():
if self.extensions:
if path.suffix.lower() in [f'.{e.lower()}' for e in self.extensions]:
files.append(path)
else:
files.append(path)
return sorted(files)
def apply_rules(self, filename: str) -> str:
result = filename
for rule in self.rules:
result = rule.apply(result)
return result
def preview(self) -> List[Tuple[str, str]]:
changes = []
for file in self.get_files():
old_name = file.stem
new_name = self.apply_rules(old_name)
if old_name != new_name:
changes.append((file.name, new_name + file.suffix))
return changes
def execute(self):
for file in self.get_files():
old_name = file.stem
new_name = self.apply_rules(old_name)
if old_name != new_name:
new_path = file.parent / (new_name + file.suffix)
file.rename(new_path)
```
### 重命名规则 (renamer/rules.py)
```python
from abc import ABC, abstractmethod
class Rule(ABC):
@abstractmethod
def apply(self, filename: str) -> str:
pass
class PrefixRule(Rule):
def __init__(self, prefix: str):
self.prefix = prefix
def apply(self, filename: str) -> str:
return f"{self.prefix}{filename}"
class SuffixRule(Rule):
def __init__(self, suffix: str):
self.suffix = suffix
def apply(self, filename: str) -> str:
return f"{filename}{self.suffix}"
class ReplaceRule(Rule):
def __init__(self, old: str, new: str):
self.old = old
self.new = new
def apply(self, filename: str) -> str:
return filename.replace(self.old, self.new)
class SequenceRule(Rule):
def __init__(self, start: int = 1, padding: int = 3):
self.counter = start
self.padding = padding
def apply(self, filename: str) -> str:
result = f"{str(self.counter).zfill(self.padding)}_{filename}"
self.counter += 1
return result
```
## 📦 安装配置 (pyproject.toml)
```toml
[build-system]
requires = ["setuptools>=61.0"]
build-backend = "setuptools.build_meta"
[project]
name = "file-renamer"
version = "1.0.0"
description = "文件批量重命名工具"
requires-python = ">=3.8"
dependencies = [
"click>=8.0",
"rich>=13.0",
]
[project.scripts]
renamer = "renamer.cli:cli"
```
## 🚀 使用示例
```bash
# 安装
pip install -e .
# 添加前缀
renamer rename ./photos --prefix "2024_"
# 替换文本
renamer rename ./docs --replace "old" "new"
# 序号命名 + 过滤扩展名
renamer rename ./images --sequence --ext jpg --ext png
# 预览模式
renamer rename ./files --prefix "backup_" --dry-run
# 递归处理
renamer rename ./project --suffix "_v2" --recursive
```
## ✅ 验收清单
- [ ] 命令行帮助信息正确显示
- [ ] 前缀/后缀功能正常
- [ ] 替换功能正常
- [ ] 序号命名功能正常
- [ ] 预览模式不执行实际操作
- [ ] 扩展名过滤正常
- [ ] 递归处理正常
## 💡 进阶挑战
- 添加撤销功能(记录操作日志)
- 支持正则表达式
- 添加日期格式化规则
- 支持配置文件
- 添加交互式模式
@@ -0,0 +1,402 @@
# 实战案例:Chrome 扩展
> 难度:⭐⭐ 中等 | 预计时间:2-3 小时 | 技术栈:JavaScript + Chrome API
## 🎯 项目目标
构建一个实用的 Chrome 扩展 - **网页笔记助手**
- 选中文本快速保存
- 自动记录来源 URL
- 本地存储笔记
- 导出功能
## 📋 开始前的准备
### 环境要求
- Chrome 浏览器
- 代码编辑器
### 第一步:需求澄清
复制以下提示词给 AI
```
我想用 Vibe Coding 的方式开发一个 Chrome 扩展 - 网页笔记助手。
技术要求:
- Manifest V3
- 纯 JavaScript(不用框架)
- Chrome Storage API
功能需求:
1. 右键菜单:选中文本后右键保存
2. 弹出窗口:显示所有笔记
3. 自动记录:来源 URL、保存时间
4. 导出功能:导出为 JSON/Markdown
请帮我:
1. 确认技术方案
2. 生成项目结构
3. 一步步指导我完成开发
要求:每完成一步问我是否成功,再继续下一步。
```
## 🏗️ 项目结构
```
web-notes/
├── manifest.json # 扩展配置
├── background.js # 后台脚本
├── popup/
│ ├── popup.html # 弹出窗口
│ ├── popup.css
│ └── popup.js
├── icons/
│ ├── icon16.png
│ ├── icon48.png
│ └── icon128.png
└── README.md
```
## 🔧 核心代码
### 扩展配置 (manifest.json)
```json
{
"manifest_version": 3,
"name": "网页笔记助手",
"version": "1.0.0",
"description": "快速保存网页内容到本地笔记",
"permissions": [
"storage",
"contextMenus",
"activeTab"
],
"background": {
"service_worker": "background.js"
},
"action": {
"default_popup": "popup/popup.html",
"default_icon": {
"16": "icons/icon16.png",
"48": "icons/icon48.png",
"128": "icons/icon128.png"
}
},
"icons": {
"16": "icons/icon16.png",
"48": "icons/icon48.png",
"128": "icons/icon128.png"
}
}
```
### 后台脚本 (background.js)
```javascript
// 创建右键菜单
chrome.runtime.onInstalled.addListener(() => {
chrome.contextMenus.create({
id: 'saveNote',
title: '保存到笔记',
contexts: ['selection']
});
});
// 处理右键菜单点击
chrome.contextMenus.onClicked.addListener(async (info, tab) => {
if (info.menuItemId === 'saveNote' && info.selectionText) {
const note = {
id: Date.now().toString(),
text: info.selectionText,
url: tab.url,
title: tab.title,
createdAt: new Date().toISOString()
};
// 获取现有笔记
const { notes = [] } = await chrome.storage.local.get('notes');
// 添加新笔记
notes.unshift(note);
// 保存
await chrome.storage.local.set({ notes });
// 显示通知(可选)
console.log('笔记已保存:', note.text.slice(0, 50));
}
});
```
### 弹出窗口 HTML (popup/popup.html)
```html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="popup.css">
</head>
<body>
<div class="container">
<header>
<h1>📝 我的笔记</h1>
<div class="actions">
<button id="exportJson">导出 JSON</button>
<button id="exportMd">导出 MD</button>
<button id="clearAll">清空</button>
</div>
</header>
<div class="search">
<input type="text" id="searchInput" placeholder="搜索笔记...">
</div>
<div id="notesList" class="notes-list">
<!-- 笔记列表 -->
</div>
<footer>
<span id="noteCount">0 条笔记</span>
</footer>
</div>
<script src="popup.js"></script>
</body>
</html>
```
### 弹出窗口样式 (popup/popup.css)
```css
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
width: 400px;
max-height: 500px;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}
.container {
padding: 16px;
}
header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 12px;
}
header h1 {
font-size: 18px;
}
.actions button {
padding: 4px 8px;
margin-left: 4px;
font-size: 12px;
cursor: pointer;
border: 1px solid #ddd;
border-radius: 4px;
background: #fff;
}
.actions button:hover {
background: #f5f5f5;
}
.search input {
width: 100%;
padding: 8px 12px;
border: 1px solid #ddd;
border-radius: 4px;
margin-bottom: 12px;
}
.notes-list {
max-height: 350px;
overflow-y: auto;
}
.note-item {
padding: 12px;
border: 1px solid #eee;
border-radius: 8px;
margin-bottom: 8px;
}
.note-text {
font-size: 14px;
line-height: 1.5;
margin-bottom: 8px;
}
.note-meta {
font-size: 12px;
color: #666;
}
.note-meta a {
color: #0066cc;
text-decoration: none;
}
.note-delete {
float: right;
cursor: pointer;
color: #999;
}
.note-delete:hover {
color: #ff4444;
}
footer {
margin-top: 12px;
text-align: center;
color: #666;
font-size: 12px;
}
.empty {
text-align: center;
color: #999;
padding: 40px;
}
```
### 弹出窗口逻辑 (popup/popup.js)
```javascript
let allNotes = [];
// 加载笔记
async function loadNotes() {
const { notes = [] } = await chrome.storage.local.get('notes');
allNotes = notes;
renderNotes(notes);
}
// 渲染笔记列表
function renderNotes(notes) {
const container = document.getElementById('notesList');
const countEl = document.getElementById('noteCount');
countEl.textContent = `${notes.length} 条笔记`;
if (notes.length === 0) {
container.innerHTML = '<div class="empty">暂无笔记<br>选中网页文字后右键保存</div>';
return;
}
container.innerHTML = notes.map(note => `
<div class="note-item" data-id="${note.id}">
<span class="note-delete" onclick="deleteNote('${note.id}')">✕</span>
<div class="note-text">${escapeHtml(note.text)}</div>
<div class="note-meta">
<a href="${note.url}" target="_blank">${note.title || '未知页面'}</a>
<br>
${formatDate(note.createdAt)}
</div>
</div>
`).join('');
}
// 删除笔记
async function deleteNote(id) {
allNotes = allNotes.filter(n => n.id !== id);
await chrome.storage.local.set({ notes: allNotes });
renderNotes(allNotes);
}
// 搜索
document.getElementById('searchInput').addEventListener('input', (e) => {
const query = e.target.value.toLowerCase();
const filtered = allNotes.filter(note =>
note.text.toLowerCase().includes(query) ||
(note.title && note.title.toLowerCase().includes(query))
);
renderNotes(filtered);
});
// 导出 JSON
document.getElementById('exportJson').addEventListener('click', () => {
const blob = new Blob([JSON.stringify(allNotes, null, 2)], { type: 'application/json' });
downloadBlob(blob, 'notes.json');
});
// 导出 Markdown
document.getElementById('exportMd').addEventListener('click', () => {
const md = allNotes.map(note =>
`## ${formatDate(note.createdAt)}\n\n${note.text}\n\n> 来源: [${note.title}](${note.url})\n`
).join('\n---\n\n');
const blob = new Blob([md], { type: 'text/markdown' });
downloadBlob(blob, 'notes.md');
});
// 清空
document.getElementById('clearAll').addEventListener('click', async () => {
if (confirm('确定清空所有笔记?')) {
allNotes = [];
await chrome.storage.local.set({ notes: [] });
renderNotes([]);
}
});
// 工具函数
function escapeHtml(text) {
const div = document.createElement('div');
div.textContent = text;
return div.innerHTML;
}
function formatDate(isoString) {
return new Date(isoString).toLocaleString('zh-CN');
}
function downloadBlob(blob, filename) {
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = filename;
a.click();
URL.revokeObjectURL(url);
}
// 初始化
loadNotes();
```
## 🚀 安装步骤
1. 打开 Chrome,访问 `chrome://extensions/`
2. 开启「开发者模式」
3. 点击「加载已解压的扩展程序」
4. 选择项目文件夹
## ✅ 验收清单
- [ ] 扩展成功加载
- [ ] 右键菜单显示「保存到笔记」
- [ ] 选中文本可以保存
- [ ] 弹出窗口显示笔记列表
- [ ] 搜索功能正常
- [ ] 删除功能正常
- [ ] 导出 JSON 正常
- [ ] 导出 Markdown 正常
## 💡 进阶挑战
- 添加标签分类
- 支持云同步(Chrome Sync
- 添加快捷键
- 支持图片保存
- 添加笔记编辑功能
+81 -16
View File
@@ -8,23 +8,62 @@
| 案例 | 难度 | 技术栈 | 耗时 | 状态 |
|:---|:---|:---|:---|:---|
| [Todo App](./01-todo-app.md) | ⭐ 入门 | HTML/CSS/JS | 30 分钟 | 待补充 |
| [个人博客](./02-blog.md) | ⭐⭐ 初级 | Next.js | 2 小时 | 待补充 |
| [AI 聊天机器人](./03-chatbot.md) | ⭐⭐ 初级 | Python/FastAPI | 1 小时 | 待补充 |
| [全栈 SaaS](./04-saas.md) | ⭐⭐ | Next.js/Supabase | 1 天 | 待补充 |
| [Chrome 插件](./05-chrome-extension.md) | ⭐⭐ 初级 | JS/Chrome API | 2 小时 | 待补充 |
| [Todo App](./01-todo-app.md) | ⭐ 入门 | HTML/CSS/JS | 30 分钟 | ✅ 完成 |
| [个人博客](./02-blog-system.md) | ⭐⭐ 中等 | Next.js/MDX | 2-4 小时 | ✅ 完成 |
| [AI 聊天机器人](./03-chatbot.md) | ⭐⭐ 中等 | Python/FastAPI | 1-2 小时 | ✅ 完成 |
| [命令行工具](./04-cli-tool.md) | ⭐⭐ 中 | Python/Click | 1-2 小时 | ✅ 完成 |
| [Chrome 扩展](./05-chrome-extension.md) | ⭐⭐ 中等 | JS/Chrome API | 2-3 小时 | ✅ 完成 |
---
## 案例格式
## 快速开始
每个案例包含:
每个案例包含:
1. **开始前的提示词** - 直接复制给 AI
2. **项目结构** - 清晰的目录规划
3. **核心代码** - 关键实现片段
4. **验收清单** - 确保功能完整
5. **进阶挑战** - 继续提升
1. **项目目标** - 一句话说明要做什么
2. **最终效果** - GIF/截图展示
3. **使用的提示词** - 完整可复制
4. **踩坑记录** - 遇到的问题和解决方案
5. **完整代码** - GitHub 链接或代码片段
### 使用方式
1. 选择一个感兴趣的案例
2. 复制「第一步」的提示词给 AI
3. 跟着 AI 的指导一步步完成
4. 对照验收清单检查功能
---
## 案例详情
### ⭐ 入门级
#### [Todo App](./01-todo-app.md)
最简单的入门项目,30 分钟完成一个待办事项应用。
- 技术栈:纯 HTML/CSS/JavaScript
- 学习重点:DOM 操作、本地存储
### ⭐⭐ 中等级
#### [个人博客](./02-blog-system.md)
构建一个支持 Markdown 的个人博客系统。
- 技术栈:Next.js + MDX + Tailwind CSS
- 学习重点:静态生成、文件系统路由
#### [AI 聊天机器人](./03-chatbot.md)
接入 AI API 的聊天机器人。
- 技术栈:Python + FastAPI + OpenAI API
- 学习重点:API 调用、流式响应
#### [命令行工具](./04-cli-tool.md)
实用的文件批量重命名工具。
- 技术栈:Python + Click + Rich
- 学习重点:CLI 开发、文件操作
#### [Chrome 扩展](./05-chrome-extension.md)
网页笔记助手浏览器扩展。
- 技术栈:JavaScript + Chrome API
- 学习重点:扩展开发、本地存储
---
@@ -32,7 +71,33 @@
欢迎提交你的 Vibe Coding 实战案例!
格式要求
- 必须包含完整提示词
- 必须有效果展示(GIF 优先)
- 记录踩坑经验
### 格式要求
```markdown
# 实战案例:项目名称
> 难度:⭐⭐ | 预计时间:X 小时 | 技术栈:XXX
## 🎯 项目目标
## 📋 开始前的准备
## 🏗️ 项目结构
## 🔧 核心代码
## 🚀 部署/使用
## ✅ 验收清单
## 💡 进阶挑战
```
### 提交方式
1. Fork 本仓库
2.`i18n/zh/documents/实战案例/` 添加案例文件
3. 更新本 README 的案例列表
4. 提交 Pull Request
---
## 相关资源
- [从零开始 Vibe Coding](../从零开始vibecoding/)
- [常见坑汇总](../常见坑汇总/)
- [提示词库](../../prompts/)