crackerjack 0.31.9__py3-none-any.whl → 0.31.12__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.

Potentially problematic release.


This version of crackerjack might be problematic. Click here for more details.

Files changed (155) hide show
  1. crackerjack/CLAUDE.md +288 -705
  2. crackerjack/__main__.py +22 -8
  3. crackerjack/agents/__init__.py +0 -3
  4. crackerjack/agents/architect_agent.py +0 -43
  5. crackerjack/agents/base.py +1 -9
  6. crackerjack/agents/coordinator.py +2 -148
  7. crackerjack/agents/documentation_agent.py +109 -81
  8. crackerjack/agents/dry_agent.py +122 -97
  9. crackerjack/agents/formatting_agent.py +3 -16
  10. crackerjack/agents/import_optimization_agent.py +1174 -130
  11. crackerjack/agents/performance_agent.py +956 -188
  12. crackerjack/agents/performance_helpers.py +229 -0
  13. crackerjack/agents/proactive_agent.py +1 -48
  14. crackerjack/agents/refactoring_agent.py +516 -246
  15. crackerjack/agents/refactoring_helpers.py +282 -0
  16. crackerjack/agents/security_agent.py +393 -90
  17. crackerjack/agents/test_creation_agent.py +1776 -120
  18. crackerjack/agents/test_specialist_agent.py +59 -15
  19. crackerjack/agents/tracker.py +0 -102
  20. crackerjack/api.py +145 -37
  21. crackerjack/cli/handlers.py +48 -30
  22. crackerjack/cli/interactive.py +11 -11
  23. crackerjack/cli/options.py +66 -4
  24. crackerjack/code_cleaner.py +808 -148
  25. crackerjack/config/global_lock_config.py +110 -0
  26. crackerjack/config/hooks.py +43 -64
  27. crackerjack/core/async_workflow_orchestrator.py +247 -97
  28. crackerjack/core/autofix_coordinator.py +192 -109
  29. crackerjack/core/enhanced_container.py +46 -63
  30. crackerjack/core/file_lifecycle.py +549 -0
  31. crackerjack/core/performance.py +9 -8
  32. crackerjack/core/performance_monitor.py +395 -0
  33. crackerjack/core/phase_coordinator.py +282 -95
  34. crackerjack/core/proactive_workflow.py +9 -58
  35. crackerjack/core/resource_manager.py +501 -0
  36. crackerjack/core/service_watchdog.py +490 -0
  37. crackerjack/core/session_coordinator.py +4 -8
  38. crackerjack/core/timeout_manager.py +504 -0
  39. crackerjack/core/websocket_lifecycle.py +475 -0
  40. crackerjack/core/workflow_orchestrator.py +355 -204
  41. crackerjack/dynamic_config.py +47 -6
  42. crackerjack/errors.py +3 -4
  43. crackerjack/executors/async_hook_executor.py +63 -13
  44. crackerjack/executors/cached_hook_executor.py +14 -14
  45. crackerjack/executors/hook_executor.py +100 -37
  46. crackerjack/executors/hook_lock_manager.py +856 -0
  47. crackerjack/executors/individual_hook_executor.py +120 -86
  48. crackerjack/intelligence/__init__.py +0 -7
  49. crackerjack/intelligence/adaptive_learning.py +13 -86
  50. crackerjack/intelligence/agent_orchestrator.py +15 -78
  51. crackerjack/intelligence/agent_registry.py +12 -59
  52. crackerjack/intelligence/agent_selector.py +31 -92
  53. crackerjack/intelligence/integration.py +1 -41
  54. crackerjack/interactive.py +9 -9
  55. crackerjack/managers/async_hook_manager.py +25 -8
  56. crackerjack/managers/hook_manager.py +9 -9
  57. crackerjack/managers/publish_manager.py +57 -59
  58. crackerjack/managers/test_command_builder.py +6 -36
  59. crackerjack/managers/test_executor.py +9 -61
  60. crackerjack/managers/test_manager.py +52 -62
  61. crackerjack/managers/test_manager_backup.py +77 -127
  62. crackerjack/managers/test_progress.py +4 -23
  63. crackerjack/mcp/cache.py +5 -12
  64. crackerjack/mcp/client_runner.py +10 -10
  65. crackerjack/mcp/context.py +64 -6
  66. crackerjack/mcp/dashboard.py +14 -11
  67. crackerjack/mcp/enhanced_progress_monitor.py +55 -55
  68. crackerjack/mcp/file_monitor.py +72 -42
  69. crackerjack/mcp/progress_components.py +103 -84
  70. crackerjack/mcp/progress_monitor.py +122 -49
  71. crackerjack/mcp/rate_limiter.py +12 -12
  72. crackerjack/mcp/server_core.py +16 -22
  73. crackerjack/mcp/service_watchdog.py +26 -26
  74. crackerjack/mcp/state.py +15 -0
  75. crackerjack/mcp/tools/core_tools.py +95 -39
  76. crackerjack/mcp/tools/error_analyzer.py +6 -32
  77. crackerjack/mcp/tools/execution_tools.py +1 -56
  78. crackerjack/mcp/tools/execution_tools_backup.py +35 -131
  79. crackerjack/mcp/tools/intelligence_tool_registry.py +0 -36
  80. crackerjack/mcp/tools/intelligence_tools.py +2 -55
  81. crackerjack/mcp/tools/monitoring_tools.py +308 -145
  82. crackerjack/mcp/tools/proactive_tools.py +12 -42
  83. crackerjack/mcp/tools/progress_tools.py +23 -15
  84. crackerjack/mcp/tools/utility_tools.py +3 -40
  85. crackerjack/mcp/tools/workflow_executor.py +40 -60
  86. crackerjack/mcp/websocket/app.py +0 -3
  87. crackerjack/mcp/websocket/endpoints.py +206 -268
  88. crackerjack/mcp/websocket/jobs.py +213 -66
  89. crackerjack/mcp/websocket/server.py +84 -6
  90. crackerjack/mcp/websocket/websocket_handler.py +137 -29
  91. crackerjack/models/config_adapter.py +3 -16
  92. crackerjack/models/protocols.py +162 -3
  93. crackerjack/models/resource_protocols.py +454 -0
  94. crackerjack/models/task.py +3 -3
  95. crackerjack/monitoring/__init__.py +0 -0
  96. crackerjack/monitoring/ai_agent_watchdog.py +25 -71
  97. crackerjack/monitoring/regression_prevention.py +28 -87
  98. crackerjack/orchestration/advanced_orchestrator.py +44 -78
  99. crackerjack/orchestration/coverage_improvement.py +10 -60
  100. crackerjack/orchestration/execution_strategies.py +16 -16
  101. crackerjack/orchestration/test_progress_streamer.py +61 -53
  102. crackerjack/plugins/base.py +1 -1
  103. crackerjack/plugins/managers.py +22 -20
  104. crackerjack/py313.py +65 -21
  105. crackerjack/services/backup_service.py +467 -0
  106. crackerjack/services/bounded_status_operations.py +627 -0
  107. crackerjack/services/cache.py +7 -9
  108. crackerjack/services/config.py +35 -52
  109. crackerjack/services/config_integrity.py +5 -16
  110. crackerjack/services/config_merge.py +542 -0
  111. crackerjack/services/contextual_ai_assistant.py +17 -19
  112. crackerjack/services/coverage_ratchet.py +51 -76
  113. crackerjack/services/debug.py +25 -39
  114. crackerjack/services/dependency_monitor.py +52 -50
  115. crackerjack/services/enhanced_filesystem.py +14 -11
  116. crackerjack/services/file_hasher.py +1 -1
  117. crackerjack/services/filesystem.py +1 -12
  118. crackerjack/services/git.py +78 -44
  119. crackerjack/services/health_metrics.py +31 -27
  120. crackerjack/services/initialization.py +281 -433
  121. crackerjack/services/input_validator.py +760 -0
  122. crackerjack/services/log_manager.py +16 -16
  123. crackerjack/services/logging.py +7 -6
  124. crackerjack/services/metrics.py +43 -43
  125. crackerjack/services/pattern_cache.py +2 -31
  126. crackerjack/services/pattern_detector.py +26 -63
  127. crackerjack/services/performance_benchmarks.py +20 -45
  128. crackerjack/services/regex_patterns.py +2887 -0
  129. crackerjack/services/regex_utils.py +537 -0
  130. crackerjack/services/secure_path_utils.py +683 -0
  131. crackerjack/services/secure_status_formatter.py +534 -0
  132. crackerjack/services/secure_subprocess.py +605 -0
  133. crackerjack/services/security.py +47 -10
  134. crackerjack/services/security_logger.py +492 -0
  135. crackerjack/services/server_manager.py +109 -50
  136. crackerjack/services/smart_scheduling.py +8 -25
  137. crackerjack/services/status_authentication.py +603 -0
  138. crackerjack/services/status_security_manager.py +442 -0
  139. crackerjack/services/thread_safe_status_collector.py +546 -0
  140. crackerjack/services/tool_version_service.py +1 -23
  141. crackerjack/services/unified_config.py +36 -58
  142. crackerjack/services/validation_rate_limiter.py +269 -0
  143. crackerjack/services/version_checker.py +9 -40
  144. crackerjack/services/websocket_resource_limiter.py +572 -0
  145. crackerjack/slash_commands/__init__.py +52 -2
  146. crackerjack/tools/__init__.py +0 -0
  147. crackerjack/tools/validate_input_validator_patterns.py +262 -0
  148. crackerjack/tools/validate_regex_patterns.py +198 -0
  149. {crackerjack-0.31.9.dist-info → crackerjack-0.31.12.dist-info}/METADATA +197 -12
  150. crackerjack-0.31.12.dist-info/RECORD +178 -0
  151. crackerjack/cli/facade.py +0 -104
  152. crackerjack-0.31.9.dist-info/RECORD +0 -149
  153. {crackerjack-0.31.9.dist-info → crackerjack-0.31.12.dist-info}/WHEEL +0 -0
  154. {crackerjack-0.31.9.dist-info → crackerjack-0.31.12.dist-info}/entry_points.txt +0 -0
  155. {crackerjack-0.31.9.dist-info → crackerjack-0.31.12.dist-info}/licenses/LICENSE +0 -0
