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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (389) hide show
  1. claude_mpm/BUILD_NUMBER +1 -1
  2. claude_mpm/VERSION +1 -1
  3. claude_mpm/__main__.py +1 -1
  4. claude_mpm/agents/BASE_PM.md +74 -46
  5. claude_mpm/agents/INSTRUCTIONS.md +11 -153
  6. claude_mpm/agents/WORKFLOW.md +61 -321
  7. claude_mpm/agents/__init__.py +11 -11
  8. claude_mpm/agents/agent_loader.py +23 -20
  9. claude_mpm/agents/agent_loader_integration.py +1 -1
  10. claude_mpm/agents/agents_metadata.py +27 -0
  11. claude_mpm/agents/async_agent_loader.py +5 -8
  12. claude_mpm/agents/base_agent_loader.py +36 -25
  13. claude_mpm/agents/frontmatter_validator.py +6 -6
  14. claude_mpm/agents/schema/agent_schema.json +1 -1
  15. claude_mpm/agents/system_agent_config.py +9 -9
  16. claude_mpm/agents/templates/api_qa.json +47 -2
  17. claude_mpm/agents/templates/engineer.json +33 -11
  18. claude_mpm/agents/templates/imagemagick.json +256 -0
  19. claude_mpm/agents/templates/qa.json +41 -2
  20. claude_mpm/agents/templates/ticketing.json +5 -5
  21. claude_mpm/agents/templates/web_qa.json +50 -2
  22. claude_mpm/cli/__init__.py +51 -46
  23. claude_mpm/cli/__main__.py +1 -1
  24. claude_mpm/cli/commands/__init__.py +10 -12
  25. claude_mpm/cli/commands/agent_manager.py +186 -181
  26. claude_mpm/cli/commands/agents.py +648 -1098
  27. claude_mpm/cli/commands/aggregate.py +30 -29
  28. claude_mpm/cli/commands/cleanup.py +50 -44
  29. claude_mpm/cli/commands/cleanup_orphaned_agents.py +25 -25
  30. claude_mpm/cli/commands/config.py +162 -127
  31. claude_mpm/cli/commands/doctor.py +52 -62
  32. claude_mpm/cli/commands/info.py +37 -25
  33. claude_mpm/cli/commands/mcp.py +3 -7
  34. claude_mpm/cli/commands/mcp_command_router.py +14 -18
  35. claude_mpm/cli/commands/mcp_install_commands.py +28 -23
  36. claude_mpm/cli/commands/mcp_pipx_config.py +58 -49
  37. claude_mpm/cli/commands/mcp_server_commands.py +23 -17
  38. claude_mpm/cli/commands/memory.py +339 -967
  39. claude_mpm/cli/commands/monitor.py +117 -88
  40. claude_mpm/cli/commands/run.py +233 -542
  41. claude_mpm/cli/commands/socketio_monitor.py +17 -19
  42. claude_mpm/cli/commands/tickets.py +92 -92
  43. claude_mpm/cli/parser.py +1 -5
  44. claude_mpm/cli/parsers/__init__.py +1 -1
  45. claude_mpm/cli/parsers/agent_manager_parser.py +50 -98
  46. claude_mpm/cli/parsers/agents_parser.py +2 -3
  47. claude_mpm/cli/parsers/base_parser.py +7 -5
  48. claude_mpm/cli/parsers/mcp_parser.py +4 -2
  49. claude_mpm/cli/parsers/monitor_parser.py +26 -18
  50. claude_mpm/cli/shared/__init__.py +10 -10
  51. claude_mpm/cli/shared/argument_patterns.py +57 -71
  52. claude_mpm/cli/shared/base_command.py +61 -53
  53. claude_mpm/cli/shared/error_handling.py +62 -58
  54. claude_mpm/cli/shared/output_formatters.py +78 -77
  55. claude_mpm/cli/startup_logging.py +280 -172
  56. claude_mpm/cli/utils.py +10 -11
  57. claude_mpm/cli_module/__init__.py +1 -1
  58. claude_mpm/cli_module/args.py +1 -1
  59. claude_mpm/cli_module/migration_example.py +5 -5
  60. claude_mpm/config/__init__.py +9 -9
  61. claude_mpm/config/agent_config.py +15 -14
  62. claude_mpm/config/experimental_features.py +4 -4
  63. claude_mpm/config/paths.py +0 -1
  64. claude_mpm/config/socketio_config.py +5 -6
  65. claude_mpm/constants.py +1 -2
  66. claude_mpm/core/__init__.py +8 -8
  67. claude_mpm/core/agent_name_normalizer.py +1 -1
  68. claude_mpm/core/agent_registry.py +22 -29
  69. claude_mpm/core/agent_session_manager.py +3 -3
  70. claude_mpm/core/base_service.py +7 -15
  71. claude_mpm/core/cache.py +4 -6
  72. claude_mpm/core/claude_runner.py +85 -113
  73. claude_mpm/core/config.py +43 -28
  74. claude_mpm/core/config_aliases.py +0 -9
  75. claude_mpm/core/config_constants.py +52 -30
  76. claude_mpm/core/constants.py +0 -1
  77. claude_mpm/core/container.py +18 -27
  78. claude_mpm/core/exceptions.py +2 -2
  79. claude_mpm/core/factories.py +10 -12
  80. claude_mpm/core/framework_loader.py +500 -680
  81. claude_mpm/core/hook_manager.py +26 -22
  82. claude_mpm/core/hook_performance_config.py +58 -47
  83. claude_mpm/core/injectable_service.py +1 -1
  84. claude_mpm/core/interactive_session.py +61 -152
  85. claude_mpm/core/interfaces.py +1 -100
  86. claude_mpm/core/lazy.py +5 -5
  87. claude_mpm/core/log_manager.py +587 -0
  88. claude_mpm/core/logger.py +125 -8
  89. claude_mpm/core/logging_config.py +15 -17
  90. claude_mpm/core/minimal_framework_loader.py +5 -8
  91. claude_mpm/core/oneshot_session.py +15 -33
  92. claude_mpm/core/optimized_agent_loader.py +4 -6
  93. claude_mpm/core/optimized_startup.py +2 -1
  94. claude_mpm/core/output_style_manager.py +147 -106
  95. claude_mpm/core/pm_hook_interceptor.py +0 -1
  96. claude_mpm/core/service_registry.py +11 -8
  97. claude_mpm/core/session_manager.py +1 -2
  98. claude_mpm/core/shared/__init__.py +1 -1
  99. claude_mpm/core/shared/config_loader.py +101 -97
  100. claude_mpm/core/shared/path_resolver.py +72 -68
  101. claude_mpm/core/shared/singleton_manager.py +56 -50
  102. claude_mpm/core/socketio_pool.py +26 -6
  103. claude_mpm/core/tool_access_control.py +4 -5
  104. claude_mpm/core/typing_utils.py +50 -59
  105. claude_mpm/core/unified_agent_registry.py +14 -19
  106. claude_mpm/core/unified_config.py +4 -6
  107. claude_mpm/core/unified_paths.py +197 -109
  108. claude_mpm/dashboard/open_dashboard.py +2 -4
  109. claude_mpm/experimental/cli_enhancements.py +51 -36
  110. claude_mpm/generators/agent_profile_generator.py +2 -4
  111. claude_mpm/hooks/base_hook.py +1 -2
  112. claude_mpm/hooks/claude_hooks/connection_pool.py +72 -26
  113. claude_mpm/hooks/claude_hooks/event_handlers.py +99 -154
  114. claude_mpm/hooks/claude_hooks/hook_handler.py +110 -720
  115. claude_mpm/hooks/claude_hooks/hook_handler_eventbus.py +104 -77
  116. claude_mpm/hooks/claude_hooks/hook_handler_original.py +1040 -0
  117. claude_mpm/hooks/claude_hooks/hook_handler_refactored.py +347 -0
  118. claude_mpm/hooks/claude_hooks/memory_integration.py +2 -4
  119. claude_mpm/hooks/claude_hooks/response_tracking.py +15 -11
  120. claude_mpm/hooks/claude_hooks/services/__init__.py +13 -0
  121. claude_mpm/hooks/claude_hooks/services/connection_manager.py +190 -0
  122. claude_mpm/hooks/claude_hooks/services/duplicate_detector.py +106 -0
  123. claude_mpm/hooks/claude_hooks/services/state_manager.py +282 -0
  124. claude_mpm/hooks/claude_hooks/services/subagent_processor.py +374 -0
  125. claude_mpm/hooks/claude_hooks/tool_analysis.py +12 -18
  126. claude_mpm/hooks/memory_integration_hook.py +5 -5
  127. claude_mpm/hooks/tool_call_interceptor.py +1 -1
  128. claude_mpm/hooks/validation_hooks.py +4 -4
  129. claude_mpm/init.py +4 -9
  130. claude_mpm/models/__init__.py +2 -2
  131. claude_mpm/models/agent_session.py +11 -14
  132. claude_mpm/scripts/mcp_server.py +20 -11
  133. claude_mpm/scripts/mcp_wrapper.py +5 -5
  134. claude_mpm/scripts/mpm_doctor.py +321 -0
  135. claude_mpm/scripts/socketio_daemon.py +28 -25
  136. claude_mpm/scripts/socketio_daemon_hardened.py +298 -258
  137. claude_mpm/scripts/socketio_server_manager.py +116 -95
  138. claude_mpm/services/__init__.py +49 -49
  139. claude_mpm/services/agent_capabilities_service.py +12 -18
  140. claude_mpm/services/agents/__init__.py +22 -22
  141. claude_mpm/services/agents/agent_builder.py +140 -119
  142. claude_mpm/services/agents/deployment/__init__.py +3 -3
  143. claude_mpm/services/agents/deployment/agent_config_provider.py +9 -9
  144. claude_mpm/services/agents/deployment/agent_configuration_manager.py +19 -20
  145. claude_mpm/services/agents/deployment/agent_definition_factory.py +1 -5
  146. claude_mpm/services/agents/deployment/agent_deployment.py +129 -511
  147. claude_mpm/services/agents/deployment/agent_discovery_service.py +4 -8
  148. claude_mpm/services/agents/deployment/agent_environment_manager.py +2 -7
  149. claude_mpm/services/agents/deployment/agent_filesystem_manager.py +6 -10
  150. claude_mpm/services/agents/deployment/agent_format_converter.py +11 -15
  151. claude_mpm/services/agents/deployment/agent_frontmatter_validator.py +2 -3
  152. claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +5 -5
  153. claude_mpm/services/agents/deployment/agent_metrics_collector.py +13 -19
  154. claude_mpm/services/agents/deployment/agent_restore_handler.py +0 -1
  155. claude_mpm/services/agents/deployment/agent_template_builder.py +26 -35
  156. claude_mpm/services/agents/deployment/agent_validator.py +0 -1
  157. claude_mpm/services/agents/deployment/agent_version_manager.py +7 -9
  158. claude_mpm/services/agents/deployment/agent_versioning.py +3 -3
  159. claude_mpm/services/agents/deployment/agents_directory_resolver.py +6 -7
  160. claude_mpm/services/agents/deployment/async_agent_deployment.py +51 -38
  161. claude_mpm/services/agents/deployment/base_agent_locator.py +132 -0
  162. claude_mpm/services/agents/deployment/config/__init__.py +1 -1
  163. claude_mpm/services/agents/deployment/config/deployment_config.py +7 -8
  164. claude_mpm/services/agents/deployment/deployment_results_manager.py +185 -0
  165. claude_mpm/services/agents/deployment/deployment_type_detector.py +1 -1
  166. claude_mpm/services/agents/deployment/deployment_wrapper.py +18 -18
  167. claude_mpm/services/agents/deployment/facade/__init__.py +1 -1
  168. claude_mpm/services/agents/deployment/facade/deployment_executor.py +0 -3
  169. claude_mpm/services/agents/deployment/facade/deployment_facade.py +3 -4
  170. claude_mpm/services/agents/deployment/interface_adapter.py +5 -7
  171. claude_mpm/services/agents/deployment/multi_source_deployment_service.py +345 -276
  172. claude_mpm/services/agents/deployment/pipeline/__init__.py +2 -2
  173. claude_mpm/services/agents/deployment/pipeline/pipeline_builder.py +1 -1
  174. claude_mpm/services/agents/deployment/pipeline/pipeline_context.py +6 -4
  175. claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +3 -3
  176. claude_mpm/services/agents/deployment/pipeline/steps/__init__.py +2 -2
  177. claude_mpm/services/agents/deployment/pipeline/steps/agent_processing_step.py +14 -13
  178. claude_mpm/services/agents/deployment/pipeline/steps/base_step.py +0 -1
  179. claude_mpm/services/agents/deployment/pipeline/steps/configuration_step.py +1 -1
  180. claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +8 -9
  181. claude_mpm/services/agents/deployment/pipeline/steps/validation_step.py +1 -1
  182. claude_mpm/services/agents/deployment/processors/__init__.py +1 -1
  183. claude_mpm/services/agents/deployment/processors/agent_processor.py +20 -16
  184. claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +5 -12
  185. claude_mpm/services/agents/deployment/results/__init__.py +1 -1
  186. claude_mpm/services/agents/deployment/results/deployment_result_builder.py +1 -1
  187. claude_mpm/services/agents/deployment/single_agent_deployer.py +315 -0
  188. claude_mpm/services/agents/deployment/strategies/__init__.py +2 -2
  189. claude_mpm/services/agents/deployment/strategies/base_strategy.py +1 -7
  190. claude_mpm/services/agents/deployment/strategies/project_strategy.py +1 -4
  191. claude_mpm/services/agents/deployment/strategies/system_strategy.py +2 -3
  192. claude_mpm/services/agents/deployment/strategies/user_strategy.py +3 -7
  193. claude_mpm/services/agents/deployment/validation/__init__.py +1 -1
  194. claude_mpm/services/agents/deployment/validation/agent_validator.py +1 -1
  195. claude_mpm/services/agents/deployment/validation/template_validator.py +2 -2
  196. claude_mpm/services/agents/deployment/validation/validation_result.py +2 -6
  197. claude_mpm/services/agents/loading/__init__.py +1 -1
  198. claude_mpm/services/agents/loading/agent_profile_loader.py +6 -12
  199. claude_mpm/services/agents/loading/base_agent_manager.py +5 -5
  200. claude_mpm/services/agents/loading/framework_agent_loader.py +2 -4
  201. claude_mpm/services/agents/management/__init__.py +1 -1
  202. claude_mpm/services/agents/management/agent_capabilities_generator.py +1 -3
  203. claude_mpm/services/agents/management/agent_management_service.py +5 -9
  204. claude_mpm/services/agents/memory/__init__.py +4 -4
  205. claude_mpm/services/agents/memory/agent_memory_manager.py +157 -503
  206. claude_mpm/services/agents/memory/agent_persistence_service.py +0 -2
  207. claude_mpm/services/agents/memory/content_manager.py +44 -38
  208. claude_mpm/services/agents/memory/memory_categorization_service.py +165 -0
  209. claude_mpm/services/agents/memory/memory_file_service.py +103 -0
  210. claude_mpm/services/agents/memory/memory_format_service.py +201 -0
  211. claude_mpm/services/agents/memory/memory_limits_service.py +99 -0
  212. claude_mpm/services/agents/memory/template_generator.py +4 -6
  213. claude_mpm/services/agents/registry/__init__.py +11 -7
  214. claude_mpm/services/agents/registry/deployed_agent_discovery.py +30 -27
  215. claude_mpm/services/agents/registry/modification_tracker.py +3 -6
  216. claude_mpm/services/async_session_logger.py +1 -2
  217. claude_mpm/services/claude_session_logger.py +1 -2
  218. claude_mpm/services/cli/__init__.py +18 -0
  219. claude_mpm/services/cli/agent_cleanup_service.py +407 -0
  220. claude_mpm/services/cli/agent_dependency_service.py +395 -0
  221. claude_mpm/services/cli/agent_listing_service.py +463 -0
  222. claude_mpm/services/cli/agent_output_formatter.py +605 -0
  223. claude_mpm/services/cli/agent_validation_service.py +589 -0
  224. claude_mpm/services/cli/dashboard_launcher.py +424 -0
  225. claude_mpm/services/cli/memory_crud_service.py +617 -0
  226. claude_mpm/services/cli/memory_output_formatter.py +604 -0
  227. claude_mpm/services/cli/session_manager.py +513 -0
  228. claude_mpm/services/cli/socketio_manager.py +498 -0
  229. claude_mpm/services/cli/startup_checker.py +370 -0
  230. claude_mpm/services/command_deployment_service.py +173 -0
  231. claude_mpm/services/command_handler_service.py +20 -22
  232. claude_mpm/services/core/__init__.py +25 -25
  233. claude_mpm/services/core/base.py +0 -5
  234. claude_mpm/services/core/cache_manager.py +311 -0
  235. claude_mpm/services/core/interfaces/__init__.py +32 -32
  236. claude_mpm/services/core/interfaces/agent.py +0 -21
  237. claude_mpm/services/core/interfaces/communication.py +0 -27
  238. claude_mpm/services/core/interfaces/infrastructure.py +0 -56
  239. claude_mpm/services/core/interfaces/service.py +0 -29
  240. claude_mpm/services/core/memory_manager.py +637 -0
  241. claude_mpm/services/core/path_resolver.py +498 -0
  242. claude_mpm/services/core/service_container.py +520 -0
  243. claude_mpm/services/core/service_interfaces.py +436 -0
  244. claude_mpm/services/diagnostics/__init__.py +1 -1
  245. claude_mpm/services/diagnostics/checks/__init__.py +6 -6
  246. claude_mpm/services/diagnostics/checks/agent_check.py +152 -97
  247. claude_mpm/services/diagnostics/checks/base_check.py +12 -16
  248. claude_mpm/services/diagnostics/checks/claude_desktop_check.py +84 -81
  249. claude_mpm/services/diagnostics/checks/common_issues_check.py +99 -91
  250. claude_mpm/services/diagnostics/checks/configuration_check.py +82 -77
  251. claude_mpm/services/diagnostics/checks/filesystem_check.py +67 -68
  252. claude_mpm/services/diagnostics/checks/installation_check.py +254 -94
  253. claude_mpm/services/diagnostics/checks/mcp_check.py +90 -88
  254. claude_mpm/services/diagnostics/checks/monitor_check.py +75 -76
  255. claude_mpm/services/diagnostics/checks/startup_log_check.py +67 -73
  256. claude_mpm/services/diagnostics/diagnostic_runner.py +67 -59
  257. claude_mpm/services/diagnostics/doctor_reporter.py +107 -70
  258. claude_mpm/services/diagnostics/models.py +21 -19
  259. claude_mpm/services/event_aggregator.py +10 -17
  260. claude_mpm/services/event_bus/__init__.py +1 -1
  261. claude_mpm/services/event_bus/config.py +54 -35
  262. claude_mpm/services/event_bus/event_bus.py +76 -71
  263. claude_mpm/services/event_bus/relay.py +74 -64
  264. claude_mpm/services/events/__init__.py +11 -11
  265. claude_mpm/services/events/consumers/__init__.py +3 -3
  266. claude_mpm/services/events/consumers/dead_letter.py +71 -63
  267. claude_mpm/services/events/consumers/logging.py +39 -37
  268. claude_mpm/services/events/consumers/metrics.py +56 -57
  269. claude_mpm/services/events/consumers/socketio.py +82 -81
  270. claude_mpm/services/events/core.py +110 -99
  271. claude_mpm/services/events/interfaces.py +56 -72
  272. claude_mpm/services/events/producers/__init__.py +1 -1
  273. claude_mpm/services/events/producers/hook.py +38 -38
  274. claude_mpm/services/events/producers/system.py +46 -44
  275. claude_mpm/services/exceptions.py +81 -80
  276. claude_mpm/services/framework_claude_md_generator/__init__.py +2 -4
  277. claude_mpm/services/framework_claude_md_generator/content_assembler.py +3 -5
  278. claude_mpm/services/framework_claude_md_generator/content_validator.py +1 -1
  279. claude_mpm/services/framework_claude_md_generator/deployment_manager.py +4 -4
  280. claude_mpm/services/framework_claude_md_generator/section_generators/__init__.py +0 -1
  281. claude_mpm/services/framework_claude_md_generator/section_generators/agents.py +0 -2
  282. claude_mpm/services/framework_claude_md_generator/version_manager.py +4 -5
  283. claude_mpm/services/hook_service.py +6 -9
  284. claude_mpm/services/infrastructure/__init__.py +1 -1
  285. claude_mpm/services/infrastructure/context_preservation.py +8 -12
  286. claude_mpm/services/infrastructure/monitoring.py +21 -23
  287. claude_mpm/services/mcp_gateway/__init__.py +37 -37
  288. claude_mpm/services/mcp_gateway/auto_configure.py +95 -103
  289. claude_mpm/services/mcp_gateway/config/__init__.py +1 -1
  290. claude_mpm/services/mcp_gateway/config/config_loader.py +23 -25
  291. claude_mpm/services/mcp_gateway/config/config_schema.py +5 -5
  292. claude_mpm/services/mcp_gateway/config/configuration.py +9 -6
  293. claude_mpm/services/mcp_gateway/core/__init__.py +10 -10
  294. claude_mpm/services/mcp_gateway/core/base.py +0 -3
  295. claude_mpm/services/mcp_gateway/core/interfaces.py +1 -38
  296. claude_mpm/services/mcp_gateway/core/process_pool.py +99 -93
  297. claude_mpm/services/mcp_gateway/core/singleton_manager.py +65 -62
  298. claude_mpm/services/mcp_gateway/core/startup_verification.py +75 -74
  299. claude_mpm/services/mcp_gateway/main.py +2 -1
  300. claude_mpm/services/mcp_gateway/registry/service_registry.py +5 -8
  301. claude_mpm/services/mcp_gateway/registry/tool_registry.py +1 -1
  302. claude_mpm/services/mcp_gateway/server/__init__.py +1 -1
  303. claude_mpm/services/mcp_gateway/server/mcp_gateway.py +12 -19
  304. claude_mpm/services/mcp_gateway/server/stdio_handler.py +4 -3
  305. claude_mpm/services/mcp_gateway/server/stdio_server.py +79 -71
  306. claude_mpm/services/mcp_gateway/tools/__init__.py +2 -2
  307. claude_mpm/services/mcp_gateway/tools/base_adapter.py +5 -6
  308. claude_mpm/services/mcp_gateway/tools/document_summarizer.py +13 -22
  309. claude_mpm/services/mcp_gateway/tools/health_check_tool.py +79 -78
  310. claude_mpm/services/mcp_gateway/tools/hello_world.py +12 -14
  311. claude_mpm/services/mcp_gateway/tools/ticket_tools.py +42 -49
  312. claude_mpm/services/mcp_gateway/tools/unified_ticket_tool.py +51 -55
  313. claude_mpm/services/memory/__init__.py +3 -3
  314. claude_mpm/services/memory/builder.py +3 -6
  315. claude_mpm/services/memory/cache/__init__.py +1 -1
  316. claude_mpm/services/memory/cache/shared_prompt_cache.py +3 -5
  317. claude_mpm/services/memory/cache/simple_cache.py +1 -1
  318. claude_mpm/services/memory/indexed_memory.py +5 -7
  319. claude_mpm/services/memory/optimizer.py +7 -10
  320. claude_mpm/services/memory/router.py +8 -9
  321. claude_mpm/services/memory_hook_service.py +48 -34
  322. claude_mpm/services/monitor_build_service.py +77 -73
  323. claude_mpm/services/port_manager.py +130 -108
  324. claude_mpm/services/project/analyzer.py +12 -10
  325. claude_mpm/services/project/registry.py +11 -11
  326. claude_mpm/services/recovery_manager.py +10 -19
  327. claude_mpm/services/response_tracker.py +0 -1
  328. claude_mpm/services/runner_configuration_service.py +19 -20
  329. claude_mpm/services/session_management_service.py +7 -11
  330. claude_mpm/services/shared/__init__.py +1 -1
  331. claude_mpm/services/shared/async_service_base.py +58 -50
  332. claude_mpm/services/shared/config_service_base.py +73 -67
  333. claude_mpm/services/shared/lifecycle_service_base.py +82 -78
  334. claude_mpm/services/shared/manager_base.py +94 -82
  335. claude_mpm/services/shared/service_factory.py +96 -98
  336. claude_mpm/services/socketio/__init__.py +3 -3
  337. claude_mpm/services/socketio/client_proxy.py +5 -5
  338. claude_mpm/services/socketio/event_normalizer.py +199 -181
  339. claude_mpm/services/socketio/handlers/__init__.py +3 -3
  340. claude_mpm/services/socketio/handlers/base.py +5 -4
  341. claude_mpm/services/socketio/handlers/connection.py +163 -136
  342. claude_mpm/services/socketio/handlers/file.py +13 -14
  343. claude_mpm/services/socketio/handlers/git.py +12 -7
  344. claude_mpm/services/socketio/handlers/hook.py +49 -44
  345. claude_mpm/services/socketio/handlers/memory.py +0 -1
  346. claude_mpm/services/socketio/handlers/project.py +0 -1
  347. claude_mpm/services/socketio/handlers/registry.py +37 -19
  348. claude_mpm/services/socketio/migration_utils.py +98 -84
  349. claude_mpm/services/socketio/server/__init__.py +1 -1
  350. claude_mpm/services/socketio/server/broadcaster.py +81 -87
  351. claude_mpm/services/socketio/server/core.py +65 -54
  352. claude_mpm/services/socketio/server/eventbus_integration.py +95 -56
  353. claude_mpm/services/socketio/server/main.py +64 -38
  354. claude_mpm/services/socketio_client_manager.py +10 -12
  355. claude_mpm/services/subprocess_launcher_service.py +4 -7
  356. claude_mpm/services/system_instructions_service.py +13 -14
  357. claude_mpm/services/ticket_manager.py +2 -2
  358. claude_mpm/services/utility_service.py +5 -13
  359. claude_mpm/services/version_control/__init__.py +16 -16
  360. claude_mpm/services/version_control/branch_strategy.py +5 -8
  361. claude_mpm/services/version_control/conflict_resolution.py +9 -23
  362. claude_mpm/services/version_control/git_operations.py +5 -7
  363. claude_mpm/services/version_control/semantic_versioning.py +16 -17
  364. claude_mpm/services/version_control/version_parser.py +13 -18
  365. claude_mpm/services/version_service.py +10 -11
  366. claude_mpm/storage/__init__.py +1 -1
  367. claude_mpm/storage/state_storage.py +22 -28
  368. claude_mpm/utils/__init__.py +6 -6
  369. claude_mpm/utils/agent_dependency_loader.py +47 -33
  370. claude_mpm/utils/config_manager.py +11 -14
  371. claude_mpm/utils/dependency_cache.py +1 -1
  372. claude_mpm/utils/dependency_manager.py +13 -17
  373. claude_mpm/utils/dependency_strategies.py +8 -10
  374. claude_mpm/utils/environment_context.py +3 -9
  375. claude_mpm/utils/error_handler.py +3 -13
  376. claude_mpm/utils/file_utils.py +1 -1
  377. claude_mpm/utils/path_operations.py +8 -12
  378. claude_mpm/utils/robust_installer.py +110 -33
  379. claude_mpm/utils/subprocess_utils.py +5 -6
  380. claude_mpm/validation/agent_validator.py +3 -6
  381. claude_mpm/validation/frontmatter_validator.py +1 -1
  382. {claude_mpm-4.1.1.dist-info → claude_mpm-4.1.3.dist-info}/METADATA +1 -1
  383. claude_mpm-4.1.3.dist-info/RECORD +528 -0
  384. claude_mpm/cli/commands/run_config_checker.py +0 -160
  385. claude_mpm-4.1.1.dist-info/RECORD +0 -494
  386. {claude_mpm-4.1.1.dist-info → claude_mpm-4.1.3.dist-info}/WHEEL +0 -0
  387. {claude_mpm-4.1.1.dist-info → claude_mpm-4.1.3.dist-info}/entry_points.txt +0 -0
  388. {claude_mpm-4.1.1.dist-info → claude_mpm-4.1.3.dist-info}/licenses/LICENSE +0 -0
  389. {claude_mpm-4.1.1.dist-info → claude_mpm-4.1.3.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,374 @@
1
+ """Subagent response processing service for Claude hook handler.
2
+
3
+ This service handles:
4
+ - SubagentStop event processing
5
+ - Structured response extraction
6
+ - Response tracking and correlation
7
+ - Memory field processing
8
+ """
9
+
10
+ import json
11
+ import os
12
+ import re
13
+ import sys
14
+ from datetime import datetime
15
+ from typing import Optional, Tuple
16
+
17
+ # Debug mode is enabled by default for better visibility into hook processing
18
+ DEBUG = os.environ.get("CLAUDE_MPM_HOOK_DEBUG", "true").lower() != "false"
19
+
20
+
21
+ class SubagentResponseProcessor:
22
+ """Processes subagent responses and extracts structured data."""
23
+
24
+ def __init__(self, state_manager, response_tracking_manager, connection_manager):
25
+ """Initialize the subagent response processor.
26
+
27
+ Args:
28
+ state_manager: StateManagerService instance
29
+ response_tracking_manager: ResponseTrackingManager instance
30
+ connection_manager: ConnectionManagerService instance
31
+ """
32
+ self.state_manager = state_manager
33
+ self.response_tracking_manager = response_tracking_manager
34
+ self.connection_manager = connection_manager
35
+
36
+ def process_subagent_stop(self, event: dict):
37
+ """Handle subagent stop events with improved agent type detection.
38
+
39
+ WHY comprehensive subagent stop capture:
40
+ - Provides visibility into subagent lifecycle and delegation patterns
41
+ - Captures agent type, ID, reason, and results for analysis
42
+ - Enables tracking of delegation success/failure patterns
43
+ - Useful for understanding subagent performance and reliability
44
+ """
45
+ # Enhanced debug logging for session correlation
46
+ session_id = event.get("session_id", "")
47
+ if DEBUG:
48
+ print(
49
+ f" - session_id: {session_id[:16] if session_id else 'None'}...",
50
+ file=sys.stderr,
51
+ )
52
+ print(f" - event keys: {list(event.keys())}", file=sys.stderr)
53
+ print(
54
+ f" - delegation_requests size: {len(self.state_manager.delegation_requests)}",
55
+ file=sys.stderr,
56
+ )
57
+ # Show all stored session IDs for comparison
58
+ all_sessions = list(self.state_manager.delegation_requests.keys())
59
+ if all_sessions:
60
+ print(" - Stored sessions (first 16 chars):", file=sys.stderr)
61
+ for sid in all_sessions[:10]: # Show up to 10
62
+ print(
63
+ f" - {sid[:16]}... (agent: {self.state_manager.delegation_requests[sid].get('agent_type', 'unknown')})",
64
+ file=sys.stderr,
65
+ )
66
+ else:
67
+ print(" - No stored sessions in delegation_requests!", file=sys.stderr)
68
+
69
+ # Get agent type and other basic info
70
+ agent_type, agent_id, reason = self._extract_basic_info(event, session_id)
71
+
72
+ # Always log SubagentStop events for debugging
73
+ if DEBUG or agent_type != "unknown":
74
+ print(
75
+ f"Hook handler: Processing SubagentStop - agent: '{agent_type}', session: '{session_id}', reason: '{reason}'",
76
+ file=sys.stderr,
77
+ )
78
+
79
+ # Get working directory and git branch
80
+ working_dir = event.get("cwd", "")
81
+ git_branch = (
82
+ self.state_manager.get_git_branch(working_dir) if working_dir else "Unknown"
83
+ )
84
+
85
+ # Try to extract structured response from output if available
86
+ output = event.get("output", "")
87
+ structured_response = self._extract_structured_response(output, agent_type)
88
+
89
+ # Track agent response
90
+ self._track_response(
91
+ event,
92
+ session_id,
93
+ agent_type,
94
+ reason,
95
+ working_dir,
96
+ git_branch,
97
+ output,
98
+ structured_response,
99
+ )
100
+
101
+ # Build subagent stop data for event emission
102
+ subagent_stop_data = self._build_subagent_stop_data(
103
+ event,
104
+ session_id,
105
+ agent_type,
106
+ agent_id,
107
+ reason,
108
+ working_dir,
109
+ git_branch,
110
+ structured_response,
111
+ )
112
+
113
+ # Debug log the processed data
114
+ if DEBUG:
115
+ print(
116
+ f"SubagentStop processed data: agent_type='{agent_type}', session_id='{session_id}'",
117
+ file=sys.stderr,
118
+ )
119
+
120
+ # Emit to /hook namespace with high priority
121
+ self.connection_manager.emit_event("/hook", "subagent_stop", subagent_stop_data)
122
+
123
+ def _extract_basic_info(self, event: dict, session_id: str) -> Tuple[str, str, str]:
124
+ """Extract basic info from the event."""
125
+ # First try to get agent type from our tracking
126
+ agent_type = (
127
+ self.state_manager.get_delegation_agent_type(session_id)
128
+ if session_id
129
+ else "unknown"
130
+ )
131
+
132
+ # Fall back to event data if tracking didn't have it
133
+ if agent_type == "unknown":
134
+ agent_type = event.get("agent_type", event.get("subagent_type", "unknown"))
135
+
136
+ agent_id = event.get("agent_id", event.get("subagent_id", ""))
137
+ reason = event.get("reason", event.get("stop_reason", "unknown"))
138
+
139
+ # Try to infer agent type from other fields if still unknown
140
+ if agent_type == "unknown" and "task" in event:
141
+ task_desc = str(event.get("task", "")).lower()
142
+ if "research" in task_desc:
143
+ agent_type = "research"
144
+ elif "engineer" in task_desc or "code" in task_desc:
145
+ agent_type = "engineer"
146
+ elif "pm" in task_desc or "project" in task_desc:
147
+ agent_type = "pm"
148
+
149
+ return agent_type, agent_id, reason
150
+
151
+ def _extract_structured_response(
152
+ self, output: str, agent_type: str
153
+ ) -> Optional[dict]:
154
+ """Extract structured JSON response from output."""
155
+ if not output:
156
+ return None
157
+
158
+ try:
159
+ json_match = re.search(r"```json\s*(\{.*?\})\s*```", str(output), re.DOTALL)
160
+ if json_match:
161
+ structured_response = json.loads(json_match.group(1))
162
+ if DEBUG:
163
+ print(
164
+ f"Extracted structured response from {agent_type} agent in SubagentStop",
165
+ file=sys.stderr,
166
+ )
167
+
168
+ # Log if MEMORIES field is present
169
+ if structured_response.get("MEMORIES") and DEBUG:
170
+ memories_count = len(structured_response["MEMORIES"])
171
+ print(
172
+ f"Agent {agent_type} returned MEMORIES field with {memories_count} items",
173
+ file=sys.stderr,
174
+ )
175
+
176
+ return structured_response
177
+ except (json.JSONDecodeError, AttributeError):
178
+ pass # No structured response, that's okay
179
+
180
+ return None
181
+
182
+ def _track_response(
183
+ self,
184
+ event: dict,
185
+ session_id: str,
186
+ agent_type: str,
187
+ reason: str,
188
+ working_dir: str,
189
+ git_branch: str,
190
+ output: str,
191
+ structured_response: Optional[dict],
192
+ ):
193
+ """Track the agent response if response tracking is enabled."""
194
+ if DEBUG:
195
+ print(
196
+ f" - response_tracking_enabled: {self.response_tracking_manager.response_tracking_enabled}",
197
+ file=sys.stderr,
198
+ )
199
+ print(
200
+ f" - response_tracker exists: {self.response_tracking_manager.response_tracker is not None}",
201
+ file=sys.stderr,
202
+ )
203
+ print(
204
+ f" - session_id: {session_id[:16] if session_id else 'None'}...",
205
+ file=sys.stderr,
206
+ )
207
+ print(f" - agent_type: {agent_type}", file=sys.stderr)
208
+ print(f" - reason: {reason}", file=sys.stderr)
209
+
210
+ if (
211
+ self.response_tracking_manager.response_tracking_enabled
212
+ and self.response_tracking_manager.response_tracker
213
+ ):
214
+ try:
215
+ # Get the original request data (with fuzzy matching fallback)
216
+ request_info = self.state_manager.find_matching_request(session_id)
217
+
218
+ if DEBUG:
219
+ print(
220
+ f" - request_info present: {bool(request_info)}",
221
+ file=sys.stderr,
222
+ )
223
+ if request_info:
224
+ print(
225
+ " - ✅ Found request data for response tracking",
226
+ file=sys.stderr,
227
+ )
228
+ print(
229
+ f" - stored agent_type: {request_info.get('agent_type')}",
230
+ file=sys.stderr,
231
+ )
232
+ print(
233
+ f" - request keys: {list(request_info.get('request', {}).keys())}",
234
+ file=sys.stderr,
235
+ )
236
+ else:
237
+ print(
238
+ f" - ❌ No request data found for session {session_id[:16]}...",
239
+ file=sys.stderr,
240
+ )
241
+
242
+ if request_info:
243
+ # Use the output as the response
244
+ response_text = (
245
+ str(output)
246
+ if output
247
+ else f"Agent {agent_type} completed with reason: {reason}"
248
+ )
249
+
250
+ # Get the original request
251
+ original_request = request_info.get("request", {})
252
+ prompt = original_request.get("prompt", "")
253
+ description = original_request.get("description", "")
254
+
255
+ # Combine prompt and description
256
+ full_request = prompt
257
+ if description and description != prompt:
258
+ if full_request:
259
+ full_request += f"\n\nDescription: {description}"
260
+ else:
261
+ full_request = description
262
+
263
+ if not full_request:
264
+ full_request = f"Task delegation to {agent_type} agent"
265
+
266
+ # Prepare metadata
267
+ metadata = {
268
+ "exit_code": event.get("exit_code", 0),
269
+ "success": reason in ["completed", "finished", "done"],
270
+ "has_error": reason
271
+ in ["error", "timeout", "failed", "blocked"],
272
+ "duration_ms": event.get("duration_ms"),
273
+ "working_directory": working_dir,
274
+ "git_branch": git_branch,
275
+ "timestamp": datetime.now().isoformat(),
276
+ "event_type": "subagent_stop",
277
+ "reason": reason,
278
+ "original_request_timestamp": request_info.get("timestamp"),
279
+ }
280
+
281
+ # Add structured response if available
282
+ if structured_response:
283
+ metadata["structured_response"] = structured_response
284
+ metadata["task_completed"] = structured_response.get(
285
+ "task_completed", False
286
+ )
287
+
288
+ # Check for MEMORIES field and process if present
289
+ if structured_response.get("MEMORIES") and DEBUG:
290
+ memories = structured_response["MEMORIES"]
291
+ print(
292
+ f"Found MEMORIES field in {agent_type} response with {len(memories)} items",
293
+ file=sys.stderr,
294
+ )
295
+ # The memory will be processed by extract_and_update_memory
296
+ # which is called by the memory hook service
297
+
298
+ # Track the response
299
+ file_path = (
300
+ self.response_tracking_manager.response_tracker.track_response(
301
+ agent_name=agent_type,
302
+ request=full_request,
303
+ response=response_text,
304
+ session_id=session_id,
305
+ metadata=metadata,
306
+ )
307
+ )
308
+
309
+ if file_path and DEBUG:
310
+ print(
311
+ f"✅ Tracked {agent_type} agent response on SubagentStop: {file_path.name}",
312
+ file=sys.stderr,
313
+ )
314
+
315
+ # Clean up the request data
316
+ self.state_manager.remove_request(session_id)
317
+
318
+ elif DEBUG:
319
+ print(
320
+ f"No request data for SubagentStop session {session_id[:8]}..., agent: {agent_type}",
321
+ file=sys.stderr,
322
+ )
323
+
324
+ except Exception as e:
325
+ if DEBUG:
326
+ print(
327
+ f"❌ Failed to track response on SubagentStop: {e}",
328
+ file=sys.stderr,
329
+ )
330
+
331
+ def _build_subagent_stop_data(
332
+ self,
333
+ event: dict,
334
+ session_id: str,
335
+ agent_type: str,
336
+ agent_id: str,
337
+ reason: str,
338
+ working_dir: str,
339
+ git_branch: str,
340
+ structured_response: Optional[dict],
341
+ ) -> dict:
342
+ """Build the subagent stop data for event emission."""
343
+ subagent_stop_data = {
344
+ "agent_type": agent_type,
345
+ "agent_id": agent_id,
346
+ "reason": reason,
347
+ "session_id": session_id,
348
+ "working_directory": working_dir,
349
+ "git_branch": git_branch,
350
+ "timestamp": datetime.now().isoformat(),
351
+ "is_successful_completion": reason in ["completed", "finished", "done"],
352
+ "is_error_termination": reason in ["error", "timeout", "failed", "blocked"],
353
+ "is_delegation_related": agent_type
354
+ in ["research", "engineer", "pm", "ops", "qa", "documentation", "security"],
355
+ "has_results": bool(event.get("results") or event.get("output")),
356
+ "duration_context": event.get("duration_ms"),
357
+ "hook_event_name": "SubagentStop", # Explicitly set for dashboard
358
+ }
359
+
360
+ # Add structured response data if available
361
+ if structured_response:
362
+ subagent_stop_data["structured_response"] = {
363
+ "task_completed": structured_response.get("task_completed", False),
364
+ "instructions": structured_response.get("instructions", ""),
365
+ "results": structured_response.get("results", ""),
366
+ "files_modified": structured_response.get("files_modified", []),
367
+ "tools_used": structured_response.get("tools_used", []),
368
+ "remember": structured_response.get("remember"),
369
+ "MEMORIES": structured_response.get(
370
+ "MEMORIES"
371
+ ), # Complete memory replacement
372
+ }
373
+
374
+ return subagent_stop_data
@@ -5,8 +5,6 @@ This module provides utilities for analyzing tool usage, extracting parameters,
5
5
  and assessing security risks.
6
6
  """
7
7
 
8
- from typing import Any, Dict, List
9
-
10
8
 
11
9
  def extract_tool_parameters(tool_name: str, tool_input: dict) -> dict:
12
10
  """Extract relevant parameters based on tool type.
@@ -99,7 +97,7 @@ def extract_tool_parameters(tool_name: str, tool_input: dict) -> dict:
99
97
  "has_in_progress": any(t.get("status") == "in_progress" for t in todos),
100
98
  "has_pending": any(t.get("status") == "pending" for t in todos),
101
99
  "has_completed": any(t.get("status") == "completed" for t in todos),
102
- "priorities": list(set(t.get("priority", "medium") for t in todos)),
100
+ "priorities": list({t.get("priority", "medium") for t in todos}),
103
101
  }
