claude-mpm 4.1.1__py3-none-any.whl → 4.1.3__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 (389) 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/engineer.json +33 -11
  18. claude_mpm/agents/templates/imagemagick.json +256 -0
  19. claude_mpm/agents/templates/qa.json +41 -2
  20. claude_mpm/agents/templates/ticketing.json +5 -5
  21. claude_mpm/agents/templates/web_qa.json +50 -2
  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 +648 -1098
  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 +339 -967
  39. claude_mpm/cli/commands/monitor.py +117 -88
  40. claude_mpm/cli/commands/run.py +233 -542
  41. claude_mpm/cli/commands/socketio_monitor.py +17 -19
  42. claude_mpm/cli/commands/tickets.py +92 -92
  43. claude_mpm/cli/parser.py +1 -5
  44. claude_mpm/cli/parsers/__init__.py +1 -1
  45. claude_mpm/cli/parsers/agent_manager_parser.py +50 -98
  46. claude_mpm/cli/parsers/agents_parser.py +2 -3
  47. claude_mpm/cli/parsers/base_parser.py +7 -5
  48. claude_mpm/cli/parsers/mcp_parser.py +4 -2
  49. claude_mpm/cli/parsers/monitor_parser.py +26 -18
  50. claude_mpm/cli/shared/__init__.py +10 -10
  51. claude_mpm/cli/shared/argument_patterns.py +57 -71
  52. claude_mpm/cli/shared/base_command.py +61 -53
  53. claude_mpm/cli/shared/error_handling.py +62 -58
  54. claude_mpm/cli/shared/output_formatters.py +78 -77
  55. claude_mpm/cli/startup_logging.py +280 -172
  56. claude_mpm/cli/utils.py +10 -11
  57. claude_mpm/cli_module/__init__.py +1 -1
  58. claude_mpm/cli_module/args.py +1 -1
  59. claude_mpm/cli_module/migration_example.py +5 -5
  60. claude_mpm/config/__init__.py +9 -9
  61. claude_mpm/config/agent_config.py +15 -14
  62. claude_mpm/config/experimental_features.py +4 -4
  63. claude_mpm/config/paths.py +0 -1
  64. claude_mpm/config/socketio_config.py +5 -6
  65. claude_mpm/constants.py +1 -2
  66. claude_mpm/core/__init__.py +8 -8
  67. claude_mpm/core/agent_name_normalizer.py +1 -1
  68. claude_mpm/core/agent_registry.py +22 -29
  69. claude_mpm/core/agent_session_manager.py +3 -3
  70. claude_mpm/core/base_service.py +7 -15
  71. claude_mpm/core/cache.py +4 -6
  72. claude_mpm/core/claude_runner.py +85 -113
  73. claude_mpm/core/config.py +43 -28
  74. claude_mpm/core/config_aliases.py +0 -9
  75. claude_mpm/core/config_constants.py +52 -30
  76. claude_mpm/core/constants.py +0 -1
  77. claude_mpm/core/container.py +18 -27
  78. claude_mpm/core/exceptions.py +2 -2
  79. claude_mpm/core/factories.py +10 -12
  80. claude_mpm/core/framework_loader.py +500 -680
  81. claude_mpm/core/hook_manager.py +26 -22
  82. claude_mpm/core/hook_performance_config.py +58 -47
  83. claude_mpm/core/injectable_service.py +1 -1
  84. claude_mpm/core/interactive_session.py +61 -152
  85. claude_mpm/core/interfaces.py +1 -100
  86. claude_mpm/core/lazy.py +5 -5
  87. claude_mpm/core/log_manager.py +587 -0
  88. claude_mpm/core/logger.py +125 -8
  89. claude_mpm/core/logging_config.py +15 -17
  90. claude_mpm/core/minimal_framework_loader.py +5 -8
  91. claude_mpm/core/oneshot_session.py +15 -33
  92. claude_mpm/core/optimized_agent_loader.py +4 -6
  93. claude_mpm/core/optimized_startup.py +2 -1
  94. claude_mpm/core/output_style_manager.py +147 -106
  95. claude_mpm/core/pm_hook_interceptor.py +0 -1
  96. claude_mpm/core/service_registry.py +11 -8
  97. claude_mpm/core/session_manager.py +1 -2
  98. claude_mpm/core/shared/__init__.py +1 -1
  99. claude_mpm/core/shared/config_loader.py +101 -97
  100. claude_mpm/core/shared/path_resolver.py +72 -68
  101. claude_mpm/core/shared/singleton_manager.py +56 -50
  102. claude_mpm/core/socketio_pool.py +26 -6
  103. claude_mpm/core/tool_access_control.py +4 -5
  104. claude_mpm/core/typing_utils.py +50 -59
  105. claude_mpm/core/unified_agent_registry.py +14 -19
  106. claude_mpm/core/unified_config.py +4 -6
  107. claude_mpm/core/unified_paths.py +197 -109
  108. claude_mpm/dashboard/open_dashboard.py +2 -4
  109. claude_mpm/experimental/cli_enhancements.py +51 -36
  110. claude_mpm/generators/agent_profile_generator.py +2 -4
  111. claude_mpm/hooks/base_hook.py +1 -2
  112. claude_mpm/hooks/claude_hooks/connection_pool.py +72 -26
  113. claude_mpm/hooks/claude_hooks/event_handlers.py +99 -154
  114. claude_mpm/hooks/claude_hooks/hook_handler.py +110 -720
  115. claude_mpm/hooks/claude_hooks/hook_handler_eventbus.py +104 -77
  116. claude_mpm/hooks/claude_hooks/hook_handler_original.py +1040 -0
  117. claude_mpm/hooks/claude_hooks/hook_handler_refactored.py +347 -0
  118. claude_mpm/hooks/claude_hooks/memory_integration.py +2 -4
  119. claude_mpm/hooks/claude_hooks/response_tracking.py +15 -11
  120. claude_mpm/hooks/claude_hooks/services/__init__.py +13 -0
  121. claude_mpm/hooks/claude_hooks/services/connection_manager.py +190 -0
  122. claude_mpm/hooks/claude_hooks/services/duplicate_detector.py +106 -0
  123. claude_mpm/hooks/claude_hooks/services/state_manager.py +282 -0
  124. claude_mpm/hooks/claude_hooks/services/subagent_processor.py +374 -0
  125. claude_mpm/hooks/claude_hooks/tool_analysis.py +12 -18
  126. claude_mpm/hooks/memory_integration_hook.py +5 -5
  127. claude_mpm/hooks/tool_call_interceptor.py +1 -1
  128. claude_mpm/hooks/validation_hooks.py +4 -4
  129. claude_mpm/init.py +4 -9
  130. claude_mpm/models/__init__.py +2 -2
  131. claude_mpm/models/agent_session.py +11 -14
  132. claude_mpm/scripts/mcp_server.py +20 -11
  133. claude_mpm/scripts/mcp_wrapper.py +5 -5
  134. claude_mpm/scripts/mpm_doctor.py +321 -0
  135. claude_mpm/scripts/socketio_daemon.py +28 -25
  136. claude_mpm/scripts/socketio_daemon_hardened.py +298 -258
  137. claude_mpm/scripts/socketio_server_manager.py +116 -95
  138. claude_mpm/services/__init__.py +49 -49
  139. claude_mpm/services/agent_capabilities_service.py +12 -18
  140. claude_mpm/services/agents/__init__.py +22 -22
  141. claude_mpm/services/agents/agent_builder.py +140 -119
  142. claude_mpm/services/agents/deployment/__init__.py +3 -3
  143. claude_mpm/services/agents/deployment/agent_config_provider.py +9 -9
  144. claude_mpm/services/agents/deployment/agent_configuration_manager.py +19 -20
  145. claude_mpm/services/agents/deployment/agent_definition_factory.py +1 -5
  146. claude_mpm/services/agents/deployment/agent_deployment.py +129 -511
  147. claude_mpm/services/agents/deployment/agent_discovery_service.py +4 -8
  148. claude_mpm/services/agents/deployment/agent_environment_manager.py +2 -7
  149. claude_mpm/services/agents/deployment/agent_filesystem_manager.py +6 -10
  150. claude_mpm/services/agents/deployment/agent_format_converter.py +11 -15
  151. claude_mpm/services/agents/deployment/agent_frontmatter_validator.py +2 -3
  152. claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +5 -5
  153. claude_mpm/services/agents/deployment/agent_metrics_collector.py +13 -19
  154. claude_mpm/services/agents/deployment/agent_restore_handler.py +0 -1
  155. claude_mpm/services/agents/deployment/agent_template_builder.py +26 -35
  156. claude_mpm/services/agents/deployment/agent_validator.py +0 -1
  157. claude_mpm/services/agents/deployment/agent_version_manager.py +7 -9
  158. claude_mpm/services/agents/deployment/agent_versioning.py +3 -3
  159. claude_mpm/services/agents/deployment/agents_directory_resolver.py +6 -7
  160. claude_mpm/services/agents/deployment/async_agent_deployment.py +51 -38
  161. claude_mpm/services/agents/deployment/base_agent_locator.py +132 -0
  162. claude_mpm/services/agents/deployment/config/__init__.py +1 -1
  163. claude_mpm/services/agents/deployment/config/deployment_config.py +7 -8
  164. claude_mpm/services/agents/deployment/deployment_results_manager.py +185 -0
  165. claude_mpm/services/agents/deployment/deployment_type_detector.py +1 -1
  166. claude_mpm/services/agents/deployment/deployment_wrapper.py +18 -18
  167. claude_mpm/services/agents/deployment/facade/__init__.py +1 -1
  168. claude_mpm/services/agents/deployment/facade/deployment_executor.py +0 -3
  169. claude_mpm/services/agents/deployment/facade/deployment_facade.py +3 -4
  170. claude_mpm/services/agents/deployment/interface_adapter.py +5 -7
  171. claude_mpm/services/agents/deployment/multi_source_deployment_service.py +345 -276
  172. claude_mpm/services/agents/deployment/pipeline/__init__.py +2 -2
  173. claude_mpm/services/agents/deployment/pipeline/pipeline_builder.py +1 -1
  174. claude_mpm/services/agents/deployment/pipeline/pipeline_context.py +6 -4
  175. claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +3 -3
  176. claude_mpm/services/agents/deployment/pipeline/steps/__init__.py +2 -2
  177. claude_mpm/services/agents/deployment/pipeline/steps/agent_processing_step.py +14 -13
  178. claude_mpm/services/agents/deployment/pipeline/steps/base_step.py +0 -1
  179. claude_mpm/services/agents/deployment/pipeline/steps/configuration_step.py +1 -1
  180. claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +8 -9
  181. claude_mpm/services/agents/deployment/pipeline/steps/validation_step.py +1 -1
  182. claude_mpm/services/agents/deployment/processors/__init__.py +1 -1
  183. claude_mpm/services/agents/deployment/processors/agent_processor.py +20 -16
  184. claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +5 -12
  185. claude_mpm/services/agents/deployment/results/__init__.py +1 -1
  186. claude_mpm/services/agents/deployment/results/deployment_result_builder.py +1 -1
  187. claude_mpm/services/agents/deployment/single_agent_deployer.py +315 -0
  188. claude_mpm/services/agents/deployment/strategies/__init__.py +2 -2
  189. claude_mpm/services/agents/deployment/strategies/base_strategy.py +1 -7
  190. claude_mpm/services/agents/deployment/strategies/project_strategy.py +1 -4
  191. claude_mpm/services/agents/deployment/strategies/system_strategy.py +2 -3
  192. claude_mpm/services/agents/deployment/strategies/user_strategy.py +3 -7
  193. claude_mpm/services/agents/deployment/validation/__init__.py +1 -1
  194. claude_mpm/services/agents/deployment/validation/agent_validator.py +1 -1
  195. claude_mpm/services/agents/deployment/validation/template_validator.py +2 -2
  196. claude_mpm/services/agents/deployment/validation/validation_result.py +2 -6
  197. claude_mpm/services/agents/loading/__init__.py +1 -1
  198. claude_mpm/services/agents/loading/agent_profile_loader.py +6 -12
  199. claude_mpm/services/agents/loading/base_agent_manager.py +5 -5
  200. claude_mpm/services/agents/loading/framework_agent_loader.py +2 -4
  201. claude_mpm/services/agents/management/__init__.py +1 -1
  202. claude_mpm/services/agents/management/agent_capabilities_generator.py +1 -3
  203. claude_mpm/services/agents/management/agent_management_service.py +5 -9
  204. claude_mpm/services/agents/memory/__init__.py +4 -4
  205. claude_mpm/services/agents/memory/agent_memory_manager.py +157 -503
  206. claude_mpm/services/agents/memory/agent_persistence_service.py +0 -2
  207. claude_mpm/services/agents/memory/content_manager.py +44 -38
  208. claude_mpm/services/agents/memory/memory_categorization_service.py +165 -0
  209. claude_mpm/services/agents/memory/memory_file_service.py +103 -0
  210. claude_mpm/services/agents/memory/memory_format_service.py +201 -0
  211. claude_mpm/services/agents/memory/memory_limits_service.py +99 -0
  212. claude_mpm/services/agents/memory/template_generator.py +4 -6
  213. claude_mpm/services/agents/registry/__init__.py +11 -7
  214. claude_mpm/services/agents/registry/deployed_agent_discovery.py +30 -27
  215. claude_mpm/services/agents/registry/modification_tracker.py +3 -6
  216. claude_mpm/services/async_session_logger.py +1 -2
  217. claude_mpm/services/claude_session_logger.py +1 -2
  218. claude_mpm/services/cli/__init__.py +18 -0
  219. claude_mpm/services/cli/agent_cleanup_service.py +407 -0
  220. claude_mpm/services/cli/agent_dependency_service.py +395 -0
  221. claude_mpm/services/cli/agent_listing_service.py +463 -0
  222. claude_mpm/services/cli/agent_output_formatter.py +605 -0
  223. claude_mpm/services/cli/agent_validation_service.py +589 -0
  224. claude_mpm/services/cli/dashboard_launcher.py +424 -0
  225. claude_mpm/services/cli/memory_crud_service.py +617 -0
  226. claude_mpm/services/cli/memory_output_formatter.py +604 -0
  227. claude_mpm/services/cli/session_manager.py +513 -0
  228. claude_mpm/services/cli/socketio_manager.py +498 -0
  229. claude_mpm/services/cli/startup_checker.py +370 -0
  230. claude_mpm/services/command_deployment_service.py +173 -0
  231. claude_mpm/services/command_handler_service.py +20 -22
  232. claude_mpm/services/core/__init__.py +25 -25
  233. claude_mpm/services/core/base.py +0 -5
  234. claude_mpm/services/core/cache_manager.py +311 -0
  235. claude_mpm/services/core/interfaces/__init__.py +32 -32
  236. claude_mpm/services/core/interfaces/agent.py +0 -21
  237. claude_mpm/services/core/interfaces/communication.py +0 -27
  238. claude_mpm/services/core/interfaces/infrastructure.py +0 -56
  239. claude_mpm/services/core/interfaces/service.py +0 -29
  240. claude_mpm/services/core/memory_manager.py +637 -0
  241. claude_mpm/services/core/path_resolver.py +498 -0
  242. claude_mpm/services/core/service_container.py +520 -0
  243. claude_mpm/services/core/service_interfaces.py +436 -0
  244. claude_mpm/services/diagnostics/__init__.py +1 -1
  245. claude_mpm/services/diagnostics/checks/__init__.py +6 -6
  246. claude_mpm/services/diagnostics/checks/agent_check.py +152 -97
  247. claude_mpm/services/diagnostics/checks/base_check.py +12 -16
  248. claude_mpm/services/diagnostics/checks/claude_desktop_check.py +84 -81
  249. claude_mpm/services/diagnostics/checks/common_issues_check.py +99 -91
  250. claude_mpm/services/diagnostics/checks/configuration_check.py +82 -77
  251. claude_mpm/services/diagnostics/checks/filesystem_check.py +67 -68
  252. claude_mpm/services/diagnostics/checks/installation_check.py +254 -94
  253. claude_mpm/services/diagnostics/checks/mcp_check.py +90 -88
  254. claude_mpm/services/diagnostics/checks/monitor_check.py +75 -76
  255. claude_mpm/services/diagnostics/checks/startup_log_check.py +67 -73
  256. claude_mpm/services/diagnostics/diagnostic_runner.py +67 -59
  257. claude_mpm/services/diagnostics/doctor_reporter.py +107 -70
  258. claude_mpm/services/diagnostics/models.py +21 -19
  259. claude_mpm/services/event_aggregator.py +10 -17
  260. claude_mpm/services/event_bus/__init__.py +1 -1
  261. claude_mpm/services/event_bus/config.py +54 -35
  262. claude_mpm/services/event_bus/event_bus.py +76 -71
  263. claude_mpm/services/event_bus/relay.py +74 -64
  264. claude_mpm/services/events/__init__.py +11 -11
  265. claude_mpm/services/events/consumers/__init__.py +3 -3
  266. claude_mpm/services/events/consumers/dead_letter.py +71 -63
  267. claude_mpm/services/events/consumers/logging.py +39 -37
  268. claude_mpm/services/events/consumers/metrics.py +56 -57
  269. claude_mpm/services/events/consumers/socketio.py +82 -81
  270. claude_mpm/services/events/core.py +110 -99
  271. claude_mpm/services/events/interfaces.py +56 -72
  272. claude_mpm/services/events/producers/__init__.py +1 -1
  273. claude_mpm/services/events/producers/hook.py +38 -38
  274. claude_mpm/services/events/producers/system.py +46 -44
  275. claude_mpm/services/exceptions.py +81 -80
  276. claude_mpm/services/framework_claude_md_generator/__init__.py +2 -4
  277. claude_mpm/services/framework_claude_md_generator/content_assembler.py +3 -5
  278. claude_mpm/services/framework_claude_md_generator/content_validator.py +1 -1
  279. claude_mpm/services/framework_claude_md_generator/deployment_manager.py +4 -4
  280. claude_mpm/services/framework_claude_md_generator/section_generators/__init__.py +0 -1
  281. claude_mpm/services/framework_claude_md_generator/section_generators/agents.py +0 -2
  282. claude_mpm/services/framework_claude_md_generator/version_manager.py +4 -5
  283. claude_mpm/services/hook_service.py +6 -9
  284. claude_mpm/services/infrastructure/__init__.py +1 -1
  285. claude_mpm/services/infrastructure/context_preservation.py +8 -12
  286. claude_mpm/services/infrastructure/monitoring.py +21 -23
  287. claude_mpm/services/mcp_gateway/__init__.py +37 -37
  288. claude_mpm/services/mcp_gateway/auto_configure.py +95 -103
  289. claude_mpm/services/mcp_gateway/config/__init__.py +1 -1
  290. claude_mpm/services/mcp_gateway/config/config_loader.py +23 -25
  291. claude_mpm/services/mcp_gateway/config/config_schema.py +5 -5
  292. claude_mpm/services/mcp_gateway/config/configuration.py +9 -6
  293. claude_mpm/services/mcp_gateway/core/__init__.py +10 -10
  294. claude_mpm/services/mcp_gateway/core/base.py +0 -3
  295. claude_mpm/services/mcp_gateway/core/interfaces.py +1 -38
  296. claude_mpm/services/mcp_gateway/core/process_pool.py +99 -93
  297. claude_mpm/services/mcp_gateway/core/singleton_manager.py +65 -62
  298. claude_mpm/services/mcp_gateway/core/startup_verification.py +75 -74
  299. claude_mpm/services/mcp_gateway/main.py +2 -1
  300. claude_mpm/services/mcp_gateway/registry/service_registry.py +5 -8
  301. claude_mpm/services/mcp_gateway/registry/tool_registry.py +1 -1
  302. claude_mpm/services/mcp_gateway/server/__init__.py +1 -1
  303. claude_mpm/services/mcp_gateway/server/mcp_gateway.py +12 -19
  304. claude_mpm/services/mcp_gateway/server/stdio_handler.py +4 -3
  305. claude_mpm/services/mcp_gateway/server/stdio_server.py +79 -71
  306. claude_mpm/services/mcp_gateway/tools/__init__.py +2 -2
  307. claude_mpm/services/mcp_gateway/tools/base_adapter.py +5 -6
  308. claude_mpm/services/mcp_gateway/tools/document_summarizer.py +13 -22
  309. claude_mpm/services/mcp_gateway/tools/health_check_tool.py +79 -78
  310. claude_mpm/services/mcp_gateway/tools/hello_world.py +12 -14
  311. claude_mpm/services/mcp_gateway/tools/ticket_tools.py +42 -49
  312. claude_mpm/services/mcp_gateway/tools/unified_ticket_tool.py +51 -55
  313. claude_mpm/services/memory/__init__.py +3 -3
  314. claude_mpm/services/memory/builder.py +3 -6
  315. claude_mpm/services/memory/cache/__init__.py +1 -1
  316. claude_mpm/services/memory/cache/shared_prompt_cache.py +3 -5
  317. claude_mpm/services/memory/cache/simple_cache.py +1 -1
  318. claude_mpm/services/memory/indexed_memory.py +5 -7
  319. claude_mpm/services/memory/optimizer.py +7 -10
  320. claude_mpm/services/memory/router.py +8 -9
  321. claude_mpm/services/memory_hook_service.py +48 -34
  322. claude_mpm/services/monitor_build_service.py +77 -73
  323. claude_mpm/services/port_manager.py +130 -108
  324. claude_mpm/services/project/analyzer.py +12 -10
  325. claude_mpm/services/project/registry.py +11 -11
  326. claude_mpm/services/recovery_manager.py +10 -19
  327. claude_mpm/services/response_tracker.py +0 -1
  328. claude_mpm/services/runner_configuration_service.py +19 -20
  329. claude_mpm/services/session_management_service.py +7 -11
  330. claude_mpm/services/shared/__init__.py +1 -1
  331. claude_mpm/services/shared/async_service_base.py +58 -50
  332. claude_mpm/services/shared/config_service_base.py +73 -67
  333. claude_mpm/services/shared/lifecycle_service_base.py +82 -78
  334. claude_mpm/services/shared/manager_base.py +94 -82
  335. claude_mpm/services/shared/service_factory.py +96 -98
  336. claude_mpm/services/socketio/__init__.py +3 -3
  337. claude_mpm/services/socketio/client_proxy.py +5 -5
  338. claude_mpm/services/socketio/event_normalizer.py +199 -181
  339. claude_mpm/services/socketio/handlers/__init__.py +3 -3
  340. claude_mpm/services/socketio/handlers/base.py +5 -4
  341. claude_mpm/services/socketio/handlers/connection.py +163 -136
  342. claude_mpm/services/socketio/handlers/file.py +13 -14
  343. claude_mpm/services/socketio/handlers/git.py +12 -7
  344. claude_mpm/services/socketio/handlers/hook.py +49 -44
  345. claude_mpm/services/socketio/handlers/memory.py +0 -1
  346. claude_mpm/services/socketio/handlers/project.py +0 -1
  347. claude_mpm/services/socketio/handlers/registry.py +37 -19
  348. claude_mpm/services/socketio/migration_utils.py +98 -84
  349. claude_mpm/services/socketio/server/__init__.py +1 -1
  350. claude_mpm/services/socketio/server/broadcaster.py +81 -87
  351. claude_mpm/services/socketio/server/core.py +65 -54
  352. claude_mpm/services/socketio/server/eventbus_integration.py +95 -56
  353. claude_mpm/services/socketio/server/main.py +64 -38
  354. claude_mpm/services/socketio_client_manager.py +10 -12
  355. claude_mpm/services/subprocess_launcher_service.py +4 -7
  356. claude_mpm/services/system_instructions_service.py +13 -14
  357. claude_mpm/services/ticket_manager.py +2 -2
  358. claude_mpm/services/utility_service.py +5 -13
  359. claude_mpm/services/version_control/__init__.py +16 -16
  360. claude_mpm/services/version_control/branch_strategy.py +5 -8
  361. claude_mpm/services/version_control/conflict_resolution.py +9 -23
  362. claude_mpm/services/version_control/git_operations.py +5 -7
  363. claude_mpm/services/version_control/semantic_versioning.py +16 -17
  364. claude_mpm/services/version_control/version_parser.py +13 -18
  365. claude_mpm/services/version_service.py +10 -11
  366. claude_mpm/storage/__init__.py +1 -1
  367. claude_mpm/storage/state_storage.py +22 -28
  368. claude_mpm/utils/__init__.py +6 -6
  369. claude_mpm/utils/agent_dependency_loader.py +47 -33
  370. claude_mpm/utils/config_manager.py +11 -14
  371. claude_mpm/utils/dependency_cache.py +1 -1
  372. claude_mpm/utils/dependency_manager.py +13 -17
  373. claude_mpm/utils/dependency_strategies.py +8 -10
  374. claude_mpm/utils/environment_context.py +3 -9
  375. claude_mpm/utils/error_handler.py +3 -13
  376. claude_mpm/utils/file_utils.py +1 -1
  377. claude_mpm/utils/path_operations.py +8 -12
  378. claude_mpm/utils/robust_installer.py +110 -33
  379. claude_mpm/utils/subprocess_utils.py +5 -6
  380. claude_mpm/validation/agent_validator.py +3 -6
  381. claude_mpm/validation/frontmatter_validator.py +1 -1
  382. {claude_mpm-4.1.1.dist-info → claude_mpm-4.1.3.dist-info}/METADATA +1 -1
  383. claude_mpm-4.1.3.dist-info/RECORD +528 -0
  384. claude_mpm/cli/commands/run_config_checker.py +0 -160
  385. claude_mpm-4.1.1.dist-info/RECORD +0 -494
  386. {claude_mpm-4.1.1.dist-info → claude_mpm-4.1.3.dist-info}/WHEEL +0 -0
  387. {claude_mpm-4.1.1.dist-info → claude_mpm-4.1.3.dist-info}/entry_points.txt +0 -0
  388. {claude_mpm-4.1.1.dist-info → claude_mpm-4.1.3.dist-info}/licenses/LICENSE +0 -0
  389. {claude_mpm-4.1.1.dist-info → claude_mpm-4.1.3.dist-info}/top_level.txt +0 -0
