claude-mpm 3.9.11__py3-none-any.whl → 4.0.4__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 (434) 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 +2 -2
  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 +330 -86
  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 +363 -220
  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 +124 -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/built/components/agent-inference.js +2 -0
  113. claude_mpm/dashboard/static/built/components/event-processor.js +2 -0
  114. claude_mpm/dashboard/static/built/components/event-viewer.js +2 -0
  115. claude_mpm/dashboard/static/built/components/export-manager.js +2 -0
  116. claude_mpm/dashboard/static/built/components/file-tool-tracker.js +2 -0
  117. claude_mpm/dashboard/static/built/components/hud-library-loader.js +2 -0
  118. claude_mpm/dashboard/static/built/components/hud-manager.js +2 -0
  119. claude_mpm/dashboard/static/built/components/hud-visualizer.js +2 -0
  120. claude_mpm/dashboard/static/built/components/module-viewer.js +2 -0
  121. claude_mpm/dashboard/static/built/components/session-manager.js +2 -0
  122. claude_mpm/dashboard/static/built/components/socket-manager.js +2 -0
  123. claude_mpm/dashboard/static/built/components/ui-state-manager.js +2 -0
  124. claude_mpm/dashboard/static/built/components/working-directory.js +2 -0
  125. claude_mpm/dashboard/static/built/dashboard.js +2 -0
  126. claude_mpm/dashboard/static/built/socket-client.js +2 -0
  127. claude_mpm/dashboard/static/css/dashboard.css +27 -8
  128. claude_mpm/dashboard/static/dist/components/agent-inference.js +2 -0
  129. claude_mpm/dashboard/static/dist/components/event-processor.js +2 -0
  130. claude_mpm/dashboard/static/dist/components/event-viewer.js +2 -0
  131. claude_mpm/dashboard/static/dist/components/export-manager.js +2 -0
  132. claude_mpm/dashboard/static/dist/components/file-tool-tracker.js +2 -0
  133. claude_mpm/dashboard/static/dist/components/hud-library-loader.js +2 -0
  134. claude_mpm/dashboard/static/dist/components/hud-manager.js +2 -0
  135. claude_mpm/dashboard/static/dist/components/hud-visualizer.js +2 -0
  136. claude_mpm/dashboard/static/dist/components/module-viewer.js +2 -0
  137. claude_mpm/dashboard/static/dist/components/session-manager.js +2 -0
  138. claude_mpm/dashboard/static/dist/components/socket-manager.js +2 -0
  139. claude_mpm/dashboard/static/dist/components/ui-state-manager.js +2 -0
  140. claude_mpm/dashboard/static/dist/components/working-directory.js +2 -0
  141. claude_mpm/dashboard/static/dist/dashboard.js +2 -0
  142. claude_mpm/dashboard/static/dist/socket-client.js +2 -0
  143. claude_mpm/dashboard/static/js/components/agent-inference.js +80 -76
  144. claude_mpm/dashboard/static/js/components/event-processor.js +71 -67
  145. claude_mpm/dashboard/static/js/components/event-viewer.js +93 -72
  146. claude_mpm/dashboard/static/js/components/export-manager.js +31 -28
  147. claude_mpm/dashboard/static/js/components/file-tool-tracker.js +110 -96
  148. claude_mpm/dashboard/static/js/components/hud-library-loader.js +11 -11
  149. claude_mpm/dashboard/static/js/components/hud-manager.js +73 -73
  150. claude_mpm/dashboard/static/js/components/hud-visualizer.js +163 -163
  151. claude_mpm/dashboard/static/js/components/module-viewer.js +305 -233
  152. claude_mpm/dashboard/static/js/components/session-manager.js +32 -29
  153. claude_mpm/dashboard/static/js/components/socket-manager.js +27 -20
  154. claude_mpm/dashboard/static/js/components/ui-state-manager.js +21 -18
  155. claude_mpm/dashboard/static/js/components/working-directory.js +74 -71
  156. claude_mpm/dashboard/static/js/dashboard.js +178 -453
  157. claude_mpm/dashboard/static/js/extension-error-handler.js +164 -0
  158. claude_mpm/dashboard/static/js/socket-client.js +133 -53
  159. claude_mpm/dashboard/templates/index.html +40 -50
  160. claude_mpm/experimental/cli_enhancements.py +60 -58
  161. claude_mpm/generators/__init__.py +1 -1
  162. claude_mpm/generators/agent_profile_generator.py +75 -65
  163. claude_mpm/hooks/__init__.py +1 -1
  164. claude_mpm/hooks/base_hook.py +33 -28
  165. claude_mpm/hooks/claude_hooks/__init__.py +1 -1
  166. claude_mpm/hooks/claude_hooks/connection_pool.py +120 -0
  167. claude_mpm/hooks/claude_hooks/event_handlers.py +743 -0
  168. claude_mpm/hooks/claude_hooks/hook_handler.py +415 -1331
  169. claude_mpm/hooks/claude_hooks/hook_wrapper.sh +4 -4
  170. claude_mpm/hooks/claude_hooks/memory_integration.py +221 -0
  171. claude_mpm/hooks/claude_hooks/response_tracking.py +348 -0
  172. claude_mpm/hooks/claude_hooks/tool_analysis.py +230 -0
  173. claude_mpm/hooks/memory_integration_hook.py +140 -100
  174. claude_mpm/hooks/tool_call_interceptor.py +89 -76
  175. claude_mpm/hooks/validation_hooks.py +57 -49
  176. claude_mpm/init.py +145 -121
  177. claude_mpm/models/__init__.py +9 -9
  178. claude_mpm/models/agent_definition.py +33 -23
  179. claude_mpm/models/agent_session.py +228 -200
  180. claude_mpm/scripts/__init__.py +1 -1
  181. claude_mpm/scripts/socketio_daemon.py +192 -75
  182. claude_mpm/scripts/socketio_server_manager.py +328 -0
  183. claude_mpm/scripts/start_activity_logging.py +25 -22
  184. claude_mpm/services/__init__.py +68 -43
  185. claude_mpm/services/agent_capabilities_service.py +271 -0
  186. claude_mpm/services/agents/__init__.py +23 -32
  187. claude_mpm/services/agents/deployment/__init__.py +3 -3
  188. claude_mpm/services/agents/deployment/agent_config_provider.py +310 -0
  189. claude_mpm/services/agents/deployment/agent_configuration_manager.py +359 -0
  190. claude_mpm/services/agents/deployment/agent_definition_factory.py +84 -0
  191. claude_mpm/services/agents/deployment/agent_deployment.py +415 -2113
  192. claude_mpm/services/agents/deployment/agent_discovery_service.py +387 -0
  193. claude_mpm/services/agents/deployment/agent_environment_manager.py +293 -0
  194. claude_mpm/services/agents/deployment/agent_filesystem_manager.py +387 -0
  195. claude_mpm/services/agents/deployment/agent_format_converter.py +453 -0
  196. claude_mpm/services/agents/deployment/agent_frontmatter_validator.py +161 -0
  197. claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +345 -495
  198. claude_mpm/services/agents/deployment/agent_metrics_collector.py +279 -0
  199. claude_mpm/services/agents/deployment/agent_restore_handler.py +88 -0
  200. claude_mpm/services/agents/deployment/agent_template_builder.py +406 -0
  201. claude_mpm/services/agents/deployment/agent_validator.py +352 -0
  202. claude_mpm/services/agents/deployment/agent_version_manager.py +313 -0
  203. claude_mpm/services/agents/deployment/agent_versioning.py +6 -9
  204. claude_mpm/services/agents/deployment/agents_directory_resolver.py +79 -0
  205. claude_mpm/services/agents/deployment/async_agent_deployment.py +298 -234
  206. claude_mpm/services/agents/deployment/config/__init__.py +13 -0
  207. claude_mpm/services/agents/deployment/config/deployment_config.py +182 -0
  208. claude_mpm/services/agents/deployment/config/deployment_config_manager.py +200 -0
  209. claude_mpm/services/agents/deployment/deployment_config_loader.py +54 -0
  210. claude_mpm/services/agents/deployment/deployment_type_detector.py +124 -0
  211. claude_mpm/services/agents/deployment/facade/__init__.py +18 -0
  212. claude_mpm/services/agents/deployment/facade/async_deployment_executor.py +159 -0
  213. claude_mpm/services/agents/deployment/facade/deployment_executor.py +73 -0
  214. claude_mpm/services/agents/deployment/facade/deployment_facade.py +270 -0
  215. claude_mpm/services/agents/deployment/facade/sync_deployment_executor.py +178 -0
  216. claude_mpm/services/agents/deployment/interface_adapter.py +227 -0
  217. claude_mpm/services/agents/deployment/lifecycle_health_checker.py +85 -0
  218. claude_mpm/services/agents/deployment/lifecycle_performance_tracker.py +100 -0
  219. claude_mpm/services/agents/deployment/pipeline/__init__.py +32 -0
  220. claude_mpm/services/agents/deployment/pipeline/pipeline_builder.py +158 -0
  221. claude_mpm/services/agents/deployment/pipeline/pipeline_context.py +159 -0
  222. claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +169 -0
  223. claude_mpm/services/agents/deployment/pipeline/steps/__init__.py +19 -0
  224. claude_mpm/services/agents/deployment/pipeline/steps/agent_processing_step.py +195 -0
  225. claude_mpm/services/agents/deployment/pipeline/steps/base_step.py +119 -0
  226. claude_mpm/services/agents/deployment/pipeline/steps/configuration_step.py +79 -0
  227. claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +90 -0
  228. claude_mpm/services/agents/deployment/pipeline/steps/validation_step.py +100 -0
  229. claude_mpm/services/agents/deployment/processors/__init__.py +15 -0
  230. claude_mpm/services/agents/deployment/processors/agent_deployment_context.py +98 -0
  231. claude_mpm/services/agents/deployment/processors/agent_deployment_result.py +235 -0
  232. claude_mpm/services/agents/deployment/processors/agent_processor.py +258 -0
  233. claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +318 -0
  234. claude_mpm/services/agents/deployment/results/__init__.py +13 -0
  235. claude_mpm/services/agents/deployment/results/deployment_metrics.py +200 -0
  236. claude_mpm/services/agents/deployment/results/deployment_result_builder.py +249 -0
  237. claude_mpm/services/agents/deployment/strategies/__init__.py +25 -0
  238. claude_mpm/services/agents/deployment/strategies/base_strategy.py +119 -0
  239. claude_mpm/services/agents/deployment/strategies/project_strategy.py +150 -0
  240. claude_mpm/services/agents/deployment/strategies/strategy_selector.py +117 -0
  241. claude_mpm/services/agents/deployment/strategies/system_strategy.py +116 -0
  242. claude_mpm/services/agents/deployment/strategies/user_strategy.py +137 -0
  243. claude_mpm/services/agents/deployment/system_instructions_deployer.py +108 -0
  244. claude_mpm/services/agents/deployment/validation/__init__.py +19 -0
  245. claude_mpm/services/agents/deployment/validation/agent_validator.py +323 -0
  246. claude_mpm/services/agents/deployment/validation/deployment_validator.py +238 -0
  247. claude_mpm/services/agents/deployment/validation/template_validator.py +299 -0
  248. claude_mpm/services/agents/deployment/validation/validation_result.py +226 -0
  249. claude_mpm/services/agents/loading/__init__.py +2 -2
  250. claude_mpm/services/agents/loading/agent_profile_loader.py +259 -229
  251. claude_mpm/services/agents/loading/base_agent_manager.py +90 -81
  252. claude_mpm/services/agents/loading/framework_agent_loader.py +154 -129
  253. claude_mpm/services/agents/management/__init__.py +2 -2
  254. claude_mpm/services/agents/management/agent_capabilities_generator.py +72 -58
  255. claude_mpm/services/agents/management/agent_management_service.py +209 -156
  256. claude_mpm/services/agents/memory/__init__.py +9 -6
  257. claude_mpm/services/agents/memory/agent_memory_manager.py +218 -1152
  258. claude_mpm/services/agents/memory/agent_persistence_service.py +20 -16
  259. claude_mpm/services/agents/memory/analyzer.py +430 -0
  260. claude_mpm/services/agents/memory/content_manager.py +376 -0
  261. claude_mpm/services/agents/memory/template_generator.py +468 -0
  262. claude_mpm/services/agents/registry/__init__.py +7 -10
  263. claude_mpm/services/agents/registry/deployed_agent_discovery.py +122 -97
  264. claude_mpm/services/agents/registry/modification_tracker.py +351 -285
  265. claude_mpm/services/async_session_logger.py +187 -153
  266. claude_mpm/services/claude_session_logger.py +87 -72
  267. claude_mpm/services/command_handler_service.py +217 -0
  268. claude_mpm/services/communication/__init__.py +3 -2
  269. claude_mpm/services/core/__init__.py +50 -97
  270. claude_mpm/services/core/base.py +60 -53
  271. claude_mpm/services/core/interfaces/__init__.py +188 -0
  272. claude_mpm/services/core/interfaces/agent.py +351 -0
  273. claude_mpm/services/core/interfaces/communication.py +343 -0
  274. claude_mpm/services/core/interfaces/infrastructure.py +413 -0
  275. claude_mpm/services/core/interfaces/service.py +434 -0
  276. claude_mpm/services/core/interfaces.py +19 -944
  277. claude_mpm/services/event_aggregator.py +208 -170
  278. claude_mpm/services/exceptions.py +387 -308
  279. claude_mpm/services/framework_claude_md_generator/__init__.py +75 -79
  280. claude_mpm/services/framework_claude_md_generator/content_assembler.py +69 -60
  281. claude_mpm/services/framework_claude_md_generator/content_validator.py +65 -61
  282. claude_mpm/services/framework_claude_md_generator/deployment_manager.py +68 -49
  283. claude_mpm/services/framework_claude_md_generator/section_generators/__init__.py +34 -34
  284. claude_mpm/services/framework_claude_md_generator/section_generators/agents.py +25 -22
  285. claude_mpm/services/framework_claude_md_generator/section_generators/claude_pm_init.py +10 -10
  286. claude_mpm/services/framework_claude_md_generator/section_generators/core_responsibilities.py +4 -3
  287. claude_mpm/services/framework_claude_md_generator/section_generators/delegation_constraints.py +4 -3
  288. claude_mpm/services/framework_claude_md_generator/section_generators/environment_config.py +4 -3
  289. claude_mpm/services/framework_claude_md_generator/section_generators/footer.py +6 -5
  290. claude_mpm/services/framework_claude_md_generator/section_generators/header.py +8 -7
  291. claude_mpm/services/framework_claude_md_generator/section_generators/orchestration_principles.py +4 -3
  292. claude_mpm/services/framework_claude_md_generator/section_generators/role_designation.py +6 -5
  293. claude_mpm/services/framework_claude_md_generator/section_generators/subprocess_validation.py +9 -8
  294. claude_mpm/services/framework_claude_md_generator/section_generators/todo_task_tools.py +4 -3
  295. claude_mpm/services/framework_claude_md_generator/section_generators/troubleshooting.py +5 -4
  296. claude_mpm/services/framework_claude_md_generator/section_manager.py +28 -27
  297. claude_mpm/services/framework_claude_md_generator/version_manager.py +30 -28
  298. claude_mpm/services/hook_service.py +106 -114
  299. claude_mpm/services/infrastructure/__init__.py +7 -5
  300. claude_mpm/services/infrastructure/context_preservation.py +233 -199
  301. claude_mpm/services/infrastructure/daemon_manager.py +279 -0
  302. claude_mpm/services/infrastructure/logging.py +83 -76
  303. claude_mpm/services/infrastructure/monitoring.py +547 -404
  304. claude_mpm/services/mcp_gateway/__init__.py +30 -13
  305. claude_mpm/services/mcp_gateway/config/__init__.py +2 -2
  306. claude_mpm/services/mcp_gateway/config/config_loader.py +61 -56
  307. claude_mpm/services/mcp_gateway/config/config_schema.py +50 -41
  308. claude_mpm/services/mcp_gateway/config/configuration.py +82 -75
  309. claude_mpm/services/mcp_gateway/core/__init__.py +13 -20
  310. claude_mpm/services/mcp_gateway/core/base.py +80 -67
  311. claude_mpm/services/mcp_gateway/core/exceptions.py +60 -46
  312. claude_mpm/services/mcp_gateway/core/interfaces.py +87 -84
  313. claude_mpm/services/mcp_gateway/main.py +287 -137
  314. claude_mpm/services/mcp_gateway/registry/__init__.py +1 -1
  315. claude_mpm/services/mcp_gateway/registry/service_registry.py +97 -94
  316. claude_mpm/services/mcp_gateway/registry/tool_registry.py +135 -126
  317. claude_mpm/services/mcp_gateway/server/__init__.py +2 -2
  318. claude_mpm/services/mcp_gateway/server/mcp_gateway.py +105 -110
  319. claude_mpm/services/mcp_gateway/server/stdio_handler.py +105 -107
  320. claude_mpm/services/mcp_gateway/server/stdio_server.py +691 -0
  321. claude_mpm/services/mcp_gateway/tools/__init__.py +4 -2
  322. claude_mpm/services/mcp_gateway/tools/base_adapter.py +109 -119
  323. claude_mpm/services/mcp_gateway/tools/document_summarizer.py +283 -215
  324. claude_mpm/services/mcp_gateway/tools/hello_world.py +122 -120
  325. claude_mpm/services/mcp_gateway/tools/ticket_tools.py +652 -0
  326. claude_mpm/services/mcp_gateway/tools/unified_ticket_tool.py +606 -0
  327. claude_mpm/services/memory/__init__.py +2 -2
  328. claude_mpm/services/memory/builder.py +451 -362
  329. claude_mpm/services/memory/cache/__init__.py +2 -2
  330. claude_mpm/services/memory/cache/shared_prompt_cache.py +232 -194
  331. claude_mpm/services/memory/cache/simple_cache.py +107 -93
  332. claude_mpm/services/memory/indexed_memory.py +195 -193
  333. claude_mpm/services/memory/optimizer.py +267 -234
  334. claude_mpm/services/memory/router.py +571 -263
  335. claude_mpm/services/memory_hook_service.py +237 -0
  336. claude_mpm/services/port_manager.py +575 -0
  337. claude_mpm/services/project/__init__.py +3 -3
  338. claude_mpm/services/project/analyzer.py +451 -305
  339. claude_mpm/services/project/registry.py +262 -240
  340. claude_mpm/services/recovery_manager.py +287 -231
  341. claude_mpm/services/response_tracker.py +87 -67
  342. claude_mpm/services/runner_configuration_service.py +587 -0
  343. claude_mpm/services/session_management_service.py +304 -0
  344. claude_mpm/services/socketio/__init__.py +4 -4
  345. claude_mpm/services/socketio/client_proxy.py +174 -0
  346. claude_mpm/services/socketio/handlers/__init__.py +3 -3
  347. claude_mpm/services/socketio/handlers/base.py +44 -30
  348. claude_mpm/services/socketio/handlers/connection.py +166 -64
  349. claude_mpm/services/socketio/handlers/file.py +123 -108
  350. claude_mpm/services/socketio/handlers/git.py +607 -373
  351. claude_mpm/services/socketio/handlers/hook.py +185 -0
  352. claude_mpm/services/socketio/handlers/memory.py +4 -4
  353. claude_mpm/services/socketio/handlers/project.py +4 -4
  354. claude_mpm/services/socketio/handlers/registry.py +53 -38
  355. claude_mpm/services/socketio/server/__init__.py +18 -0
  356. claude_mpm/services/socketio/server/broadcaster.py +252 -0
  357. claude_mpm/services/socketio/server/core.py +399 -0
  358. claude_mpm/services/socketio/server/main.py +323 -0
  359. claude_mpm/services/socketio_client_manager.py +160 -133
  360. claude_mpm/services/socketio_server.py +36 -1885
  361. claude_mpm/services/subprocess_launcher_service.py +316 -0
  362. claude_mpm/services/system_instructions_service.py +258 -0
  363. claude_mpm/services/ticket_manager.py +19 -533
  364. claude_mpm/services/utility_service.py +285 -0
  365. claude_mpm/services/version_control/__init__.py +18 -21
  366. claude_mpm/services/version_control/branch_strategy.py +20 -10
  367. claude_mpm/services/version_control/conflict_resolution.py +37 -13
  368. claude_mpm/services/version_control/git_operations.py +52 -21
  369. claude_mpm/services/version_control/semantic_versioning.py +92 -53
  370. claude_mpm/services/version_control/version_parser.py +145 -125
  371. claude_mpm/services/version_service.py +270 -0
  372. claude_mpm/storage/__init__.py +2 -2
  373. claude_mpm/storage/state_storage.py +177 -181
  374. claude_mpm/ticket_wrapper.py +2 -2
  375. claude_mpm/utils/__init__.py +2 -2
  376. claude_mpm/utils/agent_dependency_loader.py +453 -243
  377. claude_mpm/utils/config_manager.py +157 -118
  378. claude_mpm/utils/console.py +1 -1
  379. claude_mpm/utils/dependency_cache.py +102 -107
  380. claude_mpm/utils/dependency_manager.py +52 -47
  381. claude_mpm/utils/dependency_strategies.py +131 -96
  382. claude_mpm/utils/environment_context.py +110 -102
  383. claude_mpm/utils/error_handler.py +75 -55
  384. claude_mpm/utils/file_utils.py +80 -67
  385. claude_mpm/utils/framework_detection.py +12 -11
  386. claude_mpm/utils/import_migration_example.py +12 -60
  387. claude_mpm/utils/imports.py +48 -45
  388. claude_mpm/utils/path_operations.py +100 -93
  389. claude_mpm/utils/robust_installer.py +172 -164
  390. claude_mpm/utils/session_logging.py +30 -23
  391. claude_mpm/utils/subprocess_utils.py +99 -61
  392. claude_mpm/validation/__init__.py +1 -1
  393. claude_mpm/validation/agent_validator.py +151 -111
  394. claude_mpm/validation/frontmatter_validator.py +92 -71
  395. {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.4.dist-info}/METADATA +90 -22
  396. claude_mpm-4.0.4.dist-info/RECORD +417 -0
  397. {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.4.dist-info}/entry_points.txt +1 -0
  398. {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.4.dist-info}/licenses/LICENSE +1 -1
  399. claude_mpm/cli/commands/run_guarded.py +0 -511
  400. claude_mpm/config/memory_guardian_config.py +0 -325
  401. claude_mpm/config/memory_guardian_yaml.py +0 -335
  402. claude_mpm/core/config_paths.py +0 -150
  403. claude_mpm/core/memory_aware_runner.py +0 -353
  404. claude_mpm/dashboard/static/js/dashboard-original.js +0 -4134
  405. claude_mpm/deployment_paths.py +0 -261
  406. claude_mpm/hooks/claude_hooks/hook_handler_fixed.py +0 -454
  407. claude_mpm/models/state_models.py +0 -433
  408. claude_mpm/services/agent/__init__.py +0 -24
  409. claude_mpm/services/agent/deployment.py +0 -2548
  410. claude_mpm/services/agent/management.py +0 -598
  411. claude_mpm/services/agent/registry.py +0 -813
  412. claude_mpm/services/agents/registry/agent_registry.py +0 -813
  413. claude_mpm/services/communication/socketio.py +0 -1935
  414. claude_mpm/services/communication/websocket.py +0 -479
  415. claude_mpm/services/framework_claude_md_generator.py +0 -624
  416. claude_mpm/services/health_monitor.py +0 -893
  417. claude_mpm/services/infrastructure/graceful_degradation.py +0 -616
  418. claude_mpm/services/infrastructure/health_monitor.py +0 -775
  419. claude_mpm/services/infrastructure/memory_dashboard.py +0 -479
  420. claude_mpm/services/infrastructure/memory_guardian.py +0 -944
  421. claude_mpm/services/infrastructure/restart_protection.py +0 -642
  422. claude_mpm/services/infrastructure/state_manager.py +0 -774
  423. claude_mpm/services/mcp_gateway/manager.py +0 -334
  424. claude_mpm/services/optimized_hook_service.py +0 -542
  425. claude_mpm/services/project_analyzer.py +0 -864
  426. claude_mpm/services/project_registry.py +0 -608
  427. claude_mpm/services/standalone_socketio_server.py +0 -1300
  428. claude_mpm/services/ticket_manager_di.py +0 -318
  429. claude_mpm/services/ticketing_service_original.py +0 -510
  430. claude_mpm/utils/paths.py +0 -395
  431. claude_mpm/utils/platform_memory.py +0 -524
  432. claude_mpm-3.9.11.dist-info/RECORD +0 -306
  433. {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.4.dist-info}/WHEEL +0 -0
  434. {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.4.dist-info}/top_level.txt +0 -0
