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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (419) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/__init__.py +2 -2
  3. claude_mpm/__main__.py +3 -2
  4. claude_mpm/agents/__init__.py +85 -79
  5. claude_mpm/agents/agent_loader.py +464 -1003
  6. claude_mpm/agents/agent_loader_integration.py +45 -45
  7. claude_mpm/agents/agents_metadata.py +29 -30
  8. claude_mpm/agents/async_agent_loader.py +156 -138
  9. claude_mpm/agents/base_agent.json +1 -1
  10. claude_mpm/agents/base_agent_loader.py +179 -151
  11. claude_mpm/agents/frontmatter_validator.py +229 -130
  12. claude_mpm/agents/schema/agent_schema.json +1 -1
  13. claude_mpm/agents/system_agent_config.py +213 -147
  14. claude_mpm/agents/templates/__init__.py +13 -13
  15. claude_mpm/agents/templates/code_analyzer.json +2 -2
  16. claude_mpm/agents/templates/data_engineer.json +1 -1
  17. claude_mpm/agents/templates/documentation.json +23 -11
  18. claude_mpm/agents/templates/engineer.json +22 -6
  19. claude_mpm/agents/templates/memory_manager.json +1 -1
  20. claude_mpm/agents/templates/ops.json +2 -2
  21. claude_mpm/agents/templates/project_organizer.json +1 -1
  22. claude_mpm/agents/templates/qa.json +1 -1
  23. claude_mpm/agents/templates/refactoring_engineer.json +222 -0
  24. claude_mpm/agents/templates/research.json +20 -14
  25. claude_mpm/agents/templates/security.json +1 -1
  26. claude_mpm/agents/templates/ticketing.json +1 -1
  27. claude_mpm/agents/templates/version_control.json +1 -1
  28. claude_mpm/agents/templates/web_qa.json +3 -1
  29. claude_mpm/agents/templates/web_ui.json +2 -2
  30. claude_mpm/cli/__init__.py +79 -51
  31. claude_mpm/cli/__main__.py +3 -2
  32. claude_mpm/cli/commands/__init__.py +20 -20
  33. claude_mpm/cli/commands/agents.py +279 -247
  34. claude_mpm/cli/commands/aggregate.py +138 -157
  35. claude_mpm/cli/commands/cleanup.py +147 -147
  36. claude_mpm/cli/commands/config.py +93 -76
  37. claude_mpm/cli/commands/info.py +17 -16
  38. claude_mpm/cli/commands/mcp.py +140 -905
  39. claude_mpm/cli/commands/mcp_command_router.py +139 -0
  40. claude_mpm/cli/commands/mcp_config_commands.py +20 -0
  41. claude_mpm/cli/commands/mcp_install_commands.py +20 -0
  42. claude_mpm/cli/commands/mcp_server_commands.py +175 -0
  43. claude_mpm/cli/commands/mcp_tool_commands.py +34 -0
  44. claude_mpm/cli/commands/memory.py +239 -203
  45. claude_mpm/cli/commands/monitor.py +203 -81
  46. claude_mpm/cli/commands/run.py +380 -429
  47. claude_mpm/cli/commands/run_config_checker.py +160 -0
  48. claude_mpm/cli/commands/socketio_monitor.py +235 -0
  49. claude_mpm/cli/commands/tickets.py +305 -197
  50. claude_mpm/cli/parser.py +24 -1156
  51. claude_mpm/cli/parsers/__init__.py +29 -0
  52. claude_mpm/cli/parsers/agents_parser.py +136 -0
  53. claude_mpm/cli/parsers/base_parser.py +331 -0
  54. claude_mpm/cli/parsers/config_parser.py +85 -0
  55. claude_mpm/cli/parsers/mcp_parser.py +152 -0
  56. claude_mpm/cli/parsers/memory_parser.py +138 -0
  57. claude_mpm/cli/parsers/monitor_parser.py +104 -0
  58. claude_mpm/cli/parsers/run_parser.py +147 -0
  59. claude_mpm/cli/parsers/tickets_parser.py +203 -0
  60. claude_mpm/cli/ticket_cli.py +7 -3
  61. claude_mpm/cli/utils.py +55 -37
  62. claude_mpm/cli_module/__init__.py +6 -6
  63. claude_mpm/cli_module/args.py +188 -140
  64. claude_mpm/cli_module/commands.py +79 -70
  65. claude_mpm/cli_module/migration_example.py +38 -60
  66. claude_mpm/config/__init__.py +32 -25
  67. claude_mpm/config/agent_config.py +151 -119
  68. claude_mpm/config/experimental_features.py +71 -73
  69. claude_mpm/config/paths.py +94 -208
  70. claude_mpm/config/socketio_config.py +84 -73
  71. claude_mpm/constants.py +35 -18
  72. claude_mpm/core/__init__.py +9 -6
  73. claude_mpm/core/agent_name_normalizer.py +68 -71
  74. claude_mpm/core/agent_registry.py +372 -521
  75. claude_mpm/core/agent_session_manager.py +74 -63
  76. claude_mpm/core/base_service.py +116 -87
  77. claude_mpm/core/cache.py +119 -153
  78. claude_mpm/core/claude_runner.py +425 -1120
  79. claude_mpm/core/config.py +263 -168
  80. claude_mpm/core/config_aliases.py +69 -61
  81. claude_mpm/core/config_constants.py +292 -0
  82. claude_mpm/core/constants.py +57 -99
  83. claude_mpm/core/container.py +211 -178
  84. claude_mpm/core/exceptions.py +233 -89
  85. claude_mpm/core/factories.py +92 -54
  86. claude_mpm/core/framework_loader.py +378 -220
  87. claude_mpm/core/hook_manager.py +198 -83
  88. claude_mpm/core/hook_performance_config.py +136 -0
  89. claude_mpm/core/injectable_service.py +61 -55
  90. claude_mpm/core/interactive_session.py +165 -155
  91. claude_mpm/core/interfaces.py +221 -195
  92. claude_mpm/core/lazy.py +96 -96
  93. claude_mpm/core/logger.py +133 -107
  94. claude_mpm/core/logging_config.py +185 -157
  95. claude_mpm/core/minimal_framework_loader.py +20 -15
  96. claude_mpm/core/mixins.py +30 -29
  97. claude_mpm/core/oneshot_session.py +215 -181
  98. claude_mpm/core/optimized_agent_loader.py +134 -138
  99. claude_mpm/core/optimized_startup.py +159 -157
  100. claude_mpm/core/pm_hook_interceptor.py +85 -72
  101. claude_mpm/core/service_registry.py +103 -101
  102. claude_mpm/core/session_manager.py +97 -87
  103. claude_mpm/core/socketio_pool.py +212 -158
  104. claude_mpm/core/tool_access_control.py +58 -51
  105. claude_mpm/core/types.py +46 -24
  106. claude_mpm/core/typing_utils.py +166 -82
  107. claude_mpm/core/unified_agent_registry.py +721 -0
  108. claude_mpm/core/unified_config.py +550 -0
  109. claude_mpm/core/unified_paths.py +549 -0
  110. claude_mpm/dashboard/index.html +1 -1
  111. claude_mpm/dashboard/open_dashboard.py +51 -17
  112. claude_mpm/dashboard/static/css/dashboard.css +27 -8
  113. claude_mpm/dashboard/static/dist/components/agent-inference.js +2 -0
  114. claude_mpm/dashboard/static/dist/components/event-processor.js +2 -0
  115. claude_mpm/dashboard/static/dist/components/event-viewer.js +2 -0
  116. claude_mpm/dashboard/static/dist/components/export-manager.js +2 -0
  117. claude_mpm/dashboard/static/dist/components/file-tool-tracker.js +2 -0
  118. claude_mpm/dashboard/static/dist/components/hud-library-loader.js +2 -0
  119. claude_mpm/dashboard/static/dist/components/hud-manager.js +2 -0
  120. claude_mpm/dashboard/static/dist/components/hud-visualizer.js +2 -0
  121. claude_mpm/dashboard/static/dist/components/module-viewer.js +2 -0
  122. claude_mpm/dashboard/static/dist/components/session-manager.js +2 -0
  123. claude_mpm/dashboard/static/dist/components/socket-manager.js +2 -0
  124. claude_mpm/dashboard/static/dist/components/ui-state-manager.js +2 -0
  125. claude_mpm/dashboard/static/dist/components/working-directory.js +2 -0
  126. claude_mpm/dashboard/static/dist/dashboard.js +2 -0
  127. claude_mpm/dashboard/static/dist/socket-client.js +2 -0
  128. claude_mpm/dashboard/static/js/components/agent-inference.js +80 -76
  129. claude_mpm/dashboard/static/js/components/event-processor.js +71 -67
  130. claude_mpm/dashboard/static/js/components/event-viewer.js +74 -70
  131. claude_mpm/dashboard/static/js/components/export-manager.js +31 -28
  132. claude_mpm/dashboard/static/js/components/file-tool-tracker.js +106 -92
  133. claude_mpm/dashboard/static/js/components/hud-library-loader.js +11 -11
  134. claude_mpm/dashboard/static/js/components/hud-manager.js +73 -73
  135. claude_mpm/dashboard/static/js/components/hud-visualizer.js +163 -163
  136. claude_mpm/dashboard/static/js/components/module-viewer.js +305 -233
  137. claude_mpm/dashboard/static/js/components/session-manager.js +32 -29
  138. claude_mpm/dashboard/static/js/components/socket-manager.js +27 -20
  139. claude_mpm/dashboard/static/js/components/ui-state-manager.js +21 -18
  140. claude_mpm/dashboard/static/js/components/working-directory.js +74 -71
  141. claude_mpm/dashboard/static/js/dashboard.js +178 -453
  142. claude_mpm/dashboard/static/js/extension-error-handler.js +164 -0
  143. claude_mpm/dashboard/static/js/socket-client.js +120 -54
  144. claude_mpm/dashboard/templates/index.html +40 -50
  145. claude_mpm/experimental/cli_enhancements.py +60 -58
  146. claude_mpm/generators/__init__.py +1 -1
  147. claude_mpm/generators/agent_profile_generator.py +75 -65
  148. claude_mpm/hooks/__init__.py +1 -1
  149. claude_mpm/hooks/base_hook.py +33 -28
  150. claude_mpm/hooks/claude_hooks/__init__.py +1 -1
  151. claude_mpm/hooks/claude_hooks/connection_pool.py +120 -0
  152. claude_mpm/hooks/claude_hooks/event_handlers.py +743 -0
  153. claude_mpm/hooks/claude_hooks/hook_handler.py +415 -1331
  154. claude_mpm/hooks/claude_hooks/hook_wrapper.sh +4 -4
  155. claude_mpm/hooks/claude_hooks/memory_integration.py +221 -0
  156. claude_mpm/hooks/claude_hooks/response_tracking.py +348 -0
  157. claude_mpm/hooks/claude_hooks/tool_analysis.py +230 -0
  158. claude_mpm/hooks/memory_integration_hook.py +140 -100
  159. claude_mpm/hooks/tool_call_interceptor.py +89 -76
  160. claude_mpm/hooks/validation_hooks.py +57 -49
  161. claude_mpm/init.py +145 -121
  162. claude_mpm/models/__init__.py +9 -9
  163. claude_mpm/models/agent_definition.py +33 -23
  164. claude_mpm/models/agent_session.py +228 -200
  165. claude_mpm/scripts/__init__.py +1 -1
  166. claude_mpm/scripts/socketio_daemon.py +192 -75
  167. claude_mpm/scripts/socketio_server_manager.py +328 -0
  168. claude_mpm/scripts/start_activity_logging.py +25 -22
  169. claude_mpm/services/__init__.py +68 -43
  170. claude_mpm/services/agent_capabilities_service.py +271 -0
  171. claude_mpm/services/agents/__init__.py +23 -32
  172. claude_mpm/services/agents/deployment/__init__.py +3 -3
  173. claude_mpm/services/agents/deployment/agent_config_provider.py +310 -0
  174. claude_mpm/services/agents/deployment/agent_configuration_manager.py +359 -0
  175. claude_mpm/services/agents/deployment/agent_definition_factory.py +84 -0
  176. claude_mpm/services/agents/deployment/agent_deployment.py +415 -2113
  177. claude_mpm/services/agents/deployment/agent_discovery_service.py +387 -0
  178. claude_mpm/services/agents/deployment/agent_environment_manager.py +293 -0
  179. claude_mpm/services/agents/deployment/agent_filesystem_manager.py +387 -0
  180. claude_mpm/services/agents/deployment/agent_format_converter.py +453 -0
  181. claude_mpm/services/agents/deployment/agent_frontmatter_validator.py +161 -0
  182. claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +345 -495
  183. claude_mpm/services/agents/deployment/agent_metrics_collector.py +279 -0
  184. claude_mpm/services/agents/deployment/agent_restore_handler.py +88 -0
  185. claude_mpm/services/agents/deployment/agent_template_builder.py +406 -0
  186. claude_mpm/services/agents/deployment/agent_validator.py +352 -0
  187. claude_mpm/services/agents/deployment/agent_version_manager.py +313 -0
  188. claude_mpm/services/agents/deployment/agent_versioning.py +6 -9
  189. claude_mpm/services/agents/deployment/agents_directory_resolver.py +79 -0
  190. claude_mpm/services/agents/deployment/async_agent_deployment.py +298 -234
  191. claude_mpm/services/agents/deployment/config/__init__.py +13 -0
  192. claude_mpm/services/agents/deployment/config/deployment_config.py +182 -0
  193. claude_mpm/services/agents/deployment/config/deployment_config_manager.py +200 -0
  194. claude_mpm/services/agents/deployment/deployment_config_loader.py +54 -0
  195. claude_mpm/services/agents/deployment/deployment_type_detector.py +124 -0
  196. claude_mpm/services/agents/deployment/facade/__init__.py +18 -0
  197. claude_mpm/services/agents/deployment/facade/async_deployment_executor.py +159 -0
  198. claude_mpm/services/agents/deployment/facade/deployment_executor.py +73 -0
  199. claude_mpm/services/agents/deployment/facade/deployment_facade.py +270 -0
  200. claude_mpm/services/agents/deployment/facade/sync_deployment_executor.py +178 -0
  201. claude_mpm/services/agents/deployment/interface_adapter.py +227 -0
  202. claude_mpm/services/agents/deployment/lifecycle_health_checker.py +85 -0
  203. claude_mpm/services/agents/deployment/lifecycle_performance_tracker.py +100 -0
  204. claude_mpm/services/agents/deployment/pipeline/__init__.py +32 -0
  205. claude_mpm/services/agents/deployment/pipeline/pipeline_builder.py +158 -0
  206. claude_mpm/services/agents/deployment/pipeline/pipeline_context.py +159 -0
  207. claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +169 -0
  208. claude_mpm/services/agents/deployment/pipeline/steps/__init__.py +19 -0
  209. claude_mpm/services/agents/deployment/pipeline/steps/agent_processing_step.py +195 -0
  210. claude_mpm/services/agents/deployment/pipeline/steps/base_step.py +119 -0
  211. claude_mpm/services/agents/deployment/pipeline/steps/configuration_step.py +79 -0
  212. claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +90 -0
  213. claude_mpm/services/agents/deployment/pipeline/steps/validation_step.py +100 -0
  214. claude_mpm/services/agents/deployment/processors/__init__.py +15 -0
  215. claude_mpm/services/agents/deployment/processors/agent_deployment_context.py +98 -0
  216. claude_mpm/services/agents/deployment/processors/agent_deployment_result.py +235 -0
  217. claude_mpm/services/agents/deployment/processors/agent_processor.py +258 -0
  218. claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +318 -0
  219. claude_mpm/services/agents/deployment/results/__init__.py +13 -0
  220. claude_mpm/services/agents/deployment/results/deployment_metrics.py +200 -0
  221. claude_mpm/services/agents/deployment/results/deployment_result_builder.py +249 -0
  222. claude_mpm/services/agents/deployment/strategies/__init__.py +25 -0
  223. claude_mpm/services/agents/deployment/strategies/base_strategy.py +119 -0
  224. claude_mpm/services/agents/deployment/strategies/project_strategy.py +150 -0
  225. claude_mpm/services/agents/deployment/strategies/strategy_selector.py +117 -0
  226. claude_mpm/services/agents/deployment/strategies/system_strategy.py +116 -0
  227. claude_mpm/services/agents/deployment/strategies/user_strategy.py +137 -0
  228. claude_mpm/services/agents/deployment/system_instructions_deployer.py +108 -0
  229. claude_mpm/services/agents/deployment/validation/__init__.py +19 -0
  230. claude_mpm/services/agents/deployment/validation/agent_validator.py +323 -0
  231. claude_mpm/services/agents/deployment/validation/deployment_validator.py +238 -0
  232. claude_mpm/services/agents/deployment/validation/template_validator.py +299 -0
  233. claude_mpm/services/agents/deployment/validation/validation_result.py +226 -0
  234. claude_mpm/services/agents/loading/__init__.py +2 -2
  235. claude_mpm/services/agents/loading/agent_profile_loader.py +259 -229
  236. claude_mpm/services/agents/loading/base_agent_manager.py +90 -81
  237. claude_mpm/services/agents/loading/framework_agent_loader.py +154 -129
  238. claude_mpm/services/agents/management/__init__.py +2 -2
  239. claude_mpm/services/agents/management/agent_capabilities_generator.py +72 -58
  240. claude_mpm/services/agents/management/agent_management_service.py +209 -156
  241. claude_mpm/services/agents/memory/__init__.py +9 -6
  242. claude_mpm/services/agents/memory/agent_memory_manager.py +218 -1152
  243. claude_mpm/services/agents/memory/agent_persistence_service.py +20 -16
  244. claude_mpm/services/agents/memory/analyzer.py +430 -0
  245. claude_mpm/services/agents/memory/content_manager.py +376 -0
  246. claude_mpm/services/agents/memory/template_generator.py +468 -0
  247. claude_mpm/services/agents/registry/__init__.py +7 -10
  248. claude_mpm/services/agents/registry/deployed_agent_discovery.py +122 -97
  249. claude_mpm/services/agents/registry/modification_tracker.py +351 -285
  250. claude_mpm/services/async_session_logger.py +187 -153
  251. claude_mpm/services/claude_session_logger.py +87 -72
  252. claude_mpm/services/command_handler_service.py +217 -0
  253. claude_mpm/services/communication/__init__.py +3 -2
  254. claude_mpm/services/core/__init__.py +50 -97
  255. claude_mpm/services/core/base.py +60 -53
  256. claude_mpm/services/core/interfaces/__init__.py +188 -0
  257. claude_mpm/services/core/interfaces/agent.py +351 -0
  258. claude_mpm/services/core/interfaces/communication.py +343 -0
  259. claude_mpm/services/core/interfaces/infrastructure.py +413 -0
  260. claude_mpm/services/core/interfaces/service.py +434 -0
  261. claude_mpm/services/core/interfaces.py +19 -944
  262. claude_mpm/services/event_aggregator.py +208 -170
  263. claude_mpm/services/exceptions.py +387 -308
  264. claude_mpm/services/framework_claude_md_generator/__init__.py +75 -79
  265. claude_mpm/services/framework_claude_md_generator/content_assembler.py +69 -60
  266. claude_mpm/services/framework_claude_md_generator/content_validator.py +65 -61
  267. claude_mpm/services/framework_claude_md_generator/deployment_manager.py +68 -49
  268. claude_mpm/services/framework_claude_md_generator/section_generators/__init__.py +34 -34
  269. claude_mpm/services/framework_claude_md_generator/section_generators/agents.py +25 -22
  270. claude_mpm/services/framework_claude_md_generator/section_generators/claude_pm_init.py +10 -10
  271. claude_mpm/services/framework_claude_md_generator/section_generators/core_responsibilities.py +4 -3
  272. claude_mpm/services/framework_claude_md_generator/section_generators/delegation_constraints.py +4 -3
  273. claude_mpm/services/framework_claude_md_generator/section_generators/environment_config.py +4 -3
  274. claude_mpm/services/framework_claude_md_generator/section_generators/footer.py +6 -5
  275. claude_mpm/services/framework_claude_md_generator/section_generators/header.py +8 -7
  276. claude_mpm/services/framework_claude_md_generator/section_generators/orchestration_principles.py +4 -3
  277. claude_mpm/services/framework_claude_md_generator/section_generators/role_designation.py +6 -5
  278. claude_mpm/services/framework_claude_md_generator/section_generators/subprocess_validation.py +9 -8
  279. claude_mpm/services/framework_claude_md_generator/section_generators/todo_task_tools.py +4 -3
  280. claude_mpm/services/framework_claude_md_generator/section_generators/troubleshooting.py +5 -4
  281. claude_mpm/services/framework_claude_md_generator/section_manager.py +28 -27
  282. claude_mpm/services/framework_claude_md_generator/version_manager.py +30 -28
  283. claude_mpm/services/hook_service.py +106 -114
  284. claude_mpm/services/infrastructure/__init__.py +7 -5
  285. claude_mpm/services/infrastructure/context_preservation.py +233 -199
  286. claude_mpm/services/infrastructure/daemon_manager.py +279 -0
  287. claude_mpm/services/infrastructure/logging.py +83 -76
  288. claude_mpm/services/infrastructure/monitoring.py +547 -404
  289. claude_mpm/services/mcp_gateway/__init__.py +30 -13
  290. claude_mpm/services/mcp_gateway/config/__init__.py +2 -2
  291. claude_mpm/services/mcp_gateway/config/config_loader.py +61 -56
  292. claude_mpm/services/mcp_gateway/config/config_schema.py +50 -41
  293. claude_mpm/services/mcp_gateway/config/configuration.py +82 -75
  294. claude_mpm/services/mcp_gateway/core/__init__.py +13 -20
  295. claude_mpm/services/mcp_gateway/core/base.py +80 -67
  296. claude_mpm/services/mcp_gateway/core/exceptions.py +60 -46
  297. claude_mpm/services/mcp_gateway/core/interfaces.py +87 -84
  298. claude_mpm/services/mcp_gateway/main.py +287 -137
  299. claude_mpm/services/mcp_gateway/registry/__init__.py +1 -1
  300. claude_mpm/services/mcp_gateway/registry/service_registry.py +97 -94
  301. claude_mpm/services/mcp_gateway/registry/tool_registry.py +135 -126
  302. claude_mpm/services/mcp_gateway/server/__init__.py +2 -2
  303. claude_mpm/services/mcp_gateway/server/mcp_gateway.py +105 -110
  304. claude_mpm/services/mcp_gateway/server/stdio_handler.py +105 -107
  305. claude_mpm/services/mcp_gateway/server/stdio_server.py +691 -0
  306. claude_mpm/services/mcp_gateway/tools/__init__.py +4 -2
  307. claude_mpm/services/mcp_gateway/tools/base_adapter.py +109 -119
  308. claude_mpm/services/mcp_gateway/tools/document_summarizer.py +283 -215
  309. claude_mpm/services/mcp_gateway/tools/hello_world.py +122 -120
  310. claude_mpm/services/mcp_gateway/tools/ticket_tools.py +652 -0
  311. claude_mpm/services/mcp_gateway/tools/unified_ticket_tool.py +606 -0
  312. claude_mpm/services/memory/__init__.py +2 -2
  313. claude_mpm/services/memory/builder.py +451 -362
  314. claude_mpm/services/memory/cache/__init__.py +2 -2
  315. claude_mpm/services/memory/cache/shared_prompt_cache.py +232 -194
  316. claude_mpm/services/memory/cache/simple_cache.py +107 -93
  317. claude_mpm/services/memory/indexed_memory.py +195 -193
  318. claude_mpm/services/memory/optimizer.py +267 -234
  319. claude_mpm/services/memory/router.py +571 -263
  320. claude_mpm/services/memory_hook_service.py +237 -0
  321. claude_mpm/services/port_manager.py +223 -0
  322. claude_mpm/services/project/__init__.py +3 -3
  323. claude_mpm/services/project/analyzer.py +451 -305
  324. claude_mpm/services/project/registry.py +262 -240
  325. claude_mpm/services/recovery_manager.py +287 -231
  326. claude_mpm/services/response_tracker.py +87 -67
  327. claude_mpm/services/runner_configuration_service.py +587 -0
  328. claude_mpm/services/session_management_service.py +304 -0
  329. claude_mpm/services/socketio/__init__.py +4 -4
  330. claude_mpm/services/socketio/client_proxy.py +174 -0
  331. claude_mpm/services/socketio/handlers/__init__.py +3 -3
  332. claude_mpm/services/socketio/handlers/base.py +44 -30
  333. claude_mpm/services/socketio/handlers/connection.py +145 -65
  334. claude_mpm/services/socketio/handlers/file.py +123 -108
  335. claude_mpm/services/socketio/handlers/git.py +607 -373
  336. claude_mpm/services/socketio/handlers/hook.py +170 -0
  337. claude_mpm/services/socketio/handlers/memory.py +4 -4
  338. claude_mpm/services/socketio/handlers/project.py +4 -4
  339. claude_mpm/services/socketio/handlers/registry.py +53 -38
  340. claude_mpm/services/socketio/server/__init__.py +18 -0
  341. claude_mpm/services/socketio/server/broadcaster.py +252 -0
  342. claude_mpm/services/socketio/server/core.py +399 -0
  343. claude_mpm/services/socketio/server/main.py +323 -0
  344. claude_mpm/services/socketio_client_manager.py +160 -133
  345. claude_mpm/services/socketio_server.py +36 -1885
  346. claude_mpm/services/subprocess_launcher_service.py +316 -0
  347. claude_mpm/services/system_instructions_service.py +258 -0
  348. claude_mpm/services/ticket_manager.py +19 -533
  349. claude_mpm/services/utility_service.py +285 -0
  350. claude_mpm/services/version_control/__init__.py +18 -21
  351. claude_mpm/services/version_control/branch_strategy.py +20 -10
  352. claude_mpm/services/version_control/conflict_resolution.py +37 -13
  353. claude_mpm/services/version_control/git_operations.py +52 -21
  354. claude_mpm/services/version_control/semantic_versioning.py +92 -53
  355. claude_mpm/services/version_control/version_parser.py +145 -125
  356. claude_mpm/services/version_service.py +270 -0
  357. claude_mpm/storage/__init__.py +2 -2
  358. claude_mpm/storage/state_storage.py +177 -181
  359. claude_mpm/ticket_wrapper.py +2 -2
  360. claude_mpm/utils/__init__.py +2 -2
  361. claude_mpm/utils/agent_dependency_loader.py +453 -243
  362. claude_mpm/utils/config_manager.py +157 -118
  363. claude_mpm/utils/console.py +1 -1
  364. claude_mpm/utils/dependency_cache.py +102 -107
  365. claude_mpm/utils/dependency_manager.py +52 -47
  366. claude_mpm/utils/dependency_strategies.py +131 -96
  367. claude_mpm/utils/environment_context.py +110 -102
  368. claude_mpm/utils/error_handler.py +75 -55
  369. claude_mpm/utils/file_utils.py +80 -67
  370. claude_mpm/utils/framework_detection.py +12 -11
  371. claude_mpm/utils/import_migration_example.py +12 -60
  372. claude_mpm/utils/imports.py +48 -45
  373. claude_mpm/utils/path_operations.py +100 -93
  374. claude_mpm/utils/robust_installer.py +172 -164
  375. claude_mpm/utils/session_logging.py +30 -23
  376. claude_mpm/utils/subprocess_utils.py +99 -61
  377. claude_mpm/validation/__init__.py +1 -1
  378. claude_mpm/validation/agent_validator.py +151 -111
  379. claude_mpm/validation/frontmatter_validator.py +92 -71
  380. {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.3.dist-info}/METADATA +27 -1
  381. claude_mpm-4.0.3.dist-info/RECORD +402 -0
  382. {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.3.dist-info}/entry_points.txt +1 -0
  383. {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.3.dist-info}/licenses/LICENSE +1 -1
  384. claude_mpm/cli/commands/run_guarded.py +0 -511
  385. claude_mpm/config/memory_guardian_config.py +0 -325
  386. claude_mpm/config/memory_guardian_yaml.py +0 -335
  387. claude_mpm/core/config_paths.py +0 -150
  388. claude_mpm/core/memory_aware_runner.py +0 -353
  389. claude_mpm/dashboard/static/js/dashboard-original.js +0 -4134
  390. claude_mpm/deployment_paths.py +0 -261
  391. claude_mpm/hooks/claude_hooks/hook_handler_fixed.py +0 -454
  392. claude_mpm/models/state_models.py +0 -433
  393. claude_mpm/services/agent/__init__.py +0 -24
  394. claude_mpm/services/agent/deployment.py +0 -2548
  395. claude_mpm/services/agent/management.py +0 -598
  396. claude_mpm/services/agent/registry.py +0 -813
  397. claude_mpm/services/agents/registry/agent_registry.py +0 -813
  398. claude_mpm/services/communication/socketio.py +0 -1935
  399. claude_mpm/services/communication/websocket.py +0 -479
  400. claude_mpm/services/framework_claude_md_generator.py +0 -624
  401. claude_mpm/services/health_monitor.py +0 -893
  402. claude_mpm/services/infrastructure/graceful_degradation.py +0 -616
  403. claude_mpm/services/infrastructure/health_monitor.py +0 -775
  404. claude_mpm/services/infrastructure/memory_dashboard.py +0 -479
  405. claude_mpm/services/infrastructure/memory_guardian.py +0 -944
  406. claude_mpm/services/infrastructure/restart_protection.py +0 -642
  407. claude_mpm/services/infrastructure/state_manager.py +0 -774
  408. claude_mpm/services/mcp_gateway/manager.py +0 -334
  409. claude_mpm/services/optimized_hook_service.py +0 -542
  410. claude_mpm/services/project_analyzer.py +0 -864
  411. claude_mpm/services/project_registry.py +0 -608
  412. claude_mpm/services/standalone_socketio_server.py +0 -1300
  413. claude_mpm/services/ticket_manager_di.py +0 -318
  414. claude_mpm/services/ticketing_service_original.py +0 -510
  415. claude_mpm/utils/paths.py +0 -395
  416. claude_mpm/utils/platform_memory.py +0 -524
  417. claude_mpm-3.9.11.dist-info/RECORD +0 -306
  418. {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.3.dist-info}/WHEEL +0 -0
  419. {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.3.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,606 @@
1
+ """
2
+ Unified Ticket Tool for MCP Gateway
3
+ ====================================
4
+
5
+ Provides a single, unified interface for all ticket management operations
6
+ through the MCP Gateway, consolidating create, list, update, view, and search
7
+ functionality into one tool with an operation parameter.
8
+
9
+ WHY: Having 5 separate ticket tools creates unnecessary complexity. A single
10
+ tool with an operation parameter provides a cleaner, more intuitive API that
11
+ matches the mental model of "ticket operations" better.
12
+
13
+ DESIGN DECISIONS:
14
+ - Single tool with operation parameter for cleaner API
15
+ - Conditional parameter validation based on operation type
16
+ - Reuses existing logic from separate tools for consistency
17
+ - Maintains same error handling and metrics tracking patterns
18
+ - Uses JSON Schema oneOf for operation-specific parameter validation
19
+ """
20
+
21
+ import asyncio
22
+ import json
23
+ import re
24
+ import subprocess
25
+ from datetime import datetime
26
+ from typing import Any, Dict, List, Optional
27
+
28
+ from claude_mpm.services.mcp_gateway.core.interfaces import (
29
+ MCPToolDefinition,
30
+ MCPToolInvocation,
31
+ MCPToolResult,
32
+ )
33
+ from claude_mpm.services.mcp_gateway.tools.base_adapter import BaseToolAdapter
34
+
35
+
36
+ class UnifiedTicketTool(BaseToolAdapter):
37
+ """
38
+ Unified ticket management tool for aitrackdown operations.
39
+
40
+ WHY: Consolidates all ticket operations (create, list, update, view, search)
41
+ into a single tool with an operation parameter, providing a cleaner and more
42
+ intuitive interface for ticket management.
43
+
44
+ DESIGN DECISIONS:
45
+ - Use operation parameter to route to appropriate handler
46
+ - Implement conditional parameter validation per operation
47
+ - Maintain backward compatibility with existing aitrackdown CLI
48
+ - Preserve all error handling and metrics from original tools
49
+ """
50
+
51
+ def __init__(self):
52
+ """Initialize the unified ticket tool with comprehensive schema."""
53
+ definition = MCPToolDefinition(
54
+ name="ticket",
55
+ description="Unified ticket management tool for all aitrackdown operations",
56
+ input_schema={
57
+ "type": "object",
58
+ "properties": {
59
+ "operation": {
60
+ "type": "string",
61
+ "enum": ["create", "list", "update", "view", "search"],
62
+ "description": "The ticket operation to perform",
63
+ },
64
+ # Create operation parameters
65
+ "type": {
66
+ "type": "string",
67
+ "enum": ["task", "issue", "epic"],
68
+ "description": "Type of ticket (for create operation)",
69
+ },
70
+ "title": {
71
+ "type": "string",
72
+ "description": "Title of the ticket (for create operation)",
73
+ },
74
+ "description": {
75
+ "type": "string",
76
+ "description": "Detailed description (for create operation)",
77
+ },
78
+ "priority": {
79
+ "type": "string",
80
+ "enum": ["low", "medium", "high", "critical"],
81
+ "description": "Priority level",
82
+ },
83
+ "tags": {
84
+ "type": "array",
85
+ "items": {"type": "string"},
86
+ "description": "Tags to associate with the ticket (for create)",
87
+ },
88
+ "parent_epic": {
89
+ "type": "string",
90
+ "description": "Parent epic ID for issues (create operation)",
91
+ },
92
+ "parent_issue": {
93
+ "type": "string",
94
+ "description": "Parent issue ID for tasks (create operation)",
95
+ },
96
+ # List operation parameters
97
+ "limit": {
98
+ "type": "number",
99
+ "description": "Maximum number of results to return",
100
+ "default": 10,
101
+ },
102
+ # Update operation parameters
103
+ "ticket_id": {
104
+ "type": "string",
105
+ "description": "Ticket ID (for update/view operations)",
106
+ },
107
+ "status": {
108
+ "type": "string",
109
+ "enum": [
110
+ "all",
111
+ "open",
112
+ "in-progress",
113
+ "ready",
114
+ "tested",
115
+ "done",
116
+ "waiting",
117
+ "closed",
118
+ "blocked",
119
+ ],
120
+ "description": "Status filter or new status",
121
+ },
122
+ "comment": {
123
+ "type": "string",
124
+ "description": "Comment for update operation",
125
+ },
126
+ # View operation parameters
127
+ "format": {
128
+ "type": "string",
129
+ "enum": ["json", "text"],
130
+ "description": "Output format (for view operation)",
131
+ "default": "json",
132
+ },
133
+ # Search operation parameters
134
+ "query": {
135
+ "type": "string",
136
+ "description": "Search query keywords (for search operation)",
137
+ },
138
+ },
139
+ "required": ["operation"],
140
+ # Note: Additional validation is handled in the invoke method
141
+ # to avoid using allOf/oneOf/anyOf at the top level which is not
142
+ # supported by the Claude API
143
+ },
144
+ )
145
+ super().__init__(definition)
146
+
147
+ async def invoke(self, invocation: MCPToolInvocation) -> MCPToolResult:
148
+ """
149
+ Route the invocation to the appropriate operation handler.
150
+
151
+ Args:
152
+ invocation: Tool invocation request
153
+
154
+ Returns:
155
+ Tool execution result from the specific operation
156
+ """
157
+ operation = invocation.parameters.get("operation")
158
+
159
+ if not operation:
160
+ return MCPToolResult(
161
+ success=False,
162
+ error="Operation parameter is required",
163
+ execution_time=0.0,
164
+ )
165
+
166
+ # Validate required parameters based on operation type
167
+ validation_error = self._validate_parameters(operation, invocation.parameters)
168
+ if validation_error:
169
+ return MCPToolResult(
170
+ success=False,
171
+ error=validation_error,
172
+ execution_time=0.0,
173
+ )
174
+
175
+ # Route to appropriate handler based on operation
176
+ handlers = {
177
+ "create": self._handle_create,
178
+ "list": self._handle_list,
179
+ "update": self._handle_update,
180
+ "view": self._handle_view,
181
+ "search": self._handle_search,
182
+ }
183
+
184
+ handler = handlers.get(operation)
185
+ if not handler:
186
+ return MCPToolResult(
187
+ success=False,
188
+ error=f"Unknown operation: {operation}",
189
+ execution_time=0.0,
190
+ )
191
+
192
+ return await handler(invocation.parameters)
193
+
194
+ def _validate_parameters(self, operation: str, params: Dict[str, Any]) -> Optional[str]:
195
+ """
196
+ Validate parameters based on the operation type.
197
+
198
+ Args:
199
+ operation: The operation being performed
200
+ params: Parameters provided for the operation
201
+
202
+ Returns:
203
+ Error message if validation fails, None if valid
204
+ """
205
+ if operation == "create":
206
+ if "type" not in params:
207
+ return "'type' parameter is required for create operation"
208
+ if "title" not in params:
209
+ return "'title' parameter is required for create operation"
210
+ if params["type"] not in ["task", "issue", "epic"]:
211
+ return f"Invalid type '{params['type']}'. Must be 'task', 'issue', or 'epic'"
212
+
213
+ elif operation == "update":
214
+ if "ticket_id" not in params:
215
+ return "'ticket_id' parameter is required for update operation"
216
+
217
+ elif operation == "view":
218
+ if "ticket_id" not in params:
219
+ return "'ticket_id' parameter is required for view operation"
220
+
221
+ elif operation == "search":
222
+ if "query" not in params:
223
+ return "'query' parameter is required for search operation"
224
+
225
+ elif operation == "list":
226
+ # List operation has no required parameters beyond operation itself
227
+ pass
228
+
229
+ else:
230
+ return f"Unknown operation: {operation}"
231
+
232
+ return None
233
+
234
+ async def _handle_create(self, params: Dict[str, Any]) -> MCPToolResult:
235
+ """
236
+ Handle ticket creation operation.
237
+
238
+ Args:
239
+ params: Parameters for ticket creation
240
+
241
+ Returns:
242
+ Tool execution result with created ticket ID
243
+ """
244
+ start_time = datetime.now()
245
+
246
+ try:
247
+ # Build aitrackdown command
248
+ cmd = ["aitrackdown", "create", params["type"], params["title"]]
249
+
250
+ # Add optional parameters
251
+ if "description" in params:
252
+ cmd.extend(["--description", params["description"]])
253
+
254
+ if "priority" in params:
255
+ cmd.extend(["--priority", params["priority"]])
256
+
257
+ if "tags" in params and params["tags"]:
258
+ for tag in params["tags"]:
259
+ cmd.extend(["--tag", tag])
260
+
261
+ # For tasks, use --issue to associate with parent issue
262
+ if params["type"] == "task" and "parent_issue" in params:
263
+ cmd.extend(["--issue", params["parent_issue"]])
264
+
265
+ # Execute command asynchronously
266
+ process = await asyncio.create_subprocess_exec(
267
+ *cmd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE
268
+ )
269
+
270
+ stdout, stderr = await process.communicate()
271
+ execution_time = (datetime.now() - start_time).total_seconds()
272
+
273
+ if process.returncode == 0:
274
+ # Parse ticket ID from output
275
+ output = stdout.decode().strip()
276
+ ticket_id = None
277
+ for line in output.split("\n"):
278
+ if "TSK-" in line or "ISS-" in line or "EP-" in line:
279
+ match = re.search(r"(TSK|ISS|EP)-\d+", line)
280
+ if match:
281
+ ticket_id = match.group(0)
282
+ break
283
+
284
+ self._update_metrics(True, execution_time)
285
+
286
+ return MCPToolResult(
287
+ success=True,
288
+ data={
289
+ "ticket_id": ticket_id or "Unknown",
290
+ "type": params["type"],
291
+ "title": params["title"],
292
+ "message": output,
293
+ },
294
+ execution_time=execution_time,
295
+ metadata={"tool": "ticket", "operation": "create"},
296
+ )
297
+ else:
298
+ error_msg = stderr.decode() if stderr else stdout.decode()
299
+ self._update_metrics(False, execution_time)
300
+
301
+ return MCPToolResult(
302
+ success=False,
303
+ error=f"Failed to create ticket: {error_msg}",
304
+ execution_time=execution_time,
305
+ )
306
+
307
+ except Exception as e:
308
+ execution_time = (datetime.now() - start_time).total_seconds()
309
+ self._update_metrics(False, execution_time)
310
+
311
+ return MCPToolResult(
312
+ success=False,
313
+ error=f"Ticket creation failed: {str(e)}",
314
+ execution_time=execution_time,
315
+ )
316
+
317
+ async def _handle_list(self, params: Dict[str, Any]) -> MCPToolResult:
318
+ """
319
+ Handle ticket listing operation.
320
+
321
+ Args:
322
+ params: Parameters for ticket listing
323
+
324
+ Returns:
325
+ Tool execution result with list of tickets
326
+ """
327
+ start_time = datetime.now()
328
+
329
+ try:
330
+ limit = params.get("limit", 10)
331
+
332
+ # Build aitrackdown command - use status tasks for listing
333
+ cmd = ["aitrackdown", "status", "tasks", "--limit", str(limit)]
334
+
335
+ # Add filters
336
+ if params.get("status") and params["status"] != "all":
337
+ cmd.extend(["--status", params["status"]])
338
+
339
+ # Execute command asynchronously
340
+ process = await asyncio.create_subprocess_exec(
341
+ *cmd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE
342
+ )
343
+
344
+ stdout, stderr = await process.communicate()
345
+ execution_time = (datetime.now() - start_time).total_seconds()
346
+
347
+ if process.returncode == 0:
348
+ try:
349
+ # Try to parse JSON output
350
+ tickets = json.loads(stdout.decode())
351
+ except json.JSONDecodeError:
352
+ # Fallback to text parsing if JSON fails
353
+ output = stdout.decode().strip()
354
+ tickets = {"raw_output": output, "count": output.count("\n") + 1}
355
+
356
+ self._update_metrics(True, execution_time)
357
+
358
+ return MCPToolResult(
359
+ success=True,
360
+ data=tickets,
361
+ execution_time=execution_time,
362
+ metadata={
363
+ "tool": "ticket",
364
+ "operation": "list",
365
+ "count": len(tickets) if isinstance(tickets, list) else 1,
366
+ },
367
+ )
368
+ else:
369
+ error_msg = stderr.decode() if stderr else stdout.decode()
370
+ self._update_metrics(False, execution_time)
371
+
372
+ return MCPToolResult(
373
+ success=False,
374
+ error=f"Failed to list tickets: {error_msg}",
375
+ execution_time=execution_time,
376
+ )
377
+
378
+ except Exception as e:
379
+ execution_time = (datetime.now() - start_time).total_seconds()
380
+ self._update_metrics(False, execution_time)
381
+
382
+ return MCPToolResult(
383
+ success=False,
384
+ error=f"Ticket listing failed: {str(e)}",
385
+ execution_time=execution_time,
386
+ )
387
+
388
+ async def _handle_update(self, params: Dict[str, Any]) -> MCPToolResult:
389
+ """
390
+ Handle ticket update operation.
391
+
392
+ Args:
393
+ params: Parameters for ticket update
394
+
395
+ Returns:
396
+ Tool execution result
397
+ """
398
+ start_time = datetime.now()
399
+
400
+ try:
401
+ ticket_id = params["ticket_id"]
402
+
403
+ # Determine which update to perform
404
+ if "status" in params and params["status"] != "all":
405
+ # Use transition command for status updates
406
+ cmd = ["aitrackdown", "transition", ticket_id, params["status"]]
407
+
408
+ if "comment" in params:
409
+ cmd.extend(["--comment", params["comment"]])
410
+ elif "priority" in params:
411
+ # For priority updates, use transition with comment
412
+ cmd = ["aitrackdown", "transition", ticket_id, "open"]
413
+ cmd.extend(["--comment", f"Priority changed to {params['priority']}"])
414
+
415
+ if "comment" in params:
416
+ cmd.extend(["--comment", params["comment"]])
417
+ else:
418
+ return MCPToolResult(
419
+ success=False,
420
+ error="No update fields provided (status or priority required)",
421
+ execution_time=0.0,
422
+ )
423
+
424
+ # Execute command asynchronously
425
+ process = await asyncio.create_subprocess_exec(
426
+ *cmd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE
427
+ )
428
+
429
+ stdout, stderr = await process.communicate()
430
+ execution_time = (datetime.now() - start_time).total_seconds()
431
+
432
+ if process.returncode == 0:
433
+ self._update_metrics(True, execution_time)
434
+
435
+ return MCPToolResult(
436
+ success=True,
437
+ data={
438
+ "ticket_id": ticket_id,
439
+ "updated_fields": [
440
+ k for k in ["status", "priority"] if k in params
441
+ ],
442
+ "message": stdout.decode().strip(),
443
+ },
444
+ execution_time=execution_time,
445
+ metadata={"tool": "ticket", "operation": "update"},
446
+ )
447
+ else:
448
+ error_msg = stderr.decode() if stderr else stdout.decode()
449
+ self._update_metrics(False, execution_time)
450
+
451
+ return MCPToolResult(
452
+ success=False,
453
+ error=f"Failed to update ticket: {error_msg}",
454
+ execution_time=execution_time,
455
+ )
456
+
457
+ except Exception as e:
458
+ execution_time = (datetime.now() - start_time).total_seconds()
459
+ self._update_metrics(False, execution_time)
460
+
461
+ return MCPToolResult(
462
+ success=False,
463
+ error=f"Ticket update failed: {str(e)}",
464
+ execution_time=execution_time,
465
+ )
466
+
467
+ async def _handle_view(self, params: Dict[str, Any]) -> MCPToolResult:
468
+ """
469
+ Handle ticket viewing operation.
470
+
471
+ Args:
472
+ params: Parameters for ticket viewing
473
+
474
+ Returns:
475
+ Tool execution result with ticket details
476
+ """
477
+ start_time = datetime.now()
478
+
479
+ try:
480
+ ticket_id = params["ticket_id"]
481
+ format_type = params.get("format", "json")
482
+
483
+ # Build aitrackdown command - use show for viewing
484
+ cmd = ["aitrackdown", "show", ticket_id]
485
+
486
+ # Execute command asynchronously
487
+ process = await asyncio.create_subprocess_exec(
488
+ *cmd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE
489
+ )
490
+
491
+ stdout, stderr = await process.communicate()
492
+ execution_time = (datetime.now() - start_time).total_seconds()
493
+
494
+ if process.returncode == 0:
495
+ output = stdout.decode().strip()
496
+
497
+ if format_type == "json":
498
+ try:
499
+ ticket_data = json.loads(output)
500
+ except json.JSONDecodeError:
501
+ ticket_data = {"raw_output": output}
502
+ else:
503
+ ticket_data = {"raw_output": output}
504
+
505
+ self._update_metrics(True, execution_time)
506
+
507
+ return MCPToolResult(
508
+ success=True,
509
+ data=ticket_data,
510
+ execution_time=execution_time,
511
+ metadata={
512
+ "tool": "ticket",
513
+ "operation": "view",
514
+ "ticket_id": ticket_id,
515
+ },
516
+ )
517
+ else:
518
+ error_msg = stderr.decode() if stderr else stdout.decode()
519
+ self._update_metrics(False, execution_time)
520
+
521
+ return MCPToolResult(
522
+ success=False,
523
+ error=f"Failed to view ticket: {error_msg}",
524
+ execution_time=execution_time,
525
+ )
526
+
527
+ except Exception as e:
528
+ execution_time = (datetime.now() - start_time).total_seconds()
529
+ self._update_metrics(False, execution_time)
530
+
531
+ return MCPToolResult(
532
+ success=False,
533
+ error=f"Ticket view failed: {str(e)}",
534
+ execution_time=execution_time,
535
+ )
536
+
537
+ async def _handle_search(self, params: Dict[str, Any]) -> MCPToolResult:
538
+ """
539
+ Handle ticket search operation.
540
+
541
+ Args:
542
+ params: Parameters for ticket search
543
+
544
+ Returns:
545
+ Tool execution result with matching tickets
546
+ """
547
+ start_time = datetime.now()
548
+
549
+ try:
550
+ query = params["query"]
551
+ limit = params.get("limit", 10)
552
+
553
+ # Build aitrackdown command - use search tasks
554
+ cmd = ["aitrackdown", "search", "tasks", query, "--limit", str(limit)]
555
+
556
+ if params.get("type") and params["type"] != "all":
557
+ cmd.extend(["--type", params["type"]])
558
+
559
+ # Execute command asynchronously
560
+ process = await asyncio.create_subprocess_exec(
561
+ *cmd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE
562
+ )
563
+
564
+ stdout, stderr = await process.communicate()
565
+ execution_time = (datetime.now() - start_time).total_seconds()
566
+
567
+ if process.returncode == 0:
568
+ try:
569
+ # Try to parse JSON output
570
+ results = json.loads(stdout.decode())
571
+ except json.JSONDecodeError:
572
+ # Fallback to text parsing if JSON fails
573
+ output = stdout.decode().strip()
574
+ results = {"raw_output": output, "query": query}
575
+
576
+ self._update_metrics(True, execution_time)
577
+
578
+ return MCPToolResult(
579
+ success=True,
580
+ data=results,
581
+ execution_time=execution_time,
582
+ metadata={"tool": "ticket", "operation": "search", "query": query},
583
+ )
584
+ else:
585
+ error_msg = stderr.decode() if stderr else stdout.decode()
586
+ self._update_metrics(False, execution_time)
587
+
588
+ return MCPToolResult(
589
+ success=False,
590
+ error=f"Failed to search tickets: {error_msg}",
591
+ execution_time=execution_time,
592
+ )
593
+
594
+ except Exception as e:
595
+ execution_time = (datetime.now() - start_time).total_seconds()
596
+ self._update_metrics(False, execution_time)
597
+
598
+ return MCPToolResult(
599
+ success=False,
600
+ error=f"Ticket search failed: {str(e)}",
601
+ execution_time=execution_time,
602
+ )
603
+
604
+
605
+ # Export the unified ticket tool
606
+ __all__ = ["UnifiedTicketTool"]
@@ -7,11 +7,11 @@ This module provides memory management services including:
7
7
  """
8
8
 
9
9
  from .builder import MemoryBuilder
10
- from .router import MemoryRouter
11
10
  from .optimizer import MemoryOptimizer
11
+ from .router import MemoryRouter
12
12
 
13
13
  __all__ = [
14
14
  "MemoryBuilder",
15
15
  "MemoryRouter",
16
16
  "MemoryOptimizer",
17
- ]
17
+ ]