104
102
  )
105
103
 
@@ -144,18 +142,17 @@ def classify_tool_operation(tool_name: str, tool_input: dict) -> str:
144
142
  """Classify the type of operation being performed."""
145
143
  if tool_name in ["Read", "LS", "Glob", "Grep", "NotebookRead"]:
146
144
  return "read"
147
- elif tool_name in ["Write", "Edit", "MultiEdit", "NotebookEdit"]:
145
+ if tool_name in ["Write", "Edit", "MultiEdit", "NotebookEdit"]:
148
146
  return "write"
149
- elif tool_name == "Bash":
147
+ if tool_name == "Bash":
150
148
  return "execute"
151
- elif tool_name in ["WebFetch", "WebSearch"]:
149
+ if tool_name in ["WebFetch", "WebSearch"]:
152
150
  return "network"
153
- elif tool_name == "TodoWrite":
151
+ if tool_name == "TodoWrite":
154
152
  return "task_management"
155
- elif tool_name == "Task":
153
+ if tool_name == "Task":
156
154
  return "delegation"
157
- else:
158
- return "other"
155
+ return "other"
159
156
 
160
157
 
161
158
  def assess_security_risk(tool_name: str, tool_input: dict) -> str:
@@ -174,21 +171,18 @@ def assess_security_risk(tool_name: str, tool_input: dict) -> str:
174
171
  ]
