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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (357) hide show
  1. claude_mpm/BUILD_NUMBER +1 -1
  2. claude_mpm/VERSION +1 -1
  3. claude_mpm/__main__.py +1 -1
  4. claude_mpm/agents/BASE_PM.md +74 -46
  5. claude_mpm/agents/INSTRUCTIONS.md +11 -153
  6. claude_mpm/agents/WORKFLOW.md +61 -321
  7. claude_mpm/agents/__init__.py +11 -11
  8. claude_mpm/agents/agent_loader.py +23 -20
  9. claude_mpm/agents/agent_loader_integration.py +1 -1
  10. claude_mpm/agents/agents_metadata.py +27 -0
  11. claude_mpm/agents/async_agent_loader.py +5 -8
  12. claude_mpm/agents/base_agent_loader.py +36 -25
  13. claude_mpm/agents/frontmatter_validator.py +6 -6
  14. claude_mpm/agents/schema/agent_schema.json +1 -1
  15. claude_mpm/agents/system_agent_config.py +9 -9
  16. claude_mpm/agents/templates/api_qa.json +47 -2
  17. claude_mpm/agents/templates/imagemagick.json +256 -0
  18. claude_mpm/agents/templates/qa.json +41 -2
  19. claude_mpm/agents/templates/ticketing.json +5 -5
  20. claude_mpm/agents/templates/web_qa.json +50 -2
  21. claude_mpm/cli/__init__.py +51 -46
  22. claude_mpm/cli/__main__.py +1 -1
  23. claude_mpm/cli/commands/__init__.py +10 -12
  24. claude_mpm/cli/commands/agent_manager.py +186 -181
  25. claude_mpm/cli/commands/agents.py +271 -268
  26. claude_mpm/cli/commands/aggregate.py +30 -29
  27. claude_mpm/cli/commands/cleanup.py +50 -44
  28. claude_mpm/cli/commands/cleanup_orphaned_agents.py +25 -25
  29. claude_mpm/cli/commands/config.py +162 -127
  30. claude_mpm/cli/commands/doctor.py +52 -62
  31. claude_mpm/cli/commands/info.py +37 -25
  32. claude_mpm/cli/commands/mcp.py +3 -7
  33. claude_mpm/cli/commands/mcp_command_router.py +14 -18
  34. claude_mpm/cli/commands/mcp_install_commands.py +28 -23
  35. claude_mpm/cli/commands/mcp_pipx_config.py +58 -49
  36. claude_mpm/cli/commands/mcp_server_commands.py +23 -17
  37. claude_mpm/cli/commands/memory.py +192 -141
  38. claude_mpm/cli/commands/monitor.py +117 -88
  39. claude_mpm/cli/commands/run.py +120 -84
  40. claude_mpm/cli/commands/run_config_checker.py +4 -5
  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 +204 -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 +20 -23
  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 +581 -280
  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 -15
  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 +93 -38
  114. claude_mpm/hooks/claude_hooks/hook_handler.py +130 -76
  115. claude_mpm/hooks/claude_hooks/hook_handler_eventbus.py +104 -77
  116. claude_mpm/hooks/claude_hooks/memory_integration.py +2 -4
  117. claude_mpm/hooks/claude_hooks/response_tracking.py +15 -11
  118. claude_mpm/hooks/claude_hooks/tool_analysis.py +12 -18
  119. claude_mpm/hooks/memory_integration_hook.py +5 -5
  120. claude_mpm/hooks/tool_call_interceptor.py +1 -1
  121. claude_mpm/hooks/validation_hooks.py +4 -4
  122. claude_mpm/init.py +4 -9
  123. claude_mpm/models/__init__.py +2 -2
  124. claude_mpm/models/agent_session.py +11 -14
  125. claude_mpm/scripts/mcp_server.py +20 -11
  126. claude_mpm/scripts/mcp_wrapper.py +5 -5
  127. claude_mpm/scripts/mpm_doctor.py +321 -0
  128. claude_mpm/scripts/socketio_daemon.py +28 -25
  129. claude_mpm/scripts/socketio_daemon_hardened.py +298 -258
  130. claude_mpm/scripts/socketio_server_manager.py +116 -95
  131. claude_mpm/services/__init__.py +49 -49
  132. claude_mpm/services/agent_capabilities_service.py +12 -18
  133. claude_mpm/services/agents/__init__.py +22 -22
  134. claude_mpm/services/agents/agent_builder.py +140 -119
  135. claude_mpm/services/agents/deployment/__init__.py +3 -3
  136. claude_mpm/services/agents/deployment/agent_config_provider.py +9 -9
  137. claude_mpm/services/agents/deployment/agent_configuration_manager.py +19 -20
  138. claude_mpm/services/agents/deployment/agent_definition_factory.py +1 -5
  139. claude_mpm/services/agents/deployment/agent_deployment.py +136 -106
  140. claude_mpm/services/agents/deployment/agent_discovery_service.py +4 -8
  141. claude_mpm/services/agents/deployment/agent_environment_manager.py +2 -7
  142. claude_mpm/services/agents/deployment/agent_filesystem_manager.py +6 -10
  143. claude_mpm/services/agents/deployment/agent_format_converter.py +11 -15
  144. claude_mpm/services/agents/deployment/agent_frontmatter_validator.py +2 -3
  145. claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +5 -5
  146. claude_mpm/services/agents/deployment/agent_metrics_collector.py +13 -19
  147. claude_mpm/services/agents/deployment/agent_restore_handler.py +0 -1
  148. claude_mpm/services/agents/deployment/agent_template_builder.py +26 -35
  149. claude_mpm/services/agents/deployment/agent_validator.py +0 -1
  150. claude_mpm/services/agents/deployment/agent_version_manager.py +7 -9
  151. claude_mpm/services/agents/deployment/agent_versioning.py +3 -3
  152. claude_mpm/services/agents/deployment/agents_directory_resolver.py +6 -7
  153. claude_mpm/services/agents/deployment/async_agent_deployment.py +51 -38
  154. claude_mpm/services/agents/deployment/config/__init__.py +1 -1
  155. claude_mpm/services/agents/deployment/config/deployment_config.py +7 -8
  156. claude_mpm/services/agents/deployment/deployment_type_detector.py +1 -1
  157. claude_mpm/services/agents/deployment/deployment_wrapper.py +18 -18
  158. claude_mpm/services/agents/deployment/facade/__init__.py +1 -1
  159. claude_mpm/services/agents/deployment/facade/deployment_executor.py +0 -3
  160. claude_mpm/services/agents/deployment/facade/deployment_facade.py +3 -4
  161. claude_mpm/services/agents/deployment/interface_adapter.py +5 -7
  162. claude_mpm/services/agents/deployment/multi_source_deployment_service.py +345 -276
  163. claude_mpm/services/agents/deployment/pipeline/__init__.py +2 -2
  164. claude_mpm/services/agents/deployment/pipeline/pipeline_builder.py +1 -1
  165. claude_mpm/services/agents/deployment/pipeline/pipeline_context.py +6 -4
  166. claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +3 -3
  167. claude_mpm/services/agents/deployment/pipeline/steps/__init__.py +2 -2
  168. claude_mpm/services/agents/deployment/pipeline/steps/agent_processing_step.py +14 -13
  169. claude_mpm/services/agents/deployment/pipeline/steps/base_step.py +0 -1
  170. claude_mpm/services/agents/deployment/pipeline/steps/configuration_step.py +1 -1
  171. claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +8 -9
  172. claude_mpm/services/agents/deployment/pipeline/steps/validation_step.py +1 -1
  173. claude_mpm/services/agents/deployment/processors/__init__.py +1 -1
  174. claude_mpm/services/agents/deployment/processors/agent_processor.py +20 -16
  175. claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +5 -12
  176. claude_mpm/services/agents/deployment/results/__init__.py +1 -1
  177. claude_mpm/services/agents/deployment/results/deployment_result_builder.py +1 -1
  178. claude_mpm/services/agents/deployment/strategies/__init__.py +2 -2
  179. claude_mpm/services/agents/deployment/strategies/base_strategy.py +1 -7
  180. claude_mpm/services/agents/deployment/strategies/project_strategy.py +1 -4
  181. claude_mpm/services/agents/deployment/strategies/system_strategy.py +2 -3
  182. claude_mpm/services/agents/deployment/strategies/user_strategy.py +3 -7
  183. claude_mpm/services/agents/deployment/validation/__init__.py +1 -1
  184. claude_mpm/services/agents/deployment/validation/agent_validator.py +1 -1
  185. claude_mpm/services/agents/deployment/validation/template_validator.py +2 -2
  186. claude_mpm/services/agents/deployment/validation/validation_result.py +2 -6
  187. claude_mpm/services/agents/loading/__init__.py +1 -1
  188. claude_mpm/services/agents/loading/agent_profile_loader.py +6 -12
  189. claude_mpm/services/agents/loading/base_agent_manager.py +5 -5
  190. claude_mpm/services/agents/loading/framework_agent_loader.py +2 -4
  191. claude_mpm/services/agents/management/__init__.py +1 -1
  192. claude_mpm/services/agents/management/agent_capabilities_generator.py +1 -3
  193. claude_mpm/services/agents/management/agent_management_service.py +5 -9
  194. claude_mpm/services/agents/memory/__init__.py +4 -4
  195. claude_mpm/services/agents/memory/agent_memory_manager.py +280 -160
  196. claude_mpm/services/agents/memory/agent_persistence_service.py +0 -2
  197. claude_mpm/services/agents/memory/content_manager.py +44 -38
  198. claude_mpm/services/agents/memory/template_generator.py +4 -6
  199. claude_mpm/services/agents/registry/__init__.py +10 -6
  200. claude_mpm/services/agents/registry/deployed_agent_discovery.py +30 -27
  201. claude_mpm/services/agents/registry/modification_tracker.py +3 -6
  202. claude_mpm/services/async_session_logger.py +1 -2
  203. claude_mpm/services/claude_session_logger.py +1 -2
  204. claude_mpm/services/command_deployment_service.py +173 -0
  205. claude_mpm/services/command_handler_service.py +20 -22
  206. claude_mpm/services/core/__init__.py +25 -25
  207. claude_mpm/services/core/base.py +0 -5
  208. claude_mpm/services/core/interfaces/__init__.py +32 -32
  209. claude_mpm/services/core/interfaces/agent.py +0 -21
  210. claude_mpm/services/core/interfaces/communication.py +0 -27
  211. claude_mpm/services/core/interfaces/infrastructure.py +0 -56
  212. claude_mpm/services/core/interfaces/service.py +0 -29
  213. claude_mpm/services/diagnostics/__init__.py +1 -1
  214. claude_mpm/services/diagnostics/checks/__init__.py +6 -6
  215. claude_mpm/services/diagnostics/checks/agent_check.py +89 -80
  216. claude_mpm/services/diagnostics/checks/base_check.py +12 -16
  217. claude_mpm/services/diagnostics/checks/claude_desktop_check.py +84 -81
  218. claude_mpm/services/diagnostics/checks/common_issues_check.py +99 -91
  219. claude_mpm/services/diagnostics/checks/configuration_check.py +82 -77
  220. claude_mpm/services/diagnostics/checks/filesystem_check.py +67 -68
  221. claude_mpm/services/diagnostics/checks/installation_check.py +254 -94
  222. claude_mpm/services/diagnostics/checks/mcp_check.py +90 -88
  223. claude_mpm/services/diagnostics/checks/monitor_check.py +75 -76
  224. claude_mpm/services/diagnostics/checks/startup_log_check.py +67 -73
  225. claude_mpm/services/diagnostics/diagnostic_runner.py +67 -59
  226. claude_mpm/services/diagnostics/doctor_reporter.py +107 -70
  227. claude_mpm/services/diagnostics/models.py +21 -19
  228. claude_mpm/services/event_aggregator.py +10 -17
  229. claude_mpm/services/event_bus/__init__.py +1 -1
  230. claude_mpm/services/event_bus/config.py +54 -35
  231. claude_mpm/services/event_bus/event_bus.py +76 -71
  232. claude_mpm/services/event_bus/relay.py +74 -64
  233. claude_mpm/services/events/__init__.py +11 -11
  234. claude_mpm/services/events/consumers/__init__.py +3 -3
  235. claude_mpm/services/events/consumers/dead_letter.py +71 -63
  236. claude_mpm/services/events/consumers/logging.py +39 -37
  237. claude_mpm/services/events/consumers/metrics.py +56 -57
  238. claude_mpm/services/events/consumers/socketio.py +82 -81
  239. claude_mpm/services/events/core.py +110 -99
  240. claude_mpm/services/events/interfaces.py +56 -72
  241. claude_mpm/services/events/producers/__init__.py +1 -1
  242. claude_mpm/services/events/producers/hook.py +38 -38
  243. claude_mpm/services/events/producers/system.py +46 -44
  244. claude_mpm/services/exceptions.py +81 -80
  245. claude_mpm/services/framework_claude_md_generator/__init__.py +2 -4
  246. claude_mpm/services/framework_claude_md_generator/content_assembler.py +3 -5
  247. claude_mpm/services/framework_claude_md_generator/content_validator.py +1 -1
  248. claude_mpm/services/framework_claude_md_generator/deployment_manager.py +4 -4
  249. claude_mpm/services/framework_claude_md_generator/section_generators/__init__.py +0 -1
  250. claude_mpm/services/framework_claude_md_generator/section_generators/agents.py +0 -2
  251. claude_mpm/services/framework_claude_md_generator/version_manager.py +4 -5
  252. claude_mpm/services/hook_service.py +6 -9
  253. claude_mpm/services/infrastructure/__init__.py +1 -1
  254. claude_mpm/services/infrastructure/context_preservation.py +8 -12
  255. claude_mpm/services/infrastructure/monitoring.py +21 -23
  256. claude_mpm/services/mcp_gateway/__init__.py +37 -37
  257. claude_mpm/services/mcp_gateway/auto_configure.py +95 -103
  258. claude_mpm/services/mcp_gateway/config/__init__.py +1 -1
  259. claude_mpm/services/mcp_gateway/config/config_loader.py +23 -25
  260. claude_mpm/services/mcp_gateway/config/config_schema.py +5 -5
  261. claude_mpm/services/mcp_gateway/config/configuration.py +9 -6
  262. claude_mpm/services/mcp_gateway/core/__init__.py +10 -10
  263. claude_mpm/services/mcp_gateway/core/base.py +0 -3
  264. claude_mpm/services/mcp_gateway/core/interfaces.py +1 -38
  265. claude_mpm/services/mcp_gateway/core/process_pool.py +99 -93
  266. claude_mpm/services/mcp_gateway/core/singleton_manager.py +65 -62
  267. claude_mpm/services/mcp_gateway/core/startup_verification.py +75 -74
  268. claude_mpm/services/mcp_gateway/main.py +2 -1
  269. claude_mpm/services/mcp_gateway/registry/service_registry.py +5 -8
  270. claude_mpm/services/mcp_gateway/registry/tool_registry.py +1 -1
  271. claude_mpm/services/mcp_gateway/server/__init__.py +1 -1
  272. claude_mpm/services/mcp_gateway/server/mcp_gateway.py +12 -19
  273. claude_mpm/services/mcp_gateway/server/stdio_handler.py +4 -3
  274. claude_mpm/services/mcp_gateway/server/stdio_server.py +79 -71
  275. claude_mpm/services/mcp_gateway/tools/__init__.py +2 -2
  276. claude_mpm/services/mcp_gateway/tools/base_adapter.py +5 -6
  277. claude_mpm/services/mcp_gateway/tools/document_summarizer.py +13 -22
  278. claude_mpm/services/mcp_gateway/tools/health_check_tool.py +79 -78
  279. claude_mpm/services/mcp_gateway/tools/hello_world.py +12 -14
  280. claude_mpm/services/mcp_gateway/tools/ticket_tools.py +42 -49
  281. claude_mpm/services/mcp_gateway/tools/unified_ticket_tool.py +51 -55
  282. claude_mpm/services/memory/__init__.py +3 -3
  283. claude_mpm/services/memory/builder.py +3 -6
  284. claude_mpm/services/memory/cache/__init__.py +1 -1
  285. claude_mpm/services/memory/cache/shared_prompt_cache.py +3 -5
  286. claude_mpm/services/memory/cache/simple_cache.py +1 -1
  287. claude_mpm/services/memory/indexed_memory.py +5 -7
  288. claude_mpm/services/memory/optimizer.py +7 -10
  289. claude_mpm/services/memory/router.py +8 -9
  290. claude_mpm/services/memory_hook_service.py +48 -34
  291. claude_mpm/services/monitor_build_service.py +77 -73
  292. claude_mpm/services/port_manager.py +130 -108
  293. claude_mpm/services/project/analyzer.py +12 -10
  294. claude_mpm/services/project/registry.py +11 -11
  295. claude_mpm/services/recovery_manager.py +10 -19
  296. claude_mpm/services/response_tracker.py +0 -1
  297. claude_mpm/services/runner_configuration_service.py +19 -20
  298. claude_mpm/services/session_management_service.py +7 -11
  299. claude_mpm/services/shared/__init__.py +1 -1
  300. claude_mpm/services/shared/async_service_base.py +58 -50
  301. claude_mpm/services/shared/config_service_base.py +73 -67
  302. claude_mpm/services/shared/lifecycle_service_base.py +82 -78
  303. claude_mpm/services/shared/manager_base.py +94 -82
  304. claude_mpm/services/shared/service_factory.py +96 -98
  305. claude_mpm/services/socketio/__init__.py +3 -3
  306. claude_mpm/services/socketio/client_proxy.py +5 -5
  307. claude_mpm/services/socketio/event_normalizer.py +199 -181
  308. claude_mpm/services/socketio/handlers/__init__.py +3 -3
  309. claude_mpm/services/socketio/handlers/base.py +5 -4
  310. claude_mpm/services/socketio/handlers/connection.py +163 -136
  311. claude_mpm/services/socketio/handlers/file.py +13 -14
  312. claude_mpm/services/socketio/handlers/git.py +12 -7
  313. claude_mpm/services/socketio/handlers/hook.py +49 -44
  314. claude_mpm/services/socketio/handlers/memory.py +0 -1
  315. claude_mpm/services/socketio/handlers/project.py +0 -1
  316. claude_mpm/services/socketio/handlers/registry.py +37 -19
  317. claude_mpm/services/socketio/migration_utils.py +98 -84
  318. claude_mpm/services/socketio/server/__init__.py +1 -1
  319. claude_mpm/services/socketio/server/broadcaster.py +81 -87
  320. claude_mpm/services/socketio/server/core.py +65 -54
  321. claude_mpm/services/socketio/server/eventbus_integration.py +95 -56
  322. claude_mpm/services/socketio/server/main.py +64 -38
  323. claude_mpm/services/socketio_client_manager.py +10 -12
  324. claude_mpm/services/subprocess_launcher_service.py +4 -7
  325. claude_mpm/services/system_instructions_service.py +13 -14
  326. claude_mpm/services/ticket_manager.py +2 -2
  327. claude_mpm/services/utility_service.py +5 -13
  328. claude_mpm/services/version_control/__init__.py +16 -16
  329. claude_mpm/services/version_control/branch_strategy.py +5 -8
  330. claude_mpm/services/version_control/conflict_resolution.py +9 -23
  331. claude_mpm/services/version_control/git_operations.py +5 -7
  332. claude_mpm/services/version_control/semantic_versioning.py +16 -17
  333. claude_mpm/services/version_control/version_parser.py +13 -18
  334. claude_mpm/services/version_service.py +10 -11
  335. claude_mpm/storage/__init__.py +1 -1
  336. claude_mpm/storage/state_storage.py +22 -28
  337. claude_mpm/utils/__init__.py +6 -6
  338. claude_mpm/utils/agent_dependency_loader.py +47 -33
  339. claude_mpm/utils/config_manager.py +11 -14
  340. claude_mpm/utils/dependency_cache.py +1 -1
  341. claude_mpm/utils/dependency_manager.py +13 -17
  342. claude_mpm/utils/dependency_strategies.py +8 -10
  343. claude_mpm/utils/environment_context.py +3 -9
  344. claude_mpm/utils/error_handler.py +3 -13
  345. claude_mpm/utils/file_utils.py +1 -1
  346. claude_mpm/utils/path_operations.py +8 -12
  347. claude_mpm/utils/robust_installer.py +110 -33
  348. claude_mpm/utils/subprocess_utils.py +5 -6
  349. claude_mpm/validation/agent_validator.py +3 -6
  350. claude_mpm/validation/frontmatter_validator.py +1 -1
  351. {claude_mpm-4.1.1.dist-info → claude_mpm-4.1.2.dist-info}/METADATA +1 -1
  352. claude_mpm-4.1.2.dist-info/RECORD +498 -0
  353. claude_mpm-4.1.1.dist-info/RECORD +0 -494
  354. {claude_mpm-4.1.1.dist-info → claude_mpm-4.1.2.dist-info}/WHEEL +0 -0
  355. {claude_mpm-4.1.1.dist-info → claude_mpm-4.1.2.dist-info}/entry_points.txt +0 -0
  356. {claude_mpm-4.1.1.dist-info → claude_mpm-4.1.2.dist-info}/licenses/LICENSE +0 -0
  357. {claude_mpm-4.1.1.dist-info → claude_mpm-4.1.2.dist-info}/top_level.txt +0 -0
