claude-mpm 4.1.0__py3-none-any.whl → 4.1.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (358) hide show
  1. claude_mpm/BUILD_NUMBER +1 -1
  2. claude_mpm/VERSION +1 -1
  3. claude_mpm/__main__.py +1 -1
  4. claude_mpm/agents/BASE_PM.md +74 -46
  5. claude_mpm/agents/INSTRUCTIONS.md +11 -153
  6. claude_mpm/agents/WORKFLOW.md +61 -321
  7. claude_mpm/agents/__init__.py +11 -11
  8. claude_mpm/agents/agent_loader.py +23 -20
  9. claude_mpm/agents/agent_loader_integration.py +1 -1
  10. claude_mpm/agents/agents_metadata.py +27 -0
  11. claude_mpm/agents/async_agent_loader.py +5 -8
  12. claude_mpm/agents/base_agent_loader.py +36 -25
  13. claude_mpm/agents/frontmatter_validator.py +6 -6
  14. claude_mpm/agents/schema/agent_schema.json +1 -1
  15. claude_mpm/agents/system_agent_config.py +9 -9
  16. claude_mpm/agents/templates/api_qa.json +47 -2
  17. claude_mpm/agents/templates/imagemagick.json +256 -0
  18. claude_mpm/agents/templates/qa.json +41 -2
  19. claude_mpm/agents/templates/ticketing.json +5 -5
  20. claude_mpm/agents/templates/web_qa.json +133 -58
  21. claude_mpm/agents/templates/web_ui.json +3 -3
  22. claude_mpm/cli/__init__.py +51 -46
  23. claude_mpm/cli/__main__.py +1 -1
  24. claude_mpm/cli/commands/__init__.py +10 -12
  25. claude_mpm/cli/commands/agent_manager.py +186 -181
  26. claude_mpm/cli/commands/agents.py +271 -268
  27. claude_mpm/cli/commands/aggregate.py +30 -29
  28. claude_mpm/cli/commands/cleanup.py +50 -44
  29. claude_mpm/cli/commands/cleanup_orphaned_agents.py +25 -25
  30. claude_mpm/cli/commands/config.py +162 -127
  31. claude_mpm/cli/commands/doctor.py +52 -62
  32. claude_mpm/cli/commands/info.py +37 -25
  33. claude_mpm/cli/commands/mcp.py +3 -7
  34. claude_mpm/cli/commands/mcp_command_router.py +14 -18
  35. claude_mpm/cli/commands/mcp_install_commands.py +28 -23
  36. claude_mpm/cli/commands/mcp_pipx_config.py +58 -49
  37. claude_mpm/cli/commands/mcp_server_commands.py +23 -17
  38. claude_mpm/cli/commands/memory.py +192 -141
  39. claude_mpm/cli/commands/monitor.py +117 -88
  40. claude_mpm/cli/commands/run.py +120 -84
  41. claude_mpm/cli/commands/run_config_checker.py +4 -5
  42. claude_mpm/cli/commands/socketio_monitor.py +17 -19
  43. claude_mpm/cli/commands/tickets.py +92 -92
  44. claude_mpm/cli/parser.py +1 -5
  45. claude_mpm/cli/parsers/__init__.py +1 -1
  46. claude_mpm/cli/parsers/agent_manager_parser.py +50 -98
  47. claude_mpm/cli/parsers/agents_parser.py +2 -3
  48. claude_mpm/cli/parsers/base_parser.py +7 -5
  49. claude_mpm/cli/parsers/mcp_parser.py +4 -2
  50. claude_mpm/cli/parsers/monitor_parser.py +26 -18
  51. claude_mpm/cli/shared/__init__.py +10 -10
  52. claude_mpm/cli/shared/argument_patterns.py +57 -71
  53. claude_mpm/cli/shared/base_command.py +61 -53
  54. claude_mpm/cli/shared/error_handling.py +62 -58
  55. claude_mpm/cli/shared/output_formatters.py +78 -77
  56. claude_mpm/cli/startup_logging.py +204 -172
  57. claude_mpm/cli/utils.py +10 -11
  58. claude_mpm/cli_module/__init__.py +1 -1
  59. claude_mpm/cli_module/args.py +1 -1
  60. claude_mpm/cli_module/migration_example.py +5 -5
  61. claude_mpm/config/__init__.py +9 -9
  62. claude_mpm/config/agent_config.py +15 -14
  63. claude_mpm/config/experimental_features.py +4 -4
  64. claude_mpm/config/paths.py +0 -1
  65. claude_mpm/config/socketio_config.py +5 -6
  66. claude_mpm/constants.py +1 -2
  67. claude_mpm/core/__init__.py +8 -8
  68. claude_mpm/core/agent_name_normalizer.py +1 -1
  69. claude_mpm/core/agent_registry.py +20 -23
  70. claude_mpm/core/agent_session_manager.py +3 -3
  71. claude_mpm/core/base_service.py +7 -15
  72. claude_mpm/core/cache.py +4 -6
  73. claude_mpm/core/claude_runner.py +85 -113
  74. claude_mpm/core/config.py +43 -28
  75. claude_mpm/core/config_aliases.py +0 -9
  76. claude_mpm/core/config_constants.py +52 -30
  77. claude_mpm/core/constants.py +0 -1
  78. claude_mpm/core/container.py +18 -27
  79. claude_mpm/core/exceptions.py +2 -2
  80. claude_mpm/core/factories.py +10 -12
  81. claude_mpm/core/framework_loader.py +581 -280
  82. claude_mpm/core/hook_manager.py +26 -22
  83. claude_mpm/core/hook_performance_config.py +58 -47
  84. claude_mpm/core/injectable_service.py +1 -1
  85. claude_mpm/core/interactive_session.py +61 -152
  86. claude_mpm/core/interfaces.py +1 -100
  87. claude_mpm/core/lazy.py +5 -5
  88. claude_mpm/core/log_manager.py +587 -0
  89. claude_mpm/core/logger.py +125 -8
  90. claude_mpm/core/logging_config.py +15 -15
  91. claude_mpm/core/minimal_framework_loader.py +5 -8
  92. claude_mpm/core/oneshot_session.py +15 -33
  93. claude_mpm/core/optimized_agent_loader.py +4 -6
  94. claude_mpm/core/optimized_startup.py +2 -1
  95. claude_mpm/core/output_style_manager.py +147 -106
  96. claude_mpm/core/pm_hook_interceptor.py +0 -1
  97. claude_mpm/core/service_registry.py +11 -8
  98. claude_mpm/core/session_manager.py +1 -2
  99. claude_mpm/core/shared/__init__.py +1 -1
  100. claude_mpm/core/shared/config_loader.py +101 -97
  101. claude_mpm/core/shared/path_resolver.py +72 -68
  102. claude_mpm/core/shared/singleton_manager.py +56 -50
  103. claude_mpm/core/socketio_pool.py +26 -6
  104. claude_mpm/core/tool_access_control.py +4 -5
  105. claude_mpm/core/typing_utils.py +50 -59
  106. claude_mpm/core/unified_agent_registry.py +14 -19
  107. claude_mpm/core/unified_config.py +4 -6
  108. claude_mpm/core/unified_paths.py +197 -109
  109. claude_mpm/dashboard/open_dashboard.py +2 -4
  110. claude_mpm/experimental/cli_enhancements.py +51 -36
  111. claude_mpm/generators/agent_profile_generator.py +2 -4
  112. claude_mpm/hooks/base_hook.py +1 -2
  113. claude_mpm/hooks/claude_hooks/connection_pool.py +72 -26
  114. claude_mpm/hooks/claude_hooks/event_handlers.py +93 -38
  115. claude_mpm/hooks/claude_hooks/hook_handler.py +130 -76
  116. claude_mpm/hooks/claude_hooks/hook_handler_eventbus.py +104 -77
  117. claude_mpm/hooks/claude_hooks/memory_integration.py +2 -4
  118. claude_mpm/hooks/claude_hooks/response_tracking.py +15 -11
  119. claude_mpm/hooks/claude_hooks/tool_analysis.py +12 -18
  120. claude_mpm/hooks/memory_integration_hook.py +5 -5
  121. claude_mpm/hooks/tool_call_interceptor.py +1 -1
  122. claude_mpm/hooks/validation_hooks.py +4 -4
  123. claude_mpm/init.py +4 -9
  124. claude_mpm/models/__init__.py +2 -2
  125. claude_mpm/models/agent_session.py +11 -14
  126. claude_mpm/scripts/mcp_server.py +20 -11
  127. claude_mpm/scripts/mcp_wrapper.py +5 -5
  128. claude_mpm/scripts/mpm_doctor.py +321 -0
  129. claude_mpm/scripts/socketio_daemon.py +28 -25
  130. claude_mpm/scripts/socketio_daemon_hardened.py +298 -258
  131. claude_mpm/scripts/socketio_server_manager.py +116 -95
  132. claude_mpm/services/__init__.py +49 -49
  133. claude_mpm/services/agent_capabilities_service.py +12 -18
  134. claude_mpm/services/agents/__init__.py +22 -22
  135. claude_mpm/services/agents/agent_builder.py +140 -119
  136. claude_mpm/services/agents/deployment/__init__.py +3 -3
  137. claude_mpm/services/agents/deployment/agent_config_provider.py +9 -9
  138. claude_mpm/services/agents/deployment/agent_configuration_manager.py +19 -20
  139. claude_mpm/services/agents/deployment/agent_definition_factory.py +1 -5
  140. claude_mpm/services/agents/deployment/agent_deployment.py +136 -106
  141. claude_mpm/services/agents/deployment/agent_discovery_service.py +4 -8
  142. claude_mpm/services/agents/deployment/agent_environment_manager.py +2 -7
  143. claude_mpm/services/agents/deployment/agent_filesystem_manager.py +6 -10
  144. claude_mpm/services/agents/deployment/agent_format_converter.py +11 -15
  145. claude_mpm/services/agents/deployment/agent_frontmatter_validator.py +2 -3
  146. claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +5 -5
  147. claude_mpm/services/agents/deployment/agent_metrics_collector.py +13 -19
  148. claude_mpm/services/agents/deployment/agent_restore_handler.py +0 -1
  149. claude_mpm/services/agents/deployment/agent_template_builder.py +26 -35
  150. claude_mpm/services/agents/deployment/agent_validator.py +0 -1
  151. claude_mpm/services/agents/deployment/agent_version_manager.py +7 -9
  152. claude_mpm/services/agents/deployment/agent_versioning.py +3 -3
  153. claude_mpm/services/agents/deployment/agents_directory_resolver.py +6 -7
  154. claude_mpm/services/agents/deployment/async_agent_deployment.py +51 -38
  155. claude_mpm/services/agents/deployment/config/__init__.py +1 -1
  156. claude_mpm/services/agents/deployment/config/deployment_config.py +7 -8
  157. claude_mpm/services/agents/deployment/deployment_type_detector.py +1 -1
  158. claude_mpm/services/agents/deployment/deployment_wrapper.py +18 -18
  159. claude_mpm/services/agents/deployment/facade/__init__.py +1 -1
  160. claude_mpm/services/agents/deployment/facade/deployment_executor.py +0 -3
  161. claude_mpm/services/agents/deployment/facade/deployment_facade.py +3 -4
  162. claude_mpm/services/agents/deployment/interface_adapter.py +5 -7
  163. claude_mpm/services/agents/deployment/multi_source_deployment_service.py +345 -276
  164. claude_mpm/services/agents/deployment/pipeline/__init__.py +2 -2
  165. claude_mpm/services/agents/deployment/pipeline/pipeline_builder.py +1 -1
  166. claude_mpm/services/agents/deployment/pipeline/pipeline_context.py +6 -4
  167. claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +3 -3
  168. claude_mpm/services/agents/deployment/pipeline/steps/__init__.py +2 -2
  169. claude_mpm/services/agents/deployment/pipeline/steps/agent_processing_step.py +14 -13
  170. claude_mpm/services/agents/deployment/pipeline/steps/base_step.py +0 -1
  171. claude_mpm/services/agents/deployment/pipeline/steps/configuration_step.py +1 -1
  172. claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +8 -9
  173. claude_mpm/services/agents/deployment/pipeline/steps/validation_step.py +1 -1
  174. claude_mpm/services/agents/deployment/processors/__init__.py +1 -1
  175. claude_mpm/services/agents/deployment/processors/agent_processor.py +20 -16
  176. claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +5 -12
  177. claude_mpm/services/agents/deployment/results/__init__.py +1 -1
  178. claude_mpm/services/agents/deployment/results/deployment_result_builder.py +1 -1
  179. claude_mpm/services/agents/deployment/strategies/__init__.py +2 -2
  180. claude_mpm/services/agents/deployment/strategies/base_strategy.py +1 -7
  181. claude_mpm/services/agents/deployment/strategies/project_strategy.py +1 -4
  182. claude_mpm/services/agents/deployment/strategies/system_strategy.py +2 -3
  183. claude_mpm/services/agents/deployment/strategies/user_strategy.py +3 -7
  184. claude_mpm/services/agents/deployment/validation/__init__.py +1 -1
  185. claude_mpm/services/agents/deployment/validation/agent_validator.py +1 -1
  186. claude_mpm/services/agents/deployment/validation/template_validator.py +2 -2
  187. claude_mpm/services/agents/deployment/validation/validation_result.py +2 -6
  188. claude_mpm/services/agents/loading/__init__.py +1 -1
  189. claude_mpm/services/agents/loading/agent_profile_loader.py +6 -12
  190. claude_mpm/services/agents/loading/base_agent_manager.py +5 -5
  191. claude_mpm/services/agents/loading/framework_agent_loader.py +2 -4
  192. claude_mpm/services/agents/management/__init__.py +1 -1
  193. claude_mpm/services/agents/management/agent_capabilities_generator.py +1 -3
  194. claude_mpm/services/agents/management/agent_management_service.py +5 -9
  195. claude_mpm/services/agents/memory/__init__.py +4 -4
  196. claude_mpm/services/agents/memory/agent_memory_manager.py +280 -160
  197. claude_mpm/services/agents/memory/agent_persistence_service.py +0 -2
  198. claude_mpm/services/agents/memory/content_manager.py +44 -38
  199. claude_mpm/services/agents/memory/template_generator.py +4 -6
  200. claude_mpm/services/agents/registry/__init__.py +10 -6
  201. claude_mpm/services/agents/registry/deployed_agent_discovery.py +30 -27
  202. claude_mpm/services/agents/registry/modification_tracker.py +3 -6
  203. claude_mpm/services/async_session_logger.py +1 -2
  204. claude_mpm/services/claude_session_logger.py +1 -2
  205. claude_mpm/services/command_deployment_service.py +173 -0
  206. claude_mpm/services/command_handler_service.py +20 -22
  207. claude_mpm/services/core/__init__.py +25 -25
  208. claude_mpm/services/core/base.py +0 -5
  209. claude_mpm/services/core/interfaces/__init__.py +32 -32
  210. claude_mpm/services/core/interfaces/agent.py +0 -21
  211. claude_mpm/services/core/interfaces/communication.py +0 -27
  212. claude_mpm/services/core/interfaces/infrastructure.py +0 -56
  213. claude_mpm/services/core/interfaces/service.py +0 -29
  214. claude_mpm/services/diagnostics/__init__.py +1 -1
  215. claude_mpm/services/diagnostics/checks/__init__.py +6 -6
  216. claude_mpm/services/diagnostics/checks/agent_check.py +89 -80
  217. claude_mpm/services/diagnostics/checks/base_check.py +12 -16
  218. claude_mpm/services/diagnostics/checks/claude_desktop_check.py +84 -81
  219. claude_mpm/services/diagnostics/checks/common_issues_check.py +99 -91
  220. claude_mpm/services/diagnostics/checks/configuration_check.py +82 -77
  221. claude_mpm/services/diagnostics/checks/filesystem_check.py +67 -68
  222. claude_mpm/services/diagnostics/checks/installation_check.py +254 -94
  223. claude_mpm/services/diagnostics/checks/mcp_check.py +90 -88
  224. claude_mpm/services/diagnostics/checks/monitor_check.py +75 -76
  225. claude_mpm/services/diagnostics/checks/startup_log_check.py +67 -73
  226. claude_mpm/services/diagnostics/diagnostic_runner.py +67 -59
  227. claude_mpm/services/diagnostics/doctor_reporter.py +107 -70
  228. claude_mpm/services/diagnostics/models.py +21 -19
  229. claude_mpm/services/event_aggregator.py +10 -17
  230. claude_mpm/services/event_bus/__init__.py +1 -1
  231. claude_mpm/services/event_bus/config.py +54 -35
  232. claude_mpm/services/event_bus/event_bus.py +76 -71
  233. claude_mpm/services/event_bus/relay.py +74 -64
  234. claude_mpm/services/events/__init__.py +11 -11
  235. claude_mpm/services/events/consumers/__init__.py +3 -3
  236. claude_mpm/services/events/consumers/dead_letter.py +71 -63
  237. claude_mpm/services/events/consumers/logging.py +39 -37
  238. claude_mpm/services/events/consumers/metrics.py +56 -57
  239. claude_mpm/services/events/consumers/socketio.py +82 -81
  240. claude_mpm/services/events/core.py +110 -99
  241. claude_mpm/services/events/interfaces.py +56 -72
  242. claude_mpm/services/events/producers/__init__.py +1 -1
  243. claude_mpm/services/events/producers/hook.py +38 -38
  244. claude_mpm/services/events/producers/system.py +46 -44
  245. claude_mpm/services/exceptions.py +81 -80
  246. claude_mpm/services/framework_claude_md_generator/__init__.py +2 -4
  247. claude_mpm/services/framework_claude_md_generator/content_assembler.py +3 -5
  248. claude_mpm/services/framework_claude_md_generator/content_validator.py +1 -1
  249. claude_mpm/services/framework_claude_md_generator/deployment_manager.py +4 -4
  250. claude_mpm/services/framework_claude_md_generator/section_generators/__init__.py +0 -1
  251. claude_mpm/services/framework_claude_md_generator/section_generators/agents.py +0 -2
  252. claude_mpm/services/framework_claude_md_generator/version_manager.py +4 -5
  253. claude_mpm/services/hook_service.py +6 -9
  254. claude_mpm/services/infrastructure/__init__.py +1 -1
  255. claude_mpm/services/infrastructure/context_preservation.py +8 -12
  256. claude_mpm/services/infrastructure/monitoring.py +21 -23
  257. claude_mpm/services/mcp_gateway/__init__.py +37 -37
  258. claude_mpm/services/mcp_gateway/auto_configure.py +95 -103
  259. claude_mpm/services/mcp_gateway/config/__init__.py +1 -1
  260. claude_mpm/services/mcp_gateway/config/config_loader.py +23 -25
  261. claude_mpm/services/mcp_gateway/config/config_schema.py +5 -5
  262. claude_mpm/services/mcp_gateway/config/configuration.py +9 -6
  263. claude_mpm/services/mcp_gateway/core/__init__.py +10 -10
  264. claude_mpm/services/mcp_gateway/core/base.py +0 -3
  265. claude_mpm/services/mcp_gateway/core/interfaces.py +1 -38
  266. claude_mpm/services/mcp_gateway/core/process_pool.py +99 -93
  267. claude_mpm/services/mcp_gateway/core/singleton_manager.py +65 -62
  268. claude_mpm/services/mcp_gateway/core/startup_verification.py +75 -74
  269. claude_mpm/services/mcp_gateway/main.py +2 -1
  270. claude_mpm/services/mcp_gateway/registry/service_registry.py +5 -8
  271. claude_mpm/services/mcp_gateway/registry/tool_registry.py +1 -1
  272. claude_mpm/services/mcp_gateway/server/__init__.py +1 -1
  273. claude_mpm/services/mcp_gateway/server/mcp_gateway.py +12 -19
  274. claude_mpm/services/mcp_gateway/server/stdio_handler.py +4 -3
  275. claude_mpm/services/mcp_gateway/server/stdio_server.py +79 -71
  276. claude_mpm/services/mcp_gateway/tools/__init__.py +2 -2
  277. claude_mpm/services/mcp_gateway/tools/base_adapter.py +5 -6
  278. claude_mpm/services/mcp_gateway/tools/document_summarizer.py +13 -22
  279. claude_mpm/services/mcp_gateway/tools/health_check_tool.py +79 -78
  280. claude_mpm/services/mcp_gateway/tools/hello_world.py +12 -14
  281. claude_mpm/services/mcp_gateway/tools/ticket_tools.py +42 -49
  282. claude_mpm/services/mcp_gateway/tools/unified_ticket_tool.py +51 -55
  283. claude_mpm/services/memory/__init__.py +3 -3
  284. claude_mpm/services/memory/builder.py +3 -6
  285. claude_mpm/services/memory/cache/__init__.py +1 -1
  286. claude_mpm/services/memory/cache/shared_prompt_cache.py +3 -5
  287. claude_mpm/services/memory/cache/simple_cache.py +1 -1
  288. claude_mpm/services/memory/indexed_memory.py +5 -7
  289. claude_mpm/services/memory/optimizer.py +7 -10
  290. claude_mpm/services/memory/router.py +8 -9
  291. claude_mpm/services/memory_hook_service.py +48 -34
  292. claude_mpm/services/monitor_build_service.py +77 -73
  293. claude_mpm/services/port_manager.py +130 -108
  294. claude_mpm/services/project/analyzer.py +12 -10
  295. claude_mpm/services/project/registry.py +11 -11
  296. claude_mpm/services/recovery_manager.py +10 -19
  297. claude_mpm/services/response_tracker.py +0 -1
  298. claude_mpm/services/runner_configuration_service.py +19 -20
  299. claude_mpm/services/session_management_service.py +7 -11
  300. claude_mpm/services/shared/__init__.py +1 -1
  301. claude_mpm/services/shared/async_service_base.py +58 -50
  302. claude_mpm/services/shared/config_service_base.py +73 -67
  303. claude_mpm/services/shared/lifecycle_service_base.py +82 -78
  304. claude_mpm/services/shared/manager_base.py +94 -82
  305. claude_mpm/services/shared/service_factory.py +96 -98
  306. claude_mpm/services/socketio/__init__.py +3 -3
  307. claude_mpm/services/socketio/client_proxy.py +5 -5
  308. claude_mpm/services/socketio/event_normalizer.py +199 -181
  309. claude_mpm/services/socketio/handlers/__init__.py +3 -3
  310. claude_mpm/services/socketio/handlers/base.py +5 -4
  311. claude_mpm/services/socketio/handlers/connection.py +163 -136
  312. claude_mpm/services/socketio/handlers/file.py +13 -14
  313. claude_mpm/services/socketio/handlers/git.py +12 -7
  314. claude_mpm/services/socketio/handlers/hook.py +49 -44
  315. claude_mpm/services/socketio/handlers/memory.py +0 -1
  316. claude_mpm/services/socketio/handlers/project.py +0 -1
  317. claude_mpm/services/socketio/handlers/registry.py +37 -19
  318. claude_mpm/services/socketio/migration_utils.py +98 -84
  319. claude_mpm/services/socketio/server/__init__.py +1 -1
  320. claude_mpm/services/socketio/server/broadcaster.py +81 -87
  321. claude_mpm/services/socketio/server/core.py +65 -54
  322. claude_mpm/services/socketio/server/eventbus_integration.py +95 -56
  323. claude_mpm/services/socketio/server/main.py +64 -38
  324. claude_mpm/services/socketio_client_manager.py +10 -12
  325. claude_mpm/services/subprocess_launcher_service.py +4 -7
  326. claude_mpm/services/system_instructions_service.py +13 -14
  327. claude_mpm/services/ticket_manager.py +2 -2
  328. claude_mpm/services/utility_service.py +5 -13
  329. claude_mpm/services/version_control/__init__.py +16 -16
  330. claude_mpm/services/version_control/branch_strategy.py +5 -8
  331. claude_mpm/services/version_control/conflict_resolution.py +9 -23
  332. claude_mpm/services/version_control/git_operations.py +5 -7
  333. claude_mpm/services/version_control/semantic_versioning.py +16 -17
  334. claude_mpm/services/version_control/version_parser.py +13 -18
  335. claude_mpm/services/version_service.py +10 -11
  336. claude_mpm/storage/__init__.py +1 -1
  337. claude_mpm/storage/state_storage.py +22 -28
  338. claude_mpm/utils/__init__.py +6 -6
  339. claude_mpm/utils/agent_dependency_loader.py +47 -33
  340. claude_mpm/utils/config_manager.py +11 -14
  341. claude_mpm/utils/dependency_cache.py +1 -1
  342. claude_mpm/utils/dependency_manager.py +13 -17
  343. claude_mpm/utils/dependency_strategies.py +8 -10
  344. claude_mpm/utils/environment_context.py +3 -9
  345. claude_mpm/utils/error_handler.py +3 -13
  346. claude_mpm/utils/file_utils.py +1 -1
  347. claude_mpm/utils/path_operations.py +8 -12
  348. claude_mpm/utils/robust_installer.py +110 -33
  349. claude_mpm/utils/subprocess_utils.py +5 -6
  350. claude_mpm/validation/agent_validator.py +3 -6
  351. claude_mpm/validation/frontmatter_validator.py +1 -1
  352. {claude_mpm-4.1.0.dist-info → claude_mpm-4.1.2.dist-info}/METADATA +1 -1
  353. claude_mpm-4.1.2.dist-info/RECORD +498 -0
  354. claude_mpm-4.1.0.dist-info/RECORD +0 -494
  355. {claude_mpm-4.1.0.dist-info → claude_mpm-4.1.2.dist-info}/WHEEL +0 -0
  356. {claude_mpm-4.1.0.dist-info → claude_mpm-4.1.2.dist-info}/entry_points.txt +0 -0
  357. {claude_mpm-4.1.0.dist-info → claude_mpm-4.1.2.dist-info}/licenses/LICENSE +0 -0
  358. {claude_mpm-4.1.0.dist-info → claude_mpm-4.1.2.dist-info}/top_level.txt +0 -0
