crackerjack 0.32.0__py3-none-any.whl → 0.33.1__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 (200) hide show
  1. crackerjack/__main__.py +1350 -34
  2. crackerjack/adapters/__init__.py +17 -0
  3. crackerjack/adapters/lsp_client.py +358 -0
  4. crackerjack/adapters/rust_tool_adapter.py +194 -0
  5. crackerjack/adapters/rust_tool_manager.py +193 -0
  6. crackerjack/adapters/skylos_adapter.py +231 -0
  7. crackerjack/adapters/zuban_adapter.py +560 -0
  8. crackerjack/agents/base.py +7 -3
  9. crackerjack/agents/coordinator.py +271 -33
  10. crackerjack/agents/documentation_agent.py +9 -15
  11. crackerjack/agents/dry_agent.py +3 -15
  12. crackerjack/agents/formatting_agent.py +1 -1
  13. crackerjack/agents/import_optimization_agent.py +36 -180
  14. crackerjack/agents/performance_agent.py +17 -98
  15. crackerjack/agents/performance_helpers.py +7 -31
  16. crackerjack/agents/proactive_agent.py +1 -3
  17. crackerjack/agents/refactoring_agent.py +16 -85
  18. crackerjack/agents/refactoring_helpers.py +7 -42
  19. crackerjack/agents/security_agent.py +9 -48
  20. crackerjack/agents/test_creation_agent.py +356 -513
  21. crackerjack/agents/test_specialist_agent.py +0 -4
  22. crackerjack/api.py +6 -25
  23. crackerjack/cli/cache_handlers.py +204 -0
  24. crackerjack/cli/cache_handlers_enhanced.py +683 -0
  25. crackerjack/cli/facade.py +100 -0
  26. crackerjack/cli/handlers.py +224 -9
  27. crackerjack/cli/interactive.py +6 -4
  28. crackerjack/cli/options.py +642 -55
  29. crackerjack/cli/utils.py +2 -1
  30. crackerjack/code_cleaner.py +58 -117
  31. crackerjack/config/global_lock_config.py +8 -48
  32. crackerjack/config/hooks.py +53 -62
  33. crackerjack/core/async_workflow_orchestrator.py +24 -34
  34. crackerjack/core/autofix_coordinator.py +3 -17
  35. crackerjack/core/enhanced_container.py +64 -6
  36. crackerjack/core/file_lifecycle.py +12 -89
  37. crackerjack/core/performance.py +2 -2
  38. crackerjack/core/performance_monitor.py +15 -55
  39. crackerjack/core/phase_coordinator.py +257 -218
  40. crackerjack/core/resource_manager.py +14 -90
  41. crackerjack/core/service_watchdog.py +62 -95
  42. crackerjack/core/session_coordinator.py +149 -0
  43. crackerjack/core/timeout_manager.py +14 -72
  44. crackerjack/core/websocket_lifecycle.py +13 -78
  45. crackerjack/core/workflow_orchestrator.py +558 -240
  46. crackerjack/docs/INDEX.md +11 -0
  47. crackerjack/docs/generated/api/API_REFERENCE.md +10895 -0
  48. crackerjack/docs/generated/api/CLI_REFERENCE.md +109 -0
  49. crackerjack/docs/generated/api/CROSS_REFERENCES.md +1755 -0
  50. crackerjack/docs/generated/api/PROTOCOLS.md +3 -0
  51. crackerjack/docs/generated/api/SERVICES.md +1252 -0
  52. crackerjack/documentation/__init__.py +31 -0
  53. crackerjack/documentation/ai_templates.py +756 -0
  54. crackerjack/documentation/dual_output_generator.py +765 -0
  55. crackerjack/documentation/mkdocs_integration.py +518 -0
  56. crackerjack/documentation/reference_generator.py +977 -0
  57. crackerjack/dynamic_config.py +55 -50
  58. crackerjack/executors/async_hook_executor.py +10 -15
  59. crackerjack/executors/cached_hook_executor.py +117 -43
  60. crackerjack/executors/hook_executor.py +8 -34
  61. crackerjack/executors/hook_lock_manager.py +26 -183
  62. crackerjack/executors/individual_hook_executor.py +13 -11
  63. crackerjack/executors/lsp_aware_hook_executor.py +270 -0
  64. crackerjack/executors/tool_proxy.py +417 -0
  65. crackerjack/hooks/lsp_hook.py +79 -0
  66. crackerjack/intelligence/adaptive_learning.py +25 -10
  67. crackerjack/intelligence/agent_orchestrator.py +2 -5
  68. crackerjack/intelligence/agent_registry.py +34 -24
  69. crackerjack/intelligence/agent_selector.py +5 -7
  70. crackerjack/interactive.py +17 -6
  71. crackerjack/managers/async_hook_manager.py +0 -1
  72. crackerjack/managers/hook_manager.py +79 -1
  73. crackerjack/managers/publish_manager.py +66 -13
  74. crackerjack/managers/test_command_builder.py +5 -17
  75. crackerjack/managers/test_executor.py +1 -3
  76. crackerjack/managers/test_manager.py +109 -7
  77. crackerjack/managers/test_manager_backup.py +10 -9
  78. crackerjack/mcp/cache.py +2 -2
  79. crackerjack/mcp/client_runner.py +1 -1
  80. crackerjack/mcp/context.py +191 -68
  81. crackerjack/mcp/dashboard.py +7 -5
  82. crackerjack/mcp/enhanced_progress_monitor.py +31 -28
  83. crackerjack/mcp/file_monitor.py +30 -23
  84. crackerjack/mcp/progress_components.py +31 -21
  85. crackerjack/mcp/progress_monitor.py +50 -53
  86. crackerjack/mcp/rate_limiter.py +6 -6
  87. crackerjack/mcp/server_core.py +161 -32
  88. crackerjack/mcp/service_watchdog.py +2 -1
  89. crackerjack/mcp/state.py +4 -7
  90. crackerjack/mcp/task_manager.py +11 -9
  91. crackerjack/mcp/tools/core_tools.py +174 -33
  92. crackerjack/mcp/tools/error_analyzer.py +3 -2
  93. crackerjack/mcp/tools/execution_tools.py +15 -12
  94. crackerjack/mcp/tools/execution_tools_backup.py +42 -30
  95. crackerjack/mcp/tools/intelligence_tool_registry.py +7 -5
  96. crackerjack/mcp/tools/intelligence_tools.py +5 -2
  97. crackerjack/mcp/tools/monitoring_tools.py +33 -70
  98. crackerjack/mcp/tools/proactive_tools.py +24 -11
  99. crackerjack/mcp/tools/progress_tools.py +5 -8
  100. crackerjack/mcp/tools/utility_tools.py +20 -14
  101. crackerjack/mcp/tools/workflow_executor.py +62 -40
  102. crackerjack/mcp/websocket/app.py +8 -0
  103. crackerjack/mcp/websocket/endpoints.py +352 -357
  104. crackerjack/mcp/websocket/jobs.py +40 -57
  105. crackerjack/mcp/websocket/monitoring_endpoints.py +2935 -0
  106. crackerjack/mcp/websocket/server.py +7 -25
  107. crackerjack/mcp/websocket/websocket_handler.py +6 -17
  108. crackerjack/mixins/__init__.py +3 -0
  109. crackerjack/mixins/error_handling.py +145 -0
  110. crackerjack/models/config.py +21 -1
  111. crackerjack/models/config_adapter.py +49 -1
  112. crackerjack/models/protocols.py +176 -107
  113. crackerjack/models/resource_protocols.py +55 -210
  114. crackerjack/models/task.py +3 -0
  115. crackerjack/monitoring/ai_agent_watchdog.py +13 -13
  116. crackerjack/monitoring/metrics_collector.py +426 -0
  117. crackerjack/monitoring/regression_prevention.py +8 -8
  118. crackerjack/monitoring/websocket_server.py +643 -0
  119. crackerjack/orchestration/advanced_orchestrator.py +11 -6
  120. crackerjack/orchestration/coverage_improvement.py +3 -3
  121. crackerjack/orchestration/execution_strategies.py +26 -6
  122. crackerjack/orchestration/test_progress_streamer.py +8 -5
  123. crackerjack/plugins/base.py +2 -2
  124. crackerjack/plugins/hooks.py +7 -0
  125. crackerjack/plugins/managers.py +11 -8
  126. crackerjack/security/__init__.py +0 -1
  127. crackerjack/security/audit.py +90 -105
  128. crackerjack/services/anomaly_detector.py +392 -0
  129. crackerjack/services/api_extractor.py +615 -0
  130. crackerjack/services/backup_service.py +2 -2
  131. crackerjack/services/bounded_status_operations.py +15 -152
  132. crackerjack/services/cache.py +127 -1
  133. crackerjack/services/changelog_automation.py +395 -0
  134. crackerjack/services/config.py +18 -11
  135. crackerjack/services/config_merge.py +30 -85
  136. crackerjack/services/config_template.py +506 -0
  137. crackerjack/services/contextual_ai_assistant.py +48 -22
  138. crackerjack/services/coverage_badge_service.py +171 -0
  139. crackerjack/services/coverage_ratchet.py +41 -17
  140. crackerjack/services/debug.py +3 -3
  141. crackerjack/services/dependency_analyzer.py +460 -0
  142. crackerjack/services/dependency_monitor.py +14 -11
  143. crackerjack/services/documentation_generator.py +491 -0
  144. crackerjack/services/documentation_service.py +675 -0
  145. crackerjack/services/enhanced_filesystem.py +6 -5
  146. crackerjack/services/enterprise_optimizer.py +865 -0
  147. crackerjack/services/error_pattern_analyzer.py +676 -0
  148. crackerjack/services/file_hasher.py +1 -1
  149. crackerjack/services/git.py +41 -45
  150. crackerjack/services/health_metrics.py +10 -8
  151. crackerjack/services/heatmap_generator.py +735 -0
  152. crackerjack/services/initialization.py +30 -33
  153. crackerjack/services/input_validator.py +5 -97
  154. crackerjack/services/intelligent_commit.py +327 -0
  155. crackerjack/services/log_manager.py +15 -12
  156. crackerjack/services/logging.py +4 -3
  157. crackerjack/services/lsp_client.py +628 -0
  158. crackerjack/services/memory_optimizer.py +409 -0
  159. crackerjack/services/metrics.py +42 -33
  160. crackerjack/services/parallel_executor.py +416 -0
  161. crackerjack/services/pattern_cache.py +1 -1
  162. crackerjack/services/pattern_detector.py +6 -6
  163. crackerjack/services/performance_benchmarks.py +250 -576
  164. crackerjack/services/performance_cache.py +382 -0
  165. crackerjack/services/performance_monitor.py +565 -0
  166. crackerjack/services/predictive_analytics.py +510 -0
  167. crackerjack/services/quality_baseline.py +234 -0
  168. crackerjack/services/quality_baseline_enhanced.py +646 -0
  169. crackerjack/services/quality_intelligence.py +785 -0
  170. crackerjack/services/regex_patterns.py +605 -524
  171. crackerjack/services/regex_utils.py +43 -123
  172. crackerjack/services/secure_path_utils.py +5 -164
  173. crackerjack/services/secure_status_formatter.py +30 -141
  174. crackerjack/services/secure_subprocess.py +11 -92
  175. crackerjack/services/security.py +61 -30
  176. crackerjack/services/security_logger.py +18 -22
  177. crackerjack/services/server_manager.py +124 -16
  178. crackerjack/services/status_authentication.py +16 -159
  179. crackerjack/services/status_security_manager.py +4 -131
  180. crackerjack/services/terminal_utils.py +0 -0
  181. crackerjack/services/thread_safe_status_collector.py +19 -125
  182. crackerjack/services/unified_config.py +21 -13
  183. crackerjack/services/validation_rate_limiter.py +5 -54
  184. crackerjack/services/version_analyzer.py +459 -0
  185. crackerjack/services/version_checker.py +1 -1
  186. crackerjack/services/websocket_resource_limiter.py +10 -144
  187. crackerjack/services/zuban_lsp_service.py +390 -0
  188. crackerjack/slash_commands/__init__.py +2 -7
  189. crackerjack/slash_commands/run.md +2 -2
  190. crackerjack/tools/validate_input_validator_patterns.py +14 -40
  191. crackerjack/tools/validate_regex_patterns.py +19 -48
  192. {crackerjack-0.32.0.dist-info → crackerjack-0.33.1.dist-info}/METADATA +197 -26
  193. crackerjack-0.33.1.dist-info/RECORD +229 -0
  194. crackerjack/CLAUDE.md +0 -207
  195. crackerjack/RULES.md +0 -380
  196. crackerjack/py313.py +0 -234
  197. crackerjack-0.32.0.dist-info/RECORD +0 -180
  198. {crackerjack-0.32.0.dist-info → crackerjack-0.33.1.dist-info}/WHEEL +0 -0
  199. {crackerjack-0.32.0.dist-info → crackerjack-0.33.1.dist-info}/entry_points.txt +0 -0
  200. {crackerjack-0.32.0.dist-info → crackerjack-0.33.1.dist-info}/licenses/LICENSE +0 -0