claude_mpm/cli/utils.py CHANGED
@@ -7,6 +7,7 @@ for common CLI operations.
7
7
  """
8
8
 
9
9
  import sys
10
+ from pathlib import Path
10
11
  from typing import Optional
11
12
 
12
13
  from ..core.logger import get_logger
@@ -37,13 +38,11 @@ def get_user_input(input_arg: Optional[str], logger) -> str:
37
38
  if input_path.exists():
38
39
  logger.info(f"Reading input from file: {input_path}")
39
40
  return input_path.read_text()
40
- else:
41
- logger.info("Using command line input")
42
- return input_arg
43
- else:
44
- # Read from stdin
45
- logger.info("Reading input from stdin")
46
- return sys.stdin.read()
41
+ logger.info("Using command line input")
42
+ return input_arg
43
+ # Read from stdin
44
+ logger.info("Reading input from stdin")
45
+ return sys.stdin.read()
47
46
 
48
47
 
49
48
  def get_agent_versions_display() -> Optional[str]:
@@ -115,7 +114,7 @@ def get_agent_versions_display() -> Optional[str]:
115
114
  output_lines.append(
116
115
  f"\n ⚠️ {len(verification['agents_needing_migration'])} agent(s) need migration to semantic versioning"
117
116
  )
118
- output_lines.append(f" Run 'claude-mpm agents deploy' to update")
117
+ output_lines.append(" Run 'claude-mpm agents deploy' to update")
119
118
 
120
119
  output_lines.append("-" * 40)
121
120
  return "\n".join(output_lines)
@@ -132,16 +131,17 @@ def list_agent_versions_at_startup() -> None:
132
131
 
133
132
  WHY: Users want to see what agents are available when they start a session.
134
133
  This provides immediate feedback about the deployed agent environment.
135
-
134
+
136
135
  DESIGN DECISION: We suppress INFO logging during this call to avoid duplicate
137
136
  initialization messages since the deployment service will be initialized again
138
137
  later in the ClaudeRunner.
139
138
  """
