kiro-spec-engine 1.2.3 → 1.3.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 +74 -0
- package/README.md +172 -0
- package/bin/kiro-spec-engine.js +62 -0
- package/docs/agent-hooks-analysis.md +815 -0
- package/docs/cross-tool-guide.md +554 -0
- package/docs/manual-workflows-guide.md +417 -0
- package/docs/steering-strategy-guide.md +196 -0
- package/lib/adoption/detection-engine.js +14 -4
- package/lib/commands/adopt.js +117 -3
- package/lib/commands/context.js +99 -0
- package/lib/commands/prompt.js +105 -0
- package/lib/commands/status.js +225 -0
- package/lib/commands/task.js +199 -0
- package/lib/commands/watch.js +569 -0
- package/lib/commands/workflows.js +240 -0
- package/lib/commands/workspace.js +189 -0
- package/lib/context/context-exporter.js +378 -0
- package/lib/context/prompt-generator.js +482 -0
- package/lib/steering/adoption-config.js +164 -0
- package/lib/steering/steering-manager.js +289 -0
- package/lib/task/task-claimer.js +430 -0
- package/lib/utils/tool-detector.js +383 -0
- package/lib/watch/action-executor.js +458 -0
- package/lib/watch/event-debouncer.js +323 -0
- package/lib/watch/execution-logger.js +550 -0
- package/lib/watch/file-watcher.js +499 -0
- package/lib/watch/presets.js +266 -0
- package/lib/watch/watch-manager.js +533 -0
- package/lib/workspace/workspace-manager.js +370 -0
- package/lib/workspace/workspace-sync.js +356 -0
- package/package.json +3 -1
- package/template/.kiro/tools/backup_manager.py +295 -0
- package/template/.kiro/tools/configuration_manager.py +218 -0
- package/template/.kiro/tools/document_evaluator.py +550 -0
- package/template/.kiro/tools/enhancement_logger.py +168 -0
- package/template/.kiro/tools/error_handler.py +335 -0
- package/template/.kiro/tools/improvement_identifier.py +444 -0
- package/template/.kiro/tools/modification_applicator.py +737 -0
- package/template/.kiro/tools/quality_gate_enforcer.py +207 -0
- package/template/.kiro/tools/quality_scorer.py +305 -0
- package/template/.kiro/tools/report_generator.py +154 -0
- package/template/.kiro/tools/ultrawork_enhancer_refactored.py +0 -0
- package/template/.kiro/tools/ultrawork_enhancer_v2.py +463 -0
- package/template/.kiro/tools/ultrawork_enhancer_v3.py +606 -0
- package/template/.kiro/tools/workflow_quality_gate.py +100 -0
|
@@ -0,0 +1,737 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Modification Applicator - 修改应用组件
|
|
4
|
+
|
|
5
|
+
负责将识别的改进应用到文档中,同时保持现有内容和结构
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import re
|
|
9
|
+
from typing import List, Tuple, Optional
|
|
10
|
+
from dataclasses import dataclass
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@dataclass
|
|
14
|
+
class ModificationResult:
|
|
15
|
+
"""修改结果"""
|
|
16
|
+
modified_content: str
|
|
17
|
+
applied_improvements: List = None
|
|
18
|
+
failed_improvements: List[Tuple] = None
|
|
19
|
+
modification_report: str = ""
|
|
20
|
+
|
|
21
|
+
def __post_init__(self):
|
|
22
|
+
if self.applied_improvements is None:
|
|
23
|
+
self.applied_improvements = []
|
|
24
|
+
if self.failed_improvements is None:
|
|
25
|
+
self.failed_improvements = []
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class ModificationApplicator:
|
|
29
|
+
"""
|
|
30
|
+
修改应用器 - 应用文档改进
|
|
31
|
+
|
|
32
|
+
保持内容完整性和格式一致性
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
def __init__(self):
|
|
36
|
+
self.language = 'en'
|
|
37
|
+
|
|
38
|
+
def apply_requirements_improvements(self, content: str, improvements: List, language: str = 'en') -> ModificationResult:
|
|
39
|
+
"""应用 Requirements 改进 - 增强版,真正修改文档"""
|
|
40
|
+
self.language = language
|
|
41
|
+
modified_content = content
|
|
42
|
+
applied = []
|
|
43
|
+
failed = []
|
|
44
|
+
|
|
45
|
+
# 按优先级排序改进
|
|
46
|
+
improvements_sorted = sorted(improvements, key=lambda x: (
|
|
47
|
+
0 if x.priority.value == 'high' else 1 if x.priority.value == 'medium' else 2
|
|
48
|
+
))
|
|
49
|
+
|
|
50
|
+
for improvement in improvements_sorted:
|
|
51
|
+
try:
|
|
52
|
+
# 根据改进类型应用不同的修改策略
|
|
53
|
+
if improvement.type.value == "add_section":
|
|
54
|
+
result = self._add_section_to_requirements(modified_content, improvement, language)
|
|
55
|
+
if result != modified_content:
|
|
56
|
+
modified_content = result
|
|
57
|
+
applied.append(improvement)
|
|
58
|
+
|
|
59
|
+
elif improvement.type.value == "add_nfr":
|
|
60
|
+
result = self._add_nfr_section(modified_content, improvement, language)
|
|
61
|
+
if result != modified_content:
|
|
62
|
+
modified_content = result
|
|
63
|
+
applied.append(improvement)
|
|
64
|
+
|
|
65
|
+
elif improvement.type.value == "enhance_criteria":
|
|
66
|
+
result = self._enhance_acceptance_criteria(modified_content, improvement, language)
|
|
67
|
+
if result != modified_content:
|
|
68
|
+
modified_content = result
|
|
69
|
+
applied.append(improvement)
|
|
70
|
+
|
|
71
|
+
elif improvement.type.value == "add_error_handling":
|
|
72
|
+
result = self._add_error_handling_requirements(modified_content, improvement, language)
|
|
73
|
+
if result != modified_content:
|
|
74
|
+
modified_content = result
|
|
75
|
+
applied.append(improvement)
|
|
76
|
+
|
|
77
|
+
elif improvement.type.value == "add_edge_cases":
|
|
78
|
+
result = self._add_edge_case_criteria(modified_content, improvement, language)
|
|
79
|
+
if result != modified_content:
|
|
80
|
+
modified_content = result
|
|
81
|
+
applied.append(improvement)
|
|
82
|
+
|
|
83
|
+
elif improvement.type.value == "add_glossary_term":
|
|
84
|
+
result = self._add_glossary_section(modified_content, improvement, language)
|
|
85
|
+
if result != modified_content:
|
|
86
|
+
modified_content = result
|
|
87
|
+
applied.append(improvement)
|
|
88
|
+
|
|
89
|
+
except Exception as e:
|
|
90
|
+
failed.append((improvement, e))
|
|
91
|
+
|
|
92
|
+
report = self._generate_modification_report(applied, failed, language)
|
|
93
|
+
|
|
94
|
+
return ModificationResult(
|
|
95
|
+
modified_content=modified_content,
|
|
96
|
+
applied_improvements=applied,
|
|
97
|
+
failed_improvements=failed,
|
|
98
|
+
modification_report=report
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
def apply_design_improvements(self, content: str, improvements: List, requirements_content: str, language: str = 'en') -> ModificationResult:
|
|
102
|
+
"""应用 Design 改进 - 增强版,真正修改文档"""
|
|
103
|
+
self.language = language
|
|
104
|
+
modified_content = content
|
|
105
|
+
applied = []
|
|
106
|
+
failed = []
|
|
107
|
+
|
|
108
|
+
# 按优先级排序改进
|
|
109
|
+
improvements_sorted = sorted(improvements, key=lambda x: (
|
|
110
|
+
0 if x.priority.value == 'high' else 1 if x.priority.value == 'medium' else 2
|
|
111
|
+
))
|
|
112
|
+
|
|
113
|
+
for improvement in improvements_sorted:
|
|
114
|
+
try:
|
|
115
|
+
if improvement.type.value == "add_section":
|
|
116
|
+
result = self._add_section_to_design(modified_content, improvement, language)
|
|
117
|
+
if result != modified_content:
|
|
118
|
+
modified_content = result
|
|
119
|
+
applied.append(improvement)
|
|
120
|
+
|
|
121
|
+
elif improvement.type.value == "add_diagram":
|
|
122
|
+
result = self._add_architecture_diagram(modified_content, improvement, language)
|
|
123
|
+
if result != modified_content:
|
|
124
|
+
modified_content = result
|
|
125
|
+
applied.append(improvement)
|
|
126
|
+
|
|
127
|
+
elif improvement.type.value == "add_rationale":
|
|
128
|
+
result = self._add_technology_stack(modified_content, improvement, language)
|
|
129
|
+
if result != modified_content:
|
|
130
|
+
modified_content = result
|
|
131
|
+
applied.append(improvement)
|
|
132
|
+
|
|
133
|
+
elif improvement.type.value == "add_component_detail":
|
|
134
|
+
result = self._add_component_details(modified_content, improvement, language)
|
|
135
|
+
if result != modified_content:
|
|
136
|
+
modified_content = result
|
|
137
|
+
applied.append(improvement)
|
|
138
|
+
|
|
139
|
+
elif improvement.type.value == "add_traceability":
|
|
140
|
+
result = self._add_requirements_traceability(modified_content, improvement, requirements_content, language)
|
|
141
|
+
if result != modified_content:
|
|
142
|
+
modified_content = result
|
|
143
|
+
applied.append(improvement)
|
|
144
|
+
|
|
145
|
+
elif improvement.type.value == "add_properties":
|
|
146
|
+
result = self._add_correctness_properties(modified_content, improvement, language)
|
|
147
|
+
if result != modified_content:
|
|
148
|
+
modified_content = result
|
|
149
|
+
applied.append(improvement)
|
|
150
|
+
|
|
151
|
+
except Exception as e:
|
|
152
|
+
failed.append((improvement, e))
|
|
153
|
+
|
|
154
|
+
report = self._generate_modification_report(applied, failed, language)
|
|
155
|
+
|
|
156
|
+
return ModificationResult(
|
|
157
|
+
modified_content=modified_content,
|
|
158
|
+
applied_improvements=applied,
|
|
159
|
+
failed_improvements=failed,
|
|
160
|
+
modification_report=report
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
# ==================== Requirements 修改方法 ====================
|
|
164
|
+
|
|
165
|
+
def _add_section_to_requirements(self, content: str, improvement, language: str) -> str:
|
|
166
|
+
"""智能添加章节到 Requirements 文档"""
|
|
167
|
+
section_name = improvement.target_section
|
|
168
|
+
template = self._get_template(improvement.template or section_name, language)
|
|
169
|
+
|
|
170
|
+
if not template:
|
|
171
|
+
return content
|
|
172
|
+
|
|
173
|
+
# 检查章节是否已存在
|
|
174
|
+
if section_name in content or (language == 'en' and section_name.lower() in content.lower()):
|
|
175
|
+
return content
|
|
176
|
+
|
|
177
|
+
# 找到合适的插入位置
|
|
178
|
+
if section_name in ["概述", "Introduction", "Overview"]:
|
|
179
|
+
# 在文档开头插入(在标题后)
|
|
180
|
+
lines = content.split('\n')
|
|
181
|
+
insert_pos = 0
|
|
182
|
+
for i, line in enumerate(lines):
|
|
183
|
+
if line.startswith('# '):
|
|
184
|
+
insert_pos = i + 1
|
|
185
|
+
break
|
|
186
|
+
lines.insert(insert_pos, '\n' + template)
|
|
187
|
+
return '\n'.join(lines)
|
|
188
|
+
|
|
189
|
+
elif section_name in ["约束条件", "Constraints"]:
|
|
190
|
+
# 在文档末尾添加
|
|
191
|
+
return content.rstrip() + '\n\n' + template
|
|
192
|
+
|
|
193
|
+
else:
|
|
194
|
+
# 在文档末尾添加
|
|
195
|
+
return content.rstrip() + '\n\n' + template
|
|
196
|
+
|
|
197
|
+
def _add_nfr_section(self, content: str, improvement, language: str) -> str:
|
|
198
|
+
"""添加或补充非功能需求章节"""
|
|
199
|
+
# 检查是否已有非功能需求章节
|
|
200
|
+
if "## 4. 非功能需求" in content or "## Non-functional Requirements" in content:
|
|
201
|
+
# 已有章节,补充内容
|
|
202
|
+
return self._append_to_nfr_section(content, improvement, language)
|
|
203
|
+
else:
|
|
204
|
+
# 添加新章节
|
|
205
|
+
template = self._get_nfr_template(language)
|
|
206
|
+
return content.rstrip() + '\n\n' + template
|
|
207
|
+
|
|
208
|
+
def _append_to_nfr_section(self, content: str, improvement, language: str) -> str:
|
|
209
|
+
"""向现有非功能需求章节补充内容"""
|
|
210
|
+
missing_nfr = improvement.metadata.get('missing_nfr', [])
|
|
211
|
+
if not missing_nfr:
|
|
212
|
+
return content
|
|
213
|
+
|
|
214
|
+
# 找到非功能需求章节的位置
|
|
215
|
+
nfr_pattern = r'(## (?:4\. )?非功能需求|## Non-functional Requirements)'
|
|
216
|
+
match = re.search(nfr_pattern, content, re.IGNORECASE)
|
|
217
|
+
if not match:
|
|
218
|
+
return content
|
|
219
|
+
|
|
220
|
+
# 找到下一个二级标题的位置
|
|
221
|
+
next_section = re.search(r'\n## ', content[match.end():])
|
|
222
|
+
if next_section:
|
|
223
|
+
insert_pos = match.end() + next_section.start()
|
|
224
|
+
else:
|
|
225
|
+
insert_pos = len(content)
|
|
226
|
+
|
|
227
|
+
# 生成补充内容
|
|
228
|
+
additions = []
|
|
229
|
+
for nfr in missing_nfr[:3]: # 最多补充3个
|
|
230
|
+
if language == 'zh':
|
|
231
|
+
additions.append(f"\n### {nfr}\n- 待补充具体{nfr}要求\n")
|
|
232
|
+
else:
|
|
233
|
+
additions.append(f"\n### {nfr.title()} Requirements\n- To be specified\n")
|
|
234
|
+
|
|
235
|
+
new_content = content[:insert_pos] + ''.join(additions) + content[insert_pos:]
|
|
236
|
+
return new_content
|
|
237
|
+
|
|
238
|
+
def _enhance_acceptance_criteria(self, content: str, improvement, language: str) -> str:
|
|
239
|
+
"""增强验收标准 - 添加 EARS 格式示例"""
|
|
240
|
+
# 找到第一个需求章节
|
|
241
|
+
req_pattern = r'(### (?:Requirement )?\d+\.\d+[^\n]*\n)'
|
|
242
|
+
match = re.search(req_pattern, content)
|
|
243
|
+
if not match:
|
|
244
|
+
return content
|
|
245
|
+
|
|
246
|
+
# 在第一个需求后添加示例验收标准
|
|
247
|
+
insert_pos = match.end()
|
|
248
|
+
|
|
249
|
+
if language == 'zh':
|
|
250
|
+
example = """
|
|
251
|
+
**验收标准**:
|
|
252
|
+
1. WHEN 用户执行操作 THEN 系统应该返回预期结果
|
|
253
|
+
2. WHEN 输入无效数据 THEN 系统应该显示错误提示
|
|
254
|
+
"""
|
|
255
|
+
else:
|
|
256
|
+
example = """
|
|
257
|
+
#### Acceptance Criteria
|
|
258
|
+
1. WHEN the user performs an action THEN THE system SHALL return the expected result
|
|
259
|
+
2. WHEN invalid data is provided THEN THE system SHALL display an error message
|
|
260
|
+
"""
|
|
261
|
+
|
|
262
|
+
new_content = content[:insert_pos] + example + content[insert_pos:]
|
|
263
|
+
return new_content
|
|
264
|
+
|
|
265
|
+
def _add_error_handling_requirements(self, content: str, improvement, language: str) -> str:
|
|
266
|
+
"""添加错误处理需求"""
|
|
267
|
+
template = self._get_error_handling_template(language)
|
|
268
|
+
|
|
269
|
+
# 在功能需求章节后添加
|
|
270
|
+
if language == 'zh':
|
|
271
|
+
pattern = r'(## 3\. 功能需求.*?)(\n## |\Z)'
|
|
272
|
+
else:
|
|
273
|
+
pattern = r'(## (?:Functional )?Requirements.*?)(\n## |\Z)'
|
|
274
|
+
|
|
275
|
+
match = re.search(pattern, content, re.DOTALL)
|
|
276
|
+
if match:
|
|
277
|
+
insert_pos = match.end(1)
|
|
278
|
+
new_content = content[:insert_pos] + '\n\n' + template + content[insert_pos:]
|
|
279
|
+
return new_content
|
|
280
|
+
|
|
281
|
+
return content.rstrip() + '\n\n' + template
|
|
282
|
+
|
|
283
|
+
def _add_edge_case_criteria(self, content: str, improvement, language: str) -> str:
|
|
284
|
+
"""添加边界条件验收标准"""
|
|
285
|
+
# 找到第一个验收标准章节
|
|
286
|
+
if language == 'zh':
|
|
287
|
+
pattern = r'(\*\*验收标准\*\*:.*?)(\n### |\n## |\Z)'
|
|
288
|
+
else:
|
|
289
|
+
pattern = r'(#### Acceptance Criteria.*?)(\n### |\n## |\Z)'
|
|
290
|
+
|
|
291
|
+
match = re.search(pattern, content, re.DOTALL)
|
|
292
|
+
if not match:
|
|
293
|
+
return content
|
|
294
|
+
|
|
295
|
+
insert_pos = match.end(1)
|
|
296
|
+
|
|
297
|
+
if language == 'zh':
|
|
298
|
+
addition = "\n- WHEN 输入为空值 THEN 系统应该处理空值情况\n- WHEN 输入达到最大限制 THEN 系统应该正确处理边界值"
|
|
299
|
+
else:
|
|
300
|
+
addition = "\n- WHEN input is empty THEN THE system SHALL handle empty values\n- WHEN input reaches maximum limit THEN THE system SHALL handle boundary values correctly"
|
|
301
|
+
|
|
302
|
+
new_content = content[:insert_pos] + addition + content[insert_pos:]
|
|
303
|
+
return new_content
|
|
304
|
+
|
|
305
|
+
def _add_glossary_section(self, content: str, improvement, language: str) -> str:
|
|
306
|
+
"""添加术语表章节"""
|
|
307
|
+
template = self._get_glossary_template(language)
|
|
308
|
+
|
|
309
|
+
# 在 Introduction 后添加
|
|
310
|
+
if language == 'zh':
|
|
311
|
+
pattern = r'(## (?:1\. )?概述.*?)(\n## |\Z)'
|
|
312
|
+
else:
|
|
313
|
+
pattern = r'(## (?:Introduction|Overview).*?)(\n## |\Z)'
|
|
314
|
+
|
|
315
|
+
match = re.search(pattern, content, re.DOTALL | re.IGNORECASE)
|
|
316
|
+
if match:
|
|
317
|
+
insert_pos = match.end(1)
|
|
318
|
+
new_content = content[:insert_pos] + '\n\n' + template + content[insert_pos:]
|
|
319
|
+
return new_content
|
|
320
|
+
|
|
321
|
+
return content.rstrip() + '\n\n' + template
|
|
322
|
+
|
|
323
|
+
# ==================== Design 修改方法 ====================
|
|
324
|
+
|
|
325
|
+
def _add_section_to_design(self, content: str, improvement, language: str) -> str:
|
|
326
|
+
"""智能添加章节到 Design 文档"""
|
|
327
|
+
section_name = improvement.target_section
|
|
328
|
+
template = self._get_template(improvement.template or section_name, language)
|
|
329
|
+
|
|
330
|
+
if not template:
|
|
331
|
+
return content
|
|
332
|
+
|
|
333
|
+
# 检查章节是否已存在
|
|
334
|
+
if section_name in content:
|
|
335
|
+
return content
|
|
336
|
+
|
|
337
|
+
# 在文档末尾添加
|
|
338
|
+
return content.rstrip() + '\n\n' + template
|
|
339
|
+
|
|
340
|
+
def _add_architecture_diagram(self, content: str, improvement, language: str) -> str:
|
|
341
|
+
"""添加架构图"""
|
|
342
|
+
template = self._get_architecture_diagram_template(language)
|
|
343
|
+
|
|
344
|
+
# 在架构设计章节后添加
|
|
345
|
+
if language == 'zh':
|
|
346
|
+
pattern = r'(## (?:2\. )?架构设计.*?)(\n### |\n## |\Z)'
|
|
347
|
+
else:
|
|
348
|
+
pattern = r'(## (?:System )?Architecture.*?)(\n### |\n## |\Z)'
|
|
349
|
+
|
|
350
|
+
match = re.search(pattern, content, re.DOTALL | re.IGNORECASE)
|
|
351
|
+
if match:
|
|
352
|
+
insert_pos = match.end(1)
|
|
353
|
+
new_content = content[:insert_pos] + '\n\n' + template + content[insert_pos:]
|
|
354
|
+
return new_content
|
|
355
|
+
|
|
356
|
+
return content.rstrip() + '\n\n' + template
|
|
357
|
+
|
|
358
|
+
def _add_technology_stack(self, content: str, improvement, language: str) -> str:
|
|
359
|
+
"""添加技术栈说明"""
|
|
360
|
+
template = self._get_technology_stack_template(language)
|
|
361
|
+
return content.rstrip() + '\n\n' + template
|
|
362
|
+
|
|
363
|
+
def _add_component_details(self, content: str, improvement, language: str) -> str:
|
|
364
|
+
"""添加组件详细信息"""
|
|
365
|
+
# 找到组件设计章节
|
|
366
|
+
if language == 'zh':
|
|
367
|
+
pattern = r'(## (?:3\. )?组件设计.*?)(\n## |\Z)'
|
|
368
|
+
else:
|
|
369
|
+
pattern = r'(## Components.*?)(\n## |\Z)'
|
|
370
|
+
|
|
371
|
+
match = re.search(pattern, content, re.DOTALL | re.IGNORECASE)
|
|
372
|
+
if not match:
|
|
373
|
+
return content
|
|
374
|
+
|
|
375
|
+
insert_pos = match.end(1)
|
|
376
|
+
|
|
377
|
+
# 添加示例组件
|
|
378
|
+
if language == 'zh':
|
|
379
|
+
addition = """
|
|
380
|
+
|
|
381
|
+
### 3.1 核心组件
|
|
382
|
+
|
|
383
|
+
**职责**: 处理核心业务逻辑
|
|
384
|
+
|
|
385
|
+
**接口定义**:
|
|
386
|
+
```python
|
|
387
|
+
class CoreComponent:
|
|
388
|
+
def process(self, data: dict) -> dict:
|
|
389
|
+
\"\"\"处理数据\"\"\"
|
|
390
|
+
pass
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
**依赖**: 无外部依赖
|
|
394
|
+
"""
|
|
395
|
+
else:
|
|
396
|
+
addition = """
|
|
397
|
+
|
|
398
|
+
### 3.1 Core Component
|
|
399
|
+
|
|
400
|
+
**Responsibility**: Handle core business logic
|
|
401
|
+
|
|
402
|
+
**Interface Definition**:
|
|
403
|
+
```python
|
|
404
|
+
class CoreComponent:
|
|
405
|
+
def process(self, data: dict) -> dict:
|
|
406
|
+
\"\"\"Process data\"\"\"
|
|
407
|
+
pass
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
**Dependencies**: No external dependencies
|
|
411
|
+
"""
|
|
412
|
+
|
|
413
|
+
new_content = content[:insert_pos] + addition + content[insert_pos:]
|
|
414
|
+
return new_content
|
|
415
|
+
|
|
416
|
+
def _add_requirements_traceability(self, content: str, improvement, requirements_content: str, language: str) -> str:
|
|
417
|
+
"""添加需求追溯"""
|
|
418
|
+
# 找到第一个组件章节
|
|
419
|
+
pattern = r'(### \d+\.\d+ [^\n]+\n)'
|
|
420
|
+
match = re.search(pattern, content)
|
|
421
|
+
if not match:
|
|
422
|
+
return content
|
|
423
|
+
|
|
424
|
+
insert_pos = match.end()
|
|
425
|
+
|
|
426
|
+
# 添加追溯注释
|
|
427
|
+
addition = "\n**Validates: Requirements 1.1, 1.2**\n"
|
|
428
|
+
|
|
429
|
+
new_content = content[:insert_pos] + addition + content[insert_pos:]
|
|
430
|
+
return new_content
|
|
431
|
+
|
|
432
|
+
def _add_correctness_properties(self, content: str, improvement, language: str) -> str:
|
|
433
|
+
"""添加正确性属性章节"""
|
|
434
|
+
template = self._get_correctness_properties_template(language)
|
|
435
|
+
return content.rstrip() + '\n\n' + template
|
|
436
|
+
|
|
437
|
+
# ==================== 模板方法 ====================
|
|
438
|
+
|
|
439
|
+
def _get_template(self, template_name: str, language: str) -> str:
|
|
440
|
+
"""获取模板内容"""
|
|
441
|
+
templates = {
|
|
442
|
+
'introduction_zh': """## 1. 概述
|
|
443
|
+
|
|
444
|
+
本文档描述了系统的需求规格说明。
|
|
445
|
+
|
|
446
|
+
### 1.1 项目背景
|
|
447
|
+
[待补充项目背景信息]
|
|
448
|
+
|
|
449
|
+
### 1.2 项目目标
|
|
450
|
+
[待补充项目目标]
|
|
451
|
+
""",
|
|
452
|
+
'introduction_en': """## Introduction
|
|
453
|
+
|
|
454
|
+
This document describes the system requirements specification.
|
|
455
|
+
|
|
456
|
+
### Project Background
|
|
457
|
+
[To be filled with project background information]
|
|
458
|
+
|
|
459
|
+
### Project Goals
|
|
460
|
+
[To be filled with project goals]
|
|
461
|
+
""",
|
|
462
|
+
'overview_zh': """## 1. 系统概述
|
|
463
|
+
|
|
464
|
+
本设计文档描述了系统的架构和组件设计。
|
|
465
|
+
|
|
466
|
+
### 1.1 设计目标
|
|
467
|
+
- 模块化设计,易于维护和扩展
|
|
468
|
+
- 高性能,满足业务需求
|
|
469
|
+
- 安全可靠,保障数据安全
|
|
470
|
+
|
|
471
|
+
### 1.2 设计方法
|
|
472
|
+
采用分层架构,将系统划分为表示层、业务逻辑层和数据访问层。
|
|
473
|
+
""",
|
|
474
|
+
'overview_en': """## Overview
|
|
475
|
+
|
|
476
|
+
This design document describes the system architecture and component design.
|
|
477
|
+
|
|
478
|
+
### Design Goals
|
|
479
|
+
- Modular design for easy maintenance and extension
|
|
480
|
+
- High performance to meet business requirements
|
|
481
|
+
- Secure and reliable to ensure data safety
|
|
482
|
+
|
|
483
|
+
### Design Approach
|
|
484
|
+
Adopts layered architecture, dividing the system into presentation layer, business logic layer, and data access layer.
|
|
485
|
+
""",
|
|
486
|
+
'architecture_zh': """## 2. 架构设计
|
|
487
|
+
|
|
488
|
+
### 2.1 系统架构
|
|
489
|
+
|
|
490
|
+
系统采用三层架构设计:
|
|
491
|
+
|
|
492
|
+
```mermaid
|
|
493
|
+
graph TB
|
|
494
|
+
A[表示层] --> B[业务逻辑层]
|
|
495
|
+
B --> C[数据访问层]
|
|
496
|
+
C --> D[数据存储]
|
|
497
|
+
```
|
|
498
|
+
|
|
499
|
+
### 2.2 架构说明
|
|
500
|
+
- **表示层**: 负责用户界面和交互
|
|
501
|
+
- **业务逻辑层**: 处理核心业务逻辑
|
|
502
|
+
- **数据访问层**: 封装数据库操作
|
|
503
|
+
""",
|
|
504
|
+
'architecture_en': """## Architecture
|
|
505
|
+
|
|
506
|
+
### System Architecture
|
|
507
|
+
|
|
508
|
+
The system adopts a three-tier architecture:
|
|
509
|
+
|
|
510
|
+
```mermaid
|
|
511
|
+
graph TB
|
|
512
|
+
A[Presentation Layer] --> B[Business Logic Layer]
|
|
513
|
+
B --> C[Data Access Layer]
|
|
514
|
+
C --> D[Data Storage]
|
|
515
|
+
```
|
|
516
|
+
|
|
517
|
+
### Architecture Description
|
|
518
|
+
- **Presentation Layer**: Handles user interface and interaction
|
|
519
|
+
- **Business Logic Layer**: Processes core business logic
|
|
520
|
+
- **Data Access Layer**: Encapsulates database operations
|
|
521
|
+
""",
|
|
522
|
+
'components_zh': """## 3. 组件设计
|
|
523
|
+
|
|
524
|
+
### 3.1 组件概述
|
|
525
|
+
系统包含以下核心组件:
|
|
526
|
+
- 用户管理组件
|
|
527
|
+
- 数据处理组件
|
|
528
|
+
- 接口服务组件
|
|
529
|
+
""",
|
|
530
|
+
'components_en': """## Components
|
|
531
|
+
|
|
532
|
+
### Component Overview
|
|
533
|
+
The system includes the following core components:
|
|
534
|
+
- User Management Component
|
|
535
|
+
- Data Processing Component
|
|
536
|
+
- Interface Service Component
|
|
537
|
+
"""
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
return templates.get(template_name, '')
|
|
541
|
+
|
|
542
|
+
def _get_nfr_template(self, language: str) -> str:
|
|
543
|
+
"""获取非功能需求模板"""
|
|
544
|
+
if language == 'zh':
|
|
545
|
+
return """## 4. 非功能需求
|
|
546
|
+
|
|
547
|
+
### 4.1 性能需求
|
|
548
|
+
- 系统响应时间应小于 2 秒
|
|
549
|
+
- 支持并发用户数不少于 100
|
|
550
|
+
|
|
551
|
+
### 4.2 安全需求
|
|
552
|
+
- 用户数据必须加密存储
|
|
553
|
+
- 实施访问控制和身份验证
|
|
554
|
+
|
|
555
|
+
### 4.3 可用性需求
|
|
556
|
+
- 系统可用性应达到 99.9%
|
|
557
|
+
- 提供友好的用户界面
|
|
558
|
+
|
|
559
|
+
### 4.4 可维护性需求
|
|
560
|
+
- 代码应遵循编码规范
|
|
561
|
+
- 提供完整的技术文档
|
|
562
|
+
"""
|
|
563
|
+
else:
|
|
564
|
+
return """## Non-functional Requirements
|
|
565
|
+
|
|
566
|
+
### Performance Requirements
|
|
567
|
+
- System response time should be less than 2 seconds
|
|
568
|
+
- Support at least 100 concurrent users
|
|
569
|
+
|
|
570
|
+
### Security Requirements
|
|
571
|
+
- User data must be encrypted at rest
|
|
572
|
+
- Implement access control and authentication
|
|
573
|
+
|
|
574
|
+
### Usability Requirements
|
|
575
|
+
- System availability should reach 99.9%
|
|
576
|
+
- Provide user-friendly interface
|
|
577
|
+
|
|
578
|
+
### Maintainability Requirements
|
|
579
|
+
- Code should follow coding standards
|
|
580
|
+
- Provide complete technical documentation
|
|
581
|
+
"""
|
|
582
|
+
|
|
583
|
+
def _get_error_handling_template(self, language: str) -> str:
|
|
584
|
+
"""获取错误处理模板"""
|
|
585
|
+
if language == 'zh':
|
|
586
|
+
return """### 错误处理需求
|
|
587
|
+
|
|
588
|
+
**用户故事**: 作为用户,我希望系统能够优雅地处理错误,以便我了解问题并采取相应措施。
|
|
589
|
+
|
|
590
|
+
**验收标准**:
|
|
591
|
+
1. WHEN 系统遇到错误 THEN 系统应该显示清晰的错误消息
|
|
592
|
+
2. WHEN 发生异常 THEN 系统应该记录错误日志
|
|
593
|
+
3. WHEN 出现致命错误 THEN 系统应该安全关闭并保存数据
|
|
594
|
+
"""
|
|
595
|
+
else:
|
|
596
|
+
return """### Error Handling Requirements
|
|
597
|
+
|
|
598
|
+
**User Story**: As a user, I want the system to handle errors gracefully, so that I understand the issue and can take appropriate action.
|
|
599
|
+
|
|
600
|
+
**Acceptance Criteria**:
|
|
601
|
+
1. WHEN the system encounters an error THEN THE system SHALL display a clear error message
|
|
602
|
+
2. WHEN an exception occurs THEN THE system SHALL log the error
|
|
603
|
+
3. WHEN a fatal error occurs THEN THE system SHALL shut down safely and save data
|
|
604
|
+
"""
|
|
605
|
+
|
|
606
|
+
def _get_glossary_template(self, language: str) -> str:
|
|
607
|
+
"""获取术语表模板"""
|
|
608
|
+
if language == 'zh':
|
|
609
|
+
return """## 术语表
|
|
610
|
+
|
|
611
|
+
- **系统**: 指本文档描述的软件系统
|
|
612
|
+
- **用户**: 使用系统的最终用户
|
|
613
|
+
- **管理员**: 具有系统管理权限的用户
|
|
614
|
+
"""
|
|
615
|
+
else:
|
|
616
|
+
return """## Glossary
|
|
617
|
+
|
|
618
|
+
- **System**: The software system described in this document
|
|
619
|
+
- **User**: End user who uses the system
|
|
620
|
+
- **Administrator**: User with system administration privileges
|
|
621
|
+
"""
|
|
622
|
+
|
|
623
|
+
def _get_architecture_diagram_template(self, language: str) -> str:
|
|
624
|
+
"""获取架构图模板"""
|
|
625
|
+
if language == 'zh':
|
|
626
|
+
return """### 系统架构图
|
|
627
|
+
|
|
628
|
+
```mermaid
|
|
629
|
+
graph TB
|
|
630
|
+
A[用户界面] --> B[业务逻辑层]
|
|
631
|
+
B --> C[数据访问层]
|
|
632
|
+
C --> D[数据存储]
|
|
633
|
+
```
|
|
634
|
+
"""
|
|
635
|
+
else:
|
|
636
|
+
return """### System Architecture Diagram
|
|
637
|
+
|
|
638
|
+
```mermaid
|
|
639
|
+
graph TB
|
|
640
|
+
A[User Interface] --> B[Business Logic Layer]
|
|
641
|
+
B --> C[Data Access Layer]
|
|
642
|
+
C --> D[Data Storage]
|
|
643
|
+
```
|
|
644
|
+
"""
|
|
645
|
+
|
|
646
|
+
def _get_technology_stack_template(self, language: str) -> str:
|
|
647
|
+
"""获取技术栈模板"""
|
|
648
|
+
if language == 'zh':
|
|
649
|
+
return """## 技术选型
|
|
650
|
+
|
|
651
|
+
### 核心技术栈
|
|
652
|
+
- **前端**: React/Vue.js
|
|
653
|
+
- **后端**: Node.js/Python
|
|
654
|
+
- **数据库**: PostgreSQL/MongoDB
|
|
655
|
+
- **缓存**: Redis
|
|
656
|
+
|
|
657
|
+
### 选型理由
|
|
658
|
+
- 考虑团队技术栈熟悉度
|
|
659
|
+
- 满足性能和扩展性要求
|
|
660
|
+
- 社区支持和生态完善
|
|
661
|
+
"""
|
|
662
|
+
else:
|
|
663
|
+
return """## Technology Stack
|
|
664
|
+
|
|
665
|
+
### Core Technologies
|
|
666
|
+
- **Frontend**: React/Vue.js
|
|
667
|
+
- **Backend**: Node.js/Python
|
|
668
|
+
- **Database**: PostgreSQL/MongoDB
|
|
669
|
+
- **Cache**: Redis
|
|
670
|
+
|
|
671
|
+
### Selection Rationale
|
|
672
|
+
- Team familiarity with technology stack
|
|
673
|
+
- Meets performance and scalability requirements
|
|
674
|
+
- Strong community support and ecosystem
|
|
675
|
+
"""
|
|
676
|
+
|
|
677
|
+
def _get_correctness_properties_template(self, language: str) -> str:
|
|
678
|
+
"""获取正确性属性模板"""
|
|
679
|
+
if language == 'zh':
|
|
680
|
+
return """## 正确性属性
|
|
681
|
+
|
|
682
|
+
### 属性 1: 数据一致性
|
|
683
|
+
*对于任何*数据操作,操作完成后数据应保持一致状态。
|
|
684
|
+
|
|
685
|
+
**验证**: Requirements 1.1, 1.2
|
|
686
|
+
|
|
687
|
+
### 属性 2: 操作幂等性
|
|
688
|
+
*对于任何*幂等操作,多次执行应产生相同结果。
|
|
689
|
+
|
|
690
|
+
**验证**: Requirements 2.1
|
|
691
|
+
"""
|
|
692
|
+
else:
|
|
693
|
+
return """## Correctness Properties
|
|
694
|
+
|
|
695
|
+
### Property 1: Data Consistency
|
|
696
|
+
*For any* data operation, data should remain in a consistent state after the operation completes.
|
|
697
|
+
|
|
698
|
+
**Validates**: Requirements 1.1, 1.2
|
|
699
|
+
|
|
700
|
+
### Property 2: Operation Idempotency
|
|
701
|
+
*For any* idempotent operation, multiple executions should produce the same result.
|
|
702
|
+
|
|
703
|
+
**Validates**: Requirements 2.1
|
|
704
|
+
"""
|
|
705
|
+
|
|
706
|
+
def _generate_modification_report(self, applied: List, failed: List[Tuple], language: str) -> str:
|
|
707
|
+
"""生成修改报告"""
|
|
708
|
+
if language == 'zh':
|
|
709
|
+
report = f"### 修改报告\n\n"
|
|
710
|
+
report += f"- 成功应用: {len(applied)} 项改进\n"
|
|
711
|
+
report += f"- 失败: {len(failed)} 项改进\n\n"
|
|
712
|
+
|
|
713
|
+
if applied:
|
|
714
|
+
report += "#### 已应用的改进:\n"
|
|
715
|
+
for imp in applied:
|
|
716
|
+
report += f"- [{imp.priority.value.upper()}] {imp.description}\n"
|
|
717
|
+
|
|
718
|
+
if failed:
|
|
719
|
+
report += "\n#### 失败的改进:\n"
|
|
720
|
+
for imp, error in failed:
|
|
721
|
+
report += f"- {imp.description}: {str(error)}\n"
|
|
722
|
+
else:
|
|
723
|
+
report = f"### Modification Report\n\n"
|
|
724
|
+
report += f"- Successfully applied: {len(applied)} improvements\n"
|
|
725
|
+
report += f"- Failed: {len(failed)} improvements\n\n"
|
|
726
|
+
|
|
727
|
+
if applied:
|
|
728
|
+
report += "#### Applied Improvements:\n"
|
|
729
|
+
for imp in applied:
|
|
730
|
+
report += f"- [{imp.priority.value.upper()}] {imp.description}\n"
|
|
731
|
+
|
|
732
|
+
if failed:
|
|
733
|
+
report += "\n#### Failed Improvements:\n"
|
|
734
|
+
for imp, error in failed:
|
|
735
|
+
report += f"- {imp.description}: {str(error)}\n"
|
|
736
|
+
|
|
737
|
+
return report
|