devsquad 3.6.0__py3-none-any.whl

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 (95) hide show
  1. devsquad-3.6.0.dist-info/METADATA +944 -0
  2. devsquad-3.6.0.dist-info/RECORD +95 -0
  3. devsquad-3.6.0.dist-info/WHEEL +5 -0
  4. devsquad-3.6.0.dist-info/entry_points.txt +2 -0
  5. devsquad-3.6.0.dist-info/licenses/LICENSE +21 -0
  6. devsquad-3.6.0.dist-info/top_level.txt +2 -0
  7. scripts/__init__.py +0 -0
  8. scripts/ai_semantic_matcher.py +512 -0
  9. scripts/alert_manager.py +505 -0
  10. scripts/api/__init__.py +43 -0
  11. scripts/api/models.py +386 -0
  12. scripts/api/routes/__init__.py +20 -0
  13. scripts/api/routes/dispatch.py +348 -0
  14. scripts/api/routes/lifecycle.py +330 -0
  15. scripts/api/routes/metrics_gates.py +347 -0
  16. scripts/api_server.py +318 -0
  17. scripts/auth.py +451 -0
  18. scripts/cli/__init__.py +1 -0
  19. scripts/cli/cli_visual.py +642 -0
  20. scripts/cli.py +1094 -0
  21. scripts/collaboration/__init__.py +212 -0
  22. scripts/collaboration/_version.py +1 -0
  23. scripts/collaboration/agent_briefing.py +656 -0
  24. scripts/collaboration/ai_semantic_matcher.py +260 -0
  25. scripts/collaboration/anchor_checker.py +281 -0
  26. scripts/collaboration/anti_rationalization.py +470 -0
  27. scripts/collaboration/async_integration_example.py +255 -0
  28. scripts/collaboration/batch_scheduler.py +149 -0
  29. scripts/collaboration/checkpoint_manager.py +561 -0
  30. scripts/collaboration/ci_feedback_adapter.py +351 -0
  31. scripts/collaboration/code_map_generator.py +247 -0
  32. scripts/collaboration/concern_pack_loader.py +352 -0
  33. scripts/collaboration/confidence_score.py +496 -0
  34. scripts/collaboration/config_loader.py +188 -0
  35. scripts/collaboration/consensus.py +244 -0
  36. scripts/collaboration/context_compressor.py +533 -0
  37. scripts/collaboration/coordinator.py +668 -0
  38. scripts/collaboration/dispatcher.py +1636 -0
  39. scripts/collaboration/dual_layer_context.py +128 -0
  40. scripts/collaboration/enhanced_worker.py +539 -0
  41. scripts/collaboration/feature_usage_tracker.py +206 -0
  42. scripts/collaboration/five_axis_consensus.py +334 -0
  43. scripts/collaboration/input_validator.py +401 -0
  44. scripts/collaboration/integration_example.py +287 -0
  45. scripts/collaboration/intent_workflow_mapper.py +350 -0
  46. scripts/collaboration/language_parsers.py +269 -0
  47. scripts/collaboration/lifecycle_protocol.py +1446 -0
  48. scripts/collaboration/llm_backend.py +453 -0
  49. scripts/collaboration/llm_cache.py +448 -0
  50. scripts/collaboration/llm_cache_async.py +347 -0
  51. scripts/collaboration/llm_retry.py +387 -0
  52. scripts/collaboration/llm_retry_async.py +389 -0
  53. scripts/collaboration/mce_adapter.py +597 -0
  54. scripts/collaboration/memory_bridge.py +1607 -0
  55. scripts/collaboration/models.py +537 -0
  56. scripts/collaboration/null_providers.py +297 -0
  57. scripts/collaboration/operation_classifier.py +289 -0
  58. scripts/collaboration/output_slicer.py +225 -0
  59. scripts/collaboration/performance_monitor.py +462 -0
  60. scripts/collaboration/permission_guard.py +865 -0
  61. scripts/collaboration/prompt_assembler.py +756 -0
  62. scripts/collaboration/prompt_variant_generator.py +483 -0
  63. scripts/collaboration/protocols.py +267 -0
  64. scripts/collaboration/report_formatter.py +352 -0
  65. scripts/collaboration/retrospective.py +279 -0
  66. scripts/collaboration/role_matcher.py +92 -0
  67. scripts/collaboration/role_template_market.py +352 -0
  68. scripts/collaboration/rule_collector.py +678 -0
  69. scripts/collaboration/scratchpad.py +346 -0
  70. scripts/collaboration/skill_registry.py +151 -0
  71. scripts/collaboration/skillifier.py +878 -0
  72. scripts/collaboration/standardized_role_template.py +317 -0
  73. scripts/collaboration/task_completion_checker.py +237 -0
  74. scripts/collaboration/test_quality_guard.py +695 -0
  75. scripts/collaboration/unified_gate_engine.py +598 -0
  76. scripts/collaboration/usage_tracker.py +309 -0
  77. scripts/collaboration/user_friendly_error.py +176 -0
  78. scripts/collaboration/verification_gate.py +312 -0
  79. scripts/collaboration/warmup_manager.py +635 -0
  80. scripts/collaboration/worker.py +513 -0
  81. scripts/collaboration/workflow_engine.py +684 -0
  82. scripts/dashboard.py +1088 -0
  83. scripts/generate_benchmark_report.py +786 -0
  84. scripts/history_manager.py +604 -0
  85. scripts/mcp_server.py +289 -0
  86. skills/__init__.py +32 -0
  87. skills/dispatch/handler.py +52 -0
  88. skills/intent/handler.py +59 -0
  89. skills/registry.py +67 -0
  90. skills/retrospective/__init__.py +0 -0
  91. skills/retrospective/handler.py +125 -0
  92. skills/review/handler.py +356 -0
  93. skills/security/handler.py +454 -0
  94. skills/test/__init__.py +0 -0
  95. skills/test/handler.py +78 -0