175
172
  if any(pattern in command for pattern in dangerous_patterns):
176
173
  return "high"
177
- elif any(word in command for word in ["install", "delete", "format", "kill"]):
174
+ if any(word in command for word in ["install", "delete", "format", "kill"]):
178
175
  return "medium"
179
- else:
180
- return "low"
181
- elif tool_name in ["Write", "Edit", "MultiEdit"]:
176
+ return "low"
177
+ if tool_name in ["Write", "Edit", "MultiEdit"]:
182
178
  file_path = tool_input.get("file_path", "")
183
179
  # Check for system file modifications
184
180
  if any(path in file_path for path in ["/etc/", "/usr/", "/var/", "/sys/"]):
185
181
  return "high"
186
- elif file_path.startswith("/"):
182
+ if file_path.startswith("/"):
187
183
  return "medium"
188
- else:
189
- return "low"
190
- else:
191
184
  return "low"
185
+ return "low"
192
186
 
193
187
 
194
188
  def extract_tool_results(event: dict) -> dict:
@@ -13,7 +13,7 @@ agent outputs because:
13
13
  """
14
14
 
15
15
  import re
16
- from typing import Any, Dict, List
16
+ from typing import Dict, List
17
17
 
18
18
  from claude_mpm.core.config import Config
19
19
  from claude_mpm.core.logger import get_logger
@@ -162,7 +162,7 @@ INSTRUCTIONS: Review your memory above before proceeding. Apply learned patterns
162
162
  success=True,
163
163
  data=context.data,
164
164
  modified=False,
165
- error=f"Memory injection failed: {str(e)}",
165
+ error=f"Memory injection failed: {e!s}",
166
166
  )
167
167
 
168
168
 
@@ -319,7 +319,7 @@ class MemoryPostDelegationHook(PostDelegationHook):
319
319
  success=True,
320
320
  data=context.data,
321
321
  modified=False,
322
- error=f"Learning extraction failed: {str(e)}",
322
+ error=f"Learning extraction failed: {e!s}",
323
323
  )
324
324
 
325
325
  def _extract_learnings(self, text: str) -> Dict[str, List[str]]:
@@ -339,7 +339,7 @@ class MemoryPostDelegationHook(PostDelegationHook):
339
339
  Returns:
340
340
  Dictionary mapping learning types to lists of extracted learnings
341
341
  """