@@ -4,42 +4,45 @@ This module encapsulates the logic for running one-time Claude commands,
4
4
  breaking down the monolithic run_oneshot method into focused, testable components.
5
5
  """
6
6
 
7
- import json
8
7
  import os
9
8
  import subprocess
10
9
  import time
11
10
  import uuid
12
- from pathlib import Path
13
- from typing import Optional, Dict, Any, Tuple, List, TYPE_CHECKING
14
11
  from logging import Logger
12
+ from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple
15
13
 
16
14
  from claude_mpm.core.logger import get_logger
17
15
  from claude_mpm.core.typing_utils import (
18
- SessionId, SessionStatus, ErrorResult, SuccessResult,
19
- SessionConfig, SessionResult, SessionEvent
16
+ ErrorResult,
17
+ SessionConfig,
18
+ SessionEvent,
19
+ SessionId,
20
+ SessionResult,
21
+ SessionStatus,
22
+ SuccessResult,
20
23
  )
21
24
 
22
25
  if TYPE_CHECKING:
23
- from claude_mpm.core.claude_runner import ClaudeRunner
24
- from claude_mpm.services.socketio_server import SocketIOClientProxy
25
- from claude_mpm.services.response_logger import ResponseLogger
26
26
  from claude_mpm.agents.memory.ticket_manager import TicketManager
27
+ from claude_mpm.core.claude_runner import ClaudeRunner
27
28
  from claude_mpm.core.logger import ProjectLogger
29
+ from claude_mpm.services.response_logger import ResponseLogger
30
+ from claude_mpm.services.socketio_server import SocketIOClientProxy
28
31
 
29
32
 
30
33
  class OneshotSession:
31
34
  """Manages a single oneshot Claude execution session.