140
139
  # Temporarily suppress INFO level logging to avoid duplicate initialization messages
141
140
  import logging
141
+
142
142
  original_level = logging.getLogger("claude_mpm").level
143
143
  logging.getLogger("claude_mpm").setLevel(logging.WARNING)
144
-
144
+
145
145
  try:
146
146
  agent_versions = get_agent_versions_display()
147
147
  if agent_versions:
@@ -166,7 +166,6 @@ def setup_logging(args) -> object:
166
166
  Logger instance
167
167
  """
168
168
  from ..constants import LogLevel
169
- from ..core.logger import get_logger
170
169
  from ..core.logger import setup_logging as core_setup_logging
171
170
 
172
171
  # Set default logging level if not specified
@@ -9,7 +9,7 @@ from .commands import CommandDefinition, CommandRegistry, register_standard_comm
9
9
 
10
10
  __all__ = [
11
11
  "ArgumentRegistry",
12
- "CommandRegistry",
13
12
  "CommandDefinition",
13
+ "CommandRegistry",
14
14
  "register_standard_commands",
15
15
  ]
@@ -2,7 +2,7 @@
2
2
 
3
3
  import argparse
4
4
  from pathlib import Path
5
- from typing import Any, Callable, Dict, Optional
5
+ from typing import Any, Dict, Optional
6
6
 
7
7
 
8
8
  class ArgumentRegistry:
@@ -6,6 +6,7 @@ from 16 to under 10 by using ArgumentRegistry and CommandRegistry.
6
6
 
7
7
  import argparse
8
8
  import sys
9
+ from typing import Optional
9
10
 
10
11
  from claude_mpm._version import __version__
11
12
  from claude_mpm.cli import ArgumentRegistry, CommandRegistry, register_standard_commands
@@ -115,11 +116,10 @@ def _initialize_hook_service(args):
115
116
  logger.info(f"Hook service started on port {hook_manager.port}")
116
117
  print(f"Hook service started on port {hook_manager.port}")
117
118
  return hook_manager
118
- else:
119
- logger = get_logger("cli")
120
- logger.warning("Failed to start hook service, continuing without hooks")
121
- print("Failed to start hook service, continuing without hooks")
122
- return None
119
+ logger = get_logger("cli")
120
+ logger.warning("Failed to start hook service, continuing without hooks")
121
+ print("Failed to start hook service, continuing without hooks")
122
+ return None
123
123
 
124
124
  except Exception as e:
125
125
  get_logger("cli").warning(
@@ -27,19 +27,19 @@ from .paths import (
27
27
 
28
28
  __all__.extend(
29
29
  [
30
- "paths",
30
+ "AgentConfig",
31
31
  "ClaudeMPMPaths",
32
- "get_project_root",
33
- "get_src_dir",
34
- "get_claude_mpm_dir",
32
+ "ensure_src_in_path",
33
+ "get_agent_config",
35
34
  "get_agents_dir",
36
- "get_services_dir",
35
+ "get_claude_mpm_dir",
37
36
  "get_config_dir",
37
+ "get_project_root",
38
+ "get_services_dir",
39
+ "get_src_dir",
38
40
  "get_version",
39
- "ensure_src_in_path",
40
- "AgentConfig",
41
- "get_agent_config",
42
- "set_agent_config",
41
+ "paths",
43
42
  "reset_agent_config",
43
+ "set_agent_config",
44
44
  ]
45
45
  )
@@ -14,7 +14,6 @@ This module handles:
14
14
  UPDATED: Migrated to use shared ConfigLoader pattern (TSK-0141)
15
15
  """