342
- learnings = {learning_type: [] for learning_type in self.type_mapping.keys()}
342
+ learnings = {learning_type: [] for learning_type in self.type_mapping}
343
343
  seen_learnings = set() # Avoid duplicates
344
344
 
345
345
  # Pattern to find memory blocks with multiple trigger phrases
@@ -394,7 +394,7 @@ class MemoryPostDelegationHook(PostDelegationHook):
394
394
  f"Unsupported learning type: {learning_type}. Supported types: {list(self.type_mapping.keys())}"
395
395
  )
396
396
  else:
397
- logger.debug(f"Invalid memory block format - missing Type or Content")
397
+ logger.debug("Invalid memory block format - missing Type or Content")
398
398
 
399
399
  # Log summary of extracted learnings
400
400
  total_learnings = sum(len(items) for items in learnings.values())
@@ -6,7 +6,7 @@ from datetime import datetime
6
6
  from typing import Any, Dict, List, Optional
7
7
 
8
8
  from claude_mpm.core.logger import get_logger
9
- from claude_mpm.hooks.base_hook import BaseHook, HookContext, HookResult, HookType
9
+ from claude_mpm.hooks.base_hook import BaseHook, HookContext, HookType
10
10
 
11
11
  logger = get_logger(__name__)
12
12
 