@@ -12,17 +12,14 @@ import logging
12
12
  from threading import RLock
13
13
  from typing import Any, Dict, List, Optional, Type, TypeVar
14
14
 
15
- from claude_mpm.core.logger import get_logger
16
- from claude_mpm.services.mcp_gateway.core.base import BaseMCPService
17
- from claude_mpm.services.shared import ManagerBase
18
15
  from claude_mpm.services.mcp_gateway.core.interfaces import (
19
16
  IMCPCommunication,
20
17
  IMCPConfiguration,
21
18
  IMCPGateway,
22
19
  IMCPLifecycle,
23
- IMCPToolAdapter,
24
20
  IMCPToolRegistry,
25
21
  )
22
+ from claude_mpm.services.shared import ManagerBase
26
23
 
27
24
  T = TypeVar("T")
28
25
 
@@ -324,10 +321,10 @@ class MCPServiceRegistry(ManagerBase):
324
321
  """
325
322
  with self._lock:
326
323
  services = set()
327
- services.update(interface.__name__ for interface in self._services.keys())
328
- services.update(interface.__name__ for interface in self._factories.keys())
329
- services.update(interface.__name__ for interface in self._singletons.keys())
330
- return sorted(list(services))
324
+ services.update(interface.__name__ for interface in self._services)
325
+ services.update(interface.__name__ for interface in self._factories)
326
+ services.update(interface.__name__ for interface in self._singletons)
327
+ return sorted(services)
331
328
 
332
329
  def clear(self) -> None:
333
330
  """Clear all service registrations."""
@@ -321,7 +321,7 @@ class ToolRegistry(BaseMCPService, IMCPToolRegistry):
321
321
  return result
322
322
 
323
323
  except Exception as e:
324
- error_msg = f"Exception invoking tool {tool_name}: {str(e)}"
324
+ error_msg = f"Exception invoking tool {tool_name}: {e!s}"
325
325
  self.log_error(error_msg)
326
326
  self.log_error(f"Traceback: {traceback.format_exc()}")
327
327
 
@@ -9,7 +9,7 @@ from .mcp_gateway import MCPGateway
9
9
  from .stdio_handler import AlternativeStdioHandler, StdioHandler
10
10
 
11
11
  __all__ = [
12
+ "AlternativeStdioHandler",
12
13
  "MCPGateway",
13
14
  "StdioHandler",
14
- "AlternativeStdioHandler",
15
15
  ]
@@ -13,28 +13,27 @@ Part of ISS-0035: MCP Gateway Implementation - Core Gateway and Tool Registry
13
13
  """
