Initial commit: VibeEngineering V2
- 两阶段分离:设计阶段人工确认,执行阶段全自动化 - 子代理驱动:Implementer → Spec Reviewer → Quality Reviewer - 原生 Task 系统:使用 Claude Code Task 替代自定义状态管理 - 跨 Compact 恢复:PreCompact + SessionStart Hook(内联命令实现) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
60
.claude/CLAUDE.md
Normal file
60
.claude/CLAUDE.md
Normal file
@ -0,0 +1,60 @@
|
||||
## VibeEngineering V2 项目说明
|
||||
|
||||
### Task 执行规范
|
||||
|
||||
大部分 Task 应当遵照 `subagent-driven-development` skill 的流程执行(协调者循环):
|
||||
1. 派发 Implementer 子代理实现功能
|
||||
2. 派发 Spec Reviewer 子代理审查规格符合性
|
||||
3. 派发 Code Quality Reviewer 子代理审查代码质量
|
||||
4. 主窗口标记 Task completed
|
||||
|
||||
**过于简单的 Task**(如单文件小改动)主代理可以自行完成,无需派发子代理,但**同样需要更新 metadata**。
|
||||
|
||||
### Task metadata 规范
|
||||
|
||||
无论主代理自己实现还是派发子代理,都必须更新 Task metadata:
|
||||
|
||||
- `started_at`: 任务开始时间
|
||||
- `completed_at`: 任务完成时间
|
||||
- `files_modified`: 修改的文件列表
|
||||
- `git_commit`: 提交的 commit hash
|
||||
- `commit_message`: 提交信息
|
||||
- `errors_encountered`: 遇到的错误及解决方案(必须如实记录)
|
||||
- `test_results`: 测试结果
|
||||
|
||||
**用途**:
|
||||
1. 跨 Compact 恢复时,读取 metadata 了解已完成任务的执行细节
|
||||
2. 校验 Task 读取所有 metadata,检测是否有降级实现
|
||||
3. 生成 Task 快照时,保存完整的执行历史
|
||||
|
||||
**按需读取**:恢复后可按需读取各 Task 的 metadata,无需全部加载到上下文。
|
||||
|
||||
### 命令使用流程
|
||||
|
||||
```
|
||||
设计阶段(需要人工确认):
|
||||
/vibe-brainstorming "需求描述" → design.md
|
||||
↓ 用户审核
|
||||
/vibe-plan → plan.md
|
||||
↓ 用户审核
|
||||
|
||||
执行阶段(全自动化):
|
||||
/vibe-execute → 创建 Task 系统 → 协调者循环执行
|
||||
```
|
||||
|
||||
### 跨 Compact 恢复
|
||||
|
||||
当上下文即将满时:
|
||||
1. PreCompact Hook 自动提取当前任务上下文到 `.vibe/last_task_context.jsonl`
|
||||
2. Compact 后 SessionStart Hook 引导恢复
|
||||
3. 读取 design.md → Task JSON → last_task_context.jsonl
|
||||
4. 从中断点继续执行
|
||||
|
||||
### 校验 Task
|
||||
|
||||
最后一个 Task 是自动追加的校验 Task:
|
||||
1. 对比 design.md 和所有 Task metadata
|
||||
2. 检测降级信号("暂时跳过"、"简化实现"等)
|
||||
3. 运行完整测试套件
|
||||
4. 发现问题 → 创建修复 Task → 继续执行
|
||||
5. 全部通过 → 保存快照 → 标记完成
|
||||
28
.claude/commands/vibe-brainstorming.md
Normal file
28
.claude/commands/vibe-brainstorming.md
Normal file
@ -0,0 +1,28 @@
|
||||
---
|
||||
name: vibe-brainstorming
|
||||
description: 需求探索和设计文档生成
|
||||
arguments:
|
||||
- name: requirement
|
||||
description: 用户需求描述
|
||||
required: true
|
||||
---
|
||||
|
||||
# /vibe-brainstorming
|
||||
|
||||
使用 brainstorming skill 探索需求,生成设计文档。
|
||||
|
||||
## 执行步骤
|
||||
|
||||
1. 调用 brainstorming skill,传入用户需求
|
||||
2. 探索需求,澄清问题
|
||||
3. 分析 2-3 种技术方案
|
||||
4. 生成设计文档:`docs/plans/YYYY-MM-DD-<feature>-design.md`
|
||||
|
||||
## 输出
|
||||
|
||||
完成后提示用户:
|
||||
```
|
||||
设计文档已生成:docs/plans/YYYY-MM-DD-<feature>-design.md
|
||||
|
||||
请审核设计文档,确认后执行:/vibe-plan
|
||||
```
|
||||
297
.claude/commands/vibe-execute.md
Normal file
297
.claude/commands/vibe-execute.md
Normal file
@ -0,0 +1,297 @@
|
||||
---
|
||||
name: vibe-execute
|
||||
description: 从 plan.md 创建 Task 系统并执行
|
||||
---
|
||||
|
||||
# /vibe-execute
|
||||
|
||||
从 plan.md 创建 Claude Code Task 系统,协调子代理执行所有任务。
|
||||
|
||||
## Phase 1: 初始化 - 创建 Task 系统
|
||||
|
||||
### 1.1 读取 plan.md
|
||||
|
||||
读取最新的实现计划:`docs/plans/*-plan.md`
|
||||
|
||||
### 1.2 按转换规则创建业务 Task
|
||||
|
||||
遍历 plan.md 中的所有 Task(按 Task 编号识别,如 Task 0.1, Task 1.1 等),为每个 Task 调用 TaskCreate:
|
||||
|
||||
```
|
||||
TaskCreate(
|
||||
subject="{Task 标题}",
|
||||
description="{Task 完整文本,原样保留}",
|
||||
activeForm="{简短的进行时描述}",
|
||||
metadata={"plan_task_id": "{Task 编号}"}
|
||||
)
|
||||
```
|
||||
|
||||
**示例**:
|
||||
|
||||
plan.md 中:
|
||||
```markdown
|
||||
## Task 1.1: 创建配置模块基础结构
|
||||
|
||||
**目标**: 使用Pydantic创建统一配置管理模块
|
||||
|
||||
**文件**:
|
||||
- 创建: src/config/__init__.py
|
||||
- 创建: src/config/settings.py
|
||||
|
||||
**验收标准**:
|
||||
- 配置模块可导入
|
||||
- get_config()返回AppConfig实例
|
||||
```
|
||||
|
||||
转换为:
|
||||
```
|
||||
TaskCreate(
|
||||
subject="创建配置模块基础结构",
|
||||
description="## Task 1.1: 创建配置模块基础结构\n\n**目标**: 使用Pydantic创建统一配置管理模块\n\n**文件**:\n- 创建: src/config/__init__.py\n- 创建: src/config/settings.py\n\n**验收标准**:\n- 配置模块可导入\n- get_config()返回AppConfig实例",
|
||||
activeForm="创建配置模块",
|
||||
metadata={"plan_task_id": "1.1"}
|
||||
)
|
||||
```
|
||||
|
||||
### 1.3 自动追加校验 Task
|
||||
|
||||
所有业务 Task 创建完成后,自动追加校验 Task:
|
||||
|
||||
```
|
||||
TaskCreate(
|
||||
subject="[校验] 全局需求验证",
|
||||
description="""## 全局校验 Task
|
||||
|
||||
**目标**: 验证所有业务 Task 忠实实现了 design.md 的全部需求,无降级、无遗漏。
|
||||
|
||||
**固定流程**:
|
||||
|
||||
### Step 0: 读取 session.yml 获取文件路径
|
||||
- 读取 .vibe/session.yml
|
||||
- 获取 design_doc 和 plan_doc 路径
|
||||
|
||||
### Step 1: 读取所有 Task JSON + metadata
|
||||
- 调用 TaskList 获取所有任务
|
||||
- 逐个 TaskGet 读取完整信息(含 metadata)
|
||||
- 重点检查每个已完成 Task 的 metadata:
|
||||
- errors_encountered:是否含"暂时跳过"、"简化实现"、"workaround"
|
||||
- test_results:测试数量是否符合 description 中的预期
|
||||
- files_modified:是否缺少 description 中指定的文件
|
||||
- commit_message:是否含"partial"、"skip"、"TODO"
|
||||
|
||||
### Step 2: 对比 design.md 逐条校验
|
||||
- 读取 session.yml 中 design_doc 指定的设计文档
|
||||
- 逐条对照:需求 → 对应 Task description → 对应 metadata 实际执行
|
||||
- 生成校验报告:
|
||||
- ✅ 需求 X:已实现(Task N, commit abc123)
|
||||
- ❌ 需求 Y:未实现 / 实现不完整
|
||||
- ⚠️ 需求 Z:降级实现(metadata 显示 workaround)
|
||||
|
||||
### Step 3: 运行完整测试套件
|
||||
- 执行项目的完整测试命令(不能只看 metadata 里的历史结果)
|
||||
- 确认所有测试通过
|
||||
|
||||
### Step 4: 检查未解决问题
|
||||
- 扫描所有 Task metadata 的 errors_encountered
|
||||
- 确认没有"暂时跳过"、"后续处理"的遗留问题
|
||||
|
||||
### Step 5: 处理校验结果
|
||||
|
||||
**全部通过:**
|
||||
1. 读取所有 Task JSON(Glob + Read),生成 task-snapshot.md 保存到 .vibe/task-snapshot.md
|
||||
2. 标记本 Task completed
|
||||
|
||||
**发现问题:**
|
||||
1. 输出详细校验报告
|
||||
2. 为每个问题创建修复 Task(TaskCreate,description 包含具体问题)
|
||||
3. 等待修复 Task 完成后重新执行 Step 1-4
|
||||
""",
|
||||
activeForm="全局需求验证",
|
||||
metadata={"verification_task": True}
|
||||
)
|
||||
```
|
||||
|
||||
### 1.4 创建 session.yml
|
||||
|
||||
```yaml
|
||||
# .vibe/session.yml
|
||||
task_list_id: "{TaskListId}"
|
||||
design_doc: "docs/plans/{timestamp}-design.md"
|
||||
plan_doc: "docs/plans/{timestamp}-plan.md"
|
||||
created_at: "{当前时间}"
|
||||
```
|
||||
|
||||
## Phase 2: 执行循环
|
||||
|
||||
获取下一个 pending Task,判断类型:
|
||||
|
||||
### 2.1 业务 Task 执行
|
||||
|
||||
调用 `subagent-driven-development` skill,派发子代理:
|
||||
|
||||
**派发 Implementer 子代理**:
|
||||
```
|
||||
Task tool (general-purpose):
|
||||
description: "实现 Task N: {Task标题}"
|
||||
prompt: |
|
||||
你正在实现一个具体的开发任务。
|
||||
|
||||
## 任务信息
|
||||
|
||||
{Task JSON 的完整 description 内容}
|
||||
|
||||
## Task metadata 更新规范(必须遵守)
|
||||
|
||||
在执行过程中,你必须持续通过 TaskUpdate 更新 metadata,记录执行细节。
|
||||
这些 metadata 将被后续的校验 Task 读取,用于检查是否有降级实现。
|
||||
|
||||
**1. 开始任务时:**
|
||||
TaskUpdate taskId={id} metadata={"started_at": "{当前时间}"}
|
||||
|
||||
**2. 每次修改文件后:**
|
||||
TaskUpdate taskId={id} metadata={"files_modified": ["file1.py", "file2.py"]}
|
||||
|
||||
**3. 遇到错误时(必须记录,包含解决方案):**
|
||||
TaskUpdate taskId={id} metadata={"errors_encountered": ["错误描述 - 解决方案"]}
|
||||
⚠️ 如果你无法解决某个问题而选择跳过或简化,必须如实记录:
|
||||
"无法实现XX功能 - 暂时跳过" 或 "XX过于复杂 - 简化为YY"
|
||||
|
||||
**4. 运行测试后:**
|
||||
TaskUpdate taskId={id} metadata={"test_results": "5/5 passed"}
|
||||
|
||||
**5. 提交代码后:**
|
||||
TaskUpdate taskId={id} metadata={"git_commit": "{commit hash}", "commit_message": "{提交信息}"}
|
||||
|
||||
**6. 任务完成时(由主窗口标记,不是你):**
|
||||
主窗口会调用 TaskUpdate status=completed,你只需要更新 metadata。
|
||||
|
||||
## 执行要求
|
||||
|
||||
- 遵循 TDD:先写测试,再实现
|
||||
- 每个有意义的变更都要提交
|
||||
- 自审:完成后检查自己的实现是否完整
|
||||
- 如实记录:不要隐瞒错误或跳过的内容
|
||||
```
|
||||
|
||||
**派发 Spec Reviewer 子代理**:
|
||||
```
|
||||
Task tool (general-purpose):
|
||||
description: "审查 Task N 的规格符合性"
|
||||
prompt: |
|
||||
你正在审查一个实现是否符合其规格。
|
||||
|
||||
## 被请求的内容
|
||||
|
||||
{Task JSON 的完整 description 内容}
|
||||
|
||||
## 实现者声称构建的内容
|
||||
|
||||
{Implementer 子代理的返回报告}
|
||||
|
||||
## 关键:不要信任报告
|
||||
|
||||
实现者的报告可能不完整、不准确或过于乐观。你必须独立验证。
|
||||
|
||||
**要:**
|
||||
- 阅读实际代码
|
||||
- 逐行比较实现和需求
|
||||
- 检查声称实现但实际没有的部分
|
||||
- 寻找没提到的额外功能
|
||||
|
||||
**不要:**
|
||||
- 相信实现者的说法
|
||||
- 信任完整性声明
|
||||
- 接受对需求的重新解释
|
||||
|
||||
## 检查项
|
||||
|
||||
**遗漏的需求:**
|
||||
- 所有被请求的内容都实现了吗?
|
||||
- 有跳过或遗漏的需求吗?
|
||||
|
||||
**多余的工作:**
|
||||
- 构建了没有被请求的东西吗?
|
||||
- 过度设计或添加了不必要的功能吗?
|
||||
|
||||
**误解:**
|
||||
- 对需求的解释与预期不同吗?
|
||||
- 解决了错误的问题吗?
|
||||
|
||||
## 输出格式
|
||||
|
||||
- ✅ 符合规格(如果代码检查后一切匹配)
|
||||
- ❌ 发现问题:[具体列出遗漏或多余的内容,带 file:line 引用]
|
||||
```
|
||||
|
||||
**派发 Code Quality Reviewer 子代理**(规格符合性审查通过后):
|
||||
```
|
||||
Task tool (general-purpose):
|
||||
description: "审查 Task N 的代码质量"
|
||||
prompt: |
|
||||
你正在审查代码更改的生产就绪性。
|
||||
|
||||
## 实现内容
|
||||
|
||||
{Implementer 报告的描述}
|
||||
|
||||
## 需求/计划
|
||||
|
||||
{Task JSON 的完整 description 内容}
|
||||
|
||||
## 要审查的 Git 范围
|
||||
|
||||
**Base:** {任务前的提交}
|
||||
**Head:** {当前提交}
|
||||
|
||||
```bash
|
||||
git diff --stat {BASE_SHA}..{HEAD_SHA}
|
||||
git diff {BASE_SHA}..{HEAD_SHA}
|
||||
```
|
||||
|
||||
## 审查清单
|
||||
|
||||
**代码质量:** 关注点分离、错误处理、类型安全、DRY、边界情况
|
||||
**架构:** 设计决策、可扩展性、性能、安全
|
||||
**测试:** 测试真实逻辑(非mock)、边界覆盖、集成测试、全部通过
|
||||
**生产就绪:** 向后兼容、文档、无明显bug
|
||||
|
||||
## 输出格式
|
||||
|
||||
### 优点
|
||||
[什么做得好?要具体。]
|
||||
|
||||
### 问题
|
||||
|
||||
#### 关键(必须修复)
|
||||
[Bug、安全问题、数据丢失风险]
|
||||
|
||||
#### 重要(应该修复)
|
||||
[架构问题、测试缺口]
|
||||
|
||||
#### 次要(可以改进)
|
||||
[代码风格、优化机会]
|
||||
|
||||
**对于每个问题:** File:line 引用 + 什么问题 + 为什么重要 + 如何修复
|
||||
|
||||
### 评估
|
||||
**可以合并?** [是/否/修复后可以]
|
||||
**理由:** [1-2 句话]
|
||||
```
|
||||
|
||||
**标记完成**:
|
||||
```
|
||||
TaskUpdate taskId={id} status=completed
|
||||
```
|
||||
|
||||
### 2.2 校验 Task 执行
|
||||
|
||||
按照校验 Task 的 description 中的固定流程执行(Step 0-5)。
|
||||
|
||||
## 降级检测信号表
|
||||
|
||||
| metadata 字段 | 降级信号 | 说明 |
|
||||
|---------------|---------|------|
|
||||
| `errors_encountered` | 含"暂时跳过"、"简化"、"workaround" | 遇到困难绕过了 |
|
||||
| `test_results` | 测试数量 < description 中的预期 | 测试覆盖不足 |
|
||||
| `files_modified` | 缺少 description 中指定的文件 | 有文件未修改 |
|
||||
| `commit_message` | 含"partial"、"skip"、"TODO" | 部分实现 |
|
||||
24
.claude/commands/vibe-plan.md
Normal file
24
.claude/commands/vibe-plan.md
Normal file
@ -0,0 +1,24 @@
|
||||
---
|
||||
name: vibe-plan
|
||||
description: 从设计文档创建实现计划
|
||||
---
|
||||
|
||||
# /vibe-plan
|
||||
|
||||
使用 writing-plans skill 分解任务,生成实现计划。
|
||||
|
||||
## 执行步骤
|
||||
|
||||
1. 读取最新的设计文档 `docs/plans/*-design.md`
|
||||
2. 调用 writing-plans skill
|
||||
3. 分解任务,定义 TDD 步骤
|
||||
4. 生成实现计划:`docs/plans/YYYY-MM-DD-<feature>-plan.md`
|
||||
|
||||
## 输出
|
||||
|
||||
完成后提示用户:
|
||||
```
|
||||
实现计划已生成:docs/plans/YYYY-MM-DD-<feature>-plan.md
|
||||
|
||||
请审核实现计划,确认后执行:/vibe-execute
|
||||
```
|
||||
96
.claude/hooks/extract-last-context.js
Normal file
96
.claude/hooks/extract-last-context.js
Normal file
@ -0,0 +1,96 @@
|
||||
/**
|
||||
* VibeEngineering V2 - 上下文提取脚本
|
||||
* 从 transcript.jsonl 提取最后一次 TaskUpdate completed 之后的内容
|
||||
*/
|
||||
|
||||
const fs = require('fs');
|
||||
|
||||
function extractSinceLastTaskComplete(transcriptPath) {
|
||||
const content = fs.readFileSync(transcriptPath, 'utf-8');
|
||||
const lines = content.split('\n').filter(Boolean);
|
||||
|
||||
// 倒序找最后一次 TaskUpdate status=completed
|
||||
let cutoffIndex = 0;
|
||||
for (let i = lines.length - 1; i >= 0; i--) {
|
||||
try {
|
||||
const entry = JSON.parse(lines[i]);
|
||||
if (entry.tool_name === 'TaskUpdate' &&
|
||||
entry.tool_input?.status === 'completed') {
|
||||
cutoffIndex = i + 1;
|
||||
break;
|
||||
}
|
||||
} catch (e) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
const relevantLines = lines.slice(cutoffIndex);
|
||||
const simplified = simplifyEntries(relevantLines);
|
||||
return simplified.map(e => JSON.stringify(e)).join('\n');
|
||||
}
|
||||
|
||||
function simplifyEntries(lines) {
|
||||
return lines.map(line => {
|
||||
try {
|
||||
const entry = JSON.parse(line);
|
||||
|
||||
// Claude 输出:全部保留
|
||||
if (entry.role === 'assistant') {
|
||||
return { type: 'assistant', content: entry.content };
|
||||
}
|
||||
|
||||
// 用户输入:全部保留
|
||||
if (entry.role === 'user') {
|
||||
return { type: 'user', content: entry.content };
|
||||
}
|
||||
|
||||
// Task tool 返回(子代理结果):全部保留
|
||||
if (entry.type === 'tool_result' && entry.agentId) {
|
||||
return {
|
||||
type: 'task_result',
|
||||
agentId: entry.agentId,
|
||||
content: entry.content
|
||||
};
|
||||
}
|
||||
|
||||
// 工具调用
|
||||
if (entry.tool_name) {
|
||||
const input = entry.tool_input || {};
|
||||
|
||||
// Task tool(派发子代理):prompt 全部保留
|
||||
if (entry.tool_name === 'Task') {
|
||||
return {
|
||||
type: 'tool',
|
||||
name: 'Task',
|
||||
subagent_type: input.subagent_type,
|
||||
description: input.description,
|
||||
prompt: input.prompt
|
||||
};
|
||||
}
|
||||
|
||||
// 其他工具:只保留关键参数
|
||||
const simplified = { type: 'tool', name: entry.tool_name };
|
||||
if (input.file_path) simplified.file = input.file_path;
|
||||
if (input.command) simplified.command = input.command;
|
||||
if (input.pattern) simplified.pattern = input.pattern;
|
||||
if (input.path) simplified.path = input.path;
|
||||
if (input.taskId) simplified.taskId = input.taskId;
|
||||
if (input.status) simplified.status = input.status;
|
||||
|
||||
if (entry.tool_result?.exit_code !== undefined) {
|
||||
simplified.exit_code = entry.tool_result.exit_code;
|
||||
}
|
||||
return simplified;
|
||||
}
|
||||
|
||||
return null;
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}).filter(Boolean);
|
||||
}
|
||||
|
||||
const transcriptPath = process.argv[2];
|
||||
if (transcriptPath) {
|
||||
console.log(extractSinceLastTaskComplete(transcriptPath));
|
||||
}
|
||||
24
.claude/hooks/pre-compact.sh
Normal file
24
.claude/hooks/pre-compact.sh
Normal file
@ -0,0 +1,24 @@
|
||||
#!/usr/bin/env bash
|
||||
# .claude/hooks/pre-compact.sh
|
||||
# VibeEngineering V2 - PreCompact Hook
|
||||
# 当上下文即将满时,从 transcript.jsonl 提取当前任务上下文
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# 使用 CLAUDE_PROJECT_DIR 环境变量确保路径正确
|
||||
PROJECT_DIR="${CLAUDE_PROJECT_DIR:-.}"
|
||||
cd "$PROJECT_DIR"
|
||||
|
||||
INPUT=$(cat)
|
||||
TRANSCRIPT_PATH=$(echo "$INPUT" | jq -r '.transcript_path')
|
||||
|
||||
# 等待 transcript.jsonl 完全写入
|
||||
sleep 1
|
||||
|
||||
# 确保 .vibe 目录存在
|
||||
mkdir -p .vibe
|
||||
|
||||
# 调用 Node.js 脚本提取上下文
|
||||
node "$PROJECT_DIR/.claude/hooks/extract-last-context.js" "$TRANSCRIPT_PATH" > .vibe/last_task_context.jsonl
|
||||
|
||||
exit 0
|
||||
79
.claude/hooks/session-start.sh
Normal file
79
.claude/hooks/session-start.sh
Normal file
@ -0,0 +1,79 @@
|
||||
#!/usr/bin/env bash
|
||||
# .claude/hooks/session-start.sh
|
||||
# VibeEngineering V2 - SessionStart Hook
|
||||
# 只有存在 last_task_context.jsonl 才触发恢复提示
|
||||
|
||||
# 不使用严格模式,避免 Windows 环境兼容问题
|
||||
|
||||
# 检查是否存在恢复上下文文件(当前目录已由调用者设置)
|
||||
if [[ ! -f ".vibe/last_task_context.jsonl" ]]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ ! -f ".vibe/session.yml" ]]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# 读取 task_list_id(使用 grep + sed 替代 yq,兼容性更好)
|
||||
TASK_LIST_ID=$(grep 'task_list_id:' .vibe/session.yml | sed 's/task_list_id: *//' | tr -d '"' | tr -d "'")
|
||||
TASK_DIR="$HOME/.claude/tasks/$TASK_LIST_ID"
|
||||
|
||||
cat << 'PROMPT'
|
||||
## 【系统提示:检测到跨 Compact 恢复 - VibeEngineering V2 执行阶段】
|
||||
|
||||
你正在从 Compact 后恢复执行上下文。请严格按以下顺序读取信息:
|
||||
|
||||
### Step 1: 读取执行流程定义
|
||||
```
|
||||
Read .claude/commands/vibe-execute.md
|
||||
```
|
||||
了解 Phase 2 执行循环的完整流程。
|
||||
|
||||
### Step 2: 读取 subagent-driven-development skill
|
||||
```
|
||||
Read .claude/skills/subagent-driven-development/SKILL.md
|
||||
```
|
||||
了解子代理派发模板(Implementer、Spec Reviewer、Code Quality Reviewer)。
|
||||
|
||||
### Step 3: 读取设计文档
|
||||
```
|
||||
Read .vibe/session.yml
|
||||
```
|
||||
获取 design_doc 路径,然后读取设计文档了解需求。
|
||||
|
||||
### Step 4: 读取所有 Task JSON
|
||||
PROMPT
|
||||
|
||||
echo '```'
|
||||
echo "Glob pattern='*.json' path='$TASK_DIR'"
|
||||
echo "然后 Read 每个返回的 JSON 文件"
|
||||
echo '```'
|
||||
|
||||
cat << 'PROMPT'
|
||||
从 Task JSON 了解:
|
||||
- 所有任务列表(subject)和详细信息(description)
|
||||
- 任务状态(status: pending / in_progress / completed)
|
||||
- **已完成任务的 metadata**:files_modified, errors_encountered, git_commit, test_results
|
||||
|
||||
### Step 5: 读取上一窗口执行上下文
|
||||
```
|
||||
Read .vibe/last_task_context.jsonl
|
||||
```
|
||||
从 last_task_context.jsonl 了解:
|
||||
- 当前任务执行到哪一步
|
||||
- Claude 的思考过程和决策
|
||||
- 用户的纠正指令(如有)
|
||||
- 子代理派发的任务和返回结果
|
||||
|
||||
### 恢复后行为
|
||||
|
||||
1. 找到第一个 status 为 pending 或 in_progress 的 Task
|
||||
2. 如果有 in_progress 的 Task,结合 last_task_context.jsonl 从中断点继续
|
||||
3. 如果上一个 Task 已 completed,从下一个 pending Task 开始
|
||||
4. **按照 vibe-execute.md Phase 2 和 subagent-driven-development skill 执行**:
|
||||
- 业务 Task:派发 Implementer → Spec Reviewer → Code Quality Reviewer → 标记完成
|
||||
- 校验 Task:执行 Step 0-5 固定流程
|
||||
5. 所有 Task 完成后,校验 Task 保存快照并标记完成
|
||||
PROMPT
|
||||
|
||||
exit 0
|
||||
26
.claude/settings.local.json
Normal file
26
.claude/settings.local.json
Normal file
@ -0,0 +1,26 @@
|
||||
{
|
||||
"hooks": {
|
||||
"SessionStart": [
|
||||
{
|
||||
"matcher": "",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "test -f .vibe/last_task_context.jsonl && cat .vibe/session-start-prompt.txt || exit 0"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"PreCompact": [
|
||||
{
|
||||
"matcher": "",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "mkdir -p .vibe && read input && echo \"$input\" | jq -r '.transcript_path' > .vibe/debug-transcript-path.txt && sleep 1 && node .claude/hooks/extract-last-context.js $(cat .vibe/debug-transcript-path.txt) > .vibe/last_task_context.jsonl 2> .vibe/debug-error.txt; exit 0"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
128
.claude/skills/brainstorming/SKILL.md
Normal file
128
.claude/skills/brainstorming/SKILL.md
Normal file
@ -0,0 +1,128 @@
|
||||
---
|
||||
name: brainstorming
|
||||
description: 在任何创造性工作之前必须使用 - 创建功能、构建组件、添加功能或修改行为时。探索用户意图、需求和设计,然后再实现。
|
||||
---
|
||||
|
||||
# 头脑风暴:将想法转化为设计
|
||||
|
||||
## 概述
|
||||
|
||||
通过自然的协作对话,帮助将想法转化为完整的设计和规格。
|
||||
|
||||
首先了解当前项目上下文,然后**每次只问一个问题**来细化想法。一旦你理解了要构建什么,以小节(200-300 字)呈现设计,每节之后确认是否正确。
|
||||
|
||||
## 流程
|
||||
|
||||
### 理解想法
|
||||
|
||||
- 首先查看当前项目状态(文件、文档、最近的提交)
|
||||
- **每次只问一个问题**来细化想法
|
||||
- 尽可能使用多选题,但开放式问题也可以
|
||||
- 每条消息只问一个问题 - 如果一个主题需要更多探索,拆分成多个问题
|
||||
- 关注理解:目的、约束、成功标准
|
||||
|
||||
### 探索方案
|
||||
|
||||
- 提出 2-3 种不同的方案及其权衡
|
||||
- 以对话方式呈现选项,并给出你的推荐和理由
|
||||
- 先说推荐的选项并解释原因
|
||||
|
||||
### 呈现设计
|
||||
|
||||
- 一旦你认为理解了要构建什么,呈现设计
|
||||
- 将设计分成 200-300 字的小节
|
||||
- 每节之后询问是否正确
|
||||
- 涵盖:架构、组件、数据流、错误处理、测试
|
||||
- 如果有不清楚的地方,准备返回澄清
|
||||
|
||||
## 设计完成后
|
||||
|
||||
### 文档
|
||||
|
||||
- 将验证过的设计写入 `docs/plans/YYYY-MM-DD-<topic>-design.md`
|
||||
- 提交设计文档到 git
|
||||
|
||||
### 输出
|
||||
|
||||
完成后输出:
|
||||
|
||||
```
|
||||
设计文档已完成并保存到 docs/plans/YYYY-MM-DD-<topic>-design.md
|
||||
|
||||
下一步:执行 /vibe-plan 创建实现计划。
|
||||
```
|
||||
|
||||
## 核心原则
|
||||
|
||||
- **每次只问一个问题** - 不要用多个问题淹没用户
|
||||
- **多选题优先** - 在可能时比开放式问题更容易回答
|
||||
- **严格遵循 YAGNI** - 从所有设计中移除不必要的功能
|
||||
- **探索替代方案** - 在确定之前总是提出 2-3 种方案
|
||||
- **增量验证** - 分节呈现设计,验证每一节
|
||||
- **保持灵活** - 当某些内容不清楚时返回澄清
|
||||
|
||||
## 常见错误
|
||||
|
||||
| 错误 | 正确做法 |
|
||||
|------|----------|
|
||||
| 一次问多个问题 | 每条消息只问一个问题 |
|
||||
| 假设用户意图 | 询问澄清 |
|
||||
| 跳过方案探索 | 总是提出 2-3 种方案 |
|
||||
| 设计完直接开始编码 | 等待用户确认设计 |
|
||||
| 添加"可能有用"的功能 | 严格遵循 YAGNI |
|
||||
|
||||
## 危险信号 - 停下来
|
||||
|
||||
如果你发现自己想:
|
||||
- "用户可能想要这个功能"
|
||||
- "我先开始编码,边做边设计"
|
||||
- "这个设计很明显,不需要确认"
|
||||
- "我可以跳过方案探索"
|
||||
|
||||
**所有这些都意味着:停下来。遵循流程。**
|
||||
|
||||
## 示例工作流
|
||||
|
||||
```
|
||||
用户: 我想添加一个用户认证功能
|
||||
|
||||
你: 让我先了解一下项目情况...
|
||||
[查看项目文件和结构]
|
||||
|
||||
你: 关于认证方式,你倾向于哪种?
|
||||
1. 用户名/密码(传统方式)
|
||||
2. OAuth(第三方登录,如 Google、GitHub)
|
||||
3. 两者都支持
|
||||
|
||||
用户: 先支持用户名/密码
|
||||
|
||||
你: 关于密码存储,你有特定的安全要求吗?
|
||||
1. 使用 bcrypt 哈希(推荐,安全性高)
|
||||
2. 使用 SHA-256(较快,安全性中等)
|
||||
3. 有其他要求请说明
|
||||
|
||||
用户: 用 bcrypt
|
||||
|
||||
你: 好的,让我呈现设计的第一部分...
|
||||
|
||||
## 1. 用户模型设计
|
||||
|
||||
用户表结构:
|
||||
- id: UUID
|
||||
- username: 唯一字符串
|
||||
- password_hash: bcrypt 哈希
|
||||
- created_at: 时间戳
|
||||
- updated_at: 时间戳
|
||||
|
||||
这部分设计是否正确?
|
||||
|
||||
用户: 是的
|
||||
|
||||
你: [继续下一部分...]
|
||||
|
||||
[设计完成后]
|
||||
|
||||
你: 设计文档已保存到 docs/plans/2026-01-19-user-auth-design.md
|
||||
|
||||
请审查设计,确认后我将创建实现计划。
|
||||
```
|
||||
274
.claude/skills/subagent-driven-development/SKILL.md
Normal file
274
.claude/skills/subagent-driven-development/SKILL.md
Normal file
@ -0,0 +1,274 @@
|
||||
---
|
||||
name: subagent-driven-development
|
||||
description: 在当前会话中执行有独立任务的实现计划时使用
|
||||
---
|
||||
|
||||
# 子代理驱动开发
|
||||
|
||||
通过为每个任务派发新的子代理来执行计划,每个任务完成后进行两阶段审查:先规格符合性审查,再代码质量审查。
|
||||
|
||||
**核心原则:** 每个任务新子代理 + 两阶段审查(规格然后质量)= 高质量,快速迭代
|
||||
|
||||
## 何时使用
|
||||
|
||||
```
|
||||
有实现计划?
|
||||
↓ 是
|
||||
任务大多独立?
|
||||
↓ 是
|
||||
→ 子代理驱动开发
|
||||
|
||||
否则 → 手动执行或先头脑风暴
|
||||
```
|
||||
|
||||
**优势:**
|
||||
- 同一会话(无上下文切换)
|
||||
- 每个任务新子代理(无上下文污染)
|
||||
- 每个任务后两阶段审查:先规格符合性,再代码质量
|
||||
- 快速迭代(任务之间无人工等待)
|
||||
|
||||
## 流程
|
||||
|
||||
```
|
||||
读取计划,使用 Task 系统创建任务
|
||||
↓
|
||||
每个业务 Task:
|
||||
├── 派发 Implementer 子代理
|
||||
│ ├── 阅读任务需求
|
||||
│ ├── 遵循 TDD
|
||||
│ ├── 实现功能
|
||||
│ ├── Git commit
|
||||
│ └── 更新 Task metadata
|
||||
│
|
||||
├── 派发 Spec Reviewer 子代理
|
||||
│ ├── 独立阅读代码
|
||||
│ ├── 逐条验证需求
|
||||
│ └── 检查遗漏或多余功能
|
||||
│ ↓ 问题? → Implementer 修复 → 重新审查
|
||||
│
|
||||
├── 派发 Code Quality Reviewer 子代理
|
||||
│ ├── 审查代码质量
|
||||
│ └── 分类问题:关键/重要/次要
|
||||
│ ↓ 问题? → Implementer 修复 → 重新审查
|
||||
│
|
||||
└── 主窗口:TaskUpdate status=completed
|
||||
↓
|
||||
还有更多任务?
|
||||
↓ 是 → 下一个 Task
|
||||
↓ 否 → 校验 Task 执行
|
||||
```
|
||||
|
||||
## 子代理派发模板
|
||||
|
||||
### Implementer 子代理
|
||||
|
||||
```
|
||||
Task tool (general-purpose):
|
||||
description: "实现 Task N: {Task标题}"
|
||||
prompt: |
|
||||
你正在实现一个具体的开发任务。
|
||||
|
||||
## 任务信息
|
||||
|
||||
{Task JSON 的完整 description 内容}
|
||||
|
||||
## Task metadata 更新规范(必须遵守)
|
||||
|
||||
在执行过程中,你必须持续通过 TaskUpdate 更新 metadata:
|
||||
|
||||
1. 开始任务时:
|
||||
TaskUpdate taskId={id} metadata={"started_at": "{当前时间}"}
|
||||
|
||||
2. 每次修改文件后:
|
||||
TaskUpdate taskId={id} metadata={"files_modified": ["file1.py", "file2.py"]}
|
||||
|
||||
3. 遇到错误时(必须记录,包含解决方案):
|
||||
TaskUpdate taskId={id} metadata={"errors_encountered": ["错误描述 - 解决方案"]}
|
||||
⚠️ 如果你无法解决某个问题而选择跳过或简化,必须如实记录
|
||||
|
||||
4. 运行测试后:
|
||||
TaskUpdate taskId={id} metadata={"test_results": "5/5 passed"}
|
||||
|
||||
5. 提交代码后:
|
||||
TaskUpdate taskId={id} metadata={"git_commit": "{hash}", "commit_message": "{msg}"}
|
||||
|
||||
## 执行要求
|
||||
|
||||
- 遵循 TDD:先写测试,再实现
|
||||
- 每个有意义的变更都要提交
|
||||
- 自审:完成后检查实现是否完整
|
||||
- 如实记录:不要隐瞒错误或跳过的内容
|
||||
```
|
||||
|
||||
### Spec Reviewer 子代理
|
||||
|
||||
```
|
||||
Task tool (general-purpose):
|
||||
description: "审查 Task N 的规格符合性"
|
||||
prompt: |
|
||||
你正在审查一个实现是否符合其规格。
|
||||
|
||||
## 被请求的内容
|
||||
|
||||
{Task JSON 的完整 description 内容}
|
||||
|
||||
## 实现者声称构建的内容
|
||||
|
||||
{Implementer 子代理的返回报告}
|
||||
|
||||
## 关键:不要信任报告
|
||||
|
||||
实现者的报告可能不完整、不准确或过于乐观。你必须独立验证。
|
||||
|
||||
**要:** 阅读实际代码,逐行比较,检查声称但未实现的部分
|
||||
**不要:** 相信报告,信任完整性声明
|
||||
|
||||
## 输出格式
|
||||
|
||||
- ✅ 符合规格
|
||||
- ❌ 发现问题:[具体列出,带 file:line 引用]
|
||||
```
|
||||
|
||||
### Code Quality Reviewer 子代理
|
||||
|
||||
```
|
||||
Task tool (general-purpose):
|
||||
description: "审查 Task N 的代码质量"
|
||||
prompt: |
|
||||
你正在审查代码更改的生产就绪性。
|
||||
|
||||
## 实现内容
|
||||
|
||||
{Implementer 报告}
|
||||
|
||||
## 需求/计划
|
||||
|
||||
{Task description}
|
||||
|
||||
## 审查清单
|
||||
|
||||
- 代码质量:关注点分离、错误处理、类型安全、DRY
|
||||
- 架构:设计决策、可扩展性、性能、安全
|
||||
- 测试:测试真实逻辑、边界覆盖、集成测试
|
||||
- 生产就绪:向后兼容、文档、无明显bug
|
||||
|
||||
## 输出格式
|
||||
|
||||
### 优点
|
||||
[具体说明做得好的地方]
|
||||
|
||||
### 问题
|
||||
- 关键(必须修复):[Bug、安全问题]
|
||||
- 重要(应该修复):[架构问题、测试缺口]
|
||||
- 次要(可以改进):[代码风格]
|
||||
|
||||
### 评估
|
||||
可以合并?[是/否/修复后可以]
|
||||
```
|
||||
|
||||
## 示例工作流
|
||||
|
||||
```
|
||||
你: 我正在使用子代理驱动开发执行此计划。
|
||||
|
||||
[调用 TaskList 获取所有任务]
|
||||
[找到第一个 pending Task]
|
||||
|
||||
Task 1: Hook 安装脚本
|
||||
|
||||
[派发 Implementer 子代理,包含完整任务 description]
|
||||
|
||||
Implementer: "开始之前 - hook 应该安装在用户级还是系统级?"
|
||||
|
||||
你: "用户级 (~/.config/vibe/hooks/)"
|
||||
|
||||
Implementer: "好的。现在开始实现..."
|
||||
[稍后] Implementer:
|
||||
- 实现了 install-hook 命令
|
||||
- 添加了测试,5/5 通过
|
||||
- 自审:发现遗漏了 --force 标志,已添加
|
||||
- 已提交
|
||||
- metadata 已更新
|
||||
|
||||
[派发 Spec Reviewer]
|
||||
Spec Reviewer: ✅ 符合规格 - 所有需求满足
|
||||
|
||||
[派发 Code Quality Reviewer]
|
||||
Code Reviewer: 优点:测试覆盖好。问题:无。通过。
|
||||
|
||||
[TaskUpdate taskId=1 status=completed]
|
||||
|
||||
Task 2: 恢复模式
|
||||
|
||||
[派发 Implementer 子代理]
|
||||
|
||||
Implementer:
|
||||
- 添加了 verify/repair 模式
|
||||
- 8/8 测试通过
|
||||
- 已提交
|
||||
|
||||
[派发 Spec Reviewer]
|
||||
Spec Reviewer: ❌ 问题:
|
||||
- 遗漏:进度报告(规格说"每 100 项报告一次")
|
||||
- 多余:添加了 --json 标志(未请求)
|
||||
|
||||
[Implementer 修复问题]
|
||||
Implementer: 移除了 --json 标志,添加了进度报告
|
||||
|
||||
[Spec Reviewer 再次审查]
|
||||
Spec Reviewer: ✅ 现在符合规格
|
||||
|
||||
[派发 Code Quality Reviewer]
|
||||
Code Reviewer: 问题(重要):魔法数字(100)
|
||||
|
||||
[Implementer 修复]
|
||||
Implementer: 提取了 PROGRESS_INTERVAL 常量
|
||||
|
||||
[Code Reviewer 再次审查]
|
||||
Code Reviewer: ✅ 通过
|
||||
|
||||
[TaskUpdate taskId=2 status=completed]
|
||||
|
||||
...
|
||||
|
||||
[所有业务 Task 完成后]
|
||||
[校验 Task 自动执行]
|
||||
[验证 design.md + metadata → 生成快照 → 标记完成]
|
||||
```
|
||||
|
||||
## 危险信号
|
||||
|
||||
**永远不要:**
|
||||
- 跳过审查(规格符合性或代码质量)
|
||||
- 带着未修复的问题继续
|
||||
- 并行派发多个实现子代理(冲突)
|
||||
- 让子代理读取计划文件(提供完整 description 代替)
|
||||
- 跳过 metadata 更新(校验 Task 需要这些信息)
|
||||
- 忽略子代理问题(在让他们继续之前回答)
|
||||
- 接受规格符合性的"差不多"(审查者发现问题 = 未完成)
|
||||
- **在规格符合性 ✅ 之前开始代码质量审查**(顺序错误)
|
||||
- 在任一审查有未解决问题时进入下一个任务
|
||||
|
||||
**如果子代理提问:**
|
||||
- 清晰完整地回答
|
||||
- 如需要提供额外上下文
|
||||
- 不要催他们进入实现
|
||||
|
||||
**如果审查者发现问题:**
|
||||
- Implementer(同一子代理)修复
|
||||
- 审查者再次审查
|
||||
- 重复直到通过
|
||||
- 不要跳过重新审查
|
||||
|
||||
**如果子代理任务失败:**
|
||||
- 派发修复子代理,带具体指示
|
||||
- 不要手动修复(上下文污染)
|
||||
|
||||
## 集成
|
||||
|
||||
**必需的工作流 skills:**
|
||||
- **brainstorming** - 创建设计文档(design.md)
|
||||
- **writing-plans** - 创建此 skill 执行的计划(plan.md)
|
||||
|
||||
**子代理应使用:**
|
||||
- **test-driven-development** - 子代理为每个任务遵循 TDD
|
||||
255
.claude/skills/test-driven-development/SKILL.md
Normal file
255
.claude/skills/test-driven-development/SKILL.md
Normal file
@ -0,0 +1,255 @@
|
||||
---
|
||||
name: test-driven-development
|
||||
description: 在实现任何功能或修复 bug 时使用,在写实现代码之前
|
||||
---
|
||||
|
||||
# 测试驱动开发 (TDD)
|
||||
|
||||
## 概述
|
||||
|
||||
先写测试。看它失败。写最小代码通过测试。
|
||||
|
||||
**核心原则:** 如果你没有看到测试失败,你就不知道它是否测试了正确的东西。
|
||||
|
||||
**违反规则的字面意思就是违反规则的精神。**
|
||||
|
||||
## 何时使用
|
||||
|
||||
**总是:**
|
||||
- 新功能
|
||||
- Bug 修复
|
||||
- 重构
|
||||
- 行为变更
|
||||
|
||||
**例外(需要用户确认):**
|
||||
- 一次性原型
|
||||
- 生成的代码
|
||||
- 配置文件
|
||||
|
||||
想着"就这一次跳过 TDD"?停下来。那是在找借口。
|
||||
|
||||
## 铁律
|
||||
|
||||
```
|
||||
没有失败的测试,就不能写生产代码
|
||||
```
|
||||
|
||||
先写代码再写测试?删除它。重新开始。
|
||||
|
||||
**没有例外:**
|
||||
- 不要把它作为"参考"保留
|
||||
- 不要在写测试时"调整"它
|
||||
- 不要看它
|
||||
- 删除就是删除
|
||||
|
||||
从测试重新实现。就这样。
|
||||
|
||||
## RED-GREEN-REFACTOR
|
||||
|
||||
```
|
||||
RED(写失败测试)
|
||||
↓ 验证失败正确
|
||||
GREEN(最小代码)
|
||||
↓ 验证通过全绿
|
||||
REFACTOR(清理)
|
||||
↓ 保持绿色
|
||||
→ 下一个 → RED
|
||||
```
|
||||
|
||||
### RED - 写失败的测试
|
||||
|
||||
写一个最小的测试,展示应该发生什么。
|
||||
|
||||
**好的示例:**
|
||||
```typescript
|
||||
test('重试失败操作 3 次', async () => {
|
||||
let attempts = 0;
|
||||
const operation = () => {
|
||||
attempts++;
|
||||
if (attempts < 3) throw new Error('fail');
|
||||
return 'success';
|
||||
};
|
||||
|
||||
const result = await retryOperation(operation);
|
||||
|
||||
expect(result).toBe('success');
|
||||
expect(attempts).toBe(3);
|
||||
});
|
||||
```
|
||||
清晰的名称,测试真实行为,只测一件事
|
||||
|
||||
**坏的示例:**
|
||||
```typescript
|
||||
test('retry works', async () => {
|
||||
const mock = jest.fn()
|
||||
.mockRejectedValueOnce(new Error())
|
||||
.mockResolvedValueOnce('success');
|
||||
await retryOperation(mock);
|
||||
expect(mock).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
```
|
||||
模糊的名称,测试 mock 而不是代码
|
||||
|
||||
**要求:**
|
||||
- 一个行为
|
||||
- 清晰的名称
|
||||
- 真实代码(除非不可避免,否则不用 mock)
|
||||
|
||||
### 验证 RED - 看它失败
|
||||
|
||||
**强制执行。永远不要跳过。**
|
||||
|
||||
```bash
|
||||
npm test path/to/test.test.ts
|
||||
```
|
||||
|
||||
确认:
|
||||
- 测试失败(不是报错)
|
||||
- 失败消息是预期的
|
||||
- 因为功能缺失而失败(不是拼写错误)
|
||||
|
||||
**测试通过了?** 你在测试已有行为。修复测试。
|
||||
|
||||
**测试报错了?** 修复错误,重新运行直到它正确失败。
|
||||
|
||||
### GREEN - 最小代码
|
||||
|
||||
写最简单的代码通过测试。
|
||||
|
||||
**好的示例:**
|
||||
```typescript
|
||||
async function retryOperation<T>(fn: () => Promise<T>): Promise<T> {
|
||||
for (let i = 0; i < 3; i++) {
|
||||
try {
|
||||
return await fn();
|
||||
} catch (e) {
|
||||
if (i === 2) throw e;
|
||||
}
|
||||
}
|
||||
throw new Error('unreachable');
|
||||
}
|
||||
```
|
||||
刚好够通过
|
||||
|
||||
**坏的示例:**
|
||||
```typescript
|
||||
async function retryOperation<T>(
|
||||
fn: () => Promise<T>,
|
||||
options?: {
|
||||
maxRetries?: number;
|
||||
backoff?: 'linear' | 'exponential';
|
||||
onRetry?: (attempt: number) => void;
|
||||
}
|
||||
): Promise<T> {
|
||||
// YAGNI - 过度设计
|
||||
}
|
||||
```
|
||||
|
||||
不要添加功能、重构其他代码,或"改进"超出测试范围的内容。
|
||||
|
||||
### 验证 GREEN - 看它通过
|
||||
|
||||
**强制执行。**
|
||||
|
||||
```bash
|
||||
npm test path/to/test.test.ts
|
||||
```
|
||||
|
||||
确认:
|
||||
- 测试通过
|
||||
- 其他测试仍然通过
|
||||
- 输出干净(没有错误、警告)
|
||||
|
||||
**测试失败?** 修复代码,不是测试。
|
||||
|
||||
**其他测试失败?** 现在修复。
|
||||
|
||||
### REFACTOR - 清理
|
||||
|
||||
只有在绿色之后:
|
||||
- 移除重复
|
||||
- 改进名称
|
||||
- 提取辅助函数
|
||||
|
||||
保持测试绿色。不要添加行为。
|
||||
|
||||
### 重复
|
||||
|
||||
下一个失败测试,测试下一个功能。
|
||||
|
||||
## 好的测试
|
||||
|
||||
| 质量 | 好 | 坏 |
|
||||
|------|----|----|
|
||||
| **最小** | 一件事。名称中有"和"?拆分它。 | `test('验证邮箱和域名和空格')` |
|
||||
| **清晰** | 名称描述行为 | `test('test1')` |
|
||||
| **展示意图** | 展示期望的 API | 隐藏代码应该做什么 |
|
||||
|
||||
## 为什么顺序很重要
|
||||
|
||||
**"我之后写测试来验证它能工作"**
|
||||
|
||||
事后写的测试立即通过。立即通过什么都证明不了:
|
||||
- 可能测试了错误的东西
|
||||
- 可能测试的是实现,不是行为
|
||||
- 可能遗漏了你忘记的边界情况
|
||||
- 你从未看到它捕获 bug
|
||||
|
||||
先测试强迫你看到测试失败,证明它确实在测试什么。
|
||||
|
||||
## 常见借口
|
||||
|
||||
| 借口 | 现实 |
|
||||
|------|------|
|
||||
| "太简单不需要测试" | 简单代码也会出错。测试只需 30 秒。 |
|
||||
| "我之后再测试" | 测试立即通过什么都证明不了。 |
|
||||
| "已经手动测试过了" | 临时 ≠ 系统化。没有记录,无法重新运行。 |
|
||||
| "删除 X 小时的工作太浪费" | 沉没成本谬误。保留不可信的代码才是浪费。 |
|
||||
| "TDD 太教条了,务实意味着灵活" | TDD 就是务实的:更快发现 bug,防止回归。 |
|
||||
| "事后测试能达到相同目的" | 不。事后测试回答"这做了什么?"先测试回答"这应该做什么?" |
|
||||
|
||||
## 危险信号 - 停下来重新开始
|
||||
|
||||
- 先写代码再写测试
|
||||
- 实现后才写测试
|
||||
- 测试立即通过
|
||||
- 无法解释测试为什么失败
|
||||
- 测试是"之后"添加的
|
||||
- 合理化"就这一次"
|
||||
- "我已经手动测试过了"
|
||||
- "保留作为参考"或"调整现有代码"
|
||||
|
||||
**所有这些意味着:删除代码。用 TDD 重新开始。**
|
||||
|
||||
## 验证清单
|
||||
|
||||
完成工作前:
|
||||
|
||||
- [ ] 每个新函数/方法都有测试
|
||||
- [ ] 在实现之前看到每个测试失败
|
||||
- [ ] 每个测试失败的原因是预期的(功能缺失,不是拼写错误)
|
||||
- [ ] 为每个测试写了最小代码通过
|
||||
- [ ] 所有测试通过
|
||||
- [ ] 输出干净(没有错误、警告)
|
||||
- [ ] 测试使用真实代码(mock 只在不可避免时使用)
|
||||
- [ ] 边界情况和错误都有覆盖
|
||||
|
||||
无法勾选所有项?你跳过了 TDD。重新开始。
|
||||
|
||||
## 卡住时
|
||||
|
||||
| 问题 | 解决方案 |
|
||||
|------|----------|
|
||||
| 不知道如何测试 | 先写期望的 API。先写断言。问用户。 |
|
||||
| 测试太复杂 | 设计太复杂。简化接口。 |
|
||||
| 必须 mock 所有东西 | 代码耦合太紧。使用依赖注入。 |
|
||||
| 测试设置太大 | 提取辅助函数。仍然复杂?简化设计。 |
|
||||
|
||||
## 最终规则
|
||||
|
||||
```
|
||||
生产代码 → 测试存在并且先失败了
|
||||
否则 → 不是 TDD
|
||||
```
|
||||
|
||||
没有用户许可不能有例外。
|
||||
143
.claude/skills/writing-plans/SKILL.md
Normal file
143
.claude/skills/writing-plans/SKILL.md
Normal file
@ -0,0 +1,143 @@
|
||||
---
|
||||
name: writing-plans
|
||||
description: 当有规格或需求的多步骤任务时使用,在接触代码之前
|
||||
---
|
||||
|
||||
# 编写实现计划
|
||||
|
||||
## 概述
|
||||
|
||||
编写全面的实现计划,假设执行者对代码库零上下文且判断力有限。记录他们需要知道的一切:每个任务要接触哪些文件、代码、测试、可能需要检查的文档、如何测试。将整个计划作为小任务交付。DRY。YAGNI。TDD。频繁提交。
|
||||
|
||||
假设执行者是技术熟练的开发者,但对我们的工具或问题领域几乎一无所知。假设他们不太擅长测试设计。
|
||||
|
||||
**开始时宣布:** "我正在使用 writing-plans skill 创建实现计划。"
|
||||
|
||||
**保存计划到:** `docs/plans/YYYY-MM-DD-<feature-name>-plan.md`
|
||||
|
||||
## 小粒度任务
|
||||
|
||||
**每个步骤是一个动作(2-5 分钟):**
|
||||
- "写失败的测试" - 一步
|
||||
- "运行它确保它失败" - 一步
|
||||
- "实现最小代码使测试通过" - 一步
|
||||
- "运行测试确保它们通过" - 一步
|
||||
- "提交" - 一步
|
||||
|
||||
## 计划文档头部
|
||||
|
||||
**每个计划必须以此头部开始:**
|
||||
|
||||
```markdown
|
||||
# [功能名称] 实现计划
|
||||
|
||||
> **执行指令**:使用 `/vibe-execute` 命令启动自动执行流程。
|
||||
> 执行过程中会自动创建 Task 系统,派发子代理,执行校验。
|
||||
|
||||
**目标**:[一句话描述要构建什么]
|
||||
|
||||
**架构**:[2-3 句话描述方案]
|
||||
|
||||
**技术栈**:[关键技术/库]
|
||||
|
||||
---
|
||||
```
|
||||
|
||||
## 任务结构
|
||||
|
||||
```markdown
|
||||
### Task N: [组件名称]
|
||||
|
||||
**文件:**
|
||||
- 创建: `exact/path/to/file.py`
|
||||
- 修改: `exact/path/to/existing.py:123-145`
|
||||
- 测试: `tests/exact/path/to/test.py`
|
||||
|
||||
**Step 1: 写失败测试**
|
||||
|
||||
```python
|
||||
def test_specific_behavior():
|
||||
result = function(input)
|
||||
assert result == expected
|
||||
```
|
||||
|
||||
**Step 2: 运行测试验证失败**
|
||||
|
||||
运行: `pytest tests/path/test.py::test_name -v`
|
||||
预期: FAIL,提示 "function not defined"
|
||||
|
||||
**Step 3: 写最小实现**
|
||||
|
||||
```python
|
||||
def function(input):
|
||||
return expected
|
||||
```
|
||||
|
||||
**Step 4: 运行测试验证通过**
|
||||
|
||||
运行: `pytest tests/path/test.py::test_name -v`
|
||||
预期: PASS
|
||||
|
||||
**Step 5: 提交**
|
||||
|
||||
```bash
|
||||
git add tests/path/test.py src/path/file.py
|
||||
git commit -m "feat: add specific feature"
|
||||
```
|
||||
|
||||
---
|
||||
```
|
||||
|
||||
## 关键原则
|
||||
|
||||
- 始终使用精确的文件路径
|
||||
- 计划中包含完整代码(不是"添加验证逻辑")
|
||||
- 精确的命令和预期输出
|
||||
- 引用相关 skills
|
||||
- DRY, YAGNI, TDD, 频繁提交
|
||||
|
||||
## 执行交接
|
||||
|
||||
保存计划后输出:
|
||||
|
||||
```
|
||||
计划已完成并保存到 docs/plans/YYYY-MM-DD-<feature>-plan.md
|
||||
|
||||
下一步:执行 /vibe-execute 开始子代理驱动执行。
|
||||
```
|
||||
|
||||
## 完成标准
|
||||
|
||||
```markdown
|
||||
## 完成标准
|
||||
|
||||
1. 所有 Task 验收标准满足
|
||||
2. 所有测试通过
|
||||
3. 对照用户需求确认功能完整
|
||||
|
||||
## 校验
|
||||
|
||||
执行完成后,校验 Task 会自动:
|
||||
1. 对比 design.md 和所有 Task metadata
|
||||
2. 检测降级实现
|
||||
3. 运行完整测试套件
|
||||
4. 生成 Task 快照
|
||||
```
|
||||
|
||||
## 常见错误
|
||||
|
||||
| 错误 | 正确做法 |
|
||||
|------|----------|
|
||||
| 模糊的文件路径 | 使用精确路径 `src/auth/login.py` |
|
||||
| "添加验证逻辑" | 提供完整的验证代码 |
|
||||
| 任务太大(>5 分钟) | 拆分成更小的步骤 |
|
||||
| 跳过测试验证步骤 | 每个 Step 都要验证 |
|
||||
|
||||
## 危险信号 - 停下来
|
||||
|
||||
- 任务描述超过一屏
|
||||
- 需要"理解"才能完成的任务
|
||||
- 没有明确的验证命令
|
||||
- 任务之间有隐含依赖
|
||||
|
||||
**这些都意味着:任务需要进一步拆分。**
|
||||
52
.vibe/session-start-prompt.txt
Normal file
52
.vibe/session-start-prompt.txt
Normal file
@ -0,0 +1,52 @@
|
||||
## 【系统提示:检测到跨 Compact 恢复 - VibeEngineering V2 执行阶段】
|
||||
|
||||
你正在从 Compact 后恢复执行上下文。请严格按以下顺序读取信息:
|
||||
|
||||
### Step 1: 读取执行流程定义
|
||||
```
|
||||
Read .claude/commands/vibe-execute.md
|
||||
```
|
||||
了解 Phase 2 执行循环的完整流程。
|
||||
|
||||
### Step 2: 读取 subagent-driven-development skill
|
||||
```
|
||||
Read .claude/skills/subagent-driven-development/SKILL.md
|
||||
```
|
||||
了解子代理派发模板(Implementer、Spec Reviewer、Code Quality Reviewer)。
|
||||
|
||||
### Step 3: 读取设计文档
|
||||
```
|
||||
Read .vibe/session.yml
|
||||
```
|
||||
获取 design_doc 路径,然后读取设计文档了解需求。
|
||||
|
||||
### Step 4: 读取所有 Task JSON
|
||||
```
|
||||
TaskList
|
||||
```
|
||||
然后用 TaskGet 读取每个任务的详细信息。
|
||||
|
||||
从 Task JSON 了解:
|
||||
- 所有任务列表(subject)和详细信息(description)
|
||||
- 任务状态(status: pending / in_progress / completed)
|
||||
- **已完成任务的 metadata**:files_modified, errors_encountered, git_commit, test_results
|
||||
|
||||
### Step 5: 读取上一窗口执行上下文
|
||||
```
|
||||
Read .vibe/last_task_context.jsonl
|
||||
```
|
||||
从 last_task_context.jsonl 了解:
|
||||
- 当前任务执行到哪一步
|
||||
- Claude 的思考过程和决策
|
||||
- 用户的纠正指令(如有)
|
||||
- 子代理派发的任务和返回结果
|
||||
|
||||
### 恢复后行为
|
||||
|
||||
1. 找到第一个 status 为 pending 或 in_progress 的 Task
|
||||
2. 如果有 in_progress 的 Task,结合 last_task_context.jsonl 从中断点继续
|
||||
3. 如果上一个 Task 已 completed,从下一个 pending Task 开始
|
||||
4. **按照 vibe-execute.md Phase 2 和 subagent-driven-development skill 执行**:
|
||||
- 业务 Task:派发 Implementer → Spec Reviewer → Code Quality Reviewer → 标记完成
|
||||
- 校验 Task:执行 Step 0-5 固定流程
|
||||
5. 所有 Task 完成后,校验 Task 保存快照并标记完成
|
||||
241
README.md
Normal file
241
README.md
Normal file
@ -0,0 +1,241 @@
|
||||
# VibeEngineering V2
|
||||
|
||||
在 Claude Code CLI 上实现自动化开发系统,融合 Superpowers 专家方法论 + 跨 Compact 恢复机制,实现"人工把关设计,自动执行任务"的工作流程。
|
||||
|
||||
## 核心特性
|
||||
|
||||
- **两阶段分离**:设计阶段需人工确认,执行阶段全自动化
|
||||
- **子代理驱动**:Implementer → Spec Reviewer → Quality Reviewer 三阶段审查
|
||||
- **原生 Task 系统**:使用 Claude Code 原生 Task 替代自定义状态管理
|
||||
- **跨 Compact 恢复**:PreCompact 保存上下文 → SessionStart 引导恢复
|
||||
- **降级检测**:校验 Task 对比 design.md + metadata 检测实现降级
|
||||
|
||||
## 工作流程
|
||||
|
||||
```
|
||||
设计阶段(需人工确认):
|
||||
/vibe-brainstorming "需求描述" → design.md
|
||||
↓ 用户审核
|
||||
/vibe-plan → plan.md
|
||||
↓ 用户审核
|
||||
|
||||
执行阶段(全自动化):
|
||||
/vibe-execute → 创建 Task 系统 → 协调者循环执行
|
||||
```
|
||||
|
||||
## 文件结构
|
||||
|
||||
```
|
||||
项目根目录/
|
||||
├── README.md # 本文件
|
||||
├── DESIGN.md # 详细设计文档
|
||||
│
|
||||
├── docs/plans/
|
||||
│ ├── {timestamp}-design.md # 需求和架构(设计阶段产出)
|
||||
│ └── {timestamp}-plan.md # 实现计划(设计阶段产出)
|
||||
│
|
||||
├── .vibe/
|
||||
│ ├── session.yml # 会话元信息
|
||||
│ ├── session-start-prompt.txt # SessionStart 恢复提示词
|
||||
│ ├── last_task_context.jsonl # 当前任务执行上下文(PreCompact 生成)
|
||||
│ └── task-snapshot.md # Task 快照(校验通过后保存)
|
||||
│
|
||||
├── .claude/
|
||||
│ ├── commands/
|
||||
│ │ ├── vibe-brainstorming.md # 需求探索命令
|
||||
│ │ ├── vibe-plan.md # 创建计划命令
|
||||
│ │ └── vibe-execute.md # 执行命令
|
||||
│ ├── hooks/
|
||||
│ │ └── extract-last-context.js # 上下文提取脚本
|
||||
│ ├── skills/
|
||||
│ │ ├── brainstorming/ # 需求探索方法论
|
||||
│ │ ├── writing-plans/ # 计划编写方法论
|
||||
│ │ ├── test-driven-development/ # TDD 方法论
|
||||
│ │ └── subagent-driven-development/ # 子代理驱动执行
|
||||
│ ├── settings.local.json # Hook 配置(内联命令)
|
||||
│ └── CLAUDE.md # 项目级提示词
|
||||
```
|
||||
|
||||
## Hook 实现说明
|
||||
|
||||
### 设计 vs 实现
|
||||
|
||||
原设计文档中 Hook 配置为调用外部 `.sh` 脚本:
|
||||
|
||||
```json
|
||||
{
|
||||
"hooks": {
|
||||
"SessionStart": [{"command": "bash .claude/hooks/session-start.sh"}],
|
||||
"PreCompact": [{"command": "bash .claude/hooks/pre-compact.sh"}]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**由于 Windows 环境下 Claude Code 执行外部 `.sh` 脚本存在兼容性问题**,当前实现改为**内联命令**方式:
|
||||
|
||||
```json
|
||||
{
|
||||
"hooks": {
|
||||
"SessionStart": [{
|
||||
"matcher": "",
|
||||
"hooks": [{
|
||||
"type": "command",
|
||||
"command": "test -f .vibe/last_task_context.jsonl && cat .vibe/session-start-prompt.txt || exit 0"
|
||||
}]
|
||||
}],
|
||||
"PreCompact": [{
|
||||
"matcher": "",
|
||||
"hooks": [{
|
||||
"type": "command",
|
||||
"command": "mkdir -p .vibe && read input && echo \"$input\" | jq -r '.transcript_path' > .vibe/debug-transcript-path.txt && sleep 1 && node .claude/hooks/extract-last-context.js $(cat .vibe/debug-transcript-path.txt) > .vibe/last_task_context.jsonl 2> .vibe/debug-error.txt; exit 0"
|
||||
}]
|
||||
}]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 内联命令 vs 外部脚本
|
||||
|
||||
| 方面 | 外部脚本 | 内联命令 |
|
||||
|------|----------|----------|
|
||||
| 可读性 | 好(独立文件) | 差(一行挤在 JSON) |
|
||||
| 维护性 | 易修改 | 复杂命令难改 |
|
||||
| Windows 兼容 | ❌ 有问题 | ✅ 正常工作 |
|
||||
| 功能 | 完整 | 完整 |
|
||||
|
||||
**结论**:功能完全一致,内联命令只是把脚本逻辑写成一行。
|
||||
|
||||
### Hook 工作原理
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ Claude Code │
|
||||
│ │
|
||||
│ Hook 事件触发 │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ ┌─────────────────────────────────────────────┐ │
|
||||
│ │ Shell 环境 (Git Bash) │ │
|
||||
│ │ │ │
|
||||
│ │ stdin ← Claude Code 传入的 JSON 数据 │ │
|
||||
│ │ stdout → 输出注入到 Claude 上下文 │ │
|
||||
│ │ │ │
|
||||
│ └─────────────────────────────────────────────┘ │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ Claude 收到 stdout 输出 │
|
||||
└─────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### SessionStart Hook
|
||||
|
||||
**触发时机**:每次打开 Claude Code 会话
|
||||
|
||||
**逻辑**:
|
||||
```bash
|
||||
test -f .vibe/last_task_context.jsonl # 检查是否存在恢复上下文
|
||||
&& cat .vibe/session-start-prompt.txt # 存在则输出恢复提示词
|
||||
|| exit 0 # 不存在则静默退出
|
||||
```
|
||||
|
||||
**作用**:只有在 Compact 后(存在 `last_task_context.jsonl`)才注入恢复提示词,引导 Claude 读取必要文件恢复执行。
|
||||
|
||||
### PreCompact Hook
|
||||
|
||||
**触发时机**:上下文即将满,执行 `/compact` 之前
|
||||
|
||||
**逻辑**:
|
||||
```bash
|
||||
mkdir -p .vibe # 确保目录存在
|
||||
&& read input # 从 stdin 读取 Claude Code 传入的 JSON
|
||||
&& echo "$input" | jq -r '.transcript_path' # 提取 transcript 文件路径
|
||||
&& sleep 1 # 等待 transcript 写入完成
|
||||
&& node extract-last-context.js ... # 调用 Node 脚本提取上下文
|
||||
```
|
||||
|
||||
**作用**:从 `transcript.jsonl` 提取最后一次 `TaskUpdate completed` 之后的内容,保存到 `last_task_context.jsonl`,供恢复时使用。
|
||||
|
||||
## 环境要求
|
||||
|
||||
### 依赖
|
||||
|
||||
- Node.js(用于运行 `extract-last-context.js`)
|
||||
- jq(用于解析 JSON)
|
||||
- Git Bash(Windows 用户)
|
||||
|
||||
### Windows 用户注意
|
||||
|
||||
Claude Code 在 Windows 上默认使用 cmd.exe 执行 Hook 命令,无法识别 bash 语法。需要设置环境变量指定 Git Bash 路径:
|
||||
|
||||
```batch
|
||||
set CLAUDE_CODE_GIT_BASH_PATH=<你的Git安装路径>\bin\bash.exe
|
||||
```
|
||||
|
||||
例如,如果 Git 安装在 `C:\Program Files\Git`:
|
||||
```batch
|
||||
set CLAUDE_CODE_GIT_BASH_PATH=C:\Program Files\Git\bin\bash.exe
|
||||
```
|
||||
|
||||
建议将此变量添加到系统环境变量中永久生效。
|
||||
|
||||
## 跨 Compact 恢复机制
|
||||
|
||||
```
|
||||
执行中...
|
||||
│
|
||||
▼ 上下文即将满
|
||||
┌─────────────────────────────────┐
|
||||
│ PreCompact Hook 触发 │
|
||||
│ 提取 transcript → last_task_context.jsonl
|
||||
└─────────────────────────────────┘
|
||||
│
|
||||
▼ Compact 发生(上下文被压缩)
|
||||
┌─────────────────────────────────┐
|
||||
│ SessionStart Hook 触发 │
|
||||
│ 检测到 last_task_context.jsonl │
|
||||
│ 输出恢复提示词给 Claude │
|
||||
└─────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
Claude 按提示读取:
|
||||
1. vibe-execute.md(执行流程)
|
||||
2. subagent-driven-development skill(子代理模板)
|
||||
3. session.yml → design.md(需求)
|
||||
4. TaskList(任务状态)
|
||||
5. last_task_context.jsonl(中断点上下文)
|
||||
│
|
||||
▼
|
||||
从中断点继续执行
|
||||
```
|
||||
|
||||
## 快速开始
|
||||
|
||||
1. 克隆项目到本地
|
||||
|
||||
2. Windows 用户设置环境变量(参见上方"环境要求")
|
||||
|
||||
3. 进入项目目录,启动 Claude Code:
|
||||
```batch
|
||||
cd your-project
|
||||
claude
|
||||
```
|
||||
|
||||
4. 开始设计阶段:
|
||||
```
|
||||
/vibe-brainstorming "你的需求描述"
|
||||
```
|
||||
|
||||
5. 审核 design.md 后,创建计划:
|
||||
```
|
||||
/vibe-plan
|
||||
```
|
||||
|
||||
6. 审核 plan.md 后,开始执行:
|
||||
```
|
||||
/vibe-execute
|
||||
```
|
||||
|
||||
## 参考
|
||||
|
||||
- [DESIGN.md](./DESIGN.md) - 完整设计文档
|
||||
- [Claude Code 官方文档](https://docs.anthropic.com/en/docs/claude-code)
|
||||
Reference in New Issue
Block a user