@@ -1,10 +1,3 @@
1
- """
2
- Regression Prevention System
3
-
4
- Prevents known failures from reoccurring in the AI agent pipeline.
5
- Creates a comprehensive safety net against surprise failures.
6
- """
7
-
8
1
  import hashlib
9
2
  import json
10
3
  import typing as t
@@ -13,21 +6,20 @@ from datetime import datetime, timedelta
13
6
  from pathlib import Path
14
7
  from typing import Any
15
8
 
16
- from crackerjack.agents.base import FixResult, Issue, IssueType
17
9
  from rich.console import Console
18
10
  from rich.panel import Panel
19
11
  from rich.table import Table
20
12
 
13
+ from crackerjack.agents.base import FixResult, Issue, IssueType
14
+
21
15
 
22
16
  @dataclass
23
17
  class RegressionPattern:
24
- """Known failure pattern to prevent regression."""
25
-
26
18
  pattern_id: str
27
19
  name: str
28
20
  description: str
29
- issue_signature: str # Hash of issue characteristics
30
- failure_indicators: list[str] # Strings that indicate this failure
21
+ issue_signature: str
22
+ failure_indicators: list[str]
31
23
  fix_applied_date: datetime
32
24
  agent_name: str
33
25
  issue_type: IssueType
@@ -37,34 +29,26 @@ class RegressionPattern:
37
29
 