14
14
 
15
15
  import asyncio
16
+ import contextlib
16
17
  import json
17
18
  import traceback
18
19
  from datetime import datetime
19
- from typing import Any, Callable, Dict, List, Optional, Set, Union
20
+ from typing import Any, Callable, Dict, List, Optional, Union
20
21
 
21
22
  # Import from the official MCP package
22
- from mcp.server import NotificationOptions, Server
23
+ from mcp.server import Server
23
24
  from mcp.types import (
24
25
  EmbeddedResource,
25
26
  ImageContent,
26
- InitializeResult,
27
27
  TextContent,
28
28
  Tool,
29
29
  )
30
30
 
31
- from claude_mpm.services.mcp_gateway.core.base import BaseMCPService, MCPServiceState
31
+ from claude_mpm.services.mcp_gateway.core.base import BaseMCPService
32
32
  from claude_mpm.services.mcp_gateway.core.interfaces import (
33
33
  IMCPCommunication,
34
34
  IMCPGateway,
35
35
  IMCPToolRegistry,
36
36
  MCPToolInvocation,
37
- MCPToolResult,
38
37
  )
39
38
 
40
39
 
@@ -166,18 +165,14 @@ class MCPGateway(BaseMCPService, IMCPGateway):
166
165
  # Return successful result
