kiro-spec-engine 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +60 -0
- package/LICENSE +21 -0
- package/README.md +242 -0
- package/README.zh.md +242 -0
- package/bin/kiro-spec-engine.js +229 -0
- package/lib/commands/doctor.js +59 -0
- package/lib/i18n.js +79 -0
- package/lib/python-checker.js +209 -0
- package/locales/en.json +114 -0
- package/locales/zh.json +114 -0
- package/package.json +78 -0
- package/template/.kiro/README.md +288 -0
- package/template/.kiro/specs/SPEC_WORKFLOW_GUIDE.md +134 -0
- package/template/.kiro/steering/CORE_PRINCIPLES.md +140 -0
- package/template/.kiro/steering/CURRENT_CONTEXT.md +85 -0
- package/template/.kiro/steering/ENVIRONMENT.md +115 -0
- package/template/.kiro/steering/RULES_GUIDE.md +46 -0
- package/template/.kiro/tools/ultrawork_enhancer.py +676 -0
- package/template/README.md +109 -0
|
@@ -0,0 +1,676 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Ultrawork Enhancer - 为 Kiro Spec 体系注入 Sisyphus 的不懈努力精神
|
|
4
|
+
|
|
5
|
+
核心理念: 像西西弗斯推石上山一样,永不放弃,不懈努力,直到任务完美完成
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import re
|
|
9
|
+
import os
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
from typing import List, Dict, Tuple, Optional
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class UltraworkEnhancer:
|
|
15
|
+
"""
|
|
16
|
+
Ultrawork 增强器 - 在 Kiro Spec 体系中实现 Sisyphus 的不懈努力精神
|
|
17
|
+
|
|
18
|
+
不是替代现有工具,而是增强执行质量和完成度
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
def __init__(self):
|
|
22
|
+
self.quality_threshold = 9.0 # 专业级质量标准 (0-10)
|
|
23
|
+
self.max_iterations = 10 # 防止无限循环
|
|
24
|
+
self.improvement_log = [] # 记录改进过程
|
|
25
|
+
self.language = None # 文档语言 (zh/en), 自动检测
|
|
26
|
+
|
|
27
|
+
# ==================== 语言检测 ====================
|
|
28
|
+
|
|
29
|
+
def _detect_language(self, content: str) -> str:
|
|
30
|
+
"""
|
|
31
|
+
检测文档语言
|
|
32
|
+
返回: 'zh' (中文) 或 'en' (英文)
|
|
33
|
+
"""
|
|
34
|
+
# 统计中文字符数量
|
|
35
|
+
chinese_chars = len(re.findall(r'[\u4e00-\u9fff]', content))
|
|
36
|
+
# 统计英文单词数量
|
|
37
|
+
english_words = len(re.findall(r'\b[a-zA-Z]+\b', content))
|
|
38
|
+
|
|
39
|
+
# 如果中文字符超过100个,判定为中文
|
|
40
|
+
if chinese_chars > 100:
|
|
41
|
+
return 'zh'
|
|
42
|
+
# 如果英文单词超过中文字符的3倍,判定为英文
|
|
43
|
+
elif english_words > chinese_chars * 3:
|
|
44
|
+
return 'en'
|
|
45
|
+
# 默认中文
|
|
46
|
+
return 'zh'
|
|
47
|
+
|
|
48
|
+
# ==================== Requirements 阶段 Ultrawork ====================
|
|
49
|
+
|
|
50
|
+
def enhance_requirements_quality(self, requirements_path: str) -> Dict:
|
|
51
|
+
"""
|
|
52
|
+
Requirements 阶段的 Ultrawork 增强
|
|
53
|
+
|
|
54
|
+
像资深产品经理一样深入思考每个用户场景
|
|
55
|
+
"""
|
|
56
|
+
print("🔥 启动 Requirements 阶段 Ultrawork 增强...")
|
|
57
|
+
|
|
58
|
+
if not os.path.exists(requirements_path):
|
|
59
|
+
return {"error": "Requirements 文件不存在"}
|
|
60
|
+
|
|
61
|
+
with open(requirements_path, 'r', encoding='utf-8') as f:
|
|
62
|
+
content = f.read()
|
|
63
|
+
|
|
64
|
+
# 检测语言
|
|
65
|
+
self.language = self._detect_language(content)
|
|
66
|
+
print(f"📝 检测到文档语言: {'中文' if self.language == 'zh' else 'English'}")
|
|
67
|
+
|
|
68
|
+
# 评估当前质量
|
|
69
|
+
quality_score = self._assess_requirements_quality(content)
|
|
70
|
+
print(f"📊 Requirements 质量评分: {quality_score}/10")
|
|
71
|
+
|
|
72
|
+
if quality_score >= self.quality_threshold:
|
|
73
|
+
print("✅ Requirements 已达到专业级标准! Ultrawork 精神得到体现!")
|
|
74
|
+
return {
|
|
75
|
+
"success": True,
|
|
76
|
+
"iterations": 0,
|
|
77
|
+
"final_quality_score": quality_score,
|
|
78
|
+
"message": "文档质量已达到专业级标准,无需进一步改进"
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
iteration = 0
|
|
82
|
+
original_content = content
|
|
83
|
+
|
|
84
|
+
while iteration < self.max_iterations:
|
|
85
|
+
# 识别改进点
|
|
86
|
+
improvements = self._identify_requirements_improvements(content)
|
|
87
|
+
|
|
88
|
+
if not improvements:
|
|
89
|
+
print("⚠️ 无法识别更多改进点,停止迭代")
|
|
90
|
+
break
|
|
91
|
+
|
|
92
|
+
# 应用改进 (Ultrawork 精神: 不懈努力)
|
|
93
|
+
content = self._apply_requirements_improvements(content, improvements)
|
|
94
|
+
iteration += 1
|
|
95
|
+
|
|
96
|
+
# 重新评估质量
|
|
97
|
+
new_quality_score = self._assess_requirements_quality(content)
|
|
98
|
+
|
|
99
|
+
# 记录改进过程
|
|
100
|
+
self.improvement_log.append({
|
|
101
|
+
"stage": "requirements",
|
|
102
|
+
"iteration": iteration,
|
|
103
|
+
"improvements": improvements,
|
|
104
|
+
"quality_score": new_quality_score
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
print(f"🔄 第 {iteration} 轮改进: {', '.join(improvements)}")
|
|
108
|
+
print(f"📊 改进后质量评分: {new_quality_score}/10")
|
|
109
|
+
|
|
110
|
+
# 检查是否达到质量标准
|
|
111
|
+
if new_quality_score >= self.quality_threshold:
|
|
112
|
+
print("✅ Requirements 已达到专业级标准!")
|
|
113
|
+
break
|
|
114
|
+
|
|
115
|
+
# 检查是否有实际改进
|
|
116
|
+
if new_quality_score <= quality_score:
|
|
117
|
+
print("⚠️ 质量评分未提升,停止迭代")
|
|
118
|
+
break
|
|
119
|
+
|
|
120
|
+
quality_score = new_quality_score
|
|
121
|
+
|
|
122
|
+
# 如果有改进,更新文件
|
|
123
|
+
if content != original_content:
|
|
124
|
+
with open(requirements_path, 'w', encoding='utf-8') as f:
|
|
125
|
+
f.write(content)
|
|
126
|
+
print(f"📝 Requirements 已更新,共进行 {iteration} 轮 Ultrawork 改进")
|
|
127
|
+
|
|
128
|
+
return {
|
|
129
|
+
"success": True,
|
|
130
|
+
"iterations": iteration,
|
|
131
|
+
"final_quality_score": self._assess_requirements_quality(content),
|
|
132
|
+
"improvements_applied": self.improvement_log
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
def _assess_requirements_quality(self, content: str) -> float:
|
|
136
|
+
"""评估 Requirements 文档质量 (0-10) - 支持中英文"""
|
|
137
|
+
score = 0.0
|
|
138
|
+
lang = self.language or self._detect_language(content)
|
|
139
|
+
|
|
140
|
+
if lang == 'zh':
|
|
141
|
+
# 中文评分标准
|
|
142
|
+
# 基础结构检查 (2分)
|
|
143
|
+
if "## 1. 概述" in content or "## Introduction" in content: score += 0.5
|
|
144
|
+
if "## 2. 用户故事" in content: score += 0.5
|
|
145
|
+
if "## 3. 功能需求" in content: score += 0.5
|
|
146
|
+
if "## 4. 非功能需求" in content: score += 0.5
|
|
147
|
+
|
|
148
|
+
# EARS 格式检查 (2分)
|
|
149
|
+
ears_patterns = len(re.findall(r'WHEN.*THEN', content, re.IGNORECASE))
|
|
150
|
+
score += min(ears_patterns * 0.2, 2.0)
|
|
151
|
+
|
|
152
|
+
# 用户故事质量 (2分)
|
|
153
|
+
user_story_patterns = len(re.findall(r'作为.*我希望.*以便', content))
|
|
154
|
+
score += min(user_story_patterns * 0.3, 2.0)
|
|
155
|
+
|
|
156
|
+
# 验收标准完整性 (2分)
|
|
157
|
+
acceptance_criteria = len(re.findall(r'\*\*验收标准\*\*:', content))
|
|
158
|
+
score += min(acceptance_criteria * 0.4, 2.0)
|
|
159
|
+
|
|
160
|
+
# 非功能需求覆盖 (1分)
|
|
161
|
+
nfr_keywords = ['性能', '安全', '可用性', '可维护性', '兼容性']
|
|
162
|
+
nfr_coverage = sum(1 for keyword in nfr_keywords if keyword in content)
|
|
163
|
+
score += min(nfr_coverage * 0.2, 1.0)
|
|
164
|
+
|
|
165
|
+
# 约束条件 (1分)
|
|
166
|
+
if "约束条件" in content or "限制" in content:
|
|
167
|
+
score += 1.0
|
|
168
|
+
else:
|
|
169
|
+
# 英文评分标准
|
|
170
|
+
# 基础结构检查 (2分)
|
|
171
|
+
if "## Introduction" in content or "## Overview" in content: score += 0.5
|
|
172
|
+
if "## Glossary" in content or "## Terminology" in content: score += 0.5
|
|
173
|
+
if "## Requirements" in content or "## Functional Requirements" in content: score += 0.5
|
|
174
|
+
if "Non-functional" in content or "Non-Functional" in content: score += 0.5
|
|
175
|
+
|
|
176
|
+
# EARS 格式检查 (2分)
|
|
177
|
+
ears_patterns = len(re.findall(r'WHEN.*THEN|IF.*THEN', content, re.IGNORECASE))
|
|
178
|
+
score += min(ears_patterns * 0.15, 2.0)
|
|
179
|
+
|
|
180
|
+
# 用户故事质量 (2分)
|
|
181
|
+
user_story_patterns = len(re.findall(r'As a.*I want.*So that', content, re.IGNORECASE))
|
|
182
|
+
score += min(user_story_patterns * 0.25, 2.0)
|
|
183
|
+
|
|
184
|
+
# 验收标准完整性 (2分)
|
|
185
|
+
acceptance_criteria = len(re.findall(r'Acceptance Criteria|#### Acceptance Criteria', content, re.IGNORECASE))
|
|
186
|
+
score += min(acceptance_criteria * 0.3, 2.0)
|
|
187
|
+
|
|
188
|
+
# 非功能需求覆盖 (1分)
|
|
189
|
+
nfr_keywords = ['performance', 'security', 'usability', 'maintainability', 'compatibility', 'scalability']
|
|
190
|
+
nfr_coverage = sum(1 for keyword in nfr_keywords if keyword.lower() in content.lower())
|
|
191
|
+
score += min(nfr_coverage * 0.15, 1.0)
|
|
192
|
+
|
|
193
|
+
# 约束条件 (1分)
|
|
194
|
+
if "constraint" in content.lower() or "limitation" in content.lower():
|
|
195
|
+
score += 1.0
|
|
196
|
+
|
|
197
|
+
return min(score, 10.0)
|
|
198
|
+
|
|
199
|
+
def _identify_requirements_improvements(self, content: str) -> List[str]:
|
|
200
|
+
"""识别 Requirements 文档的改进点 - 支持中英文"""
|
|
201
|
+
improvements = []
|
|
202
|
+
lang = self.language or self._detect_language(content)
|
|
203
|
+
|
|
204
|
+
if lang == 'zh':
|
|
205
|
+
# 中文改进建议
|
|
206
|
+
if "## 1. 概述" not in content and "## Introduction" not in content:
|
|
207
|
+
improvements.append("添加项目概述章节")
|
|
208
|
+
|
|
209
|
+
if "## 2. 用户故事" not in content:
|
|
210
|
+
improvements.append("添加用户故事章节")
|
|
211
|
+
|
|
212
|
+
if "## 4. 非功能需求" not in content:
|
|
213
|
+
improvements.append("添加非功能需求章节")
|
|
214
|
+
|
|
215
|
+
# 检查 EARS 格式
|
|
216
|
+
if len(re.findall(r'WHEN.*THEN', content, re.IGNORECASE)) < 5:
|
|
217
|
+
improvements.append("增加更多 EARS 格式的验收标准 (WHEN...THEN)")
|
|
218
|
+
|
|
219
|
+
# 检查用户故事格式
|
|
220
|
+
if len(re.findall(r'作为.*我希望.*以便', content)) < 3:
|
|
221
|
+
improvements.append("完善用户故事格式 (作为...我希望...以便)")
|
|
222
|
+
|
|
223
|
+
# 检查非功能需求覆盖
|
|
224
|
+
nfr_keywords = ['性能需求', '安全需求', '可用性需求', '可维护性需求']
|
|
225
|
+
missing_nfr = []
|
|
226
|
+
for kw in nfr_keywords:
|
|
227
|
+
if kw not in content:
|
|
228
|
+
missing_nfr.append(kw.replace('需求', ''))
|
|
229
|
+
|
|
230
|
+
if missing_nfr and "## 4. 非功能需求" in content:
|
|
231
|
+
improvements.append(f"补充非功能需求: {', '.join(missing_nfr)}")
|
|
232
|
+
else:
|
|
233
|
+
# 英文改进建议
|
|
234
|
+
if "## Introduction" not in content and "## Overview" not in content:
|
|
235
|
+
improvements.append("Add Introduction or Overview section")
|
|
236
|
+
|
|
237
|
+
if "## Glossary" not in content and "## Terminology" not in content:
|
|
238
|
+
improvements.append("Add Glossary section to define key terms")
|
|
239
|
+
|
|
240
|
+
if "User Story" not in content and "user story" not in content:
|
|
241
|
+
improvements.append("Add User Stories section")
|
|
242
|
+
|
|
243
|
+
# 检查 EARS 格式
|
|
244
|
+
ears_count = len(re.findall(r'WHEN.*THEN|IF.*THEN', content, re.IGNORECASE))
|
|
245
|
+
if ears_count < 5:
|
|
246
|
+
improvements.append(f"Add more EARS-format acceptance criteria (currently {ears_count}, target 5+)")
|
|
247
|
+
|
|
248
|
+
# 检查用户故事格式
|
|
249
|
+
user_story_count = len(re.findall(r'As a.*I want.*So that', content, re.IGNORECASE))
|
|
250
|
+
if user_story_count < 3:
|
|
251
|
+
improvements.append(f"Add more user stories in 'As a...I want...So that' format (currently {user_story_count}, target 3+)")
|
|
252
|
+
|
|
253
|
+
# 检查非功能需求
|
|
254
|
+
nfr_keywords = ['performance', 'security', 'usability', 'maintainability', 'scalability']
|
|
255
|
+
missing_nfr = [kw for kw in nfr_keywords if kw.lower() not in content.lower()]
|
|
256
|
+
|
|
257
|
+
if missing_nfr and len(missing_nfr) > 2:
|
|
258
|
+
improvements.append(f"Add non-functional requirements: {', '.join(missing_nfr[:3])}")
|
|
259
|
+
|
|
260
|
+
return improvements
|
|
261
|
+
|
|
262
|
+
def _apply_requirements_improvements(self, content: str, improvements: List[str]) -> str:
|
|
263
|
+
"""应用 Requirements 改进 (这里是示例,实际需要更复杂的逻辑)"""
|
|
264
|
+
# 这里只是示例实现,实际应该根据具体改进点进行相应修改
|
|
265
|
+
improved_content = content
|
|
266
|
+
|
|
267
|
+
for improvement in improvements:
|
|
268
|
+
if "添加非功能需求章节" in improvement:
|
|
269
|
+
if "## 4. 非功能需求" not in improved_content:
|
|
270
|
+
improved_content += "\n\n## 4. 非功能需求\n\n### 4.1 性能需求\n- 系统响应时间应小于 2 秒\n\n### 4.2 安全需求\n- 用户数据必须加密存储\n\n### 4.3 可用性需求\n- 系统可用性应达到 99.9%\n"
|
|
271
|
+
|
|
272
|
+
return improved_content
|
|
273
|
+
|
|
274
|
+
# ==================== Design 阶段 Ultrawork ====================
|
|
275
|
+
|
|
276
|
+
def enhance_design_completeness(self, design_path: str, requirements_path: str) -> Dict:
|
|
277
|
+
"""
|
|
278
|
+
Design 阶段的 Ultrawork 增强
|
|
279
|
+
|
|
280
|
+
像资深架构师一样设计每个组件
|
|
281
|
+
"""
|
|
282
|
+
print("🔥 启动 Design 阶段 Ultrawork 增强...")
|
|
283
|
+
|
|
284
|
+
if not os.path.exists(design_path):
|
|
285
|
+
return {"error": "Design 文件不存在"}
|
|
286
|
+
|
|
287
|
+
if not os.path.exists(requirements_path):
|
|
288
|
+
return {"error": "Requirements 文件不存在,无法进行双向追溯"}
|
|
289
|
+
|
|
290
|
+
with open(design_path, 'r', encoding='utf-8') as f:
|
|
291
|
+
design_content = f.read()
|
|
292
|
+
|
|
293
|
+
with open(requirements_path, 'r', encoding='utf-8') as f:
|
|
294
|
+
requirements_content = f.read()
|
|
295
|
+
|
|
296
|
+
# 检测语言
|
|
297
|
+
self.language = self._detect_language(design_content)
|
|
298
|
+
print(f"📝 检测到文档语言: {'中文' if self.language == 'zh' else 'English'}")
|
|
299
|
+
|
|
300
|
+
iteration = 0
|
|
301
|
+
original_content = design_content
|
|
302
|
+
|
|
303
|
+
while iteration < self.max_iterations:
|
|
304
|
+
# 评估当前质量
|
|
305
|
+
quality_score = self._assess_design_quality(design_content, requirements_content)
|
|
306
|
+
print(f"📊 Design 质量评分: {quality_score}/10")
|
|
307
|
+
|
|
308
|
+
if quality_score >= self.quality_threshold:
|
|
309
|
+
print("✅ Design 已达到专业级标准!")
|
|
310
|
+
break
|
|
311
|
+
|
|
312
|
+
# 识别改进点
|
|
313
|
+
improvements = self._identify_design_improvements(design_content, requirements_content)
|
|
314
|
+
|
|
315
|
+
if not improvements:
|
|
316
|
+
print("⚠️ 无法识别更多改进点,停止迭代")
|
|
317
|
+
break
|
|
318
|
+
|
|
319
|
+
# 应用改进 (Ultrawork 精神: 不懈努力)
|
|
320
|
+
design_content = self._apply_design_improvements(design_content, improvements)
|
|
321
|
+
iteration += 1
|
|
322
|
+
|
|
323
|
+
# 记录改进过程
|
|
324
|
+
self.improvement_log.append({
|
|
325
|
+
"stage": "design",
|
|
326
|
+
"iteration": iteration,
|
|
327
|
+
"improvements": improvements,
|
|
328
|
+
"quality_score": quality_score
|
|
329
|
+
})
|
|
330
|
+
|
|
331
|
+
print(f"🔄 第 {iteration} 轮改进: {', '.join(improvements)}")
|
|
332
|
+
|
|
333
|
+
# 如果有改进,更新文件
|
|
334
|
+
if design_content != original_content:
|
|
335
|
+
with open(design_path, 'w', encoding='utf-8') as f:
|
|
336
|
+
f.write(design_content)
|
|
337
|
+
print(f"📝 Design 已更新,共进行 {iteration} 轮 Ultrawork 改进")
|
|
338
|
+
|
|
339
|
+
return {
|
|
340
|
+
"success": True,
|
|
341
|
+
"iterations": iteration,
|
|
342
|
+
"final_quality_score": self._assess_design_quality(design_content, requirements_content),
|
|
343
|
+
"improvements_applied": self.improvement_log
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
def _assess_design_quality(self, design_content: str, requirements_content: str) -> float:
|
|
347
|
+
"""评估 Design 文档质量 (0-10) - 支持中英文"""
|
|
348
|
+
score = 0.0
|
|
349
|
+
lang = self.language or self._detect_language(design_content)
|
|
350
|
+
|
|
351
|
+
if lang == 'zh':
|
|
352
|
+
# 中文评分标准
|
|
353
|
+
# 基础结构检查 (2分)
|
|
354
|
+
if "## 1. 系统概述" in design_content or "## 1. 概述" in design_content or "## Overview" in design_content: score += 0.5
|
|
355
|
+
if "## 2. 架构设计" in design_content or "## Architecture" in design_content: score += 0.5
|
|
356
|
+
if "## 3. 组件设计" in design_content or "## Components" in design_content: score += 0.5
|
|
357
|
+
if "## 4. 数据流设计" in design_content or "## 4. 接口设计" in design_content: score += 0.5
|
|
358
|
+
|
|
359
|
+
# 需求追溯性检查 (2分)
|
|
360
|
+
req_references = len(re.findall(r'需求\s*\d+\.\d+|Requirements?\s*\d+\.\d+|Requirement\s+\d+\.\d+', design_content, re.IGNORECASE))
|
|
361
|
+
score += min(req_references * 0.2, 2.0)
|
|
362
|
+
|
|
363
|
+
# 架构图和设计图 (1.5分)
|
|
364
|
+
diagram_indicators = len(re.findall(r'```mermaid|```plantuml|架构图|设计图|流程图', design_content))
|
|
365
|
+
score += min(diagram_indicators * 0.5, 1.5)
|
|
366
|
+
|
|
367
|
+
# 技术选型说明 (1.5分)
|
|
368
|
+
tech_keywords = ['技术选型', '技术栈', '框架选择', '数据库', 'API', '协议']
|
|
369
|
+
tech_coverage = sum(1 for keyword in tech_keywords if keyword in design_content)
|
|
370
|
+
score += min(tech_coverage * 0.25, 1.5)
|
|
371
|
+
|
|
372
|
+
# 非功能需求设计 (1.5分)
|
|
373
|
+
nfr_design = ['性能设计', '安全设计', '可扩展性', '容错机制', '监控']
|
|
374
|
+
nfr_coverage = sum(1 for keyword in nfr_design if keyword in design_content)
|
|
375
|
+
score += min(nfr_coverage * 0.3, 1.5)
|
|
376
|
+
|
|
377
|
+
# 接口定义完整性 (1.5分)
|
|
378
|
+
interface_indicators = len(re.findall(r'接口定义|API\s*设计|数据结构|参数说明', design_content))
|
|
379
|
+
score += min(interface_indicators * 0.4, 1.5)
|
|
380
|
+
else:
|
|
381
|
+
# 英文评分标准
|
|
382
|
+
# 基础结构检查 (2分)
|
|
383
|
+
if "## Overview" in design_content or "## Introduction" in design_content: score += 0.5
|
|
384
|
+
if "## Architecture" in design_content or "## System Architecture" in design_content: score += 0.5
|
|
385
|
+
if "## Components" in design_content or "## Component" in design_content: score += 0.5
|
|
386
|
+
if "## Interface" in design_content or "## Data Flow" in design_content or "## API" in design_content: score += 0.5
|
|
387
|
+
|
|
388
|
+
# 需求追溯性检查 (2分)
|
|
389
|
+
req_references = len(re.findall(r'Requirement[s]?\s+\d+\.\d+|_Requirements:\s+\d+\.\d+|Validates:\s+Requirements?\s+\d+\.\d+', design_content, re.IGNORECASE))
|
|
390
|
+
score += min(req_references * 0.15, 2.0)
|
|
391
|
+
|
|
392
|
+
# 架构图和设计图 (1.5分)
|
|
393
|
+
diagram_indicators = len(re.findall(r'```mermaid|```plantuml|```diagram|Architecture Diagram|Component Diagram', design_content, re.IGNORECASE))
|
|
394
|
+
score += min(diagram_indicators * 0.4, 1.5)
|
|
395
|
+
|
|
396
|
+
# 技术选型说明 (1.5分)
|
|
397
|
+
tech_keywords = ['technology', 'framework', 'database', 'api', 'protocol', 'stack', 'library']
|
|
398
|
+
tech_coverage = sum(1 for keyword in tech_keywords if keyword.lower() in design_content.lower())
|
|
399
|
+
score += min(tech_coverage * 0.2, 1.5)
|
|
400
|
+
|
|
401
|
+
# 非功能需求设计 (1.5分)
|
|
402
|
+
nfr_design = ['performance', 'security', 'scalability', 'fault tolerance', 'monitoring', 'error handling']
|
|
403
|
+
nfr_coverage = sum(1 for keyword in nfr_design if keyword.lower() in design_content.lower())
|
|
404
|
+
score += min(nfr_coverage * 0.25, 1.5)
|
|
405
|
+
|
|
406
|
+
# 接口定义完整性 (1.5分)
|
|
407
|
+
interface_indicators = len(re.findall(r'Interface|API\s+Design|Data\s+Model|Data\s+Structure|Parameter', design_content, re.IGNORECASE))
|
|
408
|
+
score += min(interface_indicators * 0.3, 1.5)
|
|
409
|
+
|
|
410
|
+
return min(score, 10.0)
|
|
411
|
+
|
|
412
|
+
def _identify_design_improvements(self, design_content: str, requirements_content: str) -> List[str]:
|
|
413
|
+
"""识别 Design 文档的改进点"""
|
|
414
|
+
improvements = []
|
|
415
|
+
|
|
416
|
+
# 检查基础结构
|
|
417
|
+
if "## 1. 系统概述" not in design_content and "## 1. 概述" not in design_content:
|
|
418
|
+
improvements.append("添加系统概述章节")
|
|
419
|
+
|
|
420
|
+
if "## 2. 架构设计" not in design_content:
|
|
421
|
+
improvements.append("添加架构设计章节")
|
|
422
|
+
|
|
423
|
+
if "## 3. 组件设计" not in design_content:
|
|
424
|
+
improvements.append("添加组件设计章节")
|
|
425
|
+
|
|
426
|
+
# 检查需求追溯
|
|
427
|
+
req_references = len(re.findall(r'需求\s*\d+\.\d+|Requirements?\s*\d+\.\d+', design_content))
|
|
428
|
+
if req_references < 3:
|
|
429
|
+
improvements.append("增加需求到设计的双向追溯")
|
|
430
|
+
|
|
431
|
+
# 检查架构图
|
|
432
|
+
if "```mermaid" not in design_content and "架构图" not in design_content:
|
|
433
|
+
improvements.append("添加架构图或设计图")
|
|
434
|
+
|
|
435
|
+
# 检查技术选型
|
|
436
|
+
tech_keywords = ['技术选型', '技术栈', '框架选择']
|
|
437
|
+
if not any(keyword in design_content for keyword in tech_keywords):
|
|
438
|
+
improvements.append("补充技术选型说明")
|
|
439
|
+
|
|
440
|
+
# 检查非功能需求设计
|
|
441
|
+
nfr_design = ['性能设计', '安全设计', '可扩展性']
|
|
442
|
+
missing_nfr = [nfr for nfr in nfr_design if nfr not in design_content]
|
|
443
|
+
if missing_nfr:
|
|
444
|
+
improvements.append(f"补充非功能需求设计: {', '.join(missing_nfr)}")
|
|
445
|
+
|
|
446
|
+
return improvements
|
|
447
|
+
|
|
448
|
+
def _apply_design_improvements(self, content: str, improvements: List[str]) -> str:
|
|
449
|
+
"""应用 Design 改进"""
|
|
450
|
+
improved_content = content
|
|
451
|
+
|
|
452
|
+
for improvement in improvements:
|
|
453
|
+
if "添加架构图或设计图" in improvement:
|
|
454
|
+
if "```mermaid" not in improved_content:
|
|
455
|
+
improved_content += "\n\n### 系统架构图\n\n```mermaid\ngraph TB\n A[用户界面] --> B[业务逻辑层]\n B --> C[数据访问层]\n C --> D[数据存储]\n```\n"
|
|
456
|
+
|
|
457
|
+
if "补充技术选型说明" in improvement:
|
|
458
|
+
if "技术选型" not in improved_content:
|
|
459
|
+
improved_content += "\n\n## 技术选型\n\n### 核心技术栈\n- 前端: React/Vue.js\n- 后端: Node.js/Python\n- 数据库: PostgreSQL/MongoDB\n- 缓存: Redis\n\n### 选型理由\n- 考虑团队技术栈熟悉度\n- 满足性能和扩展性要求\n- 社区支持和生态完善\n"
|
|
460
|
+
|
|
461
|
+
return improved_content
|
|
462
|
+
|
|
463
|
+
# ==================== Tasks 阶段 Ultrawork ====================
|
|
464
|
+
|
|
465
|
+
def enhance_task_execution(self, tasks_path: str) -> Dict:
|
|
466
|
+
"""
|
|
467
|
+
Tasks 阶段的 Ultrawork 增强
|
|
468
|
+
|
|
469
|
+
像资深开发者一样实现每行代码,遇到困难不放弃
|
|
470
|
+
"""
|
|
471
|
+
print("🔥 启动 Tasks 阶段 Ultrawork 增强...")
|
|
472
|
+
|
|
473
|
+
if not os.path.exists(tasks_path):
|
|
474
|
+
return {"error": "Tasks 文件不存在"}
|
|
475
|
+
|
|
476
|
+
with open(tasks_path, 'r', encoding='utf-8') as f:
|
|
477
|
+
content = f.read()
|
|
478
|
+
|
|
479
|
+
# 分析任务完成情况
|
|
480
|
+
task_analysis = self._analyze_task_completion(content)
|
|
481
|
+
|
|
482
|
+
if task_analysis['incomplete_count'] == 0:
|
|
483
|
+
return {
|
|
484
|
+
"success": True,
|
|
485
|
+
"message": "✅ 所有任务已完成! Ultrawork 精神得到完美体现!",
|
|
486
|
+
"task_analysis": task_analysis
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
print(f"📋 任务完成情况分析:")
|
|
490
|
+
print(f" - 总任务数: {task_analysis['total_count']}")
|
|
491
|
+
print(f" - 已完成: {task_analysis['completed_count']}")
|
|
492
|
+
print(f" - 进行中: {task_analysis['in_progress_count']}")
|
|
493
|
+
print(f" - 未开始: {task_analysis['not_started_count']}")
|
|
494
|
+
print(f" - 完成率: {task_analysis['completion_rate']:.1f}%")
|
|
495
|
+
|
|
496
|
+
# Ultrawork 精神: 不懈努力提醒
|
|
497
|
+
ultrawork_messages = self._generate_ultrawork_reminders(task_analysis)
|
|
498
|
+
|
|
499
|
+
for message in ultrawork_messages:
|
|
500
|
+
print(f"🔥 {message}")
|
|
501
|
+
|
|
502
|
+
# 识别阻塞任务和优先级
|
|
503
|
+
priority_tasks = self._identify_priority_tasks(task_analysis['incomplete_tasks'])
|
|
504
|
+
|
|
505
|
+
return {
|
|
506
|
+
"success": True,
|
|
507
|
+
"message": f"发现 {task_analysis['incomplete_count']} 个未完成任务,需要继续推进",
|
|
508
|
+
"task_analysis": task_analysis,
|
|
509
|
+
"priority_tasks": priority_tasks,
|
|
510
|
+
"ultrawork_reminders": ultrawork_messages,
|
|
511
|
+
"next_actions": self._suggest_next_actions(task_analysis)
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
def _analyze_task_completion(self, content: str) -> Dict:
|
|
515
|
+
"""分析任务完成情况"""
|
|
516
|
+
# 匹配不同状态的任务
|
|
517
|
+
completed_tasks = re.findall(r'- \[x\] (.+)', content)
|
|
518
|
+
in_progress_tasks = re.findall(r'- \[-\] (.+)', content)
|
|
519
|
+
not_started_tasks = re.findall(r'- \[ \] (.+)', content)
|
|
520
|
+
queued_tasks = re.findall(r'- \[~\] (.+)', content)
|
|
521
|
+
|
|
522
|
+
total_count = len(completed_tasks) + len(in_progress_tasks) + len(not_started_tasks) + len(queued_tasks)
|
|
523
|
+
completed_count = len(completed_tasks)
|
|
524
|
+
incomplete_count = len(in_progress_tasks) + len(not_started_tasks) + len(queued_tasks)
|
|
525
|
+
|
|
526
|
+
completion_rate = (completed_count / total_count * 100) if total_count > 0 else 0
|
|
527
|
+
|
|
528
|
+
return {
|
|
529
|
+
"total_count": total_count,
|
|
530
|
+
"completed_count": completed_count,
|
|
531
|
+
"completed_tasks": completed_tasks,
|
|
532
|
+
"in_progress_count": len(in_progress_tasks),
|
|
533
|
+
"in_progress_tasks": in_progress_tasks,
|
|
534
|
+
"not_started_count": len(not_started_tasks),
|
|
535
|
+
"not_started_tasks": not_started_tasks,
|
|
536
|
+
"queued_count": len(queued_tasks),
|
|
537
|
+
"queued_tasks": queued_tasks,
|
|
538
|
+
"incomplete_count": incomplete_count,
|
|
539
|
+
"incomplete_tasks": in_progress_tasks + not_started_tasks + queued_tasks,
|
|
540
|
+
"completion_rate": completion_rate
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
def _generate_ultrawork_reminders(self, task_analysis: Dict) -> List[str]:
|
|
544
|
+
"""生成 Ultrawork 精神提醒"""
|
|
545
|
+
reminders = []
|
|
546
|
+
|
|
547
|
+
completion_rate = task_analysis['completion_rate']
|
|
548
|
+
|
|
549
|
+
if completion_rate == 0:
|
|
550
|
+
reminders.append("Sisyphus 精神: 万事开头难,但永不放弃! 开始推动第一块石头!")
|
|
551
|
+
elif completion_rate < 30:
|
|
552
|
+
reminders.append("Sisyphus 精神: 石头刚开始滚动,保持动力,持续推进!")
|
|
553
|
+
elif completion_rate < 70:
|
|
554
|
+
reminders.append("Sisyphus 精神: 已经爬到半山腰,不能松懈,继续向山顶冲刺!")
|
|
555
|
+
elif completion_rate < 95:
|
|
556
|
+
reminders.append("Sisyphus 精神: 接近山顶了,最后的冲刺最关键,不懈努力!")
|
|
557
|
+
else:
|
|
558
|
+
reminders.append("Sisyphus 精神: 即将登顶,每个细节都要完美,追求卓越!")
|
|
559
|
+
|
|
560
|
+
if task_analysis['in_progress_count'] > 0:
|
|
561
|
+
reminders.append(f"有 {task_analysis['in_progress_count']} 个任务正在进行中,保持专注,逐个击破!")
|
|
562
|
+
|
|
563
|
+
if task_analysis['not_started_count'] > 3:
|
|
564
|
+
reminders.append("任务较多,但不要被数量吓倒,分解执行,每完成一个都是胜利!")
|
|
565
|
+
|
|
566
|
+
return reminders
|
|
567
|
+
|
|
568
|
+
def _identify_priority_tasks(self, incomplete_tasks: List[str]) -> List[Dict]:
|
|
569
|
+
"""识别优先级任务"""
|
|
570
|
+
priority_tasks = []
|
|
571
|
+
|
|
572
|
+
for i, task in enumerate(incomplete_tasks):
|
|
573
|
+
priority = "normal"
|
|
574
|
+
reasons = []
|
|
575
|
+
|
|
576
|
+
# 基于关键词判断优先级
|
|
577
|
+
high_priority_keywords = ['基础', '核心', '关键', '重要', '阻塞', '依赖']
|
|
578
|
+
urgent_keywords = ['紧急', '立即', '马上', '优先']
|
|
579
|
+
|
|
580
|
+
task_lower = task.lower()
|
|
581
|
+
|
|
582
|
+
if any(keyword in task for keyword in high_priority_keywords):
|
|
583
|
+
priority = "high"
|
|
584
|
+
reasons.append("包含关键词")
|
|
585
|
+
|
|
586
|
+
if any(keyword in task for keyword in urgent_keywords):
|
|
587
|
+
priority = "urgent"
|
|
588
|
+
reasons.append("标记为紧急")
|
|
589
|
+
|
|
590
|
+
# 基于任务编号判断(假设编号小的更基础)
|
|
591
|
+
if re.match(r'^\d+\.\d+', task) and task.startswith(('1.', '2.')):
|
|
592
|
+
if priority == "normal":
|
|
593
|
+
priority = "high"
|
|
594
|
+
reasons.append("基础任务")
|
|
595
|
+
|
|
596
|
+
priority_tasks.append({
|
|
597
|
+
"task": task,
|
|
598
|
+
"priority": priority,
|
|
599
|
+
"reasons": reasons,
|
|
600
|
+
"index": i
|
|
601
|
+
})
|
|
602
|
+
|
|
603
|
+
# 按优先级排序
|
|
604
|
+
priority_order = {"urgent": 0, "high": 1, "normal": 2}
|
|
605
|
+
priority_tasks.sort(key=lambda x: priority_order[x["priority"]])
|
|
606
|
+
|
|
607
|
+
return priority_tasks
|
|
608
|
+
|
|
609
|
+
def _suggest_next_actions(self, task_analysis: Dict) -> List[str]:
|
|
610
|
+
"""建议下一步行动"""
|
|
611
|
+
suggestions = []
|
|
612
|
+
|
|
613
|
+
if task_analysis['in_progress_count'] > 0:
|
|
614
|
+
suggestions.append("优先完成进行中的任务,避免任务切换成本")
|
|
615
|
+
|
|
616
|
+
if task_analysis['not_started_count'] > 0:
|
|
617
|
+
suggestions.append("从最基础或最重要的未开始任务开始")
|
|
618
|
+
|
|
619
|
+
if task_analysis['completion_rate'] < 50:
|
|
620
|
+
suggestions.append("建议专注于单个任务,避免并行过多任务")
|
|
621
|
+
else:
|
|
622
|
+
suggestions.append("可以考虑并行处理独立的任务以提高效率")
|
|
623
|
+
|
|
624
|
+
suggestions.append("每完成一个任务立即更新状态,保持进度可见性")
|
|
625
|
+
suggestions.append("遇到困难时体现 Ultrawork 精神: 不放弃,寻找替代方案")
|
|
626
|
+
|
|
627
|
+
return suggestions
|
|
628
|
+
|
|
629
|
+
# ==================== 通用工具方法 ====================
|
|
630
|
+
|
|
631
|
+
def get_improvement_log(self) -> List[Dict]:
|
|
632
|
+
"""获取改进日志"""
|
|
633
|
+
return self.improvement_log
|
|
634
|
+
|
|
635
|
+
def reset_log(self):
|
|
636
|
+
"""重置改进日志"""
|
|
637
|
+
self.improvement_log = []
|
|
638
|
+
|
|
639
|
+
def set_quality_threshold(self, threshold: float):
|
|
640
|
+
"""设置质量阈值"""
|
|
641
|
+
self.quality_threshold = max(0.0, min(10.0, threshold))
|
|
642
|
+
|
|
643
|
+
|
|
644
|
+
def main():
|
|
645
|
+
"""命令行工具入口"""
|
|
646
|
+
import sys
|
|
647
|
+
|
|
648
|
+
if len(sys.argv) < 2:
|
|
649
|
+
print("用法: python ultrawork_enhancer.py <command> [args]")
|
|
650
|
+
print("命令:")
|
|
651
|
+
print(" requirements <path> - 增强 Requirements 文档质量")
|
|
652
|
+
print(" design <design_path> <requirements_path> - 增强 Design 文档完整性")
|
|
653
|
+
print(" tasks <path> - 检查 Tasks 完成情况")
|
|
654
|
+
return
|
|
655
|
+
|
|
656
|
+
enhancer = UltraworkEnhancer()
|
|
657
|
+
command = sys.argv[1]
|
|
658
|
+
|
|
659
|
+
if command == "requirements" and len(sys.argv) >= 3:
|
|
660
|
+
result = enhancer.enhance_requirements_quality(sys.argv[2])
|
|
661
|
+
print(f"结果: {result}")
|
|
662
|
+
|
|
663
|
+
elif command == "design" and len(sys.argv) >= 4:
|
|
664
|
+
result = enhancer.enhance_design_completeness(sys.argv[2], sys.argv[3])
|
|
665
|
+
print(f"结果: {result}")
|
|
666
|
+
|
|
667
|
+
elif command == "tasks" and len(sys.argv) >= 3:
|
|
668
|
+
result = enhancer.enhance_task_execution(sys.argv[2])
|
|
669
|
+
print(f"结果: {result}")
|
|
670
|
+
|
|
671
|
+
else:
|
|
672
|
+
print("❌ 无效的命令或参数")
|
|
673
|
+
|
|
674
|
+
|
|
675
|
+
if __name__ == "__main__":
|
|
676
|
+
main()
|