@@ -61,7 +61,7 @@ class ValidationHooks:
61
61
  result.is_valid = False
62
62
  except Exception as e:
63
63
  logger.error(f"Pre-load hook failed: {e}")
64
- result.warnings.append(f"Pre-load hook failed: {str(e)}")
64
+ result.warnings.append(f"Pre-load hook failed: {e!s}")
65
65
 
66
66
  return result
67
67
 
@@ -79,7 +79,7 @@ class ValidationHooks:
79
79
  result.warnings.extend(hook_result.warnings)
80
80
  except Exception as e:
81
81
  logger.error(f"Post-load hook failed: {e}")
82
- result.warnings.append(f"Post-load hook failed: {str(e)}")
82
+ result.warnings.append(f"Post-load hook failed: {e!s}")
83
83
 
84
84
  return result
85
85
 
@@ -107,7 +107,7 @@ class ValidationHooks:
107
107
  result.is_valid = False
108
108
  except Exception as e:
109
109
  logger.error(f"Pre-execute hook failed: {e}")
110
- result.warnings.append(f"Pre-execute hook failed: {str(e)}")
110
+ result.warnings.append(f"Pre-execute hook failed: {e!s}")
111
111
 
112
112
  return result
113
113
 
@@ -118,7 +118,7 @@ async def validate_agent_dependencies(profile_path: Path) -> ValidationResult:
118
118
  result = ValidationResult(is_valid=True)
