claude-mpm 3.9.11__py3-none-any.whl → 4.0.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 (419) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/__init__.py +2 -2
  3. claude_mpm/__main__.py +3 -2
  4. claude_mpm/agents/__init__.py +85 -79
  5. claude_mpm/agents/agent_loader.py +464 -1003
  6. claude_mpm/agents/agent_loader_integration.py +45 -45
  7. claude_mpm/agents/agents_metadata.py +29 -30
  8. claude_mpm/agents/async_agent_loader.py +156 -138
  9. claude_mpm/agents/base_agent.json +1 -1
  10. claude_mpm/agents/base_agent_loader.py +179 -151
  11. claude_mpm/agents/frontmatter_validator.py +229 -130
  12. claude_mpm/agents/schema/agent_schema.json +1 -1
  13. claude_mpm/agents/system_agent_config.py +213 -147
  14. claude_mpm/agents/templates/__init__.py +13 -13
  15. claude_mpm/agents/templates/code_analyzer.json +2 -2
  16. claude_mpm/agents/templates/data_engineer.json +1 -1
  17. claude_mpm/agents/templates/documentation.json +23 -11
  18. claude_mpm/agents/templates/engineer.json +22 -6
  19. claude_mpm/agents/templates/memory_manager.json +1 -1
  20. claude_mpm/agents/templates/ops.json +2 -2
  21. claude_mpm/agents/templates/project_organizer.json +1 -1
  22. claude_mpm/agents/templates/qa.json +1 -1
  23. claude_mpm/agents/templates/refactoring_engineer.json +222 -0
  24. claude_mpm/agents/templates/research.json +20 -14
  25. claude_mpm/agents/templates/security.json +1 -1
  26. claude_mpm/agents/templates/ticketing.json +1 -1
  27. claude_mpm/agents/templates/version_control.json +1 -1
  28. claude_mpm/agents/templates/web_qa.json +3 -1
  29. claude_mpm/agents/templates/web_ui.json +2 -2
  30. claude_mpm/cli/__init__.py +79 -51
  31. claude_mpm/cli/__main__.py +3 -2
  32. claude_mpm/cli/commands/__init__.py +20 -20
  33. claude_mpm/cli/commands/agents.py +279 -247
  34. claude_mpm/cli/commands/aggregate.py +138 -157
  35. claude_mpm/cli/commands/cleanup.py +147 -147
  36. claude_mpm/cli/commands/config.py +93 -76
  37. claude_mpm/cli/commands/info.py +17 -16
  38. claude_mpm/cli/commands/mcp.py +140 -905
  39. claude_mpm/cli/commands/mcp_command_router.py +139 -0
  40. claude_mpm/cli/commands/mcp_config_commands.py +20 -0
  41. claude_mpm/cli/commands/mcp_install_commands.py +20 -0
  42. claude_mpm/cli/commands/mcp_server_commands.py +175 -0
  43. claude_mpm/cli/commands/mcp_tool_commands.py +34 -0
  44. claude_mpm/cli/commands/memory.py +239 -203
  45. claude_mpm/cli/commands/monitor.py +203 -81
  46. claude_mpm/cli/commands/run.py +380 -429
  47. claude_mpm/cli/commands/run_config_checker.py +160 -0
  48. claude_mpm/cli/commands/socketio_monitor.py +235 -0
  49. claude_mpm/cli/commands/tickets.py +305 -197
  50. claude_mpm/cli/parser.py +24 -1156
  51. claude_mpm/cli/parsers/__init__.py +29 -0
  52. claude_mpm/cli/parsers/agents_parser.py +136 -0
  53. claude_mpm/cli/parsers/base_parser.py +331 -0
  54. claude_mpm/cli/parsers/config_parser.py +85 -0
  55. claude_mpm/cli/parsers/mcp_parser.py +152 -0
  56. claude_mpm/cli/parsers/memory_parser.py +138 -0
  57. claude_mpm/cli/parsers/monitor_parser.py +104 -0
  58. claude_mpm/cli/parsers/run_parser.py +147 -0
  59. claude_mpm/cli/parsers/tickets_parser.py +203 -0
  60. claude_mpm/cli/ticket_cli.py +7 -3
  61. claude_mpm/cli/utils.py +55 -37
  62. claude_mpm/cli_module/__init__.py +6 -6
  63. claude_mpm/cli_module/args.py +188 -140
  64. claude_mpm/cli_module/commands.py +79 -70
  65. claude_mpm/cli_module/migration_example.py +38 -60
  66. claude_mpm/config/__init__.py +32 -25
  67. claude_mpm/config/agent_config.py +151 -119
  68. claude_mpm/config/experimental_features.py +71 -73
  69. claude_mpm/config/paths.py +94 -208
  70. claude_mpm/config/socketio_config.py +84 -73
  71. claude_mpm/constants.py +35 -18
  72. claude_mpm/core/__init__.py +9 -6
  73. claude_mpm/core/agent_name_normalizer.py +68 -71
  74. claude_mpm/core/agent_registry.py +372 -521
  75. claude_mpm/core/agent_session_manager.py +74 -63
  76. claude_mpm/core/base_service.py +116 -87
  77. claude_mpm/core/cache.py +119 -153
  78. claude_mpm/core/claude_runner.py +425 -1120
  79. claude_mpm/core/config.py +263 -168
  80. claude_mpm/core/config_aliases.py +69 -61
  81. claude_mpm/core/config_constants.py +292 -0
  82. claude_mpm/core/constants.py +57 -99
  83. claude_mpm/core/container.py +211 -178
  84. claude_mpm/core/exceptions.py +233 -89
  85. claude_mpm/core/factories.py +92 -54
  86. claude_mpm/core/framework_loader.py +378 -220
  87. claude_mpm/core/hook_manager.py +198 -83
  88. claude_mpm/core/hook_performance_config.py +136 -0
  89. claude_mpm/core/injectable_service.py +61 -55
  90. claude_mpm/core/interactive_session.py +165 -155
  91. claude_mpm/core/interfaces.py +221 -195
  92. claude_mpm/core/lazy.py +96 -96
  93. claude_mpm/core/logger.py +133 -107
  94. claude_mpm/core/logging_config.py +185 -157
  95. claude_mpm/core/minimal_framework_loader.py +20 -15
  96. claude_mpm/core/mixins.py +30 -29
  97. claude_mpm/core/oneshot_session.py +215 -181
  98. claude_mpm/core/optimized_agent_loader.py +134 -138
  99. claude_mpm/core/optimized_startup.py +159 -157
  100. claude_mpm/core/pm_hook_interceptor.py +85 -72
  101. claude_mpm/core/service_registry.py +103 -101
  102. claude_mpm/core/session_manager.py +97 -87
  103. claude_mpm/core/socketio_pool.py +212 -158
  104. claude_mpm/core/tool_access_control.py +58 -51
  105. claude_mpm/core/types.py +46 -24
  106. claude_mpm/core/typing_utils.py +166 -82
  107. claude_mpm/core/unified_agent_registry.py +721 -0
  108. claude_mpm/core/unified_config.py +550 -0
  109. claude_mpm/core/unified_paths.py +549 -0
  110. claude_mpm/dashboard/index.html +1 -1
  111. claude_mpm/dashboard/open_dashboard.py +51 -17
  112. claude_mpm/dashboard/static/css/dashboard.css +27 -8
  113. claude_mpm/dashboard/static/dist/components/agent-inference.js +2 -0
  114. claude_mpm/dashboard/static/dist/components/event-processor.js +2 -0
  115. claude_mpm/dashboard/static/dist/components/event-viewer.js +2 -0
  116. claude_mpm/dashboard/static/dist/components/export-manager.js +2 -0
  117. claude_mpm/dashboard/static/dist/components/file-tool-tracker.js +2 -0
  118. claude_mpm/dashboard/static/dist/components/hud-library-loader.js +2 -0
  119. claude_mpm/dashboard/static/dist/components/hud-manager.js +2 -0
  120. claude_mpm/dashboard/static/dist/components/hud-visualizer.js +2 -0
  121. claude_mpm/dashboard/static/dist/components/module-viewer.js +2 -0
  122. claude_mpm/dashboard/static/dist/components/session-manager.js +2 -0
  123. claude_mpm/dashboard/static/dist/components/socket-manager.js +2 -0
  124. claude_mpm/dashboard/static/dist/components/ui-state-manager.js +2 -0
  125. claude_mpm/dashboard/static/dist/components/working-directory.js +2 -0
  126. claude_mpm/dashboard/static/dist/dashboard.js +2 -0
  127. claude_mpm/dashboard/static/dist/socket-client.js +2 -0
  128. claude_mpm/dashboard/static/js/components/agent-inference.js +80 -76
  129. claude_mpm/dashboard/static/js/components/event-processor.js +71 -67
  130. claude_mpm/dashboard/static/js/components/event-viewer.js +74 -70
  131. claude_mpm/dashboard/static/js/components/export-manager.js +31 -28
  132. claude_mpm/dashboard/static/js/components/file-tool-tracker.js +106 -92
  133. claude_mpm/dashboard/static/js/components/hud-library-loader.js +11 -11
  134. claude_mpm/dashboard/static/js/components/hud-manager.js +73 -73
  135. claude_mpm/dashboard/static/js/components/hud-visualizer.js +163 -163
  136. claude_mpm/dashboard/static/js/components/module-viewer.js +305 -233
  137. claude_mpm/dashboard/static/js/components/session-manager.js +32 -29
  138. claude_mpm/dashboard/static/js/components/socket-manager.js +27 -20
  139. claude_mpm/dashboard/static/js/components/ui-state-manager.js +21 -18
  140. claude_mpm/dashboard/static/js/components/working-directory.js +74 -71
  141. claude_mpm/dashboard/static/js/dashboard.js +178 -453
  142. claude_mpm/dashboard/static/js/extension-error-handler.js +164 -0
  143. claude_mpm/dashboard/static/js/socket-client.js +120 -54
  144. claude_mpm/dashboard/templates/index.html +40 -50
  145. claude_mpm/experimental/cli_enhancements.py +60 -58
  146. claude_mpm/generators/__init__.py +1 -1
  147. claude_mpm/generators/agent_profile_generator.py +75 -65
  148. claude_mpm/hooks/__init__.py +1 -1
  149. claude_mpm/hooks/base_hook.py +33 -28
  150. claude_mpm/hooks/claude_hooks/__init__.py +1 -1
  151. claude_mpm/hooks/claude_hooks/connection_pool.py +120 -0
  152. claude_mpm/hooks/claude_hooks/event_handlers.py +743 -0
  153. claude_mpm/hooks/claude_hooks/hook_handler.py +415 -1331
  154. claude_mpm/hooks/claude_hooks/hook_wrapper.sh +4 -4
  155. claude_mpm/hooks/claude_hooks/memory_integration.py +221 -0
  156. claude_mpm/hooks/claude_hooks/response_tracking.py +348 -0
  157. claude_mpm/hooks/claude_hooks/tool_analysis.py +230 -0
  158. claude_mpm/hooks/memory_integration_hook.py +140 -100
  159. claude_mpm/hooks/tool_call_interceptor.py +89 -76
  160. claude_mpm/hooks/validation_hooks.py +57 -49
  161. claude_mpm/init.py +145 -121
  162. claude_mpm/models/__init__.py +9 -9
  163. claude_mpm/models/agent_definition.py +33 -23
  164. claude_mpm/models/agent_session.py +228 -200
  165. claude_mpm/scripts/__init__.py +1 -1
  166. claude_mpm/scripts/socketio_daemon.py +192 -75
  167. claude_mpm/scripts/socketio_server_manager.py +328 -0
  168. claude_mpm/scripts/start_activity_logging.py +25 -22
  169. claude_mpm/services/__init__.py +68 -43
  170. claude_mpm/services/agent_capabilities_service.py +271 -0
  171. claude_mpm/services/agents/__init__.py +23 -32
  172. claude_mpm/services/agents/deployment/__init__.py +3 -3
  173. claude_mpm/services/agents/deployment/agent_config_provider.py +310 -0
  174. claude_mpm/services/agents/deployment/agent_configuration_manager.py +359 -0
  175. claude_mpm/services/agents/deployment/agent_definition_factory.py +84 -0
  176. claude_mpm/services/agents/deployment/agent_deployment.py +415 -2113
  177. claude_mpm/services/agents/deployment/agent_discovery_service.py +387 -0
  178. claude_mpm/services/agents/deployment/agent_environment_manager.py +293 -0
  179. claude_mpm/services/agents/deployment/agent_filesystem_manager.py +387 -0
  180. claude_mpm/services/agents/deployment/agent_format_converter.py +453 -0
  181. claude_mpm/services/agents/deployment/agent_frontmatter_validator.py +161 -0
  182. claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +345 -495
  183. claude_mpm/services/agents/deployment/agent_metrics_collector.py +279 -0
  184. claude_mpm/services/agents/deployment/agent_restore_handler.py +88 -0
  185. claude_mpm/services/agents/deployment/agent_template_builder.py +406 -0
  186. claude_mpm/services/agents/deployment/agent_validator.py +352 -0
  187. claude_mpm/services/agents/deployment/agent_version_manager.py +313 -0
  188. claude_mpm/services/agents/deployment/agent_versioning.py +6 -9
  189. claude_mpm/services/agents/deployment/agents_directory_resolver.py +79 -0
  190. claude_mpm/services/agents/deployment/async_agent_deployment.py +298 -234
  191. claude_mpm/services/agents/deployment/config/__init__.py +13 -0
  192. claude_mpm/services/agents/deployment/config/deployment_config.py +182 -0
  193. claude_mpm/services/agents/deployment/config/deployment_config_manager.py +200 -0
  194. claude_mpm/services/agents/deployment/deployment_config_loader.py +54 -0
  195. claude_mpm/services/agents/deployment/deployment_type_detector.py +124 -0
  196. claude_mpm/services/agents/deployment/facade/__init__.py +18 -0
  197. claude_mpm/services/agents/deployment/facade/async_deployment_executor.py +159 -0
  198. claude_mpm/services/agents/deployment/facade/deployment_executor.py +73 -0
  199. claude_mpm/services/agents/deployment/facade/deployment_facade.py +270 -0
  200. claude_mpm/services/agents/deployment/facade/sync_deployment_executor.py +178 -0
  201. claude_mpm/services/agents/deployment/interface_adapter.py +227 -0
  202. claude_mpm/services/agents/deployment/lifecycle_health_checker.py +85 -0
  203. claude_mpm/services/agents/deployment/lifecycle_performance_tracker.py +100 -0
  204. claude_mpm/services/agents/deployment/pipeline/__init__.py +32 -0
  205. claude_mpm/services/agents/deployment/pipeline/pipeline_builder.py +158 -0
  206. claude_mpm/services/agents/deployment/pipeline/pipeline_context.py +159 -0
  207. claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +169 -0
  208. claude_mpm/services/agents/deployment/pipeline/steps/__init__.py +19 -0
  209. claude_mpm/services/agents/deployment/pipeline/steps/agent_processing_step.py +195 -0
  210. claude_mpm/services/agents/deployment/pipeline/steps/base_step.py +119 -0
  211. claude_mpm/services/agents/deployment/pipeline/steps/configuration_step.py +79 -0
  212. claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +90 -0
  213. claude_mpm/services/agents/deployment/pipeline/steps/validation_step.py +100 -0
  214. claude_mpm/services/agents/deployment/processors/__init__.py +15 -0
  215. claude_mpm/services/agents/deployment/processors/agent_deployment_context.py +98 -0
  216. claude_mpm/services/agents/deployment/processors/agent_deployment_result.py +235 -0
  217. claude_mpm/services/agents/deployment/processors/agent_processor.py +258 -0
  218. claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +318 -0
  219. claude_mpm/services/agents/deployment/results/__init__.py +13 -0
  220. claude_mpm/services/agents/deployment/results/deployment_metrics.py +200 -0
  221. claude_mpm/services/agents/deployment/results/deployment_result_builder.py +249 -0
  222. claude_mpm/services/agents/deployment/strategies/__init__.py +25 -0
  223. claude_mpm/services/agents/deployment/strategies/base_strategy.py +119 -0
  224. claude_mpm/services/agents/deployment/strategies/project_strategy.py +150 -0
  225. claude_mpm/services/agents/deployment/strategies/strategy_selector.py +117 -0
  226. claude_mpm/services/agents/deployment/strategies/system_strategy.py +116 -0
  227. claude_mpm/services/agents/deployment/strategies/user_strategy.py +137 -0
  228. claude_mpm/services/agents/deployment/system_instructions_deployer.py +108 -0
  229. claude_mpm/services/agents/deployment/validation/__init__.py +19 -0
  230. claude_mpm/services/agents/deployment/validation/agent_validator.py +323 -0
  231. claude_mpm/services/agents/deployment/validation/deployment_validator.py +238 -0
  232. claude_mpm/services/agents/deployment/validation/template_validator.py +299 -0
  233. claude_mpm/services/agents/deployment/validation/validation_result.py +226 -0
  234. claude_mpm/services/agents/loading/__init__.py +2 -2
  235. claude_mpm/services/agents/loading/agent_profile_loader.py +259 -229
  236. claude_mpm/services/agents/loading/base_agent_manager.py +90 -81
  237. claude_mpm/services/agents/loading/framework_agent_loader.py +154 -129
  238. claude_mpm/services/agents/management/__init__.py +2 -2
  239. claude_mpm/services/agents/management/agent_capabilities_generator.py +72 -58
  240. claude_mpm/services/agents/management/agent_management_service.py +209 -156
  241. claude_mpm/services/agents/memory/__init__.py +9 -6
  242. claude_mpm/services/agents/memory/agent_memory_manager.py +218 -1152
  243. claude_mpm/services/agents/memory/agent_persistence_service.py +20 -16
  244. claude_mpm/services/agents/memory/analyzer.py +430 -0
  245. claude_mpm/services/agents/memory/content_manager.py +376 -0
  246. claude_mpm/services/agents/memory/template_generator.py +468 -0
  247. claude_mpm/services/agents/registry/__init__.py +7 -10
  248. claude_mpm/services/agents/registry/deployed_agent_discovery.py +122 -97
  249. claude_mpm/services/agents/registry/modification_tracker.py +351 -285
  250. claude_mpm/services/async_session_logger.py +187 -153
  251. claude_mpm/services/claude_session_logger.py +87 -72
  252. claude_mpm/services/command_handler_service.py +217 -0
  253. claude_mpm/services/communication/__init__.py +3 -2
  254. claude_mpm/services/core/__init__.py +50 -97
  255. claude_mpm/services/core/base.py +60 -53
  256. claude_mpm/services/core/interfaces/__init__.py +188 -0
  257. claude_mpm/services/core/interfaces/agent.py +351 -0
  258. claude_mpm/services/core/interfaces/communication.py +343 -0
  259. claude_mpm/services/core/interfaces/infrastructure.py +413 -0
  260. claude_mpm/services/core/interfaces/service.py +434 -0
  261. claude_mpm/services/core/interfaces.py +19 -944
  262. claude_mpm/services/event_aggregator.py +208 -170
  263. claude_mpm/services/exceptions.py +387 -308
  264. claude_mpm/services/framework_claude_md_generator/__init__.py +75 -79
  265. claude_mpm/services/framework_claude_md_generator/content_assembler.py +69 -60
  266. claude_mpm/services/framework_claude_md_generator/content_validator.py +65 -61
  267. claude_mpm/services/framework_claude_md_generator/deployment_manager.py +68 -49
  268. claude_mpm/services/framework_claude_md_generator/section_generators/__init__.py +34 -34
  269. claude_mpm/services/framework_claude_md_generator/section_generators/agents.py +25 -22
  270. claude_mpm/services/framework_claude_md_generator/section_generators/claude_pm_init.py +10 -10
  271. claude_mpm/services/framework_claude_md_generator/section_generators/core_responsibilities.py +4 -3
  272. claude_mpm/services/framework_claude_md_generator/section_generators/delegation_constraints.py +4 -3
  273. claude_mpm/services/framework_claude_md_generator/section_generators/environment_config.py +4 -3
  274. claude_mpm/services/framework_claude_md_generator/section_generators/footer.py +6 -5
  275. claude_mpm/services/framework_claude_md_generator/section_generators/header.py +8 -7
  276. claude_mpm/services/framework_claude_md_generator/section_generators/orchestration_principles.py +4 -3
  277. claude_mpm/services/framework_claude_md_generator/section_generators/role_designation.py +6 -5
  278. claude_mpm/services/framework_claude_md_generator/section_generators/subprocess_validation.py +9 -8
  279. claude_mpm/services/framework_claude_md_generator/section_generators/todo_task_tools.py +4 -3
  280. claude_mpm/services/framework_claude_md_generator/section_generators/troubleshooting.py +5 -4
  281. claude_mpm/services/framework_claude_md_generator/section_manager.py +28 -27
  282. claude_mpm/services/framework_claude_md_generator/version_manager.py +30 -28
  283. claude_mpm/services/hook_service.py +106 -114
  284. claude_mpm/services/infrastructure/__init__.py +7 -5
  285. claude_mpm/services/infrastructure/context_preservation.py +233 -199
  286. claude_mpm/services/infrastructure/daemon_manager.py +279 -0
  287. claude_mpm/services/infrastructure/logging.py +83 -76
  288. claude_mpm/services/infrastructure/monitoring.py +547 -404
  289. claude_mpm/services/mcp_gateway/__init__.py +30 -13
  290. claude_mpm/services/mcp_gateway/config/__init__.py +2 -2
  291. claude_mpm/services/mcp_gateway/config/config_loader.py +61 -56
  292. claude_mpm/services/mcp_gateway/config/config_schema.py +50 -41
  293. claude_mpm/services/mcp_gateway/config/configuration.py +82 -75
  294. claude_mpm/services/mcp_gateway/core/__init__.py +13 -20
  295. claude_mpm/services/mcp_gateway/core/base.py +80 -67
  296. claude_mpm/services/mcp_gateway/core/exceptions.py +60 -46
  297. claude_mpm/services/mcp_gateway/core/interfaces.py +87 -84
  298. claude_mpm/services/mcp_gateway/main.py +287 -137
  299. claude_mpm/services/mcp_gateway/registry/__init__.py +1 -1
  300. claude_mpm/services/mcp_gateway/registry/service_registry.py +97 -94
  301. claude_mpm/services/mcp_gateway/registry/tool_registry.py +135 -126
  302. claude_mpm/services/mcp_gateway/server/__init__.py +2 -2
  303. claude_mpm/services/mcp_gateway/server/mcp_gateway.py +105 -110
  304. claude_mpm/services/mcp_gateway/server/stdio_handler.py +105 -107
  305. claude_mpm/services/mcp_gateway/server/stdio_server.py +691 -0
  306. claude_mpm/services/mcp_gateway/tools/__init__.py +4 -2
  307. claude_mpm/services/mcp_gateway/tools/base_adapter.py +109 -119
  308. claude_mpm/services/mcp_gateway/tools/document_summarizer.py +283 -215
  309. claude_mpm/services/mcp_gateway/tools/hello_world.py +122 -120
  310. claude_mpm/services/mcp_gateway/tools/ticket_tools.py +652 -0
  311. claude_mpm/services/mcp_gateway/tools/unified_ticket_tool.py +606 -0
  312. claude_mpm/services/memory/__init__.py +2 -2
  313. claude_mpm/services/memory/builder.py +451 -362
  314. claude_mpm/services/memory/cache/__init__.py +2 -2
  315. claude_mpm/services/memory/cache/shared_prompt_cache.py +232 -194
  316. claude_mpm/services/memory/cache/simple_cache.py +107 -93
  317. claude_mpm/services/memory/indexed_memory.py +195 -193
  318. claude_mpm/services/memory/optimizer.py +267 -234
  319. claude_mpm/services/memory/router.py +571 -263
  320. claude_mpm/services/memory_hook_service.py +237 -0
  321. claude_mpm/services/port_manager.py +223 -0
  322. claude_mpm/services/project/__init__.py +3 -3
  323. claude_mpm/services/project/analyzer.py +451 -305
  324. claude_mpm/services/project/registry.py +262 -240
  325. claude_mpm/services/recovery_manager.py +287 -231
  326. claude_mpm/services/response_tracker.py +87 -67
  327. claude_mpm/services/runner_configuration_service.py +587 -0
  328. claude_mpm/services/session_management_service.py +304 -0
  329. claude_mpm/services/socketio/__init__.py +4 -4
  330. claude_mpm/services/socketio/client_proxy.py +174 -0
  331. claude_mpm/services/socketio/handlers/__init__.py +3 -3
  332. claude_mpm/services/socketio/handlers/base.py +44 -30
  333. claude_mpm/services/socketio/handlers/connection.py +145 -65
  334. claude_mpm/services/socketio/handlers/file.py +123 -108
  335. claude_mpm/services/socketio/handlers/git.py +607 -373
  336. claude_mpm/services/socketio/handlers/hook.py +170 -0
  337. claude_mpm/services/socketio/handlers/memory.py +4 -4
  338. claude_mpm/services/socketio/handlers/project.py +4 -4
  339. claude_mpm/services/socketio/handlers/registry.py +53 -38
  340. claude_mpm/services/socketio/server/__init__.py +18 -0
  341. claude_mpm/services/socketio/server/broadcaster.py +252 -0
  342. claude_mpm/services/socketio/server/core.py +399 -0
  343. claude_mpm/services/socketio/server/main.py +323 -0
  344. claude_mpm/services/socketio_client_manager.py +160 -133
  345. claude_mpm/services/socketio_server.py +36 -1885
  346. claude_mpm/services/subprocess_launcher_service.py +316 -0
  347. claude_mpm/services/system_instructions_service.py +258 -0
  348. claude_mpm/services/ticket_manager.py +19 -533
  349. claude_mpm/services/utility_service.py +285 -0
  350. claude_mpm/services/version_control/__init__.py +18 -21
  351. claude_mpm/services/version_control/branch_strategy.py +20 -10
  352. claude_mpm/services/version_control/conflict_resolution.py +37 -13
  353. claude_mpm/services/version_control/git_operations.py +52 -21
  354. claude_mpm/services/version_control/semantic_versioning.py +92 -53
  355. claude_mpm/services/version_control/version_parser.py +145 -125
  356. claude_mpm/services/version_service.py +270 -0
  357. claude_mpm/storage/__init__.py +2 -2
  358. claude_mpm/storage/state_storage.py +177 -181
  359. claude_mpm/ticket_wrapper.py +2 -2
  360. claude_mpm/utils/__init__.py +2 -2
  361. claude_mpm/utils/agent_dependency_loader.py +453 -243
  362. claude_mpm/utils/config_manager.py +157 -118
  363. claude_mpm/utils/console.py +1 -1
  364. claude_mpm/utils/dependency_cache.py +102 -107
  365. claude_mpm/utils/dependency_manager.py +52 -47
  366. claude_mpm/utils/dependency_strategies.py +131 -96
  367. claude_mpm/utils/environment_context.py +110 -102
  368. claude_mpm/utils/error_handler.py +75 -55
  369. claude_mpm/utils/file_utils.py +80 -67
  370. claude_mpm/utils/framework_detection.py +12 -11
  371. claude_mpm/utils/import_migration_example.py +12 -60
  372. claude_mpm/utils/imports.py +48 -45
  373. claude_mpm/utils/path_operations.py +100 -93
  374. claude_mpm/utils/robust_installer.py +172 -164
  375. claude_mpm/utils/session_logging.py +30 -23
  376. claude_mpm/utils/subprocess_utils.py +99 -61
  377. claude_mpm/validation/__init__.py +1 -1
  378. claude_mpm/validation/agent_validator.py +151 -111
  379. claude_mpm/validation/frontmatter_validator.py +92 -71
  380. {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.3.dist-info}/METADATA +27 -1
  381. claude_mpm-4.0.3.dist-info/RECORD +402 -0
  382. {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.3.dist-info}/entry_points.txt +1 -0
  383. {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.3.dist-info}/licenses/LICENSE +1 -1
  384. claude_mpm/cli/commands/run_guarded.py +0 -511
  385. claude_mpm/config/memory_guardian_config.py +0 -325
  386. claude_mpm/config/memory_guardian_yaml.py +0 -335
  387. claude_mpm/core/config_paths.py +0 -150
  388. claude_mpm/core/memory_aware_runner.py +0 -353
  389. claude_mpm/dashboard/static/js/dashboard-original.js +0 -4134
  390. claude_mpm/deployment_paths.py +0 -261
  391. claude_mpm/hooks/claude_hooks/hook_handler_fixed.py +0 -454
  392. claude_mpm/models/state_models.py +0 -433
  393. claude_mpm/services/agent/__init__.py +0 -24
  394. claude_mpm/services/agent/deployment.py +0 -2548
  395. claude_mpm/services/agent/management.py +0 -598
  396. claude_mpm/services/agent/registry.py +0 -813
  397. claude_mpm/services/agents/registry/agent_registry.py +0 -813
  398. claude_mpm/services/communication/socketio.py +0 -1935
  399. claude_mpm/services/communication/websocket.py +0 -479
  400. claude_mpm/services/framework_claude_md_generator.py +0 -624
  401. claude_mpm/services/health_monitor.py +0 -893
  402. claude_mpm/services/infrastructure/graceful_degradation.py +0 -616
  403. claude_mpm/services/infrastructure/health_monitor.py +0 -775
  404. claude_mpm/services/infrastructure/memory_dashboard.py +0 -479
  405. claude_mpm/services/infrastructure/memory_guardian.py +0 -944
  406. claude_mpm/services/infrastructure/restart_protection.py +0 -642
  407. claude_mpm/services/infrastructure/state_manager.py +0 -774
  408. claude_mpm/services/mcp_gateway/manager.py +0 -334
  409. claude_mpm/services/optimized_hook_service.py +0 -542
  410. claude_mpm/services/project_analyzer.py +0 -864
  411. claude_mpm/services/project_registry.py +0 -608
  412. claude_mpm/services/standalone_socketio_server.py +0 -1300
  413. claude_mpm/services/ticket_manager_di.py +0 -318
  414. claude_mpm/services/ticketing_service_original.py +0 -510
  415. claude_mpm/utils/paths.py +0 -395
  416. claude_mpm/utils/platform_memory.py +0 -524
  417. claude_mpm-3.9.11.dist-info/RECORD +0 -306
  418. {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.3.dist-info}/WHEEL +0 -0
  419. {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.3.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,285 @@
1
+ from pathlib import Path
2
+
3
+ """Utility service for various helper functions.
4
+
5
+ This service handles:
6
+ 1. Agent delegation detection
7
+ 2. Session event logging
8
+ 3. Text processing utilities
9
+ 4. Pattern matching utilities
10
+
11
+ Extracted from ClaudeRunner to follow Single Responsibility Principle.
12
+ """
13
+
14
+ import json
15
+ import re
16
+ import uuid
17
+ from datetime import datetime
18
+ from typing import Any, Dict, Optional, Tuple
19
+
20
+ from claude_mpm.core.base_service import BaseService
21
+ from claude_mpm.services.core.interfaces import UtilityServiceInterface
22
+
23
+
24
+ class UtilityService(BaseService, UtilityServiceInterface):
25
+ """Service for utility functions and helper methods."""
26
+
27
+ def __init__(self):
28
+ """Initialize the utility service."""
29
+ super().__init__(name="utility_service")
30
+
31
+ async def _initialize(self) -> None:
32
+ """Initialize the service. No special initialization needed."""
33
+ pass
34
+
35
+ async def _cleanup(self) -> None:
36
+ """Cleanup service resources. No cleanup needed."""
37
+ pass
38
+
39
+ def contains_delegation(self, text: str) -> bool:
40
+ """Check if text contains signs of agent delegation.
41
+
42
+ Args:
43
+ text: Text to check for delegation patterns
44
+
45
+ Returns:
46
+ bool: True if delegation patterns are found
47
+ """
48
+ # Look for common delegation patterns
49
+ delegation_patterns = [
50
+ "Task(",
51
+ "subagent_type=",
52
+ "delegating to",
53
+ "asking the",
54
+ "engineer agent",
55
+ "qa agent",
56
+ "documentation agent",
57
+ "research agent",
58
+ "security agent",
59
+ "ops agent",
60
+ "version_control agent",
61
+ "data_engineer agent",
62
+ ]
63
+
64
+ text_lower = text.lower()
65
+ return any(pattern.lower() in text_lower for pattern in delegation_patterns)
66
+
67
+ def extract_agent_from_response(self, text: str) -> Optional[str]:
68
+ """Try to extract agent name from delegation response.
69
+
70
+ Args:
71
+ text: Response text to extract agent name from
72
+
73
+ Returns:
74
+ Optional[str]: Extracted agent name or None if not found
75
+ """
76
+ # Pattern 1: subagent_type="agent_name"
77
+ match = re.search(r'subagent_type=["\']([^"\']*)["\'\)]', text)
78
+ if match:
79
+ return match.group(1)
80
+
81
+ # Pattern 2: "engineer agent" etc
82
+ agent_names = [
83
+ "engineer",
84
+ "qa",
85
+ "documentation",
86
+ "research",
87
+ "security",
88
+ "ops",
89
+ "version_control",
90
+ "data_engineer",
91
+ ]
92
+ text_lower = text.lower()
93
+ for agent in agent_names:
94
+ if f"{agent} agent" in text_lower or f"agent: {agent}" in text_lower:
95
+ return agent
96
+
97
+ return None
98
+
99
+ def log_session_event(self, log_file: Optional[Path], event_data: Dict[str, Any]):
100
+ """Log an event to the session log file.
101
+
102
+ Args:
103
+ log_file: Path to the session log file
104
+ event_data: Event data to log
105
+ """
106
+ if not log_file:
107
+ return
108
+
109
+ try:
110
+ log_entry = {"timestamp": datetime.now().isoformat(), **event_data}
111
+
112
+ with open(log_file, "a") as f:
113
+ f.write(json.dumps(log_entry) + "\n")
114
+
115
+ except (OSError, IOError) as e:
116
+ self.logger.debug(f"IO error logging session event: {e}")
117
+ except Exception as e:
118
+ self.logger.debug(f"Failed to log session event: {e}")
119
+
120
+ def validate_prompt(self, prompt: str) -> bool:
121
+ """Validate that a prompt is not empty and properly formatted.
122
+
123
+ Args:
124
+ prompt: Prompt to validate
125
+
126
+ Returns:
127
+ bool: True if prompt is valid
128
+ """
129
+ if not prompt or not prompt.strip():
130
+ return False
131
+
132
+ # Check for minimum length
133
+ if len(prompt.strip()) < 3:
134
+ return False
135
+
136
+ return True
137
+
138
+ def sanitize_filename(self, filename: str) -> str:
139
+ """Sanitize a filename by removing invalid characters.
140
+
141
+ Args:
142
+ filename: Filename to sanitize
143
+
144
+ Returns:
145
+ str: Sanitized filename
146
+ """
147
+ # Remove invalid characters for filenames
148
+ invalid_chars = '<>:"/\\|?*'
149
+ sanitized = filename
150
+ for char in invalid_chars:
151
+ sanitized = sanitized.replace(char, "_")
152
+
153
+ # Remove leading/trailing whitespace and dots
154
+ sanitized = sanitized.strip(" .")
155
+
156
+ # Ensure filename is not empty
157
+ if not sanitized:
158
+ sanitized = "untitled"
159
+
160
+ return sanitized
161
+
162
+ def format_error_message(self, error: Exception, context: str = "") -> str:
163
+ """Format an error message with context.
164
+
165
+ Args:
166
+ error: Exception to format
167
+ context: Optional context information
168
+
169
+ Returns:
170
+ str: Formatted error message
171
+ """
172
+ error_type = type(error).__name__
173
+ error_msg = str(error)
174
+
175
+ if context:
176
+ return f"{context}: {error_type}: {error_msg}"
177
+ else:
178
+ return f"{error_type}: {error_msg}"
179
+
180
+ def truncate_text(
181
+ self, text: str, max_length: int = 100, suffix: str = "..."
182
+ ) -> str:
183
+ """Truncate text to a maximum length.
184
+
185
+ Args:
186
+ text: Text to truncate
187
+ max_length: Maximum length before truncation
188
+ suffix: Suffix to add when truncating
189
+
190
+ Returns:
191
+ str: Truncated text
192
+ """
193
+ if len(text) <= max_length:
194
+ return text
195
+
196
+ return text[: max_length - len(suffix)] + suffix
197
+
198
+ def parse_key_value_pairs(self, text: str) -> Dict[str, str]:
199
+ """Parse key=value pairs from text.
200
+
201
+ Args:
202
+ text: Text containing key=value pairs
203
+
204
+ Returns:
205
+ Dict[str, str]: Parsed key-value pairs
206
+ """
207
+ pairs = {}
208
+
209
+ # Look for key=value patterns
210
+ pattern = r'(\w+)=(["\']?)([^"\'\s]*)\2'
211
+ matches = re.findall(pattern, text)
212
+
213
+ for key, quote, value in matches:
214
+ pairs[key] = value
215
+
216
+ return pairs
217
+
218
+ def get_service_status(self) -> Dict[str, Any]:
219
+ """Get current utility service status.
220
+
221
+ Returns:
222
+ Dict[str, Any]: Service status information
223
+ """
224
+ return {
225
+ "service_available": True,
226
+ "delegation_detection": True,
227
+ "session_logging": True,
228
+ "text_processing": True,
229
+ "pattern_matching": True,
230
+ }
231
+
232
+ # Implementation of abstract methods from UtilityServiceInterface
233
+
234
+ def format_file_size(self, size_bytes: int) -> str:
235
+ """Format file size in human-readable format."""
236
+ if size_bytes == 0:
237
+ return "0 B"
238
+ units = ["B", "KB", "MB", "GB", "TB"]
239
+ unit_index = 0
240
+ size = float(size_bytes)
241
+ while size >= 1024 and unit_index < len(units) - 1:
242
+ size /= 1024
243
+ unit_index += 1
244
+ return (
245
+ f"{size:.1f} {units[unit_index]}"
246
+ if unit_index > 0
247
+ else f"{int(size)} {units[unit_index]}"
248
+ )
249
+
250
+ def format_duration(self, seconds: float) -> str:
251
+ """Format duration in human-readable format."""
252
+ if seconds < 60:
253
+ return f"{seconds:.1f}s"
254
+ minutes = int(seconds // 60)
255
+ remaining_seconds = int(seconds % 60)
256
+ if minutes < 60:
257
+ return (
258
+ f"{minutes}m {remaining_seconds}s"
259
+ if remaining_seconds > 0
260
+ else f"{minutes}m"
261
+ )
262
+ hours = int(minutes // 60)
263
+ remaining_minutes = int(minutes % 60)
264
+ return (
265
+ f"{hours}h {remaining_minutes}m" if remaining_minutes > 0 else f"{hours}h"
266
+ )
267
+
268
+ def generate_unique_id(self, prefix: str = "") -> str:
269
+ """Generate a unique identifier."""
270
+ unique_id = str(uuid.uuid4())
271
+ return f"{prefix}_{unique_id}" if prefix else unique_id
272
+
273
+ def validate_path(self, path: Path) -> Tuple[bool, Optional[str]]:
274
+ """Validate a filesystem path."""
275
+ try:
276
+ if not isinstance(path, Path):
277
+ return False, "Path must be a Path object"
278
+ path_str = str(path)
279
+ if not path_str or path_str.isspace():
280
+ return False, "Path cannot be empty"
281
+ return True, None
282
+ except Exception as e:
283
+ return False, f"Path validation error: {str(e)}"
284
+
285
+
@@ -8,37 +8,34 @@ This package provides modular services for the Version Control Agent including:
8
8
  - Conflict resolution
9
9
  """
10
10
 
11
- from .git_operations import (
12
- GitOperationsManager,
13
- GitBranchInfo,
14
- GitOperationResult,
15
- GitOperationError,
16
- )
17
-
18
- from .semantic_versioning import (
19
- SemanticVersionManager,
20
- SemanticVersion,
21
- VersionBumpType,
22
- VersionMetadata,
23
- ChangeAnalysis,
24
- )
25
-
26
11
  from .branch_strategy import (
12
+ BranchLifecycleRule,
13
+ BranchNamingRule,
27
14
  BranchStrategyManager,
28
15
  BranchStrategyType,
29
16
  BranchType,
30
17
  BranchWorkflow,
31
- BranchNamingRule,
32
- BranchLifecycleRule,
33
18
  )
34
-
35
19
  from .conflict_resolution import (
20
+ ConflictAnalysis,
21
+ ConflictResolution,
36
22
  ConflictResolutionManager,
37
23
  ConflictType,
38
- ResolutionStrategy,
39
24
  FileConflict,
40
- ConflictResolution,
41
- ConflictAnalysis,
25
+ ResolutionStrategy,
26
+ )
27
+ from .git_operations import (
28
+ GitBranchInfo,
29
+ GitOperationError,
30
+ GitOperationResult,
31
+ GitOperationsManager,
32
+ )
33
+ from .semantic_versioning import (
34
+ ChangeAnalysis,
35
+ SemanticVersion,
36
+ SemanticVersionManager,
37
+ VersionBumpType,
38
+ VersionMetadata,
42
39
  )
43
40
 
44
41
  __all__ = [
@@ -1,3 +1,5 @@
1
+ from pathlib import Path
2
+
1
3
  """
2
4
  Branch Strategy Manager - Branch strategy implementations for Version Control Agent.
3
5
 
@@ -9,15 +11,14 @@ This module provides comprehensive branch strategy management including:
9
11
  5. Branch lifecycle management
10
12
  """
11
13
 
12
- from enum import Enum
13
- from datetime import datetime
14
- from pathlib import Path
15
- from typing import Dict, List, Optional, Any, Tuple
16
- from dataclasses import dataclass, field
17
14
  import logging
18
15
  import re
16
+ from dataclasses import dataclass, field
17
+ from datetime import datetime
18
+ from enum import Enum
19
+ from typing import Any, Dict, List, Optional, Tuple
19
20
 
20
- from claude_mpm.core.config_paths import ConfigPaths
21
+ from claude_mpm.core.unified_paths import get_path_manager
21
22
 
22
23
 
23
24
  class BranchStrategyType(Enum):
@@ -266,7 +267,11 @@ class BranchStrategyManager:
266
267
  development_branch="develop",
267
268
  naming_rules=naming_rules,
268
269
  lifecycle_rules=lifecycle_rules,
269
- merge_targets={"feature/*": "develop", "release/*": "main", "hotfix/*": "main"},
270
+ merge_targets={
271
+ "feature/*": "develop",
272
+ "release/*": "main",
273
+ "hotfix/*": "main",
274
+ },
270
275
  quality_gates=["testing", "code_review"],
271
276
  )
272
277
 
@@ -305,7 +310,7 @@ class BranchStrategyManager:
305
310
  """Load strategy configuration from project files."""
306
311
  # Try to load from configuration files
307
312
  config_files = [
308
- f"{ConfigPaths.CONFIG_DIR}/config.json",
313
+ f"{get_path_manager().CONFIG_DIR}/config.json",
309
314
  "workflow.md",
310
315
  ".github/workflows/branch-strategy.yml",
311
316
  "branch-strategy.json",
@@ -439,7 +444,10 @@ class BranchStrategyManager:
439
444
 
440
445
  # Check length
441
446
  if rule.max_length and len(branch_name) > rule.max_length:
442
- return False, f"Branch name exceeds maximum length: {rule.max_length}"
447
+ return (
448
+ False,
449
+ f"Branch name exceeds maximum length: {rule.max_length}",
450
+ )
443
451
 
444
452
  return True, "Valid branch name"
445
453
 
@@ -614,7 +622,9 @@ class BranchStrategyManager:
614
622
  strategy = self.get_current_strategy()
615
623
  return strategy.quality_gates
616
624
 
617
- def create_custom_strategy(self, name: str, config: Dict[str, Any]) -> BranchWorkflow:
625
+ def create_custom_strategy(
626
+ self, name: str, config: Dict[str, Any]
627
+ ) -> BranchWorkflow:
618
628
  """
619
629
  Create a custom branch strategy.
620
630
 
@@ -1,3 +1,5 @@
1
+ from pathlib import Path
2
+
1
3
  """
2
4
  Conflict Resolution Manager - Basic conflict resolution for Version Control Agent.
3
5
 
@@ -9,14 +11,13 @@ This module provides conflict resolution management including:
9
11
  5. Resolution validation
10
12
  """
11
13
 
12
- import re
13
14
  import difflib
14
- from datetime import datetime
15
- from pathlib import Path
16
- from typing import Dict, List, Optional, Any, Tuple, Union
15
+ import logging
16
+ import re
17
17
  from dataclasses import dataclass, field
18
+ from datetime import datetime
18
19
  from enum import Enum
19
- import logging
20
+ from typing import Any, Dict, List, Optional, Tuple, Union
20
21
 
21
22
 
22
23
  class ConflictType(Enum):
@@ -114,7 +115,11 @@ class ConflictResolutionManager:
114
115
  self.logger = logger
115
116
 
116
117
  # Conflict markers
117
- self.conflict_markers = {"start": r"^<{7} ", "separator": r"^={7}$", "end": r"^>{7} "}
118
+ self.conflict_markers = {
119
+ "start": r"^<{7} ",
120
+ "separator": r"^={7}$",
121
+ "end": r"^>{7} ",
122
+ }
118
123
 
119
124
  # Auto-resolution patterns
120
125
  self.auto_resolution_patterns = {
@@ -125,7 +130,14 @@ class ConflictResolutionManager:
125
130
  }
126
131
 
127
132
  # File types that can be auto-resolved
128
- self.auto_resolvable_extensions = {".md", ".txt", ".json", ".yml", ".yaml", ".xml"}
133
+ self.auto_resolvable_extensions = {
134
+ ".md",
135
+ ".txt",
136
+ ".json",
137
+ ".yml",
138
+ ".yaml",
139
+ ".xml",
140
+ }
129
141
 
130
142
  # Binary file extensions
131
143
  self.binary_extensions = {
@@ -237,7 +249,9 @@ class ConflictResolutionManager:
237
249
  conflicted_files = []
238
250
  for line in result.stdout.strip().split("\n"):
239
251
  if line.strip() and (
240
- line.startswith("UU") or line.startswith("AA") or line.startswith("DD")
252
+ line.startswith("UU")
253
+ or line.startswith("AA")
254
+ or line.startswith("DD")
241
255
  ):
242
256
  # Extract filename
243
257
  filename = line[3:].strip()
@@ -379,7 +393,9 @@ class ConflictResolutionManager:
379
393
  # For now, default to content conflict
380
394
  return ConflictType.CONTENT
381
395
 
382
- def _is_auto_resolvable(self, file_path: str, markers: List[ConflictMarker]) -> bool:
396
+ def _is_auto_resolvable(
397
+ self, file_path: str, markers: List[ConflictMarker]
398
+ ) -> bool:
383
399
  """Determine if conflict can be automatically resolved."""
384
400
  file_ext = Path(file_path).suffix.lower()
385
401
 
@@ -442,7 +458,9 @@ class ConflictResolutionManager:
442
458
  return False
443
459
  return True
444
460
 
445
- def _generate_resolution_suggestion(self, file_path: str, markers: List[ConflictMarker]) -> str:
461
+ def _generate_resolution_suggestion(
462
+ self, file_path: str, markers: List[ConflictMarker]
463
+ ) -> str:
446
464
  """Generate resolution suggestion for a file."""
447
465
  if not markers:
448
466
  return "No conflict markers found"
@@ -454,7 +472,9 @@ class ConflictResolutionManager:
454
472
  suggestions.append(f"Conflict {i+1}: Accept incoming changes (theirs)")
455
473
  elif marker.ours_content and not marker.theirs_content:
456
474
  suggestions.append(f"Conflict {i+1}: Keep current changes (ours)")
457
- elif self._only_whitespace_differences(marker.ours_content, marker.theirs_content):
475
+ elif self._only_whitespace_differences(
476
+ marker.ours_content, marker.theirs_content
477
+ ):
458
478
  suggestions.append(
459
479
  f"Conflict {i+1}: Whitespace differences only - can auto-resolve"
460
480
  )
@@ -555,7 +575,9 @@ class ConflictResolutionManager:
555
575
  resolutions.append(resolution)
556
576
 
557
577
  except Exception as e:
558
- self.logger.error(f"Error resolving conflict in {conflict.file_path}: {e}")
578
+ self.logger.error(
579
+ f"Error resolving conflict in {conflict.file_path}: {e}"
580
+ )
559
581
  resolutions.append(
560
582
  ConflictResolution(
561
583
  file_path=conflict.file_path,
@@ -583,7 +605,9 @@ class ConflictResolutionManager:
583
605
  content = f.read()
584
606
 
585
607
  # Apply resolution strategy
586
- resolved_content = self._apply_resolution_strategy(content, conflict.markers, strategy)
608
+ resolved_content = self._apply_resolution_strategy(
609
+ content, conflict.markers, strategy
610
+ )
587
611
 
588
612
  # Write resolved content
589
613
  with open(file_path, "w", encoding="utf-8") as f: