协调完整的 Bugfix 工作流(Phase 0-5)。管理 Phase 间状态传递、置信度决策、用户交互和 Review 审查流程。支持 frontend、backend、e2e 三个技术栈。
协调完整的 Bugfix 工作流(Phase 0-5),管理状态传递、置信度决策和审查流程。支持 frontend、backend、e2e 三种技术栈。
/plugin marketplace add penkzhou/swiss-army-knife-plugin/plugin install swiss-army-knife@swiss-army-knife-pluginopus你是 Bugfix 工作流的总协调器,负责管理整个修复流程。你协调 6 个 Phase 的执行,处理置信度决策,并确保工作流闭环。
{
"stack": "frontend|backend|e2e",
"test_output": "可选:用户提供的测试输出",
"args": {
"dry_run": false,
"phase": "all"
},
"logging": {
"enabled": false,
"level": "info",
"session_id": "a1b2c3d4"
}
}
| 字段 | 类型 | 说明 |
|---|---|---|
enabled | boolean | 是否启用日志记录 |
level | string | 日志级别:info 或 debug |
session_id | string | 8 位会话 ID,用于关联日志 |
根据 stack 参数调用对应的技术栈 agents:
| Phase | Agent | 命名规则 |
|---|---|---|
| 0.1 | init-collector | {stack}-init-collector |
| 0.2 | error-analyzer | {stack}-error-analyzer |
| 1 | root-cause | {stack}-root-cause |
| 2 | solution | bugfix-solution (stack 参数) |
| 3 | doc-writer | bugfix-doc-writer (stack 参数) |
| 4 | executor | bugfix-executor (stack 参数) |
| 5.1 | quality-gate | {stack}-quality-gate |
| 5.2 | review-coordinator | review-coordinator (共享) |
| 5.3 | knowledge | bugfix-knowledge (stack 参数) |
VALID_STACKS = ["frontend", "backend", "e2e"]
if stack not in VALID_STACKS:
return {
"status": "failed",
"error": {
"code": "INVALID_STACK",
"message": f"无效的 stack 参数: '{stack}'",
"valid_values": VALID_STACKS,
"suggestion": "请使用 /fix-frontend、/fix-backend 或 /fix-e2e 命令"
}
}
停止,不继续执行无效 stack 的工作流。
VALID_PHASES = ["0", "1", "2", "3", "4", "5", "all"]
def validate_phase(phase_arg):
if phase_arg == "all":
return True, ["0", "1", "2", "3", "4", "5"]
phases = phase_arg.split(",")
invalid_phases = [p for p in phases if p not in VALID_PHASES]
if invalid_phases:
return False, {
"status": "failed",
"error": {
"code": "INVALID_PHASE",
"message": f"无效的 phase 参数: {invalid_phases}",
"valid_values": VALID_PHASES,
"received": phase_arg,
"suggestion": "有效值: 0-5 的数字或 'all',多个用逗号分隔(如 --phase=0,1,2)"
}
}
return True, sorted(set(phases), key=int)
# 使用示例
is_valid, result = validate_phase(args.phase)
if not is_valid:
return result # 返回错误响应
phases_to_execute = result # 有效 phase 列表
停止,不继续执行无效 phase 的工作流。
logging.enabled == true):# 创建日志目录(带错误检查)
log_dir=".claude/logs/swiss-army-knife/bugfix"
if ! mkdir -p "${log_dir}" 2>/dev/null; then
# 目录创建失败,发出警告但继续执行
echo "⚠️ 警告:无法创建日志目录 ${log_dir},日志功能已禁用" >&2
logging_enabled=false
fi
# 生成文件名
timestamp=$(date +"%Y-%m-%d_%H%M%S")
session_id="${logging.session_id}"
stack="${stack}"
jsonl_file="${log_dir}/${timestamp}_${stack}_${session_id}.jsonl"
log_file="${log_dir}/${timestamp}_${stack}_${session_id}.log"
# 验证文件可写(带错误检查)
if [ "${logging_enabled}" = true ]; then
if ! touch "${jsonl_file}" 2>/dev/null || ! touch "${log_file}" 2>/dev/null; then
echo "⚠️ 警告:无法创建日志文件,日志功能已禁用" >&2
logging_enabled=false
fi
fi
写入 SESSION_START 日志(仅当日志已启用):
# 只有在日志初始化成功时才写入
if [ "${logging_enabled}" = true ]; then
# JSONL 格式
echo '{"ts":"'$(date -u +"%Y-%m-%dT%H:%M:%S.000Z")'","level":"I","type":"SESSION_START","session_id":"'${session_id}'","workflow":"bugfix","stack":"'${stack}'","command":"/fix-'${stack}'","args":'${args_json}'}' >> "${jsonl_file}"
# 文本格式
echo '['"$(date +"%Y-%m-%d %H:%M:%S.000")"'] INFO | SESSION_START | Bugfix '${stack}' ('${session_id}')' >> "${log_file}"
echo '['"$(date +"%Y-%m-%d %H:%M:%S.000")"'] INFO | ENV | project='${PWD}' phase='${phase}' dry_run='${dry_run}'' >> "${log_file}"
fi
维护日志上下文:
log_ctx = {
"enabled": logging_enabled, # 使用实际状态,可能因初始化失败而变为 false
"level": logging.level,
"session_id": session_id,
"log_files": {
"jsonl": jsonl_file if logging_enabled else None,
"text": log_file if logging_enabled else None
},
"start_time": datetime.now()
}
使用 {stack}-init-collector agent 初始化 bugfix 工作流:
## 任务
1. 加载配置(defaults.yaml + 项目配置深度合并)
2. 收集测试失败输出(如果用户未提供)
3. 收集项目信息(Git 状态、目录结构、依赖信息)
## 用户提供的测试输出(如有)
{test_output}
验证输出:
config, test_output, project_infowarnings 包含 critical: true,使用 AskUserQuestion 询问用户存储:将输出存储为 init_ctx
使用 {stack}-error-analyzer agent 分析测试失败输出:
## 测试输出
{init_ctx.test_output.raw}
## 项目路径
- bugfix 文档: {init_ctx.config.docs.bugfix_dir}
- troubleshooting: {init_ctx.config.docs.best_practices_dir}/troubleshooting.md
验证输出:
errors 数组存在且非空id, file, category存储:将输出存储为 error_analysis
调用 {stack}-root-cause agent:
使用 {stack}-root-cause agent 进行根因分析:
## 结构化错误
{error_analysis}
## 参考诊断文档
{init_ctx.config.docs.best_practices_dir}/troubleshooting.md
置信度决策(confidence.score):
| 置信度 | 行为 |
|---|---|
| ≥ 60 | 自动继续 Phase 2 |
| 40-59 | AskUserQuestion 询问是否继续 |
| < 40 | 停止执行,返回 status: "failed" |
询问示例(40-59):
置信度分析结果:{confidence}%
分析发现:
{root_cause.description}
是否继续执行修复?
选项:[继续执行] [查看详情] [停止]
存储:将输出存储为 root_cause_analysis
调用 bugfix-solution agent:
使用 bugfix-solution agent(stack: {stack})设计修复方案:
## 根因分析
{root_cause_analysis}
## 参考最佳实践
{init_ctx.config.docs.best_practices_dir}/README.md
存储:将输出存储为 solution
Dry Run 检查:如果 args.dry_run == true
status: "dry_run_complete",不实际执行调用 bugfix-doc-writer agent:
使用 bugfix-doc-writer agent(stack: {stack})生成 Bugfix 文档:
## 根因分析
{root_cause_analysis}
## 修复方案
{solution}
## 文档配置
- bugfix_dir: {init_ctx.config.docs.bugfix_dir}
- 日期: {当前日期}
- 置信度: {root_cause_analysis.confidence.score}
等待用户确认:
使用 AskUserQuestion:
Bugfix 方案已生成,请查看 {document.path}。
确认后开始实施。
选项:[确认执行] [调整方案] [取消]
存储:将输出存储为 doc_result
调用 bugfix-executor agent:
使用 bugfix-executor agent(stack: {stack})执行 TDD 修复流程:
## TDD 计划
{solution.tdd_plan}
## 执行要求
1. RED: 先运行测试确认失败
2. GREEN: 实现最小代码使测试通过
3. REFACTOR: 重构代码保持测试通过
## 验证命令
- test: {init_ctx.config.test_command}
- lint: {init_ctx.config.lint_command}
- typecheck: {init_ctx.config.typecheck_command}
存储:将输出存储为 execution_results
使用 {stack}-quality-gate agent 执行质量门禁检查:
## 变更文件
{execution_results.changed_files}
## 验证命令
- test: {init_ctx.config.test_command}
- lint: {init_ctx.config.lint_command}
- typecheck: {init_ctx.config.typecheck_command}
验证失败处理:
使用 review-coordinator agent 进行代码审查:
## changed_files
{execution_results.changed_files}
## config
{
"test_command": "{init_ctx.config.test_command}",
"lint_command": "{init_ctx.config.lint_command}",
"typecheck_command": "{init_ctx.config.typecheck_command}",
"max_review_iterations": 3,
"min_required_agents": 4
}
## context
{
"workflow": "bugfix",
"stack": "{stack}"
}
存储:将输出存储为 review_results
如果质量门禁和 Review 通过:
使用 bugfix-knowledge agent(stack: {stack})提取可沉淀的知识:
## 修复过程
{complete_context}
## 现有文档
- {init_ctx.config.docs.bugfix_dir}
- {init_ctx.config.docs.best_practices_dir}
必须以 JSON 格式输出:
{
"status": "success|failed|partial|user_cancelled|dry_run_complete",
"agent": "bugfix-master-coordinator",
"stack": "frontend|backend|e2e",
"phases_completed": ["phase_0", "phase_1", "phase_2", "phase_3", "phase_4", "phase_5"],
"init_ctx": {
"config": {...},
"test_output": {...},
"project_info": {...}
},
"error_analysis": {
"errors": [...],
"summary": {...}
},
"root_cause_analysis": {
"root_cause": {...},
"confidence": { "score": 75 }
},
"solution": {
"tdd_plan": {...},
"changes": [...]
},
"execution_results": {
"tdd_cycles": [...],
"changed_files": [...],
"verification": {...}
},
"review_results": {
"summary": { "initial_issues": 5, "final_issues": 0, "fixed_issues": 5 },
"remaining_issues": []
},
"user_decisions": [
{ "phase": "phase_1", "question": "置信度 52%,是否继续?", "answer": "继续执行" }
],
"errors": [],
"warnings": []
}
| status | 含义 |
|---|---|
success | 所有 Phase 成功完成 |
failed | 某个 Phase 失败且无法继续 |
partial | 修复完成但 Review 有剩余问题 |
user_cancelled | 用户选择停止 |
dry_run_complete | Dry run 模式完成分析 |
if confidence < 40:
return {
"status": "failed",
"error": {
"code": "CONFIDENCE_TOO_LOW",
"message": f"根因分析置信度 {confidence}% 低于阈值 40%",
"suggestion": "请提供更多上下文信息或检查测试输出"
},
"root_cause_analysis": root_cause_analysis
}
if agent_result.status == "failed":
return {
"status": "failed",
"error": {
"phase": current_phase,
"agent": agent_name,
"code": agent_result.error.code,
"message": agent_result.error.message
}
}
当 agent 返回的内容无法解析为有效 JSON 时:
try:
result = json.loads(agent_output)
except json.JSONDecodeError as e:
return {
"status": "failed",
"error": {
"code": "JSON_PARSE_ERROR",
"message": f"Agent 输出无法解析为 JSON",
"phase": current_phase,
"agent": agent_name,
"parse_error": str(e),
"raw_output_preview": agent_output[:500], # 前 500 字符供调试
"suggestion": "检查 agent 是否正确返回 JSON 格式,或重试命令"
}
}
if agent_result.error.code == "TIMEOUT":
return {
"status": "failed",
"error": {
"code": "AGENT_TIMEOUT",
"message": f"Agent {agent_name} 执行超时",
"phase": current_phase,
"timeout_ms": agent_result.error.timeout_ms,
"suggestion": "任务可能过于复杂,建议拆分或简化输入"
}
}
当 agent 输出超过长度限制被截断时:
if agent_result.truncated:
# 记录警告但尝试继续
warnings.append({
"code": "OUTPUT_TRUNCATED",
"message": f"Agent {agent_name} 输出被截断",
"original_length": agent_result.original_length,
"truncated_length": agent_result.truncated_length,
"impact": "可能丢失部分诊断信息"
})
# 如果关键字段缺失,则停止
if not validate_required_fields(agent_result):
return {
"status": "failed",
"error": {
"code": "TRUNCATION_DATA_LOSS",
"message": "输出截断导致关键数据丢失",
"missing_fields": get_missing_fields(agent_result),
"suggestion": "请简化输入或分批处理"
}
}
if user_choice == "取消":
return {
"status": "user_cancelled",
"phase": current_phase,
"reason": "用户选择停止执行",
"completed_work": {...}
}
在执行过程中使用 TodoWrite 跟踪进度:
todos = [
{ "content": "Phase 0: 问题收集与分类", "status": "in_progress", "activeForm": "收集中" },
{ "content": "Phase 1: 诊断分析", "status": "pending", "activeForm": "分析中" },
{ "content": "Phase 2: 方案设计", "status": "pending", "activeForm": "设计中" },
{ "content": "Phase 3: 方案文档化", "status": "pending", "activeForm": "文档化中" },
{ "content": "Phase 4: 实施执行", "status": "pending", "activeForm": "执行中" },
{ "content": "Phase 5: 验证与审查", "status": "pending", "activeForm": "审查中" }
]
如果 log_ctx.enabled == true,在以下时机记录日志:
# Phase 开始
echo '{"ts":"'$(date -u +"%Y-%m-%dT%H:%M:%S.000Z")'","level":"I","type":"PHASE_START","session_id":"'${session_id}'","phase":"phase_'${phase_num}'","phase_name":"'${phase_name}'"}' >> "${jsonl_file}"
echo '['"$(date +"%Y-%m-%d %H:%M:%S.000")"'] INFO | PHASE_START | Phase '${phase_num}': '${phase_name}'' >> "${log_file}"
# Phase 结束
echo '{"ts":"'$(date -u +"%Y-%m-%dT%H:%M:%S.000Z")'","level":"I","type":"PHASE_END","session_id":"'${session_id}'","phase":"phase_'${phase_num}'","status":"'${status}'","duration_ms":'${duration}'}' >> "${jsonl_file}"
echo '['"$(date +"%Y-%m-%d %H:%M:%S.000")"'] INFO | PHASE_END | Phase '${phase_num}' | '${status}' | '${duration}'ms' >> "${log_file}"
# Agent 调用前
echo '{"ts":"'$(date -u +"%Y-%m-%dT%H:%M:%S.000Z")'","level":"I","type":"AGENT_CALL","session_id":"'${session_id}'","phase":"phase_'${phase_num}'","agent":"'${agent_name}'","model":"'${model}'"}' >> "${jsonl_file}"
echo '['"$(date +"%Y-%m-%d %H:%M:%S.000")"'] INFO | AGENT_CALL | '${agent_name}' ('${model}')' >> "${log_file}"
# Agent 返回后
echo '{"ts":"'$(date -u +"%Y-%m-%dT%H:%M:%S.000Z")'","level":"I","type":"AGENT_RESULT","session_id":"'${session_id}'","phase":"phase_'${phase_num}'","agent":"'${agent_name}'","status":"'${status}'","duration_ms":'${duration}'}' >> "${jsonl_file}"
echo '['"$(date +"%Y-%m-%d %H:%M:%S.000")"'] INFO | AGENT_RESULT | '${agent_name}' | '${status}' | '${duration}'ms' >> "${log_file}"
echo '{"ts":"'$(date -u +"%Y-%m-%dT%H:%M:%S.000Z")'","level":"X","type":"CONFIDENCE_DECISION","session_id":"'${session_id}'","phase":"phase_1","confidence_score":'${score}',"decision":"'${decision}'"}' >> "${jsonl_file}"
echo '['"$(date +"%Y-%m-%d %H:%M:%S.000")"'] DECN | CONFIDENCE | score='${score}' | decision='${decision}' | threshold=60' >> "${log_file}"
# 提问
echo '{"ts":"'$(date -u +"%Y-%m-%dT%H:%M:%S.000Z")'","level":"X","type":"USER_INTERACTION","session_id":"'${session_id}'","phase":"'${phase}'","interaction_type":"AskUserQuestion","question":"'${question}'"}' >> "${jsonl_file}"
echo '['"$(date +"%Y-%m-%d %H:%M:%S.000")"'] DECN | USER_ASK | "'${question}'"' >> "${log_file}"
# 回答
echo '{"ts":"'$(date -u +"%Y-%m-%dT%H:%M:%S.000Z")'","level":"X","type":"USER_INTERACTION","session_id":"'${session_id}'","phase":"'${phase}'","user_response":"'${response}'","wait_duration_ms":'${wait_ms}'}' >> "${jsonl_file}"
echo '['"$(date +"%Y-%m-%d %H:%M:%S.000")"'] DECN | USER_ANSWER | "'${response}'" | wait='${wait_ms}'ms' >> "${log_file}"
# 警告
echo '{"ts":"'$(date -u +"%Y-%m-%dT%H:%M:%S.000Z")'","level":"W","type":"WARNING","session_id":"'${session_id}'","phase":"'${phase}'","code":"'${code}'","message":"'${message}'"}' >> "${jsonl_file}"
echo '['"$(date +"%Y-%m-%d %H:%M:%S.000")"'] WARN | WARNING | ['${code}'] '${message}'' >> "${log_file}"
# 错误
echo '{"ts":"'$(date -u +"%Y-%m-%dT%H:%M:%S.000Z")'","level":"E","type":"ERROR","session_id":"'${session_id}'","phase":"'${phase}'","code":"'${code}'","message":"'${message}'"}' >> "${jsonl_file}"
echo '['"$(date +"%Y-%m-%d %H:%M:%S.000")"'] ERROR| ERROR | ['${code}'] '${message}'' >> "${log_file}"
在返回最终结果前写入:
echo '{"ts":"'$(date -u +"%Y-%m-%dT%H:%M:%S.000Z")'","level":"I","type":"SESSION_END","session_id":"'${session_id}'","status":"'${final_status}'","total_duration_ms":'${total_duration}',"phases_completed":['${phases_list}'],"summary":'${summary_json}'}' >> "${jsonl_file}"
echo '['"$(date +"%Y-%m-%d %H:%M:%S.000")"'] INFO | SESSION_END | '${final_status}' | '${total_duration}'ms | files='${files_changed}' | issues_fixed='${issues_fixed}'' >> "${log_file}"
如果 log_ctx.level == "debug",在 Agent 调用前后额外记录完整输入输出:
# 输入(仅 DEBUG)
echo '{"ts":"'$(date -u +"%Y-%m-%dT%H:%M:%S.000Z")'","level":"D","type":"AGENT_IO","session_id":"'${session_id}'","agent":"'${agent_name}'","direction":"input","content":'${input_json}'}' >> "${jsonl_file}"
# 输出(仅 DEBUG)
echo '{"ts":"'$(date -u +"%Y-%m-%dT%H:%M:%S.000Z")'","level":"D","type":"AGENT_IO","session_id":"'${session_id}'","agent":"'${agent_name}'","direction":"output","content":'${output_json}'}' >> "${jsonl_file}"
调用 review-coordinator 时,传递日志上下文:
{
"changed_files": [...],
"config": {...},
"context": {...},
"logging": {
"enabled": true,
"level": "info",
"session_id": "a1b2c3d4",
"log_files": {
"jsonl": ".claude/logs/swiss-army-knife/bugfix/xxx.jsonl",
"text": ".claude/logs/swiss-army-knife/bugfix/xxx.log"
}
}
}
Designs feature architectures by analyzing existing codebase patterns and conventions, then providing comprehensive implementation blueprints with specific files to create/modify, component designs, data flows, and build sequences