167
166
  if isinstance(result.data, str):
168
167
  return [TextContent(type="text", text=result.data)]
169
- else:
170
- return [
171
- TextContent(
172
- type="text", text=json.dumps(result.data, indent=2)
173
- )
174
- ]
175
- else:
176
- # Return error
177
- return [TextContent(type="text", text=f"Error: {result.error}")]
168
+ return [
169
+ TextContent(type="text", text=json.dumps(result.data, indent=2))
170
+ ]
171
+ # Return error
172
+ return [TextContent(type="text", text=f"Error: {result.error}")]
178
173
 
179
174
  except Exception as e:
180
- error_msg = f"Failed to invoke tool {name}: {str(e)}"
175
+ error_msg = f"Failed to invoke tool {name}: {e!s}"
181
176
  self.log_error(error_msg)
182
177
  self._metrics["errors"] += 1
183
178
  return [TextContent(type="text", text=f"Error: {error_msg}")]
@@ -267,10 +262,8 @@ class MCPGateway(BaseMCPService, IMCPGateway):
267
262
  # Cancel run task if active
268
263
  if self._run_task and not self._run_task.done():
269
264
  self._run_task.cancel()
270
- try:
265
+ with contextlib.suppress(asyncio.CancelledError):
271
266
  await self._run_task
