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
@@ -9,6 +9,10 @@ from .options import Options
9
9
 
10
10
 
11
11
  def setup_ai_agent_env(ai_agent: bool, verbose: bool = False) -> None:
12
+ # Set debug environment variable if verbose is enabled
13
+ if verbose:
14
+ os.environ["CRACKERJACK_DEBUG"] = "1"
15
+
12
16
  if ai_agent:
13
17
  os.environ["AI_AGENT"] = "1"
14
18
  os.environ["AI_AGENT_DEBUG"] = "1"
@@ -19,7 +23,7 @@ def setup_ai_agent_env(ai_agent: bool, verbose: bool = False) -> None:
19
23
  if verbose:
20
24
  console = Console()
21
25
  console.print(
22
- "[bold cyan]🐛 AI Agent Debug Mode Configuration: [/bold cyan]",
26
+ "[bold cyan]🐛 AI Agent Debug Mode Configuration: [/ bold cyan]",
23
27
  )
24
28
  console.print(f" • AI Agent: {'✅ Enabled' if ai_agent else '❌ Disabled'}")
25
29
  console.print(
@@ -34,7 +38,6 @@ def setup_ai_agent_env(ai_agent: bool, verbose: bool = False) -> None:
34
38
  def handle_mcp_server(websocket_port: int | None = None) -> None:
35
39
  from crackerjack.mcp.server import main as start_mcp_main
36
40
 
37
- # Always pass current working directory as project path
38
41
  project_path = str(Path.cwd())
39
42
 
40
43
  if websocket_port:
@@ -47,45 +50,45 @@ def handle_monitor_mode(dev_mode: bool = False) -> None:
47
50
  from crackerjack.mcp.progress_monitor import run_progress_monitor
48
51
 
49
52
  console = Console()
50
- console.print("[bold cyan]🌟 Starting Multi-Project Progress Monitor[/bold cyan]")
53
+ console.print("[bold cyan]🌟 Starting Multi-Project Progress Monitor[/ bold cyan]")
51
54
  console.print(
52
- "[bold yellow]🐕 With integrated Service Watchdog and WebSocket polling[/bold yellow]",
55
+ "[bold yellow]🐕 With integrated Service Watchdog and WebSocket polling[/ bold yellow]",
53
56
  )
54
57
 
55
58
  try:
56
59
  asyncio.run(run_progress_monitor(dev_mode=dev_mode))
57
60
  except KeyboardInterrupt:
58
- console.print("\n[yellow]🛑 Monitor stopped[/yellow]")
61
+ console.print("\n[yellow]🛑 Monitor stopped[/ yellow]")
59
62
 
60
63
 
61
64
  def handle_enhanced_monitor_mode(dev_mode: bool = False) -> None:
62
65
  from crackerjack.mcp.enhanced_progress_monitor import run_enhanced_progress_monitor
63
66
 
64
67
  console = Console()
65
- console.print("[bold magenta]✨ Starting Enhanced Progress Monitor[/bold magenta]")
68
+ console.print("[bold magenta]✨ Starting Enhanced Progress Monitor[/ bold magenta]")
66
69
  console.print(
67
- "[bold cyan]📊 With advanced MetricCard widgets and modern web UI patterns[/bold cyan]",
70
+ "[bold cyan]📊 With advanced MetricCard widgets and modern web UI patterns[/ bold cyan]",
68
71
  )
69
72
 
70
73
  try:
71
74
  asyncio.run(run_enhanced_progress_monitor(dev_mode=dev_mode))
72
75
  except KeyboardInterrupt:
73
- console.print("\n[yellow]🛑 Enhanced Monitor stopped[/yellow]")
76
+ console.print("\n[yellow]🛑 Enhanced Monitor stopped[/ yellow]")
74
77
 
75
78
 
76
79
  def handle_dashboard_mode(dev_mode: bool = False) -> None:
77
80
  from crackerjack.mcp.dashboard import run_dashboard
78
81
 
79
82
  console = Console()
80
- console.print("[bold green]🎯 Starting Comprehensive Dashboard[/bold green]")
83
+ console.print("[bold green]🎯 Starting Comprehensive Dashboard[/ bold green]")
81
84
  console.print(
82
- "[bold cyan]📈 With system metrics, job tracking, and performance monitoring[/bold cyan]",
85
+ "[bold cyan]📈 With system metrics, job tracking, and performance monitoring[/ bold cyan]",
83
86
  )
84
87
 
85
88
  try:
86
89
  run_dashboard()
87
90
  except KeyboardInterrupt:
88
- console.print("\n[yellow]🛑 Dashboard stopped[/yellow]")
91
+ console.print("\n[yellow]🛑 Dashboard stopped[/ yellow]")
89
92
 
90
93
 
91
94
  def handle_watchdog_mode() -> None:
@@ -95,7 +98,7 @@ def handle_watchdog_mode() -> None:
95
98
  try:
96
99
  asyncio.run(start_watchdog())
97
100
  except KeyboardInterrupt:
98
- console.print("\n[yellow]🛑 Watchdog stopped[/yellow]")
101
+ console.print("\n[yellow]🛑 Watchdog stopped[/ yellow]")
99
102
 
100
103
 
101
104
  def handle_start_websocket_server(port: int = 8675) -> None:
@@ -120,14 +123,14 @@ def handle_stop_mcp_server() -> None:
120
123
  from crackerjack.services.server_manager import list_server_status, stop_all_servers
121
124
 
122
125
  console = Console()
123
- console.print("[bold red]🛑 Stopping MCP Servers[/bold red]")
126
+ console.print("[bold red]🛑 Stopping MCP Servers[/ bold red]")
124
127
 
125
128
  list_server_status(console)
126
129
 
127
130
  if stop_all_servers(console):
128
- console.print("\n[bold green]✅ All servers stopped successfully[/bold green]")
131
+ console.print("\n[bold green]✅ All servers stopped successfully[/ bold green]")
129
132
  else:
130
- console.print("\n[bold red]❌ Some servers failed to stop[/bold red]")
133
+ console.print("\n[bold red]❌ Some servers failed to stop[/ bold red]")
131
134
  raise SystemExit(1)
132
135
 
133
136
 
@@ -136,9 +139,9 @@ def handle_restart_mcp_server(websocket_port: int | None = None) -> None:
136
139
 
137
140
  console = Console()
138
141
  if restart_mcp_server(websocket_port, console):
139
- console.print("\n[bold green]✅ MCP server restart completed[/bold green]")
142
+ console.print("\n[bold green]✅ MCP server restart completed[/ bold green]")
140
143
  else:
141
- console.print("\n[bold red]❌ MCP server restart failed[/bold red]")
144
+ console.print("\n[bold red]❌ MCP server restart failed[/ bold red]")
142
145
  raise SystemExit(1)
143
146
 
144
147
 
@@ -161,6 +164,11 @@ def handle_standard_mode(
161
164
 
162
165
  console = Console()
163
166
 
167
+ # Configure global lock manager from CLI options
168
+ from crackerjack.executors.hook_lock_manager import hook_lock_manager
169
+
170
+ hook_lock_manager.configure_from_options(options)
171
+
164
172
  if orchestrated:
165
173
  handle_orchestrated_mode(options, job_id)
166
174
  else:
@@ -175,15 +183,20 @@ def handle_standard_mode(
175
183
  orchestrator = AsyncWorkflowOrchestrator(
176
184
  console=console,
177
185
  pkg_path=pkg_path,
186
+ dry_run=getattr(options, "dry_run", False),
178
187
  web_job_id=job_id,
188
+ verbose=options.verbose,
189
+ debug=getattr(options, "debug", False),
179
190
  )
180
191
  success = asyncio.run(orchestrator.run_complete_workflow_async(options))
181
192
  else:
182
193
  orchestrator = WorkflowOrchestrator(
183
194
  console=console,
184
195
  pkg_path=pkg_path,
196
+ dry_run=getattr(options, "dry_run", False),
185
197
  web_job_id=job_id,
186
198
  verbose=options.verbose,
199
+ debug=getattr(options, "debug", False),
187
200
  )
188
201
  success = asyncio.run(orchestrator.run_complete_workflow(options))
189
202
 
@@ -195,7 +208,12 @@ def handle_orchestrated_mode(options: Options, job_id: str | None = None) -> Non
195
208
  from rich.console import Console
196
209
 
197
210
  console = Console()
198
- console.print("[bold bright_blue]🚀 ORCHESTRATED MODE ENABLED[/bold bright_blue]")
211
+ console.print("[bold bright_blue]🚀 ORCHESTRATED MODE ENABLED[/ bold bright_blue]")
212
+
213
+ # Configure global lock manager from CLI options
214
+ from crackerjack.executors.hook_lock_manager import hook_lock_manager
215
+
216
+ hook_lock_manager.configure_from_options(options)
199
217
 
200
218
  try:
201
219
  from crackerjack.core.session_coordinator import SessionCoordinator
@@ -209,8 +227,8 @@ def handle_orchestrated_mode(options: Options, job_id: str | None = None) -> Non
209
227
  ProgressLevel,
210
228
  )
211
229
  except ImportError as e:
212
- console.print(f"[red]Orchestrated mode not available: {e}[/red]")
213
- console.print("[yellow]Falling back to standard mode[/yellow]")
230
+ console.print(f"[red]Orchestrated mode not available: {e}[/ red]")
231
+ console.print("[yellow]Falling back to standard mode[/ yellow]")
214
232
  handle_standard_mode(options, False, job_id)
215
233
  return
216
234
 
@@ -218,7 +236,7 @@ def handle_orchestrated_mode(options: Options, job_id: str | None = None) -> Non
218
236
  strategy = ExecutionStrategy(options.orchestration_strategy)
219
237
  except ValueError:
220
238
  console.print(
221
- f"[red]Invalid orchestration strategy: {options.orchestration_strategy}[/red]",
239
+ f"[red]Invalid orchestration strategy: {options.orchestration_strategy}[/ red]",
222
240
  )
223
241
  strategy = ExecutionStrategy.ADAPTIVE
224
242
 
@@ -226,14 +244,14 @@ def handle_orchestrated_mode(options: Options, job_id: str | None = None) -> Non
226
244
  progress = ProgressLevel(options.orchestration_progress)
227
245
  except ValueError:
228
246
  console.print(
229
- f"[red]Invalid progress level: {options.orchestration_progress}[/red]",
247
+ f"[red]Invalid progress level: {options.orchestration_progress}[/ red]",
230
248
  )
231
249
  progress = ProgressLevel.GRANULAR
232
250
 
233
251
  try:
234
252
  ai_mode = AICoordinationMode(options.orchestration_ai_mode)
235
253
  except ValueError:
236
- console.print(f"[red]Invalid AI mode: {options.orchestration_ai_mode}[/red]")
254
+ console.print(f"[red]Invalid AI mode: {options.orchestration_ai_mode}[/ red]")
237
255
  ai_mode = AICoordinationMode.SINGLE_AGENT
238
256
 
239
257
  config = OrchestrationConfig(
@@ -242,9 +260,9 @@ def handle_orchestrated_mode(options: Options, job_id: str | None = None) -> Non
242
260
  ai_coordination_mode=ai_mode,
243
261
  )
244
262
 
245
- console.print(f"[cyan]Execution Strategy: [/cyan] {strategy.value}")
246
- console.print(f"[cyan]Progress Level: [/cyan] {progress.value}")
247
- console.print(f"[cyan]AI Coordination: [/cyan] {ai_mode.value}")
263
+ console.print(f"[cyan]Execution Strategy: [/ cyan] {strategy.value}")
264
+ console.print(f"[cyan]Progress Level: [/ cyan] {progress.value}")
265
+ console.print(f"[cyan]AI Coordination: [/ cyan] {ai_mode.value}")
248
266
 
249
267
  pkg_path = Path.cwd()
250
268
  session = SessionCoordinator(console, pkg_path, web_job_id=job_id)
@@ -254,14 +272,14 @@ def handle_orchestrated_mode(options: Options, job_id: str | None = None) -> Non
254
272
  success = asyncio.run(orchestrator.execute_orchestrated_workflow(options))
255
273
  if success:
256
274
  console.print(
257
- "\n[bold green]🎉 ORCHESTRATED WORKFLOW COMPLETED SUCCESSFULLY![/bold green]",
275
+ "\n[bold green]🎉 ORCHESTRATED WORKFLOW COMPLETED SUCCESSFULLY ![/ bold green]",
258
276
  )
259
277
  else:
260
- console.print("\n[bold red]❌ ORCHESTRATED WORKFLOW FAILED[/bold red]")
278
+ console.print("\n[bold red]❌ ORCHESTRATED WORKFLOW FAILED[/ bold red]")
261
279
  sys.exit(1)
262
280
  except KeyboardInterrupt:
263
- console.print("\n[yellow]🛑 Orchestrated workflow interrupted[/yellow]")
281
+ console.print("\n[yellow]🛑 Orchestrated workflow interrupted[/ yellow]")
264
282
  sys.exit(130)
265
283
  except Exception as e:
266
- console.print(f"\n[red]💥 Orchestrated workflow error: {e}[/red]")
284
+ console.print(f"\n[red]💥 Orchestrated workflow error: {e}[/ red]")
267
285
  sys.exit(1)
@@ -115,7 +115,7 @@ class InteractiveWorkflowManager:
115
115
  deps = ["cleaning"] if options.clean else []
116
116
  self.add_task(
117
117
  "hooks",
118
- "Run pre - commit hooks (fast + comprehensive)",
118
+ "Run pre-commit hooks (fast + comprehensive)",
119
119
  "run_hooks_phase",
120
120
  dependencies=deps,
121
121
  )
@@ -284,7 +284,7 @@ class InteractiveWorkflowManager:
284
284
  self.setup_workflow(options)
285
285
  if not self.tasks:
286
286
  self.console.print(
287
- "[yellow]⚠️ No tasks to execute based on options[/yellow]",
287
+ "[yellow]⚠️ No tasks to execute based on options[/ yellow]",
288
288
  )
289
289
  return True
290
290
 
@@ -292,7 +292,7 @@ class InteractiveWorkflowManager:
292
292
  self.console.print(self.layout)
293
293
 
294
294
  if not Confirm.ask("\n🚀 Start workflow?", default=True):
295
- self.console.print("[yellow]⏹️ Workflow cancelled[/yellow]")
295
+ self.console.print("[yellow]⏹️ Workflow cancelled[/ yellow]")
296
296
  return False
297
297
 
298
298
  return True
@@ -328,7 +328,7 @@ class InteractiveWorkflowManager:
328
328
  )
329
329
 
330
330
  if not retry:
331
- self.console.print("[red]⏹️ Workflow stopped due to task failure[/red]")
331
+ self.console.print("[red]⏹️ Workflow stopped due to task failure[/ red]")
332
332
  return False
333
333
 
334
334
  failed_task.skip()
@@ -373,7 +373,7 @@ class InteractiveWorkflowManager:
373
373
  }