32
-
35
+
33
36
  WHY: This class extracts the complex oneshot logic from ClaudeRunner,
34
37
  reducing cyclomatic complexity and improving maintainability.
35
-
38
+
36
39
  DESIGN DECISION: Each method focuses on a single responsibility with
37
40
  complexity < 10 and lines < 80, making the code easier to test and modify.
38
41
  """
39
-
42
+
40
43
  def __init__(self, runner):
41
44
  """Initialize the oneshot session with a reference to the runner.
42
-
45
+
43
46
  Args:
44
47
  runner: The ClaudeRunner instance that owns this session
45
48
  """
@@ -48,133 +51,147 @@ class OneshotSession:
48
51
  self.start_time = None
49
52
  self.session_id = None
50
53
  self.original_cwd = None
51
-
54
+
52
55
  def initialize_session(self, prompt: str) -> Tuple[bool, Optional[str]]:
53
56
  """Initialize the oneshot session.
54
-
57
+
55
58
  Returns:
56
59
  Tuple of (success, error_message)
57
60
  """
58
61
  self.start_time = time.time()
59
62
  self.session_id = str(uuid.uuid4())
60
-
63
+
61
64
  # Check for special MPM commands
62
65
  if prompt.strip().startswith("/mpm:"):
63
66
  result = self.runner._handle_mpm_command(prompt.strip())
64
67
  return (result, None)
65
-
68
+
66
69
  # Initialize WebSocket if enabled
67
70
  if self.runner.enable_websocket:
68
71
  self._setup_websocket()
69
-
72
+
70
73
  # Log session start
71
74
  if self.runner.project_logger:
72
75
  self.runner.project_logger.log_system(
73
76
  f"Starting non-interactive session with prompt: {prompt[:100]}",
74
77
  level="INFO",
75
- component="session"
78
+ component="session",
76
79
  )
77
-
80
+
78
81
  return (True, None)
79
-
82
+
80
83
  def deploy_agents(self) -> bool:
81
84
  """Deploy system and project agents.
