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
@@ -5,21 +5,22 @@ configurations across different file formats (JSON, YAML, TOML).
5
5
  """
6
6
 
7
7
  import json
8
- import logging
9
8
  import os
9
+ from functools import lru_cache
10
10
  from pathlib import Path
11
11
  from typing import Any, Dict, List, Optional, Union
12
- from functools import lru_cache
13
12
 
14
13
  # Handle optional imports
15
14
  try:
16
15
  import yaml
16
+
17
17
  HAS_YAML = True
18
18
  except ImportError:
19
19
  HAS_YAML = False
20
20
 
21
21
  try:
22
22
  import toml
23
+
23
24
  HAS_TOML = True
24
25
  except ImportError:
25
26
  HAS_TOML = False
@@ -31,75 +32,75 @@ logger = get_logger(__name__)
31
32
 
32
33
  class ConfigurationManager:
33
34
  """Unified configuration management with support for multiple formats."""
34
-
35
+
35
36
  def __init__(self, cache_enabled: bool = True):
36
37
  """Initialize the configuration manager.
37
-
38
+
38
39
  Args:
39
40
  cache_enabled: Whether to enable configuration caching
40
41
  """
41
42
  self.cache_enabled = cache_enabled
42
43
  self._cache: Dict[str, Any] = {}
43
-
44
+
44
45
  def _get_cache_key(self, file_path: Union[str, Path]) -> str:
45
46
  """Generate a cache key for a configuration file."""
46
47
  path = Path(file_path)
47
48
  stat = path.stat()
48
49
  return f"{path.absolute()}:{stat.st_mtime}:{stat.st_size}"
49
-
50
+
50
51
  def _check_cache(self, file_path: Union[str, Path]) -> Optional[Dict[str, Any]]:
51
52
  """Check if configuration is cached and still valid."""
52
53
  if not self.cache_enabled:
53
54
  return None
54
-
55
+
55
56
  try:
56
57
  cache_key = self._get_cache_key(file_path)
57
58
  return self._cache.get(cache_key)
58
59
  except (OSError, IOError):
59
60
  return None
60
-
61
+
61
62
  def _update_cache(self, file_path: Union[str, Path], config: Dict[str, Any]):
62
63
  """Update the configuration cache."""
63
64
  if not self.cache_enabled:
64
65
  return
65
-
66
+
66
67
  try:
67
68
  cache_key = self._get_cache_key(file_path)
68
69
  self._cache[cache_key] = config
69
70
  except (OSError, IOError):
70
71
  pass
71
-
72
+
72
73
  def clear_cache(self):
73
74
  """Clear the configuration cache."""
74
75
  self._cache.clear()
75
-
76
+
76
77
  def load_json(self, file_path: Union[str, Path]) -> Dict[str, Any]:
77
78
  """Load JSON configuration file.
78
-
79
+
79
80
  Args:
80
81
  file_path: Path to JSON file
81
-
82
+
82
83
  Returns:
83
84
  Configuration dictionary
84
-
85
+
85
86
  Raises:
86
87
  FileNotFoundError: If file doesn't exist
87
88
  json.JSONDecodeError: If JSON is invalid
88
89
  """
89
90
  file_path = Path(file_path)
90
-
91
+
91
92
  # Check cache
92
93
  cached = self._check_cache(file_path)
93
94
  if cached is not None:
94
95
  logger.debug(f"Using cached configuration for {file_path}")
95
96
  return cached
96
-
97
+
97
98
  if not file_path.exists():
98
99
  raise FileNotFoundError(f"Configuration file not found: {file_path}")
99
-
100
+
100
101
  logger.debug(f"Loading JSON configuration from {file_path}")
101
102
  try:
102
- with open(file_path, 'r', encoding='utf-8') as f:
103
+ with open(file_path, "r", encoding="utf-8") as f:
103
104
  config = json.load(f)
104
105
  self._update_cache(file_path, config)
105
106
  return config
@@ -109,38 +110,40 @@ class ConfigurationManager:
109
110
  except Exception as e:
110
111
  logger.error(f"Error loading JSON from {file_path}: {e}")
111
112
  raise
112
-
113
+
113
114
  def load_yaml(self, file_path: Union[str, Path]) -> Dict[str, Any]:
114
115
  """Load YAML configuration file.
115
-
116
+
116
117
  Args:
117
118
  file_path: Path to YAML file
118
-
119
+
119
120
  Returns:
120
121
  Configuration dictionary
121
-
122
+
122
123
  Raises:
123
124
  ImportError: If PyYAML is not installed
124
125
  FileNotFoundError: If file doesn't exist
125
126
  yaml.YAMLError: If YAML is invalid
126
127
  """
127
128
  if not HAS_YAML:
128
- raise ImportError("PyYAML is required for YAML support. Install with: pip install pyyaml")
129
-
129
+ raise ImportError(
130
+ "PyYAML is required for YAML support. Install with: pip install pyyaml"
131
+ )
132
+
130
133
  file_path = Path(file_path)
131
-
134
+
132
135
  # Check cache
133
136
  cached = self._check_cache(file_path)
134
137
  if cached is not None:
135
138
  logger.debug(f"Using cached configuration for {file_path}")
136
139
  return cached
137
-
140
+
138
141
  if not file_path.exists():
139
142
  raise FileNotFoundError(f"Configuration file not found: {file_path}")
140
-
143
+
141
144
  logger.debug(f"Loading YAML configuration from {file_path}")
142
145
  try:
143
- with open(file_path, 'r', encoding='utf-8') as f:
146
+ with open(file_path, "r", encoding="utf-8") as f:
144
147
  config = yaml.safe_load(f) or {}
145
148
  self._update_cache(file_path, config)
146
149
  return config
@@ -150,38 +153,40 @@ class ConfigurationManager:
150
153
  except Exception as e:
151
154
  logger.error(f"Error loading YAML from {file_path}: {e}")
152
155
  raise
153
-
156
+
154
157
  def load_toml(self, file_path: Union[str, Path]) -> Dict[str, Any]:
155
158
  """Load TOML configuration file.
156
-
159
+
157
160
  Args:
158
161
  file_path: Path to TOML file
159
-
162
+
160
163
  Returns:
161
164
  Configuration dictionary
162
-
165
+
163
166
  Raises:
164
167
  ImportError: If toml is not installed
165
168
  FileNotFoundError: If file doesn't exist
166
169
  toml.TomlDecodeError: If TOML is invalid
167
170
  """
168
171
  if not HAS_TOML:
169
- raise ImportError("toml is required for TOML support. Install with: pip install toml")
170
-
172
+ raise ImportError(
173
+ "toml is required for TOML support. Install with: pip install toml"
174
+ )
175
+
171
176
  file_path = Path(file_path)
172
-
177
+
173
178
  # Check cache
174
179
  cached = self._check_cache(file_path)
175
180
  if cached is not None:
176
181
  logger.debug(f"Using cached configuration for {file_path}")
177
182
  return cached
178
-
183
+
179
184
  if not file_path.exists():
180
185
  raise FileNotFoundError(f"Configuration file not found: {file_path}")
181
-
186
+
182
187
  logger.debug(f"Loading TOML configuration from {file_path}")
183
188
  try:
184
- with open(file_path, 'r', encoding='utf-8') as f:
189
+ with open(file_path, "r", encoding="utf-8") as f:
185
190
  config = toml.load(f)
186
191
  self._update_cache(file_path, config)
187
192
  return config
@@ -191,36 +196,41 @@ class ConfigurationManager:
191
196
  except Exception as e:
192
197
  logger.error(f"Error loading TOML from {file_path}: {e}")
193
198
  raise
194
-
199
+
195
200
  def load_auto(self, file_path: Union[str, Path]) -> Dict[str, Any]:
196
201
  """Auto-detect format and load configuration file.
197
-
202
+
198
203
  Args:
199
204
  file_path: Path to configuration file
200
-
205
+
201
206
  Returns:
202
207
  Configuration dictionary
203
-
208
+
204
209
  Raises:
205
210
  ValueError: If file format is not supported
206
211
  FileNotFoundError: If file doesn't exist
