crackerjack 0.31.10__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 +281 -94
  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 +343 -209
  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 +17 -63
  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 +44 -73
  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 +71 -47
  119. crackerjack/services/health_metrics.py +31 -27
  120. crackerjack/services/initialization.py +276 -428
  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.10.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.10.dist-info/RECORD +0 -149
  153. {crackerjack-0.31.10.dist-info → crackerjack-0.31.12.dist-info}/WHEEL +0 -0
  154. {crackerjack-0.31.10.dist-info → crackerjack-0.31.12.dist-info}/entry_points.txt +0 -0
  155. {crackerjack-0.31.10.dist-info → crackerjack-0.31.12.dist-info}/licenses/LICENSE +0 -0
@@ -4,10 +4,32 @@ import typing as t
4
4
  from contextlib import suppress
5
5
 
6
6
  from crackerjack.mcp.context import get_context
7
+ from crackerjack.services.bounded_status_operations import (
8
+ execute_bounded_status_operation,
9
+ )
10
+ from crackerjack.services.secure_status_formatter import (
11
+ StatusVerbosity,
12
+ format_secure_status,
13
+ get_secure_status_formatter,
14
+ )
15
+ from crackerjack.services.status_authentication import (
16
+ authenticate_status_request,
17
+ get_status_authenticator,
18
+ )
19
+ from crackerjack.services.status_security_manager import (
20
+ get_status_security_manager,
21
+ secure_status_operation,
22
+ validate_status_request,
23
+ )
24
+ from crackerjack.services.thread_safe_status_collector import (
25
+ get_thread_safe_status_collector,
26
+ )
27
+ from crackerjack.services.websocket_resource_limiter import (
28
+ get_websocket_resource_limiter,
29
+ )
7
30
 
8
31
 
9
32
  def _suggest_agent_for_context(state_manager) -> dict[str, t.Any]:
10
- """Suggest appropriate agents based on current development context."""
11
33
  suggestions = {
12
34
  "recommended_agent": None,
13
35
  "reason": "",
@@ -15,24 +37,22 @@ def _suggest_agent_for_context(state_manager) -> dict[str, t.Any]:
15
37
  "priority": "MEDIUM",
16
38
  }
17
39
 
18
- # Check for errors or failures that need specific agents
19
40
  with suppress(Exception):
20
41
  recent_errors = getattr(state_manager, "recent_errors", [])
21
42
  stage_statuses = _get_stage_status_dict(state_manager)
22
43
 
23
- # Test failures suggest test specialist
24
44
  if stage_statuses.get("tests") == "failed" or any(
25
45
  "test" in str(error).lower() for error in recent_errors
26
46
  ):
27
47
  suggestions.update(
28
48
  {
29
- "recommended_agent": "crackerjack-test-specialist",
30
- "reason": "Test failures detected - specialist needed for debugging and fixes",
31
- "usage": 'Task tool with subagent_type="crackerjack-test-specialist"',
49
+ "recommended_agent": "crackerjack - test-specialist",
50
+ "reason": "Test failures detected-specialist needed for debugging and fixes",
51
+ "usage": 'Task tool with subagent_type ="crackerjack - test-specialist"',
32
52
  "priority": "HIGH",
33
53
  }
34
54
  )
