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.
Files changed (45) hide show
  1. package/CHANGELOG.md +74 -0
  2. package/README.md +172 -0
  3. package/bin/kiro-spec-engine.js +62 -0
  4. package/docs/agent-hooks-analysis.md +815 -0
  5. package/docs/cross-tool-guide.md +554 -0
  6. package/docs/manual-workflows-guide.md +417 -0
  7. package/docs/steering-strategy-guide.md +196 -0
  8. package/lib/adoption/detection-engine.js +14 -4
  9. package/lib/commands/adopt.js +117 -3
  10. package/lib/commands/context.js +99 -0
  11. package/lib/commands/prompt.js +105 -0
  12. package/lib/commands/status.js +225 -0
  13. package/lib/commands/task.js +199 -0
  14. package/lib/commands/watch.js +569 -0
  15. package/lib/commands/workflows.js +240 -0
  16. package/lib/commands/workspace.js +189 -0
  17. package/lib/context/context-exporter.js +378 -0
  18. package/lib/context/prompt-generator.js +482 -0
  19. package/lib/steering/adoption-config.js +164 -0
  20. package/lib/steering/steering-manager.js +289 -0
  21. package/lib/task/task-claimer.js +430 -0
  22. package/lib/utils/tool-detector.js +383 -0
  23. package/lib/watch/action-executor.js +458 -0
  24. package/lib/watch/event-debouncer.js +323 -0
  25. package/lib/watch/execution-logger.js +550 -0
  26. package/lib/watch/file-watcher.js +499 -0
  27. package/lib/watch/presets.js +266 -0
  28. package/lib/watch/watch-manager.js +533 -0
  29. package/lib/workspace/workspace-manager.js +370 -0
  30. package/lib/workspace/workspace-sync.js +356 -0
  31. package/package.json +3 -1
  32. package/template/.kiro/tools/backup_manager.py +295 -0
  33. package/template/.kiro/tools/configuration_manager.py +218 -0
  34. package/template/.kiro/tools/document_evaluator.py +550 -0
  35. package/template/.kiro/tools/enhancement_logger.py +168 -0
  36. package/template/.kiro/tools/error_handler.py +335 -0
  37. package/template/.kiro/tools/improvement_identifier.py +444 -0
  38. package/template/.kiro/tools/modification_applicator.py +737 -0
  39. package/template/.kiro/tools/quality_gate_enforcer.py +207 -0
  40. package/template/.kiro/tools/quality_scorer.py +305 -0
  41. package/template/.kiro/tools/report_generator.py +154 -0
  42. package/template/.kiro/tools/ultrawork_enhancer_refactored.py +0 -0
  43. package/template/.kiro/tools/ultrawork_enhancer_v2.py +463 -0
  44. package/template/.kiro/tools/ultrawork_enhancer_v3.py +606 -0
  45. package/template/.kiro/tools/workflow_quality_gate.py +100 -0