207
212
  """
208
213
  file_path = Path(file_path)
209
214
  suffix = file_path.suffix.lower()
210
-
211
- if suffix in ['.json']:
215
+
216
+ if suffix in [".json"]:
212
217
  return self.load_json(file_path)
213
- elif suffix in ['.yaml', '.yml']:
218
+ elif suffix in [".yaml", ".yml"]:
214
219
  return self.load_yaml(file_path)
215
- elif suffix in ['.toml']:
220
+ elif suffix in [".toml"]:
216
221
  return self.load_toml(file_path)
217
222
  else:
218
223
  raise ValueError(f"Unsupported configuration format: {suffix}")
219
-
220
- def save_json(self, config: Dict[str, Any], file_path: Union[str, Path],
221
- indent: int = 2, sort_keys: bool = True):
224
+
225
+ def save_json(
226
+ self,
227
+ config: Dict[str, Any],
228
+ file_path: Union[str, Path],
229
+ indent: int = 2,
230
+ sort_keys: bool = True,
231
+ ):
222
232
  """Save configuration as JSON.
223
-
233
+
224
234
  Args:
225
235
  config: Configuration dictionary
226
236
  file_path: Path to save JSON file
@@ -229,113 +239,132 @@ class ConfigurationManager:
229
239
  """
230
240
  file_path = Path(file_path)
231
241
  logger.debug(f"Saving JSON configuration to {file_path}")
232
-
242
+
233
243
  try:
234
244
  # Create parent directories if needed
235
245
  file_path.parent.mkdir(parents=True, exist_ok=True)
236
-
237
- with open(file_path, 'w', encoding='utf-8') as f:
246
+
247
+ with open(file_path, "w", encoding="utf-8") as f:
238
248
  json.dump(config, f, indent=indent, sort_keys=sort_keys)
239
249
  logger.info(f"Configuration saved to {file_path}")
240
250
  except Exception as e:
241
251
  logger.error(f"Error saving JSON to {file_path}: {e}")
242
252
  raise
243
-
244
- def save_yaml(self, config: Dict[str, Any], file_path: Union[str, Path],
245
- default_flow_style: bool = False, sort_keys: bool = True):
253
+
254
+ def save_yaml(
255
+ self,
256
+ config: Dict[str, Any],
257
+ file_path: Union[str, Path],
258
+ default_flow_style: bool = False,
259
+ sort_keys: bool = True,
260
+ ):
246
261
  """Save configuration as YAML.
247
-
262
+
248
263
  Args:
249
264
  config: Configuration dictionary
250
265
  file_path: Path to save YAML file
251
266
  default_flow_style: Use flow style (default: False)
252
267
  sort_keys: Whether to sort keys (default: True)
253
-
268
+
254
269
  Raises:
255
270
  ImportError: If PyYAML is not installed
256
271
  """
257
272
  if not HAS_YAML:
258
- raise ImportError("PyYAML is required for YAML support. Install with: pip install pyyaml")
259
-
273
+ raise ImportError(
274
+ "PyYAML is required for YAML support. Install with: pip install pyyaml"
275
+ )
276
+
260
277
  file_path = Path(file_path)
261
278
  logger.debug(f"Saving YAML configuration to {file_path}")
262
-
279
+
263
280
  try:
264
281
  # Create parent directories if needed
265
282
  file_path.parent.mkdir(parents=True, exist_ok=True)
266
-
267
- with open(file_path, 'w', encoding='utf-8') as f:
268
- yaml.dump(config, f, default_flow_style=default_flow_style,
269
- sort_keys=sort_keys)
283
+
284
+ with open(file_path, "w", encoding="utf-8") as f:
285
+ yaml.dump(
286
+ config,
287
+ f,
288
+ default_flow_style=default_flow_style,
289
+ sort_keys=sort_keys,
290
+ )
270
291
  logger.info(f"Configuration saved to {file_path}")
271
292
  except Exception as e:
272
293
  logger.error(f"Error saving YAML to {file_path}: {e}")
273
294
  raise
274
-
295
+
275
296
  def save_toml(self, config: Dict[str, Any], file_path: Union[str, Path]):
276
297
  """Save configuration as TOML.
277
-
298
+
278
299
  Args:
279
300
  config: Configuration dictionary
280
301
  file_path: Path to save TOML file
281
-
302
+
282
303
  Raises:
283
304
  ImportError: If toml is not installed