272
- except asyncio.CancelledError:
273
- pass
274
267
 
275
268
  # Clean up resources
276
269
  if self._tool_registry:
@@ -328,7 +321,7 @@ class MCPGateway(BaseMCPService, IMCPGateway):
328
321
  return {
329
322
  "jsonrpc": "2.0",
330
323
  "id": request.get("id"),
331
- "error": {"code": -32603, "message": f"Internal error: {str(e)}"},
324
+ "error": {"code": -32603, "message": f"Internal error: {e!s}"},
332
325
  }
333
326
 
334
327
  async def run(self) -> None:
@@ -11,13 +11,14 @@ Part of ISS-0035: MCP Server Implementation - Core Server and Tool Registry
11
11
  import asyncio
12
12
  import json
13
13
  import sys
14
- import traceback
15
- from asyncio import StreamReader, StreamWriter
16
- from typing import Any, Callable, Dict, Optional
14
+ from typing import TYPE_CHECKING, Any, Dict, Optional
17
15
 
18
16
  from claude_mpm.services.mcp_gateway.core.base import BaseMCPService
19
17
  from claude_mpm.services.mcp_gateway.core.interfaces import IMCPCommunication
20
18
 
19
+ if TYPE_CHECKING:
20
+ from asyncio import StreamReader, StreamWriter
21
+
21
22
 
22
23
  class StdioHandler(BaseMCPService, IMCPCommunication):
23
24
  """
@@ -13,13 +13,11 @@ use JSON-RPC protocol, and exit cleanly when stdin closes.
13
13
  """