35
- # Security issues suggest security auditor
55
+
36
56
  elif any(
37
57
  "security" in str(error).lower() or "bandit" in str(error).lower()
38
58
  for error in recent_errors
@@ -40,28 +60,28 @@ def _suggest_agent_for_context(state_manager) -> dict[str, t.Any]:
40
60
  suggestions.update(
41
61
  {
42
62
  "recommended_agent": "security-auditor",
43
- "reason": "Security issues detected - immediate audit required",
44
- "usage": 'Task tool with subagent_type="security-auditor"',
63
+ "reason": "Security issues detected-immediate audit required",
64
+ "usage": 'Task tool with subagent_type ="security-auditor"',
45
65
  "priority": "HIGH",
46
66
  }
47
67
  )
48
- # Complexity issues suggest architect
68
+
49
69
  elif any("complex" in str(error).lower() for error in recent_errors):
50
70
  suggestions.update(
51
71
  {
52
72
  "recommended_agent": "crackerjack-architect",
53
- "reason": "Complexity issues detected - architectural review needed",
54
- "usage": 'Task tool with subagent_type="crackerjack-architect"',
73
+ "reason": "Complexity issues detected-architectural review needed",
74
+ "usage": 'Task tool with subagent_type ="crackerjack-architect"',
55
75
  "priority": "HIGH",
56
76
  }
57
77
  )
58
- # Default recommendation for Python projects
78
+
59
79
  else:
60
80
  suggestions.update(
61
81
  {
62
82
  "recommended_agent": "crackerjack-architect",
63
- "reason": "Python project - ensure crackerjack compliance from the start",
64
- "usage": 'Task tool with subagent_type="crackerjack-architect"',
83
+ "reason": "Python project-ensure crackerjack compliance from the start",
84
+ "usage": 'Task tool with subagent_type ="crackerjack-architect"',
65
85
  "priority": "MEDIUM",
66
86
  }
67
87
  )
@@ -70,7 +90,6 @@ def _suggest_agent_for_context(state_manager) -> dict[str, t.Any]:
70
90
 
71
91
 
72
92
  def _create_error_response(message: str, success: bool = False) -> str:
73
- """Utility function to create standardized error responses."""
74
93
  import json
75
94
 
76
95
  return json.dumps({"error": message, "success": success})
@@ -145,7 +164,6 @@ def _add_state_manager_stats(stats: dict, state_manager) -> None:
145
164
 
146
165
 
147
166
  def _get_active_jobs(context) -> list[dict[str, t.Any]]:
148
- """Get information about active jobs from progress files."""
149
167
  jobs = []
150
168
  if not context.progress_dir.exists():
151
169
  return jobs
@@ -174,80 +192,96 @@ def _get_active_jobs(context) -> list[dict[str, t.Any]]:
174
192
  return jobs
175
193
 
176
194
 
177
- async def _get_comprehensive_status() -> dict[str, t.Any]:
178
- """Get comprehensive status of MCP server, WebSocket server, and active jobs."""
195
+ async def _get_comprehensive_status_secure(
196
+ client_id: str = "mcp_client",
197
+ client_ip: str = "127.0.0.1",
198
+ auth_header: str | None = None,
199
+ verbosity: StatusVerbosity = StatusVerbosity.STANDARD,
200
+ ) -> dict[str, t.Any]:
201
+ """Get comprehensive status with full security integration."""
202
+
203
+ # 1. Authentication
204
+ auth_manager = get_status_authenticator()
179
205
  try:
180
- context = get_context()
181
- except RuntimeError:
182
- context = None
206
+ credentials = await authenticate_status_request(
207
+ auth_header, client_ip, "get_comprehensive_status"
208
+ )
209
+
210
+ # Check if operation is allowed for this auth level
211
+ if not auth_manager.is_operation_allowed(
212
+ "get_comprehensive_status", credentials.access_level
213
+ ):
214
+ return {"error": "Insufficient privileges for comprehensive status"}
183
215
 
184
- if not context:
185
- return {"error": "Server context not available"}
216
+ except Exception as e:
217
+ return {"error": f"Authentication failed: {e}"}
186
218
 
219
+ # 2. Security validation
187
220
  try:
188
- # Get server status
189
- from crackerjack.services.server_manager import (
190
- find_mcp_server_processes,
191
- find_websocket_server_processes,
221
+ await validate_status_request(client_id, "get_comprehensive_status", {})
222
+ except Exception as e:
223
+ return {"error": f"Security validation failed: {e}"}
224
+
225
+ # 3. Resource management with bounded operations
226
+ try:
227
+ return await execute_bounded_status_operation(
228
+ "status_collection",
229
+ client_id,
230
+ _collect_comprehensive_status_internal,
231
+ client_id,
232
+ verbosity,
192
233
  )
234
+ except Exception as e:
235
+ return {"error": f"Resource limit exceeded: {e}"}
193
236
 
194
- mcp_processes = find_mcp_server_processes()
195
- websocket_processes = find_websocket_server_processes()
196
237
 
197
- # Get active jobs
198
- active_jobs = _get_active_jobs(context)
238
+ async def _collect_comprehensive_status_internal(
239
+ client_id: str = "mcp_client",
240
+ verbosity: StatusVerbosity = StatusVerbosity.STANDARD,
241
+ ) -> dict[str, t.Any]:
242
+ """Internal comprehensive status collection using thread-safe collector."""
199
243
 
200
- # Get WebSocket server status from context
201
- websocket_status = None
202
- try:
203
- websocket_status = await context.get_websocket_server_status()
204
- except (ConnectionError, TimeoutError) as e:
205
- websocket_status = {"error": f"Connection failed: {e}"}
206
- except Exception as e:
207
- websocket_status = {"error": f"Status unavailable: {e}"}
244
+ # Use thread-safe status collector
245
+ collector = get_thread_safe_status_collector()
208
246
 
209
- # Build comprehensive status
247
+ try:
248
+ # Collect status with thread safety and proper timeout handling
249
+ snapshot = await collector.collect_comprehensive_status(
250
+ client_id=client_id,
251
+ )
252
+
253
+ # Build final status from snapshot
210
254
  status = {
211
- "services": {
212
- "mcp_server": {
213
- "running": len(mcp_processes) > 0,
214
- "processes": mcp_processes,
215
- },
216
- "websocket_server": {
217
- "running": len(websocket_processes) > 0,
218
- "processes": websocket_processes,
219
- "port": getattr(context, "websocket_server_port", 8675),
220
- "status": websocket_status,
221
- },
255
+ "services": snapshot.services,
256
+ "jobs": snapshot.jobs,
257
+ "server_stats": snapshot.server_stats,
258
+ "collection_info": {
259
+ "timestamp": snapshot.timestamp,
260
+ "duration": snapshot.collection_duration,
261
+ "is_complete": snapshot.is_complete,
262
+ "errors": snapshot.errors,
222
263
  },
223
- "jobs": {
224
- "active_count": len(
225
- [j for j in active_jobs if j["status"] == "running"],
226
- ),
227
- "completed_count": len(
228
- [j for j in active_jobs if j["status"] == "completed"],
229
- ),
230
- "failed_count": len(
231
- [j for j in active_jobs if j["status"] == "failed"],
232
- ),
233
- "details": active_jobs,
234
- },
235
- "server_stats": _build_server_stats(context),
236
- "timestamp": time.time(),
237
264
  }
238
265
 
239
- # Add state manager stats
240
- state_manager = getattr(context, "state_manager", None)
241
- _add_state_manager_stats(status["server_stats"], state_manager)
266
+ # Add agent suggestions if available
267
+ context = None
268
+ with suppress(RuntimeError):
269
+ context = get_context()
242
270
 
243
- # Add agent suggestions based on current context
244
- if state_manager:
245
- status["agent_suggestions"] = _suggest_agent_for_context(state_manager)
271
+ if context:
272
+ state_manager = getattr(context, "state_manager", None)
273
+ if state_manager:
274
+ status["agent_suggestions"] = _suggest_agent_for_context(state_manager)
246
275
 
247
276
  return status
248
277
 
249
278
  except Exception as e:
250
- return {"error": f"Failed to get comprehensive status: {e}"}
279
+ return {"error": f"Failed to collect comprehensive status: {e}"}
280
+
281
+
282
+ async def _get_comprehensive_status() -> dict[str, t.Any]:
283
+ """Legacy wrapper for backward compatibility."""
284
+ return await _get_comprehensive_status_secure()
251
285
 
252
286
 
253
287
  def register_monitoring_tools(mcp_app: t.Any) -> None:
@@ -262,20 +296,27 @@ def register_monitoring_tools(mcp_app: t.Any) -> None:
262
296
  def _register_stage_status_tool(mcp_app: t.Any) -> None:
263
297
  @mcp_app.tool()
264
298
  async def get_stage_status() -> str:
265
- context = get_context()
266
- if not context:
267
- return _create_error_response("Server context not available")
299
+ client_id = "mcp_client"
268
300
 
269
301
  try:
302
+ # Security validation
303
+ await validate_status_request(client_id, "get_stage_status", {})
304
+
305
+ context = get_context()
306
+ if not context:
307
+ return _create_error_response("Server context not available")
308
+
270
309
  state_manager = getattr(context, "state_manager", None)
271
310
  if not state_manager:
272
311
  return _create_error_response("State manager not available")
273
312
 
274
- result = {
275
- "stages": _get_stage_status_dict(state_manager),
276
- "session": _get_session_info(state_manager),
277
- "timestamp": time.time(),
278
- }
313
+ # Use bounded operation for resource protection
314
+ result = await execute_bounded_status_operation(
315
+ "stage_status",
316
+ client_id,
317
+ _build_stage_status,
318
+ state_manager,
319
+ )
279
320
 
280
321
  return json.dumps(result, indent=2)
281
322
 
@@ -283,19 +324,40 @@ def _register_stage_status_tool(mcp_app: t.Any) -> None:
283
324
  return f'{{"error": "Failed to get stage status: {e}"}}'
284
325
 
285
326
 
327
+ def _build_stage_status(state_manager) -> dict[str, t.Any]:
328
+ """Build stage status with bounded resource usage."""
329
+ return {
330
+ "stages": _get_stage_status_dict(state_manager),
331
+ "session": _get_session_info(state_manager),
332
+ "timestamp": time.time(),
333
+ }
334
+
335
+
286
336
  def _register_next_action_tool(mcp_app: t.Any) -> None:
287
337
  @mcp_app.tool()
288
338
  async def get_next_action() -> str:
289
- context = get_context()
290
- if not context:
291
- return _create_error_response("Server context not available")
339
+ client_id = "mcp_client"
292
340
 
293
341
  try:
342
+ # Security validation
343
+ await validate_status_request(client_id, "get_next_action", {})
344
+
345
+ context = get_context()
346
+ if not context:
347
+ return _create_error_response("Server context not available")
348
+
294
349
  state_manager = getattr(context, "state_manager", None)
295
350
  if not state_manager:
296
351
  return '{"recommended_action": "initialize", "reason": "No state manager available"}'
297
352
 
298
- action = _determine_next_action(state_manager)
353
+ # Use bounded operation for consistency
354
+ action = await execute_bounded_status_operation(
355
+ "next_action",
356
+ client_id,
357
+ _determine_next_action,
358
+ state_manager,
359
+ )
360
+
299
361
  return json.dumps(action, indent=2)
300
362
 
301
363
  except Exception as e:
@@ -305,53 +367,122 @@ def _register_next_action_tool(mcp_app: t.Any) -> None:
305
367
  def _register_server_stats_tool(mcp_app: t.Any) -> None:
306
368
  @mcp_app.tool()
307
369
  async def get_server_stats() -> str:
308
- context = get_context()
309
- if not context:
310
- return _create_error_response("Server context not available")
370
+ client_id = "mcp_client"
311
371
 
312
372
  try:
313
- stats = _build_server_stats(context)
314
- state_manager = getattr(context, "state_manager", None)
315
- _add_state_manager_stats(stats, state_manager)
373
+ # Security validation
374
+ await validate_status_request(client_id, "get_server_stats", {})
375
+
376
+ # Use secure status operation with resource limits
377
+ async with await secure_status_operation(
378
+ client_id, "get_server_stats", timeout=15.0
379
+ ):
380
+ # Get context
381
+ context = get_context()
382
+ if not context:
383
+ formatter = get_secure_status_formatter()
384
+ error_response = formatter.format_error_response(
385
+ "Server context not available",
386
+ )
387
+ return json.dumps(error_response, indent=2)
388
+
389
+ # Get raw stats with bounded operation
390
+ raw_stats = await execute_bounded_status_operation(
391
+ "server_stats",
392
+ client_id,
393
+ _build_server_stats_secure,
394
+ context,
395
+ )
396
+
397
+ # Apply secure formatting
398
+ secure_stats = format_secure_status(
399
+ raw_stats,
400
+ project_root=context.config.project_path,
401
+ user_context="mcp_client",
402
+ )
316
403
 
317
- return json.dumps(stats, indent=2)
404
+ return json.dumps(secure_stats, indent=2)
318
405
 
319
406
  except Exception as e:
320
- return f'{{"error": "Failed to get server stats: {e}"}}'
407
+ # Use secure error formatting
408
+ formatter = get_secure_status_formatter()
409
+ error_response = formatter.format_error_response(
410
+ str(e),
411
+ )
412
+ return json.dumps(error_response, indent=2)
413
+
414
+
415
+ def _build_server_stats_secure(context) -> dict[str, t.Any]:
416
+ """Build server stats with security controls."""
417
+
418
+ # Build base stats
419
+ stats = _build_server_stats(context)
420
+
421
+ # Add state manager stats
422
+ state_manager = getattr(context, "state_manager", None)
423
+ _add_state_manager_stats(stats, state_manager)
424
+
425
+ # Add security status
426
+ security_manager = get_status_security_manager()
427
+ stats["security_status"] = security_manager.get_security_status()
428
+
429
+ # Add resource limiter status if available
430
+ with suppress(Exception):
431
+ # Resource limiter may not be initialized
432
+ resource_limiter = get_websocket_resource_limiter()
433
+ stats["websocket_resources"] = resource_limiter.get_resource_status()
434
+
435
+ return stats
321
436
 
322
437
 
323
438
  def _register_comprehensive_status_tool(mcp_app: t.Any) -> None:
324
439
  @mcp_app.tool()
325
440
  async def get_comprehensive_status() -> str:
326
- """Get comprehensive status of MCP server, WebSocket server, and active jobs.
327
-
328
- This is the main status tool used by the /crackerjack:status slash command.
329
- Provides information about:
330
- - MCP server status and processes
331
- - WebSocket server status and connections
332
- - Active, completed, and failed jobs
333
- - Progress information for running jobs
334
- - Error metrics and resolution counts
335
- - Service health and resource usage
336
- """
441
+ client_id = "mcp_client"
442
+ client_ip = "127.0.0.1"
443
+
337
444
  try:
338
- status = await _get_comprehensive_status()
339
- return json.dumps(status, indent=2)
340
- except Exception as e:
341
- import traceback
445
+ # Use secure status operation with request lock
446
+ async with await secure_status_operation(
447
+ client_id,
448
+ "get_comprehensive_status",
449
+ ):
450
+ # Get raw status data with full security integration
451
+ raw_status = await _get_comprehensive_status_secure(
452
+ client_id=client_id,
453
+ client_ip=client_ip,
454
+ # Local-only access (auth_header defaults to None)
455
+ )
342
456
 
343
- return f'{{"error": "Failed to get comprehensive status: {e}", "traceback": "{traceback.format_exc()}"}}'
457
+ # Apply secure formatting
458
+ context = get_context()
459
+ project_root = context.config.project_path if context else None
460
+
461
+ secure_status = format_secure_status(
462
+ raw_status,
463
+ project_root=project_root,
464
+ user_context="mcp_client",
465
+ )
466
+
467
+ return json.dumps(secure_status, indent=2)
468
+
469
+ except Exception as e:
470
+ # Use secure error formatting
471
+ formatter = get_secure_status_formatter()
472
+ error_response = formatter.format_error_response(
473
+ str(e),
474
+ )
475
+ return json.dumps(error_response, indent=2)
344
476
 
345
477
 
346
478
  def _register_command_help_tool(mcp_app: t.Any) -> None:
347
479
  @mcp_app.tool()
348
480
  async def list_slash_commands() -> str:
349
- """List all available crackerjack slash commands with descriptions and usage."""
350
481
  try:
351
482
  commands = {
352
- "/crackerjack:run": {
483
+ "/ crackerjack: run": {
353
484
  "description": "Run full iterative auto-fixing with AI agent, tests, progress tracking, and verbose output",
354
- "usage": "Direct execution - no parameters needed",
485
+ "usage": "Direct execution-no parameters needed",
355
486
  "features": [
356
487
  "Up to 10 iterations of quality improvement",
357
488
  "Real-time WebSocket progress streaming",
@@ -360,9 +491,9 @@ def _register_command_help_tool(mcp_app: t.Any) -> None:
360
491
  "Debug mode support",
361
492
  ],
362
493
  },
363
- "/crackerjack:status": {
494
+ "/ crackerjack: status": {
364
495
  "description": "Get comprehensive system status including servers, jobs, and resource usage",
365
- "usage": "Direct execution - no parameters needed",
496
+ "usage": "Direct execution-no parameters needed",
366
497
  "features": [
367
498
  "MCP server health monitoring",
368
499
  "WebSocket server status",
@@ -371,11 +502,11 @@ def _register_command_help_tool(mcp_app: t.Any) -> None:
371
502
  "Error counts and progress data",
372
503
  ],
373
504
  },
374
- "/crackerjack:init": {
505
+ "/ crackerjack: init": {
375
506
  "description": "Initialize or update crackerjack configuration with smart configuration merging",
376
507
  "usage": "Optional parameters: target_path (defaults to current directory)",
377
508
  "kwargs": {
378
- "force": "boolean - force overwrite existing configurations"
509
+ "force": "boolean-force overwrite existing configurations"
379
510
  },
380
511
  "features": [
381
512
  "Smart merge preserving existing configurations",
@@ -404,9 +535,8 @@ def _register_command_help_tool(mcp_app: t.Any) -> None:
404
535
 
405
536
 
406
537
  def _validate_status_components(components: str) -> tuple[set[str], str | None]:
407
- """Validate and parse status components."""
408
538
  valid_components = {"services", "jobs", "resources", "all"}
409
- requested = {c.strip().lower() for c in components.split(",")}
539
+ requested = {c.strip().lower() for c in components.split(", ")}
410
540
 
411
541
  invalid = requested - valid_components
412
542
  if invalid:
@@ -416,7 +546,6 @@ def _validate_status_components(components: str) -> tuple[set[str], str | None]:
416
546
 
417
547
 
418
548
  def _get_services_status() -> dict:
419
- """Get services status information."""
420
549
  from crackerjack.services.server_manager import (
421
550
  find_mcp_server_processes,
422
551
  find_websocket_server_processes,
@@ -438,7 +567,6 @@ def _get_services_status() -> dict:
438
567
 
439
568
 
440
569
  def _get_resources_status(context: t.Any) -> dict:
441
- """Get resources status information."""
442
570
  temp_files_count = (
443
571
  len(list(context.progress_dir.glob("*.json")))
444
572
  if context.progress_dir.exists()
@@ -452,7 +580,6 @@ def _get_resources_status(context: t.Any) -> dict:
452
580
 
453
581
 
454
582
  def _build_filtered_status(requested: set[str], context: t.Any) -> dict:
455
- """Build filtered status based on requested components."""
456
583
  filtered_status = {"timestamp": time.time()}
457
584
 
458
585
  if "services" in requested:
@@ -470,33 +597,69 @@ def _build_filtered_status(requested: set[str], context: t.Any) -> dict:
470
597
  def _register_filtered_status_tool(mcp_app: t.Any) -> None:
471
598
  @mcp_app.tool()
472
599
  async def get_filtered_status(components: str = "all") -> str:
473
- """Get specific status components for better performance.
600
+ client_id = "mcp_client"
474
601
 
475
- Args:
476
- components: Comma-separated list of components to include:
477
- 'services', 'jobs', 'resources', 'all' (default)
478
- """
479
602
  try:
480
- requested, error = _validate_status_components(components)
481
- if error:
482
- return json.dumps({"error": error, "success": False}, indent=2)
603
+ # Security validation with component filter data
604
+ await validate_status_request(
605
+ client_id, "get_filtered_status", {"components": components}
606
+ )
483
607
 
484
- # If 'all' is requested, get everything
485
- if "all" in requested:
486
- status = await _get_comprehensive_status()
487
- return json.dumps(status, indent=2)
608
+ return await _process_filtered_status_request(client_id, components)
488
609
 
489
- context = get_context()
490
- if not context:
491
- return json.dumps(
492
- {"error": "Server context not available", "success": False}
493
- )
610
+ except Exception as e:
611
+ return _format_status_error(str(e))
494
612
 
495
- filtered_status = _build_filtered_status(requested, context)
496
- return json.dumps(filtered_status, indent=2)
497
613
 
498
- except Exception as e:
499
- return json.dumps(
500
- {"error": f"Failed to get filtered status: {e}", "success": False},
501
- indent=2,
502
- )
614
+ async def _process_filtered_status_request(client_id: str, components: str) -> str:
615
+ """Process filtered status request with component validation."""
616
+ requested, error = _validate_status_components(components)
617
+ if error:
618
+ return _format_status_error(error)
619
+
620
+ # Use secure status operation with timeout
621
+ async with await secure_status_operation(
622
+ client_id, "get_filtered_status", timeout=20.0
623
+ ):
624
+ return await _collect_status_data(client_id, requested)
625
+
626
+
627
+ async def _collect_status_data(client_id: str, requested: set[str]) -> str:
628
+ """Collect status data based on requested components."""
629
+ context = get_context()
630
+
631
+ if "all" in requested:
632
+ raw_status = await _get_comprehensive_status_secure(
633
+ client_id=client_id,
634
+ )
635
+ else:
636
+ if not context:
637
+ return _format_status_error("Server context not available")
638
+
639
+ # Use bounded operation for filtered status
640
+ raw_status = await execute_bounded_status_operation(
641
+ "filtered_status",
642
+ client_id,
643
+ _build_filtered_status,
644
+ requested,
645
+ context,
646
+ )
647
+
648
+ return _apply_secure_formatting(raw_status, context)
649
+
650
+
651
+ def _apply_secure_formatting(raw_status: dict, context: t.Any) -> str:
652
+ """Apply secure formatting to status data."""
653
+ project_root = context.config.project_path if context else None
654
+ secure_status = format_secure_status(
655
+ raw_status,
656
+ project_root=project_root,
657
+ user_context="mcp_client",
658
+ )
659
+ return json.dumps(secure_status, indent=2)
660
+
661
+
662
+ def _format_status_error(error_message: str) -> str:
663
+ """Format status error response consistently."""
664
+ formatter = get_secure_status_formatter()
665
+ return json.dumps(formatter.format_error_response(error_message), indent=2)