119
119
 
120
120
  try:
121
- with open(profile_path, "r") as f:
121
+ with open(profile_path) as f:
122
122
  profile_data = yaml.safe_load(f)
123
123
 
124
124
  # Check for circular dependencies
claude_mpm/init.py CHANGED
@@ -8,7 +8,8 @@ Handles creation of necessary directories and configuration files.
8
8
  import json
9
9
  import os
10
10
  import shutil
11
- from typing import Any, Dict, Optional
11
+ import sys
12
+ from typing import Dict, Optional
12
13
 
13
14
  import yaml
14
15
 
@@ -142,12 +143,10 @@ class ProjectInitializer:
142
143
 
143
144
  # Log successful creation with details
144
145
  self.logger.info(f"Initialized project directory at {self.project_dir}")
145
- self.logger.debug(f"Created directories: agents, config, responses, logs")
146
+ self.logger.debug("Created directories: agents, config, responses, logs")
146
147
 
147
148
  # Print appropriate message to console for visibility during startup
148
149
  # BUT: Don't print to stdout when running MCP server (interferes with JSON-RPC)
149
- import sys
150
-
151
150
  is_mcp_mode = "mcp" in sys.argv and "start" in sys.argv
152
151
 
153
152
  if not is_mcp_mode:
@@ -216,8 +215,6 @@ class ProjectInitializer:
216
215
 
