commit c484cafb454d921ed5bdad4ea057e3d3be2480c3 Author: 闫旭隆 <15945644+yan-xulong@user.noreply.gitee.com> Date: Wed Feb 4 18:00:55 2026 +0800 Initial commit: VibeEngineering V2 - 两阶段分离:设计阶段人工确认,执行阶段全自动化 - 子代理驱动:Implementer → Spec Reviewer → Quality Reviewer - 原生 Task 系统:使用 Claude Code Task 替代自定义状态管理 - 跨 Compact 恢复:PreCompact + SessionStart Hook(内联命令实现) Co-Authored-By: Claude Opus 4.5 diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md new file mode 100644 index 0000000..90385c0 --- /dev/null +++ b/.claude/CLAUDE.md @@ -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. 全部通过 → 保存快照 → 标记完成 diff --git a/.claude/commands/vibe-brainstorming.md b/.claude/commands/vibe-brainstorming.md new file mode 100644 index 0000000..87d4679 --- /dev/null +++ b/.claude/commands/vibe-brainstorming.md @@ -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--design.md` + +## 输出 + +完成后提示用户: +``` +设计文档已生成:docs/plans/YYYY-MM-DD--design.md + +请审核设计文档,确认后执行:/vibe-plan +``` diff --git a/.claude/commands/vibe-execute.md b/.claude/commands/vibe-execute.md new file mode 100644 index 0000000..c0745a5 --- /dev/null +++ b/.claude/commands/vibe-execute.md @@ -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" | 部分实现 | diff --git a/.claude/commands/vibe-plan.md b/.claude/commands/vibe-plan.md new file mode 100644 index 0000000..1677a54 --- /dev/null +++ b/.claude/commands/vibe-plan.md @@ -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--plan.md` + +## 输出 + +完成后提示用户: +``` +实现计划已生成:docs/plans/YYYY-MM-DD--plan.md + +请审核实现计划,确认后执行:/vibe-execute +``` diff --git a/.claude/hooks/extract-last-context.js b/.claude/hooks/extract-last-context.js new file mode 100644 index 0000000..8623dd3 --- /dev/null +++ b/.claude/hooks/extract-last-context.js @@ -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)); +} diff --git a/.claude/hooks/pre-compact.sh b/.claude/hooks/pre-compact.sh new file mode 100644 index 0000000..0d19421 --- /dev/null +++ b/.claude/hooks/pre-compact.sh @@ -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 diff --git a/.claude/hooks/session-start.sh b/.claude/hooks/session-start.sh new file mode 100644 index 0000000..88eab41 --- /dev/null +++ b/.claude/hooks/session-start.sh @@ -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 diff --git a/.claude/settings.local.json b/.claude/settings.local.json new file mode 100644 index 0000000..fbf9705 --- /dev/null +++ b/.claude/settings.local.json @@ -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" + } + ] + } + ] + } +} diff --git a/.claude/skills/brainstorming/SKILL.md b/.claude/skills/brainstorming/SKILL.md new file mode 100644 index 0000000..502e8ab --- /dev/null +++ b/.claude/skills/brainstorming/SKILL.md @@ -0,0 +1,128 @@ +--- +name: brainstorming +description: 在任何创造性工作之前必须使用 - 创建功能、构建组件、添加功能或修改行为时。探索用户意图、需求和设计,然后再实现。 +--- + +# 头脑风暴:将想法转化为设计 + +## 概述 + +通过自然的协作对话,帮助将想法转化为完整的设计和规格。 + +首先了解当前项目上下文,然后**每次只问一个问题**来细化想法。一旦你理解了要构建什么,以小节(200-300 字)呈现设计,每节之后确认是否正确。 + +## 流程 + +### 理解想法 + +- 首先查看当前项目状态(文件、文档、最近的提交) +- **每次只问一个问题**来细化想法 +- 尽可能使用多选题,但开放式问题也可以 +- 每条消息只问一个问题 - 如果一个主题需要更多探索,拆分成多个问题 +- 关注理解:目的、约束、成功标准 + +### 探索方案 + +- 提出 2-3 种不同的方案及其权衡 +- 以对话方式呈现选项,并给出你的推荐和理由 +- 先说推荐的选项并解释原因 + +### 呈现设计 + +- 一旦你认为理解了要构建什么,呈现设计 +- 将设计分成 200-300 字的小节 +- 每节之后询问是否正确 +- 涵盖:架构、组件、数据流、错误处理、测试 +- 如果有不清楚的地方,准备返回澄清 + +## 设计完成后 + +### 文档 + +- 将验证过的设计写入 `docs/plans/YYYY-MM-DD--design.md` +- 提交设计文档到 git + +### 输出 + +完成后输出: + +``` +设计文档已完成并保存到 docs/plans/YYYY-MM-DD--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 + +请审查设计,确认后我将创建实现计划。 +``` diff --git a/.claude/skills/subagent-driven-development/SKILL.md b/.claude/skills/subagent-driven-development/SKILL.md new file mode 100644 index 0000000..0b7f182 --- /dev/null +++ b/.claude/skills/subagent-driven-development/SKILL.md @@ -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 diff --git a/.claude/skills/test-driven-development/SKILL.md b/.claude/skills/test-driven-development/SKILL.md new file mode 100644 index 0000000..8817cd5 --- /dev/null +++ b/.claude/skills/test-driven-development/SKILL.md @@ -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(fn: () => Promise): Promise { + 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( + fn: () => Promise, + options?: { + maxRetries?: number; + backoff?: 'linear' | 'exponential'; + onRetry?: (attempt: number) => void; + } +): Promise { + // 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 +``` + +没有用户许可不能有例外。 diff --git a/.claude/skills/writing-plans/SKILL.md b/.claude/skills/writing-plans/SKILL.md new file mode 100644 index 0000000..9439721 --- /dev/null +++ b/.claude/skills/writing-plans/SKILL.md @@ -0,0 +1,143 @@ +--- +name: writing-plans +description: 当有规格或需求的多步骤任务时使用,在接触代码之前 +--- + +# 编写实现计划 + +## 概述 + +编写全面的实现计划,假设执行者对代码库零上下文且判断力有限。记录他们需要知道的一切:每个任务要接触哪些文件、代码、测试、可能需要检查的文档、如何测试。将整个计划作为小任务交付。DRY。YAGNI。TDD。频繁提交。 + +假设执行者是技术熟练的开发者,但对我们的工具或问题领域几乎一无所知。假设他们不太擅长测试设计。 + +**开始时宣布:** "我正在使用 writing-plans skill 创建实现计划。" + +**保存计划到:** `docs/plans/YYYY-MM-DD--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--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 都要验证 | + +## 危险信号 - 停下来 + +- 任务描述超过一屏 +- 需要"理解"才能完成的任务 +- 没有明确的验证命令 +- 任务之间有隐含依赖 + +**这些都意味着:任务需要进一步拆分。** diff --git a/.vibe/session-start-prompt.txt b/.vibe/session-start-prompt.txt new file mode 100644 index 0000000..91b2657 --- /dev/null +++ b/.vibe/session-start-prompt.txt @@ -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 保存快照并标记完成 diff --git a/DESIGN.md b/DESIGN.md new file mode 100644 index 0000000..cd1f972 --- /dev/null +++ b/DESIGN.md @@ -0,0 +1,1179 @@ +# VibeEngineering V2 设计文档 + +> **目标**:在 Claude Code CLI 上实现自动化开发系统,融合 Superpowers 专家方法论 + 跨 Compact 恢复机制,实现"人工把关设计,自动执行任务"的工作流程。 +> +> **核心原则**: +> - 设计阶段需要人工确认(命令边界形成自然审查点),执行阶段全自动化 +> - 执行阶段使用子代理驱动模式(Implementer → Spec Reviewer → Quality Reviewer) +> - 使用 Claude Code 原生 Task 系统替代自定义状态管理,metadata 记录执行细节 +> - 跨 Compact 恢复:PreCompact Hook 保存上下文 → SessionStart Hook 引导恢复 +> - 校验 Task 作为最后一个 Task,对比 design.md + metadata 检查降级 + +--- + +## 一、核心设计理念 + +### 1.1 命令驱动的两阶段分离 + +``` +┌─────────────────────────────────────────────────────────────────────────┐ +│ Vibe Engineering V2 │ +├─────────────────────────────────────────────────────────────────────────┤ +│ │ +│ ┌─────────────────────────────────────────────────────────────────┐ │ +│ │ 设计阶段 │ │ +│ │ ────────────────────────── │ │ +│ │ │ │ +│ │ /vibe-brainstorming "需求" │ │ +│ │ └── 使用 brainstorming skill → 生成 design.md │ │ +│ │ │ │ +│ │ ↓ 用户审核 design.md(命令边界 = 审查点) │ │ +│ │ │ │ +│ │ /vibe-plan │ │ +│ │ └── 使用 writing-plans skill → 生成 plan.md │ │ +│ │ │ │ +│ │ 特点: │ │ +│ │ ├── 每个命令独立结束,形成自然的审查点 │ │ +│ │ └── 用户手动执行下一个命令 │ │ +│ └─────────────────────────────────────────────────────────────────┘ │ +│ │ +│ ↓ 用户审核 plan.md ↓ │ +│ ↓ 执行 /vibe-execute ↓ │ +│ │ +│ ┌─────────────────────────────────────────────────────────────────┐ │ +│ │ 执行阶段 │ │ +│ │ ────────────────────────── │ │ +│ │ │ │ +│ │ /vibe-execute │ │ +│ │ ├── 按转换规则从 plan.md 创建 Task 系统 │ │ +│ │ ├── 自动追加校验 Task │ │ +│ │ ├── 创建 session.yml │ │ +│ │ └── 协调者循环执行所有 Task │ │ +│ │ │ │ +│ │ Task 执行: │ │ +│ │ ├── 派发 Implementer 子代理(实现 + TDD + 提交 + 更新 metadata)│ │ +│ │ ├── 派发 Spec Reviewer 子代理(规格符合性审查) │ │ +│ │ └── 派发 Quality Reviewer 子代理(代码质量审查) │ │ +│ │ │ │ +│ │ 跨 Compact 恢复: │ │ +│ │ ├── PreCompact Hook:保存当前任务上下文 │ │ +│ │ └── SessionStart Hook:引导恢复执行 │ │ +│ │ │ │ +│ │ 校验阶段(最后一个 Task): │ │ +│ │ ├── 对比 design.md + Task metadata 检查降级 │ │ +│ │ ├── 运行完整测试套件 │ │ +│ │ ├── 发现问题 → 创建修复 Task → 继续执行 │ │ +│ │ └── 全部通过 → 保存快照 → 标记完成 │ │ +│ └─────────────────────────────────────────────────────────────────┘ │ +│ │ +└─────────────────────────────────────────────────────────────────────────┘ +``` + +### 1.2 V1 到 V2 的关键变化 + +| 方面 | V1 | V2 | +|------|----|----| +| **状态管理** | 自定义状态文件 `vibe-state.local.md` | Claude Code 原生 Task 系统 | +| **执行细节** | 无持久化记录 | Task metadata 持久化记录 | +| **执行控制** | Stop Hook 拦截 + 灌 Prompt | Task 系统自动持久化 | +| **Compact 恢复** | 依赖状态文件 phase 字段 | PreCompact + SessionStart Hook 组合 | +| **完成验证** | verification-before-completion skill | 校验 Task(自动追加,作为最后一个 Task) | +| **降级检测** | 无 | 校验 Task 对比 metadata 检测降级 | + +### 1.3 子代理驱动模式 + +``` +执行阶段的每个业务 Task 执行流程: + +Task N(业务任务) + │ + ├── Task tool: Implementer (general-purpose) + │ │ + │ ├── 阅读任务需求 + │ ├── 遵循 TDD(RED-GREEN-REFACTOR) + │ ├── 实现功能 + │ ├── Git commit + │ └── 更新 Task metadata(files_modified, errors_encountered, test_results, git_commit) + │ │ + │ ▼ + ├── Task tool: Spec Reviewer (general-purpose) + │ │ + │ ├── 独立阅读代码(不信任 Implementer 报告) + │ ├── 逐条验证需求是否满足 + │ ├── 检查遗漏或多余功能 + │ │ + │ ▼ 问题? → Implementer 修复 → 重新审查 + │ │ + ├── Task tool: Quality Reviewer (general-purpose) + │ │ + │ ├── 审查代码质量、架构、测试 + │ ├── 分类问题:关键/重要/次要 + │ │ + │ ▼ 问题? → Implementer 修复 → 重新审查 + │ │ + └── 主窗口:TaskUpdate status=completed + +所有业务 Task completed + │ + ▼ +校验 Task 启动(最后一个 pending Task) + │ + ├── 读取所有 Task JSON + metadata + ├── 对比 design.md 逐条校验 + ├── 运行完整测试套件 + ├── 检查 metadata 中未解决问题 + │ + ▼ 发现问题? → 创建修复 Task → 执行 → 重新校验 + │ + ▼ 全部通过 + │ + ├── 保存 Task 快照 + └── 标记校验 Task completed → Task JSON 被系统删除 +``` + +--- + +## 二、整体流程图 + +```mermaid +graph TB + subgraph init ["初始化阶段 - vibe-execute"] + A1["读取 plan.md"] --> A2["按转换规则创建业务 Task"] + A2 --> A5["自动追加校验 Task"] + A5 --> A4["创建 session.yml"] + end + + subgraph exec ["执行阶段 - 协调者循环"] + B0["获取下一个 pending Task"] --> B00{"是校验 Task?"} + + B00 -->|否| B1["派发 Implementer 子代理"] + subgraph task ["业务 Task 执行"] + B1 --> B2["Implementer: 实现/测试/提交"] + B2 --> B3["Implementer: 更新 Task metadata"] + B3 --> B4["派发 Spec Reviewer"] + B4 --> B5{"规格符合?"} + B5 -->|否| B6["Implementer: 修复规格差距"] + B6 --> B4 + B5 -->|是| B7["派发 Code Quality Reviewer"] + B7 --> B8{"质量通过?"} + B8 -->|否| B9["Implementer: 修复质量问题"] + B9 --> B7 + B8 -->|是| B10["TaskUpdate status=completed"] + end + B10 --> B0 + + B00 -->|是| B20["校验 Task 开始"] + subgraph verify ["校验 Task 执行"] + B20 --> B21["读取所有 Task JSON + metadata"] + B21 --> B22["对比 design.md 逐条校验"] + B22 --> B23["运行完整测试套件"] + B23 --> B24["检查 metadata 中未解决问题"] + B24 --> B25{"全部通过?"} + B25 -->|否| B26["创建修复 Task"] + B26 --> B0 + B25 -->|是| B27["保存 Task 快照"] + B27 --> B28["标记校验 Task completed"] + B28 --> B29["Task JSON 被删除"] + end + end + + subgraph precompact ["PreCompact 阶段"] + C1["PreCompact Hook 触发"] --> C2["读取 transcript.jsonl"] + C2 --> C3["找到最后 TaskUpdate completed"] + C3 --> C4["提取之后的内容"] + C4 --> C5["写入 last_task_context.jsonl"] + C5 --> C6["Compact 发生"] + end + + subgraph recovery ["恢复阶段 - SessionStart"] + D1["SessionStart Hook 触发"] --> D2["读取 design.md"] + D2 --> D3["读取所有 Task JSON"] + D3 --> D4["读取 last_task_context.jsonl"] + end + + A4 --> B0 + B0 -.可能触发.-> C1 + C6 --> D1 + D4 --> B0 +``` + +--- + +## 三、文件体系 + +``` +项目根目录/ +├── docs/plans/ +│ ├── {timestamp}-design.md # 需求和架构(设计阶段产出) +│ └── {timestamp}-plan.md # 实现计划(设计阶段产出) +│ +├── .vibe/ +│ ├── session.yml # 会话元信息(task_list_id, design_doc) +│ ├── last_task_context.jsonl # 当前任务执行过程(PreCompact 生成) +│ └── task-snapshot.md # Task 快照(校验通过后保存) +│ +├── .claude/ +│ ├── commands/ +│ │ ├── vibe-brainstorming.md # 设计阶段第一步:需求探索 +│ │ ├── vibe-plan.md # 设计阶段第二步:创建计划 +│ │ └── vibe-execute.md # 执行阶段:创建 Task + 协调执行 +│ ├── hooks/ +│ │ ├── session-start.sh # 恢复提示词 +│ │ ├── pre-compact.sh # 调用提取脚本 +│ │ └── extract-last-context.js # transcript → last_task_context.jsonl +│ ├── skills/ +│ │ ├── brainstorming/ # 需求探索方法论 +│ │ ├── writing-plans/ # 计划编写方法论 +│ │ ├── test-driven-development/ # TDD 方法论 +│ │ └── subagent-driven-development/ # 子代理驱动执行方法论 +│ ├── settings.local.json # Hook 配置 +│ └── CLAUDE.md # 项目级提示词(含 metadata 读取说明) +│ +└── ~/.claude/tasks/{TaskListId}/ # Claude Code 原生 Task 系统 + ├── 1.json # Task + metadata(动态) + ├── 2.json + └── ... # ⚠️ 所有任务完成后被系统删除 +``` + +### 文件职责 + +| 文件 | 内容 | 生命周期 | +|------|------|---------| +| **design.md** | 需求分析、架构设计、技术选型 | 永久 | +| **plan.md** | 任务分解、TDD 步骤 | 永久 | +| **Task JSON** | 任务信息 + metadata(执行细节) | 执行期间,完成后删除 | +| **last_task_context.jsonl** | 当前任务执行过程 | 每次 PreCompact 覆盖 | +| **task-snapshot.md** | Task JSON 快照 | 永久 | +| **session.yml** | task_list_id, design_doc | 执行期间 | + +--- + +## 四、命令设计 + +### 4.1 /vibe-brainstorming - 需求探索 + +**文件**:`.claude/commands/vibe-brainstorming.md` + +````markdown +--- +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--design.md` + +## 输出 + +完成后提示用户: +``` +设计文档已生成:docs/plans/YYYY-MM-DD--design.md + +请审核设计文档,确认后执行:/vibe-plan +``` +```` + +### 4.2 /vibe-plan - 创建实现计划 + +**文件**:`.claude/commands/vibe-plan.md` + +````markdown +--- +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--plan.md` + +## 输出 + +完成后提示用户: +``` +实现计划已生成:docs/plans/YYYY-MM-DD--plan.md + +请审核实现计划,确认后执行:/vibe-execute +``` +```` + +### 4.3 /vibe-execute - 执行阶段 + +**文件**:`.claude/commands/vibe-execute.md` + +这是最关键的命令,包含完整的转换规则和执行逻辑。 + +````markdown +--- +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 执行 + +调用 test-driven-development skill,然后派发子代理: + +**派发 Implementer 子代理**(使用第五章提示词模板): +- 实现功能 +- 遵循 TDD +- 提交代码 +- **更新 Task metadata**(关键!) + +**派发 Spec Reviewer 子代理**(使用第六章提示词模板): +- 规格符合性审查 +- 问题 → Implementer 修复 → 重新审查 + +**派发 Code Quality Reviewer 子代理**(使用第七章提示词模板): +- 代码质量审查 +- 问题 → Implementer 修复 → 重新审查 + +**标记完成**: +``` +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" | 部分实现 | +```` + +--- + +## 五、Implementer 子代理提示词 + +派发 Implementer 子代理时使用此模板: + +````markdown +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:先写测试,再实现 + - 每个有意义的变更都要提交 + - 自审:完成后检查自己的实现是否完整 + - 如实记录:不要隐瞒错误或跳过的内容 +```` + +### metadata 完整示例 + +```json +{ + "id": "5", + "subject": "迁移ES配置", + "status": "completed", + "metadata": { + "plan_task_id": "2.3", + "started_at": "2026-01-26 14:00", + "completed_at": "2026-01-26 14:30", + "files_modified": [ + "src/elasticsearch/config.py", + "src/elasticsearch/client.py" + ], + "git_commit": "abc123f", + "commit_message": "refactor(es): migrate to unified config", + "errors_encountered": [ + "Pydantic版本冲突 - 已通过升级到2.0解决" + ], + "test_results": "5/5 passed" + } +} +``` + +--- + +## 六、Spec Reviewer 子代理提示词 + +规格符合性审查通过后才派发 Code Quality Reviewer。 + +````markdown +Task tool (general-purpose): + description: "审查 Task N 的规格符合性" + prompt: | + 你正在审查一个实现是否符合其规格。 + + ## 被请求的内容 + + {Task JSON 的完整 description 内容} + + ## 实现者声称构建的内容 + + {Implementer 子代理的返回报告} + + ## 关键:不要信任报告 + + 实现者的报告可能不完整、不准确或过于乐观。你必须独立验证。 + + **要:** + - 阅读实际代码 + - 逐行比较实现和需求 + - 检查声称实现但实际没有的部分 + - 寻找没提到的额外功能 + + **不要:** + - 相信实现者的说法 + - 信任完整性声明 + - 接受对需求的重新解释 + + ## 检查项 + + **遗漏的需求:** + - 所有被请求的内容都实现了吗? + - 有跳过或遗漏的需求吗? + + **多余的工作:** + - 构建了没有被请求的东西吗? + - 过度设计或添加了不必要的功能吗? + + **误解:** + - 对需求的解释与预期不同吗? + - 解决了错误的问题吗? + + ## 输出格式 + + - ✅ 符合规格(如果代码检查后一切匹配) + - ❌ 发现问题:[具体列出遗漏或多余的内容,带 file:line 引用] +```` + +--- + +## 七、Code Quality Reviewer 子代理提示词 + +只在规格符合性审查通过后派发。 + +````markdown +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 句话] +```` + +--- + +## 八、跨 Compact 恢复机制 + +### 8.1 核心机制 + +``` +恢复上下文 = design.md(架构) + + Task JSON + metadata(任务与执行细节) + + last_task_context.jsonl(当前任务上下文) +``` + +### 8.2 PreCompact Hook + +当上下文即将满时,PreCompact Hook 自动触发,从 transcript.jsonl 提取当前任务上下文。 + +**Shell 入口**:`.claude/hooks/pre-compact.sh` + +```bash +#!/usr/bin/env bash + +INPUT=$(cat) +TRANSCRIPT_PATH=$(echo "$INPUT" | jq -r '.transcript_path') + +# 等待 transcript.jsonl 完全写入 +sleep 1 + +node .claude/hooks/extract-last-context.js "$TRANSCRIPT_PATH" > .vibe/last_task_context.jsonl +``` + +**提取脚本**:`.claude/hooks/extract-last-context.js` + +```javascript +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)); +} +``` + +**提取精简规则**: + +| 类型 | 保留内容 | +|------|---------| +| Claude 输出 | ✅ 全部 content | +| 用户输入 | ✅ 全部 content | +| Task tool(派发) | ✅ prompt, subagent_type, description | +| Task tool(返回) | ✅ content, agentId | +| Read / Edit / Write | file_path | +| Bash | command, exit_code | +| Glob / Grep | pattern, path | +| TaskUpdate | taskId, status | + +### 8.3 SessionStart Hook + +Compact 后会话恢复时,SessionStart Hook 自动触发,引导 Claude 恢复执行上下文。 + +**文件**:`.claude/hooks/session-start.sh` + +````bash +#!/usr/bin/env bash + +# 只有存在 last_task_context.jsonl 才触发恢复提示 +# 说明之前发生过 PreCompact,需要恢复上下文 +if [[ ! -f ".vibe/last_task_context.jsonl" ]]; then + exit 0 +fi + +if [[ ! -f ".vibe/session.yml" ]]; then + exit 0 +fi + +# 使用 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 +```` + +--- + +## 九、项目级 CLAUDE.md + +在项目根目录的 `.claude/CLAUDE.md` 中添加以下内容,让 Claude 了解 metadata 的用途: + +````markdown +## 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,无需全部加载到上下文。 +```` + +--- + +## 十、Hook 配置 + +**文件**:`.claude/settings.local.json` + +```json +{ + "hooks": { + "SessionStart": [ + { + "matcher": "", + "hooks": [ + { + "type": "command", + "command": "bash .claude/hooks/session-start.sh" + } + ] + } + ], + "PreCompact": [ + { + "matcher": "", + "hooks": [ + { + "type": "command", + "command": "bash .claude/hooks/pre-compact.sh" + } + ] + } + ] + } +} +``` + +--- + +## 十一、session.yml 格式 + +```yaml +# .vibe/session.yml +task_list_id: "386113df-47f7-4e1d-9db2-d572e3081bf9" +design_doc: "docs/plans/20260126-design.md" +plan_doc: "docs/plans/20260126-plan.md" +created_at: "2026-01-26 10:00" +``` + +--- + +## 十二、Task 快照格式 + +**文件**:`.vibe/task-snapshot.md` + +```markdown +# Task 快照 - 2026-01-26 18:00 + +**Task List ID**: 386113df-47f7-4e1d-9db2-d572e3081bf9 +**总任务数**: 22 +**完成任务数**: 22 + +--- + +### Task 1: 代码备份与分支创建 [completed] + +**描述**: 创建重构分支,确保代码安全 + +**元数据**: +- 完成时间:2026-01-26 10:00 +- Git commit:abc123f +- 修改文件:无 +- 测试结果:无 + +--- + +### Task 2: 创建配置模块基础结构 [completed] + +**描述**: 使用Pydantic创建统一配置管理模块 + +**元数据**: +- 完成时间:2026-01-26 11:00 +- Git commit:def456g +- 修改文件:src/config/settings.py, src/config/__init__.py +- 测试结果:5/5 passed +- 错误:Pydantic版本冲突(已通过升级解决) + +--- + +...(所有 Task) +``` + +--- + +## 十三、完整执行示例 + +```bash +# ========== 设计阶段 ========== +> /vibe-brainstorming "实现代码质量改进" +# → 使用 brainstorming skill +# → 生成 docs/plans/20260126-design.md +# → Claude 停止,用户审核 + +# 用户审核 design.md + +> /vibe-plan +# → 使用 writing-plans skill +# → 生成 docs/plans/20260126-plan.md +# → Claude 停止,用户审核 + +# 用户审核 plan.md + +# ========== 初始化阶段 ========== +> /vibe-execute + +# vibe-execute 执行 Phase 1: +# 1. 读取 plan.md +# 2. 按转换规则为每个 Task 调用 TaskCreate +# 3. 自动追加:TaskCreate("[校验] 全局需求验证", ...) +# 4. 创建 .vibe/session.yml + +# ========== 执行循环 ========== +# 协调者获取 Task 1(pending) + +# → 派发 Implementer 子代理 +# - Implementer 实现功能 +# - Implementer 更新 metadata: +# TaskUpdate taskId=1 metadata={ +# "files_modified": ["src/backup.sh"], +# "git_commit": "abc123", +# "test_results": "N/A" +# } + +# → 派发 Spec Reviewer 子代理 +# - ✅ 符合规格 + +# → 派发 Code Quality Reviewer 子代理 +# - ✅ 通过 + +# → 主窗口:TaskUpdate taskId=1 status=completed + +# 继续 Task 2, 3, ... N + +# ========== PreCompact 触发(如果发生)========== +# 上下文满 → PreCompact Hook 触发 +# → 提取 transcript.jsonl 中最后 TaskUpdate completed 之后的内容 +# → 写入 .vibe/last_task_context.jsonl +# → Compact 发生 + +# ========== Compact 后恢复 ========== +# SessionStart Hook 触发 +# → Claude 按顺序读取:design.md → Task JSON → last_task_context.jsonl +# → 找到 in_progress 或下一个 pending Task +# → 继续执行循环 + +# ========== 校验阶段 ========== +# 所有业务 Task completed → 校验 Task 是下一个 pending +# 协调者获取校验 Task + +# → 校验 Task 执行固定流程: +# Step 1: 读取所有 Task JSON + metadata +# - Task 3 metadata: errors_encountered 包含"Pydantic版本冲突 - 已升级" → ✅ 已解决 +# - Task 15 metadata: errors_encountered 包含"暂时跳过第三种检索模式" → ❌ 降级! + +# Step 2: 对比 design.md +# - design.md 要求"支持3种检索模式" +# - Task 15 只实现了2种 → ❌ 需求未满足 + +# Step 3: 运行完整测试套件 +# pytest → 45/45 passed → ✅ + +# Step 4: 发现降级问题 +# → 创建修复 Task: "实现第三种检索模式" +# → Implementer 执行修复 +# → 重新校验 → ✅ 全部通过 + +# Step 5: 校验通过 +# → 保存 Task 快照(此时所有 JSON 仍存在) +# → 标记校验 Task completed → Task JSON 被系统删除 +# → task-snapshot.md 作为永久历史记录保留 +``` + +--- + +## 十四、实现清单 + +| 优先级 | 文件 | 说明 | +|--------|------|------| +| P0 | `.claude/commands/vibe-execute.md` | 第四章的完整命令(含转换规则 + 校验 Task) | +| P0 | `.claude/hooks/session-start.sh` | 第八章的恢复提示词 | +| P0 | `.claude/hooks/pre-compact.sh` | 第八章的 shell 入口 | +| P0 | `.claude/hooks/extract-last-context.js` | 第八章的提取脚本 | +| P0 | `.claude/settings.local.json` | 第十章的 Hook 配置 | +| P1 | `.claude/commands/vibe-brainstorming.md` | 第四章的命令 | +| P1 | `.claude/commands/vibe-plan.md` | 第四章的命令 | +| P1 | `.claude/CLAUDE.md` | 第九章的项目级提示词 | +| P2 | `.claude/skills/brainstorming/SKILL.md` | 继承 V1 | +| P2 | `.claude/skills/writing-plans/SKILL.md` | 继承 V1 | +| P2 | `.claude/skills/test-driven-development/SKILL.md` | 继承 V1 | +| P2 | `.claude/skills/subagent-driven-development/SKILL.md` | 子代理驱动执行 | + +--- + +## 十五、与 V1 的对比总结 + +| 方面 | V1 | V2 | +|------|----|----| +| **状态管理** | 自定义 `vibe-state.local.md` | Claude Code 原生 Task 系统 | +| **执行细节记录** | 无 | Task metadata 持久化 | +| **执行控制** | Stop Hook 拦截 + 灌 Prompt | Task 系统自动持久化 | +| **Compact 恢复** | 依赖 phase 字段 | PreCompact + SessionStart Hook | +| **完成验证** | verification-before-completion skill | 校验 Task(自动追加,作为最后一个 Task) | +| **降级检测** | 无 | 校验 Task 对比 design.md + metadata | +| **快照机制** | 无 | 校验通过后保存 task-snapshot.md | +| **Ralph Wiggum** | 使用 | 移除(Task 系统替代) | + +**核心改进**: +1. **利用原生 Task 系统**:不再维护自定义状态文件,直接使用 Claude Code 的 Task JSON +2. **metadata 记录执行细节**:每个 Task 的执行过程持久化,支持恢复和校验 +3. **自动追加校验 Task**:不再依赖 skill 提示,而是作为实际 Task 执行 +4. **降级检测**:通过 metadata 中的关键字检测"暂时跳过"、"简化实现"等降级行为 +5. **跨 Compact 完整恢复**:PreCompact 保存上下文,SessionStart 引导恢复 diff --git a/README.md b/README.md new file mode 100644 index 0000000..397974a --- /dev/null +++ b/README.md @@ -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)