claude-mpm 3.9.9__py3-none-any.whl → 4.0.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (411) 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 +155 -0
  20. claude_mpm/agents/templates/ops.json +2 -2
  21. claude_mpm/agents/templates/project_organizer.json +1 -1
  22. claude_mpm/agents/templates/qa.json +1 -1
  23. claude_mpm/agents/templates/refactoring_engineer.json +222 -0
  24. claude_mpm/agents/templates/research.json +20 -14
  25. claude_mpm/agents/templates/security.json +1 -1
  26. claude_mpm/agents/templates/ticketing.json +1 -1
  27. claude_mpm/agents/templates/version_control.json +1 -1
  28. claude_mpm/agents/templates/web_qa.json +3 -1
  29. claude_mpm/agents/templates/web_ui.json +2 -2
  30. claude_mpm/cli/__init__.py +90 -49
  31. claude_mpm/cli/__main__.py +3 -2
  32. claude_mpm/cli/commands/__init__.py +21 -18
  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 +143 -762
  39. claude_mpm/cli/commands/mcp_command_router.py +139 -0
  40. claude_mpm/cli/commands/mcp_config_commands.py +20 -0
  41. claude_mpm/cli/commands/mcp_install_commands.py +20 -0
  42. claude_mpm/cli/commands/mcp_server_commands.py +175 -0
  43. claude_mpm/cli/commands/mcp_tool_commands.py +34 -0
  44. claude_mpm/cli/commands/memory.py +239 -203
  45. claude_mpm/cli/commands/monitor.py +203 -81
  46. claude_mpm/cli/commands/run.py +380 -429
  47. claude_mpm/cli/commands/run_config_checker.py +160 -0
  48. claude_mpm/cli/commands/socketio_monitor.py +235 -0
  49. claude_mpm/cli/commands/tickets.py +305 -197
  50. claude_mpm/cli/parser.py +24 -1150
  51. claude_mpm/cli/parsers/__init__.py +29 -0
  52. claude_mpm/cli/parsers/agents_parser.py +136 -0
  53. claude_mpm/cli/parsers/base_parser.py +331 -0
  54. claude_mpm/cli/parsers/config_parser.py +85 -0
  55. claude_mpm/cli/parsers/mcp_parser.py +152 -0
  56. claude_mpm/cli/parsers/memory_parser.py +138 -0
  57. claude_mpm/cli/parsers/monitor_parser.py +104 -0
  58. claude_mpm/cli/parsers/run_parser.py +147 -0
  59. claude_mpm/cli/parsers/tickets_parser.py +203 -0
  60. claude_mpm/cli/ticket_cli.py +7 -3
  61. claude_mpm/cli/utils.py +55 -37
  62. claude_mpm/cli_module/__init__.py +6 -6
  63. claude_mpm/cli_module/args.py +188 -140
  64. claude_mpm/cli_module/commands.py +79 -70
  65. claude_mpm/cli_module/migration_example.py +38 -60
  66. claude_mpm/config/__init__.py +32 -25
  67. claude_mpm/config/agent_config.py +151 -119
  68. claude_mpm/config/experimental_features.py +217 -0
  69. claude_mpm/config/paths.py +94 -208
  70. claude_mpm/config/socketio_config.py +84 -73
  71. claude_mpm/constants.py +36 -18
  72. claude_mpm/core/__init__.py +9 -6
  73. claude_mpm/core/agent_name_normalizer.py +68 -71
  74. claude_mpm/core/agent_registry.py +372 -521
  75. claude_mpm/core/agent_session_manager.py +74 -63
  76. claude_mpm/core/base_service.py +116 -87
  77. claude_mpm/core/cache.py +119 -153
  78. claude_mpm/core/claude_runner.py +425 -1120
  79. claude_mpm/core/config.py +263 -168
  80. claude_mpm/core/config_aliases.py +69 -61
  81. claude_mpm/core/config_constants.py +292 -0
  82. claude_mpm/core/constants.py +57 -99
  83. claude_mpm/core/container.py +211 -178
  84. claude_mpm/core/exceptions.py +233 -89
  85. claude_mpm/core/factories.py +92 -54
  86. claude_mpm/core/framework_loader.py +378 -220
  87. claude_mpm/core/hook_manager.py +198 -83
  88. claude_mpm/core/hook_performance_config.py +136 -0
  89. claude_mpm/core/injectable_service.py +61 -55
  90. claude_mpm/core/interactive_session.py +165 -155
  91. claude_mpm/core/interfaces.py +221 -195
  92. claude_mpm/core/lazy.py +96 -96
  93. claude_mpm/core/logger.py +133 -107
  94. claude_mpm/core/logging_config.py +185 -157
  95. claude_mpm/core/minimal_framework_loader.py +20 -15
  96. claude_mpm/core/mixins.py +30 -29
  97. claude_mpm/core/oneshot_session.py +215 -181
  98. claude_mpm/core/optimized_agent_loader.py +134 -138
  99. claude_mpm/core/optimized_startup.py +159 -157
  100. claude_mpm/core/pm_hook_interceptor.py +85 -72
  101. claude_mpm/core/service_registry.py +103 -101
  102. claude_mpm/core/session_manager.py +97 -87
  103. claude_mpm/core/socketio_pool.py +212 -158
  104. claude_mpm/core/tool_access_control.py +58 -51
  105. claude_mpm/core/types.py +46 -24
  106. claude_mpm/core/typing_utils.py +166 -82
  107. claude_mpm/core/unified_agent_registry.py +721 -0
  108. claude_mpm/core/unified_config.py +550 -0
  109. claude_mpm/core/unified_paths.py +549 -0
  110. claude_mpm/dashboard/index.html +1 -1
  111. claude_mpm/dashboard/open_dashboard.py +51 -17
  112. claude_mpm/dashboard/static/css/dashboard.css +27 -8
  113. claude_mpm/dashboard/static/dist/components/agent-inference.js +2 -0
  114. claude_mpm/dashboard/static/dist/components/event-processor.js +2 -0
  115. claude_mpm/dashboard/static/dist/components/event-viewer.js +2 -0
  116. claude_mpm/dashboard/static/dist/components/export-manager.js +2 -0
  117. claude_mpm/dashboard/static/dist/components/file-tool-tracker.js +2 -0
  118. claude_mpm/dashboard/static/dist/components/hud-library-loader.js +2 -0
  119. claude_mpm/dashboard/static/dist/components/hud-manager.js +2 -0
  120. claude_mpm/dashboard/static/dist/components/hud-visualizer.js +2 -0
  121. claude_mpm/dashboard/static/dist/components/module-viewer.js +2 -0
  122. claude_mpm/dashboard/static/dist/components/session-manager.js +2 -0
  123. claude_mpm/dashboard/static/dist/components/socket-manager.js +2 -0
  124. claude_mpm/dashboard/static/dist/components/ui-state-manager.js +2 -0
  125. claude_mpm/dashboard/static/dist/components/working-directory.js +2 -0
  126. claude_mpm/dashboard/static/dist/dashboard.js +2 -0
  127. claude_mpm/dashboard/static/dist/socket-client.js +2 -0
  128. claude_mpm/dashboard/static/js/components/agent-inference.js +80 -76
  129. claude_mpm/dashboard/static/js/components/event-processor.js +71 -67
  130. claude_mpm/dashboard/static/js/components/event-viewer.js +74 -70
  131. claude_mpm/dashboard/static/js/components/export-manager.js +31 -28
  132. claude_mpm/dashboard/static/js/components/file-tool-tracker.js +106 -92
  133. claude_mpm/dashboard/static/js/components/hud-library-loader.js +11 -11
  134. claude_mpm/dashboard/static/js/components/hud-manager.js +73 -73
  135. claude_mpm/dashboard/static/js/components/hud-visualizer.js +163 -163
  136. claude_mpm/dashboard/static/js/components/module-viewer.js +305 -233
  137. claude_mpm/dashboard/static/js/components/session-manager.js +32 -29
  138. claude_mpm/dashboard/static/js/components/socket-manager.js +27 -20
  139. claude_mpm/dashboard/static/js/components/ui-state-manager.js +21 -18
  140. claude_mpm/dashboard/static/js/components/working-directory.js +74 -71
  141. claude_mpm/dashboard/static/js/dashboard.js +178 -453
  142. claude_mpm/dashboard/static/js/extension-error-handler.js +164 -0
  143. claude_mpm/dashboard/static/js/socket-client.js +120 -54
  144. claude_mpm/dashboard/templates/index.html +40 -50
  145. claude_mpm/experimental/cli_enhancements.py +60 -58
  146. claude_mpm/generators/__init__.py +1 -1
  147. claude_mpm/generators/agent_profile_generator.py +75 -65
  148. claude_mpm/hooks/__init__.py +1 -1
  149. claude_mpm/hooks/base_hook.py +33 -28
  150. claude_mpm/hooks/claude_hooks/__init__.py +1 -1
  151. claude_mpm/hooks/claude_hooks/connection_pool.py +120 -0
  152. claude_mpm/hooks/claude_hooks/event_handlers.py +743 -0
  153. claude_mpm/hooks/claude_hooks/hook_handler.py +415 -1331
  154. claude_mpm/hooks/claude_hooks/hook_wrapper.sh +4 -4
  155. claude_mpm/hooks/claude_hooks/memory_integration.py +221 -0
  156. claude_mpm/hooks/claude_hooks/response_tracking.py +348 -0
  157. claude_mpm/hooks/claude_hooks/tool_analysis.py +230 -0
  158. claude_mpm/hooks/memory_integration_hook.py +140 -100
  159. claude_mpm/hooks/tool_call_interceptor.py +89 -76
  160. claude_mpm/hooks/validation_hooks.py +57 -49
  161. claude_mpm/init.py +145 -121
  162. claude_mpm/models/__init__.py +9 -9
  163. claude_mpm/models/agent_definition.py +33 -23
  164. claude_mpm/models/agent_session.py +228 -200
  165. claude_mpm/scripts/__init__.py +1 -1
  166. claude_mpm/scripts/socketio_daemon.py +192 -75
  167. claude_mpm/scripts/socketio_server_manager.py +328 -0
  168. claude_mpm/scripts/start_activity_logging.py +25 -22
  169. claude_mpm/services/__init__.py +68 -43
  170. claude_mpm/services/agent_capabilities_service.py +271 -0
  171. claude_mpm/services/agents/__init__.py +23 -32
  172. claude_mpm/services/agents/deployment/__init__.py +3 -3
  173. claude_mpm/services/agents/deployment/agent_config_provider.py +310 -0
  174. claude_mpm/services/agents/deployment/agent_configuration_manager.py +359 -0
  175. claude_mpm/services/agents/deployment/agent_definition_factory.py +84 -0
  176. claude_mpm/services/agents/deployment/agent_deployment.py +415 -2113
  177. claude_mpm/services/agents/deployment/agent_discovery_service.py +387 -0
  178. claude_mpm/services/agents/deployment/agent_environment_manager.py +293 -0
  179. claude_mpm/services/agents/deployment/agent_filesystem_manager.py +387 -0
  180. claude_mpm/services/agents/deployment/agent_format_converter.py +453 -0
  181. claude_mpm/services/agents/deployment/agent_frontmatter_validator.py +161 -0
  182. claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +345 -495
  183. claude_mpm/services/agents/deployment/agent_metrics_collector.py +279 -0
  184. claude_mpm/services/agents/deployment/agent_restore_handler.py +88 -0
  185. claude_mpm/services/agents/deployment/agent_template_builder.py +406 -0
  186. claude_mpm/services/agents/deployment/agent_validator.py +352 -0
  187. claude_mpm/services/agents/deployment/agent_version_manager.py +313 -0
  188. claude_mpm/services/agents/deployment/agent_versioning.py +6 -9
  189. claude_mpm/services/agents/deployment/agents_directory_resolver.py +79 -0
  190. claude_mpm/services/agents/deployment/async_agent_deployment.py +298 -234
  191. claude_mpm/services/agents/deployment/config/__init__.py +13 -0
  192. claude_mpm/services/agents/deployment/config/deployment_config.py +182 -0
  193. claude_mpm/services/agents/deployment/config/deployment_config_manager.py +200 -0
  194. claude_mpm/services/agents/deployment/deployment_config_loader.py +54 -0
  195. claude_mpm/services/agents/deployment/deployment_type_detector.py +124 -0
  196. claude_mpm/services/agents/deployment/facade/__init__.py +18 -0
  197. claude_mpm/services/agents/deployment/facade/async_deployment_executor.py +159 -0
  198. claude_mpm/services/agents/deployment/facade/deployment_executor.py +73 -0
  199. claude_mpm/services/agents/deployment/facade/deployment_facade.py +270 -0
  200. claude_mpm/services/agents/deployment/facade/sync_deployment_executor.py +178 -0
  201. claude_mpm/services/agents/deployment/interface_adapter.py +227 -0
  202. claude_mpm/services/agents/deployment/lifecycle_health_checker.py +85 -0
  203. claude_mpm/services/agents/deployment/lifecycle_performance_tracker.py +100 -0
  204. claude_mpm/services/agents/deployment/pipeline/__init__.py +32 -0
  205. claude_mpm/services/agents/deployment/pipeline/pipeline_builder.py +158 -0
  206. claude_mpm/services/agents/deployment/pipeline/pipeline_context.py +159 -0
  207. claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +169 -0
  208. claude_mpm/services/agents/deployment/pipeline/steps/__init__.py +19 -0
  209. claude_mpm/services/agents/deployment/pipeline/steps/agent_processing_step.py +195 -0
  210. claude_mpm/services/agents/deployment/pipeline/steps/base_step.py +119 -0
  211. claude_mpm/services/agents/deployment/pipeline/steps/configuration_step.py +79 -0
  212. claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +90 -0
  213. claude_mpm/services/agents/deployment/pipeline/steps/validation_step.py +100 -0
  214. claude_mpm/services/agents/deployment/processors/__init__.py +15 -0
  215. claude_mpm/services/agents/deployment/processors/agent_deployment_context.py +98 -0
  216. claude_mpm/services/agents/deployment/processors/agent_deployment_result.py +235 -0
  217. claude_mpm/services/agents/deployment/processors/agent_processor.py +258 -0
  218. claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +318 -0
  219. claude_mpm/services/agents/deployment/results/__init__.py +13 -0
  220. claude_mpm/services/agents/deployment/results/deployment_metrics.py +200 -0
  221. claude_mpm/services/agents/deployment/results/deployment_result_builder.py +249 -0
  222. claude_mpm/services/agents/deployment/strategies/__init__.py +25 -0
  223. claude_mpm/services/agents/deployment/strategies/base_strategy.py +119 -0
  224. claude_mpm/services/agents/deployment/strategies/project_strategy.py +150 -0
  225. claude_mpm/services/agents/deployment/strategies/strategy_selector.py +117 -0
  226. claude_mpm/services/agents/deployment/strategies/system_strategy.py +116 -0
  227. claude_mpm/services/agents/deployment/strategies/user_strategy.py +137 -0
  228. claude_mpm/services/agents/deployment/system_instructions_deployer.py +108 -0
  229. claude_mpm/services/agents/deployment/validation/__init__.py +19 -0
  230. claude_mpm/services/agents/deployment/validation/agent_validator.py +323 -0
  231. claude_mpm/services/agents/deployment/validation/deployment_validator.py +238 -0
  232. claude_mpm/services/agents/deployment/validation/template_validator.py +299 -0
  233. claude_mpm/services/agents/deployment/validation/validation_result.py +226 -0
  234. claude_mpm/services/agents/loading/__init__.py +2 -2
  235. claude_mpm/services/agents/loading/agent_profile_loader.py +259 -229
  236. claude_mpm/services/agents/loading/base_agent_manager.py +90 -81
  237. claude_mpm/services/agents/loading/framework_agent_loader.py +154 -129
  238. claude_mpm/services/agents/management/__init__.py +2 -2
  239. claude_mpm/services/agents/management/agent_capabilities_generator.py +72 -58
  240. claude_mpm/services/agents/management/agent_management_service.py +209 -156
  241. claude_mpm/services/agents/memory/__init__.py +9 -6
  242. claude_mpm/services/agents/memory/agent_memory_manager.py +218 -1152
  243. claude_mpm/services/agents/memory/agent_persistence_service.py +20 -16
  244. claude_mpm/services/agents/memory/analyzer.py +430 -0
  245. claude_mpm/services/agents/memory/content_manager.py +376 -0
  246. claude_mpm/services/agents/memory/template_generator.py +468 -0
  247. claude_mpm/services/agents/registry/__init__.py +7 -10
  248. claude_mpm/services/agents/registry/deployed_agent_discovery.py +122 -97
  249. claude_mpm/services/agents/registry/modification_tracker.py +351 -285
  250. claude_mpm/services/async_session_logger.py +187 -153
  251. claude_mpm/services/claude_session_logger.py +87 -72
  252. claude_mpm/services/command_handler_service.py +217 -0
  253. claude_mpm/services/communication/__init__.py +3 -2
  254. claude_mpm/services/core/__init__.py +50 -97
  255. claude_mpm/services/core/base.py +60 -53
  256. claude_mpm/services/core/interfaces/__init__.py +188 -0
  257. claude_mpm/services/core/interfaces/agent.py +351 -0
  258. claude_mpm/services/core/interfaces/communication.py +343 -0
  259. claude_mpm/services/core/interfaces/infrastructure.py +413 -0
  260. claude_mpm/services/core/interfaces/service.py +434 -0
  261. claude_mpm/services/core/interfaces.py +19 -944
  262. claude_mpm/services/event_aggregator.py +208 -170
  263. claude_mpm/services/exceptions.py +387 -308
  264. claude_mpm/services/framework_claude_md_generator/__init__.py +75 -79
  265. claude_mpm/services/framework_claude_md_generator/content_assembler.py +69 -60
  266. claude_mpm/services/framework_claude_md_generator/content_validator.py +65 -61
  267. claude_mpm/services/framework_claude_md_generator/deployment_manager.py +68 -49
  268. claude_mpm/services/framework_claude_md_generator/section_generators/__init__.py +34 -34
  269. claude_mpm/services/framework_claude_md_generator/section_generators/agents.py +25 -22
  270. claude_mpm/services/framework_claude_md_generator/section_generators/claude_pm_init.py +10 -10
  271. claude_mpm/services/framework_claude_md_generator/section_generators/core_responsibilities.py +4 -3
  272. claude_mpm/services/framework_claude_md_generator/section_generators/delegation_constraints.py +4 -3
  273. claude_mpm/services/framework_claude_md_generator/section_generators/environment_config.py +4 -3
  274. claude_mpm/services/framework_claude_md_generator/section_generators/footer.py +6 -5
  275. claude_mpm/services/framework_claude_md_generator/section_generators/header.py +8 -7
  276. claude_mpm/services/framework_claude_md_generator/section_generators/orchestration_principles.py +4 -3
  277. claude_mpm/services/framework_claude_md_generator/section_generators/role_designation.py +6 -5
  278. claude_mpm/services/framework_claude_md_generator/section_generators/subprocess_validation.py +9 -8
  279. claude_mpm/services/framework_claude_md_generator/section_generators/todo_task_tools.py +4 -3
  280. claude_mpm/services/framework_claude_md_generator/section_generators/troubleshooting.py +5 -4
  281. claude_mpm/services/framework_claude_md_generator/section_manager.py +28 -27
  282. claude_mpm/services/framework_claude_md_generator/version_manager.py +30 -28
  283. claude_mpm/services/hook_service.py +106 -114
  284. claude_mpm/services/infrastructure/__init__.py +7 -5
  285. claude_mpm/services/infrastructure/context_preservation.py +571 -0
  286. claude_mpm/services/infrastructure/daemon_manager.py +279 -0
  287. claude_mpm/services/infrastructure/logging.py +83 -76
  288. claude_mpm/services/infrastructure/monitoring.py +547 -404
  289. claude_mpm/services/mcp_gateway/__init__.py +40 -23
  290. claude_mpm/services/mcp_gateway/config/__init__.py +2 -2
  291. claude_mpm/services/mcp_gateway/config/config_loader.py +61 -56
  292. claude_mpm/services/mcp_gateway/config/config_schema.py +50 -41
  293. claude_mpm/services/mcp_gateway/config/configuration.py +82 -75
  294. claude_mpm/services/mcp_gateway/core/__init__.py +14 -21
  295. claude_mpm/services/mcp_gateway/core/base.py +80 -67
  296. claude_mpm/services/mcp_gateway/core/exceptions.py +60 -46
  297. claude_mpm/services/mcp_gateway/core/interfaces.py +97 -93
  298. claude_mpm/services/mcp_gateway/main.py +307 -127
  299. claude_mpm/services/mcp_gateway/registry/__init__.py +1 -1
  300. claude_mpm/services/mcp_gateway/registry/service_registry.py +100 -101
  301. claude_mpm/services/mcp_gateway/registry/tool_registry.py +135 -126
  302. claude_mpm/services/mcp_gateway/server/__init__.py +4 -4
  303. claude_mpm/services/mcp_gateway/server/{mcp_server.py → mcp_gateway.py} +149 -153
  304. claude_mpm/services/mcp_gateway/server/stdio_handler.py +105 -107
  305. claude_mpm/services/mcp_gateway/server/stdio_server.py +691 -0
  306. claude_mpm/services/mcp_gateway/tools/__init__.py +4 -2
  307. claude_mpm/services/mcp_gateway/tools/base_adapter.py +110 -121
  308. claude_mpm/services/mcp_gateway/tools/document_summarizer.py +283 -215
  309. claude_mpm/services/mcp_gateway/tools/hello_world.py +122 -120
  310. claude_mpm/services/mcp_gateway/tools/ticket_tools.py +652 -0
  311. claude_mpm/services/mcp_gateway/tools/unified_ticket_tool.py +606 -0
  312. claude_mpm/services/memory/__init__.py +2 -2
  313. claude_mpm/services/memory/builder.py +451 -362
  314. claude_mpm/services/memory/cache/__init__.py +2 -2
  315. claude_mpm/services/memory/cache/shared_prompt_cache.py +232 -194
  316. claude_mpm/services/memory/cache/simple_cache.py +107 -93
  317. claude_mpm/services/memory/indexed_memory.py +195 -193
  318. claude_mpm/services/memory/optimizer.py +267 -234
  319. claude_mpm/services/memory/router.py +571 -263
  320. claude_mpm/services/memory_hook_service.py +237 -0
  321. claude_mpm/services/port_manager.py +223 -0
  322. claude_mpm/services/project/__init__.py +3 -3
  323. claude_mpm/services/project/analyzer.py +451 -305
  324. claude_mpm/services/project/registry.py +262 -240
  325. claude_mpm/services/recovery_manager.py +287 -231
  326. claude_mpm/services/response_tracker.py +87 -67
  327. claude_mpm/services/runner_configuration_service.py +587 -0
  328. claude_mpm/services/session_management_service.py +304 -0
  329. claude_mpm/services/socketio/__init__.py +4 -4
  330. claude_mpm/services/socketio/client_proxy.py +174 -0
  331. claude_mpm/services/socketio/handlers/__init__.py +3 -3
  332. claude_mpm/services/socketio/handlers/base.py +44 -30
  333. claude_mpm/services/socketio/handlers/connection.py +145 -65
  334. claude_mpm/services/socketio/handlers/file.py +123 -108
  335. claude_mpm/services/socketio/handlers/git.py +607 -373
  336. claude_mpm/services/socketio/handlers/hook.py +170 -0
  337. claude_mpm/services/socketio/handlers/memory.py +4 -4
  338. claude_mpm/services/socketio/handlers/project.py +4 -4
  339. claude_mpm/services/socketio/handlers/registry.py +53 -38
  340. claude_mpm/services/socketio/server/__init__.py +18 -0
  341. claude_mpm/services/socketio/server/broadcaster.py +252 -0
  342. claude_mpm/services/socketio/server/core.py +399 -0
  343. claude_mpm/services/socketio/server/main.py +323 -0
  344. claude_mpm/services/socketio_client_manager.py +160 -133
  345. claude_mpm/services/socketio_server.py +36 -1885
  346. claude_mpm/services/subprocess_launcher_service.py +316 -0
  347. claude_mpm/services/system_instructions_service.py +258 -0
  348. claude_mpm/services/ticket_manager.py +20 -534
  349. claude_mpm/services/utility_service.py +285 -0
  350. claude_mpm/services/version_control/__init__.py +18 -21
  351. claude_mpm/services/version_control/branch_strategy.py +20 -10
  352. claude_mpm/services/version_control/conflict_resolution.py +37 -13
  353. claude_mpm/services/version_control/git_operations.py +52 -21
  354. claude_mpm/services/version_control/semantic_versioning.py +92 -53
  355. claude_mpm/services/version_control/version_parser.py +145 -125
  356. claude_mpm/services/version_service.py +270 -0
  357. claude_mpm/storage/__init__.py +9 -0
  358. claude_mpm/storage/state_storage.py +552 -0
  359. claude_mpm/ticket_wrapper.py +2 -2
  360. claude_mpm/utils/__init__.py +2 -2
  361. claude_mpm/utils/agent_dependency_loader.py +453 -243
  362. claude_mpm/utils/config_manager.py +157 -118
  363. claude_mpm/utils/console.py +1 -1
  364. claude_mpm/utils/dependency_cache.py +102 -107
  365. claude_mpm/utils/dependency_manager.py +52 -47
  366. claude_mpm/utils/dependency_strategies.py +131 -96
  367. claude_mpm/utils/environment_context.py +110 -102
  368. claude_mpm/utils/error_handler.py +75 -55
  369. claude_mpm/utils/file_utils.py +80 -67
  370. claude_mpm/utils/framework_detection.py +12 -11
  371. claude_mpm/utils/import_migration_example.py +12 -60
  372. claude_mpm/utils/imports.py +48 -45
  373. claude_mpm/utils/path_operations.py +100 -93
  374. claude_mpm/utils/robust_installer.py +172 -164
  375. claude_mpm/utils/session_logging.py +30 -23
  376. claude_mpm/utils/subprocess_utils.py +99 -61
  377. claude_mpm/validation/__init__.py +1 -1
  378. claude_mpm/validation/agent_validator.py +151 -111
  379. claude_mpm/validation/frontmatter_validator.py +92 -71
  380. {claude_mpm-3.9.9.dist-info → claude_mpm-4.0.3.dist-info}/METADATA +51 -2
  381. claude_mpm-4.0.3.dist-info/RECORD +402 -0
  382. {claude_mpm-3.9.9.dist-info → claude_mpm-4.0.3.dist-info}/entry_points.txt +1 -0
  383. {claude_mpm-3.9.9.dist-info → claude_mpm-4.0.3.dist-info}/licenses/LICENSE +1 -1
  384. claude_mpm/config/memory_guardian_config.py +0 -325
  385. claude_mpm/core/config_paths.py +0 -150
  386. claude_mpm/dashboard/static/js/dashboard-original.js +0 -4134
  387. claude_mpm/deployment_paths.py +0 -261
  388. claude_mpm/hooks/claude_hooks/hook_handler_fixed.py +0 -454
  389. claude_mpm/models/state_models.py +0 -433
  390. claude_mpm/services/agent/__init__.py +0 -24
  391. claude_mpm/services/agent/deployment.py +0 -2548
  392. claude_mpm/services/agent/management.py +0 -598
  393. claude_mpm/services/agent/registry.py +0 -813
  394. claude_mpm/services/agents/registry/agent_registry.py +0 -813
  395. claude_mpm/services/communication/socketio.py +0 -1935
  396. claude_mpm/services/communication/websocket.py +0 -479
  397. claude_mpm/services/framework_claude_md_generator.py +0 -624
  398. claude_mpm/services/health_monitor.py +0 -893
  399. claude_mpm/services/infrastructure/memory_guardian.py +0 -770
  400. claude_mpm/services/mcp_gateway/server/mcp_server_simple.py +0 -444
  401. claude_mpm/services/optimized_hook_service.py +0 -542
  402. claude_mpm/services/project_analyzer.py +0 -864
  403. claude_mpm/services/project_registry.py +0 -608
  404. claude_mpm/services/standalone_socketio_server.py +0 -1300
  405. claude_mpm/services/ticket_manager_di.py +0 -318
  406. claude_mpm/services/ticketing_service_original.py +0 -510
  407. claude_mpm/utils/paths.py +0 -395
  408. claude_mpm/utils/platform_memory.py +0 -524
  409. claude_mpm-3.9.9.dist-info/RECORD +0 -293
  410. {claude_mpm-3.9.9.dist-info → claude_mpm-4.0.3.dist-info}/WHEEL +0 -0
  411. {claude_mpm-3.9.9.dist-info → claude_mpm-4.0.3.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,387 @@
1
+ """Agent Discovery Service
2
+
3
+ This service handles the discovery, filtering, and metadata extraction of agent templates.
4
+ Provides centralized logic for finding available agents and determining which should be deployed.
5
+
6
+ Extracted from AgentDeploymentService as part of the refactoring to improve
7
+ maintainability and testability.
8
+ """
9
+
10
+ import json
11
+ import logging
12
+ from pathlib import Path
13
+ from typing import Any, Dict, List, Optional
14
+
15
+ from claude_mpm.core.config import Config
16
+ from claude_mpm.core.logging_config import get_logger
17
+
18
+
19
+ class AgentDiscoveryService:
20
+ """Service for discovering and filtering agent templates.
21
+
22
+ This service handles:
23
+ - Agent template discovery across multiple directories
24
+ - Template filtering based on configuration
25
+ - Agent metadata extraction and validation
26
+ - Available agent listing and categorization
27
+ """
28
+
29
+ def __init__(self, templates_dir: Path):
30
+ """Initialize the agent discovery service.
31
+
32
+ Args:
33
+ templates_dir: Directory containing agent templates
34
+ """
35
+ self.logger = get_logger(__name__)
36
+ self.templates_dir = templates_dir
37
+
38
+ def list_available_agents(self) -> List[Dict[str, Any]]:
39
+ """
40
+ List all available agent templates with their metadata.
41
+
42
+ Returns:
43
+ List of agent information dictionaries containing:
44
+ - name: Agent name
45
+ - description: Agent description
46
+ - version: Agent version
47
+ - tools: List of tools the agent uses
48
+ - specializations: Agent specializations
49
+ - file_path: Path to template file
50
+ """
51
+ agents = []
52
+
53
+ if not self.templates_dir.exists():
54
+ self.logger.warning(
55
+ f"Templates directory does not exist: {self.templates_dir}"
56
+ )
57
+ return agents
58
+
59
+ # Find all JSON template files
60
+ template_files = list(self.templates_dir.glob("*.json"))
61
+
62
+ for template_file in template_files:
63
+ try:
64
+ agent_info = self._extract_agent_metadata(template_file)
65
+ if agent_info:
66
+ agents.append(agent_info)
67
+
68
+ except Exception as e:
69
+ self.logger.error(
70
+ f"Failed to process template {template_file.name}: {e}"
71
+ )
72
+ continue
73
+
74
+ # Sort by agent name for consistent ordering
75
+ agents.sort(key=lambda x: x.get("name", ""))
76
+
77
+ self.logger.info(f"Discovered {len(agents)} available agent templates")
78
+ return agents
79
+
80
+ def get_filtered_templates(
81
+ self, excluded_agents: List[str], config: Optional[Config] = None
82
+ ) -> List[Path]:
83
+ """
84
+ Get filtered list of template files based on configuration.
85
+
86
+ Args:
87
+ excluded_agents: List of agent names to exclude
88
+ config: Configuration object for additional filtering
89
+
90
+ Returns:
91
+ List of template file paths to deploy
92
+ """
93
+ if not self.templates_dir.exists():
94
+ self.logger.error(f"Templates directory not found: {self.templates_dir}")
95
+ return []
96
+
97
+ # Get all template files
98
+ template_files = list(self.templates_dir.glob("*.json"))
99
+
100
+ if not template_files:
101
+ self.logger.warning(f"No agent templates found in {self.templates_dir}")
102
+ return []
103
+
104
+ # Apply exclusion filtering
105
+ filtered_files = []
106
+ excluded_count = 0
107
+
108
+ for template_file in template_files:
109
+ agent_name = template_file.stem
110
+
111
+ # Check if agent is excluded
112
+ if self._is_agent_excluded(agent_name, excluded_agents, config):
113
+ excluded_count += 1
114
+ self.logger.debug(f"Excluding agent: {agent_name}")
115
+ continue
116
+
117
+ # Validate template file
118
+ if self._validate_template_file(template_file):
119
+ filtered_files.append(template_file)
120
+ else:
121
+ self.logger.warning(f"Invalid template file: {template_file.name}")
122
+
123
+ self.logger.info(
124
+ f"Found {len(template_files)} templates, excluded {excluded_count}, deploying {len(filtered_files)}"
125
+ )
126
+ return filtered_files
127
+
128
+ def find_agent_template(self, agent_name: str) -> Optional[Path]:
129
+ """
130
+ Find template file for a specific agent.
131
+
132
+ Args:
133
+ agent_name: Name of the agent to find
134
+
135
+ Returns:
136
+ Path to template file if found, None otherwise
137
+ """
138
+ template_file = self.templates_dir / f"{agent_name}.json"
139
+
140
+ if template_file.exists():
141
+ if self._validate_template_file(template_file):
142
+ return template_file
143
+ else:
144
+ self.logger.error(f"Invalid template file: {template_file}")
145
+ return None
146
+
147
+ self.logger.error(f"Template not found for agent: {agent_name}")
148
+ return None
149
+
150
+ def get_agent_categories(self) -> Dict[str, List[str]]:
151
+ """
152
+ Categorize available agents by type/specialization.
153
+
154
+ Returns:
155
+ Dictionary mapping categories to lists of agent names
156
+ """
157
+ categories = {}
158
+ agents = self.list_available_agents()
159
+
160
+ for agent in agents:
161
+ agent_name = agent.get("name", "unknown")
162
+ specializations = agent.get("specializations", [])
163
+
164
+ # Categorize by specializations
165
+ if specializations:
166
+ for spec in specializations:
167
+ if spec not in categories:
168
+ categories[spec] = []
169
+ categories[spec].append(agent_name)
170
+ else:
171
+ # Default category for agents without specializations
172
+ if "general" not in categories:
173
+ categories["general"] = []
174
+ categories["general"].append(agent_name)
175
+
176
+ return categories
177
+
178
+ def _extract_agent_metadata(self, template_file: Path) -> Optional[Dict[str, Any]]:
179
+ """
180
+ Extract metadata from an agent template file.
181
+
182
+ Args:
183
+ template_file: Path to the template file
184
+
185
+ Returns:
186
+ Dictionary with agent metadata or None if extraction fails
187
+ """
188
+ try:
189
+ # Read and parse template file
190
+ template_content = template_file.read_text()
191
+ template_data = json.loads(template_content)
192
+
193
+ # Extract basic metadata from the metadata section (per agent schema)
194
+ metadata = template_data.get("metadata", {})
195
+ capabilities = template_data.get("capabilities", {})
196
+
197
+ agent_info = {
198
+ "name": metadata.get("name", template_file.stem),
199
+ "description": metadata.get("description", "No description available"),
200
+ "version": template_data.get(
201
+ "agent_version", template_data.get("version", "1.0.0")
202
+ ),
203
+ "tools": capabilities.get("tools", []),
204
+ "specializations": metadata.get(
205
+ "tags", []
206
+ ), # Use tags as specializations
207
+ "file": template_file.name,
208
+ "path": str(template_file),
209
+ "file_path": str(template_file), # Keep for backward compatibility
210
+ "size": template_file.stat().st_size,
211
+ "model": capabilities.get("model", "sonnet"),
212
+ "author": metadata.get("author", "unknown"),
213
+ }
214
+
215
+ # Validate required fields
216
+ if not agent_info["name"]:
217
+ self.logger.warning(f"Template missing name: {template_file.name}")
218
+ return None
219
+
220
+ return agent_info
221
+
222
+ except json.JSONDecodeError as e:
223
+ self.logger.error(f"Invalid JSON in template {template_file.name}: {e}")
224
+ return None
225
+ except Exception as e:
226
+ self.logger.error(
227
+ f"Failed to extract metadata from {template_file.name}: {e}"
228
+ )
229
+ return None
230
+
231
+ def _is_agent_excluded(
232
+ self,
233
+ agent_name: str,
234
+ excluded_agents: List[str],
235
+ config: Optional[Config] = None,
236
+ ) -> bool:
237
+ """
238
+ Check if an agent should be excluded from deployment.
239
+
240
+ Args:
241
+ agent_name: Name of the agent to check
242
+ excluded_agents: List of explicitly excluded agents
243
+ config: Configuration object for additional exclusion rules
244
+
245
+ Returns:
246
+ True if agent should be excluded, False otherwise
247
+ """
248
+ # Check explicit exclusion list
249
+ if excluded_agents:
250
+ # Determine case sensitivity from config
251
+ case_sensitive = True
252
+ if config:
253
+ case_sensitive = config.get(
254
+ "agent_deployment.case_sensitive_exclusion", True
255
+ )
256
+
257
+ if case_sensitive:
258
+ if agent_name in excluded_agents:
259
+ return True
260
+ else:
261
+ # Case-insensitive comparison
262
+ agent_name_lower = agent_name.lower()
263
+ excluded_lower = [name.lower() for name in excluded_agents]
264
+ if agent_name_lower in excluded_lower:
265
+ return True
266
+
267
+ # Check for additional exclusion rules from config
268
+ if config:
269
+ # Check pattern-based exclusions
270
+ exclusion_patterns = config.get("agent_deployment.exclusion_patterns", [])
271
+ for pattern in exclusion_patterns:
272
+ if pattern in agent_name:
273
+ return True
274
+
275
+ # Check environment-specific exclusions
276
+ environment = config.get("environment", "development")
277
+ env_exclusions = config.get(
278
+ f"agent_deployment.{environment}_exclusions", []
279
+ )
280
+ if agent_name in env_exclusions:
281
+ return True
282
+
283
+ return False
284
+
285
+ def _validate_template_file(self, template_file: Path) -> bool:
286
+ """
287
+ Validate that a template file is properly formatted.
288
+
289
+ Args:
290
+ template_file: Path to template file to validate
291
+
292
+ Returns:
293
+ True if template is valid, False otherwise
294
+ """
295
+ try:
296
+ # Check file exists and is readable
297
+ if not template_file.exists():
298
+ return False
299
+
300
+ # Parse JSON content
301
+ content = template_file.read_text()
302
+ template_data = json.loads(content)
303
+
304
+ # Check required fields in metadata section (per agent schema)
305
+ metadata = template_data.get("metadata", {})
306
+ required_fields = ["name", "description"]
307
+ for field in required_fields:
308
+ if field not in metadata:
309
+ self.logger.warning(
310
+ f"Template {template_file.name} missing required field in metadata: {field}"
311
+ )
312
+ return False
313
+
314
+ # Validate agent ID format (Claude Code requirements)
315
+ # Use agent_id for validation, not the display name
316
+ agent_id = template_data.get("agent_id", "")
317
+ if not self._is_valid_agent_name(agent_id):
318
+ self.logger.warning(
319
+ f"Invalid agent ID format in {template_file.name}: {agent_id}"
320
+ )
321
+ return False
322
+
323
+ return True
324
+
325
+ except json.JSONDecodeError:
326
+ self.logger.error(f"Invalid JSON in template: {template_file.name}")
327
+ return False
328
+ except Exception as e:
329
+ self.logger.error(
330
+ f"Template validation failed for {template_file.name}: {e}"
331
+ )
332
+ return False
333
+
334
+ def _is_valid_agent_name(self, agent_name: str) -> bool:
335
+ """
336
+ Validate agent name format according to Claude Code requirements.
337
+
338
+ Args:
339
+ agent_name: Agent name to validate
340
+
341
+ Returns:
342
+ True if name is valid, False otherwise
343
+ """
344
+ import re
345
+
346
+ # Claude Code requires lowercase letters, numbers, and hyphens only
347
+ # Must start with letter, no consecutive hyphens, no trailing hyphens
348
+ pattern = r"^[a-z][a-z0-9]*(-[a-z0-9]+)*$"
349
+
350
+ return bool(re.match(pattern, agent_name))
351
+
352
+ def get_discovery_stats(self) -> Dict[str, Any]:
353
+ """
354
+ Get statistics about agent discovery.
355
+
356
+ Returns:
357
+ Dictionary with discovery statistics
358
+ """
359
+ stats = {
360
+ "total_templates": 0,
361
+ "valid_templates": 0,
362
+ "invalid_templates": 0,
363
+ "categories": {},
364
+ "templates_directory": str(self.templates_dir),
365
+ "directory_exists": self.templates_dir.exists(),
366
+ }
367
+
368
+ if not self.templates_dir.exists():
369
+ return stats
370
+
371
+ # Count template files
372
+ template_files = list(self.templates_dir.glob("*.json"))
373
+ stats["total_templates"] = len(template_files)
374
+
375
+ # Validate each template
376
+ valid_count = 0
377
+ for template_file in template_files:
378
+ if self._validate_template_file(template_file):
379
+ valid_count += 1
380
+
381
+ stats["valid_templates"] = valid_count
382
+ stats["invalid_templates"] = stats["total_templates"] - valid_count
383
+
384
+ # Get category distribution
385
+ stats["categories"] = self.get_agent_categories()
386
+
387
+ return stats
@@ -0,0 +1,293 @@
1
+ """Agent Environment Manager Service
2
+
3
+ This service handles environment configuration for Claude agent discovery and execution.
4
+ Manages environment variables, paths, and runtime configuration.
5
+
6
+ Extracted from AgentDeploymentService as part of the refactoring to improve
7
+ maintainability and testability.
8
+ """
9
+
10
+ import logging
11
+ import os
12
+ from pathlib import Path
13
+ from typing import Any, Dict, Optional
14
+
15
+ from claude_mpm.core.logging_config import get_logger
16
+
17
+
18
+ class AgentEnvironmentManager:
19
+ """Service for managing Claude agent environment configuration.
20
+
21
+ This service handles:
22
+ - Setting Claude environment variables
23
+ - Managing agent discovery paths
24
+ - Configuring runtime parameters
25
+ - Environment validation and verification
26
+ """
27
+
28
+ def __init__(self):
29
+ """Initialize the environment manager."""
30
+ self.logger = get_logger(__name__)
31
+
32
+ def set_claude_environment(
33
+ self, config_dir: Optional[Path] = None
34
+ ) -> Dict[str, str]:
35
+ """
36
+ Set Claude environment variables for agent discovery.
37
+
38
+ This configures the environment so Claude can discover and use deployed agents.
39
+ Essential for proper agent functionality in Claude Code.
40
+
41
+ Args:
42
+ config_dir: Claude configuration directory (default: .claude/)
43
+
44
+ Returns:
45
+ Dictionary of environment variables that were set
46
+ """
47
+ if not config_dir:
48
+ config_dir = Path.cwd() / ".claude"
49
+
50
+ # Ensure config directory exists
51
+ config_dir.mkdir(parents=True, exist_ok=True)
52
+
53
+ # Set environment variables for Claude agent discovery
54
+ env_vars = {
55
+ "CLAUDE_CONFIG_DIR": str(config_dir.absolute()),
56
+ "CLAUDE_MAX_PARALLEL_SUBAGENTS": "3", # Reasonable default
57
+ "CLAUDE_TIMEOUT": "300", # 5 minutes default timeout
58
+ }
59
+
60
+ # Apply environment variables
61
+ for key, value in env_vars.items():
62
+ os.environ[key] = value
63
+ self.logger.debug(f"Set environment variable: {key}={value}")
64
+
65
+ self.logger.info(
66
+ f"Claude environment configured for agent discovery in {config_dir}"
67
+ )
68
+ return env_vars
69
+
70
+ def get_current_environment(self) -> Dict[str, str]:
71
+ """
72
+ Get current Claude-related environment variables.
73
+
74
+ Returns:
75
+ Dictionary of current Claude environment variables
76
+ """
77
+ claude_env_vars = {}
78
+
79
+ # Check for Claude-specific environment variables
80
+ claude_prefixes = ["CLAUDE_", "ANTHROPIC_"]
81
+
82
+ for key, value in os.environ.items():
83
+ if any(key.startswith(prefix) for prefix in claude_prefixes):
84
+ claude_env_vars[key] = value
85
+
86
+ return claude_env_vars
87
+
88
+ def validate_environment(self, config_dir: Optional[Path] = None) -> Dict[str, Any]:
89
+ """
90
+ Validate the current Claude environment configuration.
91
+
92
+ Args:
93
+ config_dir: Claude configuration directory to validate
94
+
95
+ Returns:
96
+ Dictionary with validation results
97
+ """
98
+ if not config_dir:
99
+ config_dir = Path.cwd() / ".claude"
100
+
101
+ validation_results = {
102
+ "valid": True,
103
+ "warnings": [],
104
+ "errors": [],
105
+ "config_dir_exists": False,
106
+ "agents_dir_exists": False,
107
+ "environment_variables": {},
108
+ "recommendations": [],
109
+ }
110
+
111
+ # Check if config directory exists
112
+ if config_dir.exists():
113
+ validation_results["config_dir_exists"] = True
114
+ self.logger.debug(f"Config directory exists: {config_dir}")
115
+ else:
116
+ validation_results["valid"] = False
117
+ validation_results["errors"].append(
118
+ f"Config directory does not exist: {config_dir}"
119
+ )
120
+
121
+ # Check if agents directory exists
122
+ agents_dir = config_dir / "agents"
123
+ if agents_dir.exists():
124
+ validation_results["agents_dir_exists"] = True
125
+ self.logger.debug(f"Agents directory exists: {agents_dir}")
126
+ else:
127
+ validation_results["warnings"].append(
128
+ f"Agents directory does not exist: {agents_dir}"
129
+ )
130
+
131
+ # Check environment variables
132
+ current_env = self.get_current_environment()
133
+ validation_results["environment_variables"] = current_env
134
+
135
+ # Validate required environment variables
136
+ required_vars = ["CLAUDE_CONFIG_DIR"]
137
+ for var in required_vars:
138
+ if var not in current_env:
139
+ validation_results["warnings"].append(
140
+ f"Missing environment variable: {var}"
141
+ )
142
+ validation_results["recommendations"].append(
143
+ f"Set {var} to point to your Claude config directory"
144
+ )
145
+
146
+ # Check if CLAUDE_CONFIG_DIR points to the right place
147
+ if "CLAUDE_CONFIG_DIR" in current_env:
148
+ env_config_dir = Path(current_env["CLAUDE_CONFIG_DIR"])
149
+ if env_config_dir != config_dir.absolute():
150
+ validation_results["warnings"].append(
151
+ f"CLAUDE_CONFIG_DIR ({env_config_dir}) doesn't match expected path ({config_dir.absolute()})"
152
+ )
153
+
154
+ # Performance recommendations
155
+ if "CLAUDE_MAX_PARALLEL_SUBAGENTS" not in current_env:
156
+ validation_results["recommendations"].append(
157
+ "Consider setting CLAUDE_MAX_PARALLEL_SUBAGENTS for better performance"
158
+ )
159
+
160
+ if "CLAUDE_TIMEOUT" not in current_env:
161
+ validation_results["recommendations"].append(
162
+ "Consider setting CLAUDE_TIMEOUT to prevent long-running operations"
163
+ )
164
+
165
+ return validation_results
166
+
167
+ def setup_development_environment(
168
+ self, config_dir: Optional[Path] = None
169
+ ) -> Dict[str, Any]:
170
+ """
171
+ Set up a complete development environment for Claude agents.
172
+
173
+ Args:
174
+ config_dir: Claude configuration directory
175
+
176
+ Returns:
177
+ Dictionary with setup results
178
+ """
179
+ if not config_dir:
180
+ config_dir = Path.cwd() / ".claude"
181
+
182
+ setup_results = {
183
+ "success": True,
184
+ "created_directories": [],
185
+ "set_environment_variables": {},
186
+ "errors": [],
187
+ }
188
+
189
+ try:
190
+ # Create necessary directories
191
+ directories_to_create = [
192
+ config_dir,
193
+ config_dir / "agents",
194
+ config_dir / "logs",
195
+ config_dir / "cache",
196
+ ]
197
+
198
+ for directory in directories_to_create:
199
+ if not directory.exists():
200
+ directory.mkdir(parents=True, exist_ok=True)
201
+ setup_results["created_directories"].append(str(directory))
202
+ self.logger.info(f"Created directory: {directory}")
203
+
204
+ # Set up environment variables
205
+ env_vars = self.set_claude_environment(config_dir)
206
+ setup_results["set_environment_variables"] = env_vars
207
+
208
+ # Create a basic .gitignore for the config directory
209
+ gitignore_path = config_dir / ".gitignore"
210
+ if not gitignore_path.exists():
211
+ gitignore_content = """# Claude configuration files
212
+ logs/
213
+ cache/
214
+ *.log
215
+ *.tmp
216
+
217
+ # Keep agents directory but ignore specific files if needed
218
+ # agents/
219
+ """
220
+ gitignore_path.write_text(gitignore_content)
221
+ self.logger.info(f"Created .gitignore: {gitignore_path}")
222
+
223
+ except Exception as e:
224
+ setup_results["success"] = False
225
+ setup_results["errors"].append(str(e))
226
+ self.logger.error(f"Failed to set up development environment: {e}")
227
+
228
+ return setup_results
229
+
230
+ def get_environment_info(self) -> Dict[str, Any]:
231
+ """
232
+ Get comprehensive information about the current environment.
233
+
234
+ Returns:
235
+ Dictionary with environment information
236
+ """
237
+ current_env = self.get_current_environment()
238
+
239
+ info = {
240
+ "claude_environment_variables": current_env,
241
+ "python_path": os.environ.get("PYTHONPATH", "Not set"),
242
+ "current_working_directory": str(Path.cwd()),
243
+ "user_home_directory": str(Path.home()),
244
+ "claude_config_locations": self._find_claude_config_locations(),
245
+ }
246
+
247
+ return info
248
+
249
+ def cleanup_environment(self) -> Dict[str, Any]:
250
+ """
251
+ Clean up Claude environment variables.
252
+
253
+ Returns:
254
+ Dictionary with cleanup results
255
+ """
256
+ cleanup_results = {"removed_variables": [], "errors": []}
257
+
258
+ try:
259
+ # Remove Claude-specific environment variables
260
+ claude_vars = [
261
+ key for key in os.environ.keys() if key.startswith("CLAUDE_")
262
+ ]
263
+
264
+ for var in claude_vars:
265
+ if var in os.environ:
266
+ del os.environ[var]
267
+ cleanup_results["removed_variables"].append(var)
268
+ self.logger.debug(f"Removed environment variable: {var}")
269
+
270
+ self.logger.info(
271
+ f"Cleaned up {len(cleanup_results['removed_variables'])} environment variables"
272
+ )
273
+
274
+ except Exception as e:
275
+ cleanup_results["errors"].append(str(e))
276
+ self.logger.error(f"Error during environment cleanup: {e}")
277
+
278
+ return cleanup_results
279
+
280
+ def _find_claude_config_locations(self) -> list:
281
+ """Find potential Claude configuration directories."""
282
+ potential_locations = [
283
+ Path.cwd() / ".claude",
284
+ Path.home() / ".claude",
285
+ Path.home() / ".config" / "claude",
286
+ ]
287
+
288
+ existing_locations = []
289
+ for location in potential_locations:
290
+ if location.exists():
291
+ existing_locations.append(str(location))
292
+
293
+ return existing_locations