82
-
85
+
83
86
  Returns:
84
87
  True if successful, False otherwise
85
88
  """
86
89
  # Deploy system agents
87
90
  if not self.runner.setup_agents():
88
91
  print("Continuing without native agents...")
89
-
92
+
90
93
  # Deploy project-specific agents
91
94
  self.runner.deploy_project_agents_to_claude()
92
-
95
+
93
96
  return True
94
-
97
+
95
98
  def setup_infrastructure(self) -> Dict[str, Any]:
96
99
  """Set up the execution environment and build the command.
97
-
100
+
98
101
  Returns:
99
102
  Dictionary containing command, environment, and other setup details
100
103
  """
101
104
  infrastructure = {
102
- 'env': self._prepare_environment(),
103
- 'cmd': self._build_command(),
104
- 'working_dir_changed': False
105
+ "env": self._prepare_environment(),
106
+ "cmd": self._build_command(),
107
+ "working_dir_changed": False,
105
108
  }
106
-
109
+
107
110
  # Change to user working directory if specified
108
- if 'CLAUDE_MPM_USER_PWD' in infrastructure['env']:
109
- user_pwd = infrastructure['env']['CLAUDE_MPM_USER_PWD']
110
- infrastructure['env']['CLAUDE_WORKSPACE'] = user_pwd
111
-
111
+ if "CLAUDE_MPM_USER_PWD" in infrastructure["env"]:
112
+ user_pwd = infrastructure["env"]["CLAUDE_MPM_USER_PWD"]
113
+ infrastructure["env"]["CLAUDE_WORKSPACE"] = user_pwd
114
+
112
115
  try:
113
116
  self.original_cwd = os.getcwd()
114
117
  os.chdir(user_pwd)
115
- infrastructure['working_dir_changed'] = True
118
+ infrastructure["working_dir_changed"] = True
116
119
  self.logger.info(f"Changed working directory to: {user_pwd}")
117
120
  except (PermissionError, FileNotFoundError, OSError) as e:
118
121
  self.logger.warning(f"Could not change to directory {user_pwd}: {e}")
119
122
  self.original_cwd = None
120
-
123
+
121
124
  return infrastructure
122
-
123
- def execute_command(self, prompt: str, context: Optional[str],
124
- infrastructure: Dict[str, Any]) -> Tuple[bool, Optional[str]]:
125
+
126
+ def execute_command(
127
+ self, prompt: str, context: Optional[str], infrastructure: Dict[str, Any]
128
+ ) -> Tuple[bool, Optional[str]]:
125
129
  """Execute the Claude command with the given prompt.