14
14
 
15
15
  import asyncio
16
- import json
17
16
  import logging
18
17
  import os
19
18
  import sys
20
19
  import time
21
- from pathlib import Path
22
- from typing import Any, Dict, Optional
20
+ from typing import Any, Dict
23
21
 
24
22
  # Import MCP SDK components
25
23
  from mcp.server import NotificationOptions, Server
@@ -28,10 +26,7 @@ from mcp.server.stdio import stdio_server
28
26
  from mcp.types import TextContent, Tool
29
27
 
30
28
  # Import pydantic for model patching
31
- from pydantic import BaseModel
32
-
33
29
  from claude_mpm.core.logger import get_logger
34
- from claude_mpm.services.mcp_gateway.core.singleton_manager import get_gateway_manager
35
30
 
36
31
  # Import unified ticket tool if available
37
32
  try:
@@ -47,72 +42,89 @@ except ImportError:
47
42
  def apply_backward_compatibility_patches():
48
43
  """
49
44
  Apply backward compatibility patches for MCP protocol differences.
50
-
45
+
51
46
  This function patches the MCP Server to handle missing clientInfo
52
47
  in initialize requests from older Claude Code versions.
53
48
  """
54
49
  try:
55
50
  from mcp.server import Server
56
-
51
+
57
52
  logger = get_logger("MCPPatcher")
58
- logger.info("Applying MCP Server message handling patch for backward compatibility")
59
-
53
+ logger.info(
54
+ "Applying MCP Server message handling patch for backward compatibility"
55
+ )
56
+
60
57
  # Store the original _handle_message method
61
58
  original_handle_message = Server._handle_message
62
-
63
- async def patched_handle_message(self, message, session, lifespan_context, raise_exceptions=False):
59
+
60
+ async def patched_handle_message(
61
+ self, message, session, lifespan_context, raise_exceptions=False
62
+ ):
64
63
  """Patched message handler that adds clientInfo if missing from initialize requests."""
65
64
  try:
66
65
  # Check if this is a request responder with initialize method
67
- if hasattr(message, 'request') and hasattr(message.request, 'method'):
66
+ if hasattr(message, "request") and hasattr(message.request, "method"):
68
67
  request = message.request
69
- if (request.method == 'initialize' and
70
- hasattr(request, 'params') and
71
- request.params is not None):
72
-
68
+ if (
69
+ request.method == "initialize"
70
+ and hasattr(request, "params")
71
+ and request.params is not None
72
+ ):
73
+
73
74
  # Convert params to dict to check for clientInfo
74
75
  params_dict = request.params
75
- if hasattr(params_dict, 'model_dump'):
76
+ if hasattr(params_dict, "model_dump"):
76
77
  params_dict = params_dict.model_dump()
77
- elif hasattr(params_dict, 'dict'):
78
+ elif hasattr(params_dict, "dict"):
78
79
  params_dict = params_dict.dict()
79
-
80
- if isinstance(params_dict, dict) and 'clientInfo' not in params_dict:
81
- logger.info("Adding default clientInfo for backward compatibility")
82
-
80
+
81
+ if (
82
+ isinstance(params_dict, dict)
83
+ and "clientInfo" not in params_dict
84
+ ):
85
+ logger.info(
86
+ "Adding default clientInfo for backward compatibility"
87
+ )
88
+
83
89
  # Add default clientInfo