@@ -0,0 +1,168 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Enhancement Logger - 增强日志记录器
4
+
5
+ 提供详细的增强过程日志记录
6
+ 注意:这是一个轻量级实现,基本日志功能已集成在 ErrorHandler 中
7
+ """
8
+
9
+ import sys
10
+ from datetime import datetime
11
+ from pathlib import Path
12
+ from typing import Optional
13
+
14
+
15
+ class EnhancementLogger:
16
+ """
17
+ 增强日志记录器
18
+
19
+ 提供增强过程的详细日志记录,支持控制台和文件输出
20
+ """
21
+
22
+ def __init__(self, log_file: Optional[str] = None, verbose: bool = False):
23
+ """
24
+ 初始化日志记录器
25
+
26
+ Args:
27
+ log_file: 日志文件路径(可选)
28
+ verbose: 是否启用详细模式
29
+ """
30
+ self.log_file = log_file
31
+ self.verbose = verbose
32
+ self.log_handle = None
33
+
34
+ if log_file:
35
+ Path(log_file).parent.mkdir(parents=True, exist_ok=True)
36
+ self.log_handle = open(log_file, 'a', encoding='utf-8')
37
+
38
+ def __del__(self):
39
+ """清理资源"""
40
+ if self.log_handle:
41
+ self.log_handle.close()
42
+
43
+ def _write(self, message: str, to_console: bool = True):
44
+ """
45
+ 写入日志
46
+
47
+ Args:
48
+ message: 日志消息
49
+ to_console: 是否输出到控制台
50
+ """
51
+ timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
52
+ formatted = f"[{timestamp}] {message}"
53
+
54
+ if to_console:
55
+ print(formatted)
56
+
57
+ if self.log_handle:
58
+ self.log_handle.write(formatted + '\n')
59
+ self.log_handle.flush()
60
+
61
+ def log_cycle_start(self, document_type: str, document_path: str):
62
+ """
63
+ 记录增强周期开始
64
+
65
+ Args:
66
+ document_type: 文档类型 (requirements/design/tasks)
67
+ document_path: 文档路径
68
+ """
69
+ self._write(f"\n{'='*60}")
70
+ self._write(f"Enhancement Cycle Started: {document_type.upper()}")
71
+ self._write(f"Document: {document_path}")
72
+ self._write(f"{'='*60}\n")
73
+
74
+ def log_cycle_stop(self, document_type: str, initial_score: float,
75
+ final_score: float, iterations: int, reason: str):
76
+ """
77
+ 记录增强周期结束
78
+
79
+ Args:
80
+ document_type: 文档类型
81
+ initial_score: 初始分数
82
+ final_score: 最终分数
83
+ iterations: 迭代次数
84
+ reason: 停止原因
85
+ """
86
+ improvement = final_score - initial_score
87
+ self._write(f"\n{'='*60}")
88
+ self._write(f"Enhancement Cycle Completed: {document_type.upper()}")
89
+ self._write(f"Initial Score: {initial_score:.2f}/10")
90
+ self._write(f"Final Score: {final_score:.2f}/10")
91
+ self._write(f"Improvement: +{improvement:.2f}")
92
+ self._write(f"Iterations: {iterations}")
93
+ self._write(f"Stopping Reason: {reason}")
94
+ self._write(f"{'='*60}\n")
95
+
96
+ def log_iteration_start(self, iteration: int, current_score: float):
97
+ """
98
+ 记录迭代开始
99
+
100
+ Args:
101
+ iteration: 迭代编号
102
+ current_score: 当前分数
103
+ """
104
+ self._write(f"\n--- Iteration {iteration} ---")
105
+ self._write(f"Current Score: {current_score:.2f}/10")
106
+
107
+ def log_iteration_complete(self, iteration: int, new_score: float,
108
+ improvements_applied: int):
109
+ """
110
+ 记录迭代完成
111
+
112
+ Args:
113
+ iteration: 迭代编号
114
+ new_score: 新分数
115
+ improvements_applied: 应用的改进数量
116
+ """
117
+ self._write(f"Iteration {iteration} Complete:")
118
+ self._write(f" New Score: {new_score:.2f}/10")
119
+ self._write(f" Improvements Applied: {improvements_applied}")
120
+
121
+ def log_improvement_application(self, improvement_type: str,
122
+ section: str, success: bool):
123
+ """
124
+ 记录改进应用
125
+
126
+ Args:
127
+ improvement_type: 改进类型
128
+ section: 目标章节
129
+ success: 是否成功
130
+ """
131
+ status = "✓" if success else "✗"
132
+ message = f" {status} Applied: {improvement_type} → {section}"
133
+
134
+ if self.verbose or not success:
135
+ self._write(message)
136
+
137
+ def log_error(self, error_message: str):
138
+ """
139
+ 记录错误
140
+
141
+ Args:
142
+ error_message: 错误消息
143
+ """
144
+ self._write(f"ERROR: {error_message}", to_console=True)
145
+
146
+ def log_warning(self, warning_message: str):
147
+ """
148
+ 记录警告
149
+
150
+ Args:
151
+ warning_message: 警告消息
152
+ """
153
+ if self.verbose:
154
+ self._write(f"WARNING: {warning_message}")
155
+
156
+ def log_info(self, info_message: str):
157
+ """
158
+ 记录信息
159
+
160
+ Args:
161
+ info_message: 信息消息
162
+ """
163
+ if self.verbose:
164
+ self._write(f"INFO: {info_message}")
165
+
166
+
167
+ # 注意:基本日志功能已集成在 error_handler.py 的 ErrorHandler 类中
168
+ # 本类提供更详细的增强过程日志记录,可选使用
@@ -0,0 +1,335 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Error Handler - 错误处理组件
4
+
5
+ 提供全面的错误处理和弹性机制
6
+ """
7
+
8
+ import logging
9
+ import traceback
10
+ from typing import Optional, Callable, Any
11
+ from enum import Enum
12
+ from dataclasses import dataclass
13
+
14
+
15
+ class ErrorSeverity(Enum):
16
+ """错误严重程度"""
17
+ CRITICAL = "critical" # 致命错误,必须停止
18
+ ERROR = "error" # 错误,但可以继续
19
+ WARNING = "warning" # 警告
20
+ INFO = "info" # 信息
21
+
22
+
23
+ @dataclass
24
+ class ErrorContext:
25
+ """错误上下文"""
26
+ operation: str
27
+ component: str
28
+ severity: ErrorSeverity
29
+ error: Exception
30
+ details: dict
31
+ stack_trace: str
32
+
33
+
34
+ class ErrorHandler:
35
+ """
36
+ 错误处理器 - 统一错误处理和日志记录
37
+
38
+ 提供错误捕获、日志记录和恢复机制
39
+ """
40
+
41
+ def __init__(self, logger: Optional[logging.Logger] = None):
42
+ """
43
+ 初始化错误处理器
44
+
45
+ Args:
46
+ logger: 日志记录器,如果为 None 则创建默认记录器
47
+ """
48
+ self.logger = logger or self._create_default_logger()
49
+ self.error_history = []
50
+
51
+ def _create_default_logger(self) -> logging.Logger:
52
+ """创建默认日志记录器"""
53
+ logger = logging.getLogger('ultrawork')
54
+ logger.setLevel(logging.INFO)
55
+
56
+ # 控制台处理器
57
+ console_handler = logging.StreamHandler()
58
+ console_handler.setLevel(logging.INFO)
59
+
60
+ # 格式化器
61
+ formatter = logging.Formatter(
62
+ '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
63
+ )
64
+ console_handler.setFormatter(formatter)
65
+
66
+ logger.addHandler(console_handler)
67
+
68
+ return logger
69
+
70
+ def handle_error(self,
71
+ operation: str,
72
+ component: str,
73
+ error: Exception,
74
+ severity: ErrorSeverity = ErrorSeverity.ERROR,
75
+ details: Optional[dict] = None) -> ErrorContext:
76
+ """
77
+ 处理错误
78
+
79
+ Args:
80
+ operation: 操作名称
81
+ component: 组件名称
82
+ error: 异常对象
83
+ severity: 错误严重程度
84
+ details: 额外详情
85
+
86
+ Returns:
87
+ ErrorContext: 错误上下文
88
+ """
89
+ # 获取堆栈跟踪
90
+ stack_trace = traceback.format_exc()
91
+
92
+ # 创建错误上下文
93
+ context = ErrorContext(
94
+ operation=operation,
95
+ component=component,
96
+ severity=severity,
97
+ error=error,
98
+ details=details or {},
99
+ stack_trace=stack_trace
100
+ )
101
+
102
+ # 记录错误
103
+ self._log_error(context)
104
+
105
+ # 保存到历史
106
+ self.error_history.append(context)
107
+
108
+ return context
109
+
110
+ def _log_error(self, context: ErrorContext):
111
+ """记录错误到日志"""
112
+ message = (
113
+ f"[{context.component}] {context.operation} failed: "
114
+ f"{type(context.error).__name__}: {str(context.error)}"
115
+ )
116
+
117
+ if context.details:
118
+ message += f" | Details: {context.details}"
119
+
120
+ # 根据严重程度选择日志级别
121
+ if context.severity == ErrorSeverity.CRITICAL:
122
+ self.logger.critical(message)
123
+ self.logger.debug(context.stack_trace)
124
+ elif context.severity == ErrorSeverity.ERROR:
125
+ self.logger.error(message)
126
+ self.logger.debug(context.stack_trace)
127
+ elif context.severity == ErrorSeverity.WARNING:
128
+ self.logger.warning(message)
129
+ else:
130
+ self.logger.info(message)
131
+
132
+ def safe_execute(self,
133
+ operation: str,
134
+ component: str,
135
+ func: Callable,
136
+ default_return: Any = None,
137
+ severity: ErrorSeverity = ErrorSeverity.ERROR,
138
+ args: tuple = (),
139
+ kwargs: dict = None) -> tuple:
140
+ """
141
+ 安全执行函数,捕获并处理错误
142
+
143
+ Args:
144
+ operation: 操作名称
145
+ component: 组件名称
146
+ func: 要执行的函数
147
+ default_return: 发生错误时的默认返回值
148
+ severity: 错误严重程度
149
+ args: 函数参数元组
150
+ kwargs: 函数关键字参数字典
151
+
152
+ Returns:
153
+ tuple[bool, Any]: (是否成功, 返回值或默认值)
154
+ """
155
+ if kwargs is None:
156
+ kwargs = {}
157
+
158
+ try:
159
+ result = func(*args, **kwargs)
160
+ return True, result
161
+ except Exception as e:
162
+ self.handle_error(
163
+ operation=operation,
164
+ component=component,
165
+ error=e,
166
+ severity=severity,
167
+ details={'args': str(args), 'kwargs': str(kwargs)}
168
+ )
169
+ return False, default_return
170
+
171
+ def get_error_summary(self) -> dict:
172
+ """
173
+ 获取错误摘要
174
+
175
+ Returns:
176
+ dict: 错误统计信息
177
+ """
178
+ summary = {
179
+ 'total_errors': len(self.error_history),
180
+ 'by_severity': {},
181
+ 'by_component': {},
182
+ 'recent_errors': []
183
+ }
184
+
185
+ # 按严重程度统计
186
+ for context in self.error_history:
187
+ severity = context.severity.value
188
+ summary['by_severity'][severity] = summary['by_severity'].get(severity, 0) + 1
189
+
190
+ component = context.component
191
+ summary['by_component'][component] = summary['by_component'].get(component, 0) + 1
192
+
193
+ # 最近的错误(最多5个)
194
+ for context in self.error_history[-5:]:
195
+ summary['recent_errors'].append({
196
+ 'operation': context.operation,
197
+ 'component': context.component,
198
+ 'error': str(context.error),
199
+ 'severity': context.severity.value
200
+ })
201
+
202
+ return summary
203
+
204
+ def clear_history(self):
205
+ """清空错误历史"""
206
+ self.error_history.clear()
207
+
208
+
209
+ # 全局错误处理器实例
210
+ _global_error_handler = None
211
+
212
+
213
+ def get_error_handler() -> ErrorHandler:
214
+ """获取全局错误处理器"""
215
+ global _global_error_handler
216
+ if _global_error_handler is None:
217
+ _global_error_handler = ErrorHandler()
218
+ return _global_error_handler
219
+
220
+
221
+ def handle_file_system_error(operation: str, file_path: str, error: Exception) -> ErrorContext:
222
+ """
223
+ 处理文件系统错误
224
+
225
+ Args:
226
+ operation: 操作名称(read/write/delete等)
227
+ file_path: 文件路径
228
+ error: 异常对象
229
+
230
+ Returns:
231
+ ErrorContext: 错误上下文
232
+ """
233
+ handler = get_error_handler()
234
+
235
+ # 确定严重程度
236
+ if isinstance(error, FileNotFoundError):
237
+ severity = ErrorSeverity.ERROR
238
+ elif isinstance(error, PermissionError):
239
+ severity = ErrorSeverity.CRITICAL
240
+ else:
241
+ severity = ErrorSeverity.ERROR
242
+
243
+ return handler.handle_error(
244
+ operation=operation,
245
+ component='FileSystem',
246
+ error=error,
247
+ severity=severity,
248
+ details={'file_path': file_path}
249
+ )
250
+
251
+
252
+ def handle_document_error(operation: str, document_type: str, error: Exception) -> ErrorContext:
253
+ """
254
+ 处理文档处理错误
255
+
256
+ Args:
257
+ operation: 操作名称
258
+ document_type: 文档类型(requirements/design/tasks)
259
+ error: 异常对象
260
+
261
+ Returns:
262
+ ErrorContext: 错误上下文
263
+ """
264
+ handler = get_error_handler()
265
+
266
+ return handler.handle_error(
267
+ operation=operation,
268
+ component='DocumentProcessor',
269
+ error=error,
270
+ severity=ErrorSeverity.ERROR,
271
+ details={'document_type': document_type}
272
+ )
273
+
274
+
275
+ def handle_improvement_error(improvement_type: str, error: Exception) -> ErrorContext:
276
+ """
277
+ 处理改进应用错误
278
+
279
+ Args:
280
+ improvement_type: 改进类型
281
+ error: 异常对象
282
+
283
+ Returns:
284
+ ErrorContext: 错误上下文
285
+ """
286
+ handler = get_error_handler()
287
+
288
+ return handler.handle_error(
289
+ operation='apply_improvement',
290
+ component='ModificationApplicator',
291
+ error=error,
292
+ severity=ErrorSeverity.WARNING, # 单个改进失败不是致命的
293
+ details={'improvement_type': improvement_type}
294
+ )
295
+
296
+
297
+ def main():
298
+ """测试错误处理器"""
299
+ handler = ErrorHandler()
300
+
301
+ print("1. Testing safe_execute with success...")
302
+ success, result = handler.safe_execute(
303
+ operation='divide',
304
+ component='Calculator',
305
+ func=lambda x, y: x / y,
306
+ args=(10, 2)
307
+ )
308
+ print(f" Success: {success}, Result: {result}\n")
309
+
310
+ print("2. Testing safe_execute with error...")
311
+ success, result = handler.safe_execute(
312
+ operation='divide',
313
+ component='Calculator',
314
+ func=lambda x, y: x / y,
315
+ default_return=0,
316
+ args=(10, 0)
317
+ )
318
+ print(f" Success: {success}, Result: {result}\n")
319
+
320
+ print("3. Testing file system error...")
321
+ try:
322
+ with open('nonexistent.txt', 'r') as f:
323
+ pass
324
+ except Exception as e:
325
+ handle_file_system_error('read', 'nonexistent.txt', e)
326
+
327
+ print("\n4. Error summary:")
328
+ summary = handler.get_error_summary()
329
+ print(f" Total errors: {summary['total_errors']}")
330
+ print(f" By severity: {summary['by_severity']}")
331
+ print(f" By component: {summary['by_component']}")
332
+
333
+
334
+ if __name__ == '__main__':
335
+ main()