38
30
  @dataclass
39
31
  class RegressionAlert:
40
- """Alert for detected regression."""
41
-
42
32
  pattern_id: str
43
33
  pattern_name: str
44
34
  detected_at: datetime
45
35
  issue_id: str
46
36
  agent_name: str
47
37
  failure_evidence: list[str]
48
- severity: str # "warning", "error", "critical"
38
+ severity: str
49
39
 
50
40
 
51
41
  class RegressionPreventionSystem:
52
- """System to prevent known failure patterns from recurring."""
53
-
54
42
  def __init__(self, console: Console | None = None):
55
43
  self.console = console or Console()
56
44
  self.known_patterns: dict[str, RegressionPattern] = {}
57
45
  self.regression_alerts: list[RegressionAlert] = []
58
46
  self.prevention_active = True
59
47
 
60
- # Load known patterns
61
48
  self._initialize_known_patterns()
62
49
  self._load_patterns_from_file()
63
50
 
64
51
  def _initialize_known_patterns(self):
65
- """Initialize patterns for known critical failures."""
66
-
67
- # Pattern 1: detect_agent_needs complexity failure
68
52
  self.register_regression_pattern(
69
53
  pattern_id="detect_agent_needs_complexity_22",
70
54
  name="detect_agent_needs Complexity Failure",
@@ -72,7 +56,7 @@ class RegressionPreventionSystem:
72
56
  issue_signature=self._generate_issue_signature(
73
57
  issue_type=IssueType.COMPLEXITY,
74
58
  message="Function detect_agent_needs has complexity 22",
75
- file_path="crackerjack/mcp/tools/execution_tools.py",
59
+ file_path="crackerjack / mcp / tools / execution_tools.py",
76
60
  ),
77
61
  failure_indicators=[
78
62
  "Could not automatically reduce complexity",
@@ -88,7 +72,7 @@ class RegressionPreventionSystem:
88
72
  "issue": {
89
73
  "type": "COMPLEXITY",
90
74
  "message": "Function detect_agent_needs has complexity 22 (exceeds limit of 15)",
91
- "file_path": "/Users/les/Projects/crackerjack/crackerjack/mcp/tools/execution_tools.py",
75
+ "file_path": "/ Users / les / Projects / crackerjack / crackerjack / mcp / tools / execution_tools.py",
92
76
  },
93
77
  "expected_success": True,
94
78
  "expected_confidence": 0.8,
@@ -96,7 +80,6 @@ class RegressionPreventionSystem:
96
80
  ],
97
81
  )