284
305
  """
285
306
  if not HAS_TOML:
286
- raise ImportError("toml is required for TOML support. Install with: pip install toml")
287
-
307
+ raise ImportError(
308
+ "toml is required for TOML support. Install with: pip install toml"
309
+ )
310
+
288
311
  file_path = Path(file_path)
289
312
  logger.debug(f"Saving TOML configuration to {file_path}")
290
-
313
+
291
314
  try:
292
315
  # Create parent directories if needed
293
316
  file_path.parent.mkdir(parents=True, exist_ok=True)
294
-
295
- with open(file_path, 'w', encoding='utf-8') as f:
317
+
318
+ with open(file_path, "w", encoding="utf-8") as f:
296
319
  toml.dump(config, f)
297
320
  logger.info(f"Configuration saved to {file_path}")
298
321
  except Exception as e:
299
322
  logger.error(f"Error saving TOML to {file_path}: {e}")
300
323
  raise
301
-
324
+
302
325
  def merge_configs(self, *configs: Dict[str, Any]) -> Dict[str, Any]:
303
326
  """Merge multiple configurations.
304
-
327
+
305
328
  Later configurations override earlier ones. Nested dictionaries
306
329
  are merged recursively.
307
-
330
+
308
331
  Args:
309
332
  *configs: Configuration dictionaries to merge
310
-
333
+
311
334
  Returns:
312
335
  Merged configuration dictionary
313
336
  """
314
337
  result = {}
315
-
338
+
316
339
  for config in configs:
317
340
  self._deep_merge(result, config)
318
-
341
+
319
342
  return result
320
-
343
+
321
344
  def _deep_merge(self, target: Dict[str, Any], source: Dict[str, Any]):
322
345
  """Deep merge source into target dictionary."""
323
346
  for key, value in source.items():
324
- if key in target and isinstance(target[key], dict) and isinstance(value, dict):
347
+ if (
348
+ key in target
349
+ and isinstance(target[key], dict)
350
+ and isinstance(value, dict)
351
+ ):
325
352
  self._deep_merge(target[key], value)
326
353
  else:
327
354
  target[key] = value
328
-
329
- def validate_schema(self, config: Dict[str, Any], schema: Dict[str, Any]) -> List[str]:
355
+
356
+ def validate_schema(
357
+ self, config: Dict[str, Any], schema: Dict[str, Any]
358
+ ) -> List[str]:
330
359
  """Validate configuration against a schema.
331
-
360
+
332
361
  Args:
333
362
  config: Configuration to validate
334
363
  schema: Schema dictionary defining required fields and types
335
-
364
+
336
365
  Returns:
337
366
  List of validation errors (empty if valid)
338
-
367
+
339
368
  Example schema:
340
369
  {
341
370
  "required": ["field1", "field2"],
@@ -347,13 +376,13 @@ class ConfigurationManager:
347
376
  }
348
377
  """
349
378
  errors = []
350
-
379
+
351
380
  # Check required fields
352
381
  required = schema.get("required", [])
353
382
  for field in required:
354
383
  if field not in config:
355
384
  errors.append(f"Required field missing: {field}")
356
-
385
+
357
386
  # Check types
358
387
  types = schema.get("types", {})
359
388
  for field, expected_type in types.items():
@@ -361,68 +390,76 @@ class ConfigurationManager:
361
390
  if not isinstance(config[field], expected_type):
362
391
  actual_type = type(config[field]).__name__
363
392
  expected_name = expected_type.__name__
364
- errors.append(f"Invalid type for {field}: expected {expected_name}, got {actual_type}")
365
-
393
+ errors.append(
394
+ f"Invalid type for {field}: expected {expected_name}, got {actual_type}"
395
+ )
396
+
366
397
  return errors
367
-
368
- def get_with_default(self, config: Dict[str, Any], key: str,
369
- default: Any = None, separator: str = ".") -> Any:
398
+
399
+ def get_with_default(
400
+ self,
401
+ config: Dict[str, Any],
402
+ key: str,
403
+ default: Any = None,
404
+ separator: str = ".",
405
+ ) -> Any:
370
406
  """Get configuration value with default fallback.
371
-
407
+
372
408
  Supports nested keys using dot notation.
373
-
409
+
374
410
  Args:
375
411
  config: Configuration dictionary