@@ -85,7 +85,7 @@ async def _validate_context_and_rate_limit(context: t.Any) -> str | None:
85
85
  return None
86
86
 
87
87
 
88
- def _handle_task_exception(job_id: str, task: asyncio.Task) -> None:
88
+ def _handle_task_exception(job_id: str, task: asyncio.Task[t.Any]) -> None:
89
89
  import tempfile
90
90
  from pathlib import Path
91
91
 
@@ -405,10 +405,9 @@ def _create_workflow_options(kwargs: dict[str, t.Any]) -> t.Any:
405
405
 
406
406
  options = WorkflowOptions()
407
407
  options.testing.test = kwargs.get("test", True)
408
- options.ai_agent = kwargs.get("ai_agent", True)
409
- options.skip_hooks = kwargs.get("skip_hooks", False)
408
+ options.ai.ai_agent = kwargs.get("ai_agent", True)
409
+ options.hooks.skip_hooks = kwargs.get("skip_hooks", False)
410
410
 
411
- options.proactive_mode = kwargs.get("proactive_mode", True)
412
411
  return options
413
412
 
414
413
 
@@ -418,8 +417,10 @@ async def _execute_single_iteration(
418
417
  options: t.Any,
419
418
  ) -> bool:
420
419
  if use_advanced_orchestrator:
421
- return await orchestrator.execute_orchestrated_workflow(options)
422
- return await orchestrator.run_complete_workflow(options)
420
+ result = await orchestrator.execute_orchestrated_workflow(options)
421
+ return bool(result)
422
+ result = await orchestrator.run_complete_workflow(options)
423
+ return bool(result)
423
424
 
424
425
 
425
426
  def _create_success_result(
@@ -715,6 +716,8 @@ def _register_init_crackerjack_tool(mcp_app: t.Any) -> None:
715
716
 
716
717
  try:
717
718
  results = _execute_initialization(context, target_path, force)
719
+ if isinstance(results, bool):
720
+ return json.dumps({"success": results})
718
721
  return _create_init_success_response(results, target_path, force)
719
722
  except Exception as e:
720
723
  return _create_init_exception_response(e, target_path)
@@ -730,18 +733,20 @@ def _parse_init_arguments(args: str, kwargs: str) -> tuple[t.Any, bool, str | No
730
733
  target_path = args.strip() or None
731
734
 
732
735
  try:
733
- extra_kwargs = json.loads(kwargs) if kwargs.strip() else {}
736
+ extra_kwargs: dict[str, t.Any] = json.loads(kwargs) if kwargs.strip() else {}
734
737
  except json.JSONDecodeError as e:
735
738
  return None, False, _create_init_error_response(f"Invalid JSON in kwargs: {e}")
736
739
 
737
740
  force = extra_kwargs.get("force", False)
738
741
 
739
742
  if target_path:
740
- target_path = Path(target_path).resolve()
743
+ target_path_obj = Path(target_path).resolve()
744
+ target_path = str(target_path_obj)
741
745
  else:
742
- target_path = Path.cwd()
746
+ target_path_obj = Path.cwd()
747
+ target_path = str(target_path_obj)
743
748
 
744
- if not target_path.exists():
749
+ if not Path(target_path).exists():
745
750
  return (
746
751
  None,
747
752
  False,
@@ -751,9 +756,7 @@ def _parse_init_arguments(args: str, kwargs: str) -> tuple[t.Any, bool, str | No
751
756
  return target_path, force, None
752
757
 
753
758
 
754
- def _execute_initialization(
755
- context: t.Any, target_path: t.Any, force: bool
756
- ) -> dict[str, t.Any]:
759
+ def _execute_initialization(context: t.Any, target_path: t.Any, force: bool) -> bool:
757
760
  from crackerjack.services.filesystem import FileSystemService
758
761
  from crackerjack.services.git import GitService
759
762
  from crackerjack.services.initialization import InitializationService
@@ -792,15 +795,24 @@ def _register_agent_suggestions_tool(mcp_app: t.Any) -> None:
792
795
  project_type: str = "python",
793
796
  current_context: str = "",
794
797
  ) -> str:
795
- suggestions = {
796
- "primary_agents": [],
797
- "task_specific_agents": [],
798
- "usage_patterns": [],
798
+ suggestions: dict[str, list[dict[str, str]] | list[str] | str] = {
799
+ "primary_agents": t.cast(list[dict[str, str]], []),
800
+ "task_specific_agents": t.cast(list[dict[str, str]], []),
801
+ "usage_patterns": t.cast(list[str], []),
799
802
  "rationale": "",
800
803
  }
801
804
 
805
+ # Type cast the lists to ensure proper typing
806
+ primary_agents: list[dict[str, str]] = t.cast(
807
+ list[dict[str, str]], suggestions["primary_agents"]
808
+ )
809
+ task_specific_agents: list[dict[str, str]] = t.cast(
810
+ list[dict[str, str]], suggestions["task_specific_agents"]
811
+ )
812
+ t.cast(list[str], suggestions["usage_patterns"])
813
+
802
814
  if project_type.lower() == "python" or "python" in task_description.lower():
803
- suggestions["primary_agents"].append(
815
+ primary_agents.append(
804
816
  {
805
817
  "name": "crackerjack-architect",
806
818
  "emoji": "🏗️",
@@ -810,11 +822,11 @@ def _register_agent_suggestions_tool(mcp_app: t.Any) -> None:
810
822
  }
811
823
  )
812
824
 
813
- suggestions["primary_agents"].append(
825
+ primary_agents.append(
814
826
  {
815
827
  "name": "python-pro",
816
828
  "emoji": "🐍",
817
- "description": "Modern Python development with type hints, async / await patterns, and clean architecture",
829
+ "description": "Modern Python development with type hints, async/await patterns, and clean architecture",
818
830
  "usage": "Use for implementing Python code with best practices",
819
831
  "priority": "HIGH",
820
832
  }
@@ -827,9 +839,9 @@ def _register_agent_suggestions_tool(mcp_app: t.Any) -> None:
827
839
  word in task_lower + context_lower
828
840
  for word in ("test", "testing", "coverage", "pytest")
829
841
  ):
830
- suggestions["task_specific_agents"].append(
842
+ task_specific_agents.append(
831
843
  {
832
- "name": "crackerjack - test-specialist",
844
+ "name": "crackerjack-test-specialist",
833
845
  "emoji": "🧪",
834
846
  "description": "Advanced testing specialist for complex scenarios and coverage optimization",
835
847
  "usage": "Use for test creation, debugging test failures, and coverage improvements",
@@ -837,9 +849,9 @@ def _register_agent_suggestions_tool(mcp_app: t.Any) -> None:
837
849
  }
838
850
  )
839
851
 
840
- suggestions["task_specific_agents"].append(
852
+ task_specific_agents.append(
841
853
  {
842
- "name": "pytest - hypothesis-specialist",
854
+ "name": "pytest-hypothesis-specialist",
843
855
  "emoji": "🧪",
844
856
  "description": "Advanced testing patterns and property-based testing",
845
857
  "usage": "Use for comprehensive test development and optimization",
@@ -851,12 +863,12 @@ def _register_agent_suggestions_tool(mcp_app: t.Any) -> None:
851
863
  word in task_lower + context_lower
852
864
  for word in ("security", "vulnerability", "auth", "permission")
853
865
  ):
854
- suggestions["task_specific_agents"].append(
866
+ task_specific_agents.append(
855
867
  {
856
868
  "name": "security-auditor",
857
869
  "emoji": "🔒",
858
- "description": "Security analysis, vulnerability detection, and secure coding practices",
859
- "usage": "Use for security review and vulnerability assessment",
870
+ "description": "Security auditing and vulnerability detection specialist",
871
+ "usage": "Use for identifying and mitigating security vulnerabilities",
860
872
  "priority": "HIGH",
861
873
  }
862
874
  )
@@ -865,12 +877,12 @@ def _register_agent_suggestions_tool(mcp_app: t.Any) -> None:
865
877
  word in task_lower + context_lower
866
878
  for word in ("architecture", "design", "api", "backend")
867
879
  ):
868
- suggestions["task_specific_agents"].append(
880
+ task_specific_agents.append(
869
881
  {
870
882
  "name": "backend-architect",
871
883
  "emoji": "🏗️",
872
- "description": "System design, API architecture, and service integration patterns",
873
- "usage": "Use for architectural planning and system design",
884
+ "description": "Backend architecture and system design specialist",
885
+ "usage": "Use for complex backend design decisions and system architecture",
874
886
  "priority": "MEDIUM",
875
887
  }
876
888
  )
@@ -1,3 +1,5 @@
1
+ import typing as t
2
+
1
3
  from .intelligence_tools import (
2
4
  analyze_agent_performance,
3
5
  execute_smart_agent_task,
@@ -6,7 +8,7 @@ from .intelligence_tools import (
6
8
  )
7
9
 
8
10
 
9
- def register_intelligence_tools(mcp_app) -> None:
11
+ def register_intelligence_tools(mcp_app: t.Any) -> None:
10
12
  @mcp_app.tool()
11
13
  async def execute_smart_task(
12
14
  task_description: str,
@@ -14,7 +16,7 @@ def register_intelligence_tools(mcp_app) -> None:
14
16
  strategy: str = "single_best",
15
17
  max_agents: int = 3,
16
18
  use_learning: bool = True,
17
- ):
19
+ ) -> t.Any:
18
20
  return await execute_smart_agent_task(
19
21
  task_description,
20
22
  context_type,
@@ -28,7 +30,7 @@ def register_intelligence_tools(mcp_app) -> None:
28
30
  task_description: str,
29
31
  context_type: str = "general",
30
32
  include_analysis: bool = True,
31
- ):
33
+ ) -> t.Any:
32
34
  return await get_smart_agent_recommendation(
33
35
  task_description,
34
36
  context_type,
@@ -36,9 +38,9 @@ def register_intelligence_tools(mcp_app) -> None:
36
38
  )
37
39
 
38
40
  @mcp_app.tool()
39
- async def intelligence_system_status():
41
+ async def intelligence_system_status() -> t.Any:
40
42
  return await get_intelligence_system_status()
41
43
 
42
44
  @mcp_app.tool()
43
- async def agent_performance_analysis():
45
+ async def agent_performance_analysis() -> t.Any:
44
46
  return await analyze_agent_performance()
@@ -1,4 +1,5 @@
1
1
  import asyncio
2
+ import json
2
3
  import logging
3
4
  import typing as t
4
5
 
@@ -173,10 +174,12 @@ async def get_smart_agent_recommendation(
173
174
  if include_analysis:
174
175
  try:
175
176
  analysis = await system.analyze_task_complexity(task_description)
176
- response["complexity_analysis"] = analysis
177
+ response["complexity_analysis"] = json.dumps(analysis, indent=2)
177
178
  except Exception as e:
178
179
  logger.warning(f"Failed to analyze task complexity: {e}")
179
- response["complexity_analysis"] = {"error": str(e)}
180
+ response["complexity_analysis"] = json.dumps(
181
+ {"error": str(e)}, indent=2
182
+ )
180
183
 
181
184
  logger.debug(f"Generated recommendation for task: {task_description[:50]}...")
182
185
  return response
@@ -29,7 +29,7 @@ from crackerjack.services.websocket_resource_limiter import (
29
29
  )
30
30
 
31
31
 
32
- def _suggest_agent_for_context(state_manager) -> dict[str, t.Any]:
32
+ def _suggest_agent_for_context(state_manager: t.Any) -> dict[str, t.Any]:
33
33
  suggestions = {
34
34
  "recommended_agent": None,
35
35
  "reason": "",
@@ -95,12 +95,12 @@ def _create_error_response(message: str, success: bool = False) -> str:
95
95
  return json.dumps({"error": message, "success": success})
96
96
 
97
97
 
98
- def _get_stage_status_dict(state_manager) -> dict[str, str]:
98
+ def _get_stage_status_dict(state_manager: t.Any) -> dict[str, str]:
99
99
  stages = ["fast", "comprehensive", "tests", "cleaning"]
100
100
  return {stage: state_manager.get_stage_status(stage) for stage in stages}
101
101
 
102
102
 
103
- def _get_session_info(state_manager) -> dict[str, t.Any]:
103
+ def _get_session_info(state_manager: t.Any) -> dict[str, t.Any]:
104
104
  return {
105
105
  "total_iterations": getattr(state_manager, "iteration_count", 0),
106
106
  "current_iteration": getattr(state_manager, "current_iteration", 0),
@@ -108,7 +108,7 @@ def _get_session_info(state_manager) -> dict[str, t.Any]:
108
108
  }
109
109
 
110
110
 
111
- def _determine_next_action(state_manager) -> dict[str, t.Any]:
111
+ async def _determine_next_action(state_manager: t.Any) -> dict[str, t.Any]:
112
112
  stage_priorities = [
113
113
  ("fast", "Fast hooks not completed"),
114
114
  ("tests", "Tests not completed"),
@@ -130,7 +130,7 @@ def _determine_next_action(state_manager) -> dict[str, t.Any]:
130
130
  }
131
131
 
132
132
 
133
- def _build_server_stats(context) -> dict[str, t.Any]:
133
+ async def _build_server_stats(context: t.Any) -> dict[str, t.Any]:
134
134
  return {
135
135
  "server_info": {
136
136
  "project_path": str(context.config.project_path),
@@ -145,7 +145,7 @@ def _build_server_stats(context) -> dict[str, t.Any]:
145
145
  else None,
146
146
  },
147
147
  "resource_usage": {
148
- "temp_files_count": len(list(context.progress_dir.glob("*.json")))
148
+ "temp_files_count": len(list[t.Any](context.progress_dir.glob("*.json")))
149
149
  if context.progress_dir.exists()
150
150
  else 0,
151
151
  "progress_dir": str(context.progress_dir),
@@ -154,7 +154,7 @@ def _build_server_stats(context) -> dict[str, t.Any]:
154
154
  }
155
155
 
156
156
 
157
- def _add_state_manager_stats(stats: dict, state_manager) -> None:
157
+ def _add_state_manager_stats(stats: dict[str, t.Any], state_manager: t.Any) -> None:
158
158
  if state_manager:
159
159
  stats["state_manager"] = {
160
160
  "iteration_count": getattr(state_manager, "iteration_count", 0),
@@ -163,8 +163,8 @@ def _add_state_manager_stats(stats: dict, state_manager) -> None:
163
163
  }
164
164
 
165
165
 
166
- def _get_active_jobs(context) -> list[dict[str, t.Any]]:
167
- jobs = []
166
+ def _get_active_jobs(context: t.Any) -> list[dict[str, t.Any]]:
167
+ jobs: list[dict[str, t.Any]] = []
168
168
  if not context.progress_dir.exists():
169
169
  return jobs
170
170
 
@@ -198,16 +198,12 @@ async def _get_comprehensive_status_secure(
198
198
  auth_header: str | None = None,
199
199
  verbosity: StatusVerbosity = StatusVerbosity.STANDARD,
200
200
  ) -> dict[str, t.Any]:
201
- """Get comprehensive status with full security integration."""
202
-
203
- # 1. Authentication
204
201
  auth_manager = get_status_authenticator()
205
202
  try:
206
203
  credentials = await authenticate_status_request(
207
204
  auth_header, client_ip, "get_comprehensive_status"
208
205
  )
209
206
 
210
- # Check if operation is allowed for this auth level
211
207
  if not auth_manager.is_operation_allowed(
212
208
  "get_comprehensive_status", credentials.access_level
213
209
  ):
@@ -216,21 +212,20 @@ async def _get_comprehensive_status_secure(
216
212
  except Exception as e:
217
213
  return {"error": f"Authentication failed: {e}"}
218
214
 
219
- # 2. Security validation
220
215
  try:
221
216
  await validate_status_request(client_id, "get_comprehensive_status", {})
222
217
  except Exception as e:
223
218
  return {"error": f"Security validation failed: {e}"}
224
219
 
225
- # 3. Resource management with bounded operations
226
220
  try:
227
- return await execute_bounded_status_operation(
221
+ result: dict[str, t.Any] = await execute_bounded_status_operation(
228
222
  "status_collection",
229
223
  client_id,
230
224
  _collect_comprehensive_status_internal,
231
225
  client_id,
232
226
  verbosity,
233
227
  )
228
+ return result
234
229
  except Exception as e:
235
230
  return {"error": f"Resource limit exceeded: {e}"}
236
231
 
@@ -239,18 +234,13 @@ async def _collect_comprehensive_status_internal(
239
234
  client_id: str = "mcp_client",
240
235
  verbosity: StatusVerbosity = StatusVerbosity.STANDARD,
241
236
  ) -> dict[str, t.Any]:
242
- """Internal comprehensive status collection using thread-safe collector."""
243
-
244
- # Use thread-safe status collector
245
237
  collector = get_thread_safe_status_collector()
246
238
 
247
239
  try:
248
- # Collect status with thread safety and proper timeout handling
249
240
  snapshot = await collector.collect_comprehensive_status(
250
241
  client_id=client_id,
251
242
  )
252
243
 
253
- # Build final status from snapshot
254
244
  status = {
255
245
  "services": snapshot.services,
256
246
  "jobs": snapshot.jobs,
@@ -263,7 +253,6 @@ async def _collect_comprehensive_status_internal(
263
253
  },
264
254
  }
265
255
 
266
- # Add agent suggestions if available
267
256
  context = None
268
257
  with suppress(RuntimeError):
269
258
  context = get_context()
@@ -280,7 +269,6 @@ async def _collect_comprehensive_status_internal(
280
269
 
281
270
 
282
271
  async def _get_comprehensive_status() -> dict[str, t.Any]:
283
- """Legacy wrapper for backward compatibility."""
284
272
  return await _get_comprehensive_status_secure()
285
273
 
286
274
 
@@ -294,12 +282,11 @@ def register_monitoring_tools(mcp_app: t.Any) -> None:
294
282
 
295
283
 
296
284
  def _register_stage_status_tool(mcp_app: t.Any) -> None:
297
- @mcp_app.tool()
285
+ @mcp_app.tool() # type: ignore[misc] # type: ignore[misc]
298
286
  async def get_stage_status() -> str:
299
287
  client_id = "mcp_client"
300
288
 
301
289
  try:
302
- # Security validation
303
290
  await validate_status_request(client_id, "get_stage_status", {})
304
291
 
305
292
  context = get_context()
@@ -310,7 +297,6 @@ def _register_stage_status_tool(mcp_app: t.Any) -> None:
310
297
  if not state_manager:
311
298
  return _create_error_response("State manager not available")
312
299
 
313
- # Use bounded operation for resource protection
314
300
  result = await execute_bounded_status_operation(
315
301
  "stage_status",
316
302
  client_id,
@@ -324,8 +310,7 @@ def _register_stage_status_tool(mcp_app: t.Any) -> None:
324
310
  return f'{{"error": "Failed to get stage status: {e}"}}'
325
311
 
326
312
 
327
- def _build_stage_status(state_manager) -> dict[str, t.Any]:
328
- """Build stage status with bounded resource usage."""
313
+ async def _build_stage_status(state_manager: t.Any) -> dict[str, t.Any]:
329
314
  return {
330
315
  "stages": _get_stage_status_dict(state_manager),
331
316
  "session": _get_session_info(state_manager),
@@ -334,12 +319,11 @@ def _build_stage_status(state_manager) -> dict[str, t.Any]:
334
319
 
335
320
 
336
321
  def _register_next_action_tool(mcp_app: t.Any) -> None:
337
- @mcp_app.tool()
322
+ @mcp_app.tool() # type: ignore[misc] # type: ignore[misc]
338
323
  async def get_next_action() -> str:
339
324
  client_id = "mcp_client"
340
325
 
341
326
  try:
342
- # Security validation
343
327
  await validate_status_request(client_id, "get_next_action", {})
344
328
 
345
329
  context = get_context()
@@ -350,7 +334,6 @@ def _register_next_action_tool(mcp_app: t.Any) -> None:
350
334
  if not state_manager:
351
335
  return '{"recommended_action": "initialize", "reason": "No state manager available"}'
352
336
 
353
- # Use bounded operation for consistency
354
337
  action = await execute_bounded_status_operation(
355
338
  "next_action",
356
339
  client_id,
@@ -365,19 +348,16 @@ def _register_next_action_tool(mcp_app: t.Any) -> None:
365
348
 
366
349
 
367
350
  def _register_server_stats_tool(mcp_app: t.Any) -> None:
368
- @mcp_app.tool()
351
+ @mcp_app.tool() # type: ignore[misc] # type: ignore[misc]
369
352
  async def get_server_stats() -> str:
370
353
  client_id = "mcp_client"
371
354
 
372
355
  try:
373
- # Security validation
374
356
  await validate_status_request(client_id, "get_server_stats", {})
375
357
 
376
- # Use secure status operation with resource limits
377
358
  async with await secure_status_operation(
378
359
  client_id, "get_server_stats", timeout=15.0
379
360
  ):
380
- # Get context
381
361
  context = get_context()
382
362
  if not context:
383
363
  formatter = get_secure_status_formatter()
@@ -386,7 +366,6 @@ def _register_server_stats_tool(mcp_app: t.Any) -> None:
386
366
  )
387
367
  return json.dumps(error_response, indent=2)
388
368
 
389
- # Get raw stats with bounded operation
390
369
  raw_stats = await execute_bounded_status_operation(
391
370
  "server_stats",
392
371
  client_id,
@@ -394,7 +373,6 @@ def _register_server_stats_tool(mcp_app: t.Any) -> None:
394
373
  context,
395
374
  )
396
375
 
397
- # Apply secure formatting
398
376
  secure_stats = format_secure_status(
399
377
  raw_stats,
400
378
  project_root=context.config.project_path,
@@ -404,7 +382,6 @@ def _register_server_stats_tool(mcp_app: t.Any) -> None:
404
382
  return json.dumps(secure_stats, indent=2)
405
383
 
406
384
  except Exception as e:
407
- # Use secure error formatting
408
385
  formatter = get_secure_status_formatter()
409
386
  error_response = formatter.format_error_response(
410
387
  str(e),
@@ -412,23 +389,16 @@ def _register_server_stats_tool(mcp_app: t.Any) -> None:
412
389
  return json.dumps(error_response, indent=2)
413
390
 
414
391
 
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)
392
+ async def _build_server_stats_secure(context: t.Any) -> dict[str, t.Any]:
393
+ stats = await _build_server_stats(context)
420
394
 
421
- # Add state manager stats
422
395
  state_manager = getattr(context, "state_manager", None)
423
396
  _add_state_manager_stats(stats, state_manager)
424
397
 
425
- # Add security status
426
398
  security_manager = get_status_security_manager()
427
399
  stats["security_status"] = security_manager.get_security_status()
428
400
 
429
- # Add resource limiter status if available
430
401
  with suppress(Exception):
431
- # Resource limiter may not be initialized
432
402
  resource_limiter = get_websocket_resource_limiter()
433
403
  stats["websocket_resources"] = resource_limiter.get_resource_status()
434
404
 
@@ -436,25 +406,21 @@ def _build_server_stats_secure(context) -> dict[str, t.Any]:
436
406
 
437
407
 
438
408
  def _register_comprehensive_status_tool(mcp_app: t.Any) -> None:
439
- @mcp_app.tool()
409
+ @mcp_app.tool() # type: ignore[misc]
440
410
  async def get_comprehensive_status() -> str:
441
411
  client_id = "mcp_client"
442
412
  client_ip = "127.0.0.1"
443
413
 
444
414
  try:
445
- # Use secure status operation with request lock
446
415
  async with await secure_status_operation(
447
416
  client_id,
448
417
  "get_comprehensive_status",
449
418
  ):
450
- # Get raw status data with full security integration
451
419
  raw_status = await _get_comprehensive_status_secure(
452
420
  client_id=client_id,
453
421
  client_ip=client_ip,
454
- # Local-only access (auth_header defaults to None)
455
422
  )
456
423
 
457
- # Apply secure formatting
458
424
  context = get_context()
459
425
  project_root = context.config.project_path if context else None
460
426
 
@@ -467,7 +433,6 @@ def _register_comprehensive_status_tool(mcp_app: t.Any) -> None:
467
433
  return json.dumps(secure_status, indent=2)
468
434
 
469
435
  except Exception as e:
470
- # Use secure error formatting
471
436
  formatter = get_secure_status_formatter()
472
437
  error_response = formatter.format_error_response(
473
438
  str(e),
@@ -476,7 +441,7 @@ def _register_comprehensive_status_tool(mcp_app: t.Any) -> None:
476
441
 
477
442
 
478
443
  def _register_command_help_tool(mcp_app: t.Any) -> None:
479
- @mcp_app.tool()
444
+ @mcp_app.tool() # type: ignore[misc]
480
445
  async def list_slash_commands() -> str:
481
446
  try:
482
447
  commands = {
@@ -520,7 +485,7 @@ def _register_command_help_tool(mcp_app: t.Any) -> None:
520
485
 
521
486
  return json.dumps(
522
487
  {
523
- "available_commands": list(commands.keys()),
488
+ "available_commands": list[t.Any](commands.keys()),
524
489
  "command_details": commands,
525
490
  "total_commands": len(commands),
526
491
  },
@@ -529,7 +494,10 @@ def _register_command_help_tool(mcp_app: t.Any) -> None:
529
494
 
530
495
  except Exception as e:
531
496
  return json.dumps(
532
- {"error": f"Failed to list slash commands: {e}", "success": False},
497
+ {
498
+ "error": f"Failed to list[t.Any] slash commands: {e}",
499
+ "success": False,
500
+ },
533
501
  indent=2,
534
502
  )
535
503
 
@@ -545,7 +513,7 @@ def _validate_status_components(components: str) -> tuple[set[str], str | None]:
545
513
  return requested, None
546
514
 
547
515
 
548
- def _get_services_status() -> dict:
516
+ def _get_services_status() -> dict[str, t.Any]:
549
517
  from crackerjack.services.server_manager import (
550
518
  find_mcp_server_processes,
551
519
  find_websocket_server_processes,
@@ -566,9 +534,9 @@ def _get_services_status() -> dict:
566
534
  }
567
535
 
568
536
 
569
- def _get_resources_status(context: t.Any) -> dict:
537
+ def _get_resources_status(context: t.Any) -> dict[str, t.Any]:
570
538
  temp_files_count = (
571
- len(list(context.progress_dir.glob("*.json")))
539
+ len(list[t.Any](context.progress_dir.glob("*.json")))
572
540
  if context.progress_dir.exists()
573
541
  else 0
574
542
  )
@@ -579,8 +547,10 @@ def _get_resources_status(context: t.Any) -> dict:
579
547
  }
580
548
 
581
549
 
582
- def _build_filtered_status(requested: set[str], context: t.Any) -> dict:
583
- filtered_status = {"timestamp": time.time()}
550
+ async def _build_filtered_status(
551
+ requested: set[str], context: t.Any
552
+ ) -> dict[str, t.Any]:
553
+ filtered_status: dict[str, t.Any] = {"timestamp": time.time()}
584
554
 
585
555
  if "services" in requested:
586
556
  filtered_status["services"] = _get_services_status()
@@ -595,12 +565,11 @@ def _build_filtered_status(requested: set[str], context: t.Any) -> dict:
595
565
 
596
566
 
597
567
  def _register_filtered_status_tool(mcp_app: t.Any) -> None:
598
- @mcp_app.tool()
568
+ @mcp_app.tool() # type: ignore[misc]
599
569
  async def get_filtered_status(components: str = "all") -> str:
600
570
  client_id = "mcp_client"
601
571
 
602
572
  try:
603
- # Security validation with component filter data
604
573
  await validate_status_request(
605
574
  client_id, "get_filtered_status", {"components": components}
606
575
  )
@@ -612,12 +581,10 @@ def _register_filtered_status_tool(mcp_app: t.Any) -> None:
612
581
 
613
582
 
614
583
  async def _process_filtered_status_request(client_id: str, components: str) -> str:
615
- """Process filtered status request with component validation."""
616
584
  requested, error = _validate_status_components(components)
617
585
  if error:
618
586
  return _format_status_error(error)
619
587
 
620
- # Use secure status operation with timeout
621
588
  async with await secure_status_operation(
622
589
  client_id, "get_filtered_status", timeout=20.0
623
590
  ):
@@ -625,7 +592,6 @@ async def _process_filtered_status_request(client_id: str, components: str) -> s
625
592
 
626
593
 
627
594
  async def _collect_status_data(client_id: str, requested: set[str]) -> str:
628
- """Collect status data based on requested components."""
629
595
  context = get_context()
630
596
 
631
597
  if "all" in requested:
@@ -636,7 +602,6 @@ async def _collect_status_data(client_id: str, requested: set[str]) -> str:
636
602
  if not context:
637
603
  return _format_status_error("Server context not available")
638
604
 
639
- # Use bounded operation for filtered status
640
605
  raw_status = await execute_bounded_status_operation(
641
606
  "filtered_status",
642
607
  client_id,
@@ -648,8 +613,7 @@ async def _collect_status_data(client_id: str, requested: set[str]) -> str:
648
613
  return _apply_secure_formatting(raw_status, context)
649
614
 
650
615
 
651
- def _apply_secure_formatting(raw_status: dict, context: t.Any) -> str:
652
- """Apply secure formatting to status data."""
616
+ def _apply_secure_formatting(raw_status: dict[str, t.Any], context: t.Any) -> str:
653
617
  project_root = context.config.project_path if context else None
654
618
  secure_status = format_secure_status(
655
619
  raw_status,
@@ -660,6 +624,5 @@ def _apply_secure_formatting(raw_status: dict, context: t.Any) -> str:
660
624
 
661
625
 
662
626
  def _format_status_error(error_message: str) -> str:
663
- """Format status error response consistently."""
664
627
  formatter = get_secure_status_formatter()
665
628
  return json.dumps(formatter.format_error_response(error_message), indent=2)