@@ -0,0 +1,352 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Concern Pack Loader — 关注点增强包加载引擎
4
+
5
+ 根据任务描述自动匹配并加载相关的增强包,将领域知识注入到角色提示词中。
6
+
7
+ 增强包位置: templates/concerns/*.yaml
8
+ 触发机制: 任务描述中的关键词匹配增强包的 triggers.keywords
9
+
10
+ Usage:
11
+ from scripts.collaboration.concern_pack_loader import ConcernPackLoader
12
+
13
+ loader = ConcernPackLoader()
14
+ packs = loader.match_packs("设计用户权限系统")
15
+ # → [PermissionPack]
16
+
17
+ enhancements = loader.get_role_enhancements(packs, "security")
18
+ # → "【权限设计专项检查】..."
19
+ """
20
+
21
+ import os
22
+ import sys
23
+ import logging
24
+ import threading
25
+ from typing import Dict, List, Optional, Any
26
+ from dataclasses import dataclass, field
27
+
28
+ logger = logging.getLogger(__name__)
29
+
30
+
31
+ @dataclass
32
+ class DecisionOption:
33
+ id: str
34
+ name: str
35
+ when: str
36
+ examples: str = ""
37
+ complexity: int = 1
38
+ pros: str = ""
39
+ cons: str = ""
40
+
41
+
42
+ @dataclass
43
+ class DecisionStep:
44
+ question: str
45
+ description: str = ""
46
+ options: List[DecisionOption] = field(default_factory=list)
47
+ selection_guide: str = ""
48
+
49
+
50
+ @dataclass
51
+ class ChecklistItem:
52
+ item: str
53
+ severity: str = "required"
54
+
55
+
56
+ @dataclass
57
+ class Pitfall:
58
+ title: str
59
+ description: str
60
+ severity: str = "medium"
61
+ check: str = ""
62
+ fix: str = ""
63
+
64
+
65
+ @dataclass
66
+ class ConcernPack:
67
+ concern_id: str
68
+ name: str
69
+ version: str = "1.0"
70
+ description: str = ""
71
+ triggers: Dict[str, Any] = field(default_factory=dict)
72
+ decision_framework: Dict[str, Any] = field(default_factory=dict)
73
+ checklist: Dict[str, Any] = field(default_factory=dict)
74
+ role_enhancements: Dict[str, str] = field(default_factory=dict)
75
+
76
+ def get_checklist_summary(self) -> str:
77
+ must_have = self.checklist.get("must_have", [])
78
+ pitfalls = self.checklist.get("common_pitfalls", [])
79
+
80
+ lines = [f"\n### {self.name} — 检查清单\n"]
81
+
82
+ if must_have:
83
+ lines.append("**必须检查项**:")
84
+ for item in must_have:
85
+ severity = item.get("severity", "required") if isinstance(item, dict) else "required"
86
+ text = item.get("item", str(item)) if isinstance(item, dict) else str(item)
87
+ icon = "🔴" if severity == "required" else "🟡"
88
+ lines.append(f"- [{icon}] {text}")
89
+
90
+ if pitfalls:
91
+ lines.append("\n**常见陷阱**:")
92
+ for p in pitfalls:
93
+ if isinstance(p, dict):
94
+ severity = p.get("severity", "medium")
95
+ icon = {"critical": "🔴", "high": "🟠", "medium": "🟡"}.get(severity, "🟡")
96
+ lines.append(f"- [{icon}] **{p.get('title', '')}** ({severity})")
97
+ lines.append(f" → {p.get('check', p.get('description', ''))}")
98
+
99
+ return "\n".join(lines)
100
+
101
+ def get_decision_summary(self) -> str:
102
+ steps = self.decision_framework
103
+ if not steps:
104
+ return ""
105
+
106
+ lines = [f"\n### {self.name} — 决策框架\n"]
107
+
108
+ for step_key, step_data in steps.items():
109
+ if not isinstance(step_data, dict):
110
+ continue
111
+ question = step_data.get("question", "")
112
+ if question:
113
+ lines.append(f"**{question}**")
114
+
115
+ options = step_data.get("options", [])
116
+ if options:
117
+ for opt in options:
118
+ if isinstance(opt, dict):
119
+ complexity_stars = "⭐" * opt.get("complexity", 1)
120
+ lines.append(f"- **{opt.get('name', '')}** {complexity_stars}")
121
+ when = opt.get("when", "")
122
+ if when:
123
+ lines.append(f" 适用: {when}")
124
+
125
+ guide = step_data.get("selection_guide", "")
126
+ if guide:
127
+ lines.append(f"\n{guide}")
128
+
129
+ lines.append("")
130
+
131
+ return "\n".join(lines)
132
+
133
+
134
+ class ConcernPackLoader:
135
+ """
136
+ 关注点增强包加载器
137
+
138
+ 职责:
139
+ 1. 从 templates/concerns/ 加载所有增强包定义
140
+ 2. 根据任务描述匹配相关增强包
141
+ 3. 提取角色增强提示词
142
+ 4. 生成检查清单和决策框架摘要
143
+ """
144
+
145
+ def __init__(self, concerns_dir: Optional[str] = None):
146
+ if concerns_dir is None:
147
+ base_dir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
148
+ concerns_dir = os.path.join(base_dir, "templates", "concerns")
149
+ self.concerns_dir = os.path.realpath(concerns_dir)
150
+ self._packs: Dict[str, ConcernPack] = {}
151
+ self._loaded = False
152
+ self._lock = threading.Lock()
153
+
154
+ def _load_all_packs(self):
155
+ """加载所有增强包"""
156
+ with self._lock:
157
+ if self._loaded:
158
+ return
159
+
160
+ if not os.path.isdir(self.concerns_dir):
161
+ logger.debug("Concerns directory not found: %s", self.concerns_dir)
162
+ self._loaded = True
163
+ return
164
+
165
+ for filename in os.listdir(self.concerns_dir):
166
+ if not filename.endswith((".yaml", ".yml")):
167
+ continue
168
+
169
+ filepath = os.path.join(self.concerns_dir, filename)
170
+ try:
171
+ pack = self._load_pack(filepath)
172
+ if pack:
173
+ self._packs[pack.concern_id] = pack
174
+ logger.debug("Loaded concern pack: %s (%s)", pack.concern_id, pack.name)
175
+ except Exception as e:
176
+ logger.warning("Failed to load concern pack %s: %s", filename, e)
177
+
178
+ self._loaded = True
179
+ logger.info("Loaded %d concern packs", len(self._packs))
180
+
181
+ def _load_pack(self, filepath: str) -> Optional[ConcernPack]:
182
+ """加载单个增强包文件"""
183
+ try:
184
+ import yaml
185
+ except ImportError:
186
+ return self._load_pack_simple(filepath)
187
+
188
+ with open(filepath, "r", encoding="utf-8") as f:
189
+ data = yaml.safe_load(f)
190
+
191
+ if not data or not data.get("concern_id"):
192
+ return None
193
+
194
+ return ConcernPack(
195
+ concern_id=data["concern_id"],
196
+ name=data.get("name", data["concern_id"]),
197
+ version=data.get("version", "1.0"),
198
+ description=data.get("description", ""),
199
+ triggers=data.get("triggers", {}),
200
+ decision_framework=data.get("decision_framework", {}),
201
+ checklist=data.get("checklist", {}),
202
+ role_enhancements=data.get("role_enhancements", {}),
203
+ )
204
+
205
+ def _load_pack_simple(self, filepath: str) -> Optional[ConcernPack]:
206
+ """无YAML依赖时的简单加载(JSON格式备选)"""
207
+ json_path = filepath.replace(".yaml", ".json").replace(".yml", ".json")
208
+ if os.path.exists(json_path):
209
+ import json
210
+ with open(json_path, "r", encoding="utf-8") as f:
211
+ data = json.load(f)
212
+ if data and data.get("concern_id"):
213
+ return ConcernPack(
214
+ concern_id=data["concern_id"],
215
+ name=data.get("name", data["concern_id"]),
216
+ version=data.get("version", "1.0"),
217
+ description=data.get("description", ""),
218
+ triggers=data.get("triggers", {}),
219
+ decision_framework=data.get("decision_framework", {}),
220
+ checklist=data.get("checklist", {}),
221
+ role_enhancements=data.get("role_enhancements", {}),
222
+ )
223
+ return None
224
+
225
+ def match_packs(self, task_description: str) -> List[ConcernPack]:
226
+ """
227
+ 根据任务描述匹配相关增强包
228
+
229
+ Args:
230
+ task_description: 任务描述文本
231
+
232
+ Returns:
233
+ 匹配到的增强包列表
234
+ """
235
+ self._load_all_packs()
236
+
237
+ if not self._packs:
238
+ return []
239
+
240
+ task_lower = task_description.lower()
241
+ matched = []
242
+
243
+ for pack_id, pack in self._packs.items():
244
+ keywords = pack.triggers.get("keywords", [])
245
+ if not keywords:
246
+ continue
247
+
248
+ match_count = 0
249
+ for kw in keywords:
250
+ if kw.lower() in task_lower:
251
+ match_count += 1
252
+
253
+ if match_count > 0:
254
+ matched.append((match_count, pack))
255
+
256
+ matched.sort(key=lambda x: x[0], reverse=True)
257
+
258
+ result = [pack for _, pack in matched]
259
+ if result:
260
+ pack_names = ", ".join(p.name for p in result)
261
+ logger.info("Matched %d concern pack(s): %s", len(result), pack_names)
262
+
263
+ return result
264
+
265
+ def get_role_enhancements(self, packs: List[ConcernPack], role_id: str) -> str:
266
+ """
267
+ 获取指定角色的增强提示词
268
+
269
+ Args:
270
+ packs: 匹配到的增强包列表
271
+ role_id: 角色ID(如 security, architect, tester)
272
+
273
+ Returns:
274
+ 合并后的增强提示词
275
+ """
276
+ enhancements = []
277
+
278
+ for pack in packs:
279
+ enhancement = pack.role_enhancements.get(role_id, "")
280
+ text = self._extract_enhancement_text(enhancement)
281
+ if text:
282
+ enhancements.append(text)
283
+
284
+ if enhancements:
285
+ return "\n\n".join(enhancements)
286
+ return ""
287
+
288
+ def get_all_role_enhancements(self, packs: List[ConcernPack]) -> Dict[str, str]:
289
+ """
290
+ 获取所有角色的增强提示词
291
+
292
+ Returns:
293
+ {role_id: enhancement_text} 字典
294
+ """
295
+ result = {}
296
+ for pack in packs:
297
+ for role_id, enhancement in pack.role_enhancements.items():
298
+ text = self._extract_enhancement_text(enhancement)
299
+ if not text:
300
+ continue
301
+ if role_id in result:
302
+ result[role_id] += "\n\n" + text
303
+ else:
304
+ result[role_id] = text
305
+ return result
306
+
307
+ @staticmethod
308
+ def _extract_enhancement_text(enhancement) -> str:
309
+ """从增强包数据中提取提示词文本"""
310
+ if isinstance(enhancement, str):
311
+ return enhancement
312
+ if isinstance(enhancement, dict):
313
+ return enhancement.get("extra_prompt", "")
314
+ return str(enhancement) if enhancement else ""
315
+
316
+ def get_combined_checklist(self, packs: List[ConcernPack]) -> str:
317
+ """获取合并后的检查清单摘要"""
318
+ parts = []
319
+ for pack in packs:
320
+ summary = pack.get_checklist_summary()
321
+ if summary:
322
+ parts.append(summary)
323
+ return "\n".join(parts)
324
+
325
+ def get_combined_decision_framework(self, packs: List[ConcernPack]) -> str:
326
+ """获取合并后的决策框架摘要"""
327
+ parts = []
328
+ for pack in packs:
329
+ summary = pack.get_decision_summary()
330
+ if summary:
331
+ parts.append(summary)
332
+ return "\n".join(parts)
333
+
334
+ def get_pack_info(self, packs: List[ConcernPack]) -> List[Dict[str, Any]]:
335
+ """获取增强包基本信息列表"""
336
+ return [
337
+ {
338
+ "concern_id": pack.concern_id,
339
+ "name": pack.name,
340
+ "description": pack.description,
341
+ "matched_keywords": list(pack.triggers.get("keywords", []))[:5],
342
+ }
343
+ for pack in packs
344
+ ]
345
+
346
+ def list_available_packs(self) -> List[Dict[str, str]]:
347
+ """列出所有可用的增强包"""
348
+ self._load_all_packs()
349
+ return [
350
+ {"id": pack.concern_id, "name": pack.name, "description": pack.description}
351
+ for pack in self._packs.values()
352
+ ]