@@ -11,13 +11,11 @@ This module provides conflict resolution management including:
11
11
  5. Resolution validation
12
12
  """
13
13
 
14
- import difflib
15
14
  import logging
16
15
  import re
17
16
  from dataclasses import dataclass, field
18
- from datetime import datetime
19
17
  from enum import Enum
20
- from typing import Any, Dict, List, Optional, Tuple, Union
18
+ from typing import Any, Dict, List, Optional
21
19
 
22
20
 
23
21
  class ConflictType(Enum):
@@ -248,11 +246,7 @@ class ConflictResolutionManager:
248
246
 
249
247
  conflicted_files = []
250
248
  for line in result.stdout.strip().split("\n"):
251
- if line.strip() and (
252
- line.startswith("UU")
253
- or line.startswith("AA")
254
- or line.startswith("DD")
255
- ):
249
+ if line.strip() and (line.startswith(("UU", "AA", "DD"))):
256
250
  # Extract filename
257
251
  filename = line[3:].strip()
258
252
  conflicted_files.append(filename)
@@ -280,7 +274,7 @@ class ConflictResolutionManager:
280
274
  )
281
275
 
282
276
  try:
283
- with open(full_path, "r", encoding="utf-8") as f:
277
+ with open(full_path, encoding="utf-8") as f:
284
278
  content = f.read()
285
279
 
286
280
  # Parse conflict markers
@@ -404,11 +398,7 @@ class ConflictResolutionManager:
404
398
  return False
405
399
 
406
400
  # Check if all conflicts are simple
407
- for marker in markers:
408
- if not self._is_simple_conflict(marker):
409
- return False
410
-
411
- return True
401
+ return all(self._is_simple_conflict(marker) for marker in markers)
412
402
 
413
403
  def _is_simple_conflict(self, marker: ConflictMarker) -> bool:
414
404
  """Check if a conflict marker represents a simple conflict."""
@@ -428,10 +418,7 @@ class ConflictResolutionManager:
428
418
  return True
429
419
 
430
420
  # Check if differences are only imports
431
- if self._only_import_differences(ours_lines, theirs_lines):
432
- return True
433
-
434
- return False
421
+ return bool(self._only_import_differences(ours_lines, theirs_lines))
435
422
 
436
423
  def _only_whitespace_differences(self, ours: List[str], theirs: List[str]) -> bool:
437
424
  """Check if differences are only whitespace."""
@@ -444,7 +431,7 @@ class ConflictResolutionManager:
444
431
  # This is a simplified check
445
432
  for line in ours + theirs:
446
433
  stripped = line.strip()
447
- if stripped and not (stripped.startswith("#") or stripped.startswith("//")):
434
+ if stripped and not (stripped.startswith(("#", "//"))):
448
435
  return False
449
436
  return True
450
437
 
@@ -516,10 +503,9 @@ class ConflictResolutionManager:
516
503
 
517
504
  if auto_ratio > 0.8:
518
505
  return "simple"
519
- elif auto_ratio > 0.5:
506
+ if auto_ratio > 0.5:
520
507
  return "moderate"
521
- else:
522
- return "complex"
508
+ return "complex"
523
509
 
524
510
  def _estimate_resolution_time(self, file_conflicts: List[FileConflict]) -> int:
525
511
  """Estimate resolution time in minutes."""
@@ -601,7 +587,7 @@ class ConflictResolutionManager:
601
587
 
602
588
  try:
603
589
  # Read current content
604
- with open(file_path, "r", encoding="utf-8") as f:
590
+ with open(file_path, encoding="utf-8") as f:
605
591
  content = f.read()
606
592
 
607
593
  # Apply resolution strategy
@@ -13,11 +13,10 @@ This module provides comprehensive Git operation management including:
13
13
 
14
14
  import logging
15
15
  import os
16
- import re
17
16
  import subprocess
18
17
  from dataclasses import dataclass, field
19
18
  from datetime import datetime
20
- from typing import Any, Dict, List, Optional, Tuple
19
+ from typing import Any, Dict, List, Optional
21
20
 
22
21
 
23
22
  @dataclass
@@ -128,7 +127,7 @@ class GitOperationsManager:
128
127
  Raises:
129
128
  GitOperationError: If command fails and check=True
130
129
  """