98
82
 
99
- # Pattern 2: Agent coordination infinite loops
100
83
  self.register_regression_pattern(
101
84
  pattern_id="agent_coordination_infinite_loop",
102
85
  name="Agent Coordination Infinite Loop",
@@ -119,7 +102,6 @@ class RegressionPreventionSystem:
119
102
  ],
120
103
  )
121
104
 
122
- # Pattern 3: RefactoringAgent returning no changes
123
105
  self.register_regression_pattern(
124
106
  pattern_id="refactoring_agent_no_changes",
125
107
  name="RefactoringAgent No Changes Applied",
@@ -140,7 +122,6 @@ class RegressionPreventionSystem:
140
122
  ],
141
123
  )
142
124
 
143
- # Pattern 4: Import optimization failures
144
125
  self.register_regression_pattern(
145
126
  pattern_id="import_optimization_no_effect",
146
127
  name="Import Optimization No Effect",
@@ -156,7 +137,6 @@ class RegressionPreventionSystem:
156
137
  issue_type=IssueType.IMPORT_ERROR,
157
138
  )
158
139
 
159
- # Pattern 5: Test agent failures
160
140
  self.register_regression_pattern(
161
141
  pattern_id="test_agent_instantiation_failure",
162
142
  name="Test Agent Instantiation Failure",
@@ -183,7 +163,6 @@ class RegressionPreventionSystem:
183
163
  issue_type: IssueType,
184
164
  test_cases: list[dict[str, Any]] | None = None,
185
165
  ):
186
- """Register a new regression pattern."""
187
166
  pattern = RegressionPattern(
188
167
  pattern_id=pattern_id,
189
168
  name=name,
@@ -206,14 +185,12 @@ class RegressionPreventionSystem:
206
185
  file_path: str = "",
207
186
  line_number: int = 0,
208
187
  ) -> str:
209
- """Generate unique signature for an issue."""
210
- content = f"{issue_type.value}:{message}:{file_path}:{line_number}"
188
+ content = f"{issue_type.value}: {message}: {file_path}: {line_number}"
211
189
  return hashlib.md5(content.encode(), usedforsecurity=False).hexdigest()[:12]
212
190
 
213
191
  async def check_for_regression(
214
192
  self, agent_name: str, issue: Issue, result: FixResult
215
193
  ) -> RegressionAlert | None:
216
- """Check if this represents a known regression pattern."""
217
194
  if not self.prevention_active:
218
195
  return None
219
196
 
@@ -224,7 +201,6 @@ class RegressionPreventionSystem:
224
201
  line_number=issue.line_number or 0,
225
202
  )
226
203
 
227
- # Check against known patterns
228
204
  for pattern_id, pattern in self.known_patterns.items():
229
205
  if not pattern.prevention_enabled:
230
206
  continue
@@ -252,16 +228,13 @@ class RegressionPreventionSystem:
252
228
  issue: Issue,
253
229
  result: FixResult,
254
230
  ) -> list[str] | None:
255
- """Check if a pattern matches the current issue."""
256
231
  is_regression = False
257
232
  evidence = []
258
233
 