126
-
130
+
127
131
  Args:
128
132
  prompt: The user's prompt
129
133
  context: Optional context to prepend
130
134
  infrastructure: Setup details from setup_infrastructure
131
-
135
+
132
136
  Returns:
133
137
  Tuple of (success, response_or_error)
134
138
  """
135
139
  # Build final command
136
140
  cmd = self._build_final_command(prompt, context, infrastructure)
137
-
141
+
138
142
  # Log and notify
139
143
  self._notify_execution_start()
140
-
144
+
141
145
  # Execute with proper error handling
142
- return self._run_subprocess(cmd, infrastructure['env'], prompt)
143
-
144
- def _build_final_command(self, prompt: str, context: Optional[str],
145
- infrastructure: Dict[str, Any]) -> list:
146
+ return self._run_subprocess(cmd, infrastructure["env"], prompt)
147
+
148
+ def _build_final_command(
149
+ self, prompt: str, context: Optional[str], infrastructure: Dict[str, Any]
150
+ ) -> list:
146
151
  """Build the final command with prompt and system instructions."""
147
152
  full_prompt = f"{context}\n\n{prompt}" if context else prompt
148
- cmd = infrastructure['cmd'] + ["--print", full_prompt]
149
-
153
+ cmd = infrastructure["cmd"] + ["--print", full_prompt]
154
+
150
155
  # Add system instructions if available
151
156
  system_prompt = self.runner._create_system_prompt()
152
- if system_prompt and system_prompt != self._get_simple_context():
153
- cmd.insert(-2, "--append-system-prompt")
154
- cmd.insert(-2, system_prompt)
155
157
 
158
+ # Debug: log the system prompt to check for issues
159
+ if system_prompt:
160
+ self.logger.debug(f"System prompt length: {len(system_prompt)}")
161
+ if "Path.cwd()" in system_prompt or "Path(" in system_prompt:
162
+ self.logger.warning("System prompt contains Python code references!")
163
+
164
+ if system_prompt and system_prompt != self._get_simple_context():
165
+ # The problem might be with insert positioning
166
+ # Let's add system prompt differently
167
+ cmd.extend(["--append-system-prompt", system_prompt])
168
+
156
169
  return cmd
157
-
170
+
158
171
  def _notify_execution_start(self) -> None:
159
172
  """Log and notify about execution start."""
160
173
  if self.runner.project_logger:
161
174
  self.runner.project_logger.log_system(
162
- "Executing Claude subprocess",
163
- level="INFO",
164
- component="session"
175
+ "Executing Claude subprocess", level="INFO", component="session"
165
176
  )
166
-
177
+
167
178
  if self.runner.websocket_server:
168
179
  self.runner.websocket_server.claude_status_changed(
169
- status="running",
170
- message="Executing Claude oneshot command"
180
+ status="running", message="Executing Claude oneshot command"
171
181
  )
172
-
173
- def _run_subprocess(self, cmd: list, env: dict, prompt: str) -> Tuple[bool, Optional[str]]:
182
+
183
+ def _run_subprocess(
184
+ self, cmd: list, env: dict, prompt: str
185
+ ) -> Tuple[bool, Optional[str]]:
174
186
  """Run the subprocess and handle all exception types."""
175
187
  try:
176
- result = subprocess.run(cmd, capture_output=True, text=True, env=env)
188
+ # Debug: log the command being run
189
+ self.logger.debug(f"Running command: {' '.join(cmd[:5])}...")
190
+ if len(cmd) > 5:
191
+ self.logger.debug(f"Command has {len(cmd)} arguments total")
177
192
 
193
+ result = subprocess.run(cmd, capture_output=True, text=True, env=env)
194
+
178
195
  if result.returncode == 0:
179
196
  response = result.stdout.strip()
180
197
  self._handle_successful_response(response, prompt)
@@ -183,7 +200,7 @@ class OneshotSession:
183
200
  error_msg = result.stderr or "Unknown error"
184
201
  self._handle_error_response(error_msg, result.returncode)
185
202
  return (False, error_msg)
186
-
203
+
187
204
  except subprocess.TimeoutExpired as e:
188
205
  return self._handle_timeout(e)
189
206
  except FileNotFoundError:
@@ -196,7 +213,7 @@ class OneshotSession:
196
213
  return self._handle_memory_error(e)
197
214
  except Exception as e:
198
215
  return self._handle_unexpected_error(e)
199
-
216
+
200
217
  def cleanup_session(self) -> None:
201
218
  """Clean up the session and restore state."""
202
219
  # Restore original working directory
@@ -205,7 +222,7 @@ class OneshotSession:
205
222
  os.chdir(self.original_cwd)
206
223
  except Exception:
207
224
  pass
208
-
225
+
209
226
  # Log session summary
210
227
  if self.runner.project_logger:
211
228
  try:
@@ -213,65 +230,61 @@ class OneshotSession:
213
230
  self.runner.project_logger.log_system(
214
231
  f"Session {summary['session_id']} completed",
215
232
  level="INFO",
216
- component="session"
233
+ component="session",
217
234
  )
218
235
  except Exception as e:
219
236
  self.logger.debug(f"Failed to log session summary: {e}")
220
-
237
+
221
238
  # End WebSocket session
222
239
  if self.runner.websocket_server:
223
240
  self.runner.websocket_server.claude_status_changed(
224
- status="stopped",
225
- message="Session completed"
241
+ status="stopped", message="Session completed"
226
242
  )
227
243
  self.runner.websocket_server.session_ended()
228
-
244
+
229
245
  # Private helper methods
230
-
246
+
231
247
  def _setup_websocket(self) -> None:
232
248
  """Initialize WebSocket connection."""
233
249
  try:
234
250
  from claude_mpm.services.socketio_server import SocketIOClientProxy
251
+
235
252
  self.runner.websocket_server = SocketIOClientProxy(
236
253
  port=self.runner.websocket_port
237
254
  )
238
255
  self.runner.websocket_server.start()
239
256
  self.logger.info("Connected to Socket.IO monitoring server")
240
-
257
+
241
258
  # Notify session start
242
259
  self.runner.websocket_server.session_started(
243
260
  session_id=self.session_id,
244
261
  launch_method="oneshot",
245
- working_dir=os.getcwd()
262
+ working_dir=os.getcwd(),
246
263
  )
247
264
  except (ImportError, ConnectionError, Exception) as e:
248
265
  self.logger.warning(f"Socket.IO connection failed: {e}")
249
266
  self.runner.websocket_server = None
250
-
267
+
251
268
  def _prepare_environment(self) -> Dict[str, str]:
252
269
  """Prepare the execution environment."""
253
270
  return os.environ.copy()
254
-
271
+
255
272
  def _build_command(self) -> list:
256
273
  """Build the base Claude command."""
257
- cmd = [
258
- "claude",
259
- "--model", "opus",
260
- "--dangerously-skip-permissions"
261
- ]
262
-
274
+ cmd = ["claude", "--model", "opus", "--dangerously-skip-permissions"]
275
+
263
276
  # Add custom arguments
264
277
  if self.runner.claude_args:
265
278
  cmd.extend(self.runner.claude_args)
266
-
279
+
267
280
  return cmd
268
-
281
+
269
282
  def _handle_successful_response(self, response: str, prompt: str) -> None:
270
283
  """Process a successful Claude response."""
271
284
  print(response)
272
-
285
+
273
286
  execution_time = time.time() - self.start_time
274
-
287
+
275
288
  # Log response if enabled
276
289
  if self.runner.response_logger and response:
277
290
  response_summary = prompt[:200] + "..." if len(prompt) > 200 else prompt
@@ -282,184 +295,205 @@ class OneshotSession:
282
295
  "mode": "oneshot",
283
296
  "model": "opus",
284
297
  "exit_code": 0,
285
- "execution_time": execution_time
298
+ "execution_time": execution_time,
286
299
  },
287
- agent="claude-direct"
300
+ agent="claude-direct",
288
301
  )
289
-
302
+
290
303
  # Broadcast to WebSocket
291
304
  if self.runner.websocket_server and response:
292
305
  self.runner.websocket_server.claude_output(response, "stdout")
293
-
306
+
294
307
  # Check for delegation
295
308
  if self.runner._contains_delegation(response):
296
309
  agent_name = self.runner._extract_agent_from_response(response)
297
310
  if agent_name:
298
311
  self.runner.websocket_server.agent_delegated(
299
- agent=agent_name,
300
- task=prompt[:100],
301
- status="detected"
312
+ agent=agent_name, task=prompt[:100], status="detected"
302
313
  )
303
-
314
+
304
315
  # Log completion
305
316
  if self.runner.project_logger:
306
317
  self.runner.project_logger.log_system(
307
318
  f"Non-interactive session completed successfully in {execution_time:.2f}s",
308
319
  level="INFO",
309
- component="session"
320
+ component="session",
310
321
  )
311
-
312
- self.runner._log_session_event({
313
- "event": "session_complete",
314
- "success": True,
315
- "execution_time": execution_time,
316
- "response_length": len(response)
317
- })
318
-
322
+
323
+ self.runner._log_session_event(
324
+ {
325
+ "event": "session_complete",
326
+ "success": True,
327
+ "execution_time": execution_time,
328
+ "response_length": len(response),
329
+ }
330
+ )
331
+
319
332
  # Extract tickets if enabled
320
333
  if self.runner.enable_tickets and self.runner.ticket_manager and response:
321
334
  self.runner._extract_tickets(response)
322
-
335
+
323
336
  def _handle_error_response(self, error_msg: str, return_code: int) -> None:
324
337
  """Handle an error response from Claude."""
325
338
  print(f"Error: {error_msg}")
326
339
 
340
+ # Debug: print full traceback if available
341
+ import traceback
342
+ if "Traceback" in error_msg or "Error:" in error_msg:
343
+ self.logger.debug(f"Full error output:\n{error_msg}")
344
+
327
345
  # Broadcast error
328
346
  if self.runner.websocket_server:
329
347
  self.runner.websocket_server.claude_output(error_msg, "stderr")
330
348
  self.runner.websocket_server.claude_status_changed(
331
- status="error",
332
- message=f"Command failed with code {return_code}"
349
+ status="error", message=f"Command failed with code {return_code}"
333
350
  )
334
-
351
+
335
352
  # Log error
336
353
  if self.runner.project_logger:
337
354
  self.runner.project_logger.log_system(
338
355
  f"Non-interactive session failed: {error_msg}",
339
356
  level="ERROR",
340
- component="session"
357
+ component="session",
358
+ )
359
+ self.runner._log_session_event(
360
+ {
361
+ "event": "session_failed",
362
+ "success": False,
363
+ "error": error_msg,
364
+ "return_code": return_code,
365
+ }
341
366
  )
342
- self.runner._log_session_event({
343
- "event": "session_failed",
344
- "success": False,
345
- "error": error_msg,
346
- "return_code": return_code
347
- })
348
-
367
+
349
368
  def _handle_timeout(self, e: subprocess.TimeoutExpired) -> Tuple[bool, str]:
350
369
  """Handle command timeout."""
351
370
  error_msg = f"Command timed out after {e.timeout} seconds"
352
371
  print(f"⏱️ {error_msg}")
353
-
372
+
354
373
  if self.runner.project_logger:
355
- self.runner.project_logger.log_system(error_msg, level="ERROR", component="session")
356
- self.runner._log_session_event({
357
- "event": "session_timeout",
358
- "success": False,
359
- "timeout": e.timeout,
360
- "exception_type": "TimeoutExpired"
361
- })
362
-
374
+ self.runner.project_logger.log_system(
375
+ error_msg, level="ERROR", component="session"
376
+ )
377
+ self.runner._log_session_event(
378
+ {
379
+ "event": "session_timeout",
380
+ "success": False,
381
+ "timeout": e.timeout,
382
+ "exception_type": "TimeoutExpired",
383
+ }
384
+ )
385
+
363
386
  return (False, error_msg)
364
-
387
+
365
388
  def _handle_claude_not_found(self) -> Tuple[bool, str]:
366
389
  """Handle Claude CLI not found error."""
367
- error_msg = "Claude CLI not found. Please ensure 'claude' is installed and in your PATH"
390
+ error_msg = (
391
+ "Claude CLI not found. Please ensure 'claude' is installed and in your PATH"
392
+ )
368
393
  print(f"❌ {error_msg}")
369
- print("\n💡 To fix: Install Claude CLI with 'npm install -g @anthropic-ai/claude-ai'")
370
-
394
+ print(
395
+ "\n💡 To fix: Install Claude CLI with 'npm install -g @anthropic-ai/claude-ai'"
396
+ )
397
+
371
398
  if self.runner.project_logger:
372
399
  self.runner.project_logger.log_system(
373
- f"{error_msg}",
374
- level="ERROR",
375
- component="session"
400
+ f"{error_msg}", level="ERROR", component="session"
376
401
  )
377
- self.runner._log_session_event({
378
- "event": "session_exception",
379
- "success": False,
380
- "exception": "FileNotFoundError",
381
- "exception_type": "FileNotFoundError"
382
- })
383
-
402
+ self.runner._log_session_event(
403
+ {
404
+ "event": "session_exception",
405
+ "success": False,
406
+ "exception": "FileNotFoundError",
407
+ "exception_type": "FileNotFoundError",
408
+ }
409
+ )
410
+
384
411
  return (False, error_msg)
385
-
412
+
386
413
  def _handle_permission_error(self, e: PermissionError) -> Tuple[bool, str]:
387
414
  """Handle permission denied error."""
388
415
  error_msg = f"Permission denied executing Claude CLI: {e}"
389
416
  print(f"❌ {error_msg}")
390
-
417
+
391
418
  if self.runner.project_logger:
392
- self.runner.project_logger.log_system(error_msg, level="ERROR", component="session")
393
- self.runner._log_session_event({
394
- "event": "session_exception",
395
- "success": False,
396
- "exception": str(e),
397
- "exception_type": "PermissionError"
398
- })
399
-
419
+ self.runner.project_logger.log_system(
420
+ error_msg, level="ERROR", component="session"
421
+ )
422
+ self.runner._log_session_event(
423
+ {
424
+ "event": "session_exception",
425
+ "success": False,
426
+ "exception": str(e),
427
+ "exception_type": "PermissionError",
428
+ }
429
+ )
430
+
400
431
  return (False, error_msg)
401
-
432
+
402
433
  def _handle_keyboard_interrupt(self) -> Tuple[bool, str]:
403
434
  """Handle keyboard interrupt."""
404
435
  print("\n⚠️ Command interrupted by user")
405
-
436
+
406
437
  if self.runner.project_logger:
407
438
  self.runner.project_logger.log_system(
408
- "Session interrupted by user",
409
- level="INFO",
410
- component="session"
439
+ "Session interrupted by user", level="INFO", component="session"
411
440
  )
412
- self.runner._log_session_event({
413
- "event": "session_interrupted",
414
- "success": False,
415
- "reason": "user_interrupt"
416
- })
417
-
441
+ self.runner._log_session_event(
442
+ {
443
+ "event": "session_interrupted",
444
+ "success": False,
445
+ "reason": "user_interrupt",
446
+ }
447
+ )
448
+
418
449
  return (False, "User interrupted")
419
-
450
+
420
451
  def _handle_memory_error(self, e: MemoryError) -> Tuple[bool, str]:
421
452
  """Handle out of memory error."""
422
453
  error_msg = "Out of memory while processing command"
423
454
  print(f"❌ {error_msg}")
424
-
455
+
425
456
  if self.runner.project_logger:
426
457
  self.runner.project_logger.log_system(
427
- f"{error_msg}: {e}",
428
- level="ERROR",
429
- component="session"
458
+ f"{error_msg}: {e}", level="ERROR", component="session"
430
459
  )
431
- self.runner._log_session_event({
432
- "event": "session_exception",
433
- "success": False,
434
- "exception": str(e),
435
- "exception_type": "MemoryError"
436
- })
437
-
460
+ self.runner._log_session_event(
461
+ {
462
+ "event": "session_exception",
463
+ "success": False,
464
+ "exception": str(e),
465
+ "exception_type": "MemoryError",
466
+ }
467
+ )
468
+
438
469
  return (False, error_msg)
439
-
470
+
440
471
  def _handle_unexpected_error(self, e: Exception) -> Tuple[bool, str]:
441
472
  """Handle unexpected errors."""
442
473
  error_msg = f"Unexpected error: {e}"
443
474
  print(f"❌ {error_msg}")
444
475
  print(f" Error type: {type(e).__name__}")
445
-
476
+
446
477
  if self.runner.project_logger:
447
478
  self.runner.project_logger.log_system(
448
479
  f"Exception during non-interactive session: {e}",
449
480
  level="ERROR",
450
- component="session"
481
+ component="session",
451
482
  )
452
- self.runner._log_session_event({
453
- "event": "session_exception",
454
- "success": False,
455
- "exception": str(e),
456
- "exception_type": type(e).__name__
457
- })
458
-
483
+ self.runner._log_session_event(
484
+ {
485
+ "event": "session_exception",
486
+ "success": False,
487
+ "exception": str(e),
488
+ "exception_type": type(e).__name__,
489
+ }
490
+ )
491
+
459
492
  return (False, error_msg)
460
-
493
+
461
494
  def _get_simple_context(self) -> str:
462
495
  """Get the simple context string for comparison."""
463
496
  # Import here to avoid circular dependency
464
497
  from claude_mpm.core.claude_runner import create_simple_context
465
- return create_simple_context()
498
+
499
+ return create_simple_context()