376
412
  key: Key to retrieve (supports dot notation for nested keys)
377
413
  default: Default value if key not found
378
414
  separator: Key separator for nested access (default: ".")
379
-
415
+
380
416
  Returns:
381
417
  Configuration value or default
382
-
418
+
383
419
  Example:
384
420
  get_with_default(config, "database.host", "localhost")
385
421
  """
386
422
  keys = key.split(separator)
387
423
  value = config
388
-
424
+
389
425
  for k in keys:
390
426
  if isinstance(value, dict) and k in value:
391
427
  value = value[k]
392
428
  else:
393
429
  return default
394
-
430
+
395
431
  return value
396
-
397
- def interpolate_env(self, config: Dict[str, Any],
398
- pattern: str = "${%s}") -> Dict[str, Any]:
432
+
433
+ def interpolate_env(
434
+ self, config: Dict[str, Any], pattern: str = "${%s}"
435
+ ) -> Dict[str, Any]:
399
436
  """Interpolate environment variables in configuration.
400
-
437
+
401
438
  Args:
402
439
  config: Configuration dictionary
403
440
  pattern: Pattern for environment variables (default: "${VAR}")
404
-
441
+
405
442
  Returns:
406
443
  Configuration with environment variables interpolated
407
-
444
+
408
445
  Example:
409
446
  Input: {"host": "${DB_HOST}", "port": "${DB_PORT}"}
410
447
  Output: {"host": "localhost", "port": "5432"}
411
448
  """
412
449
  import re
413
-
450
+
414
451
  def _interpolate_value(value: Any) -> Any:
415
452
  if isinstance(value, str):
416
453
  # Find all environment variable references
417
454
  env_pattern = pattern.replace("%s", r"([A-Z_][A-Z0-9_]*)")
418
455
  matches = re.findall(env_pattern, value)
419
-
456
+
420
457
  result = value
421
458
  for var_name in matches:
422
459
  env_value = os.environ.get(var_name, "")
423
460
  placeholder = pattern % var_name
424
461
  result = result.replace(placeholder, env_value)
425
-
462
+
426
463
  return result
427
464
  elif isinstance(value, dict):
428
465
  return {k: _interpolate_value(v) for k, v in value.items()}
@@ -430,39 +467,41 @@ class ConfigurationManager:
430
467
  return [_interpolate_value(item) for item in value]
431
468
  else:
432
469
  return value
433
-
470
+
434
471
  return _interpolate_value(config)
435
472
 
436
473
 
437
474
  # Convenience functions
438
475
  _default_manager = ConfigurationManager()
439
476
 
477
+
440
478
  def load_config(file_path: Union[str, Path]) -> Dict[str, Any]:
441
479
  """Load configuration file with auto-detection.
442
-
480
+
443
481
  Args:
444
482
  file_path: Path to configuration file
445
-
483
+
446
484
  Returns:
447
485
  Configuration dictionary
448
486
  """
449
487
  return _default_manager.load_auto(file_path)
450
-
488
+
489
+
451
490
  def save_config(config: Dict[str, Any], file_path: Union[str, Path]):
452
491
  """Save configuration file with auto-detection.
453
-
492
+
454
493
  Args:
455
494
  config: Configuration dictionary
456
495
  file_path: Path to save configuration
457
496
  """
458
497
  file_path = Path(file_path)
459
498
  suffix = file_path.suffix.lower()
460
-
461
- if suffix in ['.json']:
499
+
500
+ if suffix in [".json"]:
462
501
  _default_manager.save_json(config, file_path)
463
- elif suffix in ['.yaml', '.yml']:
502
+ elif suffix in [".yaml", ".yml"]:
464
503
  _default_manager.save_yaml(config, file_path)
465
- elif suffix in ['.toml']:
504
+ elif suffix in [".toml"]:
466
505
  _default_manager.save_toml(config, file_path)
467
506
  else:
468
- raise ValueError(f"Unsupported configuration format: {suffix}")
507
+ raise ValueError(f"Unsupported configuration format: {suffix}")
@@ -8,4 +8,4 @@ Uses rich for enhanced formatting and color support.
8
8
  from rich.console import Console
9
9
 
10
10
  # Global console instance for consistent formatting
11
- console = Console()
11
+ console = Console()