84
- params_dict['clientInfo'] = {
85
- 'name': 'claude-desktop',
86
- 'version': 'unknown'
90
+ params_dict["clientInfo"] = {
91
+ "name": "claude-desktop",
92
+ "version": "unknown",
87
93
  }
88
-
94
+
89
95
  # Try to update the params object
90
- if hasattr(request.params, '__dict__'):
91
- request.params.clientInfo = params_dict['clientInfo']
92
-
96
+ if hasattr(request.params, "__dict__"):
97
+ request.params.clientInfo = params_dict["clientInfo"]
98
+
93
99
  # Call the original handler
94
- return await original_handle_message(self, message, session, lifespan_context, raise_exceptions)
95
-
100
+ return await original_handle_message(
101
+ self, message, session, lifespan_context, raise_exceptions
102
+ )
103
+
96
104
  except Exception as e:
97
105
  logger.warning(f"Error in patched message handler: {e}")
98
106
  # Fall back to original handler
99
- return await original_handle_message(self, message, session, lifespan_context, raise_exceptions)
100
-
107
+ return await original_handle_message(
108
+ self, message, session, lifespan_context, raise_exceptions
109
+ )
110
+
101
111
  # Apply the patch
102
112
  Server._handle_message = patched_handle_message
103
113
  logger.info("Applied MCP Server message handling patch")
104
114
  return True
105
-
115
+
106
116
  except ImportError as e:
107
- get_logger("MCPPatcher").warning(f"Could not import MCP Server for patching: {e}")
117
+ get_logger("MCPPatcher").warning(
118
+ f"Could not import MCP Server for patching: {e}"
119
+ )
108
120
  return False
109
121
  except Exception as e:
110
- get_logger("MCPPatcher").error(f"Failed to apply backward compatibility patch: {e}")
122
+ get_logger("MCPPatcher").error(
123
+ f"Failed to apply backward compatibility patch: {e}"
124
+ )
111
125
  return False
112
126
 
113
127
 
114
-
115
-
116
128
  class SimpleMCPServer:
117
129
  """
118
130
  A simple stdio-based MCP server implementation.
@@ -140,20 +152,20 @@ class SimpleMCPServer:
140
152
  self.version = version
141
153
  self.logger = get_logger("MCPStdioServer")
142
154
  self.startup_time = time.time()
143
-
155
+
144
156
  # Log startup timing
145
157
  self.logger.info(f"Initializing MCP server {name} v{version}")
146
158
  start_time = time.time()
147
159
 
148
160
  # Apply backward compatibility patches before creating server
149
161
  apply_backward_compatibility_patches()
150
-
162
+
151
163
  # Create MCP server instance
152
164
  self.server = Server(name)
153
165
 
154
166
  # Register default tools
155
167
  self._register_tools()
156
-
168
+
157
169
  # Log initialization time
158
170
  init_time = time.time() - start_time
159
171
  self.logger.info(f"MCP server initialized in {init_time:.2f} seconds")
@@ -187,21 +199,20 @@ class SimpleMCPServer:
187
199
  # Brief: First and last portions with key sentences
188
200
  return self._create_brief_summary(sentences, max_length)
189
201
 
190
- elif style == "detailed":
202
+ if style == "detailed":
191
203
  # Detailed: More comprehensive with section preservation
192
204
  return self._create_detailed_summary(sentences, content, max_length)
193
205
 
194
- elif style == "bullet_points":
206
+ if style == "bullet_points":
195
207
  # Extract key points as bullet list
196
208
  return self._create_bullet_summary(sentences, content, max_length)
197
209
 
198
- elif style == "executive":
210
+ if style == "executive":
199
211
  # Executive: Summary + key findings + recommendations
200
212
  return self._create_executive_summary(sentences, content, max_length)
201
213
 
202
- else:
203
- # Default to brief
204
- return self._create_brief_summary(sentences, max_length)
214
+ # Default to brief
215
+ return self._create_brief_summary(sentences, max_length)
205
216
 
206
217
  def _create_brief_summary(self, sentences: list[str], max_length: int) -> str:
207
218
  """Create a brief summary by selecting most important sentences."""
@@ -298,7 +309,7 @@ class SimpleMCPServer:
298
309
 
299
310
  # Summarize each paragraph
300
311
  summary_parts = []
301
- words_per_para = max_length // len(paragraphs)
312
+ max_length // len(paragraphs)
302
313
 
303
314
  for para in paragraphs:
304
315
  if not para.strip():
@@ -378,7 +389,6 @@ class SimpleMCPServer:
378
389
  sections.append(f"OVERVIEW:\n{overview}")
379
390
 
380
391
  # Key Findings
381
- import re
382
392
 
383
393
  findings = []
384
394
 
@@ -402,7 +412,7 @@ class SimpleMCPServer:
402
412
  break
403
413
 
404
414
  if findings:
405
- sections.append(f"\nKEY FINDINGS:\n• " + "\n• ".join(findings[:3]))
415
+ sections.append("\nKEY FINDINGS:\n• " + "\n• ".join(findings[:3]))
406
416
 
407
417
  # Recommendations (look for action-oriented sentences)
408
418
  action_patterns = [
@@ -424,9 +434,7 @@ class SimpleMCPServer:
424
434
  break
425
435
 
426
436
  if recommendations:
427
- sections.append(
428
- f"\nRECOMMENDATIONS:\n• " + "\n• ".join(recommendations[:3])
429
- )
437
+ sections.append("\nRECOMMENDATIONS:\n• " + "\n• ".join(recommendations[:3]))
430
438
 
431
439
  # If no sections were created, fall back to brief summary
432
440
  if not sections:
@@ -449,14 +457,14 @@ class SimpleMCPServer:
449
457
  # NOTE: Defer initialization to avoid event loop issues
450
458
  self.unified_ticket_tool = None
451
459
  self._ticket_tool_initialized = False
452
-
460
+
453
461
  @self.server.list_tools()
454
462
  async def handle_list_tools() -> list[Tool]:
455
463
  """List available tools."""
456
464
  # Initialize ticket tool lazily if needed
457
465
  if not self._ticket_tool_initialized and TICKET_TOOLS_AVAILABLE:
458
466
  await self._initialize_ticket_tool()
459
-
467
+
460
468
  tools = [
461
469
  Tool(
462
470
  name="status",
@@ -519,7 +527,6 @@ class SimpleMCPServer:
519
527
  self.logger.info(f"Listing {len(tools)} available tools")
520
528
  return tools
521
529
 
522
-
523
530
  @self.server.call_tool()
524
531
  async def handle_call_tool(
525
532
  name: str, arguments: Dict[str, Any]
@@ -544,11 +551,11 @@ class SimpleMCPServer:
544
551
 
545
552
  result = f"Working Directory: {os.getcwd()}"
546
553
  elif info_type == "all":
554
+ import datetime
555
+ import os
547
556
  import platform
548
557
  import sys
549
- import os
550
- import datetime
551
-
558
+
552
559
  result = (
553
560
  f"=== System Status ===\n"
554
561
  f"Platform: {platform.system()} {platform.release()}\n"
@@ -572,7 +579,7 @@ class SimpleMCPServer:
572
579
  # Initialize ticket tool lazily if needed
573
580
  if not self._ticket_tool_initialized and TICKET_TOOLS_AVAILABLE:
574
581
  await self._initialize_ticket_tool()
575
-
582
+
576
583
  if self.unified_ticket_tool:
577
584
  # Handle unified ticket tool invocations
578
585
  from claude_mpm.services.mcp_gateway.core.interfaces import (
@@ -605,26 +612,25 @@ class SimpleMCPServer:
605
612
  return [TextContent(type="text", text=result)]
606
613
 
607
614
  except Exception as e:
608
- error_msg = f"Error executing tool {name}: {str(e)}"
615
+ error_msg = f"Error executing tool {name}: {e!s}"
609
616
  self.logger.error(error_msg)
610
617
  return [TextContent(type="text", text=error_msg)]
611
618
 
612
-
613
619
  async def _initialize_ticket_tool(self):
614
620
  """
615
621
  Initialize the unified ticket tool asynchronously.
616
-
622
+
617
623
  This is called lazily when the tool is first needed,
618
624
  ensuring an event loop is available.
619
625
  """
620
626
  if self._ticket_tool_initialized or not TICKET_TOOLS_AVAILABLE:
621
627
  return
622
-
628
+
623
629
  try:
624
630
  self.logger.info("Initializing unified ticket tool...")
625
631
  self.unified_ticket_tool = UnifiedTicketTool()
626
632
  # If the tool has an async init method, call it
627
- if hasattr(self.unified_ticket_tool, 'initialize'):
633
+ if hasattr(self.unified_ticket_tool, "initialize"):
628
634
  await self.unified_ticket_tool.initialize()
629
635
  self._ticket_tool_initialized = True
630
636
  self.logger.info("Unified ticket tool initialized successfully")
@@ -680,15 +686,15 @@ async def main():
680
686
  level=logging.INFO,
681
687
  format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
682
688
  stream=sys.stderr,
683
- force=True # Force reconfiguration even if already configured
689
+ force=True, # Force reconfiguration even if already configured
684
690
  )
685
-
691
+
686
692
  # Ensure all loggers output to stderr
687
693
  for logger_name in logging.Logger.manager.loggerDict:
688
694
  logger = logging.getLogger(logger_name)
689
695
  for handler in logger.handlers[:]:
690
696
  # Remove any handlers that might write to stdout
691
- if hasattr(handler, 'stream') and handler.stream == sys.stdout:
697
+ if hasattr(handler, "stream") and handler.stream == sys.stdout:
692
698
  logger.removeHandler(handler)
693
699
 
694
700
  # Create and run server
@@ -699,14 +705,16 @@ async def main():
699
705
  def main_sync():
700
706
  """Synchronous entry point for use as a console script."""
701
707
  import os
708
+
702
709
  # Disable telemetry by default
703
- os.environ.setdefault('DISABLE_TELEMETRY', '1')
710
+ os.environ.setdefault("DISABLE_TELEMETRY", "1")
704
711
  asyncio.run(main())
705
712
 
706
713
 
707
714
  if __name__ == "__main__":
708
715
  import os
716
+
709
717
  # Disable telemetry by default
710
- os.environ.setdefault('DISABLE_TELEMETRY', '1')
718
+ os.environ.setdefault("DISABLE_TELEMETRY", "1")
711
719
  # Run the async main function
712
720
  main_sync()
@@ -16,9 +16,9 @@ from .unified_ticket_tool import UnifiedTicketTool
16
16
 
17
17
  __all__ = [
18
18
  "BaseToolAdapter",
19
- "EchoToolAdapter",
20
19
  "CalculatorToolAdapter",
21
- "SystemInfoToolAdapter",
22
20
  "DocumentSummarizerTool",
21
+ "EchoToolAdapter",
22
+ "SystemInfoToolAdapter",
23
23
  "UnifiedTicketTool",
24
24
  ]
@@ -7,10 +7,9 @@ Base class for MCP tool adapters and example implementations.
7
7
  Part of ISS-0035: MCP Server Implementation - Core Server and Tool Registry
8
8
  """
9
9
 
10
- import traceback
11
10
  from abc import ABC
12
11
  from datetime import datetime
13
- from typing import Any, Dict, Optional
12
+ from typing import Any, Dict
14
13
 
15
14
  from claude_mpm.services.mcp_gateway.core.base import BaseMCPService
16
15
  from claude_mpm.services.mcp_gateway.core.interfaces import (
@@ -266,7 +265,7 @@ class EchoToolAdapter(BaseToolAdapter):
266
265
 
267
266
  return MCPToolResult(
268
267
  success=False,
269
- error=f"Echo tool failed: {str(e)}",
268
+ error=f"Echo tool failed: {e!s}",
270
269
  execution_time=execution_time,
271
270
  )
272
271
 
@@ -368,7 +367,7 @@ class CalculatorToolAdapter(BaseToolAdapter):
368
367
 
369
368
  return MCPToolResult(
370
369
  success=False,
371
- error=f"Calculator tool failed: {str(e)}",
370
+ error=f"Calculator tool failed: {e!s}",
372
371
  execution_time=execution_time,
373
372
  )
374
373
 
@@ -471,7 +470,7 @@ class SystemInfoToolAdapter(BaseToolAdapter):
471
470
 
472
471
  return MCPToolResult(
473
472
  success=False,
474
- error=f"System info tool requires psutil: {str(e)}",
473
+ error=f"System info tool requires psutil: {e!s}",
475
474
  execution_time=execution_time,
476
475
  )
477
476
  except Exception as e:
@@ -481,6 +480,6 @@ class SystemInfoToolAdapter(BaseToolAdapter):
481
480
 
482
481
  return MCPToolResult(
483
482
  success=False,
484
- error=f"System info tool failed: {str(e)}",
483
+ error=f"System info tool failed: {e!s}",
485
484
  execution_time=execution_time,
486
485
  )
@@ -8,20 +8,15 @@ Supports multiple file formats and summarization strategies.
8
8
  Part of ISS-0037: Document Summarizer Tool - Intelligent Document Processing
9
9
  """
10
10
 
11
- import csv
12
11
  import hashlib
13
- import json
14
12
  import mimetypes
15
13
  import os
16
14
  import re
17
15
  from collections import OrderedDict
18
16
  from datetime import datetime
19
- from functools import lru_cache
20
17
  from pathlib import Path
21
18
  from typing import Any, Dict, List, Optional, Tuple
22
19
 
23
- import yaml
24
-
25
20
  from claude_mpm.services.mcp_gateway.core.interfaces import (
26
21
  MCPToolDefinition,
27
22
  MCPToolInvocation,
@@ -483,8 +478,7 @@ class DocumentSummarizerTool(BaseToolAdapter):
483
478
  result = "\n".join(key_lines)
484
479
  if len(result) <= max_chars:
485
480
  return result
486
- else:
487
- return self._truncate_at_sentence(result, max_chars)
481
+ return self._truncate_at_sentence(result, max_chars)
488
482
 
489
483
  # Fallback to brief summary if no key points found
490
484
  return self._summarize_brief(text, max_chars)
@@ -556,7 +550,7 @@ class DocumentSummarizerTool(BaseToolAdapter):
556
550
  # Add some code blocks if space allows
557
551
  if preserve_code and code_blocks:
558
552
  result_parts.append("# Code Samples")
559
- for i, block in enumerate(code_blocks[:3]): # Limit to first 3 blocks
553
+ for _i, block in enumerate(code_blocks[:3]): # Limit to first 3 blocks
560
554
  if len("\n".join(result_parts)) + len(block) < max_chars * 0.8:
561
555
  result_parts.append(block)
562
556
 
@@ -671,20 +665,17 @@ class DocumentSummarizerTool(BaseToolAdapter):
671
665
  summary = self._process_chunks(
672
666
  content, mode, max_chars_per_chunk, preserve_code
673
667
  )
668
+ # Process entire file
669
+ elif mode == "brief":
670
+ summary = self._summarize_brief(content, max_chars)
671
+ elif mode == "detailed":
672
+ summary = self._summarize_detailed(content, max_chars)
673
+ elif mode == "key_points":
674
+ summary = self._summarize_key_points(content, max_chars)
675
+ elif mode == "technical":
676
+ summary = self._summarize_technical(content, max_chars, preserve_code)
674
677
  else:
675
- # Process entire file
676
- if mode == "brief":
677
- summary = self._summarize_brief(content, max_chars)
678
- elif mode == "detailed":
679
- summary = self._summarize_detailed(content, max_chars)
680
- elif mode == "key_points":
681
- summary = self._summarize_key_points(content, max_chars)
682
- elif mode == "technical":
683
- summary = self._summarize_technical(
684
- content, max_chars, preserve_code
685
- )
686
- else:
687
- summary = self._summarize_brief(content, max_chars)
678
+ summary = self._summarize_brief(content, max_chars)
688
679
 
689
680
  # Calculate metrics
690
681
  summary_size = len(summary)
@@ -747,7 +738,7 @@ class DocumentSummarizerTool(BaseToolAdapter):
747
738
 
748
739
  return MCPToolResult(
749
740
  success=False,
750
- error=f"Document summarizer failed: {str(e)}",
741
+ error=f"Document summarizer failed: {e!s}",
751
742
  execution_time=execution_time,
752
743
  metadata={
753
744
  "tool": "document_summarizer",