131
- cmd = ["git"] + args
130
+ cmd = ["git", *args]
132
131
  cwd = cwd or str(self.project_root)
133
132
 
134
133
  try:
@@ -444,7 +443,7 @@ class GitOperationsManager:
444
443
  return GitOperationResult(
445
444
  success=False,
446
445
  operation="switch_branch",
447
- message=f"Cannot switch branch: uncommitted changes exist",
446
+ message="Cannot switch branch: uncommitted changes exist",
448
447
  error=f"Modified files: {', '.join(modified_files)}",
449
448
  branch_before=current_branch,
450
449
  branch_after=current_branch,
@@ -599,10 +598,9 @@ class GitOperationsManager:
599
598
  conflicted_files = []
600
599
  if has_conflicts:
601
600
  lines = result.stdout.split("\n")
602
- current_file = None
603
601
 
604
602
  for line in lines:
605
- if line.startswith("+++") or line.startswith("---"):
603
+ if line.startswith(("+++", "---")):
606
604
  # Extract filename
607
605
  parts = line.split("\t")
608
606
  if len(parts) > 1:
@@ -775,7 +773,7 @@ class GitOperationsManager:
775
773
  for line in result.stdout.strip().split("\n"):
776
774
  branch = line.strip().lstrip("* ").strip()
777
775
  # Skip target branch and current branch
778
- if branch and branch != target_branch and branch != current_branch:
776
+ if branch and branch not in (target_branch, current_branch):
779
777
  merged_branches.append(branch)
780
778
 
781
779
  # Delete merged branches
@@ -39,13 +39,12 @@ Change Analysis:
39
39
  - Confidence scoring for version bump suggestions
40
40
  """
41
41
 
42
- import json
43
42
  import logging
44
43
  import re
45
44
  from dataclasses import dataclass, field
46
45
  from datetime import datetime
47
46
  from enum import Enum
48
- from typing import Any, Dict, List, Optional, Tuple, Union
47
+ from typing import Dict, List, Optional, Tuple
49
48
 
50
49
  from ...utils.config_manager import ConfigurationManager
51
50
 
@@ -167,13 +166,13 @@ class SemanticVersion:
167
166
  if bump_type == VersionBumpType.MAJOR:
168
167
  # Breaking changes - reset minor and patch
169
168
  return SemanticVersion(self.major + 1, 0, 0)
170
- elif bump_type == VersionBumpType.MINOR:
169
+ if bump_type == VersionBumpType.MINOR:
171
170
  # New features - reset patch only
172
171
  return SemanticVersion(self.major, self.minor + 1, 0)
173
- elif bump_type == VersionBumpType.PATCH:
172
+ if bump_type == VersionBumpType.PATCH:
174
173
  # Bug fixes - increment patch only
175
174
  return SemanticVersion(self.major, self.minor, self.patch + 1)
176
- elif bump_type == VersionBumpType.PRERELEASE:
175
+ if bump_type == VersionBumpType.PRERELEASE:
177
176
  if self.prerelease:
178
177
  # Increment existing prerelease number
179
178
  match = re.match(r"(.+?)(\d+)$", self.prerelease)
@@ -423,7 +422,7 @@ class SemanticVersionManager:
423
422
  # Try different locations for version
424
423
  if "project" in data and "version" in data["project"]:
425
424
  return data["project"]["version"]
426
- elif (
425
+ if (
427
426
  "tool" in data
428
427
  and "poetry" in data["tool"]
429
428
  and "version" in data["tool"]["poetry"]
@@ -438,7 +437,7 @@ class SemanticVersionManager:
438
437
  def _parse_toml_version_regex(self, file_path: Path) -> Optional[str]:
439
438
  """Parse version from TOML file using regex."""
440
439
  try:
441
- with open(file_path, "r") as f:
440
+ with open(file_path) as f:
442
441
  content = f.read()
443
442
 
444
443
  # Look for version = "x.y.z" pattern
@@ -464,7 +463,7 @@ class SemanticVersionManager:
464
463
  def _parse_version_file(self, file_path: Path) -> Optional[str]:
465
464
  """Parse version from simple version file."""
466
465
  try:
467
- with open(file_path, "r") as f:
466
+ with open(file_path) as f:
468
467
  return f.read().strip()
469
468
  except Exception:
470
469
  return None
@@ -472,7 +471,7 @@ class SemanticVersionManager:
472
471
  def _parse_pom_xml_version(self, file_path: Path) -> Optional[str]:
473
472
  """Parse version from Maven pom.xml."""
474
473
  try:
475
- with open(file_path, "r") as f:
474
+ with open(file_path) as f:
476
475
  content = f.read()
477
476
 
478
477
  # Simple regex to find version in pom.xml
@@ -645,11 +644,11 @@ class SemanticVersionManager:
645
644
  try:
646
645
  if filename == "package.json":
647
646
  return self._update_package_json_version(file_path, new_version)
648
- elif filename in ["pyproject.toml", "Cargo.toml"]:
647
+ if filename in ["pyproject.toml", "Cargo.toml"]:
649
648
  return self._update_toml_version(file_path, new_version)
650
- elif filename in ["VERSION", "version.txt"]:
649
+ if filename in ["VERSION", "version.txt"]:
651
650
  return self._update_simple_version_file(file_path, new_version)
652
- elif filename == "pom.xml":
651
+ if filename == "pom.xml":
653
652
  return self._update_pom_xml_version(file_path, new_version)
654
653
 
655
654
  return False
@@ -674,7 +673,7 @@ class SemanticVersionManager:
674
673
  def _update_toml_version(self, file_path: Path, new_version: str) -> bool:
675
674
  """Update version in TOML file."""
676
675
  try:
677
- with open(file_path, "r") as f:
676
+ with open(file_path) as f:
678
677
  content = f.read()
679
678
 
680
679
  # Replace version field
@@ -713,7 +712,7 @@ class SemanticVersionManager:
713
712
  def _update_pom_xml_version(self, file_path: Path, new_version: str) -> bool:
714
713
  """Update version in Maven pom.xml."""
715
714
  try:
716
- with open(file_path, "r") as f:
715
+ with open(file_path) as f:
717
716
  content = f.read()
718
717
 
719
718
  # Replace first version tag (project version)
@@ -842,7 +841,7 @@ class SemanticVersionManager:
842
841
 
843
842
  # Read existing changelog or create new one
844
843
  if changelog_path.exists():
845
- with open(changelog_path, "r") as f:
844
+ with open(changelog_path) as f:
846
845
  existing_content = f.read()
847
846
 
848
847
  # Insert new entry after title
@@ -851,7 +850,7 @@ class SemanticVersionManager:
851
850
 
852
851
  # Find insertion point (after # Changelog title)
853
852
  for i, line in enumerate(lines):
854
- if line.startswith("# ") or line.startswith("## [Unreleased]"):
853
+ if line.startswith(("# ", "## [Unreleased]")):
855
854
  insert_index = i + 1
856
855
  break
857
856
 
@@ -946,7 +945,7 @@ class SemanticVersionManager:
946
945
  versions = []
947
946
 
948
947
  try:
949
- with open(changelog_path, "r") as f:
948
+ with open(changelog_path) as f:
950
949
  content = f.read()
951
950
 
952
951
  # Find version entries
@@ -15,15 +15,14 @@ from multiple sources with intelligent fallback logic:
15
15
  The system includes caching for performance and validation for data integrity.
16
16
  """
17
17
 
18
+ import contextlib
18
19
  import json
19
20
  import logging
20
21
  import re
21
22
  import subprocess
22
23
  from datetime import datetime, timedelta
23
24
  from functools import lru_cache
24
- from typing import Dict, List, Optional, Tuple, Union
25
-
26
- from claude_mpm.services.version_control.semantic_versioning import SemanticVersion
25
+ from typing import Dict, List, Optional, Tuple
27
26
 
28
27
 
29
28
  class VersionSource:
@@ -73,9 +72,9 @@ class VersionMetadata:
73
72
  return {
74
73
  "version": self.version,
75
74
  "source": self.source,
76
- "release_date": self.release_date.isoformat()
77
- if self.release_date
78
- else None,
75
+ "release_date": (
76
+ self.release_date.isoformat() if self.release_date else None
77
+ ),
79
78
  "commit_hash": self.commit_hash,
80
79
  "author": self.author,
81
80
  "message": self.message,
@@ -213,13 +212,13 @@ class EnhancedVersionParser:
213
212
  """Get version(s) from a specific source."""
214
213
  if source == VersionSource.GIT_TAGS:
215
214
  return self._get_version_from_git(latest_only)
216
- elif source == VersionSource.VERSION_FILE:
215
+ if source == VersionSource.VERSION_FILE:
217
216
  return self._get_version_from_file()
218
- elif source == VersionSource.PACKAGE_JSON:
217
+ if source == VersionSource.PACKAGE_JSON:
219
218
  return self._get_version_from_package_json()
220
- elif source == VersionSource.PYPROJECT_TOML:
219
+ if source == VersionSource.PYPROJECT_TOML:
221
220
  return self._get_version_from_pyproject()
222
- elif source == VersionSource.CHANGELOG:
221
+ if source == VersionSource.CHANGELOG:
223
222
  versions = self._get_versions_from_changelog()
224
223
  return versions[0] if versions else None
225
224
  return None
@@ -228,9 +227,9 @@ class EnhancedVersionParser:
228
227
  """Get all versions from a specific source."""
229
228
  if source == VersionSource.GIT_TAGS:
230
229
  return self._get_all_versions_from_git()
231
- elif source == VersionSource.CHANGELOG:
230
+ if source == VersionSource.CHANGELOG:
232
231
  return self._get_versions_from_changelog()
233
- elif source in [
232
+ if source in [
234
233
  VersionSource.VERSION_FILE,
235
234
  VersionSource.PACKAGE_JSON,
236
235
  VersionSource.PYPROJECT_TOML,
@@ -318,10 +317,8 @@ class EnhancedVersionParser:
318
317
  # Parse date if provided
319
318
  release_date = None
320
319
  if date_str:
321
- try:
320
+ with contextlib.suppress(Exception):
322
321
  release_date = datetime.fromisoformat(date_str.replace(" ", "T"))
323
- except:
324
- pass
325
322
 
326
323
  # Get commit hash for this tag
327
324
  commit_hash = None
@@ -422,10 +419,8 @@ class EnhancedVersionParser:
422
419
  # Parse release date
423
420
  release_date = None
424
421
  if date_str:
425
- try:
422
+ with contextlib.suppress(Exception):
426
423
  release_date = datetime.strptime(date_str, "%Y-%m-%d")
427
- except:
428
- pass
429
424
 
430
425
  # Extract changes for this version
431
426
  changes = self._extract_changelog_changes(
@@ -25,11 +25,9 @@ class VersionService(BaseService, VersionServiceInterface):
25
25
 
26
26
  async def _initialize(self) -> None:
27
27
  """Initialize the service. No special initialization needed."""
28
- pass
29
28
 
30
29
  async def _cleanup(self) -> None:
31
30
  """Cleanup service resources. No cleanup needed."""
32
- pass
33
31
 
34
32
  def get_version(self) -> str:
35
33
  """
@@ -134,12 +132,16 @@ class VersionService(BaseService, VersionServiceInterface):
134
132
  if build_file.exists():
135
133
  build_content = build_file.read_text().strip()
136
134
  build_number = int(build_content)
137
- self.logger.debug(f"Build number obtained from {build_file}: {build_number}")
135
+ self.logger.debug(
136
+ f"Build number obtained from {build_file}: {build_number}"
137
+ )
138
138
  return build_number
139
- except (ValueError, IOError) as e:
139
+ except (OSError, ValueError) as e:
140
140
  self.logger.debug(f"Could not read BUILD_NUMBER from {build_file}: {e}")
141
141
  except Exception as e:
142
- self.logger.debug(f"Unexpected error reading BUILD_NUMBER from {build_file}: {e}")
142
+ self.logger.debug(
143
+ f"Unexpected error reading BUILD_NUMBER from {build_file}: {e}"
144
+ )
143
145
 
144
146
  return None
145
147
 
@@ -162,8 +164,7 @@ class VersionService(BaseService, VersionServiceInterface):
162
164
  if build_number is not None:
163
165
  # UI/logging format with 'v' prefix and dash separator
164
166
  return f"v{version}-build.{build_number}"
165
- else:
166
- return f"v{version}"
167
+ return f"v{version}"
167
168
 
168
169
  def get_base_version(self) -> str:
169
170
  """Get base version without build number.
@@ -222,8 +223,7 @@ class VersionService(BaseService, VersionServiceInterface):
222
223
 
223
224
  if build_number is not None:
224
225
  return f"{base_version}+build.{build_number}"
225
- else:
226
- return base_version
226
+ return base_version
227
227
 
228
228
  # Implementation of abstract methods from VersionServiceInterface
229
229
 
@@ -256,8 +256,7 @@ class VersionService(BaseService, VersionServiceInterface):
256
256
  """
257
257
  if include_build:
258
258
  return self.get_version() # Already includes build number
259
- else:
260
- return self.get_base_version()
259
+ return self.get_base_version()
261
260
 
262
261
  def check_for_updates(self) -> Dict[str, Any]:
263
262
  """Check for available updates.
@@ -6,4 +6,4 @@ with atomic operations and various serialization formats.
6
6
 
7
7
  from .state_storage import StateCache, StateStorage
8
8
 
9
- __all__ = ["StateStorage", "StateCache"]
9
+ __all__ = ["StateCache", "StateStorage"]
@@ -20,12 +20,10 @@ import logging
20
20
  import os
21
21
  import pickle
22
22
  import platform
23
- import shutil
24
23
  import tempfile
25
24
  import time
26
- from contextlib import contextmanager
27
- from datetime import datetime
28
- from typing import Any, BinaryIO, Dict, Optional, TextIO, Union
25
+ from contextlib import contextmanager, suppress
26
+ from typing import Any, Dict, Optional, Tuple, Union
29
27
 
30
28
 
31
29
  class StateStorage:
@@ -76,17 +74,16 @@ class StateStorage:
76
74
  return self._atomic_write(
77
75
  file_path, data, serializer="json", compress=compress
78
76
  )
77
+ # Direct write (not atomic)
78
+ if compress:
79
+ with gzip.open(file_path, "wt", encoding="utf-8") as f:
80
+ json.dump(data, f, indent=2, default=str)
79
81
  else:
80
- # Direct write (not atomic)
81
- if compress:
82
- with gzip.open(file_path, "wt", encoding="utf-8") as f:
83
- json.dump(data, f, indent=2, default=str)
84
- else:
85
- with open(file_path, "w") as f:
86
- json.dump(data, f, indent=2, default=str)
82
+ with open(file_path, "w") as f:
83
+ json.dump(data, f, indent=2, default=str)
87
84
 
88
- self.write_count += 1
89
- return True
85
+ self.write_count += 1
86
+ return True
90
87
 
91
88
  except Exception as e:
92
89
  self.logger.error(f"Failed to write JSON to {file_path}: {e}")
@@ -121,7 +118,7 @@ class StateStorage:
121
118
  with gzip.open(file_path, "rt", encoding="utf-8") as f:
122
119
  data = json.load(f)
123
120
  else:
124
- with open(file_path, "r") as f:
121
+ with open(file_path) as f:
125
122
  data = json.load(f)
126
123
 
127
124
  self.read_count += 1
@@ -157,17 +154,16 @@ class StateStorage:
157
154
  return self._atomic_write(
158
155
  file_path, data, serializer="pickle", compress=compress
159
156
  )
157
+ # Direct write (not atomic)
158
+ if compress:
159
+ with gzip.open(file_path, "wb") as f:
160
+ pickle.dump(data, f, protocol=pickle.HIGHEST_PROTOCOL)
160
161
  else:
161
- # Direct write (not atomic)
162
- if compress:
163
- with gzip.open(file_path, "wb") as f:
164
- pickle.dump(data, f, protocol=pickle.HIGHEST_PROTOCOL)
165
- else:
166
- with open(file_path, "wb") as f:
167
- pickle.dump(data, f, protocol=pickle.HIGHEST_PROTOCOL)
162
+ with open(file_path, "wb") as f:
163
+ pickle.dump(data, f, protocol=pickle.HIGHEST_PROTOCOL)
168
164
 
169
- self.write_count += 1
170
- return True
165
+ self.write_count += 1
166
+ return True
171
167
 
172
168
  except Exception as e:
173
169
  self.logger.error(f"Failed to write pickle to {file_path}: {e}")
@@ -307,7 +303,7 @@ class StateStorage:
307
303
  try:
308
304
  fcntl.flock(f.fileno(), fcntl.LOCK_EX | fcntl.LOCK_NB)
309
305
  break
310
- except IOError:
306
+ except OSError:
311
307
  if attempt == max_attempts - 1:
312
308
  raise
313
309
  time.sleep(0.1)
@@ -316,10 +312,8 @@ class StateStorage:
316
312
 
317
313
  finally:
318
314
  if f:
319
- try:
315
+ with suppress(Exception):
320
316
  fcntl.flock(f.fileno(), fcntl.LOCK_UN)
321
- except:
322
- pass
323
317
  f.close()
324
318
 
325
319
  def _add_checksum(self, file_path: Union[str, Path]) -> None:
@@ -364,7 +358,7 @@ class StateStorage:
364
358
  return True # No checksum to verify
365
359
 
366
360
  # Read expected checksum
367
- with open(checksum_path, "r") as f:
361
+ with open(checksum_path) as f:
368
362
  expected = f.read().strip()
369
363
 
370
364
  # Calculate actual checksum
@@ -2,15 +2,15 @@
2
2
 
3
3
  # Delay imports to avoid circular dependencies
4
4
  __all__ = [
5
+ "ConfigurationManager",
6
+ "find_file_upwards",
7
+ "get_framework_root",
5
8
  "get_logger",
6
- "setup_logging",
7
- "safe_import",
8
- "safe_import_multiple",
9
9
  "get_path_manager()",
10
- "get_framework_root",
11
10
  "get_project_root",
12
- "find_file_upwards",
13
- "ConfigurationManager",
14
11
  "load_config",
12
+ "safe_import",
13
+ "safe_import_multiple",
15
14
  "save_config",
15
+ "setup_logging",
16
16
  ]