374
374
  status_text = task.status.name
375
375
  style = status_styles.get(task.status, "white")
376
- duration_text = f"{task.duration: .1f}s" if task.duration else " - "
376
+ duration_text = f"{task.duration: .1f}s" if task.duration else "-"
377
377
  details = task.error.message if task.error else task.description
378
378
  table.add_row(
379
379
  task.name,
@@ -385,11 +385,11 @@ class InteractiveWorkflowManager:
385
385
  self.console.print(table)
386
386
  if failed_count == 0:
387
387
  self.console.print(
388
- f"\n[bold green]🎉 Workflow completed ! {success_count} / {len(self.tasks)} tasks successful[/bold green]",
388
+ f"\n[bold green]🎉 Workflow completed ! {success_count} / {len(self.tasks)} tasks successful[/ bold green]",
389
389
  )
390
390
  else:
391
391
  self.console.print(
392
- f"\n[bold yellow]⚠️ Workflow completed with issues: {failed_count} failed, {skipped_count} skipped[/bold yellow]",
392
+ f"\n[bold yellow]⚠️ Workflow completed with issues: {failed_count} failed, {skipped_count} skipped[/ bold yellow]",
393
393
  )
394
394
 
395
395
 
@@ -414,7 +414,7 @@ class InteractiveCLI:
414
414
  if not success:
415
415
  raise SystemExit(1)
416
416
  except KeyboardInterrupt:
417
- self.console.print("\n[yellow]⏹️ Interactive session cancelled[/yellow]")
417
+ self.console.print("\n[yellow]⏹️ Interactive session cancelled[/ yellow]")
418
418
  raise SystemExit(130)
419
419
  except Exception as e:
420
420
  error = CrackerjackError(
@@ -426,10 +426,10 @@ class InteractiveCLI:
426
426
 
427
427
  def _show_welcome(self) -> None:
428
428
  welcome_panel = Panel(
429
- f"[bold cyan]Welcome to Crackerjack Interactive Mode ! [/bold cyan]\n\n"
429
+ f"[bold cyan]Welcome to Crackerjack Interactive Mode ! [/ bold cyan]\n\n"
430
430
  f"Version: {self.pkg_version}\n"
431
431
  f"This interactive interface will guide you through the crackerjack workflow\n"
432
- f"with real - time feedback and customizable options.",
432
+ f"with real-time feedback and customizable options.",
433
433
  title="🚀 Crackerjack Interactive",
434
434
  border_style="cyan",
435
435
  )
@@ -437,7 +437,7 @@ class InteractiveCLI:
437
437
  self.console.print()
438
438
 
439
439
  def _get_user_preferences(self, options: OptionsProtocol) -> OptionsProtocol:
440
- self.console.print("[bold]🔧 Workflow Configuration[/bold]")
440
+ self.console.print("[bold]🔧 Workflow Configuration[/ bold]")
441
441
  self.console.print("Configure your crackerjack workflow: \n")
442
442
  updated_options = type(options)(**vars(options))
443
443
  updated_options.clean = Confirm.ask(
@@ -23,6 +23,7 @@ class Options(BaseModel):
23
23
  publish: BumpOption | None = None
24
24
  bump: BumpOption | None = None
25
25
  verbose: bool = False
26
+ debug: bool = False
26
27
  clean: bool = False
27
28
  test: bool = False
28
29
  benchmark: bool = False
@@ -62,12 +63,28 @@ class Options(BaseModel):
62
63
  websocket_port: int | None = None
63
64
  dev: bool = False
64
65
  dashboard: bool = False
65
- max_iterations: int = 10
66
+ max_iterations: int = 5
66
67
  enterprise_batch: str | None = None
67
68
  monitor_dashboard: str | None = None
68
69
  coverage_status: bool = False
69
70
  coverage_goal: float | None = None
70
71
  no_coverage_ratchet: bool = False
72
+ skip_config_merge: bool = False
73
+ disable_global_locks: bool = False
74
+ global_lock_timeout: int = 600
75
+ global_lock_cleanup: bool = True
76
+ global_lock_dir: str | None = None
77
+ quick: bool = False
78
+ thorough: bool = False
79
+
80
+ @property
81
+ def effective_max_iterations(self) -> int:
82
+ """Get the effective max iterations based on quick/thorough flags."""
83
+ if self.quick:
84
+ return 3 # Quick mode: 3 iterations for CI/CD
85
+ if self.thorough:
86
+ return 8 # Thorough mode: 8 iterations for complex refactoring
87
+ return self.max_iterations # Default: 5 iterations
71
88
 
72
89
  @classmethod
73
90
  @field_validator("publish", "bump", mode="before")
@@ -112,6 +129,7 @@ CLI_OPTIONS = {
112
129
  help="Update pre-commit hooks configuration.",
113
130
  ),
114
131
  "verbose": typer.Option(False, "-v", "--verbose", help="Enable verbose output."),
132
+ "debug": typer.Option(False, "--debug", help="Enable debug output."),
115
133
  "publish": typer.Option(
116
134
  None,
117
135
  "-p",
@@ -130,7 +148,7 @@ CLI_OPTIONS = {
130
148
  False,
131
149
  "-x",
132
150
  "--clean",
133
- help="Remove docstrings, line comments, and unnecessary whitespace from source code (doesn't affect test files).",
151
+ help="Remove docstrings, line comments, and unnecessary whitespace from source code with automatic backup protection (doesn't affect test files).",
134
152
  ),
135
153
  "test": typer.Option(False, "-t", "--test", help="Run tests."),
136
154
  "benchmark": typer.Option(
@@ -275,9 +293,9 @@ CLI_OPTIONS = {
275
293
  help="Start the comprehensive dashboard with system metrics, job tracking, and performance monitoring.",
276
294
  ),
277
295
  "max_iterations": typer.Option(
278
- 10,
296
+ 5,
279
297
  "--max-iterations",
280
- help="Maximum number of iterations for AI agent auto-fixing workflows (default: 10).",
298
+ help="Maximum number of iterations for AI agent auto-fixing workflows (default: 5).",
281
299
  ),
282
300
  "ai_debug": typer.Option(
283
301
  False,
@@ -330,6 +348,36 @@ CLI_OPTIONS = {
330
348
  "--boost-coverage/--no-boost-coverage",
331
349
  help="Automatically improve test coverage after successful workflow execution (default: True).",
332
350
  ),
351
+ "disable_global_locks": typer.Option(
352
+ False,
353
+ "--disable-global-locks",
354
+ help="Disable global locking (allow concurrent hook execution across sessions).",
355
+ ),
356
+ "global_lock_timeout": typer.Option(
357
+ 600,
358
+ "--global-lock-timeout",
359
+ help="Global lock timeout in seconds (default: 600).",
360
+ ),
361
+ "global_lock_cleanup": typer.Option(
362
+ True,
363
+ "--cleanup-stale-locks/--no-cleanup-stale-locks",
364
+ help="Clean up stale global lock files before execution (default: True).",
365
+ ),
366
+ "global_lock_dir": typer.Option(
367
+ None,
368
+ "--global-lock-dir",
369
+ help="Custom directory for global lock files (default: ~/.crackerjack/locks).",
370
+ ),
371
+ "quick": typer.Option(
372
+ False,
373
+ "--quick",
374
+ help="Quick mode: Run with maximum 3 iterations (ideal for CI/CD).",
375
+ ),
376
+ "thorough": typer.Option(
377
+ False,
378
+ "--thorough",
379
+ help="Thorough mode: Run with maximum 8 iterations (for complex refactoring).",
380
+ ),
333
381
  }
334
382
 
335
383
 
@@ -339,6 +387,7 @@ def create_options(
339
387
  no_config_updates: bool,
340
388
  update_precommit: bool,
341
389
  verbose: bool,
390
+ debug: bool,
342
391
  publish: BumpOption | None,
343
392
  all: BumpOption | None,
344
393
  bump: BumpOption | None,
@@ -369,6 +418,12 @@ def create_options(
369
418
  coverage_goal: float | None,
370
419
  no_coverage_ratchet: bool,
371
420
  boost_coverage: bool,
421
+ disable_global_locks: bool,
422
+ global_lock_timeout: int,
423
+ global_lock_cleanup: bool,
424
+ global_lock_dir: str | None,
425
+ quick: bool,
426
+ thorough: bool,
372
427
  ) -> Options:
373
428
  return Options(
374
429
  commit=commit,
@@ -376,6 +431,7 @@ def create_options(
376
431
  no_config_updates=no_config_updates,
377
432
  update_precommit=update_precommit,
378
433
  verbose=verbose,
434
+ debug=debug,
379
435
  publish=publish,
380
436
  bump=bump,
381
437
  clean=clean,
@@ -406,4 +462,10 @@ def create_options(
406
462
  coverage_goal=coverage_goal,
407
463
  no_coverage_ratchet=no_coverage_ratchet,
408
464
  boost_coverage=boost_coverage,
465
+ disable_global_locks=disable_global_locks,
466
+ global_lock_timeout=global_lock_timeout,
467
+ global_lock_cleanup=global_lock_cleanup,
468
+ global_lock_dir=global_lock_dir,
469
+ quick=quick,
470
+ thorough=thorough,
409
471
  )