259
- # Check signature match
260
234
  if pattern.issue_signature == issue_signature:
261
235
  is_regression = True
262
236
  evidence.append(f"Exact issue signature match: {issue_signature}")
263
237
 
264
- # Check failure indicators
265
238
  failure_text = self._build_failure_text(result, issue)
266
239
  matched_indicators = self._find_matching_indicators(
267
240
  pattern.failure_indicators, failure_text
@@ -271,7 +244,6 @@ class RegressionPreventionSystem:
271
244
  is_regression = True
272
245
  evidence.extend([f"Matched indicator: {ind}" for ind in matched_indicators])
273
246
 
274
- # Agent-specific checks
275
247
  if self._check_agent_specific_failure(pattern, agent_name, issue, result):
276
248
  is_regression = True
277
249
  evidence.append(
@@ -281,7 +253,6 @@ class RegressionPreventionSystem:
281
253
  return evidence if is_regression else None
282
254
 
283
255
  def _build_failure_text(self, result: FixResult, issue: Issue) -> str:
284
- """Build concatenated text for failure indicator matching."""
285
256
  return " ".join(
286
257
  [
287
258
  " ".join(result.remaining_issues),
@@ -295,7 +266,6 @@ class RegressionPreventionSystem:
295
266
  def _find_matching_indicators(
296
267
  self, indicators: list[str], failure_text: str
297
268
  ) -> list[str]:
298
- """Find indicators that match in the failure text."""
299
269
  return [
300
270
  indicator
301
271
  for indicator in indicators
@@ -309,7 +279,6 @@ class RegressionPreventionSystem:
309
279
  issue: Issue,
310
280
  result: FixResult,
311
281
  ) -> bool:
312
- """Check if this is an agent-specific failure pattern."""
313
282
  return (
314
283
  pattern.agent_name == agent_name
315
284
  and pattern.issue_type == issue.type
@@ -325,7 +294,6 @@ class RegressionPreventionSystem:
325
294
  issue: Issue,
326
295
  evidence: list[str],
327
296
  ) -> RegressionAlert:
328
- """Create a regression alert with appropriate severity."""
329
297
  severity = self._determine_alert_severity(pattern_id)
330
298
 
331
299
  return RegressionAlert(
@@ -339,7 +307,6 @@ class RegressionPreventionSystem:
339
307
  )
340
308
 
341
309
  def _determine_alert_severity(self, pattern_id: str) -> str:
342
- """Determine alert severity based on pattern type."""
343
310
  if "detect_agent_needs" in pattern_id:
344
311
  return "critical"
345
312
  elif "infinite_loop" in pattern_id:
@@ -347,7 +314,6 @@ class RegressionPreventionSystem:
347
314
  return "error"
348
315
 
349
316
  async def _handle_regression_alert(self, alert: RegressionAlert):
350
- """Handle a detected regression alert."""
351
317
  color = {"warning": "yellow", "error": "red", "critical": "bold red"}.get(
352
318
  alert.severity, "white"
353
319
  )
@@ -357,32 +323,29 @@ class RegressionPreventionSystem:
357
323
  self.console.print(f"\n{icon} [bold {color}]REGRESSION DETECTED[/bold {color}]")
358
324
  self.console.print(
359
325
  Panel(
360
- f"[bold]Pattern:[/bold] {alert.pattern_name}\n"
361
- f"[bold]Agent:[/bold] {alert.agent_name}\n"
362
- f"[bold]Issue ID:[/bold] {alert.issue_id}\n"
363
- f"[bold]Evidence:[/bold]\n"
364
- + "\n".join(f" • {e}" for e in alert.failure_evidence),
326
+ f"[bold]Pattern: [/bold] {alert.pattern_name}\n"
327
+ f"[bold]Agent: [/bold] {alert.agent_name}\n"
328
+ f"[bold]Issue ID: [/bold] {alert.issue_id}\n"
329
+ f"[bold]Evidence: [/bold]\n"
330
+ + "\n".join(f" • {e}" for e in alert.failure_evidence),
365
331
  title=f"{alert.severity.upper()} Regression Alert",
366
332
  border_style=color,
367
333
  )
368
334
  )
369
335
 
370
- # Immediate actions based on severity
371
336
  if alert.severity == "critical":
372
337
  self.console.print(
373
- "[bold red]🚨 CRITICAL REGRESSION - IMMEDIATE ACTION REQUIRED[/bold red]"
338
+ "[bold red]🚨 CRITICAL REGRESSION-IMMEDIATE ACTION REQUIRED[/bold red]"
374
339
  )
375
- self.console.print("Recommended actions:")
376
- self.console.print(" 1. Stop current AI agent execution")
377
- self.console.print(" 2. Run regression tests immediately")
378
- self.console.print(" 3. Check recent agent code changes")
379
- self.console.print(" 4. Verify fix implementation")
340
+ self.console.print("Recommended actions: ")
341
+ self.console.print(" 1. Stop current AI agent execution")
342
+ self.console.print(" 2. Run regression tests immediately")
343
+ self.console.print(" 3. Check recent agent code changes")
344
+ self.console.print(" 4. Verify fix implementation")
380
345
 
381
- # Log to file for persistent tracking
382
346
  self._log_critical_regression(alert)
383
347
 
384
348
  def _log_critical_regression(self, alert: RegressionAlert):
385
- """Log critical regression for persistent tracking."""
386
349
  log_file = Path(".crackerjack") / "critical_regressions.log"
387
350
  log_file.parent.mkdir(exist_ok=True)
388
351
 
@@ -399,7 +362,6 @@ class RegressionPreventionSystem:
399
362
  f.write(json.dumps(log_entry) + "\n")
400
363
 
401
364
  def run_regression_tests(self) -> dict[str, t.Any]:
402
- """Run all regression test cases."""
403
365
  self.console.print("🧪 [bold]Running Regression Prevention Tests[/bold]")
404
366
 
405
367
  results: dict[str, t.Any] = {
@@ -410,7 +372,6 @@ class RegressionPreventionSystem:
410
372
  "failures": [],
411
373
  }
412
374
 
413
- # Type hints for clarity
414
375
  patterns_tested: int = 0
415
376
  tests_passed: int = 0
416
377
  tests_failed: int = 0
@@ -425,13 +386,11 @@ class RegressionPreventionSystem:
425
386
 
426
387
  for i, test_case in enumerate(pattern.test_cases):
427
388
  try:
428
- # This would need integration with actual agent testing
429
- # For now, simulate test execution
430
389
  test_passed = self._simulate_regression_test(test_case, pattern)
431
390
 
432
391
  if test_passed:
433
392
  tests_passed += 1
434
- self.console.print(f" ✅ Test case {i + 1} passed")
393
+ self.console.print(f" ✅ Test case {i + 1} passed")
435
394
  else:
436
395
  tests_failed += 1
437
396
  failures.append(
@@ -443,25 +402,23 @@ class RegressionPreventionSystem:
443
402
  ),
444
403
  }
445
404
  )
446
- self.console.print(f" ❌ Test case {i + 1} failed")
405
+ self.console.print(f" ❌ Test case {i + 1} failed")
447
406
 
448
407
  except Exception as e:
449
408
  tests_failed += 1
450
409
  failures.append(
451
410
  {"pattern_id": pattern_id, "test_case": i + 1, "error": str(e)}
452
411
  )
453
- self.console.print(f" ❌ Test case {i + 1} error: {e}")
412
+ self.console.print(f" ❌ Test case {i + 1} error: {e}")
454
413
 
455
- # Update results with final counts
456
414
  results["patterns_tested"] = patterns_tested
457
415
  results["tests_passed"] = tests_passed
458
416
  results["tests_failed"] = tests_failed
459
417
  results["failures"] = failures
460
418
 
461
- # Report results
462
419
  if tests_failed > 0:
463
420
  self.console.print(
464
- f"🚨 [bold red]{tests_failed} regression tests failed![/bold red]"
421
+ f"🚨 [bold red]{tests_failed} regression tests failed ![/bold red]"
465
422
  )
466
423
  else:
467
424
  self.console.print(
@@ -473,27 +430,19 @@ class RegressionPreventionSystem:
473
430
  def _simulate_regression_test(
474
431
  self, test_case: dict[str, Any], pattern: RegressionPattern
475
432
  ) -> bool:
476
- """Simulate running a regression test case."""
477
- # This is a placeholder - in practice would run actual agent tests
478
-
479
- # Simulate test based on test case requirements
480
433
  if "expected_success" in test_case:
481
- # Simulate that our fixes work
482
434
  if pattern.pattern_id == "detect_agent_needs_complexity_22":
483
- return True # Our fix should work
435
+ return True
484
436
 
485
437
  if "max_iterations" in test_case:
486
- # Simulate that coordination doesn't loop infinitely
487
438
  return True
488
439
 
489
440
  if "should_modify_files" in test_case:
490
- # Simulate that agents apply changes
491
441
  return True
492
442
 
493
- return True # Default to passing for now
443
+ return True
494
444
 
495
445
  def create_prevention_dashboard(self) -> Table:
496
- """Create regression prevention dashboard."""
497
446
  table = Table(
498
447
  title="Regression Prevention Dashboard",
499
448
  header_style="bold magenta",
@@ -507,7 +456,6 @@ class RegressionPreventionSystem:
507
456
  table.add_column("Test Cases", justify="center", width=10)
508
457
 
509
458
  for pattern in self.known_patterns.values():
510
- # Find recent alerts for this pattern
511
459
  recent_alerts = [
512
460
  a
513
461
  for a in self.regression_alerts
@@ -534,9 +482,9 @@ class RegressionPreventionSystem:
534
482
  latest = max(recent_alerts, key=lambda a: a.detected_at)
535
483
  delta = datetime.now() - latest.detected_at
536
484
  if delta.seconds < 3600:
537
- last_alert = f"{delta.seconds // 60}m ago"
485
+ last_alert = f"{delta.seconds / 60}m ago"
538
486
  else:
539
- last_alert = f"{delta.seconds // 3600}h ago"
487
+ last_alert = f"{delta.seconds / 3600}h ago"
540
488
 
541
489
  table.add_row(
542
490
  pattern.name[:24] + ("..." if len(pattern.name) > 24 else ""),
@@ -550,12 +498,10 @@ class RegressionPreventionSystem:
550
498
  return table
551
499
 
552
500
  def get_recent_regressions(self, hours: int = 24) -> list[RegressionAlert]:
553
- """Get regression alerts from recent hours."""
554
501
  cutoff = datetime.now() - timedelta(hours=hours)
555
502
  return [alert for alert in self.regression_alerts if alert.detected_at > cutoff]
556
503
 
557
504
  def _save_patterns_to_file(self):
558
- """Save patterns to persistent storage."""
559
505
  patterns_file = Path(".crackerjack") / "regression_patterns.json"
560
506
  patterns_file.parent.mkdir(exist_ok=True)
561
507
 
@@ -581,7 +527,6 @@ class RegressionPreventionSystem:
581
527
  json.dump(data, f, indent=2)
582
528
 
583
529
  def _load_patterns_from_file(self):
584
- """Load additional patterns from file."""
585
530
  patterns_file = Path(".crackerjack") / "regression_patterns.json"
586
531
  if not patterns_file.exists():
587
532
  return
@@ -591,7 +536,7 @@ class RegressionPreventionSystem:
591
536
  data = json.load(f)
592
537
 
593
538
  for pid, pdata in data.get("patterns", {}).items():
594
- if pid not in self.known_patterns: # Don't override built-in patterns
539
+ if pid not in self.known_patterns:
595
540
  pattern = RegressionPattern(
596
541
  pattern_id=pid,
597
542
  name=pdata["name"],
@@ -612,17 +557,14 @@ class RegressionPreventionSystem:
612
557
  self.console.print(f"⚠️ Warning: Could not load patterns from file: {e}")
613
558
 
614
559
 
615
- # Integration function for easy use
616
560
  async def monitor_for_regressions(
617
561
  agent_name: str, issue: Issue, result: FixResult
618
562
  ) -> RegressionAlert | None:
619
- """Quick function to check for regressions during agent execution."""
620
563
  prevention_system = RegressionPreventionSystem()
621
564
  return await prevention_system.check_for_regression(agent_name, issue, result)
622
565
 
623
566
 
624
567
  if __name__ == "__main__":
625
- # Demo the regression prevention system
626
568
  console = Console()
627
569
  system = RegressionPreventionSystem(console)
628
570
 
@@ -631,7 +573,6 @@ if __name__ == "__main__":
631
573
  f"\n📊 Monitoring {len(system.known_patterns)} known regression patterns"
632
574
  )
633
575
 
634
- # Run regression tests
635
576
  results = system.run_regression_tests()
636
577
  console.print(f"\n✅ Regression testing complete: {results}")
637
578