16
16
 
17
- import json
18
17
  import logging
19
18
  import os
20
19
  from dataclasses import dataclass, field
@@ -22,8 +21,8 @@ from enum import Enum
22
21
  from pathlib import Path
23
22
  from typing import Any, Dict, List, Optional
24
23
 
25
- from claude_mpm.core.unified_paths import get_path_manager
26
24
  from claude_mpm.core.shared.config_loader import ConfigLoader, ConfigPattern
25
+ from claude_mpm.core.unified_paths import get_path_manager
27
26
 
28
27
  logger = logging.getLogger(__name__)
29
28
 
@@ -170,11 +169,13 @@ class AgentConfig:
170
169
  "enable_caching": True,
171
170
  "validate_on_load": True,
172
171
  "strict_validation": False,
173
- "precedence_mode": "override"
174
- }
172
+ "precedence_mode": "override",
173
+ },
175
174
  )
176
175
 
177
- loaded_config = config_loader.load_config(pattern, cache_key=f"agent_{config_file}")
176
+ loaded_config = config_loader.load_config(
177
+ pattern, cache_key=f"agent_{config_file}"
178
+ )
178
179
  data = loaded_config.to_dict()
179
180
 
180
181
  config = cls()
@@ -343,15 +344,15 @@ class AgentConfig:
343
344
  def to_dict(self) -> Dict[str, Any]:
344
345
  """Convert configuration to dictionary for serialization."""
345
346
  return {
346
- "project_agents_dir": str(self.project_agents_dir)
347
- if self.project_agents_dir
348
- else None,
349
- "user_agents_dir": str(self.user_agents_dir)
350
- if self.user_agents_dir
351
- else None,
352
- "system_agents_dir": str(self.system_agents_dir)
353
- if self.system_agents_dir
354
- else None,
347
+ "project_agents_dir": (
348
+ str(self.project_agents_dir) if self.project_agents_dir else None
349
+ ),
350
+ "user_agents_dir": (
351
+ str(self.user_agents_dir) if self.user_agents_dir else None
352
+ ),
353
+ "system_agents_dir": (
354
+ str(self.system_agents_dir) if self.system_agents_dir else None
355
+ ),
355
356
  "additional_paths": [str(p) for p in self.additional_paths],
356
357
  "precedence_mode": self.precedence_mode.value,
357
358
  "enable_project_agents": self.enable_project_agents,
@@ -12,7 +12,7 @@ gradual rollout of experimental features while maintaining stability in producti
12
12
 
13
13
  import json
14
14
  import os
15
- from typing import Any, Dict, Optional
15
+ from typing import Dict, Optional
16
16
 
17
17
 
18
18
  class ExperimentalFeatures:
@@ -64,7 +64,7 @@ class ExperimentalFeatures:
64
64
  """
65
65
  if self._config_file and self._config_file.exists():
66
66
  try:
67
- with open(self._config_file, "r") as f:
67
+ with open(self._config_file) as f:
68
68
  config = json.load(f)
69
69
  experimental = config.get("experimental_features", {})
70
70
  self._features.update(experimental)
@@ -125,7 +125,7 @@ class ExperimentalFeatures:
125
125
  accepted_file = Path.home() / ".claude-mpm" / ".experimental_accepted"
126
126
  if accepted_file.exists():
127
127
  try:
128
- with open(accepted_file, "r") as f:
128
+ with open(accepted_file) as f:
129
129
  accepted = json.load(f)
130
130
  if feature in accepted.get("features", []):
131
131
  return False
@@ -148,7 +148,7 @@ class ExperimentalFeatures:
148
148
 
149
149
  try:
150
150
  if accepted_file.exists():
151
- with open(accepted_file, "r") as f:
151
+ with open(accepted_file) as f:
152
152
  data = json.load(f)
153
153
  else:
154
154
  data = {"features": [], "timestamp": {}}
@@ -9,7 +9,6 @@ without fragile parent.parent.parent patterns.
9
9
  """
10
10
 
11
11
  import logging
12
- import sys
13
12
  from pathlib import Path
14
13
  from typing import Optional, Union
15
14
 
@@ -180,7 +180,7 @@ class ConfigManager:
180
180
  # Default to development
181
181
  return "development"
182
182
 
183
- def get_config(self, environment: str = None) -> SocketIOConfig:
183
+ def get_config(self, environment: Optional[str] = None) -> SocketIOConfig:
184
184
  """Get configuration for the specified environment."""
185
185
  if environment is None:
186
186
  environment = self.detect_environment()
@@ -220,14 +220,14 @@ class ConfigManager:
220
220
  for config_path in self.config_search_paths:
221
221
  if config_path.exists():
222
222
  try:
223
- with open(config_path, "r") as f:
223
+ with open(config_path) as f:
224
224
  return json.load(f)
225
225
  except Exception as e:
226
226
  print(f"Warning: Failed to load config from {config_path}: {e}")
227
227
 
228
228
  return None
229
229
 
230
- def save_config(self, config: SocketIOConfig, path: str = None) -> bool:
230
+ def save_config(self, config: SocketIOConfig, path: Optional[str] = None) -> bool:
231
231
  """Save configuration to file."""
232
232
  import json
233
233
 
@@ -250,7 +250,7 @@ class ConfigManager:
250
250
  _config_manager = ConfigManager()
251
251
 
252
252
 
253
- def get_config(environment: str = None) -> SocketIOConfig:
253
+ def get_config(environment: Optional[str] = None) -> SocketIOConfig:
254
254
  """Get Socket.IO configuration for the current or specified environment."""
255
255
  return _config_manager.get_config(environment)
256
256
 
@@ -266,5 +266,4 @@ def get_discovery_hosts(config: SocketIOConfig) -> List[str]:
266
266
  if config.host == "0.0.0.0":
267
267
  # If server binds to all interfaces, try localhost and 127.0.0.1 for discovery
268
268
  return ["localhost", "127.0.0.1"]
269
- else:
270
- return [config.host, "localhost", "127.0.0.1"]
269
+ return [config.host, "localhost", "127.0.0.1"]
claude_mpm/constants.py CHANGED
@@ -4,7 +4,6 @@ Build number tracking is now enabled for all builds.
4
4
  """
5
5
 
6
6
  from enum import Enum
7
- from pathlib import Path
8
7
 
9
8
 
10
9
  class CLIPrefix(str, Enum):
@@ -20,7 +19,7 @@ class CLIPrefix(str, Enum):
20
19
  """Wrap a flag with the prefix."""
21
20
  if flag.startswith("--"):
22
21
  return f"--mpm:{flag[2:]}"
23
- elif flag.startswith("-"):
22
+ if flag.startswith("-"):
24
23
  return f"-mpm:{flag[1:]}"
25
24
  return self.value + flag
26
25
 
@@ -17,19 +17,19 @@ from .mixins import LoggerMixin
17
17
  from .service_registry import ServiceRegistry, get_service_registry, initialize_services
18
18
 
19
19
  __all__ = [
20
+ "AgentServiceFactory",
20
21
  "ClaudeRunner",
21
- "LoggerMixin",
22
22
  "Config",
23
+ "ConfigurationFactory",
23
24
  "DIContainer",
24
- "ServiceLifetime",
25
- "get_container",
26
- "ServiceRegistry",
27
- "get_service_registry",
28
- "initialize_services",
29
25
  "InjectableService",
26
+ "LoggerMixin",
30
27
  "ServiceFactory",
31
- "AgentServiceFactory",
28
+ "ServiceLifetime",
29
+ "ServiceRegistry",
32
30
  "SessionManagerFactory",
33
- "ConfigurationFactory",
31
+ "get_container",
34
32
  "get_factory_registry",
33
+ "get_service_registry",
34
+ "initialize_services",
35
35
  ]
@@ -1,7 +1,7 @@
1
1
  """Agent name normalization utilities for consistent naming across the system."""
2
2
 
3
3
  import logging
4
- from typing import Dict, Optional
4
+ from typing import Optional
5
5
 
6
6
  logger = logging.getLogger(__name__)
7
7
 
@@ -11,8 +11,8 @@ This module provides:
11
11
  - Legacy function names for backwards compatibility
12
12
  """
13
13
 
14
- import os
15
- import sys
14
+ import contextlib
15
+ import warnings
16
16
  from dataclasses import dataclass
17
17
  from datetime import datetime
18
18
  from pathlib import Path
@@ -20,13 +20,16 @@ from typing import Any, Dict, List, Optional, Set
20
20
 
21
21
  # Import from the unified agent registry system
22
22
  from .unified_agent_registry import AgentMetadata as UnifiedAgentMetadata
23
- from .unified_agent_registry import AgentTier, AgentType
23
+ from .unified_agent_registry import (
24
+ AgentTier,
25
+ AgentType,
26
+ )
24
27
  from .unified_agent_registry import discover_agents as unified_discover_agents
25
28
  from .unified_agent_registry import get_agent as unified_get_agent
26
- from .unified_agent_registry import get_agent_names as unified_get_agent_names
27
- from .unified_agent_registry import get_agent_registry
29
+ from .unified_agent_registry import (
30
+ get_agent_registry,
31
+ )
28
32
  from .unified_agent_registry import get_core_agents as unified_get_core_agents
29
- from .unified_agent_registry import get_project_agents as unified_get_project_agents
30
33
  from .unified_agent_registry import get_registry_stats as unified_get_registry_stats
31
34
  from .unified_agent_registry import (
32
35
  get_specialized_agents as unified_get_specialized_agents,
@@ -118,10 +121,9 @@ class SimpleAgentRegistry:
118
121
  or ".claude/agents" in str(agent_path)
119
122
  ):
120
123
  return "project"
121
- elif "user" in str(agent_path) or str(Path.home()) in str(agent_path):
124
+ if "user" in str(agent_path) or str(Path.home()) in str(agent_path):
122
125
  return "user"
123
- else:
124
- return "system"
126
+ return "system"
125
127
 
126
128
  def _extract_specializations(self, agent_id: str) -> List[str]:
127
129
  """Extract specializations based on agent type (compatibility method)."""
@@ -236,7 +238,7 @@ class SimpleAgentRegistry:
236
238
  @property
237
239
  def specialized_agent_types(self) -> Set[str]:
238
240
  """Get specialized agent types beyond core (compatibility property)."""
239
- all_types = set(metadata["type"] for metadata in self.agents.values())
241
+ all_types = {metadata["type"] for metadata in self.agents.values()}
240
242
  return all_types - self.core_agent_types
241
243
 
242
244
 
@@ -268,7 +270,6 @@ class AgentRegistryAdapter:
268
270
  def _initialize_registry(self):
269
271
  """Initialize the agent registry (compatibility method)."""
270
272
  # Registry is already initialized in __init__
271
- pass
272
273
 
273
274
  def list_agents(self, **kwargs) -> Dict[str, Any]:
274
275
  """List available agents (compatibility method)."""
@@ -465,16 +466,12 @@ def list_agents(
465
466
  unified_agent_type = None
466
467
 
467
468
  if tier:
468
- try:
469
+ with contextlib.suppress(ValueError):
469
470
  unified_tier = AgentTier(tier)
470
- except ValueError:
471
- pass
472
471
 
473
472
  if agent_type:
474
- try:
473
+ with contextlib.suppress(ValueError):
475
474
  unified_agent_type = AgentType(agent_type)
476
- except ValueError:
477
- pass
478
475
 
479
476
  unified_agents = unified_list_agents(
480
477
  tier=unified_tier, agent_type=unified_agent_type
@@ -510,18 +507,18 @@ def get_registry_stats() -> Dict[str, Any]:
510
507
 
511
508
  # Export all public symbols
512
509
  __all__ = [
510
+ "AgentMetadata",
513
511
  "AgentRegistry",
514
512
  "AgentRegistryAdapter",
515
- "AgentMetadata",
516
513
  "SimpleAgentRegistry",
517
514
  "create_agent_registry",
518
515
  "discover_agents",
519
- "get_core_agent_types",
520
- "get_specialized_agent_types",
521
- "list_agents_all",
522
- "list_agents",
523
- "listAgents", # Deprecated
524
516
  "discover_agents_sync",
525
517
  "get_agent",
518
+ "get_core_agent_types",
526
519
  "get_registry_stats",
520
+ "get_specialized_agent_types",
521
+ "listAgents", # Deprecated
522
+ "list_agents",
523
+ "list_agents_all",
527
524
  ]
@@ -5,7 +5,7 @@ import uuid
5
5
  from collections import defaultdict
6
6
  from datetime import datetime, timedelta
7
7
  from pathlib import Path
8
- from typing import Dict, Optional, Tuple
8
+ from typing import Dict, Optional
9
9
 
10
10
  from ..core.logger import get_logger
11
11
 
@@ -117,7 +117,7 @@ class AgentSessionManager:
117
117
  success: Whether task completed successfully
118
118
  """
119
119
  # Find which agent this session belongs to
120
- for agent_type, sessions in self.agent_sessions.items():
120
+ for _agent_type, sessions in self.agent_sessions.items():
121
121
  if session_id in sessions:
122
122
  sessions[session_id]["tasks_completed"].append(
123
123
  {
@@ -219,7 +219,7 @@ class AgentSessionManager:
219
219
  session_file = self.session_dir / "agent_sessions.json"
220
220
  if session_file.exists():
221
221
  try:
222
- with open(session_file, "r") as f:
222
+ with open(session_file) as f:
223
223
  data = json.load(f)
224
224
  self.agent_sessions = defaultdict(
225
225
  dict, data.get("agent_sessions", {})
@@ -28,10 +28,9 @@ from contextlib import asynccontextmanager
28
28
  from dataclasses import dataclass, field
29
29
  from datetime import datetime, timedelta
30
30
  from pathlib import Path
31
- from typing import Any, Callable, Dict, List, Optional, Type, Union
31
+ from typing import Any, Dict, List, Optional
32
32
 
33
33
  from .config import Config
34
- from .logger import setup_logging
35
34
  from .mixins import LoggerMixin
36
35
 
37
36
 
@@ -158,13 +157,11 @@ class BaseService(LoggerMixin, ABC):
158
157
  self._init_enhanced_features()
159
158
 
160
159
  # Check for quiet mode
161
- default_log_level = "INFO"
162
160
  if os.getenv("CLAUDE_PM_QUIET_MODE") == "true":
163
- default_log_level = "WARNING"
164
161
  self.logger.setLevel(logging.WARNING)
165
162
 
166
163
  # Only log if not in quiet mode
167
- if not os.environ.get("CLAUDE_PM_QUIET_MODE", "").lower() == "true":
164
+ if os.environ.get("CLAUDE_PM_QUIET_MODE", "").lower() != "true":
168
165
  self.logger.debug(f"Initialized {self.name} service")
169
166
 
170
167
  def _init_enhanced_features(self):
@@ -239,7 +236,7 @@ class BaseService(LoggerMixin, ABC):
239
236
  self.logger.error(f"Failed to start service {self.name}: {e}")
240
237
  self._health = ServiceHealth(
241
238
  status="unhealthy",
242
- message=f"Startup failed: {str(e)}",
239
+ message=f"Startup failed: {e!s}",
243
240
  timestamp=datetime.now().isoformat(),
244
241
  checks={"startup": False},
245
242
  )
@@ -406,7 +403,7 @@ class BaseService(LoggerMixin, ABC):
406
403
  self.logger.error(f"Health check failed for {self.name}: {e}")
407
404
  self._health = ServiceHealth(
408
405
  status="unhealthy",
409
- message=f"Health check error: {str(e)}",
406
+ message=f"Health check error: {e!s}",
410
407
  timestamp=datetime.now().isoformat(),
411
408
  checks={"health_check_error": True},
412
409
  )
@@ -624,10 +621,9 @@ class BaseService(LoggerMixin, ABC):
624
621
  if (
625
622
  self._circuit_breaker.failure_count
626
623
  >= self._circuit_breaker.failure_threshold
627
- ):
628
- if self._circuit_breaker.state != "open":
629
- self._circuit_breaker.state = "open"
630
- self.logger.warning(f"Circuit breaker opened for service {self.name}")
624
+ ) and self._circuit_breaker.state != "open":
625
+ self._circuit_breaker.state = "open"
626
+ self.logger.warning(f"Circuit breaker opened for service {self.name}")
631
627
 
632
628
  def _record_circuit_success(self) -> None:
633
629
  """Record circuit breaker success."""
@@ -706,7 +702,6 @@ class BaseService(LoggerMixin, ABC):
706
702
  async def _initialize_dependencies(self) -> None:
707
703
  """Initialize service dependencies (enhanced feature)."""
708
704
  # Override in subclasses for specific dependency setup
709
- pass
710
705
 
711
706
  async def _register_with_health_monitor(self) -> None:
712
707
  """Register service with health monitor (enhanced feature)."""
@@ -729,12 +724,10 @@ class BaseService(LoggerMixin, ABC):
729
724
  @abstractmethod
730
725
  async def _initialize(self) -> None:
731
726
  """Initialize the service. Must be implemented by subclasses."""
732
- pass
733
727
 
734
728
  @abstractmethod
735
729
  async def _cleanup(self) -> None:
736
730
  """Cleanup service resources. Must be implemented by subclasses."""
737
- pass
738
731
 
739
732
  async def _health_check(self) -> Dict[str, bool]:
740
733
  """
@@ -816,7 +809,6 @@ class BaseService(LoggerMixin, ABC):
816
809
  - Store aggregated data, not raw events
817
810
  - Consider metric cardinality
818
811
  """
819
- pass
820
812
 
821
813
  # Utility methods
822
814
 
claude_mpm/core/cache.py CHANGED
@@ -14,15 +14,13 @@ WHY file system caching:
14
14
  """
15
15
 
16
16
  import asyncio
17
- import hashlib
18
17
  import json
19
18
  import pickle
20
19
  import threading
21
- import time
22
20
  from collections import OrderedDict
23
21
  from dataclasses import dataclass, field
24
- from datetime import datetime, timedelta
25
- from typing import Any, Callable, Dict, Optional, Tuple, TypeVar, Union
22
+ from datetime import datetime
23
+ from typing import Any, Callable, Dict, Optional, TypeVar, Union
26
24
 
27
25
  from ..core.logger import get_logger
28
26
 
@@ -127,7 +125,7 @@ class FileSystemCache:
127
125
  """Estimate memory size of a value in bytes."""
128
126
  if isinstance(value, (str, bytes)):
129
127
  return len(value)
130
- elif isinstance(value, (list, dict)):
128
+ if isinstance(value, (list, dict)):
131
129
  # Rough estimate using JSON serialization
132
130
  try:
133
131
  return len(json.dumps(value))
@@ -353,7 +351,7 @@ class FileSystemCache:
353
351
 
354
352
  with self._lock:
355
353
  matching_keys = [
356
- key for key in self._cache.keys() if fnmatch.fnmatch(key, pattern)
354
+ key for key in self._cache if fnmatch.fnmatch(key, pattern)
357
355
  ]
358
356
 
359
357
  count = 0