Auto backup before evolver run - 2026年 03月 10日 星期二 19:00:50 CST
This commit is contained in:
@@ -0,0 +1,198 @@
|
||||
# dev-workflow 集成测试指南
|
||||
|
||||
## 测试场景
|
||||
|
||||
### 场景1: 开发简单CLI工具(通用项目)
|
||||
|
||||
**目标**: 使用 dev-workflow 开发一个简单的待办事项CLI工具
|
||||
|
||||
**测试步骤**:
|
||||
|
||||
```bash
|
||||
# 1. 初始化工作流
|
||||
cd ~/work/kb-skills/dev-workflow
|
||||
python3 orchestrator.py --init "开始开发一个简单的待办事项CLI工具,支持添加、列出、完成任务" --project-name "todo-cli"
|
||||
|
||||
# 2. 模拟头脑风暴(Phase 1)
|
||||
# 主Agent应进入问答循环,收集需求
|
||||
|
||||
# 3. 方案设计(Phase 2)
|
||||
# 应启动3个子代理设计方案
|
||||
|
||||
# 4-9. 后续阶段
|
||||
# 按流程完成各阶段
|
||||
```
|
||||
|
||||
**验收标准**:
|
||||
- [ ] 生成可运行的 todo.py
|
||||
- [ ] 支持 add/list/done 命令
|
||||
- [ ] 有单元测试
|
||||
- [ ] 代码通过审查
|
||||
|
||||
---
|
||||
|
||||
### 场景2: 开发新kb-skill(技能项目)
|
||||
|
||||
**目标**: 使用 dev-workflow 开发一个简单的 kb-hello 技能
|
||||
|
||||
**测试步骤**:
|
||||
|
||||
```bash
|
||||
# 1. 初始化工作流
|
||||
cd ~/work/kb-skills
|
||||
python3 dev-workflow/orchestrator.py --init "开始开发一个新的kb-skill,名称为kb-hello,功能是向用户问好" --project-name "kb-hello"
|
||||
|
||||
# 2-9. 按流程完成
|
||||
```
|
||||
|
||||
**验收标准**:
|
||||
- [ ] 创建 kb-hello/SKILL.md
|
||||
- [ ] SKILL.md 符合规范
|
||||
- [ ] 有示例使用说明
|
||||
- [ ] 文档完整
|
||||
|
||||
---
|
||||
|
||||
## 快速验证脚本
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# quick_test.sh - 快速验证dev-workflow基本功能
|
||||
|
||||
set -e
|
||||
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo " DEV-WORKFLOW 快速验证"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
|
||||
# 1. 检查文件结构
|
||||
echo ""
|
||||
echo "1. 检查文件结构..."
|
||||
required_files=(
|
||||
"SKILL.md"
|
||||
"state_manager.py"
|
||||
"orchestrator.py"
|
||||
"prompts/brainstorming.md"
|
||||
"prompts/solution-design.md"
|
||||
"prompts/solution-review.md"
|
||||
"prompts/solution-report.md"
|
||||
"prompts/spec-planning.md"
|
||||
"prompts/parallel-development.md"
|
||||
"prompts/testing.md"
|
||||
"prompts/code-review.md"
|
||||
"prompts/fix-verification.md"
|
||||
)
|
||||
|
||||
all_found=true
|
||||
for file in "${required_files[@]}"; do
|
||||
if [ -f "$file" ]; then
|
||||
echo " ✓ $file"
|
||||
else
|
||||
echo " ✗ $file (缺失)"
|
||||
all_found=false
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$all_found" = false ]; then
|
||||
echo "❌ 文件检查失败"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 2. 运行单元测试
|
||||
echo ""
|
||||
echo "2. 运行单元测试..."
|
||||
python3 test_dev_workflow.py
|
||||
|
||||
# 3. 测试状态管理
|
||||
echo ""
|
||||
echo "3. 测试状态管理..."
|
||||
python3 -c "
|
||||
from state_manager import init_state, load_state, set_phase, complete_phase
|
||||
|
||||
# 初始化
|
||||
state = init_state('测试项目', '测试消息')
|
||||
print(f' ✓ 初始化状态: Phase {state[\"current_phase\"]}')
|
||||
|
||||
# 设置阶段
|
||||
set_phase(3)
|
||||
state = load_state()
|
||||
print(f' ✓ 设置阶段: Phase {state[\"current_phase\"]}')
|
||||
|
||||
# 完成阶段
|
||||
complete_phase(3)
|
||||
state = load_state()
|
||||
print(f' ✓ 完成阶段: Phase 3, 当前 Phase {state[\"current_phase\"]}')
|
||||
"
|
||||
|
||||
# 4. 测试编排器
|
||||
echo ""
|
||||
echo "4. 测试编排器..."
|
||||
python3 -c "
|
||||
from orchestrator import DevWorkflowOrchestrator
|
||||
import tempfile
|
||||
import os
|
||||
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
os.chdir(tmpdir)
|
||||
|
||||
orch = DevWorkflowOrchestrator()
|
||||
orch.initialize('测试消息', '测试项目')
|
||||
print(' ✓ 编排器初始化成功')
|
||||
|
||||
# 检查阶段方法
|
||||
for i in range(1, 10):
|
||||
method = f'run_phase_{i}'
|
||||
if hasattr(orch, method):
|
||||
print(f' ✓ {method} 存在')
|
||||
else:
|
||||
print(f' ✗ {method} 缺失')
|
||||
"
|
||||
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo " ✅ 快速验证通过"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 手动测试清单
|
||||
|
||||
### 基础功能
|
||||
|
||||
- [ ] SKILL.md 触发词正确定义
|
||||
- [ ] 状态文件正确初始化
|
||||
- [ ] 阶段转换正确工作
|
||||
- [ ] 重试逻辑正确(最多3次)
|
||||
- [ ] 状态恢复正确工作
|
||||
|
||||
### Prompt模板
|
||||
|
||||
- [ ] 头脑风暴prompt包含问答策略
|
||||
- [ ] 方案设计prompt包含3种类型
|
||||
- [ ] 方案审核prompt包含交叉审核逻辑
|
||||
- [ ] Spec编排prompt包含依赖分析
|
||||
- [ ] 代码审查prompt包含完整维度
|
||||
|
||||
### 子代理集成
|
||||
|
||||
- [ ] 可以启动子代理(sessions_spawn)
|
||||
- [ ] 子代理结果正确收集
|
||||
- [ ] 并行执行正确工作
|
||||
- [ ] 失败重试正确触发
|
||||
|
||||
---
|
||||
|
||||
## 已知限制
|
||||
|
||||
1. **子代理集成**: 当前代码提供了子代理启动框架,但实际需要与 OpenClaw sessions_spawn 集成
|
||||
2. **实际执行**: 完整的9阶段流程需要实际运行环境
|
||||
3. **测试覆盖**: 单元测试覆盖了核心逻辑,端到端测试需要手动执行
|
||||
|
||||
---
|
||||
|
||||
## 下一步
|
||||
|
||||
1. **实际测试**: 在真实项目中使用 dev-workflow
|
||||
2. **优化prompt**: 根据实际效果调整各阶段prompt
|
||||
3. **收集反馈**: 记录使用中的问题和改进点
|
||||
@@ -0,0 +1,205 @@
|
||||
---
|
||||
name: dev-workflow
|
||||
description: "开始开发..." 时使用 - 多代理协作开发编排技能,解决单Agent开发的对话卡住和开发不完整问题
|
||||
---
|
||||
|
||||
# dev-workflow - 多代理协作开发编排
|
||||
|
||||
## 什么时候使用
|
||||
|
||||
当用户发送包含以下模式的消息时,此技能自动触发:
|
||||
|
||||
| 触发词 | 行为 | 示例 |
|
||||
|--------|------|------|
|
||||
| `开始开发` + 描述 | 启动完整开发流程 | "开始开发一个用户登录功能" |
|
||||
| `开始开发` + 项目类型 | 启动项目开发 | "开始开发一个新的 kb-skill" |
|
||||
|
||||
## 核心价值
|
||||
|
||||
通过多代理协作和分阶段编排,解决单Agent开发的两大痛点:
|
||||
|
||||
1. **对话卡住** — 长时间开发填满上下文窗口,质量下降
|
||||
2. **开发不完整** — 缺乏系统性流程,遗漏边界情况或测试
|
||||
|
||||
## 9阶段流程
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ DEV-WORKFLOW PIPELINE │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ 阶段1: 头脑风暴 │
|
||||
│ ┌─────────────────────────────────────────────────────────┐ │
|
||||
│ │ 主Agent 通过问答澄清需求,直到足够进行完整开发 │ │
|
||||
│ └─────────────────────────────────────────────────────────┘ │
|
||||
│ ↓ │
|
||||
│ 阶段2: 方案设计 (3个子代理并行) │
|
||||
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
|
||||
│ │ Agent A │ │ Agent B │ │ Agent C │ │
|
||||
│ │ 方案1 │ │ 方案2 │ │ 方案3 │ │
|
||||
│ └─────────┘ └─────────┘ └─────────┘ │
|
||||
│ ↓ │
|
||||
│ 阶段3: 方案审核 (交叉审核) │
|
||||
│ ┌─────────────────────────────────────────────────────────┐ │
|
||||
│ │ A审BC → B审AC → C审AB → 汇总 → 综合方案 │ │
|
||||
│ └─────────────────────────────────────────────────────────┘ │
|
||||
│ ↓ │
|
||||
│ 阶段4: 方案汇报 │
|
||||
│ ┌─────────────────────────────────────────────────────────┐ │
|
||||
│ │ 主Agent 汇报综合方案 → 用户决策 (批准/修改/重新设计) │ │
|
||||
│ └─────────────────────────────────────────────────────────┘ │
|
||||
│ ↓ │
|
||||
│ 阶段5: Spec编排 │
|
||||
│ ┌─────────────────────────────────────────────────────────┐ │
|
||||
│ │ 生成开发规格 → 分析任务依赖 → 分波执行计划 │ │
|
||||
│ └─────────────────────────────────────────────────────────┘ │
|
||||
│ ↓ │
|
||||
│ 阶段6: 并行开发 (按波次执行) │
|
||||
│ ┌─────────────────────────────────────────────────────────┐ │
|
||||
│ │ Wave 1: [Task1, Task2] 并行 → Wave 2: [Task3] → ... │ │
|
||||
│ └─────────────────────────────────────────────────────────┘ │
|
||||
│ ↓ │
|
||||
│ 阶段7: 测试 │
|
||||
│ ┌─────────────────────────────────────────────────────────┐ │
|
||||
│ │ 运行现有测试 + 运行生成测试 → 通过/失败(重试) │ │
|
||||
│ └─────────────────────────────────────────────────────────┘ │
|
||||
│ ↓ │
|
||||
│ 阶段8: 代码审查 (3个子代理并行) │
|
||||
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
|
||||
│ │ Agent X │ │ Agent Y │ │ Agent Z │ │
|
||||
│ │ 完整审查│ │ 完整审查│ │ 完整审查│ │
|
||||
│ └─────────┘ └─────────┘ └─────────┘ │
|
||||
│ ↓ │
|
||||
│ 阶段9: 修复验证 │
|
||||
│ ┌─────────────────────────────────────────────────────────┐ │
|
||||
│ │ 汇总问题 → 安排修复 → 验证子代理确认 → 汇报完成 │ │
|
||||
│ └─────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## 状态持久化
|
||||
|
||||
每个阶段完成后保存状态到 `.planning/dev-workflow/state.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"current_phase": 3,
|
||||
"current_stage": "方案设计",
|
||||
"started_at": "2026-03-09T18:00:00+08:00",
|
||||
"updated_at": "2026-03-09T19:30:00+08:00",
|
||||
"retry_count": 0,
|
||||
"phases": {
|
||||
"1": { "status": "completed", "data": {...} },
|
||||
"2": { "status": "completed", "data": {...} },
|
||||
"3": { "status": "in_progress", "agents": [...] }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
支持从任意阶段恢复继续。
|
||||
|
||||
## 失败处理
|
||||
|
||||
| 场景 | 处理方式 |
|
||||
|------|----------|
|
||||
| 子代理失败 | 自动重试,最多3次 |
|
||||
| 测试失败 | 自动重试,最多3次 |
|
||||
| 审查发现问题 | 汇总后安排修复 |
|
||||
| 超过3次重试 | 汇报用户等待决策 |
|
||||
|
||||
## 子代理配置
|
||||
|
||||
| 阶段 | 子代理数量 | 职责 |
|
||||
|------|-----------|------|
|
||||
| 方案设计 | 3 | 自由探索不同方案 |
|
||||
| 方案审核 | 3 | 交叉审核其他方案 |
|
||||
| 并行开发 | N (按任务数) | 执行开发任务 |
|
||||
| 代码审查 | 3 | 独立完整审查 |
|
||||
| 修复 | N (按问题数) | 修复发现的问题 |
|
||||
| 验证 | 1 | 确认修复完成 |
|
||||
|
||||
## 汇报机制
|
||||
|
||||
每个阶段完成后向用户汇报:
|
||||
|
||||
```
|
||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
DEV-WORKFLOW ► 阶段 X 完成
|
||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
|
||||
**阶段名称**: [阶段名称]
|
||||
**状态**: ✓ 完成 / ⚠ 需要关注
|
||||
**耗时**: [X分钟]
|
||||
|
||||
**成果摘要**:
|
||||
- [成果1]
|
||||
- [成果2]
|
||||
|
||||
**下一阶段**: [阶段名称]
|
||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
```
|
||||
|
||||
## 目录结构
|
||||
|
||||
```
|
||||
.planning/dev-workflow/
|
||||
├── state.json # 当前状态
|
||||
├── requirements.json # 收集的需求
|
||||
├── solutions/ # 方案设计
|
||||
│ ├── solution-A.md
|
||||
│ ├── solution-B.md
|
||||
│ └── solution-C.md
|
||||
├── reviews/ # 方案审核
|
||||
│ ├── review-A.md
|
||||
│ ├── review-B.md
|
||||
│ └── review-C.md
|
||||
├── final-solution.md # 综合方案
|
||||
├── spec.md # 开发规格
|
||||
├── execution-plan.md # 执行计划
|
||||
├── development/ # 开发过程
|
||||
│ └── wave-1/
|
||||
│ ├── task-1.json
|
||||
│ └── task-2.json
|
||||
├── test-results.json # 测试结果
|
||||
├── code-review/ # 代码审查
|
||||
│ ├── review-X.md
|
||||
│ ├── review-Y.md
|
||||
│ └── review-Z.md
|
||||
└── final-report.md # 最终汇报
|
||||
```
|
||||
|
||||
## 适用项目类型
|
||||
|
||||
| 类型 | 支持情况 | 说明 |
|
||||
|------|----------|------|
|
||||
| 通用软件项目 | ✓ 完全支持 | Python/JS/Go 等任意语言 |
|
||||
| kb-skills 技能 | ✓ 完全支持 | Python + SKILL.md 规范 |
|
||||
| Web应用 | ✓ 完全支持 | 前后端分离项目 |
|
||||
| CLI工具 | ✓ 完全支持 | 命令行工具 |
|
||||
|
||||
## 执行流程
|
||||
|
||||
主Agent检测到触发词后:
|
||||
|
||||
1. **初始化状态文件** — 创建 `.planning/dev-workflow/` 目录和 `state.json`
|
||||
2. **进入阶段1** — 开始头脑风暴问答循环
|
||||
3. **按流程执行** — 依次完成9个阶段
|
||||
4. **每阶段汇报** — 完成后向用户汇报进度
|
||||
5. **最终汇报** — 所有阶段完成后生成完整报告
|
||||
|
||||
## 恢复机制
|
||||
|
||||
如果会话中断:
|
||||
|
||||
1. 主Agent读取 `state.json` 获取当前状态
|
||||
2. 根据状态恢复到对应阶段
|
||||
3. 继续执行未完成的阶段
|
||||
4. 保持所有已完成的成果
|
||||
|
||||
## 注意事项
|
||||
|
||||
- **主Agent不参与实际开发** — 保持编排者角色,避免上下文膨胀
|
||||
- **方案必须用户确认** — 阶段4汇报后等待用户决策
|
||||
- **测试必须通过** — 阶段7测试失败需修复后才能继续
|
||||
- **审查问题必须处理** — 阶段9汇总所有问题并修复
|
||||
@@ -0,0 +1,305 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
dev-workflow 主编排器
|
||||
|
||||
负责协调整个9阶段开发流程。
|
||||
|
||||
Usage:
|
||||
python3 orchestrator.py --init "开始开发一个用户登录功能"
|
||||
python3 orchestrator.py --resume
|
||||
python3 orchestrator.py --status
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import subprocess
|
||||
import sys
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
from typing import Any, Optional
|
||||
|
||||
# 添加 prompts 目录到路径
|
||||
sys.path.insert(0, str(Path(__file__).parent))
|
||||
|
||||
from state_manager import (
|
||||
load_state,
|
||||
save_state,
|
||||
init_state,
|
||||
get_status,
|
||||
set_phase,
|
||||
complete_phase,
|
||||
update_phase_data,
|
||||
increment_retry,
|
||||
reset_retry
|
||||
)
|
||||
|
||||
|
||||
class DevWorkflowOrchestrator:
|
||||
"""dev-workflow 主编排器"""
|
||||
|
||||
def __init__(self, project_root: Path = None):
|
||||
self.project_root = project_root or Path.cwd()
|
||||
self.planning_dir = self.project_root / ".planning" / "dev-workflow"
|
||||
self.state = None
|
||||
|
||||
def initialize(self, trigger_message: str, project_name: str = None):
|
||||
"""初始化工作流"""
|
||||
print("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
|
||||
print(" DEV-WORKFLOW ► 初始化")
|
||||
print("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
|
||||
|
||||
# 创建目录结构
|
||||
self.planning_dir.mkdir(parents=True, exist_ok=True)
|
||||
(self.planning_dir / "solutions").mkdir(exist_ok=True)
|
||||
(self.planning_dir / "reviews").mkdir(exist_ok=True)
|
||||
(self.planning_dir / "development").mkdir(exist_ok=True)
|
||||
(self.planning_dir / "code-review").mkdir(exist_ok=True)
|
||||
|
||||
# 初始化状态
|
||||
self.state = init_state(project_name, trigger_message)
|
||||
|
||||
print(f"✅ 工作流已初始化")
|
||||
print(f" 触发消息: {trigger_message}")
|
||||
print(f" 工作目录: {self.planning_dir}")
|
||||
|
||||
return self.state
|
||||
|
||||
def load_state(self) -> dict:
|
||||
"""加载当前状态"""
|
||||
self.state = load_state()
|
||||
return self.state
|
||||
|
||||
def run_phase_1(self):
|
||||
"""阶段1: 头脑风暴"""
|
||||
print("\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
|
||||
print(" DEV-WORKFLOW ► Phase 1: 头脑风暴")
|
||||
print("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
|
||||
|
||||
set_phase(1)
|
||||
|
||||
print("\n开始需求收集问答...")
|
||||
print("提示: 您可以随时说'够了'结束问答\n")
|
||||
|
||||
# 这里应该启动交互式问答
|
||||
# 由于这是编排器,实际问答由主Agent执行
|
||||
# 这里只记录状态
|
||||
|
||||
questions = [
|
||||
"请描述您想要开发什么?",
|
||||
"这个项目解决什么问题?",
|
||||
"核心功能有哪些?",
|
||||
"技术栈偏好?",
|
||||
"有什么约束条件?"
|
||||
]
|
||||
|
||||
requirements = {
|
||||
"questions_asked": questions,
|
||||
"collected": False
|
||||
}
|
||||
|
||||
update_phase_data(1, requirements)
|
||||
|
||||
print("\n等待主Agent完成问答...")
|
||||
|
||||
return {"phase": 1, "status": "waiting_for_input"}
|
||||
|
||||
def run_phase_2(self, requirements_summary: str):
|
||||
"""阶段2: 方案设计"""
|
||||
print("\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
|
||||
print(" DEV-WORKFLOW ► Phase 2: 方案设计")
|
||||
print("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
|
||||
|
||||
set_phase(2)
|
||||
|
||||
print("\n◆ 启动3个方案设计子代理...")
|
||||
|
||||
agents = [
|
||||
{"id": "A", "type": "general", "focus": "完整通用方案"},
|
||||
{"id": "B", "type": "practical", "focus": "实用快速方案"},
|
||||
{"id": "C", "type": "creative", "focus": "创新探索方案"}
|
||||
]
|
||||
|
||||
# 这里应该实际启动子代理
|
||||
# 由于编排器只负责协调,实际子代理由主Agent启动
|
||||
|
||||
results = {
|
||||
"agents": agents,
|
||||
"output_files": [
|
||||
"solutions/solution-A.md",
|
||||
"solutions/solution-B.md",
|
||||
"solutions/solution-C.md"
|
||||
],
|
||||
"status": "waiting_for_agents"
|
||||
}
|
||||
|
||||
update_phase_data(2, results)
|
||||
|
||||
print(" → Agent A: 通用型方案")
|
||||
print(" → Agent B: 实用型方案")
|
||||
print(" → Agent C: 创新型方案")
|
||||
|
||||
return {"phase": 2, "status": "waiting_for_agents", "agents": agents}
|
||||
|
||||
def run_phase_3(self):
|
||||
"""阶段3: 方案审核"""
|
||||
print("\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
|
||||
print(" DEV-WORKFLOW ► Phase 3: 方案审核")
|
||||
print("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
|
||||
|
||||
set_phase(3)
|
||||
|
||||
print("\n◆ 启动交叉审核...")
|
||||
print(" → Agent A 审核 B, C 的方案")
|
||||
print(" → Agent B 审核 A, C 的方案")
|
||||
print(" → Agent C 审核 A, B 的方案")
|
||||
|
||||
results = {
|
||||
"review_files": [
|
||||
"reviews/review-A.md",
|
||||
"reviews/review-B.md",
|
||||
"reviews/review-C.md"
|
||||
],
|
||||
"final_solution": "final-solution.md",
|
||||
"status": "waiting_for_agents"
|
||||
}
|
||||
|
||||
update_phase_data(3, results)
|
||||
|
||||
return {"phase": 3, "status": "waiting_for_agents"}
|
||||
|
||||
def run_phase_4(self):
|
||||
"""阶段4: 方案汇报"""
|
||||
print("\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
|
||||
print(" DEV-WORKFLOW ► Phase 4: 方案汇报")
|
||||
print("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
|
||||
|
||||
set_phase(4)
|
||||
|
||||
print("\n等待用户决策...")
|
||||
print(" A. 批准方案 - 进入开发阶段")
|
||||
print(" B. 需要修改 - 调整方案")
|
||||
print(" C. 重新设计 - 重新方案")
|
||||
|
||||
return {"phase": 4, "status": "waiting_for_user_decision"}
|
||||
|
||||
def run_phase_5(self):
|
||||
"""阶段5: Spec编排"""
|
||||
print("\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
|
||||
print(" DEV-WORKFLOW ► Phase 5: Spec编排")
|
||||
print("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
|
||||
|
||||
set_phase(5)
|
||||
|
||||
print("\n◆ 生成开发规格...")
|
||||
print("◆ 分析任务依赖...")
|
||||
print("◆ 生成分波计划...")
|
||||
|
||||
return {"phase": 5, "status": "processing"}
|
||||
|
||||
def run_phase_6(self):
|
||||
"""阶段6: 并行开发"""
|
||||
print("\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
|
||||
print(" DEV-WORKFLOW ► Phase 6: 并行开发")
|
||||
print("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
|
||||
|
||||
set_phase(6)
|
||||
|
||||
print("\n◆ 按波次启动开发子代理...")
|
||||
|
||||
return {"phase": 6, "status": "waiting_for_agents"}
|
||||
|
||||
def run_phase_7(self):
|
||||
"""阶段7: 测试"""
|
||||
print("\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
|
||||
print(" DEV-WORKFLOW ► Phase 7: 测试")
|
||||
print("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
|
||||
|
||||
set_phase(7)
|
||||
|
||||
print("\n◆ 运行测试...")
|
||||
|
||||
return {"phase": 7, "status": "running_tests"}
|
||||
|
||||
def run_phase_8(self):
|
||||
"""阶段8: 代码审查"""
|
||||
print("\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
|
||||
print(" DEV-WORKFLOW ► Phase 8: 代码审查")
|
||||
print("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
|
||||
|
||||
set_phase(8)
|
||||
|
||||
print("\n◆ 启动3个代码审查子代理...")
|
||||
|
||||
return {"phase": 8, "status": "waiting_for_agents"}
|
||||
|
||||
def run_phase_9(self):
|
||||
"""阶段9: 修复验证"""
|
||||
print("\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
|
||||
print(" DEV-WORKFLOW ► Phase 9: 修复验证")
|
||||
print("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
|
||||
|
||||
set_phase(9)
|
||||
|
||||
print("\n◆ 汇总问题...")
|
||||
print("◆ 安排修复...")
|
||||
print("◆ 验证完成...")
|
||||
|
||||
return {"phase": 9, "status": "processing"}
|
||||
|
||||
def get_status(self) -> str:
|
||||
"""获取当前状态"""
|
||||
return get_status()
|
||||
|
||||
def resume(self):
|
||||
"""从当前状态恢复"""
|
||||
state = self.load_state()
|
||||
phase = state.get("current_phase", 1)
|
||||
|
||||
print(f"\n恢复到阶段 {phase}: {state.get('current_stage', '未知')}")
|
||||
|
||||
# 根据当前阶段调用对应方法
|
||||
method_name = f"run_phase_{phase}"
|
||||
if hasattr(self, method_name):
|
||||
return getattr(self, method_name)()
|
||||
else:
|
||||
print(f"❌ 未知阶段: {phase}")
|
||||
return None
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="dev-workflow 主编排器")
|
||||
|
||||
parser.add_argument("--init", type=str, metavar="MESSAGE",
|
||||
help="初始化工作流,提供触发消息")
|
||||
parser.add_argument("--resume", action="store_true",
|
||||
help="从上次状态恢复")
|
||||
parser.add_argument("--status", action="store_true",
|
||||
help="显示当前状态")
|
||||
parser.add_argument("--project-name", type=str,
|
||||
help="项目名称")
|
||||
parser.add_argument("--phase", type=int, metavar="N",
|
||||
help="执行指定阶段")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
orchestrator = DevWorkflowOrchestrator()
|
||||
|
||||
if args.init:
|
||||
orchestrator.initialize(args.init, args.project_name)
|
||||
orchestrator.run_phase_1()
|
||||
elif args.resume:
|
||||
orchestrator.resume()
|
||||
elif args.status:
|
||||
print(orchestrator.get_status())
|
||||
elif args.phase:
|
||||
method_name = f"run_phase_{args.phase}"
|
||||
if hasattr(orchestrator, method_name):
|
||||
getattr(orchestrator, method_name)()
|
||||
else:
|
||||
print(f"❌ 无效的阶段: {args.phase}")
|
||||
else:
|
||||
parser.print_help()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,175 @@
|
||||
# 头脑风暴阶段 Prompt 模板
|
||||
|
||||
## 问答策略
|
||||
|
||||
主Agent作为问答引导者,通过系统性提问收集足够开发的信息。
|
||||
|
||||
### 问答维度
|
||||
|
||||
1. **项目定位** - 这是什么项目?解决什么问题?
|
||||
2. **目标用户** - 谁会使用?使用场景是什么?
|
||||
3. **功能需求** - 核心功能有哪些?优先级如何?
|
||||
4. **技术约束** - 技术栈?平台?依赖?
|
||||
5. **非功能需求** - 性能?安全?可扩展性?
|
||||
6. **边界条件** - 不做什么?已知限制?
|
||||
7. **验收标准** - 怎样算完成?如何测试?
|
||||
|
||||
### 问答流程
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ 头脑风暴问答循环 │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ 1. 开放式启动 │
|
||||
│ "请描述您想要开发什么?" │
|
||||
│ ↓ │
|
||||
│ 2. 跟进深挖 │
|
||||
│ 根据回答,选择下一个维度深入提问 │
|
||||
│ - 功能细节 → "具体来说,[功能]应该如何工作?" │
|
||||
│ - 技术选择 → "为什么选择[技术]?有其他选项吗?" │
|
||||
│ - 边界条件 → "如果[场景],应该如何处理?" │
|
||||
│ ↓ │
|
||||
│ 3. 确认理解 │
|
||||
│ "我理解是...,对吗?" │
|
||||
│ ↓ │
|
||||
│ 4. 继续或结束 │
|
||||
│ - 有遗漏 → 回到步骤2 │
|
||||
│ - 足够完整 → "我认为信息足够了,准备生成需求摘要" │
|
||||
│ - 用户说"够了" → 生成需求摘要 │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 问题模板
|
||||
|
||||
#### 项目定位
|
||||
```
|
||||
- "请描述您想要开发什么?"
|
||||
- "这个项目解决什么问题?"
|
||||
- "为什么现在要做这个?"
|
||||
- "成功后是什么样子?"
|
||||
```
|
||||
|
||||
#### 目标用户
|
||||
```
|
||||
- "谁会使用这个产品?"
|
||||
- "他们的主要使用场景是什么?"
|
||||
- "他们目前是如何解决这个问题的?"
|
||||
- "这个产品对他们最大的价值是什么?"
|
||||
```
|
||||
|
||||
#### 功能需求
|
||||
```
|
||||
- "核心功能有哪些?请按重要性排序"
|
||||
- "[功能]具体应该做什么?"
|
||||
- "用户如何使用[功能]?请描述完整流程"
|
||||
- "[功能]有什么特殊情况需要处理?"
|
||||
- "有没有可选功能或未来扩展?"
|
||||
```
|
||||
|
||||
#### 技术约束
|
||||
```
|
||||
- "您希望使用什么技术栈?"
|
||||
- "有什么必须使用的库或框架?"
|
||||
- "需要支持哪些平台?"
|
||||
- "有什么性能要求?"
|
||||
- "有现有的代码库需要集成吗?"
|
||||
```
|
||||
|
||||
#### 非功能需求
|
||||
```
|
||||
- "对性能有什么要求?响应时间?并发量?"
|
||||
- "有什么安全要求?"
|
||||
- "需要支持多大规模的数据/用户?"
|
||||
- "对可维护性有什么期望?"
|
||||
```
|
||||
|
||||
#### 边界条件
|
||||
```
|
||||
- "有什么是明确不做的?"
|
||||
- "有没有已知的限制?"
|
||||
- "有什么技术难点或风险?"
|
||||
- "有没有时间或资源限制?"
|
||||
```
|
||||
|
||||
#### 验收标准
|
||||
```
|
||||
- "怎样算开发完成?"
|
||||
- "如何验证功能正确?"
|
||||
- "需要什么样的测试?"
|
||||
- "交付物应该包含什么?"
|
||||
```
|
||||
|
||||
### 需求摘要模板
|
||||
|
||||
问答结束后,生成需求摘要并保存:
|
||||
|
||||
```markdown
|
||||
# 需求摘要
|
||||
|
||||
## 项目概述
|
||||
- **名称**: [项目名]
|
||||
- **描述**: [一句话描述]
|
||||
- **核心价值**: [最重要的价值]
|
||||
|
||||
## 功能需求
|
||||
|
||||
### 核心功能 (Must Have)
|
||||
1. [功能1] - [描述]
|
||||
2. [功能2] - [描述]
|
||||
|
||||
### 可选功能 (Nice to Have)
|
||||
1. [功能1] - [描述]
|
||||
|
||||
## 技术要求
|
||||
- **语言**: [编程语言]
|
||||
- **框架**: [框架]
|
||||
- **依赖**: [依赖库]
|
||||
|
||||
## 非功能需求
|
||||
- **性能**: [要求]
|
||||
- **安全**: [要求]
|
||||
- **其他**: [要求]
|
||||
|
||||
## 约束条件
|
||||
- [约束1]
|
||||
- [约束2]
|
||||
|
||||
## 验收标准
|
||||
- [ ] [标准1]
|
||||
- [ ] [标准2]
|
||||
|
||||
## 不在范围内
|
||||
- [排除1] - [原因]
|
||||
```
|
||||
|
||||
### 结束条件
|
||||
|
||||
满足以下条件时可以结束头脑风暴:
|
||||
|
||||
1. **功能清晰** - 核心功能明确,每个功能有具体描述
|
||||
2. **技术确定** - 技术栈已确定或有明确选择方向
|
||||
3. **边界清晰** - 做什么和不做什么已明确
|
||||
4. **可验收** - 有明确的验收标准
|
||||
|
||||
### 保存结果
|
||||
|
||||
将需求摘要保存到:
|
||||
- `.planning/dev-workflow/requirements.json` (结构化数据)
|
||||
- `.planning/dev-workflow/requirements.md` (可读文档)
|
||||
|
||||
更新状态:
|
||||
```json
|
||||
{
|
||||
"phases": {
|
||||
"1": {
|
||||
"status": "completed",
|
||||
"data": {
|
||||
"questions_asked": 10,
|
||||
"requirements_collected": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,246 @@
|
||||
# 代码审查阶段 Prompt 模板
|
||||
|
||||
## 目标
|
||||
|
||||
启动3个子代理独立完整审查代码,发现问题并提出改进建议。
|
||||
|
||||
## 审查子代理 Prompt
|
||||
|
||||
```
|
||||
你是一个资深代码审查专家。请对以下代码变更进行完整审查。
|
||||
|
||||
## 项目信息
|
||||
- 项目名称: {project_name}
|
||||
- 审查范围: 本次开发的所有变更
|
||||
|
||||
## 变更文件列表
|
||||
{changed_files_list}
|
||||
|
||||
## 变更详情
|
||||
{changes_diff}
|
||||
|
||||
## 审查要求
|
||||
|
||||
请进行**完整、独立**的代码审查,覆盖以下所有维度:
|
||||
|
||||
### 1. 代码质量
|
||||
- 命名是否清晰、一致
|
||||
- 代码结构是否合理
|
||||
- 是否有重复代码
|
||||
- 是否有过度复杂的设计
|
||||
|
||||
### 2. 功能正确性
|
||||
- 代码是否实现了预期功能
|
||||
- 边界条件是否处理
|
||||
- 错误处理是否完善
|
||||
|
||||
### 3. 性能
|
||||
- 是否有性能问题
|
||||
- 是否有不必要的计算
|
||||
- 是否有内存泄漏风险
|
||||
|
||||
### 4. 安全性
|
||||
- 是否有安全漏洞
|
||||
- 敏感数据处理是否安全
|
||||
- 输入验证是否完善
|
||||
|
||||
### 5. 可维护性
|
||||
- 代码是否易于理解
|
||||
- 是否有足够的注释
|
||||
- 是否符合项目规范
|
||||
|
||||
### 6. 测试覆盖
|
||||
- 测试是否充分
|
||||
- 是否有遗漏的测试场景
|
||||
|
||||
## 输出格式
|
||||
|
||||
```markdown
|
||||
# 代码审查报告
|
||||
|
||||
## 审查信息
|
||||
- 审查者: Agent {A/B/C}
|
||||
- 审查时间: {timestamp}
|
||||
- 审查文件数: {file_count}
|
||||
|
||||
## 发现的问题
|
||||
|
||||
### 严重问题 (必须修复)
|
||||
|
||||
#### ISSUE-001: {issue_title}
|
||||
- **文件**: {file_path}
|
||||
- **行号**: {line_number}
|
||||
- **问题**: {description}
|
||||
- **影响**: {impact}
|
||||
- **建议修复**: {suggestion}
|
||||
|
||||
#### ISSUE-002: ...
|
||||
|
||||
---
|
||||
|
||||
### 一般问题 (建议修复)
|
||||
|
||||
#### ISSUE-003: {issue_title}
|
||||
- **文件**: {file_path}
|
||||
- **问题描述**: {description}
|
||||
- **建议**: {suggestion}
|
||||
|
||||
---
|
||||
|
||||
### 改进建议 (可选)
|
||||
|
||||
#### SUGGEST-001: {suggestion_title}
|
||||
- **当前实现**: {current}
|
||||
- **建议改进**: {improvement}
|
||||
- **收益**: {benefit}
|
||||
|
||||
---
|
||||
|
||||
## 代码亮点
|
||||
|
||||
1. {highlight_1}
|
||||
2. {highlight_2}
|
||||
|
||||
## 总结
|
||||
|
||||
- 严重问题: {critical_count}
|
||||
- 一般问题: {major_count}
|
||||
- 改进建议: {suggestion_count}
|
||||
|
||||
**整体评价**: 优秀/良好/需改进/不合格
|
||||
|
||||
## 审查结论
|
||||
- [ ] 可以合并
|
||||
- [ ] 需要修复后合并
|
||||
- [ ] 需要重大修改
|
||||
```
|
||||
|
||||
请仔细审查每一行代码,不要遗漏任何潜在问题。
|
||||
```
|
||||
|
||||
## 三个审查子代理
|
||||
|
||||
```python
|
||||
def spawn_review_agents(changes: dict) -> list:
|
||||
"""启动3个代码审查子代理"""
|
||||
|
||||
agents = [
|
||||
{"id": "X", "focus": "全面审查"},
|
||||
{"id": "Y", "focus": "全面审查"},
|
||||
{"id": "Z", "focus": "全面审查"}
|
||||
]
|
||||
|
||||
results = []
|
||||
|
||||
for agent in agents:
|
||||
prompt = build_review_prompt(changes, agent)
|
||||
|
||||
result = spawn_subagent(
|
||||
task=f"代码审查 - Agent {agent['id']}",
|
||||
prompt=prompt,
|
||||
output_file=f".planning/dev-workflow/code-review/review-{agent['id']}.md"
|
||||
)
|
||||
|
||||
results.append(result)
|
||||
|
||||
return results
|
||||
```
|
||||
|
||||
## 问题汇总
|
||||
|
||||
主代理收集三个审查结果后,汇总问题:
|
||||
|
||||
```python
|
||||
def consolidate_issues(reviews: list) -> dict:
|
||||
"""汇总三个审查的问题"""
|
||||
|
||||
all_issues = {
|
||||
"critical": [],
|
||||
"major": [],
|
||||
"suggestion": []
|
||||
}
|
||||
|
||||
for review in reviews:
|
||||
for issue in review.get("issues", []):
|
||||
# 检查是否已存在相同问题
|
||||
existing = find_similar_issue(issue, all_issues[issue["severity"]])
|
||||
|
||||
if existing:
|
||||
# 多个审查者发现同一问题,增加权重
|
||||
existing["found_by"].append(review["agent_id"])
|
||||
existing["confidence"] += 1
|
||||
else:
|
||||
issue["found_by"] = [review["agent_id"]]
|
||||
issue["confidence"] = 1
|
||||
all_issues[issue["severity"]].append(issue)
|
||||
|
||||
# 按置信度排序
|
||||
for severity in all_issues:
|
||||
all_issues[severity].sort(key=lambda x: x["confidence"], reverse=True)
|
||||
|
||||
return all_issues
|
||||
```
|
||||
|
||||
## 问题汇总报告
|
||||
|
||||
```markdown
|
||||
# 代码审查汇总
|
||||
|
||||
## 统计
|
||||
|
||||
| 审查者 | 严重 | 一般 | 建议 |
|
||||
|--------|------|------|------|
|
||||
| Agent X | 2 | 3 | 5 |
|
||||
| Agent Y | 1 | 4 | 3 |
|
||||
| Agent Z | 2 | 2 | 6 |
|
||||
|
||||
## 严重问题 (3个,多人确认)
|
||||
|
||||
### ISSUE-CRIT-001: SQL注入风险 (X, Y, Z 都发现)
|
||||
- **文件**: src/db/queries.py:45
|
||||
- **问题**: 用户输入未转义直接拼接到SQL
|
||||
- **建议**: 使用参数化查询
|
||||
|
||||
### ISSUE-CRIT-002: 空指针异常 (X, Z 发现)
|
||||
- **文件**: src/services/user.py:120
|
||||
- **问题**: 未检查返回值是否为None
|
||||
- **建议**: 添加空值检查
|
||||
|
||||
---
|
||||
|
||||
## 一般问题 (5个)
|
||||
|
||||
### ISSUE-MAJ-001: 命名不规范 (Y 发现)
|
||||
...
|
||||
|
||||
---
|
||||
|
||||
## 改进建议 (8个)
|
||||
|
||||
### SUGGEST-001: 可以提取公共函数 (X, Z 发现)
|
||||
...
|
||||
|
||||
---
|
||||
|
||||
## 下一步
|
||||
|
||||
需要修复 **3个严重问题** 和 **5个一般问题**
|
||||
```
|
||||
|
||||
## 状态更新
|
||||
|
||||
```json
|
||||
{
|
||||
"phases": {
|
||||
"8": {
|
||||
"status": "completed",
|
||||
"issues": {
|
||||
"critical": 3,
|
||||
"major": 5,
|
||||
"suggestion": 8
|
||||
},
|
||||
"reviews": ["review-X.md", "review-Y.md", "review-Z.md"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,284 @@
|
||||
# 修复验证阶段 Prompt 模板
|
||||
|
||||
## 目标
|
||||
|
||||
汇总审查问题,安排修复,验证完成,最终汇报。
|
||||
|
||||
## 流程
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ 修复验证流程 │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ 1. 汇总问题 │
|
||||
│ └→ 按优先级排序 │
|
||||
│ ↓ │
|
||||
│ 2. 分配修复任务 │
|
||||
│ └→ 启动修复子代理 │
|
||||
│ ↓ │
|
||||
│ 3. 修复执行 │
|
||||
│ └→ 子代理修复问题 │
|
||||
│ ↓ │
|
||||
│ 4. 验证修复 │
|
||||
│ └→ 启动验证子代理 │
|
||||
│ ↓ │
|
||||
│ ┌───────────────────────────────────────┐ │
|
||||
│ │ 验证结果 │ │
|
||||
│ ├───────────────────────────────────────┤ │
|
||||
│ │ 通过 → 生成最终报告 │ │
|
||||
│ │ 失败 → 重试修复(最多3次) │ │
|
||||
│ └───────────────────────────────────────┘ │
|
||||
│ ↓ │
|
||||
│ 5. 最终汇报 │
|
||||
│ └→ 向用户展示完整结果 │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## 修复子代理 Prompt
|
||||
|
||||
```
|
||||
你是一个代码修复专家。请修复以下问题。
|
||||
|
||||
## 问题列表
|
||||
|
||||
### 必须修复 (严重问题)
|
||||
{critical_issues}
|
||||
|
||||
### 建议修复 (一般问题)
|
||||
{major_issues}
|
||||
|
||||
## 项目上下文
|
||||
{project_context}
|
||||
|
||||
## 修复要求
|
||||
|
||||
1. **保持代码风格一致**
|
||||
2. **不引入新问题**
|
||||
3. **添加必要的测试**
|
||||
4. **更新相关文档**
|
||||
|
||||
## 输出格式
|
||||
|
||||
```markdown
|
||||
# 修复报告
|
||||
|
||||
## 修复的问题
|
||||
|
||||
### ISSUE-CRIT-001: {issue_title}
|
||||
- **修复方式**: {fix_description}
|
||||
- **修改文件**: {files_changed}
|
||||
- **新增测试**: {new_tests}
|
||||
|
||||
### ISSUE-CRIT-002: ...
|
||||
|
||||
## 修改的文件
|
||||
- {file_1}: [修改说明]
|
||||
- {file_2}: [修改说明]
|
||||
|
||||
## 验证
|
||||
- 运行测试: {test_result}
|
||||
- 手动验证: {manual_verification}
|
||||
|
||||
## 遗留问题
|
||||
- [如有未能修复的问题]
|
||||
```
|
||||
|
||||
请修复所有严重问题,尽量修复一般问题。
|
||||
```
|
||||
|
||||
## 验证子代理 Prompt
|
||||
|
||||
```
|
||||
你是一个质量保证专家。请验证以下问题是否已正确修复。
|
||||
|
||||
## 原始问题
|
||||
{original_issues}
|
||||
|
||||
## 修复内容
|
||||
{fix_reports}
|
||||
|
||||
## 验证任务
|
||||
|
||||
1. **检查代码** - 确认修复代码存在且正确
|
||||
2. **运行测试** - 确认测试通过
|
||||
3. **验证功能** - 确认问题不再出现
|
||||
4. **检查副作用** - 确认没有引入新问题
|
||||
|
||||
## 输出格式
|
||||
|
||||
```markdown
|
||||
# 验证报告
|
||||
|
||||
## 验证结果
|
||||
|
||||
| 问题ID | 原问题 | 验证结果 | 说明 |
|
||||
|--------|--------|----------|------|
|
||||
| ISSUE-CRIT-001 | SQL注入 | ✅ 已修复 | 使用参数化查询 |
|
||||
| ISSUE-CRIT-002 | 空指针 | ✅ 已修复 | 添加空值检查 |
|
||||
| ISSUE-MAJ-001 | 命名 | ✅ 已修复 | 重命名变量 |
|
||||
|
||||
## 测试结果
|
||||
- 运行测试: {total} 个
|
||||
- 通过: {passed} 个
|
||||
- 失败: {failed} 个
|
||||
|
||||
## 回归检查
|
||||
- [ ] 原有功能正常
|
||||
- [ ] 新功能正常
|
||||
- [ ] 无新引入问题
|
||||
|
||||
## 结论
|
||||
- [ ] 所有严重问题已修复
|
||||
- [ ] 测试全部通过
|
||||
- [ ] 代码质量达标
|
||||
|
||||
**验证结果**: 通过 / 不通过
|
||||
|
||||
## 遗留问题
|
||||
- [如有未通过的问题]
|
||||
```
|
||||
|
||||
请严格验证每个修复。
|
||||
```
|
||||
|
||||
## 修复循环逻辑
|
||||
|
||||
```python
|
||||
def fix_and_verify(issues: dict, max_retries: int = 3) -> dict:
|
||||
"""修复并验证问题"""
|
||||
|
||||
for attempt in range(1, max_retries + 1):
|
||||
print(f"\n修复尝试 {attempt}/{max_retries}")
|
||||
|
||||
# 1. 启动修复子代理
|
||||
fix_result = spawn_fix_agent(issues)
|
||||
|
||||
if fix_result["status"] != "success":
|
||||
print("修复子代理执行失败")
|
||||
continue
|
||||
|
||||
# 2. 启动验证子代理
|
||||
verify_result = spawn_verify_agent(issues, fix_result)
|
||||
|
||||
if verify_result["passed"]:
|
||||
print("✅ 验证通过")
|
||||
return {
|
||||
"status": "success",
|
||||
"fixes": fix_result,
|
||||
"verification": verify_result
|
||||
}
|
||||
|
||||
print(f"⚠️ 验证失败: {verify_result['remaining_issues']}")
|
||||
|
||||
# 更新剩余问题
|
||||
issues = verify_result["remaining_issues"]
|
||||
|
||||
print(f"❌ 已达到最大重试次数 ({max_retries})")
|
||||
return {
|
||||
"status": "failed",
|
||||
"remaining_issues": issues
|
||||
}
|
||||
```
|
||||
|
||||
## 最终汇报模板
|
||||
|
||||
```markdown
|
||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
DEV-WORKFLOW ► 开发完成
|
||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
|
||||
## 项目: {project_name}
|
||||
|
||||
### 完成摘要
|
||||
|
||||
| 阶段 | 状态 | 耗时 |
|
||||
|------|------|------|
|
||||
| 1. 头脑风暴 | ✓ 完成 | 5min |
|
||||
| 2. 方案设计 | ✓ 完成 | 10min |
|
||||
| 3. 方案审核 | ✓ 完成 | 8min |
|
||||
| 4. 方案汇报 | ✓ 完成 | 2min |
|
||||
| 5. Spec编排 | ✓ 完成 | 5min |
|
||||
| 6. 并行开发 | ✓ 完成 | 30min |
|
||||
| 7. 测试 | ✓ 完成 | 5min |
|
||||
| 8. 代码审查 | ✓ 完成 | 10min |
|
||||
| 9. 修复验证 | ✓ 完成 | 8min |
|
||||
|
||||
**总耗时**: {total_time}
|
||||
|
||||
### 交付物
|
||||
|
||||
**文件变更**:
|
||||
- 新建: {new_files_count} 个文件
|
||||
- 修改: {modified_files_count} 个文件
|
||||
- 删除: {deleted_files_count} 个文件
|
||||
|
||||
**测试覆盖**:
|
||||
- 单元测试: {unit_tests} 个
|
||||
- 集成测试: {integration_tests} 个
|
||||
- 覆盖率: {coverage}%
|
||||
|
||||
**代码质量**:
|
||||
- 严重问题: 0 (已全部修复)
|
||||
- 一般问题: 0 (已全部修复)
|
||||
- 代码审查: 通过
|
||||
|
||||
### 遗留事项
|
||||
|
||||
{remaining_items}
|
||||
|
||||
### 后续建议
|
||||
|
||||
{recommendations}
|
||||
|
||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
|
||||
🎉 开发任务已完成!
|
||||
|
||||
详细文档: `.planning/dev-workflow/`
|
||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
```
|
||||
|
||||
## 状态更新
|
||||
|
||||
```json
|
||||
{
|
||||
"current_phase": 9,
|
||||
"current_stage": "completed",
|
||||
"phases": {
|
||||
"9": {
|
||||
"status": "completed",
|
||||
"fixes": {
|
||||
"critical_fixed": 3,
|
||||
"major_fixed": 5,
|
||||
"retry_count": 1
|
||||
},
|
||||
"verification": {
|
||||
"passed": true,
|
||||
"timestamp": "2026-03-09T20:00:00+08:00"
|
||||
}
|
||||
}
|
||||
},
|
||||
"completed_at": "2026-03-09T20:00:00+08:00"
|
||||
}
|
||||
```
|
||||
|
||||
## 文档归档
|
||||
|
||||
完成后,将所有文档归档:
|
||||
|
||||
```
|
||||
.planning/dev-workflow/
|
||||
├── state.json # 最终状态
|
||||
├── requirements.json # 需求文档
|
||||
├── final-solution.md # 最终方案
|
||||
├── spec.md # 开发规格
|
||||
├── execution-plan.json # 执行计划
|
||||
├── test-results.json # 测试结果
|
||||
├── code-review/ # 代码审查
|
||||
│ ├── review-X.md
|
||||
│ ├── review-Y.md
|
||||
│ └── review-Z.md
|
||||
└── final-report.md # 最终报告
|
||||
```
|
||||
@@ -0,0 +1,222 @@
|
||||
# 并行开发阶段 Prompt 模板
|
||||
|
||||
## 目标
|
||||
|
||||
按波次启动子代理执行开发任务,同波内并行执行,波间串行。
|
||||
|
||||
## 开发子代理 Prompt
|
||||
|
||||
```
|
||||
你是一个专业的开发者。请实现以下任务。
|
||||
|
||||
## 任务信息
|
||||
|
||||
**任务ID**: {task_id}
|
||||
**任务名称**: {task_name}
|
||||
|
||||
## 任务描述
|
||||
{task_description}
|
||||
|
||||
## 输入
|
||||
{task_inputs}
|
||||
|
||||
## 输出要求
|
||||
{task_outputs}
|
||||
|
||||
## 实现要点
|
||||
{implementation_points}
|
||||
|
||||
## 验收标准
|
||||
{acceptance_criteria}
|
||||
|
||||
## 项目上下文
|
||||
|
||||
### 技术栈
|
||||
{tech_stack}
|
||||
|
||||
### 文件结构
|
||||
{file_structure}
|
||||
|
||||
### 相关文件
|
||||
{related_files}
|
||||
|
||||
## 开发要求
|
||||
|
||||
1. **代码质量**
|
||||
- 遵循项目代码规范
|
||||
- 添加必要的注释
|
||||
- 编写清晰的函数/变量命名
|
||||
|
||||
2. **测试**
|
||||
- 为新代码编写单元测试
|
||||
- 测试文件放在 tests/ 目录
|
||||
|
||||
3. **文档**
|
||||
- 更新相关文档
|
||||
- 添加必要的 docstring
|
||||
|
||||
4. **提交**
|
||||
- 完成后说明修改了哪些文件
|
||||
- 列出主要改动点
|
||||
|
||||
## 输出格式
|
||||
|
||||
完成后请输出:
|
||||
|
||||
```markdown
|
||||
# 任务完成报告
|
||||
|
||||
## 任务: {task_id} - {task_name}
|
||||
|
||||
## 修改的文件
|
||||
- {file_1}: [改动说明]
|
||||
- {file_2}: [改动说明]
|
||||
|
||||
## 主要实现
|
||||
1. [实现点1]
|
||||
2. [实现点2]
|
||||
|
||||
## 测试
|
||||
- 新增测试: {test_files}
|
||||
- 测试通过: 是/否
|
||||
|
||||
## 注意事项
|
||||
- [需要注意的点]
|
||||
|
||||
## 遗留问题
|
||||
- [如有未完成的部分]
|
||||
```
|
||||
|
||||
请开始开发。
|
||||
```
|
||||
|
||||
## 波次执行逻辑
|
||||
|
||||
```python
|
||||
import subprocess
|
||||
import json
|
||||
from concurrent.futures import ThreadPoolExecutor, as_completed
|
||||
|
||||
def execute_wave(wave_num: int, tasks: list, spec: dict):
|
||||
"""执行一个波次的开发任务"""
|
||||
|
||||
print(f"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
|
||||
print(f" WAVE {wave_num} - 并行执行 {len(tasks)} 个任务")
|
||||
print(f"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
|
||||
|
||||
results = []
|
||||
|
||||
with ThreadPoolExecutor(max_workers=len(tasks)) as executor:
|
||||
futures = {}
|
||||
|
||||
for task_id in tasks:
|
||||
task = spec["tasks"][task_id]
|
||||
|
||||
# 构建子代理 prompt
|
||||
prompt = build_developer_prompt(task, spec)
|
||||
|
||||
# 提交子代理任务
|
||||
future = executor.submit(
|
||||
spawn_developer_agent,
|
||||
task_id=task_id,
|
||||
prompt=prompt
|
||||
)
|
||||
futures[future] = task_id
|
||||
|
||||
# 收集结果
|
||||
for future in as_completed(futures):
|
||||
task_id = futures[future]
|
||||
try:
|
||||
result = future.result()
|
||||
results.append({
|
||||
"task_id": task_id,
|
||||
"status": "success",
|
||||
"output": result
|
||||
})
|
||||
print(f" ✓ {task_id} 完成")
|
||||
except Exception as e:
|
||||
results.append({
|
||||
"task_id": task_id,
|
||||
"status": "failed",
|
||||
"error": str(e)
|
||||
})
|
||||
print(f" ✗ {task_id} 失败: {e}")
|
||||
|
||||
return results
|
||||
|
||||
|
||||
def execute_all_waves(execution_plan: dict, spec: dict):
|
||||
"""执行所有波次"""
|
||||
|
||||
all_results = {}
|
||||
|
||||
for wave_num in sorted(execution_plan.keys()):
|
||||
wave_key = f"wave_{wave_num}"
|
||||
tasks = execution_plan[wave_key]
|
||||
|
||||
wave_results = execute_wave(wave_num, tasks, spec)
|
||||
all_results[wave_key] = wave_results
|
||||
|
||||
# 检查是否有失败
|
||||
failed = [r for r in wave_results if r["status"] == "failed"]
|
||||
if failed:
|
||||
print(f"\n⚠️ Wave {wave_num} 有 {len(failed)} 个任务失败")
|
||||
# 可以选择重试或停止
|
||||
|
||||
return all_results
|
||||
```
|
||||
|
||||
## 子代理启动
|
||||
|
||||
```python
|
||||
def spawn_developer_agent(task_id: str, prompt: str) -> str:
|
||||
"""启动开发子代理"""
|
||||
|
||||
# 使用 sessions_spawn 启动子代理
|
||||
result = subprocess.run([
|
||||
"openclaw", "agent", "spawn",
|
||||
"--task", prompt,
|
||||
"--cwd", get_project_root(),
|
||||
"--timeout", "1800", # 30分钟超时
|
||||
"--output", f".planning/dev-workflow/development/{task_id}.json"
|
||||
], capture_output=True, text=True)
|
||||
|
||||
if result.returncode != 0:
|
||||
raise Exception(f"子代理启动失败: {result.stderr}")
|
||||
|
||||
return result.stdout
|
||||
```
|
||||
|
||||
## 进度监控
|
||||
|
||||
```
|
||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
DEV-WORKFLOW ► 开发进度
|
||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
|
||||
Wave 1: ✓✓✓ (3/3 完成)
|
||||
Wave 2: ✓→○ (1/3 进行中)
|
||||
Wave 3: ○○ (0/2 等待中)
|
||||
|
||||
总进度: 4/8 任务 (50%)
|
||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
```
|
||||
|
||||
## 状态更新
|
||||
|
||||
```json
|
||||
{
|
||||
"phases": {
|
||||
"6": {
|
||||
"status": "completed",
|
||||
"waves": {
|
||||
"wave_1": {"status": "completed", "tasks": ["TASK-001", "TASK-002", "TASK-003"]},
|
||||
"wave_2": {"status": "completed", "tasks": ["TASK-004", "TASK-005"]},
|
||||
"wave_3": {"status": "completed", "tasks": ["TASK-006", "TASK-007", "TASK-008"]}
|
||||
},
|
||||
"total_tasks": 8,
|
||||
"completed_tasks": 8
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,215 @@
|
||||
# 方案设计阶段 Prompt 模板
|
||||
|
||||
## 目标
|
||||
|
||||
启动3个子代理并行设计方案,每个子代理独立思考,探索不同的实现路径。
|
||||
|
||||
## 子代理启动配置
|
||||
|
||||
### 子代理 A - 通用型方案
|
||||
|
||||
```
|
||||
你是一个方案设计专家。请基于以下需求,设计一个实现方案。
|
||||
|
||||
## 项目背景
|
||||
{requirements_summary}
|
||||
|
||||
## 设计要求
|
||||
1. 提供完整的技术方案
|
||||
2. 包含架构设计、数据流、关键算法
|
||||
3. 考虑可扩展性和可维护性
|
||||
4. 列出需要创建的文件和目录结构
|
||||
5. 估算开发复杂度
|
||||
|
||||
## 输出格式
|
||||
|
||||
```markdown
|
||||
# 方案设计 - [方案名称]
|
||||
|
||||
## 概述
|
||||
[一句话描述方案特点]
|
||||
|
||||
## 技术选型
|
||||
- 语言:
|
||||
- 框架:
|
||||
- 关键依赖:
|
||||
|
||||
## 架构设计
|
||||
[架构图或描述]
|
||||
|
||||
## 核心模块
|
||||
1. [模块1]
|
||||
- 职责:
|
||||
- 接口:
|
||||
- 依赖:
|
||||
|
||||
2. [模块2]
|
||||
...
|
||||
|
||||
## 数据流
|
||||
[数据如何在模块间流动]
|
||||
|
||||
## 关键算法/逻辑
|
||||
[核心算法或业务逻辑]
|
||||
|
||||
## 文件结构
|
||||
```
|
||||
项目根目录/
|
||||
├── 文件1
|
||||
├── 目录/
|
||||
│ └── 文件2
|
||||
```
|
||||
|
||||
## 开发步骤
|
||||
1. [步骤1]
|
||||
2. [步骤2]
|
||||
|
||||
## 风险和挑战
|
||||
- [风险1]: [应对策略]
|
||||
|
||||
## 复杂度评估
|
||||
- 预计文件数:
|
||||
- 预计代码行数:
|
||||
- 开发难度: 低/中/高
|
||||
```
|
||||
|
||||
请自由发挥,不必拘泥于常规方案。
|
||||
```
|
||||
|
||||
### 子代理 B - 实用型方案
|
||||
|
||||
```
|
||||
你是一个务实的工程师。请基于以下需求,设计一个**最实用、最快速实现**的方案。
|
||||
|
||||
## 项目背景
|
||||
{requirements_summary}
|
||||
|
||||
## 设计原则
|
||||
1. 优先选择成熟、稳定的技术
|
||||
2. 尽量复用现有库,减少自研
|
||||
3. 代码简洁,易于理解和维护
|
||||
4. 快速交付,迭代优化
|
||||
|
||||
## 输出格式
|
||||
[同上]
|
||||
|
||||
请专注于**实用性**,避免过度设计。
|
||||
```
|
||||
|
||||
### 子代理 C - 创新型方案
|
||||
|
||||
```
|
||||
你是一个创新探索者。请基于以下需求,设计一个**有创意、有突破**的方案。
|
||||
|
||||
## 项目背景
|
||||
{requirements_summary}
|
||||
|
||||
## 设计原则
|
||||
1. 可以尝试新技术、新架构
|
||||
2. 不必拘泥于传统实现方式
|
||||
3. 考虑未来的可扩展性
|
||||
4. 允许有一定风险,但需说明
|
||||
|
||||
## 输出格式
|
||||
[同上]
|
||||
|
||||
请大胆探索,提供**与众不同的思路**。
|
||||
```
|
||||
|
||||
## 子代理启动命令
|
||||
|
||||
```python
|
||||
# 主代理执行
|
||||
import subprocess
|
||||
import json
|
||||
|
||||
def spawn_design_agents(requirements_summary: str):
|
||||
"""启动3个方案设计子代理"""
|
||||
|
||||
agents = [
|
||||
{"id": "A", "type": "general", "focus": "完整通用方案"},
|
||||
{"id": "B", "type": "practical", "focus": "实用快速方案"},
|
||||
{"id": "C", "type": "creative", "focus": "创新探索方案"}
|
||||
]
|
||||
|
||||
results = []
|
||||
|
||||
for agent in agents:
|
||||
prompt = get_prompt_template(agent["type"]).format(
|
||||
requirements_summary=requirements_summary
|
||||
)
|
||||
|
||||
# 使用 sessions_spawn 启动子代理
|
||||
result = subprocess.run([
|
||||
"openclaw", "agent", "spawn",
|
||||
"--prompt", prompt,
|
||||
"--model", "g5", # 使用高质量模型
|
||||
"--output", f".planning/dev-workflow/solutions/solution-{agent['id']}.md"
|
||||
], capture_output=True, text=True)
|
||||
|
||||
results.append({
|
||||
"agent_id": agent["id"],
|
||||
"output_file": f"solution-{agent['id']}.md",
|
||||
"status": "success" if result.returncode == 0 else "failed"
|
||||
})
|
||||
|
||||
return results
|
||||
```
|
||||
|
||||
## 输出文件
|
||||
|
||||
每个子代理输出保存到:
|
||||
- `.planning/dev-workflow/solutions/solution-A.md`
|
||||
- `.planning/dev-workflow/solutions/solution-B.md`
|
||||
- `.planning/dev-workflow/solutions/solution-C.md`
|
||||
|
||||
## 主代理汇总
|
||||
|
||||
所有子代理完成后,主代理生成方案对比:
|
||||
|
||||
```markdown
|
||||
# 方案对比摘要
|
||||
|
||||
## 方案概览
|
||||
|
||||
| 维度 | 方案A (通用型) | 方案B (实用型) | 方案C (创新型) |
|
||||
|------|---------------|---------------|---------------|
|
||||
| 特点 | 完整、规范 | 快速、实用 | 创新、突破 |
|
||||
| 复杂度 | 中 | 低 | 高 |
|
||||
| 风险 | 低 | 低 | 中 |
|
||||
| 开发周期 | 中 | 短 | 长 |
|
||||
|
||||
## 各方案亮点
|
||||
|
||||
### 方案A
|
||||
- [亮点1]
|
||||
- [亮点2]
|
||||
|
||||
### 方案B
|
||||
- [亮点1]
|
||||
- [亮点2]
|
||||
|
||||
### 方案C
|
||||
- [亮点1]
|
||||
- [亮点2]
|
||||
|
||||
## 推荐
|
||||
[主代理的初步推荐,供审核阶段参考]
|
||||
```
|
||||
|
||||
## 状态更新
|
||||
|
||||
```json
|
||||
{
|
||||
"phases": {
|
||||
"2": {
|
||||
"status": "completed",
|
||||
"agents": ["A", "B", "C"],
|
||||
"data": {
|
||||
"solutions": ["solution-A.md", "solution-B.md", "solution-C.md"],
|
||||
"comparison": "comparison.md"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,136 @@
|
||||
# 方案汇报阶段 Prompt 模板
|
||||
|
||||
## 目标
|
||||
|
||||
向用户展示综合方案,获取用户决策:批准 / 修改 / 重新设计。
|
||||
|
||||
## 汇报格式
|
||||
|
||||
```markdown
|
||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
DEV-WORKFLOW ► 方案汇报
|
||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
|
||||
## 项目: {project_name}
|
||||
|
||||
### 需求摘要
|
||||
{requirements_summary_brief}
|
||||
|
||||
### 综合方案概述
|
||||
{final_solution_summary}
|
||||
|
||||
### 关键技术决策
|
||||
|
||||
| 决策点 | 选择 | 理由 |
|
||||
|--------|------|------|
|
||||
| {decision_1} | {choice_1} | {reason_1} |
|
||||
| {decision_2} | {choice_2} | {reason_2} |
|
||||
|
||||
### 架构概览
|
||||
{architecture_brief}
|
||||
|
||||
### 开发计划
|
||||
{development_plan_brief}
|
||||
|
||||
### 预计工作量
|
||||
- 文件数: {file_count}
|
||||
- 预计开发时间: {estimated_time}
|
||||
- 复杂度: {complexity}
|
||||
|
||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
|
||||
## 请选择:
|
||||
|
||||
**A. 批准方案** - 进入开发阶段
|
||||
|
||||
**B. 需要修改** - 请告诉我需要调整的地方
|
||||
|
||||
**C. 重新设计** - 对方案不满意,重新设计方案
|
||||
|
||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
```
|
||||
|
||||
## 用户决策处理
|
||||
|
||||
### 批准 (A)
|
||||
|
||||
```json
|
||||
{
|
||||
"phases": {
|
||||
"4": {
|
||||
"status": "completed",
|
||||
"user_decision": "approved",
|
||||
"approved_at": "2026-03-09T19:00:00+08:00"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
进入 Phase 5: Spec编排
|
||||
|
||||
### 需要修改 (B)
|
||||
|
||||
1. 收集用户修改意见
|
||||
2. 更新需求文件
|
||||
3. 回到 Phase 2 或 Phase 3(根据修改范围)
|
||||
4. 重新生成方案
|
||||
|
||||
```json
|
||||
{
|
||||
"phases": {
|
||||
"4": {
|
||||
"status": "revision_requested",
|
||||
"user_feedback": "用户的具体修改意见",
|
||||
"revision_count": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 重新设计 (C)
|
||||
|
||||
1. 记录用户不满意的原因
|
||||
2. 回到 Phase 2 重新收集需求
|
||||
3. 或回到 Phase 3 重新设计方案
|
||||
|
||||
```json
|
||||
{
|
||||
"phases": {
|
||||
"4": {
|
||||
"status": "redesign_requested",
|
||||
"user_feedback": "用户不满意的原因",
|
||||
"redesign_count": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 汇报要点
|
||||
|
||||
向用户汇报时,重点展示:
|
||||
|
||||
1. **核心决策** - 最关键的技术选择
|
||||
2. **架构图** - 系统结构可视化
|
||||
3. **文件清单** - 将要创建的文件
|
||||
4. **开发步骤** - 如何一步步实现
|
||||
5. **风险评估** - 可能的问题和应对
|
||||
|
||||
## 决策引导
|
||||
|
||||
如果用户犹豫,可以引导:
|
||||
|
||||
```
|
||||
您可能关心的问题:
|
||||
|
||||
1. "为什么选择这个技术栈?"
|
||||
→ [解释选择理由]
|
||||
|
||||
2. "有没有更简单的方案?"
|
||||
→ [对比方案复杂度]
|
||||
|
||||
3. "开发周期大概多久?"
|
||||
→ [估算工作量]
|
||||
|
||||
4. "有什么风险?"
|
||||
→ [列出风险和应对]
|
||||
```
|
||||
@@ -0,0 +1,200 @@
|
||||
# 方案审核阶段 Prompt 模板
|
||||
|
||||
## 目标
|
||||
|
||||
每个子代理审核其他两个方案,发现问题、提出改进建议,最终达成综合方案。
|
||||
|
||||
## 交叉审核矩阵
|
||||
|
||||
```
|
||||
┌─────────────┬───────────────┬───────────────┬───────────────┐
|
||||
│ 审核者 │ 审核方案A │ 审核方案B │ 审核方案C │
|
||||
├─────────────┼───────────────┼───────────────┼───────────────┤
|
||||
│ Agent A │ — │ ✓ │ ✓ │
|
||||
│ Agent B │ ✓ │ — │ ✓ │
|
||||
│ Agent C │ ✓ │ ✓ │ — │
|
||||
└─────────────┴───────────────┴───────────────┴───────────────┘
|
||||
```
|
||||
|
||||
## 审核子代理 Prompt
|
||||
|
||||
```
|
||||
你是一个代码审核专家。请审核以下两个技术方案,并提供专业的评审意见。
|
||||
|
||||
## 原始需求
|
||||
{requirements_summary}
|
||||
|
||||
## 待审核方案
|
||||
|
||||
### 方案 1
|
||||
{solution_1_content}
|
||||
|
||||
### 方案 2
|
||||
{solution_2_content}
|
||||
|
||||
## 审核维度
|
||||
|
||||
请从以下维度进行审核:
|
||||
|
||||
### 1. 完整性
|
||||
- 是否覆盖了所有需求?
|
||||
- 有没有遗漏的功能点?
|
||||
- 边界条件是否考虑周全?
|
||||
|
||||
### 2. 可行性
|
||||
- 技术方案是否可行?
|
||||
- 有没有技术风险?
|
||||
- 依赖是否稳定可靠?
|
||||
|
||||
### 3. 可维护性
|
||||
- 代码结构是否清晰?
|
||||
- 是否易于理解和修改?
|
||||
- 是否有足够的文档?
|
||||
|
||||
### 4. 性能
|
||||
- 是否满足性能要求?
|
||||
- 有没有性能瓶颈?
|
||||
- 是否有优化空间?
|
||||
|
||||
### 5. 安全性
|
||||
- 是否有安全风险?
|
||||
- 敏感数据如何处理?
|
||||
- 权限控制是否完善?
|
||||
|
||||
## 输出格式
|
||||
|
||||
```markdown
|
||||
# 方案审核报告
|
||||
|
||||
## 审核: [方案1名称] vs [方案2名称]
|
||||
|
||||
### 方案1 评审
|
||||
|
||||
#### 优点
|
||||
1. [优点1]
|
||||
2. [优点2]
|
||||
|
||||
#### 缺点
|
||||
1. [缺点1]
|
||||
2. [缺点2]
|
||||
|
||||
#### 改进建议
|
||||
1. [建议1]
|
||||
2. [建议2]
|
||||
|
||||
#### 评分 (1-10)
|
||||
- 完整性:
|
||||
- 可行性:
|
||||
- 可维护性:
|
||||
- 性能:
|
||||
- 安全性:
|
||||
- **总分**:
|
||||
|
||||
---
|
||||
|
||||
### 方案2 评审
|
||||
[同上结构]
|
||||
|
||||
---
|
||||
|
||||
## 对比结论
|
||||
|
||||
### 更推荐哪个方案?
|
||||
[选择] 及原因
|
||||
|
||||
### 两个方案可以融合的点
|
||||
1. [融合点1]
|
||||
2. [融合点2]
|
||||
|
||||
### 需要额外关注的风险
|
||||
1. [风险1]
|
||||
```
|
||||
|
||||
请客观、专业地进行审核。
|
||||
```
|
||||
|
||||
## 审核结果收集
|
||||
|
||||
每个审核子代理输出保存到:
|
||||
- `.planning/dev-workflow/reviews/review-A.md` (A审核BC)
|
||||
- `.planning/dev-workflow/reviews/review-B.md` (B审核AC)
|
||||
- `.planning/dev-workflow/reviews/review-C.md` (C审核AB)
|
||||
|
||||
## 综合方案生成
|
||||
|
||||
主代理收集所有审核意见后,生成综合方案:
|
||||
|
||||
```
|
||||
你是一个技术决策者。请基于以下信息,生成一个综合最佳方案。
|
||||
|
||||
## 原始需求
|
||||
{requirements_summary}
|
||||
|
||||
## 三个初始方案
|
||||
{all_solutions}
|
||||
|
||||
## 三份审核意见
|
||||
{all_reviews}
|
||||
|
||||
## 任务
|
||||
1. 分析每个方案的优缺点
|
||||
2. 提取各方案的亮点
|
||||
3. 融合成一个综合方案
|
||||
4. 确保综合方案覆盖所有需求
|
||||
5. 说明融合决策的理由
|
||||
|
||||
## 输出格式
|
||||
|
||||
```markdown
|
||||
# 综合技术方案
|
||||
|
||||
## 方案概述
|
||||
[综合方案的核心思路]
|
||||
|
||||
## 融合决策
|
||||
|
||||
| 决策点 | 选择来源 | 理由 |
|
||||
|--------|---------|------|
|
||||
| [决策1] | 方案A | [为什么选A] |
|
||||
| [决策2] | 方案B | [为什么选B] |
|
||||
|
||||
## 技术选型
|
||||
[最终确定的技术栈]
|
||||
|
||||
## 架构设计
|
||||
[综合后的架构]
|
||||
|
||||
## 核心模块
|
||||
[综合后的模块设计]
|
||||
|
||||
## 文件结构
|
||||
[最终的文件结构]
|
||||
|
||||
## 开发计划
|
||||
[开发步骤]
|
||||
|
||||
## 风险与应对
|
||||
[识别的风险和应对策略]
|
||||
|
||||
## 为什么这个方案最好
|
||||
[总结综合方案的优势]
|
||||
```
|
||||
|
||||
请做出明智的决策,生成最优方案。
|
||||
```
|
||||
|
||||
## 状态更新
|
||||
|
||||
```json
|
||||
{
|
||||
"phases": {
|
||||
"3": {
|
||||
"status": "completed",
|
||||
"data": {
|
||||
"reviews": ["review-A.md", "review-B.md", "review-C.md"],
|
||||
"final_solution": "final-solution.md"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,178 @@
|
||||
# Spec编排阶段 Prompt 模板
|
||||
|
||||
## 目标
|
||||
|
||||
基于确认的综合方案,生成开发规格(Spec),分析任务依赖,生成分波执行计划。
|
||||
|
||||
## Spec 生成 Prompt
|
||||
|
||||
```
|
||||
你是一个开发规划专家。请基于以下技术方案,生成详细的开发规格。
|
||||
|
||||
## 技术方案
|
||||
{final_solution}
|
||||
|
||||
## 任务
|
||||
1. 将方案拆分为独立的开发任务
|
||||
2. 每个任务要有明确的输入、输出、验收标准
|
||||
3. 分析任务之间的依赖关系
|
||||
4. 生成可并行执行的分波计划
|
||||
|
||||
## 输出格式
|
||||
|
||||
```markdown
|
||||
# 开发规格 (Development Spec)
|
||||
|
||||
## 项目概述
|
||||
{project_summary}
|
||||
|
||||
## 任务列表
|
||||
|
||||
### TASK-001: {task_name}
|
||||
|
||||
**描述**: {description}
|
||||
|
||||
**输入**:
|
||||
- {input_1}
|
||||
- {input_2}
|
||||
|
||||
**输出**:
|
||||
- {output_file_1}
|
||||
- {output_file_2}
|
||||
|
||||
**实现要点**:
|
||||
1. {point_1}
|
||||
2. {point_2}
|
||||
|
||||
**验收标准**:
|
||||
- [ ] {criteria_1}
|
||||
- [ ] {criteria_2}
|
||||
|
||||
**依赖**: TASK-XXX (如果有)
|
||||
|
||||
**预计时间**: {estimated_time}
|
||||
|
||||
**复杂度**: 低/中/高
|
||||
|
||||
---
|
||||
|
||||
### TASK-002: ...
|
||||
[重复结构]
|
||||
|
||||
---
|
||||
|
||||
## 依赖关系图
|
||||
|
||||
```
|
||||
TASK-001 (无依赖)
|
||||
↓
|
||||
TASK-002 (依赖 001)
|
||||
TASK-003 (依赖 001) ← 可并行
|
||||
↓ ↓
|
||||
TASK-004 (依赖 002, 003)
|
||||
```
|
||||
|
||||
## 分波执行计划
|
||||
|
||||
### Wave 1 (并行执行)
|
||||
- TASK-001
|
||||
|
||||
### Wave 2 (并行执行)
|
||||
- TASK-002
|
||||
- TASK-003
|
||||
|
||||
### Wave 3 (并行执行)
|
||||
- TASK-004
|
||||
|
||||
## 文件变更清单
|
||||
|
||||
| 文件路径 | 操作 | 关联任务 |
|
||||
|----------|------|----------|
|
||||
| src/main.py | 新建 | TASK-001 |
|
||||
| src/utils.py | 新建 | TASK-002 |
|
||||
|
||||
## 测试策略
|
||||
|
||||
### 单元测试
|
||||
- {test_plan}
|
||||
|
||||
### 集成测试
|
||||
- {integration_test_plan}
|
||||
|
||||
## 注意事项
|
||||
- {note_1}
|
||||
- {note_2}
|
||||
```
|
||||
|
||||
请确保每个任务足够独立,可以由不同的开发者并行完成。
|
||||
```
|
||||
|
||||
## 依赖分析规则
|
||||
|
||||
### 无依赖任务
|
||||
- 创建新文件
|
||||
- 定义数据结构
|
||||
- 编写工具函数
|
||||
|
||||
### 有依赖任务
|
||||
- 调用其他任务的输出
|
||||
- 需要其他任务创建的模块
|
||||
- 依赖其他任务的接口
|
||||
|
||||
### 分波原则
|
||||
|
||||
1. **Wave 1**: 所有无依赖的任务
|
||||
2. **Wave 2**: 只依赖 Wave 1 的任务
|
||||
3. **Wave N**: 只依赖 Wave 1..N-1 的任务
|
||||
|
||||
```python
|
||||
def analyze_dependencies(tasks: list) -> dict:
|
||||
"""分析任务依赖,生成分波计划"""
|
||||
|
||||
waves = {}
|
||||
assigned = set()
|
||||
|
||||
wave_num = 1
|
||||
while len(assigned) < len(tasks):
|
||||
# 找出所有依赖已满足的任务
|
||||
wave_tasks = []
|
||||
for task in tasks:
|
||||
if task["id"] in assigned:
|
||||
continue
|
||||
|
||||
deps = task.get("dependencies", [])
|
||||
if all(d in assigned for d in deps):
|
||||
wave_tasks.append(task["id"])
|
||||
|
||||
if not wave_tasks:
|
||||
raise Exception("检测到循环依赖")
|
||||
|
||||
waves[f"wave_{wave_num}"] = wave_tasks
|
||||
assigned.update(wave_tasks)
|
||||
wave_num += 1
|
||||
|
||||
return waves
|
||||
```
|
||||
|
||||
## 输出文件
|
||||
|
||||
- `.planning/dev-workflow/spec.md` - 开发规格
|
||||
- `.planning/dev-workflow/execution-plan.json` - 执行计划(机器可读)
|
||||
|
||||
## 状态更新
|
||||
|
||||
```json
|
||||
{
|
||||
"phases": {
|
||||
"5": {
|
||||
"status": "completed",
|
||||
"data": {
|
||||
"spec_file": "spec.md",
|
||||
"total_tasks": 10,
|
||||
"total_waves": 4,
|
||||
"execution_plan": "execution-plan.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,211 @@
|
||||
# 测试阶段 Prompt 模板
|
||||
|
||||
## 目标
|
||||
|
||||
运行项目现有测试 + 开发生成的新测试,确保代码质量。
|
||||
|
||||
## 测试流程
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ 测试阶段流程 │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ 1. 检测测试框架 │
|
||||
│ └→ pytest / jest / go test / ... │
|
||||
│ ↓ │
|
||||
│ 2. 运行现有测试 │
|
||||
│ └→ 记录结果 │
|
||||
│ ↓ │
|
||||
│ 3. 运行新增测试 │
|
||||
│ └→ 记录结果 │
|
||||
│ ↓ │
|
||||
│ ┌───────────────────────────────────────┐ │
|
||||
│ │ 测试结果 │ │
|
||||
│ ├───────────────────────────────────────┤ │
|
||||
│ │ 全部通过 → 进入下一阶段 │ │
|
||||
│ │ 有失败 → 重试(最多3次) │ │
|
||||
│ │ 超过重试 → 汇报用户 │ │
|
||||
│ └───────────────────────────────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## 测试框架检测
|
||||
|
||||
```python
|
||||
def detect_test_framework(project_root: str) -> dict:
|
||||
"""检测项目的测试框架"""
|
||||
|
||||
frameworks = []
|
||||
|
||||
# Python
|
||||
if (Path(project_root) / "pytest.ini").exists():
|
||||
frameworks.append({"name": "pytest", "command": "pytest -v", "type": "python"})
|
||||
if (Path(project_root) / "setup.py").exists():
|
||||
frameworks.append({"name": "unittest", "command": "python -m unittest", "type": "python"})
|
||||
|
||||
# JavaScript/TypeScript
|
||||
if (Path(project_root) / "jest.config.js").exists():
|
||||
frameworks.append({"name": "jest", "command": "npm test", "type": "javascript"})
|
||||
if (Path(project_root) / "vitest.config.ts").exists():
|
||||
frameworks.append({"name": "vitest", "command": "npx vitest run", "type": "javascript"})
|
||||
|
||||
# Go
|
||||
if (Path(project_root) / "go.mod").exists():
|
||||
frameworks.append({"name": "go test", "command": "go test ./...", "type": "go"})
|
||||
|
||||
return frameworks
|
||||
```
|
||||
|
||||
## 测试执行 Prompt
|
||||
|
||||
```
|
||||
你是一个测试工程师。请执行以下测试任务。
|
||||
|
||||
## 项目信息
|
||||
- 项目路径: {project_root}
|
||||
- 测试框架: {test_framework}
|
||||
|
||||
## 任务
|
||||
|
||||
1. 运行所有现有测试
|
||||
2. 运行本次开发新增的测试
|
||||
3. 记录测试结果
|
||||
4. 分析失败原因(如果有)
|
||||
|
||||
## 输出格式
|
||||
|
||||
```markdown
|
||||
# 测试报告
|
||||
|
||||
## 测试环境
|
||||
- 框架: {framework}
|
||||
- 命令: {command}
|
||||
- 执行时间: {timestamp}
|
||||
|
||||
## 测试结果摘要
|
||||
|
||||
| 类型 | 总数 | 通过 | 失败 | 跳过 |
|
||||
|------|------|------|------|------|
|
||||
| 现有测试 | {total} | {passed} | {failed} | {skipped} |
|
||||
| 新增测试 | {total} | {passed} | {failed} | {skipped} |
|
||||
|
||||
## 失败详情
|
||||
|
||||
### 失败测试 1: {test_name}
|
||||
```
|
||||
{error_message}
|
||||
```
|
||||
|
||||
**可能原因**: {analysis}
|
||||
|
||||
## 结论
|
||||
- [ ] 全部通过
|
||||
- [ ] 有失败需要修复
|
||||
|
||||
## 建议
|
||||
{recommendations}
|
||||
```
|
||||
|
||||
请执行测试并生成报告。
|
||||
```
|
||||
|
||||
## 测试结果解析
|
||||
|
||||
```python
|
||||
def parse_test_results(output: str, framework: str) -> dict:
|
||||
"""解析测试结果"""
|
||||
|
||||
if framework == "pytest":
|
||||
# 解析 pytest 输出
|
||||
import re
|
||||
match = re.search(r"(\d+) passed, (\d+) failed", output)
|
||||
if match:
|
||||
return {
|
||||
"passed": int(match.group(1)),
|
||||
"failed": int(match.group(2))
|
||||
}
|
||||
|
||||
elif framework == "jest":
|
||||
# 解析 jest 输出
|
||||
import re
|
||||
match = re.search(r"(\d+) passed, (\d+) failed", output)
|
||||
if match:
|
||||
return {
|
||||
"passed": int(match.group(1)),
|
||||
"failed": int(match.group(2))
|
||||
}
|
||||
|
||||
return {"passed": 0, "failed": 0, "raw_output": output}
|
||||
```
|
||||
|
||||
## 重试逻辑
|
||||
|
||||
```python
|
||||
def run_tests_with_retry(max_retries: int = 3) -> dict:
|
||||
"""带重试的测试执行"""
|
||||
|
||||
for attempt in range(1, max_retries + 1):
|
||||
print(f"\n尝试 {attempt}/{max_retries}...")
|
||||
|
||||
result = run_tests()
|
||||
|
||||
if result["failed"] == 0:
|
||||
print("✅ 测试全部通过")
|
||||
return result
|
||||
|
||||
print(f"⚠️ 有 {result['failed']} 个测试失败")
|
||||
|
||||
if attempt < max_retries:
|
||||
print("准备重试...")
|
||||
# 可以在这里添加自动修复逻辑
|
||||
|
||||
print(f"❌ 已达到最大重试次数 ({max_retries})")
|
||||
return result
|
||||
```
|
||||
|
||||
## 测试报告保存
|
||||
|
||||
```json
|
||||
{
|
||||
"phases": {
|
||||
"7": {
|
||||
"status": "completed",
|
||||
"test_results": {
|
||||
"framework": "pytest",
|
||||
"existing_tests": {"total": 20, "passed": 20, "failed": 0},
|
||||
"new_tests": {"total": 5, "passed": 5, "failed": 0},
|
||||
"all_passed": true,
|
||||
"retry_count": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 失败处理
|
||||
|
||||
如果测试失败且超过重试次数:
|
||||
|
||||
```
|
||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
⚠️ 测试失败
|
||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
|
||||
已重试 3 次,仍有 {failed_count} 个测试失败:
|
||||
|
||||
## 失败的测试
|
||||
1. {test_1}
|
||||
2. {test_2}
|
||||
|
||||
## 可能的原因
|
||||
{analysis}
|
||||
|
||||
## 请选择:
|
||||
A. 自动修复 - 安排子代理修复问题
|
||||
B. 手动处理 - 我来查看和修复
|
||||
C. 跳过测试 - 继续下一阶段(不推荐)
|
||||
|
||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
```
|
||||
Executable
+66
@@ -0,0 +1,66 @@
|
||||
#!/bin/bash
|
||||
# quick_test.sh - 快速验证dev-workflow基本功能
|
||||
|
||||
set -e
|
||||
|
||||
cd "$(dirname "$0")"
|
||||
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo " DEV-WORKFLOW 快速验证"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
|
||||
# 1. 检查核心文件
|
||||
echo ""
|
||||
echo "1. 检查核心文件..."
|
||||
core_files=(
|
||||
"SKILL.md"
|
||||
"state_manager.py"
|
||||
"orchestrator.py"
|
||||
"test_dev_workflow.py"
|
||||
)
|
||||
|
||||
for file in "${core_files[@]}"; do
|
||||
if [ -f "$file" ]; then
|
||||
echo " ✓ $file"
|
||||
else
|
||||
echo " ✗ $file (缺失)"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
# 2. 检查prompt模板
|
||||
echo ""
|
||||
echo "2. 检查prompt模板..."
|
||||
prompt_files=$(ls prompts/*.md 2>/dev/null | wc -l)
|
||||
if [ "$prompt_files" -ge 9 ]; then
|
||||
echo " ✓ 找到 $prompt_files 个prompt模板"
|
||||
ls prompts/*.md | while read f; do echo " - $(basename $f)"; done
|
||||
else
|
||||
echo " ✗ prompt模板数量不足: $prompt_files < 9"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 3. 运行单元测试
|
||||
echo ""
|
||||
echo "3. 运行单元测试..."
|
||||
python3 test_dev_workflow.py 2>&1 | tail -5
|
||||
|
||||
# 4. 检查SKILL.md内容
|
||||
echo ""
|
||||
echo "4. 检查SKILL.md内容..."
|
||||
if grep -q "name: dev-workflow" SKILL.md; then
|
||||
echo " ✓ 技能名称正确"
|
||||
else
|
||||
echo " ✗ 技能名称错误"
|
||||
fi
|
||||
|
||||
if grep -q "开始开发" SKILL.md; then
|
||||
echo " ✓ 触发词正确"
|
||||
else
|
||||
echo " ✗ 触发词错误"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo " ✅ 快速验证通过"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
@@ -0,0 +1,265 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
dev-workflow 状态管理工具
|
||||
|
||||
用于读写和更新 dev-workflow 的状态文件。
|
||||
|
||||
Usage:
|
||||
python3 state_manager.py --init
|
||||
python3 state_manager.py --status
|
||||
python3 state_manager.py --phase 3
|
||||
python3 state_manager.py --complete-phase 2
|
||||
python3 state_manager.py --update-phase 3 --data '{"agents": ["A", "B", "C"]}'
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
from typing import Any, Optional
|
||||
|
||||
|
||||
STATE_FILE = Path(".planning/dev-workflow/state.json")
|
||||
REQUIREMENTS_FILE = Path(".planning/dev-workflow/requirements.json")
|
||||
|
||||
|
||||
def get_state_path() -> Path:
|
||||
"""获取状态文件路径"""
|
||||
# 从当前目录向上查找项目根目录
|
||||
cwd = Path.cwd()
|
||||
while cwd != cwd.parent:
|
||||
if (cwd / ".planning").exists():
|
||||
return cwd / STATE_FILE
|
||||
cwd = cwd.parent
|
||||
return Path.cwd() / STATE_FILE
|
||||
|
||||
|
||||
def load_state() -> dict:
|
||||
"""加载状态文件"""
|
||||
state_path = get_state_path()
|
||||
if not state_path.exists():
|
||||
print(f"❌ 状态文件不存在: {state_path}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
with open(state_path, "r", encoding="utf-8") as f:
|
||||
return json.load(f)
|
||||
|
||||
|
||||
def save_state(state: dict) -> None:
|
||||
"""保存状态文件"""
|
||||
state_path = get_state_path()
|
||||
state["updated_at"] = datetime.now().isoformat()
|
||||
|
||||
state_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
with open(state_path, "w", encoding="utf-8") as f:
|
||||
json.dump(state, f, ensure_ascii=False, indent=2)
|
||||
|
||||
print(f"✅ 状态已保存: {state_path}")
|
||||
|
||||
|
||||
def init_state(project_name: str = None, trigger_message: str = None) -> dict:
|
||||
"""初始化状态文件"""
|
||||
state_path = get_state_path()
|
||||
|
||||
state = {
|
||||
"schema": "dev-workflow-state-v1",
|
||||
"project_name": project_name,
|
||||
"current_phase": 1,
|
||||
"current_stage": "头脑风暴",
|
||||
"started_at": datetime.now().isoformat(),
|
||||
"updated_at": datetime.now().isoformat(),
|
||||
"retry_count": 0,
|
||||
"max_retries": 3,
|
||||
"phases": {
|
||||
"1": {"name": "头脑风暴", "status": "in_progress", "started_at": datetime.now().isoformat()},
|
||||
"2": {"name": "方案设计", "status": "pending"},
|
||||
"3": {"name": "方案审核", "status": "pending"},
|
||||
"4": {"name": "方案汇报", "status": "pending"},
|
||||
"5": {"name": "Spec编排", "status": "pending"},
|
||||
"6": {"name": "并行开发", "status": "pending"},
|
||||
"7": {"name": "测试", "status": "pending"},
|
||||
"8": {"name": "代码审查", "status": "pending"},
|
||||
"9": {"name": "修复验证", "status": "pending"}
|
||||
},
|
||||
"context": {
|
||||
"trigger_message": trigger_message,
|
||||
"working_directory": str(Path.cwd()),
|
||||
"project_type": None
|
||||
}
|
||||
}
|
||||
|
||||
save_state(state)
|
||||
return state
|
||||
|
||||
|
||||
def get_status() -> str:
|
||||
"""获取当前状态摘要"""
|
||||
state = load_state()
|
||||
|
||||
phase = state["current_phase"]
|
||||
stage = state["current_stage"]
|
||||
started = state.get("started_at", "N/A")
|
||||
|
||||
completed = sum(1 for p in state["phases"].values() if p.get("status") == "completed")
|
||||
total = len(state["phases"])
|
||||
|
||||
status = f"""
|
||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
DEV-WORKFLOW STATUS
|
||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
|
||||
Project: {state.get("project_name", "未命名")}
|
||||
Phase: {phase}/9 - {stage}
|
||||
Progress: {completed}/{total} phases completed
|
||||
Started: {started}
|
||||
Retries: {state.get("retry_count", 0)}/{state.get("max_retries", 3)}
|
||||
|
||||
Phases:
|
||||
"""
|
||||
|
||||
for num, phase_data in state["phases"].items():
|
||||
status_icon = {
|
||||
"completed": "✓",
|
||||
"in_progress": "→",
|
||||
"pending": "○",
|
||||
"failed": "✗"
|
||||
}.get(phase_data.get("status", "pending"), "?")
|
||||
|
||||
status += f" {status_icon} Phase {num}: {phase_data['name']}\n"
|
||||
|
||||
status += "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
|
||||
return status
|
||||
|
||||
|
||||
def set_phase(phase_num: int) -> None:
|
||||
"""设置当前阶段"""
|
||||
state = load_state()
|
||||
|
||||
if str(phase_num) not in state["phases"]:
|
||||
print(f"❌ 无效的阶段: {phase_num}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
# 标记前一个阶段为完成
|
||||
current = state["current_phase"]
|
||||
if current > 0 and state["phases"][str(current)].get("status") == "in_progress":
|
||||
state["phases"][str(current)]["status"] = "completed"
|
||||
state["phases"][str(current)]["completed_at"] = datetime.now().isoformat()
|
||||
|
||||
# 设置新阶段
|
||||
state["current_phase"] = phase_num
|
||||
state["current_stage"] = state["phases"][str(phase_num)]["name"]
|
||||
state["phases"][str(phase_num)]["status"] = "in_progress"
|
||||
state["phases"][str(phase_num)]["started_at"] = datetime.now().isoformat()
|
||||
|
||||
save_state(state)
|
||||
print(f"✅ 已进入阶段 {phase_num}: {state['current_stage']}")
|
||||
|
||||
|
||||
def complete_phase(phase_num: int) -> None:
|
||||
"""标记阶段完成"""
|
||||
state = load_state()
|
||||
|
||||
if str(phase_num) not in state["phases"]:
|
||||
print(f"❌ 无效的阶段: {phase_num}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
state["phases"][str(phase_num)]["status"] = "completed"
|
||||
state["phases"][str(phase_num)]["completed_at"] = datetime.now().isoformat()
|
||||
|
||||
# 自动进入下一阶段
|
||||
next_phase = phase_num + 1
|
||||
if str(next_phase) in state["phases"]:
|
||||
state["current_phase"] = next_phase
|
||||
state["current_stage"] = state["phases"][str(next_phase)]["name"]
|
||||
state["phases"][str(next_phase)]["status"] = "pending"
|
||||
|
||||
save_state(state)
|
||||
print(f"✅ 阶段 {phase_num} 已完成")
|
||||
|
||||
|
||||
def update_phase_data(phase_num: int, data: dict) -> None:
|
||||
"""更新阶段数据"""
|
||||
state = load_state()
|
||||
|
||||
if str(phase_num) not in state["phases"]:
|
||||
print(f"❌ 无效的阶段: {phase_num}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
if "data" not in state["phases"][str(phase_num)]:
|
||||
state["phases"][str(phase_num)]["data"] = {}
|
||||
|
||||
state["phases"][str(phase_num)]["data"].update(data)
|
||||
|
||||
save_state(state)
|
||||
print(f"✅ 阶段 {phase_num} 数据已更新")
|
||||
|
||||
|
||||
def increment_retry() -> bool:
|
||||
"""增加重试计数,返回是否还可以继续重试"""
|
||||
state = load_state()
|
||||
state["retry_count"] = state.get("retry_count", 0) + 1
|
||||
|
||||
max_retries = state.get("max_retries", 3)
|
||||
can_retry = state["retry_count"] < max_retries
|
||||
|
||||
save_state(state)
|
||||
|
||||
if can_retry:
|
||||
print(f"⚠️ 重试 {state['retry_count']}/{max_retries}")
|
||||
else:
|
||||
print(f"❌ 已达到最大重试次数 ({max_retries})")
|
||||
|
||||
return can_retry
|
||||
|
||||
|
||||
def reset_retry() -> None:
|
||||
"""重置重试计数"""
|
||||
state = load_state()
|
||||
state["retry_count"] = 0
|
||||
save_state(state)
|
||||
print("✅ 重试计数已重置")
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="dev-workflow 状态管理工具")
|
||||
|
||||
parser.add_argument("--init", action="store_true", help="初始化状态文件")
|
||||
parser.add_argument("--status", action="store_true", help="显示当前状态")
|
||||
parser.add_argument("--phase", type=int, metavar="N", help="设置当前阶段")
|
||||
parser.add_argument("--complete-phase", type=int, metavar="N", help="标记阶段完成")
|
||||
parser.add_argument("--update-phase", type=int, metavar="N", help="更新阶段数据")
|
||||
parser.add_argument("--data", type=str, help="JSON 数据 (与 --update-phase 配合)")
|
||||
parser.add_argument("--retry", action="store_true", help="增加重试计数")
|
||||
parser.add_argument("--reset-retry", action="store_true", help="重置重试计数")
|
||||
parser.add_argument("--project-name", type=str, help="项目名称 (与 --init 配合)")
|
||||
parser.add_argument("--trigger", type=str, help="触发消息 (与 --init 配合)")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.init:
|
||||
init_state(args.project_name, args.trigger)
|
||||
elif args.status:
|
||||
print(get_status())
|
||||
elif args.phase:
|
||||
set_phase(args.phase)
|
||||
elif args.complete_phase:
|
||||
complete_phase(args.complete_phase)
|
||||
elif args.update_phase:
|
||||
if not args.data:
|
||||
print("❌ 需要提供 --data 参数", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
update_phase_data(args.update_phase, json.loads(args.data))
|
||||
elif args.retry:
|
||||
increment_retry()
|
||||
elif args.reset_retry:
|
||||
reset_retry()
|
||||
else:
|
||||
parser.print_help()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,189 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
dev-workflow 单元测试
|
||||
|
||||
测试状态管理和编排器的基本功能。
|
||||
"""
|
||||
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
import tempfile
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
# 添加模块路径
|
||||
sys.path.insert(0, str(Path(__file__).parent))
|
||||
|
||||
from state_manager import (
|
||||
init_state,
|
||||
load_state,
|
||||
save_state,
|
||||
set_phase,
|
||||
complete_phase,
|
||||
update_phase_data,
|
||||
increment_retry,
|
||||
reset_retry
|
||||
)
|
||||
|
||||
|
||||
class TestStateManager(unittest.TestCase):
|
||||
"""测试状态管理器"""
|
||||
|
||||
def setUp(self):
|
||||
"""设置测试环境"""
|
||||
self.temp_dir = tempfile.mkdtemp()
|
||||
self.state_file = Path(self.temp_dir) / ".planning" / "dev-workflow" / "state.json"
|
||||
self.state_file.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# 切换到临时目录
|
||||
self.original_cwd = os.getcwd()
|
||||
os.chdir(self.temp_dir)
|
||||
|
||||
def tearDown(self):
|
||||
"""清理测试环境"""
|
||||
os.chdir(self.original_cwd)
|
||||
import shutil
|
||||
shutil.rmtree(self.temp_dir)
|
||||
|
||||
def test_init_state(self):
|
||||
"""测试初始化状态"""
|
||||
state = init_state(
|
||||
project_name="测试项目",
|
||||
trigger_message="开始开发测试功能"
|
||||
)
|
||||
|
||||
self.assertEqual(state["project_name"], "测试项目")
|
||||
self.assertEqual(state["current_phase"], 1)
|
||||
self.assertEqual(state["current_stage"], "头脑风暴")
|
||||
self.assertEqual(state["phases"]["1"]["status"], "in_progress")
|
||||
self.assertIn("trigger_message", state["context"])
|
||||
|
||||
def test_set_phase(self):
|
||||
"""测试设置阶段"""
|
||||
init_state("测试项目", "测试")
|
||||
|
||||
set_phase(3)
|
||||
state = load_state()
|
||||
|
||||
self.assertEqual(state["current_phase"], 3)
|
||||
self.assertEqual(state["current_stage"], "方案审核")
|
||||
self.assertEqual(state["phases"]["3"]["status"], "in_progress")
|
||||
self.assertEqual(state["phases"]["1"]["status"], "completed")
|
||||
|
||||
def test_complete_phase(self):
|
||||
"""测试完成阶段"""
|
||||
init_state("测试项目", "测试")
|
||||
|
||||
complete_phase(1)
|
||||
state = load_state()
|
||||
|
||||
self.assertEqual(state["phases"]["1"]["status"], "completed")
|
||||
self.assertIn("completed_at", state["phases"]["1"])
|
||||
self.assertEqual(state["current_phase"], 2)
|
||||
|
||||
def test_update_phase_data(self):
|
||||
"""测试更新阶段数据"""
|
||||
init_state("测试项目", "测试")
|
||||
|
||||
update_phase_data(1, {"questions_asked": 5, "collected": True})
|
||||
state = load_state()
|
||||
|
||||
self.assertEqual(state["phases"]["1"]["data"]["questions_asked"], 5)
|
||||
self.assertEqual(state["phases"]["1"]["data"]["collected"], True)
|
||||
|
||||
def test_retry_logic(self):
|
||||
"""测试重试逻辑"""
|
||||
init_state("测试项目", "测试")
|
||||
|
||||
# 第一次重试
|
||||
can_retry = increment_retry()
|
||||
self.assertTrue(can_retry)
|
||||
state = load_state()
|
||||
self.assertEqual(state["retry_count"], 1)
|
||||
|
||||
# 重置
|
||||
reset_retry()
|
||||
state = load_state()
|
||||
self.assertEqual(state["retry_count"], 0)
|
||||
|
||||
def test_max_retries(self):
|
||||
"""测试最大重试次数"""
|
||||
init_state("测试项目", "测试")
|
||||
|
||||
# 连续重试
|
||||
for i in range(3):
|
||||
can_retry = increment_retry()
|
||||
if i < 2:
|
||||
self.assertTrue(can_retry)
|
||||
else:
|
||||
self.assertFalse(can_retry)
|
||||
|
||||
|
||||
class TestOrchestrator(unittest.TestCase):
|
||||
"""测试编排器"""
|
||||
|
||||
def setUp(self):
|
||||
"""设置测试环境"""
|
||||
self.temp_dir = tempfile.mkdtemp()
|
||||
self.original_cwd = os.getcwd()
|
||||
os.chdir(self.temp_dir)
|
||||
|
||||
def tearDown(self):
|
||||
"""清理测试环境"""
|
||||
os.chdir(self.original_cwd)
|
||||
import shutil
|
||||
shutil.rmtree(self.temp_dir)
|
||||
|
||||
def test_orchestrator_init(self):
|
||||
"""测试编排器初始化"""
|
||||
from orchestrator import DevWorkflowOrchestrator
|
||||
|
||||
orchestrator = DevWorkflowOrchestrator()
|
||||
orchestrator.initialize("开始开发测试功能", "测试项目")
|
||||
|
||||
# 检查目录结构
|
||||
planning_dir = Path(".planning/dev-workflow")
|
||||
self.assertTrue(planning_dir.exists())
|
||||
self.assertTrue((planning_dir / "solutions").exists())
|
||||
self.assertTrue((planning_dir / "reviews").exists())
|
||||
self.assertTrue((planning_dir / "development").exists())
|
||||
self.assertTrue((planning_dir / "code-review").exists())
|
||||
|
||||
def test_phase_transitions(self):
|
||||
"""测试阶段转换"""
|
||||
from orchestrator import DevWorkflowOrchestrator
|
||||
|
||||
orchestrator = DevWorkflowOrchestrator()
|
||||
orchestrator.initialize("开始开发测试功能", "测试项目")
|
||||
|
||||
# 测试各阶段方法存在
|
||||
self.assertTrue(hasattr(orchestrator, 'run_phase_1'))
|
||||
self.assertTrue(hasattr(orchestrator, 'run_phase_2'))
|
||||
self.assertTrue(hasattr(orchestrator, 'run_phase_9'))
|
||||
|
||||
|
||||
class TestSKILLDocumentation(unittest.TestCase):
|
||||
"""测试SKILL.md文档"""
|
||||
|
||||
def test_skill_md_exists(self):
|
||||
"""测试SKILL.md存在"""
|
||||
skill_md = Path(__file__).parent / "SKILL.md"
|
||||
self.assertTrue(skill_md.exists(), "SKILL.md should exist")
|
||||
|
||||
def test_skill_md_content(self):
|
||||
"""测试SKILL.md内容"""
|
||||
skill_md = Path(__file__).parent / "SKILL.md"
|
||||
content = skill_md.read_text()
|
||||
|
||||
# 检查必要内容
|
||||
self.assertIn("name: dev-workflow", content)
|
||||
self.assertIn("开始开发", content)
|
||||
self.assertIn("9阶段", content)
|
||||
self.assertIn("头脑风暴", content)
|
||||
self.assertIn("方案设计", content)
|
||||
self.assertIn("代码审查", content)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main(verbosity=2)
|
||||
Reference in New Issue
Block a user