217
216
  if migrated_count > 0:
218
217
  # Don't print to stdout when running MCP server
219
- import sys
220
-
221
218
  is_mcp_mode = "mcp" in sys.argv and "start" in sys.argv
222
219
  if not is_mcp_mode:
223
220
  print(
@@ -254,7 +251,7 @@ class ProjectInitializer:
254
251
  """
255
252
  try:
256
253
  # Read existing JSON configuration
257
- with open(old_file, "r") as f:
254
+ with open(old_file) as f:
258
255
  config = json.load(f)
259
256
 
260
257
  # Write as YAML
@@ -327,8 +324,6 @@ class ProjectInitializer:
327
324
  dependencies = {}
328
325
 
329
326
  # Check Python version
330
- import sys
331
-
332
327
  dependencies["python"] = sys.version_info >= (3, 8)
333
328
 
334
329
  # Check Claude CLI
@@ -17,8 +17,8 @@ from .agent_definition import (
17
17
  __all__ = [
18
18
  "AgentDefinition",
19
19
  "AgentMetadata",
20
- "AgentType",
20
+ "AgentPermissions",
21
21
  "AgentSection",
22
+ "AgentType",
22
23
  "AgentWorkflow",
23
- "AgentPermissions",
24
24
  ]
@@ -12,7 +12,6 @@ chronological order for session replay and analysis.
12
12
  """
13
13
 
14
14
  import json
15
- import os
16
15
  from dataclasses import asdict, dataclass, field
17
16
  from datetime import datetime
18
17
  from enum import Enum
@@ -241,29 +240,28 @@ class AgentSession:
241
240
  # Check event type patterns
242
241
  if "prompt" in event_type.lower() or event_type == "user_input":
243
242
  return EventCategory.PROMPT
244
- elif "delegation" in event_type.lower() or event_type == "Task":
243
+ if "delegation" in event_type.lower() or event_type == "Task":
245
244
  return EventCategory.DELEGATION
246
- elif "tool" in event_type.lower() or event_type in [
245
+ if "tool" in event_type.lower() or event_type in [
247
246
  "PreToolUse",
248
247
  "PostToolUse",
249
248
  ]:
250
249
  return EventCategory.TOOL
251
- elif (
250
+ if (
252
251
  "file" in event_type.lower()
253
252
  or "write" in event_type.lower()
254
253
  or "read" in event_type.lower()
255
254
  ):
256
255
  return EventCategory.FILE
257
- elif "todo" in event_type.lower():
256
+ if "todo" in event_type.lower():
258
257
  return EventCategory.TODO
259
- elif "response" in event_type.lower() or event_type in ["Stop", "SubagentStop"]:
258
+ if "response" in event_type.lower() or event_type in ["Stop", "SubagentStop"]:
260
259
  return EventCategory.RESPONSE
261
- elif "memory" in event_type.lower():
260
+ if "memory" in event_type.lower():
262
261
  return EventCategory.MEMORY
263
- elif "status" in event_type.lower() or "session" in event_type.lower():
262
+ if "status" in event_type.lower() or "session" in event_type.lower():
264
263
  return EventCategory.STATUS
265
- else:
266
- return EventCategory.SYSTEM
264
+ return EventCategory.SYSTEM
267
265
 
268
266
  def _process_event(self, event: SessionEvent):
269
267
  """Process specific event types to update session state.
@@ -376,9 +374,8 @@ class AgentSession:
376
374
  self.active_delegation.todos_modified.append(data["todos"])
377
375
 
378
376
  # Track memory updates
379
- elif event.category == EventCategory.MEMORY:
380
- if self.active_delegation:
381
- self.active_delegation.memory_updates.append(data)
377
+ elif event.category == EventCategory.MEMORY and self.active_delegation:
378
+ self.active_delegation.memory_updates.append(data)
382
379
 
383
380
  def finalize(self):
384
381
  """Finalize the session by calculating final metrics.
@@ -534,6 +531,6 @@ class AgentSession:
534
531
 
535
532
  WHY: Enables analysis of historical sessions.
536
533
  """
537
- with open(filepath, "r", encoding="utf-8") as f:
534
+ with open(filepath, encoding="utf-8") as f:
538
535
  data = json.load(f)
539
536
  return cls.from_dict(data)